mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-14 14:42:34 -04:00
Merge branch 'netpoll-code-organization-improvements'
Breno Leitao says: ==================== netpoll: Code organization improvements The netpoll_setup() function has grown complex over time, mixing different error handling and concerns like carrier waiting, IPv4 address retrieval, and IPv6 address retrieval all within a single function, which is huge (127 LoC). This patch series refactors the netpoll_setup() function to improve code organization and readability by extracting logical blocks into dedicated helper functions. netpoll_setup() length is reduced to 72 LoC. This series breaks down these responsibilities into focused helper functions. The changes are purely structural with no functional modifications. This changes were tested with the netconsole tests and the netpoll selftest (WIP)[1] Link: https://lore.kernel.org/20250612-netpoll_test-v1-1-4774fd95933f@debian.org [1] ==================== Link: https://patch.msgid.link/20250618-netpoll_ip_ref-v1-0-c2ac00fe558f@debian.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -583,13 +583,97 @@ static char *egress_dev(struct netpoll *np, char *buf)
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void netpoll_wait_carrier(struct netpoll *np, struct net_device *ndev,
|
||||
unsigned int timeout)
|
||||
{
|
||||
unsigned long atmost;
|
||||
|
||||
atmost = jiffies + timeout * HZ;
|
||||
while (!netif_carrier_ok(ndev)) {
|
||||
if (time_after(jiffies, atmost)) {
|
||||
np_notice(np, "timeout waiting for carrier\n");
|
||||
break;
|
||||
}
|
||||
msleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
char buf[MAC_ADDR_STR_LEN + 1];
|
||||
const struct in_ifaddr *ifa;
|
||||
struct in_device *in_dev;
|
||||
|
||||
in_dev = __in_dev_get_rtnl(ndev);
|
||||
if (!in_dev) {
|
||||
np_err(np, "no IP address for %s, aborting\n",
|
||||
egress_dev(np, buf));
|
||||
return -EDESTADDRREQ;
|
||||
}
|
||||
|
||||
ifa = rtnl_dereference(in_dev->ifa_list);
|
||||
if (!ifa) {
|
||||
np_err(np, "no IP address for %s, aborting\n",
|
||||
egress_dev(np, buf));
|
||||
return -EDESTADDRREQ;
|
||||
}
|
||||
|
||||
np->local_ip.ip = ifa->ifa_local;
|
||||
np_info(np, "local IP %pI4\n", &np->local_ip.ip);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int netpoll_setup(struct netpoll *np)
|
||||
{
|
||||
struct net *net = current->nsproxy->net_ns;
|
||||
char buf[MAC_ADDR_STR_LEN + 1];
|
||||
struct net_device *ndev = NULL;
|
||||
bool ip_overwritten = false;
|
||||
struct in_device *in_dev;
|
||||
int err;
|
||||
|
||||
rtnl_lock();
|
||||
@@ -613,85 +697,31 @@ int netpoll_setup(struct netpoll *np)
|
||||
}
|
||||
|
||||
if (!netif_running(ndev)) {
|
||||
unsigned long atmost;
|
||||
|
||||
np_info(np, "device %s not up yet, forcing it\n",
|
||||
egress_dev(np, buf));
|
||||
|
||||
err = dev_open(ndev, NULL);
|
||||
|
||||
if (err) {
|
||||
np_err(np, "failed to open %s\n", ndev->name);
|
||||
goto put;
|
||||
}
|
||||
|
||||
rtnl_unlock();
|
||||
atmost = jiffies + carrier_timeout * HZ;
|
||||
while (!netif_carrier_ok(ndev)) {
|
||||
if (time_after(jiffies, atmost)) {
|
||||
np_notice(np, "timeout waiting for carrier\n");
|
||||
break;
|
||||
}
|
||||
msleep(1);
|
||||
}
|
||||
|
||||
netpoll_wait_carrier(np, ndev, carrier_timeout);
|
||||
rtnl_lock();
|
||||
}
|
||||
|
||||
if (!np->local_ip.ip) {
|
||||
if (!np->ipv6) {
|
||||
const struct in_ifaddr *ifa;
|
||||
|
||||
in_dev = __in_dev_get_rtnl(ndev);
|
||||
if (!in_dev)
|
||||
goto put_noaddr;
|
||||
|
||||
ifa = rtnl_dereference(in_dev->ifa_list);
|
||||
if (!ifa) {
|
||||
put_noaddr:
|
||||
np_err(np, "no IP address for %s, aborting\n",
|
||||
egress_dev(np, buf));
|
||||
err = -EDESTADDRREQ;
|
||||
err = netpoll_take_ipv4(np, ndev);
|
||||
if (err)
|
||||
goto put;
|
||||
}
|
||||
|
||||
np->local_ip.ip = ifa->ifa_local;
|
||||
ip_overwritten = true;
|
||||
np_info(np, "local IP %pI4\n", &np->local_ip.ip);
|
||||
} 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);
|
||||
|
||||
Reference in New Issue
Block a user