summaryrefslogtreecommitdiffstats
path: root/bfdd
diff options
context:
space:
mode:
authorRafael Zalamena <rzalamena@opensourcerouting.org>2019-02-01 12:22:00 +0100
committerRafael Zalamena <rzalamena@opensourcerouting.org>2019-02-14 17:17:29 +0100
commitb333abc2959e492ee2c5ae903aaa6d857fdb7cdd (patch)
tree7bd5b7538907177400de1fb3f636b384dadcf4cf /bfdd
parentbfdd: slow down on peer connection loss (diff)
downloadfrr-b333abc2959e492ee2c5ae903aaa6d857fdb7cdd.tar.xz
frr-b333abc2959e492ee2c5ae903aaa6d857fdb7cdd.zip
bfdd: refactor session lookup
Use internal data to lookup sessions. This approach has two main advantages: * it uses less memory because it doesn't use strings for interface / vrf, it uses OS indexes instead; * prepares code to support VRF; Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Diffstat (limited to 'bfdd')
-rw-r--r--bfdd/bfd.c115
-rw-r--r--bfdd/bfd.h12
-rw-r--r--bfdd/bfd_packet.c112
-rw-r--r--bfdd/bfdd_vty.c25
-rw-r--r--bfdd/config.c17
-rw-r--r--bfdd/ptm_adapter.c21
6 files changed, 144 insertions, 158 deletions
diff --git a/bfdd/bfd.c b/bfdd/bfd.c
index ea3a586f9..5b407241f 100644
--- a/bfdd/bfd.c
+++ b/bfdd/bfd.c
@@ -53,6 +53,8 @@ struct bfd_session *bs_peer_find(struct bfd_peer_cfg *bpc)
{
struct bfd_session *bs;
struct peer_label *pl;
+ struct interface *ifp;
+ struct vrf *vrf;
struct bfd_mhop_key mhop;
struct bfd_shop_key shop;
@@ -70,17 +72,25 @@ struct bfd_session *bs_peer_find(struct bfd_peer_cfg *bpc)
memset(&mhop, 0, sizeof(mhop));
mhop.peer = bpc->bpc_peer;
mhop.local = bpc->bpc_local;
- if (bpc->bpc_has_vrfname)
- strlcpy(mhop.vrf_name, bpc->bpc_vrfname,
- sizeof(mhop.vrf_name));
+ if (bpc->bpc_has_vrfname) {
+ vrf = vrf_lookup_by_name(bpc->bpc_vrfname);
+ if (vrf == NULL)
+ return NULL;
+
+ mhop.vrfid = vrf->vrf_id;
+ }
bs = bfd_mhop_lookup(mhop);
} else {
memset(&shop, 0, sizeof(shop));
shop.peer = bpc->bpc_peer;
- if (bpc->bpc_has_localif)
- strlcpy(shop.port_name, bpc->bpc_localif,
- sizeof(shop.port_name));
+ if (bpc->bpc_has_localif) {
+ ifp = if_lookup_by_name_all_vrf(bpc->bpc_localif);
+ if (ifp == NULL)
+ return NULL;
+
+ shop.ifindex = ifp->ifindex;
+ }
bs = bfd_shop_lookup(shop);
}
@@ -211,25 +221,6 @@ void ptm_bfd_ses_dn(struct bfd_session *bfd, uint8_t diag)
}
}
-static int ptm_bfd_get_vrf_name(char *port_name, char *vrf_name)
-{
- struct bfd_iface *iface;
- struct bfd_vrf *vrf;
-
- if ((port_name == NULL) || (vrf_name == NULL))
- return -1;
-
- iface = bfd_iface_lookup(port_name);
- if (iface) {
- vrf = bfd_vrf_lookup(iface->vrf_id);
- if (vrf) {
- strlcpy(vrf_name, vrf->name, sizeof(vrf->name));
- return 0;
- }
- }
- return -1;
-}
-
static struct bfd_session *bfd_find_disc(struct sockaddr_any *sa,
uint32_t ldisc)
{
@@ -256,15 +247,15 @@ static struct bfd_session *bfd_find_disc(struct sockaddr_any *sa,
return NULL;
}
-struct bfd_session *ptm_bfd_sess_find(struct bfd_pkt *cp, char *port_name,
+struct bfd_session *ptm_bfd_sess_find(struct bfd_pkt *cp,
struct sockaddr_any *peer,
struct sockaddr_any *local,
- char *vrf_name, bool is_mhop)
+ ifindex_t ifindex, vrf_id_t vrfid,
+ bool is_mhop)
{
struct bfd_session *l_bfd = NULL;
struct bfd_mhop_key mhop;
struct bfd_shop_key shop;
- char vrf_buf[MAXNAMELEN];
/* Find our session using the ID signaled by the remote end. */
if (cp->discrs.remote_discr)
@@ -275,22 +266,13 @@ struct bfd_session *ptm_bfd_sess_find(struct bfd_pkt *cp, char *port_name,
memset(&mhop, 0, sizeof(mhop));
mhop.peer = *peer;
mhop.local = *local;
- if (vrf_name && vrf_name[0]) {
- strlcpy(mhop.vrf_name, vrf_name, sizeof(mhop.vrf_name));
- } else if (port_name && port_name[0]) {
- memset(vrf_buf, 0, sizeof(vrf_buf));
- if (ptm_bfd_get_vrf_name(port_name, vrf_buf) != -1)
- strlcpy(mhop.vrf_name, vrf_buf,
- sizeof(mhop.vrf_name));
- }
+ mhop.vrfid = vrfid;
l_bfd = bfd_mhop_lookup(mhop);
} else {
memset(&shop, 0, sizeof(shop));
shop.peer = *peer;
- if (port_name && port_name[0])
- strlcpy(shop.port_name, port_name,
- sizeof(shop.port_name));
+ shop.ifindex = ifindex;
l_bfd = bfd_shop_lookup(shop);
}
@@ -530,6 +512,7 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc)
{
struct bfd_session *bfd, *l_bfd;
struct interface *ifp = NULL;
+ struct vrf *vrf = NULL;
int psock;
/* check to see if this needs a new session */
@@ -548,16 +531,31 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc)
* First a few critical checks:
*
* * Check that the specified interface exists.
+ * * Check that the specified VRF exists.
* * Attempt to create the UDP socket (might fail if we exceed
* our limits).
*/
if (bpc->bpc_has_localif) {
- ifp = if_lookup_by_name(bpc->bpc_localif, VRF_DEFAULT);
+ ifp = if_lookup_by_name_all_vrf(bpc->bpc_localif);
if (ifp == NULL) {
log_error(
"session-new: specified interface doesn't exists.");
return NULL;
}
+
+ vrf = vrf_lookup_by_id(ifp->vrf_id);
+ if (vrf == NULL) {
+ log_error("session-new: specified VRF doesn't exists.");
+ return NULL;
+ }
+ }
+
+ if (bpc->bpc_has_vrfname) {
+ vrf = vrf_lookup_by_name(bpc->bpc_vrfname);
+ if (vrf == NULL) {
+ log_error("session-new: specified VRF doesn't exists.");
+ return NULL;
+ }
}
/*
@@ -582,6 +580,11 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc)
return NULL;
}
+ /* Assign VRF pointer. */
+ bfd->vrf = vrf;
+ if (bfd->vrf == NULL)
+ bfd->vrf = vrf_lookup_by_id(VRF_DEFAULT);
+
if (bpc->bpc_has_localif && !bpc->bpc_mhop)
bfd->ifp = ifp;
@@ -615,16 +618,18 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc)
BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_MH);
bfd->mhop.peer = bpc->bpc_peer;
bfd->mhop.local = bpc->bpc_local;
- if (bpc->bpc_has_vrfname)
- strlcpy(bfd->mhop.vrf_name, bpc->bpc_vrfname,
- sizeof(bfd->mhop.vrf_name));
+ if (vrf != NULL)
+ bfd->mhop.vrfid = vrf->vrf_id;
+ else
+ bfd->mhop.vrfid = VRF_DEFAULT;
bfd_mhop_insert(bfd);
} else {
bfd->shop.peer = bpc->bpc_peer;
- if (bpc->bpc_has_localif)
- strlcpy(bfd->shop.port_name, bpc->bpc_localif,
- sizeof(bfd->shop.port_name));
+ if (ifp != NULL)
+ bfd->shop.ifindex = ifp->ifindex;
+ else
+ bfd->shop.ifindex = IFINDEX_INTERNAL;
bfd_shop_insert(bfd);
}
@@ -1089,9 +1094,9 @@ const char *bs_to_string(struct bfd_session *bs)
" peer:%s local:%s", satostr(&bs->mhop.peer),
satostr(&bs->mhop.local));
- if (bs->mhop.vrf_name[0])
- snprintf(buf + pos, sizeof(buf) - pos, " vrf:%s",
- bs->mhop.vrf_name);
+ if (bs->mhop.vrfid != VRF_DEFAULT)
+ snprintf(buf + pos, sizeof(buf) - pos, " vrf:%u",
+ bs->mhop.vrfid);
} else {
pos += snprintf(buf + pos, sizeof(buf) - pos, " peer:%s",
satostr(&bs->shop.peer));
@@ -1101,9 +1106,9 @@ const char *bs_to_string(struct bfd_session *bs)
" local:%s",
satostr(&bs->local_address));
- if (bs->shop.port_name[0])
- snprintf(buf + pos, sizeof(buf) - pos, " interface:%s",
- bs->shop.port_name);
+ if (bs->shop.ifindex)
+ snprintf(buf + pos, sizeof(buf) - pos, " ifindex:%u",
+ bs->shop.ifindex);
}
return buf;
@@ -1229,7 +1234,7 @@ static void _shop_key(struct bfd_session *bs, const struct bfd_shop_key *shop)
static void _shop_key2(struct bfd_session *bs, const struct bfd_shop_key *shop)
{
_shop_key(bs, shop);
- memset(bs->shop.port_name, 0, sizeof(bs->shop.port_name));
+ bs->shop.ifindex = IFINDEX_INTERNAL;
}
static void _mhop_key(struct bfd_session *bs, const struct bfd_mhop_key *mhop)
@@ -1281,7 +1286,7 @@ struct bfd_session *bfd_shop_lookup(struct bfd_shop_key shop)
_shop_key(&bs, &shop);
bsp = hash_lookup(bfd_shop_hash, &bs);
- if (bsp == NULL && bs.shop.port_name[0] != 0) {
+ if (bsp == NULL && bs.shop.ifindex != 0) {
/*
* Since the local interface spec is optional, try
* searching the key without it as well.
@@ -1346,7 +1351,7 @@ struct bfd_session *bfd_shop_delete(struct bfd_shop_key shop)
_shop_key(&bs, &shop);
bsp = hash_release(bfd_shop_hash, &bs);
- if (bsp == NULL && shop.port_name[0] != 0) {
+ if (bsp == NULL && shop.ifindex != 0) {
/*
* Since the local interface spec is optional, try
* searching the key without it as well.
diff --git a/bfdd/bfd.h b/bfdd/bfd.h
index 2cd2b87a1..fba76e239 100644
--- a/bfdd/bfd.h
+++ b/bfdd/bfd.h
@@ -176,13 +176,13 @@ enum bfd_session_flags {
/* BFD session hash keys */
struct bfd_shop_key {
struct sockaddr_any peer;
- char port_name[MAXNAMELEN + 1];
+ ifindex_t ifindex;
};
struct bfd_mhop_key {
struct sockaddr_any peer;
struct sockaddr_any local;
- char vrf_name[MAXNAMELEN + 1];
+ vrf_id_t vrfid;
};
struct bfd_session_stats {
@@ -238,6 +238,7 @@ struct bfd_session {
struct sockaddr_any local_address;
struct sockaddr_any local_ip;
struct interface *ifp;
+ struct vrf *vrf;
uint8_t local_mac[ETHERNET_ADDRESS_LENGTH];
uint8_t peer_mac[ETHERNET_ADDRESS_LENGTH];
@@ -516,10 +517,9 @@ void ptm_bfd_echo_stop(struct bfd_session *bfd);
void ptm_bfd_echo_start(struct bfd_session *bfd);
void ptm_bfd_xmt_TO(struct bfd_session *bfd, int fbit);
void ptm_bfd_start_xmt_timer(struct bfd_session *bfd, bool is_echo);
-struct bfd_session *ptm_bfd_sess_find(struct bfd_pkt *cp, char *port_name,
- struct sockaddr_any *peer,
- struct sockaddr_any *local,
- char *vrf_name, bool is_mhop);
+struct bfd_session *ptm_bfd_sess_find(struct bfd_pkt *, struct sockaddr_any *,
+ struct sockaddr_any *, ifindex_t,
+ vrf_id_t, bool);
struct bfd_session *bs_peer_find(struct bfd_peer_cfg *bpc);
int bfd_session_update_label(struct bfd_session *bs, const char *nlabel);
diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c
index 7a7a5a5d9..18d6ad250 100644
--- a/bfdd/bfd_packet.c
+++ b/bfdd/bfd_packet.c
@@ -47,12 +47,10 @@ int _ptm_bfd_send(struct bfd_session *bs, uint16_t *port, const void *data,
static void bfd_sd_reschedule(int sd);
ssize_t bfd_recv_ipv4(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl,
- char *port, size_t portlen, char *vrfname,
- size_t vrfnamelen, struct sockaddr_any *local,
+ ifindex_t *ifindex, struct sockaddr_any *local,
struct sockaddr_any *peer);
ssize_t bfd_recv_ipv6(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl,
- char *port, size_t portlen, char *vrfname,
- size_t vrfnamelen, struct sockaddr_any *local,
+ ifindex_t *ifindex, struct sockaddr_any *local,
struct sockaddr_any *peer);
int bp_udp_send(int sd, uint8_t ttl, uint8_t *data, size_t datalen,
struct sockaddr *to, socklen_t tolen);
@@ -253,21 +251,16 @@ void ptm_bfd_snd(struct bfd_session *bfd, int fbit)
}
ssize_t bfd_recv_ipv4(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl,
- char *port, size_t portlen, char *vrfname,
- size_t vrfnamelen, struct sockaddr_any *local,
+ ifindex_t *ifindex, struct sockaddr_any *local,
struct sockaddr_any *peer)
{
- struct interface *ifp;
struct cmsghdr *cm;
- int ifindex;
ssize_t mlen;
struct sockaddr_in msgaddr;
struct msghdr msghdr;
struct iovec iov[1];
uint8_t cmsgbuf[255];
- port[0] = '\0';
-
/* Prepare the recvmsg params. */
iov[0].iov_base = msgbuf;
iov[0].iov_len = msgbuflen;
@@ -325,13 +318,7 @@ ssize_t bfd_recv_ipv4(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl,
local->sa_sin.sin_len = sizeof(local->sa_sin);
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
- ifp = if_lookup_by_index(pi->ipi_ifindex, VRF_DEFAULT);
- if (ifp == NULL)
- break;
-
- if (strlcpy(port, ifp->name, portlen) >= portlen)
- log_debug(
- "ipv4-recv: interface name truncated");
+ *ifindex = pi->ipi_ifindex;
break;
}
#endif /* BFD_LINUX */
@@ -366,31 +353,18 @@ ssize_t bfd_recv_ipv4(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl,
}
/* OS agnostic way of getting interface name. */
- if (port[0] == 0) {
- ifindex = getsockopt_ifindex(AF_INET, &msghdr);
- if (ifindex <= 0)
- return mlen;
-
- ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
- if (ifp == NULL)
- return mlen;
-
- if (strlcpy(port, ifp->name, portlen) >= portlen)
- log_debug("ipv4-recv: interface name truncated");
- }
+ if (*ifindex == IFINDEX_INTERNAL)
+ *ifindex = getsockopt_ifindex(AF_INET, &msghdr);
return mlen;
}
ssize_t bfd_recv_ipv6(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl,
- char *port, size_t portlen, char *vrfname,
- size_t vrfnamelen, struct sockaddr_any *local,
+ ifindex_t *ifindex, struct sockaddr_any *local,
struct sockaddr_any *peer)
{
- struct interface *ifp;
struct cmsghdr *cm;
struct in6_pktinfo *pi6 = NULL;
- int ifindex = 0;
ssize_t mlen;
uint32_t ttlval;
struct sockaddr_in6 msgaddr6;
@@ -445,24 +419,16 @@ ssize_t bfd_recv_ipv6(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl,
local->sa_sin6.sin6_len = sizeof(local->sa_sin6);
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
- ifindex = pi6->ipi6_ifindex;
- ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
- if (ifp == NULL)
- break;
-
- if (strlcpy(port, ifp->name, portlen)
- >= portlen)
- log_debug(
- "ipv6-recv: interface name truncated");
+ *ifindex = pi6->ipi6_ifindex;
}
}
}
/* Set scope ID for link local addresses. */
if (IN6_IS_ADDR_LINKLOCAL(&peer->sa_sin6.sin6_addr))
- peer->sa_sin6.sin6_scope_id = ifindex;
+ peer->sa_sin6.sin6_scope_id = *ifindex;
if (IN6_IS_ADDR_LINKLOCAL(&local->sa_sin6.sin6_addr))
- local->sa_sin6.sin6_scope_id = ifindex;
+ local->sa_sin6.sin6_scope_id = *ifindex;
return mlen;
}
@@ -497,8 +463,8 @@ static void bfd_sd_reschedule(int sd)
}
static void cp_debug(bool mhop, struct sockaddr_any *peer,
- struct sockaddr_any *local, const char *port,
- const char *vrf, const char *fmt, ...)
+ struct sockaddr_any *local, ifindex_t ifindex,
+ vrf_id_t vrfid, const char *fmt, ...)
{
char buf[512], peerstr[128], localstr[128], portstr[64], vrfstr[64];
va_list vl;
@@ -514,13 +480,13 @@ static void cp_debug(bool mhop, struct sockaddr_any *peer,
else
localstr[0] = 0;
- if (port[0])
- snprintf(portstr, sizeof(portstr), " port:%s", port);
+ if (ifindex != IFINDEX_INTERNAL)
+ snprintf(portstr, sizeof(portstr), " port:%u", ifindex);
else
portstr[0] = 0;
- if (vrf[0])
- snprintf(vrfstr, sizeof(vrfstr), " vrf:%s", port);
+ if (vrfid != VRF_DEFAULT)
+ snprintf(vrfstr, sizeof(vrfstr), " vrf:%u", vrfid);
else
vrfstr[0] = 0;
@@ -540,8 +506,9 @@ int bfd_recv_cb(struct thread *t)
bool is_mhop;
ssize_t mlen = 0;
uint8_t ttl;
+ vrf_id_t vrfid = VRF_DEFAULT;
+ ifindex_t ifindex = IFINDEX_INTERNAL;
struct sockaddr_any local, peer;
- char port[MAXNAMELEN + 1], vrfname[MAXNAMELEN + 1];
uint8_t msgbuf[1516];
/* Schedule next read. */
@@ -554,8 +521,6 @@ int bfd_recv_cb(struct thread *t)
}
/* Sanitize input/output. */
- memset(port, 0, sizeof(port));
- memset(vrfname, 0, sizeof(vrfname));
memset(&local, 0, sizeof(local));
memset(&peer, 0, sizeof(peer));
@@ -563,26 +528,24 @@ int bfd_recv_cb(struct thread *t)
is_mhop = false;
if (sd == bglobal.bg_shop || sd == bglobal.bg_mhop) {
is_mhop = sd == bglobal.bg_mhop;
- mlen = bfd_recv_ipv4(sd, msgbuf, sizeof(msgbuf), &ttl, port,
- sizeof(port), vrfname, sizeof(vrfname),
+ mlen = bfd_recv_ipv4(sd, msgbuf, sizeof(msgbuf), &ttl, &ifindex,
&local, &peer);
} else if (sd == bglobal.bg_shop6 || sd == bglobal.bg_mhop6) {
is_mhop = sd == bglobal.bg_mhop6;
- mlen = bfd_recv_ipv6(sd, msgbuf, sizeof(msgbuf), &ttl, port,
- sizeof(port), vrfname, sizeof(vrfname),
+ mlen = bfd_recv_ipv6(sd, msgbuf, sizeof(msgbuf), &ttl, &ifindex,
&local, &peer);
}
/* Implement RFC 5880 6.8.6 */
if (mlen < BFD_PKT_LEN) {
- cp_debug(is_mhop, &peer, &local, port, vrfname,
+ cp_debug(is_mhop, &peer, &local, ifindex, vrfid,
"too small (%ld bytes)", mlen);
return 0;
}
/* Validate packet TTL. */
if ((is_mhop == false) && (ttl != BFD_TTL_VAL)) {
- cp_debug(is_mhop, &peer, &local, port, vrfname,
+ cp_debug(is_mhop, &peer, &local, ifindex, vrfid,
"invalid TTL: %d expected %d", ttl, BFD_TTL_VAL);
return 0;
}
@@ -596,32 +559,32 @@ int bfd_recv_cb(struct thread *t)
*/
cp = (struct bfd_pkt *)(msgbuf);
if (BFD_GETVER(cp->diag) != BFD_VERSION) {
- cp_debug(is_mhop, &peer, &local, port, vrfname,
+ cp_debug(is_mhop, &peer, &local, ifindex, vrfid,
"bad version %d", BFD_GETVER(cp->diag));
return 0;
}
if (cp->detect_mult == 0) {
- cp_debug(is_mhop, &peer, &local, port, vrfname,
+ cp_debug(is_mhop, &peer, &local, ifindex, vrfid,
"detect multiplier set to zero");
return 0;
}
if ((cp->len < BFD_PKT_LEN) || (cp->len > mlen)) {
- cp_debug(is_mhop, &peer, &local, port, vrfname, "too small");
+ cp_debug(is_mhop, &peer, &local, ifindex, vrfid, "too small");
return 0;
}
if (cp->discrs.my_discr == 0) {
- cp_debug(is_mhop, &peer, &local, port, vrfname,
+ cp_debug(is_mhop, &peer, &local, ifindex, vrfid,
"'my discriminator' is zero");
return 0;
}
/* Find the session that this packet belongs. */
- bfd = ptm_bfd_sess_find(cp, port, &peer, &local, vrfname, is_mhop);
+ bfd = ptm_bfd_sess_find(cp, &peer, &local, ifindex, vrfid, is_mhop);
if (bfd == NULL) {
- cp_debug(is_mhop, &peer, &local, port, vrfname,
+ cp_debug(is_mhop, &peer, &local, ifindex, vrfid,
"no session found");
return 0;
}
@@ -634,7 +597,7 @@ int bfd_recv_cb(struct thread *t)
*/
if (is_mhop) {
if ((BFD_TTL_VAL - bfd->mh_ttl) > BFD_TTL_VAL) {
- cp_debug(is_mhop, &peer, &local, port, vrfname,
+ cp_debug(is_mhop, &peer, &local, ifindex, vrfid,
"exceeded max hop count (expected %d, got %d)",
bfd->mh_ttl, BFD_TTL_VAL);
return 0;
@@ -648,12 +611,12 @@ int bfd_recv_cb(struct thread *t)
* packet came in.
*/
if (bfd->ifp == NULL)
- bfd->ifp = if_lookup_by_name(port, VRF_DEFAULT);
+ bfd->ifp = if_lookup_by_index(ifindex, vrfid);
/* Log remote discriminator changes. */
if ((bfd->discrs.remote_discr != 0)
&& (bfd->discrs.remote_discr != ntohl(cp->discrs.my_discr)))
- cp_debug(is_mhop, &peer, &local, port, vrfname,
+ cp_debug(is_mhop, &peer, &local, ifindex, vrfid,
"remote discriminator mismatch (expected %d, got %d)",
bfd->discrs.remote_discr, ntohl(cp->discrs.my_discr));
@@ -711,21 +674,20 @@ int bp_bfd_echo_in(int sd, uint8_t *ttl, uint32_t *my_discr)
struct bfd_echo_pkt *bep;
ssize_t rlen;
struct sockaddr_any local, peer;
- char port[MAXNAMELEN + 1], vrfname[MAXNAMELEN + 1];
+ ifindex_t ifindex = IFINDEX_INTERNAL;
+ vrf_id_t vrfid = VRF_DEFAULT;
uint8_t msgbuf[1516];
if (sd == bglobal.bg_echo)
- rlen = bfd_recv_ipv4(sd, msgbuf, sizeof(msgbuf), ttl, port,
- sizeof(port), vrfname, sizeof(vrfname),
+ rlen = bfd_recv_ipv4(sd, msgbuf, sizeof(msgbuf), ttl, &ifindex,
&local, &peer);
else
- rlen = bfd_recv_ipv6(sd, msgbuf, sizeof(msgbuf), ttl, port,
- sizeof(port), vrfname, sizeof(vrfname),
+ rlen = bfd_recv_ipv6(sd, msgbuf, sizeof(msgbuf), ttl, &ifindex,
&local, &peer);
/* Short packet, better not risk reading it. */
if (rlen < (ssize_t)sizeof(*bep)) {
- cp_debug(false, &peer, &local, port, vrfname,
+ cp_debug(false, &peer, &local, ifindex, vrfid,
"small echo packet");
return -1;
}
@@ -743,7 +705,7 @@ int bp_bfd_echo_in(int sd, uint8_t *ttl, uint32_t *my_discr)
bep = (struct bfd_echo_pkt *)msgbuf;
*my_discr = ntohl(bep->my_discr);
if (*my_discr == 0) {
- cp_debug(false, &peer, &local, port, vrfname,
+ cp_debug(false, &peer, &local, ifindex, vrfid,
"invalid echo packet discriminator (zero)");
return -1;
}
diff --git a/bfdd/bfdd_vty.c b/bfdd/bfdd_vty.c
index 8ba8de982..71429ffbb 100644
--- a/bfdd/bfdd_vty.c
+++ b/bfdd/bfdd_vty.c
@@ -369,16 +369,16 @@ static void _display_peer_header(struct vty *vty, struct bfd_session *bs)
vty_out(vty, "\tpeer %s", satostr(&bs->mhop.peer));
vty_out(vty, " multihop");
vty_out(vty, " local-address %s", satostr(&bs->mhop.local));
- if (bs->mhop.vrf_name[0])
- vty_out(vty, " vrf %s", bs->mhop.vrf_name);
+ if (bs->mhop.vrfid != VRF_DEFAULT)
+ vty_out(vty, " vrf %s", bs->vrf->name);
vty_out(vty, "\n");
} else {
vty_out(vty, "\tpeer %s", satostr(&bs->shop.peer));
if (bs->local_address.sa_sin.sin_family != AF_UNSPEC)
vty_out(vty, " local-address %s",
satostr(&bs->local_address));
- if (bs->shop.port_name[0])
- vty_out(vty, " interface %s", bs->shop.port_name);
+ if (bs->shop.ifindex != IFINDEX_INTERNAL)
+ vty_out(vty, " interface %s", bs->ifp->name);
vty_out(vty, "\n");
}
@@ -454,17 +454,16 @@ static struct json_object *_peer_json_header(struct bfd_session *bs)
json_object_boolean_true_add(jo, "multihop");
json_object_string_add(jo, "peer", satostr(&bs->mhop.peer));
json_object_string_add(jo, "local", satostr(&bs->mhop.local));
- if (bs->mhop.vrf_name[0])
- json_object_string_add(jo, "vrf", bs->mhop.vrf_name);
+ if (bs->mhop.vrfid != VRF_DEFAULT)
+ json_object_string_add(jo, "vrf", bs->vrf->name);
} else {
json_object_boolean_false_add(jo, "multihop");
json_object_string_add(jo, "peer", satostr(&bs->shop.peer));
if (bs->local_address.sa_sin.sin_family != AF_UNSPEC)
json_object_string_add(jo, "local",
satostr(&bs->local_address));
- if (bs->shop.port_name[0])
- json_object_string_add(jo, "interface",
- bs->shop.port_name);
+ if (bs->shop.ifindex != IFINDEX_INTERNAL)
+ json_object_string_add(jo, "interface", bs->ifp->name);
}
if (bs->pl)
@@ -920,16 +919,16 @@ static void _bfdd_peer_write_config(struct hash_backet *hb, void *arg)
vty_out(vty, " peer %s", satostr(&bs->mhop.peer));
vty_out(vty, " multihop");
vty_out(vty, " local-address %s", satostr(&bs->mhop.local));
- if (bs->mhop.vrf_name[0])
- vty_out(vty, " vrf %s", bs->mhop.vrf_name);
+ if (bs->mhop.vrfid != VRF_DEFAULT)
+ vty_out(vty, " vrf %s", bs->vrf->name);
vty_out(vty, "\n");
} else {
vty_out(vty, " peer %s", satostr(&bs->shop.peer));
if (bs->local_address.sa_sin.sin_family != AF_UNSPEC)
vty_out(vty, " local-address %s",
satostr(&bs->local_address));
- if (bs->shop.port_name[0])
- vty_out(vty, " interface %s", bs->shop.port_name);
+ if (bs->shop.ifindex != IFINDEX_INTERNAL)
+ vty_out(vty, " interface %s", bs->ifp->name);
vty_out(vty, "\n");
}
diff --git a/bfdd/config.c b/bfdd/config.c
index 921fa2b97..9e3abcb1b 100644
--- a/bfdd/config.c
+++ b/bfdd/config.c
@@ -314,16 +314,16 @@ static int parse_peer_label_config(struct json_object *jo,
if (bpc->bpc_mhop) {
bpc->bpc_peer = pl->pl_bs->mhop.peer;
bpc->bpc_local = pl->pl_bs->mhop.local;
- if (pl->pl_bs->mhop.vrf_name[0]) {
+ if (pl->pl_bs->mhop.vrfid != VRF_DEFAULT) {
bpc->bpc_has_vrfname = true;
- strlcpy(bpc->bpc_vrfname, pl->pl_bs->mhop.vrf_name,
+ strlcpy(bpc->bpc_vrfname, pl->pl_bs->vrf->name,
sizeof(bpc->bpc_vrfname));
}
} else {
bpc->bpc_peer = pl->pl_bs->shop.peer;
- if (pl->pl_bs->shop.port_name[0]) {
+ if (pl->pl_bs->shop.ifindex != IFINDEX_INTERNAL) {
bpc->bpc_has_localif = true;
- strlcpy(bpc->bpc_localif, pl->pl_bs->shop.port_name,
+ strlcpy(bpc->bpc_localif, pl->pl_bs->ifp->name,
sizeof(bpc->bpc_localif));
}
}
@@ -531,9 +531,8 @@ static int json_object_add_peer(struct json_object *jo, struct bfd_session *bs)
satostr(&bs->mhop.peer));
json_object_string_add(jo, "local-address",
satostr(&bs->mhop.local));
- if (strlen(bs->mhop.vrf_name) > 0)
- json_object_string_add(jo, "vrf-name",
- bs->mhop.vrf_name);
+ if (bs->mhop.vrfid != VRF_DEFAULT)
+ json_object_string_add(jo, "vrf-name", bs->vrf->name);
} else {
json_object_boolean_false_add(jo, "multihop");
json_object_string_add(jo, "peer-address",
@@ -541,9 +540,9 @@ static int json_object_add_peer(struct json_object *jo, struct bfd_session *bs)
if (bs->local_address.sa_sin.sin_family != AF_UNSPEC)
json_object_string_add(jo, "local-address",
satostr(&bs->local_address));
- if (strlen(bs->shop.port_name) > 0)
+ if (bs->shop.ifindex != IFINDEX_INTERNAL)
json_object_string_add(jo, "local-interface",
- bs->shop.port_name);
+ bs->ifp->name);
}
if (bs->pl)
diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c
index a57167376..8ce33e527 100644
--- a/bfdd/ptm_adapter.c
+++ b/bfdd/ptm_adapter.c
@@ -618,6 +618,24 @@ static int bfdd_interface_update(int cmd, struct zclient *zc, uint16_t len,
return 0;
}
+static int bfdd_interface_vrf_update(int command __attribute__((__unused__)),
+ struct zclient *zclient,
+ zebra_size_t length
+ __attribute__((__unused__)),
+ vrf_id_t vrfid)
+{
+ struct interface *ifp;
+ vrf_id_t nvrfid;
+
+ ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrfid, &nvrfid);
+ if (ifp == NULL)
+ return 0;
+
+ if_update_to_new_vrf(ifp, nvrfid);
+
+ return 0;
+}
+
void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
{
zclient = zclient_new(master, &zclient_options_default);
@@ -637,6 +655,9 @@ void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
/* Learn interfaces from zebra instead of the OS. */
zclient->interface_add = bfdd_interface_update;
zclient->interface_delete = bfdd_interface_update;
+
+ /* Learn about interface VRF. */
+ zclient->interface_vrf_update = bfdd_interface_vrf_update;
}
void bfdd_zclient_stop(void)