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>
This commit is contained in:
John Fastabend
2017-09-08 14:00:49 -07:00
committed by David S. Miller
parent bbbe211c29
commit 5a67da2a71
4 changed files with 72 additions and 16 deletions

View File

@@ -1096,10 +1096,10 @@ static int bpf_obj_get(const union bpf_attr *attr)
#define BPF_PROG_ATTACH_LAST_FIELD attach_flags
static int sockmap_get_from_fd(const union bpf_attr *attr)
static int sockmap_get_from_fd(const union bpf_attr *attr, bool attach)
{
struct bpf_prog *prog = NULL;
int ufd = attr->target_fd;
struct bpf_prog *prog;
struct bpf_map *map;
struct fd f;
int err;
@@ -1109,16 +1109,20 @@ static int sockmap_get_from_fd(const union bpf_attr *attr)
if (IS_ERR(map))
return PTR_ERR(map);
prog = bpf_prog_get_type(attr->attach_bpf_fd, BPF_PROG_TYPE_SK_SKB);
if (IS_ERR(prog)) {
fdput(f);
return PTR_ERR(prog);
if (attach) {
prog = bpf_prog_get_type(attr->attach_bpf_fd,
BPF_PROG_TYPE_SK_SKB);
if (IS_ERR(prog)) {
fdput(f);
return PTR_ERR(prog);
}
}
err = sock_map_attach_prog(map, prog, attr->attach_type);
err = sock_map_prog(map, prog, attr->attach_type);
if (err) {
fdput(f);
bpf_prog_put(prog);
if (prog)
bpf_prog_put(prog);
return err;
}
@@ -1155,7 +1159,7 @@ static int bpf_prog_attach(const union bpf_attr *attr)
break;
case BPF_SK_SKB_STREAM_PARSER:
case BPF_SK_SKB_STREAM_VERDICT:
return sockmap_get_from_fd(attr);
return sockmap_get_from_fd(attr, true);
default:
return -EINVAL;
}
@@ -1204,7 +1208,10 @@ static int bpf_prog_detach(const union bpf_attr *attr)
ret = cgroup_bpf_update(cgrp, NULL, attr->attach_type, false);
cgroup_put(cgrp);
break;
case BPF_SK_SKB_STREAM_PARSER:
case BPF_SK_SKB_STREAM_VERDICT:
ret = sockmap_get_from_fd(attr, false);
break;
default:
return -EINVAL;
}