From f86f418c941208efe30458647e4fdb5c1854994a Mon Sep 17 00:00:00 2001 From: Gris Ge Date: Fri, 18 Mar 2022 13:34:02 +0800 Subject: [PATCH] bridge: Fix decode error on bridge with IFLA_BR_MCAST_QUERIER_STATE With kernel supporting `IFLA_BR_MCAST_QUERIER_STATE`, we got error: Decode error occurred: Failed to parse message with type 16 After painfull debug, this is caused by IFLA_BRIDGE_FLAGS holding the same value as `IFLA_BR_MCAST_QUERIER_STATE` and expecting the payload been a u16. This is incorrect: * `IFLA_BRIDGE_FLAGS` is 0, and for `IFLA_AF_SPEC`, not `IFLA_LINKINFO`. * `IFLA_BR_MCAST_QUERIER_STATE` is a nested netlink attribute, not u16 which cause this failure. I have no project needing the support `IFLA_BR_MCAST_QUERIER_STATE` of it yet, so this patch just remove `IFLA_BRIDGE_FLAGS`, `IFLA_BRIDGE_VLAN_INFO`, and their associates. Also reordering the order of parsing `IFLA_LINKINFO` for bridge, to match the numeric order. So the developer could easily compare it to `/usr/include/linux/if_link.h`. Signed-off-by: Gris Ge --- netlink-packet-route/src/rtnl/constants.rs | 21 +-- .../src/rtnl/link/nlas/link_infos.rs | 124 ++++++++---------- 2 files changed, 66 insertions(+), 79 deletions(-) diff --git a/netlink-packet-route/src/rtnl/constants.rs b/netlink-packet-route/src/rtnl/constants.rs index 789068c5..8b0b5989 100644 --- a/netlink-packet-route/src/rtnl/constants.rs +++ b/netlink-packet-route/src/rtnl/constants.rs @@ -395,16 +395,16 @@ pub const IFLA_INFO_XSTATS: u16 = 3; pub const IFLA_INFO_SLAVE_KIND: u16 = 4; pub const IFLA_INFO_SLAVE_DATA: u16 = 5; // Bridge flags -pub const IFLA_BRIDGE_FLAGS: u16 = 47; -pub const BRIDGE_FLAGS_MASTER: u16 = 1; /* Bridge command to/from master */ -pub const BRIDGE_FLAGS_SELF: u16 = 2; /* Bridge command to/from lowerdev */ - -pub const IFLA_BRIDGE_VLAN_INFO: u16 = 48; -pub const BRIDGE_VLAN_INFO_MASTER: u16 = 1; -pub const BRIDGE_VLAN_INFO_PVID: u16 = 4; -pub const BRIDGE_VLAN_INFO_UNTAGGED: u16 = 8; -pub const BRIDGE_VLAN_INFO_RANGE_BEGIN: u16 = 16; -pub const BRIDGE_VLAN_INFO_RANGE_END: u16 = 32; +// pub const IFLA_BRIDGE_FLAGS: u16 = 0; +// pub const BRIDGE_FLAGS_MASTER: u16 = 1; /* Bridge command to/from master */ +// pub const BRIDGE_FLAGS_SELF: u16 = 2; /* Bridge command to/from lowerdev */ +// +// pub const IFLA_BRIDGE_VLAN_INFO: u16 = 2; +// pub const BRIDGE_VLAN_INFO_MASTER: u16 = 1; +// pub const BRIDGE_VLAN_INFO_PVID: u16 = 4; +// pub const BRIDGE_VLAN_INFO_UNTAGGED: u16 = 8; +// pub const BRIDGE_VLAN_INFO_RANGE_BEGIN: u16 = 16; +// pub const BRIDGE_VLAN_INFO_RANGE_END: u16 = 32; pub const IFLA_BR_UNSPEC: u16 = 0; pub const IFLA_BR_FORWARD_DELAY: u16 = 1; @@ -453,6 +453,7 @@ pub const IFLA_BR_MCAST_IGMP_VERSION: u16 = 43; pub const IFLA_BR_MCAST_MLD_VERSION: u16 = 44; pub const IFLA_BR_VLAN_STATS_PER_PORT: u16 = 45; pub const IFLA_BR_MULTI_BOOLOPT: u16 = 46; +// pub const IFLA_BR_MCAST_QUERIER_STATE: u16 = 47; pub const IFLA_MACVLAN_UNSPEC: u16 = 0; pub const IFLA_MACVLAN_MODE: u16 = 1; pub const IFLA_MACVLAN_FLAGS: u16 = 2; diff --git a/netlink-packet-route/src/rtnl/link/nlas/link_infos.rs b/netlink-packet-route/src/rtnl/link/nlas/link_infos.rs index a3a0f4cc..b743f4c3 100644 --- a/netlink-packet-route/src/rtnl/link/nlas/link_infos.rs +++ b/netlink-packet-route/src/rtnl/link/nlas/link_infos.rs @@ -805,7 +805,6 @@ pub enum InfoBridge { // FIXME: what type is this? putting Vec for now but it might // be a boolean actually FdbFlush(Vec), - Flags(u16), Pad(Vec), HelloTimer(u64), TcnTimer(u64), @@ -835,7 +834,6 @@ pub enum InfoBridge { RootPort(u16), VlanDefaultPvid(u16), VlanFiltering(u8), - VlanInfo(u16), TopologyChange(u8), TopologyChangeDetected(u8), MulticastRouter(u8), @@ -886,12 +884,10 @@ impl Nla for InfoBridge { | RootPathCost(_) => 4, Priority(_) - | VlanInfo(_) | VlanProtocol(_) | GroupFwdMask(_) | RootPort(_) | VlanDefaultPvid(_) - | Flags(_) => 2, RootId(_) @@ -926,8 +922,6 @@ impl Nla for InfoBridge { fn emit_value(&self, buffer: &mut [u8]) { use self::InfoBridge::*; match self { - Flags(value) => NativeEndian::write_u16(buffer, *value), - VlanInfo(value) => NativeEndian::write_u16(buffer, *value), Unspec(ref bytes) | FdbFlush(ref bytes) | Pad(ref bytes) @@ -1004,7 +998,6 @@ impl Nla for InfoBridge { Unspec(_) => IFLA_BR_UNSPEC, GroupAddr(_) => IFLA_BR_GROUP_ADDR, FdbFlush(_) => IFLA_BR_FDB_FLUSH, - Flags(_) => IFLA_BRIDGE_FLAGS, Pad(_) => IFLA_BR_PAD, HelloTimer(_) => IFLA_BR_HELLO_TIMER, TcnTimer(_) => IFLA_BR_TCN_TIMER, @@ -1034,7 +1027,6 @@ impl Nla for InfoBridge { RootPort(_) => IFLA_BR_ROOT_PORT, VlanDefaultPvid(_) => IFLA_BR_VLAN_DEFAULT_PVID, VlanFiltering(_) => IFLA_BR_VLAN_FILTERING, - VlanInfo(_) => IFLA_BRIDGE_VLAN_INFO, TopologyChange(_) => IFLA_BR_TOPOLOGY_CHANGE, TopologyChangeDetected(_) => IFLA_BR_TOPOLOGY_CHANGE_DETECTED, MulticastRouter(_) => IFLA_BR_MCAST_ROUTER, @@ -1061,44 +1053,6 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoBridge { let payload = buf.value(); Ok(match buf.kind() { IFLA_BR_UNSPEC => Unspec(payload.to_vec()), - IFLA_BR_FDB_FLUSH => FdbFlush(payload.to_vec()), - IFLA_BR_PAD => Pad(payload.to_vec()), - IFLA_BR_HELLO_TIMER => { - HelloTimer(parse_u64(payload).context("invalid IFLA_BR_HELLO_TIMER value")?) - } - IFLA_BRIDGE_VLAN_INFO => { - VlanInfo(parse_u16(payload).context("invalid IFLA_BRIDGE_VLAN_INFO value")?) - } - IFLA_BR_TCN_TIMER => { - TcnTimer(parse_u64(payload).context("invalid IFLA_BR_TCN_TIMER value")?) - } - IFLA_BRIDGE_FLAGS => { - Flags(parse_u16(payload).context("invalid IFLA_BRIDGE_FLAGS value")?) - } - IFLA_BR_TOPOLOGY_CHANGE_TIMER => TopologyChangeTimer( - parse_u64(payload).context("invalid IFLA_BR_TOPOLOGY_CHANGE_TIMER value")?, - ), - IFLA_BR_GC_TIMER => { - GcTimer(parse_u64(payload).context("invalid IFLA_BR_GC_TIMER value")?) - } - IFLA_BR_MCAST_LAST_MEMBER_INTVL => MulticastLastMemberInterval( - parse_u64(payload).context("invalid IFLA_BR_MCAST_LAST_MEMBER_INTVL value")?, - ), - IFLA_BR_MCAST_MEMBERSHIP_INTVL => MulticastMembershipInterval( - parse_u64(payload).context("invalid IFLA_BR_MCAST_MEMBERSHIP_INTVL value")?, - ), - IFLA_BR_MCAST_QUERIER_INTVL => MulticastQuerierInterval( - parse_u64(payload).context("invalid IFLA_BR_MCAST_QUERIER_INTVL value")?, - ), - IFLA_BR_MCAST_QUERY_INTVL => MulticastQueryInterval( - parse_u64(payload).context("invalid IFLA_BR_MCAST_QUERY_INTVL value")?, - ), - IFLA_BR_MCAST_QUERY_RESPONSE_INTVL => MulticastQueryResponseInterval( - parse_u64(payload).context("invalid IFLA_BR_MCAST_QUERY_RESPONSE_INTVL value")?, - ), - IFLA_BR_MCAST_STARTUP_QUERY_INTVL => MulticastStartupQueryInterval( - parse_u64(payload).context("invalid IFLA_BR_MCAST_STARTUP_QUERY_INTVL value")?, - ), IFLA_BR_FORWARD_DELAY => { ForwardDelay(parse_u32(payload).context("invalid IFLA_BR_FORWARD_DELAY value")?) } @@ -1112,24 +1066,12 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoBridge { IFLA_BR_STP_STATE => { StpState(parse_u32(payload).context("invalid IFLA_BR_STP_STATE value")?) } - IFLA_BR_MCAST_HASH_ELASTICITY => MulticastHashElasticity( - parse_u32(payload).context("invalid IFLA_BR_MCAST_HASH_ELASTICITY value")?, - ), - IFLA_BR_MCAST_HASH_MAX => MulticastHashMax( - parse_u32(payload).context("invalid IFLA_BR_MCAST_HASH_MAX value")?, - ), - IFLA_BR_MCAST_LAST_MEMBER_CNT => MulticastLastMemberCount( - parse_u32(payload).context("invalid IFLA_BR_MCAST_LAST_MEMBER_CNT value")?, - ), - IFLA_BR_MCAST_STARTUP_QUERY_CNT => MulticastStartupQueryCount( - parse_u32(payload).context("invalid IFLA_BR_MCAST_STARTUP_QUERY_CNT value")?, - ), - IFLA_BR_ROOT_PATH_COST => { - RootPathCost(parse_u32(payload).context("invalid IFLA_BR_ROOT_PATH_COST value")?) - } IFLA_BR_PRIORITY => { Priority(parse_u16(payload).context("invalid IFLA_BR_PRIORITY value")?) } + IFLA_BR_VLAN_FILTERING => { + VlanFiltering(parse_u8(payload).context("invalid IFLA_BR_VLAN_FILTERING value")?) + } IFLA_BR_VLAN_PROTOCOL => { VlanProtocol(parse_u16_be(payload).context("invalid IFLA_BR_VLAN_PROTOCOL value")?) } @@ -1151,17 +1093,11 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoBridge { _ => unreachable!(), } } - IFLA_BR_GROUP_ADDR => { - GroupAddr(parse_mac(payload).context("invalid IFLA_BR_GROUP_ADDR value")?) - } IFLA_BR_ROOT_PORT => { RootPort(parse_u16(payload).context("invalid IFLA_BR_ROOT_PORT value")?) } - IFLA_BR_VLAN_DEFAULT_PVID => VlanDefaultPvid( - parse_u16(payload).context("invalid IFLA_BR_VLAN_DEFAULT_PVID value")?, - ), - IFLA_BR_VLAN_FILTERING => { - VlanFiltering(parse_u8(payload).context("invalid IFLA_BR_VLAN_FILTERING value")?) + IFLA_BR_ROOT_PATH_COST => { + RootPathCost(parse_u32(payload).context("invalid IFLA_BR_ROOT_PATH_COST value")?) } IFLA_BR_TOPOLOGY_CHANGE => { TopologyChange(parse_u8(payload).context("invalid IFLA_BR_TOPOLOGY_CHANGE value")?) @@ -1169,6 +1105,22 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoBridge { IFLA_BR_TOPOLOGY_CHANGE_DETECTED => TopologyChangeDetected( parse_u8(payload).context("invalid IFLA_BR_TOPOLOGY_CHANGE_DETECTED value")?, ), + IFLA_BR_HELLO_TIMER => { + HelloTimer(parse_u64(payload).context("invalid IFLA_BR_HELLO_TIMER value")?) + } + IFLA_BR_TCN_TIMER => { + TcnTimer(parse_u64(payload).context("invalid IFLA_BR_TCN_TIMER value")?) + } + IFLA_BR_TOPOLOGY_CHANGE_TIMER => TopologyChangeTimer( + parse_u64(payload).context("invalid IFLA_BR_TOPOLOGY_CHANGE_TIMER value")?, + ), + IFLA_BR_GC_TIMER => { + GcTimer(parse_u64(payload).context("invalid IFLA_BR_GC_TIMER value")?) + } + IFLA_BR_GROUP_ADDR => { + GroupAddr(parse_mac(payload).context("invalid IFLA_BR_GROUP_ADDR value")?) + } + IFLA_BR_FDB_FLUSH => FdbFlush(payload.to_vec()), IFLA_BR_MCAST_ROUTER => { MulticastRouter(parse_u8(payload).context("invalid IFLA_BR_MCAST_ROUTER value")?) } @@ -1181,6 +1133,36 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoBridge { IFLA_BR_MCAST_QUERIER => { MulticastQuerier(parse_u8(payload).context("invalid IFLA_BR_MCAST_QUERIER value")?) } + IFLA_BR_MCAST_HASH_ELASTICITY => MulticastHashElasticity( + parse_u32(payload).context("invalid IFLA_BR_MCAST_HASH_ELASTICITY value")?, + ), + IFLA_BR_MCAST_HASH_MAX => MulticastHashMax( + parse_u32(payload).context("invalid IFLA_BR_MCAST_HASH_MAX value")?, + ), + IFLA_BR_MCAST_LAST_MEMBER_CNT => MulticastLastMemberCount( + parse_u32(payload).context("invalid IFLA_BR_MCAST_LAST_MEMBER_CNT value")?, + ), + IFLA_BR_MCAST_STARTUP_QUERY_CNT => MulticastStartupQueryCount( + parse_u32(payload).context("invalid IFLA_BR_MCAST_STARTUP_QUERY_CNT value")?, + ), + IFLA_BR_MCAST_LAST_MEMBER_INTVL => MulticastLastMemberInterval( + parse_u64(payload).context("invalid IFLA_BR_MCAST_LAST_MEMBER_INTVL value")?, + ), + IFLA_BR_MCAST_MEMBERSHIP_INTVL => MulticastMembershipInterval( + parse_u64(payload).context("invalid IFLA_BR_MCAST_MEMBERSHIP_INTVL value")?, + ), + IFLA_BR_MCAST_QUERIER_INTVL => MulticastQuerierInterval( + parse_u64(payload).context("invalid IFLA_BR_MCAST_QUERIER_INTVL value")?, + ), + IFLA_BR_MCAST_QUERY_INTVL => MulticastQueryInterval( + parse_u64(payload).context("invalid IFLA_BR_MCAST_QUERY_INTVL value")?, + ), + IFLA_BR_MCAST_QUERY_RESPONSE_INTVL => MulticastQueryResponseInterval( + parse_u64(payload).context("invalid IFLA_BR_MCAST_QUERY_RESPONSE_INTVL value")?, + ), + IFLA_BR_MCAST_STARTUP_QUERY_INTVL => MulticastStartupQueryInterval( + parse_u64(payload).context("invalid IFLA_BR_MCAST_STARTUP_QUERY_INTVL value")?, + ), IFLA_BR_NF_CALL_IPTABLES => { NfCallIpTables(parse_u8(payload).context("invalid IFLA_BR_NF_CALL_IPTABLES value")?) } @@ -1190,6 +1172,10 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoBridge { IFLA_BR_NF_CALL_ARPTABLES => NfCallArpTables( parse_u8(payload).context("invalid IFLA_BR_NF_CALL_ARPTABLES value")?, ), + IFLA_BR_VLAN_DEFAULT_PVID => VlanDefaultPvid( + parse_u16(payload).context("invalid IFLA_BR_VLAN_DEFAULT_PVID value")?, + ), + IFLA_BR_PAD => Pad(payload.to_vec()), IFLA_BR_VLAN_STATS_ENABLED => VlanStatsEnabled( parse_u8(payload).context("invalid IFLA_BR_VLAN_STATS_ENABLED value")?, ),