@@ -283,6 +283,7 @@ struct nf_bridge_info {
*/
struct tc_skb_ext {
__u32 chain;
+ __u16 mru;
bool post_ct;
};
#endif
@@ -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);
}
@@ -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;
@@ -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;
@@ -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;
}