diff options
344 files changed, 28896 insertions, 2341 deletions
diff --git a/bfdd/bfd.c b/bfdd/bfd.c index 9667ba8708..ca4bf94955 100644 --- a/bfdd/bfd.c +++ b/bfdd/bfd.c @@ -313,6 +313,13 @@ int bfd_session_enable(struct bfd_session *bs) } } + if (!vrf_is_backend_netns() && vrf && vrf->vrf_id != VRF_DEFAULT + && !if_lookup_by_name(vrf->name, vrf->vrf_id)) { + zlog_err("session-enable: vrf interface %s not available yet", + vrf->name); + return 0; + } + if (bs->key.ifname[0]) { if (vrf) ifp = if_lookup_by_name(bs->key.ifname, vrf->vrf_id); @@ -320,14 +327,16 @@ int bfd_session_enable(struct bfd_session *bs) ifp = if_lookup_by_name_all_vrf(bs->key.ifname); if (ifp == NULL) { zlog_err( - "session-enable: specified interface doesn't exists."); + "session-enable: specified interface %s (VRF %s) doesn't exist.", + bs->key.ifname, vrf ? vrf->name : "<all>"); return 0; } if (bs->key.ifname[0] && !vrf) { vrf = vrf_lookup_by_id(ifp->vrf_id); if (vrf == NULL) { zlog_err( - "session-enable: specified VRF doesn't exists."); + "session-enable: specified VRF %u doesn't exist.", + ifp->vrf_id); return 0; } } diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c index 0a71c18a42..076318e6ca 100644 --- a/bfdd/bfd_packet.c +++ b/bfdd/bfd_packet.c @@ -543,6 +543,7 @@ int bfd_recv_cb(struct thread *t) ifindex_t ifindex = IFINDEX_INTERNAL; struct sockaddr_any local, peer; uint8_t msgbuf[1516]; + struct interface *ifp = NULL; struct bfd_vrf_global *bvrf = THREAD_ARG(t); vrfid = bvrf->vrf->vrf_id; @@ -572,6 +573,15 @@ int bfd_recv_cb(struct thread *t) &local, &peer); } + /* update vrf-id because when in vrf-lite mode, + * the socket is on default namespace + */ + if (ifindex) { + ifp = if_lookup_by_index(ifindex, vrfid); + if (ifp) + vrfid = ifp->vrf_id; + } + /* Implement RFC 5880 6.8.6 */ if (mlen < BFD_PKT_LEN) { cp_debug(is_mhop, &peer, &local, ifindex, vrfid, @@ -951,8 +961,9 @@ int bp_peer_socket(const struct bfd_session *bs) if (bs->key.ifname[0]) device_to_bind = (const char *)bs->key.ifname; - else if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH) - && bs->key.vrfname[0]) + else if ((!vrf_is_backend_netns() && bs->vrf->vrf_id != VRF_DEFAULT) + || ((CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH) + && bs->key.vrfname[0]))) device_to_bind = (const char *)bs->key.vrfname; frr_with_privs(&bglobal.bfdd_privs) { @@ -1018,8 +1029,9 @@ int bp_peer_socketv6(const struct bfd_session *bs) if (bs->key.ifname[0]) device_to_bind = (const char *)bs->key.ifname; - else if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH) - && bs->key.vrfname[0]) + else if ((!vrf_is_backend_netns() && bs->vrf->vrf_id != VRF_DEFAULT) + || ((CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH) + && bs->key.vrfname[0]))) device_to_bind = (const char *)bs->key.vrfname; frr_with_privs(&bglobal.bfdd_privs) { diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c index 44519c47b5..57fb81aa27 100644 --- a/bfdd/ptm_adapter.c +++ b/bfdd/ptm_adapter.c @@ -669,17 +669,24 @@ static void bfdd_sessions_enable_interface(struct interface *ifp) struct bfd_session *bs; struct vrf *vrf; + vrf = vrf_lookup_by_id(ifp->vrf_id); + if (!vrf) + return; + TAILQ_FOREACH(bso, &bglobal.bg_obslist, bso_entry) { bs = bso->bso_bs; - /* Interface name mismatch. */ - if (strcmp(ifp->name, bs->key.ifname)) - continue; - vrf = vrf_lookup_by_id(ifp->vrf_id); - if (!vrf) - continue; + /* check vrf name */ if (bs->key.vrfname[0] && strcmp(vrf->name, bs->key.vrfname)) continue; + + /* If Interface matches vrfname, then bypass iface check */ + if (vrf_is_backend_netns() || strcmp(ifp->name, vrf->name)) { + /* Interface name mismatch. */ + if (strcmp(ifp->name, bs->key.ifname)) + continue; + } + /* Skip enabled sessions. */ if (bs->sock != -1) continue; @@ -759,7 +766,8 @@ void bfdd_sessions_disable_vrf(struct vrf *vrf) static int bfd_ifp_destroy(struct interface *ifp) { if (bglobal.debug_zebra) - zlog_debug("zclient: delete interface %s", ifp->name); + zlog_debug("zclient: delete interface %s (VRF %u)", ifp->name, + ifp->vrf_id); bfdd_sessions_disable_interface(ifp); @@ -812,10 +820,10 @@ static int bfdd_interface_address_update(ZAPI_CALLBACK_ARGS) return 0; if (bglobal.debug_zebra) - zlog_debug("zclient: %s local address %pFX", + zlog_debug("zclient: %s local address %pFX (VRF %u)", cmd == ZEBRA_INTERFACE_ADDRESS_ADD ? "add" : "delete", - ifc->address); + ifc->address, vrf_id); if (cmd == ZEBRA_INTERFACE_ADDRESS_ADD) bfdd_sessions_enable_address(ifc); @@ -828,8 +836,8 @@ static int bfdd_interface_address_update(ZAPI_CALLBACK_ARGS) static int bfd_ifp_create(struct interface *ifp) { if (bglobal.debug_zebra) - zlog_debug("zclient: add interface %s", ifp->name); - + zlog_debug("zclient: add interface %s (VRF %u)", ifp->name, + ifp->vrf_id); bfdd_sessions_enable_interface(ifp); return 0; diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index ce22e8404d..c25d0e269a 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -3395,7 +3395,8 @@ void bgp_attr_extcom_tunnel_type(struct attr *attr, bgp_encap_types *tunnel_type) { struct ecommunity *ecom; - int i; + uint32_t i; + if (!attr) return; @@ -4021,7 +4022,7 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer, uint8_t *pnt; int tbit; int ecom_tr_size = 0; - int i; + uint32_t i; for (i = 0; i < attr->ecommunity->size; i++) { pnt = attr->ecommunity->val + (i * 8); diff --git a/bgpd/bgp_attr_evpn.c b/bgpd/bgp_attr_evpn.c index 7cc9ecd79e..1df646c346 100644 --- a/bgpd/bgp_attr_evpn.c +++ b/bgpd/bgp_attr_evpn.c @@ -89,7 +89,7 @@ char *ecom_mac2str(char *ecom_mac) /* Fetch router-mac from extended community */ bool bgp_attr_rmac(struct attr *attr, struct ethaddr *rmac) { - int i = 0; + uint32_t i = 0; struct ecommunity *ecom; ecom = attr->ecommunity; @@ -122,7 +122,7 @@ bool bgp_attr_rmac(struct attr *attr, struct ethaddr *rmac) uint8_t bgp_attr_default_gw(struct attr *attr) { struct ecommunity *ecom; - int i; + uint32_t i; ecom = attr->ecommunity; if (!ecom || !ecom->size) @@ -153,7 +153,7 @@ uint8_t bgp_attr_default_gw(struct attr *attr) uint16_t bgp_attr_df_pref_from_ec(struct attr *attr, uint8_t *alg) { struct ecommunity *ecom; - int i; + uint32_t i; uint16_t df_pref = 0; *alg = EVPN_MH_DF_ALG_SERVICE_CARVING; @@ -190,7 +190,7 @@ uint16_t bgp_attr_df_pref_from_ec(struct attr *attr, uint8_t *alg) uint32_t bgp_attr_mac_mobility_seqnum(struct attr *attr, uint8_t *sticky) { struct ecommunity *ecom; - int i; + uint32_t i; uint8_t flags = 0; ecom = attr->ecommunity; @@ -237,7 +237,7 @@ void bgp_attr_evpn_na_flag(struct attr *attr, uint8_t *router_flag, bool *proxy) { struct ecommunity *ecom; - int i; + uint32_t i; uint8_t val; ecom = attr->ecommunity; diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index f46d416c3c..b740979b82 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -37,19 +37,115 @@ #include "bgpd/bgp_advertise.h" #include "bgpd/bgp_vty.h" -/* Global variable to access damping configuration */ -static struct bgp_damp_config damp[AFI_MAX][SAFI_MAX]; +static void bgp_reuselist_add(struct reuselist *list, + struct bgp_damp_info *info) +{ + struct reuselist_node *new_node; + + assert(info); + new_node = XCALLOC(MTYPE_BGP_DAMP_REUSELIST, sizeof(*new_node)); + new_node->info = info; + SLIST_INSERT_HEAD(list, new_node, entry); +} + +static void bgp_reuselist_del(struct reuselist *list, + struct reuselist_node **node) +{ + if ((*node) == NULL) + return; + assert(list && node && *node); + SLIST_REMOVE(list, (*node), reuselist_node, entry); + XFREE(MTYPE_BGP_DAMP_REUSELIST, (*node)); + *node = NULL; +} -/* Utility macro to add and delete BGP dampening information to no - used list. */ -#define BGP_DAMP_LIST_ADD(N, A) BGP_PATH_INFO_ADD(N, A, no_reuse_list) -#define BGP_DAMP_LIST_DEL(N, A) BGP_PATH_INFO_DEL(N, A, no_reuse_list) +static void bgp_reuselist_switch(struct reuselist *source, + struct reuselist_node *node, + struct reuselist *target) +{ + assert(source && target && node); + SLIST_REMOVE(source, node, reuselist_node, entry); + SLIST_INSERT_HEAD(target, node, entry); +} + +static void bgp_reuselist_free(struct reuselist *list) +{ + struct reuselist_node *rn; + + assert(list); + while ((rn = SLIST_FIRST(list)) != NULL) + bgp_reuselist_del(list, &rn); +} + +static struct reuselist_node *bgp_reuselist_find(struct reuselist *list, + struct bgp_damp_info *info) +{ + struct reuselist_node *rn; + + assert(list && info); + SLIST_FOREACH (rn, list, entry) { + if (rn->info == info) + return rn; + } + return NULL; +} + +static void bgp_damp_info_unclaim(struct bgp_damp_info *bdi) +{ + struct reuselist_node *node; + + assert(bdi && bdi->config); + if (bdi->index == BGP_DAMP_NO_REUSE_LIST_INDEX) { + node = bgp_reuselist_find(&bdi->config->no_reuse_list, bdi); + if (node) + bgp_reuselist_del(&bdi->config->no_reuse_list, &node); + } else { + node = bgp_reuselist_find(&bdi->config->reuse_list[bdi->index], + bdi); + if (node) + bgp_reuselist_del(&bdi->config->reuse_list[bdi->index], + &node); + } + bdi->config = NULL; +} + +static void bgp_damp_info_claim(struct bgp_damp_info *bdi, + struct bgp_damp_config *bdc) +{ + assert(bdc && bdi); + if (bdi->config == NULL) { + bdi->config = bdc; + return; + } + bgp_damp_info_unclaim(bdi); + bdi->config = bdc; + bdi->afi = bdc->afi; + bdi->safi = bdc->safi; +} + +struct bgp_damp_config *get_active_bdc_from_pi(struct bgp_path_info *pi, + afi_t afi, safi_t safi) +{ + if (!pi) + return NULL; + if (CHECK_FLAG(pi->peer->af_flags[afi][safi], + PEER_FLAG_CONFIG_DAMPENING)) + return &pi->peer->damp[afi][safi]; + if (peer_group_active(pi->peer)) + if (CHECK_FLAG(pi->peer->group->conf->af_flags[afi][safi], + PEER_FLAG_CONFIG_DAMPENING)) + return &pi->peer->group->conf->damp[afi][safi]; + if (CHECK_FLAG(pi->peer->bgp->af_flags[afi][safi], + BGP_CONFIG_DAMPENING)) + return &pi->peer->bgp->damp[afi][safi]; + return NULL; +} /* Calculate reuse list index by penalty value. */ static int bgp_reuse_index(int penalty, struct bgp_damp_config *bdc) { unsigned int i; - int index; + unsigned int index; /* * reuse_limit can't be zero, this is for Coverity @@ -72,27 +168,45 @@ static int bgp_reuse_index(int penalty, struct bgp_damp_config *bdc) static void bgp_reuse_list_add(struct bgp_damp_info *bdi, struct bgp_damp_config *bdc) { - int index; - - index = bdi->index = bgp_reuse_index(bdi->penalty, bdc); - - bdi->prev = NULL; - bdi->next = bdc->reuse_list[index]; - if (bdc->reuse_list[index]) - bdc->reuse_list[index]->prev = bdi; - bdc->reuse_list[index] = bdi; + bgp_damp_info_claim(bdi, bdc); + bdi->index = bgp_reuse_index(bdi->penalty, bdc); + bgp_reuselist_add(&bdc->reuse_list[bdi->index], bdi); } /* Delete BGP dampening information from reuse list. */ static void bgp_reuse_list_delete(struct bgp_damp_info *bdi, struct bgp_damp_config *bdc) { - if (bdi->next) - bdi->next->prev = bdi->prev; - if (bdi->prev) - bdi->prev->next = bdi->next; - else - bdc->reuse_list[bdi->index] = bdi->next; + struct reuselist *list; + struct reuselist_node *rn; + + list = &bdc->reuse_list[bdi->index]; + rn = bgp_reuselist_find(list, bdi); + bgp_damp_info_unclaim(bdi); + bgp_reuselist_del(list, &rn); +} + +static void bgp_no_reuse_list_add(struct bgp_damp_info *bdi, + struct bgp_damp_config *bdc) +{ + bgp_damp_info_claim(bdi, bdc); + bdi->index = BGP_DAMP_NO_REUSE_LIST_INDEX; + bgp_reuselist_add(&bdc->no_reuse_list, bdi); +} + +static void bgp_no_reuse_list_delete(struct bgp_damp_info *bdi, + struct bgp_damp_config *bdc) +{ + struct reuselist_node *rn; + + assert(bdc && bdi); + if (bdi->config == NULL) { + bgp_damp_info_unclaim(bdi); + return; + } + bdi->config = NULL; + rn = bgp_reuselist_find(&bdc->no_reuse_list, bdi); + bgp_reuselist_del(&bdc->no_reuse_list, &rn); } /* Return decayed penalty value. */ @@ -115,32 +229,34 @@ int bgp_damp_decay(time_t tdiff, int penalty, struct bgp_damp_config *bdc) is evaluated. RFC2439 Section 4.8.7. */ static int bgp_reuse_timer(struct thread *t) { + struct bgp_damp_config *bdc = THREAD_ARG(t); struct bgp_damp_info *bdi; - struct bgp_damp_info *next; + struct reuselist plist; + struct reuselist_node *node; + struct bgp *bgp; time_t t_now, t_diff; - struct bgp_damp_config *bdc = THREAD_ARG(t); - - bdc->t_reuse = NULL; thread_add_timer(bm->master, bgp_reuse_timer, bdc, DELTA_REUSE, &bdc->t_reuse); t_now = bgp_clock(); - /* 1. save a pointer to the current zeroth queue head and zero the - list head entry. */ - bdi = bdc->reuse_list[bdc->reuse_offset]; - bdc->reuse_list[bdc->reuse_offset] = NULL; + /* 1. save a pointer to the current queue head and zero the list head + * list head entry. */ + assert(bdc->reuse_offset < bdc->reuse_list_size); + plist = bdc->reuse_list[bdc->reuse_offset]; + node = SLIST_FIRST(&plist); + SLIST_INIT(&bdc->reuse_list[bdc->reuse_offset]); /* 2. set offset = modulo reuse-list-size ( offset + 1 ), thereby rotating the circular queue of list-heads. */ bdc->reuse_offset = (bdc->reuse_offset + 1) % bdc->reuse_list_size; + assert(bdc->reuse_offset < bdc->reuse_list_size); /* 3. if ( the saved list head pointer is non-empty ) */ - for (; bdi; bdi = next) { - struct bgp *bgp = bdi->path->peer->bgp; - - next = bdi->next; + while ((node = SLIST_FIRST(&plist)) != NULL) { + bdi = node->info; + bgp = bdi->path->peer->bgp; /* Set t-diff = t-now - t-updated. */ t_diff = t_now - bdi->t_updated; @@ -169,16 +285,27 @@ static int bgp_reuse_timer(struct thread *t) bdi->safi); } - if (bdi->penalty <= bdc->reuse_limit / 2.0) - bgp_damp_info_free(bdi, 1, bdc->afi, bdc->safi); - else - BGP_DAMP_LIST_ADD(bdc, bdi); - } else + if (bdi->penalty <= bdc->reuse_limit / 2.0) { + bgp_damp_info_free(&bdi, bdc, 1, bdi->afi, + bdi->safi); + bgp_reuselist_del(&plist, &node); + } else { + node->info->index = + BGP_DAMP_NO_REUSE_LIST_INDEX; + bgp_reuselist_switch(&plist, node, + &bdc->no_reuse_list); + } + } else { /* Re-insert into another list (See RFC2439 Section * 4.8.6). */ - bgp_reuse_list_add(bdi, bdc); + bdi->index = bgp_reuse_index(bdi->penalty, bdc); + bgp_reuselist_switch(&plist, node, + &bdc->reuse_list[bdi->index]); + } } + assert(SLIST_EMPTY(&plist)); + return 0; } @@ -189,10 +316,13 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest, time_t t_now; struct bgp_damp_info *bdi = NULL; unsigned int last_penalty = 0; - struct bgp_damp_config *bdc = &damp[afi][safi]; + struct bgp_damp_config *bdc; - t_now = bgp_clock(); + bdc = get_active_bdc_from_pi(path, afi, safi); + if (!bdc) + return BGP_DAMP_USED; + t_now = bgp_clock(); /* Processing Unreachable Messages. */ if (path->extra) bdi = path->extra->damp_info; @@ -214,12 +344,13 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest, bdi->flap = 1; bdi->start_time = t_now; bdi->suppress_time = 0; - bdi->index = -1; + bdi->index = BGP_DAMP_NO_REUSE_LIST_INDEX; bdi->afi = afi; bdi->safi = safi; (bgp_path_info_extra_get(path))->damp_info = bdi; - BGP_DAMP_LIST_ADD(bdc, bdi); + bgp_no_reuse_list_add(bdi, bdc); } else { + bgp_damp_info_claim(bdi, bdc); last_penalty = bdi->penalty; /* 1. Set t-diff = t-now - t-updated. */ @@ -245,7 +376,7 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest, /* Remove the route from a reuse list if it is on one. */ if (CHECK_FLAG(bdi->path->flags, BGP_PATH_DAMPED)) { /* If decay rate isn't equal to 0, reinsert brn. */ - if (bdi->penalty != last_penalty && bdi->index >= 0) { + if (bdi->penalty != last_penalty) { bgp_reuse_list_delete(bdi, bdc); bgp_reuse_list_add(bdi, bdc); } @@ -257,10 +388,9 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest, if (bdi->penalty >= bdc->suppress_value) { bgp_path_info_set_flag(dest, path, BGP_PATH_DAMPED); bdi->suppress_time = t_now; - BGP_DAMP_LIST_DEL(bdc, bdi); + bgp_no_reuse_list_delete(bdi, bdc); bgp_reuse_list_add(bdi, bdc); } - return BGP_DAMP_USED; } @@ -270,7 +400,10 @@ int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest, time_t t_now; struct bgp_damp_info *bdi; int status; - struct bgp_damp_config *bdc = &damp[afi][safi]; + struct bgp_damp_config *bdc; + + bdc = get_active_bdc_from_pi(path, afi, safi); + assert(bdc); if (!path->extra || !((bdi = path->extra->damp_info))) return BGP_DAMP_USED; @@ -289,7 +422,7 @@ int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest, && (bdi->penalty < bdc->reuse_limit)) { bgp_path_info_unset_flag(dest, path, BGP_PATH_DAMPED); bgp_reuse_list_delete(bdi, bdc); - BGP_DAMP_LIST_ADD(bdc, bdi); + bgp_no_reuse_list_add(bdi, bdc); bdi->suppress_time = 0; status = BGP_DAMP_USED; } else @@ -297,36 +430,29 @@ int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest, if (bdi->penalty > bdc->reuse_limit / 2.0) bdi->t_updated = t_now; - else - bgp_damp_info_free(bdi, 0, afi, safi); + else { + bgp_damp_info_unclaim(bdi); + bgp_damp_info_free(&bdi, bdc, 0, afi, safi); + } return status; } -void bgp_damp_info_free(struct bgp_damp_info *bdi, int withdraw, afi_t afi, - safi_t safi) +void bgp_damp_info_free(struct bgp_damp_info **bdi, struct bgp_damp_config *bdc, + int withdraw, afi_t afi, safi_t safi) { - struct bgp_path_info *path; - struct bgp_damp_config *bdc = &damp[afi][safi]; + assert(bdc && bdi && *bdi); - if (!bdi) + if ((*bdi)->path == NULL) { + XFREE(MTYPE_BGP_DAMP_INFO, (*bdi)); return; + } - path = bdi->path; - path->extra->damp_info = NULL; - - if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) - bgp_reuse_list_delete(bdi, bdc); - else - BGP_DAMP_LIST_DEL(bdc, bdi); - - bgp_path_info_unset_flag(bdi->dest, path, + (*bdi)->path->extra->damp_info = NULL; + bgp_path_info_unset_flag((*bdi)->dest, (*bdi)->path, BGP_PATH_HISTORY | BGP_PATH_DAMPED); - - if (bdi->lastrecord == BGP_RECORD_WITHDRAW && withdraw) - bgp_path_info_delete(bdi->dest, path); - - XFREE(MTYPE_BGP_DAMP_INFO, bdi); + if ((*bdi)->lastrecord == BGP_RECORD_WITHDRAW && withdraw) + bgp_path_info_delete((*bdi)->dest, (*bdi)->path); } static void bgp_damp_parameter_set(int hlife, int reuse, int sup, int maxsup, @@ -369,8 +495,7 @@ static void bgp_damp_parameter_set(int hlife, int reuse, int sup, int maxsup, bdc->reuse_list = XCALLOC(MTYPE_BGP_DAMP_ARRAY, - bdc->reuse_list_size * sizeof(struct bgp_reuse_node *)); - + bdc->reuse_list_size * sizeof(struct reuselist)); /* Reuse-array computations */ bdc->reuse_index = XCALLOC(MTYPE_BGP_DAMP_ARRAY, sizeof(int) * bdc->reuse_index_size); @@ -397,7 +522,7 @@ static void bgp_damp_parameter_set(int hlife, int reuse, int sup, int maxsup, int bgp_damp_enable(struct bgp *bgp, afi_t afi, safi_t safi, time_t half, unsigned int reuse, unsigned int suppress, time_t max) { - struct bgp_damp_config *bdc = &damp[afi][safi]; + struct bgp_damp_config *bdc = &bgp->damp[afi][safi]; if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) { if (bdc->half_life == half && bdc->reuse_limit == reuse @@ -409,6 +534,8 @@ int bgp_damp_enable(struct bgp *bgp, afi_t afi, safi_t safi, time_t half, SET_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING); bgp_damp_parameter_set(half, reuse, suppress, max, bdc); + bdc->afi = afi; + bdc->safi = safi; /* Register reuse timer. */ thread_add_timer(bm->master, bgp_reuse_timer, bdc, DELTA_REUSE, @@ -417,8 +544,30 @@ int bgp_damp_enable(struct bgp *bgp, afi_t afi, safi_t safi, time_t half, return 0; } -static void bgp_damp_config_clean(struct bgp_damp_config *bdc) +/* Clean all the bgp_damp_info stored in reuse_list and no_reuse_list. */ +void bgp_damp_info_clean(struct bgp_damp_config *bdc, afi_t afi, safi_t safi) { + struct bgp_damp_info *bdi; + struct reuselist_node *rn; + struct reuselist *list; + unsigned int i; + + bdc->reuse_offset = 0; + for (i = 0; i < bdc->reuse_list_size; ++i) { + list = &bdc->reuse_list[i]; + while ((rn = SLIST_FIRST(list)) != NULL) { + bdi = rn->info; + bgp_reuselist_del(list, &rn); + bgp_damp_info_free(&bdi, bdc, 1, afi, safi); + } + } + + while ((rn = SLIST_FIRST(&bdc->no_reuse_list)) != NULL) { + bdi = rn->info; + bgp_reuselist_del(&bdc->no_reuse_list, &rn); + bgp_damp_info_free(&bdi, bdc, 1, afi, safi); + } + /* Free decay array */ XFREE(MTYPE_BGP_DAMP_ARRAY, bdc->decay_array); bdc->decay_array_size = 0; @@ -428,96 +577,81 @@ static void bgp_damp_config_clean(struct bgp_damp_config *bdc) bdc->reuse_index_size = 0; /* Free reuse list array. */ + for (i = 0; i < bdc->reuse_list_size; ++i) + bgp_reuselist_free(&bdc->reuse_list[i]); + XFREE(MTYPE_BGP_DAMP_ARRAY, bdc->reuse_list); bdc->reuse_list_size = 0; -} - -/* Clean all the bgp_damp_info stored in reuse_list. */ -void bgp_damp_info_clean(afi_t afi, safi_t safi) -{ - unsigned int i; - struct bgp_damp_info *bdi, *next; - struct bgp_damp_config *bdc = &damp[afi][safi]; - - bdc->reuse_offset = 0; - - for (i = 0; i < bdc->reuse_list_size; i++) { - if (!bdc->reuse_list[i]) - continue; - - for (bdi = bdc->reuse_list[i]; bdi; bdi = next) { - next = bdi->next; - bgp_damp_info_free(bdi, 1, afi, safi); - } - bdc->reuse_list[i] = NULL; - } - for (bdi = bdc->no_reuse_list; bdi; bdi = next) { - next = bdi->next; - bgp_damp_info_free(bdi, 1, afi, safi); - } - bdc->no_reuse_list = NULL; + THREAD_OFF(bdc->t_reuse); } +/* Disable route flap dampening for a bgp instance. + * + * Please note that this function also gets used to free memory when deleting a + * bgp instance. + */ int bgp_damp_disable(struct bgp *bgp, afi_t afi, safi_t safi) { - struct bgp_damp_config *bdc = &damp[afi][safi]; + struct bgp_damp_config *bdc; + + bdc = &bgp->damp[afi][safi]; + if (!bdc) + return 0; + /* If it wasn't enabled, there's nothing to do. */ if (!CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) return 0; /* Cancel reuse event. */ - thread_cancel(&(bdc->t_reuse)); + thread_cancel(&bdc->t_reuse); /* Clean BGP dampening information. */ - bgp_damp_info_clean(afi, safi); - - /* Clear configuration */ - bgp_damp_config_clean(bdc); + bgp_damp_info_clean(bdc, afi, safi); UNSET_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING); + return 0; } -void bgp_config_write_damp(struct vty *vty, afi_t afi, safi_t safi) +void bgp_config_write_damp(struct vty *vty, struct bgp *bgp, afi_t afi, + safi_t safi) { - if (damp[afi][safi].half_life == DEFAULT_HALF_LIFE * 60 - && damp[afi][safi].reuse_limit == DEFAULT_REUSE - && damp[afi][safi].suppress_value == DEFAULT_SUPPRESS - && damp[afi][safi].max_suppress_time - == damp[afi][safi].half_life * 4) + struct bgp_damp_config *bdc; + + bdc = &bgp->damp[afi][safi]; + if (bdc->half_life == DEFAULT_HALF_LIFE * 60 + && bdc->reuse_limit == DEFAULT_REUSE + && bdc->suppress_value == DEFAULT_SUPPRESS + && bdc->max_suppress_time == bdc->half_life * 4) vty_out(vty, " bgp dampening\n"); - else if (damp[afi][safi].half_life != DEFAULT_HALF_LIFE * 60 - && damp[afi][safi].reuse_limit == DEFAULT_REUSE - && damp[afi][safi].suppress_value == DEFAULT_SUPPRESS - && damp[afi][safi].max_suppress_time - == damp[afi][safi].half_life * 4) - vty_out(vty, " bgp dampening %lld\n", - damp[afi][safi].half_life / 60LL); + else if (bdc->half_life != DEFAULT_HALF_LIFE * 60 + && bdc->reuse_limit == DEFAULT_REUSE + && bdc->suppress_value == DEFAULT_SUPPRESS + && bdc->max_suppress_time == bdc->half_life * 4) + vty_out(vty, " bgp dampening %lld\n", bdc->half_life / 60LL); else vty_out(vty, " bgp dampening %lld %d %d %lld\n", - damp[afi][safi].half_life / 60LL, - damp[afi][safi].reuse_limit, - damp[afi][safi].suppress_value, - damp[afi][safi].max_suppress_time / 60LL); + bdc->half_life / 60LL, bdc->reuse_limit, + bdc->suppress_value, bdc->max_suppress_time / 60LL); } -static const char *bgp_get_reuse_time(unsigned int penalty, char *buf, - size_t len, afi_t afi, safi_t safi, - bool use_json, json_object *json) +static const char *bgp_get_reuse_time(struct bgp_damp_config *bdc, + unsigned int penalty, char *buf, + size_t len, bool use_json, + json_object *json) { time_t reuse_time = 0; struct tm tm; int time_store = 0; - if (penalty > damp[afi][safi].reuse_limit) { + if (penalty > bdc->reuse_limit) { reuse_time = (int)(DELTA_T - * ((log((double)damp[afi][safi].reuse_limit - / penalty)) - / (log(damp[afi][safi].decay_array[1])))); + * ((log((double)bdc->reuse_limit / penalty)) + / (log(bdc->decay_array[1])))); - if (reuse_time > damp[afi][safi].max_suppress_time) - reuse_time = damp[afi][safi].max_suppress_time; + if (reuse_time > bdc->max_suppress_time) + reuse_time = bdc->max_suppress_time; gmtime_r(&reuse_time, &tm); } else @@ -569,14 +703,15 @@ static const char *bgp_get_reuse_time(unsigned int penalty, char *buf, return buf; } -void bgp_damp_info_vty(struct vty *vty, struct bgp_path_info *path, afi_t afi, - safi_t safi, json_object *json_path) +void bgp_damp_info_vty(struct vty *vty, struct bgp *bgp, + struct bgp_path_info *path, afi_t afi, safi_t safi, + json_object *json_path) { struct bgp_damp_info *bdi; time_t t_now, t_diff; char timebuf[BGP_UPTIME_LEN]; int penalty; - struct bgp_damp_config *bdc = &damp[afi][safi]; + struct bgp_damp_config *bdc = &bgp->damp[afi][safi]; if (!path->extra) return; @@ -602,8 +737,8 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp_path_info *path, afi_t afi, if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED) && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) - bgp_get_reuse_time(penalty, timebuf, BGP_UPTIME_LEN, - afi, safi, 1, json_path); + bgp_get_reuse_time(bdc, penalty, timebuf, + BGP_UPTIME_LEN, 1, json_path); } else { vty_out(vty, " Dampinfo: penalty %d, flapped %d times in %s", @@ -614,14 +749,15 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp_path_info *path, afi_t afi, if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED) && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) vty_out(vty, ", reuse in %s", - bgp_get_reuse_time(penalty, timebuf, - BGP_UPTIME_LEN, afi, safi, 0, + bgp_get_reuse_time(bdc, penalty, timebuf, + BGP_UPTIME_LEN, 0, json_path)); vty_out(vty, "\n"); } } + const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_path_info *path, char *timebuf, size_t len, afi_t afi, safi_t safi, bool use_json, @@ -630,7 +766,11 @@ const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_path_info *path, struct bgp_damp_info *bdi; time_t t_now, t_diff; int penalty; - struct bgp_damp_config *bdc = &damp[afi][safi]; + struct bgp_damp_config *bdc; + + bdc = get_active_bdc_from_pi(path, afi, safi); + if (!bdc) + return NULL; if (!path->extra) return NULL; @@ -648,24 +788,23 @@ const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_path_info *path, t_diff = t_now - bdi->t_updated; penalty = bgp_damp_decay(t_diff, bdi->penalty, bdc); - return bgp_get_reuse_time(penalty, timebuf, len, afi, safi, use_json, - json); + return bgp_get_reuse_time(bdc, penalty, timebuf, len, use_json, json); } + static int bgp_print_dampening_parameters(struct bgp *bgp, struct vty *vty, afi_t afi, safi_t safi) { + struct bgp_damp_config *bdc; if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) { + bdc = &bgp->damp[afi][safi]; vty_out(vty, "Half-life time: %lld min\n", - (long long)damp[afi][safi].half_life / 60); - vty_out(vty, "Reuse penalty: %d\n", - damp[afi][safi].reuse_limit); - vty_out(vty, "Suppress penalty: %d\n", - damp[afi][safi].suppress_value); + (long long)bdc->half_life / 60); + vty_out(vty, "Reuse penalty: %d\n", bdc->reuse_limit); + vty_out(vty, "Suppress penalty: %d\n", bdc->suppress_value); vty_out(vty, "Max suppress time: %lld min\n", - (long long)damp[afi][safi].max_suppress_time / 60); - vty_out(vty, "Max suppress penalty: %u\n", - damp[afi][safi].ceiling); + (long long)bdc->max_suppress_time / 60); + vty_out(vty, "Max suppress penalty: %u\n", bdc->ceiling); vty_out(vty, "\n"); } else vty_out(vty, "dampening not enabled for %s\n", @@ -678,8 +817,8 @@ int bgp_show_dampening_parameters(struct vty *vty, afi_t afi, safi_t safi, uint8_t show_flags) { struct bgp *bgp; - bgp = bgp_get_default(); + bgp = bgp_get_default(); if (bgp == NULL) { vty_out(vty, "No BGP process is configured\n"); return CMD_WARNING; @@ -718,3 +857,132 @@ int bgp_show_dampening_parameters(struct vty *vty, afi_t afi, safi_t safi, } return CMD_SUCCESS; } + +void bgp_peer_damp_enable(struct peer *peer, afi_t afi, safi_t safi, + time_t half, unsigned int reuse, + unsigned int suppress, time_t max) +{ + struct bgp_damp_config *bdc; + + if (!peer) + return; + bdc = &peer->damp[afi][safi]; + if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_CONFIG_DAMPENING)) { + if (bdc->half_life == half && bdc->reuse_limit == reuse + && bdc->suppress_value == suppress + && bdc->max_suppress_time == max) + return; + bgp_peer_damp_disable(peer, afi, safi); + } + SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_CONFIG_DAMPENING); + bgp_damp_parameter_set(half, reuse, suppress, max, bdc); + bdc->afi = afi; + bdc->safi = safi; + thread_add_timer(bm->master, bgp_reuse_timer, bdc, DELTA_REUSE, + &bdc->t_reuse); +} + +/* Disable route flap dampening for a peer. + * + * Please note that this function also gets used to free memory when deleting a + * peer or peer group. + */ +void bgp_peer_damp_disable(struct peer *peer, afi_t afi, safi_t safi) +{ + struct bgp_damp_config *bdc; + + if (!peer_af_flag_check(peer, afi, safi, PEER_FLAG_CONFIG_DAMPENING)) + return; + bdc = &peer->damp[afi][safi]; + if (!bdc) + return; + bgp_damp_info_clean(bdc, afi, safi); + UNSET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_CONFIG_DAMPENING); +} + +void bgp_config_write_peer_damp(struct vty *vty, struct peer *peer, afi_t afi, + safi_t safi) +{ + struct bgp_damp_config *bdc; + + bdc = &peer->damp[afi][safi]; + if (bdc->half_life == DEFAULT_HALF_LIFE * 60 + && bdc->reuse_limit == DEFAULT_REUSE + && bdc->suppress_value == DEFAULT_SUPPRESS + && bdc->max_suppress_time == bdc->half_life * 4) + vty_out(vty, " neighbor %s dampening\n", peer->host); + else if (bdc->half_life != DEFAULT_HALF_LIFE * 60 + && bdc->reuse_limit == DEFAULT_REUSE + && bdc->suppress_value == DEFAULT_SUPPRESS + && bdc->max_suppress_time == bdc->half_life * 4) + vty_out(vty, " neighbor %s dampening %lld\n", peer->host, + bdc->half_life / 60LL); + else + vty_out(vty, " neighbor %s dampening %lld %d %d %lld\n", + peer->host, bdc->half_life / 60LL, bdc->reuse_limit, + bdc->suppress_value, bdc->max_suppress_time / 60LL); +} + +static void bgp_print_peer_dampening_parameters(struct vty *vty, + struct peer *peer, afi_t afi, + safi_t safi, bool use_json, + json_object *json) +{ + struct bgp_damp_config *bdc; + + if (!peer) + return; + if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_CONFIG_DAMPENING)) { + bdc = &peer->damp[afi][safi]; + if (!bdc) + return; + if (use_json) { + json_object_int_add(json, "halfLifeSecs", + bdc->half_life); + json_object_int_add(json, "reusePenalty", + bdc->reuse_limit); + json_object_int_add(json, "suppressPenalty", + bdc->suppress_value); + json_object_int_add(json, "maxSuppressTimeSecs", + bdc->max_suppress_time); + json_object_int_add(json, "maxSuppressPenalty", + bdc->ceiling); + } else { + vty_out(vty, "Half-life time: %lld min\n", + (long long)bdc->half_life / 60); + vty_out(vty, "Reuse penalty: %d\n", bdc->reuse_limit); + vty_out(vty, "Suppress penalty: %d\n", + bdc->suppress_value); + vty_out(vty, "Max suppress time: %lld min\n", + (long long)bdc->max_suppress_time / 60); + vty_out(vty, "Max suppress penalty: %u\n", + bdc->ceiling); + vty_out(vty, "\n"); + } + } else if (!use_json) + vty_out(vty, "neighbor dampening not enabled for %s\n", + get_afi_safi_str(afi, safi, false)); +} + +void bgp_show_peer_dampening_parameters(struct vty *vty, struct peer *peer, + afi_t afi, safi_t safi, bool use_json) +{ + json_object *json; + + if (use_json) { + json = json_object_new_object(); + json_object_string_add(json, "addressFamily", + get_afi_safi_str(afi, safi, false)); + bgp_print_peer_dampening_parameters(vty, peer, afi, safi, true, + json); + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } else { + vty_out(vty, "\nFor address family: %s\n", + get_afi_safi_str(afi, safi, false)); + bgp_print_peer_dampening_parameters(vty, peer, afi, safi, false, + NULL); + } +} diff --git a/bgpd/bgp_damp.h b/bgpd/bgp_damp.h index 604706300b..521f59b296 100644 --- a/bgpd/bgp_damp.h +++ b/bgpd/bgp_damp.h @@ -25,11 +25,6 @@ /* Structure maintained on a per-route basis. */ struct bgp_damp_info { - /* Doubly linked list. This information must be linked to - reuse_list or no_reuse_list. */ - struct bgp_damp_info *next; - struct bgp_damp_info *prev; - /* Figure-of-merit. */ unsigned int penalty; @@ -45,6 +40,9 @@ struct bgp_damp_info { /* Time of route start to be suppressed. */ time_t suppress_time; + /* Back reference to associated dampening configuration. */ + struct bgp_damp_config *config; + /* Back reference to bgp_path_info. */ struct bgp_path_info *path; @@ -53,6 +51,8 @@ struct bgp_damp_info { /* Current index in the reuse_list. */ int index; +#define BGP_DAMP_NO_REUSE_LIST_INDEX \ + (-1) /* index for elements on no_reuse_list */ /* Last time message type. */ uint8_t lastrecord; @@ -63,6 +63,13 @@ struct bgp_damp_info { safi_t safi; }; +struct reuselist_node { + SLIST_ENTRY(reuselist_node) entry; + struct bgp_damp_info *info; +}; + +SLIST_HEAD(reuselist, reuselist_node); + /* Specified parameter set configuration. */ struct bgp_damp_config { /* Value over which routes suppressed. */ @@ -100,11 +107,11 @@ struct bgp_damp_config { int *reuse_index; /* Reuse list array per-set based. */ - struct bgp_damp_info **reuse_list; - int reuse_offset; + struct reuselist *reuse_list; + unsigned int reuse_offset; /* All dampening information which is not on reuse list. */ - struct bgp_damp_info *no_reuse_list; + struct reuselist no_reuse_list; /* Reuse timer thread per-set base. */ struct thread *t_reuse; @@ -132,6 +139,8 @@ struct bgp_damp_config { #define REUSE_LIST_SIZE 256 #define REUSE_ARRAY_SIZE 1024 +extern struct bgp_damp_config *get_active_bdc_from_pi(struct bgp_path_info *pi, + afi_t afi, safi_t safi); extern int bgp_damp_enable(struct bgp *, afi_t, safi_t, time_t, unsigned int, unsigned int, time_t); extern int bgp_damp_disable(struct bgp *, afi_t, safi_t); @@ -139,13 +148,18 @@ extern int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest, afi_t afi, safi_t safi, int attr_change); extern int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest, afi_t afi, safi_t saff); -extern void bgp_damp_info_free(struct bgp_damp_info *path, int withdraw, +extern void bgp_damp_info_free(struct bgp_damp_info **path, + struct bgp_damp_config *bdc, int withdraw, afi_t afi, safi_t safi); -extern void bgp_damp_info_clean(afi_t afi, safi_t safi); +extern void bgp_damp_info_clean(struct bgp_damp_config *bdc, afi_t afi, + safi_t safi); +extern void bgp_damp_config_clean(struct bgp_damp_config *bdc); extern int bgp_damp_decay(time_t, int, struct bgp_damp_config *damp); -extern void bgp_config_write_damp(struct vty *, afi_t afi, safi_t safi); -extern void bgp_damp_info_vty(struct vty *vty, struct bgp_path_info *path, - afi_t afi, safi_t safi, json_object *json_path); +extern void bgp_config_write_damp(struct vty *vty, struct bgp *bgp, afi_t afi, + safi_t safi); +extern void bgp_damp_info_vty(struct vty *vty, struct bgp *bgp, + struct bgp_path_info *path, afi_t afi, + safi_t safi, json_object *json_path); extern const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_path_info *path, char *timebuf, size_t len, afi_t afi, @@ -153,5 +167,14 @@ extern const char *bgp_damp_reuse_time_vty(struct vty *vty, json_object *json); extern int bgp_show_dampening_parameters(struct vty *vty, afi_t, safi_t, uint8_t); +extern void bgp_peer_damp_enable(struct peer *peer, afi_t afi, safi_t safi, + time_t half, unsigned int reuse, + unsigned int suppress, time_t max); +extern void bgp_peer_damp_disable(struct peer *peer, afi_t afi, safi_t safi); +extern void bgp_config_write_peer_damp(struct vty *vty, struct peer *peer, + afi_t afi, safi_t safi); +extern void bgp_show_peer_dampening_parameters(struct vty *vty, + struct peer *peer, afi_t afi, + safi_t safi, bool use_json); #endif /* _QUAGGA_BGP_DAMP_H */ diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index cd5bef1798..3afa6eaf09 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -119,7 +119,7 @@ static const struct message bgp_notify_msg[] = { {BGP_NOTIFY_HOLD_ERR, "Hold Timer Expired"}, {BGP_NOTIFY_FSM_ERR, "Neighbor Events Error"}, {BGP_NOTIFY_CEASE, "Cease"}, - {BGP_NOTIFY_CAPABILITY_ERR, "CAPABILITY Message Error"}, + {BGP_NOTIFY_ROUTE_REFRESH_ERR, "ROUTE-REFRESH Message Error"}, {0}}; static const struct message bgp_notify_head_msg[] = { @@ -167,11 +167,9 @@ static const struct message bgp_notify_cease_msg[] = { {BGP_NOTIFY_CEASE_OUT_OF_RESOURCE, "/Out of Resource"}, {0}}; -static const struct message bgp_notify_capability_msg[] = { +static const struct message bgp_notify_route_refresh_msg[] = { {BGP_NOTIFY_SUBCODE_UNSPECIFIC, "/Unspecific"}, - {BGP_NOTIFY_CAPABILITY_INVALID_ACTION, "/Invalid Action Value"}, - {BGP_NOTIFY_CAPABILITY_INVALID_LENGTH, "/Invalid Capability Length"}, - {BGP_NOTIFY_CAPABILITY_MALFORMED_CODE, "/Malformed Capability Value"}, + {BGP_NOTIFY_ROUTE_REFRESH_INVALID_MSG_LEN, "/Invalid Message Length"}, {0}}; static const struct message bgp_notify_fsm_msg[] = { @@ -493,8 +491,8 @@ const char *bgp_notify_subcode_str(char code, char subcode) case BGP_NOTIFY_CEASE: return lookup_msg(bgp_notify_cease_msg, subcode, "Unrecognized Error Subcode"); - case BGP_NOTIFY_CAPABILITY_ERR: - return lookup_msg(bgp_notify_capability_msg, subcode, + case BGP_NOTIFY_ROUTE_REFRESH_ERR: + return lookup_msg(bgp_notify_route_refresh_msg, subcode, "Unrecognized Error Subcode"); } return ""; diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index 43bfb3e2bc..c358d4203e 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -95,7 +95,7 @@ static bool ecommunity_add_val_internal(struct ecommunity *ecom, bool unique, bool overwrite, uint8_t ecom_size) { - int c, ins_idx; + uint32_t c, ins_idx; const struct ecommunity_val *eval4 = (struct ecommunity_val *)eval; const struct ecommunity_val_ipv6 *eval6 = (struct ecommunity_val_ipv6 *)eval; @@ -113,7 +113,7 @@ static bool ecommunity_add_val_internal(struct ecommunity *ecom, /* check also if the extended community itself exists. */ c = 0; - ins_idx = -1; + ins_idx = UINT32_MAX; for (uint8_t *p = ecom->val; c < ecom->size; p += ecom_size, c++) { if (unique) { @@ -145,12 +145,12 @@ static bool ecommunity_add_val_internal(struct ecommunity *ecom, if (ret > 0) { if (!unique) break; - if (ins_idx == -1) + if (ins_idx == UINT32_MAX) ins_idx = c; } } - if (ins_idx == -1) + if (ins_idx == UINT32_MAX) ins_idx = c; /* Add the value to the structure with numerical sorting. */ @@ -193,7 +193,7 @@ static struct ecommunity * ecommunity_uniq_sort_internal(struct ecommunity *ecom, unsigned short ecom_size) { - int i; + uint32_t i; struct ecommunity *new; const void *eval; @@ -895,7 +895,7 @@ static int ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt) */ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) { - int i; + uint32_t i; uint8_t *pnt; uint8_t type = 0; uint8_t sub_type = 0; @@ -1176,8 +1176,8 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) bool ecommunity_match(const struct ecommunity *ecom1, const struct ecommunity *ecom2) { - int i = 0; - int j = 0; + uint32_t i = 0; + uint32_t j = 0; if (ecom1 == NULL && ecom2 == NULL) return true; @@ -1209,7 +1209,7 @@ extern struct ecommunity_val *ecommunity_lookup(const struct ecommunity *ecom, uint8_t type, uint8_t subtype) { uint8_t *p; - int c; + uint32_t c; /* If the value already exists in the structure return 0. */ c = 0; @@ -1230,7 +1230,7 @@ bool ecommunity_strip(struct ecommunity *ecom, uint8_t type, uint8_t subtype) { uint8_t *p, *q, *new; - int c, found = 0; + uint32_t c, found = 0; /* When this is fist value, just add it. */ if (ecom == NULL || ecom->val == NULL) return false; @@ -1278,7 +1278,7 @@ bool ecommunity_strip(struct ecommunity *ecom, uint8_t type, bool ecommunity_del_val(struct ecommunity *ecom, struct ecommunity_val *eval) { uint8_t *p; - int c, found = 0; + uint32_t c, found = 0; /* Make sure specified value exists. */ if (ecom == NULL || ecom->val == NULL) @@ -1512,7 +1512,7 @@ void bgp_remove_ecomm_from_aggregate_hash(struct bgp_aggregate *aggregate, const uint8_t *ecommunity_linkbw_present(struct ecommunity *ecom, uint32_t *bw) { const uint8_t *eval; - int i; + uint32_t i; if (bw) *bw = 0; diff --git a/bgpd/bgp_ecommunity.h b/bgpd/bgp_ecommunity.h index 6318e7edb1..6d0275a0c3 100644 --- a/bgpd/bgp_ecommunity.h +++ b/bgpd/bgp_ecommunity.h @@ -114,7 +114,7 @@ struct ecommunity { uint8_t unit_size; /* Size of Extended Communities attribute. */ - int size; + uint32_t size; /* Extended Communities value. */ uint8_t *val; diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 96f4b0aa78..88747b14b1 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -870,7 +870,7 @@ static void add_mac_mobility_to_attr(uint32_t seq_num, struct attr *attr) struct ecommunity ecom_tmp; struct ecommunity_val eval; uint8_t *ecom_val_ptr; - int i; + uint32_t i; uint8_t *pnt; int type = 0; int sub_type = 0; @@ -2710,7 +2710,7 @@ static int is_route_matching_for_vrf(struct bgp *bgp_vrf, { struct attr *attr = pi->attr; struct ecommunity *ecom; - int i; + uint32_t i; assert(attr); /* Route should have valid RT to be even considered. */ @@ -2777,7 +2777,7 @@ static int is_route_matching_for_vni(struct bgp *bgp, struct bgpevpn *vpn, { struct attr *attr = pi->attr; struct ecommunity *ecom; - int i; + uint32_t i; assert(attr); /* Route should have valid RT to be even considered. */ @@ -3260,7 +3260,7 @@ static int bgp_evpn_install_uninstall_table(struct bgp *bgp, afi_t afi, struct prefix_evpn *evp = (struct prefix_evpn *)p; struct attr *attr = pi->attr; struct ecommunity *ecom; - int i; + uint32_t i; struct prefix_evpn ad_evp; assert(attr); @@ -4906,7 +4906,7 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, */ void bgp_evpn_map_vrf_to_its_rts(struct bgp *bgp_vrf) { - int i = 0; + uint32_t i = 0; struct ecommunity_val *eval = NULL; struct listnode *node = NULL, *nnode = NULL; struct ecommunity *ecom = NULL; @@ -4926,7 +4926,7 @@ void bgp_evpn_map_vrf_to_its_rts(struct bgp *bgp_vrf) */ void bgp_evpn_unmap_vrf_from_its_rts(struct bgp *bgp_vrf) { - int i; + uint32_t i; struct ecommunity_val *eval; struct listnode *node, *nnode; struct ecommunity *ecom; @@ -4963,7 +4963,7 @@ void bgp_evpn_unmap_vrf_from_its_rts(struct bgp *bgp_vrf) */ void bgp_evpn_map_vni_to_its_rts(struct bgp *bgp, struct bgpevpn *vpn) { - int i; + uint32_t i; struct ecommunity_val *eval; struct listnode *node, *nnode; struct ecommunity *ecom; @@ -4983,7 +4983,7 @@ void bgp_evpn_map_vni_to_its_rts(struct bgp *bgp, struct bgpevpn *vpn) */ void bgp_evpn_unmap_vni_from_its_rts(struct bgp *bgp, struct bgpevpn *vpn) { - int i; + uint32_t i; struct ecommunity_val *eval; struct listnode *node, *nnode; struct ecommunity *ecom; diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index a4d17cac40..cec4a9339a 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -469,6 +469,7 @@ void bgp_timer_set(struct peer *peer) BGP_TIMER_OFF(peer->t_gr_restart); BGP_TIMER_OFF(peer->t_gr_stale); BGP_TIMER_OFF(peer->t_pmax_restart); + BGP_TIMER_OFF(peer->t_refresh_stalepath); /* fallthru */ case Clearing: BGP_TIMER_OFF(peer->t_start); @@ -1283,6 +1284,16 @@ int bgp_stop(struct peer *peer) peer->nsf[afi][safi] = 0; } + /* Stop route-refresh stalepath timer */ + if (peer->t_refresh_stalepath) { + BGP_TIMER_OFF(peer->t_refresh_stalepath); + + if (bgp_debug_neighbor_events(peer)) + zlog_debug( + "%s: route-refresh restart stalepath timer stopped", + peer->host); + } + /* If peer reset before receiving EOR, decrement EOR count and * cancel the selection deferral timer if there are no * pending EOR messages to be received @@ -2066,14 +2077,16 @@ static int bgp_establish(struct peer *peer) PEER_CAP_ORF_PREFIX_SM_ADV)) { if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV)) - bgp_route_refresh_send(peer, afi, safi, - ORF_TYPE_PREFIX, - REFRESH_IMMEDIATE, 0); + bgp_route_refresh_send( + peer, afi, safi, ORF_TYPE_PREFIX, + REFRESH_IMMEDIATE, 0, + BGP_ROUTE_REFRESH_NORMAL); else if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV)) - bgp_route_refresh_send(peer, afi, safi, - ORF_TYPE_PREFIX_OLD, - REFRESH_IMMEDIATE, 0); + bgp_route_refresh_send( + peer, afi, safi, ORF_TYPE_PREFIX_OLD, + REFRESH_IMMEDIATE, 0, + BGP_ROUTE_REFRESH_NORMAL); } } diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index f961647778..3cb3d06217 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -60,6 +60,7 @@ #include "bgpd/bgp_keepalives.h" #include "bgpd/bgp_network.h" #include "bgpd/bgp_errors.h" +#include "bgpd/bgp_script.h" #include "lib/routing_nb.h" #include "bgpd/bgp_nb.h" #include "bgpd/bgp_evpn_mh.h" @@ -253,6 +254,7 @@ static __attribute__((__noreturn__)) void bgp_exit(int status) bf_free(bm->rd_idspace); list_delete(&bm->bgp); + list_delete(&bm->addresses); bgp_lp_finish(); @@ -404,12 +406,16 @@ int main(int argc, char **argv) int tmp_port; int bgp_port = BGP_PORT_DEFAULT; - char *bgp_address = NULL; + struct list *addresses = list_new(); int no_fib_flag = 0; int no_zebra_flag = 0; int skip_runas = 0; int instance = 0; int buffer_size = BGP_SOCKET_SNDBUF_SIZE; + char *address; + struct listnode *node; + + addresses->cmp = (int (*)(void *, void *))strcmp; frr_preinit(&bgpd_di, argc, argv); frr_opt_add( @@ -463,7 +469,7 @@ int main(int argc, char **argv) break; } case 'l': - bgp_address = optarg; + listnode_add_sort_nodup(addresses, optarg); /* listenon implies -n */ /* fallthru */ case 'n': @@ -493,11 +499,10 @@ int main(int argc, char **argv) memset(&bgpd_privs, 0, sizeof(bgpd_privs)); /* BGP master init. */ - bgp_master_init(frr_init(), buffer_size); + bgp_master_init(frr_init(), buffer_size, addresses); bm->port = bgp_port; if (bgp_port == 0) bgp_option_set(BGP_OPT_NO_LISTEN); - bm->address = bgp_address; if (no_fib_flag || no_zebra_flag) bgp_option_set(BGP_OPT_NO_FIB); if (no_zebra_flag) @@ -506,6 +511,10 @@ int main(int argc, char **argv) /* Initializations. */ bgp_vrf_init(); +#ifdef HAVE_SCRIPTING + bgp_script_init(); +#endif + hook_register(routing_conf_event, routing_control_plane_protocols_name_validate); @@ -513,8 +522,16 @@ int main(int argc, char **argv) /* BGP related initialization. */ bgp_init((unsigned short)instance); - snprintf(bgpd_di.startinfo, sizeof(bgpd_di.startinfo), ", bgp@%s:%d", - (bm->address ? bm->address : "<all>"), bm->port); + if (list_isempty(bm->addresses)) { + snprintf(bgpd_di.startinfo, sizeof(bgpd_di.startinfo), + ", bgp@<all>:%d", bm->port); + } else { + for (ALL_LIST_ELEMENTS_RO(bm->addresses, node, address)) + snprintf(bgpd_di.startinfo + strlen(bgpd_di.startinfo), + sizeof(bgpd_di.startinfo) + - strlen(bgpd_di.startinfo), + ", bgp@%s:%d", address, bm->port); + } frr_config_fork(); /* must be called after fork() */ diff --git a/bgpd/bgp_memory.c b/bgpd/bgp_memory.c index f9aac35d05..0013eb2df2 100644 --- a/bgpd/bgp_memory.c +++ b/bgpd/bgp_memory.c @@ -98,6 +98,7 @@ DEFINE_MTYPE(BGPD, PEER_UPDATE_SOURCE, "BGP peer update interface") DEFINE_MTYPE(BGPD, PEER_CONF_IF, "BGP peer config interface") DEFINE_MTYPE(BGPD, BGP_DAMP_INFO, "Dampening info") DEFINE_MTYPE(BGPD, BGP_DAMP_ARRAY, "BGP Dampening array") +DEFINE_MTYPE(BGPD, BGP_DAMP_REUSELIST, "BGP Dampening reuse list") DEFINE_MTYPE(BGPD, BGP_REGEXP, "BGP regexp") DEFINE_MTYPE(BGPD, BGP_AGGREGATE, "BGP aggregate") DEFINE_MTYPE(BGPD, BGP_ADDR, "BGP own address") diff --git a/bgpd/bgp_memory.h b/bgpd/bgp_memory.h index a95d9ef931..63998e95ac 100644 --- a/bgpd/bgp_memory.h +++ b/bgpd/bgp_memory.h @@ -94,6 +94,7 @@ DECLARE_MTYPE(PEER_UPDATE_SOURCE) DECLARE_MTYPE(PEER_CONF_IF) DECLARE_MTYPE(BGP_DAMP_INFO) DECLARE_MTYPE(BGP_DAMP_ARRAY) +DECLARE_MTYPE(BGP_DAMP_REUSELIST) DECLARE_MTYPE(BGP_REGEXP) DECLARE_MTYPE(BGP_AGGREGATE) DECLARE_MTYPE(BGP_ADDR) diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 3bc4c03233..1d66d75288 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -419,8 +419,7 @@ int vpn_leak_label_callback( static bool ecom_intersect(struct ecommunity *e1, struct ecommunity *e2) { - int i; - int j; + uint32_t i, j; if (!e1 || !e2) return false; diff --git a/bgpd/bgp_nb.c b/bgpd/bgp_nb.c index 08ec64242d..f65a4be677 100644 --- a/bgpd/bgp_nb.c +++ b/bgpd/bgp_nb.c @@ -3092,6 +3092,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/rmap-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/plist-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/plist-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/access-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/access-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/add-paths/path-type", .cbs = { .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify, @@ -3324,6 +3394,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/rmap-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/plist-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/plist-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/access-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/access-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/add-paths/path-type", .cbs = { .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify, @@ -3556,6 +3696,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/rmap-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/plist-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/plist-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/access-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/access-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/add-paths/path-type", .cbs = { .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify, @@ -3788,6 +3998,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/rmap-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/plist-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/plist-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/access-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/access-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/add-paths/path-type", .cbs = { .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify, @@ -4020,6 +4300,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/rmap-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/plist-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/plist-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/access-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/access-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/add-paths/path-type", .cbs = { .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify, @@ -4212,6 +4562,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/rmap-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/plist-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/plist-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/access-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/access-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/add-paths/path-type", .cbs = { .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify, @@ -4404,6 +4824,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/rmap-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/plist-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/plist-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/access-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/access-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-as", .cbs = { .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify, @@ -4472,6 +4962,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/rmap-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/rmap-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/plist-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/plist-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/access-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/access-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/route-reflector/route-reflector-client", .cbs = { .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify, @@ -4490,6 +5050,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/rmap-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/rmap-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/plist-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/plist-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/access-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/access-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/route-reflector/route-reflector-client", .cbs = { .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify, @@ -4508,6 +5138,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/rmap-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/rmap-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/plist-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/plist-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/access-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/access-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_import_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_export_modify, + .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/add-paths/path-type", .cbs = { .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify, @@ -5048,6 +5748,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/rmap-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/plist-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/plist-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/access-list-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/access-list-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/add-paths/path-type", .cbs = { .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify, @@ -5279,6 +6049,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/rmap-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/plist-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/plist-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/access-list-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/access-list-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/add-paths/path-type", .cbs = { .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify, @@ -5510,6 +6350,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/rmap-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/plist-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/plist-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/access-list-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/access-list-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/add-paths/path-type", .cbs = { .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify, @@ -5742,6 +6652,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/rmap-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/plist-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/plist-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/access-list-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/access-list-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/add-paths/path-type", .cbs = { .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify, @@ -6444,6 +7424,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/rmap-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/rmap-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/plist-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/plist-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/access-list-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/access-list-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/route-reflector/route-reflector-client", .cbs = { .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify, @@ -6462,6 +7512,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/rmap-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/rmap-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/plist-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/plist-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/access-list-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/access-list-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_import_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_export_modify, + .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/add-paths/path-type", .cbs = { .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify, @@ -7002,6 +8122,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/filter-config/rmap-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/filter-config/plist-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/filter-config/plist-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/filter-config/access-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/filter-config/access-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/add-paths/path-type", .cbs = { .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify, @@ -7240,6 +8430,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/filter-config/rmap-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/filter-config/plist-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/filter-config/plist-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/filter-config/access-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/filter-config/access-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/add-paths/path-type", .cbs = { .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify, @@ -7478,6 +8738,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/filter-config/rmap-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/filter-config/plist-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/filter-config/plist-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/filter-config/access-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/filter-config/access-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/add-paths/path-type", .cbs = { .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify, @@ -7710,6 +9040,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/rmap-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/plist-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/plist-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/access-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/access-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/add-paths/path-type", .cbs = { .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify, @@ -7942,6 +9342,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/rmap-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/plist-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/plist-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/access-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/access-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/add-paths/path-type", .cbs = { .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify, @@ -8134,6 +9604,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/rmap-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/plist-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/plist-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/access-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/access-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/add-paths/path-type", .cbs = { .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify, @@ -8326,6 +9866,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/rmap-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/rmap-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/plist-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/plist-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/access-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/access-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-as", .cbs = { .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify, @@ -8412,6 +10022,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/filter-config/rmap-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/filter-config/rmap-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/filter-config/plist-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/filter-config/plist-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/filter-config/access-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/filter-config/access-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/route-reflector/route-reflector-client", .cbs = { .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify, @@ -8430,6 +10110,76 @@ const struct frr_yang_module_info frr_bgp_info = { } }, { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/filter-config/rmap-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/filter-config/rmap-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/filter-config/plist-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/filter-config/plist-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/filter-config/access-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/filter-config/access-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/filter-config/as-path-filter-list-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/filter-config/as-path-filter-list-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_export_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/filter-config/unsuppress-map-import", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_import_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_import_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/filter-config/unsuppress-map-export", + .cbs = { + .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_export_modify, + .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_export_destroy, + } + }, + { .xpath = NULL, }, } diff --git a/bgpd/bgp_nb.h b/bgpd/bgp_nb.h index 9c81c2457e..eb7725d3dd 100644 --- a/bgpd/bgp_nb.h +++ b/bgpd/bgp_nb.h @@ -1329,6 +1329,46 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_soft_reconfiguration_ struct nb_cb_modify_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_modify( struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_destroy( struct nb_cb_destroy_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify( @@ -1431,6 +1471,46 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attri struct nb_cb_modify_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_destroy( struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify( struct nb_cb_modify_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_modify( @@ -1531,6 +1611,46 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attri struct nb_cb_modify_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_destroy( struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify( struct nb_cb_modify_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_modify( @@ -1631,6 +1751,46 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight struct nb_cb_modify_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_destroy( struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify( struct nb_cb_modify_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_modify( @@ -1731,6 +1891,46 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight struct nb_cb_modify_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_destroy( struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify( struct nb_cb_modify_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_modify( @@ -1813,6 +2013,46 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_a struct nb_cb_modify_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_destroy( struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify( struct nb_cb_modify_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_modify( @@ -1895,6 +2135,46 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_a struct nb_cb_modify_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_destroy( struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify( struct nb_cb_modify_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_destroy( @@ -1921,18 +2201,138 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_server_route_serv struct nb_cb_modify_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_modify( struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify( struct nb_cb_modify_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_server_route_server_client_modify( struct nb_cb_modify_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration_modify( struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify( struct nb_cb_modify_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_server_route_server_client_modify( struct nb_cb_modify_args *args); int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify( struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify( struct nb_cb_modify_args *args); int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_modify( @@ -2175,6 +2575,46 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_wei struct nb_cb_modify_args *args); int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_destroy( struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify( struct nb_cb_modify_args *args); int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_modify( @@ -2275,6 +2715,46 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_w struct nb_cb_modify_args *args); int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_destroy( struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify( struct nb_cb_modify_args *args); int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_modify( @@ -2375,6 +2855,46 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_w struct nb_cb_modify_args *args); int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_destroy( struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify( struct nb_cb_modify_args *args); int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_modify( @@ -2475,6 +2995,46 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_we struct nb_cb_modify_args *args); int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_destroy( struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify( struct nb_cb_modify_args *args); int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_modify( @@ -2771,12 +3331,92 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_ser struct nb_cb_modify_args *args); int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration_modify( struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify( struct nb_cb_modify_args *args); int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_server_route_server_client_modify( struct nb_cb_modify_args *args); int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify( struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify( struct nb_cb_modify_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_modify( @@ -3019,6 +3659,46 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_weight_weight_att struct nb_cb_modify_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_destroy( struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify( struct nb_cb_modify_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_modify( @@ -3119,6 +3799,46 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_weight_weight_a struct nb_cb_modify_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_destroy( struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify( struct nb_cb_modify_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_modify( @@ -3219,6 +3939,46 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_weight_weight_a struct nb_cb_modify_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_destroy( struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify( struct nb_cb_modify_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_modify( @@ -3319,6 +4079,46 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_weight_we struct nb_cb_modify_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_destroy( struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify( struct nb_cb_modify_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_modify( @@ -3419,6 +4219,46 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_weight_we struct nb_cb_modify_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_destroy( struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify( struct nb_cb_modify_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_modify( @@ -3501,6 +4341,46 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weig struct nb_cb_modify_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_destroy( struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify( struct nb_cb_modify_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_modify( @@ -3583,6 +4463,46 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weig struct nb_cb_modify_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_destroy( struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify( struct nb_cb_modify_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_destroy( @@ -3615,12 +4535,92 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_route_server_rou struct nb_cb_modify_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration_modify( struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify( struct nb_cb_modify_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_route_server_route_server_client_modify( struct nb_cb_modify_args *args); int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify( struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args); +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args); /* * Callback registered with routing_nb lib to validate only diff --git a/bgpd/bgp_nb_config.c b/bgpd/bgp_nb_config.c index f6a138ba45..531ff4a60a 100644 --- a/bgpd/bgp_nb_config.c +++ b/bgpd/bgp_nb_config.c @@ -15124,6 +15124,66 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_bo return NB_OK; } +static int bgp_neighbor_afi_safi_rmap_modify(struct nb_cb_modify_args *args, + int direct) +{ + struct bgp *bgp; + const char *peer_str; + struct peer *peer; + const struct lyd_node *nbr_dnode; + const struct lyd_node *nbr_af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + const char *name_str; + struct route_map *route_map; + int ret; + + nbr_af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(nbr_af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + nbr_dnode = yang_dnode_get_parent(nbr_af_dnode, "neighbor"); + bgp = nb_running_get_entry(nbr_dnode, NULL, true); + peer_str = yang_dnode_get_string(nbr_dnode, "./remote-address"); + peer = bgp_neighbor_peer_lookup(bgp, peer_str, args->errmsg, + args->errmsg_len); + + name_str = yang_dnode_get_string(args->dnode, NULL); + route_map = route_map_lookup_by_name(name_str); + ret = peer_route_map_set(peer, afi, safi, direct, name_str, route_map); + + return bgp_nb_errmsg_return(args->errmsg, args->errmsg_len, ret); +} + +static int bgp_neighbor_afi_safi_rmap_destroy(struct nb_cb_destroy_args *args, + int direct) +{ + struct bgp *bgp; + const char *peer_str; + struct peer *peer; + const struct lyd_node *nbr_dnode; + const struct lyd_node *nbr_af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + int ret; + + nbr_af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(nbr_af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + nbr_dnode = yang_dnode_get_parent(nbr_af_dnode, "neighbor"); + bgp = nb_running_get_entry(nbr_dnode, NULL, true); + peer_str = yang_dnode_get_string(nbr_dnode, "./remote-address"); + peer = bgp_neighbor_peer_lookup(bgp, peer_str, args->errmsg, + args->errmsg_len); + + ret = peer_route_map_unset(peer, afi, safi, direct); + + return bgp_nb_errmsg_return(args->errmsg, args->errmsg_len, ret); +} + /* * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-import @@ -15135,9 +15195,9 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_im case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_IN); } return NB_OK; @@ -15150,9 +15210,9 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_im case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_IN); } return NB_OK; @@ -15169,9 +15229,9 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_ex case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_OUT); } return NB_OK; @@ -15184,14 +15244,72 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_ex case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_OUT); } return NB_OK; } +static int bgp_neighbor_afi_safi_plist_modify(struct nb_cb_modify_args *args, + int direct) +{ + struct bgp *bgp; + const char *peer_str; + struct peer *peer; + const struct lyd_node *nbr_dnode; + const struct lyd_node *nbr_af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + const char *name_str; + + nbr_af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(nbr_af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + nbr_dnode = yang_dnode_get_parent(nbr_af_dnode, "neighbor"); + bgp = nb_running_get_entry(nbr_dnode, NULL, true); + peer_str = yang_dnode_get_string(nbr_dnode, "./remote-address"); + peer = bgp_neighbor_peer_lookup(bgp, peer_str, args->errmsg, + args->errmsg_len); + + name_str = yang_dnode_get_string(args->dnode, NULL); + if (peer_prefix_list_set(peer, afi, safi, direct, name_str) < 0) + return NB_ERR_INCONSISTENCY; + + return NB_OK; +} + +static int bgp_neighbor_afi_safi_plist_destroy(struct nb_cb_destroy_args *args, + int direct) +{ + struct bgp *bgp; + const char *peer_str; + struct peer *peer; + const struct lyd_node *nbr_dnode; + const struct lyd_node *nbr_af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + + nbr_af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(nbr_af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + nbr_dnode = yang_dnode_get_parent(nbr_af_dnode, "neighbor"); + bgp = nb_running_get_entry(nbr_dnode, NULL, true); + peer_str = yang_dnode_get_string(nbr_dnode, "./remote-address"); + peer = bgp_neighbor_peer_lookup(bgp, peer_str, args->errmsg, + args->errmsg_len); + + if (peer_prefix_list_unset(peer, afi, safi, direct) < 0) + return NB_ERR_INCONSISTENCY; + + return NB_OK; +} + /* * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-import @@ -15203,9 +15321,9 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_i case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_IN); } return NB_OK; @@ -15218,9 +15336,9 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_i case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_IN); } return NB_OK; @@ -15237,9 +15355,9 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_e case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_OUT); } return NB_OK; @@ -15252,9 +15370,9 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_e case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_OUT); } return NB_OK; @@ -16443,6 +16561,347 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribu /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/rmap-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_IN); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/rmap-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/plist-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_IN); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/plist-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/access-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/access-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/as-path-filter-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/as-path-filter-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/unsuppress-map-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/unsuppress-map-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/add-paths/path-type */ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify( @@ -17401,6 +17860,346 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attri /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/rmap-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_IN); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/rmap-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/plist-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_IN); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/plist-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/access-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/access-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/as-path-filter-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/as-path-filter-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/unsuppress-map-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/unsuppress-map-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/add-paths/path-type */ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify( @@ -18359,6 +19158,346 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attri /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/rmap-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_IN); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/rmap-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/plist-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_IN); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/plist-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/access-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/access-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/as-path-filter-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/as-path-filter-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/unsuppress-map-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/unsuppress-map-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/add-paths/path-type */ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify( @@ -19317,6 +20456,346 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/rmap-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_IN); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/rmap-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/plist-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_IN); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/plist-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/access-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/access-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/as-path-filter-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/as-path-filter-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/unsuppress-map-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/unsuppress-map-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/add-paths/path-type */ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify( @@ -20275,6 +21754,346 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/rmap-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_IN); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/rmap-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/plist-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/plist-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/access-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/access-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/as-path-filter-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/as-path-filter-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/unsuppress-map-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/unsuppress-map-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/add-paths/path-type */ int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify( @@ -21078,6 +22897,346 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_a /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/rmap-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_IN); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/rmap-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/plist-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/plist-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/access-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/access-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/as-path-filter-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/as-path-filter-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/unsuppress-map-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/unsuppress-map-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/add-paths/path-type */ int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify( @@ -21881,6 +24040,346 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_a /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/rmap-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_IN); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/rmap-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/plist-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_IN); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/plist-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/access-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/access-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/as-path-filter-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/as-path-filter-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/unsuppress-map-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/unsuppress-map-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-as */ int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify( @@ -22156,6 +24655,346 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_mo /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/rmap-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_IN); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/rmap-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/plist-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_IN); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/plist-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/access-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/access-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/as-path-filter-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/as-path-filter-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/unsuppress-map-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/filter-config/unsuppress-map-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/route-reflector/route-reflector-client */ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify( @@ -22225,6 +25064,346 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/rmap-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_IN); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/rmap-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/plist-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_IN); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/plist-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/access-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/access-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/as-path-filter-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/as-path-filter-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/unsuppress-map-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/unsuppress-map-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/route-reflector/route-reflector-client */ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify( @@ -22292,6 +25471,346 @@ int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration return NB_OK; } +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/rmap-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_IN); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/rmap-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_modify(args, RMAP_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_rmap_destroy(args, RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/plist-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_IN); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/plist-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_modify(args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_neighbor_afi_safi_plist_destroy(args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/access-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/access-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/as-path-filter-list-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/as-path-filter-list-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/unsuppress-map-import + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/unsuppress-map-export + */ +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + static int bgp_unnumbered_neighbor_afi_safi_flag_modify(struct nb_cb_modify_args *args, uint32_t flags, bool set) @@ -23442,6 +26961,68 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capabi return NB_OK; } +static int +bgp_unnumbered_neighbor_afi_safi_rmap_modify(struct nb_cb_modify_args *args, + int direct) +{ + struct bgp *bgp; + const char *peer_str; + struct peer *peer; + const struct lyd_node *nbr_dnode; + const struct lyd_node *nbr_af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + const char *name_str; + struct route_map *route_map; + int ret; + + nbr_af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(nbr_af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + nbr_dnode = yang_dnode_get_parent(nbr_af_dnode, "unnumbered-neighbor"); + bgp = nb_running_get_entry(nbr_dnode, NULL, true); + peer_str = yang_dnode_get_string(nbr_dnode, "./interface"); + peer = bgp_unnumbered_neighbor_peer_lookup(bgp, peer_str, args->errmsg, + args->errmsg_len); + + name_str = yang_dnode_get_string(args->dnode, NULL); + route_map = route_map_lookup_by_name(name_str); + ret = peer_route_map_set(peer, afi, safi, direct, name_str, route_map); + + return bgp_nb_errmsg_return(args->errmsg, args->errmsg_len, ret); +} + +static int +bgp_unnumbered_neighbor_afi_safi_rmap_destroy(struct nb_cb_destroy_args *args, + int direct) +{ + struct bgp *bgp; + const char *peer_str; + struct peer *peer; + const struct lyd_node *nbr_dnode; + const struct lyd_node *nbr_af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + int ret; + + nbr_af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(nbr_af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + nbr_dnode = yang_dnode_get_parent(nbr_af_dnode, "unnumbered-neighbor"); + bgp = nb_running_get_entry(nbr_dnode, NULL, true); + peer_str = yang_dnode_get_string(nbr_dnode, "./interface"); + peer = bgp_unnumbered_neighbor_peer_lookup(bgp, peer_str, args->errmsg, + args->errmsg_len); + + ret = peer_route_map_unset(peer, afi, safi, direct); + + return bgp_nb_errmsg_return(args->errmsg, args->errmsg_len, ret); +} + /* * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-import @@ -23453,9 +27034,10 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_con case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_modify(args, + RMAP_IN); } return NB_OK; @@ -23468,9 +27050,10 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_con case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_destroy(args, + RMAP_IN); } return NB_OK; @@ -23487,9 +27070,10 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_con case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_modify(args, + RMAP_OUT); } return NB_OK; @@ -23502,14 +27086,74 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_con case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_destroy(args, + RMAP_OUT); } return NB_OK; } +static int +bgp_unnumbered_neighbor_afi_safi_plist_modify(struct nb_cb_modify_args *args, + int direct) +{ + struct bgp *bgp; + const char *peer_str; + struct peer *peer; + const struct lyd_node *nbr_dnode; + const struct lyd_node *nbr_af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + const char *name_str; + + nbr_af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(nbr_af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + nbr_dnode = yang_dnode_get_parent(nbr_af_dnode, "unnumbered-neighbor"); + bgp = nb_running_get_entry(nbr_dnode, NULL, true); + peer_str = yang_dnode_get_string(nbr_dnode, "./interface"); + peer = bgp_unnumbered_neighbor_peer_lookup(bgp, peer_str, args->errmsg, + args->errmsg_len); + + name_str = yang_dnode_get_string(args->dnode, NULL); + if (peer_prefix_list_set(peer, afi, safi, direct, name_str) < 0) + return NB_ERR_INCONSISTENCY; + + return NB_OK; +} + +static int +bgp_unnumbered_neighbor_afi_safi_plist_destroy(struct nb_cb_destroy_args *args, + int direct) +{ + struct bgp *bgp; + const char *peer_str; + struct peer *peer; + const struct lyd_node *nbr_dnode; + const struct lyd_node *nbr_af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + + nbr_af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(nbr_af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + + nbr_dnode = yang_dnode_get_parent(nbr_af_dnode, "unnumbered-neighbor"); + bgp = nb_running_get_entry(nbr_dnode, NULL, true); + peer_str = yang_dnode_get_string(nbr_dnode, "./interface"); + peer = bgp_unnumbered_neighbor_peer_lookup(bgp, peer_str, args->errmsg, + args->errmsg_len); + + if (peer_prefix_list_unset(peer, afi, safi, direct) < 0) + return NB_ERR_INCONSISTENCY; + + return NB_OK; +} /* * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-import @@ -23521,9 +27165,10 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_con case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_modify(args, + FILTER_IN); } return NB_OK; @@ -23536,9 +27181,10 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_con case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_destroy( + args, FILTER_IN); } return NB_OK; @@ -23555,9 +27201,10 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_con case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_modify( + args, FILTER_OUT); } return NB_OK; @@ -23570,9 +27217,10 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_con case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_destroy( + args, FILTER_OUT); } return NB_OK; @@ -24762,6 +28410,354 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_wei /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/rmap-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_modify(args, + RMAP_IN); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_destroy(args, + RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/rmap-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_modify(args, + RMAP_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_destroy(args, + RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/plist-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_modify(args, + FILTER_IN); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_destroy( + args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/plist-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_modify( + args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_destroy( + args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/access-list-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/access-list-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/as-path-filter-list-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/as-path-filter-list-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/unsuppress-map-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/filter-config/unsuppress-map-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/add-paths/path-type */ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify( @@ -25721,6 +29717,354 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_w /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/rmap-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_modify(args, + RMAP_IN); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_destroy(args, + RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/rmap-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_modify(args, + RMAP_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_destroy(args, + RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/plist-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_modify(args, + FILTER_IN); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_destroy( + args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/plist-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_modify( + args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_destroy( + args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/access-list-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/access-list-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/as-path-filter-list-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/as-path-filter-list-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/unsuppress-map-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/filter-config/unsuppress-map-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/add-paths/path-type */ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify( @@ -26680,6 +31024,355 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_w /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/rmap-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_modify(args, + RMAP_IN); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_destroy(args, + RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/rmap-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_modify(args, + RMAP_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_destroy(args, + RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/plist-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_modify(args, + FILTER_IN); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_destroy( + args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/plist-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_modify( + args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_destroy( + args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/access-list-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/access-list-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/as-path-filter-list-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/as-path-filter-list-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/unsuppress-map-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/filter-config/unsuppress-map-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/add-paths/path-type */ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify( @@ -27639,6 +32332,354 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_we /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/rmap-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_modify(args, + RMAP_IN); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_destroy(args, + RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/rmap-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_modify(args, + RMAP_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_destroy(args, + RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/plist-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_modify(args, + FILTER_IN); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_destroy( + args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/plist-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_modify( + args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_destroy( + args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/access-list-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/access-list-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/as-path-filter-list-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/as-path-filter-list-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/unsuppress-map-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/unsuppress-map-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/add-paths/path-type */ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify( @@ -30550,6 +35591,354 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_soft_reco /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/rmap-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_modify(args, + RMAP_IN); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_destroy(args, + RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/rmap-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_modify(args, + RMAP_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_destroy(args, + RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/plist-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_modify(args, + FILTER_IN); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_destroy( + args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/plist-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_modify( + args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_destroy( + args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/access-list-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/access-list-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/as-path-filter-list-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/as-path-filter-list-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/unsuppress-map-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/filter-config/unsuppress-map-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/route-reflector/route-reflector-client */ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify( @@ -30617,6 +36006,354 @@ int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_soft_reco return NB_OK; } +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/rmap-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_modify(args, + RMAP_IN); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_destroy(args, + RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/rmap-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_modify(args, + RMAP_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_rmap_destroy(args, + RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/plist-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_modify(args, + FILTER_IN); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_destroy( + args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/plist-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_modify( + args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_unnumbered_neighbor_afi_safi_plist_destroy( + args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/access-list-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/access-list-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/as-path-filter-list-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/as-path-filter-list-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/unsuppress-map-import + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/filter-config/unsuppress-map-export + */ +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + static int bgp_peer_group_afi_safi_flag_modify(struct nb_cb_modify_args *args, uint32_t flags, bool set) { @@ -31755,6 +37492,62 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_or return NB_OK; } +static int bgp_peer_group_afi_safi_rmap_modify(struct nb_cb_modify_args *args, + int direct) +{ + struct bgp *bgp; + const char *peer_str; + struct peer *peer; + const struct lyd_node *nbr_dnode; + const struct lyd_node *nbr_af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + const char *name_str; + struct route_map *route_map; + int ret; + + nbr_af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(nbr_af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + nbr_dnode = yang_dnode_get_parent(nbr_af_dnode, "peer-group"); + bgp = nb_running_get_entry(nbr_dnode, NULL, true); + peer_str = yang_dnode_get_string(nbr_dnode, "./peer-group-name"); + peer = bgp_peer_group_peer_lookup(bgp, peer_str); + + name_str = yang_dnode_get_string(args->dnode, NULL); + route_map = route_map_lookup_by_name(name_str); + ret = peer_route_map_set(peer, afi, safi, direct, name_str, route_map); + + return bgp_nb_errmsg_return(args->errmsg, args->errmsg_len, ret); +} + +static int bgp_peer_group_afi_safi_rmap_destroy(struct nb_cb_destroy_args *args, + int direct) +{ + struct bgp *bgp; + const char *peer_str; + struct peer *peer; + const struct lyd_node *nbr_dnode; + const struct lyd_node *nbr_af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + int ret; + + nbr_af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(nbr_af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + nbr_dnode = yang_dnode_get_parent(nbr_af_dnode, "peer-group"); + bgp = nb_running_get_entry(nbr_dnode, NULL, true); + peer_str = yang_dnode_get_string(nbr_dnode, "./peer-group-name"); + peer = bgp_peer_group_peer_lookup(bgp, peer_str); + + ret = peer_route_map_unset(peer, afi, safi, direct); + + return bgp_nb_errmsg_return(args->errmsg, args->errmsg_len, ret); +} + /* * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-import @@ -31766,9 +37559,9 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rma case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_IN); } return NB_OK; @@ -31781,9 +37574,9 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rma case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_IN); } return NB_OK; @@ -31800,9 +37593,9 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rma case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_OUT); } return NB_OK; @@ -31815,14 +37608,69 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rma case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_OUT); } return NB_OK; } +static int bgp_peer_group_afi_safi_plist_modify(struct nb_cb_modify_args *args, + int direct) +{ + struct bgp *bgp; + const char *peer_str; + struct peer *peer; + const struct lyd_node *nbr_dnode; + const struct lyd_node *nbr_af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + const char *name_str; + + nbr_af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(nbr_af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + nbr_dnode = yang_dnode_get_parent(nbr_af_dnode, "peer-group"); + bgp = nb_running_get_entry(nbr_dnode, NULL, true); + peer_str = yang_dnode_get_string(nbr_dnode, "./peer-group-name"); + peer = bgp_peer_group_peer_lookup(bgp, peer_str); + + name_str = yang_dnode_get_string(args->dnode, NULL); + if (peer_prefix_list_set(peer, afi, safi, direct, name_str) < 0) + return NB_ERR_INCONSISTENCY; + + return NB_OK; +} + +static int +bgp_peer_group_afi_safi_plist_destroy(struct nb_cb_destroy_args *args, + int direct) +{ + struct bgp *bgp; + const char *peer_str; + struct peer *peer; + const struct lyd_node *nbr_dnode; + const struct lyd_node *nbr_af_dnode; + const char *af_name; + afi_t afi; + safi_t safi; + + nbr_af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi"); + af_name = yang_dnode_get_string(nbr_af_dnode, "./afi-safi-name"); + yang_afi_safi_identity2value(af_name, &afi, &safi); + nbr_dnode = yang_dnode_get_parent(nbr_af_dnode, "peer-group"); + bgp = nb_running_get_entry(nbr_dnode, NULL, true); + peer_str = yang_dnode_get_string(nbr_dnode, "./peer-group-name"); + peer = bgp_peer_group_peer_lookup(bgp, peer_str); + + if (peer_prefix_list_unset(peer, afi, safi, direct) < 0) + return NB_ERR_INCONSISTENCY; + + return NB_OK; +} + /* * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-import @@ -31834,9 +37682,9 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_pli case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_modify(args, FILTER_IN); } return NB_OK; @@ -31849,9 +37697,9 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_pli case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_IN); } return NB_OK; @@ -31868,9 +37716,9 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_pli case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_modify(args, FILTER_OUT); } return NB_OK; @@ -31883,9 +37731,9 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_pli case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_OUT); } return NB_OK; @@ -33074,6 +38922,346 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_weight_weight_att /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/filter-config/rmap-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_IN); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/filter-config/rmap-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_OUT); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/filter-config/plist-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_modify(args, FILTER_IN); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/filter-config/plist-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_modify(args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/filter-config/access-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/filter-config/access-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/filter-config/as-path-filter-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/filter-config/as-path-filter-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/filter-config/unsuppress-map-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/filter-config/unsuppress-map-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/add-paths/path-type */ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify( @@ -34032,6 +40220,346 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_weight_weight_a /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/filter-config/rmap-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_IN); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/filter-config/rmap-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_OUT); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/filter-config/plist-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_modify(args, FILTER_IN); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/filter-config/plist-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_modify(args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/filter-config/access-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/filter-config/access-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/filter-config/as-path-filter-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/filter-config/as-path-filter-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/filter-config/unsuppress-map-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/filter-config/unsuppress-map-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/add-paths/path-type */ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify( @@ -34990,6 +41518,346 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_weight_weight_a /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/filter-config/rmap-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_IN); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/filter-config/rmap-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_OUT); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/filter-config/plist-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_modify(args, FILTER_IN); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/filter-config/plist-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_modify(args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/filter-config/access-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/filter-config/access-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/filter-config/as-path-filter-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/filter-config/as-path-filter-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/filter-config/unsuppress-map-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/filter-config/unsuppress-map-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/add-paths/path-type */ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify( @@ -35948,6 +42816,346 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_weight_we /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/rmap-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_IN); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/rmap-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_OUT); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/plist-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_modify(args, FILTER_IN); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/plist-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_modify(args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/access-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/access-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/as-path-filter-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/as-path-filter-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/unsuppress-map-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/filter-config/unsuppress-map-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/add-paths/path-type */ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify( @@ -36906,6 +44114,346 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_weight_we /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/rmap-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_IN); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/rmap-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_OUT); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/plist-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_modify(args, FILTER_IN); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/plist-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_modify(args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/access-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/access-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/as-path-filter-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/as-path-filter-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/unsuppress-map-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/filter-config/unsuppress-map-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/add-paths/path-type */ int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify( @@ -37709,6 +45257,346 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weig /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/rmap-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_IN); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/rmap-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_OUT); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/plist-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_modify(args, FILTER_IN); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/plist-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_modify(args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/access-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/access-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/as-path-filter-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/as-path-filter-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/unsuppress-map-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/filter-config/unsuppress-map-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/add-paths/path-type */ int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify( @@ -38512,6 +46400,346 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weig /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/rmap-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_IN); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/rmap-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_OUT); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/plist-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_modify(args, FILTER_IN); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/plist-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_modify(args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/access-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/access-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/as-path-filter-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/as-path-filter-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/unsuppress-map-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/filter-config/unsuppress-map-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-as */ int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify( @@ -38856,6 +47084,346 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_soft_reconfigura /* * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/filter-config/rmap-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_IN); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/filter-config/rmap-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_OUT); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/filter-config/plist-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_modify(args, FILTER_IN); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/filter-config/plist-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_modify(args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/filter-config/access-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/filter-config/access-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/filter-config/as-path-filter-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/filter-config/as-path-filter-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/filter-config/unsuppress-map-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/filter-config/unsuppress-map-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/route-reflector/route-reflector-client */ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify( @@ -38922,3 +47490,343 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_soft_reconfigura return NB_OK; } + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/filter-config/rmap-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_IN); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/filter-config/rmap-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_modify(args, RMAP_OUT); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_rmap_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_IN); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/filter-config/plist-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_modify(args, FILTER_IN); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_rmap_destroy(args, RMAP_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/filter-config/plist-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_modify(args, FILTER_OUT); + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_plist_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + return bgp_peer_group_afi_safi_plist_destroy(args, FILTER_OUT); + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/filter-config/access-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/filter-config/access-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_access_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/filter-config/as-path-filter-list-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/filter-config/as-path-filter-list-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_as_path_filter_list_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/filter-config/unsuppress-map-import + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_import_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_import_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/filter-config/unsuppress-map-export + */ +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_export_modify( + struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_filter_config_unsuppress_map_export_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index 6cfcb9cc3d..533518cf93 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -760,6 +760,7 @@ static const struct message capcode_str[] = { {CAPABILITY_CODE_REFRESH_OLD, "Route Refresh (Old)"}, {CAPABILITY_CODE_ORF_OLD, "ORF (Old)"}, {CAPABILITY_CODE_FQDN, "FQDN"}, + {CAPABILITY_CODE_ENHANCED_RR, "Enhanced Route Refresh"}, {0}}; /* Minimum sizes for length field of each cap (so not inc. the header) */ @@ -776,6 +777,7 @@ static const size_t cap_minsizes[] = { [CAPABILITY_CODE_REFRESH_OLD] = CAPABILITY_CODE_REFRESH_LEN, [CAPABILITY_CODE_ORF_OLD] = CAPABILITY_CODE_ORF_LEN, [CAPABILITY_CODE_FQDN] = CAPABILITY_CODE_MIN_FQDN_LEN, + [CAPABILITY_CODE_ENHANCED_RR] = CAPABILITY_CODE_ENHANCED_LEN, }; /* value the capability must be a multiple of. @@ -796,6 +798,7 @@ static const size_t cap_modsizes[] = { [CAPABILITY_CODE_REFRESH_OLD] = 1, [CAPABILITY_CODE_ORF_OLD] = 1, [CAPABILITY_CODE_FQDN] = 1, + [CAPABILITY_CODE_ENHANCED_RR] = 1, }; /** @@ -863,6 +866,7 @@ static int bgp_capability_parse(struct peer *peer, size_t length, case CAPABILITY_CODE_DYNAMIC_OLD: case CAPABILITY_CODE_ENHE: case CAPABILITY_CODE_FQDN: + case CAPABILITY_CODE_ENHANCED_RR: /* Check length. */ if (caphdr.length < cap_minsizes[caphdr.code]) { zlog_info( @@ -913,10 +917,13 @@ static int bgp_capability_parse(struct peer *peer, size_t length, ret = 0; /* Don't return error for this */ } } break; + case CAPABILITY_CODE_ENHANCED_RR: case CAPABILITY_CODE_REFRESH: case CAPABILITY_CODE_REFRESH_OLD: { /* BGP refresh capability */ - if (caphdr.code == CAPABILITY_CODE_REFRESH_OLD) + if (caphdr.code == CAPABILITY_CODE_ENHANCED_RR) + SET_FLAG(peer->cap, PEER_CAP_ENHANCED_RR_RCV); + else if (caphdr.code == CAPABILITY_CODE_REFRESH_OLD) SET_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV); else SET_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV); @@ -1450,6 +1457,13 @@ void bgp_open_capability(struct stream *s, struct peer *peer) stream_putc(s, CAPABILITY_CODE_REFRESH); stream_putc(s, CAPABILITY_CODE_REFRESH_LEN); + /* Enhanced Route Refresh. */ + SET_FLAG(peer->cap, PEER_CAP_ENHANCED_RR_ADV); + stream_putc(s, BGP_OPEN_OPT_CAP); + stream_putc(s, CAPABILITY_CODE_ENHANCED_LEN + 2); + stream_putc(s, CAPABILITY_CODE_ENHANCED_RR); + stream_putc(s, CAPABILITY_CODE_ENHANCED_LEN); + /* AS4 */ SET_FLAG(peer->cap, PEER_CAP_AS4_ADV); stream_putc(s, BGP_OPEN_OPT_CAP); diff --git a/bgpd/bgp_open.h b/bgpd/bgp_open.h index 5250a68581..471ac05c7c 100644 --- a/bgpd/bgp_open.h +++ b/bgpd/bgp_open.h @@ -49,6 +49,7 @@ struct graceful_restart_af { #define CAPABILITY_CODE_DYNAMIC_OLD 66 /* Dynamic Capability, deprecated since 2003 */ #define CAPABILITY_CODE_DYNAMIC 67 /* Dynamic Capability */ #define CAPABILITY_CODE_ADDPATH 69 /* Addpath Capability */ +#define CAPABILITY_CODE_ENHANCED_RR 70 /* Enhanced Route Refresh capability */ #define CAPABILITY_CODE_FQDN 73 /* Advertise hostname capability */ #define CAPABILITY_CODE_ENHE 5 /* Extended Next Hop Encoding */ #define CAPABILITY_CODE_REFRESH_OLD 128 /* Route Refresh Capability(cisco) */ @@ -63,6 +64,7 @@ struct graceful_restart_af { #define CAPABILITY_CODE_ADDPATH_LEN 4 #define CAPABILITY_CODE_ENHE_LEN 6 /* NRLI AFI = 2, SAFI = 2, Nexthop AFI = 2 */ #define CAPABILITY_CODE_MIN_FQDN_LEN 2 +#define CAPABILITY_CODE_ENHANCED_LEN 0 #define CAPABILITY_CODE_ORF_LEN 5 /* Cooperative Route Filtering Capability. */ diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index b2b9e04bc3..b7ecd8a49b 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -444,13 +444,45 @@ int bgp_generate_updgrp_packets(struct thread *thread) * yet. */ if (!next_pkt || !next_pkt->buffer) { - /* Make sure we supress BGP UPDATES - * for normal processing later again. - */ - if (!paf->t_announce_route) + if (!paf->t_announce_route) { + /* Make sure we supress BGP UPDATES + * for normal processing later again. + */ UNSET_FLAG(paf->subgroup->sflags, SUBGRP_STATUS_FORCE_UPDATES); + /* If route-refresh BoRR message was + * already sent and we are done with + * re-announcing tables for a decent + * afi/safi, we ready to send + * EoRR request. + */ + if (CHECK_FLAG( + peer->af_sflags[afi][safi], + PEER_STATUS_BORR_SEND)) { + bgp_route_refresh_send( + peer, afi, safi, 0, 0, + 0, + BGP_ROUTE_REFRESH_EORR); + + SET_FLAG(peer->af_sflags[afi] + [safi], + PEER_STATUS_EORR_SEND); + UNSET_FLAG( + peer->af_sflags[afi] + [safi], + PEER_STATUS_BORR_SEND); + + if (bgp_debug_neighbor_events( + peer)) + zlog_debug( + "%s sending route-refresh (EoRR) for %s/%s", + peer->host, + afi2str(afi), + safi2str(safi)); + } + } + if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) { if (!(PAF_SUBGRP(paf))->t_coalesce @@ -816,7 +848,7 @@ void bgp_notify_send(struct peer *peer, uint8_t code, uint8_t sub_code) */ void bgp_route_refresh_send(struct peer *peer, afi_t afi, safi_t safi, uint8_t orf_type, uint8_t when_to_refresh, - int remove) + int remove, uint8_t subtype) { struct stream *s; struct bgp_filter *filter; @@ -842,7 +874,10 @@ void bgp_route_refresh_send(struct peer *peer, afi_t afi, safi_t safi, /* Encode Route Refresh message. */ stream_putw(s, pkt_afi); - stream_putc(s, 0); + if (subtype) + stream_putc(s, subtype); + else + stream_putc(s, 0); stream_putc(s, pkt_safi); if (orf_type == ORF_TYPE_PREFIX || orf_type == ORF_TYPE_PREFIX_OLD) @@ -1460,6 +1495,29 @@ static int bgp_keepalive_receive(struct peer *peer, bgp_size_t size) return Receive_KEEPALIVE_message; } +static int bgp_refresh_stalepath_timer_expire(struct thread *thread) +{ + struct peer_af *paf; + + paf = THREAD_ARG(thread); + + afi_t afi = paf->afi; + safi_t safi = paf->safi; + struct peer *peer = paf->peer; + + peer->t_refresh_stalepath = NULL; + + if (peer->nsf[afi][safi]) + bgp_clear_stale_route(peer, afi, safi); + + if (bgp_debug_neighbor_events(peer)) + zlog_debug("%s: route-refresh (BoRR) timer for %s/%s expired", + peer->host, afi2str(afi), safi2str(safi)); + + bgp_timer_set(peer); + + return 0; +} /** * Process BGP UPDATE message for peer. @@ -1888,6 +1946,9 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) struct peer_af *paf; struct update_group *updgrp; struct peer *updgrp_peer; + uint8_t subtype; + bgp_size_t msg_length = + size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE); /* If peer does not have the capability, send notification. */ if (!CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_ADV)) { @@ -1915,14 +1976,9 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) /* Parse packet. */ pkt_afi = stream_getw(s); - (void)stream_getc(s); + subtype = stream_getc(s); pkt_safi = stream_getc(s); - if (bgp_debug_update(peer, NULL, NULL, 0)) - zlog_debug("%s rcvd REFRESH_REQ for afi/safi: %s/%s", - peer->host, iana_afi2str(pkt_afi), - iana_safi2str(pkt_safi)); - /* Convert AFI, SAFI to internal values and check. */ if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) { zlog_info( @@ -1938,8 +1994,34 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) uint8_t orf_type; uint16_t orf_len; - if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) - < 5) { + if (subtype) { + /* If the length, excluding the fixed-size message + * header, of the received ROUTE-REFRESH message with + * Message Subtype 1 and 2 is not 4, then the BGP + * speaker MUST send a NOTIFICATION message with the + * Error Code of "ROUTE-REFRESH Message Error" and the + * subcode of "Invalid Message Length". + */ + if (msg_length != 4) { + zlog_err( + "%s Enhanced Route Refresh message length error", + peer->host); + bgp_notify_send( + peer, BGP_NOTIFY_ROUTE_REFRESH_ERR, + BGP_NOTIFY_ROUTE_REFRESH_INVALID_MSG_LEN); + } + + /* When the BGP speaker receives a ROUTE-REFRESH message + * with a "Message Subtype" field other than 0, 1, or 2, + * it MUST ignore the received ROUTE-REFRESH message. + */ + if (subtype > 2) + zlog_err( + "%s Enhanced Route Refresh invalid subtype", + peer->host); + } + + if (msg_length < 5) { zlog_info("%s ORF route refresh length error", peer->host); bgp_notify_send(peer, BGP_NOTIFY_CEASE, @@ -2139,6 +2221,124 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) SUBGRP_STATUS_DEFAULT_ORIGINATE); } + if (subtype == BGP_ROUTE_REFRESH_BORR) { + /* A BGP speaker that has received the Graceful Restart + * Capability from its neighbor MUST ignore any BoRRs for + * an <AFI, SAFI> from the neighbor before the speaker + * receives the EoR for the given <AFI, SAFI> from the + * neighbor. + */ + if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV) + && !CHECK_FLAG(peer->af_sflags[afi][safi], + PEER_STATUS_EOR_RECEIVED)) { + if (bgp_debug_neighbor_events(peer)) + zlog_debug( + "%s rcvd route-refresh (BoRR) for %s/%s before EoR", + peer->host, afi2str(afi), + safi2str(safi)); + return BGP_PACKET_NOOP; + } + + if (peer->t_refresh_stalepath) { + if (bgp_debug_neighbor_events(peer)) + zlog_debug( + "%s rcvd route-refresh (BoRR) for %s/%s, whereas BoRR already received", + peer->host, afi2str(afi), + safi2str(safi)); + return BGP_PACKET_NOOP; + } + + SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_BORR_RECEIVED); + UNSET_FLAG(peer->af_sflags[afi][safi], + PEER_STATUS_EORR_RECEIVED); + + /* When a BGP speaker receives a BoRR message from + * a peer, it MUST mark all the routes with the given + * Address Family Identifier and Subsequent Address + * Family Identifier, <AFI, SAFI> [RFC2918], from + * that peer as stale. + */ + if (peer_active_nego(peer)) { + SET_FLAG(peer->af_sflags[afi][safi], + PEER_STATUS_ENHANCED_REFRESH); + bgp_set_stale_route(peer, afi, safi); + } + + if (peer->status == Established) + thread_add_timer(bm->master, + bgp_refresh_stalepath_timer_expire, + paf, peer->bgp->stalepath_time, + &peer->t_refresh_stalepath); + + if (bgp_debug_neighbor_events(peer)) + zlog_debug( + "%s rcvd route-refresh (BoRR) for %s/%s, triggering timer for %u seconds", + peer->host, afi2str(afi), safi2str(safi), + peer->bgp->stalepath_time); + } else if (subtype == BGP_ROUTE_REFRESH_EORR) { + if (!peer->t_refresh_stalepath) { + zlog_err( + "%s rcvd route-refresh (EoRR) for %s/%s, whereas no BoRR received", + peer->host, afi2str(afi), safi2str(safi)); + return BGP_PACKET_NOOP; + } + + BGP_TIMER_OFF(peer->t_refresh_stalepath); + + SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_EORR_RECEIVED); + UNSET_FLAG(peer->af_sflags[afi][safi], + PEER_STATUS_BORR_RECEIVED); + + if (bgp_debug_neighbor_events(peer)) + zlog_debug( + "%s rcvd route-refresh (EoRR) for %s/%s, stopping BoRR timer", + peer->host, afi2str(afi), safi2str(safi)); + + if (peer->nsf[afi][safi]) + bgp_clear_stale_route(peer, afi, safi); + } else { + if (bgp_debug_neighbor_events(peer)) + zlog_debug("%s rcvd route-refresh (REQUEST) for %s/%s", + peer->host, afi2str(afi), safi2str(safi)); + + /* In response to a "normal route refresh request" from the + * peer, the speaker MUST send a BoRR message. + */ + if (CHECK_FLAG(peer->cap, PEER_CAP_ENHANCED_RR_RCV)) { + /* For a BGP speaker that supports the BGP Graceful + * Restart, it MUST NOT send a BoRR for an <AFI, SAFI> + * to a neighbor before it sends the EoR for the + * <AFI, SAFI> to the neighbor. + */ + if (!CHECK_FLAG(peer->af_sflags[afi][safi], + PEER_STATUS_EOR_SEND)) { + if (bgp_debug_neighbor_events(peer)) + zlog_debug( + "%s rcvd route-refresh (REQUEST) for %s/%s before EoR", + peer->host, afi2str(afi), + safi2str(safi)); + return BGP_PACKET_NOOP; + } + + bgp_route_refresh_send(peer, afi, safi, 0, 0, 0, + BGP_ROUTE_REFRESH_BORR); + + if (bgp_debug_neighbor_events(peer)) + zlog_debug( + "%s sending route-refresh (BoRR) for %s/%s", + peer->host, afi2str(afi), + safi2str(safi)); + + /* Set flag Ready-To-Send to know when we can send EoRR + * message. + */ + SET_FLAG(peer->af_sflags[afi][safi], + PEER_STATUS_BORR_SEND); + UNSET_FLAG(peer->af_sflags[afi][safi], + PEER_STATUS_EORR_SEND); + } + } + /* Perform route refreshment to the peer */ bgp_announce_route(peer, afi, safi); diff --git a/bgpd/bgp_packet.h b/bgpd/bgp_packet.h index e83f7d950c..525859a2da 100644 --- a/bgpd/bgp_packet.h +++ b/bgpd/bgp_packet.h @@ -62,8 +62,9 @@ extern void bgp_open_send(struct peer *); extern void bgp_notify_send(struct peer *, uint8_t, uint8_t); extern void bgp_notify_send_with_data(struct peer *, uint8_t, uint8_t, uint8_t *, size_t); -extern void bgp_route_refresh_send(struct peer *, afi_t, safi_t, uint8_t, - uint8_t, int); +extern void bgp_route_refresh_send(struct peer *peer, afi_t afi, safi_t safi, + uint8_t orf_type, uint8_t when_to_refresh, + int remove, uint8_t subtype); extern void bgp_capability_send(struct peer *, afi_t, safi_t, int, int); extern int bgp_capability_receive(struct peer *, bgp_size_t); diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c index a3f1eb8401..4f22f5bcfe 100644 --- a/bgpd/bgp_pbr.c +++ b/bgpd/bgp_pbr.c @@ -754,7 +754,7 @@ int bgp_pbr_build_and_validate_entry(const struct prefix *p, struct bgp_pbr_entry_main *api) { int ret; - int i, action_count = 0; + uint32_t i, action_count = 0; struct ecommunity *ecom; struct ecommunity_val *ecom_eval; struct bgp_pbr_entry_action *api_action; diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 0760bbd6a2..c4ab223b7f 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -208,9 +208,6 @@ void bgp_path_info_extra_free(struct bgp_path_info_extra **extra) return; e = *extra; - if (e->damp_info) - bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi, - e->damp_info->safi); e->damp_info = NULL; if (e->parent) { @@ -3331,14 +3328,16 @@ static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi, /* apply dampening, if result is suppressed, we'll be retaining * the bgp_path_info in the RIB for historical reference. */ - if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING) - && peer->sort == BGP_PEER_EBGP) - if ((bgp_damp_withdraw(pi, dest, afi, safi, 0)) - == BGP_DAMP_SUPPRESSED) { - bgp_aggregate_decrement(peer->bgp, p, pi, afi, - safi); - return; + if (peer->sort == BGP_PEER_EBGP) { + if (get_active_bdc_from_pi(pi, afi, safi)) { + if (bgp_damp_withdraw(pi, dest, afi, safi, 0) + == BGP_DAMP_SUPPRESSED) { + bgp_aggregate_decrement(peer->bgp, p, pi, afi, + safi); + return; + } } + } #ifdef ENABLE_BGP_VNC if (safi == SAFI_MPLS_VPN) { @@ -3763,8 +3762,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, && (overlay_index_equal( afi, pi, evpn == NULL ? NULL : &evpn->gw_ip))) { - if (CHECK_FLAG(bgp->af_flags[afi][safi], - BGP_CONFIG_DAMPENING) + if (get_active_bdc_from_pi(pi, afi, safi) && peer->sort == BGP_PEER_EBGP && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) { if (bgp_debug_update(peer, p, NULL, 1)) { @@ -3858,11 +3856,11 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bgp_aggregate_decrement(bgp, p, pi, afi, safi); /* Update bgp route dampening information. */ - if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING) + if (get_active_bdc_from_pi(pi, afi, safi) && peer->sort == BGP_PEER_EBGP) { /* This is implicit withdraw so we should update - dampening - information. */ + * dampening information. + */ if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) bgp_damp_withdraw(pi, dest, afi, safi, 1); } @@ -3985,7 +3983,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, #endif /* Update bgp route dampening information. */ - if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING) + if (get_active_bdc_from_pi(pi, afi, safi) && peer->sort == BGP_PEER_EBGP) { /* Now we do normal update dampening. */ ret = bgp_damp_update(pi, dest, afi, safi); @@ -4601,8 +4599,10 @@ static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data) continue; /* graceful restart STALE flag set. */ - if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT) - && peer->nsf[afi][safi] + if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT) + && peer->nsf[afi][safi]) + || CHECK_FLAG(peer->af_sflags[afi][safi], + PEER_STATUS_ENHANCED_REFRESH)) && !CHECK_FLAG(pi->flags, BGP_PATH_STALE) && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE)) bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE); @@ -4853,7 +4853,7 @@ void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi) struct bgp_path_info *pi; struct bgp_table *table; - if (safi == SAFI_MPLS_VPN) { + if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) { for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest; dest = bgp_route_next(dest)) { struct bgp_dest *rm; @@ -4892,6 +4892,81 @@ void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi) } } +void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi) +{ + struct bgp_dest *dest, *ndest; + struct bgp_path_info *pi; + struct bgp_table *table; + + if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) { + for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest; + dest = bgp_route_next(dest)) { + table = bgp_dest_get_bgp_table_info(dest); + if (!table) + continue; + + for (ndest = bgp_table_top(table); ndest; + ndest = bgp_route_next(ndest)) { + for (pi = bgp_dest_get_bgp_path_info(ndest); pi; + pi = pi->next) { + if (pi->peer != peer) + continue; + + if ((CHECK_FLAG( + peer->af_sflags[afi][safi], + PEER_STATUS_ENHANCED_REFRESH)) + && !CHECK_FLAG(pi->flags, + BGP_PATH_STALE) + && !CHECK_FLAG( + pi->flags, + BGP_PATH_UNUSEABLE)) { + if (bgp_debug_neighbor_events( + peer)) + zlog_debug( + "%s: route-refresh for %s/%s, marking prefix %pFX as stale", + peer->host, + afi2str(afi), + safi2str(safi), + bgp_dest_get_prefix( + ndest)); + + bgp_path_info_set_flag( + ndest, pi, + BGP_PATH_STALE); + } + } + } + } + } else { + for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest; + dest = bgp_route_next(dest)) { + for (pi = bgp_dest_get_bgp_path_info(dest); pi; + pi = pi->next) { + if (pi->peer != peer) + continue; + + if ((CHECK_FLAG(peer->af_sflags[afi][safi], + PEER_STATUS_ENHANCED_REFRESH)) + && !CHECK_FLAG(pi->flags, BGP_PATH_STALE) + && !CHECK_FLAG(pi->flags, + BGP_PATH_UNUSEABLE)) { + if (bgp_debug_neighbor_events(peer)) + zlog_debug( + "%s: route-refresh for %s/%s, marking prefix %pFX as stale", + peer->host, + afi2str(afi), + safi2str(safi), + bgp_dest_get_prefix( + dest)); + + bgp_path_info_set_flag(dest, pi, + BGP_PATH_STALE); + } + } + } + } +} + bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter) { if (peer->sort == BGP_PEER_IBGP) @@ -10135,7 +10210,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, } if (path->extra && path->extra->damp_info) - bgp_damp_info_vty(vty, path, afi, safi, json_path); + bgp_damp_info_vty(vty, bgp, path, afi, safi, json_path); /* Remote Label */ if (path->extra && bgp_is_valid_label(&path->extra->label[0]) @@ -14085,7 +14160,8 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name, if (pi->extra && pi->extra->damp_info) { pi_temp = pi->next; bgp_damp_info_free( - pi->extra->damp_info, + &pi->extra->damp_info, + &bgp->damp[afi][safi], 1, afi, safi); pi = pi_temp; } else @@ -14107,7 +14183,8 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name, if (pi->extra && pi->extra->damp_info) { pi_temp = pi->next; bgp_damp_info_free( - pi->extra->damp_info, + &pi->extra->damp_info, + &bgp->damp[afi][safi], 1, afi, safi); pi = pi_temp; } else @@ -14130,7 +14207,9 @@ DEFUN (clear_ip_bgp_dampening, BGP_STR "Clear route flap dampening information\n") { - bgp_damp_info_clean(AFI_IP, SAFI_UNICAST); + VTY_DECLVAR_CONTEXT(bgp, bgp); + bgp_damp_info_clean(&bgp->damp[AFI_IP][SAFI_UNICAST], AFI_IP, + SAFI_UNICAST); return CMD_SUCCESS; } diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index ec08eb9c65..bdbf4743ab 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -575,6 +575,7 @@ extern void bgp_clear_route(struct peer *, afi_t, safi_t); extern void bgp_clear_route_all(struct peer *); extern void bgp_clear_adj_in(struct peer *, afi_t, safi_t); extern void bgp_clear_stale_route(struct peer *, afi_t, safi_t); +extern void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi); extern bool bgp_outbound_policy_exists(struct peer *, struct bgp_filter *); extern bool bgp_inbound_policy_exists(struct peer *, struct bgp_filter *); diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 637eaca397..ceaf8c0963 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -65,6 +65,7 @@ #include "bgpd/bgp_flowspec_util.h" #include "bgpd/bgp_encap_types.h" #include "bgpd/bgp_mpath.h" +#include "bgpd/bgp_script.h" #ifdef ENABLE_BGP_VNC #include "bgpd/rfapi/bgp_rfapi_cfg.h" @@ -337,99 +338,138 @@ static const struct route_map_rule_cmd route_match_peer_cmd = { route_match_peer_free }; -#if defined(HAVE_LUA) -static enum route_map_cmd_result_t -route_match_command(void *rule, const struct prefix *prefix, void *object) -{ - int status = RMAP_NOMATCH; - u_int32_t locpref = 0; - u_int32_t newlocpref = 0; - enum lua_rm_status lrm_status; - struct bgp_path_info *path = (struct bgp_path_info *)object; - lua_State *L = lua_initialize("/etc/frr/lua.scr"); - - if (L == NULL) - return status; +#ifdef HAVE_SCRIPTING +enum frrlua_rm_status { /* - * Setup the prefix information to pass in + * Script function run failure. This will translate into a deny */ - lua_setup_prefix_table(L, prefix); - - zlog_debug("Set up prefix table"); + LUA_RM_FAILURE = 0, /* - * Setup the bgp_path_info information + * No Match was found for the route map function */ - lua_newtable(L); - lua_pushinteger(L, path->attr->med); - lua_setfield(L, -2, "metric"); - lua_pushinteger(L, path->attr->nh_ifindex); - lua_setfield(L, -2, "ifindex"); - lua_pushstring(L, path->attr->aspath->str); - lua_setfield(L, -2, "aspath"); - lua_pushinteger(L, path->attr->local_pref); - lua_setfield(L, -2, "localpref"); - zlog_debug("%s %d", path->attr->aspath->str, path->attr->nh_ifindex); - lua_setglobal(L, "nexthop"); - - zlog_debug("Set up nexthop information"); + LUA_RM_NOMATCH, /* - * Run the rule + * Match was found but no changes were made to the incoming data. */ - lrm_status = lua_run_rm_rule(L, rule); - switch (lrm_status) { + LUA_RM_MATCH, + /* + * Match was found and data was modified, so figure out what changed + */ + LUA_RM_MATCH_AND_CHANGE, +}; + +static enum route_map_cmd_result_t +route_match_script(void *rule, const struct prefix *prefix, void *object) +{ + const char *scriptname = rule; + struct bgp_path_info *path = (struct bgp_path_info *)object; + + struct frrscript *fs = frrscript_load(scriptname, NULL); + + if (!fs) { + zlog_err("Issue loading script rule; defaulting to no match"); + return RMAP_NOMATCH; + } + + enum frrlua_rm_status status_failure = LUA_RM_FAILURE, + status_nomatch = LUA_RM_NOMATCH, + status_match = LUA_RM_MATCH, + status_match_and_change = LUA_RM_MATCH_AND_CHANGE; + + /* Make result values available */ + struct frrscript_env env[] = { + {"integer", "RM_FAILURE", &status_failure}, + {"integer", "RM_NOMATCH", &status_nomatch}, + {"integer", "RM_MATCH", &status_match}, + {"integer", "RM_MATCH_AND_CHANGE", &status_match_and_change}, + {"integer", "action", &status_failure}, + {"prefix", "prefix", prefix}, + {"attr", "attributes", path->attr}, + {"peer", "peer", path->peer}, + {}}; + + struct frrscript_env results[] = { + {"integer", "action"}, + {"attr", "attributes"}, + {}, + }; + + int result = frrscript_call(fs, env); + + if (result) { + zlog_err("Issue running script rule; defaulting to no match"); + return RMAP_NOMATCH; + } + + enum frrlua_rm_status *lrm_status = + frrscript_get_result(fs, &results[0]); + + int status = RMAP_NOMATCH; + + switch (*lrm_status) { case LUA_RM_FAILURE: - zlog_debug("RM_FAILURE"); + zlog_err( + "Executing route-map match script '%s' failed; defaulting to no match", + scriptname); + status = RMAP_NOMATCH; break; case LUA_RM_NOMATCH: - zlog_debug("RM_NOMATCH"); + status = RMAP_NOMATCH; break; case LUA_RM_MATCH_AND_CHANGE: - zlog_debug("MATCH AND CHANGE"); - lua_getglobal(L, "nexthop"); - path->attr->med = get_integer(L, "metric"); - /* - * This needs to be abstraced with the set function - */ + status = RMAP_MATCH; + zlog_debug("Updating attribute based on script's values"); + + uint32_t locpref = 0; + struct attr *newattr = frrscript_get_result(fs, &results[1]); + + path->attr->med = newattr->med; + if (path->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) locpref = path->attr->local_pref; - newlocpref = get_integer(L, "localpref"); - if (newlocpref != locpref) { - path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF); - path->attr->local_pref = newlocpref; + if (locpref != newattr->local_pref) { + SET_FLAG(path->attr->flag, + ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)); + path->attr->local_pref = newattr->local_pref; } - status = RMAP_MATCH; + + aspath_free(newattr->aspath); + XFREE(MTYPE_TMP, newattr); break; case LUA_RM_MATCH: - zlog_debug("MATCH ONLY"); status = RMAP_MATCH; break; } - lua_close(L); + + XFREE(MTYPE_TMP, lrm_status); + frrscript_unload(fs); + return status; } -static void *route_match_command_compile(const char *arg) +static void *route_match_script_compile(const char *arg) { - char *command; + char *scriptname; + + scriptname = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); - command = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); - return command; + return scriptname; } -static void -route_match_command_free(void *rule) +static void route_match_script_free(void *rule) { XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); } -static const struct route_map_rule_cmd route_match_command_cmd = { - "command", - route_match_command, - route_match_command_compile, - route_match_command_free +static const struct route_map_rule_cmd route_match_script_cmd = { + "script", + route_match_script, + route_match_script_compile, + route_match_script_free }; -#endif + +#endif /* HAVE_SCRIPTING */ /* `match ip address IP_ACCESS_LIST' */ @@ -3503,8 +3543,9 @@ static void bgp_route_map_process_peer(const char *rmap_name, zlog_debug( "Processing route_map %s update on peer %s (inbound, route-refresh)", rmap_name, peer->host); - bgp_route_refresh_send(peer, afi, safi, 0, 0, - 0); + bgp_route_refresh_send( + peer, afi, safi, 0, 0, 0, + BGP_ROUTE_REFRESH_NORMAL); } } } @@ -4095,30 +4136,29 @@ DEFUN (no_match_peer, RMAP_EVENT_MATCH_DELETED); } -#if defined(HAVE_LUA) -DEFUN (match_command, - match_command_cmd, - "match command WORD", - MATCH_STR - "Run a command to match\n" - "The command to run\n") -{ - return bgp_route_match_add(vty, "command", argv[2]->arg, - RMAP_EVENT_FILTER_ADDED); -} - -DEFUN (no_match_command, - no_match_command_cmd, - "no match command WORD", +#ifdef HAVE_SCRIPTING +DEFUN (match_script, + match_script_cmd, + "[no] match script WORD", NO_STR MATCH_STR - "Run a command to match\n" - "The command to run\n") + "Execute script to determine match\n" + "The script name to run, without .lua; e.g. 'myroutemap' to run myroutemap.lua\n") { - return bgp_route_match_delete(vty, "command", argv[3]->arg, - RMAP_EVENT_FILTER_DELETED); + bool no = strmatch(argv[0]->text, "no"); + int i = 0; + argv_find(argv, argc, "WORD", &i); + const char *script = argv[i]->arg; + + if (no) { + return bgp_route_match_delete(vty, "script", script, + RMAP_EVENT_FILTER_DELETED); + } else { + return bgp_route_match_add(vty, "script", script, + RMAP_EVENT_FILTER_ADDED); + } } -#endif +#endif /* HAVE_SCRIPTING */ /* match probability */ DEFUN (match_probability, @@ -5632,8 +5672,8 @@ void bgp_route_map_init(void) route_map_install_match(&route_match_peer_cmd); route_map_install_match(&route_match_local_pref_cmd); -#if defined(HAVE_LUA) - route_map_install_match(&route_match_command_cmd); +#ifdef HAVE_SCRIPTING + route_map_install_match(&route_match_script_cmd); #endif route_map_install_match(&route_match_ip_address_cmd); route_map_install_match(&route_match_ip_next_hop_cmd); @@ -5797,9 +5837,8 @@ void bgp_route_map_init(void) install_element(RMAP_NODE, &no_set_ipv6_nexthop_prefer_global_cmd); install_element(RMAP_NODE, &set_ipv6_nexthop_peer_cmd); install_element(RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd); -#if defined(HAVE_LUA) - install_element(RMAP_NODE, &match_command_cmd); - install_element(RMAP_NODE, &no_match_command_cmd); +#ifdef HAVE_SCRIPTING + install_element(RMAP_NODE, &match_script_cmd); #endif } diff --git a/bgpd/bgp_script.c b/bgpd/bgp_script.c new file mode 100644 index 0000000000..0cda1927f8 --- /dev/null +++ b/bgpd/bgp_script.c @@ -0,0 +1,192 @@ +/* BGP scripting foo + * Copyright (C) 2020 NVIDIA Corporation + * Quentin Young + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <zebra.h> + +#ifdef HAVE_SCRIPTING + +#include "bgpd.h" +#include "bgp_script.h" +#include "bgp_debug.h" +#include "bgp_aspath.h" +#include "frratomic.h" +#include "frrscript.h" +#include "frrlua.h" + +static void lua_pushpeer(lua_State *L, const struct peer *peer) +{ + lua_newtable(L); + lua_pushinteger(L, peer->as); + lua_setfield(L, -2, "remote_as"); + lua_pushinteger(L, peer->local_as); + lua_setfield(L, -2, "local_as"); + lua_pushinaddr(L, &peer->remote_id); + lua_setfield(L, -2, "remote_id"); + lua_pushinaddr(L, &peer->local_id); + lua_setfield(L, -2, "local_id"); + lua_pushstring(L, lookup_msg(bgp_status_msg, peer->status, NULL)); + lua_setfield(L, -2, "state"); + lua_pushstring(L, peer->desc ? peer->desc : ""); + lua_setfield(L, -2, "description"); + lua_pushtimet(L, &peer->uptime); + lua_setfield(L, -2, "uptime"); + lua_pushtimet(L, &peer->readtime); + lua_setfield(L, -2, "last_readtime"); + lua_pushtimet(L, &peer->resettime); + lua_setfield(L, -2, "last_resettime"); + lua_pushsockunion(L, peer->su_local); + lua_setfield(L, -2, "local_address"); + lua_pushsockunion(L, peer->su_remote); + lua_setfield(L, -2, "remote_address"); + lua_pushinteger(L, peer->cap); + lua_setfield(L, -2, "capabilities"); + lua_pushinteger(L, peer->flags); + lua_setfield(L, -2, "flags"); + lua_pushstring(L, peer->password ? peer->password : ""); + lua_setfield(L, -2, "password"); + + /* Nested tables here */ + lua_newtable(L); + { + lua_newtable(L); + { + lua_pushinteger(L, peer->holdtime); + lua_setfield(L, -2, "hold"); + lua_pushinteger(L, peer->keepalive); + lua_setfield(L, -2, "keepalive"); + lua_pushinteger(L, peer->connect); + lua_setfield(L, -2, "connect"); + lua_pushinteger(L, peer->routeadv); + lua_setfield(L, -2, "route_advertisement"); + } + lua_setfield(L, -2, "configured"); + + lua_newtable(L); + { + lua_pushinteger(L, peer->v_holdtime); + lua_setfield(L, -2, "hold"); + lua_pushinteger(L, peer->v_keepalive); + lua_setfield(L, -2, "keepalive"); + lua_pushinteger(L, peer->v_connect); + lua_setfield(L, -2, "connect"); + lua_pushinteger(L, peer->v_routeadv); + lua_setfield(L, -2, "route_advertisement"); + } + lua_setfield(L, -2, "negotiated"); + } + lua_setfield(L, -2, "timers"); + + lua_newtable(L); + { + lua_pushinteger(L, atomic_load_explicit(&peer->open_in, + memory_order_relaxed)); + lua_setfield(L, -2, "open_in"); + lua_pushinteger(L, atomic_load_explicit(&peer->open_out, + memory_order_relaxed)); + lua_setfield(L, -2, "open_out"); + lua_pushinteger(L, atomic_load_explicit(&peer->update_in, + memory_order_relaxed)); + lua_setfield(L, -2, "update_in"); + lua_pushinteger(L, atomic_load_explicit(&peer->update_out, + memory_order_relaxed)); + lua_setfield(L, -2, "update_out"); + lua_pushinteger(L, atomic_load_explicit(&peer->update_time, + memory_order_relaxed)); + lua_setfield(L, -2, "update_time"); + lua_pushinteger(L, atomic_load_explicit(&peer->keepalive_in, + memory_order_relaxed)); + lua_setfield(L, -2, "keepalive_in"); + lua_pushinteger(L, atomic_load_explicit(&peer->keepalive_out, + memory_order_relaxed)); + lua_setfield(L, -2, "keepalive_out"); + lua_pushinteger(L, atomic_load_explicit(&peer->notify_in, + memory_order_relaxed)); + lua_setfield(L, -2, "notify_in"); + lua_pushinteger(L, atomic_load_explicit(&peer->notify_out, + memory_order_relaxed)); + lua_setfield(L, -2, "notify_out"); + lua_pushinteger(L, atomic_load_explicit(&peer->refresh_in, + memory_order_relaxed)); + lua_setfield(L, -2, "refresh_in"); + lua_pushinteger(L, atomic_load_explicit(&peer->refresh_out, + memory_order_relaxed)); + lua_setfield(L, -2, "refresh_out"); + lua_pushinteger(L, atomic_load_explicit(&peer->dynamic_cap_in, + memory_order_relaxed)); + lua_setfield(L, -2, "dynamic_cap_in"); + lua_pushinteger(L, atomic_load_explicit(&peer->dynamic_cap_out, + memory_order_relaxed)); + lua_setfield(L, -2, "dynamic_cap_out"); + lua_pushinteger(L, peer->established); + lua_setfield(L, -2, "times_established"); + lua_pushinteger(L, peer->dropped); + lua_setfield(L, -2, "times_dropped"); + } + lua_setfield(L, -2, "stats"); +} + +static void lua_pushattr(lua_State *L, const struct attr *attr) +{ + lua_newtable(L); + lua_pushinteger(L, attr->med); + lua_setfield(L, -2, "metric"); + lua_pushinteger(L, attr->nh_ifindex); + lua_setfield(L, -2, "ifindex"); + lua_pushstring(L, attr->aspath->str); + lua_setfield(L, -2, "aspath"); + lua_pushinteger(L, attr->local_pref); + lua_setfield(L, -2, "localpref"); +} + +static void *lua_toattr(lua_State *L, int idx) +{ + struct attr *attr = XCALLOC(MTYPE_TMP, sizeof(struct attr)); + + lua_getfield(L, -1, "metric"); + attr->med = lua_tointeger(L, -1); + lua_pop(L, 1); + lua_getfield(L, -1, "ifindex"); + attr->nh_ifindex = lua_tointeger(L, -1); + lua_pop(L, 1); + lua_getfield(L, -1, "aspath"); + attr->aspath = aspath_str2aspath(lua_tostring(L, -1)); + lua_pop(L, 1); + lua_getfield(L, -1, "localpref"); + attr->local_pref = lua_tointeger(L, -1); + lua_pop(L, 1); + + return attr; +} + +struct frrscript_codec frrscript_codecs_bgpd[] = { + {.typename = "peer", + .encoder = (encoder_func)lua_pushpeer, + .decoder = NULL}, + {.typename = "attr", + .encoder = (encoder_func)lua_pushattr, + .decoder = lua_toattr}, + {}}; + +void bgp_script_init(void) +{ + frrscript_register_type_codecs(frrscript_codecs_bgpd); +} + +#endif /* HAVE_SCRIPTING */ diff --git a/bgpd/bgp_script.h b/bgpd/bgp_script.h new file mode 100644 index 0000000000..6682c2eebd --- /dev/null +++ b/bgpd/bgp_script.h @@ -0,0 +1,34 @@ +/* BGP scripting foo + * Copyright (C) 2020 NVIDIA Corporation + * Quentin Young + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +#ifndef __BGP_SCRIPT__ +#define __BGP_SCRIPT__ + +#include <zebra.h> + +#ifdef HAVE_SCRIPTING + +/* + * Initialize scripting stuff. + */ +void bgp_script_init(void); + +#endif /* HAVE_SCRIPTING */ + +#endif /* __BGP_SCRIPT__ */ diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index b1ff9ac251..30babb7b76 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -518,10 +518,7 @@ void bgp_adj_out_set_subgroup(struct bgp_dest *dest, /* bgp_path_info adj_out reference */ adv->pathi = bgp_path_info_lock(path); - if (attr) - adv->baa = bgp_advertise_intern(subgrp->hash, attr); - else - adv->baa = baa_new(); + adv->baa = bgp_advertise_intern(subgrp->hash, attr); adv->adj = adj; adj->attr_hash = attr_hash; diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 4cdd4d2e62..bd13b5cd5b 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -4952,27 +4952,63 @@ ALIAS_HIDDEN(no_neighbor_activate, no_neighbor_activate_hidden_cmd, NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "Enable the Address Family for this Neighbor\n") -DEFUN_YANG (neighbor_set_peer_group, - neighbor_set_peer_group_cmd, - "neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME", - NEIGHBOR_STR - NEIGHBOR_ADDR_STR2 - "Member of the peer-group\n" - "Peer-group name\n") +DEFUN (neighbor_set_peer_group, + neighbor_set_peer_group_cmd, + "neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME", + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Member of the peer-group\n" + "Peer-group name\n") { + VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_peer = 1; int idx_word = 3; - char base_xpath[XPATH_MAXLEN]; + int ret; + as_t as; + union sockunion su; + struct peer *peer; + struct peer_group *group; - if (peer_and_group_lookup_nb(vty, argv[idx_peer]->arg, base_xpath, - sizeof(base_xpath), NULL) - < 0) + ret = str2sockunion(argv[idx_peer]->arg, &su); + if (ret < 0) { + peer = peer_lookup_by_conf_if(bgp, argv[idx_peer]->arg); + if (!peer) { + vty_out(vty, "%% Malformed address or name: %s\n", + argv[idx_peer]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + } else { + if (peer_address_self_check(bgp, &su)) { + vty_out(vty, + "%% Can not configure the local system as neighbor\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* Disallow for dynamic neighbor. */ + peer = peer_lookup(bgp, &su); + if (peer && peer_dynamic_neighbor(peer)) { + vty_out(vty, + "%% Operation not allowed on a dynamic neighbor\n"); + return CMD_WARNING_CONFIG_FAILED; + } + } + + group = peer_group_lookup(bgp, argv[idx_word]->arg); + if (!group) { + vty_out(vty, "%% Configure the peer-group first\n"); return CMD_WARNING_CONFIG_FAILED; + } - nb_cli_enqueue_change(vty, "./peer-group", NB_OP_MODIFY, - argv[idx_word]->arg); + ret = peer_group_bind(bgp, &su, peer, group, &as); - return nb_cli_apply_changes(vty, base_xpath); + if (ret == BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT) { + vty_out(vty, + "%% Peer with AS %u cannot be in this peer-group, members must be all internal or all external\n", + as); + return CMD_WARNING_CONFIG_FAILED; + } + + return bgp_vty_return(vty, ret); } ALIAS_HIDDEN(neighbor_set_peer_group, neighbor_set_peer_group_hidden_cmd, @@ -5528,7 +5564,6 @@ DEFUN_YANG (neighbor_nexthop_self, afi_t afi = bgp_node_afi(vty); safi_t safi = bgp_node_safi(vty); - snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH, yang_afi_safi_value2identity(afi, safi)); @@ -5567,7 +5602,6 @@ DEFUN_YANG(neighbor_nexthop_self_force, afi_t afi = bgp_node_afi(vty); safi_t safi = bgp_node_safi(vty); - snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH, yang_afi_safi_value2identity(afi, safi)); @@ -5652,7 +5686,6 @@ DEFUN_YANG (no_neighbor_nexthop_self_force, afi_t afi = bgp_node_afi(vty); safi_t safi = bgp_node_safi(vty); - snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH, yang_afi_safi_value2identity(afi, safi)); @@ -5810,7 +5843,6 @@ DEFUN_YANG (neighbor_remove_private_as_all, afi_t afi = bgp_node_afi(vty); safi_t safi = bgp_node_safi(vty); - snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH, yang_afi_safi_value2identity(afi, safi)); @@ -5850,7 +5882,6 @@ DEFUN_YANG (neighbor_remove_private_as_replace_as, afi_t afi = bgp_node_afi(vty); safi_t safi = bgp_node_safi(vty); - snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH, yang_afi_safi_value2identity(afi, safi)); @@ -5891,7 +5922,6 @@ DEFUN_YANG (neighbor_remove_private_as_all_replace_as, afi_t afi = bgp_node_afi(vty); safi_t safi = bgp_node_safi(vty); - snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH, yang_afi_safi_value2identity(afi, safi)); @@ -5972,7 +6002,6 @@ DEFUN_YANG (no_neighbor_remove_private_as_all, afi_t afi = bgp_node_afi(vty); safi_t safi = bgp_node_safi(vty); - snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH, yang_afi_safi_value2identity(afi, safi)); @@ -6013,7 +6042,6 @@ DEFUN_YANG (no_neighbor_remove_private_as_replace_as, afi_t afi = bgp_node_afi(vty); safi_t safi = bgp_node_safi(vty); - snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH, yang_afi_safi_value2identity(afi, safi)); @@ -6055,7 +6083,6 @@ DEFUN_YANG (no_neighbor_remove_private_as_all_replace_as, afi_t afi = bgp_node_afi(vty); safi_t safi = bgp_node_safi(vty); - snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH, yang_afi_safi_value2identity(afi, safi)); @@ -6345,7 +6372,6 @@ DEFUN_YANG (neighbor_soft_reconfiguration, afi_t afi = bgp_node_afi(vty); safi_t safi = bgp_node_safi(vty); - snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH, yang_afi_safi_value2identity(afi, safi)); @@ -7732,69 +7758,44 @@ ALIAS_HIDDEN( "Filter outgoing updates\n") /* Set prefix list to the peer. */ -static int peer_prefix_list_set_vty(struct vty *vty, const char *ip_str, - afi_t afi, safi_t safi, - const char *name_str, - const char *direct_str) -{ - int ret; - int direct = FILTER_IN; - struct peer *peer; - - peer = peer_and_group_lookup_vty(vty, ip_str); - if (!peer) - return CMD_WARNING_CONFIG_FAILED; - - /* Check filter direction. */ - if (strncmp(direct_str, "i", 1) == 0) - direct = FILTER_IN; - else if (strncmp(direct_str, "o", 1) == 0) - direct = FILTER_OUT; - - ret = peer_prefix_list_set(peer, afi, safi, direct, name_str); - - return bgp_vty_return(vty, ret); -} - -static int peer_prefix_list_unset_vty(struct vty *vty, const char *ip_str, - afi_t afi, safi_t safi, - const char *direct_str) +DEFPY_YANG( + neighbor_prefix_list, neighbor_prefix_list_cmd, + "[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor_str prefix-list WORD$prefix_str <in|out>$direction", + NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2 + "Filter updates to/from this neighbor\n" + "Name of a prefix list\n" + "Filter incoming updates\n" + "Filter outgoing updates\n") { - int ret; - struct peer *peer; - int direct = FILTER_IN; + char base_xpath[XPATH_MAXLEN]; + char af_xpath[XPATH_MAXLEN]; + char plist_xpath[XPATH_MAXLEN]; + afi_t afi = bgp_node_afi(vty); + safi_t safi = bgp_node_safi(vty); - peer = peer_and_group_lookup_vty(vty, ip_str); - if (!peer) + snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH, + yang_afi_safi_value2identity(afi, safi)); + if (peer_and_group_lookup_nb(vty, neighbor_str, base_xpath, + sizeof(base_xpath), af_xpath) + < 0) return CMD_WARNING_CONFIG_FAILED; - /* Check filter direction. */ - if (strncmp(direct_str, "i", 1) == 0) - direct = FILTER_IN; - else if (strncmp(direct_str, "o", 1) == 0) - direct = FILTER_OUT; - - ret = peer_prefix_list_unset(peer, afi, safi, direct); + if (strmatch(direction, "in")) + snprintf(plist_xpath, sizeof(plist_xpath), + "./%s/filter-config/plist-import", + bgp_afi_safi_get_container_str(afi, safi)); + else if (strmatch(direction, "out")) + snprintf(plist_xpath, sizeof(plist_xpath), + "./%s/filter-config/plist-export", + bgp_afi_safi_get_container_str(afi, safi)); - return bgp_vty_return(vty, ret); -} + if (!no) + nb_cli_enqueue_change(vty, plist_xpath, NB_OP_MODIFY, + prefix_str); + else + nb_cli_enqueue_change(vty, plist_xpath, NB_OP_DESTROY, NULL); -DEFUN (neighbor_prefix_list, - neighbor_prefix_list_cmd, - "neighbor <A.B.C.D|X:X::X:X|WORD> prefix-list WORD <in|out>", - NEIGHBOR_STR - NEIGHBOR_ADDR_STR2 - "Filter updates to/from this neighbor\n" - "Name of a prefix list\n" - "Filter incoming updates\n" - "Filter outgoing updates\n") -{ - int idx_peer = 1; - int idx_word = 3; - int idx_in_out = 4; - return peer_prefix_list_set_vty( - vty, argv[idx_peer]->arg, bgp_node_afi(vty), bgp_node_safi(vty), - argv[idx_word]->arg, argv[idx_in_out]->arg); + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN(neighbor_prefix_list, neighbor_prefix_list_hidden_cmd, @@ -7805,32 +7806,6 @@ ALIAS_HIDDEN(neighbor_prefix_list, neighbor_prefix_list_hidden_cmd, "Filter incoming updates\n" "Filter outgoing updates\n") -DEFUN (no_neighbor_prefix_list, - no_neighbor_prefix_list_cmd, - "no neighbor <A.B.C.D|X:X::X:X|WORD> prefix-list WORD <in|out>", - NO_STR - NEIGHBOR_STR - NEIGHBOR_ADDR_STR2 - "Filter updates to/from this neighbor\n" - "Name of a prefix list\n" - "Filter incoming updates\n" - "Filter outgoing updates\n") -{ - int idx_peer = 2; - int idx_in_out = 5; - return peer_prefix_list_unset_vty(vty, argv[idx_peer]->arg, - bgp_node_afi(vty), bgp_node_safi(vty), - argv[idx_in_out]->arg); -} - -ALIAS_HIDDEN(no_neighbor_prefix_list, no_neighbor_prefix_list_hidden_cmd, - "no neighbor <A.B.C.D|X:X::X:X|WORD> prefix-list WORD <in|out>", - NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2 - "Filter updates to/from this neighbor\n" - "Name of a prefix list\n" - "Filter incoming updates\n" - "Filter outgoing updates\n") - static int peer_aslist_set_vty(struct vty *vty, const char *ip_str, afi_t afi, safi_t safi, const char *name_str, const char *direct_str) @@ -7991,70 +7966,52 @@ ALIAS_HIDDEN(neighbor_advertise_map, neighbor_advertise_map_hidden_cmd, "Name of the exist or non exist map\n") /* Set route-map to the peer. */ -static int peer_route_map_set_vty(struct vty *vty, const char *ip_str, - afi_t afi, safi_t safi, const char *name_str, - const char *direct_str) -{ - int ret; - struct peer *peer; - int direct = RMAP_IN; - struct route_map *route_map; - - peer = peer_and_group_lookup_vty(vty, ip_str); - if (!peer) - return CMD_WARNING_CONFIG_FAILED; - - /* Check filter direction. */ - if (strncmp(direct_str, "in", 2) == 0) - direct = RMAP_IN; - else if (strncmp(direct_str, "o", 1) == 0) - direct = RMAP_OUT; - - route_map = route_map_lookup_warn_noexist(vty, name_str); - ret = peer_route_map_set(peer, afi, safi, direct, name_str, route_map); - - return bgp_vty_return(vty, ret); -} - -static int peer_route_map_unset_vty(struct vty *vty, const char *ip_str, - afi_t afi, safi_t safi, - const char *direct_str) +DEFPY_YANG( + neighbor_route_map, neighbor_route_map_cmd, + "[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor_str route-map WORD$rmap_str <in|out>$direction", + NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2 + "Apply route map to neighbor\n" + "Name of route map\n" + "Apply map to incoming routes\n" + "Apply map to outbound routes\n") { - int ret; - struct peer *peer; - int direct = RMAP_IN; + char base_xpath[XPATH_MAXLEN]; + char af_xpath[XPATH_MAXLEN]; + char rmap_xpath[XPATH_MAXLEN]; + afi_t afi = bgp_node_afi(vty); + safi_t safi = bgp_node_safi(vty); - peer = peer_and_group_lookup_vty(vty, ip_str); - if (!peer) + snprintf(af_xpath, sizeof(af_xpath), FRR_BGP_AF_XPATH, + yang_afi_safi_value2identity(afi, safi)); + if (peer_and_group_lookup_nb(vty, neighbor_str, base_xpath, + sizeof(base_xpath), af_xpath) + < 0) return CMD_WARNING_CONFIG_FAILED; - /* Check filter direction. */ - if (strncmp(direct_str, "in", 2) == 0) - direct = RMAP_IN; - else if (strncmp(direct_str, "o", 1) == 0) - direct = RMAP_OUT; - - ret = peer_route_map_unset(peer, afi, safi, direct); + if (strmatch(direction, "in")) + snprintf(rmap_xpath, sizeof(rmap_xpath), + "./%s/filter-config/rmap-import", + bgp_afi_safi_get_container_str(afi, safi)); + else if (strmatch(direction, "out")) + snprintf(rmap_xpath, sizeof(rmap_xpath), + "./%s/filter-config/rmap-export", + bgp_afi_safi_get_container_str(afi, safi)); - return bgp_vty_return(vty, ret); -} + if (!no) { + if (!yang_dnode_exists( + vty->candidate_config->dnode, + "/frr-route-map:lib/route-map[name='%s']", + rmap_str)) { + if (vty_shell_serv(vty)) + vty_out(vty, + "The route-map '%s' does not exist.\n", + rmap_str); + } + nb_cli_enqueue_change(vty, rmap_xpath, NB_OP_MODIFY, rmap_str); + } else + nb_cli_enqueue_change(vty, rmap_xpath, NB_OP_DESTROY, NULL); -DEFUN (neighbor_route_map, - neighbor_route_map_cmd, - "neighbor <A.B.C.D|X:X::X:X|WORD> route-map WORD <in|out>", - NEIGHBOR_STR - NEIGHBOR_ADDR_STR2 - "Apply route map to neighbor\n" - "Name of route map\n" - "Apply map to incoming routes\n" - "Apply map to outbound routes\n") -{ - int idx_peer = 1; - int idx_word = 3; - int idx_in_out = 4; - return peer_route_map_set_vty( - vty, argv[idx_peer]->arg, bgp_node_afi(vty), bgp_node_safi(vty), - argv[idx_word]->arg, argv[idx_in_out]->arg); + return nb_cli_apply_changes(vty, base_xpath); } ALIAS_HIDDEN(neighbor_route_map, neighbor_route_map_hidden_cmd, @@ -8065,25 +8022,7 @@ ALIAS_HIDDEN(neighbor_route_map, neighbor_route_map_hidden_cmd, "Apply map to incoming routes\n" "Apply map to outbound routes\n") -DEFUN (no_neighbor_route_map, - no_neighbor_route_map_cmd, - "no neighbor <A.B.C.D|X:X::X:X|WORD> route-map WORD <in|out>", - NO_STR - NEIGHBOR_STR - NEIGHBOR_ADDR_STR2 - "Apply route map to neighbor\n" - "Name of route map\n" - "Apply map to incoming routes\n" - "Apply map to outbound routes\n") -{ - int idx_peer = 2; - int idx_in_out = 5; - return peer_route_map_unset_vty(vty, argv[idx_peer]->arg, - bgp_node_afi(vty), bgp_node_safi(vty), - argv[idx_in_out]->arg); -} - -ALIAS_HIDDEN(no_neighbor_route_map, no_neighbor_route_map_hidden_cmd, +ALIAS_HIDDEN(neighbor_route_map, no_neighbor_route_map_hidden_cmd, "no neighbor <A.B.C.D|X:X::X:X|WORD> route-map WORD <in|out>", NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "Apply route map to neighbor\n" @@ -8896,6 +8835,93 @@ DEFPY( return CMD_SUCCESS; } +DEFPY(neighbor_damp, + neighbor_damp_cmd, + "neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor dampening [(1-45)$half [(1-20000)$reuse (1-20000)$suppress (1-255)$max]]", + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Enable neighbor route-flap dampening\n" + "Half-life time for the penalty\n" + "Value to start reusing a route\n" + "Value to start suppressing a route\n" + "Maximum duration to suppress a stable route\n") +{ + struct peer *peer = peer_and_group_lookup_vty(vty, neighbor); + + if (!peer) + return CMD_WARNING_CONFIG_FAILED; + if (!half) + half = DEFAULT_HALF_LIFE; + if (!reuse) { + reuse = DEFAULT_REUSE; + suppress = DEFAULT_SUPPRESS; + max = half * 4; + } + if (suppress < reuse) { + vty_out(vty, + "Suppress value cannot be less than reuse value\n"); + return CMD_WARNING_CONFIG_FAILED; + } + bgp_peer_damp_enable(peer, bgp_node_afi(vty), bgp_node_safi(vty), + half * 60, reuse, suppress, max * 60); + return CMD_SUCCESS; +} + +DEFPY(no_neighbor_damp, + no_neighbor_damp_cmd, + "no neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor dampening [HALF [REUSE SUPPRESS MAX]]", + NO_STR + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Enable neighbor route-flap dampening\n" + "Half-life time for the penalty\n" + "Value to start reusing a route\n" + "Value to start suppressing a route\n" + "Maximum duration to suppress a stable route\n") +{ + struct peer *peer = peer_and_group_lookup_vty(vty, neighbor); + + if (!peer) + return CMD_WARNING_CONFIG_FAILED; + bgp_peer_damp_disable(peer, bgp_node_afi(vty), bgp_node_safi(vty)); + return CMD_SUCCESS; +} + +DEFPY (show_ip_bgp_neighbor_damp_param, + show_ip_bgp_neighbor_damp_param_cmd, + "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD>$neighbor dampening parameters [json]$json", + SHOW_STR + IP_STR + BGP_STR + BGP_AFI_HELP_STR + "Address Family modifier\n" + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Neighbor route-flap dampening information\n" + "Display detail of configured dampening parameters\n" + JSON_STR) +{ + bool use_json = false; + int idx = 0; + afi_t afi = AFI_IP; + safi_t safi = SAFI_UNICAST; + struct peer *peer; + + if (argv_find(argv, argc, "ip", &idx)) + afi = AFI_IP; + if (argv_find(argv, argc, "ipv4", &idx)) + afi = AFI_IP; + if (argv_find(argv, argc, "ipv6", &idx)) + afi = AFI_IP6; + peer = peer_and_group_lookup_vty(vty, neighbor); + if (!peer) + return CMD_WARNING; + if (json) + use_json = true; + bgp_show_peer_dampening_parameters(vty, peer, afi, safi, use_json); + return CMD_SUCCESS; +} + static int set_ecom_list(struct vty *vty, int argc, struct cmd_token **argv, struct ecommunity **list, bool is_rt6) { @@ -13153,6 +13179,37 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, "received"); } + /* Enhanced Route Refresh */ + if (CHECK_FLAG(p->cap, PEER_CAP_ENHANCED_RR_ADV) + || CHECK_FLAG(p->cap, + PEER_CAP_ENHANCED_RR_RCV)) { + if (CHECK_FLAG(p->cap, + PEER_CAP_ENHANCED_RR_ADV) + && CHECK_FLAG( + p->cap, + PEER_CAP_ENHANCED_RR_RCV)) + json_object_string_add( + json_cap, + "enhancedRouteRefresh", + "advertisedAndReceived"); + else if ( + CHECK_FLAG( + p->cap, + PEER_CAP_ENHANCED_RR_ADV)) + json_object_string_add( + json_cap, + "enhancedRouteRefresh", + "advertised"); + else if ( + CHECK_FLAG( + p->cap, + PEER_CAP_ENHANCED_RR_RCV)) + json_object_string_add( + json_cap, + "enhancedRouteRefresh", + "received"); + } + /* Multiprotocol Extensions */ json_object *json_multi = NULL; json_multi = json_object_new_object(); @@ -13525,6 +13582,28 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, vty_out(vty, "\n"); } + /* Enhanced Route Refresh */ + if (CHECK_FLAG(p->cap, PEER_CAP_ENHANCED_RR_ADV) + || CHECK_FLAG(p->cap, + PEER_CAP_ENHANCED_RR_RCV)) { + vty_out(vty, + " Enhanced Route Refresh:"); + if (CHECK_FLAG( + p->cap, + PEER_CAP_ENHANCED_RR_ADV)) + vty_out(vty, " advertised"); + if (CHECK_FLAG( + p->cap, + PEER_CAP_ENHANCED_RR_RCV)) + vty_out(vty, " %sreceived", + CHECK_FLAG( + p->cap, + PEER_CAP_REFRESH_ADV) + ? "and " + : ""); + vty_out(vty, "\n"); + } + /* Multiprotocol Extensions */ FOREACH_AFI_SAFI (afi, safi) if (p->afc_adv[afi][safi] @@ -16947,7 +17026,15 @@ static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi, /* BGP flag dampening. */ if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) - bgp_config_write_damp(vty, afi, safi); + bgp_config_write_damp(vty, bgp, afi, safi); + for (ALL_LIST_ELEMENTS_RO(bgp->group, node, group)) + if (peer_af_flag_check(group->conf, afi, safi, + PEER_FLAG_CONFIG_DAMPENING)) + bgp_config_write_peer_damp(vty, group->conf, afi, safi); + for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) + if (peer_af_flag_check(peer, afi, safi, + PEER_FLAG_CONFIG_DAMPENING)) + bgp_config_write_peer_damp(vty, peer, afi, safi); for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) bgp_config_write_peer_af(vty, bgp, group->conf, afi, safi); @@ -18483,27 +18570,16 @@ void bgp_vty_init(void) /* "neighbor prefix-list" commands. */ install_element(BGP_NODE, &neighbor_prefix_list_hidden_cmd); - install_element(BGP_NODE, &no_neighbor_prefix_list_hidden_cmd); install_element(BGP_IPV4_NODE, &neighbor_prefix_list_cmd); - install_element(BGP_IPV4_NODE, &no_neighbor_prefix_list_cmd); install_element(BGP_IPV4M_NODE, &neighbor_prefix_list_cmd); - install_element(BGP_IPV4M_NODE, &no_neighbor_prefix_list_cmd); install_element(BGP_IPV4L_NODE, &neighbor_prefix_list_cmd); - install_element(BGP_IPV4L_NODE, &no_neighbor_prefix_list_cmd); install_element(BGP_IPV6_NODE, &neighbor_prefix_list_cmd); - install_element(BGP_IPV6_NODE, &no_neighbor_prefix_list_cmd); install_element(BGP_IPV6M_NODE, &neighbor_prefix_list_cmd); - install_element(BGP_IPV6M_NODE, &no_neighbor_prefix_list_cmd); install_element(BGP_IPV6L_NODE, &neighbor_prefix_list_cmd); - install_element(BGP_IPV6L_NODE, &no_neighbor_prefix_list_cmd); install_element(BGP_VPNV4_NODE, &neighbor_prefix_list_cmd); - install_element(BGP_VPNV4_NODE, &no_neighbor_prefix_list_cmd); install_element(BGP_VPNV6_NODE, &neighbor_prefix_list_cmd); - install_element(BGP_VPNV6_NODE, &no_neighbor_prefix_list_cmd); install_element(BGP_FLOWSPECV4_NODE, &neighbor_prefix_list_cmd); - install_element(BGP_FLOWSPECV4_NODE, &no_neighbor_prefix_list_cmd); install_element(BGP_FLOWSPECV6_NODE, &neighbor_prefix_list_cmd); - install_element(BGP_FLOWSPECV6_NODE, &no_neighbor_prefix_list_cmd); /* "neighbor filter-list" commands. */ install_element(BGP_NODE, &neighbor_filter_list_hidden_cmd); @@ -18533,27 +18609,16 @@ void bgp_vty_init(void) install_element(BGP_NODE, &neighbor_route_map_hidden_cmd); install_element(BGP_NODE, &no_neighbor_route_map_hidden_cmd); install_element(BGP_IPV4_NODE, &neighbor_route_map_cmd); - install_element(BGP_IPV4_NODE, &no_neighbor_route_map_cmd); install_element(BGP_IPV4M_NODE, &neighbor_route_map_cmd); - install_element(BGP_IPV4M_NODE, &no_neighbor_route_map_cmd); install_element(BGP_IPV4L_NODE, &neighbor_route_map_cmd); - install_element(BGP_IPV4L_NODE, &no_neighbor_route_map_cmd); install_element(BGP_IPV6_NODE, &neighbor_route_map_cmd); - install_element(BGP_IPV6_NODE, &no_neighbor_route_map_cmd); install_element(BGP_IPV6M_NODE, &neighbor_route_map_cmd); - install_element(BGP_IPV6M_NODE, &no_neighbor_route_map_cmd); install_element(BGP_IPV6L_NODE, &neighbor_route_map_cmd); - install_element(BGP_IPV6L_NODE, &no_neighbor_route_map_cmd); install_element(BGP_VPNV4_NODE, &neighbor_route_map_cmd); - install_element(BGP_VPNV4_NODE, &no_neighbor_route_map_cmd); install_element(BGP_VPNV6_NODE, &neighbor_route_map_cmd); - install_element(BGP_VPNV6_NODE, &no_neighbor_route_map_cmd); install_element(BGP_FLOWSPECV4_NODE, &neighbor_route_map_cmd); - install_element(BGP_FLOWSPECV4_NODE, &no_neighbor_route_map_cmd); install_element(BGP_FLOWSPECV6_NODE, &neighbor_route_map_cmd); - install_element(BGP_FLOWSPECV6_NODE, &no_neighbor_route_map_cmd); install_element(BGP_EVPN_NODE, &neighbor_route_map_cmd); - install_element(BGP_EVPN_NODE, &no_neighbor_route_map_cmd); /* "neighbor unsuppress-map" commands. */ install_element(BGP_NODE, &neighbor_unsuppress_map_hidden_cmd); @@ -18712,6 +18777,23 @@ void bgp_vty_init(void) install_element(BGP_EVPN_NODE, &neighbor_allowas_in_cmd); install_element(BGP_EVPN_NODE, &no_neighbor_allowas_in_cmd); + /* "neighbor dampening" commands. */ + install_element(BGP_NODE, &neighbor_damp_cmd); + install_element(BGP_NODE, &no_neighbor_damp_cmd); + install_element(BGP_IPV4_NODE, &neighbor_damp_cmd); + install_element(BGP_IPV4_NODE, &no_neighbor_damp_cmd); + install_element(BGP_IPV4M_NODE, &neighbor_damp_cmd); + install_element(BGP_IPV4M_NODE, &no_neighbor_damp_cmd); + install_element(BGP_IPV4L_NODE, &neighbor_damp_cmd); + install_element(BGP_IPV4L_NODE, &no_neighbor_damp_cmd); + install_element(BGP_IPV6_NODE, &neighbor_damp_cmd); + install_element(BGP_IPV6_NODE, &no_neighbor_damp_cmd); + install_element(BGP_IPV6M_NODE, &neighbor_damp_cmd); + install_element(BGP_IPV6M_NODE, &no_neighbor_damp_cmd); + install_element(BGP_IPV6L_NODE, &neighbor_damp_cmd); + install_element(BGP_IPV6L_NODE, &no_neighbor_damp_cmd); + install_element(VIEW_NODE, &show_ip_bgp_neighbor_damp_param_cmd); + /* address-family commands. */ install_element(BGP_NODE, &address_family_ipv4_safi_cmd); install_element(BGP_NODE, &address_family_ipv6_safi_cmd); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index cd1873054e..f7c4b04adf 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1347,11 +1347,21 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, nexthop = bgp_path_info_to_ipv6_nexthop(mpinfo_cp, &ifindex); - nh_updated = update_ipv6nh_for_route_install( - nh_othervrf, nh_othervrf ? - info->extra->bgp_orig : bgp, - nexthop, ifindex, - mpinfo, info, is_evpn, api_nh); + + if (!nexthop) + nh_updated = update_ipv4nh_for_route_install( + nh_othervrf, + nh_othervrf ? info->extra->bgp_orig + : bgp, + &mpinfo_cp->attr->nexthop, + mpinfo_cp->attr, is_evpn, api_nh); + else + nh_updated = update_ipv6nh_for_route_install( + nh_othervrf, + nh_othervrf ? info->extra->bgp_orig + : bgp, + nexthop, ifindex, mpinfo, info, is_evpn, + api_nh); } /* Did we get proper nexthop info to update zebra? */ diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 026b57193e..368397d7aa 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -121,12 +121,20 @@ extern struct zclient *zclient; static int bgp_check_main_socket(bool create, struct bgp *bgp) { static int bgp_server_main_created; + struct listnode *node; + char *address; if (create) { if (bgp_server_main_created) return 0; - if (bgp_socket(bgp, bm->port, bm->address) < 0) - return BGP_ERR_INVALID_VALUE; + if (list_isempty(bm->addresses)) { + if (bgp_socket(bgp, bm->port, NULL) < 0) + return BGP_ERR_INVALID_VALUE; + } else { + for (ALL_LIST_ELEMENTS_RO(bm->addresses, node, address)) + if (bgp_socket(bgp, bm->port, address) < 0) + return BGP_ERR_INVALID_VALUE; + } bgp_server_main_created = 1; return 0; } @@ -2379,6 +2387,14 @@ int peer_delete(struct peer *peer) bgp_bfd_deregister_peer(peer); + /* Delete peer route flap dampening configuration. This needs to happen + * before removing the peer from peer groups. + */ + FOREACH_AFI_SAFI (afi, safi) + if (peer_af_flag_check(peer, afi, safi, + PEER_FLAG_CONFIG_DAMPENING)) + bgp_peer_damp_disable(peer, afi, safi); + /* If this peer belongs to peer group, clear up the relationship. */ if (peer->group) { @@ -3280,7 +3296,8 @@ struct bgp *bgp_get_evpn(void) int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf, vrf_id_t old_vrf_id, bool create) { - int ret = 0; + struct listnode *node; + char *address; /* Create BGP server socket, if listen mode not disabled */ if (!bgp || bgp_option_check(BGP_OPT_NO_LISTEN)) @@ -3309,9 +3326,14 @@ int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf, vrf_id_t old_vrf_id, */ if (vrf->vrf_id == VRF_UNKNOWN) return 0; - ret = bgp_socket(bgp, bm->port, bm->address); - if (ret < 0) - return BGP_ERR_INVALID_VALUE; + if (list_isempty(bm->addresses)) { + if (bgp_socket(bgp, bm->port, NULL) < 0) + return BGP_ERR_INVALID_VALUE; + } else { + for (ALL_LIST_ELEMENTS_RO(bm->addresses, node, address)) + if (bgp_socket(bgp, bm->port, address) < 0) + return BGP_ERR_INVALID_VALUE; + } return 0; } else return bgp_check_main_socket(create, bgp); @@ -3500,6 +3522,11 @@ int bgp_delete(struct bgp *bgp) BGP_TIMER_OFF(gr_info->t_route_select); } + /* Delete route flap dampening configuration */ + FOREACH_AFI_SAFI (afi, safi) { + bgp_damp_disable(bgp, afi, safi); + } + if (BGP_DEBUG(zebra, ZEBRA)) { if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) zlog_debug("Deleting Default VRF"); @@ -4012,7 +4039,8 @@ void peer_change_action(struct peer *peer, afi_t afi, safi_t safi, } else if (type == peer_change_reset_in) { if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV) || CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV)) - bgp_route_refresh_send(peer, afi, safi, 0, 0, 0); + bgp_route_refresh_send(peer, afi, safi, 0, 0, 0, + BGP_ROUTE_REFRESH_NORMAL); else { if ((peer->doppelganger) && (peer->doppelganger->status != Deleted) @@ -5090,7 +5118,8 @@ static void peer_on_policy_change(struct peer *peer, afi_t afi, safi_t safi, bgp_soft_reconfig_in(peer, afi, safi); else if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV) || CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV)) - bgp_route_refresh_send(peer, afi, safi, 0, 0, 0); + bgp_route_refresh_send(peer, afi, safi, 0, 0, 0, + BGP_ROUTE_REFRESH_NORMAL); } } @@ -6945,6 +6974,22 @@ int peer_advertise_map_unset(struct peer *peer, afi_t afi, safi_t safi, return 0; } +static bool peer_maximum_prefix_clear_overflow(struct peer *peer) +{ + if (!CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW)) + return false; + + UNSET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW); + if (peer->t_pmax_restart) { + BGP_TIMER_OFF(peer->t_pmax_restart); + if (bgp_debug_neighbor_events(peer)) + zlog_debug("%s Maximum-prefix restart timer cancelled", + peer->host); + } + BGP_EVENT_ADD(peer, BGP_Start); + return true; +} + int peer_maximum_prefix_set(struct peer *peer, afi_t afi, safi_t safi, uint32_t max, uint8_t threshold, int warning, uint16_t restart, bool force) @@ -7066,7 +7111,11 @@ int peer_maximum_prefix_unset(struct peer *peer, afi_t afi, safi_t safi) member->pmax[afi][safi] = 0; member->pmax_threshold[afi][safi] = 0; member->pmax_restart[afi][safi] = 0; + + peer_maximum_prefix_clear_overflow(member); } + } else { + peer_maximum_prefix_clear_overflow(peer); } return 0; @@ -7101,6 +7150,7 @@ int is_ebgp_multihop_configured(struct peer *peer) int peer_ttl_security_hops_set(struct peer *peer, int gtsm_hops) { struct peer_group *group; + struct peer *gpeer; struct listnode *node, *nnode; int ret; @@ -7137,9 +7187,10 @@ int peer_ttl_security_hops_set(struct peer *peer, int gtsm_hops) return ret; } else { group = peer->group; + group->conf->gtsm_hops = gtsm_hops; for (ALL_LIST_ELEMENTS(group->peer, node, nnode, - peer)) { - peer->gtsm_hops = group->conf->gtsm_hops; + gpeer)) { + gpeer->gtsm_hops = group->conf->gtsm_hops; /* Calling ebgp multihop also resets the * session. @@ -7149,7 +7200,7 @@ int peer_ttl_security_hops_set(struct peer *peer, int gtsm_hops) * value is * irrelevant. */ - peer_ebgp_multihop_set(peer, MAXTTL); + peer_ebgp_multihop_set(gpeer, MAXTTL); } } } else { @@ -7170,9 +7221,10 @@ int peer_ttl_security_hops_set(struct peer *peer, int gtsm_hops) MAXTTL + 1 - gtsm_hops); } else { group = peer->group; + group->conf->gtsm_hops = gtsm_hops; for (ALL_LIST_ELEMENTS(group->peer, node, nnode, - peer)) { - peer->gtsm_hops = group->conf->gtsm_hops; + gpeer)) { + gpeer->gtsm_hops = group->conf->gtsm_hops; /* Change setting of existing peer * established then change value (may break @@ -7182,17 +7234,18 @@ int peer_ttl_security_hops_set(struct peer *peer, int gtsm_hops) * no session then do nothing (will get * handled by next connection) */ - if (peer->fd >= 0 - && peer->gtsm_hops + if (gpeer->fd >= 0 + && gpeer->gtsm_hops != BGP_GTSM_HOPS_DISABLED) sockopt_minttl( - peer->su.sa.sa_family, peer->fd, - MAXTTL + 1 - peer->gtsm_hops); - if ((peer->status < Established) - && peer->doppelganger - && (peer->doppelganger->fd >= 0)) - sockopt_minttl(peer->su.sa.sa_family, - peer->doppelganger->fd, + gpeer->su.sa.sa_family, + gpeer->fd, + MAXTTL + 1 - gpeer->gtsm_hops); + if ((gpeer->status < Established) + && gpeer->doppelganger + && (gpeer->doppelganger->fd >= 0)) + sockopt_minttl(gpeer->su.sa.sa_family, + gpeer->doppelganger->fd, MAXTTL + 1 - gtsm_hops); } } @@ -7269,18 +7322,8 @@ int peer_clear(struct peer *peer, struct listnode **nnode) { if (!CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN) || !CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHUTDOWN)) { - if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW)) { - UNSET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW); - if (peer->t_pmax_restart) { - BGP_TIMER_OFF(peer->t_pmax_restart); - if (bgp_debug_neighbor_events(peer)) - zlog_debug( - "%s Maximum-prefix restart timer canceled", - peer->host); - } - BGP_EVENT_ADD(peer, BGP_Start); + if (peer_maximum_prefix_clear_overflow(peer)) return 0; - } peer->v_start = BGP_INIT_START_TIMER; if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) @@ -7338,19 +7381,23 @@ int peer_clear_soft(struct peer *peer, afi_t afi, safi_t safi, PEER_STATUS_ORF_PREFIX_SEND)) bgp_route_refresh_send( peer, afi, safi, prefix_type, - REFRESH_DEFER, 1); - bgp_route_refresh_send(peer, afi, safi, - prefix_type, - REFRESH_IMMEDIATE, 0); + REFRESH_DEFER, 1, + BGP_ROUTE_REFRESH_NORMAL); + bgp_route_refresh_send( + peer, afi, safi, prefix_type, + REFRESH_IMMEDIATE, 0, + BGP_ROUTE_REFRESH_NORMAL); } else { if (CHECK_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND)) bgp_route_refresh_send( peer, afi, safi, prefix_type, - REFRESH_IMMEDIATE, 1); + REFRESH_IMMEDIATE, 1, + BGP_ROUTE_REFRESH_NORMAL); else - bgp_route_refresh_send(peer, afi, safi, - 0, 0, 0); + bgp_route_refresh_send( + peer, afi, safi, 0, 0, 0, + BGP_ROUTE_REFRESH_NORMAL); } return 0; } @@ -7369,8 +7416,9 @@ int peer_clear_soft(struct peer *peer, afi_t afi, safi_t safi, message to the peer. */ if (CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV) || CHECK_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV)) - bgp_route_refresh_send(peer, afi, safi, 0, 0, - 0); + bgp_route_refresh_send( + peer, afi, safi, 0, 0, 0, + BGP_ROUTE_REFRESH_NORMAL); else return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED; } @@ -7425,7 +7473,8 @@ char *peer_uptime(time_t uptime2, char *buf, size_t len, bool use_json, return buf; } -void bgp_master_init(struct thread_master *master, const int buffer_size) +void bgp_master_init(struct thread_master *master, const int buffer_size, + struct list *addresses) { qobj_init(); @@ -7435,6 +7484,7 @@ void bgp_master_init(struct thread_master *master, const int buffer_size) bm->bgp = list_new(); bm->listen_sockets = list_new(); bm->port = BGP_PORT_DEFAULT; + bm->addresses = addresses; bm->master = master; bm->start_time = bgp_clock(); bm->t_rmap_update = NULL; diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 16210bed15..9089608062 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -43,6 +43,7 @@ #include "bgp_labelpool.h" #include "bgp_addpath_types.h" #include "bgp_nexthop.h" +#include "bgp_damp.h" #define BGP_MAX_HOSTNAME 64 /* Linux max, is larger than most other sys */ #define BGP_PEER_MAX_HASH_SIZE 16384 @@ -124,8 +125,8 @@ struct bgp_master { /* BGP port number. */ uint16_t port; - /* Listener address */ - char *address; + /* Listener addresses */ + struct list *addresses; /* The Mac table */ struct hash *self_mac_hash; @@ -695,6 +696,9 @@ struct bgp { uint32_t condition_filter_count; struct thread *t_condition_check; + /* BGP route flap dampening configuration */ + struct bgp_damp_config damp[AFI_MAX][SAFI_MAX]; + QOBJ_FIELDS }; DECLARE_QOBJ_TYPE(bgp) @@ -1063,6 +1067,8 @@ struct peer { #define PEER_CAP_ENHE_RCV (1U << 14) /* Extended nexthop received */ #define PEER_CAP_HOSTNAME_ADV (1U << 15) /* hostname advertised */ #define PEER_CAP_HOSTNAME_RCV (1U << 16) /* hostname received */ +#define PEER_CAP_ENHANCED_RR_ADV (1U << 17) /* enhanced rr advertised */ +#define PEER_CAP_ENHANCED_RR_RCV (1U << 18) /* enhanced rr received */ /* Capability flags (reset in bgp_stop) */ uint32_t af_cap[AFI_MAX][SAFI_MAX]; @@ -1197,6 +1203,9 @@ struct peer { /* Last update packet sent time */ time_t pkt_stime[AFI_MAX][SAFI_MAX]; + /* Peer / peer group route flap dampening configuration */ + struct bgp_damp_config damp[AFI_MAX][SAFI_MAX]; + /* Peer Per AF flags */ /* * Please consult the comments for *flags_override*, *flags_invert* and @@ -1234,6 +1243,8 @@ struct peer { #define PEER_FLAG_SEND_LARGE_COMMUNITY (1U << 26) /* Send large Communities */ #define PEER_FLAG_MAX_PREFIX_OUT (1U << 27) /* outgoing maximum prefix */ #define PEER_FLAG_MAX_PREFIX_FORCE (1U << 28) /* maximum-prefix <num> force */ +#define PEER_FLAG_CONFIG_DAMPENING (1U << 29) /* route flap dampening */ + enum bgp_addpath_strat addpath_type[AFI_MAX][SAFI_MAX]; @@ -1264,6 +1275,11 @@ struct peer { #define PEER_STATUS_PREFIX_LIMIT (1U << 3) /* exceed prefix-limit */ #define PEER_STATUS_EOR_SEND (1U << 4) /* end-of-rib send to peer */ #define PEER_STATUS_EOR_RECEIVED (1U << 5) /* end-of-rib received from peer */ +#define PEER_STATUS_ENHANCED_REFRESH (1U << 6) /* Enhanced Route Refresh */ +#define PEER_STATUS_BORR_SEND (1U << 7) /* BoRR send to peer */ +#define PEER_STATUS_BORR_RECEIVED (1U << 8) /* BoRR received from peer */ +#define PEER_STATUS_EORR_SEND (1U << 9) /* EoRR send to peer */ +#define PEER_STATUS_EORR_RECEIVED (1U << 10) /* EoRR received from peer */ /* Configured timer values. */ _Atomic uint32_t holdtime; @@ -1297,6 +1313,7 @@ struct peer { struct thread *t_gr_stale; struct thread *t_generate_updgrp_packets; struct thread *t_process_packet; + struct thread *t_refresh_stalepath; /* Thread flags. */ _Atomic uint32_t thread_flags; @@ -1621,7 +1638,7 @@ struct bgp_nlri { #define BGP_NOTIFY_HOLD_ERR 4 #define BGP_NOTIFY_FSM_ERR 5 #define BGP_NOTIFY_CEASE 6 -#define BGP_NOTIFY_CAPABILITY_ERR 7 +#define BGP_NOTIFY_ROUTE_REFRESH_ERR 7 /* Subcodes for BGP Finite State Machine Error */ #define BGP_NOTIFY_FSM_ERR_SUBCODE_UNSPECIFIC 0 @@ -1669,10 +1686,13 @@ struct bgp_nlri { #define BGP_NOTIFY_CEASE_COLLISION_RESOLUTION 7 #define BGP_NOTIFY_CEASE_OUT_OF_RESOURCE 8 -/* BGP_NOTIFY_CAPABILITY_ERR sub codes (draft-ietf-idr-dynamic-cap-02). */ -#define BGP_NOTIFY_CAPABILITY_INVALID_ACTION 1 -#define BGP_NOTIFY_CAPABILITY_INVALID_LENGTH 2 -#define BGP_NOTIFY_CAPABILITY_MALFORMED_CODE 3 +/* BGP_NOTIFY_ROUTE_REFRESH_ERR sub codes (RFC 7313). */ +#define BGP_NOTIFY_ROUTE_REFRESH_INVALID_MSG_LEN 1 + +/* BGP route refresh optional subtypes. */ +#define BGP_ROUTE_REFRESH_NORMAL 0 +#define BGP_ROUTE_REFRESH_BORR 1 +#define BGP_ROUTE_REFRESH_EORR 2 /* BGP timers default value. */ #define BGP_INIT_START_TIMER 1 @@ -1852,8 +1872,8 @@ extern char *peer_uptime(time_t uptime2, char *buf, size_t len, bool use_json, extern int bgp_config_write(struct vty *); -extern void bgp_master_init(struct thread_master *master, - const int buffer_size); +extern void bgp_master_init(struct thread_master *master, const int buffer_size, + struct list *addresses); extern void bgp_init(unsigned short instance); extern void bgp_pthreads_run(void); diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c index 3d87b63542..b2732a40b4 100644 --- a/bgpd/rfapi/rfapi_import.c +++ b/bgpd/rfapi/rfapi_import.c @@ -984,7 +984,7 @@ static int rfapiEcommunitiesMatchBeec(struct ecommunity *ecom, int rfapiEcommunitiesIntersect(struct ecommunity *e1, struct ecommunity *e2) { - int i, j; + uint32_t i, j; if (!e1 || !e2) return 0; @@ -1014,7 +1014,8 @@ int rfapiEcommunitiesIntersect(struct ecommunity *e1, struct ecommunity *e2) int rfapiEcommunityGetLNI(struct ecommunity *ecom, uint32_t *lni) { if (ecom) { - int i; + uint32_t i; + for (i = 0; i < ecom->size; ++i) { uint8_t *p = ecom->val + (i * ECOMMUNITY_SIZE); @@ -1034,7 +1035,8 @@ int rfapiEcommunityGetEthernetTag(struct ecommunity *ecom, uint16_t *tag_id) struct bgp *bgp = bgp_get_default(); *tag_id = 0; /* default to untagged */ if (ecom) { - int i; + uint32_t i; + for (i = 0; i < ecom->size; ++i) { as_t as = 0; int encode = 0; diff --git a/bgpd/rfapi/vnc_export_bgp.c b/bgpd/rfapi/vnc_export_bgp.c index 762cd2596f..bc29f05aeb 100644 --- a/bgpd/rfapi/vnc_export_bgp.c +++ b/bgpd/rfapi/vnc_export_bgp.c @@ -134,7 +134,7 @@ static void encap_attr_export_ce(struct attr *new, struct attr *orig, static int getce(struct bgp *bgp, struct attr *attr, struct prefix *pfx_ce) { uint8_t *ecp; - int i; + uint32_t i; uint16_t localadmin = bgp->rfapi_cfg->resolve_nve_roo_local_admin; for (ecp = attr->ecommunity->val, i = 0; i < attr->ecommunity->size; diff --git a/bgpd/subdir.am b/bgpd/subdir.am index ac84f4b9e4..df1555c32a 100644 --- a/bgpd/subdir.am +++ b/bgpd/subdir.am @@ -96,6 +96,7 @@ bgpd_libbgp_a_SOURCES = \ bgpd/bgp_regex.c \ bgpd/bgp_route.c \ bgpd/bgp_routemap.c \ + bgpd/bgp_script.c \ bgpd/bgp_table.c \ bgpd/bgp_updgrp.c \ bgpd/bgp_updgrp_adv.c \ @@ -175,6 +176,7 @@ noinst_HEADERS += \ bgpd/bgp_rd.h \ bgpd/bgp_regex.h \ bgpd/bgp_route.h \ + bgpd/bgp_script.h \ bgpd/bgp_table.h \ bgpd/bgp_updgrp.h \ bgpd/bgp_vpn.h \ diff --git a/configure.ac b/configure.ac index 0cbf4d22e6..8f9517763d 100755 --- a/configure.ac +++ b/configure.ac @@ -138,6 +138,12 @@ AC_ARG_WITH([moduledir], [AS_HELP_STRING([--with-moduledir=DIR], [module directo ]) AC_SUBST([moduledir], [$moduledir]) +AC_ARG_WITH([scriptdir], [AS_HELP_STRING([--with-scriptdir=DIR], [script directory (${sysconfdir}/scripts)])], [ + scriptdir="$withval" +], [ + scriptdir="\${sysconfdir}/scripts" +]) +AC_SUBST([scriptdir], [$scriptdir]) AC_ARG_WITH([yangmodelsdir], [AS_HELP_STRING([--with-yangmodelsdir=DIR], [yang models directory (${datarootdir}/yang)])], [ yangmodelsdir="$withval" @@ -274,24 +280,22 @@ if test "$enable_clang_coverage" = "yes"; then ]) fi +if test "$enable_scripting" = "yes"; then + AX_PROG_LUA([5.3]) + AX_LUA_HEADERS + AX_LUA_LIBS([ + AC_DEFINE([HAVE_SCRIPTING], [1], [Have support for scripting]) + LIBS="$LIBS $LUA_LIB" + ]) +fi + if test "$enable_dev_build" = "yes"; then AC_DEFINE([DEV_BUILD], [1], [Build for development]) if test "$orig_cflags" = ""; then AC_C_FLAG([-g3]) AC_C_FLAG([-O0]) fi - if test "$enable_lua" = "yes"; then - AX_PROG_LUA([5.3]) - AX_LUA_HEADERS - AX_LUA_LIBS([ - AC_DEFINE([HAVE_LUA], [1], [Have support for Lua interpreter]) - LIBS="$LIBS $LUA_LIB" - ]) - fi else - if test "$enable_lua" = "yes"; then - AC_MSG_ERROR([Lua is not meant to be built/used outside of development at this time]) - fi if test "$orig_cflags" = ""; then AC_C_FLAG([-g]) AC_C_FLAG([-O2]) @@ -697,8 +701,8 @@ fi AC_ARG_ENABLE([dev_build], AS_HELP_STRING([--enable-dev-build], [build for development])) -AC_ARG_ENABLE([lua], - AS_HELP_STRING([--enable-lua], [Build Lua scripting])) +AC_ARG_ENABLE([scripting], + AS_HELP_STRING([--enable-scripting], [Build with scripting support])) AC_ARG_ENABLE([netlink-debug], AS_HELP_STRING([--disable-netlink-debug], [pretty print netlink debug messages])) @@ -1862,7 +1866,7 @@ dnl --------------- dnl sysrepo dnl --------------- if test "$enable_sysrepo" = "yes"; then - PKG_CHECK_MODULES([SYSREPO], [libsysrepo], + PKG_CHECK_MODULES([SYSREPO], [sysrepo], [AC_DEFINE([HAVE_SYSREPO], [1], [Enable sysrepo integration]) SYSREPO=true], [SYSREPO=false @@ -2446,19 +2450,23 @@ CFG_SBIN="$sbindir" CFG_STATE="$frr_statedir" CFG_MODULE="$moduledir" CFG_YANGMODELS="$yangmodelsdir" +CFG_SCRIPT="$scriptdir" for I in 1 2 3 4 5 6 7 8 9 10; do eval CFG_SYSCONF="\"$CFG_SYSCONF\"" eval CFG_SBIN="\"$CFG_SBIN\"" eval CFG_STATE="\"$CFG_STATE\"" eval CFG_MODULE="\"$CFG_MODULE\"" eval CFG_YANGMODELS="\"$CFG_YANGMODELS\"" + eval CFG_SCRIPT="\"$CFG_SCRIPT\"" done AC_SUBST([CFG_SYSCONF]) AC_SUBST([CFG_SBIN]) AC_SUBST([CFG_STATE]) AC_SUBST([CFG_MODULE]) +AC_SUBST([CFG_SCRIPT]) AC_SUBST([CFG_YANGMODELS]) AC_DEFINE_UNQUOTED([MODULE_PATH], ["$CFG_MODULE"], [path to modules]) +AC_DEFINE_UNQUOTED([SCRIPT_PATH], ["$CFG_SCRIPT"], [path to scripts]) AC_DEFINE_UNQUOTED([YANG_MODELS_PATH], ["$CFG_YANGMODELS"], [path to YANG data models]) AC_DEFINE_UNQUOTED([WATCHFRR_SH_PATH], ["${CFG_SBIN%/}/watchfrr.sh"], [path to watchfrr.sh]) @@ -2582,6 +2590,7 @@ state file directory : ${frr_statedir} config file directory : `eval echo \`echo ${sysconfdir}\`` example directory : `eval echo \`echo ${exampledir}\`` module directory : ${CFG_MODULE} +script directory : ${CFG_SCRIPT} user to run as : ${enable_user} group to run as : ${enable_group} group for vty sockets : ${enable_vty_group} diff --git a/debian/control b/debian/control index 4aaa9f21bf..b9e96b55d0 100644 --- a/debian/control +++ b/debian/control @@ -29,7 +29,8 @@ Build-Depends: bison, python3-dev, python3-pytest <!nocheck>, python3-sphinx, - texinfo (>= 4.7) + texinfo (>= 4.7), + liblua5.3-dev <pkg.frr.lua> Standards-Version: 4.5.0.3 Homepage: https://www.frrouting.org/ Vcs-Browser: https://github.com/FRRouting/frr/tree/debian/master diff --git a/debian/rules b/debian/rules index 6cc03c378a..25ae04261d 100755 --- a/debian/rules +++ b/debian/rules @@ -29,6 +29,12 @@ else CONF_SYSTEMD=--enable-systemd=no endif +ifeq ($(filter pkg.frr.lua,$(DEB_BUILD_PROFILES)),) + CONF_LUA=--disable-scripting +else + CONF_LUA=--enable-scripting +endif + export PYTHON=python3 %: @@ -49,6 +55,7 @@ override_dh_auto_configure: \ $(CONF_SYSTEMD) \ $(CONF_RPKI) \ + $(CONF_LUA) \ --with-libpam \ --enable-doc \ --enable-doc-html \ diff --git a/doc/developer/index.rst b/doc/developer/index.rst index 60a7d505a7..8e7913419f 100644 --- a/doc/developer/index.rst +++ b/doc/developer/index.rst @@ -18,4 +18,5 @@ FRRouting Developer's Guide ospf zebra vtysh - pathd + path + link-state diff --git a/doc/developer/library.rst b/doc/developer/library.rst index 3d5c6a2a15..1bfe5df2f0 100644 --- a/doc/developer/library.rst +++ b/doc/developer/library.rst @@ -15,6 +15,6 @@ Library Facilities (libfrr) hooks cli modules - lua + scripting diff --git a/doc/developer/logging.rst b/doc/developer/logging.rst index 2f2444373c..cf3aa8d17f 100644 --- a/doc/developer/logging.rst +++ b/doc/developer/logging.rst @@ -83,7 +83,7 @@ Extensions +-----------+--------------------------+----------------------------------------------+ | ``%pNHs`` | ``struct nexthop *`` | ``1.2.3.4 if 15`` | +-----------+--------------------------+----------------------------------------------+ -| ``%pFX`` + ``struct bgp_dest *`` | ``fe80::1234/64`` available in BGP only | +| ``%pFX`` | ``struct bgp_dest *`` | ``fe80::1234/64`` (available in BGP only) | +-----------+--------------------------+----------------------------------------------+ Printf features like field lengths can be used normally with these extensions, diff --git a/doc/developer/lua.rst b/doc/developer/lua.rst deleted file mode 100644 index 3315c31ad7..0000000000 --- a/doc/developer/lua.rst +++ /dev/null @@ -1,65 +0,0 @@ -.. _lua: - -Lua -=== - -Lua is currently experimental within FRR and has very limited -support. If you would like to compile FRR with Lua you must -follow these steps: - -1. Installation of Relevant Libraries - - .. code-block:: shell - - apt-get install lua5.3 liblua5-3 liblua5.3-dev - - These are the Debian libraries that are needed. There should - be equivalent RPM's that can be found - -2. Compilation - - Configure needs these options - - .. code-block:: shell - - ./configure --enable-dev-build --enable-lua <all other interesting options> - - Typically you just include the two new enable lines to build with it. - -3. Using Lua - - * Copy tools/lua.scr into /etc/frr - - * Create a route-map match command - - .. code-block:: console - - ! - router bgp 55 - neighbor 10.50.11.116 remote-as external - address-family ipv4 unicast - neighbor 10.50.11.116 route-map TEST in - exit-address-family - ! - route-map TEST permit 10 - match command mooey - ! - - * In the lua.scr file make sure that you have a function named 'mooey' - - .. code-block:: console - - function mooey () - zlog_debug(string.format("afi: %d: %s %d ifdx: %d aspath: %s localpref: %d", - prefix.family, prefix.route, nexthop.metric, - nexthop.ifindex, nexthop.aspath, nexthop.localpref)) - - nexthop.metric = 33 - nexthop.localpref = 13 - return 3 - end - -4. General Comments - - Please be aware that this is extremely experimental and needs a ton of work - to get this up into a state that is usable. diff --git a/doc/developer/scripting.rst b/doc/developer/scripting.rst new file mode 100644 index 0000000000..b0413619ab --- /dev/null +++ b/doc/developer/scripting.rst @@ -0,0 +1,433 @@ +.. _scripting: + +Scripting +========= + +.. seealso:: User docs for scripting + +Overview +-------- + +FRR has the ability to call Lua scripts to perform calculations, make +decisions, or otherwise extend builtin behavior with arbitrary user code. This +is implemented using the standard Lua C bindings. The supported version of Lua +is 5.3. + +C objects may be passed into Lua and Lua objects may be retrieved by C code via +a marshalling system. In this way, arbitrary data from FRR may be passed to +scripts. It is possible to pass C functions as well. + +The Lua environment is isolated from the C environment; user scripts cannot +access FRR's address space unless explicitly allowed by FRR. + +For general information on how Lua is used to extend C, refer to Part IV of +"Programming in Lua". + +https://www.lua.org/pil/contents.html#24 + + +Design +------ + +Why Lua +^^^^^^^ + +Lua is designed to be embedded in C applications. It is very small; the +standard library is 220K. It is relatively fast. It has a simple, minimal +syntax that is relatively easy to learn and can be understood by someone with +little to no programming experience. Moreover it is widely used to add +scripting capabilities to applications. In short it is designed for this task. + +Reasons against supporting multiple scripting languages: + +- Each language would require different FFI methods, and specifically + different object encoders; a lot of code +- Languages have different capabilities that would have to be brought to + parity with each other; a lot of work +- Languages have vastly different performance characteristics; this would + create alot of basically unfixable issues, and result in a single de facto + standard scripting language (the fastest) +- Each language would need a dedicated maintainer for the above reasons; + this is pragmatically difficult +- Supporting multiple languages fractures the community and limits the audience + with which a given script can be shared + +General +^^^^^^^ + +FRR's concept of a script is somewhat abstracted away from the fact that it is +Lua underneath. A script in has two things: + +- name +- state + +In code: + +.. code-block:: c + + struct frrscript { + /* Script name */ + char *name; + + /* Lua state */ + struct lua_State *L; + }; + + +``name`` is simply a string. Everything else is in ``state``, which is itself a +Lua library object (``lua_State``). This is an opaque struct that is +manipulated using ``lua_*`` functions. The basic ones are imported from +``lua.h`` and the rest are implemented within FRR to fill our use cases. The +thing to remember is that all operations beyond the initial loading the script +take place on this opaque state object. + +There are four basic actions that can be done on a script: + +- load +- execute +- query state +- unload + +They are typically done in this order. + + +Loading +^^^^^^^ + +A snippet of Lua code is referred to as a "chunk". These are simply text. FRR +presently assumes chunks are located in individual files specific to one task. +These files are stored in the scripts directory and must end in ``.lua``. + +A script object is created by loading a script. This is done with +``frrscript_load()``. This function takes the name of the script and an +optional callback function. The string ".lua" is appended to the script name, +and the resultant filename is looked for in the scripts directory. + +For example, to load ``/etc/frr/scripts/bingus.lua``: + +.. code-block:: c + + struct frrscript *fs = frrscript_load("bingus", NULL); + +During loading the script is validated for syntax and its initial environment +is setup. By default this does not include the Lua standard library; there are +security issues to consider, though for practical purposes untrusted users +should not be able to write the scripts directory anyway. If desired the Lua +standard library may be added to the script environment using +``luaL_openlibs(fs->L)`` after loading the script. Further information on +setting up the script environment is in the Lua manual. + + +Executing +^^^^^^^^^ + +After loading, scripts may be executed. A script may take input in the form of +variable bindings set in its environment prior to being run, and may provide +results by setting the value of variables. Arbitrary C values may be +transferred into the script environment, including functions. + +A typical execution call looks something like this: + +.. code-block:: c + + struct frrscript *fs = frrscript_load(...); + + int status_ok = 0, status_fail = 1; + struct prefix p = ...; + + struct frrscript_env env[] = { + {"integer", "STATUS_FAIL", &status_fail}, + {"integer", "STATUS_OK", &status_ok}, + {"prefix", "myprefix", &p}, + {}}; + + int result = frrscript_call(fs, env); + + +To execute a loaded script, we need to define the inputs. These inputs are +passed by binding values to variable names that will be accessible within the +Lua environment. Basically, all communication with the script takes place via +global variables within the script, and to provide inputs we predefine globals +before the script runs. This is done by passing ``frrscript_call()`` an array +of ``struct frrscript_env``. Each struct has three fields. The first identifies +the type of the value being passed; more on this later. The second defines the +name of the global variable within the script environment to bind the third +argument (the value) to. + +The script is then executed and returns a general status code. In the success +case this will be 0, otherwise it will be nonzero. The script itself does not +determine this code, it is provided by the Lua interpreter. + + +Querying State +^^^^^^^^^^^^^^ + +When a chunk is executed, its state at exit is preserved and can be inspected. + +After running a script, results may be retrieved by querying the script's +state. Again this is done by retrieving the values of global variables, which +are known to the script author to be "output" variables. + +A result is retrieved like so: + +.. code-block:: c + + struct frrscript_env myresult = {"string", "myresult"}; + + char *myresult = frrscript_get_result(fs, &myresult); + + ... do something ... + + XFREE(MTYPE_TMP, myresult); + + +As with arguments, results are retrieved by providing a ``struct +frrscript_env`` specifying a type and a global name. No value is necessary, nor +is it modified by ``frrscript_get_result()``. That function simply extracts the +requested value from the script state and returns it. + +In most cases the returned value will be allocated with ``MTYPE_TMP`` and will +need to be freed after use. + + +Unloading +^^^^^^^^^ + +To destroy a script and its associated state: + +.. code-block:: c + + frrscript_unload(fs); + +Values returned by ``frrscript_get_result`` are still valid after the script +they were retrieved from is unloaded. + +Note that you must unload and then load the script if you want to reset its +state, for example to run it again with different inputs. Otherwise the state +from the previous run carries over into subsequent runs. + + +.. _marshalling: + +Marshalling +^^^^^^^^^^^ + +Earlier sections glossed over the meaning of the type name field in ``struct +frrscript_env`` and how data is passed between C and Lua. Lua, as a dynamically +typed, garbage collected language, cannot directly use C values without some +kind of marshalling / unmarshalling system to translate types between the two +runtimes. + +Lua communicates with C code using a stack. C code wishing to provide data to +Lua scripts must provide a function that marshalls the C data into a Lua +representation and pushes it on the stack. C code wishing to retrieve data from +Lua must provide a corresponding unmarshalling function that retrieves a Lua +value from the stack and converts it to the corresponding C type. These two +functions, together with a chosen name of the type they operate on, are +referred to as ``codecs`` in FRR. + +A codec is defined as: + +.. code-block:: c + + typedef void (*encoder_func)(lua_State *, const void *); + typedef void *(*decoder_func)(lua_State *, int); + + struct frrscript_codec { + const char *typename; + encoder_func encoder; + decoder_func decoder; + }; + +A typename string and two function pointers. + +``typename`` can be anything you want. For example, for the combined types of +``struct prefix`` and its equivalent in Lua I have chosen the name ``prefix``. +There is no restriction on naming here, it is just a human name used as a key +and specified when passing and retrieving values. + +``encoder`` is a function that takes a ``lua_State *`` and a C type and pushes +onto the Lua stack a value representing the C type. For C structs, the usual +case, this will typically be a Lua table (tables are the only datastructure Lua +has). For example, here is the encoder function for ``struct prefix``: + + +.. code-block:: c + + void lua_pushprefix(lua_State *L, const struct prefix *prefix) + { + char buffer[PREFIX_STRLEN]; + + zlog_debug("frrlua: pushing prefix table"); + + lua_newtable(L); + lua_pushstring(L, prefix2str(prefix, buffer, PREFIX_STRLEN)); + lua_setfield(L, -2, "network"); + lua_pushinteger(L, prefix->prefixlen); + lua_setfield(L, -2, "length"); + lua_pushinteger(L, prefix->family); + lua_setfield(L, -2, "family"); + } + +This function pushes a single value onto the Lua stack. It is a table whose equivalent in Lua is: + +.. code-block:: + + { ["network"] = "1.2.3.4/24", ["prefixlen"] = 24, ["family"] = 2 } + + +``decoder`` does the reverse; it takes a ``lua_State *`` and an index into the +stack, and unmarshalls a Lua value there into the corresponding C type. Again +for ``struct prefix``: + + +.. code-block:: c + + void *lua_toprefix(lua_State *L, int idx) + { + struct prefix *p = XCALLOC(MTYPE_TMP, sizeof(struct prefix)); + + lua_getfield(L, idx, "network"); + str2prefix(lua_tostring(L, -1), p); + lua_pop(L, 1); + + return p; + } + +By convention these functions should be called ``lua_to*``, as this is the +naming convention used by the Lua C library for the basic types e.g. +``lua_tointeger`` and ``lua_tostring``. + +The returned data must always be copied off the stack and the copy must be +allocated with ``MTYPE_TMP``. This way it is possible to unload the script +(destroy the state) without invalidating any references to values stored in it. + +To register a new type with its corresponding encoding functions: + +.. code-block:: c + + struct frrscript_codec frrscript_codecs_lib[] = { + {.typename = "prefix", + .encoder = (encoder_func)lua_pushprefix, + .decoder = lua_toprefix}, + {.typename = "sockunion", + .encoder = (encoder_func)lua_pushsockunion, + .decoder = lua_tosockunion}, + ... + {}}; + + frrscript_register_type_codecs(frrscript_codecs_lib); + +From this point on the type names are available to be used when calling any +script and getting its results. + +.. note:: + + Marshalled types are not restricted to simple values like integers, strings + and tables. It is possible to marshall a type such that the resultant object + in Lua is an actual object-oriented object, complete with methods that call + back into defined C functions. See the Lua manual for how to do this; for a + code example, look at how zlog is exported into the script environment. + + +Script Environment +------------------ + +Logging +^^^^^^^ + +For convenience, script environments are populated by default with a ``log`` +object which contains methods corresponding to each of the ``zlog`` levels: + +.. code-block:: lua + + log.info("info") + log.warn("warn") + log.error("error") + log.notice("notice") + log.debug("debug") + +The log messages will show up in the daemon's log output. + + +Examples +-------- + +For a complete code example involving passing custom types, retrieving results, +and doing complex calculations in Lua, look at the implementation of the +``match script SCRIPT`` command for BGP routemaps. This example calls into a +script with a route prefix and attributes received from a peer and expects the +script to return a match / no match / match and update result. + +An example script to use with this follows. This script matches, does not match +or updates a route depending on how many BGP UPDATE messages the peer has +received when the script is called, simply as a demonstration of what can be +accomplished with scripting. + +.. code-block:: lua + + + -- Example route map matching + -- author: qlyoung + -- + -- The following variables are available to us: + -- log + -- logging library, with the usual functions + -- prefix + -- the route under consideration + -- attributes + -- the route's attributes + -- peer + -- the peer which received this route + -- RM_FAILURE + -- status code in case of failure + -- RM_NOMATCH + -- status code for no match + -- RM_MATCH + -- status code for match + -- RM_MATCH_AND_CHANGE + -- status code for match-and-set + -- + -- We need to set the following out values: + -- action + -- Set to the appropriate status code to indicate what we did + -- attributes + -- Setting fields on here will propagate them back up to the caller if + -- 'action' is set to RM_MATCH_AND_CHANGE. + + + log.info("Evaluating route " .. prefix.network .. " from peer " .. peer.remote_id.string) + + function on_match (prefix, attrs) + log.info("Match") + action = RM_MATCH + end + + function on_nomatch (prefix, attrs) + log.info("No match") + action = RM_NOMATCH + end + + function on_match_and_change (prefix, attrs) + action = RM_MATCH_AND_CHANGE + log.info("Match and change") + attrs["metric"] = attrs["metric"] + 7 + end + + special_routes = { + ["172.16.10.4/24"] = on_match, + ["172.16.13.1/8"] = on_nomatch, + ["192.168.0.24/8"] = on_match_and_change, + } + + + if special_routes[prefix.network] then + special_routes[prefix.network](prefix, attributes) + elseif peer.stats.update_in % 3 == 0 then + on_match(prefix, attributes) + elseif peer.stats.update_in % 2 == 0 then + on_nomatch(prefix, attributes) + else + on_match_and_change(prefix, attributes) + end + diff --git a/doc/developer/subdir.am b/doc/developer/subdir.am index f131ba89d9..07a25886d0 100644 --- a/doc/developer/subdir.am +++ b/doc/developer/subdir.am @@ -33,10 +33,10 @@ dev_RSTFILES = \ doc/developer/include-compile.rst \ doc/developer/index.rst \ doc/developer/library.rst \ + doc/developer/link-state.rst \ doc/developer/lists.rst \ doc/developer/locking.rst \ doc/developer/logging.rst \ - doc/developer/lua.rst \ doc/developer/memtypes.rst \ doc/developer/modules.rst \ doc/developer/next-hop-tracking.rst \ @@ -51,7 +51,9 @@ dev_RSTFILES = \ doc/developer/path-internals.rst \ doc/developer/path.rst \ doc/developer/rcu.rst \ + doc/developer/scripting.rst \ doc/developer/static-linking.rst \ + doc/developer/tracing.rst \ doc/developer/testing.rst \ doc/developer/topotests-snippets.rst \ doc/developer/topotests.rst \ diff --git a/doc/developer/tracing.rst b/doc/developer/tracing.rst index ee0a6be008..d54f6c7aaa 100644 --- a/doc/developer/tracing.rst +++ b/doc/developer/tracing.rst @@ -57,7 +57,7 @@ run the target in non-forking mode (no ``-d``) and use LTTng as usual (refer to LTTng user manual). When using USDT probes with LTTng, follow the example in `this article <https://lttng.org/blog/2019/10/15/new-dynamic-user-space-tracing-in-lttng/>`_. -To trace with dtrace or SystemTap, compile with :option:`--enable-usdt=yes` and +To trace with dtrace or SystemTap, compile with `--enable-usdt=yes` and use your tracer as usual. To see available USDT probes:: diff --git a/doc/developer/workflow.rst b/doc/developer/workflow.rst index 4183ac6480..861d87b998 100644 --- a/doc/developer/workflow.rst +++ b/doc/developer/workflow.rst @@ -1262,6 +1262,9 @@ When documented this way, CLI commands can be cross referenced with the This is very helpful for users who want to quickly remind themselves what a particular command does. +When documenting a cli that has a ``no`` form, please do not include +the ``no`` in the ``.. index::`` line. + Configuration Snippets ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index 7bef7d19c8..e609761e1c 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -31,12 +31,23 @@ be specified (:ref:`common-invocation-options`). .. option:: -l, --listenon - Specify a specific IP address for bgpd to listen on, rather than its default + Specify specific IP addresses for bgpd to listen on, rather than its default of ``0.0.0.0`` / ``::``. This can be useful to constrain bgpd to an internal - address, or to run multiple bgpd processes on one host. + address, or to run multiple bgpd processes on one host. Multiple addresses + can be specified. + + In the following example, bgpd is started listening for connections on the + addresses 100.0.1.2 and fd00::2:2. The options -d (runs in daemon mode) and + -f (uses specific configuration file) are also used in this example as we + are likely to run multiple bgpd instances, each one with different + configurations, when using -l option. Note that this option implies the --no_kernel option, and no learned routes will be installed into the linux kernel. +.. code-block:: shell + + # /usr/lib/frr/bgpd -d -f /some-folder/bgpd.conf -l 100.0.1.2 -l fd00::2:2 + .. option:: -n, --no_kernel Do not install learned routes into the linux kernel. This option is useful @@ -457,7 +468,7 @@ Reject routes with AS_SET or AS_CONFED_SET types Suppress duplicate updates -------------------------- -.. index:: [no] bgp suppress-duplicates +.. index:: bgp suppress-duplicates .. clicmd:: [no] bgp suppress-duplicates For example, BGP routers can generate multiple identical announcements with @@ -480,28 +491,57 @@ Disable checking if nexthop is connected on EBGP sessions Route Flap Dampening -------------------- -.. clicmd:: bgp dampening (1-45) (1-20000) (1-20000) (1-255) +.. index:: [no] bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]] +.. clicmd:: [no] bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]] + + This command enables (with optionally specified dampening parameters) or + disables route-flap dampening for all routes of a BGP instance. + +.. index:: [no] neighbor PEER dampening [(1-45) [(1-20000) (1-20000) (1-255)]] +.. clicmd:: [no] neighbor PEER dampening [(1-45) [(1-20000) (1-20000) (1-255)]] + + This command enables (with optionally specified dampening parameters) or + disables route-flap dampening for all routes learned from a BGP peer. + +.. index:: [no] neighbor GROUP dampening [(1-45) [(1-20000) (1-20000) (1-255)]] +.. clicmd:: [no] neighbor GROUP dampening [(1-45) [(1-20000) (1-20000) (1-255)]] - This command enables BGP route-flap dampening and specifies dampening parameters. + This command enables (with optionally specified dampening parameters) or + disables route-flap dampening for all routes learned from peers of a peer + group. half-life - Half-life time for the penalty + Half-life time for the penalty in minutes (default value: 15). reuse-threshold - Value to start reusing a route + Value to start reusing a route (default value: 750). suppress-threshold - Value to start suppressing a route + Value to start suppressing a route (default value: 2000). max-suppress - Maximum duration to suppress a stable route + Maximum duration to suppress a stable route in minutes (default value: + 60). The route-flap damping algorithm is compatible with :rfc:`2439`. The use of - this command is not recommended nowadays. + these commands is not recommended nowadays. At the moment, route-flap dampening is not working per VRF and is working only for IPv4 unicast and multicast. + With different parameter sets configurable for BGP instances, peer groups and + peers, the active dampening profile for a route is chosen on the fly, + allowing for various changes in configuration (i.e. peer group memberships) + during runtime. The parameter sets are taking precedence in the following + order: + + 1. Peer + 2. Peer group + 3. BGP instance + + The negating commands do not allow to exclude a peer/peer group from a peer + group/BGP instances configuration. + .. seealso:: https://www.ripe.net/publications/docs/ripe-378 @@ -894,6 +934,19 @@ However, it MUST defer route selection for an address family until it either. This is command, will set the time for which stale routes are kept in RIB. +.. index:: bgp graceful-restart stalepath-time (1-4095) +.. clicmd:: bgp graceful-restart stalepath-time (1-4095) + + This is command, will set the max time (in seconds) to hold onto + restarting peer's stale paths. + + It also controls Enhanced Route-Refresh timer. + + If this command is configured and the router does not receive a Route-Refresh EoRR + message, the router removes the stale routes from the BGP table after the timer + expires. The stale path timer is started when the router receives a Route-Refresh + BoRR message. + .. _bgp-per-peer-graceful-restart: BGP Per Peer Graceful Restart @@ -1639,7 +1692,7 @@ Configuring Peers peer in question. This number is between 0 and 600 seconds, with the default advertisement interval being 0. -.. index:: [no] neighbor PEER timers delayopen (1-240) +.. index:: neighbor PEER timers delayopen (1-240) .. clicmd:: [no] neighbor PEER timers delayopen (1-240) This command allows the user enable the @@ -3539,7 +3592,7 @@ starting the daemon and the configuration gets saved, the option will persist unless removed from the configuration with the negating command prior to the configuration write operation. -.. index:: [no] bgp send-extra-data zebra +.. index:: bgp send-extra-data zebra .. clicmd:: [no] bgp send-extra-data zebra This Command turns off the ability of BGP to send extra data to zebra. diff --git a/doc/user/index.rst b/doc/user/index.rst index 993acf3b4c..7b9464668b 100644 --- a/doc/user/index.rst +++ b/doc/user/index.rst @@ -29,6 +29,7 @@ Basics ipv6 kernel snmp + scripting .. modules ######### diff --git a/doc/user/installation.rst b/doc/user/installation.rst index 382d71b71f..a13e6ce43b 100644 --- a/doc/user/installation.rst +++ b/doc/user/installation.rst @@ -362,6 +362,10 @@ options from the list below. Set hardcoded rpaths in the executable [default=yes]. +.. option:: --enable-scripting + + Enable Lua scripting [default=no]. + You may specify any combination of the above options to the configure script. By default, the executables are placed in :file:`/usr/local/sbin` and the configuration files in :file:`/usr/local/etc`. The :file:`/usr/local/` @@ -382,6 +386,10 @@ options to the configuration script. Configure zebra to use `dir` for local state files, such as pid files and unix sockets. +.. option:: --with-scriptdir <dir> + + Look for Lua scripts in ``dir`` [``prefix``/etc/frr/scripts]. + .. option:: --with-yangmodelsdir <dir> Look for YANG modules in `dir` [`prefix`/share/yang]. Note that the FRR diff --git a/doc/user/isisd.rst b/doc/user/isisd.rst index f991e3f073..7e198564b5 100644 --- a/doc/user/isisd.rst +++ b/doc/user/isisd.rst @@ -204,6 +204,12 @@ ISIS Fast-Reroute Disable load sharing across multiple LFA backups. +.. index:: fast-reroute remote-lfa prefix-list WORD [level-1 | level-2] +.. clicmd:: [no] fast-reroute remote-lfa prefix-list [WORD] [level-1 | level-2] + + Configure a prefix-list to select eligible PQ nodes (valid for all protected + interfaces). + .. _isis-region: ISIS region @@ -400,6 +406,18 @@ ISIS interface Enable per-prefix TI-LFA fast reroute link or node protection. +.. index:: isis fast-reroute remote-lfa tunnel mpls-ldp [level-1 | level-2] +.. clicmd:: [no] isis fast-reroute remote-lfa tunnel mpls-ldp [level-1 | level-2] + + Enable per-prefix Remote LFA fast reroute link protection. Note that other + routers in the network need to be configured to accept LDP targeted hello + messages in order for RLFA to work. + +.. index:: isis fast-reroute remote-lfa maximum-metric (1-16777215) [level-1 | level-2] +.. clicmd:: [no] isis fast-reroute remote-lfa maximum-metric (1-16777215) [level-1 | level-2] + + Limit Remote LFA PQ node selection within the specified metric. + .. _showing-isis-information: Showing ISIS information diff --git a/doc/user/ospfd.rst b/doc/user/ospfd.rst index cbde0fd46f..7184a0e197 100644 --- a/doc/user/ospfd.rst +++ b/doc/user/ospfd.rst @@ -322,6 +322,23 @@ To start OSPF process you have to specify the OSPF router. This feature is enabled by default. +.. index:: clear ip ospf [(1-65535)] process +.. clicmd:: clear ip ospf [(1-65535)] process + + This command can be used to clear the ospf process data structures. This + will clear the ospf neighborship as well and it will get re-established. + This will clear the LSDB too. This will be helpful when there is a change + in router-id and if user wants the router-id change to take effect, user can + use this cli instead of restarting the ospfd daemon. + +.. index:: clear ip ospf [(1-65535)] neighbor +.. clicmd:: clear ip ospf [(1-65535)] neighbor + + This command can be used to clear the ospf neighbor data structures. This + will clear the ospf neighborship and it will get re-established. This + command can be used when the neighbor state get stuck at some state and + this can be used to recover it from that state. + .. _ospf-area: Areas diff --git a/doc/user/overview.rst b/doc/user/overview.rst index a2ce67068f..f67698e404 100644 --- a/doc/user/overview.rst +++ b/doc/user/overview.rst @@ -321,6 +321,8 @@ BGP :t:`The Resource Public Key Infrastructure (RPKI) to Router Protocol. R. Bush, R. Austein. January 2013.` - :rfc:`6811` :t:`BGP Prefix Origin Validation. P. Mohapatra, J. Scudder, D. Ward, R. Bush, R. Austein. January 2013.` +- :rfc:`7313` + :t:`Enhanced Route Refresh Capability for BGP-4. K. Patel, E. Chen, B. Venkatachalapathy. July 2014.` - :rfc:`7606` :t:`Revised Error Handling for BGP UPDATE Messages. E. Chen, J. Scudder, P. Mohapatra, K. Patel. August 2015.` - :rfc:`7607` diff --git a/doc/user/pathd.rst b/doc/user/pathd.rst index 5e210e2489..0815a6c414 100644 --- a/doc/user/pathd.rst +++ b/doc/user/pathd.rst @@ -115,19 +115,19 @@ Configuration Commands Configure segment routing traffic engineering. -.. index:: [no] segment-list NAME +.. index:: segment-list NAME .. clicmd:: [no] segment-list NAME Delete or start a segment list definition. -.. index:: [no] index INDEX mpls label LABEL [nai node ADDRESS] +.. index:: index INDEX mpls label LABEL [nai node ADDRESS] .. clicmd:: [no] index INDEX mpls label LABEL [nai node ADDRESS] Delete or specify a segment in a segment list definition. -.. index:: [no] policy color COLOR endpoint ENDPOINT +.. index:: policy color COLOR endpoint ENDPOINT .. clicmd:: [no] policy color COLOR endpoint ENDPOINT Delete or start a policy definition. @@ -145,31 +145,31 @@ Configuration Commands Specify the policy SID. -.. index:: [no] candidate-path preference PREFERENCE name NAME explicit segment-list SEGMENT-LIST-NAME +.. index:: candidate-path preference PREFERENCE name NAME explicit segment-list SEGMENT-LIST-NAME .. clicmd:: [no] candidate-path preference PREFERENCE name NAME explicit segment-list SEGMENT-LIST-NAME Delete or define an explicit candidate path. -.. index:: [no] candidate-path preference PREFERENCE name NAME dynamic +.. index:: candidate-path preference PREFERENCE name NAME dynamic .. clicmd:: [no] candidate-path preference PREFERENCE name NAME dynamic Delete or start a dynamic candidate path definition. -.. index:: [no] affinity {exclude-any|include-any|include-all} BITPATTERN +.. index:: affinity {exclude-any|include-any|include-all} BITPATTERN .. clicmd:: [no] affinity {exclude-any|include-any|include-all} BITPATTERN Delete or specify an affinity constraint for a dynamic candidate path. -.. index:: [no] bandwidth BANDWIDTH [required] +.. index:: bandwidth BANDWIDTH [required] .. clicmd:: [no] bandwidth BANDWIDTH [required] Delete or specify a bandwidth constraint for a dynamic candidate path. -.. index:: [no] metric [bound] METRIC VALUE [required] +.. index:: metric [bound] METRIC VALUE [required] .. clicmd:: [no] metric [bound] METRIC VALUE [required] Delete or specify a metric constraint for a dynamic candidate path. @@ -198,7 +198,7 @@ Configuration Commands - bnc: Border Node Count metric -.. index:: [no] objective-function OBJFUN1 [required] +.. index:: objective-function OBJFUN1 [required] .. clicmd:: [no] objective-function OBJFUN1 [required] Delete or specify a PCEP objective function constraint for a dynamic @@ -224,7 +224,7 @@ Configuration Commands - msn: Minimize the number of Shared Nodes [RFC8800] -.. index:: [no] debug pathd pcep [basic|path|message|pceplib] +.. index:: debug pathd pcep [basic|path|message|pceplib] .. clicmd:: [no] debug pathd pcep [basic|path|message|pceplib] Enable or disable debugging for the pcep module: @@ -241,14 +241,14 @@ Configuration Commands Configure PCEP support. -.. index:: [no] cep-config NAME +.. index:: cep-config NAME .. clicmd:: [no] pce-config NAME Define a shared PCE configuration that can be used in multiple PCE declarations. -.. index:: [no] pce NAME +.. index:: pce NAME .. clicmd:: [no] pce NAME Define or delete a PCE definition. @@ -321,7 +321,7 @@ Configuration Commands configuration group. -.. index:: [no] pcc +.. index:: pcc .. clicmd:: [no] pcc Disable or start the definition of a PCC. @@ -333,7 +333,7 @@ Configuration Commands Specify the maximum SID depth in a PCC definition. -.. index:: [no] peer WORD [precedence (1-255)] +.. index:: peer WORD [precedence (1-255)] .. clicmd:: [no] peer WORD [precedence (1-255)] Specify a peer and its precedence in a PCC definition. diff --git a/doc/user/scripting.rst b/doc/user/scripting.rst new file mode 100644 index 0000000000..b0295e5706 --- /dev/null +++ b/doc/user/scripting.rst @@ -0,0 +1,28 @@ +.. _scripting: + +********* +Scripting +********* + +The behavior of FRR may be extended or customized using its built-in scripting +capabilities. + +Some configuration commands accept the name of a Lua script to call to perform +some task or make some decision. These scripts have their environments +populated with some set of inputs, and are expected to populate some set of +output variables, which are read by FRR after the script completes. The names +and expected contents of these scripts are documented alongside the commands +that support them. + +These scripts live in :file:`/etc/frr/scripts/` by default. This is +configurable at compile time via ``--with-scriptdir``. It may be +overriden at runtime with the ``--scriptdir`` daemon option. + +In order to use scripting, FRR must be built with ``--enable-scripting``. + +.. note:: + + Scripts are typically loaded just-in-time. This means you can change the + contents of a script that is in use without restarting FRR. Not all + scripting locations may behave this way; refer to the documentation for the + particular location. diff --git a/doc/user/subdir.am b/doc/user/subdir.am index a78d261863..3585245e85 100644 --- a/doc/user/subdir.am +++ b/doc/user/subdir.am @@ -35,6 +35,7 @@ user_RSTFILES = \ doc/user/routemap.rst \ doc/user/routeserver.rst \ doc/user/rpki.rst \ + doc/user/scripting.rst \ doc/user/setup.rst \ doc/user/sharp.rst \ doc/user/snmp.rst \ diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index 91cd205bed..b94c248b33 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -759,6 +759,12 @@ IPv6 example for OSPFv3. not created at startup. On Debian, FRR might start before ifupdown completes. Consider a reboot test. +.. index:: zebra route-map delay-timer (0-600) +.. clicmd:: [no] zebra route-map delay-timer (0-600) + + Set the delay before any route-maps are processed in zebra. The + default time for this is 5 seconds. + .. _zebra-fib-push-interface: zebra FIB push interface diff --git a/eigrpd/eigrp_cli.c b/eigrpd/eigrp_cli.c index 3610b3a869..00d8ea8867 100644 --- a/eigrpd/eigrp_cli.c +++ b/eigrpd/eigrp_cli.c @@ -29,6 +29,7 @@ #include "eigrp_structs.h" #include "eigrpd.h" #include "eigrp_zebra.h" +#include "eigrp_cli.h" #ifndef VTYSH_EXTRACT_PL #include "eigrpd/eigrp_cli_clippy.c" diff --git a/eigrpd/eigrp_cli.h b/eigrpd/eigrp_cli.h new file mode 100644 index 0000000000..c5f2fd8009 --- /dev/null +++ b/eigrpd/eigrp_cli.h @@ -0,0 +1,70 @@ +/* + * EIGRP CLI Functions. + * Copyright (C) 2019 + * Authors: + * Donnie Savage + * + * This file is part of FRR. + * + * FRR is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * FRR is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _EIGRP_CLI_H_ +#define _EIGRP_CLI_H_ + +/*Prototypes*/ +extern void eigrp_cli_show_header(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +extern void eigrp_cli_show_end_header(struct vty *vty, struct lyd_node *dnode); +extern void eigrp_cli_show_router_id(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +extern void eigrp_cli_show_passive_interface(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +extern void eigrp_cli_show_active_time(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +extern void eigrp_cli_show_variance(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +extern void eigrp_cli_show_maximum_paths(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +extern void eigrp_cli_show_metrics(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +extern void eigrp_cli_show_network(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +extern void eigrp_cli_show_neighbor(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +extern void eigrp_cli_show_redistribute(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +extern void eigrp_cli_show_delay(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +extern void eigrp_cli_show_bandwidth(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +extern void eigrp_cli_show_hello_interval(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +extern void eigrp_cli_show_hold_time(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +extern void eigrp_cli_show_summarize_address(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +extern void eigrp_cli_show_authentication(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +extern void eigrp_cli_show_keychain(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); +extern void eigrp_cli_init(void); + +#endif /*EIGRP_CLI_H_ */ diff --git a/eigrpd/eigrp_const.h b/eigrpd/eigrp_const.h index d3d9bca82a..149cf00efc 100644 --- a/eigrpd/eigrp_const.h +++ b/eigrpd/eigrp_const.h @@ -122,10 +122,10 @@ enum metric_change { METRIC_DECREASE, METRIC_SAME, METRIC_INCREASE }; #define EIGRP_TOPOLOGY_TYPE_REMOTE_EXTERNAL 2 // Remote external network /*EIGRP TT entry flags*/ -#define EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG (1 << 0) -#define EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG (1 << 1) -#define EIGRP_NEXTHOP_ENTRY_INTABLE_FLAG (1 << 2) -#define EIGRP_NEXTHOP_ENTRY_EXTERNAL_FLAG (1 << 3) +#define EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG (1 << 0) +#define EIGRP_ROUTE_DESCRIPTOR_FSUCCESSOR_FLAG (1 << 1) +#define EIGRP_ROUTE_DESCRIPTOR_INTABLE_FLAG (1 << 2) +#define EIGRP_ROUTE_DESCRIPTOR_EXTERNAL_FLAG (1 << 3) /*EIGRP FSM state count, event count*/ #define EIGRP_FSM_STATE_MAX 5 diff --git a/eigrpd/eigrp_dump.c b/eigrpd/eigrp_dump.c index dfce2acad4..e1ad51a9db 100644 --- a/eigrpd/eigrp_dump.c +++ b/eigrpd/eigrp_dump.c @@ -236,7 +236,8 @@ void show_ip_eigrp_topology_header(struct vty *vty, struct eigrp *eigrp) "Codes: P - Passive, A - Active, U - Update, Q - Query, R - Reply\n r - reply Status, s - sia Status\n\n"); } -void show_ip_eigrp_prefix_entry(struct vty *vty, struct eigrp_prefix_entry *tn) +void show_ip_eigrp_prefix_descriptor(struct vty *vty, + struct eigrp_prefix_descriptor *tn) { struct list *successors = eigrp_topology_get_successor(tn); @@ -251,14 +252,15 @@ void show_ip_eigrp_prefix_entry(struct vty *vty, struct eigrp_prefix_entry *tn) list_delete(&successors); } -void show_ip_eigrp_nexthop_entry(struct vty *vty, struct eigrp *eigrp, - struct eigrp_nexthop_entry *te, bool *first) +void show_ip_eigrp_route_descriptor(struct vty *vty, struct eigrp *eigrp, + struct eigrp_route_descriptor *te, + bool *first) { if (te->reported_distance == EIGRP_MAX_METRIC) return; if (*first) { - show_ip_eigrp_prefix_entry(vty, te->prefix); + show_ip_eigrp_prefix_descriptor(vty, te->prefix); *first = false; } diff --git a/eigrpd/eigrp_dump.h b/eigrpd/eigrp_dump.h index 348356bb3c..0d512fc63f 100644 --- a/eigrpd/eigrp_dump.h +++ b/eigrpd/eigrp_dump.h @@ -151,11 +151,11 @@ extern void show_ip_eigrp_interface_sub(struct vty *, struct eigrp *, struct eigrp_interface *); extern void show_ip_eigrp_neighbor_sub(struct vty *, struct eigrp_neighbor *, int); -extern void show_ip_eigrp_prefix_entry(struct vty *, - struct eigrp_prefix_entry *); -extern void show_ip_eigrp_nexthop_entry(struct vty *vty, struct eigrp *eigrp, - struct eigrp_nexthop_entry *ne, - bool *first); +extern void show_ip_eigrp_prefix_descriptor(struct vty *vty, + struct eigrp_prefix_descriptor *tn); +extern void show_ip_eigrp_route_descriptor(struct vty *vty, struct eigrp *eigrp, + struct eigrp_route_descriptor *ne, + bool *first); extern void eigrp_debug_init(void); diff --git a/eigrpd/eigrp_fsm.c b/eigrpd/eigrp_fsm.c index a69a3eec0a..d2d435bf2d 100644 --- a/eigrpd/eigrp_fsm.c +++ b/eigrpd/eigrp_fsm.c @@ -77,6 +77,7 @@ #include "linklist.h" #include "vty.h" +#include "eigrpd/eigrp_types.h" #include "eigrpd/eigrp_structs.h" #include "eigrpd/eigrpd.h" #include "eigrpd/eigrp_interface.h" @@ -88,6 +89,7 @@ #include "eigrpd/eigrp_dump.h" #include "eigrpd/eigrp_topology.h" #include "eigrpd/eigrp_fsm.h" +#include "eigrpd/eigrp_metric.h" /* * Prototypes @@ -262,13 +264,13 @@ eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) { // Loading base information from message // struct eigrp *eigrp = msg->eigrp; - struct eigrp_prefix_entry *prefix = msg->prefix; - struct eigrp_nexthop_entry *entry = msg->entry; + struct eigrp_prefix_descriptor *prefix = msg->prefix; + struct eigrp_route_descriptor *entry = msg->entry; uint8_t actual_state = prefix->state; enum metric_change change; if (entry == NULL) { - entry = eigrp_nexthop_entry_new(); + entry = eigrp_route_descriptor_new(); entry->adv_router = msg->adv_router; entry->ei = msg->adv_router->ei; entry->prefix = prefix; @@ -286,7 +288,7 @@ eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) switch (actual_state) { case EIGRP_FSM_STATE_PASSIVE: { - struct eigrp_nexthop_entry *head = + struct eigrp_route_descriptor *head = listnode_head(prefix->entries); if (head->reported_distance < prefix->fdistance) { @@ -307,7 +309,7 @@ eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) } case EIGRP_FSM_STATE_ACTIVE_0: { if (msg->packet_type == EIGRP_OPC_REPLY) { - struct eigrp_nexthop_entry *head = + struct eigrp_route_descriptor *head = listnode_head(prefix->entries); listnode_delete(prefix->rij, entry->adv_router); @@ -322,7 +324,7 @@ eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) return EIGRP_FSM_EVENT_LR_FCN; } else if (msg->packet_type == EIGRP_OPC_QUERY && (entry->flags - & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) { + & EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG)) { return EIGRP_FSM_EVENT_QACT; } @@ -332,14 +334,14 @@ eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) } case EIGRP_FSM_STATE_ACTIVE_1: { if (msg->packet_type == EIGRP_OPC_QUERY - && (entry->flags & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) { + && (entry->flags & EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG)) { return EIGRP_FSM_EVENT_QACT; } else if (msg->packet_type == EIGRP_OPC_REPLY) { listnode_delete(prefix->rij, entry->adv_router); if (change == METRIC_INCREASE && (entry->flags - & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) { + & EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG)) { return EIGRP_FSM_EVENT_DINC; } else if (prefix->rij->count) { return EIGRP_FSM_KEEP_STATE; @@ -350,7 +352,7 @@ eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) } else if (msg->packet_type == EIGRP_OPC_UPDATE && change == METRIC_INCREASE && (entry->flags - & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) { + & EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG)) { return EIGRP_FSM_EVENT_DINC; } return EIGRP_FSM_KEEP_STATE; @@ -359,7 +361,7 @@ eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) } case EIGRP_FSM_STATE_ACTIVE_2: { if (msg->packet_type == EIGRP_OPC_REPLY) { - struct eigrp_nexthop_entry *head = + struct eigrp_route_descriptor *head = listnode_head(prefix->entries); listnode_delete(prefix->rij, entry->adv_router); @@ -385,7 +387,7 @@ eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) if (change == METRIC_INCREASE && (entry->flags - & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) { + & EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG)) { return EIGRP_FSM_EVENT_DINC; } else if (prefix->rij->count) { return EIGRP_FSM_KEEP_STATE; @@ -396,7 +398,7 @@ eigrp_get_fsm_event(struct eigrp_fsm_action_message *msg) } else if (msg->packet_type == EIGRP_OPC_UPDATE && change == METRIC_INCREASE && (entry->flags - & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG)) { + & EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG)) { return EIGRP_FSM_EVENT_DINC; } return EIGRP_FSM_KEEP_STATE; @@ -434,9 +436,9 @@ int eigrp_fsm_event(struct eigrp_fsm_action_message *msg) int eigrp_fsm_event_nq_fcn(struct eigrp_fsm_action_message *msg) { struct eigrp *eigrp = msg->eigrp; - struct eigrp_prefix_entry *prefix = msg->prefix; + struct eigrp_prefix_descriptor *prefix = msg->prefix; struct list *successors = eigrp_topology_get_successor(prefix); - struct eigrp_nexthop_entry *ne; + struct eigrp_route_descriptor *ne; assert(successors); // If this is NULL we have shit the bed, fun huh? @@ -461,9 +463,9 @@ int eigrp_fsm_event_nq_fcn(struct eigrp_fsm_action_message *msg) int eigrp_fsm_event_q_fcn(struct eigrp_fsm_action_message *msg) { struct eigrp *eigrp = msg->eigrp; - struct eigrp_prefix_entry *prefix = msg->prefix; + struct eigrp_prefix_descriptor *prefix = msg->prefix; struct list *successors = eigrp_topology_get_successor(prefix); - struct eigrp_nexthop_entry *ne; + struct eigrp_route_descriptor *ne; assert(successors); // If this is NULL somebody poked us in the eye. @@ -487,8 +489,8 @@ int eigrp_fsm_event_q_fcn(struct eigrp_fsm_action_message *msg) int eigrp_fsm_event_keep_state(struct eigrp_fsm_action_message *msg) { struct eigrp *eigrp = msg->eigrp; - struct eigrp_prefix_entry *prefix = msg->prefix; - struct eigrp_nexthop_entry *ne = listnode_head(prefix->entries); + struct eigrp_prefix_descriptor *prefix = msg->prefix; + struct eigrp_route_descriptor *ne = listnode_head(prefix->entries); if (prefix->state == EIGRP_FSM_STATE_PASSIVE) { if (!eigrp_metrics_is_same(prefix->reported_metric, @@ -515,8 +517,8 @@ int eigrp_fsm_event_keep_state(struct eigrp_fsm_action_message *msg) int eigrp_fsm_event_lr(struct eigrp_fsm_action_message *msg) { struct eigrp *eigrp = msg->eigrp; - struct eigrp_prefix_entry *prefix = msg->prefix; - struct eigrp_nexthop_entry *ne = listnode_head(prefix->entries); + struct eigrp_prefix_descriptor *prefix = msg->prefix; + struct eigrp_route_descriptor *ne = listnode_head(prefix->entries); prefix->fdistance = prefix->distance = prefix->rdistance = ne->distance; prefix->reported_metric = ne->total_metric; @@ -545,7 +547,7 @@ int eigrp_fsm_event_lr(struct eigrp_fsm_action_message *msg) int eigrp_fsm_event_dinc(struct eigrp_fsm_action_message *msg) { struct list *successors = eigrp_topology_get_successor(msg->prefix); - struct eigrp_nexthop_entry *ne; + struct eigrp_route_descriptor *ne; assert(successors); // Trump and his big hands @@ -566,8 +568,8 @@ int eigrp_fsm_event_dinc(struct eigrp_fsm_action_message *msg) int eigrp_fsm_event_lr_fcs(struct eigrp_fsm_action_message *msg) { struct eigrp *eigrp = msg->eigrp; - struct eigrp_prefix_entry *prefix = msg->prefix; - struct eigrp_nexthop_entry *ne = listnode_head(prefix->entries); + struct eigrp_prefix_descriptor *prefix = msg->prefix; + struct eigrp_route_descriptor *ne = listnode_head(prefix->entries); prefix->state = EIGRP_FSM_STATE_PASSIVE; prefix->distance = prefix->rdistance = ne->distance; @@ -598,8 +600,8 @@ int eigrp_fsm_event_lr_fcs(struct eigrp_fsm_action_message *msg) int eigrp_fsm_event_lr_fcn(struct eigrp_fsm_action_message *msg) { struct eigrp *eigrp = msg->eigrp; - struct eigrp_prefix_entry *prefix = msg->prefix; - struct eigrp_nexthop_entry *best_successor; + struct eigrp_prefix_descriptor *prefix = msg->prefix; + struct eigrp_route_descriptor *best_successor; struct list *successors = eigrp_topology_get_successor(prefix); assert(successors); // Routing without a stack @@ -628,7 +630,7 @@ int eigrp_fsm_event_lr_fcn(struct eigrp_fsm_action_message *msg) int eigrp_fsm_event_qact(struct eigrp_fsm_action_message *msg) { struct list *successors = eigrp_topology_get_successor(msg->prefix); - struct eigrp_nexthop_entry *ne; + struct eigrp_route_descriptor *ne; assert(successors); // Cats and no Dogs diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index dd43dd0478..74eff958da 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -55,6 +55,8 @@ #include "eigrpd/eigrp_memory.h" #include "eigrpd/eigrp_fsm.h" #include "eigrpd/eigrp_dump.h" +#include "eigrpd/eigrp_types.h" +#include "eigrpd/eigrp_metric.h" struct eigrp_interface *eigrp_if_new(struct eigrp *eigrp, struct interface *ifp, struct prefix *p) @@ -229,8 +231,8 @@ void eigrp_del_if_params(struct eigrp_if_params *eip) int eigrp_if_up(struct eigrp_interface *ei) { - struct eigrp_prefix_entry *pe; - struct eigrp_nexthop_entry *ne; + struct eigrp_prefix_descriptor *pe; + struct eigrp_route_descriptor *ne; struct eigrp_metrics metric; struct eigrp_interface *ei2; struct listnode *node, *nnode; @@ -263,14 +265,14 @@ int eigrp_if_up(struct eigrp_interface *ei) /*Add connected entry to topology table*/ - ne = eigrp_nexthop_entry_new(); + ne = eigrp_route_descriptor_new(); ne->ei = ei; ne->reported_metric = metric; ne->total_metric = metric; ne->distance = eigrp_calculate_metrics(eigrp, metric); ne->reported_distance = 0; ne->adv_router = eigrp->neighbor_self; - ne->flags = EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG; + ne->flags = EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG; struct prefix dest_addr; @@ -280,7 +282,7 @@ int eigrp_if_up(struct eigrp_interface *ei) &dest_addr); if (pe == NULL) { - pe = eigrp_prefix_entry_new(); + pe = eigrp_prefix_descriptor_new(); pe->serno = eigrp->serno; pe->destination = (struct prefix *)prefix_ipv4_new(); prefix_copy(pe->destination, &dest_addr); @@ -292,10 +294,10 @@ int eigrp_if_up(struct eigrp_interface *ei) pe->state = EIGRP_FSM_STATE_PASSIVE; pe->fdistance = eigrp_calculate_metrics(eigrp, metric); pe->req_action |= EIGRP_FSM_NEED_UPDATE; - eigrp_prefix_entry_add(eigrp->topology_table, pe); + eigrp_prefix_descriptor_add(eigrp->topology_table, pe); listnode_add(eigrp->topology_changes_internalIPV4, pe); - eigrp_nexthop_entry_add(eigrp, pe, ne); + eigrp_route_descriptor_add(eigrp, pe, ne); for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei2)) { eigrp_update_send(ei2); @@ -307,7 +309,7 @@ int eigrp_if_up(struct eigrp_interface *ei) struct eigrp_fsm_action_message msg; ne->prefix = pe; - eigrp_nexthop_entry_add(eigrp, pe, ne); + eigrp_route_descriptor_add(eigrp, pe, ne); msg.packet_type = EIGRP_OPC_UPDATE; msg.eigrp = eigrp; @@ -416,7 +418,7 @@ uint8_t eigrp_default_iftype(struct interface *ifp) void eigrp_if_free(struct eigrp_interface *ei, int source) { struct prefix dest_addr; - struct eigrp_prefix_entry *pe; + struct eigrp_prefix_descriptor *pe; struct eigrp *eigrp = ei->eigrp; if (source == INTERFACE_DOWN_BY_VTY) { @@ -429,7 +431,8 @@ void eigrp_if_free(struct eigrp_interface *ei, int source) pe = eigrp_topology_table_lookup_ipv4(eigrp->topology_table, &dest_addr); if (pe) - eigrp_prefix_entry_delete(eigrp, eigrp->topology_table, pe); + eigrp_prefix_descriptor_delete(eigrp, eigrp->topology_table, + pe); eigrp_if_down(ei); @@ -494,33 +497,3 @@ struct eigrp_interface *eigrp_if_lookup_by_name(struct eigrp *eigrp, return NULL; } - -uint32_t eigrp_bandwidth_to_scaled(uint32_t bandwidth) -{ - uint64_t temp_bandwidth = (256ull * 10000000) / bandwidth; - - temp_bandwidth = temp_bandwidth < EIGRP_MAX_METRIC ? temp_bandwidth - : EIGRP_MAX_METRIC; - - return (uint32_t)temp_bandwidth; -} - -uint32_t eigrp_scaled_to_bandwidth(uint32_t scaled) -{ - uint64_t temp_scaled = scaled * (256ull * 10000000); - - temp_scaled = - temp_scaled < EIGRP_MAX_METRIC ? temp_scaled : EIGRP_MAX_METRIC; - - return (uint32_t)temp_scaled; -} - -uint32_t eigrp_delay_to_scaled(uint32_t delay) -{ - return delay * 256; -} - -uint32_t eigrp_scaled_to_delay(uint32_t scaled) -{ - return scaled / 256; -} diff --git a/eigrpd/eigrp_interface.h b/eigrpd/eigrp_interface.h index 1e66dafde2..68ab5125e3 100644 --- a/eigrpd/eigrp_interface.h +++ b/eigrpd/eigrp_interface.h @@ -58,9 +58,4 @@ extern struct eigrp_interface *eigrp_if_lookup_by_name(struct eigrp *, /* Simulate down/up on the interface. */ extern void eigrp_if_reset(struct interface *); -extern uint32_t eigrp_bandwidth_to_scaled(uint32_t); -extern uint32_t eigrp_scaled_to_bandwidth(uint32_t); -extern uint32_t eigrp_delay_to_scaled(uint32_t); -extern uint32_t eigrp_scaled_to_delay(uint32_t); - #endif /* ZEBRA_EIGRP_INTERFACE_H_ */ diff --git a/eigrpd/eigrp_main.c b/eigrpd/eigrp_main.c index 6c44ce361c..b1a6498cbc 100644 --- a/eigrpd/eigrp_main.c +++ b/eigrpd/eigrp_main.c @@ -66,6 +66,8 @@ #include "eigrpd/eigrp_filter.h" #include "eigrpd/eigrp_errors.h" #include "eigrpd/eigrp_vrf.h" +#include "eigrpd/eigrp_cli.h" +#include "eigrpd/eigrp_yang.h" //#include "eigrpd/eigrp_routemap.h" /* eigprd privileges */ diff --git a/eigrpd/eigrp_memory.c b/eigrpd/eigrp_memory.c index 85b14c28ce..57ca785340 100644 --- a/eigrpd/eigrp_memory.c +++ b/eigrpd/eigrp_memory.c @@ -37,6 +37,6 @@ DEFINE_MTYPE(EIGRPD, EIGRP_IPV4_INT_TLV, "EIGRP IPv4 TLV") DEFINE_MTYPE(EIGRPD, EIGRP_SEQ_TLV, "EIGRP SEQ TLV") DEFINE_MTYPE(EIGRPD, EIGRP_AUTH_TLV, "EIGRP AUTH TLV") DEFINE_MTYPE(EIGRPD, EIGRP_AUTH_SHA256_TLV, "EIGRP SHA TLV") -DEFINE_MTYPE(EIGRPD, EIGRP_PREFIX_ENTRY, "EIGRP Prefix") -DEFINE_MTYPE(EIGRPD, EIGRP_NEXTHOP_ENTRY, "EIGRP Nexthop Entry") +DEFINE_MTYPE(EIGRPD, EIGRP_PREFIX_DESCRIPTOR, "EIGRP Prefix") +DEFINE_MTYPE(EIGRPD, EIGRP_ROUTE_DESCRIPTOR, "EIGRP Nexthop Entry") DEFINE_MTYPE(EIGRPD, EIGRP_FSM_MSG, "EIGRP FSM Message") diff --git a/eigrpd/eigrp_memory.h b/eigrpd/eigrp_memory.h index e4d02c09d4..21ecba2aae 100644 --- a/eigrpd/eigrp_memory.h +++ b/eigrpd/eigrp_memory.h @@ -36,8 +36,8 @@ DECLARE_MTYPE(EIGRP_IPV4_INT_TLV) DECLARE_MTYPE(EIGRP_SEQ_TLV) DECLARE_MTYPE(EIGRP_AUTH_TLV) DECLARE_MTYPE(EIGRP_AUTH_SHA256_TLV) -DECLARE_MTYPE(EIGRP_PREFIX_ENTRY) -DECLARE_MTYPE(EIGRP_NEXTHOP_ENTRY) +DECLARE_MTYPE(EIGRP_PREFIX_DESCRIPTOR) +DECLARE_MTYPE(EIGRP_ROUTE_DESCRIPTOR) DECLARE_MTYPE(EIGRP_FSM_MSG) #endif /* _FRR_EIGRP_MEMORY_H */ diff --git a/eigrpd/eigrp_metric.c b/eigrpd/eigrp_metric.c new file mode 100644 index 0000000000..2b05db71d5 --- /dev/null +++ b/eigrpd/eigrp_metric.c @@ -0,0 +1,146 @@ +/* + * EIGRP Metric Math Functions. + * Copyright (C) 2013-2016 + * Authors: + * Donnie Savage + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "eigrpd/eigrp_structs.h" +#include "eigrpd/eigrpd.h" +#include "eigrpd/eigrp_types.h" +#include "eigrpd/eigrp_metric.h" + +eigrp_scaled_t eigrp_bandwidth_to_scaled(eigrp_bandwidth_t bandwidth) +{ + eigrp_bandwidth_t scaled = EIGRP_BANDWIDTH_MAX; + + if (bandwidth != EIGRP_BANDWIDTH_MAX) { + scaled = (EIGRP_CLASSIC_SCALER * EIGRP_BANDWIDTH_SCALER); + scaled = scaled / bandwidth; + + scaled = scaled ? scaled : EIGRP_BANDWIDTH_MIN; + } + + scaled = (scaled < EIGRP_METRIC_MAX) ? scaled : EIGRP_METRIC_MAX; + return (eigrp_scaled_t)scaled; +} + +eigrp_bandwidth_t eigrp_scaled_to_bandwidth(eigrp_scaled_t scaled) +{ + eigrp_bandwidth_t bandwidth = EIGRP_BANDWIDTH_MAX; + + if (scaled != EIGRP_CLASSIC_MAX) { + bandwidth = (EIGRP_CLASSIC_SCALER * EIGRP_BANDWIDTH_SCALER); + bandwidth = scaled * bandwidth; + bandwidth = (bandwidth < EIGRP_METRIC_MAX) + ? bandwidth + : EIGRP_BANDWIDTH_MAX; + } + + return bandwidth; +} + +eigrp_scaled_t eigrp_delay_to_scaled(eigrp_delay_t delay) +{ + delay = delay ? delay : EIGRP_DELAY_MIN; + return delay * EIGRP_CLASSIC_SCALER; +} + +eigrp_delay_t eigrp_scaled_to_delay(eigrp_scaled_t scaled) +{ + scaled = scaled / EIGRP_CLASSIC_SCALER; + scaled = scaled ? scaled : EIGRP_DELAY_MIN; + + return scaled; +} + +eigrp_metric_t eigrp_calculate_metrics(struct eigrp *eigrp, + struct eigrp_metrics metric) +{ + eigrp_metric_t composite = 0; + + if (metric.delay == EIGRP_MAX_METRIC) + return EIGRP_METRIC_MAX; + + /* + * EIGRP Composite = + * {K1*BW+[(K2*BW)/(256-load)]+(K3*delay)}*{K5/(reliability+K4)} + */ + + if (eigrp->k_values[0]) + composite += (eigrp->k_values[0] * metric.bandwidth); + if (eigrp->k_values[1]) + composite += ((eigrp->k_values[1] * metric.bandwidth) + / (256 - metric.load)); + if (eigrp->k_values[2]) + composite += (eigrp->k_values[2] * metric.delay); + if (eigrp->k_values[3] && !eigrp->k_values[4]) + composite *= eigrp->k_values[3]; + if (!eigrp->k_values[3] && eigrp->k_values[4]) + composite *= (eigrp->k_values[4] / metric.reliability); + if (eigrp->k_values[3] && eigrp->k_values[4]) + composite *= ((eigrp->k_values[4] / metric.reliability) + + eigrp->k_values[3]); + + composite = + (composite <= EIGRP_METRIC_MAX) ? composite : EIGRP_METRIC_MAX; + + return composite; +} + +eigrp_metric_t +eigrp_calculate_total_metrics(struct eigrp *eigrp, + struct eigrp_route_descriptor *entry) +{ + struct eigrp_interface *ei = entry->ei; + eigrp_delay_t temp_delay; + eigrp_bandwidth_t bw; + + entry->total_metric = entry->reported_metric; + temp_delay = entry->total_metric.delay + + eigrp_delay_to_scaled(ei->params.delay); + + entry->total_metric.delay = temp_delay > EIGRP_METRIC_MAX_CLASSIC + ? EIGRP_METRIC_MAX_CLASSIC + : temp_delay; + + bw = eigrp_bandwidth_to_scaled(ei->params.bandwidth); + entry->total_metric.bandwidth = entry->total_metric.bandwidth > bw + ? bw + : entry->total_metric.bandwidth; + + return eigrp_calculate_metrics(eigrp, entry->total_metric); +} + +bool eigrp_metrics_is_same(struct eigrp_metrics metric1, + struct eigrp_metrics metric2) +{ + if ((metric1.bandwidth == metric2.bandwidth) + && (metric1.delay == metric2.delay) + && (metric1.hop_count == metric2.hop_count) + && (metric1.load == metric2.load) + && (metric1.reliability == metric2.reliability) + && (metric1.mtu[0] == metric2.mtu[0]) + && (metric1.mtu[1] == metric2.mtu[1]) + && (metric1.mtu[2] == metric2.mtu[2])) { + return true; + } + + return false; /* if different */ +} diff --git a/eigrpd/eigrp_metric.h b/eigrpd/eigrp_metric.h new file mode 100644 index 0000000000..8e9cd66747 --- /dev/null +++ b/eigrpd/eigrp_metric.h @@ -0,0 +1,63 @@ +/* + * EIGRP Metric Math Functions. + * Copyright (C) 2013-2016 + * Authors: + * Donnie Savage + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _ZEBRA_EIGRP_METRIC_H_ +#define _ZEBRA_EIGRP_METRIC_H_ + +/* Constants */ +#define EIGRP_BANDWIDTH_MIN 0x1ull /* 1 */ +#define EIGRP_BANDWIDTH_SCALER 10000000ull /* Inversion value */ +#define EIGRP_BANDWIDTH_MAX 0xffffffffffffffffull /* 1.84467441x10^19 */ + +#define EIGRP_DELAY_MIN 0x1ull /* 1 */ +#define EIGRP_DELAY_PICO 1000000ull +#define EIGRP_DELAY_MAX 0xffffffffffffffffull /* 1.84467441x10^19 */ + +#define EIGRP_MAX_LOAD 256 +#define EIGRP_MAX_HOPS 100 + +#define EIGRP_INACCESSIBLE 0xFFFFFFFFFFFFFFFFull + +#define EIGRP_METRIC_MAX 0xffffffffffffffffull /* 1.84467441x10^19 */ +#define EIGRP_METRIC_MAX_CLASSIC 0xffffffff +#define EIGRP_METRIC_SCALER 65536 /* CLASSIC to WIDE conversion */ + +#define EIGRP_CLASSIC_MAX 0xffffffff /* 4294967295 */ +#define EIGRP_CLASSIC_SCALER 256 /* IGRP to EIGRP conversion */ + + +/* Prototypes */ +extern eigrp_scaled_t eigrp_bandwidth_to_scaled(eigrp_bandwidth_t bw); +extern eigrp_bandwidth_t eigrp_scaled_to_bandwidth(eigrp_scaled_t scale); +extern eigrp_scaled_t eigrp_delay_to_scaled(eigrp_delay_t delay); +extern eigrp_delay_t eigrp_scaled_to_delay(eigrp_scaled_t scale); + +extern eigrp_metric_t eigrp_calculate_metrics(struct eigrp *eigrp, + struct eigrp_metrics metric); +extern eigrp_metric_t +eigrp_calculate_total_metrics(struct eigrp *eigrp, + struct eigrp_route_descriptor *rd); +extern bool eigrp_metrics_is_same(struct eigrp_metrics m1, + struct eigrp_metrics m2); + +#endif /* _ZEBRA_EIGRP_METRIC_H_ */ diff --git a/eigrpd/eigrp_neighbor.c b/eigrpd/eigrp_neighbor.c index 2d5bb0a7d1..1da2f7a108 100644 --- a/eigrpd/eigrp_neighbor.c +++ b/eigrpd/eigrp_neighbor.c @@ -343,7 +343,7 @@ void eigrp_nbr_hard_restart(struct eigrp_neighbor *nbr, struct vty *vty) eigrp_nbr_delete(nbr); } -int eigrp_nbr_split_horizon_check(struct eigrp_nexthop_entry *ne, +int eigrp_nbr_split_horizon_check(struct eigrp_route_descriptor *ne, struct eigrp_interface *ei) { if (ne->distance == EIGRP_MAX_METRIC) diff --git a/eigrpd/eigrp_neighbor.h b/eigrpd/eigrp_neighbor.h index 1c308fa981..80ab1eded5 100644 --- a/eigrpd/eigrp_neighbor.h +++ b/eigrpd/eigrp_neighbor.h @@ -54,6 +54,6 @@ extern struct eigrp_neighbor * eigrp_nbr_lookup_by_addr_process(struct eigrp *eigrp, struct in_addr addr); extern void eigrp_nbr_hard_restart(struct eigrp_neighbor *nbr, struct vty *vty); -extern int eigrp_nbr_split_horizon_check(struct eigrp_nexthop_entry *ne, +extern int eigrp_nbr_split_horizon_check(struct eigrp_route_descriptor *ne, struct eigrp_interface *ei); #endif /* _ZEBRA_EIGRP_NEIGHBOR_H */ diff --git a/eigrpd/eigrp_network.c b/eigrpd/eigrp_network.c index 51b4998959..69dcc20253 100644 --- a/eigrpd/eigrp_network.c +++ b/eigrpd/eigrp_network.c @@ -346,76 +346,6 @@ int eigrp_network_unset(struct eigrp *eigrp, struct prefix *p) return 1; } -uint32_t eigrp_calculate_metrics(struct eigrp *eigrp, - struct eigrp_metrics metric) -{ - uint64_t temp_metric; - temp_metric = 0; - - if (metric.delay == EIGRP_MAX_METRIC) - return EIGRP_MAX_METRIC; - - // EIGRP Metric = - // {K1*BW+[(K2*BW)/(256-load)]+(K3*delay)}*{K5/(reliability+K4)} - - if (eigrp->k_values[0]) - temp_metric += (eigrp->k_values[0] * metric.bandwidth); - if (eigrp->k_values[1]) - temp_metric += ((eigrp->k_values[1] * metric.bandwidth) - / (256 - metric.load)); - if (eigrp->k_values[2]) - temp_metric += (eigrp->k_values[2] * metric.delay); - if (eigrp->k_values[3] && !eigrp->k_values[4]) - temp_metric *= eigrp->k_values[3]; - if (!eigrp->k_values[3] && eigrp->k_values[4]) - temp_metric *= (eigrp->k_values[4] / metric.reliability); - if (eigrp->k_values[3] && eigrp->k_values[4]) - temp_metric *= ((eigrp->k_values[4] / metric.reliability) - + eigrp->k_values[3]); - - if (temp_metric <= EIGRP_MAX_METRIC) - return (uint32_t)temp_metric; - else - return EIGRP_MAX_METRIC; -} - -uint32_t eigrp_calculate_total_metrics(struct eigrp *eigrp, - struct eigrp_nexthop_entry *entry) -{ - struct eigrp_interface *ei = entry->ei; - - entry->total_metric = entry->reported_metric; - uint64_t temp_delay = - (uint64_t)entry->total_metric.delay - + (uint64_t)eigrp_delay_to_scaled(ei->params.delay); - entry->total_metric.delay = temp_delay > EIGRP_MAX_METRIC - ? EIGRP_MAX_METRIC - : (uint32_t)temp_delay; - - uint32_t bw = eigrp_bandwidth_to_scaled(ei->params.bandwidth); - entry->total_metric.bandwidth = entry->total_metric.bandwidth > bw - ? bw - : entry->total_metric.bandwidth; - - return eigrp_calculate_metrics(eigrp, entry->total_metric); -} - -uint8_t eigrp_metrics_is_same(struct eigrp_metrics metric1, - struct eigrp_metrics metric2) -{ - if ((metric1.bandwidth == metric2.bandwidth) - && (metric1.delay == metric2.delay) - && (metric1.hop_count == metric2.hop_count) - && (metric1.load == metric2.load) - && (metric1.reliability == metric2.reliability) - && (metric1.mtu[0] == metric2.mtu[0]) - && (metric1.mtu[1] == metric2.mtu[1]) - && (metric1.mtu[2] == metric2.mtu[2])) - return 1; - - return 0; // if different -} - void eigrp_external_routes_refresh(struct eigrp *eigrp, int type) { } diff --git a/eigrpd/eigrp_network.h b/eigrpd/eigrp_network.h index 7839fc946b..eeb32ba356 100644 --- a/eigrpd/eigrp_network.h +++ b/eigrpd/eigrp_network.h @@ -43,11 +43,6 @@ extern int eigrp_if_drop_allspfrouters(struct eigrp *top, struct prefix *p, unsigned int ifindex); extern void eigrp_adjust_sndbuflen(struct eigrp *, unsigned int); -extern uint32_t eigrp_calculate_metrics(struct eigrp *, struct eigrp_metrics); -extern uint32_t eigrp_calculate_total_metrics(struct eigrp *, - struct eigrp_nexthop_entry *); -extern uint8_t eigrp_metrics_is_same(struct eigrp_metrics, - struct eigrp_metrics); extern void eigrp_external_routes_refresh(struct eigrp *, int); #endif /* EIGRP_NETWORK_H_ */ diff --git a/eigrpd/eigrp_northbound.c b/eigrpd/eigrp_northbound.c index 5b87f72640..482667f633 100644 --- a/eigrpd/eigrp_northbound.c +++ b/eigrpd/eigrp_northbound.c @@ -34,6 +34,7 @@ #include "eigrp_interface.h" #include "eigrp_network.h" #include "eigrp_zebra.h" +#include "eigrp_cli.h" /* Helper functions. */ static void redistribute_get_metrics(const struct lyd_node *dnode, diff --git a/eigrpd/eigrp_packet.c b/eigrpd/eigrp_packet.c index f5f6ab5dff..252cd647a2 100644 --- a/eigrpd/eigrp_packet.c +++ b/eigrpd/eigrp_packet.c @@ -1144,7 +1144,7 @@ struct TLV_IPv4_Internal_type *eigrp_read_ipv4_tlv(struct stream *s) } uint16_t eigrp_add_internalTLV_to_stream(struct stream *s, - struct eigrp_prefix_entry *pe) + struct eigrp_prefix_descriptor *pe) { uint16_t length; diff --git a/eigrpd/eigrp_packet.h b/eigrpd/eigrp_packet.h index f354615fdb..cb69bc26b2 100644 --- a/eigrpd/eigrp_packet.h +++ b/eigrpd/eigrp_packet.h @@ -36,48 +36,51 @@ extern int eigrp_read(struct thread *); extern int eigrp_write(struct thread *); -extern struct eigrp_packet *eigrp_packet_new(size_t, struct eigrp_neighbor *); -extern struct eigrp_packet *eigrp_packet_duplicate(struct eigrp_packet *, - struct eigrp_neighbor *); -extern void eigrp_packet_free(struct eigrp_packet *); -extern void eigrp_packet_delete(struct eigrp_interface *); -extern void eigrp_packet_header_init(int, struct eigrp *, struct stream *, - uint32_t, uint32_t, uint32_t); -extern void eigrp_packet_checksum(struct eigrp_interface *, struct stream *, - uint16_t); +extern struct eigrp_packet *eigrp_packet_new(size_t size, + struct eigrp_neighbor *nbr); +extern struct eigrp_packet *eigrp_packet_duplicate(struct eigrp_packet *old, + struct eigrp_neighbor *nbr); +extern void eigrp_packet_free(struct eigrp_packet *ep); +extern void eigrp_packet_delete(struct eigrp_interface *ei); +extern void eigrp_packet_header_init(int type, struct eigrp *eigrp, + struct stream *s, uint32_t flags, + uint32_t sequence, uint32_t ack); +extern void eigrp_packet_checksum(struct eigrp_interface *ei, struct stream *s, + uint16_t length); extern struct eigrp_fifo *eigrp_fifo_new(void); -extern struct eigrp_packet *eigrp_fifo_next(struct eigrp_fifo *); -extern struct eigrp_packet *eigrp_fifo_pop(struct eigrp_fifo *); -extern void eigrp_fifo_push(struct eigrp_fifo *, struct eigrp_packet *); -extern void eigrp_fifo_free(struct eigrp_fifo *); -extern void eigrp_fifo_reset(struct eigrp_fifo *); - -extern void eigrp_send_packet_reliably(struct eigrp_neighbor *); - -extern struct TLV_IPv4_Internal_type *eigrp_read_ipv4_tlv(struct stream *); -extern uint16_t eigrp_add_internalTLV_to_stream(struct stream *, - struct eigrp_prefix_entry *); -extern uint16_t eigrp_add_authTLV_MD5_to_stream(struct stream *, - struct eigrp_interface *); -extern uint16_t eigrp_add_authTLV_SHA256_to_stream(struct stream *, - struct eigrp_interface *); - -extern int eigrp_unack_packet_retrans(struct thread *); -extern int eigrp_unack_multicast_packet_retrans(struct thread *); +extern struct eigrp_packet *eigrp_fifo_next(struct eigrp_fifo *fifo); +extern struct eigrp_packet *eigrp_fifo_pop(struct eigrp_fifo *fifo); +extern void eigrp_fifo_push(struct eigrp_fifo *fifo, struct eigrp_packet *ep); +extern void eigrp_fifo_free(struct eigrp_fifo *fifo); +extern void eigrp_fifo_reset(struct eigrp_fifo *fifo); + +extern void eigrp_send_packet_reliably(struct eigrp_neighbor *nbr); + +extern struct TLV_IPv4_Internal_type *eigrp_read_ipv4_tlv(struct stream *s); +extern uint16_t +eigrp_add_internalTLV_to_stream(struct stream *s, + struct eigrp_prefix_descriptor *pe); +extern uint16_t eigrp_add_authTLV_MD5_to_stream(struct stream *s, + struct eigrp_interface *ei); +extern uint16_t eigrp_add_authTLV_SHA256_to_stream(struct stream *s, + struct eigrp_interface *ei); + +extern int eigrp_unack_packet_retrans(struct thread *thread); +extern int eigrp_unack_multicast_packet_retrans(struct thread *thread); /* * untill there is reason to have their own header, these externs are found in * eigrp_hello.c */ extern void eigrp_sw_version_initialize(void); -extern void eigrp_hello_send(struct eigrp_interface *, uint8_t, - struct in_addr *); -extern void eigrp_hello_send_ack(struct eigrp_neighbor *); -extern void eigrp_hello_receive(struct eigrp *, struct ip *, - struct eigrp_header *, struct stream *, - struct eigrp_interface *, int); -extern int eigrp_hello_timer(struct thread *); +extern void eigrp_hello_send(struct eigrp_interface *ei, uint8_t flags, + struct in_addr *nbr_addr); +extern void eigrp_hello_send_ack(struct eigrp_neighbor *nbr); +extern void eigrp_hello_receive(struct eigrp *eigrp, struct ip *iph, + struct eigrp_header *eigrph, struct stream *s, + struct eigrp_interface *ei, int size); +extern int eigrp_hello_timer(struct thread *thread); /* * These externs are found in eigrp_update.c @@ -85,76 +88,83 @@ extern int eigrp_hello_timer(struct thread *); extern bool eigrp_update_prefix_apply(struct eigrp *eigrp, struct eigrp_interface *ei, int in, struct prefix *prefix); -extern void eigrp_update_send(struct eigrp_interface *); -extern void eigrp_update_receive(struct eigrp *, struct ip *, - struct eigrp_header *, struct stream *, - struct eigrp_interface *, int); -extern void eigrp_update_send_all(struct eigrp *, struct eigrp_interface *); -extern void eigrp_update_send_init(struct eigrp_neighbor *); -extern void eigrp_update_send_EOT(struct eigrp_neighbor *); -extern int eigrp_update_send_GR_thread(struct thread *); -extern void eigrp_update_send_GR(struct eigrp_neighbor *, enum GR_type, - struct vty *); -extern void eigrp_update_send_interface_GR(struct eigrp_interface *, - enum GR_type, struct vty *); -extern void eigrp_update_send_process_GR(struct eigrp *, enum GR_type, - struct vty *); +extern void eigrp_update_send(struct eigrp_interface *ei); +extern void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, + struct eigrp_header *eigrph, struct stream *s, + struct eigrp_interface *ei, int size); +extern void eigrp_update_send_all(struct eigrp *eigrp, + struct eigrp_interface *exception); +extern void eigrp_update_send_init(struct eigrp_neighbor *nbr); +extern void eigrp_update_send_EOT(struct eigrp_neighbor *nbr); +extern int eigrp_update_send_GR_thread(struct thread *thread); +extern void eigrp_update_send_GR(struct eigrp_neighbor *nbr, + enum GR_type gr_type, struct vty *vty); +extern void eigrp_update_send_interface_GR(struct eigrp_interface *ei, + enum GR_type gr_type, + struct vty *vty); +extern void eigrp_update_send_process_GR(struct eigrp *eigrp, + enum GR_type gr_type, struct vty *vty); /* * These externs are found in eigrp_query.c */ -extern void eigrp_send_query(struct eigrp_interface *); -extern void eigrp_query_receive(struct eigrp *, struct ip *, - struct eigrp_header *, struct stream *, - struct eigrp_interface *, int); -extern uint32_t eigrp_query_send_all(struct eigrp *); +extern void eigrp_send_query(struct eigrp_interface *ei); +extern void eigrp_query_receive(struct eigrp *eigrp, struct ip *iph, + struct eigrp_header *eigrph, struct stream *s, + struct eigrp_interface *ei, int size); +extern uint32_t eigrp_query_send_all(struct eigrp *eigrp); /* * These externs are found in eigrp_reply.c */ -extern void eigrp_send_reply(struct eigrp_neighbor *, - struct eigrp_prefix_entry *); -extern void eigrp_reply_receive(struct eigrp *, struct ip *, - struct eigrp_header *, struct stream *, - struct eigrp_interface *, int); +extern void eigrp_send_reply(struct eigrp_neighbor *nbr, + struct eigrp_prefix_descriptor *pe); +extern void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph, + struct eigrp_header *eigrph, struct stream *s, + struct eigrp_interface *ei, int size); /* * These externs are found in eigrp_siaquery.c */ -extern void eigrp_send_siaquery(struct eigrp_neighbor *, - struct eigrp_prefix_entry *); -extern void eigrp_siaquery_receive(struct eigrp *, struct ip *, - struct eigrp_header *, struct stream *, - struct eigrp_interface *, int); +extern void eigrp_send_siaquery(struct eigrp_neighbor *nbr, + struct eigrp_prefix_descriptor *pe); +extern void eigrp_siaquery_receive(struct eigrp *eigrp, struct ip *iph, + struct eigrp_header *eigrph, + struct stream *s, struct eigrp_interface *ei, + int size); /* * These externs are found in eigrp_siareply.c */ -extern void eigrp_send_siareply(struct eigrp_neighbor *, - struct eigrp_prefix_entry *); -extern void eigrp_siareply_receive(struct eigrp *, struct ip *, - struct eigrp_header *, struct stream *, - struct eigrp_interface *, int); +extern void eigrp_send_siareply(struct eigrp_neighbor *nbr, + struct eigrp_prefix_descriptor *pe); +extern void eigrp_siareply_receive(struct eigrp *eigrp, struct ip *iph, + struct eigrp_header *eigrph, + struct stream *s, struct eigrp_interface *ei, + int size); extern struct TLV_MD5_Authentication_Type *eigrp_authTLV_MD5_new(void); -extern void eigrp_authTLV_MD5_free(struct TLV_MD5_Authentication_Type *); +extern void eigrp_authTLV_MD5_free(struct TLV_MD5_Authentication_Type *authTLV); extern struct TLV_SHA256_Authentication_Type *eigrp_authTLV_SHA256_new(void); -extern void eigrp_authTLV_SHA256_free(struct TLV_SHA256_Authentication_Type *); - -extern int eigrp_make_md5_digest(struct eigrp_interface *, struct stream *, - uint8_t); -extern int eigrp_check_md5_digest(struct stream *, - struct TLV_MD5_Authentication_Type *, - struct eigrp_neighbor *, uint8_t); -extern int eigrp_make_sha256_digest(struct eigrp_interface *, struct stream *, - uint8_t); -extern int eigrp_check_sha256_digest(struct stream *, - struct TLV_SHA256_Authentication_Type *, - struct eigrp_neighbor *, uint8_t); - - -extern void eigrp_IPv4_InternalTLV_free(struct TLV_IPv4_Internal_type *); +extern void +eigrp_authTLV_SHA256_free(struct TLV_SHA256_Authentication_Type *authTLV); + +extern int eigrp_make_md5_digest(struct eigrp_interface *ei, struct stream *s, + uint8_t flags); +extern int eigrp_check_md5_digest(struct stream *s, + struct TLV_MD5_Authentication_Type *authTLV, + struct eigrp_neighbor *nbr, uint8_t flags); +extern int eigrp_make_sha256_digest(struct eigrp_interface *ei, + struct stream *s, uint8_t flags); +extern int +eigrp_check_sha256_digest(struct stream *s, + struct TLV_SHA256_Authentication_Type *authTLV, + struct eigrp_neighbor *nbr, uint8_t flags); + + +extern void +eigrp_IPv4_InternalTLV_free(struct TLV_IPv4_Internal_type *IPv4_InternalTLV); extern struct TLV_Sequence_Type *eigrp_SequenceTLV_new(void); diff --git a/eigrpd/eigrp_query.c b/eigrpd/eigrp_query.c index 84dcf5e2d5..0ab7b59dbb 100644 --- a/eigrpd/eigrp_query.c +++ b/eigrpd/eigrp_query.c @@ -58,7 +58,7 @@ uint32_t eigrp_query_send_all(struct eigrp *eigrp) { struct eigrp_interface *iface; struct listnode *node, *node2, *nnode2; - struct eigrp_prefix_entry *pe; + struct eigrp_prefix_descriptor *pe; uint32_t counter; if (eigrp == NULL) { @@ -118,7 +118,7 @@ void eigrp_query_receive(struct eigrp *eigrp, struct ip *iph, dest_addr.family = AF_INET; dest_addr.u.prefix4 = tlv->destination; dest_addr.prefixlen = tlv->prefix_length; - struct eigrp_prefix_entry *dest = + struct eigrp_prefix_descriptor *dest = eigrp_topology_table_lookup_ipv4( eigrp->topology_table, &dest_addr); @@ -126,9 +126,9 @@ void eigrp_query_receive(struct eigrp *eigrp, struct ip *iph, * know)*/ if (dest != NULL) { struct eigrp_fsm_action_message msg; - struct eigrp_nexthop_entry *entry = - eigrp_prefix_entry_lookup(dest->entries, - nbr); + struct eigrp_route_descriptor *entry = + eigrp_route_descriptor_lookup( + dest->entries, nbr); msg.packet_type = EIGRP_OPC_QUERY; msg.eigrp = eigrp; msg.data_type = EIGRP_INT; @@ -164,7 +164,7 @@ void eigrp_send_query(struct eigrp_interface *ei) uint16_t length = EIGRP_HEADER_LEN; struct listnode *node, *nnode, *node2, *nnode2; struct eigrp_neighbor *nbr; - struct eigrp_prefix_entry *pe; + struct eigrp_prefix_descriptor *pe; bool has_tlv = false; bool new_packet = true; uint16_t eigrp_mtu = EIGRP_PACKET_MTU(ei->ifp->mtu); diff --git a/eigrpd/eigrp_reply.c b/eigrpd/eigrp_reply.c index 26bb27d7ac..d16482173c 100644 --- a/eigrpd/eigrp_reply.c +++ b/eigrpd/eigrp_reply.c @@ -61,20 +61,21 @@ #include "eigrpd/eigrp_memory.h" #include "eigrpd/eigrp_errors.h" -void eigrp_send_reply(struct eigrp_neighbor *nbr, struct eigrp_prefix_entry *pe) +void eigrp_send_reply(struct eigrp_neighbor *nbr, + struct eigrp_prefix_descriptor *pe) { struct eigrp_packet *ep; uint16_t length = EIGRP_HEADER_LEN; struct eigrp_interface *ei = nbr->ei; struct eigrp *eigrp = ei->eigrp; - struct eigrp_prefix_entry *pe2; + struct eigrp_prefix_descriptor *pe2; // TODO: Work in progress /* Filtering */ /* get list from eigrp process */ - pe2 = XCALLOC(MTYPE_EIGRP_PREFIX_ENTRY, - sizeof(struct eigrp_prefix_entry)); - memcpy(pe2, pe, sizeof(struct eigrp_prefix_entry)); + pe2 = XCALLOC(MTYPE_EIGRP_PREFIX_DESCRIPTOR, + sizeof(struct eigrp_prefix_descriptor)); + memcpy(pe2, pe, sizeof(struct eigrp_prefix_descriptor)); if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_OUT, pe2->destination)) { @@ -122,7 +123,7 @@ void eigrp_send_reply(struct eigrp_neighbor *nbr, struct eigrp_prefix_entry *pe) eigrp_send_packet_reliably(nbr); } - XFREE(MTYPE_EIGRP_PREFIX_ENTRY, pe2); + XFREE(MTYPE_EIGRP_PREFIX_DESCRIPTOR, pe2); } /*EIGRP REPLY read function*/ @@ -161,7 +162,7 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph, dest_addr.family = AF_INET; dest_addr.u.prefix4 = tlv->destination; dest_addr.prefixlen = tlv->prefix_length; - struct eigrp_prefix_entry *dest = + struct eigrp_prefix_descriptor *dest = eigrp_topology_table_lookup_ipv4(eigrp->topology_table, &dest_addr); /* @@ -177,8 +178,8 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph, } struct eigrp_fsm_action_message msg; - struct eigrp_nexthop_entry *entry = - eigrp_prefix_entry_lookup(dest->entries, nbr); + struct eigrp_route_descriptor *entry = + eigrp_route_descriptor_lookup(dest->entries, nbr); if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_IN, &dest_addr)) { diff --git a/eigrpd/eigrp_routemap.c b/eigrpd/eigrp_routemap.c index e15f777954..5183e645e5 100644 --- a/eigrpd/eigrp_routemap.c +++ b/eigrpd/eigrp_routemap.c @@ -265,8 +265,8 @@ route_match_metric(void *rule, struct prefix *prefix, route_map_object_t type, // uint32_t *metric; // uint32_t check; // struct rip_info *rinfo; - // struct eigrp_nexthop_entry *te; - // struct eigrp_prefix_entry *pe; + // struct eigrp_route_descriptor *te; + // struct eigrp_prefix_descriptor *pe; // struct listnode *node, *node2, *nnode, *nnode2; // struct eigrp *e; // diff --git a/eigrpd/eigrp_siaquery.c b/eigrpd/eigrp_siaquery.c index ff38325465..027700fe11 100644 --- a/eigrpd/eigrp_siaquery.c +++ b/eigrpd/eigrp_siaquery.c @@ -87,7 +87,7 @@ void eigrp_siaquery_receive(struct eigrp *eigrp, struct ip *iph, dest_addr.family = AFI_IP; dest_addr.u.prefix4 = tlv->destination; dest_addr.prefixlen = tlv->prefix_length; - struct eigrp_prefix_entry *dest = + struct eigrp_prefix_descriptor *dest = eigrp_topology_table_lookup_ipv4( eigrp->topology_table, &dest_addr); @@ -95,9 +95,9 @@ void eigrp_siaquery_receive(struct eigrp *eigrp, struct ip *iph, * know)*/ if (dest != NULL) { struct eigrp_fsm_action_message msg; - struct eigrp_nexthop_entry *entry = - eigrp_prefix_entry_lookup(dest->entries, - nbr); + struct eigrp_route_descriptor *entry = + eigrp_route_descriptor_lookup( + dest->entries, nbr); msg.packet_type = EIGRP_OPC_SIAQUERY; msg.eigrp = eigrp; msg.data_type = EIGRP_INT; @@ -114,7 +114,7 @@ void eigrp_siaquery_receive(struct eigrp *eigrp, struct ip *iph, } void eigrp_send_siaquery(struct eigrp_neighbor *nbr, - struct eigrp_prefix_entry *pe) + struct eigrp_prefix_descriptor *pe) { struct eigrp_packet *ep; uint16_t length = EIGRP_HEADER_LEN; diff --git a/eigrpd/eigrp_siareply.c b/eigrpd/eigrp_siareply.c index d3dd123f90..590b224d68 100644 --- a/eigrpd/eigrp_siareply.c +++ b/eigrpd/eigrp_siareply.c @@ -86,7 +86,7 @@ void eigrp_siareply_receive(struct eigrp *eigrp, struct ip *iph, dest_addr.family = AFI_IP; dest_addr.u.prefix4 = tlv->destination; dest_addr.prefixlen = tlv->prefix_length; - struct eigrp_prefix_entry *dest = + struct eigrp_prefix_descriptor *dest = eigrp_topology_table_lookup_ipv4( eigrp->topology_table, &dest_addr); @@ -94,9 +94,9 @@ void eigrp_siareply_receive(struct eigrp *eigrp, struct ip *iph, * know)*/ if (dest != NULL) { struct eigrp_fsm_action_message msg; - struct eigrp_nexthop_entry *entry = - eigrp_prefix_entry_lookup(dest->entries, - nbr); + struct eigrp_route_descriptor *entry = + eigrp_route_descriptor_lookup( + dest->entries, nbr); msg.packet_type = EIGRP_OPC_SIAQUERY; msg.eigrp = eigrp; msg.data_type = EIGRP_INT; @@ -113,7 +113,7 @@ void eigrp_siareply_receive(struct eigrp *eigrp, struct ip *iph, } void eigrp_send_siareply(struct eigrp_neighbor *nbr, - struct eigrp_prefix_entry *pe) + struct eigrp_prefix_descriptor *pe) { struct eigrp_packet *ep; uint16_t length = EIGRP_HEADER_LEN; diff --git a/eigrpd/eigrp_structs.h b/eigrpd/eigrp_structs.h index 82bddaaae3..cddab57dd5 100644 --- a/eigrpd/eigrp_structs.h +++ b/eigrpd/eigrp_structs.h @@ -37,26 +37,6 @@ #include "eigrpd/eigrp_const.h" #include "eigrpd/eigrp_macros.h" -/* EIGRP master for system wide configuration and variables. */ -struct eigrp_master { - /* EIGRP instance. */ - struct list *eigrp; - - /* EIGRP thread master. */ - struct thread_master *master; - - /* Zebra interface list. */ - struct list *iflist; - - /* EIGRP start time. */ - time_t start_time; - - /* Various EIGRP global configuration. */ - uint8_t options; - -#define EIGRP_MASTER_SHUTDOWN (1 << 0) /* deferred-shutdown */ -}; - struct eigrp_metrics { uint32_t delay; uint32_t bandwidth; @@ -68,6 +48,16 @@ struct eigrp_metrics { uint8_t flags; }; +struct eigrp_extdata { + uint32_t orig; + uint32_t as; + uint32_t tag; + uint32_t metric; + uint16_t reserved; + uint8_t protocol; + uint8_t flags; +}; + struct eigrp { vrf_id_t vrf_id; @@ -450,7 +440,7 @@ enum GR_type { EIGRP_GR_MANUAL, EIGRP_GR_FILTER }; //--------------------------------------------------------------------------------------------------------------------------------------------- /* EIGRP Topology table node structure */ -struct eigrp_prefix_entry { +struct eigrp_prefix_descriptor { struct list *entries, *rij; uint32_t fdistance; // FD uint32_t rdistance; // RD @@ -473,8 +463,14 @@ struct eigrp_prefix_entry { }; /* EIGRP Topology table record structure */ -struct eigrp_nexthop_entry { - struct eigrp_prefix_entry *prefix; +struct eigrp_route_descriptor { + uint16_t type; + uint16_t afi; + + struct eigrp_prefix_descriptor *prefix; + struct eigrp_neighbor *adv_router; + struct in_addr nexthop; + uint32_t reported_distance; // distance reported by neighbor uint32_t distance; // sum of reported distance and link cost to // advertised neighbor @@ -482,7 +478,9 @@ struct eigrp_nexthop_entry { struct eigrp_metrics reported_metric; struct eigrp_metrics total_metric; - struct eigrp_neighbor *adv_router; // ip address of advertising neighbor + struct eigrp_metrics metric; + struct eigrp_extdata extdata; + uint8_t flags; // used for marking successor and FS struct eigrp_interface *ei; // pointer for case of connected entry @@ -501,8 +499,8 @@ struct eigrp_fsm_action_message { uint8_t packet_type; // UPDATE, QUERY, SIAQUERY, SIAREPLY struct eigrp *eigrp; // which thread sent mesg struct eigrp_neighbor *adv_router; // advertising neighbor - struct eigrp_nexthop_entry *entry; - struct eigrp_prefix_entry *prefix; + struct eigrp_route_descriptor *entry; + struct eigrp_prefix_descriptor *prefix; msg_data_t data_type; // internal or external tlv type struct eigrp_metrics metrics; enum metric_change change; diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index 2dbee16694..1b7e9fc15b 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -39,6 +39,7 @@ #include "vty.h" #include "lib_errors.h" +#include "eigrpd/eigrp_types.h" #include "eigrpd/eigrp_structs.h" #include "eigrpd/eigrpd.h" #include "eigrpd/eigrp_interface.h" @@ -51,9 +52,10 @@ #include "eigrpd/eigrp_topology.h" #include "eigrpd/eigrp_fsm.h" #include "eigrpd/eigrp_memory.h" +#include "eigrpd/eigrp_metric.h" -static int eigrp_nexthop_entry_cmp(struct eigrp_nexthop_entry *, - struct eigrp_nexthop_entry *); +static int eigrp_route_descriptor_cmp(struct eigrp_route_descriptor *rd1, + struct eigrp_route_descriptor *rd2); /* * Returns linkedlist used as topology table @@ -70,14 +72,14 @@ struct route_table *eigrp_topology_new(void) * Returns new created toplogy node * cmp - assigned function for comparing topology entry */ -struct eigrp_prefix_entry *eigrp_prefix_entry_new(void) +struct eigrp_prefix_descriptor *eigrp_prefix_descriptor_new(void) { - struct eigrp_prefix_entry *new; - new = XCALLOC(MTYPE_EIGRP_PREFIX_ENTRY, - sizeof(struct eigrp_prefix_entry)); + struct eigrp_prefix_descriptor *new; + new = XCALLOC(MTYPE_EIGRP_PREFIX_DESCRIPTOR, + sizeof(struct eigrp_prefix_descriptor)); new->entries = list_new(); new->rij = list_new(); - new->entries->cmp = (int (*)(void *, void *))eigrp_nexthop_entry_cmp; + new->entries->cmp = (int (*)(void *, void *))eigrp_route_descriptor_cmp; new->distance = new->fdistance = new->rdistance = EIGRP_MAX_METRIC; new->destination = NULL; @@ -87,8 +89,8 @@ struct eigrp_prefix_entry *eigrp_prefix_entry_new(void) /* * Topology entry comparison */ -static int eigrp_nexthop_entry_cmp(struct eigrp_nexthop_entry *entry1, - struct eigrp_nexthop_entry *entry2) +static int eigrp_route_descriptor_cmp(struct eigrp_route_descriptor *entry1, + struct eigrp_route_descriptor *entry2) { if (entry1->distance < entry2->distance) return -1; @@ -102,12 +104,12 @@ static int eigrp_nexthop_entry_cmp(struct eigrp_nexthop_entry *entry1, * Returns new topology entry */ -struct eigrp_nexthop_entry *eigrp_nexthop_entry_new(void) +struct eigrp_route_descriptor *eigrp_route_descriptor_new(void) { - struct eigrp_nexthop_entry *new; + struct eigrp_route_descriptor *new; - new = XCALLOC(MTYPE_EIGRP_NEXTHOP_ENTRY, - sizeof(struct eigrp_nexthop_entry)); + new = XCALLOC(MTYPE_EIGRP_ROUTE_DESCRIPTOR, + sizeof(struct eigrp_route_descriptor)); new->reported_distance = EIGRP_MAX_METRIC; new->distance = EIGRP_MAX_METRIC; @@ -126,8 +128,8 @@ void eigrp_topology_free(struct eigrp *eigrp, struct route_table *table) /* * Adding topology node to topology table */ -void eigrp_prefix_entry_add(struct route_table *topology, - struct eigrp_prefix_entry *pe) +void eigrp_prefix_descriptor_add(struct route_table *topology, + struct eigrp_prefix_descriptor *pe) { struct route_node *rn; @@ -146,9 +148,9 @@ void eigrp_prefix_entry_add(struct route_table *topology, /* * Adding topology entry to topology node */ -void eigrp_nexthop_entry_add(struct eigrp *eigrp, - struct eigrp_prefix_entry *node, - struct eigrp_nexthop_entry *entry) +void eigrp_route_descriptor_add(struct eigrp *eigrp, + struct eigrp_prefix_descriptor *node, + struct eigrp_route_descriptor *entry) { struct list *l = list_new(); @@ -168,10 +170,11 @@ void eigrp_nexthop_entry_add(struct eigrp *eigrp, /* * Deleting topology node from topology table */ -void eigrp_prefix_entry_delete(struct eigrp *eigrp, struct route_table *table, - struct eigrp_prefix_entry *pe) +void eigrp_prefix_descriptor_delete(struct eigrp *eigrp, + struct route_table *table, + struct eigrp_prefix_descriptor *pe) { - struct eigrp_nexthop_entry *ne; + struct eigrp_route_descriptor *ne; struct listnode *node, *nnode; struct route_node *rn; @@ -189,7 +192,7 @@ void eigrp_prefix_entry_delete(struct eigrp *eigrp, struct route_table *table, listnode_delete(eigrp->topology_changes_internalIPV4, pe); for (ALL_LIST_ELEMENTS(pe->entries, node, nnode, ne)) - eigrp_nexthop_entry_delete(eigrp, pe, ne); + eigrp_route_descriptor_delete(eigrp, pe, ne); list_delete(&pe->entries); list_delete(&pe->rij); eigrp_zebra_route_delete(eigrp, pe->destination); @@ -198,20 +201,20 @@ void eigrp_prefix_entry_delete(struct eigrp *eigrp, struct route_table *table, rn->info = NULL; route_unlock_node(rn); // Lookup above route_unlock_node(rn); // Initial creation - XFREE(MTYPE_EIGRP_PREFIX_ENTRY, pe); + XFREE(MTYPE_EIGRP_PREFIX_DESCRIPTOR, pe); } /* * Deleting topology entry from topology node */ -void eigrp_nexthop_entry_delete(struct eigrp *eigrp, - struct eigrp_prefix_entry *node, - struct eigrp_nexthop_entry *entry) +void eigrp_route_descriptor_delete(struct eigrp *eigrp, + struct eigrp_prefix_descriptor *node, + struct eigrp_route_descriptor *entry) { if (listnode_lookup(node->entries, entry) != NULL) { listnode_delete(node->entries, entry); eigrp_zebra_route_delete(eigrp, node->destination); - XFREE(MTYPE_EIGRP_NEXTHOP_ENTRY, entry); + XFREE(MTYPE_EIGRP_ROUTE_DESCRIPTOR, entry); } } @@ -222,7 +225,7 @@ void eigrp_topology_delete_all(struct eigrp *eigrp, struct route_table *topology) { struct route_node *rn; - struct eigrp_prefix_entry *pe; + struct eigrp_prefix_descriptor *pe; for (rn = route_top(topology); rn; rn = route_next(rn)) { pe = rn->info; @@ -230,15 +233,15 @@ void eigrp_topology_delete_all(struct eigrp *eigrp, if (!pe) continue; - eigrp_prefix_entry_delete(eigrp, topology, pe); + eigrp_prefix_descriptor_delete(eigrp, topology, pe); } } -struct eigrp_prefix_entry * +struct eigrp_prefix_descriptor * eigrp_topology_table_lookup_ipv4(struct route_table *table, struct prefix *address) { - struct eigrp_prefix_entry *pe; + struct eigrp_prefix_descriptor *pe; struct route_node *rn; rn = route_node_lookup(table, address); @@ -259,14 +262,15 @@ eigrp_topology_table_lookup_ipv4(struct route_table *table, * That way we can clean up all the list_new and list_delete's * that we are doing. DBS */ -struct list *eigrp_topology_get_successor(struct eigrp_prefix_entry *table_node) +struct list * +eigrp_topology_get_successor(struct eigrp_prefix_descriptor *table_node) { struct list *successors = list_new(); - struct eigrp_nexthop_entry *data; + struct eigrp_route_descriptor *data; struct listnode *node1, *node2; for (ALL_LIST_ELEMENTS(table_node->entries, node1, node2, data)) { - if (data->flags & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG) { + if (data->flags & EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG) { listnode_add(successors, data); } } @@ -283,7 +287,7 @@ struct list *eigrp_topology_get_successor(struct eigrp_prefix_entry *table_node) } struct list * -eigrp_topology_get_successor_max(struct eigrp_prefix_entry *table_node, +eigrp_topology_get_successor_max(struct eigrp_prefix_descriptor *table_node, unsigned int maxpaths) { struct list *successors = eigrp_topology_get_successor(table_node); @@ -300,10 +304,10 @@ eigrp_topology_get_successor_max(struct eigrp_prefix_entry *table_node, return successors; } -struct eigrp_nexthop_entry * -eigrp_prefix_entry_lookup(struct list *entries, struct eigrp_neighbor *nbr) +struct eigrp_route_descriptor * +eigrp_route_descriptor_lookup(struct list *entries, struct eigrp_neighbor *nbr) { - struct eigrp_nexthop_entry *data; + struct eigrp_route_descriptor *data; struct listnode *node, *nnode; for (ALL_LIST_ELEMENTS(entries, node, nnode, data)) { if (data->adv_router == nbr) { @@ -319,8 +323,8 @@ struct list *eigrp_neighbor_prefixes_lookup(struct eigrp *eigrp, struct eigrp_neighbor *nbr) { struct listnode *node2, *node22; - struct eigrp_nexthop_entry *entry; - struct eigrp_prefix_entry *pe; + struct eigrp_route_descriptor *entry; + struct eigrp_prefix_descriptor *pe; struct route_node *rn; /* create new empty list for prefixes storage */ @@ -348,8 +352,8 @@ enum metric_change eigrp_topology_update_distance(struct eigrp_fsm_action_message *msg) { struct eigrp *eigrp = msg->eigrp; - struct eigrp_prefix_entry *prefix = msg->prefix; - struct eigrp_nexthop_entry *entry = msg->entry; + struct eigrp_prefix_descriptor *prefix = msg->prefix; + struct eigrp_route_descriptor *entry = msg->entry; enum metric_change change = METRIC_SAME; uint32_t new_reported_distance; @@ -413,7 +417,7 @@ distance_done: void eigrp_topology_update_all_node_flags(struct eigrp *eigrp) { - struct eigrp_prefix_entry *pe; + struct eigrp_prefix_descriptor *pe; struct route_node *rn; if (!eigrp) @@ -430,10 +434,10 @@ void eigrp_topology_update_all_node_flags(struct eigrp *eigrp) } void eigrp_topology_update_node_flags(struct eigrp *eigrp, - struct eigrp_prefix_entry *dest) + struct eigrp_prefix_descriptor *dest) { struct listnode *node; - struct eigrp_nexthop_entry *entry; + struct eigrp_route_descriptor *entry; for (ALL_LIST_ELEMENTS_RO(dest->entries, node, entry)) { if (entry->reported_distance < dest->fdistance) { @@ -444,29 +448,29 @@ void eigrp_topology_update_node_flags(struct eigrp *eigrp, && entry->distance != EIGRP_MAX_METRIC) { // is successor entry->flags |= - EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG; + EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG; entry->flags &= - ~EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG; + ~EIGRP_ROUTE_DESCRIPTOR_FSUCCESSOR_FLAG; } else { // is feasible successor only entry->flags |= - EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG; + EIGRP_ROUTE_DESCRIPTOR_FSUCCESSOR_FLAG; entry->flags &= - ~EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG; + ~EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG; } } else { - entry->flags &= ~EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG; - entry->flags &= ~EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG; + entry->flags &= ~EIGRP_ROUTE_DESCRIPTOR_FSUCCESSOR_FLAG; + entry->flags &= ~EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG; } } } void eigrp_update_routing_table(struct eigrp *eigrp, - struct eigrp_prefix_entry *prefix) + struct eigrp_prefix_descriptor *prefix) { struct list *successors; struct listnode *node; - struct eigrp_nexthop_entry *entry; + struct eigrp_route_descriptor *entry; successors = eigrp_topology_get_successor_max(prefix, eigrp->max_paths); @@ -474,13 +478,13 @@ void eigrp_update_routing_table(struct eigrp *eigrp, eigrp_zebra_route_add(eigrp, prefix->destination, successors, prefix->fdistance); for (ALL_LIST_ELEMENTS_RO(successors, node, entry)) - entry->flags |= EIGRP_NEXTHOP_ENTRY_INTABLE_FLAG; + entry->flags |= EIGRP_ROUTE_DESCRIPTOR_INTABLE_FLAG; list_delete(&successors); } else { eigrp_zebra_route_delete(eigrp, prefix->destination); for (ALL_LIST_ELEMENTS_RO(prefix->entries, node, entry)) - entry->flags &= ~EIGRP_NEXTHOP_ENTRY_INTABLE_FLAG; + entry->flags &= ~EIGRP_ROUTE_DESCRIPTOR_INTABLE_FLAG; } } @@ -488,8 +492,8 @@ void eigrp_topology_neighbor_down(struct eigrp *eigrp, struct eigrp_neighbor *nbr) { struct listnode *node2, *node22; - struct eigrp_prefix_entry *pe; - struct eigrp_nexthop_entry *entry; + struct eigrp_prefix_descriptor *pe; + struct eigrp_route_descriptor *entry; struct route_node *rn; for (rn = route_top(eigrp->topology_table); rn; rn = route_next(rn)) { @@ -521,18 +525,18 @@ void eigrp_topology_neighbor_down(struct eigrp *eigrp, void eigrp_update_topology_table_prefix(struct eigrp *eigrp, struct route_table *table, - struct eigrp_prefix_entry *prefix) + struct eigrp_prefix_descriptor *prefix) { struct listnode *node1, *node2; - struct eigrp_nexthop_entry *entry; + struct eigrp_route_descriptor *entry; for (ALL_LIST_ELEMENTS(prefix->entries, node1, node2, entry)) { if (entry->distance == EIGRP_MAX_METRIC) { - eigrp_nexthop_entry_delete(eigrp, prefix, entry); + eigrp_route_descriptor_delete(eigrp, prefix, entry); } } if (prefix->distance == EIGRP_MAX_METRIC && prefix->nt != EIGRP_TOPOLOGY_TYPE_CONNECTED) { - eigrp_prefix_entry_delete(eigrp, table, prefix); + eigrp_prefix_descriptor_delete(eigrp, table, prefix); } } diff --git a/eigrpd/eigrp_topology.h b/eigrpd/eigrp_topology.h index 718cece403..26fa1a11b0 100644 --- a/eigrpd/eigrp_topology.h +++ b/eigrpd/eigrp_topology.h @@ -35,43 +35,47 @@ /* EIGRP Topology table related functions. */ extern struct route_table *eigrp_topology_new(void); extern void eigrp_topology_init(struct route_table *table); -extern struct eigrp_prefix_entry *eigrp_prefix_entry_new(void); -extern struct eigrp_nexthop_entry *eigrp_nexthop_entry_new(void); +extern struct eigrp_prefix_descriptor *eigrp_prefix_descriptor_new(void); +extern struct eigrp_route_descriptor *eigrp_route_descriptor_new(void); extern void eigrp_topology_free(struct eigrp *eigrp, struct route_table *table); -extern void eigrp_prefix_entry_add(struct route_table *table, - struct eigrp_prefix_entry *pe); -extern void eigrp_nexthop_entry_add(struct eigrp *eigrp, - struct eigrp_prefix_entry *pe, - struct eigrp_nexthop_entry *ne); -extern void eigrp_prefix_entry_delete(struct eigrp *eigrp, - struct route_table *table, - struct eigrp_prefix_entry *pe); -extern void eigrp_nexthop_entry_delete(struct eigrp *eigrp, - struct eigrp_prefix_entry *pe, - struct eigrp_nexthop_entry *ne); +extern void eigrp_prefix_descriptor_add(struct route_table *table, + struct eigrp_prefix_descriptor *pe); +extern void eigrp_route_descriptor_add(struct eigrp *eigrp, + struct eigrp_prefix_descriptor *pe, + struct eigrp_route_descriptor *ne); +extern void eigrp_prefix_descriptor_delete(struct eigrp *eigrp, + struct route_table *table, + struct eigrp_prefix_descriptor *pe); +extern void eigrp_route_descriptor_delete(struct eigrp *eigrp, + struct eigrp_prefix_descriptor *pe, + struct eigrp_route_descriptor *ne); extern void eigrp_topology_delete_all(struct eigrp *eigrp, struct route_table *table); -extern struct eigrp_prefix_entry * +extern struct eigrp_prefix_descriptor * eigrp_topology_table_lookup_ipv4(struct route_table *table, struct prefix *p); -extern struct list *eigrp_topology_get_successor(struct eigrp_prefix_entry *pe); extern struct list * -eigrp_topology_get_successor_max(struct eigrp_prefix_entry *pe, +eigrp_topology_get_successor(struct eigrp_prefix_descriptor *pe); +extern struct list * +eigrp_topology_get_successor_max(struct eigrp_prefix_descriptor *pe, unsigned int maxpaths); -extern struct eigrp_nexthop_entry * -eigrp_prefix_entry_lookup(struct list *entries, struct eigrp_neighbor *neigh); +extern struct eigrp_route_descriptor * +eigrp_route_descriptor_lookup(struct list *entries, + struct eigrp_neighbor *neigh); extern struct list *eigrp_neighbor_prefixes_lookup(struct eigrp *eigrp, struct eigrp_neighbor *n); extern void eigrp_topology_update_all_node_flags(struct eigrp *eigrp); -extern void eigrp_topology_update_node_flags(struct eigrp *eigrp, - struct eigrp_prefix_entry *pe); +extern void +eigrp_topology_update_node_flags(struct eigrp *eigrp, + struct eigrp_prefix_descriptor *pe); extern enum metric_change eigrp_topology_update_distance(struct eigrp_fsm_action_message *msg); extern void eigrp_update_routing_table(struct eigrp *eigrp, - struct eigrp_prefix_entry *pe); + struct eigrp_prefix_descriptor *pe); extern void eigrp_topology_neighbor_down(struct eigrp *eigrp, struct eigrp_neighbor *neigh); -extern void eigrp_update_topology_table_prefix(struct eigrp *eigrp, - struct route_table *table, - struct eigrp_prefix_entry *pe); +extern void +eigrp_update_topology_table_prefix(struct eigrp *eigrp, + struct route_table *table, + struct eigrp_prefix_descriptor *pe); #endif diff --git a/eigrpd/eigrp_types.h b/eigrpd/eigrp_types.h new file mode 100644 index 0000000000..bd6510733b --- /dev/null +++ b/eigrpd/eigrp_types.h @@ -0,0 +1,36 @@ +/* + * EIGRP Definition of Data Types + * Copyright (C) 2018 + * Authors: + * Donnie Savage + * + * This file is part of FRR. + * + * FRR is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * FRR is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _ZEBRA_EIGRP_TYPES_H_ +#define _ZEBRA_EIGRP_TYPES_H_ + +typedef uint64_t eigrp_bandwidth_t; +typedef uint64_t eigrp_delay_t; +typedef uint64_t eigrp_metric_t; +typedef uint32_t eigrp_scaled_t; + +typedef uint32_t eigrp_system_metric_t; +typedef uint32_t eigrp_system_delay_t; +typedef uint32_t eigrp_system_bandwidth_t; + +#endif /* _ZEBRA_EIGRP_TYPES_H_ */ diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c index cd30eb5ab5..91f3b3218b 100644 --- a/eigrpd/eigrp_update.c +++ b/eigrpd/eigrp_update.c @@ -49,6 +49,7 @@ #include "routemap.h" #include "vty.h" +#include "eigrpd/eigrp_types.h" #include "eigrpd/eigrp_structs.h" #include "eigrpd/eigrpd.h" #include "eigrpd/eigrp_interface.h" @@ -62,6 +63,7 @@ #include "eigrpd/eigrp_fsm.h" #include "eigrpd/eigrp_network.h" #include "eigrpd/eigrp_memory.h" +#include "eigrpd/eigrp_metric.h" bool eigrp_update_prefix_apply(struct eigrp *eigrp, struct eigrp_interface *ei, int in, struct prefix *prefix) @@ -101,11 +103,12 @@ bool eigrp_update_prefix_apply(struct eigrp *eigrp, struct eigrp_interface *ei, * Function is used for removing received prefix * from list of neighbor prefixes */ -static void remove_received_prefix_gr(struct list *nbr_prefixes, - struct eigrp_prefix_entry *recv_prefix) +static void +remove_received_prefix_gr(struct list *nbr_prefixes, + struct eigrp_prefix_descriptor *recv_prefix) { struct listnode *node1, *node11; - struct eigrp_prefix_entry *prefix = NULL; + struct eigrp_prefix_descriptor *prefix = NULL; /* iterate over all prefixes in list */ for (ALL_LIST_ELEMENTS(nbr_prefixes, node1, node11, prefix)) { @@ -136,7 +139,7 @@ static void eigrp_update_receive_GR_ask(struct eigrp *eigrp, struct list *nbr_prefixes) { struct listnode *node1; - struct eigrp_prefix_entry *prefix; + struct eigrp_prefix_descriptor *prefix; struct eigrp_fsm_action_message fsm_msg; /* iterate over all prefixes which weren't advertised by neighbor */ @@ -148,8 +151,8 @@ static void eigrp_update_receive_GR_ask(struct eigrp *eigrp, /* set delay to MAX */ fsm_msg.metrics.delay = EIGRP_MAX_METRIC; - struct eigrp_nexthop_entry *entry = - eigrp_prefix_entry_lookup(prefix->entries, nbr); + struct eigrp_route_descriptor *entry = + eigrp_route_descriptor_lookup(prefix->entries, nbr); fsm_msg.packet_type = EIGRP_OPC_UPDATE; fsm_msg.eigrp = eigrp; @@ -172,8 +175,8 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, { struct eigrp_neighbor *nbr; struct TLV_IPv4_Internal_type *tlv; - struct eigrp_prefix_entry *pe; - struct eigrp_nexthop_entry *ne; + struct eigrp_prefix_descriptor *pe; + struct eigrp_route_descriptor *ne; uint32_t flags; uint16_t type; uint16_t length; @@ -304,7 +307,7 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, dest_addr.family = AF_INET; dest_addr.u.prefix4 = tlv->destination; dest_addr.prefixlen = tlv->prefix_length; - struct eigrp_prefix_entry *dest = + struct eigrp_prefix_descriptor *dest = eigrp_topology_table_lookup_ipv4( eigrp->topology_table, &dest_addr); @@ -317,9 +320,9 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, dest); struct eigrp_fsm_action_message msg; - struct eigrp_nexthop_entry *entry = - eigrp_prefix_entry_lookup(dest->entries, - nbr); + struct eigrp_route_descriptor *entry = + eigrp_route_descriptor_lookup( + dest->entries, nbr); msg.packet_type = EIGRP_OPC_UPDATE; msg.eigrp = eigrp; @@ -331,7 +334,7 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, eigrp_fsm_event(&msg); } else { /*Here comes topology information save*/ - pe = eigrp_prefix_entry_new(); + pe = eigrp_prefix_descriptor_new(); pe->serno = eigrp->serno; pe->destination = (struct prefix *)prefix_ipv4_new(); @@ -340,7 +343,7 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, pe->state = EIGRP_FSM_STATE_PASSIVE; pe->nt = EIGRP_TOPOLOGY_TYPE_REMOTE; - ne = eigrp_nexthop_entry_new(); + ne = eigrp_route_descriptor_new(); ne->ei = ei; ne->adv_router = nbr; ne->reported_metric = tlv->metric; @@ -361,11 +364,12 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph, pe->fdistance = pe->distance = pe->rdistance = ne->distance; ne->prefix = pe; - ne->flags = EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG; + ne->flags = + EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG; - eigrp_prefix_entry_add(eigrp->topology_table, - pe); - eigrp_nexthop_entry_add(eigrp, pe, ne); + eigrp_prefix_descriptor_add( + eigrp->topology_table, pe); + eigrp_route_descriptor_add(eigrp, pe, ne); pe->distance = pe->fdistance = pe->rdistance = ne->distance; pe->reported_metric = ne->total_metric; @@ -527,8 +531,8 @@ void eigrp_update_send_EOT(struct eigrp_neighbor *nbr) { struct eigrp_packet *ep; uint16_t length = EIGRP_HEADER_LEN; - struct eigrp_nexthop_entry *te; - struct eigrp_prefix_entry *pe; + struct eigrp_route_descriptor *te; + struct eigrp_prefix_descriptor *pe; struct listnode *node2, *nnode2; struct eigrp_interface *ei = nbr->ei; struct eigrp *eigrp = ei->eigrp; @@ -600,7 +604,7 @@ void eigrp_update_send(struct eigrp_interface *ei) { struct eigrp_packet *ep; struct listnode *node, *nnode; - struct eigrp_prefix_entry *pe; + struct eigrp_prefix_descriptor *pe; uint8_t has_tlv; struct eigrp *eigrp = ei->eigrp; struct prefix *dest_addr; @@ -626,7 +630,7 @@ void eigrp_update_send(struct eigrp_interface *ei) has_tlv = 0; for (ALL_LIST_ELEMENTS(ei->eigrp->topology_changes_internalIPV4, node, nnode, pe)) { - struct eigrp_nexthop_entry *ne; + struct eigrp_route_descriptor *ne; if (!(pe->req_action & EIGRP_FSM_NEED_UPDATE)) continue; @@ -707,7 +711,7 @@ void eigrp_update_send_all(struct eigrp *eigrp, { struct eigrp_interface *iface; struct listnode *node, *node2, *nnode2; - struct eigrp_prefix_entry *pe; + struct eigrp_prefix_descriptor *pe; for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, iface)) { if (iface != exception) { @@ -745,7 +749,7 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr) { struct eigrp_packet *ep; uint16_t length = EIGRP_HEADER_LEN; - struct eigrp_prefix_entry *pe; + struct eigrp_prefix_descriptor *pe; struct prefix *dest_addr; struct eigrp_interface *ei = nbr->ei; struct eigrp *eigrp = ei->eigrp; @@ -837,8 +841,8 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr) /* prepare message for FSM */ struct eigrp_fsm_action_message fsm_msg; - struct eigrp_nexthop_entry *entry = - eigrp_prefix_entry_lookup(pe->entries, nbr); + struct eigrp_route_descriptor *entry = + eigrp_route_descriptor_lookup(pe->entries, nbr); fsm_msg.packet_type = EIGRP_OPC_UPDATE; fsm_msg.eigrp = eigrp; @@ -956,7 +960,7 @@ int eigrp_update_send_GR_thread(struct thread *thread) void eigrp_update_send_GR(struct eigrp_neighbor *nbr, enum GR_type gr_type, struct vty *vty) { - struct eigrp_prefix_entry *pe2; + struct eigrp_prefix_descriptor *pe2; struct list *prefixes; struct route_node *rn; struct eigrp_interface *ei = nbr->ei; diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c index 66dfbaa538..0809ac2cf0 100644 --- a/eigrpd/eigrp_vty.c +++ b/eigrpd/eigrp_vty.c @@ -59,25 +59,21 @@ #include "eigrpd/eigrp_vty_clippy.c" #endif -static void eigrp_vty_display_prefix_entry(struct vty *vty, - struct eigrp *eigrp, - struct eigrp_prefix_entry *pe, +static void eigrp_vty_display_prefix_entry(struct vty *vty, struct eigrp *eigrp, + struct eigrp_prefix_descriptor *pe, bool all) { bool first = true; - struct eigrp_nexthop_entry *te; + struct eigrp_route_descriptor *te; struct listnode *node; for (ALL_LIST_ELEMENTS_RO(pe->entries, node, te)) { if (all - || (((te->flags - & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG) - == EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG) - || ((te->flags - & EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG) - == EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG))) { - show_ip_eigrp_nexthop_entry(vty, eigrp, te, - &first); + || (((te->flags & EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG) + == EIGRP_ROUTE_DESCRIPTOR_SUCCESSOR_FLAG) + || ((te->flags & EIGRP_ROUTE_DESCRIPTOR_FSUCCESSOR_FLAG) + == EIGRP_ROUTE_DESCRIPTOR_FSUCCESSOR_FLAG))) { + show_ip_eigrp_route_descriptor(vty, eigrp, te, &first); first = false; } } @@ -104,7 +100,7 @@ static struct eigrp *eigrp_vty_get_eigrp(struct vty *vty, const char *vrf_name) static void eigrp_topology_helper(struct vty *vty, struct eigrp *eigrp, const char *all) { - struct eigrp_prefix_entry *tn; + struct eigrp_prefix_descriptor *tn; struct route_node *rn; show_ip_eigrp_topology_header(vty, eigrp); @@ -168,7 +164,7 @@ DEFPY (show_ip_eigrp_topology, "For a specific prefix\n") { struct eigrp *eigrp; - struct eigrp_prefix_entry *tn; + struct eigrp_prefix_descriptor *tn; struct route_node *rn; struct prefix cmp; diff --git a/eigrpd/eigrp_yang.h b/eigrpd/eigrp_yang.h new file mode 100644 index 0000000000..a95e5310fb --- /dev/null +++ b/eigrpd/eigrp_yang.h @@ -0,0 +1,32 @@ +/* + * EIGRP YANG Functions. + * Copyright (C) 2019 + * Authors: + * Donnie Savage + * + * This file is part of FRR. + * + * FRR is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * FRR is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _EIGRP_YANG_H_ +#define _EIGRP_YANG_H_ + +/*Prototypes*/ + +/* eigrp_northbound.c */ +extern const struct frr_yang_module_info frr_eigrpd_info; + +#endif /*EIGRP_YANG_H_ */ diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c index 0795fbd6df..e79123e6b4 100644 --- a/eigrpd/eigrp_zebra.c +++ b/eigrpd/eigrp_zebra.c @@ -41,6 +41,7 @@ #include "log.h" #include "nexthop.h" +#include "eigrpd/eigrp_types.h" #include "eigrpd/eigrp_structs.h" #include "eigrpd/eigrpd.h" #include "eigrpd/eigrp_interface.h" @@ -52,6 +53,7 @@ #include "eigrpd/eigrp_network.h" #include "eigrpd/eigrp_topology.h" #include "eigrpd/eigrp_fsm.h" +#include "eigrpd/eigrp_metric.h" static int eigrp_interface_address_add(ZAPI_CALLBACK_ARGS); static int eigrp_interface_address_delete(ZAPI_CALLBACK_ARGS); @@ -194,7 +196,7 @@ void eigrp_zebra_route_add(struct eigrp *eigrp, struct prefix *p, { struct zapi_route api; struct zapi_nexthop *api_nh; - struct eigrp_nexthop_entry *te; + struct eigrp_route_descriptor *te; struct listnode *node; int count = 0; diff --git a/eigrpd/eigrpd.h b/eigrpd/eigrpd.h index 6b4d45d1fc..01173768ba 100644 --- a/eigrpd/eigrpd.h +++ b/eigrpd/eigrpd.h @@ -37,6 +37,30 @@ #define EIGRP_MAJOR_VERSION 1 #define EIGRP_MINOR_VERSION 2 +#define EIGRP_TLV_32B_VERSION 1 /* Original 32bit scaled metrics */ +#define EIGRP_TLV_64B_VERSION 2 /* Current 64bit 'wide' metrics */ +#define EIGRP_TLV_MTR_VERSION 3 /* MTR TLVs with 32bit metric *Not Supported */ +#define EIGRP_TLV_SAF_VERSION 4 /* SAF TLVs with 64bit metric *Not Supported */ + +struct eigrp_master { + /* EIGRP instance. */ + struct list *eigrp; + + /* EIGRP thread master. */ + struct thread_master *master; + + /* Zebra interface list. */ + struct list *iflist; + + /* EIGRP start time. */ + time_t start_time; + + /* Various EIGRP global configuration. */ + uint8_t options; + +#define EIGRP_MASTER_SHUTDOWN (1 << 0) /* deferred-shutdown */ +}; + /* Extern variables. */ extern struct zclient *zclient; extern struct thread_master *master; @@ -46,57 +70,10 @@ extern struct zebra_privs_t eigrpd_privs; /* Prototypes */ extern void eigrp_master_init(void); extern void eigrp_terminate(void); -extern void eigrp_finish_final(struct eigrp *); -extern void eigrp_finish(struct eigrp *); +extern void eigrp_finish_final(struct eigrp *eigrp); +extern void eigrp_finish(struct eigrp *eigrp); extern struct eigrp *eigrp_get(uint16_t as, vrf_id_t vrf_id); extern struct eigrp *eigrp_lookup(vrf_id_t vrf_id); -extern void eigrp_router_id_update(struct eigrp *); - -/* eigrp_cli.c */ -extern void eigrp_cli_show_header(struct vty *vty, struct lyd_node *dnode, - bool show_defaults); -extern void eigrp_cli_show_end_header(struct vty *vty, struct lyd_node *dnode); -extern void eigrp_cli_show_router_id(struct vty *vty, struct lyd_node *dnode, - bool show_defaults); -extern void eigrp_cli_show_passive_interface(struct vty *vty, - struct lyd_node *dnode, - bool show_defaults); -extern void eigrp_cli_show_active_time(struct vty *vty, struct lyd_node *dnode, - bool show_defaults); -extern void eigrp_cli_show_variance(struct vty *vty, struct lyd_node *dnode, - bool show_defaults); -extern void eigrp_cli_show_maximum_paths(struct vty *vty, - struct lyd_node *dnode, - bool show_defaults); -extern void eigrp_cli_show_metrics(struct vty *vty, struct lyd_node *dnode, - bool show_defaults); -extern void eigrp_cli_show_network(struct vty *vty, struct lyd_node *dnode, - bool show_defaults); -extern void eigrp_cli_show_neighbor(struct vty *vty, struct lyd_node *dnode, - bool show_defaults); -extern void eigrp_cli_show_redistribute(struct vty *vty, - struct lyd_node *dnode, - bool show_defaults); -extern void eigrp_cli_show_delay(struct vty *vty, struct lyd_node *dnode, - bool show_defaults); -extern void eigrp_cli_show_bandwidth(struct vty *vty, struct lyd_node *dnode, - bool show_defaults); -extern void eigrp_cli_show_hello_interval(struct vty *vty, - struct lyd_node *dnode, - bool show_defaults); -extern void eigrp_cli_show_hold_time(struct vty *vty, struct lyd_node *dnode, - bool show_defaults); -extern void eigrp_cli_show_summarize_address(struct vty *vty, - struct lyd_node *dnode, - bool show_defaults); -extern void eigrp_cli_show_authentication(struct vty *vty, - struct lyd_node *dnode, - bool show_defaults); -extern void eigrp_cli_show_keychain(struct vty *vty, struct lyd_node *dnode, - bool show_defaults); -extern void eigrp_cli_init(void); - -/* eigrp_northbound.c */ -extern const struct frr_yang_module_info frr_eigrpd_info; +extern void eigrp_router_id_update(struct eigrp *eigrp); #endif /* _ZEBRA_EIGRPD_H */ diff --git a/eigrpd/subdir.am b/eigrpd/subdir.am index 98f39440c3..13c9f7f8ae 100644 --- a/eigrpd/subdir.am +++ b/eigrpd/subdir.am @@ -25,6 +25,7 @@ eigrpd_libeigrp_a_SOURCES = \ eigrpd/eigrp_hello.c \ eigrpd/eigrp_interface.c \ eigrpd/eigrp_memory.c \ + eigrpd/eigrp_metric.c \ eigrpd/eigrp_neighbor.c \ eigrpd/eigrp_network.c \ eigrpd/eigrp_northbound.c \ @@ -55,6 +56,7 @@ clippy_scan += \ # end noinst_HEADERS += \ + eigrpd/eigrp_cli.h \ eigrpd/eigrp_const.h \ eigrpd/eigrp_errors.h \ eigrpd/eigrp_filter.h \ @@ -62,13 +64,16 @@ noinst_HEADERS += \ eigrpd/eigrp_interface.h \ eigrpd/eigrp_macros.h \ eigrpd/eigrp_memory.h \ + eigrpd/eigrp_metric.h \ eigrpd/eigrp_neighbor.h \ eigrpd/eigrp_network.h \ eigrpd/eigrp_packet.h \ eigrpd/eigrp_snmp.h \ eigrpd/eigrp_structs.h \ + eigrpd/eigrp_types.h \ eigrpd/eigrp_vrf.h \ eigrpd/eigrp_vty.h \ + eigrpd/eigrp_yang.h \ eigrpd/eigrp_zebra.h \ # end diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h index 50011d55ec..fb79481cb2 100644 --- a/include/linux/if_bridge.h +++ b/include/linux/if_bridge.h @@ -293,15 +293,4 @@ struct br_mcast_stats { __u64 mcast_bytes[BR_MCAST_DIR_SIZE]; __u64 mcast_packets[BR_MCAST_DIR_SIZE]; }; - -/* FDB notification bits for NDA_NOTIFY: - * - BR_FDB_NFY_STATIC - notify on activity/expire even for a static entry - * - BR_FDB_NFY_INACTIVE - mark as inactive to avoid double notification, - * used with BR_FDB_NFY_STATIC (kernel controlled) - */ -enum { - BR_FDB_NFY_STATIC, - BR_FDB_NFY_INACTIVE, - BR_FDB_NFY_MAX -}; #endif /* _UAPI_LINUX_IF_BRIDGE_H */ diff --git a/include/linux/neighbour.h b/include/linux/neighbour.h index c06fe708f7..581af73c7f 100644 --- a/include/linux/neighbour.h +++ b/include/linux/neighbour.h @@ -30,7 +30,7 @@ enum { NDA_SRC_VNI, NDA_PROTOCOL, /* Originator of entry */ NDA_NH_ID, - NDA_NOTIFY, + NDA_FDB_EXT_ATTRS, NDA_EXT_FLAGS, __NDA_MAX }; @@ -178,4 +178,27 @@ enum { }; #define NDTA_MAX (__NDTA_MAX - 1) +/* FDB activity notification bits used in NFEA_ACTIVITY_NOTIFY: + * - FDB_NOTIFY_BIT - notify on activity/expire for any entry + * - FDB_NOTIFY_INACTIVE_BIT - mark as inactive to avoid multiple notifications + */ +enum { + FDB_NOTIFY_BIT = (1 << 0), + FDB_NOTIFY_INACTIVE_BIT = (1 << 1) +}; + +/* embedded into NDA_FDB_EXT_ATTRS: + * [NDA_FDB_EXT_ATTRS] = { + * [NFEA_ACTIVITY_NOTIFY] + * ... + * } + */ +enum { + NFEA_UNSPEC, + NFEA_ACTIVITY_NOTIFY, + NFEA_DONT_REFRESH, + __NFEA_MAX +}; +#define NFEA_MAX (__NFEA_MAX - 1) + #endif diff --git a/isisd/isis_adjacency.h b/isisd/isis_adjacency.h index 3c3a211a52..2780d826f5 100644 --- a/isisd/isis_adjacency.h +++ b/isisd/isis_adjacency.h @@ -139,5 +139,6 @@ void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty, void isis_adj_build_neigh_list(struct list *adjdb, struct list *list); void isis_adj_build_up_list(struct list *adjdb, struct list *list); int isis_adj_usage2levels(enum isis_adj_usage usage); +int isis_bfd_startup_timer(struct thread *thread); #endif /* ISIS_ADJACENCY_H */ diff --git a/isisd/isis_bfd.c b/isisd/isis_bfd.c index f81dd6cf51..e74af4da21 100644 --- a/isisd/isis_bfd.c +++ b/isisd/isis_bfd.c @@ -329,6 +329,13 @@ static void bfd_handle_adj_up(struct isis_adjacency *adj, int command) if (!circuit->bfd_info) goto out; + /* If IS-IS IPv6 is configured wait for IPv6 address to be programmed + * before starting up BFD + */ + if ((circuit->ipv6_router && listcount(circuit->ipv6_link) == 0) + || adj->ipv6_address_count == 0) + return; + /* * If IS-IS is enabled for both IPv4 and IPv6 on the circuit, prefer * creating a BFD session over IPv6. @@ -443,6 +450,44 @@ static int bfd_circuit_write_settings(struct isis_circuit *circuit, } #endif +static int bfd_handle_adj_ip_enabled(struct isis_adjacency *adj, int family) +{ + + if (family != AF_INET6) + return 0; + + if (adj->bfd_session) + return 0; + + if (adj->adj_state != ISIS_ADJ_UP) + return 0; + + bfd_handle_adj_up(adj, ZEBRA_BFD_DEST_REGISTER); + + return 0; +} + +static int bfd_handle_circuit_add_addr(struct isis_circuit *circuit) +{ + struct isis_adjacency *adj; + struct listnode *node; + + if (circuit->area == 0) + return 0; + + for (ALL_LIST_ELEMENTS_RO(circuit->area->adjacency_list, node, adj)) { + if (adj->bfd_session) + continue; + + if (adj->adj_state != ISIS_ADJ_UP) + continue; + + bfd_handle_adj_up(adj, ZEBRA_BFD_DEST_REGISTER); + } + + return 0; +} + void isis_bfd_init(void) { bfd_gbl_init(); @@ -457,4 +502,6 @@ void isis_bfd_init(void) hook_register(isis_circuit_config_write, bfd_circuit_write_settings); #endif + hook_register(isis_adj_ip_enabled_hook, bfd_handle_adj_ip_enabled); + hook_register(isis_circuit_add_addr_hook, bfd_handle_circuit_add_addr); } diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index 2580a7c43a..4aac3f8880 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -252,6 +252,9 @@ struct isis_circuit *circuit_scan_by_ifp(struct interface *ifp) return circuit_lookup_by_ifp(ifp, isis->init_circ_list); } +DEFINE_HOOK(isis_circuit_add_addr_hook, (struct isis_circuit *circuit), + (circuit)) + void isis_circuit_add_addr(struct isis_circuit *circuit, struct connected *connected) { @@ -322,6 +325,9 @@ void isis_circuit_add_addr(struct isis_circuit *circuit, connected->address, circuit->interface->name); #endif /* EXTREME_DEBUG */ } + + hook_call(isis_circuit_add_addr_hook, circuit); + return; } diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h index e736d8fb1f..3387232da2 100644 --- a/isisd/isis_circuit.h +++ b/isisd/isis_circuit.h @@ -142,6 +142,8 @@ struct isis_circuit { struct bfd_info *bfd_info; struct ldp_sync_info *ldp_sync_info; bool lfa_protection[ISIS_LEVELS]; + bool rlfa_protection[ISIS_LEVELS]; + uint32_t rlfa_max_metric[ISIS_LEVELS]; struct hash *lfa_excluded_ifaces[ISIS_LEVELS]; bool tilfa_protection[ISIS_LEVELS]; bool tilfa_node_protection[ISIS_LEVELS]; @@ -223,4 +225,7 @@ DECLARE_HOOK(isis_circuit_config_write, (circuit, vty)) #endif +DECLARE_HOOK(isis_circuit_add_addr_hook, (struct isis_circuit *circuit), + (circuit)) + #endif /* _ZEBRA_ISIS_CIRCUIT_H */ diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c index 1f0bebaf45..5ca70eab0f 100644 --- a/isisd/isis_cli.c +++ b/isisd/isis_cli.c @@ -1915,22 +1915,22 @@ DEFPY_YANG (isis_frr_lfa_load_sharing, if (no) { nb_cli_enqueue_change( vty, "./fast-reroute/level-1/lfa/load-sharing", - NB_OP_DESTROY, "true"); + NB_OP_MODIFY, "true"); } else { nb_cli_enqueue_change( vty, "./fast-reroute/level-1/lfa/load-sharing", - NB_OP_CREATE, "false"); + NB_OP_MODIFY, "false"); } } if (!level || strmatch(level, "level-2")) { if (no) { nb_cli_enqueue_change( vty, "./fast-reroute/level-2/lfa/load-sharing", - NB_OP_DESTROY, "true"); + NB_OP_MODIFY, "true"); } else { nb_cli_enqueue_change( vty, "./fast-reroute/level-2/lfa/load-sharing", - NB_OP_CREATE, "false"); + NB_OP_MODIFY, "false"); } } @@ -1948,6 +1948,62 @@ void cli_show_isis_frr_lfa_load_sharing(struct vty *vty, struct lyd_node *dnode, } /* + * XPath: /frr-isisd:isis/instance/fast-reroute/level-{1,2}/remote-lfa/prefix-list + */ +DEFPY_YANG (isis_frr_remote_lfa_plist, + isis_frr_remote_lfa_plist_cmd, + "fast-reroute remote-lfa prefix-list WORD$plist [<level-1|level-2>$level]", + "Configure Fast ReRoute\n" + "Enable remote LFA related configuration\n" + "Filter PQ node router ID based on prefix list\n" + "Prefix-list name\n" + "Enable router ID filtering for level-1 only\n" + "Enable router ID filtering for level-2 only\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change( + vty, "./fast-reroute/level-1/remote-lfa/prefix-list", + NB_OP_MODIFY, plist); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change( + vty, "./fast-reroute/level-2/remote-lfa/prefix-list", + NB_OP_MODIFY, plist); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG (no_isis_frr_remote_lfa_plist, + no_isis_frr_remote_lfa_plist_cmd, + "no fast-reroute remote-lfa prefix-list [WORD] [<level-1|level-2>$level]", + NO_STR + "Configure Fast ReRoute\n" + "Enable remote LFA related configuration\n" + "Filter PQ node router ID based on prefix list\n" + "Prefix-list name\n" + "Enable router ID filtering for level-1 only\n" + "Enable router ID filtering for level-2 only\n") +{ + if (!level || strmatch(level, "level-1")) + nb_cli_enqueue_change( + vty, "./fast-reroute/level-1/remote-lfa/prefix-list", + NB_OP_DESTROY, NULL); + if (!level || strmatch(level, "level-2")) + nb_cli_enqueue_change( + vty, "./fast-reroute/level-2/remote-lfa/prefix-list", + NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_frr_remote_lfa_plist(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " fast-reroute remote-lfa prefix-list %s %s\n", + yang_dnode_get_string(dnode, NULL), + dnode->parent->parent->schema->name); +} + +/* * XPath: /frr-interface:lib/interface/frr-isisd:isis/passive */ DEFPY_YANG(isis_passive, isis_passive_cmd, "[no] isis passive", @@ -2630,6 +2686,25 @@ void cli_show_ip_isis_frr(struct vty *vty, struct lyd_node *dnode, } } + /* Remote LFA */ + l1_enabled = yang_dnode_get_bool(dnode, "./level-1/remote-lfa/enable"); + l2_enabled = yang_dnode_get_bool(dnode, "./level-2/remote-lfa/enable"); + + if (l1_enabled || l2_enabled) { + if (l1_enabled == l2_enabled) { + vty_out(vty, + " isis fast-reroute remote-lfa tunnel mpls-ldp\n"); + vty_out(vty, "\n"); + } else { + if (l1_enabled) + vty_out(vty, + " isis fast-reroute remote-lfa tunnel mpls-ldp level-1\n"); + if (l2_enabled) + vty_out(vty, + " isis fast-reroute remote-lfa tunnel mpls-ldp level-2\n"); + } + } + /* TI-LFA */ l1_enabled = yang_dnode_get_bool(dnode, "./level-1/ti-lfa/enable"); l2_enabled = yang_dnode_get_bool(dnode, "./level-2/ti-lfa/enable"); @@ -2761,6 +2836,104 @@ void cli_show_frr_lfa_exclude_interface(struct vty *vty, struct lyd_node *dnode, } /* + * XPath: + * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-{1,2}/remote-lfa/enable + */ +DEFPY(isis_remote_lfa, isis_remote_lfa_cmd, + "[no] isis fast-reroute remote-lfa tunnel mpls-ldp [level-1|level-2]$level", + NO_STR + "IS-IS routing protocol\n" + "Interface IP Fast-reroute configuration\n" + "Enable remote LFA computation\n" + "Enable remote LFA computation using tunnels\n" + "Use MPLS LDP tunnel to reach the remote LFA node\n" + "Enable LFA computation for Level 1 only\n" + "Enable LFA computation for Level 2 only\n") +{ + if (!level || strmatch(level, "level-1")) { + if (no) { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/remote-lfa/enable", + NB_OP_MODIFY, "false"); + } else { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/remote-lfa/enable", + NB_OP_MODIFY, "true"); + } + } + if (!level || strmatch(level, "level-2")) { + if (no) { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/remote-lfa/enable", + NB_OP_MODIFY, "false"); + } else { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/remote-lfa/enable", + NB_OP_MODIFY, "true"); + } + } + + return nb_cli_apply_changes(vty, NULL); +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-{1,2}/remote-lfa/maximum-metric + */ +DEFPY(isis_remote_lfa_max_metric, isis_remote_lfa_max_metric_cmd, + "[no] isis fast-reroute remote-lfa maximum-metric (1-16777215)$metric [level-1|level-2]$level", + NO_STR + "IS-IS routing protocol\n" + "Interface IP Fast-reroute configuration\n" + "Enable remote LFA computation\n" + "Limit remote LFA node selection within the metric\n" + "Value of the metric\n" + "Enable LFA computation for Level 1 only\n" + "Enable LFA computation for Level 2 only\n") +{ + if (!level || strmatch(level, "level-1")) { + if (no) { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/remote-lfa/maximum-metric", + NB_OP_DESTROY, NULL); + } else { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-1/remote-lfa/maximum-metric", + NB_OP_MODIFY, metric_str); + } + } + if (!level || strmatch(level, "level-2")) { + if (no) { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/remote-lfa/maximum-metric", + NB_OP_DESTROY, NULL); + } else { + nb_cli_enqueue_change( + vty, + "./frr-isisd:isis/fast-reroute/level-2/remote-lfa/maximum-metric", + NB_OP_MODIFY, metric_str); + } + } + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_frr_remote_lfa_max_metric(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " isis fast-reroute remote-lfa maximum-metric %s %s\n", + yang_dnode_get_string(dnode, NULL), + dnode->parent->parent->schema->name); +} + +/* * XPath: /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-{1,2}/ti-lfa/enable */ DEFPY(isis_ti_lfa, isis_ti_lfa_cmd, @@ -3085,6 +3258,8 @@ void isis_cli_init(void) install_element(ISIS_NODE, &isis_frr_lfa_priority_limit_cmd); install_element(ISIS_NODE, &isis_frr_lfa_tiebreaker_cmd); install_element(ISIS_NODE, &isis_frr_lfa_load_sharing_cmd); + install_element(ISIS_NODE, &isis_frr_remote_lfa_plist_cmd); + install_element(ISIS_NODE, &no_isis_frr_remote_lfa_plist_cmd); install_element(INTERFACE_NODE, &isis_passive_cmd); @@ -3122,6 +3297,8 @@ void isis_cli_init(void) install_element(INTERFACE_NODE, &isis_lfa_cmd); install_element(INTERFACE_NODE, &isis_lfa_exclude_interface_cmd); + install_element(INTERFACE_NODE, &isis_remote_lfa_cmd); + install_element(INTERFACE_NODE, &isis_remote_lfa_max_metric_cmd); install_element(INTERFACE_NODE, &isis_ti_lfa_cmd); install_element(ISIS_NODE, &log_adj_changes_cmd); diff --git a/isisd/isis_lfa.c b/isisd/isis_lfa.c index fc6b435b62..5b3a3827a2 100644 --- a/isisd/isis_lfa.c +++ b/isisd/isis_lfa.c @@ -25,6 +25,8 @@ #include "vrf.h" #include "table.h" #include "srcdest_table.h" +#include "plist.h" +#include "zclient.h" #include "isis_common.h" #include "isisd.h" @@ -37,11 +39,13 @@ #include "isis_mt.h" #include "isis_tlvs.h" #include "isis_spf_private.h" -#include "isisd/isis_errors.h" +#include "isis_zebra.h" +#include "isis_errors.h" DEFINE_MTYPE_STATIC(ISISD, ISIS_SPF_NODE, "ISIS SPF Node"); DEFINE_MTYPE_STATIC(ISISD, ISIS_LFA_TIEBREAKER, "ISIS LFA Tiebreaker"); DEFINE_MTYPE_STATIC(ISISD, ISIS_LFA_EXCL_IFACE, "ISIS LFA Excluded Interface"); +DEFINE_MTYPE_STATIC(ISISD, ISIS_RLFA, "ISIS Remote LFA"); static inline int isis_spf_node_compare(const struct isis_spf_node *a, const struct isis_spf_node *b) @@ -316,7 +320,7 @@ bool isis_lfa_excise_adj_check(const struct isis_spftree *spftree, { const struct lfa_protected_resource *resource; - if (spftree->type != SPF_TYPE_TI_LFA) + if (spftree->type != SPF_TYPE_RLFA && spftree->type != SPF_TYPE_TI_LFA) return false; /* @@ -832,14 +836,14 @@ spf_vertex_check_is_affected(const struct isis_vertex *vertex, return false; } -/* Check if a given TI-LFA post-convergence SPF vertex needs protection. */ -static bool tilfa_check_needs_protection(const struct isis_spftree *spftree_pc, - const struct isis_vertex *vertex) +/* Check if a given RLFA/TI-LFA post-convergence SPF vertex needs protection. */ +static bool lfa_check_needs_protection(const struct isis_spftree *spftree_pc, + const struct isis_vertex *vertex) { struct isis_vertex *vertex_old; - /* Only local adjacencies need Adj-SID protection. */ - if (VTYPE_IS(vertex->type) + /* Only local adjacencies need TI-LFA Adj-SID protection. */ + if (spftree_pc->type == SPF_TYPE_TI_LFA && VTYPE_IS(vertex->type) && !isis_adj_find(spftree_pc->area, spftree_pc->level, vertex->N.id)) return false; @@ -849,6 +853,10 @@ static bool tilfa_check_needs_protection(const struct isis_spftree *spftree_pc, if (!vertex_old) return false; + /* Skip vertex if it's already protected by local LFA. */ + if (CHECK_FLAG(vertex_old->flags, F_ISIS_VERTEX_LFA_PROTECTED)) + return false; + return spf_vertex_check_is_affected( vertex_old, spftree_pc->sysid, &spftree_pc->lfa.protected_resource); @@ -874,14 +882,12 @@ int isis_tilfa_check(struct isis_spftree *spftree_pc, if (!spftree_pc->area->srdb.enabled) return -1; - if (IS_DEBUG_LFA) - vid2string(vertex, buf, sizeof(buf)); - - if (!tilfa_check_needs_protection(spftree_pc, vertex)) { + if (!lfa_check_needs_protection(spftree_pc, vertex)) { if (IS_DEBUG_LFA) zlog_debug( "ISIS-LFA: %s %s unaffected by %s", - vtype2string(vertex->type), buf, + vtype2string(vertex->type), + vid2string(vertex, buf, sizeof(buf)), lfa_protected_resource2str( &spftree_pc->lfa.protected_resource)); @@ -902,7 +908,8 @@ int isis_tilfa_check(struct isis_spftree *spftree_pc, if (IS_DEBUG_LFA) zlog_debug( "ISIS-LFA: %s %s already covered by node protection", - vtype2string(vertex->type), buf); + vtype2string(vertex->type), + vid2string(vertex, buf, sizeof(buf))); return -1; } @@ -915,7 +922,8 @@ int isis_tilfa_check(struct isis_spftree *spftree_pc, if (IS_DEBUG_LFA) zlog_debug( "ISIS-LFA: %s %s already covered by node protection", - vtype2string(vertex->type), buf); + vtype2string(vertex->type), + vid2string(vertex, buf, sizeof(buf))); return -1; } @@ -924,7 +932,8 @@ int isis_tilfa_check(struct isis_spftree *spftree_pc, if (IS_DEBUG_LFA) zlog_debug( "ISIS-LFA: computing repair path(s) of %s %s w.r.t %s", - vtype2string(vertex->type), buf, + vtype2string(vertex->type), + vid2string(vertex, buf, sizeof(buf)), lfa_protected_resource2str( &spftree_pc->lfa.protected_resource)); @@ -939,7 +948,8 @@ int isis_tilfa_check(struct isis_spftree *spftree_pc, if (ret != 0) zlog_warn( "ISIS-LFA: failed to compute repair path(s) of %s %s w.r.t %s", - vtype2string(vertex->type), buf, + vtype2string(vertex->type), + vid2string(vertex, buf, sizeof(buf)), lfa_protected_resource2str( &spftree_pc->lfa.protected_resource)); @@ -978,13 +988,6 @@ static bool vertex_is_affected(struct isis_spftree *spftree_root, struct isis_vertex *vertex_child; struct isis_vertex_adj *vadj; bool reverse = false; - char buf1[VID2STR_BUFFER]; - char buf2[VID2STR_BUFFER]; - - if (IS_DEBUG_LFA) - zlog_debug("ISIS-LFA: vertex %s parent %s", - vid2string(vertex, buf1, sizeof(buf1)), - vid2string(pvertex, buf2, sizeof(buf2))); if (p_space && resource->type == LFA_NODE_PROTECTION) { if (isis_spf_node_find(&resource->nodes, vertex->N.id)) @@ -1059,10 +1062,6 @@ static void lfa_calc_reach_nodes(struct isis_spftree *spftree, if (isis_spf_node_find(nodes, vertex->N.id)) continue; - if (IS_DEBUG_LFA) - zlog_debug("ISIS-LFA: checking %s", - vid2string(vertex, buf, sizeof(buf))); - if (!vertex_is_affected(spftree_root, adj_nodes, p_space, vertex, resource)) { if (IS_DEBUG_LFA) @@ -1166,7 +1165,7 @@ struct isis_spftree *isis_tilfa_compute(struct isis_area *area, struct isis_spf_node *adj_node; if (IS_DEBUG_LFA) - zlog_debug("ISIS-LFA: computing the P/Q spaces w.r.t. %s", + zlog_debug("ISIS-LFA: computing TI-LFAs for %s", lfa_protected_resource2str(resource)); /* Populate list of nodes affected by link failure. */ @@ -1238,6 +1237,497 @@ int isis_spf_run_neighbors(struct isis_spftree *spftree) return 0; } +/* Find Router ID of PQ node. */ +static struct in_addr *rlfa_pq_node_rtr_id(struct isis_spftree *spftree, + const struct isis_vertex *vertex_pq) +{ + struct isis_lsp *lsp; + + lsp = isis_root_system_lsp(spftree->lspdb, vertex_pq->N.id); + if (!lsp) + return NULL; + + if (lsp->tlvs->router_cap->router_id.s_addr == INADDR_ANY) + return NULL; + + return &lsp->tlvs->router_cap->router_id; +} + +/* Find PQ node by intersecting the P/Q spaces. This is a recursive function. */ +static const struct in_addr * +rlfa_find_pq_node(struct isis_spftree *spftree_pc, + struct isis_vertex *vertex_dest, + const struct isis_vertex *vertex, + const struct isis_vertex *vertex_child) +{ + struct isis_area *area = spftree_pc->area; + int level = spftree_pc->level; + struct isis_vertex *pvertex; + struct listnode *node; + bool is_pnode, is_qnode; + + if (!vertex_child) + goto parents; + if (vertex->type != VTYPE_NONPSEUDO_IS + && vertex->type != VTYPE_NONPSEUDO_TE_IS) + goto parents; + if (!VTYPE_IS(vertex_child->type)) + vertex_child = NULL; + + /* Check if node is part of the extended P-space and/or Q-space. */ + is_pnode = lfa_ext_p_space_check(spftree_pc, vertex_dest, vertex); + is_qnode = lfa_q_space_check(spftree_pc, vertex); + + if (is_pnode && is_qnode) { + const struct in_addr *rtr_id_pq; + uint32_t max_metric; + struct prefix_list *plist = NULL; + + rtr_id_pq = rlfa_pq_node_rtr_id(spftree_pc, vertex); + if (!rtr_id_pq) { + if (IS_DEBUG_LFA) { + char buf[VID2STR_BUFFER]; + + vid2string(vertex, buf, sizeof(buf)); + zlog_debug( + "ISIS-LFA: tentative PQ node (%s %s) doesn't have a router-ID", + vtype2string(vertex->type), buf); + } + goto parents; + } + + max_metric = spftree_pc->lfa.remote.max_metric; + if (max_metric && vertex->d_N > max_metric) { + if (IS_DEBUG_LFA) + zlog_debug( + "ISIS-LFA: skipping PQ node %pI4 (maximum metric)", + rtr_id_pq); + goto parents; + } + + plist = area->rlfa_plist[level - 1]; + if (plist) { + struct prefix p; + + p.family = AF_INET; + p.prefixlen = IPV4_MAX_BITLEN; + p.u.prefix4 = *rtr_id_pq; + if (prefix_list_apply(plist, &p) == PREFIX_DENY) { + if (IS_DEBUG_LFA) + zlog_debug( + "ISIS-LFA: PQ node %pI4 filtered by prefix-list", + rtr_id_pq); + goto parents; + } + } + + if (IS_DEBUG_LFA) + zlog_debug("ISIS-LFA: found PQ node: %pI4", rtr_id_pq); + + return rtr_id_pq; + } + +parents: + for (ALL_LIST_ELEMENTS_RO(vertex->parents, node, pvertex)) { + const struct in_addr *rtr_id_pq; + + rtr_id_pq = rlfa_find_pq_node(spftree_pc, vertex_dest, pvertex, + vertex); + if (rtr_id_pq) + return rtr_id_pq; + } + + return NULL; +} + +int rlfa_cmp(const struct rlfa *a, const struct rlfa *b) +{ + return prefix_cmp(&a->prefix, &b->prefix); +} + +static struct rlfa *rlfa_add(struct isis_spftree *spftree, + struct isis_vertex *vertex, + struct in_addr pq_address) +{ + struct rlfa *rlfa; + + assert(VTYPE_IP(vertex->type)); + rlfa = XCALLOC(MTYPE_ISIS_RLFA, sizeof(*rlfa)); + rlfa->prefix = vertex->N.ip.p.dest; + rlfa->vertex = vertex; + rlfa->pq_address = pq_address; + rlfa_tree_add(&spftree->lfa.remote.rlfas, rlfa); + + return rlfa; +} + +static void rlfa_delete(struct isis_spftree *spftree, struct rlfa *rlfa) +{ + rlfa_tree_del(&spftree->lfa.remote.rlfas, rlfa); + XFREE(MTYPE_ISIS_RLFA, rlfa); +} + +static struct rlfa *rlfa_lookup(struct isis_spftree *spftree, + union prefixconstptr pu) +{ + struct rlfa s = {}; + + s.prefix = *pu.p; + return rlfa_tree_find(&spftree->lfa.remote.rlfas, &s); +} + +static int isis_area_verify_routes_cb(struct thread *thread) +{ + struct isis_area *area = THREAD_ARG(thread); + + if (IS_DEBUG_LFA) + zlog_debug("ISIS-LFA: updating RLFAs in the RIB"); + + isis_area_verify_routes(area); + + return 0; +} + +static mpls_label_t rlfa_nexthop_label(struct isis_spftree *spftree, + struct isis_vertex_adj *vadj, + struct zapi_rlfa_response *response) +{ + struct isis_spf_adj *sadj = vadj->sadj; + struct isis_adjacency *adj = sadj->adj; + + /* + * Special case to make unit tests work (use implicit-null labels + * instead of artifical ones). + */ + if (CHECK_FLAG(spftree->flags, F_SPFTREE_NO_ADJACENCIES)) + return MPLS_LABEL_IMPLICIT_NULL; + + for (unsigned int i = 0; i < response->nexthop_num; i++) { + switch (response->nexthops[i].family) { + case AF_INET: + for (unsigned int j = 0; j < adj->ipv4_address_count; + j++) { + struct in_addr addr = adj->ipv4_addresses[j]; + + if (!IPV4_ADDR_SAME( + &addr, + &response->nexthops[i].gate.ipv4)) + continue; + + return response->nexthops[i].label; + } + break; + case AF_INET6: + for (unsigned int j = 0; j < adj->ipv6_address_count; + j++) { + struct in6_addr addr = adj->ipv6_addresses[j]; + + if (!IPV6_ADDR_SAME( + &addr, + &response->nexthops[i].gate.ipv6)) + continue; + + return response->nexthops[i].label; + } + break; + + default: + break; + } + } + + return MPLS_INVALID_LABEL; +} + +int isis_rlfa_activate(struct isis_spftree *spftree, struct rlfa *rlfa, + struct zapi_rlfa_response *response) +{ + struct isis_area *area = spftree->area; + struct isis_vertex *vertex = rlfa->vertex; + struct isis_vertex_adj *vadj; + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO(vertex->Adj_N, node, vadj)) { + mpls_label_t ldp_label; + struct mpls_label_stack *label_stack; + size_t num_labels = 0; + size_t i = 0; + + ldp_label = rlfa_nexthop_label(spftree, vadj, response); + if (ldp_label == MPLS_INVALID_LABEL) { + if (IS_DEBUG_LFA) + zlog_debug( + "ISIS-LFA: failed to activate RLFA: missing LDP label to reach PQ node through %s", + sysid_print(vadj->sadj->id)); + return -1; + } + + if (ldp_label != MPLS_LABEL_IMPLICIT_NULL) + num_labels++; + if (response->pq_label != MPLS_LABEL_IMPLICIT_NULL) + num_labels++; + if (vadj->sr.present + && vadj->sr.label != MPLS_LABEL_IMPLICIT_NULL) + num_labels++; + + /* Allocate label stack. */ + label_stack = + XCALLOC(MTYPE_ISIS_NEXTHOP_LABELS, + sizeof(struct mpls_label_stack) + + num_labels * sizeof(mpls_label_t)); + label_stack->num_labels = num_labels; + + /* Push label allocated by the nexthop (outer label). */ + if (ldp_label != MPLS_LABEL_IMPLICIT_NULL) + label_stack->label[i++] = ldp_label; + /* Push label allocated by the PQ node (inner label). */ + if (response->pq_label != MPLS_LABEL_IMPLICIT_NULL) + label_stack->label[i++] = response->pq_label; + /* Preserve the original Prefix-SID label when it's present. */ + if (vadj->sr.present + && vadj->sr.label != MPLS_LABEL_IMPLICIT_NULL) + label_stack->label[i++] = vadj->sr.label; + + vadj->label_stack = label_stack; + } + + isis_route_create(&vertex->N.ip.p.dest, &vertex->N.ip.p.src, + vertex->d_N, vertex->depth, &vertex->N.ip.sr, + vertex->Adj_N, true, area, + spftree->route_table_backup); + spftree->lfa.protection_counters.rlfa[vertex->N.ip.priority] += 1; + + thread_cancel(&area->t_rlfa_rib_update); + thread_add_timer(master, isis_area_verify_routes_cb, area, 2, + &area->t_rlfa_rib_update); + + return 0; +} + +void isis_rlfa_deactivate(struct isis_spftree *spftree, struct rlfa *rlfa) +{ + struct isis_area *area = spftree->area; + struct isis_vertex *vertex = rlfa->vertex; + struct route_node *rn; + + rn = route_node_lookup(spftree->route_table_backup, &rlfa->prefix); + if (!rn) + return; + isis_route_delete(area, rn, spftree->route_table_backup); + spftree->lfa.protection_counters.rlfa[vertex->N.ip.priority] -= 1; + + thread_cancel(&area->t_rlfa_rib_update); + thread_add_timer(master, isis_area_verify_routes_cb, area, 2, + &area->t_rlfa_rib_update); +} + +void isis_rlfa_list_init(struct isis_spftree *spftree) +{ + rlfa_tree_init(&spftree->lfa.remote.rlfas); +} + +void isis_rlfa_list_clear(struct isis_spftree *spftree) +{ + while (rlfa_tree_count(&spftree->lfa.remote.rlfas) > 0) { + struct rlfa *rlfa; + + rlfa = rlfa_tree_first(&spftree->lfa.remote.rlfas); + isis_rlfa_deactivate(spftree, rlfa); + rlfa_delete(spftree, rlfa); + } +} + +void isis_rlfa_process_ldp_response(struct zapi_rlfa_response *response) +{ + struct isis *isis; + struct isis_area *area; + struct isis_spftree *spftree; + struct rlfa *rlfa; + enum spf_tree_id tree_id; + uint32_t spf_run_id; + int level; + + if (response->igp.protocol != ZEBRA_ROUTE_ISIS) + return; + + isis = isis_lookup_by_vrfid(response->igp.vrf_id); + if (!isis) + return; + + area = isis_area_lookup(response->igp.isis.area_tag, + response->igp.vrf_id); + if (!area) + return; + + tree_id = response->igp.isis.spf.tree_id; + if (tree_id != SPFTREE_IPV4 && tree_id != SPFTREE_IPV6) { + zlog_warn("ISIS-LFA: invalid SPF tree ID received from LDP"); + return; + } + + level = response->igp.isis.spf.level; + if (level != ISIS_LEVEL1 && level != ISIS_LEVEL2) { + zlog_warn("ISIS-LFA: invalid IS-IS level received from LDP"); + return; + } + + spf_run_id = response->igp.isis.spf.run_id; + spftree = area->spftree[tree_id][level - 1]; + if (spftree->runcount != spf_run_id) + /* Outdated RLFA, ignore... */ + return; + + rlfa = rlfa_lookup(spftree, &response->destination); + if (!rlfa) { + zlog_warn( + "ISIS-LFA: couldn't find Remote-LFA %pFX received from LDP", + &response->destination); + return; + } + + if (response->pq_label != MPLS_INVALID_LABEL) { + if (IS_DEBUG_LFA) + zlog_debug( + "ISIS-LFA: activating/updating RLFA for %pFX", + &rlfa->prefix); + + if (isis_rlfa_activate(spftree, rlfa, response) != 0) + isis_rlfa_deactivate(spftree, rlfa); + } else { + if (IS_DEBUG_LFA) + zlog_debug("ISIS-LFA: deactivating RLFA for %pFX", + &rlfa->prefix); + + isis_rlfa_deactivate(spftree, rlfa); + } +} + +void isis_ldp_rlfa_handle_client_close(struct zapi_client_close_info *info) +{ + struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT); + struct isis_area *area; + struct listnode *node; + + if (!isis) + return; + + /* Check if the LDP main client session closed */ + if (info->proto != ZEBRA_ROUTE_LDP || info->session_id == 0) + return; + + if (IS_DEBUG_LFA) + zlog_debug("ISIS-LFA: LDP is down, deactivating all RLFAs"); + + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) { + for (int tree = SPFTREE_IPV4; tree < SPFTREE_COUNT; tree++) { + for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; + level++) { + struct isis_spftree *spftree; + + spftree = area->spftree[tree][level - 1]; + isis_rlfa_list_clear(spftree); + } + } + } +} + +/** + * Check if the given SPF vertex needs protection and, if so, attempt to + * compute a Remote LFA for it. + * + * @param spftree_pc The post-convergence SPF tree + * @param vertex IS-IS SPF vertex to check + */ +void isis_rlfa_check(struct isis_spftree *spftree_pc, + struct isis_vertex *vertex) +{ + struct isis_spftree *spftree_old = spftree_pc->lfa.old.spftree; + struct rlfa *rlfa; + const struct in_addr *rtr_id_pq; + char buf[VID2STR_BUFFER]; + + if (!lfa_check_needs_protection(spftree_pc, vertex)) { + if (IS_DEBUG_LFA) + zlog_debug( + "ISIS-LFA: %s %s unaffected by %s", + vtype2string(vertex->type), + vid2string(vertex, buf, sizeof(buf)), + lfa_protected_resource2str( + &spftree_pc->lfa.protected_resource)); + + return; + } + + if (IS_DEBUG_LFA) + zlog_debug( + "ISIS-LFA: computing repair path(s) of %s %s w.r.t %s", + vtype2string(vertex->type), + vid2string(vertex, buf, sizeof(buf)), + lfa_protected_resource2str( + &spftree_pc->lfa.protected_resource)); + + /* Find PQ node. */ + rtr_id_pq = rlfa_find_pq_node(spftree_pc, vertex, vertex, NULL); + if (!rtr_id_pq) { + if (IS_DEBUG_LFA) + zlog_debug("ISIS-LFA: no acceptable PQ node found"); + return; + } + + /* Store valid RLFA and store LDP label for the PQ node. */ + rlfa = rlfa_add(spftree_old, vertex, *rtr_id_pq); + + /* Register RLFA with LDP. */ + if (isis_zebra_rlfa_register(spftree_old, rlfa) != 0) + rlfa_delete(spftree_old, rlfa); +} + +/** + * Compute the Remote LFA backup paths for a given protected interface. + * + * @param area IS-IS area + * @param spftree IS-IS SPF tree + * @param spftree_reverse IS-IS Reverse SPF tree + * @param max_metric Remote LFA maximum metric + * @param resource Protected resource + * + * @return Pointer to the post-convergence SPF tree + */ +struct isis_spftree *isis_rlfa_compute(struct isis_area *area, + struct isis_spftree *spftree, + struct isis_spftree *spftree_reverse, + uint32_t max_metric, + struct lfa_protected_resource *resource) +{ + struct isis_spftree *spftree_pc; + + if (IS_DEBUG_LFA) + zlog_debug("ISIS-LFA: computing remote LFAs for %s", + lfa_protected_resource2str(resource)); + + /* Create post-convergence SPF tree. */ + spftree_pc = isis_spftree_new(area, spftree->lspdb, spftree->sysid, + spftree->level, spftree->tree_id, + SPF_TYPE_RLFA, spftree->flags); + spftree_pc->lfa.old.spftree = spftree; + spftree_pc->lfa.old.spftree_reverse = spftree_reverse; + spftree_pc->lfa.remote.max_metric = max_metric; + spftree_pc->lfa.protected_resource = *resource; + + /* Compute the extended P-space and Q-space. */ + lfa_calc_pq_spaces(spftree_pc, resource); + + if (IS_DEBUG_LFA) + zlog_debug( + "ISIS-LFA: computing the post convergence SPT w.r.t. %s", + lfa_protected_resource2str(resource)); + + /* Re-run SPF in the local node to find the post-convergence paths. */ + isis_run_spf(spftree_pc); + + return spftree_pc; +} + /* Calculate the distance from the root node to the given IP destination. */ static int lfa_calc_dist_destination(struct isis_spftree *spftree, const struct isis_vertex *vertex_N, @@ -1451,8 +1941,7 @@ static bool clfa_node_protecting_check(struct isis_spftree *spftree, } static struct list * -isis_lfa_tiebreakers(struct isis_area *area, struct isis_circuit *circuit, - struct isis_spftree *spftree, +isis_lfa_tiebreakers(struct isis_area *area, struct isis_spftree *spftree, struct lfa_protected_resource *resource, struct isis_vertex *vertex, struct isis_spf_adj *sadj_primary, struct list *lfa_list) @@ -1572,6 +2061,10 @@ void isis_lfa_compute(struct isis_area *area, struct isis_circuit *circuit, resource->type = LFA_LINK_PROTECTION; + if (IS_DEBUG_LFA) + zlog_debug("ISIS-LFA: computing local LFAs for %s", + lfa_protected_resource2str(resource)); + for (ALL_QUEUE_ELEMENTS_RO(&spftree->paths, vnode, vertex)) { struct list *lfa_list; struct list *filtered_lfa_list; @@ -1591,7 +2084,8 @@ void isis_lfa_compute(struct isis_area *area, struct isis_circuit *circuit, resource)) { if (IS_DEBUG_LFA) zlog_debug( - "ISIS-LFA: route unaffected by %s", + "ISIS-LFA: %s %s unaffected by %s", + vtype2string(vertex->type), buf, lfa_protected_resource2str(resource)); continue; } @@ -1697,15 +2191,18 @@ void isis_lfa_compute(struct isis_area *area, struct isis_circuit *circuit, if (list_isempty(lfa_list)) { if (IS_DEBUG_LFA) - zlog_debug("ISIS-LFA: no valid LFAs found"); + zlog_debug( + "ISIS-LFA: no valid local LFAs found"); list_delete(&lfa_list); continue; } + SET_FLAG(vertex->flags, F_ISIS_VERTEX_LFA_PROTECTED); + /* Check tie-breakers. */ filtered_lfa_list = - isis_lfa_tiebreakers(area, circuit, spftree, resource, - vertex, sadj_primary, lfa_list); + isis_lfa_tiebreakers(area, spftree, resource, vertex, + sadj_primary, lfa_list); /* Create backup route using the best LFAs. */ allow_ecmp = area->lfa_load_sharing[level - 1]; @@ -1746,7 +2243,7 @@ static void isis_spf_run_tilfa(struct isis_area *area, } /** - * Run the LFA/TI-LFA algorithms for all protected interfaces. + * Run the LFA/RLFA/TI-LFA algorithms for all protected interfaces. * * @param area IS-IS area * @param spftree IS-IS SPF tree @@ -1756,13 +2253,11 @@ void isis_spf_run_lfa(struct isis_area *area, struct isis_spftree *spftree) struct isis_spftree *spftree_reverse = NULL; struct isis_circuit *circuit; struct listnode *node; - bool tilfa_configured; int level = spftree->level; - tilfa_configured = (area->tilfa_protected_links[level - 1] > 0); - /* Run reverse SPF locally. */ - if (tilfa_configured) + if (area->rlfa_protected_links[level - 1] > 0 + || area->tilfa_protected_links[level - 1] > 0) spftree_reverse = isis_spf_reverse_run(spftree); /* Run forward SPF on all adjacent routers. */ @@ -1808,15 +2303,32 @@ void isis_spf_run_lfa(struct isis_area *area, struct isis_spftree *spftree) continue; } - if (circuit->lfa_protection[level - 1]) + if (circuit->lfa_protection[level - 1]) { + /* Run local LFA. */ isis_lfa_compute(area, circuit, spftree, &resource); - else if (circuit->tilfa_protection[level - 1]) { + + if (circuit->rlfa_protection[level - 1]) { + struct isis_spftree *spftree_pc; + uint32_t max_metric; + + /* Run remote LFA. */ + assert(spftree_reverse); + max_metric = + circuit->rlfa_max_metric[level - 1]; + spftree_pc = isis_rlfa_compute( + area, spftree, spftree_reverse, + max_metric, &resource); + listnode_add(spftree->lfa.remote.pc_spftrees, + spftree_pc); + } + } else if (circuit->tilfa_protection[level - 1]) { + /* Run TI-LFA. */ assert(spftree_reverse); isis_spf_run_tilfa(area, circuit, spftree, spftree_reverse, &resource); } } - if (tilfa_configured) + if (spftree_reverse) isis_spftree_del(spftree_reverse); } diff --git a/isisd/isis_lfa.h b/isisd/isis_lfa.h index f09fc663a4..65891cae44 100644 --- a/isisd/isis_lfa.h +++ b/isisd/isis_lfa.h @@ -21,8 +21,10 @@ #define _FRR_ISIS_LFA_H #include "lib/typesafe.h" +#include "lib/zclient.h" PREDECL_RBTREE_UNIQ(lfa_tiebreaker_tree) +PREDECL_RBTREE_UNIQ(rlfa_tree) enum lfa_tiebreaker_type { LFA_TIEBREAKER_DOWNSTREAM = 0, @@ -41,6 +43,15 @@ int lfa_tiebreaker_cmp(const struct lfa_tiebreaker *a, DECLARE_RBTREE_UNIQ(lfa_tiebreaker_tree, struct lfa_tiebreaker, entry, lfa_tiebreaker_cmp) +struct rlfa { + struct rlfa_tree_item entry; + struct prefix prefix; + struct isis_vertex *vertex; + struct in_addr pq_address; +}; +int rlfa_cmp(const struct rlfa *a, const struct rlfa *b); +DECLARE_RBTREE_UNIQ(rlfa_tree, struct rlfa, entry, rlfa_cmp) + enum isis_tilfa_sid_type { TILFA_SID_PREFIX = 1, TILFA_SID_ADJ, @@ -145,6 +156,19 @@ bool isis_lfa_excise_node_check(const struct isis_spftree *spftree, const uint8_t *id); struct isis_spftree *isis_spf_reverse_run(const struct isis_spftree *spftree); int isis_spf_run_neighbors(struct isis_spftree *spftree); +int isis_rlfa_activate(struct isis_spftree *spftree, struct rlfa *rlfa, + struct zapi_rlfa_response *response); +void isis_rlfa_deactivate(struct isis_spftree *spftree, struct rlfa *rlfa); +void isis_rlfa_list_init(struct isis_spftree *spftree); +void isis_rlfa_list_clear(struct isis_spftree *spftree); +void isis_rlfa_process_ldp_response(struct zapi_rlfa_response *response); +void isis_ldp_rlfa_handle_client_close(struct zapi_client_close_info *info); +void isis_rlfa_check(struct isis_spftree *spftree, struct isis_vertex *vertex); +struct isis_spftree *isis_rlfa_compute(struct isis_area *area, + struct isis_spftree *spftree, + struct isis_spftree *spftree_reverse, + uint32_t max_metric, + struct lfa_protected_resource *resource); void isis_lfa_compute(struct isis_area *area, struct isis_circuit *circuit, struct isis_spftree *spftree, struct lfa_protected_resource *resource); diff --git a/isisd/isis_main.c b/isisd/isis_main.c index 4576a4a95c..1b04f4f7a0 100644 --- a/isisd/isis_main.c +++ b/isisd/isis_main.c @@ -246,6 +246,8 @@ int main(int argc, char **argv, char **envp) access_list_delete_hook(isis_filter_update); isis_vrf_init(); prefix_list_init(); + prefix_list_add_hook(isis_prefix_list_update); + prefix_list_delete_hook(isis_prefix_list_update); isis_init(); isis_circuit_init(); #ifdef FABRICD diff --git a/isisd/isis_memory.c b/isisd/isis_memory.c index b63a82f404..f716e060cd 100644 --- a/isisd/isis_memory.c +++ b/isisd/isis_memory.c @@ -46,3 +46,4 @@ DEFINE_MTYPE(ISISD, ISIS_EXT_ROUTE, "ISIS redistributed route") DEFINE_MTYPE(ISISD, ISIS_EXT_INFO, "ISIS redistributed route info") DEFINE_MTYPE(ISISD, ISIS_MPLS_TE, "ISIS MPLS_TE parameters") DEFINE_MTYPE(ISISD, ISIS_ACL_NAME, "ISIS access-list name") +DEFINE_MTYPE(ISISD, ISIS_PLIST_NAME, "ISIS prefix-list name") diff --git a/isisd/isis_memory.h b/isisd/isis_memory.h index 3ef1c5bf0b..5bcd2a3983 100644 --- a/isisd/isis_memory.h +++ b/isisd/isis_memory.h @@ -45,5 +45,6 @@ DECLARE_MTYPE(ISIS_EXT_ROUTE) DECLARE_MTYPE(ISIS_EXT_INFO) DECLARE_MTYPE(ISIS_MPLS_TE) DECLARE_MTYPE(ISIS_ACL_NAME) +DECLARE_MTYPE(ISIS_PLIST_NAME) #endif /* _QUAGGA_ISIS_MEMORY_H */ diff --git a/isisd/isis_nb.c b/isisd/isis_nb.c index c3d2f238dd..a02e6a45b1 100644 --- a/isisd/isis_nb.c +++ b/isisd/isis_nb.c @@ -485,6 +485,14 @@ const struct frr_yang_module_info frr_isisd_info = { } }, { + .xpath = "/frr-isisd:isis/instance/fast-reroute/level-1/remote-lfa/prefix-list", + .cbs = { + .cli_show = cli_show_isis_frr_remote_lfa_plist, + .modify = isis_instance_fast_reroute_level_1_remote_lfa_prefix_list_modify, + .destroy = isis_instance_fast_reroute_level_1_remote_lfa_prefix_list_destroy, + } + }, + { .xpath = "/frr-isisd:isis/instance/fast-reroute/level-2/lfa/load-sharing", .cbs = { .cli_show = cli_show_isis_frr_lfa_load_sharing, @@ -514,6 +522,14 @@ const struct frr_yang_module_info frr_isisd_info = { } }, { + .xpath = "/frr-isisd:isis/instance/fast-reroute/level-2/remote-lfa/prefix-list", + .cbs = { + .cli_show = cli_show_isis_frr_remote_lfa_plist, + .modify = isis_instance_fast_reroute_level_2_remote_lfa_prefix_list_modify, + .destroy = isis_instance_fast_reroute_level_2_remote_lfa_prefix_list_destroy, + } + }, + { .xpath = "/frr-isisd:isis/instance/log-adjacency-changes", .cbs = { .cli_show = cli_show_isis_log_adjacency, @@ -927,6 +943,20 @@ const struct frr_yang_module_info frr_isisd_info = { } }, { + .xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/remote-lfa/enable", + .cbs = { + .modify = lib_interface_isis_fast_reroute_level_1_remote_lfa_enable_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/remote-lfa/maximum-metric", + .cbs = { + .cli_show = cli_show_frr_remote_lfa_max_metric, + .modify = lib_interface_isis_fast_reroute_level_1_remote_lfa_maximum_metric_modify, + .destroy = lib_interface_isis_fast_reroute_level_1_remote_lfa_maximum_metric_destroy, + } + }, + { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/ti-lfa/enable", .cbs = { .modify = lib_interface_isis_fast_reroute_level_1_ti_lfa_enable_modify, @@ -953,6 +983,20 @@ const struct frr_yang_module_info frr_isisd_info = { } }, { + .xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/remote-lfa/enable", + .cbs = { + .modify = lib_interface_isis_fast_reroute_level_2_remote_lfa_enable_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/remote-lfa/maximum-metric", + .cbs = { + .cli_show = cli_show_frr_remote_lfa_max_metric, + .modify = lib_interface_isis_fast_reroute_level_2_remote_lfa_maximum_metric_modify, + .destroy = lib_interface_isis_fast_reroute_level_2_remote_lfa_maximum_metric_destroy, + } + }, + { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/ti-lfa/enable", .cbs = { .modify = lib_interface_isis_fast_reroute_level_2_ti_lfa_enable_modify, diff --git a/isisd/isis_nb.h b/isisd/isis_nb.h index f529f20861..679bc6345d 100644 --- a/isisd/isis_nb.h +++ b/isisd/isis_nb.h @@ -183,6 +183,10 @@ int isis_instance_fast_reroute_level_1_lfa_tiebreaker_destroy( struct nb_cb_destroy_args *args); int isis_instance_fast_reroute_level_1_lfa_tiebreaker_type_modify( struct nb_cb_modify_args *args); +int isis_instance_fast_reroute_level_1_remote_lfa_prefix_list_modify( + struct nb_cb_modify_args *args); +int isis_instance_fast_reroute_level_1_remote_lfa_prefix_list_destroy( + struct nb_cb_destroy_args *args); int isis_instance_fast_reroute_level_2_lfa_load_sharing_modify( struct nb_cb_modify_args *args); int isis_instance_fast_reroute_level_2_lfa_priority_limit_modify( @@ -195,6 +199,10 @@ int isis_instance_fast_reroute_level_2_lfa_tiebreaker_destroy( struct nb_cb_destroy_args *args); int isis_instance_fast_reroute_level_2_lfa_tiebreaker_type_modify( struct nb_cb_modify_args *args); +int isis_instance_fast_reroute_level_2_remote_lfa_prefix_list_modify( + struct nb_cb_modify_args *args); +int isis_instance_fast_reroute_level_2_remote_lfa_prefix_list_destroy( + struct nb_cb_destroy_args *args); int isis_instance_log_adjacency_changes_modify(struct nb_cb_modify_args *args); int isis_instance_mpls_te_create(struct nb_cb_create_args *args); int isis_instance_mpls_te_destroy(struct nb_cb_destroy_args *args); @@ -300,6 +308,12 @@ int lib_interface_isis_fast_reroute_level_1_lfa_exclude_interface_create( struct nb_cb_create_args *args); int lib_interface_isis_fast_reroute_level_1_lfa_exclude_interface_destroy( struct nb_cb_destroy_args *args); +int lib_interface_isis_fast_reroute_level_1_remote_lfa_enable_modify( + struct nb_cb_modify_args *args); +int lib_interface_isis_fast_reroute_level_1_remote_lfa_maximum_metric_modify( + struct nb_cb_modify_args *args); +int lib_interface_isis_fast_reroute_level_1_remote_lfa_maximum_metric_destroy( + struct nb_cb_destroy_args *args); int lib_interface_isis_fast_reroute_level_1_ti_lfa_enable_modify( struct nb_cb_modify_args *args); int lib_interface_isis_fast_reroute_level_1_ti_lfa_node_protection_modify( @@ -310,6 +324,12 @@ int lib_interface_isis_fast_reroute_level_2_lfa_exclude_interface_create( struct nb_cb_create_args *args); int lib_interface_isis_fast_reroute_level_2_lfa_exclude_interface_destroy( struct nb_cb_destroy_args *args); +int lib_interface_isis_fast_reroute_level_2_remote_lfa_enable_modify( + struct nb_cb_modify_args *args); +int lib_interface_isis_fast_reroute_level_2_remote_lfa_maximum_metric_modify( + struct nb_cb_modify_args *args); +int lib_interface_isis_fast_reroute_level_2_remote_lfa_maximum_metric_destroy( + struct nb_cb_destroy_args *args); int lib_interface_isis_fast_reroute_level_2_ti_lfa_enable_modify( struct nb_cb_modify_args *args); int lib_interface_isis_fast_reroute_level_2_ti_lfa_node_protection_modify( @@ -467,6 +487,8 @@ void cli_show_isis_frr_lfa_tiebreaker(struct vty *vty, struct lyd_node *dnode, bool show_defaults); void cli_show_isis_frr_lfa_load_sharing(struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_isis_frr_remote_lfa_plist(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); void cli_show_ip_isis_passive(struct vty *vty, struct lyd_node *dnode, bool show_defaults); void cli_show_ip_isis_password(struct vty *vty, struct lyd_node *dnode, @@ -503,6 +525,8 @@ void cli_show_ip_isis_frr(struct vty *vty, struct lyd_node *dnode, bool show_defaults); void cli_show_frr_lfa_exclude_interface(struct vty *vty, struct lyd_node *dnode, bool show_defaults); +void cli_show_frr_remote_lfa_max_metric(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); void cli_show_ip_isis_circ_type(struct vty *vty, struct lyd_node *dnode, bool show_defaults); void cli_show_ip_isis_network_type(struct vty *vty, struct lyd_node *dnode, diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c index 2f7469b1b1..ed0fea8824 100644 --- a/isisd/isis_nb_config.c +++ b/isisd/isis_nb_config.c @@ -28,6 +28,7 @@ #include "log.h" #include "bfd.h" #include "filter.h" +#include "plist.h" #include "spf_backoff.h" #include "lib_errors.h" #include "vrf.h" @@ -1552,6 +1553,45 @@ int isis_instance_fast_reroute_level_1_lfa_tiebreaker_type_modify( } /* + * XPath: /frr-isisd:isis/instance/fast-reroute/level-1/remote-lfa/prefix-list + */ +int isis_instance_fast_reroute_level_1_remote_lfa_prefix_list_modify( + struct nb_cb_modify_args *args) +{ + struct isis_area *area; + const char *plist_name; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + area = nb_running_get_entry(args->dnode, NULL, true); + plist_name = yang_dnode_get_string(args->dnode, NULL); + + area->rlfa_plist_name[0] = XSTRDUP(MTYPE_ISIS_PLIST_NAME, plist_name); + area->rlfa_plist[0] = prefix_list_lookup(AFI_IP, plist_name); + lsp_regenerate_schedule(area, area->is_type, 0); + + return NB_OK; +} + +int isis_instance_fast_reroute_level_1_remote_lfa_prefix_list_destroy( + struct nb_cb_destroy_args *args) +{ + struct isis_area *area; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + area = nb_running_get_entry(args->dnode, NULL, true); + + XFREE(MTYPE_ISIS_PLIST_NAME, area->rlfa_plist_name[0]); + area->rlfa_plist[0] = NULL; + lsp_regenerate_schedule(area, area->is_type, 0); + + return NB_OK; +} + +/* * XPath: /frr-isisd:isis/instance/fast-reroute/level-2/lfa/load-sharing */ int isis_instance_fast_reroute_level_2_lfa_load_sharing_modify( @@ -1662,6 +1702,45 @@ int isis_instance_fast_reroute_level_2_lfa_tiebreaker_type_modify( } /* + * XPath: /frr-isisd:isis/instance/fast-reroute/level-2/remote-lfa/prefix-list + */ +int isis_instance_fast_reroute_level_2_remote_lfa_prefix_list_modify( + struct nb_cb_modify_args *args) +{ + struct isis_area *area; + const char *plist_name; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + area = nb_running_get_entry(args->dnode, NULL, true); + plist_name = yang_dnode_get_string(args->dnode, NULL); + + area->rlfa_plist_name[1] = XSTRDUP(MTYPE_ISIS_PLIST_NAME, plist_name); + area->rlfa_plist[1] = prefix_list_lookup(AFI_IP, plist_name); + lsp_regenerate_schedule(area, area->is_type, 0); + + return NB_OK; +} + +int isis_instance_fast_reroute_level_2_remote_lfa_prefix_list_destroy( + struct nb_cb_destroy_args *args) +{ + struct isis_area *area; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + area = nb_running_get_entry(args->dnode, NULL, true); + + XFREE(MTYPE_ISIS_PLIST_NAME, area->rlfa_plist_name[1]); + area->rlfa_plist[1] = NULL; + lsp_regenerate_schedule(area, area->is_type, 0); + + return NB_OK; +} + +/* * XPath: /frr-isisd:isis/instance/log-adjacency-changes */ int isis_instance_log_adjacency_changes_modify(struct nb_cb_modify_args *args) @@ -3448,6 +3527,74 @@ int lib_interface_isis_fast_reroute_level_1_lfa_exclude_interface_destroy( /* * XPath: + * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/remote-lfa/enable + */ +int lib_interface_isis_fast_reroute_level_1_remote_lfa_enable_modify( + struct nb_cb_modify_args *args) +{ + struct isis_area *area; + struct isis_circuit *circuit; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + circuit = nb_running_get_entry(args->dnode, NULL, true); + circuit->rlfa_protection[0] = yang_dnode_get_bool(args->dnode, NULL); + if (circuit->rlfa_protection[0]) + circuit->area->rlfa_protected_links[0]++; + else { + assert(circuit->area->rlfa_protected_links[0] > 0); + circuit->area->rlfa_protected_links[0]--; + } + + area = circuit->area; + lsp_regenerate_schedule(area, area->is_type, 0); + + return NB_OK; +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/remote-lfa/maximum-metric + */ +int lib_interface_isis_fast_reroute_level_1_remote_lfa_maximum_metric_modify( + struct nb_cb_modify_args *args) +{ + struct isis_area *area; + struct isis_circuit *circuit; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + circuit = nb_running_get_entry(args->dnode, NULL, true); + circuit->rlfa_max_metric[0] = yang_dnode_get_uint32(args->dnode, NULL); + + area = circuit->area; + lsp_regenerate_schedule(area, area->is_type, 0); + + return NB_OK; +} + +int lib_interface_isis_fast_reroute_level_1_remote_lfa_maximum_metric_destroy( + struct nb_cb_destroy_args *args) +{ + struct isis_area *area; + struct isis_circuit *circuit; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + circuit = nb_running_get_entry(args->dnode, NULL, true); + circuit->rlfa_max_metric[0] = 0; + + area = circuit->area; + lsp_regenerate_schedule(area, area->is_type, 0); + + return NB_OK; +} + +/* + * XPath: * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/ti-lfa/enable */ int lib_interface_isis_fast_reroute_level_1_ti_lfa_enable_modify( @@ -3571,6 +3718,74 @@ int lib_interface_isis_fast_reroute_level_2_lfa_exclude_interface_destroy( /* * XPath: + * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/remote-lfa/enable + */ +int lib_interface_isis_fast_reroute_level_2_remote_lfa_enable_modify( + struct nb_cb_modify_args *args) +{ + struct isis_area *area; + struct isis_circuit *circuit; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + circuit = nb_running_get_entry(args->dnode, NULL, true); + circuit->rlfa_protection[1] = yang_dnode_get_bool(args->dnode, NULL); + if (circuit->rlfa_protection[1]) + circuit->area->rlfa_protected_links[1]++; + else { + assert(circuit->area->rlfa_protected_links[1] > 0); + circuit->area->rlfa_protected_links[1]--; + } + + area = circuit->area; + lsp_regenerate_schedule(area, area->is_type, 0); + + return NB_OK; +} + +/* + * XPath: + * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/remote-lfa/maximum-metric + */ +int lib_interface_isis_fast_reroute_level_2_remote_lfa_maximum_metric_modify( + struct nb_cb_modify_args *args) +{ + struct isis_area *area; + struct isis_circuit *circuit; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + circuit = nb_running_get_entry(args->dnode, NULL, true); + circuit->rlfa_max_metric[1] = yang_dnode_get_uint32(args->dnode, NULL); + + area = circuit->area; + lsp_regenerate_schedule(area, area->is_type, 0); + + return NB_OK; +} + +int lib_interface_isis_fast_reroute_level_2_remote_lfa_maximum_metric_destroy( + struct nb_cb_destroy_args *args) +{ + struct isis_area *area; + struct isis_circuit *circuit; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + circuit = nb_running_get_entry(args->dnode, NULL, true); + circuit->rlfa_max_metric[1] = 0; + + area = circuit->area; + lsp_regenerate_schedule(area, area->is_type, 0); + + return NB_OK; +} + +/* + * XPath: * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/ti-lfa/enable */ int lib_interface_isis_fast_reroute_level_2_ti_lfa_enable_modify( diff --git a/isisd/isis_route.c b/isisd/isis_route.c index d32f219e98..e1baf351f4 100644 --- a/isisd/isis_route.c +++ b/isisd/isis_route.c @@ -279,6 +279,22 @@ static bool isis_sr_psid_info_same(struct isis_sr_psid_info *new, return true; } +static bool isis_label_stack_same(struct mpls_label_stack *new, + struct mpls_label_stack *old) +{ + if (!new && !old) + return true; + if (!new || !old) + return false; + if (new->num_labels != old->num_labels) + return false; + if (memcmp(&new->label, &old->label, + sizeof(mpls_label_t) * new->num_labels)) + return false; + + return true; +} + static int isis_route_info_same(struct isis_route_info *new, struct isis_route_info *old, char *buf, size_t buf_size) @@ -327,6 +343,12 @@ static int isis_route_info_same(struct isis_route_info *new, snprintf(buf, buf_size, "nhop SR label"); return 0; } + if (!isis_label_stack_same(new_nh->label_stack, + old_nh->label_stack)) { + if (buf) + snprintf(buf, buf_size, "nhop label stack"); + return 0; + } } /* only the resync flag needs to be checked */ @@ -400,8 +422,8 @@ isis_route_create(struct prefix *prefix, struct prefix_ipv6 *src_p, return route_info; } -static void isis_route_delete(struct isis_area *area, struct route_node *rode, - struct route_table *table) +void isis_route_delete(struct isis_area *area, struct route_node *rode, + struct route_table *table) { struct isis_route_info *rinfo; char buff[SRCDEST2STR_BUFFER]; @@ -466,9 +488,6 @@ static void isis_route_update(struct isis_area *area, struct prefix *prefix, SET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC); } else { - if (!CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) - return; - /* Uninstall Prefix-SID label. */ if (route_info->sr.present) isis_zebra_prefix_sid_uninstall( @@ -516,6 +535,10 @@ static void _isis_route_verify_table(struct isis_area *area, rinfo->backup = rnode_bck->info; UNSET_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); + } else if (rinfo->backup) { + rinfo->backup = NULL; + UNSET_FLAG(rinfo->flag, + ISIS_ROUTE_FLAG_ZEBRA_SYNCED); } } @@ -629,6 +652,10 @@ void isis_route_verify_merge(struct isis_area *area, rinfo->backup = rnode_bck->info; UNSET_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); + } else if (rinfo->backup) { + rinfo->backup = NULL; + UNSET_FLAG(rinfo->flag, + ISIS_ROUTE_FLAG_ZEBRA_SYNCED); } mrnode = srcdest_rnode_get(merge, prefix, src_p); diff --git a/isisd/isis_route.h b/isisd/isis_route.h index 0d4f884959..d6763ec76c 100644 --- a/isisd/isis_route.h +++ b/isisd/isis_route.h @@ -63,6 +63,8 @@ isis_route_create(struct prefix *prefix, struct prefix_ipv6 *src_p, uint32_t cost, uint32_t depth, struct isis_sr_psid_info *sr, struct list *adjacencies, bool allow_ecmp, struct isis_area *area, struct route_table *table); +void isis_route_delete(struct isis_area *area, struct route_node *rode, + struct route_table *table); /* Walk the given table and install new routes to zebra and remove old ones. * route status is tracked using ISIS_ROUTE_FLAG_ACTIVE */ diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 57b1d66c22..dee082fce1 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -56,6 +56,7 @@ #include "isis_csm.h" #include "isis_mt.h" #include "isis_tlvs.h" +#include "isis_zebra.h" #include "fabricd.h" #include "isis_spf_private.h" @@ -354,7 +355,10 @@ struct isis_spftree *isis_spftree_new(struct isis_area *area, tree->tree_id = tree_id; tree->family = (tree->tree_id == SPFTREE_IPV4) ? AF_INET : AF_INET6; tree->flags = flags; - if (tree->type == SPF_TYPE_TI_LFA) { + isis_rlfa_list_init(tree); + tree->lfa.remote.pc_spftrees = list_new(); + tree->lfa.remote.pc_spftrees->del = (void (*)(void *))isis_spftree_del; + if (tree->type == SPF_TYPE_RLFA || tree->type == SPF_TYPE_TI_LFA) { isis_spf_node_list_init(&tree->lfa.p_space); isis_spf_node_list_init(&tree->lfa.q_space); } @@ -366,7 +370,11 @@ void isis_spftree_del(struct isis_spftree *spftree) { hash_clean(spftree->prefix_sids, NULL); hash_free(spftree->prefix_sids); - if (spftree->type == SPF_TYPE_TI_LFA) { + isis_zebra_rlfa_unregister_all(spftree); + isis_rlfa_list_clear(spftree); + list_delete(&spftree->lfa.remote.pc_spftrees); + if (spftree->type == SPF_TYPE_RLFA + || spftree->type == SPF_TYPE_TI_LFA) { isis_spf_node_list_clear(&spftree->lfa.q_space); isis_spf_node_list_clear(&spftree->lfa.p_space); } @@ -820,7 +828,8 @@ lspfragloop: #endif /* EXTREME_DEBUG */ if (no_overload) { - if (pseudo_lsp || spftree->mtid == ISIS_MT_IPV4_UNICAST) { + if ((pseudo_lsp || spftree->mtid == ISIS_MT_IPV4_UNICAST) + && spftree->area->oldmetric) { struct isis_oldstyle_reach *r; for (r = (struct isis_oldstyle_reach *) lsp->tlvs->oldstyle_reach.head; @@ -848,42 +857,47 @@ lspfragloop: } } - struct isis_item_list *te_neighs = NULL; - if (pseudo_lsp || spftree->mtid == ISIS_MT_IPV4_UNICAST) - te_neighs = &lsp->tlvs->extended_reach; - else - te_neighs = isis_lookup_mt_items(&lsp->tlvs->mt_reach, - spftree->mtid); - - struct isis_extended_reach *er; - for (er = te_neighs - ? (struct isis_extended_reach *) - te_neighs->head - : NULL; - er; er = er->next) { - /* C.2.6 a) */ - /* Two way connectivity */ - if (!LSP_PSEUDO_ID(er->id) - && !memcmp(er->id, root_sysid, ISIS_SYS_ID_LEN)) - continue; - if (!pseudo_lsp - && !memcmp(er->id, null_sysid, ISIS_SYS_ID_LEN)) - continue; - dist = cost - + (CHECK_FLAG(spftree->flags, - F_SPFTREE_HOPCOUNT_METRIC) - ? 1 - : er->metric); - process_N(spftree, - LSP_PSEUDO_ID(er->id) ? VTYPE_PSEUDO_TE_IS - : VTYPE_NONPSEUDO_TE_IS, - (void *)er->id, dist, depth + 1, NULL, - parent); + if (spftree->area->newmetric) { + struct isis_item_list *te_neighs = NULL; + if (pseudo_lsp || spftree->mtid == ISIS_MT_IPV4_UNICAST) + te_neighs = &lsp->tlvs->extended_reach; + else + te_neighs = isis_lookup_mt_items( + &lsp->tlvs->mt_reach, spftree->mtid); + + struct isis_extended_reach *er; + for (er = te_neighs ? (struct isis_extended_reach *) + te_neighs->head + : NULL; + er; er = er->next) { + /* C.2.6 a) */ + /* Two way connectivity */ + if (!LSP_PSEUDO_ID(er->id) + && !memcmp(er->id, root_sysid, + ISIS_SYS_ID_LEN)) + continue; + if (!pseudo_lsp + && !memcmp(er->id, null_sysid, + ISIS_SYS_ID_LEN)) + continue; + dist = cost + + (CHECK_FLAG(spftree->flags, + F_SPFTREE_HOPCOUNT_METRIC) + ? 1 + : er->metric); + process_N(spftree, + LSP_PSEUDO_ID(er->id) + ? VTYPE_PSEUDO_TE_IS + : VTYPE_NONPSEUDO_TE_IS, + (void *)er->id, dist, depth + 1, NULL, + parent); + } } } if (!fabricd && !pseudo_lsp && spftree->family == AF_INET - && spftree->mtid == ISIS_MT_IPV4_UNICAST) { + && spftree->mtid == ISIS_MT_IPV4_UNICAST + && spftree->area->oldmetric) { struct isis_item_list *reachs[] = { &lsp->tlvs->oldstyle_ip_reach, &lsp->tlvs->oldstyle_ip_reach_ext}; @@ -908,6 +922,10 @@ lspfragloop: } } + /* we can skip all the rest if we're using metric style narrow */ + if (!spftree->area->newmetric) + goto end; + if (!pseudo_lsp && spftree->family == AF_INET) { struct isis_item_list *ipv4_reachs; if (spftree->mtid == ISIS_MT_IPV4_UNICAST) @@ -1027,6 +1045,7 @@ lspfragloop: } } +end: if (fragnode == NULL) fragnode = listhead(lsp->lspu.frags); else @@ -1429,6 +1448,9 @@ static void init_spt(struct isis_spftree *spftree, int mtid) list_delete_all_node(spftree->sadj_list); isis_vertex_queue_clear(&spftree->tents); isis_vertex_queue_clear(&spftree->paths); + isis_zebra_rlfa_unregister_all(spftree); + isis_rlfa_list_clear(spftree); + list_delete_all_node(spftree->lfa.remote.pc_spftrees); memset(&spftree->lfa.protection_counters, 0, sizeof(spftree->lfa.protection_counters)); @@ -1502,12 +1524,13 @@ static void spf_path_process(struct isis_spftree *spftree, priority = spf_prefix_priority(spftree, vertex); vertex->N.ip.priority = priority; if (vertex->depth == 1 || listcount(vertex->Adj_N) > 0) { + struct isis_spftree *pre_spftree; struct route_table *route_table; bool allow_ecmp; - if (spftree->type == SPF_TYPE_TI_LFA) { - struct isis_spftree *pre_spftree; - + switch (spftree->type) { + case SPF_TYPE_RLFA: + case SPF_TYPE_TI_LFA: if (priority > area->lfa_priority_limit[level - 1]) { if (IS_DEBUG_LFA) @@ -1520,7 +1543,16 @@ static void spf_path_process(struct isis_spftree *spftree, sizeof(buff))); return; } + break; + default: + break; + } + switch (spftree->type) { + case SPF_TYPE_RLFA: + isis_rlfa_check(spftree, vertex); + return; + case SPF_TYPE_TI_LFA: if (isis_tilfa_check(spftree, vertex) != 0) return; @@ -1529,7 +1561,8 @@ static void spf_path_process(struct isis_spftree *spftree, allow_ecmp = area->lfa_load_sharing[level - 1]; pre_spftree->lfa.protection_counters .tilfa[vertex->N.ip.priority] += 1; - } else { + break; + default: route_table = spftree->route_table; allow_ecmp = true; @@ -1544,6 +1577,7 @@ static void spf_path_process(struct isis_spftree *spftree, spftree->lfa.protection_counters .ecmp[priority] += 1; } + break; } isis_route_create( @@ -1834,6 +1868,7 @@ int _isis_spf_schedule(struct isis_area *area, int level, area->area_tag, level, diff, func, file, line); } + thread_cancel(&area->t_rlfa_rib_update); if (area->spf_delay_ietf[level - 1]) { /* Need to call schedule function also if spf delay is running * to diff --git a/isisd/isis_spf.h b/isisd/isis_spf.h index 5b6fcdaf68..5b3aa59379 100644 --- a/isisd/isis_spf.h +++ b/isisd/isis_spf.h @@ -31,6 +31,7 @@ struct isis_spftree; enum spf_type { SPF_TYPE_FORWARD = 1, SPF_TYPE_REVERSE, + SPF_TYPE_RLFA, SPF_TYPE_TI_LFA, }; diff --git a/isisd/isis_spf_private.h b/isisd/isis_spf_private.h index b7f326ca86..79dfa3e164 100644 --- a/isisd/isis_spf_private.h +++ b/isisd/isis_spf_private.h @@ -76,7 +76,9 @@ struct isis_vertex { struct list *parents; /* list of parents for ECMP */ struct hash *firsthops; /* first two hops to neighbor */ uint64_t insert_counter; + uint8_t flags; }; +#define F_ISIS_VERTEX_LFA_PROTECTED 0x01 /* Vertex Queue and associated functions */ @@ -349,6 +351,21 @@ struct isis_spftree { struct isis_spf_nodes p_space; struct isis_spf_nodes q_space; + /* Remote LFA related information. */ + struct { + /* List of RLFAs eligible to be installed. */ + struct rlfa_tree_head rlfas; + + /* + * RLFA post-convergence SPTs (needed to activate RLFAs + * once label information is received from LDP). + */ + struct list *pc_spftrees; + + /* RLFA maximum metric (or zero if absent). */ + uint32_t max_metric; + } remote; + /* Protection counters. */ struct { uint32_t lfa[SPF_PREFIX_PRIO_MAX]; diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index f08737c2c1..703532234a 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -47,6 +47,8 @@ #include "isisd/isis_circuit.h" #include "isisd/isis_csm.h" #include "isisd/isis_lsp.h" +#include "isisd/isis_spf.h" +#include "isisd/isis_spf_private.h" #include "isisd/isis_route.h" #include "isisd/isis_zebra.h" #include "isisd/isis_adjacency.h" @@ -540,6 +542,72 @@ void isis_zebra_redistribute_unset(afi_t afi, int type) type, 0, VRF_DEFAULT); } +/** + * Register RLFA with LDP. + */ +int isis_zebra_rlfa_register(struct isis_spftree *spftree, struct rlfa *rlfa) +{ + struct isis_area *area = spftree->area; + struct zapi_rlfa_request zr = {}; + int ret; + + if (!zclient) + return 0; + + zr.igp.vrf_id = area->isis->vrf_id; + zr.igp.protocol = ZEBRA_ROUTE_ISIS; + strlcpy(zr.igp.isis.area_tag, area->area_tag, + sizeof(zr.igp.isis.area_tag)); + zr.igp.isis.spf.tree_id = spftree->tree_id; + zr.igp.isis.spf.level = spftree->level; + zr.igp.isis.spf.run_id = spftree->runcount; + zr.destination = rlfa->prefix; + zr.pq_address = rlfa->pq_address; + + zlog_debug("ISIS-LFA: registering RLFA %pFX@%pI4 with LDP", + &rlfa->prefix, &rlfa->pq_address); + + ret = zclient_send_opaque_unicast(zclient, LDP_RLFA_REGISTER, + ZEBRA_ROUTE_LDP, 0, 0, + (const uint8_t *)&zr, sizeof(zr)); + if (ret == ZCLIENT_SEND_FAILURE) { + zlog_warn("ISIS-LFA: failed to register RLFA with LDP"); + return -1; + } + + return 0; +} + +/** + * Unregister all RLFAs from the given SPF tree with LDP. + */ +void isis_zebra_rlfa_unregister_all(struct isis_spftree *spftree) +{ + struct isis_area *area = spftree->area; + struct zapi_rlfa_igp igp = {}; + int ret; + + if (!zclient || spftree->type != SPF_TYPE_FORWARD + || CHECK_FLAG(spftree->flags, F_SPFTREE_NO_ADJACENCIES)) + return; + + if (IS_DEBUG_LFA) + zlog_debug("ISIS-LFA: unregistering all RLFAs with LDP"); + + igp.vrf_id = area->isis->vrf_id; + igp.protocol = ZEBRA_ROUTE_ISIS; + strlcpy(igp.isis.area_tag, area->area_tag, sizeof(igp.isis.area_tag)); + igp.isis.spf.tree_id = spftree->tree_id; + igp.isis.spf.level = spftree->level; + igp.isis.spf.run_id = spftree->runcount; + + ret = zclient_send_opaque_unicast(zclient, LDP_RLFA_UNREGISTER_ALL, + ZEBRA_ROUTE_LDP, 0, 0, + (const uint8_t *)&igp, sizeof(igp)); + if (ret == ZCLIENT_SEND_FAILURE) + zlog_warn("ISIS-LFA: failed to unregister RLFA with LDP"); +} + /* Label Manager Functions */ /** @@ -659,6 +727,7 @@ void isis_zebra_vrf_register(struct isis *isis) static void isis_zebra_connected(struct zclient *zclient) { zclient_send_reg_requests(zclient, VRF_DEFAULT); + zclient_register_opaque(zclient, LDP_RLFA_LABELS); } /* @@ -670,6 +739,7 @@ static int isis_opaque_msg_handler(ZAPI_CALLBACK_ARGS) struct zapi_opaque_msg info; struct ldp_igp_sync_if_state state; struct ldp_igp_sync_announce announce; + struct zapi_rlfa_response rlfa; int ret = 0; s = zclient->ibuf; @@ -685,6 +755,10 @@ static int isis_opaque_msg_handler(ZAPI_CALLBACK_ARGS) STREAM_GET(&announce, s, sizeof(announce)); ret = isis_ldp_sync_announce_update(announce); break; + case LDP_RLFA_LABELS: + STREAM_GET(&rlfa, s, sizeof(rlfa)); + isis_rlfa_process_ldp_response(&rlfa); + break; default: break; } @@ -704,6 +778,7 @@ static int isis_zebra_client_close_notify(ZAPI_CALLBACK_ARGS) return -1; isis_ldp_sync_handle_client_close(&info); + isis_ldp_rlfa_handle_client_close(&info); return ret; } @@ -742,6 +817,7 @@ void isis_zebra_init(struct thread_master *master, int instance) void isis_zebra_stop(void) { + zclient_unregister_opaque(zclient, LDP_RLFA_LABELS); zclient_stop(zclient_sync); zclient_free(zclient_sync); zclient_stop(zclient); diff --git a/isisd/isis_zebra.h b/isisd/isis_zebra.h index c5c52a6bc6..b44ec4f085 100644 --- a/isisd/isis_zebra.h +++ b/isisd/isis_zebra.h @@ -59,6 +59,8 @@ void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra); int isis_distribute_list_update(int routetype); void isis_zebra_redistribute_set(afi_t afi, int type); void isis_zebra_redistribute_unset(afi_t afi, int type); +int isis_zebra_rlfa_register(struct isis_spftree *spftree, struct rlfa *rlfa); +void isis_zebra_rlfa_unregister_all(struct isis_spftree *spftree); bool isis_zebra_label_manager_ready(void); int isis_zebra_label_manager_connect(void); int isis_zebra_request_label_range(uint32_t base, uint32_t chunk_size); diff --git a/isisd/isisd.c b/isisd/isisd.c index 827e022baf..eabebab4e0 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -32,6 +32,7 @@ #include "if.h" #include "hash.h" #include "filter.h" +#include "plist.h" #include "stream.h" #include "prefix.h" #include "table.h" @@ -485,6 +486,7 @@ void isis_area_destroy(struct isis_area *area) thread_cancel(&area->t_tick); thread_cancel(&area->t_lsp_refresh[0]); thread_cancel(&area->t_lsp_refresh[1]); + thread_cancel(&area->t_rlfa_rib_update); thread_cancel_event(master, area); @@ -649,6 +651,34 @@ void isis_filter_update(struct access_list *access) } } +void isis_prefix_list_update(struct prefix_list *plist) +{ + struct isis *isis; + struct isis_area *area; + struct listnode *node, *anode; + + for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) { + for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) { + for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; + level++) { + const char *plist_name = + prefix_list_name(plist); + + if (!area->rlfa_plist_name[level - 1]) + continue; + + if (!strmatch(area->rlfa_plist_name[level - 1], + plist_name)) + continue; + + area->rlfa_plist[level - 1] = + prefix_list_lookup(AFI_IP, plist_name); + lsp_regenerate_schedule(area, area->is_type, 0); + } + } + } +} + #ifdef FABRICD static void area_set_mt_enabled(struct isis_area *area, uint16_t mtid, bool enabled) diff --git a/isisd/isisd.h b/isisd/isisd.h index 4618d14af3..9b903eed48 100644 --- a/isisd/isisd.h +++ b/isisd/isisd.h @@ -131,6 +131,7 @@ struct isis_area { struct thread *t_tick; /* LSP walker */ struct thread *t_lsp_refresh[ISIS_LEVELS]; struct timeval last_lsp_refresh_event[ISIS_LEVELS]; + struct thread *t_rlfa_rib_update; /* t_lsp_refresh is used in two ways: * a) regular refresh of LSPs * b) (possibly throttled) updates to LSPs @@ -197,6 +198,9 @@ struct isis_area { size_t lfa_load_sharing[ISIS_LEVELS]; enum spf_prefix_priority lfa_priority_limit[ISIS_LEVELS]; struct lfa_tiebreaker_tree_head lfa_tiebreakers[ISIS_LEVELS]; + char *rlfa_plist_name[ISIS_LEVELS]; + struct prefix_list *rlfa_plist[ISIS_LEVELS]; + size_t rlfa_protected_links[ISIS_LEVELS]; size_t tilfa_protected_links[ISIS_LEVELS]; /* Counters */ uint32_t circuit_state_changes; @@ -240,6 +244,7 @@ struct isis_area *isis_area_lookup_by_vrf(const char *area_tag, int isis_area_get(struct vty *vty, const char *area_tag); void isis_area_destroy(struct isis_area *area); void isis_filter_update(struct access_list *access); +void isis_prefix_list_update(struct prefix_list *plist); void print_debug(struct vty *, int, int); struct isis_lsp *lsp_for_arg(struct lspdb_head *head, const char *argv, struct isis *isis); diff --git a/ldpd/adjacency.c b/ldpd/adjacency.c index 795a41491c..d390e70ad0 100644 --- a/ldpd/adjacency.c +++ b/ldpd/adjacency.c @@ -183,7 +183,8 @@ adj_itimer(struct thread *thread) if (adj->source.type == HELLO_TARGETED) { if (!(adj->source.target->flags & F_TNBR_CONFIGURED) && - adj->source.target->pw_count == 0) { + adj->source.target->pw_count == 0 && + adj->source.target->rlfa_count == 0) { /* remove dynamic targeted neighbor */ tnbr_del(leconf, adj->source.target); return (0); @@ -259,7 +260,7 @@ struct tnbr * tnbr_check(struct ldpd_conf *xconf, struct tnbr *tnbr) { if (!(tnbr->flags & (F_TNBR_CONFIGURED|F_TNBR_DYNAMIC)) && - tnbr->pw_count == 0) { + tnbr->pw_count == 0 && tnbr->rlfa_count == 0) { tnbr_del(xconf, tnbr); return (NULL); } diff --git a/ldpd/hello.c b/ldpd/hello.c index 327cb32434..5aa14ed067 100644 --- a/ldpd/hello.c +++ b/ldpd/hello.c @@ -67,7 +67,8 @@ send_hello(enum hello_type type, struct iface_af *ia, struct tnbr *tnbr) af = tnbr->af; holdtime = tnbr_get_hello_holdtime(tnbr); flags = F_HELLO_TARGETED; - if ((tnbr->flags & F_TNBR_CONFIGURED) || tnbr->pw_count) + if ((tnbr->flags & F_TNBR_CONFIGURED) || tnbr->pw_count + || tnbr->rlfa_count) flags |= F_HELLO_REQ_TARG; fd = (ldp_af_global_get(&global, af))->ldp_edisc_socket; diff --git a/ldpd/lde.c b/ldpd/lde.c index 5ed0ed4520..69338b8bad 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -27,6 +27,7 @@ #include "log.h" #include "lde.h" #include "ldp_debug.h" +#include "rlfa.h" #include <lib/log.h> #include "memory.h" @@ -444,6 +445,10 @@ lde_dispatch_parent(struct thread *thread) int shut = 0; struct fec fec; struct ldp_access *laccess; + struct ldp_rlfa_node *rnode, *rntmp; + struct ldp_rlfa_client *rclient; + struct zapi_rlfa_request *rlfa_req; + struct zapi_rlfa_igp *rlfa_igp; iev->ev_read = NULL; @@ -650,6 +655,42 @@ lde_dispatch_parent(struct thread *thread) lde_check_filter_af(AF_INET6, &ldeconf->ipv6, laccess->name); break; + case IMSG_RLFA_REG: + if (imsg.hdr.len != IMSG_HEADER_SIZE + + sizeof(struct zapi_rlfa_request)) { + log_warnx("%s: wrong imsg len", __func__); + break; + } + rlfa_req = imsg.data; + rnode = rlfa_node_find(&rlfa_req->destination, + rlfa_req->pq_address); + if (!rnode) + rnode = rlfa_node_new(&rlfa_req->destination, + rlfa_req->pq_address); + rclient = rlfa_client_find(rnode, &rlfa_req->igp); + if (rclient) + /* RLFA already registered - do nothing */ + break; + rclient = rlfa_client_new(rnode, &rlfa_req->igp); + lde_rlfa_check(rclient); + break; + case IMSG_RLFA_UNREG_ALL: + if (imsg.hdr.len != IMSG_HEADER_SIZE + + sizeof(struct zapi_rlfa_igp)) { + log_warnx("%s: wrong imsg len", __func__); + break; + } + rlfa_igp = imsg.data; + + RB_FOREACH_SAFE (rnode, ldp_rlfa_node_head, + &rlfa_node_tree, rntmp) { + rclient = rlfa_client_find(rnode, rlfa_igp); + if (!rclient) + continue; + + rlfa_client_del(rclient); + } + break; default: log_debug("%s: unexpected imsg %d", __func__, imsg.hdr.type); @@ -876,6 +917,48 @@ lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh) } void +lde_fec2prefix(const struct fec *fec, struct prefix *prefix) +{ + memset(prefix, 0, sizeof(*prefix)); + switch (fec->type) { + case FEC_TYPE_IPV4: + prefix->family = AF_INET; + prefix->u.prefix4 = fec->u.ipv4.prefix; + prefix->prefixlen = fec->u.ipv4.prefixlen; + break; + case FEC_TYPE_IPV6: + prefix->family = AF_INET6; + prefix->u.prefix6 = fec->u.ipv6.prefix; + prefix->prefixlen = fec->u.ipv6.prefixlen; + break; + default: + prefix->family = AF_UNSPEC; + break; + } +} + +void +lde_prefix2fec(const struct prefix *prefix, struct fec *fec) +{ + memset(fec, 0, sizeof(*fec)); + switch (prefix->family) { + case AF_INET: + fec->type = FEC_TYPE_IPV4; + fec->u.ipv4.prefix = prefix->u.prefix4; + fec->u.ipv4.prefixlen = prefix->prefixlen; + break; + case AF_INET6: + fec->type = FEC_TYPE_IPV6; + fec->u.ipv6.prefix = prefix->u.prefix6; + fec->u.ipv6.prefixlen = prefix->prefixlen; + break; + default: + fatalx("lde_prefix2fec: unknown af"); + break; + } +} + +void lde_fec2map(struct fec *fec, struct map *map) { memset(map, 0, sizeof(*map)); @@ -1388,6 +1471,9 @@ lde_nbr_del(struct lde_nbr *ln) RB_FOREACH(f, fec_tree, &ft) { fn = (struct fec_node *)f; + /* Update RLFA clients. */ + lde_rlfa_update_clients(f, ln, MPLS_INVALID_LABEL); + LIST_FOREACH(fnh, &fn->nexthops, entry) { switch (f->type) { case FEC_TYPE_IPV4: diff --git a/ldpd/lde.h b/ldpd/lde.h index 660aeafb34..e09be01ece 100644 --- a/ldpd/lde.h +++ b/ldpd/lde.h @@ -156,6 +156,8 @@ uint32_t lde_update_label(struct fec_node *); void lde_free_label(uint32_t label); void lde_send_change_klabel(struct fec_node *, struct fec_nh *); void lde_send_delete_klabel(struct fec_node *, struct fec_nh *); +void lde_fec2prefix(const struct fec *fec, struct prefix *prefix); +void lde_prefix2fec(const struct prefix *prefix, struct fec *fec); void lde_fec2map(struct fec *, struct map *); void lde_map2fec(struct map *, struct in_addr, struct fec *); void lde_send_labelmapping(struct lde_nbr *, struct fec_node *, diff --git a/ldpd/lde_lib.c b/ldpd/lde_lib.c index 9db931677d..0f91f49920 100644 --- a/ldpd/lde_lib.c +++ b/ldpd/lde_lib.c @@ -23,6 +23,7 @@ #include "ldpe.h" #include "lde.h" #include "log.h" +#include "rlfa.h" #include "mpls.h" @@ -601,6 +602,10 @@ lde_check_mapping(struct map *map, struct lde_nbr *ln, int rcvd_label_mapping) break; } } + + /* Update RLFA clients. */ + lde_rlfa_update_clients(&fec, ln, map->label); + /* LMp.13 & LMp.16: Record the mapping from this peer */ if (me == NULL) me = lde_map_add(ln, fn, 0); @@ -858,6 +863,9 @@ lde_check_withdraw(struct map *map, struct lde_nbr *ln) fnh->remote_label = NO_LABEL; } + /* Update RLFA clients. */ + lde_rlfa_update_clients(&fec, ln, MPLS_INVALID_LABEL); + /* LWd.2: send label release */ lde_send_labelrelease(ln, fn, NULL, map->label); @@ -940,6 +948,9 @@ lde_check_withdraw_wcard(struct map *map, struct lde_nbr *ln) fnh->remote_label = NO_LABEL; } + /* Update RLFA clients. */ + lde_rlfa_update_clients(f, ln, MPLS_INVALID_LABEL); + /* LWd.3: check previously received label mapping */ if (me && (map->label == NO_LABEL || map->label == me->map.label)) diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c index a53854fa56..ea86c2dc03 100644 --- a/ldpd/ldp_zebra.c +++ b/ldpd/ldp_zebra.c @@ -114,12 +114,16 @@ static void ldp_zebra_opaque_register(void) { zclient_register_opaque(zclient, LDP_IGP_SYNC_IF_STATE_REQUEST); + zclient_register_opaque(zclient, LDP_RLFA_REGISTER); + zclient_register_opaque(zclient, LDP_RLFA_UNREGISTER_ALL); } static void ldp_zebra_opaque_unregister(void) { zclient_unregister_opaque(zclient, LDP_IGP_SYNC_IF_STATE_REQUEST); + zclient_unregister_opaque(zclient, LDP_RLFA_REGISTER); + zclient_unregister_opaque(zclient, LDP_RLFA_UNREGISTER_ALL); } int @@ -147,12 +151,29 @@ ldp_sync_zebra_send_announce(void) return 0; } +int ldp_zebra_send_rlfa_labels(struct zapi_rlfa_response *rlfa_labels) +{ + int ret; + + ret = zclient_send_opaque(zclient, LDP_RLFA_LABELS, + (const uint8_t *)rlfa_labels, + sizeof(*rlfa_labels)); + if (ret == ZCLIENT_SEND_FAILURE) { + log_warn("failed to send RLFA labels to IGP"); + return -1; + } + + return 0; +} + static int ldp_zebra_opaque_msg_handler(ZAPI_CALLBACK_ARGS) { struct stream *s; struct zapi_opaque_msg info; struct ldp_igp_sync_if_state_req state_req; + struct zapi_rlfa_igp igp; + struct zapi_rlfa_request rlfa; s = zclient->ibuf; @@ -165,6 +186,14 @@ ldp_zebra_opaque_msg_handler(ZAPI_CALLBACK_ARGS) main_imsg_compose_ldpe(IMSG_LDP_SYNC_IF_STATE_REQUEST, 0, &state_req, sizeof(state_req)); break; + case LDP_RLFA_REGISTER: + STREAM_GET(&rlfa, s, sizeof(rlfa)); + main_imsg_compose_both(IMSG_RLFA_REG, &rlfa, sizeof(rlfa)); + break; + case LDP_RLFA_UNREGISTER_ALL: + STREAM_GET(&igp, s, sizeof(igp)); + main_imsg_compose_both(IMSG_RLFA_UNREG_ALL, &igp, sizeof(igp)); + break; default: break; } diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c index d6da45c862..83e93ebbbc 100644 --- a/ldpd/ldpd.c +++ b/ldpd/ldpd.c @@ -625,6 +625,7 @@ main_dispatch_lde(struct thread *thread) struct imsg imsg; ssize_t n; int shut = 0; + struct zapi_rlfa_response *rlfa_labels; iev->ev_read = NULL; @@ -691,6 +692,15 @@ main_dispatch_lde(struct thread *thread) fatalx("IMSG_ACL_CHECK imsg with wrong len"); ldp_acl_reply(iev, (struct acl_check *)imsg.data); break; + case IMSG_RLFA_LABELS: + if (imsg.hdr.len != IMSG_HEADER_SIZE + + sizeof(struct zapi_rlfa_response)) { + log_warnx("%s: wrong imsg len", __func__); + break; + } + rlfa_labels = imsg.data; + ldp_zebra_send_rlfa_labels(rlfa_labels); + break; default: log_debug("%s: error handling imsg %d", __func__, imsg.hdr.type); diff --git a/ldpd/ldpd.h b/ldpd/ldpd.h index f8a94b4e2a..beb625d8a2 100644 --- a/ldpd/ldpd.h +++ b/ldpd/ldpd.h @@ -157,7 +157,10 @@ enum imsg_type { IMSG_FILTER_UPDATE, IMSG_NBR_SHUTDOWN, IMSG_LDP_SYNC_IF_STATE_REQUEST, - IMSG_LDP_SYNC_IF_STATE_UPDATE + IMSG_LDP_SYNC_IF_STATE_UPDATE, + IMSG_RLFA_REG, + IMSG_RLFA_UNREG_ALL, + IMSG_RLFA_LABELS, }; struct ldpd_init { @@ -373,6 +376,7 @@ struct tnbr { union ldpd_addr addr; int state; uint16_t pw_count; + uint32_t rlfa_count; uint8_t flags; QOBJ_FIELDS }; @@ -875,6 +879,8 @@ extern char ctl_sock_path[MAXPATHLEN]; void ldp_zebra_init(struct thread_master *); void ldp_zebra_destroy(void); int ldp_sync_zebra_send_state_update(struct ldp_igp_sync_if_state *); +int ldp_zebra_send_rlfa_labels(struct zapi_rlfa_response * + rlfa_labels); /* compatibility */ #ifndef __OpenBSD__ diff --git a/ldpd/ldpe.c b/ldpd/ldpe.c index f3f8b85102..6a5a0750bd 100644 --- a/ldpd/ldpe.c +++ b/ldpd/ldpe.c @@ -27,6 +27,7 @@ #include "control.h" #include "log.h" #include "ldp_debug.h" +#include "rlfa.h" #include <lib/log.h> #include "memory.h" @@ -298,7 +299,11 @@ ldpe_dispatch_main(struct thread *thread) int n, shut = 0; struct ldp_access *laccess; struct ldp_igp_sync_if_state_req *ldp_sync_if_state_req; - + struct ldp_rlfa_node *rnode, *rntmp; + struct ldp_rlfa_client *rclient; + struct zapi_rlfa_request *rlfa_req; + struct zapi_rlfa_igp *rlfa_igp; + iev->ev_read = NULL; if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) @@ -569,6 +574,44 @@ ldpe_dispatch_main(struct thread *thread) ldp_sync_if_state_req = imsg.data; ldp_sync_fsm_state_req(ldp_sync_if_state_req); break; + case IMSG_RLFA_REG: + if (imsg.hdr.len != IMSG_HEADER_SIZE + + sizeof(struct zapi_rlfa_request)) { + log_warnx("%s: wrong imsg len", __func__); + break; + } + rlfa_req = imsg.data; + + rnode = rlfa_node_find(&rlfa_req->destination, + rlfa_req->pq_address); + if (!rnode) + rnode = rlfa_node_new(&rlfa_req->destination, + rlfa_req->pq_address); + rclient = rlfa_client_find(rnode, &rlfa_req->igp); + if (rclient) + /* RLFA already registered - do nothing */ + break; + rclient = rlfa_client_new(rnode, &rlfa_req->igp); + ldpe_rlfa_init(rclient); + break; + case IMSG_RLFA_UNREG_ALL: + if (imsg.hdr.len != IMSG_HEADER_SIZE + + sizeof(struct zapi_rlfa_igp)) { + log_warnx("%s: wrong imsg len", __func__); + break; + } + rlfa_igp = imsg.data; + + RB_FOREACH_SAFE (rnode, ldp_rlfa_node_head, + &rlfa_node_tree, rntmp) { + rclient = rlfa_client_find(rnode, rlfa_igp); + if (!rclient) + continue; + + ldpe_rlfa_exit(rclient); + rlfa_client_del(rclient); + } + break; default: log_debug("ldpe_dispatch_main: error handling imsg %d", imsg.hdr.type); diff --git a/ldpd/rlfa.c b/ldpd/rlfa.c new file mode 100644 index 0000000000..697ec08af8 --- /dev/null +++ b/ldpd/rlfa.c @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2020 NetDEF, Inc. + * Renato Westphal + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <zebra.h> + +#include "ldpd.h" +#include "lde.h" +#include "ldpe.h" +#include "log.h" +#include "ldp_debug.h" +#include "rlfa.h" + +#include <lib/log.h> + +struct ldp_rlfa_node_head rlfa_node_tree; + +static int ldp_rlfa_client_compare(const struct ldp_rlfa_client *a, + const struct ldp_rlfa_client *b) +{ + if (a->igp.vrf_id < b->igp.vrf_id) + return -1; + if (a->igp.vrf_id > b->igp.vrf_id) + return 1; + + if (a->igp.protocol < b->igp.protocol) + return -1; + if (a->igp.protocol > b->igp.protocol) + return 1; + + if (a->igp.isis.spf.tree_id < b->igp.isis.spf.tree_id) + return -1; + if (a->igp.isis.spf.tree_id > b->igp.isis.spf.tree_id) + return 1; + + if (a->igp.isis.spf.level < b->igp.isis.spf.level) + return -1; + if (a->igp.isis.spf.level > b->igp.isis.spf.level) + return 1; + + return 0; +} +RB_GENERATE(ldp_rlfa_client_head, ldp_rlfa_client, entry, + ldp_rlfa_client_compare) + +static int ldp_rlfa_node_compare(const struct ldp_rlfa_node *a, + const struct ldp_rlfa_node *b) +{ + if (ntohl(a->pq_address.s_addr) < ntohl(b->pq_address.s_addr)) + return -1; + if (ntohl(a->pq_address.s_addr) > ntohl(b->pq_address.s_addr)) + return 1; + + return prefix_cmp(&a->destination, &b->destination); +} +RB_GENERATE(ldp_rlfa_node_head, ldp_rlfa_node, entry, ldp_rlfa_node_compare) + +struct ldp_rlfa_client *rlfa_client_new(struct ldp_rlfa_node *rnode, + struct zapi_rlfa_igp *igp) +{ + struct ldp_rlfa_client *rclient; + + if ((rclient = calloc(1, sizeof(*rclient))) == NULL) + fatal(__func__); + + rclient->igp = *igp; + rclient->node = rnode; + RB_INSERT(ldp_rlfa_client_head, &rnode->clients, rclient); + + return rclient; +} + +void rlfa_client_del(struct ldp_rlfa_client *rclient) +{ + struct ldp_rlfa_node *rnode = rclient->node; + + RB_REMOVE(ldp_rlfa_client_head, &rnode->clients, rclient); + free(rclient); + + /* Delete RLFA node if it's empty. */ + if (RB_EMPTY(ldp_rlfa_client_head, &rnode->clients)) + rlfa_node_del(rnode); +} + +struct ldp_rlfa_client *rlfa_client_find(struct ldp_rlfa_node *rnode, + struct zapi_rlfa_igp *igp) +{ + struct ldp_rlfa_client rclient; + + rclient.igp = *igp; + return RB_FIND(ldp_rlfa_client_head, &rnode->clients, &rclient); +} + +struct ldp_rlfa_node *rlfa_node_new(const struct prefix *destination, + struct in_addr pq_address) +{ + struct ldp_rlfa_node *rnode; + + if ((rnode = calloc(1, sizeof(*rnode))) == NULL) + fatal(__func__); + + rnode->destination = *destination; + rnode->pq_address = pq_address; + rnode->pq_label = MPLS_INVALID_LABEL; + RB_INIT(ldp_rlfa_client_head, &rnode->clients); + RB_INSERT(ldp_rlfa_node_head, &rlfa_node_tree, rnode); + + return rnode; +} + +void rlfa_node_del(struct ldp_rlfa_node *rnode) +{ + /* Delete RLFA clients. */ + while (!RB_EMPTY(ldp_rlfa_client_head, &rnode->clients)) { + struct ldp_rlfa_client *rclient; + + rclient = RB_ROOT(ldp_rlfa_client_head, &rnode->clients); + rlfa_client_del(rclient); + } + + RB_REMOVE(ldp_rlfa_node_head, &rlfa_node_tree, rnode); + free(rnode); +} + +struct ldp_rlfa_node *rlfa_node_find(const struct prefix *destination, + struct in_addr pq_address) +{ + struct ldp_rlfa_node rnode = {}; + + rnode.destination = *destination; + rnode.pq_address = pq_address; + return RB_FIND(ldp_rlfa_node_head, &rlfa_node_tree, &rnode); +} + +void lde_rlfa_client_send(struct ldp_rlfa_client *rclient) +{ + struct ldp_rlfa_node *rnode = rclient->node; + struct zapi_rlfa_response rlfa_labels = {}; + struct fec fec; + struct fec_node *fn; + struct fec_nh *fnh; + int i = 0; + + /* Fill in inner label (allocated by PQ node). */ + rlfa_labels.igp = rclient->igp; + rlfa_labels.destination = rnode->destination; + rlfa_labels.pq_label = rnode->pq_label; + + /* Fill in outer label(s) (allocated by the nexthop routers). */ + fec.type = FEC_TYPE_IPV4; + fec.u.ipv4.prefix = rnode->pq_address; + fec.u.ipv4.prefixlen = IPV4_MAX_BITLEN; + fn = (struct fec_node *)fec_find(&ft, &fec); + if (!fn) + return; + LIST_FOREACH(fnh, &fn->nexthops, entry) { + if (fnh->remote_label == NO_LABEL) + continue; + + rlfa_labels.nexthops[i].family = fnh->af; + switch (fnh->af) { + case AF_INET: + rlfa_labels.nexthops[i].gate.ipv4 = fnh->nexthop.v4; + break; + case AF_INET6: + rlfa_labels.nexthops[i].gate.ipv6 = fnh->nexthop.v6; + break; + default: + continue; + } + rlfa_labels.nexthops[i].label = fnh->remote_label; + i++; + } + rlfa_labels.nexthop_num = i; + + lde_imsg_compose_parent(IMSG_RLFA_LABELS, 0, &rlfa_labels, + sizeof(rlfa_labels)); +} + +void lde_rlfa_label_update(const struct fec *fec) +{ + struct ldp_rlfa_node *rnode; + + if (fec->type != FEC_TYPE_IPV4 + || fec->u.ipv4.prefixlen != IPV4_MAX_BITLEN) + return; + + /* + * TODO: use an rb-tree lookup to restrict the iteration to the RLFAs + * that were effectivelly affected by the label update. + */ + RB_FOREACH (rnode, ldp_rlfa_node_head, &rlfa_node_tree) { + struct ldp_rlfa_client *rclient; + + if (!IPV4_ADDR_SAME(&rnode->pq_address, &fec->u.ipv4.prefix)) + continue; + + RB_FOREACH (rclient, ldp_rlfa_client_head, &rnode->clients) + lde_rlfa_client_send(rclient); + } +} + +void lde_rlfa_check(struct ldp_rlfa_client *rclient) +{ + struct lde_nbr *ln; + struct lde_map *me; + struct fec fec; + union ldpd_addr pq_address = {}; + + pq_address.v4 = rclient->node->pq_address; + ln = lde_nbr_find_by_addr(AF_INET, &pq_address); + if (!ln) + return; + + lde_prefix2fec(&rclient->node->destination, &fec); + me = (struct lde_map *)fec_find(&ln->recv_map, &fec); + if (!me) + return; + + rclient->node->pq_label = me->map.label; + lde_rlfa_client_send(rclient); +} + +/* + * Check if there's any registered RLFA client for this prefix/neighbor (PQ + * node) and notify about the updated label. + */ +void lde_rlfa_update_clients(struct fec *fec, struct lde_nbr *ln, + uint32_t label) +{ + struct prefix rlfa_dest; + struct ldp_rlfa_node *rnode; + + lde_fec2prefix(fec, &rlfa_dest); + rnode = rlfa_node_find(&rlfa_dest, ln->id); + if (rnode) { + struct ldp_rlfa_client *rclient; + + rnode->pq_label = label; + RB_FOREACH (rclient, ldp_rlfa_client_head, &rnode->clients) + lde_rlfa_client_send(rclient); + } else + lde_rlfa_label_update(fec); +} + +void ldpe_rlfa_init(struct ldp_rlfa_client *rclient) +{ + struct tnbr *tnbr; + union ldpd_addr pq_address = {}; + + pq_address.v4 = rclient->node->pq_address; + tnbr = tnbr_find(leconf, AF_INET, &pq_address); + if (tnbr == NULL) { + tnbr = tnbr_new(AF_INET, &pq_address); + tnbr_update(tnbr); + RB_INSERT(tnbr_head, &leconf->tnbr_tree, tnbr); + } + + tnbr->rlfa_count++; +} + +void ldpe_rlfa_exit(struct ldp_rlfa_client *rclient) +{ + struct tnbr *tnbr; + union ldpd_addr pq_address = {}; + + pq_address.v4 = rclient->node->pq_address; + tnbr = tnbr_find(leconf, AF_INET, &pq_address); + if (tnbr) { + tnbr->rlfa_count--; + tnbr_check(leconf, tnbr); + } +} diff --git a/ldpd/rlfa.h b/ldpd/rlfa.h new file mode 100644 index 0000000000..fe67917e8a --- /dev/null +++ b/ldpd/rlfa.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2020 NetDEF, Inc. + * Renato Westphal + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _LDPD_RLFA_H_ +#define _LDPD_RLFA_H_ + +#include "openbsd-tree.h" +#include "zclient.h" + +struct ldp_rlfa_client { + RB_ENTRY(ldp_rlfa_client) entry; + + /* IGP instance data. */ + struct zapi_rlfa_igp igp; + + /* Backpointer to RLFA node. */ + struct ldp_rlfa_node *node; +}; +RB_HEAD(ldp_rlfa_client_head, ldp_rlfa_client); +RB_PROTOTYPE(ldp_rlfa_client_head, ldp_rlfa_client, entry, + ldp_rlfa_client_compare); + +struct ldp_rlfa_node { + RB_ENTRY(ldp_rlfa_node) entry; + + /* Destination prefix. */ + struct prefix destination; + + /* PQ node address. */ + struct in_addr pq_address; + + /* RLFA clients. */ + struct ldp_rlfa_client_head clients; + + /* Label allocated by the PQ node to the RLFA destination. */ + mpls_label_t pq_label; +}; +RB_HEAD(ldp_rlfa_node_head, ldp_rlfa_node); +RB_PROTOTYPE(ldp_rlfa_node_head, ldp_rlfa_node, entry, ldp_rlfa_node_compare); + +extern struct ldp_rlfa_node_head rlfa_node_tree; + +/* prototypes */ +struct ldp_rlfa_client *rlfa_client_new(struct ldp_rlfa_node *rnode, + struct zapi_rlfa_igp *igp); +void rlfa_client_del(struct ldp_rlfa_client *rclient); +struct ldp_rlfa_client *rlfa_client_find(struct ldp_rlfa_node *rnode, + struct zapi_rlfa_igp *igp); +struct ldp_rlfa_node *rlfa_node_new(const struct prefix *destination, + struct in_addr pq_address); +void rlfa_node_del(struct ldp_rlfa_node *rnode); +struct ldp_rlfa_node *rlfa_node_find(const struct prefix *destination, + struct in_addr pq_address); +void lde_rlfa_check(struct ldp_rlfa_client *rclient); +void lde_rlfa_client_send(struct ldp_rlfa_client *rclient); +void lde_rlfa_label_update(const struct fec *fec); +void lde_rlfa_update_clients(struct fec *fec, struct lde_nbr *ln, + uint32_t label); +void ldpe_rlfa_init(struct ldp_rlfa_client *rclient); +void ldpe_rlfa_exit(struct ldp_rlfa_client *rclient); + +#endif /* _LDPD_RLFA_H_ */ diff --git a/ldpd/subdir.am b/ldpd/subdir.am index 2058d2596a..d89d18341d 100644 --- a/ldpd/subdir.am +++ b/ldpd/subdir.am @@ -36,6 +36,7 @@ ldpd_libldp_a_SOURCES = \ ldpd/notification.c \ ldpd/packet.c \ ldpd/pfkey.c \ + ldpd/rlfa.c \ ldpd/socket.c \ ldpd/util.c \ # end @@ -53,6 +54,7 @@ noinst_HEADERS += \ ldpd/ldpd.h \ ldpd/ldpe.h \ ldpd/log.h \ + ldpd/rlfa.h \ # end ldpd_ldpd_SOURCES = ldpd/ldpd.c diff --git a/lib/command.c b/lib/command.c index f40fe6e2c5..b34fa7ff3e 100644 --- a/lib/command.c +++ b/lib/command.c @@ -49,6 +49,8 @@ #include "northbound_cli.h" #include "network.h" +#include "frrscript.h" + DEFINE_MTYPE_STATIC(LIB, HOST, "Host config") DEFINE_MTYPE(LIB, COMPLETION, "Completion item") @@ -2303,6 +2305,31 @@ done: return CMD_SUCCESS; } +#if defined(DEV_BUILD) && defined(HAVE_SCRIPTING) +DEFUN(script, + script_cmd, + "script SCRIPT", + "Test command - execute a script\n" + "Script name (same as filename in /etc/frr/scripts/\n") +{ + struct prefix p; + + (void)str2prefix("1.2.3.4/24", &p); + + struct frrscript *fs = frrscript_load(argv[1]->arg, NULL); + + if (fs == NULL) { + vty_out(vty, "Script '/etc/frr/scripts/%s.lua' not found\n", + argv[1]->arg); + } else { + int ret = frrscript_call(fs, NULL); + vty_out(vty, "Script result: %d\n", ret); + } + + return CMD_SUCCESS; +} +#endif + /* Set config filename. Called from vty.c */ void host_config_set(const char *filename) { @@ -2397,6 +2424,10 @@ void cmd_init(int terminal) install_element(VIEW_NODE, &echo_cmd); install_element(VIEW_NODE, &autocomplete_cmd); install_element(VIEW_NODE, &find_cmd); +#if defined(DEV_BUILD) && defined(HAVE_SCRIPTING) + install_element(VIEW_NODE, &script_cmd); +#endif + install_element(ENABLE_NODE, &config_end_cmd); install_element(ENABLE_NODE, &config_disable_cmd); diff --git a/lib/compiler.h b/lib/compiler.h index 217a60d888..70ef8e9bc8 100644 --- a/lib/compiler.h +++ b/lib/compiler.h @@ -279,6 +279,29 @@ extern "C" { #define array_size(ar) (sizeof(ar) / sizeof(ar[0])) +/* Some insane macros to count number of varargs to a functionlike macro */ +#define PP_ARG_N( \ + _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \ + _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \ + _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \ + _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \ + _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \ + _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \ + _61, _62, _63, N, ...) N + +#define PP_RSEQ_N() \ + 62, 61, 60, \ + 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, \ + 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, \ + 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, \ + 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \ + 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \ + 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 + +#define PP_NARG_(...) PP_ARG_N(__VA_ARGS__) +#define PP_NARG(...) PP_NARG_(_, ##__VA_ARGS__, PP_RSEQ_N()) + + /* sigh. this is so ugly, it overflows and wraps to being nice again. * * printfrr() supports "%Ld" for <int64_t>, whatever that is typedef'd to. diff --git a/lib/frrlua.c b/lib/frrlua.c index 9f9cf8c1f6..d8aaa3aa3c 100644 --- a/lib/frrlua.c +++ b/lib/frrlua.c @@ -2,128 +2,365 @@ * This file defines the lua interface into * FRRouting. * - * Copyright (C) 2016 Cumulus Networks, Inc. - * Donald Sharp + * Copyright (C) 2016-2019 Cumulus Networks, Inc. + * Donald Sharp, Quentin Young * - * This file is part of FRRouting (FRR). + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. * - * FRR is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2, or (at your option) any later version. - * - * FRR is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * * You should have received a copy of the GNU General Public License along - * with FRR; see the file COPYING. If not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <zebra.h> -#if defined(HAVE_LUA) +#ifdef HAVE_SCRIPTING + #include "prefix.h" #include "frrlua.h" #include "log.h" +#include "buffer.h" + +/* Lua stuff */ -static int lua_zlog_debug(lua_State *L) +/* + * FRR convenience functions. + * + * This section has convenience functions used to make interacting with the Lua + * stack easier. + */ + +int frrlua_table_get_integer(lua_State *L, const char *key) { - int debug_lua = 1; - const char *string = lua_tostring(L, 1); + int result; - if (debug_lua) - zlog_debug("%s", string); + lua_pushstring(L, key); + lua_gettable(L, -2); - return 0; + result = lua_tointeger(L, -1); + lua_pop(L, 1); + + return result; } -const char *get_string(lua_State *L, const char *key) +/* + * Encoders. + * + * This section has functions that convert internal FRR datatypes into Lua + * datatypes. + */ + +void lua_pushprefix(lua_State *L, const struct prefix *prefix) { - const char *str; + char buffer[PREFIX_STRLEN]; - lua_pushstring(L, key); - lua_gettable(L, -2); + lua_newtable(L); + lua_pushstring(L, prefix2str(prefix, buffer, PREFIX_STRLEN)); + lua_setfield(L, -2, "network"); + lua_pushinteger(L, prefix->prefixlen); + lua_setfield(L, -2, "length"); + lua_pushinteger(L, prefix->family); + lua_setfield(L, -2, "family"); +} - str = (const char *)lua_tostring(L, -1); +void *lua_toprefix(lua_State *L, int idx) +{ + struct prefix *p = XCALLOC(MTYPE_TMP, sizeof(struct prefix)); + + lua_getfield(L, idx, "network"); + (void)str2prefix(lua_tostring(L, -1), p); lua_pop(L, 1); - return str; + return p; } -int get_integer(lua_State *L, const char *key) +void lua_pushinterface(lua_State *L, const struct interface *ifp) { - int result; + lua_newtable(L); + lua_pushstring(L, ifp->name); + lua_setfield(L, -2, "name"); + lua_pushinteger(L, ifp->ifindex); + lua_setfield(L, -2, "ifindex"); + lua_pushinteger(L, ifp->status); + lua_setfield(L, -2, "status"); + lua_pushinteger(L, ifp->flags); + lua_setfield(L, -2, "flags"); + lua_pushinteger(L, ifp->metric); + lua_setfield(L, -2, "metric"); + lua_pushinteger(L, ifp->speed); + lua_setfield(L, -2, "speed"); + lua_pushinteger(L, ifp->mtu); + lua_setfield(L, -2, "mtu"); + lua_pushinteger(L, ifp->mtu6); + lua_setfield(L, -2, "mtu6"); + lua_pushinteger(L, ifp->bandwidth); + lua_setfield(L, -2, "bandwidth"); + lua_pushinteger(L, ifp->link_ifindex); + lua_setfield(L, -2, "link_ifindex"); + lua_pushinteger(L, ifp->ll_type); + lua_setfield(L, -2, "linklayer_type"); +} - lua_pushstring(L, key); - lua_gettable(L, -2); +void *lua_tointerface(lua_State *L, int idx) +{ + struct interface *ifp = XCALLOC(MTYPE_TMP, sizeof(struct interface)); - result = lua_tointeger(L, -1); + lua_getfield(L, idx, "name"); + strlcpy(ifp->name, lua_tostring(L, -1), sizeof(ifp->name)); + lua_pop(L, 1); + lua_getfield(L, idx, "ifindex"); + ifp->ifindex = lua_tointeger(L, -1); + lua_pop(L, 1); + lua_getfield(L, idx, "status"); + ifp->status = lua_tointeger(L, -1); + lua_pop(L, 1); + lua_getfield(L, idx, "flags"); + ifp->flags = lua_tointeger(L, -1); + lua_pop(L, 1); + lua_getfield(L, idx, "metric"); + ifp->metric = lua_tointeger(L, -1); + lua_pop(L, 1); + lua_getfield(L, idx, "speed"); + ifp->speed = lua_tointeger(L, -1); + lua_pop(L, 1); + lua_getfield(L, idx, "mtu"); + ifp->mtu = lua_tointeger(L, -1); + lua_pop(L, 1); + lua_getfield(L, idx, "mtu6"); + ifp->mtu6 = lua_tointeger(L, -1); + lua_pop(L, 1); + lua_getfield(L, idx, "bandwidth"); + ifp->bandwidth = lua_tointeger(L, -1); + lua_pop(L, 1); + lua_getfield(L, idx, "link_ifindex"); + ifp->link_ifindex = lua_tointeger(L, -1); + lua_pop(L, 1); + lua_getfield(L, idx, "linklayer_type"); + ifp->ll_type = lua_tointeger(L, -1); lua_pop(L, 1); - return result; + return ifp; } -static void *lua_alloc(void *ud, void *ptr, size_t osize, - size_t nsize) +void lua_pushinaddr(lua_State *L, const struct in_addr *addr) { - (void)ud; (void)osize; /* not used */ - if (nsize == 0) { - free(ptr); - return NULL; - } else - return realloc(ptr, nsize); + char buf[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, addr, buf, sizeof(buf)); + + lua_newtable(L); + lua_pushinteger(L, addr->s_addr); + lua_setfield(L, -2, "value"); + lua_pushstring(L, buf); + lua_setfield(L, -2, "string"); } -lua_State *lua_initialize(const char *file) +void *lua_toinaddr(lua_State *L, int idx) { - int status; - lua_State *L = lua_newstate(lua_alloc, NULL); + struct in_addr *inaddr = XCALLOC(MTYPE_TMP, sizeof(struct in_addr)); - zlog_debug("Newstate: %p", L); - luaL_openlibs(L); - zlog_debug("Opened lib"); - status = luaL_loadfile(L, file); - if (status) { - zlog_debug("Failure to open %s %d", file, status); - lua_close(L); - return NULL; - } + lua_getfield(L, idx, "value"); + inaddr->s_addr = lua_tointeger(L, -1); + lua_pop(L, 1); - lua_pcall(L, 0, LUA_MULTRET, 0); - zlog_debug("Setting global function"); - lua_pushcfunction(L, lua_zlog_debug); - lua_setglobal(L, "zlog_debug"); + return inaddr; +} + + +void lua_pushin6addr(lua_State *L, const struct in6_addr *addr) +{ + char buf[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, addr, buf, sizeof(buf)); + + lua_newtable(L); + lua_pushlstring(L, (const char *)addr->s6_addr, 16); + lua_setfield(L, -2, "value"); + lua_pushstring(L, buf); + lua_setfield(L, -2, "string"); +} + +void *lua_toin6addr(lua_State *L, int idx) +{ + struct in6_addr *in6addr = XCALLOC(MTYPE_TMP, sizeof(struct in6_addr)); + + lua_getfield(L, idx, "string"); + inet_pton(AF_INET6, lua_tostring(L, -1), in6addr); + lua_pop(L, 1); - return L; + return in6addr; } -void lua_setup_prefix_table(lua_State *L, const struct prefix *prefix) +void lua_pushsockunion(lua_State *L, const union sockunion *su) { - char buffer[100]; + char buf[SU_ADDRSTRLEN]; + sockunion2str(su, buf, sizeof(buf)); lua_newtable(L); - lua_pushstring(L, prefix2str(prefix, buffer, 100)); - lua_setfield(L, -2, "route"); - lua_pushinteger(L, prefix->family); - lua_setfield(L, -2, "family"); - lua_setglobal(L, "prefix"); + lua_pushlstring(L, (const char *)sockunion_get_addr(su), + sockunion_get_addrlen(su)); + lua_setfield(L, -2, "value"); + lua_pushstring(L, buf); + lua_setfield(L, -2, "string"); } -enum lua_rm_status lua_run_rm_rule(lua_State *L, const char *rule) +void *lua_tosockunion(lua_State *L, int idx) { - int status; + union sockunion *su = XCALLOC(MTYPE_TMP, sizeof(union sockunion)); + + lua_getfield(L, idx, "string"); + str2sockunion(lua_tostring(L, -1), su); + + return su; +} - lua_getglobal(L, rule); - status = lua_pcall(L, 0, 1, 0); - if (status) { - zlog_debug("Executing Failure with function: %s: %d", - rule, status); - return LUA_RM_FAILURE; +void lua_pushtimet(lua_State *L, const time_t *time) +{ + lua_pushinteger(L, *time); +} + +void *lua_totimet(lua_State *L, int idx) +{ + time_t *t = XCALLOC(MTYPE_TMP, sizeof(time_t)); + + *t = lua_tointeger(L, idx); + + return t; +} + +void lua_pushintegerp(lua_State *L, const long long *num) +{ + lua_pushinteger(L, *num); +} + +void *lua_tointegerp(lua_State *L, int idx) +{ + int isnum; + long long *num = XCALLOC(MTYPE_TMP, sizeof(long long)); + + *num = lua_tonumberx(L, idx, &isnum); + assert(isnum); + + return num; +} + +void *lua_tostringp(lua_State *L, int idx) +{ + char *string = XSTRDUP(MTYPE_TMP, lua_tostring(L, idx)); + + return string; +} + +/* + * Logging. + * + * Lua-compatible wrappers for FRR logging functions. + */ +static const char *frrlua_log_thunk(lua_State *L) +{ + int nargs; + + nargs = lua_gettop(L); + assert(nargs == 1); + + return lua_tostring(L, 1); +} + +static int frrlua_log_debug(lua_State *L) +{ + zlog_debug("%s", frrlua_log_thunk(L)); + return 0; +} + +static int frrlua_log_info(lua_State *L) +{ + zlog_info("%s", frrlua_log_thunk(L)); + return 0; +} + +static int frrlua_log_notice(lua_State *L) +{ + zlog_notice("%s", frrlua_log_thunk(L)); + return 0; +} + +static int frrlua_log_warn(lua_State *L) +{ + zlog_warn("%s", frrlua_log_thunk(L)); + return 0; +} + +static int frrlua_log_error(lua_State *L) +{ + zlog_err("%s", frrlua_log_thunk(L)); + return 0; +} + +static const luaL_Reg log_funcs[] = { + {"debug", frrlua_log_debug}, + {"info", frrlua_log_info}, + {"notice", frrlua_log_notice}, + {"warn", frrlua_log_warn}, + {"error", frrlua_log_error}, + {}, +}; + +void frrlua_export_logging(lua_State *L) +{ + lua_newtable(L); + luaL_setfuncs(L, log_funcs, 0); + lua_setglobal(L, "log"); +} + +/* + * Debugging. + */ + +char *frrlua_stackdump(lua_State *L) +{ + int top = lua_gettop(L); + + char tmpbuf[64]; + struct buffer *buf = buffer_new(4098); + + for (int i = 1; i <= top; i++) { + int t = lua_type(L, i); + + switch (t) { + case LUA_TSTRING: /* strings */ + snprintf(tmpbuf, sizeof(tmpbuf), "\"%s\"\n", + lua_tostring(L, i)); + buffer_putstr(buf, tmpbuf); + break; + case LUA_TBOOLEAN: /* booleans */ + snprintf(tmpbuf, sizeof(tmpbuf), "%s\n", + lua_toboolean(L, i) ? "true" : "false"); + buffer_putstr(buf, tmpbuf); + break; + case LUA_TNUMBER: /* numbers */ + snprintf(tmpbuf, sizeof(tmpbuf), "%g\n", + lua_tonumber(L, i)); + buffer_putstr(buf, tmpbuf); + break; + default: /* other values */ + snprintf(tmpbuf, sizeof(tmpbuf), "%s\n", + lua_typename(L, t)); + buffer_putstr(buf, tmpbuf); + break; + } } - status = lua_tonumber(L, -1); - return status; + char *result = XSTRDUP(MTYPE_TMP, buffer_getstr(buf)); + + buffer_free(buf); + + return result; } -#endif + +#endif /* HAVE_SCRIPTING */ diff --git a/lib/frrlua.h b/lib/frrlua.h index 40c7a67b89..8e52931e50 100644 --- a/lib/frrlua.h +++ b/lib/frrlua.h @@ -1,88 +1,173 @@ /* - * This file defines the lua interface into - * FRRouting. + * Copyright (C) 2016-2019 Cumulus Networks, Inc. + * Donald Sharp, Quentin Young * - * Copyright (C) 2016 Cumulus Networks, Inc. - * Donald Sharp + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. * - * This file is part of FRRouting (FRR). - * - * FRR is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2, or (at your option) any later version. - * - * FRR is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * * You should have received a copy of the GNU General Public License along - * with FRR; see the file COPYING. If not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef __LUA_H__ -#define __LUA_H__ +#ifndef __FRRLUA_H__ +#define __FRRLUA_H__ + +#include <zebra.h> + +#ifdef HAVE_SCRIPTING -#if defined(HAVE_LUA) +#include <lua.h> +#include <lualib.h> +#include <lauxlib.h> -#include "lua.h" -#include "lualib.h" -#include "lauxlib.h" +#include "prefix.h" +#include "frrscript.h" #ifdef __cplusplus extern "C" { #endif /* - * These functions are helper functions that - * try to glom some of the lua_XXX functionality - * into what we actually need, instead of having - * to make multiple calls to set up what - * we want + * Converts a prefix to a Lua value and pushes it on the stack. + */ +void lua_pushprefix(lua_State *L, const struct prefix *prefix); + +/* + * Converts the Lua value at idx to a prefix. + * + * Returns: + * struct prefix allocated with MTYPE_TMP + */ +void *lua_toprefix(lua_State *L, int idx); + +/* + * Converts an interface to a Lua value and pushes it on the stack. + */ +void lua_pushinterface(lua_State *L, const struct interface *ifp); + +/* + * Converts the Lua value at idx to an interface. + * + * Returns: + * struct interface allocated with MTYPE_TMP. This interface is not hooked + * to anything, nor is it inserted in the global interface tree. + */ +void *lua_tointerface(lua_State *L, int idx); + +/* + * Converts an in_addr to a Lua value and pushes it on the stack. + */ +void lua_pushinaddr(lua_State *L, const struct in_addr *addr); + +/* + * Converts the Lua value at idx to an in_addr. + * + * Returns: + * struct in_addr allocated with MTYPE_TMP. + */ +void *lua_toinaddr(lua_State *L, int idx); + +/* + * Converts an in6_addr to a Lua value and pushes it on the stack. */ -enum lua_rm_status { - /* - * Script function run failure. This will translate into a - * deny - */ - LUA_RM_FAILURE = 0, - /* - * No Match was found for the route map function - */ - LUA_RM_NOMATCH, - /* - * Match was found but no changes were made to the - * incoming data. - */ - LUA_RM_MATCH, - /* - * Match was found and data was modified, so - * figure out what changed - */ - LUA_RM_MATCH_AND_CHANGE, -}; +void lua_pushin6addr(lua_State *L, const struct in6_addr *addr); /* - * Open up the lua.scr file and parse - * initial global values, if any. + * Converts the Lua value at idx to an in6_addr. + * + * Returns: + * struct in6_addr allocated with MTYPE_TMP. */ -lua_State *lua_initialize(const char *file); +void *lua_toin6addr(lua_State *L, int idx); -void lua_setup_prefix_table(lua_State *L, const struct prefix *prefix); +/* + * Converts a time_t to a Lua value and pushes it on the stack. + */ +void lua_pushtimet(lua_State *L, const time_t *time); -enum lua_rm_status lua_run_rm_rule(lua_State *L, const char *rule); +/* + * Converts the Lua value at idx to a time_t. + * + * Returns: + * time_t allocated with MTYPE_TMP. + */ +void *lua_totimet(lua_State *L, int idx); /* - * Get particular string/integer information - * from a table. It is *assumed* that - * the table has already been selected + * Converts a sockunion to a Lua value and pushes it on the stack. */ -const char *get_string(lua_State *L, const char *key); -int get_integer(lua_State *L, const char *key); +void lua_pushsockunion(lua_State *L, const union sockunion *su); + +/* + * Converts the Lua value at idx to a sockunion. + * + * Returns: + * sockunion allocated with MTYPE_TMP. + */ +void *lua_tosockunion(lua_State *L, int idx); + +/* + * Converts an int to a Lua value and pushes it on the stack. + */ +void lua_pushintegerp(lua_State *L, const long long *num); + +/* + * Converts the Lua value at idx to an int. + * + * Returns: + * int allocated with MTYPE_TMP. + */ +void *lua_tointegerp(lua_State *L, int idx); + +/* + * Pop string. + * + * Sets *string to a copy of the string at the top of the stack. The copy is + * allocated with MTYPE_TMP and the caller is responsible for freeing it. + */ +void *lua_tostringp(lua_State *L, int idx); + +/* + * Retrieve an integer from table on the top of the stack. + * + * key + * Key of string value in table + */ +int frrlua_table_get_integer(lua_State *L, const char *key); + +/* + * Exports a new table containing bindings to FRR zlog functions into the + * global namespace. + * + * From Lua, these functions may be accessed as: + * + * - log.debug() + * - log.info() + * - log.warn() + * - log.error() + * + * They take a single string argument. + */ +void frrlua_export_logging(lua_State *L); + +/* + * Dump Lua stack to a string. + * + * Return value must be freed with XFREE(MTYPE_TMP, ...); + */ +char *frrlua_stackdump(lua_State *L); #ifdef __cplusplus } #endif -#endif -#endif +#endif /* HAVE_SCRIPTING */ + +#endif /* __FRRLUA_H__ */ diff --git a/lib/frrscript.c b/lib/frrscript.c new file mode 100644 index 0000000000..a3de474a4e --- /dev/null +++ b/lib/frrscript.c @@ -0,0 +1,272 @@ +/* Scripting foo + * Copyright (C) 2020 NVIDIA Corporation + * Quentin Young + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <zebra.h> + +#ifdef HAVE_SCRIPTING + +#include <stdarg.h> +#include <lua.h> + +#include "frrscript.h" +#include "frrlua.h" +#include "memory.h" +#include "hash.h" +#include "log.h" + + +DEFINE_MTYPE_STATIC(LIB, SCRIPT, "Scripting"); + +/* Codecs */ + +struct frrscript_codec frrscript_codecs_lib[] = { + {.typename = "integer", + .encoder = (encoder_func)lua_pushintegerp, + .decoder = lua_tointegerp}, + {.typename = "string", + .encoder = (encoder_func)lua_pushstring, + .decoder = lua_tostringp}, + {.typename = "prefix", + .encoder = (encoder_func)lua_pushprefix, + .decoder = lua_toprefix}, + {.typename = "interface", + .encoder = (encoder_func)lua_pushinterface, + .decoder = lua_tointerface}, + {.typename = "in_addr", + .encoder = (encoder_func)lua_pushinaddr, + .decoder = lua_toinaddr}, + {.typename = "in6_addr", + .encoder = (encoder_func)lua_pushin6addr, + .decoder = lua_toin6addr}, + {.typename = "sockunion", + .encoder = (encoder_func)lua_pushsockunion, + .decoder = lua_tosockunion}, + {.typename = "time_t", + .encoder = (encoder_func)lua_pushtimet, + .decoder = lua_totimet}, + {}}; + +/* Type codecs */ + +struct hash *codec_hash; +char scriptdir[MAXPATHLEN]; + +static unsigned int codec_hash_key(const void *data) +{ + const struct frrscript_codec *c = data; + + return string_hash_make(c->typename); +} + +static bool codec_hash_cmp(const void *d1, const void *d2) +{ + const struct frrscript_codec *e1 = d1; + const struct frrscript_codec *e2 = d2; + + return strmatch(e1->typename, e2->typename); +} + +static void *codec_alloc(void *arg) +{ + struct frrscript_codec *tmp = arg; + + struct frrscript_codec *e = + XCALLOC(MTYPE_SCRIPT, sizeof(struct frrscript_codec)); + e->typename = XSTRDUP(MTYPE_SCRIPT, tmp->typename); + e->encoder = tmp->encoder; + e->decoder = tmp->decoder; + + return e; +} + +#if 0 +static void codec_free(struct codec *c) +{ + XFREE(MTYPE_TMP, c->typename); + XFREE(MTYPE_TMP, c); +} +#endif + +/* Generic script APIs */ + +int frrscript_call(struct frrscript *fs, struct frrscript_env *env) +{ + struct frrscript_codec c = {}; + const void *arg; + const char *bindname; + + /* Encode script arguments */ + for (int i = 0; env && env[i].val != NULL; i++) { + bindname = env[i].name; + c.typename = env[i].typename; + arg = env[i].val; + + struct frrscript_codec *codec = hash_lookup(codec_hash, &c); + assert(codec && "No encoder for type"); + codec->encoder(fs->L, arg); + + lua_setglobal(fs->L, bindname); + } + + int ret = lua_pcall(fs->L, 0, 0, 0); + + switch (ret) { + case LUA_OK: + break; + case LUA_ERRRUN: + zlog_err("Script '%s' runtime error: %s", fs->name, + lua_tostring(fs->L, -1)); + break; + case LUA_ERRMEM: + zlog_err("Script '%s' memory error: %s", fs->name, + lua_tostring(fs->L, -1)); + break; + case LUA_ERRERR: + zlog_err("Script '%s' error handler error: %s", fs->name, + lua_tostring(fs->L, -1)); + break; + case LUA_ERRGCMM: + zlog_err("Script '%s' garbage collector error: %s", fs->name, + lua_tostring(fs->L, -1)); + break; + default: + zlog_err("Script '%s' unknown error: %s", fs->name, + lua_tostring(fs->L, -1)); + break; + } + + if (ret != LUA_OK) { + lua_pop(fs->L, 1); + goto done; + } + +done: + /* LUA_OK is 0, so we can just return lua_pcall's result directly */ + return ret; +} + +void *frrscript_get_result(struct frrscript *fs, + const struct frrscript_env *result) +{ + void *r; + struct frrscript_codec c = {.typename = result->typename}; + + struct frrscript_codec *codec = hash_lookup(codec_hash, &c); + assert(codec && "No encoder for type"); + + if (!codec->decoder) { + zlog_err("No script decoder for type '%s'", result->typename); + return NULL; + } + + lua_getglobal(fs->L, result->name); + r = codec->decoder(fs->L, -1); + lua_pop(fs->L, 1); + + return r; +} + +void frrscript_register_type_codec(struct frrscript_codec *codec) +{ + struct frrscript_codec c = *codec; + + if (hash_lookup(codec_hash, &c)) { + zlog_backtrace(LOG_ERR); + assert(!"Type codec double-registered."); + } + + assert(hash_get(codec_hash, &c, codec_alloc)); +} + +void frrscript_register_type_codecs(struct frrscript_codec *codecs) +{ + for (int i = 0; codecs[i].typename != NULL; i++) + frrscript_register_type_codec(&codecs[i]); +} + +struct frrscript *frrscript_load(const char *name, + int (*load_cb)(struct frrscript *)) +{ + struct frrscript *fs = XCALLOC(MTYPE_SCRIPT, sizeof(struct frrscript)); + + fs->name = XSTRDUP(MTYPE_SCRIPT, name); + fs->L = luaL_newstate(); + frrlua_export_logging(fs->L); + + char fname[MAXPATHLEN]; + snprintf(fname, sizeof(fname), "%s/%s.lua", scriptdir, fs->name); + + int ret = luaL_loadfile(fs->L, fname); + + switch (ret) { + case LUA_OK: + break; + case LUA_ERRSYNTAX: + zlog_err("Failed loading script '%s': syntax error: %s", fname, + lua_tostring(fs->L, -1)); + break; + case LUA_ERRMEM: + zlog_err("Failed loading script '%s': out-of-memory error: %s", + fname, lua_tostring(fs->L, -1)); + break; + case LUA_ERRGCMM: + zlog_err( + "Failed loading script '%s': garbage collector error: %s", + fname, lua_tostring(fs->L, -1)); + break; + case LUA_ERRFILE: + zlog_err("Failed loading script '%s': file read error: %s", + fname, lua_tostring(fs->L, -1)); + break; + default: + zlog_err("Failed loading script '%s': unknown error: %s", fname, + lua_tostring(fs->L, -1)); + break; + } + + if (ret != LUA_OK) + goto fail; + + if (load_cb && (*load_cb)(fs) != 0) + goto fail; + + return fs; +fail: + frrscript_unload(fs); + return NULL; +} + +void frrscript_unload(struct frrscript *fs) +{ + lua_close(fs->L); + XFREE(MTYPE_SCRIPT, fs->name); + XFREE(MTYPE_SCRIPT, fs); +} + +void frrscript_init(const char *sd) +{ + codec_hash = hash_create(codec_hash_key, codec_hash_cmp, + "Lua type encoders"); + + strlcpy(scriptdir, sd, sizeof(scriptdir)); + + /* Register core library types */ + frrscript_register_type_codecs(frrscript_codecs_lib); +} + +#endif /* HAVE_SCRIPTING */ diff --git a/lib/frrscript.h b/lib/frrscript.h new file mode 100644 index 0000000000..f4057f531b --- /dev/null +++ b/lib/frrscript.h @@ -0,0 +1,138 @@ +/* Scripting foo + * Copyright (C) 2020 NVIDIA Corporation + * Quentin Young + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __FRRSCRIPT_H__ +#define __FRRSCRIPT_H__ + +#include <zebra.h> + +#ifdef HAVE_SCRIPTING + +#include <lua.h> +#include "frrlua.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*encoder_func)(lua_State *, const void *); +typedef void *(*decoder_func)(lua_State *, int); + +struct frrscript_codec { + const char *typename; + encoder_func encoder; + decoder_func decoder; +}; + +struct frrscript { + /* Script name */ + char *name; + + /* Lua state */ + struct lua_State *L; +}; + +struct frrscript_env { + /* Value type */ + const char *typename; + + /* Binding name */ + const char *name; + + /* Value */ + const void *val; +}; + +/* + * Create new FRR script. + */ +struct frrscript *frrscript_load(const char *name, + int (*load_cb)(struct frrscript *)); + +/* + * Destroy FRR script. + */ +void frrscript_unload(struct frrscript *fs); + +/* + * Register a Lua codec for a type. + * + * tname + * Name of type; e.g., "peer", "ospf_interface", etc. Chosen at will. + * + * codec(s) + * Function pointer to codec struct. Encoder function should push a Lua + * table representing the passed argument - which will have the C type + * associated with the chosen 'tname' to the provided stack. The decoder + * function should pop a value from the top of the stack and return a heap + * chunk containing that value. Allocations should be made with MTYPE_TMP. + * + * If using the plural function variant, pass a NULL-terminated array. + * + */ +void frrscript_register_type_codec(struct frrscript_codec *codec); +void frrscript_register_type_codecs(struct frrscript_codec *codecs); + +/* + * Initialize scripting subsystem. Call this before anything else. + * + * scriptdir + * Directory in which to look for scripts + */ +void frrscript_init(const char *scriptdir); + + +/* + * Call script. + * + * fs + * The script to call; this is obtained from frrscript_load(). + * + * env + * The script's environment. Specify this as an array of frrscript_env. + * + * Returns: + * 0 if the script ran successfully, nonzero otherwise. + */ +int frrscript_call(struct frrscript *fs, struct frrscript_env *env); + + +/* + * Get result from finished script. + * + * fs + * The script. This script must have been run already. + * + * result + * The result to extract from the script. + * This reuses the frrscript_env type, but only the typename and name fields + * need to be set. The value is returned directly. + * + * Returns: + * The script result of the specified name and type, or NULL. + */ +void *frrscript_get_result(struct frrscript *fs, + const struct frrscript_env *result); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* HAVE_SCRIPTING */ + +#endif /* __FRRSCRIPT_H__ */ diff --git a/lib/libfrr.c b/lib/libfrr.c index 8e7777a1a9..b83883779c 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -43,6 +43,7 @@ #include "frrcu.h" #include "frr_pthread.h" #include "defaults.h" +#include "frrscript.h" DEFINE_HOOK(frr_late_init, (struct thread_master * tm), (tm)) DEFINE_HOOK(frr_very_late_init, (struct thread_master * tm), (tm)) @@ -55,6 +56,7 @@ char frr_vtydir[256]; const char frr_dbdir[] = DAEMON_DB_DIR; #endif const char frr_moduledir[] = MODULE_PATH; +const char frr_scriptdir[] = SCRIPT_PATH; char frr_protoname[256] = "NONE"; char frr_protonameinst[256] = "NONE"; @@ -100,6 +102,7 @@ static void opt_extend(const struct optspec *os) #define OPTION_DB_FILE 1006 #define OPTION_LOGGING 1007 #define OPTION_LIMIT_FDS 1008 +#define OPTION_SCRIPTDIR 1009 static const struct option lo_always[] = { {"help", no_argument, NULL, 'h'}, @@ -110,6 +113,7 @@ static const struct option lo_always[] = { {"pathspace", required_argument, NULL, 'N'}, {"vty_socket", required_argument, NULL, OPTION_VTYSOCK}, {"moduledir", required_argument, NULL, OPTION_MODULEDIR}, + {"scriptdir", required_argument, NULL, OPTION_SCRIPTDIR}, {"log", required_argument, NULL, OPTION_LOG}, {"log-level", required_argument, NULL, OPTION_LOGLEVEL}, {"tcli", no_argument, NULL, OPTION_TCLI}, @@ -126,6 +130,7 @@ static const struct optspec os_always = { " -N, --pathspace Insert prefix into config & socket paths\n" " --vty_socket Override vty socket path\n" " --moduledir Override modules directory\n" + " --scriptdir Override scripts directory\n" " --log Set Logging to stdout, syslog, or file:<name>\n" " --log-level Set Logging Level to use, debug, info, warn, etc\n" " --tcli Use transaction-based CLI\n" @@ -533,6 +538,14 @@ static int frr_opt(int opt) } di->module_path = optarg; break; + case OPTION_SCRIPTDIR: + if (di->script_path) { + fprintf(stderr, "--scriptdir option specified more than once!\n"); + errors++; + break; + } + di->script_path = optarg; + break; case OPTION_TCLI: di->cli_mode = FRR_CLI_TRANSACTIONAL; break; @@ -717,6 +730,9 @@ struct thread_master *frr_init(void) lib_cmd_init(); frr_pthread_init(); +#ifdef HAVE_SCRIPTING + frrscript_init(di->script_path ? di->script_path : frr_scriptdir); +#endif log_ref_init(); log_ref_vty_init(); diff --git a/lib/libfrr.h b/lib/libfrr.h index 2e4dcbe093..c446931468 100644 --- a/lib/libfrr.h +++ b/lib/libfrr.h @@ -81,6 +81,7 @@ struct frr_daemon_info { #endif const char *vty_path; const char *module_path; + const char *script_path; const char *pathspace; bool zpathspace; @@ -162,6 +163,7 @@ extern char frr_zclientpath[256]; extern const char frr_sysconfdir[]; extern char frr_vtydir[256]; extern const char frr_moduledir[]; +extern const char frr_scriptdir[]; extern char frr_protoname[]; extern char frr_protonameinst[]; diff --git a/lib/northbound.h b/lib/northbound.h index c37d66d580..8dd6b4c337 100644 --- a/lib/northbound.h +++ b/lib/northbound.h @@ -552,7 +552,7 @@ struct nb_node { * from working properly on shared libraries. For those compilers, use a fixed * size array to work around the problem. */ -#define YANG_MODULE_MAX_NODES 1400 +#define YANG_MODULE_MAX_NODES 2000 struct frr_yang_module_info { /* YANG module name. */ diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c index 7048df99fb..853f643472 100644 --- a/lib/northbound_cli.c +++ b/lib/northbound_cli.c @@ -693,6 +693,12 @@ static int nb_write_config(struct nb_config *config, enum nb_cfg_format format, __func__, safe_strerror(errno)); return -1; } + if (fchmod(fd, CONFIGFILE_MASK) != 0) { + flog_warn(EC_LIB_SYSTEM_CALL, + "%s: fchmod() failed: %s(%d):", __func__, + safe_strerror(errno), errno); + return -1; + } /* Make vty for configuration file. */ file_vty = vty_new(); diff --git a/lib/routemap.c b/lib/routemap.c index 1c2f43d968..360fd25cc9 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -2399,6 +2399,7 @@ route_map_result_t route_map_apply(struct route_map *map, index = route_map_get_index(map, prefix, object, (uint8_t *)&match_ret); if (index) { + index->applied++; if (rmap_debug) zlog_debug( "Best match route-map: %s, sequence: %d for pfx: %pFX, result: %s", diff --git a/lib/sockunion.c b/lib/sockunion.c index 1dbf77efa4..1dbf77efa4 100755..100644 --- a/lib/sockunion.c +++ b/lib/sockunion.c diff --git a/lib/sockunion.h b/lib/sockunion.h index 5e80ba1090..5e80ba1090 100755..100644 --- a/lib/sockunion.h +++ b/lib/sockunion.h diff --git a/lib/subdir.am b/lib/subdir.am index ee9e827ee8..570e0c3d28 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -26,6 +26,7 @@ lib_libfrr_la_SOURCES = \ lib/filter_nb.c \ lib/frrcu.c \ lib/frrlua.c \ + lib/frrscript.c \ lib/frr_pthread.c \ lib/frrstr.c \ lib/getopt.c \ @@ -185,6 +186,7 @@ pkginclude_HEADERS += \ lib/filter.h \ lib/freebsd-queue.h \ lib/frrlua.h \ + lib/frrscript.h \ lib/frr_pthread.h \ lib/frratomic.h \ lib/frrcu.h \ diff --git a/lib/zclient.c b/lib/zclient.c index cb4555650d..f16c94369b 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -40,6 +40,7 @@ #include "nexthop_group.h" #include "lib_errors.h" #include "srte.h" +#include "printfrr.h" DEFINE_MTYPE_STATIC(LIB, ZCLIENT, "Zclient") DEFINE_MTYPE_STATIC(LIB, REDIST_INST, "Redistribution instance IDs") @@ -4121,3 +4122,51 @@ uint32_t zclient_get_nhg_start(uint32_t proto) return ZEBRA_NHG_PROTO_SPACING * proto; } + +char *zclient_dump_route_flags(uint32_t flags, char *buf, size_t len) +{ + if (flags == 0) { + snprintfrr(buf, len, "None "); + return buf; + } + + snprintfrr( + buf, len, "%s%s%s%s%s%s%s%s%s%s", + CHECK_FLAG(flags, ZEBRA_FLAG_ALLOW_RECURSION) ? "Recursion " + : "", + CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE) ? "Self " : "", + CHECK_FLAG(flags, ZEBRA_FLAG_IBGP) ? "iBGP " : "", + CHECK_FLAG(flags, ZEBRA_FLAG_SELECTED) ? "Selected " : "", + CHECK_FLAG(flags, ZEBRA_FLAG_FIB_OVERRIDE) ? "Override " : "", + CHECK_FLAG(flags, ZEBRA_FLAG_EVPN_ROUTE) ? "Evpn " : "", + CHECK_FLAG(flags, ZEBRA_FLAG_RR_USE_DISTANCE) ? "RR Distance " + : "", + CHECK_FLAG(flags, ZEBRA_FLAG_TRAPPED) ? "Trapped " : "", + CHECK_FLAG(flags, ZEBRA_FLAG_OFFLOADED) ? "Offloaded " : "", + CHECK_FLAG(flags, ZEBRA_FLAG_OFFLOAD_FAILED) ? "Offload Failed " + : ""); + return buf; +} + +char *zclient_evpn_dump_macip_flags(uint8_t flags, char *buf, size_t len) +{ + if (flags == 0) { + snprintfrr(buf, len, "None "); + return buf; + } + + snprintfrr( + buf, len, "%s%s%s%s%s%s%s", + CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY) ? "Sticky MAC " : "", + CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW) ? "Gateway MAC " : "", + CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG) ? "Router " + : "", + CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_OVERRIDE_FLAG) ? "Override " + : "", + CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_SVI_IP) ? "SVI MAC " : "", + CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT) ? "Proxy " + : "", + CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_SYNC_PATH) ? "Sync " : ""); + + return buf; +} diff --git a/lib/zclient.h b/lib/zclient.h index 2af448a20c..57bad7c2e6 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -479,6 +479,7 @@ struct zapi_route { uint8_t type; unsigned short instance; + /* If you add flags, update zclient_dump_route_flags */ uint32_t flags; /* * Cause Zebra to consider this routes nexthops recursively @@ -580,6 +581,8 @@ struct zapi_route { } opaque; }; +extern char *zclient_dump_route_flags(uint32_t flags, char *buf, size_t len); + struct zapi_labels { uint8_t message; #define ZAPI_LABELS_FTN 0x01 @@ -634,6 +637,52 @@ struct zapi_pw_status { uint32_t status; }; +/* IGP instance data associated to a RLFA. */ +struct zapi_rlfa_igp { + vrf_id_t vrf_id; + int protocol; + union { + struct { + char area_tag[32]; + struct { + int tree_id; + int level; + unsigned int run_id; + } spf; + } isis; + }; +}; + +/* IGP -> LDP RLFA (un)registration message. */ +struct zapi_rlfa_request { + /* IGP instance data. */ + struct zapi_rlfa_igp igp; + + /* Destination prefix. */ + struct prefix destination; + + /* PQ node address. */ + struct in_addr pq_address; +}; + +/* LDP -> IGP RLFA label update. */ +struct zapi_rlfa_response { + /* IGP instance data. */ + struct zapi_rlfa_igp igp; + + /* Destination prefix. */ + struct prefix destination; + + /* Resolved LDP labels. */ + mpls_label_t pq_label; + uint16_t nexthop_num; + struct { + int family; + union g_addr gate; + mpls_label_t label; + } nexthops[MULTIPATH_NUM]; +}; + enum zapi_route_notify_owner { ZAPI_ROUTE_FAIL_INSTALL, ZAPI_ROUTE_BETTER_ADMIN_WON, @@ -722,8 +771,11 @@ zapi_rule_notify_owner2str(enum zapi_rule_notify_owner note) #define ZEBRA_MACIP_TYPE_PROXY_ADVERT 0x20 /* Not locally active */ #define ZEBRA_MACIP_TYPE_SYNC_PATH 0x40 /* sync path */ /* XXX - flags is an u8; that needs to be changed to u32 if you need - * to allocate past 0x80 + * to allocate past 0x80. Additionally touch zclient_evpn_dump_macip_flags */ +#define MACIP_BUF_SIZE 128 +extern char *zclient_evpn_dump_macip_flags(uint8_t flags, char *buf, + size_t len); /* Zebra ES VTEP flags (ZEBRA_REMOTE_ES_VTEP_ADD) */ /* ESR has been rxed from the VTEP. Only VTEPs that have advertised the @@ -1091,6 +1143,12 @@ enum zapi_opaque_registry { LDP_IGP_SYNC_IF_STATE_UPDATE = 4, /* Announce that LDP is up */ LDP_IGP_SYNC_ANNOUNCE_UPDATE = 5, + /* Register RLFA with LDP */ + LDP_RLFA_REGISTER = 7, + /* Unregister all RLFAs with LDP */ + LDP_RLFA_UNREGISTER_ALL = 8, + /* Announce LDP labels associated to a previously registered RLFA */ + LDP_RLFA_LABELS = 9, }; /* Send the hello message. diff --git a/nhrpd/nhrp_cache.c b/nhrpd/nhrp_cache.c index 0b5a0427e6..0b5a0427e6 100755..100644 --- a/nhrpd/nhrp_cache.c +++ b/nhrpd/nhrp_cache.c diff --git a/nhrpd/nhrp_interface.c b/nhrpd/nhrp_interface.c index 269499cc59..269499cc59 100755..100644 --- a/nhrpd/nhrp_interface.c +++ b/nhrpd/nhrp_interface.c diff --git a/nhrpd/nhrp_nhs.c b/nhrpd/nhrp_nhs.c index 540708f1ae..540708f1ae 100755..100644 --- a/nhrpd/nhrp_nhs.c +++ b/nhrpd/nhrp_nhs.c diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c index 9aaa9dec1e..9aaa9dec1e 100755..100644 --- a/nhrpd/nhrp_peer.c +++ b/nhrpd/nhrp_peer.c diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c index ce2b1fe2ff..ce2b1fe2ff 100755..100644 --- a/nhrpd/nhrp_route.c +++ b/nhrpd/nhrp_route.c diff --git a/nhrpd/nhrpd.h b/nhrpd/nhrpd.h index a36d0c445d..a36d0c445d 100755..100644 --- a/nhrpd/nhrpd.h +++ b/nhrpd/nhrpd.h diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c index e99653f918..e18d8ddb31 100644 --- a/ospfd/ospf_ase.c +++ b/ospfd/ospf_ase.c @@ -748,8 +748,13 @@ void ospf_ase_unregister_external_lsa(struct ospf_lsa *lsa, struct ospf *top) if (rn) { lst = rn->info; - listnode_delete(lst, lsa); - ospf_lsa_unlock(&lsa); /* external_lsas list */ + struct listnode *node = listnode_lookup(lst, lsa); + /* Unlock lsa only if node is present in the list */ + if (node) { + listnode_delete(lst, lsa); + ospf_lsa_unlock(&lsa); /* external_lsas list */ + } + route_unlock_node(rn); } } diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index d4492634b3..f7d144d35b 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -2787,7 +2787,7 @@ int ospf_check_nbr_status(struct ospf *ospf) static int ospf_maxage_lsa_remover(struct thread *thread) { struct ospf *ospf = THREAD_ARG(thread); - struct ospf_lsa *lsa; + struct ospf_lsa *lsa, *old; struct route_node *rn; int reschedule = 0; @@ -2849,6 +2849,17 @@ static int ospf_maxage_lsa_remover(struct thread *thread) /* Remove from lsdb. */ if (lsa->lsdb) { + old = ospf_lsdb_lookup(lsa->lsdb, lsa); + /* The max age LSA here must be the same + * as the LSA in LSDB + */ + if (old != lsa) { + flog_err(EC_OSPF_LSA_MISSING, + "%s: LSA[Type%d:%s]: LSA not in LSDB", + __func__, lsa->data->type, + inet_ntoa(lsa->data->id)); + continue; + } ospf_discard_from_db(ospf, lsa->lsdb, lsa); ospf_lsdb_delete(lsa->lsdb, lsa); } else { diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 6052d48e83..4c67d33cb9 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -280,7 +280,7 @@ DEFPY (ospf_router_id, for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) if (area->full_nbrs) { vty_out(vty, - "For this router-id change to take effect, save config and restart ospfd\n"); + "For this router-id change to take effect, use “clear ip ospf process” command\n"); return CMD_SUCCESS; } @@ -313,7 +313,7 @@ DEFUN_HIDDEN (ospf_router_id_old, for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) if (area->full_nbrs) { vty_out(vty, - "For this router-id change to take effect, save config and restart ospfd\n"); + "For this router-id change to take effect, use “clear ip ospf process” command\n"); return CMD_SUCCESS; } @@ -346,7 +346,7 @@ DEFPY (no_ospf_router_id, for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) if (area->full_nbrs) { vty_out(vty, - "For this router-id change to take effect, save config and restart ospfd\n"); + "For this router-id change to take effect, use “clear ip ospf process” command\n"); return CMD_SUCCESS; } @@ -3365,6 +3365,54 @@ DEFUN (show_ip_ospf_instance, return ret; } +static void ospf_interface_auth_show(struct vty *vty, struct ospf_interface *oi, + json_object *json, bool use_json) +{ + int auth_type; + + auth_type = OSPF_IF_PARAM(oi, auth_type); + + switch (auth_type) { + case OSPF_AUTH_NULL: + if (use_json) + json_object_string_add(json, "authentication", + "authenticationNone"); + else + vty_out(vty, " Authentication NULL is enabled\n"); + break; + case OSPF_AUTH_SIMPLE: { + if (use_json) + json_object_string_add(json, "authentication", + "authenticationSimplePassword"); + else + vty_out(vty, + " Simple password authentication enabled\n"); + break; + } + case OSPF_AUTH_CRYPTOGRAPHIC: { + struct crypt_key *ckey; + + if (list_isempty(OSPF_IF_PARAM(oi, auth_crypt))) + return; + + ckey = listgetdata(listtail(OSPF_IF_PARAM(oi, auth_crypt))); + if (ckey) { + if (use_json) { + json_object_string_add(json, "authentication", + "authenticationMessageDigest"); + } else { + vty_out(vty, + " Cryptographic authentication enabled\n"); + vty_out(vty, " Algorithm:MD5\n"); + } + } + break; + } + default: + break; + } +} + static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, struct interface *ifp, json_object *json_interface_sub, @@ -3686,6 +3734,9 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, ospf_nbr_count(oi, 0), ospf_nbr_count(oi, NSM_Full)); ospf_bfd_interface_show(vty, ifp, json_interface_sub, use_json); + + /* OSPF Authentication information */ + ospf_interface_auth_show(vty, oi, json_interface_sub, use_json); } } @@ -8870,6 +8921,7 @@ DEFUN (no_ip_ospf_area, struct ospf_if_params *params; unsigned short instance = 0; struct in_addr addr; + struct in_addr area_id; if (argv_find(argv, argc, "(1-65535)", &idx)) instance = strtol(argv[idx]->arg, NULL, 10); @@ -8897,6 +8949,7 @@ DEFUN (no_ip_ospf_area, } else params = IF_DEF_PARAMS(ifp); + area_id = params->if_area; if (!OSPF_IF_PARAM_CONFIGURED(params, if_area)) { vty_out(vty, "Can't find specified interface area configuration.\n"); @@ -8912,6 +8965,7 @@ DEFUN (no_ip_ospf_area, if (ospf) { ospf_interface_area_unset(ospf, ifp); ospf->if_ospf_cli_count--; + ospf_area_check_free(ospf, area_id); } return CMD_SUCCESS; @@ -11176,6 +11230,70 @@ DEFUN (show_ip_ospf_vrfs, return CMD_SUCCESS; } +DEFPY (clear_ip_ospf_neighbor, + clear_ip_ospf_neighbor_cmd, + "clear ip ospf [(1-65535)]$instance neighbor [A.B.C.D$nbr_id]", + CLEAR_STR + IP_STR + "OSPF information\n" + "Instance ID\n" + "Reset OSPF Neighbor\n" + "Neighbor ID\n") +{ + struct listnode *node; + struct ospf *ospf = NULL; + + /* If user does not specify the arguments, + * instance = 0 and nbr_id = 0.0.0.0 + */ + if (instance != 0) { + /* This means clear only the particular ospf process */ + ospf = ospf_lookup_instance(instance); + if (ospf == NULL) + return CMD_NOT_MY_INSTANCE; + } + + /* Clear all the ospf processes */ + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + if (!ospf->oi_running) + continue; + + ospf_neighbor_reset(ospf, nbr_id, nbr_id_str); + } + + return CMD_SUCCESS; +} + +DEFPY (clear_ip_ospf_process, + clear_ip_ospf_process_cmd, + "clear ip ospf [(1-65535)]$instance process", + CLEAR_STR + IP_STR + "OSPF information\n" + "Instance ID\n" + "Reset OSPF Process\n") +{ + struct listnode *node; + struct ospf *ospf = NULL; + + /* Check if instance is not passed as an argument */ + if (instance != 0) { + /* This means clear only the particular ospf process */ + ospf = ospf_lookup_instance(instance); + if (ospf == NULL) + return CMD_NOT_MY_INSTANCE; + } + + /* Clear all the ospf processes */ + for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) { + if (!ospf->oi_running) + continue; + + ospf_process_reset(ospf); + } + + return CMD_SUCCESS; +} static const char *const ospf_abr_type_str[] = { "unknown", "standard", "ibm", "cisco", "shortcut" @@ -12572,6 +12690,8 @@ DEFUN (clear_ip_ospf_interface, void ospf_vty_clear_init(void) { install_element(ENABLE_NODE, &clear_ip_ospf_interface_cmd); + install_element(ENABLE_NODE, &clear_ip_ospf_process_cmd); + install_element(ENABLE_NODE, &clear_ip_ospf_neighbor_cmd); } diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 0adf8a7b41..bab75995b7 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -87,13 +87,15 @@ static void ospf_finish_final(struct ospf *); #define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1 -void ospf_router_id_update(struct ospf *ospf) +void ospf_process_refresh_data(struct ospf *ospf, bool reset) { struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id); struct in_addr router_id, router_id_old; struct ospf_interface *oi; struct interface *ifp; - struct listnode *node; + struct listnode *node, *nnode; + struct ospf_area *area; + bool rid_change = false; if (!ospf->oi_running) { if (IS_DEBUG_OSPF_EVENT) @@ -126,8 +128,8 @@ void ospf_router_id_update(struct ospf *ospf) zlog_debug("Router-ID[OLD:%pI4]: Update to %pI4", &ospf->router_id, &router_id); - if (!IPV4_ADDR_SAME(&router_id_old, &router_id)) { - + rid_change = !(IPV4_ADDR_SAME(&router_id_old, &router_id)); + if (rid_change || (reset)) { for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { /* Some nbrs are identified by router_id, these needs * to be rebuilt. Possible optimization would be to do @@ -149,16 +151,8 @@ void ospf_router_id_update(struct ospf *ospf) ospf_if_up(oi); } - /* Flush (inline) all external LSAs based on the OSPF_LSA_SELF - * flag */ - if (ospf->lsdb) { - struct route_node *rn; - struct ospf_lsa *lsa; - - LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa) - if (IS_LSA_SELF(lsa)) - ospf_lsa_flush_schedule(ospf, lsa); - } + /* Flush (inline) all the self originated LSAs */ + ospf_flush_self_originated_lsas_now(ospf); ospf->router_id = router_id; if (IS_DEBUG_OSPF_EVENT) @@ -183,24 +177,81 @@ void ospf_router_id_update(struct ospf *ospf) LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa) { /* AdvRouter and Router ID is the same. */ if (IPV4_ADDR_SAME(&lsa->data->adv_router, - &ospf->router_id)) { + &ospf->router_id) && rid_change) { SET_FLAG(lsa->flags, OSPF_LSA_SELF_CHECKED); SET_FLAG(lsa->flags, OSPF_LSA_SELF); ospf_lsa_flush_schedule(ospf, lsa); } + /* The above flush will send immediately + * So discard the LSA to originate new + */ + ospf_discard_from_db(ospf, ospf->lsdb, lsa); } + + LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa) + ospf_discard_from_db(ospf, ospf->lsdb, lsa); + + ospf_lsdb_delete_all(ospf->lsdb); } + /* Delete the LSDB */ + for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) + ospf_area_lsdb_discard_delete(area); + /* update router-lsa's for each area */ ospf_router_lsa_update(ospf); /* update ospf_interface's */ - FOR_ALL_INTERFACES (vrf, ifp) - ospf_if_update(ospf, ifp); + FOR_ALL_INTERFACES (vrf, ifp) { + if (reset) + ospf_if_reset(ifp); + else + ospf_if_update(ospf, ifp); + } ospf_external_lsa_rid_change(ospf); } + + ospf->inst_shutdown = 0; +} + +void ospf_router_id_update(struct ospf *ospf) +{ + ospf_process_refresh_data(ospf, false); +} + +void ospf_process_reset(struct ospf *ospf) +{ + ospf_process_refresh_data(ospf, true); +} + +void ospf_neighbor_reset(struct ospf *ospf, struct in_addr nbr_id, + const char *nbr_str) +{ + struct route_node *rn; + struct ospf_neighbor *nbr; + struct ospf_interface *oi; + struct listnode *node; + + /* Clear only a particular nbr with nbr router id as nbr_id */ + if (nbr_str != NULL) { + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { + nbr = ospf_nbr_lookup_by_routerid(oi->nbrs, &nbr_id); + if (nbr) + OSPF_NSM_EVENT_EXECUTE(nbr, NSM_KillNbr); + } + return; + } + + /* send Neighbor event KillNbr to all associated neighbors. */ + for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) { + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) { + nbr = rn->info; + if (nbr && (nbr != oi->nbr_self)) + OSPF_NSM_EVENT_EXECUTE(nbr, NSM_KillNbr); + } + } } /* For OSPF area sort by area id. */ @@ -870,14 +921,11 @@ static struct ospf_area *ospf_area_new(struct ospf *ospf, return new; } -static void ospf_area_free(struct ospf_area *area) +void ospf_area_lsdb_discard_delete(struct ospf_area *area) { struct route_node *rn; struct ospf_lsa *lsa; - ospf_opaque_type10_lsa_term(area); - - /* Free LSDBs. */ LSDB_LOOP (ROUTER_LSDB(area), rn, lsa) ospf_discard_from_db(area->ospf, area->lsdb, lsa); LSDB_LOOP (NETWORK_LSDB(area), rn, lsa) @@ -895,6 +943,15 @@ static void ospf_area_free(struct ospf_area *area) ospf_discard_from_db(area->ospf, area->lsdb, lsa); ospf_lsdb_delete_all(area->lsdb); +} + +static void ospf_area_free(struct ospf_area *area) +{ + ospf_opaque_type10_lsa_term(area); + + /* Free LSDBs. */ + ospf_area_lsdb_discard_delete(area); + ospf_lsdb_free(area->lsdb); ospf_lsa_unlock(&area->router_lsa_self); diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index 3087b735ae..6960d151c2 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -571,7 +571,11 @@ extern struct ospf *ospf_lookup_by_inst_name(unsigned short instance, const char *name); extern struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id); extern void ospf_finish(struct ospf *); +extern void ospf_process_refresh_data(struct ospf *ospf, bool reset); extern void ospf_router_id_update(struct ospf *ospf); +extern void ospf_process_reset(struct ospf *ospf); +extern void ospf_neighbor_reset(struct ospf *ospf, struct in_addr nbr_id, + const char *nbr_str); extern int ospf_network_set(struct ospf *, struct prefix_ipv4 *, struct in_addr, int); extern int ospf_network_unset(struct ospf *, struct prefix_ipv4 *, @@ -596,6 +600,7 @@ extern int ospf_area_shortcut_set(struct ospf *, struct ospf_area *, int); extern int ospf_area_shortcut_unset(struct ospf *, struct ospf_area *); extern int ospf_timers_refresh_set(struct ospf *, int); extern int ospf_timers_refresh_unset(struct ospf *); +void ospf_area_lsdb_discard_delete(struct ospf_area *area); extern int ospf_nbr_nbma_set(struct ospf *, struct in_addr); extern int ospf_nbr_nbma_unset(struct ospf *, struct in_addr); extern int ospf_nbr_nbma_priority_set(struct ospf *, struct in_addr, uint8_t); diff --git a/pathd/path_pcep_controller.c b/pathd/path_pcep_controller.c index 255503b459..f4871a4d8d 100644 --- a/pathd/path_pcep_controller.c +++ b/pathd/path_pcep_controller.c @@ -185,7 +185,7 @@ int pcep_ctrl_initialize(struct thread_master *main_thread, PCEP_DEBUG("Initializing pcep module controller"); /* Create and start the FRR pthread */ - *fpt = frr_pthread_new(&attr, "PCEP thread", "pcep"); + *fpt = frr_pthread_new(&attr, "PCEP thread", "pcep_controller"); if (*fpt == NULL) { flog_err(EC_PATH_SYSTEM_CALL, "failed to initialize PCEP thread"); diff --git a/pathd/path_pcep_lib.c b/pathd/path_pcep_lib.c index fc72be8979..bb6bfb1336 100644 --- a/pathd/path_pcep_lib.c +++ b/pathd/path_pcep_lib.c @@ -285,7 +285,7 @@ int pcep_lib_pthread_create_cb(pthread_t *thread_id, const pthread_attr_t *attr, .start = pcep_lib_pthread_start_passthrough, .stop = pcep_lib_pthread_stop_cb}; struct frr_pthread *fpt = - frr_pthread_new(&fpt_attr, thread_name, "pcep"); + frr_pthread_new(&fpt_attr, thread_name, "pcep_lib"); if (fpt == NULL) { return 1; } diff --git a/pbrd/pbr_nht.c b/pbrd/pbr_nht.c index dbe5de724c..f99971ab7b 100644 --- a/pbrd/pbr_nht.c +++ b/pbrd/pbr_nht.c @@ -770,18 +770,20 @@ pbr_nht_individual_nexthop_gw_update(struct pbr_nexthop_cache *pnhc, goto done; } - switch (pnhi->nhr->prefix.family) { - case AF_INET: - if (pnhc->nexthop.gate.ipv4.s_addr - != pnhi->nhr->prefix.u.prefix4.s_addr) - goto done; /* Unrelated change */ - break; - case AF_INET6: - if (memcmp(&pnhc->nexthop.gate.ipv6, - &pnhi->nhr->prefix.u.prefix6, 16) - != 0) - goto done; /* Unrelated change */ - break; + if (pnhi->nhr) { + switch (pnhi->nhr->prefix.family) { + case AF_INET: + if (pnhc->nexthop.gate.ipv4.s_addr + != pnhi->nhr->prefix.u.prefix4.s_addr) + goto done; /* Unrelated change */ + break; + case AF_INET6: + if (memcmp(&pnhc->nexthop.gate.ipv6, + &pnhi->nhr->prefix.u.prefix6, 16) + != 0) + goto done; /* Unrelated change */ + break; + } } pnhi->nhr_matched = true; diff --git a/pimd/pim_jp_agg.c b/pimd/pim_jp_agg.c index 5279a00855..d95d9dd25d 100644 --- a/pimd/pim_jp_agg.c +++ b/pimd/pim_jp_agg.c @@ -360,11 +360,9 @@ void pim_jp_agg_switch_interface(struct pim_rpf *orpf, struct pim_rpf *nrpf, void pim_jp_agg_single_upstream_send(struct pim_rpf *rpf, struct pim_upstream *up, bool is_join) { - static struct list *groups = NULL; - static struct pim_jp_agg_group jag; - static struct pim_jp_sources js; - - static bool first = true; + struct list groups, sources; + struct pim_jp_agg_group jag; + struct pim_jp_sources js; /* skip JP upstream messages if source is directly connected */ if (!up || !rpf->source_nexthop.interface || @@ -373,19 +371,19 @@ void pim_jp_agg_single_upstream_send(struct pim_rpf *rpf, if_is_loopback_or_vrf(rpf->source_nexthop.interface)) return; - if (first) { - groups = list_new(); - jag.sources = list_new(); - - listnode_add(groups, &jag); - listnode_add(jag.sources, &js); + memset(&groups, 0, sizeof(groups)); + memset(&sources, 0, sizeof(sources)); + jag.sources = &sources; - first = false; - } + listnode_add(&groups, &jag); + listnode_add(jag.sources, &js); jag.group.s_addr = up->sg.grp.s_addr; js.up = up; js.is_join = is_join; - pim_joinprune_send(rpf, groups); + pim_joinprune_send(rpf, &groups); + + list_delete_all_node(jag.sources); + list_delete_all_node(&groups); } diff --git a/staticd/static_nb.c b/staticd/static_nb.c index 51704426f0..a2a14751cf 100644 --- a/staticd/static_nb.c +++ b/staticd/static_nb.c @@ -47,12 +47,6 @@ const struct frr_yang_module_info frr_staticd_info = { } }, { - .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/table-id", - .cbs = { - .modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_table_id_modify, - } - }, - { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop", .cbs = { .apply_finish = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_apply_finish, @@ -72,7 +66,6 @@ const struct frr_yang_module_info frr_staticd_info = { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/onlink", .cbs = { .modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_onlink_modify, - .destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_onlink_destroy, } }, { @@ -132,12 +125,6 @@ const struct frr_yang_module_info frr_staticd_info = { } }, { - .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/table-id", - .cbs = { - .modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_table_id_modify, - } - }, - { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop", .cbs = { .apply_finish = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_apply_finish, @@ -157,7 +144,6 @@ const struct frr_yang_module_info frr_staticd_info = { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/onlink", .cbs = { .modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_onlink_modify, - .destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_onlink_destroy, } }, { diff --git a/staticd/static_nb.h b/staticd/static_nb.h index d145c31f77..e85e1d0e9f 100644 --- a/staticd/static_nb.h +++ b/staticd/static_nb.h @@ -31,8 +31,6 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_pa struct nb_cb_destroy_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_tag_modify( struct nb_cb_modify_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_table_id_modify( - struct nb_cb_modify_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_create( struct nb_cb_create_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_destroy( @@ -43,8 +41,6 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_pa struct nb_cb_destroy_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_onlink_modify( struct nb_cb_modify_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_onlink_destroy( - struct nb_cb_destroy_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_color_modify( struct nb_cb_modify_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_color_destroy( @@ -75,8 +71,6 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_sr struct nb_cb_destroy_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_tag_modify( struct nb_cb_modify_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_table_id_modify( - struct nb_cb_modify_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_create( struct nb_cb_create_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_destroy( @@ -87,8 +81,6 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_sr struct nb_cb_destroy_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_onlink_modify( struct nb_cb_modify_args *args); -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_onlink_destroy( - struct nb_cb_destroy_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_color_modify( struct nb_cb_modify_args *args); int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_color_destroy( @@ -134,13 +126,11 @@ int routing_control_plane_protocols_name_validate( "/frr-routing:routing/control-plane-protocols/" \ "control-plane-protocol[type='%s'][name='%s'][vrf='%s']/" \ "frr-staticd:staticd/route-list[prefix='%s'][afi-safi='%s']/" \ - "path-list[distance='%u']" + "path-list[table-id='%u'][distance='%u']" #define FRR_STATIC_ROUTE_PATH_TAG_XPATH "/tag" -#define FRR_STATIC_ROUTE_PATH_TABLEID_XPATH "/table-id" - /* route-list/frr-nexthops */ #define FRR_STATIC_ROUTE_NH_KEY_XPATH \ "/frr-nexthops/" \ @@ -161,7 +151,7 @@ int routing_control_plane_protocols_name_validate( "/frr-routing:routing/control-plane-protocols/" \ "control-plane-protocol[type='%s'][name='%s'][vrf='%s']/" \ "frr-staticd:staticd/route-list[prefix='%s'][afi-safi='%s']/" \ - "src-list[src-prefix='%s']/path-list[distance='%u']" + "src-list[src-prefix='%s']/path-list[table-id='%u'][distance='%u']" /* route-list/frr-nexthops */ #define FRR_DEL_S_ROUTE_NH_KEY_XPATH \ diff --git a/staticd/static_nb_config.c b/staticd/static_nb_config.c index 6e59f50a00..bf669957bf 100644 --- a/staticd/static_nb_config.c +++ b/staticd/static_nb_config.c @@ -35,17 +35,40 @@ static int static_path_list_create(struct nb_cb_create_args *args) { struct route_node *rn; struct static_path *pn; + const struct lyd_node *vrf_dnode; + const char *vrf; uint8_t distance; + uint32_t table_id; switch (args->event) { case NB_EV_VALIDATE: + vrf_dnode = yang_dnode_get_parent(args->dnode, + "control-plane-protocol"); + vrf = yang_dnode_get_string(vrf_dnode, "./vrf"); + table_id = yang_dnode_get_uint32(args->dnode, "./table-id"); + + /* + * TableId is not applicable for VRF. Consider the case of + * l3mdev, there is one uint32_t space to work with. + * A l3mdev device points at a specific table that it + * relates to and a set of interfaces it belongs to. + */ + if (table_id && (strcmp(vrf, vrf_get_default_name()) != 0) + && !vrf_is_backend_netns()) { + snprintf( + args->errmsg, args->errmsg_len, + "%% table param only available when running on netns-based vrfs"); + return NB_ERR_VALIDATION; + } + break; case NB_EV_ABORT: case NB_EV_PREPARE: break; case NB_EV_APPLY: rn = nb_running_get_entry(args->dnode, NULL, true); distance = yang_dnode_get_uint8(args->dnode, "./distance"); - pn = static_add_path(rn, distance); + table_id = yang_dnode_get_uint32(args->dnode, "./table-id"); + pn = static_add_path(rn, table_id, distance); nb_running_set_entry(args->dnode, pn); } @@ -80,44 +103,6 @@ static void static_path_list_tag_modify(struct nb_cb_modify_args *args, static_install_path(rn, pn, info->safi, info->svrf); } -static int static_path_list_tableid_modify(struct nb_cb_modify_args *args, - const struct lyd_node *rn_dnode, - struct stable_info *info) -{ - struct static_path *pn; - struct route_node *rn; - uint32_t table_id; - const struct lyd_node *vrf_dnode; - const char *vrf; - - switch (args->event) { - case NB_EV_VALIDATE: - vrf_dnode = yang_dnode_get_parent(args->dnode, - "control-plane-protocol"); - vrf = yang_dnode_get_string(vrf_dnode, "./vrf"); - table_id = yang_dnode_get_uint32(args->dnode, NULL); - if (table_id && (strcmp(vrf, vrf_get_default_name()) != 0) - && !vrf_is_backend_netns()) { - snprintf(args->errmsg, args->errmsg_len, - "%% table param only available when running on netns-based vrfs"); - return NB_ERR_VALIDATION; - } - break; - case NB_EV_PREPARE: - case NB_EV_ABORT: - break; - case NB_EV_APPLY: - table_id = yang_dnode_get_uint32(args->dnode, NULL); - pn = nb_running_get_entry(args->dnode, NULL, true); - pn->table_id = table_id; - rn = nb_running_get_entry(rn_dnode, NULL, true); - static_install_path(rn, pn, info->safi, info->svrf); - break; - } - - return NB_OK; -} - static bool static_nexthop_create(struct nb_cb_create_args *args, const struct lyd_node *rn_dnode, struct stable_info *info) @@ -302,9 +287,27 @@ static int static_nexthop_mpls_label_modify(struct nb_cb_modify_args *args) static int static_nexthop_onlink_modify(struct nb_cb_modify_args *args) { struct static_nexthop *nh; + static_types nh_type; - nh = nb_running_get_entry(args->dnode, NULL, true); - nh->onlink = yang_dnode_get_bool(args->dnode, NULL); + switch (args->event) { + case NB_EV_VALIDATE: + nh_type = yang_dnode_get_enum(args->dnode, "../nh-type"); + if ((nh_type != STATIC_IPV4_GATEWAY_IFNAME) + && (nh_type != STATIC_IPV6_GATEWAY_IFNAME)) { + snprintf( + args->errmsg, args->errmsg_len, + "nexthop type is not the ipv4 or ipv6 interface type"); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + nh = nb_running_get_entry(args->dnode, NULL, true); + nh->onlink = yang_dnode_get_bool(args->dnode, NULL); + break; + } return NB_OK; } @@ -332,9 +335,25 @@ static int static_nexthop_color_destroy(struct nb_cb_destroy_args *args) static int static_nexthop_bh_type_modify(struct nb_cb_modify_args *args) { struct static_nexthop *nh; + static_types nh_type; - nh = nb_running_get_entry(args->dnode, NULL, true); - nh->bh_type = yang_dnode_get_enum(args->dnode, NULL); + switch (args->event) { + case NB_EV_VALIDATE: + nh_type = yang_dnode_get_enum(args->dnode, "../nh-type"); + if (nh_type != STATIC_BLACKHOLE) { + snprintf(args->errmsg, args->errmsg_len, + "nexthop type is not the blackhole type"); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + nh = nb_running_get_entry(args->dnode, NULL, true); + nh->bh_type = yang_dnode_get_enum(args->dnode, NULL); + break; + } return NB_OK; } @@ -580,38 +599,6 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_pa /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/table-id - */ -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_table_id_modify( - struct nb_cb_modify_args *args) -{ - struct route_node *rn; - const struct lyd_node *rn_dnode; - struct stable_info *info; - - switch (args->event) { - case NB_EV_VALIDATE: - if (static_path_list_tableid_modify(args, NULL, NULL) != NB_OK) - return NB_ERR_VALIDATION; - break; - case NB_EV_PREPARE: - case NB_EV_ABORT: - break; - case NB_EV_APPLY: - rn_dnode = yang_dnode_get_parent(args->dnode, "route-list"); - rn = nb_running_get_entry(rn_dnode, NULL, true); - info = route_table_get_info(rn->table); - - if (static_path_list_tableid_modify(args, rn_dnode, info) - != NB_OK) - return NB_ERR_VALIDATION; - break; - } - return NB_OK; -} - -/* - * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop */ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_create( @@ -636,7 +623,7 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_pa info = route_table_get_info(rn->table); if (static_nexthop_create(args, rn_dnode, info) != NB_OK) - return NB_ERR_VALIDATION; + return NB_ERR_INCONSISTENCY; break; } return NB_OK; @@ -673,17 +660,7 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_pa int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_bh_type_modify( struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - break; - case NB_EV_APPLY: - if (static_nexthop_bh_type_modify(args) != NB_OK) - return NB_ERR; - break; - } - return NB_OK; + return static_nexthop_bh_type_modify(args); } int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_bh_type_destroy( @@ -709,33 +686,7 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_pa int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_onlink_modify( struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - break; - case NB_EV_APPLY: - if (static_nexthop_onlink_modify(args) != NB_OK) - return NB_ERR; - - break; - } - return NB_OK; -} -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_onlink_destroy( - struct nb_cb_destroy_args *args) -{ - /* onlink has a boolean type with default value, - * so no need to do any operations in destroy callback - */ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - break; - } - return NB_OK; + return static_nexthop_onlink_modify(args); } /* @@ -1023,41 +974,6 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_sr /* * XPath: - * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/table-id - */ -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_table_id_modify( - struct nb_cb_modify_args *args) -{ - struct route_node *rn; - const struct lyd_node *rn_dnode; - const struct lyd_node *src_dnode; - struct stable_info *info; - - switch (args->event) { - case NB_EV_VALIDATE: - if (static_path_list_tableid_modify(args, NULL, NULL) != NB_OK) - return NB_ERR_VALIDATION; - break; - case NB_EV_PREPARE: - case NB_EV_ABORT: - break; - case NB_EV_APPLY: - src_dnode = yang_dnode_get_parent(args->dnode, "src-list"); - rn_dnode = yang_dnode_get_parent(src_dnode, "route-list"); - rn = nb_running_get_entry(rn_dnode, NULL, true); - info = route_table_get_info(rn->table); - - if (static_path_list_tableid_modify(args, src_dnode, info) - != NB_OK) - return NB_ERR_VALIDATION; - - break; - } - return NB_OK; -} - -/* - * XPath: * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop */ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_create( @@ -1124,17 +1040,7 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_sr int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_bh_type_modify( struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - break; - case NB_EV_APPLY: - if (static_nexthop_bh_type_modify(args) != NB_OK) - return NB_ERR; - break; - } - return NB_OK; + return static_nexthop_bh_type_modify(args); } int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_bh_type_destroy( @@ -1161,35 +1067,7 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_sr int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_onlink_modify( struct nb_cb_modify_args *args) { - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - break; - case NB_EV_APPLY: - if (static_nexthop_onlink_modify(args) != NB_OK) - return NB_ERR; - - break; - } - return NB_OK; -} - - -int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_onlink_destroy( - struct nb_cb_destroy_args *args) -{ - /* onlink has a boolean type with default value, - * so no need to do any operations in destroy callback - */ - switch (args->event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - break; - } - return NB_OK; + return static_nexthop_onlink_modify(args); } /* diff --git a/staticd/static_routes.c b/staticd/static_routes.c index 05355c48fe..1c436a66b0 100644 --- a/staticd/static_routes.c +++ b/staticd/static_routes.c @@ -161,7 +161,8 @@ bool static_add_nexthop_validate(struct static_vrf *svrf, static_types type, return true; } -struct static_path *static_add_path(struct route_node *rn, uint8_t distance) +struct static_path *static_add_path(struct route_node *rn, uint32_t table_id, + uint8_t distance) { struct static_path *pn; struct static_route_info *si; @@ -172,6 +173,7 @@ struct static_path *static_add_path(struct route_node *rn, uint8_t distance) pn = XCALLOC(MTYPE_STATIC_PATH, sizeof(struct static_path)); pn->distance = distance; + pn->table_id = table_id; static_nexthop_list_init(&(pn->nexthop_list)); si = rn->info; diff --git a/staticd/static_routes.h b/staticd/static_routes.h index bd2cd78fd9..470afb605d 100644 --- a/staticd/static_routes.h +++ b/staticd/static_routes.h @@ -187,7 +187,7 @@ extern void static_del_route(struct route_node *rn, safi_t safi, struct static_vrf *svrf); extern struct static_path *static_add_path(struct route_node *rn, - uint8_t distance); + uint32_t table_id, uint8_t distance); extern void static_del_path(struct route_node *rn, struct static_path *pn, safi_t safi, struct static_vrf *svrf); diff --git a/staticd/static_vty.c b/staticd/static_vty.c index c3c453f42d..1488cc1775 100644 --- a/staticd/static_vty.c +++ b/staticd/static_vty.c @@ -68,7 +68,6 @@ static int static_route_leak(struct vty *vty, const char *svrf, char buf_src_prefix[PREFIX_STRLEN]; char buf_nh_type[PREFIX_STRLEN]; char buf_tag[PREFIX_STRLEN]; - char buf_tableid[PREFIX_STRLEN]; uint8_t label_stack_id = 0; const char *buf_gate_str; uint8_t distance = ZEBRA_STATIC_DISTANCE_DEFAULT; @@ -162,14 +161,14 @@ static int static_route_leak(struct vty *vty, const char *svrf, "frr-staticd:staticd", "staticd", svrf, buf_prefix, yang_afi_safi_value2identity(afi, safi), - buf_src_prefix, distance); + buf_src_prefix, table_id, distance); else snprintf(xpath_prefix, sizeof(xpath_prefix), FRR_STATIC_ROUTE_INFO_KEY_XPATH, "frr-staticd:staticd", "staticd", svrf, buf_prefix, yang_afi_safi_value2identity(afi, safi), - distance); + table_id, distance); nb_cli_enqueue_change(vty, xpath_prefix, NB_OP_CREATE, NULL); @@ -180,12 +179,6 @@ static int static_route_leak(struct vty *vty, const char *svrf, sizeof(ab_xpath)); nb_cli_enqueue_change(vty, ab_xpath, NB_OP_MODIFY, buf_tag); - /* Table-Id processing */ - snprintf(buf_tableid, sizeof(buf_tableid), "%u", table_id); - strlcpy(ab_xpath, xpath_prefix, sizeof(ab_xpath)); - strlcat(ab_xpath, FRR_STATIC_ROUTE_PATH_TABLEID_XPATH, - sizeof(ab_xpath)); - nb_cli_enqueue_change(vty, ab_xpath, NB_OP_MODIFY, buf_tableid); /* nexthop processing */ snprintf(ab_xpath, sizeof(ab_xpath), @@ -289,16 +282,16 @@ static int static_route_leak(struct vty *vty, const char *svrf, "frr-staticd:staticd", "staticd", svrf, buf_prefix, yang_afi_safi_value2identity(afi, safi), - buf_src_prefix, distance, buf_nh_type, nh_svrf, - buf_gate_str, ifname); + buf_src_prefix, table_id, distance, + buf_nh_type, nh_svrf, buf_gate_str, ifname); else snprintf(ab_xpath, sizeof(ab_xpath), FRR_DEL_S_ROUTE_NH_KEY_XPATH, "frr-staticd:staticd", "staticd", svrf, buf_prefix, yang_afi_safi_value2identity(afi, safi), - distance, buf_nh_type, nh_svrf, buf_gate_str, - ifname); + table_id, distance, buf_nh_type, nh_svrf, + buf_gate_str, ifname); dnode = yang_dnode_get(vty->candidate_config->dnode, ab_xpath); if (!dnode) diff --git a/tests/bgpd/test_aspath.c b/tests/bgpd/test_aspath.c index 439891b559..936ffaaad5 100644 --- a/tests/bgpd/test_aspath.c +++ b/tests/bgpd/test_aspath.c @@ -1265,7 +1265,8 @@ int main(void) { int i = 0; qobj_init(); - bgp_master_init(thread_master_create(NULL), BGP_SOCKET_SNDBUF_SIZE); + bgp_master_init(thread_master_create(NULL), BGP_SOCKET_SNDBUF_SIZE, + list_new()); master = bm->master; bgp_option_set(BGP_OPT_NO_LISTEN); bgp_attr_init(); diff --git a/tests/bgpd/test_capability.c b/tests/bgpd/test_capability.c index 1b3f90434b..153b83897d 100644 --- a/tests/bgpd/test_capability.c +++ b/tests/bgpd/test_capability.c @@ -912,7 +912,7 @@ int main(void) qobj_init(); master = thread_master_create(NULL); - bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE); + bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new()); vrf_init(NULL, NULL, NULL, NULL, NULL); bgp_option_set(BGP_OPT_NO_LISTEN); diff --git a/tests/bgpd/test_mp_attr.c b/tests/bgpd/test_mp_attr.c index 7fabaad7fa..f510760913 100644 --- a/tests/bgpd/test_mp_attr.c +++ b/tests/bgpd/test_mp_attr.c @@ -1086,7 +1086,7 @@ int main(void) cmd_init(0); bgp_vty_init(); master = thread_master_create("test mp attr"); - bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE); + bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new()); vrf_init(NULL, NULL, NULL, NULL, NULL); bgp_option_set(BGP_OPT_NO_LISTEN); bgp_attr_init(); diff --git a/tests/bgpd/test_mpath.c b/tests/bgpd/test_mpath.c index 520c460f15..92efd4c3d6 100644 --- a/tests/bgpd/test_mpath.c +++ b/tests/bgpd/test_mpath.c @@ -393,7 +393,7 @@ static int global_test_init(void) qobj_init(); master = thread_master_create(NULL); zclient = zclient_new(master, &zclient_options_default); - bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE); + bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new()); vrf_init(NULL, NULL, NULL, NULL, NULL); bgp_option_set(BGP_OPT_NO_LISTEN); diff --git a/tests/bgpd/test_packet.c b/tests/bgpd/test_packet.c index d2c093fbea..db5918745d 100644 --- a/tests/bgpd/test_packet.c +++ b/tests/bgpd/test_packet.c @@ -59,7 +59,7 @@ int main(int argc, char *argv[]) qobj_init(); bgp_attr_init(); master = thread_master_create(NULL); - bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE); + bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new()); vrf_init(NULL, NULL, NULL, NULL, NULL); bgp_option_set(BGP_OPT_NO_LISTEN); diff --git a/tests/bgpd/test_peer_attr.c b/tests/bgpd/test_peer_attr.c index 0a15886c10..123d97bc97 100644 --- a/tests/bgpd/test_peer_attr.c +++ b/tests/bgpd/test_peer_attr.c @@ -1399,7 +1399,7 @@ static void bgp_startup(void) master = thread_master_create(NULL); yang_init(true); nb_init(master, bgpd_yang_modules, array_size(bgpd_yang_modules), false); - bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE); + bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new()); bgp_option_set(BGP_OPT_NO_LISTEN); vrf_init(NULL, NULL, NULL, NULL, NULL); frr_pthread_init(); diff --git a/tests/isisd/test_common.c b/tests/isisd/test_common.c index 5fa604c749..5b2028ffd4 100644 --- a/tests/isisd/test_common.c +++ b/tests/isisd/test_common.c @@ -69,6 +69,24 @@ test_find_adjacency(const struct isis_test_node *tnode, const char *hostname) return NULL; } +mpls_label_t test_topology_node_ldp_label(const struct isis_topology *topology, + struct in_addr router_id) +{ + for (size_t i = 0; topology->nodes[i].hostname[0]; i++) { + const struct isis_test_node *tnode = &topology->nodes[i]; + struct in_addr node_router_id; + + if (!tnode->router_id) + continue; + + (void)inet_pton(AF_INET, tnode->router_id, &node_router_id); + if (IPV4_ADDR_SAME(&router_id, &node_router_id)) + return (50000 + (i + 1) * 100); + } + + return MPLS_INVALID_LABEL; +} + static struct isis_lsp *lsp_add(struct lspdb_head *lspdb, struct isis_area *area, int level, const uint8_t *sysid, uint8_t pseudonode_id) diff --git a/tests/isisd/test_common.h b/tests/isisd/test_common.h index 6fd0d3813e..3359a893ac 100644 --- a/tests/isisd/test_common.h +++ b/tests/isisd/test_common.h @@ -70,6 +70,9 @@ test_topology_find_node(const struct isis_topology *topology, const char *hostname, uint8_t pseudonode_id); extern const struct isis_topology * test_topology_find(struct isis_topology *test_topologies, uint16_t number); +extern mpls_label_t +test_topology_node_ldp_label(const struct isis_topology *topology, + struct in_addr router_id); extern int test_topology_load(const struct isis_topology *topology, struct isis_area *area, struct lspdb_head lspdb[]); diff --git a/tests/isisd/test_isis_spf.c b/tests/isisd/test_isis_spf.c index 36ef93669b..e06944a037 100644 --- a/tests/isisd/test_isis_spf.c +++ b/tests/isisd/test_isis_spf.c @@ -31,6 +31,7 @@ #include "isisd/isisd.h" #include "isisd/isis_dynhn.h" #include "isisd/isis_misc.h" +#include "isisd/isis_route.h" #include "isisd/isis_spf.h" #include "isisd/isis_spf_private.h" @@ -40,6 +41,7 @@ enum test_type { TEST_SPF = 1, TEST_REVERSE_SPF, TEST_LFA, + TEST_RLFA, TEST_TI_LFA, }; @@ -105,6 +107,86 @@ static void test_run_lfa(struct vty *vty, const struct isis_topology *topology, isis_spftree_del(spftree_self); } +static void test_run_rlfa(struct vty *vty, const struct isis_topology *topology, + const struct isis_test_node *root, + struct isis_area *area, struct lspdb_head *lspdb, + int level, int tree, + struct lfa_protected_resource *protected_resource) +{ + struct isis_spftree *spftree_self; + struct isis_spftree *spftree_reverse; + struct isis_spftree *spftree_pc; + struct isis_spf_node *spf_node, *node; + struct rlfa *rlfa; + uint8_t flags; + + /* Run forward SPF in the root node. */ + flags = F_SPFTREE_NO_ADJACENCIES; + spftree_self = isis_spftree_new(area, lspdb, root->sysid, level, tree, + SPF_TYPE_FORWARD, flags); + isis_run_spf(spftree_self); + + /* Run reverse SPF in the root node. */ + spftree_reverse = isis_spf_reverse_run(spftree_self); + + /* Run forward SPF on all adjacent routers. */ + isis_spf_run_neighbors(spftree_self); + + /* Compute the local LFA repair paths. */ + isis_lfa_compute(area, NULL, spftree_self, protected_resource); + + /* Compute the remote LFA repair paths. */ + spftree_pc = isis_rlfa_compute(area, spftree_self, spftree_reverse, 0, + protected_resource); + + /* Print the extended P-space and Q-space. */ + vty_out(vty, "P-space (self):\n"); + RB_FOREACH (node, isis_spf_nodes, &spftree_pc->lfa.p_space) + vty_out(vty, " %s\n", print_sys_hostname(node->sysid)); + vty_out(vty, "\n"); + RB_FOREACH (spf_node, isis_spf_nodes, &spftree_self->adj_nodes) { + if (RB_EMPTY(isis_spf_nodes, &spf_node->lfa.p_space)) + continue; + vty_out(vty, "P-space (%s):\n", + print_sys_hostname(spf_node->sysid)); + RB_FOREACH (node, isis_spf_nodes, &spf_node->lfa.p_space) + vty_out(vty, " %s\n", print_sys_hostname(node->sysid)); + vty_out(vty, "\n"); + } + vty_out(vty, "Q-space:\n"); + RB_FOREACH (node, isis_spf_nodes, &spftree_pc->lfa.q_space) + vty_out(vty, " %s\n", print_sys_hostname(node->sysid)); + vty_out(vty, "\n"); + + /* Print the post-convergence SPT. */ + isis_print_spftree(vty, spftree_pc); + + /* + * Activate the computed RLFAs (if any) using artificial LDP labels for + * the PQ nodes. + */ + frr_each_safe (rlfa_tree, &spftree_self->lfa.remote.rlfas, rlfa) { + struct zapi_rlfa_response response = {}; + + response.pq_label = test_topology_node_ldp_label( + topology, rlfa->pq_address); + assert(response.pq_label != MPLS_INVALID_LABEL); + isis_rlfa_activate(spftree_self, rlfa, &response); + } + + /* Print the SPT and the corresponding main/backup routing tables. */ + isis_print_spftree(vty, spftree_self); + vty_out(vty, "Main:\n"); + isis_print_routes(vty, spftree_self, false, false); + vty_out(vty, "Backup:\n"); + isis_print_routes(vty, spftree_self, false, true); + + /* Cleanup everything. */ + isis_spftree_del(spftree_self); + isis_spftree_del(spftree_reverse); + isis_spftree_del(spftree_pc); +} + static void test_run_ti_lfa(struct vty *vty, const struct isis_topology *topology, const struct isis_test_node *root, @@ -242,6 +324,11 @@ static int test_run(struct vty *vty, const struct isis_topology *topology, &area->lspdb[level - 1], level, tree, &protected_resource); break; + case TEST_RLFA: + test_run_rlfa(vty, topology, root, area, + &area->lspdb[level - 1], level, + tree, &protected_resource); + break; case TEST_TI_LFA: test_run_ti_lfa(vty, topology, root, area, &area->lspdb[level - 1], level, @@ -266,6 +353,7 @@ DEFUN(test_isis, test_isis_cmd, spf\ |reverse-spf\ |lfa system-id WORD [pseudonode-id <1-255>]\ + |remote-lfa system-id WORD [pseudonode-id <1-255>]\ |ti-lfa system-id WORD [pseudonode-id <1-255>] [node-protection]\ >\ [display-lspdb] [<ipv4-only|ipv6-only>] [<level-1-only|level-2-only>]", @@ -282,6 +370,11 @@ DEFUN(test_isis, test_isis_cmd, "System ID\n" "Pseudonode-ID\n" "Pseudonode-ID\n" + "Remote LFA\n" + "System ID\n" + "System ID\n" + "Pseudonode-ID\n" + "Pseudonode-ID\n" "Topology Independent LFA\n" "System ID\n" "System ID\n" @@ -335,6 +428,14 @@ DEFUN(test_isis, test_isis_cmd, fail_pseudonode_id = strtoul(argv[idx + 1]->arg, NULL, 10); protection_type = LFA_LINK_PROTECTION; + } else if (argv_find(argv, argc, "remote-lfa", &idx)) { + test_type = TEST_RLFA; + + fail_sysid_str = argv[idx + 2]->arg; + if (argv_find(argv, argc, "pseudonode-id", &idx)) + fail_pseudonode_id = + strtoul(argv[idx + 1]->arg, NULL, 10); + protection_type = LFA_LINK_PROTECTION; } else if (argv_find(argv, argc, "ti-lfa", &idx)) { test_type = TEST_TI_LFA; diff --git a/tests/isisd/test_isis_spf.in b/tests/isisd/test_isis_spf.in index 93e18124e6..f8f65ffdf7 100644 --- a/tests/isisd/test_isis_spf.in +++ b/tests/isisd/test_isis_spf.in @@ -31,6 +31,18 @@ test isis topology 14 root rt1 lfa system-id rt1 pseudonode-id 1 test isis topology 14 root rt1 lfa system-id rt2 test isis topology 14 root rt5 lfa system-id rt4 +test isis topology 1 root rt1 remote-lfa system-id rt2 +test isis topology 2 root rt5 remote-lfa system-id rt1 pseudonode-id 1 +test isis topology 3 root rt5 remote-lfa system-id rt4 ipv4-only +test isis topology 3 root rt5 remote-lfa system-id rt3 ipv4-only +test isis topology 5 root rt1 remote-lfa system-id rt2 ipv4-only +test isis topology 6 root rt4 remote-lfa system-id rt3 ipv4-only +test isis topology 7 root rt11 remote-lfa system-id rt8 ipv4-only +test isis topology 7 root rt6 remote-lfa system-id rt5 ipv4-only +test isis topology 8 root rt2 remote-lfa system-id rt5 ipv4-only +test isis topology 11 root rt2 remote-lfa system-id rt4 +test isis topology 13 root rt1 remote-lfa system-id rt3 ipv4-only + test isis topology 1 root rt1 ti-lfa system-id rt2 test isis topology 2 root rt1 ti-lfa system-id rt3 test isis topology 2 root rt1 ti-lfa system-id rt1 pseudonode-id 1 diff --git a/tests/isisd/test_isis_spf.refout b/tests/isisd/test_isis_spf.refout index dced6fb103..024f7256e0 100644 --- a/tests/isisd/test_isis_spf.refout +++ b/tests/isisd/test_isis_spf.refout @@ -1807,6 +1807,1227 @@ IS-IS L1 IPv6 routing table: 2001:db8::4/128 60 - rt3 -
test#
+test# test isis topology 1 root rt1 remote-lfa system-id rt2
+P-space (self):
+ rt3
+ rt5
+
+P-space (rt3):
+ rt3
+ rt5
+ rt6
+
+Q-space:
+ rt2
+ rt4
+ rt6
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt6 TE-IS 30 rt3 - rt5(4)
+10.0.255.5/32 IP TE 30 rt3 - rt5(4)
+rt4 TE-IS 40 rt3 - rt6(4)
+10.0.255.6/32 IP TE 40 rt3 - rt6(4)
+rt2 TE-IS 50 rt3 - rt4(4)
+10.0.255.4/32 IP TE 50 rt3 - rt4(4)
+10.0.255.2/32 IP TE 60 rt3 - rt2(4)
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt6 TE-IS 30 rt2 - rt4(4)
+ rt3 - rt5(4)
+10.0.255.4/32 IP TE 30 rt2 - rt4(4)
+10.0.255.5/32 IP TE 30 rt3 - rt5(4)
+10.0.255.6/32 IP TE 40 rt2 - rt6(4)
+ rt3 -
+
+Main:
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 0 - - -
+ 10.0.255.2/32 20 - rt2 implicit-null
+ 10.0.255.3/32 20 - rt3 implicit-null
+ 10.0.255.4/32 30 - rt2 16040
+ 10.0.255.5/32 30 - rt3 16050
+ 10.0.255.6/32 40 - rt2 16060
+ - rt3 16060
+
+Backup:
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ --------------------------------------------------------
+ 10.0.255.2/32 60 - rt3 50600/16020
+ 10.0.255.4/32 50 - rt3 50600/16040
+
+P-space (self):
+ rt3
+ rt5
+
+P-space (rt3):
+ rt3
+ rt5
+ rt6
+
+Q-space:
+ rt2
+ rt4
+ rt6
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+2001:db8::1/128 IP6 internal 0 rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+2001:db8::3/128 IP6 internal 20 rt3 - rt3(4)
+rt6 TE-IS 30 rt3 - rt5(4)
+2001:db8::5/128 IP6 internal 30 rt3 - rt5(4)
+rt4 TE-IS 40 rt3 - rt6(4)
+2001:db8::6/128 IP6 internal 40 rt3 - rt6(4)
+rt2 TE-IS 50 rt3 - rt4(4)
+2001:db8::4/128 IP6 internal 50 rt3 - rt4(4)
+2001:db8::2/128 IP6 internal 60 rt3 - rt2(4)
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+2001:db8::1/128 IP6 internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+2001:db8::2/128 IP6 internal 20 rt2 - rt2(4)
+2001:db8::3/128 IP6 internal 20 rt3 - rt3(4)
+rt6 TE-IS 30 rt2 - rt4(4)
+ rt3 - rt5(4)
+2001:db8::4/128 IP6 internal 30 rt2 - rt4(4)
+2001:db8::5/128 IP6 internal 30 rt3 - rt5(4)
+2001:db8::6/128 IP6 internal 40 rt2 - rt6(4)
+ rt3 -
+
+Main:
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ------------------------------------------------------------
+ 2001:db8::1/128 0 - - -
+ 2001:db8::2/128 20 - rt2 implicit-null
+ 2001:db8::3/128 20 - rt3 implicit-null
+ 2001:db8::4/128 30 - rt2 16041
+ 2001:db8::5/128 30 - rt3 16051
+ 2001:db8::6/128 40 - rt2 16061
+ - rt3 16061
+
+Backup:
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 2001:db8::2/128 60 - rt3 50600/16021
+ 2001:db8::4/128 50 - rt3 50600/16041
+
+test# test isis topology 2 root rt5 remote-lfa system-id rt1 pseudonode-id 1
+P-space (self):
+ rt6
+
+P-space (rt3):
+ rt1
+ rt2
+ rt3
+ rt4
+
+P-space (rt6):
+ rt4
+ rt6
+
+Q-space:
+ rt1
+ rt2
+ rt3
+ rt4
+ rt6
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt5
+10.0.255.5/32 IP internal 0 rt5(4)
+rt6 TE-IS 10 rt6 - rt5(4)
+rt4 TE-IS 20 rt6 - rt6(4)
+10.0.255.6/32 IP TE 20 rt6 - rt6(4)
+rt1 pseudo_TE-IS 30 rt6 - rt4(4)
+rt1 TE-IS 30 rt6 - rt1(2)
+10.0.255.4/32 IP TE 30 rt6 - rt4(4)
+rt3 TE-IS 40 rt3 - rt5(4)
+10.0.255.1/32 IP TE 40 rt6 - rt1(4)
+rt2 TE-IS 45 rt6 - rt1(4)
+10.0.255.3/32 IP TE 50 rt3 - rt3(4)
+10.0.255.2/32 IP TE 55 rt6 - rt2(4)
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt5
+10.0.255.5/32 IP internal 0 rt5(4)
+rt1 TE-IS 10 rt1 - rt5(4)
+rt4 TE-IS 10 rt4 - rt5(4)
+rt6 TE-IS 10 rt6 - rt5(4)
+rt1 pseudo_TE-IS 20 rt1 - rt1(4)
+ rt4 - rt4(4)
+10.0.255.1/32 IP TE 20 rt1 - rt1(4)
+10.0.255.4/32 IP TE 20 rt4 - rt4(4)
+10.0.255.6/32 IP TE 20 rt6 - rt6(4)
+rt2 TE-IS 25 rt1 - rt1(4)
+10.0.255.2/32 IP TE 35 rt1 - rt2(4)
+rt3 TE-IS 40 rt3 - rt5(4)
+ rt1 - rt1(4)
+10.0.255.3/32 IP TE 50 rt3 - rt3(4)
+ rt1 -
+
+Main:
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 20 - rt1 implicit-null
+ 10.0.255.2/32 35 - rt1 16020
+ 10.0.255.3/32 50 - rt3 implicit-null
+ - rt1 implicit-null
+ 10.0.255.4/32 20 - rt4 implicit-null
+ 10.0.255.5/32 0 - - -
+ 10.0.255.6/32 20 - rt6 implicit-null
+
+Backup:
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ --------------------------------------------------------
+ 10.0.255.1/32 40 - rt6 50400/16010
+ 10.0.255.2/32 55 - rt6 50400/16020
+ 10.0.255.4/32 30 - rt6 50400/16040
+
+P-space (self):
+ rt6
+
+P-space (rt3):
+ rt1
+ rt2
+ rt3
+ rt4
+
+P-space (rt6):
+ rt4
+ rt6
+
+Q-space:
+ rt1
+ rt2
+ rt3
+ rt4
+ rt6
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt5
+2001:db8::5/128 IP6 internal 0 rt5(4)
+rt6 TE-IS 10 rt6 - rt5(4)
+rt4 TE-IS 20 rt6 - rt6(4)
+2001:db8::6/128 IP6 internal 20 rt6 - rt6(4)
+rt1 pseudo_TE-IS 30 rt6 - rt4(4)
+rt1 TE-IS 30 rt6 - rt1(2)
+2001:db8::4/128 IP6 internal 30 rt6 - rt4(4)
+rt3 TE-IS 40 rt3 - rt5(4)
+2001:db8::1/128 IP6 internal 40 rt6 - rt1(4)
+rt2 TE-IS 45 rt6 - rt1(4)
+2001:db8::3/128 IP6 internal 50 rt3 - rt3(4)
+2001:db8::2/128 IP6 internal 55 rt6 - rt2(4)
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt5
+2001:db8::5/128 IP6 internal 0 rt5(4)
+rt1 TE-IS 10 rt1 - rt5(4)
+rt4 TE-IS 10 rt4 - rt5(4)
+rt6 TE-IS 10 rt6 - rt5(4)
+rt1 pseudo_TE-IS 20 rt1 - rt1(4)
+ rt4 - rt4(4)
+2001:db8::1/128 IP6 internal 20 rt1 - rt1(4)
+2001:db8::4/128 IP6 internal 20 rt4 - rt4(4)
+2001:db8::6/128 IP6 internal 20 rt6 - rt6(4)
+rt2 TE-IS 25 rt1 - rt1(4)
+2001:db8::2/128 IP6 internal 35 rt1 - rt2(4)
+rt3 TE-IS 40 rt3 - rt5(4)
+ rt1 - rt1(4)
+2001:db8::3/128 IP6 internal 50 rt3 - rt3(4)
+ rt1 -
+
+Main:
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ------------------------------------------------------------
+ 2001:db8::1/128 20 - rt1 implicit-null
+ 2001:db8::2/128 35 - rt1 16021
+ 2001:db8::3/128 50 - rt3 implicit-null
+ - rt1 implicit-null
+ 2001:db8::4/128 20 - rt4 implicit-null
+ 2001:db8::5/128 0 - - -
+ 2001:db8::6/128 20 - rt6 implicit-null
+
+Backup:
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 2001:db8::1/128 40 - rt6 50400/16011
+ 2001:db8::2/128 55 - rt6 50400/16021
+ 2001:db8::4/128 30 - rt6 50400/16041
+
+test# test isis topology 3 root rt5 remote-lfa system-id rt4 ipv4-only
+P-space (self):
+ rt6
+
+P-space (rt3):
+ rt1
+ rt2
+ rt3
+ rt4
+ rt6
+
+P-space (rt6):
+ rt1
+ rt2
+ rt3
+ rt4
+ rt6
+
+Q-space:
+ rt1
+ rt2
+ rt3
+ rt4
+ rt6
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt5
+10.0.255.5/32 IP internal 0 rt5(4)
+rt6 TE-IS 10 rt6 - rt5(4)
+rt4 TE-IS 20 rt6 - rt6(4)
+10.0.255.6/32 IP TE 20 rt6 - rt6(4)
+rt3 TE-IS 30 rt3 - rt5(4)
+rt2 TE-IS 30 rt6 - rt4(4)
+10.0.255.4/32 IP TE 30 rt6 - rt4(4)
+rt1 TE-IS 40 rt3 - rt3(4)
+ rt6 - rt2(4)
+10.0.255.3/32 IP TE 40 rt3 - rt3(4)
+10.0.255.2/32 IP TE 40 rt6 - rt2(4)
+10.0.255.1/32 IP TE 50 rt3 - rt1(4)
+ rt6 -
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt5
+10.0.255.5/32 IP internal 0 rt5(4)
+rt4 TE-IS 10 rt4 - rt5(4)
+rt6 TE-IS 10 rt6 - rt5(4)
+rt2 TE-IS 20 rt4 - rt4(4)
+10.0.255.4/32 IP TE 20 rt4 - rt4(4)
+10.0.255.6/32 IP TE 20 rt6 - rt6(4)
+rt3 TE-IS 30 rt3 - rt5(4)
+ rt4 - rt2(4)
+rt1 TE-IS 30 rt4 - rt2(4)
+10.0.255.2/32 IP TE 30 rt4 - rt2(4)
+10.0.255.3/32 IP TE 40 rt3 - rt3(4)
+ rt4 -
+10.0.255.1/32 IP TE 40 rt4 - rt1(4)
+
+Main:
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 40 - rt4 16010
+ 10.0.255.2/32 30 - rt4 16020
+ 10.0.255.3/32 40 - rt3 implicit-null
+ - rt4 implicit-null
+ 10.0.255.4/32 20 - rt4 implicit-null
+ 10.0.255.5/32 0 - - -
+ 10.0.255.6/32 20 - rt6 implicit-null
+
+Backup:
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------
+ 10.0.255.1/32 40 - rt3 16010
+ - rt6 16010
+ 10.0.255.2/32 30 - rt3 16020
+ - rt6 16020
+ 10.0.255.4/32 20 - rt3 16040
+ - rt6 16040
+
+test# test isis topology 3 root rt5 remote-lfa system-id rt3 ipv4-only
+P-space (self):
+ rt1
+ rt2
+ rt4
+ rt6
+
+P-space (rt4):
+ rt1
+ rt2
+ rt3
+ rt4
+ rt6
+
+P-space (rt6):
+ rt1
+ rt2
+ rt3
+ rt4
+ rt6
+
+Q-space:
+ rt1
+ rt2
+ rt3
+ rt4
+ rt6
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt5
+10.0.255.5/32 IP internal 0 rt5(4)
+rt4 TE-IS 10 rt4 - rt5(4)
+rt6 TE-IS 10 rt6 - rt5(4)
+rt2 TE-IS 20 rt4 - rt4(4)
+10.0.255.4/32 IP TE 20 rt4 - rt4(4)
+10.0.255.6/32 IP TE 20 rt6 - rt6(4)
+rt1 TE-IS 30 rt4 - rt2(4)
+rt3 TE-IS 30 rt4 - rt2(4)
+10.0.255.2/32 IP TE 30 rt4 - rt2(4)
+10.0.255.1/32 IP TE 40 rt4 - rt1(4)
+10.0.255.3/32 IP TE 40 rt4 - rt3(4)
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt5
+10.0.255.5/32 IP internal 0 rt5(4)
+rt4 TE-IS 10 rt4 - rt5(4)
+rt6 TE-IS 10 rt6 - rt5(4)
+rt2 TE-IS 20 rt4 - rt4(4)
+10.0.255.4/32 IP TE 20 rt4 - rt4(4)
+10.0.255.6/32 IP TE 20 rt6 - rt6(4)
+rt3 TE-IS 30 rt3 - rt5(4)
+ rt4 - rt2(4)
+rt1 TE-IS 30 rt4 - rt2(4)
+10.0.255.2/32 IP TE 30 rt4 - rt2(4)
+10.0.255.3/32 IP TE 40 rt3 - rt3(4)
+ rt4 -
+10.0.255.1/32 IP TE 40 rt4 - rt1(4)
+
+Main:
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 40 - rt4 16010
+ 10.0.255.2/32 30 - rt4 16020
+ 10.0.255.3/32 40 - rt3 implicit-null
+ - rt4 implicit-null
+ 10.0.255.4/32 20 - rt4 implicit-null
+ 10.0.255.5/32 0 - - -
+ 10.0.255.6/32 20 - rt6 implicit-null
+
+Backup:
+IS-IS L1 IPv4 routing table:
+
+test# test isis topology 5 root rt1 remote-lfa system-id rt2 ipv4-only
+P-space (self):
+ rt3
+ rt5
+ rt7
+
+P-space (rt3):
+ rt3
+ rt5
+ rt7
+ rt8
+
+Q-space:
+ rt2
+ rt4
+ rt6
+ rt8
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt7 TE-IS 30 rt3 - rt5(4)
+10.0.255.5/32 IP TE 30 rt3 - rt5(4)
+rt8 TE-IS 40 rt3 - rt7(4)
+10.0.255.7/32 IP TE 40 rt3 - rt7(4)
+rt6 TE-IS 50 rt3 - rt8(4)
+10.0.255.8/32 IP TE 50 rt3 - rt8(4)
+rt4 TE-IS 60 rt3 - rt6(4)
+10.0.255.6/32 IP TE 60 rt3 - rt6(4)
+rt2 TE-IS 70 rt3 - rt4(4)
+10.0.255.4/32 IP TE 70 rt3 - rt4(4)
+10.0.255.2/32 IP TE 80 rt3 - rt2(4)
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt6 TE-IS 30 rt2 - rt4(4)
+rt7 TE-IS 30 rt3 - rt5(4)
+10.0.255.4/32 IP TE 30 rt2 - rt4(4)
+10.0.255.5/32 IP TE 30 rt3 - rt5(4)
+rt8 TE-IS 40 rt2 - rt6(4)
+ rt3 - rt7(4)
+10.0.255.6/32 IP TE 40 rt2 - rt6(4)
+10.0.255.7/32 IP TE 40 rt3 - rt7(4)
+10.0.255.8/32 IP TE 50 rt2 - rt8(4)
+ rt3 -
+
+Main:
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 0 - - -
+ 10.0.255.2/32 20 - rt2 implicit-null
+ 10.0.255.3/32 20 - rt3 implicit-null
+ 10.0.255.4/32 30 - rt2 16040
+ 10.0.255.5/32 30 - rt3 16050
+ 10.0.255.6/32 40 - rt2 16060
+ 10.0.255.7/32 40 - rt3 16070
+ 10.0.255.8/32 50 - rt2 16080
+ - rt3 16080
+
+Backup:
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ --------------------------------------------------------
+ 10.0.255.2/32 80 - rt3 50800/16020
+ 10.0.255.4/32 70 - rt3 50800/16040
+ 10.0.255.6/32 60 - rt3 50800/16060
+
+test# test isis topology 6 root rt4 remote-lfa system-id rt3 ipv4-only
+P-space (self):
+ rt2
+ rt5
+ rt6
+ rt7
+ rt8
+
+P-space (rt2):
+ rt1
+ rt2
+
+P-space (rt6):
+ rt5
+ rt6
+ rt7
+ rt8
+
+Q-space:
+ rt1
+ rt3
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt4
+10.0.255.4/32 IP internal 0 rt4(4)
+rt2 TE-IS 10 rt2 - rt4(4)
+rt6 TE-IS 10 rt6 - rt4(4)
+rt1 TE-IS 20 rt2 - rt2(4)
+rt5 TE-IS 20 rt6 - rt6(4)
+rt8 TE-IS 20 rt6 - rt6(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+10.0.255.6/32 IP TE 20 rt6 - rt6(4)
+rt3 TE-IS 30 rt2 - rt1(4)
+rt7 TE-IS 30 rt6 - rt5(4)
+ rt8(4)
+10.0.255.1/32 IP TE 30 rt2 - rt1(4)
+10.0.255.5/32 IP TE 30 rt6 - rt5(4)
+10.0.255.8/32 IP TE 30 rt6 - rt8(4)
+10.0.255.3/32 IP TE 40 rt2 - rt3(4)
+10.0.255.7/32 IP TE 40 rt6 - rt7(4)
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt4
+10.0.255.4/32 IP internal 0 rt4(4)
+rt2 TE-IS 10 rt2 - rt4(4)
+rt3 TE-IS 10 rt3 - rt4(4)
+rt6 TE-IS 10 rt6 - rt4(4)
+rt1 TE-IS 20 rt2 - rt2(4)
+ rt3 - rt3(4)
+rt5 TE-IS 20 rt6 - rt6(4)
+rt8 TE-IS 20 rt6 - rt6(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+10.0.255.6/32 IP TE 20 rt6 - rt6(4)
+rt7 TE-IS 30 rt6 - rt5(4)
+ rt8(4)
+10.0.255.1/32 IP TE 30 rt2 - rt1(4)
+ rt3 -
+10.0.255.5/32 IP TE 30 rt6 - rt5(4)
+10.0.255.8/32 IP TE 30 rt6 - rt8(4)
+10.0.255.7/32 IP TE 40 rt6 - rt7(4)
+
+Main:
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 30 - rt2 16010
+ - rt3 16010
+ 10.0.255.2/32 20 - rt2 implicit-null
+ 10.0.255.3/32 20 - rt3 implicit-null
+ 10.0.255.4/32 0 - - -
+ 10.0.255.5/32 30 - rt6 16050
+ 10.0.255.6/32 20 - rt6 implicit-null
+ 10.0.255.7/32 40 - rt6 16070
+ 10.0.255.8/32 30 - rt6 16080
+
+Backup:
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ --------------------------------------------------------
+ 10.0.255.3/32 40 - rt2 50100/16030
+
+test# test isis topology 7 root rt11 remote-lfa system-id rt8 ipv4-only
+P-space (self):
+ rt10
+ rt12
+
+P-space (rt10):
+ rt1
+ rt4
+ rt7
+ rt10
+
+P-space (rt12):
+ rt9
+ rt12
+
+Q-space:
+ rt1
+ rt2
+ rt3
+ rt4
+ rt5
+ rt6
+ rt7
+ rt8
+ rt9
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt11
+10.0.255.11/32 IP internal 0 rt11(4)
+rt10 TE-IS 10 rt10 - rt11(4)
+rt12 TE-IS 10 rt12 - rt11(4)
+rt9 TE-IS 20 rt12 - rt12(4)
+10.0.255.10/32 IP TE 20 rt10 - rt10(4)
+10.0.255.12/32 IP TE 20 rt12 - rt12(4)
+rt7 TE-IS 30 rt10 - rt10(4)
+rt8 TE-IS 30 rt12 - rt9(4)
+10.0.255.9/32 IP TE 30 rt12 - rt9(4)
+rt4 TE-IS 40 rt10 - rt7(4)
+rt5 TE-IS 40 rt12 - rt8(4)
+10.0.255.7/32 IP TE 40 rt10 - rt7(4)
+10.0.255.8/32 IP TE 40 rt12 - rt8(4)
+rt6 TE-IS 50 rt12 - rt9(4)
+ rt5(4)
+rt1 TE-IS 50 rt10 - rt4(4)
+rt2 TE-IS 50 rt12 - rt5(4)
+10.0.255.4/32 IP TE 50 rt10 - rt4(4)
+10.0.255.5/32 IP TE 50 rt12 - rt5(4)
+rt3 TE-IS 60 rt12 - rt6(4)
+ rt2(4)
+10.0.255.6/32 IP TE 60 rt12 - rt6(4)
+10.0.255.1/32 IP TE 60 rt10 - rt1(4)
+10.0.255.2/32 IP TE 60 rt12 - rt2(4)
+10.0.255.3/32 IP TE 70 rt12 - rt3(4)
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt11
+10.0.255.11/32 IP internal 0 rt11(4)
+rt8 TE-IS 10 rt8 - rt11(4)
+rt10 TE-IS 10 rt10 - rt11(4)
+rt12 TE-IS 10 rt12 - rt11(4)
+rt5 TE-IS 20 rt8 - rt8(4)
+rt7 TE-IS 20 rt8 - rt8(4)
+rt9 TE-IS 20 rt8 - rt8(4)
+ rt12 - rt12(4)
+10.0.255.8/32 IP TE 20 rt8 - rt8(4)
+10.0.255.10/32 IP TE 20 rt10 - rt10(4)
+10.0.255.12/32 IP TE 20 rt12 - rt12(4)
+rt2 TE-IS 30 rt8 - rt5(4)
+rt4 TE-IS 30 rt8 - rt5(4)
+ rt7(4)
+rt6 TE-IS 30 rt8 - rt5(4)
+10.0.255.5/32 IP TE 30 rt8 - rt5(4)
+10.0.255.7/32 IP TE 30 rt8 - rt7(4)
+10.0.255.9/32 IP TE 30 rt8 - rt9(4)
+ rt12 -
+rt3 TE-IS 40 rt8 - rt2(4)
+ rt6(4)
+rt1 TE-IS 40 rt8 - rt4(4)
+10.0.255.2/32 IP TE 40 rt8 - rt2(4)
+10.0.255.4/32 IP TE 40 rt8 - rt4(4)
+10.0.255.6/32 IP TE 40 rt8 - rt6(4)
+10.0.255.3/32 IP TE 50 rt8 - rt3(4)
+10.0.255.1/32 IP TE 50 rt8 - rt1(4)
+
+Main:
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------------
+ 10.0.255.1/32 50 - rt8 16010
+ 10.0.255.2/32 40 - rt8 16020
+ 10.0.255.3/32 50 - rt8 16030
+ 10.0.255.4/32 40 - rt8 16040
+ 10.0.255.5/32 30 - rt8 16050
+ 10.0.255.6/32 40 - rt8 16060
+ 10.0.255.7/32 30 - rt8 16070
+ 10.0.255.8/32 20 - rt8 implicit-null
+ 10.0.255.9/32 30 - rt8 16090
+ - rt12 16090
+ 10.0.255.10/32 20 - rt10 implicit-null
+ 10.0.255.11/32 0 - - -
+ 10.0.255.12/32 20 - rt12 implicit-null
+
+Backup:
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ --------------------------------------------------------
+ 10.0.255.1/32 50 - rt10 16010
+ 10.0.255.2/32 60 - rt12 50900/16020
+ 10.0.255.3/32 70 - rt12 50900/16030
+ 10.0.255.4/32 40 - rt10 16040
+ 10.0.255.5/32 50 - rt12 50900/16050
+ 10.0.255.6/32 60 - rt12 50900/16060
+ 10.0.255.7/32 30 - rt10 16070
+ 10.0.255.8/32 40 - rt12 50900/16080
+
+test# test isis topology 7 root rt6 remote-lfa system-id rt5 ipv4-only
+P-space (self):
+ rt3
+
+P-space (rt3):
+ rt2
+ rt3
+
+P-space (rt9):
+ rt1
+ rt2
+ rt4
+ rt5
+ rt7
+ rt8
+ rt9
+ rt10
+ rt11
+ rt12
+
+Q-space:
+ rt1
+ rt2
+ rt4
+ rt5
+ rt7
+ rt8
+ rt9
+ rt10
+ rt11
+ rt12
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt6
+10.0.255.6/32 IP internal 0 rt6(4)
+rt3 TE-IS 10 rt3 - rt6(4)
+rt2 TE-IS 20 rt3 - rt3(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt9 TE-IS 30 rt9 - rt6(4)
+rt5 TE-IS 30 rt3 - rt2(4)
+10.0.255.2/32 IP TE 30 rt3 - rt2(4)
+rt8 TE-IS 40 rt9 - rt9(4)
+ rt3 - rt5(4)
+rt12 TE-IS 40 rt9 - rt9(4)
+rt4 TE-IS 40 rt3 - rt5(4)
+10.0.255.9/32 IP TE 40 rt9 - rt9(4)
+10.0.255.5/32 IP TE 40 rt3 - rt5(4)
+rt7 TE-IS 50 rt9 - rt8(4)
+ rt3 - rt4(4)
+rt11 TE-IS 50 rt9 - rt8(4)
+ rt3 - rt12(4)
+rt1 TE-IS 50 rt3 - rt4(4)
+10.0.255.8/32 IP TE 50 rt9 - rt8(4)
+ rt3 -
+10.0.255.12/32 IP TE 50 rt9 - rt12(4)
+10.0.255.4/32 IP TE 50 rt3 - rt4(4)
+rt10 TE-IS 60 rt9 - rt11(4)
+ rt3 -
+10.0.255.7/32 IP TE 60 rt9 - rt7(4)
+ rt3 -
+10.0.255.11/32 IP TE 60 rt9 - rt11(4)
+ rt3 -
+10.0.255.1/32 IP TE 60 rt3 - rt1(4)
+10.0.255.10/32 IP TE 70 rt9 - rt10(4)
+ rt3 -
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt6
+10.0.255.6/32 IP internal 0 rt6(4)
+rt3 TE-IS 10 rt3 - rt6(4)
+rt5 TE-IS 10 rt5 - rt6(4)
+rt2 TE-IS 20 rt3 - rt3(4)
+ rt5 - rt5(4)
+rt4 TE-IS 20 rt5 - rt5(4)
+rt8 TE-IS 20 rt5 - rt5(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+10.0.255.5/32 IP TE 20 rt5 - rt5(4)
+rt9 TE-IS 30 rt9 - rt6(4)
+ rt5 - rt8(4)
+rt1 TE-IS 30 rt5 - rt4(4)
+rt7 TE-IS 30 rt5 - rt4(4)
+ rt8(4)
+rt11 TE-IS 30 rt5 - rt8(4)
+10.0.255.2/32 IP TE 30 rt3 - rt2(4)
+ rt5 -
+10.0.255.4/32 IP TE 30 rt5 - rt4(4)
+10.0.255.8/32 IP TE 30 rt5 - rt8(4)
+rt12 TE-IS 40 rt9 - rt9(4)
+ rt5 - rt11(4)
+rt10 TE-IS 40 rt5 - rt11(4)
+10.0.255.9/32 IP TE 40 rt9 - rt9(4)
+ rt5 -
+10.0.255.1/32 IP TE 40 rt5 - rt1(4)
+10.0.255.7/32 IP TE 40 rt5 - rt7(4)
+10.0.255.11/32 IP TE 40 rt5 - rt11(4)
+10.0.255.12/32 IP TE 50 rt9 - rt12(4)
+ rt5 -
+10.0.255.10/32 IP TE 50 rt5 - rt10(4)
+
+Main:
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------------
+ 10.0.255.1/32 40 - rt5 16010
+ 10.0.255.2/32 30 - rt3 16020
+ - rt5 16020
+ 10.0.255.3/32 20 - rt3 implicit-null
+ 10.0.255.4/32 30 - rt5 16040
+ 10.0.255.5/32 20 - rt5 implicit-null
+ 10.0.255.6/32 0 - - -
+ 10.0.255.7/32 40 - rt5 16070
+ 10.0.255.8/32 30 - rt5 16080
+ 10.0.255.9/32 40 - rt9 implicit-null
+ - rt5 implicit-null
+ 10.0.255.10/32 50 - rt5 16100
+ 10.0.255.11/32 40 - rt5 16110
+ 10.0.255.12/32 50 - rt9 16120
+ - rt5 16120
+
+Backup:
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ------------------------------------------------------
+ 10.0.255.1/32 70 - rt9 16010
+ 10.0.255.4/32 60 - rt9 16040
+ 10.0.255.5/32 50 - rt9 16050
+ 10.0.255.7/32 50 - rt9 16070
+ 10.0.255.8/32 40 - rt9 16080
+ 10.0.255.10/32 60 - rt9 16100
+ 10.0.255.11/32 50 - rt9 16110
+
+test# test isis topology 8 root rt2 remote-lfa system-id rt5 ipv4-only
+P-space (self):
+ rt1
+ rt3
+ rt4
+ rt7
+ rt10
+
+P-space (rt1):
+ rt1
+ rt4
+ rt7
+ rt10
+
+P-space (rt3):
+ rt3
+ rt6
+
+Q-space:
+ rt5
+ rt6
+ rt8
+ rt9
+ rt11
+ rt12
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt2
+10.0.255.2/32 IP internal 0 rt2(4)
+rt1 TE-IS 10 rt1 - rt2(4)
+rt3 TE-IS 10 rt3 - rt2(4)
+rt4 TE-IS 20 rt1 - rt1(4)
+rt6 TE-IS 20 rt3 - rt3(4)
+10.0.255.1/32 IP TE 20 rt1 - rt1(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt7 TE-IS 30 rt1 - rt4(4)
+rt5 TE-IS 30 rt3 - rt6(4)
+10.0.255.4/32 IP TE 30 rt1 - rt4(4)
+10.0.255.6/32 IP TE 30 rt3 - rt6(4)
+rt10 TE-IS 40 rt1 - rt7(4)
+rt8 TE-IS 40 rt3 - rt5(4)
+10.0.255.7/32 IP TE 40 rt1 - rt7(4)
+10.0.255.5/32 IP TE 40 rt3 - rt5(4)
+rt9 TE-IS 50 rt3 - rt8(4)
+rt11 TE-IS 50 rt3 - rt8(4)
+10.0.255.10/32 IP TE 50 rt1 - rt10(4)
+10.0.255.8/32 IP TE 50 rt3 - rt8(4)
+rt12 TE-IS 60 rt3 - rt9(4)
+ rt11(4)
+10.0.255.9/32 IP TE 60 rt3 - rt9(4)
+10.0.255.11/32 IP TE 60 rt3 - rt11(4)
+10.0.255.12/32 IP TE 70 rt3 - rt12(4)
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt2
+10.0.255.2/32 IP internal 0 rt2(4)
+rt1 TE-IS 10 rt1 - rt2(4)
+rt3 TE-IS 10 rt3 - rt2(4)
+rt5 TE-IS 10 rt5 - rt2(4)
+rt4 TE-IS 20 rt1 - rt1(4)
+rt6 TE-IS 20 rt3 - rt3(4)
+ rt5 - rt5(4)
+rt8 TE-IS 20 rt5 - rt5(4)
+10.0.255.1/32 IP TE 20 rt1 - rt1(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+10.0.255.5/32 IP TE 20 rt5 - rt5(4)
+rt7 TE-IS 30 rt1 - rt4(4)
+rt9 TE-IS 30 rt5 - rt8(4)
+rt11 TE-IS 30 rt5 - rt8(4)
+10.0.255.4/32 IP TE 30 rt1 - rt4(4)
+10.0.255.6/32 IP TE 30 rt3 - rt6(4)
+ rt5 -
+10.0.255.8/32 IP TE 30 rt5 - rt8(4)
+rt10 TE-IS 40 rt1 - rt7(4)
+rt12 TE-IS 40 rt5 - rt9(4)
+ rt11(4)
+10.0.255.7/32 IP TE 40 rt1 - rt7(4)
+10.0.255.9/32 IP TE 40 rt5 - rt9(4)
+10.0.255.11/32 IP TE 40 rt5 - rt11(4)
+10.0.255.10/32 IP TE 50 rt1 - rt10(4)
+10.0.255.12/32 IP TE 50 rt5 - rt12(4)
+
+Main:
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ -----------------------------------------------------------
+ 10.0.255.1/32 20 - rt1 implicit-null
+ 10.0.255.2/32 0 - - -
+ 10.0.255.3/32 20 - rt3 implicit-null
+ 10.0.255.4/32 30 - rt1 16040
+ 10.0.255.5/32 20 - rt5 implicit-null
+ 10.0.255.6/32 30 - rt3 16060
+ - rt5 16060
+ 10.0.255.7/32 40 - rt1 16070
+ 10.0.255.8/32 30 - rt5 16080
+ 10.0.255.9/32 40 - rt5 16090
+ 10.0.255.10/32 50 - rt1 16100
+ 10.0.255.11/32 40 - rt5 16110
+ 10.0.255.12/32 50 - rt5 16120
+
+Backup:
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ---------------------------------------------------------
+ 10.0.255.5/32 40 - rt3 50600/16050
+ 10.0.255.8/32 50 - rt3 50600/16080
+ 10.0.255.9/32 60 - rt3 50600/16090
+ 10.0.255.11/32 60 - rt3 50600/16110
+ 10.0.255.12/32 70 - rt3 50600/16120
+
+test# test isis topology 11 root rt2 remote-lfa system-id rt4
+P-space (self):
+
+P-space (rt1):
+ rt1
+ rt3
+ rt5
+
+P-space (rt3):
+ rt1
+ rt3
+ rt5
+ rt6
+
+Q-space:
+ rt1
+ rt3
+ rt4
+ rt5
+ rt6
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt2
+10.0.255.2/32 IP internal 0 rt2(4)
+rt1 TE-IS 50 rt1 - rt2(4)
+rt3 TE-IS 50 rt3 - rt2(4)
+rt2
+rt5 TE-IS 60 rt3 - rt3(4)
+10.0.255.1/32 IP TE 60 rt1 - rt1(4)
+10.0.255.3/32 IP TE 60 rt3 - rt3(4)
+rt4 TE-IS 70 rt3 - rt5(4)
+rt6 TE-IS 70 rt3 - rt5(4)
+10.0.255.5/32 IP TE 70 rt3 - rt5(4)
+10.0.255.4/32 IP TE 80 rt3 - rt4(4)
+10.0.255.6/32 IP TE 80 rt3 - rt6(4)
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt2
+10.0.255.2/32 IP internal 0 rt2(4)
+rt4 TE-IS 10 rt4 - rt2(4)
+rt5 TE-IS 20 rt4 - rt4(4)
+rt6 TE-IS 20 rt4 - rt4(4)
+10.0.255.4/32 IP TE 20 rt4 - rt4(4)
+rt3 TE-IS 30 rt4 - rt5(4)
+10.0.255.5/32 IP TE 30 rt4 - rt5(4)
+10.0.255.6/32 IP TE 30 rt4 - rt6(4)
+rt2
+rt1 TE-IS 40 rt4 - rt2(2)
+10.0.255.3/32 IP TE 40 rt4 - rt3(4)
+10.0.255.1/32 IP TE 50 rt4 - rt1(4)
+
+Main:
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 50 - rt4 16010
+ 10.0.255.2/32 0 - - -
+ 10.0.255.3/32 40 - rt4 16030
+ 10.0.255.4/32 20 - rt4 implicit-null
+ 10.0.255.5/32 30 - rt4 16050
+ 10.0.255.6/32 30 - rt4 16060
+
+Backup:
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 50 - rt1 implicit-null
+ - rt3 16010
+ 10.0.255.3/32 50 - rt1 16030
+ - rt3 implicit-null
+ 10.0.255.4/32 80 - rt3 50500/16040
+ 10.0.255.5/32 60 - rt1 16050
+ - rt3 16050
+ 10.0.255.6/32 70 - rt3 16060
+
+P-space (self):
+
+P-space (rt1):
+ rt1
+ rt3
+ rt5
+
+P-space (rt3):
+ rt1
+ rt3
+ rt5
+ rt6
+
+Q-space:
+ rt1
+ rt3
+ rt4
+ rt5
+ rt6
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt2
+2001:db8::2/128 IP6 internal 0 rt2(4)
+rt1 TE-IS 50 rt1 - rt2(4)
+rt3 TE-IS 50 rt3 - rt2(4)
+rt2
+rt5 TE-IS 60 rt3 - rt3(4)
+2001:db8::1/128 IP6 internal 60 rt1 - rt1(4)
+2001:db8::3/128 IP6 internal 60 rt3 - rt3(4)
+rt4 TE-IS 70 rt3 - rt5(4)
+rt6 TE-IS 70 rt3 - rt5(4)
+2001:db8::5/128 IP6 internal 70 rt3 - rt5(4)
+2001:db8::4/128 IP6 internal 80 rt3 - rt4(4)
+2001:db8::6/128 IP6 internal 80 rt3 - rt6(4)
+
+IS-IS paths to level-1 routers that speak IPv6
+Vertex Type Metric Next-Hop Interface Parent
+rt2
+2001:db8::2/128 IP6 internal 0 rt2(4)
+rt4 TE-IS 10 rt4 - rt2(4)
+rt5 TE-IS 20 rt4 - rt4(4)
+rt6 TE-IS 20 rt4 - rt4(4)
+2001:db8::4/128 IP6 internal 20 rt4 - rt4(4)
+rt3 TE-IS 30 rt4 - rt5(4)
+2001:db8::5/128 IP6 internal 30 rt4 - rt5(4)
+2001:db8::6/128 IP6 internal 30 rt4 - rt6(4)
+rt2
+rt1 TE-IS 40 rt4 - rt2(2)
+2001:db8::3/128 IP6 internal 40 rt4 - rt3(4)
+2001:db8::1/128 IP6 internal 50 rt4 - rt1(4)
+
+Main:
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ------------------------------------------------------------
+ 2001:db8::1/128 50 - rt4 16011
+ 2001:db8::2/128 0 - - -
+ 2001:db8::3/128 40 - rt4 16031
+ 2001:db8::4/128 20 - rt4 implicit-null
+ 2001:db8::5/128 30 - rt4 16051
+ 2001:db8::6/128 30 - rt4 16061
+
+Backup:
+IS-IS L1 IPv6 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ------------------------------------------------------------
+ 2001:db8::1/128 50 - rt1 implicit-null
+ - rt3 16011
+ 2001:db8::3/128 50 - rt1 16031
+ - rt3 implicit-null
+ 2001:db8::4/128 80 - rt3 50500/16041
+ 2001:db8::5/128 60 - rt1 16051
+ - rt3 16051
+ 2001:db8::6/128 70 - rt3 16061
+
+test# test isis topology 13 root rt1 remote-lfa system-id rt3 ipv4-only
+P-space (self):
+ rt2
+
+P-space (rt2):
+ rt2
+ rt4
+
+Q-space:
+ rt3
+ rt4
+ rt5
+ rt6
+ rt7
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+rt3 TE-IS 30 rt2 - rt4(4)
+10.0.255.4/32 IP TE 30 rt2 - rt4(4)
+rt5 TE-IS 40 rt2 - rt3(4)
+rt6 TE-IS 40 rt2 - rt3(4)
+10.0.255.3/32 IP TE 40 rt2 - rt3(4)
+rt7 TE-IS 50 rt2 - rt5(4)
+ rt6(4)
+10.0.255.5/32 IP TE 50 rt2 - rt5(4)
+10.0.255.6/32 IP TE 50 rt2 - rt6(4)
+10.0.255.7/32 IP TE 60 rt2 - rt7(4)
+
+IS-IS paths to level-1 routers that speak IP
+Vertex Type Metric Next-Hop Interface Parent
+rt1
+10.0.255.1/32 IP internal 0 rt1(4)
+rt2 TE-IS 10 rt2 - rt1(4)
+rt3 TE-IS 10 rt3 - rt1(4)
+rt4 TE-IS 20 rt2 - rt2(4)
+ rt3 - rt3(4)
+rt5 TE-IS 20 rt3 - rt3(4)
+rt6 TE-IS 20 rt3 - rt3(4)
+10.0.255.2/32 IP TE 20 rt2 - rt2(4)
+10.0.255.3/32 IP TE 20 rt3 - rt3(4)
+rt7 TE-IS 30 rt3 - rt5(4)
+ rt6(4)
+10.0.255.4/32 IP TE 30 rt2 - rt4(4)
+ rt3 -
+10.0.255.5/32 IP TE 30 rt3 - rt5(4)
+10.0.255.6/32 IP TE 30 rt3 - rt6(4)
+10.0.255.7/32 IP TE 40 rt3 - rt7(4)
+
+Main:
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ ----------------------------------------------------------
+ 10.0.255.1/32 0 - - -
+ 10.0.255.2/32 20 - rt2 implicit-null
+ 10.0.255.3/32 20 - rt3 implicit-null
+ 10.0.255.4/32 30 - rt2 16040
+ - rt3 16040
+ 10.0.255.5/32 30 - rt3 16050
+ 10.0.255.6/32 30 - rt3 16060
+ 10.0.255.7/32 40 - rt3 16070
+
+Backup:
+IS-IS L1 IPv4 routing table:
+
+ Prefix Metric Interface Nexthop Label(s)
+ --------------------------------------------------------
+ 10.0.255.3/32 40 - rt2 50400/16030
+ 10.0.255.5/32 50 - rt2 50400/16050
+ 10.0.255.6/32 50 - rt2 50400/16060
+ 10.0.255.7/32 60 - rt2 50400/16070
+
+test#
test# test isis topology 1 root rt1 ti-lfa system-id rt2
P-space (self):
rt3
diff --git a/tests/topotests/all-protocol-startup/test_all_protocol_startup.py b/tests/topotests/all-protocol-startup/test_all_protocol_startup.py index ab9358408e..24bef07ec2 100644 --- a/tests/topotests/all-protocol-startup/test_all_protocol_startup.py +++ b/tests/topotests/all-protocol-startup/test_all_protocol_startup.py @@ -82,7 +82,9 @@ class NetworkTopo(Topo): ## ##################################################### - +@pytest.mark.isis +@pytest.mark.ospf +@pytest.mark.rip def setup_module(module): global topo, net global fatal_error diff --git a/tests/topotests/bfd-bgp-cbit-topo3/test_bfd_bgp_cbit_topo3.py b/tests/topotests/bfd-bgp-cbit-topo3/test_bfd_bgp_cbit_topo3.py index 98a5033f53..cc1c1e3a0c 100644 --- a/tests/topotests/bfd-bgp-cbit-topo3/test_bfd_bgp_cbit_topo3.py +++ b/tests/topotests/bfd-bgp-cbit-topo3/test_bfd_bgp_cbit_topo3.py @@ -64,7 +64,7 @@ class BFDTopo(Topo): switch.add_link(tgen.gears["r2"]) switch.add_link(tgen.gears["r3"]) - +@pytest.mark.bfd def setup_module(mod): "Sets up the pytest environment" tgen = Topogen(BFDTopo, mod.__name__) diff --git a/tests/topotests/bfd-isis-topo1/test_bfd_isis_topo1.py b/tests/topotests/bfd-isis-topo1/test_bfd_isis_topo1.py index 1adfec76d8..23da7ed850 100644 --- a/tests/topotests/bfd-isis-topo1/test_bfd_isis_topo1.py +++ b/tests/topotests/bfd-isis-topo1/test_bfd_isis_topo1.py @@ -127,7 +127,8 @@ class TemplateTopo(Topo): switch.add_link(tgen.gears["rt4"], nodeif="eth-rt5") switch.add_link(tgen.gears["rt5"], nodeif="eth-rt4") - +@pytest.mark.bfd +@pytest.mark.isis def setup_module(mod): "Sets up the pytest environment" tgen = Topogen(TemplateTopo, mod.__name__) diff --git a/tests/topotests/bfd-ospf-topo1/__init__.py b/tests/topotests/bfd-ospf-topo1/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/__init__.py diff --git a/tests/topotests/bfd-ospf-topo1/rt1/bfdd.conf b/tests/topotests/bfd-ospf-topo1/rt1/bfdd.conf new file mode 100644 index 0000000000..610a20f88a --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt1/bfdd.conf @@ -0,0 +1,9 @@ +log file bfdd.log +log timestamp precision 3 +! +debug bfd network +debug bfd peer +debug bfd zebra +! +bfd +! diff --git a/tests/topotests/bfd-ospf-topo1/rt1/ospf6d.conf b/tests/topotests/bfd-ospf-topo1/rt1/ospf6d.conf new file mode 100644 index 0000000000..18def599b4 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt1/ospf6d.conf @@ -0,0 +1,21 @@ +log file ospf6d.log +log timestamp precision 3 +! +hostname rt1 +! +password 1 +! +interface eth-rt2 + ipv6 ospf6 network broadcast + ipv6 ospf6 bfd +! +interface eth-rt3 + ipv6 ospf6 network broadcast + ipv6 ospf6 bfd +! +router ospf6 + ospf6 router-id 1.1.1.1 + interface eth-rt2 area 0.0.0.0 + interface eth-rt3 area 0.0.0.0 + redistribute connected +! diff --git a/tests/topotests/bfd-ospf-topo1/rt1/ospfd.conf b/tests/topotests/bfd-ospf-topo1/rt1/ospfd.conf new file mode 100644 index 0000000000..07b42f9885 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt1/ospfd.conf @@ -0,0 +1,26 @@ +log file ospfd.log +log timestamp precision 3 +! +hostname rt1 +! +password 1 +! +debug ospf event +debug ospf zebra +! +interface lo + ip ospf area 0.0.0.0 +! +interface eth-rt2 + ip ospf area 0.0.0.0 + ip ospf bfd +! +interface eth-rt3 + ip ospf area 0.0.0.0 + ip ospf bfd +! +router ospf + ospf router-id 1.1.1.1 + passive interface lo + router-info area 0.0.0.0 +! diff --git a/tests/topotests/bfd-ospf-topo1/rt1/step1/show_ip_route.ref b/tests/topotests/bfd-ospf-topo1/rt1/step1/show_ip_route.ref new file mode 100644 index 0000000000..f354eff697 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt1/step1/show_ip_route.ref @@ -0,0 +1,74 @@ +{ + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"ospf", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"ospf", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"ospf", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"ospf", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/bfd-ospf-topo1/rt1/step1/show_ipv6_route.ref b/tests/topotests/bfd-ospf-topo1/rt1/step1/show_ipv6_route.ref new file mode 100644 index 0000000000..6465efb8b5 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt1/step1/show_ipv6_route.ref @@ -0,0 +1,70 @@ +{ + "::ffff:202:202\/128":[ + { + "prefix":"::ffff:202:202\/128", + "protocol":"ospf6", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", + "active":true + } + ] + } + ], + "::ffff:303:303\/128":[ + { + "prefix":"::ffff:303:303\/128", + "protocol":"ospf6", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", + "active":true + } + ] + } + ], + "::ffff:404:404\/128":[ + { + "prefix":"::ffff:404:404\/128", + "protocol":"ospf6", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", + "active":true + } + ] + } + ], + "::ffff:505:505\/128":[ + { + "prefix":"::ffff:505:505\/128", + "protocol":"ospf6", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/bfd-ospf-topo1/rt1/step2/show_bfd_peers.ref b/tests/topotests/bfd-ospf-topo1/rt1/step2/show_bfd_peers.ref new file mode 100644 index 0000000000..63f0d50784 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt1/step2/show_bfd_peers.ref @@ -0,0 +1,26 @@ +[ + { + "interface": "eth-rt3", + "status": "up", + "diagnostic": "ok", + "remote-diagnostic": "ok" + }, + { + "interface": "eth-rt2", + "status": "up", + "diagnostic": "ok", + "remote-diagnostic": "ok" + }, + { + "interface": "eth-rt3", + "status": "up", + "diagnostic": "ok", + "remote-diagnostic": "ok" + }, + { + "interface": "eth-rt2", + "status": "up", + "diagnostic": "ok", + "remote-diagnostic": "ok" + } +] diff --git a/tests/topotests/bfd-ospf-topo1/rt1/step3/show_bfd_peers_healthy.ref b/tests/topotests/bfd-ospf-topo1/rt1/step3/show_bfd_peers_healthy.ref new file mode 100644 index 0000000000..42051f9582 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt1/step3/show_bfd_peers_healthy.ref @@ -0,0 +1,28 @@ +[ + { + "peer": "10.0.2.2", + "interface": "eth-rt3", + "status": "up", + "diagnostic": "ok", + "remote-diagnostic": "ok" + }, + { + "peer": "10.0.1.2", + "interface": "eth-rt2", + "status": "up", + "diagnostic": "ok", + "remote-diagnostic": "ok" + }, + { + "interface": "eth-rt3", + "status": "up", + "diagnostic": "ok", + "remote-diagnostic": "ok" + }, + { + "interface": "eth-rt2", + "status": "up", + "diagnostic": "ok", + "remote-diagnostic": "ok" + } +] diff --git a/tests/topotests/bfd-ospf-topo1/rt1/step3/show_bfd_peers_rt2_down.ref b/tests/topotests/bfd-ospf-topo1/rt1/step3/show_bfd_peers_rt2_down.ref new file mode 100644 index 0000000000..d844ee6813 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt1/step3/show_bfd_peers_rt2_down.ref @@ -0,0 +1,15 @@ +[ + { + "peer": "10.0.2.2", + "interface": "eth-rt3", + "status": "up", + "diagnostic": "ok", + "remote-diagnostic": "ok" + }, + { + "interface": "eth-rt3", + "status": "up", + "diagnostic": "ok", + "remote-diagnostic": "ok" + } +] diff --git a/tests/topotests/bfd-ospf-topo1/rt1/step3/show_bfd_peers_rt3_down.ref b/tests/topotests/bfd-ospf-topo1/rt1/step3/show_bfd_peers_rt3_down.ref new file mode 100644 index 0000000000..32799084fb --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt1/step3/show_bfd_peers_rt3_down.ref @@ -0,0 +1,15 @@ +[ + { + "peer": "10.0.1.2", + "interface": "eth-rt2", + "status": "up", + "diagnostic": "ok", + "remote-diagnostic": "ok" + }, + { + "interface": "eth-rt2", + "status": "up", + "diagnostic": "ok", + "remote-diagnostic": "ok" + } +] diff --git a/tests/topotests/bfd-ospf-topo1/rt1/step3/show_ip_route_healthy.ref b/tests/topotests/bfd-ospf-topo1/rt1/step3/show_ip_route_healthy.ref new file mode 100644 index 0000000000..f354eff697 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt1/step3/show_ip_route_healthy.ref @@ -0,0 +1,74 @@ +{ + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"ospf", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"ospf", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"ospf", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"ospf", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/bfd-ospf-topo1/rt1/step3/show_ip_route_rt2_down.ref b/tests/topotests/bfd-ospf-topo1/rt1/step3/show_ip_route_rt2_down.ref new file mode 100644 index 0000000000..43eecd0b7a --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt1/step3/show_ip_route_rt2_down.ref @@ -0,0 +1,74 @@ +{ + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"ospf", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"ospf", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"ospf", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"ospf", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/bfd-ospf-topo1/rt1/step3/show_ip_route_rt3_down.ref b/tests/topotests/bfd-ospf-topo1/rt1/step3/show_ip_route_rt3_down.ref new file mode 100644 index 0000000000..409af6308b --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt1/step3/show_ip_route_rt3_down.ref @@ -0,0 +1,74 @@ +{ + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"ospf", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"ospf", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"ospf", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"ospf", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/bfd-ospf-topo1/rt1/step3/show_ipv6_route_healthy.ref b/tests/topotests/bfd-ospf-topo1/rt1/step3/show_ipv6_route_healthy.ref new file mode 100644 index 0000000000..6465efb8b5 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt1/step3/show_ipv6_route_healthy.ref @@ -0,0 +1,70 @@ +{ + "::ffff:202:202\/128":[ + { + "prefix":"::ffff:202:202\/128", + "protocol":"ospf6", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", + "active":true + } + ] + } + ], + "::ffff:303:303\/128":[ + { + "prefix":"::ffff:303:303\/128", + "protocol":"ospf6", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", + "active":true + } + ] + } + ], + "::ffff:404:404\/128":[ + { + "prefix":"::ffff:404:404\/128", + "protocol":"ospf6", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", + "active":true + } + ] + } + ], + "::ffff:505:505\/128":[ + { + "prefix":"::ffff:505:505\/128", + "protocol":"ospf6", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/bfd-ospf-topo1/rt1/step3/show_ipv6_route_rt2_down.ref b/tests/topotests/bfd-ospf-topo1/rt1/step3/show_ipv6_route_rt2_down.ref new file mode 100644 index 0000000000..cfb1ef1bb6 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt1/step3/show_ipv6_route_rt2_down.ref @@ -0,0 +1,70 @@ +{ + "::ffff:202:202\/128":[ + { + "prefix":"::ffff:202:202\/128", + "protocol":"ospf6", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", + "active":true + } + ] + } + ], + "::ffff:303:303\/128":[ + { + "prefix":"::ffff:303:303\/128", + "protocol":"ospf6", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", + "active":true + } + ] + } + ], + "::ffff:404:404\/128":[ + { + "prefix":"::ffff:404:404\/128", + "protocol":"ospf6", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", + "active":true + } + ] + } + ], + "::ffff:505:505\/128":[ + { + "prefix":"::ffff:505:505\/128", + "protocol":"ospf6", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/bfd-ospf-topo1/rt1/step3/show_ipv6_route_rt3_down.ref b/tests/topotests/bfd-ospf-topo1/rt1/step3/show_ipv6_route_rt3_down.ref new file mode 100644 index 0000000000..58b44da5c2 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt1/step3/show_ipv6_route_rt3_down.ref @@ -0,0 +1,70 @@ +{ + "::ffff:202:202\/128":[ + { + "prefix":"::ffff:202:202\/128", + "protocol":"ospf6", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", + "active":true + } + ] + } + ], + "::ffff:303:303\/128":[ + { + "prefix":"::ffff:303:303\/128", + "protocol":"ospf6", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", + "active":true + } + ] + } + ], + "::ffff:404:404\/128":[ + { + "prefix":"::ffff:404:404\/128", + "protocol":"ospf6", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", + "active":true + } + ] + } + ], + "::ffff:505:505\/128":[ + { + "prefix":"::ffff:505:505\/128", + "protocol":"ospf6", + "selected":true, + "destSelected":true, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/bfd-ospf-topo1/rt1/zebra.conf b/tests/topotests/bfd-ospf-topo1/rt1/zebra.conf new file mode 100644 index 0000000000..6003125b6b --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt1/zebra.conf @@ -0,0 +1,25 @@ +log file zebra.log +log timestamp precision 3 +! +hostname rt1 +! +debug zebra kernel +debug zebra packet +debug zebra events +debug zebra rib +! +interface lo + ip address 1.1.1.1/32 + ipv6 address ::ffff:0101:0101/128 +! +interface eth-rt2 + ip address 10.0.1.1/24 +! +interface eth-rt3 + ip address 10.0.2.1/24 +! +ip forwarding +ipv6 forwarding +! +line vty +! diff --git a/tests/topotests/bfd-ospf-topo1/rt2/bfdd.conf b/tests/topotests/bfd-ospf-topo1/rt2/bfdd.conf new file mode 100644 index 0000000000..437f063d8f --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt2/bfdd.conf @@ -0,0 +1,7 @@ +! +debug bfd network +debug bfd peer +debug bfd zebra +! +bfd +! diff --git a/tests/topotests/bfd-ospf-topo1/rt2/ospf6d.conf b/tests/topotests/bfd-ospf-topo1/rt2/ospf6d.conf new file mode 100644 index 0000000000..2f35099564 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt2/ospf6d.conf @@ -0,0 +1,19 @@ +log file ospf6d.log +! +hostname rt2 +! +password 1 +! +interface eth-rt1 + ipv6 ospf6 network broadcast + ipv6 ospf6 bfd +! +interface eth-rt5 + ipv6 ospf6 network broadcast +! +router ospf6 + ospf6 router-id 2.2.2.2 + interface eth-rt1 area 0.0.0.0 + interface eth-rt5 area 0.0.0.0 + redistribute connected +! diff --git a/tests/topotests/bfd-ospf-topo1/rt2/ospfd.conf b/tests/topotests/bfd-ospf-topo1/rt2/ospfd.conf new file mode 100644 index 0000000000..a05d8b58c8 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt2/ospfd.conf @@ -0,0 +1,24 @@ +log file ospfd.log +! +hostname rt2 +! +password 1 +! +debug ospf event +debug ospf zebra +! +interface lo + ip ospf area 0.0.0.0 +! +interface eth-rt1 + ip ospf area 0.0.0.0 + ip ospf bfd +! +interface eth-rt5 + ip ospf area 0.0.0.0 +! +router ospf + ospf router-id 2.2.2.2 + passive interface lo + router-info area 0.0.0.0 +! diff --git a/tests/topotests/bfd-ospf-topo1/rt2/step2/show_bfd_peers.ref b/tests/topotests/bfd-ospf-topo1/rt2/step2/show_bfd_peers.ref new file mode 100644 index 0000000000..d6df1ebfb2 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt2/step2/show_bfd_peers.ref @@ -0,0 +1,14 @@ +[ + { + "interface": "eth-rt1", + "status": "up", + "diagnostic": "ok", + "remote-diagnostic": "ok" + }, + { + "interface": "eth-rt1", + "status": "up", + "diagnostic": "ok", + "remote-diagnostic": "ok" + } +] diff --git a/tests/topotests/bfd-ospf-topo1/rt2/zebra.conf b/tests/topotests/bfd-ospf-topo1/rt2/zebra.conf new file mode 100644 index 0000000000..5fc7fc5b28 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt2/zebra.conf @@ -0,0 +1,22 @@ +log file zebra.log +! +hostname rt2 +! +debug zebra kernel +debug zebra packet +! +interface lo + ip address 2.2.2.2/32 + ipv6 address ::ffff:0202:0202/128 +! +interface eth-rt1 + ip address 10.0.1.2/24 +! +interface eth-rt5 + ip address 10.0.3.1/24 +! +ip forwarding +ipv6 forwarding +! +line vty +! diff --git a/tests/topotests/bfd-ospf-topo1/rt3/bfdd.conf b/tests/topotests/bfd-ospf-topo1/rt3/bfdd.conf new file mode 100644 index 0000000000..437f063d8f --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt3/bfdd.conf @@ -0,0 +1,7 @@ +! +debug bfd network +debug bfd peer +debug bfd zebra +! +bfd +! diff --git a/tests/topotests/bfd-ospf-topo1/rt3/ospf6d.conf b/tests/topotests/bfd-ospf-topo1/rt3/ospf6d.conf new file mode 100644 index 0000000000..3e8777019e --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt3/ospf6d.conf @@ -0,0 +1,19 @@ +log file ospf6d.log +! +hostname rt3 +! +password 1 +! +interface eth-rt1 + ipv6 ospf6 network broadcast + ipv6 ospf6 bfd +! +interface eth-rt4 + ipv6 ospf6 network broadcast +! +router ospf6 + ospf6 router-id 3.3.3.3 + interface eth-rt1 area 0.0.0.0 + interface eth-rt4 area 0.0.0.0 + redistribute connected +! diff --git a/tests/topotests/bfd-ospf-topo1/rt3/ospfd.conf b/tests/topotests/bfd-ospf-topo1/rt3/ospfd.conf new file mode 100644 index 0000000000..1196e6d189 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt3/ospfd.conf @@ -0,0 +1,24 @@ +log file ospfd.log +! +hostname rt3 +! +password 1 +! +debug ospf event +debug ospf zebra +! +interface lo + ip ospf area 0.0.0.0 +! +interface eth-rt1 + ip ospf area 0.0.0.0 + ip ospf bfd +! +interface eth-rt4 + ip ospf area 0.0.0.0 +! +router ospf + ospf router-id 3.3.3.3 + passive interface lo + router-info area 0.0.0.0 +! diff --git a/tests/topotests/bfd-ospf-topo1/rt3/step2/show_bfd_peers.ref b/tests/topotests/bfd-ospf-topo1/rt3/step2/show_bfd_peers.ref new file mode 100644 index 0000000000..d6df1ebfb2 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt3/step2/show_bfd_peers.ref @@ -0,0 +1,14 @@ +[ + { + "interface": "eth-rt1", + "status": "up", + "diagnostic": "ok", + "remote-diagnostic": "ok" + }, + { + "interface": "eth-rt1", + "status": "up", + "diagnostic": "ok", + "remote-diagnostic": "ok" + } +] diff --git a/tests/topotests/bfd-ospf-topo1/rt3/zebra.conf b/tests/topotests/bfd-ospf-topo1/rt3/zebra.conf new file mode 100644 index 0000000000..d368de9bbe --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt3/zebra.conf @@ -0,0 +1,22 @@ +log file zebra.log +! +hostname rt3 +! +debug zebra kernel +debug zebra packet +! +interface lo + ip address 3.3.3.3/32 + ipv6 address ::ffff:0303:0303/128 +! +interface eth-rt1 + ip address 10.0.2.2/24 +! +interface eth-rt4 + ip address 10.0.4.1/24 +! +ip forwarding +ipv6 forwarding +! +line vty +! diff --git a/tests/topotests/bfd-ospf-topo1/rt4/bfdd.conf b/tests/topotests/bfd-ospf-topo1/rt4/bfdd.conf new file mode 100644 index 0000000000..f35e772790 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt4/bfdd.conf @@ -0,0 +1,5 @@ +! +debug bfd network +debug bfd peer +debug bfd zebra +! diff --git a/tests/topotests/bfd-ospf-topo1/rt4/ospf6d.conf b/tests/topotests/bfd-ospf-topo1/rt4/ospf6d.conf new file mode 100644 index 0000000000..bccd1e75bd --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt4/ospf6d.conf @@ -0,0 +1,18 @@ +log file ospf6d.log +! +hostname rt4 +! +password 1 +! +interface eth-rt3 + ipv6 ospf6 network broadcast +! +interface eth-rt5 + ipv6 ospf6 network broadcast +! +router ospf6 + ospf6 router-id 4.4.4.4 + interface eth-rt3 area 0.0.0.0 + interface eth-rt5 area 0.0.0.0 + redistribute connected +! diff --git a/tests/topotests/bfd-ospf-topo1/rt4/ospfd.conf b/tests/topotests/bfd-ospf-topo1/rt4/ospfd.conf new file mode 100644 index 0000000000..3a2568b4ab --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt4/ospfd.conf @@ -0,0 +1,23 @@ +log file ospfd.log +! +hostname rt4 +! +password 1 +! +debug ospf event +debug ospf zebra +! +interface lo + ip ospf area 0.0.0.0 +! +interface eth-rt3 + ip ospf area 0.0.0.0 +! +interface eth-rt5 + ip ospf area 0.0.0.0 +! +router ospf + ospf router-id 4.4.4.4 + passive interface lo + router-info area 0.0.0.0 +! diff --git a/tests/topotests/bfd-ospf-topo1/rt4/zebra.conf b/tests/topotests/bfd-ospf-topo1/rt4/zebra.conf new file mode 100644 index 0000000000..7b053bac35 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt4/zebra.conf @@ -0,0 +1,22 @@ +log file zebra.log +! +hostname rt4 +! +debug zebra kernel +debug zebra packet +! +interface lo + ip address 4.4.4.4/32 + ipv6 address ::ffff:0404:0404/128 +! +interface eth-rt3 + ip address 10.0.4.2/24 +! +interface eth-rt5 + ip address 10.0.5.1/24 +! +ip forwarding +ipv6 forwarding +! +line vty +! diff --git a/tests/topotests/bfd-ospf-topo1/rt5/bfdd.conf b/tests/topotests/bfd-ospf-topo1/rt5/bfdd.conf new file mode 100644 index 0000000000..f35e772790 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt5/bfdd.conf @@ -0,0 +1,5 @@ +! +debug bfd network +debug bfd peer +debug bfd zebra +! diff --git a/tests/topotests/bfd-ospf-topo1/rt5/ospf6d.conf b/tests/topotests/bfd-ospf-topo1/rt5/ospf6d.conf new file mode 100644 index 0000000000..766862276c --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt5/ospf6d.conf @@ -0,0 +1,18 @@ +log file ospf6d.log +! +hostname rt5 +! +password 1 +! +interface eth-rt2 + ipv6 ospf6 network broadcast +! +interface eth-rt4 + ipv6 ospf6 network broadcast +! +router ospf6 + ospf6 router-id 5.5.5.5 + interface eth-rt2 area 0.0.0.0 + interface eth-rt4 area 0.0.0.0 + redistribute connected +! diff --git a/tests/topotests/bfd-ospf-topo1/rt5/ospfd.conf b/tests/topotests/bfd-ospf-topo1/rt5/ospfd.conf new file mode 100644 index 0000000000..a35de5f45f --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt5/ospfd.conf @@ -0,0 +1,23 @@ +log file ospfd.log +! +hostname rt5 +! +password 1 +! +debug ospf event +debug ospf zebra +! +interface lo + ip ospf area 0.0.0.0 +! +interface eth-rt2 + ip ospf area 0.0.0.0 +! +interface eth-rt4 + ip ospf area 0.0.0.0 +! +router ospf + ospf router-id 5.5.5.5 + passive interface lo + router-info area 0.0.0.0 +! diff --git a/tests/topotests/bfd-ospf-topo1/rt5/zebra.conf b/tests/topotests/bfd-ospf-topo1/rt5/zebra.conf new file mode 100644 index 0000000000..0b7c9e02f3 --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/rt5/zebra.conf @@ -0,0 +1,22 @@ +log file zebra.log +! +hostname rt5 +! +debug zebra kernel +debug zebra packet +! +interface lo + ip address 5.5.5.5/32 + ipv6 address ::ffff:0505:0505/128 +! +interface eth-rt2 + ip address 10.0.3.2/24 +! +interface eth-rt4 + ip address 10.0.5.2/24 +! +ip forwarding +ipv6 forwarding +! +line vty +! diff --git a/tests/topotests/bfd-ospf-topo1/test_bfd_ospf_topo1.py b/tests/topotests/bfd-ospf-topo1/test_bfd_ospf_topo1.py new file mode 100755 index 0000000000..1cec62789b --- /dev/null +++ b/tests/topotests/bfd-ospf-topo1/test_bfd_ospf_topo1.py @@ -0,0 +1,307 @@ +#!/usr/bin/env python + +# +# test_bfd_ospf_topo1.py +# Part of NetDEF Topology Tests +# +# Copyright (c) 2020 by +# Network Device Education Foundation, Inc. ("NetDEF") +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +test_bfd_ospf_topo1.py: + + +---------+ + | | + eth-rt2 (.1) | RT1 | eth-rt3 (.1) + +----------+ 1.1.1.1 +----------+ + | | | | + | +---------+ | + | | + | 10.0.2.0/24 | + | | + | eth-rt1 | (.2) + | 10.0.1.0/24 +----+----+ + | | | + | | RT3 | + | | 3.3.3.3 | + | | | + (.2) | eth-rt1 +----+----+ + +----+----+ eth-rt4 | (.1) + | | | + | RT2 | | + | 2.2.2.2 | 10.0.4.0/24 | + | | | + +----+----+ | + (.1) | eth-rt5 eth-rt3 | (.2) + | +----+----+ + | | | + | | RT4 | + | | 4.4.4.4 | + | | | + | +----+----+ + | 10.0.3.0/24 eth-rt5 | (.1) + | | + | | + | 10.0.5.0/24 | + | | + | +---------+ | + | | | | + +----------+ RT5 +----------+ + eth-rt2 (.2) | 5.5.5.5 | eth-rt4 (.2) + | | + +---------+ + +""" + +import os +import sys +import pytest +import json +import re +from time import sleep +from time import time +from functools import partial + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger + +# Required to instantiate the topology builder class. +from mininet.topo import Topo + + +class TemplateTopo(Topo): + "Test topology builder" + + def build(self, *_args, **_opts): + "Build function" + tgen = get_topogen(self) + + # + # Define FRR Routers + # + for router in ["rt1", "rt2", "rt3", "rt4", "rt5"]: + tgen.add_router(router) + + # + # Define connections + # + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["rt1"], nodeif="eth-rt2") + switch.add_link(tgen.gears["rt2"], nodeif="eth-rt1") + + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["rt1"], nodeif="eth-rt3") + switch.add_link(tgen.gears["rt3"], nodeif="eth-rt1") + + switch = tgen.add_switch("s3") + switch.add_link(tgen.gears["rt2"], nodeif="eth-rt5") + switch.add_link(tgen.gears["rt5"], nodeif="eth-rt2") + + switch = tgen.add_switch("s4") + switch.add_link(tgen.gears["rt3"], nodeif="eth-rt4") + switch.add_link(tgen.gears["rt4"], nodeif="eth-rt3") + + switch = tgen.add_switch("s5") + switch.add_link(tgen.gears["rt4"], nodeif="eth-rt5") + switch.add_link(tgen.gears["rt5"], nodeif="eth-rt4") + + +def setup_module(mod): + "Sets up the pytest environment" + tgen = Topogen(TemplateTopo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + # For all registered routers, load the zebra configuration file + for rname, router in router_list.iteritems(): + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_BFD, os.path.join(CWD, "{}/bfdd.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_OSPF, os.path.join(CWD, "{}/ospfd.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_OSPF6, os.path.join(CWD, "{}/ospf6d.conf".format(rname)) + ) + + tgen.start_router() + + +def teardown_module(mod): + "Teardown the pytest environment" + tgen = get_topogen() + + # This function tears down the whole topology. + tgen.stop_topology() + + +def print_cmd_result(rname, command): + print(get_topogen().gears[rname].vtysh_cmd(command, isjson=False)) + + +def router_compare_json_output(rname, command, reference, count=120, wait=0.5): + "Compare router JSON output" + + logger.info('Comparing router "%s" "%s" output', rname, command) + + tgen = get_topogen() + filename = "{}/{}/{}".format(CWD, rname, reference) + expected = json.loads(open(filename).read()) + + # Run test function until we get an result. Wait at most 60 seconds. + test_func = partial(topotest.router_json_cmp, tgen.gears[rname], command, expected) + _, diff = topotest.run_and_expect(test_func, None, count=count, wait=wait) + assertmsg = '"{}" JSON output mismatches the expected result'.format(rname) + assert diff is None, assertmsg + + +## TEST STEPS + + +def test_rib_ospf_step1(): + logger.info("Test (step 1): verify RIB for OSPF") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + router_compare_json_output( + "rt1", "show ip route ospf json", "step1/show_ip_route.ref" + ) + router_compare_json_output( + "rt1", "show ipv6 route ospf json", "step1/show_ipv6_route.ref" + ) + + +def test_bfd_ospf_sessions_step2(): + logger.info("Test (step 2): verify BFD peers for OSPF") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + # BFD is just used on three routers + for rt in ["rt1", "rt2", "rt3"]: + router_compare_json_output( + rt, "show bfd peers json", "step2/show_bfd_peers.ref" + ) + + +def test_bfd_ospf_interface_failure_rt2_step3(): + logger.info("Test (step 3): Check failover handling with RT2 down") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + # Let's kill the interface on rt2 and see what happens with the RIB and BFD on rt1 + tgen.gears["rt2"].link_enable("eth-rt1", enabled=False) + + # By default BFD provides a recovery time of 900ms plus jitter, so let's wait + # initial 2 seconds to let the CI not suffer. + # TODO: add check for array size + sleep(2) + router_compare_json_output( + "rt1", "show ip route ospf json", "step3/show_ip_route_rt2_down.ref", 1, 0 + ) + router_compare_json_output( + "rt1", "show ipv6 route ospf json", "step3/show_ipv6_route_rt2_down.ref", 1, 0 + ) + router_compare_json_output( + "rt1", "show bfd peers json", "step3/show_bfd_peers_rt2_down.ref", 1, 0 + ) + + # Check recovery, this can take some time + tgen.gears["rt2"].link_enable("eth-rt1", enabled=True) + + router_compare_json_output( + "rt1", "show ip route ospf json", "step3/show_ip_route_healthy.ref" + ) + router_compare_json_output( + "rt1", "show ipv6 route ospf json", "step3/show_ipv6_route_healthy.ref" + ) + router_compare_json_output( + "rt1", "show bfd peers json", "step3/show_bfd_peers_healthy.ref" + ) + + +def test_bfd_ospf_interface_failure_rt3_step3(): + logger.info("Test (step 3): Check failover handling with RT3 down") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + # Let's kill the interface on rt3 and see what happens with the RIB and BFD on rt1 + tgen.gears["rt3"].link_enable("eth-rt1", enabled=False) + + # By default BFD provides a recovery time of 900ms plus jitter, so let's wait + # initial 2 seconds to let the CI not suffer. + # TODO: add check for array size + sleep(2) + router_compare_json_output( + "rt1", "show ip route ospf json", "step3/show_ip_route_rt3_down.ref", 1, 0 + ) + router_compare_json_output( + "rt1", "show ipv6 route ospf json", "step3/show_ipv6_route_rt3_down.ref", 1, 0 + ) + router_compare_json_output( + "rt1", "show bfd peers json", "step3/show_bfd_peers_rt3_down.ref", 1, 0 + ) + + # Check recovery, this can take some time + tgen.gears["rt3"].link_enable("eth-rt1", enabled=True) + + router_compare_json_output( + "rt1", "show ip route ospf json", "step3/show_ip_route_healthy.ref" + ) + router_compare_json_output( + "rt1", "show ipv6 route ospf json", "step3/show_ipv6_route_healthy.ref" + ) + router_compare_json_output( + "rt1", "show bfd peers json", "step3/show_bfd_peers_healthy.ref" + ) + + +def test_memory_leak(): + "Run the memory leak test and report results." + tgen = get_topogen() + if not tgen.is_memleak_enabled(): + pytest.skip("Memory leak test/report is disabled") + + tgen.report_memory_leaks() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bfd-profiles-topo1/test_bfd_profiles_topo1.py b/tests/topotests/bfd-profiles-topo1/test_bfd_profiles_topo1.py index bd3b876eeb..6283f03ddf 100644 --- a/tests/topotests/bfd-profiles-topo1/test_bfd_profiles_topo1.py +++ b/tests/topotests/bfd-profiles-topo1/test_bfd_profiles_topo1.py @@ -77,7 +77,8 @@ class BFDProfTopo(Topo): switch.add_link(tgen.gears["r1"]) switch.add_link(tgen.gears["r6"]) - +@pytest.mark.bfd +@pytest.mark.isis def setup_module(mod): "Sets up the pytest environment" tgen = Topogen(BFDProfTopo, mod.__name__) diff --git a/tests/topotests/bfd-topo1/test_bfd_topo1.py b/tests/topotests/bfd-topo1/test_bfd_topo1.py index 6e589d55eb..4c13fdcfc5 100644 --- a/tests/topotests/bfd-topo1/test_bfd_topo1.py +++ b/tests/topotests/bfd-topo1/test_bfd_topo1.py @@ -69,7 +69,7 @@ class BFDTopo(Topo): switch.add_link(tgen.gears["r2"]) switch.add_link(tgen.gears["r4"]) - +@pytest.mark.bfd def setup_module(mod): "Sets up the pytest environment" tgen = Topogen(BFDTopo, mod.__name__) diff --git a/tests/topotests/bfd-topo2/test_bfd_topo2.py b/tests/topotests/bfd-topo2/test_bfd_topo2.py index feb4576bd3..5181a40f47 100644 --- a/tests/topotests/bfd-topo2/test_bfd_topo2.py +++ b/tests/topotests/bfd-topo2/test_bfd_topo2.py @@ -70,7 +70,7 @@ class BFDTopo(Topo): switch.add_link(tgen.gears["r2"]) switch.add_link(tgen.gears["r4"]) - +@pytest.mark.bfd def setup_module(mod): "Sets up the pytest environment" tgen = Topogen(BFDTopo, mod.__name__) diff --git a/tests/topotests/bfd-vrf-topo1/test_bfd_vrf_topo1.py b/tests/topotests/bfd-vrf-topo1/test_bfd_vrf_topo1.py index 5fed135f8d..956b526583 100644 --- a/tests/topotests/bfd-vrf-topo1/test_bfd_vrf_topo1.py +++ b/tests/topotests/bfd-vrf-topo1/test_bfd_vrf_topo1.py @@ -70,7 +70,7 @@ class BFDTopo(Topo): switch.add_link(tgen.gears["r2"]) switch.add_link(tgen.gears["r4"]) - +@pytest.mark.bfd def setup_module(mod): "Sets up the pytest environment" tgen = Topogen(BFDTopo, mod.__name__) diff --git a/tests/topotests/bgp-evpn-mh/test_evpn_mh.py b/tests/topotests/bgp-evpn-mh/test_evpn_mh.py index 6a24684649..4e37ab00a3 100644 --- a/tests/topotests/bgp-evpn-mh/test_evpn_mh.py +++ b/tests/topotests/bgp-evpn-mh/test_evpn_mh.py @@ -362,7 +362,7 @@ def config_hosts(tgen, hosts): host = tgen.gears[host_name] config_host(host_name, host) - +@pytest.mark.pim def setup_module(module): "Setup topology" tgen = Topogen(NetworkTopo, module.__name__) diff --git a/tests/topotests/bgp_features/exabgp.env b/tests/topotests/bgp_features/exabgp.env new file mode 100644 index 0000000000..6c554f5fa8 --- /dev/null +++ b/tests/topotests/bgp_features/exabgp.env @@ -0,0 +1,53 @@ + +[exabgp.api] +encoder = text +highres = false +respawn = false +socket = '' + +[exabgp.bgp] +openwait = 60 + +[exabgp.cache] +attributes = true +nexthops = true + +[exabgp.daemon] +daemonize = true +pid = '/var/run/exabgp/exabgp.pid' +user = 'exabgp' + +[exabgp.log] +all = false +configuration = true +daemon = true +destination = '/var/log/exabgp.log' +enable = true +level = INFO +message = false +network = true +packets = false +parser = false +processes = true +reactor = true +rib = false +routes = false +short = false +timers = false + +[exabgp.pdb] +enable = false + +[exabgp.profile] +enable = false +file = '' + +[exabgp.reactor] +speed = 1.0 + +[exabgp.tcp] +acl = false +bind = '' +delay = 0 +once = false +port = 179 diff --git a/tests/topotests/bgp_features/peer1/exa_readpipe.py b/tests/topotests/bgp_features/peer1/exa_readpipe.py new file mode 100644 index 0000000000..dba1536388 --- /dev/null +++ b/tests/topotests/bgp_features/peer1/exa_readpipe.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python +"Helper script to read api commands from a pipe and feed them to ExaBGP" + +import sys + +if len(sys.argv) != 2: + sys.exit(1) +fifo = sys.argv[1] + +while True: + pipe = open(fifo, 'r') + with pipe: + line = pipe.readline().strip() + if line != "": + sys.stdout.write("{}\n".format(line)) + sys.stdout.flush() + pipe.close() + +sys.exit(0) diff --git a/tests/topotests/bgp_features/peer1/exabgp.cfg b/tests/topotests/bgp_features/peer1/exabgp.cfg new file mode 100644 index 0000000000..2e95252cf6 --- /dev/null +++ b/tests/topotests/bgp_features/peer1/exabgp.cfg @@ -0,0 +1,12 @@ +group exabgp { + process announce-routes { + run "/etc/exabgp/exa_readpipe.py /var/run/exabgp_peer1.in"; + encoder text; + } + neighbor 192.168.101.1 { + router-id 192.168.101.3; + local-address 192.168.101.3; + local-as 65403; + peer-as 65000; + } +} diff --git a/tests/topotests/bgp_features/peer2/exa_readpipe.py b/tests/topotests/bgp_features/peer2/exa_readpipe.py new file mode 100644 index 0000000000..dba1536388 --- /dev/null +++ b/tests/topotests/bgp_features/peer2/exa_readpipe.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python +"Helper script to read api commands from a pipe and feed them to ExaBGP" + +import sys + +if len(sys.argv) != 2: + sys.exit(1) +fifo = sys.argv[1] + +while True: + pipe = open(fifo, 'r') + with pipe: + line = pipe.readline().strip() + if line != "": + sys.stdout.write("{}\n".format(line)) + sys.stdout.flush() + pipe.close() + +sys.exit(0) diff --git a/tests/topotests/bgp_features/peer2/exabgp.cfg b/tests/topotests/bgp_features/peer2/exabgp.cfg new file mode 100644 index 0000000000..1f65547bc5 --- /dev/null +++ b/tests/topotests/bgp_features/peer2/exabgp.cfg @@ -0,0 +1,12 @@ +group exabgp { + process announce-routes { + run "/etc/exabgp/exa_readpipe.py /var/run/exabgp_peer2.in"; + encoder text; + } + neighbor 192.168.101.1 { + router-id 192.168.101.4; + local-address 192.168.101.4; + local-as 65404; + peer-as 65000; + } +} diff --git a/tests/topotests/bgp_features/peer3/exa_readpipe.py b/tests/topotests/bgp_features/peer3/exa_readpipe.py new file mode 100644 index 0000000000..dba1536388 --- /dev/null +++ b/tests/topotests/bgp_features/peer3/exa_readpipe.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python +"Helper script to read api commands from a pipe and feed them to ExaBGP" + +import sys + +if len(sys.argv) != 2: + sys.exit(1) +fifo = sys.argv[1] + +while True: + pipe = open(fifo, 'r') + with pipe: + line = pipe.readline().strip() + if line != "": + sys.stdout.write("{}\n".format(line)) + sys.stdout.flush() + pipe.close() + +sys.exit(0) diff --git a/tests/topotests/bgp_features/peer3/exabgp.cfg b/tests/topotests/bgp_features/peer3/exabgp.cfg new file mode 100644 index 0000000000..8632cc86c5 --- /dev/null +++ b/tests/topotests/bgp_features/peer3/exabgp.cfg @@ -0,0 +1,12 @@ +group exabgp { + process announce-routes { + run "/etc/exabgp/exa_readpipe.py /var/run/exabgp_peer3.in"; + encoder text; + } + neighbor 192.168.101.1 { + router-id 192.168.101.5; + local-address 192.168.101.5; + local-as 65405; + peer-as 65000; + } +} diff --git a/tests/topotests/bgp_features/peer4/exa_readpipe.py b/tests/topotests/bgp_features/peer4/exa_readpipe.py new file mode 100644 index 0000000000..dba1536388 --- /dev/null +++ b/tests/topotests/bgp_features/peer4/exa_readpipe.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python +"Helper script to read api commands from a pipe and feed them to ExaBGP" + +import sys + +if len(sys.argv) != 2: + sys.exit(1) +fifo = sys.argv[1] + +while True: + pipe = open(fifo, 'r') + with pipe: + line = pipe.readline().strip() + if line != "": + sys.stdout.write("{}\n".format(line)) + sys.stdout.flush() + pipe.close() + +sys.exit(0) diff --git a/tests/topotests/bgp_features/peer4/exabgp.cfg b/tests/topotests/bgp_features/peer4/exabgp.cfg new file mode 100644 index 0000000000..06bc0d6e64 --- /dev/null +++ b/tests/topotests/bgp_features/peer4/exabgp.cfg @@ -0,0 +1,12 @@ +group exabgp { + process announce-routes { + run "/etc/exabgp/exa_readpipe.py /var/run/exabgp_peer4.in"; + encoder text; + } + neighbor 192.168.101.1 { + router-id 192.168.101.6; + local-address 192.168.101.6; + local-as 65406; + peer-as 65000; + } +} diff --git a/tests/topotests/bgp_features/r1/bgp_damp_announced.json b/tests/topotests/bgp_features/r1/bgp_damp_announced.json new file mode 100644 index 0000000000..cb4a2c9b2f --- /dev/null +++ b/tests/topotests/bgp_features/r1/bgp_damp_announced.json @@ -0,0 +1,21 @@ +{ + "localAS":65000, + "routes":{ + "192.168.31.0/24": [ { "valid":true, "network":"192.168.31.0\/24", "peerId":"192.168.101.3" } ], + "192.168.32.0/24": [ { "valid":true, "network":"192.168.32.0\/24", "peerId":"192.168.101.3" } ], + "192.168.33.0/24": [ { "valid":true, "network":"192.168.33.0\/24", "peerId":"192.168.101.3" } ], + "192.168.34.0/24": [ { "valid":true, "network":"192.168.34.0\/24", "peerId":"192.168.101.3" } ], + "192.168.41.0/24": [ { "valid":true, "network":"192.168.41.0\/24", "peerId":"192.168.101.4" } ], + "192.168.42.0/24": [ { "valid":true, "network":"192.168.42.0\/24", "peerId":"192.168.101.4" } ], + "192.168.43.0/24": [ { "valid":true, "network":"192.168.43.0\/24", "peerId":"192.168.101.4" } ], + "192.168.44.0/24": [ { "valid":true, "network":"192.168.44.0\/24", "peerId":"192.168.101.4" } ], + "192.168.51.0/24": [ { "valid":true, "network":"192.168.51.0\/24", "peerId":"192.168.101.5" } ], + "192.168.52.0/24": [ { "valid":true, "network":"192.168.52.0\/24", "peerId":"192.168.101.5" } ], + "192.168.53.0/24": [ { "valid":true, "network":"192.168.53.0\/24", "peerId":"192.168.101.5" } ], + "192.168.54.0/24": [ { "valid":true, "network":"192.168.54.0\/24", "peerId":"192.168.101.5" } ], + "192.168.61.0/24": [ { "valid":true, "network":"192.168.61.0\/24", "peerId":"192.168.101.6" } ], + "192.168.62.0/24": [ { "valid":true, "network":"192.168.62.0\/24", "peerId":"192.168.101.6" } ], + "192.168.63.0/24": [ { "valid":true, "network":"192.168.63.0\/24", "peerId":"192.168.101.6" } ], + "192.168.64.0/24": [ { "valid":true, "network":"192.168.64.0\/24", "peerId":"192.168.101.6" } ] + } +} diff --git a/tests/topotests/bgp_features/r1/bgp_damp_setup.json b/tests/topotests/bgp_features/r1/bgp_damp_setup.json new file mode 100644 index 0000000000..f9f89db894 --- /dev/null +++ b/tests/topotests/bgp_features/r1/bgp_damp_setup.json @@ -0,0 +1,10 @@ +{ + "ipv4Unicast":{ + "peers":{ + "192.168.101.3":{"remoteAs":65403, "state":"Established"}, + "192.168.101.4":{"remoteAs":65404, "state":"Established"}, + "192.168.101.5":{"remoteAs":65405, "state":"Established"}, + "192.168.101.6":{"remoteAs":65406, "state":"Established"} + } + } +} diff --git a/tests/topotests/bgp_features/r2/bgp_damp_announced.json b/tests/topotests/bgp_features/r2/bgp_damp_announced.json new file mode 100644 index 0000000000..9394358f82 --- /dev/null +++ b/tests/topotests/bgp_features/r2/bgp_damp_announced.json @@ -0,0 +1,21 @@ +{ + "localAS":65000, + "routes":{ + "192.168.31.0/24": [ { "network":"192.168.31.0\/24", "peerId":"192.168.0.1" } ], + "192.168.32.0/24": [ { "network":"192.168.32.0\/24", "peerId":"192.168.0.1" } ], + "192.168.33.0/24": [ { "network":"192.168.33.0\/24", "peerId":"192.168.0.1" } ], + "192.168.34.0/24": [ { "network":"192.168.34.0\/24", "peerId":"192.168.0.1" } ], + "192.168.41.0/24": [ { "network":"192.168.41.0\/24", "peerId":"192.168.0.1" } ], + "192.168.42.0/24": [ { "network":"192.168.42.0\/24", "peerId":"192.168.0.1" } ], + "192.168.43.0/24": [ { "network":"192.168.43.0\/24", "peerId":"192.168.0.1" } ], + "192.168.44.0/24": [ { "network":"192.168.44.0\/24", "peerId":"192.168.0.1" } ], + "192.168.51.0/24": [ { "network":"192.168.51.0\/24", "peerId":"192.168.0.1" } ], + "192.168.52.0/24": [ { "network":"192.168.52.0\/24", "peerId":"192.168.0.1" } ], + "192.168.53.0/24": [ { "network":"192.168.53.0\/24", "peerId":"192.168.0.1" } ], + "192.168.54.0/24": [ { "network":"192.168.54.0\/24", "peerId":"192.168.0.1" } ], + "192.168.61.0/24": [ { "network":"192.168.61.0\/24", "peerId":"192.168.0.1" } ], + "192.168.62.0/24": [ { "network":"192.168.62.0\/24", "peerId":"192.168.0.1" } ], + "192.168.63.0/24": [ { "network":"192.168.63.0\/24", "peerId":"192.168.0.1" } ], + "192.168.64.0/24": [ { "network":"192.168.64.0\/24", "peerId":"192.168.0.1" } ] + } +} diff --git a/tests/topotests/bgp_features/r2/bgp_damp_withdrawn.json b/tests/topotests/bgp_features/r2/bgp_damp_withdrawn.json new file mode 100644 index 0000000000..f3c54a70a1 --- /dev/null +++ b/tests/topotests/bgp_features/r2/bgp_damp_withdrawn.json @@ -0,0 +1,18 @@ +{ + "192.168.31.0/24": null, + "192.168.32.0/24": null, + "192.168.33.0/24": null, + "192.168.34.0/24": null, + "192.168.41.0/24": null, + "192.168.42.0/24": null, + "192.168.43.0/24": null, + "192.168.44.0/24": null, + "192.168.51.0/24": null, + "192.168.52.0/24": null, + "192.168.53.0/24": null, + "192.168.54.0/24": null, + "192.168.61.0/24": null, + "192.168.62.0/24": null, + "192.168.63.0/24": null, + "192.168.64.0/24": null +} diff --git a/tests/topotests/bgp_features/test_bgp_features.py b/tests/topotests/bgp_features/test_bgp_features.py index 5f3809c2b3..3d963b4cf6 100644 --- a/tests/topotests/bgp_features/test_bgp_features.py +++ b/tests/topotests/bgp_features/test_bgp_features.py @@ -33,6 +33,7 @@ import sys import pytest import re import time +from time import sleep # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) @@ -64,6 +65,14 @@ class BGPFeaturesTopo1(Topo): for rtrNum in range(1, 6): tgen.add_router("r{}".format(rtrNum)) + # create ExaBGP peers + for peer_num in range(1, 5): + tgen.add_exabgp_peer( + "peer{}".format(peer_num), + ip="192.168.101.{}".format(peer_num + 2), + defaultRoute="via 192.168.101.1", + ) + # Setup Switches and connections for swNum in range(1, 11): tgen.add_switch("sw{}".format(swNum)) @@ -89,6 +98,12 @@ class BGPFeaturesTopo1(Topo): tgen.gears["r2"].add_link(tgen.gears["sw5"]) tgen.gears["r5"].add_link(tgen.gears["sw5"]) + # Add ExaBGP peers to sw4 + tgen.gears["peer1"].add_link(tgen.gears["sw4"]) + tgen.gears["peer2"].add_link(tgen.gears["sw4"]) + tgen.gears["peer3"].add_link(tgen.gears["sw4"]) + tgen.gears["peer4"].add_link(tgen.gears["sw4"]) + ##################################################### # @@ -1093,6 +1108,662 @@ def test_bgp_delayopen_dual(): # end test_bgp_delayopen_dual +def test_bgp_dampening_setup(): + "BGP route-flap dampening test setup" + + # This test starts four ExaBGP peers, adds them as neighbors to the + # configuration of router r1 and checks if connections get established. + + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Starting BGP route-flap dampening test setup") + + # Start ExaBGP peers connected to r1 via switch 4 + logger.info("Starting ExaBGP peers") + for peer_num in range(1, 5): + logger.info("Creating named pipe for ExaBGP peer peer{}".format(peer_num)) + fifo_in = "/var/run/exabgp_peer{}.in".format(peer_num) + if os.path.exists(fifo_in): + os.remove(fifo_in) + os.mkfifo(fifo_in, 0o777) + logger.info("Starting ExaBGP on peer peer{}".format(peer_num)) + peer = tgen.gears["peer{}".format(peer_num)] + peer_dir = os.path.join(CWD, "peer{}".format(peer_num)) + env_file = os.path.join(CWD, "exabgp.env") + peer.start(peer_dir, env_file) + + # Add ExaBGP peers to configuration of router r2 + logger.info("Adding ExaBGP peers as neighbors to configuration of router r2") + tgen.net["r1"].cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "neighbor 192.168.101.3 remote-as 65403"' + ) + tgen.net["r1"].cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor 192.168.101.3 route-map testmap-in"' + ) + tgen.net["r1"].cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor 192.168.101.3 route-map testmap-out"' + ) + tgen.net["r1"].cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "neighbor 192.168.101.4 remote-as 65404"' + ) + tgen.net["r1"].cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor 192.168.101.4 route-map testmap-in"' + ) + tgen.net["r1"].cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor 192.168.101.4 route-map testmap-out"' + ) + tgen.net["r1"].cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "neighbor 192.168.101.5 remote-as 65405"' + ) + tgen.net["r1"].cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor 192.168.101.5 route-map testmap-in"' + ) + tgen.net["r1"].cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor 192.168.101.5 route-map testmap-out"' + ) + tgen.net["r1"].cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "neighbor 192.168.101.6 remote-as 65406"' + ) + tgen.net["r1"].cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor 192.168.101.6 route-map testmap-in"' + ) + tgen.net["r1"].cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor 192.168.101.6 route-map testmap-out"' + ) + + # Check if exabgp peers are up and running + logger.info("Checking for established connections to ExaBGP peers on router r1") + router = tgen.gears["r1"] + reffile = os.path.join(CWD, "r1/bgp_damp_setup.json") + expected = json.loads(open(reffile).read()) + test_func = functools.partial( + topotest.router_json_cmp, router, "show ip bgp summary json", expected + ) + _, res = topotest.run_and_expect(test_func, None, count=10, wait=1) + assertmsg = ( + "BGP session on r1 did not establish connections with one ore more ExaBGP peers" + ) + assert res is None, assertmsg + + # end test_bgp_dampening_setup + + +def test_bgp_dampening_route_announce(): + "Test of BGP route-flap dampening route announcement" + + # This test checks if the four ExaBGP peers can announce routes to router + # r1 and if these routes get forwarded to router r2. + + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Starting test of BGP route-flap dampening route announcement") + + # Announce routes on exabgp peers to r2 + logger.info("Announcing routes on ExaBGP peers to r1") + for prefix_iter in range(1, 5): + for peer_num in range(1, 5): + pipe = open("/run/exabgp_peer{}.in".format(peer_num), "w") + with pipe: + pipe.write( + "announce route 192.168.{}{}.0/24 next-hop 192.168.101.{}\n".format( + (peer_num + 2), prefix_iter, (peer_num + 2) + ) + ) + pipe.close() + sleep(0.1) # ExaBGP API command processing delay + + # Check if routes announced by ExaBGP peers are present in RIB of router r1 + logger.info( + "Checking if routes announced by ExaBGP peers are present in RIB of router r1" + ) + router = tgen.gears["r1"] + reffile = os.path.join(CWD, "r1/bgp_damp_announced.json") + expected = json.loads(open(reffile).read()) + test_func = functools.partial( + topotest.router_json_cmp, router, "show ip bgp json", expected + ) + _, res = topotest.run_and_expect(test_func, None, count=10, wait=1) + assertmsg = ( + "BGP session on router r1 did not receive routes announced by ExaBGP peers" + ) + assert res is None, assertmsg + + # Check if routes announced by ExaBGP peers to router r1 have been forwarded + # and are now present in RIB of router r2 + logger.info( + "Checking if forwarded routes announced by ExaBGP peers are present in RIB of router r2" + ) + router = tgen.gears["r2"] + reffile = os.path.join(CWD, "r2/bgp_damp_announced.json") + expected = json.loads(open(reffile).read()) + test_func = functools.partial( + topotest.router_json_cmp, router, "show ip bgp json", expected + ) + _, res = topotest.run_and_expect(test_func, None, count=10, wait=1) + assertmsg = "BGP session on router r2 did not receive routes announced by ExaBGP peers forwarded by router r1" + assert res is None, assertmsg + + # end test_bgp_dampening_route_announce + + +def test_bgp_dampening_disabled(): + "Test of BGP route-flapping with dampening disabled" + + # This test verifies that flapped routes do not get withdrawn from the RIB + # of router r1 if dampening is disabled. + + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Starting test of BGP route-flapping with dampening disabled") + + # Flapping routes on ExaBGP peer peer1 + logger.info( + "Flapping routes on ExaBGP peer peer1 with route-flap dampening disabled" + ) + for _ in range(1, 5): + for prefix_iter in range(1, 5): + pipe = open("/run/exabgp_peer1.in", "w") + with pipe: + pipe.write( + "withdraw route 192.168.3{}.0/24 next-hop 192.168.101.3\n".format( + prefix_iter + ) + ) + pipe.close() + sleep(0.1) # ExaBGP API command processing delay + sleep(1) # Give the BGP session on router r1 time to process routes + for prefix_iter in range(1, 5): + pipe = open("/run/exabgp_peer1.in", "w") + with pipe: + pipe.write( + "announce route 192.168.3{}.0/24 next-hop 192.168.101.3\n".format( + prefix_iter + ) + ) + pipe.close() + sleep(0.1) # ExaBGP API command processing delay + + # Verify flapped routes are still present in RIB of router r1 + logger.info( + "Verifying that the flapped routes are still present in RIB of router r1" + ) + router = tgen.gears["r1"] + reffile = os.path.join(CWD, "r1/bgp_damp_announced.json") + expected = json.loads(open(reffile).read()) + test_func = functools.partial( + topotest.router_json_cmp, router, "show ip bgp json", expected + ) + _, res = topotest.run_and_expect(test_func, None, count=10, wait=1) + assertmsg = "BGP session on router r1 removed flapped routes despite route-flap dampening being disabled" + assert res is None, assertmsg + + # end test_bgp_dampening_disabled + + +def test_bgp_dampening_config(): + "Test of BGP route-flap dampening configuration" + + # This test adds peer-group group1 with peers peer1 and peer2 to the + # configuration of router r1, sets up dampening configurations with + # different profiles and verifies the configured dampening parameters. + + tgen = get_topogen() + r_1 = tgen.net["r1"] + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Starting test of BGP route-flap dampening configuration") + + # Add peer-group group1 with peers peer1 and peer2 + logger.info( + "Creating peer-group group1 and adding ExaBGP peers peer1 and peer2 to it" + ) + r_1.cmd('vtysh -c "conf t" -c "router bgp 65000" -c "neighbor group1 peer-group"') + r_1.cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "neighbor 192.168.101.3 peer-group group1"' + ) # peer1 + r_1.cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "neighbor 192.168.101.4 peer-group group1"' + ) # peer2 + + # Enable different dampening profiles for peer1, peer3, group1 and global + # configuration + logger.info( + "Enabling different dampening profiles for peer1, peer3, group1 and global configuration" + ) + r_1.cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "bgp dampening 30 300 900 90"' + ) + r_1.cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor group1 dampening 20 200 600 60"' + ) + r_1.cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor 192.168.101.3 dampening 10 100 300 30"' + ) # peer1 + r_1.cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "neighbor 192.168.101.5 dampening 10 100 300 30"' + ) # peer3 + + # Verify route-flap dampening configuration + logger.info("Verifying route-flap dampening configuration on router r1") + vtyout = r_1.cmd('vtysh -c "show running-config"') + assertmsg = "BGP Session on r1 does not show enabled global route-flap dampening in running configuration" + assert re.search("bgp dampening 30 300 900 90", vtyout), assertmsg + assertmsg = "BGP Session on r1 does not show route-flap dampening enabled for peer-group group1 in running configuration" + assert re.search("neighbor group1 dampening 20 200 600 60", vtyout), assertmsg + assertmsg = "BGP Session on r1 does not show route-flap dampening enabled for peer peer1 in running configuration" + assert re.search( + "neighbor 192.168.101.3 dampening 10 100 300 30", vtyout + ), assertmsg + assertmsg = "BGP Session on r1 does not show route-flap dampening enabled for peer peer3 in running configuration" + assert re.search( + "neighbor 192.168.101.5 dampening 10 100 300 30", vtyout + ), assertmsg + + # end test_bgp_dampening_config + + +def test_bgp_dampening_profile_peer_over_group(): + "Test of BGP route-flap dampening profile preferences: peer over group" + + # This test verifies that the dampening profile of a peer takes precedence + # over the dampening profile of its peer-group by flapping the peers routes + # until dampened and comparing the reuse times to the one specified in the + # dampening configuration. + + tgen = get_topogen() + r_1 = tgen.net["r1"] + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info( + "Starting test of BGP route-flap dampening profile preferences: peer over group" + ) + + # Flapping routes on ExaBGP peer peer1 + logger.info( + "Flapping routes on ExaBGP peer peer1 with route-flap dampening enabled" + ) + for _ in range(1, 5): + for prefix_iter in range(1, 5): + pipe = open("/run/exabgp_peer1.in", "w") + with pipe: + pipe.write( + "withdraw route 192.168.3{}.0/24 next-hop 192.168.101.3\n".format( + prefix_iter + ) + ) + pipe.close() + sleep(0.1) # ExaBGP API command processing delay + sleep(1) # Give the BGP session on router r1 time to process routes + for prefix_iter in range(1, 5): + pipe = open("/run/exabgp_peer1.in", "w") + with pipe: + pipe.write( + "announce route 192.168.3{}.0/24 next-hop 192.168.101.3\n".format( + prefix_iter + ) + ) + pipe.close() + sleep(0.1) # ExaBGP API command processing delay + + # Check damped paths on r1 for routes of peer1 witn peer profile + logger.info( + "Checking if router r1 used the correct dampening profile on routes flapped by ExaBGP peer peer1" + ) + sleep(5) # Wait 5 seconds for paths to show up in dampened-paths list + vtyout = r_1.cmd('vtysh -c "show ip bgp dampening dampened-paths"') + routes = re.findall(r"\*d 192\.168\.3\d\.0\/24.*", vtyout) + assertmsg = ( + "BGP session on router r1 did not dampen routes flapped by ExaBGP peer peer1" + ) + assert len(routes) == 4, assertmsg + assertmsg = "BGP session on router r1 used wrong dampening profile for a route flapped by ExaBGP peer peer1" + for route in routes: + assert (int(route.split()[3].split(":")[0]) == 0) and ( # hours of reuse time + 35 > int(route.split()[3].split(":")[1]) > 25 + ), assertmsg # minutes of reuse time + + # end test_bgp_dampening_profile_peer_over_group + + +def test_bgp_dampening_profile_group_over_global(): + "Test of BGP route-flap dampening profile preferences: group over global" + + # This test verifies that the dampening profile of a peer-group takes + # precedence over the global dampening profile by flapping the routes of a + # peer-group member until dampened and comparing the reuse times to the one + # specified in the dampening configuration. + + tgen = get_topogen() + r_1 = tgen.net["r1"] + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info( + "Starting test of BGP route-flap dampening profile preferences: group over global" + ) + + # Flapping routes on ExaBGP peer peer2 + logger.info( + "Flapping routes on ExaBGP peer peer2 with route-flap dampening enabled" + ) + for _ in range(1, 5): + for prefix_iter in range(1, 5): + pipe = open("/run/exabgp_peer2.in", "w") + with pipe: + pipe.write( + "withdraw route 192.168.4{}.0/24 next-hop 192.168.101.4\n".format( + prefix_iter + ) + ) + pipe.close() + sleep(0.1) # ExaBGP API command processing delay + sleep(1) # Give the BGP session on router r1 time to process routes + for prefix_iter in range(1, 5): + pipe = open("/run/exabgp_peer2.in", "w") + with pipe: + pipe.write( + "announce route 192.168.4{}.0/24 next-hop 192.168.101.4\n".format( + prefix_iter + ) + ) + pipe.close() + sleep(0.1) # ExaBGP API command processing delay + + # Check damped paths on r1 for routes of peer2 witn group profile + logger.info( + "Checking if router r1 used the correct dampening profile on routes flapped by ExaBGP peer peer2" + ) + sleep(5) # wait 5 seconds for paths to shop up in damp list + vtyout = r_1.cmd('vtysh -c "show ip bgp dampening dampened-paths"') + routes = re.findall(r"\*d 192\.168\.4\d\.0\/24.*", vtyout) + assertmsg = ( + "BGP session on router r1 did not dampen routes flapped by ExaBGP peer peer2" + ) + assert len(routes) == 4, assertmsg + assertmsg = "BGP session on router r1 used wrong dampening profile for a route flapped by ExaBGP peer peer2" + for route in routes: + assert (int(route.split()[3].split(":")[0]) == 0) and ( # hours of reuse time + 65 > int(route.split()[3].split(":")[1]) > 55 + ), assertmsg # minutes of reuse time + + # end test_bgp_dampening_profile_group_over_global + + +def test_bgp_dampening_profile_peer_over_global(): + "Test of BGP route-flap dampening profile preferences: peer over global" + + # This test verifies that the dampening profile of a peer takes precedence + # over the global dampening profile by flapping the routes of the peer until + # dampened and comparing the reuse times to the one specified in the + # dampening configuration. + + tgen = get_topogen() + r_1 = tgen.net["r1"] + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info( + "Starting test of BGP route-flap dampening profile preferences: peer over global" + ) + + # Flapping routes on ExaBGP peer peer3 + logger.info( + "Flapping routes on ExaBGP peer peer3 with route-flap dampening enabled" + ) + for _ in range(1, 5): + for prefix_iter in range(1, 5): + pipe = open("/run/exabgp_peer3.in", "w") + with pipe: + pipe.write( + "withdraw route 192.168.5{}.0/24 next-hop 192.168.101.5\n".format( + prefix_iter + ) + ) + pipe.close() + sleep(0.1) # ExaBGP API command processing delay + sleep(1) # Give the BGP session on router r1 time to process routes + for prefix_iter in range(1, 5): + pipe = open("/run/exabgp_peer3.in", "w") + with pipe: + pipe.write( + "announce route 192.168.5{}.0/24 next-hop 192.168.101.5\n".format( + prefix_iter + ) + ) + pipe.close() + sleep(0.1) # ExaBGP API command processing delay + + # Check damped paths on r1 for routes of peer3 witn peer profile + logger.info( + "Checking if router r1 used the correct dampening profile on routes flapped by ExaBGP peer peer3" + ) + sleep(5) # wait 5 seconds for paths to shop up in damp list + vtyout = r_1.cmd('vtysh -c "show ip bgp dampening dampened-paths"') + routes = re.findall(r"\*d 192\.168\.5\d\.0\/24.*", vtyout) + assertmsg = ( + "BGP session on router r1 did not dampen routes flapped by ExaBGP peer peer3" + ) + assert len(routes) == 4, assertmsg + assertmsg = "BGP session on router r1 used wrong dampening profile for a route flapped by ExaBGP peer peer3" + for route in routes: + assert (int(route.split()[3].split(":")[0]) == 0) and ( # hours of reuse time + 35 > int(route.split()[3].split(":")[1]) > 25 + ), assertmsg # minutes of reuse time + + # end test_bgp_dampening_profile_peer_over_global + + +def test_bgp_dampening_profile_global(): + "Test of BGP route-flap dampening global profile" + + # This test verifies the application of the global dampening profile by + # flapping the routes of a peer until dampened and comparing the reuse times + # to the one specified in the dampening configuration. + + tgen = get_topogen() + r_1 = tgen.net["r1"] + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Starting test of BGP route-flap dampening global profile") + + # Flapping routes on ExaBGP peer peer4 + logger.info( + "Flapping routes on ExaBGP peer peer4 with route-flap dampening enabled" + ) + for _ in range(1, 5): + for prefix_iter in range(1, 5): + pipe = open("/run/exabgp_peer4.in", "w") + with pipe: + pipe.write( + "withdraw route 192.168.6{}.0/24 next-hop 192.168.101.6\n".format( + prefix_iter + ) + ) + pipe.close() + sleep(0.1) # ExaBGP API command processing delay + sleep(1) # Give the BGP session on router r1 time to process routes + for prefix_iter in range(1, 5): + pipe = open("/run/exabgp_peer4.in", "w") + with pipe: + pipe.write( + "announce route 192.168.6{}.0/24 next-hop 192.168.101.6\n".format( + prefix_iter + ) + ) + pipe.close() + sleep(0.1) # ExaBGP API command processing delay + + # Check damped paths on r1 for routes of peer4 witn global profile + logger.info( + "Checking if router r1 used the global dampening profile on routes flapped by ExaBGP peer peer4" + ) + sleep(5) # wait 5 seconds for paths to shop up in damp list + vtyout = r_1.cmd('vtysh -c "show ip bgp dampening dampened-paths"') + routes = re.findall(r"\*d 192\.168\.6\d\.0\/24.*", vtyout) + assertmsg = ( + "BGP session on router r1 did not dampen routes flapped by ExaBGP peer peer4" + ) + assert len(routes) == 4, assertmsg + assertmsg = "BGP session on router r1 did not use the global dampening profile for a route flapped by ExaBGP peer peer4" + for route in routes: + assert (int(route.split()[3].split(":")[0]) == 1) and ( # hours of reuse time + 35 > int(route.split()[3].split(":")[1]) > 25 + ), assertmsg # minutes of reuse time + + # end test_bgp_dampening_profile_global + + +def test_bgp_dampening_withdaw(): + "Test BGP route-flap dampening route withdraw" + + # This test verifies that the withrawl of dampened routes from the RIB of + # router r1 was propagated to router r2. + + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Starting test of BGP route-flap dampening route withdraw") + + # Check if routes dampened on router r1 have been withdrawn from the RIB on + # router r2 + logger.info( + "Checking if routes dampened on router r1 have been withdrawn of RIB on router r2" + ) + reffile = os.path.join(CWD, "r2/bgp_damp_withdrawn.json") + expected = json.loads(open(reffile).read()) + test_func = functools.partial( + topotest.router_json_cmp, tgen.gears["r2"], "show ip bgp json", expected + ) + _, res = topotest.run_and_expect(test_func, None, count=5, wait=1) + assertmsg = "BGP session on router r2 did not receive withdraw of routes dampened on router r1" + assert res is None, assertmsg + + # end test_bgp_dampening_withdaw + + +def test_bgp_dampening_cleanup(): + "BGP route-flap dampening test cleanup" + + # This test cleans up after other tests associated with route-flap dampening + # by disabling all dampening configurations, removing added peers and + # peer-groups from the configuration on router r1, and shutting down ExaBGP + # peers peer1, peer2 and peer3. + + tgen = get_topogen() + r_1 = tgen.net["r1"] + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Starting BGP route-flap dampening test cleanup") + + # Disable all dampening configurations + logger.info("Disabling all dampening configurations") + r_1.cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "no bgp dampening"' + ) + r_1.cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "no neighbor group1 dampening"' + ) + r_1.cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "no neighbor 192.168.101.3 dampening"' + ) + r_1.cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "address-family ipv4 unicast" -c "no neighbor 192.168.101.5 dampening"' + ) + + # Remove ExaBGP peers from configuration of router r1 + logger.info("Removing ExaBGP peers from configuration of router r1") + for router_num in range(3, 7): + r_1.cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "no neighbor 192.168.101.{}"'.format( + router_num + ) + ) + + # Remove peer-group group1 from configuration of router r1 + logger.info("Removing peer-group group1 peers from configuration of router r1") + r_1.cmd( + 'vtysh -c "conf t" -c "router bgp 65000" -c "no neighbor group1 peer-group"' + ) + + # Stop ExaBGP peers and remove associated named pipes + logger.info("Stopping ExaBGP peers and removing associated named pipes") + for peer_num in range(1, 5): + logger.info("Terminating ExaBGP on peer peer{}".format(peer_num)) + peer = tgen.gears["peer{}".format(peer_num)] + logger.info("Removing named pipe of ExaBGP peer peer{}".format(peer_num)) + fifo_in = "/var/run/exabgp_peer{}.in".format(peer_num) + peer.stop() + if os.path.exists(fifo_in): + os.remove(fifo_in) + + # end test_bgp_dampening_cleanup + + +def test_bgp_dampening_aftermath(): + "BGP route-flap dampening aftermath test" + + # This test verifies routers r1 and r2 not being affected by the route-flap + # dampening test series. + + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + # Check BGP Summary on routers r1 and r2 + for rtr_num in [1, 2]: + logger.info( + "Checking if BGP router on r{} remains unaffected by route-flap dampening tests".format( + rtr_num + ) + ) + router = tgen.gears["r{}".format(rtr_num)] + reffile = os.path.join(CWD, "r{}/show_bgp.json".format(rtr_num)) + expected = json.loads(open(reffile).read()) + test_func = functools.partial( + topotest.router_json_cmp, router, "show ip bgp json", expected + ) + _, res = topotest.run_and_expect(test_func, None, count=10, wait=2) + assertmsg = "BGP routes on router r{} are wrong after route-flap dampening tests".format( + rtr_num + ) + assert res is None, assertmsg + + # end test_bgp_dampening_aftermath + + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_listen_on_multiple_addresses/bgp_listen_on_multiple_addresses.json b/tests/topotests/bgp_listen_on_multiple_addresses/bgp_listen_on_multiple_addresses.json new file mode 100644 index 0000000000..95de8cc10c --- /dev/null +++ b/tests/topotests/bgp_listen_on_multiple_addresses/bgp_listen_on_multiple_addresses.json @@ -0,0 +1,154 @@ +{ + "ipv4base": "10.0.0.0", + "ipv4mask": 24, + "ipv6base": "fd00::", + "ipv6mask": 64, + "link_ip_start": { + "ipv4": "10.0.0.0", + "v4mask": 24, + "ipv6": "fd00::", + "v6mask": 64 + }, + "lo_prefix": { + "ipv4": "1.0.", + "v4mask": 32, + "ipv6": "2001:DB8:F::", + "v6mask": 128 + }, + "routers": { + "r1": { + "links": { + "lo": { + "ipv4": "auto", + "ipv6": "auto", + "type": "loopback" + }, + "r2": { + "ipv4": "auto", + "ipv6": "auto" + } + }, + "bgp": { + "local_as": "1000", + "address_family": { + "ipv4": { + "unicast": { + "neighbor": { + "r2": { + "dest_link": { + "r1": {} + } + } + } + } + } + } + } + }, + "r2": { + "links": { + "lo": { + "ipv4": "auto", + "ipv6": "auto", + "type": "loopback" + }, + "r1": { + "ipv4": "auto", + "ipv6": "auto" + }, + "r3": { + "ipv4": "auto", + "ipv6": "auto" + } + }, + "bgp": { + "local_as": "2000", + "address_family": { + "ipv4": { + "unicast": { + "neighbor": { + "r1": { + "dest_link": { + "r2": {} + } + }, + "r3": { + "dest_link": { + "r2": {} + } + } + } + } + } + } + } + }, + "r3": { + "links": { + "lo": { + "ipv4": "auto", + "ipv6": "auto", + "type": "loopback" + }, + "r2": { + "ipv4": "auto", + "ipv6": "auto" + }, + "r4": { + "ipv4": "auto", + "ipv6": "auto" + } + }, + "bgp": { + "local_as": "2000", + "address_family": { + "ipv4": { + "unicast": { + "neighbor": { + "r2": { + "dest_link": { + "r3": {} + } + }, + "r4": { + "dest_link": { + "r3": {} + } + } + } + } + } + } + } + }, + "r4": { + "links": { + "lo": { + "ipv4": "auto", + "ipv6": "auto", + "type": "loopback" + }, + "r3": { + "ipv4": "auto", + "ipv6": "auto" + } + }, + "bgp": { + "local_as": "3000", + "address_family": { + "ipv4": { + "unicast": { + "neighbor": { + "r3": { + "dest_link": { + "r4": {} + } + } + } + } + } + } + } + } + } +} diff --git a/tests/topotests/bgp_listen_on_multiple_addresses/test_bgp_listen_on_multiple_addresses.py b/tests/topotests/bgp_listen_on_multiple_addresses/test_bgp_listen_on_multiple_addresses.py new file mode 100755 index 0000000000..d773e87ef6 --- /dev/null +++ b/tests/topotests/bgp_listen_on_multiple_addresses/test_bgp_listen_on_multiple_addresses.py @@ -0,0 +1,160 @@ +#!/usr/bin/env python + +# +# test_bgp_listen_on_multiple_addresses.py +# Part of NetDEF Topology Tests +# +# Copyright (c) 2021 by Boeing Defence Australia +# Adriano Marto Reis +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +test_bgp_listen_on_multiple_addresses.py: Test BGP daemon listening for +connections on multiple addresses. + + +------+ +------+ +------+ +------+ + | | | | | | | | + | r1 |--------| r2 |--------| r3 |--------| r4 | + | | | | | | | | + +------+ +------+ +------+ +------+ + + | | | | + | AS 1000 | AS 2000 | AS 3000 | + | | | | + +------------+--------------------------------+-------------+ +""" + +import os +import sys +import json +import pytest + + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +from lib.topogen import Topogen, get_topogen +from lib.topojson import build_topo_from_json, build_config_from_json +from lib.common_config import start_topology +from lib.topotest import router_json_cmp, run_and_expect +from mininet.topo import Topo +from functools import partial + + +LISTEN_ADDRESSES = { + "r1": ["10.0.0.1"], + "r2": ["10.0.0.2", "10.0.1.1"], + "r3": ["10.0.1.2", "10.0.2.1"], + "r4": ["10.0.2.2"], +} + + +# Reads data from JSON File for topology and configuration creation. +jsonFile = "{}/bgp_listen_on_multiple_addresses.json".format(CWD) +try: + with open(jsonFile, "r") as topoJson: + topo = json.load(topoJson) +except IOError: + assert False, "Could not read file {}".format(jsonFile) + + +class TemplateTopo(Topo): + "Topology builder." + + def build(self, *_args, **_opts): + "Defines the allocation and relationship between routers and switches." + tgen = get_topogen(self) + build_topo_from_json(tgen, topo) + + +def setup_module(mod): + "Sets up the test environment." + tgen = Topogen(TemplateTopo, mod.__name__) + + # Adds extra parameters to bgpd so they listen for connections on specific + # multiple addresses. + for router_name in tgen.routers().keys(): + tgen.net[router_name].daemons_options["bgpd"] = "-l " + " -l ".join( + LISTEN_ADDRESSES[router_name] + ) + + start_topology(tgen) + build_config_from_json(tgen, topo) + + +def teardown_module(_mod): + "Tears-down the test environment." + tgen = get_topogen() + tgen.stop_topology() + + +def test_peering(): + "Checks if the routers peer-up." + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + _bgp_converge_initial("r1", "10.0.0.2") + _bgp_converge_initial("r2", "10.0.0.1") + _bgp_converge_initial("r2", "10.0.1.2") + _bgp_converge_initial("r3", "10.0.1.1") + _bgp_converge_initial("r3", "10.0.2.2") + _bgp_converge_initial("r4", "10.0.2.1") + + +def test_listening_address(): + """ + Checks if bgpd is only listening on the specified IP addresses. + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for router in tgen.routers().values(): + # bgpd must not be listening on the default address. + output = router.run("netstat -nlt4 | grep 0.0.0.0:179") + assert output == "", "{}: bpgd is listening on 0.0.0.0:179".format(router.name) + + # bgpd must be listening on the specified addresses. + for address in LISTEN_ADDRESSES[router.name]: + output = router.run("netstat -nlt4 | grep {}:179".format(address)) + assert output != "", "{}: bpgd is not listening on {}:179".format( + router.name, address + ) + + +def _bgp_converge_initial(router_name, peer_address, timeout=180): + """ + Waits for the BGP connection between a given router and a given peer + (specified by its IP address) to be established. If the connection is + not established within a given timeout, then an exception is raised. + """ + tgen = get_topogen() + router = tgen.routers()[router_name] + expected = {"ipv4Unicast": {"peers": {peer_address: {"state": "Established"}}}} + + test_func = partial(router_json_cmp, router, "show ip bgp summary json", expected) + _, result = run_and_expect(test_func, None, count=timeout, wait=1) + assert result is None, "{}: Failed to establish connection with {}".format( + router_name, peer_address + ) + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_peer-group/__init__.py b/tests/topotests/bgp_peer-group/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp_peer-group/__init__.py diff --git a/tests/topotests/bgp_peer-group/r1/bgpd.conf b/tests/topotests/bgp_peer-group/r1/bgpd.conf new file mode 100644 index 0000000000..19b490a359 --- /dev/null +++ b/tests/topotests/bgp_peer-group/r1/bgpd.conf @@ -0,0 +1,8 @@ +! +router bgp 65001 + neighbor PG peer-group + neighbor PG remote-as external + neighbor PG timers 3 10 + neighbor 192.168.255.3 peer-group PG + neighbor r1-eth0 interface peer-group PG +! diff --git a/tests/topotests/bgp_peer-group/r1/zebra.conf b/tests/topotests/bgp_peer-group/r1/zebra.conf new file mode 100644 index 0000000000..e2c399e536 --- /dev/null +++ b/tests/topotests/bgp_peer-group/r1/zebra.conf @@ -0,0 +1,6 @@ +! +interface r1-eth0 + ip address 192.168.255.1/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_peer-group/r2/bgpd.conf b/tests/topotests/bgp_peer-group/r2/bgpd.conf new file mode 100644 index 0000000000..0880ee9fae --- /dev/null +++ b/tests/topotests/bgp_peer-group/r2/bgpd.conf @@ -0,0 +1,7 @@ +! +router bgp 65002 + neighbor PG peer-group + neighbor PG remote-as external + neighbor PG timers 3 10 + neighbor r2-eth0 interface peer-group PG +! diff --git a/tests/topotests/bgp_peer-group/r2/zebra.conf b/tests/topotests/bgp_peer-group/r2/zebra.conf new file mode 100644 index 0000000000..606c17bec9 --- /dev/null +++ b/tests/topotests/bgp_peer-group/r2/zebra.conf @@ -0,0 +1,6 @@ +! +interface r2-eth0 + ip address 192.168.255.2/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_peer-group/r3/bgpd.conf b/tests/topotests/bgp_peer-group/r3/bgpd.conf new file mode 100644 index 0000000000..eb2fca15fb --- /dev/null +++ b/tests/topotests/bgp_peer-group/r3/bgpd.conf @@ -0,0 +1,7 @@ +! +router bgp 65003 + neighbor PG peer-group + neighbor PG remote-as external + neighbor PG timers 3 10 + neighbor 192.168.255.1 peer-group PG +! diff --git a/tests/topotests/bgp_peer-group/r3/zebra.conf b/tests/topotests/bgp_peer-group/r3/zebra.conf new file mode 100644 index 0000000000..e9fdfb70c5 --- /dev/null +++ b/tests/topotests/bgp_peer-group/r3/zebra.conf @@ -0,0 +1,6 @@ +! +interface r3-eth0 + ip address 192.168.255.3/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_peer-group/test_bgp_peer-group.py b/tests/topotests/bgp_peer-group/test_bgp_peer-group.py new file mode 100644 index 0000000000..7c7a8b87ed --- /dev/null +++ b/tests/topotests/bgp_peer-group/test_bgp_peer-group.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python + +# +# Copyright (c) 2021 by +# Donatas Abraitis <donatas.abraitis@gmail.com> +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +Test if peer-group works for numbered and unnumbered configurations. +""" + +import os +import sys +import json +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger +from mininet.topo import Topo + + +class TemplateTopo(Topo): + def build(self, *_args, **_opts): + tgen = get_topogen(self) + + for routern in range(1, 4): + tgen.add_router("r{}".format(routern)) + + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + switch.add_link(tgen.gears["r3"]) + + +def setup_module(mod): + tgen = Topogen(TemplateTopo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for i, (rname, router) in enumerate(router_list.items(), 1): + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) + ) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_peer_group(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + def _bgp_peer_group_configured(): + output = json.loads(tgen.gears["r1"].vtysh_cmd("show ip bgp neighbor json")) + expected = { + "r1-eth0": {"peerGroup": "PG", "bgpState": "Established"}, + "192.168.255.3": {"peerGroup": "PG", "bgpState": "Established"}, + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_peer_group_configured) + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + + assert result is None, 'Failed bgp convergence in "{}"'.format(tgen.gears["r1"]) + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/eigrp-topo1/test_eigrp_topo1.py b/tests/topotests/eigrp-topo1/test_eigrp_topo1.py index 3ce1472ac0..bf94d39a4b 100644 --- a/tests/topotests/eigrp-topo1/test_eigrp_topo1.py +++ b/tests/topotests/eigrp-topo1/test_eigrp_topo1.py @@ -91,7 +91,7 @@ class NetworkTopo(Topo): ## ##################################################### - +@pytest.mark.eigrp def setup_module(module): "Setup topology" tgen = Topogen(NetworkTopo, module.__name__) diff --git a/tests/topotests/evpn-pim-1/test_evpn_pim_topo1.py b/tests/topotests/evpn-pim-1/test_evpn_pim_topo1.py index 265124132f..07623af063 100644 --- a/tests/topotests/evpn-pim-1/test_evpn_pim_topo1.py +++ b/tests/topotests/evpn-pim-1/test_evpn_pim_topo1.py @@ -97,7 +97,7 @@ class NetworkTopo(Topo): ## ##################################################### - +@pytest.mark.pim def setup_module(module): "Setup topology" tgen = Topogen(NetworkTopo, module.__name__) diff --git a/tests/topotests/isis-lfa-topo1/test_isis_lfa_topo1.py b/tests/topotests/isis-lfa-topo1/test_isis_lfa_topo1.py index 6f80ffd1aa..a655b418cf 100755 --- a/tests/topotests/isis-lfa-topo1/test_isis_lfa_topo1.py +++ b/tests/topotests/isis-lfa-topo1/test_isis_lfa_topo1.py @@ -163,7 +163,7 @@ class TemplateTopo(Topo): f_in.close() f_out.close() - +@pytest.mark.isis def setup_module(mod): "Sets up the pytest environment" tgen = Topogen(TemplateTopo, mod.__name__) diff --git a/tests/topotests/isis-rlfa-topo1/__init__.py b/tests/topotests/isis-rlfa-topo1/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/__init__.py diff --git a/tests/topotests/isis-rlfa-topo1/rt1/isisd.conf b/tests/topotests/isis-rlfa-topo1/rt1/isisd.conf new file mode 100644 index 0000000000..a80f30dc7b --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/isisd.conf @@ -0,0 +1,39 @@ +password 1 +hostname rt1 +log file isisd.log +! +debug isis events +debug isis route-events +debug isis spf-events +debug isis lsp-gen +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-rt2 + ip router isis 1 + ipv6 router isis 1 + isis hello-multiplier 3 + isis network point-to-point + isis fast-reroute lfa + isis fast-reroute remote-lfa tunnel mpls-ldp +! +interface eth-rt3 + ip router isis 1 + ipv6 router isis 1 + isis hello-multiplier 3 + isis network point-to-point + isis fast-reroute lfa + isis fast-reroute remote-lfa tunnel mpls-ldp +! +ip prefix-list PLIST seq 5 permit 10.0.255.8/32 +! +router isis 1 + net 49.0000.0000.0000.0001.00 + is-type level-1-2 + lsp-gen-interval 2 + topology ipv6-unicast + fast-reroute remote-lfa prefix-list PLIST +! diff --git a/tests/topotests/isis-rlfa-topo1/rt1/ldpd.conf b/tests/topotests/isis-rlfa-topo1/rt1/ldpd.conf new file mode 100644 index 0000000000..f60fdb9742 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/ldpd.conf @@ -0,0 +1,30 @@ +log file ldpd.log +! +hostname rt1 +! +debug mpls ldp messages recv +debug mpls ldp messages sent +debug mpls ldp zebra +! +mpls ldp + router-id 10.0.255.1 + dual-stack transport-connection prefer ipv4 + ! + address-family ipv4 + label local allocate host-routes + discovery targeted-hello accept + discovery transport-address 10.0.255.1 + ! + interface eth-rt2 + interface eth-rt3 + ! + ! + address-family ipv6 + label local allocate host-routes + discovery transport-address 2001:db8::1 + ! + interface eth-rt2 + interface eth-rt3 + ! + ! +! diff --git a/tests/topotests/isis-rlfa-topo1/rt1/step1/show_ip_route.ref b/tests/topotests/isis-rlfa-topo1/rt1/step1/show_ip_route.ref new file mode 100644 index 0000000000..680b31eb8d --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/step1/show_ip_route.ref @@ -0,0 +1,235 @@ +{ + "10.0.255.2\/32":[ + { + "prefix":"10.0.255.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.255.2", + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, + "onLink":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.255.3", + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true, + "onLink":true, + "labels":"*" + } + ] + } + ], + "10.0.255.3\/32":[ + { + "prefix":"10.0.255.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.255.3", + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true, + "onLink":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.255.2", + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, + "onLink":true, + "labels":"*" + } + ] + } + ], + "10.0.255.4\/32":[ + { + "prefix":"10.0.255.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.255.2", + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, + "onLink":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.255.3", + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true, + "onLink":true, + "labels":"*" + } + ] + } + ], + "10.0.255.5\/32":[ + { + "prefix":"10.0.255.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.255.3", + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true, + "onLink":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.255.2", + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, + "onLink":true, + "labels":"*" + } + ] + } + ], + "10.0.255.6\/32":[ + { + "prefix":"10.0.255.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.255.2", + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, + "onLink":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.255.3", + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true, + "onLink":true, + "labels":"*" + } + ] + } + ], + "10.0.255.7\/32":[ + { + "prefix":"10.0.255.7\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.255.3", + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true, + "onLink":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.255.2", + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, + "onLink":true, + "labels":"*" + } + ] + } + ], + "10.0.255.8\/32":[ + { + "prefix":"10.0.255.8\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":50, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.255.2", + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, + "onLink":true + }, + { + "fib":true, + "ip":"10.0.255.3", + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true, + "onLink":true + } + ] + } + ] +} diff --git a/tests/topotests/isis-rlfa-topo1/rt1/step1/show_ipv6_route.ref b/tests/topotests/isis-rlfa-topo1/rt1/step1/show_ipv6_route.ref new file mode 100644 index 0000000000..c487d2740d --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/step1/show_ipv6_route.ref @@ -0,0 +1,207 @@ +{ + "2001:db8::2\/128":[ + { + "prefix":"2001:db8::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt3", + "active":true, + "labels":"*" + } + ] + } + ], + "2001:db8::3\/128":[ + { + "prefix":"2001:db8::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt2", + "active":true, + "labels":"*" + } + ] + } + ], + "2001:db8::4\/128":[ + { + "prefix":"2001:db8::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt3", + "active":true, + "labels":"*" + } + ] + } + ], + "2001:db8::5\/128":[ + { + "prefix":"2001:db8::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt2", + "active":true, + "labels":"*" + } + ] + } + ], + "2001:db8::6\/128":[ + { + "prefix":"2001:db8::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt3", + "active":true, + "labels":"*" + } + ] + } + ], + "2001:db8::7\/128":[ + { + "prefix":"2001:db8::7\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt2", + "active":true, + "labels":"*" + } + ] + } + ], + "2001:db8::8\/128":[ + { + "prefix":"2001:db8::8\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":50, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis-rlfa-topo1/rt1/step1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-rlfa-topo1/rt1/step1/show_yang_interface_isis_adjacencies.ref new file mode 100644 index 0000000000..3fe2b798a0 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/step1/show_yang_interface_isis_adjacencies.ref @@ -0,0 +1,44 @@ +{ + "frr-interface:lib": { + "interface": [ + { + "name": "eth-rt2", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1-2", + "neighbor-sysid": "0000.0000.0002", + "hold-timer": 9, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + }, + { + "name": "eth-rt3", + "vrf": "default", + "state": { + "frr-isisd:isis": { + "adjacencies": { + "adjacency": [ + { + "neighbor-sys-type": "level-1-2", + "neighbor-sysid": "0000.0000.0003", + "hold-timer": 9, + "neighbor-priority": 0, + "state": "up" + } + ] + } + } + } + } + ] + } +} diff --git a/tests/topotests/isis-rlfa-topo1/rt1/step10/show_ip_route.ref.diff b/tests/topotests/isis-rlfa-topo1/rt1/step10/show_ip_route.ref.diff new file mode 100644 index 0000000000..ef5707f14a --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/step10/show_ip_route.ref.diff @@ -0,0 +1,68 @@ +--- a/rt1/step9/show_ip_route.ref ++++ b/rt1/step10/show_ip_route.ref +@@ -15,7 +15,20 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, +- "onLink":true ++ "onLink":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.255.3", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt3", ++ "active":true, ++ "onLink":true, ++ "labels":"*" + } + ] + } +@@ -70,7 +83,20 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, +- "onLink":true ++ "onLink":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.255.3", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt3", ++ "active":true, ++ "onLink":true, ++ "labels":"*" + } + ] + } +@@ -125,7 +151,20 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, +- "onLink":true ++ "onLink":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.255.3", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt3", ++ "active":true, ++ "onLink":true, ++ "labels":"*" + } + ] + } diff --git a/tests/topotests/isis-rlfa-topo1/rt1/step10/show_ipv6_route.ref.diff b/tests/topotests/isis-rlfa-topo1/rt1/step10/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..acd2ce003a --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/step10/show_ipv6_route.ref.diff @@ -0,0 +1,62 @@ +--- a/rt1/step9/show_ipv6_route.ref ++++ b/rt1/step10/show_ipv6_route.ref +@@ -13,7 +13,18 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt3", ++ "active":true, ++ "labels":"*" + } + ] + } +@@ -62,7 +73,18 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt3", ++ "active":true, ++ "labels":"*" + } + ] + } +@@ -111,7 +133,18 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt3", ++ "active":true, ++ "labels":"*" + } + ] + } diff --git a/tests/topotests/isis-rlfa-topo1/rt1/step2/show_ip_route.ref.diff b/tests/topotests/isis-rlfa-topo1/rt1/step2/show_ip_route.ref.diff new file mode 100644 index 0000000000..f7f31ac021 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/step2/show_ip_route.ref.diff @@ -0,0 +1,134 @@ +--- a/rt1/step1/show_ip_route.ref ++++ b/rt1/step2/show_ip_route.ref +@@ -15,20 +15,7 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, +- "onLink":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.255.3", +- "afi":"ipv4", +- "interfaceName":"eth-rt3", +- "active":true, +- "onLink":true, +- "labels":"*" ++ "onLink":true + } + ] + } +@@ -49,20 +36,7 @@ + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true, +- "onLink":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.255.2", +- "afi":"ipv4", +- "interfaceName":"eth-rt2", +- "active":true, +- "onLink":true, +- "labels":"*" ++ "onLink":true + } + ] + } +@@ -83,20 +57,7 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, +- "onLink":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.255.3", +- "afi":"ipv4", +- "interfaceName":"eth-rt3", +- "active":true, +- "onLink":true, +- "labels":"*" ++ "onLink":true + } + ] + } +@@ -117,20 +78,7 @@ + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true, +- "onLink":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.255.2", +- "afi":"ipv4", +- "interfaceName":"eth-rt2", +- "active":true, +- "onLink":true, +- "labels":"*" ++ "onLink":true + } + ] + } +@@ -151,20 +99,7 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, +- "onLink":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.255.3", +- "afi":"ipv4", +- "interfaceName":"eth-rt3", +- "active":true, +- "onLink":true, +- "labels":"*" ++ "onLink":true + } + ] + } +@@ -185,20 +120,7 @@ + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true, +- "onLink":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.255.2", +- "afi":"ipv4", +- "interfaceName":"eth-rt2", +- "active":true, +- "onLink":true, +- "labels":"*" ++ "onLink":true + } + ] + } diff --git a/tests/topotests/isis-rlfa-topo1/rt1/step2/show_ipv6_route.ref.diff b/tests/topotests/isis-rlfa-topo1/rt1/step2/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..e980031ad7 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/step2/show_ipv6_route.ref.diff @@ -0,0 +1,122 @@ +--- a/rt1/step1/show_ipv6_route.ref ++++ b/rt1/step2/show_ipv6_route.ref +@@ -13,18 +13,7 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt3", +- "active":true, +- "labels":"*" ++ "active":true + } + ] + } +@@ -43,18 +32,7 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt2", +- "active":true, +- "labels":"*" ++ "active":true + } + ] + } +@@ -73,18 +51,7 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt3", +- "active":true, +- "labels":"*" ++ "active":true + } + ] + } +@@ -103,18 +70,7 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt2", +- "active":true, +- "labels":"*" ++ "active":true + } + ] + } +@@ -133,18 +89,7 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt3", +- "active":true, +- "labels":"*" ++ "active":true + } + ] + } +@@ -163,18 +108,7 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt2", +- "active":true, +- "labels":"*" ++ "active":true + } + ] + } diff --git a/tests/topotests/isis-rlfa-topo1/rt1/step3/show_ip_route.ref.diff b/tests/topotests/isis-rlfa-topo1/rt1/step3/show_ip_route.ref.diff new file mode 100644 index 0000000000..f3ed764f0b --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/step3/show_ip_route.ref.diff @@ -0,0 +1,134 @@ +--- a/rt1/step2/show_ip_route.ref ++++ b/rt1/step3/show_ip_route.ref +@@ -15,7 +15,20 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, +- "onLink":true ++ "onLink":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.255.3", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt3", ++ "active":true, ++ "onLink":true, ++ "labels":"*" + } + ] + } +@@ -36,7 +49,20 @@ + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true, +- "onLink":true ++ "onLink":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.255.2", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt2", ++ "active":true, ++ "onLink":true, ++ "labels":"*" + } + ] + } +@@ -57,7 +83,20 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, +- "onLink":true ++ "onLink":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.255.3", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt3", ++ "active":true, ++ "onLink":true, ++ "labels":"*" + } + ] + } +@@ -78,7 +117,20 @@ + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true, +- "onLink":true ++ "onLink":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.255.2", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt2", ++ "active":true, ++ "onLink":true, ++ "labels":"*" + } + ] + } +@@ -99,7 +151,20 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, +- "onLink":true ++ "onLink":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.255.3", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt3", ++ "active":true, ++ "onLink":true, ++ "labels":"*" + } + ] + } +@@ -120,7 +185,20 @@ + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true, +- "onLink":true ++ "onLink":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.255.2", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt2", ++ "active":true, ++ "onLink":true, ++ "labels":"*" + } + ] + } diff --git a/tests/topotests/isis-rlfa-topo1/rt1/step3/show_ipv6_route.ref.diff b/tests/topotests/isis-rlfa-topo1/rt1/step3/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..57b0b1de1a --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/step3/show_ipv6_route.ref.diff @@ -0,0 +1,122 @@ +--- a/rt1/step2/show_ipv6_route.ref ++++ b/rt1/step3/show_ipv6_route.ref +@@ -13,7 +13,18 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt3", ++ "active":true, ++ "labels":"*" + } + ] + } +@@ -32,7 +43,18 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt2", ++ "active":true, ++ "labels":"*" + } + ] + } +@@ -51,7 +73,18 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt3", ++ "active":true, ++ "labels":"*" + } + ] + } +@@ -70,7 +103,18 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt2", ++ "active":true, ++ "labels":"*" + } + ] + } +@@ -89,7 +133,18 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt3", ++ "active":true, ++ "labels":"*" + } + ] + } +@@ -108,7 +163,18 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt2", ++ "active":true, ++ "labels":"*" + } + ] + } diff --git a/tests/topotests/isis-rlfa-topo1/rt1/step4/show_ip_route.ref.diff b/tests/topotests/isis-rlfa-topo1/rt1/step4/show_ip_route.ref.diff new file mode 100644 index 0000000000..107a0ba2f7 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/step4/show_ip_route.ref.diff @@ -0,0 +1,68 @@ +--- a/rt1/step3/show_ip_route.ref ++++ b/rt1/step4/show_ip_route.ref +@@ -15,20 +15,7 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, +- "onLink":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.255.3", +- "afi":"ipv4", +- "interfaceName":"eth-rt3", +- "active":true, +- "onLink":true, +- "labels":"*" ++ "onLink":true + } + ] + } +@@ -83,20 +70,7 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, +- "onLink":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.255.3", +- "afi":"ipv4", +- "interfaceName":"eth-rt3", +- "active":true, +- "onLink":true, +- "labels":"*" ++ "onLink":true + } + ] + } +@@ -151,20 +125,7 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, +- "onLink":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.255.3", +- "afi":"ipv4", +- "interfaceName":"eth-rt3", +- "active":true, +- "onLink":true, +- "labels":"*" ++ "onLink":true + } + ] + } diff --git a/tests/topotests/isis-rlfa-topo1/rt1/step4/show_ipv6_route.ref.diff b/tests/topotests/isis-rlfa-topo1/rt1/step4/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..9cf24082e1 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/step4/show_ipv6_route.ref.diff @@ -0,0 +1,62 @@ +--- a/rt1/step3/show_ipv6_route.ref ++++ b/rt1/step4/show_ipv6_route.ref +@@ -13,18 +13,7 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt3", +- "active":true, +- "labels":"*" ++ "active":true + } + ] + } +@@ -73,18 +62,7 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt3", +- "active":true, +- "labels":"*" ++ "active":true + } + ] + } +@@ -133,18 +111,7 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt3", +- "active":true, +- "labels":"*" ++ "active":true + } + ] + } diff --git a/tests/topotests/isis-rlfa-topo1/rt1/step5/show_ip_route.ref.diff b/tests/topotests/isis-rlfa-topo1/rt1/step5/show_ip_route.ref.diff new file mode 100644 index 0000000000..09469501f5 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/step5/show_ip_route.ref.diff @@ -0,0 +1,68 @@ +--- a/rt1/step4/show_ip_route.ref ++++ b/rt1/step5/show_ip_route.ref +@@ -36,20 +36,7 @@ + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true, +- "onLink":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.255.2", +- "afi":"ipv4", +- "interfaceName":"eth-rt2", +- "active":true, +- "onLink":true, +- "labels":"*" ++ "onLink":true + } + ] + } +@@ -91,20 +78,7 @@ + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true, +- "onLink":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.255.2", +- "afi":"ipv4", +- "interfaceName":"eth-rt2", +- "active":true, +- "onLink":true, +- "labels":"*" ++ "onLink":true + } + ] + } +@@ -146,20 +120,7 @@ + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true, +- "onLink":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.255.2", +- "afi":"ipv4", +- "interfaceName":"eth-rt2", +- "active":true, +- "onLink":true, +- "labels":"*" ++ "onLink":true + } + ] + } diff --git a/tests/topotests/isis-rlfa-topo1/rt1/step5/show_ipv6_route.ref.diff b/tests/topotests/isis-rlfa-topo1/rt1/step5/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..70fb1a65c7 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/step5/show_ipv6_route.ref.diff @@ -0,0 +1,62 @@ +--- a/rt1/step4/show_ipv6_route.ref ++++ b/rt1/step5/show_ipv6_route.ref +@@ -32,18 +32,7 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt2", +- "active":true, +- "labels":"*" ++ "active":true + } + ] + } +@@ -81,18 +70,7 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt2", +- "active":true, +- "labels":"*" ++ "active":true + } + ] + } +@@ -130,18 +108,7 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt2", +- "active":true, +- "labels":"*" ++ "active":true + } + ] + } diff --git a/tests/topotests/isis-rlfa-topo1/rt1/step6/show_ip_route.ref.diff b/tests/topotests/isis-rlfa-topo1/rt1/step6/show_ip_route.ref.diff new file mode 100644 index 0000000000..4e4a5692a4 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/step6/show_ip_route.ref.diff @@ -0,0 +1,134 @@ +--- a/rt1/step5/show_ip_route.ref ++++ b/rt1/step6/show_ip_route.ref +@@ -15,7 +15,20 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, +- "onLink":true ++ "onLink":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.255.3", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt3", ++ "active":true, ++ "onLink":true, ++ "labels":"*" + } + ] + } +@@ -36,7 +49,20 @@ + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true, +- "onLink":true ++ "onLink":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.255.2", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt2", ++ "active":true, ++ "onLink":true, ++ "labels":"*" + } + ] + } +@@ -57,7 +83,20 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, +- "onLink":true ++ "onLink":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.255.3", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt3", ++ "active":true, ++ "onLink":true, ++ "labels":"*" + } + ] + } +@@ -78,7 +117,20 @@ + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true, +- "onLink":true ++ "onLink":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.255.2", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt2", ++ "active":true, ++ "onLink":true, ++ "labels":"*" + } + ] + } +@@ -99,7 +151,20 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, +- "onLink":true ++ "onLink":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.255.3", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt3", ++ "active":true, ++ "onLink":true, ++ "labels":"*" + } + ] + } +@@ -120,7 +185,20 @@ + "afi":"ipv4", + "interfaceName":"eth-rt3", + "active":true, +- "onLink":true ++ "onLink":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "ip":"10.0.255.2", ++ "afi":"ipv4", ++ "interfaceName":"eth-rt2", ++ "active":true, ++ "onLink":true, ++ "labels":"*" + } + ] + } diff --git a/tests/topotests/isis-rlfa-topo1/rt1/step6/show_ipv6_route.ref.diff b/tests/topotests/isis-rlfa-topo1/rt1/step6/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..c9ebb1e3f5 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/step6/show_ipv6_route.ref.diff @@ -0,0 +1,122 @@ +--- a/rt1/step5/show_ipv6_route.ref ++++ b/rt1/step6/show_ipv6_route.ref +@@ -13,7 +13,18 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt3", ++ "active":true, ++ "labels":"*" + } + ] + } +@@ -32,7 +43,18 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt2", ++ "active":true, ++ "labels":"*" + } + ] + } +@@ -51,7 +73,18 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt3", ++ "active":true, ++ "labels":"*" + } + ] + } +@@ -70,7 +103,18 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt2", ++ "active":true, ++ "labels":"*" + } + ] + } +@@ -89,7 +133,18 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt3", ++ "active":true, ++ "labels":"*" + } + ] + } +@@ -108,7 +163,18 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3", +- "active":true ++ "active":true, ++ "backupIndex":[ ++ 0 ++ ] ++ } ++ ], ++ "backupNexthops":[ ++ { ++ "afi":"ipv6", ++ "interfaceName":"eth-rt2", ++ "active":true, ++ "labels":"*" + } + ] + } diff --git a/tests/topotests/isis-rlfa-topo1/rt1/step7/show_ip_route.ref.diff b/tests/topotests/isis-rlfa-topo1/rt1/step7/show_ip_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/step7/show_ip_route.ref.diff diff --git a/tests/topotests/isis-rlfa-topo1/rt1/step7/show_ipv6_route.ref.diff b/tests/topotests/isis-rlfa-topo1/rt1/step7/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/step7/show_ipv6_route.ref.diff diff --git a/tests/topotests/isis-rlfa-topo1/rt1/step8/show_ip_route.ref.diff b/tests/topotests/isis-rlfa-topo1/rt1/step8/show_ip_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/step8/show_ip_route.ref.diff diff --git a/tests/topotests/isis-rlfa-topo1/rt1/step8/show_ipv6_route.ref.diff b/tests/topotests/isis-rlfa-topo1/rt1/step8/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/step8/show_ipv6_route.ref.diff diff --git a/tests/topotests/isis-rlfa-topo1/rt1/step9/show_ip_route.ref.diff b/tests/topotests/isis-rlfa-topo1/rt1/step9/show_ip_route.ref.diff new file mode 100644 index 0000000000..33eb6577bd --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/step9/show_ip_route.ref.diff @@ -0,0 +1,68 @@ +--- a/rt1/step8/show_ip_route.ref ++++ b/rt1/step9/show_ip_route.ref +@@ -15,20 +15,7 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, +- "onLink":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.255.3", +- "afi":"ipv4", +- "interfaceName":"eth-rt3", +- "active":true, +- "onLink":true, +- "labels":"*" ++ "onLink":true + } + ] + } +@@ -83,20 +70,7 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, +- "onLink":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.255.3", +- "afi":"ipv4", +- "interfaceName":"eth-rt3", +- "active":true, +- "onLink":true, +- "labels":"*" ++ "onLink":true + } + ] + } +@@ -151,20 +125,7 @@ + "afi":"ipv4", + "interfaceName":"eth-rt2", + "active":true, +- "onLink":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "ip":"10.0.255.3", +- "afi":"ipv4", +- "interfaceName":"eth-rt3", +- "active":true, +- "onLink":true, +- "labels":"*" ++ "onLink":true + } + ] + } diff --git a/tests/topotests/isis-rlfa-topo1/rt1/step9/show_ipv6_route.ref.diff b/tests/topotests/isis-rlfa-topo1/rt1/step9/show_ipv6_route.ref.diff new file mode 100644 index 0000000000..7aaca3354e --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/step9/show_ipv6_route.ref.diff @@ -0,0 +1,62 @@ +--- a/rt1/step8/show_ipv6_route.ref ++++ b/rt1/step9/show_ipv6_route.ref +@@ -13,18 +13,7 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt3", +- "active":true, +- "labels":"*" ++ "active":true + } + ] + } +@@ -73,18 +62,7 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt3", +- "active":true, +- "labels":"*" ++ "active":true + } + ] + } +@@ -133,18 +111,7 @@ + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2", +- "active":true, +- "backupIndex":[ +- 0 +- ] +- } +- ], +- "backupNexthops":[ +- { +- "afi":"ipv6", +- "interfaceName":"eth-rt3", +- "active":true, +- "labels":"*" ++ "active":true + } + ] + } diff --git a/tests/topotests/isis-rlfa-topo1/rt1/zebra.conf b/tests/topotests/isis-rlfa-topo1/rt1/zebra.conf new file mode 100644 index 0000000000..741fc2d02b --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt1/zebra.conf @@ -0,0 +1,22 @@ +log file zebra.log +! +hostname rt1 +! +debug zebra kernel +debug zebra packet +debug zebra mpls +! +interface lo + ip address 10.0.255.1/32 + ipv6 address 2001:db8::1/128 +! +interface eth-rt2 + ip address 10.0.255.1/32 +! +interface eth-rt3 + ip address 10.0.255.1/32 +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/isis-rlfa-topo1/rt2/isisd.conf b/tests/topotests/isis-rlfa-topo1/rt2/isisd.conf new file mode 100644 index 0000000000..7b4c6c50b9 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt2/isisd.conf @@ -0,0 +1,32 @@ +password 1 +hostname rt2 +log file isisd.log +! +debug isis events +debug isis route-events +debug isis spf-events +debug isis lsp-gen +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-rt1 + ip router isis 1 + ipv6 router isis 1 + isis hello-multiplier 3 + isis network point-to-point +! +interface eth-rt4 + ip router isis 1 + ipv6 router isis 1 + isis hello-multiplier 3 + isis network point-to-point +! +router isis 1 + net 49.0000.0000.0000.0002.00 + is-type level-1-2 + lsp-gen-interval 2 + topology ipv6-unicast +! diff --git a/tests/topotests/isis-rlfa-topo1/rt2/ldpd.conf b/tests/topotests/isis-rlfa-topo1/rt2/ldpd.conf new file mode 100644 index 0000000000..0a815ef004 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt2/ldpd.conf @@ -0,0 +1,30 @@ +log file ldpd.log +! +hostname rt2 +! +debug mpls ldp messages recv +debug mpls ldp messages sent +debug mpls ldp zebra +! +mpls ldp + router-id 10.0.255.2 + dual-stack transport-connection prefer ipv4 + ! + address-family ipv4 + label local allocate host-routes + discovery targeted-hello accept + discovery transport-address 10.0.255.2 + ! + interface eth-rt1 + interface eth-rt4 + ! + ! + address-family ipv6 + label local allocate host-routes + discovery transport-address 2001:db8::2 + ! + interface eth-rt1 + interface eth-rt4 + ! + ! +! diff --git a/tests/topotests/isis-rlfa-topo1/rt2/zebra.conf b/tests/topotests/isis-rlfa-topo1/rt2/zebra.conf new file mode 100644 index 0000000000..657c69bf28 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt2/zebra.conf @@ -0,0 +1,22 @@ +log file zebra.log +! +hostname rt2 +! +debug zebra kernel +debug zebra packet +debug zebra mpls +! +interface lo + ip address 10.0.255.2/32 + ipv6 address 2001:db8::2/128 +! +interface eth-rt1 + ip address 10.0.255.2/32 +! +interface eth-rt4 + ip address 10.0.255.2/32 +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/isis-rlfa-topo1/rt3/isisd.conf b/tests/topotests/isis-rlfa-topo1/rt3/isisd.conf new file mode 100644 index 0000000000..17d58a9d15 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt3/isisd.conf @@ -0,0 +1,32 @@ +password 1 +hostname rt3 +log file isisd.log +! +debug isis events +debug isis route-events +debug isis spf-events +debug isis lsp-gen +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-rt1 + ip router isis 1 + ipv6 router isis 1 + isis hello-multiplier 3 + isis network point-to-point +! +interface eth-rt5 + ip router isis 1 + ipv6 router isis 1 + isis hello-multiplier 3 + isis network point-to-point +! +router isis 1 + net 49.0000.0000.0000.0003.00 + is-type level-1-2 + lsp-gen-interval 2 + topology ipv6-unicast +! diff --git a/tests/topotests/isis-rlfa-topo1/rt3/ldpd.conf b/tests/topotests/isis-rlfa-topo1/rt3/ldpd.conf new file mode 100644 index 0000000000..40f1f5587a --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt3/ldpd.conf @@ -0,0 +1,30 @@ +log file ldpd.log +! +hostname rt3 +! +debug mpls ldp messages recv +debug mpls ldp messages sent +debug mpls ldp zebra +! +mpls ldp + router-id 10.0.255.3 + dual-stack transport-connection prefer ipv4 + ! + address-family ipv4 + label local allocate host-routes + discovery targeted-hello accept + discovery transport-address 10.0.255.3 + ! + interface eth-rt1 + interface eth-rt5 + ! + ! + address-family ipv6 + label local allocate host-routes + discovery transport-address 2001:db8::3 + ! + interface eth-rt1 + interface eth-rt5 + ! + ! +! diff --git a/tests/topotests/isis-rlfa-topo1/rt3/zebra.conf b/tests/topotests/isis-rlfa-topo1/rt3/zebra.conf new file mode 100644 index 0000000000..86f5d2871a --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt3/zebra.conf @@ -0,0 +1,22 @@ +log file zebra.log +! +hostname rt3 +! +debug zebra kernel +debug zebra packet +debug zebra mpls +! +interface lo + ip address 10.0.255.3/32 + ipv6 address 2001:db8::3/128 +! +interface eth-rt1 + ip address 10.0.255.3/32 +! +interface eth-rt5 + ip address 10.0.255.3/32 +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/isis-rlfa-topo1/rt4/isisd.conf b/tests/topotests/isis-rlfa-topo1/rt4/isisd.conf new file mode 100644 index 0000000000..1519fd4c16 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt4/isisd.conf @@ -0,0 +1,32 @@ +password 1 +hostname rt4 +log file isisd.log +! +debug isis events +debug isis route-events +debug isis spf-events +debug isis lsp-gen +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-rt2 + ip router isis 1 + ipv6 router isis 1 + isis hello-multiplier 3 + isis network point-to-point +! +interface eth-rt6 + ip router isis 1 + ipv6 router isis 1 + isis hello-multiplier 3 + isis network point-to-point +! +router isis 1 + net 49.0000.0000.0000.0004.00 + is-type level-1-2 + lsp-gen-interval 2 + topology ipv6-unicast +! diff --git a/tests/topotests/isis-rlfa-topo1/rt4/ldpd.conf b/tests/topotests/isis-rlfa-topo1/rt4/ldpd.conf new file mode 100644 index 0000000000..569ecf733e --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt4/ldpd.conf @@ -0,0 +1,30 @@ +log file ldpd.log +! +hostname rt4 +! +debug mpls ldp messages recv +debug mpls ldp messages sent +debug mpls ldp zebra +! +mpls ldp + router-id 10.0.255.4 + dual-stack transport-connection prefer ipv4 + ! + address-family ipv4 + label local allocate host-routes + discovery targeted-hello accept + discovery transport-address 10.0.255.4 + ! + interface eth-rt2 + interface eth-rt6 + ! + ! + address-family ipv6 + label local allocate host-routes + discovery transport-address 2001:db8::4 + ! + interface eth-rt2 + interface eth-rt6 + ! + ! +! diff --git a/tests/topotests/isis-rlfa-topo1/rt4/zebra.conf b/tests/topotests/isis-rlfa-topo1/rt4/zebra.conf new file mode 100644 index 0000000000..1dd09bf83b --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt4/zebra.conf @@ -0,0 +1,22 @@ +log file zebra.log +! +hostname rt4 +! +debug zebra kernel +debug zebra packet +debug zebra mpls +! +interface lo + ip address 10.0.255.4/32 + ipv6 address 2001:db8::4/128 +! +interface eth-rt2 + ip address 10.0.255.4/32 +! +interface eth-rt6 + ip address 10.0.255.4/32 +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/isis-rlfa-topo1/rt5/isisd.conf b/tests/topotests/isis-rlfa-topo1/rt5/isisd.conf new file mode 100644 index 0000000000..caf7477073 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt5/isisd.conf @@ -0,0 +1,32 @@ +password 1 +hostname rt5 +log file isisd.log +! +debug isis events +debug isis route-events +debug isis spf-events +debug isis lsp-gen +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-rt3 + ip router isis 1 + ipv6 router isis 1 + isis hello-multiplier 3 + isis network point-to-point +! +interface eth-rt7 + ip router isis 1 + ipv6 router isis 1 + isis hello-multiplier 3 + isis network point-to-point +! +router isis 1 + net 49.0000.0000.0000.0005.00 + is-type level-1-2 + lsp-gen-interval 2 + topology ipv6-unicast +! diff --git a/tests/topotests/isis-rlfa-topo1/rt5/ldpd.conf b/tests/topotests/isis-rlfa-topo1/rt5/ldpd.conf new file mode 100644 index 0000000000..519c3d3628 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt5/ldpd.conf @@ -0,0 +1,30 @@ +log file ldpd.log +! +hostname rt5 +! +debug mpls ldp messages recv +debug mpls ldp messages sent +debug mpls ldp zebra +! +mpls ldp + router-id 10.0.255.5 + dual-stack transport-connection prefer ipv4 + ! + address-family ipv4 + label local allocate host-routes + discovery targeted-hello accept + discovery transport-address 10.0.255.5 + ! + interface eth-rt3 + interface eth-rt7 + ! + ! + address-family ipv6 + label local allocate host-routes + discovery transport-address 2001:db8::5 + ! + interface eth-rt3 + interface eth-rt7 + ! + ! +! diff --git a/tests/topotests/isis-rlfa-topo1/rt5/zebra.conf b/tests/topotests/isis-rlfa-topo1/rt5/zebra.conf new file mode 100644 index 0000000000..7117a2a2e3 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt5/zebra.conf @@ -0,0 +1,22 @@ +log file zebra.log +! +hostname rt5 +! +debug zebra kernel +debug zebra packet +debug zebra mpls +! +interface lo + ip address 10.0.255.5/32 + ipv6 address 2001:db8::5/128 +! +interface eth-rt3 + ip address 10.0.255.5/32 +! +interface eth-rt7 + ip address 10.0.255.5/32 +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/isis-rlfa-topo1/rt6/isisd.conf b/tests/topotests/isis-rlfa-topo1/rt6/isisd.conf new file mode 100644 index 0000000000..cdf6267236 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt6/isisd.conf @@ -0,0 +1,32 @@ +password 1 +hostname rt6 +log file isisd.log +! +debug isis events +debug isis route-events +debug isis spf-events +debug isis lsp-gen +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-rt4 + ip router isis 1 + ipv6 router isis 1 + isis hello-multiplier 3 + isis network point-to-point +! +interface eth-rt8 + ip router isis 1 + ipv6 router isis 1 + isis hello-multiplier 3 + isis network point-to-point +! +router isis 1 + net 49.0000.0000.0000.0006.00 + is-type level-1-2 + lsp-gen-interval 2 + topology ipv6-unicast +! diff --git a/tests/topotests/isis-rlfa-topo1/rt6/ldpd.conf b/tests/topotests/isis-rlfa-topo1/rt6/ldpd.conf new file mode 100644 index 0000000000..a5b7062bec --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt6/ldpd.conf @@ -0,0 +1,30 @@ +log file ldpd.log +! +hostname rt6 +! +debug mpls ldp messages recv +debug mpls ldp messages sent +debug mpls ldp zebra +! +mpls ldp + router-id 10.0.255.6 + dual-stack transport-connection prefer ipv4 + ! + address-family ipv4 + label local allocate host-routes + discovery targeted-hello accept + discovery transport-address 10.0.255.6 + ! + interface eth-rt4 + interface eth-rt8 + ! + ! + address-family ipv6 + label local allocate host-routes + discovery transport-address 2001:db8::6 + ! + interface eth-rt4 + interface eth-rt8 + ! + ! +! diff --git a/tests/topotests/isis-rlfa-topo1/rt6/zebra.conf b/tests/topotests/isis-rlfa-topo1/rt6/zebra.conf new file mode 100644 index 0000000000..c6344870b7 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt6/zebra.conf @@ -0,0 +1,22 @@ +log file zebra.log +! +hostname rt6 +! +debug zebra kernel +debug zebra packet +debug zebra mpls +! +interface lo + ip address 10.0.255.6/32 + ipv6 address 2001:db8::6/128 +! +interface eth-rt4 + ip address 10.0.255.6/32 +! +interface eth-rt8 + ip address 10.0.255.6/32 +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/isis-rlfa-topo1/rt7/isisd.conf b/tests/topotests/isis-rlfa-topo1/rt7/isisd.conf new file mode 100644 index 0000000000..8ab8fcb232 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt7/isisd.conf @@ -0,0 +1,32 @@ +password 1 +hostname rt7 +log file isisd.log +! +debug isis events +debug isis route-events +debug isis spf-events +debug isis lsp-gen +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-rt5 + ip router isis 1 + ipv6 router isis 1 + isis hello-multiplier 3 + isis network point-to-point +! +interface eth-rt8 + ip router isis 1 + ipv6 router isis 1 + isis hello-multiplier 3 + isis network point-to-point +! +router isis 1 + net 49.0000.0000.0000.0007.00 + is-type level-1-2 + lsp-gen-interval 2 + topology ipv6-unicast +! diff --git a/tests/topotests/isis-rlfa-topo1/rt7/ldpd.conf b/tests/topotests/isis-rlfa-topo1/rt7/ldpd.conf new file mode 100644 index 0000000000..26d428c4c6 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt7/ldpd.conf @@ -0,0 +1,30 @@ +log file ldpd.log +! +hostname rt7 +! +debug mpls ldp messages recv +debug mpls ldp messages sent +debug mpls ldp zebra +! +mpls ldp + router-id 10.0.255.7 + dual-stack transport-connection prefer ipv4 + ! + address-family ipv4 + label local allocate host-routes + discovery targeted-hello accept + discovery transport-address 10.0.255.7 + ! + interface eth-rt5 + interface eth-rt8 + ! + ! + address-family ipv6 + label local allocate host-routes + discovery transport-address 2001:db8::7 + ! + interface eth-rt5 + interface eth-rt8 + ! + ! +! diff --git a/tests/topotests/isis-rlfa-topo1/rt7/zebra.conf b/tests/topotests/isis-rlfa-topo1/rt7/zebra.conf new file mode 100644 index 0000000000..4c5e0f1126 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt7/zebra.conf @@ -0,0 +1,22 @@ +log file zebra.log +! +hostname rt7 +! +debug zebra kernel +debug zebra packet +debug zebra mpls +! +interface lo + ip address 10.0.255.7/32 + ipv6 address 2001:db8::7/128 +! +interface eth-rt5 + ip address 10.0.255.7/32 +! +interface eth-rt8 + ip address 10.0.255.7/32 +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/isis-rlfa-topo1/rt8/isisd.conf b/tests/topotests/isis-rlfa-topo1/rt8/isisd.conf new file mode 100644 index 0000000000..abdc6a53a5 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt8/isisd.conf @@ -0,0 +1,32 @@ +password 1 +hostname rt8 +log file isisd.log +! +debug isis events +debug isis route-events +debug isis spf-events +debug isis lsp-gen +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-rt6 + ip router isis 1 + ipv6 router isis 1 + isis hello-multiplier 3 + isis network point-to-point +! +interface eth-rt7 + ip router isis 1 + ipv6 router isis 1 + isis hello-multiplier 3 + isis network point-to-point +! +router isis 1 + net 49.0000.0000.0000.0008.00 + is-type level-1-2 + lsp-gen-interval 2 + topology ipv6-unicast +! diff --git a/tests/topotests/isis-rlfa-topo1/rt8/ldpd.conf b/tests/topotests/isis-rlfa-topo1/rt8/ldpd.conf new file mode 100644 index 0000000000..1629f82de1 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt8/ldpd.conf @@ -0,0 +1,30 @@ +log file ldpd.log +! +hostname rt8 +! +debug mpls ldp messages recv +debug mpls ldp messages sent +debug mpls ldp zebra +! +mpls ldp + router-id 10.0.255.8 + dual-stack transport-connection prefer ipv4 + ! + address-family ipv4 + label local allocate host-routes + discovery targeted-hello accept + discovery transport-address 10.0.255.8 + ! + interface eth-rt6 + interface eth-rt7 + ! + ! + address-family ipv6 + label local allocate host-routes + discovery transport-address 2001:db8::8 + ! + interface eth-rt6 + interface eth-rt7 + ! + ! +! diff --git a/tests/topotests/isis-rlfa-topo1/rt8/zebra.conf b/tests/topotests/isis-rlfa-topo1/rt8/zebra.conf new file mode 100644 index 0000000000..f3f10f649a --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/rt8/zebra.conf @@ -0,0 +1,22 @@ +log file zebra.log +! +hostname rt8 +! +debug zebra kernel +debug zebra packet +debug zebra mpls +! +interface lo + ip address 10.0.255.8/32 + ipv6 address 2001:db8::8/128 +! +interface eth-rt6 + ip address 10.0.255.8/32 +! +interface eth-rt7 + ip address 10.0.255.8/32 +! +ip forwarding +! +line vty +! diff --git a/tests/topotests/isis-rlfa-topo1/test_isis_rlfa_topo1.py b/tests/topotests/isis-rlfa-topo1/test_isis_rlfa_topo1.py new file mode 100755 index 0000000000..bb43e6b114 --- /dev/null +++ b/tests/topotests/isis-rlfa-topo1/test_isis_rlfa_topo1.py @@ -0,0 +1,662 @@ +#!/usr/bin/env python + +# +# test_isis_rlfa_topo1.py +# Part of NetDEF Topology Tests +# +# Copyright (c) 2020 by +# Network Device Education Foundation, Inc. ("NetDEF") +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +test_isis_rlfa_topo1.py: + + +---------+ +---------+ + | | | | + | RT1 | | RT2 | + | +---------------------+ | + | | | | + +---+-----+ +------+--+ + | | + | | + | | + +---+-----+ +------+--+ + | | | | + | RT3 | | RT4 | + | | | | + | | | | + +---+-----+ +------+--+ + | | + | | + | | + +---+-----+ +------+--+ + | | | | + | RT5 | | RT6 | + | | | | + | | | | + +---+-----+ +------+--+ + | | + | | + | | + +---+-----+ +------+--+ + | | | | + | RT7 | | RT8 | + | +---------------------+ | + | | | | + +---------+ +---------+ +""" + +import os +import sys +import pytest +import json +import re +import tempfile +from time import sleep +from functools import partial + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger + +# Required to instantiate the topology builder class. +from mininet.topo import Topo + +# Global multi-dimensional dictionary containing all expected outputs +outputs = {} + + +class TemplateTopo(Topo): + "Test topology builder" + + def build(self, *_args, **_opts): + "Build function" + tgen = get_topogen(self) + + # + # Define FRR Routers + # + for router in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6", "rt7", "rt8"]: + tgen.add_router(router) + + # + # Define connections + # + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["rt1"], nodeif="eth-rt2") + switch.add_link(tgen.gears["rt2"], nodeif="eth-rt1") + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["rt1"], nodeif="eth-rt3") + switch.add_link(tgen.gears["rt3"], nodeif="eth-rt1") + switch = tgen.add_switch("s3") + switch.add_link(tgen.gears["rt2"], nodeif="eth-rt4") + switch.add_link(tgen.gears["rt4"], nodeif="eth-rt2") + switch = tgen.add_switch("s4") + switch.add_link(tgen.gears["rt3"], nodeif="eth-rt5") + switch.add_link(tgen.gears["rt5"], nodeif="eth-rt3") + switch = tgen.add_switch("s5") + switch.add_link(tgen.gears["rt4"], nodeif="eth-rt6") + switch.add_link(tgen.gears["rt6"], nodeif="eth-rt4") + switch = tgen.add_switch("s6") + switch.add_link(tgen.gears["rt5"], nodeif="eth-rt7") + switch.add_link(tgen.gears["rt7"], nodeif="eth-rt5") + switch = tgen.add_switch("s7") + switch.add_link(tgen.gears["rt6"], nodeif="eth-rt8") + switch.add_link(tgen.gears["rt8"], nodeif="eth-rt6") + switch = tgen.add_switch("s8") + switch.add_link(tgen.gears["rt7"], nodeif="eth-rt8") + switch.add_link(tgen.gears["rt8"], nodeif="eth-rt7") + + # + # Populate multi-dimensional dictionary containing all expected outputs + # + files = [ + "show_ip_route.ref", + "show_ipv6_route.ref", + "show_yang_interface_isis_adjacencies.ref", + ] + for rname in ["rt1"]: + outputs[rname] = {} + for step in range(1, 10 + 1): + outputs[rname][step] = {} + for file in files: + if step == 1: + # Get snapshots relative to the expected initial network convergence + filename = "{}/{}/step{}/{}".format(CWD, rname, step, file) + outputs[rname][step][file] = open(filename).read() + else: + if file == "show_yang_interface_isis_adjacencies.ref": + continue + + # Get diff relative to the previous step + filename = "{}/{}/step{}/{}.diff".format(CWD, rname, step, file) + + # Create temporary files in order to apply the diff + f_in = tempfile.NamedTemporaryFile() + f_in.write(outputs[rname][step - 1][file]) + f_in.flush() + f_out = tempfile.NamedTemporaryFile() + os.system( + "patch -s -o %s %s %s" % (f_out.name, f_in.name, filename) + ) + + # Store the updated snapshot and remove the temporary files + outputs[rname][step][file] = open(f_out.name).read() + f_in.close() + f_out.close() + +@pytest.mark.isis +def setup_module(mod): + "Sets up the pytest environment" + tgen = Topogen(TemplateTopo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + # For all registered routers, load the zebra configuration file + for rname, router in router_list.iteritems(): + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_LDP, os.path.join(CWD, "{}/ldpd.conf".format(rname)) + ) + + tgen.start_router() + + +def teardown_module(mod): + "Teardown the pytest environment" + tgen = get_topogen() + + # This function tears down the whole topology. + tgen.stop_topology() + + +def router_compare_json_output(rname, command, reference): + "Compare router JSON output" + + logger.info('Comparing router "%s" "%s" output', rname, command) + + tgen = get_topogen() + expected = json.loads(reference) + + # Run test function until we get an result. Wait at most 60 seconds. + test_func = partial(topotest.router_json_cmp, tgen.gears[rname], command, expected) + _, diff = topotest.run_and_expect(test_func, None, count=120, wait=0.5) + assertmsg = '"{}" JSON output mismatches the expected result'.format(rname) + assert diff is None, assertmsg + + +# +# Step 1 +# +# Test initial network convergence +# +def test_isis_adjacencies_step1(): + logger.info("Test (step 1): check IS-IS adjacencies") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["rt1"]: + router_compare_json_output( + rname, + "show yang operational-data /frr-interface:lib isisd", + outputs[rname][1]["show_yang_interface_isis_adjacencies.ref"], + ) + + +def test_rib_ipv4_step1(): + logger.info("Test (step 1): verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["rt1"]: + router_compare_json_output( + rname, "show ip route isis json", outputs[rname][1]["show_ip_route.ref"] + ) + + +def test_rib_ipv6_step1(): + logger.info("Test (step 1): verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["rt1"]: + router_compare_json_output( + rname, "show ipv6 route isis json", outputs[rname][1]["show_ipv6_route.ref"] + ) + + +# +# Step 2 +# +# Action(s): +# -Configure rt8 (rt1's PQ router) to not accept targeted hello messages +# +# Expected changes: +# -All rt1 backup routes should be uninstalled +# +def test_rib_ipv4_step2(): + logger.info("Test (step 2): verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Configuring rt8 to not accept targeted hello messages") + tgen.net["rt8"].cmd( + 'vtysh -c "conf t" -c "mpls ldp" -c "address-family ipv4" -c "no discovery targeted-hello accept"' + ) + + for rname in ["rt1"]: + router_compare_json_output( + rname, "show ip route isis json", outputs[rname][2]["show_ip_route.ref"] + ) + + +def test_rib_ipv6_step2(): + logger.info("Test (step 2): verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["rt1"]: + router_compare_json_output( + rname, "show ipv6 route isis json", outputs[rname][2]["show_ipv6_route.ref"] + ) + + +# +# Step 3 +# +# Action(s): +# -Configure rt8 (rt1's PQ router) to accept targeted hello messages +# +# Expected changes: +# -All rt1 previously uninstalled backup routes should be reinstalled +# +def test_rib_ipv4_step3(): + logger.info("Test (step 3): verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Configuring rt8 to accept targeted hello messages") + tgen.net["rt8"].cmd( + 'vtysh -c "conf t" -c "mpls ldp" -c "address-family ipv4" -c "discovery targeted-hello accept"' + ) + + for rname in ["rt1"]: + router_compare_json_output( + rname, "show ip route isis json", outputs[rname][3]["show_ip_route.ref"] + ) + + +def test_rib_ipv6_step3(): + logger.info("Test (step 3): verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["rt1"]: + router_compare_json_output( + rname, "show ipv6 route isis json", outputs[rname][3]["show_ipv6_route.ref"] + ) + + +# +# Step 4 +# +# Action(s): +# -Disable RLFA on rt1's eth-rt2 interface +# +# Expected changes: +# -All non-ECMP routes whose primary nexthop is eth-rt2 should lose their backup nexthops +# +def test_rib_ipv4_step4(): + logger.info("Test (step 4): verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Disabling RLFA on rt1's eth-rt2 interface") + tgen.net["rt1"].cmd( + 'vtysh -c "conf t" -c "interface eth-rt2" -c "no isis fast-reroute remote-lfa tunnel mpls-ldp"' + ) + + for rname in ["rt1"]: + router_compare_json_output( + rname, "show ip route isis json", outputs[rname][4]["show_ip_route.ref"] + ) + + +def test_rib_ipv6_step4(): + logger.info("Test (step 4): verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["rt1"]: + router_compare_json_output( + rname, "show ipv6 route isis json", outputs[rname][4]["show_ipv6_route.ref"] + ) + + +# +# Step 5 +# +# Action(s): +# -Disable RLFA on rt1's eth-rt3 interface +# +# Expected changes: +# -All non-ECMP routes whose primary nexthop is eth-rt3 should lose their backup nexthops +# +def test_rib_ipv4_step5(): + logger.info("Test (step 5): verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Disabling RLFA on rt1's eth-rt3 interface") + tgen.net["rt1"].cmd( + 'vtysh -c "conf t" -c "interface eth-rt3" -c "no isis fast-reroute remote-lfa tunnel mpls-ldp"' + ) + + for rname in ["rt1"]: + router_compare_json_output( + rname, "show ip route isis json", outputs[rname][5]["show_ip_route.ref"] + ) + + +def test_rib_ipv6_step5(): + logger.info("Test (step 5): verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["rt1"]: + router_compare_json_output( + rname, "show ipv6 route isis json", outputs[rname][5]["show_ipv6_route.ref"] + ) + + +# +# Step 6 +# +# Action(s): +# -Re-enable RLFA on rt1's eth-rt2 and eth-rt3 interfaces +# +# Expected changes: +# -Revert changes from the previous two steps (reinstall all backup routes) +# +def test_rib_ipv4_step6(): + logger.info("Test (step 6): verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Re-enabling RLFA on rt1's eth-rt2 and eth-rt3 interfaces") + tgen.net["rt1"].cmd( + 'vtysh -c "conf t" -c "interface eth-rt2" -c "isis fast-reroute remote-lfa tunnel mpls-ldp"' + ) + tgen.net["rt1"].cmd( + 'vtysh -c "conf t" -c "interface eth-rt3" -c "isis fast-reroute remote-lfa tunnel mpls-ldp"' + ) + + for rname in ["rt1"]: + router_compare_json_output( + rname, "show ip route isis json", outputs[rname][6]["show_ip_route.ref"] + ) + + +def test_rib_ipv6_step6(): + logger.info("Test (step 6): verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["rt1"]: + router_compare_json_output( + rname, "show ipv6 route isis json", outputs[rname][6]["show_ipv6_route.ref"] + ) + + +# +# Step 7 +# +# Action(s): +# -Configure a PQ node prefix-list filter +# +# Expected changes: +# -All backup routes should be uninstalled +# +def test_rib_ipv4_step7(): + logger.info("Test (step 7): verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Configuring a PQ node prefix-list filter") + tgen.net["rt1"].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "fast-reroute remote-lfa prefix-list PLIST"' + ) + + for rname in ["rt1"]: + router_compare_json_output( + rname, "show ip route isis json", outputs[rname][7]["show_ip_route.ref"] + ) + + +def test_rib_ipv6_step7(): + logger.info("Test (step 7): verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["rt1"]: + router_compare_json_output( + rname, "show ipv6 route isis json", outputs[rname][7]["show_ipv6_route.ref"] + ) + + +# +# Step 8 +# +# Action(s): +# -Configure a prefix-list allowing rt8 as a PQ node +# +# Expected changes: +# -All backup routes should be installed again +# +def test_rib_ipv4_step8(): + logger.info("Test (step 8): verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Configuring a prefix-list allowing rt8 as a PQ node") + tgen.net["rt1"].cmd( + 'vtysh -c "conf t" -c "ip prefix-list PLIST seq 5 permit 10.0.255.8/32"' + ) + + for rname in ["rt1"]: + router_compare_json_output( + rname, "show ip route isis json", outputs[rname][8]["show_ip_route.ref"] + ) + + +def test_rib_ipv6_step8(): + logger.info("Test (step 8): verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["rt1"]: + router_compare_json_output( + rname, "show ipv6 route isis json", outputs[rname][8]["show_ipv6_route.ref"] + ) + + +# +# Step 9 +# +# Action(s): +# -Change the maximum metric up to the PQ node to 30 on the eth-rt2 interface +# +# Expected changes: +# -All non-ECMP routes whose primary nexthop is eth-rt2 should lose their backup nexthops +# +def test_rib_ipv4_step9(): + logger.info("Test (step 9): verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info( + "Changing the maximum metric up to the PQ node to 30 on the eth-rt2 interface" + ) + tgen.net["rt1"].cmd( + 'vtysh -c "conf t" -c "interface eth-rt2" -c "isis fast-reroute remote-lfa maximum-metric 30"' + ) + + for rname in ["rt1"]: + router_compare_json_output( + rname, "show ip route isis json", outputs[rname][9]["show_ip_route.ref"] + ) + + +def test_rib_ipv6_step9(): + logger.info("Test (step 9): verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["rt1"]: + router_compare_json_output( + rname, "show ipv6 route isis json", outputs[rname][9]["show_ipv6_route.ref"] + ) + + +# +# Step 10 +# +# Action(s): +# -Change the maximum metric up to the PQ node to 40 on the eth-rt2 interface +# +# Expected changes: +# -All non-ECMP routes whose primary nexthop is eth-rt2 should recover their backup nexthops +# +def test_rib_ipv4_step10(): + logger.info("Test (step 10): verify IPv4 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info( + "Changing the maximum metric up to the PQ node to 40 on the eth-rt2 interface" + ) + tgen.net["rt1"].cmd( + 'vtysh -c "conf t" -c "interface eth-rt2" -c "isis fast-reroute remote-lfa maximum-metric 40"' + ) + + for rname in ["rt1"]: + router_compare_json_output( + rname, "show ip route isis json", outputs[rname][10]["show_ip_route.ref"] + ) + + +def test_rib_ipv6_step10(): + logger.info("Test (step 10): verify IPv6 RIB") + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["rt1"]: + router_compare_json_output( + rname, + "show ipv6 route isis json", + outputs[rname][10]["show_ipv6_route.ref"], + ) + + +# Memory leak test template +def test_memory_leak(): + "Run the memory leak test and report results." + tgen = get_topogen() + if not tgen.is_memleak_enabled(): + pytest.skip("Memory leak test/report is disabled") + + tgen.report_memory_leaks() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/isis-sr-te-topo1/test_isis_sr_te_topo1.py b/tests/topotests/isis-sr-te-topo1/test_isis_sr_te_topo1.py index b1071310cf..bfd2f92a28 100755 --- a/tests/topotests/isis-sr-te-topo1/test_isis_sr_te_topo1.py +++ b/tests/topotests/isis-sr-te-topo1/test_isis_sr_te_topo1.py @@ -148,6 +148,7 @@ class TemplateTopo(Topo): switch.add_link(tgen.gears['rt6'], nodeif="eth-dst") switch.add_link(tgen.gears['dst'], nodeif="eth-rt6") +@pytest.mark.isis def setup_module(mod): "Sets up the pytest environment" diff --git a/tests/topotests/isis-sr-topo1/test_isis_sr_topo1.py b/tests/topotests/isis-sr-topo1/test_isis_sr_topo1.py index 34eb6d90f6..63be3f78aa 100644 --- a/tests/topotests/isis-sr-topo1/test_isis_sr_topo1.py +++ b/tests/topotests/isis-sr-topo1/test_isis_sr_topo1.py @@ -134,7 +134,7 @@ class TemplateTopo(Topo): switch.add_link(tgen.gears["rt5"], nodeif="eth-rt6") switch.add_link(tgen.gears["rt6"], nodeif="eth-rt5") - +@pytest.mark.isis def setup_module(mod): "Sets up the pytest environment" tgen = Topogen(TemplateTopo, mod.__name__) diff --git a/tests/topotests/isis-tilfa-topo1/test_isis_tilfa_topo1.py b/tests/topotests/isis-tilfa-topo1/test_isis_tilfa_topo1.py index a1263de8ad..83751fabcd 100755 --- a/tests/topotests/isis-tilfa-topo1/test_isis_tilfa_topo1.py +++ b/tests/topotests/isis-tilfa-topo1/test_isis_tilfa_topo1.py @@ -177,7 +177,7 @@ class TemplateTopo(Topo): f_in.close() f_out.close() - +@pytest.mark.isis def setup_module(mod): "Sets up the pytest environment" tgen = Topogen(TemplateTopo, mod.__name__) diff --git a/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py index 12121e4ddf..a79c8a268b 100644 --- a/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py +++ b/tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py @@ -82,7 +82,7 @@ class ISISTopo1(Topo): sw.add_link(tgen.gears["r4"]) sw.add_link(tgen.gears["r5"]) - +@pytest.mark.isis def setup_module(mod): "Sets up the pytest environment" tgen = Topogen(ISISTopo1, mod.__name__) diff --git a/tests/topotests/isis-topo1/test_isis_topo1.py b/tests/topotests/isis-topo1/test_isis_topo1.py index 71005a0362..25116d9452 100644 --- a/tests/topotests/isis-topo1/test_isis_topo1.py +++ b/tests/topotests/isis-topo1/test_isis_topo1.py @@ -84,7 +84,7 @@ class ISISTopo1(Topo): sw.add_link(tgen.gears["r4"]) sw.add_link(tgen.gears["r5"]) - +@pytest.mark.isis def setup_module(mod): "Sets up the pytest environment" tgen = Topogen(ISISTopo1, mod.__name__) diff --git a/tests/topotests/ldp-topo1/test_ldp_topo1.py b/tests/topotests/ldp-topo1/test_ldp_topo1.py index 9822686dfc..dfe65f010e 100644 --- a/tests/topotests/ldp-topo1/test_ldp_topo1.py +++ b/tests/topotests/ldp-topo1/test_ldp_topo1.py @@ -159,7 +159,7 @@ class NetworkTopo(Topo): ## ##################################################### - +@pytest.mark.ldp def setup_module(module): global topo, net global fatal_error diff --git a/tests/topotests/ldp-vpls-topo1/test_ldp_vpls_topo1.py b/tests/topotests/ldp-vpls-topo1/test_ldp_vpls_topo1.py index ba94cd47d4..d659acb470 100644 --- a/tests/topotests/ldp-vpls-topo1/test_ldp_vpls_topo1.py +++ b/tests/topotests/ldp-vpls-topo1/test_ldp_vpls_topo1.py @@ -121,7 +121,8 @@ class TemplateTopo(Topo): switch.add_link(tgen.gears["r2"]) switch.add_link(tgen.gears["r3"]) - +@pytest.mark.ldp +@pytest.mark.ospf def setup_module(mod): "Sets up the pytest environment" tgen = Topogen(TemplateTopo, mod.__name__) diff --git a/tests/topotests/lib/bgp.py b/tests/topotests/lib/bgp.py index 68a7217dd6..22602cb460 100644 --- a/tests/topotests/lib/bgp.py +++ b/tests/topotests/lib/bgp.py @@ -692,8 +692,8 @@ def __create_bgp_neighbor(topo, input_dict, router, addr_type, add_neigh=True): config_data.append("{} activate".format(neigh_cxt)) disable_connected = peer.setdefault("disable_connected_check", False) - keep_alive = peer.setdefault("keepalivetimer", 60) - hold_down = peer.setdefault("holddowntimer", 180) + keep_alive = peer.setdefault("keepalivetimer", 3) + hold_down = peer.setdefault("holddowntimer", 10) password = peer.setdefault("password", None) no_password = peer.setdefault("no_password", None) max_hop_limit = peer.setdefault("ebgp_multihop", 1) diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py index 27efecb762..175d660d1e 100644 --- a/tests/topotests/lib/common_config.py +++ b/tests/topotests/lib/common_config.py @@ -1659,7 +1659,7 @@ def create_interfaces_cfg(tgen, topo, build=False): interface_data.append("no ip ospf " " hello-interval") else: interface_data.append( - "ip ospf " " hello-interval {}".format(intf_ospf_hello) + "ip ospf" " hello-interval {}".format(intf_ospf_hello) ) if "dead_interval" in ospf_data: @@ -1670,7 +1670,7 @@ def create_interfaces_cfg(tgen, topo, build=False): interface_data.append("no ip ospf" " dead-interval") else: interface_data.append( - "ip ospf " " dead-interval {}".format(intf_ospf_dead) + "ip ospf" " dead-interval {}".format(intf_ospf_dead) ) if "network" in ospf_data: @@ -3065,7 +3065,11 @@ def verify_rib( errormsg = ( "[DUT: {}]: tag value {}" " is not matched for" - " route {} in RIB \n".format(dut, _tag, st_rt,) + " route {} in RIB \n".format( + dut, + _tag, + st_rt, + ) ) return errormsg @@ -3082,7 +3086,11 @@ def verify_rib( errormsg = ( "[DUT: {}]: metric value " "{} is not matched for " - "route {} in RIB \n".format(dut, metric, st_rt,) + "route {} in RIB \n".format( + dut, + metric, + st_rt, + ) ) return errormsg @@ -4333,3 +4341,58 @@ def kill_iperf(tgen, dut=None, action=None): rnode.run(cmd) logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name)) + + +def verify_ip_nht(tgen, input_dict): + """ + Running "show ip nht" command and verifying given nexthop resolution + Parameters + ---------- + * `tgen` : topogen object + * `input_dict`: data to verify nexthop + Usage + ----- + input_dict_4 = { + "r1": { + nh: { + "Address": nh, + "resolvedVia": "connected", + "nexthops": { + "nexthop1": { + "Interface": intf + } + } + } + } + } + result = verify_ip_nht(tgen, input_dict_4) + Returns + ------- + errormsg(str) or True + """ + + logger.debug("Entering lib API: verify_ip_nht()") + + for router in input_dict.keys(): + if router not in tgen.routers(): + continue + + rnode = tgen.routers()[router] + nh_list = input_dict[router] + + if validate_ip_address(nh_list.keys()[0]) is "ipv6": + show_ip_nht = run_frr_cmd(rnode, "show ipv6 nht") + else: + show_ip_nht = run_frr_cmd(rnode, "show ip nht") + + for nh in nh_list: + if nh in show_ip_nht: + logger.info("Nexthop %s is resolved on %s", nh, router) + return True + else: + errormsg = "Nexthop {} is resolved on {}".format(nh, router) + return errormsg + + logger.debug("Exiting lib API: verify_ip_nht()") + return False + diff --git a/tests/topotests/lib/ospf.py b/tests/topotests/lib/ospf.py index 23b647d094..3e368cd7d3 100644 --- a/tests/topotests/lib/ospf.py +++ b/tests/topotests/lib/ospf.py @@ -62,7 +62,7 @@ def create_router_ospf(tgen, topo, input_dict=None, build=False, load_config=Tru "r1": { "ospf": { "router_id": "22.22.22.22", - "area": [{ "id":0.0.0.0, "type": "nssa"}] + "area": [{ "id": "0.0.0.0", "type": "nssa"}] } } @@ -327,7 +327,7 @@ def config_ospf_interface(tgen, topo, input_dict=None, build=False, load_config= "links": { "r2": { "ospf": { - "authentication": 'message-digest', + "authentication": "message-digest", "authentication-key": "ospf", "message-digest-key": "10" } @@ -376,6 +376,7 @@ def config_ospf_interface(tgen, topo, input_dict=None, build=False, load_config= if data_ospf_area: cmd = "ip ospf area {}".format(data_ospf_area) config_data.append(cmd) + # interface ospf auth if data_ospf_auth: if data_ospf_auth == "null": @@ -461,6 +462,32 @@ def clear_ospf(tgen, router): logger.debug("Exiting lib API: clear_ospf()") +def redistribute_ospf(tgen, topo, dut, route_type, **kwargs): + """ + Redstribution of routes inside ospf. + + Parameters + ---------- + * `tgen`: Topogen object + * `topo` : json file data + * `dut`: device under test + * `route_type`: "static" or "connected" or .... + * `kwargs`: pass extra information (see below) + + Usage + ----- + redistribute_ospf(tgen, topo, "r0", "static", delete=True) + redistribute_ospf(tgen, topo, "r0", "static", route_map="rmap_ipv4") + """ + + ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": route_type}]}}} + for k, v in kwargs.items(): + ospf_red[dut]["ospf"]["redistribute"][0][k] = v + + result = create_router_ospf(tgen, topo, ospf_red) + assert result is True, "Testcase : Failed \n Error: {}".format(result) + + ################################ # Verification procs ################################ @@ -522,7 +549,7 @@ def verify_ospf_neighbor(tgen, topo, dut=None, input_dict=None, lan=False): logger.info("Verifying OSPF neighborship on router %s:", router) show_ospf_json = run_frr_cmd( - rnode, "show ip ospf neighbor all json", isjson=True + rnode, "show ip ospf neighbor all json", isjson=True ) # Verifying output dictionary show_ospf_json is empty or not @@ -844,19 +871,23 @@ def verify_ospf_rib( if "routeType" not in ospf_rib_json[st_rt]: errormsg = ( "[DUT: {}]: routeType missing" - "for route {} in OSPF RIB \n".format(dut, st_rt) + " for route {} in OSPF RIB \n".format( + dut, st_rt + ) ) return errormsg elif _rtype != ospf_rib_json[st_rt]["routeType"]: errormsg = ( "[DUT: {}]: routeType mismatch" - "for route {} in OSPF RIB \n".format(dut, st_rt) + " for route {} in OSPF RIB \n".format( + dut, st_rt + ) ) return errormsg else: logger.info( - "DUT: {}]: Found routeType {}" - "for route {}".format(dut, _rtype, st_rt) + "[DUT: {}]: Found routeType {}" + " for route {}".format(dut, _rtype, st_rt) ) if tag: if "tag" not in ospf_rib_json[st_rt]: diff --git a/tests/topotests/ospf_basic_functionality/ospf_p2mp.json b/tests/topotests/ospf_basic_functionality/ospf_p2mp.json new file mode 100644 index 0000000000..40815f36f3 --- /dev/null +++ b/tests/topotests/ospf_basic_functionality/ospf_p2mp.json @@ -0,0 +1,198 @@ +{ + + "ipv4base": "10.0.0.0", + "ipv4mask": 24, + "link_ip_start": { + "ipv4": "10.0.0.0", + "v4mask": 24 + }, + "lo_prefix": { + "ipv4": "1.0.", + "v4mask": 32 + }, + "routers": { + "r0": { + "links": { + "lo": { + "ipv4": "auto", + "type": "loopback" + }, + "r1": { + "ipv4": "auto", + "ospf": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4, + "network": "point-to-multipoint" + } + }, + "r2": { + "ipv4": "auto", + "ospf": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4, + "network": "point-to-multipoint" + } + }, + "r3": { + "ipv4": "auto", + "ospf": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4, + "network": "point-to-multipoint" + } + } + }, + "ospf": { + "router_id": "100.1.1.0", + "neighbors": { + "r1": {}, + "r2": {}, + "r3": {} + } + } + }, + "r1": { + "links": { + "lo": { + "ipv4": "auto", + "type": "loopback" + }, + "r0": { + "ipv4": "auto", + "ospf": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4, + "network": "point-to-multipoint" + } + }, + "r2": { + "ipv4": "auto", + "ospf": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4, + "network": "point-to-multipoint" + } + }, + "r3": { + "ipv4": "auto", + "ospf": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4, + "network": "point-to-multipoint" + } + }, + "r3-link0": { + "ipv4": "auto", + "description": "DummyIntftoR3" + } + }, + "ospf": { + "router_id": "100.1.1.1", + "neighbors": { + "r0": {}, + "r2": {}, + "r3": {} + } + } + }, + "r2": { + "links": { + "lo": { + "ipv4": "auto", + "type": "loopback" + }, + "r0": { + "ipv4": "auto", + "ospf": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4, + "network": "point-to-multipoint" + } + }, + "r1": { + "ipv4": "auto", + "ospf": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4, + "network": "point-to-multipoint" + } + }, + "r3": { + "ipv4": "auto", + "ospf": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4, + "network": "point-to-multipoint" + } + } + }, + "ospf": { + "router_id": "100.1.1.2", + "neighbors": { + "r1": {}, + "r0": {}, + "r3": {} + } + } + }, + "r3": { + "links": { + "lo": { + "ipv4": "auto", + "type": "loopback" + }, + "r0": { + "ipv4": "auto", + "ospf": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4, + "network": "point-to-multipoint" + } + }, + "r1": { + "ipv4": "auto", + "ospf": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4, + "network": "point-to-multipoint" + } + }, + "r2": { + "ipv4": "auto", + "ospf": { + "area": "0.0.0.0", + "hello_interval": 1, + "dead_interval": 4, + "network": "point-to-multipoint" + } + }, + "r1-link0": { + "ipv4": "auto", + "description": "DummyIntftoR1", + "ospf": { + "area": "0.0.0.0" + } + } + }, + "ospf": { + "router_id": "100.1.1.3", + "neighbors": { + "r0": {}, + "r1": {}, + "r2": {} + } + } + } + } +}
\ No newline at end of file diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py index 5ef6b9b0be..441368e8fa 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py @@ -65,6 +65,7 @@ from lib.ospf import ( verify_ospf_rib, create_router_ospf, verify_ospf_interface, + redistribute_ospf, ) topo = None @@ -184,38 +185,6 @@ def teardown_module(mod): logger.info("=" * 40) -def red_static(dut, config=True): - """Local def for Redstribute static routes inside ospf.""" - global topo - tgen = get_topogen() - if config: - ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": "static"}]}}} - else: - ospf_red = { - dut: {"ospf": {"redistribute": [{"redist_type": "static", "delete": True}]}} - } - result = create_router_ospf(tgen, topo, ospf_red) - assert result is True, "Testcase : Failed \n Error: {}".format(result) - - -def red_connected(dut, config=True): - """Local def for Redstribute connected routes inside ospf.""" - global topo - tgen = get_topogen() - if config: - ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": "connected"}]}}} - else: - ospf_red = { - dut: { - "ospf": { - "redistribute": [{"redist_type": "connected", "del_action": True}] - } - } - } - result = create_router_ospf(tgen, topo, ospf_red) - assert result is True, "Testcase: Failed \n Error: {}".format(result) - - # ################################## # Test cases start here. # ################################## @@ -264,7 +233,7 @@ def test_ospf_ecmp_tc16_p0(request): assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) dut = "r0" - red_static(dut) + redistribute_ospf(tgen, topo, dut, "static") step("Verify that route in R2 in stalled with 8 next hops.") nh = [] @@ -345,7 +314,7 @@ def test_ospf_ecmp_tc16_p0(request): step(" Un configure static route on R0") dut = "r0" - red_static(dut, config=False) + redistribute_ospf(tgen, topo, dut, "static", delete=True) # Wait for R0 to flush external LSAs. sleep(10) @@ -376,7 +345,7 @@ def test_ospf_ecmp_tc16_p0(request): step("Re configure the static route in R0.") dut = "r0" - red_static(dut) + redistribute_ospf(tgen, topo, dut, "static") dut = "r1" result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh) @@ -431,7 +400,7 @@ def test_ospf_ecmp_tc17_p0(request): assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) dut = "r0" - red_static(dut) + redistribute_ospf(tgen, topo, dut, "static") step("Verify that route in R2 in stalled with 2 next hops.") @@ -450,7 +419,7 @@ def test_ospf_ecmp_tc17_p0(request): step(" Un configure static route on R0") dut = "r0" - red_static(dut, config=False) + redistribute_ospf(tgen, topo, dut, "static", delete=True) # sleep till the route gets withdrawn sleep(10) @@ -480,7 +449,7 @@ def test_ospf_ecmp_tc17_p0(request): step("Reconfigure the static route in R0.Change ECMP value to 2.") dut = "r0" - red_static(dut) + redistribute_ospf(tgen, topo, dut, "static") step("Configure cost on R0 as 100") r0_ospf_cost = {"r0": {"links": {"r1": {"ospf": {"cost": 100}}}}} diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py index 967bc44879..2da1dcd21a 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py @@ -66,6 +66,7 @@ from lib.ospf import ( verify_ospf_rib, create_router_ospf, verify_ospf_interface, + redistribute_ospf, ) from ipaddress import IPv4Address @@ -187,42 +188,6 @@ def teardown_module(): pass -def red_static(dut, config=True): - """Local def for Redstribute static routes inside ospf.""" - global topo - tgen = get_topogen() - if config: - ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": "static"}]}}} - else: - ospf_red = { - dut: { - "ospf": { - "redistribute": [{"redist_type": "static", "del_action": True}] - } - } - } - result = create_router_ospf(tgen, topo, ospf_red) - assert result is True, "Testcase : Failed \n Error: {}".format(result) - - -def red_connected(dut, config=True): - """Local def for Redstribute connected routes inside ospf.""" - global topo - tgen = get_topogen() - if config: - ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": "connected"}]}}} - else: - ospf_red = { - dut: { - "ospf": { - "redistribute": [{"redist_type": "connected", "del_action": True}] - } - } - } - result = create_router_ospf(tgen, topo, ospf_red) - assert result is True, "Testcase: Failed \n Error: {}".format(result) - - # ################################## # Test cases start here. # ################################## @@ -275,7 +240,7 @@ def test_ospf_lan_ecmp_tc18_p0(request): ) dut = rtr - red_static(dut) + redistribute_ospf(tgen, topo, dut, "static") step( "Verify that route in R0 in stalled with 8 hops. " diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_lan.py b/tests/topotests/ospf_basic_functionality/test_ospf_lan.py index 0f1115f815..dac32090bc 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_lan.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_lan.py @@ -183,42 +183,6 @@ def teardown_module(): pass -def red_static(dut, config=True): - """Local def for Redstribute static routes inside ospf.""" - global topo - tgen = get_topogen() - if config: - ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": "static"}]}}} - else: - ospf_red = { - dut: { - "ospf": { - "redistribute": [{"redist_type": "static", "del_action": True}] - } - } - } - result = create_router_ospf(tgen, topo, ospf_red) - assert result is True, "Testcase : Failed \n Error: {}".format(result) - - -def red_connected(dut, config=True): - """Local def for Redstribute connected routes inside ospf.""" - global topo - tgen = get_topogen() - if config: - ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": "connected"}]}}} - else: - ospf_red = { - dut: { - "ospf": { - "redistribute": [{"redist_type": "connected", "del_action": True}] - } - } - } - result = create_router_ospf(tgen, topo, ospf_red) - assert result is True, "Testcase: Failed \n Error: {}".format(result) - - # ################################## # Test cases start here. # ################################## diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_nssa.py b/tests/topotests/ospf_basic_functionality/test_ospf_nssa.py index 82a34d046c..3644bff3dc 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_nssa.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_nssa.py @@ -30,6 +30,7 @@ from lib.ospf import ( verify_ospf_rib, create_router_ospf, verify_ospf_interface, + redistribute_ospf, ) from lib.topojson import build_topo_from_json, build_config_from_json from lib.topolog import logger @@ -181,38 +182,6 @@ def teardown_module(mod): logger.info("=" * 40) -def red_static(dut, config=True): - """Local def for Redstribute static routes inside ospf.""" - global topo - tgen = get_topogen() - if config: - ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": "static"}]}}} - else: - ospf_red = { - dut: {"ospf": {"redistribute": [{"redist_type": "static", "delete": True}]}} - } - result = create_router_ospf(tgen, topo, ospf_red) - assert result is True, "Testcase : Failed \n Error: {}".format(result) - - -def red_connected(dut, config=True): - """Local def for Redstribute connected routes inside ospf.""" - global topo - tgen = get_topogen() - if config: - ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": "connected"}]}}} - else: - ospf_red = { - dut: { - "ospf": { - "redistribute": [{"redist_type": "connected", "del_action": True}] - } - } - } - result = create_router_ospf(tgen, topo, ospf_red) - assert result is True, "Testcase: Failed \n Error: {}".format(result) - - # ################################## # Test cases start here. # ################################## @@ -268,7 +237,7 @@ def test_ospf_learning_tc15_p0(request): step("Redistribute static route in R2 ospf.") dut = "r2" - red_static(dut) + redistribute_ospf(tgen, topo, dut, "static") step("Verify that Type 5 LSA is originated by R2.") dut = "r0" diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py b/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py new file mode 100644 index 0000000000..c90275ecb0 --- /dev/null +++ b/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py @@ -0,0 +1,416 @@ +#!/usr/bin/python + +# +# Copyright (c) 2020 by VMware, Inc. ("VMware") +# Used Copyright (c) 2018 by Network Device Education Foundation, Inc. +# ("NetDEF") in this file. +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + + +"""OSPF Basic Functionality Automation.""" +import os +import sys +import time +import pytest +import json +from copy import deepcopy +from ipaddress import IPv4Address + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) +sys.path.append(os.path.join(CWD, "../lib/")) + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from mininet.topo import Topo +from lib.topogen import Topogen, get_topogen +import ipaddress + +# Import topoJson from lib, to create topology and initial configuration +from lib.common_config import ( + start_topology, + write_test_header, + write_test_footer, + reset_config_on_routers, + verify_rib, + create_static_routes, + step, + create_route_maps, + shutdown_bringup_interface, + create_interfaces_cfg, + topo_daemons, +) +from lib.topolog import logger +from lib.topojson import build_topo_from_json, build_config_from_json + +from lib.ospf import ( + verify_ospf_neighbor, + config_ospf_interface, + clear_ospf, + verify_ospf_rib, + create_router_ospf, + verify_ospf_interface, + verify_ospf_database, +) + +# Global variables +topo = None + +# Reading the data from JSON File for topology creation +jsonFile = "{}/ospf_p2mp.json".format(CWD) +try: + with open(jsonFile, "r") as topoJson: + topo = json.load(topoJson) +except IOError: + assert False, "Could not read file {}".format(jsonFile) + +""" +TOPOOLOGY = + Please view in a fixed-width font such as Courier. + +---+ A1 +---+ + +R1 +------------+R2 | + +-+-+- +--++ + | -- -- | + | -- A0 -- | + A0| ---- | + | ---- | A2 + | -- -- | + | -- -- | + +-+-+- +-+-+ + +R0 +-------------+R3 | + +---+ A3 +---+ + +TESTCASES = +1. OSPF P2MP -Verify state change events on p2mp network. + """ + + +class CreateTopo(Topo): + """ + Test topology builder. + + * `Topo`: Topology object + """ + + def build(self, *_args, **_opts): + """Build function.""" + tgen = get_topogen(self) + + # Building topology from json file + build_topo_from_json(tgen, topo) + + +def setup_module(mod): + """ + Sets up the pytest environment + + * `mod`: module name + """ + global topo + testsuite_run_time = time.asctime(time.localtime(time.time())) + logger.info("Testsuite start time: {}".format(testsuite_run_time)) + logger.info("=" * 40) + + logger.info("Running setup_module to create topology") + + # This function initiates the topology build with Topogen... + tgen = Topogen(CreateTopo, mod.__name__) + # ... and here it calls Mininet initialization functions. + + # get list of daemons needs to be started for this suite. + daemons = topo_daemons(tgen, topo) + + # Starting topology, create tmp files which are loaded to routers + # to start deamons and then start routers + start_topology(tgen, daemons) + + # Creating configuration from JSON + build_config_from_json(tgen, topo) + + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + + logger.info("Running setup_module() done") + + +def teardown_module(mod): + """ + Teardown the pytest environment. + + * `mod`: module name + """ + + logger.info("Running teardown_module to delete topology") + + tgen = get_topogen() + + # Stop toplogy and Remove tmp files + tgen.stop_topology() + + logger.info( + "Testsuite end time: {}".format(time.asctime(time.localtime(time.time()))) + ) + logger.info("=" * 40) + + +# ################################## +# Test cases start here. +# ################################## + + +def test_ospf_p2mp_tc1_p0(request): + """OSPF IFSM -Verify state change events on p2mp network.""" + tc_name = request.node.name + write_test_header(tc_name) + tgen = get_topogen() + + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + global topo + step("Bring up the base config as per the topology") + reset_config_on_routers(tgen) + step( + "Verify that OSPF is subscribed to multi cast services " + "(All SPF, all DR Routers)." + ) + step("Verify that interface is enabled in ospf.") + step("Verify that config is successful.") + dut = "r0" + input_dict = { + "r0": { + "links": { + "r3": {"ospf": {"mcastMemberOspfAllRouters": True, "ospfEnabled": True}} + } + } + } + result = verify_ospf_interface(tgen, topo, dut=dut, input_dict=input_dict) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + + step("Delete the ip address") + topo1 = { + "r0": { + "links": { + "r3": { + "ipv4": topo["routers"]["r0"]["links"]["r3"]["ipv4"], + "interface": topo["routers"]["r0"]["links"]["r3"]["interface"], + "delete": True, + } + } + } + } + + result = create_interfaces_cfg(tgen, topo1) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + + step("Change the ip on the R0 interface") + + topo_modify_change_ip = deepcopy(topo) + intf_ip = topo_modify_change_ip["routers"]["r0"]["links"]["r3"]["ipv4"] + topo_modify_change_ip["routers"]["r0"]["links"]["r3"]["ipv4"] = str( + IPv4Address(unicode(intf_ip.split("/")[0])) + 3 + ) + "/{}".format(intf_ip.split("/")[1]) + + build_config_from_json(tgen, topo_modify_change_ip, save_bkup=False) + step("Verify that interface is enabled in ospf.") + dut = "r0" + input_dict = { + "r0": { + "links": { + "r3": { + "ospf": { + "ipAddress": topo_modify_change_ip["routers"]["r0"]["links"][ + "r3" + ]["ipv4"].split("/")[0], + "ipAddressPrefixlen": int( + topo_modify_change_ip["routers"]["r0"]["links"]["r3"][ + "ipv4" + ].split("/")[1] + ), + } + } + } + } + } + result = verify_ospf_interface(tgen, topo, dut=dut, input_dict=input_dict) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + + step("Modify the mask on the R0 interface") + ip_addr = topo_modify_change_ip["routers"]["r0"]["links"]["r3"]["ipv4"] + mask = topo_modify_change_ip["routers"]["r0"]["links"]["r3"]["ipv4"] + step("Delete the ip address") + topo1 = { + "r0": { + "links": { + "r3": { + "ipv4": ip_addr, + "interface": topo["routers"]["r0"]["links"]["r3"]["interface"], + "delete": True, + } + } + } + } + + result = create_interfaces_cfg(tgen, topo1) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + + step("Change the ip on the R0 interface") + + topo_modify_change_ip = deepcopy(topo) + intf_ip = topo_modify_change_ip["routers"]["r0"]["links"]["r3"]["ipv4"] + topo_modify_change_ip["routers"]["r0"]["links"]["r3"]["ipv4"] = str( + IPv4Address(unicode(intf_ip.split("/")[0])) + 3 + ) + "/{}".format(int(intf_ip.split("/")[1]) + 1) + + build_config_from_json(tgen, topo_modify_change_ip, save_bkup=False) + step("Verify that interface is enabled in ospf.") + dut = "r0" + input_dict = { + "r0": { + "links": { + "r3": { + "ospf": { + "ipAddress": topo_modify_change_ip["routers"]["r0"]["links"][ + "r3" + ]["ipv4"].split("/")[0], + "ipAddressPrefixlen": int( + topo_modify_change_ip["routers"]["r0"]["links"]["r3"][ + "ipv4" + ].split("/")[1] + ), + } + } + } + } + } + result = verify_ospf_interface(tgen, topo, dut=dut, input_dict=input_dict) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + + topo1 = { + "r0": { + "links": { + "r3": { + "ipv4": topo_modify_change_ip["routers"]["r0"]["links"]["r3"][ + "ipv4" + ], + "interface": topo_modify_change_ip["routers"]["r0"]["links"]["r3"][ + "interface" + ], + "delete": True, + } + } + } + } + + result = create_interfaces_cfg(tgen, topo1) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + + build_config_from_json(tgen, topo, save_bkup=False) + + step("Change the area id on the interface") + input_dict = { + "r0": { + "links": { + "r3": { + "interface": topo["routers"]["r0"]["links"]["r3"]["interface"], + "ospf": {"area": "0.0.0.0"}, + "delete": True, + } + } + } + } + + result = create_interfaces_cfg(tgen, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + input_dict = { + "r0": { + "links": { + "r3": { + "interface": topo["routers"]["r0"]["links"]["r3"]["interface"], + "ospf": {"area": "0.0.0.1"}, + } + } + } + } + + result = create_interfaces_cfg(tgen, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + step("Verify that interface is enabled in ospf.") + dut = "r0" + input_dict = { + "r0": {"links": {"r3": {"ospf": {"area": "0.0.0.1", "ospfEnabled": True}}}} + } + result = verify_ospf_interface(tgen, topo, dut=dut, input_dict=input_dict) + assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + + input_dict = { + "r0": { + "links": { + "r3": { + "interface": topo["routers"]["r0"]["links"]["r3"]["interface"], + "ospf": {"area": "0.0.0.1"}, + "delete": True, + } + } + } + } + + result = create_interfaces_cfg(tgen, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + input_dict = { + "r0": { + "links": { + "r3": { + "interface": topo["routers"]["r0"]["links"]["r3"]["interface"], + "ospf": {"area": "0.0.0.0"}, + } + } + } + } + + result = create_interfaces_cfg(tgen, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step("Verify if interface is enabled with network type P2MP") + input_dict = { + "r0": { + "links": { + "r3": { + "interface": topo["routers"]["r0"]["links"]["r3"]["interface"], + "ospf": { + "area": "0.0.0.0", + "networkType":"POINTOMULTIPOINT" + }, + } + } + } + } + result = create_interfaces_cfg(tgen, input_dict) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + write_test_footer(tc_name) + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py b/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py index 88667a6ac8..ceadb3975b 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py @@ -62,6 +62,7 @@ from lib.ospf import ( verify_ospf_rib, create_router_ospf, verify_ospf_database, + redistribute_ospf, ) # Global variables @@ -226,9 +227,7 @@ def test_ospf_routemaps_functionality_tc19_p0(request): result = create_static_routes(tgen, input_dict) assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) - ospf_red_r1 = {"r0": {"ospf": {"redistribute": [{"redist_type": "static"}]}}} - result = create_router_ospf(tgen, topo, ospf_red_r1) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + redistribute_ospf(tgen, topo, "r0", "static") dut = "r1" lsid = NETWORK["ipv4"][0].split("/")[0] @@ -240,13 +239,7 @@ def test_ospf_routemaps_functionality_tc19_p0(request): result = verify_rib(tgen, "ipv4", dut, input_dict, protocol=protocol) assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) - ospf_red_r1 = { - "r0": { - "ospf": {"redistribute": [{"redist_type": "static", "del_action": True}]} - } - } - result = create_router_ospf(tgen, topo, ospf_red_r1) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + redistribute_ospf(tgen, topo, "r0", "static", delete=True) step( "Create prefix-list in R0 to permit 10.0.20.1/32 prefix &" " deny 10.0.20.2/32" @@ -293,15 +286,7 @@ def test_ospf_routemaps_functionality_tc19_p0(request): " ospf using route map rmap1" ) - ospf_red_r1 = { - "r0": { - "ospf": { - "redistribute": [{"redist_type": "static", "route_map": "rmap_ipv4"}] - } - } - } - result = create_router_ospf(tgen, topo, ospf_red_r1) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + redistribute_ospf(tgen, topo, "r0", "static", route_map="rmap_ipv4") step("Change prefix rules to permit 10.0.20.2 and deny 10.0.20.1") # Create ip prefix list @@ -495,15 +480,7 @@ def test_ospf_routemaps_functionality_tc20_p0(request): assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) step("Redistribute to ospf using route map ( non existent route map)") - ospf_red_r1 = { - "r0": { - "ospf": { - "redistribute": [{"redist_type": "static", "route_map": "rmap_ipv4"}] - } - } - } - result = create_router_ospf(tgen, topo, ospf_red_r1) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + redistribute_ospf(tgen, topo, "r0", "static", route_map="rmap_ipv4") step( "Verify that routes are not allowed in OSPF even tough no " @@ -633,15 +610,7 @@ def test_ospf_routemaps_functionality_tc21_p0(request): result = create_static_routes(tgen, input_dict) assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) - ospf_red_r0 = { - "r0": { - "ospf": { - "redistribute": [{"redist_type": "static", "route_map": "rmap_ipv4"}] - } - } - } - result = create_router_ospf(tgen, topo, ospf_red_r0) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + redistribute_ospf(tgen, topo, "r0", "static", route_map="rmap_ipv4") # Create route map routemaps = { @@ -877,15 +846,7 @@ def test_ospf_routemaps_functionality_tc24_p0(request): result = create_static_routes(tgen, input_dict) assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) - ospf_red_r0 = { - "r0": { - "ospf": { - "redistribute": [{"redist_type": "static", "route_map": "rmap_ipv4"}] - } - } - } - result = create_router_ospf(tgen, topo, ospf_red_r0) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + redistribute_ospf(tgen, topo, "r0", "static", route_map="rmap_ipv4") # Create ip prefix list pfx_list = { diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py b/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py index 434d7f8ef5..5aa2779aee 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py @@ -61,6 +61,7 @@ from lib.ospf import ( clear_ospf, verify_ospf_rib, create_router_ospf, + redistribute_ospf, ) # Global variables @@ -183,42 +184,6 @@ def teardown_module(mod): logger.info("=" * 40) -def red_static(dut, config=True): - """Local def for Redstribute static routes inside ospf.""" - global topo - tgen = get_topogen() - if config: - ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": "static"}]}}} - else: - ospf_red = { - dut: { - "ospf": { - "redistribute": [{"redist_type": "static", "del_action": True}] - } - } - } - result = create_router_ospf(tgen, topo, ospf_red) - assert result is True, "Testcase : Failed \n Error: {}".format(result) - - -def red_connected(dut, config=True): - """Local def for Redstribute connected routes inside ospf.""" - global topo - tgen = get_topogen() - if config: - ospf_red = {dut: {"ospf": {"redistribute": [{"redist_type": "connected"}]}}} - else: - ospf_red = { - dut: { - "ospf": { - "redistribute": [{"redist_type": "connected", "del_action": True}] - } - } - } - result = create_router_ospf(tgen, topo, ospf_red) - assert result is True, "Testcase: Failed \n Error: {}".format(result) - - # ################################## # Test cases start here. # ################################## @@ -486,8 +451,8 @@ def test_ospf_redistribution_tc8_p1(request): "advertised/exchaged via ospf" ) for rtr in topo["routers"]: - red_static(rtr) - red_connected(rtr) + redistribute_ospf(tgen, topo, rtr, "static") + redistribute_ospf(tgen, topo, rtr, "connected") for node in topo["routers"]: input_dict = { "r0": { @@ -544,13 +509,7 @@ def test_ospf_redistribution_tc8_p1(request): ) for rtr in topo["routers"]: - ospf_red = { - rtr: {"ospf": {"redistribute": [{"redist_type": "static", "delete": True}]}} - } - result = create_router_ospf(tgen, topo, ospf_red) - assert result is True, "Testcase {} : Failed \n Error: {}".format( - tc_name, result - ) + redistribute_ospf(tgen, topo, rtr, "static", delete=True) input_dict = { "r0": { diff --git a/tests/topotests/pbr-topo1/test_pbr_topo1.py b/tests/topotests/pbr-topo1/test_pbr_topo1.py index fcbe3c0adf..5161d5eec7 100644 --- a/tests/topotests/pbr-topo1/test_pbr_topo1.py +++ b/tests/topotests/pbr-topo1/test_pbr_topo1.py @@ -80,7 +80,7 @@ class NetworkTopo(Topo): ## ##################################################### - +@pytest.mark.pbr def setup_module(module): "Setup topology" tgen = Topogen(NetworkTopo, module.__name__) diff --git a/tests/topotests/pim-basic/test_pim.py b/tests/topotests/pim-basic/test_pim.py index e8a9f72b48..74a7fbf16e 100644 --- a/tests/topotests/pim-basic/test_pim.py +++ b/tests/topotests/pim-basic/test_pim.py @@ -80,7 +80,7 @@ class PIMTopo(Topo): sw.add_link(tgen.gears["r1"]) sw.add_link(tgen.gears["r3"]) - +@pytest.mark.pim def setup_module(mod): "Sets up the pytest environment" tgen = Topogen(PIMTopo, mod.__name__) diff --git a/tests/topotests/pytest.ini b/tests/topotests/pytest.ini index 6e8e749092..d1b18a57bb 100644 --- a/tests/topotests/pytest.ini +++ b/tests/topotests/pytest.ini @@ -1,6 +1,16 @@ # Skip pytests example directory [pytest] norecursedirs = .git example-test example-topojson-test lib docker +markers = + babel: Tests that run against BABEL + bfd: Tests that run against BFDD + eigrp: Tests that run against EIGRPD + isis: Tests that run against ISISD + ldp: Tests that run against LDPD + ospf: Tests that run against OSPF( v2 and v3 ) + pbr: Tests that run against PBRD + pim: Tests that run against pim + rip: Tests that run against RIP, both v4 and v6 [topogen] # Default configuration values diff --git a/tests/topotests/rip-topo1/test_rip_topo1.py b/tests/topotests/rip-topo1/test_rip_topo1.py index fdafa50aba..edad1ff65d 100644 --- a/tests/topotests/rip-topo1/test_rip_topo1.py +++ b/tests/topotests/rip-topo1/test_rip_topo1.py @@ -104,7 +104,7 @@ class NetworkTopo(Topo): ## ##################################################### - +@pytest.mark.rip def setup_module(module): global topo, net diff --git a/tests/topotests/ripng-topo1/test_ripng_topo1.py b/tests/topotests/ripng-topo1/test_ripng_topo1.py index 4702d33dae..47b63e5b26 100644 --- a/tests/topotests/ripng-topo1/test_ripng_topo1.py +++ b/tests/topotests/ripng-topo1/test_ripng_topo1.py @@ -104,7 +104,7 @@ class NetworkTopo(Topo): ## ##################################################### - +@pytest.mark.rip def setup_module(module): global topo, net diff --git a/tests/topotests/static_routing_with_ebgp/static_routes_topo3_ebgp.json b/tests/topotests/static_routing_with_ebgp/static_routes_topo3_ebgp.json new file mode 100644 index 0000000000..5246a311ea --- /dev/null +++ b/tests/topotests/static_routing_with_ebgp/static_routes_topo3_ebgp.json @@ -0,0 +1,189 @@ +{ + "address_types": [ + "ipv4", + "ipv6" + ], + "ipv4base": "10.0.0.0", + "ipv4mask": 30, + "ipv6base": "fd00::", + "ipv6mask": 64, + "link_ip_start": { + "ipv4": "10.0.0.0", + "v4mask": 29, + "ipv6": "fd00::", + "v6mask": 64 + }, + "lo_prefix": { + "ipv4": "1.0.", + "v4mask": 32, + "ipv6": "2001:db8:f::", + "v6mask": 128 + }, + "routers": { + "r1": { + "links": { + "lo": { + "ipv4": "auto", + "ipv6": "auto", + "type": "loopback" + }, + "r2-link0": { + "ipv4": "auto", + "ipv6": "auto" + }, + "r2-link1": { + "ipv4": "auto", + "ipv6": "auto" + }, + "r2-link2": { + "ipv4": "auto", + "ipv6": "auto" + }, + "r2-link3": { + "ipv4": "auto", + "ipv6": "auto" + }, + "r2-link4": { + "ipv4": "auto", + "ipv6": "auto" + }, + "r2-link5": { + "ipv4": "auto", + "ipv6": "auto" + }, + "r2-link6": { + "ipv4": "auto", + "ipv6": "auto" + }, + "r2-link7": { + "ipv4": "auto", + "ipv6": "auto" + } + } + }, + "r2": { + "links": { + "lo": { + "ipv4": "auto", + "ipv6": "auto", + "type": "loopback" + }, + "r1-link0": { + "ipv4": "auto", + "ipv6": "auto" + }, + "r1-link1": { + "ipv4": "auto", + "ipv6": "auto" + }, + "r1-link2": { + "ipv4": "auto", + "ipv6": "auto" + }, + "r1-link3": { + "ipv4": "auto", + "ipv6": "auto" + }, + "r1-link4": { + "ipv4": "auto", + "ipv6": "auto" + }, + "r1-link5": { + "ipv4": "auto", + "ipv6": "auto" + }, + "r1-link6": { + "ipv4": "auto", + "ipv6": "auto" + }, + "r1-link7": { + "ipv4": "auto", + "ipv6": "auto" + }, + "r3-link0": { + "ipv4": "auto", + "ipv6": "auto" + } + }, + "bgp": { + "local_as": "100", + "address_family": { + "ipv4": { + "unicast": { + "neighbor": { + "r3": { + "dest_link": { + "r2-link0": { + "keepalivetimer": 1, + "holddowntimer": 4 + } + } + } + } + } + }, + "ipv6": { + "unicast": { + "neighbor": { + "r3": { + "dest_link": { + "r2-link0": { + "keepalivetimer": 1, + "holddowntimer": 4 + } + } + } + } + } + } + } + } + }, + "r3": { + "links": { + "lo": { + "ipv4": "auto", + "ipv6": "auto", + "type": "loopback" + }, + "r2-link0": { + "ipv4": "auto", + "ipv6": "auto" + } + }, + "bgp": { + "local_as": "200", + "address_family": { + "ipv4": { + "unicast": { + "neighbor": { + "r2": { + "dest_link": { + "r3-link0": { + "keepalivetimer": 1, + "holddowntimer": 4 + } + } + } + } + } + }, + "ipv6": { + "unicast": { + "neighbor": { + "r2": { + "dest_link": { + "r3-link0": { + "keepalivetimer": 1, + "holddowntimer": 4 + } + } + } + } + } + } + } + } + } + } +}
\ No newline at end of file diff --git a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo3_ebgp.py b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo3_ebgp.py new file mode 100644 index 0000000000..255bb073b4 --- /dev/null +++ b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo3_ebgp.py @@ -0,0 +1,1333 @@ +#!/usr/bin/python + +# +# Copyright (c) 2020 by VMware, Inc. ("VMware") +# Used Copyright (c) 2018 by Network Device Education Foundation, +# Inc. ("NetDEF") in this file. +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# +""" + -Verify static route ECMP functionality with 8 next hop + + -Verify static route functionality with 8 next hop different AD value + + -Verify static route with tag option + + -Verify BGP did not install the static route when it receive route + with local next hop + +""" +import sys +import json +import time +import os +import pytest +import random +import platform +from lib.topotest import version_cmp + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) +sys.path.append(os.path.join(CWD, "../lib/")) +# pylint: disable=C0413 +# Import topogen and topotest helpers +from mininet.topo import Topo +from lib.topogen import Topogen, get_topogen + +from lib.common_config import ( + start_topology, + write_test_header, + write_test_footer, + reset_config_on_routers, + verify_rib, + create_static_routes, + check_address_types, + step, + create_interfaces_cfg, + shutdown_bringup_interface, + stop_router, + start_router, + create_route_maps, + verify_ip_nht, +) +from lib.topolog import logger +from lib.bgp import verify_bgp_convergence, create_router_bgp, verify_bgp_rib +from lib.topojson import build_topo_from_json, build_config_from_json + +# Reading the data from JSON File for topology creation +jsonFile = "{}/static_routes_topo3_ebgp.json".format(CWD) +try: + with open(jsonFile, "r") as topoJson: + topo = json.load(topoJson) +except IOError: + assert False, "Could not read file {}".format(jsonFile) + +# Global variables +BGP_CONVERGENCE = False +ADDR_TYPES = check_address_types() +NETWORK = { + "ipv4": [ + "11.0.20.1/32", + "11.0.20.2/32", + "11.0.20.3/32", + "11.0.20.4/32", + "11.0.20.5/32", + "11.0.20.6/32", + "11.0.20.7/32", + "11.0.20.8/32", + ], + "ipv6": [ + "2::1/128", + "2::2/128", + "2::3/128", + "2::4/128", + "2::5/128", + "2::6/128", + "2::7/128", + "2::8/128", + ], +} +PREFIX1 = {"ipv4": "110.0.20.1/32", "ipv6": "20::1/128"} +NETWORK2 = {"ipv4": ["11.0.20.1/32"], "ipv6": ["2::1/128"]} +NEXT_HOP_IP = [] + + +class CreateTopo(Topo): + """ + Test CreateTopo - topology 1. + + * `Topo`: Topology object + """ + + def build(self, *_args, **_opts): + """Build function.""" + tgen = get_topogen(self) + + # Building topology from json file + build_topo_from_json(tgen, topo) + + +def setup_module(mod): + """ + + Set up the pytest environment. + + * `mod`: module name + """ + global topo + testsuite_run_time = time.asctime(time.localtime(time.time())) + logger.info("Testsuite start time: {}".format(testsuite_run_time)) + logger.info("=" * 40) + + logger.info("Running setup_module to create topology") + + # This function initiates the topology build with Topogen... + tgen = Topogen(CreateTopo, mod.__name__) + # ... and here it calls Mininet initialization functions. + + # Starting topology, create tmp files which are loaded to routers + # to start deamons and then start routers + start_topology(tgen) + + # Creating configuration from JSON + build_config_from_json(tgen, topo) + + if version_cmp(platform.release(), "4.19") < 0: + error_msg = ( + 'These tests will not run. (have kernel "{}", ' + "requires kernel >= 4.19)".format(platform.release()) + ) + pytest.skip(error_msg) + + # Checking BGP convergence + global BGP_CONVERGENCE + global ADDR_TYPES + + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + # Api call verify whether BGP is converged + BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo) + assert BGP_CONVERGENCE is True, "setup_module :Failed \n Error: {}".format( + BGP_CONVERGENCE + ) + + logger.info("Running setup_module() done") + + +def teardown_module(mod): + """ + Teardown the pytest environment + + * `mod`: module name + """ + + logger.info("Running teardown_module to delete topology") + + tgen = get_topogen() + + # Stop toplogy and Remove tmp files + tgen.stop_topology() + + logger.info( + "Testsuite end time: {}".format(time.asctime(time.localtime(time.time()))) + ) + logger.info("=" * 40) + + +def populate_nh(): + NEXT_HOP_IP = { + "nh1": { + "ipv4": topo["routers"]["r1"]["links"]["r2-link0"]["ipv4"].split("/")[0], + "ipv6": topo["routers"]["r1"]["links"]["r2-link0"]["ipv6"].split("/")[0], + }, + "nh2": { + "ipv4": topo["routers"]["r1"]["links"]["r2-link1"]["ipv4"].split("/")[0], + "ipv6": topo["routers"]["r1"]["links"]["r2-link1"]["ipv6"].split("/")[0], + }, + "nh3": { + "ipv4": topo["routers"]["r1"]["links"]["r2-link2"]["ipv4"].split("/")[0], + "ipv6": topo["routers"]["r1"]["links"]["r2-link2"]["ipv6"].split("/")[0], + }, + "nh4": { + "ipv4": topo["routers"]["r1"]["links"]["r2-link3"]["ipv4"].split("/")[0], + "ipv6": topo["routers"]["r1"]["links"]["r2-link3"]["ipv6"].split("/")[0], + }, + "nh5": { + "ipv4": topo["routers"]["r1"]["links"]["r2-link4"]["ipv4"].split("/")[0], + "ipv6": topo["routers"]["r1"]["links"]["r2-link4"]["ipv6"].split("/")[0], + }, + "nh6": { + "ipv4": topo["routers"]["r1"]["links"]["r2-link5"]["ipv4"].split("/")[0], + "ipv6": topo["routers"]["r1"]["links"]["r2-link5"]["ipv6"].split("/")[0], + }, + "nh7": { + "ipv4": topo["routers"]["r1"]["links"]["r2-link6"]["ipv4"].split("/")[0], + "ipv6": topo["routers"]["r1"]["links"]["r2-link6"]["ipv6"].split("/")[0], + }, + "nh8": { + "ipv4": topo["routers"]["r1"]["links"]["r2-link7"]["ipv4"].split("/")[0], + "ipv6": topo["routers"]["r1"]["links"]["r2-link7"]["ipv6"].split("/")[0], + }, + } + return NEXT_HOP_IP + + +##################################################### +# +# Tests starting +# +##################################################### + + +def test_staticroute_with_ecmp_p0_tc3_ebgp(request): + """ + Verify static route ECMP functionality with 8 next hop' + + """ + tc_name = request.node.name + write_test_header(tc_name) + tgen = get_topogen() + + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + reset_config_on_routers(tgen) + NEXT_HOP_IP = populate_nh() + + step("Configure 8 interfaces / links between R1 and R2,") + step( + "Configure IPv4 static route in R2 with 8 next hop" + "N1(21.1.1.2), N2(22.1.1.2), N3(23.1.1.2), N4(24.1.1.2)," + "N5(25.1.1.2), N6(26.1.1.2), N7(27.1.1.2),N8(28.1.1.2), Static" + "route next-hop present on R1" + ) + + step("Configure IBGP IPv4 peering between R2 and R3 router.") + + for addr_type in ADDR_TYPES: + # Enable static routes + for nhp in range(1, 9): + input_dict_4 = { + "r2": { + "static_routes": [ + { + "network": PREFIX1[addr_type], + "next_hop": NEXT_HOP_IP["nh" + str(nhp)][addr_type], + } + ] + } + } + logger.info("Configure static routes") + result = create_static_routes(tgen, input_dict_4) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + logger.info("Verifying %s routes on r2", addr_type) + nh = [ + NEXT_HOP_IP["nh1"][addr_type], + NEXT_HOP_IP["nh2"][addr_type], + NEXT_HOP_IP["nh3"][addr_type], + NEXT_HOP_IP["nh4"][addr_type], + NEXT_HOP_IP["nh5"][addr_type], + NEXT_HOP_IP["nh6"][addr_type], + NEXT_HOP_IP["nh7"][addr_type], + NEXT_HOP_IP["nh8"][addr_type], + ] + + dut = "r2" + protocol = "static" + result = verify_rib( + tgen, addr_type, dut, input_dict_4, next_hop=nh, protocol=protocol + ) + assert result is True, "Testcase {} : Failed \nError: Routes are" + " missing in RIB".format(tc_name) + step("Configure redistribute static in BGP on R2 router") + for addr_type in ADDR_TYPES: + input_dict_2 = { + "r2": { + "bgp": { + "address_family": { + addr_type: { + "unicast": {"redistribute": [{"redist_type": "static"}]} + } + } + } + } + } + result = create_router_bgp(tgen, topo, input_dict_2) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + step( + "Remove the static route configured with nexthop N1 to N8, one" + "by one from running config" + ) + for addr_type in ADDR_TYPES: + # delete static routes + for nhp in range(1, 9): + input_dict_4 = { + "r2": { + "static_routes": [ + { + "network": PREFIX1[addr_type], + "next_hop": NEXT_HOP_IP["nh" + str(nhp)][addr_type], + "delete": True, + } + ] + } + } + + logger.info("Configure static routes") + result = create_static_routes(tgen, input_dict_4) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + result = verify_rib( + tgen, + addr_type, + dut, + input_dict_4, + next_hop=nh, + protocol=protocol, + expected=False, + ) + assert result is not True, "Testcase {} : Failed \nError: Routes are" + " still present in RIB".format(tc_name) + + step("Configure the static route with nexthop N1 to N8, one by" "one") + + for addr_type in ADDR_TYPES: + # add static routes + for nhp in range(1, 9): + input_dict_4 = { + "r2": { + "static_routes": [ + { + "network": PREFIX1[addr_type], + "next_hop": NEXT_HOP_IP["nh" + str(nhp)][addr_type], + } + ] + } + } + + logger.info("Configure static routes") + result = create_static_routes(tgen, input_dict_4) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + result = verify_rib( + tgen, addr_type, dut, input_dict_4, next_hop=nh, protocol=protocol + ) + assert result is True, "Testcase {} : Failed \nError: Routes are" + " missing in RIB".format(tc_name) + + step("Random shut of the nexthop interfaces") + randnum = random.randint(0, 7) + for addr_type in ADDR_TYPES: + intf = topo["routers"]["r2"]["links"]["r1-link" + str(randnum)]["interface"] + shutdown_bringup_interface(tgen, dut, intf, False) + nhip = NEXT_HOP_IP["nh" + str(randnum + 1)][addr_type] + input_dict_5 = { + "r2": { + "static_routes": [ + { + "network": PREFIX1[addr_type], + "next_hop": NEXT_HOP_IP["nh" + str(randnum + 1)][addr_type], + } + ] + } + } + result = verify_rib( + tgen, + addr_type, + dut, + input_dict_5, + next_hop=nhip, + protocol=protocol, + expected=False, + ) + assert result is not True, "Testcase {} : Failed \n" + "Error: Routes are still present in RIB".format(tc_name) + + step("Random no shut of the nexthop interfaces") + for addr_type in ADDR_TYPES: + intf = topo["routers"]["r2"]["links"]["r1-link" + str(randnum)]["interface"] + shutdown_bringup_interface(tgen, dut, intf, True) + nhip = NEXT_HOP_IP["nh" + str(randnum + 1)][addr_type] + result = verify_rib( + tgen, addr_type, dut, input_dict_5, next_hop=nhip, protocol=protocol + ) + assert result is True, "Testcase {} : Failed \n" + "Error: Routes are missing in RIB".format(tc_name) + + step("Reload the FRR router") + # stop/start -> restart FRR router and verify + stop_router(tgen, "r2") + start_router(tgen, "r2") + + result = verify_rib( + tgen, addr_type, dut, input_dict_4, next_hop=nh, protocol=protocol + ) + assert result is True, "Testcase {} : Failed \nError: Routes are" + " missing in RIB".format(tc_name) + + write_test_footer(tc_name) + + +def test_staticroute_with_ecmp_with_diff_AD_p0_tc4_ebgp(request): + """ + Verify static route ECMP functionality with 8 next hop + + """ + tc_name = request.node.name + write_test_header(tc_name) + tgen = get_topogen() + + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + reset_config_on_routers(tgen) + NEXT_HOP_IP = populate_nh() + + step("Configure 8 interfaces / links between R1 and R2,") + step("Configure IBGP IPv4 peering between R2 and R3 router.") + reset_config_on_routers(tgen) + NEXT_HOP_IP = populate_nh() + nh_all = {} + for addr_type in ADDR_TYPES: + nh_all[addr_type] = [] + for nhp in range(1, 9): + nh_all[addr_type].append(NEXT_HOP_IP["nh" + str(nhp)][addr_type]) + step( + "Configure IPv4 static route in R2 with 8 next hop" + "N1(21.1.1.2) AD 10, N2(22.1.1.2) AD 20, N3(23.1.1.2) AD 30," + "N4(24.1.1.2) AD 40, N5(25.1.1.2) AD 50, N6(26.1.1.2) AD 60," + "N7(27.1.1.2) AD 70, N8(28.1.1.2) AD 80, Static route next-hop" + "present on R1" + ) + for addr_type in ADDR_TYPES: + for nhp in range(1, 9): + input_dict_4 = { + "r2": { + "static_routes": [ + { + "network": PREFIX1[addr_type], + "next_hop": NEXT_HOP_IP["nh" + str(nhp)][addr_type], + "admin_distance": 10 * nhp, + } + ] + } + } + logger.info("Configure static routes") + result = create_static_routes(tgen, input_dict_4) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + logger.info("Verifying %s routes on r2", addr_type) + + step( + "On R2, static route installed in RIB using " + "show ip route with 8 next hop, lowest AD nexthop is active" + ) + step("On R2, static route with lowest AD nexthop installed in FIB") + input_dict_4 = { + "r2": { + "static_routes": [ + { + "network": PREFIX1[addr_type], + "next_hop": NEXT_HOP_IP["nh1"][addr_type], + "admin_distance": 10, + } + ] + } + } + dut = "r2" + protocol = "static" + nh = NEXT_HOP_IP["nh1"][addr_type] + result = verify_rib( + tgen, addr_type, dut, input_dict_4, next_hop=nh, protocol=protocol, fib=True + ) + assert result is True, "Testcase {} : Failed \nError: Route with " + " lowest AD is missing in RIB".format(tc_name) + + nh = [] + for nhp in range(2, 9): + nh.append(NEXT_HOP_IP["nh" + str(nhp)][addr_type]) + result = verify_rib( + tgen, + addr_type, + dut, + input_dict_4, + next_hop=nh, + protocol=protocol, + fib=True, + expected=False, + ) + assert result is not True, "Testcase {} : Failed \nError: Routes " + " with high AD are active in RIB".format(tc_name) + + step("Configure redistribute static in BGP on R2 router") + for addr_type in ADDR_TYPES: + input_dict_2 = { + "r2": { + "bgp": { + "address_family": { + addr_type: { + "unicast": {"redistribute": [{"redist_type": "static"}]} + } + } + } + } + } + + logger.info("Configuring redistribute static") + result = create_router_bgp(tgen, topo, input_dict_2) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + step( + "After configuring them, route is always active with lowest AD" + "value and all the nexthop populated in RIB and FIB again " + ) + input_dict_4 = { + "r2": { + "static_routes": [ + { + "network": PREFIX1[addr_type], + "next_hop": NEXT_HOP_IP["nh1"][addr_type], + "admin_distance": 10, + } + ] + } + } + dut = "r2" + protocol = "static" + nh = NEXT_HOP_IP["nh1"][addr_type] + result = verify_rib( + tgen, addr_type, dut, input_dict_4, next_hop=nh, protocol=protocol, fib=True + ) + assert result is True, "Testcase {} : Failed \nError: Route with " + " lowest AD is missing in RIB".format(tc_name) + + step( + "Remove the static route configured with nexthop N1 to N8, one" + "by one from running config" + ) + + for addr_type in ADDR_TYPES: + # delete static routes + for nhp in range(1, 9): + input_dict_4 = { + "r2": { + "static_routes": [ + { + "network": PREFIX1[addr_type], + "next_hop": NEXT_HOP_IP["nh" + str(nhp)][addr_type], + "admin_distance": 10 * nhp, + "delete": True, + } + ] + } + } + + logger.info("Configure static routes") + result = create_static_routes(tgen, input_dict_4) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + step( + "After removing the static route with N1 to N8 one by one, " + "route become active with next preferred nexthop and nexthop which " + "got removed is not shown in RIB and FIB" + ) + result = verify_rib( + tgen, + addr_type, + dut, + input_dict_4, + next_hop=nh_all[addr_type], + protocol=protocol, + expected=False, + ) + assert result is not True, "Testcase {} : Failed \nError: Routes are" + " still present in RIB".format(tc_name) + + step("Configure the static route with nexthop N1 to N8, one by" "one") + for addr_type in ADDR_TYPES: + # add static routes + for nhp in range(1, 9): + input_dict_4 = { + "r2": { + "static_routes": [ + { + "network": PREFIX1[addr_type], + "next_hop": NEXT_HOP_IP["nh" + str(nhp)][addr_type], + "admin_distance": 10 * nhp, + } + ] + } + } + logger.info("Configure static routes") + result = create_static_routes(tgen, input_dict_4) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + step("On R2, static route with lowest AD nexthop installed in FIB") + input_dict_4 = { + "r2": { + "static_routes": [ + { + "network": PREFIX1[addr_type], + "next_hop": NEXT_HOP_IP["nh1"][addr_type], + "admin_distance": 10, + } + ] + } + } + dut = "r2" + protocol = "static" + nh = NEXT_HOP_IP["nh1"][addr_type] + result = verify_rib( + tgen, addr_type, dut, input_dict_4, next_hop=nh, protocol=protocol, fib=True + ) + assert result is True, "Testcase {} : Failed \nError: Route with " + " lowest AD is missing in RIB".format(tc_name) + + nh = [] + for nhp in range(2, 9): + nh.append(NEXT_HOP_IP["nh" + str(nhp)][addr_type]) + result = verify_rib( + tgen, + addr_type, + dut, + input_dict_4, + next_hop=nh, + protocol=protocol, + fib=True, + expected=False, + ) + assert result is not True, "Testcase {} : Failed \nError: Routes " + " with high AD are active in RIB".format(tc_name) + + step("Random shut of the nexthop interfaces") + randnum = random.randint(0, 7) + for addr_type in ADDR_TYPES: + intf = topo["routers"]["r2"]["links"]["r1-link" + str(randnum)]["interface"] + shutdown_bringup_interface(tgen, dut, intf, False) + nhip = NEXT_HOP_IP["nh" + str(randnum + 1)][addr_type] + input_dict_5 = { + "r2": { + "static_routes": [ + { + "network": PREFIX1[addr_type], + "next_hop": NEXT_HOP_IP["nh" + str(randnum + 1)][addr_type], + } + ] + } + } + result = verify_rib( + tgen, + addr_type, + dut, + input_dict_5, + next_hop=nhip, + protocol=protocol, + expected=False, + ) + assert result is not True, "Testcase {} : Failed \n" + "Error: Routes are still present in RIB".format(tc_name) + + step("Random no shut of the nexthop interfaces") + for addr_type in ADDR_TYPES: + intf = topo["routers"]["r2"]["links"]["r1-link" + str(randnum)]["interface"] + shutdown_bringup_interface(tgen, dut, intf, True) + nhip = NEXT_HOP_IP["nh" + str(randnum + 1)][addr_type] + result = verify_rib( + tgen, addr_type, dut, input_dict_5, next_hop=nhip, protocol=protocol + ) + assert result is True, "Testcase {} : Failed \n" + "Error: Routes are missing in RIB".format(tc_name) + + step("Reload the FRR router") + # stop/start -> restart FRR router and verify + stop_router(tgen, "r2") + start_router(tgen, "r2") + + step( + "After reload of FRR router, static route installed " + "in RIB and FIB properly ." + ) + for addr_type in ADDR_TYPES: + input_dict_4 = { + "r2": { + "static_routes": [ + { + "network": PREFIX1[addr_type], + "next_hop": NEXT_HOP_IP["nh1"][addr_type], + "admin_distance": 10, + } + ] + } + } + dut = "r2" + protocol = "static" + nh = NEXT_HOP_IP["nh1"][addr_type] + result = verify_rib( + tgen, addr_type, dut, input_dict_4, next_hop=nh, protocol=protocol, fib=True + ) + assert result is True, "Testcase {} : Failed \nError: Route with " + " lowest AD is missing in RIB".format(tc_name) + + nh = [] + for nhp in range(2, 9): + nh.append(NEXT_HOP_IP["nh" + str(nhp)][addr_type]) + result = verify_rib( + tgen, + addr_type, + dut, + input_dict_4, + next_hop=nh, + protocol=protocol, + fib=True, + expected=False, + ) + assert result is not True, "Testcase {} : Failed \nError: Routes " + " with high AD are active in RIB".format(tc_name) + + write_test_footer(tc_name) + + +def test_bgp_local_nexthop_p1_tc14_ebgp(request): + """ + Verify BGP did not install the static route when it receive route + with local next hop + + """ + tc_name = request.node.name + write_test_header(tc_name) + tgen = get_topogen() + + step("Configure BGP IPv4 session between R2 and R3") + step("Configure IPv4 static route on R2") + reset_config_on_routers(tgen) + + for addr_type in ADDR_TYPES: + # Enable static routes + input_dict_4 = { + "r2": { + "static_routes": [ + { + "network": NETWORK[addr_type], + "next_hop": topo["routers"]["r3"]["links"]["r2-link0"][ + addr_type + ].split("/")[0], + } + ] + } + } + + logger.info("Configure static routes") + result = create_static_routes(tgen, input_dict_4) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + step("Configure redistribute static in the BGP") + + input_dict_2 = { + "r2": { + "bgp": { + "address_family": { + addr_type: { + "unicast": {"redistribute": [{"redist_type": "static"}]} + } + } + } + } + } + result = create_router_bgp(tgen, topo, input_dict_2) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + step("Verify R2 BGP table has IPv4 route") + dut = "r2" + result = verify_rib(tgen, addr_type, dut, input_dict_4) + assert result is True, "Testcase {} : Failed \nError: Routes is" + " missing in RIB of R2".format(tc_name) + + step(" Verify route did not install in the R3 BGP table, RIB/FIB") + dut = "r3" + result = verify_bgp_rib(tgen, addr_type, dut, input_dict_4, expected=False) + assert result is not True, "Testcase {} : Failed \nError: Routes is" + " still present in BGP RIB of R2".format(tc_name) + + result = verify_rib(tgen, addr_type, dut, input_dict_4, expected=False) + assert result is not True, "Testcase {} : Failed \nError: Routes is" + " still present in RIB of R2".format(tc_name) + + write_test_footer(tc_name) + + +def test_frr_intf_name_as_gw_gap_tc4_ebgp_p0(request): + """ + Verify static route configure with interface name as gateway' + 'address' + """ + tc_name = request.node.name + write_test_header(tc_name) + tgen = get_topogen() + + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + reset_config_on_routers(tgen) + + dut = "r1" + intf = topo["routers"]["r1"]["links"]["r2-link0"]["interface"] + nh = topo["routers"]["r1"]["links"]["r2-link0"] + ip_list = { + "ipv4": [(dut, intf, ["1.1.1.1/32"], nh["ipv4"].split("/")[0])], + "ipv6": [(dut, intf, ["4001::32/128"], nh["ipv6"].split("/")[0])], + } + + step( + "Configure IPv4 and IPv6 static route in FRR with different next" + "hop (ens224 as nexthop))" + ) + step("ip route 2.2.2.0/24 20.1.1.1 ens224 ----from FRR cli") + step("ipv6 route 2000::1/120 5000::1 ens224 ----from FRR cli") + + for addr_type in ADDR_TYPES: + # Enable static routes + nh = topo["routers"]["r2"]["links"]["r1-link0"][addr_type].split("/")[0] + input_dict_4 = { + "r1": { + "static_routes": [ + {"network": ip_list[addr_type][0][2][0], "next_hop": nh} + ] + } + } + + logger.info("Configure static routes") + result = create_static_routes(tgen, input_dict_4) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + step( + "IPv4 and IPv6 Static route added in FRR verify using " + "show ip route , nexthop is resolved using show nht" + ) + protocol = "static" + result = verify_rib( + tgen, addr_type, dut, input_dict_4, protocol=protocol, next_hop=nh + ) + assert result is True, "Testcase {} : Failed \nError: Routes is" + " missing in RIB".format(tc_name) + + input_dict_nh = { + "r1": { + nh: { + "Address": nh, + "resolvedVia": "connected", + "nexthops": {"nexthop1": {"Interfcae": intf}}, + } + } + } + result = verify_ip_nht(tgen, input_dict_nh) + assert result is True, "Testcase {} : Failed \nError: Nexthop is" + " missing in RIB".format(tc_name) + + step( + "Shut / no shut IPv4 and IPv6 static next hop interface from" + "kernel and FRR CLI" + ) + + shutdown_bringup_interface(tgen, dut, intf, False) + + step( + "After shut of nexthop interface, IPv4 and IPv6 route got removed " + "from RIB verify using show ip route show nht" + ) + result = verify_rib( + tgen, + addr_type, + dut, + input_dict_4, + protocol=protocol, + next_hop=nh, + expected=False, + ) + assert result is not True, "Testcase {} : Failed \nError: Routes is" + " missing in RIB".format(tc_name) + + shutdown_bringup_interface(tgen, dut, intf, True) + + step( + "After no shut route got added again in RIB /FIB using " + "show ip route nexthop is resolved using show nht" + ) + result = verify_rib(tgen, addr_type, dut, input_dict_4, protocol=protocol) + assert result is True, "Testcase {} : Failed".format(tc_name) + + for addr_type in ADDR_TYPES: + nh = topo["routers"]["r2"]["links"]["r1-link0"][addr_type].split("/")[0] + input_dict_4 = { + "r1": { + "static_routes": [ + { + "network": ip_list[addr_type][0][2][0], + "next_hop": nh, + "delete": True, + } + ] + } + } + + logger.info("Configure static routes") + result = create_static_routes(tgen, input_dict_4) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + step( + "Removing FRR configured static route verify FRR route also " + "removed from FRR" + ) + result = verify_rib( + tgen, + addr_type, + dut, + input_dict_4, + protocol=protocol, + next_hop=nh, + expected=False, + ) + assert result is not True, "Testcase {} : Failed \nError: Routes" + " still present in RIB".format(tc_name) + + write_test_footer(tc_name) + + +def test_static_route_with_tag_p0_tc_13_ebgp(request): + """ + Verify static route with tag option + + """ + tc_name = request.node.name + write_test_header(tc_name) + tgen = get_topogen() + + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + step("Configure 8 links between R1 and R2") + step("Configure 1 links between R2 and R3") + NEXT_HOP_IP = populate_nh() + + step( + "Configure 2 IPv4 static route (S1 and S2) in R2 with same" + "next hop N1 28.1.1.2" + ) + step("Configure static route S1 with tag 1 and static route S2 with" "tag2") + step("S1= ip route 10.1.1.1/24 28.1.1.2 tag 1") + step("S2= ip route 20.1.1.1/24 28.1.1.2 tag 2") + step("Enable redistribute static in BGP with route-map") + reset_config_on_routers(tgen) + + for addr_type in ADDR_TYPES: + # Enable static routes + input_dict_4 = { + "r2": { + "static_routes": [ + { + "network": NETWORK[addr_type], + "next_hop": NEXT_HOP_IP["nh1"][addr_type], + "tag": 4001, + }, + { + "network": NETWORK2[addr_type], + "next_hop": NEXT_HOP_IP["nh1"][addr_type], + "tag": 4002, + }, + ] + } + } + + logger.info("Configure static routes") + result = create_static_routes(tgen, input_dict_4) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + step("verify routes are present in RIB") + dut = "r2" + protocol = "static" + nh = NEXT_HOP_IP["nh1"][addr_type] + result = verify_rib( + tgen, addr_type, dut, input_dict_4, next_hop=nh, protocol=protocol + ) + assert result is True, "Testcase {} : Failed \nError: Routes are" + " missing in RIB".format(tc_name) + + step("Configure route-map on R2 with allow tag1 and deny tag2") + + # Create route map + input_dict_3 = { + "r2": { + "route_maps": { + "rmap_match_tag_1_{}".format(addr_type): [ + { + "action": "permit", + "seq_id": 10, + "match": {addr_type: {"tag": "4001"}}, + }, + { + "action": "deny", + "seq_id": 20, + "match": {addr_type: {"tag": "4002"}}, + }, + ] + } + } + } + result = create_route_maps(tgen, input_dict_3) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + # Configure neighbor for route map + input_dict_4 = { + "r2": { + "bgp": { + "address_family": { + addr_type: { + "unicast": { + "neighbor": { + "r3": { + "dest_link": { + "r2-link0": { + "route_maps": [ + { + "name": "rmap_match_tag_1_ipv4", + "direction": "out", + } + ] + } + } + } + }, + "redistribute": [{"redist_type": "static"}], + } + } + } + } + } + } + result = create_router_bgp(tgen, topo, input_dict_4) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + step( + "Verify static route S1 advetised in BGP table when tag1 permit" + "in route-map else it is denied" + ) + dut = "r3" + input_dict_0 = { + "r2": { + "static_routes": [ + { + "network": NETWORK2[addr_type], + "next_hop": NEXT_HOP_IP["nh1"][addr_type], + "tag": 4002, + } + ] + } + } + + result = verify_rib( + tgen, addr_type, dut, input_dict_0, protocol=protocol, expected=False + ) + assert result is not True, "Testcase {} : Failed \nError: Route with " + "tag 4002 is still present in RIB".format(tc_name) + + dut = "r2" + input_dict_1 = { + "r2": {"static_routes": [{"network": NETWORK[addr_type], "tag": 4001}]} + } + + result = verify_rib(tgen, addr_type, dut, input_dict_0, protocol=protocol) + assert result is True, "Testcase {} : Failed \nError: Route with " + "tag 4001 is missing in RIB".format(tc_name) + + step("Modify the route-map to allow tag2 and deny tag1") + # Create route map + input_dict_3 = { + "r2": { + "route_maps": { + "rmap_match_tag_1_{}".format(addr_type): [ + { + "action": "deny", + "seq_id": 10, + "match": {addr_type: {"tag": "4001"}}, + }, + { + "action": "permit", + "seq_id": 20, + "match": {addr_type: {"tag": "4002"}}, + }, + ] + } + } + } + result = create_route_maps(tgen, input_dict_3) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + dut = "r3" + step( + "Verify static route S2 advertised in BGP table when tag2" + "permit in route-map else it is denied" + ) + protocol = "bgp" + input_dict_0 = { + "r2": {"static_routes": [{"network": NETWORK2[addr_type], "tag": 4002}]} + } + + result = verify_rib(tgen, addr_type, dut, input_dict_0, protocol=protocol) + assert result is True, "Testcase {} : Failed \nError: Route with " + "tag 4002 is missing in RIB".format(tc_name) + + input_dict_1 = { + "r2": {"static_routes": [{"network": NETWORK[addr_type], "tag": 4001}]} + } + result = verify_rib( + tgen, addr_type, dut, input_dict_1, protocol=protocol, expected=False + ) + assert result is not True, "Testcase {} : Failed \nError: Route with " + "tag 4001 is still present in RIB".format(tc_name, result) + + step("Configure one static route with 2 ECMP nexthop N1 and N2") + step("For N1 configure tag 1 and for N2 configure tag 2") + step("S1= ip route 10.1.1.1/24 28.1.1.2 tag 1") + step("S1= ip route 10.1.1.1/24 29.1.1.2 tag 2") + step("configure the route-map to allow tag1 and deny tag 2") + step("Modify the route-map to allow tag2 and deny tag1") + + for addr_type in ADDR_TYPES: + # Enable static routes + input_dict_4 = { + "r2": { + "static_routes": [ + { + "network": NETWORK2[addr_type], + "next_hop": NEXT_HOP_IP["nh1"][addr_type], + "tag": 4001, + }, + { + "network": NETWORK2[addr_type], + "next_hop": NEXT_HOP_IP["nh2"][addr_type], + "tag": 4002, + }, + ] + } + } + + logger.info("Configure static routes") + result = create_static_routes(tgen, input_dict_4) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + dut = "r2" + protocol = "static" + result = verify_rib( + tgen, addr_type, dut, input_dict_4, protocol=protocol, fib=True + ) + assert result is True, "Testcase {} : Failed \nError: Routes are" + " missing in RIB".format(tc_name) + + step("shut/no shut of tag1 and tag2 nexthop") + + intf = topo["routers"]["r2"]["links"]["r1-link0"]["interface"] + shutdown_bringup_interface(tgen, dut, intf, False) + + shutdown_bringup_interface(tgen, dut, intf, True) + + step("configure one static route with 3 next-hop") + step("N1-tag1, N2-tag2, N3-tag3") + step("S1= ip route 10.1.1.1/24 28.1.1.2 tag 1") + step("S1= ip route 10.1.1.1/24 29.1.1.2 tag 2") + step("S1= ip route 10.1.1.1/24 28.1.1.2 tag 3") + + for addr_type in ADDR_TYPES: + # Enable static routes + input_dict_4 = { + "r2": { + "static_routes": [ + { + "network": NETWORK2[addr_type], + "next_hop": NEXT_HOP_IP["nh1"][addr_type], + "tag": 4001, + }, + { + "network": NETWORK2[addr_type], + "next_hop": NEXT_HOP_IP["nh2"][addr_type], + "tag": 4002, + }, + { + "network": NETWORK2[addr_type], + "next_hop": NEXT_HOP_IP["nh3"][addr_type], + "tag": 4003, + }, + ] + } + } + + logger.info("Configure static routes") + result = create_static_routes(tgen, input_dict_4) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + dut = "r2" + protocol = "static" + result = verify_rib(tgen, addr_type, dut, input_dict_4, protocol=protocol) + + step("configure the route-map to allow tag2 & tag3 and deny tag1") + # Create route map + input_dict_3 = { + "r2": { + "route_maps": { + "rmap_match_tag_1_{}".format(addr_type): [ + { + "action": "deny", + "seq_id": 10, + "match": {addr_type: {"tag": "4001"}}, + }, + { + "action": "permit", + "seq_id": 20, + "match": {addr_type: {"tag": "4002"}}, + }, + { + "action": "permit", + "seq_id": 30, + "match": {addr_type: {"tag": "4003"}}, + }, + ] + } + } + } + result = create_route_maps(tgen, input_dict_3) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + step( + "Verify static route advertised in BGP table with tag3" + " nexthop if tag2 is down" + ) + dut = "r3" + protocol = "bgp" + result = verify_bgp_rib(tgen, addr_type, dut, input_dict_4) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + step("shut / no shut of tag2 and tag3 next-hop") + + intf = topo["routers"]["r2"]["links"]["r1-link1"]["interface"] + shutdown_bringup_interface(tgen, dut, intf, False) + + intf = topo["routers"]["r2"]["links"]["r1-link2"]["interface"] + shutdown_bringup_interface(tgen, dut, intf, False) + + step("shut/no shut of tag2 and tag3 nexthop") + intf = topo["routers"]["r2"]["links"]["r1-link1"]["interface"] + shutdown_bringup_interface(tgen, dut, intf, True) + + intf = topo["routers"]["r2"]["links"]["r1-link2"]["interface"] + shutdown_bringup_interface(tgen, dut, intf, True) + + step("Verify after shut/noshut of nexthop BGP table updated correctly") + dut = "r3" + protocol = "bgp" + result = verify_bgp_rib(tgen, addr_type, dut, input_dict_4) + assert result is True, "Testcase {} : Failed \n Error: {}".format( + tc_name, result + ) + + write_test_footer(tc_name) + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/zebra_rib/r1/iproute.ref b/tests/topotests/zebra_rib/r1/iproute.ref new file mode 100644 index 0000000000..b28182c2d1 --- /dev/null +++ b/tests/topotests/zebra_rib/r1/iproute.ref @@ -0,0 +1,512 @@ +4.5.1.0/24 via 192.168.210.2 dev r1-eth0 metric 4278198272 +4.5.2.0/24 via 192.168.211.2 dev r1-eth1 metric 16777217 +4.5.3.0/24 via 192.168.212.2 dev r1-eth2 metric 167772161 +4.5.3.0/24 via 192.168.213.2 dev r1-eth3 metric 2684354561 +10.0.0.0 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.1 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.2 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.3 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.4 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.5 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.6 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.7 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.8 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.9 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.10 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.11 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.12 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.13 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.14 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.15 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.16 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.17 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.18 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.19 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.20 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.21 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.22 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.23 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.24 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.25 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.26 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.27 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.28 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.29 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.30 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.31 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.32 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.33 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.34 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.35 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.36 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.37 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.38 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.39 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.40 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.41 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.42 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.43 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.45 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.46 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.47 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.48 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.49 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.50 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.51 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.52 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.53 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.54 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.55 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.56 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.57 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.58 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.59 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.60 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.61 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.62 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.63 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.64 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.65 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.66 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.67 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.68 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.69 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.70 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.71 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.72 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.73 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.74 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.75 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.76 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.77 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.78 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.79 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.80 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.81 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.82 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.83 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.84 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.85 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.86 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.87 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.88 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.89 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.90 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.91 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.92 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.93 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.94 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.95 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.96 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.97 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.98 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.99 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.100 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.101 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.102 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.103 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.104 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.105 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.106 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.107 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.108 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.109 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.110 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.111 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.112 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.113 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.114 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.115 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.116 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.117 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.118 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.119 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.120 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.121 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.122 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.123 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.124 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.125 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.126 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.127 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.128 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.129 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.130 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.131 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.132 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.133 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.134 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.135 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.136 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.137 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.138 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.139 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.140 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.141 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.142 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.143 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.144 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.145 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.146 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.147 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.148 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.149 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.150 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.151 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.152 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.153 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.154 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.155 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.156 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.157 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.158 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.159 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.160 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.161 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.162 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.163 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.164 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.165 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.166 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.167 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.168 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.169 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.170 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.171 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.172 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.173 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.174 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.175 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.176 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.177 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.178 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.179 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.180 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.181 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.182 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.183 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.184 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.185 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.186 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.187 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.188 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.189 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.190 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.191 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.192 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.193 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.194 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.195 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.196 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.197 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.198 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.199 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.200 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.201 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.202 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.203 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.204 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.205 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.206 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.207 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.208 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.209 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.210 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.211 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.212 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.213 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.214 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.215 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.216 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.217 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.218 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.219 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.220 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.221 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.222 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.223 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.224 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.225 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.226 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.227 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.228 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.229 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.230 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.231 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.232 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.233 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.234 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.235 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.236 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.237 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.238 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.239 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.240 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.241 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.242 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.243 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.244 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.245 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.246 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.247 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.248 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.249 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.250 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.251 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.252 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.253 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.254 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.0.255 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.213.1 metric 20 +10.0.1.0 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.1 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.2 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.3 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.4 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.5 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.6 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.7 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.8 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.9 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.10 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.11 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.12 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.13 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.14 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.15 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.16 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.17 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.18 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.19 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.20 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.21 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.22 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.23 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.24 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.25 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.26 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.27 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.28 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.29 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.30 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.31 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.32 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.33 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.34 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.35 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.36 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.37 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.38 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.39 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.40 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.41 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.42 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.43 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.44 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.45 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.46 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.47 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.48 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.49 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.50 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.51 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.52 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.53 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.54 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.55 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.56 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.57 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.58 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.59 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.60 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.61 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.62 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.63 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.64 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.65 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.66 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.67 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.68 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.69 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.70 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.71 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.72 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.73 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.74 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.75 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.76 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.77 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.78 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.79 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.80 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.81 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.82 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.83 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.84 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.85 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.86 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.87 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.88 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.89 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.90 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.91 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.92 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.93 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.94 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.95 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.96 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.97 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.98 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.99 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.100 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.101 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.102 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.103 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.104 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.105 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.106 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.107 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.108 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.109 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.110 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.111 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.112 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.113 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.114 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.115 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.116 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.117 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.118 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.119 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.120 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.121 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.122 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.123 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.124 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.125 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.126 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.127 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.128 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.129 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.130 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.131 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.132 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.133 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.134 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.135 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.136 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.137 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.138 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.139 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.140 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.141 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.142 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.143 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.144 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.145 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.146 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.147 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.148 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.149 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.150 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.151 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.152 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.153 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.154 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.155 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.156 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.157 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.158 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.159 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.160 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.161 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.162 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.163 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.164 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.165 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.166 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.167 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.168 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.169 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.170 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.171 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.172 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.173 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.174 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.175 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.176 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.177 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.178 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.179 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.180 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.181 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.182 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.183 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.184 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.185 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.186 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.187 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.188 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.189 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.190 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.191 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.192 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.193 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.194 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.195 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.196 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.197 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.198 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.199 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.200 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.201 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.202 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.203 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.204 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.205 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.206 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.207 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.208 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.209 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.210 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.211 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.212 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.213 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.214 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.215 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.216 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.217 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.218 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.219 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.220 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.221 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.222 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.223 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.224 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.225 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.226 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.227 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.228 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.229 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.230 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.231 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.232 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.233 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.234 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.235 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.236 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.237 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.238 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.239 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.240 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.241 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.242 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.0.1.243 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.214.1 metric 20 +10.100.100.100 via 192.168.216.3 dev r1-eth6 proto XXXX src 192.168.215.1 metric 20 +192.168.210.0/24 dev r1-eth0 proto XXXX scope link src 192.168.210.1 +192.168.211.0/24 dev r1-eth1 proto XXXX scope link src 192.168.211.1 +192.168.212.0/24 dev r1-eth2 proto XXXX scope link src 192.168.212.1 +192.168.213.0/24 dev r1-eth3 proto XXXX scope link src 192.168.213.1 +192.168.214.0/24 dev r1-eth4 proto XXXX scope link src 192.168.214.1 +192.168.215.0/24 dev r1-eth5 proto XXXX scope link src 192.168.215.1 +192.168.216.0/24 dev r1-eth6 proto XXXX scope link src 192.168.216.1 +192.168.217.0/24 dev r1-eth7 proto XXXX scope link src 192.168.217.1 diff --git a/tests/topotests/zebra_rib/r1/sharp_rmap.ref b/tests/topotests/zebra_rib/r1/sharp_rmap.ref new file mode 100644 index 0000000000..47a9eb6a49 --- /dev/null +++ b/tests/topotests/zebra_rib/r1/sharp_rmap.ref @@ -0,0 +1,17 @@ +ZEBRA: +route-map: sharp Invoked: 500 Optimization: enabled Processed Change: false + permit, sequence 10 Invoked 244 + Match clauses: + ip address 10 + Set clauses: + src 192.168.214.1 + Call clause: + Action: + Exit routemap + permit, sequence 20 Invoked 256 + Match clauses: + Set clauses: + src 192.168.213.1 + Call clause: + Action: + Exit routemap diff --git a/tests/topotests/zebra_rib/r1/static_rmap.ref b/tests/topotests/zebra_rib/r1/static_rmap.ref new file mode 100644 index 0000000000..2de98bd514 --- /dev/null +++ b/tests/topotests/zebra_rib/r1/static_rmap.ref @@ -0,0 +1,9 @@ +ZEBRA: +route-map: static Invoked: 2 Optimization: enabled Processed Change: false + permit, sequence 10 Invoked 2 + Match clauses: + Set clauses: + src 192.168.215.1 + Call clause: + Action: + Exit routemap diff --git a/tests/topotests/zebra_rib/test_zebra_rib.py b/tests/topotests/zebra_rib/test_zebra_rib.py index ef4b597206..daf8f7be20 100644 --- a/tests/topotests/zebra_rib/test_zebra_rib.py +++ b/tests/topotests/zebra_rib/test_zebra_rib.py @@ -41,6 +41,7 @@ sys.path.append(os.path.join(CWD, "../")) from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger +from time import sleep # Required to instantiate the topology builder class. from mininet.topo import Topo @@ -75,8 +76,9 @@ def setup_module(mod): router_list = tgen.routers() for rname, router in router_list.items(): router.load_config( - TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) - ) + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))) + router.load_config( + TopoRouter.RD_SHARP, os.path.join(CWD, "{}/sharpd.conf".format(rname))) # Initialize all routers. tgen.start_router() @@ -157,6 +159,111 @@ def test_zebra_kernel_override(): _, result = topotest.run_and_expect(test_func, None, count=2, wait=0.5) assert result is None, '"r1" JSON output mismatches' +def test_route_map_usage(): + "Test that FRR only reruns over routes associated with the routemap" + logger.info("Test that FRR runs on selected re's on route-map changes") + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip("Skipped because of previous test failure") + + thisDir = os.path.dirname(os.path.realpath(__file__)) + + r1 = tgen.gears["r1"] + # set the delay timer to 1 to improve test coverage (HA) + r1.vtysh_cmd("conf\nzebra route-map delay-timer 1") + r1.vtysh_cmd("conf\nroute-map static permit 10\nset src 192.168.215.1") + r1.vtysh_cmd("conf\naccess-list 5 seq 5 permit 10.0.0.44/32") + r1.vtysh_cmd("conf\naccess-list 10 seq 5 permit 10.0.1.0/24") + r1.vtysh_cmd("conf\nroute-map sharp permit 10\nmatch ip address 10\nset src 192.168.214.1") + r1.vtysh_cmd("conf\nroute-map sharp permit 20\nset src 192.168.213.1") + r1.vtysh_cmd("conf\nip protocol static route-map static") + r1.vtysh_cmd("conf\nip protocol sharp route-map sharp") + sleep(4) + r1.vtysh_cmd("conf\nip route 10.100.100.100/32 192.168.216.3") + r1.vtysh_cmd("conf\nip route 10.100.100.101/32 10.0.0.44") + r1.vtysh_cmd("sharp install route 10.0.0.0 nexthop 192.168.216.3 500") + sleep(4) + + static_rmapfile = "%s/r1/static_rmap.ref" % (thisDir) + expected = open(static_rmapfile).read().rstrip() + expected = ('\n'.join(expected.splitlines()) + '\n').rstrip() + actual = r1.vtysh_cmd("show route-map static") + actual = ('\n'.join(actual.splitlines()) + '\n').rstrip() + logger.info("Does the show route-map static command run the correct number of times") + + diff = topotest.get_textdiff(actual, expected, + title1 = "Actual Route-map output", + title2 = "Expected Route-map output") + if diff: + logger.info("Actual:") + logger.info(actual) + logger.info("Expected:") + logger.info(expected) + srun = r1.vtysh_cmd("show run") + srun = ('\n'.join(srun.splitlines()) + '\n').rstrip() + logger.info("Show run") + logger.info(srun) + assert 0, "r1 static route processing:\n" + + sharp_rmapfile = "%s/r1/sharp_rmap.ref" % (thisDir) + expected = open(sharp_rmapfile).read().rstrip() + expected = ('\n'.join(expected.splitlines()) + '\n').rstrip() + actual = r1.vtysh_cmd("show route-map sharp") + actual = ('\n'.join(actual.splitlines()) + '\n').rstrip() + logger.info("Does the show route-map sharp command run the correct number of times") + + diff = topotest.get_textdiff(actual, expected, + title1 = "Actual Route-map output", + title2 = "Expected Route-map output") + if diff: + logger.info("Actual:") + logger.info(actual) + logger.info("Expected:") + logger.info(expected) + srun = r1.vtysh_cmd("show run") + srun = ('\n'.join(srun.splitlines()) + '\n').rstrip() + logger.info("Show run:") + logger.info(srun) + assert 0, "r1 sharp route-map processing:\n" + + logger.info("Add a extension to the static route-map to see the static route go away") + r1.vtysh_cmd("conf\nroute-map sharp deny 5\nmatch ip address 5") + sleep(2) + # we are only checking the kernel here as that this will give us the implied + # testing of both the route-map and staticd withdrawing the route + # let's spot check that the routes were installed correctly + # in the kernel + logger.info("Test that the routes installed are correct") + sharp_ipfile = "%s/r1/iproute.ref" % (thisDir) + expected = open(sharp_ipfile).read().rstrip() + expected = ('\n'.join(expected.splitlines()) + '\n').rstrip() + actual = r1.run("ip route show") + actual = ('\n'.join(actual.splitlines()) + '\n').rstrip() + actual = re.sub(r" nhid [0-9][0-9]", "", actual) + actual = re.sub(r" proto sharp", " proto XXXX", actual) + actual = re.sub(r" proto static", " proto XXXX", actual) + actual = re.sub(r" proto 194", " proto XXXX", actual) + actual = re.sub(r" proto 196", " proto XXXX", actual) + actual = re.sub(r" proto kernel", " proto XXXX", actual) + actual = re.sub(r" proto 2", " proto XXXX", actual) + # Some platforms have double spaces? Why?????? + actual = re.sub(r" proto XXXX ", " proto XXXX ", actual) + actual = re.sub(r" metric", " metric", actual) + actual = re.sub(r" link ", " link ", actual) + diff = topotest.get_textdiff(actual, expected, + title1 = "Actual ip route show", + title2 = "Expected ip route show") + + if diff: + logger.info("Actual:") + logger.info(actual) + logger.info("Expected:") + logger.info(expected) + srun = r1.vtysh_cmd("show run") + srun = ('\n'.join(srun.splitlines()) + '\n').rstrip() + logger.info("Show run:") + logger.info(srun) + assert 0, "r1 ip route show is not correct:" def test_memory_leak(): "Run the memory leak test and report results." diff --git a/tools/frr-reload.py b/tools/frr-reload.py index d5fa8ab6a3..0aa5f1e516 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -221,6 +221,7 @@ ip forwarding for ligne in lines: self.dlines[ligne] = True + def get_normalized_es_id(line): """ The es-id or es-sys-mac need to be converted to lower case @@ -233,6 +234,7 @@ def get_normalized_es_id(line): break return line + def get_normalized_mac_ip_line(line): if line.startswith("evpn mh es"): return get_normalized_es_id(line) @@ -242,6 +244,7 @@ def get_normalized_mac_ip_line(line): return line + class Config(object): """ @@ -640,7 +643,7 @@ end log.debug( "LINE %-50s: popping segment routing sub-context to ctx%-50s", line, - ctx_keys + ctx_keys, ) elif line in ["exit-address-family", "exit", "exit-vnc"]: @@ -654,7 +657,7 @@ end log.debug( "LINE %-50s: popping from subcontext to ctx%-50s", line, - ctx_keys + ctx_keys, ) elif line in ["exit-vni", "exit-ldp-if"]: @@ -755,7 +758,8 @@ end self.save_contexts(ctx_keys, current_context_lines) current_context_lines = [] log.debug( - "LINE %-50s: entering segment routing sub-context, append to ctx_keys", line + "LINE %-50s: entering segment routing sub-context, append to ctx_keys", + line, ) ctx_keys.append(line) @@ -770,7 +774,8 @@ end self.save_contexts(ctx_keys, current_context_lines) current_context_lines = [] log.debug( - "LINE %-50s: entering segment routing sub-context, append to ctx_keys", line + "LINE %-50s: entering segment routing sub-context, append to ctx_keys", + line, ) ctx_keys.append(line) @@ -785,7 +790,8 @@ end self.save_contexts(ctx_keys, current_context_lines) current_context_lines = [] log.debug( - "LINE %-50s: entering segment routing sub-context, append to ctx_keys", line + "LINE %-50s: entering segment routing sub-context, append to ctx_keys", + line, ) ctx_keys.append(line) @@ -803,7 +809,8 @@ end current_context_lines = [] main_ctx_key = copy.deepcopy(ctx_keys) log.debug( - "LINE %-50s: entering candidate-path sub-context, append to ctx_keys", line + "LINE %-50s: entering candidate-path sub-context, append to ctx_keys", + line, ) ctx_keys.append(line) @@ -836,7 +843,8 @@ end current_context_lines = [] main_ctx_key = copy.deepcopy(ctx_keys) log.debug( - "LINE %-50s: entering pce-config sub-context, append to ctx_keys", line + "LINE %-50s: entering pce-config sub-context, append to ctx_keys", + line, ) ctx_keys.append(line) @@ -1230,30 +1238,44 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): lines_to_add_to_del.append((ctx[0], None)) """ - ip/ipv6 prefix-list can be specified without a seq number. However, - the running config always adds 'seq x', where x is a number incremented - by 5 for every element, to the prefix list. So, ignore such lines as - well. Sample prefix-list lines: + ip/ipv6 prefix-lists and access-lists can be specified without a seq number. + However, the running config always adds 'seq x', where x is a number + incremented by 5 for every element of the prefix/access list. + So, ignore such lines as well. Sample prefix-list and acces-list lines: ip prefix-list PR-TABLE-2 seq 5 permit 20.8.2.0/24 le 32 ip prefix-list PR-TABLE-2 seq 10 permit 20.8.2.0/24 le 32 ipv6 prefix-list vrfdev6-12 permit 2000:9:2::/64 gt 64 + access-list FOO seq 5 permit 2.2.2.2/32 + ipv6 access-list BAR seq 5 permit 2:2:2::2/128 """ - re_ip_pfxlst = re.search( - "^(ip|ipv6)(\s+prefix-list\s+)(\S+\s+)(seq \d+\s+)(permit|deny)(.*)$", + re_acl_pfxlst = re.search( + "^(ip |ipv6 |)(prefix-list|access-list)(\s+\S+\s+)(seq \d+\s+)(permit|deny)(.*)$", ctx_keys[0], ) - if re_ip_pfxlst: + if re_acl_pfxlst: + found = False tmpline = ( - re_ip_pfxlst.group(1) - + re_ip_pfxlst.group(2) - + re_ip_pfxlst.group(3) - + re_ip_pfxlst.group(5) - + re_ip_pfxlst.group(6) + re_acl_pfxlst.group(1) + + re_acl_pfxlst.group(2) + + re_acl_pfxlst.group(3) + + re_acl_pfxlst.group(5) + + re_acl_pfxlst.group(6) ) for ctx in lines_to_add: if ctx[0][0] == tmpline: lines_to_del_to_del.append((ctx_keys, None)) lines_to_add_to_del.append(((tmpline,), None)) + found = True + """ + If prefix-lists or access-lists are being deleted and + not added (see comment above), add command with 'no' to + lines_to_add and remove from lines_to_del to improve + scaling performance. + """ + if found is False: + add_cmd = ("no " + ctx_keys[0],) + lines_to_add.append((add_cmd, None)) + lines_to_del_to_del.append((ctx_keys, None)) if ( len(ctx_keys) == 3 @@ -1451,14 +1473,9 @@ def compare_context_objects(newconf, running): # doing vtysh -c inefficient (and can time out.) For # these commands, instead of adding them to lines_to_del, # add the "no " version to lines_to_add. - elif ( - running_ctx_keys[0].startswith("ip route") - or running_ctx_keys[0].startswith("ipv6 route") - or running_ctx_keys[0].startswith("access-list") - or running_ctx_keys[0].startswith("ipv6 access-list") - or running_ctx_keys[0].startswith("ip prefix-list") - or running_ctx_keys[0].startswith("ipv6 prefix-list") - ): + elif running_ctx_keys[0].startswith("ip route") or running_ctx_keys[ + 0 + ].startswith("ipv6 route"): add_cmd = ("no " + running_ctx_keys[0],) lines_to_add.append((add_cmd, None)) @@ -1473,14 +1490,17 @@ def compare_context_objects(newconf, running): continue # same thing for a pseudowire sub-context inside an l2vpn context - elif (len(running_ctx_keys) > 1 and running_ctx_keys[0].startswith('l2vpn') and - running_ctx_keys[1].startswith('member pseudowire') and - (running_ctx_keys[:1], None) in lines_to_del): + elif ( + len(running_ctx_keys) > 1 + and running_ctx_keys[0].startswith("l2vpn") + and running_ctx_keys[1].startswith("member pseudowire") + and (running_ctx_keys[:1], None) in lines_to_del + ): continue # Segment routing and traffic engineering never need to be deleted elif ( - running_ctx_keys[0].startswith('segment-routing') + running_ctx_keys[0].startswith("segment-routing") and len(running_ctx_keys) < 3 ): continue @@ -1488,8 +1508,8 @@ def compare_context_objects(newconf, running): # Neither the pcep command elif ( len(running_ctx_keys) == 3 - and running_ctx_keys[0].startswith('segment-routing') - and running_ctx_keys[2].startswith('pcep') + and running_ctx_keys[0].startswith("segment-routing") + and running_ctx_keys[2].startswith("pcep") ): continue @@ -1497,8 +1517,8 @@ def compare_context_objects(newconf, running): # use them, so add them to a separate array that is going to be appended at the end elif ( len(running_ctx_keys) == 3 - and running_ctx_keys[0].startswith('segment-routing') - and running_ctx_keys[2].startswith('segment-list') + and running_ctx_keys[0].startswith("segment-routing") + and running_ctx_keys[2].startswith("segment-list") ): seglist_to_del.append((running_ctx_keys, None)) @@ -1506,8 +1526,8 @@ def compare_context_objects(newconf, running): # we add them to a separate array that is going to be appended at the end elif ( len(running_ctx_keys) == 3 - and running_ctx_keys[0].startswith('segment-routing') - and running_ctx_keys[2].startswith('policy') + and running_ctx_keys[0].startswith("segment-routing") + and running_ctx_keys[2].startswith("policy") ): pollist_to_del.append((running_ctx_keys, None)) @@ -1515,16 +1535,16 @@ def compare_context_objects(newconf, running): # to a separate array that is going to be appended at the end elif ( len(running_ctx_keys) >= 4 - and running_ctx_keys[0].startswith('segment-routing') - and running_ctx_keys[3].startswith('pce-config') + and running_ctx_keys[0].startswith("segment-routing") + and running_ctx_keys[3].startswith("pce-config") ): pceconf_to_del.append((running_ctx_keys, None)) # pcc must be deleted after the pce and pce-config too elif ( len(running_ctx_keys) >= 4 - and running_ctx_keys[0].startswith('segment-routing') - and running_ctx_keys[3].startswith('pcc') + and running_ctx_keys[0].startswith("segment-routing") + and running_ctx_keys[3].startswith("pcc") ): pcclist_to_del.append((running_ctx_keys, None)) @@ -1572,9 +1592,9 @@ def compare_context_objects(newconf, running): # so add them to a separate array that is going to be appended at the end if ( len(newconf_ctx_keys) == 3 - and newconf_ctx_keys[0].startswith('segment-routing') - and newconf_ctx_keys[2].startswith('policy ') - and line.startswith('candidate-path ') + and newconf_ctx_keys[0].startswith("segment-routing") + and newconf_ctx_keys[2].startswith("policy ") + and line.startswith("candidate-path ") ): candidates_to_add.append((newconf_ctx_keys, line)) @@ -1593,8 +1613,8 @@ def compare_context_objects(newconf, running): # so add them to a separate array that is going to be appended at the end if ( len(newconf_ctx_keys) == 4 - and newconf_ctx_keys[0].startswith('segment-routing') - and newconf_ctx_keys[3].startswith('candidate-path') + and newconf_ctx_keys[0].startswith("segment-routing") + and newconf_ctx_keys[3].startswith("candidate-path") ): candidates_to_add.append((newconf_ctx_keys, None)) for line in newconf_ctx.lines: @@ -1823,8 +1843,6 @@ if __name__ == "__main__": else: running.load_from_show_running(args.daemon) - - (lines_to_add, lines_to_del) = compare_context_objects(newconf, running) lines_to_configure = [] diff --git a/yang/frr-bgp.yang b/yang/frr-bgp.yang index 2fb5d13fa7..24998a470d 100644 --- a/yang/frr-bgp.yang +++ b/yang/frr-bgp.yang @@ -598,6 +598,8 @@ module frr-bgp { uses structure-neighbor-group-soft-reconfiguration; uses structure-neighbor-weight; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast" { @@ -626,6 +628,8 @@ module frr-bgp { uses structure-neighbor-group-soft-reconfiguration; uses structure-neighbor-weight; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast" { @@ -654,7 +658,9 @@ module frr-bgp { uses structure-neighbor-group-soft-reconfiguration; uses structure-neighbor-weight; - } + + uses structure-neighbor-group-filter-config; + } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast" { uses structure-neighbor-group-add-paths; @@ -682,6 +688,8 @@ module frr-bgp { uses structure-neighbor-group-soft-reconfiguration; uses structure-neighbor-weight; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast" { @@ -710,6 +718,8 @@ module frr-bgp { uses structure-neighbor-group-soft-reconfiguration; uses structure-neighbor-weight; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast" { @@ -734,6 +744,8 @@ module frr-bgp { uses structure-neighbor-group-soft-reconfiguration; uses structure-neighbor-weight; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast" { @@ -758,6 +770,8 @@ module frr-bgp { uses structure-neighbor-group-soft-reconfiguration; uses structure-neighbor-weight; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn" { @@ -772,6 +786,8 @@ module frr-bgp { uses structure-neighbor-route-server; uses structure-neighbor-group-soft-reconfiguration; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec" { @@ -780,6 +796,8 @@ module frr-bgp { uses structure-neighbor-route-server; uses structure-neighbor-group-soft-reconfiguration; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec" { @@ -788,6 +806,8 @@ module frr-bgp { uses structure-neighbor-route-server; uses structure-neighbor-group-soft-reconfiguration; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast" { @@ -855,6 +875,8 @@ module frr-bgp { uses structure-neighbor-group-soft-reconfiguration; uses structure-neighbor-weight; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast" { @@ -883,6 +905,8 @@ module frr-bgp { uses structure-neighbor-group-soft-reconfiguration; uses structure-neighbor-weight; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast" { @@ -911,6 +935,8 @@ module frr-bgp { uses structure-neighbor-group-soft-reconfiguration; uses structure-neighbor-weight; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast" { @@ -939,6 +965,8 @@ module frr-bgp { uses structure-neighbor-group-soft-reconfiguration; uses structure-neighbor-weight; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast" { @@ -1037,6 +1065,8 @@ module frr-bgp { uses structure-neighbor-route-server; uses structure-neighbor-group-soft-reconfiguration; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec" { @@ -1045,6 +1075,8 @@ module frr-bgp { uses structure-neighbor-route-server; uses structure-neighbor-group-soft-reconfiguration; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast" { @@ -1112,6 +1144,8 @@ module frr-bgp { uses structure-neighbor-group-soft-reconfiguration; uses structure-neighbor-weight; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast" { @@ -1140,6 +1174,8 @@ module frr-bgp { uses structure-neighbor-group-soft-reconfiguration; uses structure-neighbor-weight; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast" { @@ -1168,6 +1204,8 @@ module frr-bgp { uses structure-neighbor-group-soft-reconfiguration; uses structure-neighbor-weight; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast" { @@ -1196,6 +1234,8 @@ module frr-bgp { uses structure-neighbor-group-soft-reconfiguration; uses structure-neighbor-weight; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast" { @@ -1224,6 +1264,8 @@ module frr-bgp { uses structure-neighbor-group-soft-reconfiguration; uses structure-neighbor-weight; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast" { @@ -1248,6 +1290,8 @@ module frr-bgp { uses structure-neighbor-group-soft-reconfiguration; uses structure-neighbor-weight; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast" { @@ -1272,6 +1316,8 @@ module frr-bgp { uses structure-neighbor-group-soft-reconfiguration; uses structure-neighbor-weight; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn" { @@ -1294,6 +1340,8 @@ module frr-bgp { uses structure-neighbor-route-server; uses structure-neighbor-group-soft-reconfiguration; + + uses structure-neighbor-group-filter-config; } augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec" { @@ -1302,5 +1350,7 @@ module frr-bgp { uses structure-neighbor-route-server; uses structure-neighbor-group-soft-reconfiguration; + + uses structure-neighbor-group-filter-config; } } diff --git a/yang/frr-isisd.yang b/yang/frr-isisd.yang index d751a19f07..812dd4159d 100644 --- a/yang/frr-isisd.yang +++ b/yang/frr-isisd.yang @@ -248,6 +248,10 @@ module frr-isisd { type string; } + typedef prefix-list-ref { + type string; + } + grouping redistribute-attributes { description "Common optional attributes of any redistribute entry."; @@ -410,6 +414,19 @@ module frr-isisd { } } + grouping global-config-remote-lfa { + container remote-lfa { + description + "Remote LFA configuration."; + + leaf prefix-list { + type prefix-list-ref; + description + "Filter PQ node router ID based on prefix list."; + } + } + } + grouping interface-config-lfa { container lfa { description @@ -428,6 +445,32 @@ module frr-isisd { } } + grouping interface-config-remote-lfa { + container remote-lfa { + description + "Remote LFA configuration."; + + leaf enable { + type boolean; + default false; + description + "Enables remote LFA computation using LDP tunnels."; + must ". = 'false' or ../../lfa/enable = 'true'" { + error-message + "Remote LFA depends on classic LFA being configured in the interface."; + } + + } + leaf maximum-metric { + type uint32 { + range "1..16777215"; + } + description + "Limit remote LFA node selection within the metric."; + } + } + } + grouping interface-config-ti-lfa { container ti-lfa { description @@ -761,6 +804,7 @@ module frr-isisd { "Can't enable both classic LFA and TI-LFA in the same interface."; } uses interface-config-lfa; + uses interface-config-remote-lfa; uses interface-config-ti-lfa; } container level-2 { @@ -771,6 +815,7 @@ module frr-isisd { "Can't enable both classic LFA and TI-LFA in the same interface."; } uses interface-config-lfa; + uses interface-config-remote-lfa; uses interface-config-ti-lfa; } } @@ -1394,11 +1439,13 @@ module frr-isisd { description "Level-1 IP Fast-reroute configuration."; uses global-config-lfa; + uses global-config-remote-lfa; } container level-2 { description "Level-2 IP Fast-reroute configuration."; uses global-config-lfa; + uses global-config-remote-lfa; } } diff --git a/yang/frr-nexthop.yang b/yang/frr-nexthop.yang index 619514de7d..2df2e2958e 100644 --- a/yang/frr-nexthop.yang +++ b/yang/frr-nexthop.yang @@ -61,7 +61,7 @@ module frr-nexthop { type union { type inet:ip-address; type string { - pattern ''; + pattern ""; } } } @@ -160,6 +160,7 @@ module frr-nexthop { description "The nexthop vrf name, if different from the route."; } + leaf gateway { type frr-nexthop:optional-ip-address; description @@ -173,15 +174,12 @@ module frr-nexthop { } leaf bh-type { - when "../nh-type = 'blackhole'"; type blackhole-type; description "A blackhole sub-type, if the nexthop is a blackhole type."; } leaf onlink { - when "../nh-type = 'ip4-ifindex' or - ../nh-type = 'ip6-ifindex'"; type boolean; default "false"; description diff --git a/yang/frr-staticd.yang b/yang/frr-staticd.yang index 281b4903c0..98ff3a83c6 100644 --- a/yang/frr-staticd.yang +++ b/yang/frr-staticd.yang @@ -63,7 +63,13 @@ module frr-staticd { grouping staticd-prefix-attributes { list path-list { - key "distance"; + key "table-id distance"; + leaf table-id { + type uint32; + description + "Table-id"; + } + leaf distance { type frr-rt:administrative-distance; description @@ -77,13 +83,6 @@ module frr-staticd { "Route tag"; } - leaf table-id { - type uint32; - default "0"; - description - "Table-id"; - } - uses frr-nexthop:frr-nexthop; } } diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c index 51ce59c477..bf733e38f7 100644 --- a/zebra/dplane_fpm_nl.c +++ b/zebra/dplane_fpm_nl.c @@ -1236,7 +1236,13 @@ static int fpm_process_queue(struct thread *t) if (ctx == NULL) break; - fpm_nl_enqueue(fnc, ctx); + /* + * Intentionally ignoring the return value + * as that we are ensuring that we can write to + * the output data in the STREAM_WRITEABLE + * check above, so we can ignore the return + */ + (void)fpm_nl_enqueue(fnc, ctx); /* Account the processed entries. */ processed_contexts++; diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index 5d64f57b3e..bbe2fccc60 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -489,6 +489,19 @@ static void netlink_install_filter(int sock, __u32 pid, __u32 dplane_pid) safe_strerror(errno)); } +void netlink_parse_rtattr_flags(struct rtattr **tb, int max, + struct rtattr *rta, int len, unsigned short flags) +{ + unsigned short type; + + while (RTA_OK(rta, len)) { + type = rta->rta_type & ~flags; + if ((type <= max) && (!tb[type])) + tb[type] = rta; + rta = RTA_NEXT(rta, len); + } +} + void netlink_parse_rtattr(struct rtattr **tb, int max, struct rtattr *rta, int len) { diff --git a/zebra/kernel_netlink.h b/zebra/kernel_netlink.h index 696f9be4f6..a7b152b31b 100644 --- a/zebra/kernel_netlink.h +++ b/zebra/kernel_netlink.h @@ -79,6 +79,9 @@ extern void nl_attr_rtnh_end(struct nlmsghdr *n, struct rtnexthop *rtnh); extern void netlink_parse_rtattr(struct rtattr **tb, int max, struct rtattr *rta, int len); +extern void netlink_parse_rtattr_flags(struct rtattr **tb, int max, + struct rtattr *rta, int len, + unsigned short flags); extern void netlink_parse_rtattr_nested(struct rtattr **tb, int max, struct rtattr *rta); extern const char *nl_msg_type_to_str(uint16_t msg_type); diff --git a/zebra/rib.h b/zebra/rib.h index d653425f0d..86766b8175 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -406,9 +406,8 @@ extern struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p, vrf_id_t vrf_id); extern void rib_update(enum rib_update_event event); -extern void rib_update_vrf(vrf_id_t vrf_id, enum rib_update_event event); extern void rib_update_table(struct route_table *table, - enum rib_update_event event); + enum rib_update_event event, int rtype); extern int rib_sweep_route(struct thread *t); extern void rib_sweep_table(struct route_table *table); extern void rib_close_table(struct route_table *table); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 547700d0c5..d96d77e77c 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -77,16 +77,7 @@ /* Re-defining as I am unable to include <linux/if_bridge.h> which has the * UAPI for MAC sync. */ #ifndef _UAPI_LINUX_IF_BRIDGE_H -/* FDB notification bits for NDA_NOTIFY: - * - BR_FDB_NFY_STATIC - notify on activity/expire even for a static entry - * - BR_FDB_NFY_INACTIVE - mark as inactive to avoid double notification, - * used with BR_FDB_NFY_STATIC (kernel controlled) - */ -enum { - BR_FDB_NFY_STATIC, - BR_FDB_NFY_INACTIVE, - BR_FDB_NFY_MAX -}; +#define BR_SPH_LIST_SIZE 10 #endif static vlanid_t filter_vlan = 0; @@ -2766,11 +2757,23 @@ static ssize_t netlink_neigh_update_msg_encode( } if (nfy) { - if (!nl_attr_put(&req->n, datalen, NDA_NOTIFY, - &nfy_flags, sizeof(nfy_flags))) + struct rtattr *nest; + + nest = nl_attr_nest(&req->n, datalen, + NDA_FDB_EXT_ATTRS | NLA_F_NESTED); + if (!nest) + return 0; + + if (!nl_attr_put(&req->n, datalen, NFEA_ACTIVITY_NOTIFY, + &nfy_flags, sizeof(nfy_flags))) + return 0; + if (!nl_attr_put(&req->n, datalen, NFEA_DONT_REFRESH, NULL, 0)) return 0; + + nl_attr_nest_end(&req->n, nest); } + if (ext) { if (!nl_attr_put(&req->n, datalen, NDA_EXT_FLAGS, &ext_flags, sizeof(ext_flags))) @@ -2855,7 +2858,8 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id) * validation of the fields. */ memset(tb, 0, sizeof tb); - netlink_parse_rtattr(tb, NDA_MAX, NDA_RTA(ndm), len); + netlink_parse_rtattr_flags(tb, NDA_MAX, NDA_RTA(ndm), len, + NLA_F_NESTED); if (!tb[NDA_LLADDR]) { if (IS_ZEBRA_DEBUG_KERNEL) @@ -2897,14 +2901,21 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id) if (ndm->ndm_state & NUD_STALE) local_inactive = true; - if (tb[NDA_NOTIFY]) { - uint8_t nfy_flags; + if (tb[NDA_FDB_EXT_ATTRS]) { + struct rtattr *attr = tb[NDA_FDB_EXT_ATTRS]; + struct rtattr *nfea_tb[NFEA_MAX + 1] = {0}; - dp_static = true; - nfy_flags = *(uint8_t *)RTA_DATA(tb[NDA_NOTIFY]); - /* local activity has not been detected on the entry */ - if (nfy_flags & (1 << BR_FDB_NFY_INACTIVE)) - local_inactive = true; + netlink_parse_rtattr_nested(nfea_tb, NFEA_MAX, attr); + if (nfea_tb[NFEA_ACTIVITY_NOTIFY]) { + uint8_t nfy_flags; + + nfy_flags = *(uint8_t *)RTA_DATA( + nfea_tb[NFEA_ACTIVITY_NOTIFY]); + if (nfy_flags & FDB_NOTIFY_BIT) + dp_static = true; + if (nfy_flags & FDB_NOTIFY_INACTIVE_BIT) + local_inactive = true; + } } if (IS_ZEBRA_DEBUG_KERNEL) @@ -3206,12 +3217,12 @@ ssize_t netlink_macfdb_update_ctx(struct zebra_dplane_ctx *ctx, void *data, } else { /* local mac */ if (update_flags & DPLANE_MAC_SET_STATIC) { - nfy_flags |= (1 << BR_FDB_NFY_STATIC); + nfy_flags |= FDB_NOTIFY_BIT; state |= NUD_NOARP; } if (update_flags & DPLANE_MAC_SET_INACTIVE) - nfy_flags |= (1 << BR_FDB_NFY_INACTIVE); + nfy_flags |= FDB_NOTIFY_INACTIVE_BIT; nfy = true; } diff --git a/zebra/sample_plugin.c b/zebra/sample_plugin.c index c96a86cc73..464205f2f3 100644 --- a/zebra/sample_plugin.c +++ b/zebra/sample_plugin.c @@ -92,7 +92,6 @@ static int sample_process(struct zebra_dplane_provider *prov) static int init_sample_plugin(struct thread_master *tm) { int ret; - struct zebra_dplane_provider *prov = NULL; /* Note that we don't use or store the thread_master 'tm'. We * don't use the zebra main pthread: our plugin code will run in diff --git a/zebra/subdir.am b/zebra/subdir.am index cdacabc102..f842a8c0f3 100644 --- a/zebra/subdir.am +++ b/zebra/subdir.am @@ -40,6 +40,11 @@ if LINUX module_LTLIBRARIES += zebra/zebra_cumulus_mlag.la endif +# Dataplane sample plugin +if DEV_BUILD +module_LTLIBRARIES += zebra/dplane_sample_plugin.la +endif + man8 += $(MANBUILD)/frr-zebra.8 ## endif ZEBRA endif @@ -206,6 +211,12 @@ zebra/zebra_fpm_dt.lo: fpm/fpm.pb-c.h qpb/qpb.pb-c.h endif endif +# Sample dataplane plugin +if DEV_BUILD +zebra_dplane_sample_plugin_la_SOURCES = zebra/sample_plugin.c +zebra_dplane_sample_plugin_la_LDFLAGS = -module -shared -avoid-version -export-dynamic +endif + nodist_zebra_zebra_SOURCES = \ yang/frr-zebra.yang.c \ # end diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index da7f4cf64e..db2b9e002e 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -3684,7 +3684,7 @@ int dplane_show_helper(struct vty *vty, bool detailed) int dplane_show_provs_helper(struct vty *vty, bool detailed) { struct zebra_dplane_provider *prov; - uint64_t in, in_max, out, out_max; + uint64_t in, in_q, in_max, out, out_q, out_max; vty_out(vty, "Zebra dataplane providers:\n"); @@ -3697,17 +3697,20 @@ int dplane_show_provs_helper(struct vty *vty, bool detailed) in = atomic_load_explicit(&prov->dp_in_counter, memory_order_relaxed); + in_q = atomic_load_explicit(&prov->dp_in_queued, + memory_order_relaxed); in_max = atomic_load_explicit(&prov->dp_in_max, memory_order_relaxed); out = atomic_load_explicit(&prov->dp_out_counter, memory_order_relaxed); + out_q = atomic_load_explicit(&prov->dp_out_queued, + memory_order_relaxed); out_max = atomic_load_explicit(&prov->dp_out_max, memory_order_relaxed); - vty_out(vty, - "%s (%u): in: %" PRIu64 ", q_max: %" PRIu64 - ", out: %" PRIu64 ", q_max: %" PRIu64 "\n", - prov->dp_name, prov->dp_id, in, in_max, out, out_max); + vty_out(vty, "%s (%u): in: %"PRIu64", q: %"PRIu64", q_max: %"PRIu64", out: %"PRIu64", q: %"PRIu64", q_max: %"PRIu64"\n", + prov->dp_name, prov->dp_id, in, in_q, in_max, + out, out_q, out_max); DPLANE_LOCK(); prov = TAILQ_NEXT(prov, dp_prov_link); @@ -3912,11 +3915,24 @@ uint32_t dplane_provider_out_ctx_queue_len(struct zebra_dplane_provider *prov) void dplane_provider_enqueue_out_ctx(struct zebra_dplane_provider *prov, struct zebra_dplane_ctx *ctx) { + uint64_t curr, high; + dplane_provider_lock(prov); TAILQ_INSERT_TAIL(&(prov->dp_ctx_out_q), ctx, zd_q_entries); + /* Maintain out-queue counters */ + atomic_fetch_add_explicit(&(prov->dp_out_queued), 1, + memory_order_relaxed); + curr = atomic_load_explicit(&prov->dp_out_queued, + memory_order_relaxed); + high = atomic_load_explicit(&prov->dp_out_max, + memory_order_relaxed); + if (curr > high) + atomic_store_explicit(&prov->dp_out_max, curr, + memory_order_relaxed); + dplane_provider_unlock(prov); atomic_fetch_add_explicit(&(prov->dp_out_counter), 1, diff --git a/zebra/zebra_evpn_mac.c b/zebra/zebra_evpn_mac.c index 376721f83a..6753bf520c 100644 --- a/zebra/zebra_evpn_mac.c +++ b/zebra/zebra_evpn_mac.c @@ -29,6 +29,7 @@ #include "prefix.h" #include "vlan.h" #include "json.h" +#include "printfrr.h" #include "zebra/zserv.h" #include "zebra/debug.h" @@ -254,6 +255,37 @@ static void zebra_evpn_mac_get_access_info(zebra_mac_t *mac, } } +#define MAC_BUF_SIZE 256 +static char *zebra_evpn_zebra_mac_flag_dump(struct zebra_mac_t_ *mac, char *buf, + size_t len) +{ + if (mac->flags == 0) { + snprintfrr(buf, len, "None "); + return buf; + } + + snprintfrr( + buf, len, "%s%s%s%s%s%s%s%s%s%s%s%s", + CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL) ? "LOC " : "", + CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) ? "REM " : "", + CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO) ? "AUTO " : "", + CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? "STICKY " : "", + CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_RMAC) ? "REM Router " + : "", + CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW) ? "Default GW " : "", + CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW) ? "REM DEF GW " + : "", + CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE) ? "DUP " : "", + CHECK_FLAG(mac->flags, ZEBRA_MAC_FPM_SENT) ? "FPM " : "", + CHECK_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_ACTIVE) ? "LOC Active " + : "", + CHECK_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_PROXY) ? "PROXY " : "", + CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE) + ? "LOC Inactive " + : ""); + return buf; +} + static int zebra_evpn_dad_mac_auto_recovery_exp(struct thread *t) { struct zebra_vrf *zvrf = NULL; @@ -278,12 +310,17 @@ static int zebra_evpn_dad_mac_auto_recovery_exp(struct thread *t) if (!mac) return 0; - if (IS_ZEBRA_DEBUG_VXLAN) + if (IS_ZEBRA_DEBUG_VXLAN) { + char mac_buf[MAC_BUF_SIZE]; + zlog_debug( - "%s: duplicate addr mac %s flags 0x%x learn count %u host count %u auto recovery expired", + "%s: duplicate addr mac %s flags %slearn count %u host count %u auto recovery expired", __func__, prefix_mac2str(&mac->macaddr, buf, sizeof(buf)), - mac->flags, mac->dad_count, listcount(mac->neigh_list)); + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf)), + mac->dad_count, listcount(mac->neigh_list)); + } /* Remove all IPs as duplicate associcated with this MAC */ for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) { @@ -350,14 +387,17 @@ static void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf, * Remote MAC event -> hold on installing it. */ if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) { - if (IS_ZEBRA_DEBUG_VXLAN) + if (IS_ZEBRA_DEBUG_VXLAN) { + char mac_buf[MAC_BUF_SIZE]; + zlog_debug( - "%s: duplicate addr MAC %s flags 0x%x skip update to client, learn count %u recover time %u", + "%s: duplicate addr MAC %s flags %sskip update to client, learn count %u recover time %u", __func__, prefix_mac2str(&mac->macaddr, buf, sizeof(buf)), - mac->flags, mac->dad_count, - zvrf->dad_freeze_time); - + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf)), + mac->dad_count, zvrf->dad_freeze_time); + } /* For duplicate MAC do not update * client but update neigh due to * this MAC update. @@ -385,12 +425,17 @@ static void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf, } if (reset_params) { - if (IS_ZEBRA_DEBUG_VXLAN) + if (IS_ZEBRA_DEBUG_VXLAN) { + char mac_buf[MAC_BUF_SIZE]; + zlog_debug( - "%s: duplicate addr MAC %s flags 0x%x detection time passed, reset learn count %u", + "%s: duplicate addr MAC %s flags %sdetection time passed, reset learn count %u", __func__, prefix_mac2str(&mac->macaddr, buf, sizeof(buf)), - mac->flags, mac->dad_count); + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf)), + mac->dad_count); + } mac->dad_count = 0; /* Start dup. addr detection (DAD) start time, @@ -452,13 +497,18 @@ static void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf, /* Start auto recovery timer for this MAC */ THREAD_OFF(mac->dad_mac_auto_recovery_timer); if (zvrf->dad_freeze && zvrf->dad_freeze_time) { - if (IS_ZEBRA_DEBUG_VXLAN) + if (IS_ZEBRA_DEBUG_VXLAN) { + char mac_buf[MAC_BUF_SIZE]; + zlog_debug( - "%s: duplicate addr MAC %s flags 0x%x auto recovery time %u start", + "%s: duplicate addr MAC %s flags %sauto recovery time %u start", __func__, prefix_mac2str(&mac->macaddr, buf, sizeof(buf)), - mac->flags, zvrf->dad_freeze_time); + zebra_evpn_zebra_mac_flag_dump( + mac, mac_buf, sizeof(mac_buf)), + zvrf->dad_freeze_time); + } thread_add_timer(zrouter.master, zebra_evpn_dad_mac_auto_recovery_exp, @@ -694,7 +744,7 @@ void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json) } static char *zebra_evpn_print_mac_flags(zebra_mac_t *mac, char *flags_buf, - uint32_t flags_buf_sz) + size_t flags_buf_sz) { snprintf(flags_buf, flags_buf_sz, "%s%s%s%s", mac->sync_neigh_cnt ? @@ -903,14 +953,19 @@ int zebra_evpn_macip_send_msg_to_client(vni_t vni, struct ethaddr *macaddr, /* Write packet size. */ stream_putw_at(s, 0, stream_get_endp(s)); - if (IS_ZEBRA_DEBUG_VXLAN) + if (IS_ZEBRA_DEBUG_VXLAN) { + char flag_buf[MACIP_BUF_SIZE]; + zlog_debug( - "Send MACIP %s f 0x%x MAC %s IP %s seq %u L2-VNI %u ESI %s to %s", - (cmd == ZEBRA_MACIP_ADD) ? "Add" : "Del", flags, + "Send MACIP %s f %s MAC %s IP %s seq %u L2-VNI %u ESI %s to %s", + (cmd == ZEBRA_MACIP_ADD) ? "Add" : "Del", + zclient_evpn_dump_macip_flags(flags, flag_buf, + sizeof(flag_buf)), prefix_mac2str(macaddr, buf, sizeof(buf)), ipaddr2str(ip, buf2, sizeof(buf2)), seq, vni, es ? es->esi_str : "-", zebra_route_string(client->proto)); + } if (cmd == ZEBRA_MACIP_ADD) client->macipadd_cnt++; @@ -982,10 +1037,12 @@ zebra_mac_t *zebra_evpn_mac_add(zebra_evpn_t *zevpn, struct ethaddr *macaddr) mac->uptime = monotime(NULL); if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC) { char buf[ETHER_ADDR_STRLEN]; + char mac_buf[MAC_BUF_SIZE]; - zlog_debug("%s: MAC %s flags 0x%x", __func__, + zlog_debug("%s: MAC %s flags %s", __func__, prefix_mac2str(&mac->macaddr, buf, sizeof(buf)), - mac->flags); + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf))); } return mac; } @@ -999,10 +1056,12 @@ int zebra_evpn_mac_del(zebra_evpn_t *zevpn, zebra_mac_t *mac) if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC) { char buf[ETHER_ADDR_STRLEN]; + char mac_buf[MAC_BUF_SIZE]; - zlog_debug("%s: MAC %s flags 0x%x", __func__, + zlog_debug("%s: MAC %s flags %s", __func__, prefix_mac2str(&mac->macaddr, buf, sizeof(buf)), - mac->flags); + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf))); } /* If the MAC is freed before the neigh we will end up @@ -1047,11 +1106,13 @@ static bool zebra_evpn_check_mac_del_from_db(struct mac_walk_ctx *wctx, && !listcount(mac->neigh_list)) { if (IS_ZEBRA_DEBUG_VXLAN) { char buf[ETHER_ADDR_STRLEN]; + char mac_buf[MAC_BUF_SIZE]; zlog_debug( - "%s: Del MAC %s flags 0x%x", __func__, + "%s: Del MAC %s flags %s", __func__, prefix_mac2str(&mac->macaddr, buf, sizeof(buf)), - mac->flags); + zebra_evpn_zebra_mac_flag_dump( + mac, mac_buf, sizeof(mac_buf))); } wctx->uninstall = 0; @@ -1204,24 +1265,34 @@ int zebra_evpn_sync_mac_dp_install(zebra_mac_t *mac, bool set_inactive, zebra_evpn_mac_get_access_info(mac, &ifp, &vid); if (!ifp) { - if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) { + char mac_buf[MAC_BUF_SIZE]; + zlog_debug( - "%s: dp-install sync-mac vni %u mac %pEA es %s 0x%x %sskipped, no access-port", + "%s: dp-install sync-mac vni %u mac %pEA es %s %s%sskipped, no access-port", caller, zevpn->vni, &mac->macaddr, - mac->es ? mac->es->esi_str : "-", mac->flags, + mac->es ? mac->es->esi_str : "-", + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf)), set_inactive ? "inactive " : ""); + } return -1; } zif = ifp->info; br_ifp = zif->brslave_info.br_if; if (!br_ifp) { - if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) { + char mac_buf[MAC_BUF_SIZE]; + zlog_debug( - "%s: dp-install sync-mac vni %u mac %pEA es %s 0x%x %sskipped, no br", + "%s: dp-install sync-mac vni %u mac %pEA es %s %s%sskipped, no br", caller, zevpn->vni, &mac->macaddr, - mac->es ? mac->es->esi_str : "-", mac->flags, + mac->es ? mac->es->esi_str : "-", + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf)), set_inactive ? "inactive " : ""); + } return -1; } @@ -1236,13 +1307,18 @@ int zebra_evpn_sync_mac_dp_install(zebra_mac_t *mac, bool set_inactive, * supported and if the local ES is oper-down. */ if (mac->es && zebra_evpn_es_local_mac_via_network_port(mac->es)) { - if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) { + char mac_buf[MAC_BUF_SIZE]; + zlog_debug( - "dp-%s sync-nw-mac vni %u mac %pEA es %s 0x%x %s", + "dp-%s sync-nw-mac vni %u mac %pEA es %s %s%s", set_static ? "install" : "uninstall", zevpn->vni, &mac->macaddr, - mac->es ? mac->es->esi_str : "-", mac->flags, + mac->es ? mac->es->esi_str : "-", + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf)), set_inactive ? "inactive " : ""); + } if (set_static) /* XXX - old_static needs to be computed more * accurately @@ -1256,13 +1332,17 @@ int zebra_evpn_sync_mac_dp_install(zebra_mac_t *mac, bool set_inactive, return 0; } - if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) - zlog_debug( - "dp-install sync-mac vni %u mac %pEA es %s 0x%x %s%s", - zevpn->vni, &mac->macaddr, - mac->es ? mac->es->esi_str : "-", mac->flags, - set_static ? "static " : "", - set_inactive ? "inactive " : ""); + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) { + char mac_buf[MAC_BUF_SIZE]; + + zlog_debug("dp-install sync-mac vni %u mac %pEA es %s %s%s%s", + zevpn->vni, &mac->macaddr, + mac->es ? mac->es->esi_str : "-", + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf)), + set_static ? "static " : "", + set_inactive ? "inactive " : ""); + } dplane_local_mac_add(ifp, br_ifp, vid, &mac->macaddr, sticky, set_static, set_inactive); @@ -1310,12 +1390,17 @@ static int zebra_evpn_mac_hold_exp_cb(struct thread *t) new_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags); new_static = zebra_evpn_mac_is_static(mac); - if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) { + char mac_buf[MAC_BUF_SIZE]; + zlog_debug( - "sync-mac vni %u mac %s es %s 0x%x hold expired", + "sync-mac vni %u mac %s es %s %shold expired", mac->zevpn->vni, prefix_mac2str(&mac->macaddr, macbuf, sizeof(macbuf)), - mac->es ? mac->es->esi_str : "-", mac->flags); + mac->es ? mac->es->esi_str : "-", + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf))); + } /* re-program the local mac in the dataplane if the mac is no * longer static @@ -1340,12 +1425,17 @@ static inline void zebra_evpn_mac_start_hold_timer(zebra_mac_t *mac) if (mac->hold_timer) return; - if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) { + char mac_buf[MAC_BUF_SIZE]; + zlog_debug( - "sync-mac vni %u mac %s es %s 0x%x hold started", + "sync-mac vni %u mac %s es %s %shold started", mac->zevpn->vni, prefix_mac2str(&mac->macaddr, macbuf, sizeof(macbuf)), - mac->es ? mac->es->esi_str : "-", mac->flags); + mac->es ? mac->es->esi_str : "-", + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf))); + } thread_add_timer(zrouter.master, zebra_evpn_mac_hold_exp_cb, mac, zmh_info->mac_hold_time, &mac->hold_timer); } @@ -1357,12 +1447,18 @@ void zebra_evpn_mac_stop_hold_timer(zebra_mac_t *mac) if (!mac->hold_timer) return; - if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) { + char mac_buf[MAC_BUF_SIZE]; + zlog_debug( - "sync-mac vni %u mac %s es %s 0x%x hold stopped", + "sync-mac vni %u mac %s es %s %shold stopped", mac->zevpn->vni, prefix_mac2str(&mac->macaddr, macbuf, sizeof(macbuf)), - mac->es ? mac->es->esi_str : "-", mac->flags); + mac->es ? mac->es->esi_str : "-", + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf))); + } + THREAD_OFF(mac->hold_timer); } @@ -1372,13 +1468,18 @@ void zebra_evpn_sync_mac_del(zebra_mac_t *mac) bool old_static; bool new_static; - if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) { + char mac_buf[MAC_BUF_SIZE]; + zlog_debug( - "sync-mac del vni %u mac %s es %s seq %d f 0x%x", + "sync-mac del vni %u mac %s es %s seq %d f %s", mac->zevpn->vni, prefix_mac2str(&mac->macaddr, macbuf, sizeof(macbuf)), mac->es ? mac->es->esi_str : "-", mac->loc_seq, - mac->flags); + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf))); + } + old_static = zebra_evpn_mac_is_static(mac); UNSET_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_PROXY); if (CHECK_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_ACTIVE)) @@ -1418,9 +1519,12 @@ static inline bool zebra_evpn_mac_is_bgp_seq_ok(zebra_evpn_t *zevpn, */ if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL) && !zebra_evpn_mac_is_ready_for_bgp(mac->flags)) { - if (IS_ZEBRA_DEBUG_EVPN_MH_MAC || IS_ZEBRA_DEBUG_VXLAN) + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC + || IS_ZEBRA_DEBUG_VXLAN) { + char mac_buf[MAC_BUF_SIZE]; + zlog_debug( - "%s-macip accept vni %u %s-mac %s%s%s lower seq %u f 0x%x", + "%s-macip accept vni %u %s-mac %s%s%s lower seq %u f %s", sync ? "sync" : "rem", zevpn->vni, n_type, prefix_mac2str(&mac->macaddr, macbuf, @@ -1429,13 +1533,19 @@ static inline bool zebra_evpn_mac_is_bgp_seq_ok(zebra_evpn_t *zevpn, ipa_len ? ipaddr2str(ipaddr, ipbuf, sizeof(ipbuf)) : "", - tmp_seq, mac->flags); + tmp_seq, + zebra_evpn_zebra_mac_flag_dump( + mac, mac_buf, sizeof(mac_buf))); + } + return true; } - if (IS_ZEBRA_DEBUG_EVPN_MH_MAC || IS_ZEBRA_DEBUG_VXLAN) + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC || IS_ZEBRA_DEBUG_VXLAN) { + char mac_buf[MAC_BUF_SIZE]; + zlog_debug( - "%s-macip ignore vni %u %s-mac %s%s%s as existing has higher seq %u f 0x%x", + "%s-macip ignore vni %u %s-mac %s%s%s as existing has higher seq %u f %s", sync ? "sync" : "rem", zevpn->vni, n_type, prefix_mac2str(&mac->macaddr, macbuf, sizeof(macbuf)), @@ -1443,7 +1553,10 @@ static inline bool zebra_evpn_mac_is_bgp_seq_ok(zebra_evpn_t *zevpn, ipa_len ? ipaddr2str(ipaddr, ipbuf, sizeof(ipbuf)) : "", - tmp_seq, mac->flags); + tmp_seq, + zebra_evpn_zebra_mac_flag_dump( + mac, mac_buf, sizeof(mac_buf))); + } return false; } @@ -1574,12 +1687,20 @@ zebra_evpn_proc_sync_mac_update(zebra_evpn_t *zevpn, struct ethaddr *macaddr, memset(&mac->fwd_info, 0, sizeof(mac->fwd_info)); mac->flags = new_flags; - if (IS_ZEBRA_DEBUG_EVPN_MH_MAC && (old_flags != new_flags)) + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC && (old_flags != new_flags)) { + char mac_buf[MAC_BUF_SIZE], omac_buf[MAC_BUF_SIZE]; + struct zebra_mac_t_ omac; + + omac.flags = old_flags; zlog_debug( - "sync-mac vni %u mac %s old_f 0x%x new_f 0x%x", + "sync-mac vni %u mac %s old_f %snew_f %s", zevpn->vni, prefix_mac2str(macaddr, macbuf, sizeof(macbuf)), - old_flags, mac->flags); + zebra_evpn_zebra_mac_flag_dump( + &omac, omac_buf, sizeof(omac_buf)), + zebra_evpn_zebra_mac_flag_dump( + mac, mac_buf, sizeof(mac_buf))); + } /* update es */ es_change = zebra_evpn_es_mac_ref(mac, esi); @@ -1613,13 +1734,18 @@ zebra_evpn_proc_sync_mac_update(zebra_evpn_t *zevpn, struct ethaddr *macaddr, inform_bgp = true; } - if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) - zlog_debug("sync-mac %s vni %u mac %s es %s seq %d f 0x%x%s%s", + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) { + char mac_buf[MAC_BUF_SIZE]; + + zlog_debug("sync-mac %s vni %u mac %s es %s seq %d f %s%s%s", ctx->mac_created ? "created" : "updated", zevpn->vni, prefix_mac2str(macaddr, macbuf, sizeof(macbuf)), mac->es ? mac->es->esi_str : "-", mac->loc_seq, - mac->flags, inform_bgp ? " inform_bgp" : "", + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf)), + inform_bgp ? "inform_bgp" : "", inform_dataplane ? " inform_dp" : ""); + } if (inform_bgp) zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready, @@ -1869,14 +1995,20 @@ int process_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf, if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) { /* force drop the sync flags */ old_static = zebra_evpn_mac_is_static(mac); - if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) { + char mac_buf[MAC_BUF_SIZE]; + zlog_debug( - "sync-mac->remote vni %u mac %s es %s seq %d f 0x%x", + "sync-mac->remote vni %u mac %s es %s seq %d f %s", zevpn->vni, prefix_mac2str(macaddr, buf, sizeof(buf)), mac->es ? mac->es->esi_str : "-", - mac->loc_seq, mac->flags); + mac->loc_seq, + zebra_evpn_zebra_mac_flag_dump( + mac, mac_buf, sizeof(mac_buf))); + } + zebra_evpn_mac_clear_sync_info(mac); zebra_evpn_mac_send_del_to_client(zevpn->vni, macaddr, mac->flags, @@ -1970,14 +2102,18 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn, SET_FLAG(mac->flags, ZEBRA_MAC_STICKY); inform_client = true; } else { - if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC) + if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC) { + char mac_buf[MAC_BUF_SIZE]; + zlog_debug( - "UPD %sMAC %s intf %s(%u) VID %u -> VNI %u %scurFlags 0x%x", + "UPD %sMAC %s intf %s(%u) VID %u -> VNI %u %scurFlags %s", sticky ? "sticky " : "", prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name, ifp->ifindex, vid, zevpn->vni, local_inactive ? "local-inactive " : "", - mac->flags); + zebra_evpn_zebra_mac_flag_dump( + mac, mac_buf, sizeof(mac_buf))); + } if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) { struct interface *old_ifp; @@ -2125,14 +2261,19 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn, */ if ((old_local_inactive != local_inactive) || (new_bgp_ready != old_bgp_ready)) { - if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) { + char mac_buf[MAC_BUF_SIZE]; + zlog_debug( - "local mac vni %u mac %s es %s seq %d f 0x%x%s", + "local mac vni %u mac %s es %s seq %d f %s%s", zevpn->vni, prefix_mac2str(macaddr, buf, sizeof(buf)), mac->es ? mac->es->esi_str : "", mac->loc_seq, - mac->flags, - local_inactive ? " local-inactive" : ""); + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf)), + local_inactive ? "local-inactive" : ""); + } + if (!is_dup_detect) inform_client = true; } @@ -2177,12 +2318,18 @@ int zebra_evpn_del_local_mac(zebra_evpn_t *zevpn, struct ethaddr *macaddr, if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) return 0; - if (IS_ZEBRA_DEBUG_VXLAN) + if (IS_ZEBRA_DEBUG_VXLAN) { + char mac_buf[MAC_BUF_SIZE]; + zlog_debug( - "DEL MAC %s intf %s(%u) VID %u -> VNI %u seq %u flags 0x%x nbr count %u", + "DEL MAC %s intf %s(%u) VID %u -> VNI %u seq %u flags %snbr count %u", prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name, ifp->ifindex, mac->fwd_info.local.vid, zevpn->vni, - mac->loc_seq, mac->flags, listcount(mac->neigh_list)); + mac->loc_seq, + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf)), + listcount(mac->neigh_list)); + } old_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags); if (zebra_evpn_mac_is_static(mac)) { @@ -2191,13 +2338,17 @@ int zebra_evpn_del_local_mac(zebra_evpn_t *zevpn, struct ethaddr *macaddr, */ memset(&mac->fwd_info, 0, sizeof(mac->fwd_info)); - if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) { + char mac_buf[MAC_BUF_SIZE]; + zlog_debug( - "re-add sync-mac vni %u mac %s es %s seq %d f 0x%x", + "re-add sync-mac vni %u mac %s es %s seq %d f %s", zevpn->vni, prefix_mac2str(macaddr, buf, sizeof(buf)), mac->es ? mac->es->esi_str : "-", mac->loc_seq, - mac->flags); + zebra_evpn_zebra_mac_flag_dump( + mac, mac_buf, sizeof(mac_buf))); + } /* inform-bgp about change in local-activity if any */ if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE)) { diff --git a/zebra/zebra_evpn_mac.h b/zebra/zebra_evpn_mac.h index 1730991f1e..e21b610501 100644 --- a/zebra/zebra_evpn_mac.h +++ b/zebra/zebra_evpn_mac.h @@ -56,6 +56,7 @@ struct zebra_mac_t_ { /* MAC address. */ struct ethaddr macaddr; + /* When modifying flags please fixup zebra_evpn_zebra_mac_flag_dump */ uint32_t flags; #define ZEBRA_MAC_LOCAL 0x01 #define ZEBRA_MAC_REMOTE 0x02 diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c index 2bf48c6277..18ccbb79fb 100644 --- a/zebra/zebra_fpm.c +++ b/zebra/zebra_fpm.c @@ -273,6 +273,11 @@ struct zfpm_glob { * If non-zero, the last time when statistics were cleared. */ time_t last_stats_clear_time; + + /* + * Flag to track the MAC dump status to FPM + */ + bool fpm_mac_dump_done; }; static struct zfpm_glob zfpm_glob_space; @@ -517,8 +522,6 @@ static int zfpm_conn_up_thread_cb(struct thread *thread) struct zfpm_rnodes_iter *iter; rib_dest_t *dest; - zfpm_g->t_conn_up = NULL; - iter = &zfpm_g->t_conn_up_state.iter; if (zfpm_g->state != ZFPM_STATE_ESTABLISHED) { @@ -528,8 +531,13 @@ static int zfpm_conn_up_thread_cb(struct thread *thread) goto done; } - /* Enqueue FPM updates for all the RMAC entries */ - hash_iterate(zrouter.l3vni_table, zfpm_iterate_rmac_table, NULL); + if (!zfpm_g->fpm_mac_dump_done) { + /* Enqueue FPM updates for all the RMAC entries */ + hash_iterate(zrouter.l3vni_table, zfpm_iterate_rmac_table, + NULL); + /* mark dump done so that its not repeated after yield */ + zfpm_g->fpm_mac_dump_done = true; + } while ((rnode = zfpm_rnodes_iter_next(iter))) { dest = rib_dest_from_rnode(rnode); @@ -547,7 +555,6 @@ static int zfpm_conn_up_thread_cb(struct thread *thread) zfpm_g->stats.t_conn_up_yields++; zfpm_rnodes_iter_pause(iter); - zfpm_g->t_conn_up = NULL; thread_add_timer_msec(zfpm_g->master, zfpm_conn_up_thread_cb, NULL, 0, &zfpm_g->t_conn_up); return 0; @@ -575,12 +582,13 @@ static void zfpm_connection_up(const char *detail) /* * Start thread to push existing routes to the FPM. */ - assert(!zfpm_g->t_conn_up); + thread_cancel(&zfpm_g->t_conn_up); zfpm_rnodes_iter_init(&zfpm_g->t_conn_up_state.iter); + zfpm_g->fpm_mac_dump_done = false; zfpm_debug("Starting conn_up thread"); - zfpm_g->t_conn_up = NULL; + thread_add_timer_msec(zfpm_g->master, zfpm_conn_up_thread_cb, NULL, 0, &zfpm_g->t_conn_up); zfpm_g->stats.t_conn_up_starts++; diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c index 44f574073c..f7c5da5dec 100644 --- a/zebra/zebra_fpm_netlink.c +++ b/zebra/zebra_fpm_netlink.c @@ -133,6 +133,7 @@ struct netlink_nh_info { * A structure for holding information for a netlink route message. */ struct netlink_route_info { + uint32_t nlmsg_pid; uint16_t nlmsg_type; uint8_t rtm_type; uint32_t rtm_table; @@ -244,14 +245,20 @@ static int netlink_route_info_fill(struct netlink_route_info *ri, int cmd, rib_dest_t *dest, struct route_entry *re) { struct nexthop *nexthop; + struct rib_table_info *table_info = + rib_table_info(rib_dest_table(dest)); + struct zebra_vrf *zvrf = table_info->zvrf; memset(ri, 0, sizeof(*ri)); ri->prefix = rib_dest_prefix(dest); ri->af = rib_dest_af(dest); + if (zvrf && zvrf->zns) + ri->nlmsg_pid = zvrf->zns->netlink_dplane.snl.nl_pid; + ri->nlmsg_type = cmd; - ri->rtm_table = rib_table_info(rib_dest_table(dest))->table_id; + ri->rtm_table = table_info->table_id; ri->rtm_protocol = RTPROT_UNSPEC; /* @@ -357,6 +364,7 @@ static int netlink_route_info_encode(struct netlink_route_info *ri, req->n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); req->n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST; + req->n.nlmsg_pid = ri->nlmsg_pid; req->n.nlmsg_type = ri->nlmsg_type; req->r.rtm_family = ri->af; diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index 375be45df0..0a692feb35 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -2120,7 +2120,6 @@ static unsigned nexthop_active_check(struct route_node *rn, struct interface *ifp; route_map_result_t ret = RMAP_PERMITMATCH; int family; - char buf[SRCDEST2STR_BUFFER]; const struct prefix *p, *src_p; struct zebra_vrf *zvrf; @@ -2230,10 +2229,9 @@ static unsigned nexthop_active_check(struct route_node *rn, zvrf, re->tag); if (ret == RMAP_DENYMATCH) { if (IS_ZEBRA_DEBUG_RIB) { - srcdest_rnode2str(rn, buf, sizeof(buf)); zlog_debug( - "%u:%s: Filtering out with NH out %s due to route map", - re->vrf_id, buf, + "%u:%pRN: Filtering out with NH out %s due to route map", + re->vrf_id, rn, ifindex2ifname(nexthop->ifindex, nexthop->vrf_id)); } diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 1f92c43a69..8914f9c59c 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -38,6 +38,7 @@ #include "workqueue.h" #include "nexthop_group_private.h" #include "frr_pthread.h" +#include "printfrr.h" #include "zebra/zebra_router.h" #include "zebra/connected.h" @@ -148,6 +149,30 @@ _rnode_zlog(const char *_func, vrf_id_t vrf_id, struct route_node *rn, zlog(priority, "%s: (%u:%u):%s: %s", _func, vrf_id, table, buf, msgbuf); } +static char *_dump_re_status(const struct route_entry *re, char *buf, + size_t len) +{ + if (re->status == 0) { + snprintfrr(buf, len, "None "); + return buf; + } + + snprintfrr( + buf, len, "%s%s%s%s%s%s%s", + CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED) ? "Removed " : "", + CHECK_FLAG(re->status, ROUTE_ENTRY_CHANGED) ? "Changed " : "", + CHECK_FLAG(re->status, ROUTE_ENTRY_LABELS_CHANGED) + ? "Label Changed " + : "", + CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED) ? "Queued " : "", + CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED) ? "Installed " + : "", + CHECK_FLAG(re->status, ROUTE_ENTRY_FAILED) ? "Failed " : "", + CHECK_FLAG(re->status, ROUTE_ENTRY_USE_FIB_NHG) ? "Fib NHG " + : ""); + return buf; +} + #define rnode_debug(node, vrf_id, ...) \ _rnode_zlog(__func__, vrf_id, node, LOG_DEBUG, __VA_ARGS__) #define rnode_info(node, ...) \ @@ -1080,12 +1105,20 @@ static void rib_process(struct route_node *rn) } RNODE_FOREACH_RE_SAFE (rn, re, next) { - if (IS_ZEBRA_DEBUG_RIB_DETAILED) + if (IS_ZEBRA_DEBUG_RIB_DETAILED) { + char flags_buf[128]; + char status_buf[128]; + zlog_debug( - "%s(%u:%u):%s: Examine re %p (%s) status %x flags %x dist %d metric %d", + "%s(%u:%u):%s: Examine re %p (%s) status: %sflags: %sdist %d metric %d", VRF_LOGNAME(vrf), vrf_id, re->table, buf, re, - zebra_route_string(re->type), re->status, - re->flags, re->distance, re->metric); + zebra_route_string(re->type), + _dump_re_status(re, status_buf, + sizeof(status_buf)), + zclient_dump_route_flags(re->flags, flags_buf, + sizeof(flags_buf)), + re->distance, re->metric); + } /* Currently selected re. */ if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) { @@ -1107,6 +1140,9 @@ static void rib_process(struct route_node *rn) */ if (CHECK_FLAG(re->status, ROUTE_ENTRY_CHANGED)) { if (!nexthop_active_update(rn, re)) { + const struct prefix *p; + struct rib_table_info *info; + if (re->type == ZEBRA_ROUTE_TABLE) { /* XXX: HERE BE DRAGONS!!!!! * In all honesty, I have not yet @@ -1136,6 +1172,11 @@ static void rib_process(struct route_node *rn) ROUTE_ENTRY_REMOVED); } + info = srcdest_rnode_table_info(rn); + srcdest_rnode_prefixes(rn, &p, NULL); + zsend_route_notify_owner(re, p, + ZAPI_ROUTE_FAIL_INSTALL, + info->afi, info->safi); continue; } } else { @@ -2791,6 +2832,8 @@ void _route_entry_dump(const char *func, union prefixconstptr pp, bool is_srcdst = src_p && src_p->prefixlen; char straddr[PREFIX_STRLEN]; char srcaddr[PREFIX_STRLEN]; + char flags_buf[128]; + char status_buf[128]; struct nexthop *nexthop; struct vrf *vrf = vrf_lookup_by_id(re->vrf_id); struct nexthop_group *nhg; @@ -2804,9 +2847,12 @@ void _route_entry_dump(const char *func, union prefixconstptr pp, zlog_debug("%s: uptime == %lu, type == %u, instance == %d, table == %d", straddr, (unsigned long)re->uptime, re->type, re->instance, re->table); - zlog_debug("%s: metric == %u, mtu == %u, distance == %u, flags == %u, status == %u", - straddr, re->metric, re->mtu, re->distance, re->flags, - re->status); + zlog_debug( + "%s: metric == %u, mtu == %u, distance == %u, flags == %sstatus == %s", + straddr, re->metric, re->mtu, re->distance, + zclient_dump_route_flags(re->flags, flags_buf, + sizeof(flags_buf)), + _dump_re_status(re, status_buf, sizeof(status_buf))); zlog_debug("%s: nexthop_num == %u, nexthop_active_num == %u", straddr, nexthop_group_nexthop_num(&(re->nhe->nhg)), nexthop_group_active_nexthop_num(&(re->nhe->nhg))); @@ -2941,8 +2987,10 @@ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p, struct nhg_hash_entry *nhe = NULL; struct route_table *table; struct route_node *rn; - struct route_entry *same = NULL; + struct route_entry *same = NULL, *first_same = NULL; int ret = 0; + int same_count = 0; + rib_dest_t *dest; if (!re || !re_nhe) return -1; @@ -3010,14 +3058,22 @@ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p, * for the install don't do a route replace. */ RNODE_FOREACH_RE (rn, same) { - if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED)) + if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED)) { + same_count++; continue; + } /* Compare various route_entry properties */ - if (rib_compare_routes(re, same)) - break; + if (rib_compare_routes(re, same)) { + same_count++; + + if (first_same == NULL) + first_same = same; + } } + same = first_same; + /* If this route is kernel/connected route, notify the dataplane. */ if (RIB_SYSTEM_ROUTE(re)) { /* Notify dataplane */ @@ -3027,8 +3083,9 @@ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p, /* Link new re to node.*/ if (IS_ZEBRA_DEBUG_RIB) { rnode_debug(rn, re->vrf_id, - "Inserting route rn %p, re %p (%s) existing %p", - rn, re, zebra_route_string(re->type), same); + "Inserting route rn %p, re %p (%s) existing %p, same_count %d", + rn, re, zebra_route_string(re->type), same, + same_count); if (IS_ZEBRA_DEBUG_RIB_DETAILED) route_entry_dump(p, src_p, re); @@ -3042,6 +3099,24 @@ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p, if (same) rib_delnode(rn, same); + /* See if we can remove some RE entries that are queued for + * removal, but won't be considered in rib processing. + */ + dest = rib_dest_from_rnode(rn); + RNODE_FOREACH_RE_SAFE (rn, re, same) { + if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)) { + /* If the route was used earlier, must retain it. */ + if (dest && re == dest->selected_fib) + continue; + + if (IS_ZEBRA_DEBUG_RIB) + rnode_debug(rn, re->vrf_id, "rn %p, removing unneeded re %p", + rn, re); + + rib_unlink(rn, re); + } + } + route_unlock_node(rn); return ret; } @@ -3378,7 +3453,8 @@ static void rib_update_route_node(struct route_node *rn, int type) } /* Schedule routes of a particular table (address-family) based on event. */ -void rib_update_table(struct route_table *table, enum rib_update_event event) +void rib_update_table(struct route_table *table, enum rib_update_event event, + int rtype) { struct route_node *rn; @@ -3391,12 +3467,12 @@ void rib_update_table(struct route_table *table, enum rib_update_event event) : NULL; vrf = zvrf ? zvrf->vrf : NULL; - zlog_debug("%s: %s VRF %s Table %u event %s", __func__, + zlog_debug("%s: %s VRF %s Table %u event %s Route type: %s", __func__, table->info ? afi2str( ((struct rib_table_info *)table->info)->afi) : "Unknown", VRF_LOGNAME(vrf), zvrf ? zvrf->table_id : 0, - rib_update_event2str(event)); + rib_update_event2str(event), zebra_route_string(rtype)); } /* Walk all routes and queue for processing, if appropriate for @@ -3419,7 +3495,7 @@ void rib_update_table(struct route_table *table, enum rib_update_event event) break; case RIB_UPDATE_RMAP_CHANGE: case RIB_UPDATE_OTHER: - rib_update_route_node(rn, ZEBRA_ROUTE_ALL); + rib_update_route_node(rn, rtype); break; default: break; @@ -3427,7 +3503,8 @@ void rib_update_table(struct route_table *table, enum rib_update_event event) } } -static void rib_update_handle_vrf(vrf_id_t vrf_id, enum rib_update_event event) +static void rib_update_handle_vrf(vrf_id_t vrf_id, enum rib_update_event event, + int rtype) { struct route_table *table; @@ -3438,14 +3515,14 @@ static void rib_update_handle_vrf(vrf_id_t vrf_id, enum rib_update_event event) /* Process routes of interested address-families. */ table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id); if (table) - rib_update_table(table, event); + rib_update_table(table, event, rtype); table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id); if (table) - rib_update_table(table, event); + rib_update_table(table, event, rtype); } -static void rib_update_handle_vrf_all(enum rib_update_event event) +static void rib_update_handle_vrf_all(enum rib_update_event event, int rtype) { struct zebra_router_table *zrt; @@ -3455,7 +3532,7 @@ static void rib_update_handle_vrf_all(enum rib_update_event event) /* Just iterate over all the route tables, rather than vrf lookups */ RB_FOREACH (zrt, zebra_router_table_head, &zrouter.tables) - rib_update_table(zrt->table, event); + rib_update_table(zrt->table, event, rtype); } struct rib_update_ctx { @@ -3489,9 +3566,9 @@ static int rib_update_handler(struct thread *thread) ctx = THREAD_ARG(thread); if (ctx->vrf_all) - rib_update_handle_vrf_all(ctx->event); + rib_update_handle_vrf_all(ctx->event, ZEBRA_ROUTE_ALL); else - rib_update_handle_vrf(ctx->vrf_id, ctx->event); + rib_update_handle_vrf(ctx->vrf_id, ctx->event, ZEBRA_ROUTE_ALL); rib_update_ctx_fini(&ctx); @@ -3504,26 +3581,6 @@ static int rib_update_handler(struct thread *thread) */ static struct thread *t_rib_update_threads[RIB_UPDATE_MAX]; -/* Schedule a RIB update event for specific vrf */ -void rib_update_vrf(vrf_id_t vrf_id, enum rib_update_event event) -{ - struct rib_update_ctx *ctx; - - ctx = rib_update_ctx_init(vrf_id, event); - - /* Don't worry about making sure multiple rib updates for specific vrf - * are scheduled at once for now. If it becomes a problem, we can use a - * lookup of some sort to keep track of running threads via t_vrf_id - * like how we are doing it in t_rib_update_threads[]. - */ - thread_add_event(zrouter.master, rib_update_handler, ctx, 0, NULL); - - if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug("%s: Scheduled VRF %s, event %s", __func__, - vrf_id_to_name(ctx->vrf_id), - rib_update_event2str(event)); -} - /* Schedule a RIB update event for all vrfs */ void rib_update(enum rib_update_event event) { diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index bbc8b6f19d..229b705ec9 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -267,7 +267,8 @@ static int ip_protocol_rm_add(struct zebra_vrf *zvrf, const char *rmap, /* Process routes of interested address-families. */ table = zebra_vrf_table(afi, safi, zvrf->vrf->vrf_id); if (table) - rib_update_table(table, RIB_UPDATE_RMAP_CHANGE); + rib_update_table(table, RIB_UPDATE_RMAP_CHANGE, + rtype); } return CMD_SUCCESS; @@ -294,7 +295,8 @@ static int ip_protocol_rm_del(struct zebra_vrf *zvrf, const char *rmap, /* Process routes of interested address-families. */ table = zebra_vrf_table(afi, safi, zvrf->vrf->vrf_id); if (table) - rib_update_table(table, RIB_UPDATE_RMAP_CHANGE); + rib_update_table(table, RIB_UPDATE_RMAP_CHANGE, + rtype); } XFREE(MTYPE_ROUTE_MAP_NAME, PROTO_RM_NAME(zvrf, afi, rtype)); } @@ -576,7 +578,7 @@ DEFUN (zebra_route_map_timer, ZEBRA_STR "Set route-map parameters\n" "Time to wait before route-map updates are processed\n" - "0 means event-driven updates are disabled\n") + "0 means route-map changes are run immediately instead of delaying\n") { int idx_number = 3; uint32_t rmap_delay_timer; @@ -594,7 +596,7 @@ DEFUN (no_zebra_route_map_timer, ZEBRA_STR "Set route-map parameters\n" "Reset delay-timer to default value, 30 secs\n" - "0 means event-driven updates are disabled\n") + "0 means route-map changes are run immediately instead of delaying\n") { zebra_route_map_set_delay_timer(ZEBRA_RMAP_DEFAULT_UPDATE_TIMER); @@ -1454,8 +1456,6 @@ static void zebra_rib_table_rm_update(const char *rmap) struct vrf *vrf = NULL; struct zebra_vrf *zvrf = NULL; char *rmap_name; - char afi_ip = 0; - char afi_ipv6 = 0; struct route_map *old = NULL; RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { @@ -1486,16 +1486,12 @@ static void zebra_rib_table_rm_update(const char *rmap) PROTO_RM_MAP(zvrf, AFI_IP, i)); /* There is single rib table for all protocols */ - if (afi_ip == 0) { - table = zvrf->table[AFI_IP] - [SAFI_UNICAST]; - if (table) { - - afi_ip = 1; - rib_update_table( - table, - RIB_UPDATE_RMAP_CHANGE); - } + table = zvrf->table[AFI_IP][SAFI_UNICAST]; + if (table) { + rib_update_table( + table, + RIB_UPDATE_RMAP_CHANGE, + i); } } rmap_name = PROTO_RM_NAME(zvrf, AFI_IP6, i); @@ -1515,16 +1511,12 @@ static void zebra_rib_table_rm_update(const char *rmap) PROTO_RM_MAP(zvrf, AFI_IP6, i)); /* There is single rib table for all protocols */ - if (afi_ipv6 == 0) { - table = zvrf->table[AFI_IP6] - [SAFI_UNICAST]; - if (table) { - - afi_ipv6 = 1; - rib_update_table( - table, - RIB_UPDATE_RMAP_CHANGE); - } + table = zvrf->table[AFI_IP6][SAFI_UNICAST]; + if (table) { + rib_update_table( + table, + RIB_UPDATE_RMAP_CHANGE, + i); } } } @@ -1628,8 +1620,6 @@ static void zebra_route_map_process_update_cb(char *rmap_name) static int zebra_route_map_update_timer(struct thread *thread) { - zebra_t_rmap_update = NULL; - if (IS_ZEBRA_DEBUG_EVENT) zlog_debug("Event driven route-map update triggered"); @@ -1654,8 +1644,8 @@ static void zebra_route_map_set_delay_timer(uint32_t value) if (!value && zebra_t_rmap_update) { /* Event driven route map updates is being disabled */ /* But there's a pending timer. Fire it off now */ - thread_cancel(&zebra_t_rmap_update); - zebra_route_map_update_timer(zebra_t_rmap_update); + THREAD_OFF(zebra_t_rmap_update); + zebra_route_map_update_timer(NULL); } } @@ -1664,7 +1654,7 @@ void zebra_routemap_finish(void) /* Set zebra_rmap_update_timer to 0 so that it wont schedule again */ zebra_rmap_update_timer = 0; /* Thread off if any scheduled already */ - thread_cancel(&zebra_t_rmap_update); + THREAD_OFF(zebra_t_rmap_update); route_map_finish(); } @@ -1780,12 +1770,11 @@ route_map_result_t zebra_nht_route_map_check(afi_t afi, int client_proto, static void zebra_route_map_mark_update(const char *rmap_name) { /* rmap_update_timer of 0 means don't do route updates */ - if (zebra_rmap_update_timer && !zebra_t_rmap_update) { - zebra_t_rmap_update = NULL; - thread_add_timer(zrouter.master, zebra_route_map_update_timer, - NULL, zebra_rmap_update_timer, - &zebra_t_rmap_update); - } + if (zebra_rmap_update_timer) + THREAD_OFF(zebra_t_rmap_update); + + thread_add_timer(zrouter.master, zebra_route_map_update_timer, + NULL, zebra_rmap_update_timer, &zebra_t_rmap_update); } static void zebra_route_map_add(const char *rmap_name) |
