Skip to content

Commit ae5a045

Browse files
leitaokuba-moo
authored andcommitted
netpoll: Ensure clean state on setup failures
Modify netpoll_setup() and __netpoll_setup() to ensure that the netpoll structure (np) is left in a clean state if setup fails for any reason. This prevents carrying over misconfigured fields in case of partial setup success. Key changes: - np->dev is now set only after successful setup, ensuring it's always NULL if netpoll is not configured or if netpoll_setup() fails. - np->local_ip is zeroed if netpoll setup doesn't complete successfully. - Added DEBUG_NET_WARN_ON_ONCE() checks to catch unexpected states. - Reordered some operations in __netpoll_setup() for better logical flow. These changes improve the reliability of netpoll configuration, since it assures that the structure is fully initialized or totally unset. Suggested-by: Paolo Abeni <[email protected]> Signed-off-by: Breno Leitao <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent f086d18 commit ae5a045

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

net/core/netpoll.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -624,12 +624,9 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev)
624624
const struct net_device_ops *ops;
625625
int err;
626626

627-
np->dev = ndev;
628-
strscpy(np->dev_name, ndev->name, IFNAMSIZ);
629-
630627
if (ndev->priv_flags & IFF_DISABLE_NETPOLL) {
631628
np_err(np, "%s doesn't support polling, aborting\n",
632-
np->dev_name);
629+
ndev->name);
633630
err = -ENOTSUPP;
634631
goto out;
635632
}
@@ -647,7 +644,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev)
647644

648645
refcount_set(&npinfo->refcnt, 1);
649646

650-
ops = np->dev->netdev_ops;
647+
ops = ndev->netdev_ops;
651648
if (ops->ndo_netpoll_setup) {
652649
err = ops->ndo_netpoll_setup(ndev, npinfo);
653650
if (err)
@@ -658,6 +655,8 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev)
658655
refcount_inc(&npinfo->refcnt);
659656
}
660657

658+
np->dev = ndev;
659+
strscpy(np->dev_name, ndev->name, IFNAMSIZ);
661660
npinfo->netpoll = np;
662661

663662
/* last thing to do is link it to the net device structure */
@@ -675,6 +674,7 @@ EXPORT_SYMBOL_GPL(__netpoll_setup);
675674
int netpoll_setup(struct netpoll *np)
676675
{
677676
struct net_device *ndev = NULL;
677+
bool ip_overwritten = false;
678678
struct in_device *in_dev;
679679
int err;
680680

@@ -739,6 +739,7 @@ int netpoll_setup(struct netpoll *np)
739739
}
740740

741741
np->local_ip.ip = ifa->ifa_local;
742+
ip_overwritten = true;
742743
np_info(np, "local IP %pI4\n", &np->local_ip.ip);
743744
} else {
744745
#if IS_ENABLED(CONFIG_IPV6)
@@ -755,6 +756,7 @@ int netpoll_setup(struct netpoll *np)
755756
!!(ipv6_addr_type(&np->remote_ip.in6) & IPV6_ADDR_LINKLOCAL))
756757
continue;
757758
np->local_ip.in6 = ifp->addr;
759+
ip_overwritten = true;
758760
err = 0;
759761
break;
760762
}
@@ -785,6 +787,9 @@ int netpoll_setup(struct netpoll *np)
785787
return 0;
786788

787789
put:
790+
DEBUG_NET_WARN_ON_ONCE(np->dev);
791+
if (ip_overwritten)
792+
memset(&np->local_ip, 0, sizeof(np->local_ip));
788793
netdev_put(ndev, &np->dev_tracker);
789794
unlock:
790795
rtnl_unlock();

0 commit comments

Comments
 (0)