Back to home page

OSCL-LXR

 
 

    


0001 /* Copyright (c) 2016 Facebook
0002  *
0003  * This program is free software; you can redistribute it and/or
0004  * modify it under the terms of version 2 of the GNU General Public
0005  * License as published by the Free Software Foundation.
0006  */
0007 #define KBUILD_MODNAME "foo"
0008 #include <uapi/linux/if_ether.h>
0009 #include <uapi/linux/in6.h>
0010 #include <uapi/linux/ipv6.h>
0011 #include <uapi/linux/pkt_cls.h>
0012 #include <uapi/linux/bpf.h>
0013 #include <bpf/bpf_helpers.h>
0014 
0015 /* copy of 'struct ethhdr' without __packed */
0016 struct eth_hdr {
0017     unsigned char   h_dest[ETH_ALEN];
0018     unsigned char   h_source[ETH_ALEN];
0019     unsigned short  h_proto;
0020 };
0021 
0022 #define PIN_GLOBAL_NS       2
0023 struct bpf_elf_map {
0024     __u32 type;
0025     __u32 size_key;
0026     __u32 size_value;
0027     __u32 max_elem;
0028     __u32 flags;
0029     __u32 id;
0030     __u32 pinning;
0031 };
0032 
0033 struct bpf_elf_map SEC("maps") test_cgrp2_array_pin = {
0034     .type       = BPF_MAP_TYPE_CGROUP_ARRAY,
0035     .size_key   = sizeof(uint32_t),
0036     .size_value = sizeof(uint32_t),
0037     .pinning    = PIN_GLOBAL_NS,
0038     .max_elem   = 1,
0039 };
0040 
0041 SEC("filter")
0042 int handle_egress(struct __sk_buff *skb)
0043 {
0044     void *data = (void *)(long)skb->data;
0045     struct eth_hdr *eth = data;
0046     struct ipv6hdr *ip6h = data + sizeof(*eth);
0047     void *data_end = (void *)(long)skb->data_end;
0048     char dont_care_msg[] = "dont care %04x %d\n";
0049     char pass_msg[] = "pass\n";
0050     char reject_msg[] = "reject\n";
0051 
0052     /* single length check */
0053     if (data + sizeof(*eth) + sizeof(*ip6h) > data_end)
0054         return TC_ACT_OK;
0055 
0056     if (eth->h_proto != htons(ETH_P_IPV6) ||
0057         ip6h->nexthdr != IPPROTO_ICMPV6) {
0058         bpf_trace_printk(dont_care_msg, sizeof(dont_care_msg),
0059                  eth->h_proto, ip6h->nexthdr);
0060         return TC_ACT_OK;
0061     } else if (bpf_skb_under_cgroup(skb, &test_cgrp2_array_pin, 0) != 1) {
0062         bpf_trace_printk(pass_msg, sizeof(pass_msg));
0063         return TC_ACT_OK;
0064     } else {
0065         bpf_trace_printk(reject_msg, sizeof(reject_msg));
0066         return TC_ACT_SHOT;
0067     }
0068 }
0069 
0070 char _license[] SEC("license") = "GPL";