mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-09 12:39:21 +00:00
Merge pull request #3600 from opensourcerouting/bfd-zebra-if
bfdd: use zebra API to learn about interfaces
This commit is contained in:
commit
25794e0f15
33
bfdd/bfd.c
33
bfdd/bfd.c
@ -540,6 +540,7 @@ static void bfd_session_free(struct bfd_session *bs)
|
|||||||
struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc)
|
struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc)
|
||||||
{
|
{
|
||||||
struct bfd_session *bfd, *l_bfd;
|
struct bfd_session *bfd, *l_bfd;
|
||||||
|
struct interface *ifp = NULL;
|
||||||
int psock;
|
int psock;
|
||||||
|
|
||||||
/* check to see if this needs a new session */
|
/* check to see if this needs a new session */
|
||||||
@ -552,6 +553,24 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No session found, we have to allocate a new one.
|
||||||
|
*
|
||||||
|
* First a few critical checks:
|
||||||
|
*
|
||||||
|
* * Check that the specified interface 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);
|
||||||
|
if (ifp == NULL) {
|
||||||
|
log_error(
|
||||||
|
"session-new: specified interface doesn't exists.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get socket for transmitting control packets. Note that if we
|
* Get socket for transmitting control packets. Note that if we
|
||||||
* could use the destination port (3784) for the source
|
* could use the destination port (3784) for the source
|
||||||
@ -574,19 +593,21 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bpc->bpc_has_localif && !bpc->bpc_mhop) {
|
if (bpc->bpc_has_localif && !bpc->bpc_mhop)
|
||||||
bfd->ifindex = ptm_bfd_fetch_ifindex(bpc->bpc_localif);
|
bfd->ifp = ifp;
|
||||||
ptm_bfd_fetch_local_mac(bpc->bpc_localif, bfd->local_mac);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bpc->bpc_ipv4 == false) {
|
if (bpc->bpc_ipv4 == false) {
|
||||||
BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_IPV6);
|
BFD_SET_FLAG(bfd->flags, BFD_SESS_FLAG_IPV6);
|
||||||
|
|
||||||
/* Set the IPv6 scope id for link-local addresses. */
|
/* Set the IPv6 scope id for link-local addresses. */
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(&bpc->bpc_local.sa_sin6.sin6_addr))
|
if (IN6_IS_ADDR_LINKLOCAL(&bpc->bpc_local.sa_sin6.sin6_addr))
|
||||||
bpc->bpc_local.sa_sin6.sin6_scope_id = bfd->ifindex;
|
bpc->bpc_local.sa_sin6.sin6_scope_id =
|
||||||
|
bfd->ifp != NULL ? bfd->ifp->ifindex
|
||||||
|
: IFINDEX_INTERNAL;
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(&bpc->bpc_peer.sa_sin6.sin6_addr))
|
if (IN6_IS_ADDR_LINKLOCAL(&bpc->bpc_peer.sa_sin6.sin6_addr))
|
||||||
bpc->bpc_peer.sa_sin6.sin6_scope_id = bfd->ifindex;
|
bpc->bpc_peer.sa_sin6.sin6_scope_id =
|
||||||
|
bfd->ifp != NULL ? bfd->ifp->ifindex
|
||||||
|
: IFINDEX_INTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the session */
|
/* Initialize the session */
|
||||||
|
20
bfdd/bfd.h
20
bfdd/bfd.h
@ -31,6 +31,7 @@
|
|||||||
#include "lib/libfrr.h"
|
#include "lib/libfrr.h"
|
||||||
#include "lib/qobj.h"
|
#include "lib/qobj.h"
|
||||||
#include "lib/queue.h"
|
#include "lib/queue.h"
|
||||||
|
#include "lib/vrf.h"
|
||||||
|
|
||||||
#include "bfdctl.h"
|
#include "bfdctl.h"
|
||||||
|
|
||||||
@ -237,7 +238,7 @@ struct bfd_session {
|
|||||||
|
|
||||||
struct sockaddr_any local_address;
|
struct sockaddr_any local_address;
|
||||||
struct sockaddr_any local_ip;
|
struct sockaddr_any local_ip;
|
||||||
int ifindex;
|
struct interface *ifp;
|
||||||
uint8_t local_mac[ETHERNET_ADDRESS_LENGTH];
|
uint8_t local_mac[ETHERNET_ADDRESS_LENGTH];
|
||||||
uint8_t peer_mac[ETHERNET_ADDRESS_LENGTH];
|
uint8_t peer_mac[ETHERNET_ADDRESS_LENGTH];
|
||||||
|
|
||||||
@ -512,7 +513,6 @@ struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc);
|
|||||||
int ptm_bfd_ses_del(struct bfd_peer_cfg *bpc);
|
int ptm_bfd_ses_del(struct bfd_peer_cfg *bpc);
|
||||||
void ptm_bfd_ses_dn(struct bfd_session *bfd, uint8_t diag);
|
void ptm_bfd_ses_dn(struct bfd_session *bfd, uint8_t diag);
|
||||||
void ptm_bfd_ses_up(struct bfd_session *bfd);
|
void ptm_bfd_ses_up(struct bfd_session *bfd);
|
||||||
void fetch_portname_from_ifindex(int ifindex, char *ifname, size_t ifnamelen);
|
|
||||||
void ptm_bfd_echo_stop(struct bfd_session *bfd, int polling);
|
void ptm_bfd_echo_stop(struct bfd_session *bfd, int polling);
|
||||||
void ptm_bfd_echo_start(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_xmt_TO(struct bfd_session *bfd, int fbit);
|
||||||
@ -584,20 +584,4 @@ void bfdd_zclient_stop(void);
|
|||||||
|
|
||||||
int ptm_bfd_notify(struct bfd_session *bs);
|
int ptm_bfd_notify(struct bfd_session *bs);
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* OS compatibility functions.
|
|
||||||
*/
|
|
||||||
#if defined(BFD_LINUX) || defined(BFD_BSD)
|
|
||||||
int ptm_bfd_fetch_ifindex(const char *ifname);
|
|
||||||
void ptm_bfd_fetch_local_mac(const char *ifname, uint8_t *mac);
|
|
||||||
void fetch_portname_from_ifindex(int ifindex, char *ifname, size_t ifnamelen);
|
|
||||||
#endif /* BFD_LINUX || BFD_BSD */
|
|
||||||
|
|
||||||
#ifdef BFD_BSD
|
|
||||||
ssize_t bsd_echo_sock_read(int sd, uint8_t *buf, ssize_t *buflen,
|
|
||||||
struct sockaddr_storage *ss, socklen_t *sslen,
|
|
||||||
uint8_t *ttl, uint32_t *id);
|
|
||||||
#endif /* BFD_BSD */
|
|
||||||
|
|
||||||
#endif /* _BFD_H_ */
|
#endif /* _BFD_H_ */
|
||||||
|
@ -241,6 +241,7 @@ ssize_t bfd_recv_ipv4(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl,
|
|||||||
size_t vrfnamelen, struct sockaddr_any *local,
|
size_t vrfnamelen, struct sockaddr_any *local,
|
||||||
struct sockaddr_any *peer)
|
struct sockaddr_any *peer)
|
||||||
{
|
{
|
||||||
|
struct interface *ifp;
|
||||||
struct cmsghdr *cm;
|
struct cmsghdr *cm;
|
||||||
int ifindex;
|
int ifindex;
|
||||||
ssize_t mlen;
|
ssize_t mlen;
|
||||||
@ -307,8 +308,14 @@ ssize_t bfd_recv_ipv4(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl,
|
|||||||
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
|
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
|
||||||
local->sa_sin.sin_len = sizeof(local->sa_sin);
|
local->sa_sin.sin_len = sizeof(local->sa_sin);
|
||||||
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
|
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
|
||||||
fetch_portname_from_ifindex(pi->ipi_ifindex, port,
|
|
||||||
portlen);
|
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");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif /* BFD_LINUX */
|
#endif /* BFD_LINUX */
|
||||||
@ -345,8 +352,15 @@ ssize_t bfd_recv_ipv4(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl,
|
|||||||
/* OS agnostic way of getting interface name. */
|
/* OS agnostic way of getting interface name. */
|
||||||
if (port[0] == 0) {
|
if (port[0] == 0) {
|
||||||
ifindex = getsockopt_ifindex(AF_INET, &msghdr);
|
ifindex = getsockopt_ifindex(AF_INET, &msghdr);
|
||||||
if (ifindex > 0)
|
if (ifindex <= 0)
|
||||||
fetch_portname_from_ifindex(ifindex, port, portlen);
|
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
return mlen;
|
return mlen;
|
||||||
@ -357,6 +371,7 @@ ssize_t bfd_recv_ipv6(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl,
|
|||||||
size_t vrfnamelen, struct sockaddr_any *local,
|
size_t vrfnamelen, struct sockaddr_any *local,
|
||||||
struct sockaddr_any *peer)
|
struct sockaddr_any *peer)
|
||||||
{
|
{
|
||||||
|
struct interface *ifp;
|
||||||
struct cmsghdr *cm;
|
struct cmsghdr *cm;
|
||||||
struct in6_pktinfo *pi6 = NULL;
|
struct in6_pktinfo *pi6 = NULL;
|
||||||
int ifindex = 0;
|
int ifindex = 0;
|
||||||
@ -413,9 +428,16 @@ ssize_t bfd_recv_ipv6(int sd, uint8_t *msgbuf, size_t msgbuflen, uint8_t *ttl,
|
|||||||
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
|
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
|
||||||
local->sa_sin6.sin6_len = sizeof(local->sa_sin6);
|
local->sa_sin6.sin6_len = sizeof(local->sa_sin6);
|
||||||
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
|
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
|
||||||
fetch_portname_from_ifindex(pi6->ipi6_ifindex,
|
|
||||||
port, portlen);
|
|
||||||
ifindex = pi6->ipi6_ifindex;
|
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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -610,8 +632,8 @@ int bfd_recv_cb(struct thread *t)
|
|||||||
* If no interface was detected, save the interface where the
|
* If no interface was detected, save the interface where the
|
||||||
* packet came in.
|
* packet came in.
|
||||||
*/
|
*/
|
||||||
if (bfd->ifindex == 0)
|
if (bfd->ifp == NULL)
|
||||||
bfd->ifindex = ptm_bfd_fetch_ifindex(port);
|
bfd->ifp = if_lookup_by_name(port, VRF_DEFAULT);
|
||||||
|
|
||||||
/* Log remote discriminator changes. */
|
/* Log remote discriminator changes. */
|
||||||
if ((bfd->discrs.remote_discr != 0)
|
if ((bfd->discrs.remote_discr != 0)
|
||||||
@ -1046,7 +1068,8 @@ int bp_peer_socket(struct bfd_peer_cfg *bpc)
|
|||||||
|
|
||||||
int bp_peer_socketv6(struct bfd_peer_cfg *bpc)
|
int bp_peer_socketv6(struct bfd_peer_cfg *bpc)
|
||||||
{
|
{
|
||||||
int sd, pcount, ifindex;
|
struct interface *ifp;
|
||||||
|
int sd, pcount;
|
||||||
struct sockaddr_in6 sin6;
|
struct sockaddr_in6 sin6;
|
||||||
static int srcPort = BFD_SRCPORTINIT;
|
static int srcPort = BFD_SRCPORTINIT;
|
||||||
|
|
||||||
@ -1076,9 +1099,11 @@ int bp_peer_socketv6(struct bfd_peer_cfg *bpc)
|
|||||||
sin6.sin6_len = sizeof(sin6);
|
sin6.sin6_len = sizeof(sin6);
|
||||||
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
|
#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */
|
||||||
sin6 = bpc->bpc_local.sa_sin6;
|
sin6 = bpc->bpc_local.sa_sin6;
|
||||||
ifindex = ptm_bfd_fetch_ifindex(bpc->bpc_localif);
|
if (IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr)) {
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr))
|
ifp = if_lookup_by_name(bpc->bpc_localif, VRF_DEFAULT);
|
||||||
sin6.sin6_scope_id = ifindex;
|
sin6.sin6_scope_id =
|
||||||
|
(ifp != NULL) ? ifp->ifindex : IFINDEX_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (bpc->bpc_has_localif) {
|
if (bpc->bpc_has_localif) {
|
||||||
if (bp_bind_dev(sd, bpc->bpc_localif) != 0) {
|
if (bp_bind_dev(sd, bpc->bpc_localif) != 0) {
|
||||||
|
64
bfdd/bsd.c
64
bfdd/bsd.c
@ -35,70 +35,6 @@
|
|||||||
/*
|
/*
|
||||||
* Definitions.
|
* Definitions.
|
||||||
*/
|
*/
|
||||||
int ptm_bfd_fetch_ifindex(const char *ifname)
|
|
||||||
{
|
|
||||||
return if_nametoindex(ifname);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ptm_bfd_fetch_local_mac(const char *ifname, uint8_t *mac)
|
|
||||||
{
|
|
||||||
struct ifaddrs *ifap, *ifa;
|
|
||||||
struct if_data *ifi;
|
|
||||||
struct sockaddr_dl *sdl;
|
|
||||||
size_t maclen;
|
|
||||||
|
|
||||||
/* Always clean the target, zeroed macs mean failure. */
|
|
||||||
memset(mac, 0, ETHERNET_ADDRESS_LENGTH);
|
|
||||||
|
|
||||||
if (getifaddrs(&ifap) != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
|
|
||||||
/* Find interface with that name. */
|
|
||||||
if (strcmp(ifa->ifa_name, ifname) != 0)
|
|
||||||
continue;
|
|
||||||
/* Skip non link addresses. We want the MAC address. */
|
|
||||||
if (ifa->ifa_addr->sa_family != AF_LINK)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
sdl = (struct sockaddr_dl *)ifa->ifa_addr;
|
|
||||||
ifi = (struct if_data *)ifa->ifa_data;
|
|
||||||
/* Skip non ethernet related data. */
|
|
||||||
if (ifi->ifi_type != IFT_ETHER)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (sdl->sdl_alen != ETHERNET_ADDRESS_LENGTH)
|
|
||||||
log_warning("%s:%d mac address length %d (expected %d)",
|
|
||||||
__func__, __LINE__, sdl->sdl_alen,
|
|
||||||
ETHERNET_ADDRESS_LENGTH);
|
|
||||||
|
|
||||||
maclen = (sdl->sdl_alen > ETHERNET_ADDRESS_LENGTH)
|
|
||||||
? ETHERNET_ADDRESS_LENGTH
|
|
||||||
: sdl->sdl_alen;
|
|
||||||
memcpy(mac, LLADDR(sdl), maclen);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
freeifaddrs(ifap);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Was _fetch_portname_from_ifindex() */
|
|
||||||
void fetch_portname_from_ifindex(int ifindex, char *ifname, size_t ifnamelen)
|
|
||||||
{
|
|
||||||
char ifname_tmp[IF_NAMESIZE];
|
|
||||||
|
|
||||||
/* Set ifname to empty to signalize failures. */
|
|
||||||
memset(ifname, 0, ifnamelen);
|
|
||||||
|
|
||||||
if (if_indextoname(ifindex, ifname_tmp) == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (strlcpy(ifname, ifname_tmp, ifnamelen) > ifnamelen)
|
|
||||||
log_warning("%s:%d interface name truncated", __func__,
|
|
||||||
__LINE__);
|
|
||||||
}
|
|
||||||
|
|
||||||
int bp_bind_dev(int sd, const char *dev)
|
int bp_bind_dev(int sd, const char *dev)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
58
bfdd/linux.c
58
bfdd/linux.c
@ -29,64 +29,6 @@
|
|||||||
/*
|
/*
|
||||||
* Definitions.
|
* Definitions.
|
||||||
*/
|
*/
|
||||||
int ptm_bfd_fetch_ifindex(const char *ifname)
|
|
||||||
{
|
|
||||||
struct ifreq ifr;
|
|
||||||
|
|
||||||
if (strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name))
|
|
||||||
> sizeof(ifr.ifr_name))
|
|
||||||
log_error("interface-to-index: name truncated ('%s' -> '%s')",
|
|
||||||
ifr.ifr_name, ifname);
|
|
||||||
|
|
||||||
if (ioctl(bglobal.bg_shop, SIOCGIFINDEX, &ifr) == -1) {
|
|
||||||
log_error("interface-to-index: %s translation failed: %s",
|
|
||||||
ifname, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ifr.ifr_ifindex;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ptm_bfd_fetch_local_mac(const char *ifname, uint8_t *mac)
|
|
||||||
{
|
|
||||||
struct ifreq ifr;
|
|
||||||
|
|
||||||
if (strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name))
|
|
||||||
> sizeof(ifr.ifr_name))
|
|
||||||
log_error("interface-mac: name truncated ('%s' -> '%s')",
|
|
||||||
ifr.ifr_name, ifname);
|
|
||||||
|
|
||||||
if (ioctl(bglobal.bg_shop, SIOCGIFHWADDR, &ifr) == -1) {
|
|
||||||
log_error("interface-mac: %s MAC retrieval failed: %s", ifname,
|
|
||||||
strerror(errno));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(mac, ifr.ifr_hwaddr.sa_data, ETHERNET_ADDRESS_LENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Was _fetch_portname_from_ifindex() */
|
|
||||||
void fetch_portname_from_ifindex(int ifindex, char *ifname, size_t ifnamelen)
|
|
||||||
{
|
|
||||||
struct ifreq ifr;
|
|
||||||
|
|
||||||
ifname[0] = 0;
|
|
||||||
|
|
||||||
memset(&ifr, 0, sizeof(ifr));
|
|
||||||
ifr.ifr_ifindex = ifindex;
|
|
||||||
|
|
||||||
if (ioctl(bglobal.bg_shop, SIOCGIFNAME, &ifr) == -1) {
|
|
||||||
log_error("index-to-interface: index %d failure: %s", ifindex,
|
|
||||||
strerror(errno));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlcpy(ifname, ifr.ifr_name, ifnamelen) >= ifnamelen)
|
|
||||||
log_debug("index-to-interface: name truncated '%s' -> '%s'",
|
|
||||||
ifr.ifr_name, ifname);
|
|
||||||
}
|
|
||||||
|
|
||||||
int bp_bind_dev(int sd __attribute__((__unused__)),
|
int bp_bind_dev(int sd __attribute__((__unused__)),
|
||||||
const char *dev __attribute__((__unused__)))
|
const char *dev __attribute__((__unused__)))
|
||||||
{
|
{
|
||||||
|
@ -189,7 +189,10 @@ int ptm_bfd_notify(struct bfd_session *bs)
|
|||||||
stream_putl(msg, ZEBRA_INTERFACE_BFD_DEST_UPDATE);
|
stream_putl(msg, ZEBRA_INTERFACE_BFD_DEST_UPDATE);
|
||||||
|
|
||||||
/* NOTE: Interface is a shortcut to avoid comparing source address. */
|
/* NOTE: Interface is a shortcut to avoid comparing source address. */
|
||||||
stream_putl(msg, bs->ifindex);
|
if (bs->ifp != NULL)
|
||||||
|
stream_putl(msg, bs->ifp->ifindex);
|
||||||
|
else
|
||||||
|
stream_putl(msg, IFINDEX_INTERNAL);
|
||||||
|
|
||||||
/* BFD destination prefix information. */
|
/* BFD destination prefix information. */
|
||||||
if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH))
|
if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH))
|
||||||
@ -287,6 +290,7 @@ stream_failure:
|
|||||||
static int _ptm_msg_read(struct stream *msg, int command,
|
static int _ptm_msg_read(struct stream *msg, int command,
|
||||||
struct bfd_peer_cfg *bpc, struct ptm_client **pc)
|
struct bfd_peer_cfg *bpc, struct ptm_client **pc)
|
||||||
{
|
{
|
||||||
|
struct interface *ifp;
|
||||||
uint32_t pid;
|
uint32_t pid;
|
||||||
uint8_t ttl __attribute__((unused));
|
uint8_t ttl __attribute__((unused));
|
||||||
size_t ifnamelen;
|
size_t ifnamelen;
|
||||||
@ -393,9 +397,19 @@ static int _ptm_msg_read(struct stream *msg, int command,
|
|||||||
*/
|
*/
|
||||||
if (bpc->bpc_ipv4 == false
|
if (bpc->bpc_ipv4 == false
|
||||||
&& IN6_IS_ADDR_LINKLOCAL(
|
&& IN6_IS_ADDR_LINKLOCAL(
|
||||||
&bpc->bpc_peer.sa_sin6.sin6_addr))
|
&bpc->bpc_peer.sa_sin6.sin6_addr)) {
|
||||||
|
ifp = if_lookup_by_name_all_vrf(
|
||||||
|
bpc->bpc_localif);
|
||||||
|
if (ifp == NULL) {
|
||||||
|
log_error(
|
||||||
|
"ptm-read: interface %s doesn't exists",
|
||||||
|
bpc->bpc_localif);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
bpc->bpc_peer.sa_sin6.sin6_scope_id =
|
bpc->bpc_peer.sa_sin6.sin6_scope_id =
|
||||||
ptm_bfd_fetch_ifindex(bpc->bpc_localif);
|
ifp->ifindex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -576,9 +590,34 @@ static void bfdd_zebra_connected(struct zclient *zc)
|
|||||||
stream_putl(msg, ZEBRA_BFD_DEST_REPLAY);
|
stream_putl(msg, ZEBRA_BFD_DEST_REPLAY);
|
||||||
stream_putw_at(msg, 0, stream_get_endp(msg));
|
stream_putw_at(msg, 0, stream_get_endp(msg));
|
||||||
|
|
||||||
|
/* Ask for interfaces information. */
|
||||||
|
zclient_create_header(msg, ZEBRA_INTERFACE_ADD, VRF_DEFAULT);
|
||||||
|
|
||||||
|
/* Send requests. */
|
||||||
zclient_send_message(zclient);
|
zclient_send_message(zclient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int bfdd_interface_update(int cmd, struct zclient *zc, uint16_t len,
|
||||||
|
vrf_id_t vrfid)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* `zebra_interface_add_read` will handle the interface creation
|
||||||
|
* on `lib/if.c`. We'll use that data structure instead of
|
||||||
|
* rolling our own.
|
||||||
|
*/
|
||||||
|
if (cmd == ZEBRA_INTERFACE_ADD) {
|
||||||
|
zebra_interface_add_read(zc->ibuf, vrfid);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update interface information. */
|
||||||
|
zebra_interface_state_read(zc->ibuf, vrfid);
|
||||||
|
|
||||||
|
/* TODO: stop all sessions using this interface. */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
|
void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
|
||||||
{
|
{
|
||||||
zclient = zclient_new(master, &zclient_options_default);
|
zclient = zclient_new(master, &zclient_options_default);
|
||||||
@ -594,6 +633,10 @@ void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
|
|||||||
|
|
||||||
/* Send replay request on zebra connect. */
|
/* Send replay request on zebra connect. */
|
||||||
zclient->zebra_connected = bfdd_zebra_connected;
|
zclient->zebra_connected = bfdd_zebra_connected;
|
||||||
|
|
||||||
|
/* Learn interfaces from zebra instead of the OS. */
|
||||||
|
zclient->interface_add = bfdd_interface_update;
|
||||||
|
zclient->interface_delete = bfdd_interface_update;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bfdd_zclient_stop(void)
|
void bfdd_zclient_stop(void)
|
||||||
|
Loading…
Reference in New Issue
Block a user