Define ofproto flow lookup function that can be used by dpif implementation.
Signed-off-by: Pravin B Shelar <pshe...@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 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev