Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

+91 -61
+91 -61
net/core/netpoll.c
··· 583 583 return buf; 584 584 } 585 585 586 + static void netpoll_wait_carrier(struct netpoll *np, struct net_device *ndev, 587 + unsigned int timeout) 588 + { 589 + unsigned long atmost; 590 + 591 + atmost = jiffies + timeout * HZ; 592 + while (!netif_carrier_ok(ndev)) { 593 + if (time_after(jiffies, atmost)) { 594 + np_notice(np, "timeout waiting for carrier\n"); 595 + break; 596 + } 597 + msleep(1); 598 + } 599 + } 600 + 601 + /* 602 + * Take the IPv6 from ndev and populate local_ip structure in netpoll 603 + */ 604 + static int netpoll_take_ipv6(struct netpoll *np, struct net_device *ndev) 605 + { 606 + char buf[MAC_ADDR_STR_LEN + 1]; 607 + int err = -EDESTADDRREQ; 608 + struct inet6_dev *idev; 609 + 610 + if (!IS_ENABLED(CONFIG_IPV6)) { 611 + np_err(np, "IPv6 is not supported %s, aborting\n", 612 + egress_dev(np, buf)); 613 + return -EINVAL; 614 + } 615 + 616 + idev = __in6_dev_get(ndev); 617 + if (idev) { 618 + struct inet6_ifaddr *ifp; 619 + 620 + read_lock_bh(&idev->lock); 621 + list_for_each_entry(ifp, &idev->addr_list, if_list) { 622 + if (!!(ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL) != 623 + !!(ipv6_addr_type(&np->remote_ip.in6) & IPV6_ADDR_LINKLOCAL)) 624 + continue; 625 + /* Got the IP, let's return */ 626 + np->local_ip.in6 = ifp->addr; 627 + err = 0; 628 + break; 629 + } 630 + read_unlock_bh(&idev->lock); 631 + } 632 + if (err) { 633 + np_err(np, "no IPv6 address for %s, aborting\n", 634 + egress_dev(np, buf)); 635 + return err; 636 + } 637 + 638 + np_info(np, "local IPv6 %pI6c\n", &np->local_ip.in6); 639 + return 0; 640 + } 641 + 642 + /* 643 + * Take the IPv4 from ndev and populate local_ip structure in netpoll 644 + */ 645 + static int netpoll_take_ipv4(struct netpoll *np, struct net_device *ndev) 646 + { 647 + char buf[MAC_ADDR_STR_LEN + 1]; 648 + const struct in_ifaddr *ifa; 649 + struct in_device *in_dev; 650 + 651 + in_dev = __in_dev_get_rtnl(ndev); 652 + if (!in_dev) { 653 + np_err(np, "no IP address for %s, aborting\n", 654 + egress_dev(np, buf)); 655 + return -EDESTADDRREQ; 656 + } 657 + 658 + ifa = rtnl_dereference(in_dev->ifa_list); 659 + if (!ifa) { 660 + np_err(np, "no IP address for %s, aborting\n", 661 + egress_dev(np, buf)); 662 + return -EDESTADDRREQ; 663 + } 664 + 665 + np->local_ip.ip = ifa->ifa_local; 666 + np_info(np, "local IP %pI4\n", &np->local_ip.ip); 667 + 668 + return 0; 669 + } 670 + 586 671 int netpoll_setup(struct netpoll *np) 587 672 { 588 673 struct net *net = current->nsproxy->net_ns; 589 674 char buf[MAC_ADDR_STR_LEN + 1]; 590 675 struct net_device *ndev = NULL; 591 676 bool ip_overwritten = false; 592 - struct in_device *in_dev; 593 677 int err; 594 678 595 679 rtnl_lock(); ··· 697 613 } 698 614 699 615 if (!netif_running(ndev)) { 700 - unsigned long atmost; 701 - 702 616 np_info(np, "device %s not up yet, forcing it\n", 703 617 egress_dev(np, buf)); 704 618 705 619 err = dev_open(ndev, NULL); 706 - 707 620 if (err) { 708 621 np_err(np, "failed to open %s\n", ndev->name); 709 622 goto put; 710 623 } 711 624 712 625 rtnl_unlock(); 713 - atmost = jiffies + carrier_timeout * HZ; 714 - while (!netif_carrier_ok(ndev)) { 715 - if (time_after(jiffies, atmost)) { 716 - np_notice(np, "timeout waiting for carrier\n"); 717 - break; 718 - } 719 - msleep(1); 720 - } 721 - 626 + netpoll_wait_carrier(np, ndev, carrier_timeout); 722 627 rtnl_lock(); 723 628 } 724 629 725 630 if (!np->local_ip.ip) { 726 631 if (!np->ipv6) { 727 - const struct in_ifaddr *ifa; 728 - 729 - in_dev = __in_dev_get_rtnl(ndev); 730 - if (!in_dev) 731 - goto put_noaddr; 732 - 733 - ifa = rtnl_dereference(in_dev->ifa_list); 734 - if (!ifa) { 735 - put_noaddr: 736 - np_err(np, "no IP address for %s, aborting\n", 737 - egress_dev(np, buf)); 738 - err = -EDESTADDRREQ; 632 + err = netpoll_take_ipv4(np, ndev); 633 + if (err) 739 634 goto put; 740 - } 741 - 742 - np->local_ip.ip = ifa->ifa_local; 743 - ip_overwritten = true; 744 - np_info(np, "local IP %pI4\n", &np->local_ip.ip); 745 635 } else { 746 - #if IS_ENABLED(CONFIG_IPV6) 747 - struct inet6_dev *idev; 748 - 749 - err = -EDESTADDRREQ; 750 - idev = __in6_dev_get(ndev); 751 - if (idev) { 752 - struct inet6_ifaddr *ifp; 753 - 754 - read_lock_bh(&idev->lock); 755 - list_for_each_entry(ifp, &idev->addr_list, if_list) { 756 - if (!!(ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL) != 757 - !!(ipv6_addr_type(&np->remote_ip.in6) & IPV6_ADDR_LINKLOCAL)) 758 - continue; 759 - np->local_ip.in6 = ifp->addr; 760 - ip_overwritten = true; 761 - err = 0; 762 - break; 763 - } 764 - read_unlock_bh(&idev->lock); 765 - } 766 - if (err) { 767 - np_err(np, "no IPv6 address for %s, aborting\n", 768 - egress_dev(np, buf)); 636 + err = netpoll_take_ipv6(np, ndev); 637 + if (err) 769 638 goto put; 770 - } else 771 - np_info(np, "local IPv6 %pI6c\n", &np->local_ip.in6); 772 - #else 773 - np_err(np, "IPv6 is not supported %s, aborting\n", 774 - egress_dev(np, buf)); 775 - err = -EINVAL; 776 - goto put; 777 - #endif 778 639 } 640 + ip_overwritten = true; 779 641 } 780 642 781 643 err = __netpoll_setup(np, ndev);