summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2018-07-04 16:42:42 +0200
committerOndrej Zajicek (work) <santiago@crfreenet.org>2018-07-17 13:16:35 +0200
commitaa2ec912f5a557f340a633e95b9fbf2ad7937edd (patch)
treece2c7f1173793c16355f2bcab57dd1e22da6d52b
parenta9d869c484f899f2ef509659a8d928804d020461 (diff)
BGP: Long-lived graceful restart enhancements
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.
-rw-r--r--doc/bird.sgml9
-rw-r--r--proto/bgp/bgp.c24
-rw-r--r--proto/bgp/bgp.h2
-rw-r--r--proto/bgp/config.Y1
4 files changed, 32 insertions, 4 deletions
diff --git a/doc/bird.sgml b/doc/bird.sgml
index c66e8c72..7cbb4de6 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -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
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index 0932051a..369d78f5 100644
--- a/proto/bgp/bgp.c
+++ b/proto/bgp/bgp.c
@@ -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
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index 53194fb6..7703fb6e 100644
--- a/proto/bgp/bgp.h
+++ b/proto/bgp/bgp.h
@@ -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;
diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y
index 2ed1944d..95ceccb5 100644
--- a/proto/bgp/config.Y
+++ b/proto/bgp/config.Y
@@ -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