diff options
| author | John Fastabend <john.fastabend@gmail.com> | 2017-08-28 10:10:04 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2017-08-28 14:13:21 -0400 |
| commit | 464bc0fd6273d518aee79fbd37211dd9bc35d863 (patch) | |
| tree | 32280f0588583c50f6712de2ad0e3af886dcaadd | |
| parent | 901c5d2fbfcdc5d1d49a7a835b9ce9be5eee6393 (diff) | |
bpf: convert sockmap field attach_bpf_fd2 to type
In the initial sockmap API we provided strparser and verdict programs
using a single attach command by extending the attach API with a the
attach_bpf_fd2 field.
However, if we add other programs in the future we will be adding a
field for every new possible type, attach_bpf_fd(3,4,..). This
seems a bit clumsy for an API. So lets push the programs using two
new type fields.
BPF_SK_SKB_STREAM_PARSER
BPF_SK_SKB_STREAM_VERDICT
This has the advantage of having a readable name and can easily be
extended in the future.
Updates to samples and sockmap included here also generalize tests
slightly to support upcoming patch for multiple map support.
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
Fixes: 174a79ff9515 ("bpf: sockmap with sk redirect support")
Suggested-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | include/linux/bpf.h | 10 | ||||
| -rw-r--r-- | include/uapi/linux/bpf.h | 9 | ||||
| -rw-r--r-- | kernel/bpf/sockmap.c | 25 | ||||
| -rw-r--r-- | kernel/bpf/syscall.c | 38 | ||||
| -rw-r--r-- | samples/sockmap/sockmap_kern.c | 6 | ||||
| -rw-r--r-- | samples/sockmap/sockmap_user.c | 12 | ||||
| -rw-r--r-- | tools/include/uapi/linux/bpf.h | 9 | ||||
| -rw-r--r-- | tools/lib/bpf/bpf.c | 14 | ||||
| -rw-r--r-- | tools/lib/bpf/bpf.h | 4 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/bpf_helpers.h | 3 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/sockmap_parse_prog.c | 2 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/sockmap_verdict_prog.c | 2 | ||||
| -rw-r--r-- | tools/testing/selftests/bpf/test_maps.c | 133 |
13 files changed, 116 insertions, 151 deletions
diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 830f472d8df5..c2cb1b5c094e 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h | |||
| @@ -39,8 +39,6 @@ struct bpf_map_ops { | |||
| 39 | void (*map_fd_put_ptr)(void *ptr); | 39 | void (*map_fd_put_ptr)(void *ptr); |
| 40 | u32 (*map_gen_lookup)(struct bpf_map *map, struct bpf_insn *insn_buf); | 40 | u32 (*map_gen_lookup)(struct bpf_map *map, struct bpf_insn *insn_buf); |
| 41 | u32 (*map_fd_sys_lookup_elem)(void *ptr); | 41 | u32 (*map_fd_sys_lookup_elem)(void *ptr); |
| 42 | int (*map_attach)(struct bpf_map *map, | ||
| 43 | struct bpf_prog *p1, struct bpf_prog *p2); | ||
| 44 | }; | 42 | }; |
| 45 | 43 | ||
| 46 | struct bpf_map { | 44 | struct bpf_map { |
| @@ -387,11 +385,19 @@ static inline void __dev_map_flush(struct bpf_map *map) | |||
| 387 | 385 | ||
| 388 | #if defined(CONFIG_STREAM_PARSER) && defined(CONFIG_BPF_SYSCALL) | 386 | #if defined(CONFIG_STREAM_PARSER) && defined(CONFIG_BPF_SYSCALL) |
| 389 | struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key); | 387 | struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key); |
| 388 | int sock_map_attach_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type); | ||
| 390 | #else | 389 | #else |
| 391 | static inline struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key) | 390 | static inline struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key) |
| 392 | { | 391 | { |
| 393 | return NULL; | 392 | return NULL; |
| 394 | } | 393 | } |
| 394 | |||
| 395 | static inline int sock_map_attach_prog(struct bpf_map *map, | ||
| 396 | struct bpf_prog *prog, | ||
| 397 | u32 type) | ||
| 398 | { | ||
| 399 | return -EOPNOTSUPP; | ||
| 400 | } | ||
| 395 | #endif | 401 | #endif |
| 396 | 402 | ||
| 397 | /* verifier prototypes for helper functions called from eBPF programs */ | 403 | /* verifier prototypes for helper functions called from eBPF programs */ |
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 843818dff96d..97227be3690c 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h | |||
| @@ -136,7 +136,8 @@ enum bpf_attach_type { | |||
| 136 | BPF_CGROUP_INET_EGRESS, | 136 | BPF_CGROUP_INET_EGRESS, |
| 137 | BPF_CGROUP_INET_SOCK_CREATE, | 137 | BPF_CGROUP_INET_SOCK_CREATE, |
| 138 | BPF_CGROUP_SOCK_OPS, | 138 | BPF_CGROUP_SOCK_OPS, |
| 139 | BPF_CGROUP_SMAP_INGRESS, | 139 | BPF_SK_SKB_STREAM_PARSER, |
| 140 | BPF_SK_SKB_STREAM_VERDICT, | ||
| 140 | __MAX_BPF_ATTACH_TYPE | 141 | __MAX_BPF_ATTACH_TYPE |
| 141 | }; | 142 | }; |
| 142 | 143 | ||
| @@ -224,7 +225,6 @@ union bpf_attr { | |||
| 224 | __u32 attach_bpf_fd; /* eBPF program to attach */ | 225 | __u32 attach_bpf_fd; /* eBPF program to attach */ |
| 225 | __u32 attach_type; | 226 | __u32 attach_type; |
| 226 | __u32 attach_flags; | 227 | __u32 attach_flags; |
| 227 | __u32 attach_bpf_fd2; | ||
| 228 | }; | 228 | }; |
| 229 | 229 | ||
| 230 | struct { /* anonymous struct used by BPF_PROG_TEST_RUN command */ | 230 | struct { /* anonymous struct used by BPF_PROG_TEST_RUN command */ |
| @@ -580,14 +580,11 @@ union bpf_attr { | |||
| 580 | * @flags: reserved for future use | 580 | * @flags: reserved for future use |
| 581 | * Return: SK_REDIRECT | 581 | * Return: SK_REDIRECT |
| 582 | * | 582 | * |
| 583 | * int bpf_sock_map_update(skops, map, key, flags, map_flags) | 583 | * int bpf_sock_map_update(skops, map, key, flags) |
| 584 | * @skops: pointer to bpf_sock_ops | 584 | * @skops: pointer to bpf_sock_ops |
| 585 | * @map: pointer to sockmap to update | 585 | * @map: pointer to sockmap to update |
| 586 | * @key: key to insert/update sock in map | 586 | * @key: key to insert/update sock in map |
| 587 | * @flags: same flags as map update elem | 587 | * @flags: same flags as map update elem |
| 588 | * @map_flags: sock map specific flags | ||
| 589 | * bit 1: Enable strparser | ||
| 590 | * other bits: reserved | ||
| 591 | */ | 588 | */ |
| 592 | #define __BPF_FUNC_MAPPER(FN) \ | 589 | #define __BPF_FUNC_MAPPER(FN) \ |
| 593 | FN(unspec), \ | 590 | FN(unspec), \ |
diff --git a/kernel/bpf/sockmap.c b/kernel/bpf/sockmap.c index 617c239590c2..cf570d108fd5 100644 --- a/kernel/bpf/sockmap.c +++ b/kernel/bpf/sockmap.c | |||
| @@ -723,20 +723,24 @@ out: | |||
| 723 | return err; | 723 | return err; |
| 724 | } | 724 | } |
| 725 | 725 | ||
| 726 | static int sock_map_attach_prog(struct bpf_map *map, | 726 | int sock_map_attach_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type) |
| 727 | struct bpf_prog *parse, | ||
| 728 | struct bpf_prog *verdict) | ||
| 729 | { | 727 | { |
| 730 | struct bpf_stab *stab = container_of(map, struct bpf_stab, map); | 728 | struct bpf_stab *stab = container_of(map, struct bpf_stab, map); |
| 731 | struct bpf_prog *_parse, *_verdict; | 729 | struct bpf_prog *orig; |
| 732 | 730 | ||
| 733 | _parse = xchg(&stab->bpf_parse, parse); | 731 | switch (type) { |
| 734 | _verdict = xchg(&stab->bpf_verdict, verdict); | 732 | case BPF_SK_SKB_STREAM_PARSER: |
| 733 | orig = xchg(&stab->bpf_parse, prog); | ||
| 734 | break; | ||
| 735 | case BPF_SK_SKB_STREAM_VERDICT: | ||
| 736 | orig = xchg(&stab->bpf_verdict, prog); | ||
| 737 | break; | ||
| 738 | default: | ||
| 739 | return -EOPNOTSUPP; | ||
| 740 | } | ||
| 735 | 741 | ||
| 736 | if (_parse) | 742 | if (orig) |
| 737 | bpf_prog_put(_parse); | 743 | bpf_prog_put(orig); |
| 738 | if (_verdict) | ||
| 739 | bpf_prog_put(_verdict); | ||
| 740 | 744 | ||
| 741 | return 0; | 745 | return 0; |
| 742 | } | 746 | } |
| @@ -777,7 +781,6 @@ const struct bpf_map_ops sock_map_ops = { | |||
| 777 | .map_get_next_key = sock_map_get_next_key, | 781 | .map_get_next_key = sock_map_get_next_key, |
| 778 | .map_update_elem = sock_map_update_elem, | 782 | .map_update_elem = sock_map_update_elem, |
| 779 | .map_delete_elem = sock_map_delete_elem, | 783 | .map_delete_elem = sock_map_delete_elem, |
| 780 | .map_attach = sock_map_attach_prog, | ||
| 781 | }; | 784 | }; |
| 782 | 785 | ||
| 783 | BPF_CALL_5(bpf_sock_map_update, struct bpf_sock_ops_kern *, bpf_sock, | 786 | BPF_CALL_5(bpf_sock_map_update, struct bpf_sock_ops_kern *, bpf_sock, |
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 9378f3ba2cbf..021a05d9d800 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c | |||
| @@ -1093,12 +1093,12 @@ static int bpf_obj_get(const union bpf_attr *attr) | |||
| 1093 | 1093 | ||
| 1094 | #ifdef CONFIG_CGROUP_BPF | 1094 | #ifdef CONFIG_CGROUP_BPF |
| 1095 | 1095 | ||
| 1096 | #define BPF_PROG_ATTACH_LAST_FIELD attach_bpf_fd2 | 1096 | #define BPF_PROG_ATTACH_LAST_FIELD attach_flags |
| 1097 | 1097 | ||
| 1098 | static int sockmap_get_from_fd(const union bpf_attr *attr, int ptype) | 1098 | static int sockmap_get_from_fd(const union bpf_attr *attr) |
| 1099 | { | 1099 | { |
| 1100 | struct bpf_prog *prog1, *prog2; | ||
| 1101 | int ufd = attr->target_fd; | 1100 | int ufd = attr->target_fd; |
| 1101 | struct bpf_prog *prog; | ||
| 1102 | struct bpf_map *map; | 1102 | struct bpf_map *map; |
| 1103 | struct fd f; | 1103 | struct fd f; |
| 1104 | int err; | 1104 | int err; |
| @@ -1108,29 +1108,16 @@ static int sockmap_get_from_fd(const union bpf_attr *attr, int ptype) | |||
| 1108 | if (IS_ERR(map)) | 1108 | if (IS_ERR(map)) |
| 1109 | return PTR_ERR(map); | 1109 | return PTR_ERR(map); |
| 1110 | 1110 | ||
| 1111 | if (!map->ops->map_attach) { | 1111 | prog = bpf_prog_get_type(attr->attach_bpf_fd, BPF_PROG_TYPE_SK_SKB); |
| 1112 | fdput(f); | 1112 | if (IS_ERR(prog)) { |
| 1113 | return -EOPNOTSUPP; | ||
| 1114 | } | ||
| 1115 | |||
| 1116 | prog1 = bpf_prog_get_type(attr->attach_bpf_fd, ptype); | ||
| 1117 | if (IS_ERR(prog1)) { | ||
| 1118 | fdput(f); | 1113 | fdput(f); |
| 1119 | return PTR_ERR(prog1); | 1114 | return PTR_ERR(prog); |
| 1120 | } | ||
| 1121 | |||
| 1122 | prog2 = bpf_prog_get_type(attr->attach_bpf_fd2, ptype); | ||
| 1123 | if (IS_ERR(prog2)) { | ||
| 1124 | fdput(f); | ||
| 1125 | bpf_prog_put(prog1); | ||
| 1126 | return PTR_ERR(prog2); | ||
| 1127 | } | 1115 | } |
| 1128 | 1116 | ||
| 1129 | err = map->ops->map_attach(map, prog1, prog2); | 1117 | err = sock_map_attach_prog(map, prog, attr->attach_type); |
| 1130 | if (err) { | 1118 | if (err) { |
| 1131 | fdput(f); | 1119 | fdput(f); |
| 1132 | bpf_prog_put(prog1); | 1120 | bpf_prog_put(prog); |
| 1133 | bpf_prog_put(prog2); | ||
| 1134 | return err; | 1121 | return err; |
| 1135 | } | 1122 | } |
| 1136 | 1123 | ||
| @@ -1165,16 +1152,13 @@ static int bpf_prog_attach(const union bpf_attr *attr) | |||
| 1165 | case BPF_CGROUP_SOCK_OPS: | 1152 | case BPF_CGROUP_SOCK_OPS: |
| 1166 | ptype = BPF_PROG_TYPE_SOCK_OPS; | 1153 | ptype = BPF_PROG_TYPE_SOCK_OPS; |
| 1167 | break; | 1154 | break; |
| 1168 | case BPF_CGROUP_SMAP_INGRESS: | 1155 | case BPF_SK_SKB_STREAM_PARSER: |
| 1169 | ptype = BPF_PROG_TYPE_SK_SKB; | 1156 | case BPF_SK_SKB_STREAM_VERDICT: |
| 1170 | break; | 1157 | return sockmap_get_from_fd(attr); |
| 1171 | default: | 1158 | default: |
| 1172 | return -EINVAL; | 1159 | return -EINVAL; |
| 1173 | } | 1160 | } |
| 1174 | 1161 | ||
| 1175 | if (attr->attach_type == BPF_CGROUP_SMAP_INGRESS) | ||
| 1176 | return sockmap_get_from_fd(attr, ptype); | ||
| 1177 | |||
| 1178 | prog = bpf_prog_get_type(attr->attach_bpf_fd, ptype); | 1162 | prog = bpf_prog_get_type(attr->attach_bpf_fd, ptype); |
| 1179 | if (IS_ERR(prog)) | 1163 | if (IS_ERR(prog)) |
| 1180 | return PTR_ERR(prog); | 1164 | return PTR_ERR(prog); |
diff --git a/samples/sockmap/sockmap_kern.c b/samples/sockmap/sockmap_kern.c index 6ff986f7059b..f9b38ef82dc2 100644 --- a/samples/sockmap/sockmap_kern.c +++ b/samples/sockmap/sockmap_kern.c | |||
| @@ -82,8 +82,7 @@ int bpf_sockmap(struct bpf_sock_ops *skops) | |||
| 82 | if (lport == 10000) { | 82 | if (lport == 10000) { |
| 83 | ret = 1; | 83 | ret = 1; |
| 84 | err = bpf_sock_map_update(skops, &sock_map, &ret, | 84 | err = bpf_sock_map_update(skops, &sock_map, &ret, |
| 85 | BPF_NOEXIST, | 85 | BPF_NOEXIST); |
| 86 | BPF_SOCKMAP_STRPARSER); | ||
| 87 | bpf_printk("passive(%i -> %i) map ctx update err: %d\n", | 86 | bpf_printk("passive(%i -> %i) map ctx update err: %d\n", |
| 88 | lport, bpf_ntohl(rport), err); | 87 | lport, bpf_ntohl(rport), err); |
| 89 | } | 88 | } |
| @@ -95,8 +94,7 @@ int bpf_sockmap(struct bpf_sock_ops *skops) | |||
| 95 | if (bpf_ntohl(rport) == 10001) { | 94 | if (bpf_ntohl(rport) == 10001) { |
| 96 | ret = 10; | 95 | ret = 10; |
| 97 | err = bpf_sock_map_update(skops, &sock_map, &ret, | 96 | err = bpf_sock_map_update(skops, &sock_map, &ret, |
| 98 | BPF_NOEXIST, | 97 | BPF_NOEXIST); |
| 99 | BPF_SOCKMAP_STRPARSER); | ||
| 100 | bpf_printk("active(%i -> %i) map ctx update err: %d\n", | 98 | bpf_printk("active(%i -> %i) map ctx update err: %d\n", |
| 101 | lport, bpf_ntohl(rport), err); | 99 | lport, bpf_ntohl(rport), err); |
| 102 | } | 100 | } |
diff --git a/samples/sockmap/sockmap_user.c b/samples/sockmap/sockmap_user.c index fb78f5abefb4..7cc9d228216f 100644 --- a/samples/sockmap/sockmap_user.c +++ b/samples/sockmap/sockmap_user.c | |||
| @@ -256,8 +256,16 @@ int main(int argc, char **argv) | |||
| 256 | } | 256 | } |
| 257 | 257 | ||
| 258 | /* Attach programs to sockmap */ | 258 | /* Attach programs to sockmap */ |
| 259 | err = __bpf_prog_attach(prog_fd[0], prog_fd[1], map_fd[0], | 259 | err = bpf_prog_attach(prog_fd[0], map_fd[0], |
| 260 | BPF_CGROUP_SMAP_INGRESS, 0); | 260 | BPF_SK_SKB_STREAM_PARSER, 0); |
| 261 | if (err) { | ||
| 262 | fprintf(stderr, "ERROR: bpf_prog_attach (sockmap): %d (%s)\n", | ||
| 263 | err, strerror(errno)); | ||
| 264 | return err; | ||
| 265 | } | ||
| 266 | |||
| 267 | err = bpf_prog_attach(prog_fd[1], map_fd[0], | ||
| 268 | BPF_SK_SKB_STREAM_VERDICT, 0); | ||
| 261 | if (err) { | 269 | if (err) { |
| 262 | fprintf(stderr, "ERROR: bpf_prog_attach (sockmap): %d (%s)\n", | 270 | fprintf(stderr, "ERROR: bpf_prog_attach (sockmap): %d (%s)\n", |
| 263 | err, strerror(errno)); | 271 | err, strerror(errno)); |
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index f8f6377fd541..09ac590eefb1 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h | |||
| @@ -136,7 +136,8 @@ enum bpf_attach_type { | |||
| 136 | BPF_CGROUP_INET_EGRESS, | 136 | BPF_CGROUP_INET_EGRESS, |
| 137 | BPF_CGROUP_INET_SOCK_CREATE, | 137 | BPF_CGROUP_INET_SOCK_CREATE, |
| 138 | BPF_CGROUP_SOCK_OPS, | 138 | BPF_CGROUP_SOCK_OPS, |
| 139 | BPF_CGROUP_SMAP_INGRESS, | 139 | BPF_SK_SKB_STREAM_PARSER, |
| 140 | BPF_SK_SKB_STREAM_VERDICT, | ||
| 140 | __MAX_BPF_ATTACH_TYPE | 141 | __MAX_BPF_ATTACH_TYPE |
| 141 | }; | 142 | }; |
| 142 | 143 | ||
| @@ -227,7 +228,6 @@ union bpf_attr { | |||
| 227 | __u32 attach_bpf_fd; /* eBPF program to attach */ | 228 | __u32 attach_bpf_fd; /* eBPF program to attach */ |
| 228 | __u32 attach_type; | 229 | __u32 attach_type; |
| 229 | __u32 attach_flags; | 230 | __u32 attach_flags; |
| 230 | __u32 attach_bpf_fd2; | ||
| 231 | }; | 231 | }; |
| 232 | 232 | ||
| 233 | struct { /* anonymous struct used by BPF_PROG_TEST_RUN command */ | 233 | struct { /* anonymous struct used by BPF_PROG_TEST_RUN command */ |
| @@ -572,14 +572,11 @@ union bpf_attr { | |||
| 572 | * @flags: reserved for future use | 572 | * @flags: reserved for future use |
| 573 | * Return: SK_REDIRECT | 573 | * Return: SK_REDIRECT |
| 574 | * | 574 | * |
| 575 | * int bpf_sock_map_update(skops, map, key, flags, map_flags) | 575 | * int bpf_sock_map_update(skops, map, key, flags) |
| 576 | * @skops: pointer to bpf_sock_ops | 576 | * @skops: pointer to bpf_sock_ops |
| 577 | * @map: pointer to sockmap to update | 577 | * @map: pointer to sockmap to update |
| 578 | * @key: key to insert/update sock in map | 578 | * @key: key to insert/update sock in map |
| 579 | * @flags: same flags as map update elem | 579 | * @flags: same flags as map update elem |
| 580 | * @map_flags: sock map specific flags | ||
| 581 | * bit 1: Enable strparser | ||
| 582 | * other bits: reserved | ||
| 583 | */ | 580 | */ |
| 584 | #define __BPF_FUNC_MAPPER(FN) \ | 581 | #define __BPF_FUNC_MAPPER(FN) \ |
| 585 | FN(unspec), \ | 582 | FN(unspec), \ |
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index a0717610b116..1d6907d379c9 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c | |||
| @@ -235,28 +235,20 @@ int bpf_obj_get(const char *pathname) | |||
| 235 | return sys_bpf(BPF_OBJ_GET, &attr, sizeof(attr)); | 235 | return sys_bpf(BPF_OBJ_GET, &attr, sizeof(attr)); |
| 236 | } | 236 | } |
| 237 | 237 | ||
| 238 | int __bpf_prog_attach(int prog_fd1, int prog_fd2, int target_fd, | 238 | int bpf_prog_attach(int prog_fd, int target_fd, enum bpf_attach_type type, |
| 239 | enum bpf_attach_type type, | 239 | unsigned int flags) |
| 240 | unsigned int flags) | ||
| 241 | { | 240 | { |
| 242 | union bpf_attr attr; | 241 | union bpf_attr attr; |
| 243 | 242 | ||
| 244 | bzero(&attr, sizeof(attr)); | 243 | bzero(&attr, sizeof(attr)); |
| 245 | attr.target_fd = target_fd; | 244 | attr.target_fd = target_fd; |
| 246 | attr.attach_bpf_fd = prog_fd1; | 245 | attr.attach_bpf_fd = prog_fd; |
| 247 | attr.attach_bpf_fd2 = prog_fd2; | ||
| 248 | attr.attach_type = type; | 246 | attr.attach_type = type; |
| 249 | attr.attach_flags = flags; | 247 | attr.attach_flags = flags; |
| 250 | 248 | ||
| 251 | return sys_bpf(BPF_PROG_ATTACH, &attr, sizeof(attr)); | 249 | return sys_bpf(BPF_PROG_ATTACH, &attr, sizeof(attr)); |
| 252 | } | 250 | } |
| 253 | 251 | ||
| 254 | int bpf_prog_attach(int prog_fd, int target_fd, enum bpf_attach_type type, | ||
| 255 | unsigned int flags) | ||
| 256 | { | ||
| 257 | return __bpf_prog_attach(prog_fd, 0, target_fd, type, flags); | ||
| 258 | } | ||
| 259 | |||
| 260 | int bpf_prog_detach(int target_fd, enum bpf_attach_type type) | 252 | int bpf_prog_detach(int target_fd, enum bpf_attach_type type) |
| 261 | { | 253 | { |
| 262 | union bpf_attr attr; | 254 | union bpf_attr attr; |
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h index 90e9d4e85d08..b8ea5843c39e 100644 --- a/tools/lib/bpf/bpf.h +++ b/tools/lib/bpf/bpf.h | |||
| @@ -56,10 +56,6 @@ int bpf_obj_pin(int fd, const char *pathname); | |||
| 56 | int bpf_obj_get(const char *pathname); | 56 | int bpf_obj_get(const char *pathname); |
| 57 | int bpf_prog_attach(int prog_fd, int attachable_fd, enum bpf_attach_type type, | 57 | int bpf_prog_attach(int prog_fd, int attachable_fd, enum bpf_attach_type type, |
| 58 | unsigned int flags); | 58 | unsigned int flags); |
| 59 | int __bpf_prog_attach(int prog1, int prog2, | ||
| 60 | int attachable_fd, | ||
| 61 | enum bpf_attach_type type, | ||
| 62 | unsigned int flags); | ||
| 63 | int bpf_prog_detach(int attachable_fd, enum bpf_attach_type type); | 59 | int bpf_prog_detach(int attachable_fd, enum bpf_attach_type type); |
| 64 | int bpf_prog_test_run(int prog_fd, int repeat, void *data, __u32 size, | 60 | int bpf_prog_test_run(int prog_fd, int repeat, void *data, __u32 size, |
| 65 | void *data_out, __u32 *size_out, __u32 *retval, | 61 | void *data_out, __u32 *size_out, __u32 *retval, |
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h index 98f3be26d390..36fb9161b34a 100644 --- a/tools/testing/selftests/bpf/bpf_helpers.h +++ b/tools/testing/selftests/bpf/bpf_helpers.h | |||
| @@ -68,8 +68,7 @@ static int (*bpf_setsockopt)(void *ctx, int level, int optname, void *optval, | |||
| 68 | static int (*bpf_sk_redirect_map)(void *map, int key, int flags) = | 68 | static int (*bpf_sk_redirect_map)(void *map, int key, int flags) = |
| 69 | (void *) BPF_FUNC_sk_redirect_map; | 69 | (void *) BPF_FUNC_sk_redirect_map; |
| 70 | static int (*bpf_sock_map_update)(void *map, void *key, void *value, | 70 | static int (*bpf_sock_map_update)(void *map, void *key, void *value, |
| 71 | unsigned long long flags, | 71 | unsigned long long flags) = |
| 72 | unsigned long long map_lags) = | ||
| 73 | (void *) BPF_FUNC_sock_map_update; | 72 | (void *) BPF_FUNC_sock_map_update; |
| 74 | 73 | ||
| 75 | 74 | ||
diff --git a/tools/testing/selftests/bpf/sockmap_parse_prog.c b/tools/testing/selftests/bpf/sockmap_parse_prog.c index 8b5453158399..710f43f42dc4 100644 --- a/tools/testing/selftests/bpf/sockmap_parse_prog.c +++ b/tools/testing/selftests/bpf/sockmap_parse_prog.c | |||
| @@ -30,7 +30,7 @@ int bpf_prog1(struct __sk_buff *skb) | |||
| 30 | */ | 30 | */ |
| 31 | d[0] = 1; | 31 | d[0] = 1; |
| 32 | 32 | ||
| 33 | bpf_printk("data[0] = (%u): local_port %i remote %i\n", | 33 | bpf_printk("parse: data[0] = (%u): local_port %i remote %i\n", |
| 34 | d[0], lport, bpf_ntohl(rport)); | 34 | d[0], lport, bpf_ntohl(rport)); |
| 35 | return skb->len; | 35 | return skb->len; |
| 36 | } | 36 | } |
diff --git a/tools/testing/selftests/bpf/sockmap_verdict_prog.c b/tools/testing/selftests/bpf/sockmap_verdict_prog.c index d5f9447b3808..0573c1db2519 100644 --- a/tools/testing/selftests/bpf/sockmap_verdict_prog.c +++ b/tools/testing/selftests/bpf/sockmap_verdict_prog.c | |||
| @@ -40,7 +40,7 @@ int bpf_prog2(struct __sk_buff *skb) | |||
| 40 | d[6] = 0xe; | 40 | d[6] = 0xe; |
| 41 | d[7] = 0xf; | 41 | d[7] = 0xf; |
| 42 | 42 | ||
| 43 | bpf_printk("data[0] = (%u): local_port %i remote %i\n", | 43 | bpf_printk("verdict: data[0] = (%u): local_port %i remote %i redirect 5\n", |
| 44 | d[0], lport, bpf_ntohl(rport)); | 44 | d[0], lport, bpf_ntohl(rport)); |
| 45 | return bpf_sk_redirect_map(&sock_map, 5, 0); | 45 | return bpf_sk_redirect_map(&sock_map, 5, 0); |
| 46 | } | 46 | } |
diff --git a/tools/testing/selftests/bpf/test_maps.c b/tools/testing/selftests/bpf/test_maps.c index 40b2d1faf02b..6df6e6257424 100644 --- a/tools/testing/selftests/bpf/test_maps.c +++ b/tools/testing/selftests/bpf/test_maps.c | |||
| @@ -547,20 +547,26 @@ static void test_sockmap(int task, void *data) | |||
| 547 | goto out_sockmap; | 547 | goto out_sockmap; |
| 548 | } | 548 | } |
| 549 | 549 | ||
| 550 | /* Nothing attached so these should fail */ | 550 | /* Test update without programs */ |
| 551 | for (i = 0; i < 6; i++) { | 551 | for (i = 0; i < 6; i++) { |
| 552 | err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY); | 552 | err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY); |
| 553 | if (!err) { | 553 | if (err) { |
| 554 | printf("Failed invalid update sockmap '%i:%i'\n", | 554 | printf("Failed noprog update sockmap '%i:%i'\n", |
| 555 | i, sfd[i]); | 555 | i, sfd[i]); |
| 556 | goto out_sockmap; | 556 | goto out_sockmap; |
| 557 | } | 557 | } |
| 558 | } | 558 | } |
| 559 | 559 | ||
| 560 | /* Test attaching bad fds */ | 560 | /* Test attaching bad fds */ |
| 561 | err = __bpf_prog_attach(-1, -2, fd, BPF_CGROUP_SMAP_INGRESS, 0); | 561 | err = bpf_prog_attach(-1, fd, BPF_SK_SKB_STREAM_PARSER, 0); |
| 562 | if (!err) { | 562 | if (!err) { |
| 563 | printf("Failed invalid prog attach\n"); | 563 | printf("Failed invalid parser prog attach\n"); |
| 564 | goto out_sockmap; | ||
| 565 | } | ||
| 566 | |||
| 567 | err = bpf_prog_attach(-1, fd, BPF_SK_SKB_STREAM_VERDICT, 0); | ||
| 568 | if (!err) { | ||
| 569 | printf("Failed invalid verdict prog attach\n"); | ||
| 564 | goto out_sockmap; | 570 | goto out_sockmap; |
| 565 | } | 571 | } |
| 566 | 572 | ||
| @@ -591,14 +597,21 @@ static void test_sockmap(int task, void *data) | |||
| 591 | goto out_sockmap; | 597 | goto out_sockmap; |
| 592 | } | 598 | } |
| 593 | 599 | ||
| 594 | err = __bpf_prog_attach(parse_prog, verdict_prog, map_fd, | 600 | err = bpf_prog_attach(parse_prog, map_fd, |
| 595 | BPF_CGROUP_SMAP_INGRESS, 0); | 601 | BPF_SK_SKB_STREAM_PARSER, 0); |
| 602 | if (err) { | ||
| 603 | printf("Failed bpf prog attach\n"); | ||
| 604 | goto out_sockmap; | ||
| 605 | } | ||
| 606 | |||
| 607 | err = bpf_prog_attach(verdict_prog, map_fd, | ||
| 608 | BPF_SK_SKB_STREAM_VERDICT, 0); | ||
| 596 | if (err) { | 609 | if (err) { |
| 597 | printf("Failed bpf prog attach\n"); | 610 | printf("Failed bpf prog attach\n"); |
| 598 | goto out_sockmap; | 611 | goto out_sockmap; |
| 599 | } | 612 | } |
| 600 | 613 | ||
| 601 | /* Test map update elem */ | 614 | /* Test map update elem afterwards fd lives in fd and map_fd */ |
| 602 | for (i = 0; i < 6; i++) { | 615 | for (i = 0; i < 6; i++) { |
| 603 | err = bpf_map_update_elem(map_fd, &i, &sfd[i], BPF_ANY); | 616 | err = bpf_map_update_elem(map_fd, &i, &sfd[i], BPF_ANY); |
| 604 | if (err) { | 617 | if (err) { |
| @@ -649,96 +662,68 @@ static void test_sockmap(int task, void *data) | |||
| 649 | goto out_sockmap; | 662 | goto out_sockmap; |
| 650 | } | 663 | } |
| 651 | 664 | ||
| 652 | /* Delete the reset of the elems include some NULL elems */ | 665 | /* Push fd into same slot */ |
| 653 | for (i = 0; i < 6; i++) { | 666 | i = 2; |
| 654 | err = bpf_map_delete_elem(map_fd, &i); | ||
| 655 | if (err && (i == 0 || i == 1 || i >= 4)) { | ||
| 656 | printf("Failed delete sockmap %i '%i:%i'\n", | ||
| 657 | err, i, sfd[i]); | ||
| 658 | goto out_sockmap; | ||
| 659 | } else if (!err && (i == 2 || i == 3)) { | ||
| 660 | printf("Failed null delete sockmap %i '%i:%i'\n", | ||
| 661 | err, i, sfd[i]); | ||
| 662 | goto out_sockmap; | ||
| 663 | } | ||
| 664 | } | ||
| 665 | |||
| 666 | /* Test having multiple SMAPs open and active on same fds */ | ||
| 667 | err = __bpf_prog_attach(parse_prog, verdict_prog, fd, | ||
| 668 | BPF_CGROUP_SMAP_INGRESS, 0); | ||
| 669 | if (err) { | ||
| 670 | printf("Failed fd bpf prog attach\n"); | ||
| 671 | goto out_sockmap; | ||
| 672 | } | ||
| 673 | |||
| 674 | for (i = 0; i < 6; i++) { | ||
| 675 | err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY); | ||
| 676 | if (err) { | ||
| 677 | printf("Failed fd update sockmap %i '%i:%i'\n", | ||
| 678 | err, i, sfd[i]); | ||
| 679 | goto out_sockmap; | ||
| 680 | } | ||
| 681 | } | ||
| 682 | |||
| 683 | /* Test duplicate socket add of NOEXIST, ANY and EXIST */ | ||
| 684 | i = 0; | ||
| 685 | err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_NOEXIST); | 667 | err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_NOEXIST); |
| 686 | if (!err) { | 668 | if (!err) { |
| 687 | printf("Failed BPF_NOEXIST create\n"); | 669 | printf("Failed allowed sockmap dup slot BPF_NOEXIST\n"); |
| 688 | goto out_sockmap; | 670 | goto out_sockmap; |
| 689 | } | 671 | } |
| 690 | 672 | ||
| 691 | err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY); | 673 | err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY); |
| 692 | if (err) { | 674 | if (err) { |
| 693 | printf("Failed sockmap update BPF_ANY\n"); | 675 | printf("Failed sockmap update new slot BPF_ANY\n"); |
| 694 | goto out_sockmap; | 676 | goto out_sockmap; |
| 695 | } | 677 | } |
| 696 | 678 | ||
| 697 | err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_EXIST); | 679 | err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_EXIST); |
| 698 | if (err) { | 680 | if (err) { |
| 699 | printf("Failed sockmap update BPF_EXIST\n"); | 681 | printf("Failed sockmap update new slot BPF_EXIST\n"); |
| 700 | goto out_sockmap; | 682 | goto out_sockmap; |
| 701 | } | 683 | } |
| 702 | 684 | ||
| 703 | /* The above were pushing fd into same slot try different slot now */ | 685 | /* Delete the elems without programs */ |
| 704 | i = 2; | 686 | for (i = 0; i < 6; i++) { |
| 705 | err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_NOEXIST); | 687 | err = bpf_map_delete_elem(fd, &i); |
| 706 | if (!err) { | 688 | if (err) { |
| 707 | printf("Failed BPF_NOEXIST create\n"); | 689 | printf("Failed delete sockmap %i '%i:%i'\n", |
| 708 | goto out_sockmap; | 690 | err, i, sfd[i]); |
| 691 | } | ||
| 709 | } | 692 | } |
| 710 | 693 | ||
| 711 | err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY); | 694 | /* Test having multiple maps open and set with programs on same fds */ |
| 695 | err = bpf_prog_attach(parse_prog, fd, | ||
| 696 | BPF_SK_SKB_STREAM_PARSER, 0); | ||
| 712 | if (err) { | 697 | if (err) { |
| 713 | printf("Failed sockmap update BPF_ANY\n"); | 698 | printf("Failed fd bpf parse prog attach\n"); |
| 714 | goto out_sockmap; | 699 | goto out_sockmap; |
| 715 | } | 700 | } |
| 716 | 701 | err = bpf_prog_attach(verdict_prog, fd, | |
| 717 | err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_EXIST); | 702 | BPF_SK_SKB_STREAM_VERDICT, 0); |
| 718 | if (err) { | 703 | if (err) { |
| 719 | printf("Failed sockmap update BPF_EXIST\n"); | 704 | printf("Failed fd bpf verdict prog attach\n"); |
| 720 | goto out_sockmap; | 705 | goto out_sockmap; |
| 721 | } | 706 | } |
| 722 | 707 | ||
| 723 | /* Try pushing fd into different map, this is not allowed at the | 708 | for (i = 4; i < 6; i++) { |
| 724 | * moment. Which programs would we use? | 709 | err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY); |
| 725 | */ | 710 | if (!err) { |
| 726 | err = bpf_map_update_elem(map_fd, &i, &sfd[i], BPF_NOEXIST); | 711 | printf("Failed allowed duplicate programs in update ANY sockmap %i '%i:%i'\n", |
| 727 | if (!err) { | 712 | err, i, sfd[i]); |
| 728 | printf("Failed BPF_NOEXIST create\n"); | 713 | goto out_sockmap; |
| 729 | goto out_sockmap; | 714 | } |
| 730 | } | 715 | err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_NOEXIST); |
| 731 | 716 | if (!err) { | |
| 732 | err = bpf_map_update_elem(map_fd, &i, &sfd[i], BPF_ANY); | 717 | printf("Failed allowed duplicate program in update NOEXIST sockmap %i '%i:%i'\n", |
| 733 | if (!err) { | 718 | err, i, sfd[i]); |
| 734 | printf("Failed sockmap update BPF_ANY\n"); | 719 | goto out_sockmap; |
| 735 | goto out_sockmap; | 720 | } |
| 736 | } | 721 | err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_EXIST); |
| 737 | 722 | if (!err) { | |
| 738 | err = bpf_map_update_elem(map_fd, &i, &sfd[i], BPF_EXIST); | 723 | printf("Failed allowed duplicate program in update EXIST sockmap %i '%i:%i'\n", |
| 739 | if (!err) { | 724 | err, i, sfd[i]); |
| 740 | printf("Failed sockmap update BPF_EXIST\n"); | 725 | goto out_sockmap; |
| 741 | goto out_sockmap; | 726 | } |
| 742 | } | 727 | } |
| 743 | 728 | ||
| 744 | /* Test map close sockets */ | 729 | /* Test map close sockets */ |
