summaryrefslogtreecommitdiff
path: root/kernel/bpf
diff options
context:
space:
mode:
authorHou Tao <houtao1@huawei.com>2024-12-06 19:06:16 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-12-14 20:03:19 +0100
commit81ec3c6ceb7c9e67aeed32efff97009362088b8a (patch)
tree2d90630efbfa0a88fb39b9c9f3bb93639c8ff669 /kernel/bpf
parent0d8658c0cb599a5a2de809f88e335072c38d463d (diff)
downloadlinux-81ec3c6ceb7c9e67aeed32efff97009362088b8a.tar.gz
linux-81ec3c6ceb7c9e67aeed32efff97009362088b8a.tar.bz2
linux-81ec3c6ceb7c9e67aeed32efff97009362088b8a.zip
bpf: Handle BPF_EXIST and BPF_NOEXIST for LPM trie
[ Upstream commit eae6a075e9537dd69891cf77ca5a88fa8a28b4a1 ] 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. Fixes: b95a5c4db09b ("bpf: add a longest prefix match trie map implementation") Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: Hou Tao <houtao1@huawei.com> Link: https://lore.kernel.org/r/20241206110622.1161752-4-houtao@huaweicloud.com Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'kernel/bpf')
-rw-r--r--kernel/bpf/lpm_trie.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/kernel/bpf/lpm_trie.c b/kernel/bpf/lpm_trie.c
index 9b60eda0f727..a82cf3693778 100644
--- a/kernel/bpf/lpm_trie.c
+++ b/kernel/bpf/lpm_trie.c
@@ -376,6 +376,10 @@ static long trie_update_elem(struct bpf_map *map,
* simply assign the @new_node to that slot and be done.
*/
if (!node) {
+ if (flags == BPF_EXIST) {
+ ret = -ENOENT;
+ goto out;
+ }
rcu_assign_pointer(*slot, new_node);
goto out;
}
@@ -384,18 +388,31 @@ static long trie_update_elem(struct bpf_map *map,
* which already has the correct data array set.
*/
if (node->prefixlen == matchlen) {
+ if (!(node->flags & LPM_TREE_NODE_FLAG_IM)) {
+ if (flags == BPF_NOEXIST) {
+ ret = -EEXIST;
+ goto out;
+ }
+ trie->n_entries--;
+ } else if (flags == BPF_EXIST) {
+ ret = -ENOENT;
+ goto out;
+ }
+
new_node->child[0] = node->child[0];
new_node->child[1] = node->child[1];
- if (!(node->flags & LPM_TREE_NODE_FLAG_IM))
- trie->n_entries--;
-
rcu_assign_pointer(*slot, new_node);
free_node = node;
goto out;
}
+ if (flags == BPF_EXIST) {
+ ret = -ENOENT;
+ goto out;
+ }
+
/* If the new node matches the prefix completely, it must be inserted
* as an ancestor. Simply insert it between @node and *@slot.
*/