Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ddb11554 authored by Cambda Zhu's avatar Cambda Zhu Committed by Greg Kroah-Hartman
Browse files

ipvlan: Fix return value of ipvlan_queue_xmit()



[ 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: 2ad7bf36 ("ipvlan: Initial check-in of the IPVLAN driver.")
Signed-off-by: default avatarCambda Zhu <cambda@linux.alibaba.com>
Link: https://lore.kernel.org/r/20230626093347.7492-1-cambda@linux.alibaba.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 335ae30a
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -592,7 +592,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:
@@ -618,7 +619,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);
@@ -630,7 +632,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);