summaryrefslogtreecommitdiff
path: root/proto/bgp
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2020-11-08 15:33:22 +0100
committerOndrej Zajicek (work) <santiago@crfreenet.org>2020-11-08 15:33:22 +0100
commit9d3fc3062b236f51b2c72a4c2c7b068f1946261d (patch)
tree0a24e42caff1ba4eb004fc1831b1c0b00407216f /proto/bgp
parentfc1e3211b109400c0e96f889829c9f5145ac7226 (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.c28
-rw-r--r--proto/bgp/bgp.h2
-rw-r--r--proto/bgp/config.Y5
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; }
;