Skip to content

Commit f043e56

Browse files
committed
Added IPv6 packets counter
1 parent 30cf1c9 commit f043e56

File tree

3 files changed

+82
-27
lines changed

3 files changed

+82
-27
lines changed

counter.c

+33-14
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,22 @@
33
#include <linux/bpf.h>
44
#include <linux/if_ether.h>
55
#include <linux/ip.h>
6+
#include <linux/ipv6.h>
67
#include "headers/bpf_helpers.h"
78

89
struct {
910
__uint(type, BPF_MAP_TYPE_HASH);
1011
__type(key, __be32);
1112
__type(value, __u64);
1213
__uint(max_entries, 1024);
13-
} pkt_count SEC(".maps");
14+
} ipv4_counter_map SEC(".maps");
15+
16+
struct {
17+
__uint(type, BPF_MAP_TYPE_HASH);
18+
__type(key, struct in6_addr);
19+
__type(value, __u64);
20+
__uint(max_entries, 1024);
21+
} ipv6_counter_map SEC(".maps");
1422

1523
SEC("xdp")
1624
int xdp_ip_packet_counter(struct xdp_md* ctx) {
@@ -20,19 +28,30 @@ int xdp_ip_packet_counter(struct xdp_md* ctx) {
2028
if ((void*)(eth + 1) > data_end) {
2129
return XDP_PASS;
2230
}
23-
if (eth->h_proto != __constant_htons(ETH_P_IP)) {
24-
return XDP_PASS;
25-
}
26-
struct iphdr *ip = (struct iphdr*)(eth + 1);
27-
if ((void*)(ip + 1) > data_end) {
28-
return XDP_PASS;
29-
}
30-
__u64 *count, init_val = 1;
31-
count = bpf_map_lookup_elem(&pkt_count, &ip->saddr);
32-
if (count) {
33-
__sync_fetch_and_add(count, 1);
34-
} else {
35-
bpf_map_update_elem(&pkt_count, &ip->saddr, &init_val, BPF_ANY);
31+
if (eth->h_proto == __constant_htons(ETH_P_IP)) {
32+
struct iphdr *ip = (struct iphdr*)(eth + 1);
33+
if ((void*)(ip + 1) > data_end) {
34+
return XDP_PASS;
35+
}
36+
__u64 *count, init_val = 1;
37+
count = bpf_map_lookup_elem(&ipv4_counter_map, &ip->saddr);
38+
if (count) {
39+
__sync_fetch_and_add(count, 1);
40+
} else {
41+
bpf_map_update_elem(&ipv4_counter_map, &ip->saddr, &init_val, BPF_ANY);
42+
}
43+
} else if (eth->h_proto == __constant_htons(ETH_P_IPV6)) {
44+
struct ipv6hdr *ip6 = (struct ipv6hdr*)(eth + 1);
45+
if ((void*)(ip6 + 1) > data_end) {
46+
return XDP_PASS;
47+
}
48+
__u64 *count, init_val = 1;
49+
count = bpf_map_lookup_elem(&ipv6_counter_map, &ip6->saddr);
50+
if (count) {
51+
__sync_fetch_and_add(count, 1);
52+
} else {
53+
bpf_map_update_elem(&ipv6_counter_map, &ip6->saddr, &init_val, BPF_ANY);
54+
}
3655
}
3756
return XDP_PASS;
3857
}

counter.o

2.43 KB
Binary file not shown.

main.go

+49-13
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,52 @@ import (
1616

1717
const bpfProgramPath = "counter.o"
1818

19-
func ipToString(ip uint32) net.IP {
19+
func ip4ToString(ip uint32) net.IP {
2020
address := make(net.IP, 4)
2121
binary.LittleEndian.PutUint32(address, ip)
2222
return address
2323
}
2424

25+
func ip6ToString(ip [16]byte) string {
26+
return net.IP(ip[:]).String()
27+
}
28+
29+
func printMap(m *ebpf.Map, ipToString func(interface{}) string) {
30+
iter := m.Iterate()
31+
var ip interface{}
32+
var count uint64
33+
for iter.Next(&ip, &count) {
34+
fmt.Printf("%s: %d packets\n", ipToString(ip), count)
35+
}
36+
if err := iter.Err(); err != nil {
37+
fmt.Printf("Error iterating map: %v\n", err)
38+
}
39+
}
40+
41+
func printIPv4Map(m *ebpf.Map) {
42+
iter := m.Iterate()
43+
var ip uint32
44+
var count uint64
45+
for iter.Next(&ip, &count) {
46+
fmt.Printf(" %s: %d packets\n", ip4ToString(ip), count)
47+
}
48+
if err := iter.Err(); err != nil {
49+
fmt.Printf("Error iterating map: %v\n", err)
50+
}
51+
}
52+
53+
func printIPv6Map(m *ebpf.Map) {
54+
iter := m.Iterate()
55+
var ip [16]byte
56+
var count uint64
57+
for iter.Next(&ip, &count) {
58+
fmt.Printf(" %s: %d packets\n", ip6ToString(ip), count)
59+
}
60+
if err := iter.Err(); err != nil {
61+
fmt.Printf("Error iterating map: %v\n", err)
62+
}
63+
}
64+
2565
func main() {
2666
if len(os.Args) < 3 || os.Args[1] != "-count" {
2767
fmt.Println("Usage: ./ebpf-packet-filter -count <interface_name>")
@@ -39,9 +79,10 @@ func main() {
3979
log.Fatal("Failed to create BPF collection:", err)
4080
}
4181
defer collection.Close()
42-
ipMap := collection.Maps["pkt_count"]
43-
if ipMap == nil {
44-
log.Fatal("Failed to find pkt_count map in the BPF program")
82+
ip4Map := collection.Maps["ipv4_counter_map"]
83+
ip6Map := collection.Maps["ipv6_counter_map"]
84+
if ip4Map == nil || ip6Map == nil {
85+
log.Fatal("Failed to find required map in the BPF program")
4586
}
4687
ifname := os.Args[2]
4788
iface, err := net.InterfaceByName(ifname)
@@ -68,15 +109,10 @@ func main() {
68109
for {
69110
select {
70111
case <-tick:
71-
iter := ipMap.Iterate()
72-
var ip uint32
73-
var count uint64
74-
for iter.Next(&ip, &count) {
75-
log.Printf("%s: %d packets\n", ipToString(ip), count)
76-
}
77-
if err := iter.Err(); err != nil {
78-
log.Fatal("Error iterating map:", err)
79-
}
112+
fmt.Println("IPv4 Packets count:")
113+
printIPv4Map(ip4Map)
114+
fmt.Println("IPv6 Packets count:")
115+
printIPv6Map(ip6Map)
80116
case <-stop:
81117
log.Println("Received signal, exiting...")
82118
return

0 commit comments

Comments
 (0)