[ovs-dev] [bug 7550 5/9] odp-util: Change user_action_cookie from struct to union.

Ben Pfaff blp at nicira.com
Wed Dec 21 21:03:53 UTC 2011


This will make it easier to use a convenient set of members for each
possible format, instead of being stuck with a single layout.

An upcoming commit will add a new member to the 'controller' case.

Signed-off-by: Ben Pfaff <blp at nicira.com>
---
 lib/odp-util.c               |   35 +++++++++++++++++++----------------
 lib/odp-util.h               |   25 ++++++++++++++++---------
 ofproto/ofproto-dpif-sflow.c |   16 +++++++++-------
 ofproto/ofproto-dpif-sflow.h |    4 ++--
 ofproto/ofproto-dpif.c       |   42 +++++++++++++++++++++---------------------
 5 files changed, 67 insertions(+), 55 deletions(-)

diff --git a/lib/odp-util.c b/lib/odp-util.c
index ee1c378..6fafe79 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -185,17 +185,20 @@ format_odp_userspace_action(struct ds *ds, const struct nlattr *attr)
 
     if (a[OVS_USERSPACE_ATTR_USERDATA]) {
         uint64_t userdata = nl_attr_get_u64(a[OVS_USERSPACE_ATTR_USERDATA]);
-        struct user_action_cookie cookie;
+        union user_action_cookie cookie;
 
         memcpy(&cookie, &userdata, sizeof cookie);
 
         if (cookie.type == USER_ACTION_COOKIE_CONTROLLER) {
-            ds_put_format(ds, ",controller,length=%"PRIu32, cookie.data);
+            ds_put_format(ds, ",controller,length=%"PRIu16,
+                          cookie.controller.max_len);
         } else if (cookie.type == USER_ACTION_COOKIE_SFLOW) {
             ds_put_format(ds, ",sFlow,n_output=%"PRIu8","
                           "vid=%"PRIu16",pcp=%"PRIu8",ifindex=%"PRIu32,
-                          cookie.n_output, vlan_tci_to_vid(cookie.vlan_tci),
-                          vlan_tci_to_pcp(cookie.vlan_tci), cookie.data);
+                          cookie.sflow.n_output,
+                          vlan_tci_to_vid(cookie.sflow.vlan_tci),
+                          vlan_tci_to_pcp(cookie.sflow.vlan_tci),
+                          cookie.sflow.ifindex);
         } else {
             ds_put_format(ds, ",userdata=0x%"PRIx64, userdata);
         }
@@ -340,18 +343,17 @@ parse_odp_action(const char *s, const struct shash *port_names,
             return n;
         } else if (sscanf(s, "userspace(pid=%lli,controller,length=%lli)%n",
                           &pid, &length, &n) > 0 && n > 0) {
-            struct user_action_cookie cookie;
+            union user_action_cookie cookie;
 
-            cookie.type = USER_ACTION_COOKIE_CONTROLLER;
-            cookie.n_output = 0;
-            cookie.vlan_tci = htons(0);
-            cookie.data = length;
+            memset(&cookie, 0, sizeof cookie);
+            cookie.controller.type = USER_ACTION_COOKIE_CONTROLLER;
+            cookie.controller.max_len = length;
             odp_put_userspace_action(pid, &cookie, actions);
             return n;
         } else if (sscanf(s, "userspace(pid=%lli,sFlow,n_output=%i,vid=%i,"
                           "pcp=%i,ifindex=%lli)%n", &pid, &n_output,
                           &vid, &pcp, &ifindex, &n) > 0 && n > 0) {
-            struct user_action_cookie cookie;
+            union user_action_cookie cookie;
             uint16_t tci;
 
             tci = vid | (pcp << VLAN_PCP_SHIFT);
@@ -359,16 +361,17 @@ parse_odp_action(const char *s, const struct shash *port_names,
                 tci |= VLAN_CFI;
             }
 
-            cookie.type = USER_ACTION_COOKIE_SFLOW;
-            cookie.n_output = n_output;
-            cookie.vlan_tci = htons(tci);
-            cookie.data = ifindex;
+            memset(&cookie, 0, sizeof cookie);
+            cookie.sflow.type = USER_ACTION_COOKIE_SFLOW;
+            cookie.sflow.n_output = n_output;
+            cookie.sflow.vlan_tci = htons(tci);
+            cookie.sflow.ifindex = ifindex;
             odp_put_userspace_action(pid, &cookie, actions);
             return n;
         } else if (sscanf(s, "userspace(pid=%lli,userdata="
                           "%31[x0123456789abcdefABCDEF])%n", &pid, userdata_s,
                           &n) > 0 && n > 0) {
-            struct user_action_cookie cookie;
+            union user_action_cookie cookie;
             uint64_t userdata;
 
             userdata = strtoull(userdata_s, NULL, 0);
@@ -1706,7 +1709,7 @@ odp_flow_key_to_flow(const struct nlattr *key, size_t key_len,
  * the start of the cookie.  (If 'cookie' is null, then the return value is not
  * meaningful.) */
 size_t
-odp_put_userspace_action(uint32_t pid, const struct user_action_cookie *cookie,
+odp_put_userspace_action(uint32_t pid, const union user_action_cookie *cookie,
                          struct ofpbuf *odp_actions)
 {
     size_t offset;
diff --git a/lib/odp-util.h b/lib/odp-util.h
index 7c9b588..245e292 100644
--- a/lib/odp-util.h
+++ b/lib/odp-util.h
@@ -123,18 +123,25 @@ enum user_action_cookie_type {
 
 /* user_action_cookie is passed as argument to OVS_ACTION_ATTR_USERSPACE.
  * Since is it passed to kernel as u64, its size has to be 8 bytes. */
-struct user_action_cookie {
-    uint8_t   type;                 /* enum user_action_cookie_type. */
-    uint8_t   n_output;             /* No of output ports. used by sflow. */
-    ovs_be16  vlan_tci;             /* Used by sFlow */
-    uint32_t  data;                 /* Data is len for OFPP_CONTROLLER action.
-                                       For sFlow it is port_ifindex. */
+union user_action_cookie {
+    uint8_t   type;             /* enum user_action_cookie_type. */
+
+    struct {
+        uint8_t type;           /* USER_ACTION_COOKIE_SFLOW. */
+        uint8_t n_output;       /* Number of output ports. */
+        ovs_be16 vlan_tci;      /* VLAN TCI value. */
+        uint32_t ifindex;       /* sFlow notion for output port. */
+    } sflow;
+
+    struct {
+        uint8_t type;           /* USER_ACTION_COOKIE_CONTROLLER. */
+        uint16_t max_len;       /* Maximum number of bytes to send. */
+    } controller;
 };
-
-BUILD_ASSERT_DECL(sizeof(struct user_action_cookie) == 8);
+BUILD_ASSERT_DECL(sizeof(union user_action_cookie) == 8);
 
 size_t odp_put_userspace_action(uint32_t pid,
-                                const struct user_action_cookie *,
+                                const union user_action_cookie *,
                                 struct ofpbuf *odp_actions);
 
 void commit_odp_actions(const struct flow *, struct flow *base,
diff --git a/ofproto/ofproto-dpif-sflow.c b/ofproto/ofproto-dpif-sflow.c
index 5825636..d777591 100644
--- a/ofproto/ofproto-dpif-sflow.c
+++ b/ofproto/ofproto-dpif-sflow.c
@@ -491,7 +491,7 @@ dpif_sflow_odp_port_to_ifindex(const struct dpif_sflow *ds,
 void
 dpif_sflow_received(struct dpif_sflow *ds, struct ofpbuf *packet,
                     const struct flow *flow,
-                    const struct user_action_cookie *cookie)
+                    const union user_action_cookie *cookie)
 {
     SFL_FLOW_SAMPLE_TYPE fs;
     SFLFlow_sample_element hdrElem;
@@ -500,6 +500,7 @@ dpif_sflow_received(struct dpif_sflow *ds, struct ofpbuf *packet,
     SFLSampler *sampler;
     struct dpif_sflow_port *in_dsp;
     struct netdev_stats stats;
+    ovs_be16 vlan_tci;
     int error;
 
     /* Build a flow sample */
@@ -549,20 +550,21 @@ dpif_sflow_received(struct dpif_sflow *ds, struct ofpbuf *packet,
     switchElem.flowType.sw.src_priority = vlan_tci_to_pcp(flow->vlan_tci);
 
     /* Retrieve data from user_action_cookie. */
-    switchElem.flowType.sw.dst_vlan = vlan_tci_to_vid(cookie->vlan_tci);
-    switchElem.flowType.sw.dst_priority = vlan_tci_to_pcp(cookie->vlan_tci);
+    vlan_tci = cookie->sflow.vlan_tci;
+    switchElem.flowType.sw.dst_vlan = vlan_tci_to_vid(vlan_tci);
+    switchElem.flowType.sw.dst_priority = vlan_tci_to_pcp(vlan_tci);
 
     /* Set output port, as defined by http://www.sflow.org/sflow_version_5.txt
        (search for "Input/output port information"). */
-    if (!cookie->n_output) {
+    if (!cookie->sflow.n_output) {
         /* This value indicates that the packet was dropped for an unknown
          * reason. */
         fs.output = 0x40000000 | 256;
-    } else if (cookie->n_output > 1 || !cookie->data) {
+    } else if (cookie->sflow.n_output > 1 || !cookie->sflow.ifindex) {
         /* Setting the high bit means "multiple output ports". */
-        fs.output = 0x80000000 | cookie->n_output;
+        fs.output = 0x80000000 | cookie->sflow.n_output;
     } else {
-        fs.output = cookie->data;
+        fs.output = cookie->sflow.ifindex;
     }
 
     /* Submit the flow sample to be encoded into the next datagram. */
diff --git a/ofproto/ofproto-dpif-sflow.h b/ofproto/ofproto-dpif-sflow.h
index 0b6c1b4..9726310 100644
--- a/ofproto/ofproto-dpif-sflow.h
+++ b/ofproto/ofproto-dpif-sflow.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2009, 2010 InMon Corp.
- * Copyright (c) 2009 Nicira Networks.
+ * Copyright (c) 2009, 2011 Nicira Networks.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -46,7 +46,7 @@ void dpif_sflow_wait(struct dpif_sflow *);
 void dpif_sflow_received(struct dpif_sflow *,
                          struct ofpbuf *,
                          const struct flow *,
-                         const struct user_action_cookie *);
+                         const union user_action_cookie *);
 
 int dpif_sflow_odp_port_to_ifindex(const struct dpif_sflow *, uint16_t);
 
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 2840123..2bd76a6 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -2397,7 +2397,7 @@ send_packet_in_action(struct ofproto_dpif *ofproto, struct ofpbuf *packet,
                       uint64_t userdata, const struct flow *flow, bool clone)
 {
     struct ofputil_packet_in pin;
-    struct user_action_cookie cookie;
+    union user_action_cookie cookie;
 
     memcpy(&cookie, &userdata, sizeof(cookie));
 
@@ -2405,7 +2405,7 @@ send_packet_in_action(struct ofproto_dpif *ofproto, struct ofpbuf *packet,
     pin.in_port = flow->in_port;
     pin.reason = OFPR_ACTION;
     pin.buffer_id = 0;          /* not yet known */
-    pin.send_len = cookie.data;
+    pin.send_len = cookie.controller.max_len;
     connmgr_send_packet_in(ofproto->up.connmgr, &pin, flow,
                            clone ? NULL : packet);
 }
@@ -2706,7 +2706,7 @@ static void
 handle_userspace_upcall(struct ofproto_dpif *ofproto,
                         struct dpif_upcall *upcall)
 {
-    struct user_action_cookie cookie;
+    union user_action_cookie cookie;
     enum odp_key_fitness fitness;
     ovs_be16 initial_tci;
     struct flow flow;
@@ -4006,7 +4006,7 @@ static size_t
 put_userspace_action(const struct ofproto_dpif *ofproto,
                      struct ofpbuf *odp_actions,
                      const struct flow *flow,
-                     const struct user_action_cookie *cookie)
+                     const union user_action_cookie *cookie)
 {
     uint32_t pid;
 
@@ -4025,7 +4025,7 @@ compose_sflow_action(const struct ofproto_dpif *ofproto,
 {
     uint32_t port_ifindex;
     uint32_t probability;
-    struct user_action_cookie cookie;
+    union user_action_cookie cookie;
     size_t sample_offset, actions_offset;
     int cookie_offset, n_output;
 
@@ -4049,10 +4049,10 @@ compose_sflow_action(const struct ofproto_dpif *ofproto,
 
     actions_offset = nl_msg_start_nested(odp_actions, OVS_SAMPLE_ATTR_ACTIONS);
 
-    cookie.type = USER_ACTION_COOKIE_SFLOW;
-    cookie.data = port_ifindex;
-    cookie.n_output = n_output;
-    cookie.vlan_tci = 0;
+    cookie.sflow.type = USER_ACTION_COOKIE_SFLOW;
+    cookie.sflow.ifindex = port_ifindex;
+    cookie.sflow.n_output = n_output;
+    cookie.sflow.vlan_tci = htons(0);
     cookie_offset = put_userspace_action(ofproto, odp_actions, flow, &cookie);
 
     nl_msg_end_nested(odp_actions, actions_offset);
@@ -4080,27 +4080,27 @@ static void
 fix_sflow_action(struct action_xlate_ctx *ctx)
 {
     const struct flow *base = &ctx->base_flow;
-    struct user_action_cookie *cookie;
+    union user_action_cookie *cookie;
 
     if (!ctx->user_cookie_offset) {
         return;
     }
 
     cookie = ofpbuf_at(ctx->odp_actions, ctx->user_cookie_offset,
-                     sizeof(*cookie));
+                       sizeof *cookie);
     assert(cookie != NULL);
     assert(cookie->type == USER_ACTION_COOKIE_SFLOW);
 
     if (ctx->sflow_n_outputs) {
-        cookie->data = dpif_sflow_odp_port_to_ifindex(ctx->ofproto->sflow,
-                                                    ctx->sflow_odp_port);
+        cookie->sflow.ifindex = dpif_sflow_odp_port_to_ifindex(
+            ctx->ofproto->sflow, ctx->sflow_odp_port);
     }
     if (ctx->sflow_n_outputs >= 255) {
-        cookie->n_output = 255;
+        cookie->sflow.n_output = 255;
     } else {
-        cookie->n_output = ctx->sflow_n_outputs;
+        cookie->sflow.n_output = ctx->sflow_n_outputs;
     }
-    cookie->vlan_tci = base->vlan_tci;
+    cookie->sflow.vlan_tci = base->vlan_tci;
 }
 
 static void
@@ -4246,13 +4246,13 @@ flood_packets(struct action_xlate_ctx *ctx, bool all)
 static void
 compose_controller_action(struct action_xlate_ctx *ctx, int len)
 {
-    struct user_action_cookie cookie;
+    union user_action_cookie cookie;
 
     commit_odp_actions(&ctx->flow, &ctx->base_flow, ctx->odp_actions);
-    cookie.type = USER_ACTION_COOKIE_CONTROLLER;
-    cookie.data = len;
-    cookie.n_output = 0;
-    cookie.vlan_tci = 0;
+
+    memset(&cookie, 0, sizeof cookie);
+    cookie.controller.type = USER_ACTION_COOKIE_CONTROLLER;
+    cookie.controller.max_len = len;
     put_userspace_action(ctx->ofproto, ctx->odp_actions, &ctx->flow, &cookie);
 }
 
-- 
1.7.2.5




More information about the dev mailing list