From 516d7591d68cf4537bb7f0603ff703e808381d03 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Mon, 5 Feb 2018 17:00:45 +0100 Subject: [PATCH] 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 --- lib/vrf.c | 20 ++++++++++++++++++++ lib/vrf.h | 2 ++ zebra/if_netlink.c | 13 +------------ 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/lib/vrf.c b/lib/vrf.c index 0ca517d051..890a7adca2 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -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; diff --git a/lib/vrf.h b/lib/vrf.h index 326418791d..cb4159a0a3 100644 --- a/lib/vrf.h +++ b/lib/vrf.h @@ -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 */ diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index a02533c1fe..65f1e56587 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -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) { -- 2.39.5