[ovs-dev] [PATCH v3 03/16] dpif: Defer recirc actions in dpif_execute_helper_cb()

Simon Horman horms at verge.net.au
Tue Apr 22 08:54:51 UTC 2014


Rather then prohibiting recirc actions dpif_execute_helper_cb()
deffer their processing by saving the required state.

This is in preparation for allowing execution of recirc actions
in ovs-vswitchd.

Signed-off-by: Simon Horman <horms at verge.net.au>
---
 lib/dpif.c | 37 +++++++++++++++++++++++++++++++++++--
 lib/dpif.h | 10 ++++++++++
 2 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/lib/dpif.c b/lib/dpif.c
index 41b8eb7..6a67127 100644
--- a/lib/dpif.c
+++ b/lib/dpif.c
@@ -1102,8 +1102,36 @@ dpif_flow_dump_done(struct dpif_flow_dump *dump)
 struct dpif_execute_helper_aux {
     struct dpif *dpif;
     int error;
+    struct list *recirc_list;
 };
 
+static void
+dpif_execute_recirc_add(uint32_t id, struct ofpbuf *packet,
+                        struct pkt_metadata *md, struct list *list)
+{
+    struct dpif_execute_recirc *recirc;
+
+    if (!list) {
+        return;
+    }
+
+    recirc = xmalloc(sizeof(struct dpif_execute_recirc));
+    list_init(&recirc->list_node);
+    list_push_front(list, &recirc->list_node);
+    recirc->md = *md;
+    recirc->md.recirc_id = id;
+    recirc->packet = ofpbuf_clone_with_headroom(packet,
+                                                ofpbuf_headroom(packet));
+}
+
+void
+dpif_execute_recirc_destroy(struct dpif_execute_recirc *recirc)
+{
+    list_remove(&recirc->list_node);
+    ofpbuf_delete(recirc->packet);
+    free(recirc);
+}
+
 /* This is called for actions that need the context of the datapath to be
  * meaningful. */
 static void
@@ -1126,6 +1154,12 @@ dpif_execute_helper_cb(void *aux_, struct ofpbuf *packet,
         aux->error = aux->dpif->dpif_class->execute(aux->dpif, &execute);
         break;
 
+    case OVS_ACTION_ATTR_RECIRC:
+        /* XXX: Use may_steal */
+        dpif_execute_recirc_add(nl_attr_get_u32(action), packet,
+                                md, aux->recirc_list);
+        break;
+
     case OVS_ACTION_ATTR_PUSH_VLAN:
     case OVS_ACTION_ATTR_POP_VLAN:
     case OVS_ACTION_ATTR_PUSH_MPLS:
@@ -1133,7 +1167,6 @@ dpif_execute_helper_cb(void *aux_, struct ofpbuf *packet,
     case OVS_ACTION_ATTR_SET:
     case OVS_ACTION_ATTR_SAMPLE:
     case OVS_ACTION_ATTR_UNSPEC:
-    case OVS_ACTION_ATTR_RECIRC:
     case OVS_ACTION_ATTR_HASH:
     case __OVS_ACTION_ATTR_MAX:
         OVS_NOT_REACHED();
@@ -1148,7 +1181,7 @@ dpif_execute_helper_cb(void *aux_, struct ofpbuf *packet,
 static int
 dpif_execute_with_help(struct dpif *dpif, struct dpif_execute *execute)
 {
-    struct dpif_execute_helper_aux aux = {dpif, 0};
+    struct dpif_execute_helper_aux aux = {dpif, 0, execute->recirc_list};
 
     COVERAGE_INC(dpif_execute_with_help);
 
diff --git a/lib/dpif.h b/lib/dpif.h
index e7aca8e..d47f3db 100644
--- a/lib/dpif.h
+++ b/lib/dpif.h
@@ -577,6 +577,14 @@ struct dpif_flow_del {
     struct dpif_flow_stats *stats;  /* Optional flow statistics. */
 };
 
+struct dpif_execute_recirc {
+    struct list list_node;      /* Private list element for use by owner. */
+    struct pkt_metadata md;
+    struct ofpbuf *packet;
+};
+
+void dpif_execute_recirc_destroy(struct dpif_execute_recirc *);
+
 struct dpif_execute {
     /* Raw support for execute passed along to the provider. */
     const struct nlattr *actions;   /* Actions to execute on packet. */
@@ -592,6 +600,8 @@ struct dpif_execute {
      * OVS_ACTION_ATTR_USERSPACE actions it passes the packet through to the
      * dpif implementation. */
     bool needs_help;
+
+    struct list *recirc_list;
 };
 
 int dpif_execute(struct dpif *, struct dpif_execute *);
-- 
1.8.5.2




More information about the dev mailing list