[ovs-dev,v2,2/2] OVN: add icmp6 action to ovn acl reject support
diff mbox series

Message ID b1953bd176aacffd5adec39fbe70e6759bfe020e.1523266851.git.lorenzo.bianconi@redhat.com
State Accepted
Headers show
Series
  • add icmp6 action support to ovn acl framework
Related show

Commit Message

Lorenzo Bianconi April 9, 2018, 10 a.m. UTC
Whenever the acl reject rule is hit by an IPv6 packet send back
an ICMPv6 destination unreachable packet using the icmp6 action

Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
---
 NEWS                    |  4 ++++
 ovn/northd/ovn-northd.c | 25 ++++++++++++++++++++++---
 ovn/ovn-nb.xml          |  3 ++-
 tests/ovn.at            | 20 ++++++++++++++++++++
 4 files changed, 48 insertions(+), 4 deletions(-)

Patch
diff mbox series

diff --git a/NEWS b/NEWS
index 0cfcac54f..757d648a1 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,10 @@  Post-v2.9.0
      * OFPT_ROLE_STATUS is now available in OpenFlow 1.3.
    - Linux kernel 4.14
      * Add support for compiling OVS with the latest Linux 4.14 kernel
+   - ovn:
+     * implemented icmp4/icmp6/tcp_reset actions in order to drop the packet
+       and reply with a RST for TCP or ICMPv4/ICMPv6 unreachable message for
+       other IPv4/IPv6-based protocols whenever a reject ACL rule is hit.
 
 v2.9.0 - 19 Feb 2018
 --------------------
diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
index 9ca15bc2f..845faba86 100644
--- a/ovn/northd/ovn-northd.c
+++ b/ovn/northd/ovn-northd.c
@@ -2912,10 +2912,12 @@  build_pre_acls(struct ovn_datapath *od, struct hmap *lflows)
          * unreachable packets. */
         ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_ACL, 110,
                       "nd || nd_rs || nd_ra || icmp4.type == 3 || "
-                      "(tcp && tcp.flags == 4)", "next;");
+                      "icmp6.type == 1 || (tcp && tcp.flags == 4)",
+                      "next;");
         ovn_lflow_add(lflows, od, S_SWITCH_OUT_PRE_ACL, 110,
                       "nd || nd_rs || nd_ra || icmp4.type == 3 || "
-                      "(tcp && tcp.flags == 4)", "next;");
+                      "icmp6.type == 1 || (tcp && tcp.flags == 4)",
+                      "next;");
 
         /* Ingress and Egress Pre-ACL Table (Priority 100).
          *
@@ -3131,7 +3133,7 @@  build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows,
     ovn_lflow_add(lflows, od, stage, acl->priority + OVN_ACL_PRI_OFFSET + 10,
                   ds_cstr(&match), ds_cstr(&actions));
 
-    /* IPv4 traffic */
+    /* IP traffic */
     ds_clear(&match);
     ds_clear(&actions);
     build_acl_log(&actions, acl);
@@ -3148,6 +3150,23 @@  build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows,
                   ingress ? "output;" : "next(pipeline=ingress,table=0);");
     ovn_lflow_add(lflows, od, stage, acl->priority + OVN_ACL_PRI_OFFSET,
                   ds_cstr(&match), ds_cstr(&actions));
+    ds_clear(&match);
+    ds_clear(&actions);
+    build_acl_log(&actions, acl);
+    if (extra_match->length > 0) {
+        ds_put_format(&match, "(%s) && ", extra_match->string);
+    }
+    ds_put_format(&match, "ip6 && (%s)", acl->match);
+    if (extra_actions->length > 0) {
+        ds_put_format(&actions, "%s ", extra_actions->string);
+    }
+    ds_put_format(&actions, "reg0 = 0; icmp6 { "
+                  "eth.dst <-> eth.src; ip6.dst <-> ip6.src; "
+                  "outport <-> inport; %s };",
+                  ingress ? "output;" : "next(pipeline=ingress,table=0);");
+    ovn_lflow_add(lflows, od, stage, acl->priority + OVN_ACL_PRI_OFFSET,
+                  ds_cstr(&match), ds_cstr(&actions));
+
     ds_destroy(&match);
     ds_destroy(&actions);
 }
diff --git a/ovn/ovn-nb.xml b/ovn/ovn-nb.xml
index 2ebaac561..1f6e69e2d 100644
--- a/ovn/ovn-nb.xml
+++ b/ovn/ovn-nb.xml
@@ -1061,7 +1061,8 @@ 
 
         <li>
           <code>reject</code>: Drop the packet, replying with a RST for TCP or
-          ICMP unreachable message for other IP-based protocols.
+          ICMPv4/ICMPv6 unreachable message for other IPv4/IPv6-based
+          protocols.
         </li>
       </ul>
     </column>
diff --git a/tests/ovn.at b/tests/ovn.at
index 423c73c26..3bb9932f2 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -9412,6 +9412,24 @@  test_ip_packet() {
     as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
 }
 
+# test_ipv6_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST EXP_ICMP_CHKSUM
+#
+# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6 packet with
+# ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST as specified.
+# EXP_ICMP_CHKSUM is the icmp6 checksums of the icmp6 destination unreachable frame generated from ACL rule hit
+test_ipv6_packet() {
+    local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 exp_icmp_chksum=$7
+    shift 7
+
+    local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
+    local packet=${eth_dst}${eth_src}86dd${ip6_hdr}0000000000000000
+
+    local reply=${eth_src}${eth_dst}86dd6000000000303aff${ipv6_dst}${ipv6_src}0101${exp_icmp_chksum}00000000${ip6_hdr}
+    echo $reply >> vif$inport.expected
+
+    as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
+}
+
 # test_tcp_syn_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_IP_CHKSUM EXP_TCP_RST_CHKSUM
 #
 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
@@ -9486,6 +9504,8 @@  test_ip_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_
 test_ip_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 7d8d fcfe
 test_ip_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 7d82 fcfe
 
+test_ipv6_packet 11 1 000000000011 000000000021 fe80000000000000020001fffe000001 fe80000000000000020001fffe000002 6183
+
 test_tcp_syn_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 8b40 3039 0000 7d8d 4486
 test_tcp_syn_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 8b40 3039 0000 7d8d 4486
 test_tcp_syn_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 8b40 3039 0000 7d82 4486