]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
BGP: Long-lived graceful restart enhancements
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Wed, 4 Jul 2018 14:42:42 +0000 (16:42 +0200)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 17 Jul 2018 11:16:35 +0000 (13:16 +0200)
When use of LLGR is negotiated, handle hold timeout by LLGR instead of by
hard restart. Allow to configure whether BFD session down event should be
handled by GR/LLGR or by hard restart.

doc/bird.sgml
proto/bgp/bgp.c
proto/bgp/bgp.h
proto/bgp/config.Y

index c66e8c72583bf0a7f3a5a35fda650dbb74075b7b..7cbb4de698d819cfc8a0ead26965797c688ecf52 100644 (file)
@@ -1977,13 +1977,16 @@ using the following configuration parameters:
        immediately shut down. Note that this option cannot be used with
        multihop BGP. Default: disabled.
 
-       <tag><label id="bgp-bfd">bfd <M>switch</M></tag>
+       <tag><label id="bgp-bfd">bfd <M>switch</M>|graceful</tag>
        BGP could use BFD protocol as an advisory mechanism for neighbor
        liveness and failure detection. If enabled, BIRD setups a BFD session
        for the BGP neighbor and tracks its liveness by it. This has an
        advantage of an order of magnitude lower detection times in case of
-       failure. Note that BFD protocol also has to be configured, see
-       <ref id="bfd" name="BFD"> section for details. Default: disabled.
+       failure. When a neighbor failure is detected, the BGP session is
+       restarted. Optionally, it can be configured (by <cf/graceful/ argument)
+       to trigger graceful restart instead of regular restart.  Note that BFD
+       protocol also has to be configured, see <ref id="bfd" name="BFD">
+       section for details. Default: disabled.
 
        <tag><label id="bgp-ttl-security">ttl security <m/switch/</tag>
        Use GTSM (<rfc id="5082"> - the generalized TTL security mechanism). GTSM
index 0932051abdf6186acd7619a1669e83e4ea811fc0..369d78f579ece16e3f5e8d1b3ca6d137b9c8d72a 100644 (file)
@@ -704,6 +704,12 @@ bgp_hold_timeout(timer *t)
 
   if (sk_rx_ready(conn->sk) > 0)
     bgp_start_timer(conn->hold_timer, 10);
+  else if ((conn->state == BS_ESTABLISHED) && p->gr_ready && conn->peer_llgr_able)
+  {
+    BGP_TRACE(D_EVENTS, "Hold timer expired");
+    bgp_handle_graceful_restart(p);
+    bgp_conn_enter_idle_state(conn);
+  }
   else
     bgp_error(conn, 4, 0, NULL, 0);
 }
@@ -1046,13 +1052,29 @@ bgp_bfd_notify(struct bfd_request *req)
   int ps = p->p.proto_state;
 
   if (req->down && ((ps == PS_START) || (ps == PS_UP)))
+  {
+    BGP_TRACE(D_EVENTS, "BFD session down");
+
+    /* Ignore if already in GR */
+    if (p->gr_active && (p->cf->bfd == BGP_BFD_GRACEFUL))
+      return;
+
+    if (p->conn && (p->conn->state == BS_ESTABLISHED) &&
+       p->gr_ready && (p->cf->bfd == BGP_BFD_GRACEFUL))
+    {
+      /* Trigger graceful restart */
+      bgp_handle_graceful_restart(p);
+      bgp_conn_enter_idle_state(p->conn);
+    }
+    else
     {
-      BGP_TRACE(D_EVENTS, "BFD session down");
+      /* Trigger session down */
       bgp_store_error(p, NULL, BE_MISC, BEM_BFD_DOWN);
       if (ps == PS_UP)
        bgp_update_startup_delay(p);
       bgp_stop(p, 0, NULL, 0);
     }
+  }
 }
 
 static void
index 53194fb622d17ab600e19f36fa6ad13cb82198c0..7703fb6e96622c6d2e45f13117b2dd40c4e3fe90 100644 (file)
@@ -102,6 +102,8 @@ struct bgp_config {
 #define BGP_GRS_LLGR_1         2       /* Long-lived GR phase 1 (restart time) */
 #define BGP_GRS_LLGR_2         3       /* Long-lived GR phase 2 (stale time) */
 
+#define BGP_BFD_GRACEFUL       2       /* BFD down triggers graceful restart */
+
 
 struct bgp_conn {
   struct bgp_proto *bgp;
index 2ed1944df5dd423292c33beeac44031c6eaa95ad..95ceccb5f6f7d604873eb404dd2457cf5ca7ffb6 100644 (file)
@@ -172,6 +172,7 @@ bgp_proto:
  | bgp_proto TTL SECURITY bool ';' { BGP_CFG->ttl_security = $4; }
  | bgp_proto CHECK LINK bool ';' { BGP_CFG->check_link = $4; }
  | bgp_proto BFD bool ';' { BGP_CFG->bfd = $3; cf_check_bfd($3); }
+ | bgp_proto BFD GRACEFUL ';' { BGP_CFG->bfd = BGP_BFD_GRACEFUL; cf_check_bfd(1); }
  ;
 
 CF_ADDTO(dynamic_attr, BGP_ORIGIN