[ovs-dev] [PATCH 4/5] ofproto: Define ofproto_flow_lookup()

Pravin pshelar at nicira.com
Thu Mar 27 16:44:35 UTC 2014


Define ofproto flow lookup function that can be used by dpif
implementation.

Signed-off-by: Pravin B Shelar <pshelar at nicira.com>
---
 ofproto/ofproto-dpif-upcall.c |   68 +++++++++++++++++++++++++++++++++++++++++
 ofproto/ofproto-dpif-upcall.h |    8 +++++
 ofproto/ofproto-dpif-xlate.c  |   34 +++++++++++++++++++++
 ofproto/ofproto-dpif-xlate.h  |    3 ++
 ofproto/ofproto-dpif.c        |   14 +++++++++
 5 files changed, 127 insertions(+)

diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index 95e4e86..57b2e1f 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -1727,3 +1727,71 @@ upcall_unixctl_set_flow_limit(struct unixctl_conn *conn,
     unixctl_command_reply(conn, ds_cstr(&ds));
     ds_destroy(&ds);
 }
+
+int
+ofproto_flow_lookup(const void *data,
+                    struct ofpbuf *packet, struct flow *flow,
+                    struct flow_wildcards *wc, struct ofpbuf *actions)
+{
+    struct udpif *udpif = (struct udpif *) data;
+    bool megaflow;
+    struct dpif_flow_stats stats;
+    struct ofproto_dpif *ofproto;
+    struct xlate_out xout;
+    struct xlate_in xin;
+    int err;
+
+    err = xlate_lookup_port(udpif->backer, packet, flow, &ofproto);
+    if (err) {
+        return err;
+    }
+
+    stats.used = time_msec();
+    stats.tcp_flags = ntohs(flow->tcp_flags);
+    stats.n_bytes = packet->size;
+    stats.n_packets = 1;
+
+    xlate_in_init(&xin, ofproto, flow, NULL, stats.tcp_flags, NULL);
+    xin.may_learn = true;
+    xin.resubmit_stats = &stats;
+
+    xlate_actions(&xin, &xout);
+    if (xout.fail_open) {
+        struct ofproto_packet_in *pin;
+
+        pin = xmalloc(sizeof *pin);
+        pin->up.packet = xmemdup(packet->data, packet->size);
+        pin->up.packet_len = packet->size;
+        pin->up.reason = OFPR_NO_MATCH;
+        pin->up.table_id = 0;
+        pin->up.cookie = OVS_BE64_MAX;
+        flow_get_metadata(flow, &pin->up.fmd);
+        pin->send_len = 0; /* Not used for flow table misses. */
+        pin->miss_type = OFPROTO_PACKET_IN_NO_MISS;
+        ofproto_dpif_send_packet_in(ofproto, pin);
+
+        return -ENOENT;
+    }
+
+    atomic_read(&enable_megaflows, &megaflow);
+    if (megaflow) {
+        wc->masks = xout.wc.masks;
+    } else {
+        flow_mask_unwildcard_all(flow, &wc->masks);
+    }
+
+    if (!xout.slow) {
+        ofpbuf_put(actions, xout.odp_actions.data, xout.odp_actions.size);
+    } else {
+        uint64_t slow_path_buf[128 / 8];
+        struct ofpbuf buf;
+
+        ofpbuf_use_stack(&buf, slow_path_buf, sizeof slow_path_buf);
+        compose_slow_path(udpif, &xout, flow->in_port.odp_port, &buf);
+
+        ofpbuf_put(actions, buf.data, buf.size);
+    }
+
+    xlate_out_uninit(&xout);
+    return 0;
+}
diff --git a/ofproto/ofproto-dpif-upcall.h b/ofproto/ofproto-dpif-upcall.h
index 23e8fc7..b8ba557 100644
--- a/ofproto/ofproto-dpif-upcall.h
+++ b/ofproto/ofproto-dpif-upcall.h
@@ -38,4 +38,12 @@ void udpif_get_memory_usage(struct udpif *, struct simap *usage);
 struct seq *udpif_dump_seq(struct udpif *);
 void udpif_flush(struct udpif *);
 
+struct ofpbuf;
+struct flow;
+struct flow_wildcards;
+
+int ofproto_flow_lookup(const void *backer, struct ofpbuf *packet,
+                        struct flow *flow,
+                        struct flow_wildcards *wc, struct ofpbuf *actions);
+
 #endif /* ofproto-dpif-upcall.h */
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 3385cdd..6e2ea27 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -3249,3 +3249,37 @@ xlate_send_packet(const struct ofport_dpif *ofport, struct ofpbuf *packet)
                                         &output.ofpact, sizeof output,
                                         packet);
 }
+
+int
+xlate_lookup_port(const struct dpif_backer *backer, struct ofpbuf *packet,
+                  struct flow *flow, struct ofproto_dpif **ofproto)
+{
+    const struct xport *xport;
+    int error = ENODEV;
+
+    ovs_rwlock_rdlock(&xlate_rwlock);
+    xport = xport_lookup(tnl_port_should_receive(flow)
+                         ? tnl_port_receive(flow)
+                         : odp_port_to_ofport(backer, flow->in_port.odp_port));
+
+    flow->in_port.ofp_port = xport ? xport->ofp_port : OFPP_NONE;
+    if (!xport) {
+        goto exit;
+    }
+
+    if (vsp_adjust_flow(xport->xbridge->ofproto, flow)) {
+        if (packet) {
+            /* Make the packet resemble the flow, so that it gets sent to
+             * an OpenFlow controller properly, so that it looks correct
+             * for sFlow, and so that flow_extract() will get the correct
+             * vlan_tci if it is called on 'packet'. */
+            eth_push_vlan(packet, htons(ETH_TYPE_VLAN), flow->vlan_tci);
+        }
+    }
+    *ofproto = xport->xbridge->ofproto;
+    error = 0;
+
+exit:
+    ovs_rwlock_unlock(&xlate_rwlock);
+    return error;
+}
diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h
index 8b01d4e..0c4087a 100644
--- a/ofproto/ofproto-dpif-xlate.h
+++ b/ofproto/ofproto-dpif-xlate.h
@@ -169,4 +169,7 @@ void xlate_out_copy(struct xlate_out *dst, const struct xlate_out *src);
 
 int xlate_send_packet(const struct ofport_dpif *, struct ofpbuf *);
 
+int xlate_lookup_port(const struct dpif_backer *backer, struct ofpbuf *packet,
+                      struct flow *flow, struct ofproto_dpif **ofproto);
+
 #endif /* ofproto-dpif-xlate.h */
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index e42255f..22a67e4 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -797,6 +797,19 @@ struct odp_garbage {
 static bool check_variable_length_userdata(struct dpif_backer *backer);
 static size_t check_max_mpls_depth(struct dpif_backer *backer);
 
+static void
+set_ofproto_flow_lookup_cb(void)
+{
+    static bool initialized;
+
+    if (initialized) {
+        return;
+    }
+    fn_ofproto_flow_lookup = ofproto_flow_lookup;
+
+    initialized = true;
+}
+
 static int
 open_dpif_backer(const char *type, struct dpif_backer **backerp)
 {
@@ -1094,6 +1107,7 @@ construct(struct ofproto *ofproto_)
     error = add_internal_flows(ofproto);
     ofproto->up.tables[TBL_INTERNAL].flags = OFTABLE_HIDDEN | OFTABLE_READONLY;
 
+    set_ofproto_flow_lookup_cb();
     return error;
 }
 
-- 
1.7.9.5




More information about the dev mailing list