aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/syscall.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r--kernel/bpf/syscall.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 323be2473c4b..1574b9f0f24e 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -824,7 +824,10 @@ static int find_prog_type(enum bpf_prog_type type, struct bpf_prog *prog)
824 if (type >= ARRAY_SIZE(bpf_prog_types) || !bpf_prog_types[type]) 824 if (type >= ARRAY_SIZE(bpf_prog_types) || !bpf_prog_types[type])
825 return -EINVAL; 825 return -EINVAL;
826 826
827 prog->aux->ops = bpf_prog_types[type]; 827 if (!bpf_prog_is_dev_bound(prog->aux))
828 prog->aux->ops = bpf_prog_types[type];
829 else
830 prog->aux->ops = &bpf_offload_prog_ops;
828 prog->type = type; 831 prog->type = type;
829 return 0; 832 return 0;
830} 833}
@@ -1054,7 +1057,7 @@ struct bpf_prog *bpf_prog_inc_not_zero(struct bpf_prog *prog)
1054} 1057}
1055EXPORT_SYMBOL_GPL(bpf_prog_inc_not_zero); 1058EXPORT_SYMBOL_GPL(bpf_prog_inc_not_zero);
1056 1059
1057static struct bpf_prog *__bpf_prog_get(u32 ufd, enum bpf_prog_type *type) 1060static struct bpf_prog *__bpf_prog_get(u32 ufd, enum bpf_prog_type *attach_type)
1058{ 1061{
1059 struct fd f = fdget(ufd); 1062 struct fd f = fdget(ufd);
1060 struct bpf_prog *prog; 1063 struct bpf_prog *prog;
@@ -1062,7 +1065,7 @@ static struct bpf_prog *__bpf_prog_get(u32 ufd, enum bpf_prog_type *type)
1062 prog = ____bpf_prog_get(f); 1065 prog = ____bpf_prog_get(f);
1063 if (IS_ERR(prog)) 1066 if (IS_ERR(prog))
1064 return prog; 1067 return prog;
1065 if (type && prog->type != *type) { 1068 if (attach_type && (prog->type != *attach_type || prog->aux->offload)) {
1066 prog = ERR_PTR(-EINVAL); 1069 prog = ERR_PTR(-EINVAL);
1067 goto out; 1070 goto out;
1068 } 1071 }
@@ -1089,7 +1092,7 @@ struct bpf_prog *bpf_prog_get_type(u32 ufd, enum bpf_prog_type type)
1089EXPORT_SYMBOL_GPL(bpf_prog_get_type); 1092EXPORT_SYMBOL_GPL(bpf_prog_get_type);
1090 1093
1091/* last field in 'union bpf_attr' used by this command */ 1094/* last field in 'union bpf_attr' used by this command */
1092#define BPF_PROG_LOAD_LAST_FIELD prog_name 1095#define BPF_PROG_LOAD_LAST_FIELD prog_target_ifindex
1093 1096
1094static int bpf_prog_load(union bpf_attr *attr) 1097static int bpf_prog_load(union bpf_attr *attr)
1095{ 1098{
@@ -1152,6 +1155,12 @@ static int bpf_prog_load(union bpf_attr *attr)
1152 atomic_set(&prog->aux->refcnt, 1); 1155 atomic_set(&prog->aux->refcnt, 1);
1153 prog->gpl_compatible = is_gpl ? 1 : 0; 1156 prog->gpl_compatible = is_gpl ? 1 : 0;
1154 1157
1158 if (attr->prog_target_ifindex) {
1159 err = bpf_prog_offload_init(prog, attr);
1160 if (err)
1161 goto free_prog;
1162 }
1163
1155 /* find program type: socket_filter vs tracing_filter */ 1164 /* find program type: socket_filter vs tracing_filter */
1156 err = find_prog_type(type, prog); 1165 err = find_prog_type(type, prog);
1157 if (err < 0) 1166 if (err < 0)