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:
Jukka Rissanen 2016-05-09 15:49:48 +03:00
commit 7047e00f85
6 changed files with 306 additions and 0 deletions

View file

@ -20,3 +20,134 @@
* 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 */

View file

@ -96,6 +96,13 @@ config NET_NBUF_DATA_SIZE
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.
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
bool "Use SLIP connectivity with Qemu"
default n

View file

@ -1,4 +1,5 @@
ccflags-y += -I${srctree}/net/ip
obj-y = net_core.o \
net_if.o \
net_context.o \
nbuf.o

164
net/yaip/net_context.c Normal file
View 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);
}

View file

@ -133,6 +133,8 @@ static int net_init(struct device *unused)
net_if_init();
net_context_init();
return network_initialization();
}

View file

@ -24,3 +24,4 @@
extern void net_nbuf_init(void);
extern int net_if_init(void);
extern void net_context_init(void);