diff options
author | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2020-01-28 18:07:25 +0100 |
---|---|---|
committer | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2020-01-28 18:07:25 +0100 |
commit | 7f9adafc109d576d5249c25ef284606dbac4adfa (patch) | |
tree | ca66bc6bf3598b0659569385fa02e6e67bb92585 | |
parent | 9f2670277cc0d56d3364d4784348056174175aba (diff) |
BFD: Option to specify which class of BFD sessions are accepted
Allows to configure IPv4/IPv6-only or direct/multihop-only BFD protocol
instances.
-rw-r--r-- | doc/bird.sgml | 9 | ||||
-rw-r--r-- | proto/bfd/bfd.c | 34 | ||||
-rw-r--r-- | proto/bfd/bfd.h | 4 | ||||
-rw-r--r-- | proto/bfd/config.Y | 20 |
4 files changed, 61 insertions, 6 deletions
diff --git a/doc/bird.sgml b/doc/bird.sgml index 8548c9c6..b965da87 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1955,6 +1955,7 @@ milliseconds. <code> protocol bfd [<name>] { + accept [ipv4|ipv6] [direct|multihop]; interface <interface pattern> { interval <time>; min rx interval <time>; @@ -1989,6 +1990,14 @@ protocol bfd [<name>] { </code> <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> Interface definitions allow to specify options for sessions associated with such interfaces and also may contain interface specific options. diff --git a/proto/bfd/bfd.c b/proto/bfd/bfd.c index a3e6d01c..b4c53754 100644 --- a/proto/bfd/bfd.c +++ b/proto/bfd/bfd.c @@ -624,9 +624,17 @@ bfd_request_notify(struct bfd_request *req, u8 state, u8 diag) static int 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)) 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); u8 state, diag; @@ -986,10 +994,19 @@ bfd_start(struct proto *P) add_tail(&bfd_proto_list, &p->bfd_node); birdloop_enter(p->loop); - p->rx4_1 = bfd_open_rx_sk(p, 0, SK_IPV4); - p->rx4_m = bfd_open_rx_sk(p, 1, SK_IPV4); - p->rx6_1 = bfd_open_rx_sk(p, 0, SK_IPV6); - p->rx6_m = bfd_open_rx_sk(p, 1, SK_IPV6); + + if (cf->accept_ipv4 && cf->accept_direct) + 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); + + if (cf->accept_ipv6 && cf->accept_direct) + 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); + birdloop_leave(p->loop); bfd_take_requests(p); @@ -1034,10 +1051,17 @@ static int bfd_reconfigure(struct proto *P, struct proto_config *c) { 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_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); WALK_LIST(ifa, p->iface_list) diff --git a/proto/bfd/bfd.h b/proto/bfd/bfd.h index bc4fe969..5c2054cc 100644 --- a/proto/bfd/bfd.h +++ b/proto/bfd/bfd.h @@ -43,6 +43,10 @@ struct bfd_config list patt_list; /* List of iface configs (struct bfd_iface_config) */ list neigh_list; /* List of configured neighbors (struct bfd_neighbor) */ struct bfd_iface_config *multihop; /* Multihop pseudoiface config */ + u8 accept_ipv4; + u8 accept_ipv6; + u8 accept_direct; + u8 accept_multihop; }; struct bfd_iface_config diff --git a/proto/bfd/config.Y b/proto/bfd/config.Y index ed416f25..84d12306 100644 --- a/proto/bfd/config.Y +++ b/proto/bfd/config.Y @@ -23,7 +23,7 @@ CF_DECLS CF_KEYWORDS(BFD, MIN, IDLE, RX, TX, INTERVAL, MULTIPLIER, PASSIVE, 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 <a> bfd_neigh_local @@ -38,10 +38,13 @@ 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); + BFD_CFG->accept_ipv4 = BFD_CFG->accept_ipv6 = 1; + BFD_CFG->accept_direct = BFD_CFG->accept_multihop = 1; }; bfd_proto_item: proto_item + | ACCEPT bfd_accept | INTERFACE bfd_iface | MULTIHOP bfd_multihop | NEIGHBOR bfd_neighbor @@ -56,6 +59,21 @@ bfd_proto: 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: { this_ipatt = cfg_allocz(sizeof(struct bfd_iface_config)); |