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_nht.c b/bgpd/bgp_nht.c
index 21e1411..34b5fd1 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -39,6 +39,7 @@
#include "bgpd/bgp_nexthop.h"
#include "bgpd/bgp_debug.h"
#include "bgpd/bgp_nht.h"
+#include "bgpd/bgp_fsm.h"
extern struct zclient *zclient;
extern struct bgp_table *bgp_nexthop_cache_table[AFI_MAX];
@@ -51,19 +52,15 @@
int keep);
int
-bgp_find_nexthop (struct bgp_info *path, int *changed, int *metricchanged)
+bgp_find_nexthop (struct bgp_info *path, int connected)
{
struct bgp_nexthop_cache *bnc = path->nexthop;
if (!bnc)
return 0;
- if (changed)
- *changed = CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED);
-
- if (metricchanged)
- *metricchanged = CHECK_FLAG(bnc->change_flags,
- BGP_NEXTHOP_METRIC_CHANGED);
+ if (connected && !(CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)))
+ return 0;
return (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID));
}
@@ -78,7 +75,7 @@
path_nh_map(path, NULL, 0);
- if (LIST_EMPTY(&(bnc->paths)))
+ if (LIST_EMPTY(&(bnc->paths)) && !bnc->nht_info)
{
if (BGP_DEBUG(nht, NHT))
{
@@ -94,15 +91,34 @@
}
int
-bgp_find_or_add_nexthop (afi_t afi, struct bgp_info *ri, int *changed,
- int *metricchanged)
+bgp_find_or_add_nexthop (afi_t afi, struct bgp_info *ri, struct peer *peer,
+ int connected)
{
struct bgp_node *rn;
struct bgp_nexthop_cache *bnc;
struct prefix p;
- if (make_prefix(afi, ri, &p) < 0)
- return 1;
+ if (ri)
+ {
+ if (make_prefix(afi, ri, &p) < 0)
+ return 1;
+ }
+ else if (peer)
+ {
+ if (afi == AFI_IP)
+ {
+ p.family = AF_INET;
+ p.prefixlen = IPV4_MAX_BITLEN;
+ p.u.prefix4 = peer->su.sin.sin_addr;
+ }
+ else if (afi == AFI_IP6)
+ {
+ p.family = AF_INET6;
+ p.prefixlen = IPV6_MAX_BITLEN;
+ p.u.prefix6 = peer->su.sin6.sin6_addr;
+ }
+ }
+
rn = bgp_node_get (bgp_nexthop_cache_table[afi], &p);
if (!rn->info)
@@ -111,23 +127,27 @@
rn->info = bnc;
bnc->node = rn;
bgp_lock_node(rn);
- register_nexthop(bnc);
+ if (connected)
+ SET_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED);
}
+
bnc = rn->info;
bgp_unlock_node (rn);
- path_nh_map(ri, bnc, 1);
- if (changed)
- *changed = CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED);
+ if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
+ register_nexthop(bnc);
- if (metricchanged)
- *metricchanged = CHECK_FLAG(bnc->change_flags,
- BGP_NEXTHOP_METRIC_CHANGED);
+ if (ri)
+ {
+ path_nh_map(ri, bnc, 1);
- if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID) && bnc->metric)
- (bgp_info_extra_get(ri))->igpmetric = bnc->metric;
- else if (ri->extra)
- ri->extra->igpmetric = 0;
+ if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID) && bnc->metric)
+ (bgp_info_extra_get(ri))->igpmetric = bnc->metric;
+ else if (ri->extra)
+ ri->extra->igpmetric = 0;
+ }
+ else if (peer)
+ bnc->nht_info = (void *)peer;
return (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID));
}
@@ -269,6 +289,7 @@
else
{
bnc->flags &= ~BGP_NEXTHOP_VALID;
+ UNSET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED);
bnc_nexthop_free(bnc);
bnc->nexthop = NULL;
}
@@ -326,12 +347,21 @@
/* Check socket. */
if (!zclient || zclient->sock < 0)
- return;
+ {
+ zlog_debug("%s: Can't send NH register, Zebra client not established",
+ __FUNCTION__);
+ return;
+ }
p = &(bnc->node->p);
s = zclient->obuf;
stream_reset (s);
zclient_create_header (s, command, VRF_DEFAULT);
+ if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED))
+ stream_putc(s, 1);
+ else
+ stream_putc(s, 0);
+
stream_putw(s, PREFIX_FAMILY(p));
stream_putc(s, p->prefixlen);
switch (PREFIX_FAMILY(p))
@@ -339,11 +369,9 @@
case AF_INET:
stream_put_in_addr (s, &p->u.prefix4);
break;
-#ifdef HAVE_IPV6
case AF_INET6:
stream_put(s, &(p->u.prefix6), 16);
break;
-#endif
default:
break;
}
@@ -353,6 +381,11 @@
/* TBD: handle the failure */
if (ret < 0)
zlog_warn("sendmsg_nexthop: zclient_send_message() failed");
+
+ if (command == ZEBRA_NEXTHOP_REGISTER)
+ SET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
+ else if (command == ZEBRA_NEXTHOP_UNREGISTER)
+ UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
return;
}
@@ -371,7 +404,6 @@
if (bnc->flags & BGP_NEXTHOP_REGISTERED)
return;
sendmsg_nexthop(bnc, ZEBRA_NEXTHOP_REGISTER);
- SET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
}
/**
@@ -389,7 +421,6 @@
return;
sendmsg_nexthop(bnc, ZEBRA_NEXTHOP_UNREGISTER);
- UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
}
/**
@@ -406,6 +437,7 @@
struct bgp_info *path;
struct bgp *bgp = bgp_get_default();
int afi;
+ struct peer *peer = (struct peer *)bnc->nht_info;
LIST_FOREACH(path, &(bnc->paths), nh_thread)
{
@@ -448,6 +480,15 @@
bgp_process(bgp, rn, afi, SAFI_UNICAST);
}
+
+ if (peer && !CHECK_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED))
+ {
+ if (BGP_DEBUG(nht, NHT))
+ zlog_debug("%s: Updating peer (%s) status with NHT", __FUNCTION__, peer->host);
+ bgp_fsm_nht_update(peer, CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID));
+ SET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED);
+ }
+
RESET_FLAG(bnc->change_flags);
}