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 --- |