From 0dbdcc770dc60f55a56449514d9de0aed01f8eb5 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 20 Sep 2021 10:22:50 +0200 Subject: [PATCH] net: sockets: Add socket processing priority When creating a socket, all of the registered socket implementation are processed in a sequence, allowing to find appropriate socket implementation for specified family/type/protocol. So far however, the order of processing was not clearly defined, leaving ambiguity if multiple implmentations supported the same set of parameters. Fix this, by registering socket priority along with implementation. This makes the processing order of particular socket implementations explicit, giving more flexibility to the user, for example when it's neeed to prioritze one implementation over another if they support the same set of parameters. Signed-off-by: Robert Lubos --- drivers/modem/quectel-bg9x.c | 3 ++- drivers/modem/ublox-sara-r4.c | 4 ++-- drivers/wifi/eswifi/eswifi_socket_offload.c | 4 ++-- drivers/wifi/simplelink/simplelink_sockets.c | 4 ++-- include/net/socket.h | 10 ++++++---- subsys/net/lib/sockets/Kconfig | 17 +++++++++++++++++ subsys/net/lib/sockets/sockets.c | 4 ++-- subsys/net/lib/sockets/sockets_can.c | 3 ++- subsys/net/lib/sockets/sockets_net_mgmt.c | 4 ++-- subsys/net/lib/sockets/sockets_packet.c | 3 ++- subsys/net/lib/sockets/sockets_tls.c | 11 ++++++++++- tests/net/socket/register/src/main.c | 16 +++++++++------- 12 files changed, 58 insertions(+), 25 deletions(-) diff --git a/drivers/modem/quectel-bg9x.c b/drivers/modem/quectel-bg9x.c index e2b32ce6343..5ae52e18c40 100644 --- a/drivers/modem/quectel-bg9x.c +++ b/drivers/modem/quectel-bg9x.c @@ -1203,4 +1203,5 @@ NET_DEVICE_DT_INST_OFFLOAD_DEFINE(0, modem_init, NULL, &api_funcs, MDM_MAX_DATA_LENGTH); /* Register NET sockets. */ -NET_SOCKET_REGISTER(quectel_bg9x, AF_UNSPEC, offload_is_supported, offload_socket); +NET_SOCKET_REGISTER(quectel_bg9x, NET_SOCKET_DEFAULT_PRIO, AF_UNSPEC, + offload_is_supported, offload_socket); diff --git a/drivers/modem/ublox-sara-r4.c b/drivers/modem/ublox-sara-r4.c index 35b376a033f..60eb398ba6a 100644 --- a/drivers/modem/ublox-sara-r4.c +++ b/drivers/modem/ublox-sara-r4.c @@ -1956,8 +1956,8 @@ static bool offload_is_supported(int family, int type, int proto) return true; } -NET_SOCKET_REGISTER(ublox_sara_r4, AF_UNSPEC, offload_is_supported, - offload_socket); +NET_SOCKET_REGISTER(ublox_sara_r4, NET_SOCKET_DEFAULT_PRIO, AF_UNSPEC, + offload_is_supported, offload_socket); #if defined(CONFIG_DNS_RESOLVER) /* TODO: This is a bare-bones implementation of DNS handling diff --git a/drivers/wifi/eswifi/eswifi_socket_offload.c b/drivers/wifi/eswifi/eswifi_socket_offload.c index beee4d80ae1..ffa01b33c10 100644 --- a/drivers/wifi/eswifi/eswifi_socket_offload.c +++ b/drivers/wifi/eswifi/eswifi_socket_offload.c @@ -571,8 +571,8 @@ static const struct socket_op_vtable eswifi_socket_fd_op_vtable = { }; #ifdef CONFIG_NET_SOCKETS_OFFLOAD -NET_SOCKET_REGISTER(eswifi, AF_UNSPEC, eswifi_socket_is_supported, - eswifi_socket_create); +NET_SOCKET_REGISTER(eswifi, NET_SOCKET_DEFAULT_PRIO, AF_UNSPEC, + eswifi_socket_is_supported, eswifi_socket_create); #endif static int eswifi_off_getaddrinfo(const char *node, const char *service, diff --git a/drivers/wifi/simplelink/simplelink_sockets.c b/drivers/wifi/simplelink/simplelink_sockets.c index f315f59df00..4f11fc5845e 100644 --- a/drivers/wifi/simplelink/simplelink_sockets.c +++ b/drivers/wifi/simplelink/simplelink_sockets.c @@ -1264,8 +1264,8 @@ static int simplelink_socket_accept(void *obj, struct sockaddr *addr, } #ifdef CONFIG_NET_SOCKETS_OFFLOAD -NET_SOCKET_REGISTER(simplelink, AF_UNSPEC, simplelink_is_supported, - simplelink_socket_create); +NET_SOCKET_REGISTER(simplelink, NET_SOCKET_DEFAULT_PRIO, AF_UNSPEC, + simplelink_is_supported, simplelink_socket_create); #endif void simplelink_sockets_init(void) diff --git a/include/net/socket.h b/include/net/socket.h index 2ef26ab730c..8ef4eeea7e7 100644 --- a/include/net/socket.h +++ b/include/net/socket.h @@ -880,12 +880,14 @@ struct net_socket_register { int (*handler)(int family, int type, int proto); }; -#define NET_SOCKET_GET_NAME(socket_name) \ - (__net_socket_register_##socket_name) +#define NET_SOCKET_DEFAULT_PRIO CONFIG_NET_SOCKETS_PRIORITY_DEFAULT -#define NET_SOCKET_REGISTER(socket_name, _family, _is_supported, _handler) \ +#define NET_SOCKET_GET_NAME(socket_name, prio) \ + (__net_socket_register_##prio##_##socket_name) + +#define NET_SOCKET_REGISTER(socket_name, prio, _family, _is_supported, _handler) \ static const STRUCT_SECTION_ITERABLE(net_socket_register, \ - NET_SOCKET_GET_NAME(socket_name)) = { \ + NET_SOCKET_GET_NAME(socket_name, prio)) = { \ .family = _family, \ .is_supported = _is_supported, \ .handler = _handler, \ diff --git a/subsys/net/lib/sockets/Kconfig b/subsys/net/lib/sockets/Kconfig index 943d49fd66d..c4508b416f5 100644 --- a/subsys/net/lib/sockets/Kconfig +++ b/subsys/net/lib/sockets/Kconfig @@ -10,6 +10,16 @@ menuconfig NET_SOCKETS if NET_SOCKETS +config NET_SOCKETS_PRIORITY_DEFAULT + int "Default processing priority for sockets" + default 50 + help + Default processing priority for socket implementations. This defines + the order of processing of particular socket implementations when + creating a new socket, lower value indicate earlier processing. This + allows to for instance prioritize offloaded socket processing during + socket creation over the native one, or vice versa. + config NET_SOCKETS_POSIX_NAMES bool "POSIX names for Sockets API (without full POSIX API)" default y if !POSIX_API @@ -62,6 +72,13 @@ config NET_SOCKETS_SOCKOPT_TLS Enable TLS socket option support which automatically establishes a TLS connection to the remote host. +config NET_SOCKETS_TLS_PRIORITY + int "Default processing priority for TLS sockets" + default 45 + help + Processing priority for TLS sockets. Should be lower than + NET_SOCKETS_PRIORITY_DEFAULT in order to be processed correctly. + config NET_SOCKETS_TLS_SET_MAX_FRAGMENT_LENGTH bool "Set Maximum Fragment Length (MFL)" default y diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index 8632c6b6d82..b6cab6ef537 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -2217,6 +2217,6 @@ static bool inet_is_supported(int family, int type, int proto) return true; } -NET_SOCKET_REGISTER(af_inet46, AF_UNSPEC, inet_is_supported, - zsock_socket_internal); +NET_SOCKET_REGISTER(af_inet46, NET_SOCKET_DEFAULT_PRIO, AF_UNSPEC, + inet_is_supported, zsock_socket_internal); #endif /* CONFIG_NET_NATIVE */ diff --git a/subsys/net/lib/sockets/sockets_can.c b/subsys/net/lib/sockets/sockets_can.c index 4ff17c39a1f..418509a270e 100644 --- a/subsys/net/lib/sockets/sockets_can.c +++ b/subsys/net/lib/sockets/sockets_can.c @@ -703,4 +703,5 @@ static bool can_is_supported(int family, int type, int proto) return true; } -NET_SOCKET_REGISTER(af_can, AF_CAN, can_is_supported, zcan_socket); +NET_SOCKET_REGISTER(af_can, NET_SOCKET_DEFAULT_PRIO, AF_CAN, can_is_supported, + zcan_socket); diff --git a/subsys/net/lib/sockets/sockets_net_mgmt.c b/subsys/net/lib/sockets/sockets_net_mgmt.c index 7f0fa646876..989d3806885 100644 --- a/subsys/net/lib/sockets/sockets_net_mgmt.c +++ b/subsys/net/lib/sockets/sockets_net_mgmt.c @@ -390,5 +390,5 @@ static bool net_mgmt_is_supported(int family, int type, int proto) return true; } -NET_SOCKET_REGISTER(af_net_mgmt, AF_NET_MGMT, net_mgmt_is_supported, - znet_mgmt_socket); +NET_SOCKET_REGISTER(af_net_mgmt, NET_SOCKET_DEFAULT_PRIO, AF_NET_MGMT, + net_mgmt_is_supported, znet_mgmt_socket); diff --git a/subsys/net/lib/sockets/sockets_packet.c b/subsys/net/lib/sockets/sockets_packet.c index 3e2099085a4..3e99f7622c9 100644 --- a/subsys/net/lib/sockets/sockets_packet.c +++ b/subsys/net/lib/sockets/sockets_packet.c @@ -394,4 +394,5 @@ static bool packet_is_supported(int family, int type, int proto) return false; } -NET_SOCKET_REGISTER(af_packet, AF_PACKET, packet_is_supported, zpacket_socket); +NET_SOCKET_REGISTER(af_packet, NET_SOCKET_DEFAULT_PRIO, AF_PACKET, + packet_is_supported, zpacket_socket); diff --git a/subsys/net/lib/sockets/sockets_tls.c b/subsys/net/lib/sockets/sockets_tls.c index 515afacc68c..6c8214f3847 100644 --- a/subsys/net/lib/sockets/sockets_tls.c +++ b/subsys/net/lib/sockets/sockets_tls.c @@ -2658,4 +2658,13 @@ static bool tls_is_supported(int family, int type, int proto) return false; } -NET_SOCKET_REGISTER(tls, AF_UNSPEC, tls_is_supported, ztls_socket); +/* Since both, TLS sockets and regular ones fall under the same address family, + * it's required to process TLS first in order to capture socket calls which + * create sockets for secure protocols. Every other call for AF_INET/AF_INET6 + * will be forwarded to regular socket implementation. + */ +BUILD_ASSERT(CONFIG_NET_SOCKETS_TLS_PRIORITY < CONFIG_NET_SOCKETS_PRIORITY_DEFAULT, + "CONFIG_NET_SOCKETS_TLS_PRIORITY have to be smaller than CONFIG_NET_SOCKETS_PRIORITY_DEFAULT"); + +NET_SOCKET_REGISTER(tls, CONFIG_NET_SOCKETS_TLS_PRIORITY, AF_UNSPEC, + tls_is_supported, ztls_socket); diff --git a/tests/net/socket/register/src/main.c b/tests/net/socket/register/src/main.c index 6e2295c09f0..f515815da98 100644 --- a/tests/net/socket/register/src/main.c +++ b/tests/net/socket/register/src/main.c @@ -133,7 +133,7 @@ static const struct test_result { .test_case.type = SOCK_RAW, .test_case.proto = IPPROTO_RAW, .result = -1, - .error = EPFNOSUPPORT, + .error = EAFNOSUPPORT, }, { /* 15 */ @@ -212,14 +212,16 @@ static bool is_ip(int family, int type, int proto) return true; } -NET_SOCKET_REGISTER(af_inet, AF_INET, is_ip, socket_test); -NET_SOCKET_REGISTER(af_inet6, AF_INET6, is_ip, socket_test); -NET_SOCKET_REGISTER(af_can2, AF_CAN, is_ip, socket_test); +#define TEST_SOCKET_PRIO 40 + +NET_SOCKET_REGISTER(af_inet, TEST_SOCKET_PRIO, AF_INET, is_ip, socket_test); +NET_SOCKET_REGISTER(af_inet6, TEST_SOCKET_PRIO, AF_INET6, is_ip, socket_test); +NET_SOCKET_REGISTER(af_can2, TEST_SOCKET_PRIO, AF_CAN, is_ip, socket_test); /* For these socket families, we return ok always for now */ -NET_SOCKET_REGISTER(tls, AF_UNSPEC, is_tls, socket_test_ok); -NET_SOCKET_REGISTER(af_packet, AF_PACKET, is_packet, socket_test_ok); -NET_SOCKET_REGISTER(af_can, AF_CAN, is_can, socket_test_ok); +NET_SOCKET_REGISTER(tls, TEST_SOCKET_PRIO, AF_UNSPEC, is_tls, socket_test_ok); +NET_SOCKET_REGISTER(af_packet, TEST_SOCKET_PRIO, AF_PACKET, is_packet, socket_test_ok); +NET_SOCKET_REGISTER(af_can, TEST_SOCKET_PRIO, AF_CAN, is_can, socket_test_ok); void test_create_sockets(void) {