diff --git a/src/bpfilter/CMakeLists.txt b/src/bpfilter/CMakeLists.txt index f951efc7..d630c136 100644 --- a/src/bpfilter/CMakeLists.txt +++ b/src/bpfilter/CMakeLists.txt @@ -23,6 +23,7 @@ add_executable(bpfilter ${CMAKE_CURRENT_SOURCE_DIR}/cgen/matcher/tcp.h ${CMAKE_CURRENT_SOURCE_DIR}/cgen/matcher/tcp.c ${CMAKE_CURRENT_SOURCE_DIR}/cgen/matcher/udp.h ${CMAKE_CURRENT_SOURCE_DIR}/cgen/matcher/udp.c ${CMAKE_CURRENT_SOURCE_DIR}/cgen/matcher/meta.h ${CMAKE_CURRENT_SOURCE_DIR}/cgen/matcher/meta.c + ${CMAKE_CURRENT_SOURCE_DIR}/cgen/matcher/packet.h ${CMAKE_CURRENT_SOURCE_DIR}/cgen/matcher/packet.c ${CMAKE_CURRENT_SOURCE_DIR}/cgen/matcher/set.h ${CMAKE_CURRENT_SOURCE_DIR}/cgen/matcher/set.c ${CMAKE_CURRENT_SOURCE_DIR}/cgen/matcher/icmp.h ${CMAKE_CURRENT_SOURCE_DIR}/cgen/matcher/icmp.c ${CMAKE_CURRENT_SOURCE_DIR}/cgen/nf.h ${CMAKE_CURRENT_SOURCE_DIR}/cgen/nf.c diff --git a/src/bpfilter/cgen/cgroup_skb.c b/src/bpfilter/cgen/cgroup_skb.c index 00a276af..7d3330ea 100644 --- a/src/bpfilter/cgen/cgroup_skb.c +++ b/src/bpfilter/cgen/cgroup_skb.c @@ -15,9 +15,12 @@ #include #include #include +#include #include #include "cgen/cgen.h" +#include "cgen/matcher/meta.h" +#include "cgen/matcher/packet.h" #include "cgen/program.h" #include "cgen/stub.h" #include "cgen/swich.h" @@ -114,30 +117,35 @@ static int _bf_cgroup_skb_gen_inline_set_mark(struct bf_program *program, return 0; } -static int _bf_cgroup_skb_gen_inline_get_mark(struct bf_program *program, - int reg) +static int _bf_cgroup_skb_gen_inline_matcher(struct bf_program *program, + const struct bf_matcher *matcher) { - EMIT(program, - BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, BF_PROG_CTX_OFF(arg))); - EMIT(program, - BPF_LDX_MEM(BPF_W, reg, BPF_REG_1, offsetof(struct __sk_buff, mark))); + assert(program); + assert(matcher); - return 0; -} + switch (bf_matcher_get_type(matcher)) { + case BF_MATCHER_META_MARK: + EMIT(program, + BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, BF_PROG_CTX_OFF(arg))); + EMIT(program, BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1, + offsetof(struct __sk_buff, mark))); -static int _bf_cgroup_skb_gen_inline_get_skb(struct bf_program *program, - int reg) -{ - EMIT(program, BPF_LDX_MEM(BPF_DW, reg, BPF_REG_10, BF_PROG_CTX_OFF(arg))); + return bf_matcher_generate_meta_mark_cmp(program, matcher); + case BF_MATCHER_META_FLOW_HASH: + EMIT(program, + BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, BF_PROG_CTX_OFF(arg))); - return 0; + return bf_matcher_generate_meta_flow_hash_cmp(program, matcher); + default: + return bf_matcher_generate_packet(program, matcher); + } } /** * Convert a standard verdict into a return value. * * @param verdict Verdict to convert. Must be valid. - * @return TC return code corresponding to the verdict, as an integer. + * @return Cgroup return code corresponding to the verdict, as an integer. */ static int _bf_cgroup_skb_get_verdict(enum bf_verdict verdict) { @@ -155,7 +163,6 @@ const struct bf_flavor_ops bf_flavor_ops_cgroup_skb = { .gen_inline_prologue = _bf_cgroup_skb_gen_inline_prologue, .gen_inline_epilogue = _bf_cgroup_skb_gen_inline_epilogue, .gen_inline_set_mark = _bf_cgroup_skb_gen_inline_set_mark, - .gen_inline_get_mark = _bf_cgroup_skb_gen_inline_get_mark, - .gen_inline_get_skb = _bf_cgroup_skb_gen_inline_get_skb, .get_verdict = _bf_cgroup_skb_get_verdict, + .gen_inline_matcher = _bf_cgroup_skb_gen_inline_matcher, }; diff --git a/src/bpfilter/cgen/matcher/meta.c b/src/bpfilter/cgen/matcher/meta.c index 02f12300..719e3fb5 100644 --- a/src/bpfilter/cgen/matcher/meta.c +++ b/src/bpfilter/cgen/matcher/meta.c @@ -141,15 +141,15 @@ static int _bf_matcher_generate_meta_port(struct bf_program *program, return 0; } -static int _bf_matcher_generate_meta_mark(struct bf_program *program, - const struct bf_matcher *matcher) +int bf_matcher_generate_meta_mark_cmp(struct bf_program *program, + const struct bf_matcher *matcher) { - uint32_t mark = *(uint32_t *)bf_matcher_payload(matcher); - int r; + uint32_t mark; - r = program->runtime.ops->gen_inline_get_mark(program, BPF_REG_1); - if (r) - return bf_err_r(r, "failed to get inline mark"); + assert(program); + assert(matcher); + + mark = *(uint32_t *)bf_matcher_payload(matcher); switch (bf_matcher_get_op(matcher)) { case BF_MATCHER_EQ: @@ -169,15 +169,15 @@ static int _bf_matcher_generate_meta_mark(struct bf_program *program, return 0; } -static int _bf_matcher_generate_meta_flow_hash(struct bf_program *program, - const struct bf_matcher *matcher) +int bf_matcher_generate_meta_flow_hash_cmp(struct bf_program *program, + const struct bf_matcher *matcher) { - uint32_t *hash = (uint32_t *)bf_matcher_payload(matcher); - int r; + uint32_t *hash; - r = program->runtime.ops->gen_inline_get_skb(program, BPF_REG_1); - if (r) - return bf_err_r(r, "failed to get inline skb"); + assert(program); + assert(matcher); + + hash = (uint32_t *)bf_matcher_payload(matcher); EMIT(program, BPF_EMIT_CALL(BPF_FUNC_get_hash_recalc)); @@ -276,15 +276,14 @@ int bf_matcher_generate_meta(struct bf_program *program, case BF_MATCHER_META_DPORT: r = _bf_matcher_generate_meta_port(program, matcher); break; - case BF_MATCHER_META_MARK: - r = _bf_matcher_generate_meta_mark(program, matcher); - break; - case BF_MATCHER_META_FLOW_HASH: - r = _bf_matcher_generate_meta_flow_hash(program, matcher); - break; case BF_MATCHER_META_FLOW_PROBABILITY: r = _bf_matcher_generate_meta_flow_probability(program, matcher); break; + case BF_MATCHER_META_MARK: + case BF_MATCHER_META_FLOW_HASH: + return bf_err_r(-ENOTSUP, + "matcher '%s' requires flavor-specific dispatch", + bf_matcher_type_to_str(bf_matcher_get_type(matcher))); default: return bf_err_r(-EINVAL, "unknown matcher type %d", bf_matcher_get_type(matcher)); diff --git a/src/bpfilter/cgen/matcher/meta.h b/src/bpfilter/cgen/matcher/meta.h index 14791c92..7594c92c 100644 --- a/src/bpfilter/cgen/matcher/meta.h +++ b/src/bpfilter/cgen/matcher/meta.h @@ -10,3 +10,29 @@ struct bf_program; int bf_matcher_generate_meta(struct bf_program *program, const struct bf_matcher *matcher); + +/** + * @brief Generate bytecode to compare a packet mark. + * + * The mark value must already be loaded into `BPF_REG_1`. + * + * @param program Program being generated. Can't be NULL. + * @param matcher Matcher to generate comparison for. Can't be NULL. + * @return 0 on success, negative errno on error. + */ +int bf_matcher_generate_meta_mark_cmp(struct bf_program *program, + const struct bf_matcher *matcher); + +/** + * @brief Generate bytecode to compute and compare a flow hash. + * + * The skb pointer must already be loaded into `BPF_REG_1`. Calls + * `bpf_get_hash_recalc` on the skb, then compares the result against the + * matcher's payload. + * + * @param program Program being generated. Can't be NULL. + * @param matcher Matcher to generate comparison for. Can't be NULL. + * @return 0 on success, negative errno on error. + */ +int bf_matcher_generate_meta_flow_hash_cmp(struct bf_program *program, + const struct bf_matcher *matcher); diff --git a/src/bpfilter/cgen/matcher/packet.c b/src/bpfilter/cgen/matcher/packet.c new file mode 100644 index 00000000..ece0a008 --- /dev/null +++ b/src/bpfilter/cgen/matcher/packet.c @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + */ + +#include "cgen/matcher/packet.h" + +#include + +#include +#include +#include + +#include "cgen/matcher/icmp.h" +#include "cgen/matcher/ip4.h" +#include "cgen/matcher/ip6.h" +#include "cgen/matcher/meta.h" +#include "cgen/matcher/set.h" +#include "cgen/matcher/tcp.h" +#include "cgen/matcher/udp.h" +#include "cgen/program.h" + +int bf_matcher_generate_packet(struct bf_program *program, + const struct bf_matcher *matcher) +{ + assert(program); + assert(matcher); + + switch (bf_matcher_get_type(matcher)) { + case BF_MATCHER_META_IFACE: + case BF_MATCHER_META_L3_PROTO: + case BF_MATCHER_META_L4_PROTO: + case BF_MATCHER_META_PROBABILITY: + case BF_MATCHER_META_SPORT: + case BF_MATCHER_META_DPORT: + case BF_MATCHER_META_FLOW_PROBABILITY: + return bf_matcher_generate_meta(program, matcher); + case BF_MATCHER_META_MARK: + case BF_MATCHER_META_FLOW_HASH: + return bf_err_r(-ENOTSUP, + "matcher '%s' is not supported by this flavor", + bf_matcher_type_to_str(bf_matcher_get_type(matcher))); + case BF_MATCHER_IP4_SADDR: + case BF_MATCHER_IP4_SNET: + case BF_MATCHER_IP4_DADDR: + case BF_MATCHER_IP4_DNET: + case BF_MATCHER_IP4_PROTO: + case BF_MATCHER_IP4_DSCP: + return bf_matcher_generate_ip4(program, matcher); + case BF_MATCHER_IP6_SADDR: + case BF_MATCHER_IP6_SNET: + case BF_MATCHER_IP6_DADDR: + case BF_MATCHER_IP6_DNET: + case BF_MATCHER_IP6_NEXTHDR: + case BF_MATCHER_IP6_DSCP: + return bf_matcher_generate_ip6(program, matcher); + case BF_MATCHER_TCP_SPORT: + case BF_MATCHER_TCP_DPORT: + case BF_MATCHER_TCP_FLAGS: + return bf_matcher_generate_tcp(program, matcher); + case BF_MATCHER_UDP_SPORT: + case BF_MATCHER_UDP_DPORT: + return bf_matcher_generate_udp(program, matcher); + case BF_MATCHER_ICMP_TYPE: + case BF_MATCHER_ICMP_CODE: + case BF_MATCHER_ICMPV6_TYPE: + case BF_MATCHER_ICMPV6_CODE: + return bf_matcher_generate_icmp(program, matcher); + case BF_MATCHER_SET: + return bf_matcher_generate_set(program, matcher); + default: + return bf_err_r(-EINVAL, "unknown matcher type %d", + bf_matcher_get_type(matcher)); + } +} diff --git a/src/bpfilter/cgen/matcher/packet.h b/src/bpfilter/cgen/matcher/packet.h new file mode 100644 index 00000000..54acd0a1 --- /dev/null +++ b/src/bpfilter/cgen/matcher/packet.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + */ + +#pragma once + +struct bf_matcher; +struct bf_program; + +/** + * @brief Generate bytecode for a packet-based matcher. + * + * Dispatches to the appropriate matcher codegen function based on the matcher + * type. Handles all matchers that operate on packet headers or metadata common + * to all packet-based flavors. + * + * `BF_MATCHER_META_MARK` and `BF_MATCHER_META_FLOW_HASH` are not supported + * by this function and return `-ENOTSUP`, as they require flavor-specific + * context access. + * + * @param program Program being generated. Can't be NULL. + * @param matcher Matcher to generate code for. Can't be NULL. + * @return 0 on success, negative errno on error. + */ +int bf_matcher_generate_packet(struct bf_program *program, + const struct bf_matcher *matcher); diff --git a/src/bpfilter/cgen/nf.c b/src/bpfilter/cgen/nf.c index 8d2957b7..9f3984d1 100644 --- a/src/bpfilter/cgen/nf.c +++ b/src/bpfilter/cgen/nf.c @@ -19,9 +19,12 @@ #include #include #include +#include #include #include "cgen/jmp.h" +#include "cgen/matcher/meta.h" +#include "cgen/matcher/packet.h" #include "cgen/program.h" #include "cgen/stub.h" #include "cgen/swich.h" @@ -124,38 +127,44 @@ static int _bf_nf_gen_inline_epilogue(struct bf_program *program) return 0; } -static int _bf_nf_gen_inline_get_mark(struct bf_program *program, int reg) +static int _bf_nf_gen_inline_matcher(struct bf_program *program, + const struct bf_matcher *matcher) { int offset; - EMIT(program, - BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, BF_PROG_CTX_OFF(arg))); - if ((offset = bf_btf_get_field_off("bpf_nf_ctx", "skb")) < 0) - return offset; - EMIT(program, BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, offset)); - if ((offset = bf_btf_get_field_off("sk_buff", "mark")) < 0) - return offset; - EMIT(program, BPF_LDX_MEM(BPF_W, reg, BPF_REG_2, offset)); - - return 0; -} + assert(program); + assert(matcher); -static int _bf_nf_gen_inline_get_skb(struct bf_program *program, int reg) -{ - int offset; + switch (bf_matcher_get_type(matcher)) { + case BF_MATCHER_META_MARK: + EMIT(program, + BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, BF_PROG_CTX_OFF(arg))); + if ((offset = bf_btf_get_field_off("bpf_nf_ctx", "skb")) < 0) + return offset; + EMIT(program, BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, offset)); + if ((offset = bf_btf_get_field_off("sk_buff", "mark")) < 0) + return offset; + EMIT(program, BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_2, offset)); - EMIT(program, BPF_LDX_MEM(BPF_DW, reg, BPF_REG_10, BF_PROG_CTX_OFF(arg))); - if ((offset = bf_btf_get_field_off("bpf_nf_ctx", "skb")) < 0) - return offset; + return bf_matcher_generate_meta_mark_cmp(program, matcher); + case BF_MATCHER_META_FLOW_HASH: + EMIT(program, + BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, BF_PROG_CTX_OFF(arg))); + if ((offset = bf_btf_get_field_off("bpf_nf_ctx", "skb")) < 0) + return offset; + EMIT(program, BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, offset)); - return 0; + return bf_matcher_generate_meta_flow_hash_cmp(program, matcher); + default: + return bf_matcher_generate_packet(program, matcher); + } } /** * Convert a standard verdict into a return value. * * @param verdict Verdict to convert. Must be valid. - * @return TC return code corresponding to the verdict, as an integer. + * @return Netfilter return code corresponding to the verdict, as an integer. */ static int _bf_nf_get_verdict(enum bf_verdict verdict) { @@ -172,7 +181,6 @@ static int _bf_nf_get_verdict(enum bf_verdict verdict) const struct bf_flavor_ops bf_flavor_ops_nf = { .gen_inline_prologue = _bf_nf_gen_inline_prologue, .gen_inline_epilogue = _bf_nf_gen_inline_epilogue, - .gen_inline_get_mark = _bf_nf_gen_inline_get_mark, - .gen_inline_get_skb = _bf_nf_gen_inline_get_skb, .get_verdict = _bf_nf_get_verdict, + .gen_inline_matcher = _bf_nf_gen_inline_matcher, }; diff --git a/src/bpfilter/cgen/program.c b/src/bpfilter/cgen/program.c index 33853f0c..9f98f64e 100644 --- a/src/bpfilter/cgen/program.c +++ b/src/bpfilter/cgen/program.c @@ -41,13 +41,7 @@ #include "cgen/fixup.h" #include "cgen/handle.h" #include "cgen/jmp.h" -#include "cgen/matcher/icmp.h" -#include "cgen/matcher/ip4.h" -#include "cgen/matcher/ip6.h" -#include "cgen/matcher/meta.h" -#include "cgen/matcher/set.h" -#include "cgen/matcher/tcp.h" -#include "cgen/matcher/udp.h" +#include "cgen/matcher/packet.h" #include "cgen/nf.h" #include "cgen/printer.h" #include "cgen/prog/link.h" @@ -299,73 +293,14 @@ static int _bf_program_generate_rule(struct bf_program *program, if (rule->disabled) return 0; + assert(program->runtime.ops->gen_inline_matcher); + bf_list_foreach (&rule->matchers, matcher_node) { struct bf_matcher *matcher = bf_list_node_get_data(matcher_node); - switch (bf_matcher_get_type(matcher)) { - case BF_MATCHER_META_IFACE: - case BF_MATCHER_META_L3_PROTO: - case BF_MATCHER_META_L4_PROTO: - case BF_MATCHER_META_PROBABILITY: - case BF_MATCHER_META_SPORT: - case BF_MATCHER_META_DPORT: - case BF_MATCHER_META_MARK: - case BF_MATCHER_META_FLOW_HASH: - case BF_MATCHER_META_FLOW_PROBABILITY: - r = bf_matcher_generate_meta(program, matcher); - if (r) - return r; - break; - case BF_MATCHER_IP4_SADDR: - case BF_MATCHER_IP4_SNET: - case BF_MATCHER_IP4_DADDR: - case BF_MATCHER_IP4_DNET: - case BF_MATCHER_IP4_PROTO: - case BF_MATCHER_IP4_DSCP: - r = bf_matcher_generate_ip4(program, matcher); - if (r) - return r; - break; - case BF_MATCHER_IP6_SADDR: - case BF_MATCHER_IP6_SNET: - case BF_MATCHER_IP6_DADDR: - case BF_MATCHER_IP6_DNET: - case BF_MATCHER_IP6_NEXTHDR: - case BF_MATCHER_IP6_DSCP: - r = bf_matcher_generate_ip6(program, matcher); - if (r) - return r; - break; - case BF_MATCHER_TCP_SPORT: - case BF_MATCHER_TCP_DPORT: - case BF_MATCHER_TCP_FLAGS: - r = bf_matcher_generate_tcp(program, matcher); - if (r) - return r; - break; - case BF_MATCHER_UDP_SPORT: - case BF_MATCHER_UDP_DPORT: - r = bf_matcher_generate_udp(program, matcher); - if (r) - return r; - break; - case BF_MATCHER_ICMP_TYPE: - case BF_MATCHER_ICMP_CODE: - case BF_MATCHER_ICMPV6_TYPE: - case BF_MATCHER_ICMPV6_CODE: - r = bf_matcher_generate_icmp(program, matcher); - if (r) - return r; - break; - case BF_MATCHER_SET: - r = bf_matcher_generate_set(program, matcher); - if (r) - return r; - break; - default: - return bf_err_r(-EINVAL, "unknown matcher type %d", - bf_matcher_get_type(matcher)); - }; + r = program->runtime.ops->gen_inline_matcher(program, matcher); + if (r) + return r; } if (bf_rule_mark_is_set(rule)) { diff --git a/src/bpfilter/cgen/tc.c b/src/bpfilter/cgen/tc.c index 3571bb2f..077f8d01 100644 --- a/src/bpfilter/cgen/tc.c +++ b/src/bpfilter/cgen/tc.c @@ -15,9 +15,12 @@ #include #include #include +#include #include #include "cgen/cgen.h" +#include "cgen/matcher/meta.h" +#include "cgen/matcher/packet.h" #include "cgen/program.h" #include "cgen/stub.h" #include "filter.h" @@ -85,21 +88,28 @@ static int _bf_tc_gen_inline_set_mark(struct bf_program *program, uint32_t mark) return 0; } -static int _bf_tc_gen_inline_get_mark(struct bf_program *program, int reg) +static int _bf_tc_gen_inline_matcher(struct bf_program *program, + const struct bf_matcher *matcher) { - EMIT(program, - BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, BF_PROG_CTX_OFF(arg))); - EMIT(program, - BPF_LDX_MEM(BPF_W, reg, BPF_REG_1, offsetof(struct __sk_buff, mark))); + assert(program); + assert(matcher); - return 0; -} + switch (bf_matcher_get_type(matcher)) { + case BF_MATCHER_META_MARK: + EMIT(program, + BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, BF_PROG_CTX_OFF(arg))); + EMIT(program, BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_1, + offsetof(struct __sk_buff, mark))); -static int _bf_tc_gen_inline_get_skb(struct bf_program *program, int reg) -{ - EMIT(program, BPF_LDX_MEM(BPF_DW, reg, BPF_REG_10, BF_PROG_CTX_OFF(arg))); + return bf_matcher_generate_meta_mark_cmp(program, matcher); + case BF_MATCHER_META_FLOW_HASH: + EMIT(program, + BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, BF_PROG_CTX_OFF(arg))); - return 0; + return bf_matcher_generate_meta_flow_hash_cmp(program, matcher); + default: + return bf_matcher_generate_packet(program, matcher); + } } /** @@ -154,8 +164,7 @@ const struct bf_flavor_ops bf_flavor_ops_tc = { .gen_inline_prologue = _bf_tc_gen_inline_prologue, .gen_inline_epilogue = _bf_tc_gen_inline_epilogue, .gen_inline_set_mark = _bf_tc_gen_inline_set_mark, - .gen_inline_get_mark = _bf_tc_gen_inline_get_mark, - .gen_inline_get_skb = _bf_tc_gen_inline_get_skb, .gen_inline_redirect = _bf_tc_gen_inline_redirect, .get_verdict = _bf_tc_get_verdict, + .gen_inline_matcher = _bf_tc_gen_inline_matcher, }; diff --git a/src/bpfilter/cgen/xdp.c b/src/bpfilter/cgen/xdp.c index 58376e4e..a57ddeec 100644 --- a/src/bpfilter/cgen/xdp.c +++ b/src/bpfilter/cgen/xdp.c @@ -14,6 +14,7 @@ #include #include +#include "cgen/matcher/packet.h" #include "cgen/program.h" #include "cgen/stub.h" #include "filter.h" @@ -123,4 +124,5 @@ const struct bf_flavor_ops bf_flavor_ops_xdp = { .gen_inline_epilogue = _bf_xdp_gen_inline_epilogue, .gen_inline_redirect = _bf_xdp_gen_inline_redirect, .get_verdict = _bf_xdp_get_verdict, + .gen_inline_matcher = bf_matcher_generate_packet, }; diff --git a/src/libbpfilter/include/bpfilter/flavor.h b/src/libbpfilter/include/bpfilter/flavor.h index 8464ce6d..0605fac9 100644 --- a/src/libbpfilter/include/bpfilter/flavor.h +++ b/src/libbpfilter/include/bpfilter/flavor.h @@ -9,6 +9,7 @@ #include +struct bf_matcher; struct bf_program; /** @@ -91,8 +92,6 @@ struct bf_flavor_ops int (*gen_inline_epilogue)(struct bf_program *program); int (*gen_inline_set_mark)(struct bf_program *program, uint32_t mark); - int (*gen_inline_get_mark)(struct bf_program *program, int reg); - int (*gen_inline_get_skb)(struct bf_program *program, int reg); /** * @brief Generate bytecode to redirect a packet to another interface. @@ -117,6 +116,16 @@ struct bf_flavor_ops * value on failure. */ int (*get_verdict)(enum bf_verdict verdict); + + /** + * @brief Generate bytecode for a matcher. Required for all flavors. + * + * @param program Program being generated. Can't be NULL. + * @param matcher Matcher to generate code for. Can't be NULL. + * @return 0 on success, negative errno on error. + */ + int (*gen_inline_matcher)(struct bf_program *program, + const struct bf_matcher *matcher); }; /**