Skip to content

Commit 2019d91

Browse files
committed
daemon: cgen: add cgroup_sock_addr flavor codegen
Implement bf_flavor_ops for BF_FLAVOR_CGROUP_SOCK_ADDR so chains with a default policy can be loaded and attached to a cgroup.
1 parent 18ab8e6 commit 2019d91

File tree

7 files changed

+122
-5
lines changed

7 files changed

+122
-5
lines changed

src/bpfilter/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ add_executable(bpfilter
1414
${CMAKE_CURRENT_SOURCE_DIR}/opts.h ${CMAKE_CURRENT_SOURCE_DIR}/opts.c
1515
${CMAKE_CURRENT_SOURCE_DIR}/cgen/cgen.h ${CMAKE_CURRENT_SOURCE_DIR}/cgen/cgen.c
1616
${CMAKE_CURRENT_SOURCE_DIR}/cgen/cgroup_skb.h ${CMAKE_CURRENT_SOURCE_DIR}/cgen/cgroup_skb.c
17+
${CMAKE_CURRENT_SOURCE_DIR}/cgen/cgroup_sock_addr.h ${CMAKE_CURRENT_SOURCE_DIR}/cgen/cgroup_sock_addr.c
1718
${CMAKE_CURRENT_SOURCE_DIR}/cgen/dump.h ${CMAKE_CURRENT_SOURCE_DIR}/cgen/dump.c
1819
${CMAKE_CURRENT_SOURCE_DIR}/cgen/elfstub.h ${CMAKE_CURRENT_SOURCE_DIR}/cgen/elfstub.c
1920
${CMAKE_CURRENT_SOURCE_DIR}/cgen/fixup.h ${CMAKE_CURRENT_SOURCE_DIR}/cgen/fixup.c
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* Copyright (c) 2023 Meta Platforms, Inc. and affiliates.
4+
*/
5+
6+
#include "cgen/cgroup_sock_addr.h"
7+
8+
#include <linux/bpf_common.h>
9+
#include <linux/if_ether.h>
10+
11+
#include <assert.h>
12+
#include <errno.h>
13+
#include <stddef.h>
14+
#include <sys/socket.h>
15+
16+
#include <bpfilter/flavor.h>
17+
#include <bpfilter/verdict.h>
18+
19+
#include "cgen/program.h"
20+
#include "cgen/swich.h"
21+
#include "filter.h"
22+
#include "linux/bpf.h"
23+
24+
// Forward definition to avoid headers clusterfuck.
25+
uint16_t htons(uint16_t hostshort);
26+
27+
static int _bf_cgroup_sock_addr_gen_inline_prologue(struct bf_program *program)
28+
{
29+
int r;
30+
31+
assert(program);
32+
33+
// The counters stub reads pkt_size unconditionally; zero it out.
34+
EMIT(program, BPF_ST_MEM(BPF_DW, BPF_REG_10, BF_PROG_CTX_OFF(pkt_size), 0));
35+
36+
/* Convert bpf_sock_addr.family to L3 protocol ID in R7, using the same
37+
* bf_swich pattern as cgroup_skb. */
38+
EMIT(program, BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
39+
offsetof(struct bpf_sock_addr, family)));
40+
41+
{
42+
_clean_bf_swich_ struct bf_swich swich =
43+
bf_swich_get(program, BPF_REG_2);
44+
45+
EMIT_SWICH_OPTION(&swich, AF_INET,
46+
BPF_MOV64_IMM(BPF_REG_7, htons(ETH_P_IP)));
47+
EMIT_SWICH_OPTION(&swich, AF_INET6,
48+
BPF_MOV64_IMM(BPF_REG_7, htons(ETH_P_IPV6)));
49+
EMIT_SWICH_DEFAULT(&swich, BPF_MOV64_IMM(BPF_REG_7, 0));
50+
51+
r = bf_swich_generate(&swich);
52+
if (r)
53+
return r;
54+
}
55+
56+
EMIT(program, BPF_LDX_MEM(BPF_W, BPF_REG_8, BPF_REG_1,
57+
offsetof(struct bpf_sock_addr, protocol)));
58+
59+
return 0;
60+
}
61+
62+
static int _bf_cgroup_sock_addr_gen_inline_epilogue(struct bf_program *program)
63+
{
64+
(void)program;
65+
66+
return 0;
67+
}
68+
69+
static int
70+
_bf_cgroup_sock_addr_gen_inline_matcher(struct bf_program *program,
71+
const struct bf_matcher *matcher)
72+
{
73+
(void)program;
74+
(void)matcher;
75+
76+
return -ENOTSUP;
77+
}
78+
79+
/**
80+
* Convert a standard verdict into a return value.
81+
*
82+
* @param verdict Verdict to convert. Must be valid.
83+
* @return Cgroup return code corresponding to the verdict, as an integer.
84+
*/
85+
static int _bf_cgroup_sock_addr_get_verdict(enum bf_verdict verdict)
86+
{
87+
switch (verdict) {
88+
case BF_VERDICT_ACCEPT:
89+
return 1;
90+
case BF_VERDICT_DROP:
91+
return 0;
92+
default:
93+
return -ENOTSUP;
94+
}
95+
}
96+
97+
const struct bf_flavor_ops bf_flavor_ops_cgroup_sock_addr = {
98+
.gen_inline_prologue = _bf_cgroup_sock_addr_gen_inline_prologue,
99+
.gen_inline_epilogue = _bf_cgroup_sock_addr_gen_inline_epilogue,
100+
.get_verdict = _bf_cgroup_sock_addr_get_verdict,
101+
.gen_inline_matcher = _bf_cgroup_sock_addr_gen_inline_matcher,
102+
};
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* Copyright (c) 2023 Meta Platforms, Inc. and affiliates.
4+
*/
5+
6+
#pragma once
7+
8+
#include <bpfilter/flavor.h>
9+
10+
extern const struct bf_flavor_ops bf_flavor_ops_cgroup_sock_addr;

src/bpfilter/cgen/prog/link.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ int bf_link_new(struct bf_link **link, const char *name, enum bf_hook hook,
7373
fd = r;
7474
break;
7575
case BF_FLAVOR_CGROUP_SKB:
76+
case BF_FLAVOR_CGROUP_SOCK_ADDR:
7677
cgroup_fd = open(_hookopts->cgpath, O_DIRECTORY | O_RDONLY);
7778
if (cgroup_fd < 0) {
7879
return bf_err_r(errno, "failed to open cgroup '%s'",
@@ -81,7 +82,7 @@ int bf_link_new(struct bf_link **link, const char *name, enum bf_hook hook,
8182

8283
r = bf_bpf_link_create(prog_fd, cgroup_fd, hook, 0, 0, 0);
8384
if (r < 0)
84-
return bf_err_r(r, "failed to create cgroup_skb BPF link");
85+
return bf_err_r(r, "failed to create cgroup BPF link");
8586

8687
fd = r;
8788
break;
@@ -291,6 +292,7 @@ int bf_link_update(struct bf_link *link, int prog_fd)
291292
case BF_FLAVOR_XDP:
292293
case BF_FLAVOR_TC:
293294
case BF_FLAVOR_CGROUP_SKB:
295+
case BF_FLAVOR_CGROUP_SOCK_ADDR:
294296
r = bf_bpf_link_update(link->fd, prog_fd);
295297
break;
296298
case BF_FLAVOR_NF:

src/bpfilter/cgen/program.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <bpfilter/verdict.h>
3838

3939
#include "cgen/cgroup_skb.h"
40+
#include "cgen/cgroup_sock_addr.h"
4041
#include "cgen/dump.h"
4142
#include "cgen/fixup.h"
4243
#include "cgen/handle.h"
@@ -83,7 +84,7 @@ static const struct bf_flavor_ops *bf_flavor_ops_get(enum bf_flavor flavor)
8384
[BF_FLAVOR_NF] = &bf_flavor_ops_nf,
8485
[BF_FLAVOR_XDP] = &bf_flavor_ops_xdp,
8586
[BF_FLAVOR_CGROUP_SKB] = &bf_flavor_ops_cgroup_skb,
86-
[BF_FLAVOR_CGROUP_SOCK_ADDR] = NULL,
87+
[BF_FLAVOR_CGROUP_SOCK_ADDR] = &bf_flavor_ops_cgroup_sock_addr,
8788
};
8889

8990
static_assert_enum_mapping(flavor_ops, _BF_FLAVOR_MAX);

src/bpfilter/cgen/runtime.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ struct bf_runtime
7575
* - `BF_FLAVOR_XDP`: `struct xdp_md *`
7676
* - `BF_FLAVOR_TC`: `struct struct __sk_buff *`
7777
* - `BF_FLAVOR_CGROUP_SKB`: `struct __sk_buff *`
78-
* - `BF_FLAVOR_NF`: `struct bpf_nf_ctx *` */
78+
* - `BF_FLAVOR_NF`: `struct bpf_nf_ctx *`
79+
* - `BF_FLAVOR_CGROUP_SOCK_ADDR`: `struct bpf_sock_addr *` */
7980
void *arg;
8081

8182
/** BPF dynamic pointer to access the packet data. Dynamic pointers are
@@ -85,7 +86,7 @@ struct bf_runtime
8586
/** Ring buffer map containing the logged packets. */
8687
void *log_map;
8788

88-
/** Total size of the packet. */
89+
/** Total size of the packet, or 0 for non-packet flavors. */
8990
__u64 pkt_size;
9091

9192
/** IPv6 extension header mask */

src/libbpfilter/include/bpfilter/flavor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ enum bf_flavor
6767
* cgroup_sock_addr BPF programs, attached to a cgroup to intercept
6868
* socket operations (connect, bind, sendmsg, recvmsg):
6969
* - Input: `struct bpf_sock_addr`
70-
* - Headers available: from L3
70+
* - No packet data; L3/L4 protocol from socket metadata
7171
* - Return code: 0 to drop, 1 to accept
7272
*/
7373
BF_FLAVOR_CGROUP_SOCK_ADDR,

0 commit comments

Comments
 (0)