From patchwork Thu Sep 17 12:51:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dumitru Ceara X-Patchwork-Id: 1366104 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=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=LZmkVUD6; dkim-atps=neutral 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 4BscKb5Wsvz9sS8 for ; Thu, 17 Sep 2020 22:51:30 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by whitealder.osuosl.org (Postfix) with ESMTP id 2F53F878B7; Thu, 17 Sep 2020 12:51:29 +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 YofILjxT9Oy3; Thu, 17 Sep 2020 12:51:25 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by whitealder.osuosl.org (Postfix) with ESMTP id 83E85878BE; Thu, 17 Sep 2020 12:51:25 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 5CCE5C0864; Thu, 17 Sep 2020 12:51:25 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from fraxinus.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 72EF0C0864 for ; Thu, 17 Sep 2020 12:51:23 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by fraxinus.osuosl.org (Postfix) with ESMTP id 6F8E487029 for ; Thu, 17 Sep 2020 12:51:23 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from fraxinus.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id lKcfj05AR_te for ; Thu, 17 Sep 2020 12:51:22 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by fraxinus.osuosl.org (Postfix) with ESMTPS id 5A1AB87034 for ; Thu, 17 Sep 2020 12:51:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1600347081; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=yGMXlPFfuHUKM97Uj8Gj752w7wDZ+R6iV4FqcQU4+zI=; b=LZmkVUD6gvgDn9ALwjnnOpujcGo4o2+a+TUF9BBuuNOoXm1xC87xLd5Zdy9NjMs9thXA/H QmPuumzRO8f6QQgn4p5H3AzlS8rTyQN8uL7Aa0Fh57eJ3apJQ/TjXm2ItxkdgZ98ffrDnm wadF0IguowKlxPeoqbJ+Svl3X5vnA8U= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-171-NIKcb7_dPbK75n7xWT9C0Q-1; Thu, 17 Sep 2020 08:51:17 -0400 X-MC-Unique: NIKcb7_dPbK75n7xWT9C0Q-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id B53E11006714 for ; Thu, 17 Sep 2020 12:51:16 +0000 (UTC) Received: from dceara.remote.csb (ovpn-113-244.ams2.redhat.com [10.36.113.244]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3F1802C31E for ; Thu, 17 Sep 2020 12:51:16 +0000 (UTC) From: Dumitru Ceara To: dev@openvswitch.org Date: Thu, 17 Sep 2020 14:51:09 +0200 Message-Id: <20200917125102.19729.95989.stgit@dceara.remote.csb> In-Reply-To: <20200917125025.19729.19409.stgit@dceara.remote.csb> References: <20200917125025.19729.19409.stgit@dceara.remote.csb> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=dceara@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH v3 ovn 2/4] ovn-northd: Move NAT ARP/ND resolution to separate functions. 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" To avoid duplicating code later on, move out the code that generates ARP/ND replies for NAT external IPs to separate functions. Signed-off-by: Dumitru Ceara Acked-by: Han Zhou --- northd/ovn-northd.c | 172 ++++++++++++++++++++++++++++----------------------- 1 file changed, 94 insertions(+), 78 deletions(-) diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index d5d7631..f79ed99 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -8636,6 +8636,94 @@ build_lrouter_nd_flow(struct ovn_datapath *od, struct ovn_port *op, } static void +build_lrouter_nat_arp_nd_flow(struct ovn_datapath *od, + struct ovn_nat *nat_entry, + struct hmap *lflows) +{ + struct lport_addresses *ext_addrs = &nat_entry->ext_addrs; + const struct nbrec_nat *nat = nat_entry->nb; + + if (nat_entry_is_v6(nat_entry)) { + build_lrouter_nd_flow(od, NULL, "nd_na", + ext_addrs->ipv6_addrs[0].addr_s, + ext_addrs->ipv6_addrs[0].sn_addr_s, + REG_INPORT_ETH_ADDR, NULL, false, 90, + &nat->header_, lflows); + } else { + build_lrouter_arp_flow(od, NULL, + ext_addrs->ipv4_addrs[0].addr_s, + REG_INPORT_ETH_ADDR, NULL, false, 90, + &nat->header_, lflows); + } +} + +static void +build_lrouter_port_nat_arp_nd_flow(struct ovn_port *op, + struct ovn_nat *nat_entry, + struct hmap *lflows) +{ + struct lport_addresses *ext_addrs = &nat_entry->ext_addrs; + const struct nbrec_nat *nat = nat_entry->nb; + struct ds match = DS_EMPTY_INITIALIZER; + + /* Mac address to use when replying to ARP/NS. */ + const char *mac_s = REG_INPORT_ETH_ADDR; + struct eth_addr mac; + + if (nat->external_mac && + eth_addr_from_string(nat->external_mac, &mac) + && nat->logical_port) { + /* distributed NAT case, use nat->external_mac */ + mac_s = nat->external_mac; + /* Traffic with eth.src = nat->external_mac should only be + * sent from the chassis where nat->logical_port is + * resident, so that upstream MAC learning points to the + * correct chassis. Also need to avoid generation of + * multiple ARP responses from different chassis. */ + ds_put_format(&match, "is_chassis_resident(\"%s\")", + nat->logical_port); + } else { + mac_s = REG_INPORT_ETH_ADDR; + /* Traffic with eth.src = l3dgw_port->lrp_networks.ea_s + * should only be sent from the "redirect-chassis", so that + * upstream MAC learning points to the "redirect-chassis". + * Also need to avoid generation of multiple ARP responses + * from different chassis. */ + if (op->od->l3redirect_port) { + ds_put_format(&match, "is_chassis_resident(%s)", + op->od->l3redirect_port->json_key); + } + } + + /* Respond to ARP/NS requests on the chassis that binds the gw + * port. Drop the ARP/NS requests on other chassis. + */ + if (nat_entry_is_v6(nat_entry)) { + build_lrouter_nd_flow(op->od, op, "nd_na", + ext_addrs->ipv6_addrs[0].addr_s, + ext_addrs->ipv6_addrs[0].sn_addr_s, + mac_s, &match, false, 92, + &nat->header_, lflows); + build_lrouter_nd_flow(op->od, op, "nd_na", + ext_addrs->ipv6_addrs[0].addr_s, + ext_addrs->ipv6_addrs[0].sn_addr_s, + mac_s, NULL, true, 91, + &nat->header_, lflows); + } else { + build_lrouter_arp_flow(op->od, op, + ext_addrs->ipv4_addrs[0].addr_s, + mac_s, &match, false, 92, + &nat->header_, lflows); + build_lrouter_arp_flow(op->od, op, + ext_addrs->ipv4_addrs[0].addr_s, + mac_s, NULL, true, 91, + &nat->header_, lflows); + } + + ds_destroy(&match); +} + +static void build_lrouter_force_snat_flows(struct hmap *lflows, struct ovn_datapath *od, const char *ip_version, const char *ip_addr, const char *context) @@ -8869,6 +8957,10 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, /* Priority-90-92 flows handle ARP requests and ND packets. Most are * per logical port but DNAT addresses can be handled per datapath * for non gateway router ports. + * + * 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 sset snat_ips = SSET_INITIALIZER(&snat_ips); for (int i = 0; i < od->nbr->n_nat; i++) { @@ -8890,23 +8982,7 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, continue; } } - - /* 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. - */ - if (nat_entry_is_v6(nat_entry)) { - build_lrouter_nd_flow(od, NULL, "nd_na", - ext_addrs->ipv6_addrs[0].addr_s, - ext_addrs->ipv6_addrs[0].sn_addr_s, - REG_INPORT_ETH_ADDR, NULL, false, 90, - &nat->header_, lflows); - } else { - build_lrouter_arp_flow(od, NULL, - ext_addrs->ipv4_addrs[0].addr_s, - REG_INPORT_ETH_ADDR, NULL, false, 90, - &nat->header_, lflows); - } + build_lrouter_nat_arp_nd_flow(od, nat_entry, lflows); } sset_destroy(&snat_ips); @@ -9212,67 +9288,7 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports, continue; } } - - /* Mac address to use when replying to ARP/NS. */ - const char *mac_s = REG_INPORT_ETH_ADDR; - - /* ARP / ND handling for external IP addresses. - * - * DNAT IP addresses are external IP addresses that need ARP - * handling. */ - - struct eth_addr mac; - - ds_clear(&match); - if (nat->external_mac && - eth_addr_from_string(nat->external_mac, &mac) - && nat->logical_port) { - /* distributed NAT case, use nat->external_mac */ - mac_s = nat->external_mac; - /* Traffic with eth.src = nat->external_mac should only be - * sent from the chassis where nat->logical_port is - * resident, so that upstream MAC learning points to the - * correct chassis. Also need to avoid generation of - * multiple ARP responses from different chassis. */ - ds_put_format(&match, "is_chassis_resident(\"%s\")", - nat->logical_port); - } else { - mac_s = REG_INPORT_ETH_ADDR; - /* Traffic with eth.src = l3dgw_port->lrp_networks.ea_s - * should only be sent from the "redirect-chassis", so that - * upstream MAC learning points to the "redirect-chassis". - * Also need to avoid generation of multiple ARP responses - * from different chassis. */ - if (op->od->l3redirect_port) { - ds_put_format(&match, "is_chassis_resident(%s)", - op->od->l3redirect_port->json_key); - } - } - - /* Respond to ARP/NS requests on the chassis that binds the gw - * port. Drop the ARP/NS requests on other chassis. - */ - if (nat_entry_is_v6(nat_entry)) { - build_lrouter_nd_flow(op->od, op, "nd_na", - ext_addrs->ipv6_addrs[0].addr_s, - ext_addrs->ipv6_addrs[0].sn_addr_s, - mac_s, &match, false, 92, - &nat->header_, lflows); - build_lrouter_nd_flow(op->od, op, "nd_na", - ext_addrs->ipv6_addrs[0].addr_s, - ext_addrs->ipv6_addrs[0].sn_addr_s, - mac_s, NULL, true, 91, - &nat->header_, lflows); - } else { - build_lrouter_arp_flow(op->od, op, - ext_addrs->ipv4_addrs[0].addr_s, - mac_s, &match, false, 92, - &nat->header_, lflows); - build_lrouter_arp_flow(op->od, op, - ext_addrs->ipv4_addrs[0].addr_s, - mac_s, NULL, true, 91, - &nat->header_, lflows); - } + build_lrouter_port_nat_arp_nd_flow(op, nat_entry, lflows); } sset_destroy(&sset_snat_ips); }