syscall.c (0c9a66ec0e362fe9aff545b755430e56f58f2b96) syscall.c (6710e1126934d8b4372b4d2f9ae1646cd3f151bf)
1/* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com
2 *
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of version 2 of the GNU General Public
5 * License as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranty of

--- 9 unchanged lines hidden (view full) ---

18#include <linux/mmzone.h>
19#include <linux/anon_inodes.h>
20#include <linux/file.h>
21#include <linux/license.h>
22#include <linux/filter.h>
23#include <linux/version.h>
24#include <linux/kernel.h>
25#include <linux/idr.h>
1/* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com
2 *
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of version 2 of the GNU General Public
5 * License as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranty of

--- 9 unchanged lines hidden (view full) ---

18#include <linux/mmzone.h>
19#include <linux/anon_inodes.h>
20#include <linux/file.h>
21#include <linux/license.h>
22#include <linux/filter.h>
23#include <linux/version.h>
24#include <linux/kernel.h>
25#include <linux/idr.h>
26#include <linux/cred.h>
27#include <linux/timekeeping.h>
28#include <linux/ctype.h>
26
27#define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PROG_ARRAY || \
28 (map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \
29 (map)->map_type == BPF_MAP_TYPE_CGROUP_ARRAY || \
30 (map)->map_type == BPF_MAP_TYPE_ARRAY_OF_MAPS)
31#define IS_FD_HASH(map) ((map)->map_type == BPF_MAP_TYPE_HASH_OF_MAPS)
32#define IS_FD_MAP(map) (IS_FD_ARRAY(map) || IS_FD_HASH(map))
33

--- 273 unchanged lines hidden (view full) ---

307/* helper macro to check that unused fields 'union bpf_attr' are zero */
308#define CHECK_ATTR(CMD) \
309 memchr_inv((void *) &attr->CMD##_LAST_FIELD + \
310 sizeof(attr->CMD##_LAST_FIELD), 0, \
311 sizeof(*attr) - \
312 offsetof(union bpf_attr, CMD##_LAST_FIELD) - \
313 sizeof(attr->CMD##_LAST_FIELD)) != NULL
314
29
30#define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PROG_ARRAY || \
31 (map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \
32 (map)->map_type == BPF_MAP_TYPE_CGROUP_ARRAY || \
33 (map)->map_type == BPF_MAP_TYPE_ARRAY_OF_MAPS)
34#define IS_FD_HASH(map) ((map)->map_type == BPF_MAP_TYPE_HASH_OF_MAPS)
35#define IS_FD_MAP(map) (IS_FD_ARRAY(map) || IS_FD_HASH(map))
36

--- 273 unchanged lines hidden (view full) ---

310/* helper macro to check that unused fields 'union bpf_attr' are zero */
311#define CHECK_ATTR(CMD) \
312 memchr_inv((void *) &attr->CMD##_LAST_FIELD + \
313 sizeof(attr->CMD##_LAST_FIELD), 0, \
314 sizeof(*attr) - \
315 offsetof(union bpf_attr, CMD##_LAST_FIELD) - \
316 sizeof(attr->CMD##_LAST_FIELD)) != NULL
317
315#define BPF_MAP_CREATE_LAST_FIELD numa_node
318/* dst and src must have at least BPF_OBJ_NAME_LEN number of bytes.
319 * Return 0 on success and < 0 on error.
320 */
321static int bpf_obj_name_cpy(char *dst, const char *src)
322{
323 const char *end = src + BPF_OBJ_NAME_LEN;
324
325 memset(dst, 0, BPF_OBJ_NAME_LEN);
326
327 /* Copy all isalnum() and '_' char */
328 while (src < end && *src) {
329 if (!isalnum(*src) && *src != '_')
330 return -EINVAL;
331 *dst++ = *src++;
332 }
333
334 /* No '\0' found in BPF_OBJ_NAME_LEN number of bytes */
335 if (src == end)
336 return -EINVAL;
337
338 return 0;
339}
340
341#define BPF_MAP_CREATE_LAST_FIELD map_name
316/* called via syscall */
317static int map_create(union bpf_attr *attr)
318{
319 int numa_node = bpf_map_attr_numa_node(attr);
320 struct bpf_map *map;
321 int err;
322
323 err = CHECK_ATTR(BPF_MAP_CREATE);

--- 5 unchanged lines hidden (view full) ---

329 !node_online(numa_node)))
330 return -EINVAL;
331
332 /* find map type and init map: hashtable vs rbtree vs bloom vs ... */
333 map = find_and_alloc_map(attr);
334 if (IS_ERR(map))
335 return PTR_ERR(map);
336
342/* called via syscall */
343static int map_create(union bpf_attr *attr)
344{
345 int numa_node = bpf_map_attr_numa_node(attr);
346 struct bpf_map *map;
347 int err;
348
349 err = CHECK_ATTR(BPF_MAP_CREATE);

--- 5 unchanged lines hidden (view full) ---

355 !node_online(numa_node)))
356 return -EINVAL;
357
358 /* find map type and init map: hashtable vs rbtree vs bloom vs ... */
359 map = find_and_alloc_map(attr);
360 if (IS_ERR(map))
361 return PTR_ERR(map);
362
363 err = bpf_obj_name_cpy(map->name, attr->map_name);
364 if (err)
365 goto free_map_nouncharge;
366
337 atomic_set(&map->refcnt, 1);
338 atomic_set(&map->usercnt, 1);
339
340 err = bpf_map_charge_memlock(map);
341 if (err)
342 goto free_map_nouncharge;
343
344 err = bpf_map_alloc_id(map);

--- 212 unchanged lines hidden (view full) ---

557 value = kmalloc(value_size, GFP_USER | __GFP_NOWARN);
558 if (!value)
559 goto free_key;
560
561 err = -EFAULT;
562 if (copy_from_user(value, uvalue, value_size) != 0)
563 goto free_value;
564
367 atomic_set(&map->refcnt, 1);
368 atomic_set(&map->usercnt, 1);
369
370 err = bpf_map_charge_memlock(map);
371 if (err)
372 goto free_map_nouncharge;
373
374 err = bpf_map_alloc_id(map);

--- 212 unchanged lines hidden (view full) ---

587 value = kmalloc(value_size, GFP_USER | __GFP_NOWARN);
588 if (!value)
589 goto free_key;
590
591 err = -EFAULT;
592 if (copy_from_user(value, uvalue, value_size) != 0)
593 goto free_value;
594
595 /* Need to create a kthread, thus must support schedule */
596 if (map->map_type == BPF_MAP_TYPE_CPUMAP) {
597 err = map->ops->map_update_elem(map, key, value, attr->flags);
598 goto out;
599 }
600
565 /* must increment bpf_prog_active to avoid kprobe+bpf triggering from
566 * inside bpf map update or delete otherwise deadlocks are possible
567 */
568 preempt_disable();
569 __this_cpu_inc(bpf_prog_active);
570 if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
571 map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) {
572 err = bpf_percpu_hash_update(map, key, value, attr->flags);

--- 14 unchanged lines hidden (view full) ---

587 rcu_read_unlock();
588 } else {
589 rcu_read_lock();
590 err = map->ops->map_update_elem(map, key, value, attr->flags);
591 rcu_read_unlock();
592 }
593 __this_cpu_dec(bpf_prog_active);
594 preempt_enable();
601 /* must increment bpf_prog_active to avoid kprobe+bpf triggering from
602 * inside bpf map update or delete otherwise deadlocks are possible
603 */
604 preempt_disable();
605 __this_cpu_inc(bpf_prog_active);
606 if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
607 map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) {
608 err = bpf_percpu_hash_update(map, key, value, attr->flags);

--- 14 unchanged lines hidden (view full) ---

623 rcu_read_unlock();
624 } else {
625 rcu_read_lock();
626 err = map->ops->map_update_elem(map, key, value, attr->flags);
627 rcu_read_unlock();
628 }
629 __this_cpu_dec(bpf_prog_active);
630 preempt_enable();
595
631out:
596 if (!err)
597 trace_bpf_map_update_elem(map, ufd, key, value);
598free_value:
599 kfree(value);
600free_key:
601 kfree(key);
602err_put:
603 fdput(f);

--- 364 unchanged lines hidden (view full) ---

968
969 if (!IS_ERR(prog))
970 trace_bpf_prog_get_type(prog);
971 return prog;
972}
973EXPORT_SYMBOL_GPL(bpf_prog_get_type);
974
975/* last field in 'union bpf_attr' used by this command */
632 if (!err)
633 trace_bpf_map_update_elem(map, ufd, key, value);
634free_value:
635 kfree(value);
636free_key:
637 kfree(key);
638err_put:
639 fdput(f);

--- 364 unchanged lines hidden (view full) ---

1004
1005 if (!IS_ERR(prog))
1006 trace_bpf_prog_get_type(prog);
1007 return prog;
1008}
1009EXPORT_SYMBOL_GPL(bpf_prog_get_type);
1010
1011/* last field in 'union bpf_attr' used by this command */
976#define BPF_PROG_LOAD_LAST_FIELD prog_flags
1012#define BPF_PROG_LOAD_LAST_FIELD prog_name
977
978static int bpf_prog_load(union bpf_attr *attr)
979{
980 enum bpf_prog_type type = attr->prog_type;
981 struct bpf_prog *prog;
982 int err;
983 char license[128];
984 bool is_gpl;

--- 47 unchanged lines hidden (view full) ---

1032 atomic_set(&prog->aux->refcnt, 1);
1033 prog->gpl_compatible = is_gpl ? 1 : 0;
1034
1035 /* find program type: socket_filter vs tracing_filter */
1036 err = find_prog_type(type, prog);
1037 if (err < 0)
1038 goto free_prog;
1039
1013
1014static int bpf_prog_load(union bpf_attr *attr)
1015{
1016 enum bpf_prog_type type = attr->prog_type;
1017 struct bpf_prog *prog;
1018 int err;
1019 char license[128];
1020 bool is_gpl;

--- 47 unchanged lines hidden (view full) ---

1068 atomic_set(&prog->aux->refcnt, 1);
1069 prog->gpl_compatible = is_gpl ? 1 : 0;
1070
1071 /* find program type: socket_filter vs tracing_filter */
1072 err = find_prog_type(type, prog);
1073 if (err < 0)
1074 goto free_prog;
1075
1076 prog->aux->load_time = ktime_get_boot_ns();
1077 err = bpf_obj_name_cpy(prog->aux->name, attr->prog_name);
1078 if (err)
1079 goto free_prog;
1080
1040 /* run eBPF verifier */
1041 err = bpf_check(&prog, attr);
1042 if (err < 0)
1043 goto free_used_maps;
1044
1045 /* eBPF program is ready to be JITed */
1046 prog = bpf_prog_select_runtime(prog, &err);
1047 if (err < 0)

--- 79 unchanged lines hidden (view full) ---

1127 bpf_prog_put(prog);
1128 return err;
1129 }
1130
1131 fdput(f);
1132 return 0;
1133}
1134
1081 /* run eBPF verifier */
1082 err = bpf_check(&prog, attr);
1083 if (err < 0)
1084 goto free_used_maps;
1085
1086 /* eBPF program is ready to be JITed */
1087 prog = bpf_prog_select_runtime(prog, &err);
1088 if (err < 0)

--- 79 unchanged lines hidden (view full) ---

1168 bpf_prog_put(prog);
1169 return err;
1170 }
1171
1172 fdput(f);
1173 return 0;
1174}
1175
1176#define BPF_F_ATTACH_MASK \
1177 (BPF_F_ALLOW_OVERRIDE | BPF_F_ALLOW_MULTI)
1178
1135static int bpf_prog_attach(const union bpf_attr *attr)
1136{
1137 enum bpf_prog_type ptype;
1138 struct bpf_prog *prog;
1139 struct cgroup *cgrp;
1140 int ret;
1141
1142 if (!capable(CAP_NET_ADMIN))
1143 return -EPERM;
1144
1145 if (CHECK_ATTR(BPF_PROG_ATTACH))
1146 return -EINVAL;
1147
1179static int bpf_prog_attach(const union bpf_attr *attr)
1180{
1181 enum bpf_prog_type ptype;
1182 struct bpf_prog *prog;
1183 struct cgroup *cgrp;
1184 int ret;
1185
1186 if (!capable(CAP_NET_ADMIN))
1187 return -EPERM;
1188
1189 if (CHECK_ATTR(BPF_PROG_ATTACH))
1190 return -EINVAL;
1191
1148 if (attr->attach_flags & ~BPF_F_ALLOW_OVERRIDE)
1192 if (attr->attach_flags & ~BPF_F_ATTACH_MASK)
1149 return -EINVAL;
1150
1151 switch (attr->attach_type) {
1152 case BPF_CGROUP_INET_INGRESS:
1153 case BPF_CGROUP_INET_EGRESS:
1154 ptype = BPF_PROG_TYPE_CGROUP_SKB;
1155 break;
1156 case BPF_CGROUP_INET_SOCK_CREATE:

--- 14 unchanged lines hidden (view full) ---

1171 return PTR_ERR(prog);
1172
1173 cgrp = cgroup_get_from_fd(attr->target_fd);
1174 if (IS_ERR(cgrp)) {
1175 bpf_prog_put(prog);
1176 return PTR_ERR(cgrp);
1177 }
1178
1193 return -EINVAL;
1194
1195 switch (attr->attach_type) {
1196 case BPF_CGROUP_INET_INGRESS:
1197 case BPF_CGROUP_INET_EGRESS:
1198 ptype = BPF_PROG_TYPE_CGROUP_SKB;
1199 break;
1200 case BPF_CGROUP_INET_SOCK_CREATE:

--- 14 unchanged lines hidden (view full) ---

1215 return PTR_ERR(prog);
1216
1217 cgrp = cgroup_get_from_fd(attr->target_fd);
1218 if (IS_ERR(cgrp)) {
1219 bpf_prog_put(prog);
1220 return PTR_ERR(cgrp);
1221 }
1222
1179 ret = cgroup_bpf_update(cgrp, prog, attr->attach_type,
1180 attr->attach_flags & BPF_F_ALLOW_OVERRIDE);
1223 ret = cgroup_bpf_attach(cgrp, prog, attr->attach_type,
1224 attr->attach_flags);
1181 if (ret)
1182 bpf_prog_put(prog);
1183 cgroup_put(cgrp);
1184
1185 return ret;
1186}
1187
1188#define BPF_PROG_DETACH_LAST_FIELD attach_type
1189
1190static int bpf_prog_detach(const union bpf_attr *attr)
1191{
1225 if (ret)
1226 bpf_prog_put(prog);
1227 cgroup_put(cgrp);
1228
1229 return ret;
1230}
1231
1232#define BPF_PROG_DETACH_LAST_FIELD attach_type
1233
1234static int bpf_prog_detach(const union bpf_attr *attr)
1235{
1236 enum bpf_prog_type ptype;
1237 struct bpf_prog *prog;
1192 struct cgroup *cgrp;
1193 int ret;
1194
1195 if (!capable(CAP_NET_ADMIN))
1196 return -EPERM;
1197
1198 if (CHECK_ATTR(BPF_PROG_DETACH))
1199 return -EINVAL;
1200
1201 switch (attr->attach_type) {
1202 case BPF_CGROUP_INET_INGRESS:
1203 case BPF_CGROUP_INET_EGRESS:
1238 struct cgroup *cgrp;
1239 int ret;
1240
1241 if (!capable(CAP_NET_ADMIN))
1242 return -EPERM;
1243
1244 if (CHECK_ATTR(BPF_PROG_DETACH))
1245 return -EINVAL;
1246
1247 switch (attr->attach_type) {
1248 case BPF_CGROUP_INET_INGRESS:
1249 case BPF_CGROUP_INET_EGRESS:
1250 ptype = BPF_PROG_TYPE_CGROUP_SKB;
1251 break;
1204 case BPF_CGROUP_INET_SOCK_CREATE:
1252 case BPF_CGROUP_INET_SOCK_CREATE:
1253 ptype = BPF_PROG_TYPE_CGROUP_SOCK;
1254 break;
1205 case BPF_CGROUP_SOCK_OPS:
1255 case BPF_CGROUP_SOCK_OPS:
1206 cgrp = cgroup_get_from_fd(attr->target_fd);
1207 if (IS_ERR(cgrp))
1208 return PTR_ERR(cgrp);
1209
1210 ret = cgroup_bpf_update(cgrp, NULL, attr->attach_type, false);
1211 cgroup_put(cgrp);
1256 ptype = BPF_PROG_TYPE_SOCK_OPS;
1212 break;
1213 case BPF_SK_SKB_STREAM_PARSER:
1214 case BPF_SK_SKB_STREAM_VERDICT:
1257 break;
1258 case BPF_SK_SKB_STREAM_PARSER:
1259 case BPF_SK_SKB_STREAM_VERDICT:
1215 ret = sockmap_get_from_fd(attr, false);
1216 break;
1260 return sockmap_get_from_fd(attr, false);
1217 default:
1218 return -EINVAL;
1219 }
1220
1261 default:
1262 return -EINVAL;
1263 }
1264
1265 cgrp = cgroup_get_from_fd(attr->target_fd);
1266 if (IS_ERR(cgrp))
1267 return PTR_ERR(cgrp);
1268
1269 prog = bpf_prog_get_type(attr->attach_bpf_fd, ptype);
1270 if (IS_ERR(prog))
1271 prog = NULL;
1272
1273 ret = cgroup_bpf_detach(cgrp, prog, attr->attach_type, 0);
1274 if (prog)
1275 bpf_prog_put(prog);
1276 cgroup_put(cgrp);
1221 return ret;
1222}
1223
1277 return ret;
1278}
1279
1280#define BPF_PROG_QUERY_LAST_FIELD query.prog_cnt
1281
1282static int bpf_prog_query(const union bpf_attr *attr,
1283 union bpf_attr __user *uattr)
1284{
1285 struct cgroup *cgrp;
1286 int ret;
1287
1288 if (!capable(CAP_NET_ADMIN))
1289 return -EPERM;
1290 if (CHECK_ATTR(BPF_PROG_QUERY))
1291 return -EINVAL;
1292 if (attr->query.query_flags & ~BPF_F_QUERY_EFFECTIVE)
1293 return -EINVAL;
1294
1295 switch (attr->query.attach_type) {
1296 case BPF_CGROUP_INET_INGRESS:
1297 case BPF_CGROUP_INET_EGRESS:
1298 case BPF_CGROUP_INET_SOCK_CREATE:
1299 case BPF_CGROUP_SOCK_OPS:
1300 break;
1301 default:
1302 return -EINVAL;
1303 }
1304 cgrp = cgroup_get_from_fd(attr->query.target_fd);
1305 if (IS_ERR(cgrp))
1306 return PTR_ERR(cgrp);
1307 ret = cgroup_bpf_query(cgrp, attr, uattr);
1308 cgroup_put(cgrp);
1309 return ret;
1310}
1224#endif /* CONFIG_CGROUP_BPF */
1225
1226#define BPF_PROG_TEST_RUN_LAST_FIELD test.duration
1227
1228static int bpf_prog_test_run(const union bpf_attr *attr,
1229 union bpf_attr __user *uattr)
1230{
1231 struct bpf_prog *prog;

--- 121 unchanged lines hidden (view full) ---

1353 return err;
1354 info_len = min_t(u32, sizeof(info), info_len);
1355
1356 if (copy_from_user(&info, uinfo, info_len))
1357 return -EFAULT;
1358
1359 info.type = prog->type;
1360 info.id = prog->aux->id;
1311#endif /* CONFIG_CGROUP_BPF */
1312
1313#define BPF_PROG_TEST_RUN_LAST_FIELD test.duration
1314
1315static int bpf_prog_test_run(const union bpf_attr *attr,
1316 union bpf_attr __user *uattr)
1317{
1318 struct bpf_prog *prog;

--- 121 unchanged lines hidden (view full) ---

1440 return err;
1441 info_len = min_t(u32, sizeof(info), info_len);
1442
1443 if (copy_from_user(&info, uinfo, info_len))
1444 return -EFAULT;
1445
1446 info.type = prog->type;
1447 info.id = prog->aux->id;
1448 info.load_time = prog->aux->load_time;
1449 info.created_by_uid = from_kuid_munged(current_user_ns(),
1450 prog->aux->user->uid);
1361
1362 memcpy(info.tag, prog->tag, sizeof(prog->tag));
1451
1452 memcpy(info.tag, prog->tag, sizeof(prog->tag));
1453 memcpy(info.name, prog->aux->name, sizeof(prog->aux->name));
1363
1454
1455 ulen = info.nr_map_ids;
1456 info.nr_map_ids = prog->aux->used_map_cnt;
1457 ulen = min_t(u32, info.nr_map_ids, ulen);
1458 if (ulen) {
1459 u32 __user *user_map_ids = u64_to_user_ptr(info.map_ids);
1460 u32 i;
1461
1462 for (i = 0; i < ulen; i++)
1463 if (put_user(prog->aux->used_maps[i]->id,
1464 &user_map_ids[i]))
1465 return -EFAULT;
1466 }
1467
1364 if (!capable(CAP_SYS_ADMIN)) {
1365 info.jited_prog_len = 0;
1366 info.xlated_prog_len = 0;
1367 goto done;
1368 }
1369
1370 ulen = info.jited_prog_len;
1371 info.jited_prog_len = prog->jited_len;

--- 36 unchanged lines hidden (view full) ---

1408 info_len = min_t(u32, sizeof(info), info_len);
1409
1410 info.type = map->map_type;
1411 info.id = map->id;
1412 info.key_size = map->key_size;
1413 info.value_size = map->value_size;
1414 info.max_entries = map->max_entries;
1415 info.map_flags = map->map_flags;
1468 if (!capable(CAP_SYS_ADMIN)) {
1469 info.jited_prog_len = 0;
1470 info.xlated_prog_len = 0;
1471 goto done;
1472 }
1473
1474 ulen = info.jited_prog_len;
1475 info.jited_prog_len = prog->jited_len;

--- 36 unchanged lines hidden (view full) ---

1512 info_len = min_t(u32, sizeof(info), info_len);
1513
1514 info.type = map->map_type;
1515 info.id = map->id;
1516 info.key_size = map->key_size;
1517 info.value_size = map->value_size;
1518 info.max_entries = map->max_entries;
1519 info.map_flags = map->map_flags;
1520 memcpy(info.name, map->name, sizeof(map->name));
1416
1417 if (copy_to_user(uinfo, &info, info_len) ||
1418 put_user(info_len, &uattr->info.info_len))
1419 return -EFAULT;
1420
1421 return 0;
1422}
1423

--- 70 unchanged lines hidden (view full) ---

1494 break;
1495#ifdef CONFIG_CGROUP_BPF
1496 case BPF_PROG_ATTACH:
1497 err = bpf_prog_attach(&attr);
1498 break;
1499 case BPF_PROG_DETACH:
1500 err = bpf_prog_detach(&attr);
1501 break;
1521
1522 if (copy_to_user(uinfo, &info, info_len) ||
1523 put_user(info_len, &uattr->info.info_len))
1524 return -EFAULT;
1525
1526 return 0;
1527}
1528

--- 70 unchanged lines hidden (view full) ---

1599 break;
1600#ifdef CONFIG_CGROUP_BPF
1601 case BPF_PROG_ATTACH:
1602 err = bpf_prog_attach(&attr);
1603 break;
1604 case BPF_PROG_DETACH:
1605 err = bpf_prog_detach(&attr);
1606 break;
1607 case BPF_PROG_QUERY:
1608 err = bpf_prog_query(&attr, uattr);
1609 break;
1502#endif
1503 case BPF_PROG_TEST_RUN:
1504 err = bpf_prog_test_run(&attr, uattr);
1505 break;
1506 case BPF_PROG_GET_NEXT_ID:
1507 err = bpf_obj_get_next_id(&attr, uattr,
1508 &prog_idr, &prog_idr_lock);
1509 break;

--- 20 unchanged lines hidden ---
1610#endif
1611 case BPF_PROG_TEST_RUN:
1612 err = bpf_prog_test_run(&attr, uattr);
1613 break;
1614 case BPF_PROG_GET_NEXT_ID:
1615 err = bpf_obj_get_next_id(&attr, uattr,
1616 &prog_idr, &prog_idr_lock);
1617 break;

--- 20 unchanged lines hidden ---