]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: TX shutdown message
authorDavid Lamparter <equinox@opensourcerouting.org>
Wed, 25 Jan 2017 02:30:52 +0000 (03:30 +0100)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Tue, 7 Mar 2017 00:40:26 +0000 (19:40 -0500)
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
bgpd/bgp_vty.c
bgpd/bgpd.c
bgpd/bgpd.h

index 547247206071a1661939856a16e8968ad079c968..7b71caf98b500e27314a6c9ff249068287d8202e 100644 (file)
@@ -3409,29 +3409,63 @@ DEFUN (no_neighbor_passive,
 }
 
 /* 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,
@@ -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);
index 5592749b286217ed0054a7b7e05794fe109c2be9..745b86c4ee9cb8a9cff87a660c8cdf8f8beece48 100644 (file)
@@ -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);
         }
     }
 
index 87d8288cfdce16dfc6c79d9e70a35718012f820e..b0b28590cb787ba94d978aaac606e9320c552043 100644 (file)
@@ -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);