当前位置:网站首页>Use BPF to count network traffic
Use BPF to count network traffic
2022-06-24 17:23:00 【ritchiechen】
This paper introduces the use of BPF Count network traffic . Network traffic is an important billing indicator of cloud products , The server can process millions of packets per second , This also requires efficient methods to count traffic , and BPF Technology originally handled as a network packet , Traffic processing designed and constructed to support this rate .
Use libpcap
stay BPF Times before , We can use libpcap Realization and tcpdump In a similar way , Capture network traffic and copy it to the user program for statistics .
Here is a simple example :
#define ETHERNET_HEADER_LEN 14
#define MIN_IP_HEADER_LEN 20
#define IP_HL(ip) (((ip)->ihl) & 0x0f)
const char* dev = "br-7e20abc6df31";
const char* filter_expr = "src net 172.20.0.0/16";
int64_t traffic = 0;
// Reference:
// https://www.tcpdump.org/manpages/
// https://tools.ietf.org/html/rfc791
void traffic_stat() {
// find the IPv4 network number and netmask for a device
bpf_u_int32 net = 0;
bpf_u_int32 mask = 0;
char errbuf[PCAP_ERRBUF_SIZE] = {0};
int ret = pcap_lookupnet(dev, &net, &mask, errbuf);
if (ret == PCAP_ERROR) {
fprintf(stderr, "pcap_lookupnet failed: %s\n", errbuf);
exit(EXIT_FAILURE);
}
// open a device for capturing
int promisc = 1;
int timeout = 1000; // in milliseconds
const int SNAP_LEN = 64;
auto handle = pcap_open_live(dev, SNAP_LEN, promisc, timeout, errbuf);
if (!handle) {
fprintf(stderr, "pcap_open_live failed: %s\n", errbuf);
exit(EXIT_FAILURE);
}
// compile a filter expression
struct bpf_program fp;
int optimize = 1;
ret = pcap_compile(handle, &fp, filter_expr, optimize, net);
if (ret == PCAP_ERROR) {
fprintf(stderr, "pcap_compile failed: %s\n", pcap_geterr(handle));
exit(EXIT_FAILURE);
}
// set the filter
ret = pcap_setfilter(handle, &fp);
if (ret == PCAP_ERROR) {
fprintf(stderr, "pcap_setfilter failed: %s\n", pcap_geterr(handle));
exit(EXIT_FAILURE);
}
// process packets from a live capture
int packet_count = -1; // -1 means infinity
pcap_loop(handle, packet_count, [](u_char* args, const struct pcap_pkthdr* header, const u_char* bytes) {
auto ip_header = reinterpret_cast<iphdr*>(const_cast<u_char*>(bytes) + ETHERNET_HEADER_LEN);
const int ip_header_len = IP_HL(ip_header) * 4;
if (ip_header_len < MIN_IP_HEADER_LEN) {
return;
}
auto len = ntohs(ip_header->tot_len);
if (len <= 0) {
return;
}
auto traffic = reinterpret_cast<int64_t*>(args);
*traffic += len;
}, reinterpret_cast<u_char*>(&traffic));
// free a BPF program
pcap_freecode(&fp);
// close the capture device
pcap_close(handle);
}br-7e20abc6df31 It's using Docker Created bridge ,IP yes 172.20.0.1, Use src net 172.20.0.0/16 Expression to filter outbound traffic .
This program can do the right thing , Namely, statistical flow . The problem lies in , It needs to copy all the traffic flowing through the network card to the user program , Then the statistics are carried out , These copies are then discarded , A lot of system resources are wasted .
Big killer BPF
and BPF Obviously the perfect solution to this problem . All we need is to accumulate outbound traffic , If it can be executed in kernel mode , That means we don't need to copy network packets .
Here is a use libbpf Written program , Its function is similar to the above libpcap Consistent role :
#include <vmlinux.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
int ifindex = 0;
__u64 traffic = 0;
SEC("tp_btf/netif_receive_skb")
int BPF_PROG(netif_receive_skb, struct sk_buff *skb)
{
if (skb->dev->ifindex == ifindex) {
traffic += skb->data_len;
}
return 0;
}
char LICENSE[] SEC("license") = "GPL"; here ,ifindex That is, the above network equipment br-7e20abc6df31 Interface index of .
In this program , We attached it to netif_receive_skb This tracepoint On , After the network card receives the packet , We judge whether it is the target device , if , Then accumulate the flow . No data copies , No context switch , A simple and efficient .
actual combat
Use dd Create a 512M Size file :
$ dd if=/dev/zero of=/tmp/testfile bs=4096 count=131072
Create a new network device :
$ sudo docker network create my-tc-net
Use the network created above to run a nginx The server , Provide file download :
$ sudo docker run -d --rm \
-p 10086:80 \
-v /tmp/testfile:/home/data/testfile \
-v $(PWD)/default.conf:/etc/nginx/conf.d/default.conf \
--name my-nginx \
--network my-tc-net \
nginx:alpineThis is our server configuration :
server {
listen 80;
listen [::]:80;
server_name localhost;
location /downloads/ {
alias /home/data/;
}
}Run the above flow statistics program :
$ sudo ./trafficstat
Download the file :
$ curl http://localhost:10086/downloads/testfile --output testfile
View traffic statistics output :
$ sudo ./trafficstat ... traffic in bytes: 536878816 ...
In line with expectations , Be accomplished . The source code of this article can be found in here find .
Conclusion
This article demonstrates the use of libbpf To write BPF Program , A scheme to achieve efficient statistics of network traffic in the kernel state .
边栏推荐
- Cloud development environment to create a five-star development experience
- zblog系统实现前台调用当天发布文章数量的教程
- Coding enhances security vulnerability scanning capability and helps the team "move left safely"
- [play with Tencent cloud] play with cloud database mysql
- Cloud native monitoring via blackbox_ Exporter monitoring website
- Go kit microservice integrates Promtheus to solve monitoring alarm problems
- Low education without food? As an old Android rookie in the past six years, I was the most difficult one
- IBM: supporting AI and enterprise digital reshaping in the cloud era with modern architecture
- Comparison of similarities and differences between easynvr video edge computing gateway and easynvr software versions
- test
猜你喜欢

Daily algorithm & interview questions, 28 days of special training in large factories - the 15th day (string)

MySQL learning -- table structure of SQL test questions
Using consistent hash algorithm in Presto to enhance the data cache locality of dynamic clusters

Why do you develop middleware when you are young? "You can choose your own way"
![[leetcode108] convert an ordered array into a binary search tree (medium order traversal)](/img/e1/0fac59a531040d74fd7531e2840eb5.jpg)
[leetcode108] convert an ordered array into a binary search tree (medium order traversal)
随机推荐
"Competition" and "opportunity" hidden in security operation in the cloud Era
[play with Tencent cloud] check 9 popular Tencent cloud products
TVP experts talk about geese factory middleware: innovating forward and meeting the future
How to perform concurrent stress testing on RTSP video streams distributed by audio and video streaming servers?
GB gb28181 video cascading intelligent analysis platform easygbs broadcast video console error 401
"Gambler" bubble Matt turns around
[go language development] start to develop Meitu station from 0 - Lesson 5 [receive pictures and upload]
zblog系统实现前台调用当天发布文章数量的教程
The TKE cluster node reports an error when executing kubectl
Let ups "Impressionist users" re understand reliability
test
How to learn go language happily? Let's go!
Building a cross public chain platform to solve DAPP development problems
04. Tencent cloud IOT device side learning - network connection and device authentication
Jmeter+grafana+influxdb build a visual performance test monitoring platform
How to troubleshoot and solve the problem that the ultra-low delay security live broadcast system webrtc client plays no audio in the browser?
Zabix5.0-0 - agent2 monitoring MariaDB database (Linux based)
Learn typescript with VAM (phase 1)
Development analysis of main chain system
zblog判断某个插件是否安装启用的内置函数代码