Skip to content

Commit

Permalink
net: sockets: Add a socket offload module
Browse files Browse the repository at this point in the history
This patch enables BSD socket offload to a dedicated
TCP/IP offload engine.

This provides a simpler, more direct mechanism than going
through NET_OFFLOAD (zsock -> net_context -> socket conversions)
for those devices which provide complete TCP/IP offload at the
BSD socket level, and whose use cases do not require
IP routing between multiple network interfaces.

To use, configure CONFIG_NET_SOCKETS_OFFLOAD=y, and register
socket_offload_ops with this module.

Fixes #3706

Signed-off-by: Gil Pitney <gil.pitney@linaro.org>
  • Loading branch information
Gil Pitney authored and jukkar committed Sep 11, 2018
1 parent 213a88f commit c21b0fb
Show file tree
Hide file tree
Showing 6 changed files with 249 additions and 8 deletions.
19 changes: 12 additions & 7 deletions include/net/socket.h
Expand Up @@ -186,6 +186,8 @@ int ztls_setsockopt(int sock, int level, int optname,
#endif /* defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) */

#if defined(CONFIG_NET_SOCKETS_POSIX_NAMES)
#define pollfd zsock_pollfd
#if !defined(CONFIG_NET_SOCKETS_OFFLOAD)
static inline int socket(int family, int type, int proto)
{
#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
Expand Down Expand Up @@ -296,13 +298,6 @@ static inline int poll(struct zsock_pollfd *fds, int nfds, int timeout)
#endif /* defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) */
}

#define pollfd zsock_pollfd
#define POLLIN ZSOCK_POLLIN
#define POLLOUT ZSOCK_POLLOUT

#define MSG_PEEK ZSOCK_MSG_PEEK
#define MSG_DONTWAIT ZSOCK_MSG_DONTWAIT

static inline int getsockopt(int sock, int level, int optname,
void *optval, socklen_t *optlen)
{
Expand All @@ -323,6 +318,16 @@ static inline int setsockopt(int sock, int level, int optname,
#endif
}

#else
#include <net/socket_offload.h>
#endif /* !defined(CONFIG_NET_SOCKETS_OFFLOAD) */

#define POLLIN ZSOCK_POLLIN
#define POLLOUT ZSOCK_POLLOUT

#define MSG_PEEK ZSOCK_MSG_PEEK
#define MSG_DONTWAIT ZSOCK_MSG_DONTWAIT

static inline char *inet_ntop(sa_family_t family, const void *src, char *dst,
size_t size)
{
Expand Down
147 changes: 147 additions & 0 deletions include/net/socket_offload.h
@@ -0,0 +1,147 @@
/*
* Copyright (c) 2018 Linaro Limited.
*
* SPDX-License-Identifier: Apache-2.0
*/

/**
* @file
* @brief Socket Offload Redirect API
*/

#ifndef __SOCKET_OFFLOAD_H__
#define __SOCKET_OFFLOAD_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <net/socket_offload_ops.h>

extern const struct socket_offload *socket_ops;

static inline int socket(int family, int type, int proto)
{
__ASSERT_NO_MSG(socket_ops);
__ASSERT_NO_MSG(socket_ops->socket);

return socket_ops->socket(family, type, proto);
}

static inline int close(int sock)
{
__ASSERT_NO_MSG(socket_ops);
__ASSERT_NO_MSG(socket_ops->close);

return socket_ops->close(sock);
}

static inline int accept(int sock, struct sockaddr *addr,
socklen_t *addrlen)
{
__ASSERT_NO_MSG(socket_ops);
__ASSERT_NO_MSG(socket_ops->accept);

return socket_ops->accept(sock, addr, addrlen);
}


static inline int bind(int sock, const struct sockaddr *addr,
socklen_t addrlen)
{
__ASSERT_NO_MSG(socket_ops);
__ASSERT_NO_MSG(socket_ops->bind);

return socket_ops->bind(sock, addr, addrlen);
}

static inline int listen(int sock, int backlog)
{
__ASSERT_NO_MSG(socket_ops);
__ASSERT_NO_MSG(socket_ops->listen);

return socket_ops->listen(sock, backlog);
}

static inline int connect(int sock, const struct sockaddr *addr,
socklen_t addrlen)
{
__ASSERT_NO_MSG(socket_ops);
__ASSERT_NO_MSG(socket_ops->connect);

return socket_ops->connect(sock, addr, addrlen);
}

static inline int poll(struct pollfd *fds, int nfds, int timeout)
{
__ASSERT_NO_MSG(socket_ops);
__ASSERT_NO_MSG(socket_ops->poll);

return socket_ops->poll(fds, nfds, timeout);
}

static inline int setsockopt(int sock, int level, int optname,
const void *optval,
socklen_t optlen)
{
__ASSERT_NO_MSG(socket_ops);
__ASSERT_NO_MSG(socket_ops->setsockopt);

return socket_ops->setsockopt(sock, level, optname, optval, optlen);
}

static inline int getsockopt(int sock, int level, int optname,
void *optval, socklen_t *optlen)
{
__ASSERT_NO_MSG(socket_ops);
__ASSERT_NO_MSG(socket_ops->getsockopt);

return socket_ops->getsockopt(sock, level, optname, optval, optlen);
}

static inline ssize_t recv(int sock, void *buf, size_t max_len,
int flags)
{
__ASSERT_NO_MSG(socket_ops);
__ASSERT_NO_MSG(socket_ops->recv);

return socket_ops->recv(sock, buf, max_len, flags);
}

static inline ssize_t recvfrom(int sock, void *buf,
short int len,
short int flags,
struct sockaddr *from,
socklen_t *fromlen)
{
__ASSERT_NO_MSG(socket_ops);
__ASSERT_NO_MSG(socket_ops->recvfrom);

return socket_ops->recvfrom(sock, buf, len, flags, from, fromlen);
}

static inline ssize_t send(int sock, const void *buf, size_t len,
int flags)
{
__ASSERT_NO_MSG(socket_ops);
__ASSERT_NO_MSG(socket_ops->send);

return socket_ops->send(sock, buf, len, flags);
}

static inline ssize_t sendto(int sock, const void *buf,
size_t len, int flags,
const struct sockaddr *to,
socklen_t tolen)
{
__ASSERT_NO_MSG(socket_ops);
__ASSERT_NO_MSG(socket_ops->sendto);

return socket_ops->sendto(sock, buf, len, flags, to, tolen);
}

#ifdef __cplusplus
}
#endif

#endif /* __SOCKET_OFFLOAD_H__ */
56 changes: 56 additions & 0 deletions include/net/socket_offload_ops.h
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2018 Linaro Limited.
*
* SPDX-License-Identifier: Apache-2.0
*/

/**
* @file
* @brief Socket Offload Redirect API
*/

#ifndef __SOCKET_OFFLOAD_OPS_H__
#define __SOCKET_OFFLOAD_OPS_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <sys/types.h>
#include <net/net_ip.h>
#include <net/socket.h> /* needed for struct pollfd */

/*
* It is assumed that these offload functions follow the
* POSIX socket API standard for arguments, return values and setting of errno.
*/
struct socket_offload {
/* POSIX Socket Functions: */
int (*socket)(int family, int type, int proto);
int (*close)(int sock);
int (*accept)(int sock, struct sockaddr *addr, socklen_t *addrlen);
int (*bind)(int sock, const struct sockaddr *addr, socklen_t addrlen);
int (*listen)(int sock, int backlog);
int (*connect)(int sock, const struct sockaddr *addr,
socklen_t addrlen);
int (*poll)(struct pollfd *fds, int nfds, int timeout);
int (*setsockopt)(int sock, int level, int optname,
const void *optval, socklen_t optlen);
int (*getsockopt)(int sock, int level, int optname, void *optval,
socklen_t *optlen);
ssize_t (*recv)(int sock, void *buf, size_t max_len, int flags);
ssize_t (*recvfrom)(int sock, void *buf, short int len,
short int flags, struct sockaddr *from,
socklen_t *fromlen);
ssize_t (*send)(int sock, const void *buf, size_t len, int flags);
ssize_t (*sendto)(int sock, const void *buf, size_t len, int flags,
const struct sockaddr *to, socklen_t tolen);
};

extern void socket_offload_register(const struct socket_offload *ops);

#ifdef __cplusplus
}
#endif

#endif /* __SOCKET_OFFLOAD_OPS_H__ */
3 changes: 2 additions & 1 deletion subsys/net/lib/sockets/CMakeLists.txt
Expand Up @@ -4,4 +4,5 @@ zephyr_sources(
sockets.c
)

zephyr_sources_ifdef(CONFIG_NET_SOCKETS_SOCKOPT_TLS sockets_tls.c)
zephyr_sources_ifdef(CONFIG_NET_SOCKETS_SOCKOPT_TLS sockets_tls.c)
zephyr_sources_ifdef(CONFIG_NET_SOCKETS_OFFLOAD socket_offload.c)
14 changes: 14 additions & 0 deletions subsys/net/lib/sockets/Kconfig
Expand Up @@ -82,6 +82,20 @@ config NET_SOCKETS_TLS_MAX_CIPHERSUITES
By default, all ciphersuites that are available in the system are
available to the socket.

config NET_SOCKETS_OFFLOAD
bool "Offload Socket APIs [EXPERIMENTAL]"
select NET_SOCKETS_POSIX_NAMES
help
Enables direct offloading of socket operations to dedicated TCP/IP
hardware.
This feature is intended to save resources by bypassing the Zephyr
TCP/IP stack in the case where there is only one network interface
required in the system, providing full BSD socket offload capability.
As a result, it bypasses any potential IP routing that Zephyr might
provide between multiple network interfaces.
See NET_OFFLOAD for a more deeply integrated approach which offloads
from the net_context() API within the Zephyr IP stack.

config NET_DEBUG_SOCKETS
bool "Debug BSD Sockets compatible API calls"
default y if NET_LOG_GLOBAL
Expand Down
18 changes: 18 additions & 0 deletions subsys/net/lib/sockets/socket_offload.c
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2018 Linaro Limited.
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <net/socket_offload.h>

/* Only one provider may register socket operations upon boot. */
const struct socket_offload *socket_ops;

void socket_offload_register(const struct socket_offload *ops)
{
__ASSERT_NO_MSG(ops);
__ASSERT_NO_MSG(socket_ops == NULL);

socket_ops = ops;
}

0 comments on commit c21b0fb

Please sign in to comment.