aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/syscall.c
diff options
context:
space:
mode:
authorJohn Fastabend <john.fastabend@gmail.com>2017-09-08 17:00:49 -0400
committerDavid S. Miller <davem@davemloft.net>2017-09-09 00:11:00 -0400
commit5a67da2a71c64daeb456f6f3e87b5c7cecdc5ffa (patch)
treef79a061cee45f81cf3a5a9a2c9606e5b4532f2f9 /kernel/bpf/syscall.c
parentbbbe211c295ffb309247adb7b871dda60d92d2d5 (diff)
bpf: add support for sockmap detach programs
The bpf map sockmap supports adding programs via attach commands. This patch adds the detach command to keep the API symmetric and allow users to remove previously added programs. Otherwise the user would have to delete the map and re-add it to get in this state. This also adds a series of additional tests to capture detach operation and also attaching/detaching invalid prog types. API note: socks will run (or not run) programs depending on the state of the map at the time the sock is added. We do not for example walk the map and remove programs from previously attached socks. Acked-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: John Fastabend <john.fastabend@gmail.com> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r--kernel/bpf/syscall.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 70ad8e220343..cb17e1cd1d43 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -1096,10 +1096,10 @@ static int bpf_obj_get(const union bpf_attr *attr)
1096 1096
1097#define BPF_PROG_ATTACH_LAST_FIELD attach_flags 1097#define BPF_PROG_ATTACH_LAST_FIELD attach_flags
1098 1098
1099static int sockmap_get_from_fd(const union bpf_attr *attr) 1099static int sockmap_get_from_fd(const union bpf_attr *attr, bool attach)
1100{ 1100{
1101 struct bpf_prog *prog = NULL;
1101 int ufd = attr->target_fd; 1102 int ufd = attr->target_fd;
1102 struct bpf_prog *prog;
1103 struct bpf_map *map; 1103 struct bpf_map *map;
1104 struct fd f; 1104 struct fd f;
1105 int err; 1105 int err;
@@ -1109,16 +1109,20 @@ static int sockmap_get_from_fd(const union bpf_attr *attr)
1109 if (IS_ERR(map)) 1109 if (IS_ERR(map))
1110 return PTR_ERR(map); 1110 return PTR_ERR(map);
1111 1111
1112 prog = bpf_prog_get_type(attr->attach_bpf_fd, BPF_PROG_TYPE_SK_SKB); 1112 if (attach) {
1113 if (IS_ERR(prog)) { 1113 prog = bpf_prog_get_type(attr->attach_bpf_fd,
1114 fdput(f); 1114 BPF_PROG_TYPE_SK_SKB);
1115 return PTR_ERR(prog); 1115 if (IS_ERR(prog)) {
1116 fdput(f);
1117 return PTR_ERR(prog);
1118 }
1116 } 1119 }
1117 1120
1118 err = sock_map_attach_prog(map, prog, attr->attach_type); 1121 err = sock_map_prog(map, prog, attr->attach_type);
1119 if (err) { 1122 if (err) {
1120 fdput(f); 1123 fdput(f);
1121 bpf_prog_put(prog); 1124 if (prog)
1125 bpf_prog_put(prog);
1122 return err; 1126 return err;
1123 } 1127 }
1124 1128
@@ -1155,7 +1159,7 @@ static int bpf_prog_attach(const union bpf_attr *attr)
1155 break; 1159 break;
1156 case BPF_SK_SKB_STREAM_PARSER: 1160 case BPF_SK_SKB_STREAM_PARSER:
1157 case BPF_SK_SKB_STREAM_VERDICT: 1161 case BPF_SK_SKB_STREAM_VERDICT:
1158 return sockmap_get_from_fd(attr); 1162 return sockmap_get_from_fd(attr, true);
1159 default: 1163 default:
1160 return -EINVAL; 1164 return -EINVAL;
1161 } 1165 }
@@ -1204,7 +1208,10 @@ static int bpf_prog_detach(const union bpf_attr *attr)
1204 ret = cgroup_bpf_update(cgrp, NULL, attr->attach_type, false); 1208 ret = cgroup_bpf_update(cgrp, NULL, attr->attach_type, false);
1205 cgroup_put(cgrp); 1209 cgroup_put(cgrp);
1206 break; 1210 break;
1207 1211 case BPF_SK_SKB_STREAM_PARSER:
1212 case BPF_SK_SKB_STREAM_VERDICT:
1213 ret = sockmap_get_from_fd(attr, false);
1214 break;
1208 default: 1215 default:
1209 return -EINVAL; 1216 return -EINVAL;
1210 } 1217 }