Reputation: 35
I am new to ebpf xdp and I wrote a program to analyse Packets coming into the network.
//This program is used to analyse network traffic (packet count, packet loss, latency and packet size).
//The required headers
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/in.h>
#include <bpf/bpf_helpers.h>
BPF_HASH(packet_count, struct iphdr*, u64);
BPF_HASH(packet_size, struct iphdr*, u64);
BPF_HASH(latency, struct iphdr*, u64);
BPF_HASH(packet_loss, struct iphdr*, u64);
SEC("packet_stats")
int monitor_packets(struct xdp_md *ctx){
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
struct iphdr *iph = data + sizeof(struct ethhdr);
if (iph + 1 > data_end) {
return XDP_PASS;
}
// Count the number of packets
u64 *count = packet_count.lookup(&iph);
if (count) {
*count += 1;
} else {
packet_count.insert(&iph, &(u64){1});
}
// Track the size of packets
u64 *size = packet_size.lookup(&iph);
if (size) {
*size += ntohs(iph->tot_len);
} else {
packet_size.insert(&iph, &(u64){ntohs(iph->tot_len)});
}
// Track the latency of packets
u64 *ts = latency.lookup(&iph);
if (ts) {
u64 now = bpf_ktime_get_ns();
*ts = now - *ts;
latency.delete(&iph);
} else {
u64 now = bpf_ktime_get_ns();
latency.insert(&iph, &now);
}
u64 *loss = packet_loss.lookup(&iph);
if (!value) {
packet_loss.insert(&key, &(u64){1});
} else {
(*value)++;
}
return XDP_PASS
}
char _license[] SEC("license") = "GPL";
I compiled the program using the below command
clang -O2 -target bpf -c demo.c -o demo.o
But I am getting the following error
BPF_HASH(packet_count, struct iphdr*, u64);
^
xdp_pass.c:10:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
BPF_HASH(packet_count, struct iphdr*, u64);
^
xdp_pass.c:11:23: error: expected identifier
BPF_HASH(packet_size, struct iphdr*, u64);
^
xdp_pass.c:11:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
BPF_HASH(packet_size, struct iphdr*, u64);
^
xdp_pass.c:12:19: error: expected identifier
BPF_HASH(latency, struct iphdr*, u64);
^
xdp_pass.c:12:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
BPF_HASH(latency, struct iphdr*, u64);
^
xdp_pass.c:13:23: error: expected identifier
BPF_HASH(packet_loss, struct iphdr*, u64);
^
xdp_pass.c:13:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
BPF_HASH(packet_loss, struct iphdr*, u64);
^
xdp_pass.c:22:13: warning: comparison of distinct pointer types ('struct iphdr *' and 'void *') [-Wcompare-distinct-pointer-types]
if (iph + 1 > data_end) {
~~~~~~~ ^ ~~~~~~~~
xdp_pass.c:27:1: error: use of undeclared identifier 'u64'
u64 *count = packet_count.lookup(&iph);
^
xdp_pass.c:27:6: error: use of undeclared identifier 'count'
u64 *count = packet_count.lookup(&iph);
^
xdp_pass.c:27:14: error: use of undeclared identifier 'packet_count'
u64 *count = packet_count.lookup(&iph);
^
xdp_pass.c:28:5: error: use of undeclared identifier 'count'
if (count) {
^
xdp_pass.c:29:6: error: use of undeclared identifier 'count'
*count += 1;
^
xdp_pass.c:31:5: error: use of undeclared identifier 'packet_count'
packet_count.insert(&iph, &(u64){1});
^
xdp_pass.c:31:33: error: use of undeclared identifier 'u64'
packet_count.insert(&iph, &(u64){1});
^
xdp_pass.c:35:1: error: use of undeclared identifier 'u64'
u64 *size = packet_size.lookup(&iph);
^
xdp_pass.c:35:6: error: use of undeclared identifier 'size'
u64 *size = packet_size.lookup(&iph);
^
xdp_pass.c:35:13: error: use of undeclared identifier 'packet_size'
u64 *size = packet_size.lookup(&iph);
^
xdp_pass.c:36:5: error: use of undeclared identifier 'size'
if (size) {
^
xdp_pass.c:37:14: warning: implicit declaration of function 'ntohs' is invalid in C99 [-Wimplicit-function-declaration]
*size += ntohs(iph->tot_len);
^
xdp_pass.c:37:6: error: use of undeclared identifier 'size'
*size += ntohs(iph->tot_len);
^
xdp_pass.c:39:5: error: use of undeclared identifier 'packet_size'
packet_size.insert(&iph, &(u64){ntohs(iph->tot_len)});
^
xdp_pass.c:39:32: error: use of undeclared identifier 'u64'
packet_size.insert(&iph, &(u64){ntohs(iph->tot_len)});
^
xdp_pass.c:43:1: error: use of undeclared identifier 'u64'
u64 *ts = latency.lookup(&iph);
^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
6 warnings and 20 errors generated.
I am not the best programmer so please don't mind shitty programming. Please suggest what I can do about this and where I am going wrong.
Upvotes: 0
Views: 548
Reputation: 13208
TL;DR. BPF_HASH
, packet_size.lookup
, latency.insert
, etc. are bcc constructs. If you want to use them, you will have to use bcc to compile and load your BPF program. If you don't want to use bcc, you will have to get rid of those bcc constructs or redefine them yourself.
You can find examples of how to load a BPF program with bcc in the official bcc tutorial. For example, you might do:
b = BPF(src_file="demo.c")
fn = b.load_func("packet_stats", BPF.XDP, None)
b.attach_xdp(device, fn, BPF.XDP_FLAGS_DRV_MODE)
See https://github.com/iovisor/bcc/blob/master/examples/networking/xdp/xdp_drop_count.py for a full example XDP program with bcc.
Upvotes: 1