net: socket: Add option to create native TLS sock with offloaded TCP

In some cases (for examples when offloaded socket implementation does
not implement TLS functionality) it could be desired to create a native
TLS socket with an underlying offloaded socket.

This cannot be achieved with SO_BINDTODEVICE option only, as TLS socket
type is not really associated with a particular interface - it either
has to be offloaded, or a fully native socket is created (native TLS on
a native interface).

In order to address the problem, introduce TLS_NATIVE socket option.
This option instructs the socket dispatcher layer to create a native TLS
socket. As with the socket dispatcher the underlying socket
implementation is not decided during TLS socket creation, therefore it's
possible to use SO_BINDTODEVICE to choose either native or offloaded
interface for the underlying socket.

Additionally remove NET_SOCKETS_OFFLOAD_TLS Kconfig option, as it's no
longer needed with an runtime option to select whether to offload TLS or
not.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit is contained in:
Robert Lubos 2022-04-04 13:53:15 +02:00 committed by Carles Cufí
parent 641b2a0d93
commit e2fe8e7307
6 changed files with 49 additions and 15 deletions

View File

@ -145,6 +145,18 @@ struct zsock_pollfd {
*/
#define TLS_CERT_NOCOPY 10
/** TLS socket option to use with offloading. The option instructs the network
* stack only to offload underlying TCP/UDP communication. The TLS/DTLS
* operation is handled by a native TLS/DTLS socket implementation from Zephyr.
*
* Note, that this option is only applicable if socket dispatcher is used
* (CONFIG_NET_SOCKETS_OFFLOAD_DISPATCHER is enabled).
* In such case, it should be the first socket option set on a newly created
* socket. After that, the application may use SO_BINDTODEVICE to choose the
* dedicated network interface for the underlying TCP/UDP socket.
*/
#define TLS_NATIVE 11
/** @} */
/* Valid values for TLS_PEER_VERIFY option */

View File

@ -17,13 +17,10 @@ endif()
zephyr_sources_ifdef(CONFIG_NET_SOCKETS_CAN sockets_can.c)
zephyr_sources_ifdef(CONFIG_NET_SOCKETS_PACKET sockets_packet.c)
zephyr_sources_ifdef(CONFIG_NET_SOCKETS_SOCKOPT_TLS sockets_tls.c)
zephyr_sources_ifdef(CONFIG_NET_SOCKETS_OFFLOAD socket_offload.c)
zephyr_sources_ifdef(CONFIG_NET_SOCKETS_OFFLOAD_DISPATCHER socket_dispatcher.c)
if (CONFIG_NET_SOCKETS_SOCKOPT_TLS AND NOT CONFIG_NET_SOCKETS_OFFLOAD_TLS)
zephyr_sources(sockets_tls.c)
endif()
if(CONFIG_NET_SOCKETS_NET_MGMT)
zephyr_sources(sockets_net_mgmt.c)
zephyr_include_directories(${ZEPHYR_BASE}/subsys/net/ip)

View File

@ -199,15 +199,6 @@ config NET_SOCKETS_OFFLOAD_DISPATCHER_CONTEXT_MAX
After a proper socket has been created for a given file descriptor,
the dispatcher context is released and can be reused.
config NET_SOCKETS_OFFLOAD_TLS
bool "Offload TLS socket calls to the offloaded sockets"
depends on NET_SOCKETS_OFFLOAD
default y
help
If enabled, the offloading engine is expected to handle TLS/DTLS
socket calls. Otherwise, Zephyrs native TLS socket implementation
will be used, and only TCP/UDP socket calls will be offloaded.
config NET_SOCKETS_PACKET
bool "Packet socket support"
help

View File

@ -26,6 +26,16 @@ static K_MUTEX_DEFINE(dispatcher_lock);
static int sock_dispatch_create(int family, int type, int proto);
static bool is_tls(int proto)
{
if ((proto >= IPPROTO_TLS_1_0 && proto <= IPPROTO_TLS_1_2) ||
(proto >= IPPROTO_DTLS_1_0 && proto <= IPPROTO_DTLS_1_2)) {
return true;
}
return false;
}
static void dispatcher_ctx_free(struct dispatcher_context *ctx)
{
(void)k_mutex_lock(&dispatcher_lock, K_FOREVER);
@ -334,6 +344,26 @@ static int sock_dispatch_setsockopt_vmeth(void *obj, int level, int optname,
/* Native interface - use native socket implementation. */
fd = sock_dispatch_native(obj);
}
} else if ((level == SOL_TLS) && (optname == TLS_NATIVE)) {
const int *tls_native = optval;
struct dispatcher_context *ctx = obj;
if ((tls_native == NULL) || (optlen != sizeof(int))) {
errno = EINVAL;
return -1;
}
if (!is_tls(ctx->proto)) {
errno = ENOPROTOOPT;
return -1;
}
if (*tls_native) {
fd = sock_dispatch_native(obj);
} else {
/* No action needed */
return 0;
}
} else {
fd = sock_dispatch_default(obj);
}

View File

@ -33,8 +33,7 @@ static inline uintptr_t sock_get_flag(struct net_context *ctx, uintptr_t mask)
void net_socket_update_tc_rx_time(struct net_pkt *pkt, uint32_t end_tick);
#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) && \
!defined(CONFIG_NET_SOCKETS_OFFLOAD_TLS)
#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
bool net_socket_is_tls(void *obj);
#else
static inline bool net_socket_is_tls(void *obj)

View File

@ -2574,6 +2574,11 @@ int ztls_setsockopt_ctx(struct tls_context *ctx, int level, int optname,
break;
#endif /* CONFIG_NET_SOCKETS_ENABLE_DTLS */
case TLS_NATIVE:
/* Option handled at the socket dispatcher level. */
err = 0;
break;
default:
/* Unknown or read-only option. */
err = -ENOPROTOOPT;