Advertisement
drpanwe

udp_flood_blocker.bpf.c

Jan 22nd, 2025
35
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.17 KB | Source Code | 0 0
  1. // udp_flood_blocker.bpf.c
  2. // Compile with: clang -O2 -target bpf -c udp_flood_blocker.bpf.c -o udp_flood_blocker.bpf.o
  3.  
  4. #define KBUILD_MODNAME "udp_flood_blocker"
  5. #include <linux/bpf.h>
  6. #include <bpf/bpf_helpers.h>
  7. #include <linux/if_ether.h>
  8. #include <linux/ip.h>
  9. #include <linux/udp.h>
  10.  
  11. /*
  12.   Map #1: udp_count
  13.   - Type: PERCPU_ARRAY
  14.   - Holds a single key (0) storing a 64-bit counter of UDP packets.
  15. */
  16. struct {
  17.     __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
  18.     __uint(max_entries, 1);
  19.     __type(key, __u32);
  20.     __type(value, __u64);
  21. } udp_count SEC(".maps");
  22.  
  23. /*
  24.   Map #2: block_state
  25.   - Type: ARRAY
  26.   - Holds a single key (0) storing a 32-bit "block" flag (0 = allow, 1 = drop).
  27. */
  28. struct {
  29.     __uint(type, BPF_MAP_TYPE_ARRAY);
  30.     __uint(max_entries, 1);
  31.     __type(key, __u32);
  32.     __type(value, __u32);
  33. } block_state SEC(".maps");
  34.  
  35. // XDP hook function: detect UDP and optionally block
  36. SEC("xdp")
  37. int detect_and_block_udp(struct xdp_md *ctx)
  38. {
  39.     void *data_end = (void *)(long)ctx->data_end;
  40.     void *data     = (void *)(long)ctx->data;
  41.  
  42.     // parse Ethernet header
  43.     struct ethhdr *eth = data;
  44.     if ((void *)(eth + 1) > data_end) {
  45.         return XDP_PASS; // packet too small/malformed
  46.     }
  47.  
  48.     // check if it's IPv4
  49.     if (bpf_ntohs(eth->h_proto) == ETH_P_IP) {
  50.         struct iphdr *iph = (struct iphdr *)(eth + 1);
  51.         if ((void *)(iph + 1) > data_end) {
  52.             return XDP_PASS;
  53.         }
  54.  
  55.         // check if it's UDP
  56.         if (iph->protocol == IPPROTO_UDP) {
  57.             // 1) Check block_state
  58.             __u32 zero_key = 0;
  59.             __u32 *block_val = bpf_map_lookup_elem(&block_state, &zero_key);
  60.             if (block_val && *block_val == 1) {
  61.                 // If we are in block mode, drop all UDP
  62.                 return XDP_DROP;
  63.             }
  64.  
  65.             // 2) Not blocked => increment the global UDP counter
  66.             __u64 *cnt_val = bpf_map_lookup_elem(&udp_count, &zero_key);
  67.             if (cnt_val) {
  68.                 __sync_fetch_and_add(cnt_val, 1);
  69.             }
  70.         }
  71.     }
  72.  
  73.     // pass non-UDP or non-IPv4 packets
  74.     return XDP_PASS;
  75. }
  76.  
  77. char _license[] SEC("license") = "GPL";
  78.  
Tags: eBPF
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement