Skip to content

Commit c62da14

Browse files
committed
Merge branch 'richiejp-cgroup'
2 parents 269d15e + 62687f8 commit c62da14

8 files changed

+192
-42
lines changed

.editorconfig

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# EditorConfig file
2+
# https://editorconfig.org/
3+
4+
# C settings
5+
[*.c]
6+
indent_style = space
7+
indent_size = 2
8+
tab_width = 2
9+
end_of_line = lf
10+
insert_final_newline = true
11+
trim_trailing_whitespace = true
12+
max_line_length = 80
13+
charset = utf-8
14+
15+
# Go settings
16+
[*.go]
17+
indent_style = tab
18+
indent_size = 2
19+
tab_width = 2
20+
end_of_line = lf
21+
insert_final_newline = true
22+
trim_trailing_whitespace = true
23+
max_line_length = 80
24+
charset = utf-8

counter.c

+75-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2020
// SOFTWARE.
2121

22-
// go:build ignore
22+
//go:build ignore
2323

2424
#include "vmlinux.h"
2525

@@ -45,6 +45,7 @@
4545

4646
#define OK 1
4747
#define NOK 0
48+
#define ALLOW_PKT 1
4849

4950
// Map key struct for IP traffic
5051
typedef struct statkey_t {
@@ -237,6 +238,7 @@ static inline void process_eth(void *data, void *data_end, __u64 pkt_len) {
237238

238239
// validate Ethernet size
239240
if ((void *)eth + sizeof(*eth) > data_end) {
241+
bpf_printk("size validation failure");
240242
return;
241243
}
242244

@@ -265,6 +267,7 @@ static inline void process_eth(void *data, void *data_end, __u64 pkt_len) {
265267
break;
266268
}
267269
default:
270+
bpf_printk("wrong packet type: %d", eth->h_proto);
268271
return;
269272
}
270273

@@ -281,6 +284,63 @@ static inline void process_eth(void *data, void *data_end, __u64 pkt_len) {
281284
}
282285
}
283286

287+
/**
288+
* Process SKB as it is seen by the cgroup, which is without the ethernet
289+
* headers
290+
*
291+
* @param skb The CGroup skb
292+
*
293+
* @return none
294+
*
295+
* @throws none
296+
*/
297+
static inline void process_cgroup_skb(struct __sk_buff *skb) {
298+
void *data = (void *)(long)skb->data;
299+
void *data_end = (void *)(long)skb->data_end;
300+
__u64 pkt_len = skb->len;
301+
302+
// initialize key
303+
statkey key;
304+
__builtin_memset(&key, 0, sizeof(key));
305+
306+
switch (bpf_ntohs(skb->protocol)) {
307+
case ETH_P_IP: {
308+
struct iphdr *ip4 = data;
309+
310+
if (process_ip4(ip4, data_end, &key) == NOK) {
311+
return;
312+
}
313+
314+
break;
315+
}
316+
case ETH_P_IPV6: {
317+
struct ipv6hdr *ip6 = data;
318+
319+
if (process_ip6(ip6, data_end, &key) == NOK) {
320+
return;
321+
}
322+
323+
break;
324+
}
325+
default:
326+
bpf_printk("wrong packet type: %d", skb->protocol);
327+
return;
328+
329+
}
330+
331+
// lookup value in hash
332+
statvalue *val = (statvalue *)bpf_map_lookup_elem(&pkt_count, &key);
333+
if (val) {
334+
// atomic XADD, doesn't need bpf_spin_lock()
335+
__sync_fetch_and_add(&val->packets, 1);
336+
__sync_fetch_and_add(&val->bytes, pkt_len);
337+
} else {
338+
statvalue initval = {.packets = 1, .bytes = pkt_len};
339+
340+
bpf_map_update_elem(&pkt_count, &key, &initval, BPF_NOEXIST);
341+
}
342+
}
343+
284344
/**
285345
* Process the packet for traffic control and take necessary actions.
286346
*
@@ -352,6 +412,20 @@ int tc_count_packets(struct __sk_buff *skb) {
352412
return TC_ACT_UNSPEC;
353413
}
354414

415+
SEC("cgroup_skb/ingress")
416+
int cgroup_skb_ingress(struct __sk_buff *skb) {
417+
process_cgroup_skb(skb);
418+
419+
return ALLOW_PKT;
420+
}
421+
422+
SEC("cgroup_skb/egress")
423+
int cgroup_skb_egress(struct __sk_buff *skb) {
424+
process_cgroup_skb(skb);
425+
426+
return ALLOW_PKT;
427+
}
428+
355429
/**
356430
* Process TCP socket information and populate the key structure with
357431
* extracted data.

counter_arm64_bpfel.go

+26-20
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

counter_arm64_bpfel.o

6.29 KB
Binary file not shown.

counter_x86_bpfel.go

+26-20
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

counter_x86_bpfel.o

6.28 KB
Binary file not shown.

flags.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const (
4040
)
4141

4242
var (
43-
ifname, xdpMode *string
43+
ifname, xdpMode, useCGroup *string
4444
jsonOutput, version, help, useXDP, useKProbes, enableTUI *bool
4545
timeout, refresh *time.Duration
4646
xdpAttachFlags link.XDPAttachFlags
@@ -51,6 +51,7 @@ func parseFags() {
5151

5252
help = fs.Bool('?', "help", "display help")
5353
jsonOutput = fs.Bool('j', "json", "if true, output in JSON format")
54+
useCGroup = fs.String('c', "cgroup", "", "the path to a CGroup V2 to measure statistics on")
5455
useXDP = fs.Bool('x', "xdp", "if true, use XDP instead of TC (this disables egress statistics)")
5556
useKProbes = fs.Bool('k', "kprobes", "if true, use KProbes for per-proces TCP/UDP statistics")
5657
enableTUI = fs.Bool('g', "tui", "if true, enable TUI")

main.go

+39
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ func main() {
6868
}()
6969

7070
switch {
71+
case *useCGroup != "":
72+
links = startCgroup(objs, *useCGroup, links)
7173
// KProbes w/ PID tracking
7274
case *useKProbes:
7375
hooks := []kprobeHook{
@@ -289,3 +291,40 @@ func startTC(objs counterObjects, iface *net.Interface, links []link.Link) []lin
289291

290292
return links
291293
}
294+
295+
func startCgroup(objs counterObjects, cgroupPath string, links []link.Link) []link.Link {
296+
var l link.Link
297+
298+
err := features.HaveProgramType(ebpf.CGroupSKB)
299+
if errors.Is(err, ebpf.ErrNotSupported) {
300+
log.Fatalf("CgroupSKB not supported on this kernel")
301+
}
302+
303+
if err != nil {
304+
log.Fatalf("Error checking CGroupSKB support: %v", err)
305+
}
306+
307+
l, err = link.AttachCgroup(link.CgroupOptions{
308+
Program: objs.CgroupSkbIngress,
309+
Attach: ebpf.AttachCGroupInetIngress,
310+
Path: cgroupPath,
311+
})
312+
if err != nil {
313+
log.Fatalf("Error attaching CgroupSkbIngress to %s: %v", cgroupPath, err)
314+
}
315+
316+
l, err = link.AttachCgroup(link.CgroupOptions{
317+
Program: objs.CgroupSkbEgress,
318+
Attach: ebpf.AttachCGroupInetEgress,
319+
Path: cgroupPath,
320+
})
321+
if err != nil {
322+
log.Fatalf("Error attaching CgroupSkbEgress to %s: %v", cgroupPath, err)
323+
}
324+
325+
links = append(links, l)
326+
327+
log.Printf("Starting on CGroup %s", cgroupPath)
328+
329+
return links
330+
}

0 commit comments

Comments
 (0)