[ovs-dev] [DPDK Upcalls 08/11] xlate: Pull key parsing out of xlate_receive().

Ethan Jackson ethan at nicira.com
Sat Aug 2 01:39:19 UTC 2014


In future patches, dpif-netdev will not create a flow key for each
upcall.  To accommodate this, we require callers to handle flow
parsing themselves.

Signed-off-by: Ethan Jackson <ethan at nicira.com>
---
 ofproto/ofproto-dpif-upcall.c | 30 ++++++++++++++++++++----------
 ofproto/ofproto-dpif-xlate.c  | 23 +++++++++--------------
 ofproto/ofproto-dpif-xlate.h  |  8 ++++----
 ofproto/ofproto-dpif.c        | 17 ++++++++++++-----
 4 files changed, 45 insertions(+), 33 deletions(-)

diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index b0fd203..3003455 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -858,9 +858,14 @@ convert_upcall(struct udpif *udpif, struct upcall *upcall)
     odp_port_t odp_in_port;
     int error;
 
-    error = xlate_receive(udpif->backer, dupcall->key,
-                          dupcall->key_len, &flow,
-                          &ofproto, &ipfix, &sflow, NULL, &odp_in_port);
+    if (odp_flow_key_to_flow(dupcall->key, dupcall->key_len, &flow)
+        == ODP_FIT_ERROR) {
+        error = EINVAL;
+        goto destroy_upcall;
+    }
+
+    error = xlate_receive(udpif->backer, &flow, &ofproto, &ipfix, &sflow, NULL,
+                          &odp_in_port);
 
     if (error) {
         if (error == ENODEV) {
@@ -1238,8 +1243,13 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey,
         goto exit;
     }
 
-    error = xlate_receive(udpif->backer, ukey->key, ukey->key_len, &flow,
-                          &ofproto, NULL, NULL, &netflow, &odp_in_port);
+    if (odp_flow_key_to_flow(ukey->key, ukey->key_len, &flow)
+        == ODP_FIT_ERROR) {
+        goto exit;
+    }
+
+    error = xlate_receive(udpif->backer, &flow, &ofproto, NULL, NULL, &netflow,
+                          &odp_in_port);
     if (error) {
         goto exit;
     }
@@ -1355,7 +1365,6 @@ push_dump_ops__(struct udpif *udpif, struct dump_op *ops, size_t n_ops)
             struct netflow *netflow;
             struct flow flow;
             bool may_learn;
-            int error;
 
             may_learn = push->n_packets > 0;
             ovs_mutex_lock(&op->ukey->mutex);
@@ -1366,10 +1375,11 @@ push_dump_ops__(struct udpif *udpif, struct dump_op *ops, size_t n_ops)
             }
             ovs_mutex_unlock(&op->ukey->mutex);
 
-            error = xlate_receive(udpif->backer, op->op.u.flow_del.key,
-                                  op->op.u.flow_del.key_len, &flow, &ofproto,
-                                  NULL, NULL, &netflow, NULL);
-            if (!error) {
+            if (odp_flow_key_to_flow(op->op.u.flow_del.key,
+                                     op->op.u.flow_del.key_len,
+                                     &flow) != ODP_FIT_ERROR
+                && !xlate_receive(udpif->backer, &flow, &ofproto, NULL, NULL,
+                                 &netflow, NULL)) {
                 struct xlate_in xin;
 
                 xlate_in_init(&xin, ofproto, &flow, NULL, push->tcp_flags,
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index f115849..a1d13c7 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -934,12 +934,11 @@ xlate_ofport_remove(struct ofport_dpif *ofport)
     xlate_xport_remove(new_xcfg, xport);
 }
 
-/* Given a datpath and flow metadata ('backer', and 'key' respectively),
- * populates 'flow' with the result of odp_flow_key_to_flow().  Optionally
- * populates 'ofproto' with the ofproto_dpif, 'odp_in_port' with the datapath
- * in_port, and 'ipfix', 'sflow', and 'netflow' with the appropriate handles
- * for those protocols if they're enabled.  Caller is responsible for unrefing
- * them.
+/* Given a datpath and flow metadata ('backer', and 'flow' respectively),
+ * Optionally populates 'ofproto' with the ofproto_dpif, 'odp_in_port' with the
+ * datapath in_port, and 'ipfix', 'sflow', and 'netflow' with the appropriate
+ * handles for those protocols if they're enabled.  Caller is responsible for
+ * unrefing them.
  *
  * If 'ofproto' is nonnull, requires 'flow''s in_port to exist.  Otherwise sets
  * 'flow''s in_port to OFPP_NONE.
@@ -951,18 +950,14 @@ xlate_ofport_remove(struct ofport_dpif *ofport)
  * Returns 0 if successful, ENODEV if the parsed flow has no associated ofport,
  * or some other positive errno if there are other problems. */
 int
-xlate_receive(const struct dpif_backer *backer, const struct nlattr *key,
-              size_t key_len, struct flow *flow, struct ofproto_dpif **ofproto,
-              struct dpif_ipfix **ipfix, struct dpif_sflow **sflow,
-              struct netflow **netflow, odp_port_t *odp_in_port)
+xlate_receive(const struct dpif_backer *backer, struct flow *flow,
+              struct ofproto_dpif **ofproto, struct dpif_ipfix **ipfix,
+              struct dpif_sflow **sflow, struct netflow **netflow,
+              odp_port_t *odp_in_port)
 {
     struct xlate_cfg *xcfg = ovsrcu_get(struct xlate_cfg *, &xcfgp);
     const struct xport *xport;
 
-    if (odp_flow_key_to_flow(key, key_len, flow) == ODP_FIT_ERROR) {
-        return EINVAL;
-    }
-
     if (odp_in_port) {
         *odp_in_port = flow->in_port.odp_port;
     }
diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h
index 3522c0b..07586aa 100644
--- a/ofproto/ofproto-dpif-xlate.h
+++ b/ofproto/ofproto-dpif-xlate.h
@@ -173,10 +173,10 @@ void xlate_ofport_set(struct ofproto_dpif *, struct ofbundle *,
                       bool may_enable);
 void xlate_ofport_remove(struct ofport_dpif *);
 
-int xlate_receive(const struct dpif_backer *, const struct nlattr *key,
-                  size_t key_len, struct flow *, struct ofproto_dpif **,
-                  struct dpif_ipfix **, struct dpif_sflow **,
-                  struct netflow **, odp_port_t *odp_in_port);
+int xlate_receive(const struct dpif_backer *, struct flow *,
+                  struct ofproto_dpif **, struct dpif_ipfix **,
+                  struct dpif_sflow **, struct netflow **,
+                  odp_port_t *odp_in_port);
 
 void xlate_actions(struct xlate_in *, struct xlate_out *);
 void xlate_in_init(struct xlate_in *, struct ofproto_dpif *,
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index c49f1fb..77cdce3 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -4205,9 +4205,13 @@ parse_flow_and_packet(int argc, const char *argv[],
             goto exit;
         }
 
-        if (xlate_receive(backer, ofpbuf_data(&odp_key),
-                          ofpbuf_size(&odp_key), flow,
-                          ofprotop, NULL, NULL, NULL, NULL)) {
+        if (odp_flow_key_to_flow(ofpbuf_data(&odp_key), ofpbuf_size(&odp_key),
+                                 flow) == ODP_FIT_ERROR) {
+            error = "Failed to parse flow key";
+            goto exit;
+        }
+
+        if (xlate_receive(backer, flow, ofprotop, NULL, NULL, NULL, NULL)) {
             error = "Invalid datapath flow";
             goto exit;
         }
@@ -4592,8 +4596,11 @@ ofproto_dpif_contains_flow(const struct ofproto_dpif *ofproto,
     struct ofproto_dpif *ofp;
     struct flow flow;
 
-    xlate_receive(ofproto->backer, key, key_len, &flow, &ofp, NULL, NULL, NULL,
-                  NULL);
+    if (odp_flow_key_to_flow(key, key_len, &flow) == ODP_FIT_ERROR) {
+        return false;
+    }
+
+    xlate_receive(ofproto->backer, &flow, &ofp, NULL, NULL, NULL, NULL);
     return ofp == ofproto;
 }
 
-- 
1.8.1.2




More information about the dev mailing list