diff options
| -rw-r--r-- | bgpd/bgp_evpn.c | 17 | ||||
| -rw-r--r-- | bgpd/bgp_evpn.h | 41 | ||||
| -rw-r--r-- | bgpd/bgp_mplsvpn.c | 37 | ||||
| -rw-r--r-- | bgpd/bgp_mplsvpn.h | 33 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 10 | ||||
| -rw-r--r-- | bgpd/bgp_route.h | 18 | ||||
| -rw-r--r-- | bgpd/bgp_vty.c | 4 | ||||
| -rw-r--r-- | bgpd/bgpd.c | 9 | ||||
| -rw-r--r-- | bgpd/bgpd.h | 3 | ||||
| -rw-r--r-- | lib/northbound.c | 94 | ||||
| -rw-r--r-- | ospfd/ospf_vty.c | 28 | ||||
| -rw-r--r-- | pimd/pim_cmd.c | 2 | ||||
| -rw-r--r-- | ripd/rip_cli.c | 17 | ||||
| -rw-r--r-- | tests/topotests/all-protocol-startup/r1/show_bgp_ipv6_summary.ref | 2 | ||||
| -rw-r--r-- | zebra/zapi_msg.c | 8 |
15 files changed, 226 insertions, 97 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 84f3649758..19cda453f5 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -2502,6 +2502,9 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, /* Perform route selection and update zebra, if required. */ bgp_process(bgp_vrf, rn, afi, safi); + /* Process for route leaking. */ + vpn_leak_from_vrf_update(bgp_get_default(), bgp_vrf, pi); + return ret; } @@ -2667,6 +2670,9 @@ static int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, if (!pi) return 0; + /* Process for route leaking. */ + vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp_vrf, pi); + bgp_aggregate_decrement(bgp_vrf, &rn->p, pi, afi, safi); /* Mark entry for deletion */ @@ -4222,11 +4228,13 @@ void bgp_evpn_withdraw_type5_routes(struct bgp *bgp_vrf, afi_t afi, safi_t safi) table = bgp_vrf->rib[afi][safi]; for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) { - /* Only care about "selected" routes - non-imported. */ + /* Only care about "selected" routes. Also ensure that + * these are routes that are injectable into EVPN. + */ /* TODO: Support for AddPath for EVPN. */ for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) { if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) - && (!pi->extra || !pi->extra->parent)) { + && is_route_injectable_into_evpn(pi)) { bgp_evpn_withdraw_type5_route(bgp_vrf, &rn->p, afi, safi); break; @@ -4293,12 +4301,13 @@ void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi, table = bgp_vrf->rib[afi][safi]; for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) { /* Need to identify the "selected" route entry to use its - * attribute. Also, we only consider "non-imported" routes. + * attribute. Also, ensure that the route is injectable + * into EVPN. * TODO: Support for AddPath for EVPN. */ for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) { if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) - && (!pi->extra || !pi->extra->parent)) { + && is_route_injectable_into_evpn(pi)) { /* apply the route-map */ if (bgp_vrf->adv_cmd_rmap[afi][safi].map) { diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index fbf30083e1..22fb0939c9 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -88,8 +88,13 @@ static inline int is_route_parent_evpn(struct bgp_path_info *ri) !ri->extra->parent) return 0; - /* See if the parent is of family L2VPN/EVPN */ - parent_ri = (struct bgp_path_info *)ri->extra->parent; + /* Determine parent recursively */ + for (parent_ri = ri->extra->parent; + parent_ri->extra && parent_ri->extra->parent; + parent_ri = parent_ri->extra->parent) + ; + + /* See if of family L2VPN/EVPN */ rn = parent_ri->net; if (!rn) return 0; @@ -101,6 +106,38 @@ static inline int is_route_parent_evpn(struct bgp_path_info *ri) return 0; } +/* Flag if the route path's family is EVPN. */ +static inline bool is_pi_family_evpn(struct bgp_path_info *pi) +{ + return is_pi_family_matching(pi, AFI_L2VPN, SAFI_EVPN); +} + +/* Flag if the route is injectable into EVPN. This would be either a + * non-imported route or a non-EVPN imported route. + */ +static inline bool is_route_injectable_into_evpn(struct bgp_path_info *pi) +{ + struct bgp_path_info *parent_pi; + struct bgp_table *table; + struct bgp_node *rn; + + if (pi->sub_type != BGP_ROUTE_IMPORTED || + !pi->extra || + !pi->extra->parent) + return true; + + parent_pi = (struct bgp_path_info *)pi->extra->parent; + rn = parent_pi->net; + if (!rn) + return true; + table = bgp_node_table(rn); + if (table && + table->afi == AFI_L2VPN && + table->safi == SAFI_EVPN) + return false; + return true; +} + extern void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf, struct prefix *p, struct attr *src_attr, afi_t afi, diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 446d094c94..d211f1afff 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -46,6 +46,7 @@ #include "bgpd/bgp_zebra.h" #include "bgpd/bgp_nexthop.h" #include "bgpd/bgp_nht.h" +#include "bgpd/bgp_evpn.h" #if ENABLE_BGP_VNC #include "bgpd/rfapi/rfapi_backend.h" @@ -552,8 +553,12 @@ leak_update(struct bgp *bgp, /* destination bgp instance */ if (bpi->extra && bpi->extra->bgp_orig) bgp_nexthop = bpi->extra->bgp_orig; - /* No nexthop tracking for redistributed routes */ - if (bpi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE) + /* + * No nexthop tracking for redistributed routes or for + * EVPN-imported routes that get leaked. + */ + if (bpi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE || + is_pi_family_evpn(bpi_ultimate)) nh_valid = 1; else /* @@ -614,8 +619,11 @@ leak_update(struct bgp *bgp, /* destination bgp instance */ * No nexthop tracking for redistributed routes because * their originating protocols will do the tracking and * withdraw those routes if the nexthops become unreachable + * This also holds good for EVPN-imported routes that get + * leaked. */ - if (bpi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE) + if (bpi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE || + is_pi_family_evpn(bpi_ultimate)) nh_valid = 1; else /* @@ -683,11 +691,10 @@ void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */ return; } - /* loop check - should not be an imported route. */ - if (path_vrf->extra && path_vrf->extra->bgp_orig) + /* Is this route exportable into the VPN table? */ + if (!is_route_injectable_into_vpn(path_vrf)) return; - if (!vpn_leak_to_vpn_active(bgp_vrf, afi, &debugmsg)) { if (debug) zlog_debug("%s: %s skipping: %s", __func__, @@ -894,15 +901,6 @@ void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */ path_vrf->type, path_vrf->sub_type); } - if (path_vrf->sub_type != BGP_ROUTE_NORMAL - && path_vrf->sub_type != BGP_ROUTE_STATIC - && path_vrf->sub_type != BGP_ROUTE_REDISTRIBUTE) { - - if (debug) - zlog_debug("%s: wrong sub_type %d", __func__, - path_vrf->sub_type); - return; - } if (!bgp_vpn) return; @@ -912,6 +910,10 @@ void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn, /* to */ return; } + /* Is this route exportable into the VPN table? */ + if (!is_route_injectable_into_vpn(path_vrf)) + return; + if (!vpn_leak_to_vpn_active(bgp_vrf, afi, &debugmsg)) { if (debug) zlog_debug("%s: skipping: %s", __func__, debugmsg); @@ -1352,7 +1354,10 @@ void vpn_leak_to_vrf_withdraw_all(struct bgp *bgp_vrf, /* to */ for (bpi = bgp_node_get_bgp_path_info(bn); bpi; bpi = bpi->next) { - if (bpi->extra && bpi->extra->bgp_orig != bgp_vrf) { + if (bpi->extra + && bpi->extra->bgp_orig != bgp_vrf + && bpi->extra->parent + && is_pi_family_vpn(bpi->extra->parent)) { /* delete route */ bgp_aggregate_decrement(bgp_vrf, &bn->p, bpi, diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h index 5b989e1853..2ef9570aac 100644 --- a/bgpd/bgp_mplsvpn.h +++ b/bgpd/bgp_mplsvpn.h @@ -226,6 +226,39 @@ static inline void vpn_leak_postchange(vpn_policy_direction_t direction, } } +/* Flag if the route is injectable into VPN. This would be either a + * non-imported route or a non-VPN imported route. + */ +static inline bool is_route_injectable_into_vpn(struct bgp_path_info *pi) +{ + struct bgp_path_info *parent_pi; + struct bgp_table *table; + struct bgp_node *rn; + + if (pi->sub_type != BGP_ROUTE_IMPORTED || + !pi->extra || + !pi->extra->parent) + return true; + + parent_pi = (struct bgp_path_info *)pi->extra->parent; + rn = parent_pi->net; + if (!rn) + return true; + table = bgp_node_table(rn); + if (table && + (table->afi == AFI_IP || table->afi == AFI_IP6) && + table->safi == SAFI_MPLS_VPN) + return false; + return true; +} + +/* Flag if the route path's family is VPN. */ +static inline bool is_pi_family_vpn(struct bgp_path_info *pi) +{ + return (is_pi_family_matching(pi, AFI_IP, SAFI_MPLS_VPN) || + is_pi_family_matching(pi, AFI_IP6, SAFI_MPLS_VPN)); +} + extern void vpn_policy_routemap_event(const char *rmap_name); extern vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 90a8f8cec5..eca632dd44 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -2476,8 +2476,9 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn, /* advertise/withdraw type-5 routes */ if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) { - if (advertise_type5_routes(bgp, afi) && new_select && - (!new_select->extra || !new_select->extra->parent)) { + if (advertise_type5_routes(bgp, afi) && + new_select && + is_route_injectable_into_evpn(new_select)) { /* apply the route-map */ if (bgp->adv_cmd_rmap[afi][safi].map) { @@ -2500,8 +2501,9 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn, afi, safi); } - } else if (advertise_type5_routes(bgp, afi) && old_select && - (!old_select->extra || !old_select->extra->parent)) + } else if (advertise_type5_routes(bgp, afi) && + old_select && + is_route_injectable_into_evpn(old_select)) bgp_evpn_withdraw_type5_route(bgp, &rn->p, afi, safi); } diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 04a3c85f2c..fc5bf0c755 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -409,6 +409,24 @@ static inline int bgp_fibupd_safi(safi_t safi) return 0; } +/* Flag if the route path's family matches params. */ +static inline bool is_pi_family_matching(struct bgp_path_info *pi, + afi_t afi, safi_t safi) +{ + struct bgp_table *table; + struct bgp_node *rn; + + rn = pi->net; + if (!rn) + return false; + table = bgp_node_table(rn); + if (table && + table->afi == afi && + table->safi == safi) + return true; + return false; +} + /* Prototypes. */ extern void bgp_rib_remove(struct bgp_node *rn, struct bgp_path_info *pi, struct peer *peer, afi_t afi, safi_t safi); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index b059ef2205..3e100f2f0a 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -8036,7 +8036,7 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, json, "ribMemory", ents * sizeof(struct bgp_node)); - ents = listcount(bgp->peer); + ents = bgp->af_peer_count[afi][safi]; json_object_int_add(json, "peerCount", ents); json_object_int_add(json, "peerMemory", ents * sizeof(struct peer)); @@ -8076,7 +8076,7 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, bgp_node))); /* Peer related usage */ - ents = listcount(bgp->peer); + ents = bgp->af_peer_count[afi][safi]; vty_out(vty, "Peers %ld, using %s of memory\n", ents, mtype_memstr( diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index a200424561..54e8f5f369 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -707,6 +707,7 @@ struct peer_af *peer_af_create(struct peer *peer, afi_t afi, safi_t safi) { struct peer_af *af; int afid; + struct bgp *bgp; if (!peer) return NULL; @@ -715,6 +716,7 @@ struct peer_af *peer_af_create(struct peer *peer, afi_t afi, safi_t safi) if (afid >= BGP_AF_MAX) return NULL; + bgp = peer->bgp; assert(peer->peer_af_array[afid] == NULL); /* Allocate new peer af */ @@ -725,6 +727,7 @@ struct peer_af *peer_af_create(struct peer *peer, afi_t afi, safi_t safi) af->safi = safi; af->afid = afid; af->peer = peer; + bgp->af_peer_count[afi][safi]++; return af; } @@ -747,6 +750,7 @@ int peer_af_delete(struct peer *peer, afi_t afi, safi_t safi) { struct peer_af *af; int afid; + struct bgp *bgp; if (!peer) return -1; @@ -759,6 +763,7 @@ int peer_af_delete(struct peer *peer, afi_t afi, safi_t safi) if (!af) return -1; + bgp = peer->bgp; bgp_stop_announce_route_timer(af); if (PAF_SUBGRP(af)) { @@ -768,8 +773,12 @@ int peer_af_delete(struct peer *peer, afi_t afi, safi_t safi) af->subgroup->id, peer->host); } + update_subgroup_remove_peer(af->subgroup, af); + if (bgp->af_peer_count[afi][safi]) + bgp->af_peer_count[afi][safi]--; + peer->peer_af_array[afid] = NULL; XFREE(MTYPE_BGP_PEER_AF, af); return 0; diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 9ca09101e9..7a77c8b3ee 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -377,6 +377,9 @@ struct bgp { #define BGP_CONFIG_VRF_TO_VRF_IMPORT (1 << 7) #define BGP_CONFIG_VRF_TO_VRF_EXPORT (1 << 8) + /* BGP per AF peer count */ + uint32_t af_peer_count[AFI_MAX][SAFI_MAX]; + /* Route table for next-hop lookup cache. */ struct bgp_table *nexthop_cache_table[AFI_MAX]; diff --git a/lib/northbound.c b/lib/northbound.c index 15139aa8d0..edf7e0eca6 100644 --- a/lib/northbound.c +++ b/lib/northbound.c @@ -348,39 +348,58 @@ static void nb_config_diff_del_changes(struct nb_config_cbs *changes) * configurations. Given a new subtree, calculate all new YANG data nodes, * excluding default leafs and leaf-lists. This is a recursive function. */ -static void nb_config_diff_new_subtree(const struct lyd_node *dnode, - struct nb_config_cbs *changes) +static void nb_config_diff_created(const struct lyd_node *dnode, + struct nb_config_cbs *changes) { + enum nb_operation operation; struct lyd_node *child; - LY_TREE_FOR (dnode->child, child) { - enum nb_operation operation; + switch (dnode->schema->nodetype) { + case LYS_LEAF: + case LYS_LEAFLIST: + if (lyd_wd_default((struct lyd_node_leaf_list *)dnode)) + break; - switch (child->schema->nodetype) { - case LYS_LEAF: - case LYS_LEAFLIST: - if (lyd_wd_default((struct lyd_node_leaf_list *)child)) - break; + if (nb_operation_is_valid(NB_OP_CREATE, dnode->schema)) + operation = NB_OP_CREATE; + else if (nb_operation_is_valid(NB_OP_MODIFY, dnode->schema)) + operation = NB_OP_MODIFY; + else + return; - if (nb_operation_is_valid(NB_OP_CREATE, child->schema)) - operation = NB_OP_CREATE; - else if (nb_operation_is_valid(NB_OP_MODIFY, - child->schema)) - operation = NB_OP_MODIFY; - else - continue; + nb_config_diff_add_change(changes, operation, dnode); + break; + case LYS_CONTAINER: + case LYS_LIST: + if (nb_operation_is_valid(NB_OP_CREATE, dnode->schema)) + nb_config_diff_add_change(changes, NB_OP_CREATE, dnode); - nb_config_diff_add_change(changes, operation, child); - break; - case LYS_CONTAINER: - case LYS_LIST: - if (nb_operation_is_valid(NB_OP_CREATE, child->schema)) - nb_config_diff_add_change(changes, NB_OP_CREATE, - child); - nb_config_diff_new_subtree(child, changes); - break; - default: - break; + /* Process child nodes recursively. */ + LY_TREE_FOR (dnode->child, child) { + nb_config_diff_created(child, changes); + } + break; + default: + break; + } +} + +static void nb_config_diff_deleted(const struct lyd_node *dnode, + struct nb_config_cbs *changes) +{ + if (nb_operation_is_valid(NB_OP_DESTROY, dnode->schema)) + nb_config_diff_add_change(changes, NB_OP_DESTROY, dnode); + else if (CHECK_FLAG(dnode->schema->nodetype, LYS_CONTAINER)) { + struct lyd_node *child; + + /* + * Non-presence containers need special handling since they + * don't have "destroy" callbacks. In this case, what we need to + * do is to call the "destroy" callbacks of their child nodes + * when applicable (i.e. optional nodes). + */ + LY_TREE_FOR (dnode->child, child) { + nb_config_diff_deleted(child, changes); } } } @@ -399,42 +418,27 @@ static void nb_config_diff(const struct nb_config *config1, for (int i = 0; diff->type[i] != LYD_DIFF_END; i++) { LYD_DIFFTYPE type; struct lyd_node *dnode; - enum nb_operation operation; type = diff->type[i]; switch (type) { case LYD_DIFF_CREATED: dnode = diff->second[i]; - - if (nb_operation_is_valid(NB_OP_CREATE, dnode->schema)) - operation = NB_OP_CREATE; - else if (nb_operation_is_valid(NB_OP_MODIFY, - dnode->schema)) - operation = NB_OP_MODIFY; - else - continue; + nb_config_diff_created(dnode, changes); break; case LYD_DIFF_DELETED: dnode = diff->first[i]; - operation = NB_OP_DESTROY; + nb_config_diff_deleted(dnode, changes); break; case LYD_DIFF_CHANGED: dnode = diff->second[i]; - operation = NB_OP_MODIFY; + nb_config_diff_add_change(changes, NB_OP_MODIFY, dnode); break; case LYD_DIFF_MOVEDAFTER1: case LYD_DIFF_MOVEDAFTER2: default: continue; } - - nb_config_diff_add_change(changes, operation, dnode); - - if (type == LYD_DIFF_CREATED - && CHECK_FLAG(dnode->schema->nodetype, - LYS_CONTAINER | LYS_LIST)) - nb_config_diff_new_subtree(dnode, changes); } lyd_free_diff(diff); diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 2ab480e9d7..b5d8739fcb 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -3029,13 +3029,13 @@ static int show_ip_ospf_common(struct vty *vty, struct ospf *ospf, if (ospf->stub_router_startup_time != OSPF_STUB_ROUTER_UNCONFIGURED) json_object_int_add( - json_vrf, "postStartEnabledMsecs", - ospf->stub_router_startup_time / 1000); + json_vrf, "postStartEnabledSecs", + ospf->stub_router_startup_time); if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED) json_object_int_add( - json_vrf, "preShutdownEnabledMsecs", - ospf->stub_router_shutdown_time / 1000); + json_vrf, "preShutdownEnabledSecs", + ospf->stub_router_shutdown_time); } else { vty_out(vty, " Stub router advertisement is configured\n"); @@ -3511,8 +3511,8 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, json_object_int_add(json_interface_sub, "cost", oi->output_cost); json_object_int_add( - json_interface_sub, "transmitDelayMsecs", - OSPF_IF_PARAM(oi, transmit_delay) / 1000); + json_interface_sub, "transmitDelaySecs", + OSPF_IF_PARAM(oi, transmit_delay)); json_object_string_add(json_interface_sub, "state", lookup_msg(ospf_ism_state_msg, oi->state, NULL)); @@ -3616,20 +3616,20 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, if (OSPF_IF_PARAM(oi, fast_hello) == 0) json_object_int_add( json_interface_sub, "timerMsecs", - OSPF_IF_PARAM(oi, v_hello) / 1000); + OSPF_IF_PARAM(oi, v_hello) * 1000); else json_object_int_add( json_interface_sub, "timerMsecs", - OSPF_IF_PARAM(oi, fast_hello) / 1000); + 1000 / OSPF_IF_PARAM(oi, fast_hello)); json_object_int_add(json_interface_sub, - "timerDeadMsecs", - OSPF_IF_PARAM(oi, v_wait) / 1000); + "timerDeadSecs", + OSPF_IF_PARAM(oi, v_wait)); json_object_int_add(json_interface_sub, - "timerWaitMsecs", - OSPF_IF_PARAM(oi, v_wait) / 1000); + "timerWaitSecs", + OSPF_IF_PARAM(oi, v_wait)); json_object_int_add( - json_interface_sub, "timerRetransmit", - OSPF_IF_PARAM(oi, retransmit_interval) / 1000); + json_interface_sub, "timerRetransmitSecs", + OSPF_IF_PARAM(oi, retransmit_interval)); } else { vty_out(vty, " Timer intervals configured,"); vty_out(vty, " Hello "); diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index f521704f1b..012c3b4f1d 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -1191,7 +1191,7 @@ static void pim_show_interfaces_single(struct pim_instance *pim, vty_out(vty, "Designated Router\n"); vty_out(vty, "-----------------\n"); vty_out(vty, "Address : %s\n", dr_str); - vty_out(vty, "Priority : %d(%d)\n", + vty_out(vty, "Priority : %u(%d)\n", pim_ifp->pim_dr_priority, pim_ifp->pim_dr_num_nondrpri_neighbors); vty_out(vty, "Uptime : %s\n", dr_uptime); diff --git a/ripd/rip_cli.c b/ripd/rip_cli.c index 6fbcdc059b..62aaad5d97 100644 --- a/ripd/rip_cli.c +++ b/ripd/rip_cli.c @@ -378,10 +378,19 @@ DEFPY (rip_passive_interface, "Suppress routing updates on an interface\n" "Interface name\n") { - nb_cli_enqueue_change(vty, "./passive-interface", - no ? NB_OP_DESTROY : NB_OP_CREATE, ifname); - nb_cli_enqueue_change(vty, "./non-passive-interface", - no ? NB_OP_CREATE : NB_OP_DESTROY, ifname); + bool passive_default = + yang_dnode_get_bool(vty->candidate_config->dnode, "%s%s", + VTY_CURR_XPATH, "/passive-default"); + + if (passive_default) { + nb_cli_enqueue_change(vty, "./non-passive-interface", + no ? NB_OP_CREATE : NB_OP_DESTROY, + ifname); + } else { + nb_cli_enqueue_change(vty, "./passive-interface", + no ? NB_OP_DESTROY : NB_OP_CREATE, + ifname); + } return nb_cli_apply_changes(vty, NULL); } diff --git a/tests/topotests/all-protocol-startup/r1/show_bgp_ipv6_summary.ref b/tests/topotests/all-protocol-startup/r1/show_bgp_ipv6_summary.ref index 6777cd9fc3..85388c738d 100644 --- a/tests/topotests/all-protocol-startup/r1/show_bgp_ipv6_summary.ref +++ b/tests/topotests/all-protocol-startup/r1/show_bgp_ipv6_summary.ref @@ -1,7 +1,7 @@ BGP router identifier 192.168.0.1, local AS number 100 vrf-id 0 BGP table version 1 RIB entries 1, using XXXX bytes of memory -Peers 4, using XXXX KiB of memory +Peers 2, using XXXX KiB of memory Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd fc00:0:0:8::1000 4 100 0 0 0 0 0 never Active diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 9f2bbcf426..4e97c272fb 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -1456,8 +1456,8 @@ static void zread_route_add(ZAPI_HANDLER_ARGS) &(api_nh->gate.ipv4), sizeof(struct in_addr)); zebra_vxlan_evpn_vrf_route_add( - vrf_id, &api_nh->rmac, &vtep_ip, - &api.prefix); + api_nh->vrf_id, &api_nh->rmac, + &vtep_ip, &api.prefix); } break; case NEXTHOP_TYPE_IPV6: @@ -1479,8 +1479,8 @@ static void zread_route_add(ZAPI_HANDLER_ARGS) memcpy(&vtep_ip.ipaddr_v6, &(api_nh->gate.ipv6), sizeof(struct in6_addr)); zebra_vxlan_evpn_vrf_route_add( - vrf_id, &api_nh->rmac, &vtep_ip, - &api.prefix); + api_nh->vrf_id, &api_nh->rmac, + &vtep_ip, &api.prefix); } break; case NEXTHOP_TYPE_BLACKHOLE: |
