From patchwork Wed Nov 3 13:36:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mohammad Heib X-Patchwork-Id: 1550267 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.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=IupPCDCx; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HknrJ22s3z9sRN for ; Thu, 4 Nov 2021 00:37:18 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 2243A80EAE; Wed, 3 Nov 2021 13:37:15 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 2RrimMH2N0YS; Wed, 3 Nov 2021 13:37:13 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp1.osuosl.org (Postfix) with ESMTPS id C305980EAC; Wed, 3 Nov 2021 13:37:12 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 930D9C0012; Wed, 3 Nov 2021 13:37:12 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 89FCEC000E for ; Wed, 3 Nov 2021 13:37:11 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 6540440109 for ; Wed, 3 Nov 2021 13:37:11 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Authentication-Results: smtp2.osuosl.org (amavisd-new); dkim=pass (1024-bit key) header.d=redhat.com Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Ijb3TLjlvSEP for ; Wed, 3 Nov 2021 13:37:09 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by smtp2.osuosl.org (Postfix) with ESMTPS id 61D2C400C5 for ; Wed, 3 Nov 2021 13:37:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1635946628; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=h9/Ay+6R2FojjkYqd2Kw+u/fYTc760eMfEIwvdk7LEE=; b=IupPCDCx/xqWaXXoK2n3Lwh3Ek+Ho4xnsWX/Er75OupL4u4ZOhvgPbrtgd85rM8JOr2d1E pbBKfsFgUG9kfPX0U4OhRruwWn7wFh8eL++Lon8Fy8/2Dsum+wiNl+xc3A2sF4j0N2Qi0J RfFUcapTNXCRDFXowQouTngQBUavxXE= 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-543-ZjAzV5PqO4i8WULDzZSGjg-1; Wed, 03 Nov 2021 09:36:45 -0400 X-MC-Unique: ZjAzV5PqO4i8WULDzZSGjg-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 1C3BC100CC88 for ; Wed, 3 Nov 2021 13:36:44 +0000 (UTC) Received: from mheiblap.localdomain.com (unknown [10.35.206.232]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2624179453; Wed, 3 Nov 2021 13:36:38 +0000 (UTC) From: Mohammad Heib To: dev@openvswitch.org Date: Wed, 3 Nov 2021 15:36:16 +0200 Message-Id: <20211103133616.433626-1-mheib@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=mheib@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH ovn v4] ovn-northd: Virtual port add ND/ARP responder flows for IPv6 VIPs. 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" currently ovn-northd only handle virtual ports with VIP IPv4 and ignores virtual ports with VIP IPv6. This patch adds support for virtual ports with VIP IPv6 by adding lflows to the lsp_in_arp_rsp logical switch pipeline. Those lflows handle Neighbor Solicitations and Neighbor Advertisement requests that target the virtual port VIPs and bind the virtual port to the desired VIF. Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2003091 Fixes: 054f4c85c413 ("Add a new logical switch port type - 'virtual'") Signed-off-by: Mohammad Heib --- northd/northd.c | 92 +++++++++++++++++++++++++++++++++-------- northd/ovn-northd.8.xml | 11 +++-- tests/ovn.at | 66 +++++++++++++++++++++++------ 3 files changed, 134 insertions(+), 35 deletions(-) diff --git a/northd/northd.c b/northd/northd.c index da4f9cd14..4e1b6edb1 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -7501,7 +7501,7 @@ build_lswitch_arp_nd_responder_skip_local(struct ovn_port *op, } } -/* Ingress table 13: ARP/ND responder, reply for known IPs. +/* Ingress table 16: ARP/ND responder, reply for known IPs. * (priority 50). */ static void build_lswitch_arp_nd_responder_known_ips(struct ovn_port *op, @@ -7519,17 +7519,37 @@ build_lswitch_arp_nd_responder_known_ips(struct ovn_port *op, * * - ARP reply from the virtual ip which belongs to a logical * port of type 'virtual' and bind that port. + * + * - IPv6 Neighbor Solicitations requests that targets virtual + * ip which belongs to a logical port of type 'virtual' and + * bind that port. + * + * - IPv6 unsolicited Neighbor Advertisements that targets + * ip which belongs to a logical port of type 'virtual' + * and bind that port. * */ - ovs_be32 ip; + struct in6_addr ip; + const char *virtual_ip = smap_get(&op->nbsp->options, "virtual-ip"); const char *virtual_parents = smap_get(&op->nbsp->options, "virtual-parents"); - if (!virtual_ip || !virtual_parents || - !ip_parse(virtual_ip, &ip)) { + if (!virtual_ip || !virtual_parents) { return; } + bool is_ipv4 = strchr(virtual_ip, '.') ? true : false; + if (is_ipv4) { + ovs_be32 ipv4; + if (!ip_parse(virtual_ip, &ipv4)) { + return; + } + } else { + if (!ipv6_parse(virtual_ip, &ip)) { + return; + } + } + char *tokstr = xstrdup(virtual_parents); char *save_ptr = NULL; char *vparent; @@ -7542,13 +7562,33 @@ build_lswitch_arp_nd_responder_known_ips(struct ovn_port *op, continue; } - ds_clear(match); - ds_put_format(match, "inport == \"%s\" && " - "((arp.op == 1 && arp.spa == %s && " - "arp.tpa == %s) || (arp.op == 2 && " - "arp.spa == %s))", - vparent, virtual_ip, virtual_ip, - virtual_ip); + if (is_ipv4) { + ds_clear(match); + ds_put_format(match, "inport == \"%s\" && " + "((arp.op == 1 && arp.spa == %s && " + "arp.tpa == %s) || (arp.op == 2 && " + "arp.spa == %s))", + vparent, virtual_ip, virtual_ip, + virtual_ip); + } else { + struct ipv6_netaddr na; + /* Find VIP multicast group */ + in6_addr_solicited_node(&na.sn_addr, &ip); + inet_ntop(AF_INET6, &na.sn_addr, na.sn_addr_s, + sizeof na.sn_addr_s); + + ds_clear(match); + ds_put_format(match, "inport == \"%s\" && " + "((nd_ns && ip6.dst == {%s, %s} && " + "nd.target == %s) ||" + "(nd_na && nd.target == %s))", + vparent, + virtual_ip, + na.sn_addr_s, + virtual_ip, + virtual_ip); + } + ds_clear(actions); ds_put_format(actions, "bind_vport(%s, inport); " @@ -11172,17 +11212,29 @@ build_arp_resolve_flows_for_lrouter_port( * 00:00:00:00:00:00 and advance to next table so that ARP is * resolved by router pipeline using the arp{} action. * The MAC_Binding entry for the virtual ip might be invalid. */ - ovs_be32 ip; const char *vip = smap_get(&op->nbsp->options, "virtual-ip"); const char *virtual_parents = smap_get(&op->nbsp->options, "virtual-parents"); - if (!vip || !virtual_parents || - !ip_parse(vip, &ip) || !op->sb) { + + if (!vip || !virtual_parents || !op->sb) { return; } + bool is_ipv4 = strchr(vip, '.') ? true : false; + if (is_ipv4) { + ovs_be32 ipv4; + if (!ip_parse(vip, &ipv4)) { + return; + } + } else { + struct in6_addr ipv6; + if (!ipv6_parse(vip, &ipv6)) { + return; + } + } + if (!op->sb->virtual_parent || !op->sb->virtual_parent[0] || !op->sb->chassis) { /* The virtual port is not claimed yet. */ @@ -11196,8 +11248,10 @@ build_arp_resolve_flows_for_lrouter_port( if (find_lrp_member_ip(peer, vip)) { ds_clear(match); ds_put_format(match, "outport == %s && " - REG_NEXT_HOP_IPV4 " == %s", - peer->json_key, vip); + "%s == %s", + peer->json_key, + is_ipv4 ? REG_NEXT_HOP_IPV4 : REG_NEXT_HOP_IPV6, + vip); const char *arp_actions = "eth.dst = 00:00:00:00:00:00; next;"; @@ -11235,8 +11289,10 @@ build_arp_resolve_flows_for_lrouter_port( ds_clear(match); ds_put_format(match, "outport == %s && " - REG_NEXT_HOP_IPV4 " == %s", - peer->json_key, vip); + "%s == %s", + peer->json_key, + is_ipv4 ? REG_NEXT_HOP_IPV4 : REG_NEXT_HOP_IPV6, + vip); ds_clear(actions); ds_put_format(actions, "eth.dst = %s; next;", ea_s); diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml index d219c5618..cf7dc2fda 100644 --- a/northd/ovn-northd.8.xml +++ b/northd/ovn-northd.8.xml @@ -1066,12 +1066,13 @@
  • If inport V is of type virtual adds a - priority-100 logical flow for each P configured in the + priority-100 logical flows for each P configured in the column with the match

     inport == P && && ((arp.op == 1 && arp.spa == VIP && arp.tpa == VIP) || (arp.op == 2 && arp.spa == VIP))
    +inport == P && && ((nd_ns && ip6.dst == {VIP, NS_MULTICAST_ADDR} && nd.target == VIP) || (nd_na && nd.target == VIP))
             

    @@ -1087,7 +1088,9 @@

    Where VIP is the virtual ip configured in the column - . + and + NS_MULTICAST_ADDR is solicited-node multicast address corresponding + to the VIP.

  • @@ -3629,7 +3632,7 @@ outport = P record and the virtual parent with the Ethernet address E and the virtual ip is reachable via the router port P, a priority-100 flow with match outport === P - && reg0 == A has actions + && xxreg0/reg0 == A has actions eth.dst = E; next;.

    @@ -3641,7 +3644,7 @@ outport = P record and the virtual ip A is reachable via the router port P, a priority-100 flow with match outport === P - && reg0 == A has actions + && xxreg0/reg0 == A has actions eth.dst = 00:00:00:00:00:00; next;. This flow is added so that the ARP is always resolved for the virtual ip A by generating ARP request and diff --git a/tests/ovn.at b/tests/ovn.at index 5458552d3..ddd0df6f4 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -17950,6 +17950,11 @@ AT_SETUP([virtual ports]) AT_KEYWORDS([virtual ports]) ovn_start +send_nd_ns() { + local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 ip6_src=$5 ip6_dst=$6 tgt_ip=$7 + local request=${eth_dst}${eth_src}86dd6000000000203aff${ip6_src}${ip6_dst}870005c900000000${tgt_ip}0101${eth_src} + as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request +} send_garp() { local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 spa=$5 tpa=$6 local request=${eth_dst}${eth_src}08060001080006040001${eth_src}${spa}${eth_dst}${tpa} @@ -18018,43 +18023,52 @@ check ovn-nbctl lsp-set-type sw0-vir virtual check ovn-nbctl set logical_switch_port sw0-vir options:virtual-ip=10.0.0.10 check ovn-nbctl set logical_switch_port sw0-vir options:virtual-parents=sw0-p1,sw0-p2,sw0-p3 + +check ovn-nbctl lsp-add sw0 sw0-vir6 +check ovn-nbctl lsp-set-addresses sw0-vir6 "50:54:00:00:00:11 1000::61d1" +check ovn-nbctl lsp-set-port-security sw0-vir6 "50:54:00:00:00:11 1000::61d1" +check ovn-nbctl lsp-set-type sw0-vir6 virtual +check ovn-nbctl set logical_switch_port sw0-vir6 options:virtual-ip=1000::61d1 +check ovn-nbctl set logical_switch_port sw0-vir6 options:virtual-parents=sw0-p1,sw0-p2,sw0-p3 + check ovn-nbctl lsp-add sw0 sw0-p1 -check ovn-nbctl lsp-set-addresses sw0-p1 "50:54:00:00:00:03 10.0.0.3" -check ovn-nbctl lsp-set-port-security sw0-p1 "50:54:00:00:00:03 10.0.0.3 10.0.0.10" +check ovn-nbctl lsp-set-addresses sw0-p1 "50:54:00:00:00:03 10.0.0.3 1000::3" +check ovn-nbctl lsp-set-port-security sw0-p1 "50:54:00:00:00:03 10.0.0.3 10.0.0.10 1000::3" check ovn-nbctl lsp-add sw0 sw0-p2 -check ovn-nbctl lsp-set-addresses sw0-p2 "50:54:00:00:00:04 10.0.0.4" -check ovn-nbctl lsp-set-port-security sw0-p2 "50:54:00:00:00:04 10.0.0.4 10.0.0.10" +check ovn-nbctl lsp-set-addresses sw0-p2 "50:54:00:00:00:04 10.0.0.4 1000::4" +check ovn-nbctl lsp-set-port-security sw0-p2 "50:54:00:00:00:04 10.0.0.4 10.0.0.10 1000::4" check ovn-nbctl lsp-add sw0 sw0-p3 -check ovn-nbctl lsp-set-addresses sw0-p3 "50:54:00:00:00:05 10.0.0.5" -check ovn-nbctl lsp-set-port-security sw0-p3 "50:54:00:00:00:05 10.0.0.5 10.0.0.10" +check ovn-nbctl lsp-set-addresses sw0-p3 "50:54:00:00:00:05 10.0.0.5 1000::5" +check ovn-nbctl lsp-set-port-security sw0-p3 "50:54:00:00:00:05 10.0.0.5 10.0.0.10 1000::5" # Create the second logical switch with one port check ovn-nbctl ls-add sw1 check ovn-nbctl lsp-add sw1 sw1-p1 -check ovn-nbctl lsp-set-addresses sw1-p1 "40:54:00:00:00:03 20.0.0.3" -check ovn-nbctl lsp-set-port-security sw1-p1 "40:54:00:00:00:03 20.0.0.3" +check ovn-nbctl lsp-set-addresses sw1-p1 "40:54:00:00:00:03 20.0.0.3 2000::3" +check ovn-nbctl lsp-set-port-security sw1-p1 "40:54:00:00:00:03 20.0.0.3 2000::3" # Create a logical router and attach both logical switches check ovn-nbctl lr-add lr0 -check ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24 +check ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24 1000::a/64 check ovn-nbctl lsp-add sw0 sw0-lr0 check ovn-nbctl lsp-set-type sw0-lr0 router check ovn-nbctl lsp-set-addresses sw0-lr0 00:00:00:00:ff:01 check ovn-nbctl lsp-set-options sw0-lr0 router-port=lr0-sw0 -check ovn-nbctl lrp-add lr0 lr0-sw1 00:00:00:00:ff:02 20.0.0.1/24 +check ovn-nbctl lrp-add lr0 lr0-sw1 00:00:00:00:ff:02 20.0.0.1/24 2000::a/64 check ovn-nbctl lsp-add sw1 sw1-lr0 check ovn-nbctl lsp-set-type sw1-lr0 router check ovn-nbctl lsp-set-addresses sw1-lr0 00:00:00:00:ff:02 check ovn-nbctl lsp-set-options sw1-lr0 router-port=lr0-sw1 -# Add an ACL that matches on sw0-vir being bound locally. +# Add an ACL that matches on sw0-vir/sw0-vir6 being bound locally. check ovn-nbctl acl-add sw0 to-lport 1000 'is_chassis_resident("sw0-vir") && ip' allow +check ovn-nbctl acl-add sw0 to-lport 1000 'is_chassis_resident("sw0-vir6") && ip' allow check ovn-nbctl ls-add public -check ovn-nbctl lrp-add lr0 lr0-public 00:00:20:20:12:13 172.168.0.100/24 +check ovn-nbctl lrp-add lr0 lr0-public 00:00:20:20:12:13 172.168.0.100/24 2001:db8::1/64 check ovn-nbctl lsp-add public public-lr0 check ovn-nbctl lsp-set-type public-lr0 router check ovn-nbctl lsp-set-addresses public-lr0 router @@ -18070,13 +18084,14 @@ check ovn-nbctl lsp-set-options ln-public network_name=public check ovn-nbctl --wait=hv lrp-set-gateway-chassis lr0-public hv1 20 check ovn-nbctl lr-nat-add lr0 dnat_and_snat 172.168.0.50 10.0.0.10 sw0-vir 10:54:00:00:00:10 +check ovn-nbctl lr-nat-add lr0 dnat_and_snat 2001:db8::61d1 1000::61d1 sw0-vir6 20:01:db:86:d1:10 OVN_POPULATE_ARP wait_for_ports_up ovn-nbctl --wait=hv sync -# Check that logical flows are added for sw0-vir in lsp_in_arp_rsp pipeline +# Check that logical flows are added for sw0-vir/sw0vir6 in lsp_in_arp_rsp pipeline # with bind_vport action. ovn-sbctl dump-flows sw0 > sw0-flows @@ -18084,8 +18099,11 @@ AT_CAPTURE_FILE([sw0-flows]) AT_CHECK([grep ls_in_arp_rsp sw0-flows | grep bind_vport | sed 's/table=../table=??/' | sort], [0], [dnl table=??(ls_in_arp_rsp ), priority=100 , match=(inport == "sw0-p1" && ((arp.op == 1 && arp.spa == 10.0.0.10 && arp.tpa == 10.0.0.10) || (arp.op == 2 && arp.spa == 10.0.0.10))), action=(bind_vport("sw0-vir", inport); next;) + table=??(ls_in_arp_rsp ), priority=100 , match=(inport == "sw0-p1" && ((nd_ns && ip6.dst == {1000::61d1, ff02::1:ff00:61d1} && nd.target == 1000::61d1) ||(nd_na && nd.target == 1000::61d1))), action=(bind_vport("sw0-vir6", inport); next;) table=??(ls_in_arp_rsp ), priority=100 , match=(inport == "sw0-p2" && ((arp.op == 1 && arp.spa == 10.0.0.10 && arp.tpa == 10.0.0.10) || (arp.op == 2 && arp.spa == 10.0.0.10))), action=(bind_vport("sw0-vir", inport); next;) + table=??(ls_in_arp_rsp ), priority=100 , match=(inport == "sw0-p2" && ((nd_ns && ip6.dst == {1000::61d1, ff02::1:ff00:61d1} && nd.target == 1000::61d1) ||(nd_na && nd.target == 1000::61d1))), action=(bind_vport("sw0-vir6", inport); next;) table=??(ls_in_arp_rsp ), priority=100 , match=(inport == "sw0-p3" && ((arp.op == 1 && arp.spa == 10.0.0.10 && arp.tpa == 10.0.0.10) || (arp.op == 2 && arp.spa == 10.0.0.10))), action=(bind_vport("sw0-vir", inport); next;) + table=??(ls_in_arp_rsp ), priority=100 , match=(inport == "sw0-p3" && ((nd_ns && ip6.dst == {1000::61d1, ff02::1:ff00:61d1} && nd.target == 1000::61d1) ||(nd_na && nd.target == 1000::61d1))), action=(bind_vport("sw0-vir6", inport); next;) ]) ovn-sbctl dump-flows lr0 > lr0-flows @@ -18097,6 +18115,10 @@ AT_CHECK([grep lr_in_arp_resolve lr0-flows | grep "reg0 == 10.0.0.10" | sed 's/t table=??(lr_in_arp_resolve ), priority=100 , match=(outport == "lr0-sw0" && reg0 == 10.0.0.10), action=(eth.dst = 00:00:00:00:00:00; next;) ]) +AT_CHECK([grep lr_in_arp_resolve lr0-flows | grep "xxreg0 == 1000::61d1" | sed 's/table=../table=??/'], [0], [dnl + table=??(lr_in_arp_resolve ), priority=100 , match=(outport == "lr0-sw0" && xxreg0 == 1000::61d1), action=(eth.dst = 00:00:00:00:00:00; next;) +]) + hv1_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv1"` hv2_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv2"` @@ -18105,6 +18127,8 @@ logical_port=sw0-vir) = x], [0], []) AT_CHECK([test x$(ovn-sbctl --bare --columns virtual_parent find port_binding \ logical_port=sw0-vir) = x]) +AT_CHECK([test x$(ovn-sbctl --bare --columns virtual_parent find port_binding \ +logical_port=sw0-vir6) = x]) # Try to bind sw0-vir directly to an OVS port. This should be ignored by # ovn-controller. @@ -18155,11 +18179,22 @@ spa=$(ip_to_hex 10 0 0 10) tpa=$(ip_to_hex 10 0 0 10) send_garp 1 1 $eth_src $eth_dst $spa $tpa +eth_dst=3333ff0061d1 +ipv6_src=10000000000000000000000000000003 +ipv6_dst=ff0200000000000000000001ff0061d1 +ipv6_tgt=100000000000000000000000000061d1 +send_nd_ns 1 1 $eth_src $eth_dst $ipv6_src $ipv6_dst $ipv6_tgt + wait_row_count Port_Binding 1 logical_port=sw0-vir chassis=$hv1_ch_uuid check_row_count Port_Binding 1 logical_port=sw0-vir virtual_parent=sw0-p1 wait_for_ports_up sw0-vir check ovn-nbctl --wait=hv sync +wait_row_count Port_Binding 1 logical_port=sw0-vir6 chassis=$hv1_ch_uuid +check_row_count Port_Binding 1 logical_port=sw0-vir6 virtual_parent=sw0-p1 +wait_for_ports_up sw0-vir6 +check ovn-nbctl --wait=hv sync + # There should be an arp resolve flow to resolve the virtual_ip with the # sw0-p1's MAC. ovn-sbctl dump-flows lr0 > lr0-flows2 @@ -18168,6 +18203,10 @@ AT_CHECK([grep lr_in_arp_resolve lr0-flows2 | grep "reg0 == 10.0.0.10" | sed 's/ table=??(lr_in_arp_resolve ), priority=100 , match=(outport == "lr0-sw0" && reg0 == 10.0.0.10), action=(eth.dst = 50:54:00:00:00:03; next;) ]) +AT_CHECK([grep lr_in_arp_resolve lr0-flows2 | grep "xxreg0 == 1000::61d1" | sed 's/table=../table=??/'], [0], [dnl + table=??(lr_in_arp_resolve ), priority=100 , match=(outport == "lr0-sw0" && xxreg0 == 1000::61d1), action=(eth.dst = 50:54:00:00:00:03; next;) +]) + # hv1 should add the flow for the ACL with is_chassis_redirect check for sw0-vir and # arp responder flow in lr0 pipeline. check_virtual_offlows_present hv1 @@ -18440,6 +18479,7 @@ wait_row_count nb:Logical_Switch_Port 1 up=false name=sw0-vir # Clear virtual_ip column of sw0-vir. There should be no bind_vport flows. ovn-nbctl --wait=hv remove logical_switch_port sw0-vir options virtual-ip +ovn-nbctl --wait=hv remove logical_switch_port sw0-vir6 options virtual-ip ovn-sbctl dump-flows sw0 > sw0-flows2 AT_CAPTURE_FILE([sw0-flows2])