diff options
author | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2020-11-08 15:33:22 +0100 |
---|---|---|
committer | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2020-11-08 15:33:22 +0100 |
commit | 9d3fc3062b236f51b2c72a4c2c7b068f1946261d (patch) | |
tree | 0a24e42caff1ba4eb004fc1831b1c0b00407216f /proto/bgp | |
parent | fc1e3211b109400c0e96f889829c9f5145ac7226 (diff) |
BFD: Allow per-request session options
BFD session options are configured per interface in BFD protocol. This
patch allows to specify them also per-request in protocols requesting
sessions (currently limited to BGP).
Diffstat (limited to 'proto/bgp')
-rw-r--r-- | proto/bgp/bgp.c | 28 | ||||
-rw-r--r-- | proto/bgp/bgp.h | 2 | ||||
-rw-r--r-- | proto/bgp/config.Y | 5 |
3 files changed, 24 insertions, 11 deletions
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index b9ed6c78..b34dc325 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -134,7 +134,7 @@ static void bgp_active(struct bgp_proto *p); static void bgp_setup_conn(struct bgp_proto *p, struct bgp_conn *conn); static void bgp_setup_sk(struct bgp_conn *conn, sock *s); static void bgp_send_open(struct bgp_conn *conn); -static void bgp_update_bfd(struct bgp_proto *p, int use_bfd); +static void bgp_update_bfd(struct bgp_proto *p, const struct bfd_options *bfd); static int bgp_incoming_connection(sock *sk, uint dummy UNUSED); static void bgp_listen_sock_err(sock *sk UNUSED, int err); @@ -1357,7 +1357,7 @@ bgp_bfd_notify(struct bfd_request *req) BGP_TRACE(D_EVENTS, "BFD session down"); bgp_store_error(p, NULL, BE_MISC, BEM_BFD_DOWN); - if (p->cf->bfd == BGP_BFD_GRACEFUL) + if (req->opts.mode == BGP_BFD_GRACEFUL) { /* Trigger graceful restart */ if (p->conn && (p->conn->state == BS_ESTABLISHED) && p->gr_ready) @@ -1380,14 +1380,17 @@ bgp_bfd_notify(struct bfd_request *req) } static void -bgp_update_bfd(struct bgp_proto *p, int use_bfd) +bgp_update_bfd(struct bgp_proto *p, const struct bfd_options *bfd) { - if (use_bfd && !p->bfd_req && !bgp_is_dynamic(p)) + if (bfd && p->bfd_req) + bfd_update_request(p->bfd_req, bfd); + + if (bfd && !p->bfd_req && !bgp_is_dynamic(p)) p->bfd_req = bfd_request_session(p->p.pool, p->remote_ip, p->local_ip, p->cf->multihop ? NULL : p->neigh->iface, - p->p.vrf, bgp_bfd_notify, p); + p->p.vrf, bgp_bfd_notify, p, bfd); - if (!use_bfd && p->bfd_req) + if (!bfd && p->bfd_req) { rfree(p->bfd_req); p->bfd_req = NULL; @@ -2138,9 +2141,18 @@ bgp_channel_reconfigure(struct channel *C, struct channel_config *CC, int *impor } static void -bgp_copy_config(struct proto_config *dest UNUSED, struct proto_config *src UNUSED) +bgp_copy_config(struct proto_config *dest, struct proto_config *src) { - /* Just a shallow copy */ + struct bgp_config *d = (void *) dest; + struct bgp_config *s = (void *) src; + + /* Copy BFD options */ + if (s->bfd) + { + struct bfd_options *opts = cfg_alloc(sizeof(struct bfd_options)); + memcpy(opts, s->bfd, sizeof(struct bfd_options)); + d->bfd = opts; + } } diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index 455f04f9..5f365fcd 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -130,7 +130,7 @@ struct bgp_config { const char *dynamic_name; /* Name pattern for dynamic BGP */ int dynamic_name_digits; /* Minimum number of digits for dynamic names */ int check_link; /* Use iface link state for liveness detection */ - int bfd; /* Use BFD for liveness detection */ + const struct bfd_options *bfd; /* Use BFD for liveness detection */ }; struct bgp_channel_config { diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y index 7279560b..dc295645 100644 --- a/proto/bgp/config.Y +++ b/proto/bgp/config.Y @@ -190,8 +190,9 @@ bgp_proto: | bgp_proto LONG LIVED STALE TIME expr ';' { BGP_CFG->llgr_time = $6; } | 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); } + | bgp_proto BFD bool ';' { cf_check_bfd($3); BGP_CFG->bfd = $3 ? bfd_new_options() : NULL; } + | bgp_proto BFD GRACEFUL ';' { cf_check_bfd(1); struct bfd_options *opts = bfd_new_options(); opts->mode = BGP_BFD_GRACEFUL; BGP_CFG->bfd = opts; } + | bgp_proto BFD bfd_opts ';' { BGP_CFG->bfd = $3; cf_check_bfd(1); } | bgp_proto ENFORCE FIRST AS bool ';' { BGP_CFG->enforce_first_as = $5; } ; |