之前聊过tcpdump 抓包原理,tcpdump使用packet 抓包,使用packet_map 完成零拷贝。但是这个零拷贝也有点假,何为假呢?从网卡到内存走的dma,哪能不能直接从dma拷贝到用户空间呢?? 使用dpdk直接从网卡中轮询数据?
如果使用现有的tcpip协议栈,反正内核态需要处理网络数据,那就将数据线从网卡缓存dma拷贝到内核态buff吧,然后再来一个所谓的零拷贝到用户空间吧。。。
在https://blog.cloudflare.com/sockmap-tcp-splicing-of-the-future/ 这篇文章中有相关介绍
怎样使用sockmap
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 },
好久不使用了。
ebpf是由bpf延伸过来;eBPF支持在用户态将C语言编写的一小段“内核代码”注入到内核中运行,注入时要先用llvm编译得到使用BPF指令集的elf文件,然后从elf文件中解析出可以注入内核的部分,最后用bpf_load_program方法完成注入。 用户态程序和注入到内核中的程序通过共用一个位于内核中map
实现通信。为了防止注入的代码导致内核崩溃,eBPF会对注入的代码进行严格检查,拒绝不合格的代码的注入。
BCC是一个python库,实现了map创建、代码编译、解析、注入等操作,使开发人员只需聚焦于用C语言开发要注入的内核代码
bpf
的系统调用,为用户态程序提供与内核中的eBPF进行交互的途径对于ebpf的使用:参考如下文章
原文:https://www.cnblogs.com/codestack/p/12723229.html