Le jeu. 22 oct. 2026 à 14:43, Ilya Maximets <[email protected]> a écrit : > > On 10/22/26 11:22 AM, Jamal Hadi Salim wrote: > > The issue: > > pop_nsh() restores MAC_PROTO_ETHERNET when the popped NSH next-protocol > > is TUN_P_ETHERNET, but nsh_pop() only guarantees that the NSH header is > > in the linear area. When the inner Ethernet header sits in a page > > fragment, the datapath then claims an Ethernet header it cannot access > > linearly. > > > > Output to an OVS internal vport then calls eth_type_trans(), which > > pulls ETH_HLEN from an empty linear area and triggers the BUG in > > __skb_pull(): > > > > kernel BUG at ./include/linux/skbuff.h:2830! > > RIP: 0010:eth_type_trans+0x335/0x500 > > internal_dev_recv > > ovs_vport_send > > do_output > > do_execute_actions > > ovs_execute_actions > > ovs_dp_process_packet > > ovs_vport_receive > > internal_dev_xmit > > > > Conditions to recreate the bug: > > On a system with 4 KiB pages and CONFIG_OPENVSWITCH and CONFIG_PACKET > > enabled, use CAP_NET_ADMIN to create an OVS datapath and bring its local > > internal port up with MTU 9000. Install a flow matching an Ethernet/NSH > > packet with a 24-byte MD1 header whose next-protocol is TUN_P_ETHERNET, > > and actions pop_eth, pop_nsh, output to the local port. With > > CAP_NET_RAW, send a 4148-byte AF_PACKET/SOCK_RAW frame containing outer > > Ethernet, the NSH header, inner Ethernet and 4096 payload bytes. The > > two pops consume the linear headers and expose the inner Ethernet header > > in page fragments. > > > > The fix: > > Pull the inner Ethernet header into the linear area before restoring > > MAC_PROTO_ETHERNET. This is the NSH counterpart of the MPLS/TEB > > producer fix in the previous patch. > > > > Fixes: b2d0f5d5dc53 ("openvswitch: enable NSH support") > > Link: > > https://lore.kernel.org/netdev/[email protected]/ > > Cc: [email protected] > > Signed-off-by: Jamal Hadi Salim <[email protected]> > > --- > > net/openvswitch/actions.c | 7 +++++-- > > 1 file changed, 5 insertions(+), 2 deletions(-) > > > > diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c > > index 03b31e33e880..cb7e16c6a8ef 100644 > > --- a/net/openvswitch/actions.c > > +++ b/net/openvswitch/actions.c > > @@ -314,10 +314,13 @@ static int pop_nsh(struct sk_buff *skb, struct > > sw_flow_key *key) > > return err; > > > > /* safe right before invalidate_flow_key */ > > - if (skb->protocol == htons(ETH_P_TEB)) > > + if (skb->protocol == htons(ETH_P_TEB)) { > > + if (!pskb_may_pull(skb, ETH_HLEN)) > > + return -ENOMEM; > > key->mac_proto = MAC_PROTO_ETHERNET; > > - else > > + } else { > > key->mac_proto = MAC_PROTO_NONE; > > + } > > invalidate_flow_key(key); > > return 0; > > } > > Reviewed-by: Ilya Maximets <[email protected]>
Reviewed-by: Eric Dumazet <[email protected]> _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
