diff options
| author | Philippe Guibert <philippe.guibert@6wind.com> | 2018-02-05 17:28:51 +0100 |
|---|---|---|
| committer | Philippe Guibert <philippe.guibert@6wind.com> | 2018-02-27 11:11:24 +0100 |
| commit | 0f4977c6689441e7b3075fc7a82c1ddc9ffdfa1c (patch) | |
| tree | a4679fd142c21212e652e3253c23bec821fff7b4 /lib/vrf.c | |
| parent | 516d7591d68cf4537bb7f0603ff703e808381d03 (diff) | |
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>
Diffstat (limited to 'lib/vrf.c')
| -rw-r--r-- | lib/vrf.c | 38 |
1 files changed, 36 insertions, 2 deletions
@@ -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; } |
