Skip to content

Commit 700f7fd

Browse files
authored
Merge pull request #5 from danielinux/multi-if
Add support for multiple datalink interfaces
2 parents f5dd378 + bdb734b commit 700f7fd

File tree

22 files changed

+2859
-417
lines changed

22 files changed

+2859
-417
lines changed

.github/workflows/cppcheck.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
Name: CppCheck code linter
2-
1+
name: CppCheck code linter
32

43
on:
54
push:
@@ -9,16 +8,17 @@ on:
98

109
jobs:
1110
linter:
12-
runs-on: ubuntu-22.04
11+
runs-on: ubuntu-latest
1312

1413
steps:
15-
- uses: actions/checkout@v2
14+
- uses: actions/checkout@v4
1615
with:
1716
submodules: true
1817

1918
- name: Update repo
2019
run: |
2120
sudo apt-get update
21+
sudo apt install -y cppcheck
2222
2323
- name: Run cppcheck
2424
run: |

.github/workflows/linux.yml

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
Name: Linux interop tests
2-
1+
name: Linux interop tests
32

43
on:
54
push:
@@ -8,26 +7,40 @@ on:
87
branches: [ '*' ]
98

109
jobs:
11-
unit_test:
12-
runs-on: ubuntu-22.04
10+
linux_test:
11+
runs-on: ubuntu-latest
1312

1413
steps:
15-
- uses: actions/checkout@v2
14+
- uses: actions/checkout@v4
1615
with:
1716
submodules: true
1817

1918
- name: Update repo
2019
run: |
2120
sudo apt-get update
21+
sudo apt-get install -y libwolfssl-dev
2222
sudo modprobe tun
2323
2424
- name: Build linux tests
2525
run: |
2626
mkdir -p build/port
2727
make
2828
29-
# - name: Run interop tests
30-
# run: |
31-
# sudo build/test
32-
#
33-
#
29+
- name: Run standalone "event loop" test
30+
run: |
31+
sudo ./build/test-evloop
32+
sudo killall tcpdump || true
33+
34+
- name: Run standalone wolfssl test
35+
run: |
36+
sudo ./build/test-wolfssl
37+
sudo killall tcpdump || true
38+
39+
- name: Run standalone forwarding test
40+
run: |
41+
sudo ./build/test-wolfssl-forwarding
42+
43+
- name: Run standalone TTL expired test
44+
run: |
45+
./build/test-ttl-expired
46+

.github/workflows/units.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
Name: Unit Tests
2-
1+
name: Unit Tests
32

43
on:
54
push:
@@ -9,10 +8,10 @@ on:
98

109
jobs:
1110
unit_test:
12-
runs-on: ubuntu-22.04
11+
runs-on: ubuntu-latest
1312

1413
steps:
15-
- uses: actions/checkout@v2
14+
- uses: actions/checkout@v4
1615
with:
1716
submodules: true
1817

Makefile

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,31 @@
11
CC?=gcc
22
CFLAGS:=-Wall -Werror -Wextra -I. -D_GNU_SOURCE
3-
CFLAGS+=-g -ggdb
3+
CFLAGS+=-g -ggdb -Wdeclaration-after-statement
44
LDFLAGS+=-pthread
55

66
CPPCHECK=cppcheck
7-
CPPCHECK_FLAGS=--enable=all --suppress=missingIncludeSystem \
7+
CPPCHECK_FLAGS=--enable=warning,performance,portability,missingInclude \
8+
--suppress=missingIncludeSystem \
9+
-i src/test \
810
--suppress=unusedFunction --suppress=unusedVariable \
911
--suppress=missingInclude --suppress=variableScope \
1012
--suppress=constVariable --suppress=constVariablePointer \
1113
--suppress=constParameterPointer \
1214
--suppress=constParameterCallback \
1315
--suppress=toomanyconfigs \
1416
--suppress=unmatchedSuppression --inconclusive \
17+
--disable=style \
1518
--std=c99 --language=c \
1619
--platform=unix64 \
20+
--check-level=exhaustive \
1721
--error-exitcode=1 --xml --xml-version=2
1822

1923
OBJ=build/wolfip.o \
2024
build/port/posix/linux_tap.o
2125

2226
EXE=build/tcpecho build/tcp_netcat_poll build/tcp_netcat_select \
23-
build/test-evloop build/test-dns
27+
build/test-evloop build/test-dns build/test-wolfssl-forwarding \
28+
build/test-ttl-expired build/test-wolfssl
2429
LIB=libwolfip.so
2530

2631
PREFIX=/usr/local
@@ -80,12 +85,29 @@ build/tcp_netcat_select: $(OBJ) build/port/posix/bsd_socket.o build/test/tcp_net
8085

8186
build/test-wolfssl:CFLAGS+=-Wno-cpp -DWOLFSSL_DEBUG -DWOLFSSL_WOLFIP
8287
build/test-httpd:CFLAGS+=-Wno-cpp -DWOLFSSL_DEBUG -DWOLFSSL_WOLFIP -Isrc/http
88+
build/test-wolfssl-forwarding:CFLAGS+=-Wno-cpp -DWOLFSSL_DEBUG -DWOLFSSL_WOLFIP -DWOLFIP_MAX_INTERFACES=2 -DWOLFIP_ENABLE_FORWARDING=1
8389

8490

8591
build/test-wolfssl: $(OBJ) build/test/test_native_wolfssl.o build/port/wolfssl_io.o build/certs/server_key.o build/certs/ca_cert.o build/certs/server_cert.o
8692
@echo "[LD] $@"
8793
@$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -Wl,--start-group $(^) -lwolfssl -Wl,--end-group
8894

95+
build/test-wolfssl-forwarding: build/test/test_wolfssl_forwarding.o build/test/wolfip_forwarding.o build/port/posix/linux_tap.o build/port/wolfssl_io.o build/certs/server_key.o build/certs/ca_cert.o build/certs/server_cert.o
96+
@echo "[LD] $@"
97+
@$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -Wl,--start-group $(^) -lwolfssl -Wl,--end-group
98+
99+
build/test/test_wolfssl_forwarding.o: CFLAGS+=-DWOLFIP_MAX_INTERFACES=2 -DWOLFIP_ENABLE_FORWARDING=1
100+
101+
build/test/wolfip_forwarding.o: src/wolfip.c
102+
@mkdir -p `dirname $@` || true
103+
@echo "[CC] $< (forwarding)"
104+
@$(CC) $(CFLAGS) -DWOLFIP_MAX_INTERFACES=2 -DWOLFIP_ENABLE_FORWARDING=1 -c $< -o $@
105+
106+
build/test/test_ttl_expired.o: CFLAGS+=-DWOLFIP_MAX_INTERFACES=2 -DWOLFIP_ENABLE_FORWARDING=1
107+
build/test-ttl-expired: build/test/test_ttl_expired.o build/test/wolfip_forwarding.o
108+
@echo "[LD] $@"
109+
@$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -Wl,--start-group $(^) -Wl,--end-group
110+
89111
build/test-httpd: $(OBJ) build/test/test_httpd.o build/port/wolfssl_io.o build/certs/server_key.o build/certs/server_cert.o build/http/httpd.o
90112
@echo "[LD] $@"
91113
@$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -Wl,--start-group $(^) -lwolfssl -Wl,--end-group

config.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,27 @@
66

77
#define MAX_TCPSOCKETS 4
88
#define MAX_UDPSOCKETS 2
9-
#define RXBUF_SIZE LINK_MTU * 4
10-
#define TXBUF_SIZE LINK_MTU * 4
9+
#define RXBUF_SIZE LINK_MTU * 16
10+
#define TXBUF_SIZE LINK_MTU * 16
1111

1212
#define MAX_NEIGHBORS 16
1313

14+
#ifndef WOLFIP_MAX_INTERFACES
15+
#define WOLFIP_MAX_INTERFACES 2
16+
#endif
17+
18+
#ifndef WOLFIP_ENABLE_FORWARDING
19+
#define WOLFIP_ENABLE_FORWARDING 0
20+
#endif
21+
22+
#ifndef WOLFIP_ENABLE_LOOPBACK
23+
#define WOLFIP_ENABLE_LOOPBACK 0
24+
#endif
25+
26+
#if WOLFIP_ENABLE_LOOPBACK && WOLFIP_MAX_INTERFACES < 2
27+
#error "WOLFIP_ENABLE_LOOPBACK requires WOLFIP_MAX_INTERFACES > 1"
28+
#endif
29+
1430
/* Linux test configuration */
1531
#define WOLFIP_IP "10.10.10.2"
1632
#define LINUX_IP "10.10.10.1"

docs/API.md

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,32 @@ wolfIP is a minimal TCP/IP stack designed for resource-constrained embedded syst
2323

2424
### Device Driver Interface
2525
```c
26-
struct ll {
26+
struct wolfIP_ll_dev {
2727
uint8_t mac[6]; // Device MAC address
2828
char ifname[16]; // Interface name
29-
int (*poll)(struct ll *ll, void *buf, uint32_t len); // Receive function
30-
int (*send)(struct ll *ll, void *buf, uint32_t len); // Transmit function
29+
int (*poll)(struct wolfIP_ll_dev *ll, void *buf, uint32_t len); // Receive function
30+
int (*send)(struct wolfIP_ll_dev *ll, void *buf, uint32_t len); // Transmit function
3131
};
3232
```
33+
wolfIP maintains an array of these descriptors sized by `WOLFIP_MAX_INTERFACES` (default `1`). Call `wolfIP_getdev_ex()` to access a specific slot; the legacy `wolfIP_getdev()` helper targets the first hardware slot (index `0` normally, or `1` when the optional loopback interface is enabled).
3334

3435
### IP Configuration
3536
```c
3637
struct ipconf {
37-
struct ll *ll; // Link layer device
38+
struct wolfIP_ll_dev *ll; // Link layer device
3839
ip4 ip; // IPv4 address
3940
ip4 mask; // Subnet mask
4041
ip4 gw; // Default gateway
4142
};
4243
```
44+
Each `struct wolfIP` instance owns `WOLFIP_MAX_INTERFACES` `ipconf` entries—one per link-layer slot. Use the `_ex` helpers to read or update a specific interface; the legacy accessors operate on the first hardware interface (index `0` unless loopback support is compiled in).
45+
46+
If `WOLFIP_ENABLE_FORWARDING` is set to `1` at compile time, the stack performs simple IPv4 forwarding between interfaces. Packets received on one interface whose destinations match another configured interface are re-sent with the IP TTL decreased by one (or an ICMP TTL-exceeded response if the TTL would drop to zero).
47+
48+
Enabling `WOLFIP_ENABLE_LOOPBACK` (requires `WOLFIP_MAX_INTERFACES > 1`) creates an internal loopback
49+
device at index `0` with the fixed address `127.0.0.1/8`. Traffic sent to that address is reflected back
50+
through the stack so local sockets, pings, and other services behave as they would on a standard
51+
loopback interface; the first hardware interface then shifts to index `1` for legacy helpers.
4352

4453
### Socket Address Structures
4554
```c
@@ -151,6 +160,11 @@ Initializes a static wolfIP instance.
151160
- Parameters:
152161
- s: Pointer to wolfIP instance pointer
153162
163+
```c
164+
size_t wolfIP_instance_size(void);
165+
```
166+
Returns the size (in bytes) required to store a `struct wolfIP`. Use this when allocating stacks from custom memory managers.
167+
154168
```c
155169
int wolfIP_poll(struct wolfIP *s, uint64_t now);
156170
```
@@ -160,6 +174,12 @@ Processes pending network events.
160174
- now: Current timestamp
161175
- Returns: Number of events processed
162176
177+
```c
178+
void wolfIP_recv(struct wolfIP *s, void *buf, uint32_t len);
179+
void wolfIP_recv_ex(struct wolfIP *s, unsigned int if_idx, void *buf, uint32_t len);
180+
```
181+
Pass inbound frames to the stack. `_ex` allows the caller to specify which interface slot produced the frame.
182+
163183
```c
164184
void wolfIP_ipconfig_set(struct wolfIP *s, ip4 ip, ip4 mask, ip4 gw);
165185
void wolfIP_ipconfig_get(struct wolfIP *s, ip4 *ip, ip4 *mask, ip4 *gw);
@@ -171,6 +191,18 @@ Set/get IP configuration.
171191
- mask: Subnet mask
172192
- gw: Default gateway
173193
194+
```c
195+
void wolfIP_ipconfig_set_ex(struct wolfIP *s, unsigned int if_idx, ip4 ip, ip4 mask, ip4 gw);
196+
void wolfIP_ipconfig_get_ex(struct wolfIP *s, unsigned int if_idx, ip4 *ip, ip4 *mask, ip4 *gw);
197+
```
198+
Per-interface versions of the IP configuration helpers. The legacy functions target interface `0`.
199+
200+
```c
201+
struct wolfIP_ll_dev *wolfIP_getdev(struct wolfIP *s);
202+
struct wolfIP_ll_dev *wolfIP_getdev_ex(struct wolfIP *s, unsigned int if_idx);
203+
```
204+
Access the link-layer descriptor(s) that should be wired to hardware drivers. `_ex` returns `NULL` if `if_idx` exceeds `WOLFIP_MAX_INTERFACES`.
205+
174206
## DHCP Client Functions
175207
176208
```c

0 commit comments

Comments
 (0)