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

Merge branch 'netconsole-reuse-netpoll_parse_ip_addr-in-configfs-helpers'

Breno Leitao says:

====================
netconsole: reuse netpoll_parse_ip_addr in configfs helpers

This patchset refactors the IP address parsing logic in the netconsole
driver to eliminate code duplication and improve maintainability. The
changes centralize IPv4 and IPv6 address parsing into a single function
(netpoll_parse_ip_addr). For that, it needs to teach
netpoll_parse_ip_addr() to handle strings with newlines, which is the
type of string coming from configfs.

Background

The netconsole driver currently has duplicate IP address parsing logic
in both local_ip_store() and remote_ip_store() functions. This
duplication increases the risk of inconsistencies and makes the code
harder to maintain.

Benefits

* Reduced code duplication: ~40 lines of duplicate parsing logic
eliminated
* Improved robustness: Centralized parsing reduces the chance
of inconsistencies
* Easier to maintain: Code follow more the netdev way

v3: https://lore.kernel.org/20250723-netconsole_ref-v3-0-8be9b24e4a99@debian.org
v2: https://lore.kernel.org/20250721-netconsole_ref-v2-0-b42f1833565a@debian.org
v1: https://lore.kernel.org/20250718-netconsole_ref-v1-0-86ef253b7a7a@debian.org
====================

Link: https://patch.msgid.link/20250811-netconsole_ref-v4-0-9c510d8713a2@debian.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+37 -54
+37 -54
drivers/net/netconsole.c
··· 300 300 np_info(np, "remote ethernet address %pM\n", np->remote_mac); 301 301 } 302 302 303 + /* Parse the string and populate the `inet_addr` union. Return 0 if IPv4 is 304 + * populated, 1 if IPv6 is populated, and -1 upon failure. 305 + */ 306 + static int netpoll_parse_ip_addr(const char *str, union inet_addr *addr) 307 + { 308 + const char *end = NULL; 309 + int len; 310 + 311 + len = strlen(str); 312 + if (!len) 313 + return -1; 314 + 315 + if (str[len - 1] == '\n') 316 + len -= 1; 317 + 318 + if (in4_pton(str, len, (void *)addr, -1, &end) > 0 && 319 + (!end || *end == 0 || *end == '\n')) 320 + return 0; 321 + 322 + if (IS_ENABLED(CONFIG_IPV6) && 323 + in6_pton(str, len, (void *)addr, -1, &end) > 0 && 324 + (!end || *end == 0 || *end == '\n')) 325 + return 1; 326 + 327 + return -1; 328 + } 329 + 303 330 #ifdef CONFIG_NETCONSOLE_DYNAMIC 304 331 305 332 /* ··· 757 730 { 758 731 struct netconsole_target *nt = to_target(item); 759 732 ssize_t ret = -EINVAL; 733 + int ipv6; 760 734 761 735 mutex_lock(&dynamic_netconsole_mutex); 762 736 if (nt->enabled) { ··· 766 738 goto out_unlock; 767 739 } 768 740 769 - if (strnchr(buf, count, ':')) { 770 - const char *end; 771 - 772 - if (in6_pton(buf, count, nt->np.local_ip.in6.s6_addr, -1, &end) > 0) { 773 - if (*end && *end != '\n') { 774 - pr_err("invalid IPv6 address at: <%c>\n", *end); 775 - goto out_unlock; 776 - } 777 - nt->np.ipv6 = true; 778 - } else 779 - goto out_unlock; 780 - } else { 781 - if (!nt->np.ipv6) 782 - nt->np.local_ip.ip = in_aton(buf); 783 - else 784 - goto out_unlock; 785 - } 741 + ipv6 = netpoll_parse_ip_addr(buf, &nt->np.local_ip); 742 + if (ipv6 == -1) 743 + goto out_unlock; 744 + nt->np.ipv6 = !!ipv6; 786 745 787 746 ret = strnlen(buf, count); 788 747 out_unlock: ··· 782 767 { 783 768 struct netconsole_target *nt = to_target(item); 784 769 ssize_t ret = -EINVAL; 770 + int ipv6; 785 771 786 772 mutex_lock(&dynamic_netconsole_mutex); 787 773 if (nt->enabled) { ··· 791 775 goto out_unlock; 792 776 } 793 777 794 - if (strnchr(buf, count, ':')) { 795 - const char *end; 796 - 797 - if (in6_pton(buf, count, nt->np.remote_ip.in6.s6_addr, -1, &end) > 0) { 798 - if (*end && *end != '\n') { 799 - pr_err("invalid IPv6 address at: <%c>\n", *end); 800 - goto out_unlock; 801 - } 802 - nt->np.ipv6 = true; 803 - } else 804 - goto out_unlock; 805 - } else { 806 - if (!nt->np.ipv6) 807 - nt->np.remote_ip.ip = in_aton(buf); 808 - else 809 - goto out_unlock; 810 - } 778 + ipv6 = netpoll_parse_ip_addr(buf, &nt->np.remote_ip); 779 + if (ipv6 == -1) 780 + goto out_unlock; 781 + nt->np.ipv6 = !!ipv6; 811 782 812 783 ret = strnlen(buf, count); 813 784 out_unlock: ··· 1743 1740 } 1744 1741 } 1745 1742 spin_unlock_irqrestore(&target_list_lock, flags); 1746 - } 1747 - 1748 - static int netpoll_parse_ip_addr(const char *str, union inet_addr *addr) 1749 - { 1750 - const char *end; 1751 - 1752 - if (!strchr(str, ':') && 1753 - in4_pton(str, -1, (void *)addr, -1, &end) > 0) { 1754 - if (!*end) 1755 - return 0; 1756 - } 1757 - if (in6_pton(str, -1, addr->in6.s6_addr, -1, &end) > 0) { 1758 - #if IS_ENABLED(CONFIG_IPV6) 1759 - if (!*end) 1760 - return 1; 1761 - #else 1762 - return -1; 1763 - #endif 1764 - } 1765 - return -1; 1766 1743 } 1767 1744 1768 1745 static int netconsole_parser_cmdline(struct netpoll *np, char *opt)