diff options
author | Rafael Zalamena <rzalamena@opensourcerouting.org> | 2019-02-01 12:22:00 +0100 |
---|---|---|
committer | Rafael Zalamena <rzalamena@opensourcerouting.org> | 2019-02-14 17:17:29 +0100 |
commit | b333abc2959e492ee2c5ae903aaa6d857fdb7cdd (patch) | |
tree | 7bd5b7538907177400de1fb3f636b384dadcf4cf /bfdd | |
parent | bfdd: slow down on peer connection loss (diff) | |
download | frr-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.c | 115 | ||||
-rw-r--r-- | bfdd/bfd.h | 12 | ||||
-rw-r--r-- | bfdd/bfd_packet.c | 112 | ||||
-rw-r--r-- | bfdd/bfdd_vty.c | 25 | ||||
-rw-r--r-- | bfdd/config.c | 17 | ||||
-rw-r--r-- | bfdd/ptm_adapter.c | 21 |
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) |