blob: a62f80d79b6f8d194e5fe18ac6ecc47d48cd820d [file] [log] [blame]
Brenden Blanco561dafc2015-06-29 11:09:00 -07001#!/usr/bin/env python
2# Copyright (c) PLUMgrid, Inc.
3# Licensed under the Apache License, Version 2.0 (the "License")
4
Brenden Blancoc35989d2015-09-02 18:04:07 -07005from bcc import BPF
Brenden Blanco561dafc2015-06-29 11:09:00 -07006from unittest import main, TestCase
7
8class TestClang(TestCase):
9 def test_complex(self):
10 b = BPF(src_file="test_clang_complex.c", debug=0)
11 fn = b.load_func("handle_packet", BPF.SCHED_CLS)
12 def test_printk(self):
13 text = """
14#include <bcc/proto.h>
15int handle_packet(void *ctx) {
Brenden Blanco6ec65e42015-07-02 10:02:04 -070016 u8 *cursor = 0;
17 struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
18 bpf_trace_printk("ethernet->dst = %llx, ethernet->src = %llx\\n",
19 ethernet->dst, ethernet->src);
Brenden Blanco561dafc2015-06-29 11:09:00 -070020 return 0;
21}
22"""
23 b = BPF(text=text, debug=0)
24 fn = b.load_func("handle_packet", BPF.SCHED_CLS)
25
Brenden Blancob711d452015-07-01 15:23:18 -070026 def test_probe_read1(self):
27 text = """
28#include <linux/sched.h>
29#include <uapi/linux/ptrace.h>
30int count_sched(struct pt_regs *ctx, struct task_struct *prev) {
31 pid_t p = prev->pid;
32 return (p != -1);
33}
34"""
35 b = BPF(text=text, debug=0)
36 fn = b.load_func("count_sched", BPF.KPROBE)
37
38 def test_probe_read2(self):
39 text = """
40#include <linux/sched.h>
41#include <uapi/linux/ptrace.h>
42int count_foo(struct pt_regs *ctx, unsigned long a, unsigned long b) {
43 return (a != b);
44}
45"""
46 b = BPF(text=text, debug=0)
47 fn = b.load_func("count_foo", BPF.KPROBE)
48
Brenden Blanco3c4a29c2015-09-08 22:16:10 -070049 def test_probe_read_keys(self):
50 text = """
51#include <uapi/linux/ptrace.h>
52#include <linux/blkdev.h>
53BPF_HASH(start, struct request *);
54int do_request(struct pt_regs *ctx, struct request *req) {
55 u64 ts = bpf_ktime_get_ns();
56 start.update(&req, &ts);
57 return 0;
58}
59
60int do_completion(struct pt_regs *ctx, struct request *req) {
61 u64 *tsp = start.lookup(&req);
62 if (tsp != 0) {
63 start.delete(&req);
64 }
65 return 0;
66}
67"""
68 b = BPF(text=text, debug=0)
69 fns = b.load_funcs(BPF.KPROBE)
70
Brenden Blanco00ee4fe2015-08-07 21:04:35 -070071 def test_sscanf(self):
Brenden Blanco52b0a902015-08-07 08:28:02 -070072 text = """
Brenden Blanco985adf62015-08-08 21:00:59 -070073BPF_TABLE("hash", int, struct { u64 a; u64 b; u64 c:36; u64 d:28; struct { u32 a; u32 b; } s; }, stats, 10);
Brenden Blanco52b0a902015-08-07 08:28:02 -070074int foo(void *ctx) {
75 return 0;
76}
77"""
78 b = BPF(text=text, debug=0)
79 fn = b.load_func("foo", BPF.KPROBE)
Brenden Blanco985adf62015-08-08 21:00:59 -070080 t = b.get_table("stats")
Brenden Blanco2582ecf2015-08-12 12:08:00 -070081 s1 = t.key_sprintf(t.Key(2))
82 self.assertEqual(s1, b"0x2")
83 s2 = t.leaf_sprintf(t.Leaf(2, 3, 4, 1, (5, 6)))
84 l = t.leaf_scanf(s2)
Brenden Blanco985adf62015-08-08 21:00:59 -070085 self.assertEqual(l.a, 2)
86 self.assertEqual(l.b, 3)
87 self.assertEqual(l.c, 4)
88 self.assertEqual(l.d, 1)
89 self.assertEqual(l.s.a, 5)
90 self.assertEqual(l.s.b, 6)
Brenden Blanco52b0a902015-08-07 08:28:02 -070091
Brenden Blancodfcdf0a2015-08-11 12:45:00 -070092 def test_iosnoop(self):
93 text = """
94#include <linux/blkdev.h>
95#include <uapi/linux/ptrace.h>
96
97struct key_t {
98 struct request *req;
99};
100
101BPF_TABLE("hash", struct key_t, u64, start, 1024);
102int do_request(struct pt_regs *ctx, struct request *req) {
103 struct key_t key = {};
104
105 bpf_trace_printk("traced start %d\\n", req->__data_len);
106
107 return 0;
108}
109"""
110 b = BPF(text=text, debug=0)
111 fn = b.load_func("do_request", BPF.KPROBE)
112
Brenden Blancoa328d232015-08-11 18:33:49 -0700113 def test_blk_start_request(self):
114 text = """
115#include <linux/blkdev.h>
116#include <uapi/linux/ptrace.h>
117int do_request(struct pt_regs *ctx, int req) {
118 bpf_trace_printk("req ptr: 0x%x\\n", req);
119 return 0;
120}
121"""
122 b = BPF(text=text, debug=0)
123 fn = b.load_func("do_request", BPF.KPROBE)
124
Brenden Blanco7b9e5f12015-09-05 21:54:59 -0700125 def test_bpf_hash(self):
126 text = """
127BPF_HASH(table1);
128BPF_HASH(table2, u32);
129BPF_HASH(table3, u32, int);
130"""
131 b = BPF(text=text, debug=0)
132
Brenden Blanco70fa0a12015-09-15 15:46:26 -0700133 def test_consecutive_probe_read(self):
134 text = """
135#include <linux/fs.h>
136#include <linux/mount.h>
137BPF_HASH(table1, struct super_block *);
138int trace_entry(struct pt_regs *ctx, struct file *file) {
139 if (!file) return 0;
140 struct vfsmount *mnt = file->f_path.mnt;
141 if (mnt) {
142 struct super_block *k = mnt->mnt_sb;
143 u64 zero = 0;
144 table1.update(&k, &zero);
145 k = mnt->mnt_sb;
146 table1.update(&k, &zero);
147 }
148
149 return 0;
150}
151"""
152 b = BPF(text=text, debug=0)
153 fn = b.load_func("trace_entry", BPF.KPROBE)
154
155 def test_nested_probe_read(self):
156 text = """
157#include <linux/fs.h>
158int trace_entry(struct pt_regs *ctx, struct file *file) {
159 if (!file) return 0;
160 const char *name = file->f_path.dentry->d_name.name;
161 bpf_trace_printk("%s\\n", name);
162 return 0;
163}
164"""
165 b = BPF(text=text, debug=0)
166 fn = b.load_func("trace_entry", BPF.KPROBE)
167
Brenden Blanco9518e742015-09-16 14:06:06 -0700168 def test_char_array_probe(self):
169 BPF(text="""#include <linux/blkdev.h>
170int kprobe__blk_update_request(struct pt_regs *ctx, struct request *req) {
171 bpf_trace_printk("%s\\n", req->rq_disk->disk_name);
172 return 0;
173}""")
174
Brenden Blanco561dafc2015-06-29 11:09:00 -0700175if __name__ == "__main__":
176 main()