mirror of
https://github.com/threefoldtech/mycelium.git
synced 2026-03-29 07:39:51 +00:00
Fix #614: Properly reply to local packets for local subnet
Previously packets for the local subnet would trigger a route lookup, which leads to a no-route entry being generated. Instead, reply to such packets with an ICMP host unreachable - address uncreachable. This can be done unilaterally since IF the address would exist on the host, the packet would not be pushed to the TUN interface by the kernel and thus, by extension, if such a packet is handled by mycelium, it means there is no address or local subnet configuration. Signed-off-by: Lee Smet <lee.smet@hotmail.com>
This commit is contained in:
@@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Fixed an unsoundness issue in the routing table clone implementation.
|
||||
- Clear dead peer buffer once peers have been removed from the routing table.
|
||||
- Properly reply with an address unreachable ICMP when pinging an IP in the local
|
||||
subnet which does not exist.
|
||||
|
||||
## [0.6.0] - 2025-04-25
|
||||
|
||||
|
||||
@@ -102,6 +102,8 @@ where
|
||||
T: Sink<PacketBuffer> + Clone + Send + Unpin + 'static,
|
||||
T::Error: std::fmt::Display,
|
||||
{
|
||||
let node_subnet = self.router.node_tun_subnet();
|
||||
|
||||
while let Some(packet) = l3_packet_stream.next().await {
|
||||
let mut packet = match packet {
|
||||
Err(e) => {
|
||||
@@ -146,6 +148,31 @@ where
|
||||
.expect("Static range bounds on slice are correct length"),
|
||||
);
|
||||
|
||||
// If this is a packet for our own Subnet, it means there is no local configuration for
|
||||
// the destination ip or /64 subnet, and the IP is unreachable
|
||||
if node_subnet.contains_ip(dst_ip.into()) {
|
||||
trace!(
|
||||
"Replying to local packet for unexisting address: {}",
|
||||
dst_ip
|
||||
);
|
||||
|
||||
let mut icmp_packet = PacketBuffer::new();
|
||||
let host = self.router.node_public_key().address().octets();
|
||||
let icmp = PacketBuilder::ipv6(host, src_ip.octets(), 64).icmpv6(
|
||||
Icmpv6Type::DestinationUnreachable(DestUnreachableCode::Address),
|
||||
);
|
||||
icmp_packet.set_size(icmp.size(packet.len().min(1280 - 48)));
|
||||
let mut writer = &mut icmp_packet.buffer_mut()[..];
|
||||
if let Err(e) = icmp.write(&mut writer, &packet[..packet.len().min(1280 - 48)]) {
|
||||
error!("Failed to construct ICMP packet: {e}");
|
||||
continue;
|
||||
}
|
||||
if let Err(e) = l3_packet_sink.send(icmp_packet).await {
|
||||
error!("Failed to send ICMP packet to host: {e}");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
trace!("Received packet from TUN with dest addr: {:?}", dst_ip);
|
||||
// Check if the source address is part of 400::/7
|
||||
let first_src_byte = src_ip.segments()[0] >> 8;
|
||||
|
||||
Reference in New Issue
Block a user