Conversation
3d56c6e to
63e5923
Compare
qdeslandes
left a comment
There was a problem hiding this comment.
I went for an early review, mostly for the parsing part. On the BPF side, the map will contain the runtime values for a given rule's rate limit (current burst/allowance, limit, last update time...).
df768e9 to
fd116e7
Compare
|
Here is a working POC Things done:
Things remaining:
Testing: There's a bunch of doc to do and leftover comments to remove, but that should be enough to swi(t)ch this PR from draft to "ready-for-review" now that the feature is working ! |
src/bpfilter/cgen/program.c
Outdated
| EMIT(program, BPF_MOV32_IMM(BPF_REG_3, rule->ratelimit)); | ||
| EMIT_FIXUP_ELFSTUB(program, BF_ELFSTUB_RATELIMIT); | ||
|
|
||
| _clean_bf_jmpctx_ struct bf_jmpctx ctx = |
There was a problem hiding this comment.
Variables are defined at the beginning of the scope.
There was a problem hiding this comment.
Like this ?
if (rule->ratelimit) {
EMIT_LOAD_RATELIMIT_FD_FIXUP(program, BPF_REG_1);
EMIT(program, BPF_MOV32_IMM(BPF_REG_2, rule->index));
EMIT(program, BPF_MOV32_IMM(BPF_REG_3, rule->ratelimit));
EMIT_FIXUP_ELFSTUB(program, BF_ELFSTUB_RATELIMIT);
+ {
_clean_bf_jmpctx_ struct bf_jmpctx ctx =
bf_jmpctx_get(program, BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 0));
EMIT(program,
BPF_MOV64_IMM(BPF_REG_0,
program->runtime.ops->get_verdict(BF_VERDICT_DROP)));
EMIT(program, BPF_EXIT_INSN());
+ }
}
src/bpfilter/cgen/program.c
Outdated
| EMIT(program, | ||
| BPF_MOV64_IMM(BPF_REG_0, | ||
| program->runtime.ops->get_verdict(BF_VERDICT_DROP))); | ||
| EMIT(program, BPF_EXIT_INSN()); |
There was a problem hiding this comment.
We need to think this through. With the current implementation: if the rate limit is reached, all extra packet matching the rule are dropped. What if the rule already drops the packet? Then you drop all the matching packets, meaning the rate limit actually matches because the outcome is the same.
Currently, actions (mark, log, counter) don't have any impact on whether the rule matches or not. This one does. Would this make more sense as a matcher instead? It would allow for negative matches:
rule meta.ratelimit 4pkt/s ACCEPT: if the packet is within the limit, accept itrule meta.ratelimit not 4pkt/s DROP: packets within the limit are ignored, while packets above are matched and dropped (notor another keyword that fits better).
Seems like this would be more in line with nftables. What do you think? I'm open to alternatives here.
There was a problem hiding this comment.
I'm not super familiar with nftables, but I really like the idea of "negative matches", I think it makes rate limiting very versatile and nice to use
Changing it to a matcher seems to make more sense
1b098e3 to
b9d8538
Compare
Fix #215
Currently a WIP POC
I've started getting into adding this features.So far, I've managed to add the
ratelimit [int]/[time_unit]keyword to the cli and put it's value into abf_map.However I'm not sure about implementing a "real" rate limiting as it seems to requireEMIT(and that look scary).Added (empty for now) elfstub to handle rate limitingThe idea of the implementation so far is pretty naive (only allow the first X requests to pass through), mostly because it was easier to implement and I hadn't strong feelings on which direction to go.I'll keep this as a draft for now since it's still in its early stages.