mirror of
https://github.com/aya-rs/aya.git
synced 2026-06-13 15:37:16 +02:00
Merge pull request #526 from dave-tucker/trie
aya: Remove iter_key from LPM Trie API
This commit is contained in:
+22
-65
@@ -6,7 +6,7 @@ use std::{
|
||||
|
||||
use crate::{
|
||||
maps::{check_kv_size, IterableMap, MapData, MapError, MapIter, MapKeys},
|
||||
sys::{bpf_map_delete_elem, bpf_map_get_next_key, bpf_map_lookup_elem, bpf_map_update_elem},
|
||||
sys::{bpf_map_delete_elem, bpf_map_lookup_elem, bpf_map_update_elem},
|
||||
Pod,
|
||||
};
|
||||
|
||||
@@ -26,7 +26,7 @@ use crate::{
|
||||
/// let mut trie = LpmTrie::try_from(bpf.map_mut("LPM_TRIE").unwrap())?;
|
||||
/// let ipaddr = Ipv4Addr::new(8, 8, 8, 8);
|
||||
/// // The following represents a key for the "8.8.8.8/16" subnet.
|
||||
/// // The first argument - the prefix length - represents how many bytes should be matched against. The second argument is the actual data to be matched.
|
||||
/// // The first argument - the prefix length - represents how many bits should be matched against. The second argument is the actual data to be matched.
|
||||
/// let key = Key::new(16, u32::from(ipaddr).to_be());
|
||||
/// trie.insert(&key, 1, 0)?;
|
||||
///
|
||||
@@ -51,7 +51,7 @@ pub struct LpmTrie<T, K, V> {
|
||||
_v: PhantomData<V>,
|
||||
}
|
||||
|
||||
/// A Key for and LpmTrie map.
|
||||
/// A Key for an LpmTrie map.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@@ -64,15 +64,18 @@ pub struct LpmTrie<T, K, V> {
|
||||
/// ```
|
||||
#[repr(packed)]
|
||||
pub struct Key<K: Pod> {
|
||||
/// Represents the number of bytes matched against.
|
||||
pub prefix_len: u32,
|
||||
/// Represents arbitrary data stored in the LpmTrie.
|
||||
pub data: K,
|
||||
prefix_len: u32,
|
||||
data: K,
|
||||
}
|
||||
|
||||
impl<K: Pod> Key<K> {
|
||||
/// Creates a new key.
|
||||
///
|
||||
/// `prefix_len` is the number of bits in the data to match against.
|
||||
/// `data` is the data in the key which is typically an IPv4 or IPv6 address.
|
||||
/// If using a key to perform a longest prefix match on you would use a `prefix_len`
|
||||
/// of 32 for IPv4 and 128 for IPv6.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
@@ -85,6 +88,16 @@ impl<K: Pod> Key<K> {
|
||||
pub fn new(prefix_len: u32, data: K) -> Self {
|
||||
Self { prefix_len, data }
|
||||
}
|
||||
|
||||
/// Returns the number of bits in the data to be matched.
|
||||
pub fn prefix_len(&self) -> u32 {
|
||||
self.prefix_len
|
||||
}
|
||||
|
||||
/// Returns the data stored in the Key.
|
||||
pub fn data(&self) -> K {
|
||||
self.data
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Pod> Copy for Key<K> {}
|
||||
@@ -124,23 +137,17 @@ impl<T: Borrow<MapData>, K: Pod, V: Pod> LpmTrie<T, K, V> {
|
||||
value.ok_or(MapError::KeyNotFound)
|
||||
}
|
||||
|
||||
/// An iterator visiting all key-value pairs in arbitrary order. The
|
||||
/// An iterator visiting all key-value pairs. The
|
||||
/// iterator item type is `Result<(K, V), MapError>`.
|
||||
pub fn iter(&self) -> MapIter<'_, Key<K>, V, Self> {
|
||||
MapIter::new(self)
|
||||
}
|
||||
|
||||
/// An iterator visiting all keys in arbitrary order. The iterator element
|
||||
/// An iterator visiting all keys. The iterator element
|
||||
/// type is `Result<Key<K>, MapError>`.
|
||||
pub fn keys(&self) -> MapKeys<'_, Key<K>> {
|
||||
MapKeys::new(self.inner.borrow())
|
||||
}
|
||||
|
||||
/// An iterator visiting all keys matching key. The
|
||||
/// iterator item type is `Result<Key<K>, MapError>`.
|
||||
pub fn iter_key(&self, key: Key<K>) -> LpmTrieKeys<'_, K> {
|
||||
LpmTrieKeys::new(self.inner.borrow(), key)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BorrowMut<MapData>, K: Pod, V: Pod> LpmTrie<T, K, V> {
|
||||
@@ -186,56 +193,6 @@ impl<T: Borrow<MapData>, K: Pod, V: Pod> IterableMap<Key<K>, V> for LpmTrie<T, K
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterator returned by `LpmTrie::iter_key()`.
|
||||
pub struct LpmTrieKeys<'coll, K: Pod> {
|
||||
map: &'coll MapData,
|
||||
err: bool,
|
||||
key: Key<K>,
|
||||
}
|
||||
|
||||
impl<'coll, K: Pod> LpmTrieKeys<'coll, K> {
|
||||
fn new(map: &'coll MapData, key: Key<K>) -> LpmTrieKeys<'coll, K> {
|
||||
LpmTrieKeys {
|
||||
map,
|
||||
err: false,
|
||||
key,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Pod> Iterator for LpmTrieKeys<'_, K> {
|
||||
type Item = Result<Key<K>, MapError>;
|
||||
|
||||
fn next(&mut self) -> Option<Result<Key<K>, MapError>> {
|
||||
if self.err {
|
||||
return None;
|
||||
}
|
||||
|
||||
let fd = match self.map.fd_or_err() {
|
||||
Ok(fd) => fd,
|
||||
Err(e) => {
|
||||
self.err = true;
|
||||
return Some(Err(e));
|
||||
}
|
||||
};
|
||||
|
||||
match bpf_map_get_next_key(fd, Some(&self.key)) {
|
||||
Ok(Some(key)) => {
|
||||
self.key = key;
|
||||
Some(Ok(key))
|
||||
}
|
||||
Ok(None) => None,
|
||||
Err((_, io_error)) => {
|
||||
self.err = true;
|
||||
Some(Err(MapError::SyscallError {
|
||||
call: "bpf_map_get_next_key".to_owned(),
|
||||
io_error,
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user