This helps reduce confusion about when a flow is a flow
and when it is just metadata.

Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com>
---
 lib/dpif-linux.c              |    9 ++++--
 lib/dpif-netdev.c             |   59 ++++++++++++++--------------------
 lib/dpif-provider.h           |    8 ++---
 lib/dpif.c                    |   57 +++++++--------------------------
 lib/dpif.h                    |   23 +++++++++----
 lib/odp-execute.c             |    7 ++--
 lib/odp-execute.h             |    6 ++--
 lib/odp-util.c                |   71 ++++++++++++++++++++++++++++++++++++++++-
 lib/odp-util.h                |    6 ++++
 ofproto/ofproto-dpif-upcall.c |    5 +--
 ofproto/ofproto-dpif-xlate.c  |    8 ++---
 ofproto/ofproto-dpif.c        |   13 ++++----
 12 files changed, 158 insertions(+), 114 deletions(-)

diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c
index bfea02d..d61226b 100644
--- a/lib/dpif-linux.c
+++ b/lib/dpif-linux.c
@@ -1051,10 +1051,11 @@ dpif_linux_encode_execute(int dp_ifindex, const struct 
dpif_execute *d_exec,
                           struct ofpbuf *buf)
 {
     struct ovs_header *k_exec;
+    size_t key_ofs;
 
     ofpbuf_prealloc_tailroom(buf, (64
                                    + d_exec->packet->size
-                                   + d_exec->key_len
+                                   + ODP_KEY_METADATA_SIZE
                                    + d_exec->actions_len));
 
     nl_msg_put_genlmsghdr(buf, 0, ovs_packet_family, NLM_F_REQUEST,
@@ -1065,7 +1066,11 @@ dpif_linux_encode_execute(int dp_ifindex, const struct 
dpif_execute *d_exec,
 
     nl_msg_put_unspec(buf, OVS_PACKET_ATTR_PACKET,
                       d_exec->packet->data, d_exec->packet->size);
-    nl_msg_put_unspec(buf, OVS_PACKET_ATTR_KEY, d_exec->key, d_exec->key_len);
+
+    key_ofs = nl_msg_start_nested(buf, OVS_PACKET_ATTR_KEY);
+    odp_key_from_dpif_metadata(buf, d_exec->md);
+    nl_msg_end_nested(buf, key_ofs);
+
     nl_msg_put_unspec(buf, OVS_PACKET_ATTR_ACTIONS,
                       d_exec->actions, d_exec->actions_len);
 }
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 9c79ad1..ac81461 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -160,13 +160,11 @@ static int dp_netdev_output_userspace(struct dp_netdev *, 
const struct ofpbuf *,
                                     int queue_no, const struct flow *,
                                     const struct nlattr *userdata);
 static void dp_netdev_execute_actions(struct dp_netdev *, const struct flow *,
-                                      struct ofpbuf *,
+                                      struct ofpbuf *, struct dpif_metadata *,
                                       const struct nlattr *actions,
                                       size_t actions_len);
-static void dp_netdev_port_input(struct dp_netdev *dp,
-                                 struct dp_netdev_port *port,
-                                 struct ofpbuf *packet, uint32_t skb_priority,
-                                 uint32_t pkt_mark, const struct flow_tnl 
*tnl);
+static void dp_netdev_port_input(struct dp_netdev *dp, struct ofpbuf *packet,
+                                 struct dpif_metadata *md);
 
 static struct dpif_netdev *
 dpif_netdev_cast(const struct dpif *dpif)
@@ -1030,28 +1028,22 @@ static int
 dpif_netdev_execute(struct dpif *dpif, struct dpif_execute *execute)
 {
     struct dp_netdev *dp = get_dp_netdev(dpif);
-    struct flow md;
-    int error;
+    struct dpif_metadata *md = execute->md;
+    struct flow key;
 
     if (execute->packet->size < ETH_HEADER_LEN ||
         execute->packet->size > UINT16_MAX) {
         return EINVAL;
     }
 
-    /* Get packet metadata. */
-    error = dpif_netdev_flow_from_nlattrs(execute->key, execute->key_len, &md);
-    if (!error) {
-        struct flow key;
-
-        /* Extract flow key. */
-        flow_extract(execute->packet, md.skb_priority, md.pkt_mark, &md.tunnel,
-                     &md.in_port, &key);
-        ovs_mutex_lock(&dp_netdev_mutex);
-        dp_netdev_execute_actions(dp, &key, execute->packet,
-                                  execute->actions, execute->actions_len);
-        ovs_mutex_unlock(&dp_netdev_mutex);
-    }
-    return error;
+    /* Extract flow key. */
+    flow_extract(execute->packet, md->skb_priority, md->pkt_mark, &md->tunnel,
+                 (union flow_in_port *)&md->in_port, &key);
+    ovs_mutex_lock(&dp_netdev_mutex);
+    dp_netdev_execute_actions(dp, &key, execute->packet, md, execute->actions,
+                              execute->actions_len);
+    ovs_mutex_unlock(&dp_netdev_mutex);
+    return 0;
 }
 
 static int
@@ -1146,23 +1138,21 @@ dp_netdev_flow_used(struct dp_netdev_flow *netdev_flow,
 }
 
 static void
-dp_netdev_port_input(struct dp_netdev *dp, struct dp_netdev_port *port,
-                     struct ofpbuf *packet, uint32_t skb_priority,
-                     uint32_t pkt_mark, const struct flow_tnl *tnl)
+dp_netdev_port_input(struct dp_netdev *dp, struct ofpbuf *packet,
+                     struct dpif_metadata *md)
 {
     struct dp_netdev_flow *netdev_flow;
     struct flow key;
-    union flow_in_port in_port_;
 
     if (packet->size < ETH_HEADER_LEN) {
         return;
     }
-    in_port_.odp_port = port->port_no;
-    flow_extract(packet, skb_priority, pkt_mark, tnl, &in_port_, &key);
+    flow_extract(packet, md->skb_priority, md->pkt_mark, &md->tunnel,
+                 (union flow_in_port *)&md->in_port, &key);
     netdev_flow = dp_netdev_lookup_flow(dp, &key);
     if (netdev_flow) {
         dp_netdev_flow_used(netdev_flow, packet);
-        dp_netdev_execute_actions(dp, &key, packet,
+        dp_netdev_execute_actions(dp, &key, packet, md,
                                   netdev_flow->actions,
                                   netdev_flow->actions_len);
         dp->n_hit++;
@@ -1193,7 +1183,8 @@ dpif_netdev_run(struct dpif *dpif)
 
         error = port->rx ? netdev_rx_recv(port->rx, &packet) : EOPNOTSUPP;
         if (!error) {
-            dp_netdev_port_input(dp, port, &packet, 0, 0, NULL);
+            struct dpif_metadata md = DPIF_METADATA_INITIALIZER(port->port_no);
+            dp_netdev_port_input(dp, &packet, &md);
         } else if (error != EAGAIN && error != EOPNOTSUPP) {
             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
 
@@ -1299,8 +1290,8 @@ struct dp_netdev_execute_aux {
 };
 
 static void
-dp_execute_cb(void *aux_, struct ofpbuf *packet, struct flow *flow OVS_UNUSED,
-              const struct nlattr *a)
+dp_execute_cb(void *aux_, struct ofpbuf *packet,
+              struct dpif_metadata *md OVS_UNUSED, const struct nlattr *a)
 {
     struct dp_netdev_execute_aux *aux = aux_;
     int type = nl_attr_type(a);
@@ -1332,14 +1323,12 @@ dp_execute_cb(void *aux_, struct ofpbuf *packet, struct 
flow *flow OVS_UNUSED,
 
 static void
 dp_netdev_execute_actions(struct dp_netdev *dp, const struct flow *key,
-                          struct ofpbuf *packet,
+                          struct ofpbuf *packet, struct dpif_metadata *md,
                           const struct nlattr *actions, size_t actions_len)
 {
     struct dp_netdev_execute_aux aux = {dp, key};
-    struct flow md = *key;   /* Packet metadata, may be modified by actions. */
 
-    odp_execute_actions(&aux, packet, &md, actions, actions_len,
-                        dp_execute_cb);
+    odp_execute_actions(&aux, packet, md, actions, actions_len, dp_execute_cb);
 }
 
 const struct dpif_class dpif_netdev_class = {
diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h
index c5f8b04..0c6d8bd 100644
--- a/lib/dpif-provider.h
+++ b/lib/dpif-provider.h
@@ -311,11 +311,9 @@ struct dpif_class {
     int (*flow_dump_done)(const struct dpif *dpif, void *state);
 
     /* Performs the 'execute->actions_len' bytes of actions in
-     * 'execute->actions' on the Ethernet frame specified in 'execute->packet'
-     * taken from the flow specified in the 'execute->key_len' bytes of
-     * 'execute->key'.  ('execute->key' is mostly redundant with
-     * 'execute->packet', but it contains some metadata that cannot be
-     * recovered from 'execute->packet', such as tunnel and in_port.) */
+     * 'execute->actions' on the Ethernet frame in 'execute->packet'
+     * and on the packet metadata in 'execute->md'.
+     * May modify both packet and metadata. */
     int (*execute)(struct dpif *dpif, struct dpif_execute *execute);
 
     /* Executes each of the 'n_ops' operations in 'ops' on 'dpif', in the order
diff --git a/lib/dpif.c b/lib/dpif.c
index 6cfa4e6..21fc3e3 100644
--- a/lib/dpif.c
+++ b/lib/dpif.c
@@ -1061,43 +1061,20 @@ struct dpif_execute_helper_aux {
 };
 
 static void
-dpif_execute_helper_execute__(void *aux_, struct ofpbuf *packet,
-                              const struct flow *flow,
-                              const struct nlattr *actions, size_t actions_len)
+dpif_execute_helper_cb(void *aux_, struct ofpbuf *packet,
+                       struct dpif_metadata *md, const struct nlattr *action)
 {
     struct dpif_execute_helper_aux *aux = aux_;
-    struct dpif_execute execute;
-    struct odputil_keybuf key_stub;
-    struct ofpbuf key;
-    int error;
-
-    ofpbuf_use_stub(&key, &key_stub, sizeof key_stub);
-    odp_flow_key_from_flow(&key, flow, flow->in_port.odp_port);
-
-    execute.key = key.data;
-    execute.key_len = key.size;
-    execute.actions = actions;
-    execute.actions_len = actions_len;
-    execute.packet = packet;
-    execute.needs_help = false;
-
-    error = aux->dpif->dpif_class->execute(aux->dpif, &execute);
-    if (error) {
-        aux->error = error;
-    }
-}
 
-static void
-dpif_execute_helper_cb(void *aux, struct ofpbuf *packet, struct flow *flow,
-                       const struct nlattr *action)
-{
     int type = nl_attr_type(action);
     switch ((enum ovs_action_attr)type) {
     case OVS_ACTION_ATTR_OUTPUT:
     case OVS_ACTION_ATTR_USERSPACE:
-        dpif_execute_helper_execute__(aux, packet, flow,
-                                      action, NLA_ALIGN(action->nla_len));
+        aux->error = dpif_execute(aux->dpif,
+                                  action, NLA_ALIGN(action->nla_len),
+                                  packet, md, false);
         break;
+
     case OVS_ACTION_ATTR_PUSH_VLAN:
     case OVS_ACTION_ATTR_POP_VLAN:
     case OVS_ACTION_ATTR_PUSH_MPLS:
@@ -1119,22 +1096,15 @@ static int
 dpif_execute_with_help(struct dpif *dpif, struct dpif_execute *execute)
 {
     struct dpif_execute_helper_aux aux;
-    enum odp_key_fitness fit;
     struct ofpbuf *packet;
-    struct flow flow;
 
     COVERAGE_INC(dpif_execute_with_help);
 
-    fit = odp_flow_key_to_flow(execute->key, execute->key_len, &flow);
-    if (fit == ODP_FIT_ERROR) {
-        return EINVAL;
-    }
-
     aux.dpif = dpif;
     aux.error = 0;
 
     packet = ofpbuf_clone_with_headroom(execute->packet, VLAN_HEADER_LEN);
-    odp_execute_actions(&aux, packet, &flow,
+    odp_execute_actions(&aux, packet, execute->md,
                         execute->actions, execute->actions_len,
                         dpif_execute_helper_cb);
     ofpbuf_delete(packet);
@@ -1162,10 +1132,8 @@ dpif_execute__(struct dpif *dpif, struct dpif_execute 
*execute)
 }
 
 /* Causes 'dpif' to perform the 'actions_len' bytes of actions in 'actions' on
- * the Ethernet frame specified in 'packet' taken from the flow specified in
- * the 'key_len' bytes of 'key'.  ('key' is mostly redundant with 'packet', but
- * it contains some metadata that cannot be recovered from 'packet', such as
- * tunnel and in_port.)
+ * the Ethernet frame in 'packet' and on packet metadata in 'md'.  The
+ * implementation is allowed to modify both the '*packet' and '*md'.
  *
  * Some dpif providers do not implement every action.  The Linux kernel
  * datapath, in particular, does not implement ARP field modification.  If
@@ -1179,17 +1147,16 @@ dpif_execute__(struct dpif *dpif, struct dpif_execute 
*execute)
  * Returns 0 if successful, otherwise a positive errno value. */
 int
 dpif_execute(struct dpif *dpif,
-             const struct nlattr *key, size_t key_len,
              const struct nlattr *actions, size_t actions_len,
-             struct ofpbuf *buf, bool needs_help)
+             struct ofpbuf *buf, struct dpif_metadata *md,
+             bool needs_help)
 {
     struct dpif_execute execute;
 
-    execute.key = key;
-    execute.key_len = key_len;
     execute.actions = actions;
     execute.actions_len = actions_len;
     execute.packet = buf;
+    execute.md = md;
     execute.needs_help = needs_help || nl_attr_oversized(actions_len);
     return dpif_execute__(dpif, &execute);
 }
diff --git a/lib/dpif.h b/lib/dpif.h
index 3bf3688..2086ec5 100644
--- a/lib/dpif.h
+++ b/lib/dpif.h
@@ -342,6 +342,7 @@
 #include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
+#include "flow.h"
 #include "openflow/openflow.h"
 #include "netdev.h"
 #include "util.h"
@@ -352,7 +353,6 @@ extern "C" {
 
 struct dpif;
 struct ds;
-struct flow;
 struct nlattr;
 struct ofpbuf;
 struct sset;
@@ -492,10 +492,19 @@ int dpif_flow_dump_done(struct dpif_flow_dump *);
 
 /* Packet operations. */
 
+/* Datapath packet metadata */
+struct dpif_metadata {
+    struct flow_tnl tunnel;     /* Encapsulating tunnel parameters. */
+    uint32_t skb_priority;      /* Packet priority for QoS. */
+    uint32_t pkt_mark;          /* Packet mark. */
+    odp_port_t in_port;         /* Input port. */
+};
+
+#define DPIF_METADATA_INITIALIZER(PORT) { { 0 }, 0, 0, (PORT) }
+
 int dpif_execute(struct dpif *,
-                 const struct nlattr *key, size_t key_len,
                  const struct nlattr *actions, size_t actions_len,
-                 struct ofpbuf *, bool needs_help);
+                 struct ofpbuf *, struct dpif_metadata *, bool needs_help);
 
 /* Operation batching interface.
  *
@@ -534,11 +543,10 @@ struct dpif_flow_del {
 
 struct dpif_execute {
     /* Raw support for execute passed along to the provider. */
-    const struct nlattr *key;       /* Partial flow key (only for metadata). */
-    size_t key_len;                 /* Length of 'key' in bytes. */
     const struct nlattr *actions;   /* Actions to execute on packet. */
     size_t actions_len;             /* Length of 'actions' in bytes. */
     struct ofpbuf *packet;          /* Packet to execute. */
+    struct dpif_metadata *md;       /* Packet metadata. */
 
     /* Some dpif providers do not implement every action.  The Linux kernel
      * datapath, in particular, does not implement ARP field modification.
@@ -556,7 +564,10 @@ struct dpif_op {
     union {
         struct dpif_flow_put flow_put;
         struct dpif_flow_del flow_del;
-        struct dpif_execute execute;
+        struct {
+            struct dpif_execute execute;
+            struct dpif_metadata metadata;
+        };
     } u;
 };
 
diff --git a/lib/odp-execute.c b/lib/odp-execute.c
index 8b29ddc..12f17d4 100644
--- a/lib/odp-execute.c
+++ b/lib/odp-execute.c
@@ -21,6 +21,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "dpif.h"
 #include "netlink.h"
 #include "ofpbuf.h"
 #include "odp-util.h"
@@ -61,7 +62,7 @@ set_arp(struct ofpbuf *packet, const struct ovs_key_arp 
*arp_key)
 
 static void
 odp_execute_set_action(struct ofpbuf *packet, const struct nlattr *a,
-                       struct flow *md)
+                       struct dpif_metadata *md)
 {
     enum ovs_key_attr type = nl_attr_type(a);
     const struct ovs_key_ipv4 *ipv4_key;
@@ -140,7 +141,7 @@ odp_execute_set_action(struct ofpbuf *packet, const struct 
nlattr *a,
 }
 
 static void
-odp_execute_sample(void *dp, struct ofpbuf *packet, struct flow *md,
+odp_execute_sample(void *dp, struct ofpbuf *packet, struct dpif_metadata *md,
                    const struct nlattr *action, odp_execute_callback callback)
 {
     const struct nlattr *subactions = NULL;
@@ -173,7 +174,7 @@ odp_execute_sample(void *dp, struct ofpbuf *packet, struct 
flow *md,
 }
 
 void
-odp_execute_actions(void *dp, struct ofpbuf *packet, struct flow *md,
+odp_execute_actions(void *dp, struct ofpbuf *packet, struct dpif_metadata *md,
                     const struct nlattr *actions, size_t actions_len,
                     odp_execute_callback callback)
 {
diff --git a/lib/odp-execute.h b/lib/odp-execute.h
index 6f2376b..5ddc3d4 100644
--- a/lib/odp-execute.h
+++ b/lib/odp-execute.h
@@ -22,16 +22,16 @@
 #include <stdint.h>
 #include "openvswitch/types.h"
 
-struct flow;
 struct nlattr;
 struct ofpbuf;
+struct dpif_metadata;
 
 typedef void (*odp_execute_callback)(void *dp, struct ofpbuf *packet,
-                                     struct flow *metadata,
+                                     struct dpif_metadata *,
                                      const struct nlattr *action);
 
 void
-odp_execute_actions(void *dp, struct ofpbuf *packet, struct flow *metadata,
+odp_execute_actions(void *dp, struct ofpbuf *packet, struct dpif_metadata *,
                     const struct nlattr *actions, size_t actions_len,
                     odp_execute_callback callback);
 #endif
diff --git a/lib/odp-util.c b/lib/odp-util.c
index 6ac3853..238c5e1 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -26,6 +26,7 @@
 #include <string.h>
 #include "byte-order.h"
 #include "coverage.h"
+#include "dpif.h"
 #include "dynamic-string.h"
 #include "flow.h"
 #include "netlink.h"
@@ -856,7 +857,7 @@ odp_tun_key_from_attr(const struct nlattr *attr, struct 
flow_tnl *tun)
         return ODP_FIT_ERROR;
     }
     if (unknown) {
-            return ODP_FIT_TOO_MUCH;
+        return ODP_FIT_TOO_MUCH;
     }
     return ODP_FIT_PERFECT;
 }
@@ -2676,6 +2677,74 @@ odp_flow_key_from_mask(struct ofpbuf *buf, const struct 
flow *mask,
     odp_flow_key_from_flow__(buf, mask, flow, u32_to_odp(odp_in_port_mask));
 }
 
+/* Generate ODP flow key from the given 'metadata' */
+void
+odp_key_from_dpif_metadata(struct ofpbuf *buf, const struct dpif_metadata *md)
+{
+    nl_msg_put_u32(buf, OVS_KEY_ATTR_PRIORITY, md->skb_priority);
+
+    if (md->tunnel.ip_dst) {
+        tun_key_to_attr(buf, &md->tunnel);
+    }
+
+    nl_msg_put_u32(buf, OVS_KEY_ATTR_SKB_MARK, md->pkt_mark);
+
+    /* Add an ingress port attribute if 'odp_in_port' is not the magical
+     * value "ODPP_NONE". */
+    if (md->in_port != ODPP_NONE) {
+        nl_msg_put_odp_port(buf, OVS_KEY_ATTR_IN_PORT, md->in_port);
+    }
+}
+
+/* Generate ODP packet metadata from the given ODP flow key. */
+void
+odp_key_to_dpif_metadata(const struct nlattr *key, size_t key_len,
+                         struct dpif_metadata *md)
+{
+    const struct nlattr *nla;
+    size_t left;
+    uint32_t wanted_attrs = 1u << OVS_KEY_ATTR_PRIORITY |
+        1u << OVS_KEY_ATTR_SKB_MARK | 1u << OVS_KEY_ATTR_TUNNEL |
+        1u << OVS_KEY_ATTR_IN_PORT;
+
+    memset(md, 0, sizeof *md);
+    md->in_port = ODPP_NONE;
+
+    NL_ATTR_FOR_EACH (nla, left, key, key_len) {
+        uint16_t type = nl_attr_type(nla);
+        size_t len = nl_attr_get_size(nla);
+        int expected_len = odp_flow_key_attr_len(type);
+
+        if (len != expected_len && expected_len >= 0) {
+            continue;
+        }
+
+        if (type == OVS_KEY_ATTR_PRIORITY) {
+            md->skb_priority = nl_attr_get_u32(nla);
+            wanted_attrs &= ~(1u << OVS_KEY_ATTR_PRIORITY);
+        } else if (type == OVS_KEY_ATTR_SKB_MARK) {
+            md->pkt_mark = nl_attr_get_u32(nla);
+            wanted_attrs &= ~(1u << OVS_KEY_ATTR_SKB_MARK);
+        } else if (type == OVS_KEY_ATTR_TUNNEL) {
+            enum odp_key_fitness res;
+
+            res = odp_tun_key_from_attr(nla, &md->tunnel);
+            if (res == ODP_FIT_ERROR) {
+                memset(&md->tunnel, 0, sizeof md->tunnel);
+            } else if (res == ODP_FIT_PERFECT) {
+                wanted_attrs &= ~(1u << OVS_KEY_ATTR_TUNNEL);
+            }
+        } else if (type == OVS_KEY_ATTR_IN_PORT) {
+            md->in_port = nl_attr_get_odp_port(nla);
+            wanted_attrs &= ~(1u << OVS_KEY_ATTR_IN_PORT);
+        }
+
+        if (!wanted_attrs) {
+            return; /* Have everything. */
+        }
+    }
+}
+
 uint32_t
 odp_flow_key_hash(const struct nlattr *key, size_t key_len)
 {
diff --git a/lib/odp-util.h b/lib/odp-util.h
index 821b2c4..9a77c95 100644
--- a/lib/odp-util.h
+++ b/lib/odp-util.h
@@ -34,6 +34,7 @@ struct flow_wildcards;
 struct nlattr;
 struct ofpbuf;
 struct simap;
+struct dpif_metadata;
 
 #define SLOW_PATH_REASONS                                               \
     /* These reasons are mutually exclusive. */                         \
@@ -149,6 +150,11 @@ void odp_flow_key_from_mask(struct ofpbuf *, const struct 
flow *mask,
 
 uint32_t odp_flow_key_hash(const struct nlattr *, size_t);
 
+enum { ODP_KEY_METADATA_SIZE = 9 * 8 }; /* Space to reserve for metadata. */
+void odp_key_from_dpif_metadata(struct ofpbuf *, const struct dpif_metadata *);
+void odp_key_to_dpif_metadata(const struct nlattr *key, size_t key_len,
+                              struct dpif_metadata *md);
+
 /* How well a kernel-provided flow key (a sequence of OVS_KEY_ATTR_*
  * attributes) matches OVS userspace expectations.
  *
diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index dba3d3b..b3cb8d6 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -813,9 +813,10 @@ handle_upcalls(struct udpif *udpif, struct list *upcalls)
 
             op = &ops[n_ops++];
             op->type = DPIF_OP_EXECUTE;
-            op->u.execute.key = miss->key;
-            op->u.execute.key_len = miss->key_len;
             op->u.execute.packet = packet;
+            odp_key_to_dpif_metadata(miss->key, miss->key_len,
+                                     &op->u.metadata);
+            op->u.execute.md = &op->u.metadata;
             op->u.execute.actions = miss->xout.odp_actions.data;
             op->u.execute.actions_len = miss->xout.odp_actions.size;
             op->u.execute.needs_help = (miss->xout.slow & SLOW_ACTION) != 0;
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index fa1dc30..d47125e 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -2039,7 +2039,7 @@ execute_controller_action(struct xlate_ctx *ctx, int len,
 {
     struct ofproto_packet_in *pin;
     struct ofpbuf *packet;
-    struct flow key;
+    struct dpif_metadata md = DPIF_METADATA_INITIALIZER(0);
 
     ctx->xout->slow |= SLOW_CONTROLLER;
     if (!ctx->xin->packet) {
@@ -2048,16 +2048,12 @@ execute_controller_action(struct xlate_ctx *ctx, int 
len,
 
     packet = ofpbuf_clone(ctx->xin->packet);
 
-    key.skb_priority = 0;
-    key.pkt_mark = 0;
-    memset(&key.tunnel, 0, sizeof key.tunnel);
-
     ctx->xout->slow |= commit_odp_actions(&ctx->xin->flow, &ctx->base_flow,
                                           &ctx->xout->odp_actions,
                                           &ctx->xout->wc,
                                           &ctx->mpls_depth_delta);
 
-    odp_execute_actions(NULL, packet, &key, ctx->xout->odp_actions.data,
+    odp_execute_actions(NULL, packet, &md, ctx->xout->odp_actions.data,
                         ctx->xout->odp_actions.size, NULL);
 
     pin = xmalloc(sizeof *pin);
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index da27f6a..ec6d0bc 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -3824,12 +3824,11 @@ ofproto_dpif_execute_actions(struct ofproto_dpif 
*ofproto,
                              const struct ofpact *ofpacts, size_t ofpacts_len,
                              struct ofpbuf *packet)
 {
-    struct odputil_keybuf keybuf;
     struct dpif_flow_stats stats;
     struct xlate_out xout;
     struct xlate_in xin;
     ofp_port_t in_port;
-    struct ofpbuf key;
+    struct dpif_metadata md;
     int error;
 
     ovs_assert((rule != NULL) != (ofpacts != NULL));
@@ -3845,15 +3844,17 @@ ofproto_dpif_execute_actions(struct ofproto_dpif 
*ofproto,
     xin.resubmit_stats = &stats;
     xlate_actions(&xin, &xout);
 
-    ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
     in_port = flow->in_port.ofp_port;
     if (in_port == OFPP_NONE) {
         in_port = OFPP_LOCAL;
     }
-    odp_flow_key_from_flow(&key, flow, ofp_port_to_odp_port(ofproto, in_port));
+    md.tunnel = flow->tunnel;
+    md.skb_priority = flow->skb_priority;
+    md.pkt_mark = flow->pkt_mark;
+    md.in_port = ofp_port_to_odp_port(ofproto, in_port);
 
-    error = dpif_execute(ofproto->backer->dpif, key.data, key.size,
-                         xout.odp_actions.data, xout.odp_actions.size, packet,
+    error = dpif_execute(ofproto->backer->dpif, xout.odp_actions.data,
+                         xout.odp_actions.size, packet, &md,
                          (xout.slow & SLOW_ACTION) != 0);
     xlate_out_uninit(&xout);
 
-- 
1.7.10.4

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to