Re: [ovs-dev] [PATCH V4 13/14] netdev-offload-dpdk: Support vports flows offload

2021-03-30 Thread Sriharsha Basavapatna via dev
On Wed, Mar 17, 2021 at 12:05 PM Eli Britstein  wrote:
>
> Vports are virtual, OVS only logical devices, so rte_flows cannot be
> applied as is on them. Instead, apply the rules the physical port from
> which the packet has arrived, provided by orig_in_port field.
>
> Signed-off-by: Eli Britstein 
> Reviewed-by: Gaetan Rivet 
> ---
>  lib/netdev-offload-dpdk.c | 204 --
>  1 file changed, 171 insertions(+), 33 deletions(-)
>
> diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c
> index ade7fae09..69aaefa0f 100644
> --- a/lib/netdev-offload-dpdk.c
> +++ b/lib/netdev-offload-dpdk.c
> @@ -25,6 +25,7 @@
>  #include "netdev-offload-provider.h"
>  #include "netdev-provider.h"
>  #include "netdev-vport.h"
> +#include "odp-util.h"
>  #include "openvswitch/match.h"
>  #include "openvswitch/vlog.h"
>  #include "packets.h"
> @@ -62,6 +63,7 @@ struct ufid_to_rte_flow_data {
>  struct rte_flow *rte_flow;
>  bool actions_offloaded;
>  struct dpif_flow_stats stats;
> +struct netdev *physdev;
>  };
>
>  /* Find rte_flow with @ufid. */
> @@ -87,7 +89,8 @@ ufid_to_rte_flow_data_find(const ovs_u128 *ufid, bool warn)
>
>  static inline struct ufid_to_rte_flow_data *
>  ufid_to_rte_flow_associate(const ovs_u128 *ufid, struct netdev *netdev,
> -   struct rte_flow *rte_flow, bool actions_offloaded)
> +   struct netdev *vport, struct rte_flow *rte_flow,
> +   bool actions_offloaded)
>  {
>  size_t hash = hash_bytes(ufid, sizeof *ufid, 0);
>  struct ufid_to_rte_flow_data *data = xzalloc(sizeof *data);
> @@ -105,7 +108,8 @@ ufid_to_rte_flow_associate(const ovs_u128 *ufid, struct 
> netdev *netdev,
>  }
>
>  data->ufid = *ufid;
> -data->netdev = netdev_ref(netdev);
> +data->physdev = netdev_ref(netdev);
> +data->netdev = vport ? netdev_ref(vport) : netdev;
>  data->rte_flow = rte_flow;
>  data->actions_offloaded = actions_offloaded;
>
> @@ -121,7 +125,10 @@ ufid_to_rte_flow_disassociate(struct 
> ufid_to_rte_flow_data *data)
>
>  cmap_remove(&ufid_to_rte_flow,
>  CONST_CAST(struct cmap_node *, &data->node), hash);
> -netdev_close(data->netdev);
> +if (data->netdev != data->physdev) {
> +netdev_close(data->netdev);
> +}
> +netdev_close(data->physdev);
>  ovsrcu_postpone(free, data);
>  }
>
> @@ -134,6 +141,8 @@ struct flow_patterns {
>  struct rte_flow_item *items;
>  int cnt;
>  int current_max;
> +uint32_t tnl_pmd_items_cnt;
> +struct ds s_tnl;
>  };
>
>  struct flow_actions {
> @@ -154,16 +163,20 @@ struct flow_actions {
>  static void
>  dump_flow_attr(struct ds *s, struct ds *s_extra,
> const struct rte_flow_attr *attr,
> +   struct flow_patterns *flow_patterns,
> struct flow_actions *flow_actions)
>  {
>  if (flow_actions->tnl_pmd_actions_cnt) {
>  ds_clone(s_extra, &flow_actions->s_tnl);
> +} else if (flow_patterns->tnl_pmd_items_cnt) {
> +ds_clone(s_extra, &flow_patterns->s_tnl);
>  }
> -ds_put_format(s, "%s%spriority %"PRIu32" group %"PRIu32" %s%s",
> +ds_put_format(s, "%s%spriority %"PRIu32" group %"PRIu32" %s%s%s",
>attr->ingress  ? "ingress " : "",
>attr->egress   ? "egress " : "", attr->priority, 
> attr->group,
>attr->transfer ? "transfer " : "",
> -  flow_actions->tnl_pmd_actions_cnt ? "tunnel_set 1 " : "");
> +  flow_actions->tnl_pmd_actions_cnt ? "tunnel_set 1 " : "",
> +  flow_patterns->tnl_pmd_items_cnt ? "tunnel_match 1 " : "");
>  }
>
>  /* Adds one pattern item 'field' with the 'mask' to dynamic string 's' using
> @@ -177,9 +190,18 @@ dump_flow_attr(struct ds *s, struct ds *s_extra,
>  }
>
>  static void
> -dump_flow_pattern(struct ds *s, const struct rte_flow_item *item)
> +dump_flow_pattern(struct ds *s,
> +  struct flow_patterns *flow_patterns,
> +  int pattern_index)
>  {
> -if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
> +const struct rte_flow_item *item = &flow_patterns->items[pattern_index];
> +
> +if (item->type == RTE_FLOW_ITEM_TYPE_END) {
> +ds_put_cstr(s, "end ");
> +} else if (flow_patterns->tnl_pmd_items_cnt &&
> +   pattern_index < flow_patterns->tnl_pmd_items_cnt) {
> +return;
> +} else if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
>  const struct rte_flow_item_eth *eth_spec = item->spec;
>  const struct rte_flow_item_eth *eth_mask = item->mask;
>
> @@ -569,19 +591,19 @@ dump_flow_action(struct ds *s, struct ds *s_extra,
>  static struct ds *
>  dump_flow(struct ds *s, struct ds *s_extra,
>const struct rte_flow_attr *attr,
> -  const struct rte_flow_item *items,
> +  struct flow_patterns *flow_patterns,
>struct flow_actions *flow_actions)
>  

[ovs-dev] [PATCH V4 13/14] netdev-offload-dpdk: Support vports flows offload

2021-03-16 Thread Eli Britstein
Vports are virtual, OVS only logical devices, so rte_flows cannot be
applied as is on them. Instead, apply the rules the physical port from
which the packet has arrived, provided by orig_in_port field.

Signed-off-by: Eli Britstein 
Reviewed-by: Gaetan Rivet 
---
 lib/netdev-offload-dpdk.c | 204 --
 1 file changed, 171 insertions(+), 33 deletions(-)

diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c
index ade7fae09..69aaefa0f 100644
--- a/lib/netdev-offload-dpdk.c
+++ b/lib/netdev-offload-dpdk.c
@@ -25,6 +25,7 @@
 #include "netdev-offload-provider.h"
 #include "netdev-provider.h"
 #include "netdev-vport.h"
+#include "odp-util.h"
 #include "openvswitch/match.h"
 #include "openvswitch/vlog.h"
 #include "packets.h"
@@ -62,6 +63,7 @@ struct ufid_to_rte_flow_data {
 struct rte_flow *rte_flow;
 bool actions_offloaded;
 struct dpif_flow_stats stats;
+struct netdev *physdev;
 };
 
 /* Find rte_flow with @ufid. */
@@ -87,7 +89,8 @@ ufid_to_rte_flow_data_find(const ovs_u128 *ufid, bool warn)
 
 static inline struct ufid_to_rte_flow_data *
 ufid_to_rte_flow_associate(const ovs_u128 *ufid, struct netdev *netdev,
-   struct rte_flow *rte_flow, bool actions_offloaded)
+   struct netdev *vport, struct rte_flow *rte_flow,
+   bool actions_offloaded)
 {
 size_t hash = hash_bytes(ufid, sizeof *ufid, 0);
 struct ufid_to_rte_flow_data *data = xzalloc(sizeof *data);
@@ -105,7 +108,8 @@ ufid_to_rte_flow_associate(const ovs_u128 *ufid, struct 
netdev *netdev,
 }
 
 data->ufid = *ufid;
-data->netdev = netdev_ref(netdev);
+data->physdev = netdev_ref(netdev);
+data->netdev = vport ? netdev_ref(vport) : netdev;
 data->rte_flow = rte_flow;
 data->actions_offloaded = actions_offloaded;
 
@@ -121,7 +125,10 @@ ufid_to_rte_flow_disassociate(struct ufid_to_rte_flow_data 
*data)
 
 cmap_remove(&ufid_to_rte_flow,
 CONST_CAST(struct cmap_node *, &data->node), hash);
-netdev_close(data->netdev);
+if (data->netdev != data->physdev) {
+netdev_close(data->netdev);
+}
+netdev_close(data->physdev);
 ovsrcu_postpone(free, data);
 }
 
@@ -134,6 +141,8 @@ struct flow_patterns {
 struct rte_flow_item *items;
 int cnt;
 int current_max;
+uint32_t tnl_pmd_items_cnt;
+struct ds s_tnl;
 };
 
 struct flow_actions {
@@ -154,16 +163,20 @@ struct flow_actions {
 static void
 dump_flow_attr(struct ds *s, struct ds *s_extra,
const struct rte_flow_attr *attr,
+   struct flow_patterns *flow_patterns,
struct flow_actions *flow_actions)
 {
 if (flow_actions->tnl_pmd_actions_cnt) {
 ds_clone(s_extra, &flow_actions->s_tnl);
+} else if (flow_patterns->tnl_pmd_items_cnt) {
+ds_clone(s_extra, &flow_patterns->s_tnl);
 }
-ds_put_format(s, "%s%spriority %"PRIu32" group %"PRIu32" %s%s",
+ds_put_format(s, "%s%spriority %"PRIu32" group %"PRIu32" %s%s%s",
   attr->ingress  ? "ingress " : "",
   attr->egress   ? "egress " : "", attr->priority, attr->group,
   attr->transfer ? "transfer " : "",
-  flow_actions->tnl_pmd_actions_cnt ? "tunnel_set 1 " : "");
+  flow_actions->tnl_pmd_actions_cnt ? "tunnel_set 1 " : "",
+  flow_patterns->tnl_pmd_items_cnt ? "tunnel_match 1 " : "");
 }
 
 /* Adds one pattern item 'field' with the 'mask' to dynamic string 's' using
@@ -177,9 +190,18 @@ dump_flow_attr(struct ds *s, struct ds *s_extra,
 }
 
 static void
-dump_flow_pattern(struct ds *s, const struct rte_flow_item *item)
+dump_flow_pattern(struct ds *s,
+  struct flow_patterns *flow_patterns,
+  int pattern_index)
 {
-if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
+const struct rte_flow_item *item = &flow_patterns->items[pattern_index];
+
+if (item->type == RTE_FLOW_ITEM_TYPE_END) {
+ds_put_cstr(s, "end ");
+} else if (flow_patterns->tnl_pmd_items_cnt &&
+   pattern_index < flow_patterns->tnl_pmd_items_cnt) {
+return;
+} else if (item->type == RTE_FLOW_ITEM_TYPE_ETH) {
 const struct rte_flow_item_eth *eth_spec = item->spec;
 const struct rte_flow_item_eth *eth_mask = item->mask;
 
@@ -569,19 +591,19 @@ dump_flow_action(struct ds *s, struct ds *s_extra,
 static struct ds *
 dump_flow(struct ds *s, struct ds *s_extra,
   const struct rte_flow_attr *attr,
-  const struct rte_flow_item *items,
+  struct flow_patterns *flow_patterns,
   struct flow_actions *flow_actions)
 {
 int i;
 
 if (attr) {
-dump_flow_attr(s, s_extra, attr, flow_actions);
+dump_flow_attr(s, s_extra, attr, flow_patterns, flow_actions);
 }
 ds_put_cstr(s, "pattern ");
-while (items && items->type != RTE_FLOW_ITEM_TYPE_END) {
-dump_flow_patte