]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
BFD: Option to specify which class of BFD sessions are accepted
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 28 Jan 2020 17:07:25 +0000 (18:07 +0100)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 28 Jan 2020 17:07:25 +0000 (18:07 +0100)
Allows to configure IPv4/IPv6-only or direct/multihop-only BFD protocol
instances.

doc/bird.sgml
proto/bfd/bfd.c
proto/bfd/bfd.h
proto/bfd/config.Y

index 8548c9c6f8addef116dccb780916f62fc7957128..b965da87828c18727a43b64b5a9f745091122f88 100644 (file)
@@ -1955,6 +1955,7 @@ milliseconds.
 
 <code>
 protocol bfd [&lt;name&gt;] {
+       accept [ipv4|ipv6] [direct|multihop];
        interface &lt;interface pattern&gt; {
                interval &lt;time&gt;;
                min rx interval &lt;time&gt;;
@@ -1989,6 +1990,14 @@ protocol bfd [&lt;name&gt;] {
 </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.
index a3e6d01cce82e82545d500a58dfda89fc720afda..b4c53754b6c89f8f09866b69bae23038d4ad51a1 100644 (file)
@@ -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)
index bc4fe969afbfd6fc2c68455a7e4d526ece7e5fad..5c2054cc39343ebdecbe0cca0bcc2c8d6b0a629d 100644 (file)
@@ -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
index ed416f2505be91c35bff1b66a68c3f74a355050a..84d12306c829c367e2c294daaf6e5a4894dc3e4d 100644 (file)
@@ -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));