aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/syscall.c
diff options
context:
space:
mode:
authorJakub Kicinski <jakub.kicinski@netronome.com>2017-11-03 16:56:17 -0400
committerDavid S. Miller <davem@davemloft.net>2017-11-05 08:26:18 -0500
commitab3f0063c48c26c927851b6767824e35a716d878 (patch)
tree8439b73e4a3f3287024e903c9a8786b74b69f1ed /kernel/bpf/syscall.c
parentf4e63525ee35f9c02e9f51f90571718363e9a9a9 (diff)
bpf: offload: add infrastructure for loading programs for a specific netdev
The fact that we don't know which device the program is going to be used on is quite limiting in current eBPF infrastructure. We have to reverse or limit the changes which kernel makes to the loaded bytecode if we want it to be offloaded to a networking device. We also have to invent new APIs for debugging and troubleshooting support. Make it possible to load programs for a specific netdev. This helps us to bring the debug information closer to the core eBPF infrastructure (e.g. we will be able to reuse the verifer log in device JIT). It allows device JITs to perform translation on the original bytecode. __bpf_prog_get() when called to get a reference for an attachment point will now refuse to give it if program has a device assigned. Following patches will add a version of that function which passes the expected netdev in. @type argument in __bpf_prog_get() is renamed to attach_type to make it clearer that it's only set on attachment. All calls to ndo_bpf are protected by rtnl, only verifier callbacks are not. We need a wait queue to make sure netdev doesn't get destroyed while verifier is still running and calling its driver. Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Reviewed-by: Simon Horman <simon.horman@netronome.com> Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
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)