SchOS/kernel/net/lwip/lwipopts.h
Nexoniarz 26bca020b6 licence: SchOS is GPL-2.0-or-later, no longer Apache-2.0
Nexoniarz is the sole author and SchOS was never published under
Apache-2.0, so this is a straight relicence. LICENSE is the FSF GPLv2 text,
every first-party SPDX header moves to GPL-2.0-or-later, and NOTICE,
README.md, docs/licensing.md and the site say so. projects/schfs-linux
follows the rest of the tree.

The GPL gives copyleft: a fork has to ship its source. It also lifts the
old "Linux drivers, never" rule, since GPL-2.0-only code combines with
GPL-2.0-or-later. "Or later" leaves room for GPLv3, but one binary still
has to pick one version, so docs/licensing.md now keeps Apache-2.0 and
GPLv3 code out of the kernel to keep Linux code possible there. BSD
4-clause code goes from "avoid" to "no", because the advertising clause
is GPL-incompatible.

LDLS still ships no .ko. That boundary is now project policy rather than
a legal requirement, and ldls.md, devices.md and licensing.md section 6
say so. refmod declares license=GPL, and ldls-check passes (27 checks).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 08:48:45 +02:00

106 lines
4.6 KiB
C

// SPDX-License-Identifier: GPL-2.0-or-later
//
// lwIP configuration for SchOS.
//
// The shape of this file is one decision: NO_SYS=1.
//
// lwIP can run either as a set of threads of its own (NO_SYS=0), which needs a
// port layer of semaphores, mailboxes and thread creation and then hands you a
// blocking sockets API for free; or bare, with no threading assumptions
// (NO_SYS=1), where every call must come from one context and the blocking is
// yours to write. This kernel takes the second, for two reasons: the sys_arch
// a threaded lwIP wants is more code than the socket layer it would save, and
// the kernel already has a socket layer with its own shape (kernel/net/unix.c)
// that AF_INET has to fit into rather than replace.
//
// "One context" is enforced by a single lock rather than by literally one
// thread: kernel/net/net.c takes it around the network thread's work, and the
// socket syscalls take it around theirs. That is the entire concurrency model.
#ifndef LWIP_LWIPOPTS_H
#define LWIP_LWIPOPTS_H
#define NO_SYS 1
#define SYS_LIGHTWEIGHT_PROT 1
#define LWIP_NETCONN 0 // needs NO_SYS=0
#define LWIP_SOCKET 0 // ours lives in kernel/net/inet.c
// Memory. All of it is static: the kernel's allocator hands out whole pages
// and nothing else, so lwIP's own pools are a better fit than wrapping kalloc.
// These numbers are sized for a handful of connections, not for a server.
#define MEM_LIBC_MALLOC 0
#define MEMP_MEM_MALLOC 0
#define MEM_ALIGNMENT 4
#define MEM_SIZE (192 * 1024)
#define MEMP_NUM_PBUF 32
#define MEMP_NUM_UDP_PCB 8
#define MEMP_NUM_TCP_PCB 16
#define MEMP_NUM_TCP_PCB_LISTEN 8
#define MEMP_NUM_TCP_SEG 64
#define MEMP_NUM_ARP_QUEUE 16
#define MEMP_NUM_SYS_TIMEOUT 16
#define PBUF_POOL_SIZE 48
#define PBUF_POOL_BUFSIZE 1536 // one Ethernet frame plus room
// Protocols. IPv4 only: the driver is proven for it, the QEMU test network is
// v4, and every line of v6 here would be untested.
#define LWIP_IPV4 1
#define LWIP_IPV6 0
#define LWIP_ARP 1
#define LWIP_ETHERNET 1
#define LWIP_ICMP 1
#define LWIP_RAW 1
// A loopback interface, so 127.0.0.1 is a real destination rather than an
// address with no route. lwip_init() creates it; nothing else has to.
//
// LWIP_NETIF_LOOPBACK is the other half and is easy to miss: without it a
// packet addressed to an interface's *own* address goes out of the wire and
// never comes back. With NO_SYS=1 there is no thread to drain the loopback
// queue either, so netif_poll_all() is called from the network thread -- see
// kernel/net/net.c.
#define LWIP_HAVE_LOOPIF 1
#define LWIP_NETIF_LOOPBACK 1
#define LWIP_LOOPBACK_MAX_PBUFS 8
#define LWIP_UDP 1
#define LWIP_TCP 1
#define LWIP_DHCP 1
#define LWIP_DNS 1
#define LWIP_AUTOIP 0
#define LWIP_IGMP 0
#define LWIP_NETIF_HOSTNAME 1
// DHCP needs UDP checksums and a broadcast path; both are on. Requesting an
// address rather than hard-coding one matters because QEMU's user-mode network
// hands out 10.0.2.15 through DHCP and nothing else will route.
#define LWIP_NETIF_STATUS_CALLBACK 1
#define LWIP_NETIF_LINK_CALLBACK 1
#define TCP_MSS 1460
#define TCP_SND_BUF (8 * TCP_MSS)
#define TCP_WND (8 * TCP_MSS)
#define TCP_SND_QUEUELEN ((4 * TCP_SND_BUF) / TCP_MSS)
#define TCP_LISTEN_BACKLOG 1
// Checksums in software. The e1000 can offload them, but the driver does not
// ask it to, and a checksum computed by a device the stack has not been told
// about is the sort of mismatch that shows up only against a real peer.
#define CHECKSUM_GEN_IP 1
#define CHECKSUM_GEN_UDP 1
#define CHECKSUM_GEN_TCP 1
#define CHECKSUM_CHECK_IP 1
#define CHECKSUM_CHECK_UDP 1
#define CHECKSUM_CHECK_TCP 1
// Statistics are what /proc/net reports; they cost a few counters.
#define LWIP_STATS 1
#define LWIP_STATS_DISPLAY 0
// Debug output off by default -- turning LWIP_DEBUG on here makes the stack
// extremely chatty on the console, which is occasionally exactly what you want.
#define LWIP_DEBUG 0
// lwIP would otherwise provide its own errno, which would then disagree with
// the kernel's for every value a syscall returns.
#define LWIP_PROVIDE_ERRNO 1
#endif