Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xdp-sni xdp_sni.bpf.c program is too large #6

Open
vincentmli opened this issue Oct 6, 2024 · 3 comments
Open

xdp-sni xdp_sni.bpf.c program is too large #6

vincentmli opened this issue Oct 6, 2024 · 3 comments

Comments

@vincentmli
Copy link
Owner

after add follow bpf ringbuff to xdp_sni.bpf.c, it compiles ok with clang 18.0.0 on ubuntu 22.04 , but failed to load

diff --git a/xdp-sni/xdp_sni.bpf.c b/xdp-sni/xdp_sni.bpf.c
index 51f7487..962da9d 100644
--- a/xdp-sni/xdp_sni.bpf.c
+++ b/xdp-sni/xdp_sni.bpf.c
@@ -28,7 +28,7 @@
 #include <linux/in.h>
 
 #define SERVER_NAME_EXTENSION 0
-#define MAX_DOMAIN_SIZE 127
+#define MAX_DOMAIN_SIZE 63 
 
 struct domain_name {
     struct bpf_lpm_trie_key lpm_key;
@@ -56,6 +56,31 @@ struct sni_extension {
     __u16 len;
 } __attribute__((packed));
 
+struct {
+        __uint(type, BPF_MAP_TYPE_RINGBUF);
+        __uint(max_entries, 1 << 12); // 4KB buffer
+        __uint(pinning, LIBBPF_PIN_BY_NAME);
+} sni_ringbuf SEC(".maps");
+
+struct sni_event {
+        __u8 len;
+        __u32 src_ip; // Store IPv4 address
+        char sni[MAX_DOMAIN_SIZE + 1];
+};
+
+static __always_inline void *custom_memcpy(void *dest, const void *src,
+                                           __u8 len)
+{
+        __u8 i;
+
+        // Perform the copy byte-by-byte to satisfy the BPF verifier
+        for (i = 0; i < len; i++) {
+                *((__u8 *)dest + i) = *((__u8 *)src + i);
+        }
+
+        return dest;
+}
+
 static __always_inline void reverse_string(char *str, __u8 len) {
     for (int i = 0; i < (len - 1) / 2; i++) {
         char temp = str[i];
@@ -199,6 +224,23 @@ int xdp_tls_sni(struct xdp_md *ctx) {
 
             bpf_printk("TLS SNI: %s", dn.server_name);
 
+           // Allocate a buffer from the ring buffer
+            struct sni_event *event = bpf_ringbuf_reserve(
+                    &sni_ringbuf, sizeof(*event), 0);
+
+            if (!event) {
+       //          bpf_printk("no space for event log\n");
+                    return XDP_PASS; // Drop if no space
+           }
+
+            // Set event fields
+            event->len = server_name_len;
+            event->src_ip = ip->saddr; // Extract source IP address
+            custom_memcpy(event->sni, dn.server_name, server_name_len);
+           event->sni[server_name_len] = '\0';
+           // Submit the event
+            bpf_ringbuf_submit(event, 0);
+
            reverse_string(dn.server_name, server_name_len);
 
             if (bpf_map_lookup_elem(&sni_denylist, &dn)) {


load error

; if (!event) {
164: (15) if r0 == 0x0 goto pc+54     ; R0=ringbuf_mem(ref_obj_id=3918,sz=72) refs=3918
; 
165: (bf) r1 = r0                     ; R0=ringbuf_mem(ref_obj_id=3918,sz=72) R1_w=ringbuf_mem(ref_obj_id=3918,sz=72) refs=3918
; event->len = server_name_len;
166: (73) *(u8 *)(r1 +0) = r8         ; R1_w=ringbuf_mem(ref_obj_id=3918,sz=72) R8=48 refs=3918
; event->src_ip = ip->saddr; // Extract source IP address
167: (61) r2 = *(u32 *)(r7 +26)       ; R2_w=scalar(smin=0,smax=umax=0xffffffff,var_off=(0x0; 0xffffffff)) R7=pkt(r=34) refs=3918
; event->src_ip = ip->saddr; // Extract source IP address
168: (63) *(u32 *)(r1 +4) = r2        ; R1_w=ringbuf_mem(ref_obj_id=3918,sz=72) R2_w=scalar(smin=0,smax=umax=0xffffffff,var_off=(0x0; 0xffffffff)) refs=3918
; event->len = server_name_len;
169: (bf) r7 = r8                     ; R7_w=48 R8=48 refs=3918
170: (57) r7 &= 255                   ; R7_w=48 refs=3918
; for (i = 0; i < len; i++) {
171: (15) if r7 == 0x0 goto pc+11     ; R7_w=48 refs=3918
172: (bf) r2 = r0                     ; R0=ringbuf_mem(ref_obj_id=3918,sz=72) R2_w=ringbuf_mem(ref_obj_id=3918,sz=72) refs=3918
173: (07) r2 += 8                     ; R2_w=ringbuf_mem(ref_obj_id=3918,off=8,sz=72) refs=3918
174: (b7) r3 = 0                      ; R3=0 refs=3918
; *((__u8 *)dest + i) = *((__u8 *)src + i);
175: (bf) r4 = r2                     ; R2=ringbuf_mem(ref_obj_id=3918,off=8,sz=72) R4_w=ringbuf_mem(ref_obj_id=3918,off=8,sz=72) refs=3918
176: (0f) r4 += r3                    ; R3=0 R4_w=ringbuf_mem(ref_obj_id=3918,off=8,sz=72) refs=3918
; *((__u8 *)dest + i) = *((__u8 *)src + i);
177: (bf) r5 = r6                     ; R5_w=fp-68 R6=fp-68 refs=3918
178: (0f) r5 += r3                    ; R3=0 R5_w=fp-68 refs=3918
; *((__u8 *)dest + i) = *((__u8 *)src + i);
179: (71) r5 = *(u8 *)(r5 +0)         ; R5_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=255,var_off=(0x0; 0xff)) fp-72=mmmm384 refs=3918
; *((__u8 *)dest + i) = *((__u8 *)src + i);
180: (73) *(u8 *)(r4 +0) = r5         ; R4_w=ringbuf_mem(ref_obj_id=3918,off=8,sz=72) R5_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=255,var_off=(0x0; 0xff)) refs=3918
; for (i = 0; i < len; i++) {
181: (07) r3 += 1                     ; R3_w=1 refs=3918
; for (i = 0; i < len; i++) {
182: (2d) if r7 > r3 goto pc-8        ; R3_w=1 R7=48 refs=3918
; *((__u8 *)dest + i) = *((__u8 *)src + i);
175: (bf) r4 = r2                     ; R2=ringbuf_mem(ref_obj_id=3918,off=8,sz=72) R4_w=ringbuf_mem(ref_obj_id=3918,off=8,sz=72) refs=3918
176: (0f) r4 += r3                    ; R3_w=1 R4_w=ringbuf_mem(ref_obj_id=3918,off=9,sz=72) refs=3918
; *((__u8 *)dest + i) = *((__u8 *)src + i);
177: (bf) r5 = r6                     ; R5_w=fp-68 R6=fp-68 refs=3918
178: (0f) r5 += r3                    ; R3_w=1 R5_w=fp-67 refs=3918
; *((__u8 *)dest + i) = *((__u8 *)src + i);
179: (71) r5 = *(u8 *)(r5 +0)         ; R5_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=255,var_off=(0x0; 0xff)) fp-72=mmmm384 refs=3918
; *((__u8 *)dest + i) = *((__u8 *)src + i);
180: (73) *(u8 *)(r4 +0) = r5
BPF program is too large. Processed 1000001 insn
processed 1000001 insns (limit 1000000) max_states_per_insn 10 total_states 21646 peak_states 382 mark_read 14
-- END PROG LOAD LOG --
  libbpf: prog 'xdp_tls_sni': failed to load: -7
  libbpf: failed to load object 'xdp-sni/xdp_sni.bpf.o'
 libxdp: Got 'argument list too long' error while loading component program.
 libxdp: Falling back to loading single prog without dispatcher
 libxdp: Checking for kernel frags support
 libxdp: Loading XDP program 'xdp-dispatcher.o' from embedded object file
 ......
 libxdp: Loaded XDP program xdp_pass, got fd 6
 libxdp: Duplicated fd 6 to 7 for prog xdp_pass
 libxdp: Kernel supports XDP programs with frags
 libxdp: XDP program xdp_tls_sni is already loaded with fd -2
 libxdp: Error on fcntl: Bad file descriptorCouldn't attach XDP program on iface 'lo': Bad file descriptor(-9)


@vincentmli
Copy link
Owner Author

while trying to build new llvm-project from upstream on ubuntu 22.04,

     $ git clone https://github.com/llvm/llvm-project.git
     $ mkdir -p llvm-project/llvm/build
     $ cd llvm-project/llvm/build
     $ cmake .. -G "Ninja" -DLLVM_TARGETS_TO_BUILD="BPF;X86" \
                -DLLVM_ENABLE_PROJECTS="clang"    \
                -DCMAKE_BUILD_TYPE=Release        \
                -DLLVM_BUILD_RUNTIME=OFF


got error similar to https://askubuntu.com/questions/1472032/cannot-build-darling
fix the error with apt install libstdc++-12-dev

@vincentmli
Copy link
Owner Author

vincentmli commented Oct 6, 2024

ninja -j8 to build llvm 19.1 version result in error below

cc: error: unrecognized command-line option ‘-Wcovered-switch-default’; did you mean ‘-Wno-switch-default’?
cc: error: unrecognized command-line option ‘-Wstring-conversion’; did you mean ‘-Wsign-conversion’?

llvm-project 18.1.8 has no build problem, but use clang 18.1.8 to compile xdp_sni.bpf.c did not resolve the program is too large issue.

@vincentmli
Copy link
Owner Author

by now remove the reverse_string function to avoid program is too large issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant