Skip to content

Commit

Permalink
Merge pull request #966 from korken89/neighbor-cache-expiry-fix
Browse files Browse the repository at this point in the history
Reset expiry of entries in the neighbor cache on packet reception
  • Loading branch information
Dirbaio authored Aug 5, 2024
2 parents 53caf70 + 8e97c95 commit 8be46b9
Show file tree
Hide file tree
Showing 12 changed files with 105 additions and 10 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,11 @@ iface-max-sixlowpan-address-context-count-1024 = []
iface-neighbor-cache-count-1 = []
iface-neighbor-cache-count-2 = []
iface-neighbor-cache-count-3 = []
iface-neighbor-cache-count-4 = [] # Default
iface-neighbor-cache-count-4 = []
iface-neighbor-cache-count-5 = []
iface-neighbor-cache-count-6 = []
iface-neighbor-cache-count-7 = []
iface-neighbor-cache-count-8 = []
iface-neighbor-cache-count-8 = [] # Default
iface-neighbor-cache-count-16 = []
iface-neighbor-cache-count-32 = []
iface-neighbor-cache-count-64 = []
Expand Down
2 changes: 1 addition & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ static CONFIGS: &[(&str, usize)] = &[
("IFACE_MAX_ADDR_COUNT", 2),
("IFACE_MAX_MULTICAST_GROUP_COUNT", 4),
("IFACE_MAX_SIXLOWPAN_ADDRESS_CONTEXT_COUNT", 4),
("IFACE_NEIGHBOR_CACHE_COUNT", 4),
("IFACE_NEIGHBOR_CACHE_COUNT", 8),
("IFACE_MAX_ROUTE_COUNT", 2),
("FRAGMENTATION_BUFFER_SIZE", 1500),
("ASSEMBLER_MAX_SEGMENT_COUNT", 4),
Expand Down
2 changes: 1 addition & 1 deletion gen_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def feature(name, default, min, max, pow2=None):
feature("iface_max_addr_count", default=2, min=1, max=8)
feature("iface_max_multicast_group_count", default=4, min=1, max=1024, pow2=8)
feature("iface_max_sixlowpan_address_context_count", default=4, min=1, max=1024, pow2=8)
feature("iface_neighbor_cache_count", default=4, min=1, max=1024, pow2=8)
feature("iface_neighbor_cache_count", default=8, min=1, max=1024, pow2=8)
feature("iface_max_route_count", default=2, min=1, max=1024, pow2=8)
feature("fragmentation_buffer_size", default=1500, min=256, max=65536, pow2=True)
feature("assembler_max_segment_count", default=4, min=1, max=32, pow2=4)
Expand Down
12 changes: 9 additions & 3 deletions src/iface/interface/ethernet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,19 @@ impl InterfaceInner {
EthernetProtocol::Ipv4 => {
let ipv4_packet = check!(Ipv4Packet::new_checked(eth_frame.payload()));

self.process_ipv4(sockets, meta, &ipv4_packet, fragments)
.map(EthernetPacket::Ip)
self.process_ipv4(
sockets,
meta,
eth_frame.src_addr().into(),
&ipv4_packet,
fragments,
)
.map(EthernetPacket::Ip)
}
#[cfg(feature = "proto-ipv6")]
EthernetProtocol::Ipv6 => {
let ipv6_packet = check!(Ipv6Packet::new_checked(eth_frame.payload()));
self.process_ipv6(sockets, meta, &ipv6_packet)
self.process_ipv6(sockets, meta, eth_frame.src_addr().into(), &ipv6_packet)
.map(EthernetPacket::Ip)
}
// Drop all other traffic.
Expand Down
10 changes: 10 additions & 0 deletions src/iface/interface/ipv4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ impl InterfaceInner {
&mut self,
sockets: &mut SocketSet,
meta: PacketMeta,
source_hardware_addr: HardwareAddress,
ipv4_packet: &Ipv4Packet<&'a [u8]>,
frag: &'a mut FragmentsBuffer,
) -> Option<Packet<'a>> {
Expand Down Expand Up @@ -196,6 +197,15 @@ impl InterfaceInner {
}
}

#[cfg(feature = "medium-ethernet")]
if self.is_unicast_v4(ipv4_repr.dst_addr) {
self.neighbor_cache.reset_expiry_if_existing(
IpAddress::Ipv4(ipv4_repr.src_addr),
source_hardware_addr,
self.now,
);
}

match ipv4_repr.next_header {
IpProtocol::Icmp => self.process_icmpv4(sockets, ipv4_repr, ip_payload),

Expand Down
10 changes: 10 additions & 0 deletions src/iface/interface/ipv6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ impl InterfaceInner {
&mut self,
sockets: &mut SocketSet,
meta: PacketMeta,
source_hardware_addr: HardwareAddress,
ipv6_packet: &Ipv6Packet<&'frame [u8]>,
) -> Option<Packet<'frame>> {
let ipv6_repr = check!(Ipv6Repr::parse(ipv6_packet));
Expand Down Expand Up @@ -228,6 +229,15 @@ impl InterfaceInner {
#[cfg(not(feature = "socket-raw"))]
let handled_by_raw_socket = false;

#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
if ipv6_repr.dst_addr.is_unicast() {
self.neighbor_cache.reset_expiry_if_existing(
IpAddress::Ipv6(ipv6_repr.src_addr),
source_hardware_addr,
self.now,
);
}

self.process_nxt_hdr(
sockets,
meta,
Expand Down
4 changes: 2 additions & 2 deletions src/iface/interface/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -785,12 +785,12 @@ impl InterfaceInner {
Ok(IpVersion::Ipv4) => {
let ipv4_packet = check!(Ipv4Packet::new_checked(ip_payload));

self.process_ipv4(sockets, meta, &ipv4_packet, frag)
self.process_ipv4(sockets, meta, HardwareAddress::Ip, &ipv4_packet, frag)
}
#[cfg(feature = "proto-ipv6")]
Ok(IpVersion::Ipv6) => {
let ipv6_packet = check!(Ipv6Packet::new_checked(ip_payload));
self.process_ipv6(sockets, meta, &ipv6_packet)
self.process_ipv6(sockets, meta, HardwareAddress::Ip, &ipv6_packet)
}
// Drop all other traffic.
_ => None,
Expand Down
10 changes: 9 additions & 1 deletion src/iface/interface/sixlowpan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,15 @@ impl InterfaceInner {
}
};

self.process_ipv6(sockets, meta, &check!(Ipv6Packet::new_checked(payload)))
self.process_ipv6(
sockets,
meta,
match ieee802154_repr.src_addr {
Some(s) => HardwareAddress::Ieee802154(s),
None => HardwareAddress::Ieee802154(Ieee802154Address::Absent),
},
&check!(Ipv6Packet::new_checked(payload)),
)
}

#[cfg(feature = "proto-sixlowpan-fragmentation")]
Expand Down
5 changes: 5 additions & 0 deletions src/iface/interface/tests/ipv4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ fn test_no_icmp_no_unicast(#[case] medium: Medium) {
iface.inner.process_ipv4(
&mut sockets,
PacketMeta::default(),
HardwareAddress::default(),
&frame,
&mut iface.fragments
),
Expand Down Expand Up @@ -152,6 +153,7 @@ fn test_icmp_error_no_payload(#[case] medium: Medium) {
iface.inner.process_ipv4(
&mut sockets,
PacketMeta::default(),
HardwareAddress::default(),
&frame,
&mut iface.fragments
),
Expand Down Expand Up @@ -397,6 +399,7 @@ fn test_handle_ipv4_broadcast(#[case] medium: Medium) {
iface.inner.process_ipv4(
&mut sockets,
PacketMeta::default(),
HardwareAddress::default(),
&frame,
&mut iface.fragments
),
Expand Down Expand Up @@ -828,6 +831,7 @@ fn test_raw_socket_no_reply(#[case] medium: Medium) {
iface.inner.process_ipv4(
&mut sockets,
PacketMeta::default(),
HardwareAddress::default(),
&frame,
&mut iface.fragments
),
Expand Down Expand Up @@ -925,6 +929,7 @@ fn test_raw_socket_with_udp_socket(#[case] medium: Medium) {
iface.inner.process_ipv4(
&mut sockets,
PacketMeta::default(),
HardwareAddress::default(),
&frame,
&mut iface.fragments
),
Expand Down
15 changes: 15 additions & 0 deletions src/iface/interface/tests/ipv6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ fn any_ip(#[case] medium: Medium) {
iface.inner.process_ipv6(
&mut sockets,
PacketMeta::default(),
HardwareAddress::default(),
&Ipv6Packet::new_checked(&data[..]).unwrap()
),
None
Expand All @@ -98,6 +99,7 @@ fn any_ip(#[case] medium: Medium) {
.process_ipv6(
&mut sockets,
PacketMeta::default(),
HardwareAddress::default(),
&Ipv6Packet::new_checked(&data[..]).unwrap()
)
.is_some());
Expand Down Expand Up @@ -125,6 +127,7 @@ fn multicast_source_address(#[case] medium: Medium) {
iface.inner.process_ipv6(
&mut sockets,
PacketMeta::default(),
HardwareAddress::default(),
&Ipv6Packet::new_checked(&data[..]).unwrap()
),
response
Expand Down Expand Up @@ -173,6 +176,7 @@ fn hop_by_hop_skip_with_icmp(#[case] medium: Medium) {
iface.inner.process_ipv6(
&mut sockets,
PacketMeta::default(),
HardwareAddress::default(),
&Ipv6Packet::new_checked(&data[..]).unwrap()
),
response
Expand Down Expand Up @@ -208,6 +212,7 @@ fn hop_by_hop_discard_with_icmp(#[case] medium: Medium) {
iface.inner.process_ipv6(
&mut sockets,
PacketMeta::default(),
HardwareAddress::default(),
&Ipv6Packet::new_checked(&data[..]).unwrap()
),
response
Expand Down Expand Up @@ -262,6 +267,7 @@ fn hop_by_hop_discard_param_problem(#[case] medium: Medium) {
iface.inner.process_ipv6(
&mut sockets,
PacketMeta::default(),
HardwareAddress::default(),
&Ipv6Packet::new_checked(&data[..]).unwrap()
),
response
Expand Down Expand Up @@ -319,6 +325,7 @@ fn hop_by_hop_discard_with_multicast(#[case] medium: Medium) {
iface.inner.process_ipv6(
&mut sockets,
PacketMeta::default(),
HardwareAddress::default(),
&Ipv6Packet::new_checked(&data[..]).unwrap()
),
response
Expand Down Expand Up @@ -378,6 +385,7 @@ fn imcp_empty_echo_request(#[case] medium: Medium) {
iface.inner.process_ipv6(
&mut sockets,
PacketMeta::default(),
HardwareAddress::default(),
&Ipv6Packet::new_checked(&data[..]).unwrap()
),
response
Expand Down Expand Up @@ -438,6 +446,7 @@ fn icmp_echo_request(#[case] medium: Medium) {
iface.inner.process_ipv6(
&mut sockets,
PacketMeta::default(),
HardwareAddress::default(),
&Ipv6Packet::new_checked(&data[..]).unwrap()
),
response
Expand Down Expand Up @@ -485,6 +494,7 @@ fn icmp_echo_reply_as_input(#[case] medium: Medium) {
iface.inner.process_ipv6(
&mut sockets,
PacketMeta::default(),
HardwareAddress::default(),
&Ipv6Packet::new_checked(&data[..]).unwrap()
),
response
Expand Down Expand Up @@ -533,6 +543,7 @@ fn unknown_proto_with_multicast_dst_address(#[case] medium: Medium) {
iface.inner.process_ipv6(
&mut sockets,
PacketMeta::default(),
HardwareAddress::default(),
&Ipv6Packet::new_checked(&data[..]).unwrap()
),
response
Expand Down Expand Up @@ -582,6 +593,7 @@ fn unknown_proto(#[case] medium: Medium) {
iface.inner.process_ipv6(
&mut sockets,
PacketMeta::default(),
HardwareAddress::default(),
&Ipv6Packet::new_checked(&data[..]).unwrap()
),
response
Expand Down Expand Up @@ -626,6 +638,7 @@ fn ndsic_neighbor_advertisement_ethernet(#[case] medium: Medium) {
iface.inner.process_ipv6(
&mut sockets,
PacketMeta::default(),
HardwareAddress::default(),
&Ipv6Packet::new_checked(&data[..]).unwrap()
),
response
Expand Down Expand Up @@ -682,6 +695,7 @@ fn ndsic_neighbor_advertisement_ethernet_multicast_addr(#[case] medium: Medium)
iface.inner.process_ipv6(
&mut sockets,
PacketMeta::default(),
HardwareAddress::default(),
&Ipv6Packet::new_checked(&data[..]).unwrap()
),
response
Expand Down Expand Up @@ -734,6 +748,7 @@ fn ndsic_neighbor_advertisement_ieee802154(#[case] medium: Medium) {
iface.inner.process_ipv6(
&mut sockets,
PacketMeta::default(),
HardwareAddress::default(),
&Ipv6Packet::new_checked(&data[..]).unwrap()
),
response
Expand Down
17 changes: 17 additions & 0 deletions src/iface/neighbor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,23 @@ impl Cache {
}
}

pub fn reset_expiry_if_existing(
&mut self,
protocol_addr: IpAddress,
source_hardware_addr: HardwareAddress,
timestamp: Instant,
) {
if let Some(Neighbor {
expires_at,
hardware_addr,
}) = self.storage.get_mut(&protocol_addr)
{
if source_hardware_addr == *hardware_addr {
*expires_at = timestamp + Self::ENTRY_LIFETIME;
}
}
}

pub fn fill(
&mut self,
protocol_addr: IpAddress,
Expand Down
24 changes: 24 additions & 0 deletions src/wire/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,30 @@ pub enum HardwareAddress {
Ieee802154(Ieee802154Address),
}

#[cfg(any(
feature = "medium-ip",
feature = "medium-ethernet",
feature = "medium-ieee802154"
))]
#[cfg(test)]
impl Default for HardwareAddress {
fn default() -> Self {
#![allow(unreachable_code)]
#[cfg(feature = "medium-ethernet")]
{
return Self::Ethernet(EthernetAddress::default());
}
#[cfg(feature = "medium-ip")]
{
return Self::Ip;
}
#[cfg(feature = "medium-ieee802154")]
{
Self::Ieee802154(Ieee802154Address::default())
}
}
}

#[cfg(any(
feature = "medium-ip",
feature = "medium-ethernet",
Expand Down

0 comments on commit 8be46b9

Please sign in to comment.