]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
BFD: Support for VRFs
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Wed, 17 Jul 2019 14:20:35 +0000 (16:20 +0200)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Wed, 17 Jul 2019 14:20:35 +0000 (16:20 +0200)
Allow multiple BFD instances in separate VRFs, dispatch BFD requests
according to VRFs.

Thanks to Alexander Zubkov for notice and patches.

nest/bfd.h
proto/bfd/bfd.c
proto/bfd/config.Y
proto/bfd/packets.c
proto/bgp/bgp.c
proto/ospf/neighbor.c
proto/rip/rip.c
proto/static/static.c

index 04d6c00176631adb4cad23fff0e3ac98c70371f2..36add991fd5a662478aa638922213968dcb8f20e 100644 (file)
@@ -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 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"); }
 
index fdcd72255b85c61410bda30c2e345fd871d57f39..151e0e1d528de8cb89f0a5bc74ea029adcd1dc96 100644 (file)
@@ -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;
   }
 
@@ -1051,15 +1056,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,
 };
index 3f5714fdb8be6acdd2eba34c8698c1b39349c2cf..53977dfbfd6704b9058ea1512c21ab8ac05a9460 100644 (file)
@@ -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:
index 6d5151eadfec9ec73dddc206b23e5e6914203ac1..703c6e28a7fdfbc5c801ba2f6d876ee0131681ca 100644 (file)
@@ -413,6 +413,7 @@ bfd_open_rx_sk(struct bfd_proto *p, int multihop, int af)
   sk->type = SK_UDP;
   sk->subtype = af;
   sk->sport = !multihop ? BFD_CONTROL_PORT : BFD_MULTI_CTL_PORT;
+  sk->vrf = p->p.vrf;
   sk->data = p;
 
   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->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;
index cfc31ed0093f1fc936299a0366aa6d32a0a4d027..98e66c67421efe620fa12e07ab88e6aaf5706259 100644 (file)
@@ -1371,7 +1371,7 @@ bgp_update_bfd(struct bgp_proto *p, int use_bfd)
   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->cf->multihop ? NULL : p->neigh->iface,
-                                    bgp_bfd_notify, p);
+                                    p->p.vrf, bgp_bfd_notify, p);
 
   if (!use_bfd && p->bfd_req)
   {
index 50ef6a498be7db3077bb872b39dfe5eb4af593db..112625c8af48b1fea05def4259935f1845169ea3 100644 (file)
@@ -771,8 +771,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)
index 91c0058850666bcb8f80999709833ad5f7b01664..4559310ebb0ff6b0db342677e1b508080c9d9125 100644 (file)
@@ -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;
     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)
index 75a74ad0e33ef1bb1c84b639fab7c21d0bf7647f..609263497821d11f0afcda0324d7826c723b3bfc 100644 (file)
@@ -159,7 +159,8 @@ static_update_bfd(struct static_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->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);
   }