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 */