netdev-dpif: Add metadata to dpif-packet.
authorPravin B Shelar <pshelar@nicira.com>
Sat, 4 Oct 2014 03:23:58 +0000 (20:23 -0700)
committerPravin B Shelar <pshelar@nicira.com>
Thu, 9 Oct 2014 21:12:11 +0000 (14:12 -0700)
Today dpif-netdev has single metadat for given batch, since one
batch belongs to one port, but soon packets fro single tunnel ports
can belong to different ports, so we need to have per packet metadata.

Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Acked-by: Jarno Rajahalme <jrajahalme@nicira.com>
lib/dpif-netdev.c
lib/dpif.c
lib/odp-execute.c
lib/odp-execute.h
lib/packet-dpif.c
lib/packet-dpif.h
ofproto/ofproto-dpif-xlate.c

index a1db620..cea7c88 100644 (file)
@@ -384,12 +384,12 @@ static int dpif_netdev_open(const struct dpif_class *, const char *name,
                             bool create, struct dpif **);
 static void dp_netdev_execute_actions(struct dp_netdev_pmd_thread *pmd,
                                       struct dpif_packet **, int c,
-                                      bool may_steal, struct pkt_metadata *,
+                                      bool may_steal,
                                       const struct nlattr *actions,
                                       size_t actions_len);
 static void dp_netdev_input(struct dp_netdev_pmd_thread *,
-                            struct dpif_packet **, int cnt,
-                            struct pkt_metadata *);
+                            struct dpif_packet **, int cnt);
+
 static void dp_netdev_disable_upcall(struct dp_netdev *);
 static void dp_netdev_configure_pmd(struct dp_netdev_pmd_thread *pmd,
                                     struct dp_netdev *dp, int index,
@@ -1853,7 +1853,6 @@ dpif_netdev_execute(struct dpif *dpif, struct dpif_execute *execute)
     struct dp_netdev *dp = get_dp_netdev(dpif);
     struct dp_netdev_pmd_thread *pmd;
     struct dpif_packet packet, *pp;
-    struct pkt_metadata *md = &execute->md;
 
     if (ofpbuf_size(execute->packet) < ETH_HEADER_LEN ||
         ofpbuf_size(execute->packet) > UINT16_MAX) {
@@ -1861,6 +1860,7 @@ dpif_netdev_execute(struct dpif *dpif, struct dpif_execute *execute)
     }
 
     packet.ofpbuf = *execute->packet;
+    packet.md = execute->md;
     pp = &packet;
 
     /* Tries finding the 'pmd'.  If NULL is returned, that means
@@ -1876,7 +1876,7 @@ dpif_netdev_execute(struct dpif *dpif, struct dpif_execute *execute)
     if (pmd->core_id == NON_PMD_CORE_ID) {
         ovs_mutex_lock(&dp->non_pmd_mutex);
     }
-    dp_netdev_execute_actions(pmd, &pp, 1, false, md, execute->actions,
+    dp_netdev_execute_actions(pmd, &pp, 1, false, execute->actions,
                               execute->actions_len);
     if (pmd->core_id == NON_PMD_CORE_ID) {
         ovs_mutex_unlock(&dp->non_pmd_mutex);
@@ -1886,7 +1886,7 @@ dpif_netdev_execute(struct dpif *dpif, struct dpif_execute *execute)
      * reallocate the ofpbuf memory. We need to pass those changes to the
      * caller */
     *execute->packet = packet.ofpbuf;
-
+    execute->md = packet.md;
     return 0;
 }
 
@@ -2037,10 +2037,15 @@ dp_netdev_process_rxq_port(struct dp_netdev_pmd_thread *pmd,
 
     error = netdev_rxq_recv(rxq, packets, &cnt);
     if (!error) {
-        struct pkt_metadata md = PKT_METADATA_INITIALIZER(port->port_no);
+        int i;
 
         *recirc_depth_get() = 0;
-        dp_netdev_input(pmd, packets, cnt, &md);
+
+        /* XXX: initialize md in netdev implementation. */
+        for (i = 0; i < cnt; i++) {
+            packets[i]->md = PKT_METADATA_INITIALIZER(port->port_no);
+        }
+        dp_netdev_input(pmd, packets, cnt);
     } else if (error != EAGAIN && error != EOPNOTSUPP) {
         static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
 
@@ -2486,7 +2491,6 @@ struct packet_batch {
     struct dp_netdev_flow *flow;
 
     struct dpif_packet *packets[NETDEV_MAX_RX_BATCH];
-    struct pkt_metadata md;
 };
 
 static inline void
@@ -2499,11 +2503,9 @@ packet_batch_update(struct packet_batch *batch, struct dpif_packet *packet,
 }
 
 static inline void
-packet_batch_init(struct packet_batch *batch, struct dp_netdev_flow *flow,
-                  struct pkt_metadata *md)
+packet_batch_init(struct packet_batch *batch, struct dp_netdev_flow *flow)
 {
     batch->flow = flow;
-    batch->md = *md;
 
     batch->packet_count = 0;
     batch->byte_count = 0;
@@ -2523,13 +2525,13 @@ packet_batch_execute(struct packet_batch *batch,
     actions = dp_netdev_flow_get_actions(flow);
 
     dp_netdev_execute_actions(pmd, batch->packets, batch->packet_count, true,
-                              &batch->md, actions->actions, actions->size);
+                              actions->actions, actions->size);
 
     dp_netdev_count_packet(pmd->dp, DP_STAT_HIT, batch->packet_count);
 }
 
 static inline bool
-dp_netdev_queue_batches(struct dpif_packet *pkt, struct pkt_metadata *md,
+dp_netdev_queue_batches(struct dpif_packet *pkt,
                         struct dp_netdev_flow *flow, const struct miniflow *mf,
                         struct packet_batch *batches, size_t *n_batches,
                         size_t max_batches)
@@ -2558,7 +2560,7 @@ dp_netdev_queue_batches(struct dpif_packet *pkt, struct pkt_metadata *md,
     }
 
     batch = &batches[(*n_batches)++];
-    packet_batch_init(batch, flow, md);
+    packet_batch_init(batch, flow);
     packet_batch_update(batch, pkt, mf);
     return true;
 }
@@ -2581,8 +2583,7 @@ dpif_packet_swap(struct dpif_packet **a, struct dpif_packet **b)
  */
 static inline size_t
 emc_processing(struct dp_netdev_pmd_thread *pmd, struct dpif_packet **packets,
-               size_t cnt, struct pkt_metadata *md,
-               struct netdev_flow_key *keys)
+               size_t cnt, struct netdev_flow_key *keys)
 {
     struct netdev_flow_key key;
     struct packet_batch batches[4];
@@ -2601,12 +2602,12 @@ emc_processing(struct dp_netdev_pmd_thread *pmd, struct dpif_packet **packets,
             continue;
         }
 
-        miniflow_extract(&packets[i]->ofpbuf, md, &key.flow);
+        miniflow_extract(&packets[i]->ofpbuf, &packets[i]->md, &key.flow);
 
         hash = dpif_netdev_packet_get_dp_hash(packets[i], &key.flow);
 
         flow = emc_lookup(flow_cache, &key.flow, hash);
-        if (OVS_UNLIKELY(!dp_netdev_queue_batches(packets[i], md,
+        if (OVS_UNLIKELY(!dp_netdev_queue_batches(packets[i],
                                                   flow,  &key.flow,
                                                   batches, &n_batches,
                                                   ARRAY_SIZE(batches)))) {
@@ -2628,7 +2629,7 @@ emc_processing(struct dp_netdev_pmd_thread *pmd, struct dpif_packet **packets,
 static inline void
 fast_path_processing(struct dp_netdev_pmd_thread *pmd,
                      struct dpif_packet **packets, size_t cnt,
-                     struct pkt_metadata *md, struct netdev_flow_key *keys)
+                     struct netdev_flow_key *keys)
 {
 #if !defined(__CHECKER__) && !defined(_WIN32)
     const size_t PKT_ARRAY_SIZE = cnt;
@@ -2689,7 +2690,7 @@ fast_path_processing(struct dp_netdev_pmd_thread *pmd,
             /* We can't allow the packet batching in the next loop to execute
              * the actions.  Otherwise, if there are any slow path actions,
              * we'll send the packet up twice. */
-            dp_netdev_execute_actions(pmd, &packets[i], 1, true, md,
+            dp_netdev_execute_actions(pmd, &packets[i], 1, true,
                                       ofpbuf_data(&actions),
                                       ofpbuf_size(&actions));
 
@@ -2740,7 +2741,7 @@ fast_path_processing(struct dp_netdev_pmd_thread *pmd,
         flow = dp_netdev_flow_cast(rules[i]);
         emc_insert(flow_cache, mfs[i], dpif_packet_get_dp_hash(packet),
                    flow);
-        dp_netdev_queue_batches(packet, md, flow, mfs[i], batches, &n_batches,
+        dp_netdev_queue_batches(packet, flow, mfs[i], batches, &n_batches,
                                 ARRAY_SIZE(batches));
     }
 
@@ -2751,7 +2752,7 @@ fast_path_processing(struct dp_netdev_pmd_thread *pmd,
 
 static void
 dp_netdev_input(struct dp_netdev_pmd_thread *pmd,
-                struct dpif_packet **packets, int cnt, struct pkt_metadata *md)
+                struct dpif_packet **packets, int cnt)
 {
 #if !defined(__CHECKER__) && !defined(_WIN32)
     const size_t PKT_ARRAY_SIZE = cnt;
@@ -2762,9 +2763,9 @@ dp_netdev_input(struct dp_netdev_pmd_thread *pmd,
     struct netdev_flow_key keys[PKT_ARRAY_SIZE];
     size_t newcnt;
 
-    newcnt = emc_processing(pmd, packets, cnt, md, keys);
+    newcnt = emc_processing(pmd, packets, cnt, keys);
     if (OVS_UNLIKELY(newcnt)) {
-        fast_path_processing(pmd, packets, newcnt, md, keys);
+        fast_path_processing(pmd, packets, newcnt, keys);
     }
 }
 
@@ -2795,7 +2796,6 @@ dp_netdev_drop_packets(struct dpif_packet ** packets, int cnt, bool may_steal)
 
 static void
 dp_execute_cb(void *aux_, struct dpif_packet **packets, int cnt,
-              struct pkt_metadata *md,
               const struct nlattr *a, bool may_steal)
     OVS_NO_THREAD_SAFETY_ANALYSIS
 {
@@ -2830,13 +2830,13 @@ dp_execute_cb(void *aux_, struct dpif_packet **packets, int cnt,
 
                 ofpbuf_clear(&actions);
 
-                flow_extract(&packets[i]->ofpbuf, md, &flow);
+                flow_extract(&packets[i]->ofpbuf, &packets[i]->md, &flow);
                 error = dp_netdev_upcall(dp, packets[i], &flow, NULL,
                                          DPIF_UC_ACTION, userdata, &actions,
                                          NULL);
                 if (!error || error == ENOSPC) {
                     dp_netdev_execute_actions(pmd, &packets[i], 1, may_steal,
-                                              md, ofpbuf_data(&actions),
+                                              ofpbuf_data(&actions),
                                               ofpbuf_size(&actions));
                 } else if (may_steal) {
                     dpif_packet_delete(packets[i]);
@@ -2872,9 +2872,6 @@ dp_execute_cb(void *aux_, struct dpif_packet **packets, int cnt,
                 hash = 1; /* 0 is not valid */
             }
 
-            if (i == 0) {
-                md->dp_hash = hash;
-            }
             dpif_packet_set_dp_hash(packets[i], hash);
         }
         return;
@@ -2886,18 +2883,16 @@ dp_execute_cb(void *aux_, struct dpif_packet **packets, int cnt,
             (*depth)++;
             for (i = 0; i < cnt; i++) {
                 struct dpif_packet *recirc_pkt;
-                struct pkt_metadata recirc_md = *md;
 
                 recirc_pkt = (may_steal) ? packets[i]
                                     : dpif_packet_clone(packets[i]);
 
-                recirc_md.recirc_id = nl_attr_get_u32(a);
+                recirc_pkt->md.recirc_id = nl_attr_get_u32(a);
 
                 /* Hash is private to each packet */
-                recirc_md.dp_hash = dpif_packet_get_dp_hash(packets[i]);
+                recirc_pkt->md.dp_hash = dpif_packet_get_dp_hash(packets[i]);
 
-                dp_netdev_input(pmd, &recirc_pkt, 1,
-                                &recirc_md);
+                dp_netdev_input(pmd, &recirc_pkt, 1);
             }
             (*depth)--;
 
@@ -2925,12 +2920,12 @@ dp_execute_cb(void *aux_, struct dpif_packet **packets, int cnt,
 static void
 dp_netdev_execute_actions(struct dp_netdev_pmd_thread *pmd,
                           struct dpif_packet **packets, int cnt,
-                          bool may_steal, struct pkt_metadata *md,
+                          bool may_steal,
                           const struct nlattr *actions, size_t actions_len)
 {
-    struct dp_netdev_execute_aux aux = {pmd};
+    struct dp_netdev_execute_aux aux = { pmd };
 
-    odp_execute_actions(&aux, packets, cnt, may_steal, md, actions,
+    odp_execute_actions(&aux, packets, cnt, may_steal, actions,
                         actions_len, dp_execute_cb);
 }
 
index 91e9baf..d088f68 100644 (file)
@@ -991,12 +991,12 @@ struct dpif_execute_helper_aux {
  * meaningful. */
 static void
 dpif_execute_helper_cb(void *aux_, struct dpif_packet **packets, int cnt,
-                       struct pkt_metadata *md,
                        const struct nlattr *action, bool may_steal OVS_UNUSED)
 {
     struct dpif_execute_helper_aux *aux = aux_;
     int type = nl_attr_type(action);
-    struct ofpbuf * packet = &packets[0]->ofpbuf;
+    struct ofpbuf *packet = &packets[0]->ofpbuf;
+    struct pkt_metadata *md = &packets[0]->md;
 
     ovs_assert(cnt == 1);
 
@@ -1064,15 +1064,17 @@ dpif_execute_with_help(struct dpif *dpif, struct dpif_execute *execute)
     COVERAGE_INC(dpif_execute_with_help);
 
     packet.ofpbuf = *execute->packet;
+    packet.md = execute->md;
     pp = &packet;
 
-    odp_execute_actions(&aux, &pp, 1, false, &execute->md, execute->actions,
+    odp_execute_actions(&aux, &pp, 1, false, execute->actions,
                         execute->actions_len, dpif_execute_helper_cb);
 
     /* Even though may_steal is set to false, some actions could modify or
      * reallocate the ofpbuf memory. We need to pass those changes to the
      * caller */
     *execute->packet = packet.ofpbuf;
+    execute->md = packet.md;
 
     return aux.error;
 }
index e2bc6de..230e6e1 100644 (file)
@@ -175,8 +175,7 @@ set_arp(struct ofpbuf *packet, const struct ovs_key_arp *key,
 }
 
 static void
-odp_execute_set_action(struct dpif_packet *packet, const struct nlattr *a,
-                       struct pkt_metadata *md)
+odp_execute_set_action(struct dpif_packet *packet, const struct nlattr *a)
 {
     enum ovs_key_attr type = nl_attr_type(a);
     const struct ovs_key_ipv4 *ipv4_key;
@@ -184,6 +183,7 @@ odp_execute_set_action(struct dpif_packet *packet, const struct nlattr *a,
     const struct ovs_key_tcp *tcp_key;
     const struct ovs_key_udp *udp_key;
     const struct ovs_key_sctp *sctp_key;
+    struct pkt_metadata *md = &packet->md;
 
     switch (type) {
     case OVS_KEY_ATTR_PRIORITY:
@@ -271,8 +271,9 @@ odp_execute_set_action(struct dpif_packet *packet, const struct nlattr *a,
 
 static void
 odp_execute_masked_set_action(struct dpif_packet *packet,
-                              const struct nlattr *a, struct pkt_metadata *md)
+                              const struct nlattr *a)
 {
+    struct pkt_metadata *md = &packet->md;
     enum ovs_key_attr type = nl_attr_type(a);
     struct mpls_hdr *mh;
 
@@ -360,7 +361,7 @@ odp_execute_masked_set_action(struct dpif_packet *packet,
 
 static void
 odp_execute_sample(void *dp, struct dpif_packet *packet, bool steal,
-                   struct pkt_metadata *md, const struct nlattr *action,
+                   const struct nlattr *action,
                    odp_execute_cb dp_execute_action)
 {
     const struct nlattr *subactions = NULL;
@@ -391,13 +392,12 @@ odp_execute_sample(void *dp, struct dpif_packet *packet, bool steal,
         }
     }
 
-    odp_execute_actions(dp, &packet, 1, steal, md, nl_attr_get(subactions),
+    odp_execute_actions(dp, &packet, 1, steal, nl_attr_get(subactions),
                         nl_attr_get_size(subactions), dp_execute_action);
 }
 
 void
-odp_execute_actions(void *dp, struct dpif_packet **packets, int cnt,
-                    bool steal, struct pkt_metadata *md,
+odp_execute_actions(void *dp, struct dpif_packet **packets, int cnt, bool steal,
                     const struct nlattr *actions, size_t actions_len,
                     odp_execute_cb dp_execute_action)
 {
@@ -419,7 +419,7 @@ odp_execute_actions(void *dp, struct dpif_packet **packets, int cnt,
                  * not need it any more. */
                 bool may_steal = steal && last_action;
 
-                dp_execute_action(dp, packets, cnt, md, a, may_steal);
+                dp_execute_action(dp, packets, cnt, a, may_steal);
 
                 if (last_action) {
                     /* We do not need to free the packets. dp_execute_actions()
@@ -441,16 +441,9 @@ odp_execute_actions(void *dp, struct dpif_packet **packets, int cnt,
                 uint32_t hash;
 
                 for (i = 0; i < cnt; i++) {
-                    struct ofpbuf *buf = &packets[i]->ofpbuf;
-
-                    flow_extract(buf, md, &flow);
+                    flow_extract(&packets[i]->ofpbuf, &packets[i]->md, &flow);
                     hash = flow_hash_5tuple(&flow, hash_act->hash_basis);
 
-                    /* The hash of the first packet is in shared metadata */
-                    if (i == 0) {
-                        md->dp_hash = hash ? hash : 1;
-                    }
-
                     /* We also store the hash value with each packet */
                     dpif_packet_set_dp_hash(packets[i], hash ? hash : 1);
                 }
@@ -501,19 +494,19 @@ odp_execute_actions(void *dp, struct dpif_packet **packets, int cnt,
 
         case OVS_ACTION_ATTR_SET:
             for (i = 0; i < cnt; i++) {
-                odp_execute_set_action(packets[i], nl_attr_get(a), md);
+                odp_execute_set_action(packets[i], nl_attr_get(a));
             }
             break;
 
         case OVS_ACTION_ATTR_SET_MASKED:
             for (i = 0; i < cnt; i++) {
-                odp_execute_masked_set_action(packets[i], nl_attr_get(a), md);
+                odp_execute_masked_set_action(packets[i], nl_attr_get(a));
             }
             break;
 
         case OVS_ACTION_ATTR_SAMPLE:
             for (i = 0; i < cnt; i++) {
-                odp_execute_sample(dp, packets[i], steal && last_action, md, a,
+                odp_execute_sample(dp, packets[i], steal && last_action, a,
                                    dp_execute_action);
             }
 
index 23dc219..4710bec 100644 (file)
@@ -28,7 +28,6 @@ struct dpif_packet;
 struct pkt_metadata;
 
 typedef void (*odp_execute_cb)(void *dp, struct dpif_packet **packets, int cnt,
-                               struct pkt_metadata *,
                                const struct nlattr *action, bool may_steal);
 
 /* Actions that need to be executed in the context of a datapath are handed
@@ -36,7 +35,7 @@ typedef void (*odp_execute_cb)(void *dp, struct dpif_packet **packets, int cnt,
  * actions OVS_ACTION_ATTR_OUTPUT and OVS_ACTION_ATTR_USERSPACE so
  * 'dp_execute_action' needs to handle only these. */
 void odp_execute_actions(void *dp, struct dpif_packet **packets, int cnt,
-                         bool steal, struct pkt_metadata *,
+                         bool steal,
                          const struct nlattr *actions, size_t actions_len,
                          odp_execute_cb dp_execute_action);
 #endif
index 3a912e1..db739c5 100644 (file)
@@ -27,6 +27,7 @@ dpif_packet_new_with_headroom(size_t size, size_t headroom)
 
     ofpbuf_init(b, size + headroom);
     ofpbuf_reserve(b, headroom);
+    p->md = PKT_METADATA_INITIALIZER(0);
 
     return p;
 }
@@ -38,6 +39,7 @@ dpif_packet_clone_from_ofpbuf(const struct ofpbuf *b)
     size_t headroom = ofpbuf_headroom(b);
 
     ofpbuf_init(&p->ofpbuf, ofpbuf_size(b) + headroom);
+    p->md = PKT_METADATA_INITIALIZER(0);
     ofpbuf_reserve(&p->ofpbuf, headroom);
 
     ofpbuf_put(&p->ofpbuf, ofpbuf_data(b), ofpbuf_size(b));
@@ -61,6 +63,7 @@ dpif_packet_clone(struct dpif_packet *p)
     struct dpif_packet *newp;
 
     newp = dpif_packet_clone_from_ofpbuf(&p->ofpbuf);
+    memcpy(&newp->md, &p->md, sizeof p->md);
 
     dpif_packet_set_dp_hash(newp, dpif_packet_get_dp_hash(p));
 
index 89f048e..1a5efb6 100644 (file)
@@ -30,6 +30,7 @@ struct dpif_packet {
 #ifndef DPDK_NETDEV
     uint32_t dp_hash;           /* Packet hash. */
 #endif
+    struct pkt_metadata md;
 };
 
 struct dpif_packet *dpif_packet_new_with_headroom(size_t size,
index a881dfb..07a1f29 100644 (file)
@@ -3015,7 +3015,6 @@ execute_controller_action(struct xlate_ctx *ctx, int len,
 {
     struct ofproto_packet_in *pin;
     struct dpif_packet *packet;
-    struct pkt_metadata md = PKT_METADATA_INITIALIZER(0);
 
     ctx->xout->slow |= SLOW_CONTROLLER;
     if (!ctx->xin->packet) {
@@ -3029,7 +3028,7 @@ execute_controller_action(struct xlate_ctx *ctx, int len,
                                           &ctx->xout->wc,
                                           ctx->xbridge->masked_set_action);
 
-    odp_execute_actions(NULL, &packet, 1, false, &md,
+    odp_execute_actions(NULL, &packet, 1, false,
                         ofpbuf_data(ctx->xout->odp_actions),
                         ofpbuf_size(ctx->xout->odp_actions), NULL);