bgpd-nht-connected-route.patch

BGP: Use next hop tracking for connected routes too

And cleanup obsolete code in bgp_scan and bgp_import.
This commit is contained in:
Donald Sharp 2015-05-19 17:47:21 -07:00
parent 9f0ea7d4f2
commit fc9a856f70
14 changed files with 339 additions and 1168 deletions

View File

@ -1185,6 +1185,7 @@ int
bgp_start (struct peer *peer)
{
int status;
int connected = 0;
bgp_peer_conf_if_to_su_update(peer);
@ -1225,6 +1226,12 @@ bgp_start (struct peer *peer)
return 0;
}
/* Register to be notified on peer up */
if ((peer->ttl == 1) || (peer->gtsm_hops == 1))
connected = 1;
bgp_find_or_add_nexthop(family2afi(peer->su.sa.sa_family), NULL, peer,
connected);
status = bgp_connect (peer);
switch (status)
@ -1492,6 +1499,45 @@ bgp_ignore (struct peer *peer)
return 0;
}
void
bgp_fsm_nht_update(struct peer *peer, int valid)
{
int ret = 0;
if (!peer)
return;
switch (peer->status)
{
case Idle:
if (valid)
BGP_EVENT_ADD(peer, BGP_Start);
break;
case Connect:
ret = bgp_connect_check(peer, 0);
if (!ret && valid)
{
BGP_TIMER_OFF(peer->t_connect);
BGP_EVENT_ADD(peer, ConnectRetry_timer_expired);
}
break;
case Active:
if (valid)
{
BGP_TIMER_OFF(peer->t_connect);
BGP_EVENT_ADD(peer, ConnectRetry_timer_expired);
}
case OpenSent:
case OpenConfirm:
case Established:
case Clearing:
case Deleted:
default:
break;
}
}
/* Finite State Machine structure */
static const struct {
int (*func) (struct peer *);

View File

@ -74,6 +74,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#define BGP_MSEC_JITTER 10
/* Prototypes. */
extern void bgp_fsm_nht_update(struct peer *, int valid);
extern int bgp_event (struct thread *);
extern int bgp_event_update (struct peer *, int event);
extern int bgp_stop (struct peer *peer);

View File

@ -227,7 +227,6 @@ bgp_exit (int status)
int *socket;
struct interface *ifp;
extern struct zclient *zclient;
extern struct zclient *zlookup;
/* it only makes sense for this to be called on a clean exit */
assert (status == 0);
@ -266,9 +265,6 @@ bgp_exit (int status)
/* cleanup route maps */
bgp_route_map_terminate();
/* reverse bgp_scan_init */
bgp_scan_finish ();
/* reverse access_list_init */
access_list_add_hook (NULL);
access_list_delete_hook (NULL);
@ -291,13 +287,14 @@ bgp_exit (int status)
vty_terminate ();
if (zclient)
zclient_free (zclient);
if (zlookup)
zclient_free (zlookup);
if (bgp_nexthop_buf)
stream_free (bgp_nexthop_buf);
if (bgp_ifindices_buf)
stream_free (bgp_ifindices_buf);
/* reverse bgp_scan_init */
bgp_scan_finish ();
/* reverse bgp_master_init */
if (master)
thread_master_free (master);

File diff suppressed because it is too large Load Diff

View File

@ -25,21 +25,9 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "queue.h"
#include "prefix.h"
#define BGP_SCAN_INTERVAL_DEFAULT 60
#define BGP_IMPORT_INTERVAL_DEFAULT 15
/* BGP nexthop cache value structure. */
struct bgp_nexthop_cache
{
/* This nexthop exists in IGP. */
u_char valid;
/* Nexthop is changed. */
u_char changed;
/* Nexthop is changed. */
u_char metricchanged;
/* IGP route's metric. */
u_int32_t metric;
@ -49,26 +37,28 @@ struct bgp_nexthop_cache
time_t last_update;
u_int16_t flags;
#define BGP_NEXTHOP_VALID (1 << 0)
#define BGP_NEXTHOP_REGISTERED (1 << 1)
#define BGP_NEXTHOP_VALID (1 << 0)
#define BGP_NEXTHOP_REGISTERED (1 << 1)
#define BGP_NEXTHOP_CONNECTED (1 << 2)
#define BGP_NEXTHOP_PEER_NOTIFIED (1 << 3)
u_int16_t change_flags;
#define BGP_NEXTHOP_CHANGED (1 << 0)
#define BGP_NEXTHOP_METRIC_CHANGED (1 << 1)
#define BGP_NEXTHOP_CHANGED (1 << 0)
#define BGP_NEXTHOP_METRIC_CHANGED (1 << 1)
#define BGP_NEXTHOP_CONNECTED_CHANGED (1 << 2)
struct bgp_node *node;
void *nht_info; /* In BGP, peer session */
LIST_HEAD(path_list, bgp_info) paths;
unsigned int path_count;
};
extern void bgp_scan_init (void);
extern void bgp_scan_finish (void);
extern int bgp_nexthop_lookup (afi_t, struct peer *peer, struct bgp_info *,
int *, int *);
extern void bgp_connected_add (struct connected *c);
extern void bgp_connected_delete (struct connected *c);
extern int bgp_multiaccess_check_v4 (struct in_addr, char *);
extern int bgp_multiaccess_check_v4 (struct in_addr, struct peer *);
extern int bgp_config_write_scan_time (struct vty *);
extern int bgp_nexthop_onlink (afi_t, struct attr *);
extern int bgp_nexthop_self (struct attr *);

View File

@ -50,19 +50,15 @@ static void path_nh_map(struct bgp_info *path, struct bgp_nexthop_cache *bnc,
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));
}
@ -77,7 +73,7 @@ bgp_unlink_nexthop (struct bgp_info *path)
path_nh_map(path, NULL, 0);
if (LIST_EMPTY(&(bnc->paths)))
if (LIST_EMPTY(&(bnc->paths)) && !bnc->nht_info)
{
if (BGP_DEBUG(nht, NHT))
{
@ -93,15 +89,34 @@ bgp_unlink_nexthop (struct bgp_info *path)
}
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)
@ -110,23 +125,27 @@ bgp_find_or_add_nexthop (afi_t afi, struct bgp_info *ri, int *changed,
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));
}
@ -265,6 +284,7 @@ bgp_parse_nexthop_update (void)
else
{
bnc->flags &= ~BGP_NEXTHOP_VALID;
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED);
bnc_nexthop_free(bnc);
bnc->nexthop = NULL;
}
@ -322,12 +342,21 @@ sendmsg_nexthop (struct bgp_nexthop_cache *bnc, int command)
/* 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);
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))
@ -349,6 +378,11 @@ sendmsg_nexthop (struct bgp_nexthop_cache *bnc, int command)
/* 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;
}
@ -367,7 +401,6 @@ register_nexthop (struct bgp_nexthop_cache *bnc)
if (bnc->flags & BGP_NEXTHOP_REGISTERED)
return;
sendmsg_nexthop(bnc, ZEBRA_NEXTHOP_REGISTER);
SET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
}
/**
@ -385,7 +418,6 @@ unregister_nexthop (struct bgp_nexthop_cache *bnc)
return;
sendmsg_nexthop(bnc, ZEBRA_NEXTHOP_UNREGISTER);
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
}
/**
@ -402,6 +434,7 @@ evaluate_paths (struct bgp_nexthop_cache *bnc)
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)
{
@ -444,6 +477,15 @@ evaluate_paths (struct bgp_nexthop_cache *bnc)
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);
}

View File

@ -31,12 +31,9 @@ extern void bgp_parse_nexthop_update();
* bgp_find_nexthop() - lookup the nexthop cache table for the bnc object
* ARGUMENTS:
* p - path for which the nexthop object is being looked up
* c - output variable that stores whether the nexthop object has changed
* since last time.
* m - output variable that stores whether the nexthop metric has changed
* since last time.
* connected - True if NH MUST be a connected route
*/
extern int bgp_find_nexthop(struct bgp_info *p, int *c, int *m);
extern int bgp_find_nexthop(struct bgp_info *p, int connected);
/**
* bgp_find_or_add_nexthop() - lookup the nexthop cache table for the bnc
@ -45,12 +42,11 @@ extern int bgp_find_nexthop(struct bgp_info *p, int *c, int *m);
* ARGUMENTS:
* a - afi: AFI_IP or AF_IP6
* p - path for which the nexthop object is being looked up
* c - output variable that stores whether the nexthop object has changed
* since last time.
* m - output variable that stores whether the nexthop metric has changed
* since last time.
* peer - The BGP peer associated with this NHT
* connected - True if NH MUST be a connected route
*/
extern int bgp_find_or_add_nexthop(afi_t a, struct bgp_info *p, int *c, int *m);
extern int bgp_find_or_add_nexthop(afi_t a, struct bgp_info *p,
struct peer *peer, int connected);
/**
* bgp_unlink_nexthop() - Unlink the nexthop object from the path structure.

View File

@ -100,8 +100,8 @@ bgp_packet_delete (struct peer *peer)
}
/* Check file descriptor whether connect is established. */
static void
bgp_connect_check (struct peer *peer)
int
bgp_connect_check (struct peer *peer, int change_state)
{
int status;
socklen_t slen;
@ -120,20 +120,23 @@ bgp_connect_check (struct peer *peer)
{
zlog (peer->log, LOG_INFO, "can't get sockopt for nonblocking connect");
BGP_EVENT_ADD (peer, TCP_fatal_error);
return;
return -1;
}
/* When status is 0 then TCP connection is established. */
if (status == 0)
{
BGP_EVENT_ADD (peer, TCP_connection_open);
return 1;
}
else
{
if (BGP_DEBUG (events, EVENTS))
plog_debug (peer->log, "%s [Event] Connect failed (%s)",
peer->host, safe_strerror (errno));
BGP_EVENT_ADD (peer, TCP_connection_open_failed);
if (change_state)
BGP_EVENT_ADD (peer, TCP_connection_open_failed);
return 0;
}
}
@ -698,7 +701,7 @@ bgp_write (struct thread *thread)
/* For non-blocking IO check. */
if (peer->status == Connect)
{
bgp_connect_check (peer);
bgp_connect_check (peer, 1);
return 0;
}
@ -2541,7 +2544,7 @@ bgp_read (struct thread *thread)
/* For non-blocking IO check. */
if (peer->status == Connect)
{
bgp_connect_check (peer);
bgp_connect_check (peer, 1);
goto done;
}
else

View File

@ -40,6 +40,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
/* Packet send and receive function prototypes. */
extern int bgp_read (struct thread *);
extern int bgp_write (struct thread *);
extern int bgp_connect_check (struct peer *, int change_state);
extern void bgp_keepalive_send (struct peer *);
extern void bgp_open_send (struct peer *);

View File

@ -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 ((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);
@ -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;
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;
}
@ -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);

View File

@ -58,6 +58,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_network.h"
#include "bgpd/bgp_vty.h"
#include "bgpd/bgp_mpath.h"
#include "bgpd/bgp_nht.h"
#ifdef HAVE_SNMP
#include "bgpd/bgp_snmp.h"
#endif /* HAVE_SNMP */
@ -4733,24 +4734,33 @@ peer_maximum_prefix_set (struct peer *peer, afi_t afi, safi_t safi,
else
UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (! peer->af_group[afi][safi])
continue;
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
{
if (! peer->af_group[afi][safi])
continue;
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
peer->pmax[afi][safi] = max;
peer->pmax_threshold[afi][safi] = threshold;
peer->pmax_restart[afi][safi] = restart;
if (warning)
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
else
UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
peer->pmax[afi][safi] = max;
peer->pmax_threshold[afi][safi] = threshold;
peer->pmax_restart[afi][safi] = restart;
if (warning)
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
else
UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
if ((peer->status == Established) && (peer->afc[afi][safi]))
bgp_maximum_prefix_overflow (peer, afi, safi, 1);
}
}
else
{
if ((peer->status == Established) && (peer->afc[afi][safi]))
bgp_maximum_prefix_overflow (peer, afi, safi, 1);
}
return 0;
}
@ -5767,9 +5777,6 @@ bgp_config_write (struct vty *vty)
if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
vty_out (vty, " bgp network import-check%s", VTY_NEWLINE);
/* BGP scan interval. */
bgp_config_write_scan_time (vty);
/* BGP flag dampening. */
if (CHECK_FLAG (bgp->af_flags[AFI_IP][SAFI_UNICAST],
BGP_CONFIG_DAMPENING))
@ -5849,12 +5856,16 @@ bgp_master_init (void)
void
bgp_init (void)
{
/* BGP VTY commands installation. */
bgp_vty_init ();
/* allocates some vital data structures used by peer commands in vty_init */
bgp_scan_init ();
/* Init zebra. */
bgp_zebra_init ();
/* BGP VTY commands installation. */
bgp_vty_init ();
/* BGP inits. */
bgp_attr_init ();
bgp_debug_init ();
@ -5862,7 +5873,7 @@ bgp_init (void)
bgp_route_init ();
bgp_route_map_init ();
bgp_address_init ();
bgp_scan_init ();
bgp_scan_vty_init();
bgp_mplsvpn_init ();
/* Access list initialize. */

View File

@ -233,7 +233,15 @@ zebra_evaluate_rnh_table (int vrfid, int family, int force)
if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
continue;
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
break;
{
if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED))
{
if (rib->type == ZEBRA_ROUTE_CONNECT)
break;
}
else
break;
}
}
}
@ -649,7 +657,9 @@ print_rnh (struct route_node *rn, struct vty *vty)
print_nh(nexthop, vty);
}
else
vty_out(vty, " unresolved%s", VTY_NEWLINE);
vty_out(vty, " unresolved%s%s",
CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED) ? "(Connected)" : "",
VTY_NEWLINE);
vty_out(vty, " Client list:");
for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client))

View File

@ -30,6 +30,7 @@
struct rnh
{
u_char flags;
#define ZEBRA_NHT_CONNECTED 0x1
struct rib *state;
struct list *client_list;
struct route_node *node;

View File

@ -755,6 +755,7 @@ zserv_nexthop_register (struct zserv *client, int sock, u_short length)
struct stream *s;
struct prefix p;
u_short l = 0;
u_char connected;
if (IS_ZEBRA_DEBUG_NHT)
zlog_debug("nexthop_register msg from client %s: length=%d\n",
@ -764,12 +765,16 @@ zserv_nexthop_register (struct zserv *client, int sock, u_short length)
while (l < length)
{
connected = stream_getc(s);
p.family = stream_getw(s);
p.prefixlen = stream_getc(s);
l += 3;
l += 4;
stream_get(&p.u.prefix, s, PSIZE(p.prefixlen));
l += PSIZE(p.prefixlen);
rnh = zebra_add_rnh(&p, 0);
if (connected)
SET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED);
zebra_add_rnh_client(rnh, client);
}
zebra_evaluate_rnh_table(0, AF_INET, 0);
@ -785,6 +790,7 @@ zserv_nexthop_unregister (struct zserv *client, int sock, u_short length)
struct stream *s;
struct prefix p;
u_short l = 0;
u_char connected;
if (IS_ZEBRA_DEBUG_NHT)
zlog_debug("nexthop_unregister msg from client %s: length=%d\n",
@ -794,9 +800,10 @@ zserv_nexthop_unregister (struct zserv *client, int sock, u_short length)
while (l < length)
{
connected = stream_getc(s);
p.family = stream_getw(s);
p.prefixlen = stream_getc(s);
l += 3;
l += 4;
stream_get(&p.u.prefix, s, PSIZE(p.prefixlen));
l += PSIZE(p.prefixlen);
rnh = zebra_lookup_rnh(&p, 0);