From: Philippe Guibert Date: Fri, 26 Jan 2018 11:28:27 +0000 (+0100) Subject: lib: add two APIs to handle socket operations with VRF NETNS X-Git-Tag: frr-5.0-dev~209^2~19 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=2e0d2b3d9c4f2681d00ec2607319f3bb8078e31d;p=mirror%2Ffrr.git lib: add two APIs to handle socket operations with VRF NETNS The vrf_sockunion_socket() wraps sockunion_socket() with vrf_id as additional parameter. The creation of socket forces the user to transparently move to new NETNS for doing the operation. The vrf_getaddr_info() wraps getaddr_info() with vrf_id as additional parameter. That API relies on the underlying system. Then there may be need to switch to an other netns in that case too. Also, the vrf_socket() implementation is simplified. Signed-off-by: Philippe Guibert --- diff --git a/lib/vrf.c b/lib/vrf.c index f4dc237eb3..ade1895bd4 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -490,10 +490,19 @@ 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 ret = -1; + int ret, save_errno, ret2; + 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)); ret = socket(domain, type, protocol); - + save_errno = errno; + ret2 = vrf_switchback_to_initial(); + if (ret2 < 0) + zlog_err("%s: Can't switchback from VRF %u (%s)", + __func__, vrf_id, safe_strerror(errno)); + errno = save_errno; return ret; } @@ -661,3 +670,41 @@ vrf_id_t vrf_get_default_id(void) else return VRF_DEFAULT_INTERNAL; } + +int vrf_getaddrinfo(const char *node, const char *service, + const struct addrinfo *hints, + struct addrinfo **res, vrf_id_t vrf_id) +{ + int ret, ret2, save_errno; + + 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)); + ret = getaddrinfo(node, service, hints, res); + save_errno = errno; + ret2 = vrf_switchback_to_initial(); + if (ret2 < 0) + zlog_err("%s: Can't switchback from VRF %u (%s)", + __func__, vrf_id, safe_strerror(errno)); + errno = save_errno; + return ret; +} + +int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id) +{ + int ret, save_errno, ret2; + + 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)); + ret = sockunion_socket(su); + save_errno = errno; + ret2 = vrf_switchback_to_initial(); + if (ret2 < 0) + zlog_err("%s: Can't switchback from VRF %u (%s)", + __func__, vrf_id, safe_strerror(errno)); + errno = save_errno; + return ret; +} diff --git a/lib/vrf.h b/lib/vrf.h index 9553d43808..08c53484ee 100644 --- a/lib/vrf.h +++ b/lib/vrf.h @@ -222,6 +222,15 @@ int vrf_is_mapped_on_netns(vrf_id_t vrf_id); extern int vrf_switch_to_netns(vrf_id_t vrf_id); extern int vrf_switchback_to_initial(void); +/* VRF ioctl operations */ +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_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id); +/* VRF switch from NETNS */ +extern int vrf_switch_to_netns(vrf_id_t vrf_id); +extern int vrf_switchback_to_initial(void); + /* used by NS when vrf backend is NS. * Notify a change in the VRF ID of the VRF */