diff options
author | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2019-07-18 02:04:42 +0200 |
---|---|---|
committer | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2019-07-18 02:04:42 +0200 |
commit | f9deedf1f045d1b64edaf2f27209e5227cce155a (patch) | |
tree | cd092a8b499d79be68ee22cb5981154811ed8021 | |
parent | 9ff6c8d83c7fee5f354d4d6ed4efc15bfc6bc7e1 (diff) |
BFD: Support for VRFs
Allow multiple BFD instances in separate VRFs, dispatch BFD requests
according to VRFs.
Thanks to Alexander Zubkov for notice and patches.
-rw-r--r-- | nest/bfd.h | 5 | ||||
-rw-r--r-- | proto/bfd/bfd.c | 21 | ||||
-rw-r--r-- | proto/bfd/config.Y | 4 | ||||
-rw-r--r-- | proto/bfd/packets.c | 2 | ||||
-rw-r--r-- | proto/bgp/bgp.c | 2 | ||||
-rw-r--r-- | proto/ospf/neighbor.c | 5 | ||||
-rw-r--r-- | proto/rip/rip.c | 3 | ||||
-rw-r--r-- | proto/static/static.c | 2 |
8 files changed, 21 insertions, 23 deletions
@@ -19,6 +19,7 @@ struct bfd_request { ip_addr addr; ip_addr local; struct iface *iface; + struct iface *vrf; void (*hook)(struct bfd_request *); void *data; @@ -40,13 +41,13 @@ struct bfd_request { #ifdef CONFIG_BFD -struct bfd_request * bfd_request_session(pool *p, ip_addr addr, ip_addr local, struct iface *iface, void (*hook)(struct bfd_request *), void *data); +struct bfd_request * bfd_request_session(pool *p, ip_addr addr, ip_addr local, struct iface *iface, struct iface *vrf, void (*hook)(struct bfd_request *), void *data); static inline void cf_check_bfd(int use UNUSED) { } #else -static inline struct bfd_request * bfd_request_session(pool *p, ip_addr addr, ip_addr local, struct iface *iface, void (*hook)(struct bfd_request *), void *data) { return NULL; } +static inline struct bfd_request * bfd_request_session(pool *p, ip_addr addr, ip_addr local, struct iface *iface, struct iface *vrf, void (*hook)(struct bfd_request *), void *data) { return NULL; } static inline void cf_check_bfd(int use) { if (use) cf_error("BFD not available"); } diff --git a/proto/bfd/bfd.c b/proto/bfd/bfd.c index 79135fae..c9f1a7e5 100644 --- a/proto/bfd/bfd.c +++ b/proto/bfd/bfd.c @@ -624,6 +624,9 @@ bfd_request_notify(struct bfd_request *req, u8 state, u8 diag) static int bfd_add_request(struct bfd_proto *p, struct bfd_request *req) { + if (p->p.vrf && (p->p.vrf != req->vrf)) + return 0; + struct bfd_session *s = bfd_find_session_by_addr(p, req->addr); u8 state, diag; @@ -685,7 +688,8 @@ bfd_drop_requests(struct bfd_proto *p) static struct resclass bfd_request_class; struct bfd_request * -bfd_request_session(pool *p, ip_addr addr, ip_addr local, struct iface *iface, +bfd_request_session(pool *p, ip_addr addr, ip_addr local, + struct iface *iface, struct iface *vrf, void (*hook)(struct bfd_request *), void *data) { struct bfd_request *req = ralloc(p, &bfd_request_class); @@ -696,6 +700,7 @@ bfd_request_session(pool *p, ip_addr addr, ip_addr local, struct iface *iface, req->addr = addr; req->local = local; req->iface = iface; + req->vrf = vrf; bfd_submit_request(req); @@ -754,7 +759,7 @@ bfd_neigh_notify(struct neighbor *nb) if ((nb->scope > 0) && !n->req) { ip_addr local = ipa_nonzero(n->local) ? n->local : nb->ifa->ip; - n->req = bfd_request_session(p->p.pool, n->addr, local, nb->iface, NULL, NULL); + n->req = bfd_request_session(p->p.pool, n->addr, local, nb->iface, p->p.vrf, NULL, NULL); } if ((nb->scope <= 0) && n->req) @@ -771,7 +776,7 @@ bfd_start_neighbor(struct bfd_proto *p, struct bfd_neighbor *n) if (n->multihop) { - n->req = bfd_request_session(p->p.pool, n->addr, n->local, NULL, NULL, NULL); + n->req = bfd_request_session(p->p.pool, n->addr, n->local, NULL, p->p.vrf, NULL, NULL); return; } @@ -1052,15 +1057,6 @@ bfd_reconfigure(struct proto *P, struct proto_config *c) return 1; } -/* Ensure one instance */ -struct bfd_config *bfd_cf; - -static void -bfd_preconfig(struct protocol *P UNUSED, struct config *c UNUSED) -{ - bfd_cf = NULL; -} - static void bfd_copy_config(struct proto_config *dest, struct proto_config *src UNUSED) { @@ -1123,6 +1119,5 @@ struct protocol proto_bfd = { .start = bfd_start, .shutdown = bfd_shutdown, .reconfigure = bfd_reconfigure, - .preconfig = bfd_preconfig, .copy_config = bfd_copy_config, }; diff --git a/proto/bfd/config.Y b/proto/bfd/config.Y index 73414362..7e0d63bc 100644 --- a/proto/bfd/config.Y +++ b/proto/bfd/config.Y @@ -38,10 +38,6 @@ bfd_proto_start: proto_start BFD this_proto = proto_config_new(&proto_bfd, $1); init_list(&BFD_CFG->patt_list); init_list(&BFD_CFG->neigh_list); - - if (bfd_cf) - cf_error("Only one BFD instance allowed"); - bfd_cf = BFD_CFG; }; bfd_proto_item: diff --git a/proto/bfd/packets.c b/proto/bfd/packets.c index f577ed31..08c6c508 100644 --- a/proto/bfd/packets.c +++ b/proto/bfd/packets.c @@ -412,6 +412,7 @@ bfd_open_rx_sk(struct bfd_proto *p, int multihop) sock *sk = sk_new(p->tpool); sk->type = SK_UDP; sk->sport = !multihop ? BFD_CONTROL_PORT : BFD_MULTI_CTL_PORT; + sk->vrf = p->p.vrf; sk->data = p; sk->rbsize = BFD_MAX_LEN; @@ -447,6 +448,7 @@ bfd_open_tx_sk(struct bfd_proto *p, ip_addr local, struct iface *ifa) sk->saddr = local; sk->dport = ifa ? BFD_CONTROL_PORT : BFD_MULTI_CTL_PORT; sk->iface = ifa; + sk->vrf = p->p.vrf; sk->data = p; sk->tbsize = BFD_MAX_LEN; diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index 3d59a31b..e40a6266 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -1084,7 +1084,7 @@ bgp_update_bfd(struct bgp_proto *p, int use_bfd) if (use_bfd && !p->bfd_req) p->bfd_req = bfd_request_session(p->p.pool, p->cf->remote_ip, p->source_addr, p->cf->multihop ? NULL : p->neigh->iface, - bgp_bfd_notify, p); + p->p.vrf, bgp_bfd_notify, p); if (!use_bfd && p->bfd_req) { diff --git a/proto/ospf/neighbor.c b/proto/ospf/neighbor.c index 9fe3c028..bc274e5f 100644 --- a/proto/ospf/neighbor.c +++ b/proto/ospf/neighbor.c @@ -584,8 +584,11 @@ ospf_neigh_bfd_hook(struct bfd_request *req) void ospf_neigh_update_bfd(struct ospf_neighbor *n, int use_bfd) { + struct ospf_proto *p = n->ifa->oa->po; + if (use_bfd && !n->bfd_req) - n->bfd_req = bfd_request_session(n->pool, n->ip, n->ifa->addr->ip, n->ifa->iface, + n->bfd_req = bfd_request_session(n->pool, n->ip, n->ifa->addr->ip, + n->ifa->iface, p->p.vrf, ospf_neigh_bfd_hook, n); if (!use_bfd && n->bfd_req) diff --git a/proto/rip/rip.c b/proto/rip/rip.c index 88d7b7c8..6afdc084 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -504,7 +504,8 @@ rip_update_bfd(struct rip_proto *p, struct rip_neighbor *n) */ ip_addr saddr = rip_is_v2(p) ? n->ifa->sk->saddr : n->nbr->ifa->ip; n->bfd_req = bfd_request_session(p->p.pool, n->nbr->addr, saddr, - n->nbr->iface, rip_bfd_notify, n); + n->nbr->iface, p->p.vrf, + rip_bfd_notify, n); } if (!use_bfd && n->bfd_req) diff --git a/proto/static/static.c b/proto/static/static.c index 6ddff146..9e9c07fa 100644 --- a/proto/static/static.c +++ b/proto/static/static.c @@ -150,7 +150,7 @@ static_update_bfd(struct proto *p, struct static_route *r) if (bfd_up && !r->bfd_req) { // ip_addr local = ipa_nonzero(r->local) ? r->local : nb->ifa->ip; - r->bfd_req = bfd_request_session(p->pool, r->via, nb->ifa->ip, nb->iface, + r->bfd_req = bfd_request_session(p->pool, r->via, nb->ifa->ip, nb->iface, p->vrf, static_bfd_notify, r); } |