bridge: 5 unit tests for FDB learn/age/lookup
Bridge MAC learning tests: - learn_stores_unicast_mapping: stored MAC resolves on correct port - learn_ignores_multicast: broadcast/multicast never enters FDB - learn_replaces_existing_entry_on_new_port: MAC moves update port - age_entries_removes_expired_macs: 300s timeout respected - lookup_returns_none_for_unknown_mac: unknown MAC returns None Total tests across netstack: 20 (5 table + 4 conntrack + 6 nat + 5 bridge) All passing.
This commit is contained in:
@@ -259,4 +259,62 @@ impl LinkDevice for BridgeDevice {
|
||||
}
|
||||
out
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use smoltcp::wire::EthernetAddress;
|
||||
|
||||
fn mac(a: u8, b: u8, c: u8, d: u8, e: u8, f: u8) -> EthernetAddress {
|
||||
EthernetAddress([a, b, c, d, e, f])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn learn_stores_unicast_mapping() {
|
||||
let b = BridgeDevice::new("br0");
|
||||
let m = mac(0x00, 0x11, 0x22, 0x33, 0x44, 0x55);
|
||||
b.learn(m, 2, Instant::from_secs(0));
|
||||
assert_eq!(b.lookup(m), Some(2),
|
||||
"Learned MAC must be found on port 2");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn learn_ignores_multicast() {
|
||||
let b = BridgeDevice::new("br0");
|
||||
let multicast = EthernetAddress::BROADCAST;
|
||||
b.learn(multicast, 1, Instant::from_secs(0));
|
||||
assert_eq!(b.lookup(multicast), None,
|
||||
"Multicast MACs must not be learned");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn learn_replaces_existing_entry_on_new_port() {
|
||||
let b = BridgeDevice::new("br0");
|
||||
let m = mac(0x00, 0x11, 0x22, 0x33, 0x44, 0x55);
|
||||
b.learn(m, 1, Instant::from_secs(0));
|
||||
assert_eq!(b.lookup(m), Some(1));
|
||||
b.learn(m, 2, Instant::from_secs(10));
|
||||
assert_eq!(b.lookup(m), Some(2),
|
||||
"MAC move from port 1 to port 2 must update FDB");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn age_entries_removes_expired_macs() {
|
||||
let b = BridgeDevice::new("br0");
|
||||
let m1 = mac(0x00, 0x11, 0x22, 0x33, 0x44, 0x55);
|
||||
let m2 = mac(0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE);
|
||||
b.learn(m1, 1, Instant::from_secs(0));
|
||||
b.learn(m2, 2, Instant::from_secs(MAC_AGE_TIMEOUT.secs() as i64)); // Age boundary
|
||||
// Age just past the 300s timeout
|
||||
b.age_entries(Instant::from_secs(MAC_AGE_TIMEOUT.secs() as i64 + 1));
|
||||
assert_eq!(b.lookup(m1), None, "m1 (learned at 0) must be aged out");
|
||||
assert_eq!(b.lookup(m2), Some(2),
|
||||
"m2 (learned at 300s) must still be valid");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lookup_returns_none_for_unknown_mac() {
|
||||
let b = BridgeDevice::new("br0");
|
||||
assert_eq!(b.lookup(mac(0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01)), None);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user