aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/syscall.c
diff options
context:
space:
mode:
authorJakub Kicinski <jakub.kicinski@netronome.com>2017-11-20 18:21:54 -0500
committerDaniel Borkmann <daniel@iogearbox.net>2017-11-20 18:37:35 -0500
commit288b3de55aace830f13280985ec9e6bcbff33b1b (patch)
tree9b8376e3af3c10bbbe144cae48ea5eb5bce8fa27 /kernel/bpf/syscall.c
parent1f6f4cb7ba219b00a3fa9afe8049fa16444d8b52 (diff)
bpf: offload: move offload device validation out to the drivers
With TC shared block changes we can't depend on correct netdev pointer being available in cls_bpf. Move the device validation to the driver. Core will only make sure that offloaded programs are always attached in the driver (or in HW by the driver). We trust that drivers which implement offload callbacks will perform necessary checks. Moving the checks to the driver is generally a useful thing, in practice the check should be against a switchdev instance, not a netdev, given that most ASICs will probably allow using the same program on many ports. Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com> Acked-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r--kernel/bpf/syscall.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 8e9d065bb7cd..38da55905ab0 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -1057,22 +1057,23 @@ struct bpf_prog *bpf_prog_inc_not_zero(struct bpf_prog *prog)
1057} 1057}
1058EXPORT_SYMBOL_GPL(bpf_prog_inc_not_zero); 1058EXPORT_SYMBOL_GPL(bpf_prog_inc_not_zero);
1059 1059
1060static bool bpf_prog_can_attach(struct bpf_prog *prog, 1060static bool bpf_prog_get_ok(struct bpf_prog *prog,
1061 enum bpf_prog_type *attach_type, 1061 enum bpf_prog_type *attach_type, bool attach_drv)
1062 struct net_device *netdev)
1063{ 1062{
1064 struct bpf_dev_offload *offload = prog->aux->offload; 1063 /* not an attachment, just a refcount inc, always allow */
1064 if (!attach_type)
1065 return true;
1065 1066
1066 if (prog->type != *attach_type) 1067 if (prog->type != *attach_type)
1067 return false; 1068 return false;
1068 if (offload && offload->netdev != netdev) 1069 if (bpf_prog_is_dev_bound(prog->aux) && !attach_drv)
1069 return false; 1070 return false;
1070 1071
1071 return true; 1072 return true;
1072} 1073}
1073 1074
1074static struct bpf_prog *__bpf_prog_get(u32 ufd, enum bpf_prog_type *attach_type, 1075static struct bpf_prog *__bpf_prog_get(u32 ufd, enum bpf_prog_type *attach_type,
1075 struct net_device *netdev) 1076 bool attach_drv)
1076{ 1077{
1077 struct fd f = fdget(ufd); 1078 struct fd f = fdget(ufd);
1078 struct bpf_prog *prog; 1079 struct bpf_prog *prog;
@@ -1080,7 +1081,7 @@ static struct bpf_prog *__bpf_prog_get(u32 ufd, enum bpf_prog_type *attach_type,
1080 prog = ____bpf_prog_get(f); 1081 prog = ____bpf_prog_get(f);
1081 if (IS_ERR(prog)) 1082 if (IS_ERR(prog))
1082 return prog; 1083 return prog;
1083 if (attach_type && !bpf_prog_can_attach(prog, attach_type, netdev)) { 1084 if (!bpf_prog_get_ok(prog, attach_type, attach_drv)) {
1084 prog = ERR_PTR(-EINVAL); 1085 prog = ERR_PTR(-EINVAL);
1085 goto out; 1086 goto out;
1086 } 1087 }
@@ -1093,12 +1094,12 @@ out:
1093 1094
1094struct bpf_prog *bpf_prog_get(u32 ufd) 1095struct bpf_prog *bpf_prog_get(u32 ufd)
1095{ 1096{
1096 return __bpf_prog_get(ufd, NULL, NULL); 1097 return __bpf_prog_get(ufd, NULL, false);
1097} 1098}
1098 1099
1099struct bpf_prog *bpf_prog_get_type(u32 ufd, enum bpf_prog_type type) 1100struct bpf_prog *bpf_prog_get_type(u32 ufd, enum bpf_prog_type type)
1100{ 1101{
1101 struct bpf_prog *prog = __bpf_prog_get(ufd, &type, NULL); 1102 struct bpf_prog *prog = __bpf_prog_get(ufd, &type, false);
1102 1103
1103 if (!IS_ERR(prog)) 1104 if (!IS_ERR(prog))
1104 trace_bpf_prog_get_type(prog); 1105 trace_bpf_prog_get_type(prog);
@@ -1107,9 +1108,9 @@ struct bpf_prog *bpf_prog_get_type(u32 ufd, enum bpf_prog_type type)
1107EXPORT_SYMBOL_GPL(bpf_prog_get_type); 1108EXPORT_SYMBOL_GPL(bpf_prog_get_type);
1108 1109
1109struct bpf_prog *bpf_prog_get_type_dev(u32 ufd, enum bpf_prog_type type, 1110struct bpf_prog *bpf_prog_get_type_dev(u32 ufd, enum bpf_prog_type type,
1110 struct net_device *netdev) 1111 bool attach_drv)
1111{ 1112{
1112 struct bpf_prog *prog = __bpf_prog_get(ufd, &type, netdev); 1113 struct bpf_prog *prog = __bpf_prog_get(ufd, &type, attach_drv);
1113 1114
1114 if (!IS_ERR(prog)) 1115 if (!IS_ERR(prog))
1115 trace_bpf_prog_get_type(prog); 1116 trace_bpf_prog_get_type(prog);