Existing rte_flow offload provider is updated to use the new
framework for port management.

Signed-off-by: Eelco Chaudron <echau...@redhat.com>
---
 lib/dpif-offload-rte_flow.c | 85 +++++++++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)

diff --git a/lib/dpif-offload-rte_flow.c b/lib/dpif-offload-rte_flow.c
index 0041b5613..01a7a0730 100644
--- a/lib/dpif-offload-rte_flow.c
+++ b/lib/dpif-offload-rte_flow.c
@@ -15,6 +15,7 @@
  */
 
 #include <config.h>
+#include <errno.h>
 
 #include "dpif-offload.h"
 #include "dpif-offload-provider.h"
@@ -34,6 +35,7 @@ static unsigned int offload_thread_nb = 
DEFAULT_OFFLOAD_THREAD_NB;
 /* dpif offload interface for the rte implementation. */
 struct dpif_offload_rte_flow {
     struct dpif_offload offload;
+    struct dpif_offload_port_mgr *port_mgr;
 
     /* Configuration specific variables. */
     struct ovsthread_once once_enable; /* Track first-time enablement. */
@@ -46,6 +48,59 @@ dpif_offload_rte_cast(const struct dpif_offload *offload)
     return CONTAINER_OF(offload, struct dpif_offload_rte_flow, offload);
 }
 
+static int
+dpif_offload_rte_enable_offload(struct dpif_offload *dpif_offload,
+                                struct dpif_offload_port_mgr_port *port)
+{
+    dpif_offload_set_netdev_offload(port->netdev, dpif_offload);
+    return 0;
+}
+
+static int
+dpif_offload_rte_cleanup_offload(struct dpif_offload *dpif_offload OVS_UNUSED,
+                                 struct dpif_offload_port_mgr_port *port)
+{
+    dpif_offload_set_netdev_offload(port->netdev, NULL);
+    return 0;
+}
+
+static int
+dpif_offload_rte_port_add(struct dpif_offload *offload,
+                          struct netdev *netdev, odp_port_t port_no)
+{
+    struct dpif_offload_rte_flow *offload_rte = dpif_offload_rte_cast(offload);
+    struct dpif_offload_port_mgr_port *port = xmalloc(sizeof *port);
+
+    if (dpif_offload_port_mgr_add(offload_rte->port_mgr, port, netdev,
+                                  port_no, false)) {
+        if (dpif_offload_is_offload_enabled()) {
+            return dpif_offload_rte_enable_offload(offload, port);
+        }
+        return 0;
+    }
+
+    free(port);
+    return EEXIST;
+}
+
+static int
+dpif_offload_rte_port_del(struct dpif_offload *offload, odp_port_t port_no)
+{
+    struct dpif_offload_rte_flow *offload_rte = dpif_offload_rte_cast(offload);
+    struct dpif_offload_port_mgr_port *port;
+    int ret = 0;
+
+    port = dpif_offload_port_mgr_remove(offload_rte->port_mgr, port_no, true);
+    if (port) {
+        if (dpif_offload_is_offload_enabled()) {
+            ret = dpif_offload_rte_cleanup_offload(offload, port);
+        }
+        netdev_close(port->netdev);
+        ovsrcu_postpone(free, port);
+    }
+    return ret;
+}
+
 static int
 dpif_offload_rte_open(const struct dpif_offload_class *offload_class,
                       struct dpif *dpif, struct dpif_offload **dpif_offload)
@@ -55,6 +110,7 @@ dpif_offload_rte_open(const struct dpif_offload_class 
*offload_class,
     offload_rte = xmalloc(sizeof(struct dpif_offload_rte_flow));
 
     dpif_offload_init(&offload_rte->offload, offload_class, dpif);
+    offload_rte->port_mgr = dpif_offload_port_mgr_init();
     offload_rte->once_enable = (struct ovsthread_once)
         OVSTHREAD_ONCE_INITIALIZER;
 
@@ -62,15 +118,38 @@ dpif_offload_rte_open(const struct dpif_offload_class 
*offload_class,
     return 0;
 }
 
+static bool
+dpif_offload_rte_cleanup_port(struct dpif_offload_port_mgr_port *port,
+                              void *aux)
+{
+    struct dpif_offload *offload = aux;
+
+    dpif_offload_rte_port_del(offload, port->port_no);
+    return false;
+}
+
 static void
 dpif_offload_rte_close(struct dpif_offload *dpif_offload)
 {
     struct dpif_offload_rte_flow *offload_rte;
 
     offload_rte = dpif_offload_rte_cast(dpif_offload);
+
+    dpif_offload_port_mgr_traverse_ports(offload_rte->port_mgr,
+                                         dpif_offload_rte_cleanup_port,
+                                         dpif_offload);
+
+    dpif_offload_port_mgr_uninit(offload_rte->port_mgr);
     free(offload_rte);
 }
 
+static bool dpif_offload_rte_late_enable(struct dpif_offload_port_mgr_port *p,
+                                         void *aux)
+{
+    dpif_offload_rte_enable_offload(aux, p);
+    return false;
+}
+
 static void
 dpif_offload_rte_set_config(struct dpif_offload *offload,
                            const struct smap *other_cfg)
@@ -99,6 +178,10 @@ dpif_offload_rte_set_config(struct dpif_offload *offload,
                           offload_thread_nb > 1 ? "s" : "");
             }
 
+            dpif_offload_port_mgr_traverse_ports(offload_rte->port_mgr,
+                                                 dpif_offload_rte_late_enable,
+                                                 offload);
+
             ovsthread_once_done(&offload_rte->once_enable);
         }
     }
@@ -127,6 +210,8 @@ struct dpif_offload_class dpif_offload_rte_flow_class = {
     .close = dpif_offload_rte_close,
     .set_config = dpif_offload_rte_set_config,
     .can_offload = dpif_offload_rte_can_offload,
+    .port_add = dpif_offload_rte_port_add,
+    .port_del = dpif_offload_rte_port_del,
 };
 
 /* XXX: Temporary functions below, which will be removed once fully
-- 
2.50.1

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

Reply via email to