github.com/dylandreimerink/gobpfld@v0.6.1-0.20220205171531-e79c330ad608/cmd/examples/map_in_map/bpf/map_in_map_counter.c (about)

     1  /* SPDX-License-Identifier: GPL-2.0 */
     2  #include <linux/bpf.h>
     3  #include <linux/if_ether.h>
     4  
     5  /*
     6   * bpf_map_lookup_elem
     7   *
     8   * 	Perform a lookup in *map* for an entry associated to *key*.
     9   *
    10   * Returns
    11   * 	Map value associated to *key*, or **NULL** if no entry was
    12   * 	found.
    13   */
    14  static void *(*bpf_map_lookup_elem)(void *map, const void *key) = (void *) 1;
    15  
    16  #define SEC(NAME) __attribute__((section(NAME), used))
    17  
    18  struct bpf_map_def {
    19  	unsigned int type;
    20  	unsigned int key_size;
    21  	unsigned int value_size;
    22  	unsigned int max_entries;
    23  	unsigned int map_flags;
    24  };
    25  
    26  struct datarec {
    27  	__u64 rx_packets;
    28  };
    29  
    30  struct bpf_map_def SEC("maps") map_of_maps = {
    31  	.type        = BPF_MAP_TYPE_ARRAY_OF_MAPS,
    32  	.key_size    = sizeof(__u32),
    33  	.value_size  = sizeof(__u32),
    34  	.max_entries = 2,
    35  };
    36  
    37  
    38  /* LLVM maps __sync_fetch_and_add() as a built-in function to the BPF atomic add
    39   * instruction (that is BPF_STX | BPF_XADD | BPF_W for word sizes)
    40   */
    41  #ifndef lock_xadd
    42  #define lock_xadd(ptr, val)	((void) __sync_fetch_and_add(ptr, val))
    43  #endif
    44  
    45  SEC("xdp")
    46  int  xdp_stats1_func(struct xdp_md *ctx)
    47  {	
    48  	__u32 key = 0;
    49  
    50  	// Lookup the pointer to the map inner map
    51  	struct bpf_map_def *stats_map = bpf_map_lookup_elem(&map_of_maps, &key);
    52  	if (!stats_map) {
    53  		return XDP_ABORTED;
    54  	}
    55  
    56  	// Lookup datarec struct in inner map, we will use key
    57  	struct datarec *rec;
    58  	key = XDP_PASS; /* XDP_PASS = 2 */
    59  
    60  	rec = bpf_map_lookup_elem(stats_map, &key);
    61  	if (!rec)
    62  		return XDP_ABORTED;
    63  
    64  	/* Multiple CPUs can access data record. Thus, the accounting needs to
    65  	 * use an atomic operation.
    66  	 */
    67  	lock_xadd(&rec->rx_packets, 1);
    68  
    69  	return XDP_PASS;
    70  }
    71  
    72  char _license[] SEC("license") = "GPL";