summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2025-08-12 17:32:44 -0700
committerJakub Kicinski <kuba@kernel.org>2025-08-12 17:32:45 -0700
commitb1987f1e05b7dd2e08b51967cc187dbe8092cbd9 (patch)
tree0edd443ab6774e01d441e8fec603da0a59396979
parent75f26257667588260d067fa022ebd6ac39b4a9c1 (diff)
parent4aeb452c237afa6d7e8d09185bca6e34454ca333 (diff)
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>
-rw-r--r--drivers/net/netconsole.c91
1 files changed, 37 insertions, 54 deletions
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index e3722de08ea9..194570443493 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -300,6 +300,33 @@ static void netconsole_print_banner(struct netpoll *np)
np_info(np, "remote ethernet address %pM\n", np->remote_mac);
}
+/* Parse the string and populate the `inet_addr` union. Return 0 if IPv4 is
+ * populated, 1 if IPv6 is populated, and -1 upon failure.
+ */
+static int netpoll_parse_ip_addr(const char *str, union inet_addr *addr)
+{
+ const char *end = NULL;
+ int len;
+
+ len = strlen(str);
+ if (!len)
+ return -1;
+
+ if (str[len - 1] == '\n')
+ len -= 1;
+
+ if (in4_pton(str, len, (void *)addr, -1, &end) > 0 &&
+ (!end || *end == 0 || *end == '\n'))
+ return 0;
+
+ if (IS_ENABLED(CONFIG_IPV6) &&
+ in6_pton(str, len, (void *)addr, -1, &end) > 0 &&
+ (!end || *end == 0 || *end == '\n'))
+ return 1;
+
+ return -1;
+}
+
#ifdef CONFIG_NETCONSOLE_DYNAMIC
/*
@@ -730,6 +757,7 @@ static ssize_t local_ip_store(struct config_item *item, const char *buf,
{
struct netconsole_target *nt = to_target(item);
ssize_t ret = -EINVAL;
+ int ipv6;
mutex_lock(&dynamic_netconsole_mutex);
if (nt->enabled) {
@@ -738,23 +766,10 @@ static ssize_t local_ip_store(struct config_item *item, const char *buf,
goto out_unlock;
}
- if (strnchr(buf, count, ':')) {
- const char *end;
-
- if (in6_pton(buf, count, nt->np.local_ip.in6.s6_addr, -1, &end) > 0) {
- if (*end && *end != '\n') {
- pr_err("invalid IPv6 address at: <%c>\n", *end);
- goto out_unlock;
- }
- nt->np.ipv6 = true;
- } else
- goto out_unlock;
- } else {
- if (!nt->np.ipv6)
- nt->np.local_ip.ip = in_aton(buf);
- else
- goto out_unlock;
- }
+ ipv6 = netpoll_parse_ip_addr(buf, &nt->np.local_ip);
+ if (ipv6 == -1)
+ goto out_unlock;
+ nt->np.ipv6 = !!ipv6;
ret = strnlen(buf, count);
out_unlock:
@@ -767,6 +782,7 @@ static ssize_t remote_ip_store(struct config_item *item, const char *buf,
{
struct netconsole_target *nt = to_target(item);
ssize_t ret = -EINVAL;
+ int ipv6;
mutex_lock(&dynamic_netconsole_mutex);
if (nt->enabled) {
@@ -775,23 +791,10 @@ static ssize_t remote_ip_store(struct config_item *item, const char *buf,
goto out_unlock;
}
- if (strnchr(buf, count, ':')) {
- const char *end;
-
- if (in6_pton(buf, count, nt->np.remote_ip.in6.s6_addr, -1, &end) > 0) {
- if (*end && *end != '\n') {
- pr_err("invalid IPv6 address at: <%c>\n", *end);
- goto out_unlock;
- }
- nt->np.ipv6 = true;
- } else
- goto out_unlock;
- } else {
- if (!nt->np.ipv6)
- nt->np.remote_ip.ip = in_aton(buf);
- else
- goto out_unlock;
- }
+ ipv6 = netpoll_parse_ip_addr(buf, &nt->np.remote_ip);
+ if (ipv6 == -1)
+ goto out_unlock;
+ nt->np.ipv6 = !!ipv6;
ret = strnlen(buf, count);
out_unlock:
@@ -1742,26 +1745,6 @@ static void write_msg(struct console *con, const char *msg, unsigned int len)
spin_unlock_irqrestore(&target_list_lock, flags);
}
-static int netpoll_parse_ip_addr(const char *str, union inet_addr *addr)
-{
- const char *end;
-
- if (!strchr(str, ':') &&
- in4_pton(str, -1, (void *)addr, -1, &end) > 0) {
- if (!*end)
- return 0;
- }
- if (in6_pton(str, -1, addr->in6.s6_addr, -1, &end) > 0) {
-#if IS_ENABLED(CONFIG_IPV6)
- if (!*end)
- return 1;
-#else
- return -1;
-#endif
- }
- return -1;
-}
-
static int netconsole_parser_cmdline(struct netpoll *np, char *opt)
{
bool ipversion_set = false;