summaryrefslogtreecommitdiffstats
path: root/src/vppinfra/socket.c
diff options
context:
space:
mode:
authorNathan Skrzypczak <nathan.skrzypczak@gmail.com>2021-07-19 18:21:43 +0200
committerFlorin Coras <florin.coras@gmail.com>2021-07-22 15:22:22 +0000
commit4cef6de5915d22508c3e79335fbbe226f47ad0f5 (patch)
tree2f002039bc89a43d37265deee740330d84bfaf56 /src/vppinfra/socket.c
parent2cf583e3d6b7f8290e4fefec3b70968048d8dae0 (diff)
vppinfra: add abstract socket & netns fns
* Add clib_socket_init support for abstract sockets if name starts with an '@' * Add clib_socket_init_netns to open socket in netns * Add clib_netns_open Type: feature Change-Id: I89637ad657c702ec38ddecb5c03a1673d0dfb104 Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
Diffstat (limited to 'src/vppinfra/socket.c')
-rw-r--r--src/vppinfra/socket.c53
1 files changed, 50 insertions, 3 deletions
diff --git a/src/vppinfra/socket.c b/src/vppinfra/socket.c
index d8427852400..26427d98fa1 100644
--- a/src/vppinfra/socket.c
+++ b/src/vppinfra/socket.c
@@ -52,6 +52,7 @@
#include <vppinfra/mem.h>
#include <vppinfra/vec.h>
#include <vppinfra/socket.h>
+#include <vppinfra/linux/netns.h>
#include <vppinfra/format.h>
#include <vppinfra/error.h>
@@ -113,6 +114,18 @@ socket_config (char *config,
*addr_len = sizeof (su[0]);
}
+ /* Treat everything that starts with @ as an abstract socket. */
+ else if (config[0] == '@')
+ {
+ struct sockaddr_un *su = addr;
+ su->sun_family = PF_LOCAL;
+ clib_memcpy (&su->sun_path, config,
+ clib_min (sizeof (su->sun_path), 1 + strlen (config)));
+
+ *addr_len = sizeof (su->sun_family) + strlen (config);
+ su->sun_path[0] = '\0';
+ }
+
/* Hostname or hostname:port or port. */
else
{
@@ -440,7 +453,8 @@ clib_socket_init (clib_socket_t * s)
need_bind = 0;
}
}
- if (addr.sa.sa_family == PF_LOCAL)
+ if (addr.sa.sa_family == PF_LOCAL &&
+ ((struct sockaddr_un *) &addr)->sun_path[0] != 0)
unlink (((struct sockaddr_un *) &addr)->sun_path);
/* Make address available for multiple users. */
@@ -477,8 +491,9 @@ clib_socket_init (clib_socket_t * s)
s->fd, s->config);
goto done;
}
- if (addr.sa.sa_family == PF_LOCAL
- && s->flags & CLIB_SOCKET_F_ALLOW_GROUP_WRITE)
+ if (addr.sa.sa_family == PF_LOCAL &&
+ s->flags & CLIB_SOCKET_F_ALLOW_GROUP_WRITE &&
+ ((struct sockaddr_un *) &addr)->sun_path[0] != 0)
{
struct stat st = { 0 };
if (stat (((struct sockaddr_un *) &addr)->sun_path, &st) < 0)
@@ -539,6 +554,38 @@ done:
}
__clib_export clib_error_t *
+clib_socket_init_netns (clib_socket_t *s, u8 *namespace)
+{
+ if (namespace == NULL || namespace[0] == 0)
+ return clib_socket_init (s);
+
+ clib_error_t *error;
+ int old_netns_fd, nfd;
+
+ old_netns_fd = clib_netns_open (NULL /* self */);
+ if ((nfd = clib_netns_open (namespace)) == -1)
+ {
+ error = clib_error_return_unix (0, "clib_netns_open '%s'", namespace);
+ goto done;
+ }
+
+ if (clib_setns (nfd) == -1)
+ {
+ error = clib_error_return_unix (0, "setns '%s'", namespace);
+ goto done;
+ }
+
+ error = clib_socket_init (s);
+
+done:
+ if (clib_setns (old_netns_fd) == -1)
+ clib_warning ("Cannot set old ns");
+ close (old_netns_fd);
+
+ return error;
+}
+
+__clib_export clib_error_t *
clib_socket_accept (clib_socket_t * server, clib_socket_t * client)
{
clib_error_t *err = 0;