diff options
| author | Alexei Starovoitov <ast@plumgrid.com> | 2015-03-13 14:57:42 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2015-03-15 22:02:28 -0400 |
| commit | 9bac3d6d548e5cc925570b263f35b70a00a00ffd (patch) | |
| tree | 00ae5c37fb877d7c2b4fdf5ee0b8fe4837b1d476 /include | |
| parent | a498cfe990f569dd3766bfc9bfd2a5ee04468cd2 (diff) | |
bpf: allow extended BPF programs access skb fields
introduce user accessible mirror of in-kernel 'struct sk_buff':
struct __sk_buff {
__u32 len;
__u32 pkt_type;
__u32 mark;
__u32 queue_mapping;
};
bpf programs can do:
int bpf_prog(struct __sk_buff *skb)
{
__u32 var = skb->pkt_type;
which will be compiled to bpf assembler as:
dst_reg = *(u32 *)(src_reg + 4) // 4 == offsetof(struct __sk_buff, pkt_type)
bpf verifier will check validity of access and will convert it to:
dst_reg = *(u8 *)(src_reg + offsetof(struct sk_buff, __pkt_type_offset))
dst_reg &= 7
since skb->pkt_type is a bitfield.
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 | 5 | ||||
| -rw-r--r-- | include/uapi/linux/bpf.h | 10 |
2 files changed, 14 insertions, 1 deletions
diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 30bfd331882a..280a315de8d6 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h | |||
| @@ -103,6 +103,9 @@ struct bpf_verifier_ops { | |||
| 103 | * with 'type' (read or write) is allowed | 103 | * with 'type' (read or write) is allowed |
| 104 | */ | 104 | */ |
| 105 | bool (*is_valid_access)(int off, int size, enum bpf_access_type type); | 105 | bool (*is_valid_access)(int off, int size, enum bpf_access_type type); |
| 106 | |||
| 107 | u32 (*convert_ctx_access)(int dst_reg, int src_reg, int ctx_off, | ||
| 108 | struct bpf_insn *insn); | ||
| 106 | }; | 109 | }; |
| 107 | 110 | ||
| 108 | struct bpf_prog_type_list { | 111 | struct bpf_prog_type_list { |
| @@ -133,7 +136,7 @@ struct bpf_map *bpf_map_get(struct fd f); | |||
| 133 | void bpf_map_put(struct bpf_map *map); | 136 | void bpf_map_put(struct bpf_map *map); |
| 134 | 137 | ||
| 135 | /* verify correctness of eBPF program */ | 138 | /* verify correctness of eBPF program */ |
| 136 | int bpf_check(struct bpf_prog *fp, union bpf_attr *attr); | 139 | int bpf_check(struct bpf_prog **fp, union bpf_attr *attr); |
| 137 | #else | 140 | #else |
| 138 | static inline void bpf_register_prog_type(struct bpf_prog_type_list *tl) | 141 | static inline void bpf_register_prog_type(struct bpf_prog_type_list *tl) |
| 139 | { | 142 | { |
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index de1f63668daf..929545a27546 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h | |||
| @@ -170,4 +170,14 @@ enum bpf_func_id { | |||
| 170 | __BPF_FUNC_MAX_ID, | 170 | __BPF_FUNC_MAX_ID, |
| 171 | }; | 171 | }; |
| 172 | 172 | ||
| 173 | /* user accessible mirror of in-kernel sk_buff. | ||
| 174 | * new fields can only be added to the end of this structure | ||
| 175 | */ | ||
| 176 | struct __sk_buff { | ||
| 177 | __u32 len; | ||
| 178 | __u32 pkt_type; | ||
| 179 | __u32 mark; | ||
| 180 | __u32 queue_mapping; | ||
| 181 | }; | ||
| 182 | |||
| 173 | #endif /* _UAPI__LINUX_BPF_H__ */ | 183 | #endif /* _UAPI__LINUX_BPF_H__ */ |
