On Wed, Jul 17, 2019 at 2:47 PM Ondrej Zajicek <santi...@crfreenet.org> wrote:
>
> On Wed, Jul 17, 2019 at 12:05:49PM +0200, Alexander Zubkov wrote:
> > Hello,
> >
> > I made small fix for myself, that allow bfd to work in one VRF,
> > defined in the configuration:
> >
> > --- a/proto/bfd/packets.c
> > +++ b/proto/bfd/packets.c
> > @@ -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;
> >
> > It works, but I suppose vrf change should be handled somehow in
> > bfd_reconfigure also. Not sure if reopening socket is enough or it
>
> Hello
>
> This would work, it is necessary to also set sk->vrf for bfd_open_tx_sk()
> foir multihop BFD. It is not necessary to handle it in bfd_reconfigure(),
> as VRF change is handled in generic code in proto_reconfigure().
>
> I also just implemented BFD request dispatch based on VRFs to handle multiple
> VRFs and multiple BFD instances.

Oh! I was just trying to figure out it myself today too. See the
attached patch. :)
It adds vrf parameter to the bfd_request and bfd_request_session
funciton. Not sure though that I passed vrf correctly from all
protocols.

>
> --
> Elen sila lumenn' omentielvo
>
> Ondrej 'Santiago' Zajicek (email: santi...@crfreenet.org)
> OpenPGP encrypted e-mails preferred (KeyID 0x11DEADC3, wwwkeys.pgp.net)
> "To err is human -- to blame it on a computer is even more so."
diff --git a/nest/bfd.h b/nest/bfd.h
index 04d6c00..36add99 100644
--- a/nest/bfd.h
+++ b/nest/bfd.h
@@ -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"); }
 
diff --git a/proto/bfd/bfd.c b/proto/bfd/bfd.c
index fdcd722..28b483b 100644
--- a/proto/bfd/bfd.c
+++ b/proto/bfd/bfd.c
@@ -627,6 +627,9 @@ bfd_add_request(struct bfd_proto *p, struct bfd_request *req)
   struct bfd_session *s = bfd_find_session_by_addr(p, req->addr);
   u8 state, diag;
 
+  if (p->p.vrf != req->vrf)
+    return 0;
+
   if (!s)
     s = bfd_add_session(p, req->addr, req->local, req->iface);
 
@@ -686,7 +689,8 @@ static struct resclass bfd_request_class;
 
 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 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;
   }
 
diff --git a/proto/bfd/packets.c b/proto/bfd/packets.c
index 6d5151e..703c6e2 100644
--- a/proto/bfd/packets.c
+++ b/proto/bfd/packets.c
@@ -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;
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index cfc31ed..98e66c6 100644
--- a/proto/bgp/bgp.c
+++ b/proto/bgp/bgp.c
@@ -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)
   {
diff --git a/proto/ospf/neighbor.c b/proto/ospf/neighbor.c
index 50ef6a4..a0fd93f 100644
--- a/proto/ospf/neighbor.c
+++ b/proto/ospf/neighbor.c
@@ -772,7 +772,8 @@ void
 ospf_neigh_update_bfd(struct ospf_neighbor *n, int use_bfd)
 {
   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, n->ifa->oa->po,
 				     ospf_neigh_bfd_hook, n);
 
   if (!use_bfd && n->bfd_req)
diff --git a/proto/rip/rip.c b/proto/rip/rip.c
index 91c0058..99936b6 100644
--- a/proto/rip/rip.c
+++ b/proto/rip/rip.c
@@ -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)
diff --git a/proto/static/static.c b/proto/static/static.c
index 75a74ad..f388634 100644
--- a/proto/static/static.c
+++ b/proto/static/static.c
@@ -160,7 +160,7 @@ static_update_bfd(struct static_proto *p, struct static_route *r)
   {
     // 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,
-				     static_bfd_notify, r);
+				     p->p.vrf, static_bfd_notify, r);
   }
 
   if (!bfd_up && r->bfd_req)

Reply via email to