diff mbox series

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

Message ID 1630516460-16421-3-git-send-email-bodong@nvidia.com
State New
Headers show
Series Fix fragmentation support for TC connection tracking | expand

Commit Message

Bodong Wang Sept. 1, 2021, 5:14 p.m. UTC
From: wenxu <wenxu@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@ucloud.cn>
Reviewed-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: David S. Miller <davem@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@nvidia.com>
Signed-off-by: Bodong Wang <bodong@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 mbox series

Patch

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;
 	}