[SRU][F:linux-bluefield][PATCH V2 2/9] net/sched: act_ct: fix miss set mru for ovs after defrag in act_ct

Bodong Wang bodong at nvidia.com
Wed Sep 1 17:14:13 UTC 2021


From: wenxu <wenxu at ucloud.cn>

BugLink: https://bugs.launchpad.net/bugs/1940872

When openvswitch conntrack offload with act_ct action. Fragment packets
defrag in the ingress tc act_ct action and miss the next chain. Then the
packet pass to the openvswitch datapath without the mru. The over
mtu packet will be dropped in output action in openvswitch for over mtu.

"kernel: net2: dropped over-mtu packet: 1528 > 1500"

This patch add mru in the tc_skb_ext for adefrag and miss next chain
situation. And also add mru in the qdisc_skb_cb. The act_ct set the mru
to the qdisc_skb_cb when the packet defrag. And When the chain miss,
The mru is set to tc_skb_ext which can be got by ovs datapath.

Fixes: b57dc7c13ea9 ("net/sched: Introduce action ct")
Signed-off-by: wenxu <wenxu at ucloud.cn>
Reviewed-by: Cong Wang <xiyou.wangcong at gmail.com>
Signed-off-by: David S. Miller <davem at davemloft.net>
(backport from 038ebb1a713d114d54dbf14868a73181c0c92758)
[maor: align to 0617099db3d3 ("net/sched: act_api: fix miss set post_ct for ovs after do conntrack in act_ct")]
Signed-off-by: Maor Dickman <maord at nvidia.com>
Signed-off-by: Bodong Wang <bodong at nvidia.com>
---
 include/linux/skbuff.h    | 1 +
 include/net/sch_generic.h | 3 ++-
 net/openvswitch/flow.c    | 1 +
 net/sched/act_ct.c        | 8 ++++++--
 net/sched/cls_api.c       | 1 +
 5 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 1222db3..62e17a5 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -283,6 +283,7 @@ struct nf_bridge_info {
  */
 struct tc_skb_ext {
 	__u32 chain;
+	__u16 mru;
 	bool post_ct;
 };
 #endif
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index c395d63..75e0781 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -413,6 +413,7 @@ struct qdisc_skb_cb {
 	};
 #define QDISC_CB_PRIV_LEN 20
 	unsigned char		data[QDISC_CB_PRIV_LEN];
+	u16			mru;
 	bool			post_ct;
 };
 
@@ -493,7 +494,7 @@ static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz)
 {
 	struct qdisc_skb_cb *qcb;
 
-	BUILD_BUG_ON(sizeof(skb->cb) < offsetof(struct qdisc_skb_cb, data) + sz);
+	BUILD_BUG_ON(sizeof(skb->cb) < sizeof(*qcb));
 	BUILD_BUG_ON(sizeof(qcb->data) < sz);
 }
 
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 84f3bf8..3d2e8fd 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -883,6 +883,7 @@ int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info,
 	if (static_branch_unlikely(&tc_recirc_sharing_support)) {
 		tc_ext = skb_ext_find(skb, TC_SKB_EXT);
 		key->recirc_id = tc_ext ? tc_ext->chain : 0;
+		OVS_CB(skb)->mru = tc_ext ? tc_ext->mru : 0;
 		post_ct = tc_ext ? tc_ext->post_ct : false;
 	} else {
 		key->recirc_id = 0;
diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
index 39547cf1..5a13ad69 100644
--- a/net/sched/act_ct.c
+++ b/net/sched/act_ct.c
@@ -713,8 +713,10 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
 		if (err && err != -EINPROGRESS)
 			return err;
 
-		if (!err)
+		if (!err) {
 			*defrag = true;
+			cb.mru = IPCB(skb)->frag_max_size;
+		}
 	} else { /* NFPROTO_IPV6 */
 #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
 		enum ip6_defrag_users user = IP6_DEFRAG_CONNTRACK_IN + zone;
@@ -724,8 +726,10 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
 		if (err && err != -EINPROGRESS)
 			return err;
 
-		if (!err)
+		if (!err) {
 			*defrag = true;
+			cb.mru = IP6CB(skb)->frag_max_size;
+		}
 #else
 		err = -EOPNOTSUPP;
 		goto out_free;
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 9c9afc0..25174e4 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -1679,6 +1679,7 @@ int tcf_classify_ingress(struct sk_buff *skb,
 		if (WARN_ON_ONCE(!ext))
 			return TC_ACT_SHOT;
 		ext->chain = last_executed_chain;
+		ext->mru = qdisc_skb_cb(skb)->mru;
 		ext->post_ct = qdisc_skb_cb(skb)->post_ct;
 	}
 
-- 
1.8.3.1




More information about the kernel-team mailing list