drivers: nsos: support for AF_UNIX
Handle AF_UNIX family sockets for NSOS offloaded driver
Note that the size of struct sockaddr_un is done conditionnaly based on
CONFIG_NET_NATIVE_OFFLOADED_SOCKETS
Also, NET_SOCKADDR_PTR_MAX_SIZE needs to be updated only if
CONFIG_NET_SOCKETS_PACKET is not set. Otherwise, for a AF_PACKET socket,
a struct net_context variable can be corrupted, as local would have be on
16 bytes instead of 20 bytes.
Signed-off-by: Noemie Gillet <ngillet@sequans.com>
diff --git a/drivers/net/nsos.h b/drivers/net/nsos.h
index f1e2f12..37fd16a 100644
--- a/drivers/net/nsos.h
+++ b/drivers/net/nsos.h
@@ -14,11 +14,13 @@
#define NSOS_MID_PF_UNSPEC 0 /**< Unspecified protocol family. */
#define NSOS_MID_PF_INET 1 /**< IP protocol family version 4. */
#define NSOS_MID_PF_INET6 2 /**< IP protocol family version 6. */
+#define NSOS_MID_PF_UNIX 6 /**< Unix protocol. */
/* Address families. */
#define NSOS_MID_AF_UNSPEC NSOS_MID_PF_UNSPEC /**< Unspecified address family. */
#define NSOS_MID_AF_INET NSOS_MID_PF_INET /**< IP protocol family version 4. */
#define NSOS_MID_AF_INET6 NSOS_MID_PF_INET6 /**< IP protocol family version 6. */
+#define NSOS_MID_AF_UNIX NSOS_MID_PF_UNIX /**< Unix protocol. */
/** Protocol numbers from IANA/BSD */
enum nsos_mid_net_ip_protocol {
@@ -63,10 +65,18 @@
uint32_t sin6_scope_id; /* Set of interfaces for a scope */
};
+#define UNIX_PATH_MAX 108
+struct nsos_mid_sockaddr_un {
+ sa_family_t sun_family; /* AF_UNIX */
+ char sun_path[UNIX_PATH_MAX]; /* pathname */
+};
+
+
struct nsos_mid_sockaddr_storage {
union {
struct nsos_mid_sockaddr_in sockaddr_in;
struct nsos_mid_sockaddr_in6 sockaddr_in6;
+ struct nsos_mid_sockaddr_un sockaddr_un;
};
};
diff --git a/drivers/net/nsos_adapt.c b/drivers/net/nsos_adapt.c
index af98caa..d51bc01 100644
--- a/drivers/net/nsos_adapt.c
+++ b/drivers/net/nsos_adapt.c
@@ -23,6 +23,7 @@
#include <sys/epoll.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
+#include <sys/un.h>
#include <unistd.h>
#include "nsos.h"
@@ -68,6 +69,9 @@
case NSOS_MID_AF_INET6:
*family = AF_INET6;
break;
+ case NSOS_MID_AF_UNIX:
+ *family = AF_UNIX;
+ break;
default:
nsi_print_warning("%s: socket family %d not supported\n", __func__, family_mid);
return -NSOS_MID_EAFNOSUPPORT;
@@ -88,6 +92,9 @@
case AF_INET6:
*family_mid = NSOS_MID_AF_INET6;
break;
+ case AF_UNIX:
+ *family_mid = NSOS_MID_AF_UNIX;
+ break;
default:
nsi_print_warning("%s: socket family %d not supported\n", __func__, family);
return -NSOS_MID_EAFNOSUPPORT;
@@ -296,6 +303,19 @@
return 0;
}
+ case NSOS_MID_AF_UNIX: {
+ const struct nsos_mid_sockaddr_un *addr_un_mid =
+ (const struct nsos_mid_sockaddr_un *)addr_mid;
+ struct sockaddr_un *addr_un = (struct sockaddr_un *)*addr;
+
+ addr_un->sun_family = AF_UNIX;
+ memcpy(addr_un->sun_path, addr_un_mid->sun_path,
+ sizeof(addr_un->sun_path));
+
+ *addrlen = sizeof(*addr_un);
+
+ return 0;
+ }
}
return -NSOS_MID_EINVAL;
@@ -347,6 +367,23 @@
return 0;
}
+ case AF_UNIX: {
+ struct nsos_mid_sockaddr_un *addr_un_mid =
+ (struct nsos_mid_sockaddr_un *)addr_mid;
+ const struct sockaddr_un *addr_un = (const struct sockaddr_un *)addr;
+
+ if (addr_un_mid) {
+ addr_un_mid->sun_family = NSOS_MID_AF_UNIX;
+ memcpy(addr_un_mid->sun_path, addr_un->sun_path,
+ sizeof(addr_un_mid->sun_path));
+ }
+
+ if (addrlen_mid) {
+ *addrlen_mid = sizeof(*addr_un);
+ }
+
+ return 0;
+ }
}
nsi_print_warning("%s: socket family %d not supported\n", __func__, addr->sa_family);
diff --git a/drivers/net/nsos_sockets.c b/drivers/net/nsos_sockets.c
index bfd8cb2..ec9c895 100644
--- a/drivers/net/nsos_sockets.c
+++ b/drivers/net/nsos_sockets.c
@@ -72,6 +72,9 @@
case AF_INET6:
*family_mid = NSOS_MID_AF_INET6;
break;
+ case AF_UNIX:
+ *family_mid = NSOS_MID_AF_UNIX;
+ break;
default:
return -NSOS_MID_EAFNOSUPPORT;
}
@@ -448,6 +451,24 @@
return 0;
}
+ case AF_UNIX: {
+ const struct sockaddr_un *addr_un =
+ (const struct sockaddr_un *)addr;
+ struct nsos_mid_sockaddr_un *addr_un_mid =
+ (struct nsos_mid_sockaddr_un *)*addr_mid;
+
+ if (addrlen < sizeof(*addr_un)) {
+ return -NSOS_MID_EINVAL;
+ }
+
+ addr_un_mid->sun_family = NSOS_MID_AF_UNIX;
+ memcpy(addr_un_mid->sun_path, addr_un->sun_path,
+ sizeof(addr_un_mid->sun_path));
+
+ *addrlen_mid = sizeof(*addr_un_mid);
+
+ return 0;
+ }
}
return -NSOS_MID_EINVAL;
@@ -946,6 +967,9 @@
case NSOS_MID_AF_INET6:
*family = AF_INET6;
break;
+ case NSOS_MID_AF_UNIX:
+ *family = AF_UNIX;
+ break;
default:
return -NSOS_MID_EAFNOSUPPORT;
}
diff --git a/include/zephyr/net/net_ip.h b/include/zephyr/net/net_ip.h
index c60498b..ed3c741 100644
--- a/include/zephyr/net/net_ip.h
+++ b/include/zephyr/net/net_ip.h
@@ -231,6 +231,12 @@
uint8_t *sll_addr; /**< Physical-layer address, big endian */
};
+/** Socket address struct for unix socket where address is a pointer */
+struct sockaddr_un_ptr {
+ sa_family_t sun_family; /**< Always AF_UNIX */
+ char *sun_path; /**< pathname */
+};
+
struct sockaddr_can_ptr {
sa_family_t can_family;
int can_ifindex;
@@ -373,14 +379,27 @@
#endif
#endif
+#if defined(CONFIG_NET_NATIVE_OFFLOADED_SOCKETS)
+#define UNIX_PATH_MAX 108
+#undef NET_SOCKADDR_MAX_SIZE
+/* Define NET_SOCKADDR_MAX_SIZE to be struct of sa_family_t + char[UNIX_PATH_MAX] */
+#define NET_SOCKADDR_MAX_SIZE (UNIX_PATH_MAX+sizeof(sa_family_t))
+#if !defined(CONFIG_NET_SOCKETS_PACKET)
+#undef NET_SOCKADDR_PTR_MAX_SIZE
+#define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct sockaddr_un_ptr))
+#endif
+#endif
+
#if !defined(CONFIG_NET_IPV4)
#if !defined(CONFIG_NET_IPV6)
#if !defined(CONFIG_NET_SOCKETS_PACKET)
+#if !defined(CONFIG_NET_NATIVE_OFFLOADED_SOCKETS)
#define NET_SOCKADDR_MAX_SIZE (sizeof(struct sockaddr_in6))
#define NET_SOCKADDR_PTR_MAX_SIZE (sizeof(struct sockaddr_in6_ptr))
#endif
#endif
#endif
+#endif
/** @endcond */