History

bpf: Handle BPF_EXIST and BPF_NOEXIST for LPM trie

Add the currently missing handling for the BPF_EXIST and BPF_NOEXIST flags. These flags can be specified by users and are relevant since LPM trie supports exact matches during update.

Hou Tao committed 1 year ago

Commit eae6a071 parent 3d5611b1 file · +20 −3Browse files

Unified · Split

kernel/bpf/lpm_trie.c+20−3
@@ -375,6 +375,10 @@ static long trie_update_elem(struct bpf_map *map, · 374 unmodified lines
375375 * simply assign the @new_node to that slot and be done.
376376 */
377377 if (!node) {
378+ if (flags == BPF_EXIST) {
379+ ret = -ENOENT;
380+ goto out;
381+ }
378382 rcu_assign_pointer(*slot, new_node);
379383 goto out;
380384 }
@@ -383,18 +387,31 @@ static long trie_update_elem(struct bpf_map *map, · 2 unmodified lines
383387 * which already has the correct data array set.
384388 */
385389 if (node->prefixlen == matchlen) {
390+ if (!(node->flags & LPM_TREE_NODE_FLAG_IM)) {
391+ if (flags == BPF_NOEXIST) {
392+ ret = -EEXIST;
393+ goto out;
394+ }
395+ trie->n_entries--;
396+ } else if (flags == BPF_EXIST) {
397+ ret = -ENOENT;
398+ goto out;
399+ }
400+
386401 new_node->child[0] = node->child[0];
387402 new_node->child[1] = node->child[1];
388403
389− if (!(node->flags & LPM_TREE_NODE_FLAG_IM))
390− trie->n_entries--;
391−
392404 rcu_assign_pointer(*slot, new_node);
393405 free_node = node;
394406
395407 goto out;
396408 }
397409
410+ if (flags == BPF_EXIST) {
411+ ret = -ENOENT;
412+ goto out;
413+ }
414+
398415 /* If the new node matches the prefix completely, it must be inserted
399416 * as an ancestor. Simply insert it between @node and *@slot.
400417 */