fix: enter unreachable HBH Discard multicast addr

It was previously possible to enter an unreachable path when the HBH
option type was 0b11 and the destination address was multicast. This is
now fixed in the interface.

I also changed the way an HBH option type is parsed. The option type is
only 2 bits, meaning that we can't have an unknown state.
This commit is contained in:
Thibaut Vandervelden 2024-09-27 09:07:51 +02:00
parent a2b92ed6e8
commit d17d47b4c0
2 changed files with 40 additions and 19 deletions

View File

@ -288,12 +288,11 @@ impl InterfaceInner {
Ipv6OptionFailureType::DiscardSendAll => {
return HopByHopResponse::Discard(param_problem());
}
Ipv6OptionFailureType::DiscardSendUnicast
if !ipv6_repr.dst_addr.is_multicast() =>
{
return HopByHopResponse::Discard(param_problem());
Ipv6OptionFailureType::DiscardSendUnicast => {
if !ipv6_repr.dst_addr.is_multicast() {
return HopByHopResponse::Discard(param_problem());
}
}
_ => unreachable!(),
}
}
}

View File

@ -51,19 +51,42 @@ impl RouterAlert {
pub const DATA_LEN: u8 = 2;
}
enum_with_unknown! {
/// Action required when parsing the given IPv6 Extension
/// Header Option Type fails
pub enum FailureType(u8) {
/// Skip this option and continue processing the packet
Skip = 0b00000000,
/// Discard the containing packet
Discard = 0b01000000,
/// Discard the containing packet and notify the sender
DiscardSendAll = 0b10000000,
/// Discard the containing packet and only notify the sender
/// if the sender is a unicast address
DiscardSendUnicast = 0b11000000,
/// Action required when parsing the given IPv6 Extension
/// Header Option Type fails
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum FailureType {
/// Skip this option and continue processing the packet
Skip = 0b00000000,
/// Discard the containing packet
Discard = 0b01000000,
/// Discard the containing packet and notify the sender
DiscardSendAll = 0b10000000,
/// Discard the containing packet and only notify the sender
/// if the sender is a unicast address
DiscardSendUnicast = 0b11000000,
}
impl From<u8> for FailureType {
fn from(value: u8) -> FailureType {
match value & 0b11000000 {
0b00000000 => FailureType::Skip,
0b01000000 => FailureType::Discard,
0b10000000 => FailureType::DiscardSendAll,
0b11000000 => FailureType::DiscardSendUnicast,
_ => unreachable!(),
}
}
}
impl From<FailureType> for u8 {
fn from(value: FailureType) -> Self {
match value {
FailureType::Skip => 0b00000000,
FailureType::Discard => 0b01000000,
FailureType::DiscardSendAll => 0b10000000,
FailureType::DiscardSendUnicast => 0b11000000,
}
}
}
@ -74,7 +97,6 @@ impl fmt::Display for FailureType {
FailureType::Discard => write!(f, "discard"),
FailureType::DiscardSendAll => write!(f, "discard and send error"),
FailureType::DiscardSendUnicast => write!(f, "discard and send error if unicast"),
FailureType::Unknown(id) => write!(f, "Unknown({id})"),
}
}
}