Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (c) 2021 Facebook */
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 /* it will not exist in vmlinux */ {
0067     int len;
0068 } __attribute__((preserve_access_index));
0069 
0070 struct bpf_testmod_test_read_ctx /* it exists in bpf_testmod */ {
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     /* pragma unroll doesn't work on large loops */
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         /* below is a dead code with unresolvable CO-RE relo */ \
0092         i += ((struct __sk_bUfF *)ctx)->len; \
0093         /* this CO-RE relo may or may not resolve
0094          * depending on whether bpf_testmod is loaded.
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; /* 90 calls */
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";