diff mbox series

[ovs-dev,v2,4/4] netdev-offload-tc: Expand tunnel source IPs masked match

Message ID 20200602135025.20704-5-xiangxia.m.yue@gmail.com
State Accepted
Commit 3f82ac1fe36d6d8ad9b21750e7d878394f031147
Headers show
Series netdev-offload-tc: Allow to match the IP and port mask of tunnel | expand

Commit Message

Tonghao Zhang June 2, 2020, 1:50 p.m. UTC
From: Tonghao Zhang <xiangxia.m.yue@gmail.com>

To support more use case, for example, DDOS, which
packets should be dropped in hardware, this patch
allows users to match only the tunnel source IPs with
masked value.

$ ovs-appctl dpctl/add-flow "tunnel(src=2.2.2.0/255.255.255.0,tp_dst=4789,ttl=64),\
  recirc_id(2),in_port(3),eth(),eth_type(0x0800),ipv4()" ""

$ ovs-appctl dpctl/dump-flows
  tunnel(src=2.2.2.0/255.255.255.0,ttl=64,tp_dst=4789) ... actions:drop
$ tc filter show dev vxlan_sys_4789 ingress
  ...
  eth_type ipv4
  enc_src_ip 2.2.2.0/24
  enc_dst_port 4789
  enc_ttl 64
  in_hw in_hw_count 2
    action order 1: gact action drop
    ...

Cc: Simon Horman <simon.horman@netronome.com>
Cc: Paul Blakey <paulb@mellanox.com>
Cc: Roi Dayan <roid@mellanox.com>
Cc: Ben Pfaff <blp@ovn.org>
Cc: William Tu <u9012063@gmail.com>
Cc: Ilya Maximets <i.maximets@ovn.org>
Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com>
Acked-by: Roi Dayan <roid@mellanox.com>
---
 lib/netdev-offload-tc.c | 9 ++++++---
 lib/odp-util.c          | 3 ++-
 lib/packets.h           | 6 ++++++
 3 files changed, 14 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
index 8ba22312ec00..f7f9c231e3cf 100644
--- a/lib/netdev-offload-tc.c
+++ b/lib/netdev-offload-tc.c
@@ -633,14 +633,16 @@  parse_tc_flower_to_match(struct tc_flower *flower,
             match_set_tun_id(match, flower->key.tunnel.id);
             match->flow.tunnel.flags |= FLOW_TNL_F_KEY;
         }
-        if (flower->mask.tunnel.ipv4.ipv4_dst) {
+        if (flower->mask.tunnel.ipv4.ipv4_dst ||
+            flower->mask.tunnel.ipv4.ipv4_src) {
             match_set_tun_dst_masked(match,
                                      flower->key.tunnel.ipv4.ipv4_dst,
                                      flower->mask.tunnel.ipv4.ipv4_dst);
             match_set_tun_src_masked(match,
                                      flower->key.tunnel.ipv4.ipv4_src,
                                      flower->mask.tunnel.ipv4.ipv4_src);
-        } else if (ipv6_addr_is_set(&flower->mask.tunnel.ipv6.ipv6_dst)) {
+        } else if (ipv6_addr_is_set(&flower->mask.tunnel.ipv6.ipv6_dst) ||
+                   ipv6_addr_is_set(&flower->mask.tunnel.ipv6.ipv6_src)) {
             match_set_tun_ipv6_dst_masked(match,
                                           &flower->key.tunnel.ipv6.ipv6_dst,
                                           &flower->mask.tunnel.ipv6.ipv6_dst);
@@ -1400,7 +1402,8 @@  netdev_tc_flow_put(struct netdev *netdev, struct match *match,
     chain = key->recirc_id;
     mask->recirc_id = 0;
 
-    if (flow_tnl_dst_is_set(&key->tunnel)) {
+    if (flow_tnl_dst_is_set(&key->tunnel) ||
+        flow_tnl_src_is_set(&key->tunnel)) {
         VLOG_DBG_RL(&rl,
                     "tunnel: id %#" PRIx64 " src " IP_FMT
                     " dst " IP_FMT " tp_src %d tp_dst %d",
diff --git a/lib/odp-util.c b/lib/odp-util.c
index b66d266cca1d..72601dc6ba2b 100644
--- a/lib/odp-util.c
+++ b/lib/odp-util.c
@@ -6125,7 +6125,8 @@  odp_flow_key_from_flow__(const struct odp_flow_key_parms *parms,
 
     nl_msg_put_u32(buf, OVS_KEY_ATTR_PRIORITY, data->skb_priority);
 
-    if (flow_tnl_dst_is_set(&flow->tunnel) || export_mask) {
+    if (flow_tnl_dst_is_set(&flow->tunnel) ||
+        flow_tnl_src_is_set(&flow->tunnel) || export_mask) {
         tun_key_to_attr(buf, &data->tunnel, &parms->flow->tunnel,
                         parms->key_buf, NULL);
     }
diff --git a/lib/packets.h b/lib/packets.h
index 447e6f6fafa5..395bc869eb00 100644
--- a/lib/packets.h
+++ b/lib/packets.h
@@ -52,6 +52,12 @@  flow_tnl_dst_is_set(const struct flow_tnl *tnl)
     return tnl->ip_dst || ipv6_addr_is_set(&tnl->ipv6_dst);
 }
 
+static inline bool
+flow_tnl_src_is_set(const struct flow_tnl *tnl)
+{
+    return tnl->ip_src || ipv6_addr_is_set(&tnl->ipv6_src);
+}
+
 struct in6_addr flow_tnl_dst(const struct flow_tnl *tnl);
 struct in6_addr flow_tnl_src(const struct flow_tnl *tnl);