bgpd: TX shutdown message

Signed-off-by: Christian Franke <chris@opensourcerouting.org>
This commit is contained in:
David Lamparter 2017-01-25 03:30:52 +01:00 committed by Donald Sharp
parent 38de8d0229
commit 73d70fa68a
3 changed files with 94 additions and 12 deletions

View File

@ -3409,28 +3409,62 @@ DEFUN (no_neighbor_passive,
} }
/* neighbor shutdown. */ /* neighbor shutdown. */
DEFUN (neighbor_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"
"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);
}
ALIAS (neighbor_shutdown_msg,
neighbor_shutdown_cmd, neighbor_shutdown_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> shutdown", "neighbor <A.B.C.D|X:X::X:X|WORD> shutdown",
NEIGHBOR_STR NEIGHBOR_STR
NEIGHBOR_ADDR_STR2 NEIGHBOR_ADDR_STR2
"Administratively shut down this neighbor\n") "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 = 1; int idx_peer = 2;
return peer_flag_set_vty (vty, argv[idx_peer]->arg, PEER_FLAG_SHUTDOWN);
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);
} }
DEFUN (no_neighbor_shutdown, ALIAS (no_neighbor_shutdown_msg,
no_neighbor_shutdown_cmd, no_neighbor_shutdown_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> shutdown", "no neighbor <A.B.C.D|X:X::X:X|WORD> shutdown",
NO_STR NO_STR
NEIGHBOR_STR NEIGHBOR_STR
NEIGHBOR_ADDR_STR2 NEIGHBOR_ADDR_STR2
"Administratively shut down this neighbor\n") "Administratively shut down this neighbor\n")
{
int idx_peer = 2;
return peer_flag_unset_vty (vty, argv[idx_peer]->arg, PEER_FLAG_SHUTDOWN);
}
/* neighbor capability dynamic. */ /* neighbor capability dynamic. */
DEFUN (neighbor_capability_dynamic, DEFUN (neighbor_capability_dynamic,
@ -10589,6 +10623,8 @@ bgp_vty_init (void)
/* "neighbor shutdown" commands. */ /* "neighbor shutdown" commands. */
install_element (BGP_NODE, &neighbor_shutdown_cmd); install_element (BGP_NODE, &neighbor_shutdown_cmd);
install_element (BGP_NODE, &no_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.*/ /* "neighbor capability extended-nexthop" commands.*/
install_element (BGP_NODE, &neighbor_capability_enhe_cmd); install_element (BGP_NODE, &neighbor_capability_enhe_cmd);

View File

@ -80,6 +80,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_memory.h" #include "bgpd/bgp_memory.h"
#include "bgpd/bgp_evpn_vty.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_master)
DEFINE_QOBJ_TYPE(bgp) DEFINE_QOBJ_TYPE(bgp)
DEFINE_QOBJ_TYPE(peer) DEFINE_QOBJ_TYPE(peer)
@ -1071,6 +1073,8 @@ peer_free (struct peer *peer)
!peer_dynamic_neighbor (peer)) !peer_dynamic_neighbor (peer))
bgp_delete_connected_nexthop (family2afi(peer->su.sa.sa_family), 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) if (peer->desc)
{ {
XFREE (MTYPE_PEER_DESC, peer->desc); XFREE (MTYPE_PEER_DESC, peer->desc);
@ -3811,8 +3815,25 @@ peer_flag_modify_action (struct peer *peer, u_int32_t flag)
peer_nsf_stop (peer); peer_nsf_stop (peer);
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) 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 else
bgp_session_reset(peer); bgp_session_reset(peer);
} }
@ -4094,6 +4115,21 @@ peer_af_flag_unset (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
return peer_af_flag_modify (peer, afi, safi, flag, 0); 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. */ /* EBGP multihop configuration. */
int int
peer_ebgp_multihop_set (struct peer *peer, int ttl) peer_ebgp_multihop_set (struct peer *peer, int ttl)
@ -6615,9 +6651,14 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp,
if (CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN)) if (CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
{ {
if (! peer_group_active (peer) || 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);
} }
} }

View File

@ -675,6 +675,8 @@ struct peer
#if ENABLE_BGP_VNC #if ENABLE_BGP_VNC
#define PEER_FLAG_IS_RFAPI_HD (1 << 15) /* attached to rfapi HD */ #define PEER_FLAG_IS_RFAPI_HD (1 << 15) /* attached to rfapi HD */
#endif #endif
/* outgoing message sent in CEASE_ADMIN_SHUTDOWN notify */
char *tx_shutdown_message;
/* NSF mode (graceful restart) */ /* NSF mode (graceful restart) */
u_char nsf[AFI_MAX][SAFI_MAX]; u_char nsf[AFI_MAX][SAFI_MAX];
@ -1354,6 +1356,9 @@ extern int peer_clear_soft (struct peer *, afi_t, safi_t, enum bgp_clear_type);
extern int peer_ttl_security_hops_set (struct peer *, int); extern int peer_ttl_security_hops_set (struct peer *, int);
extern int peer_ttl_security_hops_unset (struct peer *); 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 int bgp_route_map_update_timer (struct thread *thread);
extern void bgp_route_map_terminate(void); extern void bgp_route_map_terminate(void);