mirror of
https://github.com/smoltcp-rs/smoltcp.git
synced 2025-10-02 15:15:05 +00:00
Merge pull request #790 from thvdveld/rpl-relations-buffer
Add RPL relations table
This commit is contained in:
commit
7b4246d003
@ -214,6 +214,15 @@ dns-max-name-size-64 = []
|
|||||||
dns-max-name-size-128 = []
|
dns-max-name-size-128 = []
|
||||||
dns-max-name-size-255 = [] # Default
|
dns-max-name-size-255 = [] # Default
|
||||||
|
|
||||||
|
rpl-relations-buffer-count-1 = []
|
||||||
|
rpl-relations-buffer-count-2 = []
|
||||||
|
rpl-relations-buffer-count-4 = []
|
||||||
|
rpl-relations-buffer-count-8 = []
|
||||||
|
rpl-relations-buffer-count-16 = [] # Default
|
||||||
|
rpl-relations-buffer-count-32 = []
|
||||||
|
rpl-relations-buffer-count-64 = []
|
||||||
|
rpl-relations-buffer-count-128 = []
|
||||||
|
|
||||||
# END AUTOGENERATED CONFIG FEATURES
|
# END AUTOGENERATED CONFIG FEATURES
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
|
1
build.rs
1
build.rs
@ -18,6 +18,7 @@ static CONFIGS: &[(&str, usize)] = &[
|
|||||||
("DNS_MAX_RESULT_COUNT", 1),
|
("DNS_MAX_RESULT_COUNT", 1),
|
||||||
("DNS_MAX_SERVER_COUNT", 1),
|
("DNS_MAX_SERVER_COUNT", 1),
|
||||||
("DNS_MAX_NAME_SIZE", 255),
|
("DNS_MAX_NAME_SIZE", 255),
|
||||||
|
("RPL_RELATIONS_BUFFER_COUNT", 16),
|
||||||
// END AUTOGENERATED CONFIG FEATURES
|
// END AUTOGENERATED CONFIG FEATURES
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ feature("reassembly_buffer_count", default=1, min=1, max=32, pow2=4)
|
|||||||
feature("dns_max_result_count", default=1, min=1, max=32, pow2=4)
|
feature("dns_max_result_count", default=1, min=1, max=32, pow2=4)
|
||||||
feature("dns_max_server_count", default=1, min=1, max=32, pow2=4)
|
feature("dns_max_server_count", default=1, min=1, max=32, pow2=4)
|
||||||
feature("dns_max_name_size", default=255, min=64, max=255, pow2=True)
|
feature("dns_max_name_size", default=255, min=64, max=255, pow2=True)
|
||||||
|
feature("rpl_relations_buffer_count", default=16, min=1, max=128, pow2=True)
|
||||||
|
|
||||||
# ========= Update Cargo.toml
|
# ========= Update Cargo.toml
|
||||||
|
|
||||||
|
@ -3,4 +3,5 @@
|
|||||||
mod consts;
|
mod consts;
|
||||||
mod lollipop;
|
mod lollipop;
|
||||||
mod rank;
|
mod rank;
|
||||||
|
mod relations;
|
||||||
mod trickle;
|
mod trickle;
|
||||||
|
162
src/iface/rpl/relations.rs
Normal file
162
src/iface/rpl/relations.rs
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
use crate::time::Instant;
|
||||||
|
use crate::wire::Ipv6Address;
|
||||||
|
|
||||||
|
use crate::config::RPL_RELATIONS_BUFFER_COUNT;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Relation {
|
||||||
|
destination: Ipv6Address,
|
||||||
|
next_hop: Ipv6Address,
|
||||||
|
expiration: Instant,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct Relations {
|
||||||
|
relations: heapless::Vec<Relation, { RPL_RELATIONS_BUFFER_COUNT }>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Relations {
|
||||||
|
/// Add a new relation to the buffer. If there was already a relation in the buffer, then
|
||||||
|
/// update it.
|
||||||
|
pub fn add_relation(
|
||||||
|
&mut self,
|
||||||
|
destination: Ipv6Address,
|
||||||
|
next_hop: Ipv6Address,
|
||||||
|
expiration: Instant,
|
||||||
|
) {
|
||||||
|
if let Some(r) = self
|
||||||
|
.relations
|
||||||
|
.iter_mut()
|
||||||
|
.find(|r| r.destination == destination)
|
||||||
|
{
|
||||||
|
r.next_hop = next_hop;
|
||||||
|
r.expiration = expiration;
|
||||||
|
} else {
|
||||||
|
let relation = Relation {
|
||||||
|
destination,
|
||||||
|
next_hop,
|
||||||
|
expiration,
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err(e) = self.relations.push(relation) {
|
||||||
|
net_debug!("Unable to add relation, buffer is full");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove all relation entries for a specific destination.
|
||||||
|
pub fn remove_relation(&mut self, destination: Ipv6Address) {
|
||||||
|
self.relations.retain(|r| r.destination != destination)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the next hop for a specific IPv6 address, if there is one.
|
||||||
|
pub fn find_next_hop(&mut self, destination: Ipv6Address) -> Option<Ipv6Address> {
|
||||||
|
self.relations.iter().find_map(|r| {
|
||||||
|
if r.destination == destination {
|
||||||
|
Some(r.next_hop)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Purge expired relations.
|
||||||
|
pub fn purge(&mut self, now: Instant) {
|
||||||
|
self.relations.retain(|r| r.expiration > now)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::time::Duration;
|
||||||
|
|
||||||
|
fn addresses(count: usize) -> Vec<Ipv6Address> {
|
||||||
|
(0..count)
|
||||||
|
.map(|i| {
|
||||||
|
let mut ip = Ipv6Address::default();
|
||||||
|
ip.0[0] = i as u8;
|
||||||
|
ip
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_relation() {
|
||||||
|
let addrs = addresses(2);
|
||||||
|
|
||||||
|
let mut relations = Relations::default();
|
||||||
|
relations.add_relation(addrs[0], addrs[1], Instant::now());
|
||||||
|
assert_eq!(relations.relations.len(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_relations_full_buffer() {
|
||||||
|
let addrs = addresses(crate::config::RPL_RELATIONS_BUFFER_COUNT + 1);
|
||||||
|
|
||||||
|
// Try to add RPL_RELATIONS_BUFFER_COUNT + 1 to the buffer.
|
||||||
|
// The size of the buffer should still be RPL_RELATIONS_BUFFER_COUNT.
|
||||||
|
let mut relations = Relations::default();
|
||||||
|
for a in addrs {
|
||||||
|
relations.add_relation(a, a, Instant::now());
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(relations.relations.len(), RPL_RELATIONS_BUFFER_COUNT);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn update_relation() {
|
||||||
|
let addrs = addresses(3);
|
||||||
|
|
||||||
|
let mut relations = Relations::default();
|
||||||
|
relations.add_relation(addrs[0], addrs[1], Instant::now());
|
||||||
|
assert_eq!(relations.relations.len(), 1);
|
||||||
|
|
||||||
|
relations.add_relation(addrs[0], addrs[2], Instant::now());
|
||||||
|
assert_eq!(relations.relations.len(), 1);
|
||||||
|
|
||||||
|
assert_eq!(relations.find_next_hop(addrs[0]), Some(addrs[2]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn find_next_hop() {
|
||||||
|
let addrs = addresses(3);
|
||||||
|
|
||||||
|
let mut relations = Relations::default();
|
||||||
|
relations.add_relation(addrs[0], addrs[1], Instant::now());
|
||||||
|
assert_eq!(relations.relations.len(), 1);
|
||||||
|
assert_eq!(relations.find_next_hop(addrs[0]), Some(addrs[1]));
|
||||||
|
|
||||||
|
relations.add_relation(addrs[0], addrs[2], Instant::now());
|
||||||
|
assert_eq!(relations.relations.len(), 1);
|
||||||
|
assert_eq!(relations.find_next_hop(addrs[0]), Some(addrs[2]));
|
||||||
|
|
||||||
|
// Find the next hop of a destination not in the buffer.
|
||||||
|
assert_eq!(relations.find_next_hop(addrs[1]), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn remove_relation() {
|
||||||
|
let addrs = addresses(2);
|
||||||
|
|
||||||
|
let mut relations = Relations::default();
|
||||||
|
relations.add_relation(addrs[0], addrs[1], Instant::now());
|
||||||
|
assert_eq!(relations.relations.len(), 1);
|
||||||
|
|
||||||
|
relations.remove_relation(addrs[0]);
|
||||||
|
assert!(relations.relations.is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn purge_relation() {
|
||||||
|
let addrs = addresses(2);
|
||||||
|
|
||||||
|
let mut relations = Relations::default();
|
||||||
|
relations.add_relation(addrs[0], addrs[1], Instant::now() - Duration::from_secs(1));
|
||||||
|
|
||||||
|
assert_eq!(relations.relations.len(), 1);
|
||||||
|
|
||||||
|
relations.purge(Instant::now());
|
||||||
|
assert!(relations.relations.is_empty());
|
||||||
|
}
|
||||||
|
}
|
@ -144,6 +144,7 @@ mod config {
|
|||||||
pub const IFACE_NEIGHBOR_CACHE_COUNT: usize = 3;
|
pub const IFACE_NEIGHBOR_CACHE_COUNT: usize = 3;
|
||||||
pub const REASSEMBLY_BUFFER_COUNT: usize = 4;
|
pub const REASSEMBLY_BUFFER_COUNT: usize = 4;
|
||||||
pub const REASSEMBLY_BUFFER_SIZE: usize = 1500;
|
pub const REASSEMBLY_BUFFER_SIZE: usize = 1500;
|
||||||
|
pub const RPL_RELATIONS_BUFFER_COUNT: usize = 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user