Netdev List
 help / color / mirror / Atom feed
From: Breno Leitao <leitao@debian.org>
To: "David S. Miller" <davem@davemloft.net>,
	 Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>,
	 Paolo Abeni <pabeni@redhat.com>, Simon Horman <horms@kernel.org>,
	 Andrew Lunn <andrew+netdev@lunn.ch>
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	 gustavold@gmail.com, asantostc@gmail.com,
	Breno Leitao <leitao@debian.org>,
	 kernel-team@meta.com
Subject: [PATCH net-next 8/9] netconsole: move local_ip/remote_ip/ipv6 to netconsole_target
Date: Fri, 24 Jul 2026 08:04:16 -0700	[thread overview]
Message-ID: <20260724-netconsole_move_more_final-v1-8-a5f7691db81c@debian.org> (raw)
In-Reply-To: <20260724-netconsole_move_more_final-v1-0-a5f7691db81c@debian.org>

With netpoll_setup() and the packet-building path now living in
netconsole, local_ip, remote_ip and ipv6 in struct netpoll are read
and written only by netconsole. No other netpoll user touches them.

Move the three fields into netconsole_target and switch the packet
builders and setup helpers to take the target instead of the netpoll
handle. struct netpoll is left holding only the device-binding state
that the shared netpoll transport needs.

Signed-off-by: Breno Leitao <leitao@debian.org>
---
 drivers/net/netconsole.c | 143 +++++++++++++++++++++++++----------------------
 include/linux/netpoll.h  |   3 -
 2 files changed, 76 insertions(+), 70 deletions(-)

diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index fc575adc29bd7..199d0e1ac17b2 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -177,9 +177,10 @@ enum target_state {
  * @np:		The netpoll structure for this target.
  *		Contains the other userspace visible parameters:
  *		dev_name	(read-write)
- *		local_ip	(read-write)
- *		remote_ip	(read-write)
  *		local_mac	(read-only)
+ * @local_ip:	Source IP address of the target (read-write).
+ * @remote_ip:	Destination IP address of the target (read-write).
+ * @ipv6:	Whether the target addresses are IPv6 (read-write).
  * @local_port:	Source UDP port of the target (read-write).
  * @remote_port: Destination UDP port of the target (read-write).
  * @remote_mac:	Destination ethernet address of the target (read-write).
@@ -210,6 +211,8 @@ struct netconsole_target {
 	bool			extended;
 	bool			release;
 	struct netpoll		np;
+	union inet_addr		local_ip, remote_ip;
+	bool			ipv6;
 	u16			local_port, remote_port;
 	u8			remote_mac[ETH_ALEN];
 	/* protected by target_list_lock; +1 gives scnprintf() room for its
@@ -370,11 +373,13 @@ static char *netcons_egress_dev(struct netpoll *np, char *buf, size_t bufsz)
 }
 
 /*
- * Take the IPv6 from ndev and populate local_ip structure in netpoll
+ * Populate the target's local_ip with the IPv6 address from ndev.
  */
-static int netcons_take_ipv6(struct netpoll *np, struct net_device *ndev)
+static int netcons_take_ipv6(struct netconsole_target *nt,
+			     struct net_device *ndev)
 {
 	char buf[MAC_ADDR_STR_LEN + 1];
+	struct netpoll *np = &nt->np;
 	int err = -EDESTADDRREQ;
 	struct inet6_dev *idev;
 
@@ -391,10 +396,10 @@ static int netcons_take_ipv6(struct netpoll *np, struct net_device *ndev)
 		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))
+				!!(ipv6_addr_type(&nt->remote_ip.in6) & IPV6_ADDR_LINKLOCAL))
 				continue;
 			/* Got the IP, let's return */
-			np->local_ip.in6 = ifp->addr;
+			nt->local_ip.in6 = ifp->addr;
 			err = 0;
 			break;
 		}
@@ -406,16 +411,18 @@ static int netcons_take_ipv6(struct netpoll *np, struct net_device *ndev)
 		return err;
 	}
 
-	np_info(np, "local IPv6 %pI6c\n", &np->local_ip.in6);
+	np_info(np, "local IPv6 %pI6c\n", &nt->local_ip.in6);
 	return 0;
 }
 
 /*
- * Take the IPv4 from ndev and populate local_ip structure in netpoll
+ * Populate the target's local_ip with the IPv4 address from ndev.
  */
-static int netcons_take_ipv4(struct netpoll *np, struct net_device *ndev)
+static int netcons_take_ipv4(struct netconsole_target *nt,
+			     struct net_device *ndev)
 {
 	char buf[MAC_ADDR_STR_LEN + 1];
+	struct netpoll *np = &nt->np;
 	const struct in_ifaddr *ifa;
 	struct in_device *in_dev;
 
@@ -433,34 +440,35 @@ static int netcons_take_ipv4(struct netpoll *np, struct net_device *ndev)
 		return -EDESTADDRREQ;
 	}
 
-	np->local_ip.ip = ifa->ifa_local;
-	np_info(np, "local IP %pI4\n", &np->local_ip.ip);
+	nt->local_ip.ip = ifa->ifa_local;
+	np_info(np, "local IP %pI4\n", &nt->local_ip.ip);
 
 	return 0;
 }
 
 /*
- * Test whether the caller left np->local_ip unset, so that
+ * Test whether the caller left nt->local_ip unset, so that
  * netcons_netpoll_setup() should auto-populate it from the egress device.
  *
- * np->local_ip is a union of __be32 (IPv4) and struct in6_addr (IPv6),
+ * nt->local_ip is a union of __be32 (IPv4) and struct in6_addr (IPv6),
  * so an IPv6 address whose first 4 bytes are zero (e.g. ::1, ::2,
  * IPv4-mapped ::ffff:a.b.c.d) must not be tested via the IPv4 arm —
  * doing so would misclassify a caller-supplied address as unset and
  * silently overwrite it with whatever address the device exposes.
  */
-static bool netcons_local_ip_unset(const struct netpoll *np)
+static bool netcons_local_ip_unset(const struct netconsole_target *nt)
 {
-	if (np->ipv6)
-		return ipv6_addr_any(&np->local_ip.in6);
-	return !np->local_ip.ip;
+	if (nt->ipv6)
+		return ipv6_addr_any(&nt->local_ip.in6);
+	return !nt->local_ip.ip;
 }
 
-static int netcons_netpoll_setup(struct netpoll *np)
+static int netcons_netpoll_setup(struct netconsole_target *nt)
 {
 	struct net *net = current->nsproxy->net_ns;
 	char buf[MAC_ADDR_STR_LEN + 1];
 	struct net_device *ndev = NULL;
+	struct netpoll *np = &nt->np;
 	bool ip_overwritten = false;
 	int err;
 
@@ -500,13 +508,13 @@ static int netcons_netpoll_setup(struct netpoll *np)
 		rtnl_lock();
 	}
 
-	if (netcons_local_ip_unset(np)) {
-		if (!np->ipv6) {
-			err = netcons_take_ipv4(np, ndev);
+	if (netcons_local_ip_unset(nt)) {
+		if (!nt->ipv6) {
+			err = netcons_take_ipv4(nt, ndev);
 			if (err)
 				goto put;
 		} else {
-			err = netcons_take_ipv6(np, ndev);
+			err = netcons_take_ipv6(nt, ndev);
 			if (err)
 				goto put;
 		}
@@ -529,7 +537,7 @@ static int netcons_netpoll_setup(struct netpoll *np)
 put:
 	DEBUG_NET_WARN_ON_ONCE(np->dev);
 	if (ip_overwritten)
-		memset(&np->local_ip, 0, sizeof(np->local_ip));
+		memset(&nt->local_ip, 0, sizeof(nt->local_ip));
 	netdev_put(ndev, &np->dev_tracker);
 unlock:
 	rtnl_unlock();
@@ -546,7 +554,7 @@ static void resume_target(struct netconsole_target *nt)
 	 */
 	netconsole_skb_pool_init(nt);
 
-	if (netcons_netpoll_setup(&nt->np)) {
+	if (netcons_netpoll_setup(nt)) {
 		/* netpoll fails setup once, do not try again. */
 		netconsole_skb_pool_flush(nt);
 		nt->state = STATE_DISABLED;
@@ -691,17 +699,17 @@ static void netconsole_print_banner(struct netconsole_target *nt)
 	struct netpoll *np = &nt->np;
 
 	np_info(np, "local port %d\n", nt->local_port);
-	if (np->ipv6)
-		np_info(np, "local IPv6 address %pI6c\n", &np->local_ip.in6);
+	if (nt->ipv6)
+		np_info(np, "local IPv6 address %pI6c\n", &nt->local_ip.in6);
 	else
-		np_info(np, "local IPv4 address %pI4\n", &np->local_ip.ip);
+		np_info(np, "local IPv4 address %pI4\n", &nt->local_ip.ip);
 	np_info(np, "interface name '%s'\n", np->dev_name);
 	np_info(np, "local ethernet address '%pM'\n", np->dev_mac);
 	np_info(np, "remote port %d\n", nt->remote_port);
-	if (np->ipv6)
-		np_info(np, "remote IPv6 address %pI6c\n", &np->remote_ip.in6);
+	if (nt->ipv6)
+		np_info(np, "remote IPv6 address %pI6c\n", &nt->remote_ip.in6);
 	else
-		np_info(np, "remote IPv4 address %pI4\n", &np->remote_ip.ip);
+		np_info(np, "remote IPv4 address %pI4\n", &nt->remote_ip.ip);
 	np_info(np, "remote ethernet address %pM\n", nt->remote_mac);
 }
 
@@ -832,20 +840,20 @@ static ssize_t local_ip_show(struct config_item *item, char *buf)
 {
 	struct netconsole_target *nt = to_target(item);
 
-	if (nt->np.ipv6)
-		return sysfs_emit(buf, "%pI6c\n", &nt->np.local_ip.in6);
+	if (nt->ipv6)
+		return sysfs_emit(buf, "%pI6c\n", &nt->local_ip.in6);
 	else
-		return sysfs_emit(buf, "%pI4\n", &nt->np.local_ip);
+		return sysfs_emit(buf, "%pI4\n", &nt->local_ip);
 }
 
 static ssize_t remote_ip_show(struct config_item *item, char *buf)
 {
 	struct netconsole_target *nt = to_target(item);
 
-	if (nt->np.ipv6)
-		return sysfs_emit(buf, "%pI6c\n", &nt->np.remote_ip.in6);
+	if (nt->ipv6)
+		return sysfs_emit(buf, "%pI6c\n", &nt->remote_ip.in6);
 	else
-		return sysfs_emit(buf, "%pI4\n", &nt->np.remote_ip);
+		return sysfs_emit(buf, "%pI4\n", &nt->remote_ip);
 }
 
 static ssize_t local_mac_show(struct config_item *item, char *buf)
@@ -1025,7 +1033,7 @@ static ssize_t enabled_store(struct config_item *item,
 		 */
 		netconsole_skb_pool_init(nt);
 
-		ret = netcons_netpoll_setup(&nt->np);
+		ret = netcons_netpoll_setup(nt);
 		if (ret) {
 			netconsole_skb_pool_flush(nt);
 			goto out_unlock;
@@ -1199,10 +1207,10 @@ static ssize_t local_ip_store(struct config_item *item, const char *buf,
 		goto out_unlock;
 	}
 
-	ipv6 = netpoll_parse_ip_addr(buf, &nt->np.local_ip);
+	ipv6 = netpoll_parse_ip_addr(buf, &nt->local_ip);
 	if (ipv6 == -1)
 		goto out_unlock;
-	nt->np.ipv6 = !!ipv6;
+	nt->ipv6 = !!ipv6;
 
 	ret = count;
 out_unlock:
@@ -1224,10 +1232,10 @@ static ssize_t remote_ip_store(struct config_item *item, const char *buf,
 		goto out_unlock;
 	}
 
-	ipv6 = netpoll_parse_ip_addr(buf, &nt->np.remote_ip);
+	ipv6 = netpoll_parse_ip_addr(buf, &nt->remote_ip);
 	if (ipv6 == -1)
 		goto out_unlock;
-	nt->np.ipv6 = !!ipv6;
+	nt->ipv6 = !!ipv6;
 
 	ret = count;
 out_unlock:
@@ -2027,8 +2035,8 @@ static struct sk_buff *find_skb(struct netconsole_target *nt, int len,
 	return skb;
 }
 
-static void netpoll_udp_checksum(struct netpoll *np, struct sk_buff *skb,
-				 int len)
+static void netpoll_udp_checksum(struct netconsole_target *nt,
+				 struct sk_buff *skb, int len)
 {
 	struct udphdr *udph;
 	int udp_len;
@@ -2038,14 +2046,14 @@ static void netpoll_udp_checksum(struct netpoll *np, struct sk_buff *skb,
 
 	/* check needs to be set, since it will be consumed in csum_partial */
 	udph->check = 0;
-	if (np->ipv6)
-		udph->check = csum_ipv6_magic(&np->local_ip.in6,
-					      &np->remote_ip.in6,
+	if (nt->ipv6)
+		udph->check = csum_ipv6_magic(&nt->local_ip.in6,
+					      &nt->remote_ip.in6,
 					      udp_len, IPPROTO_UDP,
 					      csum_partial(udph, udp_len, 0));
 	else
-		udph->check = csum_tcpudp_magic(np->local_ip.ip,
-						np->remote_ip.ip,
+		udph->check = csum_tcpudp_magic(nt->local_ip.ip,
+						nt->remote_ip.ip,
 						udp_len, IPPROTO_UDP,
 						csum_partial(udph, udp_len, 0));
 	if (udph->check == 0)
@@ -2054,7 +2062,6 @@ static void netpoll_udp_checksum(struct netpoll *np, struct sk_buff *skb,
 
 static void push_udp(struct netconsole_target *nt, struct sk_buff *skb, int len)
 {
-	struct netpoll *np = &nt->np;
 	struct udphdr *udph;
 	int udp_len;
 
@@ -2068,7 +2075,7 @@ static void push_udp(struct netconsole_target *nt, struct sk_buff *skb, int len)
 	udph->dest = htons(nt->remote_port);
 	udp_set_len_short(udph, udp_len);
 
-	netpoll_udp_checksum(np, skb, len);
+	netpoll_udp_checksum(nt, skb, len);
 }
 
 static void push_eth(struct netconsole_target *nt, struct sk_buff *skb)
@@ -2080,13 +2087,14 @@ static void push_eth(struct netconsole_target *nt, struct sk_buff *skb)
 	skb_reset_mac_header(skb);
 	ether_addr_copy(eth->h_source, np->dev->dev_addr);
 	ether_addr_copy(eth->h_dest, nt->remote_mac);
-	if (np->ipv6)
+	if (nt->ipv6)
 		eth->h_proto = htons(ETH_P_IPV6);
 	else
 		eth->h_proto = htons(ETH_P_IP);
 }
 
-static void push_ipv4(struct netpoll *np, struct sk_buff *skb, int len)
+static void push_ipv4(struct netconsole_target *nt, struct sk_buff *skb,
+		      int len)
 {
 	static atomic_t ip_ident;
 	struct iphdr *iph;
@@ -2107,13 +2115,14 @@ static void push_ipv4(struct netpoll *np, struct sk_buff *skb, int len)
 	iph->ttl = 64;
 	iph->protocol = IPPROTO_UDP;
 	iph->check = 0;
-	put_unaligned(np->local_ip.ip, &iph->saddr);
-	put_unaligned(np->remote_ip.ip, &iph->daddr);
+	put_unaligned(nt->local_ip.ip, &iph->saddr);
+	put_unaligned(nt->remote_ip.ip, &iph->daddr);
 	iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
 	skb->protocol = htons(ETH_P_IP);
 }
 
-static void push_ipv6(struct netpoll *np, struct sk_buff *skb, int len)
+static void push_ipv6(struct netconsole_target *nt, struct sk_buff *skb,
+		      int len)
 {
 	struct ipv6hdr *ip6h;
 
@@ -2130,8 +2139,8 @@ static void push_ipv6(struct netpoll *np, struct sk_buff *skb, int len)
 	ip6h->payload_len = htons(sizeof(struct udphdr) + len);
 	ip6h->nexthdr = IPPROTO_UDP;
 	ip6h->hop_limit = 32;
-	ip6h->saddr = np->local_ip.in6;
-	ip6h->daddr = np->remote_ip.in6;
+	ip6h->saddr = nt->local_ip.in6;
+	ip6h->daddr = nt->remote_ip.in6;
 
 	skb->protocol = htons(ETH_P_IPV6);
 }
@@ -2147,7 +2156,7 @@ static int netpoll_send_udp(struct netconsole_target *nt, const char *msg,
 		WARN_ON_ONCE(!irqs_disabled());
 
 	udp_len = len + sizeof(struct udphdr);
-	if (np->ipv6)
+	if (nt->ipv6)
 		ip_len = udp_len + sizeof(struct ipv6hdr);
 	else
 		ip_len = udp_len + sizeof(struct iphdr);
@@ -2163,10 +2172,10 @@ static int netpoll_send_udp(struct netconsole_target *nt, const char *msg,
 	skb_put(skb, len);
 
 	push_udp(nt, skb, len);
-	if (np->ipv6)
-		push_ipv6(np, skb, len);
+	if (nt->ipv6)
+		push_ipv6(nt, skb, len);
 	else
-		push_ipv4(np, skb, len);
+		push_ipv4(nt, skb, len);
 	push_eth(nt, skb);
 	skb->dev = np->dev;
 
@@ -2505,11 +2514,11 @@ static int netconsole_parser_cmdline(struct netconsole_target *nt, char *opt)
 		if (!delim)
 			goto parse_failed;
 		*delim = 0;
-		ipv6 = netpoll_parse_ip_addr(cur, &np->local_ip);
+		ipv6 = netpoll_parse_ip_addr(cur, &nt->local_ip);
 		if (ipv6 < 0)
 			goto parse_failed;
 		else
-			np->ipv6 = (bool)ipv6;
+			nt->ipv6 = (bool)ipv6;
 		cur = delim;
 	}
 	cur++;
@@ -2551,13 +2560,13 @@ static int netconsole_parser_cmdline(struct netconsole_target *nt, char *opt)
 	if (!delim)
 		goto parse_failed;
 	*delim = 0;
-	ipv6 = netpoll_parse_ip_addr(cur, &np->remote_ip);
+	ipv6 = netpoll_parse_ip_addr(cur, &nt->remote_ip);
 	if (ipv6 < 0)
 		goto parse_failed;
-	else if (ipversion_set && np->ipv6 != (bool)ipv6)
+	else if (ipversion_set && nt->ipv6 != (bool)ipv6)
 		goto parse_failed;
 	else
-		np->ipv6 = (bool)ipv6;
+		nt->ipv6 = (bool)ipv6;
 	cur = delim + 1;
 
 	if (*cur != 0) {
@@ -2615,7 +2624,7 @@ static struct netconsole_target *alloc_param_target(char *target_config,
 	 */
 	netconsole_skb_pool_init(nt);
 
-	err = netcons_netpoll_setup(&nt->np);
+	err = netcons_netpoll_setup(nt);
 	if (err) {
 		pr_err("Not enabling netconsole for %s%d. Netpoll setup failed\n",
 		       NETCONSOLE_PARAM_TARGET_PREFIX, cmdline_count);
diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h
index dac8dc2529de0..ef88a30b11f40 100644
--- a/include/linux/netpoll.h
+++ b/include/linux/netpoll.h
@@ -32,9 +32,6 @@ struct netpoll {
 	char dev_name[IFNAMSIZ];
 	u8 dev_mac[ETH_ALEN];
 	const char *name;
-
-	union inet_addr local_ip, remote_ip;
-	bool ipv6;
 };
 
 #define np_info(np, fmt, ...)				\

-- 
2.53.0-Meta


  parent reply	other threads:[~2026-07-24 15:05 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-24 15:04 [PATCH net-next 0/9] netpoll: finish untangling netconsole from netpoll Breno Leitao
2026-07-24 15:04 ` [PATCH net-next 1/9] netpoll: export carrier_timeout via netpoll_get_carrier_timeout() Breno Leitao
2026-07-24 15:04 ` [PATCH net-next 2/9] netpoll: export the netpoll_setup() helpers for netconsole Breno Leitao
2026-07-24 15:04 ` [PATCH net-next 3/9] netconsole: take over netpoll_setup() from netpoll Breno Leitao
2026-07-24 15:04 ` [PATCH net-next 4/9] netconsole: move netpoll_local_ip_unset() as netcons_local_ip_unset() Breno Leitao
2026-07-24 15:04 ` [PATCH net-next 5/9] netconsole: move netpoll_take_ipv4() as netcons_take_ipv4() Breno Leitao
2026-07-24 15:04 ` [PATCH net-next 6/9] netconsole: move netpoll_take_ipv6() as netcons_take_ipv6() Breno Leitao
2026-07-24 15:04 ` [PATCH net-next 7/9] netconsole: move egress_dev() as netcons_egress_dev() Breno Leitao
2026-07-24 15:04 ` Breno Leitao [this message]
2026-07-24 15:04 ` [PATCH net-next 9/9] netconsole: move netpoll_wait_carrier() as netcons_wait_carrier() Breno Leitao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260724-netconsole_move_more_final-v1-8-a5f7691db81c@debian.org \
    --to=leitao@debian.org \
    --cc=andrew+netdev@lunn.ch \
    --cc=asantostc@gmail.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=gustavold@gmail.com \
    --cc=horms@kernel.org \
    --cc=kernel-team@meta.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox