]> git.kaiwu.me - nginx.git/commitdiff
QUIC: added BPF packet data fallback
authorSai Krishna Kumar Reddy YADAMAKANTI <s.yadamakanti@f5.com>
Tue, 29 Sep 2026 15:04:37 +0000 (15:04 +0000)
committerRoman Arutyunyan <arutyunyan.roman@gmail.com>
Tue, 29 Sep 2026 17:46:41 +0000 (21:46 +0400)
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

src/event/quic/bpf/ngx_quic_reuseport_helper.c
src/event/quic/ngx_event_quic_bpf_code.c

index 51b78f043600d1c3315f4bf52ca3f9343b033aab..cf7a24c5a6bcf4fdfd4c6873fe59c81c0702f355 100644 (file)
@@ -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);
index 625f404056d9bd02e5757305a09f39b637b2b659..e32f1c68eadaccac58e3b13ea085ae4e0d1acb39 100644 (file)
@@ -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 },