Commit ec624fe7 authored by Paul Blakey's avatar Paul Blakey Committed by Jakub Kicinski

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: default avatarPaul Blakey <paulb@nvidia.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 8ca4090f
...@@ -193,4 +193,19 @@ static inline void skb_txtime_consumed(struct sk_buff *skb) ...@@ -193,4 +193,19 @@ static inline void skb_txtime_consumed(struct sk_buff *skb)
skb->tstamp = ktime_set(0, 0); skb->tstamp = ktime_set(0, 0);
} }
struct tc_skb_cb {
struct qdisc_skb_cb qdisc_cb;
u16 mru;
bool post_ct;
};
static inline struct tc_skb_cb *tc_skb_cb(const struct sk_buff *skb)
{
struct tc_skb_cb *cb = (struct tc_skb_cb *)skb->cb;
BUILD_BUG_ON(sizeof(*cb) > sizeof_field(struct sk_buff, cb));
return cb;
}
#endif #endif
...@@ -447,8 +447,6 @@ struct qdisc_skb_cb { ...@@ -447,8 +447,6 @@ struct qdisc_skb_cb {
}; };
#define QDISC_CB_PRIV_LEN 20 #define QDISC_CB_PRIV_LEN 20
unsigned char data[QDISC_CB_PRIV_LEN]; unsigned char data[QDISC_CB_PRIV_LEN];
u16 mru;
bool post_ct;
}; };
typedef void tcf_chain_head_change_t(struct tcf_proto *tp_head, void *priv); typedef void tcf_chain_head_change_t(struct tcf_proto *tp_head, void *priv);
......
...@@ -3941,8 +3941,8 @@ sch_handle_egress(struct sk_buff *skb, int *ret, struct net_device *dev) ...@@ -3941,8 +3941,8 @@ sch_handle_egress(struct sk_buff *skb, int *ret, struct net_device *dev)
return skb; return skb;
/* qdisc_skb_cb(skb)->pkt_len was already set by the caller. */ /* qdisc_skb_cb(skb)->pkt_len was already set by the caller. */
qdisc_skb_cb(skb)->mru = 0; tc_skb_cb(skb)->mru = 0;
qdisc_skb_cb(skb)->post_ct = false; tc_skb_cb(skb)->post_ct = false;
mini_qdisc_bstats_cpu_update(miniq, skb); mini_qdisc_bstats_cpu_update(miniq, skb);
switch (tcf_classify(skb, miniq->block, miniq->filter_list, &cl_res, false)) { switch (tcf_classify(skb, miniq->block, miniq->filter_list, &cl_res, false)) {
...@@ -5103,8 +5103,8 @@ sch_handle_ingress(struct sk_buff *skb, struct packet_type **pt_prev, int *ret, ...@@ -5103,8 +5103,8 @@ sch_handle_ingress(struct sk_buff *skb, struct packet_type **pt_prev, int *ret,
} }
qdisc_skb_cb(skb)->pkt_len = skb->len; qdisc_skb_cb(skb)->pkt_len = skb->len;
qdisc_skb_cb(skb)->mru = 0; tc_skb_cb(skb)->mru = 0;
qdisc_skb_cb(skb)->post_ct = false; tc_skb_cb(skb)->post_ct = false;
skb->tc_at_ingress = 1; skb->tc_at_ingress = 1;
mini_qdisc_bstats_cpu_update(miniq, skb); mini_qdisc_bstats_cpu_update(miniq, skb);
......
...@@ -690,10 +690,10 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb, ...@@ -690,10 +690,10 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
u8 family, u16 zone, bool *defrag) u8 family, u16 zone, bool *defrag)
{ {
enum ip_conntrack_info ctinfo; enum ip_conntrack_info ctinfo;
struct qdisc_skb_cb cb;
struct nf_conn *ct; struct nf_conn *ct;
int err = 0; int err = 0;
bool frag; bool frag;
u16 mru;
/* Previously seen (loopback)? Ignore. */ /* Previously seen (loopback)? Ignore. */
ct = nf_ct_get(skb, &ctinfo); ct = nf_ct_get(skb, &ctinfo);
...@@ -708,7 +708,7 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb, ...@@ -708,7 +708,7 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
return err; return err;
skb_get(skb); skb_get(skb);
cb = *qdisc_skb_cb(skb); mru = tc_skb_cb(skb)->mru;
if (family == NFPROTO_IPV4) { if (family == NFPROTO_IPV4) {
enum ip_defrag_users user = IP_DEFRAG_CONNTRACK_IN + zone; enum ip_defrag_users user = IP_DEFRAG_CONNTRACK_IN + zone;
...@@ -722,7 +722,7 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb, ...@@ -722,7 +722,7 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
if (!err) { if (!err) {
*defrag = true; *defrag = true;
cb.mru = IPCB(skb)->frag_max_size; mru = IPCB(skb)->frag_max_size;
} }
} else { /* NFPROTO_IPV6 */ } else { /* NFPROTO_IPV6 */
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
...@@ -735,7 +735,7 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb, ...@@ -735,7 +735,7 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
if (!err) { if (!err) {
*defrag = true; *defrag = true;
cb.mru = IP6CB(skb)->frag_max_size; mru = IP6CB(skb)->frag_max_size;
} }
#else #else
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
...@@ -744,7 +744,7 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb, ...@@ -744,7 +744,7 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
} }
if (err != -EINPROGRESS) if (err != -EINPROGRESS)
*qdisc_skb_cb(skb) = cb; tc_skb_cb(skb)->mru = mru;
skb_clear_hash(skb); skb_clear_hash(skb);
skb->ignore_df = 1; skb->ignore_df = 1;
return err; return err;
...@@ -963,7 +963,7 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a, ...@@ -963,7 +963,7 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
tcf_action_update_bstats(&c->common, skb); tcf_action_update_bstats(&c->common, skb);
if (clear) { if (clear) {
qdisc_skb_cb(skb)->post_ct = false; tc_skb_cb(skb)->post_ct = false;
ct = nf_ct_get(skb, &ctinfo); ct = nf_ct_get(skb, &ctinfo);
if (ct) { if (ct) {
nf_conntrack_put(&ct->ct_general); nf_conntrack_put(&ct->ct_general);
...@@ -1048,7 +1048,7 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a, ...@@ -1048,7 +1048,7 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
out_push: out_push:
skb_push_rcsum(skb, nh_ofs); skb_push_rcsum(skb, nh_ofs);
qdisc_skb_cb(skb)->post_ct = true; tc_skb_cb(skb)->post_ct = true;
out_clear: out_clear:
if (defrag) if (defrag)
qdisc_skb_cb(skb)->pkt_len = skb->len; qdisc_skb_cb(skb)->pkt_len = skb->len;
......
...@@ -1617,12 +1617,14 @@ int tcf_classify(struct sk_buff *skb, ...@@ -1617,12 +1617,14 @@ int tcf_classify(struct sk_buff *skb,
/* If we missed on some chain */ /* If we missed on some chain */
if (ret == TC_ACT_UNSPEC && last_executed_chain) { if (ret == TC_ACT_UNSPEC && last_executed_chain) {
struct tc_skb_cb *cb = tc_skb_cb(skb);
ext = tc_skb_ext_alloc(skb); ext = tc_skb_ext_alloc(skb);
if (WARN_ON_ONCE(!ext)) if (WARN_ON_ONCE(!ext))
return TC_ACT_SHOT; return TC_ACT_SHOT;
ext->chain = last_executed_chain; ext->chain = last_executed_chain;
ext->mru = qdisc_skb_cb(skb)->mru; ext->mru = cb->mru;
ext->post_ct = qdisc_skb_cb(skb)->post_ct; ext->post_ct = cb->post_ct;
} }
return ret; return ret;
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <net/sch_generic.h> #include <net/sch_generic.h>
#include <net/pkt_cls.h> #include <net/pkt_cls.h>
#include <net/pkt_sched.h>
#include <net/ip.h> #include <net/ip.h>
#include <net/flow_dissector.h> #include <net/flow_dissector.h>
#include <net/geneve.h> #include <net/geneve.h>
...@@ -309,7 +310,7 @@ static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp, ...@@ -309,7 +310,7 @@ static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp,
struct tcf_result *res) struct tcf_result *res)
{ {
struct cls_fl_head *head = rcu_dereference_bh(tp->root); struct cls_fl_head *head = rcu_dereference_bh(tp->root);
bool post_ct = qdisc_skb_cb(skb)->post_ct; bool post_ct = tc_skb_cb(skb)->post_ct;
struct fl_flow_key skb_key; struct fl_flow_key skb_key;
struct fl_flow_mask *mask; struct fl_flow_mask *mask;
struct cls_fl_filter *f; struct cls_fl_filter *f;
......
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
#include <net/netlink.h> #include <net/netlink.h>
#include <net/sch_generic.h> #include <net/sch_generic.h>
#include <net/pkt_sched.h>
#include <net/dst.h> #include <net/dst.h>
#include <net/ip.h> #include <net/ip.h>
#include <net/ip6_fib.h> #include <net/ip6_fib.h>
...@@ -137,7 +138,7 @@ static int sch_fragment(struct net *net, struct sk_buff *skb, ...@@ -137,7 +138,7 @@ static int sch_fragment(struct net *net, struct sk_buff *skb,
int sch_frag_xmit_hook(struct sk_buff *skb, int (*xmit)(struct sk_buff *skb)) int sch_frag_xmit_hook(struct sk_buff *skb, int (*xmit)(struct sk_buff *skb))
{ {
u16 mru = qdisc_skb_cb(skb)->mru; u16 mru = tc_skb_cb(skb)->mru;
int err; int err;
if (mru && skb->len > mru + skb->dev->hard_header_len) if (mru && skb->len > mru + skb->dev->hard_header_len)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment