19cc873e8SAlexei Starovoitov // SPDX-License-Identifier: GPL-2.0 29cc873e8SAlexei Starovoitov #define BPF_NO_PRESERVE_ACCESS_INDEX 39cc873e8SAlexei Starovoitov #include <vmlinux.h> 49cc873e8SAlexei Starovoitov #include <bpf/bpf_core_read.h> 59cc873e8SAlexei Starovoitov #include <bpf/bpf_helpers.h> 69cc873e8SAlexei Starovoitov 79cc873e8SAlexei Starovoitov #define INLINE __always_inline 89cc873e8SAlexei Starovoitov 99cc873e8SAlexei Starovoitov #define skb_shorter(skb, len) ((void *)(long)(skb)->data + (len) > (void *)(long)skb->data_end) 109cc873e8SAlexei Starovoitov 119cc873e8SAlexei Starovoitov #define ETH_IPV4_TCP_SIZE (14 + sizeof(struct iphdr) + sizeof(struct tcphdr)) 129cc873e8SAlexei Starovoitov get_iphdr(struct __sk_buff * skb)139cc873e8SAlexei Starovoitovstatic INLINE struct iphdr *get_iphdr(struct __sk_buff *skb) 149cc873e8SAlexei Starovoitov { 159cc873e8SAlexei Starovoitov struct iphdr *ip = NULL; 169cc873e8SAlexei Starovoitov struct ethhdr *eth; 179cc873e8SAlexei Starovoitov 189cc873e8SAlexei Starovoitov if (skb_shorter(skb, ETH_IPV4_TCP_SIZE)) 199cc873e8SAlexei Starovoitov goto out; 209cc873e8SAlexei Starovoitov 219cc873e8SAlexei Starovoitov eth = (void *)(long)skb->data; 229cc873e8SAlexei Starovoitov ip = (void *)(eth + 1); 239cc873e8SAlexei Starovoitov 249cc873e8SAlexei Starovoitov out: 259cc873e8SAlexei Starovoitov return ip; 269cc873e8SAlexei Starovoitov } 279cc873e8SAlexei Starovoitov 28*c22bdd28SAndrii Nakryiko SEC("tc") main_prog(struct __sk_buff * skb)299cc873e8SAlexei Starovoitovint main_prog(struct __sk_buff *skb) 309cc873e8SAlexei Starovoitov { 319cc873e8SAlexei Starovoitov struct iphdr *ip = NULL; 329cc873e8SAlexei Starovoitov struct tcphdr *tcp; 339cc873e8SAlexei Starovoitov __u8 proto = 0; 349cc873e8SAlexei Starovoitov 359cc873e8SAlexei Starovoitov if (!(ip = get_iphdr(skb))) 369cc873e8SAlexei Starovoitov goto out; 379cc873e8SAlexei Starovoitov 389cc873e8SAlexei Starovoitov proto = ip->protocol; 399cc873e8SAlexei Starovoitov 409cc873e8SAlexei Starovoitov if (proto != IPPROTO_TCP) 419cc873e8SAlexei Starovoitov goto out; 429cc873e8SAlexei Starovoitov 439cc873e8SAlexei Starovoitov tcp = (void*)(ip + 1); 449cc873e8SAlexei Starovoitov if (tcp->dest != 0) 459cc873e8SAlexei Starovoitov goto out; 469cc873e8SAlexei Starovoitov if (!tcp) 479cc873e8SAlexei Starovoitov goto out; 489cc873e8SAlexei Starovoitov 499cc873e8SAlexei Starovoitov return tcp->urg_ptr; 509cc873e8SAlexei Starovoitov out: 519cc873e8SAlexei Starovoitov return -1; 529cc873e8SAlexei Starovoitov } 539cc873e8SAlexei Starovoitov char _license[] SEC("license") = "GPL"; 54