map_lpm_trie.rst 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. .. SPDX-License-Identifier: GPL-2.0-only
  2. .. Copyright (C) 2022 Red Hat, Inc.
  3. =====================
  4. BPF_MAP_TYPE_LPM_TRIE
  5. =====================
  6. .. note::
  7. - ``BPF_MAP_TYPE_LPM_TRIE`` was introduced in kernel version 4.11
  8. ``BPF_MAP_TYPE_LPM_TRIE`` provides a longest prefix match algorithm that
  9. can be used to match IP addresses to a stored set of prefixes.
  10. Internally, data is stored in an unbalanced trie of nodes that uses
  11. ``prefixlen,data`` pairs as its keys. The ``data`` is interpreted in
  12. network byte order, i.e. big endian, so ``data[0]`` stores the most
  13. significant byte.
  14. LPM tries may be created with a maximum prefix length that is a multiple
  15. of 8, in the range from 8 to 2048. The key used for lookup and update
  16. operations is a ``struct bpf_lpm_trie_key_u8``, extended by
  17. ``max_prefixlen/8`` bytes.
  18. - For IPv4 addresses the data length is 4 bytes
  19. - For IPv6 addresses the data length is 16 bytes
  20. The value type stored in the LPM trie can be any user defined type.
  21. .. note::
  22. When creating a map of type ``BPF_MAP_TYPE_LPM_TRIE`` you must set the
  23. ``BPF_F_NO_PREALLOC`` flag.
  24. Usage
  25. =====
  26. Kernel BPF
  27. ----------
  28. bpf_map_lookup_elem()
  29. ~~~~~~~~~~~~~~~~~~~~~
  30. .. code-block:: c
  31. void *bpf_map_lookup_elem(struct bpf_map *map, const void *key)
  32. The longest prefix entry for a given data value can be found using the
  33. ``bpf_map_lookup_elem()`` helper. This helper returns a pointer to the
  34. value associated with the longest matching ``key``, or ``NULL`` if no
  35. entry was found.
  36. The ``key`` should have ``prefixlen`` set to ``max_prefixlen`` when
  37. performing longest prefix lookups. For example, when searching for the
  38. longest prefix match for an IPv4 address, ``prefixlen`` should be set to
  39. ``32``.
  40. bpf_map_update_elem()
  41. ~~~~~~~~~~~~~~~~~~~~~
  42. .. code-block:: c
  43. long bpf_map_update_elem(struct bpf_map *map, const void *key, const void *value, u64 flags)
  44. Prefix entries can be added or updated using the ``bpf_map_update_elem()``
  45. helper. This helper replaces existing elements atomically.
  46. ``bpf_map_update_elem()`` returns ``0`` on success, or negative error in
  47. case of failure.
  48. .. note::
  49. The flags parameter must be one of BPF_ANY, BPF_NOEXIST or BPF_EXIST,
  50. but the value is ignored, giving BPF_ANY semantics.
  51. bpf_map_delete_elem()
  52. ~~~~~~~~~~~~~~~~~~~~~
  53. .. code-block:: c
  54. long bpf_map_delete_elem(struct bpf_map *map, const void *key)
  55. Prefix entries can be deleted using the ``bpf_map_delete_elem()``
  56. helper. This helper will return 0 on success, or negative error in case
  57. of failure.
  58. Userspace
  59. ---------
  60. Access from userspace uses libbpf APIs with the same names as above, with
  61. the map identified by ``fd``.
  62. bpf_map_get_next_key()
  63. ~~~~~~~~~~~~~~~~~~~~~~
  64. .. code-block:: c
  65. int bpf_map_get_next_key (int fd, const void *cur_key, void *next_key)
  66. A userspace program can iterate through the entries in an LPM trie using
  67. libbpf's ``bpf_map_get_next_key()`` function. The first key can be
  68. fetched by calling ``bpf_map_get_next_key()`` with ``cur_key`` set to
  69. ``NULL``. Subsequent calls will fetch the next key that follows the
  70. current key. ``bpf_map_get_next_key()`` returns ``0`` on success,
  71. ``-ENOENT`` if ``cur_key`` is the last key in the trie, or negative
  72. error in case of failure.
  73. ``bpf_map_get_next_key()`` will iterate through the LPM trie elements
  74. from leftmost leaf first. This means that iteration will return more
  75. specific keys before less specific ones.
  76. Examples
  77. ========
  78. Please see ``tools/testing/selftests/bpf/test_lpm_map.c`` for examples
  79. of LPM trie usage from userspace. The code snippets below demonstrate
  80. API usage.
  81. Kernel BPF
  82. ----------
  83. The following BPF code snippet shows how to declare a new LPM trie for IPv4
  84. address prefixes:
  85. .. code-block:: c
  86. #include <linux/bpf.h>
  87. #include <bpf/bpf_helpers.h>
  88. struct ipv4_lpm_key {
  89. __u32 prefixlen;
  90. __u32 data;
  91. };
  92. struct {
  93. __uint(type, BPF_MAP_TYPE_LPM_TRIE);
  94. __type(key, struct ipv4_lpm_key);
  95. __type(value, __u32);
  96. __uint(map_flags, BPF_F_NO_PREALLOC);
  97. __uint(max_entries, 255);
  98. } ipv4_lpm_map SEC(".maps");
  99. The following BPF code snippet shows how to lookup by IPv4 address:
  100. .. code-block:: c
  101. void *lookup(__u32 ipaddr)
  102. {
  103. struct ipv4_lpm_key key = {
  104. .prefixlen = 32,
  105. .data = ipaddr
  106. };
  107. return bpf_map_lookup_elem(&ipv4_lpm_map, &key);
  108. }
  109. Userspace
  110. ---------
  111. The following snippet shows how to insert an IPv4 prefix entry into an
  112. LPM trie:
  113. .. code-block:: c
  114. int add_prefix_entry(int lpm_fd, __u32 addr, __u32 prefixlen, struct value *value)
  115. {
  116. struct ipv4_lpm_key ipv4_key = {
  117. .prefixlen = prefixlen,
  118. .data = addr
  119. };
  120. return bpf_map_update_elem(lpm_fd, &ipv4_key, value, BPF_ANY);
  121. }
  122. The following snippet shows a userspace program walking through the entries
  123. of an LPM trie:
  124. .. code-block:: c
  125. #include <bpf/libbpf.h>
  126. #include <bpf/bpf.h>
  127. void iterate_lpm_trie(int map_fd)
  128. {
  129. struct ipv4_lpm_key *cur_key = NULL;
  130. struct ipv4_lpm_key next_key;
  131. struct value value;
  132. int err;
  133. for (;;) {
  134. err = bpf_map_get_next_key(map_fd, cur_key, &next_key);
  135. if (err)
  136. break;
  137. bpf_map_lookup_elem(map_fd, &next_key, &value);
  138. /* Use key and value here */
  139. cur_key = &next_key;
  140. }
  141. }