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 <robert.lubos@nordicsemi.no>
This commit is contained in:
Robert Lubos 2021-09-20 10:22:50 +02:00 committed by Christopher Friedt
commit 0dbdcc770d
12 changed files with 58 additions and 25 deletions

View file

@ -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);

View file

@ -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

View file

@ -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,

View file

@ -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)

View file

@ -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, \

View file

@ -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

View file

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

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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)
{