On 2/21/22 13:34, Eelco Chaudron wrote:
> 
> 
> On 21 Feb 2022, at 12:36, Ilya Maximets wrote:
> 
>> On 2/21/22 10:57, Eelco Chaudron wrote:
>>>
>>>
>>> On 17 Feb 2022, at 14:00, Ilya Maximets wrote:
>>>
>>>> On 1/31/22 11:53, Eelco Chaudron wrote:
>>>>> This patch checks for none offloadable ct_state match flag combinations.
>>>>> If they exist tell the user about it once, and ignore the offload.
>>>>>
>>>>> Signed-off-by: Eelco Chaudron <echau...@redhat.com>
>>>>> ---
>>>>>  lib/netdev-offload-tc.c |   18 +++++++++++++++---
>>>>>  1 file changed, 15 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
>>>>> index 8135441c6..f3d1d3e61 100644
>>>>> --- a/lib/netdev-offload-tc.c
>>>>> +++ b/lib/netdev-offload-tc.c
>>>>> @@ -1478,14 +1478,14 @@ flower_match_to_tun_opt(struct tc_flower *flower, 
>>>>> const struct flow_tnl *tnl,
>>>>>      flower->mask.tunnel.metadata.present.len = tnl->metadata.present.len;
>>>>>  }
>>>>>
>>>>> -static void
>>>>> +static int
>>>>>  parse_match_ct_state_to_flower(struct tc_flower *flower, struct match 
>>>>> *match)
>>>>>  {
>>>>>      const struct flow *key = &match->flow;
>>>>>      struct flow *mask = &match->wc.masks;
>>>>>
>>>>>      if (!ct_state_support) {
>>>>> -        return;
>>>>> +        return 0;
>>>>>      }
>>>>>
>>>>>      if ((ct_state_support & mask->ct_state) == mask->ct_state) {
>>>>> @@ -1541,6 +1541,13 @@ parse_match_ct_state_to_flower(struct tc_flower 
>>>>> *flower, struct match *match)
>>>>>              flower->key.ct_state &= ~(TCA_FLOWER_KEY_CT_FLAGS_NEW);
>>>>>              flower->mask.ct_state &= ~(TCA_FLOWER_KEY_CT_FLAGS_NEW);
>>>>>          }
>>>>> +
>>>>> +        if (flower->key.ct_state &&
>>>>> +            !(flower->key.ct_state & TCA_FLOWER_KEY_CT_FLAGS_TRACKED)) {
>>>>> +            VLOG_INFO_ONCE("For ct_state match offload to work, you must 
>>>>> "
>>>>> +                           "include +trk with any other flags set!");
>>>>
>>>> Why should OVS care about that?  Is it a workaround for a kernel bug?
>>>
>>> This is not a kernel TC bug, but it just does not make sense to match on ct 
>>> flags without the +trk flag.
>>> So TC marks these as invalid arguments and refuses to take the filter.
>>>
>>>> I mean, kernel should reject offload attempts for unsupported flag 
>>>> combinations.
>>>
>>> Yes, the kernel reports unsupported offload attempts by returning an 
>>> EINVAL. However, if this is returned as-is, the infrastructure sees this as 
>>> an error, not an incompatibility. For unsupported it only accepts 
>>> EOPNOTSUPP.
>>
>> Should we fix the return value in the kernel then?
> 
> Well in practice we supply the wrong arguments, as this is not a valid 
> scenario, so EINVAL is ok.
> 
>> I mean, -trk is a valid match criteria, and if tc doesn't support it,
>> it should say that it doesn't support it, instead of complaining that
>> arguments are invalid.
> 
> This is valid, as the bit value included with the mask, is 0, and this is not 
> creating the warning.
> It will if we do -trk +new
> 
>> This is misleading, unless that is documented
>> somewhere as invalid tc configuration.  Is it?
> 
> Don’t think it is, it makes perfect sense, as we should never have -trk and 
> any other flag.
> Because if you are not tracking you can not have this state.
> 
> For fail-safe you normally do “if (flower->key.ct_state & 
> flower->mast.ct_state && ….” but we know that the above code will only set 
> the bit if the mask is also set.
> 
> 
>> My original fix had this:
>>>
>>> @@ -1975,6 +1975,11 @@ netdev_tc_flow_put(struct netdev *netdev, struct 
>>> match *match,
>>>          add_ufid_tc_mapping(netdev, ufid, &id);
>>>      }
>>>
>>> +    if (err == EINVAL) {
>>> +        err = EOPNOTSUPP;
>>> +    }
>>> +
>>>      return err;
>>>  }
>>>
>>> But to make it easier to debug, I decided to catch this earlier and log it. 
>>> This way, hopefully, we do not get people asking why the offload did not 
>>> work.
>>>
>>> I would prefer to keep the error message (with the check), what do you 
>>> think?
>>
>> Code snippet above is a bit overboard as it converts every error into
>> EOPNOTSUPP, and that doesn't make much sense.  For the change in the
>> current patch, I think it will also reject plain +est match or something
>> similar, because it checks the key, but not the mask.
>>
> 
> Yes, that is why I did not follow through.
> 
>> All in all, all combinations of flags that OVS tries to offload should
>> be valid (unless there is an OVS bug in the flow translation layer).
>> And we can't make assumptions on why user created this kind of OF pipeline.
>>
>>
>> If we want to forbid some combination of matches, we should do that at
>> the point of OpenFlow flow insertion.
> 
> Yes, I agree, but this is how it is now, so maybe blocking this might render 
> existing deployments no longer working.
> I know it will fail a hand full of self-tests ;)
> 
>> '-trk' seems to be a very popular match that will be used in almost every
>> pipeline, so the INFO message above will be printed always on every
>> setup with ct and offload enabled, so I'm not sure how much value it has.
>> 'extack' message should, probably, be the right way to receive the
>> explanation why the certain flow is not offloaded.
> 
> Don’t think this is true, it will only print if +trk and any other flags are 
> set.
> Guess this is where the miscommunication is.> 
>> The message also seems to be a bit aggressive, especially since it will
>> almost always be printed.

Yeah.  I missed the fact that you're checking for zero and flower->key.ct_state
will actually mark existence of other flags.  So, that is fine.

However, I'm still not sure that the condition is fully correct.

If we'll take a match on '+est' with all other flags wildcarded, that will
trigger the condition, because 'flower->key.ct_state' will contain the 'est' 
bit,
but 'trk' bit will not be set.  The point is that even though -trk+est is not
a valid combination and +trk+est is, OVS may in theory produce the match with
'est' bit set and 'trk' bit wildcarded.  And that can be a correct 
configuration.

Or am I missing something else?

>>
>> As a temporary solution we may convert the error to EOPNOTSUPP, but for
>> this case only, i.e.
>>   err == EINVAL
>>   && !(flower->key.ct_state & TCA_FLOWER_KEY_CT_FLAGS_TRACKED)
>>   && flower->mask.ct_state & TCA_FLOWER_KEY_CT_FLAGS_TRACKED
>>
>> And maybe print a debug level message.
>>
>> What do you think?
> 
> See above, I think the existing code is fine, so we do not try to offload it 
> to TC.
> 
>> And while we're here, I'm not sure why we need to check the +est+new
>> combination in that code either.
> 
> Because according to the kernel these two flags are mutually exclusive, so 
> you can not set a filter for both. A connection can be new and established at 
> the same time, not sure why they choose to ignore the new state, guess the 
> kernel module ignores this also.
> 
> Guess I could also do a similar fix, i.e. force the +trk flag when not set? 
> What do you think!? I did not test this, so it might bring new side effects ;)
> 
> 
>> Best regards, Ilya Maximets.
> 

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to