Re: [RFC] A new bpf map type for fuzzy matching key

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, Apr 15, 2023 at 9:32 PM 沈安琪(凛玥) <amy.saq@xxxxxxxxxxxx> wrote:
>
>
> Hi everyone,
>
> For supporting fuzzy matching in bpf map as described in the original
> question [0], we come up with a proposal that would like to have some
> advice or comments from bpf thread. Thanks a lot for all the feedback :)
>
> We plan to implement a new bpf map type, naming BPF_FM_MAP, standing for
> fuzzy matching map.
> The basic idea is implementing a trie-tree using map of map runtime
> structure.
>
> The number of tree levels equals to the number of fields in the key
> struct. Assuming that the key struct has M fields, the first (M-1) level
> of tree nodes will be hash maps with key as the value of (M-1)-th field
> and entry as the fd of next level map. The last level, regarded as leaf
> nodes, will be hash maps with key as the value of M-th field and entry
> as user-defined entry for this BPF_FM_MAP.
>
> To support fuzzy matching, we add a special value -1 as (M-1)-th field
> key if (M-1)-th field is set as general match.
>
> When looking up a target key in BPF_FM_MAP, it will lookup the first
> level hashmap, matching the entry with the same value on this field and
> with -1 if exists. Then it will lookup the next-level hashmap, whose fd
> is the value it get from the previous level hashmap. It will go through
> all the levels of tree and get a set of leaf nodes it matches. Finally,
> it will sort the set of matched leaf nodes based on their priority,
> which is defined in BPF_FM_MAP entry struct, and return the
> corresponding return value also defined in BPF_FM_MAP entry struct.
>
>
> Given a user-defined key struct and entry struct as following:
>
> struct fm_key {
>      int a;
>      int b;
>      int c;
> }
>
> struct fm_entry {
>      int priority;
>      int value;
> }
>
> and declare a BPF_FM_MAP DEMO_MAP to store incoming key-value pair:
>
> struct {
>      __uint(type, BPF_FM_MAP);
>      __type(key, struct fm_key);
>      __type(value, struct fm_entry);
>      __uint(pinning, LIBBPF_PIN_BY_NAME);
>      __uint(max_entries, 1024);
>      __uint(map_flags, BPF_F_NO_PREALLOC);
> } DEMO_MAP SEC(".maps");
>
> Now, we add the following three key-value pairs into DEMO_MAP:
>
> |a    |b    |c    |priority    |value    |
> |-    |-    |1    |1           |1        |
> |-    |2    |1    |2           |2        |
> |3    |2    |1    |3           |3        |
>
> The tree will be constructed as following:
>
> field a             field b               field c
>
>                                            fd = 3
>                                       ---->| key | (prioriy, value) |
>                                      |     |  1  |       (1, 1) |
>                                      |
>                      fd = 1          |
>                   -->| key | val |   |
>                  |   | -1  |  3  |----     fd = 4
>                  |   |  2  |  4  |-------->| key | (prioriy, value) |
>   fd = 0         |                         |  1  |       (2, 2) |
> | key | val |   |
> | -1  |  1  |----
> |  3  |  2  |----
>                  |   fd = 2
>                   -->| key | val |         fd = 5
>                      |  2  |  5  |-------->| key | (prioriy, value) |
>                                            |  1  |       (3, 3) |
>
>
> After updating the tree, we have three target tuples to lookup in DEMO_MAP.
>
> struct fm_key t1 = {
>      .a = 6,
>      .b = 4,
>      .c = 1
> };
>
> struct fm_key t2 = {
>      .a = 5,
>      .b = 2,
>      .c = 1
> };
>
> struct fm_key t3 = {
>      .a = 3,
>      .b = 2,
>      .c = 1
> };
>
> // map lookup order: 0 -> 1 -> 3
> // matched leaf nodes: (1, 1)
> // picked return value: 1
> map_lookup_elem(&DEMO_MAP, &t1) == 1
>
> // map loopup order: 0 -> 1 -> (3, 4)
> // matched leaf nodes: (1, 1), (2, 2)
> // picked return value: 2
> map_lookup_elem(&DEMO_MAP, &t2) == 2
>
> // map lookup order: 0 -> (1, 2) -> (3, 4, 5)
> // matched leaf nodes: (1, 1), (2, 2), (3, 3)
> // picked return value: 3
> map_loopup_elem(&DEMO_MAP, &t3) == 3
>
>
> Thanks a lot for reviewing this proposal and we really appreciate any
> feedback here.

This sounds like several hash maps chained together with a custom logic.
If so it's not clear why a new map type is necessary.
Just let bpf prog lookup multiple hash maps.




[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux