netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net] bonding: fix ICMPv6 header handling when receiving IPv6 messages
@ 2022-11-01  9:13 Hangbin Liu
  2022-11-01 10:12 ` Jay Vosburgh
  0 siblings, 1 reply; 8+ messages in thread
From: Hangbin Liu @ 2022-11-01  9:13 UTC (permalink / raw)
  To: netdev
  Cc: Jay Vosburgh, David S . Miller, Jakub Kicinski, Jonathan Toppins,
	Paolo Abeni, David Ahern, Hangbin Liu, Liang Li

Some drivers, like bnx2x, will call ipv6_gro_receive() and set skb
IPv6 transport header before bond_handle_frame(). But some other drivers,
like be2net, will not call ipv6_gro_receive() and skb transport header
is not set properly. Thus we can't use icmp6_hdr(skb) to get the icmp6
header directly when dealing with IPv6 messages.

Fix this by checking the skb length manually and getting icmp6 header based
on the IPv6 header offset.

Reported-by: Liang Li <liali@redhat.com>
Fixes: 4e24be018eb9 ("bonding: add new parameter ns_targets")
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
---
 drivers/net/bonding/bond_main.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index e84c49bf4d0c..08b5f512f5fb 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3231,12 +3231,23 @@ static int bond_na_rcv(const struct sk_buff *skb, struct bonding *bond,
 		       struct slave *slave)
 {
 	struct slave *curr_active_slave, *curr_arp_slave;
-	struct icmp6hdr *hdr = icmp6_hdr(skb);
+	const struct icmp6hdr *icmp6_hdr;
 	struct in6_addr *saddr, *daddr;
+	const struct ipv6hdr *hdr;
+	u16 pkt_len;
+
+	/* Check if the length is enough manually as we can't use pskb_may_pull */
+	hdr = ipv6_hdr(skb);
+	pkt_len = ntohs(hdr->payload_len);
+	if (hdr->nexthdr != NEXTHDR_ICMP || pkt_len < sizeof(*icmp6_hdr) ||
+	    skb_headlen(skb) < sizeof(*hdr) + pkt_len)
+		goto out;
+
+	icmp6_hdr = (const struct icmp6hdr *)(skb->data + sizeof(*hdr));
 
 	if (skb->pkt_type == PACKET_OTHERHOST ||
 	    skb->pkt_type == PACKET_LOOPBACK ||
-	    hdr->icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT)
+	    icmp6_hdr->icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT)
 		goto out;
 
 	saddr = &ipv6_hdr(skb)->saddr;
-- 
2.38.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH net] bonding: fix ICMPv6 header handling when receiving IPv6 messages
  2022-11-01  9:13 [PATCH net] bonding: fix ICMPv6 header handling when receiving IPv6 messages Hangbin Liu
@ 2022-11-01 10:12 ` Jay Vosburgh
  2022-11-01 13:39   ` Hangbin Liu
  0 siblings, 1 reply; 8+ messages in thread
From: Jay Vosburgh @ 2022-11-01 10:12 UTC (permalink / raw)
  To: Hangbin Liu
  Cc: netdev, David S . Miller, Jakub Kicinski, Jonathan Toppins,
	Paolo Abeni, David Ahern, Liang Li

Hangbin Liu <liuhangbin@gmail.com> wrote:

>Some drivers, like bnx2x, will call ipv6_gro_receive() and set skb
>IPv6 transport header before bond_handle_frame(). But some other drivers,
>like be2net, will not call ipv6_gro_receive() and skb transport header
>is not set properly. Thus we can't use icmp6_hdr(skb) to get the icmp6
>header directly when dealing with IPv6 messages.

	I don't understand this explanation, as ipv6_gro_receive() isn't
called directly by the device drivers, but from within the GRO
processing, e.g., by dev_gro_receive().

	Could you explain how the call paths actually differ?  

	-J

>Fix this by checking the skb length manually and getting icmp6 header based
>on the IPv6 header offset.
>
>Reported-by: Liang Li <liali@redhat.com>
>Fixes: 4e24be018eb9 ("bonding: add new parameter ns_targets")
>Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
>---
> drivers/net/bonding/bond_main.c | 15 +++++++++++++--
> 1 file changed, 13 insertions(+), 2 deletions(-)
>
>diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
>index e84c49bf4d0c..08b5f512f5fb 100644
>--- a/drivers/net/bonding/bond_main.c
>+++ b/drivers/net/bonding/bond_main.c
>@@ -3231,12 +3231,23 @@ static int bond_na_rcv(const struct sk_buff *skb, struct bonding *bond,
> 		       struct slave *slave)
> {
> 	struct slave *curr_active_slave, *curr_arp_slave;
>-	struct icmp6hdr *hdr = icmp6_hdr(skb);
>+	const struct icmp6hdr *icmp6_hdr;
> 	struct in6_addr *saddr, *daddr;
>+	const struct ipv6hdr *hdr;
>+	u16 pkt_len;
>+
>+	/* Check if the length is enough manually as we can't use pskb_may_pull */
>+	hdr = ipv6_hdr(skb);
>+	pkt_len = ntohs(hdr->payload_len);
>+	if (hdr->nexthdr != NEXTHDR_ICMP || pkt_len < sizeof(*icmp6_hdr) ||
>+	    skb_headlen(skb) < sizeof(*hdr) + pkt_len)
>+		goto out;
>+
>+	icmp6_hdr = (const struct icmp6hdr *)(skb->data + sizeof(*hdr));
> 
> 	if (skb->pkt_type == PACKET_OTHERHOST ||
> 	    skb->pkt_type == PACKET_LOOPBACK ||
>-	    hdr->icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT)
>+	    icmp6_hdr->icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT)
> 		goto out;
> 
> 	saddr = &ipv6_hdr(skb)->saddr;
>-- 
>2.38.1
>

---
	-Jay Vosburgh, jay.vosburgh@canonical.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net] bonding: fix ICMPv6 header handling when receiving IPv6 messages
  2022-11-01 10:12 ` Jay Vosburgh
@ 2022-11-01 13:39   ` Hangbin Liu
  2022-11-01 14:17     ` Hangbin Liu
  0 siblings, 1 reply; 8+ messages in thread
From: Hangbin Liu @ 2022-11-01 13:39 UTC (permalink / raw)
  To: Jay Vosburgh
  Cc: netdev, David S . Miller, Jakub Kicinski, Jonathan Toppins,
	Paolo Abeni, David Ahern, Liang Li

On Tue, Nov 01, 2022 at 11:12:43AM +0100, Jay Vosburgh wrote:
> Hangbin Liu <liuhangbin@gmail.com> wrote:
> 
> >Some drivers, like bnx2x, will call ipv6_gro_receive() and set skb
> >IPv6 transport header before bond_handle_frame(). But some other drivers,
> >like be2net, will not call ipv6_gro_receive() and skb transport header
> >is not set properly. Thus we can't use icmp6_hdr(skb) to get the icmp6
> >header directly when dealing with IPv6 messages.
> 
> 	I don't understand this explanation, as ipv6_gro_receive() isn't
> called directly by the device drivers, but from within the GRO
> processing, e.g., by dev_gro_receive().
> 
> 	Could you explain how the call paths actually differ?  

Er..Yes, it's a little weird.

I checked if the transport header is set before  __netif_receive_skb_core().
The bnx2x driver set it while be2net does not. So the transport header is reset
in __netif_receive_skb_core() with be2net.

I also found ipv6_gro_receive() is called before bond_handle_frame() when
receive NA message. Not sure which path it go through. I'm not very familiar
with driver part. But I can do more investigating.

Thanks
Hangbin

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net] bonding: fix ICMPv6 header handling when receiving IPv6 messages
  2022-11-01 13:39   ` Hangbin Liu
@ 2022-11-01 14:17     ` Hangbin Liu
  2022-11-03 16:03       ` Jay Vosburgh
  0 siblings, 1 reply; 8+ messages in thread
From: Hangbin Liu @ 2022-11-01 14:17 UTC (permalink / raw)
  To: Jay Vosburgh
  Cc: netdev, David S . Miller, Jakub Kicinski, Jonathan Toppins,
	Paolo Abeni, David Ahern, Liang Li

On Tue, Nov 01, 2022 at 09:39:22PM +0800, Hangbin Liu wrote:
> > 	I don't understand this explanation, as ipv6_gro_receive() isn't
> > called directly by the device drivers, but from within the GRO
> > processing, e.g., by dev_gro_receive().
> > 
> > 	Could you explain how the call paths actually differ?  
> 
> Er..Yes, it's a little weird.
> 
> I checked if the transport header is set before  __netif_receive_skb_core().
> The bnx2x driver set it while be2net does not. So the transport header is reset
> in __netif_receive_skb_core() with be2net.
> 
> I also found ipv6_gro_receive() is called before bond_handle_frame() when
> receive NA message. Not sure which path it go through. I'm not very familiar
> with driver part. But I can do more investigating.

With dump_stack(), it shows bnx2x do calls ipv6_gro_receive().
PS: I only dump the stack when receive NA.

[   65.537605]  dump_stack_lvl+0x34/0x48
[   65.541695]  ipv6_gro_receive.cold+0x1b/0x3d
[   65.546453]  dev_gro_receive+0x16c/0x380
[   65.550831]  napi_gro_receive+0x64/0x210
[   65.555206]  bnx2x_rx_int+0x44c/0x820 [bnx2x]
[   65.560100]  bnx2x_poll+0xe5/0x1d0 [bnx2x]
[   65.564687]  __napi_poll+0x2c/0x160
[   65.568579]  net_rx_action+0x296/0x350

Thanks
Hangbin

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net] bonding: fix ICMPv6 header handling when receiving IPv6 messages
  2022-11-01 14:17     ` Hangbin Liu
@ 2022-11-03 16:03       ` Jay Vosburgh
  2022-11-04  8:08         ` Hangbin Liu
  0 siblings, 1 reply; 8+ messages in thread
From: Jay Vosburgh @ 2022-11-03 16:03 UTC (permalink / raw)
  To: Hangbin Liu
  Cc: netdev, David S . Miller, Jakub Kicinski, Jonathan Toppins,
	Paolo Abeni, David Ahern, Liang Li

Hangbin Liu <liuhangbin@gmail.com> wrote:

>On Tue, Nov 01, 2022 at 09:39:22PM +0800, Hangbin Liu wrote:
>> > 	I don't understand this explanation, as ipv6_gro_receive() isn't
>> > called directly by the device drivers, but from within the GRO
>> > processing, e.g., by dev_gro_receive().
>> > 
>> > 	Could you explain how the call paths actually differ?  
>> 
>> Er..Yes, it's a little weird.
>> 
>> I checked if the transport header is set before  __netif_receive_skb_core().
>> The bnx2x driver set it while be2net does not. So the transport header is reset
>> in __netif_receive_skb_core() with be2net.
>> 
>> I also found ipv6_gro_receive() is called before bond_handle_frame() when
>> receive NA message. Not sure which path it go through. I'm not very familiar
>> with driver part. But I can do more investigating.

	I suspect that what you're seeing is caused by bnx2x calling
skb_set_transport_header() in bnx2x_gro_ipv6_csum() to explicitly set
the transport header for IPv6, and benet having no equivalent call.  If
benet were to set the transport header, I think it would happen in
be_rx_compl_process_gro().

	__netif_receive_skb_core() calls skb_reset_transport_header() if
the transport header isn't set, but I presume that doesn't do the right
thing for ICMPv6.

	I don't believe there's any expectation that drivers must set
the transport header at this point, so I tentatively think that what
your patch is trying to do is reasonable.

	Briefly looking at the patch, the commit message needs updating,
and I'm curious to know why pskb_may_pull can't be used.

	-J

>With dump_stack(), it shows bnx2x do calls ipv6_gro_receive().
>PS: I only dump the stack when receive NA.
>
>[   65.537605]  dump_stack_lvl+0x34/0x48
>[   65.541695]  ipv6_gro_receive.cold+0x1b/0x3d
>[   65.546453]  dev_gro_receive+0x16c/0x380
>[   65.550831]  napi_gro_receive+0x64/0x210
>[   65.555206]  bnx2x_rx_int+0x44c/0x820 [bnx2x]
>[   65.560100]  bnx2x_poll+0xe5/0x1d0 [bnx2x]
>[   65.564687]  __napi_poll+0x2c/0x160
>[   65.568579]  net_rx_action+0x296/0x350
>
>Thanks
>Hangbin

---
	-Jay Vosburgh, jay.vosburgh@canonical.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net] bonding: fix ICMPv6 header handling when receiving IPv6 messages
  2022-11-03 16:03       ` Jay Vosburgh
@ 2022-11-04  8:08         ` Hangbin Liu
  2022-11-04  8:18           ` Jay Vosburgh
  0 siblings, 1 reply; 8+ messages in thread
From: Hangbin Liu @ 2022-11-04  8:08 UTC (permalink / raw)
  To: Jay Vosburgh
  Cc: netdev, David S . Miller, Jakub Kicinski, Jonathan Toppins,
	Paolo Abeni, David Ahern, Liang Li

On Thu, Nov 03, 2022 at 05:03:59PM +0100, Jay Vosburgh wrote:
> 	Briefly looking at the patch, the commit message needs updating,
> and I'm curious to know why pskb_may_pull can't be used.

Oh, forgot to reply this. pskb_may_pull() need "struct sk_buff *skb" but we
defined "const struct sk_buff *skb" in bond_na_rcv().

Thanks
Hangbin

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net] bonding: fix ICMPv6 header handling when receiving IPv6 messages
  2022-11-04  8:08         ` Hangbin Liu
@ 2022-11-04  8:18           ` Jay Vosburgh
  2022-11-04 11:50             ` Hangbin Liu
  0 siblings, 1 reply; 8+ messages in thread
From: Jay Vosburgh @ 2022-11-04  8:18 UTC (permalink / raw)
  To: Hangbin Liu
  Cc: netdev, David S . Miller, Jakub Kicinski, Jonathan Toppins,
	Paolo Abeni, David Ahern, Liang Li

Hangbin Liu <liuhangbin@gmail.com> wrote:

>On Thu, Nov 03, 2022 at 05:03:59PM +0100, Jay Vosburgh wrote:
>> 	Briefly looking at the patch, the commit message needs updating,
>> and I'm curious to know why pskb_may_pull can't be used.
>
>Oh, forgot to reply this. pskb_may_pull() need "struct sk_buff *skb" but we
>defined "const struct sk_buff *skb" in bond_na_rcv().

	Perhaps you could use skb_header_pointer(), similarly to what is
done in bond_3ad_lacpdu_recv() or rlb_arp_recv()?

	-J

---
	-Jay Vosburgh, jay.vosburgh@canonical.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net] bonding: fix ICMPv6 header handling when receiving IPv6 messages
  2022-11-04  8:18           ` Jay Vosburgh
@ 2022-11-04 11:50             ` Hangbin Liu
  0 siblings, 0 replies; 8+ messages in thread
From: Hangbin Liu @ 2022-11-04 11:50 UTC (permalink / raw)
  To: Jay Vosburgh
  Cc: netdev, David S . Miller, Jakub Kicinski, Jonathan Toppins,
	Paolo Abeni, David Ahern, Liang Li

On Fri, Nov 04, 2022 at 09:18:52AM +0100, Jay Vosburgh wrote:
> Hangbin Liu <liuhangbin@gmail.com> wrote:
> 
> >On Thu, Nov 03, 2022 at 05:03:59PM +0100, Jay Vosburgh wrote:
> >> 	Briefly looking at the patch, the commit message needs updating,
> >> and I'm curious to know why pskb_may_pull can't be used.
> >
> >Oh, forgot to reply this. pskb_may_pull() need "struct sk_buff *skb" but we
> >defined "const struct sk_buff *skb" in bond_na_rcv().
> 
> 	Perhaps you could use skb_header_pointer(), similarly to what is
> done in bond_3ad_lacpdu_recv() or rlb_arp_recv()?

Cool, Thanks Jay. This saves my lumbering checking.

Cheers
Hangbin

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2022-11-04 11:50 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-11-01  9:13 [PATCH net] bonding: fix ICMPv6 header handling when receiving IPv6 messages Hangbin Liu
2022-11-01 10:12 ` Jay Vosburgh
2022-11-01 13:39   ` Hangbin Liu
2022-11-01 14:17     ` Hangbin Liu
2022-11-03 16:03       ` Jay Vosburgh
2022-11-04  8:08         ` Hangbin Liu
2022-11-04  8:18           ` Jay Vosburgh
2022-11-04 11:50             ` Hangbin Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).