Message ID | 1658958779-31025-1-git-send-email-bodong@nvidia.com |
---|---|
State | New |
Headers | show |
Series | net/sched: store the last executed chain also for clsact egress | expand |
On 7/27/22 15:52, Bodong Wang wrote: > From: Davide Caratti <dcaratti@redhat.com> > > BugLink: https://bugs.launchpad.net/bugs/1982980 > > currently, only 'ingress' and 'clsact ingress' qdiscs store the tc 'chain > id' in the skb extension. However, userspace programs (like ovs) are able > to setup egress rules, and datapath gets confused in case it doesn't find > the 'chain id' for a packet that's "recirculated" by tc. > Change tcf_classify() to have the same semantic as tcf_classify_ingress() > so that a single function can be called in ingress / egress, using the tc > ingress / egress block respectively. > > Suggested-by: Alaa Hleilel <alaa@nvidia.com> > Signed-off-by: Davide Caratti <dcaratti@redhat.com> > Reviewed-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> > Signed-off-by: David S. Miller <davem@davemloft.net> > (backported from commit 3aa2605594556c676fb88744bd9845acae60683d) > [paulb: Removed tcf_qevent_handle change in cls_api] > Signed-off-by: Paul Blakey <paulb@nvidia.com> > Signed-off-by: Bodong Wang <bodong@nvidia.com> > --- > include/net/pkt_cls.h | 22 +++++++--------------- > net/core/dev.c | 5 ++--- > net/sched/cls_api.c | 40 ++++++++++++++++------------------------ > net/sched/sch_atm.c | 2 +- > net/sched/sch_cake.c | 2 +- > net/sched/sch_cbq.c | 2 +- > net/sched/sch_drr.c | 2 +- > net/sched/sch_dsmark.c | 2 +- > net/sched/sch_fq_codel.c | 2 +- > net/sched/sch_hfsc.c | 2 +- > net/sched/sch_htb.c | 2 +- > net/sched/sch_multiq.c | 2 +- > net/sched/sch_prio.c | 2 +- > net/sched/sch_qfq.c | 2 +- > net/sched/sch_sfb.c | 2 +- > net/sched/sch_sfq.c | 2 +- > 16 files changed, 38 insertions(+), 55 deletions(-) > > diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h > index d23d7fe..18e9373 100644 > --- a/include/net/pkt_cls.h > +++ b/include/net/pkt_cls.h > @@ -70,12 +70,10 @@ static inline struct Qdisc *tcf_block_q(struct tcf_block *block) > return block->q; > } > > -int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp, > - struct tcf_result *res, bool compat_mode); > -int tcf_classify_ingress(struct sk_buff *skb, > - const struct tcf_block *ingress_block, > - const struct tcf_proto *tp, struct tcf_result *res, > - bool compat_mode); > +int tcf_classify(struct sk_buff *skb, > + const struct tcf_block *block, > + const struct tcf_proto *tp, struct tcf_result *res, > + bool compat_mode); > > #else > static inline bool tcf_block_shared(struct tcf_block *block) > @@ -132,20 +130,14 @@ void tc_setup_cb_block_unregister(struct tcf_block *block, flow_setup_cb_t *cb, > { > } > > -static inline int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp, > +static inline int tcf_classify(struct sk_buff *skb, > + const struct tcf_block *block, > + const struct tcf_proto *tp, > struct tcf_result *res, bool compat_mode) > { > return TC_ACT_UNSPEC; > } > > -static inline int tcf_classify_ingress(struct sk_buff *skb, > - const struct tcf_block *ingress_block, > - const struct tcf_proto *tp, > - struct tcf_result *res, bool compat_mode) > -{ > - return TC_ACT_UNSPEC; > -} > - > #endif > > static inline unsigned long > diff --git a/net/core/dev.c b/net/core/dev.c > index 4a32897..a50c5dd 100644 > --- a/net/core/dev.c > +++ b/net/core/dev.c > @@ -3513,7 +3513,7 @@ int dev_loopback_xmit(struct net *net, struct sock *sk, struct sk_buff *skb) > tc_skb_cb(skb)->post_ct = false; > mini_qdisc_bstats_cpu_update(miniq, skb); > > - switch (tcf_classify(skb, miniq->filter_list, &cl_res, false)) { > + switch (tcf_classify(skb, miniq->block, miniq->filter_list, &cl_res, false)) { > case TC_ACT_OK: > case TC_ACT_RECLASSIFY: > skb->tc_index = TC_H_MIN(cl_res.classid); > @@ -4608,8 +4608,7 @@ static __latent_entropy void net_tx_action(struct softirq_action *h) > skb->tc_at_ingress = 1; > mini_qdisc_bstats_cpu_update(miniq, skb); > > - switch (tcf_classify_ingress(skb, miniq->block, miniq->filter_list, > - &cl_res, false)) { > + switch (tcf_classify(skb, miniq->block, miniq->filter_list, &cl_res, false)) { > case TC_ACT_OK: > case TC_ACT_RECLASSIFY: > skb->tc_index = TC_H_MIN(cl_res.classid); > diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c > index 698648a..ddc2d94 100644 > --- a/net/sched/cls_api.c > +++ b/net/sched/cls_api.c > @@ -1628,21 +1628,11 @@ static inline int __tcf_classify(struct sk_buff *skb, > #endif > } > > -int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp, > +int tcf_classify(struct sk_buff *skb, > + const struct tcf_block *block, > + const struct tcf_proto *tp, > struct tcf_result *res, bool compat_mode) > { > - u32 last_executed_chain = 0; > - > - return __tcf_classify(skb, tp, tp, res, compat_mode, > - &last_executed_chain); > -} > -EXPORT_SYMBOL(tcf_classify); > - > -int tcf_classify_ingress(struct sk_buff *skb, > - const struct tcf_block *ingress_block, > - const struct tcf_proto *tp, > - struct tcf_result *res, bool compat_mode) > -{ > #if !IS_ENABLED(CONFIG_NET_TC_SKB_EXT) > u32 last_executed_chain = 0; > > @@ -1654,20 +1644,22 @@ int tcf_classify_ingress(struct sk_buff *skb, > struct tc_skb_ext *ext; > int ret; > > - ext = skb_ext_find(skb, TC_SKB_EXT); > + if (block) { > + ext = skb_ext_find(skb, TC_SKB_EXT); > > - if (ext && ext->chain) { > - struct tcf_chain *fchain; > + if (ext && ext->chain) { > + struct tcf_chain *fchain; > > - fchain = tcf_chain_lookup_rcu(ingress_block, ext->chain); > - if (!fchain) > - return TC_ACT_SHOT; > + fchain = tcf_chain_lookup_rcu(block, ext->chain); > + if (!fchain) > + return TC_ACT_SHOT; > > - /* Consume, so cloned/redirect skbs won't inherit ext */ > - skb_ext_del(skb, TC_SKB_EXT); > + /* Consume, so cloned/redirect skbs won't inherit ext */ > + skb_ext_del(skb, TC_SKB_EXT); > > - tp = rcu_dereference_bh(fchain->filter_chain); > - last_executed_chain = fchain->index; > + tp = rcu_dereference_bh(fchain->filter_chain); > + last_executed_chain = fchain->index; > + } > } > > ret = __tcf_classify(skb, tp, orig_tp, res, compat_mode, > @@ -1691,7 +1683,7 @@ int tcf_classify_ingress(struct sk_buff *skb, > return ret; > #endif > } > -EXPORT_SYMBOL(tcf_classify_ingress); > +EXPORT_SYMBOL(tcf_classify); > > struct tcf_chain_info { > struct tcf_proto __rcu **pprev; > diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c > index 6385995..98a52c3 100644 > --- a/net/sched/sch_atm.c > +++ b/net/sched/sch_atm.c > @@ -393,7 +393,7 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch, > list_for_each_entry(flow, &p->flows, list) { > fl = rcu_dereference_bh(flow->filter_list); > if (fl) { > - result = tcf_classify(skb, fl, &res, true); > + result = tcf_classify(skb, NULL, fl, &res, true); > if (result < 0) > continue; > flow = (struct atm_flow_data *)res.class; > diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c > index 0eb4d4a..e36c34a 100644 > --- a/net/sched/sch_cake.c > +++ b/net/sched/sch_cake.c > @@ -1629,7 +1629,7 @@ static u32 cake_classify(struct Qdisc *sch, struct cake_tin_data **t, > goto hash; > > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > - result = tcf_classify(skb, filter, &res, false); > + result = tcf_classify(skb, NULL, filter, &res, false); > > if (result >= 0) { > #ifdef CONFIG_NET_CLS_ACT > diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c > index e597288..5b7ea18 100644 > --- a/net/sched/sch_cbq.c > +++ b/net/sched/sch_cbq.c > @@ -228,7 +228,7 @@ struct cbq_sched_data { > /* > * Step 2+n. Apply classifier. > */ > - result = tcf_classify(skb, fl, &res, true); > + result = tcf_classify(skb, NULL, fl, &res, true); > if (!fl || result < 0) > goto fallback; > > diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c > index 07a2b0b..60a5a56 100644 > --- a/net/sched/sch_drr.c > +++ b/net/sched/sch_drr.c > @@ -316,7 +316,7 @@ static struct drr_class *drr_classify(struct sk_buff *skb, struct Qdisc *sch, > > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > fl = rcu_dereference_bh(q->filter_list); > - result = tcf_classify(skb, fl, &res, false); > + result = tcf_classify(skb, NULL, fl, &res, false); > if (result >= 0) { > #ifdef CONFIG_NET_CLS_ACT > switch (result) { > diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c > index 76ed1a0..5be11c4 100644 > --- a/net/sched/sch_dsmark.c > +++ b/net/sched/sch_dsmark.c > @@ -241,7 +241,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch, > else { > struct tcf_result res; > struct tcf_proto *fl = rcu_dereference_bh(p->filter_list); > - int result = tcf_classify(skb, fl, &res, false); > + int result = tcf_classify(skb, NULL, fl, &res, false); > > pr_debug("result %d class 0x%04x\n", result, res.classid); > > diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c > index 86fb2f9..1d2f3f4 100644 > --- a/net/sched/sch_fq_codel.c > +++ b/net/sched/sch_fq_codel.c > @@ -92,7 +92,7 @@ static unsigned int fq_codel_classify(struct sk_buff *skb, struct Qdisc *sch, > return fq_codel_hash(q, skb) + 1; > > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > - result = tcf_classify(skb, filter, &res, false); > + result = tcf_classify(skb, NULL, filter, &res, false); > if (result >= 0) { > #ifdef CONFIG_NET_CLS_ACT > switch (result) { > diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c > index 433f219..091eea4 100644 > --- a/net/sched/sch_hfsc.c > +++ b/net/sched/sch_hfsc.c > @@ -1129,7 +1129,7 @@ struct hfsc_sched { > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > head = &q->root; > tcf = rcu_dereference_bh(q->root.filter_list); > - while (tcf && (result = tcf_classify(skb, tcf, &res, false)) >= 0) { > + while (tcf && (result = tcf_classify(skb, NULL, tcf, &res, false)) >= 0) { > #ifdef CONFIG_NET_CLS_ACT > switch (result) { > case TC_ACT_QUEUED: > diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c > index 8184c87..176359f 100644 > --- a/net/sched/sch_htb.c > +++ b/net/sched/sch_htb.c > @@ -232,7 +232,7 @@ static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch, > } > > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > - while (tcf && (result = tcf_classify(skb, tcf, &res, false)) >= 0) { > + while (tcf && (result = tcf_classify(skb, NULL, tcf, &res, false)) >= 0) { > #ifdef CONFIG_NET_CLS_ACT > switch (result) { > case TC_ACT_QUEUED: > diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c > index 1330ad2..bc5f288 100644 > --- a/net/sched/sch_multiq.c > +++ b/net/sched/sch_multiq.c > @@ -36,7 +36,7 @@ struct multiq_sched_data { > int err; > > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > - err = tcf_classify(skb, fl, &res, false); > + err = tcf_classify(skb, NULL, fl, &res, false); > #ifdef CONFIG_NET_CLS_ACT > switch (err) { > case TC_ACT_STOLEN: > diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c > index 6479417..41573b8 100644 > --- a/net/sched/sch_prio.c > +++ b/net/sched/sch_prio.c > @@ -39,7 +39,7 @@ struct prio_sched_data { > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > if (TC_H_MAJ(skb->priority) != sch->handle) { > fl = rcu_dereference_bh(q->filter_list); > - err = tcf_classify(skb, fl, &res, false); > + err = tcf_classify(skb, NULL, fl, &res, false); > #ifdef CONFIG_NET_CLS_ACT > switch (err) { > case TC_ACT_STOLEN: > diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c > index 1eb339d..d6827b54 100644 > --- a/net/sched/sch_qfq.c > +++ b/net/sched/sch_qfq.c > @@ -689,7 +689,7 @@ static struct qfq_class *qfq_classify(struct sk_buff *skb, struct Qdisc *sch, > > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > fl = rcu_dereference_bh(q->filter_list); > - result = tcf_classify(skb, fl, &res, false); > + result = tcf_classify(skb, NULL, fl, &res, false); > if (result >= 0) { > #ifdef CONFIG_NET_CLS_ACT > switch (result) { > diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c > index 4074c50..28a7ed6 100644 > --- a/net/sched/sch_sfb.c > +++ b/net/sched/sch_sfb.c > @@ -257,7 +257,7 @@ static bool sfb_classify(struct sk_buff *skb, struct tcf_proto *fl, > struct tcf_result res; > int result; > > - result = tcf_classify(skb, fl, &res, false); > + result = tcf_classify(skb, NULL, fl, &res, false); > if (result >= 0) { > #ifdef CONFIG_NET_CLS_ACT > switch (result) { > diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c > index b92bafa..a090c53 100644 > --- a/net/sched/sch_sfq.c > +++ b/net/sched/sch_sfq.c > @@ -178,7 +178,7 @@ static unsigned int sfq_classify(struct sk_buff *skb, struct Qdisc *sch, > return sfq_hash(q, skb) + 1; > > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > - result = tcf_classify(skb, fl, &res, false); > + result = tcf_classify(skb, NULL, fl, &res, false); > if (result >= 0) { > #ifdef CONFIG_NET_CLS_ACT > switch (result) { Acked-by: Tim Gardner <tim.gardner@canonical.com> One can only assume this patch is destined for focal/bluefield
Acked-by Zachary Tahenakos <zachary.tahenakos@canonical.com> On Wed, Jul 27, 2022 at 5:53 PM Bodong Wang <bodong@nvidia.com> wrote: > From: Davide Caratti <dcaratti@redhat.com> > > BugLink: https://bugs.launchpad.net/bugs/1982980 > > currently, only 'ingress' and 'clsact ingress' qdiscs store the tc 'chain > id' in the skb extension. However, userspace programs (like ovs) are able > to setup egress rules, and datapath gets confused in case it doesn't find > the 'chain id' for a packet that's "recirculated" by tc. > Change tcf_classify() to have the same semantic as tcf_classify_ingress() > so that a single function can be called in ingress / egress, using the tc > ingress / egress block respectively. > > Suggested-by: Alaa Hleilel <alaa@nvidia.com> > Signed-off-by: Davide Caratti <dcaratti@redhat.com> > Reviewed-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> > Signed-off-by: David S. Miller <davem@davemloft.net> > (backported from commit 3aa2605594556c676fb88744bd9845acae60683d) > [paulb: Removed tcf_qevent_handle change in cls_api] > Signed-off-by: Paul Blakey <paulb@nvidia.com> > Signed-off-by: Bodong Wang <bodong@nvidia.com> > --- > include/net/pkt_cls.h | 22 +++++++--------------- > net/core/dev.c | 5 ++--- > net/sched/cls_api.c | 40 ++++++++++++++++------------------------ > net/sched/sch_atm.c | 2 +- > net/sched/sch_cake.c | 2 +- > net/sched/sch_cbq.c | 2 +- > net/sched/sch_drr.c | 2 +- > net/sched/sch_dsmark.c | 2 +- > net/sched/sch_fq_codel.c | 2 +- > net/sched/sch_hfsc.c | 2 +- > net/sched/sch_htb.c | 2 +- > net/sched/sch_multiq.c | 2 +- > net/sched/sch_prio.c | 2 +- > net/sched/sch_qfq.c | 2 +- > net/sched/sch_sfb.c | 2 +- > net/sched/sch_sfq.c | 2 +- > 16 files changed, 38 insertions(+), 55 deletions(-) > > diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h > index d23d7fe..18e9373 100644 > --- a/include/net/pkt_cls.h > +++ b/include/net/pkt_cls.h > @@ -70,12 +70,10 @@ static inline struct Qdisc *tcf_block_q(struct > tcf_block *block) > return block->q; > } > > -int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp, > - struct tcf_result *res, bool compat_mode); > -int tcf_classify_ingress(struct sk_buff *skb, > - const struct tcf_block *ingress_block, > - const struct tcf_proto *tp, struct tcf_result > *res, > - bool compat_mode); > +int tcf_classify(struct sk_buff *skb, > + const struct tcf_block *block, > + const struct tcf_proto *tp, struct tcf_result *res, > + bool compat_mode); > > #else > static inline bool tcf_block_shared(struct tcf_block *block) > @@ -132,20 +130,14 @@ void tc_setup_cb_block_unregister(struct tcf_block > *block, flow_setup_cb_t *cb, > { > } > > -static inline int tcf_classify(struct sk_buff *skb, const struct > tcf_proto *tp, > +static inline int tcf_classify(struct sk_buff *skb, > + const struct tcf_block *block, > + const struct tcf_proto *tp, > struct tcf_result *res, bool compat_mode) > { > return TC_ACT_UNSPEC; > } > > -static inline int tcf_classify_ingress(struct sk_buff *skb, > - const struct tcf_block > *ingress_block, > - const struct tcf_proto *tp, > - struct tcf_result *res, bool > compat_mode) > -{ > - return TC_ACT_UNSPEC; > -} > - > #endif > > static inline unsigned long > diff --git a/net/core/dev.c b/net/core/dev.c > index 4a32897..a50c5dd 100644 > --- a/net/core/dev.c > +++ b/net/core/dev.c > @@ -3513,7 +3513,7 @@ int dev_loopback_xmit(struct net *net, struct sock > *sk, struct sk_buff *skb) > tc_skb_cb(skb)->post_ct = false; > mini_qdisc_bstats_cpu_update(miniq, skb); > > - switch (tcf_classify(skb, miniq->filter_list, &cl_res, false)) { > + switch (tcf_classify(skb, miniq->block, miniq->filter_list, > &cl_res, false)) { > case TC_ACT_OK: > case TC_ACT_RECLASSIFY: > skb->tc_index = TC_H_MIN(cl_res.classid); > @@ -4608,8 +4608,7 @@ static __latent_entropy void net_tx_action(struct > softirq_action *h) > skb->tc_at_ingress = 1; > mini_qdisc_bstats_cpu_update(miniq, skb); > > - switch (tcf_classify_ingress(skb, miniq->block, miniq->filter_list, > - &cl_res, false)) { > + switch (tcf_classify(skb, miniq->block, miniq->filter_list, > &cl_res, false)) { > case TC_ACT_OK: > case TC_ACT_RECLASSIFY: > skb->tc_index = TC_H_MIN(cl_res.classid); > diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c > index 698648a..ddc2d94 100644 > --- a/net/sched/cls_api.c > +++ b/net/sched/cls_api.c > @@ -1628,21 +1628,11 @@ static inline int __tcf_classify(struct sk_buff > *skb, > #endif > } > > -int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp, > +int tcf_classify(struct sk_buff *skb, > + const struct tcf_block *block, > + const struct tcf_proto *tp, > struct tcf_result *res, bool compat_mode) > { > - u32 last_executed_chain = 0; > - > - return __tcf_classify(skb, tp, tp, res, compat_mode, > - &last_executed_chain); > -} > -EXPORT_SYMBOL(tcf_classify); > - > -int tcf_classify_ingress(struct sk_buff *skb, > - const struct tcf_block *ingress_block, > - const struct tcf_proto *tp, > - struct tcf_result *res, bool compat_mode) > -{ > #if !IS_ENABLED(CONFIG_NET_TC_SKB_EXT) > u32 last_executed_chain = 0; > > @@ -1654,20 +1644,22 @@ int tcf_classify_ingress(struct sk_buff *skb, > struct tc_skb_ext *ext; > int ret; > > - ext = skb_ext_find(skb, TC_SKB_EXT); > + if (block) { > + ext = skb_ext_find(skb, TC_SKB_EXT); > > - if (ext && ext->chain) { > - struct tcf_chain *fchain; > + if (ext && ext->chain) { > + struct tcf_chain *fchain; > > - fchain = tcf_chain_lookup_rcu(ingress_block, ext->chain); > - if (!fchain) > - return TC_ACT_SHOT; > + fchain = tcf_chain_lookup_rcu(block, ext->chain); > + if (!fchain) > + return TC_ACT_SHOT; > > - /* Consume, so cloned/redirect skbs won't inherit ext */ > - skb_ext_del(skb, TC_SKB_EXT); > + /* Consume, so cloned/redirect skbs won't inherit > ext */ > + skb_ext_del(skb, TC_SKB_EXT); > > - tp = rcu_dereference_bh(fchain->filter_chain); > - last_executed_chain = fchain->index; > + tp = rcu_dereference_bh(fchain->filter_chain); > + last_executed_chain = fchain->index; > + } > } > > ret = __tcf_classify(skb, tp, orig_tp, res, compat_mode, > @@ -1691,7 +1683,7 @@ int tcf_classify_ingress(struct sk_buff *skb, > return ret; > #endif > } > -EXPORT_SYMBOL(tcf_classify_ingress); > +EXPORT_SYMBOL(tcf_classify); > > struct tcf_chain_info { > struct tcf_proto __rcu **pprev; > diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c > index 6385995..98a52c3 100644 > --- a/net/sched/sch_atm.c > +++ b/net/sched/sch_atm.c > @@ -393,7 +393,7 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct > Qdisc *sch, > list_for_each_entry(flow, &p->flows, list) { > fl = rcu_dereference_bh(flow->filter_list); > if (fl) { > - result = tcf_classify(skb, fl, &res, true); > + result = tcf_classify(skb, NULL, fl, &res, > true); > if (result < 0) > continue; > flow = (struct atm_flow_data *)res.class; > diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c > index 0eb4d4a..e36c34a 100644 > --- a/net/sched/sch_cake.c > +++ b/net/sched/sch_cake.c > @@ -1629,7 +1629,7 @@ static u32 cake_classify(struct Qdisc *sch, struct > cake_tin_data **t, > goto hash; > > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > - result = tcf_classify(skb, filter, &res, false); > + result = tcf_classify(skb, NULL, filter, &res, false); > > if (result >= 0) { > #ifdef CONFIG_NET_CLS_ACT > diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c > index e597288..5b7ea18 100644 > --- a/net/sched/sch_cbq.c > +++ b/net/sched/sch_cbq.c > @@ -228,7 +228,7 @@ struct cbq_sched_data { > /* > * Step 2+n. Apply classifier. > */ > - result = tcf_classify(skb, fl, &res, true); > + result = tcf_classify(skb, NULL, fl, &res, true); > if (!fl || result < 0) > goto fallback; > > diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c > index 07a2b0b..60a5a56 100644 > --- a/net/sched/sch_drr.c > +++ b/net/sched/sch_drr.c > @@ -316,7 +316,7 @@ static struct drr_class *drr_classify(struct sk_buff > *skb, struct Qdisc *sch, > > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > fl = rcu_dereference_bh(q->filter_list); > - result = tcf_classify(skb, fl, &res, false); > + result = tcf_classify(skb, NULL, fl, &res, false); > if (result >= 0) { > #ifdef CONFIG_NET_CLS_ACT > switch (result) { > diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c > index 76ed1a0..5be11c4 100644 > --- a/net/sched/sch_dsmark.c > +++ b/net/sched/sch_dsmark.c > @@ -241,7 +241,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct > Qdisc *sch, > else { > struct tcf_result res; > struct tcf_proto *fl = rcu_dereference_bh(p->filter_list); > - int result = tcf_classify(skb, fl, &res, false); > + int result = tcf_classify(skb, NULL, fl, &res, false); > > pr_debug("result %d class 0x%04x\n", result, res.classid); > > diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c > index 86fb2f9..1d2f3f4 100644 > --- a/net/sched/sch_fq_codel.c > +++ b/net/sched/sch_fq_codel.c > @@ -92,7 +92,7 @@ static unsigned int fq_codel_classify(struct sk_buff > *skb, struct Qdisc *sch, > return fq_codel_hash(q, skb) + 1; > > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > - result = tcf_classify(skb, filter, &res, false); > + result = tcf_classify(skb, NULL, filter, &res, false); > if (result >= 0) { > #ifdef CONFIG_NET_CLS_ACT > switch (result) { > diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c > index 433f219..091eea4 100644 > --- a/net/sched/sch_hfsc.c > +++ b/net/sched/sch_hfsc.c > @@ -1129,7 +1129,7 @@ struct hfsc_sched { > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > head = &q->root; > tcf = rcu_dereference_bh(q->root.filter_list); > - while (tcf && (result = tcf_classify(skb, tcf, &res, false)) >= 0) > { > + while (tcf && (result = tcf_classify(skb, NULL, tcf, &res, false)) > >= 0) { > #ifdef CONFIG_NET_CLS_ACT > switch (result) { > case TC_ACT_QUEUED: > diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c > index 8184c87..176359f 100644 > --- a/net/sched/sch_htb.c > +++ b/net/sched/sch_htb.c > @@ -232,7 +232,7 @@ static struct htb_class *htb_classify(struct sk_buff > *skb, struct Qdisc *sch, > } > > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > - while (tcf && (result = tcf_classify(skb, tcf, &res, false)) >= 0) > { > + while (tcf && (result = tcf_classify(skb, NULL, tcf, &res, false)) > >= 0) { > #ifdef CONFIG_NET_CLS_ACT > switch (result) { > case TC_ACT_QUEUED: > diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c > index 1330ad2..bc5f288 100644 > --- a/net/sched/sch_multiq.c > +++ b/net/sched/sch_multiq.c > @@ -36,7 +36,7 @@ struct multiq_sched_data { > int err; > > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > - err = tcf_classify(skb, fl, &res, false); > + err = tcf_classify(skb, NULL, fl, &res, false); > #ifdef CONFIG_NET_CLS_ACT > switch (err) { > case TC_ACT_STOLEN: > diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c > index 6479417..41573b8 100644 > --- a/net/sched/sch_prio.c > +++ b/net/sched/sch_prio.c > @@ -39,7 +39,7 @@ struct prio_sched_data { > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > if (TC_H_MAJ(skb->priority) != sch->handle) { > fl = rcu_dereference_bh(q->filter_list); > - err = tcf_classify(skb, fl, &res, false); > + err = tcf_classify(skb, NULL, fl, &res, false); > #ifdef CONFIG_NET_CLS_ACT > switch (err) { > case TC_ACT_STOLEN: > diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c > index 1eb339d..d6827b54 100644 > --- a/net/sched/sch_qfq.c > +++ b/net/sched/sch_qfq.c > @@ -689,7 +689,7 @@ static struct qfq_class *qfq_classify(struct sk_buff > *skb, struct Qdisc *sch, > > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > fl = rcu_dereference_bh(q->filter_list); > - result = tcf_classify(skb, fl, &res, false); > + result = tcf_classify(skb, NULL, fl, &res, false); > if (result >= 0) { > #ifdef CONFIG_NET_CLS_ACT > switch (result) { > diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c > index 4074c50..28a7ed6 100644 > --- a/net/sched/sch_sfb.c > +++ b/net/sched/sch_sfb.c > @@ -257,7 +257,7 @@ static bool sfb_classify(struct sk_buff *skb, struct > tcf_proto *fl, > struct tcf_result res; > int result; > > - result = tcf_classify(skb, fl, &res, false); > + result = tcf_classify(skb, NULL, fl, &res, false); > if (result >= 0) { > #ifdef CONFIG_NET_CLS_ACT > switch (result) { > diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c > index b92bafa..a090c53 100644 > --- a/net/sched/sch_sfq.c > +++ b/net/sched/sch_sfq.c > @@ -178,7 +178,7 @@ static unsigned int sfq_classify(struct sk_buff *skb, > struct Qdisc *sch, > return sfq_hash(q, skb) + 1; > > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > - result = tcf_classify(skb, fl, &res, false); > + result = tcf_classify(skb, NULL, fl, &res, false); > if (result >= 0) { > #ifdef CONFIG_NET_CLS_ACT > switch (result) { > -- > 1.8.3.1 > > > -- > kernel-team mailing list > kernel-team@lists.ubuntu.com > https://lists.ubuntu.com/mailman/listinfo/kernel-team >
Applied to focal:linux-bluefield. Thanks, Zack On Wed, Jul 27, 2022 at 5:53 PM Bodong Wang <bodong@nvidia.com> wrote: > From: Davide Caratti <dcaratti@redhat.com> > > BugLink: https://bugs.launchpad.net/bugs/1982980 > > currently, only 'ingress' and 'clsact ingress' qdiscs store the tc 'chain > id' in the skb extension. However, userspace programs (like ovs) are able > to setup egress rules, and datapath gets confused in case it doesn't find > the 'chain id' for a packet that's "recirculated" by tc. > Change tcf_classify() to have the same semantic as tcf_classify_ingress() > so that a single function can be called in ingress / egress, using the tc > ingress / egress block respectively. > > Suggested-by: Alaa Hleilel <alaa@nvidia.com> > Signed-off-by: Davide Caratti <dcaratti@redhat.com> > Reviewed-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> > Signed-off-by: David S. Miller <davem@davemloft.net> > (backported from commit 3aa2605594556c676fb88744bd9845acae60683d) > [paulb: Removed tcf_qevent_handle change in cls_api] > Signed-off-by: Paul Blakey <paulb@nvidia.com> > Signed-off-by: Bodong Wang <bodong@nvidia.com> > --- > include/net/pkt_cls.h | 22 +++++++--------------- > net/core/dev.c | 5 ++--- > net/sched/cls_api.c | 40 ++++++++++++++++------------------------ > net/sched/sch_atm.c | 2 +- > net/sched/sch_cake.c | 2 +- > net/sched/sch_cbq.c | 2 +- > net/sched/sch_drr.c | 2 +- > net/sched/sch_dsmark.c | 2 +- > net/sched/sch_fq_codel.c | 2 +- > net/sched/sch_hfsc.c | 2 +- > net/sched/sch_htb.c | 2 +- > net/sched/sch_multiq.c | 2 +- > net/sched/sch_prio.c | 2 +- > net/sched/sch_qfq.c | 2 +- > net/sched/sch_sfb.c | 2 +- > net/sched/sch_sfq.c | 2 +- > 16 files changed, 38 insertions(+), 55 deletions(-) > > diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h > index d23d7fe..18e9373 100644 > --- a/include/net/pkt_cls.h > +++ b/include/net/pkt_cls.h > @@ -70,12 +70,10 @@ static inline struct Qdisc *tcf_block_q(struct > tcf_block *block) > return block->q; > } > > -int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp, > - struct tcf_result *res, bool compat_mode); > -int tcf_classify_ingress(struct sk_buff *skb, > - const struct tcf_block *ingress_block, > - const struct tcf_proto *tp, struct tcf_result > *res, > - bool compat_mode); > +int tcf_classify(struct sk_buff *skb, > + const struct tcf_block *block, > + const struct tcf_proto *tp, struct tcf_result *res, > + bool compat_mode); > > #else > static inline bool tcf_block_shared(struct tcf_block *block) > @@ -132,20 +130,14 @@ void tc_setup_cb_block_unregister(struct tcf_block > *block, flow_setup_cb_t *cb, > { > } > > -static inline int tcf_classify(struct sk_buff *skb, const struct > tcf_proto *tp, > +static inline int tcf_classify(struct sk_buff *skb, > + const struct tcf_block *block, > + const struct tcf_proto *tp, > struct tcf_result *res, bool compat_mode) > { > return TC_ACT_UNSPEC; > } > > -static inline int tcf_classify_ingress(struct sk_buff *skb, > - const struct tcf_block > *ingress_block, > - const struct tcf_proto *tp, > - struct tcf_result *res, bool > compat_mode) > -{ > - return TC_ACT_UNSPEC; > -} > - > #endif > > static inline unsigned long > diff --git a/net/core/dev.c b/net/core/dev.c > index 4a32897..a50c5dd 100644 > --- a/net/core/dev.c > +++ b/net/core/dev.c > @@ -3513,7 +3513,7 @@ int dev_loopback_xmit(struct net *net, struct sock > *sk, struct sk_buff *skb) > tc_skb_cb(skb)->post_ct = false; > mini_qdisc_bstats_cpu_update(miniq, skb); > > - switch (tcf_classify(skb, miniq->filter_list, &cl_res, false)) { > + switch (tcf_classify(skb, miniq->block, miniq->filter_list, > &cl_res, false)) { > case TC_ACT_OK: > case TC_ACT_RECLASSIFY: > skb->tc_index = TC_H_MIN(cl_res.classid); > @@ -4608,8 +4608,7 @@ static __latent_entropy void net_tx_action(struct > softirq_action *h) > skb->tc_at_ingress = 1; > mini_qdisc_bstats_cpu_update(miniq, skb); > > - switch (tcf_classify_ingress(skb, miniq->block, miniq->filter_list, > - &cl_res, false)) { > + switch (tcf_classify(skb, miniq->block, miniq->filter_list, > &cl_res, false)) { > case TC_ACT_OK: > case TC_ACT_RECLASSIFY: > skb->tc_index = TC_H_MIN(cl_res.classid); > diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c > index 698648a..ddc2d94 100644 > --- a/net/sched/cls_api.c > +++ b/net/sched/cls_api.c > @@ -1628,21 +1628,11 @@ static inline int __tcf_classify(struct sk_buff > *skb, > #endif > } > > -int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp, > +int tcf_classify(struct sk_buff *skb, > + const struct tcf_block *block, > + const struct tcf_proto *tp, > struct tcf_result *res, bool compat_mode) > { > - u32 last_executed_chain = 0; > - > - return __tcf_classify(skb, tp, tp, res, compat_mode, > - &last_executed_chain); > -} > -EXPORT_SYMBOL(tcf_classify); > - > -int tcf_classify_ingress(struct sk_buff *skb, > - const struct tcf_block *ingress_block, > - const struct tcf_proto *tp, > - struct tcf_result *res, bool compat_mode) > -{ > #if !IS_ENABLED(CONFIG_NET_TC_SKB_EXT) > u32 last_executed_chain = 0; > > @@ -1654,20 +1644,22 @@ int tcf_classify_ingress(struct sk_buff *skb, > struct tc_skb_ext *ext; > int ret; > > - ext = skb_ext_find(skb, TC_SKB_EXT); > + if (block) { > + ext = skb_ext_find(skb, TC_SKB_EXT); > > - if (ext && ext->chain) { > - struct tcf_chain *fchain; > + if (ext && ext->chain) { > + struct tcf_chain *fchain; > > - fchain = tcf_chain_lookup_rcu(ingress_block, ext->chain); > - if (!fchain) > - return TC_ACT_SHOT; > + fchain = tcf_chain_lookup_rcu(block, ext->chain); > + if (!fchain) > + return TC_ACT_SHOT; > > - /* Consume, so cloned/redirect skbs won't inherit ext */ > - skb_ext_del(skb, TC_SKB_EXT); > + /* Consume, so cloned/redirect skbs won't inherit > ext */ > + skb_ext_del(skb, TC_SKB_EXT); > > - tp = rcu_dereference_bh(fchain->filter_chain); > - last_executed_chain = fchain->index; > + tp = rcu_dereference_bh(fchain->filter_chain); > + last_executed_chain = fchain->index; > + } > } > > ret = __tcf_classify(skb, tp, orig_tp, res, compat_mode, > @@ -1691,7 +1683,7 @@ int tcf_classify_ingress(struct sk_buff *skb, > return ret; > #endif > } > -EXPORT_SYMBOL(tcf_classify_ingress); > +EXPORT_SYMBOL(tcf_classify); > > struct tcf_chain_info { > struct tcf_proto __rcu **pprev; > diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c > index 6385995..98a52c3 100644 > --- a/net/sched/sch_atm.c > +++ b/net/sched/sch_atm.c > @@ -393,7 +393,7 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct > Qdisc *sch, > list_for_each_entry(flow, &p->flows, list) { > fl = rcu_dereference_bh(flow->filter_list); > if (fl) { > - result = tcf_classify(skb, fl, &res, true); > + result = tcf_classify(skb, NULL, fl, &res, > true); > if (result < 0) > continue; > flow = (struct atm_flow_data *)res.class; > diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c > index 0eb4d4a..e36c34a 100644 > --- a/net/sched/sch_cake.c > +++ b/net/sched/sch_cake.c > @@ -1629,7 +1629,7 @@ static u32 cake_classify(struct Qdisc *sch, struct > cake_tin_data **t, > goto hash; > > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > - result = tcf_classify(skb, filter, &res, false); > + result = tcf_classify(skb, NULL, filter, &res, false); > > if (result >= 0) { > #ifdef CONFIG_NET_CLS_ACT > diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c > index e597288..5b7ea18 100644 > --- a/net/sched/sch_cbq.c > +++ b/net/sched/sch_cbq.c > @@ -228,7 +228,7 @@ struct cbq_sched_data { > /* > * Step 2+n. Apply classifier. > */ > - result = tcf_classify(skb, fl, &res, true); > + result = tcf_classify(skb, NULL, fl, &res, true); > if (!fl || result < 0) > goto fallback; > > diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c > index 07a2b0b..60a5a56 100644 > --- a/net/sched/sch_drr.c > +++ b/net/sched/sch_drr.c > @@ -316,7 +316,7 @@ static struct drr_class *drr_classify(struct sk_buff > *skb, struct Qdisc *sch, > > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > fl = rcu_dereference_bh(q->filter_list); > - result = tcf_classify(skb, fl, &res, false); > + result = tcf_classify(skb, NULL, fl, &res, false); > if (result >= 0) { > #ifdef CONFIG_NET_CLS_ACT > switch (result) { > diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c > index 76ed1a0..5be11c4 100644 > --- a/net/sched/sch_dsmark.c > +++ b/net/sched/sch_dsmark.c > @@ -241,7 +241,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct > Qdisc *sch, > else { > struct tcf_result res; > struct tcf_proto *fl = rcu_dereference_bh(p->filter_list); > - int result = tcf_classify(skb, fl, &res, false); > + int result = tcf_classify(skb, NULL, fl, &res, false); > > pr_debug("result %d class 0x%04x\n", result, res.classid); > > diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c > index 86fb2f9..1d2f3f4 100644 > --- a/net/sched/sch_fq_codel.c > +++ b/net/sched/sch_fq_codel.c > @@ -92,7 +92,7 @@ static unsigned int fq_codel_classify(struct sk_buff > *skb, struct Qdisc *sch, > return fq_codel_hash(q, skb) + 1; > > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > - result = tcf_classify(skb, filter, &res, false); > + result = tcf_classify(skb, NULL, filter, &res, false); > if (result >= 0) { > #ifdef CONFIG_NET_CLS_ACT > switch (result) { > diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c > index 433f219..091eea4 100644 > --- a/net/sched/sch_hfsc.c > +++ b/net/sched/sch_hfsc.c > @@ -1129,7 +1129,7 @@ struct hfsc_sched { > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > head = &q->root; > tcf = rcu_dereference_bh(q->root.filter_list); > - while (tcf && (result = tcf_classify(skb, tcf, &res, false)) >= 0) > { > + while (tcf && (result = tcf_classify(skb, NULL, tcf, &res, false)) > >= 0) { > #ifdef CONFIG_NET_CLS_ACT > switch (result) { > case TC_ACT_QUEUED: > diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c > index 8184c87..176359f 100644 > --- a/net/sched/sch_htb.c > +++ b/net/sched/sch_htb.c > @@ -232,7 +232,7 @@ static struct htb_class *htb_classify(struct sk_buff > *skb, struct Qdisc *sch, > } > > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > - while (tcf && (result = tcf_classify(skb, tcf, &res, false)) >= 0) > { > + while (tcf && (result = tcf_classify(skb, NULL, tcf, &res, false)) > >= 0) { > #ifdef CONFIG_NET_CLS_ACT > switch (result) { > case TC_ACT_QUEUED: > diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c > index 1330ad2..bc5f288 100644 > --- a/net/sched/sch_multiq.c > +++ b/net/sched/sch_multiq.c > @@ -36,7 +36,7 @@ struct multiq_sched_data { > int err; > > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > - err = tcf_classify(skb, fl, &res, false); > + err = tcf_classify(skb, NULL, fl, &res, false); > #ifdef CONFIG_NET_CLS_ACT > switch (err) { > case TC_ACT_STOLEN: > diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c > index 6479417..41573b8 100644 > --- a/net/sched/sch_prio.c > +++ b/net/sched/sch_prio.c > @@ -39,7 +39,7 @@ struct prio_sched_data { > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > if (TC_H_MAJ(skb->priority) != sch->handle) { > fl = rcu_dereference_bh(q->filter_list); > - err = tcf_classify(skb, fl, &res, false); > + err = tcf_classify(skb, NULL, fl, &res, false); > #ifdef CONFIG_NET_CLS_ACT > switch (err) { > case TC_ACT_STOLEN: > diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c > index 1eb339d..d6827b54 100644 > --- a/net/sched/sch_qfq.c > +++ b/net/sched/sch_qfq.c > @@ -689,7 +689,7 @@ static struct qfq_class *qfq_classify(struct sk_buff > *skb, struct Qdisc *sch, > > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > fl = rcu_dereference_bh(q->filter_list); > - result = tcf_classify(skb, fl, &res, false); > + result = tcf_classify(skb, NULL, fl, &res, false); > if (result >= 0) { > #ifdef CONFIG_NET_CLS_ACT > switch (result) { > diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c > index 4074c50..28a7ed6 100644 > --- a/net/sched/sch_sfb.c > +++ b/net/sched/sch_sfb.c > @@ -257,7 +257,7 @@ static bool sfb_classify(struct sk_buff *skb, struct > tcf_proto *fl, > struct tcf_result res; > int result; > > - result = tcf_classify(skb, fl, &res, false); > + result = tcf_classify(skb, NULL, fl, &res, false); > if (result >= 0) { > #ifdef CONFIG_NET_CLS_ACT > switch (result) { > diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c > index b92bafa..a090c53 100644 > --- a/net/sched/sch_sfq.c > +++ b/net/sched/sch_sfq.c > @@ -178,7 +178,7 @@ static unsigned int sfq_classify(struct sk_buff *skb, > struct Qdisc *sch, > return sfq_hash(q, skb) + 1; > > *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; > - result = tcf_classify(skb, fl, &res, false); > + result = tcf_classify(skb, NULL, fl, &res, false); > if (result >= 0) { > #ifdef CONFIG_NET_CLS_ACT > switch (result) { > -- > 1.8.3.1 > > > -- > kernel-team mailing list > kernel-team@lists.ubuntu.com > https://lists.ubuntu.com/mailman/listinfo/kernel-team >
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index d23d7fe..18e9373 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -70,12 +70,10 @@ static inline struct Qdisc *tcf_block_q(struct tcf_block *block) return block->q; } -int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp, - struct tcf_result *res, bool compat_mode); -int tcf_classify_ingress(struct sk_buff *skb, - const struct tcf_block *ingress_block, - const struct tcf_proto *tp, struct tcf_result *res, - bool compat_mode); +int tcf_classify(struct sk_buff *skb, + const struct tcf_block *block, + const struct tcf_proto *tp, struct tcf_result *res, + bool compat_mode); #else static inline bool tcf_block_shared(struct tcf_block *block) @@ -132,20 +130,14 @@ void tc_setup_cb_block_unregister(struct tcf_block *block, flow_setup_cb_t *cb, { } -static inline int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp, +static inline int tcf_classify(struct sk_buff *skb, + const struct tcf_block *block, + const struct tcf_proto *tp, struct tcf_result *res, bool compat_mode) { return TC_ACT_UNSPEC; } -static inline int tcf_classify_ingress(struct sk_buff *skb, - const struct tcf_block *ingress_block, - const struct tcf_proto *tp, - struct tcf_result *res, bool compat_mode) -{ - return TC_ACT_UNSPEC; -} - #endif static inline unsigned long diff --git a/net/core/dev.c b/net/core/dev.c index 4a32897..a50c5dd 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3513,7 +3513,7 @@ int dev_loopback_xmit(struct net *net, struct sock *sk, struct sk_buff *skb) tc_skb_cb(skb)->post_ct = false; mini_qdisc_bstats_cpu_update(miniq, skb); - switch (tcf_classify(skb, miniq->filter_list, &cl_res, false)) { + switch (tcf_classify(skb, miniq->block, miniq->filter_list, &cl_res, false)) { case TC_ACT_OK: case TC_ACT_RECLASSIFY: skb->tc_index = TC_H_MIN(cl_res.classid); @@ -4608,8 +4608,7 @@ static __latent_entropy void net_tx_action(struct softirq_action *h) skb->tc_at_ingress = 1; mini_qdisc_bstats_cpu_update(miniq, skb); - switch (tcf_classify_ingress(skb, miniq->block, miniq->filter_list, - &cl_res, false)) { + switch (tcf_classify(skb, miniq->block, miniq->filter_list, &cl_res, false)) { case TC_ACT_OK: case TC_ACT_RECLASSIFY: skb->tc_index = TC_H_MIN(cl_res.classid); diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 698648a..ddc2d94 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -1628,21 +1628,11 @@ static inline int __tcf_classify(struct sk_buff *skb, #endif } -int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp, +int tcf_classify(struct sk_buff *skb, + const struct tcf_block *block, + const struct tcf_proto *tp, struct tcf_result *res, bool compat_mode) { - u32 last_executed_chain = 0; - - return __tcf_classify(skb, tp, tp, res, compat_mode, - &last_executed_chain); -} -EXPORT_SYMBOL(tcf_classify); - -int tcf_classify_ingress(struct sk_buff *skb, - const struct tcf_block *ingress_block, - const struct tcf_proto *tp, - struct tcf_result *res, bool compat_mode) -{ #if !IS_ENABLED(CONFIG_NET_TC_SKB_EXT) u32 last_executed_chain = 0; @@ -1654,20 +1644,22 @@ int tcf_classify_ingress(struct sk_buff *skb, struct tc_skb_ext *ext; int ret; - ext = skb_ext_find(skb, TC_SKB_EXT); + if (block) { + ext = skb_ext_find(skb, TC_SKB_EXT); - if (ext && ext->chain) { - struct tcf_chain *fchain; + if (ext && ext->chain) { + struct tcf_chain *fchain; - fchain = tcf_chain_lookup_rcu(ingress_block, ext->chain); - if (!fchain) - return TC_ACT_SHOT; + fchain = tcf_chain_lookup_rcu(block, ext->chain); + if (!fchain) + return TC_ACT_SHOT; - /* Consume, so cloned/redirect skbs won't inherit ext */ - skb_ext_del(skb, TC_SKB_EXT); + /* Consume, so cloned/redirect skbs won't inherit ext */ + skb_ext_del(skb, TC_SKB_EXT); - tp = rcu_dereference_bh(fchain->filter_chain); - last_executed_chain = fchain->index; + tp = rcu_dereference_bh(fchain->filter_chain); + last_executed_chain = fchain->index; + } } ret = __tcf_classify(skb, tp, orig_tp, res, compat_mode, @@ -1691,7 +1683,7 @@ int tcf_classify_ingress(struct sk_buff *skb, return ret; #endif } -EXPORT_SYMBOL(tcf_classify_ingress); +EXPORT_SYMBOL(tcf_classify); struct tcf_chain_info { struct tcf_proto __rcu **pprev; diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index 6385995..98a52c3 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c @@ -393,7 +393,7 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch, list_for_each_entry(flow, &p->flows, list) { fl = rcu_dereference_bh(flow->filter_list); if (fl) { - result = tcf_classify(skb, fl, &res, true); + result = tcf_classify(skb, NULL, fl, &res, true); if (result < 0) continue; flow = (struct atm_flow_data *)res.class; diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c index 0eb4d4a..e36c34a 100644 --- a/net/sched/sch_cake.c +++ b/net/sched/sch_cake.c @@ -1629,7 +1629,7 @@ static u32 cake_classify(struct Qdisc *sch, struct cake_tin_data **t, goto hash; *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; - result = tcf_classify(skb, filter, &res, false); + result = tcf_classify(skb, NULL, filter, &res, false); if (result >= 0) { #ifdef CONFIG_NET_CLS_ACT diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index e597288..5b7ea18 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -228,7 +228,7 @@ struct cbq_sched_data { /* * Step 2+n. Apply classifier. */ - result = tcf_classify(skb, fl, &res, true); + result = tcf_classify(skb, NULL, fl, &res, true); if (!fl || result < 0) goto fallback; diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c index 07a2b0b..60a5a56 100644 --- a/net/sched/sch_drr.c +++ b/net/sched/sch_drr.c @@ -316,7 +316,7 @@ static struct drr_class *drr_classify(struct sk_buff *skb, struct Qdisc *sch, *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; fl = rcu_dereference_bh(q->filter_list); - result = tcf_classify(skb, fl, &res, false); + result = tcf_classify(skb, NULL, fl, &res, false); if (result >= 0) { #ifdef CONFIG_NET_CLS_ACT switch (result) { diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index 76ed1a0..5be11c4 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c @@ -241,7 +241,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch, else { struct tcf_result res; struct tcf_proto *fl = rcu_dereference_bh(p->filter_list); - int result = tcf_classify(skb, fl, &res, false); + int result = tcf_classify(skb, NULL, fl, &res, false); pr_debug("result %d class 0x%04x\n", result, res.classid); diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c index 86fb2f9..1d2f3f4 100644 --- a/net/sched/sch_fq_codel.c +++ b/net/sched/sch_fq_codel.c @@ -92,7 +92,7 @@ static unsigned int fq_codel_classify(struct sk_buff *skb, struct Qdisc *sch, return fq_codel_hash(q, skb) + 1; *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; - result = tcf_classify(skb, filter, &res, false); + result = tcf_classify(skb, NULL, filter, &res, false); if (result >= 0) { #ifdef CONFIG_NET_CLS_ACT switch (result) { diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index 433f219..091eea4 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -1129,7 +1129,7 @@ struct hfsc_sched { *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; head = &q->root; tcf = rcu_dereference_bh(q->root.filter_list); - while (tcf && (result = tcf_classify(skb, tcf, &res, false)) >= 0) { + while (tcf && (result = tcf_classify(skb, NULL, tcf, &res, false)) >= 0) { #ifdef CONFIG_NET_CLS_ACT switch (result) { case TC_ACT_QUEUED: diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 8184c87..176359f 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -232,7 +232,7 @@ static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch, } *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; - while (tcf && (result = tcf_classify(skb, tcf, &res, false)) >= 0) { + while (tcf && (result = tcf_classify(skb, NULL, tcf, &res, false)) >= 0) { #ifdef CONFIG_NET_CLS_ACT switch (result) { case TC_ACT_QUEUED: diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c index 1330ad2..bc5f288 100644 --- a/net/sched/sch_multiq.c +++ b/net/sched/sch_multiq.c @@ -36,7 +36,7 @@ struct multiq_sched_data { int err; *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; - err = tcf_classify(skb, fl, &res, false); + err = tcf_classify(skb, NULL, fl, &res, false); #ifdef CONFIG_NET_CLS_ACT switch (err) { case TC_ACT_STOLEN: diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 6479417..41573b8 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c @@ -39,7 +39,7 @@ struct prio_sched_data { *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; if (TC_H_MAJ(skb->priority) != sch->handle) { fl = rcu_dereference_bh(q->filter_list); - err = tcf_classify(skb, fl, &res, false); + err = tcf_classify(skb, NULL, fl, &res, false); #ifdef CONFIG_NET_CLS_ACT switch (err) { case TC_ACT_STOLEN: diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index 1eb339d..d6827b54 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c @@ -689,7 +689,7 @@ static struct qfq_class *qfq_classify(struct sk_buff *skb, struct Qdisc *sch, *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; fl = rcu_dereference_bh(q->filter_list); - result = tcf_classify(skb, fl, &res, false); + result = tcf_classify(skb, NULL, fl, &res, false); if (result >= 0) { #ifdef CONFIG_NET_CLS_ACT switch (result) { diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c index 4074c50..28a7ed6 100644 --- a/net/sched/sch_sfb.c +++ b/net/sched/sch_sfb.c @@ -257,7 +257,7 @@ static bool sfb_classify(struct sk_buff *skb, struct tcf_proto *fl, struct tcf_result res; int result; - result = tcf_classify(skb, fl, &res, false); + result = tcf_classify(skb, NULL, fl, &res, false); if (result >= 0) { #ifdef CONFIG_NET_CLS_ACT switch (result) { diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index b92bafa..a090c53 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -178,7 +178,7 @@ static unsigned int sfq_classify(struct sk_buff *skb, struct Qdisc *sch, return sfq_hash(q, skb) + 1; *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; - result = tcf_classify(skb, fl, &res, false); + result = tcf_classify(skb, NULL, fl, &res, false); if (result >= 0) { #ifdef CONFIG_NET_CLS_ACT switch (result) {