lib: add vrf_ioctl API

That API can be used to wrap the ioctl call with various vrf instances.
This permits transparently doing the ioctl() call without taking into
consideration the vrf backend kind.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
Philippe Guibert 2018-02-05 17:00:45 +01:00
parent 9dab51ac71
commit 516d7591d6
3 changed files with 23 additions and 12 deletions

View File

@ -815,6 +815,26 @@ int vrf_getaddrinfo(const char *node, const char *service,
return ret;
}
int vrf_ioctl(vrf_id_t vrf_id, int d, unsigned long request, char *params)
{
int ret, saved_errno, rc;
ret = vrf_switch_to_netns(vrf_id);
if (ret < 0) {
zlog_err("%s: Can't switch to VRF %u (%s)",
__func__, vrf_id, safe_strerror(errno));
return 0;
}
rc = ioctl(d, request, params);
saved_errno = errno;
ret = vrf_switchback_to_initial();
if (ret < 0)
zlog_err("%s: Can't switchback from VRF %u (%s)",
__func__, vrf_id, safe_strerror(errno));
errno = saved_errno;
return rc;
}
int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id)
{
int ret, save_errno, ret2;

View File

@ -216,6 +216,8 @@ extern int vrf_getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints,
struct addrinfo **res, vrf_id_t vrf_id);
extern int vrf_ioctl(vrf_id_t vrf_id, int d, unsigned long request, char *args);
/* function called by macro VRF_DEFAULT
* to get the default VRF_ID
*/

View File

@ -351,7 +351,6 @@ static int get_iflink_speed(struct interface *interface)
struct ethtool_cmd ecmd;
int sd;
int rc;
int ret, saved_errno;
const char *ifname = interface->name;
/* initialize struct */
@ -376,17 +375,7 @@ static int get_iflink_speed(struct interface *interface)
return 0;
}
/* Get the current link state for the interface */
ret = vrf_switch_to_netns(interface->vrf_id);
if (ret < 0)
zlog_err("%s: Can't switch to VRF %u (%s)",
__func__, interface->vrf_id, safe_strerror(errno));
rc = ioctl(sd, SIOCETHTOOL, (char *)&ifdata);
saved_errno = errno;
ret = vrf_switchback_to_initial();
if (ret < 0)
zlog_err("%s: Can't switchback from VRF %u (%s)",
__func__, interface->vrf_id, safe_strerror(errno));
errno = saved_errno;
rc = vrf_ioctl(interface->vrf_id, sd, SIOCETHTOOL, (char *)&ifdata);
if (zserv_privs.change(ZPRIVS_LOWER))
zlog_err("Can't lower privileges");
if (rc < 0) {