diff options
author | Alexei Starovoitov <ast@plumgrid.com> | 2014-09-26 03:17:00 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-09-26 15:05:14 -0400 |
commit | 09756af46893c18839062976c3252e93a1beeba7 (patch) | |
tree | 203642a5473496ecb6ff10cd22dba39b22ed5f0a /include | |
parent | db20fd2b01087bdfbe30bce314a198eefedcc42e (diff) |
bpf: expand BPF syscall with program load/unload
eBPF programs are similar to kernel modules. They are loaded by the user
process and automatically unloaded when process exits. Each eBPF program is
a safe run-to-completion set of instructions. eBPF verifier statically
determines that the program terminates and is safe to execute.
The following syscall wrapper can be used to load the program:
int bpf_prog_load(enum bpf_prog_type prog_type,
const struct bpf_insn *insns, int insn_cnt,
const char *license)
{
union bpf_attr attr = {
.prog_type = prog_type,
.insns = ptr_to_u64(insns),
.insn_cnt = insn_cnt,
.license = ptr_to_u64(license),
};
return bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
}
where 'insns' is an array of eBPF instructions and 'license' is a string
that must be GPL compatible to call helper functions marked gpl_only
Upon succesful load the syscall returns prog_fd.
Use close(prog_fd) to unload the program.
User space tests and examples follow in the later patches
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/bpf.h | 38 | ||||
-rw-r--r-- | include/linux/filter.h | 8 | ||||
-rw-r--r-- | include/uapi/linux/bpf.h | 26 |
3 files changed, 66 insertions, 6 deletions
diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 2887f3f9da59..92979182be81 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h | |||
@@ -46,4 +46,42 @@ void bpf_register_map_type(struct bpf_map_type_list *tl); | |||
46 | void bpf_map_put(struct bpf_map *map); | 46 | void bpf_map_put(struct bpf_map *map); |
47 | struct bpf_map *bpf_map_get(struct fd f); | 47 | struct bpf_map *bpf_map_get(struct fd f); |
48 | 48 | ||
49 | /* eBPF function prototype used by verifier to allow BPF_CALLs from eBPF programs | ||
50 | * to in-kernel helper functions and for adjusting imm32 field in BPF_CALL | ||
51 | * instructions after verifying | ||
52 | */ | ||
53 | struct bpf_func_proto { | ||
54 | u64 (*func)(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5); | ||
55 | bool gpl_only; | ||
56 | }; | ||
57 | |||
58 | struct bpf_verifier_ops { | ||
59 | /* return eBPF function prototype for verification */ | ||
60 | const struct bpf_func_proto *(*get_func_proto)(enum bpf_func_id func_id); | ||
61 | }; | ||
62 | |||
63 | struct bpf_prog_type_list { | ||
64 | struct list_head list_node; | ||
65 | struct bpf_verifier_ops *ops; | ||
66 | enum bpf_prog_type type; | ||
67 | }; | ||
68 | |||
69 | void bpf_register_prog_type(struct bpf_prog_type_list *tl); | ||
70 | |||
71 | struct bpf_prog; | ||
72 | |||
73 | struct bpf_prog_aux { | ||
74 | atomic_t refcnt; | ||
75 | bool is_gpl_compatible; | ||
76 | enum bpf_prog_type prog_type; | ||
77 | struct bpf_verifier_ops *ops; | ||
78 | struct bpf_map **used_maps; | ||
79 | u32 used_map_cnt; | ||
80 | struct bpf_prog *prog; | ||
81 | struct work_struct work; | ||
82 | }; | ||
83 | |||
84 | void bpf_prog_put(struct bpf_prog *prog); | ||
85 | struct bpf_prog *bpf_prog_get(u32 ufd); | ||
86 | |||
49 | #endif /* _LINUX_BPF_H */ | 87 | #endif /* _LINUX_BPF_H */ |
diff --git a/include/linux/filter.h b/include/linux/filter.h index 1a0bc6d134d7..4ffc0958d85e 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h | |||
@@ -21,6 +21,7 @@ | |||
21 | struct sk_buff; | 21 | struct sk_buff; |
22 | struct sock; | 22 | struct sock; |
23 | struct seccomp_data; | 23 | struct seccomp_data; |
24 | struct bpf_prog_aux; | ||
24 | 25 | ||
25 | /* ArgX, context and stack frame pointer register positions. Note, | 26 | /* ArgX, context and stack frame pointer register positions. Note, |
26 | * Arg1, Arg2, Arg3, etc are used as argument mappings of function | 27 | * Arg1, Arg2, Arg3, etc are used as argument mappings of function |
@@ -300,17 +301,12 @@ struct bpf_binary_header { | |||
300 | u8 image[]; | 301 | u8 image[]; |
301 | }; | 302 | }; |
302 | 303 | ||
303 | struct bpf_work_struct { | ||
304 | struct bpf_prog *prog; | ||
305 | struct work_struct work; | ||
306 | }; | ||
307 | |||
308 | struct bpf_prog { | 304 | struct bpf_prog { |
309 | u16 pages; /* Number of allocated pages */ | 305 | u16 pages; /* Number of allocated pages */ |
310 | bool jited; /* Is our filter JIT'ed? */ | 306 | bool jited; /* Is our filter JIT'ed? */ |
311 | u32 len; /* Number of filter blocks */ | 307 | u32 len; /* Number of filter blocks */ |
312 | struct sock_fprog_kern *orig_prog; /* Original BPF program */ | 308 | struct sock_fprog_kern *orig_prog; /* Original BPF program */ |
313 | struct bpf_work_struct *work; /* Deferred free work struct */ | 309 | struct bpf_prog_aux *aux; /* Auxiliary fields */ |
314 | unsigned int (*bpf_func)(const struct sk_buff *skb, | 310 | unsigned int (*bpf_func)(const struct sk_buff *skb, |
315 | const struct bpf_insn *filter); | 311 | const struct bpf_insn *filter); |
316 | /* Instructions for interpreter */ | 312 | /* Instructions for interpreter */ |
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 395cabd2ca0a..424f442016e7 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h | |||
@@ -99,12 +99,23 @@ enum bpf_cmd { | |||
99 | * returns zero and stores next key or negative error | 99 | * returns zero and stores next key or negative error |
100 | */ | 100 | */ |
101 | BPF_MAP_GET_NEXT_KEY, | 101 | BPF_MAP_GET_NEXT_KEY, |
102 | |||
103 | /* verify and load eBPF program | ||
104 | * prog_fd = bpf(BPF_PROG_LOAD, union bpf_attr *attr, u32 size) | ||
105 | * Using attr->prog_type, attr->insns, attr->license | ||
106 | * returns fd or negative error | ||
107 | */ | ||
108 | BPF_PROG_LOAD, | ||
102 | }; | 109 | }; |
103 | 110 | ||
104 | enum bpf_map_type { | 111 | enum bpf_map_type { |
105 | BPF_MAP_TYPE_UNSPEC, | 112 | BPF_MAP_TYPE_UNSPEC, |
106 | }; | 113 | }; |
107 | 114 | ||
115 | enum bpf_prog_type { | ||
116 | BPF_PROG_TYPE_UNSPEC, | ||
117 | }; | ||
118 | |||
108 | union bpf_attr { | 119 | union bpf_attr { |
109 | struct { /* anonymous struct used by BPF_MAP_CREATE command */ | 120 | struct { /* anonymous struct used by BPF_MAP_CREATE command */ |
110 | __u32 map_type; /* one of enum bpf_map_type */ | 121 | __u32 map_type; /* one of enum bpf_map_type */ |
@@ -121,6 +132,21 @@ union bpf_attr { | |||
121 | __aligned_u64 next_key; | 132 | __aligned_u64 next_key; |
122 | }; | 133 | }; |
123 | }; | 134 | }; |
135 | |||
136 | struct { /* anonymous struct used by BPF_PROG_LOAD command */ | ||
137 | __u32 prog_type; /* one of enum bpf_prog_type */ | ||
138 | __u32 insn_cnt; | ||
139 | __aligned_u64 insns; | ||
140 | __aligned_u64 license; | ||
141 | }; | ||
124 | } __attribute__((aligned(8))); | 142 | } __attribute__((aligned(8))); |
125 | 143 | ||
144 | /* integer value in 'imm' field of BPF_CALL instruction selects which helper | ||
145 | * function eBPF program intends to call | ||
146 | */ | ||
147 | enum bpf_func_id { | ||
148 | BPF_FUNC_unspec, | ||
149 | __BPF_FUNC_MAX_ID, | ||
150 | }; | ||
151 | |||
126 | #endif /* _UAPI__LINUX_BPF_H__ */ | 152 | #endif /* _UAPI__LINUX_BPF_H__ */ |