diff src/event/quic/bpf/bpfgen.sh @ 8676:7df607cb2d11 quic

QUIC: ngx_quic_bpf module. The quic kernel bpf helper inspects packet payload for DCID, extracts key and routes the packet into socket matching the key. Due to reuseport feature, each worker owns a personal socket, which is identified by the same key, used to create DCID. BPF objects are locked in RAM and are subject to RLIMIT_MEMLOCK. The "ulimit -l" command may be used to setup proper limits, if maps cannot be created with EPERM or updated with ETOOLONG.
author Vladimir Homutov <vl@nginx.com>
date Fri, 25 Dec 2020 15:01:15 +0300
parents
children
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/src/event/quic/bpf/bpfgen.sh
@@ -0,0 +1,113 @@
+#!/bin/bash
+
+export LANG=C
+
+set -e
+
+if [ $# -lt 1 ]; then
+    echo "Usage: PROGNAME=foo LICENSE=bar $0 <bpf object file>"
+    exit 1
+fi
+
+
+self=$0
+filename=$1
+funcname=$PROGNAME
+
+generate_head()
+{
+    cat << END
+/* AUTO-GENERATED, DO NOT EDIT. */
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "ngx_bpf.h"
+
+
+END
+}
+
+generate_tail()
+{
+    cat << END
+
+ngx_bpf_program_t $PROGNAME = {
+    .relocs = bpf_reloc_prog_$funcname,
+    .nrelocs = sizeof(bpf_reloc_prog_$funcname)
+               / sizeof(bpf_reloc_prog_$funcname[0]),
+    .ins = bpf_insn_prog_$funcname,
+    .nins = sizeof(bpf_insn_prog_$funcname)
+            / sizeof(bpf_insn_prog_$funcname[0]),
+    .license = "$LICENSE",
+    .type = BPF_PROG_TYPE_SK_REUSEPORT,
+};
+
+END
+}
+
+process_relocations()
+{
+    echo "static ngx_bpf_reloc_t bpf_reloc_prog_$funcname[] = {"
+
+    objdump -r $filename | awk '{
+
+    if (enabled && $NF > 0) {
+        off = strtonum(sprintf("0x%s", $1));
+        name = $3;
+
+        printf("    { \"%s\", %d },\n", name, off/8);
+    }
+
+    if ($1 == "OFFSET") {
+        enabled=1;
+    }
+}'
+    echo "};"
+    echo
+}
+
+process_section()
+{
+    echo "static struct bpf_insn bpf_insn_prog_$funcname[] = {"
+    echo "    /* opcode dst          src         offset imm */"
+
+    section_info=$(objdump -h $filename --section=$funcname | grep "1 $funcname")
+
+    # dd doesn't know hex
+    length=$(printf "%d" 0x$(echo $section_info | cut -d ' ' -f3))
+    offset=$(printf "%d" 0x$(echo $section_info | cut -d ' ' -f6))
+
+    for ins in $(dd if="$filename" bs=1 count=$length skip=$offset status=none | xxd -p -c 8)
+    do
+        opcode=0x${ins:0:2}
+        srcdst=0x${ins:2:2}
+
+        # bytes are dumped in LE order
+        offset=0x${ins:6:2}${ins:4:2}                        # short
+        immedi=0x${ins:14:2}${ins:12:2}${ins:10:2}${ins:8:2} # int
+
+        dst="$(($srcdst & 0xF))"
+        src="$(($srcdst & 0xF0))"
+        src="$(($src >> 4))"
+
+        opcode=$(printf "0x%x" $opcode)
+        dst=$(printf "BPF_REG_%d" $dst)
+        src=$(printf "BPF_REG_%d" $src)
+        offset=$(printf "%d" $offset)
+        immedi=$(printf "0x%x" $immedi)
+
+        printf "    { %4s, %11s, %11s, (int16_t) %6s, %10s },\n" $opcode $dst $src $offset $immedi
+    done
+
+cat << END
+};
+
+END
+}
+
+generate_head
+process_relocations
+process_section
+generate_tail
+