diff options
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r-- | kernel/bpf/syscall.c | 17 |
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 | } |
1055 | EXPORT_SYMBOL_GPL(bpf_prog_inc_not_zero); | 1058 | EXPORT_SYMBOL_GPL(bpf_prog_inc_not_zero); |
1056 | 1059 | ||
1057 | static struct bpf_prog *__bpf_prog_get(u32 ufd, enum bpf_prog_type *type) | 1060 | static 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) | |||
1089 | EXPORT_SYMBOL_GPL(bpf_prog_get_type); | 1092 | EXPORT_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 | ||
1094 | static int bpf_prog_load(union bpf_attr *attr) | 1097 | static 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) |