From: David Lamparter Date: Wed, 25 Jan 2017 02:30:52 +0000 (+0100) Subject: bgpd: TX shutdown message X-Git-Tag: frr-3.0-branchpoint~3^2~2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=73d70fa68a59b49c625bb4d5b69b60eaa31d294e;p=matthieu%2Ffrr.git bgpd: TX shutdown message Signed-off-by: Christian Franke --- diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 5472472060..7b71caf98b 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -3409,29 +3409,63 @@ DEFUN (no_neighbor_passive, } /* neighbor shutdown. */ -DEFUN (neighbor_shutdown, - neighbor_shutdown_cmd, - "neighbor shutdown", +DEFUN (neighbor_shutdown_msg, + neighbor_shutdown_msg_cmd, + "neighbor 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 shutdown", - NO_STR +ALIAS (neighbor_shutdown_msg, + neighbor_shutdown_cmd, + "neighbor shutdown", NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "Administratively shut down this neighbor\n") + +DEFUN (no_neighbor_shutdown_msg, + no_neighbor_shutdown_msg_cmd, + "no neighbor 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 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, @@ -10589,6 +10623,8 @@ bgp_vty_init (void) /* "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); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 5592749b28..745b86c4ee 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -80,6 +80,8 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #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) @@ -1071,6 +1073,8 @@ peer_free (struct peer *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); @@ -3811,8 +3815,25 @@ peer_flag_modify_action (struct peer *peer, u_int32_t flag) 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); } @@ -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); } + +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) @@ -6615,9 +6651,14 @@ bgp_config_write_peer_global (struct vty *vty, struct bgp *bgp, 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); } } diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 87d8288cfd..b0b28590cb 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -675,6 +675,8 @@ struct peer #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]; @@ -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_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);