ebpf-lab

Example code from Learning eBPF by Liz Rice, https://github.com/lizrice/learning-ebpf
git clone https://git.in0rdr.ch/ebpf-lab.git
Log | Files | Refs | Pull requests |Archive | README

hello-xdp.bcc.c (2091B)


      1 #include <linux/bpf.h>
      2 // sections, printk, license, etc.
      3 #include <bpf/bpf_helpers.h>
      4 // bpf_ntohs
      5 #include <bpf/bpf_endian.h>
      6 // struct ethhdr
      7 #include <linux/if_ether.h>
      8 // struct iphdr
      9 #include <linux/ip.h>
     10 
     11 // https://github.com/lizrice/learning-ebpf/blob/main/chapter8
     12 
     13 // XDP type of BPF program
     14 SEC("xdp")
     15 
     16 int hello_xdp(struct xdp_md *ctx) {
     17   // helper macro to print out debug messages, wrapper for bpf_trace_printk()
     18   // /usr/include/bpf/bpf_helpers.h
     19   bpf_printk("received packet");
     20   // XDP_PASS      : let the packet pass
     21   // XDP_DROP      : you shall not pass
     22   // XDP_TC        : send packet back through the interface it came through
     23   // XDP_REDIRECT  : send packet to different interface
     24 
     25   // Parse xdp packet and detect request type/protocol
     26   int protocol = 0;
     27 
     28   // pointers to start and end of packet in memory
     29   void* data = (void*)(long)ctx->data;
     30   void* data_end = (void*)(long)ctx->data_end;
     31 
     32   // start of ethernet header
     33   // /usr/include/linux/if_ether.h
     34   // we could already lookup dest/source here
     35   struct ethhdr* eth = data;
     36 
     37   // check that packet is big enough for entire ethernet header
     38   if (data + sizeof(struct ethhdr) > data_end)
     39   // try to check this falsely and the verifiy will shout at you during bptool
     40   // prog load (offset is outside of the packet)
     41   //if (data + sizeof(struct ethhdr) <= data_end)
     42     return XDP_DROP;
     43 
     44   // check that it's an IP packet
     45   // bpf_ntohs is a bpf helper
     46   if (bpf_ntohs(eth->h_proto) != ETH_P_IP)
     47     return XDP_DROP;
     48 
     49   // start address of IP header
     50   struct iphdr* iph = data + sizeof(struct ethhdr);
     51 
     52   // check that entire header fits the packet
     53   if (data + sizeof(struct ethhdr) + sizeof(struct iphdr) > data_end)
     54     return XDP_DROP;
     55 
     56   // fetch protocol type from IP header
     57   // /usr/include/linux/ip.h
     58   protocol = iph->protocol;
     59 
     60   if (protocol == 1) {
     61     // ICMP
     62     bpf_printk("dropping ICMP packet");
     63     return XDP_DROP;
     64   }
     65   return XDP_PASS;
     66 }
     67 
     68 // cannot call GPL-restricted functions (e.g., bpf_trace_printk) from non-GPL
     69 // compatible program
     70 char LICENSE[] SEC("license") = "GPL";
     71