* [PATCH net-next 1/7] netpoll: Improve code clarity with explicit struct size calculations
2025-06-27 17:55 [PATCH net-next 0/7] netpoll: Factor out functions from netpoll_send_udp() and add ipv6 selftest Breno Leitao
@ 2025-06-27 17:55 ` Breno Leitao
2025-06-27 17:55 ` [PATCH net-next 2/7] netpoll: factor out UDP checksum calculation into helper Breno Leitao
` (5 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Breno Leitao @ 2025-06-27 17:55 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Andrew Lunn, Shuah Khan
Cc: netdev, linux-kernel, linux-kselftest, Breno Leitao, gustavold
Replace pointer-dereference sizeof() operations with explicit struct names
for improved readability and maintainability. This change:
1. Replaces `sizeof(*udph)` with `sizeof(struct udphdr)`
2. Replaces `sizeof(*ip6h)` with `sizeof(struct ipv6hdr)`
3. Replaces `sizeof(*iph)` with `sizeof(struct iphdr)`
This will make it easy to move code in the upcoming patches.
No functional changes are introduced by this patch.
Signed-off-by: Breno Leitao <leitao@debian.org>
---
net/core/netpoll.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 54f9d505895f6..ac0ae9630654a 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -402,11 +402,11 @@ int netpoll_send_udp(struct netpoll *np, const char *msg, int len)
if (!IS_ENABLED(CONFIG_PREEMPT_RT))
WARN_ON_ONCE(!irqs_disabled());
- udp_len = len + sizeof(*udph);
+ udp_len = len + sizeof(struct udphdr);
if (np->ipv6)
- ip_len = udp_len + sizeof(*ip6h);
+ ip_len = udp_len + sizeof(struct ipv6hdr);
else
- ip_len = udp_len + sizeof(*iph);
+ ip_len = udp_len + sizeof(struct iphdr);
total_len = ip_len + LL_RESERVED_SPACE(np->dev);
@@ -418,7 +418,7 @@ int netpoll_send_udp(struct netpoll *np, const char *msg, int len)
skb_copy_to_linear_data(skb, msg, len);
skb_put(skb, len);
- skb_push(skb, sizeof(*udph));
+ skb_push(skb, sizeof(struct udphdr));
skb_reset_transport_header(skb);
udph = udp_hdr(skb);
udph->source = htons(np->local_port);
@@ -434,7 +434,7 @@ int netpoll_send_udp(struct netpoll *np, const char *msg, int len)
if (udph->check == 0)
udph->check = CSUM_MANGLED_0;
- skb_push(skb, sizeof(*ip6h));
+ skb_push(skb, sizeof(struct ipv6hdr));
skb_reset_network_header(skb);
ip6h = ipv6_hdr(skb);
@@ -461,7 +461,7 @@ int netpoll_send_udp(struct netpoll *np, const char *msg, int len)
if (udph->check == 0)
udph->check = CSUM_MANGLED_0;
- skb_push(skb, sizeof(*iph));
+ skb_push(skb, sizeof(struct iphdr));
skb_reset_network_header(skb);
iph = ip_hdr(skb);
--
2.47.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next 2/7] netpoll: factor out UDP checksum calculation into helper
2025-06-27 17:55 [PATCH net-next 0/7] netpoll: Factor out functions from netpoll_send_udp() and add ipv6 selftest Breno Leitao
2025-06-27 17:55 ` [PATCH net-next 1/7] netpoll: Improve code clarity with explicit struct size calculations Breno Leitao
@ 2025-06-27 17:55 ` Breno Leitao
2025-06-27 17:55 ` [PATCH net-next 3/7] netpoll: factor out IPv6 header setup into push_ipv6() helper Breno Leitao
` (4 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Breno Leitao @ 2025-06-27 17:55 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Andrew Lunn, Shuah Khan
Cc: netdev, linux-kernel, linux-kselftest, Breno Leitao, gustavold
Extract UDP checksum calculation logic from netpoll_send_udp()
into a new static helper function netpoll_udp_checksum(). This
reduces code duplication and improves readability for both IPv4
and IPv6 cases.
No functional change intended.
Signed-off-by: Breno Leitao <leitao@debian.org>
---
net/core/netpoll.c | 41 ++++++++++++++++++++++++++---------------
1 file changed, 26 insertions(+), 15 deletions(-)
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index ac0ae9630654a..24e6ad2da8096 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -372,6 +372,31 @@ static netdev_tx_t __netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
return ret;
}
+static void netpoll_udp_checksum(struct netpoll *np, struct sk_buff *skb,
+ int len)
+{
+ struct udphdr *udph;
+ int udp_len;
+
+ udp_len = len + sizeof(struct udphdr);
+ udph = udp_hdr(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,
+ udp_len, IPPROTO_UDP,
+ csum_partial(udph, udp_len, 0));
+ else
+ udph->check = csum_tcpudp_magic(np->local_ip.ip,
+ np->remote_ip.ip,
+ udp_len, IPPROTO_UDP,
+ csum_partial(udph, udp_len, 0));
+ if (udph->check == 0)
+ udph->check = CSUM_MANGLED_0;
+}
+
netdev_tx_t netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
{
unsigned long flags;
@@ -425,15 +450,8 @@ int netpoll_send_udp(struct netpoll *np, const char *msg, int len)
udph->dest = htons(np->remote_port);
udph->len = htons(udp_len);
- udph->check = 0;
+ netpoll_udp_checksum(np, skb, len);
if (np->ipv6) {
- udph->check = csum_ipv6_magic(&np->local_ip.in6,
- &np->remote_ip.in6,
- udp_len, IPPROTO_UDP,
- csum_partial(udph, udp_len, 0));
- if (udph->check == 0)
- udph->check = CSUM_MANGLED_0;
-
skb_push(skb, sizeof(struct ipv6hdr));
skb_reset_network_header(skb);
ip6h = ipv6_hdr(skb);
@@ -454,13 +472,6 @@ int netpoll_send_udp(struct netpoll *np, const char *msg, int len)
skb_reset_mac_header(skb);
skb->protocol = eth->h_proto = htons(ETH_P_IPV6);
} else {
- udph->check = csum_tcpudp_magic(np->local_ip.ip,
- np->remote_ip.ip,
- udp_len, IPPROTO_UDP,
- csum_partial(udph, udp_len, 0));
- if (udph->check == 0)
- udph->check = CSUM_MANGLED_0;
-
skb_push(skb, sizeof(struct iphdr));
skb_reset_network_header(skb);
iph = ip_hdr(skb);
--
2.47.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next 3/7] netpoll: factor out IPv6 header setup into push_ipv6() helper
2025-06-27 17:55 [PATCH net-next 0/7] netpoll: Factor out functions from netpoll_send_udp() and add ipv6 selftest Breno Leitao
2025-06-27 17:55 ` [PATCH net-next 1/7] netpoll: Improve code clarity with explicit struct size calculations Breno Leitao
2025-06-27 17:55 ` [PATCH net-next 2/7] netpoll: factor out UDP checksum calculation into helper Breno Leitao
@ 2025-06-27 17:55 ` Breno Leitao
2025-06-27 17:55 ` [PATCH net-next 4/7] netpoll: factor out IPv4 header setup into push_ipv4() helper Breno Leitao
` (3 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Breno Leitao @ 2025-06-27 17:55 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Andrew Lunn, Shuah Khan
Cc: netdev, linux-kernel, linux-kselftest, Breno Leitao, gustavold
Move IPv6 header construction from netpoll_send_udp() into a new
static helper function, push_ipv6(). This refactoring reduces code
duplication and improves readability in netpoll_send_udp().
Signed-off-by: Breno Leitao <leitao@debian.org>
---
net/core/netpoll.c | 49 +++++++++++++++++++++++++++++--------------------
1 file changed, 29 insertions(+), 20 deletions(-)
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 24e6ad2da8096..247a73762fc2c 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -414,6 +414,33 @@ netdev_tx_t netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
}
EXPORT_SYMBOL(netpoll_send_skb);
+static void push_ipv6(struct netpoll *np, struct sk_buff *skb, int len)
+{
+ struct ipv6hdr *ip6h;
+ struct ethhdr *eth;
+
+ skb_push(skb, sizeof(struct ipv6hdr));
+ skb_reset_network_header(skb);
+ ip6h = ipv6_hdr(skb);
+
+ /* ip6h->version = 6; ip6h->priority = 0; */
+ *(unsigned char *)ip6h = 0x60;
+ ip6h->flow_lbl[0] = 0;
+ ip6h->flow_lbl[1] = 0;
+ ip6h->flow_lbl[2] = 0;
+
+ 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;
+
+ eth = skb_push(skb, ETH_HLEN);
+ skb_reset_mac_header(skb);
+ skb->protocol = htons(ETH_P_IPV6);
+ eth->h_proto = htons(ETH_P_IPV6);
+}
+
int netpoll_send_udp(struct netpoll *np, const char *msg, int len)
{
int total_len, ip_len, udp_len;
@@ -422,7 +449,6 @@ int netpoll_send_udp(struct netpoll *np, const char *msg, int len)
struct iphdr *iph;
struct ethhdr *eth;
static atomic_t ip_ident;
- struct ipv6hdr *ip6h;
if (!IS_ENABLED(CONFIG_PREEMPT_RT))
WARN_ON_ONCE(!irqs_disabled());
@@ -452,25 +478,8 @@ int netpoll_send_udp(struct netpoll *np, const char *msg, int len)
netpoll_udp_checksum(np, skb, len);
if (np->ipv6) {
- skb_push(skb, sizeof(struct ipv6hdr));
- skb_reset_network_header(skb);
- ip6h = ipv6_hdr(skb);
-
- /* ip6h->version = 6; ip6h->priority = 0; */
- *(unsigned char *)ip6h = 0x60;
- ip6h->flow_lbl[0] = 0;
- ip6h->flow_lbl[1] = 0;
- ip6h->flow_lbl[2] = 0;
-
- 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;
-
- eth = skb_push(skb, ETH_HLEN);
- skb_reset_mac_header(skb);
- skb->protocol = eth->h_proto = htons(ETH_P_IPV6);
+ push_ipv6(np, skb, len);
+ eth = eth_hdr(skb);
} else {
skb_push(skb, sizeof(struct iphdr));
skb_reset_network_header(skb);
--
2.47.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next 4/7] netpoll: factor out IPv4 header setup into push_ipv4() helper
2025-06-27 17:55 [PATCH net-next 0/7] netpoll: Factor out functions from netpoll_send_udp() and add ipv6 selftest Breno Leitao
` (2 preceding siblings ...)
2025-06-27 17:55 ` [PATCH net-next 3/7] netpoll: factor out IPv6 header setup into push_ipv6() helper Breno Leitao
@ 2025-06-27 17:55 ` Breno Leitao
2025-06-27 17:55 ` [PATCH net-next 5/7] netpoll: factor out UDP header setup into push_udp() helper Breno Leitao
` (2 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Breno Leitao @ 2025-06-27 17:55 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Andrew Lunn, Shuah Khan
Cc: netdev, linux-kernel, linux-kselftest, Breno Leitao, gustavold
Move IPv4 header construction from netpoll_send_udp() into a new
static helper function push_ipv4(). This completes the refactoring
started with IPv6 header handling, creating symmetric helper functions
for both IP versions.
Changes include:
1. Extracting IPv4 header setup logic into push_ipv4()
2. Replacing inline IPv4 code with helper call
3. Moving eth assignment after helper calls for consistency
The refactoring reduces code duplication and improves maintainability
by isolating IP version-specific logic.
Signed-off-by: Breno Leitao <leitao@debian.org>
---
net/core/netpoll.c | 62 +++++++++++++++++++++++++++++++-----------------------
1 file changed, 36 insertions(+), 26 deletions(-)
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 247a73762fc2c..ff64e94df5351 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -441,14 +441,44 @@ static void push_ipv6(struct netpoll *np, struct sk_buff *skb, int len)
eth->h_proto = htons(ETH_P_IPV6);
}
+static void push_ipv4(struct netpoll *np, struct sk_buff *skb, int len)
+{
+ static atomic_t ip_ident;
+ struct ethhdr *eth;
+ struct iphdr *iph;
+ int ip_len;
+
+ ip_len = len + sizeof(struct udphdr) + sizeof(struct iphdr);
+
+ skb_push(skb, sizeof(struct iphdr));
+ skb_reset_network_header(skb);
+ iph = ip_hdr(skb);
+
+ /* iph->version = 4; iph->ihl = 5; */
+ *(unsigned char *)iph = 0x45;
+ iph->tos = 0;
+ put_unaligned(htons(ip_len), &iph->tot_len);
+ iph->id = htons(atomic_inc_return(&ip_ident));
+ iph->frag_off = 0;
+ 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);
+ iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
+
+ eth = skb_push(skb, ETH_HLEN);
+ skb_reset_mac_header(skb);
+ skb->protocol = htons(ETH_P_IP);
+ eth->h_proto = htons(ETH_P_IP);
+}
+
int netpoll_send_udp(struct netpoll *np, const char *msg, int len)
{
int total_len, ip_len, udp_len;
struct sk_buff *skb;
struct udphdr *udph;
- struct iphdr *iph;
struct ethhdr *eth;
- static atomic_t ip_ident;
if (!IS_ENABLED(CONFIG_PREEMPT_RT))
WARN_ON_ONCE(!irqs_disabled());
@@ -477,32 +507,12 @@ int netpoll_send_udp(struct netpoll *np, const char *msg, int len)
udph->len = htons(udp_len);
netpoll_udp_checksum(np, skb, len);
- if (np->ipv6) {
+ if (np->ipv6)
push_ipv6(np, skb, len);
- eth = eth_hdr(skb);
- } else {
- skb_push(skb, sizeof(struct iphdr));
- skb_reset_network_header(skb);
- iph = ip_hdr(skb);
-
- /* iph->version = 4; iph->ihl = 5; */
- *(unsigned char *)iph = 0x45;
- iph->tos = 0;
- put_unaligned(htons(ip_len), &(iph->tot_len));
- iph->id = htons(atomic_inc_return(&ip_ident));
- iph->frag_off = 0;
- 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));
- iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
-
- eth = skb_push(skb, ETH_HLEN);
- skb_reset_mac_header(skb);
- skb->protocol = eth->h_proto = htons(ETH_P_IP);
- }
+ else
+ push_ipv4(np, skb, len);
+ eth = eth_hdr(skb);
ether_addr_copy(eth->h_source, np->dev->dev_addr);
ether_addr_copy(eth->h_dest, np->remote_mac);
--
2.47.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next 5/7] netpoll: factor out UDP header setup into push_udp() helper
2025-06-27 17:55 [PATCH net-next 0/7] netpoll: Factor out functions from netpoll_send_udp() and add ipv6 selftest Breno Leitao
` (3 preceding siblings ...)
2025-06-27 17:55 ` [PATCH net-next 4/7] netpoll: factor out IPv4 header setup into push_ipv4() helper Breno Leitao
@ 2025-06-27 17:55 ` Breno Leitao
2025-06-27 17:55 ` [PATCH net-next 6/7] netpoll: move Ethernet setup to push_eth() helper Breno Leitao
2025-06-27 17:55 ` [PATCH net-next 7/7] selftests: net: Add IPv6 support to netconsole basic tests Breno Leitao
6 siblings, 0 replies; 10+ messages in thread
From: Breno Leitao @ 2025-06-27 17:55 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Andrew Lunn, Shuah Khan
Cc: netdev, linux-kernel, linux-kselftest, Breno Leitao, gustavold
Move UDP header construction from netpoll_send_udp() into a new
static helper function push_udp(). This completes the protocol
layer refactoring by:
1. Creating a dedicated helper for UDP header assembly
2. Removing UDP-specific logic from the main send function
3. Establishing a consistent pattern with existing IPv4/IPv6 helpers:
- push_udp()
- push_ipv4()
- push_ipv6()
The change improves code organization and maintains the encapsulation
pattern established in previous refactorings.
Signed-off-by: Breno Leitao <leitao@debian.org>
---
net/core/netpoll.c | 28 +++++++++++++++++++---------
1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index ff64e94df5351..70035e27d91cc 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -473,11 +473,28 @@ static void push_ipv4(struct netpoll *np, struct sk_buff *skb, int len)
eth->h_proto = htons(ETH_P_IP);
}
+static void push_udp(struct netpoll *np, struct sk_buff *skb, int len)
+{
+ struct udphdr *udph;
+ int udp_len;
+
+ udp_len = len + sizeof(struct udphdr);
+
+ skb_push(skb, sizeof(struct udphdr));
+ skb_reset_transport_header(skb);
+
+ udph = udp_hdr(skb);
+ udph->source = htons(np->local_port);
+ udph->dest = htons(np->remote_port);
+ udph->len = htons(udp_len);
+
+ netpoll_udp_checksum(np, skb, len);
+}
+
int netpoll_send_udp(struct netpoll *np, const char *msg, int len)
{
int total_len, ip_len, udp_len;
struct sk_buff *skb;
- struct udphdr *udph;
struct ethhdr *eth;
if (!IS_ENABLED(CONFIG_PREEMPT_RT))
@@ -499,14 +516,7 @@ int netpoll_send_udp(struct netpoll *np, const char *msg, int len)
skb_copy_to_linear_data(skb, msg, len);
skb_put(skb, len);
- skb_push(skb, sizeof(struct udphdr));
- skb_reset_transport_header(skb);
- udph = udp_hdr(skb);
- udph->source = htons(np->local_port);
- udph->dest = htons(np->remote_port);
- udph->len = htons(udp_len);
-
- netpoll_udp_checksum(np, skb, len);
+ push_udp(np, skb, len);
if (np->ipv6)
push_ipv6(np, skb, len);
else
--
2.47.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH net-next 6/7] netpoll: move Ethernet setup to push_eth() helper
2025-06-27 17:55 [PATCH net-next 0/7] netpoll: Factor out functions from netpoll_send_udp() and add ipv6 selftest Breno Leitao
` (4 preceding siblings ...)
2025-06-27 17:55 ` [PATCH net-next 5/7] netpoll: factor out UDP header setup into push_udp() helper Breno Leitao
@ 2025-06-27 17:55 ` Breno Leitao
2025-07-02 0:53 ` Jakub Kicinski
2025-06-27 17:55 ` [PATCH net-next 7/7] selftests: net: Add IPv6 support to netconsole basic tests Breno Leitao
6 siblings, 1 reply; 10+ messages in thread
From: Breno Leitao @ 2025-06-27 17:55 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Andrew Lunn, Shuah Khan
Cc: netdev, linux-kernel, linux-kselftest, Breno Leitao, gustavold
Refactor Ethernet header population into dedicated function, completing
the layered abstraction with:
- push_eth() for link layer
- push_udp() for transport
- push_ipv4()/push_ipv6() for network
Signed-off-by: Breno Leitao <leitao@debian.org>
---
net/core/netpoll.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 70035e27d91cc..9ab3cf78a393c 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -491,11 +491,19 @@ static void push_udp(struct netpoll *np, struct sk_buff *skb, int len)
netpoll_udp_checksum(np, skb, len);
}
+static void push_eth(struct netpoll *np, struct sk_buff *skb)
+{
+ struct ethhdr *eth;
+
+ eth = eth_hdr(skb);
+ ether_addr_copy(eth->h_source, np->dev->dev_addr);
+ ether_addr_copy(eth->h_dest, np->remote_mac);
+}
+
int netpoll_send_udp(struct netpoll *np, const char *msg, int len)
{
int total_len, ip_len, udp_len;
struct sk_buff *skb;
- struct ethhdr *eth;
if (!IS_ENABLED(CONFIG_PREEMPT_RT))
WARN_ON_ONCE(!irqs_disabled());
@@ -521,11 +529,7 @@ int netpoll_send_udp(struct netpoll *np, const char *msg, int len)
push_ipv6(np, skb, len);
else
push_ipv4(np, skb, len);
-
- eth = eth_hdr(skb);
- ether_addr_copy(eth->h_source, np->dev->dev_addr);
- ether_addr_copy(eth->h_dest, np->remote_mac);
-
+ push_eth(np, skb);
skb->dev = np->dev;
return (int)netpoll_send_skb(np, skb);
--
2.47.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH net-next 6/7] netpoll: move Ethernet setup to push_eth() helper
2025-06-27 17:55 ` [PATCH net-next 6/7] netpoll: move Ethernet setup to push_eth() helper Breno Leitao
@ 2025-07-02 0:53 ` Jakub Kicinski
2025-07-02 9:25 ` Breno Leitao
0 siblings, 1 reply; 10+ messages in thread
From: Jakub Kicinski @ 2025-07-02 0:53 UTC (permalink / raw)
To: Breno Leitao
Cc: David S. Miller, Eric Dumazet, Paolo Abeni, Simon Horman,
Andrew Lunn, Shuah Khan, netdev, linux-kernel, linux-kselftest,
gustavold
On Fri, 27 Jun 2025 10:55:52 -0700 Breno Leitao wrote:
> +static void push_eth(struct netpoll *np, struct sk_buff *skb)
> +{
> + struct ethhdr *eth;
> +
> + eth = eth_hdr(skb);
> + ether_addr_copy(eth->h_source, np->dev->dev_addr);
> + ether_addr_copy(eth->h_dest, np->remote_mac);
> +}
Can you move the pushing of the header and setting h_proto here?
if the goal of the series is to slice up the code per network layer
then its a bit odd for the IP layer handlers to be pushing the L2
header and setting its proto.
Just:
if (np->ipv6)
eth->h_proto = htons(ETH_P_IPV6);
else
eth->h_proto = htons(ETH_P_IP);
no?
Unless there's some complication here that I'm missing...
--
pw-bot: cr
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH net-next 6/7] netpoll: move Ethernet setup to push_eth() helper
2025-07-02 0:53 ` Jakub Kicinski
@ 2025-07-02 9:25 ` Breno Leitao
0 siblings, 0 replies; 10+ messages in thread
From: Breno Leitao @ 2025-07-02 9:25 UTC (permalink / raw)
To: Jakub Kicinski
Cc: David S. Miller, Eric Dumazet, Paolo Abeni, Simon Horman,
Andrew Lunn, Shuah Khan, netdev, linux-kernel, linux-kselftest,
gustavold
On Tue, Jul 01, 2025 at 05:53:25PM -0700, Jakub Kicinski wrote:
> On Fri, 27 Jun 2025 10:55:52 -0700 Breno Leitao wrote:
> > +static void push_eth(struct netpoll *np, struct sk_buff *skb)
> > +{
> > + struct ethhdr *eth;
> > +
> > + eth = eth_hdr(skb);
> > + ether_addr_copy(eth->h_source, np->dev->dev_addr);
> > + ether_addr_copy(eth->h_dest, np->remote_mac);
> > +}
>
> Can you move the pushing of the header and setting h_proto here?
>
> if the goal of the series is to slice up the code per network layer
> then its a bit odd for the IP layer handlers to be pushing the L2
> header and setting its proto.
>
> Just:
>
> if (np->ipv6)
> eth->h_proto = htons(ETH_P_IPV6);
> else
> eth->h_proto = htons(ETH_P_IP);
>
> no?
yes. We can do it. In fact, if we want to do even better, we can move
the can move the skb_push(skb, ETH_HLEN) and skb_reset_mac_header() here
as well. This will slice up the code even better.
The function will look like the following:
static void push_eth(struct netpoll *np, struct sk_buff *skb)
{
struct ethhdr *eth;
eth = skb_push(skb, ETH_HLEN);
skb_reset_mac_header(skb);
ether_addr_copy(eth->h_source, np->dev->dev_addr);
ether_addr_copy(eth->h_dest, np->remote_mac);
if (np->ipv6)
eth->h_proto = htons(ETH_P_IPV6);
else
eth->h_proto = htons(ETH_P_IP);
}
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH net-next 7/7] selftests: net: Add IPv6 support to netconsole basic tests
2025-06-27 17:55 [PATCH net-next 0/7] netpoll: Factor out functions from netpoll_send_udp() and add ipv6 selftest Breno Leitao
` (5 preceding siblings ...)
2025-06-27 17:55 ` [PATCH net-next 6/7] netpoll: move Ethernet setup to push_eth() helper Breno Leitao
@ 2025-06-27 17:55 ` Breno Leitao
6 siblings, 0 replies; 10+ messages in thread
From: Breno Leitao @ 2025-06-27 17:55 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Andrew Lunn, Shuah Khan
Cc: netdev, linux-kernel, linux-kselftest, Breno Leitao, gustavold
Add IPv6 support to the netconsole basic functionality tests by:
- Introducing separate IPv4 and IPv6 address variables (SRCIP4/SRCIP6,
DSTIP4/DSTIP6) to replace the single SRCIP/DSTIP variables
- Adding select_ipv4_or_ipv6() function to choose protocol version
- Updating socat configuration to use UDP6-LISTEN for IPv6 tests
- Adding wait_for_port() wrapper to handle protocol-specific port waiting
- Expanding test matrix to run both basic and extended formats against
both IPv4 and IPv6 protocols
- Improving cleanup to kill any remaining socat processes
- Adding sleep delays for better IPv6 packet handling reliability
The test now validates netconsole functionality across both IP versions,
improving test coverage for dual-stack network environments.
This test would avoid the regression fixed by commit f59902070269 ("net:
netpoll: Initialize UDP checksum field before checksumming")
Signed-off-by: Breno Leitao <leitao@debian.org>
---
.../selftests/drivers/net/lib/sh/lib_netcons.sh | 74 ++++++++++++++++++++--
.../testing/selftests/drivers/net/netcons_basic.sh | 52 ++++++++-------
2 files changed, 96 insertions(+), 30 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
index 3fcf85a345969..60f968713cad7 100644
--- a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
+++ b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
@@ -11,9 +11,11 @@ set -euo pipefail
LIBDIR=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")")
SRCIF="" # to be populated later
-SRCIP=192.0.2.1
+SRCIP4="192.0.2.1"
+SRCIP6="fc00::1"
DSTIF="" # to be populated later
-DSTIP=192.0.2.2
+DSTIP4="192.0.2.2"
+DSTIP6="fc00::2"
PORT="6666"
MSG="netconsole selftest"
@@ -80,7 +82,23 @@ function configure_ip() {
ip link set "${SRCIF}" up
}
+function select_ipv4_or_ipv6()
+{
+ local VERSION=${1}
+
+ if [[ "$VERSION" == "ipv6" ]]
+ then
+ DSTIP="${DSTIP6}"
+ SRCIP="${SRCIP6}"
+ else
+ DSTIP="${DSTIP4}"
+ SRCIP="${SRCIP4}"
+ fi
+}
+
function set_network() {
+ local IP_VERSION=${1:-"ipv4"}
+
# setup_ns function is coming from lib.sh
setup_ns NAMESPACE
@@ -91,6 +109,7 @@ function set_network() {
# Link both interfaces back to back
link_ifaces
+ select_ipv4_or_ipv6 "${IP_VERSION}"
configure_ip
}
@@ -119,6 +138,11 @@ function create_dynamic_target() {
fi
echo 1 > "${NETCONS_PATH}"/enabled
+
+ # This will make sure that the kernel was able to
+ # load the netconsole driver configuration. The console message
+ # gets more organized/sequential as well.
+ sleep 1
}
# Generate the command line argument for netconsole following:
@@ -179,9 +203,18 @@ function set_user_data() {
function listen_port_and_save_to() {
local OUTPUT=${1}
+ local IPVERSION=${2:-"ipv4"}
+
+ if [ "${IPVERSION}" == "ipv4" ]
+ then
+ SOCAT_MODE="UDP-LISTEN"
+ else
+ SOCAT_MODE="UDP6-LISTEN"
+ fi
+
# Just wait for 2 seconds
timeout 2 ip netns exec "${NAMESPACE}" \
- socat UDP-LISTEN:"${PORT}",fork "${OUTPUT}"
+ socat "${SOCAT_MODE}":"${PORT}",fork "${OUTPUT}"
}
# Only validate that the message arrived properly
@@ -263,8 +296,13 @@ function check_for_dependencies() {
exit "${ksft_skip}"
fi
- if ip addr list | grep -E "inet.*(${SRCIP}|${DSTIP})" 2> /dev/null; then
- echo "SKIP: IPs already in use. Skipping it" >&2
+ if ip addr list | grep -E "inet.*(${SRCIP4}|${DSTIP4})" 2> /dev/null; then
+ echo "SKIP: IPv4s already in use. Skipping it" >&2
+ exit "${ksft_skip}"
+ fi
+
+ if ip addr list | grep -E "inet.*(${SRCIP6}|${DSTIP6})" 2> /dev/null; then
+ echo "SKIP: IPv6s already in use. Skipping it" >&2
exit "${ksft_skip}"
fi
}
@@ -278,11 +316,13 @@ function check_for_taskset() {
# This is necessary if running multiple tests in a row
function pkill_socat() {
- PROCESS_NAME="socat UDP-LISTEN:6666,fork ${OUTPUT_FILE}"
+ PROCESS_NAME4="socat UDP-LISTEN:6666,fork ${OUTPUT_FILE}"
+ PROCESS_NAME6="socat UDP6-LISTEN:6666,fork ${OUTPUT_FILE}"
# socat runs under timeout(1), kill it if it is still alive
# do not fail if socat doesn't exist anymore
set +e
- pkill -f "${PROCESS_NAME}"
+ pkill -f "${PROCESS_NAME4}"
+ pkill -f "${PROCESS_NAME6}"
set -e
}
@@ -294,3 +334,23 @@ function check_netconsole_module() {
exit "${ksft_skip}"
fi
}
+
+# A wrapper to translate protocol version to udp version
+function wait_for_port() {
+ local NAMESPACE=${1}
+ local PORT=${2}
+ IP_VERSION=${3}
+
+ if [ "${IP_VERSION}" == "ipv6" ]
+ then
+ PROTOCOL="udp6"
+ else
+ PROTOCOL="udp"
+ fi
+
+ wait_local_port_listen "${NAMESPACE}" "${PORT}" "${PROTOCOL}"
+ # even after the port is open, let's wait 1 second before writing
+ # otherwise the packet could be missed, and the test will fail. Happens
+ # more frequently on IPv6
+ sleep 1
+}
diff --git a/tools/testing/selftests/drivers/net/netcons_basic.sh b/tools/testing/selftests/drivers/net/netcons_basic.sh
index 40a6ac6191b8b..c627993dc8605 100755
--- a/tools/testing/selftests/drivers/net/netcons_basic.sh
+++ b/tools/testing/selftests/drivers/net/netcons_basic.sh
@@ -36,30 +36,36 @@ trap cleanup EXIT
# Run the test twice, with different format modes
for FORMAT in "basic" "extended"
do
- echo "Running with target mode: ${FORMAT}"
- # Create one namespace and two interfaces
- set_network
- # Create a dynamic target for netconsole
- create_dynamic_target "${FORMAT}"
- # Only set userdata for extended format
- if [ "$FORMAT" == "extended" ]
- then
- # Set userdata "key" with the "value" value
- set_user_data
- fi
- # Listed for netconsole port inside the namespace and destination interface
- listen_port_and_save_to "${OUTPUT_FILE}" &
- # Wait for socat to start and listen to the port.
- wait_local_port_listen "${NAMESPACE}" "${PORT}" udp
- # Send the message
- echo "${MSG}: ${TARGET}" > /dev/kmsg
- # Wait until socat saves the file to disk
- busywait "${BUSYWAIT_TIMEOUT}" test -s "${OUTPUT_FILE}"
+ for IP_VERSION in "ipv6" "ipv4"
+ do
+ echo "Running with target mode: ${FORMAT} (${IP_VERSION})"
+ # Create one namespace and two interfaces
+ set_network "${IP_VERSION}"
+ # Create a dynamic target for netconsole
+ create_dynamic_target "${FORMAT}"
+ # Only set userdata for extended format
+ if [ "$FORMAT" == "extended" ]
+ then
+ # Set userdata "key" with the "value" value
+ set_user_data
+ fi
+ # Listed for netconsole port inside the namespace and destination interface
+ listen_port_and_save_to "${OUTPUT_FILE}" "${IP_VERSION}" &
+ # Wait for socat to start and listen to the port.
+ wait_for_port "${NAMESPACE}" "${PORT}" "${IP_VERSION}"
+ # Send the message
+ echo "${MSG}: ${TARGET}" > /dev/kmsg
+ # Wait until socat saves the file to disk
+ busywait "${BUSYWAIT_TIMEOUT}" test -s "${OUTPUT_FILE}"
- # Make sure the message was received in the dst part
- # and exit
- validate_result "${OUTPUT_FILE}" "${FORMAT}"
- cleanup
+ # Make sure the message was received in the dst part
+ # and exit
+ validate_result "${OUTPUT_FILE}" "${FORMAT}"
+ # kill socat in case it is still running
+ pkill_socat
+ cleanup
+ echo "${FORMAT} : ${IP_VERSION} : Test passed" >&2
+ done
done
trap - EXIT
--
2.47.1
^ permalink raw reply related [flat|nested] 10+ messages in thread