]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
ipvlan: Fix return value of ipvlan_queue_xmit()
authorCambda Zhu <cambda@linux.alibaba.com>
Mon, 26 Jun 2023 09:33:47 +0000 (17:33 +0800)
committerRoxana Nicolescu <roxana.nicolescu@canonical.com>
Mon, 2 Oct 2023 15:19:38 +0000 (17:19 +0200)
BugLink: https://bugs.launchpad.net/bugs/2034469
[ Upstream commit 8a9922e7be6d042fa00f894c376473b17a162b66 ]

ipvlan_queue_xmit() should return NET_XMIT_XXX, but
ipvlan_xmit_mode_l2/l3() returns rx_handler_result_t or NET_RX_XXX
in some cases. ipvlan_rcv_frame() will only return RX_HANDLER_CONSUMED
in ipvlan_xmit_mode_l2/l3() because 'local' is true. It's equal to
NET_XMIT_SUCCESS. But dev_forward_skb() can return NET_RX_SUCCESS or
NET_RX_DROP, and returning NET_RX_DROP(NET_XMIT_DROP) will increase
both ipvlan and ipvlan->phy_dev drops counter.

The skb to forward can be treated as xmitted successfully. This patch
makes ipvlan_queue_xmit() return NET_XMIT_SUCCESS for forward skb.

Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.")
Signed-off-by: Cambda Zhu <cambda@linux.alibaba.com>
Link: https://lore.kernel.org/r/20230626093347.7492-1-cambda@linux.alibaba.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
drivers/net/ipvlan/ipvlan_core.c

index 2de3bd3b0c278cc4fe772a6074b5bf2b190b2cab..59e29e08398a0bc5bd88919276c968ac8c2ec210 100644 (file)
@@ -585,7 +585,8 @@ static int ipvlan_xmit_mode_l3(struct sk_buff *skb, struct net_device *dev)
                                consume_skb(skb);
                                return NET_XMIT_DROP;
                        }
-                       return ipvlan_rcv_frame(addr, &skb, true);
+                       ipvlan_rcv_frame(addr, &skb, true);
+                       return NET_XMIT_SUCCESS;
                }
        }
 out:
@@ -611,7 +612,8 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev)
                                        consume_skb(skb);
                                        return NET_XMIT_DROP;
                                }
-                               return ipvlan_rcv_frame(addr, &skb, true);
+                               ipvlan_rcv_frame(addr, &skb, true);
+                               return NET_XMIT_SUCCESS;
                        }
                }
                skb = skb_share_check(skb, GFP_ATOMIC);
@@ -623,7 +625,8 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev)
                 * the skb for the main-dev. At the RX side we just return
                 * RX_PASS for it to be processed further on the stack.
                 */
-               return dev_forward_skb(ipvlan->phy_dev, skb);
+               dev_forward_skb(ipvlan->phy_dev, skb);
+               return NET_XMIT_SUCCESS;
 
        } else if (is_multicast_ether_addr(eth->h_dest)) {
                skb_reset_mac_header(skb);