From 4cef6de5915d22508c3e79335fbbe226f47ad0f5 Mon Sep 17 00:00:00 2001 From: Nathan Skrzypczak Date: Mon, 19 Jul 2021 18:21:43 +0200 Subject: 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 --- src/vppinfra/socket.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-) (limited to 'src/vppinfra/socket.c') 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 #include #include +#include #include #include @@ -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) @@ -538,6 +553,38 @@ done: return error; } +__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) { -- cgit 1.2.3-korg