之前聊过tcpdump 抓包原理,tcpdump使用packet 抓包,使用packet_map 完成零拷贝。但是这个零拷贝也有点假,何为假呢?从网卡到内存走的dma,哪能不能直接从dma拷贝到用户空间呢?? 使用dpdk直接从网卡中轮询数据?
如果使用现有的tcpip协议栈,反正内核态需要处理网络数据,那就将数据线从网卡缓存dma拷贝到内核态buff吧,然后再来一个所谓的零拷贝到用户空间吧。。。
在https://blog.cloudflare.com/sockmap-tcp-splicing-of-the-future/ 这篇文章中有相关介绍
怎样使用sockmap
SOCKMAP or specifically "BPF_MAP_TYPE_SOCKMAP", is a type of an eBPF map
bpf map 一个古老的东西,以前也没人管他,结构现在又整出新东西来了。对于之前使用bpf也就只有在packet socket 抓包过滤协议报文时才会使用,tcpdump -dd xxx 找出对应的bpf字节掩码或者tcpdump -d xxx 生成指令集
比如
1 root@fp:~# tcpdump -d -i ens33 tcp and port 80 2 (000) ldh [12] 3 (001) jeq #0x86dd jt 2 jf 8 4 (002) ldb [20] 5 (003) jeq #0x6 jt 4 jf 19 6 (004) ldh [54] 7 (005) jeq #0x50 jt 18 jf 6 8 (006) ldh [56] 9 (007) jeq #0x50 jt 18 jf 19 10 (008) jeq #0x800 jt 9 jf 19 11 (009) ldb [23] 12 (010) jeq #0x6 jt 11 jf 19 13 (011) ldh [20] 14 (012) jset #0x1fff jt 19 jf 13 15 (013) ldxb 4*([14]&0xf) 16 (014) ldh [x + 14] 17 (015) jeq #0x50 jt 18 jf 16 18 (016) ldh [x + 16] 19 (017) jeq #0x50 jt 18 jf 19 20 (018) ret #262144 21 (019) ret #0 22 root@fp:~# tcpdump -dd -i ens33 tcp and port 80 23 { 0x28, 0, 0, 0x0000000c }, 24 { 0x15, 0, 6, 0x000086dd }, 25 { 0x30, 0, 0, 0x00000014 }, 26 { 0x15, 0, 15, 0x00000006 }, 27 { 0x28, 0, 0, 0x00000036 }, 28 { 0x15, 12, 0, 0x00000050 }, 29 { 0x28, 0, 0, 0x00000038 }, 30 { 0x15, 10, 11, 0x00000050 }, 31 { 0x15, 0, 10, 0x00000800 }, 32 { 0x30, 0, 0, 0x00000017 }, 33 { 0x15, 0, 8, 0x00000006 }, 34 { 0x28, 0, 0, 0x00000014 }, 35 { 0x45, 6, 0, 0x00001fff }, 36 { 0xb1, 0, 0, 0x0000000e }, 37 { 0x48, 0, 0, 0x0000000e }, 38 { 0x15, 2, 0, 0x00000050 }, 39 { 0x48, 0, 0, 0x00000010 }, 40 { 0x15, 0, 1, 0x00000050 }, 41 { 0x6, 0, 0, 0x00040000 }, 42 { 0x6, 0, 0, 0x00000000 },