From aa2ec912f5a557f340a633e95b9fbf2ad7937edd Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Wed, 4 Jul 2018 16:42:42 +0200 Subject: 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. --- proto/bgp/bgp.c | 24 +++++++++++++++++++++++- proto/bgp/bgp.h | 2 ++ proto/bgp/config.Y | 1 + 3 files changed, 26 insertions(+), 1 deletion(-) (limited to 'proto') 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 -- cgit v1.2.3