[ovs-dev] [flow_metadata 5/5] flow: Make flow_extract()'s caller responsible for metadata.

Ben Pfaff blp at nicira.com
Fri May 10 23:42:28 UTC 2013


We are getting to have a lot of metadata in struct flow.  Until now, we
have tried to pass all of it as parameters to flow_extract().  Now that
the data and metadata members of struct flow are clearly separated, it
seems more reasonable to just make the caller initialize them itself.

Signed-off-by: Ben Pfaff <blp at nicira.com>
---
 lib/dpif-netdev.c      |    5 +++--
 lib/flow.c             |   16 +++-------------
 lib/flow.h             |    3 +--
 lib/learning-switch.c  |    3 ++-
 lib/ofp-print.c        |    2 +-
 ofproto/ofproto-dpif.c |   12 ++++++++----
 ofproto/ofproto.c      |    6 ++++--
 tests/test-flows.c     |    5 +++--
 8 files changed, 25 insertions(+), 27 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 8984f7d..f9a845d 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -941,7 +941,7 @@ dpif_netdev_execute(struct dpif *dpif, const struct dpif_execute *execute)
     ofpbuf_reserve(&copy, DP_NETDEV_HEADROOM);
     ofpbuf_put(&copy, execute->packet->data, execute->packet->size);
 
-    flow_extract(&copy, 0, 0, NULL, -1, &key);
+    flow_extract(&copy, &key);
     error = dpif_netdev_flow_from_nlattrs(execute->key, execute->key_len,
                                           &key);
     if (!error) {
@@ -1039,7 +1039,8 @@ dp_netdev_port_input(struct dp_netdev *dp, struct dp_netdev_port *port,
     if (packet->size < ETH_HEADER_LEN) {
         return;
     }
-    flow_extract(packet, 0, 0, NULL, port->port_no, &key);
+    flow_extract(packet, &key);
+    key.md.in_port = port->port_no;
     flow = dp_netdev_lookup_flow(dp, &key);
     if (flow) {
         dp_netdev_flow_used(flow, packet);
diff --git a/lib/flow.c b/lib/flow.c
index de4d171..2eb87e6 100644
--- a/lib/flow.c
+++ b/lib/flow.c
@@ -336,8 +336,8 @@ invalid:
 
 }
 
-/* Initializes 'flow' members from 'packet', 'skb_priority', 'tnl', and
- * 'ofp_in_port'.
+/* Initializes 'flow' data members from 'packet'.  Zeroes 'flow->md', which the
+ * caller must initialize appropriately afterward.
  *
  * Initializes 'packet' header pointers as follows:
  *
@@ -356,9 +356,7 @@ invalid:
  *      present and has a correct length, and otherwise NULL.
  */
 void
-flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t skb_mark,
-             const struct flow_tnl *tnl, uint16_t ofp_in_port,
-             struct flow *flow)
+flow_extract(struct ofpbuf *packet, struct flow *flow)
 {
     struct ofpbuf b = *packet;
     struct eth_header *eth;
@@ -367,14 +365,6 @@ flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t skb_mark,
 
     memset(flow, 0, sizeof *flow);
 
-    if (tnl) {
-        ovs_assert(tnl != &flow->md.tunnel);
-        flow->md.tunnel = *tnl;
-    }
-    flow->md.in_port = ofp_in_port;
-    flow->md.skb_priority = skb_priority;
-    flow->md.skb_mark = skb_mark;
-
     packet->l2   = b.data;
     packet->l2_5 = NULL;
     packet->l3   = NULL;
diff --git a/lib/flow.h b/lib/flow.h
index 1610871..d593882 100644
--- a/lib/flow.h
+++ b/lib/flow.h
@@ -116,8 +116,7 @@ BUILD_ASSERT_DECL(sizeof(struct flow) % 4 == 0);
 BUILD_ASSERT_DECL(sizeof(struct flow) == sizeof(struct flow_metadata) + 104 &&
                   FLOW_WC_SEQ == 20);
 
-void flow_extract(struct ofpbuf *, uint32_t priority, uint32_t mark,
-                  const struct flow_tnl *, uint16_t in_port, struct flow *);
+void flow_extract(struct ofpbuf *, 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 ec308fe..c55b102 100644
--- a/lib/learning-switch.c
+++ b/lib/learning-switch.c
@@ -558,7 +558,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);
-    flow_extract(&pkt, 0, 0, &pi.fmd.tunnel, pi.fmd.in_port, &flow);
+    flow_extract(&pkt, &flow);
+    flow.md = pi.fmd;
 
     /* Choose output port. */
     out_port = lswitch_choose_destination(sw, &flow);
diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index 1b89d3d..af2ca4a 100644
--- a/lib/ofp-print.c
+++ b/lib/ofp-print.c
@@ -62,7 +62,7 @@ ofp_packet_to_string(const void *data, size_t len)
     struct flow flow;
 
     ofpbuf_use_const(&buf, data, len);
-    flow_extract(&buf, 0, 0, NULL, 0, &flow);
+    flow_extract(&buf, &flow);
     flow_format(&ds, &flow);
 
     if (buf.l7) {
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 5c37509..a9c1ad3 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -4030,8 +4030,8 @@ handle_miss_upcalls(struct dpif_backer *backer, struct dpif_upcall *upcalls,
         }
 
         ofproto->n_missed++;
-        flow_extract(upcall->packet, flow.md.skb_priority, flow.md.skb_mark,
-                     &flow.md.tunnel, flow.md.in_port, &miss->flow);
+        flow_extract(upcall->packet, &miss->flow);
+        miss->flow.md = flow.md;
 
         /* Add other packets to a to-do list. */
         hash = flow_hash(&miss->flow, 0);
@@ -5821,7 +5821,8 @@ send_packet(const struct ofport_dpif *ofport, struct ofpbuf *packet)
     ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
 
     /* Use OFPP_NONE as the in_port to avoid special packet processing. */
-    flow_extract(packet, 0, 0, NULL, OFPP_NONE, &flow);
+    flow_extract(packet, &flow);
+    flow.md.in_port = OFPP_NONE;
     odp_flow_key_from_flow(&key, &flow, ofp_port_to_odp_port(ofproto,
                                                              OFPP_LOCAL));
     dpif_flow_stats_extract(&flow, packet, time_msec(), &stats);
@@ -8227,7 +8228,10 @@ ofproto_unixctl_trace(struct unixctl_conn *conn, int argc, const char *argv[],
         ds_put_cstr(&result, s);
         free(s);
 
-        flow_extract(packet, priority, mark, NULL, in_port, &flow);
+        flow_extract(packet, &flow);
+        flow.md.skb_priority = priority;
+        flow.md.skb_mark = mark;
+        flow.md.in_port = in_port;
         flow.md.tunnel.tun_id = tun_id;
         initial_vals.vlan_tci = flow.vlan_tci;
     } else {
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 28df181..211e0e7 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -2179,7 +2179,8 @@ rule_execute(struct rule *rule, uint16_t in_port, struct ofpbuf *packet)
 
     ovs_assert(ofpbuf_headroom(packet) >= sizeof(struct ofp10_packet_in));
 
-    flow_extract(packet, 0, 0, NULL, in_port, &flow);
+    flow_extract(packet, &flow);
+    flow.md.in_port = in_port;
     return rule->ofproto->ofproto_class->rule_execute(rule, &flow, packet);
 }
 
@@ -2373,7 +2374,8 @@ handle_packet_out(struct ofconn *ofconn, const struct ofp_header *oh)
     }
 
     /* Verify actions against packet, then send packet if successful. */
-    flow_extract(payload, 0, 0, NULL, po.in_port, &flow);
+    flow_extract(payload, &flow);
+    flow.md.in_port = po.in_port;
     error = ofpacts_check(po.ofpacts, po.ofpacts_len, &flow, p->max_ports);
     if (!error) {
         error = p->ofproto_class->packet_out(p, payload, &flow,
diff --git a/tests/test-flows.c b/tests/test-flows.c
index c77372f..1b76cad 100644
--- a/tests/test-flows.c
+++ b/tests/test-flows.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -68,7 +68,8 @@ main(int argc OVS_UNUSED, char *argv[])
             ovs_fatal(retval, "error reading pcap file");
         }
 
-        flow_extract(packet, 0, 0, NULL, 1, &flow);
+        flow_extract(packet, &flow);
+        flow.md.in_port = 1;
         match_init_exact(&match, &flow);
         ofputil_match_to_ofp10_match(&match, &extracted_match);
 
-- 
1.7.10.4




More information about the dev mailing list