Commit cf7ff995 authored by Ondrej Zajicek (work)'s avatar Ondrej Zajicek (work)
Browse files

BFD: Support for VRFs

Allow multiple BFD instances in separate VRFs, dispatch BFD requests
according to VRFs.

Thanks to Alexander Zubkov for notice and patches.
parent 2eaf65ec
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -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"); }

+8 −13
Original line number Diff line number Diff line
@@ -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,
};
+0 −4
Original line number Diff line number Diff line
@@ -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:
+2 −0
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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)
  {
Loading