xref: /linux/Documentation/bpf/map_bloom_filter.rst (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
1*264c2186SDonald Hunter.. SPDX-License-Identifier: GPL-2.0-only
2*264c2186SDonald Hunter.. Copyright (C) 2022 Red Hat, Inc.
3*264c2186SDonald Hunter
4*264c2186SDonald Hunter=========================
5*264c2186SDonald HunterBPF_MAP_TYPE_BLOOM_FILTER
6*264c2186SDonald Hunter=========================
7*264c2186SDonald Hunter
8*264c2186SDonald Hunter.. note::
9*264c2186SDonald Hunter   - ``BPF_MAP_TYPE_BLOOM_FILTER`` was introduced in kernel version 5.16
10*264c2186SDonald Hunter
11*264c2186SDonald Hunter``BPF_MAP_TYPE_BLOOM_FILTER`` provides a BPF bloom filter map. Bloom
12*264c2186SDonald Hunterfilters are a space-efficient probabilistic data structure used to
13*264c2186SDonald Hunterquickly test whether an element exists in a set. In a bloom filter,
14*264c2186SDonald Hunterfalse positives are possible whereas false negatives are not.
15*264c2186SDonald Hunter
16*264c2186SDonald HunterThe bloom filter map does not have keys, only values. When the bloom
17*264c2186SDonald Hunterfilter map is created, it must be created with a ``key_size`` of 0.  The
18*264c2186SDonald Hunterbloom filter map supports two operations:
19*264c2186SDonald Hunter
20*264c2186SDonald Hunter- push: adding an element to the map
21*264c2186SDonald Hunter- peek: determining whether an element is present in the map
22*264c2186SDonald Hunter
23*264c2186SDonald HunterBPF programs must use ``bpf_map_push_elem`` to add an element to the
24*264c2186SDonald Hunterbloom filter map and ``bpf_map_peek_elem`` to query the map. These
25*264c2186SDonald Hunteroperations are exposed to userspace applications using the existing
26*264c2186SDonald Hunter``bpf`` syscall in the following way:
27*264c2186SDonald Hunter
28*264c2186SDonald Hunter- ``BPF_MAP_UPDATE_ELEM`` -> push
29*264c2186SDonald Hunter- ``BPF_MAP_LOOKUP_ELEM`` -> peek
30*264c2186SDonald Hunter
31*264c2186SDonald HunterThe ``max_entries`` size that is specified at map creation time is used
32*264c2186SDonald Hunterto approximate a reasonable bitmap size for the bloom filter, and is not
33*264c2186SDonald Hunterotherwise strictly enforced. If the user wishes to insert more entries
34*264c2186SDonald Hunterinto the bloom filter than ``max_entries``, this may lead to a higher
35*264c2186SDonald Hunterfalse positive rate.
36*264c2186SDonald Hunter
37*264c2186SDonald HunterThe number of hashes to use for the bloom filter is configurable using
38*264c2186SDonald Hunterthe lower 4 bits of ``map_extra`` in ``union bpf_attr`` at map creation
39*264c2186SDonald Huntertime. If no number is specified, the default used will be 5 hash
40*264c2186SDonald Hunterfunctions. In general, using more hashes decreases both the false
41*264c2186SDonald Hunterpositive rate and the speed of a lookup.
42*264c2186SDonald Hunter
43*264c2186SDonald HunterIt is not possible to delete elements from a bloom filter map. A bloom
44*264c2186SDonald Hunterfilter map may be used as an inner map. The user is responsible for
45*264c2186SDonald Huntersynchronising concurrent updates and lookups to ensure no false negative
46*264c2186SDonald Hunterlookups occur.
47*264c2186SDonald Hunter
48*264c2186SDonald HunterUsage
49*264c2186SDonald Hunter=====
50*264c2186SDonald Hunter
51*264c2186SDonald HunterKernel BPF
52*264c2186SDonald Hunter----------
53*264c2186SDonald Hunter
54*264c2186SDonald Hunterbpf_map_push_elem()
55*264c2186SDonald Hunter~~~~~~~~~~~~~~~~~~~
56*264c2186SDonald Hunter
57*264c2186SDonald Hunter.. code-block:: c
58*264c2186SDonald Hunter
59*264c2186SDonald Hunter   long bpf_map_push_elem(struct bpf_map *map, const void *value, u64 flags)
60*264c2186SDonald Hunter
61*264c2186SDonald HunterA ``value`` can be added to a bloom filter using the
62*264c2186SDonald Hunter``bpf_map_push_elem()`` helper. The ``flags`` parameter must be set to
63*264c2186SDonald Hunter``BPF_ANY`` when adding an entry to the bloom filter. This helper
64*264c2186SDonald Hunterreturns ``0`` on success, or negative error in case of failure.
65*264c2186SDonald Hunter
66*264c2186SDonald Hunterbpf_map_peek_elem()
67*264c2186SDonald Hunter~~~~~~~~~~~~~~~~~~~
68*264c2186SDonald Hunter
69*264c2186SDonald Hunter.. code-block:: c
70*264c2186SDonald Hunter
71*264c2186SDonald Hunter   long bpf_map_peek_elem(struct bpf_map *map, void *value)
72*264c2186SDonald Hunter
73*264c2186SDonald HunterThe ``bpf_map_peek_elem()`` helper is used to determine whether
74*264c2186SDonald Hunter``value`` is present in the bloom filter map. This helper returns ``0``
75*264c2186SDonald Hunterif ``value`` is probably present in the map, or ``-ENOENT`` if ``value``
76*264c2186SDonald Hunteris definitely not present in the map.
77*264c2186SDonald Hunter
78*264c2186SDonald HunterUserspace
79*264c2186SDonald Hunter---------
80*264c2186SDonald Hunter
81*264c2186SDonald Hunterbpf_map_update_elem()
82*264c2186SDonald Hunter~~~~~~~~~~~~~~~~~~~~~
83*264c2186SDonald Hunter
84*264c2186SDonald Hunter.. code-block:: c
85*264c2186SDonald Hunter
86*264c2186SDonald Hunter   int bpf_map_update_elem (int fd, const void *key, const void *value, __u64 flags)
87*264c2186SDonald Hunter
88*264c2186SDonald HunterA userspace program can add a ``value`` to a bloom filter using libbpf's
89*264c2186SDonald Hunter``bpf_map_update_elem`` function. The ``key`` parameter must be set to
90*264c2186SDonald Hunter``NULL`` and ``flags`` must be set to ``BPF_ANY``. Returns ``0`` on
91*264c2186SDonald Huntersuccess, or negative error in case of failure.
92*264c2186SDonald Hunter
93*264c2186SDonald Hunterbpf_map_lookup_elem()
94*264c2186SDonald Hunter~~~~~~~~~~~~~~~~~~~~~
95*264c2186SDonald Hunter
96*264c2186SDonald Hunter.. code-block:: c
97*264c2186SDonald Hunter
98*264c2186SDonald Hunter   int bpf_map_lookup_elem (int fd, const void *key, void *value)
99*264c2186SDonald Hunter
100*264c2186SDonald HunterA userspace program can determine the presence of ``value`` in a bloom
101*264c2186SDonald Hunterfilter using libbpf's ``bpf_map_lookup_elem`` function. The ``key``
102*264c2186SDonald Hunterparameter must be set to ``NULL``. Returns ``0`` if ``value`` is
103*264c2186SDonald Hunterprobably present in the map, or ``-ENOENT`` if ``value`` is definitely
104*264c2186SDonald Hunternot present in the map.
105*264c2186SDonald Hunter
106*264c2186SDonald HunterExamples
107*264c2186SDonald Hunter========
108*264c2186SDonald Hunter
109*264c2186SDonald HunterKernel BPF
110*264c2186SDonald Hunter----------
111*264c2186SDonald Hunter
112*264c2186SDonald HunterThis snippet shows how to declare a bloom filter in a BPF program:
113*264c2186SDonald Hunter
114*264c2186SDonald Hunter.. code-block:: c
115*264c2186SDonald Hunter
116*264c2186SDonald Hunter    struct {
117*264c2186SDonald Hunter            __uint(type, BPF_MAP_TYPE_BLOOM_FILTER);
118*264c2186SDonald Hunter            __type(value, __u32);
119*264c2186SDonald Hunter            __uint(max_entries, 1000);
120*264c2186SDonald Hunter            __uint(map_extra, 3);
121*264c2186SDonald Hunter    } bloom_filter SEC(".maps");
122*264c2186SDonald Hunter
123*264c2186SDonald HunterThis snippet shows how to determine presence of a value in a bloom
124*264c2186SDonald Hunterfilter in a BPF program:
125*264c2186SDonald Hunter
126*264c2186SDonald Hunter.. code-block:: c
127*264c2186SDonald Hunter
128*264c2186SDonald Hunter    void *lookup(__u32 key)
129*264c2186SDonald Hunter    {
130*264c2186SDonald Hunter            if (bpf_map_peek_elem(&bloom_filter, &key) == 0) {
131*264c2186SDonald Hunter                    /* Verify not a false positive and fetch an associated
132*264c2186SDonald Hunter                     * value using a secondary lookup, e.g. in a hash table
133*264c2186SDonald Hunter                     */
134*264c2186SDonald Hunter                    return bpf_map_lookup_elem(&hash_table, &key);
135*264c2186SDonald Hunter            }
136*264c2186SDonald Hunter            return 0;
137*264c2186SDonald Hunter    }
138*264c2186SDonald Hunter
139*264c2186SDonald HunterUserspace
140*264c2186SDonald Hunter---------
141*264c2186SDonald Hunter
142*264c2186SDonald HunterThis snippet shows how to use libbpf to create a bloom filter map from
143*264c2186SDonald Hunteruserspace:
144*264c2186SDonald Hunter
145*264c2186SDonald Hunter.. code-block:: c
146*264c2186SDonald Hunter
147*264c2186SDonald Hunter    int create_bloom()
148*264c2186SDonald Hunter    {
149*264c2186SDonald Hunter            LIBBPF_OPTS(bpf_map_create_opts, opts,
150*264c2186SDonald Hunter                        .map_extra = 3);             /* number of hashes */
151*264c2186SDonald Hunter
152*264c2186SDonald Hunter            return bpf_map_create(BPF_MAP_TYPE_BLOOM_FILTER,
153*264c2186SDonald Hunter                                  "ipv6_bloom",      /* name */
154*264c2186SDonald Hunter                                  0,                 /* key size, must be zero */
155*264c2186SDonald Hunter                                  sizeof(ipv6_addr), /* value size */
156*264c2186SDonald Hunter                                  10000,             /* max entries */
157*264c2186SDonald Hunter                                  &opts);            /* create options */
158*264c2186SDonald Hunter    }
159*264c2186SDonald Hunter
160*264c2186SDonald HunterThis snippet shows how to add an element to a bloom filter from
161*264c2186SDonald Hunteruserspace:
162*264c2186SDonald Hunter
163*264c2186SDonald Hunter.. code-block:: c
164*264c2186SDonald Hunter
165*264c2186SDonald Hunter    int add_element(struct bpf_map *bloom_map, __u32 value)
166*264c2186SDonald Hunter    {
167*264c2186SDonald Hunter            int bloom_fd = bpf_map__fd(bloom_map);
168*264c2186SDonald Hunter            return bpf_map_update_elem(bloom_fd, NULL, &value, BPF_ANY);
169*264c2186SDonald Hunter    }
170*264c2186SDonald Hunter
171*264c2186SDonald HunterReferences
172*264c2186SDonald Hunter==========
173*264c2186SDonald Hunter
174*264c2186SDonald Hunterhttps://lwn.net/ml/bpf/20210831225005.2762202-1-joannekoong@fb.com/
175