diff options
93 files changed, 2154 insertions, 2013 deletions
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index 213de45c55..a8ca8c1fa6 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -353,7 +353,7 @@ struct transit { __builtin_choose_expr((X) >= 1 && (X) <= 64, 1ULL << ((X)-1), (void)0) #define BGP_CLUSTER_LIST_LENGTH(attr) \ - (((attr)->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) \ + (CHECK_FLAG((attr)->flag, ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) \ ? bgp_attr_get_cluster((attr))->length \ : 0) diff --git a/bgpd/bgp_attr_evpn.c b/bgpd/bgp_attr_evpn.c index fc7548d9bf..a3ffe61eb8 100644 --- a/bgpd/bgp_attr_evpn.c +++ b/bgpd/bgp_attr_evpn.c @@ -218,7 +218,8 @@ uint32_t bgp_attr_mac_mobility_seqnum(struct attr *attr) continue; flags = *pnt++; - if (flags & ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY) + if (CHECK_FLAG(flags, + ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY)) SET_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_STICKY); else UNSET_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_STICKY); @@ -258,11 +259,12 @@ void bgp_attr_evpn_na_flag(struct attr *attr, bool *proxy) sub_type == ECOMMUNITY_EVPN_SUBTYPE_ND) { val = *pnt++; - if (val & ECOMMUNITY_EVPN_SUBTYPE_ND_ROUTER_FLAG) + if (CHECK_FLAG(val, + ECOMMUNITY_EVPN_SUBTYPE_ND_ROUTER_FLAG)) SET_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_ROUTER); - if (val & ECOMMUNITY_EVPN_SUBTYPE_PROXY_FLAG) + if (CHECK_FLAG(val, ECOMMUNITY_EVPN_SUBTYPE_PROXY_FLAG)) *proxy = true; break; diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index 44a4c0f00b..556738a606 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -2543,9 +2543,9 @@ DEFPY(bmp_monitor_cfg, bmp_monitor_cmd, prev = bt->afimon[afi][safi]; if (no) - bt->afimon[afi][safi] &= ~flag; + UNSET_FLAG(bt->afimon[afi][safi], flag); else - bt->afimon[afi][safi] |= flag; + SET_FLAG(bt->afimon[afi][safi], flag); if (prev == bt->afimon[afi][safi]) return CMD_SUCCESS; diff --git a/bgpd/bgp_btoa.c b/bgpd/bgp_btoa.c index 1d5034efd2..32823cc376 100644 --- a/bgpd/bgp_btoa.c +++ b/bgpd/bgp_btoa.c @@ -69,7 +69,7 @@ static void attr_parse(struct stream *s, uint16_t len) flag = stream_getc(s); type = stream_getc(s); - if (flag & BGP_ATTR_FLAG_EXTLEN) + if (CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN)) length = stream_getw(s); else length = stream_getc(s); diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index 339bfae56d..93f5a19902 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -779,7 +779,8 @@ int bgp_show_dampening_parameters(struct vty *vty, afi_t afi, safi_t safi, bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON); bgp = bgp_get_default(); - if (bgp == NULL) { + + if (bgp == NULL || IS_BGP_INSTANCE_HIDDEN(bgp)) { vty_out(vty, "No BGP process is configured\n"); return CMD_WARNING; } diff --git a/bgpd/bgp_ecommunity.h b/bgpd/bgp_ecommunity.h index 929e4e60be..67c16aeb9e 100644 --- a/bgpd/bgp_ecommunity.h +++ b/bgpd/bgp_ecommunity.h @@ -155,12 +155,12 @@ struct ecommunity_ip6 { /* Extended community value is eight octet. */ struct ecommunity_val { - char val[ECOMMUNITY_SIZE]; + uint8_t val[ECOMMUNITY_SIZE]; }; /* IPv6 Extended community value is eight octet. */ struct ecommunity_val_ipv6 { - char val[IPV6_ECOMMUNITY_SIZE]; + uint8_t val[IPV6_ECOMMUNITY_SIZE]; }; #define ecom_length_size(X, Y) ((X)->size * (Y)) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index db93640635..fb7d2f47fb 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -117,7 +117,7 @@ int vni_list_cmp(void *p1, void *p2) static unsigned int vrf_import_rt_hash_key_make(const void *p) { const struct vrf_irt_node *irt = p; - const char *pnt = irt->rt.val; + const uint8_t *pnt = irt->rt.val; return jhash(pnt, 8, 0x5abc1234); } @@ -229,7 +229,7 @@ static int is_vrf_present_in_irt_vrfs(struct list *vrfs, struct bgp *bgp_vrf) static unsigned int import_rt_hash_key_make(const void *p) { const struct irt_node *irt = p; - const char *pnt = irt->rt.val; + const uint8_t *pnt = irt->rt.val; return jhash(pnt, 8, 0xdeadbeef); } @@ -621,7 +621,7 @@ static void form_auto_rt(struct bgp *bgp, vni_t vni, struct list *rtl, struct listnode *node; if (bgp->advertise_autort_rfc8365) - vni |= EVPN_AUTORT_VXLAN; + SET_FLAG(vni, EVPN_AUTORT_VXLAN); encode_route_target_as((bgp->as & 0xFFFF), vni, &eval, true); ecomadd = ecommunity_new(); @@ -1314,12 +1314,11 @@ enum zclient_send_status evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn * flag set install the local entry as a router entry */ if (is_evpn_prefix_ipaddr_v6(p) && - (pi->attr->es_flags & - ATTR_ES_PEER_ROUTER)) + CHECK_FLAG(pi->attr->es_flags, ATTR_ES_PEER_ROUTER)) SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG); - if (!(pi->attr->es_flags & ATTR_ES_PEER_ACTIVE)) + if (!CHECK_FLAG(pi->attr->es_flags, ATTR_ES_PEER_ACTIVE)) SET_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT); } @@ -1611,12 +1610,16 @@ static int update_evpn_type5_route_entry(struct bgp *bgp_evpn, struct bgp_labels bgp_labels = {}; struct bgp_path_info *local_pi = NULL; struct bgp_path_info *tmp_pi = NULL; + struct aspath *new_aspath; + struct attr static_attr = { 0 }; *route_changed = 0; /* See if this is an update of an existing route, or a new add. */ local_pi = bgp_evpn_route_get_local_path(bgp_evpn, dest); + static_attr = *attr; + /* * create a new route entry if one doesn't exist. * Otherwise see if route attr has changed @@ -1626,8 +1629,19 @@ static int update_evpn_type5_route_entry(struct bgp *bgp_evpn, /* route has changed as this is the first entry */ *route_changed = 1; + /* + * if the asn values are different, copy the as of + * source vrf to the target entry + */ + if (bgp_vrf->as != bgp_evpn->as) { + new_aspath = aspath_dup(static_attr.aspath); + new_aspath = aspath_add_seq(new_aspath, bgp_vrf->as); + static_attr.aspath = new_aspath; + } + /* Add (or update) attribute to hash. */ - attr_new = bgp_attr_intern(attr); + attr_new = bgp_attr_intern(&static_attr); + bgp_attr_flush(&static_attr); /* create the route info from attribute */ pi = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, @@ -1897,42 +1911,44 @@ static void update_evpn_route_entry_sync_info(struct bgp *bgp, mac); attr->mm_sync_seqnum = max_sync_seq; if (active_on_peer) - attr->es_flags |= ATTR_ES_PEER_ACTIVE; + SET_FLAG(attr->es_flags, ATTR_ES_PEER_ACTIVE); else - attr->es_flags &= ~ATTR_ES_PEER_ACTIVE; + UNSET_FLAG(attr->es_flags, ATTR_ES_PEER_ACTIVE); if (proxy_from_peer) - attr->es_flags |= ATTR_ES_PEER_PROXY; + SET_FLAG(attr->es_flags, ATTR_ES_PEER_PROXY); else - attr->es_flags &= ~ATTR_ES_PEER_PROXY; + UNSET_FLAG(attr->es_flags, ATTR_ES_PEER_PROXY); if (peer_router) - attr->es_flags |= ATTR_ES_PEER_ROUTER; + SET_FLAG(attr->es_flags, ATTR_ES_PEER_ROUTER); else - attr->es_flags &= ~ATTR_ES_PEER_ROUTER; + UNSET_FLAG(attr->es_flags, ATTR_ES_PEER_ROUTER); if (BGP_DEBUG(evpn_mh, EVPN_MH_RT)) { char esi_buf[ESI_STR_LEN]; - zlog_debug( - "setup sync info for %pFX es %s max_seq %d %s%s%s", - evp, - esi_to_str(esi, esi_buf, - sizeof(esi_buf)), - max_sync_seq, - (attr->es_flags & ATTR_ES_PEER_ACTIVE) - ? "peer-active " - : "", - (attr->es_flags & ATTR_ES_PEER_PROXY) - ? "peer-proxy " - : "", - (attr->es_flags & ATTR_ES_PEER_ROUTER) - ? "peer-router " - : ""); + zlog_debug("setup sync info for %pFX es %s max_seq %d %s%s%s", + evp, + esi_to_str(esi, esi_buf, + sizeof(esi_buf)), + max_sync_seq, + CHECK_FLAG(attr->es_flags, + ATTR_ES_PEER_ACTIVE) + ? "peer-active " + : "", + CHECK_FLAG(attr->es_flags, + ATTR_ES_PEER_PROXY) + ? "peer-proxy " + : "", + CHECK_FLAG(attr->es_flags, + ATTR_ES_PEER_ROUTER) + ? "peer-router " + : ""); } } } else { attr->mm_sync_seqnum = 0; - attr->es_flags &= ~ATTR_ES_PEER_ACTIVE; - attr->es_flags &= ~ATTR_ES_PEER_PROXY; + UNSET_FLAG(attr->es_flags, ATTR_ES_PEER_ACTIVE); + UNSET_FLAG(attr->es_flags, ATTR_ES_PEER_PROXY); } } @@ -2217,16 +2233,16 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG)) SET_FLAG(attr.evpn_flags, ATTR_EVPN_FLAG_ROUTER); if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT)) - attr.es_flags |= ATTR_ES_PROXY_ADVERT; + SET_FLAG(attr.es_flags, ATTR_ES_PROXY_ADVERT); if (esi && bgp_evpn_is_esi_valid(esi)) { memcpy(&attr.esi, esi, sizeof(esi_t)); - attr.es_flags |= ATTR_ES_IS_LOCAL; + SET_FLAG(attr.es_flags, ATTR_ES_IS_LOCAL); } /* PMSI is only needed for type-3 routes */ if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE) { - attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL); + SET_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)); bgp_attr_set_pmsi_tnl_type(&attr, PMSI_TNLTYPE_INGR_REPL); } @@ -2258,8 +2274,12 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, * IPv4 or IPv6 global addresses and we're advertising L3VNI with * these routes. */ - add_l3_ecomm = bgp_evpn_route_add_l3_ecomm_ok( - vpn, p, (attr.es_flags & ATTR_ES_IS_LOCAL) ? &attr.esi : NULL); + add_l3_ecomm = + bgp_evpn_route_add_l3_ecomm_ok(vpn, p, + CHECK_FLAG(attr.es_flags, + ATTR_ES_IS_LOCAL) + ? &attr.esi + : NULL); if (bgp->evpn_info) macvrf_soo = bgp->evpn_info->soo; @@ -2531,9 +2551,12 @@ void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct bgpevpn *vpn, /* Add L3 VNI RTs and RMAC for non IPv6 link-local if * using L3 VNI for type-2 routes also. */ - add_l3_ecomm = bgp_evpn_route_add_l3_ecomm_ok( - vpn, &evp, - (attr.es_flags & ATTR_ES_IS_LOCAL) ? &attr.esi : NULL); + add_l3_ecomm = + bgp_evpn_route_add_l3_ecomm_ok(vpn, &evp, + CHECK_FLAG(attr.es_flags, + ATTR_ES_IS_LOCAL) + ? &attr.esi + : NULL); if (bgp->evpn_info) macvrf_soo = bgp->evpn_info->soo; @@ -3091,23 +3114,23 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, attr.mp_nexthop_len = IPV6_MAX_BYTELEN; } else { attr.nexthop = bre->gw_ip.ipaddr_v4; - attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP); + SET_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)); } } else { if (afi == AFI_IP6) evpn_convert_nexthop_to_ipv6(&attr); else { attr.nexthop = attr.mp_nexthop_global_in; - attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP); + SET_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)); } } bgp_evpn_es_vrf_use_nhg(bgp_vrf, &parent_pi->attr->esi, &use_l3nhg, &is_l3nhg_active, NULL); if (use_l3nhg) - attr.es_flags |= ATTR_ES_L3_NHG_USE; + SET_FLAG(attr.es_flags, ATTR_ES_L3_NHG_USE); if (is_l3nhg_active) - attr.es_flags |= ATTR_ES_L3_NHG_ACTIVE; + SET_FLAG(attr.es_flags, ATTR_ES_L3_NHG_ACTIVE); /* Check if route entry is already present. */ for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) @@ -3271,8 +3294,7 @@ static int install_evpn_route_entry_in_vni_common( if (BGP_DEBUG(evpn_mh, EVPN_MH_RT)) zlog_debug("VNI %d path %pFX chg to %s es", vpn->vni, &pi->net->rn->p, - new_local_es ? "local" - : "non-local"); + new_local_es ? "local" : "non-local"); bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED); } @@ -3635,7 +3657,7 @@ static int is_route_matching_for_vrf(struct bgp *bgp_vrf, assert(attr); /* Route should have valid RT to be even considered. */ - if (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) + if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) return 0; ecom = bgp_attr_get_ecommunity(attr); @@ -3702,7 +3724,7 @@ static int is_route_matching_for_vni(struct bgp *bgp, struct bgpevpn *vpn, assert(attr); /* Route should have valid RT to be even considered. */ - if (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) + if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) return 0; ecom = bgp_attr_get_ecommunity(attr); @@ -4204,7 +4226,7 @@ static int bgp_evpn_install_uninstall_table(struct bgp *bgp, afi_t afi, return 0; /* If we don't have Route Target, nothing much to do. */ - if (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) + if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) return 0; /* EAD prefix in the global table doesn't include the VTEP-IP so @@ -4734,9 +4756,9 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi, STREAM_GET(&attr->esi, pkt, sizeof(esi_t)); if (bgp_evpn_is_esi_local_and_non_bypass(&attr->esi)) - attr->es_flags |= ATTR_ES_IS_LOCAL; + SET_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL); else - attr->es_flags &= ~ATTR_ES_IS_LOCAL; + UNSET_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL); } else { STREAM_FORWARD_GETP(pkt, sizeof(esi_t)); } @@ -4838,8 +4860,7 @@ static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi, * Note: We just simply ignore the values as it is not clear if * doing anything else is better. */ - if (attr && - (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL))) { + if (attr && CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL))) { enum pta_type pmsi_tnl_type = bgp_attr_get_pmsi_tnl_type(attr); if (pmsi_tnl_type != PMSI_TNLTYPE_INGR_REPL @@ -5441,7 +5462,7 @@ void evpn_rt_delete_auto(struct bgp *bgp, vni_t vni, struct list *rtl, struct ecommunity_val eval; if (bgp->advertise_autort_rfc8365) - vni |= EVPN_AUTORT_VXLAN; + SET_FLAG(vni, EVPN_AUTORT_VXLAN); encode_route_target_as((bgp->as & 0xFFFF), vni, &eval, true); @@ -7719,18 +7740,18 @@ static void bgp_evpn_remote_ip_process_nexthops(struct bgpevpn *vpn, * MAC/IP route or SVI or tenant vrf being added to EVI. * Set nexthop as valid only if it is already L3 reachable */ - if (resolve && bnc->flags & BGP_NEXTHOP_EVPN_INCOMPLETE) { - bnc->flags &= ~BGP_NEXTHOP_EVPN_INCOMPLETE; - bnc->flags |= BGP_NEXTHOP_VALID; - bnc->change_flags |= BGP_NEXTHOP_MACIP_CHANGED; + if (resolve && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_EVPN_INCOMPLETE)) { + UNSET_FLAG(bnc->flags, BGP_NEXTHOP_EVPN_INCOMPLETE); + SET_FLAG(bnc->flags, BGP_NEXTHOP_VALID); + SET_FLAG(bnc->change_flags, BGP_NEXTHOP_MACIP_CHANGED); evaluate_paths(bnc); } /* MAC/IP route or SVI or tenant vrf being deleted from EVI */ - if (!resolve && bnc->flags & BGP_NEXTHOP_VALID) { - bnc->flags &= ~BGP_NEXTHOP_VALID; - bnc->flags |= BGP_NEXTHOP_EVPN_INCOMPLETE; - bnc->change_flags |= BGP_NEXTHOP_MACIP_CHANGED; + if (!resolve && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID)) { + UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID); + SET_FLAG(bnc->flags, BGP_NEXTHOP_EVPN_INCOMPLETE); + SET_FLAG(bnc->change_flags, BGP_NEXTHOP_MACIP_CHANGED); evaluate_paths(bnc); } } diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 74ad65f1ec..cdd9b7ae4d 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -1799,18 +1799,14 @@ bgp_connect_fail(struct peer_connection *connection) */ static void bgp_connect_in_progress_update_connection(struct peer *peer) { - if (bgp_getsockname(peer) < 0) { - if (!peer->su_remote && - !BGP_CONNECTION_SU_UNSPEC(peer->connection)) { - /* if connect initiated, then dest port and dest addresses are well known */ - peer->su_remote = sockunion_dup(&peer->connection->su); - if (sockunion_family(peer->su_remote) == AF_INET) - peer->su_remote->sin.sin_port = - htons(peer->port); - else if (sockunion_family(peer->su_remote) == AF_INET6) - peer->su_remote->sin6.sin6_port = - htons(peer->port); - } + bgp_updatesockname(peer); + if (!peer->su_remote && !BGP_CONNECTION_SU_UNSPEC(peer->connection)) { + /* if connect initiated, then dest port and dest addresses are well known */ + peer->su_remote = sockunion_dup(&peer->connection->su); + if (sockunion_family(peer->su_remote) == AF_INET) + peer->su_remote->sin.sin_port = htons(peer->port); + else if (sockunion_family(peer->su_remote) == AF_INET6) + peer->su_remote->sin6.sin6_port = htons(peer->port); } } diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index f5dbb4aa58..13da55ffb7 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -34,6 +34,7 @@ #include "bgpd/bgp_nht.h" #include "bgpd/bgp_evpn.h" #include "bgpd/bgp_memory.h" +#include "bgpd/bgp_aspath.h" #ifdef ENABLE_BGP_VNC #include "bgpd/rfapi/rfapi_backend.h" @@ -2156,6 +2157,7 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */ struct bgp *src_vrf; struct interface *ifp = NULL; char rd_buf[RD_ADDRSTRLEN]; + struct aspath *new_aspath; int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF); @@ -2213,6 +2215,32 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */ return; } + bn = bgp_afi_node_get(to_bgp->rib[afi][safi], afi, safi, p, NULL); + + /* Check if leaked route has our asn. If so, don't import it. */ + if (aspath_loop_check(path_vpn->attr->aspath, to_bgp->as)) { + for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; + bpi = bpi->next) { + if (bpi->extra && bpi->extra->vrfleak && + (struct bgp_path_info *)bpi->extra->vrfleak->parent == + path_vpn) { + break; + } + } + + if (bpi) { + if (debug) + zlog_debug("%s: blocking import of %p, as-path match", + __func__, bpi); + bgp_aggregate_decrement(to_bgp, p, bpi, afi, safi); + bgp_path_info_delete(bn, bpi); + bgp_process(to_bgp, bn, bpi, afi, safi); + } + bgp_dest_unlock_node(bn); + + return; + } + if (debug) zlog_debug("%s: updating RD %s, %pFX to %s", __func__, rd_buf, p, to_bgp->name_pretty); @@ -2365,6 +2393,21 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */ nexthop_self_flag = 0; } + /* + * if the asn values are different, copy the asn of the source vrf + * into the entry before importing. This helps with as-path loop + * detection + */ + if (path_vpn->extra && path_vpn->extra->vrfleak && + path_vpn->extra->vrfleak->bgp_orig && + (to_bgp->as != path_vpn->extra->vrfleak->bgp_orig->as)) { + new_aspath = aspath_dup(static_attr.aspath); + new_aspath = + aspath_add_seq(new_aspath, + path_vpn->extra->vrfleak->bgp_orig->as); + static_attr.aspath = new_aspath; + } + new_attr = bgp_attr_intern(&static_attr); bgp_attr_flush(&static_attr); @@ -3866,7 +3909,8 @@ void bgp_vpn_leak_unimport(struct bgp *from_bgp) bool is_vrf_leak_bind; int debug; - if (from_bgp->inst_type != BGP_INSTANCE_TYPE_VRF) + if (from_bgp->inst_type != BGP_INSTANCE_TYPE_VRF && + from_bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT) return; debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) | diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index e09dbc22af..de57d91806 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -861,8 +861,7 @@ int bgp_connect(struct peer_connection *connection) htons(peer->port), ifindex); } -/* After TCP connection is established. Get local address and port. */ -int bgp_getsockname(struct peer *peer) +void bgp_updatesockname(struct peer *peer) { if (peer->su_local) { sockunion_free(peer->su_local); @@ -876,6 +875,12 @@ int bgp_getsockname(struct peer *peer) peer->su_local = sockunion_getsockname(peer->connection->fd); peer->su_remote = sockunion_getpeername(peer->connection->fd); +} + +/* After TCP connection is established. Get local address and port. */ +int bgp_getsockname(struct peer *peer) +{ + bgp_updatesockname(peer); if (!bgp_zebra_nexthop_set(peer->su_local, peer->su_remote, &peer->nexthop, peer)) { diff --git a/bgpd/bgp_network.h b/bgpd/bgp_network.h index 7a0b3cc67d..ceb6b6f002 100644 --- a/bgpd/bgp_network.h +++ b/bgpd/bgp_network.h @@ -23,6 +23,7 @@ extern void bgp_close_vrf_socket(struct bgp *bgp); extern void bgp_close(void); extern int bgp_connect(struct peer_connection *connection); extern int bgp_getsockname(struct peer *peer); +extern void bgp_updatesockname(struct peer *peer); extern int bgp_md5_set_prefix(struct bgp *bgp, struct prefix *p, const char *password); diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index fa03f1d21d..62be7ffbf7 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -2702,6 +2702,19 @@ static int bgp_notify_receive(struct peer_connection *connection, inner.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM) UNSET_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN); + /* Resend the next OPEN message with a global AS number if we received + * a `Bad Peer AS` notification. This is only valid if `dual-as` is + * configured. + */ + if (inner.code == BGP_NOTIFY_OPEN_ERR && + inner.subcode == BGP_NOTIFY_OPEN_BAD_PEER_AS && + CHECK_FLAG(peer->flags, PEER_FLAG_DUAL_AS)) { + if (peer->change_local_as != peer->bgp->as) + peer->change_local_as = peer->bgp->as; + else + peer->change_local_as = peer->local_as; + } + /* If Graceful-Restart N-bit (Notification) is exchanged, * and it's not a Hard Reset, let's retain the routes. */ diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c index 43682de413..ec5b50a08f 100644 --- a/bgpd/bgp_pbr.c +++ b/bgpd/bgp_pbr.c @@ -775,14 +775,12 @@ int bgp_pbr_build_and_validate_entry(const struct prefix *p, } api_action = &api->actions[action_count - 1]; - if ((ecom_eval->val[1] == - (char)ECOMMUNITY_REDIRECT_VRF) && - (ecom_eval->val[0] == - (char)ECOMMUNITY_ENCODE_TRANS_EXP || + if ((ecom_eval->val[1] == ECOMMUNITY_REDIRECT_VRF) && + (ecom_eval->val[0] == ECOMMUNITY_ENCODE_TRANS_EXP || ecom_eval->val[0] == - (char)ECOMMUNITY_EXTENDED_COMMUNITY_PART_2 || + ECOMMUNITY_EXTENDED_COMMUNITY_PART_2 || ecom_eval->val[0] == - (char)ECOMMUNITY_EXTENDED_COMMUNITY_PART_3)) { + ECOMMUNITY_EXTENDED_COMMUNITY_PART_3)) { struct ecommunity *eckey = ecommunity_new(); struct ecommunity_val ecom_copy; @@ -800,9 +798,9 @@ int bgp_pbr_build_and_validate_entry(const struct prefix *p, eckey); ecommunity_free(&eckey); } else if ((ecom_eval->val[0] == - (char)ECOMMUNITY_ENCODE_REDIRECT_IP_NH) && + ECOMMUNITY_ENCODE_REDIRECT_IP_NH) && (ecom_eval->val[1] == - (char)ECOMMUNITY_REDIRECT_IP_NH)) { + ECOMMUNITY_REDIRECT_IP_NH)) { /* in case the 2 ecom present, * do not overwrite * draft-ietf-idr-flowspec-redirect @@ -861,10 +859,9 @@ int bgp_pbr_build_and_validate_entry(const struct prefix *p, = ecom_eval->val[7]; api_action_redirect_ip = api_action; } - } else if ((ecom_eval->val[0] == - (char)ECOMMUNITY_ENCODE_IP) && + } else if ((ecom_eval->val[0] == ECOMMUNITY_ENCODE_IP) && (ecom_eval->val[1] == - (char)ECOMMUNITY_FLOWSPEC_REDIRECT_IPV4)) { + ECOMMUNITY_FLOWSPEC_REDIRECT_IPV4)) { /* in case the 2 ecom present, * overwrite simpson draft * update redirect ip fields @@ -888,7 +885,7 @@ int bgp_pbr_build_and_validate_entry(const struct prefix *p, } } else { if (ecom_eval->val[0] != - (char)ECOMMUNITY_ENCODE_TRANS_EXP) + ECOMMUNITY_ENCODE_TRANS_EXP) continue; ret = ecommunity_fill_pbr_action(ecom_eval, api_action, @@ -920,9 +917,9 @@ int bgp_pbr_build_and_validate_entry(const struct prefix *p, } api_action = &api->actions[action_count - 1]; if ((ipv6_ecom_eval->val[1] == - (char)ECOMMUNITY_FLOWSPEC_REDIRECT_IPV6) && + ECOMMUNITY_FLOWSPEC_REDIRECT_IPV6) && (ipv6_ecom_eval->val[0] == - (char)ECOMMUNITY_ENCODE_TRANS_EXP)) { + ECOMMUNITY_ENCODE_TRANS_EXP)) { struct ecommunity *eckey = ecommunity_new(); struct ecommunity_val_ipv6 ecom_copy; diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index f10a84dce9..f28c9adda2 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -2472,13 +2472,16 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, if (NEXTHOP_IS_V6) { attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL; if ((CHECK_FLAG(peer->af_flags[afi][safi], - PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED) - && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local)) - || (!reflect && !transparent - && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local) - && peer->shared_network - && (from == bgp->peer_self - || peer->sort == BGP_PEER_EBGP))) { + PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED) && + IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local)) || + (!reflect && !transparent && + IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local) && + peer->shared_network && + ((from == bgp->peer_self && peer->sort == BGP_PEER_EBGP) || + (from == bgp->peer_self && peer->sort != BGP_PEER_EBGP) || + (from != bgp->peer_self && + IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local) && + peer->sort == BGP_PEER_EBGP)))) { if (safi == SAFI_MPLS_VPN) attr->mp_nexthop_len = BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL; @@ -3618,7 +3621,16 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, struct bgp_path_info_pair old_and_new; int debug = 0; - if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) { + /* + * For default bgp instance, which is deleted i.e. marked hidden + * we are skipping SAFI_MPLS_VPN route table deletion + * in bgp_cleanup_routes. + * So, we need to delete routes from VPNV4 table. + * Here for !IS_BGP_INSTANCE_HIDDEN, + * !(SAFI_MPLS_VPN && AF_IP/AF_IP6), + * we ignore the event for the prefix. + */ + if (BGP_INSTANCE_HIDDEN_DELETE_IN_PROGRESS(bgp, afi, safi)) { if (dest) debug = bgp_debug_bestpath(dest); if (debug) @@ -3757,7 +3769,8 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, if (old_select || new_select) { bgp_bump_version(dest); - if (!bgp->t_rmap_def_originate_eval) + if (!bgp->t_rmap_def_originate_eval && + bgp->rmap_def_originate_eval_timer) event_add_timer( bm->master, update_group_refresh_default_originate_route_map, @@ -6443,16 +6456,21 @@ void bgp_cleanup_routes(struct bgp *bgp) if (afi != AFI_L2VPN) { safi_t safi; safi = SAFI_MPLS_VPN; - for (dest = bgp_table_top(bgp->rib[afi][safi]); dest; - dest = bgp_route_next(dest)) { - table = bgp_dest_get_bgp_table_info(dest); - if (table != NULL) { - bgp_cleanup_table(bgp, table, afi, safi); - bgp_table_finish(&table); - bgp_dest_set_bgp_table_info(dest, NULL); - dest = bgp_dest_unlock_node(dest); - - assert(dest); + if (!IS_BGP_INSTANCE_HIDDEN(bgp)) { + for (dest = bgp_table_top(bgp->rib[afi][safi]); + dest; dest = bgp_route_next(dest)) { + table = bgp_dest_get_bgp_table_info( + dest); + if (table != NULL) { + bgp_cleanup_table(bgp, table, + afi, safi); + bgp_table_finish(&table); + bgp_dest_set_bgp_table_info(dest, + NULL); + dest = bgp_dest_unlock_node( + dest); + assert(dest); + } } } safi = SAFI_ENCAP; @@ -12156,7 +12174,7 @@ static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, bgp = bgp_get_default(); } - if (bgp == NULL) { + if (bgp == NULL || IS_BGP_INSTANCE_HIDDEN(bgp)) { if (!use_json) vty_out(vty, "No BGP process is configured\n"); else @@ -12202,6 +12220,8 @@ static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi, vty_out(vty, "{\n"); for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { + if (IS_BGP_INSTANCE_HIDDEN(bgp)) + continue; route_output = true; if (use_json) { if (!is_first) @@ -12720,7 +12740,7 @@ static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str, { if (!bgp) { bgp = bgp_get_default(); - if (!bgp) { + if (!bgp || IS_BGP_INSTANCE_HIDDEN(bgp)) { if (!use_json) vty_out(vty, "No BGP process is configured\n"); else @@ -13672,6 +13692,8 @@ enum bgp_stats { BGP_STATS_ASPATH_MAXSIZE, BGP_STATS_ASPATH_TOTSIZE, BGP_STATS_ASN_HIGHEST, + BGP_STATS_REDISTRIBUTED, + BGP_STATS_LOCAL_AGGREGATES, BGP_STATS_MAX, }; @@ -13701,6 +13723,8 @@ static const char *table_stats_strs[][2] = { [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)", "averageAsPathSizeBytes"}, [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"}, + [BGP_STATS_REDISTRIBUTED] = {"Redistributed routes", "totalRedistributed"}, + [BGP_STATS_LOCAL_AGGREGATES] = {"Local aggregates", "totalLocalAggregates"}, [BGP_STATS_MAX] = {NULL, NULL} }; @@ -13750,6 +13774,15 @@ static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top, ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))) ts->counts[BGP_STATS_AGGREGATES]++; + if (pi->peer == ts->table->bgp->peer_self) { + if (pi->sub_type == BGP_ROUTE_REDISTRIBUTE) + ts->counts[BGP_STATS_REDISTRIBUTED]++; + + if ((pi->type == ZEBRA_ROUTE_BGP) && + (pi->sub_type == BGP_ROUTE_AGGREGATE)) + ts->counts[BGP_STATS_LOCAL_AGGREGATES]++; + } + /* as-path stats */ if (pi->attr->aspath) { unsigned int hops = aspath_count_hops(pi->attr->aspath); @@ -14365,7 +14398,7 @@ DEFUN (show_ip_bgp_vpn_all_route_prefix, int idx = 0; char *network = NULL; struct bgp *bgp = bgp_get_default(); - if (!bgp) { + if (!bgp || IS_BGP_INSTANCE_HIDDEN(bgp)) { vty_out(vty, "Can't find default instance\n"); return CMD_WARNING; } @@ -15867,7 +15900,7 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name, /* BGP structure lookup. */ if (view_name) { bgp = bgp_lookup_by_name(view_name); - if (bgp == NULL) { + if (bgp == NULL || IS_BGP_INSTANCE_HIDDEN(bgp)) { vty_out(vty, "%% Can't find BGP instance %s\n", view_name); return CMD_WARNING; diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index f9cbf24031..347c5d02a1 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -1920,81 +1920,6 @@ DEFUN (no_rpki_retry_interval, return CMD_SUCCESS; } -#if CONFDATE > 20240916 -CPP_NOTICE("Remove rpki_cache_cmd") -#endif -DEFPY(rpki_cache, rpki_cache_cmd, - "rpki cache <A.B.C.D|WORD> <TCPPORT|(1-65535)$sshport SSH_UNAME SSH_PRIVKEY [KNOWN_HOSTS_PATH]> [source <A.B.C.D>$bindaddr] preference (1-255)", - RPKI_OUTPUT_STRING - "Install a cache server to current group\n" - "IP address of cache server\n" - "Hostname of cache server\n" - "TCP port number\n" - "SSH port number\n" - "SSH user name\n" - "Path to own SSH private key\n" - "Path to the known hosts file\n" - "Configure source IP address of RPKI connection\n" - "Define a Source IP Address\n" - "Preference of the cache server\n" - "Preference value\n") -{ - int return_value; - struct listnode *cache_node; - struct cache *current_cache; - struct rpki_vrf *rpki_vrf; - bool init; - - if (vty->node == RPKI_VRF_NODE) - rpki_vrf = VTY_GET_CONTEXT_SUB(rpki_vrf); - else - rpki_vrf = VTY_GET_CONTEXT(rpki_vrf); - - if (!rpki_vrf) - return CMD_WARNING_CONFIG_FAILED; - - if (!rpki_vrf || !rpki_vrf->cache_list) - return CMD_WARNING; - - init = !!list_isempty(rpki_vrf->cache_list); - - for (ALL_LIST_ELEMENTS_RO(rpki_vrf->cache_list, cache_node, - current_cache)) { - if (current_cache->preference == preference) { - vty_out(vty, - "Cache with preference %ld is already configured\n", - preference); - return CMD_WARNING; - } - } - - // use ssh connection - if (ssh_uname) { -#if defined(FOUND_SSH) - return_value = add_ssh_cache(rpki_vrf, cache, sshport, ssh_uname, - ssh_privkey, known_hosts_path, - preference, bindaddr_str); -#else - return_value = SUCCESS; - vty_out(vty, - "ssh sockets are not supported. Please recompile rtrlib and frr with ssh support. If you want to use it\n"); -#endif - } else { // use tcp connection - return_value = add_tcp_cache(rpki_vrf, cache, tcpport, - preference, bindaddr_str); - } - - if (return_value == ERROR) { - vty_out(vty, "Could not create new rpki cache\n"); - return CMD_WARNING; - } - - if (init) - start(rpki_vrf); - - return CMD_SUCCESS; -} - DEFPY(rpki_cache_tcp, rpki_cache_tcp_cmd, "rpki cache tcp <A.B.C.D|WORD>$cache TCPPORT [source <A.B.C.D>$bindaddr] preference (1-255)", RPKI_OUTPUT_STRING @@ -2820,7 +2745,6 @@ static void install_cli_commands(void) /* Install rpki cache commands */ install_element(RPKI_NODE, &rpki_cache_tcp_cmd); install_element(RPKI_NODE, &rpki_cache_ssh_cmd); - install_element(RPKI_NODE, &rpki_cache_cmd); install_element(RPKI_NODE, &no_rpki_cache_cmd); /* RPKI_VRF_NODE commands */ @@ -2844,7 +2768,6 @@ static void install_cli_commands(void) /* Install rpki cache commands */ install_element(RPKI_VRF_NODE, &rpki_cache_tcp_cmd); install_element(RPKI_VRF_NODE, &rpki_cache_ssh_cmd); - install_element(RPKI_VRF_NODE, &rpki_cache_cmd); install_element(RPKI_VRF_NODE, &no_rpki_cache_cmd); /* Install show commands */ diff --git a/bgpd/bgp_script.h b/bgpd/bgp_script.h index f2f47e940d..9feb550135 100644 --- a/bgpd/bgp_script.h +++ b/bgpd/bgp_script.h @@ -7,7 +7,6 @@ #define __BGP_SCRIPT__ #include <zebra.h> -#include "bgpd.h" #ifdef HAVE_SCRIPTING @@ -18,6 +17,10 @@ */ void bgp_script_init(void); +/* Forward references */ +struct peer; +struct attr; + void lua_pushpeer(lua_State *L, const struct peer *peer); void lua_pushattr(lua_State *L, const struct attr *attr); diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c index 115bc35cdc..90c43b938f 100644 --- a/bgpd/bgp_updgrp.c +++ b/bgpd/bgp_updgrp.c @@ -783,8 +783,11 @@ static int update_group_show_walkcb(struct update_group *updgrp, void *arg) json_updgrp, "replaceLocalAs", CHECK_FLAG(updgrp->conf->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS)); + json_object_boolean_add(json_updgrp, "dualAs", + CHECK_FLAG(updgrp->conf->flags, + PEER_FLAG_DUAL_AS)); } else { - vty_out(vty, " Local AS %u%s%s\n", + vty_out(vty, " Local AS %u%s%s%s\n", updgrp->conf->change_local_as, CHECK_FLAG(updgrp->conf->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) @@ -793,6 +796,10 @@ static int update_group_show_walkcb(struct update_group *updgrp, void *arg) CHECK_FLAG(updgrp->conf->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) ? " replace-as" + : "", + CHECK_FLAG(updgrp->conf->flags, + PEER_FLAG_DUAL_AS) + ? " dual-as" : ""); } } diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index f669564bb8..cf74a6566c 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -879,6 +879,7 @@ int bgp_vty_return(struct vty *vty, enum bgp_create_error_code ret) switch (ret) { case BGP_SUCCESS: case BGP_CREATED: + case BGP_INSTANCE_EXISTS: case BGP_GR_NO_OPERATION: break; case BGP_ERR_INVALID_VALUE: @@ -1418,7 +1419,7 @@ DEFUN_HIDDEN (bgp_local_mac, seq = strtoul(argv[7]->arg, NULL, 10); bgp = bgp_get_default(); - if (!bgp) { + if (!bgp || IS_BGP_INSTANCE_HIDDEN(bgp)) { vty_out(vty, "Default BGP instance is not there\n"); return CMD_WARNING; } @@ -1458,7 +1459,7 @@ DEFUN_HIDDEN (no_bgp_local_mac, memset(&ip, 0, sizeof(ip)); bgp = bgp_get_default(); - if (!bgp) { + if (!bgp || IS_BGP_INSTANCE_HIDDEN(bgp)) { vty_out(vty, "Default BGP instance is not there\n"); return CMD_WARNING; } @@ -1601,8 +1602,12 @@ DEFUN_NOSH (router_bgp, if (is_new_bgp && inst_type == BGP_INSTANCE_TYPE_DEFAULT) vpn_leak_postchange_all(); - if (inst_type == BGP_INSTANCE_TYPE_VRF) + if (inst_type == BGP_INSTANCE_TYPE_VRF || + IS_BGP_INSTANCE_HIDDEN(bgp)) { bgp_vpn_leak_export(bgp); + UNSET_FLAG(bgp->flags, BGP_FLAG_INSTANCE_HIDDEN); + UNSET_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS); + } /* Pending: handle when user tries to change a view to vrf n vv. */ /* for pre-existing bgp instance, @@ -1674,7 +1679,7 @@ DEFUN (no_router_bgp, argv[idx_asn]->arg); return CMD_WARNING_CONFIG_FAILED; } - if (argc > 4) { + if (argc > 4 && strncmp(argv[4]->arg, "vrf", 3) == 0) { name = argv[idx_vrf]->arg; if (strmatch(argv[idx_vrf - 1]->text, "vrf") && strmatch(name, VRF_DEFAULT_NAME)) @@ -5451,7 +5456,7 @@ DEFUN (neighbor_local_as, return CMD_WARNING_CONFIG_FAILED; } - ret = peer_local_as_set(peer, as, 0, 0, argv[idx_number]->arg); + ret = peer_local_as_set(peer, as, 0, 0, 0, argv[idx_number]->arg); return bgp_vty_return(vty, ret); } @@ -5480,19 +5485,20 @@ DEFUN (neighbor_local_as_no_prepend, return CMD_WARNING_CONFIG_FAILED; } - ret = peer_local_as_set(peer, as, 1, 0, argv[idx_number]->arg); + ret = peer_local_as_set(peer, as, 1, 0, 0, argv[idx_number]->arg); return bgp_vty_return(vty, ret); } -DEFUN (neighbor_local_as_no_prepend_replace_as, +DEFPY (neighbor_local_as_no_prepend_replace_as, neighbor_local_as_no_prepend_replace_as_cmd, - "neighbor <A.B.C.D|X:X::X:X|WORD> local-as ASNUM no-prepend replace-as", + "neighbor <A.B.C.D|X:X::X:X|WORD> local-as ASNUM no-prepend replace-as [dual-as$dual_as]", NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "Specify a local-as number\n" "AS number expressed in dotted or plain format used as local AS\n" "Do not prepend local-as to updates from ebgp peers\n" - "Do not prepend local-as to updates from ibgp peers\n") + "Do not prepend local-as to updates from ibgp peers\n" + "Allow peering with a global AS number or local-as number\n") { int idx_peer = 1; int idx_number = 3; @@ -5510,20 +5516,21 @@ DEFUN (neighbor_local_as_no_prepend_replace_as, return CMD_WARNING_CONFIG_FAILED; } - ret = peer_local_as_set(peer, as, 1, 1, argv[idx_number]->arg); + ret = peer_local_as_set(peer, as, 1, 1, dual_as, argv[idx_number]->arg); return bgp_vty_return(vty, ret); } DEFUN (no_neighbor_local_as, no_neighbor_local_as_cmd, - "no neighbor <A.B.C.D|X:X::X:X|WORD> local-as [ASNUM [no-prepend [replace-as]]]", + "no neighbor <A.B.C.D|X:X::X:X|WORD> local-as [ASNUM [no-prepend [replace-as] [dual-as]]]", NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "Specify a local-as number\n" "AS number expressed in dotted or plain format used as local AS\n" "Do not prepend local-as to updates from ebgp peers\n" - "Do not prepend local-as to updates from ibgp peers\n") + "Do not prepend local-as to updates from ibgp peers\n" + "Allow peering with a global AS number or local-as number\n") { int idx_peer = 2; struct peer *peer; @@ -8417,7 +8424,7 @@ DEFPY (bgp_condadv_period, DEFPY (bgp_def_originate_eval, bgp_def_originate_eval_cmd, - "[no$no] bgp default-originate timer (0-3600)$timer", + "[no$no] bgp default-originate timer (0-65535)$timer", NO_STR BGP_STR "Control default-originate\n" @@ -8426,8 +8433,7 @@ DEFPY (bgp_def_originate_eval, { VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp->rmap_def_originate_eval_timer = - no ? RMAP_DEFAULT_ORIGINATE_EVAL_TIMER : timer; + bgp->rmap_def_originate_eval_timer = no ? 0 : timer; if (bgp->t_rmap_def_originate_eval) EVENT_OFF(bgp->t_rmap_def_originate_eval); @@ -10445,9 +10451,9 @@ DEFPY(af_import_vrf_route_map, af_import_vrf_route_map_cmd, bgp_default = bgp_get_default(); if (!bgp_default) { int32_t ret; - as_t as = bgp->as; + as_t as = AS_UNSPECIFIED; - /* Auto-create assuming the same AS */ + /* Auto-create with AS_UNSPECIFIED, to be filled in later */ ret = bgp_get_vty(&bgp_default, &as, NULL, BGP_INSTANCE_TYPE_DEFAULT, NULL, ASNOTATION_UNDEFINED); @@ -10457,6 +10463,8 @@ DEFPY(af_import_vrf_route_map, af_import_vrf_route_map_cmd, "VRF default is not configured as a bgp instance\n"); return CMD_WARNING; } + + SET_FLAG(bgp_default->flags, BGP_FLAG_INSTANCE_HIDDEN); } vpn_leak_prechange(dir, afi, bgp_get_default(), bgp); @@ -10560,7 +10568,9 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd, bgp_default = bgp_get_default(); if (!bgp_default) { - /* Auto-create assuming the same AS */ + as = AS_UNSPECIFIED; + + /* Auto-create with AS_UNSPECIFIED, to be filled in later */ ret = bgp_get_vty(&bgp_default, &as, NULL, BGP_INSTANCE_TYPE_DEFAULT, NULL, ASNOTATION_UNDEFINED); @@ -10570,6 +10580,8 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd, "VRF default is not configured as a bgp instance\n"); return CMD_WARNING; } + + SET_FLAG(bgp_default->flags, BGP_FLAG_INSTANCE_HIDDEN); } vrf_bgp = bgp_lookup_by_name(import_name); @@ -10577,9 +10589,19 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd, if (strcmp(import_name, VRF_DEFAULT_NAME) == 0) { vrf_bgp = bgp_default; } else { - /* Auto-create assuming the same AS */ + as = AS_UNSPECIFIED; + + /* Auto-create with AS_UNSPECIFIED, fill in later */ ret = bgp_get_vty(&vrf_bgp, &as, import_name, bgp_type, NULL, ASNOTATION_UNDEFINED); + if (ret) { + vty_out(vty, + "VRF %s is not configured as a bgp instance\n", + import_name); + return CMD_WARNING; + } + + SET_FLAG(vrf_bgp->flags, BGP_FLAG_INSTANCE_HIDDEN); /* Auto created VRF instances should be marked * properly, otherwise we have a state after bgpd @@ -11550,7 +11572,7 @@ DEFUN(show_bgp_martian_nexthop_db, show_bgp_martian_nexthop_db_cmd, else bgp = bgp_get_default(); - if (!bgp) { + if (!bgp || IS_BGP_INSTANCE_HIDDEN(bgp)) { vty_out(vty, "%% No BGP process is configured\n"); return CMD_WARNING; } @@ -12782,6 +12804,9 @@ static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi, if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) continue; + if (IS_BGP_INSTANCE_HIDDEN(bgp)) + continue; + nbr_output = true; if (use_json) { if (!is_first) @@ -14052,6 +14077,10 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, if (CHECK_FLAG(p->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS)) json_object_boolean_true_add(json_neigh, "localAsReplaceAs"); + + json_object_boolean_add(json_neigh, "localAsReplaceAsDualAs", + !!CHECK_FLAG(p->flags, + PEER_FLAG_DUAL_AS)); } else { if (p->as_type == AS_SPECIFIED || CHECK_FLAG(p->as_type, AS_AUTO) || @@ -14066,13 +14095,15 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, vty_out(vty, ASN_FORMAT(bgp->asnotation), p->change_local_as ? &p->change_local_as : &p->local_as); - vty_out(vty, "%s%s, ", + vty_out(vty, "%s%s%s, ", CHECK_FLAG(p->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) ? " no-prepend" : "", CHECK_FLAG(p->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) ? " replace-as" - : ""); + : "", + CHECK_FLAG(p->flags, PEER_FLAG_DUAL_AS) ? " dual-as" + : ""); } /* peer type internal or confed-internal */ if ((p->as == p->local_as) || (CHECK_FLAG(p->as_type, AS_INTERNAL))) { @@ -16170,6 +16201,9 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty, if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) continue; + if (IS_BGP_INSTANCE_HIDDEN(bgp)) + continue; + nbr_output = true; if (use_json) { if (!(json = json_object_new_object())) { @@ -16825,6 +16859,9 @@ static void bgp_show_all_instances_updgrps_vty(struct vty *vty, afi_t afi, if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) continue; + if (IS_BGP_INSTANCE_HIDDEN(bgp)) + continue; + if (!uj) vty_out(vty, "\nInstance %s:\n", (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) @@ -16947,7 +16984,7 @@ DEFUN (show_bgp_updgrps_stats, struct bgp *bgp; bgp = bgp_get_default(); - if (bgp) + if (bgp && !IS_BGP_INSTANCE_HIDDEN(bgp)) update_group_show_stats(bgp, vty); return CMD_SUCCESS; @@ -18664,6 +18701,8 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp, vty_out(vty, " no-prepend"); if (peergroup_flag_check(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS)) vty_out(vty, " replace-as"); + if (peergroup_flag_check(peer, PEER_FLAG_DUAL_AS)) + vty_out(vty, " dual-as"); vty_out(vty, "\n"); } @@ -18942,6 +18981,10 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp, char *addr; bool flag_scomm, flag_secomm, flag_slcomm; + /* skip hidden default vrf bgp instance */ + if (IS_BGP_INSTANCE_HIDDEN(bgp)) + return; + /* Skip dynamic neighbors. */ if (peer_dynamic_neighbor(peer)) return; @@ -19247,6 +19290,9 @@ static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi, struct peer_group *group; struct listnode *node, *nnode; + /* skip hidden default vrf bgp instance */ + if (IS_BGP_INSTANCE_HIDDEN(bgp)) + return; vty_frame(vty, " !\n address-family "); if (afi == AFI_IP) { @@ -19429,6 +19475,10 @@ int bgp_config_write(struct vty *vty) if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) continue; + /* skip hidden default vrf bgp instance */ + if (IS_BGP_INSTANCE_HIDDEN(bgp)) + continue; + /* Router bgp ASN */ vty_out(vty, "router bgp %s", bgp->as_pretty); @@ -19792,8 +19842,9 @@ int bgp_config_write(struct vty *vty) bgp->condition_check_period); /* default-originate timer configuration */ - if (bgp->rmap_def_originate_eval_timer != - RMAP_DEFAULT_ORIGINATE_EVAL_TIMER) + if (bgp->rmap_def_originate_eval_timer && + bgp->rmap_def_originate_eval_timer != + RMAP_DEFAULT_ORIGINATE_EVAL_TIMER) vty_out(vty, " bgp default-originate timer %u\n", bgp->rmap_def_originate_eval_timer); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 19f26e9c75..bffa5a0e6b 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -542,7 +542,7 @@ static int zebra_read_route(ZAPI_CALLBACK_ARGS) /* Now perform the add/update. */ bgp_redistribute_add(bgp, &api.prefix, &nexthop, ifindex, - nhtype, bhtype, api.distance, api.metric, + nhtype, api.distance, bhtype, api.metric, api.type, api.instance, api.tag); } else { bgp_redistribute_delete(bgp, &api.prefix, api.type, diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 9d36ed9008..a3caa5a806 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1255,7 +1255,6 @@ static void peer_free(struct peer *peer) EVENT_OFF(peer->t_revalidate_all[afi][safi]); assert(!peer->connection->t_write); assert(!peer->connection->t_read); - event_cancel_event_ready(bm->master, peer->connection); /* Free connected nexthop, if present */ if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE) @@ -3421,12 +3420,18 @@ static void bgp_vrf_string_name_delete(void *data) static struct bgp *bgp_create(as_t *as, const char *name, enum bgp_instance_type inst_type, const char *as_pretty, - enum asnotation_mode asnotation) + enum asnotation_mode asnotation, + struct bgp *bgp_old, bool hidden) { struct bgp *bgp; afi_t afi; safi_t safi; + if (hidden) { + bgp = bgp_old; + goto peer_init; + } + bgp = XCALLOC(MTYPE_BGP, sizeof(struct bgp)); bgp->as = *as; if (as_pretty) @@ -3480,18 +3485,24 @@ static struct bgp *bgp_create(as_t *as, const char *name, bgp->peer_self->domainname = XSTRDUP(MTYPE_BGP_PEER_HOST, cmd_domainname_get()); bgp->peer = list_new(); + +peer_init: bgp->peer->cmp = (int (*)(void *, void *))peer_cmp; bgp->peerhash = hash_create(peer_hash_key_make, peer_hash_same, "BGP Peer Hash"); bgp->peerhash->max_size = BGP_PEER_MAX_HASH_SIZE; - bgp->group = list_new(); + if (!hidden) + bgp->group = list_new(); bgp->group->cmp = (int (*)(void *, void *))peer_group_cmp; FOREACH_AFI_SAFI (afi, safi) { - bgp->route[afi][safi] = bgp_table_init(bgp, afi, safi); - bgp->aggregate[afi][safi] = bgp_table_init(bgp, afi, safi); - bgp->rib[afi][safi] = bgp_table_init(bgp, afi, safi); + if (!hidden) { + bgp->route[afi][safi] = bgp_table_init(bgp, afi, safi); + bgp->aggregate[afi][safi] = bgp_table_init(bgp, afi, + safi); + bgp->rib[afi][safi] = bgp_table_init(bgp, afi, safi); + } /* Enable maximum-paths */ bgp_maximum_paths_set(bgp, afi, safi, BGP_PEER_EBGP, @@ -3512,7 +3523,8 @@ static struct bgp *bgp_create(as_t *as, const char *name, bgp->default_subgroup_pkt_queue_max = BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX; bgp_tcp_keepalive_unset(bgp); - bgp_timers_unset(bgp); + if (!hidden) + bgp_timers_unset(bgp); bgp->default_min_holdtime = 0; bgp->restart_time = BGP_DEFAULT_RESTART_TIME; bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME; @@ -3527,10 +3539,10 @@ static struct bgp *bgp_create(as_t *as, const char *name, bgp_addpath_init_bgp_data(&bgp->tx_addpath); bgp->fast_convergence = false; bgp->llgr_stale_time = BGP_DEFAULT_LLGR_STALE_TIME; - bgp->rmap_def_originate_eval_timer = RMAP_DEFAULT_ORIGINATE_EVAL_TIMER; + bgp->rmap_def_originate_eval_timer = 0; #ifdef ENABLE_BGP_VNC - if (inst_type != BGP_INSTANCE_TYPE_VRF) { + if (inst_type != BGP_INSTANCE_TYPE_VRF && !hidden) { bgp->rfapi = bgp_rfapi_new(bgp); assert(bgp->rfapi); assert(bgp->rfapi_cfg); @@ -3547,9 +3559,11 @@ static struct bgp *bgp_create(as_t *as, const char *name, bgp->vpn_policy[afi].import_vrf = list_new(); bgp->vpn_policy[afi].import_vrf->del = bgp_vrf_string_name_delete; - bgp->vpn_policy[afi].export_vrf = list_new(); - bgp->vpn_policy[afi].export_vrf->del = - bgp_vrf_string_name_delete; + if (!hidden) { + bgp->vpn_policy[afi].export_vrf = list_new(); + bgp->vpn_policy[afi].export_vrf->del = + bgp_vrf_string_name_delete; + } SET_FLAG(bgp->af_flags[afi][SAFI_MPLS_VPN], BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL); } @@ -3567,7 +3581,7 @@ static struct bgp *bgp_create(as_t *as, const char *name, bgp->restart_time, &bgp->t_startup); /* printable name we can use in debug messages */ - if (inst_type == BGP_INSTANCE_TYPE_DEFAULT) { + if (inst_type == BGP_INSTANCE_TYPE_DEFAULT && !hidden) { bgp->name_pretty = XSTRDUP(MTYPE_BGP_NAME, "VRF default"); } else { const char *n; @@ -3595,17 +3609,20 @@ static struct bgp *bgp_create(as_t *as, const char *name, bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME; bgp->default_af[AFI_IP][SAFI_UNICAST] = true; - QOBJ_REG(bgp, bgp); + if (!hidden) + QOBJ_REG(bgp, bgp); update_bgp_group_init(bgp); - /* assign a unique rd id for auto derivation of vrf's RD */ - bf_assign_index(bm->rd_idspace, bgp->vrf_rd_id); + if (!hidden) { + /* assign a unique rd id for auto derivation of vrf's RD */ + bf_assign_index(bm->rd_idspace, bgp->vrf_rd_id); - bgp_evpn_init(bgp); - bgp_evpn_vrf_es_init(bgp); - bgp_pbr_init(bgp); - bgp_srv6_init(bgp); + bgp_evpn_init(bgp); + bgp_evpn_vrf_es_init(bgp); + bgp_pbr_init(bgp); + bgp_srv6_init(bgp); + } /*initilize global GR FSM */ bgp_global_gr_init(bgp); @@ -3743,10 +3760,15 @@ int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf, vrf_id_t old_vrf_id, return bgp_check_main_socket(create, bgp); } -int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, const char *name, +int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, + const char *as_pretty, + enum asnotation_mode asnotation, const char *name, enum bgp_instance_type inst_type) { struct bgp *bgp; + struct peer *peer = NULL; + struct listnode *node, *nnode; + bool hidden = false; /* Multiple instance check. */ if (name) @@ -3755,14 +3777,41 @@ int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, const char *name, bgp = bgp_get_default(); if (bgp) { - *bgp_val = bgp; + if (IS_BGP_INSTANCE_HIDDEN(bgp) && *as != AS_UNSPECIFIED) + hidden = true; + /* Handle AS number change */ if (bgp->as != *as) { + if (hidden || CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) { + if (hidden) { + bgp_create(as, name, inst_type, + as_pretty, asnotation, bgp, + hidden); + UNSET_FLAG(bgp->flags, + BGP_FLAG_INSTANCE_HIDDEN); + } else { + bgp->as = *as; + UNSET_FLAG(bgp->vrf_flags, BGP_VRF_AUTO); + } + + /* Set all peer's local AS with this ASN */ + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, + peer)) + peer->local_as = *as; + *bgp_val = bgp; + return BGP_INSTANCE_EXISTS; + } + *as = bgp->as; - return BGP_ERR_AS_MISMATCH; + *bgp_val = bgp; + return BGP_ERR_INSTANCE_MISMATCH; } if (bgp->inst_type != inst_type) return BGP_ERR_INSTANCE_MISMATCH; - return BGP_SUCCESS; + if (hidden) + bgp_create(as, name, inst_type, as_pretty, asnotation, + bgp, hidden); + *bgp_val = bgp; + return BGP_INSTANCE_EXISTS; } *bgp_val = NULL; @@ -3778,11 +3827,13 @@ int bgp_get(struct bgp **bgp_val, as_t *as, const char *name, struct vrf *vrf = NULL; int ret = 0; - ret = bgp_lookup_by_as_name_type(bgp_val, as, name, inst_type); + ret = bgp_lookup_by_as_name_type(bgp_val, as, as_pretty, asnotation, + name, inst_type); if (ret || *bgp_val) return ret; - bgp = bgp_create(as, name, inst_type, as_pretty, asnotation); + bgp = bgp_create(as, name, inst_type, as_pretty, asnotation, NULL, + false); /* * view instances will never work inside of a vrf @@ -4022,6 +4073,15 @@ int bgp_delete(struct bgp *bgp) bgp_damp_disable(bgp, afi, safi); } + if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT && + (bgp_table_top(bgp->rib[AFI_IP][SAFI_MPLS_VPN]) || + bgp_table_top(bgp->rib[AFI_IP6][SAFI_MPLS_VPN]))) { + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug( + "Marking the deleting default bgp instance as hidden"); + SET_FLAG(bgp->flags, BGP_FLAG_INSTANCE_HIDDEN); + } + if (BGP_DEBUG(zebra, ZEBRA)) { if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) zlog_debug("Deleting Default VRF"); @@ -4034,7 +4094,8 @@ int bgp_delete(struct bgp *bgp) } /* unmap from RT list */ - bgp_evpn_vrf_delete(bgp); + if (!IS_BGP_INSTANCE_HIDDEN(bgp)) + bgp_evpn_vrf_delete(bgp); /* unmap bgp vrf label */ vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP); @@ -4066,7 +4127,7 @@ int bgp_delete(struct bgp *bgp) peer_delete(peer); } - if (bgp->peer_self) { + if (bgp->peer_self && !IS_BGP_INSTANCE_HIDDEN(bgp)) { peer_delete(bgp->peer_self); bgp->peer_self = NULL; } @@ -4076,7 +4137,8 @@ int bgp_delete(struct bgp *bgp) /* TODO - Other memory may need to be freed - e.g., NHT */ #ifdef ENABLE_BGP_VNC - rfapi_delete(bgp); + if (!IS_BGP_INSTANCE_HIDDEN(bgp)) + rfapi_delete(bgp); #endif /* Free memory allocated with aggregate address configuration. */ @@ -4118,7 +4180,7 @@ int bgp_delete(struct bgp *bgp) } /* Deregister from Zebra, if needed */ - if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) { + if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp) && !IS_BGP_INSTANCE_HIDDEN(bgp)) { if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug( "%s: deregistering this bgp %s instance from zebra", @@ -4126,17 +4188,19 @@ int bgp_delete(struct bgp *bgp) bgp_zebra_instance_deregister(bgp); } - /* Remove visibility via the master list - there may however still be - * routes to be processed still referencing the struct bgp. - */ - listnode_delete(bm->bgp, bgp); - - /* Free interfaces in this instance. */ - bgp_if_finish(bgp); + if (!IS_BGP_INSTANCE_HIDDEN(bgp)) { + /* Remove visibility via the master list - + * there may however still be routes to be processed + * still referencing the struct bgp. + */ + listnode_delete(bm->bgp, bgp); + /* Free interfaces in this instance. */ + bgp_if_finish(bgp); + } vrf = bgp_vrf_lookup_by_instance_type(bgp); bgp_handle_socket(bgp, vrf, VRF_UNKNOWN, false); - if (vrf) + if (vrf && !IS_BGP_INSTANCE_HIDDEN(bgp)) bgp_vrf_unlink(bgp, vrf); /* Update EVPN VRF pointer */ @@ -4151,7 +4215,22 @@ int bgp_delete(struct bgp *bgp) work_queue_free_and_null(&bgp->process_queue); event_master_free_unused(bm->master); - bgp_unlock(bgp); /* initial reference */ + + if (!IS_BGP_INSTANCE_HIDDEN(bgp)) + bgp_unlock(bgp); /* initial reference */ + else { + for (afi = AFI_IP; afi < AFI_MAX; afi++) { + enum vpn_policy_direction dir; + + if (bgp->vpn_policy[afi].import_vrf) + list_delete(&bgp->vpn_policy[afi].import_vrf); + + dir = BGP_VPN_POLICY_DIR_FROMVPN; + if (bgp->vpn_policy[afi].rtlist[dir]) + ecommunity_free( + &bgp->vpn_policy[afi].rtlist[dir]); + } + } return 0; } @@ -4696,6 +4775,7 @@ static const struct peer_flag_action peer_flag_action_list[] = { {PEER_FLAG_LOCAL_AS, 0, peer_change_reset}, {PEER_FLAG_LOCAL_AS_NO_PREPEND, 0, peer_change_reset}, {PEER_FLAG_LOCAL_AS_REPLACE_AS, 0, peer_change_reset}, + {PEER_FLAG_DUAL_AS, 0, peer_change_reset}, {PEER_FLAG_UPDATE_SOURCE, 0, peer_change_none}, {PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE, 0, peer_change_none}, {PEER_FLAG_EXTENDED_OPT_PARAMS, 0, peer_change_reset}, @@ -5791,6 +5871,10 @@ int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi, subgrp = peer_subgroup(peer, afi, safi); if (rmap) { + if (!peer->bgp->rmap_def_originate_eval_timer) + peer->bgp->rmap_def_originate_eval_timer = + RMAP_DEFAULT_ORIGINATE_EVAL_TIMER; + if (!peer->default_rmap[afi][safi].name || strcmp(rmap, peer->default_rmap[afi][safi].name) != 0) { struct route_map *map = NULL; @@ -5873,6 +5957,10 @@ int peer_default_originate_set(struct peer *peer, afi_t afi, safi_t safi, if (rmap) { struct route_map *map = NULL; + if (!member->bgp->rmap_def_originate_eval_timer) + member->bgp->rmap_def_originate_eval_timer = + RMAP_DEFAULT_ORIGINATE_EVAL_TIMER; + if (member->default_rmap[afi][safi].name) { map = route_map_lookup_by_name( member->default_rmap[afi][safi].name); @@ -6638,9 +6726,9 @@ int peer_allowas_in_unset(struct peer *peer, afi_t afi, safi_t safi) } int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend, - bool replace_as, const char *as_str) + bool replace_as, bool dual_as, const char *as_str) { - bool old_no_prepend, old_replace_as; + bool old_no_prepend, old_replace_as, old_dual_as; struct bgp *bgp = peer->bgp; struct peer *member; struct listnode *node, *nnode; @@ -6653,14 +6741,16 @@ int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend, !!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND); old_replace_as = !!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS); + old_dual_as = !!CHECK_FLAG(peer->flags, PEER_FLAG_DUAL_AS); /* Set flag and configuration on peer. */ peer_flag_set(peer, PEER_FLAG_LOCAL_AS); peer_flag_modify(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND, no_prepend); peer_flag_modify(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS, replace_as); + peer_flag_modify(peer, PEER_FLAG_DUAL_AS, dual_as); - if (peer->change_local_as == as && old_no_prepend == no_prepend - && old_replace_as == replace_as) + if (peer->change_local_as == as && old_no_prepend == no_prepend && + old_replace_as == replace_as && old_dual_as == dual_as) return 0; peer->change_local_as = as; if (as_str) { @@ -6689,10 +6779,11 @@ int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend, PEER_FLAG_LOCAL_AS_NO_PREPEND); old_replace_as = CHECK_FLAG(member->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS); - if (member->change_local_as == as - && CHECK_FLAG(member->flags, PEER_FLAG_LOCAL_AS) - && old_no_prepend == no_prepend - && old_replace_as == replace_as) + old_dual_as = !!CHECK_FLAG(member->flags, PEER_FLAG_DUAL_AS); + if (member->change_local_as == as && + CHECK_FLAG(member->flags, PEER_FLAG_LOCAL_AS) && + old_no_prepend == no_prepend && + old_replace_as == replace_as && old_dual_as == dual_as) continue; /* Set flag and configuration on peer-group member. */ @@ -6701,6 +6792,7 @@ int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend, no_prepend); COND_FLAG(member->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS, replace_as); + COND_FLAG(member->flags, PEER_FLAG_DUAL_AS, dual_as); member->change_local_as = as; if (as_str) member->change_local_as_pretty = XSTRDUP(MTYPE_BGP_NAME, @@ -6723,12 +6815,14 @@ int peer_local_as_unset(struct peer *peer) peer_flag_inherit(peer, PEER_FLAG_LOCAL_AS); peer_flag_inherit(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND); peer_flag_inherit(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS); + peer_flag_inherit(peer, PEER_FLAG_DUAL_AS); PEER_ATTR_INHERIT(peer, peer->group, change_local_as); } else { /* Otherwise remove flag and configuration from peer. */ peer_flag_unset(peer, PEER_FLAG_LOCAL_AS); peer_flag_unset(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND); peer_flag_unset(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS); + peer_flag_unset(peer, PEER_FLAG_DUAL_AS); peer->change_local_as = 0; XFREE(MTYPE_BGP_NAME, peer->change_local_as_pretty); } @@ -6760,6 +6854,7 @@ int peer_local_as_unset(struct peer *peer) UNSET_FLAG(member->flags, PEER_FLAG_LOCAL_AS); UNSET_FLAG(member->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND); UNSET_FLAG(member->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS); + UNSET_FLAG(member->flags, PEER_FLAG_DUAL_AS); member->change_local_as = 0; XFREE(MTYPE_BGP_NAME, member->change_local_as_pretty); member->last_reset = PEER_DOWN_LOCAL_AS_CHANGE; diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index def12ee642..3c3655f0a5 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -550,6 +550,7 @@ struct bgp { #define BGP_FLAG_ENFORCE_FIRST_AS (1ULL << 36) #define BGP_FLAG_DYNAMIC_CAPABILITY (1ULL << 37) #define BGP_FLAG_VNI_DOWN (1ULL << 38) +#define BGP_FLAG_INSTANCE_HIDDEN (1ULL << 39) /* BGP default address-families. * New peers inherit enabled afi/safis from bgp instance. @@ -1507,6 +1508,7 @@ struct peer { #define PEER_FLAG_CAPABILITY_FQDN (1ULL << 37) /* fqdn capability */ #define PEER_FLAG_AS_LOOP_DETECTION (1ULL << 38) /* as path loop detection */ #define PEER_FLAG_EXTENDED_LINK_BANDWIDTH (1ULL << 39) +#define PEER_FLAG_DUAL_AS (1ULL << 40) /* *GR-Disabled mode means unset PEER_FLAG_GRACEFUL_RESTART @@ -2152,6 +2154,7 @@ enum bgp_clear_type { enum bgp_create_error_code { BGP_SUCCESS = 0, BGP_CREATED = 1, + BGP_INSTANCE_EXISTS = 2, BGP_ERR_INVALID_VALUE = -1, BGP_ERR_INVALID_FLAG = -2, BGP_ERR_INVALID_AS = -3, @@ -2443,7 +2446,7 @@ extern int peer_allowas_in_set(struct peer *, afi_t, safi_t, int, int); extern int peer_allowas_in_unset(struct peer *, afi_t, safi_t); extern int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend, - bool replace_as, const char *as_str); + bool replace_as, bool dual_as, const char *as_str); extern int peer_local_as_unset(struct peer *); extern int peer_prefix_list_set(struct peer *, afi_t, safi_t, int, @@ -2822,6 +2825,8 @@ extern struct peer *peer_new(struct bgp *bgp); extern struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp, const char *ip_str, bool use_json); extern int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, + const char *as_pretty, + enum asnotation_mode asnotation, const char *name, enum bgp_instance_type inst_type); @@ -2863,4 +2868,17 @@ extern void bgp_session_reset_safe(struct peer *peer, struct listnode **nnode); /* clang-format on */ #endif +/* Macro to check if default bgp instance is hidden */ +#define IS_BGP_INSTANCE_HIDDEN(_bgp) \ + (CHECK_FLAG(_bgp->flags, BGP_FLAG_INSTANCE_HIDDEN) && \ + (_bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT || \ + _bgp->inst_type == BGP_INSTANCE_TYPE_VRF)) + +/* Macro to check if bgp instance delete in-progress and !hidden */ +#define BGP_INSTANCE_HIDDEN_DELETE_IN_PROGRESS(_bgp, _afi, _safi) \ + (CHECK_FLAG(_bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS) && \ + !IS_BGP_INSTANCE_HIDDEN(_bgp) && \ + !(_afi == AFI_IP && _safi == SAFI_MPLS_VPN) && \ + !(_afi == AFI_IP6 && _safi == SAFI_MPLS_VPN)) + #endif /* _QUAGGA_BGPD_H */ diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index b6d289fac9..438c60a3f6 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -1818,7 +1818,7 @@ Configuring Peers Since sent prefix count is managed by update-groups, this option creates a separate update-group for outgoing updates. -.. clicmd:: neighbor PEER local-as AS-NUMBER [no-prepend] [replace-as] +.. clicmd:: neighbor PEER local-as AS-NUMBER [no-prepend [replace-as [dual-as]]] Specify an alternate AS for this BGP process when interacting with the specified peer. With no modifiers, the specified local-as is prepended to @@ -1834,6 +1834,10 @@ Configuring Peers Note that replace-as can only be specified if no-prepend is. + The ``dual-as`` keyword is used to configure the neighbor to establish a peering + session using the real autonomous-system number (``router bgp ASN``) or by using + the autonomous system number configured with the ``local-as``. + This command is only allowed for eBGP peers. .. clicmd:: neighbor <A.B.C.D|X:X::X:X|WORD> as-override @@ -1972,12 +1976,14 @@ Configuring Peers and will not be displayed as part of a `show run`. The no form of the command turns off this ability. -.. clicmd:: bgp default-originate timer (0-3600) +.. clicmd:: bgp default-originate timer (0-65535) Set the period to rerun the default-originate route-map scanner process. The default is 5 seconds. With a full routing table, it might be useful to increase this setting to avoid scanning the whole BGP table aggressively. + Setting to 0 turns off the scanning at all. + .. clicmd:: bgp default ipv4-unicast This command allows the user to specify that the IPv4 Unicast address diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index 391d42fba1..d588af314c 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -711,10 +711,6 @@ void lsp_print_common(struct isis_lsp *lsp, struct vty *vty, struct json_object } } -#if CONFDATE > 20240916 -CPP_NOTICE("Remove JSON in '-' format") -#endif - void lsp_print_json(struct isis_lsp *lsp, struct json_object *json, char dynhost, struct isis *isis) { @@ -728,19 +724,11 @@ void lsp_print_json(struct isis_lsp *lsp, struct json_object *json, own_json = json_object_new_object(); json_object_object_add(json, "lsp", own_json); json_object_string_add(own_json, "id", LSPid); -#if CONFDATE > 20240916 - CPP_NOTICE("remove own key") -#endif json_object_string_add(own_json, "own", lsp->own_lsp ? "*" : " "); if (lsp->own_lsp) json_object_boolean_add(own_json, "ownLSP", true); - json_object_int_add(json, "pdu-len", lsp->hdr.pdu_len); json_object_int_add(json, "pduLen", lsp->hdr.pdu_len); snprintfrr(buf, sizeof(buf), "0x%08x", lsp->hdr.seqno); -#if CONFDATE > 20240916 - CPP_NOTICE("remove seq-number key") -#endif - json_object_string_add(json, "seq-number", buf); json_object_string_add(json, "seqNumber", buf); snprintfrr(buf, sizeof(buf), "0x%04hx", lsp->hdr.checksum); json_object_string_add(json, "chksum", buf); @@ -751,11 +739,6 @@ void lsp_print_json(struct isis_lsp *lsp, struct json_object *json, } else { json_object_int_add(json, "holdtime", lsp->hdr.rem_lifetime); } -#if CONFDATE > 20240916 - CPP_NOTICE("remove att-p-ol key") -#endif - json_object_string_add( - json, "att-p-ol", lsp_bits2string(lsp->hdr.lsp_bits, b, sizeof(b))); json_object_string_add(json, "attPOl", lsp_bits2string(lsp->hdr.lsp_bits, b, sizeof(b))); } diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 0f37ed012a..8fc0f144b2 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -1469,14 +1469,13 @@ static void spf_adj_list_parse_tlv(struct isis_spftree *spftree, sadj->metric = metric; if (oldmetric) SET_FLAG(flags, F_ISIS_SPF_ADJ_OLDMETRIC); + if ((oldmetric && sadj->metric == ISIS_NARROW_METRIC_INFINITY) || + (!oldmetric && sadj->metric == ISIS_WIDE_METRIC_INFINITY)) + SET_FLAG(flags, F_ISIS_SPF_ADJ_METRIC_INFINITY); sadj->lsp = lsp; sadj->subtlvs = subtlvs; sadj->flags = flags; - if ((oldmetric && metric == ISIS_NARROW_METRIC_INFINITY) - || (!oldmetric && metric == ISIS_WIDE_METRIC_INFINITY)) - SET_FLAG(flags, F_ISIS_SPF_ADJ_METRIC_INFINITY); - /* Set real adjacency. */ if (!CHECK_FLAG(spftree->flags, F_SPFTREE_NO_ADJACENCIES) && !LSP_PSEUDO_ID(id)) { diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index eca944759a..b5caf396c1 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -565,10 +565,6 @@ static void format_item_asla_subtlvs(struct isis_asla_subtlvs *asla, asla->use_bw); } -#if CONFDATE > 20240916 -CPP_NOTICE("Remove JSON in '-' format") -#endif - /* mtid parameter is used to manage multi-topology i.e. IPv4 / IPv6 */ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, struct sbuf *buf, struct json_object *json, @@ -585,10 +581,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { snprintfrr(aux_buf, sizeof(aux_buf), "0x%x", exts->adm_group); -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_string_add(json, "adm-group", aux_buf); json_object_string_add(json, "admGroup", aux_buf); } else { sbuf_push(buf, indent, "Admin Group: 0x%08x\n", @@ -639,13 +631,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, } if (IS_SUBTLV(exts, EXT_LLRI)) { if (json) { -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_int_add(json, "link-local-id", - exts->local_llri); - json_object_int_add(json, "link-remote-id", - exts->remote_llri); json_object_int_add(json, "linkLocalId", exts->local_llri); json_object_int_add(json, "linkRemoteId", @@ -661,10 +646,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { inet_ntop(AF_INET, &exts->local_addr, aux_buf, sizeof(aux_buf)); -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_string_add(json, "local-iface-ip", aux_buf); json_object_string_add(json, "localIfaceIp", aux_buf); } else sbuf_push(buf, indent, @@ -675,11 +656,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { inet_ntop(AF_INET, &exts->neigh_addr, aux_buf, sizeof(aux_buf)); -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_string_add(json, "remote-iface-ip", - aux_buf); json_object_string_add(json, "remoteIfaceIp", aux_buf); } else sbuf_push(buf, indent, @@ -690,11 +666,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { inet_ntop(AF_INET6, &exts->local_addr6, aux_buf, sizeof(aux_buf)); -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_string_add(json, "local-iface-ipv6", - aux_buf); json_object_string_add(json, "localIfaceIpv6", aux_buf); } else sbuf_push(buf, indent, @@ -705,11 +676,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { inet_ntop(AF_INET6, &exts->neigh_addr6, aux_buf, sizeof(aux_buf)); -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_string_add(json, "remote-iface-ipv6", - aux_buf); json_object_string_add(json, "remoteIfaceIpv6", aux_buf); } else sbuf_push(buf, indent, @@ -720,11 +686,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { snprintfrr(aux_buf, sizeof(aux_buf), "%g", exts->max_bw); -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_string_add(json, "max-bandwith-bytes-sec", - aux_buf); json_object_string_add(json, "maxBandwithBytesSec", aux_buf); } else @@ -736,11 +697,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { snprintfrr(aux_buf, sizeof(aux_buf), "%g", exts->max_rsv_bw); -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_string_add( - json, "max-res-bandwith-bytes-sec", aux_buf); json_object_string_add(json, "maxResBandwithBytesSec", aux_buf); } else @@ -763,22 +719,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, json_object_string_add(unrsv_json, cnt_buf, aux_buf); } - -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - /* old deprecated key format */ - unrsv_json = json_object_new_object(); - json_object_object_add(json, "unrsv-bandwith-bytes-sec", - unrsv_json); - for (int j = 0; j < MAX_CLASS_TYPE; j += 1) { - snprintfrr(cnt_buf, sizeof(cnt_buf), "%d", j); - snprintfrr(aux_buf, sizeof(aux_buf), "%g", - exts->unrsv_bw[j]); - json_object_string_add(unrsv_json, cnt_buf, - aux_buf); - } - /* end old deprecated key format */ } else { sbuf_push(buf, indent, "Unreserved Bandwidth:\n"); for (int j = 0; j < MAX_CLASS_TYPE; j += 2) { @@ -791,27 +731,18 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, } } if (IS_SUBTLV(exts, EXT_TE_METRIC)) { - if (json) { -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_int_add(json, "te-metric", exts->te_metric); + if (json) json_object_int_add(json, "teMetric", exts->te_metric); - } else + else sbuf_push(buf, indent, "Traffic Engineering Metric: %u\n", exts->te_metric); } if (IS_SUBTLV(exts, EXT_RMT_AS)) { - if (json) { -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_int_add(json, "inter-as-te-remote-as", - exts->remote_as); + if (json) json_object_int_add(json, "interAsTeRemoteAs", exts->remote_as); - } else + else sbuf_push(buf, indent, "Inter-AS TE Remote AS number: %u\n", exts->remote_as); @@ -820,11 +751,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { inet_ntop(AF_INET6, &exts->remote_ip, aux_buf, sizeof(aux_buf)); -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_string_add( - json, "inter-as-te-remote-asbr-ip", aux_buf); json_object_string_add(json, "interAsTeRemoteAsbrIp", aux_buf); } else @@ -836,16 +762,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (IS_SUBTLV(exts, EXT_DELAY)) { if (json) { struct json_object *avg_json; - avg_json = json_object_new_object(); -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_object_add(json, "avg-delay", avg_json); - json_object_string_add(avg_json, "delay", - IS_ANORMAL(exts->delay) - ? "Anomalous" - : "Normal"); - json_object_int_add(avg_json, "micro-sec", exts->delay); avg_json = json_object_new_object(); json_object_object_add(json, "avgDelay", avg_json); @@ -864,19 +780,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (IS_SUBTLV(exts, EXT_MM_DELAY)) { if (json) { struct json_object *avg_json; - avg_json = json_object_new_object(); -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_object_add(json, "max-min-delay", avg_json); - json_object_string_add(avg_json, "delay", - IS_ANORMAL(exts->min_delay) - ? "Anomalous" - : "Normal"); - snprintfrr(aux_buf, sizeof(aux_buf), "%u / %u", - exts->min_delay & TE_EXT_MASK, - exts->max_delay & TE_EXT_MASK); - json_object_string_add(avg_json, "micro-sec", aux_buf); avg_json = json_object_new_object(); json_object_object_add(json, "maxMinDelay", avg_json); @@ -899,15 +802,10 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, exts->max_delay & TE_EXT_MASK); } if (IS_SUBTLV(exts, EXT_DELAY_VAR)) { - if (json) { -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_int_add(json, "delay-variation-micro-sec", - exts->delay_var & TE_EXT_MASK); + if (json) json_object_int_add(json, "delayVariationMicroSec", exts->delay_var & TE_EXT_MASK); - } else + else sbuf_push(buf, indent, "Delay Variation: %u (micro-sec)\n", exts->delay_var & TE_EXT_MASK); @@ -919,20 +817,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, LOSS_PRECISION)); struct json_object *link_json; -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - link_json = json_object_new_object(); - json_object_object_add(json, "link-packet-loss", - link_json); - json_object_string_add(link_json, "loss", - IS_ANORMAL(exts->pkt_loss) - ? "Anomalous" - : "Normal"); - /* typo */ - json_object_string_add(link_json, "percentaje", - aux_buf); - link_json = json_object_new_object(); json_object_object_add(json, "linkPacketLoss", link_json); @@ -952,12 +836,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { snprintfrr(aux_buf, sizeof(aux_buf), "%g", (exts->res_bw)); -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_string_add(json, - "unidir-residual-band-bytes-sec", - aux_buf); json_object_string_add(json, "unidirResidualBandBytesSec", aux_buf); @@ -971,12 +849,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { snprintfrr(aux_buf, sizeof(aux_buf), "%g", (exts->ava_bw)); -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_string_add( - json, "unidir-available-band-bytes-sec", - aux_buf); json_object_string_add(json, "unidirAvailableBandBytesSec", aux_buf); @@ -991,12 +863,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, snprintfrr(aux_buf, sizeof(aux_buf), "%g", (exts->use_bw)); json_object_string_add(json, - "unidir-utilized-band-bytes-sec", - aux_buf); -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_string_add(json, "unidirUtilizedBandBytesSec", aux_buf); } else @@ -1012,50 +878,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { struct json_object *arr_adj_json, *adj_sid_json; -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - /* old deprecated key format */ - arr_adj_json = json_object_new_array(); - json_object_object_add(json, "adj-sid", arr_adj_json); - for (adj = (struct isis_adj_sid *)exts->adj_sid.head; - adj; adj = adj->next) { - snprintfrr(cnt_buf, sizeof(cnt_buf), "%d", - adj->sid); - adj_sid_json = json_object_new_object(); - json_object_int_add(adj_sid_json, "sid", - adj->sid); - json_object_int_add(adj_sid_json, "weight", - adj->weight); - json_object_string_add(adj_sid_json, "flag-f", - adj->flags & EXT_SUBTLV_LINK_ADJ_SID_FFLG - ? "1" - : "0"); - json_object_string_add(adj_sid_json, "flag-b", - adj->flags & EXT_SUBTLV_LINK_ADJ_SID_BFLG - ? "1" - : "0"); - json_object_string_add(adj_sid_json, "flag-v", - adj->flags & EXT_SUBTLV_LINK_ADJ_SID_VFLG - ? "1" - : "0"); - json_object_string_add(adj_sid_json, "flag-l", - adj->flags & EXT_SUBTLV_LINK_ADJ_SID_LFLG - ? "1" - : "0"); - json_object_string_add(adj_sid_json, "flag-s", - adj->flags & EXT_SUBTLV_LINK_ADJ_SID_SFLG - ? "1" - : "0"); - json_object_string_add(adj_sid_json, "flag-p", - adj->flags & EXT_SUBTLV_LINK_ADJ_SID_PFLG - ? "1" - : "0"); - json_object_array_add(arr_adj_json, - adj_sid_json); - } - /* end old deprecated key format */ - arr_adj_json = json_object_new_array(); json_object_object_add(json, "adjSid", arr_adj_json); for (adj = (struct isis_adj_sid *)exts->adj_sid.head; @@ -1127,57 +949,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { struct json_object *arr_adj_json, *lan_adj_json; -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - /* old deprecated key format */ - arr_adj_json = json_object_new_array(); - json_object_object_add(json, "lan-adj-sid", - arr_adj_json); - for (lan = (struct isis_lan_adj_sid *) - exts->adj_sid.head; - lan; lan = lan->next) { - if (((mtid == ISIS_MT_IPV4_UNICAST) && - (lan->family != AF_INET)) || - ((mtid == ISIS_MT_IPV6_UNICAST) && - (lan->family != AF_INET6))) - continue; - snprintfrr(cnt_buf, sizeof(cnt_buf), "%d", - lan->sid); - lan_adj_json = json_object_new_object(); - json_object_int_add(lan_adj_json, "sid", - lan->sid); - json_object_int_add(lan_adj_json, "weight", - lan->weight); - json_object_string_add(lan_adj_json, "flag-f", - lan->flags & EXT_SUBTLV_LINK_ADJ_SID_FFLG - ? "1" - : "0"); - json_object_string_add(lan_adj_json, "flag-b", - lan->flags & EXT_SUBTLV_LINK_ADJ_SID_BFLG - ? "1" - : "0"); - json_object_string_add(lan_adj_json, "flag-v", - lan->flags & EXT_SUBTLV_LINK_ADJ_SID_VFLG - ? "1" - : "0"); - json_object_string_add(lan_adj_json, "flag-l", - lan->flags & EXT_SUBTLV_LINK_ADJ_SID_LFLG - ? "1" - : "0"); - json_object_string_add(lan_adj_json, "flag-s", - lan->flags & EXT_SUBTLV_LINK_ADJ_SID_SFLG - ? "1" - : "0"); - json_object_string_add(lan_adj_json, "flag-p", - lan->flags & EXT_SUBTLV_LINK_ADJ_SID_PFLG - ? "1" - : "0"); - json_object_array_add(arr_adj_json, - lan_adj_json); - } - /* end old deprecated key format */ - arr_adj_json = json_object_new_array(); json_object_object_add(json, "lanAdjSid", arr_adj_json); for (lan = (struct isis_lan_adj_sid *)exts->adj_sid.head; @@ -1264,57 +1035,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { struct json_object *arr_adj_json, *srv6_endx_sid_json; -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - /* old deprecated key format */ - arr_adj_json = json_object_new_array(); - json_object_object_add(json, "srv6-endx-sid", - arr_adj_json); - for (adj = (struct isis_srv6_endx_sid_subtlv *) - exts->srv6_endx_sid.head; - adj; adj = adj->next) { - snprintfrr(cnt_buf, sizeof(cnt_buf), "%pI6", - &adj->sid); - srv6_endx_sid_json = json_object_new_object(); - json_object_string_addf(srv6_endx_sid_json, - "sid", "%pI6", - &adj->sid); - json_object_string_add(srv6_endx_sid_json, - "algorithm", - sr_algorithm_string( - adj->algorithm)); - json_object_int_add(srv6_endx_sid_json, - "weight", adj->weight); - json_object_string_add(srv6_endx_sid_json, - "behavior", - seg6local_action2str( - adj->behavior)); - json_object_string_add(srv6_endx_sid_json, - "flag-b", - adj->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_BFLG - ? "1" - : "0"); - json_object_string_add(srv6_endx_sid_json, - "flag-s", - adj->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_SFLG - ? "1" - : "0"); - json_object_string_add(srv6_endx_sid_json, - "flag-p", - adj->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_PFLG - ? "1" - : "0"); - json_object_array_add(arr_adj_json, - srv6_endx_sid_json); - if (adj->subsubtlvs) - isis_format_subsubtlvs(adj->subsubtlvs, - NULL, - srv6_endx_sid_json, - indent + 4); - } - /* end old deprecated key format */ - arr_adj_json = json_object_new_array(); json_object_object_add(json, "srv6EndXSID", arr_adj_json); @@ -1390,63 +1110,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, struct json_object *arr_adj_json, *srv6_lan_endx_sid_json; -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - /* old deprecated key format */ - arr_adj_json = json_object_new_array(); - json_object_object_add(json, "srv6-lan-endx-sid", - arr_adj_json); - for (lan = (struct isis_srv6_lan_endx_sid_subtlv *) - exts->srv6_lan_endx_sid.head; - lan; lan = lan->next) { - snprintfrr(cnt_buf, sizeof(cnt_buf), "%pI6", - &lan->sid); - srv6_lan_endx_sid_json = - json_object_new_object(); - json_object_string_addf(srv6_lan_endx_sid_json, - "sid", "%pI6", - &lan->sid); - json_object_int_add(srv6_lan_endx_sid_json, - "weight", lan->weight); - json_object_string_add(srv6_lan_endx_sid_json, - "algorithm", - sr_algorithm_string( - lan->algorithm)); - json_object_int_add(srv6_lan_endx_sid_json, - "weight", lan->weight); - json_object_string_add(srv6_lan_endx_sid_json, - "behavior", - seg6local_action2str( - lan->behavior)); - json_object_string_add(srv6_lan_endx_sid_json, - "flag-b", - lan->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_BFLG - ? "1" - : "0"); - json_object_string_add(srv6_lan_endx_sid_json, - "flag-s", - lan->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_SFLG - ? "1" - : "0"); - json_object_string_add(srv6_lan_endx_sid_json, - "flag-p", - lan->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_PFLG - ? "1" - : "0"); - json_object_string_addf(srv6_lan_endx_sid_json, - "neighbor-id", "%pSY", - lan->neighbor_id); - json_object_array_add(arr_adj_json, - srv6_lan_endx_sid_json); - if (lan->subsubtlvs) - isis_format_subsubtlvs(lan->subsubtlvs, - NULL, - srv6_lan_endx_sid_json, - indent + 4); - } - /* end old deprecated key format */ - arr_adj_json = json_object_new_array(); json_object_object_add(json, "srv6LanEndxSID", arr_adj_json); @@ -2613,33 +2276,6 @@ static void format_item_prefix_sid(uint16_t mtid, struct isis_item *i, } json_object_int_add(sr_json, "alg", sid->algorithm); -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated non boolean json") -#endif - /* old deprecated keys (no booleans) */ - json_object_string_add( - sr_json, "readvertised", - ((sid->flags & ISIS_PREFIX_SID_READVERTISED) ? "yes" - : "")); - json_object_string_add( - sr_json, "node", - ((sid->flags & ISIS_PREFIX_SID_NODE) ? "yes" : "")); - json_object_string_add(sr_json, "php", - ((sid->flags & ISIS_PREFIX_SID_NO_PHP) - ? "no-php" - : "php")); - json_object_string_add( - sr_json, "explicit-null", - ((sid->flags & ISIS_PREFIX_SID_EXPLICIT_NULL) ? "yes" - : "")); - json_object_string_add( - sr_json, "value", - ((sid->flags & ISIS_PREFIX_SID_VALUE) ? "yes" : "")); - json_object_string_add( - sr_json, "local", - ((sid->flags & ISIS_PREFIX_SID_LOCAL) ? "yes" : "")); - /* end deprecated keys (no booleans) */ - struct json_object *flags_json; flags_json = json_object_new_object(); @@ -2788,10 +2424,6 @@ static void format_subtlv_ipv6_source_prefix(struct prefix_ipv6 *p, char prefixbuf[PREFIX2STR_BUFFER]; if (json) { prefix2str(p, prefixbuf, sizeof(prefixbuf)); -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_string_add(json, "ipv6-src-prefix", prefixbuf); json_object_string_add(json, "ipv6SrcPrefix", prefixbuf); } else { sbuf_push(buf, indent, "IPv6 Source Prefix: %s\n", @@ -2895,23 +2527,6 @@ static void format_subsubtlv_srv6_sid_structure( if (json) { struct json_object *sid_struct_json; -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - /* old deprecated key format */ - sid_struct_json = json_object_new_object(); - json_object_object_add(json, "srv6-sid-structure", - sid_struct_json); - json_object_int_add(sid_struct_json, "loc-block-len", - sid_struct->loc_block_len); - json_object_int_add(sid_struct_json, "loc-node-len", - sid_struct->loc_node_len); - json_object_int_add(sid_struct_json, "func-len", - sid_struct->func_len); - json_object_int_add(sid_struct_json, "arg-len", - sid_struct->arg_len); - /* end old deprecated key format */ - sid_struct_json = json_object_new_object(); json_object_object_add(json, "srv6SidStructure", sid_struct_json); @@ -3205,26 +2820,6 @@ static void format_item_srv6_end_sid(uint16_t mtid, struct isis_item *i, if (json) { struct json_object *sid_json; -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - /* old deprecated key format */ - sid_json = json_object_new_object(); - json_object_object_add(json, "srv6-end-sid", sid_json); - json_object_string_add(sid_json, "endpoint-behavior", - seg6local_action2str(sid->behavior)); - json_object_string_addf(sid_json, "sid-value", "%pI6", - &sid->sid); - if (sid->subsubtlvs) { - struct json_object *subtlvs_json; - subtlvs_json = json_object_new_object(); - json_object_object_add(sid_json, "subsubtlvs", - subtlvs_json); - isis_format_subsubtlvs(sid->subsubtlvs, NULL, - subtlvs_json, 0); - } - /* end old deprecated key format */ - sid_json = json_object_new_object(); json_object_object_add(json, "srv6EndSid", sid_json); json_object_string_add(sid_json, "endpointBehavior", @@ -3385,13 +2980,9 @@ static void format_item_area_address(uint16_t mtid, struct isis_item *i, memcpy(iso_addr.area_addr, addr->addr, ISO_ADDR_SIZE); iso_addr.addr_len = addr->len; - if (json) { -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_string_addf(json, "area-addr", "%pIS", &iso_addr); + if (json) json_object_string_addf(json, "areaAddr", "%pIS", &iso_addr); - } else + else sbuf_push(buf, indent, "Area Address: %pIS\n", &iso_addr); } @@ -3479,22 +3070,6 @@ static void format_item_oldstyle_reach(uint16_t mtid, struct isis_item *i, if (json) { struct json_object *old_json, *array_json; -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - /* old deprecated key format */ - old_json = json_object_new_object(); - json_object_object_get_ex(json, "old-reach-style", &array_json); - if (!array_json) { - array_json = json_object_new_array(); - json_object_object_add(json, "old-reach-style", - array_json); - } - json_object_array_add(array_json, old_json); - json_object_string_add(old_json, "is-reach", sys_id); - json_object_int_add(old_json, "metric", r->metric); - /* end old deprecated key format */ - old_json = json_object_new_object(); json_object_object_get_ex(json, "oldReachStyle", &array_json); if (!array_json) { @@ -3582,13 +3157,9 @@ static void format_item_lan_neighbor(uint16_t mtid, struct isis_item *i, char sys_id[ISO_SYSID_STRLEN]; snprintfrr(sys_id, ISO_SYSID_STRLEN, "%pSY", n->mac); - if (json) { -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_string_add(json, "lan-neighbor", sys_id); + if (json) json_object_string_add(json, "lanNeighbor", sys_id); - } else + else sbuf_push(buf, indent, "LAN Neighbor: %s\n", sys_id); } @@ -3660,17 +3231,6 @@ static void format_item_lsp_entry(uint16_t mtid, struct isis_item *i, if (json) { char buf[255]; struct json_object *lsp_json; - lsp_json = json_object_new_object(); -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_object_add(json, "lsp-entry", lsp_json); - json_object_string_add(lsp_json, "id", sys_id); - snprintfrr(buf,sizeof(buf),"0x%08x",e->seqno); - json_object_string_add(lsp_json, "seq", buf); - snprintfrr(buf,sizeof(buf),"0x%04hx",e->checksum); - json_object_string_add(lsp_json, "chksum", buf); - json_object_int_add(lsp_json, "lifetime", e->checksum); lsp_json = json_object_new_object(); json_object_object_add(json, "lspEntry", lsp_json); @@ -3762,31 +3322,6 @@ static void format_item_extended_reach(uint16_t mtid, struct isis_item *i, if (json) { struct json_object *reach_json, *array_json; -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - /* old deprecated key format */ - reach_json = json_object_new_object(); - json_object_object_get_ex(json, "ext-reach", &array_json); - if (!array_json) { - array_json = json_object_new_array(); - json_object_object_add(json, "ext-reach", array_json); - } - json_object_array_add(array_json, reach_json); - json_object_string_add( - reach_json, "mt-id", - (mtid == ISIS_MT_IPV4_UNICAST) ? "Extended" : "MT"); - json_object_string_add(reach_json, "id", sys_id); - json_object_int_add(reach_json, "metric", r->metric); - if (mtid != ISIS_MT_IPV4_UNICAST) - json_object_string_add(reach_json, "mt-name", - isis_mtid2str(mtid)); - - if (r->subtlvs) - format_item_ext_subtlvs(r->subtlvs, NULL, reach_json, - indent + 2, mtid); - /* end old deprecated key format */ - reach_json = json_object_new_object(); json_object_object_get_ex(json, "extReach", &array_json); if (!array_json) { @@ -3935,24 +3470,6 @@ static void format_item_oldstyle_ip_reach(uint16_t mtid, struct isis_item *i, if (json) { struct json_object *old_json, *array_json; -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - /* old deprecated key format */ - old_json = json_object_new_object(); - json_object_object_get_ex(json, "old-ip-reach-style", - &array_json); - if (!array_json) { - array_json = json_object_new_array(); - json_object_object_add(json, "old-ip-reach-style", - old_json); - } - json_object_array_add(array_json, old_json); - json_object_string_add(old_json, "prefix", - prefix2str(&r->prefix, prefixbuf, sizeof(prefixbuf))); - json_object_int_add(old_json, "metric", r->metric); - /* end old deprecated key format */ - old_json = json_object_new_object(); json_object_object_get_ex(json, "oldIpReachStyle", &array_json); if (!array_json) { @@ -4058,19 +3575,6 @@ static void format_tlv_protocols_supported(struct isis_protocols_supported *p, struct json_object *protocol_json; char buf[255]; -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - /* old deprecated key format */ - protocol_json = json_object_new_object(); - json_object_object_add(json, "protocols-supported", - protocol_json); - for (uint8_t i = 0; i < p->count; i++) { - snprintfrr(buf, sizeof(buf), "%d", i); - json_object_string_add(protocol_json, buf, - nlpid2str(p->protocols[i])); - } - protocol_json = json_object_new_object(); json_object_object_add(json, "supportedProtocols", protocol_json); @@ -4079,7 +3583,6 @@ static void format_tlv_protocols_supported(struct isis_protocols_supported *p, json_object_string_add(protocol_json, buf, nlpid2str(p->protocols[i])); } - /* end old deprecated key format */ } else { sbuf_push(buf, indent, "Protocols Supported: "); for (uint8_t i = 0; i < p->count; i++) { @@ -4295,13 +3798,9 @@ static void format_item_global_ipv6_address(uint16_t mtid, struct isis_item *i, char addrbuf[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &a->addr, addrbuf, sizeof(addrbuf)); - if (json) { -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_string_add(json, "global-ipv6", addrbuf); + if (json) json_object_string_add(json, "globalIpv6", addrbuf); - } else + else sbuf_push(buf, indent, "Global IPv6 Interface Address: %s\n", addrbuf); } @@ -4383,12 +3882,6 @@ static void format_item_mt_router_info(uint16_t mtid, struct isis_item *i, json_object_string_add(mt_json, "mtDescription", isis_mtid2str(mtid)); -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated non boolean format") -#endif - json_object_string_add(mt_json, "overload", info->overload?"true":"false"); - json_object_string_add(mt_json, "attached", info->attached?"true":"false"); - json_object_boolean_add(mt_json, "overloadBit", !!info->overload); json_object_boolean_add(mt_json, "attachedbit", @@ -4475,13 +3968,9 @@ static void format_tlv_te_router_id(const struct in_addr *id, struct sbuf *buf, char addrbuf[INET_ADDRSTRLEN]; inet_ntop(AF_INET, id, addrbuf, sizeof(addrbuf)); - if (json) { -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_string_add(json, "te-router-id", addrbuf); + if (json) json_object_string_add(json, "teRouterId", addrbuf); - } else + else sbuf_push(buf, indent, "TE Router ID: %s\n", addrbuf); } @@ -4556,37 +4045,6 @@ static void format_item_extended_ip_reach(uint16_t mtid, struct isis_item *i, char prefixbuf[PREFIX2STR_BUFFER]; if (json) { -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - /* old deprecated key format */ - ext_json = json_object_new_object(); - json_object_object_get_ex(json, "ext-ip-reach", &array_json); - if (!array_json) { - array_json = json_object_new_array(); - json_object_object_add(json, "ext-ip-reach", array_json); - } - json_object_array_add(array_json, ext_json); - json_object_string_add(ext_json, "mt-id", - (mtid == ISIS_MT_IPV4_UNICAST) - ? "Extended" - : "MT"); - json_object_string_add(ext_json, "ip-reach", - prefix2str(&r->prefix, prefixbuf, - sizeof(prefixbuf))); - json_object_int_add(ext_json, "ip-reach-metric", r->metric); - json_object_string_add(ext_json, "down", r->down ? "yes" : ""); - if (mtid != ISIS_MT_IPV4_UNICAST) - json_object_string_add(ext_json, "mt-name", - isis_mtid2str(mtid)); - if (r->subtlvs) { - struct json_object *subtlv_json; - subtlv_json = json_object_new_object(); - json_object_object_add(ext_json, "subtlvs", subtlv_json); - format_subtlvs(r->subtlvs, NULL, subtlv_json, 0); - } - /* end old deprecated key format */ - ext_json = json_object_new_object(); json_object_object_get_ex(json, "extIpReach", &array_json); if (!array_json) { @@ -4869,13 +4327,9 @@ static void format_tlv_te_router_id_ipv6(const struct in6_addr *id, char addrbuf[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, id, addrbuf, sizeof(addrbuf)); - if (json) { -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_string_add(json, "ipv6-te-router-id", addrbuf); + if (json) json_object_string_add(json, "ipv6TeRouterId", addrbuf); - } else + else sbuf_push(buf, indent, "IPv6 TE Router ID: %s\n", addrbuf); } @@ -4953,30 +4407,6 @@ static void format_tlv_spine_leaf(const struct isis_spine_leaf *spine_leaf, if (json) { struct json_object *spine_json; -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - /* old deprecated format */ - spine_json = json_object_new_object(); - json_object_object_add(json, "spine-leaf-extension", - spine_json); - if (spine_leaf->has_tier) { - snprintfrr(aux_buf, sizeof(aux_buf), "%hhu", - spine_leaf->tier); - json_object_string_add( - spine_json, "tier", - (spine_leaf->tier == ISIS_TIER_UNDEFINED) - ? "undefined" - : aux_buf); - } - json_object_string_add(spine_json, "flag-leaf", - spine_leaf->is_leaf ? "yes" : ""); - json_object_string_add(spine_json, "flag-spine", - spine_leaf->is_spine ? "yes" : ""); - json_object_string_add(spine_json, "flag-backup", - spine_leaf->is_backup ? "yes" : ""); - /* end old deprecated format */ - spine_json = json_object_new_object(); json_object_object_add(json, "spineLeafExtension", spine_json); if (spine_leaf->has_tier) { @@ -5136,26 +4566,6 @@ format_tlv_threeway_adj(const struct isis_threeway_adj *threeway_adj, if (json) { struct json_object *three_json; -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - /* old deprecated key format */ - three_json = json_object_new_object(); - json_object_object_add(json, "p2p-three-way-adj", three_json); - json_object_string_add( - three_json, "state-name", - isis_threeway_state_name(threeway_adj->state)); - json_object_int_add(three_json, "state", threeway_adj->state); - json_object_int_add(three_json, "ext-local-circuit-id", - threeway_adj->local_circuit_id); - if (threeway_adj->neighbor_set) { - json_object_string_add(three_json, "neigh-system-id", - sys_id); - json_object_int_add(three_json, "neigh-ext-circuit-id", - threeway_adj->neighbor_circuit_id); - } - /* end old deprecated key format */ - three_json = json_object_new_object(); json_object_object_add(json, "p2pThreeWayAdj", three_json); json_object_string_add(three_json, "stateName", @@ -5306,40 +4716,6 @@ static void format_item_ipv6_reach(uint16_t mtid, struct isis_item *i, subtlvs_json); format_subtlvs(r->subtlvs, NULL, subtlvs_json, 0); } - -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - /* old deprecated JSON key format */ - reach_json = json_object_new_object(); - json_object_object_get_ex(json, "ipv6-reach", &array_json); - if (!array_json) { - array_json = json_object_new_array(); - json_object_object_add(json, "ipv6-reach", array_json); - } - json_object_array_add(array_json, reach_json); - json_object_string_add(reach_json, "mt-id", - (mtid == ISIS_MT_IPV4_UNICAST) ? "" - : "mt"); - json_object_string_add( - reach_json, "prefix", - prefix2str(&r->prefix, prefixbuf, sizeof(prefixbuf))); - json_object_int_add(reach_json, "metric", r->metric); - json_object_string_add(reach_json, "down", - r->down ? "yes" : ""); - json_object_string_add(reach_json, "external", - r->external ? "yes" : ""); - if (mtid != ISIS_MT_IPV4_UNICAST) - json_object_string_add(reach_json, "mt-name", - isis_mtid2str(mtid)); - if (r->subtlvs) { - struct json_object *subtlvs_json; - subtlvs_json = json_object_new_object(); - json_object_object_add(reach_json, "subtlvs", - subtlvs_json); - format_subtlvs(r->subtlvs, NULL, subtlvs_json, 0); - } - /* end deprecated key format */ } else { sbuf_push(buf, indent, "%sIPv6 Reachability: %s (Metric: %u)%s%s", @@ -5552,22 +4928,6 @@ static void format_tlv_router_cap_json(const struct isis_router_cap *router_cap, /* Router ID and Flags */ struct json_object *cap_json; -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - /* deprecated JSON key format */ - cap_json = json_object_new_object(); - json_object_object_add(json, "router-capability", cap_json); - inet_ntop(AF_INET, &router_cap->router_id, addrbuf, sizeof(addrbuf)); - json_object_string_add(cap_json, "id", addrbuf); - json_object_string_add( - cap_json, "flag-d", - router_cap->flags & ISIS_ROUTER_CAP_FLAG_D ? "1" : "0"); - json_object_string_add( - cap_json, "flag-s", - router_cap->flags & ISIS_ROUTER_CAP_FLAG_S ? "1" : "0"); - /* end deprecated JSON key format */ - cap_json = json_object_new_object(); json_object_object_add(json, "routerCapability", cap_json); inet_ntop(AF_INET, &router_cap->router_id, addrbuf, sizeof(addrbuf)); @@ -5582,23 +4942,6 @@ static void format_tlv_router_cap_json(const struct isis_router_cap *router_cap, if (router_cap->srgb.range_size != 0) { struct json_object *gb_json; -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - /* deprecated old key format */ - gb_json = json_object_new_object(); - json_object_object_add(json, "segment-routing-gb", gb_json); - json_object_string_add(gb_json, "ipv4", - IS_SR_IPV4(&router_cap->srgb) ? "1" - : "0"); - json_object_string_add(gb_json, "ipv6", - IS_SR_IPV6(&router_cap->srgb) ? "1" - : "0"); - json_object_int_add(gb_json, "global-block-base", - router_cap->srgb.lower_bound); - json_object_int_add(gb_json, "global-block-range", - router_cap->srgb.range_size); - gb_json = json_object_new_object(); json_object_object_add(json, "segmentRoutingGb", gb_json); json_object_boolean_add(gb_json, "ipv4", @@ -5615,18 +4958,6 @@ static void format_tlv_router_cap_json(const struct isis_router_cap *router_cap, if (router_cap->srlb.range_size != 0) { struct json_object *lb_json; -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - /* old deprecated key format */ - lb_json = json_object_new_object(); - json_object_object_add(json, "segment-routing-lb", lb_json); - json_object_int_add(lb_json, "global-block-base", - router_cap->srlb.lower_bound); - json_object_int_add(lb_json, "global-block-range", - router_cap->srlb.range_size); - /* end old deprecated key format */ - lb_json = json_object_new_object(); json_object_object_add(json, "segmentRoutingLb", lb_json); json_object_int_add(lb_json, "globalBlockBase", @@ -5640,23 +4971,6 @@ static void format_tlv_router_cap_json(const struct isis_router_cap *router_cap, char buf[255]; struct json_object *alg_json; -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - /* old deprecated key format */ - alg_json = json_object_new_object(); - json_object_object_add(json, "segment-routing-algorithm", - alg_json); - for (int i = 0; i < SR_ALGORITHM_COUNT; i++) - if (router_cap->algo[i] != SR_ALGORITHM_UNSET) { - snprintfrr(buf, sizeof(buf), "%d", i); - json_object_string_add(alg_json, buf, - router_cap->algo[i] == 0 - ? "SPF" - : "Strict SPF"); - } - /* end old deprecated key format */ - alg_json = json_object_new_object(); json_object_object_add(json, "segmentRoutingAlgorithm", alg_json); @@ -6511,24 +5825,16 @@ static void format_item_auth(uint16_t mtid, struct isis_item *i, struct isis_auth *auth = (struct isis_auth *)i; char obuf[768]; - if (json) { -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_string_add(json, "test-auth", "ok"); + if (json) json_object_string_add(json, "testAuth", "ok"); - } else + else sbuf_push(buf, indent, "Authentication:\n"); switch (auth->type) { case ISIS_PASSWD_TYPE_CLEARTXT: zlog_sanitize(obuf, sizeof(obuf), auth->value, auth->length); - if (json) { -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_string_add(json, "auth-pass", obuf); + if (json) json_object_string_add(json, "authPass", obuf); - } else + else sbuf_push(buf, indent, " Password: %s\n", obuf); break; case ISIS_PASSWD_TYPE_HMAC_MD5: @@ -6536,23 +5842,15 @@ static void format_item_auth(uint16_t mtid, struct isis_item *i, snprintf(obuf + 2 * j, sizeof(obuf) - 2 * j, "%02hhx", auth->value[j]); } - if (json) { -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_string_add(json, "auth-hmac-md5", obuf); + if (json) json_object_string_add(json, "authHmacMd5", obuf); - } else + else sbuf_push(buf, indent, " HMAC-MD5: %s\n", obuf); break; default: - if (json) { -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_int_add(json, "auth-unknown", auth->type); + if (json) json_object_int_add(json, "authUnknown", auth->type); - } else + else sbuf_push(buf, indent, " Unknown (%hhu)\n", auth->type); break; @@ -6668,18 +5966,6 @@ static void format_tlv_purge_originator(struct isis_purge_originator *poi, if (json) { struct json_object *purge_json; -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - /* old deprecated key format */ - purge_json = json_object_new_object(); - json_object_object_add(json, "purge_originator", purge_json); - - json_object_string_add(purge_json, "id", gen_id); - if (poi->sender_set) - json_object_string_add(purge_json, "rec-from", sen_id); - /* end old deprecated key format */ - purge_json = json_object_new_object(); json_object_object_add(json, "purgeOriginator", purge_json); @@ -7229,33 +6515,6 @@ static void format_item_srv6_locator(uint16_t mtid, struct isis_item *i, if (json) { struct json_object *loc_json; -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - /* old json key format */ - loc_json = json_object_new_object(); - json_object_object_add(json, "srv6-locator", loc_json); - json_object_int_add(loc_json, "mt-id", mtid); - json_object_string_addf(loc_json, "prefix", "%pFX", - &loc->prefix); - json_object_int_add(loc_json, "metric", loc->metric); - json_object_string_add( - loc_json, "d-flag", - CHECK_FLAG(loc->flags, ISIS_TLV_SRV6_LOCATOR_FLAG_D) - ? "yes" - : ""); - json_object_int_add(loc_json, "algorithm", loc->algorithm); - json_object_string_add(loc_json, "mt-name", - isis_mtid2str(mtid)); - if (loc->subtlvs) { - struct json_object *subtlvs_json; - subtlvs_json = json_object_new_object(); - json_object_object_add(loc_json, "subtlvs", - subtlvs_json); - format_subtlvs(loc->subtlvs, NULL, subtlvs_json, 0); - } - /* old deprecated key format */ - loc_json = json_object_new_object(); json_object_object_add(json, "srv6Locator", loc_json); json_object_int_add(loc_json, "mtId", mtid); @@ -7557,13 +6816,9 @@ static void format_tlvs(struct isis_tlvs *tlvs, struct sbuf *buf, struct json_ob &tlvs->area_addresses, buf, json, indent); if (tlvs->mt_router_info_empty) { - if (json) { -#if CONFDATE > 20240916 - CPP_NOTICE("remove deprecated key format with -") -#endif - json_object_string_add(json, "mt-router-info", "none"); + if (json) json_object_object_add(json, "mtRouterInfo", NULL); - } else + else sbuf_push(buf, indent, "MT Router Info: None\n"); } else { format_items(ISIS_CONTEXT_LSP, ISIS_TLV_MT_ROUTER_INFO, diff --git a/lib/libfrr.c b/lib/libfrr.c index 0a575abac6..a1982841d3 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -1125,9 +1125,12 @@ static void frr_terminal_close(int isexit) * don't redirect when stdout is set with --log stdout */ for (fd = 2; fd >= 0; fd--) - if (isatty(fd) && - (fd != STDOUT_FILENO || !logging_to_stdout)) + if (logging_to_stdout && isatty(fd) && + fd == STDOUT_FILENO) { + /* Do nothing. */ + } else { dup2(nullfd, fd); + } close(nullfd); } } @@ -1213,9 +1216,12 @@ void frr_run(struct event_loop *master) * stdout */ for (fd = 2; fd >= 0; fd--) - if (isatty(fd) && - (fd != STDOUT_FILENO || !logging_to_stdout)) + if (logging_to_stdout && isatty(fd) && + fd == STDOUT_FILENO) { + /* Do nothing. */ + } else { dup2(nullfd, fd); + } close(nullfd); } diff --git a/lib/northbound.h b/lib/northbound.h index b2cccb6716..dd3fbf8f73 100644 --- a/lib/northbound.h +++ b/lib/northbound.h @@ -1716,6 +1716,7 @@ extern void nb_terminate(void); extern void nb_oper_init(struct event_loop *loop); extern void nb_oper_terminate(void); +extern bool nb_oper_is_yang_lib_query(const char *xpath); #ifdef __cplusplus } diff --git a/lib/northbound_oper.c b/lib/northbound_oper.c index e95f99a2bd..a3ff360780 100644 --- a/lib/northbound_oper.c +++ b/lib/northbound_oper.c @@ -1741,6 +1741,16 @@ static enum nb_error nb_op_walk_start(struct nb_op_yield_state *ys) return __walk(ys, false); } +bool nb_oper_is_yang_lib_query(const char *xpath) +{ + const char *libstr = "/ietf-yang-library:"; + const unsigned long liblen = strlen(libstr); + + if (strncmp(libstr, xpath, liblen)) + return false; + + return strlen(xpath) > liblen; +} void *nb_oper_walk(const char *xpath, struct yang_translator *translator, uint32_t flags, bool should_batch, nb_oper_data_cb cb, diff --git a/mgmtd/mgmt.c b/mgmtd/mgmt.c index cfadad4829..02c54b9215 100644 --- a/mgmtd/mgmt.c +++ b/mgmtd/mgmt.c @@ -57,6 +57,9 @@ void mgmt_init(void) /* Initialize MGMTD Transaction module */ mgmt_txn_init(mm, mm->master); + /* Add yang-library module */ + yang_module_load("ietf-yang-library", NULL); + /* Initialize the MGMTD Frontend Adapter Module */ mgmt_fe_adapter_init(mm->master); diff --git a/mgmtd/mgmt_fe_adapter.c b/mgmtd/mgmt_fe_adapter.c index 8d305ed52f..32f28a5774 100644 --- a/mgmtd/mgmt_fe_adapter.c +++ b/mgmtd/mgmt_fe_adapter.c @@ -1337,6 +1337,31 @@ static void fe_adapter_handle_get_data(struct mgmt_fe_session_ctx *session, goto done; } + /* Check for yang-library shortcut */ + if (nb_oper_is_yang_lib_query(msg->xpath)) { + struct lyd_node *ylib = NULL; + LY_ERR err; + + err = ly_ctx_get_yanglib_data(ly_native_ctx, &ylib, "%u", + ly_ctx_get_change_count( + ly_native_ctx)); + if (err) { + fe_adapter_send_error(session, req_id, false, err, + "Error getting yang-library data, session-id: %" PRIu64 + " error: %s", + session->session_id, + ly_last_errmsg()); + } else { + yang_lyd_trim_xpath(&ylib, msg->xpath); + (void)fe_adapter_send_tree_data(session, req_id, false, + msg->result_type, + wd_options, ylib, 0); + } + if (ylib) + lyd_free_all(ylib); + goto done; + } + switch (msg->datastore) { case MGMT_MSG_DATASTORE_CANDIDATE: ds_id = MGMTD_DS_CANDIDATE; diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c index 0c5be29ff8..343dfefcec 100644 --- a/ospf6d/ospf6_abr.c +++ b/ospf6d/ospf6_abr.c @@ -553,8 +553,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, lsa_header = (struct ospf6_lsa_header *)buffer; if (route->type == OSPF6_DEST_TYPE_ROUTER) { - router_lsa = (struct ospf6_inter_router_lsa *) - ospf6_lsa_header_end(lsa_header); + router_lsa = lsa_after_header(lsa_header); p = (caddr_t)router_lsa + sizeof(struct ospf6_inter_router_lsa); /* Fill Inter-Area-Router-LSA */ @@ -565,8 +564,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, router_lsa->router_id = ADV_ROUTER_IN_PREFIX(&route->prefix); type = htons(OSPF6_LSTYPE_INTER_ROUTER); } else { - prefix_lsa = (struct ospf6_inter_prefix_lsa *) - ospf6_lsa_header_end(lsa_header); + prefix_lsa = lsa_after_header(lsa_header); p = (caddr_t)prefix_lsa + sizeof(struct ospf6_inter_prefix_lsa); /* Fill Inter-Area-Prefix-LSA */ @@ -1016,8 +1014,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) oa->name); } - prefix_lsa = (struct ospf6_inter_prefix_lsa *) - ospf6_lsa_header_end(lsa->header); + prefix_lsa = lsa_after_header(lsa->header); prefix.family = AF_INET6; prefix.prefixlen = prefix_lsa->prefix.prefix_length; ospf6_prefix_in6_addr(&prefix.u.prefix6, prefix_lsa, @@ -1036,8 +1033,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) oa->name); } - router_lsa = (struct ospf6_inter_router_lsa *) - ospf6_lsa_header_end(lsa->header); + router_lsa = lsa_after_header(lsa->header); ospf6_linkstate_prefix(router_lsa->router_id, htonl(0), &prefix); if (is_debug) inet_ntop(AF_INET, &router_lsa->router_id, buf, @@ -1429,8 +1425,7 @@ static char *ospf6_inter_area_prefix_lsa_get_prefix_str(struct ospf6_lsa *lsa, char tbuf[16]; if (lsa != NULL) { - prefix_lsa = (struct ospf6_inter_prefix_lsa *) - ospf6_lsa_header_end(lsa->header); + prefix_lsa = lsa_after_header(lsa->header); ospf6_prefix_in6_addr(&in6, prefix_lsa, &prefix_lsa->prefix); if (buf) { @@ -1452,8 +1447,7 @@ static int ospf6_inter_area_prefix_lsa_show(struct vty *vty, struct ospf6_inter_prefix_lsa *prefix_lsa; char buf[INET6_ADDRSTRLEN]; - prefix_lsa = (struct ospf6_inter_prefix_lsa *)ospf6_lsa_header_end( - lsa->header); + prefix_lsa = lsa_after_header(lsa->header); if (use_json) { json_object_int_add( @@ -1489,9 +1483,7 @@ static char *ospf6_inter_area_router_lsa_get_prefix_str(struct ospf6_lsa *lsa, struct ospf6_inter_router_lsa *router_lsa; if (lsa != NULL) { - router_lsa = (struct ospf6_inter_router_lsa *) - ospf6_lsa_header_end(lsa->header); - + router_lsa = lsa_after_header(lsa->header); if (buf) inet_ntop(AF_INET, &router_lsa->router_id, buf, buflen); @@ -1508,8 +1500,7 @@ static int ospf6_inter_area_router_lsa_show(struct vty *vty, struct ospf6_inter_router_lsa *router_lsa; char buf[64]; - router_lsa = (struct ospf6_inter_router_lsa *)ospf6_lsa_header_end( - lsa->header); + router_lsa = lsa_after_header(lsa->header); ospf6_options_printbuf(router_lsa->options, buf, sizeof(buf)); if (use_json) { diff --git a/ospf6d/ospf6_abr.h b/ospf6d/ospf6_abr.h index 52686ed49f..ab9e000d43 100644 --- a/ospf6d/ospf6_abr.h +++ b/ospf6d/ospf6_abr.h @@ -17,22 +17,6 @@ extern unsigned char conf_debug_ospf6_abr; #define OSPF6_DEBUG_ABR_OFF() (conf_debug_ospf6_abr = 0) #define IS_OSPF6_DEBUG_ABR (conf_debug_ospf6_abr) -/* Inter-Area-Prefix-LSA */ -#define OSPF6_INTER_PREFIX_LSA_MIN_SIZE 4U /* w/o IPv6 prefix */ -struct ospf6_inter_prefix_lsa { - uint32_t metric; - struct ospf6_prefix prefix; -}; - -/* Inter-Area-Router-LSA */ -#define OSPF6_INTER_ROUTER_LSA_FIX_SIZE 12U -struct ospf6_inter_router_lsa { - uint8_t mbz; - uint8_t options[3]; - uint32_t metric; - uint32_t router_id; -}; - #define OSPF6_ABR_SUMMARY_METRIC(E) \ (ntohl((E)->metric & htonl(OSPF6_EXT_PATH_METRIC_MAX))) #define OSPF6_ABR_SUMMARY_METRIC_SET(E, C) \ diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 2065527c93..8fa85badbe 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -39,6 +39,7 @@ #include "ospf6d.h" #include "ospf6_spf.h" #include "ospf6_nssa.h" +#include "ospf6_tlv.h" #include "ospf6_gr.h" #include "lib/json.h" @@ -102,8 +103,7 @@ struct ospf6_lsa *ospf6_as_external_lsa_originate(struct ospf6_route *route, /* prepare buffer */ memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; - as_external_lsa = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( - lsa_header); + as_external_lsa = lsa_after_header(lsa_header); p = (caddr_t)((caddr_t)as_external_lsa + sizeof(struct ospf6_as_external_lsa)); @@ -216,8 +216,7 @@ static route_tag_t ospf6_as_external_lsa_get_tag(struct ospf6_lsa *lsa) if (!lsa) return 0; - external = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( - lsa->header); + external = lsa_after_header(lsa->header); if (!CHECK_FLAG(external->bits_metric, OSPF6_ASBR_BIT_T)) return 0; @@ -520,8 +519,7 @@ void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa) type = ntohs(lsa->header->type); oa = lsa->lsdb->data; - external = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( - lsa->header); + external = lsa_after_header(lsa->header); if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) zlog_debug("Calculate AS-External route for %s", lsa->name); @@ -725,8 +723,7 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa, int type; bool debug = false; - external = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( - lsa->header); + external = lsa_after_header(lsa->header); if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) || (IS_OSPF6_DEBUG_NSSA)) debug = true; @@ -2424,8 +2421,7 @@ static char *ospf6_as_external_lsa_get_prefix_str(struct ospf6_lsa *lsa, char tbuf[16]; if (lsa) { - external = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( - lsa->header); + external = lsa_after_header(lsa->header); if (pos == 0) { ospf6_prefix_in6_addr(&in6, external, @@ -2459,8 +2455,7 @@ static int ospf6_as_external_lsa_show(struct vty *vty, struct ospf6_lsa *lsa, char buf[64]; assert(lsa->header); - external = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( - lsa->header); + external = lsa_after_header(lsa->header); /* bits */ snprintf(buf, sizeof(buf), "%c%c%c", @@ -3027,8 +3022,7 @@ ospf6_originate_summary_lsa(struct ospf6 *ospf6, return; } - external = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( - aggr_lsa->header); + external = lsa_after_header(aggr_lsa->header); metric = (unsigned long)OSPF6_ASBR_METRIC(external); tag = ospf6_as_external_lsa_get_tag(aggr_lsa); mtype = CHECK_FLAG(external->bits_metric, @@ -3176,7 +3170,7 @@ ospf6_handle_external_aggr_modify(struct ospf6 *ospf6, return OSPF6_FAILURE; } - asel = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end(lsa->header); + asel = lsa_after_header(lsa->header); metric = (unsigned long)OSPF6_ASBR_METRIC(asel); tag = ospf6_as_external_lsa_get_tag(lsa); mtype = CHECK_FLAG(asel->bits_metric, @@ -3365,8 +3359,7 @@ static void ospf6_handle_aggregated_exnl_rt(struct ospf6 *ospf6, lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL), htonl(info->id), ospf6->router_id, ospf6->lsdb); if (lsa) { - ext_lsa = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( - lsa->header); + ext_lsa = lsa_after_header(lsa->header); if (rt->prefix.prefixlen != ext_lsa->prefix.prefix_length) return; diff --git a/ospf6d/ospf6_asbr.h b/ospf6d/ospf6_asbr.h index 21e6d898e8..ace3ba8488 100644 --- a/ospf6d/ospf6_asbr.h +++ b/ospf6d/ospf6_asbr.h @@ -79,17 +79,6 @@ struct ospf6_external_aggr_rt { struct hash *match_extnl_hash; }; -/* AS-External-LSA */ -#define OSPF6_AS_EXTERNAL_LSA_MIN_SIZE 4U /* w/o IPv6 prefix */ -struct ospf6_as_external_lsa { - uint32_t bits_metric; - - struct ospf6_prefix prefix; - /* followed by none or one forwarding address */ - /* followed by none or one external route tag */ - /* followed by none or one referenced LS-ID */ -}; - #define OSPF6_ASBR_BIT_T ntohl (0x01000000) #define OSPF6_ASBR_BIT_F ntohl (0x02000000) #define OSPF6_ASBR_BIT_E ntohl (0x04000000) diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c index b87aa2ffe1..04ff35083f 100644 --- a/ospf6d/ospf6_flood.c +++ b/ospf6d/ospf6_flood.c @@ -26,6 +26,7 @@ #include "ospf6_flood.h" #include "ospf6_nssa.h" +#include "ospf6_tlv.h" #include "ospf6_gr.h" unsigned char conf_debug_ospf6_flooding; diff --git a/ospf6d/ospf6_gr.c b/ospf6d/ospf6_gr.c index ab119a4ea4..64eb90d5f2 100644 --- a/ospf6d/ospf6_gr.c +++ b/ospf6d/ospf6_gr.c @@ -16,6 +16,7 @@ #include "printfrr.h" #include "lib_errors.h" +#include "ospf6_proto.h" #include "ospf6d/ospf6_lsa.h" #include "ospf6d/ospf6_lsdb.h" #include "ospf6d/ospf6_route.h" @@ -30,6 +31,7 @@ #include "ospf6d/ospf6_flood.h" #include "ospf6d/ospf6_intra.h" #include "ospf6d/ospf6_spf.h" +#include "ospf6d/ospf6_tlv.h" #include "ospf6d/ospf6_gr.h" #include "ospf6d/ospf6_gr_clippy.c" @@ -54,16 +56,17 @@ static int ospf6_gr_lsa_originate(struct ospf6_interface *oi, /* prepare buffer */ memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; - grace_lsa = (struct ospf6_grace_lsa *)ospf6_lsa_header_end(lsa_header); + grace_lsa = lsa_after_header(lsa_header); /* Put grace period. */ - grace_lsa->tlv_period.header.type = htons(GRACE_PERIOD_TYPE); - grace_lsa->tlv_period.header.length = htons(GRACE_PERIOD_LENGTH); + grace_lsa->tlv_period.header.type = htons(TLV_GRACE_PERIOD_TYPE); + grace_lsa->tlv_period.header.length = htons(TLV_GRACE_PERIOD_LENGTH); grace_lsa->tlv_period.interval = htonl(gr_info->grace_period); /* Put restart reason. */ - grace_lsa->tlv_reason.header.type = htons(RESTART_REASON_TYPE); - grace_lsa->tlv_reason.header.length = htons(RESTART_REASON_LENGTH); + grace_lsa->tlv_reason.header.type = htons(TLV_GRACE_RESTART_REASON_TYPE); + grace_lsa->tlv_reason.header.length = + htons(TLV_GRACE_RESTART_REASON_LENGTH); grace_lsa->tlv_reason.reason = reason; /* Fill LSA Header */ diff --git a/ospf6d/ospf6_gr.h b/ospf6d/ospf6_gr.h index 84ef3aeb8a..e10d20680b 100644 --- a/ospf6d/ospf6_gr.h +++ b/ospf6d/ospf6_gr.h @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* - * OSPF6 Graceful Retsart helper functions. + * OSPF6 Graceful Restart helper functions. + * Ref RFC 5187 * * Copyright (C) 2021-22 Vmware, Inc. * Rajesh Kumar Girada @@ -60,58 +61,16 @@ enum ospf6_gr_helper_rejected_reason { OSPF6_HELPER_RESTARTING, }; -#ifdef roundup -#define ROUNDUP(val, gran) roundup(val, gran) -#else /* roundup */ -#define ROUNDUP(val, gran) (((val)-1 | (gran)-1) + 1) -#endif /* roundup */ -/* - * Generic TLV (type, length, value) macros - */ -struct tlv_header { - uint16_t type; /* Type of Value */ - uint16_t length; /* Length of Value portion only, in bytes */ -}; - -#define TLV_HDR_SIZE (sizeof(struct tlv_header)) - -#define TLV_BODY_SIZE(tlvh) (ROUNDUP(ntohs((tlvh)->length), sizeof(uint32_t))) - -#define TLV_SIZE(tlvh) (uint32_t)(TLV_HDR_SIZE + TLV_BODY_SIZE(tlvh)) - -#define TLV_HDR_TOP(lsah) \ - (struct tlv_header *)((char *)(lsah) + OSPF6_LSA_HEADER_SIZE) - -#define TLV_HDR_NEXT(tlvh) \ - (struct tlv_header *)((char *)(tlvh) + TLV_SIZE(tlvh)) - -/* Ref RFC5187 appendix-A */ -/* Grace period TLV */ -#define GRACE_PERIOD_TYPE 1 -#define GRACE_PERIOD_LENGTH 4 -struct grace_tlv_graceperiod { - struct tlv_header header; - uint32_t interval; -}; -#define GRACE_PERIOD_TLV_SIZE sizeof(struct grace_tlv_graceperiod) - -/* Restart reason TLV */ -#define RESTART_REASON_TYPE 2 -#define RESTART_REASON_LENGTH 1 -struct grace_tlv_restart_reason { - struct tlv_header header; - uint8_t reason; - uint8_t reserved[3]; -}; -#define GRACE_RESTART_REASON_TLV_SIZE sizeof(struct grace_tlv_restart_reason) +#define GRACE_PERIOD_TLV_SIZE sizeof(struct tlv_grace_period) +#define GRACE_RESTART_REASON_TLV_SIZE sizeof(struct tlv_grace_restart_reason) #define OSPF6_GRACE_LSA_MIN_SIZE \ GRACE_PERIOD_TLV_SIZE + GRACE_RESTART_REASON_TLV_SIZE struct ospf6_grace_lsa { - struct grace_tlv_graceperiod tlv_period; - struct grace_tlv_restart_reason tlv_reason; + struct tlv_grace_period tlv_period; + struct tlv_grace_restart_reason tlv_reason; }; struct advRtr { diff --git a/ospf6d/ospf6_gr_helper.c b/ospf6d/ospf6_gr_helper.c index f0e5d3a15c..da8b829cf1 100644 --- a/ospf6d/ospf6_gr_helper.c +++ b/ospf6d/ospf6_gr_helper.c @@ -32,6 +32,7 @@ #include "ospf6_neighbor.h" #include "ospf6_intra.h" #include "ospf6d.h" +#include "ospf6_tlv.h" #include "ospf6_gr.h" #include "lib/json.h" #include "ospf6d/ospf6_gr_helper_clippy.c" @@ -129,8 +130,8 @@ static int ospf6_extract_grace_lsa_fields(struct ospf6_lsa *lsa, { struct ospf6_lsa_header *lsah = NULL; struct tlv_header *tlvh = NULL; - struct grace_tlv_graceperiod *gracePeriod; - struct grace_tlv_restart_reason *grReason; + struct tlv_grace_period *gracePeriod; + struct tlv_grace_restart_reason *grReason; uint16_t length = 0; int sum = 0; @@ -144,9 +145,8 @@ static int ospf6_extract_grace_lsa_fields(struct ospf6_lsa *lsa, length = ntohs(lsah->length) - OSPF6_LSA_HEADER_SIZE; - for (tlvh = TLV_HDR_TOP(lsah); sum < length && tlvh; + for (tlvh = lsdesc_start(lsah); sum < length && tlvh; tlvh = TLV_HDR_NEXT(tlvh)) { - /* Check TLV len against overall LSA */ if (sum + TLV_SIZE(tlvh) > length) { if (IS_DEBUG_OSPF6_GR) @@ -157,8 +157,8 @@ static int ospf6_extract_grace_lsa_fields(struct ospf6_lsa *lsa, } switch (ntohs(tlvh->type)) { - case GRACE_PERIOD_TYPE: - gracePeriod = (struct grace_tlv_graceperiod *)tlvh; + case TLV_GRACE_PERIOD_TYPE: + gracePeriod = (struct tlv_grace_period *)tlvh; *interval = ntohl(gracePeriod->interval); sum += TLV_SIZE(tlvh); @@ -167,8 +167,8 @@ static int ospf6_extract_grace_lsa_fields(struct ospf6_lsa *lsa, || *interval < OSPF6_MIN_GRACE_INTERVAL) return OSPF6_FAILURE; break; - case RESTART_REASON_TYPE: - grReason = (struct grace_tlv_restart_reason *)tlvh; + case TLV_GRACE_RESTART_REASON_TYPE: + grReason = (struct tlv_grace_restart_reason *)tlvh; *reason = grReason->reason; sum += TLV_SIZE(tlvh); @@ -1218,8 +1218,8 @@ static int ospf6_grace_lsa_show_info(struct vty *vty, struct ospf6_lsa *lsa, { struct ospf6_lsa_header *lsah = NULL; struct tlv_header *tlvh = NULL; - struct grace_tlv_graceperiod *gracePeriod; - struct grace_tlv_restart_reason *grReason; + struct tlv_grace_period *gracePeriod; + struct tlv_grace_restart_reason *grReason; uint16_t length = 0; int sum = 0; @@ -1240,9 +1240,8 @@ static int ospf6_grace_lsa_show_info(struct vty *vty, struct ospf6_lsa *lsa, zlog_debug(" TLV info:"); } - for (tlvh = TLV_HDR_TOP(lsah); sum < length && tlvh; + for (tlvh = lsdesc_start(lsah); sum < length && tlvh; tlvh = TLV_HDR_NEXT(tlvh)) { - /* Check TLV len */ if (sum + TLV_SIZE(tlvh) > length) { if (vty) @@ -1255,8 +1254,8 @@ static int ospf6_grace_lsa_show_info(struct vty *vty, struct ospf6_lsa *lsa, } switch (ntohs(tlvh->type)) { - case GRACE_PERIOD_TYPE: - gracePeriod = (struct grace_tlv_graceperiod *)tlvh; + case TLV_GRACE_PERIOD_TYPE: + gracePeriod = (struct tlv_grace_period *)tlvh; sum += TLV_SIZE(tlvh); if (vty) { @@ -1272,8 +1271,8 @@ static int ospf6_grace_lsa_show_info(struct vty *vty, struct ospf6_lsa *lsa, ntohl(gracePeriod->interval)); } break; - case RESTART_REASON_TYPE: - grReason = (struct grace_tlv_restart_reason *)tlvh; + case TLV_GRACE_RESTART_REASON_TYPE: + grReason = (struct tlv_grace_restart_reason *)tlvh; sum += TLV_SIZE(tlvh); if (vty) { if (use_json) diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index 7f813ce3cc..60f92385dd 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -14,6 +14,7 @@ #include "plist.h" #include "zclient.h" +#include "ospf6_proto.h" #include "ospf6_lsa.h" #include "ospf6_lsdb.h" #include "ospf6_top.h" @@ -30,9 +31,9 @@ #include "ospf6d.h" #include "ospf6_bfd.h" #include "ospf6_zebra.h" +#include "ospf6_tlv.h" #include "ospf6_gr.h" #include "lib/json.h" -#include "ospf6_proto.h" #include "lib/keychain.h" #include "ospf6_auth_trailer.h" #include "ospf6d/ospf6_interface_clippy.c" diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c index b06796ada0..324cd7abe8 100644 --- a/ospf6d/ospf6_intra.c +++ b/ospf6d/ospf6_intra.c @@ -32,6 +32,7 @@ #include "ospf6_flood.h" #include "ospf6d.h" #include "ospf6_spf.h" +#include "ospf6_tlv.h" #include "ospf6_gr.h" unsigned char conf_debug_ospf6_brouter = 0; @@ -43,41 +44,20 @@ uint32_t conf_debug_ospf6_brouter_specific_area_id; /* RFC2740 3.4.3.1 Router-LSA */ /******************************/ +/* OSPF6_LSTYPE_ROUTER */ static char *ospf6_router_lsa_get_nbr_id(struct ospf6_lsa *lsa, char *buf, int buflen, int pos) { - struct ospf6_router_lsa *router_lsa; - struct ospf6_router_lsdesc *lsdesc; - char *start, *end; char buf1[INET_ADDRSTRLEN], buf2[INET_ADDRSTRLEN]; + struct ospf6_router_lsdesc *lsdesc = nth_lsdesc(lsa->header, pos); - if (lsa) { - router_lsa = (struct ospf6_router_lsa - *)((char *)lsa->header - + sizeof(struct ospf6_lsa_header)); - start = (char *)router_lsa + sizeof(struct ospf6_router_lsa); - end = (char *)lsa->header + ntohs(lsa->header->length); - - lsdesc = (struct ospf6_router_lsdesc - *)(start - + pos * (sizeof(struct - ospf6_router_lsdesc))); - if ((char *)lsdesc + sizeof(struct ospf6_router_lsdesc) - <= end) { - if (buf && (buflen > INET_ADDRSTRLEN * 2)) { - inet_ntop(AF_INET, - &lsdesc->neighbor_interface_id, buf1, - sizeof(buf1)); - inet_ntop(AF_INET, &lsdesc->neighbor_router_id, - buf2, sizeof(buf2)); - snprintf(buf, buflen, "%s/%s", buf2, buf1); - - return buf; - } - } - } + if (!lsdesc || !buf || buflen < (2 + 2 * INET_ADDRSTRLEN)) + return NULL; - return NULL; + inet_ntop(AF_INET, &lsdesc->neighbor_interface_id, buf1, sizeof(buf1)); + inet_ntop(AF_INET, &lsdesc->neighbor_router_id, buf2, sizeof(buf2)); + snprintf(buf, buflen, "%s/%s", buf2, buf1); + return buf; } static int ospf6_router_lsa_show(struct vty *vty, struct ospf6_lsa *lsa, @@ -195,9 +175,7 @@ int ospf6_router_is_stub_router(struct ospf6_lsa *lsa) struct ospf6_router_lsa *rtr_lsa; if (lsa != NULL && OSPF6_LSA_IS_TYPE(ROUTER, lsa)) { - rtr_lsa = (struct ospf6_router_lsa - *)((caddr_t)lsa->header - + sizeof(struct ospf6_lsa_header)); + rtr_lsa = lsa_after_header(lsa->header); if (!OSPF6_OPT_ISSET(rtr_lsa->options, OSPF6_OPT_R)) { return OSPF6_IS_STUB_ROUTER; @@ -242,14 +220,12 @@ void ospf6_router_lsa_originate(struct event *thread) memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; - router_lsa = (struct ospf6_router_lsa *)ospf6_lsa_header_end(lsa_header); + router_lsa = lsa_after_header(lsa_header); ospf6_router_lsa_options_set(oa, router_lsa); /* describe links for each interfaces */ - lsdesc = (struct ospf6_router_lsdesc - *)((caddr_t)router_lsa - + sizeof(struct ospf6_router_lsa)); + lsdesc = lsdesc_start_lsa_type(lsa_header, OSPF6_LSTYPE_ROUTER); for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi)) { /* Interfaces in state Down or Loopback are not described */ @@ -272,9 +248,9 @@ void ospf6_router_lsa_originate(struct event *thread) && ((size_t)((char *)lsdesc - buffer) + sizeof(struct ospf6_router_lsdesc) > oa->router_lsa_size_limit)) { - if ((caddr_t)lsdesc - == (caddr_t)router_lsa - + sizeof(struct ospf6_router_lsa)) { + if (lsdesc == + lsdesc_start_lsa_type(lsa_header, + OSPF6_LSTYPE_ROUTER)) { zlog_warn( "Size limit setting for Router-LSA too short"); return; @@ -303,15 +279,13 @@ void ospf6_router_lsa_originate(struct event *thread) /* Reset Buffer to fill next Router LSA */ memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; - router_lsa = (struct ospf6_router_lsa *) - ospf6_lsa_header_end(lsa_header); + router_lsa = lsa_after_header(lsa_header); ospf6_router_lsa_options_set(oa, router_lsa); /* describe links for each interfaces */ - lsdesc = (struct ospf6_router_lsdesc - *)((caddr_t)router_lsa - + sizeof(struct ospf6_router_lsa)); + lsdesc = lsdesc_start_lsa_type(lsa_header, + OSPF6_LSTYPE_ROUTER); link_state_id++; } @@ -424,30 +398,13 @@ void ospf6_router_lsa_originate(struct event *thread) static char *ospf6_network_lsa_get_ar_id(struct ospf6_lsa *lsa, char *buf, int buflen, int pos) { - char *start, *end, *current; - struct ospf6_network_lsa *network_lsa; - struct ospf6_network_lsdesc *lsdesc; + struct ospf6_network_lsdesc *lsdesc = nth_lsdesc(lsa->header, pos); - if (lsa) { - network_lsa = (struct ospf6_network_lsa - *)((caddr_t)lsa->header - + sizeof(struct ospf6_lsa_header)); - - start = (char *)network_lsa + sizeof(struct ospf6_network_lsa); - end = (char *)lsa->header + ntohs(lsa->header->length); - current = start + pos * (sizeof(struct ospf6_network_lsdesc)); - - if ((current + sizeof(struct ospf6_network_lsdesc)) <= end) { - lsdesc = (struct ospf6_network_lsdesc *)current; - if (buf) { - inet_ntop(AF_INET, &lsdesc->router_id, buf, - buflen); - return buf; - } - } - } + if (!lsdesc || !buf || buflen < (1 + INET_ADDRSTRLEN)) + return NULL; - return NULL; + inet_ntop(AF_INET, &lsdesc->router_id, buf, buflen); + return buf; } static int ospf6_network_lsa_show(struct vty *vty, struct ospf6_lsa *lsa, @@ -459,9 +416,7 @@ static int ospf6_network_lsa_show(struct vty *vty, struct ospf6_lsa *lsa, char buf[128], options[32]; json_object *json_arr = NULL; - network_lsa = - (struct ospf6_network_lsa *)((caddr_t)lsa->header - + sizeof(struct ospf6_lsa_header)); + network_lsa = lsa_after_header(lsa->header); ospf6_options_printbuf(network_lsa->options, options, sizeof(options)); if (use_json) @@ -563,23 +518,19 @@ void ospf6_network_lsa_originate(struct event *thread) /* prepare buffer */ memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; - network_lsa = - (struct ospf6_network_lsa *)ospf6_lsa_header_end(lsa_header); + network_lsa = lsa_after_header(lsa_header); /* Collect the interface's Link-LSAs to describe network's optional capabilities */ type = htons(OSPF6_LSTYPE_LINK); for (ALL_LSDB_TYPED(oi->lsdb, type, lsa)) { - link_lsa = (struct ospf6_link_lsa *)ospf6_lsa_header_end( - lsa->header); + link_lsa = lsa_after_header(lsa->header); network_lsa->options[0] |= link_lsa->options[0]; network_lsa->options[1] |= link_lsa->options[1]; network_lsa->options[2] |= link_lsa->options[2]; } - lsdesc = (struct ospf6_network_lsdesc - *)((caddr_t)network_lsa - + sizeof(struct ospf6_network_lsa)); + lsdesc = lsdesc_start_lsa_type(lsa_header, OSPF6_LSTYPE_NETWORK); /* set Link Description to the router itself */ lsdesc->router_id = oi->area->ospf6->router_id; @@ -623,52 +574,24 @@ void ospf6_network_lsa_originate(struct event *thread) static char *ospf6_link_lsa_get_prefix_str(struct ospf6_lsa *lsa, char *buf, int buflen, int pos) { - char *start, *end, *current; - struct ospf6_link_lsa *link_lsa; - struct in6_addr in6; - struct ospf6_prefix *prefix; - int cnt = 0, prefixnum; + struct ospf6_link_lsa *link_lsa = lsa_after_header(lsa->header); + struct ospf6_prefix *prefix = nth_prefix(lsa->header, pos); + struct in6_addr in6 = { 0 }; - if (lsa) { - link_lsa = (struct ospf6_link_lsa - *)((caddr_t)lsa->header - + sizeof(struct ospf6_lsa_header)); - - if (pos == 0) { - inet_ntop(AF_INET6, &link_lsa->linklocal_addr, buf, - buflen); - return (buf); - } + if (!lsa || !prefix || !buf || buflen < (1 + INET6_ADDRSTRLEN)) + return NULL; - prefixnum = ntohl(link_lsa->prefix_num); - if (pos > prefixnum) - return NULL; + /* position zero is used for the lladdr in the body of the LSA */ + if (pos == 0) { + inet_ntop(AF_INET6, &link_lsa->linklocal_addr, buf, buflen); + return buf; + } - start = (char *)link_lsa + sizeof(struct ospf6_link_lsa); - end = (char *)lsa->header + ntohs(lsa->header->length); - current = start; - - while (current + sizeof(struct ospf6_prefix) <= end) { - prefix = (struct ospf6_prefix *)current; - if (prefix->prefix_length == 0 - || current + OSPF6_PREFIX_SIZE(prefix) > end) { - return NULL; - } + memcpy(&in6, OSPF6_PREFIX_BODY(prefix), + OSPF6_PREFIX_SPACE(prefix->prefix_length)); + inet_ntop(AF_INET6, &in6, buf, buflen); - if (cnt < (pos - 1)) { - current += OSPF6_PREFIX_SIZE(prefix); - cnt++; - } else { - memset(&in6, 0, sizeof(in6)); - memcpy(&in6, OSPF6_PREFIX_BODY(prefix), - OSPF6_PREFIX_SPACE( - prefix->prefix_length)); - inet_ntop(AF_INET6, &in6, buf, buflen); - return (buf); - } - } - } - return NULL; + return buf; } static int ospf6_link_lsa_show(struct vty *vty, struct ospf6_lsa *lsa, @@ -684,8 +607,7 @@ static int ospf6_link_lsa_show(struct vty *vty, struct ospf6_lsa *lsa, json_object *json_arr = NULL; char prefix_string[133]; - link_lsa = (struct ospf6_link_lsa *)((caddr_t)lsa->header - + sizeof(struct ospf6_lsa_header)); + link_lsa = lsa_after_header(lsa->header); ospf6_options_printbuf(link_lsa->options, options, sizeof(options)); inet_ntop(AF_INET6, &link_lsa->linklocal_addr, buf, sizeof(buf)); @@ -795,7 +717,7 @@ void ospf6_link_lsa_originate(struct event *thread) /* prepare buffer */ memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; - link_lsa = (struct ospf6_link_lsa *)ospf6_lsa_header_end(lsa_header); + link_lsa = lsa_after_header(lsa_header); /* Fill Link-LSA */ link_lsa->priority = oi->priority; @@ -804,8 +726,7 @@ void ospf6_link_lsa_originate(struct event *thread) sizeof(struct in6_addr)); link_lsa->prefix_num = htonl(oi->route_connected->count); - op = (struct ospf6_prefix *)((caddr_t)link_lsa - + sizeof(struct ospf6_link_lsa)); + op = lsdesc_start_lsa_type(lsa_header, OSPF6_LSTYPE_LINK); /* connected prefix to advertise */ for (route = ospf6_route_head(oi->route_connected); route; @@ -846,52 +767,22 @@ static char *ospf6_intra_prefix_lsa_get_prefix_str(struct ospf6_lsa *lsa, char *buf, int buflen, int pos) { - char *start, *end, *current; - struct ospf6_intra_prefix_lsa *intra_prefix_lsa; - struct in6_addr in6; - int prefixnum, cnt = 0; - struct ospf6_prefix *prefix; + struct ospf6_prefix *prefix = nth_prefix(lsa->header, pos); + struct in6_addr in6 = { 0 }; char tbuf[16]; - if (lsa) { - intra_prefix_lsa = - (struct ospf6_intra_prefix_lsa - *)((caddr_t)lsa->header - + sizeof(struct ospf6_lsa_header)); + /* ensure buflen >= INET6_ADDRSTRLEN + '/128\0' */ + if (!lsa || !prefix || !buf || buflen < (5 + INET6_ADDRSTRLEN)) + return NULL; - prefixnum = ntohs(intra_prefix_lsa->prefix_num); - if ((pos + 1) > prefixnum) - return NULL; + memcpy(&in6, OSPF6_PREFIX_BODY(prefix), + OSPF6_PREFIX_SPACE(prefix->prefix_length)); + inet_ntop(AF_INET6, &in6, buf, buflen); - start = (char *)intra_prefix_lsa - + sizeof(struct ospf6_intra_prefix_lsa); - end = ospf6_lsa_end(lsa->header); - current = start; + snprintf(tbuf, sizeof(tbuf), "/%d", prefix->prefix_length); + strlcat(buf, tbuf, buflen); - while (current + sizeof(struct ospf6_prefix) <= end) { - prefix = (struct ospf6_prefix *)current; - if (prefix->prefix_length == 0 - || current + OSPF6_PREFIX_SIZE(prefix) > end) { - return NULL; - } - - if (cnt < pos) { - current += OSPF6_PREFIX_SIZE(prefix); - cnt++; - } else { - memset(&in6, 0, sizeof(in6)); - memcpy(&in6, OSPF6_PREFIX_BODY(prefix), - OSPF6_PREFIX_SPACE( - prefix->prefix_length)); - inet_ntop(AF_INET6, &in6, buf, buflen); - snprintf(tbuf, sizeof(tbuf), "/%d", - prefix->prefix_length); - strlcat(buf, tbuf, buflen); - return (buf); - } - } - } - return NULL; + return buf; } static int ospf6_intra_prefix_lsa_show(struct vty *vty, struct ospf6_lsa *lsa, @@ -908,9 +799,7 @@ static int ospf6_intra_prefix_lsa_show(struct vty *vty, struct ospf6_lsa *lsa, json_object *json_arr = NULL; char prefix_string[133]; - intra_prefix_lsa = (struct ospf6_intra_prefix_lsa - *)((caddr_t)lsa->header - + sizeof(struct ospf6_lsa_header)); + intra_prefix_lsa = lsa_after_header(lsa->header); prefixnum = ntohs(intra_prefix_lsa->prefix_num); @@ -1037,8 +926,7 @@ void ospf6_intra_prefix_lsa_originate_stub(struct event *thread) /* prepare buffer */ memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; - intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)ospf6_lsa_header_end( - lsa_header); + intra_prefix_lsa = lsa_after_header(lsa_header); /* Fill Intra-Area-Prefix-LSA */ intra_prefix_lsa->ref_type = htons(OSPF6_LSTYPE_ROUTER); @@ -1122,12 +1010,10 @@ void ospf6_intra_prefix_lsa_originate_stub(struct event *thread) /* put prefixes to advertise */ prefix_num = 0; - op = (struct ospf6_prefix *)((caddr_t)intra_prefix_lsa - + sizeof(struct ospf6_intra_prefix_lsa)); + op = lsdesc_start_lsa_type(lsa_header, OSPF6_LSTYPE_INTRA_PREFIX); for (route = ospf6_route_head(route_advertise); route; route = ospf6_route_best_next(route)) { if (((caddr_t)op - (caddr_t)lsa_header) > MAX_LSA_PAYLOAD) { - intra_prefix_lsa->prefix_num = htons(prefix_num); /* Fill LSA Header */ @@ -1153,8 +1039,7 @@ void ospf6_intra_prefix_lsa_originate_stub(struct event *thread) /* Prepare next buffer */ memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; - intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) - ospf6_lsa_header_end(lsa_header); + intra_prefix_lsa = lsa_after_header(lsa_header); /* Fill Intra-Area-Prefix-LSA */ intra_prefix_lsa->ref_type = htons(OSPF6_LSTYPE_ROUTER); @@ -1163,10 +1048,8 @@ void ospf6_intra_prefix_lsa_originate_stub(struct event *thread) /* Put next set of prefixes to advertise */ prefix_num = 0; - op = (struct ospf6_prefix - *)((caddr_t)intra_prefix_lsa - + sizeof(struct - ospf6_intra_prefix_lsa)); + op = lsdesc_start_lsa_type(lsa_header, + OSPF6_LSTYPE_INTRA_PREFIX); } op->prefix_length = route->prefix.prefixlen; @@ -1261,8 +1144,7 @@ void ospf6_intra_prefix_lsa_originate_transit(struct event *thread) /* prepare buffer */ memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; - intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)ospf6_lsa_header_end( - lsa_header); + intra_prefix_lsa = lsa_after_header(lsa_header); /* Fill Intra-Area-Prefix-LSA */ intra_prefix_lsa->ref_type = htons(OSPF6_LSTYPE_NETWORK); @@ -1311,9 +1193,7 @@ void ospf6_intra_prefix_lsa_originate_transit(struct event *thread) } } - link_lsa = (struct ospf6_link_lsa - *)((caddr_t)lsa->header - + sizeof(struct ospf6_lsa_header)); + link_lsa = lsa_after_header(lsa->header); prefix_num = (unsigned short)ntohl(link_lsa->prefix_num); start = (char *)link_lsa + sizeof(struct ospf6_link_lsa); @@ -1356,8 +1236,7 @@ void ospf6_intra_prefix_lsa_originate_transit(struct event *thread) zlog_debug("Trailing garbage in %s", lsa->name); } - op = (struct ospf6_prefix *)((caddr_t)intra_prefix_lsa - + sizeof(struct ospf6_intra_prefix_lsa)); + op = lsdesc_start_lsa_type(lsa_header, OSPF6_LSTYPE_INTRA_PREFIX); prefix_num = 0; for (route = ospf6_route_head(route_advertise); route; @@ -1658,10 +1537,7 @@ void ospf6_intra_prefix_route_ecmp_path(struct ospf6_area *oa, } continue; } - intra_prefix_lsa = - (struct ospf6_intra_prefix_lsa *) - ospf6_lsa_header_end( - lsa->header); + intra_prefix_lsa = lsa_after_header(lsa->header); if (intra_prefix_lsa->ref_adv_router == oa->ospf6->router_id) { @@ -1742,8 +1618,7 @@ void ospf6_intra_prefix_lsa_add(struct ospf6_lsa *lsa) oa = OSPF6_AREA(lsa->lsdb->data); - intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)ospf6_lsa_header_end( - lsa->header); + intra_prefix_lsa = lsa_after_header(lsa->header); if (intra_prefix_lsa->ref_type == htons(OSPF6_LSTYPE_ROUTER) || intra_prefix_lsa->ref_type == htons(OSPF6_LSTYPE_NETWORK)) ospf6_linkstate_prefix(intra_prefix_lsa->ref_adv_router, @@ -1971,8 +1846,7 @@ void ospf6_intra_prefix_lsa_remove(struct ospf6_lsa *lsa) oa = OSPF6_AREA(lsa->lsdb->data); - intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)ospf6_lsa_header_end( - lsa->header); + intra_prefix_lsa = lsa_after_header(lsa->header); prefix_num = ntohs(intra_prefix_lsa->prefix_num); start = (caddr_t)intra_prefix_lsa diff --git a/ospf6d/ospf6_intra.h b/ospf6d/ospf6_intra.h index 7d154cb4c6..fafa6d1282 100644 --- a/ospf6d/ospf6_intra.h +++ b/ospf6d/ospf6_intra.h @@ -13,10 +13,13 @@ extern in_addr_t conf_debug_ospf6_brouter_specific_area_id; #define OSPF6_DEBUG_BROUTER_SUMMARY 0x01 #define OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER 0x02 #define OSPF6_DEBUG_BROUTER_SPECIFIC_AREA 0x04 + #define OSPF6_DEBUG_BROUTER_ON() \ (conf_debug_ospf6_brouter |= OSPF6_DEBUG_BROUTER_SUMMARY) + #define OSPF6_DEBUG_BROUTER_OFF() \ (conf_debug_ospf6_brouter &= ~OSPF6_DEBUG_BROUTER_SUMMARY) + #define IS_OSPF6_DEBUG_BROUTER \ (conf_debug_ospf6_brouter & OSPF6_DEBUG_BROUTER_SUMMARY) @@ -26,14 +29,17 @@ extern in_addr_t conf_debug_ospf6_brouter_specific_area_id; conf_debug_ospf6_brouter |= \ OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER; \ } while (0) + #define OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_OFF() \ do { \ conf_debug_ospf6_brouter_specific_router_id = 0; \ conf_debug_ospf6_brouter &= \ ~OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER; \ } while (0) + #define IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER \ (conf_debug_ospf6_brouter & OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER) + #define IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID(router_id) \ (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER \ && conf_debug_ospf6_brouter_specific_router_id == (router_id)) @@ -43,42 +49,21 @@ extern in_addr_t conf_debug_ospf6_brouter_specific_area_id; conf_debug_ospf6_brouter_specific_area_id = (area_id); \ conf_debug_ospf6_brouter |= OSPF6_DEBUG_BROUTER_SPECIFIC_AREA; \ } while (0) + #define OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_OFF() \ do { \ conf_debug_ospf6_brouter_specific_area_id = 0; \ conf_debug_ospf6_brouter &= \ ~OSPF6_DEBUG_BROUTER_SPECIFIC_AREA; \ } while (0) + #define IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA \ (conf_debug_ospf6_brouter & OSPF6_DEBUG_BROUTER_SPECIFIC_AREA) + #define IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA_ID(area_id) \ (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_AREA \ && conf_debug_ospf6_brouter_specific_area_id == (area_id)) -/* Router-LSA */ -#define OSPF6_ROUTER_LSA_MIN_SIZE 4U -struct ospf6_router_lsa { - uint8_t bits; - uint8_t options[3]; - /* followed by ospf6_router_lsdesc(s) */ -}; - -/* Link State Description in Router-LSA */ -#define OSPF6_ROUTER_LSDESC_FIX_SIZE 16U -struct ospf6_router_lsdesc { - uint8_t type; - uint8_t reserved; - uint16_t metric; /* output cost */ - uint32_t interface_id; - uint32_t neighbor_interface_id; - in_addr_t neighbor_router_id; -}; - -#define OSPF6_ROUTER_LSDESC_POINTTOPOINT 1 -#define OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK 2 -#define OSPF6_ROUTER_LSDESC_STUB_NETWORK 3 -#define OSPF6_ROUTER_LSDESC_VIRTUAL_LINK 4 - enum stub_router_mode { OSPF6_NOT_STUB_ROUTER, OSPF6_IS_STUB_ROUTER, @@ -92,49 +77,16 @@ enum stub_router_mode { : 0) #define ROUTER_LSDESC_GET_METRIC(x) \ (ntohs(((struct ospf6_router_lsdesc *)(x))->metric)) + #define ROUTER_LSDESC_GET_IFID(x) \ (ntohl(((struct ospf6_router_lsdesc *)(x))->interface_id)) + #define ROUTER_LSDESC_GET_NBR_IFID(x) \ (ntohl(((struct ospf6_router_lsdesc *)(x))->neighbor_interface_id)) + #define ROUTER_LSDESC_GET_NBR_ROUTERID(x) \ (((struct ospf6_router_lsdesc *)(x))->neighbor_router_id) -/* Network-LSA */ -#define OSPF6_NETWORK_LSA_MIN_SIZE 4U -struct ospf6_network_lsa { - uint8_t reserved; - uint8_t options[3]; - /* followed by ospf6_netowrk_lsd(s) */ -}; - -/* Link State Description in Router-LSA */ -#define OSPF6_NETWORK_LSDESC_FIX_SIZE 4U -struct ospf6_network_lsdesc { - in_addr_t router_id; -}; -#define NETWORK_LSDESC_GET_NBR_ROUTERID(x) \ - (((struct ospf6_network_lsdesc *)(x))->router_id) - -/* Link-LSA */ -#define OSPF6_LINK_LSA_MIN_SIZE 24U /* w/o 1st IPv6 prefix */ -struct ospf6_link_lsa { - uint8_t priority; - uint8_t options[3]; - struct in6_addr linklocal_addr; - uint32_t prefix_num; - /* followed by ospf6 prefix(es) */ -}; - -/* Intra-Area-Prefix-LSA */ -#define OSPF6_INTRA_PREFIX_LSA_MIN_SIZE 12U /* w/o 1st IPv6 prefix */ -struct ospf6_intra_prefix_lsa { - uint16_t prefix_num; - uint16_t ref_type; - uint32_t ref_id; - in_addr_t ref_adv_router; - /* followed by ospf6 prefix(es) */ -}; - #define OSPF6_ROUTER_LSA_SCHEDULE(oa) \ do { \ @@ -142,18 +94,21 @@ struct ospf6_intra_prefix_lsa { event_add_event(master, ospf6_router_lsa_originate, \ oa, 0, &(oa)->thread_router_lsa); \ } while (0) + #define OSPF6_NETWORK_LSA_SCHEDULE(oi) \ do { \ if (!CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \ event_add_event(master, ospf6_network_lsa_originate, \ oi, 0, &(oi)->thread_network_lsa); \ } while (0) + #define OSPF6_LINK_LSA_SCHEDULE(oi) \ do { \ if (!CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \ event_add_event(master, ospf6_link_lsa_originate, oi, \ 0, &(oi)->thread_link_lsa); \ } while (0) + #define OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oa) \ do { \ if (CHECK_FLAG((oa)->flag, OSPF6_AREA_ENABLE)) \ @@ -161,6 +116,7 @@ struct ospf6_intra_prefix_lsa { master, ospf6_intra_prefix_lsa_originate_stub, \ oa, 0, &(oa)->thread_intra_prefix_lsa); \ } while (0) + #define OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi) \ do { \ if (!CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \ diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index 017751825f..622e5f9e0f 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -37,8 +37,85 @@ DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_LSA, "OSPF6 LSA"); DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_LSA_HEADER, "OSPF6 LSA header"); DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_LSA_SUMMARY, "OSPF6 LSA summary"); +const uint8_t ospf6_lsa_min_size[OSPF6_LSTYPE_SIZE] = { + [OSPF6_LSTYPE_UNKNOWN] = 0, + [0x00ff & OSPF6_LSTYPE_ROUTER] = OSPF6_ROUTER_LSA_MIN_SIZE, + [0x00ff & OSPF6_LSTYPE_NETWORK] = OSPF6_NETWORK_LSA_MIN_SIZE, + [0x00ff & OSPF6_LSTYPE_INTER_PREFIX] = OSPF6_INTER_PREFIX_LSA_MIN_SIZE, + [0x00ff & OSPF6_LSTYPE_INTER_ROUTER] = OSPF6_INTER_ROUTER_LSA_FIX_SIZE, + [0x00ff & OSPF6_LSTYPE_AS_EXTERNAL] = OSPF6_AS_EXTERNAL_LSA_MIN_SIZE, + [0x00ff & OSPF6_LSTYPE_GROUP_MEMBERSHIP] = 0, /* Unused */ + [0x00ff & OSPF6_LSTYPE_TYPE_7] = OSPF6_AS_EXTERNAL_LSA_MIN_SIZE, + [0x00ff & OSPF6_LSTYPE_LINK] = OSPF6_LINK_LSA_MIN_SIZE, + [0x00ff & OSPF6_LSTYPE_INTRA_PREFIX] = OSPF6_INTRA_PREFIX_LSA_MIN_SIZE, + [0x00ff & OSPF6_LSTYPE_GRACE_LSA] = 0 +}; + +void *lsdesc_start_lsa_type(struct ospf6_lsa_header *header, int lsa_type) +{ + uint8_t t = (0x00ff & lsa_type); + + if (t == OSPF6_LSTYPE_UNKNOWN || t >= OSPF6_LSTYPE_SIZE) { + zlog_debug("Cannot get descriptor offset for unknown lsa type 0x%x", + t); + return ospf6_lsa_end(header); + } + return (char *)lsa_after_header(header) + ospf6_lsa_min_size[t]; +} + +void *lsdesc_start(struct ospf6_lsa_header *header) +{ + return lsdesc_start_lsa_type(header, ntohs(header->type)); +} + static struct ospf6_lsa_handler *lsa_handlers[OSPF6_LSTYPE_SIZE]; +void *nth_lsdesc(struct ospf6_lsa_header *header, int pos) +{ + char *lsdesc = lsdesc_start(header); + char *lsa_end = ospf6_lsa_end(header); + char *nth; + int lsdesc_size; + + if (ntohs(header->type) == OSPF6_LSTYPE_ROUTER) + lsdesc_size = OSPF6_ROUTER_LSDESC_FIX_SIZE; + else if (ntohs(header->type) == OSPF6_LSTYPE_NETWORK) + lsdesc_size = OSPF6_NETWORK_LSDESC_FIX_SIZE; + else + return NULL; + + nth = lsdesc + (pos * lsdesc_size); + + if (nth + lsdesc_size <= lsa_end) + return nth; + + return NULL; +} + +void *nth_prefix(struct ospf6_lsa_header *header, int pos) +{ + struct ospf6_prefix *prefix = lsdesc_start(header); + char *end = ospf6_lsa_end(header); + int i = 0; + + if (ntohs(header->type) != OSPF6_LSTYPE_LINK && + ntohs(header->type) != OSPF6_LSTYPE_INTRA_PREFIX) + return NULL; + + if (pos == 0) + return prefix; + + while ((char *)prefix < end && + (char *)prefix + OSPF6_PREFIX_SIZE(prefix) <= end) { + if (i == pos) + return prefix; + i++; + prefix = OSPF6_PREFIX_NEXT(prefix); + } + + return NULL; +} + struct ospf6 *ospf6_get_by_lsdb(struct ospf6_lsa *lsa) { struct ospf6 *ospf6 = NULL; @@ -65,7 +142,7 @@ static int ospf6_unknown_lsa_show(struct vty *vty, struct ospf6_lsa *lsa, { char *start, *end, *current; - start = ospf6_lsa_header_end(lsa->header); + start = lsa_after_header(lsa->header); end = ospf6_lsa_end(lsa->header); if (use_json) { @@ -234,8 +311,8 @@ int ospf6_lsa_is_changed(struct ospf6_lsa *lsa1, struct ospf6_lsa *lsa2) if (length <= 0) return 0; - return memcmp(ospf6_lsa_header_end(lsa1->header), - ospf6_lsa_header_end(lsa2->header), length); + return memcmp(lsa_after_header(lsa1->header), + lsa_after_header(lsa2->header), length); } /* ospf6 age functions */ diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h index 4fc2f0dd18..b2c83a1d37 100644 --- a/ospf6d/ospf6_lsa.h +++ b/ospf6d/ospf6_lsa.h @@ -87,11 +87,17 @@ struct ospf6_lsa_header { uint16_t length; /* LSA length */ }; + static inline char *ospf6_lsa_header_end(struct ospf6_lsa_header *header) { return (char *)header + sizeof(struct ospf6_lsa_header); } +static inline void *lsa_after_header(struct ospf6_lsa_header *header) +{ + return (char *)header + sizeof(struct ospf6_lsa_header); +} + static inline char *ospf6_lsa_end(struct ospf6_lsa_header *header) { return (char *)header + ntohs(header->length); @@ -116,6 +122,94 @@ static inline uint16_t ospf6_lsa_size(struct ospf6_lsa_header *header) #define OSPF6_LSA_IS_CHANGED(L1, L2) ospf6_lsa_is_changed (L1, L2) #define OSPF6_LSA_IS_SEQWRAP(L) ((L)->header->seqnum == htonl(OSPF_MAX_SEQUENCE_NUMBER + 1)) +/* Router-LSA */ +#define OSPF6_ROUTER_LSA_MIN_SIZE 4U +struct ospf6_router_lsa { + uint8_t bits; + uint8_t options[3]; + /* followed by ospf6_router_lsdesc(s) */ +}; + +/* Link State Description in Router-LSA */ +#define OSPF6_ROUTER_LSDESC_FIX_SIZE 16U +struct ospf6_router_lsdesc { + uint8_t type; + uint8_t reserved; + uint16_t metric; /* output cost */ + uint32_t interface_id; + uint32_t neighbor_interface_id; + in_addr_t neighbor_router_id; +}; + +#define OSPF6_ROUTER_LSDESC_POINTTOPOINT 1 +#define OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK 2 +#define OSPF6_ROUTER_LSDESC_STUB_NETWORK 3 +#define OSPF6_ROUTER_LSDESC_VIRTUAL_LINK 4 + +/* Network-LSA */ +#define OSPF6_NETWORK_LSA_MIN_SIZE 4U +struct ospf6_network_lsa { + uint8_t reserved; + uint8_t options[3]; + /* followed by ospf6_network_lsdesc(s) */ +}; + +/* Link State Description in Network-LSA */ +#define OSPF6_NETWORK_LSDESC_FIX_SIZE 4U +struct ospf6_network_lsdesc { + in_addr_t router_id; +}; +#define NETWORK_LSDESC_GET_NBR_ROUTERID(x) \ + (((struct ospf6_network_lsdesc *)(x))->router_id) + +/* Inter-Area-Prefix-LSA */ +#define OSPF6_INTER_PREFIX_LSA_MIN_SIZE 4U /* w/o IPv6 prefix */ +struct ospf6_inter_prefix_lsa { + uint32_t metric; + struct ospf6_prefix prefix; +}; + +/* Inter-Area-Router-LSA */ +#define OSPF6_INTER_ROUTER_LSA_FIX_SIZE 12U +struct ospf6_inter_router_lsa { + uint8_t mbz; + uint8_t options[3]; + uint32_t metric; + uint32_t router_id; +}; + +/* AS-External-LSA */ +#define OSPF6_AS_EXTERNAL_LSA_MIN_SIZE 4U /* w/o IPv6 prefix */ +struct ospf6_as_external_lsa { + uint32_t bits_metric; + + struct ospf6_prefix prefix; + /* followed by none or one forwarding address */ + /* followed by none or one external route tag */ + /* followed by none or one referenced LS-ID */ +}; + +/* FIXME: move nssa lsa here. */ + +/* Link-LSA */ +#define OSPF6_LINK_LSA_MIN_SIZE 24U /* w/o 1st IPv6 prefix */ +struct ospf6_link_lsa { + uint8_t priority; + uint8_t options[3]; + struct in6_addr linklocal_addr; + uint32_t prefix_num; + /* followed by ospf6 prefix(es) */ +}; + +/* Intra-Area-Prefix-LSA */ +#define OSPF6_INTRA_PREFIX_LSA_MIN_SIZE 12U /* w/o 1st IPv6 prefix */ +struct ospf6_intra_prefix_lsa { + uint16_t prefix_num; + uint16_t ref_type; + uint32_t ref_id; + in_addr_t ref_adv_router; + /* followed by ospf6 prefix(es) */ +}; struct ospf6_lsa { char name[64]; /* dump string */ @@ -146,6 +240,7 @@ struct ospf6_lsa { bool tobe_acknowledged; }; + #define OSPF6_LSA_HEADERONLY 0x01 #define OSPF6_LSA_FLOODBACK 0x02 #define OSPF6_LSA_DUPLICATE 0x04 @@ -274,4 +369,11 @@ extern void ospf6_flush_self_originated_lsas_now(struct ospf6 *ospf6); extern struct ospf6 *ospf6_get_by_lsdb(struct ospf6_lsa *lsa); struct ospf6_lsa *ospf6_find_external_lsa(struct ospf6 *ospf6, struct prefix *p); + +void *lsdesc_start_lsa_type(struct ospf6_lsa_header *header, int lsa_type); +void *lsdesc_start(struct ospf6_lsa_header *header); + +void *nth_lsdesc(struct ospf6_lsa_header *header, int pos); +void *nth_prefix(struct ospf6_lsa_header *header, int pos); + #endif /* OSPF6_LSA_H */ diff --git a/ospf6d/ospf6_lsdb.c b/ospf6d/ospf6_lsdb.c index 9aca5550a6..e5de30484a 100644 --- a/ospf6d/ospf6_lsdb.c +++ b/ospf6d/ospf6_lsdb.c @@ -229,8 +229,7 @@ struct ospf6_lsa *ospf6_find_inter_prefix_lsa(struct ospf6 *ospf6, struct ospf6_inter_prefix_lsa *prefix_lsa; struct prefix prefix; - prefix_lsa = (struct ospf6_inter_prefix_lsa *) - ospf6_lsa_header_end(lsa->header); + prefix_lsa = lsa_after_header(lsa->header); prefix.family = AF_INET6; prefix.prefixlen = prefix_lsa->prefix.prefix_length; ospf6_prefix_in6_addr(&prefix.u.prefix6, prefix_lsa, diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index a6ee8d8b01..33d15e7243 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -33,6 +33,7 @@ #include "ospf6_flood.h" #include "ospf6d.h" +#include "ospf6_tlv.h" #include "ospf6_gr.h" #include <netinet/ip6.h> #include "lib/libospf.h" @@ -1303,9 +1304,7 @@ static unsigned ospf6_lsa_examin(struct ospf6_lsa_header *lsah, 4 bytes of referenced link state ID. */ if (headeronly) break; - as_external_lsa = - (struct ospf6_as_external_lsa - *)((caddr_t)lsah + OSPF6_LSA_HEADER_SIZE); + as_external_lsa = lsa_after_header(lsah); exp_length = OSPF6_LSA_HEADER_SIZE + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE; /* To find out if the last optional field (Referenced Link State @@ -1350,8 +1349,7 @@ static unsigned ospf6_lsa_examin(struct ospf6_lsa_header *lsah, by N>=0 IPv6 prefix blocks (with N declared beforehand). */ if (headeronly) break; - link_lsa = (struct ospf6_link_lsa *)((caddr_t)lsah - + OSPF6_LSA_HEADER_SIZE); + link_lsa = lsa_after_header(lsah); return ospf6_prefixes_examin( (struct ospf6_prefix *)((caddr_t)link_lsa + OSPF6_LINK_LSA_MIN_SIZE), @@ -1366,9 +1364,7 @@ static unsigned ospf6_lsa_examin(struct ospf6_lsa_header *lsah, */ if (headeronly) break; - intra_prefix_lsa = - (struct ospf6_intra_prefix_lsa - *)((caddr_t)lsah + OSPF6_LSA_HEADER_SIZE); + intra_prefix_lsa = lsa_after_header(lsah); return ospf6_prefixes_examin( (struct ospf6_prefix *)((caddr_t)intra_prefix_lsa diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c index 0e44f2a142..acf15da4c3 100644 --- a/ospf6d/ospf6_neighbor.c +++ b/ospf6d/ospf6_neighbor.c @@ -30,6 +30,7 @@ #include "ospf6_lsa.h" #include "ospf6_spf.h" #include "ospf6_zebra.h" +#include "ospf6_tlv.h" #include "ospf6_gr.h" #include "lib/json.h" diff --git a/ospf6d/ospf6_nssa.c b/ospf6d/ospf6_nssa.c index ea2be20cf3..8a5de468c9 100644 --- a/ospf6d/ospf6_nssa.c +++ b/ospf6d/ospf6_nssa.c @@ -52,8 +52,7 @@ static int ospf6_abr_nssa_am_elected(struct ospf6_area *oa) /* Verify all the router LSA to compare the router ID */ for (ALL_LSDB_TYPED(oa->lsdb, type, lsa)) { - router_lsa = (struct ospf6_router_lsa *)ospf6_lsa_header_end( - lsa->header); + router_lsa = lsa_after_header(lsa->header); /* ignore non-ABR routers */ if (!CHECK_FLAG(router_lsa->bits, OSPF6_ROUTER_BIT_B)) @@ -414,8 +413,7 @@ static struct ospf6_lsa *ospf6_lsa_translated_nssa_new(struct ospf6_area *area, } /* find the translated Type-5 for this Type-7 */ - nssa = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( - type7->header); + nssa = lsa_after_header(type7->header); prefix.family = AF_INET6; prefix.prefixlen = nssa->prefix.prefix_length; ospf6_prefix_in6_addr(&prefix.u.prefix6, nssa, &nssa->prefix); @@ -435,10 +433,8 @@ static struct ospf6_lsa *ospf6_lsa_translated_nssa_new(struct ospf6_area *area, /* prepare buffer */ memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; - extnew = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( - lsa_header); - ext = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( - type7->header); + extnew = lsa_after_header(lsa_header); + ext = lsa_after_header(type7->header); old_ptr = (caddr_t)((caddr_t)ext + sizeof(struct ospf6_as_external_lsa)); new_ptr = (caddr_t)((caddr_t)extnew @@ -546,8 +542,7 @@ struct ospf6_lsa *ospf6_translated_nssa_refresh(struct ospf6_area *area, "%s: try to find translated Type-5 LSA for %s", __func__, type7->name); - ext_lsa = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( - type7->header); + ext_lsa = lsa_after_header(type7->header); prefix.family = AF_INET6; prefix.prefixlen = ext_lsa->prefix.prefix_length; ospf6_prefix_in6_addr(&prefix.u.prefix6, ext_lsa, @@ -614,8 +609,7 @@ static void ospf6_abr_translate_nssa(struct ospf6_area *area, struct ospf6 *ospf6; ospf6 = area->ospf6; - nssa_lsa = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( - lsa->header); + nssa_lsa = lsa_after_header(lsa->header); if (!CHECK_FLAG(nssa_lsa->prefix.prefix_options, OSPF6_PREFIX_OPTION_P)) { @@ -1240,8 +1234,7 @@ void ospf6_nssa_lsa_originate(struct ospf6_route *route, /* prepare buffer */ memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; - as_external_lsa = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( - lsa_header); + as_external_lsa = lsa_after_header(lsa_header); p = (caddr_t)((caddr_t)as_external_lsa + sizeof(struct ospf6_as_external_lsa)); diff --git a/ospf6d/ospf6_proto.h b/ospf6d/ospf6_proto.h index 4307ee3c6e..645a408781 100644 --- a/ospf6d/ospf6_proto.h +++ b/ospf6d/ospf6_proto.h @@ -16,11 +16,12 @@ #define ALLSPFROUTERS6 "ff02::5" #define ALLDROUTERS6 "ff02::6" -#define OSPF6_ROUTER_BIT_W (1 << 3) +/* RFC 5340 A.4.3 Router-LSAs Options field */ +#define OSPF6_ROUTER_BIT_NT (1 << 4) +#define OSPF6_ROUTER_BIT_W (1 << 3) /* DEPRECATED */ #define OSPF6_ROUTER_BIT_V (1 << 2) #define OSPF6_ROUTER_BIT_E (1 << 1) #define OSPF6_ROUTER_BIT_B (1 << 0) -#define OSPF6_ROUTER_BIT_NT (1 << 4) /* OSPF options */ diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index 7879dae8d7..5f2c5a6c47 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -16,11 +16,11 @@ #include "frrevent.h" #include "lib_errors.h" +#include "ospf6_proto.h" #include "ospf6_lsa.h" #include "ospf6_lsdb.h" #include "ospf6_route.h" #include "ospf6_area.h" -#include "ospf6_proto.h" #include "ospf6_abr.h" #include "ospf6_asbr.h" #include "ospf6_spf.h" @@ -290,8 +290,7 @@ static void ospf6_nexthop_calc(struct ospf6_vertex *w, struct ospf6_vertex *v, != lsa->header->id) continue; - link_lsa = (struct ospf6_link_lsa *)ospf6_lsa_header_end( - lsa->header); + link_lsa = lsa_after_header(lsa->header); if (IS_OSPF6_DEBUG_SPF(PROCESS)) { inet_ntop(AF_INET6, &link_lsa->linklocal_addr, buf, sizeof(buf)); @@ -1136,8 +1135,7 @@ int ospf6_ase_calculate_route(struct ospf6 *ospf6, struct ospf6_lsa *lsa, return 0; } - external = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( - lsa->header); + external = lsa_after_header(lsa->header); prefix.family = AF_INET6; prefix.prefixlen = external->prefix.prefix_length; ospf6_prefix_in6_addr(&prefix.u.prefix6, external, &external->prefix); diff --git a/ospf6d/ospf6_tlv.h b/ospf6d/ospf6_tlv.h new file mode 100644 index 0000000000..a687a05939 --- /dev/null +++ b/ospf6d/ospf6_tlv.h @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * OSPFv3 Type Length Value. + * + */ + +#ifndef OSPF6_TLV_H +#define OSPF6_TLV_H + +/* + * Generic TLV (type, length, value) macros + */ +struct tlv_header { + uint16_t type; /* Type of Value */ + uint16_t length; /* Length of Value portion only, in bytes */ +}; + +#ifdef roundup +#define ROUNDUP(val, gran) roundup(val, gran) +#else /* roundup */ +#define ROUNDUP(val, gran) (((val)-1 | (gran)-1) + 1) +#endif /* roundup */ + +#define TLV_HDR_SIZE (sizeof(struct tlv_header)) + +#define TLV_BODY_SIZE(tlvh) (ROUNDUP(ntohs((tlvh)->length), sizeof(uint32_t))) + +#define TLV_SIZE(tlvh) ((uint32_t)(TLV_HDR_SIZE + TLV_BODY_SIZE(tlvh))) + +#define TLV_HDR_NEXT(tlvh) \ + ((struct tlv_header *)((char *)(tlvh) + TLV_SIZE(tlvh))) + +/* + * RFC 5187 - OSPFv3 Graceful Restart - Grace-LSA + * Graceful restart predates Extended-LSA TLVs and IANA TLV register. + */ +/* Grace period TLV. */ +#define TLV_GRACE_PERIOD_TYPE 1 +#define TLV_GRACE_PERIOD_LENGTH 4 +struct tlv_grace_period { + struct tlv_header header; + uint32_t interval; +}; + +/* Restart reason TLV. */ +#define TLV_GRACE_RESTART_REASON_TYPE 2 +#define TLV_GRACE_RESTART_REASON_LENGTH 1 +struct tlv_grace_restart_reason { + struct tlv_header header; + uint8_t reason; + uint8_t reserved[3]; +}; + + +#endif /* OSPF6_TLV_H */ diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index a3fb205374..ad487f3565 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -37,6 +37,7 @@ #include "ospf6_intra.h" #include "ospf6_spf.h" #include "ospf6d.h" +#include "ospf6_tlv.h" #include "ospf6_gr.h" #include "lib/json.h" #include "ospf6_nssa.h" diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index 911f3567d4..466301309f 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -27,6 +27,7 @@ #include "ospf6_zebra.h" #include "ospf6d.h" #include "ospf6_area.h" +#include "ospf6_tlv.h" #include "ospf6_gr.h" #include "lib/json.h" diff --git a/ospf6d/ospf6d.c b/ospf6d/ospf6d.c index d90a950d79..e4e0354fc9 100644 --- a/ospf6d/ospf6d.c +++ b/ospf6d/ospf6d.c @@ -30,6 +30,7 @@ #include "ospf6_flood.h" #include "ospf6d.h" #include "ospf6_bfd.h" +#include "ospf6_tlv.h" #include "ospf6_gr.h" #include "lib/json.h" #include "ospf6_nssa.h" diff --git a/ospf6d/subdir.am b/ospf6d/subdir.am index 5f89af9508..a7bd94bd77 100644 --- a/ospf6d/subdir.am +++ b/ospf6d/subdir.am @@ -58,6 +58,7 @@ noinst_HEADERS += \ ospf6d/ospf6_route.h \ ospf6d/ospf6_routemap_nb.h \ ospf6d/ospf6_spf.h \ + ospf6d/ospf6_tlv.h \ ospf6d/ospf6_top.h \ ospf6d/ospf6_zebra.h \ ospf6d/ospf6d.h \ diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c index 198309c1ef..97dc578679 100644 --- a/ospfd/ospf_sr.c +++ b/ospfd/ospf_sr.c @@ -1459,7 +1459,8 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa) /* Update Algorithm, SRLB and MSD if present */ if (algo != NULL) { int i; - for (i = 0; i < ntohs(algo->header.length); i++) + for (i = 0; + i < ntohs(algo->header.length) && i < ALGORITHM_COUNT; i++) srn->algo[i] = algo->value[0]; for (; i < ALGORITHM_COUNT; i++) srn->algo[i] = SR_ALGORITHM_UNSET; diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index d7d7fb76ea..b7261da261 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -2291,6 +2291,10 @@ static int ospf_timers_spf_set(struct vty *vty, unsigned int delay, { VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); + if (ospf->spf_delay != delay || ospf->spf_holdtime != hold || + ospf->spf_max_holdtime != max) + ospf->spf_hold_multiplier = 1; + ospf->spf_delay = delay; ospf->spf_holdtime = hold; ospf->spf_max_holdtime = max; diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 2c518f2c9e..c7cba1e20f 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -119,8 +119,9 @@ static int ospf_interface_address_delete(ZAPI_CALLBACK_ARGS) return 0; if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) - zlog_debug("Zebra: interface %s address delete %pFX", - c->ifp->name, c->address); + zlog_debug("Zebra: interface %s address delete %pFX vrf %s id %u", + c->ifp->name, c->address, + ospf_vrf_id_to_name(vrf_id), vrf_id); ifp = c->ifp; p = *c->address; @@ -261,9 +262,8 @@ void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p, if (ospf->gr_info.restart_in_progress) { if (IS_DEBUG_OSPF_GR) - zlog_debug( - "Zebra: Graceful Restart in progress -- not installing %pFX", - p); + zlog_debug("Zebra: Graceful Restart in progress -- not installing %pFX(%s)", + p, ospf_vrf_id_to_name(ospf->vrf_id)); return; } @@ -311,10 +311,10 @@ void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p, ifp = if_lookup_by_index(path->ifindex, ospf->vrf_id); - zlog_debug( - "Zebra: Route add %pFX nexthop %pI4, ifindex=%d %s", - p, &path->nexthop, path->ifindex, - ifp ? ifp->name : " "); + zlog_debug("Zebra: Route add %pFX(%s) nexthop %pI4, ifindex=%d %s", + p, ospf_vrf_id_to_name(ospf->vrf_id), + &path->nexthop, path->ifindex, + ifp ? ifp->name : " "); } } @@ -331,9 +331,8 @@ void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *p, if (ospf->gr_info.restart_in_progress) { if (IS_DEBUG_OSPF_GR) - zlog_debug( - "Zebra: Graceful Restart in progress -- not uninstalling %pFX", - p); + zlog_debug("Zebra: Graceful Restart in progress -- not uninstalling %pFX(%s)", + p, ospf_vrf_id_to_name(ospf->vrf_id)); return; } @@ -345,7 +344,8 @@ void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *p, memcpy(&api.prefix, p, sizeof(*p)); if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug("Zebra: Route delete %pFX", p); + zlog_debug("Zebra: Route delete %pFX(%s)", p, + ospf_vrf_id_to_name(ospf->vrf_id)); zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); } @@ -356,9 +356,8 @@ void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *p) if (ospf->gr_info.restart_in_progress) { if (IS_DEBUG_OSPF_GR) - zlog_debug( - "Zebra: Graceful Restart in progress -- not installing %pFX", - p); + zlog_debug("Zebra: Graceful Restart in progress -- not installing %pFX(%s)", + p, ospf_vrf_id_to_name(ospf->vrf_id)); return; } @@ -373,7 +372,8 @@ void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *p) zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug("Zebra: Route add discard %pFX", p); + zlog_debug("Zebra: Route add discard %pFX(%s)", p, + ospf_vrf_id_to_name(ospf->vrf_id)); } void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p) @@ -382,9 +382,8 @@ void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p) if (ospf->gr_info.restart_in_progress) { if (IS_DEBUG_OSPF_GR) - zlog_debug( - "Zebra: Graceful Restart in progress -- not uninstalling %pFX", - p); + zlog_debug("Zebra: Graceful Restart in progress -- not uninstalling %pFX(%s)", + p, ospf_vrf_id_to_name(ospf->vrf_id)); return; } @@ -399,7 +398,8 @@ void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p) zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug("Zebra: Route delete discard %pFX", p); + zlog_debug("Zebra: Route delete discard %pFX(%s)", p, + ospf_vrf_id_to_name(ospf->vrf_id)); } struct ospf_external *ospf_external_lookup(struct ospf *ospf, uint8_t type, @@ -475,8 +475,9 @@ bool ospf_external_default_routemap_apply_walk(struct ospf *ospf, if (ret && ei) { if (IS_DEBUG_OSPF_DEFAULT_INFO) - zlog_debug("Default originate routemap permit ei: %pI4", - &ei->p.prefix); + zlog_debug("Default originate routemap permit ei: %pI4(%s)", + &ei->p.prefix, + ospf_vrf_id_to_name(ospf->vrf_id)); return true; } @@ -507,7 +508,8 @@ static void ospf_external_lsa_default_routemap_timer(struct event *thread) if (!default_ei) { /* Nothing to be done here. */ if (IS_DEBUG_OSPF_DEFAULT_INFO) - zlog_debug("Default originate info not present"); + zlog_debug("Default originate info not present(%s)", + ospf_vrf_id_to_name(ospf->vrf_id)); return; } @@ -821,11 +823,11 @@ int ospf_redistribute_update(struct ospf *ospf, struct ospf_redist *red, ospf_external_lsa_refresh_type(ospf, type, instance, force); if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug( - "Redistribute[%s][%d]: Refresh Type[%d], Metric[%d]", - ospf_redist_string(type), instance, - metric_type(ospf, type, instance), - metric_value(ospf, type, instance)); + zlog_debug("Redistribute[%s][%d][%s]: Refresh Type[%d], Metric[%d]", + ospf_redist_string(type), instance, + ospf_vrf_id_to_name(ospf->vrf_id), + metric_type(ospf, type, instance), + metric_value(ospf, type, instance)); return CMD_SUCCESS; } @@ -842,11 +844,11 @@ int ospf_redistribute_set(struct ospf *ospf, struct ospf_redist *red, int type, instance, ospf->vrf_id); if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug( - "Redistribute[%s][%d] vrf id %u: Start Type[%d], Metric[%d]", - ospf_redist_string(type), instance, ospf->vrf_id, - metric_type(ospf, type, instance), - metric_value(ospf, type, instance)); + zlog_debug("Redistribute[%s][%d][%s]: Start Type[%d], Metric[%d]", + ospf_redist_string(type), instance, + ospf_vrf_id_to_name(ospf->vrf_id), + metric_type(ospf, type, instance), + metric_value(ospf, type, instance)); ospf_asbr_status_update(ospf, ++ospf->redistribute); @@ -863,8 +865,9 @@ int ospf_redistribute_unset(struct ospf *ospf, int type, instance, ospf->vrf_id); if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug("Redistribute[%s][%d] vrf id %u: Stop", - ospf_redist_string(type), instance, ospf->vrf_id); + zlog_debug("Redistribute[%s][%d][%s]: Stop", + ospf_redist_string(type), instance, + ospf_vrf_id_to_name(ospf->vrf_id)); /* Remove the routes from OSPF table. */ ospf_redistribute_withdraw(ospf, type, instance); @@ -894,11 +897,11 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype, if (cur_originate == originate) { /* Refresh the lsa since metric might different */ if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug( - "Redistribute[%s]: Refresh Type[%d], Metric[%d]", - ospf_redist_string(DEFAULT_ROUTE), - metric_type(ospf, DEFAULT_ROUTE, 0), - metric_value(ospf, DEFAULT_ROUTE, 0)); + zlog_debug("Redistribute[%s][%s]: Refresh Type[%d], Metric[%d]", + ospf_redist_string(DEFAULT_ROUTE), + ospf_vrf_id_to_name(ospf->vrf_id), + metric_type(ospf, DEFAULT_ROUTE, 0), + metric_value(ospf, DEFAULT_ROUTE, 0)); ospf_external_lsa_refresh_default(ospf); return CMD_SUCCESS; @@ -939,10 +942,10 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype, } if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug("Redistribute[DEFAULT]: %s Type[%d], Metric[%d]", - type_str, - metric_type(ospf, DEFAULT_ROUTE, 0), - metric_value(ospf, DEFAULT_ROUTE, 0)); + zlog_debug("Redistribute[DEFAULT][%s]: %s Type[%d], Metric[%d]", + ospf_vrf_id_to_name(ospf->vrf_id), type_str, + metric_type(ospf, DEFAULT_ROUTE, 0), + metric_value(ospf, DEFAULT_ROUTE, 0)); ospf_external_lsa_refresh_default(ospf); ospf_asbr_status_update(ospf, ospf->redistribute); @@ -1047,16 +1050,18 @@ static bool ospf_external_lsa_default_routemap_apply(struct ospf *ospf, } if (IS_DEBUG_OSPF_DEFAULT_INFO) - zlog_debug("Apply default originate routemap on ei: %pI4 cmd: %d", - &ei->p.prefix, cmd); + zlog_debug("Apply default originate routemap on ei: %pI4(%s) cmd: %d", + &ei->p.prefix, ospf_vrf_id_to_name(ospf->vrf_id), + cmd); ret = ospf_external_info_apply_default_routemap(ospf, ei, default_ei); /* If deny then nothing to be done both in add and del case. */ if (!ret) { if (IS_DEBUG_OSPF_DEFAULT_INFO) - zlog_debug("Default originte routemap deny for ei: %pI4", - &ei->p.prefix); + zlog_debug("Default originte routemap deny for ei: %pI4(%s)", + &ei->p.prefix, + ospf_vrf_id_to_name(ospf->vrf_id)); return false; } @@ -1068,12 +1073,14 @@ static bool ospf_external_lsa_default_routemap_apply(struct ospf *ospf, /* If permit and default already advertise then return. */ if (lsa && !IS_LSA_MAXAGE(lsa)) { if (IS_DEBUG_OSPF_DEFAULT_INFO) - zlog_debug("Default lsa already originated"); + zlog_debug("Default lsa already originated(%s)", + ospf_vrf_id_to_name(ospf->vrf_id)); return true; } if (IS_DEBUG_OSPF_DEFAULT_INFO) - zlog_debug("Originating/Refreshing default lsa"); + zlog_debug("Originating/Refreshing default lsa(%s)", + ospf_vrf_id_to_name(ospf->vrf_id)); if (lsa && IS_LSA_MAXAGE(lsa)) /* Refresh lsa.*/ @@ -1088,15 +1095,15 @@ static bool ospf_external_lsa_default_routemap_apply(struct ospf *ospf, /* If deny and lsa is not originated then nothing to be done.*/ if (!lsa) { if (IS_DEBUG_OSPF_DEFAULT_INFO) - zlog_debug( - "Default lsa not originated, not flushing"); + zlog_debug("Default lsa not originated, not flushing(%s)", + ospf_vrf_id_to_name(ospf->vrf_id)); return true; } if (IS_DEBUG_OSPF_DEFAULT_INFO) - zlog_debug( - "Running default route-map again as ei: %pI4 deleted", - &ei->p.prefix); + zlog_debug("Running default route-map again as ei: %pI4(%s) deleted", + &ei->p.prefix, + ospf_vrf_id_to_name(ospf->vrf_id)); /* * if this route delete was permitted then we need to check * there are any other external info which can still trigger @@ -1142,9 +1149,10 @@ int ospf_redistribute_check(struct ospf *ospf, struct external_info *ei, if (access_list_apply(DISTRIBUTE_LIST(ospf, type), p) == FILTER_DENY) { if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug( - "Redistribute[%s]: %pFX filtered by distribute-list.", - ospf_redist_string(type), p); + zlog_debug("Redistribute[%s]: %pFX(%s) filtered by distribute-list.", + ospf_redist_string(type), p, + ospf_vrf_id_to_name( + ospf->vrf_id)); return 0; } @@ -1165,9 +1173,9 @@ int ospf_redistribute_check(struct ospf *ospf, struct external_info *ei, if (ret == RMAP_DENYMATCH) { ei->route_map_set = save_values; if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug( - "Redistribute[%s]: %pFX filtered by route-map.", - ospf_redist_string(type), p); + zlog_debug("Redistribute[%s]: %pFX(%s) filtered by route-map.", + ospf_redist_string(type), p, + ospf_vrf_id_to_name(ospf->vrf_id)); return 0; } @@ -1230,7 +1238,8 @@ static int ospf_zebra_gr_update(struct ospf *ospf, int command, int ospf_zebra_gr_enable(struct ospf *ospf, uint32_t stale_time) { if (IS_DEBUG_OSPF_GR) - zlog_debug("Zebra enable GR [stale time %u]", stale_time); + zlog_debug("Zebra enable GR [stale time %u] vrf %s", stale_time, + ospf_vrf_id_to_name(ospf->vrf_id)); return ospf_zebra_gr_update(ospf, ZEBRA_CLIENT_GR_CAPABILITIES, stale_time); @@ -1239,7 +1248,8 @@ int ospf_zebra_gr_enable(struct ospf *ospf, uint32_t stale_time) int ospf_zebra_gr_disable(struct ospf *ospf) { if (IS_DEBUG_OSPF_GR) - zlog_debug("Zebra disable GR"); + zlog_debug("Zebra disable GR vrf: %s", + ospf_vrf_id_to_name(ospf->vrf_id)); return ospf_zebra_gr_update(ospf, ZEBRA_CLIENT_GR_DISABLE, 0); } @@ -1286,11 +1296,11 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS) rt_type = DEFAULT_ROUTE; if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug( - "%s: cmd %s from client %s: vrf_id %d, p %pFX, metric %d", - __func__, zserv_command_string(cmd), - zebra_route_string(api.type), vrf_id, &api.prefix, - api.metric); + zlog_debug("%s: cmd %s from client %s: vrf %s(%u), p %pFX, metric %d", + __func__, zserv_command_string(cmd), + zebra_route_string(api.type), + ospf_vrf_id_to_name(vrf_id), vrf_id, &api.prefix, + api.metric); if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD) { /* XXX|HACK|TODO|FIXME: @@ -1343,11 +1353,12 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS) return 0; if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR)) - zlog_debug( - "%s: Send Aggreate LSA (%pI4/%d)", - __func__, - &aggr->p.prefix, - aggr->p.prefixlen); + zlog_debug("%s: Send Aggreate LSA (%pI4/%d)(%s)", + __func__, + &aggr->p.prefix, + aggr->p.prefixlen, + ospf_vrf_id_to_name( + ospf->vrf_id)); ospf_originate_summary_lsa(ospf, aggr, ei); @@ -1402,10 +1413,11 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS) if (IS_DEBUG_OSPF( zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug( - "%s: %pI4 refreshing LSA", - __func__, - &p.prefix); + zlog_debug("%s: %pI4(%s) refreshing LSA", + __func__, + &p.prefix, + ospf_vrf_id_to_name( + ospf->vrf_id)); ospf_external_lsa_refresh( ospf, current, ei, LSA_REFRESH_FORCE, @@ -1464,7 +1476,8 @@ void ospf_zebra_import_default_route(struct ospf *ospf, bool unreg) if (zclient->sock < 0) { if (IS_DEBUG_OSPF(zebra, ZEBRA)) - zlog_debug(" Not connected to Zebra"); + zlog_debug(" Not connected to Zebra vrf: %s", + ospf_vrf_id_to_name(ospf->vrf_id)); return; } @@ -1477,14 +1490,14 @@ void ospf_zebra_import_default_route(struct ospf *ospf, bool unreg) command = ZEBRA_NEXTHOP_REGISTER; if (IS_DEBUG_OSPF(zebra, ZEBRA)) - zlog_debug("%s: sending cmd %s for %pFX (vrf %u)", __func__, + zlog_debug("%s: sending cmd %s for %pFX(%s)", __func__, zserv_command_string(command), &prefix, - ospf->vrf_id); + ospf_vrf_id_to_name(ospf->vrf_id)); if (zclient_send_rnh(zclient, command, &prefix, SAFI_UNICAST, false, true, ospf->vrf_id) == ZCLIENT_SEND_FAILURE) - flog_err(EC_LIB_ZAPI_SOCKET, "%s: zclient_send_rnh() failed", - __func__); + flog_err(EC_LIB_ZAPI_SOCKET, "%s(%s): zclient_send_rnh() failed", + __func__, ospf_vrf_id_to_name(ospf->vrf_id)); } static void ospf_zebra_import_check_update(struct vrf *vrf, struct prefix *match, @@ -1556,7 +1569,8 @@ static void ospf_distribute_list_update_timer(struct event *thread) ospf->t_distribute_update = NULL; - zlog_info("Zebra[Redistribute]: distribute-list update timer fired!"); + zlog_info("Zebra[Redistribute]: vrf: %s distribute-list update timer fired!", + ospf_vrf_id_to_name(ospf->vrf_id)); if (IS_DEBUG_OSPF_EVENT) { zlog_debug("%s: ospf distribute-list update vrf %s id %d", @@ -1607,10 +1621,12 @@ static void ospf_distribute_list_update_timer(struct event *thread) lsa, EXTNL_LSA_AGGR)) zlog_debug( - "%s: Send Aggregate LSA (%pI4/%d)", + "%s: Send Aggregate LSA (%pI4/%d)(%s)", __func__, &aggr->p.prefix, - aggr->p.prefixlen); + aggr->p.prefixlen, + ospf_vrf_id_to_name( + ospf->vrf_id)); /* Originate Aggregate * LSA diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 1d013b260e..7638e979a2 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -1098,6 +1098,15 @@ struct ospf_interface *add_ospf_interface(struct connected *co, oi->p2mp_delay_reflood = IF_DEF_PARAMS(co->ifp)->p2mp_delay_reflood; oi->p2mp_non_broadcast = IF_DEF_PARAMS(co->ifp)->p2mp_non_broadcast; + /* + * If a neighbor filter is configured, update the neighbor filter + * for the interface. + */ + if (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS(co->ifp), nbr_filter_name)) + oi->nbr_filter = prefix_list_lookup(AFI_IP, + IF_DEF_PARAMS(co->ifp) + ->nbr_filter_name); + /* Add pseudo neighbor. */ ospf_nbr_self_reset(oi, oi->ospf->router_id); diff --git a/tests/ospf6d/test_lsdb.c b/tests/ospf6d/test_lsdb.c index f9df73538a..9cec4a3182 100644 --- a/tests/ospf6d/test_lsdb.c +++ b/tests/ospf6d/test_lsdb.c @@ -12,6 +12,7 @@ #include "vector.h" #include "vty.h" +#include "ospf6d/ospf6_proto.h" /* for struct ospf6_prefix */ #include "ospf6d/ospf6_lsa.h" #include "ospf6d/ospf6_lsdb.h" diff --git a/tests/topotests/bgp_dual_as/__init__.py b/tests/topotests/bgp_dual_as/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp_dual_as/__init__.py diff --git a/tests/topotests/bgp_dual_as/r1/frr.conf b/tests/topotests/bgp_dual_as/r1/frr.conf new file mode 100644 index 0000000000..9dcfe05d69 --- /dev/null +++ b/tests/topotests/bgp_dual_as/r1/frr.conf @@ -0,0 +1,11 @@ +! +interface r1-eth0 + ip address 10.0.0.1/24 +! +router bgp 65000 + no bgp ebgp-requires-policy + neighbor 10.0.0.2 remote-as 65002 + neighbor 10.0.0.2 local-as 65001 no-prepend replace-as dual-as + neighbor 10.0.0.2 timers 3 10 + neighbor 10.0.0.2 timers connect 1 +! diff --git a/tests/topotests/bgp_dual_as/r2/frr.conf b/tests/topotests/bgp_dual_as/r2/frr.conf new file mode 100644 index 0000000000..cf5731b601 --- /dev/null +++ b/tests/topotests/bgp_dual_as/r2/frr.conf @@ -0,0 +1,10 @@ +! +interface r2-eth0 + ip address 10.0.0.2/24 +! +router bgp 65002 + no bgp ebgp-requires-policy + neighbor 10.0.0.1 remote-as 65001 + neighbor 10.0.0.1 timers 3 10 + neighbor 10.0.0.1 timers connect 1 +! diff --git a/tests/topotests/bgp_dual_as/test_bgp_dual_as.py b/tests/topotests/bgp_dual_as/test_bgp_dual_as.py new file mode 100644 index 0000000000..fcac9c94ec --- /dev/null +++ b/tests/topotests/bgp_dual_as/test_bgp_dual_as.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# Copyright (c) 2024 by +# Donatas Abraitis <donatas@opensourcerouting.org> +# + +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, get_topogen +from lib.common_config import step + +pytestmark = [pytest.mark.bgpd] + + +def build_topo(tgen): + r1 = tgen.add_router("r1") + r2 = tgen.add_router("r2") + + switch = tgen.add_switch("s1") + switch.add_link(r1) + switch.add_link(r2) + + +def setup_module(mod): + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + for _, (rname, router) in enumerate(tgen.routers().items(), 1): + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_dual_as(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + r2 = tgen.gears["r2"] + + def _bgp_converge_65001(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 summary json")) + expected = { + "ipv4Unicast": { + "as": 65000, + "peers": { + "10.0.0.2": { + "hostname": "r2", + "remoteAs": 65002, + "localAs": 65001, + "state": "Established", + "peerState": "OK", + } + }, + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_converge_65001) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Can't establish BGP session using local-as AS 65001" + + step("Change remote-as from r2 to use global AS 65000") + r2.vtysh_cmd( + """ + configure terminal + router bgp + neighbor 10.0.0.1 remote-as 65000 + """ + ) + + def _bgp_converge_65000(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 summary json")) + expected = { + "ipv4Unicast": { + "as": 65000, + "peers": { + "10.0.0.2": { + "hostname": "r2", + "remoteAs": 65002, + "localAs": 65000, + "state": "Established", + "peerState": "OK", + } + }, + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_converge_65000) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Can't establish BGP session using global AS 65000" + + +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/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py index 2400cd2853..bba0061858 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py @@ -21,7 +21,7 @@ from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger from lib.common_config import required_linux_kernel_version -from lib.checkping import check_ping, check_ping +from lib.checkping import check_ping pytestmark = [pytest.mark.bgpd] diff --git a/tests/topotests/dump_of_bgp/r1/frr.conf b/tests/topotests/dump_of_bgp/r1/frr.conf new file mode 100644 index 0000000000..d677e2007e --- /dev/null +++ b/tests/topotests/dump_of_bgp/r1/frr.conf @@ -0,0 +1,12 @@ +! +int r1-eth0 + ip address 192.168.1.1/24 +! +router bgp 65001 + no bgp ebgp-requires-policy + neighbor 192.168.1.2 remote-as external + neighbor 192.168.1.2 timers 1 3 + neighbor 192.168.1.2 timers connect 1 + neighbor 192.168.1.2 capability dynamic + ! +! diff --git a/tests/topotests/dump_of_bgp/r2/frr.conf b/tests/topotests/dump_of_bgp/r2/frr.conf new file mode 100644 index 0000000000..d68d13d075 --- /dev/null +++ b/tests/topotests/dump_of_bgp/r2/frr.conf @@ -0,0 +1,17 @@ +! +int lo + ip address 10.10.10.10/32 +! +int r2-eth0 + ip address 192.168.1.2/24 +! +router bgp 65002 + no bgp ebgp-requires-policy + neighbor 192.168.1.1 remote-as external + neighbor 192.168.1.1 timers 1 3 + neighbor 192.168.1.1 timers connect 1 + ! + address-family ipv4 unicast + redistribute connected + exit-address-family +! diff --git a/tests/topotests/dump_of_bgp/test_dump_of_bgp.py b/tests/topotests/dump_of_bgp/test_dump_of_bgp.py new file mode 100644 index 0000000000..1359c57f31 --- /dev/null +++ b/tests/topotests/dump_of_bgp/test_dump_of_bgp.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# Copyright (c) 2024 by Nvidia Corporation +# Donald Sharp <sharpd@nvidia.com> + +import os +import sys +import json +import pytest +import functools +from lib.topolog import logger + +pytestmark = [pytest.mark.bgpd] + +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, get_topogen + + +def setup_module(mod): + topodef = {"s1": ("r1", "r2")} + tgen = Topogen(topodef, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for _, (rname, router) in enumerate(router_list.items(), 1): + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_dump(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Test the ability for bgp to dump a file specified") + r1 = tgen.gears["r1"] + + logger.info("Converge BGP") + def _converge(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast 10.10.10.10/32 json")) + expected = { + "paths": [ + { + "valid": True, + "nexthops": [ + { + "hostname": "r2", + "accessible": True, + } + ], + } + ] + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _converge, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Can't converge" + + logger.info("Dumping file") + #### + # Create a dump file + #### + r1.vtysh_cmd( + """ + configure terminal + dump bgp all bgp_dump.file + """ + ) + + def _test_dump_file_existence(): + dump_file = "{}/r1/bgp_dump.file".format(tgen.logdir) + + logger.info("Looking for {} file".format(dump_file)) + logger.info(os.path.isfile(dump_file)) + return os.path.isfile(dump_file) + + logger.info("Ensure that Log file exists") + _, result = topotest.run_and_expect(_test_dump_file_existence, True, count=30, wait = 3) + assert result is True + + # At this point all we have done is ensure that the dump file + # is generated for r1. What is correctness of the dump anyways? + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/forwarding_on_off/r1/frr.conf b/tests/topotests/forwarding_on_off/r1/frr.conf new file mode 100644 index 0000000000..677ba8f63e --- /dev/null +++ b/tests/topotests/forwarding_on_off/r1/frr.conf @@ -0,0 +1,14 @@ +int lo + ip address 10.1.1.1/32 + ip address 10:1::1:1/128 + +int eth0 + ip address 10.1.2.1/24 + ipv6 address 10:1::2:1/120 + +ip route 10.1.1.2/32 10.1.2.2 +ip route 10.1.1.3/32 10.1.2.2 +ip route 10.1.3.0/24 10.1.2.2 +ipv6 route 10:1::1:2/128 10:1::2:2 +ipv6 route 10:1::1:3/128 10:1::2:2 +ipv6 route 10:1::3:0/90 10:1::2:2
\ No newline at end of file diff --git a/tests/topotests/forwarding_on_off/r2/frr.conf b/tests/topotests/forwarding_on_off/r2/frr.conf new file mode 100644 index 0000000000..b6da6e2231 --- /dev/null +++ b/tests/topotests/forwarding_on_off/r2/frr.conf @@ -0,0 +1,19 @@ +no ip forwarding +no ipv6 forwarding + +int lo + ip address 10.1.1.2/32 + ipv6 address 10:1::1:2/128 + +int eth0 + ip address 10.1.2.2/24 + ipv6 address 10:1::2:2/120 + +int eth1 + ip address 10.1.3.2/24 + ipv6 address 10:1::3:2/120 + +ip route 10.1.1.1/32 10.1.2.1 +ip route 10.1.1.3/32 10.1.3.3 +ipv6 route 10:1::1:1/128 10:1::2:1 +ipv6 route 10:1::1:3/128 10:1::3:3 diff --git a/tests/topotests/forwarding_on_off/r3/frr.conf b/tests/topotests/forwarding_on_off/r3/frr.conf new file mode 100644 index 0000000000..ea05f18400 --- /dev/null +++ b/tests/topotests/forwarding_on_off/r3/frr.conf @@ -0,0 +1,15 @@ +int lo + ip address 10.1.1.3/32 + ipv6 address 10:1::1:3/128 + +int eth0 + ip address 10.1.3.3/24 + ipv6 address 10:1::3:3/120 + + +ip route 10.1.1.1/32 10.1.3.2 +ip route 10.1.1.2/32 10.1.3.2 +ip route 10.1.2.0/24 10.1.3.2 +ipv6 route 10:1::1:1/128 10:1::3:2 +ipv6 route 10:1::1:2/128 10:1::3:2 +ipv6 route 10:1::2:0/120 10:1::3:2
\ No newline at end of file diff --git a/tests/topotests/forwarding_on_off/test_forwarding_on_off.py b/tests/topotests/forwarding_on_off/test_forwarding_on_off.py new file mode 100644 index 0000000000..fa0483888c --- /dev/null +++ b/tests/topotests/forwarding_on_off/test_forwarding_on_off.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC +# +# test_forwarding_on_off.py +# +# Copyright (c) 2024 by Nvidia Corporation +# Donald Sharp +# + +""" +test_forwarding_on_off.py: Test that forwarding is turned off then back on + +""" + +import ipaddress +import json +import pytest +import sys +import time + +from functools import partial +from lib import topotest +from lib.topogen import Topogen, get_topogen +from lib.topolog import logger +from lib.checkping import check_ping + +pytestmark = [ + pytest.mark.staticd, +] + + +def build_topo(tgen): + """Build the topology used by all tests below.""" + + # Create 3 routers + r1 = tgen.add_router("r1") + r2 = tgen.add_router("r2") + r3 = tgen.add_router("r3") + + # Add a link between r1 <-> r2 and r2 <-> r3 + tgen.add_link(r1, r2, ifname1="eth0", ifname2="eth0") + tgen.add_link(r2, r3, ifname1="eth1", ifname2="eth0") + + +def setup_module(mod): + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for _, router in router_list.items(): + router.load_frr_config("frr.conf") + + tgen.start_router() + + +def teardown_module(): + tgen = get_topogen() + tgen.stop_topology() + + +def test_no_forwarding(): + tgen = get_topogen() + r2 = tgen.gears["r2"] + + def _no_forwarding(family, status): + logger.info("Testing for: {} {}".format(family, status)) + rc, o, e = r2.net.cmd_status( + 'vtysh -c "show zebra" | grep "{}" | grep "{}"'.format(family, status) + ) + + logger.info("Output: {}".format(o)) + return rc + + test_func = partial(_no_forwarding, "v4 Forwarding", "Off") + _, result = topotest.run_and_expect(test_func, 0, count=15, wait=1) + assert result == 0 + + test_func = partial(_no_forwarding, "v6 Forwarding", "Off") + _, result = topotest.run_and_expect(test_func, 0, count=15, wait=1) + assert result == 0 + + logger.info("Sending pings that should fail") + check_ping("r1", "10.1.1.3", False, 10, 1) + check_ping("r1", "10:1::1:3", False, 10, 1) + + logger.info("Turning on Forwarding") + r2.vtysh_cmd("conf\nip forwarding\nipv6 forwarding") + + test_func = partial(_no_forwarding, "v4 Forwarding", "On") + _, result = topotest.run_and_expect(test_func, 0, count=15, wait=1) + assert result == 0 + + test_func = partial(_no_forwarding, "v6 Forwarding", "On") + _, result = topotest.run_and_expect(test_func, 0, count=15, wait=1) + assert result == 0 + + check_ping("r1", "10.1.1.3", True, 10, 1) + check_ping("r1", "10:1::1:3", True, 10, 1) + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py index 540a627c65..cb71112af3 100644 --- a/tests/topotests/lib/common_config.py +++ b/tests/topotests/lib/common_config.py @@ -936,7 +936,7 @@ def generate_support_bundle(): tgen = get_topogen() if tgen is None: - logger.warn( + logger.warning( "Support bundle attempted to be generated, but topogen is not being used" ) return True diff --git a/tests/topotests/lib/topotest.py b/tests/topotests/lib/topotest.py index dc6107bbef..d15fefc039 100644 --- a/tests/topotests/lib/topotest.py +++ b/tests/topotests/lib/topotest.py @@ -424,7 +424,7 @@ def run_and_expect(func, what, count=20, wait=3): minimum_wait_time = 15 # The overall minimum seconds for the test to wait wait_time = wait * count if wait_time < minimum_wait_time: - logger.warn( + logger.warning( f"Waiting time is too small (count={count}, wait={wait}), using default values (count={minimum_count}, wait={minimum_wait})" ) count = minimum_count diff --git a/tests/topotests/mgmt_oper/r1/frr-yanglib.conf b/tests/topotests/mgmt_oper/r1/frr-yanglib.conf new file mode 100644 index 0000000000..f37766b158 --- /dev/null +++ b/tests/topotests/mgmt_oper/r1/frr-yanglib.conf @@ -0,0 +1,10 @@ +log timestamp precision 6 +log file frr.log + +no debug memstats-at-exit + +debug mgmt backend datastore frontend transaction + +interface r1-eth0 + ip address 1.1.1.1/24 +exit diff --git a/tests/topotests/mgmt_oper/test_yanglib.py b/tests/topotests/mgmt_oper/test_yanglib.py new file mode 100644 index 0000000000..e094ca5443 --- /dev/null +++ b/tests/topotests/mgmt_oper/test_yanglib.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC +# -*- coding: utf-8 eval: (blacken-mode 1) -*- +# +# September 17 2024, Christian Hopps <chopps@labn.net> +# +# Copyright (c) 2024, LabN Consulting, L.L.C. +# + +import json +import pytest +from lib.topogen import Topogen + +pytestmark = [pytest.mark.staticd, pytest.mark.mgmtd] + + +@pytest.fixture(scope="module") +def tgen(request): + "Setup/Teardown the environment and provide tgen argument to tests" + + topodef = {"s1": ("r1",)} + + tgen = Topogen(topodef, request.module.__name__) + tgen.start_topology() + + router_list = tgen.routers() + for rname, router in router_list.items(): + router.load_frr_config("frr-yanglib.conf") + + tgen.start_router() + yield tgen + tgen.stop_topology() + + +def test_yang_lib(tgen): + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"].net + output = r1.cmd_nostatus( + "vtysh -c 'show mgmt get-data /ietf-yang-library:yang-library'" + ) + ret = json.loads(output) + loaded_modules = ret['ietf-yang-library:yang-library']['module-set'][0]['module'] + assert len(loaded_modules) > 10, "Modules missing from yang-library" diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt index 797bced7b8..131085a47a 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt @@ -2,7 +2,7 @@ O 10.0.1.0/24 [110/10] is directly connected, r1-eth0, weight 1, XX:XX:XX C>* 10.0.1.0/24 is directly connected, r1-eth0, weight 1, XX:XX:XX L>* 10.0.1.1/32 is directly connected, r1-eth0, weight 1, XX:XX:XX O>* 10.0.2.0/24 [110/20] via 10.0.20.2, r1-eth1, weight 1, XX:XX:XX -B>* 10.0.3.0/24 [20/20] via 10.0.30.3, r1-eth2 (vrf neno), weight 1, XX:XX:XX +B>* 10.0.3.0/24 [110/20] via 10.0.30.3, r1-eth2 (vrf neno), weight 1, XX:XX:XX O>* 10.0.4.0/24 [110/20] via 10.0.20.2, r1-eth1, weight 1, XX:XX:XX O 10.0.20.0/24 [110/10] is directly connected, r1-eth1, weight 1, XX:XX:XX C>* 10.0.20.0/24 is directly connected, r1-eth1, weight 1, XX:XX:XX diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-neno.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-neno.txt index 1dc574f360..45ee1071d4 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-neno.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-neno.txt @@ -1,7 +1,7 @@ VRF neno: O>* 10.0.3.0/24 [110/20] via 10.0.30.3, r1-eth2, weight 1, XX:XX:XX -B>* 10.0.4.0/24 [20/20] via 10.0.20.2, r1-eth1 (vrf default), weight 1, XX:XX:XX +B>* 10.0.4.0/24 [110/20] via 10.0.20.2, r1-eth1 (vrf default), weight 1, XX:XX:XX O 10.0.30.0/24 [110/10] is directly connected, r1-eth2, weight 1, XX:XX:XX C>* 10.0.30.0/24 is directly connected, r1-eth2, weight 1, XX:XX:XX L>* 10.0.30.1/32 is directly connected, r1-eth2, weight 1, XX:XX:XX -B>* 10.0.40.0/24 [20/20] via 10.0.20.2, r1-eth1 (vrf default), weight 1, XX:XX:XX +B>* 10.0.40.0/24 [110/20] via 10.0.20.2, r1-eth1 (vrf default), weight 1, XX:XX:XX diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt index b5e81bc0e9..f3724bbb9f 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt @@ -4,7 +4,7 @@ O 10.0.2.0/24 [110/10] is directly connected, r2-eth0, weight 1, XX:XX:XX C>* 10.0.2.0/24 is directly connected, r2-eth0, weight 1, XX:XX:XX L>* 10.0.2.2/32 is directly connected, r2-eth0, weight 1, XX:XX:XX O>* 10.0.3.0/24 [110/20] via 10.0.20.1, r2-eth1, weight 1, XX:XX:XX -B>* 10.0.4.0/24 [20/20] via 10.0.40.4, r2-eth2 (vrf ray), weight 1, XX:XX:XX +B>* 10.0.4.0/24 [110/20] via 10.0.40.4, r2-eth2 (vrf ray), weight 1, XX:XX:XX O 10.0.20.0/24 [110/10] is directly connected, r2-eth1, weight 1, XX:XX:XX C>* 10.0.20.0/24 is directly connected, r2-eth1, weight 1, XX:XX:XX L>* 10.0.20.2/32 is directly connected, r2-eth1, weight 1, XX:XX:XX diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt index c403496ff6..0f8b12bdfa 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt @@ -1,10 +1,10 @@ VRF ray: -B 10.0.1.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default) inactive, weight 1, XX:XX:XX +B 10.0.1.0/24 [110/20] via 10.0.20.1, r2-eth1 (vrf default) inactive, weight 1, XX:XX:XX B 10.0.2.0/24 [20/0] is directly connected, r2-eth0 (vrf default) inactive, weight 1, XX:XX:XX -B>* 10.0.3.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default), weight 1, XX:XX:XX +B>* 10.0.3.0/24 [110/20] via 10.0.20.1, r2-eth1 (vrf default), weight 1, XX:XX:XX O>* 10.0.4.0/24 [110/20] via 10.0.40.4, r2-eth2, weight 1, XX:XX:XX B 10.0.20.0/24 [20/0] is directly connected, r2-eth1 (vrf default) inactive, weight 1, XX:XX:XX -B>* 10.0.30.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default), weight 1, XX:XX:XX +B>* 10.0.30.0/24 [110/20] via 10.0.20.1, r2-eth1 (vrf default), weight 1, XX:XX:XX O 10.0.40.0/24 [110/10] is directly connected, r2-eth2, weight 1, XX:XX:XX C>* 10.0.40.0/24 is directly connected, r2-eth2, weight 1, XX:XX:XX L>* 10.0.40.2/32 is directly connected, r2-eth2, weight 1, XX:XX:XX diff --git a/tests/topotests/srv6_encap_src_addr/r1/zebra.conf b/tests/topotests/srv6_encap_src_addr/r1/zebra.conf index c570756b52..c245dd2d96 100644 --- a/tests/topotests/srv6_encap_src_addr/r1/zebra.conf +++ b/tests/topotests/srv6_encap_src_addr/r1/zebra.conf @@ -4,7 +4,6 @@ hostname r1 ! debug zebra rib detailed ! log stdout notifications -log monitor notifications log commands log file zebra.log debugging ! diff --git a/tests/topotests/srv6_sid_manager/rt1/bgpd.conf b/tests/topotests/srv6_sid_manager/rt1/bgpd.conf index 461e9023f0..20c396afde 100644 --- a/tests/topotests/srv6_sid_manager/rt1/bgpd.conf +++ b/tests/topotests/srv6_sid_manager/rt1/bgpd.conf @@ -6,7 +6,6 @@ hostname rt1 password zebra ! log stdout notifications -log monitor notifications log commands ! !debug bgp neighbor-events diff --git a/tests/topotests/srv6_sid_manager/rt6/bgpd.conf b/tests/topotests/srv6_sid_manager/rt6/bgpd.conf index fe82feece4..c36fae7901 100644 --- a/tests/topotests/srv6_sid_manager/rt6/bgpd.conf +++ b/tests/topotests/srv6_sid_manager/rt6/bgpd.conf @@ -6,7 +6,6 @@ hostname rt6 password zebra ! log stdout notifications -log monitor notifications log commands ! !debug bgp neighbor-events diff --git a/tests/topotests/zebra_seg6local_route/r1/routes.json b/tests/topotests/zebra_seg6local_route/r1/routes.json index e391922566..7dcc6450fa 100644 --- a/tests/topotests/zebra_seg6local_route/r1/routes.json +++ b/tests/topotests/zebra_seg6local_route/r1/routes.json @@ -119,5 +119,78 @@ }] }], "required_kernel": "5.14" + }, + { + "in": { + "dest": "6::1", + "context": "End_DX6 2001::1" + }, + "out":[{ + "prefix":"6::1/128", + "protocol":"sharp", + "selected":true, + "destSelected":true, + "distance":150, + "metric":0, + "installed":true, + "table":254, + "nexthops":[{ + "flags":3, + "fib":true, + "active":true, + "directlyConnected":true, + "interfaceName": "dum0", + "seg6local": { "action": "End.DX6" } + }] + }] + }, + { + "in": { + "dest": "7::1", + "context": "End_DT4 10" + }, + "out":[{ + "prefix":"7::1/128", + "protocol":"sharp", + "selected":true, + "destSelected":true, + "distance":150, + "metric":0, + "installed":true, + "table":254, + "nexthops":[{ + "flags":3, + "fib":true, + "active":true, + "directlyConnected":true, + "interfaceName": "dum0", + "seg6local": { "action": "End.DT4" } + }] + }], + "required_kernel": "5.11" + }, + { + "in": { + "dest": "8::1", + "context": "End_DT6 10" + }, + "out":[{ + "prefix":"8::1/128", + "protocol":"sharp", + "selected":true, + "destSelected":true, + "distance":150, + "metric":0, + "installed":true, + "table":254, + "nexthops":[{ + "flags":3, + "fib":true, + "active":true, + "directlyConnected":true, + "interfaceName": "dum0", + "seg6local": { "action": "End.DT6" } + }] + }] } ] diff --git a/tests/topotests/zebra_seg6local_route/test_zebra_seg6local_route.py b/tests/topotests/zebra_seg6local_route/test_zebra_seg6local_route.py index a90f5c9c98..59c681df48 100755 --- a/tests/topotests/zebra_seg6local_route/test_zebra_seg6local_route.py +++ b/tests/topotests/zebra_seg6local_route/test_zebra_seg6local_route.py @@ -42,7 +42,7 @@ def setup_module(mod): tgen = Topogen({None: "r1"}, mod.__name__) tgen.start_topology() router_list = tgen.routers() - for rname, router in tgen.routers().items(): + for rname, router in router_list.items(): router.run( "/bin/bash {}".format(os.path.join(CWD, "{}/setup.sh".format(rname))) ) diff --git a/yang/frr-bgp-common.yang b/yang/frr-bgp-common.yang index 2b1babdd28..9d21597304 100644 --- a/yang/frr-bgp-common.yang +++ b/yang/frr-bgp-common.yang @@ -320,6 +320,19 @@ submodule frr-bgp-common { When set to 'false' BGP instance type is regular."; } + leaf as-notation { + type enumeration { + enum "plain" { value 0; } + enum "dot" { value 1; } + enum "dot+" { value 2; } + } + description + "The as-notation type: + - plain: use plain format for all AS values + - dot: use 'AA.BB' format for AS 4 byte values. + - dot+: use 'AA.BB' format for all AS values."; + } + leaf ebgp-multihop-connected-route-check { type boolean; default "false"; diff --git a/yang/frr-bgp-route-map.yang b/yang/frr-bgp-route-map.yang index abfb14c23c..44058ab04e 100644 --- a/yang/frr-bgp-route-map.yang +++ b/yang/frr-bgp-route-map.yang @@ -847,7 +847,7 @@ identity set-extcommunity-color { } case extcommunity-nt { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:set-extcommunity-nt')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:set-extcommunity-nt')"; description "Value of the ext-community"; leaf extcommunity-nt { @@ -1008,7 +1008,7 @@ identity set-extcommunity-color { } case aigp-metric { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:aigp-metric')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:aigp-metric')"; leaf aigp-metric { type string; description @@ -1127,16 +1127,14 @@ identity set-extcommunity-color { case comm-list-name { when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:comm-list-delete') or " + "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:large-comm-list-delete') or " - + "derived-from-or-self(../frr-route-map:action, -'frr-bgp-route-map:extended-comm-list-delete')"; + + "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:extended-comm-list-delete')"; leaf comm-list-name { type bgp-filter:bgp-list-name; } } case evpn-gateway-ip-ipv4 { when - "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, - 'frr-bgp-route-map:set-evpn-gateway-ip-ipv4')"; + "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:set-evpn-gateway-ip-ipv4')"; description "Set EVPN gateway IP overlay index IPv4"; leaf evpn-gateway-ip-ipv4 { @@ -1145,8 +1143,7 @@ identity set-extcommunity-color { } case evpn-gateway-ip-ipv6 { when - "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, - 'frr-bgp-route-map:set-evpn-gateway-ip-ipv6')"; + "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:set-evpn-gateway-ip-ipv6')"; description "Set EVPN gateway IP overlay index IPv6"; leaf evpn-gateway-ip-ipv6 { @@ -1155,8 +1152,7 @@ identity set-extcommunity-color { } case l3vpn-nexthop-encapsulation { when - "derived-from-or-self(../frr-route-map:action, - 'frr-bgp-route-map:set-l3vpn-nexthop-encapsulation')"; + "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:set-l3vpn-nexthop-encapsulation')"; description "Accept L3VPN traffic over other than LSP encapsulation"; leaf l3vpn-nexthop-encapsulation { diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 3233519873..5fb908eb0d 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -1799,14 +1799,18 @@ int netlink_tunneldump_read(struct zebra_ns *zns) ret = netlink_request_tunneldump(zns, PF_BRIDGE, tmp_if->ifindex); - if (ret < 0) + if (ret < 0) { + route_unlock_node(rn); return ret; + } ret = netlink_parse_info(netlink_link_change, netlink_cmd, &dp_info, 0, true); - if (ret < 0) + if (ret < 0) { + route_unlock_node(rn); return ret; + } } return 0; diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index d2f1db67ee..84aabc4254 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -672,21 +672,6 @@ void netlink_parse_rtattr_nested(struct rtattr **tb, int max, netlink_parse_rtattr(tb, max, RTA_DATA(rta), RTA_PAYLOAD(rta)); } -bool nl_addraw_l(struct nlmsghdr *n, unsigned int maxlen, const void *data, - unsigned int len) -{ - if (NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len) > maxlen) { - zlog_err("ERROR message exceeded bound of %d", maxlen); - return false; - } - - memcpy(NLMSG_TAIL(n), data, len); - memset((uint8_t *)NLMSG_TAIL(n) + len, 0, NLMSG_ALIGN(len) - len); - n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len); - - return true; -} - bool nl_attr_put(struct nlmsghdr *n, unsigned int maxlen, int type, const void *data, unsigned int alen) { diff --git a/zebra/kernel_netlink.h b/zebra/kernel_netlink.h index e37bba0cf6..9db4e5789a 100644 --- a/zebra/kernel_netlink.h +++ b/zebra/kernel_netlink.h @@ -77,14 +77,6 @@ extern void netlink_parse_rtattr_flags(struct rtattr **tb, int max, unsigned short flags); extern void netlink_parse_rtattr_nested(struct rtattr **tb, int max, struct rtattr *rta); -/* - * nl_addraw_l copies raw form the netlink message buffer into netlink - * message header pointer. It ensures the aligned data buffer does not - * override past max length. - * return value is 0 if its successful - */ -extern bool nl_addraw_l(struct nlmsghdr *n, unsigned int maxlen, - const void *data, unsigned int len); extern const char *nl_msg_type_to_str(uint16_t msg_type); extern const char *nl_rtproto_to_str(uint8_t rtproto); extern const char *nl_family_to_str(uint8_t family); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index ddcb83cd8c..75e4396e92 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1688,7 +1688,7 @@ static bool _netlink_route_build_singlepath(const struct prefix *p, return false; if (!nl_attr_put(nlmsg, req_size, SEG6_LOCAL_NH6, &ctx->nh6, - sizeof(struct in_addr))) + sizeof(struct in6_addr))) return false; break; case ZEBRA_SEG6_LOCAL_ACTION_END_DT6: @@ -2979,7 +2979,7 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd, if (!nl_attr_put(&req->n, buflen, SEG6_LOCAL_NH6, &ctx->nh6, - sizeof(struct in_addr))) + sizeof(struct in6_addr))) return 0; break; case SEG6_LOCAL_ACTION_END_DT6: diff --git a/zebra/zebra_evpn.c b/zebra/zebra_evpn.c index ebb5a42298..a733b5917f 100644 --- a/zebra/zebra_evpn.c +++ b/zebra/zebra_evpn.c @@ -663,6 +663,7 @@ static int zebra_evpn_map_vlan_ns(struct ns *ns, vni_id = zebra_vxlan_if_access_vlan_vni_find(zif, br_if); if (vni_id) { found = 1; + route_unlock_node(rn); break; } } @@ -757,6 +758,7 @@ static int zebra_evpn_from_svi_ns(struct ns *ns, zebra_vxlan_if_access_vlan_vni_find(zif, br_if); if (vni_id) { found = 1; + route_unlock_node(rn); break; } } @@ -842,6 +844,7 @@ static int zvni_map_to_macvlan_ns(struct ns *ns, void *_in_param, void **_p_ifp) if (zif->link == in_param->svi_if) { *p_ifp = tmp_if; + route_unlock_node(rn); return NS_WALK_STOP; } } diff --git a/zebra/zebra_evpn_mac.c b/zebra/zebra_evpn_mac.c index bfc060db61..0d53591336 100644 --- a/zebra/zebra_evpn_mac.c +++ b/zebra/zebra_evpn_mac.c @@ -47,9 +47,9 @@ uint32_t num_valid_macs(struct zebra_evpn *zevpn) for (i = 0; i < hash->size; i++) { for (hb = hash->index[i]; hb; hb = hb->next) { mac = (struct zebra_mac *)hb->data; - if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) - || CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL) - || !CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) + if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) || + CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL) || + !CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) num_macs++; } } @@ -103,7 +103,8 @@ static void zebra_evpn_mac_ifp_unlink(struct zebra_mac *zmac) if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) zlog_debug("VNI %d MAC %pEA unlinked from ifp %s (%u)", - zmac->zevpn->vni, &zmac->macaddr, ifp->name, ifp->ifindex); + zmac->zevpn->vni, &zmac->macaddr, ifp->name, + ifp->ifindex); zif = ifp->info; list_delete_node(zif->mac_list, &zmac->ifp_listnode); @@ -117,16 +118,17 @@ void zebra_evpn_mac_ifp_del(struct interface *ifp) struct listnode *node; struct zebra_mac *zmac; - if (zif->mac_list) { - if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) - zlog_debug("MAC list deleted for ifp %s (%u)", - zif->ifp->name, zif->ifp->ifindex); + if (!zif->mac_list) + return; - for (ALL_LIST_ELEMENTS_RO(zif->mac_list, node, zmac)) { - zebra_evpn_mac_ifp_unlink(zmac); - } - list_delete(&zif->mac_list); - } + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) + zlog_debug("MAC list deleted for ifp %s (%u)", zif->ifp->name, + zif->ifp->ifindex); + + for (ALL_LIST_ELEMENTS_RO(zif->mac_list, node, zmac)) + zebra_evpn_mac_ifp_unlink(zmac); + + list_delete(&zif->mac_list); } /* Link local mac to destination access port. This is done only if the @@ -159,7 +161,8 @@ static void zebra_evpn_mac_ifp_link(struct zebra_mac *zmac, if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) zlog_debug("VNI %d MAC %pEA linked to ifp %s (%u)", - zmac->zevpn->vni, &zmac->macaddr, ifp->name, ifp->ifindex); + zmac->zevpn->vni, &zmac->macaddr, ifp->name, + ifp->ifindex); zmac->ifp = ifp; listnode_init(&zmac->ifp_listnode, zmac); @@ -201,7 +204,7 @@ int zebra_evpn_rem_mac_install(struct zebra_evpn *zevpn, struct zebra_mac *mac, return -1; sticky = !!CHECK_FLAG(mac->flags, - (ZEBRA_MAC_STICKY | ZEBRA_MAC_REMOTE_DEF_GW)); + (ZEBRA_MAC_STICKY | ZEBRA_MAC_REMOTE_DEF_GW)); /* If nexthop group for the FDB entry is inactive (not programmed in * the dataplane) the MAC entry cannot be installed @@ -245,14 +248,14 @@ int zebra_evpn_rem_mac_uninstall(struct zebra_evpn *zevpn, enum zebra_dplane_result res; /* If the MAC was not installed there is no need to uninstall it */ - if (!force && mac->es && !CHECK_FLAG(mac->es->flags, ZEBRA_EVPNES_NHG_ACTIVE)) + if (!force && mac->es && + !CHECK_FLAG(mac->es->flags, ZEBRA_EVPNES_NHG_ACTIVE)) return -1; if (!zevpn->vxlan_if) { if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "VNI %u hash %p couldn't be uninstalled - no intf", - zevpn->vni, zevpn); + zlog_debug("VNI %u hash %p couldn't be uninstalled - no intf", + zevpn->vni, zevpn); return -1; } @@ -278,7 +281,8 @@ int zebra_evpn_rem_mac_uninstall(struct zebra_evpn *zevpn, ifp = zevpn->vxlan_if; vtep_ip = mac->fwd_info.r_vtep_ip; - res = dplane_rem_mac_del(ifp, br_ifp, vid, &mac->macaddr, vni->vni, vtep_ip); + res = dplane_rem_mac_del(ifp, br_ifp, vid, &mac->macaddr, vni->vni, + vtep_ip); if (res != ZEBRA_DPLANE_REQUEST_FAILURE) return 0; else @@ -297,9 +301,9 @@ void zebra_evpn_deref_ip2mac(struct zebra_evpn *zevpn, struct zebra_mac *mac) /* If all remote neighbors referencing a remote MAC go away, * we need to uninstall the MAC. */ - if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) - && remote_neigh_count(mac) == 0) { - zebra_evpn_rem_mac_uninstall(zevpn, mac, false /*force*/); + if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) && + remote_neigh_count(mac) == 0) { + zebra_evpn_rem_mac_uninstall(zevpn, mac, false); zebra_evpn_es_mac_deref_entry(mac); UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE); } @@ -336,7 +340,8 @@ static void zebra_evpn_mac_get_access_info(struct zebra_mac *mac, *vid = mac->fwd_info.local.vid; zns = zebra_ns_lookup(mac->fwd_info.local.ns_id); - *p_ifp = if_lookup_by_index_per_ns(zns, mac->fwd_info.local.ifindex); + *p_ifp = if_lookup_by_index_per_ns(zns, + mac->fwd_info.local.ifindex); } } @@ -350,18 +355,26 @@ static char *zebra_evpn_zebra_mac_flag_dump(struct zebra_mac *mac, char *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) ? "PEER Active " : "", - CHECK_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_PROXY) ? "PROXY " : "", - CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE) ? "LOC Inactive " : ""); + 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) + ? "PEER Active " + : "", + CHECK_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_PROXY) ? "PROXY " + : "", + CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE) + ? "LOC Inactive " + : ""); return buf; } @@ -391,11 +404,11 @@ static void zebra_evpn_dad_mac_auto_recovery_exp(struct event *t) if (IS_ZEBRA_DEBUG_VXLAN) { char mac_buf[MAC_BUF_SIZE]; - zlog_debug( - "%s: duplicate addr mac %pEA flags %slearn count %u host count %u auto recovery expired", - __func__, &mac->macaddr, - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)), - mac->dad_count, listcount(mac->neigh_list)); + zlog_debug("%s: duplicate addr mac %pEA flags %slearn count %u host count %u auto recovery expired", + __func__, &mac->macaddr, + 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 */ @@ -404,7 +417,7 @@ static void zebra_evpn_dad_mac_auto_recovery_exp(struct event *t) if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) ZEBRA_NEIGH_SET_INACTIVE(nbr); else if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_REMOTE)) - zebra_evpn_rem_neigh_install(zevpn, nbr, false /*was_static*/); + zebra_evpn_rem_neigh_install(zevpn, nbr, false); } UNSET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE); @@ -423,11 +436,12 @@ static void zebra_evpn_dad_mac_auto_recovery_exp(struct event *t) if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) { /* Inform to BGP */ if (zebra_evpn_mac_send_add_to_client(zevpn->vni, &mac->macaddr, - mac->flags, mac->loc_seq, mac->es)) + mac->flags, mac->loc_seq, + mac->es)) return; /* Process all neighbors associated with this MAC. */ - zebra_evpn_process_neigh_on_local_mac_change(zevpn, mac, 0, 0 /*es_change*/); + zebra_evpn_process_neigh_on_local_mac_change(zevpn, mac, 0, 0); } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) { zebra_evpn_process_neigh_on_remote_mac_add(zevpn, mac); @@ -445,7 +459,7 @@ static void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf, { struct zebra_neigh *nbr; struct listnode *node = NULL; - struct timeval elapsed = {0, 0}; + struct timeval elapsed = { 0, 0 }; bool reset_params = false; if (!(zebra_evpn_do_dup_addr_detect(zvrf) && do_dad)) @@ -459,11 +473,11 @@ static void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf, if (IS_ZEBRA_DEBUG_VXLAN) { char mac_buf[MAC_BUF_SIZE]; - zlog_debug( - "%s: duplicate addr MAC %pEA flags %sskip update to client, learn count %u recover time %u", - __func__, &mac->macaddr, - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)), - mac->dad_count, zvrf->dad_freeze_time); + zlog_debug("%s: duplicate addr MAC %pEA flags %sskip update to client, learn count %u recover time %u", + __func__, &mac->macaddr, + 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 @@ -495,11 +509,11 @@ static void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf, if (IS_ZEBRA_DEBUG_VXLAN) { char mac_buf[MAC_BUF_SIZE]; - zlog_debug( - "%s: duplicate addr MAC %pEA flags %sdetection time passed, reset learn count %u", - __func__, &mac->macaddr, - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)), - mac->dad_count); + zlog_debug("%s: duplicate addr MAC %pEA flags %sdetection time passed, reset learn count %u", + __func__, &mac->macaddr, + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf)), + mac->dad_count); } mac->dad_count = 0; @@ -526,10 +540,11 @@ static void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf, if (mac->dad_count >= zvrf->dad_max_moves) { flog_warn(EC_ZEBRA_DUP_MAC_DETECTED, - "VNI %u: MAC %pEA detected as duplicate during %s VTEP %pI4", - mac->zevpn->vni, &mac->macaddr, - is_local ? "local update, last" : "remote update, from", - &vtep_ip); + "VNI %u: MAC %pEA detected as duplicate during %s VTEP %pI4", + mac->zevpn->vni, &mac->macaddr, + is_local ? "local update, last" + : "remote update, from", + &vtep_ip); SET_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE); @@ -540,7 +555,6 @@ static void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf, * associcated with this MAC */ for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, nbr)) { - /* Ony Mark IPs which are Local */ if (!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL)) continue; @@ -561,16 +575,18 @@ static void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf, if (IS_ZEBRA_DEBUG_VXLAN) { char mac_buf[MAC_BUF_SIZE]; - zlog_debug( - "%s: duplicate addr MAC %pEA flags %sauto recovery time %u start", - __func__, &mac->macaddr, - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)), - zvrf->dad_freeze_time); + zlog_debug("%s: duplicate addr MAC %pEA flags %sauto recovery time %u start", + __func__, &mac->macaddr, + zebra_evpn_zebra_mac_flag_dump( + mac, mac_buf, + sizeof(mac_buf)), + zvrf->dad_freeze_time); } event_add_timer(zrouter.master, - zebra_evpn_dad_mac_auto_recovery_exp, mac, - zvrf->dad_freeze_time, &mac->dad_mac_auto_recovery_timer); + zebra_evpn_dad_mac_auto_recovery_exp, + mac, zvrf->dad_freeze_time, + &mac->dad_mac_auto_recovery_timer); } /* In case of local update, do not inform to client (BGPd), @@ -592,7 +608,7 @@ void zebra_evpn_print_mac(struct zebra_mac *mac, void *ctxt, json_object *json) char buf1[ETHER_ADDR_STRLEN]; char buf2[INET6_ADDRSTRLEN]; struct zebra_vrf *zvrf; - struct timeval detect_start_time = {0, 0}; + struct timeval detect_start_time = { 0, 0 }; char timebuf[MONOTIME_STRLEN]; char thread_buf[EVENT_TIMER_STRLEN]; time_t uptime; @@ -617,18 +633,22 @@ void zebra_evpn_print_mac(struct zebra_mac *mac, void *ctxt, json_object *json) zebra_evpn_mac_get_access_info(mac, &ifp, &vid); json_object_string_add(json_mac, "type", "local"); if (ifp) { - json_object_string_add(json_mac, "intf", ifp->name); - json_object_int_add(json_mac, "ifindex", ifp->ifindex); + json_object_string_add(json_mac, "intf", + ifp->name); + json_object_int_add(json_mac, "ifindex", + ifp->ifindex); } if (vid) json_object_int_add(json_mac, "vlan", vid); } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) { json_object_string_add(json_mac, "type", "remote"); if (mac->es) - json_object_string_add(json_mac, "remoteEs", mac->es->esi_str); + json_object_string_add(json_mac, "remoteEs", + mac->es->esi_str); else - json_object_string_addf( - json_mac, "remoteVtep", "%pI4", &mac->fwd_info.r_vtep_ip); + json_object_string_addf(json_mac, "remoteVtep", + "%pI4", + &mac->fwd_info.r_vtep_ip); } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) json_object_string_add(json_mac, "type", "auto"); @@ -642,7 +662,8 @@ void zebra_evpn_print_mac(struct zebra_mac *mac, void *ctxt, json_object *json) json_object_boolean_true_add(json_mac, "defaultGateway"); if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW)) - json_object_boolean_true_add(json_mac, "remoteGatewayMac"); + json_object_boolean_true_add(json_mac, + "remoteGatewayMac"); json_object_string_add(json_mac, "uptime", up_str); json_object_int_add(json_mac, "localSequence", mac->loc_seq); @@ -663,30 +684,42 @@ void zebra_evpn_print_mac(struct zebra_mac *mac, void *ctxt, json_object *json) if (CHECK_FLAG(mac->flags, ZEBRA_MAC_ES_PEER_ACTIVE)) json_object_boolean_true_add(json_mac, "peerActive"); if (mac->hold_timer) - json_object_string_add(json_mac, "peerActiveHold", - event_timer_to_hhmmss(thread_buf, sizeof(thread_buf), mac->hold_timer)); + json_object_string_add( + json_mac, "peerActiveHold", + event_timer_to_hhmmss(thread_buf, + sizeof(thread_buf), + mac->hold_timer)); if (mac->es) - json_object_string_add(json_mac, "esi", mac->es->esi_str); + json_object_string_add(json_mac, "esi", + mac->es->esi_str); /* print all the associated neigh */ if (!listcount(mac->neigh_list)) json_object_string_add(json_mac, "neighbors", "none"); else { json_object *json_active_nbrs = json_object_new_array(); - json_object *json_inactive_nbrs = json_object_new_array(); + json_object *json_inactive_nbrs = + json_object_new_array(); json_object *json_nbrs = json_object_new_object(); for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, n)) { if (IS_ZEBRA_NEIGH_ACTIVE(n)) - json_object_array_add(json_active_nbrs, - json_object_new_string(ipaddr2str(&n->ip, buf2, sizeof(buf2)))); + json_object_array_add( + json_active_nbrs, + json_object_new_string( + ipaddr2str(&n->ip, buf2, + sizeof(buf2)))); else json_object_array_add( json_inactive_nbrs, - json_object_new_string(ipaddr2str(&n->ip, buf2, sizeof(buf2)))); + json_object_new_string( + ipaddr2str(&n->ip, buf2, + sizeof(buf2)))); } - json_object_object_add(json_nbrs, "active", json_active_nbrs); - json_object_object_add(json_nbrs, "inactive", json_inactive_nbrs); + json_object_object_add(json_nbrs, "active", + json_active_nbrs); + json_object_object_add(json_nbrs, "inactive", + json_inactive_nbrs); json_object_object_add(json_mac, "neighbors", json_nbrs); } @@ -704,7 +737,8 @@ void zebra_evpn_print_mac(struct zebra_mac *mac, void *ctxt, json_object *json) vty_out(vty, " ESI: %s\n", mac->es->esi_str); if (ifp) - vty_out(vty, " Intf: %s(%u)", ifp->name, ifp->ifindex); + vty_out(vty, " Intf: %s(%u)", ifp->name, + ifp->ifindex); else vty_out(vty, " Intf: -"); vty_out(vty, " VLAN: %u", vid); @@ -712,7 +746,8 @@ void zebra_evpn_print_mac(struct zebra_mac *mac, void *ctxt, json_object *json) if (mac->es) vty_out(vty, " Remote ES: %s", mac->es->esi_str); else - vty_out(vty, " Remote VTEP: %pI4", &mac->fwd_info.r_vtep_ip); + vty_out(vty, " Remote VTEP: %pI4", + &mac->fwd_info.r_vtep_ip); } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) { vty_out(vty, " Auto Mac "); } @@ -739,18 +774,24 @@ void zebra_evpn_print_mac(struct zebra_mac *mac, void *ctxt, json_object *json) vty_out(vty, " peer-active"); if (mac->hold_timer) vty_out(vty, " (ht: %s)", - event_timer_to_hhmmss(thread_buf, sizeof(thread_buf), mac->hold_timer)); + event_timer_to_hhmmss(thread_buf, + sizeof(thread_buf), + mac->hold_timer)); vty_out(vty, "\n"); - vty_out(vty, " Local Seq: %u Remote Seq: %u\n", mac->loc_seq, mac->rem_seq); + vty_out(vty, " Local Seq: %u Remote Seq: %u\n", mac->loc_seq, + mac->rem_seq); vty_out(vty, " Uptime: %s\n", up_str); if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) { vty_out(vty, " Duplicate, detected at %s", - time_to_string(mac->dad_dup_detect_time, timebuf)); + time_to_string(mac->dad_dup_detect_time, + timebuf)); } else if (mac->dad_count) { - monotime_since(&mac->detect_start_time, &detect_start_time); + monotime_since(&mac->detect_start_time, + &detect_start_time); if (detect_start_time.tv_sec <= zvrf->dad_time) { - time_to_string(mac->detect_start_time.tv_sec, timebuf); + time_to_string(mac->detect_start_time.tv_sec, + timebuf); vty_out(vty, " Duplicate detection started at %s, detection count %u\n", timebuf, mac->dad_count); @@ -765,7 +806,8 @@ void zebra_evpn_print_mac(struct zebra_mac *mac, void *ctxt, json_object *json) for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, n)) { vty_out(vty, " %s %s\n", ipaddr2str(&n->ip, buf2, sizeof(buf2)), - (IS_ZEBRA_NEIGH_ACTIVE(n) ? "Active" : "Inactive")); + (IS_ZEBRA_NEIGH_ACTIVE(n) ? "Active" + : "Inactive")); } } @@ -817,12 +859,14 @@ void zebra_evpn_print_mac_hash(struct hash_bucket *bucket, void *ctxt) zebra_evpn_mac_get_access_info(mac, &ifp, &vid); if (json_mac_hdr == NULL) { vty_out(vty, "%-17s %-6s %-5s %-30s", buf1, "local", - zebra_evpn_print_mac_flags(mac, flags_buf, sizeof(flags_buf)), + zebra_evpn_print_mac_flags(mac, flags_buf, + sizeof(flags_buf)), ifp ? ifp->name : "-"); } else { json_object_string_add(json_mac, "type", "local"); if (ifp) - json_object_string_add(json_mac, "intf", ifp->name); + json_object_string_add(json_mac, "intf", + ifp->name); } if (vid) { if (json_mac_hdr == NULL) @@ -831,35 +875,41 @@ void zebra_evpn_print_mac_hash(struct hash_bucket *bucket, void *ctxt) json_object_int_add(json_mac, "vlan", vid); } else /* No vid? fill out the space */ if (json_mac_hdr == NULL) - vty_out(vty, " %-5s", ""); + vty_out(vty, " %-5s", ""); if (json_mac_hdr == NULL) { vty_out(vty, " %u/%u", mac->loc_seq, mac->rem_seq); vty_out(vty, "\n"); } else { - json_object_int_add(json_mac, "localSequence", mac->loc_seq); - json_object_int_add(json_mac, "remoteSequence", mac->rem_seq); - json_object_int_add(json_mac, "detectionCount", mac->dad_count); + json_object_int_add(json_mac, "localSequence", + mac->loc_seq); + json_object_int_add(json_mac, "remoteSequence", + mac->rem_seq); + json_object_int_add(json_mac, "detectionCount", + mac->dad_count); if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) - json_object_boolean_true_add(json_mac, "isDuplicate"); + json_object_boolean_true_add(json_mac, + "isDuplicate"); else - json_object_boolean_false_add(json_mac, "isDuplicate"); + json_object_boolean_false_add(json_mac, + "isDuplicate"); json_object_object_add(json_mac_hdr, buf1, json_mac); } wctx->count++; } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) { - - if (CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP) - && !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &wctx->r_vtep_ip)) + if (CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP) && + !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &wctx->r_vtep_ip)) return; if (json_mac_hdr == NULL) { - if (CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP) - && (wctx->count == 0)) { + if (CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP) && + (wctx->count == 0)) { vty_out(vty, "\nVNI %u\n\n", wctx->zevpn->vni); vty_out(vty, "%-17s %-6s %-5s%-30s %-5s %s\n", - "MAC", "Type", "Flags", "Intf/Remote ES/VTEP", "VLAN", "Seq #'s"); + "MAC", "Type", "Flags", + "Intf/Remote ES/VTEP", "VLAN", + "Seq #'s"); } if (mac->es == NULL) inet_ntop(AF_INET, &mac->fwd_info.r_vtep_ip, @@ -867,24 +917,32 @@ void zebra_evpn_print_mac_hash(struct hash_bucket *bucket, void *ctxt) vty_out(vty, "%-17s %-6s %-5s %-30s %-5s %u/%u\n", buf1, "remote", - zebra_evpn_print_mac_flags(mac, flags_buf, sizeof(flags_buf)), - mac->es ? mac->es->esi_str : addr_buf, - "", mac->loc_seq, mac->rem_seq); + zebra_evpn_print_mac_flags(mac, flags_buf, + sizeof(flags_buf)), + mac->es ? mac->es->esi_str : addr_buf, "", + mac->loc_seq, mac->rem_seq); } else { json_object_string_add(json_mac, "type", "remote"); if (mac->es) - json_object_string_add(json_mac, "remoteEs", mac->es->esi_str); + json_object_string_add(json_mac, "remoteEs", + mac->es->esi_str); else - json_object_string_addf( - json_mac, "remoteVtep", "%pI4", &mac->fwd_info.r_vtep_ip); + json_object_string_addf(json_mac, "remoteVtep", + "%pI4", + &mac->fwd_info.r_vtep_ip); json_object_object_add(json_mac_hdr, buf1, json_mac); - json_object_int_add(json_mac, "localSequence", mac->loc_seq); - json_object_int_add(json_mac, "remoteSequence", mac->rem_seq); - json_object_int_add(json_mac, "detectionCount", mac->dad_count); + json_object_int_add(json_mac, "localSequence", + mac->loc_seq); + json_object_int_add(json_mac, "remoteSequence", + mac->rem_seq); + json_object_int_add(json_mac, "detectionCount", + mac->dad_count); if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) - json_object_boolean_true_add(json_mac, "isDuplicate"); + json_object_boolean_true_add(json_mac, + "isDuplicate"); else - json_object_boolean_false_add(json_mac, "isDuplicate"); + json_object_boolean_false_add(json_mac, + "isDuplicate"); } wctx->count++; @@ -917,8 +975,7 @@ void zebra_evpn_print_mac_hash_detail(struct hash_bucket *bucket, void *ctxt) /* * Inform BGP about local MACIP. */ -int zebra_evpn_macip_send_msg_to_client(vni_t vni, - const struct ethaddr *macaddr, +int zebra_evpn_macip_send_msg_to_client(vni_t vni, const struct ethaddr *macaddr, const struct ipaddr *ip, uint8_t flags, uint32_t seq, int state, struct zebra_evpn_es *es, uint16_t cmd) @@ -966,13 +1023,12 @@ int zebra_evpn_macip_send_msg_to_client(vni_t vni, if (IS_ZEBRA_DEBUG_VXLAN) { char flag_buf[MACIP_BUF_SIZE]; - zlog_debug( - "Send MACIP %s f %s state %u MAC %pEA IP %pIA 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)), - state, macaddr, ip, seq, vni, - es ? es->esi_str : "-", - zebra_route_string(client->proto)); + zlog_debug("Send MACIP %s f %s state %u MAC %pEA IP %pIA 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)), + state, macaddr, ip, seq, vni, es ? es->esi_str : "-", + zebra_route_string(client->proto)); } if (cmd == ZEBRA_MACIP_ADD) @@ -1005,7 +1061,8 @@ static bool mac_cmp(const void *p1, const void *p2) if (pmac1 == NULL || pmac2 == NULL) return false; - return (memcmp(pmac1->macaddr.octet, pmac2->macaddr.octet, ETH_ALEN) == 0); + return (memcmp(pmac1->macaddr.octet, pmac2->macaddr.octet, ETH_ALEN) == + 0); } /* @@ -1046,7 +1103,8 @@ struct zebra_mac *zebra_evpn_mac_add(struct zebra_evpn *zevpn, char mac_buf[MAC_BUF_SIZE]; zlog_debug("%s: MAC %pEA flags %s", __func__, &mac->macaddr, - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf))); + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf))); } return mac; } @@ -1062,7 +1120,8 @@ int zebra_evpn_mac_del(struct zebra_evpn *zevpn, struct zebra_mac *mac) char mac_buf[MAC_BUF_SIZE]; zlog_debug("%s: MAC %pEA flags %s", __func__, &mac->macaddr, - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf))); + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf))); } /* force de-ref any ES entry linked to the MAC */ @@ -1087,10 +1146,10 @@ int zebra_evpn_mac_del(struct zebra_evpn *zevpn, struct zebra_mac *mac) */ if (!list_isempty(mac->neigh_list)) { if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "MAC %pEA (flags 0x%x vni %u) has non-empty neigh list " - "count %u, mark MAC as AUTO", &mac->macaddr, mac->flags, - zevpn->vni, listcount(mac->neigh_list)); + zlog_debug("MAC %pEA (flags 0x%x vni %u) has non-empty neigh list " + "count %u, mark MAC as AUTO", + &mac->macaddr, mac->flags, zevpn->vni, + listcount(mac->neigh_list)); SET_FLAG(mac->flags, ZEBRA_MAC_AUTO); return 0; @@ -1127,25 +1186,26 @@ struct zebra_mac *zebra_evpn_mac_add_auto(struct zebra_evpn *zevpn, static bool zebra_evpn_check_mac_del_from_db(struct mac_walk_ctx *wctx, struct zebra_mac *mac) { - if (CHECK_FLAG(wctx->flags, DEL_LOCAL_MAC) - && CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) + if (CHECK_FLAG(wctx->flags, DEL_LOCAL_MAC) && + CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) return true; - else if (CHECK_FLAG(wctx->flags, DEL_REMOTE_MAC) - && CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) + else if (CHECK_FLAG(wctx->flags, DEL_REMOTE_MAC) && + CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) return true; - else if (CHECK_FLAG(wctx->flags, DEL_REMOTE_MAC_FROM_VTEP) - && CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) - && IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &wctx->r_vtep_ip)) + else if (CHECK_FLAG(wctx->flags, DEL_REMOTE_MAC_FROM_VTEP) && + CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) && + IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &wctx->r_vtep_ip)) return true; - else if (CHECK_FLAG(wctx->flags, DEL_LOCAL_MAC) - && CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO) - && !listcount(mac->neigh_list)) { + else if (CHECK_FLAG(wctx->flags, DEL_LOCAL_MAC) && + CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO) && + !listcount(mac->neigh_list)) { if (IS_ZEBRA_DEBUG_VXLAN) { char mac_buf[MAC_BUF_SIZE]; - zlog_debug( - "%s: Del MAC %pEA flags %s", __func__, &mac->macaddr, - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf))); + zlog_debug("%s: Del MAC %pEA flags %s", __func__, + &mac->macaddr, + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf))); } wctx->uninstall = 0; @@ -1163,23 +1223,25 @@ static void zebra_evpn_mac_del_hash_entry(struct hash_bucket *bucket, void *arg) struct mac_walk_ctx *wctx = arg; struct zebra_mac *mac = bucket->data; - if (zebra_evpn_check_mac_del_from_db(wctx, mac)) { - if (wctx->upd_client && CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) { - zebra_evpn_mac_send_del_to_client(wctx->zevpn->vni, - &mac->macaddr, mac->flags, false); - } - if (wctx->uninstall) { - if (zebra_evpn_mac_is_static(mac)) - zebra_evpn_sync_mac_dp_install(mac, false /* set_inactive */, - true /* force_clear_static */, __func__); + if (!zebra_evpn_check_mac_del_from_db(wctx, mac)) + return; - if (mac->flags & ZEBRA_MAC_REMOTE) - zebra_evpn_rem_mac_uninstall(wctx->zevpn, mac, false /*force*/); - } + if (wctx->upd_client && CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) { + zebra_evpn_mac_send_del_to_client(wctx->zevpn->vni, + &mac->macaddr, mac->flags, + false); + } + if (wctx->uninstall) { + if (zebra_evpn_mac_is_static(mac)) + zebra_evpn_sync_mac_dp_install(mac, false, true, + __func__); - zebra_evpn_mac_del(wctx->zevpn, mac); + if (mac->flags & ZEBRA_MAC_REMOTE) + zebra_evpn_rem_mac_uninstall(wctx->zevpn, mac, false); } + zebra_evpn_mac_del(wctx->zevpn, mac); + return; } @@ -1249,7 +1311,8 @@ int zebra_evpn_mac_send_add_to_client(vni_t vni, const struct ethaddr *macaddr, SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW); return zebra_evpn_macip_send_msg_to_client(vni, macaddr, NULL, flags, - seq, ZEBRA_NEIGH_ACTIVE, es, ZEBRA_MACIP_ADD); + seq, ZEBRA_NEIGH_ACTIVE, es, + ZEBRA_MACIP_ADD); } /* @@ -1261,8 +1324,8 @@ int zebra_evpn_mac_send_del_to_client(vni_t vni, const struct ethaddr *macaddr, int state = ZEBRA_NEIGH_ACTIVE; if (!force) { - if (CHECK_FLAG(flags, ZEBRA_MAC_LOCAL_INACTIVE) - && !CHECK_FLAG(flags, ZEBRA_MAC_ES_PEER_ACTIVE)) + if (CHECK_FLAG(flags, ZEBRA_MAC_LOCAL_INACTIVE) && + !CHECK_FLAG(flags, ZEBRA_MAC_ES_PEER_ACTIVE)) /* the host was not advertised - nothing to delete */ return 0; @@ -1275,8 +1338,8 @@ int zebra_evpn_mac_send_del_to_client(vni_t vni, const struct ethaddr *macaddr, state = ZEBRA_NEIGH_INACTIVE; } - return zebra_evpn_macip_send_msg_to_client(vni, macaddr, NULL, - 0 /* flags */, 0 /* seq */, state, NULL, ZEBRA_MACIP_DEL); + return zebra_evpn_macip_send_msg_to_client(vni, macaddr, NULL, 0, 0, + state, NULL, ZEBRA_MACIP_DEL); } /* @@ -1308,12 +1371,11 @@ int zebra_evpn_sync_mac_dp_install(struct zebra_mac *mac, bool set_inactive, es_evi = zebra_evpn_es_evi_find(mac->es, mac->zevpn); if (!es_evi) { if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) - zlog_debug( - "%s: dp-install sync-mac vni %u mac %pEA es %s 0x%x %sskipped, no es-evi", - caller, zevpn->vni, &mac->macaddr, - mac->es ? mac->es->esi_str : "-", - mac->flags, - set_inactive ? "inactive " : ""); + zlog_debug("%s: dp-install sync-mac vni %u mac %pEA es %s 0x%x %sskipped, no es-evi", + caller, zevpn->vni, &mac->macaddr, + mac->es ? mac->es->esi_str : "-", + mac->flags, + set_inactive ? "inactive " : ""); return -1; } } @@ -1325,12 +1387,12 @@ int zebra_evpn_sync_mac_dp_install(struct zebra_mac *mac, bool set_inactive, 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 %s%sskipped, no access-port", - caller, zevpn->vni, &mac->macaddr, - mac->es ? mac->es->esi_str : "-", - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)), - set_inactive ? "inactive " : ""); + zlog_debug("%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 : "-", + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf)), + set_inactive ? "inactive " : ""); } return -1; } @@ -1341,12 +1403,12 @@ int zebra_evpn_sync_mac_dp_install(struct zebra_mac *mac, bool set_inactive, 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 %s%sskipped, no br", - caller, zevpn->vni, &mac->macaddr, - mac->es ? mac->es->esi_str : "-", - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)), - set_inactive ? "inactive " : ""); + zlog_debug("%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 : "-", + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf)), + set_inactive ? "inactive " : ""); } return -1; } @@ -1365,21 +1427,21 @@ int zebra_evpn_sync_mac_dp_install(struct zebra_mac *mac, bool set_inactive, 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 %s%s", - set_static ? "install" : "uninstall", - zevpn->vni, &mac->macaddr, - mac->es ? mac->es->esi_str : "-", - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)), - set_inactive ? "inactive " : ""); + zlog_debug("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 : "-", + 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 */ - zebra_evpn_rem_mac_install(zevpn, mac, true /* old_static */); + zebra_evpn_rem_mac_install(zevpn, mac, true); else - zebra_evpn_rem_mac_uninstall(zevpn, mac, false /* force */); + zebra_evpn_rem_mac_uninstall(zevpn, mac, false); return 0; } @@ -1390,13 +1452,14 @@ int zebra_evpn_sync_mac_dp_install(struct zebra_mac *mac, bool set_inactive, 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)), + 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); + set_static, set_inactive); return 0; } @@ -1406,11 +1469,11 @@ void zebra_evpn_mac_send_add_del_to_client(struct zebra_mac *mac, { if (new_bgp_ready) zebra_evpn_mac_send_add_to_client(mac->zevpn->vni, - &mac->macaddr, mac->flags, - mac->loc_seq, mac->es); + &mac->macaddr, mac->flags, + mac->loc_seq, mac->es); else if (old_bgp_ready) - zebra_evpn_mac_send_del_to_client(mac->zevpn->vni, - &mac->macaddr, mac->flags, true /* force */); + zebra_evpn_mac_send_del_to_client(mac->zevpn->vni, &mac->macaddr, + mac->flags, true); } /* MAC hold timer is used to age out peer-active flag. @@ -1443,23 +1506,23 @@ static void zebra_evpn_mac_hold_exp_cb(struct event *t) if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) { char mac_buf[MAC_BUF_SIZE]; - zlog_debug( - "sync-mac vni %u mac %pEA es %s %shold expired", - mac->zevpn->vni, &mac->macaddr, - mac->es ? mac->es->esi_str : "-", - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf))); + zlog_debug("sync-mac vni %u mac %pEA es %s %shold expired", + mac->zevpn->vni, &mac->macaddr, + 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 */ if (old_static != new_static) - zebra_evpn_sync_mac_dp_install(mac, false /* set_inactive */, - false /* force_clear_static */, __func__); + zebra_evpn_sync_mac_dp_install(mac, false, false, __func__); /* inform bgp if needed */ if (old_bgp_ready != new_bgp_ready) - zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready, new_bgp_ready); + zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready, + new_bgp_ready); } static inline void zebra_evpn_mac_start_hold_timer(struct zebra_mac *mac) @@ -1470,11 +1533,11 @@ static inline void zebra_evpn_mac_start_hold_timer(struct zebra_mac *mac) if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) { char mac_buf[MAC_BUF_SIZE]; - zlog_debug( - "sync-mac vni %u mac %pEA es %s %shold started", - mac->zevpn->vni, &mac->macaddr, - mac->es ? mac->es->esi_str : "-", - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf))); + zlog_debug("sync-mac vni %u mac %pEA es %s %shold started", + mac->zevpn->vni, &mac->macaddr, + mac->es ? mac->es->esi_str : "-", + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf))); } event_add_timer(zrouter.master, zebra_evpn_mac_hold_exp_cb, mac, zmh_info->mac_hold_time, &mac->hold_timer); @@ -1488,11 +1551,11 @@ void zebra_evpn_mac_stop_hold_timer(struct zebra_mac *mac) if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) { char mac_buf[MAC_BUF_SIZE]; - zlog_debug( - "sync-mac vni %u mac %pEA es %s %shold stopped", - mac->zevpn->vni, &mac->macaddr, - mac->es ? mac->es->esi_str : "-", - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf))); + zlog_debug("sync-mac vni %u mac %pEA es %s %shold stopped", + mac->zevpn->vni, &mac->macaddr, + mac->es ? mac->es->esi_str : "-", + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf))); } EVENT_OFF(mac->hold_timer); @@ -1506,11 +1569,11 @@ void zebra_evpn_sync_mac_del(struct zebra_mac *mac) if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) { char mac_buf[MAC_BUF_SIZE]; - zlog_debug( - "sync-mac del vni %u mac %pEA es %s seq %d f %s", - mac->zevpn->vni, &mac->macaddr, - mac->es ? mac->es->esi_str : "-", mac->loc_seq, - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf))); + zlog_debug("sync-mac del vni %u mac %pEA es %s seq %d f %s", + mac->zevpn->vni, &mac->macaddr, + mac->es ? mac->es->esi_str : "-", mac->loc_seq, + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf))); } old_static = zebra_evpn_mac_is_static(mac); @@ -1521,8 +1584,7 @@ void zebra_evpn_sync_mac_del(struct zebra_mac *mac) if (old_static != new_static) /* program the local mac in the kernel */ - zebra_evpn_sync_mac_dp_install(mac, false /* set_inactive */, - false /* force_clear_static */, __func__); + zebra_evpn_sync_mac_dp_install(mac, false, false, __func__); } static inline bool zebra_evpn_mac_is_bgp_seq_ok(struct zebra_evpn *zevpn, @@ -1543,44 +1605,41 @@ static inline bool zebra_evpn_mac_is_bgp_seq_ok(struct zebra_evpn *zevpn, n_type = "remote"; } - if (seq < tmp_seq) { - - if (is_local && !zebra_evpn_mac_is_ready_for_bgp(mac->flags)) { - if (IS_ZEBRA_DEBUG_EVPN_MH_MAC || IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "%s-macip not ready vni %u %s-mac %pEA lower seq %u f 0x%x", - sync ? "sync" : "rem", zevpn->vni, - n_type, &mac->macaddr, tmp_seq, mac->flags); - return true; - } - - /* if the mac was never advertised to bgp we must accept - * whatever sequence number bgp sends - */ - if (!is_local && zebra_vxlan_get_accept_bgp_seq()) { - if (IS_ZEBRA_DEBUG_EVPN_MH_MAC || - IS_ZEBRA_DEBUG_VXLAN) { - zlog_debug( - "%s-macip accept vni %u %s-mac %pEA lower seq %u f %s", - (sync ? "sync" : "rem"), - zevpn->vni, n_type, &mac->macaddr, tmp_seq, - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf))); - } + if (seq >= tmp_seq) + return true; - return true; - } + if (is_local && !zebra_evpn_mac_is_ready_for_bgp(mac->flags)) { + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC || IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("%s-macip not ready vni %u %s-mac %pEA lower seq %u f 0x%x", + sync ? "sync" : "rem", zevpn->vni, n_type, + &mac->macaddr, tmp_seq, mac->flags); + return true; + } + /* if the mac was never advertised to bgp we must accept + * whatever sequence number bgp sends + */ + if (!is_local && zebra_vxlan_get_accept_bgp_seq()) { if (IS_ZEBRA_DEBUG_EVPN_MH_MAC || IS_ZEBRA_DEBUG_VXLAN) { - zlog_debug( - "%s-macip ignore vni %u %s-mac %pEA as existing has higher seq %u f %s", - (sync ? "sync" : "rem"), zevpn->vni, n_type, &mac->macaddr, tmp_seq, - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf))); + zlog_debug("%s-macip accept vni %u %s-mac %pEA lower seq %u f %s", + (sync ? "sync" : "rem"), zevpn->vni, n_type, + &mac->macaddr, tmp_seq, + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf))); } - return false; + return true; } - return true; + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC || IS_ZEBRA_DEBUG_VXLAN) { + zlog_debug("%s-macip ignore vni %u %s-mac %pEA as existing has higher seq %u f %s", + (sync ? "sync" : "rem"), zevpn->vni, n_type, + &mac->macaddr, tmp_seq, + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf))); + } + + return false; } struct zebra_mac *zebra_evpn_proc_sync_mac_update(struct zebra_evpn *zevpn, @@ -1644,13 +1703,14 @@ struct zebra_mac *zebra_evpn_proc_sync_mac_update(struct zebra_evpn *zevpn, remote_gw = !!CHECK_FLAG(old_flags, ZEBRA_MAC_REMOTE_DEF_GW); if (sticky || remote_gw) { if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH) - zlog_debug( - "Ignore sync-macip vni %u mac %pEA%s%s%s%s", - zevpn->vni, macaddr, - ipa_len ? " IP " : "", - ipa_len ? ipaddr2str(ipaddr, ipbuf, sizeof(ipbuf)) : "", - sticky ? " sticky" : "", - remote_gw ? " remote_gw" : ""); + zlog_debug("Ignore sync-macip vni %u mac %pEA%s%s%s%s", + zevpn->vni, macaddr, + ipa_len ? " IP " : "", + ipa_len ? ipaddr2str(ipaddr, ipbuf, + sizeof(ipbuf)) + : "", + sticky ? " sticky" : "", + remote_gw ? " remote_gw" : ""); return NULL; } if (!zebra_evpn_mac_is_bgp_seq_ok(zevpn, mac, seq, true)) @@ -1664,7 +1724,9 @@ struct zebra_mac *zebra_evpn_proc_sync_mac_update(struct zebra_evpn *zevpn, SET_FLAG(new_flags, ZEBRA_MAC_LOCAL); /* retain old local activity flag */ if (CHECK_FLAG(old_flags, ZEBRA_MAC_LOCAL)) - SET_FLAG (new_flags, CHECK_FLAG(old_flags, ZEBRA_MAC_LOCAL_INACTIVE)); + SET_FLAG(new_flags, + CHECK_FLAG(old_flags, + ZEBRA_MAC_LOCAL_INACTIVE)); else SET_FLAG(new_flags, ZEBRA_MAC_LOCAL_INACTIVE); @@ -1672,7 +1734,9 @@ struct zebra_mac *zebra_evpn_proc_sync_mac_update(struct zebra_evpn *zevpn, /* if mac-ip route do NOT update the peer flags * i.e. retain only flags as is */ - SET_FLAG(new_flags, CHECK_FLAG(old_flags, ZEBRA_MAC_ALL_PEER_FLAGS)); + SET_FLAG(new_flags, + CHECK_FLAG(old_flags, + ZEBRA_MAC_ALL_PEER_FLAGS)); } else { /* if mac-only route update peer flags */ if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT)) { @@ -1682,8 +1746,10 @@ struct zebra_mac *zebra_evpn_proc_sync_mac_update(struct zebra_evpn *zevpn, * holdtimer on it. the peer-active flag is * cleared on holdtimer expiry. */ - if (CHECK_FLAG(old_flags, ZEBRA_MAC_ES_PEER_ACTIVE)) { - SET_FLAG(new_flags, ZEBRA_MAC_ES_PEER_ACTIVE); + if (CHECK_FLAG(old_flags, + ZEBRA_MAC_ES_PEER_ACTIVE)) { + SET_FLAG(new_flags, + ZEBRA_MAC_ES_PEER_ACTIVE); zebra_evpn_mac_start_hold_timer(mac); } } else { @@ -1703,11 +1769,13 @@ struct zebra_mac *zebra_evpn_proc_sync_mac_update(struct zebra_evpn *zevpn, struct zebra_mac omac; omac.flags = old_flags; - zlog_debug( - "sync-mac vni %u mac %pEA old_f %snew_f %s", - zevpn->vni, macaddr, - zebra_evpn_zebra_mac_flag_dump(&omac, omac_buf, sizeof(omac_buf)), - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf))); + zlog_debug("sync-mac vni %u mac %pEA old_f %snew_f %s", + zevpn->vni, macaddr, + 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 */ @@ -1747,24 +1815,25 @@ struct zebra_mac *zebra_evpn_proc_sync_mac_update(struct zebra_evpn *zevpn, char mac_buf[MAC_BUF_SIZE]; zlog_debug("sync-mac %s vni %u mac %pEA es %s seq %d f %s%s%s", - created ? "created" : "updated", - zevpn->vni, macaddr, - mac->es ? mac->es->esi_str : "-", - mac->loc_seq, - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)), - inform_bgp ? "inform_bgp" : "", - inform_dataplane ? " inform_dp" : ""); + created ? "created" : "updated", zevpn->vni, macaddr, + mac->es ? mac->es->esi_str : "-", mac->loc_seq, + 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, new_bgp_ready); + zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready, + new_bgp_ready); /* neighs using the mac may need to be re-sent to * bgp with updated info */ if (seq_change || es_change || !old_local) - zebra_evpn_process_neigh_on_local_mac_change( - zevpn, mac, seq_change, es_change); + zebra_evpn_process_neigh_on_local_mac_change(zevpn, mac, + seq_change, + es_change); if (inform_dataplane && !ipa_len) { /* program the local mac in the kernel. when the ES @@ -1772,8 +1841,8 @@ struct zebra_mac *zebra_evpn_proc_sync_mac_update(struct zebra_evpn *zevpn, * the activity as we are yet to establish activity * locally */ - zebra_evpn_sync_mac_dp_install(mac, mac_inactive /* set_inactive */, - false /* force_clear_static */, __func__); + zebra_evpn_sync_mac_dp_install(mac, mac_inactive, false, + __func__); } return mac; @@ -1783,7 +1852,8 @@ struct zebra_mac *zebra_evpn_proc_sync_mac_update(struct zebra_evpn *zevpn, * is detected */ static bool zebra_evpn_local_mac_update_fwd_info(struct zebra_mac *mac, - struct interface *ifp, vlanid_t vid) + struct interface *ifp, + vlanid_t vid) { struct zebra_if *zif = ifp->info; bool es_change; @@ -1825,8 +1895,8 @@ static void zebra_evpn_send_mac_hash_entry_to_client(struct hash_bucket *bucket, if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_LOCAL)) zebra_evpn_mac_send_add_to_client(wctx->zevpn->vni, - &zmac->macaddr, zmac->flags, - zmac->loc_seq, zmac->es); + &zmac->macaddr, zmac->flags, + zmac->loc_seq, zmac->es); } /* Iterator to Notify Local MACs of a EVPN */ @@ -1840,7 +1910,8 @@ void zebra_evpn_send_mac_list_to_client(struct zebra_evpn *zevpn) memset(&wctx, 0, sizeof(wctx)); wctx.zevpn = zevpn; - hash_iterate(zevpn->mac_table, zebra_evpn_send_mac_hash_entry_to_client, &wctx); + hash_iterate(zevpn->mac_table, zebra_evpn_send_mac_hash_entry_to_client, + &wctx); } void zebra_evpn_rem_mac_del(struct zebra_evpn *zevpn, struct zebra_mac *mac) @@ -1857,7 +1928,7 @@ void zebra_evpn_rem_mac_del(struct zebra_evpn *zevpn, struct zebra_mac *mac) * go away, we need to uninstall the MAC. */ if (remote_neigh_count(mac) == 0) { - zebra_evpn_rem_mac_uninstall(zevpn, mac, false /*force*/); + zebra_evpn_rem_mac_uninstall(zevpn, mac, false); zebra_evpn_es_mac_deref_entry(mac); UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE); } @@ -1917,12 +1988,11 @@ int zebra_evpn_mac_remote_macip_add(struct zebra_evpn *zevpn, mac = zebra_evpn_mac_lookup(zevpn, macaddr); /* Ignore if the mac is already present as a gateway mac */ - if (mac && CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW) - && CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) { + if (mac && CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW) && + CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) { if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "Ignore remote MACIP ADD VNI %u MAC %pEA as MAC is already configured as gateway MAC", - zevpn->vni, macaddr); + zlog_debug("Ignore remote MACIP ADD VNI %u MAC %pEA as MAC is already configured as gateway MAC", + zevpn->vni, macaddr); return -1; } @@ -1932,13 +2002,11 @@ int zebra_evpn_mac_remote_macip_add(struct zebra_evpn *zevpn, * If so, that needs to be updated first. Note that client could * install MAC and MACIP separately or just install the latter. */ - if (!mac - || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) - || sticky != !!CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) - || remote_gw != !!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW) - || !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip) - || memcmp(old_esi, esi, sizeof(esi_t)) - || seq != mac->rem_seq) + if (!mac || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) || + sticky != !!CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) || + remote_gw != !!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW) || + !IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip, &vtep_ip) || + memcmp(old_esi, esi, sizeof(esi_t)) || seq != mac->rem_seq) update_mac = 1; if (update_mac) { @@ -1954,7 +2022,8 @@ int zebra_evpn_mac_remote_macip_add(struct zebra_evpn *zevpn, * the sequence number and ignore this update * if appropriate. */ - if (!zebra_evpn_mac_is_bgp_seq_ok(zevpn, mac, seq, false)) + if (!zebra_evpn_mac_is_bgp_seq_ok(zevpn, mac, seq, + false)) return -1; old_es_present = !!mac->es; @@ -1981,8 +2050,9 @@ int zebra_evpn_mac_remote_macip_add(struct zebra_evpn *zevpn, * MAC is already marked duplicate set dad, then * is_dup_detect will be set to not install the entry. */ - if ((!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) && mac->dad_count) - || CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) + if ((!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) && + mac->dad_count) || + CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) do_dad = true; /* Remove local MAC from BGP. */ @@ -1992,17 +2062,18 @@ int zebra_evpn_mac_remote_macip_add(struct zebra_evpn *zevpn, if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) { char mac_buf[MAC_BUF_SIZE]; - zlog_debug( - "sync-mac->remote vni %u mac %pEA es %s seq %d f %s", - zevpn->vni, macaddr, - mac->es ? mac->es->esi_str : "-", - mac->loc_seq, - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf))); + zlog_debug("sync-mac->remote vni %u mac %pEA es %s seq %d f %s", + zevpn->vni, macaddr, + mac->es ? mac->es->esi_str : "-", + 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, - false /* force */); + zebra_evpn_mac_send_del_to_client(zevpn->vni, macaddr, + mac->flags, false); } /* Set "auto" and "remote" forwarding info. */ @@ -2021,8 +2092,10 @@ int zebra_evpn_mac_remote_macip_add(struct zebra_evpn *zevpn, else UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW); - zebra_evpn_dup_addr_detect_for_mac( - zvrf, mac, mac->fwd_info.r_vtep_ip, do_dad, &is_dup_detect, false); + zebra_evpn_dup_addr_detect_for_mac(zvrf, mac, + mac->fwd_info.r_vtep_ip, + do_dad, &is_dup_detect, + false); if (!is_dup_detect) { zebra_evpn_process_neigh_on_remote_mac_add(zevpn, mac); @@ -2049,7 +2122,7 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, bool inform_client = false; bool upd_neigh = false; bool is_dup_detect = false; - struct in_addr vtep_ip = {.s_addr = 0}; + struct in_addr vtep_ip = { .s_addr = 0 }; bool es_change = false; bool new_bgp_ready; /* assume inactive if not present or if not local */ @@ -2064,11 +2137,10 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, mac = zebra_evpn_mac_lookup(zevpn, macaddr); if (!mac) { if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC) - zlog_debug( - "ADD %sMAC %pEA intf %s(%u) VID %u -> VNI %u%s", - sticky ? "sticky " : "", - macaddr, ifp->name, ifp->ifindex, vid, zevpn->vni, - local_inactive ? " local-inactive" : ""); + zlog_debug("ADD %sMAC %pEA intf %s(%u) VID %u -> VNI %u%s", + sticky ? "sticky " : "", macaddr, ifp->name, + ifp->ifindex, vid, zevpn->vni, + local_inactive ? " local-inactive" : ""); mac = zebra_evpn_mac_add(zevpn, macaddr); SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL); @@ -2080,12 +2152,12 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC) { char mac_buf[MAC_BUF_SIZE]; - zlog_debug( - "UPD %sMAC %pEA intf %s(%u) VID %u -> VNI %u %scurFlags %s", - sticky ? "sticky " : "", - macaddr, ifp->name, ifp->ifindex, vid, zevpn->vni, - local_inactive ? "local-inactive " : "", - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf))); + zlog_debug("UPD %sMAC %pEA intf %s(%u) VID %u -> VNI %u %scurFlags %s", + sticky ? "sticky " : "", macaddr, ifp->name, + ifp->ifindex, vid, zevpn->vni, + local_inactive ? "local-inactive " : "", + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf))); } if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) { @@ -2094,27 +2166,34 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, bool old_static; zebra_evpn_mac_get_access_info(mac, &old_ifp, &old_vid); - old_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags); - old_local_inactive = !!(mac->flags & ZEBRA_MAC_LOCAL_INACTIVE); + old_bgp_ready = + zebra_evpn_mac_is_ready_for_bgp(mac->flags); + old_local_inactive = !!(mac->flags & + ZEBRA_MAC_LOCAL_INACTIVE); old_static = zebra_evpn_mac_is_static(mac); if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) mac_sticky = true; - es_change = zebra_evpn_local_mac_update_fwd_info(mac, ifp, vid); + es_change = zebra_evpn_local_mac_update_fwd_info(mac, + ifp, + vid); /* * Update any changes and if changes are relevant to * BGP, note it. */ - if (mac_sticky == sticky && old_ifp == ifp && old_vid == vid - && old_local_inactive == local_inactive - && dp_static == old_static && !es_change) { + if (mac_sticky == sticky && old_ifp == ifp && + old_vid == vid && + old_local_inactive == local_inactive && + dp_static == old_static && !es_change) { if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - " Add/Update %sMAC %pEA intf %s(%u) VID %u -> VNI %u%s, " - "entry exists and has not changed ", - sticky ? "sticky " : "", - macaddr, ifp->name, ifp->ifindex, vid, zevpn->vni, - local_inactive ? " local_inactive" : ""); + zlog_debug(" Add/Update %sMAC %pEA intf %s(%u) VID %u -> VNI %u%s, " + "entry exists and has not changed ", + sticky ? "sticky " : "", + macaddr, ifp->name, + ifp->ifindex, vid, zevpn->vni, + local_inactive + ? " local_inactive" + : ""); return 0; } if (mac_sticky != sticky) { @@ -2139,9 +2218,11 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, /* force drop the peer/sync info as it is * simply no longer relevant */ - if (CHECK_FLAG(mac->flags, ZEBRA_MAC_ALL_PEER_FLAGS)) { + if (CHECK_FLAG(mac->flags, + ZEBRA_MAC_ALL_PEER_FLAGS)) { zebra_evpn_mac_clear_sync_info(mac); - new_static = zebra_evpn_mac_is_static(mac); + new_static = + zebra_evpn_mac_is_static(mac); /* if we clear peer-flags we * also need to notify the dataplane * to drop the static flag @@ -2150,8 +2231,8 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, inform_dataplane = true; } } - } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) - || CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) { + } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) || + CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) { bool do_dad = false; /* @@ -2161,16 +2242,17 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, * operator error. */ if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) { - flog_warn( - EC_ZEBRA_STICKY_MAC_ALREADY_LEARNT, - "MAC %pEA already learnt as remote sticky MAC behind VTEP %pI4 VNI %u", - macaddr, &mac->fwd_info.r_vtep_ip, zevpn->vni); + flog_warn(EC_ZEBRA_STICKY_MAC_ALREADY_LEARNT, + "MAC %pEA already learnt as remote sticky MAC behind VTEP %pI4 VNI %u", + macaddr, &mac->fwd_info.r_vtep_ip, + zevpn->vni); return 0; } /* If an actual move, compute MAC's seq number */ if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) { - mac->loc_seq = MAX(mac->rem_seq + 1, mac->loc_seq); + mac->loc_seq = MAX(mac->rem_seq + 1, + mac->loc_seq); vtep_ip = mac->fwd_info.r_vtep_ip; /* Trigger DAD for remote MAC */ do_dad = true; @@ -2179,7 +2261,9 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE); UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO); SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL); - es_change = zebra_evpn_local_mac_update_fwd_info(mac, ifp, vid); + es_change = zebra_evpn_local_mac_update_fwd_info(mac, + ifp, + vid); if (sticky) SET_FLAG(mac->flags, ZEBRA_MAC_STICKY); else @@ -2191,8 +2275,9 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, inform_client = true; upd_neigh = true; - zebra_evpn_dup_addr_detect_for_mac( - zvrf, mac, vtep_ip, do_dad, &is_dup_detect, true); + zebra_evpn_dup_addr_detect_for_mac(zvrf, mac, vtep_ip, + do_dad, + &is_dup_detect, true); if (is_dup_detect) { inform_client = false; upd_neigh = false; @@ -2218,17 +2303,17 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, /* if local-activity has changed we need update bgp * even if bgp already knows about the mac */ - if ((old_local_inactive != local_inactive) - || (new_bgp_ready != old_bgp_ready)) { + if ((old_local_inactive != local_inactive) || + (new_bgp_ready != old_bgp_ready)) { if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) { char mac_buf[MAC_BUF_SIZE]; - zlog_debug( - "local mac vni %u mac %pEA es %s seq %d f %s%s", - zevpn->vni, macaddr, - mac->es ? mac->es->esi_str : "", mac->loc_seq, - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf)), - local_inactive ? "local-inactive" : ""); + zlog_debug("local mac vni %u mac %pEA es %s seq %d f %s%s", + zevpn->vni, macaddr, + mac->es ? mac->es->esi_str : "", mac->loc_seq, + zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, + sizeof(mac_buf)), + local_inactive ? "local-inactive" : ""); } if (!is_dup_detect) @@ -2242,16 +2327,17 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, /* Inform dataplane if required. */ if (inform_dataplane) - zebra_evpn_sync_mac_dp_install(mac, false /* set_inactive */, - false /* force_clear_static */, __func__); + zebra_evpn_sync_mac_dp_install(mac, false, false, __func__); /* Inform BGP if required. */ if (inform_client) - zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready, new_bgp_ready); + zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready, + new_bgp_ready); /* Process all neighbors associated with this MAC, if required. */ if (upd_neigh) - zebra_evpn_process_neigh_on_local_mac_change(zevpn, mac, 0, es_change); + zebra_evpn_process_neigh_on_local_mac_change(zevpn, mac, 0, + es_change); return 0; } @@ -2277,24 +2363,25 @@ int zebra_evpn_del_local_mac(struct zebra_evpn *zevpn, struct zebra_mac *mac, if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) { char mac_buf[MAC_BUF_SIZE]; - zlog_debug( - "re-add sync-mac vni %u mac %pEA es %s seq %d f %s", - zevpn->vni, &mac->macaddr, - mac->es ? mac->es->esi_str : "-", mac->loc_seq, - zebra_evpn_zebra_mac_flag_dump(mac, mac_buf, sizeof(mac_buf))); + zlog_debug("re-add sync-mac vni %u mac %pEA es %s seq %d f %s", + zevpn->vni, &mac->macaddr, + mac->es ? mac->es->esi_str : "-", + mac->loc_seq, + 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)) { SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE); - new_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags); - zebra_evpn_mac_send_add_del_to_client( - mac, old_bgp_ready, new_bgp_ready); + new_bgp_ready = + zebra_evpn_mac_is_ready_for_bgp(mac->flags); + zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready, + new_bgp_ready); } /* re-install the inactive entry in the kernel */ - zebra_evpn_sync_mac_dp_install(mac, true /* set_inactive */, - false /* force_clear_static */, __func__); + zebra_evpn_sync_mac_dp_install(mac, true, false, __func__); return 0; } @@ -2307,7 +2394,7 @@ int zebra_evpn_del_local_mac(struct zebra_evpn *zevpn, struct zebra_mac *mac, /* Remove MAC from BGP. */ zebra_evpn_mac_send_del_to_client(zevpn->vni, &mac->macaddr, mac->flags, - clear_static /* force */); + clear_static); zebra_evpn_es_mac_deref_entry(mac); @@ -2329,8 +2416,7 @@ int zebra_evpn_del_local_mac(struct zebra_evpn *zevpn, struct zebra_mac *mac, return 0; } -void zebra_evpn_mac_gw_macip_add(struct interface *ifp, - struct zebra_evpn *zevpn, +void zebra_evpn_mac_gw_macip_add(struct interface *ifp, struct zebra_evpn *zevpn, const struct ipaddr *ip, struct zebra_mac **macp, const struct ethaddr *macaddr, @@ -2376,15 +2462,17 @@ void zebra_evpn_mac_svi_del(struct interface *ifp, struct zebra_evpn *zevpn) memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN); mac = zebra_evpn_mac_lookup(zevpn, &macaddr); - if (mac && CHECK_FLAG(mac->flags, ZEBRA_MAC_SVI)) { - if (IS_ZEBRA_DEBUG_EVPN_MH_ES) - zlog_debug("SVI %s mac free", ifp->name); - - old_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags); - UNSET_FLAG(mac->flags, ZEBRA_MAC_SVI); - zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready, false); - zebra_evpn_deref_ip2mac(mac->zevpn, mac); - } + + if (!mac || CHECK_FLAG(mac->flags, ZEBRA_MAC_SVI)) + return; + + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug("SVI %s mac free", ifp->name); + + old_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags); + UNSET_FLAG(mac->flags, ZEBRA_MAC_SVI); + zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready, false); + zebra_evpn_deref_ip2mac(mac->zevpn, mac); } void zebra_evpn_mac_svi_add(struct interface *ifp, struct zebra_evpn *zevpn) @@ -2395,8 +2483,8 @@ void zebra_evpn_mac_svi_add(struct interface *ifp, struct zebra_evpn *zevpn) bool old_bgp_ready; bool new_bgp_ready; - if (!zebra_evpn_mh_do_adv_svi_mac() - || !zebra_evpn_send_to_client_ok(zevpn)) + if (!zebra_evpn_mh_do_adv_svi_mac() || + !zebra_evpn_send_to_client_ok(zevpn)) return; memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN); @@ -2410,8 +2498,9 @@ void zebra_evpn_mac_svi_add(struct interface *ifp, struct zebra_evpn *zevpn) if (IS_ZEBRA_DEBUG_EVPN_MH_ES) zlog_debug("SVI %s mac add", zif->ifp->name); - old_bgp_ready = - (mac && zebra_evpn_mac_is_ready_for_bgp(mac->flags)) ? true : false; + old_bgp_ready = (mac && zebra_evpn_mac_is_ready_for_bgp(mac->flags)) + ? true + : false; zebra_evpn_mac_gw_macip_add(ifp, zevpn, NULL, &mac, &macaddr, 0, false); diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index 637eabde8d..4ee9dc5fcf 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -1167,7 +1167,8 @@ static void zebra_nhg_handle_install(struct nhg_hash_entry *nhe, bool install) "%s nh id %u (flags 0x%x) associated dependent NHG %pNG install", __func__, nhe->id, nhe->flags, rb_node_dep->nhe); - zebra_nhg_install_kernel(rb_node_dep->nhe, true); + zebra_nhg_install_kernel(rb_node_dep->nhe, + ZEBRA_ROUTE_MAX); } } } |
