aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/syscall.c
diff options
context:
space:
mode:
authorJakub Kicinski <jakub.kicinski@netronome.com>2017-11-03 16:56:20 -0400
committerDavid S. Miller <davem@davemloft.net>2017-11-05 08:26:19 -0500
commit248f346ffe9508dee0039db4ac839cb31ba3bdec (patch)
treea7fb34eb8268d73edcbcb257c679f8e98afec568 /kernel/bpf/syscall.c
parent928631e05495fa1f0e9775f555b94dbcbb4e2fb5 (diff)
xdp: allow attaching programs loaded for specific device
Pass the netdev pointer to bpf_prog_get_type(). This way BPF code can decide whether the device matches what the code was loaded/translated for. 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.c33
1 files changed, 29 insertions, 4 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 3217c20ea91b..68f9123acd39 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -1057,7 +1057,22 @@ 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 struct bpf_prog *__bpf_prog_get(u32 ufd, enum bpf_prog_type *attach_type) 1060static bool bpf_prog_can_attach(struct bpf_prog *prog,
1061 enum bpf_prog_type *attach_type,
1062 struct net_device *netdev)
1063{
1064 struct bpf_dev_offload *offload = prog->aux->offload;
1065
1066 if (prog->type != *attach_type)
1067 return false;
1068 if (offload && offload->netdev != netdev)
1069 return false;
1070
1071 return true;
1072}
1073
1074static struct bpf_prog *__bpf_prog_get(u32 ufd, enum bpf_prog_type *attach_type,
1075 struct net_device *netdev)
1061{ 1076{
1062 struct fd f = fdget(ufd); 1077 struct fd f = fdget(ufd);
1063 struct bpf_prog *prog; 1078 struct bpf_prog *prog;
@@ -1065,7 +1080,7 @@ static struct bpf_prog *__bpf_prog_get(u32 ufd, enum bpf_prog_type *attach_type)
1065 prog = ____bpf_prog_get(f); 1080 prog = ____bpf_prog_get(f);
1066 if (IS_ERR(prog)) 1081 if (IS_ERR(prog))
1067 return prog; 1082 return prog;
1068 if (attach_type && (prog->type != *attach_type || prog->aux->offload)) { 1083 if (attach_type && !bpf_prog_can_attach(prog, attach_type, netdev)) {
1069 prog = ERR_PTR(-EINVAL); 1084 prog = ERR_PTR(-EINVAL);
1070 goto out; 1085 goto out;
1071 } 1086 }
@@ -1078,12 +1093,12 @@ out:
1078 1093
1079struct bpf_prog *bpf_prog_get(u32 ufd) 1094struct bpf_prog *bpf_prog_get(u32 ufd)
1080{ 1095{
1081 return __bpf_prog_get(ufd, NULL); 1096 return __bpf_prog_get(ufd, NULL, NULL);
1082} 1097}
1083 1098
1084struct bpf_prog *bpf_prog_get_type(u32 ufd, enum bpf_prog_type type) 1099struct bpf_prog *bpf_prog_get_type(u32 ufd, enum bpf_prog_type type)
1085{ 1100{
1086 struct bpf_prog *prog = __bpf_prog_get(ufd, &type); 1101 struct bpf_prog *prog = __bpf_prog_get(ufd, &type, NULL);
1087 1102
1088 if (!IS_ERR(prog)) 1103 if (!IS_ERR(prog))
1089 trace_bpf_prog_get_type(prog); 1104 trace_bpf_prog_get_type(prog);
@@ -1091,6 +1106,16 @@ struct bpf_prog *bpf_prog_get_type(u32 ufd, enum bpf_prog_type type)
1091} 1106}
1092EXPORT_SYMBOL_GPL(bpf_prog_get_type); 1107EXPORT_SYMBOL_GPL(bpf_prog_get_type);
1093 1108
1109struct bpf_prog *bpf_prog_get_type_dev(u32 ufd, enum bpf_prog_type type,
1110 struct net_device *netdev)
1111{
1112 struct bpf_prog *prog = __bpf_prog_get(ufd, &type, netdev);
1113
1114 if (!IS_ERR(prog))
1115 trace_bpf_prog_get_type(prog);
1116 return prog;
1117}
1118
1094/* last field in 'union bpf_attr' used by this command */ 1119/* last field in 'union bpf_attr' used by this command */
1095#define BPF_PROG_LOAD_LAST_FIELD prog_target_ifindex 1120#define BPF_PROG_LOAD_LAST_FIELD prog_target_ifindex
1096 1121