-
Notifications
You must be signed in to change notification settings - Fork 433
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Eviction of entries from owned neighbor cache #83
Comments
hi @whitequark! I'm new here and v. interested in contributing to this library! I want to confirm what needs to happen here before diving in: It looks like in the case where the neighbor cache is not using heap-allocated storage that there is already logic in place to evict old entries: // src/iface/neighbor.rs:94
Err((protocol_addr, neighbor)) => {
// If we're going down this branch, it means that a fixed-size cache storage
// is full, and we need to evict an entry.
let old_protocol_addr = match self.storage {
ManagedMap::Borrowed(ref mut pairs) => {
pairs
.iter()
.min_by_key(|pair_opt| {
let (_protocol_addr, neighbor) = pair_opt.unwrap();
neighbor.expires_at
})
.expect("empty neighbor cache storage") // unwraps min_by_key
.unwrap() // unwraps pair
.0
}
// Owned maps can extend themselves.
#[cfg(any(feature = "std", feature = "alloc"))]
ManagedMap::Owned(_) => unreachable!()
};
let _old_neighbor =
self.storage.remove(&old_protocol_addr).unwrap();
match self.storage.insert(protocol_addr, neighbor) {
Ok(None) => {
net_trace!("filled {} => {} (evicted {} => {})",
protocol_addr, hardware_addr,
old_protocol_addr, _old_neighbor.hardware_addr);
}
// We've covered everything else above.
_ => unreachable!()
}
} is the task here to repeat this logic for the heap-allocated case?
Thanks a lot for any guidance & for building this awesome library--I'm excited to dive in! |
Hi @squidarth! The challenge here, first and foremost, in figuring out what logic exactly should be followed here. I didn't really have much time to put into this issue myself. Do you think you could look at other TCP/IP stacks and see what sort of logic they use for the neighbor table? |
Yep--sounds good |
@squidarth You might also check out the NDISC RFC. It has some good info about the Neighbor Cache. I can't remember if it says anything about evicting entries from the cache though. |
Alright, so today I spent some time digging into how Linux handles cache eviction: My takeaway: I think we can simply add automatic garbage collection in the How the Linux Kernel handles cache evictionFirst off, the kernel keeps a lot more state on entries in the ARP translation table does. It refers to items in the table as "neighbors", which go through a state machine (defined here), where they start out as There is another function Garbage collection is also triggered when allocating new neighbors if the number of entries in the table is above some constant value. On linux, these constants live at:
More thoughtsI don't think there's a huge need to redo how the ARP table is managed in smoltcp to adapt to having multiple states, and also think that an approach that uses another thread to garbage collect in the background would add a lot of complexity (we would have to move the Re: the constants that linux provides, we probably want to allow users to supply these, but can use similar defaults. Let me know what you think! |
No threads--all functionality should be available either with core or with core+alloc. Otherwise, sounds great. |
I agree with @whitequark, this sounds great!
The states mentioned above are the states of an entry in the Neighbor Cache required by NDISC that are required by Neighbor Unreachability Detection (NUD). So we will eventually need to add this state to the cache in order to be compliant with the RFC. I have a bullet in the issue #103 for this, but it should probably be its own issue. |
Right now the neighbor cache will simply grow for as long as it can when unseen before IPs are added. This can potentially take a lot of memory if we're talking about a /8 network that someone runs an ARP scan against. We should probably do something about it.
The text was updated successfully, but these errors were encountered: