From 89bf1578d9624a146e9c41fb3f2bb75ac2ed4a66 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 7 Feb 2019 14:44:15 +0200 Subject: [PATCH] net: sockets: Add a way to register a socket family handler Allow automatic handling of registered socket families. Signed-off-by: Jukka Rissanen --- include/linker/common-rom.ld | 10 ++++++++++ include/net/socket.h | 24 ++++++++++++++++++++++++ scripts/sanitycheck | 3 ++- subsys/net/lib/sockets/sockets.c | 22 ++++++++++++++++++++++ 4 files changed, 58 insertions(+), 1 deletion(-) diff --git a/include/linker/common-rom.ld b/include/linker/common-rom.ld index 91934c4cf7e..bef2b4fe260 100644 --- a/include/linker/common-rom.ld +++ b/include/linker/common-rom.ld @@ -67,6 +67,16 @@ __net_l2_end = .; } GROUP_LINK_IN(ROMABLE_REGION) +#if defined(CONFIG_NET_SOCKETS) + SECTION_PROLOGUE(net_socket_register,,) + { + __net_socket_register_start = .; + *(".net_socket_register.init") + KEEP(*(SORT_BY_NAME(".net_socket_register.init*"))) + __net_socket_register_end = .; + } GROUP_LINK_IN(ROMABLE_REGION) +#endif + SECTION_DATA_PROLOGUE(_bt_services_area,,SUBALIGN(4)) { _bt_services_start = .; diff --git a/include/net/socket.h b/include/net/socket.h index 34ba0245bf7..bfa2cda8665 100644 --- a/include/net/socket.h +++ b/include/net/socket.h @@ -719,6 +719,30 @@ static inline char *inet_ntop(sa_family_t family, const void *src, char *dst, /** sockopt: Don't support IPv4 access (ignored, for compatibility) */ #define IPV6_V6ONLY 26 +/** @cond INTERNAL_HIDDEN */ +/** + * @brief Registration information for a given BSD socket family. + */ +struct net_socket_register { + int family; + bool (*is_supported)(int family, int type, int proto); + int (*handler)(int family, int type, int proto); +}; + +#define NET_SOCKET_GET_NAME(socket_name) \ + (__net_socket_register_##socket_name) + +#define NET_SOCKET_REGISTER(socket_name, _family, _is_supported, _handler) \ + static const struct net_socket_register \ + (NET_SOCKET_GET_NAME(socket_name)) __used \ + __attribute__((__section__(".net_socket_register.init"))) = { \ + .family = _family, \ + .is_supported = _is_supported, \ + .handler = _handler, \ + } + +/** @endcond */ + #ifdef __cplusplus } #endif diff --git a/scripts/sanitycheck b/scripts/sanitycheck index 94f6ec8c77c..a1f9c8c025f 100755 --- a/scripts/sanitycheck +++ b/scripts/sanitycheck @@ -896,7 +896,8 @@ class SizeCalculator: # These get copied into RAM only on non-XIP ro_sections = ["text", "ctors", "init_array", "reset", "object_access", "rodata", "devconfig", "net_l2", "vector", "sw_isr_table", - "_bt_settings_area", "_bt_services_area", "vectors"] + "_bt_settings_area", "_bt_services_area", "vectors", + "net_socket_register"] def __init__(self, filename, extra_sections): """Constructor diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index d491f90fc27..63ab9be4d12 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -20,6 +20,9 @@ LOG_MODULE_REGISTER(net_sock, CONFIG_NET_SOCKETS_LOG_LEVEL); #include "sockets_internal.h" +extern struct net_socket_register __net_socket_register_start[]; +extern struct net_socket_register __net_socket_register_end[]; + #define SET_ERRNO(x) \ { int _err = x; if (_err < 0) { errno = -_err; return -1; } } @@ -129,6 +132,25 @@ int zsock_socket_internal(int family, int type, int proto) int z_impl_zsock_socket(int family, int type, int proto) { + struct net_socket_register *sock_family; + + for (sock_family = __net_socket_register_start; + sock_family != __net_socket_register_end; + sock_family++) { + if (sock_family->family != family && + sock_family->family != AF_UNSPEC) { + continue; + } + + NET_ASSERT(sock_family->is_supported); + + if (!sock_family->is_supported(family, type, proto)) { + continue; + } + + return sock_family->handler(family, type, proto); + } + #if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) if (((proto >= IPPROTO_TLS_1_0) && (proto <= IPPROTO_TLS_1_2)) || (proto >= IPPROTO_DTLS_1_0 && proto <= IPPROTO_DTLS_1_2)) {