Skip to content

Commit 86e0f76

Browse files
committed
CM4: VIMAGE feasibility PoC - enable VNET-based per-stack isolation (route B validated)
- opt_global.h: enable VIMAGE; compile net/vnet.c + netinet/tcp_ecn.c - ff_vimage_glue.c: minimal prison_owns_vnet (verbatim from kern_jail.c), avoids pulling the 141KB kern_jail.c and its jail subsystem deps - ff_stub_14_extra.c: drop ECN stub globals/no-op stubs; real tcp_ecn.c takes over - ff_freebsd_init.c: pin main thread td_vnet=vnet0 after mi_startup so V_* resolve under curvnet (fixes SIGSEGV at sysctl on curvnet=NULL) - ECN switch: new [freebsd] tcp_ecn config (default 0=off, zero-regression; 1=passive ECN). V_tcp_do_ecn set after td_vnet bind. Runtime PoC (thread_mode=0): vnet0 auto-bootstrap OK, vnet data segment relocation OK, lo 127.0.0.1 OK, DPDK 9.134.214.176:80 curl HTTP 200. Gates: build PASS (0 error, 51 warning == baseline), review PASS (zero-regression), unit tests 199/199 PASS. Per-thread td_vnet is CM5.
1 parent e79ceb9 commit 86e0f76

9 files changed

Lines changed: 148 additions & 54 deletions

File tree

lib/Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,8 @@ FF_SRCS+= \
282282
ff_vfs_ops.c \
283283
ff_veth.c \
284284
ff_route.c \
285-
ff_stub_14_extra.c
285+
ff_stub_14_extra.c \
286+
ff_vimage_glue.c
286287

287288
ifdef FF_NETGRAPH
288289
FF_SRCS+= \
@@ -440,7 +441,8 @@ NET_SRCS+= \
440441
nhop.c \
441442
nhop_ctl.c \
442443
rtsock.c \
443-
slcompress.c
444+
slcompress.c \
445+
vnet.c
444446

445447
ifdef FF_NETGRAPH
446448
NETGRAPH_SRCS += \
@@ -520,6 +522,7 @@ NETINET_SRCS+= \
520522
tcp_timer.c \
521523
tcp_timewait.c \
522524
tcp_usrreq.c \
525+
tcp_ecn.c \
523526
udp_usrreq.c \
524527
cc.c \
525528
cc_newreno.c \

lib/ff_config.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,8 @@ ini_parse_handler(void* user, const char* section, const char* name,
11081108
pconfig->freebsd.fd_reserve = atoi(value);
11091109
} else if (strcmp(name, "memsz_MB") == 0) {
11101110
pconfig->freebsd.mem_size = atoi(value);
1111+
} else if (strcmp(name, "tcp_ecn") == 0) {
1112+
pconfig->freebsd.tcp_ecn = atoi(value);
11111113
} else {
11121114
return freebsd_conf_handler(pconfig, "boot", name, value);
11131115
}
@@ -1514,6 +1516,7 @@ ff_default_config(struct ff_config *cfg)
15141516
cfg->freebsd.physmem = 1048576*256;
15151517
cfg->freebsd.fd_reserve = 0;
15161518
cfg->freebsd.mem_size = 256;
1519+
cfg->freebsd.tcp_ecn = 0;
15171520

15181521
cfg->log.level = FF_LOG_DISABLE;
15191522
cfg->log.dir = strdup(FF_LOG_FILENAME_PREFIX);

lib/ff_config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ struct ff_config {
359359
int hz;
360360
int fd_reserve;
361361
int mem_size;
362+
int tcp_ecn; /* 0=disable ECN (default, zero-regression); 1=passive ECN (upstream default 2) */
362363
} freebsd;
363364

364365
struct {

lib/ff_freebsd_init.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,11 @@
5252
#include <net/if.h>
5353
#include <net/if_var.h>
5454
#include <net/if_private.h>
55+
#include <net/vnet.h>
5556
#include <netinet/in_var.h>
57+
#include <netinet/in_pcb.h>
58+
#include <netinet/tcp.h>
59+
#include <netinet/tcp_var.h>
5660

5761
int lo_set_defaultaddr(void);
5862

@@ -178,6 +182,22 @@ ff_freebsd_init(void)
178182

179183
mutex_init();
180184
mi_startup();
185+
186+
/*
187+
* CM4 PoC: vnet_init_done clears curvnet at boot end (FreeBSD design).
188+
* Under VIMAGE all V_* go through curvnet, so pin the main thread to
189+
* vnet0 for the whole thread_mode=0 single-thread path (sysctl loop,
190+
* lo_set_defaultaddr, ff_run/main_loop). Per-thread td_vnet is CM5.
191+
*/
192+
curthread->td_vnet = vnet0;
193+
194+
/*
195+
* ECN switch (default off for zero-regression vs CM0-3). Real tcp_ecn.c
196+
* defaults V_tcp_do_ecn=2 (passive ECN); apply the config value here,
197+
* after td_vnet=vnet0 so V_* resolves. 0=off, 1=passive(=2).
198+
*/
199+
V_tcp_do_ecn = ff_global_cfg.freebsd.tcp_ecn ? 2 : 0;
200+
181201
sx_init(&proctree_lock, "proctree");
182202
ff_fdused_range(ff_global_cfg.freebsd.fd_reserve);
183203

lib/ff_stub_14_extra.c

Lines changed: 5 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -572,57 +572,11 @@ int sendfile_wait_generic(struct sendfile_sync *sfs, int *err)
572572
return (0);
573573
}
574574

575-
int tcp_do_ecn = 2;
576-
577-
void tcp_ecn_input_parallel_syn(struct tcpcb *tp, uint16_t thflags, int iptos);
578-
void tcp_ecn_input_parallel_syn(struct tcpcb *tp, uint16_t thflags, int iptos)
579-
{
580-
581-
}
582-
583-
int tcp_ecn_input_segment(struct tcpcb *tp, uint16_t thflags, int tlen, int pkts_acked, int iptos);
584-
int tcp_ecn_input_segment(struct tcpcb *tp, uint16_t thflags, int tlen, int pkts_acked, int iptos)
585-
{
586-
return (0);
587-
}
588-
589-
void tcp_ecn_input_syn_sent(struct tcpcb *tp, uint16_t thflags, int iptos);
590-
void tcp_ecn_input_syn_sent(struct tcpcb *tp, uint16_t thflags, int iptos)
591-
{
592-
593-
}
594-
595-
int tcp_ecn_maxretries = 1;
596-
597-
int tcp_ecn_output_established(struct tcpcb *tp, uint16_t *thflags, int len, bool rxmit);
598-
int tcp_ecn_output_established(struct tcpcb *tp, uint16_t *thflags, int len, bool rxmit)
599-
{
600-
return (0);
601-
}
602-
603-
uint16_t tcp_ecn_output_syn_sent(struct tcpcb *tp);
604-
uint16_t tcp_ecn_output_syn_sent(struct tcpcb *tp)
605-
{
606-
return (0);
607-
}
608-
609-
void tcp_ecn_syncache_add(struct syncache *sc, int iptos, uint16_t thflags);
610-
void tcp_ecn_syncache_add(struct syncache *sc, int iptos, uint16_t thflags)
611-
{
612-
613-
}
614-
615-
uint16_t tcp_ecn_syncache_respond(uint16_t thflags, struct syncache *sc);
616-
uint16_t tcp_ecn_syncache_respond(uint16_t thflags, struct syncache *sc)
617-
{
618-
return (thflags);
619-
}
620-
621-
void tcp_ecn_syncache_socket(struct tcpcb *tp, struct syncache *sc);
622-
void tcp_ecn_syncache_socket(struct tcpcb *tp, struct syncache *sc)
623-
{
624-
625-
}
575+
/*
576+
* ECN stubs (tcp_do_ecn/tcp_ecn_maxretries + 8 tcp_ecn_* no-ops) removed:
577+
* under VIMAGE V_tcp_do_ecn needs the real VNET_DEFINE segment symbols,
578+
* provided by the now-compiled freebsd/netinet/tcp_ecn.c.
579+
*/
626580

627581
void (*tcp_hpts_softclock)(void) = NULL;
628582

lib/ff_vimage_glue.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright (C) 2017-2021 THL A29 Limited, a Tencent company.
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
*
8+
* 1. Redistributions of source code must retain the above copyright notice, this
9+
* list of conditions and the following disclaimer.
10+
* 2. Redistributions in binary form must reproduce the above copyright notice,
11+
* this list of conditions and the following disclaimer in the documentation
12+
* and/or other materials provided with the distribution.
13+
*
14+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18+
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+
*
25+
*/
26+
27+
/*
28+
* VIMAGE glue layer (CM4).
29+
*
30+
* Enabling VIMAGE makes V_* macros resolve through the set_vnet segment and
31+
* pulls in a small number of symbols from kern_jail.c's #ifdef VIMAGE block
32+
* that are not otherwise compiled into libfstack. Compiling the whole 141KB
33+
* kern_jail.c is infeasible here (it #includes opt_nfs.h and drags the entire
34+
* jail/osd/racct subsystem). This file provides only the minimal necessary
35+
* symbol, copied verbatim from FreeBSD kern/kern_jail.c:4048, to avoid that
36+
* connected dependency explosion.
37+
*/
38+
39+
#include <sys/param.h>
40+
#include <sys/jail.h>
41+
42+
/*
43+
* Determine whether the prison owns its VNET.
44+
*/
45+
bool
46+
prison_owns_vnet(struct prison *pr)
47+
{
48+
49+
/*
50+
* vnets cannot be added/removed after jail creation,
51+
* so no need to lock here.
52+
*/
53+
return ((pr->pr_flags & PR_VNET) != 0);
54+
}

lib/opt/opt_global.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
#define RWLOCK_NOINLINE 1
33
#define SX_NOINLINE 1
44
#define DEV_RANDOM 1
5-
#define NO_EVENTTIMERS 1
5+
#define NO_EVENTTIMERS 1
6+
#define VIMAGE 1
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
; CM4 ECN config switch: tcp_ecn lives in [freebsd.boot] (ff_config.c:1111).
2+
; tcp_ecn=1 -> freebsd.tcp_ecn parsed as 1 (runtime maps to V_tcp_do_ecn=2).
3+
[dpdk]
4+
lcore_mask=1
5+
channel=4
6+
promiscuous=1
7+
numa_on=1
8+
port_list=0
9+
10+
[port0]
11+
addr=192.168.1.10
12+
netmask=255.255.255.0
13+
broadcast=192.168.1.255
14+
gateway=192.168.1.1
15+
16+
[freebsd.boot]
17+
hz=100
18+
physmem=268435456
19+
fd_reserve=1024
20+
mem_size=256
21+
tcp_ecn=1
22+
23+
[freebsd.sysctl]
24+
kern.ipc.maxsockbuf=16777216

tests/unit/test_ff_config.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,6 +1206,37 @@ test_ff_load_config_thread_mode_secondary_conflict(void **state)
12061206
assert_int_equal(rv, -1);
12071207
}
12081208

1209+
/* ======================================================================== */
1210+
/* CM4 (native-mt): ECN config switch (freebsd.tcp_ecn, [freebsd.boot] key) */
1211+
/* Spec: native_mt_spec/zh_cn. Parse @ff_config.c:1111, default 0 @:1519. */
1212+
/* Runtime maps tcp_ecn -> V_tcp_do_ecn (0=off / 1=passive) in */
1213+
/* ff_freebsd_init.c; that runtime effect is out of unit-test scope. */
1214+
/* ======================================================================== */
1215+
1216+
/* TC-CM4-01: no tcp_ecn key -> defaults to 0 (zero-regression). */
1217+
static void
1218+
test_ff_load_config_tcp_ecn_default_off(void **state)
1219+
{
1220+
(void)state;
1221+
/* valid_minimal.ini has [freebsd.boot] but NO tcp_ecn key. */
1222+
int rv = load_with_fixture(FIXTURE_PATH("valid_minimal.ini"));
1223+
(void)rv;
1224+
assert_int_equal(ff_global_cfg.freebsd.tcp_ecn, 0);
1225+
}
1226+
1227+
/* TC-CM4-02: explicit tcp_ecn=1 in [freebsd.boot] -> parsed as 1. */
1228+
static void
1229+
test_ff_load_config_tcp_ecn_enabled(void **state)
1230+
{
1231+
(void)state;
1232+
int rv = load_with_fixture(FIXTURE_PATH("valid_tcp_ecn.ini"));
1233+
(void)rv;
1234+
assert_int_equal(ff_global_cfg.freebsd.tcp_ecn, 1);
1235+
/* New key must not disturb sibling [freebsd.boot] parsing. */
1236+
assert_int_equal(ff_global_cfg.freebsd.hz, 100);
1237+
assert_int_equal(ff_global_cfg.freebsd.mem_size, 256);
1238+
}
1239+
12091240
int
12101241
main(void)
12111242
{
@@ -1280,6 +1311,9 @@ main(void)
12801311
cmocka_unit_test_setup_teardown(test_ff_load_config_thread_mode_enabled, test_setup, NULL),
12811312
cmocka_unit_test_setup_teardown(test_ff_load_config_thread_mode_default_off, test_setup, NULL),
12821313
cmocka_unit_test_setup_teardown(test_ff_load_config_thread_mode_secondary_conflict, test_setup, NULL),
1314+
/* CM4 (native-mt) ECN config switch (freebsd.tcp_ecn) */
1315+
cmocka_unit_test_setup_teardown(test_ff_load_config_tcp_ecn_default_off, test_setup, NULL),
1316+
cmocka_unit_test_setup_teardown(test_ff_load_config_tcp_ecn_enabled, test_setup, NULL),
12831317
#ifdef FF_KERNEL_COEXIST
12841318
/* kernel_event_support: [stack] kernel_coexist */
12851319
cmocka_unit_test_setup_teardown(test_ff_load_config_stack_coexist_enabled, test_setup, NULL),

0 commit comments

Comments
 (0)