[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