mirror of
https://git.proxmox.com/git/mirror_frr
synced 2026-01-03 20:43:14 +00:00
lib: add vrf-lite bind capability to vrf APIs
Because socket creation is tightly linked with socket binding for vrf lite, the proposal is made to extend socket creation APIs and to create a new API called vrf_bind that applies to vrf lite. The passed interface name is the interface that will be bound to the socket passed. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
parent
516d7591d6
commit
0f4977c668
@ -571,7 +571,7 @@ int bgp_connect(struct peer *peer)
|
||||
if (bgpd_privs.change(ZPRIVS_RAISE))
|
||||
zlog_err("Can't raise privileges");
|
||||
/* Make socket for the peer. */
|
||||
peer->fd = vrf_sockunion_socket(&peer->su, peer->bgp->vrf_id);
|
||||
peer->fd = vrf_sockunion_socket(&peer->su, peer->bgp->vrf_id, NULL);
|
||||
if (bgpd_privs.change(ZPRIVS_LOWER))
|
||||
zlog_err("Can't lower privileges");
|
||||
if (peer->fd < 0)
|
||||
@ -751,7 +751,7 @@ int bgp_socket(struct bgp *bgp, unsigned short port, const char *address)
|
||||
if (bgpd_privs.change(ZPRIVS_RAISE))
|
||||
zlog_err("Can't raise privileges");
|
||||
sock = vrf_socket(ainfo->ai_family, ainfo->ai_socktype,
|
||||
ainfo->ai_protocol, bgp->vrf_id);
|
||||
ainfo->ai_protocol, bgp->vrf_id, NULL);
|
||||
if (bgpd_privs.change(ZPRIVS_LOWER))
|
||||
zlog_err("Can't lower privileges");
|
||||
if (sock < 0) {
|
||||
|
||||
38
lib/vrf.c
38
lib/vrf.c
@ -493,7 +493,8 @@ void vrf_terminate(void)
|
||||
}
|
||||
|
||||
/* Create a socket for the VRF. */
|
||||
int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id)
|
||||
int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id,
|
||||
char *interfacename)
|
||||
{
|
||||
int ret, save_errno, ret2;
|
||||
|
||||
@ -508,6 +509,13 @@ int vrf_socket(int domain, int type, int protocol, vrf_id_t vrf_id)
|
||||
zlog_err("%s: Can't switchback from VRF %u (%s)",
|
||||
__func__, vrf_id, safe_strerror(errno));
|
||||
errno = save_errno;
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
ret2 = vrf_bind(vrf_id, ret, interfacename);
|
||||
if (ret2 < 0) {
|
||||
close(ret);
|
||||
ret = ret2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -795,6 +803,23 @@ vrf_id_t vrf_get_default_id(void)
|
||||
return VRF_DEFAULT_INTERNAL;
|
||||
}
|
||||
|
||||
int vrf_bind(vrf_id_t vrf_id, int fd, char *name)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (fd < 0 || name == NULL)
|
||||
return fd;
|
||||
if (vrf_is_mapped_on_netns(vrf_id))
|
||||
return fd;
|
||||
#ifdef SO_BINDTODEVICE
|
||||
ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, name,
|
||||
strlen(name));
|
||||
if (ret < 0)
|
||||
zlog_debug("bind to interface %s failed, errno=%d",
|
||||
name, errno);
|
||||
#endif /* SO_BINDTODEVICE */
|
||||
return ret;
|
||||
}
|
||||
int vrf_getaddrinfo(const char *node, const char *service,
|
||||
const struct addrinfo *hints,
|
||||
struct addrinfo **res, vrf_id_t vrf_id)
|
||||
@ -835,7 +860,8 @@ int vrf_ioctl(vrf_id_t vrf_id, int d, unsigned long request, char *params)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id)
|
||||
int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id,
|
||||
char *interfacename)
|
||||
{
|
||||
int ret, save_errno, ret2;
|
||||
|
||||
@ -850,5 +876,13 @@ int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id)
|
||||
zlog_err("%s: Can't switchback from VRF %u (%s)",
|
||||
__func__, vrf_id, safe_strerror(errno));
|
||||
errno = save_errno;
|
||||
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
ret2 = vrf_bind(vrf_id, ret, interfacename);
|
||||
if (ret2 < 0) {
|
||||
close(ret);
|
||||
ret = ret2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -207,9 +207,13 @@ extern void vrf_terminate(void);
|
||||
|
||||
/* Create a socket serving for the given VRF */
|
||||
extern int vrf_socket(int domain, int type,
|
||||
int protocol, vrf_id_t vrf_id);
|
||||
int protocol, vrf_id_t vrf_id,
|
||||
char *name);
|
||||
|
||||
extern int vrf_sockunion_socket(const union sockunion *su,
|
||||
vrf_id_t vrf_id);
|
||||
vrf_id_t vrf_id, char *name);
|
||||
|
||||
extern int vrf_bind(vrf_id_t vrf_id, int fd, char *name);
|
||||
|
||||
/* VRF ioctl operations */
|
||||
extern int vrf_getaddrinfo(const char *node, const char *service,
|
||||
|
||||
@ -367,7 +367,8 @@ static int get_iflink_speed(struct interface *interface)
|
||||
/* use ioctl to get IP address of an interface */
|
||||
if (zserv_privs.change(ZPRIVS_RAISE))
|
||||
zlog_err("Can't raise privileges");
|
||||
sd = vrf_socket(PF_INET, SOCK_DGRAM, IPPROTO_IP, interface->vrf_id);
|
||||
sd = vrf_socket(PF_INET, SOCK_DGRAM, IPPROTO_IP,
|
||||
interface->vrf_id, NULL);
|
||||
if (sd < 0) {
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug("Failure to read interface %s speed: %d %s",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user