From patchwork Tue Aug 11 07:34:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Numan Siddique X-Patchwork-Id: 1343187 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.138; helo=whitealder.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ovn.org Received: from whitealder.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BQl2p0TsVz9sTR for ; Tue, 11 Aug 2020 17:34:25 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id EC9FB876FB; Tue, 11 Aug 2020 07:34:22 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from whitealder.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id yxzuGTQ3GGqR; Tue, 11 Aug 2020 07:34:21 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by whitealder.osuosl.org (Postfix) with ESMTP id 9AFF3862E1; Tue, 11 Aug 2020 07:34:21 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 7A161C07FF; Tue, 11 Aug 2020 07:34:21 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id D97C7C004D for ; Tue, 11 Aug 2020 07:34:19 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by silver.osuosl.org (Postfix) with ESMTP id AB08B2043E for ; Tue, 11 Aug 2020 07:34:19 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from silver.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id e+Miga5ZIuRv for ; Tue, 11 Aug 2020 07:34:17 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net [217.70.183.195]) by silver.osuosl.org (Postfix) with ESMTPS id 634222041C for ; Tue, 11 Aug 2020 07:34:15 +0000 (UTC) X-Originating-IP: 60.243.255.170 Received: from nusiddiq.home.org.com (unknown [60.243.255.170]) (Authenticated sender: numans@ovn.org) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 478A560010; Tue, 11 Aug 2020 07:34:10 +0000 (UTC) From: numans@ovn.org To: dev@openvswitch.org Date: Tue, 11 Aug 2020 13:04:04 +0530 Message-Id: <20200811073404.2154888-1-numans@ovn.org> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 Cc: Alexander Constantinescu Subject: [ovs-dev] [PATCH ovn] ovn-northd: Add ARP responder flows for SNAT entries. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: Numan Siddique If the below SNAT entry is added: ovn-nbctl lr-nat-add snat 172.168.0.120 10.0.0.5 And when the logical port with IP - 10.0.0.5, sends a packet destined to outside, gets SNATted to 172.168.0.120 as expected, but for the reverse traffic if the upstream switch sends an ARP request for 172.168.0.120, then OVN doesn't reply and the reply traffic never reaches the logical port. This patch fixes this issue by addding ARP responder flows for SNAT entries. Note that, if 172.168.0.120 happens to be the logical router IP, then it works. Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=1861294 Reported-by: Alexander Constantinescu Signed-off-by: Numan Siddique --- northd/ovn-northd.8.xml | 18 +++++++++--------- northd/ovn-northd.c | 14 ++++++++++++-- tests/ovn-northd.at | 8 ++++++++ 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml index 20fd19450..ee21c825d 100644 --- a/northd/ovn-northd.8.xml +++ b/northd/ovn-northd.8.xml @@ -1952,15 +1952,15 @@ nd_na_router {
  • These flows reply to ARP requests or IPv6 neighbor solicitation - for the virtual IP addresses configured in the router for DNAT - or load balancing. + for the virtual IP addresses configured in the router for NAT + (both DNAT and SNAT) or load balancing.

    - IPv4: For a configured DNAT IP address or a load balancer - IPv4 VIP A, for each router port P with - Ethernet address E, a priority-90 flow matches - arp.op == 1 && arp.tpa == A + IPv4: For a configured NAT (both DNAT and SNAT) IP address or a + load balancer IPv4 VIP A, for each router port + P with Ethernet address E, a priority-90 flow + matches arp.op == 1 && arp.tpa == A (ARP request) with the following actions:

    @@ -1990,9 +1990,9 @@ output;

    - IPv6: For a configured DNAT IP address or a load balancer - IPv6 VIP A, solicited node address S, - for each router port P with + IPv6: For a configured NAT (both DNAT and SNAT) IP address or a + load balancer IPv6 VIP A, solicited node address + S, for each router port P with Ethernet address E, a priority-90 flow matches inport == P && nd_ns && ip6.dst == {A, S} && diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index 99eb582c3..3b0272b00 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -8648,6 +8648,7 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, * per logical port but DNAT addresses can be handled per datapath * for non gateway router ports. */ + struct sset snat_ips = SSET_INITIALIZER(&snat_ips); for (int i = 0; i < od->nbr->n_nat; i++) { struct ovn_nat *nat_entry = &od->nat_entries[i]; const struct nbrec_nat *nat = nat_entry->nb; @@ -8657,15 +8658,22 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, continue; } + struct lport_addresses *ext_addrs = &nat_entry->ext_addrs; + char *ext_addr = nat_entry_is_v6(nat_entry) ? + ext_addrs->ipv6_addrs[0].addr_s : + ext_addrs->ipv4_addrs[0].addr_s; + if (!strcmp(nat->type, "snat")) { - continue; + if (sset_contains(&snat_ips, ext_addr)) { + continue; + } + sset_add(&snat_ips, ext_addr); } /* Priority 91 and 92 flows are added for each gateway router * port to handle the special cases. In case we get the packet * on a regular port, just reply with the port's ETH address. */ - struct lport_addresses *ext_addrs = &nat_entry->ext_addrs; if (nat_entry_is_v6(nat_entry)) { build_lrouter_nd_flow(od, NULL, "nd_na", ext_addrs->ipv6_addrs[0].addr_s, @@ -8679,6 +8687,8 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, &nat->header_, lflows); } } + sset_destroy(&snat_ips); + /* Drop ARP packets (priority 85). ARP request packets for router's own * IPs are handled with priority-90 flows. diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index 7872d5051..8344c7f5e 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -1572,6 +1572,8 @@ ovn-nbctl set logical_router lr options:chassis=ch ovn-nbctl lr-nat-add lr dnat_and_snat 43.43.43.2 42.42.42.2 ovn-nbctl lr-nat-add lr dnat 43.43.43.3 42.42.42.3 ovn-nbctl lr-nat-add lr dnat_and_snat 43.43.43.4 42.42.42.4 ls-vm 00:00:00:00:00:02 +ovn-nbctl lr-nat-add lr snat 43.43.43.150 43.43.43.50 +ovn-nbctl lr-nat-add lr snat 43.43.43.150 43.43.43.51 ovn-nbctl --wait=sb sync @@ -1594,6 +1596,9 @@ action=(xreg0[[0..47]] = 00:00:00:00:01:00; next;) # Ingress router port ETH address is used for ARP reply/NA in lr_in_ip_input. AT_CHECK([ovn-sbctl lflow-list | grep -E "lr_in_ip_input.*priority=90" | grep "arp\|nd" | sort], [0], [dnl table=3 (lr_in_ip_input ), priority=90 , dnl +match=(arp.op == 1 && arp.tpa == 43.43.43.150), dnl +action=(eth.dst = eth.src; eth.src = xreg0[[0..47]]; arp.op = 2; /* ARP reply */ arp.tha = arp.sha; arp.sha = xreg0[[0..47]]; arp.tpa = arp.spa; arp.spa = 43.43.43.150; outport = inport; flags.loopback = 1; output;) + table=3 (lr_in_ip_input ), priority=90 , dnl match=(arp.op == 1 && arp.tpa == 43.43.43.2), dnl action=(eth.dst = eth.src; eth.src = xreg0[[0..47]]; arp.op = 2; /* ARP reply */ arp.tha = arp.sha; arp.sha = xreg0[[0..47]]; arp.tpa = arp.spa; arp.spa = 43.43.43.2; outport = inport; flags.loopback = 1; output;) table=3 (lr_in_ip_input ), priority=90 , dnl @@ -1648,6 +1653,9 @@ action=(xreg0[[0..47]] = 00:00:00:00:01:00; next;) # Priority 90 flows (per router). AT_CHECK([ovn-sbctl lflow-list | grep -E "lr_in_ip_input.*priority=90" | grep "arp\|nd" | sort], [0], [dnl table=3 (lr_in_ip_input ), priority=90 , dnl +match=(arp.op == 1 && arp.tpa == 43.43.43.150), dnl +action=(eth.dst = eth.src; eth.src = xreg0[[0..47]]; arp.op = 2; /* ARP reply */ arp.tha = arp.sha; arp.sha = xreg0[[0..47]]; arp.tpa = arp.spa; arp.spa = 43.43.43.150; outport = inport; flags.loopback = 1; output;) + table=3 (lr_in_ip_input ), priority=90 , dnl match=(arp.op == 1 && arp.tpa == 43.43.43.2), dnl action=(eth.dst = eth.src; eth.src = xreg0[[0..47]]; arp.op = 2; /* ARP reply */ arp.tha = arp.sha; arp.sha = xreg0[[0..47]]; arp.tpa = arp.spa; arp.spa = 43.43.43.2; outport = inport; flags.loopback = 1; output;) table=3 (lr_in_ip_input ), priority=90 , dnl