Skip to content

Commit eb29076

Browse files
committed
Added simple packet forwarding between interfaces
1 parent 4173749 commit eb29076

File tree

10 files changed

+1350
-43
lines changed

10 files changed

+1350
-43
lines changed

.github/workflows/linux.yml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,21 @@ jobs:
1919
- name: Update repo
2020
run: |
2121
sudo apt-get update
22+
sudo apt-get install -y libwolfssl-dev
2223
sudo modprobe tun
2324
2425
- name: Build linux tests
2526
run: |
2627
mkdir -p build/port
2728
make
2829
29-
# - name: Run interop tests
30-
# run: |
31-
# sudo build/test
32-
#
33-
#
30+
- name: Run unit tests
31+
run: make unit
32+
33+
- name: Run standalone tests
34+
run: |
35+
sudo ./build/test-evloop
36+
sudo ./build/test-wolfssl
37+
./build/test-wolfssl-forwarding
38+
./build/test-ttl-expired
39+

Makefile

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ OBJ=build/wolfip.o \
2020
build/port/posix/linux_tap.o
2121

2222
EXE=build/tcpecho build/tcp_netcat_poll build/tcp_netcat_select \
23-
build/test-evloop build/test-dns
23+
build/test-evloop build/test-dns build/test-wolfssl-forwarding \
24+
build/test-ttl-expired build/test-wolfssl
2425
LIB=libwolfip.so
2526

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

8182
build/test-wolfssl:CFLAGS+=-Wno-cpp -DWOLFSSL_DEBUG -DWOLFSSL_WOLFIP
8283
build/test-httpd:CFLAGS+=-Wno-cpp -DWOLFSSL_DEBUG -DWOLFSSL_WOLFIP -Isrc/http
84+
build/test-wolfssl-forwarding:CFLAGS+=-Wno-cpp -DWOLFSSL_DEBUG -DWOLFSSL_WOLFIP -DWOLFIP_MAX_INTERFACES=2 -DWOLFIP_ENABLE_FORWARDING=1
8385

8486

8587
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
8688
@echo "[LD] $@"
8789
@$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -Wl,--start-group $(^) -lwolfssl -Wl,--end-group
8890

91+
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
92+
@echo "[LD] $@"
93+
@$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -Wl,--start-group $(^) -lwolfssl -Wl,--end-group
94+
95+
build/test/test_wolfssl_forwarding.o: CFLAGS+=-DWOLFIP_MAX_INTERFACES=2 -DWOLFIP_ENABLE_FORWARDING=1
96+
97+
build/test/wolfip_forwarding.o: src/wolfip.c
98+
@mkdir -p `dirname $@` || true
99+
@echo "[CC] $< (forwarding)"
100+
@$(CC) $(CFLAGS) -DWOLFIP_MAX_INTERFACES=2 -DWOLFIP_ENABLE_FORWARDING=1 -c $< -o $@
101+
102+
build/test/test_ttl_expired.o: CFLAGS+=-DWOLFIP_MAX_INTERFACES=2 -DWOLFIP_ENABLE_FORWARDING=1
103+
build/test-ttl-expired: build/test/test_ttl_expired.o build/test/wolfip_forwarding.o
104+
@echo "[LD] $@"
105+
@$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -Wl,--start-group $(^) -Wl,--end-group
106+
89107
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
90108
@echo "[LD] $@"
91109
@$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -Wl,--start-group $(^) -lwolfssl -Wl,--end-group

config.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
#define WOLFIP_MAX_INTERFACES 1
1616
#endif
1717

18+
#ifndef WOLFIP_ENABLE_FORWARDING
19+
#define WOLFIP_ENABLE_FORWARDING 0
20+
#endif
21+
1822
/* Linux test configuration */
1923
#define WOLFIP_IP "10.10.10.2"
2024
#define LINUX_IP "10.10.10.1"

docs/API.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ struct ipconf {
4343
```
4444
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 index `0` for backwards compatibility.
4545

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+
4648
### Socket Address Structures
4749
```c
4850
struct wolfIP_sockaddr_in {
@@ -153,6 +155,11 @@ Initializes a static wolfIP instance.
153155
- Parameters:
154156
- s: Pointer to wolfIP instance pointer
155157
158+
```c
159+
size_t wolfIP_instance_size(void);
160+
```
161+
Returns the size (in bytes) required to store a `struct wolfIP`. Use this when allocating stacks from custom memory managers.
162+
156163
```c
157164
int wolfIP_poll(struct wolfIP *s, uint64_t now);
158165
```

src/port/wolfssl_io.c

Lines changed: 72 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
/* wolfssl_io.c
2-
*
3-
* Copyright (C) 2024 wolfSSL Inc.
2+
* Copyright (C) 2025 wolfSSL Inc.
43
*
54
* This file is part of wolfIP TCP/IP stack.
65
*
@@ -17,39 +16,77 @@
1716
* You should have received a copy of the GNU General Public License
1817
* along with this program; if not, write to the Free Software
1918
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
19+
*
20+
* wolfIP <-> wolfSSL glue for custom IO callbacks.
2021
*/
2122
#include "wolfip.h"
2223
#include <wolfssl/wolfcrypt/settings.h>
2324
#include <wolfssl/ssl.h>
25+
#include <wolfssl/wolfcrypt/memory.h>
26+
27+
#define MAX_WOLFIP_CTX 8
28+
29+
struct ctx_entry {
30+
WOLFSSL_CTX *ctx;
31+
struct wolfIP *stack;
32+
};
33+
34+
struct wolfip_io_desc {
35+
int fd;
36+
struct wolfIP *stack;
37+
};
2438

25-
static struct wolfIP *ref_ipstack = NULL;
39+
static struct ctx_entry ctx_map[MAX_WOLFIP_CTX];
40+
static struct wolfip_io_desc io_descs[MAX_WOLFIP_CTX];
41+
42+
static struct wolfIP *wolfIP_lookup_stack(WOLFSSL_CTX *ctx)
43+
{
44+
for (int i = 0; i < MAX_WOLFIP_CTX; i++) {
45+
if (ctx_map[i].ctx == ctx)
46+
return ctx_map[i].stack;
47+
}
48+
return NULL;
49+
}
50+
51+
static void wolfIP_register_stack(WOLFSSL_CTX *ctx, struct wolfIP *stack)
52+
{
53+
for (int i = 0; i < MAX_WOLFIP_CTX; i++) {
54+
if (ctx_map[i].ctx == ctx || ctx_map[i].ctx == NULL) {
55+
ctx_map[i].ctx = ctx;
56+
ctx_map[i].stack = stack;
57+
return;
58+
}
59+
}
60+
}
2661

2762
static int wolfIP_io_recv(WOLFSSL* ssl, char* buf, int sz, void* ctx)
2863
{
29-
int ret = 0;
30-
int fd = (intptr_t)ctx;
64+
struct wolfip_io_desc *desc = (struct wolfip_io_desc *)ctx;
3165
(void)ssl;
32-
if (!ref_ipstack)
33-
return -1;
34-
ret = wolfIP_sock_recv(ref_ipstack, fd, buf, sz, 0);
35-
if (ret == -11)
66+
67+
if (!desc || !desc->stack)
68+
return WOLFSSL_CBIO_ERR_GENERAL;
69+
70+
int ret = wolfIP_sock_recv(desc->stack, desc->fd, buf, sz, 0);
71+
if (ret == -11 || ret == -1)
3672
return WOLFSSL_CBIO_ERR_WANT_READ;
37-
else if (ret <= 0)
73+
if (ret <= 0)
3874
return WOLFSSL_CBIO_ERR_CONN_CLOSE;
3975
return ret;
4076
}
4177

4278
static int wolfIP_io_send(WOLFSSL* ssl, char* buf, int sz, void* ctx)
4379
{
44-
int ret = 0;
45-
int fd = (intptr_t)ctx;
80+
struct wolfip_io_desc *desc = (struct wolfip_io_desc *)ctx;
4681
(void)ssl;
47-
if (!ref_ipstack)
48-
return -1;
49-
ret = wolfIP_sock_send(ref_ipstack, fd, buf, sz, 0);
50-
if (ret == -11)
82+
83+
if (!desc || !desc->stack)
84+
return WOLFSSL_CBIO_ERR_GENERAL;
85+
86+
int ret = wolfIP_sock_send(desc->stack, desc->fd, buf, sz, 0);
87+
if (ret == -11 || ret == -1)
5188
return WOLFSSL_CBIO_ERR_WANT_WRITE;
52-
else if (ret <= 0)
89+
if (ret <= 0)
5390
return WOLFSSL_CBIO_ERR_CONN_CLOSE;
5491
return ret;
5592
}
@@ -58,14 +95,27 @@ int wolfSSL_SetIO_wolfIP_CTX(WOLFSSL_CTX* ctx, struct wolfIP *s)
5895
{
5996
wolfSSL_SetIORecv(ctx, wolfIP_io_recv);
6097
wolfSSL_SetIOSend(ctx, wolfIP_io_send);
61-
ref_ipstack = s;
98+
wolfIP_register_stack(ctx, s);
6299
return 0;
63100
}
64101

65102
int wolfSSL_SetIO_wolfIP(WOLFSSL* ssl, int fd)
66103
{
67-
wolfSSL_SetIOReadCtx(ssl, (void*)(intptr_t)fd);
68-
wolfSSL_SetIOWriteCtx(ssl, (void*)(intptr_t)fd);
69-
return 0;
70-
}
104+
WOLFSSL_CTX *ctx = wolfSSL_get_SSL_CTX(ssl);
105+
struct wolfIP *stack = wolfIP_lookup_stack(ctx);
106+
107+
if (!stack)
108+
return WOLFSSL_CBIO_ERR_GENERAL;
71109

110+
for (int i = 0; i < MAX_WOLFIP_CTX; i++) {
111+
if (io_descs[i].stack == NULL) {
112+
io_descs[i].fd = fd;
113+
io_descs[i].stack = stack;
114+
wolfSSL_SetIOReadCtx(ssl, &io_descs[i]);
115+
wolfSSL_SetIOWriteCtx(ssl, &io_descs[i]);
116+
return 0;
117+
}
118+
}
119+
120+
return -1;
121+
}

0 commit comments

Comments
 (0)