BFD: Option to specify which class of BFD sessions are accepted
Allows to configure IPv4/IPv6-only or direct/multihop-only BFD protocol instances.
This commit is contained in:
parent
9f2670277c
commit
7f9adafc10
4 changed files with 61 additions and 6 deletions
|
@ -1955,6 +1955,7 @@ milliseconds.
|
||||||
|
|
||||||
<code>
|
<code>
|
||||||
protocol bfd [<name>] {
|
protocol bfd [<name>] {
|
||||||
|
accept [ipv4|ipv6] [direct|multihop];
|
||||||
interface <interface pattern> {
|
interface <interface pattern> {
|
||||||
interval <time>;
|
interval <time>;
|
||||||
min rx interval <time>;
|
min rx interval <time>;
|
||||||
|
@ -1989,6 +1990,14 @@ protocol bfd [<name>] {
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
<descrip>
|
<descrip>
|
||||||
|
<tag><label id="bfd-accept">accept [ipv4|ipv6] [direct|multihop]</tag>
|
||||||
|
A BFD protocol instance accepts (by default) all BFD session requests
|
||||||
|
(with regard to VRF restrictions, see above). This option controls
|
||||||
|
whether IPv4 / IPv6 and direct / multihop session requests are accepted
|
||||||
|
(and which listening sockets are opened). It can be used, for example,
|
||||||
|
to configure separate BFD protocol instances for IPv4 and for IPv6
|
||||||
|
sessions.
|
||||||
|
|
||||||
<tag><label id="bfd-iface">interface <m/pattern/ [, <m/.../] { <m/options/ }</tag>
|
<tag><label id="bfd-iface">interface <m/pattern/ [, <m/.../] { <m/options/ }</tag>
|
||||||
Interface definitions allow to specify options for sessions associated
|
Interface definitions allow to specify options for sessions associated
|
||||||
with such interfaces and also may contain interface specific options.
|
with such interfaces and also may contain interface specific options.
|
||||||
|
|
|
@ -624,9 +624,17 @@ 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)
|
||||||
{
|
{
|
||||||
|
struct bfd_config *cf = (struct bfd_config *) (p->p.cf);
|
||||||
|
|
||||||
if (p->p.vrf_set && (p->p.vrf != req->vrf))
|
if (p->p.vrf_set && (p->p.vrf != req->vrf))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (ipa_is_ip4(req->addr) ? !cf->accept_ipv4 : !cf->accept_ipv6)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (req->iface ? !cf->accept_direct : !cf->accept_multihop)
|
||||||
|
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;
|
||||||
|
|
||||||
|
@ -986,10 +994,19 @@ bfd_start(struct proto *P)
|
||||||
add_tail(&bfd_proto_list, &p->bfd_node);
|
add_tail(&bfd_proto_list, &p->bfd_node);
|
||||||
|
|
||||||
birdloop_enter(p->loop);
|
birdloop_enter(p->loop);
|
||||||
|
|
||||||
|
if (cf->accept_ipv4 && cf->accept_direct)
|
||||||
p->rx4_1 = bfd_open_rx_sk(p, 0, SK_IPV4);
|
p->rx4_1 = bfd_open_rx_sk(p, 0, SK_IPV4);
|
||||||
|
|
||||||
|
if (cf->accept_ipv4 && cf->accept_multihop)
|
||||||
p->rx4_m = bfd_open_rx_sk(p, 1, SK_IPV4);
|
p->rx4_m = bfd_open_rx_sk(p, 1, SK_IPV4);
|
||||||
|
|
||||||
|
if (cf->accept_ipv6 && cf->accept_direct)
|
||||||
p->rx6_1 = bfd_open_rx_sk(p, 0, SK_IPV6);
|
p->rx6_1 = bfd_open_rx_sk(p, 0, SK_IPV6);
|
||||||
|
|
||||||
|
if (cf->accept_ipv6 && cf->accept_multihop)
|
||||||
p->rx6_m = bfd_open_rx_sk(p, 1, SK_IPV6);
|
p->rx6_m = bfd_open_rx_sk(p, 1, SK_IPV6);
|
||||||
|
|
||||||
birdloop_leave(p->loop);
|
birdloop_leave(p->loop);
|
||||||
|
|
||||||
bfd_take_requests(p);
|
bfd_take_requests(p);
|
||||||
|
@ -1034,10 +1051,17 @@ static int
|
||||||
bfd_reconfigure(struct proto *P, struct proto_config *c)
|
bfd_reconfigure(struct proto *P, struct proto_config *c)
|
||||||
{
|
{
|
||||||
struct bfd_proto *p = (struct bfd_proto *) P;
|
struct bfd_proto *p = (struct bfd_proto *) P;
|
||||||
// struct bfd_config *old = (struct bfd_config *) (P->cf);
|
struct bfd_config *old = (struct bfd_config *) (P->cf);
|
||||||
struct bfd_config *new = (struct bfd_config *) c;
|
struct bfd_config *new = (struct bfd_config *) c;
|
||||||
struct bfd_iface *ifa;
|
struct bfd_iface *ifa;
|
||||||
|
|
||||||
|
/* TODO: Improve accept reconfiguration */
|
||||||
|
if ((new->accept_ipv4 != old->accept_ipv4) ||
|
||||||
|
(new->accept_ipv6 != old->accept_ipv6) ||
|
||||||
|
(new->accept_direct != old->accept_direct) ||
|
||||||
|
(new->accept_multihop != old->accept_multihop))
|
||||||
|
return 0;
|
||||||
|
|
||||||
birdloop_mask_wakeups(p->loop);
|
birdloop_mask_wakeups(p->loop);
|
||||||
|
|
||||||
WALK_LIST(ifa, p->iface_list)
|
WALK_LIST(ifa, p->iface_list)
|
||||||
|
|
|
@ -43,6 +43,10 @@ struct bfd_config
|
||||||
list patt_list; /* List of iface configs (struct bfd_iface_config) */
|
list patt_list; /* List of iface configs (struct bfd_iface_config) */
|
||||||
list neigh_list; /* List of configured neighbors (struct bfd_neighbor) */
|
list neigh_list; /* List of configured neighbors (struct bfd_neighbor) */
|
||||||
struct bfd_iface_config *multihop; /* Multihop pseudoiface config */
|
struct bfd_iface_config *multihop; /* Multihop pseudoiface config */
|
||||||
|
u8 accept_ipv4;
|
||||||
|
u8 accept_ipv6;
|
||||||
|
u8 accept_direct;
|
||||||
|
u8 accept_multihop;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct bfd_iface_config
|
struct bfd_iface_config
|
||||||
|
|
|
@ -23,7 +23,7 @@ CF_DECLS
|
||||||
|
|
||||||
CF_KEYWORDS(BFD, MIN, IDLE, RX, TX, INTERVAL, MULTIPLIER, PASSIVE,
|
CF_KEYWORDS(BFD, MIN, IDLE, RX, TX, INTERVAL, MULTIPLIER, PASSIVE,
|
||||||
INTERFACE, MULTIHOP, NEIGHBOR, DEV, LOCAL, AUTHENTICATION,
|
INTERFACE, MULTIHOP, NEIGHBOR, DEV, LOCAL, AUTHENTICATION,
|
||||||
NONE, SIMPLE, METICULOUS, KEYED, MD5, SHA1)
|
NONE, SIMPLE, METICULOUS, KEYED, MD5, SHA1, IPV4, IPV6, DIRECT)
|
||||||
|
|
||||||
%type <iface> bfd_neigh_iface
|
%type <iface> bfd_neigh_iface
|
||||||
%type <a> bfd_neigh_local
|
%type <a> bfd_neigh_local
|
||||||
|
@ -38,10 +38,13 @@ 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);
|
||||||
|
BFD_CFG->accept_ipv4 = BFD_CFG->accept_ipv6 = 1;
|
||||||
|
BFD_CFG->accept_direct = BFD_CFG->accept_multihop = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
bfd_proto_item:
|
bfd_proto_item:
|
||||||
proto_item
|
proto_item
|
||||||
|
| ACCEPT bfd_accept
|
||||||
| INTERFACE bfd_iface
|
| INTERFACE bfd_iface
|
||||||
| MULTIHOP bfd_multihop
|
| MULTIHOP bfd_multihop
|
||||||
| NEIGHBOR bfd_neighbor
|
| NEIGHBOR bfd_neighbor
|
||||||
|
@ -56,6 +59,21 @@ bfd_proto:
|
||||||
bfd_proto_start proto_name '{' bfd_proto_opts '}';
|
bfd_proto_start proto_name '{' bfd_proto_opts '}';
|
||||||
|
|
||||||
|
|
||||||
|
bfd_accept_item:
|
||||||
|
IPV4 { BFD_CFG->accept_ipv4 = 1; BFD_CFG->accept_ipv6 = 0; }
|
||||||
|
| IPV6 { BFD_CFG->accept_ipv4 = 0; BFD_CFG->accept_ipv6 = 1; }
|
||||||
|
| DIRECT { BFD_CFG->accept_direct = 1; BFD_CFG->accept_multihop = 0; }
|
||||||
|
| MULTIHOP { BFD_CFG->accept_direct = 0; BFD_CFG->accept_multihop = 1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
bfd_accept:
|
||||||
|
{
|
||||||
|
BFD_CFG->accept_ipv4 = BFD_CFG->accept_ipv6 = 1;
|
||||||
|
BFD_CFG->accept_direct = BFD_CFG->accept_multihop = 1;
|
||||||
|
}
|
||||||
|
| bfd_accept bfd_accept_item
|
||||||
|
|
||||||
|
|
||||||
bfd_iface_start:
|
bfd_iface_start:
|
||||||
{
|
{
|
||||||
this_ipatt = cfg_allocz(sizeof(struct bfd_iface_config));
|
this_ipatt = cfg_allocz(sizeof(struct bfd_iface_config));
|
||||||
|
|
Loading…
Reference in a new issue