Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net/sched: Extend qdisc control block with tc control block

BPF layer extends the qdisc control block via struct bpf_skb_data_end
and because of that there is no more room to add variables to the
qdisc layer control block without going over the skb->cb size.

Extend the qdisc control block with a tc control block,
and move all tc related variables to there as a pre-step for
extending the tc control block with additional members.

Signed-off-by: Paul Blakey <paulb@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Paul Blakey and committed by
Jakub Kicinski
ec624fe7 8ca4090f

+34 -17
+15
include/net/pkt_sched.h
··· 193 193 skb->tstamp = ktime_set(0, 0); 194 194 } 195 195 196 + struct tc_skb_cb { 197 + struct qdisc_skb_cb qdisc_cb; 198 + 199 + u16 mru; 200 + bool post_ct; 201 + }; 202 + 203 + static inline struct tc_skb_cb *tc_skb_cb(const struct sk_buff *skb) 204 + { 205 + struct tc_skb_cb *cb = (struct tc_skb_cb *)skb->cb; 206 + 207 + BUILD_BUG_ON(sizeof(*cb) > sizeof_field(struct sk_buff, cb)); 208 + return cb; 209 + } 210 + 196 211 #endif
-2
include/net/sch_generic.h
··· 447 447 }; 448 448 #define QDISC_CB_PRIV_LEN 20 449 449 unsigned char data[QDISC_CB_PRIV_LEN]; 450 - u16 mru; 451 - bool post_ct; 452 450 }; 453 451 454 452 typedef void tcf_chain_head_change_t(struct tcf_proto *tp_head, void *priv);
+4 -4
net/core/dev.c
··· 3941 3941 return skb; 3942 3942 3943 3943 /* qdisc_skb_cb(skb)->pkt_len was already set by the caller. */ 3944 - qdisc_skb_cb(skb)->mru = 0; 3945 - qdisc_skb_cb(skb)->post_ct = false; 3944 + tc_skb_cb(skb)->mru = 0; 3945 + tc_skb_cb(skb)->post_ct = false; 3946 3946 mini_qdisc_bstats_cpu_update(miniq, skb); 3947 3947 3948 3948 switch (tcf_classify(skb, miniq->block, miniq->filter_list, &cl_res, false)) { ··· 5103 5103 } 5104 5104 5105 5105 qdisc_skb_cb(skb)->pkt_len = skb->len; 5106 - qdisc_skb_cb(skb)->mru = 0; 5107 - qdisc_skb_cb(skb)->post_ct = false; 5106 + tc_skb_cb(skb)->mru = 0; 5107 + tc_skb_cb(skb)->post_ct = false; 5108 5108 skb->tc_at_ingress = 1; 5109 5109 mini_qdisc_bstats_cpu_update(miniq, skb); 5110 5110
+7 -7
net/sched/act_ct.c
··· 690 690 u8 family, u16 zone, bool *defrag) 691 691 { 692 692 enum ip_conntrack_info ctinfo; 693 - struct qdisc_skb_cb cb; 694 693 struct nf_conn *ct; 695 694 int err = 0; 696 695 bool frag; 696 + u16 mru; 697 697 698 698 /* Previously seen (loopback)? Ignore. */ 699 699 ct = nf_ct_get(skb, &ctinfo); ··· 708 708 return err; 709 709 710 710 skb_get(skb); 711 - cb = *qdisc_skb_cb(skb); 711 + mru = tc_skb_cb(skb)->mru; 712 712 713 713 if (family == NFPROTO_IPV4) { 714 714 enum ip_defrag_users user = IP_DEFRAG_CONNTRACK_IN + zone; ··· 722 722 723 723 if (!err) { 724 724 *defrag = true; 725 - cb.mru = IPCB(skb)->frag_max_size; 725 + mru = IPCB(skb)->frag_max_size; 726 726 } 727 727 } else { /* NFPROTO_IPV6 */ 728 728 #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) ··· 735 735 736 736 if (!err) { 737 737 *defrag = true; 738 - cb.mru = IP6CB(skb)->frag_max_size; 738 + mru = IP6CB(skb)->frag_max_size; 739 739 } 740 740 #else 741 741 err = -EOPNOTSUPP; ··· 744 744 } 745 745 746 746 if (err != -EINPROGRESS) 747 - *qdisc_skb_cb(skb) = cb; 747 + tc_skb_cb(skb)->mru = mru; 748 748 skb_clear_hash(skb); 749 749 skb->ignore_df = 1; 750 750 return err; ··· 963 963 tcf_action_update_bstats(&c->common, skb); 964 964 965 965 if (clear) { 966 - qdisc_skb_cb(skb)->post_ct = false; 966 + tc_skb_cb(skb)->post_ct = false; 967 967 ct = nf_ct_get(skb, &ctinfo); 968 968 if (ct) { 969 969 nf_conntrack_put(&ct->ct_general); ··· 1048 1048 out_push: 1049 1049 skb_push_rcsum(skb, nh_ofs); 1050 1050 1051 - qdisc_skb_cb(skb)->post_ct = true; 1051 + tc_skb_cb(skb)->post_ct = true; 1052 1052 out_clear: 1053 1053 if (defrag) 1054 1054 qdisc_skb_cb(skb)->pkt_len = skb->len;
+4 -2
net/sched/cls_api.c
··· 1617 1617 1618 1618 /* If we missed on some chain */ 1619 1619 if (ret == TC_ACT_UNSPEC && last_executed_chain) { 1620 + struct tc_skb_cb *cb = tc_skb_cb(skb); 1621 + 1620 1622 ext = tc_skb_ext_alloc(skb); 1621 1623 if (WARN_ON_ONCE(!ext)) 1622 1624 return TC_ACT_SHOT; 1623 1625 ext->chain = last_executed_chain; 1624 - ext->mru = qdisc_skb_cb(skb)->mru; 1625 - ext->post_ct = qdisc_skb_cb(skb)->post_ct; 1626 + ext->mru = cb->mru; 1627 + ext->post_ct = cb->post_ct; 1626 1628 } 1627 1629 1628 1630 return ret;
+2 -1
net/sched/cls_flower.c
··· 19 19 20 20 #include <net/sch_generic.h> 21 21 #include <net/pkt_cls.h> 22 + #include <net/pkt_sched.h> 22 23 #include <net/ip.h> 23 24 #include <net/flow_dissector.h> 24 25 #include <net/geneve.h> ··· 310 309 struct tcf_result *res) 311 310 { 312 311 struct cls_fl_head *head = rcu_dereference_bh(tp->root); 313 - bool post_ct = qdisc_skb_cb(skb)->post_ct; 312 + bool post_ct = tc_skb_cb(skb)->post_ct; 314 313 struct fl_flow_key skb_key; 315 314 struct fl_flow_mask *mask; 316 315 struct cls_fl_filter *f;
+2 -1
net/sched/sch_frag.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2 2 #include <net/netlink.h> 3 3 #include <net/sch_generic.h> 4 + #include <net/pkt_sched.h> 4 5 #include <net/dst.h> 5 6 #include <net/ip.h> 6 7 #include <net/ip6_fib.h> ··· 138 137 139 138 int sch_frag_xmit_hook(struct sk_buff *skb, int (*xmit)(struct sk_buff *skb)) 140 139 { 141 - u16 mru = qdisc_skb_cb(skb)->mru; 140 + u16 mru = tc_skb_cb(skb)->mru; 142 141 int err; 143 142 144 143 if (mru && skb->len > mru + skb->dev->hard_header_len)