Re: [ovs-dev] [PATCH V10 15/33] netdev-tc-offloads: Implement netdev flow dump api using tc interface
On 08/06/2017 14:46, Roi Dayan wrote: From: Paul BlakeySigned-off-by: Paul Blakey Reviewed-by: Roi Dayan Reviewed-by: Simon Horman --- lib/netdev-tc-offloads.c | 186 --- 1 file changed, 177 insertions(+), 9 deletions(-) diff --git a/lib/netdev-tc-offloads.c b/lib/netdev-tc-offloads.c index 0786048..4b14c5c 100644 --- a/lib/netdev-tc-offloads.c +++ b/lib/netdev-tc-offloads.c @@ -150,7 +150,7 @@ get_ufid_tc_mapping(const ovs_u128 *ufid, int *prio, struct netdev **netdev) * * Returns true on success. */ -static bool OVS_UNUSED +static bool find_ufid(int prio, int handle, struct netdev *netdev, ovs_u128 *ufid) { int ifindex = netdev_get_ifindex(netdev); @@ -188,9 +188,20 @@ int netdev_tc_flow_dump_create(struct netdev *netdev, struct netdev_flow_dump **dump_out) { -struct netdev_flow_dump *dump = xzalloc(sizeof *dump); +struct netdev_flow_dump *dump; +int ifindex; + +ifindex = netdev_get_ifindex(netdev); +if (ifindex < 0) { +VLOG_ERR_RL(_rl, "failed to get ifindex for %s: %s", +netdev_get_name(netdev), ovs_strerror(-ifindex)); +return -ifindex; +} +dump = xzalloc(sizeof *dump); +dump->nl_dump = xzalloc(sizeof *dump->nl_dump); dump->netdev = netdev_ref(netdev); +tc_dump_flower_start(ifindex, dump->nl_dump); *dump_out = dump; @@ -200,21 +211,178 @@ netdev_tc_flow_dump_create(struct netdev *netdev, int netdev_tc_flow_dump_destroy(struct netdev_flow_dump *dump) { +nl_dump_done(dump->nl_dump); netdev_close(dump->netdev); +free(dump->nl_dump); free(dump); +return 0; +} + +static int +parse_tc_flower_to_match(struct tc_flower *flower, + struct match *match, + struct nlattr **actions, + struct dpif_flow_stats *stats, + struct ofpbuf *buf) { +size_t act_off; +struct tc_flower_key *key = >key; +struct tc_flower_key *mask = >mask; +odp_port_t outport = 0; + +if (flower->ifindex_out) { +outport = netdev_ifindex_to_odp_port(flower->ifindex_out); +if (!outport) { +return ENOENT; +} +} + +ofpbuf_clear(buf); + +match_init_catchall(match); +match_set_dl_type(match, key->eth_type); +match_set_dl_src_masked(match, key->src_mac, mask->src_mac); +match_set_dl_dst_masked(match, key->dst_mac, mask->dst_mac); +if (key->vlan_id || key->vlan_prio) { we should probably check if key->eth_type is vlan eth type. +match_set_dl_vlan(match, htons(key->vlan_id)); +match_set_dl_vlan_pcp(match, key->vlan_prio); +match_set_dl_type(match, key->encap_eth_type); +} + +if (key->ip_proto && +(key->eth_type == htons(ETH_P_IP) + || key->eth_type == htons(ETH_P_IPV6))) { we missed here. key is flower key and for vlan this will be vlan eth type so we need to compare to match->dl_type which is little up being set to the encap eth type if in vlan. +match_set_nw_proto(match, key->ip_proto); +} + +match_set_nw_src_masked(match, key->ipv4.ipv4_src, mask->ipv4.ipv4_src); +match_set_nw_dst_masked(match, key->ipv4.ipv4_dst, mask->ipv4.ipv4_dst); + +match_set_ipv6_src_masked(match, + >ipv6.ipv6_src, >ipv6.ipv6_src); +match_set_ipv6_dst_masked(match, + >ipv6.ipv6_dst, >ipv6.ipv6_dst); + +match_set_tp_dst_masked(match, key->dst_port, mask->dst_port); +match_set_tp_src_masked(match, key->src_port, mask->src_port); + +if (flower->tunnel.tunnel) { +match_set_tun_id(match, flower->tunnel.id); +if (flower->tunnel.ipv4.ipv4_dst) { +match_set_tun_src(match, flower->tunnel.ipv4.ipv4_src); +match_set_tun_dst(match, flower->tunnel.ipv4.ipv4_dst); +} else if (!is_all_zeros(>tunnel.ipv6.ipv6_dst, + sizeof flower->tunnel.ipv6.ipv6_dst)) { +match_set_tun_ipv6_src(match, >tunnel.ipv6.ipv6_src); +match_set_tun_ipv6_dst(match, >tunnel.ipv6.ipv6_dst); +} +if (flower->tunnel.tp_dst) { +match_set_tun_tp_dst(match, flower->tunnel.tp_dst); +} +} + +act_off = nl_msg_start_nested(buf, OVS_FLOW_ATTR_ACTIONS); +{ +if (flower->vlan_pop) { +nl_msg_put_flag(buf, OVS_ACTION_ATTR_POP_VLAN); +} + +if (flower->vlan_push_id || flower->vlan_push_prio) { +struct ovs_action_push_vlan *push; +push = nl_msg_put_unspec_zero(buf, OVS_ACTION_ATTR_PUSH_VLAN, + sizeof *push); + +push->vlan_tpid = htons(ETH_TYPE_VLAN); +push->vlan_tci = htons(flower->vlan_push_id + | (flower->vlan_push_prio << 13)
Re: [ovs-dev] [PATCH V10 15/33] netdev-tc-offloads: Implement netdev flow dump api using tc interface
On Thu, Jun 08, 2017 at 02:46:32PM +0300, Roi Dayan wrote: > From: Paul Blakey> > Signed-off-by: Paul Blakey > Reviewed-by: Roi Dayan > Reviewed-by: Simon Horman > --- Acked-by: Flavio Leitner ___ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev
[ovs-dev] [PATCH V10 15/33] netdev-tc-offloads: Implement netdev flow dump api using tc interface
From: Paul BlakeySigned-off-by: Paul Blakey Reviewed-by: Roi Dayan Reviewed-by: Simon Horman --- lib/netdev-tc-offloads.c | 186 --- 1 file changed, 177 insertions(+), 9 deletions(-) diff --git a/lib/netdev-tc-offloads.c b/lib/netdev-tc-offloads.c index 0786048..4b14c5c 100644 --- a/lib/netdev-tc-offloads.c +++ b/lib/netdev-tc-offloads.c @@ -150,7 +150,7 @@ get_ufid_tc_mapping(const ovs_u128 *ufid, int *prio, struct netdev **netdev) * * Returns true on success. */ -static bool OVS_UNUSED +static bool find_ufid(int prio, int handle, struct netdev *netdev, ovs_u128 *ufid) { int ifindex = netdev_get_ifindex(netdev); @@ -188,9 +188,20 @@ int netdev_tc_flow_dump_create(struct netdev *netdev, struct netdev_flow_dump **dump_out) { -struct netdev_flow_dump *dump = xzalloc(sizeof *dump); +struct netdev_flow_dump *dump; +int ifindex; + +ifindex = netdev_get_ifindex(netdev); +if (ifindex < 0) { +VLOG_ERR_RL(_rl, "failed to get ifindex for %s: %s", +netdev_get_name(netdev), ovs_strerror(-ifindex)); +return -ifindex; +} +dump = xzalloc(sizeof *dump); +dump->nl_dump = xzalloc(sizeof *dump->nl_dump); dump->netdev = netdev_ref(netdev); +tc_dump_flower_start(ifindex, dump->nl_dump); *dump_out = dump; @@ -200,21 +211,178 @@ netdev_tc_flow_dump_create(struct netdev *netdev, int netdev_tc_flow_dump_destroy(struct netdev_flow_dump *dump) { +nl_dump_done(dump->nl_dump); netdev_close(dump->netdev); +free(dump->nl_dump); free(dump); +return 0; +} + +static int +parse_tc_flower_to_match(struct tc_flower *flower, + struct match *match, + struct nlattr **actions, + struct dpif_flow_stats *stats, + struct ofpbuf *buf) { +size_t act_off; +struct tc_flower_key *key = >key; +struct tc_flower_key *mask = >mask; +odp_port_t outport = 0; + +if (flower->ifindex_out) { +outport = netdev_ifindex_to_odp_port(flower->ifindex_out); +if (!outport) { +return ENOENT; +} +} + +ofpbuf_clear(buf); + +match_init_catchall(match); +match_set_dl_type(match, key->eth_type); +match_set_dl_src_masked(match, key->src_mac, mask->src_mac); +match_set_dl_dst_masked(match, key->dst_mac, mask->dst_mac); +if (key->vlan_id || key->vlan_prio) { +match_set_dl_vlan(match, htons(key->vlan_id)); +match_set_dl_vlan_pcp(match, key->vlan_prio); +match_set_dl_type(match, key->encap_eth_type); +} + +if (key->ip_proto && +(key->eth_type == htons(ETH_P_IP) + || key->eth_type == htons(ETH_P_IPV6))) { +match_set_nw_proto(match, key->ip_proto); +} + +match_set_nw_src_masked(match, key->ipv4.ipv4_src, mask->ipv4.ipv4_src); +match_set_nw_dst_masked(match, key->ipv4.ipv4_dst, mask->ipv4.ipv4_dst); + +match_set_ipv6_src_masked(match, + >ipv6.ipv6_src, >ipv6.ipv6_src); +match_set_ipv6_dst_masked(match, + >ipv6.ipv6_dst, >ipv6.ipv6_dst); + +match_set_tp_dst_masked(match, key->dst_port, mask->dst_port); +match_set_tp_src_masked(match, key->src_port, mask->src_port); + +if (flower->tunnel.tunnel) { +match_set_tun_id(match, flower->tunnel.id); +if (flower->tunnel.ipv4.ipv4_dst) { +match_set_tun_src(match, flower->tunnel.ipv4.ipv4_src); +match_set_tun_dst(match, flower->tunnel.ipv4.ipv4_dst); +} else if (!is_all_zeros(>tunnel.ipv6.ipv6_dst, + sizeof flower->tunnel.ipv6.ipv6_dst)) { +match_set_tun_ipv6_src(match, >tunnel.ipv6.ipv6_src); +match_set_tun_ipv6_dst(match, >tunnel.ipv6.ipv6_dst); +} +if (flower->tunnel.tp_dst) { +match_set_tun_tp_dst(match, flower->tunnel.tp_dst); +} +} + +act_off = nl_msg_start_nested(buf, OVS_FLOW_ATTR_ACTIONS); +{ +if (flower->vlan_pop) { +nl_msg_put_flag(buf, OVS_ACTION_ATTR_POP_VLAN); +} + +if (flower->vlan_push_id || flower->vlan_push_prio) { +struct ovs_action_push_vlan *push; +push = nl_msg_put_unspec_zero(buf, OVS_ACTION_ATTR_PUSH_VLAN, + sizeof *push); + +push->vlan_tpid = htons(ETH_TYPE_VLAN); +push->vlan_tci = htons(flower->vlan_push_id + | (flower->vlan_push_prio << 13) + | VLAN_CFI); +} + +if (flower->set.set) { +size_t set_offset = nl_msg_start_nested(buf, OVS_ACTION_ATTR_SET); +size_t tunnel_offset = +nl_msg_start_nested(buf, OVS_KEY_ATTR_TUNNEL); + +