0001
0002
0003 #include <linux/bpf.h>
0004 #include <time.h>
0005 #include <errno.h>
0006 #include <bpf/bpf_helpers.h>
0007 #include "bpf_tcp_helpers.h"
0008
0009 char _license[] SEC("license") = "GPL";
0010 struct hmap_elem {
0011 int counter;
0012 struct bpf_timer timer;
0013 struct bpf_spin_lock lock;
0014 };
0015
0016 struct {
0017 __uint(type, BPF_MAP_TYPE_HASH);
0018 __uint(max_entries, 1000);
0019 __type(key, int);
0020 __type(value, struct hmap_elem);
0021 } hmap SEC(".maps");
0022
0023 struct {
0024 __uint(type, BPF_MAP_TYPE_HASH);
0025 __uint(map_flags, BPF_F_NO_PREALLOC);
0026 __uint(max_entries, 1000);
0027 __type(key, int);
0028 __type(value, struct hmap_elem);
0029 } hmap_malloc SEC(".maps");
0030
0031 struct elem {
0032 struct bpf_timer t;
0033 };
0034
0035 struct {
0036 __uint(type, BPF_MAP_TYPE_ARRAY);
0037 __uint(max_entries, 2);
0038 __type(key, int);
0039 __type(value, struct elem);
0040 } array SEC(".maps");
0041
0042 struct {
0043 __uint(type, BPF_MAP_TYPE_LRU_HASH);
0044 __uint(max_entries, 4);
0045 __type(key, int);
0046 __type(value, struct elem);
0047 } lru SEC(".maps");
0048
0049 __u64 bss_data;
0050 __u64 err;
0051 __u64 ok;
0052 __u64 callback_check = 52;
0053 __u64 callback2_check = 52;
0054
0055 #define ARRAY 1
0056 #define HTAB 2
0057 #define HTAB_MALLOC 3
0058 #define LRU 4
0059
0060
0061 static int timer_cb1(void *map, int *key, struct bpf_timer *timer)
0062 {
0063
0064
0065
0066 bss_data += 5;
0067
0068
0069
0070
0071 if (*key == ARRAY) {
0072 struct bpf_timer *lru_timer;
0073 int lru_key = LRU;
0074
0075
0076 if (bpf_timer_start(timer, 1ull << 35, 0) != 0)
0077 err |= 1;
0078
0079 lru_timer = bpf_map_lookup_elem(&lru, &lru_key);
0080 if (!lru_timer)
0081 return 0;
0082 bpf_timer_set_callback(lru_timer, timer_cb1);
0083 if (bpf_timer_start(lru_timer, 0, 0) != 0)
0084 err |= 2;
0085 } else if (*key == LRU) {
0086 int lru_key, i;
0087
0088 for (i = LRU + 1;
0089 i <= 100
0090
0091 ;
0092 i++) {
0093 struct elem init = {};
0094
0095
0096
0097
0098 lru_key = i;
0099
0100
0101
0102
0103 bpf_map_update_elem(map, &lru_key, &init, 0);
0104
0105 bpf_map_lookup_elem(map, &lru_key);
0106
0107
0108
0109
0110 if (*key != LRU)
0111 break;
0112 }
0113
0114
0115 if (bpf_timer_cancel(timer) != -EINVAL)
0116 err |= 4;
0117 ok |= 1;
0118 }
0119 return 0;
0120 }
0121
0122 SEC("fentry/bpf_fentry_test1")
0123 int BPF_PROG(test1, int a)
0124 {
0125 struct bpf_timer *arr_timer, *lru_timer;
0126 struct elem init = {};
0127 int lru_key = LRU;
0128 int array_key = ARRAY;
0129
0130 arr_timer = bpf_map_lookup_elem(&array, &array_key);
0131 if (!arr_timer)
0132 return 0;
0133 bpf_timer_init(arr_timer, &array, CLOCK_MONOTONIC);
0134
0135 bpf_map_update_elem(&lru, &lru_key, &init, 0);
0136 lru_timer = bpf_map_lookup_elem(&lru, &lru_key);
0137 if (!lru_timer)
0138 return 0;
0139 bpf_timer_init(lru_timer, &lru, CLOCK_MONOTONIC);
0140
0141 bpf_timer_set_callback(arr_timer, timer_cb1);
0142 bpf_timer_start(arr_timer, 0 , 0);
0143
0144
0145
0146
0147 array_key = 0;
0148 arr_timer = bpf_map_lookup_elem(&array, &array_key);
0149 if (!arr_timer)
0150 return 0;
0151 bpf_timer_init(arr_timer, &array, CLOCK_MONOTONIC);
0152 return 0;
0153 }
0154
0155
0156 static int timer_cb2(void *map, int *key, struct hmap_elem *val)
0157 {
0158 if (*key == HTAB)
0159 callback_check--;
0160 else
0161 callback2_check--;
0162 if (val->counter > 0 && --val->counter) {
0163
0164 bpf_timer_start(&val->timer, 1000, 0);
0165 } else if (*key == HTAB) {
0166 struct bpf_timer *arr_timer;
0167 int array_key = ARRAY;
0168
0169
0170
0171
0172 arr_timer = bpf_map_lookup_elem(&array, &array_key);
0173 if (!arr_timer)
0174 return 0;
0175 if (bpf_timer_cancel(arr_timer) != 1)
0176
0177
0178
0179 err |= 8;
0180
0181
0182 if (bpf_timer_cancel(&val->timer) != -EDEADLK)
0183 err |= 16;
0184
0185
0186
0187
0188 bpf_map_delete_elem(map, key);
0189
0190
0191
0192
0193
0194
0195 if (bpf_timer_start(&val->timer, 1000, 0) != -EINVAL)
0196 err |= 32;
0197 ok |= 2;
0198 } else {
0199 if (*key != HTAB_MALLOC)
0200 err |= 64;
0201
0202
0203 if (bpf_timer_cancel(&val->timer) != -EDEADLK)
0204 err |= 128;
0205
0206
0207
0208
0209 bpf_map_delete_elem(map, key);
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220 if (bpf_timer_start(&val->timer, 1ull << 35, 0) != 0)
0221 err |= 256;
0222 ok |= 4;
0223 }
0224 return 0;
0225 }
0226
0227 int bpf_timer_test(void)
0228 {
0229 struct hmap_elem *val;
0230 int key = HTAB, key_malloc = HTAB_MALLOC;
0231
0232 val = bpf_map_lookup_elem(&hmap, &key);
0233 if (val) {
0234 if (bpf_timer_init(&val->timer, &hmap, CLOCK_BOOTTIME) != 0)
0235 err |= 512;
0236 bpf_timer_set_callback(&val->timer, timer_cb2);
0237 bpf_timer_start(&val->timer, 1000, 0);
0238 }
0239 val = bpf_map_lookup_elem(&hmap_malloc, &key_malloc);
0240 if (val) {
0241 if (bpf_timer_init(&val->timer, &hmap_malloc, CLOCK_BOOTTIME) != 0)
0242 err |= 1024;
0243 bpf_timer_set_callback(&val->timer, timer_cb2);
0244 bpf_timer_start(&val->timer, 1000, 0);
0245 }
0246 return 0;
0247 }
0248
0249 SEC("fentry/bpf_fentry_test2")
0250 int BPF_PROG(test2, int a, int b)
0251 {
0252 struct hmap_elem init = {}, *val;
0253 int key = HTAB, key_malloc = HTAB_MALLOC;
0254
0255 init.counter = 10;
0256 bpf_map_update_elem(&hmap, &key, &init, 0);
0257 val = bpf_map_lookup_elem(&hmap, &key);
0258 if (val)
0259 bpf_timer_init(&val->timer, &hmap, CLOCK_BOOTTIME);
0260
0261 bpf_map_update_elem(&hmap, &key, &init, 0);
0262
0263 bpf_map_update_elem(&hmap_malloc, &key_malloc, &init, 0);
0264 val = bpf_map_lookup_elem(&hmap_malloc, &key_malloc);
0265 if (val)
0266 bpf_timer_init(&val->timer, &hmap_malloc, CLOCK_BOOTTIME);
0267
0268 bpf_map_update_elem(&hmap_malloc, &key_malloc, &init, 0);
0269
0270
0271
0272
0273 key = 0;
0274 bpf_map_update_elem(&hmap, &key, &init, 0);
0275 val = bpf_map_lookup_elem(&hmap, &key);
0276 if (val)
0277 bpf_timer_init(&val->timer, &hmap, CLOCK_BOOTTIME);
0278 bpf_map_delete_elem(&hmap, &key);
0279 bpf_map_update_elem(&hmap, &key, &init, 0);
0280 val = bpf_map_lookup_elem(&hmap, &key);
0281 if (val)
0282 bpf_timer_init(&val->timer, &hmap, CLOCK_BOOTTIME);
0283
0284
0285 key_malloc = 0;
0286 bpf_map_update_elem(&hmap_malloc, &key_malloc, &init, 0);
0287 val = bpf_map_lookup_elem(&hmap_malloc, &key_malloc);
0288 if (val)
0289 bpf_timer_init(&val->timer, &hmap_malloc, CLOCK_BOOTTIME);
0290 bpf_map_delete_elem(&hmap_malloc, &key_malloc);
0291 bpf_map_update_elem(&hmap_malloc, &key_malloc, &init, 0);
0292 val = bpf_map_lookup_elem(&hmap_malloc, &key_malloc);
0293 if (val)
0294 bpf_timer_init(&val->timer, &hmap_malloc, CLOCK_BOOTTIME);
0295
0296 return bpf_timer_test();
0297 }