[ovs-dev] [PATCH] lib: simplify flow_extract() API

Andy Zhou azhou at nicira.com
Thu Feb 27 02:22:39 UTC 2014


Change the flow_extract() API to accept struct pkt_metadta,
instead of individual metadata fields. It will make the API more
logical and easier to maintain when we need to expand metadata
down the road.

Signed-off-by: Andy Zhou <azhou at nicira.com>
---
 lib/dpif-netdev.c             |    6 ++----
 lib/flow.c                    |   20 ++++++++------------
 lib/flow.h                    |    4 ++--
 lib/learning-switch.c         |    4 +++-
 lib/ofp-print.c               |    4 +++-
 lib/packets.c                 |   28 ++++++++++++++++++++++++++++
 lib/packets.h                 |    7 +++++++
 ofproto/ofproto-dpif-upcall.c |    5 +++--
 ofproto/ofproto-dpif-xlate.c  |    5 ++++-
 ofproto/ofproto-dpif.c        |    7 +++++--
 ofproto/ofproto.c             |    8 ++++++--
 tests/test-flows.c            |    4 +++-
 utilities/ovs-ofctl.c         |    6 ++++--
 13 files changed, 78 insertions(+), 30 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index c4ba646..6b07817 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -1419,8 +1419,7 @@ dpif_netdev_execute(struct dpif *dpif, struct dpif_execute *execute)
     }
 
     /* Extract flow key. */
-    flow_extract(execute->packet, md->skb_priority, md->pkt_mark, &md->tunnel,
-                 (union flow_in_port *)&md->in_port, &key);
+    flow_extract(execute->packet, md, &key);
 
     ovs_rwlock_rdlock(&dp->port_rwlock);
     dp_netdev_execute_actions(dp, &key, execute->packet, md, execute->actions,
@@ -1693,8 +1692,7 @@ dp_netdev_port_input(struct dp_netdev *dp, struct ofpbuf *packet,
     if (packet->size < ETH_HEADER_LEN) {
         return;
     }
-    flow_extract(packet, md->skb_priority, md->pkt_mark, &md->tunnel,
-                 (union flow_in_port *)&md->in_port, &key);
+    flow_extract(packet, md, &key);
     netdev_flow = dp_netdev_lookup_flow(dp, &key);
     if (netdev_flow) {
         struct dp_netdev_actions *actions;
diff --git a/lib/flow.c b/lib/flow.c
index e7fe4d3..3fa61a8 100644
--- a/lib/flow.c
+++ b/lib/flow.c
@@ -35,6 +35,7 @@
 #include "ofpbuf.h"
 #include "openflow/openflow.h"
 #include "packets.h"
+#include "odp-util.h"
 #include "random.h"
 #include "unaligned.h"
 
@@ -361,8 +362,7 @@ invalid:
 
 }
 
-/* Initializes 'flow' members from 'packet', 'skb_priority', 'tnl', and
- * 'in_port'.
+/* Initializes 'flow' members from 'packet' and 'md'
  *
  * Initializes 'packet' header pointers as follows:
  *
@@ -381,8 +381,7 @@ invalid:
  *      present and has a correct length, and otherwise NULL.
  */
 void
-flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t pkt_mark,
-             const struct flow_tnl *tnl, const union flow_in_port *in_port,
+flow_extract(struct ofpbuf *packet, const struct pkt_metadata *md,
              struct flow *flow)
 {
     struct ofpbuf b = *packet;
@@ -392,15 +391,12 @@ flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t pkt_mark,
 
     memset(flow, 0, sizeof *flow);
 
-    if (tnl) {
-        ovs_assert(tnl != &flow->tunnel);
-        flow->tunnel = *tnl;
+    flow->tunnel = md->tunnel;
+    if (md->in_port != ODPP_NONE) {
+        flow->in_port.odp_port = md->in_port;
     }
-    if (in_port) {
-        flow->in_port = *in_port;
-    }
-    flow->skb_priority = skb_priority;
-    flow->pkt_mark = pkt_mark;
+    flow->skb_priority = md->skb_priority;
+    flow->pkt_mark = md->pkt_mark;
 
     packet->l2   = b.data;
     packet->l2_5 = NULL;
diff --git a/lib/flow.h b/lib/flow.h
index 3109a84..1e8d137 100644
--- a/lib/flow.h
+++ b/lib/flow.h
@@ -32,6 +32,7 @@ struct ds;
 struct flow_wildcards;
 struct minimask;
 struct ofpbuf;
+struct pkt_metadata;
 
 /* This sequence number should be incremented whenever anything involving flows
  * or the wildcarding of flows changes.  This will cause build assertion
@@ -173,8 +174,7 @@ struct flow_metadata {
     ofp_port_t in_port;              /* OpenFlow port or zero. */
 };
 
-void flow_extract(struct ofpbuf *, uint32_t priority, uint32_t mark,
-                  const struct flow_tnl *, const union flow_in_port *in_port,
+void flow_extract(struct ofpbuf *, const struct pkt_metadata *md,
                   struct flow *);
 
 void flow_zero_wildcards(struct flow *, const struct flow_wildcards *);
diff --git a/lib/learning-switch.c b/lib/learning-switch.c
index 8efbce1..ef2976f 100644
--- a/lib/learning-switch.c
+++ b/lib/learning-switch.c
@@ -547,6 +547,7 @@ process_packet_in(struct lswitch *sw, const struct ofp_header *oh)
     struct ofputil_packet_in pi;
     uint32_t queue_id;
     ofp_port_t out_port;
+    struct pkt_metadata md;
 
     uint64_t ofpacts_stub[64 / 8];
     struct ofpbuf ofpacts;
@@ -575,7 +576,8 @@ process_packet_in(struct lswitch *sw, const struct ofp_header *oh)
     /* Extract flow data from 'opi' into 'flow'. */
     ofpbuf_use_const(&pkt, pi.packet, pi.packet_len);
     in_port_.ofp_port = pi.fmd.in_port;
-    flow_extract(&pkt, 0, 0, NULL, &in_port_, &flow);
+    pkt_metadata_init(&md, &in_port_);
+    flow_extract(&pkt, &md,  &flow);
     flow.tunnel.tun_id = pi.fmd.tun_id;
 
     /* Choose output port. */
diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index 4c89b36..06e64f6 100644
--- a/lib/ofp-print.c
+++ b/lib/ofp-print.c
@@ -46,6 +46,7 @@
 #include "packets.h"
 #include "type-props.h"
 #include "unaligned.h"
+#include "odp-util.h"
 #include "util.h"
 
 static void ofp_print_queue_name(struct ds *string, uint32_t port);
@@ -58,11 +59,12 @@ char *
 ofp_packet_to_string(const void *data, size_t len)
 {
     struct ds ds = DS_EMPTY_INITIALIZER;
+    const struct pkt_metadata md = PKT_METADATA_INITIALIZER(ODPP_NONE);
     struct ofpbuf buf;
     struct flow flow;
 
     ofpbuf_use_const(&buf, data, len);
-    flow_extract(&buf, 0, 0, NULL, NULL, &flow);
+    flow_extract(&buf, &md, &flow);
     flow_format(&ds, &flow);
 
     if (buf.l7) {
diff --git a/lib/packets.c b/lib/packets.c
index 7238f42..0286954 100644
--- a/lib/packets.c
+++ b/lib/packets.c
@@ -29,6 +29,7 @@
 #include "dynamic-string.h"
 #include "ofpbuf.h"
 #include "ovs-thread.h"
+#include "odp-util.h"
 #include "unaligned.h"
 
 const struct in6_addr in6addr_exact = IN6ADDR_EXACT_INIT;
@@ -991,3 +992,30 @@ packet_format_tcp_flags(struct ds *s, uint16_t tcp_flags)
         ds_put_cstr(s, "[800]");
     }
 }
+
+void pkt_metadata_init(struct pkt_metadata *md,
+                       const union flow_in_port* in_port)
+{
+    pkt_metadata_init_full(md, NULL, 0, 0, in_port);
+}
+
+void pkt_metadata_init_full(struct pkt_metadata *md, const struct flow_tnl *tnl,
+                            const uint32_t skb_priority,
+                            const uint32_t pkt_mark,
+                            const union flow_in_port *in_port)
+{
+
+    tnl ? memcpy(&md->tunnel, tnl, sizeof(md->tunnel))
+        : memset(&md->tunnel, 0, sizeof(md->tunnel));
+
+    md->skb_priority = skb_priority;
+    md->pkt_mark = pkt_mark;
+    md->in_port = in_port ? in_port->odp_port : ODPP_NONE;
+}
+
+void pkt_metadata_from_flow(struct pkt_metadata *md, const struct flow *flow)
+{
+
+    pkt_metadata_init_full(md, &flow->tunnel, flow->skb_priority,
+                           flow->pkt_mark, &flow->in_port);
+}
diff --git a/lib/packets.h b/lib/packets.h
index 1855a1c..5e1d52d 100644
--- a/lib/packets.h
+++ b/lib/packets.h
@@ -42,6 +42,13 @@ struct pkt_metadata {
 #define PKT_METADATA_INITIALIZER(PORT) \
     (struct pkt_metadata){ { 0, 0, 0, 0, 0, 0}, 0, 0, (PORT) }
 
+void pkt_metadata_init(struct pkt_metadata *md, const union flow_in_port *in_port);
+void pkt_metadata_init_full(struct pkt_metadata *md, const struct flow_tnl *tnl,
+                            const uint32_t skb_priority,
+                            const uint32_t pkt_mark,
+                            const union flow_in_port *in_port);
+void pkt_metadata_from_flow(struct pkt_metadata *md, const struct flow *flow);
+
 bool dpid_from_string(const char *s, uint64_t *dpidp);
 
 #define ETH_ADDR_LEN           6
diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index e4f81a1..6cc0b67 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -983,9 +983,10 @@ handle_upcalls(struct handler *handler, struct list *upcalls)
         type = classify_upcall(upcall);
         if (type == MISS_UPCALL) {
             uint32_t hash;
+            struct pkt_metadata md;
 
-            flow_extract(packet, flow.skb_priority, flow.pkt_mark,
-                         &flow.tunnel, &flow.in_port, &miss->flow);
+            pkt_metadata_from_flow(&md, &flow);
+            flow_extract(packet, &md, &miss->flow);
 
             hash = flow_hash(&miss->flow, 0);
             existing_miss = flow_miss_find(&misses, ofproto, &miss->flow,
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 89d92af..0955d64 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -3184,12 +3184,15 @@ xlate_send_packet(const struct ofport_dpif *ofport, struct ofpbuf *packet)
     struct xport *xport;
     struct ofpact_output output;
     struct flow flow;
+    struct pkt_metadata md;
     union flow_in_port in_port_;
 
     ofpact_init(&output.ofpact, OFPACT_OUTPUT, sizeof output);
     /* Use OFPP_NONE as the in_port to avoid special packet processing. */
     in_port_.ofp_port = OFPP_NONE;
-    flow_extract(packet, 0, 0, NULL, &in_port_, &flow);
+
+    pkt_metadata_init(&md, &in_port_);
+    flow_extract(packet, &md, &flow);
 
     ovs_rwlock_rdlock(&xlate_rwlock);
     xport = xport_lookup(ofport);
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index c597114..6c48c18 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -3784,11 +3784,14 @@ parse_flow_and_packet(int argc, const char *argv[],
             flow_compose(packet, flow);
         } else {
             union flow_in_port in_port = flow->in_port;
+            struct pkt_metadata md;
 
             /* Use the metadata from the flow and the packet argument
              * to reconstruct the flow. */
-            flow_extract(packet, flow->skb_priority, flow->pkt_mark, NULL,
-                         &in_port, flow);
+            pkt_metadata_init_full(&md, NULL, flow->skb_priority,
+                                   flow->pkt_mark, &in_port);
+
+            flow_extract(packet, &md, flow);
         }
     }
 
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 7117e1f..e400b32 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -2715,9 +2715,11 @@ run_rule_executes(struct ofproto *ofproto)
     LIST_FOR_EACH_SAFE (e, next, list_node, &executes) {
         union flow_in_port in_port_;
         struct flow flow;
+        struct pkt_metadata md;
 
         in_port_.ofp_port = e->in_port;
-        flow_extract(e->packet, 0, 0, NULL, &in_port_, &flow);
+        pkt_metadata_init(&md, &in_port_);
+        flow_extract(e->packet, &md, &flow);
         ofproto->ofproto_class->rule_execute(e->rule, &flow, e->packet);
 
         rule_execute_destroy(e);
@@ -2928,6 +2930,7 @@ handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh)
     struct flow flow;
     union flow_in_port in_port_;
     enum ofperr error;
+    struct pkt_metadata md;
 
     COVERAGE_INC(ofproto_packet_out);
 
@@ -2961,7 +2964,8 @@ handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh)
 
     /* Verify actions against packet, then send packet if successful. */
     in_port_.ofp_port = po.in_port;
-    flow_extract(payload, 0, 0, NULL, &in_port_, &flow);
+    pkt_metadata_init(&md, &in_port_);
+    flow_extract(payload, &md, &flow);
     error = ofproto_check_ofpacts(p, po.ofpacts, po.ofpacts_len);
     if (!error) {
         error = p->ofproto_class->packet_out(p, payload, &flow,
diff --git a/tests/test-flows.c b/tests/test-flows.c
index 2910035..7907523 100644
--- a/tests/test-flows.c
+++ b/tests/test-flows.c
@@ -58,6 +58,7 @@ main(int argc OVS_UNUSED, char *argv[])
         struct ofp10_match extracted_match;
         struct match match;
         struct flow flow;
+        struct pkt_metadata md;
         union flow_in_port in_port_;
         n++;
 
@@ -69,7 +70,8 @@ main(int argc OVS_UNUSED, char *argv[])
         }
 
         in_port_.ofp_port = u16_to_ofp(1);
-        flow_extract(packet, 0, 0, NULL, &in_port_, &flow);
+        pkt_metadata_init(&md, &in_port_);
+        flow_extract(packet, &md, &flow);
         match_wc_init(&match, &flow);
         ofputil_match_to_ofp10_match(&match, &extracted_match);
 
diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
index 4ab9ca4..e62e646 100644
--- a/utilities/ovs-ofctl.c
+++ b/utilities/ovs-ofctl.c
@@ -1864,12 +1864,13 @@ ofctl_ofp_parse_pcap(int argc OVS_UNUSED, char *argv[])
         struct ofpbuf *packet;
         long long int when;
         struct flow flow;
+        const struct pkt_metadata md = PKT_METADATA_INITIALIZER(ODPP_NONE);
 
         error = ovs_pcap_read(file, &packet, &when);
         if (error) {
             break;
         }
-        flow_extract(packet, 0, 0, NULL, NULL, &flow);
+        flow_extract(packet, &md, &flow);
         if (flow.dl_type == htons(ETH_TYPE_IP)
             && flow.nw_proto == IPPROTO_TCP
             && (is_openflow_port(flow.tp_src, argv + 2) ||
@@ -3208,6 +3209,7 @@ ofctl_parse_pcap(int argc OVS_UNUSED, char *argv[])
     for (;;) {
         struct ofpbuf *packet;
         struct flow flow;
+        const struct pkt_metadata md = PKT_METADATA_INITIALIZER(ODPP_NONE);
         int error;
 
         error = ovs_pcap_read(pcap, &packet, NULL);
@@ -3217,7 +3219,7 @@ ofctl_parse_pcap(int argc OVS_UNUSED, char *argv[])
             ovs_fatal(error, "%s: read failed", argv[1]);
         }
 
-        flow_extract(packet, 0, 0, NULL, NULL, &flow);
+        flow_extract(packet, &md, &flow);
         flow_print(stdout, &flow);
         putchar('\n');
         ofpbuf_delete(packet);
-- 
1.7.9.5




More information about the dev mailing list