bgpd, zebra: Use next hop tracking for connected routes too
Allow next hop tracking to work with connected routes
And cleanup obsolete code in bgp_scan and bgp_import.
Signed-off-by: Dinesh Dutt <ddutt@cumulusnetworks.com>
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Edits: Paul Jakma <paul.jakma@hpe.com> Rebase re-ordering conflicts with
NHT route-map, potential errors.
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 066637b..a88a022 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -55,7 +55,7 @@
#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[];
@@ -998,7 +998,7 @@
|| (NEXTHOP_IS_V6 &&
IN6_IS_ADDR_UNSPECIFIED(&attr->extra->mp_nexthop_global))
|| (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 (NEXTHOP_IS_V4)
@@ -2129,6 +2129,7 @@
struct bgp_info *new;
const char *reason;
char buf[SU_ADDRSTRLEN];
+ int connected = 0;
memset (&new_attr, 0, sizeof(struct attr));
memset (&new_extra, 0, sizeof(struct attr_extra));
@@ -2209,17 +2210,6 @@
/* 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
@@ -2347,20 +2337,29 @@
}
/* 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);
bgp_attr_flush (&new_attr);
@@ -2390,17 +2389,26 @@
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 ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST)
{
- if (bgp_find_or_add_nexthop (afi, new, 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, 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);
@@ -3532,6 +3540,23 @@
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);
@@ -3544,7 +3569,25 @@
/* 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);
@@ -3562,7 +3605,7 @@
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;
@@ -3646,6 +3689,23 @@
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);
@@ -3659,7 +3719,25 @@
/* 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);
@@ -3720,6 +3798,7 @@
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);
}
@@ -3978,17 +4057,12 @@
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;
+ bgp_static->valid = 1;
+ if (need_update)
+ bgp_static_withdraw (bgp, &p, afi, safi);
- 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;
}