773311
From 92f6a2f668708c677a8b10b0ac861bfd712f6a20 Mon Sep 17 00:00:00 2001
773311
Message-Id: <92f6a2f668708c677a8b10b0ac861bfd712f6a20.1590585469.git.lorenzo.bianconi@redhat.com>
773311
In-Reply-To: <d9ed450713eda62af1bec5009694b2d206c9f435.1590585469.git.lorenzo.bianconi@redhat.com>
773311
References: <d9ed450713eda62af1bec5009694b2d206c9f435.1590585469.git.lorenzo.bianconi@redhat.com>
773311
From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
773311
Date: Mon, 25 May 2020 18:31:27 +0200
773311
Subject: [PATCH ovn 3/3] northd: manage ARP request locally for FIP traffic
773311
773311
Modify 100-priority logical flows in Gateway Redirect table of
773311
logical router ingress pipeline (table 15) in order to manage ARP
773311
request locally for FIP traffic. In particular set reg1 and eth.src
773311
to NAT external ip and NAT external mac respectively and do not
773311
distribute ARP traffic using FIP
773311
773311
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
773311
---
773311
 northd/ovn-northd.8.xml | 10 +++++++---
773311
 northd/ovn-northd.c     | 23 ++++++++++++++++-------
773311
 tests/ovn.at            | 28 +++++++++++++++++++++++++---
773311
 tests/system-ovn.at     | 30 ++++++++++++++++++++++++++++++
773311
 4 files changed, 78 insertions(+), 13 deletions(-)
773311
773311
--- a/northd/ovn-northd.8.xml
773311
+++ b/northd/ovn-northd.8.xml
773311
@@ -2879,9 +2879,13 @@ icmp4 {
773311
         For each NAT rule in the OVN Northbound database that can
773311
         be handled in a distributed manner, a priority-100 logical
773311
         flow with match ip4.src == B &&
773311
-        outport == GW, where GW is
773311
-        the logical router distributed gateway port, with actions
773311
-        next;.
773311
+        outport == GW &&
773311
+        is_chassis_resident(P), where GW is
773311
+        the logical router distributed gateway port and P
773311
+        is the NAT logical port. IP traffic matching the above rule
773311
+        will be managed locally setting reg1 to C
773311
+        and eth.src to D, where C is NAT
773311
+        external ip and D is NAT external mac.
773311
       
773311
 
773311
       
  • 773311
    --- a/northd/ovn-northd.c
    773311
    +++ b/northd/ovn-northd.c
    773311
    @@ -9137,16 +9137,25 @@ build_lrouter_flows(struct hmap *datapat
    773311
                 /* Ingress Gateway Redirect Table: For NAT on a distributed
    773311
                  * router, add flows that are specific to a NAT rule.  These
    773311
                  * flows indicate the presence of an applicable NAT rule that
    773311
    -             * can be applied in a distributed manner. */
    773311
    +             * can be applied in a distributed manner.
    773311
    +             * In particulr reg1 and eth.src are set to NAT external IP and
    773311
    +             * NAT external mac so the ARP request generated in the following
    773311
    +             * stage is sent out with proper IP/MAC src addresses
    773311
    +             */
    773311
                 if (distributed) {
    773311
                     ds_clear(&match);
    773311
    -                ds_put_format(&match, "ip%s.src == %s && outport == %s",
    773311
    -                              is_v6 ? "6" : "4",
    773311
    -                              nat->logical_ip,
    773311
    -                              od->l3dgw_port->json_key);
    773311
    +                ds_clear(&actions);
    773311
    +                ds_put_format(&match,
    773311
    +                              "ip%s.src == %s && outport == %s && "
    773311
    +                              "is_chassis_resident(\"%s\")",
    773311
    +                              is_v6 ? "6" : "4", nat->logical_ip,
    773311
    +                              od->l3dgw_port->json_key, nat->logical_port);
    773311
    +                ds_put_format(&actions, "eth.src = %s; %sreg1 = %s; next;",
    773311
    +                              nat->external_mac, is_v6 ? "xx" : "",
    773311
    +                              nat->external_ip);
    773311
                     ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_GW_REDIRECT,
    773311
    -                                        100, ds_cstr(&match), "next;",
    773311
    -                                        &nat->header_);
    773311
    +                                        100, ds_cstr(&match),
    773311
    +                                        ds_cstr(&actions), &nat->header_);
    773311
                 }
    773311
     
    773311
                 /* Egress Loopback table: For NAT on a distributed router.
    773311
    --- a/tests/ovn.at
    773311
    +++ b/tests/ovn.at
    773311
    @@ -14353,9 +14353,14 @@ ovs-vsctl -- add-port br-int hv2-vif1 --
    773311
         set interface hv2-vif1 external-ids:iface-id=sw1-p0 \
    773311
         options:tx_pcap=hv2/vif1-tx.pcap \
    773311
         options:rxq_pcap=hv2/vif1-rx.pcap \
    773311
    -    ofport-request=1
    773311
    +    ofport-request=2
    773311
    +ovs-vsctl -- add-port br-int hv2-vif2 -- \
    773311
    +    set interface hv2-vif2 external-ids:iface-id=sw0-p1 \
    773311
    +    options:tx_pcap=hv2/vif2-tx.pcap \
    773311
    +    options:rxq_pcap=hv2/vif2-rx.pcap \
    773311
    +    ofport-request=3
    773311
     
    773311
    -ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
    773311
    +ovn-nbctl create Logical_Router name=lr0
    773311
     ovn-nbctl ls-add sw0
    773311
     ovn-nbctl ls-add sw1
    773311
     
    773311
    @@ -14364,13 +14369,16 @@ ovn-nbctl lsp-add sw0 rp-sw0 -- set Logi
    773311
         type=router options:router-port=sw0 \
    773311
         -- lsp-set-addresses rp-sw0 router
    773311
     
    773311
    -ovn-nbctl lrp-add lr0 sw1 00:00:02:01:02:03 172.16.1.1/24 2002:0:0:0:0:0:0:1/64
    773311
    +ovn-nbctl lrp-add lr0 sw1 00:00:02:01:02:03 172.16.1.1/24 2002:0:0:0:0:0:0:1/64 \
    773311
    +    -- set Logical_Router_Port sw1 options:redirect-chassis="hv2"
    773311
     ovn-nbctl lsp-add sw1 rp-sw1 -- set Logical_Switch_Port rp-sw1 \
    773311
         type=router options:router-port=sw1 \
    773311
         -- lsp-set-addresses rp-sw1 router
    773311
     
    773311
     ovn-nbctl lsp-add sw0 sw0-p0 \
    773311
         -- lsp-set-addresses sw0-p0 "f0:00:00:01:02:03 192.168.1.2 2001::2"
    773311
    +ovn-nbctl lsp-add sw0 sw0-p1 \
    773311
    +    -- lsp-set-addresses sw0-p1 "f0:00:00:11:02:03 192.168.1.3 2001::3"
    773311
     
    773311
     ovn-nbctl lsp-add sw1 sw1-p0 \
    773311
         -- lsp-set-addresses sw1-p0 unknown
    773311
    @@ -14416,6 +14424,20 @@ send_na 2 1 $dst_mac $router_mac1 $dst_i
    773311
     
    773311
     OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
    773311
     
    773311
    +# Create FIP on sw0-p0, add a route on logical router pipeline and
    773311
    +# ARP request for a unkwon destination is sent using FIP MAC/IP
    773311
    +ovn-nbctl lr-nat-add lr0 dnat_and_snat 172.16.1.2 192.168.1.3 sw0-p1 f0:00:00:01:02:04
    773311
    +ovn-nbctl lr-route-add lr0 172.16.2.0/24 172.16.1.11
    773311
    +
    773311
    +dst_ip=$(ip_to_hex 172 16 2 10)
    773311
    +fip_ip=$(ip_to_hex 172 16 1 2)
    773311
    +src_ip=$(ip_to_hex 192 168 1 3)
    773311
    +gw_router=$(ip_to_hex 172 16 1 11)
    773311
    +send_icmp_packet 2 2 f00000110203 $router_mac0 $src_ip $dst_ip 0000 $data
    773311
    +echo $(get_arp_req f00000010204 $fip_ip $gw_router) >> expected
    773311
    +
    773311
    +OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
    773311
    +
    773311
     OVN_CLEANUP([hv1],[hv2])
    773311
     AT_CLEANUP
    773311
     
    773311
    --- a/tests/system-ovn.at
    773311
    +++ b/tests/system-ovn.at
    773311
    @@ -2747,6 +2747,19 @@ ADD_VETH(alice1, alice1, br-int, "172.16
    773311
     ovn-nbctl lsp-add alice alice1 \
    773311
     -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.2"
    773311
     
    773311
    +# Add external network
    773311
    +ADD_NAMESPACES(ext-net)
    773311
    +AT_CHECK([ip link add alice-ext netns alice1 type veth peer name ext-veth netns ext-net])
    773311
    +NS_CHECK_EXEC([ext-net], [ip link set dev ext-veth up], [0], [])
    773311
    +NS_CHECK_EXEC([ext-net], [ip addr add 10.0.0.1/24 dev ext-veth], [0], [])
    773311
    +NS_CHECK_EXEC([ext-net], [ip route add default via 10.0.0.2], [0], [])
    773311
    +
    773311
    +NS_CHECK_EXEC([alice1], [ip link set dev alice-ext up], [0], [])
    773311
    +NS_CHECK_EXEC([alice1], [ip addr add 10.0.0.2/24 dev alice-ext], [0], [])
    773311
    +NS_CHECK_EXEC([alice1], [sysctl -w net.ipv4.conf.all.forwarding=1],[0], [dnl
    773311
    +net.ipv4.conf.all.forwarding = 1
    773311
    +])
    773311
    +
    773311
     # Add DNAT rules
    773311
     AT_CHECK([ovn-nbctl lr-nat-add R1 dnat_and_snat 172.16.1.3 192.168.1.2 foo1 00:00:02:02:03:04])
    773311
     AT_CHECK([ovn-nbctl lr-nat-add R1 dnat_and_snat 172.16.1.4 192.168.1.3 foo2 00:00:02:02:03:05])
    773311
    @@ -2754,6 +2767,9 @@ AT_CHECK([ovn-nbctl lr-nat-add R1 dnat_a
    773311
     # Add a SNAT rule
    773311
     AT_CHECK([ovn-nbctl lr-nat-add R1 snat 172.16.1.1 192.168.0.0/16])
    773311
     
    773311
    +# Add default route to ext-net
    773311
    +AT_CHECK([ovn-nbctl lr-route-add R1 10.0.0.0/24 172.16.1.2])
    773311
    +
    773311
     ovn-nbctl --wait=hv sync
    773311
     OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep 'nat(src=172.16.1.1)'])
    773311
     
    773311
    @@ -2797,6 +2813,20 @@ sed -e 's/zone=[[0-9]]*/zone=<cleared>/'
    773311
     icmp,orig=(src=192.168.2.2,dst=172.16.1.2,id=<cleared>,type=8,code=0),reply=(src=172.16.1.2,dst=172.16.1.1,id=<cleared>,type=0,code=0),zone=<cleared>
    773311
     ])
    773311
     
    773311
    +# Try to ping external network
    773311
    +NS_CHECK_EXEC([ext-net], [tcpdump -n -c 3 -i ext-veth dst 172.16.1.3 and icmp > ext-net.pcap &])
    773311
    +sleep 1
    773311
    +AT_CHECK([ovn-nbctl lr-nat-del R1 snat])
    773311
    +NS_CHECK_EXEC([foo1], [ping -q -c 3 -i 0.3 -w 2 10.0.0.1 | FORMAT_PING], \
    773311
    +[0], [dnl
    773311
    +3 packets transmitted, 3 received, 0% packet loss, time 0ms
    773311
    +])
    773311
    +
    773311
    +OVS_WAIT_UNTIL([
    773311
    +    total_pkts=$(cat ext-net.pcap | wc -l)
    773311
    +    test "${total_pkts}" = "3"
    773311
    +])
    773311
    +
    773311
     OVS_APP_EXIT_AND_WAIT([ovn-controller])
    773311
     
    773311
     as ovn-sb