On 27 Jan 2025, at 17:19, Roi Dayan wrote:

> On 22/01/2025 15:02, Roi Dayan wrote:
>>
>>
>> On 22/01/2025 14:30, Ilya Maximets wrote:
>>> On 1/22/25 13:02, Roi Dayan via dev wrote:
>>>>
>>>>
>>>> On 22/01/2025 11:34, Eelco Chaudron wrote:
>>>>>
>>>>>
>>>>> On 22 Jan 2025, at 8:37, Roi Dayan wrote:
>>>>>
>>>>>> On 21/01/2025 15:02, Ilya Maximets wrote:
>>>>>>> On 1/20/25 16:13, Eelco Chaudron wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>> On 20 Jan 2025, at 14:50, Roi Dayan wrote:
>>>>>>>>
>>>>>>>>> On 20/01/2025 14:57, Eelco Chaudron wrote:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On 15 Jan 2025, at 10:18, Roi Dayan via dev wrote:
>>>>>>>>>>
>>>>>>>>>>> Use this instead of directly using dpif_is_netdev() from 
>>>>>>>>>>> dpif-netdev.
>>>>>>>>>>> Return true in dpif-netdev.
>>>>>>>>>>
>>>>>>>>>> Not sure if we need an API for this, or maybe I should say, what is 
>>>>>>>>>> the definition
>>>>>>>>>> of userspace? If this means anything but the kernel, we could 
>>>>>>>>>> probably use !dpif_is_netlink().
>>>>>>>>>>
>>>>>>>>>> But I guess, the better question would be, what would we use this 
>>>>>>>>>> call for? If it’s similar
>>>>>>>>>> to the existing use cases, we are probably better off by adding a 
>>>>>>>>>> features API to dpif.
>>>>>>>>>>
>>>>>>>>>> Thoughts?
>>>>>>>>>>
>>>>>>>>>> Cheers,
>>>>>>>>>>
>>>>>>>>>> Eelco
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> The meaning of dpif is a userspace means it needs to handle tunneling 
>>>>>>>>> and other stuff that
>>>>>>>>> kernel dpif doesn't need as the kernel does it for it.
>>>>>>>>> So while !dpif_is_netlink() is even more correct and better than 
>>>>>>>>> current dpif_is_netdev()
>>>>>>>>> there was also a point here that dpif.c is not familiar with a 
>>>>>>>>> specific dpif and not accessing
>>>>>>>>> a specific dpif function.
>>>>>>>>
>>>>>>>> So, this means a lot of potential stuff, so to me a general 
>>>>>>>> dpif_is_userspace() does not make sense.
>>>>>>>>
>>>>>>>>> I think introducing a features API to dpif could be an overkill at 
>>>>>>>>> this point.
>>>>>>>>> So if future dpifs might need something specific other than handled 
>>>>>>>>> by kernel or not I think
>>>>>>>>> this can be done at a later time.
>>>>>>>>
>>>>>>>> It might look like an overkill right now, but the current use cases 
>>>>>>>> might warrant one already.
>>>>>>>> Or are you suggesting to use/introduce !dpif_is_netlink() instead for 
>>>>>>>> now?
>>>>>>>>
>>>>>>>>
>>>>>>>> Ilya and other maintainers have any preferences or thoughts on this.
>>>>>>>
>>>>>>> In general, using either dpif_is_netlink or dpif_is_netdev outside of 
>>>>>>> dpif-netlink
>>>>>>> and dpif-netdev respectively is icky.  And I agree that even today the 
>>>>>>> number of
>>>>>>> uses of these functions outside their modules justifies doing the 
>>>>>>> feature discovery
>>>>>>> properly.  Majority of the cases here in dpif.c are caused by the fact 
>>>>>>> that
>>>>>>> dpif-netdev doesn't validate actions, so it's not possible to probe 
>>>>>>> them.  It may be
>>>>>>> better to introduce some form of action validation in case of probing 
>>>>>>> instead, so
>>>>>>> the features can be discovered normally.
>>>>>>>
>>>>>>> Best regards, Ilya Maximets.
>>>>>>
>>>>>> I think this is out-of-scope for this patch.
>>>>>> In this small commit I just wanted to do the separation from dpif.c 
>>>>>> knowing
>>>>>> about existing dpifs and accessing them directly and not introducing new 
>>>>>> layers and mechanisem.
>>>
>>> Feature probing is not a new mechanism.  We do that for many other actions
>>> and it is a primary mechanism for a datapath feature discovery.
>>>
>>>>>> Can we continue with this patch currently? a rename to the callback is 
>>>>>> also feasible though
>>>>>> I think its saying exactly what it is.
>>>>>
>>>>> This patch introduces a new API, but its purpose is unclear to me. While 
>>>>> it’s a small change,
>>>>> I don't see a concrete use case for it. The term 'userspace' seems vague 
>>>>> when used outside the
>>>>> context of the actual dpif. Could you provide a clear example of how this 
>>>>> API will be used?
>>>>> This might help us explore better alternative approaches if needed. For 
>>>>> the current use cases
>>>>> see Ilya’s response.
>>>>>
>>>>> Cheers,
>>>>>
>>>>> Eelco
>>>>>
>>>>
>>>> A concrete example is tunnel handling. In "netdev" datapath, OVS userspace 
>>>> application handles
>>>> tunnel push and pop, as opposed to "netlink" datapath in which the kernel 
>>>> handles it.
>>>> A more suitable name for it in the first place was "is_userspace".
>>>> We want to add another userspace datapath (dpif-doca), that will handle 
>>>> tunnels, therefore this
>>>> change.
>>>
>>> This is exactly the use case for a feature probing.  How we do that for 
>>> other
>>> matches and actions is constructing a dummy flow rule, calling flow_put 
>>> with a
>>> probe flag set and letting datapath validate it.  This works for various 
>>> versions
>>> of linux kernel datapath that can be running and that works for windows 
>>> datapath.
>>> This works fine for userspace datapath as well, except only for matches.  
>>> For
>>> actions it doesn't work, because the userspace datapath doesn't validate 
>>> actions.
>>> If we plan to have multiple implementations for userspace-style datpaths, 
>>> then we
>>> should probe them properly as we do for multiple implementations of 
>>> dpif-netlink.
>>
>> Are you talking about the TC probing in netdev-offload-tc ? those probing is 
>> not being done from the dpif.c.
>> TC offloading checks the probes there and either offload or not.
>> Maybe all those wrappers checking dpif_is_netdev in dpif.c should not exists 
>> then and maybe all actions should just be passed into the dpif and the dpif 
>> itself should decide what to do with the actions. dpif-netlink should decide 
>> if to skip the actions or not.
>> All this seems out of scope of keeping the same behavior as it but just 
>> opening it a bit without touching the specific logic that exists now.
>> Moving to the proposal using !dpif_is_netlink also solves the issue for 
>> userspace dpif implementations.
>> if not, I don't understand what kind of probing is expected here. can you 
>> share an example?
>>
>
> Hi,
>
> Just updating here that point is not to change the API or logic of the 
> callers using the dpif_is_netdev.
>
> dpif_supports_tnl_push_pop
> dpif_may_support_explicit_drop_action
> dpif_supports_lb_output_action
> dpif_may_support_psample
>
> My intention that if I test with a new userspace dpif then not getting 
> blocked by dpif that those features are not supported just because its not 
> specific dpif-netdev.
> Please provide an example how you suggest you proceed here.

I think what Ilya proposed is to add proper action verification for 
dpif-netdev, so we can get rid of the psample instance, and then you change the 
remaining cases to actual probes. Ilya, correct me if I’m wrong.

For the netdev part, see a quick patch below;

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 87d69c46d..e6b7131d4 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -4307,6 +4307,60 @@ exit:
     return error;
 }

+static bool
+dpif_netdev_actions_supported(const struct nlattr *actions, size_t actions_len)
+{
+    const struct nlattr *nla;
+    size_t left;
+
+    if (!actions_len) {
+        return true;
+    }
+
+    NL_ATTR_FOR_EACH(nla, left, actions, actions_len) {
+        enum ovs_action_attr type = nl_attr_type(nla);
+
+        switch (type) {
+            /* Supported actions go here in order of definition. */
+            case OVS_ACTION_ATTR_OUTPUT:
+            case OVS_ACTION_ATTR_USERSPACE:
+            case OVS_ACTION_ATTR_SET:
+            case OVS_ACTION_ATTR_PUSH_VLAN:
+            case OVS_ACTION_ATTR_POP_VLAN:
+            case OVS_ACTION_ATTR_SAMPLE:
+            case OVS_ACTION_ATTR_RECIRC:
+            case OVS_ACTION_ATTR_HASH:
+            case OVS_ACTION_ATTR_PUSH_MPLS:
+            case OVS_ACTION_ATTR_POP_MPLS:
+            case OVS_ACTION_ATTR_SET_MASKED:
+            case OVS_ACTION_ATTR_CT:
+            case OVS_ACTION_ATTR_TRUNC:
+            case OVS_ACTION_ATTR_PUSH_ETH:
+            case OVS_ACTION_ATTR_POP_ETH:
+            case OVS_ACTION_ATTR_CT_CLEAR:
+            case OVS_ACTION_ATTR_PUSH_NSH:
+            case OVS_ACTION_ATTR_POP_NSH:
+            case OVS_ACTION_ATTR_METER:
+            case OVS_ACTION_ATTR_CLONE:
+            case OVS_ACTION_ATTR_CHECK_PKT_LEN:
+            case OVS_ACTION_ATTR_ADD_MPLS:
+            case OVS_ACTION_ATTR_DEC_TTL:
+            case OVS_ACTION_ATTR_DROP:
+            case OVS_ACTION_ATTR_TUNNEL_PUSH:
+            case OVS_ACTION_ATTR_TUNNEL_POP:
+            case OVS_ACTION_ATTR_LB_OUTPUT:
+                return true;
+
+            /* Unsupported actions go here in order of definition. */
+            case OVS_ACTION_ATTR_UNSPEC:
+            case OVS_ACTION_ATTR_PSAMPLE:
+            case __OVS_ACTION_ATTR_MAX:
+                break;
+        }
+    }
+    return false;
+}
+
 static int
 dpif_netdev_flow_put(struct dpif *dpif, const struct dpif_flow_put *put)
 {
@@ -4367,6 +4421,13 @@ dpif_netdev_flow_put(struct dpif *dpif, const struct 
dpif_flow_put *put)
      * address mask. Installation of the flow will use the match variable. */
     netdev_flow_key_init(&key, &match.flow);

+    /* For probe operations, verify if the individual actions are supported.
+     * Otherwise, assume the higher layer, ofproto, manages action support. */
+    if (probe && !dpif_netdev_actions_supported(put->actions,
+                                                put->actions_len)) {
+        return EINVAL;
+    }
+
     if (put->pmd_id == PMD_ID_NULL) {
         if (cmap_count(&dp->poll_threads) == 0) {
             return EINVAL;
diff --git a/lib/dpif.c b/lib/dpif.c
index a064f717f..c22a47c3c 100644
--- a/lib/dpif.c
+++ b/lib/dpif.c
@@ -1953,13 +1953,6 @@ dpif_supports_lb_output_action(const struct dpif *dpif)
     return dpif_is_netdev(dpif);
 }

-bool
-dpif_may_support_psample(const struct dpif *dpif)
-{
-    /* Userspace datapath does not support this action. */
-    return !dpif_is_netdev(dpif);
-}
-
 /* Meters */
 void
 dpif_meter_get_features(const struct dpif *dpif,
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index bf43d5d4b..7637d93de 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -1646,8 +1646,8 @@ check_psample(struct dpif_backer *backer)

     odp_put_psample_action(&actions, 10, cookie, sizeof cookie);

-    supported = dpif_may_support_psample(backer->dpif) &&
-        dpif_probe_feature(backer->dpif, "psample", &key, &actions, NULL);
+    supported = dpif_probe_feature(backer->dpif, "psample", &key, &actions,
+                                   NULL);

     ofpbuf_uninit(&actions);
     VLOG_INFO("%s: Datapath %s psample action", dpif_name(backer->dpif),



>>>
>>> This is_userspace call is actually a request "if this implementation 
>>> supports
>>> the following actions: tunnel_push_pop, explicit drop, lb_output and 
>>> psample?".
>>> Answer "true" corresponds to "yes, yes, yes, no", and "false" means "no, 
>>> maybe,
>>> no, maybe", and then dpif.c proceeds to probe for "maybe" actions.
>>>
>>> So, this call is only a shortcut with non-obvious overloaded meaning that 
>>> will
>>> change over time as we add new actions.  Instead, we can remove it and just 
>>> do
>>> probing as dpif layer already does for most of other matches and actions.
>>> It should also be easier for you to maintain an alternative userspace 
>>> datapath
>>> implementation this way, as you'll not need to worry about what this call
>>> actually means, as dpif layer would just probe what it needs directly 
>>> instead
>>> of assuming things based on a single boolean value.
>>>
>>> Best regards, Ilya Maximets.
>>

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

Reply via email to