phunix/minix/net/lwip/lnksock.c
David van Moolenbroek ef8d499e2d Add lwip: a new lwIP-based TCP/IP service
This commit adds a new TCP/IP service to MINIX 3.  As its core, the
service uses the lwIP TCP/IP stack for maintenance reasons.  The
service aims to be compatible with NetBSD userland, including its
low-level network management utilities.  It also aims to support
modern features such as IPv6.  In summary, the new LWIP service has
support for the following main features:

- TCP, UDP, RAW sockets with mostly standard BSD API semantics;
- IPv6 support: host mode (complete) and router mode (partial);
- most of the standard BSD API socket options (SO_);
- all of the standard BSD API message flags (MSG_);
- the most used protocol-specific socket and control options;
- a default loopback interface and the ability to create one more;
- configuration-free ethernet interfaces and driver tracking;
- queuing and multiple concurrent requests to each ethernet driver;
- standard ioctl(2)-based BSD interface management;
- radix tree backed, destination-based routing;
- routing sockets for standard BSD route reporting and management;
- multicast traffic and multicast group membership tracking;
- Berkeley Packet Filter (BPF) devices;
- standard and custom sysctl(7) nodes for many internals;
- a slab allocation based, hybrid static/dynamic memory pool model.

Many of its modules come with fairly elaborate comments that cover
many aspects of what is going on.  The service is primarily a socket
driver built on top of the libsockdriver library, but for BPF devices
it is at the same time also a character driver.

Change-Id: Ib0c02736234b21143915e5fcc0fda8fe408f046f
2017-04-30 13:16:03 +00:00

78 lines
1.7 KiB
C

/* LWIP service - lnksock.c - link sockets */
/*
* This module contains absolutely minimal support for AF_LINK type sockets,
* because for now we need them only to support a specific set of IOCTLs, as
* required by for example ifconfig(8).
*/
#include "lwip.h"
/* The number of link sockets. */
#define NR_LNKSOCK 4
static struct lnksock {
struct sock lnk_sock; /* socket object, MUST be first */
SIMPLEQ_ENTRY(lnksock) lnk_next; /* next in free list */
} lnk_array[NR_LNKSOCK];
static SIMPLEQ_HEAD(, lnksock) lnk_freelist; /* list of free link sockets */
static const struct sockevent_ops lnksock_ops;
/*
* Initialize the link sockets module.
*/
void
lnksock_init(void)
{
unsigned int slot;
/* Initialize the list of free link sockets. */
SIMPLEQ_INIT(&lnk_freelist);
for (slot = 0; slot < __arraycount(lnk_array); slot++)
SIMPLEQ_INSERT_TAIL(&lnk_freelist, &lnk_array[slot], lnk_next);
}
/*
* Create a link socket.
*/
sockid_t
lnksock_socket(int type, int protocol, struct sock ** sockp,
const struct sockevent_ops ** ops)
{
struct lnksock *lnk;
if (type != SOCK_DGRAM)
return EPROTOTYPE;
if (protocol != 0)
return EPROTONOSUPPORT;
if (SIMPLEQ_EMPTY(&lnk_freelist))
return ENOBUFS;
lnk = SIMPLEQ_FIRST(&lnk_freelist);
SIMPLEQ_REMOVE_HEAD(&lnk_freelist, lnk_next);
*sockp = &lnk->lnk_sock;
*ops = &lnksock_ops;
return SOCKID_LNK | (sockid_t)(lnk - lnk_array);
}
/*
* Free up a closed link socket.
*/
static void
lnksock_free(struct sock * sock)
{
struct lnksock *lnk = (struct lnksock *)sock;
SIMPLEQ_INSERT_HEAD(&lnk_freelist, lnk, lnk_next);
}
static const struct sockevent_ops lnksock_ops = {
.sop_ioctl = ifconf_ioctl,
.sop_free = lnksock_free
};