Message ID | 20211028110646.13791-9-simon.horman@corigine.com (mailing list archive) |
---|---|
State | RFC |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | allow user to offload tc action to net device | expand |
Context | Check | Description |
---|---|---|
netdev/cover_letter | success | Series has a cover letter |
netdev/fixes_present | success | Fixes tag not required for -next series |
netdev/patch_count | success | Link |
netdev/tree_selection | success | Clearly marked for net-next |
netdev/subject_prefix | success | Link |
netdev/cc_maintainers | warning | 2 maintainers not CCed: davem@davemloft.net kuba@kernel.org |
netdev/source_inline | success | Was 0 now: 0 |
netdev/verify_signedoff | success | Signed-off-by tag matches author and committer |
netdev/module_param | success | Was 0 now: 0 |
netdev/build_32bit | success | Errors and warnings before: 8 this patch: 8 |
netdev/kdoc | success | Errors and warnings before: 0 this patch: 0 |
netdev/verify_fixes | success | No Fixes tag |
netdev/checkpatch | success | total: 0 errors, 0 warnings, 0 checks, 76 lines checked |
netdev/build_allmodconfig_warn | success | Errors and warnings before: 8 this patch: 8 |
netdev/header_inline | success | No static functions without inline keyword in header files |
On Thu 28 Oct 2021 at 14:06, Simon Horman <simon.horman@corigine.com> wrote: > From: Baowen Zheng <baowen.zheng@corigine.com> > > Add process to validate flags of filter and actions when adding > a tc filter. > > We need to prevent adding filter with flags conflicts with its actions. > > Signed-off-by: Baowen Zheng <baowen.zheng@corigine.com> > Signed-off-by: Louis Peens <louis.peens@corigine.com> > Signed-off-by: Simon Horman <simon.horman@corigine.com> > --- > net/sched/cls_api.c | 26 ++++++++++++++++++++++++++ > net/sched/cls_flower.c | 3 ++- > net/sched/cls_matchall.c | 4 ++-- > net/sched/cls_u32.c | 7 ++++--- > 4 files changed, 34 insertions(+), 6 deletions(-) > > diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c > index 351d93988b8b..80647da9713a 100644 > --- a/net/sched/cls_api.c > +++ b/net/sched/cls_api.c > @@ -3025,6 +3025,29 @@ void tcf_exts_destroy(struct tcf_exts *exts) > } > EXPORT_SYMBOL(tcf_exts_destroy); > > +static bool tcf_exts_validate_actions(const struct tcf_exts *exts, u32 flags) > +{ > +#ifdef CONFIG_NET_CLS_ACT > + bool skip_sw = tc_skip_sw(flags); > + bool skip_hw = tc_skip_hw(flags); > + int i; > + > + if (!(skip_sw | skip_hw)) > + return true; > + > + for (i = 0; i < exts->nr_actions; i++) { > + struct tc_action *a = exts->actions[i]; > + > + if ((skip_sw && tc_act_skip_hw(a->tcfa_flags)) || > + (skip_hw && tc_act_skip_sw(a->tcfa_flags))) > + return false; > + } > + return true; > +#else > + return true; > +#endif > +} > + I know Jamal suggested to have skip_sw for actions, but it complicates the code and I'm still not entirely understand why it is necessary. After all, action can only get applied to a packet if the packet has been matched by some filter and filters already have skip sw/hw controls. Forgoing action skip_sw flag would: - Alleviate the need to validate that filter and action flags are compatible. (trying to offload filter that points to existing skip_hw action would just fail because the driver wouldn't find the action with provided id in its tables) - Remove the need to add more conditionals into TC software data path in patch 4. WDYT? > int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb, > struct nlattr *rate_tlv, struct tcf_exts *exts, > u32 flags, struct netlink_ext_ack *extack) > @@ -3066,6 +3089,9 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb, > return err; > exts->nr_actions = err; > } > + > + if (!tcf_exts_validate_actions(exts, flags)) > + return -EINVAL; > } > #else > if ((exts->action && tb[exts->action]) || > diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c > index eb6345a027e1..55f89f0e393e 100644 > --- a/net/sched/cls_flower.c > +++ b/net/sched/cls_flower.c > @@ -2035,7 +2035,8 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, > } > > err = fl_set_parms(net, tp, fnew, mask, base, tb, tca[TCA_RATE], > - tp->chain->tmplt_priv, flags, extack); > + tp->chain->tmplt_priv, flags | fnew->flags, > + extack); Aren't you or-ing flags from two different ranges (TCA_CLS_FLAGS_* and TCA_ACT_FLAGS_*) that map to same bits, or am I missing something? This isn't explained in commit message so it is hard for me to understand the idea here. > if (err) > goto errout; > > diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c > index 24f0046ce0b3..00b76fbc1dce 100644 > --- a/net/sched/cls_matchall.c > +++ b/net/sched/cls_matchall.c > @@ -226,8 +226,8 @@ static int mall_change(struct net *net, struct sk_buff *in_skb, > goto err_alloc_percpu; > } > > - err = mall_set_parms(net, tp, new, base, tb, tca[TCA_RATE], flags, > - extack); > + err = mall_set_parms(net, tp, new, base, tb, tca[TCA_RATE], > + flags | new->flags, extack); > if (err) > goto err_set_parms; > > diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c > index 4272814487f0..fc670cc45122 100644 > --- a/net/sched/cls_u32.c > +++ b/net/sched/cls_u32.c > @@ -895,7 +895,8 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, > return -ENOMEM; > > err = u32_set_parms(net, tp, base, new, tb, > - tca[TCA_RATE], flags, extack); > + tca[TCA_RATE], flags | new->flags, > + extack); > > if (err) { > u32_destroy_key(new, false); > @@ -1060,8 +1061,8 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, > } > #endif > > - err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE], flags, > - extack); > + err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE], > + flags | n->flags, extack); > if (err == 0) { > struct tc_u_knode __rcu **ins; > struct tc_u_knode *pins;
On 2021-10-29 14:01, Vlad Buslov wrote: > On Thu 28 Oct 2021 at 14:06, Simon Horman <simon.horman@corigine.com> wrote: >> From: Baowen Zheng <baowen.zheng@corigine.com> >> >> Add process to validate flags of filter and actions when adding >> a tc filter. >> >> We need to prevent adding filter with flags conflicts with its actions. >> >> Signed-off-by: Baowen Zheng <baowen.zheng@corigine.com> >> Signed-off-by: Louis Peens <louis.peens@corigine.com> >> Signed-off-by: Simon Horman <simon.horman@corigine.com> >> --- >> net/sched/cls_api.c | 26 ++++++++++++++++++++++++++ >> net/sched/cls_flower.c | 3 ++- >> net/sched/cls_matchall.c | 4 ++-- >> net/sched/cls_u32.c | 7 ++++--- >> 4 files changed, 34 insertions(+), 6 deletions(-) >> >> diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c >> index 351d93988b8b..80647da9713a 100644 >> --- a/net/sched/cls_api.c >> +++ b/net/sched/cls_api.c >> @@ -3025,6 +3025,29 @@ void tcf_exts_destroy(struct tcf_exts *exts) >> } >> EXPORT_SYMBOL(tcf_exts_destroy); >> >> +static bool tcf_exts_validate_actions(const struct tcf_exts *exts, u32 flags) >> +{ >> +#ifdef CONFIG_NET_CLS_ACT >> + bool skip_sw = tc_skip_sw(flags); >> + bool skip_hw = tc_skip_hw(flags); >> + int i; >> + >> + if (!(skip_sw | skip_hw)) >> + return true; >> + >> + for (i = 0; i < exts->nr_actions; i++) { >> + struct tc_action *a = exts->actions[i]; >> + >> + if ((skip_sw && tc_act_skip_hw(a->tcfa_flags)) || >> + (skip_hw && tc_act_skip_sw(a->tcfa_flags))) >> + return false; >> + } >> + return true; >> +#else >> + return true; >> +#endif >> +} >> + > > I know Jamal suggested to have skip_sw for actions, but it complicates > the code and I'm still not entirely understand why it is necessary. If the hardware can independently accept an action offload then skip_sw per action makes total sense. BTW, my understanding is _your_ hardware is capable as such at least for policers ;-> And such policers are then shared across filters. Other than the architectural reason I may have missed something because I dont see much complexity added as a result. Are you more worried about slowing down the update rate? cheers, jamal
On Sat 30 Oct 2021 at 13:54, Jamal Hadi Salim <jhs@mojatatu.com> wrote: > On 2021-10-29 14:01, Vlad Buslov wrote: >> On Thu 28 Oct 2021 at 14:06, Simon Horman <simon.horman@corigine.com> wrote: >>> From: Baowen Zheng <baowen.zheng@corigine.com> >>> >>> Add process to validate flags of filter and actions when adding >>> a tc filter. >>> >>> We need to prevent adding filter with flags conflicts with its actions. >>> >>> Signed-off-by: Baowen Zheng <baowen.zheng@corigine.com> >>> Signed-off-by: Louis Peens <louis.peens@corigine.com> >>> Signed-off-by: Simon Horman <simon.horman@corigine.com> >>> --- >>> net/sched/cls_api.c | 26 ++++++++++++++++++++++++++ >>> net/sched/cls_flower.c | 3 ++- >>> net/sched/cls_matchall.c | 4 ++-- >>> net/sched/cls_u32.c | 7 ++++--- >>> 4 files changed, 34 insertions(+), 6 deletions(-) >>> >>> diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c >>> index 351d93988b8b..80647da9713a 100644 >>> --- a/net/sched/cls_api.c >>> +++ b/net/sched/cls_api.c >>> @@ -3025,6 +3025,29 @@ void tcf_exts_destroy(struct tcf_exts *exts) >>> } >>> EXPORT_SYMBOL(tcf_exts_destroy); >>> +static bool tcf_exts_validate_actions(const struct tcf_exts *exts, u32 >>> flags) >>> +{ >>> +#ifdef CONFIG_NET_CLS_ACT >>> + bool skip_sw = tc_skip_sw(flags); >>> + bool skip_hw = tc_skip_hw(flags); >>> + int i; >>> + >>> + if (!(skip_sw | skip_hw)) >>> + return true; >>> + >>> + for (i = 0; i < exts->nr_actions; i++) { >>> + struct tc_action *a = exts->actions[i]; >>> + >>> + if ((skip_sw && tc_act_skip_hw(a->tcfa_flags)) || >>> + (skip_hw && tc_act_skip_sw(a->tcfa_flags))) >>> + return false; >>> + } >>> + return true; >>> +#else >>> + return true; >>> +#endif >>> +} >>> + >> I know Jamal suggested to have skip_sw for actions, but it complicates >> the code and I'm still not entirely understand why it is necessary. > > If the hardware can independently accept an action offload then > skip_sw per action makes total sense. BTW, my understanding is Example configuration that seems bizarre to me is when offloaded shared action has skip_sw flag set but filter doesn't. Then behavior of classifier that points to such action diverges between hardware and software (different lists of actions are applied). We always try to make offloaded TC data path behave exactly the same as software and, even though here it would be explicit and deliberate, I don't see any practical use-case for this. > _your_ hardware is capable as such at least for policers ;-> > And such policers are then shared across filters. True, but why do you need skip_sw action flag for that? > Other than the architectural reason I may have missed something > because I dont see much complexity added as a result. Well, other part of my email was about how I don't understand what is going on in the flags handling code here. This patch and parts of other patches in the series would be unnecessary, if we forgo the action skip_sw flag. I guess we can just make the code nicer by folding the validation into tcf_action_init(), for example. > Are you more worried about slowing down the update rate? I don't expect the validation code to significantly impact the update rate.
On 2021-10-30 22:27, Baowen Zheng wrote: > Thanks for your review, after some considerarion, I think I understand what you are meaning. > [..] >>>> I know Jamal suggested to have skip_sw for actions, but it complicates >>>> the code and I'm still not entirely understand why it is necessary. >>> >>> If the hardware can independently accept an action offload then >>> skip_sw per action makes total sense. BTW, my understanding is >> >> Example configuration that seems bizarre to me is when offloaded shared >> action has skip_sw flag set but filter doesn't. Then behavior of >> classifier that points to such action diverges between hardware and >> software (different lists of actions are applied). We always try to make >> offloaded TC data path behave exactly the same as software and, even >> though here it would be explicit and deliberate, I don't see any >> practical use-case for this. > We add the skip_sw to keep compatible with the filter flags and give the user an > option to specify if the action should run in software. I understand what you mean, > maybe our example is not proper, we need to prevent the filter to run in software if the > actions it applies is skip_sw, so we need to add more validation to check about this. > Also I think your suggestion makes full sense if there is no use case to specify the action > should not run in sw and indeed it will make our implement more simple if we omit the > skip_sw option. > Jamal, WDYT? Let me use an example to illustrate my concern: #add a policer offload it tc actions add action police skip_sw rate ... index 20 #now add filter1 which is offloaded tc filter add dev $DEV1 proto ip parent ffff: flower \ skip_sw ip_proto tcp action police index 20 #add filter2 likewise offloaded tc filter add dev $DEV1 proto ip parent ffff: flower \ skip_sw ip_proto udp action police index 20 All good so far... #Now add a filter3 which is s/w only tc filter add dev $DEV1 proto ip parent ffff: flower \ skip_hw ip_proto icmp action police index 20 filter3 should not be allowed. If we had added the policer without skip_sw and without skip_hw then i think filter3 should have been legal (we just need to account for stats in_hw vs in_sw). Not sure if that makes sense (and addresses Vlad's earlier comment). cheers, jamal
On 2021-10-31 9:31 PM, Jamal Hadi Salim wrote: >On 2021-10-30 22:27, Baowen Zheng wrote: >> Thanks for your review, after some considerarion, I think I understand what >you are meaning. >> > >[..] > >>>>> I know Jamal suggested to have skip_sw for actions, but it >>>>> complicates the code and I'm still not entirely understand why it is >necessary. >>>> >>>> If the hardware can independently accept an action offload then >>>> skip_sw per action makes total sense. BTW, my understanding is >>> >>> Example configuration that seems bizarre to me is when offloaded >>> shared action has skip_sw flag set but filter doesn't. Then behavior >>> of classifier that points to such action diverges between hardware >>> and software (different lists of actions are applied). We always try >>> to make offloaded TC data path behave exactly the same as software >>> and, even though here it would be explicit and deliberate, I don't >>> see any practical use-case for this. >> We add the skip_sw to keep compatible with the filter flags and give >> the user an option to specify if the action should run in software. I >> understand what you mean, maybe our example is not proper, we need to >> prevent the filter to run in software if the actions it applies is skip_sw, so we >need to add more validation to check about this. >> Also I think your suggestion makes full sense if there is no use case >> to specify the action should not run in sw and indeed it will make our >> implement more simple if we omit the skip_sw option. >> Jamal, WDYT? > > >Let me use an example to illustrate my concern: > >#add a policer offload it >tc actions add action police skip_sw rate ... index 20 #now add filter1 which is >offloaded tc filter add dev $DEV1 proto ip parent ffff: flower \ > skip_sw ip_proto tcp action police index 20 #add filter2 likewise offloaded >tc filter add dev $DEV1 proto ip parent ffff: flower \ > skip_sw ip_proto udp action police index 20 > >All good so far... >#Now add a filter3 which is s/w only >tc filter add dev $DEV1 proto ip parent ffff: flower \ > skip_hw ip_proto icmp action police index 20 > >filter3 should not be allowed. > >If we had added the policer without skip_sw and without skip_hw then i think >filter3 should have been legal (we just need to account for stats in_hw vs >in_sw). > >Not sure if that makes sense (and addresses Vlad's earlier comment). > I think the cases you mentioned make sense to us. But what Vlad concerns is the use case as: #add a policer offload it tc actions add action police skip_sw rate ... index 20 #now add filter4 which can't be offloaded tc filter add dev $DEV1 proto ip parent ffff: flower \ ip_proto tcp action police index 20 it is possible the filter4 can't be offloaded, then filter4 will run in software, should this be legal? Originally I think this is legal, but as comments of Vlad, this should not be legal, since the action will not be executed in software. I think what Vlad concerns is do we really need skip_sw flag for an action? If a packet matches the filter in software, the action should not be skip_sw. If we choose to omit the skip_sw flag and just keep skip_hw, it will simplify our work. Of course, we can also keep skip_sw by adding more check to avoid the above case. Vlad, I am not sure if I understand your idea correctly.
On Mon 01 Nov 2021 at 05:29, Baowen Zheng <baowen.zheng@corigine.com> wrote: > On 2021-10-31 9:31 PM, Jamal Hadi Salim wrote: >>On 2021-10-30 22:27, Baowen Zheng wrote: >>> Thanks for your review, after some considerarion, I think I understand what >>you are meaning. >>> >> >>[..] >> >>>>>> I know Jamal suggested to have skip_sw for actions, but it >>>>>> complicates the code and I'm still not entirely understand why it is >>necessary. >>>>> >>>>> If the hardware can independently accept an action offload then >>>>> skip_sw per action makes total sense. BTW, my understanding is >>>> >>>> Example configuration that seems bizarre to me is when offloaded >>>> shared action has skip_sw flag set but filter doesn't. Then behavior >>>> of classifier that points to such action diverges between hardware >>>> and software (different lists of actions are applied). We always try >>>> to make offloaded TC data path behave exactly the same as software >>>> and, even though here it would be explicit and deliberate, I don't >>>> see any practical use-case for this. >>> We add the skip_sw to keep compatible with the filter flags and give >>> the user an option to specify if the action should run in software. I >>> understand what you mean, maybe our example is not proper, we need to >>> prevent the filter to run in software if the actions it applies is skip_sw, so we >>need to add more validation to check about this. >>> Also I think your suggestion makes full sense if there is no use case >>> to specify the action should not run in sw and indeed it will make our >>> implement more simple if we omit the skip_sw option. >>> Jamal, WDYT? >> >> >>Let me use an example to illustrate my concern: >> >>#add a policer offload it >>tc actions add action police skip_sw rate ... index 20 #now add filter1 which is >>offloaded tc filter add dev $DEV1 proto ip parent ffff: flower \ >> skip_sw ip_proto tcp action police index 20 #add filter2 likewise offloaded >>tc filter add dev $DEV1 proto ip parent ffff: flower \ >> skip_sw ip_proto udp action police index 20 >> >>All good so far... >>#Now add a filter3 which is s/w only >>tc filter add dev $DEV1 proto ip parent ffff: flower \ >> skip_hw ip_proto icmp action police index 20 >> >>filter3 should not be allowed. >> >>If we had added the policer without skip_sw and without skip_hw then i think >>filter3 should have been legal (we just need to account for stats in_hw vs >>in_sw). >> >>Not sure if that makes sense (and addresses Vlad's earlier comment). >> > I think the cases you mentioned make sense to us. But what Vlad concerns is the use > case as: > #add a policer offload it > tc actions add action police skip_sw rate ... index 20 > #now add filter4 which can't be offloaded > tc filter add dev $DEV1 proto ip parent ffff: flower \ > ip_proto tcp action police index 20 > it is possible the filter4 can't be offloaded, then filter4 will run in software, > should this be legal? > Originally I think this is legal, but as comments of Vlad, this should not be legal, since the action > will not be executed in software. I think what Vlad concerns is do we really need skip_sw flag for > an action? If a packet matches the filter in software, the action should not be skip_sw. > If we choose to omit the skip_sw flag and just keep skip_hw, it will simplify our work. > Of course, we can also keep skip_sw by adding more check to avoid the above case. > > Vlad, I am not sure if I understand your idea correctly. My suggestion was to forgo the skip_sw flag for shared action offload and, consecutively, remove the validation code, not to add even more checks. I still don't see a practical case where skip_sw shared action is useful. But I don't have any strong feelings about this flag, so if Jamal thinks it is necessary, then fine by me.
On Mon, Nov 01, 2021 at 09:38:34AM +0200, Vlad Buslov wrote: > On Mon 01 Nov 2021 at 05:29, Baowen Zheng <baowen.zheng@corigine.com> wrote: > > On 2021-10-31 9:31 PM, Jamal Hadi Salim wrote: > >>On 2021-10-30 22:27, Baowen Zheng wrote: > >>> Thanks for your review, after some considerarion, I think I understand what .. > >>Let me use an example to illustrate my concern: > >> > >>#add a policer offload it > >>tc actions add action police skip_sw rate ... index 20 #now add filter1 which is > >>offloaded tc filter add dev $DEV1 proto ip parent ffff: flower \ > >> skip_sw ip_proto tcp action police index 20 #add filter2 likewise offloaded > >>tc filter add dev $DEV1 proto ip parent ffff: flower \ > >> skip_sw ip_proto udp action police index 20 > >> > >>All good so far... > >>#Now add a filter3 which is s/w only > >>tc filter add dev $DEV1 proto ip parent ffff: flower \ > >> skip_hw ip_proto icmp action police index 20 > >> > >>filter3 should not be allowed. > >> > >>If we had added the policer without skip_sw and without skip_hw then i think > >>filter3 should have been legal (we just need to account for stats in_hw vs > >>in_sw). > >> > >>Not sure if that makes sense (and addresses Vlad's earlier comment). > >> > > I think the cases you mentioned make sense to us. But what Vlad concerns is the use > > case as: > > #add a policer offload it > > tc actions add action police skip_sw rate ... index 20 > > #now add filter4 which can't be offloaded > > tc filter add dev $DEV1 proto ip parent ffff: flower \ > > ip_proto tcp action police index 20 > > it is possible the filter4 can't be offloaded, then filter4 will run in software, > > should this be legal? > > Originally I think this is legal, but as comments of Vlad, this should not be legal, since the action > > will not be executed in software. I think what Vlad concerns is do we really need skip_sw flag for > > an action? If a packet matches the filter in software, the action should not be skip_sw. > > If we choose to omit the skip_sw flag and just keep skip_hw, it will simplify our work. > > Of course, we can also keep skip_sw by adding more check to avoid the above case. > > > > Vlad, I am not sure if I understand your idea correctly. > > My suggestion was to forgo the skip_sw flag for shared action offload > and, consecutively, remove the validation code, not to add even more > checks. I still don't see a practical case where skip_sw shared action > is useful. But I don't have any strong feelings about this flag, so if > Jamal thinks it is necessary, then fine by me. FWIIW, my feelings are the same as Vlad's. I think these flags add complexity that would be nice to avoid. But if Jamal thinks its necessary, then including the flags implementation is fine by me.
On November 2, 2021 8:40 PM, Simon Horman wrote: >On Mon, Nov 01, 2021 at 09:38:34AM +0200, Vlad Buslov wrote: >> On Mon 01 Nov 2021 at 05:29, Baowen Zheng ><baowen.zheng@corigine.com> wrote: >> > On 2021-10-31 9:31 PM, Jamal Hadi Salim wrote: >> >>On 2021-10-30 22:27, Baowen Zheng wrote: >> >>> Thanks for your review, after some considerarion, I think I >> >>> understand what > >.. > >> >>Let me use an example to illustrate my concern: >> >> >> >>#add a policer offload it >> >>tc actions add action police skip_sw rate ... index 20 #now add >> >>filter1 which is offloaded tc filter add dev $DEV1 proto ip parent ffff: >flower \ >> >> skip_sw ip_proto tcp action police index 20 #add filter2 >> >>likewise offloaded tc filter add dev $DEV1 proto ip parent ffff: flower \ >> >> skip_sw ip_proto udp action police index 20 >> >> >> >>All good so far... >> >>#Now add a filter3 which is s/w only tc filter add dev $DEV1 proto >> >>ip parent ffff: flower \ >> >> skip_hw ip_proto icmp action police index 20 >> >> >> >>filter3 should not be allowed. >> >> >> >>If we had added the policer without skip_sw and without skip_hw then >> >>i think >> >>filter3 should have been legal (we just need to account for stats >> >>in_hw vs in_sw). >> >> >> >>Not sure if that makes sense (and addresses Vlad's earlier comment). >> >> >> > I think the cases you mentioned make sense to us. But what Vlad >> > concerns is the use case as: >> > #add a policer offload it >> > tc actions add action police skip_sw rate ... index 20 #now add >> > filter4 which can't be offloaded tc filter add dev $DEV1 proto ip >> > parent ffff: flower \ ip_proto tcp action police index 20 it is >> > possible the filter4 can't be offloaded, then filter4 will run in >> > software, should this be legal? >> > Originally I think this is legal, but as comments of Vlad, this >> > should not be legal, since the action will not be executed in >> > software. I think what Vlad concerns is do we really need skip_sw flag for >an action? If a packet matches the filter in software, the action should not be >skip_sw. >> > If we choose to omit the skip_sw flag and just keep skip_hw, it will simplify >our work. >> > Of course, we can also keep skip_sw by adding more check to avoid the >above case. >> > >> > Vlad, I am not sure if I understand your idea correctly. >> >> My suggestion was to forgo the skip_sw flag for shared action offload >> and, consecutively, remove the validation code, not to add even more >> checks. I still don't see a practical case where skip_sw shared action >> is useful. But I don't have any strong feelings about this flag, so if >> Jamal thinks it is necessary, then fine by me. > >FWIIW, my feelings are the same as Vlad's. > >I think these flags add complexity that would be nice to avoid. >But if Jamal thinks its necessary, then including the flags implementation is >fine by me. Thanks Simon. Jamal, do you think it is necessary to keep the skip_sw flag for user to specify the action should not run in software?
On 2021-11-03 03:57, Baowen Zheng wrote: > On November 2, 2021 8:40 PM, Simon Horman wrote: >> On Mon, Nov 01, 2021 at 09:38:34AM +0200, Vlad Buslov wrote: >>> On Mon 01 Nov 2021 at 05:29, Baowen Zheng [..] >>> >>> My suggestion was to forgo the skip_sw flag for shared action offload >>> and, consecutively, remove the validation code, not to add even more >>> checks. I still don't see a practical case where skip_sw shared action >>> is useful. But I don't have any strong feelings about this flag, so if >>> Jamal thinks it is necessary, then fine by me. >> >> FWIIW, my feelings are the same as Vlad's. >> >> I think these flags add complexity that would be nice to avoid. >> But if Jamal thinks its necessary, then including the flags implementation is >> fine by me. > Thanks Simon. Jamal, do you think it is necessary to keep the skip_sw flag for user to specify > the action should not run in software? > Just catching up with discussion... IMO, we need the flag. Oz indicated with requirement to be able to identify the action with an index. So if a specific action is added for skip_sw (as standalone or alongside a filter) then it cant be used for skip_hw. To illustrate using extended example: #filter 1, skip_sw tc filter add dev $DEV1 proto ip parent ffff: flower \ skip_sw ip_proto tcp action police blah index 10 #filter 2, skip_hw tc filter add dev $DEV1 proto ip parent ffff: flower \ skip_hw ip_proto udp action police index 10 Filter2 should be illegal. And when i dump the actions as so: tc actions ls action police For debugability, I should see index 10 clearly marked with the flag as skip_sw The other example i gave earlier which showed the sharing of actions: #add a policer action and offload it tc actions add action police skip_sw rate ... index 20 #now add filter1 which is offloaded using offloaded policer tc filter add dev $DEV1 proto ip parent ffff: flower \ skip_sw ip_proto tcp action police index 20 #add filter2 likewise offloaded tc filter add dev $DEV1 proto ip parent ffff: flower \ skip_sw ip_proto udp action police index 20 All good and filter 1 and 2 are sharing policer instance with index 20. #Now add a filter3 which is s/w only tc filter add dev $DEV1 proto ip parent ffff: flower \ skip_hw ip_proto icmp action police index 20 filter3 should not be allowed. cheers, jamal
On November 3, 2021 6:14 PM, Jamal Hadi Salim wrote: >On 2021-11-03 03:57, Baowen Zheng wrote: >> On November 2, 2021 8:40 PM, Simon Horman wrote: >>> On Mon, Nov 01, 2021 at 09:38:34AM +0200, Vlad Buslov wrote: >>>> On Mon 01 Nov 2021 at 05:29, Baowen Zheng > >[..] >>>> >>>> My suggestion was to forgo the skip_sw flag for shared action >>>> offload and, consecutively, remove the validation code, not to add >>>> even more checks. I still don't see a practical case where skip_sw >>>> shared action is useful. But I don't have any strong feelings about >>>> this flag, so if Jamal thinks it is necessary, then fine by me. >>> >>> FWIIW, my feelings are the same as Vlad's. >>> >>> I think these flags add complexity that would be nice to avoid. >>> But if Jamal thinks its necessary, then including the flags >>> implementation is fine by me. >> Thanks Simon. Jamal, do you think it is necessary to keep the skip_sw >> flag for user to specify the action should not run in software? >> > >Just catching up with discussion... >IMO, we need the flag. Oz indicated with requirement to be able to identify >the action with an index. So if a specific action is added for skip_sw (as >standalone or alongside a filter) then it cant be used for skip_hw. To illustrate >using extended example: > >#filter 1, skip_sw >tc filter add dev $DEV1 proto ip parent ffff: flower \ > skip_sw ip_proto tcp action police blah index 10 > >#filter 2, skip_hw >tc filter add dev $DEV1 proto ip parent ffff: flower \ > skip_hw ip_proto udp action police index 10 > >Filter2 should be illegal. >And when i dump the actions as so: >tc actions ls action police > >For debugability, I should see index 10 clearly marked with the flag as skip_sw > >The other example i gave earlier which showed the sharing of actions: > >#add a policer action and offload it >tc actions add action police skip_sw rate ... index 20 #now add filter1 which is >offloaded using offloaded policer tc filter add dev $DEV1 proto ip parent ffff: >flower \ > skip_sw ip_proto tcp action police index 20 #add filter2 likewise offloaded >tc filter add dev $DEV1 proto ip parent ffff: flower \ > skip_sw ip_proto udp action police index 20 > >All good and filter 1 and 2 are sharing policer instance with index 20. > >#Now add a filter3 which is s/w only >tc filter add dev $DEV1 proto ip parent ffff: flower \ > skip_hw ip_proto icmp action police index 20 > >filter3 should not be allowed. I think the use cases you mentioned above are clear for us. For the case: #add a policer action and offload it tc actions add action police skip_sw rate ... index 20 #Now add a filter4 which has no flag tc filter add dev $DEV1 proto ip parent ffff: flower \ ip_proto icmp action police index 20 Is filter4 legal? basically, it should be legal, but since filter4 may be offloaded failed so it will run in software, you know the action police should not run in software with skip_sw, so I think filter4 should be illegal and we should not allow this case. That is if the action is skip_sw, then the filter refers to this action should also skip_sw. WDYT?
On 2021-11-03 07:30, Baowen Zheng wrote: > On November 3, 2021 6:14 PM, Jamal Hadi Salim wrote: >> On 2021-11-03 03:57, Baowen Zheng wrote: >>> On November 2, 2021 8:40 PM, Simon Horman wrote: >>>> On Mon, Nov 01, 2021 at 09:38:34AM +0200, Vlad Buslov wrote: >>>>> On Mon 01 Nov 2021 at 05:29, Baowen Zheng >> >> [..] >>>>> >>>>> My suggestion was to forgo the skip_sw flag for shared action >>>>> offload and, consecutively, remove the validation code, not to add >>>>> even more checks. I still don't see a practical case where skip_sw >>>>> shared action is useful. But I don't have any strong feelings about >>>>> this flag, so if Jamal thinks it is necessary, then fine by me. >>>> >>>> FWIIW, my feelings are the same as Vlad's. >>>> >>>> I think these flags add complexity that would be nice to avoid. >>>> But if Jamal thinks its necessary, then including the flags >>>> implementation is fine by me. >>> Thanks Simon. Jamal, do you think it is necessary to keep the skip_sw >>> flag for user to specify the action should not run in software? >>> >> >> Just catching up with discussion... >> IMO, we need the flag. Oz indicated with requirement to be able to identify >> the action with an index. So if a specific action is added for skip_sw (as >> standalone or alongside a filter) then it cant be used for skip_hw. To illustrate >> using extended example: >> >> #filter 1, skip_sw >> tc filter add dev $DEV1 proto ip parent ffff: flower \ >> skip_sw ip_proto tcp action police blah index 10 >> >> #filter 2, skip_hw >> tc filter add dev $DEV1 proto ip parent ffff: flower \ >> skip_hw ip_proto udp action police index 10 >> >> Filter2 should be illegal. >> And when i dump the actions as so: >> tc actions ls action police >> >> For debugability, I should see index 10 clearly marked with the flag as skip_sw >> >> The other example i gave earlier which showed the sharing of actions: >> >> #add a policer action and offload it >> tc actions add action police skip_sw rate ... index 20 #now add filter1 which is >> offloaded using offloaded policer tc filter add dev $DEV1 proto ip parent ffff: >> flower \ >> skip_sw ip_proto tcp action police index 20 #add filter2 likewise offloaded >> tc filter add dev $DEV1 proto ip parent ffff: flower \ >> skip_sw ip_proto udp action police index 20 >> >> All good and filter 1 and 2 are sharing policer instance with index 20. >> >> #Now add a filter3 which is s/w only >> tc filter add dev $DEV1 proto ip parent ffff: flower \ >> skip_hw ip_proto icmp action police index 20 >> >> filter3 should not be allowed. > I think the use cases you mentioned above are clear for us. For the case: > > #add a policer action and offload it > tc actions add action police skip_sw rate ... index 20 > #Now add a filter4 which has no flag > tc filter add dev $DEV1 proto ip parent ffff: flower \ > ip_proto icmp action police index 20 > > Is filter4 legal? Yes it is _based on current semantics_. The reason is when adding a filter and specifying neither skip_sw nor skip_hw it defaults to allowing both. i.e is the same as skip_sw|skip_hw. You will need to have counters for both s/w and h/w (which i think is taken care of today). >basically, it should be legal, but since filter4 may be offloaded failed so > it will run in software, you know the action police should not run in software with skip_sw, > so I think filter4 should be illegal and we should not allow this case. > That is if the action is skip_sw, then the filter refers to this action should also skip_sw. > WDYT? See above.. cheers, jamal
On 2021-11-03 08:33, Jamal Hadi Salim wrote: > On 2021-11-03 07:30, Baowen Zheng wrote: >> On November 3, 2021 6:14 PM, Jamal Hadi Salim wrote: >>> On 2021-11-03 03:57, Baowen Zheng wrote: >>>> On November 2, 2021 8:40 PM, Simon Horman wrote: >>>>> On Mon, Nov 01, 2021 at 09:38:34AM +0200, Vlad Buslov wrote: >>>>>> On Mon 01 Nov 2021 at 05:29, Baowen Zheng >>> >>> [..] >>>>>> >>>>>> My suggestion was to forgo the skip_sw flag for shared action >>>>>> offload and, consecutively, remove the validation code, not to add >>>>>> even more checks. I still don't see a practical case where skip_sw >>>>>> shared action is useful. But I don't have any strong feelings about >>>>>> this flag, so if Jamal thinks it is necessary, then fine by me. >>>>> >>>>> FWIIW, my feelings are the same as Vlad's. >>>>> >>>>> I think these flags add complexity that would be nice to avoid. >>>>> But if Jamal thinks its necessary, then including the flags >>>>> implementation is fine by me. >>>> Thanks Simon. Jamal, do you think it is necessary to keep the skip_sw >>>> flag for user to specify the action should not run in software? >>>> >>> >>> Just catching up with discussion... >>> IMO, we need the flag. Oz indicated with requirement to be able to >>> identify >>> the action with an index. So if a specific action is added for >>> skip_sw (as >>> standalone or alongside a filter) then it cant be used for skip_hw. >>> To illustrate >>> using extended example: >>> >>> #filter 1, skip_sw >>> tc filter add dev $DEV1 proto ip parent ffff: flower \ >>> skip_sw ip_proto tcp action police blah index 10 >>> >>> #filter 2, skip_hw >>> tc filter add dev $DEV1 proto ip parent ffff: flower \ >>> skip_hw ip_proto udp action police index 10 >>> >>> Filter2 should be illegal. >>> And when i dump the actions as so: >>> tc actions ls action police >>> >>> For debugability, I should see index 10 clearly marked with the flag >>> as skip_sw >>> >>> The other example i gave earlier which showed the sharing of actions: >>> >>> #add a policer action and offload it >>> tc actions add action police skip_sw rate ... index 20 #now add >>> filter1 which is >>> offloaded using offloaded policer tc filter add dev $DEV1 proto ip >>> parent ffff: >>> flower \ >>> skip_sw ip_proto tcp action police index 20 #add filter2 >>> likewise offloaded >>> tc filter add dev $DEV1 proto ip parent ffff: flower \ >>> skip_sw ip_proto udp action police index 20 >>> >>> All good and filter 1 and 2 are sharing policer instance with index 20. >>> >>> #Now add a filter3 which is s/w only >>> tc filter add dev $DEV1 proto ip parent ffff: flower \ >>> skip_hw ip_proto icmp action police index 20 >>> >>> filter3 should not be allowed. >> I think the use cases you mentioned above are clear for us. For the case: >> >> #add a policer action and offload it >> tc actions add action police skip_sw rate ... index 20 >> #Now add a filter4 which has no flag >> tc filter add dev $DEV1 proto ip parent ffff: flower \ >> ip_proto icmp action police index 20 >> >> Is filter4 legal? > > Yes it is _based on current semantics_. > The reason is when adding a filter and specifying neither > skip_sw nor skip_hw it defaults to allowing both. > i.e is the same as skip_sw|skip_hw. You will need to have > counters for both s/w and h/w (which i think is taken care of today). > > Apologies, i will like to take this one back. Couldnt stop thinking about it while sipping coffee;-> To be safe that should be illegal. The flags have to match _exactly_ for both action and filter to make any sense. i.e in the above case they are not. cheers, jamal
On November 3, 2021 8:34 PM, Jamal Hadi Salim wrote: >On 2021-11-03 07:30, Baowen Zheng wrote: >> On November 3, 2021 6:14 PM, Jamal Hadi Salim wrote: >>> On 2021-11-03 03:57, Baowen Zheng wrote: >>>> On November 2, 2021 8:40 PM, Simon Horman wrote: >>>>> On Mon, Nov 01, 2021 at 09:38:34AM +0200, Vlad Buslov wrote: >>>>>> On Mon 01 Nov 2021 at 05:29, Baowen Zheng >>> >>> [..] >>>>>> >>>>>> My suggestion was to forgo the skip_sw flag for shared action >>>>>> offload and, consecutively, remove the validation code, not to add >>>>>> even more checks. I still don't see a practical case where skip_sw >>>>>> shared action is useful. But I don't have any strong feelings >>>>>> about this flag, so if Jamal thinks it is necessary, then fine by me. >>>>> >>>>> FWIIW, my feelings are the same as Vlad's. >>>>> >>>>> I think these flags add complexity that would be nice to avoid. >>>>> But if Jamal thinks its necessary, then including the flags >>>>> implementation is fine by me. >>>> Thanks Simon. Jamal, do you think it is necessary to keep the >>>> skip_sw flag for user to specify the action should not run in software? >>>> >>> >>> Just catching up with discussion... >>> IMO, we need the flag. Oz indicated with requirement to be able to >>> identify the action with an index. So if a specific action is added >>> for skip_sw (as standalone or alongside a filter) then it cant be >>> used for skip_hw. To illustrate using extended example: >>> >>> #filter 1, skip_sw >>> tc filter add dev $DEV1 proto ip parent ffff: flower \ >>> skip_sw ip_proto tcp action police blah index 10 >>> >>> #filter 2, skip_hw >>> tc filter add dev $DEV1 proto ip parent ffff: flower \ >>> skip_hw ip_proto udp action police index 10 >>> >>> Filter2 should be illegal. >>> And when i dump the actions as so: >>> tc actions ls action police >>> >>> For debugability, I should see index 10 clearly marked with the flag >>> as skip_sw >>> >>> The other example i gave earlier which showed the sharing of actions: >>> >>> #add a policer action and offload it >>> tc actions add action police skip_sw rate ... index 20 #now add >>> filter1 which is offloaded using offloaded policer tc filter add dev $DEV1 >proto ip parent ffff: >>> flower \ >>> skip_sw ip_proto tcp action police index 20 #add filter2 >>> likewise offloaded tc filter add dev $DEV1 proto ip parent ffff: flower \ >>> skip_sw ip_proto udp action police index 20 >>> >>> All good and filter 1 and 2 are sharing policer instance with index 20. >>> >>> #Now add a filter3 which is s/w only >>> tc filter add dev $DEV1 proto ip parent ffff: flower \ >>> skip_hw ip_proto icmp action police index 20 >>> >>> filter3 should not be allowed. >> I think the use cases you mentioned above are clear for us. For the case: >> >> #add a policer action and offload it >> tc actions add action police skip_sw rate ... index 20 #Now add a >> filter4 which has no flag tc filter add dev $DEV1 proto ip parent >> ffff: flower \ >> ip_proto icmp action police index 20 >> >> Is filter4 legal? > >Yes it is _based on current semantics_. >The reason is when adding a filter and specifying neither skip_sw nor skip_hw >it defaults to allowing both. >i.e is the same as skip_sw|skip_hw. You will need to have counters for both >s/w and h/w (which i think is taken care of today). Thanks, but what we concern is not the counters but the behavior of this filter. Since the filter runs in software and action is skip_sw, so the action will not execute in software. So when the packet matches the filter, it will execute all the actions except the skip_sw action. I think it is not what we expect, we expect the packet execute all the actions the filter refers to. So I think in this case, filter4 should not be allowed. WDYT? >>basically, it should be legal, but since filter4 may be offloaded >>failed so it will run in software, you know the action police should >>not run in software with skip_sw, so I think filter4 should be illegal and we >should not allow this case. >> That is if the action is skip_sw, then the filter refers to this action should also >skip_sw. >> WDYT? > >See above.. > >cheers, >jamal
On Wed, Nov 03, 2021 at 09:33:52AM -0400, Jamal Hadi Salim wrote: > On 2021-11-03 08:33, Jamal Hadi Salim wrote: > > On 2021-11-03 07:30, Baowen Zheng wrote: > > > On November 3, 2021 6:14 PM, Jamal Hadi Salim wrote: > > > > On 2021-11-03 03:57, Baowen Zheng wrote: > > > > > On November 2, 2021 8:40 PM, Simon Horman wrote: > > > > > > On Mon, Nov 01, 2021 at 09:38:34AM +0200, Vlad Buslov wrote: > > > > > > > On Mon 01 Nov 2021 at 05:29, Baowen Zheng > > > > > > > > [..] > > > > > > > > > > > > > > My suggestion was to forgo the skip_sw flag for shared action > > > > > > > offload and, consecutively, remove the validation code, not to add > > > > > > > even more checks. I still don't see a practical case where skip_sw > > > > > > > shared action is useful. But I don't have any strong feelings about > > > > > > > this flag, so if Jamal thinks it is necessary, then fine by me. > > > > > > > > > > > > FWIIW, my feelings are the same as Vlad's. > > > > > > > > > > > > I think these flags add complexity that would be nice to avoid. > > > > > > But if Jamal thinks its necessary, then including the flags > > > > > > implementation is fine by me. > > > > > Thanks Simon. Jamal, do you think it is necessary to keep the skip_sw > > > > > flag for user to specify the action should not run in software? > > > > > > > > > > > > > Just catching up with discussion... > > > > IMO, we need the flag. Oz indicated with requirement to be able > > > > to identify > > > > the action with an index. So if a specific action is added for > > > > skip_sw (as > > > > standalone or alongside a filter) then it cant be used for > > > > skip_hw. To illustrate > > > > using extended example: > > > > > > > > #filter 1, skip_sw > > > > tc filter add dev $DEV1 proto ip parent ffff: flower \ > > > > skip_sw ip_proto tcp action police blah index 10 > > > > > > > > #filter 2, skip_hw > > > > tc filter add dev $DEV1 proto ip parent ffff: flower \ > > > > skip_hw ip_proto udp action police index 10 > > > > > > > > Filter2 should be illegal. > > > > And when i dump the actions as so: > > > > tc actions ls action police > > > > > > > > For debugability, I should see index 10 clearly marked with the > > > > flag as skip_sw > > > > > > > > The other example i gave earlier which showed the sharing of actions: > > > > > > > > #add a policer action and offload it > > > > tc actions add action police skip_sw rate ... index 20 #now add > > > > filter1 which is > > > > offloaded using offloaded policer tc filter add dev $DEV1 proto > > > > ip parent ffff: > > > > flower \ > > > > skip_sw ip_proto tcp action police index 20 #add filter2 > > > > likewise offloaded > > > > tc filter add dev $DEV1 proto ip parent ffff: flower \ > > > > skip_sw ip_proto udp action police index 20 > > > > > > > > All good and filter 1 and 2 are sharing policer instance with index 20. > > > > > > > > #Now add a filter3 which is s/w only > > > > tc filter add dev $DEV1 proto ip parent ffff: flower \ > > > > skip_hw ip_proto icmp action police index 20 > > > > > > > > filter3 should not be allowed. > > > I think the use cases you mentioned above are clear for us. For the case: > > > > > > #add a policer action and offload it > > > tc actions add action police skip_sw rate ... index 20 > > > #Now add a filter4 which has no flag > > > tc filter add dev $DEV1 proto ip parent ffff: flower \ > > > ip_proto icmp action police index 20 > > > > > > Is filter4 legal? > > > > Yes it is _based on current semantics_. > > The reason is when adding a filter and specifying neither > > skip_sw nor skip_hw it defaults to allowing both. > > i.e is the same as skip_sw|skip_hw. You will need to have > > counters for both s/w and h/w (which i think is taken care of today). > > > > > > Apologies, i will like to take this one back. Couldnt stop thinking > about it while sipping coffee;-> > To be safe that should be illegal. The flags have to match _exactly_ > for both action and filter to make any sense. i.e in the above case > they are not. I could be wrong, but I would have thought that in this case the flow is legal but is only added to hw (because the action doesn't exist in sw). But if you prefer to make it illegal I guess that is ok too.
Thanks for your reply. On November 3, 2021 9:34 PM, Jamal Hadi Salim wrote: >On 2021-11-03 08:33, Jamal Hadi Salim wrote: >> On 2021-11-03 07:30, Baowen Zheng wrote: >>> On November 3, 2021 6:14 PM, Jamal Hadi Salim wrote: >>>> On 2021-11-03 03:57, Baowen Zheng wrote: >>>>> On November 2, 2021 8:40 PM, Simon Horman wrote: >>>>>> On Mon, Nov 01, 2021 at 09:38:34AM +0200, Vlad Buslov wrote: >>>>>>> On Mon 01 Nov 2021 at 05:29, Baowen Zheng >>>> >>>> [..] >>>>>>> >>>>>>> My suggestion was to forgo the skip_sw flag for shared action >>>>>>> offload and, consecutively, remove the validation code, not to >>>>>>> add even more checks. I still don't see a practical case where >>>>>>> skip_sw shared action is useful. But I don't have any strong >>>>>>> feelings about this flag, so if Jamal thinks it is necessary, then fine by >me. >>>>>> >>>>>> FWIIW, my feelings are the same as Vlad's. >>>>>> >>>>>> I think these flags add complexity that would be nice to avoid. >>>>>> But if Jamal thinks its necessary, then including the flags >>>>>> implementation is fine by me. >>>>> Thanks Simon. Jamal, do you think it is necessary to keep the >>>>> skip_sw flag for user to specify the action should not run in software? >>>>> >>>> >>>> Just catching up with discussion... >>>> IMO, we need the flag. Oz indicated with requirement to be able to >>>> identify the action with an index. So if a specific action is added >>>> for skip_sw (as standalone or alongside a filter) then it cant be >>>> used for skip_hw. >>>> To illustrate >>>> using extended example: >>>> >>>> #filter 1, skip_sw >>>> tc filter add dev $DEV1 proto ip parent ffff: flower \ >>>> skip_sw ip_proto tcp action police blah index 10 >>>> >>>> #filter 2, skip_hw >>>> tc filter add dev $DEV1 proto ip parent ffff: flower \ >>>> skip_hw ip_proto udp action police index 10 >>>> >>>> Filter2 should be illegal. >>>> And when i dump the actions as so: >>>> tc actions ls action police >>>> >>>> For debugability, I should see index 10 clearly marked with the flag >>>> as skip_sw >>>> >>>> The other example i gave earlier which showed the sharing of actions: >>>> >>>> #add a policer action and offload it tc actions add action police >>>> skip_sw rate ... index 20 #now add >>>> filter1 which is >>>> offloaded using offloaded policer tc filter add dev $DEV1 proto ip >>>> parent ffff: >>>> flower \ >>>> skip_sw ip_proto tcp action police index 20 #add filter2 >>>> likewise offloaded tc filter add dev $DEV1 proto ip parent ffff: >>>> flower \ >>>> skip_sw ip_proto udp action police index 20 >>>> >>>> All good and filter 1 and 2 are sharing policer instance with index 20. >>>> >>>> #Now add a filter3 which is s/w only tc filter add dev $DEV1 proto >>>> ip parent ffff: flower \ >>>> skip_hw ip_proto icmp action police index 20 >>>> >>>> filter3 should not be allowed. >>> I think the use cases you mentioned above are clear for us. For the case: >>> >>> #add a policer action and offload it >>> tc actions add action police skip_sw rate ... index 20 #Now add a >>> filter4 which has no flag tc filter add dev $DEV1 proto ip parent >>> ffff: flower \ >>> ip_proto icmp action police index 20 >>> >>> Is filter4 legal? >> >> Yes it is _based on current semantics_. >> The reason is when adding a filter and specifying neither skip_sw nor >> skip_hw it defaults to allowing both. >> i.e is the same as skip_sw|skip_hw. You will need to have counters for >> both s/w and h/w (which i think is taken care of today). >> >> > >Apologies, i will like to take this one back. Couldnt stop thinking about it while >sipping coffee;-> To be safe that should be illegal. The flags have to match >_exactly_ for both action and filter to make any sense. i.e in the above case >they are not. Thanks. I think we have get agreement that filter4 is illegal. Sorry for more clarification about another case that Vlad mentioned: #add a policer action with skip_hw tc actions add action police skip_hw rate ... index 20 #Now add a filter5 which has no flag tc filter add dev $DEV1 proto ip parent ffff: flower \ ip_proto icmp action police index 20 I think the filter5 could be legal, since it will not run in hardware. Driver will check failed when try to offload this filter. So the filter5 will only run in software. WDYT?
On 2021-11-03 09:38, Simon Horman wrote: > On Wed, Nov 03, 2021 at 09:33:52AM -0400, Jamal Hadi Salim wrote: >> On 2021-11-03 08:33, Jamal Hadi Salim wrote: >>> On 2021-11-03 07:30, Baowen Zheng wrote: >>>> On November 3, 2021 6:14 PM, Jamal Hadi Salim wrote: >>>>> On 2021-11-03 03:57, Baowen Zheng wrote: >>>>>> On November 2, 2021 8:40 PM, Simon Horman wrote: >>>>>>> On Mon, Nov 01, 2021 at 09:38:34AM +0200, Vlad Buslov wrote: >>>>>>>> On Mon 01 Nov 2021 at 05:29, Baowen Zheng >>>>> >>>>> [..] >>>>>>>> >>>>>>>> My suggestion was to forgo the skip_sw flag for shared action >>>>>>>> offload and, consecutively, remove the validation code, not to add >>>>>>>> even more checks. I still don't see a practical case where skip_sw >>>>>>>> shared action is useful. But I don't have any strong feelings about >>>>>>>> this flag, so if Jamal thinks it is necessary, then fine by me. >>>>>>> >>>>>>> FWIIW, my feelings are the same as Vlad's. >>>>>>> >>>>>>> I think these flags add complexity that would be nice to avoid. >>>>>>> But if Jamal thinks its necessary, then including the flags >>>>>>> implementation is fine by me. >>>>>> Thanks Simon. Jamal, do you think it is necessary to keep the skip_sw >>>>>> flag for user to specify the action should not run in software? >>>>>> >>>>> >>>>> Just catching up with discussion... >>>>> IMO, we need the flag. Oz indicated with requirement to be able >>>>> to identify >>>>> the action with an index. So if a specific action is added for >>>>> skip_sw (as >>>>> standalone or alongside a filter) then it cant be used for >>>>> skip_hw. To illustrate >>>>> using extended example: >>>>> >>>>> #filter 1, skip_sw >>>>> tc filter add dev $DEV1 proto ip parent ffff: flower \ >>>>> skip_sw ip_proto tcp action police blah index 10 >>>>> >>>>> #filter 2, skip_hw >>>>> tc filter add dev $DEV1 proto ip parent ffff: flower \ >>>>> skip_hw ip_proto udp action police index 10 >>>>> >>>>> Filter2 should be illegal. >>>>> And when i dump the actions as so: >>>>> tc actions ls action police >>>>> >>>>> For debugability, I should see index 10 clearly marked with the >>>>> flag as skip_sw >>>>> >>>>> The other example i gave earlier which showed the sharing of actions: >>>>> >>>>> #add a policer action and offload it >>>>> tc actions add action police skip_sw rate ... index 20 #now add >>>>> filter1 which is >>>>> offloaded using offloaded policer tc filter add dev $DEV1 proto >>>>> ip parent ffff: >>>>> flower \ >>>>> skip_sw ip_proto tcp action police index 20 #add filter2 >>>>> likewise offloaded >>>>> tc filter add dev $DEV1 proto ip parent ffff: flower \ >>>>> skip_sw ip_proto udp action police index 20 >>>>> >>>>> All good and filter 1 and 2 are sharing policer instance with index 20. >>>>> >>>>> #Now add a filter3 which is s/w only >>>>> tc filter add dev $DEV1 proto ip parent ffff: flower \ >>>>> skip_hw ip_proto icmp action police index 20 >>>>> >>>>> filter3 should not be allowed. >>>> I think the use cases you mentioned above are clear for us. For the case: >>>> >>>> #add a policer action and offload it >>>> tc actions add action police skip_sw rate ... index 20 >>>> #Now add a filter4 which has no flag >>>> tc filter add dev $DEV1 proto ip parent ffff: flower \ >>>> ip_proto icmp action police index 20 >>>> >>>> Is filter4 legal? >>> >>> Yes it is _based on current semantics_. >>> The reason is when adding a filter and specifying neither >>> skip_sw nor skip_hw it defaults to allowing both. >>> i.e is the same as skip_sw|skip_hw. You will need to have >>> counters for both s/w and h/w (which i think is taken care of today). >>> >>> >> >> Apologies, i will like to take this one back. Couldnt stop thinking >> about it while sipping coffee;-> >> To be safe that should be illegal. The flags have to match _exactly_ >> for both action and filter to make any sense. i.e in the above case >> they are not. > > I could be wrong, but I would have thought that in this case the flow > is legal but is only added to hw (because the action doesn't exist in sw). > I was worried what would show up in a dump of the filter. Would it show only the h/w counter? And if yes, is the s/w version mutated with no policer (since the policer is only in h/w)? > But if you prefer to make it illegal I guess that is ok too. It just seemed easier from manageability pov to make it illegal, no? i.e if flags dont match exactly it is illegal is a simple check. cheers, jamal
On 2021-11-03 10:03, Baowen Zheng wrote: > Thanks for your reply. > On November 3, 2021 9:34 PM, Jamal Hadi Salim wrote: >> On 2021-11-03 08:33, Jamal Hadi Salim wrote: >>> On 2021-11-03 07:30, Baowen Zheng wrote: >>>> On November 3, 2021 6:14 PM, Jamal Hadi Salim wrote: [..] > Sorry for more clarification about another case that Vlad mentioned: > #add a policer action with skip_hw > tc actions add action police skip_hw rate ... index 20 > #Now add a filter5 which has no flag > tc filter add dev $DEV1 proto ip parent ffff: flower \ > ip_proto icmp action police index 20 > I think the filter5 could be legal, since it will not run in hardware. > Driver will check failed when try to offload this filter. So the filter5 will only run in software. > WDYT? > I think this one also has ambiguity. If the filter doesnt specify skip_sw or skip_hw it will run both in s/w and h/w. I am worried if that looks suprising to someone debugging after because in h/w there is filter 5 but no policer but in s/w twin we have filter 5 and policer index 20. It could be design intent, but in my opinion we have priorities to resolve such ambiguities in policies. If we use the rule which says the flags have to match exactly then we can simplify resolving any ambiguity - which will make it illegal, no? cheers, jamal
On November 3, 2021 10:16 PM, Jamal Hadi Salim wrote: >On 2021-11-03 10:03, Baowen Zheng wrote: >> Thanks for your reply. >> On November 3, 2021 9:34 PM, Jamal Hadi Salim wrote: >>> On 2021-11-03 08:33, Jamal Hadi Salim wrote: >>>> On 2021-11-03 07:30, Baowen Zheng wrote: >>>>> On November 3, 2021 6:14 PM, Jamal Hadi Salim wrote: > > >[..] > >> Sorry for more clarification about another case that Vlad mentioned: >> #add a policer action with skip_hw >> tc actions add action police skip_hw rate ... index 20 #Now add a >> filter5 which has no flag tc filter add dev $DEV1 proto ip parent >> ffff: flower \ >> ip_proto icmp action police index 20 I think the filter5 could >> be legal, since it will not run in hardware. >> Driver will check failed when try to offload this filter. So the filter5 will only >run in software. >> WDYT? >> > >I think this one also has ambiguity. If the filter doesnt specify skip_sw or >skip_hw it will run both in s/w and h/w. I am worried if that looks suprising to >someone debugging after because in h/w there is filter 5 but no policer but in >s/w twin we have filter 5 and policer index 20. In this case, the filter will not in h/w because when the driver tries to offload the filter, It will found the action is not in h/w and return failed, then the filter will not in h/w, so the filter will only In software. >It could be design intent, but in my opinion we have priorities to resolve such >ambiguities in policies. > >If we use the rule which says the flags have to match exactly then we can >simplify resolving any ambiguity - which will make it illegal, no? When you mentioned " match exactly ", do you mean the flags of the filter and the actions should be exactly same? Please consider the case that filter has flag and the action does not have any flag. I think we should allow this case. Because it is legal before our patch, we do not expect to break this use case, yes? So maybe the "match exactly" just limits action flags, when action has flags(skip_sw or skip_hw), the filter must have exactly the same flags. WDYT?
On 2021-11-03 10:48, Baowen Zheng wrote: > On November 3, 2021 10:16 PM, Jamal Hadi Salim wrote: >> On 2021-11-03 10:03, Baowen Zheng wrote: >>> Thanks for your reply. >>> On November 3, 2021 9:34 PM, Jamal Hadi Salim wrote: >>>> On 2021-11-03 08:33, Jamal Hadi Salim wrote: >>>>> On 2021-11-03 07:30, Baowen Zheng wrote: >>>>>> On November 3, 2021 6:14 PM, Jamal Hadi Salim wrote: >> >> >> [..] >> >>> Sorry for more clarification about another case that Vlad mentioned: >>> #add a policer action with skip_hw >>> tc actions add action police skip_hw rate ... index 20 #Now add a >>> filter5 which has no flag tc filter add dev $DEV1 proto ip parent >>> ffff: flower \ >>> ip_proto icmp action police index 20 I think the filter5 could >>> be legal, since it will not run in hardware. >>> Driver will check failed when try to offload this filter. So the filter5 will only >> run in software. >>> WDYT? >>> >> >> I think this one also has ambiguity. If the filter doesnt specify skip_sw or >> skip_hw it will run both in s/w and h/w. I am worried if that looks suprising to >> someone debugging after because in h/w there is filter 5 but no policer but in >> s/w twin we have filter 5 and policer index 20. > In this case, the filter will not in h/w because when the driver tries to offload the filter, > It will found the action is not in h/w and return failed, then the filter will not in h/w, so the filter will only > In software. So you have partial failure? That doesnt sound good. What do you return to the user - "success" or "somehow success"? I worry it is still ambigous. Did the user really intend to do that? If they did maybe they should have just added it to s/w instead of h/w and s/w and then get saved by the driver? >> It could be design intent, but in my opinion we have priorities to resolve such >> ambiguities in policies. >> >> If we use the rule which says the flags have to match exactly then we can >> simplify resolving any ambiguity - which will make it illegal, no? > When you mentioned " match exactly ", do you mean the flags of the filter and the actions should be > exactly same? > Please consider the case that filter has flag and the action does not have any flag. See above. > I think we should allow this case. > Because it is legal before our patch, we do not expect to break this use case, yes? > So maybe the "match exactly" just limits action flags, when action has flags(skip_sw or skip_hw), the filter must have > exactly the same flags. Maybe i am missing something but nothing should break. I think what you mean is when the action is specified with the filter. The flags should be the same in that case. Example, filter 1: tc filter add dev $DEV1 proto ip paren ffff: flower \ ip_proto icmp action police blah where flag is 0 implies this filter goes both in h/w and s/w. If i dump the policer or the filter i will see some index provided by the kernel and i should be able to see both s/w and h/w counters. Same thing if i did: Example filter 2: tc filter add dev $DEV1 proto ip paren ffff: flower \ skip_sw ip_proto udp action police blah both filter + action will have where flag of skip_sw when i dump implies this filter goes only in h/w and any displayed index is allocated by the kernel. Our challenge is when someone specifies a specific action by index and tries to use it ambigously. cheers, jamal
Thanks for your review and sorry for delay in responding. On October 30, 2021 2:01 AM, Vlad Buslov wrote: >On Thu 28 Oct 2021 at 14:06, Simon Horman <simon.horman@corigine.com> >wrote: >> From: Baowen Zheng <baowen.zheng@corigine.com> >> >> Add process to validate flags of filter and actions when adding a tc >> filter. >> >> We need to prevent adding filter with flags conflicts with its actions. >> >> Signed-off-by: Baowen Zheng <baowen.zheng@corigine.com> >> Signed-off-by: Louis Peens <louis.peens@corigine.com> >> Signed-off-by: Simon Horman <simon.horman@corigine.com> >> --- >> net/sched/cls_api.c | 26 ++++++++++++++++++++++++++ >> net/sched/cls_flower.c | 3 ++- >> net/sched/cls_matchall.c | 4 ++-- >> net/sched/cls_u32.c | 7 ++++--- >> 4 files changed, 34 insertions(+), 6 deletions(-) >> >> diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index >> 351d93988b8b..80647da9713a 100644 >> --- a/net/sched/cls_api.c >> +++ b/net/sched/cls_api.c >> @@ -3025,6 +3025,29 @@ void tcf_exts_destroy(struct tcf_exts *exts) } >> EXPORT_SYMBOL(tcf_exts_destroy); >> >> +static bool tcf_exts_validate_actions(const struct tcf_exts *exts, >> +u32 flags) { #ifdef CONFIG_NET_CLS_ACT >> + bool skip_sw = tc_skip_sw(flags); >> + bool skip_hw = tc_skip_hw(flags); >> + int i; >> + >> + if (!(skip_sw | skip_hw)) >> + return true; >> + >> + for (i = 0; i < exts->nr_actions; i++) { >> + struct tc_action *a = exts->actions[i]; >> + >> + if ((skip_sw && tc_act_skip_hw(a->tcfa_flags)) || >> + (skip_hw && tc_act_skip_sw(a->tcfa_flags))) >> + return false; >> + } >> + return true; >> +#else >> + return true; >> +#endif >> +} >> + > >I know Jamal suggested to have skip_sw for actions, but it complicates the >code and I'm still not entirely understand why it is necessary. >After all, action can only get applied to a packet if the packet has been >matched by some filter and filters already have skip sw/hw controls. Forgoing >action skip_sw flag would: > >- Alleviate the need to validate that filter and action flags are compatible. >(trying to offload filter that points to existing skip_hw action would just fail >because the driver wouldn't find the action with provided id in its tables) > >- Remove the need to add more conditionals into TC software data path in >patch 4. > >WDYT? As we discussed with Jamal, we will keep the flag of skip_sw and we need to make exactly match for the actions with flags and the filter specific action with index. > >> int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb, >> struct nlattr *rate_tlv, struct tcf_exts *exts, >> u32 flags, struct netlink_ext_ack *extack) @@ -3066,6 >+3089,9 >> @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr >**tb, >> return err; >> exts->nr_actions = err; >> } >> + >> + if (!tcf_exts_validate_actions(exts, flags)) >> + return -EINVAL; >> } >> #else >> if ((exts->action && tb[exts->action]) || diff --git >> a/net/sched/cls_flower.c b/net/sched/cls_flower.c index >> eb6345a027e1..55f89f0e393e 100644 >> --- a/net/sched/cls_flower.c >> +++ b/net/sched/cls_flower.c >> @@ -2035,7 +2035,8 @@ static int fl_change(struct net *net, struct sk_buff >*in_skb, >> } >> >> err = fl_set_parms(net, tp, fnew, mask, base, tb, tca[TCA_RATE], >> - tp->chain->tmplt_priv, flags, extack); >> + tp->chain->tmplt_priv, flags | fnew->flags, >> + extack); > >Aren't you or-ing flags from two different ranges (TCA_CLS_FLAGS_* and >TCA_ACT_FLAGS_*) that map to same bits, or am I missing something? This >isn't explained in commit message so it is hard for me to understand the idea >here. Yes, as you said we use TCA_CLS_FLAGS_* or TCA_ACT_FLAGS_* flags to validate the action flags. As you know, the TCA_ACT_FLAGS_* in flags are system flags(in high 16 bits) and the TCA_CLS_FLAGS_* are user flags(in low 16 bits), so they will not be conflict. But I think you suggestion also makes sense to us, do you think we need to pass a single filter flag to make the process more clear? > >> if (err) >> goto errout; >> >> diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c index >> 24f0046ce0b3..00b76fbc1dce 100644 >> --- a/net/sched/cls_matchall.c >> +++ b/net/sched/cls_matchall.c >> @@ -226,8 +226,8 @@ static int mall_change(struct net *net, struct sk_buff >*in_skb, >> goto err_alloc_percpu; >> } >> >> - err = mall_set_parms(net, tp, new, base, tb, tca[TCA_RATE], flags, >> - extack); >> + err = mall_set_parms(net, tp, new, base, tb, tca[TCA_RATE], >> + flags | new->flags, extack); >> if (err) >> goto err_set_parms; >> >> diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index >> 4272814487f0..fc670cc45122 100644 >> --- a/net/sched/cls_u32.c >> +++ b/net/sched/cls_u32.c >> @@ -895,7 +895,8 @@ static int u32_change(struct net *net, struct sk_buff >*in_skb, >> return -ENOMEM; >> >> err = u32_set_parms(net, tp, base, new, tb, >> - tca[TCA_RATE], flags, extack); >> + tca[TCA_RATE], flags | new->flags, >> + extack); >> >> if (err) { >> u32_destroy_key(new, false); >> @@ -1060,8 +1061,8 @@ static int u32_change(struct net *net, struct >sk_buff *in_skb, >> } >> #endif >> >> - err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE], flags, >> - extack); >> + err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE], >> + flags | n->flags, extack); >> if (err == 0) { >> struct tc_u_knode __rcu **ins; >> struct tc_u_knode *pins;
Sorry for reply this message again. On November 4, 2021 10:31 AM, Baowen Zheng wrote: >Thanks for your review and sorry for delay in responding. >On October 30, 2021 2:01 AM, Vlad Buslov wrote: >>On Thu 28 Oct 2021 at 14:06, Simon Horman <simon.horman@corigine.com> >>wrote: >>> From: Baowen Zheng <baowen.zheng@corigine.com> >>> >>> Add process to validate flags of filter and actions when adding a tc >>> filter. >>> >>> We need to prevent adding filter with flags conflicts with its actions. >>> >>> Signed-off-by: Baowen Zheng <baowen.zheng@corigine.com> >>> Signed-off-by: Louis Peens <louis.peens@corigine.com> >>> Signed-off-by: Simon Horman <simon.horman@corigine.com> >>> --- >>> net/sched/cls_api.c | 26 ++++++++++++++++++++++++++ >>> net/sched/cls_flower.c | 3 ++- >>> net/sched/cls_matchall.c | 4 ++-- >>> net/sched/cls_u32.c | 7 ++++--- >>> 4 files changed, 34 insertions(+), 6 deletions(-) >>> >>> diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index >>> 351d93988b8b..80647da9713a 100644 >>> --- a/net/sched/cls_api.c >>> +++ b/net/sched/cls_api.c >>> @@ -3025,6 +3025,29 @@ void tcf_exts_destroy(struct tcf_exts *exts) >>> } EXPORT_SYMBOL(tcf_exts_destroy); >>> >>> +static bool tcf_exts_validate_actions(const struct tcf_exts *exts, >>> +u32 flags) { #ifdef CONFIG_NET_CLS_ACT >>> + bool skip_sw = tc_skip_sw(flags); >>> + bool skip_hw = tc_skip_hw(flags); >>> + int i; >>> + >>> + if (!(skip_sw | skip_hw)) >>> + return true; >>> + >>> + for (i = 0; i < exts->nr_actions; i++) { >>> + struct tc_action *a = exts->actions[i]; >>> + >>> + if ((skip_sw && tc_act_skip_hw(a->tcfa_flags)) || >>> + (skip_hw && tc_act_skip_sw(a->tcfa_flags))) >>> + return false; >>> + } >>> + return true; >>> +#else >>> + return true; >>> +#endif >>> +} >>> + >> >>I know Jamal suggested to have skip_sw for actions, but it complicates >>the code and I'm still not entirely understand why it is necessary. >>After all, action can only get applied to a packet if the packet has >>been matched by some filter and filters already have skip sw/hw >>controls. Forgoing action skip_sw flag would: >> >>- Alleviate the need to validate that filter and action flags are compatible. >>(trying to offload filter that points to existing skip_hw action would >>just fail because the driver wouldn't find the action with provided id >>in its tables) >> >>- Remove the need to add more conditionals into TC software data path >>in patch 4. >> >>WDYT? >As we discussed with Jamal, we will keep the flag of skip_sw and we need to >make exactly match for the actions with flags and the filter specific action with >index. >> >>> int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr >**tb, >>> struct nlattr *rate_tlv, struct tcf_exts *exts, >>> u32 flags, struct netlink_ext_ack *extack) @@ -3066,6 >>+3089,9 >>> @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, >>> struct nlattr >>**tb, >>> return err; >>> exts->nr_actions = err; >>> } >>> + >>> + if (!tcf_exts_validate_actions(exts, flags)) >>> + return -EINVAL; >>> } >>> #else >>> if ((exts->action && tb[exts->action]) || diff --git >>> a/net/sched/cls_flower.c b/net/sched/cls_flower.c index >>> eb6345a027e1..55f89f0e393e 100644 >>> --- a/net/sched/cls_flower.c >>> +++ b/net/sched/cls_flower.c >>> @@ -2035,7 +2035,8 @@ static int fl_change(struct net *net, struct >>> sk_buff >>*in_skb, >>> } >>> >>> err = fl_set_parms(net, tp, fnew, mask, base, tb, tca[TCA_RATE], >>> - tp->chain->tmplt_priv, flags, extack); >>> + tp->chain->tmplt_priv, flags | fnew->flags, >>> + extack); >> >>Aren't you or-ing flags from two different ranges (TCA_CLS_FLAGS_* and >>TCA_ACT_FLAGS_*) that map to same bits, or am I missing something? This >>isn't explained in commit message so it is hard for me to understand >>the idea here. >Yes, as you said we use TCA_CLS_FLAGS_* or TCA_ACT_FLAGS_* flags to >validate the action flags. >As you know, the TCA_ACT_FLAGS_* in flags are system flags(in high 16 bits) >and the TCA_CLS_FLAGS_* are user flags(in low 16 bits), so they will not be >conflict. >But I think you suggestion also makes sense to us, do you think we need to >pass a single filter flag to make the process more clear? After consideration, I think it is better to separate CLS flags and ACT flags. So we will pass CLS flags as a separate flags, thanks. >> >>> if (err) >>> goto errout; >>> >>> diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c >>> index 24f0046ce0b3..00b76fbc1dce 100644 >>> --- a/net/sched/cls_matchall.c >>> +++ b/net/sched/cls_matchall.c >>> @@ -226,8 +226,8 @@ static int mall_change(struct net *net, struct >>> sk_buff >>*in_skb, >>> goto err_alloc_percpu; >>> } >>> >>> - err = mall_set_parms(net, tp, new, base, tb, tca[TCA_RATE], flags, >>> - extack); >>> + err = mall_set_parms(net, tp, new, base, tb, tca[TCA_RATE], >>> + flags | new->flags, extack); >>> if (err) >>> goto err_set_parms; >>> >>> diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index >>> 4272814487f0..fc670cc45122 100644 >>> --- a/net/sched/cls_u32.c >>> +++ b/net/sched/cls_u32.c >>> @@ -895,7 +895,8 @@ static int u32_change(struct net *net, struct >>> sk_buff >>*in_skb, >>> return -ENOMEM; >>> >>> err = u32_set_parms(net, tp, base, new, tb, >>> - tca[TCA_RATE], flags, extack); >>> + tca[TCA_RATE], flags | new->flags, >>> + extack); >>> >>> if (err) { >>> u32_destroy_key(new, false); >>> @@ -1060,8 +1061,8 @@ static int u32_change(struct net *net, struct >>sk_buff *in_skb, >>> } >>> #endif >>> >>> - err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE], flags, >>> - extack); >>> + err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE], >>> + flags | n->flags, extack); >>> if (err == 0) { >>> struct tc_u_knode __rcu **ins; >>> struct tc_u_knode *pins;
On Thu 04 Nov 2021 at 07:51, Baowen Zheng <baowen.zheng@corigine.com> wrote: > Sorry for reply this message again. > On November 4, 2021 10:31 AM, Baowen Zheng wrote: >>Thanks for your review and sorry for delay in responding. >>On October 30, 2021 2:01 AM, Vlad Buslov wrote: >>>On Thu 28 Oct 2021 at 14:06, Simon Horman <simon.horman@corigine.com> >>>wrote: >>>> From: Baowen Zheng <baowen.zheng@corigine.com> >>>> >>>> Add process to validate flags of filter and actions when adding a tc >>>> filter. >>>> >>>> We need to prevent adding filter with flags conflicts with its actions. >>>> >>>> Signed-off-by: Baowen Zheng <baowen.zheng@corigine.com> >>>> Signed-off-by: Louis Peens <louis.peens@corigine.com> >>>> Signed-off-by: Simon Horman <simon.horman@corigine.com> >>>> --- >>>> net/sched/cls_api.c | 26 ++++++++++++++++++++++++++ >>>> net/sched/cls_flower.c | 3 ++- >>>> net/sched/cls_matchall.c | 4 ++-- >>>> net/sched/cls_u32.c | 7 ++++--- >>>> 4 files changed, 34 insertions(+), 6 deletions(-) >>>> >>>> diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index >>>> 351d93988b8b..80647da9713a 100644 >>>> --- a/net/sched/cls_api.c >>>> +++ b/net/sched/cls_api.c >>>> @@ -3025,6 +3025,29 @@ void tcf_exts_destroy(struct tcf_exts *exts) >>>> } EXPORT_SYMBOL(tcf_exts_destroy); >>>> >>>> +static bool tcf_exts_validate_actions(const struct tcf_exts *exts, >>>> +u32 flags) { #ifdef CONFIG_NET_CLS_ACT >>>> + bool skip_sw = tc_skip_sw(flags); >>>> + bool skip_hw = tc_skip_hw(flags); >>>> + int i; >>>> + >>>> + if (!(skip_sw | skip_hw)) >>>> + return true; >>>> + >>>> + for (i = 0; i < exts->nr_actions; i++) { >>>> + struct tc_action *a = exts->actions[i]; >>>> + >>>> + if ((skip_sw && tc_act_skip_hw(a->tcfa_flags)) || >>>> + (skip_hw && tc_act_skip_sw(a->tcfa_flags))) >>>> + return false; >>>> + } >>>> + return true; >>>> +#else >>>> + return true; >>>> +#endif >>>> +} >>>> + >>> >>>I know Jamal suggested to have skip_sw for actions, but it complicates >>>the code and I'm still not entirely understand why it is necessary. >>>After all, action can only get applied to a packet if the packet has >>>been matched by some filter and filters already have skip sw/hw >>>controls. Forgoing action skip_sw flag would: >>> >>>- Alleviate the need to validate that filter and action flags are compatible. >>>(trying to offload filter that points to existing skip_hw action would >>>just fail because the driver wouldn't find the action with provided id >>>in its tables) >>> >>>- Remove the need to add more conditionals into TC software data path >>>in patch 4. >>> >>>WDYT? >>As we discussed with Jamal, we will keep the flag of skip_sw and we need to >>make exactly match for the actions with flags and the filter specific action with >>index. >>> >>>> int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr >>**tb, >>>> struct nlattr *rate_tlv, struct tcf_exts *exts, >>>> u32 flags, struct netlink_ext_ack *extack) @@ -3066,6 >>>+3089,9 >>>> @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, >>>> struct nlattr >>>**tb, >>>> return err; >>>> exts->nr_actions = err; >>>> } >>>> + >>>> + if (!tcf_exts_validate_actions(exts, flags)) >>>> + return -EINVAL; >>>> } >>>> #else >>>> if ((exts->action && tb[exts->action]) || diff --git >>>> a/net/sched/cls_flower.c b/net/sched/cls_flower.c index >>>> eb6345a027e1..55f89f0e393e 100644 >>>> --- a/net/sched/cls_flower.c >>>> +++ b/net/sched/cls_flower.c >>>> @@ -2035,7 +2035,8 @@ static int fl_change(struct net *net, struct >>>> sk_buff >>>*in_skb, >>>> } >>>> >>>> err = fl_set_parms(net, tp, fnew, mask, base, tb, tca[TCA_RATE], >>>> - tp->chain->tmplt_priv, flags, extack); >>>> + tp->chain->tmplt_priv, flags | fnew->flags, >>>> + extack); >>> >>>Aren't you or-ing flags from two different ranges (TCA_CLS_FLAGS_* and >>>TCA_ACT_FLAGS_*) that map to same bits, or am I missing something? This >>>isn't explained in commit message so it is hard for me to understand >>>the idea here. >>Yes, as you said we use TCA_CLS_FLAGS_* or TCA_ACT_FLAGS_* flags to >>validate the action flags. >>As you know, the TCA_ACT_FLAGS_* in flags are system flags(in high 16 bits) >>and the TCA_CLS_FLAGS_* are user flags(in low 16 bits), so they will not be >>conflict. Indeed, currently available TCA_CLS_FLAGS_* fit into first 16 bits, but the field itself is 32 bits and with addition of more flags in the future higher bits may start to be used since TCA_CLS_FLAGS_* and TCA_ACT_FLAGS_* are independent sets. >>But I think you suggestion also makes sense to us, do you think we need to >>pass a single filter flag to make the process more clear? > After consideration, I think it is better to separate CLS flags and ACT flags. > So we will pass CLS flags as a separate flags, thanks. Please also validate inside tcf_action_init() instead of creating new tcf_exts_validate_actions() function, if possible. I think this will lead to cleaner and more simple code. >>> >>>> if (err) >>>> goto errout; >>>> >>>> diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c >>>> index 24f0046ce0b3..00b76fbc1dce 100644 >>>> --- a/net/sched/cls_matchall.c >>>> +++ b/net/sched/cls_matchall.c >>>> @@ -226,8 +226,8 @@ static int mall_change(struct net *net, struct >>>> sk_buff >>>*in_skb, >>>> goto err_alloc_percpu; >>>> } >>>> >>>> - err = mall_set_parms(net, tp, new, base, tb, tca[TCA_RATE], flags, >>>> - extack); >>>> + err = mall_set_parms(net, tp, new, base, tb, tca[TCA_RATE], >>>> + flags | new->flags, extack); >>>> if (err) >>>> goto err_set_parms; >>>> >>>> diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index >>>> 4272814487f0..fc670cc45122 100644 >>>> --- a/net/sched/cls_u32.c >>>> +++ b/net/sched/cls_u32.c >>>> @@ -895,7 +895,8 @@ static int u32_change(struct net *net, struct >>>> sk_buff >>>*in_skb, >>>> return -ENOMEM; >>>> >>>> err = u32_set_parms(net, tp, base, new, tb, >>>> - tca[TCA_RATE], flags, extack); >>>> + tca[TCA_RATE], flags | new->flags, >>>> + extack); >>>> >>>> if (err) { >>>> u32_destroy_key(new, false); >>>> @@ -1060,8 +1061,8 @@ static int u32_change(struct net *net, struct >>>sk_buff *in_skb, >>>> } >>>> #endif >>>> >>>> - err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE], flags, >>>> - extack); >>>> + err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE], >>>> + flags | n->flags, extack); >>>> if (err == 0) { >>>> struct tc_u_knode __rcu **ins; >>>> struct tc_u_knode *pins;
On November 4, 2021 5:07 PM, Vlad Buslov wrote: >On Thu 04 Nov 2021 at 07:51, Baowen Zheng <baowen.zheng@corigine.com> >wrote: >> Sorry for reply this message again. >> On November 4, 2021 10:31 AM, Baowen Zheng wrote: >>>Thanks for your review and sorry for delay in responding. >>>On October 30, 2021 2:01 AM, Vlad Buslov wrote: >>>>On Thu 28 Oct 2021 at 14:06, Simon Horman ><simon.horman@corigine.com> >>>>wrote: >>>>> From: Baowen Zheng <baowen.zheng@corigine.com> >>>>> >>>>> Add process to validate flags of filter and actions when adding a >>>>> tc filter. >>>>> >>>>> We need to prevent adding filter with flags conflicts with its actions. >>>>> >>>>> Signed-off-by: Baowen Zheng <baowen.zheng@corigine.com> >>>>> Signed-off-by: Louis Peens <louis.peens@corigine.com> >>>>> Signed-off-by: Simon Horman <simon.horman@corigine.com> >>>>> --- >>>>> net/sched/cls_api.c | 26 ++++++++++++++++++++++++++ >>>>> net/sched/cls_flower.c | 3 ++- >>>>> net/sched/cls_matchall.c | 4 ++-- >>>>> net/sched/cls_u32.c | 7 ++++--- >>>>> 4 files changed, 34 insertions(+), 6 deletions(-) >>>>> >>>>> diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index >>>>> 351d93988b8b..80647da9713a 100644 >>>>> --- a/net/sched/cls_api.c >>>>> +++ b/net/sched/cls_api.c >>>>> @@ -3025,6 +3025,29 @@ void tcf_exts_destroy(struct tcf_exts *exts) >>>>> } EXPORT_SYMBOL(tcf_exts_destroy); >>>>> >>>>> +static bool tcf_exts_validate_actions(const struct tcf_exts *exts, >>>>> +u32 flags) { #ifdef CONFIG_NET_CLS_ACT >>>>> + bool skip_sw = tc_skip_sw(flags); >>>>> + bool skip_hw = tc_skip_hw(flags); >>>>> + int i; >>>>> + >>>>> + if (!(skip_sw | skip_hw)) >>>>> + return true; >>>>> + >>>>> + for (i = 0; i < exts->nr_actions; i++) { >>>>> + struct tc_action *a = exts->actions[i]; >>>>> + >>>>> + if ((skip_sw && tc_act_skip_hw(a->tcfa_flags)) || >>>>> + (skip_hw && tc_act_skip_sw(a->tcfa_flags))) >>>>> + return false; >>>>> + } >>>>> + return true; >>>>> +#else >>>>> + return true; >>>>> +#endif >>>>> +} >>>>> + >>>> >>>>I know Jamal suggested to have skip_sw for actions, but it >>>>complicates the code and I'm still not entirely understand why it is >necessary. >>>>After all, action can only get applied to a packet if the packet has >>>>been matched by some filter and filters already have skip sw/hw >>>>controls. Forgoing action skip_sw flag would: >>>> >>>>- Alleviate the need to validate that filter and action flags are compatible. >>>>(trying to offload filter that points to existing skip_hw action >>>>would just fail because the driver wouldn't find the action with >>>>provided id in its tables) >>>> >>>>- Remove the need to add more conditionals into TC software data path >>>>in patch 4. >>>> >>>>WDYT? >>>As we discussed with Jamal, we will keep the flag of skip_sw and we >>>need to make exactly match for the actions with flags and the filter >>>specific action with index. >>>> >>>>> int tcf_exts_validate(struct net *net, struct tcf_proto *tp, >>>>> struct nlattr >>>**tb, >>>>> struct nlattr *rate_tlv, struct tcf_exts *exts, >>>>> u32 flags, struct netlink_ext_ack *extack) @@ -3066,6 >>>>+3089,9 >>>>> @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, >>>>> struct nlattr >>>>**tb, >>>>> return err; >>>>> exts->nr_actions = err; >>>>> } >>>>> + >>>>> + if (!tcf_exts_validate_actions(exts, flags)) >>>>> + return -EINVAL; >>>>> } >>>>> #else >>>>> if ((exts->action && tb[exts->action]) || diff --git >>>>> a/net/sched/cls_flower.c b/net/sched/cls_flower.c index >>>>> eb6345a027e1..55f89f0e393e 100644 >>>>> --- a/net/sched/cls_flower.c >>>>> +++ b/net/sched/cls_flower.c >>>>> @@ -2035,7 +2035,8 @@ static int fl_change(struct net *net, struct >>>>> sk_buff >>>>*in_skb, >>>>> } >>>>> >>>>> err = fl_set_parms(net, tp, fnew, mask, base, tb, tca[TCA_RATE], >>>>> - tp->chain->tmplt_priv, flags, extack); >>>>> + tp->chain->tmplt_priv, flags | fnew->flags, >>>>> + extack); >>>> >>>>Aren't you or-ing flags from two different ranges (TCA_CLS_FLAGS_* >>>>and >>>>TCA_ACT_FLAGS_*) that map to same bits, or am I missing something? >>>>This isn't explained in commit message so it is hard for me to >>>>understand the idea here. >>>Yes, as you said we use TCA_CLS_FLAGS_* or TCA_ACT_FLAGS_* flags to >>>validate the action flags. >>>As you know, the TCA_ACT_FLAGS_* in flags are system flags(in high 16 >>>bits) and the TCA_CLS_FLAGS_* are user flags(in low 16 bits), so they >>>will not be conflict. > >Indeed, currently available TCA_CLS_FLAGS_* fit into first 16 bits, but the field >itself is 32 bits and with addition of more flags in the future higher bits may >start to be used since TCA_CLS_FLAGS_* and >TCA_ACT_FLAGS_* are independent sets. Thanks, we will use a single parameter as the filter flag. > >>>But I think you suggestion also makes sense to us, do you think we >>>need to pass a single filter flag to make the process more clear? >> After consideration, I think it is better to separate CLS flags and ACT flags. >> So we will pass CLS flags as a separate flags, thanks. > >Please also validate inside tcf_action_init() instead of creating new >tcf_exts_validate_actions() function, if possible. I think this will lead to cleaner >and more simple code. Thanks, we will consider to implement the validation inside tcf_action_init(). > >>>> >>>>> if (err) >>>>> goto errout; >>>>> >>>>> diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c >>>>> index 24f0046ce0b3..00b76fbc1dce 100644 >>>>> --- a/net/sched/cls_matchall.c >>>>> +++ b/net/sched/cls_matchall.c >>>>> @@ -226,8 +226,8 @@ static int mall_change(struct net *net, struct >>>>> sk_buff >>>>*in_skb, >>>>> goto err_alloc_percpu; >>>>> } >>>>> >>>>> - err = mall_set_parms(net, tp, new, base, tb, tca[TCA_RATE], flags, >>>>> - extack); >>>>> + err = mall_set_parms(net, tp, new, base, tb, tca[TCA_RATE], >>>>> + flags | new->flags, extack); >>>>> if (err) >>>>> goto err_set_parms; >>>>> >>>>> diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index >>>>> 4272814487f0..fc670cc45122 100644 >>>>> --- a/net/sched/cls_u32.c >>>>> +++ b/net/sched/cls_u32.c >>>>> @@ -895,7 +895,8 @@ static int u32_change(struct net *net, struct >>>>> sk_buff >>>>*in_skb, >>>>> return -ENOMEM; >>>>> >>>>> err = u32_set_parms(net, tp, base, new, tb, >>>>> - tca[TCA_RATE], flags, extack); >>>>> + tca[TCA_RATE], flags | new->flags, >>>>> + extack); >>>>> >>>>> if (err) { >>>>> u32_destroy_key(new, false); >>>>> @@ -1060,8 +1061,8 @@ static int u32_change(struct net *net, struct >>>>sk_buff *in_skb, >>>>> } >>>>> #endif >>>>> >>>>> - err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE], flags, >>>>> - extack); >>>>> + err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE], >>>>> + flags | n->flags, extack); >>>>> if (err == 0) { >>>>> struct tc_u_knode __rcu **ins; >>>>> struct tc_u_knode *pins;
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 351d93988b8b..80647da9713a 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -3025,6 +3025,29 @@ void tcf_exts_destroy(struct tcf_exts *exts) } EXPORT_SYMBOL(tcf_exts_destroy); +static bool tcf_exts_validate_actions(const struct tcf_exts *exts, u32 flags) +{ +#ifdef CONFIG_NET_CLS_ACT + bool skip_sw = tc_skip_sw(flags); + bool skip_hw = tc_skip_hw(flags); + int i; + + if (!(skip_sw | skip_hw)) + return true; + + for (i = 0; i < exts->nr_actions; i++) { + struct tc_action *a = exts->actions[i]; + + if ((skip_sw && tc_act_skip_hw(a->tcfa_flags)) || + (skip_hw && tc_act_skip_sw(a->tcfa_flags))) + return false; + } + return true; +#else + return true; +#endif +} + int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb, struct nlattr *rate_tlv, struct tcf_exts *exts, u32 flags, struct netlink_ext_ack *extack) @@ -3066,6 +3089,9 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb, return err; exts->nr_actions = err; } + + if (!tcf_exts_validate_actions(exts, flags)) + return -EINVAL; } #else if ((exts->action && tb[exts->action]) || diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index eb6345a027e1..55f89f0e393e 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -2035,7 +2035,8 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, } err = fl_set_parms(net, tp, fnew, mask, base, tb, tca[TCA_RATE], - tp->chain->tmplt_priv, flags, extack); + tp->chain->tmplt_priv, flags | fnew->flags, + extack); if (err) goto errout; diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c index 24f0046ce0b3..00b76fbc1dce 100644 --- a/net/sched/cls_matchall.c +++ b/net/sched/cls_matchall.c @@ -226,8 +226,8 @@ static int mall_change(struct net *net, struct sk_buff *in_skb, goto err_alloc_percpu; } - err = mall_set_parms(net, tp, new, base, tb, tca[TCA_RATE], flags, - extack); + err = mall_set_parms(net, tp, new, base, tb, tca[TCA_RATE], + flags | new->flags, extack); if (err) goto err_set_parms; diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 4272814487f0..fc670cc45122 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -895,7 +895,8 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, return -ENOMEM; err = u32_set_parms(net, tp, base, new, tb, - tca[TCA_RATE], flags, extack); + tca[TCA_RATE], flags | new->flags, + extack); if (err) { u32_destroy_key(new, false); @@ -1060,8 +1061,8 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, } #endif - err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE], flags, - extack); + err = u32_set_parms(net, tp, base, n, tb, tca[TCA_RATE], + flags | n->flags, extack); if (err == 0) { struct tc_u_knode __rcu **ins; struct tc_u_knode *pins;