0001
0002
0003 #include <linux/stddef.h>
0004 #include <linux/if_ether.h>
0005 #include <linux/ipv6.h>
0006 #include <linux/bpf.h>
0007 #include <linux/tcp.h>
0008 #include <bpf/bpf_helpers.h>
0009 #include <bpf/bpf_endian.h>
0010 #include <bpf/bpf_tracing.h>
0011
0012 struct sk_buff {
0013 unsigned int len;
0014 };
0015
0016 __u64 test_result = 0;
0017 SEC("fexit/test_pkt_access")
0018 int BPF_PROG(test_main, struct sk_buff *skb, int ret)
0019 {
0020 int len;
0021
0022 __builtin_preserve_access_index(({
0023 len = skb->len;
0024 }));
0025 if (len != 74 || ret != 0)
0026 return 0;
0027 test_result = 1;
0028 return 0;
0029 }
0030
0031 __u64 test_result_subprog1 = 0;
0032 SEC("fexit/test_pkt_access_subprog1")
0033 int BPF_PROG(test_subprog1, struct sk_buff *skb, int ret)
0034 {
0035 int len;
0036
0037 __builtin_preserve_access_index(({
0038 len = skb->len;
0039 }));
0040 if (len != 74 || ret != 148)
0041 return 0;
0042 test_result_subprog1 = 1;
0043 return 0;
0044 }
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060 struct args_subprog2 {
0061 __u64 args[5];
0062 __u64 ret;
0063 };
0064 __u64 test_result_subprog2 = 0;
0065 SEC("fexit/test_pkt_access_subprog2")
0066 int test_subprog2(struct args_subprog2 *ctx)
0067 {
0068 struct sk_buff *skb = (void *)ctx->args[0];
0069 __u64 ret;
0070 int len;
0071
0072 bpf_probe_read_kernel(&len, sizeof(len),
0073 __builtin_preserve_access_index(&skb->len));
0074
0075 ret = ctx->ret;
0076
0077
0078
0079
0080
0081 ret = (__u32) ret;
0082 if (len != 74 || ret != 148)
0083 return 0;
0084 test_result_subprog2 = 1;
0085 return 0;
0086 }
0087
0088 __u64 test_result_subprog3 = 0;
0089 SEC("fexit/test_pkt_access_subprog3")
0090 int BPF_PROG(test_subprog3, int val, struct sk_buff *skb, int ret)
0091 {
0092 int len;
0093
0094 __builtin_preserve_access_index(({
0095 len = skb->len;
0096 }));
0097 if (len != 74 || ret != 74 * val || val != 3)
0098 return 0;
0099 test_result_subprog3 = 1;
0100 return 0;
0101 }
0102
0103 __u64 test_get_skb_len = 0;
0104 SEC("freplace/get_skb_len")
0105 int new_get_skb_len(struct __sk_buff *skb)
0106 {
0107 int len = skb->len;
0108
0109 if (len != 74)
0110 return 0;
0111 test_get_skb_len = 1;
0112 return 74;
0113 }
0114
0115 __u64 test_get_skb_ifindex = 0;
0116 SEC("freplace/get_skb_ifindex")
0117 int new_get_skb_ifindex(int val, struct __sk_buff *skb, int var)
0118 {
0119 void *data_end = (void *)(long)skb->data_end;
0120 void *data = (void *)(long)skb->data;
0121 struct ipv6hdr ip6, *ip6p;
0122 int ifindex = skb->ifindex;
0123 __u32 eth_proto;
0124 __u32 nh_off;
0125
0126
0127 if (data + 14 + sizeof(ip6) > data_end)
0128 return 0;
0129 ip6p = data + 14;
0130
0131 if (ip6p->nexthdr != 6 || ip6p->payload_len != __bpf_constant_htons(123))
0132 return 0;
0133
0134
0135 if (bpf_skb_load_bytes(skb, 14, &ip6, sizeof(ip6)) < 0)
0136 return 0;
0137 ip6p = &ip6;
0138 if (ip6p->nexthdr != 6 || ip6p->payload_len != __bpf_constant_htons(123))
0139 return 0;
0140
0141 if (ifindex != 1 || val != 3 || var != 1)
0142 return 0;
0143 test_get_skb_ifindex = 1;
0144 return 3;
0145 }
0146
0147 volatile __u64 test_get_constant = 0;
0148 SEC("freplace/get_constant")
0149 int new_get_constant(long val)
0150 {
0151 if (val != 123)
0152 return 0;
0153 test_get_constant = 1;
0154 return test_get_constant;
0155 }
0156
0157 __u64 test_pkt_write_access_subprog = 0;
0158 SEC("freplace/test_pkt_write_access_subprog")
0159 int new_test_pkt_write_access_subprog(struct __sk_buff *skb, __u32 off)
0160 {
0161
0162 void *data = (void *)(long)skb->data;
0163 void *data_end = (void *)(long)skb->data_end;
0164 struct tcphdr *tcp;
0165
0166 if (off > sizeof(struct ethhdr) + sizeof(struct ipv6hdr))
0167 return -1;
0168
0169 tcp = data + off;
0170 if (tcp + 1 > data_end)
0171 return -1;
0172
0173
0174 tcp->check++;
0175 tcp->syn = 0;
0176
0177 test_pkt_write_access_subprog = 1;
0178 return 0;
0179 }
0180
0181 char _license[] SEC("license") = "GPL";