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