From: Paul Blakey <[email protected]> Search all datapath added netdevs for a given flow using netdev flow api and parse it back to dpif flow.
Signed-off-by: Paul Blakey <[email protected]> Reviewed-by: Roi Dayan <[email protected]> Reviewed-by: Simon Horman <[email protected]> --- lib/dpif-netlink.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- lib/netdev.c | 21 +++++++++++++++++++++ lib/netdev.h | 5 +++++ 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index f959ed9..21b9a99 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -1986,6 +1986,45 @@ dpif_netlink_operate__(struct dpif_netlink *dpif, } static int +parse_flow_get(struct dpif_netlink *dpif, struct dpif_flow_get *get) +{ + struct dpif_flow *dpif_flow = get->flow; + struct match match; + struct nlattr *actions; + struct dpif_flow_stats stats; + struct ofpbuf buf; + uint64_t act_buf[1024 / 8]; + struct odputil_keybuf maskbuf; + struct odputil_keybuf keybuf; + struct odputil_keybuf actbuf; + struct ofpbuf key, mask, act; + int err; + + ofpbuf_use_stack(&buf, &act_buf, sizeof act_buf); + err = netdev_ports_flow_get(DPIF_HMAP_KEY(&dpif->dpif), &match, + &actions, get->ufid, &stats, &buf); + if (err) { + return err; + } + + VLOG_DBG("found flow from netdev, translating to dpif flow"); + + ofpbuf_use_stack(&key, &keybuf, sizeof keybuf); + ofpbuf_use_stack(&act, &actbuf, sizeof actbuf); + ofpbuf_use_stack(&mask, &maskbuf, sizeof maskbuf); + dpif_netlink_netdev_match_to_dpif_flow(&match, &key, &mask, actions, + &stats, + (ovs_u128 *) get->ufid, + dpif_flow, + false); + ofpbuf_put(get->buffer, nl_attr_get(actions), nl_attr_get_size(actions)); + dpif_flow->actions = ofpbuf_at(get->buffer, 0, 0); + dpif_flow->actions_len = nl_attr_get_size(actions); + + return 0; +} + +static int parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put) { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20); @@ -2157,7 +2196,17 @@ try_send_to_netdev(struct dpif_netlink *dpif, struct dpif_op *op) del->stats); break; } - case DPIF_OP_FLOW_GET: + case DPIF_OP_FLOW_GET: { + struct dpif_flow_get *get = &op->u.flow_get; + + if (!op->u.flow_get.ufid) { + break; + } + dbg_print_flow(get->key, get->key_len, NULL, 0, NULL, 0, + get->ufid, "GET"); + err = parse_flow_get(dpif, get); + break; + } case DPIF_OP_EXECUTE: default: break; diff --git a/lib/netdev.c b/lib/netdev.c index 4311c21..0aae83a 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -2324,6 +2324,27 @@ netdev_ports_flow_del(const void *obj, const ovs_u128 *ufid, return ENOENT; } +int +netdev_ports_flow_get(const void *obj, struct match *match, + struct nlattr **actions, + const ovs_u128 *ufid, + struct dpif_flow_stats *stats, + struct ofpbuf *buf) +{ + struct port_to_netdev_data *data; + + ovs_mutex_lock(&netdev_hmap_mutex); + HMAP_FOR_EACH(data, node, &port_to_netdev) { + if (data->obj == obj && !netdev_flow_get(data->netdev, match, actions, + ufid, stats, buf)) { + ovs_mutex_unlock(&netdev_hmap_mutex); + return 0; + } + } + ovs_mutex_unlock(&netdev_hmap_mutex); + return ENOENT; +} + #ifdef __linux__ void netdev_set_flow_api_enabled(const struct smap *ovs_other_config) diff --git a/lib/netdev.h b/lib/netdev.h index 2ddc595..31846fa 100644 --- a/lib/netdev.h +++ b/lib/netdev.h @@ -192,6 +192,11 @@ struct netdev_flow_dump **netdev_ports_flow_dump_create(const void *obj, void netdev_ports_flow_flush(const void *obj); int netdev_ports_flow_del(const void *obj, const ovs_u128 *ufid, struct dpif_flow_stats *stats); +int netdev_ports_flow_get(const void *obj, struct match *match, + struct nlattr **actions, + const ovs_u128 *ufid, + struct dpif_flow_stats *stats, + struct ofpbuf *buf); /* native tunnel APIs */ /* Structure to pass parameters required to build a tunnel header. */ -- 2.7.4 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
