aboutsummaryrefslogtreecommitdiffstats
path: root/samples
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@plumgrid.com>2015-06-12 22:39:12 -0400
committerDavid S. Miller <davem@davemloft.net>2015-06-15 18:53:50 -0400
commitffeedafbf0236f03aeb2e8db273b3e5ae5f5bc89 (patch)
treee00f1b0bba1c217afbcf4dda00ef950afdfcafbc /samples
parentada6c1de9ecabcfc5619479bcd29a208f2e248a0 (diff)
bpf: introduce current->pid, tgid, uid, gid, comm accessors
eBPF programs attached to kprobes need to filter based on current->pid, uid and other fields, so introduce helper functions: u64 bpf_get_current_pid_tgid(void) Return: current->tgid << 32 | current->pid u64 bpf_get_current_uid_gid(void) Return: current_gid << 32 | current_uid bpf_get_current_comm(char *buf, int size_of_buf) stores current->comm into buf They can be used from the programs attached to TC as well to classify packets based on current task fields. Update tracex2 example to print histogram of write syscalls for each process instead of aggregated for all. Signed-off-by: Alexei Starovoitov <ast@plumgrid.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'samples')
-rw-r--r--samples/bpf/bpf_helpers.h6
-rw-r--r--samples/bpf/tracex2_kern.c24
-rw-r--r--samples/bpf/tracex2_user.c67
3 files changed, 83 insertions, 14 deletions
diff --git a/samples/bpf/bpf_helpers.h b/samples/bpf/bpf_helpers.h
index f531a0b3282d..bdf1c1607b80 100644
--- a/samples/bpf/bpf_helpers.h
+++ b/samples/bpf/bpf_helpers.h
@@ -25,6 +25,12 @@ static void (*bpf_tail_call)(void *ctx, void *map, int index) =
25 (void *) BPF_FUNC_tail_call; 25 (void *) BPF_FUNC_tail_call;
26static unsigned long long (*bpf_get_smp_processor_id)(void) = 26static unsigned long long (*bpf_get_smp_processor_id)(void) =
27 (void *) BPF_FUNC_get_smp_processor_id; 27 (void *) BPF_FUNC_get_smp_processor_id;
28static unsigned long long (*bpf_get_current_pid_tgid)(void) =
29 (void *) BPF_FUNC_get_current_pid_tgid;
30static unsigned long long (*bpf_get_current_uid_gid)(void) =
31 (void *) BPF_FUNC_get_current_uid_gid;
32static int (*bpf_get_current_comm)(void *buf, int buf_size) =
33 (void *) BPF_FUNC_get_current_comm;
28 34
29/* llvm builtin functions that eBPF C program may use to 35/* llvm builtin functions that eBPF C program may use to
30 * emit BPF_LD_ABS and BPF_LD_IND instructions 36 * emit BPF_LD_ABS and BPF_LD_IND instructions
diff --git a/samples/bpf/tracex2_kern.c b/samples/bpf/tracex2_kern.c
index 19ec1cfc45db..dc50f4f2943f 100644
--- a/samples/bpf/tracex2_kern.c
+++ b/samples/bpf/tracex2_kern.c
@@ -62,11 +62,18 @@ static unsigned int log2l(unsigned long v)
62 return log2(v); 62 return log2(v);
63} 63}
64 64
65struct hist_key {
66 char comm[16];
67 u64 pid_tgid;
68 u64 uid_gid;
69 u32 index;
70};
71
65struct bpf_map_def SEC("maps") my_hist_map = { 72struct bpf_map_def SEC("maps") my_hist_map = {
66 .type = BPF_MAP_TYPE_ARRAY, 73 .type = BPF_MAP_TYPE_HASH,
67 .key_size = sizeof(u32), 74 .key_size = sizeof(struct hist_key),
68 .value_size = sizeof(long), 75 .value_size = sizeof(long),
69 .max_entries = 64, 76 .max_entries = 1024,
70}; 77};
71 78
72SEC("kprobe/sys_write") 79SEC("kprobe/sys_write")
@@ -75,11 +82,18 @@ int bpf_prog3(struct pt_regs *ctx)
75 long write_size = ctx->dx; /* arg3 */ 82 long write_size = ctx->dx; /* arg3 */
76 long init_val = 1; 83 long init_val = 1;
77 long *value; 84 long *value;
78 u32 index = log2l(write_size); 85 struct hist_key key = {};
86
87 key.index = log2l(write_size);
88 key.pid_tgid = bpf_get_current_pid_tgid();
89 key.uid_gid = bpf_get_current_uid_gid();
90 bpf_get_current_comm(&key.comm, sizeof(key.comm));
79 91
80 value = bpf_map_lookup_elem(&my_hist_map, &index); 92 value = bpf_map_lookup_elem(&my_hist_map, &key);
81 if (value) 93 if (value)
82 __sync_fetch_and_add(value, 1); 94 __sync_fetch_and_add(value, 1);
95 else
96 bpf_map_update_elem(&my_hist_map, &key, &init_val, BPF_ANY);
83 return 0; 97 return 0;
84} 98}
85char _license[] SEC("license") = "GPL"; 99char _license[] SEC("license") = "GPL";
diff --git a/samples/bpf/tracex2_user.c b/samples/bpf/tracex2_user.c
index 91b8d0896fbb..cd0241c1447a 100644
--- a/samples/bpf/tracex2_user.c
+++ b/samples/bpf/tracex2_user.c
@@ -3,6 +3,7 @@
3#include <stdlib.h> 3#include <stdlib.h>
4#include <signal.h> 4#include <signal.h>
5#include <linux/bpf.h> 5#include <linux/bpf.h>
6#include <string.h>
6#include "libbpf.h" 7#include "libbpf.h"
7#include "bpf_load.h" 8#include "bpf_load.h"
8 9
@@ -20,23 +21,42 @@ static void stars(char *str, long val, long max, int width)
20 str[i] = '\0'; 21 str[i] = '\0';
21} 22}
22 23
23static void print_hist(int fd) 24struct task {
25 char comm[16];
26 __u64 pid_tgid;
27 __u64 uid_gid;
28};
29
30struct hist_key {
31 struct task t;
32 __u32 index;
33};
34
35#define SIZE sizeof(struct task)
36
37static void print_hist_for_pid(int fd, void *task)
24{ 38{
25 int key; 39 struct hist_key key = {}, next_key;
40 char starstr[MAX_STARS];
26 long value; 41 long value;
27 long data[MAX_INDEX] = {}; 42 long data[MAX_INDEX] = {};
28 char starstr[MAX_STARS];
29 int i;
30 int max_ind = -1; 43 int max_ind = -1;
31 long max_value = 0; 44 long max_value = 0;
45 int i, ind;
32 46
33 for (key = 0; key < MAX_INDEX; key++) { 47 while (bpf_get_next_key(fd, &key, &next_key) == 0) {
34 bpf_lookup_elem(fd, &key, &value); 48 if (memcmp(&next_key, task, SIZE)) {
35 data[key] = value; 49 key = next_key;
36 if (value && key > max_ind) 50 continue;
37 max_ind = key; 51 }
52 bpf_lookup_elem(fd, &next_key, &value);
53 ind = next_key.index;
54 data[ind] = value;
55 if (value && ind > max_ind)
56 max_ind = ind;
38 if (value > max_value) 57 if (value > max_value)
39 max_value = value; 58 max_value = value;
59 key = next_key;
40 } 60 }
41 61
42 printf(" syscall write() stats\n"); 62 printf(" syscall write() stats\n");
@@ -48,6 +68,35 @@ static void print_hist(int fd)
48 MAX_STARS, starstr); 68 MAX_STARS, starstr);
49 } 69 }
50} 70}
71
72static void print_hist(int fd)
73{
74 struct hist_key key = {}, next_key;
75 static struct task tasks[1024];
76 int task_cnt = 0;
77 int i;
78
79 while (bpf_get_next_key(fd, &key, &next_key) == 0) {
80 int found = 0;
81
82 for (i = 0; i < task_cnt; i++)
83 if (memcmp(&tasks[i], &next_key, SIZE) == 0)
84 found = 1;
85 if (!found)
86 memcpy(&tasks[task_cnt++], &next_key, SIZE);
87 key = next_key;
88 }
89
90 for (i = 0; i < task_cnt; i++) {
91 printf("\npid %d cmd %s uid %d\n",
92 (__u32) tasks[i].pid_tgid,
93 tasks[i].comm,
94 (__u32) tasks[i].uid_gid);
95 print_hist_for_pid(fd, &tasks[i]);
96 }
97
98}
99
51static void int_exit(int sig) 100static void int_exit(int sig)
52{ 101{
53 print_hist(map_fd[1]); 102 print_hist(map_fd[1]);