当前位置:网站首页>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 .
边栏推荐
- How to convert XML to HL7
- Can yangjianyun's new media operation in 2021 bear all the expectations of the enterprise's private domain traffic demand?
- H265/webvr video web page without plug-in player easyplayer Solution to the problem of cumulative delay of FLV video played by JS
- [DB Bao 45] MySQL highly available mgr+consult architecture deployment
- How to save data to the greatest extent after deleting LV by misoperation under AIX?
- [2021 taac & Ti-One] FAQs related to preliminary round computing resources
- Live broadcast Preview - on April 1, I made an appointment with you to explore tcapulusdb with Tencent cloud
- [play with Tencent cloud] play with cloud database mysql
- The problem is as big as the middle stage
- [play Tencent cloud] experience and development of game multimedia engine (II)
猜你喜欢
![[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)

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

Why do you develop middleware when you are young? "You can choose your own way"
Using consistent hash algorithm in Presto to enhance the data cache locality of dynamic clusters

MySQL learning -- table structure of SQL test questions
随机推荐
2021-04-02: given a square or rectangular matrix, zigzag printing can be realized.
Go kit microservice integrates Promtheus to solve monitoring alarm problems
Live broadcast Preview - on April 1, I made an appointment with you to explore tcapulusdb with Tencent cloud
[play with Tencent cloud] play with cloud database mysql
Today, Tencent safety and SAIC Group officially announced!
Low education without food? As an old Android rookie in the past six years, I was the most difficult one
Building a cross public chain platform to solve DAPP development problems
Ramda 鲜为人知的一面
Tencent cloud database mysql:sql flow restriction
Introduction to koa (II) building the koa program
Why do you develop middleware when you are young? "You can choose your own way"
About with admin option and with grant option
Future banks need to think about today's structure with tomorrow's thinking
Comparison of similarities and differences between easynvr video edge computing gateway and easynvr software versions
zblog判断某个插件是否安装启用的内置函数代码
Swift array map/flatmap/compactmap/filter/reduce/chaining Usage Summary
Best practices for H5 page adaptation and wechat default font size
Contributed code to famous projects for the first time, a little nervous
Memory alignment in golang
让UPS“印象派用户”重新认识可靠性