diff options
author | Jakub Kicinski <jakub.kicinski@netronome.com> | 2017-11-03 16:56:20 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-11-05 08:26:19 -0500 |
commit | 248f346ffe9508dee0039db4ac839cb31ba3bdec (patch) | |
tree | a7fb34eb8268d73edcbcb257c679f8e98afec568 /kernel/bpf/syscall.c | |
parent | 928631e05495fa1f0e9775f555b94dbcbb4e2fb5 (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.c | 33 |
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 | } |
1058 | EXPORT_SYMBOL_GPL(bpf_prog_inc_not_zero); | 1058 | EXPORT_SYMBOL_GPL(bpf_prog_inc_not_zero); |
1059 | 1059 | ||
1060 | static struct bpf_prog *__bpf_prog_get(u32 ufd, enum bpf_prog_type *attach_type) | 1060 | static 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 | |||
1074 | static 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 | ||
1079 | struct bpf_prog *bpf_prog_get(u32 ufd) | 1094 | struct 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 | ||
1084 | struct bpf_prog *bpf_prog_get_type(u32 ufd, enum bpf_prog_type type) | 1099 | struct 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 | } |
1092 | EXPORT_SYMBOL_GPL(bpf_prog_get_type); | 1107 | EXPORT_SYMBOL_GPL(bpf_prog_get_type); |
1093 | 1108 | ||
1109 | struct 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 | ||