In future patches, dpif-netdev will not create a flow key for each upcall. To accommodate this, we require callers to handle flow parsing themselves.
Signed-off-by: Ethan Jackson <et...@nicira.com> --- ofproto/ofproto-dpif-upcall.c | 30 ++++++++++++++++++++---------- ofproto/ofproto-dpif-xlate.c | 23 +++++++++-------------- ofproto/ofproto-dpif-xlate.h | 8 ++++---- ofproto/ofproto-dpif.c | 17 ++++++++++++----- 4 files changed, 45 insertions(+), 33 deletions(-) diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index b0fd203..3003455 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -858,9 +858,14 @@ convert_upcall(struct udpif *udpif, struct upcall *upcall) odp_port_t odp_in_port; int error; - error = xlate_receive(udpif->backer, dupcall->key, - dupcall->key_len, &flow, - &ofproto, &ipfix, &sflow, NULL, &odp_in_port); + if (odp_flow_key_to_flow(dupcall->key, dupcall->key_len, &flow) + == ODP_FIT_ERROR) { + error = EINVAL; + goto destroy_upcall; + } + + error = xlate_receive(udpif->backer, &flow, &ofproto, &ipfix, &sflow, NULL, + &odp_in_port); if (error) { if (error == ENODEV) { @@ -1238,8 +1243,13 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey, goto exit; } - error = xlate_receive(udpif->backer, ukey->key, ukey->key_len, &flow, - &ofproto, NULL, NULL, &netflow, &odp_in_port); + if (odp_flow_key_to_flow(ukey->key, ukey->key_len, &flow) + == ODP_FIT_ERROR) { + goto exit; + } + + error = xlate_receive(udpif->backer, &flow, &ofproto, NULL, NULL, &netflow, + &odp_in_port); if (error) { goto exit; } @@ -1355,7 +1365,6 @@ push_dump_ops__(struct udpif *udpif, struct dump_op *ops, size_t n_ops) struct netflow *netflow; struct flow flow; bool may_learn; - int error; may_learn = push->n_packets > 0; ovs_mutex_lock(&op->ukey->mutex); @@ -1366,10 +1375,11 @@ push_dump_ops__(struct udpif *udpif, struct dump_op *ops, size_t n_ops) } ovs_mutex_unlock(&op->ukey->mutex); - error = xlate_receive(udpif->backer, op->op.u.flow_del.key, - op->op.u.flow_del.key_len, &flow, &ofproto, - NULL, NULL, &netflow, NULL); - if (!error) { + if (odp_flow_key_to_flow(op->op.u.flow_del.key, + op->op.u.flow_del.key_len, + &flow) != ODP_FIT_ERROR + && !xlate_receive(udpif->backer, &flow, &ofproto, NULL, NULL, + &netflow, NULL)) { struct xlate_in xin; xlate_in_init(&xin, ofproto, &flow, NULL, push->tcp_flags, diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index f115849..a1d13c7 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -934,12 +934,11 @@ xlate_ofport_remove(struct ofport_dpif *ofport) xlate_xport_remove(new_xcfg, xport); } -/* Given a datpath and flow metadata ('backer', and 'key' respectively), - * populates 'flow' with the result of odp_flow_key_to_flow(). Optionally - * populates 'ofproto' with the ofproto_dpif, 'odp_in_port' with the datapath - * in_port, and 'ipfix', 'sflow', and 'netflow' with the appropriate handles - * for those protocols if they're enabled. Caller is responsible for unrefing - * them. +/* Given a datpath and flow metadata ('backer', and 'flow' respectively), + * Optionally populates 'ofproto' with the ofproto_dpif, 'odp_in_port' with the + * datapath in_port, and 'ipfix', 'sflow', and 'netflow' with the appropriate + * handles for those protocols if they're enabled. Caller is responsible for + * unrefing them. * * If 'ofproto' is nonnull, requires 'flow''s in_port to exist. Otherwise sets * 'flow''s in_port to OFPP_NONE. @@ -951,18 +950,14 @@ xlate_ofport_remove(struct ofport_dpif *ofport) * Returns 0 if successful, ENODEV if the parsed flow has no associated ofport, * or some other positive errno if there are other problems. */ int -xlate_receive(const struct dpif_backer *backer, const struct nlattr *key, - size_t key_len, struct flow *flow, struct ofproto_dpif **ofproto, - struct dpif_ipfix **ipfix, struct dpif_sflow **sflow, - struct netflow **netflow, odp_port_t *odp_in_port) +xlate_receive(const struct dpif_backer *backer, struct flow *flow, + struct ofproto_dpif **ofproto, struct dpif_ipfix **ipfix, + struct dpif_sflow **sflow, struct netflow **netflow, + odp_port_t *odp_in_port) { struct xlate_cfg *xcfg = ovsrcu_get(struct xlate_cfg *, &xcfgp); const struct xport *xport; - if (odp_flow_key_to_flow(key, key_len, flow) == ODP_FIT_ERROR) { - return EINVAL; - } - if (odp_in_port) { *odp_in_port = flow->in_port.odp_port; } diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h index 3522c0b..07586aa 100644 --- a/ofproto/ofproto-dpif-xlate.h +++ b/ofproto/ofproto-dpif-xlate.h @@ -173,10 +173,10 @@ void xlate_ofport_set(struct ofproto_dpif *, struct ofbundle *, bool may_enable); void xlate_ofport_remove(struct ofport_dpif *); -int xlate_receive(const struct dpif_backer *, const struct nlattr *key, - size_t key_len, struct flow *, struct ofproto_dpif **, - struct dpif_ipfix **, struct dpif_sflow **, - struct netflow **, odp_port_t *odp_in_port); +int xlate_receive(const struct dpif_backer *, struct flow *, + struct ofproto_dpif **, struct dpif_ipfix **, + struct dpif_sflow **, struct netflow **, + odp_port_t *odp_in_port); void xlate_actions(struct xlate_in *, struct xlate_out *); void xlate_in_init(struct xlate_in *, struct ofproto_dpif *, diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index c49f1fb..77cdce3 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -4205,9 +4205,13 @@ parse_flow_and_packet(int argc, const char *argv[], goto exit; } - if (xlate_receive(backer, ofpbuf_data(&odp_key), - ofpbuf_size(&odp_key), flow, - ofprotop, NULL, NULL, NULL, NULL)) { + if (odp_flow_key_to_flow(ofpbuf_data(&odp_key), ofpbuf_size(&odp_key), + flow) == ODP_FIT_ERROR) { + error = "Failed to parse flow key"; + goto exit; + } + + if (xlate_receive(backer, flow, ofprotop, NULL, NULL, NULL, NULL)) { error = "Invalid datapath flow"; goto exit; } @@ -4592,8 +4596,11 @@ ofproto_dpif_contains_flow(const struct ofproto_dpif *ofproto, struct ofproto_dpif *ofp; struct flow flow; - xlate_receive(ofproto->backer, key, key_len, &flow, &ofp, NULL, NULL, NULL, - NULL); + if (odp_flow_key_to_flow(key, key_len, &flow) == ODP_FIT_ERROR) { + return false; + } + + xlate_receive(ofproto->backer, &flow, &ofp, NULL, NULL, NULL, NULL); return ofp == ofproto; } -- 1.8.1.2 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev