}
/* neighbor shutdown. */
-DEFUN (neighbor_shutdown,
- neighbor_shutdown_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> shutdown",
+DEFUN (neighbor_shutdown_msg,
+ neighbor_shutdown_msg_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> shutdown message MSG...",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Administratively shut down this neighbor\n")
+ "Administratively shut down this neighbor\n"
+ "Add a shutdown message (draft-ietf-idr-shutdown-06)\n"
+ "Shutdown message\n")
{
int idx_peer = 1;
+
+ if (argc >= 5)
+ {
+ struct peer *peer = peer_lookup_vty (vty, argv[idx_peer]->arg);
+ char *message;
+
+ message = argv_concat (argv, argc, 4);
+ peer_tx_shutdown_message_set (peer, message);
+ XFREE (MTYPE_TMP, message);
+ }
+
return peer_flag_set_vty (vty, argv[idx_peer]->arg, PEER_FLAG_SHUTDOWN);
}
-DEFUN (no_neighbor_shutdown,
- no_neighbor_shutdown_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> shutdown",
- NO_STR
+ALIAS (neighbor_shutdown_msg,
+ neighbor_shutdown_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> shutdown",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Administratively shut down this neighbor\n")
+
+DEFUN (no_neighbor_shutdown_msg,
+ no_neighbor_shutdown_msg_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> shutdown message MSG...",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Administratively shut down this neighbor\n"
+ "Remove a shutdown message (draft-ietf-idr-shutdown-06)\n"
+ "Shutdown message\n")
{
int idx_peer = 2;
+
+ struct peer *peer = peer_lookup_vty (vty, argv[idx_peer]->arg);
+ peer_tx_shutdown_message_unset (peer);
+
return peer_flag_unset_vty (vty, argv[idx_peer]->arg, PEER_FLAG_SHUTDOWN);
}
+ALIAS (no_neighbor_shutdown_msg,
+ no_neighbor_shutdown_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> shutdown",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Administratively shut down this neighbor\n")
+
/* neighbor capability dynamic. */
DEFUN (neighbor_capability_dynamic,
neighbor_capability_dynamic_cmd,
/* "neighbor shutdown" commands. */
install_element (BGP_NODE, &neighbor_shutdown_cmd);
install_element (BGP_NODE, &no_neighbor_shutdown_cmd);
+ install_element (BGP_NODE, &neighbor_shutdown_msg_cmd);
+ install_element (BGP_NODE, &no_neighbor_shutdown_msg_cmd);
/* "neighbor capability extended-nexthop" commands.*/
install_element (BGP_NODE, &neighbor_capability_enhe_cmd);
#include "bgpd/bgp_memory.h"
#include "bgpd/bgp_evpn_vty.h"
+
+DEFINE_MTYPE_STATIC(BGPD, PEER_TX_SHUTDOWN_MSG, "Peer shutdown message (TX)");
DEFINE_QOBJ_TYPE(bgp_master)
DEFINE_QOBJ_TYPE(bgp)
DEFINE_QOBJ_TYPE(peer)
!peer_dynamic_neighbor (peer))
bgp_delete_connected_nexthop (family2afi(peer->su.sa.sa_family), peer);
+ XFREE (MTYPE_PEER_TX_SHUTDOWN_MSG, peer->tx_shutdown_message);
+
if (peer->desc)
{
XFREE (MTYPE_PEER_DESC, peer->desc);
peer_nsf_stop (peer);
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
- bgp_notify_send (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
+ {
+ char *msg = peer->tx_shutdown_message;
+ size_t msglen;
+
+ if (!msg && peer_group_active (peer))
+ msg = peer->group->conf->tx_shutdown_message;
+ msglen = msg ? strlen(msg) : 0;
+ if (msglen > 128)
+ msglen = 128;
+
+ u_char msgbuf[129];
+
+ msgbuf[0] = msglen;
+ memcpy(msgbuf + 1, msg, msglen);
+
+ bgp_notify_send_with_data (peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN,
+ msgbuf, msglen + 1);
+ }
else
bgp_session_reset(peer);
}
return peer_af_flag_modify (peer, afi, safi, flag, 0);
}
+
+int peer_tx_shutdown_message_set (struct peer *peer, const char *msg)
+{
+ XFREE (MTYPE_PEER_TX_SHUTDOWN_MSG, peer->tx_shutdown_message);
+ peer->tx_shutdown_message = msg ? XSTRDUP (MTYPE_PEER_TX_SHUTDOWN_MSG, msg) : NULL;
+ return 0;
+}
+
+int peer_tx_shutdown_message_unset (struct peer *peer)
+{
+ XFREE (MTYPE_PEER_TX_SHUTDOWN_MSG, peer->tx_shutdown_message);
+ return 0;
+}
+
+
/* EBGP multihop configuration. */
int
peer_ebgp_multihop_set (struct peer *peer, int ttl)
if (CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
{
if (! peer_group_active (peer) ||
- ! CHECK_FLAG (g_peer->flags, PEER_FLAG_SHUTDOWN))
+ ! CHECK_FLAG (g_peer->flags, PEER_FLAG_SHUTDOWN) ||
+ peer->tx_shutdown_message)
{
- vty_out (vty, " neighbor %s shutdown%s", addr, VTY_NEWLINE);
+ if (peer->tx_shutdown_message)
+ vty_out (vty, " neighbor %s shutdown message %s%s", addr,
+ peer->tx_shutdown_message, VTY_NEWLINE);
+ else
+ vty_out (vty, " neighbor %s shutdown%s", addr, VTY_NEWLINE);
}
}
#if ENABLE_BGP_VNC
#define PEER_FLAG_IS_RFAPI_HD (1 << 15) /* attached to rfapi HD */
#endif
+ /* outgoing message sent in CEASE_ADMIN_SHUTDOWN notify */
+ char *tx_shutdown_message;
/* NSF mode (graceful restart) */
u_char nsf[AFI_MAX][SAFI_MAX];
extern int peer_ttl_security_hops_set (struct peer *, int);
extern int peer_ttl_security_hops_unset (struct peer *);
+extern int peer_tx_shutdown_message_set (struct peer *, const char *msg);
+extern int peer_tx_shutdown_message_unset (struct peer *);
+
extern int bgp_route_map_update_timer (struct thread *thread);
extern void bgp_route_map_terminate(void);