diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2015-05-20 02:47:21 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2015-05-20 02:47:21 +0200 |
commit | fc9a856f7051b9e5ffd1cf0938ca2be20388a95f (patch) | |
tree | b7e776b34f27c8476feca6b5e90348b2db1f1b5f /bgpd/bgp_route.c | |
parent | zebra: zebra-nht-routemap.patch (diff) | |
download | frr-fc9a856f7051b9e5ffd1cf0938ca2be20388a95f.tar.xz frr-fc9a856f7051b9e5ffd1cf0938ca2be20388a95f.zip |
bgpd-nht-connected-route.patch
BGP: Use next hop tracking for connected routes too
And cleanup obsolete code in bgp_scan and bgp_import.
Diffstat (limited to 'bgpd/bgp_route.c')
-rw-r--r-- | bgpd/bgp_route.c | 163 |
1 files changed, 119 insertions, 44 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index d45ffd0e1..4638d7512 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -55,7 +55,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include "bgpd/bgp_zebra.h" #include "bgpd/bgp_vty.h" #include "bgpd/bgp_mpath.h" -#include "bgpd/bgp_nht.c" +#include "bgpd/bgp_nht.h" /* Extern from bgp_dump.c */ extern const char *bgp_origin_str[]; @@ -1064,7 +1064,7 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p, IN6_IS_ADDR_UNSPECIFIED(&attr->extra->mp_nexthop_global)) #endif /* HAVE_IPV6 */ || (peer->sort == BGP_PEER_EBGP - && bgp_multiaccess_check_v4 (attr->nexthop, peer->host) == 0)) + && (bgp_multiaccess_check_v4 (attr->nexthop, peer) == 0))) { /* Set IPv4 nexthop. */ if (p->family == AF_INET) @@ -2229,6 +2229,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr, struct bgp_info *new; const char *reason; char buf[SU_ADDRSTRLEN]; + int connected = 0; bgp = peer->bgp; rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd); @@ -2306,17 +2307,6 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr, /* IPv4 unicast next hop check. */ if (afi == AFI_IP && safi == SAFI_UNICAST) { - /* If the peer is EBGP and nexthop is not on connected route, - discard it. */ - if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1 - && ! bgp_nexthop_onlink (afi, &new_attr) - && ! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)) - { - reason = "non-connected next-hop;"; - bgp_attr_flush (&new_attr); - goto filtered; - } - /* Next hop must not be 0.0.0.0 nor Class D/E address. Next hop must not be my own address. */ if (new_attr.nexthop.s_addr == 0 @@ -2443,20 +2433,29 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr, } /* Nexthop reachability check. */ - if ((afi == AFI_IP || afi == AFI_IP6) - && safi == SAFI_UNICAST - && (peer->sort == BGP_PEER_IBGP - || peer->sort == BGP_PEER_CONFED - || (peer->sort == BGP_PEER_EBGP && peer->ttl != 1) - || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))) + if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST) { - if (bgp_find_or_add_nexthop (afi, ri, NULL, NULL)) + if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1 && + ! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)) + connected = 1; + else + connected = 0; + + if (bgp_find_or_add_nexthop (afi, ri, NULL, connected)) bgp_info_set_flag (rn, ri, BGP_INFO_VALID); else - bgp_info_unset_flag (rn, ri, BGP_INFO_VALID); + { + if (BGP_DEBUG(nht, NHT)) + { + char buf1[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET, (const void *)&attr_new->nexthop, buf1, INET6_ADDRSTRLEN); + zlog_debug("%s(%s): NH unresolved", __FUNCTION__, buf1); + } + bgp_info_unset_flag (rn, ri, BGP_INFO_VALID); + } } else - bgp_info_set_flag (rn, ri, BGP_INFO_VALID); + bgp_info_set_flag (rn, ri, BGP_INFO_VALID); /* Process change. */ bgp_aggregate_increment (bgp, p, ri, afi, safi); @@ -2484,17 +2483,26 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr, memcpy ((bgp_info_extra_get (new))->tag, tag, 3); /* Nexthop reachability check. */ - if ((afi == AFI_IP || afi == AFI_IP6) - && safi == SAFI_UNICAST - && (peer->sort == BGP_PEER_IBGP - || peer->sort == BGP_PEER_CONFED - || (peer->sort == BGP_PEER_EBGP && peer->ttl != 1) - || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))) - { - if (bgp_find_or_add_nexthop (afi, new, NULL, NULL)) + if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST) + { + if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1 && + ! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)) + connected = 1; + else + connected = 0; + + if (bgp_find_or_add_nexthop (afi, new, NULL, connected)) bgp_info_set_flag (rn, new, BGP_INFO_VALID); else - bgp_info_unset_flag (rn, new, BGP_INFO_VALID); + { + if (BGP_DEBUG(nht, NHT)) + { + char buf1[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET, (const void *)&attr_new->nexthop, buf1, INET6_ADDRSTRLEN); + zlog_debug("%s(%s): NH unresolved", __FUNCTION__, buf1); + } + bgp_info_unset_flag (rn, new, BGP_INFO_VALID); + } } else bgp_info_set_flag (rn, new, BGP_INFO_VALID); @@ -3558,6 +3566,23 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p, ri->attr = attr_new; ri->uptime = bgp_clock (); + /* Nexthop reachability check. */ + if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK)) + { + if (bgp_find_or_add_nexthop (afi, ri, NULL, 0)) + bgp_info_set_flag (rn, ri, BGP_INFO_VALID); + else + { + if (BGP_DEBUG(nht, NHT)) + { + char buf1[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET, (const void *)&attr_new->nexthop, + buf1, INET6_ADDRSTRLEN); + zlog_debug("%s(%s): NH unresolved", __FUNCTION__, buf1); + } + bgp_info_unset_flag (rn, ri, BGP_INFO_VALID); + } + } /* Process change. */ bgp_process (bgp, rn, afi, safi); bgp_unlock_node (rn); @@ -3570,7 +3595,25 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p, /* Make new BGP info. */ new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, bgp->peer_self, attr_new, rn); - SET_FLAG (new->flags, BGP_INFO_VALID); + /* Nexthop reachability check. */ + if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK)) + { + if (bgp_find_or_add_nexthop (afi, new, NULL, 0)) + bgp_info_set_flag (rn, new, BGP_INFO_VALID); + else + { + if (BGP_DEBUG(nht, NHT)) + { + char buf1[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET, (const void *)&attr_new->nexthop, + buf1, INET6_ADDRSTRLEN); + zlog_debug("%s(%s): NH unresolved", __FUNCTION__, buf1); + } + bgp_info_unset_flag (rn, new, BGP_INFO_VALID); + } + } + else + bgp_info_set_flag (rn, new, BGP_INFO_VALID); /* Register new BGP information. */ bgp_info_add (rn, new); @@ -3588,7 +3631,7 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p, static void bgp_static_update_main (struct bgp *bgp, struct prefix *p, - struct bgp_static *bgp_static, afi_t afi, safi_t safi) + struct bgp_static *bgp_static, afi_t afi, safi_t safi) { struct bgp_node *rn; struct bgp_info *ri; @@ -3672,6 +3715,23 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p, ri->attr = attr_new; ri->uptime = bgp_clock (); + /* Nexthop reachability check. */ + if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK)) + { + if (bgp_find_or_add_nexthop (afi, ri, NULL, 0)) + bgp_info_set_flag (rn, ri, BGP_INFO_VALID); + else + { + if (BGP_DEBUG(nht, NHT)) + { + char buf1[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET, (const void *)&attr_new->nexthop, + buf1, INET6_ADDRSTRLEN); + zlog_debug("%s(%s): NH unresolved", __FUNCTION__, buf1); + } + bgp_info_unset_flag (rn, ri, BGP_INFO_VALID); + } + } /* Process change. */ bgp_aggregate_increment (bgp, p, ri, afi, safi); bgp_process (bgp, rn, afi, safi); @@ -3685,7 +3745,25 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p, /* Make new BGP info. */ new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, bgp->peer_self, attr_new, rn); - SET_FLAG (new->flags, BGP_INFO_VALID); + /* Nexthop reachability check. */ + if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK)) + { + if (bgp_find_or_add_nexthop (afi, new, NULL, 0)) + bgp_info_set_flag (rn, new, BGP_INFO_VALID); + else + { + if (BGP_DEBUG(nht, NHT)) + { + char buf1[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET, (const void *)&attr_new->nexthop, buf1, + INET6_ADDRSTRLEN); + zlog_debug("%s(%s): NH unresolved", __FUNCTION__, buf1); + } + bgp_info_unset_flag (rn, new, BGP_INFO_VALID); + } + } + else + bgp_info_set_flag (rn, new, BGP_INFO_VALID); /* Aggregate address increment. */ bgp_aggregate_increment (bgp, p, new, afi, safi); @@ -3770,6 +3848,7 @@ bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi, if (ri) { bgp_aggregate_decrement (bgp, p, ri, afi, safi); + bgp_unlink_nexthop(ri); bgp_info_delete (rn, ri); bgp_process (bgp, rn, afi, safi); } @@ -3906,17 +3985,12 @@ bgp_static_set (struct vty *vty, struct bgp *bgp, const char *ip_str, rn->info = bgp_static; } - /* If BGP scan is not enabled, we should install this route here. */ - if (! bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK)) - { - bgp_static->valid = 1; - - if (need_update) - bgp_static_withdraw (bgp, &p, afi, safi); + bgp_static->valid = 1; + if (need_update) + bgp_static_withdraw (bgp, &p, afi, safi); - if (! bgp_static->backdoor) - bgp_static_update (bgp, &p, bgp_static, afi, safi); - } + if (! bgp_static->backdoor) + bgp_static_update (bgp, &p, bgp_static, afi, safi); return CMD_SUCCESS; } @@ -3964,6 +4038,7 @@ bgp_static_unset (struct vty *vty, struct bgp *bgp, const char *ip_str, bgp_static_withdraw (bgp, &p, afi, safi); /* Clear configuration. */ + bgp_unlink_nexthop(bgp_static); bgp_static_free (bgp_static); rn->info = NULL; bgp_unlock_node (rn); |