]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
BGP: Implement 'disable after cease' option
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 16 Jan 2018 18:17:04 +0000 (19:17 +0100)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 16 Jan 2018 18:17:04 +0000 (19:17 +0100)
The option allows to specify that some cease subcodes should
disable the protocol when received.

proto/bgp/bgp.h
proto/bgp/config.Y
proto/bgp/packets.c

index 22a150ab7e592110da2aba1c593f4c1b21893f7b..b3db8b7e8e5568a329ce23d877a83ba7ce2fbada 100644 (file)
@@ -62,6 +62,7 @@ struct bgp_config {
   unsigned error_delay_time_min;       /* Time to wait after an error is detected */
   unsigned error_delay_time_max;
   unsigned disable_after_error;                /* Disable the protocol when error is detected */
+  u32 disable_after_cease;             /* Disable it when cease is received, bitfield */
 
   char *password;                      /* Password used for MD5 authentication */
   struct rtable_config *igp_table;     /* Table used for recursive next hop lookups */
index 55c602f1e80121177de323b8fee27e2f128a75cf..075403a3fd0d67ed8ffe3057df729f5fe7729357 100644 (file)
@@ -29,6 +29,12 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY,
        SECONDARY, ALLOW, BFD, ADD, PATHS, RX, TX, GRACEFUL, RESTART, AWARE,
        CHECK, LINK, PORT, EXTENDED, MESSAGES, SETKEY, BGP_LARGE_COMMUNITY)
 
+CF_KEYWORDS(CEASE, PREFIX, LIMIT, HIT, ADMINISTRATIVE, SHUTDOWN, RESET, PEER,
+       CONFIGURATION, CHANGE, DECONFIGURED, CONNECTION, REJECTED, COLLISION,
+       OUT, OF, RESOURCES)
+
+%type<i> bgp_cease_mask bgp_cease_list bgp_cease_flag
+
 CF_GRAMMAR
 
 CF_ADDTO(proto, bgp_proto '}' { bgp_check_config(BGP_CFG); } )
@@ -64,6 +70,29 @@ bgp_nbr_opts:
  | bgp_nbr_opts AS expr { BGP_CFG->remote_as = $3; }
  ;
 
+bgp_cease_mask:
+   /* true -> all except connection collision */
+   bool { $$ = $1 ? ~(1 << 7) : 0; }
+ | '{' bgp_cease_list '}' { $$ = $2; }
+ ;
+
+bgp_cease_list:
+   bgp_cease_flag
+ | bgp_cease_list ',' bgp_cease_flag { $$ = $1 | $3; }
+ ;
+
+bgp_cease_flag:
+   CEASE                       { $$ = 1 << 0; }
+ | PREFIX LIMIT HIT            { $$ = 1 << 1; }
+ | ADMINISTRATIVE SHUTDOWN     { $$ = 1 << 2; }
+ | PEER DECONFIGURED           { $$ = 1 << 3; }
+ | ADMINISTRATIVE RESET                { $$ = 1 << 4; }
+ | CONNECTION REJECTED         { $$ = 1 << 5; }
+ | CONFIGURATION CHANGE                { $$ = 1 << 6; }
+ | CONNECTION COLLISION                { $$ = 1 << 7; }
+ | OUT OF RESOURCES            { $$ = 1 << 8; }
+ ;
+
 bgp_proto:
    bgp_proto_start proto_name '{'
  | bgp_proto proto_item ';'
@@ -107,6 +136,7 @@ bgp_proto:
  | bgp_proto ERROR FORGET TIME expr ';' { BGP_CFG->error_amnesia_time = $5; }
  | bgp_proto ERROR WAIT TIME expr ',' expr ';' { BGP_CFG->error_delay_time_min = $5; BGP_CFG->error_delay_time_max = $7; }
  | bgp_proto DISABLE AFTER ERROR bool ';' { BGP_CFG->disable_after_error = $5; }
+ | bgp_proto DISABLE AFTER CEASE bgp_cease_mask ';' { BGP_CFG->disable_after_cease = $5; }
  | bgp_proto ENABLE ROUTE REFRESH bool ';' { BGP_CFG->enable_refresh = $5; }
  | bgp_proto ENABLE AS4 bool ';' { BGP_CFG->enable_as4 = $4; }
  | bgp_proto ENABLE EXTENDED MESSAGES bool ';' { BGP_CFG->enable_extended_messages = $5; }
index af3b15b59ca46a28c36829e2cf51993011ac2428..f0049d3a56a665ca1fdc9b2ffe70fbec74121ab5 100644 (file)
@@ -1607,6 +1607,16 @@ bgp_rx_notification(struct bgp_conn *conn, byte *pkt, uint len)
       bgp_update_startup_delay(p);
       bgp_stop(p, 0, NULL, 0);
     }
+  else
+    {
+      uint subcode_bit = 1 << ((subcode <= 8) ? subcode : 0);
+      if (p->cf->disable_after_cease & subcode_bit)
+      {
+       log(L_INFO "%s: Disabled after Cease notification", p->p.name);
+       p->startup_delay = 0;
+       p->p.disabled = 1;
+      }
+    }
 }
 
 static void