net: Add net_context to compilation
Network context defines network endpoints a.k.a sockets. Change-Id: Ib1fab03f0862b298a441a79a4f4173f18a8260cb Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
parent
8c8052497d
commit
7047e00f85
6 changed files with 306 additions and 0 deletions
|
@ -20,3 +20,134 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef __NET_CONTEXT_H
|
||||||
|
#define __NET_CONTEXT_H
|
||||||
|
|
||||||
|
#include <nanokernel.h>
|
||||||
|
|
||||||
|
#include <net/net_ip.h>
|
||||||
|
#include <net/net_if.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_NET_YAIP)
|
||||||
|
|
||||||
|
struct net_context {
|
||||||
|
/* Connection tuple identifies the connection */
|
||||||
|
struct net_tuple tuple;
|
||||||
|
|
||||||
|
/* Application receives data via this fifo */
|
||||||
|
struct nano_fifo rx_queue;
|
||||||
|
|
||||||
|
/* Network interface assigned to this context */
|
||||||
|
struct net_if *iface;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get network context.
|
||||||
|
*
|
||||||
|
* @details Network context is used to define the connection
|
||||||
|
* 5-tuple (protocol, remote address, remote port, source
|
||||||
|
* address and source port).
|
||||||
|
*
|
||||||
|
* @param ip_proto Protocol to use. Currently only UDP is supported.
|
||||||
|
* @param remote_addr Remote IPv6/IPv4 address.
|
||||||
|
* @param remote_port Remote UDP/TCP port.
|
||||||
|
* @param local_addr Local IPv6/IPv4 address. If the local address is
|
||||||
|
* set to be anyaddr (all zeros), the IP stack will use the link
|
||||||
|
* local address defined for the system.
|
||||||
|
* @param local_port Local UDP/TCP port. If the local port is 0,
|
||||||
|
* then a random port will be allocated.
|
||||||
|
*
|
||||||
|
* @return Network context if successful, NULL otherwise.
|
||||||
|
*/
|
||||||
|
struct net_context *net_context_get(enum ip_protocol ip_proto,
|
||||||
|
const struct net_addr *remote_addr,
|
||||||
|
uint16_t remote_port,
|
||||||
|
struct net_addr *local_addr,
|
||||||
|
uint16_t local_port);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Release network context.
|
||||||
|
*
|
||||||
|
* @details Free the resources allocated for the context.
|
||||||
|
* All network listeners tied to this context are removed.
|
||||||
|
*
|
||||||
|
* @param context Network context.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void net_context_put(struct net_context *context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get network tuple for this context.
|
||||||
|
*
|
||||||
|
* @details This function returns the used connection tuple.
|
||||||
|
*
|
||||||
|
* @param context Network context.
|
||||||
|
*
|
||||||
|
* @return Network tuple if successful, NULL otherwise.
|
||||||
|
*/
|
||||||
|
static inline
|
||||||
|
struct net_tuple *net_context_get_tuple(struct net_context *context)
|
||||||
|
{
|
||||||
|
return &context->tuple;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get network queue for this context.
|
||||||
|
*
|
||||||
|
* @details This function returns the used network queue.
|
||||||
|
*
|
||||||
|
* @param context Network context.
|
||||||
|
*
|
||||||
|
* @return Context RX queue if successful, NULL otherwise.
|
||||||
|
*/
|
||||||
|
static inline
|
||||||
|
struct nano_fifo *net_context_get_queue(struct net_context *context)
|
||||||
|
{
|
||||||
|
return &context->rx_queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get network interface for this context.
|
||||||
|
*
|
||||||
|
* @details This function returns the used network interface.
|
||||||
|
*
|
||||||
|
* @param context Network context.
|
||||||
|
*
|
||||||
|
* @return Context network interface if context is bind to interface,
|
||||||
|
* NULL otherwise.
|
||||||
|
*/
|
||||||
|
static inline
|
||||||
|
struct net_if *net_context_get_iface(struct net_context *context)
|
||||||
|
{
|
||||||
|
return context->iface;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set network interface for this context.
|
||||||
|
*
|
||||||
|
* @details This function binds network interface to this context.
|
||||||
|
*
|
||||||
|
* @param context Network context.
|
||||||
|
* @param iface Network interface.
|
||||||
|
*/
|
||||||
|
static inline void net_context_set_iface(struct net_context *context,
|
||||||
|
struct net_if *iface)
|
||||||
|
{
|
||||||
|
context->iface = iface;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void *net_context_get_internal_connection(struct net_context *context);
|
||||||
|
|
||||||
|
#endif /* CONFIG_NET_YAIP */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __NET_CONTEXT_H */
|
||||||
|
|
|
@ -96,6 +96,13 @@ config NET_NBUF_DATA_SIZE
|
||||||
In order to be able to receive at least full IPv6 packet which
|
In order to be able to receive at least full IPv6 packet which
|
||||||
has a size of 1280 bytes, the one should allocate 16 fragments here.
|
has a size of 1280 bytes, the one should allocate 16 fragments here.
|
||||||
|
|
||||||
|
config CONFIG_NET_MAX_CONTEXTS
|
||||||
|
int "Number of network contexts to allocate"
|
||||||
|
default 6
|
||||||
|
help
|
||||||
|
Each network context is used to describe a network 5-tuple that
|
||||||
|
is used when listening or sending network traffic.
|
||||||
|
|
||||||
config NET_SLIP
|
config NET_SLIP
|
||||||
bool "Use SLIP connectivity with Qemu"
|
bool "Use SLIP connectivity with Qemu"
|
||||||
default n
|
default n
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
ccflags-y += -I${srctree}/net/ip
|
ccflags-y += -I${srctree}/net/ip
|
||||||
obj-y = net_core.o \
|
obj-y = net_core.o \
|
||||||
net_if.o \
|
net_if.o \
|
||||||
|
net_context.o \
|
||||||
nbuf.o
|
nbuf.o
|
||||||
|
|
164
net/yaip/net_context.c
Normal file
164
net/yaip/net_context.c
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
/** @file
|
||||||
|
@brief Network context API
|
||||||
|
|
||||||
|
An API for applications to define a network connection.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Intel Corporation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <nanokernel.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include <net/net_ip.h>
|
||||||
|
#include <net/net_context.h>
|
||||||
|
|
||||||
|
/* Override this in makefile if needed */
|
||||||
|
#if defined(CONFIG_NET_MAX_CONTEXTS)
|
||||||
|
#define NET_MAX_CONTEXT CONFIG_NET_MAX_CONTEXTS
|
||||||
|
#else
|
||||||
|
#define NET_MAX_CONTEXT 6
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct net_context contexts[NET_MAX_CONTEXT];
|
||||||
|
static struct nano_sem contexts_lock;
|
||||||
|
|
||||||
|
static void context_sem_give(struct nano_sem *chan)
|
||||||
|
{
|
||||||
|
switch (sys_execution_context_type_get()) {
|
||||||
|
case NANO_CTX_FIBER:
|
||||||
|
nano_fiber_sem_give(chan);
|
||||||
|
break;
|
||||||
|
case NANO_CTX_TASK:
|
||||||
|
nano_task_sem_give(chan);
|
||||||
|
break;
|
||||||
|
case NANO_CTX_ISR:
|
||||||
|
default:
|
||||||
|
/* Invalid context type */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int context_port_used(enum ip_protocol ip_proto, uint16_t local_port,
|
||||||
|
const struct net_addr *local_addr)
|
||||||
|
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < NET_MAX_CONTEXT; i++) {
|
||||||
|
if (contexts[i].tuple.ip_proto == ip_proto &&
|
||||||
|
contexts[i].tuple.local_port == local_port &&
|
||||||
|
!memcmp(&contexts[i].tuple.local_addr, local_addr,
|
||||||
|
sizeof(struct net_addr))) {
|
||||||
|
return -EEXIST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct net_context *net_context_get(enum ip_protocol ip_proto,
|
||||||
|
const struct net_addr *remote_addr,
|
||||||
|
uint16_t remote_port,
|
||||||
|
struct net_addr *local_addr,
|
||||||
|
uint16_t local_port)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_NET_IPV6
|
||||||
|
const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
|
||||||
|
#endif
|
||||||
|
int i;
|
||||||
|
struct net_context *context = NULL;
|
||||||
|
|
||||||
|
/* User must provide storage for the local address. */
|
||||||
|
if (!local_addr) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_NET_IPV6)
|
||||||
|
if (memcmp(&local_addr->in6_addr, &in6addr_any,
|
||||||
|
sizeof(in6addr_any)) == 0) {
|
||||||
|
/* FIXME */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_NET_IPV4)
|
||||||
|
if (local_addr->in_addr.s_addr == INADDR_ANY) {
|
||||||
|
/* FIXME */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
nano_sem_take(&contexts_lock, TICKS_UNLIMITED);
|
||||||
|
|
||||||
|
if (local_port) {
|
||||||
|
if (context_port_used(ip_proto, local_port, local_addr) < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
do {
|
||||||
|
local_port = sys_rand32_get() | 0x8000;
|
||||||
|
} while (context_port_used(ip_proto, local_port,
|
||||||
|
local_addr) == -EEXIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < NET_MAX_CONTEXT; i++) {
|
||||||
|
if (!contexts[i].tuple.ip_proto) {
|
||||||
|
contexts[i].tuple.ip_proto = ip_proto;
|
||||||
|
contexts[i].tuple.remote_addr = (struct net_addr *)remote_addr;
|
||||||
|
contexts[i].tuple.remote_port = remote_port;
|
||||||
|
contexts[i].tuple.local_addr = (struct net_addr *)local_addr;
|
||||||
|
contexts[i].tuple.local_port = local_port;
|
||||||
|
context = &contexts[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
context_sem_give(&contexts_lock);
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
void net_context_put(struct net_context *context)
|
||||||
|
{
|
||||||
|
if (!context) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nano_sem_take(&contexts_lock, TICKS_UNLIMITED);
|
||||||
|
|
||||||
|
if (context->tuple.ip_proto == IPPROTO_UDP) {
|
||||||
|
/* FIXME */
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&context->tuple, 0, sizeof(context->tuple));
|
||||||
|
|
||||||
|
context_sem_give(&contexts_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void net_context_init(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
nano_sem_init(&contexts_lock);
|
||||||
|
|
||||||
|
memset(contexts, 0, sizeof(contexts));
|
||||||
|
|
||||||
|
for (i = 0; i < NET_MAX_CONTEXT; i++) {
|
||||||
|
nano_fifo_init(&contexts[i].rx_queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
context_sem_give(&contexts_lock);
|
||||||
|
}
|
|
@ -133,6 +133,8 @@ static int net_init(struct device *unused)
|
||||||
|
|
||||||
net_if_init();
|
net_if_init();
|
||||||
|
|
||||||
|
net_context_init();
|
||||||
|
|
||||||
return network_initialization();
|
return network_initialization();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,3 +24,4 @@
|
||||||
|
|
||||||
extern void net_nbuf_init(void);
|
extern void net_nbuf_init(void);
|
||||||
extern int net_if_init(void);
|
extern int net_if_init(void);
|
||||||
|
extern void net_context_init(void);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue