Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'ipvlan-multicast-delivery-changes'

Eric Dumazet says:

====================
ipvlan: multicast delivery changes

As we did recently for macvlan, this series adds some relief
when ipvlan is under multicast storms.
====================

Link: https://patch.msgid.link/20260409085238.1122947-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+23 -19
+23 -19
drivers/net/ipvlan/ipvlan_core.c
··· 744 744 static rx_handler_result_t ipvlan_handle_mode_l2(struct sk_buff **pskb, 745 745 struct ipvl_port *port) 746 746 { 747 - struct sk_buff *skb = *pskb; 747 + struct sk_buff *nskb, *skb = *pskb; 748 748 struct ethhdr *eth = eth_hdr(skb); 749 - rx_handler_result_t ret = RX_HANDLER_PASS; 750 749 751 750 if (unlikely(skb->pkt_type == PACKET_LOOPBACK)) 752 751 return RX_HANDLER_PASS; 753 752 754 - if (is_multicast_ether_addr(eth->h_dest)) { 755 - if (ipvlan_external_frame(skb, port)) { 756 - struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC); 753 + /* Perform like l3 mode for non-multicast packet */ 754 + if (likely(!is_multicast_ether_addr(eth->h_dest))) 755 + return ipvlan_handle_mode_l3(pskb, port); 757 756 758 - /* External frames are queued for device local 759 - * distribution, but a copy is given to master 760 - * straight away to avoid sending duplicates later 761 - * when work-queue processes this frame. This is 762 - * achieved by returning RX_HANDLER_PASS. 763 - */ 764 - if (nskb) { 765 - ipvlan_skb_crossing_ns(nskb, NULL); 766 - ipvlan_multicast_enqueue(port, nskb, false); 767 - } 768 - } 757 + /* External frames are queued for device local 758 + * distribution, but a copy is given to master 759 + * straight away to avoid sending duplicates later 760 + * when work-queue processes this frame. 761 + * This is achieved by returning RX_HANDLER_PASS. 762 + */ 763 + if (!ipvlan_external_frame(skb, port)) 764 + return RX_HANDLER_PASS; 765 + 766 + if (skb_queue_len_lockless(&port->backlog) >= IPVLAN_QBACKLOG_LIMIT) 767 + nskb = NULL; 768 + else 769 + nskb = skb_clone(skb, GFP_ATOMIC); 770 + 771 + if (nskb) { 772 + ipvlan_skb_crossing_ns(nskb, NULL); 773 + ipvlan_multicast_enqueue(port, nskb, false); 769 774 } else { 770 - /* Perform like l3 mode for non-multicast packet */ 771 - ret = ipvlan_handle_mode_l3(pskb, port); 775 + dev_core_stats_rx_dropped_inc(skb->dev); 772 776 } 773 777 774 - return ret; 778 + return RX_HANDLER_PASS; 775 779 } 776 780 777 781 rx_handler_result_t ipvlan_handle_frame(struct sk_buff **pskb)