0001
0002
0003 #include "vmlinux.h"
0004
0005 #include <bpf/bpf_helpers.h>
0006 #include <bpf/bpf_tracing.h>
0007 #include <bpf/bpf_core_read.h>
0008
0009 #define ATTR __always_inline
0010 #include "test_jhash.h"
0011
0012 struct {
0013 __uint(type, BPF_MAP_TYPE_ARRAY);
0014 __type(key, u32);
0015 __type(value, u32);
0016 __uint(max_entries, 256);
0017 } array1 SEC(".maps");
0018
0019 struct {
0020 __uint(type, BPF_MAP_TYPE_ARRAY);
0021 __type(key, u32);
0022 __type(value, u32);
0023 __uint(max_entries, 256);
0024 } array2 SEC(".maps");
0025
0026 static __noinline int randmap(int v, const struct net_device *dev)
0027 {
0028 struct bpf_map *map = (struct bpf_map *)&array1;
0029 int key = bpf_get_prandom_u32() & 0xff;
0030 int *val;
0031
0032 if (bpf_get_prandom_u32() & 1)
0033 map = (struct bpf_map *)&array2;
0034
0035 val = bpf_map_lookup_elem(map, &key);
0036 if (val)
0037 *val = bpf_get_prandom_u32() + v + dev->mtu;
0038
0039 return 0;
0040 }
0041
0042 SEC("tp_btf/xdp_devmap_xmit")
0043 int BPF_PROG(tp_xdp_devmap_xmit_multi, const struct net_device
0044 *from_dev, const struct net_device *to_dev, int sent, int drops,
0045 int err)
0046 {
0047 return randmap(from_dev->ifindex, from_dev);
0048 }
0049
0050 SEC("fentry/eth_type_trans")
0051 int BPF_PROG(fentry_eth_type_trans, struct sk_buff *skb,
0052 struct net_device *dev, unsigned short protocol)
0053 {
0054 return randmap(dev->ifindex + skb->len, dev);
0055 }
0056
0057 SEC("fexit/eth_type_trans")
0058 int BPF_PROG(fexit_eth_type_trans, struct sk_buff *skb,
0059 struct net_device *dev, unsigned short protocol)
0060 {
0061 return randmap(dev->ifindex + skb->len, dev);
0062 }
0063
0064 volatile const int never;
0065
0066 struct __sk_bUfF {
0067 int len;
0068 } __attribute__((preserve_access_index));
0069
0070 struct bpf_testmod_test_read_ctx {
0071 size_t len;
0072 } __attribute__((preserve_access_index));
0073
0074 SEC("tc")
0075 int balancer_ingress(struct __sk_buff *ctx)
0076 {
0077 void *data_end = (void *)(long)ctx->data_end;
0078 void *data = (void *)(long)ctx->data;
0079 void *ptr;
0080 int ret = 0, nh_off, i = 0;
0081
0082 nh_off = 14;
0083
0084
0085 #define C do { \
0086 ptr = data + i; \
0087 if (ptr + nh_off > data_end) \
0088 break; \
0089 ctx->tc_index = jhash(ptr, nh_off, ctx->cb[0] + i++); \
0090 if (never) { \
0091 \
0092 i += ((struct __sk_bUfF *)ctx)->len; \
0093
0094
0095 \
0096 i += ((struct bpf_testmod_test_read_ctx *)ctx)->len; \
0097 } \
0098 } while (0);
0099 #define C30 C;C;C;C;C;C;C;C;C;C;C;C;C;C;C;C;C;C;C;C;C;C;C;C;C;C;C;C;C;C;
0100 C30;C30;C30;
0101 return 0;
0102 }
0103
0104 typedef int (*func_proto_typedef___match)(long);
0105 typedef int (*func_proto_typedef___doesnt_match)(char *);
0106 typedef int (*func_proto_typedef_nested1)(func_proto_typedef___match);
0107
0108 int proto_out[3];
0109
0110 SEC("raw_tracepoint/sys_enter")
0111 int core_relo_proto(void *ctx)
0112 {
0113 proto_out[0] = bpf_core_type_exists(func_proto_typedef___match);
0114 proto_out[1] = bpf_core_type_exists(func_proto_typedef___doesnt_match);
0115 proto_out[2] = bpf_core_type_exists(func_proto_typedef_nested1);
0116
0117 return 0;
0118 }
0119
0120 char LICENSE[] SEC("license") = "GPL";