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.
This commit is contained in:
parent
2eaf65ec60
commit
cf7ff99513
8 changed files with 22 additions and 23 deletions
|
@ -19,6 +19,7 @@ struct bfd_request {
|
||||||
ip_addr addr;
|
ip_addr addr;
|
||||||
ip_addr local;
|
ip_addr local;
|
||||||
struct iface *iface;
|
struct iface *iface;
|
||||||
|
struct iface *vrf;
|
||||||
|
|
||||||
void (*hook)(struct bfd_request *);
|
void (*hook)(struct bfd_request *);
|
||||||
void *data;
|
void *data;
|
||||||
|
@ -40,13 +41,13 @@ struct bfd_request {
|
||||||
|
|
||||||
#ifdef CONFIG_BFD
|
#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) { }
|
static inline void cf_check_bfd(int use UNUSED) { }
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static inline struct bfd_request * bfd_request_session(pool *p UNUSED, ip_addr addr UNUSED, ip_addr local UNUSED, struct iface *iface UNUSED, void (*hook)(struct bfd_request *) UNUSED, void *data UNUSED) { return NULL; }
|
static inline struct bfd_request * bfd_request_session(pool *p UNUSED, ip_addr addr UNUSED, ip_addr local UNUSED, struct iface *iface UNUSED, struct iface *vrf UNUSED, void (*hook)(struct bfd_request *) UNUSED, void *data UNUSED) { return NULL; }
|
||||||
|
|
||||||
static inline void cf_check_bfd(int use) { if (use) cf_error("BFD not available"); }
|
static inline void cf_check_bfd(int use) { if (use) cf_error("BFD not available"); }
|
||||||
|
|
||||||
|
|
|
@ -624,6 +624,9 @@ bfd_request_notify(struct bfd_request *req, u8 state, u8 diag)
|
||||||
static int
|
static int
|
||||||
bfd_add_request(struct bfd_proto *p, struct bfd_request *req)
|
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);
|
struct bfd_session *s = bfd_find_session_by_addr(p, req->addr);
|
||||||
u8 state, diag;
|
u8 state, diag;
|
||||||
|
|
||||||
|
@ -685,7 +688,8 @@ bfd_drop_requests(struct bfd_proto *p)
|
||||||
static struct resclass bfd_request_class;
|
static struct resclass bfd_request_class;
|
||||||
|
|
||||||
struct bfd_request *
|
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)
|
void (*hook)(struct bfd_request *), void *data)
|
||||||
{
|
{
|
||||||
struct bfd_request *req = ralloc(p, &bfd_request_class);
|
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->addr = addr;
|
||||||
req->local = local;
|
req->local = local;
|
||||||
req->iface = iface;
|
req->iface = iface;
|
||||||
|
req->vrf = vrf;
|
||||||
|
|
||||||
bfd_submit_request(req);
|
bfd_submit_request(req);
|
||||||
|
|
||||||
|
@ -754,7 +759,7 @@ bfd_neigh_notify(struct neighbor *nb)
|
||||||
if ((nb->scope > 0) && !n->req)
|
if ((nb->scope > 0) && !n->req)
|
||||||
{
|
{
|
||||||
ip_addr local = ipa_nonzero(n->local) ? n->local : nb->ifa->ip;
|
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)
|
if ((nb->scope <= 0) && n->req)
|
||||||
|
@ -771,7 +776,7 @@ bfd_start_neighbor(struct bfd_proto *p, struct bfd_neighbor *n)
|
||||||
|
|
||||||
if (n->multihop)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1051,15 +1056,6 @@ bfd_reconfigure(struct proto *P, struct proto_config *c)
|
||||||
return 1;
|
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
|
static void
|
||||||
bfd_copy_config(struct proto_config *dest, struct proto_config *src UNUSED)
|
bfd_copy_config(struct proto_config *dest, struct proto_config *src UNUSED)
|
||||||
{
|
{
|
||||||
|
@ -1123,6 +1119,5 @@ struct protocol proto_bfd = {
|
||||||
.start = bfd_start,
|
.start = bfd_start,
|
||||||
.shutdown = bfd_shutdown,
|
.shutdown = bfd_shutdown,
|
||||||
.reconfigure = bfd_reconfigure,
|
.reconfigure = bfd_reconfigure,
|
||||||
.preconfig = bfd_preconfig,
|
|
||||||
.copy_config = bfd_copy_config,
|
.copy_config = bfd_copy_config,
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,10 +38,6 @@ bfd_proto_start: proto_start BFD
|
||||||
this_proto = proto_config_new(&proto_bfd, $1);
|
this_proto = proto_config_new(&proto_bfd, $1);
|
||||||
init_list(&BFD_CFG->patt_list);
|
init_list(&BFD_CFG->patt_list);
|
||||||
init_list(&BFD_CFG->neigh_list);
|
init_list(&BFD_CFG->neigh_list);
|
||||||
|
|
||||||
if (bfd_cf)
|
|
||||||
cf_error("Only one BFD instance allowed");
|
|
||||||
bfd_cf = BFD_CFG;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bfd_proto_item:
|
bfd_proto_item:
|
||||||
|
|
|
@ -413,6 +413,7 @@ bfd_open_rx_sk(struct bfd_proto *p, int multihop, int af)
|
||||||
sk->type = SK_UDP;
|
sk->type = SK_UDP;
|
||||||
sk->subtype = af;
|
sk->subtype = af;
|
||||||
sk->sport = !multihop ? BFD_CONTROL_PORT : BFD_MULTI_CTL_PORT;
|
sk->sport = !multihop ? BFD_CONTROL_PORT : BFD_MULTI_CTL_PORT;
|
||||||
|
sk->vrf = p->p.vrf;
|
||||||
sk->data = p;
|
sk->data = p;
|
||||||
|
|
||||||
sk->rbsize = BFD_MAX_LEN;
|
sk->rbsize = BFD_MAX_LEN;
|
||||||
|
@ -444,6 +445,7 @@ bfd_open_tx_sk(struct bfd_proto *p, ip_addr local, struct iface *ifa)
|
||||||
sk->saddr = local;
|
sk->saddr = local;
|
||||||
sk->dport = ifa ? BFD_CONTROL_PORT : BFD_MULTI_CTL_PORT;
|
sk->dport = ifa ? BFD_CONTROL_PORT : BFD_MULTI_CTL_PORT;
|
||||||
sk->iface = ifa;
|
sk->iface = ifa;
|
||||||
|
sk->vrf = p->p.vrf;
|
||||||
sk->data = p;
|
sk->data = p;
|
||||||
|
|
||||||
sk->tbsize = BFD_MAX_LEN;
|
sk->tbsize = BFD_MAX_LEN;
|
||||||
|
|
|
@ -1371,7 +1371,7 @@ bgp_update_bfd(struct bgp_proto *p, int use_bfd)
|
||||||
if (use_bfd && !p->bfd_req && !bgp_is_dynamic(p))
|
if (use_bfd && !p->bfd_req && !bgp_is_dynamic(p))
|
||||||
p->bfd_req = bfd_request_session(p->p.pool, p->remote_ip, p->local_ip,
|
p->bfd_req = bfd_request_session(p->p.pool, p->remote_ip, p->local_ip,
|
||||||
p->cf->multihop ? NULL : p->neigh->iface,
|
p->cf->multihop ? NULL : p->neigh->iface,
|
||||||
bgp_bfd_notify, p);
|
p->p.vrf, bgp_bfd_notify, p);
|
||||||
|
|
||||||
if (!use_bfd && p->bfd_req)
|
if (!use_bfd && p->bfd_req)
|
||||||
{
|
{
|
||||||
|
|
|
@ -771,8 +771,11 @@ ospf_neigh_bfd_hook(struct bfd_request *req)
|
||||||
void
|
void
|
||||||
ospf_neigh_update_bfd(struct ospf_neighbor *n, int use_bfd)
|
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)
|
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);
|
ospf_neigh_bfd_hook, n);
|
||||||
|
|
||||||
if (!use_bfd && n->bfd_req)
|
if (!use_bfd && n->bfd_req)
|
||||||
|
|
|
@ -483,7 +483,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;
|
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->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)
|
if (!use_bfd && n->bfd_req)
|
||||||
|
|
|
@ -159,7 +159,8 @@ static_update_bfd(struct static_proto *p, struct static_route *r)
|
||||||
if (bfd_up && !r->bfd_req)
|
if (bfd_up && !r->bfd_req)
|
||||||
{
|
{
|
||||||
// ip_addr local = ipa_nonzero(r->local) ? r->local : nb->ifa->ip;
|
// ip_addr local = ipa_nonzero(r->local) ? r->local : nb->ifa->ip;
|
||||||
r->bfd_req = bfd_request_session(p->p.pool, r->via, nb->ifa->ip, nb->iface,
|
r->bfd_req = bfd_request_session(p->p.pool, r->via, nb->ifa->ip,
|
||||||
|
nb->iface, p->p.vrf,
|
||||||
static_bfd_notify, r);
|
static_bfd_notify, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue