From patchwork Thu Sep 19 13:31:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Bartzen Acosta X-Patchwork-Id: 1987432 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=luizalabs.com header.i=@luizalabs.com header.a=rsa-sha256 header.s=google header.b=TjReV+m9; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4X8byq0HxKz1y1g for ; Thu, 19 Sep 2024 23:31:46 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id E568B42820; Thu, 19 Sep 2024 13:31:44 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id ppfQtDpYKjLX; Thu, 19 Sep 2024 13:31:42 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=2605:bc80:3010:104::8cd3:938; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 5B25A41A4A Authentication-Results: smtp4.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key, unprotected) header.d=luizalabs.com header.i=@luizalabs.com header.a=rsa-sha256 header.s=google header.b=TjReV+m9 Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp4.osuosl.org (Postfix) with ESMTPS id 5B25A41A4A; Thu, 19 Sep 2024 13:31:42 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 34CFEC0012; Thu, 19 Sep 2024 13:31:42 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 95E77C0011 for ; Thu, 19 Sep 2024 13:31:40 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 921E580A94 for ; Thu, 19 Sep 2024 13:31:40 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id JI0n37u5KnRP for ; Thu, 19 Sep 2024 13:31:39 +0000 (UTC) Received-SPF: None (mailfrom) identity=mailfrom; client-ip=2607:f8b0:4864:20::629; helo=mail-pl1-x629.google.com; envelope-from=roberto.acosta@luizalabs.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp1.osuosl.org 3150E80A90 Authentication-Results: smtp1.osuosl.org; dmarc=pass (p=quarantine dis=none) header.from=luizalabs.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 3150E80A90 Authentication-Results: smtp1.osuosl.org; dkim=pass (1024-bit key, unprotected) header.d=luizalabs.com header.i=@luizalabs.com header.a=rsa-sha256 header.s=google header.b=TjReV+m9 Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) by smtp1.osuosl.org (Postfix) with ESMTPS id 3150E80A90 for ; Thu, 19 Sep 2024 13:31:39 +0000 (UTC) Received: by mail-pl1-x629.google.com with SMTP id d9443c01a7336-2055f630934so7847305ad.1 for ; Thu, 19 Sep 2024 06:31:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=luizalabs.com; s=google; t=1726752698; x=1727357498; darn=openvswitch.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=0eBkGlDCaNagRzsXtNJ8SiN+iPswtL65I/LqTPIKxTw=; b=TjReV+m9j22qlItE82cNOD7fTOFoMI0dlhRMZ69XltlQ0coxKXyeJEHHjt4LnjWEa0 iiKU/S6/ShnBMlFvXm6tRx2ANL+NGpDiaryNrwLom9ui/rnDtVsVlvuVrrA/pWmYGF7u 9lSVU81+iOYwTsc0LqjVzbG0t42+jvPbsMTK0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726752698; x=1727357498; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=0eBkGlDCaNagRzsXtNJ8SiN+iPswtL65I/LqTPIKxTw=; b=kWzs0uAg1GbAP+RtOySS2EN6dS2/d9umcrRKvPYBjf3l82jp8eRirUj2VjTbynmyB6 2OPSilmGSoMfIr5aVhwSsb8jCK3LKo8MEBN4b2ddnhmwouqgotiOSyygW3iTI+QtnJzQ verwoge/SYXlu2csSXMcfU+DSYaiHYljV6SvLUXapvcJQO8JwVyF7GOZhgT6NbDrXLPO FXdYKyR0w/21kMDbt8+ioMrs5eT6pXHoYvitVxVFMuACGVjcio4NFP/6VnETEMeZsjSp uVj+xeCLFbXKWB1wTMJ0LJ+hDj5rqnaZviHsk13QzrIDuGXTqPw0qCL9g2+/uwCQHFzd Aetw== X-Gm-Message-State: AOJu0Yz130fnNpnqXhdXonELeg2Qk1fT/e6PBtCqQbD6s5HxroxDAPcT D3elW8lcjxP2D9o2WBlmeqtWW7MsYn5pNaSiIHNfN+/nMLWZ+z5dyg3quZA2YtJfZE5fCV5HQKU KT1eRNk7EN5BwFf/VxATtaum0QvVPw8CikzTy+uz+TCCbD0zv5NS+ejwfUng= X-Google-Smtp-Source: AGHT+IF/49EXX/fs8LJPCZpJGI1UAWt9X5Rj9nfFB9/IkItY1KVePgedDnvjaFOMN4KlU8+qdZf7VA== X-Received: by 2002:a17:902:e5c3:b0:205:709e:1949 with SMTP id d9443c01a7336-2076e421fd0mr411837285ad.57.1726752697738; Thu, 19 Sep 2024 06:31:37 -0700 (PDT) Received: from roberto.. ([2804:14c:7989:8165:4910:5eaa:645c:f654]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-207946d151bsm80082175ad.142.2024.09.19.06.31.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Sep 2024 06:31:37 -0700 (PDT) To: dev@openvswitch.org Date: Thu, 19 Sep 2024 10:31:31 -0300 Message-Id: <20240919133131.162213-1-roberto.acosta@luizalabs.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Subject: [ovs-dev] [PATCH ovn v2] ovn-ic: Add support for route tag. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Roberto Bartzen Acosta via dev From: Roberto Bartzen Acosta Reply-To: Roberto Bartzen Acosta Cc: Roberto Bartzen Acosta Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" From: Roberto Bartzen Acosta The OVN-IC feature can handle multiple points of redistribution when we include more than one TS in the same Logical Router. So, it is a good idea to use route tagging to prevent learing routes from logical routers in the same user domain via Transit switch created for peer-links with another user domain. This means that there can be a logical separation by user domain (e.g. VPCs), and a Transit Switch that peers between the different VPCs, connecting the routers in the VPC1 with the routers in the VPC2, for example. In this case, the route tag can ensure that the Logical Routers of VPC1 does not learn routes from VPC1 itself via the peering TS, avoiding installing additional openflow flows to handle multipath/ecmp unnecessarily. To use this route tag feature, new options were created to be configured in the Logical Router Port connected to the TS. This configuration must be performed in the LRP insted of the LR because the LRP is the path used to advertise and learn routes connected to a specific TS (nexthop). Signed-off-by: Roberto Bartzen Acosta --- ic/ovn-ic.c | 80 ++++++++++++++----- ovn-nb.xml | 27 +++++++ tests/ovn-ic.at | 200 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 288 insertions(+), 19 deletions(-) diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c index 69bac4ab2..452416e8b 100644 --- a/ic/ovn-ic.c +++ b/ic/ovn-ic.c @@ -874,6 +874,7 @@ struct ic_route_info { struct in6_addr nexthop; const char *origin; const char *route_table; + const char *route_tag; const struct nbrec_logical_router *nb_lr; @@ -1124,7 +1125,8 @@ add_to_routes_ad(struct hmap *routes_ad, const struct in6_addr prefix, const char *origin, const char *route_table, const struct nbrec_logical_router_port *nb_lrp, const struct nbrec_logical_router_static_route *nb_route, - const struct nbrec_logical_router *nb_lr) + const struct nbrec_logical_router *nb_lr, + const char *route_tag) { if (route_table == NULL) { route_table = ""; @@ -1143,6 +1145,7 @@ add_to_routes_ad(struct hmap *routes_ad, const struct in6_addr prefix, ic_route->route_table = route_table; ic_route->nb_lrp = nb_lrp; ic_route->nb_lr = nb_lr; + ic_route->route_tag = route_tag; hmap_insert(routes_ad, &ic_route->node, hash); } else { static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); @@ -1158,7 +1161,8 @@ add_static_to_routes_ad( const struct nbrec_logical_router_static_route *nb_route, const struct nbrec_logical_router *nb_lr, const struct lport_addresses *nexthop_addresses, - const struct smap *nb_options) + const struct smap *nb_options, + const char *route_tag) { struct in6_addr prefix, nexthop; unsigned int plen; @@ -1199,7 +1203,7 @@ add_static_to_routes_ad( } add_to_routes_ad(routes_ad, prefix, plen, nexthop, ROUTE_ORIGIN_STATIC, - nb_route->route_table, NULL, nb_route, nb_lr); + nb_route->route_table, NULL, nb_route, nb_lr, route_tag); } static void @@ -1207,7 +1211,8 @@ add_network_to_routes_ad(struct hmap *routes_ad, const char *network, const struct nbrec_logical_router_port *nb_lrp, const struct lport_addresses *nexthop_addresses, const struct smap *nb_options, - const struct nbrec_logical_router *nb_lr) + const struct nbrec_logical_router *nb_lr, + const char *route_tag) { struct in6_addr prefix, nexthop; unsigned int plen; @@ -1246,7 +1251,7 @@ add_network_to_routes_ad(struct hmap *routes_ad, const char *network, /* directly-connected routes go to
route table */ add_to_routes_ad(routes_ad, prefix, plen, nexthop, ROUTE_ORIGIN_CONNECTED, - NULL, nb_lrp, NULL, nb_lr); + NULL, nb_lrp, NULL, nb_lr, route_tag); } static bool @@ -1315,8 +1320,8 @@ get_lrp_name_by_ts_port_name(struct ic_context *ctx, const char *ts_port_name) return smap_get(&nb_lsp->options, "router-port"); } -static const char * -get_route_table_by_lrp_name(struct ic_context *ctx, const char *lrp_name) +static const struct nbrec_logical_router_port * +get_lrp_by_lrp_name(struct ic_context *ctx, const char *lrp_name) { const struct nbrec_logical_router_port *lrp; const struct nbrec_logical_router_port *lrp_key = @@ -1326,10 +1331,7 @@ get_route_table_by_lrp_name(struct ic_context *ctx, const char *lrp_name) lrp_key); nbrec_logical_router_port_index_destroy_row(lrp_key); - if (lrp) { - return smap_get_def(&lrp->options, "route_table", ""); - } - return ""; /*
route table */ + return lrp; } static bool @@ -1359,12 +1361,21 @@ sync_learned_routes(struct ic_context *ctx, nbrec_nb_global_first(ctx->ovnnb_idl); ovs_assert(nb_global); - const char *lrp_name, *ts_route_table; + const char *lrp_name, *ts_route_table, *route_filter_tag; const struct icsbrec_port_binding *isb_pb; + const struct nbrec_logical_router_port *lrp; for (int i = 0; i < ic_lr->n_isb_pbs; i++) { isb_pb = ic_lr->isb_pbs[i]; lrp_name = get_lrp_name_by_ts_port_name(ctx, isb_pb->logical_port); - ts_route_table = get_route_table_by_lrp_name(ctx, lrp_name); + lrp = get_lrp_by_lrp_name(ctx, lrp_name); + if (lrp) { + ts_route_table = smap_get_def(&lrp->options, "route_table", ""); + route_filter_tag = smap_get_def(&lrp->options, + "ic-route-filter-tag", ""); + } else { + ts_route_table = ""; + route_filter_tag = ""; + } isb_route_key = icsbrec_route_index_init_row(ctx->icsbrec_route_by_ts); icsbrec_route_index_set_transit_switch(isb_route_key, @@ -1384,6 +1395,17 @@ sync_learned_routes(struct ic_context *ctx, continue; } + const char *isb_route_tag = smap_get(&isb_route->external_ids, + "ic-route-tag"); + if ((isb_route_tag != NULL) && + (!strcmp(isb_route_tag, route_filter_tag))) { + VLOG_DBG("Skip learning route %s -> %s as either " + "its route tag %s is filtered by %s of TS LRP ", + isb_route->ip_prefix, isb_route->nexthop, + isb_route_tag, route_filter_tag); + continue; + } + if (isb_route->route_table[0] && strcmp(isb_route->route_table, ts_route_table)) { if (VLOG_IS_DBG_ENABLED()) { @@ -1471,6 +1493,7 @@ ad_route_sync_external_ids(const struct ic_route_info *route_adv, const struct icsbrec_route *isb_route) { struct uuid isb_ext_id, nb_id, isb_ext_lr_id, lr_id; + const char *route_tag; smap_get_uuid(&isb_route->external_ids, "nb-id", &isb_ext_id); smap_get_uuid(&isb_route->external_ids, "lr-id", &isb_ext_lr_id); nb_id = route_adv->nb_route ? route_adv->nb_route->header_.uuid @@ -1488,6 +1511,16 @@ ad_route_sync_external_ids(const struct ic_route_info *route_adv, uuid_s); free(uuid_s); } + if (strcmp(route_adv->route_tag, "")) { + icsbrec_route_update_external_ids_setkey(isb_route, "ic-route-tag", + route_adv->route_tag); + } else { + route_tag = smap_get(&isb_route->external_ids, "ic-route-tag"); + if (route_tag) { + icsbrec_route_update_external_ids_delkey(isb_route, + "ic-route-tag"); + } + } } /* Sync routes from routes_ad to IC-SB. */ @@ -1580,7 +1613,8 @@ build_ts_routes_to_adv(struct ic_context *ctx, struct hmap *routes_ad, struct lport_addresses *ts_port_addrs, const struct nbrec_nb_global *nb_global, - const char *ts_route_table) + const char *ts_route_table, + const char *route_tag) { const struct nbrec_logical_router *lr = ic_lr->lr; @@ -1603,7 +1637,7 @@ build_ts_routes_to_adv(struct ic_context *ctx, } else if (!strcmp(ts_route_table, nb_route->route_table)) { /* It may be a route to be advertised */ add_static_to_routes_ad(routes_ad, nb_route, lr, ts_port_addrs, - &nb_global->options); + &nb_global->options, route_tag); } } @@ -1615,7 +1649,7 @@ build_ts_routes_to_adv(struct ic_context *ctx, add_network_to_routes_ad(routes_ad, lrp->networks[j], lrp, ts_port_addrs, &nb_global->options, - lr); + lr, route_tag); } } else { /* The router port of the TS port is ignored. */ @@ -1635,9 +1669,10 @@ collect_lr_routes(struct ic_context *ctx, ovs_assert(nb_global); const struct icsbrec_port_binding *isb_pb; - const char *lrp_name, *ts_name, *route_table; + const char *lrp_name, *ts_name, *route_table, *route_tag; struct lport_addresses ts_port_addrs; const struct icnbrec_transit_switch *key; + const struct nbrec_logical_router_port *lrp; struct hmap *routes_ad; const struct icnbrec_transit_switch *t_sw; @@ -1669,9 +1704,16 @@ collect_lr_routes(struct ic_context *ctx, continue; } lrp_name = get_lrp_name_by_ts_port_name(ctx, isb_pb->logical_port); - route_table = get_route_table_by_lrp_name(ctx, lrp_name); + lrp = get_lrp_by_lrp_name(ctx, lrp_name); + if (lrp) { + route_table = smap_get_def(&lrp->options, "route_table", ""); + route_tag = smap_get_def(&lrp->options, "ic-route-tag", ""); + } else { + route_table = ""; + route_tag = ""; + } build_ts_routes_to_adv(ctx, ic_lr, routes_ad, &ts_port_addrs, - nb_global, route_table); + nb_global, route_table, route_tag); destroy_lport_addresses(&ts_port_addrs); } } diff --git a/ovn-nb.xml b/ovn-nb.xml index 2836f58f5..adb9144ae 100644 --- a/ovn-nb.xml +++ b/ovn-nb.xml @@ -3662,6 +3662,33 @@ or + + +

+ This option expects a name of a route-tag that's present in the + Logical Router Port. If set, it causes any route advertised by + the Logical Router Port to include the route-tag in + the external_ids register of the advertised route + entry in the table of + the database. + + This allows to tag and filter route tags in the process of + advertising and learning routes in ovn-ic daemon. +

+
+ + +

+ This option expects a name of a filtered route-tag that's present + in the Logical Router Port. If set, it causes any route learned by + the Logical Router Port with the route-tag present in + the external_ids register of the advertised route entry in the + table of the + database, will be filtered and not + learned by the ovn-ic daemon. +

+
diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at index 9fa41200e..33ad37f2e 100644 --- a/tests/ovn-ic.at +++ b/tests/ovn-ic.at @@ -2357,3 +2357,203 @@ OVN_CLEANUP_SBOX([hv2], ["/IGMP Querier enabled without a valid IPv4/d OVN_CLEANUP_IC([az1],[az2]) AT_CLEANUP ]) + +OVN_FOR_EACH_NORTHD([ +AT_SETUP([ovn-ic -- route tag -- tagging and filtering routes]) + +ovn_init_ic_db +ovn-ic-nbctl ts-add ts1 + +for i in 1 2; do + ovn_start az$i + ovn_as az$i + + # Enable route learning at AZ level + ovn-nbctl set nb_global . options:ic-route-learn=true + # Enable route advertising at AZ level + ovn-nbctl set nb_global . options:ic-route-adv=true +done + +# Create new transit switches and LRs. Test topology is next: +# VPC1: +# / transit switch (ts11) \ +# logical router (lr11) - transit switch (ts12) - logical router (lr12) +# \ / +# transit switch (tspeer) +# VPC2: / \ +# logical router (lr21) - transit switch (ts21) - logical router (lr22) +# \ transit switch (ts22) / +# + +# VPC1 +# create lr11, lr12, ts11, ts12 and connect them +for i in 1 2; do + ovn_as az$i + + lr=lr1$i + ovn-nbctl lr-add $lr + + for j in 1 2; do + ts=ts1$j + ovn-ic-nbctl --wait=sb --may-exist ts-add $ts + + lrp=lrp-$lr-$ts + lsp=lsp-$ts-$lr + # Create LRP and connect to TS + ovn-nbctl lrp-add $lr $lrp aa:aa:aa:aa:a$j:0$i 169.254.10$j.$i/24 + ovn-nbctl lsp-add $ts $lsp \ + -- lsp-set-addresses $lsp router \ + -- lsp-set-type $lsp router \ + -- lsp-set-options $lsp router-port=$lrp + done +done + +# VPC2 +# create lr21, lr22, ts21, ts22 and connect them +for i in 1 2; do + ovn_as az$i + + lr=lr2$i + ovn-nbctl lr-add $lr + + for j in 1 2; do + ts=ts2$j + ovn-ic-nbctl --wait=sb --may-exist ts-add $ts + + lrp=lrp-$lr-$ts + lsp=lsp-$ts-$lr + # Create LRP and connect to TS + ovn-nbctl lrp-add $lr $lrp aa:aa:aa:aa:a$j:0$i 169.254.10$j.$i/24 + ovn-nbctl lsp-add $ts $lsp \ + -- lsp-set-addresses $lsp router \ + -- lsp-set-type $lsp router \ + -- lsp-set-options $lsp router-port=$lrp + done +done + +# Create directly-connected route in VPC1 +ovn_as az2 ovn-nbctl lrp-add lr12 lrp-lr12 aa:aa:aa:aa:bb:01 "192.168.0.1/24" + +# Create directly-connected route in VPC2 +ovn_as az2 ovn-nbctl --wait=sb lrp-add lr22 lrp-lr22 aa:aa:aa:aa:cc:01 "192.168.1.1/24" + +check ovn-ic-nbctl --wait=sb sync + +# Test direct routes from lr12 were learned to lr11 +OVS_WAIT_FOR_OUTPUT([ovn_as az1 ovn-nbctl lr-route-list lr11 | grep 192.168 | + grep learned | awk '{print $1, $2, $5}' | sort ], [0], [dnl +192.168.0.0/24 169.254.101.2 ecmp +192.168.0.0/24 169.254.102.2 ecmp +]) + +# Test direct routes from lr22 were learned to lr21 +OVS_WAIT_FOR_OUTPUT([ovn_as az1 ovn-nbctl lr-route-list lr21 | grep 192.168 | + grep learned | awk '{print $1, $2, $5}' | sort ], [0], [dnl +192.168.1.0/24 169.254.101.2 ecmp +192.168.1.0/24 169.254.102.2 ecmp +]) + +# Create peering TS +ovn-ic-nbctl --wait=sb --may-exist ts-add tspeer + +# Create LRPs and connect to the peering TS +ovn_as az1 +ovn-nbctl lrp-add lr11 lrp-lr11-tspeer aa:aa:aa:aa:11:01 169.254.103.11/24 +ovn-nbctl lsp-add tspeer lsp-tspeer-lr11 \ + -- lsp-set-addresses lsp-tspeer-lr11 router \ + -- lsp-set-type lsp-tspeer-lr11 router \ + -- lsp-set-options lsp-tspeer-lr11 router-port=lrp-lr11-tspeer + +ovn_as az2 +ovn-nbctl lrp-add lr12 lrp-lr12-tspeer aa:aa:aa:aa:12:01 169.254.103.12/24 +ovn-nbctl lsp-add tspeer lsp-tspeer-lr12 \ + -- lsp-set-addresses lsp-tspeer-lr12 router \ + -- lsp-set-type lsp-tspeer-lr12 router \ + -- lsp-set-options lsp-tspeer-lr12 router-port=lrp-lr12-tspeer + +ovn_as az1 +ovn-nbctl lrp-add lr21 lrp-lr21-tspeer aa:aa:aa:aa:21:01 169.254.103.21/24 +ovn-nbctl lsp-add tspeer lsp-tspeer-lr21 \ + -- lsp-set-addresses lsp-tspeer-lr21 router \ + -- lsp-set-type lsp-tspeer-lr21 router \ + -- lsp-set-options lsp-tspeer-lr21 router-port=lrp-lr21-tspeer + +ovn_as az2 +ovn-nbctl lrp-add lr22 lrp-lr22-tspeer aa:aa:aa:aa:22:01 169.254.103.22/24 +ovn-nbctl lsp-add tspeer lsp-tspeer-lr22 \ + -- lsp-set-addresses lsp-tspeer-lr22 router \ + -- lsp-set-type lsp-tspeer-lr22 router \ + -- lsp-set-options lsp-tspeer-lr22 router-port=lrp-lr22-tspeer + +check ovn-ic-nbctl --wait=sb sync + +# Test direct routes from lr12/lr22 were learned to lr11 +OVS_WAIT_FOR_OUTPUT([ovn_as az1 ovn-nbctl lr-route-list lr11 | grep 192.168 | + grep learned | awk '{print $1, $2}' | sort ], [0], [dnl +192.168.0.0/24 169.254.101.2 +192.168.0.0/24 169.254.102.2 +192.168.0.0/24 169.254.103.12 +192.168.1.0/24 169.254.103.22 +]) + +# Test direct routes from lr22/lr12 were learned to lr21 +OVS_WAIT_FOR_OUTPUT([ovn_as az1 ovn-nbctl lr-route-list lr21 | grep 192.168 | + grep learned | awk '{print $1, $2}' | sort ], [0], [dnl +192.168.0.0/24 169.254.103.12 +192.168.1.0/24 169.254.101.2 +192.168.1.0/24 169.254.102.2 +192.168.1.0/24 169.254.103.22 +]) + +# VPC1: Create a route tag for VPC1 mark its own routes via lrp-lr12 +ovn_as az2 ovn-nbctl set logical_router_port lrp-lr12-tspeer options:ic-route-tag=vpc1 + +# Test advertised routes with the vpc1 route tag present +ovn-ic-sbctl list route +wait_row_count ic-sb:Route 1 ip_prefix=192.168.0.1/24 nexthop=169.254.103.12 origin=connected external_ids:ic-route-tag=vpc1 + +# Filter routes on VPC1 lrp-lr11-tspeer with the route tag vpc1 present +ovn_as az1 ovn-nbctl set logical_router_port lrp-lr11-tspeer options:ic-route-filter-tag=vpc1 + +# Test remaining direct routes from lr12 were learned to lr11 +# Routes from the 169.254.101.2 nexthop have been filtered +OVS_WAIT_FOR_OUTPUT([ovn_as az1 ovn-nbctl lr-route-list lr11 | grep 192.168 | + grep learned | awk '{print $1, $2}' | sort ], [0], [dnl +192.168.0.0/24 169.254.101.2 +192.168.0.0/24 169.254.102.2 +192.168.1.0/24 169.254.103.22 +]) + +# Remove the route tag used for advertisement +ovn_as az2 ovn-nbctl remove logical_router_port lrp-lr12-tspeer options ic-route-tag=vpc1 + +# Test advertised routes with the vpc1 route tag present +ovn-ic-sbctl list route +wait_row_count ic-sb:Route 0 ip_prefix=192.168.0.1/24 nexthop=169.254.103.12 origin=connected external_ids:ic-route-tag=vpc1 + +# Test the original direct routes from lr12/lr22 were learned to lr11 +OVS_WAIT_FOR_OUTPUT([ovn_as az1 ovn-nbctl lr-route-list lr11 | grep 192.168 | + grep learned | awk '{print $1, $2}' | sort ], [0], [dnl +192.168.0.0/24 169.254.101.2 +192.168.0.0/24 169.254.102.2 +192.168.0.0/24 169.254.103.12 +192.168.1.0/24 169.254.103.22 +]) + +# Remove route tag filter and add route tag on lrp-lr12-tspeer advertised routes +ovn_as az1 ovn-nbctl remove logical_router_port lrp-lr11-tspeer options ic-route-filter-tag=vpc1 +ovn_as az2 ovn-nbctl set logical_router_port lrp-lr12-tspeer options:ic-route-tag=vpc1 + +# Test if all the routes are learned because we no longer have the filter tag option enabled +OVS_WAIT_FOR_OUTPUT([ovn_as az1 ovn-nbctl lr-route-list lr11 | grep 192.168 | + grep learned | awk '{print $1, $2}' | sort ], [0], [dnl +192.168.0.0/24 169.254.101.2 +192.168.0.0/24 169.254.102.2 +192.168.0.0/24 169.254.103.12 +192.168.1.0/24 169.254.103.22 +]) + +OVN_CLEANUP_IC([az1], [az2]) + +AT_CLEANUP +])