162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright (c) 2021 Facebook */ 362306a36Sopenharmony_ci#include <linux/bpf.h> 462306a36Sopenharmony_ci#include <time.h> 562306a36Sopenharmony_ci#include <errno.h> 662306a36Sopenharmony_ci#include <bpf/bpf_helpers.h> 762306a36Sopenharmony_ci#include "bpf_tcp_helpers.h" 862306a36Sopenharmony_ci 962306a36Sopenharmony_cichar _license[] SEC("license") = "GPL"; 1062306a36Sopenharmony_cistruct hmap_elem { 1162306a36Sopenharmony_ci int pad; /* unused */ 1262306a36Sopenharmony_ci struct bpf_timer timer; 1362306a36Sopenharmony_ci}; 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_cistruct inner_map { 1662306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_HASH); 1762306a36Sopenharmony_ci __uint(max_entries, 1024); 1862306a36Sopenharmony_ci __type(key, int); 1962306a36Sopenharmony_ci __type(value, struct hmap_elem); 2062306a36Sopenharmony_ci} inner_htab SEC(".maps"); 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define ARRAY_KEY 1 2362306a36Sopenharmony_ci#define HASH_KEY 1234 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cistruct outer_arr { 2662306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS); 2762306a36Sopenharmony_ci __uint(max_entries, 2); 2862306a36Sopenharmony_ci __uint(key_size, sizeof(int)); 2962306a36Sopenharmony_ci __uint(value_size, sizeof(int)); 3062306a36Sopenharmony_ci __array(values, struct inner_map); 3162306a36Sopenharmony_ci} outer_arr SEC(".maps") = { 3262306a36Sopenharmony_ci .values = { [ARRAY_KEY] = &inner_htab }, 3362306a36Sopenharmony_ci}; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci__u64 err; 3662306a36Sopenharmony_ci__u64 ok; 3762306a36Sopenharmony_ci__u64 cnt; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistatic int timer_cb1(void *map, int *key, struct hmap_elem *val); 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_cistatic int timer_cb2(void *map, int *key, struct hmap_elem *val) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci cnt++; 4462306a36Sopenharmony_ci bpf_timer_set_callback(&val->timer, timer_cb1); 4562306a36Sopenharmony_ci if (bpf_timer_start(&val->timer, 1000, 0)) 4662306a36Sopenharmony_ci err |= 1; 4762306a36Sopenharmony_ci ok |= 1; 4862306a36Sopenharmony_ci return 0; 4962306a36Sopenharmony_ci} 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci/* callback for inner hash map */ 5262306a36Sopenharmony_cistatic int timer_cb1(void *map, int *key, struct hmap_elem *val) 5362306a36Sopenharmony_ci{ 5462306a36Sopenharmony_ci cnt++; 5562306a36Sopenharmony_ci bpf_timer_set_callback(&val->timer, timer_cb2); 5662306a36Sopenharmony_ci if (bpf_timer_start(&val->timer, 1000, 0)) 5762306a36Sopenharmony_ci err |= 2; 5862306a36Sopenharmony_ci /* Do a lookup to make sure 'map' and 'key' pointers are correct */ 5962306a36Sopenharmony_ci bpf_map_lookup_elem(map, key); 6062306a36Sopenharmony_ci ok |= 2; 6162306a36Sopenharmony_ci return 0; 6262306a36Sopenharmony_ci} 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ciSEC("fentry/bpf_fentry_test1") 6562306a36Sopenharmony_ciint BPF_PROG(test1, int a) 6662306a36Sopenharmony_ci{ 6762306a36Sopenharmony_ci struct hmap_elem init = {}; 6862306a36Sopenharmony_ci struct bpf_map *inner_map; 6962306a36Sopenharmony_ci struct hmap_elem *val; 7062306a36Sopenharmony_ci int array_key = ARRAY_KEY; 7162306a36Sopenharmony_ci int hash_key = HASH_KEY; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci inner_map = bpf_map_lookup_elem(&outer_arr, &array_key); 7462306a36Sopenharmony_ci if (!inner_map) 7562306a36Sopenharmony_ci return 0; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci bpf_map_update_elem(inner_map, &hash_key, &init, 0); 7862306a36Sopenharmony_ci val = bpf_map_lookup_elem(inner_map, &hash_key); 7962306a36Sopenharmony_ci if (!val) 8062306a36Sopenharmony_ci return 0; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci bpf_timer_init(&val->timer, inner_map, CLOCK_MONOTONIC); 8362306a36Sopenharmony_ci if (bpf_timer_set_callback(&val->timer, timer_cb1)) 8462306a36Sopenharmony_ci err |= 4; 8562306a36Sopenharmony_ci if (bpf_timer_start(&val->timer, 0, 0)) 8662306a36Sopenharmony_ci err |= 8; 8762306a36Sopenharmony_ci return 0; 8862306a36Sopenharmony_ci} 89