summaryrefslogtreecommitdiff
path: root/net/core
diff options
context:
space:
mode:
authorBreno Leitao <leitao@debian.org>2025-06-18 02:32:47 -0700
committerJakub Kicinski <kuba@kernel.org>2025-06-19 16:15:35 -0700
commit6ad7969a361cbec5822285fb39203678ff462b64 (patch)
tree2996919be163a77ed55c10f50a8ab05a6e57841e /net/core
parent3699f992e8c22d3ce54d2c1a5774e2c49028f99c (diff)
netpoll: Extract IPv6 address retrieval function
Extract the IPv6 address retrieval logic from netpoll_setup() into a dedicated helper function netpoll_take_ipv6() to improve code organization and readability. The function handles obtaining the local IPv6 address from the network device, including proper address type matching between local and remote addresses (link-local vs global), and includes appropriate error handling when IPv6 is not supported or no suitable address is available. Signed-off-by: Breno Leitao <leitao@debian.org> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://patch.msgid.link/20250618-netpoll_ip_ref-v1-3-c2ac00fe558f@debian.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/netpoll.c76
1 files changed, 44 insertions, 32 deletions
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 6ab494559b5c..7021ea45a053 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -599,6 +599,47 @@ static void netpoll_wait_carrier(struct netpoll *np, struct net_device *ndev,
}
/*
+ * Take the IPv6 from ndev and populate local_ip structure in netpoll
+ */
+static int netpoll_take_ipv6(struct netpoll *np, struct net_device *ndev)
+{
+ char buf[MAC_ADDR_STR_LEN + 1];
+ int err = -EDESTADDRREQ;
+ struct inet6_dev *idev;
+
+ if (!IS_ENABLED(CONFIG_IPV6)) {
+ np_err(np, "IPv6 is not supported %s, aborting\n",
+ egress_dev(np, buf));
+ return -EINVAL;
+ }
+
+ idev = __in6_dev_get(ndev);
+ if (idev) {
+ struct inet6_ifaddr *ifp;
+
+ read_lock_bh(&idev->lock);
+ list_for_each_entry(ifp, &idev->addr_list, if_list) {
+ if (!!(ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL) !=
+ !!(ipv6_addr_type(&np->remote_ip.in6) & IPV6_ADDR_LINKLOCAL))
+ continue;
+ /* Got the IP, let's return */
+ np->local_ip.in6 = ifp->addr;
+ err = 0;
+ break;
+ }
+ read_unlock_bh(&idev->lock);
+ }
+ if (err) {
+ np_err(np, "no IPv6 address for %s, aborting\n",
+ egress_dev(np, buf));
+ return err;
+ }
+
+ np_info(np, "local IPv6 %pI6c\n", &np->local_ip.in6);
+ return 0;
+}
+
+/*
* Take the IPv4 from ndev and populate local_ip structure in netpoll
*/
static int netpoll_take_ipv4(struct netpoll *np, struct net_device *ndev)
@@ -675,41 +716,12 @@ int netpoll_setup(struct netpoll *np)
err = netpoll_take_ipv4(np, ndev);
if (err)
goto put;
- ip_overwritten = true;
} else {
-#if IS_ENABLED(CONFIG_IPV6)
- struct inet6_dev *idev;
-
- err = -EDESTADDRREQ;
- idev = __in6_dev_get(ndev);
- if (idev) {
- struct inet6_ifaddr *ifp;
-
- read_lock_bh(&idev->lock);
- list_for_each_entry(ifp, &idev->addr_list, if_list) {
- if (!!(ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL) !=
- !!(ipv6_addr_type(&np->remote_ip.in6) & IPV6_ADDR_LINKLOCAL))
- continue;
- np->local_ip.in6 = ifp->addr;
- ip_overwritten = true;
- err = 0;
- break;
- }
- read_unlock_bh(&idev->lock);
- }
- if (err) {
- np_err(np, "no IPv6 address for %s, aborting\n",
- egress_dev(np, buf));
+ err = netpoll_take_ipv6(np, ndev);
+ if (err)
goto put;
- } else
- np_info(np, "local IPv6 %pI6c\n", &np->local_ip.in6);
-#else
- np_err(np, "IPv6 is not supported %s, aborting\n",
- egress_dev(np, buf));
- err = -EINVAL;
- goto put;
-#endif
}
+ ip_overwritten = true;
}
err = __netpoll_setup(np, ndev);