aleksandr.fedorov_itglobal.com created this revision.
aleksandr.fedorov_itglobal.com added reviewers: vmaffione, jhb, bz.

REVISION SUMMARY
  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.

TEST PLAN
  pkt-gen test through vlan beetween real machines over physical network to 
check first panic:
  
    1. Machine
    # ifconfig vlan create vlan10 vlandev ix0 up
    vlan0
    # pkt-gen -i vlan0 -f tx
    2. Machine 
    # ifconfig vlan create vlan10 vlandev ix0 up
    vlan0
    # pkt-gen -i vlan0 -f rx
  
  pkt-gen test beetween VM's on same machine to check the second panic:
  
    VM1:
    # ifconfig vlan create vlan10 vlandev vtnet0 up
    vlan0
    # pkt-gen -i vlan0 -f tx
    VM2:
    # ifconfig vlan create vlan10 vlandev vtnet0 up
    vlan0
    # pkt-gen -i vlan0 -f rx

REVISION DETAIL
  https://reviews.freebsd.org/D20824

AFFECTED FILES
  sys/dev/netmap/netmap_freebsd.c

CHANGE DETAILS

diff --git a/sys/dev/netmap/netmap_freebsd.c b/sys/dev/netmap/netmap_freebsd.c
--- a/sys/dev/netmap/netmap_freebsd.c
+++ b/sys/dev/netmap/netmap_freebsd.c
@@ -444,6 +444,7 @@
        m->m_ext.ext_size = len;
 #endif /* __FreeBSD_version >= 1100000 */
 
+       m->m_flags |= M_PKTHDR;
        m->m_len = m->m_pkthdr.len = len;
 
        /* mbuf refcnt is not contended, no need to use atomic
@@ -452,7 +453,9 @@
        M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE);
        m->m_pkthdr.flowid = a->ring_nr;
        m->m_pkthdr.rcvif = ifp; /* used for tx notification */
+       CURVNET_SET(ifp->if_vnet);
        ret = NA(ifp)->if_transmit(ifp, m);
+       CURVNET_RESTORE();
        return ret ? -1 : 0;
 }
 



EMAIL PREFERENCES
  https://reviews.freebsd.org/settings/panel/emailpreferences/

To: aleksandr.fedorov_itglobal.com, vmaffione, jhb, bz
Cc: krion, evgueni.gavrilov_itglobal.com, freebsd-net-list
diff --git a/sys/dev/netmap/netmap_freebsd.c b/sys/dev/netmap/netmap_freebsd.c
--- a/sys/dev/netmap/netmap_freebsd.c
+++ b/sys/dev/netmap/netmap_freebsd.c
@@ -444,6 +444,7 @@
 	m->m_ext.ext_size = len;
 #endif /* __FreeBSD_version >= 1100000 */
 
+	m->m_flags |= M_PKTHDR;
 	m->m_len = m->m_pkthdr.len = len;
 
 	/* mbuf refcnt is not contended, no need to use atomic
@@ -452,7 +453,9 @@
 	M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE);
 	m->m_pkthdr.flowid = a->ring_nr;
 	m->m_pkthdr.rcvif = ifp; /* used for tx notification */
+	CURVNET_SET(ifp->if_vnet);
 	ret = NA(ifp)->if_transmit(ifp, m);
+	CURVNET_RESTORE();
 	return ret ? -1 : 0;
 }
 

_______________________________________________
freebsd-net@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"

Reply via email to