mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-02 18:52:04 +00:00
* bgp_fsm.c, bgp_open.c, bgp_packet.c, bgp_route.[ch], bgp_vty.c,
bgpd.[ch]: Add BGP_INFO_STALE flag and end-of-rib support. "bgp graceful-restart" commands added. Show numbers of individual messages in "show ip bgp neighbor" command. Final pieces of graceful restart. [merge from GNU Zebra]
This commit is contained in:
parent
c9502438e8
commit
93406d87e6
@ -1,3 +1,11 @@
|
||||
2005-02-02 Akihiro Mizutani <mizutani@net-chef.net
|
||||
|
||||
* bgp_fsm.c, bgp_open.c, bgp_packet.c, bgp_route.[ch], bgp_vty.c,
|
||||
bgpd.[ch]: Add BGP_INFO_STALE flag and end-of-rib support. "bgp
|
||||
graceful-restart" commands added. Show numbers of individual
|
||||
messages in "show ip bgp neighbor" command. Final pieces of graceful
|
||||
restart.
|
||||
|
||||
2005-02-01 Akihiro Mizutani <mizutani@net-chef.net>
|
||||
|
||||
* bgp_open.c, bgp_packet.c, bgp_vty.c, bgpd.[ch]: Remove "no neighbor
|
||||
|
133
bgpd/bgp_fsm.c
133
bgpd/bgp_fsm.c
@ -118,7 +118,8 @@ bgp_timer_set (struct peer *peer)
|
||||
connect timer is expired, change status to Connect. */
|
||||
BGP_TIMER_OFF (peer->t_start);
|
||||
/* If peer is passive mode, do not set connect timer. */
|
||||
if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE))
|
||||
if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE)
|
||||
|| CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
|
||||
{
|
||||
BGP_TIMER_OFF (peer->t_connect);
|
||||
}
|
||||
@ -331,9 +332,62 @@ const char *peer_down_str[] =
|
||||
"Peer-group delete member",
|
||||
"Capability changed",
|
||||
"Passive config change",
|
||||
"Multihop config change"
|
||||
"Multihop config change",
|
||||
"NSF peer closed the session"
|
||||
};
|
||||
|
||||
int
|
||||
bgp_graceful_restart_timer_expire (struct thread *thread)
|
||||
{
|
||||
struct peer *peer;
|
||||
afi_t afi;
|
||||
safi_t safi;
|
||||
|
||||
peer = THREAD_ARG (thread);
|
||||
peer->t_gr_restart = NULL;
|
||||
|
||||
/* NSF delete stale route */
|
||||
for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
|
||||
for (safi = SAFI_UNICAST ; safi < SAFI_UNICAST_MULTICAST ; safi++)
|
||||
if (peer->nsf[afi][safi])
|
||||
bgp_clear_stale_route (peer, afi, safi);
|
||||
|
||||
UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
|
||||
BGP_TIMER_OFF (peer->t_gr_stale);
|
||||
|
||||
if (BGP_DEBUG (events, EVENTS))
|
||||
{
|
||||
zlog_debug ("%s graceful restart timer expired", peer->host);
|
||||
zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
|
||||
}
|
||||
|
||||
bgp_timer_set (peer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bgp_graceful_stale_timer_expire (struct thread *thread)
|
||||
{
|
||||
struct peer *peer;
|
||||
afi_t afi;
|
||||
safi_t safi;
|
||||
|
||||
peer = THREAD_ARG (thread);
|
||||
peer->t_gr_stale = NULL;
|
||||
|
||||
if (BGP_DEBUG (events, EVENTS))
|
||||
zlog_debug ("%s graceful restart stalepath timer expired", peer->host);
|
||||
|
||||
/* NSF delete stale route */
|
||||
for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
|
||||
for (safi = SAFI_UNICAST ; safi < SAFI_UNICAST_MULTICAST ; safi++)
|
||||
if (peer->nsf[afi][safi])
|
||||
bgp_clear_stale_route (peer, afi, safi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Administrative BGP peer stop event. */
|
||||
int
|
||||
bgp_stop (struct peer *peer)
|
||||
@ -353,6 +407,36 @@ bgp_stop (struct peer *peer)
|
||||
zlog_info ("%%ADJCHANGE: neighbor %s Down %s", peer->host,
|
||||
peer_down_str [(int) peer->last_reset]);
|
||||
|
||||
/* graceful restart */
|
||||
if (peer->t_gr_stale)
|
||||
{
|
||||
BGP_TIMER_OFF (peer->t_gr_stale);
|
||||
if (BGP_DEBUG (events, EVENTS))
|
||||
zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
|
||||
}
|
||||
if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
|
||||
{
|
||||
if (BGP_DEBUG (events, EVENTS))
|
||||
{
|
||||
zlog_debug ("%s graceful restart timer started for %d sec",
|
||||
peer->host, peer->v_gr_restart);
|
||||
zlog_debug ("%s graceful restart stalepath timer started for %d sec",
|
||||
peer->host, peer->bgp->stalepath_time);
|
||||
}
|
||||
BGP_TIMER_ON (peer->t_gr_restart, bgp_graceful_restart_timer_expire,
|
||||
peer->v_gr_restart);
|
||||
BGP_TIMER_ON (peer->t_gr_stale, bgp_graceful_stale_timer_expire,
|
||||
peer->bgp->stalepath_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
|
||||
|
||||
for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
|
||||
for (safi = SAFI_UNICAST ; safi < SAFI_UNICAST_MULTICAST ; safi++)
|
||||
peer->nsf[afi][safi] = 0;
|
||||
}
|
||||
|
||||
/* set last reset time */
|
||||
peer->resettime = time (NULL);
|
||||
/* Reset uptime. */
|
||||
@ -655,6 +739,7 @@ bgp_establish (struct peer *peer)
|
||||
struct bgp_notify *notify;
|
||||
afi_t afi;
|
||||
safi_t safi;
|
||||
int nsf_af_count = 0;
|
||||
|
||||
/* Reset capability open status flag. */
|
||||
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN))
|
||||
@ -677,6 +762,50 @@ bgp_establish (struct peer *peer)
|
||||
if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
|
||||
zlog_info ("%%ADJCHANGE: neighbor %s Up", peer->host);
|
||||
|
||||
/* graceful restart */
|
||||
UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
|
||||
for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
|
||||
for (safi = SAFI_UNICAST ; safi < SAFI_UNICAST_MULTICAST ; safi++)
|
||||
{
|
||||
if (peer->afc_nego[afi][safi]
|
||||
&& CHECK_FLAG (peer->cap, PEER_CAP_RESTART_ADV)
|
||||
&& CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV))
|
||||
{
|
||||
if (peer->nsf[afi][safi]
|
||||
&& ! CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV))
|
||||
bgp_clear_stale_route (peer, afi, safi);
|
||||
|
||||
peer->nsf[afi][safi] = 1;
|
||||
nsf_af_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (peer->nsf[afi][safi])
|
||||
bgp_clear_stale_route (peer, afi, safi);
|
||||
peer->nsf[afi][safi] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (nsf_af_count)
|
||||
SET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
|
||||
else
|
||||
{
|
||||
UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
|
||||
if (peer->t_gr_stale)
|
||||
{
|
||||
BGP_TIMER_OFF (peer->t_gr_stale);
|
||||
if (BGP_DEBUG (events, EVENTS))
|
||||
zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
|
||||
}
|
||||
}
|
||||
|
||||
if (peer->t_gr_restart)
|
||||
{
|
||||
BGP_TIMER_OFF (peer->t_gr_restart);
|
||||
if (BGP_DEBUG (events, EVENTS))
|
||||
zlog_debug ("%s graceful restart timer stopped", peer->host);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SNMP
|
||||
bgpTrapEstablished (peer);
|
||||
#endif /* HAVE_SNMP */
|
||||
|
@ -401,7 +401,6 @@ bgp_capability_parse (struct peer *peer, u_char *pnt, u_char length,
|
||||
struct graceful_restart_af graf;
|
||||
u_int16_t restart_flag_time;
|
||||
int restart_bit = 0;
|
||||
int forwarding_bit = 0;
|
||||
u_char *restart_pnt;
|
||||
u_char *restart_end;
|
||||
|
||||
@ -418,15 +417,15 @@ bgp_capability_parse (struct peer *peer, u_char *pnt, u_char length,
|
||||
restart_flag_time = ntohs(cap.mpc.afi);
|
||||
if (CHECK_FLAG (restart_flag_time, RESTART_R_BIT))
|
||||
restart_bit = 1;
|
||||
UNSET_FLAG (restart_flag_time, 0xF000);
|
||||
peer->restart_time_rcv = restart_flag_time;
|
||||
UNSET_FLAG (restart_flag_time, 0xF000);
|
||||
peer->v_gr_restart = restart_flag_time;
|
||||
|
||||
if (BGP_DEBUG (normal, NORMAL))
|
||||
{
|
||||
zlog_debug ("%s OPEN has Graceful Restart capability", peer->host);
|
||||
zlog_debug ("%s Peer has%srestarted. Restart Time : %d",
|
||||
peer->host, restart_bit ? " " : " not ",
|
||||
peer->restart_time_rcv);
|
||||
peer->v_gr_restart);
|
||||
}
|
||||
|
||||
restart_pnt = pnt + 4;
|
||||
@ -440,7 +439,7 @@ bgp_capability_parse (struct peer *peer, u_char *pnt, u_char length,
|
||||
safi = graf.safi;
|
||||
|
||||
if (CHECK_FLAG (graf.flag, RESTART_F_BIT))
|
||||
forwarding_bit = 1;
|
||||
SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV);
|
||||
|
||||
if (strcmp (afi_safi_print (afi, safi), "Unknown") == 0)
|
||||
{
|
||||
@ -458,12 +457,13 @@ bgp_capability_parse (struct peer *peer, u_char *pnt, u_char length,
|
||||
{
|
||||
if (BGP_DEBUG (normal, NORMAL))
|
||||
zlog_debug ("%s Address family %s is%spreserved", peer->host,
|
||||
afi_safi_print (afi, safi), forwarding_bit ? " " : " not ");
|
||||
afi_safi_print (afi, safi),
|
||||
CHECK_FLAG (peer->af_cap[afi][safi],
|
||||
PEER_CAP_RESTART_AF_PRESERVE_RCV)
|
||||
? " " : " not ");
|
||||
|
||||
if (forwarding_bit)
|
||||
SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV);
|
||||
}
|
||||
forwarding_bit = 0;
|
||||
restart_pnt += 4;
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "bgpd/bgp_network.h"
|
||||
#include "bgpd/bgp_mplsvpn.h"
|
||||
#include "bgpd/bgp_advertise.h"
|
||||
#include "bgpd/bgp_vty.h"
|
||||
|
||||
int stream_put_prefix (struct stream *, struct prefix *);
|
||||
|
||||
@ -243,7 +244,50 @@ bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi)
|
||||
return packet;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct stream *
|
||||
bgp_update_packet_eor (struct peer *peer, afi_t afi, safi_t safi)
|
||||
{
|
||||
struct stream *s;
|
||||
struct stream *packet;
|
||||
|
||||
#ifdef DISABLE_BGP_ANNOUNCE
|
||||
return;
|
||||
#endif /* DISABLE_BGP_ANNOUNCE */
|
||||
|
||||
if (BGP_DEBUG (normal, NORMAL))
|
||||
zlog_debug ("send End-of-RIB for %s to %s", afi_safi_print (afi, safi), peer->host);
|
||||
|
||||
s = stream_new (BGP_MAX_PACKET_SIZE);
|
||||
|
||||
/* Make BGP update packet. */
|
||||
bgp_packet_set_marker (s, BGP_MSG_UPDATE);
|
||||
|
||||
/* Unfeasible Routes Length */
|
||||
stream_putw (s, 0);
|
||||
|
||||
if (afi == AFI_IP && safi == SAFI_UNICAST)
|
||||
{
|
||||
/* Total Path Attribute Length */
|
||||
stream_putw (s, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Total Path Attribute Length */
|
||||
stream_putw (s, 6);
|
||||
stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);
|
||||
stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);
|
||||
stream_putc (s, 3);
|
||||
stream_putw (s, afi);
|
||||
stream_putc (s, safi);
|
||||
}
|
||||
|
||||
bgp_packet_set_size (s);
|
||||
packet = bgp_packet_dup (s);
|
||||
bgp_packet_add (peer, packet);
|
||||
stream_free (s);
|
||||
return packet;
|
||||
}
|
||||
|
||||
/* Make BGP withdraw packet. */
|
||||
@ -504,11 +548,34 @@ bgp_write_packet (struct peer *peer)
|
||||
if (adv)
|
||||
{
|
||||
if (adv->binfo && adv->binfo->uptime < peer->synctime)
|
||||
s = bgp_update_packet (peer, afi, safi);
|
||||
{
|
||||
if (CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_RCV)
|
||||
&& CHECK_FLAG (adv->binfo->peer->cap, PEER_CAP_RESTART_ADV)
|
||||
&& ! CHECK_FLAG (adv->binfo->flags, BGP_INFO_STALE)
|
||||
&& safi != SAFI_MPLS_VPN)
|
||||
{
|
||||
if (CHECK_FLAG (adv->binfo->peer->af_sflags[afi][safi],
|
||||
PEER_STATUS_EOR_RECEIVED))
|
||||
s = bgp_update_packet (peer, afi, safi);
|
||||
}
|
||||
else
|
||||
s = bgp_update_packet (peer, afi, safi);
|
||||
}
|
||||
|
||||
if (s)
|
||||
return s;
|
||||
}
|
||||
|
||||
if (CHECK_FLAG (peer->cap, PEER_CAP_RESTART_RCV))
|
||||
{
|
||||
if (peer->afc_nego[afi][safi] && peer->synctime
|
||||
&& ! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)
|
||||
&& safi != SAFI_MPLS_VPN)
|
||||
{
|
||||
SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_SEND);
|
||||
return bgp_update_packet_eor (peer, afi, safi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@ -1192,13 +1259,24 @@ bgp_open_receive (struct peer *peer, bgp_size_t size)
|
||||
/* Hack part. */
|
||||
if (CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
|
||||
{
|
||||
if (ret == 0 && realpeer->status != Active
|
||||
&& realpeer->status != OpenSent
|
||||
&& realpeer->status != OpenConfirm)
|
||||
if (realpeer->status == Established
|
||||
&& CHECK_FLAG (realpeer->sflags, PEER_STATUS_NSF_MODE))
|
||||
{
|
||||
realpeer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
|
||||
SET_FLAG (realpeer->sflags, PEER_STATUS_NSF_WAIT);
|
||||
}
|
||||
else if (ret == 0 && realpeer->status != Active
|
||||
&& realpeer->status != OpenSent
|
||||
&& realpeer->status != OpenConfirm)
|
||||
|
||||
{
|
||||
if (BGP_DEBUG (events, EVENTS))
|
||||
zlog_debug ("%s [Event] peer's status is %s close connection",
|
||||
realpeer->host, LOOKUP (bgp_status_msg, peer->status));
|
||||
zlog_debug ("%s peer status is %s close connection",
|
||||
realpeer->host, LOOKUP (bgp_status_msg,
|
||||
realpeer->status));
|
||||
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
|
||||
BGP_NOTIFY_CEASE_CONNECT_REJECT);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1524,8 +1602,14 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
|
||||
if (! attribute_len && ! withdraw_len)
|
||||
{
|
||||
/* End-of-RIB received */
|
||||
SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
|
||||
PEER_STATUS_EOR_RECEIVED);
|
||||
|
||||
if (BGP_DEBUG (update, UPDATE_IN))
|
||||
/* NSF delete stale route */
|
||||
if (peer->nsf[AFI_IP][SAFI_UNICAST])
|
||||
bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
|
||||
|
||||
if (BGP_DEBUG (normal, NORMAL))
|
||||
zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Unicast from %s",
|
||||
peer->host);
|
||||
}
|
||||
@ -1542,14 +1626,20 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
|
||||
&& mp_withdraw.safi == SAFI_MULTICAST)
|
||||
bgp_nlri_parse (peer, NULL, &mp_withdraw);
|
||||
|
||||
if (attribute_len == 6 && ! withdraw_len
|
||||
if (! withdraw_len
|
||||
&& mp_withdraw.afi == AFI_IP
|
||||
&& mp_withdraw.safi == SAFI_MULTICAST
|
||||
&& mp_withdraw.length == 0)
|
||||
{
|
||||
/* End-of-RIB received */
|
||||
SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
|
||||
PEER_STATUS_EOR_RECEIVED);
|
||||
|
||||
if (BGP_DEBUG (update, UPDATE_IN))
|
||||
/* NSF delete stale route */
|
||||
if (peer->nsf[AFI_IP][SAFI_MULTICAST])
|
||||
bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
|
||||
|
||||
if (BGP_DEBUG (normal, NORMAL))
|
||||
zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv4 Multicast from %s",
|
||||
peer->host);
|
||||
}
|
||||
@ -1566,14 +1656,19 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
|
||||
&& mp_withdraw.safi == SAFI_UNICAST)
|
||||
bgp_nlri_parse (peer, NULL, &mp_withdraw);
|
||||
|
||||
if (attribute_len == 6 && ! withdraw_len
|
||||
if (! withdraw_len
|
||||
&& mp_withdraw.afi == AFI_IP6
|
||||
&& mp_withdraw.safi == SAFI_UNICAST
|
||||
&& mp_withdraw.length == 0)
|
||||
{
|
||||
/* End-of-RIB received */
|
||||
SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
|
||||
|
||||
if (BGP_DEBUG (update, UPDATE_IN))
|
||||
/* NSF delete stale route */
|
||||
if (peer->nsf[AFI_IP6][SAFI_UNICAST])
|
||||
bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
|
||||
|
||||
if (BGP_DEBUG (normal, NORMAL))
|
||||
zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Unicast from %s",
|
||||
peer->host);
|
||||
}
|
||||
@ -1590,13 +1685,17 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
|
||||
&& mp_withdraw.safi == SAFI_MULTICAST)
|
||||
bgp_nlri_parse (peer, NULL, &mp_withdraw);
|
||||
|
||||
if (attribute_len == 6 && ! withdraw_len
|
||||
if (! withdraw_len
|
||||
&& mp_withdraw.afi == AFI_IP6
|
||||
&& mp_withdraw.safi == SAFI_MULTICAST
|
||||
&& mp_withdraw.length == 0)
|
||||
{
|
||||
/* End-of-RIB received */
|
||||
|
||||
/* NSF delete stale route */
|
||||
if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
|
||||
bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
|
||||
|
||||
if (BGP_DEBUG (update, UPDATE_IN))
|
||||
zlog (peer->log, LOG_DEBUG, "rcvd End-of-RIB for IPv6 Multicast from %s",
|
||||
peer->host);
|
||||
@ -1614,7 +1713,7 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
|
||||
&& mp_withdraw.safi == BGP_SAFI_VPNV4)
|
||||
bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw);
|
||||
|
||||
if (attribute_len == 6 && ! withdraw_len
|
||||
if (! withdraw_len
|
||||
&& mp_withdraw.afi == AFI_IP
|
||||
&& mp_withdraw.safi == BGP_SAFI_VPNV4
|
||||
&& mp_withdraw.length == 0)
|
||||
@ -2080,6 +2179,18 @@ bgp_read_packet (struct peer *peer)
|
||||
|
||||
plog_err (peer->log, "%s [Error] bgp_read_packet error: %s",
|
||||
peer->host, safe_strerror (errno));
|
||||
|
||||
if (peer->status == Established)
|
||||
{
|
||||
if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
|
||||
{
|
||||
peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
|
||||
SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
|
||||
}
|
||||
else
|
||||
peer->last_reset = PEER_DOWN_CLOSE_SESSION;
|
||||
}
|
||||
|
||||
BGP_EVENT_ADD (peer, TCP_fatal_error);
|
||||
return -1;
|
||||
}
|
||||
@ -2092,7 +2203,15 @@ bgp_read_packet (struct peer *peer)
|
||||
peer->host, peer->fd);
|
||||
|
||||
if (peer->status == Established)
|
||||
peer->last_reset = PEER_DOWN_CLOSE_SESSION;
|
||||
{
|
||||
if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_MODE))
|
||||
{
|
||||
peer->last_reset = PEER_DOWN_NSF_CLOSE_SESSION;
|
||||
SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
|
||||
}
|
||||
else
|
||||
peer->last_reset = PEER_DOWN_CLOSE_SESSION;
|
||||
}
|
||||
|
||||
BGP_EVENT_ADD (peer, TCP_connection_closed);
|
||||
return -1;
|
||||
|
108
bgpd/bgp_route.c
108
bgpd/bgp_route.c
@ -1393,7 +1393,8 @@ bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
|
||||
if (! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY) &&
|
||||
rn->table->type == BGP_TABLE_MAIN)
|
||||
{
|
||||
peer->pcount[afi][safi]--;
|
||||
if (! CHECK_FLAG (ri->flags, BGP_INFO_STALE))
|
||||
peer->pcount[afi][safi]--;
|
||||
bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi);
|
||||
}
|
||||
|
||||
@ -1780,6 +1781,13 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
|
||||
peer->host,
|
||||
inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
|
||||
p->prefixlen);
|
||||
|
||||
/* graceful restart STALE flag unset. */
|
||||
if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
|
||||
{
|
||||
UNSET_FLAG (ri->flags, BGP_INFO_STALE);
|
||||
peer->pcount[afi][safi]++;
|
||||
}
|
||||
}
|
||||
|
||||
bgp_unlock_node (rn);
|
||||
@ -1794,6 +1802,13 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
|
||||
inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
|
||||
p->prefixlen);
|
||||
|
||||
/* graceful restart STALE flag unset. */
|
||||
if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
|
||||
{
|
||||
UNSET_FLAG (ri->flags, BGP_INFO_STALE);
|
||||
peer->pcount[afi][safi]++;
|
||||
}
|
||||
|
||||
/* The attribute is changed. */
|
||||
SET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED);
|
||||
|
||||
@ -2255,7 +2270,18 @@ bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,
|
||||
for (ri = rn->info; ri; ri = ri->next)
|
||||
if (ri->peer == peer)
|
||||
{
|
||||
bgp_rib_remove (rn, ri, peer, afi, safi);
|
||||
/* graceful restart STALE flag set. */
|
||||
if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT)
|
||||
&& peer->nsf[afi][safi]
|
||||
&& ! CHECK_FLAG (ri->flags, BGP_INFO_STALE)
|
||||
&& ! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY)
|
||||
&& ! CHECK_FLAG (ri->flags, BGP_INFO_DAMPED))
|
||||
{
|
||||
SET_FLAG (ri->flags, BGP_INFO_STALE);
|
||||
peer->pcount[afi][safi]--;
|
||||
}
|
||||
else
|
||||
bgp_rib_remove (rn, ri, peer, afi, safi);
|
||||
break;
|
||||
}
|
||||
for (ain = rn->adj_in; ain; ain = ain->next)
|
||||
@ -2327,6 +2353,27 @@ bgp_clear_adj_in (struct peer *peer, afi_t afi, safi_t safi)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bgp_clear_stale_route (struct peer *peer, afi_t afi, safi_t safi)
|
||||
{
|
||||
struct bgp_node *rn;
|
||||
struct bgp_info *ri;
|
||||
struct bgp_table *table;
|
||||
|
||||
table = peer->bgp->rib[afi][safi];
|
||||
|
||||
for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
|
||||
{
|
||||
for (ri = rn->info; ri; ri = ri->next)
|
||||
if (ri->peer == peer)
|
||||
{
|
||||
if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
|
||||
bgp_rib_remove (rn, ri, peer, afi, safi);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete all kernel routes. */
|
||||
void
|
||||
@ -4725,7 +4772,9 @@ route_vty_out (struct vty *vty, struct prefix *p,
|
||||
struct attr *attr;
|
||||
|
||||
/* Route status display. */
|
||||
if (binfo->suppress)
|
||||
if (CHECK_FLAG (binfo->flags, BGP_INFO_STALE))
|
||||
vty_out (vty, "S");
|
||||
else if (binfo->suppress)
|
||||
vty_out (vty, "s");
|
||||
else if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
|
||||
vty_out (vty, "*");
|
||||
@ -5106,26 +5155,19 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
|
||||
aspath_print_vty (vty, attr->aspath);
|
||||
}
|
||||
|
||||
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR)
|
||||
|| CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT)
|
||||
|| CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
|
||||
|| CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY)
|
||||
|| CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
|
||||
{
|
||||
vty_out (vty, ",");
|
||||
|
||||
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))
|
||||
vty_out (vty, " (aggregated by %d %s)", attr->aggregator_as,
|
||||
inet_ntoa (attr->aggregator_addr));
|
||||
if (CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
|
||||
vty_out (vty, " (Received from a RR-client)");
|
||||
if (CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
|
||||
vty_out (vty, " (Received from a RS-client)");
|
||||
if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
|
||||
vty_out (vty, " (history entry)");
|
||||
else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
|
||||
vty_out (vty, " (suppressed due to dampening)");
|
||||
}
|
||||
if (CHECK_FLAG (binfo->flags, BGP_INFO_STALE))
|
||||
vty_out (vty, ", (stale)");
|
||||
if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR)))
|
||||
vty_out (vty, ", (aggregated by %d %s)", attr->aggregator_as,
|
||||
inet_ntoa (attr->aggregator_addr));
|
||||
if (CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
|
||||
vty_out (vty, ", (Received from a RR-client)");
|
||||
if (CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
|
||||
vty_out (vty, ", (Received from a RS-client)");
|
||||
if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
|
||||
vty_out (vty, ", (history entry)");
|
||||
else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
|
||||
vty_out (vty, ", (suppressed due to dampening)");
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
|
||||
/* Line2 display Next-hop, Neighbor, Router-id */
|
||||
@ -5251,6 +5293,8 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
}
|
||||
|
||||
#define BGP_SHOW_SCODE_HEADER "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,%s r RIB-failure, S Stale%s"
|
||||
#define BGP_SHOW_OCODE_HEADER "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s"
|
||||
#define BGP_SHOW_HEADER " Network Next Hop Metric LocPrf Weight Path%s"
|
||||
#define BGP_SHOW_DAMP_HEADER " Network From Reuse Path%s"
|
||||
#define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path%s"
|
||||
@ -5449,9 +5493,9 @@ bgp_show_table (struct vty *vty, struct bgp_table *table, struct in_addr *router
|
||||
|
||||
if (header)
|
||||
{
|
||||
vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (*router_id), VTY_NEWLINE);
|
||||
vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s", VTY_NEWLINE);
|
||||
vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s", VTY_NEWLINE, VTY_NEWLINE);
|
||||
vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (*router_id), VTY_NEWLINE);
|
||||
vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
|
||||
vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
|
||||
if (type == bgp_show_type_dampend_paths
|
||||
|| type == bgp_show_type_damp_neighbor)
|
||||
vty_out (vty, BGP_SHOW_DAMP_HEADER, VTY_NEWLINE);
|
||||
@ -8114,8 +8158,8 @@ show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
|
||||
PEER_STATUS_DEFAULT_ORIGINATE))
|
||||
{
|
||||
vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
|
||||
vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s", VTY_NEWLINE);
|
||||
vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s", VTY_NEWLINE, VTY_NEWLINE);
|
||||
vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
|
||||
vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
|
||||
|
||||
vty_out (vty, "Originating default network 0.0.0.0%s%s",
|
||||
VTY_NEWLINE, VTY_NEWLINE);
|
||||
@ -8131,8 +8175,8 @@ show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
|
||||
if (header1)
|
||||
{
|
||||
vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
|
||||
vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s", VTY_NEWLINE);
|
||||
vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s", VTY_NEWLINE, VTY_NEWLINE);
|
||||
vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
|
||||
vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
|
||||
header1 = 0;
|
||||
}
|
||||
if (header2)
|
||||
@ -8155,8 +8199,8 @@ show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
|
||||
if (header1)
|
||||
{
|
||||
vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
|
||||
vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s", VTY_NEWLINE);
|
||||
vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s", VTY_NEWLINE, VTY_NEWLINE);
|
||||
vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
|
||||
vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
|
||||
header1 = 0;
|
||||
}
|
||||
if (header2)
|
||||
|
@ -36,7 +36,7 @@ struct bgp_info
|
||||
#define BGP_ROUTE_REDISTRIBUTE 3
|
||||
|
||||
/* BGP information status. */
|
||||
u_char flags;
|
||||
u_int16_t flags;
|
||||
#define BGP_INFO_IGP_CHANGED (1 << 0)
|
||||
#define BGP_INFO_DAMPED (1 << 1)
|
||||
#define BGP_INFO_HISTORY (1 << 2)
|
||||
@ -45,6 +45,7 @@ struct bgp_info
|
||||
#define BGP_INFO_ATTR_CHANGED (1 << 5)
|
||||
#define BGP_INFO_DMED_CHECK (1 << 6)
|
||||
#define BGP_INFO_DMED_SELECTED (1 << 7)
|
||||
#define BGP_INFO_STALE (1 << 8)
|
||||
|
||||
/* Peer structure. */
|
||||
struct peer *peer;
|
||||
@ -134,6 +135,7 @@ void bgp_check_local_routes_rsclient (struct peer *rsclient, afi_t afi, safi_t s
|
||||
void bgp_clear_route (struct peer *, afi_t, safi_t);
|
||||
void bgp_clear_route_all (struct peer *);
|
||||
void bgp_clear_adj_in (struct peer *, afi_t, safi_t);
|
||||
void bgp_clear_stale_route (struct peer *, afi_t, safi_t);
|
||||
|
||||
int bgp_nlri_sanity_check (struct peer *, int, u_char *, bgp_size_t);
|
||||
int bgp_nlri_parse (struct peer *, struct attr *, struct bgp_nlri *);
|
||||
|
145
bgpd/bgp_vty.c
145
bgpd/bgp_vty.c
@ -806,6 +806,53 @@ DEFUN (no_bgp_graceful_restart,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (bgp_graceful_restart_stalepath_time,
|
||||
bgp_graceful_restart_stalepath_time_cmd,
|
||||
"bgp graceful-restart stalepath-time <1-3600>",
|
||||
"BGP specific commands\n"
|
||||
"Graceful restart capability parameters\n"
|
||||
"Set the max time to hold onto restarting peer's stale paths\n"
|
||||
"Delay value (seconds)\n")
|
||||
{
|
||||
struct bgp *bgp;
|
||||
u_int32_t stalepath;
|
||||
|
||||
bgp = vty->index;
|
||||
if (! bgp)
|
||||
return CMD_WARNING;
|
||||
|
||||
VTY_GET_INTEGER_RANGE ("stalepath-time", stalepath, argv[0], 1, 3600);
|
||||
bgp->stalepath_time = stalepath;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (no_bgp_graceful_restart_stalepath_time,
|
||||
no_bgp_graceful_restart_stalepath_time_cmd,
|
||||
"no bgp graceful-restart stalepath-time",
|
||||
NO_STR
|
||||
"BGP specific commands\n"
|
||||
"Graceful restart capability parameters\n"
|
||||
"Set the max time to hold onto restarting peer's stale paths\n")
|
||||
{
|
||||
struct bgp *bgp;
|
||||
|
||||
bgp = vty->index;
|
||||
if (! bgp)
|
||||
return CMD_WARNING;
|
||||
|
||||
bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
ALIAS (no_bgp_graceful_restart_stalepath_time,
|
||||
no_bgp_graceful_restart_stalepath_time_val_cmd,
|
||||
"no bgp graceful-restart stalepath-time <1-3600>",
|
||||
NO_STR
|
||||
"BGP specific commands\n"
|
||||
"Graceful restart capability parameters\n"
|
||||
"Set the max time to hold onto restarting peer's stale paths\n"
|
||||
"Delay value (seconds)\n")
|
||||
|
||||
/* "bgp fast-external-failover" configuration. */
|
||||
DEFUN (bgp_fast_external_failover,
|
||||
bgp_fast_external_failover_cmd,
|
||||
@ -6950,6 +6997,13 @@ bgp_show_peer (struct vty *vty, struct peer *p)
|
||||
if (p->status == Established)
|
||||
vty_out (vty, ", up for %8s",
|
||||
peer_uptime (p->uptime, timebuf, BGP_UPTIME_LEN));
|
||||
else if (p->status == Active)
|
||||
{
|
||||
if (CHECK_FLAG (p->flags, PEER_FLAG_PASSIVE))
|
||||
vty_out (vty, " (passive)");
|
||||
else if (CHECK_FLAG (p->sflags, PEER_STATUS_NSF_WAIT))
|
||||
vty_out (vty, " (NSF passive)");
|
||||
}
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
|
||||
/* read timer */
|
||||
@ -6964,7 +7018,7 @@ bgp_show_peer (struct vty *vty, struct peer *p)
|
||||
vty_out (vty, ", keepalive interval is %d seconds%s",
|
||||
p->keepalive, VTY_NEWLINE);
|
||||
}
|
||||
|
||||
|
||||
/* Capability. */
|
||||
if (p->status == Established)
|
||||
{
|
||||
@ -7046,17 +7100,19 @@ bgp_show_peer (struct vty *vty, struct peer *p)
|
||||
int restart_af_count = 0;
|
||||
|
||||
vty_out (vty, " Remote Restart timer is %d seconds%s",
|
||||
p->restart_time_rcv, VTY_NEWLINE);
|
||||
vty_out (vty, " Address families preserved by peer:%s ", VTY_NEWLINE);
|
||||
p->v_gr_restart, VTY_NEWLINE);
|
||||
vty_out (vty, " Address families by peer:%s ", VTY_NEWLINE);
|
||||
|
||||
for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
|
||||
for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
|
||||
if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV))
|
||||
{
|
||||
vty_out (vty, "%s%s", restart_af_count ? ", " : "",
|
||||
afi_safi_print (afi, safi));
|
||||
vty_out (vty, "%s%s(%s)", restart_af_count ? ", " : "",
|
||||
afi_safi_print (afi, safi),
|
||||
CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV) ?
|
||||
"preserved" : "not preserved");
|
||||
restart_af_count++;
|
||||
}
|
||||
}
|
||||
if (! restart_af_count)
|
||||
vty_out (vty, "none");
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
@ -7065,15 +7121,67 @@ bgp_show_peer (struct vty *vty, struct peer *p)
|
||||
}
|
||||
}
|
||||
|
||||
/* graceful restart information */
|
||||
if (CHECK_FLAG (p->cap, PEER_CAP_RESTART_RCV)
|
||||
|| p->t_gr_restart
|
||||
|| p->t_gr_stale)
|
||||
{
|
||||
int eor_send_af_count = 0;
|
||||
int eor_receive_af_count = 0;
|
||||
|
||||
vty_out (vty, " Graceful restart informations:%s", VTY_NEWLINE);
|
||||
if (p->status == Established)
|
||||
{
|
||||
vty_out (vty, " End-of-RIB send: ");
|
||||
for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
|
||||
for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
|
||||
if (CHECK_FLAG (p->af_sflags[afi][safi], PEER_STATUS_EOR_SEND))
|
||||
{
|
||||
vty_out (vty, "%s%s", eor_send_af_count ? ", " : "",
|
||||
afi_safi_print (afi, safi));
|
||||
eor_send_af_count++;
|
||||
}
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
|
||||
vty_out (vty, " End-of-RIB received: ");
|
||||
for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
|
||||
for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
|
||||
if (CHECK_FLAG (p->af_sflags[afi][safi], PEER_STATUS_EOR_RECEIVED))
|
||||
{
|
||||
vty_out (vty, "%s%s", eor_receive_af_count ? ", " : "",
|
||||
afi_safi_print (afi, safi));
|
||||
eor_receive_af_count++;
|
||||
}
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
}
|
||||
|
||||
if (p->t_gr_restart)
|
||||
{
|
||||
vty_out (vty, " The remaining time of restart timer is %ld%s",
|
||||
thread_timer_remain_second (p->t_gr_restart), VTY_NEWLINE);
|
||||
}
|
||||
if (p->t_gr_stale)
|
||||
{
|
||||
vty_out (vty, " The remaining time of stalepath timer is %ld%s",
|
||||
thread_timer_remain_second (p->t_gr_stale), VTY_NEWLINE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Packet counts. */
|
||||
vty_out(vty, " Received %d messages, %d notifications, %d in queue%s",
|
||||
p->open_in + p->update_in + p->keepalive_in + p->refresh_in
|
||||
+ p->dynamic_cap_in, p->notify_in, 0, VTY_NEWLINE);
|
||||
vty_out(vty, " Sent %d messages, %d notifications, %ld in queue%s",
|
||||
p->open_out + p->update_out + p->keepalive_out + p->refresh_out
|
||||
+ p->dynamic_cap_out, p->notify_out, p->obuf->count, VTY_NEWLINE);
|
||||
vty_out(vty, " Route refresh request: received %d, sent %d%s",
|
||||
p->refresh_in, p->refresh_out, VTY_NEWLINE);
|
||||
vty_out (vty, " Message statistics:%s", VTY_NEWLINE);
|
||||
vty_out (vty, " Inq depth is 0%s", VTY_NEWLINE);
|
||||
vty_out (vty, " Outq depth is %ld%s", p->obuf->count, VTY_NEWLINE);
|
||||
vty_out (vty, " Sent Rcvd%s", VTY_NEWLINE);
|
||||
vty_out (vty, " Opens: %10d %10d%s", p->open_out, p->open_in, VTY_NEWLINE);
|
||||
vty_out (vty, " Notifications: %10d %10d%s", p->notify_out, p->notify_in, VTY_NEWLINE);
|
||||
vty_out (vty, " Updates: %10d %10d%s", p->update_out, p->update_in, VTY_NEWLINE);
|
||||
vty_out (vty, " Keepalives: %10d %10d%s", p->keepalive_out, p->keepalive_in, VTY_NEWLINE);
|
||||
vty_out (vty, " Route Refresh: %10d %10d%s", p->refresh_out, p->refresh_in, VTY_NEWLINE);
|
||||
vty_out (vty, " Capability: %10d %10d%s", p->dynamic_cap_out, p->dynamic_cap_in, VTY_NEWLINE);
|
||||
vty_out (vty, " Total: %10d %10d%s", p->open_out + p->notify_out +
|
||||
p->update_out + p->keepalive_out + p->refresh_out + p->dynamic_cap_out,
|
||||
p->open_in + p->notify_in + p->update_in + p->keepalive_in + p->refresh_in +
|
||||
p->dynamic_cap_in, VTY_NEWLINE);
|
||||
|
||||
/* advertisement-interval */
|
||||
vty_out (vty, " Minimum time between advertisement runs is %d seconds%s",
|
||||
@ -7136,11 +7244,9 @@ bgp_show_peer (struct vty *vty, struct peer *p)
|
||||
/* Local address. */
|
||||
if (p->su_local)
|
||||
{
|
||||
vty_out (vty, "Local host: %s, Local port: %d%s%s",
|
||||
vty_out (vty, "Local host: %s, Local port: %d%s",
|
||||
sockunion2str (p->su_local, buf1, SU_ADDRSTRLEN),
|
||||
ntohs (p->su_local->sin.sin_port),
|
||||
CHECK_FLAG (p->flags, PEER_FLAG_PASSIVE) ?
|
||||
", passive-mode" : "",
|
||||
VTY_NEWLINE);
|
||||
}
|
||||
|
||||
@ -8480,11 +8586,12 @@ bgp_vty_init ()
|
||||
install_element (BGP_NODE, &bgp_deterministic_med_cmd);
|
||||
install_element (BGP_NODE, &no_bgp_deterministic_med_cmd);
|
||||
|
||||
#if 0
|
||||
/* "bgp graceful-restart" commands */
|
||||
install_element (BGP_NODE, &bgp_graceful_restart_cmd);
|
||||
install_element (BGP_NODE, &no_bgp_graceful_restart_cmd);
|
||||
#endif /* 0 */
|
||||
install_element (BGP_NODE, &bgp_graceful_restart_stalepath_time_cmd);
|
||||
install_element (BGP_NODE, &no_bgp_graceful_restart_stalepath_time_cmd);
|
||||
install_element (BGP_NODE, &no_bgp_graceful_restart_stalepath_time_val_cmd);
|
||||
|
||||
/* "bgp fast-external-failover" commands */
|
||||
install_element (BGP_NODE, &bgp_fast_external_failover_cmd);
|
||||
|
42
bgpd/bgpd.c
42
bgpd/bgpd.c
@ -1040,6 +1040,34 @@ peer_deactivate (struct peer *peer, afi_t afi, safi_t safi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
peer_nsf_stop (struct peer *peer)
|
||||
{
|
||||
afi_t afi;
|
||||
safi_t safi;
|
||||
|
||||
UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
|
||||
UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
|
||||
|
||||
for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
|
||||
for (safi = SAFI_UNICAST ; safi < SAFI_UNICAST_MULTICAST ; safi++)
|
||||
peer->nsf[afi][safi] = 0;
|
||||
|
||||
if (peer->t_gr_restart)
|
||||
{
|
||||
BGP_TIMER_OFF (peer->t_gr_restart);
|
||||
if (BGP_DEBUG (events, EVENTS))
|
||||
zlog_debug ("%s graceful restart timer stopped", peer->host);
|
||||
}
|
||||
if (peer->t_gr_stale)
|
||||
{
|
||||
BGP_TIMER_OFF (peer->t_gr_stale);
|
||||
if (BGP_DEBUG (events, EVENTS))
|
||||
zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
|
||||
}
|
||||
bgp_clear_route_all (peer);
|
||||
}
|
||||
|
||||
/* Delete peer from confguration. */
|
||||
int
|
||||
peer_delete (struct peer *peer)
|
||||
@ -1052,6 +1080,9 @@ peer_delete (struct peer *peer)
|
||||
|
||||
bgp = peer->bgp;
|
||||
|
||||
if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
|
||||
peer_nsf_stop (peer);
|
||||
|
||||
/* If this peer belongs to peer group. Clearn up the
|
||||
relationship. */
|
||||
if (peer->group)
|
||||
@ -1075,6 +1106,8 @@ peer_delete (struct peer *peer)
|
||||
BGP_TIMER_OFF (peer->t_asorig);
|
||||
BGP_TIMER_OFF (peer->t_routeadv);
|
||||
BGP_TIMER_OFF (peer->t_pmax_restart);
|
||||
BGP_TIMER_OFF (peer->t_gr_restart);
|
||||
BGP_TIMER_OFF (peer->t_gr_stale);
|
||||
|
||||
/* Delete from all peer list. */
|
||||
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
|
||||
@ -2148,6 +2181,9 @@ peer_flag_modify_action (struct peer *peer, u_int32_t flag)
|
||||
{
|
||||
if (CHECK_FLAG (peer->flags, flag))
|
||||
{
|
||||
if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
|
||||
peer_nsf_stop (peer);
|
||||
|
||||
UNSET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
|
||||
if (peer->t_pmax_restart)
|
||||
{
|
||||
@ -2157,6 +2193,9 @@ peer_flag_modify_action (struct peer *peer, u_int32_t flag)
|
||||
peer->host);
|
||||
}
|
||||
|
||||
if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
|
||||
peer_nsf_stop (peer);
|
||||
|
||||
if (peer->status == Established)
|
||||
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
|
||||
BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
|
||||
@ -4703,6 +4742,9 @@ bgp_config_write (struct vty *vty)
|
||||
vty_out (vty, " bgp deterministic-med%s", VTY_NEWLINE);
|
||||
|
||||
/* BGP graceful-restart. */
|
||||
if (bgp->stalepath_time != BGP_DEFAULT_STALEPATH_TIME)
|
||||
vty_out (vty, " bgp graceful-restart stalepath-time %d%s",
|
||||
bgp->stalepath_time, VTY_NEWLINE);
|
||||
if (bgp_flag_check (bgp, BGP_FLAG_GRACEFUL_RESTART))
|
||||
vty_out (vty, " bgp graceful-restart%s", VTY_NEWLINE);
|
||||
|
||||
|
23
bgpd/bgpd.h
23
bgpd/bgpd.h
@ -142,8 +142,8 @@ struct bgp
|
||||
u_int32_t default_keepalive;
|
||||
|
||||
/* BGP graceful restart */
|
||||
u_int16_t restart_time;
|
||||
u_int16_t stalepath_time;
|
||||
u_int32_t restart_time;
|
||||
u_int32_t stalepath_time;
|
||||
};
|
||||
|
||||
/* BGP peer-group support. */
|
||||
@ -318,10 +318,8 @@ struct peer
|
||||
#define PEER_CAP_ORF_PREFIX_RM_RCV (1 << 3) /* receive-mode received */
|
||||
#define PEER_CAP_ORF_PREFIX_SM_OLD_RCV (1 << 4) /* send-mode received */
|
||||
#define PEER_CAP_ORF_PREFIX_RM_OLD_RCV (1 << 5) /* receive-mode received */
|
||||
#define PEER_CAP_RESTART_AF_RCV (1 << 6) /* graceful restart received */
|
||||
|
||||
/* Gracefull Restart */
|
||||
u_int16_t restart_time_rcv;
|
||||
#define PEER_CAP_RESTART_AF_RCV (1 << 6) /* graceful restart afi/safi received */
|
||||
#define PEER_CAP_RESTART_AF_PRESERVE_RCV (1 << 7) /* graceful restart afi/safi F-bit received */
|
||||
|
||||
/* Global configuration flags. */
|
||||
u_int32_t flags;
|
||||
@ -334,6 +332,9 @@ struct peer
|
||||
#define PEER_FLAG_ENFORCE_MULTIHOP (1 << 6) /* enforce-multihop */
|
||||
#define PEER_FLAG_LOCAL_AS_NO_PREPEND (1 << 7) /* local-as no-prepend */
|
||||
|
||||
/* NSF mode (graceful restart) */
|
||||
u_char nsf[AFI_MAX][SAFI_MAX];
|
||||
|
||||
/* Per AF configuration flags. */
|
||||
u_int32_t af_flags[AFI_MAX][SAFI_MAX];
|
||||
#define PEER_FLAG_SEND_COMMUNITY (1 << 0) /* send-community */
|
||||
@ -368,6 +369,8 @@ struct peer
|
||||
#define PEER_STATUS_CAPABILITY_OPEN (1 << 2) /* capability open send */
|
||||
#define PEER_STATUS_HAVE_ACCEPT (1 << 3) /* accept peer's parent */
|
||||
#define PEER_STATUS_GROUP (1 << 4) /* peer-group conf */
|
||||
#define PEER_STATUS_NSF_MODE (1 << 5) /* NSF aware peer */
|
||||
#define PEER_STATUS_NSF_WAIT (1 << 6) /* wait comeback peer */
|
||||
|
||||
/* Peer status af flags (reset in bgp_stop) */
|
||||
u_int16_t af_sflags[AFI_MAX][SAFI_MAX];
|
||||
@ -376,6 +379,8 @@ struct peer
|
||||
#define PEER_STATUS_DEFAULT_ORIGINATE (1 << 2) /* default-originate peer */
|
||||
#define PEER_STATUS_PREFIX_THRESHOLD (1 << 3) /* exceed prefix-threshold */
|
||||
#define PEER_STATUS_PREFIX_LIMIT (1 << 4) /* exceed prefix-limit */
|
||||
#define PEER_STATUS_EOR_SEND (1 << 5) /* end-of-rib send to peer */
|
||||
#define PEER_STATUS_EOR_RECEIVED (1 << 6) /* end-of-rib received from peer */
|
||||
|
||||
|
||||
/* Default attribute value for the peer. */
|
||||
@ -398,6 +403,7 @@ struct peer
|
||||
u_int32_t v_asorig;
|
||||
u_int32_t v_routeadv;
|
||||
u_int32_t v_pmax_restart;
|
||||
u_int32_t v_gr_restart;
|
||||
|
||||
/* Threads. */
|
||||
struct thread *t_read;
|
||||
@ -409,6 +415,8 @@ struct peer
|
||||
struct thread *t_asorig;
|
||||
struct thread *t_routeadv;
|
||||
struct thread *t_pmax_restart;
|
||||
struct thread *t_gr_restart;
|
||||
struct thread *t_gr_stale;
|
||||
|
||||
/* Statistics field */
|
||||
u_int32_t open_in; /* Open message input count */
|
||||
@ -486,6 +494,7 @@ struct peer
|
||||
#define PEER_DOWN_CAPABILITY_CHANGE 19 /* neighbor capability command */
|
||||
#define PEER_DOWN_PASSIVE_CHANGE 20 /* neighbor passive command */
|
||||
#define PEER_DOWN_MULTIHOP_CHANGE 21 /* neighbor multihop command */
|
||||
#define PEER_DOWN_NSF_CLOSE_SESSION 22 /* NSF tcp session close */
|
||||
|
||||
/* The kind of route-map Flags.*/
|
||||
u_char rmap_type;
|
||||
@ -893,3 +902,5 @@ int peer_maximum_prefix_unset (struct peer *, afi_t, safi_t);
|
||||
|
||||
int peer_clear (struct peer *);
|
||||
int peer_clear_soft (struct peer *, afi_t, safi_t, enum bgp_clear_type);
|
||||
|
||||
void peer_nsf_stop (struct peer *);
|
||||
|
Loading…
Reference in New Issue
Block a user