+2005-05-20 Kunihiro Ishiguro <kunihiro@ipinfusion.com>
+
+ * *: Maximum prefix threshold support.
+ * *: Reset notification fixups.
+
2004-05-08 Paul Jakma <paul@dishone.st>
* bgp_zebra.c: (bgp_interface_address_add) sync to zclient changes
as_list_delete (aslist);
+ /* Run hook function. */
+ if (as_list_master.delete_hook)
+ (*as_list_master.delete_hook) ();
+
return CMD_SUCCESS;
}
peer->uptime = time (NULL);
}
+/* BGP Peer Down Cause */
+char *peer_down_str[] =
+{
+ "",
+ "Router ID changed",
+ "Remote AS changed",
+ "Local AS change",
+ "Cluster ID changed",
+ "Confederation identifier changed",
+ "Confederation peer changed",
+ "RR client config change",
+ "RS client config change",
+ "Update source change",
+ "Address family activated",
+ "Admin. shutdown",
+ "User reset",
+ "BGP Notification received",
+ "BGP Notification send",
+ "Peer closed the session",
+ "Neighbor deleted",
+ "Peer-group add member",
+ "Peer-group delete member",
+ "Capability changed",
+ "Passive config change",
+ "Multihop config change"
+};
+
/* Administrative BGP peer stop event. */
int
bgp_stop (struct peer *peer)
/* bgp log-neighbor-changes of neighbor Down */
if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
- zlog_info ("%%ADJCHANGE: neighbor %s Down", peer->host);
+ zlog_info ("%%ADJCHANGE: neighbor %s Down %s", peer->host,
+ peer_down_str [(int) peer->last_reset]);
/* set last reset time */
peer->resettime = time (NULL);
int bgp_stop (struct peer *peer);
void bgp_timer_set (struct peer *);
void bgp_fsm_change_status (struct peer *peer, int status);
+extern char *peer_down_str[];
continue;
if (peer->afc[AFI_IP][SAFI_UNICAST])
- bgp_maximum_prefix_overflow (peer, AFI_IP, SAFI_UNICAST);
+ bgp_maximum_prefix_overflow (peer, AFI_IP, SAFI_UNICAST, 1);
if (peer->afc[AFI_IP][SAFI_MULTICAST])
- bgp_maximum_prefix_overflow (peer, AFI_IP, SAFI_MULTICAST);
+ bgp_maximum_prefix_overflow (peer, AFI_IP, SAFI_MULTICAST, 1);
if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
- bgp_maximum_prefix_overflow (peer, AFI_IP, SAFI_MPLS_VPN);
+ bgp_maximum_prefix_overflow (peer, AFI_IP, SAFI_MPLS_VPN, 1);
}
for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_UNICAST]); rn;
continue;
if (peer->afc[AFI_IP6][SAFI_UNICAST])
- bgp_maximum_prefix_overflow (peer, AFI_IP6, SAFI_UNICAST);
+ bgp_maximum_prefix_overflow (peer, AFI_IP6, SAFI_UNICAST, 1);
if (peer->afc[AFI_IP6][SAFI_MULTICAST])
- bgp_maximum_prefix_overflow (peer, AFI_IP6, SAFI_MULTICAST);
+ bgp_maximum_prefix_overflow (peer, AFI_IP6, SAFI_MULTICAST, 1);
}
for (rn = bgp_table_top (bgp->rib[AFI_IP6][SAFI_UNICAST]); rn;
zlog_info ("%s send message type %d, length (incl. header) %d",
peer->host, BGP_MSG_NOTIFY, length);
+ /* peer reset cause */
+ if (sub_code != BGP_NOTIFY_CEASE_CONFIG_CHANGE)
+ {
+ if (sub_code == BGP_NOTIFY_CEASE_ADMIN_RESET)
+ peer->last_reset = PEER_DOWN_USER_RESET;
+ else if (sub_code == BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN)
+ peer->last_reset = PEER_DOWN_USER_SHUTDOWN;
+ else
+ peer->last_reset = PEER_DOWN_NOTIFY_SEND;
+ }
+
/* Call imidiately. */
BGP_WRITE_OFF (peer->t_write);
connection initiated by the remote system. */
if (peer->fd >= 0)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
return 1;
}
else
OpenConfirm state). */
if (new->fd >= 0)
- bgp_notify_send (new, BGP_NOTIFY_CEASE, 0);
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_COLLISION_RESOLUTION);
return -1;
}
}
/* peer count update */
peer->notify_in++;
+ if (peer->status == Established)
+ peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;
+
/* We have to check for Notify with Unsupported Optional Parameter.
in that case we fallback to open without the capability option.
But this done in bgp_stop. We just mark it here to avoid changing
if (BGP_DEBUG (events, EVENTS))
plog_info (peer->log, "%s [Event] BGP connection closed fd %d",
peer->host, peer->fd);
+
+ if (peer->status == Established)
+ peer->last_reset = PEER_DOWN_CLOSE_SESSION;
+
BGP_EVENT_ADD (peer, TCP_connection_closed);
return -1;
}
}
int
-bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi, safi_t safi)
+bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi, safi_t safi, int always)
{
- if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
+ if (!CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
+ return 0;
+
+ if (peer->pcount[afi][safi] > peer->pmax[afi][safi])
{
- if (peer->pcount[afi][safi] > peer->pmax[afi][safi])
- {
- zlog (peer->log, LOG_INFO,
- "MAXPFXEXCEED: No. of prefix received from %s (afi %d): %ld exceed limit %ld", peer->host, afi, peer->pcount[afi][safi], peer->pmax[afi][safi]);
- if (! CHECK_FLAG (peer->af_flags[afi][safi],
- PEER_FLAG_MAX_PREFIX_WARNING))
- {
- char ndata[7];
-
- ndata[0] = (u_char)(afi >> 8);
- ndata[1] = (u_char) afi;
- ndata[3] = (u_char)(peer->pmax[afi][safi] >> 24);
- ndata[4] = (u_char)(peer->pmax[afi][safi] >> 16);
- ndata[5] = (u_char)(peer->pmax[afi][safi] >> 8);
- ndata[6] = (u_char)(peer->pmax[afi][safi]);
-
- if (safi == SAFI_MPLS_VPN)
- safi = BGP_SAFI_VPNV4;
- ndata[2] = (u_char) safi;
-
- SET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
- bgp_notify_send_with_data (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_MAX_PREFIX,
- ndata, 7);
- return 1;
- }
- }
+ if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT)
+ && ! always)
+ return 0;
+
+ zlog (peer->log, LOG_INFO,
+ "%%MAXPFXEXCEED: No. of prefix received from %s (afi %d): %ld exceed limit %ld",
+ peer->host, afi, peer->pcount[afi][safi], peer->pmax[afi][safi]);
+ SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
+
+ if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
+ return 0;
+
+ {
+ char ndata[7];
+
+ ndata[0] = (u_char)(afi >> 8);
+ ndata[1] = (u_char) afi;
+ ndata[3] = (u_char)(peer->pmax[afi][safi] >> 24);
+ ndata[4] = (u_char)(peer->pmax[afi][safi] >> 16);
+ ndata[5] = (u_char)(peer->pmax[afi][safi] >> 8);
+ ndata[6] = (u_char)(peer->pmax[afi][safi]);
+
+ if (safi == SAFI_MPLS_VPN)
+ safi = BGP_SAFI_VPNV4;
+ ndata[2] = (u_char) safi;
+
+ SET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
+ bgp_notify_send_with_data (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_MAX_PREFIX, ndata, 7);
+ }
+ return 1;
}
+ else
+ UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
+
+ if (peer->pcount[afi][safi] > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100))
+ {
+ if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_THRESHOLD)
+ && ! always)
+ return 0;
+
+ zlog (peer->log, LOG_INFO,
+ "%%MAXPFX: No. of prefix received from %s (afi %d) reaches %ld, max %ld",
+ peer->host, afi, peer->pcount[afi][safi], peer->pmax[afi][safi]);
+ SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_THRESHOLD);
+ }
+ else
+ UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_THRESHOLD);
return 0;
}
/* If maximum prefix count is configured and current prefix
count exeed it. */
- if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
- if (bgp_maximum_prefix_overflow (peer, afi, safi))
- return -1;
+ if (bgp_maximum_prefix_overflow (peer, afi, safi, 0))
+ return -1;
/* Process change. */
bgp_process (bgp, rn, afi, safi);
int bgp_nlri_sanity_check (struct peer *, int, u_char *, bgp_size_t);
int bgp_nlri_parse (struct peer *, struct attr *, struct bgp_nlri *);
-int bgp_maximum_prefix_overflow (struct peer *, afi_t, safi_t);
+int bgp_maximum_prefix_overflow (struct peer *, afi_t, safi_t, int);
void bgp_redistribute_add (struct prefix *, struct in_addr *, u_int32_t, u_char);
void bgp_redistribute_delete (struct prefix *, u_char);
#include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_community.h"
#include "bgpd/bgp_debug.h"
+#include "bgpd/bgp_fsm.h"
#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_open.h"
#include "bgpd/bgp_route.h"
\f
int
peer_maximum_prefix_set_vty (struct vty *vty, char *ip_str, afi_t afi,
- safi_t safi, char *num_str, int warning)
+ safi_t safi, char *num_str, char *threshold_str,
+ int warning)
{
int ret;
struct peer *peer;
u_int32_t max;
+ u_char threshold;
peer = peer_and_group_lookup_vty (vty, ip_str);
if (! peer)
return CMD_WARNING;
VTY_GET_INTEGER ("maxmum number", max, num_str);
+ if (threshold_str)
+ threshold = atoi (threshold_str);
+ else
+ threshold = MAXIMUM_PREFIX_THRESHOLD_DEFAULT;
- ret = peer_maximum_prefix_set (peer, afi, safi, max, warning);
+ ret = peer_maximum_prefix_set (peer, afi, safi, max, threshold, warning);
return bgp_vty_return (vty, ret);
}
"maximum no. of prefix limit\n")
{
return peer_maximum_prefix_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), argv[1], 0);
+ bgp_node_safi (vty), argv[1], NULL, 0);
}
+DEFUN (neighbor_maximum_prefix_threshold,
+ neighbor_maximum_prefix_threshold_cmd,
+ NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> <1-100>",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Maximum number of prefix accept from this peer\n"
+ "maximum no. of prefix limit\n"
+ "Threshold value (%) at which to generate a warning msg\n")
+{
+ return peer_maximum_prefix_set_vty (vty, argv[0], bgp_node_afi (vty),
+ bgp_node_safi (vty), argv[1], argv[2], 0);
+ }
+
DEFUN (neighbor_maximum_prefix_warning,
neighbor_maximum_prefix_warning_cmd,
NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> warning-only",
"Only give warning message when limit is exceeded\n")
{
return peer_maximum_prefix_set_vty (vty, argv[0], bgp_node_afi (vty),
- bgp_node_safi (vty), argv[1], 1);
+ bgp_node_safi (vty), argv[1], NULL, 1);
}
+DEFUN (neighbor_maximum_prefix_threshold_warning,
+ neighbor_maximum_prefix_threshold_warning_cmd,
+ NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> <1-100> warning-only",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Maximum number of prefix accept from this peer\n"
+ "maximum no. of prefix limit\n"
+ "Threshold value (%) at which to generate a warning msg\n"
+ "Only give warning message when limit is exceeded\n")
+{
+ return peer_maximum_prefix_set_vty (vty, argv[0], bgp_node_afi (vty),
+ bgp_node_safi (vty), argv[1], argv[2], 1);
+ }
+
DEFUN (no_neighbor_maximum_prefix,
no_neighbor_maximum_prefix_cmd,
NO_NEIGHBOR_CMD2 "maximum-prefix",
ALIAS (no_neighbor_maximum_prefix,
no_neighbor_maximum_prefix_val2_cmd,
+ NO_NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> <1-100> warning-only",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Maximum number of prefix accept from this peer\n"
+ "maximum no. of prefix limit\n"
+ "Threshold value (%) at which to generate a warning msg\n"
+ "Only give warning message when limit is exceeded\n")
+
+ALIAS (no_neighbor_maximum_prefix,
+ no_neighbor_maximum_prefix_val3_cmd,
NO_NEIGHBOR_CMD2 "maximum-prefix <1-4294967295> warning-only",
NO_STR
NEIGHBOR_STR
filter->usmap.name, VTY_NEWLINE);
/* Receive prefix count */
- vty_out (vty, " %ld accepted prefixes",
- p->pcount[afi][safi]);
+ vty_out (vty, " %ld accepted prefixes%s", p->pcount[afi][safi], VTY_NEWLINE);
+
/* Maximum prefix */
if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
{
- vty_out (vty, ", maximum limit %ld%s",
- p->pmax[afi][safi],
+ vty_out (vty, " maximum limit %ld%s%s", p->pmax[afi][safi],
CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING)
- ? " (warning-only)" : "");
+ ? " (warning-only)" : "", VTY_NEWLINE);
+ vty_out (vty, " Threshold for warning message %d%%%s", p->pmax_threshold [afi][safi],
+ VTY_NEWLINE);
}
- vty_out (vty, "%s", VTY_NEWLINE);
vty_out (vty, "%s", VTY_NEWLINE);
}
VTY_NEWLINE);
/* Confederation */
- if (bgp_confederation_peers_check (bgp, p->as))
+ if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION)
+ && bgp_confederation_peers_check (bgp, p->as))
vty_out (vty, " Neighbor under common administration%s", VTY_NEWLINE);
/* Status. */
p->established, p->dropped,
VTY_NEWLINE);
- vty_out (vty, " Last reset %s%s", p->dropped ? peer_uptime (p->resettime, timebuf, BGP_UPTIME_LEN) : "never",
- VTY_NEWLINE);
+ if (! p->dropped)
+ vty_out (vty, " Last reset never%s", VTY_NEWLINE);
+ else
+ vty_out (vty, " Last reset %s, due to %s%s",
+ peer_uptime (p->resettime, timebuf, BGP_UPTIME_LEN),
+ peer_down_str[(int) p->last_reset], VTY_NEWLINE);
if (CHECK_FLAG (p->sflags, PEER_STATUS_PREFIX_OVERFLOW))
{
/* "neighbor maximum-prefix" commands. */
install_element (BGP_NODE, &neighbor_maximum_prefix_cmd);
+ install_element (BGP_NODE, &neighbor_maximum_prefix_threshold_cmd);
install_element (BGP_NODE, &neighbor_maximum_prefix_warning_cmd);
+ install_element (BGP_NODE, &neighbor_maximum_prefix_threshold_warning_cmd);
install_element (BGP_NODE, &no_neighbor_maximum_prefix_cmd);
install_element (BGP_NODE, &no_neighbor_maximum_prefix_val_cmd);
install_element (BGP_NODE, &no_neighbor_maximum_prefix_val2_cmd);
+ install_element (BGP_NODE, &no_neighbor_maximum_prefix_val3_cmd);
install_element (BGP_IPV4_NODE, &neighbor_maximum_prefix_cmd);
+ install_element (BGP_IPV4_NODE, &neighbor_maximum_prefix_threshold_cmd);
install_element (BGP_IPV4_NODE, &neighbor_maximum_prefix_warning_cmd);
+ install_element (BGP_IPV4_NODE, &neighbor_maximum_prefix_threshold_warning_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_maximum_prefix_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_maximum_prefix_val_cmd);
install_element (BGP_IPV4_NODE, &no_neighbor_maximum_prefix_val2_cmd);
+ install_element (BGP_IPV4_NODE, &no_neighbor_maximum_prefix_val3_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_maximum_prefix_cmd);
+ install_element (BGP_IPV4M_NODE, &neighbor_maximum_prefix_threshold_cmd);
install_element (BGP_IPV4M_NODE, &neighbor_maximum_prefix_warning_cmd);
+ install_element (BGP_IPV4M_NODE, &neighbor_maximum_prefix_threshold_warning_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_maximum_prefix_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_maximum_prefix_val_cmd);
install_element (BGP_IPV4M_NODE, &no_neighbor_maximum_prefix_val2_cmd);
+ install_element (BGP_IPV4M_NODE, &no_neighbor_maximum_prefix_val3_cmd);
install_element (BGP_IPV6_NODE, &neighbor_maximum_prefix_cmd);
+ install_element (BGP_IPV6_NODE, &neighbor_maximum_prefix_threshold_cmd);
install_element (BGP_IPV6_NODE, &neighbor_maximum_prefix_warning_cmd);
+ install_element (BGP_IPV6_NODE, &neighbor_maximum_prefix_threshold_warning_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_maximum_prefix_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_maximum_prefix_val_cmd);
install_element (BGP_IPV6_NODE, &no_neighbor_maximum_prefix_val2_cmd);
+ install_element (BGP_IPV6_NODE, &no_neighbor_maximum_prefix_val3_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_maximum_prefix_cmd);
+ install_element (BGP_VPNV4_NODE, &neighbor_maximum_prefix_threshold_cmd);
install_element (BGP_VPNV4_NODE, &neighbor_maximum_prefix_warning_cmd);
+ install_element (BGP_VPNV4_NODE, &neighbor_maximum_prefix_threshold_warning_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_maximum_prefix_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_maximum_prefix_val_cmd);
install_element (BGP_VPNV4_NODE, &no_neighbor_maximum_prefix_val2_cmd);
+ install_element (BGP_VPNV4_NODE, &no_neighbor_maximum_prefix_val3_cmd);
/* "neighbor allowas-in" */
install_element (BGP_NODE, &neighbor_allowas_in_cmd);
IPV4_ADDR_COPY (&peer->local_id, id);
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_RID_CHANGE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
}
return 0;
}
LIST_LOOP (bgp->peer, peer, nn)
{
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_RID_CHANGE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
}
return 0;
continue;
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_CLID_CHANGE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
}
return 0;
}
continue;
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_CLID_CHANGE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
}
return 0;
}
{
peer->local_as = as;
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
+
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
if (peer_sort (peer) == BGP_PEER_EBGP)
peer->local_as = as;
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
{
peer->local_as = bgp->as;
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
+
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
{
peer->local_as = bgp->as;
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
{
peer->local_as = bgp->confed_id;
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
/* Clear neighbor maximum-prefix */
peer->pmax[afi][safi] = 0;
+ peer->pmax_threshold[afi][safi] = MAXIMUM_PREFIX_THRESHOLD_DEFAULT;
}
/* peer global config reset */
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_REMOTE_AS_CHANGE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
}
}
else
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_AF_ACTIVATE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
}
}
}
peer->pcount[afi][safi] = 0;
}
else
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
}
else
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
}
}
return 0;
/* Withdraw all information from routing table. We can not use
BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
executed after peer structure is deleted. */
+ peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
bgp_stop (peer);
bgp_fsm_change_status (peer, Idle);
/* maximum-prefix */
peer->pmax[afi][safi] = conf->pmax[afi][safi];
+ peer->pmax_threshold[afi][safi] = conf->pmax_threshold[afi][safi];
/* allowas-in */
peer->allowas_in[afi][safi] = conf->allowas_in[afi][safi];
peer_group2peer_config_copy (group, peer, afi, safi);
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_RMAP_BIND;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_RMAP_UNBIND;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
else
BGP_EVENT_ADD (peer, BGP_Stop);
/* Action when the flag is changed. */
enum peer_change_type type;
+
+ /* Peer down cause */
+ u_char peer_down;
};
struct peer_flag_action peer_flag_action_list[] =
CAPABILITY_ACTION_UNSET : CAPABILITY_ACTION_SET);
}
else
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ if (flag == PEER_FLAG_NO_ROUTE_REFRESH_CAP)
+ peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
+ else if (flag == PEER_FLAG_DYNAMIC_CAPABILITY)
+ peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
+ else if (flag == PEER_FLAG_PASSIVE)
+ peer->last_reset = PEER_DOWN_PASSIVE_CHANGE;
+ else if (flag == PEER_FLAG_ENFORCE_MULTIHOP)
+ peer->last_reset = PEER_DOWN_MULTIHOP_CHANGE;
+
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
}
else
BGP_EVENT_ADD (peer, BGP_Stop);
if (! set && flag == PEER_FLAG_SOFT_RECONFIG)
bgp_clear_adj_in (peer, afi, safi);
else
- peer_change_action (peer, afi, safi, action.type);
+ {
+ if (flag == PEER_FLAG_REFLECTOR_CLIENT)
+ peer->last_reset = PEER_DOWN_RR_CLIENT_CHANGE;
+ else if (flag == PEER_FLAG_RSERVER_CLIENT)
+ peer->last_reset = PEER_DOWN_RS_CLIENT_CHANGE;
+ else if (flag == PEER_FLAG_ORF_PREFIX_SM)
+ peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
+ else if (flag == PEER_FLAG_ORF_PREFIX_RM)
+ peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
+
+ peer_change_action (peer, afi, safi, action.type);
+ }
+
}
/* Peer group member updates. */
if (! set && flag == PEER_FLAG_SOFT_RECONFIG)
bgp_clear_adj_in (peer, afi, safi);
else
- peer_change_action (peer, afi, safi, action.type);
+ {
+ if (flag == PEER_FLAG_REFLECTOR_CLIENT)
+ peer->last_reset = PEER_DOWN_RR_CLIENT_CHANGE;
+ else if (flag == PEER_FLAG_RSERVER_CLIENT)
+ peer->last_reset = PEER_DOWN_RS_CLIENT_CHANGE;
+ else if (flag == PEER_FLAG_ORF_PREFIX_SM)
+ peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
+ else if (flag == PEER_FLAG_ORF_PREFIX_RM)
+ peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
+
+ peer_change_action (peer, afi, safi, action.type);
+ }
}
}
}
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
else
BGP_EVENT_ADD (peer, BGP_Stop);
return 0;
peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, ifname);
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
else
BGP_EVENT_ADD (peer, BGP_Stop);
return 0;
peer->update_source = sockunion_dup (su);
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
else
BGP_EVENT_ADD (peer, BGP_Stop);
return 0;
}
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
else
BGP_EVENT_ADD (peer, BGP_Stop);
UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
else
BGP_EVENT_ADD (peer, BGP_Stop);
UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
if (peer->status == Established)
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ {
+ peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
\f
int
peer_maximum_prefix_set (struct peer *peer, afi_t afi, safi_t safi,
- u_int32_t max, int warning)
+ u_int32_t max, u_char threshold, int warning)
{
struct peer_group *group;
struct listnode *nn;
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
peer->pmax[afi][safi] = max;
+ peer->pmax_threshold[afi][safi] = threshold;
if (warning)
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
else
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
peer->pmax[afi][safi] = max;
+ peer->pmax_threshold[afi][safi] = threshold;
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);
peer->pmax[afi][safi] = peer->group->conf->pmax[afi][safi];
+ peer->pmax_threshold[afi][safi] = peer->group->conf->pmax_threshold[afi][safi];
return 0;
}
UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
peer->pmax[afi][safi] = 0;
+ peer->pmax_threshold[afi][safi] = MAXIMUM_PREFIX_THRESHOLD_DEFAULT;
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
peer->pmax[afi][safi] = 0;
+ peer->pmax_threshold[afi][safi] = MAXIMUM_PREFIX_THRESHOLD_DEFAULT;
}
return 0;
}
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
if (! peer->af_group[afi][safi]
|| g_peer->pmax[afi][safi] != peer->pmax[afi][safi]
+ || g_peer->pmax_threshold[afi][safi] != peer->pmax_threshold[afi][safi]
|| CHECK_FLAG (g_peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING)
!= CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
- vty_out (vty, " neighbor %s maximum-prefix %ld%s%s",
- addr, peer->pmax[afi][safi],
- CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING)
- ? " warning-only" : "", VTY_NEWLINE);
+ {
+ vty_out (vty, " neighbor %s maximum-prefix %ld", addr, peer->pmax[afi][safi]);
+ if (peer->pmax_threshold[afi][safi] != MAXIMUM_PREFIX_THRESHOLD_DEFAULT)
+ vty_out (vty, " %d", peer->pmax_threshold[afi][safi]);
+ if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
+ vty_out (vty, " warning-only");
+ vty_out (vty, "%s", VTY_NEWLINE);
+ }
/* Route server client. */
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
vty_out (vty, " bgp cluster-id %s%s", inet_ntoa (bgp->cluster_id),
VTY_NEWLINE);
- /* Confederation Information */
+ /* Confederation identifier*/
if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION))
+ vty_out (vty, " bgp confederation identifier %i%s", bgp->confed_id,
+ VTY_NEWLINE);
+
+ /* Confederation peer */
+ if (bgp->confed_peers_cnt > 0)
{
- vty_out (vty, " bgp confederation identifier %i%s", bgp->confed_id,
- VTY_NEWLINE);
- if (bgp->confed_peers_cnt > 0)
- {
- int i;
+ int i;
- vty_out (vty, " bgp confederation peers");
+ vty_out (vty, " bgp confederation peers");
- for (i = 0; i < bgp->confed_peers_cnt; i++)
- {
- vty_out(vty, " ");
- vty_out(vty, "%d", bgp->confed_peers[i]);
- }
+ for (i = 0; i < bgp->confed_peers_cnt; i++)
+ vty_out(vty, " %d", bgp->confed_peers[i]);
- vty_out (vty, "%s", VTY_NEWLINE);
- }
+ vty_out (vty, "%s", VTY_NEWLINE);
}
/* BGP enforce-first-as. */
#define PEER_STATUS_ORF_PREFIX_SEND (1 << 0) /* prefix-list send peer */
#define PEER_STATUS_ORF_WAIT_REFRESH (1 << 1) /* wait refresh received 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 */
+
/* Default attribute value for the peer. */
u_int32_t config;
/* Max prefix count. */
unsigned long pmax[AFI_MAX][SAFI_MAX];
+ u_char pmax_threshold[AFI_MAX][SAFI_MAX];
+#define MAXIMUM_PREFIX_THRESHOLD_DEFAULT 75
/* allowas-in. */
char allowas_in[AFI_MAX][SAFI_MAX];
+ /* peer reset cause */
+ char last_reset;
+#define PEER_DOWN_RID_CHANGE 1 /* bgp router-id command */
+#define PEER_DOWN_REMOTE_AS_CHANGE 2 /* neighbor remote-as command */
+#define PEER_DOWN_LOCAL_AS_CHANGE 3 /* neighbor local-as command */
+#define PEER_DOWN_CLID_CHANGE 4 /* bgp cluster-id command */
+#define PEER_DOWN_CONFED_ID_CHANGE 5 /* bgp confederation identifier command */
+#define PEER_DOWN_CONFED_PEER_CHANGE 6 /* bgp confederation peer command */
+#define PEER_DOWN_RR_CLIENT_CHANGE 7 /* neighbor route-reflector-client command */
+#define PEER_DOWN_RS_CLIENT_CHANGE 8 /* neighbor route-server-client command */
+#define PEER_DOWN_UPDATE_SOURCE_CHANGE 9 /* neighbor update-source command */
+#define PEER_DOWN_AF_ACTIVATE 10 /* neighbor activate command */
+#define PEER_DOWN_USER_SHUTDOWN 11 /* neighbor shutdown command */
+#define PEER_DOWN_USER_RESET 12 /* clear ip bgp command */
+#define PEER_DOWN_NOTIFY_RECEIVED 13 /* notification received */
+#define PEER_DOWN_NOTIFY_SEND 14 /* notification send */
+#define PEER_DOWN_CLOSE_SESSION 15 /* tcp session close */
+#define PEER_DOWN_NEIGHBOR_DELETE 16 /* neghbor delete */
+#define PEER_DOWN_RMAP_BIND 17 /* neghbor peer-group command */
+#define PEER_DOWN_RMAP_UNBIND 18 /* no neighbor peer-group command */
+#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 */
+
/* The kind of route-map Flags.*/
u_char rmap_type;
#define PEER_RMAP_TYPE_IN (1 << 0) /* neighbor route-map in */
int peer_unsuppress_map_set (struct peer *, afi_t, safi_t, char *);
int peer_unsuppress_map_unset (struct peer *, afi_t, safi_t);
-int peer_maximum_prefix_set (struct peer *, afi_t, safi_t, u_int32_t, int);
+int peer_maximum_prefix_set (struct peer *, afi_t, safi_t, u_int32_t, u_char, int);
int peer_maximum_prefix_unset (struct peer *, afi_t, safi_t);
int peer_clear (struct peer *);