Skip to content

Commit

Permalink
net/sched: act_ct: fix miss set mru for ovs after defrag in act_ct
Browse files Browse the repository at this point in the history
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: b57dc7c ("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>
  • Loading branch information
wenxu authored and davem330 committed Aug 3, 2020
1 parent 530fe9d commit 038ebb1
Show file tree
Hide file tree
Showing 5 changed files with 11 additions and 3 deletions.
1 change: 1 addition & 0 deletions include/linux/skbuff.h
Expand Up @@ -283,6 +283,7 @@ struct nf_bridge_info {
*/
struct tc_skb_ext {
__u32 chain;
__u16 mru;
};
#endif

Expand Down
3 changes: 2 additions & 1 deletion include/net/sch_generic.h
Expand Up @@ -384,6 +384,7 @@ struct qdisc_skb_cb {
};
#define QDISC_CB_PRIV_LEN 20
unsigned char data[QDISC_CB_PRIV_LEN];
u16 mru;
};

typedef void tcf_chain_head_change_t(struct tcf_proto *tp_head, void *priv);
Expand Down Expand Up @@ -463,7 +464,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);
}

Expand Down
1 change: 1 addition & 0 deletions net/openvswitch/flow.c
Expand Up @@ -890,6 +890,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;
} else {
key->recirc_id = 0;
}
Expand Down
8 changes: 6 additions & 2 deletions net/sched/act_ct.c
Expand Up @@ -706,8 +706,10 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
if (err && err != -EINPROGRESS)
goto out_free;

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;
Expand All @@ -717,8 +719,10 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
if (err && err != -EINPROGRESS)
goto out_free;

if (!err)
if (!err) {
*defrag = true;
cb.mru = IP6CB(skb)->frag_max_size;
}
#else
err = -EOPNOTSUPP;
goto out_free;
Expand Down
1 change: 1 addition & 0 deletions net/sched/cls_api.c
Expand Up @@ -1629,6 +1629,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;
}

return ret;
Expand Down

0 comments on commit 038ebb1

Please sign in to comment.