lxip: update to Linux 6.1.20

This commit updates lxip from version 4.4.3 to 6.1.20. It uses the
current lx_kit approach and is a shared library again. The stack has
been tested for x86_32/x86_64/arm_v6/arm_v7/arm_8.

The C-interface of the IP stack can be found under
lxip/include/genode_c_api/socket.h.

issue #5104
This commit is contained in:
Sebastian Sumpf 2023-09-01 19:14:59 +02:00 committed by Christian Helmuth
parent c2080ecc03
commit 42d9640443
35 changed files with 11571 additions and 0 deletions

View File

@ -0,0 +1 @@
INC_DIR += $(REP_DIR)/src/lib/lxip/include

View File

@ -0,0 +1,33 @@
LXIP_DIR := $(REP_DIR)/src/lib/lxip
LIBS := jitterentropy virt_lx_emul virt_linux_generated
SHARED_LIB := yes
TARGET_LIB_DIR := $(LXIP_DIR)
INC_DIR += $(LXIP_DIR)/shadow $(LXIP_DIR)/include $(LXIP_DIR)
SRC_CC += lx_emul/random.cc
SRC_CC += init.cc \
socket.cc \
SRC_C += dummies.c \
generated_dummies.c \
lx_emul.c \
lx_socket.c \
lx_user.c \
net_driver.c \
SRC_CC += genode_c_api/nic_client.cc
#
# Don't create jump slots for everything compiled in here since there are
# function calls from inline assembly (i.e., __sw_hweight64) with unaligned sp
# leading to GPs during fxsave on x86).
#
LD_OPT += -Bsymbolic-functions
vpath %.cc $(REP_DIR)/src/lib
vpath %.c $(LXIP_DIR)/spec/$(SPEC_ARCH)
vpath % $(LXIP_DIR)
# vi: set ft=make :

View File

@ -0,0 +1,3 @@
SPEC_ARCH := arm_v6
include $(REP_DIR)/lib/mk/lxip.inc

View File

@ -0,0 +1,3 @@
SPEC_ARCH := arm_v7
include $(REP_DIR)/lib/mk/lxip.inc

View File

@ -0,0 +1,5 @@
SPEC_ARCH := arm_v8
SRC_C += lx_emul/shadow/arch/arm64/kernel/smp.c
include $(REP_DIR)/lib/mk/lxip.inc

View File

@ -0,0 +1,5 @@
SPEC_ARCH := x86_32
SRC_C = lx_emul/spec/x86_32/atomic64_32.c
include $(REP_DIR)/lib/mk/lxip.inc

View File

@ -0,0 +1,3 @@
SPEC_ARCH := x86_64
include $(REP_DIR)/lib/mk/lxip.inc

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,365 @@
/*
* \brief Dummy definitions of Linux kernel functions
* \author Sebastian Sumpf
* \date 2024-01-29
*/
/*
* Copyright (C) 2024 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <lx_emul.h>
unsigned smp_on_up;
/* lx_kit's 'kernel_init' in start.c */
extern int __init devices_init(void);
int __init devices_init(void)
{
lx_emul_trace(__func__);
return 0;
}
extern int __init buses_init(void);
int __init buses_init(void)
{
lx_emul_trace(__func__);
return 0;
}
#include <linux/jump_label.h>
#include <asm/processor.h>
struct static_key_false init_on_alloc;
unsigned long sysctl_net_busy_read;
DEFINE_STATIC_KEY_FALSE(force_irqthreads_key);
DEFINE_STATIC_KEY_FALSE(bpf_stats_enabled_key);
#include <linux/cpumask.h>
#include <linux/percpu-defs.h>
DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_map);
EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
#include <net/ipv6_stubs.h>
const struct ipv6_stub *ipv6_stub = NULL;
#include <asm/uaccess.h>
long strncpy_from_user(char * dst,const char __user * src,long count)
{
lx_emul_trace_and_stop(__func__);
}
int __copy_from_user_flushcache(void *dst, const void __user *src, unsigned size)
{
lx_emul_trace_and_stop(__func__);
}
#ifdef __x86_64__
unsigned long clear_user(void *mem, unsigned long len)
{
lx_emul_trace_and_stop(__func__);
}
#endif
#ifdef ARCH_HAS_NOCACHE_UACCESS
int __copy_from_user_inatomic_nocache(void *dst, const void __user *src,
unsigned size)
{
lx_emul_trace_and_stop(__func__);
}
#endif
#include <asm/uaccess.h>
long strnlen_user(const char __user * str,long count)
{
lx_emul_trace_and_stop(__func__);
}
void add_device_randomness(const void * buf,size_t len)
{
lx_emul_trace(__func__);
}
#include <linux/device.h>
void *__devres_alloc_node(dr_release_t release, size_t size, gfp_t gfp,
int nid, const char *name)
{
lx_emul_trace_and_stop(__func__);
return 0;
}
void devres_free(void *res)
{
lx_emul_trace_and_stop(__func__);
}
void devres_add(struct device *dev, void *res)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/rcutree.h>
void synchronize_rcu_expedited(void)
{
lx_emul_trace(__func__);
}
#include <linux/rcupdate.h>
void synchronize_rcu(void)
{
lx_emul_trace(__func__);
}
#include <linux/kernel.h>
char *get_options(const char *str, int nints, int *ints)
{
lx_emul_trace_and_stop(__func__);
return 0;
}
#include <linux/fs.h>
char *file_path(struct file *, char *, int)
{
lx_emul_trace_and_stop(__func__);
return 0;
}
#include <asm/page.h>
#ifdef __x86_64__
void copy_page(void *to, void *from)
{
lx_emul_trace_and_stop(__func__);
}
#endif
#include <linux/filter.h>
void bpf_jit_compile(struct bpf_prog *prog)
{
lx_emul_trace_and_stop(__func__);
}
#include <linux/bpf.h>
u64 bpf_get_raw_cpu_id(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
{
lx_emul_trace_and_stop(__func__);
return 0;
}
#ifndef __arm__
#include <linux/timekeeper_internal.h>
void update_vsyscall(struct timekeeper * tk)
{
lx_emul_trace(__func__);
}
#else
#include <asm/cacheflush.h>
struct cpu_cache_fns cpu_cache;
#include <asm/uaccess.h>
asmlinkage void __div0(void);
asmlinkage void __div0(void)
{
lx_emul_trace_and_stop(__func__);
}
#endif
#include <linux/kobject.h>
int kobject_uevent(struct kobject * kobj,enum kobject_action action)
{
lx_emul_trace(__func__);
return 0;
}
#include <linux/ethtool.h>
int ethtool_check_ops(const struct ethtool_ops * ops)
{
lx_emul_trace(__func__);
return 0;
}
#include <linux/device/driver.h>
void wait_for_device_probe(void)
{
lx_emul_trace(__func__);
}
#include <linux/irq_work.h>
void irq_work_tick(void)
{
lx_emul_trace(__func__);
}
#include <linux/pid.h>
void put_pid(struct pid * pid)
{
lx_emul_trace(__func__);
}
#include <linux/ratelimit_types.h>
int ___ratelimit(struct ratelimit_state * rs,const char * func)
{
lx_emul_trace(__func__);
return 0;
}
#include <asm-generic/softirq_stack.h>
void do_softirq_own_stack(void)
{
lx_emul_trace(__func__);
}
unsigned long __must_check __arch_clear_user(void __user *to, unsigned long n);
unsigned long __must_check __arch_clear_user(void __user *to, unsigned long n)
{
lx_emul_trace_and_stop(__func__);
}
unsigned long __must_check arm_clear_user(void __user *addr, unsigned long n);
unsigned long __must_check arm_clear_user(void __user *addr, unsigned long n)
{
lx_emul_trace_and_stop(__func__);
}
u64 bpf_user_rnd_u32(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
{
lx_emul_trace_and_stop(__func__);
return 0;
}
u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size,
void *ctx, u64 ctx_size, bpf_ctx_copy_t ctx_copy)
{
lx_emul_trace_and_stop(__func__);
return 0;
}
/* kernel/sched/cpudeadline.h */
struct cpudl;
int cpudl_init(struct cpudl *cp)
{
lx_emul_trace_and_stop(__func__);
return -1;
}
void cpudl_cleanup(struct cpudl *cp)
{
lx_emul_trace_and_stop(__func__);
}
void dl_clear_root_domain(struct root_domain *rd)
{
lx_emul_trace_and_stop(__func__);
}
/* kernel/sched/sched.h */
bool sched_smp_initialized = true;
struct dl_bw;
void init_dl_bw(struct dl_bw *dl_b)
{
lx_emul_trace_and_stop(__func__);
}
struct irq_work;
void rto_push_irq_work_func(struct irq_work *work)
{
lx_emul_trace_and_stop(__func__);
}
/* include/linux/sched/topology.h */
int arch_asym_cpu_priority(int cpu)
{
lx_emul_trace_and_stop(__func__);
return 0;
}
extern int __init netdev_kobject_init(void);
int __init netdev_kobject_init(void)
{
lx_emul_trace(__func__);
return 0;
}
extern int netdev_register_kobject(struct net_device * ndev);
int netdev_register_kobject(struct net_device * ndev)
{
lx_emul_trace(__func__);
return 0;
}

View File

@ -0,0 +1,248 @@
/*
* \brief C interface to Genode's nic_client session
* \author Norman Feske
* \date 2021-07-06
*/
/*
* Copyright (C) 2021 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <base/registry.h>
#include <base/log.h>
#include <base/session_label.h>
#include <nic_session/connection.h>
#include <nic/packet_allocator.h>
#include <genode_c_api/nic_client.h>
using namespace Genode;
struct Statics
{
Env *env_ptr;
Allocator *alloc_ptr;
Signal_context_capability sigh { };
Registry<Registered<genode_nic_client>> nic_clients { };
};
static Statics & statics()
{
static Statics instance { };
return instance;
};
struct genode_nic_client : private Noncopyable, private Interface
{
private:
Env &_env;
Allocator &_alloc;
Nic::Packet_allocator _packet_alloc { &_alloc };
static constexpr size_t
PACKET_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE,
BUF_SIZE = Nic::Session::QUEUE_SIZE * PACKET_SIZE;
Session_label const _session_label;
Nic::Connection _connection { _env, &_packet_alloc,
BUF_SIZE, BUF_SIZE,
_session_label.string() };
public:
genode_nic_client(Env &env, Allocator &alloc, Signal_context_capability sigh,
Session_label const &session_label)
:
_env(env), _alloc(alloc),
_session_label(session_label)
{
_connection.rx_channel()->sigh_ready_to_ack (sigh);
_connection.rx_channel()->sigh_packet_avail (sigh);
_connection.tx_channel()->sigh_ack_avail (sigh);
_connection.tx_channel()->sigh_ready_to_submit(sigh);
}
void notify_peer()
{
_connection.rx()->wakeup();
_connection.tx()->wakeup();
}
template <typename FN>
bool tx_one_packet(FN const &fn)
{
bool progress = false;
Nic::Session::Tx::Source &tx_source = *_connection.tx();
/*
* Process acknowledgements
*/
while (tx_source.ack_avail()) {
tx_source.release_packet(tx_source.try_get_acked_packet());
progress = true;
}
/*
* Submit packet
*/
if (!tx_source.ready_to_submit(1))
return progress;
typedef Nic::Packet_descriptor Packet_descriptor;
Packet_descriptor packet { };
size_t const max_bytes = Nic::Packet_allocator::OFFSET_PACKET_SIZE;
tx_source.alloc_packet_attempt(max_bytes).with_result(
[&] (Packet_descriptor packet)
{
char * const dst_ptr = tx_source.packet_content(packet);
size_t const payload_bytes = min(max_bytes, fn(dst_ptr, max_bytes));
/* imprint payload size into packet descriptor */
packet = Packet_descriptor(packet.offset(), payload_bytes);
tx_source.try_submit_packet(packet);
progress = true;
},
[] (auto) {}
);
return progress;
}
template <typename FN>
bool for_each_rx_packet(FN const &fn)
{
/*
* Implementation mirrored from (commented) block/request_stream.h
*/
bool overall_progress = false;
Nic::Session::Rx::Sink &rx_sink = *_connection.rx();
for (;;) {
if (!rx_sink.packet_avail() || !rx_sink.ack_slots_free())
break;
typedef Nic::Packet_descriptor Packet_descriptor;
Packet_descriptor const packet = rx_sink.peek_packet();
bool const packet_valid = rx_sink.packet_valid(packet)
&& (packet.offset() >= 0);
char const *content = rx_sink.packet_content(packet);
genode_nic_client_rx_result_t const
response = packet_valid
? fn(content, packet.size())
: GENODE_NIC_CLIENT_RX_REJECTED;
bool progress = false;
switch (response) {
case GENODE_NIC_CLIENT_RX_ACCEPTED:
case GENODE_NIC_CLIENT_RX_REJECTED:
(void)rx_sink.try_get_packet();
rx_sink.try_ack_packet(packet);
progress = true;
break;
case GENODE_NIC_CLIENT_RX_RETRY:
Genode::warning("RETRY");
break;
}
if (progress)
overall_progress = true;
if (!progress)
break;
}
return overall_progress;
}
Nic::Mac_address mac_address() { return _connection.mac_address(); }
};
void genode_nic_client_init(genode_env *env_ptr,
genode_allocator *alloc_ptr,
genode_signal_handler *sigh_ptr)
{
statics().env_ptr = env_ptr;
statics().alloc_ptr = alloc_ptr;
statics().sigh = cap(sigh_ptr);
}
void genode_nic_client_notify_peers()
{
statics().nic_clients.for_each([&] (genode_nic_client &nic_client) {
nic_client.notify_peer(); });
}
genode_mac_address genode_nic_client_mac_address(genode_nic_client *nic_client_ptr)
{
Nic::Mac_address mac = nic_client_ptr->mac_address();
struct genode_mac_address genode_mac;
Genode::memcpy(genode_mac.addr, &mac.addr, sizeof(genode_mac_address));
return genode_mac;
}
bool genode_nic_client_tx_packet(genode_nic_client *nic_client_ptr,
genode_nic_client_tx_packet_content_t tx_packet_content_cb,
genode_nic_client_tx_packet_context *ctx_ptr)
{
return nic_client_ptr->tx_one_packet([&] (char *dst, size_t len) {
return tx_packet_content_cb(ctx_ptr, dst, len); });
}
bool genode_nic_client_rx(struct genode_nic_client *nic_client_ptr,
genode_nic_client_rx_one_packet_t rx_one_packet_cb,
struct genode_nic_client_rx_context *ctx_ptr)
{
return nic_client_ptr->for_each_rx_packet([&] (char const *ptr, size_t len) {
return rx_one_packet_cb(ctx_ptr, ptr, len); });
}
struct genode_nic_client *genode_nic_client_create(char const *label)
{
if (!statics().env_ptr || !statics().alloc_ptr) {
error("genode_nic_client_create: missing call of genode_nic_client_init");
return nullptr;
}
return new (*statics().alloc_ptr)
Registered<genode_nic_client>(statics().nic_clients, *statics().env_ptr,
*statics().alloc_ptr, statics().sigh,
Session_label(label));
}
void genode_nic_client_destroy(genode_nic_client *nic_client_ptr)
{
destroy(*statics().alloc_ptr, nic_client_ptr);
}

View File

@ -0,0 +1,110 @@
/*
* \brief C interface to Genode's NIC session
* \author Norman Feske
* \author Sebastian Sumpf
* \date 2024-01-29
*/
/*
* Copyright (C) 2024 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef __GENODE_C_API__NIC_CLIENT_H_
#define __GENODE_C_API__NIC_CLIENT_H_
#include <genode_c_api/base.h>
#include <genode_c_api/mac_address_reporter.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Initialize NIC handling
*
* \param sigh signal handler to be installed at the NIC connection
*/
void genode_nic_client_init(struct genode_env *,
struct genode_allocator *,
struct genode_signal_handler *);
/**
* Wake up NIC server if progress can be made at the server side
*
* This function should be called whenever the component becomes idle.
*/
void genode_nic_client_notify_peers(void);
struct genode_nic_client; /* definition is private to the implementation */
/**************
** Lifetime **
**************/
struct genode_nic_client *genode_nic_client_create(char const *label);
void genode_nic_client_destroy(struct genode_nic_client *);
/*************
** Session **
*************/
/**
* Retreive MAC address from server
*/
struct genode_mac_address genode_nic_client_mac_address(struct genode_nic_client *);
/**********************************************
** Transmit packets towards the NIC session **
**********************************************/
struct genode_nic_client_tx_packet_context;
/**
* Callback called by 'genode_nic_client_tx_packet' to provide the content
*/
typedef unsigned long (*genode_nic_client_tx_packet_content_t)
(struct genode_nic_client_tx_packet_context *, char *dst, unsigned long dst_len);
/**
* Process packet transmission
*
* \return true if progress was made
*/
bool genode_nic_client_tx_packet(struct genode_nic_client *,
genode_nic_client_tx_packet_content_t,
struct genode_nic_client_tx_packet_context *);
/******************************************
** Receive packets from the NIC session **
******************************************/
struct genode_nic_client_rx_context;
typedef enum { GENODE_NIC_CLIENT_RX_REJECTED,
GENODE_NIC_CLIENT_RX_ACCEPTED,
GENODE_NIC_CLIENT_RX_RETRY } genode_nic_client_rx_result_t;
typedef genode_nic_client_rx_result_t (*genode_nic_client_rx_one_packet_t)
(struct genode_nic_client_rx_context *, char const *ptr, unsigned long len);
/**
* Process packet reception
*
* \return true if progress was made
*/
bool genode_nic_client_rx(struct genode_nic_client *,
genode_nic_client_rx_one_packet_t rx_one_packet,
struct genode_nic_client_rx_context *);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __GENODE_C_API__NIC_CLIENT_H_ */

View File

@ -0,0 +1,254 @@
/*
* \brief Genode socket C-API
* \author Sebastian Sumpf
* \date 2024-01-29
*/
/*
* Copyright (C) 2024 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <base/fixed_stdint.h>
#include <genode_c_api/base.h>
#ifdef __cplusplus
extern "C" {
#endif
enum Errno {
GENODE_ENONE = 0,
GENODE_E2BIG = 1,
GENODE_EACCES = 2,
GENODE_EADDRINUSE = 3,
GENODE_EADDRNOTAVAIL = 4,
GENODE_EAFNOSUPPORT = 5,
GENODE_EAGAIN = 6,
GENODE_EALREADY = 7,
GENODE_EBADF = 8,
GENODE_EBADFD = 9,
GENODE_EBADMSG = 10,
GENODE_EBADRQC = 11,
GENODE_EBUSY = 12,
GENODE_ECONNABORTED = 13,
GENODE_ECONNREFUSED = 14,
GENODE_EDESTADDRREQ = 15,
GENODE_EDOM = 16,
GENODE_EEXIST = 17,
GENODE_EFAULT = 18,
GENODE_EFBIG = 19,
GENODE_EHOSTUNREACH = 20,
GENODE_EINPROGRESS = 21,
GENODE_EINTR = 22,
GENODE_EINVAL = 23,
GENODE_EIO = 24,
GENODE_EISCONN = 25,
GENODE_ELOOP = 26,
GENODE_EMLINK = 27,
GENODE_EMSGSIZE = 28,
GENODE_ENAMETOOLONG = 29,
GENODE_ENETDOWN = 30,
GENODE_ENETUNREACH = 31,
GENODE_ENFILE = 32,
GENODE_ENOBUFS = 33,
GENODE_ENODATA = 34,
GENODE_ENODEV = 35,
GENODE_ENOENT = 36,
GENODE_ENOIOCTLCMD = 37,
GENODE_ENOLINK = 38,
GENODE_ENOMEM = 39,
GENODE_ENOMSG = 40,
GENODE_ENOPROTOOPT = 41,
GENODE_ENOSPC = 42,
GENODE_ENOSYS = 43,
GENODE_ENOTCONN = 44,
GENODE_ENOTSUPP = 45,
GENODE_ENOTTY = 46,
GENODE_ENXIO = 47,
GENODE_EOPNOTSUPP = 48,
GENODE_EOVERFLOW = 49,
GENODE_EPERM = 50,
GENODE_EPFNOSUPPORT = 51,
GENODE_EPIPE = 52,
GENODE_EPROTO = 53,
GENODE_EPROTONOSUPPORT = 54,
GENODE_EPROTOTYPE = 55,
GENODE_ERANGE = 56,
GENODE_EREMCHG = 57,
GENODE_ESOCKTNOSUPPORT = 58,
GENODE_ESPIPE = 59,
GENODE_ESRCH = 60,
GENODE_ESTALE = 61,
GENODE_ETIMEDOUT = 62,
GENODE_ETOOMANYREFS = 63,
GENODE_EUSERS = 64,
GENODE_EXDEV = 65,
GENODE_MAX_ERRNO = 66,
};
enum Sock_opt {
/* found in lxip and lwip */
GENODE_SO_DEBUG = 1,
GENODE_SO_ACCEPTCONN = 2,
GENODE_SO_DONTROUTE = 3,
GENODE_SO_LINGER = 4,
GENODE_SO_OOBINLINE = 5,
GENODE_SO_REUSEPORT = 6,
GENODE_SO_SNDBUF = 7,
GENODE_SO_RCVBUF = 8,
GENODE_SO_SNDLOWAT = 9,
GENODE_SO_RCVLOWAT = 10,
GENODE_SO_SNDTIMEO = 11,
GENODE_SO_RCVTIMEO = 12,
GENODE_SO_ERROR = 13,
GENODE_SO_TYPE = 14,
GENODE_SO_BINDTODEVICE = 15,
GENODE_SO_BROADCAST = 16,
};
enum Sock_level {
GENODE_SOL_SOCKET = 1,
};
struct genode_socket_handle;
struct genode_sockaddr
{
genode_uint16_t family;
union {
/* AF_INET (or IPv4) */
struct {
genode_uint16_t port; /* be */
genode_uint32_t addr; /* be */
} in;
};
};
/*
* I/O progress callback can be registered via genode_socket_init and is
* executed when possible progress (e.g., packet received) has been made
*/
struct genode_socket_io_progress
{
void *data;
void (*callback)(void *);
};
void genode_socket_init(struct genode_env *env,
struct genode_socket_io_progress *);
/**
* IPv4 address configuration (DHCP or static)
*/
struct genode_socket_config
{
/* IPv4 */
bool dhcp;
char const *ip_addr;
char const *netmask;
char const *gateway;
char const *nameserver;
};
/**
* Configure/obtain IP address (blocking)
*/
void genode_socket_config_address(struct genode_socket_config *config);
/**
* Configure MTU size (default should be 1500)
*/
void genode_socket_configure_mtu(unsigned mtu);
/**
* Wait for I/O progress (synchronous) - used for testing if no
* genode_socket_io_progress has been registered.
*/
void genode_socket_wait_for_progress(void);
/**
* The following calls have POSIX semantics and are non-blocking
*/
struct genode_socket_handle *
genode_socket(int domain, int type, int protocol, enum Errno *);
enum Errno genode_socket_bind(struct genode_socket_handle *,
struct genode_sockaddr const *);
enum Errno genode_socket_listen(struct genode_socket_handle *,
int backlog);
struct genode_socket_handle *
genode_socket_accept(struct genode_socket_handle *,
struct genode_sockaddr *,
enum Errno *);
enum Errno genode_socket_connect(struct genode_socket_handle *,
struct genode_sockaddr *);
unsigned genode_socket_pollin_set(void);
unsigned genode_socket_pollout_set(void);
unsigned genode_socket_pollex_set(void);
unsigned genode_socket_poll(struct genode_socket_handle *);
enum Errno genode_socket_getsockopt(struct genode_socket_handle *,
enum Sock_level, enum Sock_opt,
void *optval, unsigned *optlen);
enum Errno genode_socket_setsockopt(struct genode_socket_handle *,
enum Sock_level, enum Sock_opt,
void const *optval,
unsigned optlen);
enum Errno genode_socket_getsockname(struct genode_socket_handle *,
struct genode_sockaddr *);
enum Errno genode_socket_getpeername(struct genode_socket_handle *,
struct genode_sockaddr *);
/**
* I/O vector
*/
struct genode_iovec
{
void *base;
unsigned long size;
};
struct genode_msghdr
{
struct genode_sockaddr *name; /* can be NULL for TCP */
struct genode_iovec *iov; /* array of iovecs */
unsigned long iovlen; /* nr elements in msg_iov */
};
enum Errno genode_socket_sendmsg(struct genode_socket_handle *,
struct genode_msghdr *,
unsigned long *bytes_send);
/**
* \param msg_peek Does not advance data read pointer, so data can be re-read
* later
*/
enum Errno genode_socket_recvmsg(struct genode_socket_handle *,
struct genode_msghdr *,
unsigned long *bytes_recv,
bool msg_peek);
enum Errno genode_socket_shutdown(struct genode_socket_handle *,
int how);
enum Errno genode_socket_release(struct genode_socket_handle *);
#ifdef __cplusplus
} /* extern "C" */
#endif

View File

@ -0,0 +1,33 @@
/*
* \brief Definitions of standard socket API values used when no libc headers
* are present
* \author Sebastian Sumpf
* \date 2024-01-29
*/
/*
* Copyright (C) 2024 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
enum {
/* socket domain */
AF_UNSPEC = 0,
AF_INET = 2,
/* socket type */
SOCK_STREAM = 1,
SOCK_DGRAM = 2,
/* protocol */
IPPROTO_TCP = 6,
IPPROTO_UDP = 17,
/* sockaddr_in */
INADDR_ANY = 0ul,
INADDR_BROADCAST = ~0u,
/* shutdown */
SHUT_RD = 0,
SHUT_WR = 1,
SHUT_RDWR = 2,
};

View File

@ -0,0 +1,89 @@
/*
* \brief lx_kit C++ initialization and client handling
* \author Sebastian Sumpf
* \date 2024-01-29
*/
/*
* Copyright (C) 2024 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <lx_kit/env.h>
#include <lx_emul/init.h>
#include <lx_emul/task.h>
#include <genode_c_api/nic_client.h>
#include <genode_c_api/socket.h>
#include "lx_user.h"
#include "net_driver.h"
using namespace Genode;
struct Main
{
Env &env;
genode_socket_io_progress *io_progress;
Signal_handler<Main> schedule_handler { env.ep(), *this,
&Main::handle_schedule };
Io_signal_handler<Main> nic_client_handler { env.ep(), *this,
&Main::handle_nic_client };
Main(Env &env, genode_socket_io_progress *io_progress)
: env(env), io_progress(io_progress)
{ }
void handle_schedule()
{
Lx_kit::env().scheduler.execute();
if (io_progress && io_progress->callback)
io_progress->callback(io_progress->data);
}
void handle_nic_client()
{
lx_emul_task_unblock(lx_nic_client_rx_task());
Lx_kit::env().scheduler.execute();
if (io_progress && io_progress->callback)
io_progress->callback(io_progress->data);
}
void init()
{
genode_nic_client_init(genode_env_ptr(env),
genode_allocator_ptr(Lx_kit::env().heap),
genode_signal_handler_ptr(nic_client_handler));
}
Main(const Main&) = delete;
Main operator=(const Main&) = delete;
};
void genode_socket_init(struct genode_env *_env,
struct genode_socket_io_progress *io_progress)
{
Env &env = *static_cast<Env *>(_env);
static Main main { env, io_progress };
Lx_kit::initialize(env, main.schedule_handler);
main.init();
/* must be called before initcalls */
lx_user_configure_ip_stack();
lx_emul_start_kernel(nullptr);
/* wait to finish initialization before returning to callee */
lx_emul_execute_kernel_until(lx_user_startup_complete, nullptr);
}

View File

@ -0,0 +1,367 @@
/*
* \brief Implementation of driver specific Linux functions
* \author Sebastian Sumpf
* \date 2024-01-29
*/
/*
* Copyright (C) 2024 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <lx_emul.h>
#include <linux/net.h>
#include <linux/skbuff.h>
unsigned long __FIXADDR_TOP = 0xfffff000;
#include <linux/mm.h>
int mmap_rnd_bits;
#include <linux/percpu.h>
DEFINE_PER_CPU(unsigned long, cpu_scale);
#include <asm/pgtable.h>
#ifndef __arm__
pgd_t reserved_pg_dir[PTRS_PER_PGD];
#endif
bool arm64_use_ng_mappings = false;
pteval_t __default_kernel_pte_mask __read_mostly = ~0;
/* shadowed */
#include <linux/utsname.h>
struct new_utsname init_uts_ns;
#include <linux/random.h>
u8 get_random_u8(void)
{
return get_random_u32() & 0xff;
}
u16 get_random_u16(void)
{
return get_random_u32() & 0xffff;
}
#ifdef __arm__
#include <asm/uaccess.h>
unsigned long arm_copy_from_user(void *to, const void *from, unsigned long n)
{
memcpy(to, from, n);
return 0;
}
unsigned long arm_copy_to_user(void *to, const void *from, unsigned long n)
{
memcpy(to, from, n);
return 0;
}
#endif
#include <linux/uaccess.h>
#ifndef INLINE_COPY_TO_USER
unsigned long _copy_from_user(void * to,const void __user * from,unsigned long n)
{
memcpy(to, from, n);
return 0;
}
unsigned long raw_copy_from_user(void *to, const void * from, unsigned long n)
{
memcpy(to, from, n);
return 0;
}
#else
unsigned long __must_check __arch_copy_from_user(void *to, const void __user *from, unsigned long n);
unsigned long __must_check __arch_copy_from_user(void *to, const void __user *from, unsigned long n)
{
memcpy(to, from, n);
return 0;
}
#endif
#ifndef INLINE_COPY_FROM_USER
unsigned long _copy_to_user(void __user * to,const void * from,unsigned long n)
{
memcpy(to, from, n);
return 0;
}
unsigned long raw_copy_to_user(void *to, const void *from, unsigned long n)
{
memcpy(to, from, n);
return 0;
}
#else
unsigned long __must_check __arch_copy_to_user(void __user *to, const void *from, unsigned long n);
unsigned long __must_check __arch_copy_to_user(void __user *to, const void *from, unsigned long n)
{
memcpy(to, from, n);
return 0;
}
#endif
__wsum csum_partial_copy_from_user(const void __user *src, void *dst, int len)
{
memcpy(dst, src, len);
return csum_partial(dst, len, 0);
}
#include <linux/slab.h>
struct kmem_cache * kmem_cache_create_usercopy(const char * name,
unsigned int size,
unsigned int align,
slab_flags_t flags,
unsigned int useroffset,
unsigned int usersize,
void (* ctor)(void *))
{
return kmem_cache_create(name, size, align, flags, ctor);
}
#include <linux/stringhash.h>
unsigned int full_name_hash(const void *salt, const char *name, unsigned int len)
{
unsigned hash = ((unsigned long)salt) & ~0u;
unsigned i;
for (i = 0; i < len; i++)
hash += name[i];
return hash;
}
#include <linux/memblock.h>
void *alloc_large_system_hash(const char *tablename,
unsigned long bucketsize,
unsigned long numentries,
int scale,
int flags,
unsigned int *_hash_shift,
unsigned int *_hash_mask,
unsigned long low_limit,
unsigned long high_limit)
{
unsigned long elements = numentries ? numentries : high_limit;
unsigned long nlog2 = ilog2(elements);
void *table;
nlog2 <<= (1 << nlog2) < elements ? 1 : 0;
table = lx_emul_mem_alloc_aligned(elements * bucketsize, PAGE_SIZE);
if (!table) {
printk("%s:%d error failed to allocate system hash\n", __func__, __LINE__);
return NULL;
}
if (_hash_mask)
*_hash_mask = (1 << nlog2) - 1;
if (_hash_shift)
*_hash_shift = nlog2;
return table;
}
#include <linux/syscore_ops.h>
void register_syscore_ops(struct syscore_ops * ops)
{
lx_emul_trace(__func__);
}
#include <linux/gfp.h>
unsigned long get_zeroed_page(gfp_t gfp_mask)
{
return (unsigned long)kzalloc(PAGE_SIZE, GFP_KERNEL);
}
#include <linux/gfp.h>
void * page_frag_alloc_align(struct page_frag_cache * nc, unsigned int fragsz,
gfp_t gfp_mask, unsigned int align_mask)
{
if (align_mask != ~0U) {
printk("page_frag_alloc_align: unsupported align_mask=%x\n", align_mask);
lx_emul_trace_and_stop(__func__);
}
if (fragsz > PAGE_SIZE) {
printk("page_frag_alloc_align: unsupported fragsz=%u\n", fragsz);
lx_emul_trace_and_stop(__func__);
}
return alloc_pages_exact(PAGE_SIZE, GFP_KERNEL);
}
void page_frag_free(void * addr)
{
free_pages_exact(addr, PAGE_SIZE);
}
/* mm/page_alloc. */
/**
* nr_free_buffer_pages - count number of pages beyond high watermark
*
* nr_free_buffer_pages() counts the number of pages which are beyond the high
* watermark within ZONE_DMA and ZONE_NORMAL.
*
* used in 'tcp_mem_init'
*
* limit = max(nr_free_buffer_pages()/16, 128)
* -> set to max
*/
unsigned long nr_free_buffer_pages(void)
{
return 2048;
}
/****************************
** Linux socket functions **
****************************/
static const struct net_proto_family *net_families[NPROTO];
int sock_register(const struct net_proto_family *ops)
{
if (ops->family >= NPROTO) {
printk("protocol %d >= NPROTO (%d)\n", ops->family, NPROTO);
return -ENOBUFS;
}
net_families[ops->family] = ops;
pr_info("NET: Registered protocol family %d\n", ops->family);
return 0;
}
struct socket *sock_alloc(void)
{
struct socket *sock = (struct socket *)kzalloc(sizeof(struct socket), 0);
init_waitqueue_head(&sock->wq.wait);
sock->wq.fasync_list = NULL;
sock->wq.flags = 0;
sock->state = SS_UNCONNECTED;
sock->flags = 0;
sock->ops = NULL;
sock->sk = NULL;
sock->file = NULL;
return sock;
}
void sock_release(struct socket *sock)
{
kfree(sock);
}
int sock_create_lite(int family, int type, int protocol, struct socket **res)
{
struct socket *sock = sock_alloc();
if (!sock)
return -ENOMEM;
sock->type = type;
*res = sock;
return 0;
}
int sock_create_kern(struct net *net, int family, int type, int proto,
struct socket **res)
{
struct socket *sock;
const struct net_proto_family *pf;
int err;
if (family < 0 || family > NPROTO)
return -EAFNOSUPPORT;
if (type < 0 || type > SOCK_MAX)
return -EINVAL;
pf = net_families[family];
if (!pf) {
printk("No protocol found for family %d\n", family);
return -ENOPROTOOPT;
}
sock = sock_alloc();
if (!sock) {
printk("Could not allocate socket\n");
return -ENFILE;
}
sock->type = type;
err = pf->create(net, sock, proto, 1);
if (err) {
kfree(sock);
return err;
}
*res = sock;
return 0;
}
static int sock_init(void)
{
skb_init();
return 0;
}
core_initcall(sock_init);

View File

@ -0,0 +1,17 @@
/*
* \brief Definitions of Linux Kernel functions
* \author Sebastian Sumpf
* \date 2024-01-29
*/
/*
* Copyright (C) 2024 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <lx_emul/debug.h>
#include <linux/init.h>
#include <linux/sched/debug.h>

View File

@ -0,0 +1,475 @@
/*
* \brief C-interface to Linux socked kernel code
* \author Sebastian Sumpf
* \date 2024-01-29
*
* Can only be called by lx_lit tasks
*/
/*
* Copyright (C) 2024 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <linux/net.h>
#include <net/sock.h>
#include "lx_socket.h"
extern struct net init_net;
static enum Errno _genode_errno(int errno)
{
if (errno < 0) errno *= -1;
switch (errno) {
case 0: return GENODE_ENONE;
case E2BIG: return GENODE_E2BIG;
case EACCES: return GENODE_EACCES;
case EADDRINUSE: return GENODE_EADDRINUSE;
case EADDRNOTAVAIL: return GENODE_EADDRNOTAVAIL;
case EAFNOSUPPORT: return GENODE_EAFNOSUPPORT;
case EAGAIN: return GENODE_EAGAIN;
case EALREADY: return GENODE_EALREADY;
case EBADF: return GENODE_EBADF;
case EBADFD: return GENODE_EBADFD;
case EBADMSG: return GENODE_EBADMSG;
case EBADRQC: return GENODE_EBADRQC;
case EBUSY: return GENODE_EBUSY;
case ECONNABORTED: return GENODE_ECONNABORTED;
case ECONNREFUSED: return GENODE_ECONNREFUSED;
case EDESTADDRREQ: return GENODE_EDESTADDRREQ;
case EDOM: return GENODE_EDOM;
case EEXIST: return GENODE_EEXIST;
case EFAULT: return GENODE_EFAULT;
case EFBIG: return GENODE_EFBIG;
case EHOSTUNREACH: return GENODE_EHOSTUNREACH;
case EINPROGRESS: return GENODE_EINPROGRESS;
case EINTR: return GENODE_EINTR;
case EINVAL: return GENODE_EINVAL;
case EIO: return GENODE_EIO;
case EISCONN: return GENODE_EISCONN;
case ELOOP: return GENODE_ELOOP;
case EMLINK: return GENODE_EMLINK;
case EMSGSIZE: return GENODE_EMSGSIZE;
case ENAMETOOLONG: return GENODE_ENAMETOOLONG;
case ENETDOWN: return GENODE_ENETDOWN;
case ENETUNREACH: return GENODE_ENETUNREACH;
case ENFILE: return GENODE_ENFILE;
case ENOBUFS: return GENODE_ENOBUFS;
case ENODATA: return GENODE_ENODATA;
case ENODEV: return GENODE_ENODEV;
case ENOENT: return GENODE_ENOENT;
case ENOIOCTLCMD: return GENODE_ENOIOCTLCMD;
case ENOLINK: return GENODE_ENOLINK;
case ENOMEM: return GENODE_ENOMEM;
case ENOMSG: return GENODE_ENOMSG;
case ENOPROTOOPT: return GENODE_ENOPROTOOPT;
case ENOSPC: return GENODE_ENOSPC;
case ENOSYS: return GENODE_ENOSYS;
case ENOTCONN: return GENODE_ENOTCONN;
case ENOTSUPP: return GENODE_ENOTSUPP;
case ENOTTY: return GENODE_ENOTTY;
case ENXIO: return GENODE_ENXIO;
case EOPNOTSUPP: return GENODE_EOPNOTSUPP;
case EOVERFLOW: return GENODE_EOVERFLOW;
case EPERM: return GENODE_EPERM;
case EPFNOSUPPORT: return GENODE_EPFNOSUPPORT;
case EPIPE: return GENODE_EPIPE;
case EPROTO: return GENODE_EPROTO;
case EPROTONOSUPPORT: return GENODE_EPROTONOSUPPORT;
case EPROTOTYPE: return GENODE_EPROTOTYPE;
case ERANGE: return GENODE_ERANGE;
case EREMCHG: return GENODE_EREMCHG;
case ESOCKTNOSUPPORT: return GENODE_ESOCKTNOSUPPORT;
case ESPIPE: return GENODE_ESPIPE;
case ESRCH: return GENODE_ESRCH;
case ESTALE: return GENODE_ESTALE;
case ETIMEDOUT: return GENODE_ETIMEDOUT;
case ETOOMANYREFS: return GENODE_ETOOMANYREFS;
case EUSERS: return GENODE_EUSERS;
case EXDEV: return GENODE_EXDEV;
default:
printk("%s:%d unsupported errno %d\n",
__func__, __LINE__, errno);
}
return GENODE_EINVAL;
}
/* index must match with socket.h Genode 'Sock_opt' */
static int sock_opts[] = {
0,
SO_DEBUG,
SO_ACCEPTCONN,
SO_DONTROUTE,
SO_LINGER,
SO_OOBINLINE,
SO_REUSEPORT,
SO_SNDBUF,
SO_RCVBUF,
SO_SNDLOWAT,
SO_RCVLOWAT,
SO_SNDTIMEO_NEW,
SO_RCVTIMEO_NEW,
SO_ERROR,
SO_TYPE,
SO_BINDTODEVICE,
SO_BROADCAST,
};
static int _linux_sockopt(enum Sock_opt sockopt)
{
return sock_opts[sockopt];
}
static struct sockaddr _sockaddr(struct genode_sockaddr const *addr)
{
struct sockaddr sock_addr = { };
if (addr->family == AF_UNSPEC) {
sock_addr.sa_family = AF_UNSPEC;
}
else if (addr->family == AF_INET) {
struct sockaddr_in in_addr = {
.sin_family = AF_INET,
.sin_port = addr->in.port,
.sin_addr.s_addr = addr->in.addr
};
memcpy(&sock_addr, &in_addr, sizeof(in_addr));
} else {
printk("%s:%d error: family %d not implemented\n", __func__, __LINE__,
addr->family);
}
return sock_addr;
}
static void _genode_sockaddr(struct genode_sockaddr *addr,
struct sockaddr const *linux_addr,
int length)
{
if (length == sizeof(struct sockaddr_in)) {
struct sockaddr_in const * in = (struct sockaddr_in const *)linux_addr;
addr->family = in->sin_family;
addr->in.port = in->sin_port;
addr->in.addr = in->sin_addr.s_addr;
} else
printk("%s:%d: unknown sockaddr length %d\n", __func__, __LINE__, length);
}
static int _sockaddr_len(struct genode_sockaddr const *addr)
{
if (addr->family == AF_INET)
return sizeof(struct sockaddr_in);
printk("error: _sockaddr_len unknown family: %u\n", addr->family);
return 0;
}
struct socket *lx_sock_alloc(void) { return sock_alloc(); }
void lx_sock_release(struct socket* sock) { sock_release(sock); }
extern int __setup_ip_auto_config_setup(char *);
void lx_socket_address(struct genode_socket_config *config)
{
if (config->dhcp) {
__setup_ip_auto_config_setup("dhcp");
}
else {
char address_config[128];
snprintf(address_config, sizeof(address_config),
"%s::%s:%s:::off:%s",
config->ip_addr, config->gateway, config->netmask,
config->nameserver);
__setup_ip_auto_config_setup(address_config);
}
lx_emul_initcall("__initcall_ip_auto_config7");
};
void lx_socket_mtu(unsigned mtu)
{
/* zero mtu means reset to default */
unsigned new_mtu = mtu ? mtu : ETH_DATA_LEN;
struct net *net;
struct net_device *dev;
for_each_net(net) {
for_each_netdev(net, dev) {
dev_set_mtu(dev, new_mtu);
}
}
}
enum Errno lx_socket_create(int domain, int type, int protocol,
struct socket **res)
{
int err = sock_create_kern(&init_net, domain, type, protocol, res);
if (err) return _genode_errno(err);
init_waitqueue_head(&(*res)->wq.wait);
return GENODE_ENONE;
}
enum Errno lx_socket_bind(struct socket *sock, struct genode_sockaddr const *addr)
{
struct sockaddr sock_addr = _sockaddr(addr);
return _genode_errno(sock->ops->bind(sock, &sock_addr, _sockaddr_len(addr)));
}
enum Errno lx_socket_listen(struct socket *sock, int length)
{
return _genode_errno(sock->ops->listen(sock, length));
}
enum Errno lx_socket_accept(struct socket *sock, struct socket *new_sock,
struct genode_sockaddr *addr)
{
struct sockaddr linux_addr;
int err;
new_sock->type = sock->type;
new_sock->ops = sock->ops;
err = sock->ops->accept(sock, new_sock, O_NONBLOCK, true);
if (err == 0) {
err = sock->ops->getname(new_sock, &linux_addr, 0);
if (err > 0) _genode_sockaddr(addr, &linux_addr, err);
}
return err < 0 ? _genode_errno(err) : GENODE_ENONE;
}
enum Errno lx_socket_connect(struct socket *sock, struct genode_sockaddr const *addr)
{
struct sockaddr sock_addr = _sockaddr(addr);
return _genode_errno(sock->ops->connect(sock, &sock_addr, _sockaddr_len(addr),
O_NONBLOCK));
}
unsigned lx_socket_pollin_set(void)
{
return (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR);
}
unsigned lx_socket_pollout_set(void)
{
return (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR);
}
unsigned lx_socket_pollex_set(void)
{
return POLLPRI;
}
unsigned lx_socket_poll(struct socket *sock)
{
struct file file = { };
return sock->ops->poll(&file, sock, NULL);
}
enum Errno lx_socket_getsockopt(struct socket *sock, enum Sock_level level,
enum Sock_opt opt, void *optval, unsigned *optlen)
{
int name = _linux_sockopt(opt);
enum Errno errno;
int err;
if (level != GENODE_SOL_SOCKET) return GENODE_ENOPROTOOPT;
if (opt == GENODE_SO_ERROR && *optlen < sizeof(enum Sock_opt))
return GENODE_EFAULT;
if (level == GENODE_SOL_SOCKET)
err = sock_getsockopt(sock, SOL_SOCKET, name, optval, optlen);
/* we might need this later
else {
err = sock->ops->getsockopt(sock, SOL_SOCKET, name, optval, optlen);
}
*/
if (err) return _genode_errno(err);
if (opt == GENODE_SO_ERROR) {
err = *((int *)optval);
errno = _genode_errno(err);
memcpy(optval, &errno, sizeof(enum Sock_opt));
}
return GENODE_ENONE;
}
enum Errno lx_socket_setsockopt(struct socket *sock, enum Sock_level level,
enum Sock_opt opt, void const *optval, unsigned optlen)
{
int name = _linux_sockopt(opt);
int err;
if (level != GENODE_SOL_SOCKET) return GENODE_ENOPROTOOPT;
if (level == GENODE_SOL_SOCKET) {
sockptr_t val = { .user = optval, .is_kernel = 0 };
err = sock_setsockopt(sock, SOL_SOCKET, name, val, optlen);
}
/* we might need this later
else {
err = sock->ops->getsockopt(sock, SOL_SOCKET, name, optval, optlen);
}
*/
if (err) return _genode_errno(err);
return GENODE_ENONE;
}
enum Errno lx_socket_getname(struct socket *sock, struct genode_sockaddr *addr, bool peer)
{
struct sockaddr linux_addr;
int err = sock->ops->getname(sock, &linux_addr, peer ? 1 : 0);
if (err < 0) return _genode_errno(err);
_genode_sockaddr(addr, &linux_addr, err);
return GENODE_ENONE;
}
static struct msghdr *_create_msghdr(struct genode_msghdr *msg, bool write)
{
struct msghdr *msghdr;
struct sockaddr_storage *storage = NULL;
unsigned long total = 0;
msghdr = (struct msghdr *)kzalloc(sizeof(*msghdr), GFP_KERNEL);
if (!msghdr) goto msghdr;
/* sockaddr */
if (msg->name) {
struct sockaddr sock_addr = _sockaddr(msg->name);
storage = (struct sockaddr_storage *)kmalloc(sizeof(*storage), GFP_KERNEL);
if (!storage) goto sock_addr;
memcpy(storage, &sock_addr, _sockaddr_len(msg->name));
msghdr->msg_name = storage;
msghdr->msg_namelen = _sockaddr_len(msg->name);
}
/* iovec iterator */
msghdr->msg_iter.iter_type = ITER_IOVEC;
msghdr->msg_iter.data_source = write;
msghdr->msg_iter.nr_segs = msg->iovlen;
msghdr->msg_iter.iov = (struct iovec *)msg->iov;
for (unsigned i = 0; i < msg->iovlen; i++)
total += msg->iov[i].size;
msghdr->msg_iter.count = total;
/* non-blocking */
msghdr->msg_flags = MSG_DONTWAIT;
return msghdr;
sock_addr:
kfree(msghdr);
msghdr:
return NULL;
}
static void _destroy_msghdr(struct msghdr *msg)
{
if (msg->msg_name) kfree(msg->msg_name);
kfree(msg);
}
enum Errno lx_socket_sendmsg(struct socket *sock, struct genode_msghdr *msg,
unsigned long *bytes_send)
{
struct msghdr *m = _create_msghdr(msg, false);
int ret;
if (!m) return GENODE_ENOMEM;
ret = sock->ops->sendmsg(sock, m, m->msg_iter.count);
_destroy_msghdr(m);
if (ret < 0)
return _genode_errno(ret);
*bytes_send = (unsigned long)ret;
return GENODE_ENONE;
}
enum Errno lx_socket_recvmsg(struct socket *sock, struct genode_msghdr *msg,
unsigned long *bytes_recv, bool peek)
{
struct msghdr *m = _create_msghdr(msg, true);
int ret;
int flags = MSG_DONTWAIT;
if (peek) flags |= MSG_PEEK;
if (!m) return GENODE_ENOMEM;
ret = sock->ops->recvmsg(sock, m, m->msg_iter.count, flags);
/* convert to genode_sockaddr */
if (ret && msg->name) {
_genode_sockaddr(msg->name, m->msg_name, _sockaddr_len(msg->name));
}
_destroy_msghdr(m);
if (ret < 0)
return _genode_errno(ret);
*bytes_recv = (unsigned long)ret;
return GENODE_ENONE;
}
enum Errno lx_socket_shutdown(struct socket *sock, int how)
{
return _genode_errno(sock->ops->shutdown(sock, how));
}
enum Errno lx_socket_release(struct socket *sock)
{
return _genode_errno(sock->ops->release(sock));
}

View File

@ -0,0 +1,57 @@
/*
* \brief C-interface to Linux socked kernel code
* \author Sebastian Sumpf
* \date 2024-01-29
*
* Can only be called by lx_lit tasks
*/
/*
* Copyright (C) 2024 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <genode_c_api/socket.h>
#ifdef __cplusplus
extern "C" {
#endif
struct socket *lx_sock_alloc(void);
void lx_sock_release(struct socket* sock);
void lx_socket_address(struct genode_socket_config *config);
void lx_socket_mtu(unsigned mtu);
enum Errno lx_socket_create(int domain, int type, int protocol, struct socket **res);
enum Errno lx_socket_bind(struct socket *sock, struct genode_sockaddr const *addr);
enum Errno lx_socket_listen(struct socket *sock, int length);
enum Errno lx_socket_accept(struct socket *sock, struct socket *new_sock,
struct genode_sockaddr *addr);
enum Errno lx_socket_connect(struct socket *sock, struct genode_sockaddr const *addr);
unsigned lx_socket_pollin_set(void);
unsigned lx_socket_pollout_set(void);
unsigned lx_socket_pollex_set(void);
unsigned lx_socket_poll(struct socket *sock);
enum Errno lx_socket_getsockopt(struct socket *sock, enum Sock_level level,
enum Sock_opt opt, void *optval, unsigned *optlen);
enum Errno lx_socket_setsockopt(struct socket *sock, enum Sock_level level,
enum Sock_opt opt, void const *optval, unsigned optlen);
enum Errno lx_socket_getname(struct socket *sock, struct genode_sockaddr *addr, bool peer);
enum Errno lx_socket_sendmsg(struct socket *sock, struct genode_msghdr *msg,
unsigned long *bytes_send);
enum Errno lx_socket_recvmsg(struct socket *sock, struct genode_msghdr *msg,
unsigned long *bytes_recv, bool peek);
enum Errno lx_socket_shutdown(struct socket *sock, int how);
enum Errno lx_socket_release(struct socket *sock);
#ifdef __cplusplus
} /* extern "C" */
#endif

View File

@ -0,0 +1,67 @@
/*
* \brief Post kernel activity
* \author Sebastian Sumpf
* \date 2024-01-29
*/
/*
* Copyright (C) 2024 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <linux/sched/task.h>
#include <linux/init.h>
#include "lx_user.h"
struct task_struct *lx_user_new_task(int (*func)(void*), void *args)
{
int pid = kernel_thread(func, args, CLONE_FS | CLONE_FILES);
return find_task_by_pid_ns(pid, NULL);
}
void lx_user_destroy_task(struct task_struct *task)
{
if (task != current) {
printk("%s: task: %px is not current: %px\n", __func__,
task, current);
return;
}
do_exit(0);
}
static int _startup_finished = 0;
int lx_user_startup_complete(void *) { return _startup_finished; }
static struct task_struct *_socket_dispatch_root = NULL;
struct task_struct *lx_socket_dispatch_root(void)
{
return _socket_dispatch_root;
}
int __setup_set_thash_entries(char const *str);
int __setup_set_uhash_entries(char const *str);
void lx_user_configure_ip_stack(void)
{
__setup_set_thash_entries("2048");
__setup_set_uhash_entries("2048");
}
void lx_user_init(void)
{
_socket_dispatch_root = lx_user_new_task(lx_socket_dispatch,
lx_socket_dispatch_queue());
_startup_finished = 1;
}

View File

@ -0,0 +1,34 @@
/*
* \brief Post kernel activity
* \author Sebastian Sumpf
* \date 2024-01-29
*/
/*
* Copyright (C) 2024 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#ifdef __cplusplus
extern "C" {
#endif
struct task_struct;
/* set kernel parameters for Genode */
void lx_user_configure_ip_stack(void);
int lx_user_startup_complete(void *);
void *lx_socket_dispatch_queue(void);
int lx_socket_dispatch(void *arg);
struct task_struct *lx_socket_dispatch_root(void);
struct task_struct *lx_user_new_task(int (*func)(void*), void *args);
void lx_user_destroy_task(struct task_struct *task);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,215 @@
/**
* \brief Nic client that transfers packets from/to IP stack to/from nic client
* C-API
* \author Sebastian Sumpf
* \date 2024-01-29
*/
/*
* Copyright (C) 2024 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <genode_c_api/nic_client.h>
static struct genode_nic_client *dev_nic_client(struct net_device *dev)
{
return (struct genode_nic_client *)dev->ifalias;
}
static int net_open(struct net_device *dev)
{
return 0;
}
struct genode_nic_client_tx_packet_context
{
struct sk_buff *skb;
};
static unsigned long nic_tx_packet_content(struct genode_nic_client_tx_packet_context *ctx,
char *dst, unsigned long dst_len)
{
struct sk_buff * const skb = ctx->skb;
if (dst_len < skb->len) {
printk("nic_tx_packet_content: packet exceeds uplink packet size\n");
memset(dst, 0, dst_len);
return 0;
}
skb_copy_from_linear_data(skb, dst, skb->len);
/* clear unused part of the destination buffer */
memset(dst + skb->len, 0, dst_len - skb->len);
return skb->len;
}
static int driver_net_xmit(struct sk_buff *skb, struct net_device *dev)
{
bool progress = false;
struct net_device_stats *stats = (struct net_device_stats*) netdev_priv(dev);
struct genode_nic_client *nic_client = dev_nic_client(dev);
struct genode_nic_client_tx_packet_context ctx = { .skb = skb };
if (!nic_client) return NETDEV_TX_BUSY;
progress = genode_nic_client_tx_packet(nic_client, nic_tx_packet_content, &ctx);
/* transmit to nic-session */
if (!progress) {
/* tx queue is full, could not enqueue packet */
return NETDEV_TX_BUSY;
}
dev_kfree_skb(skb);
/* save timestamp */
netif_trans_update(dev);
stats->tx_packets++;
stats->tx_bytes += skb->len;
genode_nic_client_notify_peers();
return NETDEV_TX_OK;
}
static const struct net_device_ops net_ops =
{
.ndo_open = net_open,
.ndo_start_xmit = driver_net_xmit,
};
static struct task_struct *nic_rx_task_struct_ptr;
struct genode_nic_client_rx_context
{
struct net_device *dev;
};
struct task_struct *lx_nic_client_rx_task(void)
{
return nic_rx_task_struct_ptr;
}
static genode_nic_client_rx_result_t nic_rx_one_packet(struct genode_nic_client_rx_context *ctx,
char const *ptr, unsigned long len)
{
enum {
ADDITIONAL_HEADROOM = 4, /* smallest value found by trial & error */
};
struct sk_buff *skb = netdev_alloc_skb_ip_align(ctx->dev, len + ADDITIONAL_HEADROOM);
struct net_device_stats *stats = netdev_priv(ctx->dev);
if (!skb) {
printk("alloc_skb failed\n");
return GENODE_NIC_CLIENT_RX_RETRY;
}
skb_copy_to_linear_data(skb, ptr, len);
skb_put(skb, len);
skb->dev = ctx->dev;
skb->protocol = eth_type_trans(skb, ctx->dev);
skb->ip_summed = CHECKSUM_NONE;
netif_receive_skb(skb);
stats->rx_packets++;
stats->rx_bytes += len;
return GENODE_NIC_CLIENT_RX_ACCEPTED;
}
static int rx_task_function(void *arg)
{
struct net_device *dev = arg;
struct genode_nic_client *nic_client = dev_nic_client(dev);
struct genode_nic_client_rx_context ctx = { .dev = dev };
while (true) {
bool progress = false;
lx_emul_task_schedule(true);
while (genode_nic_client_rx(nic_client,
nic_rx_one_packet,
&ctx)) {
progress = true; }
if (progress) genode_nic_client_notify_peers();
}
return 0;
}
static int __init virtio_net_driver_init(void)
{
struct net_device *dev;
int err = -ENODEV;
struct genode_mac_address mac;
pid_t pid;
dev = alloc_etherdev(0);
if (!(dev = alloc_etherdev(0)))
goto out;
dev->netdev_ops = &net_ops;
dev->ifalias = (struct dev_ifalias *)genode_nic_client_create("");
if (!dev->ifalias) {
printk("Failed to create nic client\n");
goto out_free;
}
/* set MAC */
mac = genode_nic_client_mac_address(dev_nic_client(dev));
dev_addr_set(dev, mac.addr);
if ((err = register_netdev(dev))) {
printk("Could not register net device driver %d\n", err);
goto out_nic;
}
/* create RX task */
pid = kernel_thread(rx_task_function, dev, CLONE_FS | CLONE_FILES);
nic_rx_task_struct_ptr = find_task_by_pid_ns(pid, NULL);
return 0;
out_nic:
genode_nic_client_destroy(dev_nic_client(dev));
out_free:
free_netdev(dev);
out:
return err;
}
/**
* Let's hook into the virtio_net_driver initcall, so we do not need to register
* an additional one
*/
module_init(virtio_net_driver_init);

View File

@ -0,0 +1,27 @@
/**
* \brief Nic client that transfers packets from/to IP stack to/from nic client
* C-API
* \author Sebastian Sumpf
* \date 2024-01-29
*/
/*
* Copyright (C) 2024 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#ifndef _NET_DRIVER_H_
#define _NET_DRIVER_H_
#ifdef __cplusplus
extern "C" {
#endif
struct task_struct;
struct task_struct *lx_nic_client_rx_task(void);
#ifdef __cplusplus
}
#endif
#endif /* _NET_DRIVER_H_ */

View File

@ -0,0 +1,30 @@
/*
* \brief This file shadows linux/init.h
* \author Sebastian Sumpf
* \date 2024-01-29
*/
/*
* Copyright (C) 2024 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#ifndef _SHADOW__LINUX__INIT_H_
#define _SHADOW__LINUX__INIT_H_
/* include the next linux/init.h found in include paths */
#include_next <linux/init.h>
#undef __setup
/*
* '__setup' calls are currently only used by lxip, keep ti local in order to
* avoid problems with other projects
*/
#define __setup(str, fn) \
int __setup_##fn(char * string) { return fn(string); }
#endif

View File

@ -0,0 +1,32 @@
/*
* \brief This file shadows linux/utsname.h
* \author Sebastian Sumpf
* \date 2024-01-29
*/
/*
* Copyright (C) 2024 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#ifndef _SHADOW__LINUX__UTSNAME_H_
#define _SHADOW__LINUX__UTSNAME_H_
#include <uapi/linux/utsname.h>
extern struct new_utsname init_uts_ns;
static inline struct new_utsname *init_utsname(void)
{
return &init_uts_ns;
}
static inline struct new_utsname *utsname(void)
{
return init_utsname();
}
#endif /* _SHADOW__LINUX__UTSNAME_H_ */

View File

@ -0,0 +1,641 @@
/*
* \brief Implementation of Genode's socket C-API for lxip
* \author Sebastian Sumpf
* \date 2024-01-29
*
* The functions here can only be called from native Genode EPs, the socket
* calls will switch from the EP to DDE Linux task and call Linux kernel C-code.
*
* All calls except 'genode_socket_config_address' are non-blocking.
*/
/*
* Copyright (C) 2024 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <base/log.h>
#include <util/fifo.h>
#include <lx_kit/env.h>
#include <lx_emul/task.h>
#include "lx_socket.h"
#include "lx_user.h"
using namespace Genode;
struct Lx_call;
typedef Fifo<Lx_call> Socket_queue;
struct genode_socket_handle
{
struct socket *sock { nullptr };
struct task_struct *task { nullptr };
Socket_queue *queue { };
};
void genode_socket_wait_for_progress()
{
Lx_kit::env().env.ep().wait_and_dispatch_one_io_signal();
Lx_kit::env().scheduler.execute();
}
/*
* Wakeup Linux task and call C-code
*/
struct Lx_call : private Socket_queue::Element
{
friend class Fifo<Lx_call>;
genode_socket_handle &handle;
enum Errno err { GENODE_ENONE };
bool finished { false };
bool may_block { false };
Lx_call(genode_socket_handle &handle)
: handle(handle) { }
virtual ~Lx_call() { }
/* called from ep */
void schedule()
{
handle.queue->enqueue(*this);
lx_emul_task_unblock(handle.task);
Lx_kit::env().scheduler.execute();
while (!finished) {
if (may_block == false)
warning("socket interface call blocked (this should not happen)");
genode_socket_wait_for_progress();
}
}
virtual void execute() = 0;
};
struct Lx_address : Lx_call
{
genode_socket_config *config;
Lx_address(genode_socket_handle &handle,
genode_socket_config *config)
: Lx_call(handle), config(config)
{
/* we allow this call to block */
may_block = true;
schedule();
}
void execute() override
{
lx_socket_address(config);
finished = true;
}
Lx_address(const Lx_address&) = delete;
Lx_address operator=(const Lx_address&) = delete;
};
struct Lx_mtu : Lx_call
{
unsigned mtu;
Lx_mtu(genode_socket_handle &handle, unsigned mtu)
: Lx_call(handle), mtu(mtu)
{
schedule();
}
void execute() override
{
lx_socket_mtu(mtu);
finished = true;
}
};
struct Lx_socket : Lx_call
{
int domain, type, protocol;
Lx_socket(genode_socket_handle &handle, int domain, int type, int protocol)
: Lx_call(handle), domain(domain), type(type), protocol(protocol)
{
schedule();
}
/* called from root dispatch task */
void execute() override
{
err = lx_socket_create(domain, type, protocol, &handle.sock);
finished = true;
}
};
struct Lx_bind : Lx_call
{
genode_sockaddr const &addr;
Lx_bind(genode_socket_handle &handle, genode_sockaddr const &addr)
: Lx_call(handle), addr(addr)
{
schedule();
}
void execute() override
{
err = lx_socket_bind(handle.sock, &addr);
finished = true;
}
};
struct Lx_listen : Lx_call
{
int length;
Lx_listen(genode_socket_handle &handle, int length)
: Lx_call(handle), length(length)
{
schedule();
}
void execute() override
{
err = lx_socket_listen(handle.sock, length);
finished = true;
}
};
struct Lx_accept : Lx_call
{
genode_socket_handle &client;
genode_sockaddr addr { };
Lx_accept(genode_socket_handle &handle,
genode_socket_handle &client)
: Lx_call(handle), client(client)
{
schedule();
}
void execute() override
{
client.sock = lx_sock_alloc();
if (!client.sock) {
err = GENODE_ENOMEM;
finished = true;
return;
}
err = lx_socket_accept(handle.sock, client.sock, &addr);
if (err)
lx_sock_release(client.sock);
finished = true;
}
};
struct Lx_connect : Lx_call
{
genode_sockaddr &addr;
Lx_connect(genode_socket_handle &handle,
genode_sockaddr &addr)
: Lx_call(handle), addr(addr)
{
schedule();
}
void execute() override
{
err = lx_socket_connect(handle.sock, &addr);
finished = true;
}
};
struct Lx_poll : Lx_call
{
unsigned result = 0;
Lx_poll(genode_socket_handle &handle)
: Lx_call(handle)
{
schedule();
}
void execute() override
{
result = lx_socket_poll(handle.sock);
finished = true;
}
};
struct Lx_getsockopt : Lx_call
{
enum Sock_level level;
enum Sock_opt opt;
void *optval;
unsigned *optlen;
Lx_getsockopt(genode_socket_handle &handle,
enum Sock_level level,
enum Sock_opt opt,
void *optval, unsigned *optlen)
: Lx_call(handle), level(level), opt(opt), optval(optval), optlen(optlen)
{
schedule();
}
void execute() override
{
err = lx_socket_getsockopt(handle.sock, level, opt, optval, optlen);
finished = true;
}
Lx_getsockopt(const Lx_getsockopt&) = delete;
Lx_getsockopt operator=(const Lx_getsockopt&) = delete;
};
struct Lx_setsockopt : Lx_call
{
enum Sock_level level;
enum Sock_opt opt;
void const *optval;
unsigned optlen;
Lx_setsockopt(genode_socket_handle &handle,
enum Sock_level level,
enum Sock_opt opt,
void const *optval, unsigned optlen)
: Lx_call(handle), level(level), opt(opt), optval(optval), optlen(optlen)
{
schedule();
}
void execute() override
{
err = lx_socket_setsockopt(handle.sock, level, opt, optval, optlen);
finished = true;
}
Lx_setsockopt(const Lx_setsockopt&) = delete;
Lx_setsockopt operator=(const Lx_setsockopt&) = delete;
};
struct Lx_getname : Lx_call
{
genode_sockaddr &addr;
bool peer;
Lx_getname(genode_socket_handle &handle, genode_sockaddr &addr, bool peer)
: Lx_call(handle), addr(addr), peer(peer)
{
schedule();
}
void execute() override
{
err = lx_socket_getname(handle.sock, &addr, peer);
finished = true;
}
};
struct Lx_sendmsg : Lx_call
{
genode_msghdr &msg;
unsigned long bytes { 0 };
Lx_sendmsg(genode_socket_handle &handle,
genode_msghdr &msg)
: Lx_call(handle), msg(msg)
{
schedule();
}
void execute() override
{
err = lx_socket_sendmsg(handle.sock, &msg, &bytes);
finished = true;
}
};
struct Lx_recvmsg : Lx_call
{
genode_msghdr &msg;
unsigned long bytes { 0 };
bool peek;
Lx_recvmsg(genode_socket_handle &handle,
genode_msghdr &msg, bool peek)
: Lx_call(handle), msg(msg), peek(peek)
{
schedule();
}
void execute() override
{
err = lx_socket_recvmsg(handle.sock, &msg, &bytes, peek);
finished = true;
}
};
struct Lx_shutdown : Lx_call
{
int how;
Lx_shutdown(genode_socket_handle &handle,
int how)
: Lx_call(handle), how(how)
{
schedule();
}
void execute() override
{
err = lx_socket_shutdown(handle.sock, how);
finished = true;
}
};
struct Lx_release : Lx_call
{
Lx_release(genode_socket_handle &handle) : Lx_call(handle)
{
schedule();
}
void execute() override
{
err = lx_socket_release(handle.sock);
finished = true;
}
};
/*
* Dispatch socket calls in Linux task
*/
void *lx_socket_dispatch_queue(void)
{
static Socket_queue queue;
return &queue;
}
int lx_socket_dispatch(void *arg)
{
Socket_queue &queue = *static_cast<Socket_queue *>(arg);
while (true) {
if (queue.empty())
lx_emul_task_schedule(true);
queue.dequeue([] (Lx_call &call) { call.execute(); });
}
}
/*
* Socket C-API
*/
static genode_socket_handle * _create_handle()
{
genode_socket_handle *handle = new (Lx_kit::env().heap) genode_socket_handle();
handle->task = lx_socket_dispatch_root();
handle->queue = static_cast<Socket_queue *>(lx_socket_dispatch_queue());
handle->sock = nullptr;
return handle;
}
static void _destroy_handle(genode_socket_handle *handle)
{
if (handle->sock) lx_sock_release(handle->sock);
destroy(Lx_kit::env().heap, handle);
}
/*
* Genode socket C-API
*/
void genode_socket_config_address(struct genode_socket_config *config)
{
genode_socket_handle handle = {
.task = lx_socket_dispatch_root(),
.queue = static_cast<Socket_queue *>(lx_socket_dispatch_queue()),
};
Lx_address addr { handle, config };
}
void genode_socket_configure_mtu(unsigned mtu)
{
genode_socket_handle handle = {
.task = lx_socket_dispatch_root(),
.queue = static_cast<Socket_queue *>(lx_socket_dispatch_queue()),
};
Lx_mtu addr { handle, mtu };
}
genode_socket_handle *
genode_socket(int domain, int type, int protocol, enum Errno *errno)
{
genode_socket_handle *handle = _create_handle();
if (!handle) {
*errno = GENODE_ENOMEM;
return nullptr;
}
Lx_socket socket { *handle, domain, type, protocol };
*errno = socket.err;
return handle;
}
enum Errno genode_socket_bind(struct genode_socket_handle *handle,
struct genode_sockaddr const *addr)
{
Lx_bind bind { *handle, *addr };
return bind.err;
}
enum Errno genode_socket_listen(struct genode_socket_handle *handle,
int backlog)
{
Lx_listen listen { *handle, backlog };
return listen.err;
}
genode_socket_handle *
genode_socket_accept(struct genode_socket_handle *handle,
struct genode_sockaddr *addr,
enum Errno *errno)
{
genode_socket_handle *client = _create_handle();
if (!handle) {
*errno = GENODE_ENOMEM;
return nullptr;
}
Lx_accept accept { *handle, *client };
*errno = accept.err;
if (*errno) {
_destroy_handle(client);
return nullptr;
}
if (addr)
*addr = accept.addr;
return client;
}
enum Errno genode_socket_connect(struct genode_socket_handle *handle,
struct genode_sockaddr *addr)
{
Lx_connect connect { *handle, *addr };
return connect.err;
}
unsigned genode_socket_pollin_set(void)
{
return lx_socket_pollin_set();
}
unsigned genode_socket_pollout_set(void)
{
return lx_socket_pollout_set();
}
unsigned genode_socket_pollex_set(void)
{
return lx_socket_pollex_set();
}
unsigned genode_socket_poll(struct genode_socket_handle *handle)
{
Lx_poll poll { *handle };
return poll.result;
}
enum Errno genode_socket_getsockopt(struct genode_socket_handle *handle,
enum Sock_level level, enum Sock_opt opt,
void *optval, unsigned *optlen)
{
Lx_getsockopt sock_opt { *handle, level, opt, optval, optlen };
return sock_opt.err;
}
enum Errno genode_socket_setsockopt(struct genode_socket_handle *handle,
enum Sock_level level, enum Sock_opt opt,
void const *optval,
unsigned optlen)
{
Lx_setsockopt sock_opt { *handle, level, opt, optval, optlen };
return sock_opt.err;
}
enum Errno genode_socket_getsockname(struct genode_socket_handle *handle,
struct genode_sockaddr *addr)
{
Lx_getname name { *handle, *addr, false };
return name.err;
}
enum Errno genode_socket_getpeername(struct genode_socket_handle *handle,
struct genode_sockaddr *addr)
{
Lx_getname name { *handle, *addr, true };
return name.err;
}
enum Errno genode_socket_sendmsg(struct genode_socket_handle *handle,
struct genode_msghdr *msg,
unsigned long *bytes_send)
{
Lx_sendmsg send { *handle, *msg };
*bytes_send = send.bytes;
return send.err;
}
enum Errno genode_socket_recvmsg(struct genode_socket_handle *handle,
struct genode_msghdr *msg,
unsigned long *bytes_recv,
bool peek)
{
Lx_recvmsg recv { *handle, *msg, peek };
*bytes_recv = recv.bytes;
return recv.err;
}
enum Errno genode_socket_shutdown(struct genode_socket_handle *handle,
int how)
{
Lx_shutdown shutdown { *handle, how };
return shutdown.err;
}
enum Errno genode_socket_release(struct genode_socket_handle *handle)
{
Lx_release release { *handle };
handle->sock = nullptr;
_destroy_handle(handle);
return release.err;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,158 @@
arch/arm/lib/clearbit.S
arch/arm/lib/csumipv6.S
arch/arm/lib/csumpartial.S
arch/arm/lib/csumpartialcopy.S
arch/arm/lib/div64.S
arch/arm/lib/findbit.S
arch/arm/lib/memchr.S
arch/arm/lib/setbit.S
arch/arm/lib/strchr.S
arch/arm/lib/testclearbit.S
arch/arm/lib/testsetbit.S
drivers/base/class.c
drivers/net/loopback.c
fs/nls/nls_base.c
kernel/kthread.c
kernel/locking/mutex.c
kernel/locking/osq_lock.c
kernel/locking/rwsem.c
kernel/notifier.c
kernel/sched/build_utility.c
kernel/smpboot.c
kernel/softirq.c
kernel/time/clockevents.c
kernel/time/clocksource.c
kernel/time/hrtimer.c
kernel/time/jiffies.c
kernel/time/ntp.c
kernel/time/tick-broadcast-hrtimer.c
kernel/time/tick-broadcast.c
kernel/time/tick-common.c
kernel/time/tick-oneshot.c
kernel/time/tick-sched.c
kernel/time/time.c
kernel/time/timeconv.c
kernel/time/timecounter.c
kernel/time/timekeeping.c
kernel/time/timer.c
kernel/time/timer_list.c
kernel/workqueue.c
lib/bitmap.c
lib/ctype.c
lib/find_bit.c
lib/hexdump.c
lib/hweight.c
lib/idr.c
lib/iov_iter.c
lib/kasprintf.c
lib/klist.c
lib/kobject.c
lib/kstrtox.c
lib/math/div64.c
lib/nlattr.c
lib/once.c
lib/percpu_counter.c
lib/radix-tree.c
lib/rbtree.c
lib/rhashtable.c
lib/siphash.c
lib/string.c
lib/string_helpers.c
lib/timerqueue.c
lib/vsprintf.c
lib/win_minmax.c
lib/xarray.c
mm/util.c
net/core/datagram.c
net/core/dev.c
net/core/dev_addr_lists.c
net/core/dev_ioctl.c
net/core/dst.c
net/core/dst_cache.c
net/core/failover.c
net/core/fib_notifier.c
net/core/filter.c
net/core/flow_dissector.c
net/core/flow_offload.c
net/core/gen_estimator.c
net/core/gen_stats.c
net/core/gro.c
net/core/gro_cells.c
net/core/link_watch.c
net/core/neighbour.c
net/core/net_namespace.c
net/core/netevent.c
net/core/request_sock.c
net/core/rtnetlink.c
net/core/scm.c
net/core/secure_seq.c
net/core/selftests.c
net/core/skbuff.c
net/core/sock.c
net/core/sock_diag.c
net/core/sock_reuseport.c
net/core/stream.c
net/core/tso.c
net/core/utils.c
net/core/xdp.c
net/ethernet/eth.c
net/ipv4/af_inet.c
net/ipv4/arp.c
net/ipv4/datagram.c
net/ipv4/devinet.c
net/ipv4/fib_frontend.c
net/ipv4/fib_notifier.c
net/ipv4/fib_semantics.c
net/ipv4/fib_trie.c
net/ipv4/gre_offload.c
net/ipv4/icmp.c
net/ipv4/igmp.c
net/ipv4/inet_connection_sock.c
net/ipv4/inet_diag.c
net/ipv4/inet_fragment.c
net/ipv4/inet_hashtables.c
net/ipv4/inet_timewait_sock.c
net/ipv4/inetpeer.c
net/ipv4/ip_forward.c
net/ipv4/ip_fragment.c
net/ipv4/ip_input.c
net/ipv4/ip_options.c
net/ipv4/ip_output.c
net/ipv4/ip_sockglue.c
net/ipv4/ip_tunnel.c
net/ipv4/ip_tunnel_core.c
net/ipv4/ipconfig.c
net/ipv4/metrics.c
net/ipv4/netlink.c
net/ipv4/nexthop.c
net/ipv4/ping.c
net/ipv4/protocol.c
net/ipv4/raw.c
net/ipv4/route.c
net/ipv4/tcp.c
net/ipv4/tcp_cong.c
net/ipv4/tcp_cubic.c
net/ipv4/tcp_diag.c
net/ipv4/tcp_fastopen.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_metrics.c
net/ipv4/tcp_minisocks.c
net/ipv4/tcp_offload.c
net/ipv4/tcp_output.c
net/ipv4/tcp_rate.c
net/ipv4/tcp_recovery.c
net/ipv4/tcp_timer.c
net/ipv4/tcp_ulp.c
net/ipv4/udp.c
net/ipv4/udp_offload.c
net/ipv4/udp_tunnel_core.c
net/ipv4/udp_tunnel_nic.c
net/ipv4/udp_tunnel_stub.c
net/ipv4/udplite.c
net/netlink/af_netlink.c
net/netlink/genetlink.c
net/netlink/policy.c
net/sched/sch_frag.c
net/sched/sch_generic.c
net/sched/sch_mq.c

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,158 @@
arch/arm/lib/clearbit.S
arch/arm/lib/csumipv6.S
arch/arm/lib/csumpartial.S
arch/arm/lib/csumpartialcopy.S
arch/arm/lib/div64.S
arch/arm/lib/findbit.S
arch/arm/lib/memchr.S
arch/arm/lib/setbit.S
arch/arm/lib/strchr.S
arch/arm/lib/testclearbit.S
arch/arm/lib/testsetbit.S
drivers/base/class.c
drivers/net/loopback.c
fs/nls/nls_base.c
kernel/kthread.c
kernel/locking/mutex.c
kernel/locking/osq_lock.c
kernel/locking/rwsem.c
kernel/notifier.c
kernel/sched/build_utility.c
kernel/smpboot.c
kernel/softirq.c
kernel/time/clockevents.c
kernel/time/clocksource.c
kernel/time/hrtimer.c
kernel/time/jiffies.c
kernel/time/ntp.c
kernel/time/tick-broadcast-hrtimer.c
kernel/time/tick-broadcast.c
kernel/time/tick-common.c
kernel/time/tick-oneshot.c
kernel/time/tick-sched.c
kernel/time/time.c
kernel/time/timeconv.c
kernel/time/timecounter.c
kernel/time/timekeeping.c
kernel/time/timer.c
kernel/time/timer_list.c
kernel/workqueue.c
lib/bitmap.c
lib/ctype.c
lib/find_bit.c
lib/hexdump.c
lib/hweight.c
lib/idr.c
lib/iov_iter.c
lib/kasprintf.c
lib/klist.c
lib/kobject.c
lib/kstrtox.c
lib/math/div64.c
lib/nlattr.c
lib/once.c
lib/percpu_counter.c
lib/radix-tree.c
lib/rbtree.c
lib/rhashtable.c
lib/siphash.c
lib/string.c
lib/string_helpers.c
lib/timerqueue.c
lib/vsprintf.c
lib/win_minmax.c
lib/xarray.c
mm/util.c
net/core/datagram.c
net/core/dev.c
net/core/dev_addr_lists.c
net/core/dev_ioctl.c
net/core/dst.c
net/core/dst_cache.c
net/core/failover.c
net/core/fib_notifier.c
net/core/filter.c
net/core/flow_dissector.c
net/core/flow_offload.c
net/core/gen_estimator.c
net/core/gen_stats.c
net/core/gro.c
net/core/gro_cells.c
net/core/link_watch.c
net/core/neighbour.c
net/core/net_namespace.c
net/core/netevent.c
net/core/request_sock.c
net/core/rtnetlink.c
net/core/scm.c
net/core/secure_seq.c
net/core/selftests.c
net/core/skbuff.c
net/core/sock.c
net/core/sock_diag.c
net/core/sock_reuseport.c
net/core/stream.c
net/core/tso.c
net/core/utils.c
net/core/xdp.c
net/ethernet/eth.c
net/ipv4/af_inet.c
net/ipv4/arp.c
net/ipv4/datagram.c
net/ipv4/devinet.c
net/ipv4/fib_frontend.c
net/ipv4/fib_notifier.c
net/ipv4/fib_semantics.c
net/ipv4/fib_trie.c
net/ipv4/gre_offload.c
net/ipv4/icmp.c
net/ipv4/igmp.c
net/ipv4/inet_connection_sock.c
net/ipv4/inet_diag.c
net/ipv4/inet_fragment.c
net/ipv4/inet_hashtables.c
net/ipv4/inet_timewait_sock.c
net/ipv4/inetpeer.c
net/ipv4/ip_forward.c
net/ipv4/ip_fragment.c
net/ipv4/ip_input.c
net/ipv4/ip_options.c
net/ipv4/ip_output.c
net/ipv4/ip_sockglue.c
net/ipv4/ip_tunnel.c
net/ipv4/ip_tunnel_core.c
net/ipv4/ipconfig.c
net/ipv4/metrics.c
net/ipv4/netlink.c
net/ipv4/nexthop.c
net/ipv4/ping.c
net/ipv4/protocol.c
net/ipv4/raw.c
net/ipv4/route.c
net/ipv4/tcp.c
net/ipv4/tcp_cong.c
net/ipv4/tcp_cubic.c
net/ipv4/tcp_diag.c
net/ipv4/tcp_fastopen.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_metrics.c
net/ipv4/tcp_minisocks.c
net/ipv4/tcp_offload.c
net/ipv4/tcp_output.c
net/ipv4/tcp_rate.c
net/ipv4/tcp_recovery.c
net/ipv4/tcp_timer.c
net/ipv4/tcp_ulp.c
net/ipv4/udp.c
net/ipv4/udp_offload.c
net/ipv4/udp_tunnel_core.c
net/ipv4/udp_tunnel_nic.c
net/ipv4/udp_tunnel_stub.c
net/ipv4/udplite.c
net/netlink/af_netlink.c
net/netlink/genetlink.c
net/netlink/policy.c
net/sched/sch_frag.c
net/sched/sch_generic.c
net/sched/sch_mq.c

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,155 @@
arch/arm64/lib/csum.c
arch/arm64/lib/memchr.S
arch/arm64/lib/memcmp.S
arch/arm64/lib/strchr.S
arch/arm64/lib/strcmp.S
arch/arm64/lib/strlen.S
arch/arm64/lib/strncmp.S
arch/arm64/lib/strnlen.S
drivers/base/class.c
drivers/net/loopback.c
fs/nls/nls_base.c
kernel/kthread.c
kernel/locking/mutex.c
kernel/locking/osq_lock.c
kernel/locking/rwsem.c
kernel/notifier.c
kernel/sched/build_utility.c
kernel/smpboot.c
kernel/softirq.c
kernel/time/clockevents.c
kernel/time/clocksource.c
kernel/time/hrtimer.c
kernel/time/jiffies.c
kernel/time/ntp.c
kernel/time/tick-broadcast-hrtimer.c
kernel/time/tick-broadcast.c
kernel/time/tick-common.c
kernel/time/tick-oneshot.c
kernel/time/tick-sched.c
kernel/time/time.c
kernel/time/timeconv.c
kernel/time/timecounter.c
kernel/time/timekeeping.c
kernel/time/timer.c
kernel/time/timer_list.c
kernel/workqueue.c
lib/bitmap.c
lib/checksum.c
lib/ctype.c
lib/find_bit.c
lib/hexdump.c
lib/hweight.c
lib/idr.c
lib/iov_iter.c
lib/kasprintf.c
lib/klist.c
lib/kobject.c
lib/kstrtox.c
lib/nlattr.c
lib/once.c
lib/percpu_counter.c
lib/radix-tree.c
lib/rbtree.c
lib/rhashtable.c
lib/siphash.c
lib/string.c
lib/string_helpers.c
lib/timerqueue.c
lib/vsprintf.c
lib/win_minmax.c
lib/xarray.c
mm/util.c
net/core/datagram.c
net/core/dev.c
net/core/dev_addr_lists.c
net/core/dev_ioctl.c
net/core/dst.c
net/core/dst_cache.c
net/core/failover.c
net/core/fib_notifier.c
net/core/filter.c
net/core/flow_dissector.c
net/core/flow_offload.c
net/core/gen_estimator.c
net/core/gen_stats.c
net/core/gro.c
net/core/gro_cells.c
net/core/link_watch.c
net/core/neighbour.c
net/core/net_namespace.c
net/core/netevent.c
net/core/request_sock.c
net/core/rtnetlink.c
net/core/scm.c
net/core/secure_seq.c
net/core/selftests.c
net/core/skbuff.c
net/core/sock.c
net/core/sock_diag.c
net/core/sock_reuseport.c
net/core/stream.c
net/core/tso.c
net/core/utils.c
net/core/xdp.c
net/ethernet/eth.c
net/ipv4/af_inet.c
net/ipv4/arp.c
net/ipv4/datagram.c
net/ipv4/devinet.c
net/ipv4/fib_frontend.c
net/ipv4/fib_notifier.c
net/ipv4/fib_semantics.c
net/ipv4/fib_trie.c
net/ipv4/gre_offload.c
net/ipv4/icmp.c
net/ipv4/igmp.c
net/ipv4/inet_connection_sock.c
net/ipv4/inet_diag.c
net/ipv4/inet_fragment.c
net/ipv4/inet_hashtables.c
net/ipv4/inet_timewait_sock.c
net/ipv4/inetpeer.c
net/ipv4/ip_forward.c
net/ipv4/ip_fragment.c
net/ipv4/ip_input.c
net/ipv4/ip_options.c
net/ipv4/ip_output.c
net/ipv4/ip_sockglue.c
net/ipv4/ip_tunnel.c
net/ipv4/ip_tunnel_core.c
net/ipv4/ipconfig.c
net/ipv4/metrics.c
net/ipv4/netlink.c
net/ipv4/nexthop.c
net/ipv4/ping.c
net/ipv4/protocol.c
net/ipv4/raw.c
net/ipv4/route.c
net/ipv4/tcp.c
net/ipv4/tcp_cong.c
net/ipv4/tcp_cubic.c
net/ipv4/tcp_diag.c
net/ipv4/tcp_fastopen.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_metrics.c
net/ipv4/tcp_minisocks.c
net/ipv4/tcp_offload.c
net/ipv4/tcp_output.c
net/ipv4/tcp_rate.c
net/ipv4/tcp_recovery.c
net/ipv4/tcp_timer.c
net/ipv4/tcp_ulp.c
net/ipv4/udp.c
net/ipv4/udp_offload.c
net/ipv4/udp_tunnel_core.c
net/ipv4/udp_tunnel_nic.c
net/ipv4/udp_tunnel_stub.c
net/ipv4/udplite.c
net/netlink/af_netlink.c
net/netlink/genetlink.c
net/netlink/policy.c
net/sched/sch_frag.c
net/sched/sch_generic.c
net/sched/sch_mq.c

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,147 @@
arch/x86/lib/checksum_32.S
arch/x86/lib/hweight.S
drivers/base/class.c
drivers/net/loopback.c
fs/nls/nls_base.c
kernel/kthread.c
kernel/locking/mutex.c
kernel/locking/osq_lock.c
kernel/locking/rwsem.c
kernel/notifier.c
kernel/sched/build_utility.c
kernel/smpboot.c
kernel/softirq.c
kernel/time/clockevents.c
kernel/time/clocksource.c
kernel/time/hrtimer.c
kernel/time/jiffies.c
kernel/time/ntp.c
kernel/time/tick-broadcast.c
kernel/time/tick-common.c
kernel/time/tick-oneshot.c
kernel/time/tick-sched.c
kernel/time/time.c
kernel/time/timeconv.c
kernel/time/timecounter.c
kernel/time/timekeeping.c
kernel/time/timer.c
kernel/time/timer_list.c
kernel/workqueue.c
lib/bitmap.c
lib/ctype.c
lib/find_bit.c
lib/hexdump.c
lib/idr.c
lib/iov_iter.c
lib/kasprintf.c
lib/klist.c
lib/kobject.c
lib/kstrtox.c
lib/math/div64.c
lib/nlattr.c
lib/once.c
lib/percpu_counter.c
lib/radix-tree.c
lib/rbtree.c
lib/rhashtable.c
lib/siphash.c
lib/string.c
lib/string_helpers.c
lib/timerqueue.c
lib/vsprintf.c
lib/win_minmax.c
lib/xarray.c
mm/util.c
net/core/datagram.c
net/core/dev.c
net/core/dev_addr_lists.c
net/core/dev_ioctl.c
net/core/dst.c
net/core/dst_cache.c
net/core/failover.c
net/core/fib_notifier.c
net/core/filter.c
net/core/flow_dissector.c
net/core/flow_offload.c
net/core/gen_estimator.c
net/core/gen_stats.c
net/core/gro.c
net/core/gro_cells.c
net/core/link_watch.c
net/core/neighbour.c
net/core/net_namespace.c
net/core/netevent.c
net/core/request_sock.c
net/core/rtnetlink.c
net/core/scm.c
net/core/secure_seq.c
net/core/selftests.c
net/core/skbuff.c
net/core/sock.c
net/core/sock_diag.c
net/core/sock_reuseport.c
net/core/stream.c
net/core/tso.c
net/core/utils.c
net/core/xdp.c
net/ethernet/eth.c
net/ipv4/af_inet.c
net/ipv4/arp.c
net/ipv4/datagram.c
net/ipv4/devinet.c
net/ipv4/fib_frontend.c
net/ipv4/fib_notifier.c
net/ipv4/fib_semantics.c
net/ipv4/fib_trie.c
net/ipv4/gre_offload.c
net/ipv4/icmp.c
net/ipv4/igmp.c
net/ipv4/inet_connection_sock.c
net/ipv4/inet_diag.c
net/ipv4/inet_fragment.c
net/ipv4/inet_hashtables.c
net/ipv4/inet_timewait_sock.c
net/ipv4/inetpeer.c
net/ipv4/ip_forward.c
net/ipv4/ip_fragment.c
net/ipv4/ip_input.c
net/ipv4/ip_options.c
net/ipv4/ip_output.c
net/ipv4/ip_sockglue.c
net/ipv4/ip_tunnel.c
net/ipv4/ip_tunnel_core.c
net/ipv4/ipconfig.c
net/ipv4/metrics.c
net/ipv4/netlink.c
net/ipv4/nexthop.c
net/ipv4/ping.c
net/ipv4/protocol.c
net/ipv4/raw.c
net/ipv4/route.c
net/ipv4/tcp.c
net/ipv4/tcp_cong.c
net/ipv4/tcp_cubic.c
net/ipv4/tcp_diag.c
net/ipv4/tcp_fastopen.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_metrics.c
net/ipv4/tcp_minisocks.c
net/ipv4/tcp_offload.c
net/ipv4/tcp_output.c
net/ipv4/tcp_rate.c
net/ipv4/tcp_recovery.c
net/ipv4/tcp_timer.c
net/ipv4/tcp_ulp.c
net/ipv4/udp.c
net/ipv4/udp_offload.c
net/ipv4/udp_tunnel_core.c
net/ipv4/udp_tunnel_nic.c
net/ipv4/udp_tunnel_stub.c
net/ipv4/udplite.c
net/netlink/af_netlink.c
net/netlink/genetlink.c
net/netlink/policy.c
net/sched/sch_frag.c
net/sched/sch_generic.c
net/sched/sch_mq.c

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,148 @@
arch/x86/lib/csum-copy_64.S
arch/x86/lib/csum-partial_64.c
arch/x86/lib/csum-wrappers_64.c
arch/x86/lib/hweight.S
drivers/base/class.c
drivers/net/loopback.c
fs/nls/nls_base.c
kernel/kthread.c
kernel/locking/mutex.c
kernel/locking/osq_lock.c
kernel/locking/rwsem.c
kernel/notifier.c
kernel/sched/build_utility.c
kernel/smpboot.c
kernel/softirq.c
kernel/time/clockevents.c
kernel/time/clocksource.c
kernel/time/hrtimer.c
kernel/time/jiffies.c
kernel/time/ntp.c
kernel/time/tick-broadcast.c
kernel/time/tick-common.c
kernel/time/tick-oneshot.c
kernel/time/tick-sched.c
kernel/time/time.c
kernel/time/timeconv.c
kernel/time/timecounter.c
kernel/time/timekeeping.c
kernel/time/timer.c
kernel/time/timer_list.c
kernel/workqueue.c
lib/bitmap.c
lib/ctype.c
lib/find_bit.c
lib/hexdump.c
lib/idr.c
lib/iov_iter.c
lib/kasprintf.c
lib/klist.c
lib/kobject.c
lib/kstrtox.c
lib/nlattr.c
lib/once.c
lib/percpu_counter.c
lib/radix-tree.c
lib/rbtree.c
lib/rhashtable.c
lib/siphash.c
lib/string.c
lib/string_helpers.c
lib/timerqueue.c
lib/vsprintf.c
lib/win_minmax.c
lib/xarray.c
mm/util.c
net/core/datagram.c
net/core/dev.c
net/core/dev_addr_lists.c
net/core/dev_ioctl.c
net/core/dst.c
net/core/dst_cache.c
net/core/failover.c
net/core/fib_notifier.c
net/core/filter.c
net/core/flow_dissector.c
net/core/flow_offload.c
net/core/gen_estimator.c
net/core/gen_stats.c
net/core/gro.c
net/core/gro_cells.c
net/core/link_watch.c
net/core/neighbour.c
net/core/net_namespace.c
net/core/netevent.c
net/core/request_sock.c
net/core/rtnetlink.c
net/core/scm.c
net/core/secure_seq.c
net/core/selftests.c
net/core/skbuff.c
net/core/sock.c
net/core/sock_diag.c
net/core/sock_reuseport.c
net/core/stream.c
net/core/tso.c
net/core/utils.c
net/core/xdp.c
net/ethernet/eth.c
net/ipv4/af_inet.c
net/ipv4/arp.c
net/ipv4/datagram.c
net/ipv4/devinet.c
net/ipv4/fib_frontend.c
net/ipv4/fib_notifier.c
net/ipv4/fib_semantics.c
net/ipv4/fib_trie.c
net/ipv4/gre_offload.c
net/ipv4/icmp.c
net/ipv4/igmp.c
net/ipv4/inet_connection_sock.c
net/ipv4/inet_diag.c
net/ipv4/inet_fragment.c
net/ipv4/inet_hashtables.c
net/ipv4/inet_timewait_sock.c
net/ipv4/inetpeer.c
net/ipv4/ip_forward.c
net/ipv4/ip_fragment.c
net/ipv4/ip_input.c
net/ipv4/ip_options.c
net/ipv4/ip_output.c
net/ipv4/ip_sockglue.c
net/ipv4/ip_tunnel.c
net/ipv4/ip_tunnel_core.c
net/ipv4/ipconfig.c
net/ipv4/metrics.c
net/ipv4/netlink.c
net/ipv4/nexthop.c
net/ipv4/ping.c
net/ipv4/protocol.c
net/ipv4/raw.c
net/ipv4/route.c
net/ipv4/tcp.c
net/ipv4/tcp_cong.c
net/ipv4/tcp_cubic.c
net/ipv4/tcp_diag.c
net/ipv4/tcp_fastopen.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_metrics.c
net/ipv4/tcp_minisocks.c
net/ipv4/tcp_offload.c
net/ipv4/tcp_output.c
net/ipv4/tcp_rate.c
net/ipv4/tcp_recovery.c
net/ipv4/tcp_timer.c
net/ipv4/tcp_ulp.c
net/ipv4/udp.c
net/ipv4/udp_offload.c
net/ipv4/udp_tunnel_core.c
net/ipv4/udp_tunnel_nic.c
net/ipv4/udp_tunnel_stub.c
net/ipv4/udplite.c
net/netlink/af_netlink.c
net/netlink/genetlink.c
net/netlink/policy.c
net/sched/sch_frag.c
net/sched/sch_generic.c
net/sched/sch_mq.c