]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bfdd: refactor session lookup
authorRafael Zalamena <rzalamena@opensourcerouting.org>
Fri, 1 Feb 2019 11:22:00 +0000 (09:22 -0200)
committerRafael Zalamena <rzalamena@opensourcerouting.org>
Thu, 14 Feb 2019 16:17:29 +0000 (14:17 -0200)
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>
bfdd/bfd.c
bfdd/bfd.h
bfdd/bfd_packet.c
bfdd/bfdd_vty.c
bfdd/config.c
bfdd/ptm_adapter.c

index ea3a586f95b08afde19d6dfe273cd9aebca1804e..5b407241f615ba817cb3770eaf3b118fdd7a9c32 100644 (file)
@@ -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.
index 2cd2b87a1f85645784e6584a13c84b5e3827aeab..fba76e2396f66ab3b40ed4c3f306c1c8b935735b 100644 (file)
@@ -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);
index 7a7a5a5d969e1db16f70c70d4295e19ad574306c..18d6ad25025d50aef1f2c3cae5bb8390fccb0aad 100644 (file)
@@ -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;
        }
index 8ba8de9823d85f9f3f44fd6b7d5c0c195f50669e..71429ffbbf9b17d9b98139c018980c9e57ced32d 100644 (file)
@@ -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");
        }
 
index 921fa2b973a00f3f0ec0b6155c8ecf6d4f7c3f6c..9e3abcb1b8aaa9cece49a269b298632cc293aece 100644 (file)
@@ -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)
index a57167376a75eaf32b16716f5736b79c6589ce2c..8ce33e5270ccc72607c708335b560e545e78a4ea 100644 (file)
@@ -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)