[PATCH net-next 06/10] net: vxlan: add skb drop reasons to vxlan_rcv()
From: Menglong Dong <hidden>
Date: 2024-08-15 12:46:12
Also in:
lkml
Subsystem:
networking drivers, networking [general], the rest · Maintainers:
Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Introduce skb drop reasons to the function vxlan_rcv(). Following new vxlan drop reasons are added: VXLAN_DROP_FLAGS VXLAN_DROP_VNI VXLAN_DROP_MAC And Following core skb drop reason is added: SKB_DROP_REASON_IP_TUNNEL_ECN As ip tunnel is a public module, I'm not sure how to deal with it. So I simply add it to the core drop reasons. Signed-off-by: Menglong Dong <redacted> --- drivers/net/vxlan/drop.h | 3 +++ drivers/net/vxlan/vxlan_core.c | 35 +++++++++++++++++++++++++--------- include/net/dropreason-core.h | 6 ++++++ 3 files changed, 35 insertions(+), 9 deletions(-)
diff --git a/drivers/net/vxlan/drop.h b/drivers/net/vxlan/drop.h
index 83e10550dd6a..cae1e0ea8c56 100644
--- a/drivers/net/vxlan/drop.h
+++ b/drivers/net/vxlan/drop.h@@ -9,6 +9,9 @@ #include <net/dropreason.h> #define VXLAN_DROP_REASONS(R) \ + R(VXLAN_DROP_FLAGS) \ + R(VXLAN_DROP_VNI) \ + R(VXLAN_DROP_MAC) \ /* deliberate comment for trailing \ */ enum vxlan_drop_reason {
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index e971c4785962..9a61f04bb95d 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c@@ -1668,6 +1668,7 @@ static bool vxlan_ecn_decapsulate(struct vxlan_sock *vs, void *oiph, /* Callback from net/ipv4/udp.c to receive packets */ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb) { + enum skb_drop_reason reason = pskb_may_pull_reason(skb, VXLAN_HLEN); struct vxlan_vni_node *vninode = NULL; struct vxlan_dev *vxlan; struct vxlan_sock *vs;
@@ -1681,7 +1682,7 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb) int nh; /* Need UDP and VXLAN header to be present */ - if (!pskb_may_pull(skb, VXLAN_HLEN)) + if (reason != SKB_NOT_DROPPED_YET) goto drop; unparsed = *vxlan_hdr(skb);
@@ -1690,6 +1691,7 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb) netdev_dbg(skb->dev, "invalid vxlan flags=%#x vni=%#x\n", ntohl(vxlan_hdr(skb)->vx_flags), ntohl(vxlan_hdr(skb)->vx_vni)); + reason = (u32)VXLAN_DROP_FLAGS; /* Return non vxlan pkt */ goto drop; }
@@ -1703,8 +1705,10 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb) vni = vxlan_vni(vxlan_hdr(skb)->vx_vni); vxlan = vxlan_vs_find_vni(vs, skb->dev->ifindex, vni, &vninode); - if (!vxlan) + if (!vxlan) { + reason = (u32)VXLAN_DROP_VNI; goto drop; + } /* For backwards compatibility, only allow reserved fields to be * used by VXLAN extensions if explicitly requested.
@@ -1717,12 +1721,16 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb) } if (__iptunnel_pull_header(skb, VXLAN_HLEN, protocol, raw_proto, - !net_eq(vxlan->net, dev_net(vxlan->dev)))) + !net_eq(vxlan->net, dev_net(vxlan->dev)))) { + reason = SKB_DROP_REASON_NOMEM; goto drop; + } - if (vs->flags & VXLAN_F_REMCSUM_RX) - if (unlikely(!vxlan_remcsum(&unparsed, skb, vs->flags))) + if (vs->flags & VXLAN_F_REMCSUM_RX) { + reason = vxlan_remcsum(&unparsed, skb, vs->flags); + if (unlikely(reason != SKB_NOT_DROPPED_YET)) goto drop; + } if (vxlan_collect_metadata(vs)) { IP_TUNNEL_DECLARE_FLAGS(flags) = { };
@@ -1732,8 +1740,10 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb) tun_dst = udp_tun_rx_dst(skb, vxlan_get_sk_family(vs), flags, key32_to_tunnel_id(vni), sizeof(*md)); - if (!tun_dst) + if (!tun_dst) { + reason = SKB_DROP_REASON_NOMEM; goto drop; + } md = ip_tunnel_info_opts(&tun_dst->u.tun_info);
@@ -1757,12 +1767,15 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb) * is more robust and provides a little more security in * adding extensions to VXLAN. */ + reason = (u32)VXLAN_DROP_FLAGS; goto drop; } if (!raw_proto) { - if (!vxlan_set_mac(vxlan, vs, skb, vni)) + if (!vxlan_set_mac(vxlan, vs, skb, vni)) { + reason = (u32)VXLAN_DROP_MAC; goto drop; + } } else { skb_reset_mac_header(skb); skb->dev = vxlan->dev;
@@ -1777,7 +1790,8 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb) skb_reset_network_header(skb); - if (!pskb_inet_may_pull(skb)) { + reason = pskb_inet_may_pull_reason(skb); + if (reason != SKB_NOT_DROPPED_YET) { DEV_STATS_INC(vxlan->dev, rx_length_errors); DEV_STATS_INC(vxlan->dev, rx_errors); vxlan_vnifilter_count(vxlan, vni, vninode,
@@ -1789,6 +1803,7 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb) oiph = skb->head + nh; if (!vxlan_ecn_decapsulate(vs, oiph, skb)) { + reason = SKB_DROP_REASON_IP_TUNNEL_ECN; DEV_STATS_INC(vxlan->dev, rx_frame_errors); DEV_STATS_INC(vxlan->dev, rx_errors); vxlan_vnifilter_count(vxlan, vni, vninode,
@@ -1803,6 +1818,7 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb) dev_core_stats_rx_dropped_inc(vxlan->dev); vxlan_vnifilter_count(vxlan, vni, vninode, VXLAN_VNI_STATS_RX_DROPS, 0); + reason = SKB_DROP_REASON_DEV_READY; goto drop; }
@@ -1815,8 +1831,9 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb) return 0; drop: + SKB_DR_RESET(reason); /* Consume bad packet */ - kfree_skb(skb); + kfree_skb_reason(skb, reason); return 0; }
diff --git a/include/net/dropreason-core.h b/include/net/dropreason-core.h
index 8da0129d1ed6..8388c0ae893d 100644
--- a/include/net/dropreason-core.h
+++ b/include/net/dropreason-core.h@@ -92,6 +92,7 @@ FN(PACKET_SOCK_ERROR) \ FN(TC_CHAIN_NOTFOUND) \ FN(TC_RECLASSIFY_LOOP) \ + FN(IP_TUNNEL_ECN) \ FNe(MAX) /**
@@ -418,6 +419,11 @@ enum skb_drop_reason { * iterations. */ SKB_DROP_REASON_TC_RECLASSIFY_LOOP, + /** + * @SKB_DROP_REASON_IP_TUNNEL_ECN: skb is dropped according to + * RFC 6040 4.2, see __INET_ECN_decapsulate() for detail. + */ + SKB_DROP_REASON_IP_TUNNEL_ECN, /** * @SKB_DROP_REASON_MAX: the maximum of core drop reasons, which * shouldn't be used as a real 'reason' - only for tracing code gen
--
2.39.2