]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: add two APIs to handle socket operations with VRF NETNS
authorPhilippe Guibert <philippe.guibert@6wind.com>
Fri, 26 Jan 2018 11:28:27 +0000 (12:28 +0100)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Tue, 27 Feb 2018 10:11:24 +0000 (11:11 +0100)
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 <philippe.guibert@6wind.com>
lib/vrf.c
lib/vrf.h

index f4dc237eb3d289e67c44b6b3c7cadf1cb726465d..ade1895bd4809513085039d63b323c20ecf749d6 100644 (file)
--- 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;
+}
index 9553d43808ef3779f36dddefe9ee97947c389c8a..08c53484eeef2f30d8083b6fbb80b1c5665d9b06 100644 (file)
--- 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
  */