From ce6e7d6c12c1f21c0180805d031bb8042b19658a Mon Sep 17 00:00:00 2001 From: Sai Krishna Kumar Reddy YADAMAKANTI Date: Tue, 29 Sep 2026 15:04:37 +0000 Subject: [PATCH] QUIC: added BPF packet data fallback Use bpf_skb_load_bytes() in the reuseport BPF helper when the required QUIC header bytes are not available through direct packet access. This keeps the direct access fast path while allowing the helper to parse the flags byte, DCID length byte, and DCID key from non linear skb data. A similar approach was implemented in [1]. [1] https://git.angie.software/web-server/angie/commit/4b527f5 --- .../quic/bpf/ngx_quic_reuseport_helper.c | 65 +++++---- src/event/quic/ngx_event_quic_bpf_code.c | 134 ++++++++++-------- 2 files changed, 112 insertions(+), 87 deletions(-) diff --git a/src/event/quic/bpf/ngx_quic_reuseport_helper.c b/src/event/quic/bpf/ngx_quic_reuseport_helper.c index 51b78f043..cf7a24c5a 100644 --- a/src/event/quic/bpf/ngx_quic_reuseport_helper.c +++ b/src/event/quic/bpf/ngx_quic_reuseport_helper.c @@ -44,15 +44,6 @@ char _license[] SEC("license") = LICENSE; #define NGX_QUIC_SERVER_CID_LEN 20 -#define advance_data(nbytes) \ - offset += nbytes; \ - if (start + offset > end) { \ - debugmsg("cannot read %ld bytes at offset %ld", nbytes, offset); \ - goto failed; \ - } \ - data = start + offset - 1; - - #define ngx_quic_parse_uint64(p) \ (((__u64)(p)[0] << 56) | \ ((__u64)(p)[1] << 48) | \ @@ -75,38 +66,54 @@ int ngx_quic_select_socket_by_dcid(struct sk_reuseport_md *ctx) { int rc; __u64 key; - size_t len, offset; - unsigned char *start, *end, *data, *dcid; + size_t offset; + unsigned char *start, *end, *dcid, byte, buf[NGX_QUIC_SERVER_CID_LEN]; - start = ctx->data; + start = (unsigned char *) ctx->data; end = (unsigned char *) ctx->data_end; - offset = 0; + offset = sizeof(struct udphdr); - advance_data(sizeof(struct udphdr)); /* data at UDP header */ - advance_data(1); /* data at QUIC flags */ + if (start + offset >= end) { - if (data[0] & NGX_QUIC_PKT_LONG) { + if (bpf_skb_load_bytes(ctx, offset, &byte, 1)) { + goto failed; + } - advance_data(4); /* data at QUIC version */ - advance_data(1); /* data at DCID len */ + } else { + byte = start[offset]; + } - len = data[0]; /* read DCID length */ + if (byte & NGX_QUIC_PKT_LONG) { - if (len < 8) { - /* it's useless to search for key in such short DCID */ - return SK_PASS; + offset += 5; + + if (start + offset >= end) { + + if (bpf_skb_load_bytes(ctx, offset, &byte, 1)) { + goto failed; + } + + } else { + byte = start[offset]; } - } else { - len = NGX_QUIC_SERVER_CID_LEN; + if (byte != NGX_QUIC_SERVER_CID_LEN) { + return SK_PASS; + } } - dcid = &data[1]; - advance_data(len); /* we expect the packet to have full DCID */ + offset++; - /* make verifier happy */ - if (dcid + sizeof(__u64) > end) { - goto failed; + if (start + offset + NGX_QUIC_SERVER_CID_LEN > end) { + + if (bpf_skb_load_bytes(ctx, offset, buf, NGX_QUIC_SERVER_CID_LEN)) { + goto failed; + } + + dcid = buf; + + } else { + dcid = start + offset; } key = ngx_quic_parse_uint64(dcid); diff --git a/src/event/quic/ngx_event_quic_bpf_code.c b/src/event/quic/ngx_event_quic_bpf_code.c index 625f40405..e32f1c68e 100644 --- a/src/event/quic/ngx_event_quic_bpf_code.c +++ b/src/event/quic/ngx_event_quic_bpf_code.c @@ -7,70 +7,88 @@ static ngx_bpf_reloc_t bpf_reloc_prog_ngx_quic_reuseport_helper[] = { - { "ngx_quic_sockmap", 59 }, + { "ngx_quic_sockmap", 77 }, }; static struct bpf_insn bpf_insn_prog_ngx_quic_reuseport_helper[] = { /* opcode dst src offset imm */ - { 0x79, BPF_REG_2, BPF_REG_1, (int16_t) 0, 0x0 }, - { 0x79, BPF_REG_3, BPF_REG_1, (int16_t) 8, 0x0 }, - { 0xbf, BPF_REG_6, BPF_REG_2, (int16_t) 0, 0x0 }, - { 0x7, BPF_REG_6, BPF_REG_0, (int16_t) 0, 0x8 }, - { 0x2d, BPF_REG_6, BPF_REG_3, (int16_t) 58, 0x0 }, - { 0xbf, BPF_REG_4, BPF_REG_2, (int16_t) 0, 0x0 }, - { 0x7, BPF_REG_4, BPF_REG_0, (int16_t) 0, 0x9 }, - { 0x2d, BPF_REG_4, BPF_REG_3, (int16_t) 55, 0x0 }, - { 0xb7, BPF_REG_4, BPF_REG_0, (int16_t) 0, 0x8 }, - { 0xb7, BPF_REG_5, BPF_REG_0, (int16_t) 0, 0x14 }, - { 0xb7, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x9 }, - { 0x71, BPF_REG_6, BPF_REG_6, (int16_t) 0, 0x0 }, - { 0x67, BPF_REG_6, BPF_REG_0, (int16_t) 0, 0x38 }, - { 0xc7, BPF_REG_6, BPF_REG_0, (int16_t) 0, 0x38 }, - { 0x65, BPF_REG_6, BPF_REG_0, (int16_t) 11, 0xffffffff }, - { 0xbf, BPF_REG_5, BPF_REG_2, (int16_t) 0, 0x0 }, - { 0x7, BPF_REG_5, BPF_REG_0, (int16_t) 0, 0xd }, - { 0x2d, BPF_REG_5, BPF_REG_3, (int16_t) 45, 0x0 }, - { 0xbf, BPF_REG_4, BPF_REG_2, (int16_t) 0, 0x0 }, - { 0x7, BPF_REG_4, BPF_REG_0, (int16_t) 0, 0xe }, - { 0x2d, BPF_REG_4, BPF_REG_3, (int16_t) 42, 0x0 }, - { 0xb7, BPF_REG_4, BPF_REG_0, (int16_t) 0, 0xd }, - { 0xb7, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0xe }, - { 0x71, BPF_REG_5, BPF_REG_5, (int16_t) 0, 0x0 }, - { 0xb7, BPF_REG_6, BPF_REG_0, (int16_t) 0, 0x8 }, - { 0x2d, BPF_REG_6, BPF_REG_5, (int16_t) 37, 0x0 }, - { 0xbf, BPF_REG_6, BPF_REG_2, (int16_t) 0, 0x0 }, - { 0xf, BPF_REG_6, BPF_REG_0, (int16_t) 0, 0x0 }, - { 0xf, BPF_REG_6, BPF_REG_5, (int16_t) 0, 0x0 }, - { 0x2d, BPF_REG_6, BPF_REG_3, (int16_t) 33, 0x0 }, - { 0xf, BPF_REG_2, BPF_REG_4, (int16_t) 0, 0x0 }, - { 0xbf, BPF_REG_4, BPF_REG_2, (int16_t) 0, 0x0 }, - { 0x7, BPF_REG_4, BPF_REG_0, (int16_t) 0, 0x9 }, - { 0x2d, BPF_REG_4, BPF_REG_3, (int16_t) 29, 0x0 }, - { 0x71, BPF_REG_4, BPF_REG_2, (int16_t) 1, 0x0 }, - { 0x67, BPF_REG_4, BPF_REG_0, (int16_t) 0, 0x38 }, - { 0x71, BPF_REG_3, BPF_REG_2, (int16_t) 2, 0x0 }, - { 0x67, BPF_REG_3, BPF_REG_0, (int16_t) 0, 0x30 }, - { 0x4f, BPF_REG_3, BPF_REG_4, (int16_t) 0, 0x0 }, - { 0x71, BPF_REG_4, BPF_REG_2, (int16_t) 3, 0x0 }, - { 0x67, BPF_REG_4, BPF_REG_0, (int16_t) 0, 0x28 }, - { 0x4f, BPF_REG_3, BPF_REG_4, (int16_t) 0, 0x0 }, - { 0x71, BPF_REG_4, BPF_REG_2, (int16_t) 4, 0x0 }, - { 0x67, BPF_REG_4, BPF_REG_0, (int16_t) 0, 0x20 }, - { 0x4f, BPF_REG_3, BPF_REG_4, (int16_t) 0, 0x0 }, - { 0x71, BPF_REG_4, BPF_REG_2, (int16_t) 5, 0x0 }, - { 0x67, BPF_REG_4, BPF_REG_0, (int16_t) 0, 0x18 }, - { 0x4f, BPF_REG_3, BPF_REG_4, (int16_t) 0, 0x0 }, - { 0x71, BPF_REG_4, BPF_REG_2, (int16_t) 6, 0x0 }, - { 0x67, BPF_REG_4, BPF_REG_0, (int16_t) 0, 0x10 }, - { 0x4f, BPF_REG_3, BPF_REG_4, (int16_t) 0, 0x0 }, - { 0x71, BPF_REG_4, BPF_REG_2, (int16_t) 7, 0x0 }, - { 0x67, BPF_REG_4, BPF_REG_0, (int16_t) 0, 0x8 }, - { 0x4f, BPF_REG_3, BPF_REG_4, (int16_t) 0, 0x0 }, - { 0x71, BPF_REG_2, BPF_REG_2, (int16_t) 8, 0x0 }, - { 0x4f, BPF_REG_3, BPF_REG_2, (int16_t) 0, 0x0 }, - { 0x7b, BPF_REG_10, BPF_REG_3, (int16_t) 65528, 0x0 }, + { 0xbf, BPF_REG_6, BPF_REG_1, (int16_t) 0, 0x0 }, + { 0x79, BPF_REG_8, BPF_REG_6, (int16_t) 8, 0x0 }, + { 0x79, BPF_REG_7, BPF_REG_6, (int16_t) 0, 0x0 }, + { 0xbf, BPF_REG_1, BPF_REG_7, (int16_t) 0, 0x0 }, + { 0x7, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0x8 }, + { 0x2d, BPF_REG_8, BPF_REG_1, (int16_t) 10, 0x0 }, + { 0xbf, BPF_REG_3, BPF_REG_10, (int16_t) 0, 0x0 }, + { 0x7, BPF_REG_3, BPF_REG_0, (int16_t) 0, 0xfffffff7 }, + { 0xbf, BPF_REG_1, BPF_REG_6, (int16_t) 0, 0x0 }, + { 0xb7, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x8 }, + { 0xb7, BPF_REG_4, BPF_REG_0, (int16_t) 0, 0x1 }, + { 0x85, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x1a }, + { 0x15, BPF_REG_0, BPF_REG_0, (int16_t) 1, 0x0 }, + { 0x5, BPF_REG_0, BPF_REG_0, (int16_t) 67, 0x0 }, + { 0x71, BPF_REG_1, BPF_REG_10, (int16_t) 65527, 0x0 }, + { 0x5, BPF_REG_0, BPF_REG_0, (int16_t) 2, 0x0 }, + { 0x71, BPF_REG_1, BPF_REG_1, (int16_t) 0, 0x0 }, + { 0x73, BPF_REG_10, BPF_REG_1, (int16_t) 65527, 0x0 }, + { 0xb7, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x9 }, + { 0x67, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0x38 }, + { 0xc7, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0x38 }, + { 0x65, BPF_REG_1, BPF_REG_0, (int16_t) 18, 0xffffffff }, + { 0xbf, BPF_REG_1, BPF_REG_7, (int16_t) 0, 0x0 }, + { 0x7, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0xd }, + { 0x2d, BPF_REG_8, BPF_REG_1, (int16_t) 11, 0x0 }, + { 0xbf, BPF_REG_3, BPF_REG_10, (int16_t) 0, 0x0 }, + { 0x7, BPF_REG_3, BPF_REG_0, (int16_t) 0, 0xfffffff7 }, + { 0xbf, BPF_REG_1, BPF_REG_6, (int16_t) 0, 0x0 }, + { 0xb7, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0xd }, + { 0xb7, BPF_REG_4, BPF_REG_0, (int16_t) 0, 0x1 }, + { 0x85, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x1a }, + { 0x55, BPF_REG_0, BPF_REG_0, (int16_t) 49, 0x0 }, + { 0xb7, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0xe }, + { 0x71, BPF_REG_1, BPF_REG_10, (int16_t) 65527, 0x0 }, + { 0x15, BPF_REG_1, BPF_REG_0, (int16_t) 5, 0x14 }, + { 0x5, BPF_REG_0, BPF_REG_0, (int16_t) 45, 0x0 }, + { 0xb7, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0xe }, + { 0x71, BPF_REG_1, BPF_REG_1, (int16_t) 0, 0x0 }, + { 0x73, BPF_REG_10, BPF_REG_1, (int16_t) 65527, 0x0 }, + { 0x55, BPF_REG_1, BPF_REG_0, (int16_t) 41, 0x14 }, + { 0xf, BPF_REG_7, BPF_REG_2, (int16_t) 0, 0x0 }, + { 0xbf, BPF_REG_1, BPF_REG_7, (int16_t) 0, 0x0 }, + { 0x7, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0x14 }, + { 0x3d, BPF_REG_8, BPF_REG_1, (int16_t) 7, 0x0 }, + { 0xbf, BPF_REG_7, BPF_REG_10, (int16_t) 0, 0x0 }, + { 0x7, BPF_REG_7, BPF_REG_0, (int16_t) 0, 0xffffffe3 }, + { 0xbf, BPF_REG_1, BPF_REG_6, (int16_t) 0, 0x0 }, + { 0xbf, BPF_REG_3, BPF_REG_7, (int16_t) 0, 0x0 }, + { 0xb7, BPF_REG_4, BPF_REG_0, (int16_t) 0, 0x14 }, + { 0x85, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x1a }, + { 0x55, BPF_REG_0, BPF_REG_0, (int16_t) 30, 0x0 }, + { 0x71, BPF_REG_2, BPF_REG_7, (int16_t) 0, 0x0 }, + { 0x67, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x38 }, + { 0x71, BPF_REG_1, BPF_REG_7, (int16_t) 1, 0x0 }, + { 0x67, BPF_REG_1, BPF_REG_0, (int16_t) 0, 0x30 }, + { 0x4f, BPF_REG_1, BPF_REG_2, (int16_t) 0, 0x0 }, + { 0x71, BPF_REG_2, BPF_REG_7, (int16_t) 2, 0x0 }, + { 0x67, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x28 }, + { 0x4f, BPF_REG_1, BPF_REG_2, (int16_t) 0, 0x0 }, + { 0x71, BPF_REG_2, BPF_REG_7, (int16_t) 3, 0x0 }, + { 0x67, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x20 }, + { 0x4f, BPF_REG_1, BPF_REG_2, (int16_t) 0, 0x0 }, + { 0x71, BPF_REG_2, BPF_REG_7, (int16_t) 4, 0x0 }, + { 0x67, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x18 }, + { 0x4f, BPF_REG_1, BPF_REG_2, (int16_t) 0, 0x0 }, + { 0x71, BPF_REG_2, BPF_REG_7, (int16_t) 5, 0x0 }, + { 0x67, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x10 }, + { 0x4f, BPF_REG_1, BPF_REG_2, (int16_t) 0, 0x0 }, + { 0x71, BPF_REG_2, BPF_REG_7, (int16_t) 6, 0x0 }, + { 0x67, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x8 }, + { 0x4f, BPF_REG_1, BPF_REG_2, (int16_t) 0, 0x0 }, + { 0x71, BPF_REG_2, BPF_REG_7, (int16_t) 7, 0x0 }, + { 0x4f, BPF_REG_1, BPF_REG_2, (int16_t) 0, 0x0 }, + { 0x7b, BPF_REG_10, BPF_REG_1, (int16_t) 65528, 0x0 }, { 0xbf, BPF_REG_3, BPF_REG_10, (int16_t) 0, 0x0 }, { 0x7, BPF_REG_3, BPF_REG_0, (int16_t) 0, 0xfffffff8 }, + { 0xbf, BPF_REG_1, BPF_REG_6, (int16_t) 0, 0x0 }, { 0x18, BPF_REG_2, BPF_REG_0, (int16_t) 0, 0x0 }, { 0x0, BPF_REG_0, BPF_REG_0, (int16_t) 0, 0x0 }, { 0xb7, BPF_REG_4, BPF_REG_0, (int16_t) 0, 0x0 }, -- 2.47.3