aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Fastabend <john.fastabend@gmail.com>2017-08-28 10:10:04 -0400
committerDavid S. Miller <davem@davemloft.net>2017-08-28 14:13:21 -0400
commit464bc0fd6273d518aee79fbd37211dd9bc35d863 (patch)
tree32280f0588583c50f6712de2ad0e3af886dcaadd
parent901c5d2fbfcdc5d1d49a7a835b9ce9be5eee6393 (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.h10
-rw-r--r--include/uapi/linux/bpf.h9
-rw-r--r--kernel/bpf/sockmap.c25
-rw-r--r--kernel/bpf/syscall.c38
-rw-r--r--samples/sockmap/sockmap_kern.c6
-rw-r--r--samples/sockmap/sockmap_user.c12
-rw-r--r--tools/include/uapi/linux/bpf.h9
-rw-r--r--tools/lib/bpf/bpf.c14
-rw-r--r--tools/lib/bpf/bpf.h4
-rw-r--r--tools/testing/selftests/bpf/bpf_helpers.h3
-rw-r--r--tools/testing/selftests/bpf/sockmap_parse_prog.c2
-rw-r--r--tools/testing/selftests/bpf/sockmap_verdict_prog.c2
-rw-r--r--tools/testing/selftests/bpf/test_maps.c133
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
46struct bpf_map { 44struct 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)
389struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key); 387struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key);
388int sock_map_attach_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type);
390#else 389#else
391static inline struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key) 390static inline struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key)
392{ 391{
393 return NULL; 392 return NULL;
394} 393}
394
395static 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
726static int sock_map_attach_prog(struct bpf_map *map, 726int 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
783BPF_CALL_5(bpf_sock_map_update, struct bpf_sock_ops_kern *, bpf_sock, 786BPF_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
1098static int sockmap_get_from_fd(const union bpf_attr *attr, int ptype) 1098static 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
238int __bpf_prog_attach(int prog_fd1, int prog_fd2, int target_fd, 238int 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
254int 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
260int bpf_prog_detach(int target_fd, enum bpf_attach_type type) 252int 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);
56int bpf_obj_get(const char *pathname); 56int bpf_obj_get(const char *pathname);
57int bpf_prog_attach(int prog_fd, int attachable_fd, enum bpf_attach_type type, 57int bpf_prog_attach(int prog_fd, int attachable_fd, enum bpf_attach_type type,
58 unsigned int flags); 58 unsigned int flags);
59int __bpf_prog_attach(int prog1, int prog2,
60 int attachable_fd,
61 enum bpf_attach_type type,
62 unsigned int flags);
63int bpf_prog_detach(int attachable_fd, enum bpf_attach_type type); 59int bpf_prog_detach(int attachable_fd, enum bpf_attach_type type);
64int bpf_prog_test_run(int prog_fd, int repeat, void *data, __u32 size, 60int 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,
68static int (*bpf_sk_redirect_map)(void *map, int key, int flags) = 68static 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;
70static int (*bpf_sock_map_update)(void *map, void *key, void *value, 70static 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 */