Logical router adv in ovn-ic the sb learned routes from dynamic routing. Also, it doesn't learn route in ovn-ic if prefix is already learned in sb learned route table.
Signed-off-by: Lucas Vargas Dias <[email protected]> --- ic/ovn-ic.c | 110 +++++++++++++++++++++++++++++++++++---- tests/ovn-ic.at | 135 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 236 insertions(+), 9 deletions(-) diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c index 2a7dfe405..d092a96ee 100644 --- a/ic/ovn-ic.c +++ b/ic/ovn-ic.c @@ -70,7 +70,9 @@ struct ic_context { struct ovsdb_idl_index *nbrec_lrp_by_name; struct ovsdb_idl_index *nbrec_port_by_name; struct ovsdb_idl_index *sbrec_chassis_by_name; + struct ovsdb_idl_index *sbrec_learned_route_by_datapath; struct ovsdb_idl_index *sbrec_port_binding_by_name; + struct ovsdb_idl_index *sbrec_datapath_binding_by_nb_uuid; struct ovsdb_idl_index *sbrec_service_monitor_by_remote_type; struct ovsdb_idl_index *sbrec_service_monitor_by_ic_learned; struct ovsdb_idl_index *sbrec_service_monitor_by_remote_type_logical_port; @@ -660,6 +662,22 @@ find_sb_pb_by_name(struct ovsdb_idl_index *sbrec_port_binding_by_name, return pb; } +static const struct sbrec_datapath_binding * +find_sb_dp_by_nb_uuid(struct ovsdb_idl_index *sbrec_datapath_binding, + const struct uuid *nb_uuid) +{ + const struct sbrec_datapath_binding *key = + sbrec_datapath_binding_index_init_row(sbrec_datapath_binding); + + sbrec_datapath_binding_set_nb_uuid(key, nb_uuid, 1); + + const struct sbrec_datapath_binding *dp = + sbrec_datapath_binding_index_find(sbrec_datapath_binding, key); + sbrec_datapath_binding_index_destroy_row(key); + + return dp; +} + static const struct sbrec_port_binding * find_peer_port(struct ic_context *ctx, const struct sbrec_port_binding *sb_pb) @@ -1575,7 +1593,7 @@ add_to_routes_ad(struct hmap *routes_ad, const struct in6_addr prefix, const struct nbrec_load_balancer *nb_lb, const char *route_tag) { - ovs_assert(nb_route || nb_lrp || nb_lb); + ovs_assert(nb_route || nb_lrp || nb_lb || nb_lr); if (route_table == NULL) { route_table = ""; @@ -1607,9 +1625,12 @@ add_to_routes_ad(struct hmap *routes_ad, const struct in6_addr prefix, } else if (nb_lb) { VLOG_WARN_RL(&rl, msg_fmt, origin, "loadbalancer", UUID_ARGS(&nb_lb->header_.uuid)); - } else { + } else if (nb_lrp) { VLOG_WARN_RL(&rl, msg_fmt, origin, "lrp", UUID_ARGS(&nb_lrp->header_.uuid)); + } else { + VLOG_WARN_RL(&rl, msg_fmt, origin, "route", + UUID_ARGS(&nb_lr->header_.uuid)); } } } @@ -1685,8 +1706,16 @@ add_network_to_routes_ad(struct hmap *routes_ad, const char *network, if (!route_need_advertise(NULL, &prefix, plen, nb_options, nb_lr, ts_lrp)) { - VLOG_DBG("Route ad: skip network %s of lrp %s.", - network, nb_lrp->name); + if (VLOG_IS_DBG_ENABLED()) { + struct ds msg = DS_EMPTY_INITIALIZER; + ds_put_format(&msg, "Route ad: skip network %s", network); + if (nb_lrp) { + ds_put_format(&msg, " of lrp %s", nb_lrp->name); + } + ds_put_format(&msg, "."); + VLOG_DBG("%s", ds_cstr(&msg)); + ds_destroy(&msg); + } return; } @@ -1700,8 +1729,12 @@ add_network_to_routes_ad(struct hmap *routes_ad, const char *network, struct ds msg = DS_EMPTY_INITIALIZER; ds_put_format(&msg, "Adding direct network route to <main> routing " - "table: %s of lrp %s, nexthop ", network, nb_lrp->name); + "table: %s", network); + if (nb_lrp) { + ds_put_format(&msg, " of lrp %s,", nb_lrp->name); + } + ds_put_format(&msg, " nexthop "); if (IN6_IS_ADDR_V4MAPPED(&nexthop)) { ds_put_format(&msg, IP_FMT, IP_ARGS(in6_addr_get_mapped_ipv4(&nexthop))); @@ -1882,7 +1915,8 @@ route_matches_local_lb(const struct nbrec_load_balancer *nb_lb, } static bool -route_need_learn(const struct nbrec_logical_router *lr, +route_need_learn(struct ic_context *ctx, + const struct nbrec_logical_router *lr, const struct icsbrec_route *isb_route, struct in6_addr *prefix, unsigned int plen, const struct smap *nb_options, @@ -1952,6 +1986,27 @@ route_need_learn(const struct nbrec_logical_router *lr, } } + const struct sbrec_datapath_binding *dp = + find_sb_dp_by_nb_uuid(ctx->sbrec_datapath_binding_by_nb_uuid, + &lr->header_.uuid); + if (!dp) { + return true; + } + + + struct sbrec_learned_route *filter = sbrec_learned_route_index_init_row( + ctx->sbrec_learned_route_by_datapath); + sbrec_learned_route_index_set_datapath(filter, dp); + struct sbrec_learned_route *sb_route; + SBREC_LEARNED_ROUTE_FOR_EACH_EQUAL (sb_route, filter, + ctx->sbrec_learned_route_by_datapath) { + if (!strcmp(isb_route->ip_prefix, sb_route->ip_prefix)) { + sbrec_learned_route_index_destroy_row(filter); + return false; + } + } + sbrec_learned_route_index_destroy_row(filter); + return true; } @@ -2125,7 +2180,7 @@ sync_learned_routes(struct ic_context *ctx, isb_route->nexthop); continue; } - if (!route_need_learn(ic_lr->lr, isb_route, &prefix, plen, + if (!route_need_learn(ctx, ic_lr->lr, isb_route, &prefix, plen, &nb_global->options, lrp, &nexthop)) { continue; } @@ -2196,7 +2251,8 @@ ad_route_sync_external_ids(const struct ic_route_info *route_adv, smap_get_uuid(&isb_route->external_ids, "lr-id", &isb_ext_lr_id); nb_id = route_adv->nb_lb ? route_adv->nb_lb->header_.uuid : route_adv->nb_route ? route_adv->nb_route->header_.uuid : - route_adv->nb_lrp->header_.uuid; + route_adv->nb_lrp ? route_adv->nb_lrp->header_.uuid : + route_adv->nb_lr->header_.uuid; lr_id = route_adv->nb_lr->header_.uuid; if (!uuid_equals(&isb_ext_id, &nb_id)) { @@ -2388,6 +2444,26 @@ build_ts_routes_to_adv(struct ic_context *ctx, } } } + + const struct sbrec_datapath_binding *dp = + find_sb_dp_by_nb_uuid(ctx->sbrec_datapath_binding_by_nb_uuid, + &lr->header_.uuid); + if (!dp) { + return; + } + + struct sbrec_learned_route *filter = sbrec_learned_route_index_init_row( + ctx->sbrec_learned_route_by_datapath); + sbrec_learned_route_index_set_datapath(filter, dp); + struct sbrec_learned_route *sb_route; + SBREC_LEARNED_ROUTE_FOR_EACH_EQUAL (sb_route, filter, + ctx->sbrec_learned_route_by_datapath) { + add_network_to_routes_ad(routes_ad, sb_route->ip_prefix, NULL, + ts_port_addrs, + &nb_global->options, + lr, route_tag, ts_lrp); + } + sbrec_learned_route_index_destroy_row(filter); } static void @@ -2484,7 +2560,7 @@ delete_orphan_ic_routes(struct ic_context *ctx, static void route_run(struct ic_context *ctx) { - if (!ctx->ovnisb_txn || !ctx->ovnnb_txn) { + if (!ctx->ovnisb_txn || !ctx->ovnnb_txn || !ctx->ovnsb_txn) { return; } @@ -3476,6 +3552,11 @@ main(int argc, char *argv[]) ovsdb_idl_add_column(ovnsb_idl_loop.idl, &sbrec_service_monitor_col_options); + ovsdb_idl_add_table(ovnsb_idl_loop.idl, &sbrec_table_learned_route); + ovsdb_idl_add_column(ovnsb_idl_loop.idl, + &sbrec_learned_route_col_ip_prefix); + ovsdb_idl_add_column(ovnsb_idl_loop.idl, + &sbrec_learned_route_col_datapath); /* Create IDL indexes */ struct ovsdb_idl_index *nbrec_ls_by_name = ovsdb_idl_index_create1(ovnnb_idl_loop.idl, @@ -3491,10 +3572,17 @@ main(int argc, char *argv[]) struct ovsdb_idl_index *sbrec_port_binding_by_name = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, &sbrec_port_binding_col_logical_port); + struct ovsdb_idl_index *sbrec_datapath_binding_by_nb_uuid + = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, + &sbrec_datapath_binding_col_nb_uuid); struct ovsdb_idl_index *sbrec_chassis_by_name = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, &sbrec_chassis_col_name); + struct ovsdb_idl_index *sbrec_learned_route_by_datapath + = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, + &sbrec_learned_route_col_datapath); + struct ovsdb_idl_index *sbrec_service_monitor_by_remote_type = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, &sbrec_service_monitor_col_remote); @@ -3602,7 +3690,11 @@ main(int argc, char *argv[]) .nbrec_lrp_by_name = nbrec_lrp_by_name, .nbrec_port_by_name = nbrec_port_by_name, .sbrec_port_binding_by_name = sbrec_port_binding_by_name, + .sbrec_datapath_binding_by_nb_uuid = + sbrec_datapath_binding_by_nb_uuid, .sbrec_chassis_by_name = sbrec_chassis_by_name, + .sbrec_learned_route_by_datapath = + sbrec_learned_route_by_datapath, .sbrec_service_monitor_by_remote_type = sbrec_service_monitor_by_remote_type, .sbrec_service_monitor_by_ic_learned = diff --git a/tests/ovn-ic.at b/tests/ovn-ic.at index c444cc214..621fe7a62 100644 --- a/tests/ovn-ic.at +++ b/tests/ovn-ic.at @@ -3502,6 +3502,141 @@ OVN_CLEANUP_IC([az1], [az2]) AT_CLEANUP ]) +OVN_FOR_EACH_NORTHD([ +AT_SETUP([ovn-ic -- Check ovn-ic adv and learn from SB Learned Route]) + +ovn_init_ic_db + +for i in 1 2; do + ovn_start az$i + ovn_as az$i + + # Enable route learning at AZ level + check ovn-nbctl set nb_global . options:ic-route-learn=true + # Enable route advertising at AZ level + check ovn-nbctl set nb_global . options:ic-route-adv=true +done + +# Create new transit switches and LRs. Test topology is next: +# +# +# logical router (lr11) - transit switch (ts11) - logical router (lr12) +# +# + +# Create lr11, lr12 and ts11 and connect them +for i in 1 2; do + ovn_as az$i + + lr=lr1$i + check ovn-nbctl lr-add $lr + + ts=ts11 + check ovn-ic-nbctl --wait=sb --may-exist ts-add $ts + + lrp=lrp-$lr-$ts + lsp=lsp-$ts-$lr + # Create LRP and connect to TS + check ovn-nbctl lrp-add $lr $lrp aa:aa:aa:aa:a1:0$i 169.254.101.$i/24 + check ovn-nbctl lsp-add-router-port $ts $lsp $lrp +done + +# Create directly-connected route in lr11 +check ovn_as az2 ovn-nbctl lrp-add lr12 lrp-lr12 aa:aa:aa:aa:bb:01 "192.168.0.1/24" +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 +]) + +ovn_as az2 +check ovn-nbctl --wait=sb set Logical_Router lr12 option:dynamic-routing=true \ + option:dynamic-routing-redistribute="connected,static" +check ovn_as az2 ovn-nbctl --wait=sb lrp-add lr12 lr12-dr1 00:00:00:00:ff:01 10.0.0.1/24 +dr1=$(fetch_column port_binding _uuid logical_port=lr12-dr1) +datapath=$(fetch_column datapath_binding _uuid external_ids:name=lr12) + +check_uuid ovn-sbctl create Learned_Route \ + datapath=$datapath \ + logical_port=$dr1 \ + ip_prefix=192.168.1.0/24 \ + nexthop=10.0.0.20 + +# Check Learned_Route adv in ovn-ic +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.1.0/24 169.254.101.2 +]) + +ovn_as az2 +learned=$(fetch_column Learned_Route _uuid ip_prefix=192.168.1.0/24) +check ovn-sbctl destroy Learned_Route $learned + +# Check Learned_Route removed is not adv and learned. +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 +]) + + +# Duplicate routes, SB learn route by two paths. +ovn_as az2 +check_uuid ovn-sbctl create Learned_Route \ + datapath=$datapath \ + logical_port=$dr1 \ + ip_prefix=192.168.1.0/24 \ + nexthop=10.0.0.20 + +check ovn-nbctl --wait=sb lrp-add lr12 lr12-dr2 00:00:00:00:ff:02 169.254.254.1/24 +dr2=$(fetch_column port_binding _uuid logical_port=lr12-dr2) + +check_uuid ovn-sbctl create Learned_Route \ + datapath=$datapath \ + logical_port=$dr2 \ + ip_prefix=192.168.1.0/24 \ + nexthop=169.254.254.3 + +check_uuid ovn-sbctl create Learned_Route \ + datapath=$datapath \ + logical_port=$dr2 \ + ip_prefix=192.168.2.0/24 \ + nexthop=169.254.254.3 + +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.1.0/24 169.254.101.2 +192.168.2.0/24 169.254.101.2 +]) + +# Insert the same route Learned Route in the lr11 and don't learn by ovn-ic. +ovn_as az1 +check ovn-nbctl --wait=sb set Logical_Router lr11 option:dynamic-routing=true \ + option:dynamic-routing-redistribute="connected,static" +datapath_lr11=$(fetch_column datapath_binding _uuid external_ids:name=lr11) +check ovn-nbctl --wait=sb lrp-add lr11 lr11-dr1 00:00:00:00:ff:03 169.254.254.2/24 +sw1_dr1=$(fetch_column port_binding _uuid logical_port=lr11-dr1) +check_uuid ovn-sbctl create Learned_Route \ + datapath=$datapath_lr11 \ + logical_port=$sw1_dr1 \ + ip_prefix=192.168.1.0/24 \ + nexthop=169.254.254.3 + +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.2.0/24 169.254.101.2 +]) + +OVS_WAIT_FOR_OUTPUT([ovn_as az2 ovn-nbctl lr-route-list lr12 | grep 192.168 | + grep learned | awk '{print $1, $2}' | sort ], [0], [dnl +]) + +OVN_CLEANUP_IC([az1], [az2]) + +AT_CLEANUP +]) + AT_BANNER([OVN Interconnection Service Monitor synchronization]) OVN_FOR_EACH_NORTHD([ AT_SETUP([ovn-ic -- Service Monitor synchronization: mock_test]) -- 2.43.0 -- _'Esta mensagem é direcionada apenas para os endereços constantes no cabeçalho inicial. Se você não está listado nos endereços constantes no cabeçalho, pedimos-lhe que desconsidere completamente o conteúdo dessa mensagem e cuja cópia, encaminhamento e/ou execução das ações citadas estão imediatamente anuladas e proibidas'._ * **'Apesar do Magazine Luiza tomar todas as precauções razoáveis para assegurar que nenhum vírus esteja presente nesse e-mail, a empresa não poderá aceitar a responsabilidade por quaisquer perdas ou danos causados por esse e-mail ou por seus anexos'.* _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
