[ovs-dev,no-slow,v2,6/8] ofproto: Add 'ofproto_uuid' and 'ofp_in_port' to user action cookie.

Message ID 1515623246-3820-6-git-send-email-jpettit@ovn.org
State Accepted
Headers show
Series
  • [ovs-dev,no-slow,v2,1/8] ofproto-dpif: Use a fixed size userspace cookie.
Related show

Commit Message

Justin Pettit Jan. 10, 2018, 10:27 p.m.
Previously, the ofproto instance and OpenFlow port have been derived
based on the datapath port number.  This change explicitly declares them
both, which will be helpful in future commits that no longer can depend
on having a unique datapath port (e.g., a source port that represents
the controller).

Signed-off-by: Justin Pettit <jpettit@ovn.org>
Acked-by: Ben Pfaff <blp@ovn.org>
---
v1->v2: Changes suggested by Ben.
---
 lib/odp-util.c                |  9 +++++++-
 lib/odp-util.h                |  5 ++++-
 ofproto/ofproto-dpif-upcall.c | 49 ++++++++++++++++++++++++++++++-------------
 ofproto/ofproto-dpif-xlate.c  | 13 +++++++++---
 4 files changed, 56 insertions(+), 20 deletions(-)

Patch

diff --git a/lib/odp-util.c b/lib/odp-util.c
index 2910e1514985..a2a8d615f708 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -1142,13 +1142,16 @@  parse_odp_userspace_action(const char *s, struct ofpbuf *actions)
             }
 
             cookie.type = USER_ACTION_COOKIE_SFLOW;
+            cookie.ofp_in_port = OFPP_NONE;
+            cookie.ofproto_uuid = UUID_ZERO;
             cookie.sflow.vlan_tci = htons(tci);
             cookie.sflow.output = output;
         } else if (ovs_scan(&s[n], ",slow_path(%n",
                             &n1)) {
             n += n1;
             cookie.type = USER_ACTION_COOKIE_SLOW_PATH;
-            cookie.slow_path.unused = 0;
+            cookie.ofp_in_port = OFPP_NONE;
+            cookie.ofproto_uuid = UUID_ZERO;
             cookie.slow_path.reason = 0;
 
             res = parse_odp_flags(&s[n], slow_path_reason_to_string,
@@ -1169,6 +1172,8 @@  parse_odp_userspace_action(const char *s, struct ofpbuf *actions)
             n += n1;
 
             cookie.type = USER_ACTION_COOKIE_FLOW_SAMPLE;
+            cookie.ofp_in_port = OFPP_NONE;
+            cookie.ofproto_uuid = UUID_ZERO;
             cookie.flow_sample.probability = probability;
             cookie.flow_sample.collector_set_id = collector_set_id;
             cookie.flow_sample.obs_domain_id = obs_domain_id;
@@ -1193,6 +1198,8 @@  parse_odp_userspace_action(const char *s, struct ofpbuf *actions)
                             &output, &n1) ) {
             n += n1;
             cookie.type = USER_ACTION_COOKIE_IPFIX;
+            cookie.ofp_in_port = OFPP_NONE;
+            cookie.ofproto_uuid = UUID_ZERO;
             cookie.ipfix.output_odp_port = u32_to_odp(output);
         } else if (ovs_scan(&s[n], ",userdata(%n",
                             &n1)) {
diff --git a/lib/odp-util.h b/lib/odp-util.h
index b08ff7190168..2a4b3d13812b 100644
--- a/lib/odp-util.h
+++ b/lib/odp-util.h
@@ -25,6 +25,7 @@ 
 #include "hash.h"
 #include "openvswitch/hmap.h"
 #include "openvswitch/ofp-actions.h"
+#include "openvswitch/uuid.h"
 #include "odp-netlink.h"
 #include "openflow/openflow.h"
 #include "util.h"
@@ -302,6 +303,8 @@  enum user_action_cookie_type {
 /* user_action_cookie is passed as argument to OVS_ACTION_ATTR_USERSPACE. */
 struct user_action_cookie {
     uint16_t type;              /* enum user_action_cookie_type. */
+    ofp_port_t ofp_in_port;     /* OpenFlow in port, or OFPP_NONE. */
+    struct uuid ofproto_uuid;   /* UUID of ofproto-dpif. */
 
     union {
         struct {
@@ -332,7 +335,7 @@  struct user_action_cookie {
         } ipfix;
     };
 };
-BUILD_ASSERT_DECL(sizeof(struct user_action_cookie) == 28);
+BUILD_ASSERT_DECL(sizeof(struct user_action_cookie) == 48);
 
 size_t odp_put_userspace_action(uint32_t pid,
                                 const void *userdata, size_t userdata_size,
diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index 5ba1006893dc..bd7dc9e7b718 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -38,6 +38,7 @@ 
 #include "packets.h"
 #include "openvswitch/poll-loop.h"
 #include "seq.h"
+#include "tunnel.h"
 #include "unixctl.h"
 #include "openvswitch/vlog.h"
 
@@ -207,7 +208,7 @@  struct upcall {
     const ovs_u128 *ufid;          /* Unique identifier for 'flow'. */
     unsigned pmd_id;               /* Datapath poll mode driver id. */
     const struct dp_packet *packet;   /* Packet associated with this upcall. */
-    ofp_port_t in_port;            /* OpenFlow in port, or OFPP_NONE. */
+    ofp_port_t ofp_in_port;        /* OpenFlow in port, or OFPP_NONE. */
     uint16_t mru;                  /* If !0, Maximum receive unit of
                                       fragmented IP packet */
 
@@ -1021,16 +1022,18 @@  classify_upcall(enum dpif_upcall_type type, const struct nlattr *userdata,
  * initialized with at least 128 bytes of space. */
 static void
 compose_slow_path(struct udpif *udpif, struct xlate_out *xout,
-                  const struct flow *flow, odp_port_t odp_in_port,
+                  const struct flow *flow,
+                  odp_port_t odp_in_port, ofp_port_t ofp_in_port,
                   struct ofpbuf *buf, uint32_t slowpath_meter_id,
-                  uint32_t controller_meter_id)
+                  uint32_t controller_meter_id, struct uuid *ofproto_uuid)
 {
     struct user_action_cookie cookie;
     odp_port_t port;
     uint32_t pid;
 
     cookie.type = USER_ACTION_COOKIE_SLOW_PATH;
-    cookie.slow_path.unused = 0;
+    cookie.ofp_in_port = ofp_in_port;
+    cookie.ofproto_uuid = *ofproto_uuid;
     cookie.slow_path.reason = xout->slow;
 
     port = xout->slow & (SLOW_CFM | SLOW_BFD | SLOW_LACP | SLOW_STP)
@@ -1077,12 +1080,23 @@  upcall_receive(struct upcall *upcall, const struct dpif_backer *backer,
     upcall->type = classify_upcall(type, userdata, &upcall->cookie);
     if (upcall->type == BAD_UPCALL) {
         return EAGAIN;
-    }
-
-    error = xlate_lookup(backer, flow, &upcall->ofproto, &upcall->ipfix,
-                         &upcall->sflow, NULL, &upcall->in_port);
-    if (error) {
-        return error;
+    } else if (upcall->type == MISS_UPCALL) {
+        error = xlate_lookup(backer, flow, &upcall->ofproto, &upcall->ipfix,
+                             &upcall->sflow, NULL, &upcall->ofp_in_port);
+        if (error) {
+            return error;
+        }
+    } else {
+        struct ofproto_dpif *ofproto
+            = ofproto_dpif_lookup_by_uuid(&upcall->cookie.ofproto_uuid);
+        if (!ofproto) {
+            VLOG_INFO_RL(&rl, "upcall could not find ofproto");
+            return ENODEV;
+        }
+        upcall->ofproto = ofproto;
+        upcall->ipfix = ofproto->ipfix;
+        upcall->sflow = ofproto->sflow;
+        upcall->ofp_in_port = upcall->cookie.ofp_in_port;
     }
 
     upcall->recirc = NULL;
@@ -1123,7 +1137,7 @@  upcall_xlate(struct udpif *udpif, struct upcall *upcall,
 
     xlate_in_init(&xin, upcall->ofproto,
                   ofproto_dpif_get_tables_version(upcall->ofproto),
-                  upcall->flow, upcall->in_port, NULL,
+                  upcall->flow, upcall->ofp_in_port, NULL,
                   stats.tcp_flags, upcall->packet, wc, odp_actions);
 
     if (upcall->type == MISS_UPCALL) {
@@ -1168,8 +1182,9 @@  upcall_xlate(struct udpif *udpif, struct upcall *upcall,
         uint32_t cmid = upcall->ofproto->up.controller_meter_id;
         /* upcall->put_actions already initialized by upcall_receive(). */
         compose_slow_path(udpif, &upcall->xout, upcall->flow,
-                          upcall->flow->in_port.odp_port,
-                          &upcall->put_actions, smid, cmid);
+                          upcall->flow->in_port.odp_port, upcall->ofp_in_port,
+                          &upcall->put_actions, smid, cmid,
+                          &upcall->ofproto->uuid);
     }
 
     /* This function is also called for slow-pathed flows.  As we are only
@@ -2025,13 +2040,17 @@  revalidate_ukey__(struct udpif *udpif, const struct udpif_key *ukey,
 
     if (xoutp->slow) {
         struct ofproto_dpif *ofproto;
-        ofproto = xlate_lookup_ofproto(udpif->backer, &ctx.flow, NULL);
+        ofp_port_t ofp_in_port;
+
+        ofproto = xlate_lookup_ofproto(udpif->backer, &ctx.flow,
+                                       &ofp_in_port);
         uint32_t smid = ofproto ? ofproto->up.slowpath_meter_id : UINT32_MAX;
         uint32_t cmid = ofproto ? ofproto->up.controller_meter_id : UINT32_MAX;
 
         ofpbuf_clear(odp_actions);
         compose_slow_path(udpif, xoutp, &ctx.flow, ctx.flow.in_port.odp_port,
-                          odp_actions, smid, cmid);
+                          ofp_in_port, odp_actions, smid, cmid,
+                          &ofproto->uuid);
     }
 
     if (odp_flow_key_to_mask(ukey->mask, ukey->mask_len, &dp_mask, &ctx.flow)
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 63d15e94331f..2b1cbddae4e2 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -2927,7 +2927,11 @@  compose_sflow_action(struct xlate_ctx *ctx)
         return 0;
     }
 
-    struct user_action_cookie cookie = { .type = USER_ACTION_COOKIE_SFLOW };
+    struct user_action_cookie cookie = {
+        .type = USER_ACTION_COOKIE_SFLOW,
+        .ofp_in_port = ctx->xin->flow.in_port.ofp_port,
+        .ofproto_uuid = ctx->xbridge->ofproto->uuid
+    };
     return compose_sample_action(ctx, dpif_sflow_get_probability(sflow),
                                  &cookie, ODPP_NONE, true);
 }
@@ -2969,7 +2973,9 @@  compose_ipfix_action(struct xlate_ctx *ctx, odp_port_t output_odp_port)
 
     struct user_action_cookie cookie = {
         .type = USER_ACTION_COOKIE_IPFIX,
-        .ipfix.output_odp_port = output_odp_port,
+        .ofp_in_port = ctx->xin->flow.in_port.ofp_port,
+        .ofproto_uuid = ctx->xbridge->ofproto->uuid,
+        .ipfix.output_odp_port = output_odp_port
     };
     compose_sample_action(ctx,
                           dpif_ipfix_get_bridge_exporter_probability(ipfix),
@@ -2990,7 +2996,6 @@  fix_sflow_action(struct xlate_ctx *ctx, unsigned int user_cookie_offset)
     cookie = ofpbuf_at(ctx->odp_actions, user_cookie_offset, sizeof *cookie);
     ovs_assert(cookie->type == USER_ACTION_COOKIE_SFLOW);
 
-    cookie->type = USER_ACTION_COOKIE_SFLOW;
     cookie->sflow.vlan_tci = base->vlans[0].tci;
 
     /* See http://www.sflow.org/sflow_version_5.txt (search for "Input/output
@@ -5270,6 +5275,8 @@  xlate_sample_action(struct xlate_ctx *ctx,
 
     struct user_action_cookie cookie = {
         .type = USER_ACTION_COOKIE_FLOW_SAMPLE,
+        .ofp_in_port = ctx->xin->flow.in_port.ofp_port,
+        .ofproto_uuid = ctx->xbridge->ofproto->uuid,
         .flow_sample = {
             .probability = os->probability,
             .collector_set_id = os->collector_set_id,