X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvppinfra%2Fsocket.c;h=26427d98fa1aa6d8d9784f7f6aa518799ef478c6;hb=4cef6de59;hp=1d8b2ca2e4501b64fc376953fb4ce020bfbce046;hpb=5fe9457fa2ac49ca7134b09c6886192c7001335c;p=vpp.git diff --git a/src/vppinfra/socket.c b/src/vppinfra/socket.c index 1d8b2ca2e45..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) @@ -518,8 +533,10 @@ clib_socket_init (clib_socket_t * s) s->fd, s->config); goto done; } - /* Connect was blocking so set fd to non-blocking now */ + /* Connect was blocking so set fd to non-blocking now unless + * blocking mode explicitly requested. */ if (!(s->flags & CLIB_SOCKET_F_NON_BLOCKING_CONNECT) && + !(s->flags & CLIB_SOCKET_F_BLOCKING) && fcntl (s->fd, F_SETFL, O_NONBLOCK) < 0) { error = clib_error_return_unix (0, "fcntl NONBLOCK2 (fd %d, '%s')", @@ -536,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) {