diff options
| -rw-r--r-- | bgpd/bgp_packet.c | 4 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 265 | ||||
| -rw-r--r-- | bgpd/bgpd.h | 11 | ||||
| -rw-r--r-- | ospfd/ospfd.c | 2 |
4 files changed, 121 insertions, 161 deletions
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 0523a4b02b..a76a300c11 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -2314,7 +2314,7 @@ static int bgp_update_receive(struct peer_connection *connection, attr.label = MPLS_INVALID_LABEL; memset(&nlris, 0, sizeof(nlris)); memset(peer->rcvd_attr_str, 0, BUFSIZ); - peer->rcvd_attr_printed = 0; + peer->rcvd_attr_printed = false; s = peer->curr; end = stream_pnt(s) + size; @@ -2422,7 +2422,7 @@ static int bgp_update_receive(struct peer_connection *connection, BGP_DEBUG(update, UPDATE_DETAIL)) { zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer, peer->rcvd_attr_str); - peer->rcvd_attr_printed = 1; + peer->rcvd_attr_printed = true; } } diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index baeb96a9c8..7a87739479 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -4623,6 +4623,60 @@ static bool bgp_accept_own(struct peer *peer, afi_t afi, safi_t safi, return false; } +static inline void +bgp_update_nexthop_reachability_check(struct bgp *bgp, struct peer *peer, struct bgp_dest *dest, + const struct prefix *p, afi_t afi, safi_t safi, + struct bgp_path_info *pi, struct attr *attr_new, + const struct prefix *bgp_nht_param_prefix, bool accept_own) +{ + bool connected; + afi_t nh_afi; + + if (((afi == AFI_IP || afi == AFI_IP6) && + (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST || + (safi == SAFI_MPLS_VPN && pi->sub_type != BGP_ROUTE_IMPORTED))) || + (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) { + if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP && + peer->ttl == BGP_DEFAULT_TTL && + !CHECK_FLAG(peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK) && + !CHECK_FLAG(bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK)) + connected = true; + else + connected = false; + + struct bgp *bgp_nexthop = bgp; + + if (pi->extra && pi->extra->vrfleak && pi->extra->vrfleak->bgp_orig) + bgp_nexthop = pi->extra->vrfleak->bgp_orig; + + nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr); + + if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi, safi, pi, NULL, connected, + bgp_nht_param_prefix) || + CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) { + if (accept_own) + bgp_path_info_set_flag(dest, pi, BGP_PATH_ACCEPT_OWN); + + bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID); + } else { + if (BGP_DEBUG(nht, NHT)) { + zlog_debug("%s(%pI4): NH unresolved for existing %pFX pi %p flags 0x%x", + __func__, (in_addr_t *)&attr_new->nexthop, p, pi, + pi->flags); + } + bgp_path_info_unset_flag(dest, pi, BGP_PATH_VALID); + } + } else { + /* case mpls-vpn routes with accept-own community + * (which have the BGP_ROUTE_IMPORTED subtype) + * case other afi/safi not supporting nexthop tracking + */ + if (accept_own) + bgp_path_info_set_flag(dest, pi, BGP_PATH_ACCEPT_OWN); + bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID); + } +} + void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, struct attr *attr, afi_t afi, safi_t safi, int type, int sub_type, struct prefix_rd *prd, mpls_label_t *label, @@ -4630,7 +4684,6 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, struct bgp_route_evpn *evpn) { int ret; - int aspath_loop_count = 0; struct bgp_dest *dest; struct bgp *bgp; struct attr new_attr = {}; @@ -4639,12 +4692,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, struct bgp_path_info *new = NULL; const char *reason; char pfx_buf[BGP_PRD_PATH_STRLEN]; - int connected = 0; - int do_loop_check = 1; - afi_t nh_afi; bool force_evpn_import = false; safi_t orig_safi = safi; - int allowas_in = 0; struct bgp_labels bgp_labels = {}; uint8_t i; @@ -4669,11 +4718,12 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bgp = peer->bgp; dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd); - if ((afi == AFI_L2VPN && safi == SAFI_EVPN) || - bgp_is_valid_label(&label[0])) + if (num_labels && + ((afi == AFI_L2VPN && safi == SAFI_EVPN) || bgp_is_valid_label(&label[0]))) { bgp_labels.num_labels = num_labels; - for (i = 0; i < bgp_labels.num_labels; i++) - bgp_labels.label[i] = label[i]; + for (i = 0; i < bgp_labels.num_labels; i++) + bgp_labels.label[i] = label[i]; + } /* When peer's soft reconfiguration enabled. Record input packet in Adj-RIBs-In. */ @@ -4695,10 +4745,6 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bgp_adj_in_set(dest, peer, attr, addpath_id, &bgp_labels); } - /* Update permitted loop count */ - if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN)) - allowas_in = peer->allowas_in[afi][safi]; - /* Check previously received route. */ for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) if (pi->peer == peer && pi->type == type @@ -4708,8 +4754,11 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, /* AS path local-as loop check. */ if (peer->change_local_as) { - if (allowas_in) - aspath_loop_count = allowas_in; + int32_t aspath_loop_count = 0; + + /* Update permitted loop count */ + if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN)) + aspath_loop_count = peer->allowas_in[afi][safi]; else if (!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND)) aspath_loop_count = 1; @@ -4722,14 +4771,6 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, } } - /* If the peer is configured for "allowas-in origin" and the last ASN in - * the - * as-path is our ASN then we do not need to call aspath_loop_check - */ - if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN)) - if (aspath_get_last_as(attr->aspath) == bgp->as) - do_loop_check = 0; - /* When using bgp ipv4 labeled session, the local prefix is * received by a peer, and finds out that the proposed prefix * and its next-hop are the same. To avoid a route loop locally, @@ -4750,24 +4791,30 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, else bgp_nht_param_prefix = p; - /* AS path loop check. */ - if (do_loop_check) { + /* + * If the peer is configured for "allowas-in origin" and the last ASN in + * the as-path is our ASN then we do not need to call aspath_loop_check + */ + if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN) || + (aspath_get_last_as(attr->aspath) != bgp->as)) { + /* AS path loop check. */ if (aspath_loop_check(attr->aspath, bgp->as) > peer->allowas_in[afi][safi]) { peer->stat_pfx_aspath_loop++; reason = "as-path contains our own AS;"; goto filtered; } - } - /* If we're a CONFED we need to loop check the CONFED ID too */ - if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) && do_loop_check) - if (aspath_loop_check_confed(attr->aspath, bgp->confed_id) > - peer->allowas_in[afi][safi]) { - peer->stat_pfx_aspath_loop++; - reason = "as-path contains our own confed AS;"; - goto filtered; + /* If we're a CONFED we need to loop check the CONFED ID too */ + if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) { + if (aspath_loop_check_confed(attr->aspath, bgp->confed_id) > + peer->allowas_in[afi][safi]) { + peer->stat_pfx_aspath_loop++; + reason = "as-path contains our own confed AS;"; + goto filtered; + } } + } /* Route reflector originator ID check. If ACCEPT_OWN mechanism is * enabled, then take care of that too. @@ -4792,6 +4839,28 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, goto filtered; } + /* RFC 8212 to prevent route leaks. + * This specification intends to improve this situation by requiring the + * explicit configuration of both BGP Import and Export Policies for any + * External BGP (EBGP) session such as customers, peers, or + * confederation boundaries for all enabled address families. Through + * codification of the aforementioned requirement, operators will + * benefit from consistent behavior across different BGP + * implementations. + */ + if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY)) + if (!bgp_inbound_policy_exists(peer, &peer->filter[afi][safi])) { + reason = "inbound policy missing"; + if (monotime_since(&bgp->ebgprequirespolicywarning, NULL) > + FIFTEENMINUTE2USEC || + bgp->ebgprequirespolicywarning.tv_sec == 0) { + zlog_warn( + "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly"); + monotime(&bgp->ebgprequirespolicywarning); + } + goto filtered; + } + /* Apply incoming filter. */ if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) { peer->stat_pfx_filter++; @@ -4824,29 +4893,6 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, } } - /* RFC 8212 to prevent route leaks. - * This specification intends to improve this situation by requiring the - * explicit configuration of both BGP Import and Export Policies for any - * External BGP (EBGP) session such as customers, peers, or - * confederation boundaries for all enabled address families. Through - * codification of the aforementioned requirement, operators will - * benefit from consistent behavior across different BGP - * implementations. - */ - if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY)) - if (!bgp_inbound_policy_exists(peer, - &peer->filter[afi][safi])) { - reason = "inbound policy missing"; - if (monotime_since(&bgp->ebgprequirespolicywarning, - NULL) > FIFTEENMINUTE2USEC || - bgp->ebgprequirespolicywarning.tv_sec == 0) { - zlog_warn( - "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly"); - monotime(&bgp->ebgprequirespolicywarning); - } - goto filtered; - } - /* draft-ietf-idr-deprecate-as-set-confed-set * Filter routes having AS_SET or AS_CONFED_SET in the path. * Eventually, This document (if approved) updates RFC 4271 @@ -4937,7 +4983,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, goto filtered; } - if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) { + if (safi == SAFI_EVPN && (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac))) { peer->stat_pfx_nh_invalid++; reason = "self mac;"; bgp_attr_flush(&new_attr); @@ -5016,7 +5062,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, "%pBP rcvd UPDATE w/ attr: %s", peer, peer->rcvd_attr_str); - peer->rcvd_attr_printed = 1; + peer->rcvd_attr_printed = true; } bgp_debug_rdpfxpath2str( @@ -5209,62 +5255,11 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, } } + bgp_update_nexthop_reachability_check(bgp, peer, dest, p, afi, safi, pi, attr_new, + bgp_nht_param_prefix, accept_own); /* Nexthop reachability check - for unicast and * labeled-unicast.. */ - if (((afi == AFI_IP || afi == AFI_IP6) && - (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST || - (safi == SAFI_MPLS_VPN && - pi->sub_type != BGP_ROUTE_IMPORTED))) || - (safi == SAFI_EVPN && - bgp_evpn_is_prefix_nht_supported(p))) { - if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP - && peer->ttl == BGP_DEFAULT_TTL - && !CHECK_FLAG(peer->flags, - PEER_FLAG_DISABLE_CONNECTED_CHECK) - && !CHECK_FLAG(bgp->flags, - BGP_FLAG_DISABLE_NH_CONNECTED_CHK)) - connected = 1; - else - connected = 0; - struct bgp *bgp_nexthop = bgp; - - if (pi->extra && pi->extra->vrfleak && - pi->extra->vrfleak->bgp_orig) - bgp_nexthop = pi->extra->vrfleak->bgp_orig; - - nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr); - - if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi, - safi, pi, NULL, connected, - bgp_nht_param_prefix) || - CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) { - if (accept_own) - bgp_path_info_set_flag( - dest, pi, BGP_PATH_ACCEPT_OWN); - - bgp_path_info_set_flag(dest, pi, - BGP_PATH_VALID); - } else { - if (BGP_DEBUG(nht, NHT)) { - zlog_debug("%s(%pI4): NH unresolved for existing %pFX pi %p flags 0x%x", - __func__, - (in_addr_t *)&attr_new->nexthop, - p, pi, pi->flags); - } - bgp_path_info_unset_flag(dest, pi, - BGP_PATH_VALID); - } - } else { - /* case mpls-vpn routes with accept-own community - * (which have the BGP_ROUTE_IMPORTED subtype) - * case other afi/safi not supporting nexthop tracking - */ - if (accept_own) - bgp_path_info_set_flag(dest, pi, - BGP_PATH_ACCEPT_OWN); - bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID); - } #ifdef ENABLE_BGP_VNC if (safi == SAFI_MPLS_VPN) { @@ -5350,7 +5345,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (!peer->rcvd_attr_printed) { zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer, peer->rcvd_attr_str); - peer->rcvd_attr_printed = 1; + peer->rcvd_attr_printed = true; } bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, @@ -5366,48 +5361,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bgp_path_info_extra_get(new); new->extra->labels = bgp_labels_intern(&bgp_labels); - /* Nexthop reachability check. */ - if (((afi == AFI_IP || afi == AFI_IP6) && - (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST || - (safi == SAFI_MPLS_VPN && - new->sub_type != BGP_ROUTE_IMPORTED))) || - (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) { - if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP - && peer->ttl == BGP_DEFAULT_TTL - && !CHECK_FLAG(peer->flags, - PEER_FLAG_DISABLE_CONNECTED_CHECK) - && !CHECK_FLAG(bgp->flags, - BGP_FLAG_DISABLE_NH_CONNECTED_CHK)) - connected = 1; - else - connected = 0; - - nh_afi = BGP_ATTR_NH_AFI(afi, new->attr); - - if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL, - connected, bgp_nht_param_prefix) || - CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) { - if (accept_own) - bgp_path_info_set_flag(dest, new, - BGP_PATH_ACCEPT_OWN); - - bgp_path_info_set_flag(dest, new, BGP_PATH_VALID); - } else { - if (BGP_DEBUG(nht, NHT)) - zlog_debug("%s(%pI4): NH unresolved", __func__, - &attr_new->nexthop); - bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID); - } - } else { - /* case mpls-vpn routes with accept-own community - * (which have the BGP_ROUTE_IMPORTED subtype) - * case other afi/safi not supporting nexthop tracking - */ - if (accept_own) - bgp_path_info_set_flag(dest, new, BGP_PATH_ACCEPT_OWN); - bgp_path_info_set_flag(dest, new, BGP_PATH_VALID); - } - + bgp_update_nexthop_reachability_check(bgp, peer, dest, p, afi, safi, new, attr_new, + bgp_nht_param_prefix, accept_own); /* If maximum prefix count is configured and current prefix * count exeed it. */ @@ -5494,7 +5449,7 @@ filtered: if (!peer->rcvd_attr_printed) { zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer, peer->rcvd_attr_str); - peer->rcvd_attr_printed = 1; + peer->rcvd_attr_printed = true; } bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index f37a722f0c..f7f74c670f 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1769,8 +1769,15 @@ struct peer { /* Text description of last attribute rcvd */ char rcvd_attr_str[BUFSIZ]; - /* Track if we printed the attribute in debugs */ - int rcvd_attr_printed; + /* + * Track if we printed the attribute in debugs + * + * These two rcvd_attr_str and rcvd_attr_printed are going to + * be fun in the long term when we want to break up parsing + * of data from the nlri in multiple pthreads or really + * if we ever change order of things this will just break + */ + bool rcvd_attr_printed; /* Accepted prefix count */ uint32_t pcount[AFI_MAX][SAFI_MAX]; diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 9d7870d2f7..7638e979a2 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -1730,8 +1730,6 @@ int ospf_area_nssa_unset(struct ospf *ospf, struct in_addr area_id) area->no_summary = 0; area->suppress_fa = 0; area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE; - if (area->NSSATranslatorState == OSPF_NSSA_TRANSLATE_ENABLED) - ospf_asbr_status_update(ospf, --ospf->redistribute); area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED; area->NSSATranslatorStabilityInterval = OSPF_NSSA_TRANS_STABLE_DEFAULT; ospf_area_type_set(area, OSPF_AREA_DEFAULT); |
