Re: [ovs-dev] [PATCH v28 3/8] netdev-offload-tc: Introduce group ID management API

2024-03-25 Thread Chris Mi via dev

On 6/24/2023 4:17 AM, Ilya Maximets wrote:

On 6/19/23 07:05, Chris Mi wrote:

When offloading sample action to TC, userspace creates a unique ID
to map sample action and tunnel info and passes this ID to kernel
instead of the sample info. Kernel will send this ID and sampled
packet to userspace. Using the ID, userspace can recover the sample
info and send sampled packet to the right sample monitoring host.

Signed-off-by: Chris Mi 
Reviewed-by: Roi Dayan 
---
  lib/netdev-offload-tc.c | 156 +---
  lib/util.c  |   6 ++
  lib/util.h  |   1 +
  3 files changed, 154 insertions(+), 9 deletions(-)

diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
index 4f26dd8cc..56726acf8 100644
--- a/lib/netdev-offload-tc.c
+++ b/lib/netdev-offload-tc.c
@@ -19,28 +19,29 @@
  #include 
  #include 
  
+#include "cmap.h"

+#include "dpif-provider.h"
  #include "dpif.h"
  #include "hash.h"
  #include "id-pool.h"
-#include "openvswitch/hmap.h"
-#include "openvswitch/match.h"
-#include "openvswitch/ofpbuf.h"
-#include "openvswitch/thread.h"
-#include "openvswitch/types.h"
-#include "openvswitch/util.h"
-#include "openvswitch/vlog.h"
  #include "netdev-linux.h"
  #include "netdev-offload-provider.h"
  #include "netdev-provider.h"
  #include "netdev-vport.h"
-#include "netlink.h"
  #include "netlink-socket.h"
+#include "netlink.h"
  #include "odp-netlink.h"
  #include "odp-util.h"
+#include "openvswitch/hmap.h"
+#include "openvswitch/match.h"
+#include "openvswitch/ofpbuf.h"
+#include "openvswitch/thread.h"
+#include "openvswitch/types.h"
+#include "openvswitch/util.h"
+#include "openvswitch/vlog.h"
  #include "tc.h"
  #include "unaligned.h"
  #include "util.h"
-#include "dpif-provider.h"
  
  VLOG_DEFINE_THIS_MODULE(netdev_offload_tc);
  
@@ -103,6 +104,125 @@ static void parse_tc_flower_to_stats(struct tc_flower *flower,

  static int get_ufid_adjust_stats(const ovs_u128 *ufid,
   struct dpif_flow_stats *stats);
  
+/* When offloading sample action to TC, userspace creates a unique ID

+ * to map sample action and tunnel info and passes this ID to kernel
+ * instead of the sample info. Kernel will send this ID and sampled
+ * packet to userspace. Using the ID, userspace can recover the sample
+ * info and send sampled packet to the right sample monitoring host. */
+struct offload_sample {
+uint16_t type; /* enum user_action_cookie_type. */
+struct nlattr *action; /* Sample action. Used in flow_get. */
+struct nlattr *userdata;   /* Struct user_action_cookie. */
+struct nlattr *userspace_actions;  /* All actions to get output tunnel. */
+struct flow_tnl *tunnel;   /* Input tunnel. */
+uint16_t ifindex;  /* Input ifindex. */
+};
+
+/* This maps a sample group ID to struct offload_sample. */
+struct sgid_node {
+struct cmap_node id_node;
+uint32_t id;
+struct offload_sample sample;
+};
+
+/* The sgid_map mutex protects the sample_group_ids and the sgid_map for
+ * cmap_insert(), cmap_remove(), or cmap_replace() operations. */
+static struct ovs_mutex sgid_lock = OVS_MUTEX_INITIALIZER;
+static struct cmap sgid_map = CMAP_INITIALIZER;
+static struct id_pool *sample_group_ids OVS_GUARDED_BY(sgid_lock);
+
+static void
+sgid_node_free(struct sgid_node *node)
+{
+if (node) {
+if (node->id) {
+ovs_mutex_lock(&sgid_lock);
+id_pool_free_id(sample_group_ids, node->id);
+ovs_mutex_unlock(&sgid_lock);
+}
+free(node->sample.tunnel);
+free(node->sample.action);
+free(node->sample.userspace_actions);
+free(node->sample.userdata);
+free(node);
+}
+}
+
+static struct sgid_node *
+sgid_find(uint32_t id)
+{
+const struct cmap_node *node = cmap_find(&sgid_map, id);
+
+return node ? CONTAINER_OF(node, struct sgid_node, id_node) : NULL;
+}
+
+static void
+offload_sample_clone(struct offload_sample *dst,
+ const struct offload_sample *src,
+ bool steal_userspace_actions)
+{
+dst->type = src->type;
+dst->action = nullable_xmemdup(src->action, src->action ?
+src->action->nla_len : 0);
+if (steal_userspace_actions) {
+dst->userspace_actions = src->userspace_actions;
+} else {
+dst->userspace_actions = src->userspace_actions
+? xmemdup(src->userspace_actions,
+  src->userspace_actions->nla_len)
+: NULL;
+}
+dst->userdata = nullable_xmemdup(src->userdata, src->userdata ?
+src->userdata->nla_len :
+0);
+dst->tunnel = nullable_xmemdup(src->tunnel, sizeof *src->tunnel);
+dst->ifindex = src->ifindex;
+}
+
+/* Allocate a unique group id for the given set of flow metadata. The id

Re: [ovs-dev] [PATCH v28 3/8] netdev-offload-tc: Introduce group ID management API

2023-06-23 Thread Ilya Maximets
On 6/19/23 07:05, Chris Mi wrote:
> When offloading sample action to TC, userspace creates a unique ID
> to map sample action and tunnel info and passes this ID to kernel
> instead of the sample info. Kernel will send this ID and sampled
> packet to userspace. Using the ID, userspace can recover the sample
> info and send sampled packet to the right sample monitoring host.
> 
> Signed-off-by: Chris Mi 
> Reviewed-by: Roi Dayan 
> ---
>  lib/netdev-offload-tc.c | 156 +---
>  lib/util.c  |   6 ++
>  lib/util.h  |   1 +
>  3 files changed, 154 insertions(+), 9 deletions(-)
> 
> diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
> index 4f26dd8cc..56726acf8 100644
> --- a/lib/netdev-offload-tc.c
> +++ b/lib/netdev-offload-tc.c
> @@ -19,28 +19,29 @@
>  #include 
>  #include 
>  
> +#include "cmap.h"
> +#include "dpif-provider.h"
>  #include "dpif.h"
>  #include "hash.h"
>  #include "id-pool.h"
> -#include "openvswitch/hmap.h"
> -#include "openvswitch/match.h"
> -#include "openvswitch/ofpbuf.h"
> -#include "openvswitch/thread.h"
> -#include "openvswitch/types.h"
> -#include "openvswitch/util.h"
> -#include "openvswitch/vlog.h"
>  #include "netdev-linux.h"
>  #include "netdev-offload-provider.h"
>  #include "netdev-provider.h"
>  #include "netdev-vport.h"
> -#include "netlink.h"
>  #include "netlink-socket.h"
> +#include "netlink.h"
>  #include "odp-netlink.h"
>  #include "odp-util.h"
> +#include "openvswitch/hmap.h"
> +#include "openvswitch/match.h"
> +#include "openvswitch/ofpbuf.h"
> +#include "openvswitch/thread.h"
> +#include "openvswitch/types.h"
> +#include "openvswitch/util.h"
> +#include "openvswitch/vlog.h"
>  #include "tc.h"
>  #include "unaligned.h"
>  #include "util.h"
> -#include "dpif-provider.h"
>  
>  VLOG_DEFINE_THIS_MODULE(netdev_offload_tc);
>  
> @@ -103,6 +104,125 @@ static void parse_tc_flower_to_stats(struct tc_flower 
> *flower,
>  static int get_ufid_adjust_stats(const ovs_u128 *ufid,
>   struct dpif_flow_stats *stats);
>  
> +/* When offloading sample action to TC, userspace creates a unique ID
> + * to map sample action and tunnel info and passes this ID to kernel
> + * instead of the sample info. Kernel will send this ID and sampled
> + * packet to userspace. Using the ID, userspace can recover the sample
> + * info and send sampled packet to the right sample monitoring host. */
> +struct offload_sample {
> +uint16_t type; /* enum user_action_cookie_type. */
> +struct nlattr *action; /* Sample action. Used in flow_get. */
> +struct nlattr *userdata;   /* Struct user_action_cookie. */
> +struct nlattr *userspace_actions;  /* All actions to get output tunnel. 
> */
> +struct flow_tnl *tunnel;   /* Input tunnel. */
> +uint16_t ifindex;  /* Input ifindex. */
> +};
> +
> +/* This maps a sample group ID to struct offload_sample. */
> +struct sgid_node {
> +struct cmap_node id_node;
> +uint32_t id;
> +struct offload_sample sample;
> +};
> +
> +/* The sgid_map mutex protects the sample_group_ids and the sgid_map for
> + * cmap_insert(), cmap_remove(), or cmap_replace() operations. */
> +static struct ovs_mutex sgid_lock = OVS_MUTEX_INITIALIZER;
> +static struct cmap sgid_map = CMAP_INITIALIZER;
> +static struct id_pool *sample_group_ids OVS_GUARDED_BY(sgid_lock);
> +
> +static void
> +sgid_node_free(struct sgid_node *node)
> +{
> +if (node) {
> +if (node->id) {
> +ovs_mutex_lock(&sgid_lock);
> +id_pool_free_id(sample_group_ids, node->id);
> +ovs_mutex_unlock(&sgid_lock);
> +}
> +free(node->sample.tunnel);
> +free(node->sample.action);
> +free(node->sample.userspace_actions);
> +free(node->sample.userdata);
> +free(node);
> +}
> +}
> +
> +static struct sgid_node *
> +sgid_find(uint32_t id)
> +{
> +const struct cmap_node *node = cmap_find(&sgid_map, id);
> +
> +return node ? CONTAINER_OF(node, struct sgid_node, id_node) : NULL;
> +}
> +
> +static void
> +offload_sample_clone(struct offload_sample *dst,
> + const struct offload_sample *src,
> + bool steal_userspace_actions)
> +{
> +dst->type = src->type;
> +dst->action = nullable_xmemdup(src->action, src->action ?
> +src->action->nla_len : 0);
> +if (steal_userspace_actions) {
> +dst->userspace_actions = src->userspace_actions;
> +} else {
> +dst->userspace_actions = src->userspace_actions
> +? xmemdup(src->userspace_actions,
> +  src->userspace_actions->nla_len)
> +: NULL;
> +}
> +dst->userdata = nullable_xmemdup(src->userdata, src->userdata ?
> +src->userdata->nla_len :
> + 

Re: [ovs-dev] [PATCH v28 3/8] netdev-offload-tc: Introduce group ID management API

2023-06-19 Thread Eelco Chaudron



On 19 Jun 2023, at 7:05, Chris Mi wrote:

> When offloading sample action to TC, userspace creates a unique ID
> to map sample action and tunnel info and passes this ID to kernel
> instead of the sample info. Kernel will send this ID and sampled
> packet to userspace. Using the ID, userspace can recover the sample
> info and send sampled packet to the right sample monitoring host.
>
> Signed-off-by: Chris Mi 
> Reviewed-by: Roi Dayan 

Thanks for making all the suggested changes.

Acked-by: Eelco Chaudron 

//Eelco

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


[ovs-dev] [PATCH v28 3/8] netdev-offload-tc: Introduce group ID management API

2023-06-18 Thread Chris Mi via dev
When offloading sample action to TC, userspace creates a unique ID
to map sample action and tunnel info and passes this ID to kernel
instead of the sample info. Kernel will send this ID and sampled
packet to userspace. Using the ID, userspace can recover the sample
info and send sampled packet to the right sample monitoring host.

Signed-off-by: Chris Mi 
Reviewed-by: Roi Dayan 
---
 lib/netdev-offload-tc.c | 156 +---
 lib/util.c  |   6 ++
 lib/util.h  |   1 +
 3 files changed, 154 insertions(+), 9 deletions(-)

diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
index 4f26dd8cc..56726acf8 100644
--- a/lib/netdev-offload-tc.c
+++ b/lib/netdev-offload-tc.c
@@ -19,28 +19,29 @@
 #include 
 #include 
 
+#include "cmap.h"
+#include "dpif-provider.h"
 #include "dpif.h"
 #include "hash.h"
 #include "id-pool.h"
-#include "openvswitch/hmap.h"
-#include "openvswitch/match.h"
-#include "openvswitch/ofpbuf.h"
-#include "openvswitch/thread.h"
-#include "openvswitch/types.h"
-#include "openvswitch/util.h"
-#include "openvswitch/vlog.h"
 #include "netdev-linux.h"
 #include "netdev-offload-provider.h"
 #include "netdev-provider.h"
 #include "netdev-vport.h"
-#include "netlink.h"
 #include "netlink-socket.h"
+#include "netlink.h"
 #include "odp-netlink.h"
 #include "odp-util.h"
+#include "openvswitch/hmap.h"
+#include "openvswitch/match.h"
+#include "openvswitch/ofpbuf.h"
+#include "openvswitch/thread.h"
+#include "openvswitch/types.h"
+#include "openvswitch/util.h"
+#include "openvswitch/vlog.h"
 #include "tc.h"
 #include "unaligned.h"
 #include "util.h"
-#include "dpif-provider.h"
 
 VLOG_DEFINE_THIS_MODULE(netdev_offload_tc);
 
@@ -103,6 +104,125 @@ static void parse_tc_flower_to_stats(struct tc_flower 
*flower,
 static int get_ufid_adjust_stats(const ovs_u128 *ufid,
  struct dpif_flow_stats *stats);
 
+/* When offloading sample action to TC, userspace creates a unique ID
+ * to map sample action and tunnel info and passes this ID to kernel
+ * instead of the sample info. Kernel will send this ID and sampled
+ * packet to userspace. Using the ID, userspace can recover the sample
+ * info and send sampled packet to the right sample monitoring host. */
+struct offload_sample {
+uint16_t type; /* enum user_action_cookie_type. */
+struct nlattr *action; /* Sample action. Used in flow_get. */
+struct nlattr *userdata;   /* Struct user_action_cookie. */
+struct nlattr *userspace_actions;  /* All actions to get output tunnel. */
+struct flow_tnl *tunnel;   /* Input tunnel. */
+uint16_t ifindex;  /* Input ifindex. */
+};
+
+/* This maps a sample group ID to struct offload_sample. */
+struct sgid_node {
+struct cmap_node id_node;
+uint32_t id;
+struct offload_sample sample;
+};
+
+/* The sgid_map mutex protects the sample_group_ids and the sgid_map for
+ * cmap_insert(), cmap_remove(), or cmap_replace() operations. */
+static struct ovs_mutex sgid_lock = OVS_MUTEX_INITIALIZER;
+static struct cmap sgid_map = CMAP_INITIALIZER;
+static struct id_pool *sample_group_ids OVS_GUARDED_BY(sgid_lock);
+
+static void
+sgid_node_free(struct sgid_node *node)
+{
+if (node) {
+if (node->id) {
+ovs_mutex_lock(&sgid_lock);
+id_pool_free_id(sample_group_ids, node->id);
+ovs_mutex_unlock(&sgid_lock);
+}
+free(node->sample.tunnel);
+free(node->sample.action);
+free(node->sample.userspace_actions);
+free(node->sample.userdata);
+free(node);
+}
+}
+
+static struct sgid_node *
+sgid_find(uint32_t id)
+{
+const struct cmap_node *node = cmap_find(&sgid_map, id);
+
+return node ? CONTAINER_OF(node, struct sgid_node, id_node) : NULL;
+}
+
+static void
+offload_sample_clone(struct offload_sample *dst,
+ const struct offload_sample *src,
+ bool steal_userspace_actions)
+{
+dst->type = src->type;
+dst->action = nullable_xmemdup(src->action, src->action ?
+src->action->nla_len : 0);
+if (steal_userspace_actions) {
+dst->userspace_actions = src->userspace_actions;
+} else {
+dst->userspace_actions = src->userspace_actions
+? xmemdup(src->userspace_actions,
+  src->userspace_actions->nla_len)
+: NULL;
+}
+dst->userdata = nullable_xmemdup(src->userdata, src->userdata ?
+src->userdata->nla_len :
+0);
+dst->tunnel = nullable_xmemdup(src->tunnel, sizeof *src->tunnel);
+dst->ifindex = src->ifindex;
+}
+
+/* Allocate a unique group id for the given set of flow metadata. The id
+ * space is 2^^32 - 1. 0 is reserved. */
+static uint32_t
+sgid_alloc(const struct offload_sample *sample)