165d472fbSAlexei Starovoitov /* Copyright (c) 2016 Facebook 265d472fbSAlexei Starovoitov * 365d472fbSAlexei Starovoitov * This program is free software; you can redistribute it and/or 465d472fbSAlexei Starovoitov * modify it under the terms of version 2 of the GNU General Public 565d472fbSAlexei Starovoitov * License as published by the Free Software Foundation. 665d472fbSAlexei Starovoitov */ 796a8eb1eSDaniel Borkmann #define KBUILD_MODNAME "foo" 865d472fbSAlexei Starovoitov #include <linux/ip.h> 965d472fbSAlexei Starovoitov #include <linux/ipv6.h> 1065d472fbSAlexei Starovoitov #include <linux/in.h> 1165d472fbSAlexei Starovoitov #include <linux/tcp.h> 1265d472fbSAlexei Starovoitov #include <linux/udp.h> 1365d472fbSAlexei Starovoitov #include <uapi/linux/bpf.h> 1465d472fbSAlexei Starovoitov #include <net/ip.h> 15*7cf245a3SToke Høiland-Jørgensen #include <bpf/bpf_helpers.h> 1665d472fbSAlexei Starovoitov 1765d472fbSAlexei Starovoitov #define DEFAULT_PKTGEN_UDP_PORT 9 1865d472fbSAlexei Starovoitov 1965d472fbSAlexei Starovoitov /* copy of 'struct ethhdr' without __packed */ 2065d472fbSAlexei Starovoitov struct eth_hdr { 2165d472fbSAlexei Starovoitov unsigned char h_dest[ETH_ALEN]; 2265d472fbSAlexei Starovoitov unsigned char h_source[ETH_ALEN]; 2365d472fbSAlexei Starovoitov unsigned short h_proto; 2465d472fbSAlexei Starovoitov }; 2565d472fbSAlexei Starovoitov 2665d472fbSAlexei Starovoitov SEC("simple") handle_ingress(struct __sk_buff * skb)2765d472fbSAlexei Starovoitovint handle_ingress(struct __sk_buff *skb) 2865d472fbSAlexei Starovoitov { 2965d472fbSAlexei Starovoitov void *data = (void *)(long)skb->data; 3065d472fbSAlexei Starovoitov struct eth_hdr *eth = data; 3165d472fbSAlexei Starovoitov struct iphdr *iph = data + sizeof(*eth); 3265d472fbSAlexei Starovoitov struct udphdr *udp = data + sizeof(*eth) + sizeof(*iph); 3365d472fbSAlexei Starovoitov void *data_end = (void *)(long)skb->data_end; 3465d472fbSAlexei Starovoitov 3565d472fbSAlexei Starovoitov /* single length check */ 3665d472fbSAlexei Starovoitov if (data + sizeof(*eth) + sizeof(*iph) + sizeof(*udp) > data_end) 3765d472fbSAlexei Starovoitov return 0; 3865d472fbSAlexei Starovoitov 3965d472fbSAlexei Starovoitov if (eth->h_proto != htons(ETH_P_IP)) 4065d472fbSAlexei Starovoitov return 0; 4165d472fbSAlexei Starovoitov if (iph->protocol != IPPROTO_UDP || iph->ihl != 5) 4265d472fbSAlexei Starovoitov return 0; 4365d472fbSAlexei Starovoitov if (ip_is_fragment(iph)) 4465d472fbSAlexei Starovoitov return 0; 4565d472fbSAlexei Starovoitov if (udp->dest == htons(DEFAULT_PKTGEN_UDP_PORT)) 4665d472fbSAlexei Starovoitov return TC_ACT_SHOT; 4765d472fbSAlexei Starovoitov return 0; 4865d472fbSAlexei Starovoitov } 4965d472fbSAlexei Starovoitov char _license[] SEC("license") = "GPL"; 50