It is very useful to be able to create virtual networks, such as: VM1 - VALE switch - if_vlan - ix0 -- physical network -- ix0 - if_vlan - VALE switch - VM2.
This patch fixes two panic.
First panic:
root@current:~ # ifconfig vlan create vlan 1024 vlandev vtnet0 up
vlan0
root@current:~ # pkt-gen -i vlan0 -f tx
611.182750 main [2889] interface is vlan0
611.183004 main [3011] using default burst size: 512
611.183021 main [3019] running on 1 cpus (have 4)
611.185667 extract_ip_range [471] range is 10.0.611.186530 [1129] generic_netmap_attach Emulated adapter for vlan0 created (prev was 0)
0.1:1234 to 10.0.0.1:1234
611.185897 extract_ip_range [471] range is 10.1.0.1:1234 to 10.1.0.1:1234
611.185980 nm_open [858] overriding ARG1 0
611.186215 nm_open [862] overriding ARG2 0
611.186227 nm_open [866] overriding ARG3 0
611.186237 nm_open [870] overriding RING_CFG
611.186248 nm_open [879] overriding ifname vlan0 ringid 0x0 flags 0x8001
611.385901 [ 320] generic_netmap_register Emulated adapter for vlan0 activated
611.387781 main [3117] mapped 334980KB at 0x800e00000
Sending on netmap:vlan0: 1 queues, 1 threads and 1 cpus.
10.0.0.1 -> 10.1.0.1 (00:00:00:00:00:00 -> ff:ff:ff:ff:ff:ff)
611.389515 main [3224] Sending 512 packets every 0.000000000 s
611.389636 start_threads [2549] Wait 2 secs for phy reset
613.435285 start_threads [2551] Ready...
613.435737 sender_body [1580] start, fd 3 main_fd 3
613.436545 sender_body [1638] frags 1 frag_
Fatal trap 12: page fault while in kernel mode
cpuid = 1; apic id = 01
fault virtual address = 0x28
fault code = supervisor read data, page not present
instruction pointer = 0x20:0xffffffff80cd5f2e
stack pointer = 0x28:0xfffffe001971d520
frame pointer = 0x28:0xfffffe001971d550
code segment = base 0x0, limit 0xfffff, type 0x1b
= DPL 0, pres 1, long 1, def32 0, gran 1
processor eflags = interrupt enabled, resume, IOPL = 0
current process = 732 (pkt-gen)
trap number = 12
panic: page fault
cpuid = 1
time = 1561989613
KDB: stack backtrace:
db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe001971d1e0
vpanic() at vpanic+0x19d/frame 0xfffffe001971d230
panic() at panic+0x43/frame 0xfffffe001971d290
trap_fatal() at trap_fatal+0x39c/frame 0xfffffe001971d2f0
trap_pfault() at trap_pfault+0x62/frame 0xfffffe001971d340
trap() at trap+0x2b4/frame 0xfffffe001971d450
calltrap() at calltrap+0x8/frame 0xfffffe001971d450
--- trap 0xc, rip = 0xffffffff80cd5f2e, rsp = 0xfffffe001971d520, rbp = 0xfffffe001971d550 ---
ether_8021q_frame() at ether_8021q_frame+0x2e/frame 0xfffffe001971d550
vlan_transmit() at vlan_transmit+0xd4/frame 0xfffffe001971d5c0
nm_os_generic_xmit_frame() at nm_os_generic_xmit_frame+0x48/frame 0xfffffe001971d5d0
generic_netmap_txsync() at generic_netmap_txsync+0x25d/frame 0xfffffe001971d6a0
netmap_poll() at netmap_poll+0x324/frame 0xfffffe001971d770
freebsd_netmap_poll() at freebsd_netmap_poll+0x32/frame 0xfffffe001971d7a0
devfs_poll_f() at devfs_poll_f+0x71/frame 0xfffffe001971d7f0
kern_poll() at kern_poll+0x3d9/frame 0xfffffe001971d970
sys_poll() at sys_poll+0x50/frame 0xfffffe001971d990
amd64_syscall() at amd64_syscall+0x276/frame 0xfffffe001971dab0
fast_syscall_common() at fast_syscall_common+0x101/frame 0xfffffe001971dab0
--- syscall (209, FreeBSD ELF64, sys_poll), rip = 0x8004943aa, rsp = 0x7fffdfffde48, rbp = 0x7fffdfffde80 ---
KDB: enter: panic
[ thread pid 732 tid 100137 ]
Stopped at kdb_enter+0x3b: movq $0,kdb_why
db>Netmap generic directly calls the if_transmit method of the underlying driver (https://svnweb.freebsd.org/base/head/sys/dev/netmap/netmap_freebsd.c?revision=348022&view=markup#l455). Panic occurs at https://svnweb.freebsd.org/base/head/sys/net/if_ethersubr.c?revision=348254&view=markup#l1371 due to the fact that the current VNET is not set. The panic disappears if the VIMAGE option is disabled in the config.
To correct this panic, set the current VNET to the driver VNET.
The second panic:
root@current:~ # pkt-gen -i vlan0 -f tx 372.565904 main [2889] interface is vlan0 372.566203 main [3011] using default burst size: 512 372.566513 main [3019] running on 1 cpus (have 4) 372.568995 extract_ip_range [471] range is 10.0.0.1:1234 to 10.0.0.1:1234 372.569272 extract_ip_range [471] ran372.571191 [1129] generic_netmap_attach Emulated adapter for vlan0 created (prev was 0) ge is 10.1.0.1:1234 to 10.1.0.1:1234 372.569632 nm_open [858] overriding ARG1 0 372.569930 nm_open [862] overriding ARG2 0 372.570231 nm_open [866] overriding ARG3 0 372.570534 nm_open [870] overriding RING_CFG 372.570863 nm_open [879] overriding ifname vlan0 ringid 0x0 flags 0x8001 372.785305 [ 320] generic_netmap_register Emulated adapter for vlan0 activated 372.787260 main [3117] mapped 334980KB at 0x800e00000 Sending on netmap:vlan0: 1 queues, 1 threads and 1 cpus. 10.0.0.1 -> 10.1.0.1 (00:00:00:00:00:00 -> ff:ff:ff:ff:ff:ff) 372.788704 main [3224] Sending 512 packets every 0.000000000 s 372.789062 start_threads [2549] Wait 2 secs for phy reset 374.865353 start_threads [2551] Ready... 374.866365 sender_body [1580] start, fd 3 main_fd 3 374.866666 sender_body [1638] frags 1 frag_size 60 panic: vtnet_txq_encap: no mbuf packet header! cpuid = 0 time = 1561994374 KDB: stack backtrace: db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe0019732380 vpanic() at vpanic+0x19d/frame 0xfffffe00197323d0 panic() at panic+0x43/frame 0xfffffe0019732430 vtnet_txq_encap() at vtnet_txq_encap+0x3ba/frame 0xfffffe00197324a0 vtnet_txq_mq_start_locked() at vtnet_txq_mq_start_locked+0x126/frame 0xfffffe0019732500 vtnet_txq_mq_start() at vtnet_txq_mq_start+0x70/frame 0xfffffe0019732540 vlan_transmit() at vlan_transmit+0xe6/frame 0xfffffe00197325b0 nm_os_generic_xmit_frame() at nm_os_generic_xmit_frame+0x78/frame 0xfffffe00197325d0 generic_netmap_txsync() at generic_netmap_txsync+0x25d/frame 0xfffffe00197326a0 netmap_poll() at netmap_poll+0x324/frame 0xfffffe0019732770 freebsd_netmap_poll() at freebsd_netmap_poll+0x32/frame 0xfffffe00197327a0 devfs_poll_f() at devfs_poll_f+0x71/frame 0xfffffe00197327f0 kern_poll() at kern_poll+0x3d9/frame 0xfffffe0019732970 sys_poll() at sys_poll+0x50/frame 0xfffffe0019732990 amd64_syscall() at amd64_syscall+0x276/frame 0xfffffe0019732ab0 fast_syscall_common() at fast_syscall_common+0x101/frame 0xfffffe0019732ab0 --- syscall (209, FreeBSD ELF64, sys_poll), rip = 0x8004943aa, rsp = 0x7fffdfffde48, rbp = 0x7fffdfffde80 --- KDB: enter: panic [ thread pid 779 tid 100113 ] Stopped at kdb_enter+0x3b: movq $0,kdb_why db>
Netmap uses a preallocated array of mbuf's to send packets through the underlying driver. These mbuf's are allocated and initialized during the creation of the netmap adapter, in particular, the M_PKTHDR flag is set for them. After completing sending, netmap tries to reuse these mbuf's, but some network drivers (if_vlan, if_vxlan) may reset the M_PKTHDR flag. This leads to a panic on M_ASSERTPKTHDR (m) at line: https://svnweb.freebsd.org/base/head/sys/dev/virtio/network/if_vtnet.c?revision=348599&view=markup#l2201
To fix the second panic, restore M_PKTHDR flag before call if_transmit method.