Re: [ovs-dev] [PATCH V10 15/33] netdev-tc-offloads: Implement netdev flow dump api using tc interface

2017-06-13 Thread Roi Dayan



On 08/06/2017 14:46, Roi Dayan wrote:

From: Paul Blakey 

Signed-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

2017-06-09 Thread Flavio Leitner
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

2017-06-08 Thread Roi Dayan
From: Paul Blakey 

Signed-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);
+
+