-
Notifications
You must be signed in to change notification settings - Fork 54
Add CGROUP_SOCK_ADDR Set Support
#493
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
02b41ef
c241211
f88971e
a0ce260
9a79cd3
392e248
73c0dee
5ab9f35
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,15 +14,19 @@ | |
| #include <stdint.h> | ||
| #include <sys/socket.h> | ||
|
|
||
| #include <bpfilter/chain.h> | ||
| #include <bpfilter/flavor.h> | ||
| #include <bpfilter/logger.h> | ||
| #include <bpfilter/matcher.h> | ||
| #include <bpfilter/runtime.h> | ||
| #include <bpfilter/set.h> | ||
| #include <bpfilter/verdict.h> | ||
|
|
||
| #include "cgen/matcher/cmp.h" | ||
| #include "cgen/matcher/meta.h" | ||
| #include "cgen/matcher/set.h" | ||
| #include "cgen/program.h" | ||
| #include "cgen/stub.h" | ||
| #include "cgen/swich.h" | ||
| #include "filter.h" | ||
|
|
||
|
|
@@ -204,6 +208,99 @@ static int _bf_cgroup_sock_addr_generate_port(struct bf_program *program, | |
| bf_matcher_payload(matcher), 2, BPF_REG_1); | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Claude: nit: |
||
|
|
||
| static size_t _bf_cgroup_sock_addr_ctx_offset(enum bf_matcher_type type) | ||
| { | ||
| switch (type) { | ||
| case BF_MATCHER_IP4_SADDR: | ||
| case BF_MATCHER_IP4_SNET: | ||
| return offsetof(struct bpf_sock_addr, msg_src_ip4); | ||
| case BF_MATCHER_IP4_DADDR: | ||
| case BF_MATCHER_IP4_DNET: | ||
| return offsetof(struct bpf_sock_addr, user_ip4); | ||
| case BF_MATCHER_IP6_SADDR: | ||
| case BF_MATCHER_IP6_SNET: | ||
| return offsetof(struct bpf_sock_addr, msg_src_ip6); | ||
| case BF_MATCHER_IP6_DADDR: | ||
| case BF_MATCHER_IP6_DNET: | ||
| return offsetof(struct bpf_sock_addr, user_ip6); | ||
| case BF_MATCHER_IP4_PROTO: | ||
| return offsetof(struct bpf_sock_addr, protocol); | ||
| case BF_MATCHER_TCP_DPORT: | ||
yaakov-stein marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| case BF_MATCHER_UDP_DPORT: | ||
| return offsetof(struct bpf_sock_addr, user_port); | ||
| default: | ||
| return (size_t)-1; | ||
| } | ||
| } | ||
|
|
||
| static int _bf_cgroup_sock_addr_generate_set(struct bf_program *program, | ||
| const struct bf_matcher *matcher) | ||
| { | ||
| assert(program); | ||
| assert(matcher); | ||
|
|
||
| const struct bf_set *set = | ||
| bf_chain_get_set_for_matcher(program->runtime.chain, matcher); | ||
| size_t offset = 0; | ||
| int r; | ||
|
|
||
| if (!set) { | ||
| return bf_err_r(-ENOENT, "set #%u not found in %s", | ||
| *(uint32_t *)bf_matcher_payload(matcher), | ||
| program->runtime.chain->name); | ||
| } | ||
|
|
||
| if (set->use_trie) { | ||
yaakov-stein marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| const struct bf_matcher_meta *meta = bf_matcher_get_meta(set->key[0]); | ||
| size_t ctx_off = _bf_cgroup_sock_addr_ctx_offset(set->key[0]); | ||
|
|
||
| if (!meta) { | ||
| return bf_err_r(-EINVAL, "missing meta for set component '%s'", | ||
| bf_matcher_type_to_str(set->key[0])); | ||
| } | ||
|
|
||
| if (ctx_off == (size_t)-1) { | ||
| return bf_err_r( | ||
| -ENOTSUP, | ||
| "set component '%s' not supported for cgroup_sock_addr", | ||
| bf_matcher_type_to_str(set->key[0])); | ||
| } | ||
|
|
||
| return bf_set_generate_trie_lookup(program, matcher, ctx_off, | ||
| meta->hdr_payload_size); | ||
| } | ||
|
|
||
| for (size_t i = 0; i < set->n_comps; ++i) { | ||
| enum bf_matcher_type type = set->key[i]; | ||
| const struct bf_matcher_meta *meta = bf_matcher_get_meta(type); | ||
| size_t ctx_off = _bf_cgroup_sock_addr_ctx_offset(type); | ||
|
|
||
| if (!meta) { | ||
| return bf_err_r(-EINVAL, "missing meta for set component '%s'", | ||
| bf_matcher_type_to_str(type)); | ||
| } | ||
|
|
||
| if (ctx_off == (size_t)-1) { | ||
| return bf_err_r( | ||
| -ENOTSUP, | ||
| "set component '%s' not supported for cgroup_sock_addr", | ||
| bf_matcher_type_to_str(type)); | ||
| } | ||
|
|
||
| /* For ports, `hdr_payload_size` is 2 but `user_port` is a | ||
| * 4-byte `__u32`. The BPF verifier rewrites this 2-byte narrow | ||
| * ctx read to extract the correct NBO port value. */ | ||
| r = bf_stub_load(program, ctx_off, meta->hdr_payload_size, | ||
yaakov-stein marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| BF_PROG_SCR_OFF(offset)); | ||
| if (r) | ||
| return r; | ||
|
|
||
| offset += meta->hdr_payload_size; | ||
| } | ||
|
|
||
| return bf_set_generate_map_lookup(program, matcher, BF_PROG_SCR_OFF(0)); | ||
| } | ||
|
|
||
| static int | ||
| _bf_cgroup_sock_addr_gen_inline_matcher(struct bf_program *program, | ||
| const struct bf_matcher *matcher) | ||
|
|
@@ -248,6 +345,8 @@ _bf_cgroup_sock_addr_gen_inline_matcher(struct bf_program *program, | |
| case BF_MATCHER_TCP_DPORT: | ||
| case BF_MATCHER_UDP_DPORT: | ||
| return _bf_cgroup_sock_addr_generate_port(program, matcher); | ||
| case BF_MATCHER_SET: | ||
| return _bf_cgroup_sock_addr_generate_set(program, matcher); | ||
| default: | ||
| return bf_err_r(-ENOTSUP, | ||
| "matcher '%s' not supported for cgroup_sock_addr", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,9 +14,11 @@ | |
| #include <errno.h> | ||
| #include <stdint.h> | ||
|
|
||
| #include <bpfilter/chain.h> | ||
| #include <bpfilter/helper.h> | ||
| #include <bpfilter/logger.h> | ||
| #include <bpfilter/matcher.h> | ||
| #include <bpfilter/set.h> | ||
|
|
||
| #include "cgen/matcher/cmp.h" | ||
| #include "cgen/matcher/meta.h" | ||
|
|
@@ -296,6 +298,64 @@ static int _bf_matcher_pkt_generate_ip6_dscp(struct bf_program *program, | |
| return 0; | ||
| } | ||
|
|
||
| static int _bf_matcher_pkt_generate_set(struct bf_program *program, | ||
| const struct bf_matcher *matcher) | ||
| { | ||
| assert(program); | ||
| assert(matcher); | ||
|
|
||
| const struct bf_set *set = | ||
| bf_chain_get_set_for_matcher(program->runtime.chain, matcher); | ||
| size_t offset = 0; | ||
| int r; | ||
|
|
||
| if (!set) { | ||
| return bf_err_r(-ENOENT, "set #%u not found in %s", | ||
| *(uint32_t *)bf_matcher_payload(matcher), | ||
| program->runtime.chain->name); | ||
| } | ||
|
|
||
yaakov-stein marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if (set->use_trie) { | ||
| const struct bf_matcher_meta *meta = bf_matcher_get_meta(set->key[0]); | ||
|
|
||
yaakov-stein marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if (!meta) { | ||
| return bf_err_r(-EINVAL, "missing meta for '%s'", | ||
| bf_matcher_type_to_str(set->key[0])); | ||
| } | ||
|
|
||
| r = bf_stub_load_header(program, meta, BPF_REG_6); | ||
| if (r) | ||
| return bf_err_r(r, "failed to load protocol header into BPF_REG_6"); | ||
|
|
||
| return bf_set_generate_trie_lookup( | ||
| program, matcher, meta->hdr_payload_offset, meta->hdr_payload_size); | ||
| } | ||
|
|
||
| for (size_t i = 0; i < set->n_comps; ++i) { | ||
| enum bf_matcher_type type = set->key[i]; | ||
| const struct bf_matcher_meta *meta = bf_matcher_get_meta(type); | ||
|
|
||
| if (!meta) { | ||
| return bf_err_r(-EINVAL, "missing meta for '%s'", | ||
| bf_matcher_type_to_str(type)); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Claude: suggestion: In the hash-map loop of Consider tracking the loaded layer (similar to how |
||
| } | ||
|
|
||
| r = bf_stub_load_header(program, meta, BPF_REG_6); | ||
| if (r) | ||
| return bf_err_r(r, "failed to load protocol header into BPF_REG_6"); | ||
|
|
||
| r = bf_stub_stx_payload(program, meta, offset); | ||
| if (r) { | ||
| return bf_err_r(r, | ||
| "failed to generate bytecode to load packet data"); | ||
| } | ||
|
|
||
| offset += meta->hdr_payload_size; | ||
| } | ||
|
|
||
| return bf_set_generate_map_lookup(program, matcher, BF_PROG_SCR_OFF(0)); | ||
| } | ||
|
|
||
| int bf_matcher_generate_packet(struct bf_program *program, | ||
| const struct bf_matcher *matcher) | ||
| { | ||
|
|
@@ -349,7 +409,7 @@ int bf_matcher_generate_packet(struct bf_program *program, | |
| case BF_MATCHER_IP6_DSCP: | ||
| return _bf_matcher_pkt_generate_ip6_dscp(program, matcher, meta); | ||
| case BF_MATCHER_SET: | ||
| return bf_matcher_generate_set(program, matcher); | ||
| return _bf_matcher_pkt_generate_set(program, matcher); | ||
| default: | ||
| return bf_err_r(-EINVAL, "unknown matcher type %d", | ||
| bf_matcher_get_type(matcher)); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
drive-by fix (document
ip6.d/saddrworks in sets)