Skip to content

Commit aad6df2

Browse files
committed
link vxlan: Add IFLA_VXLAN_MC_ROUTE support and test
Added InfoVxlan::McRoute(bool) variant for IFLA_VXLAN_MC_ROUTE attribute and a round-trip test for creating a vxlan with mcroute. Signed-off-by: Gris Ge <cnfourt@gmail.com>
1 parent e7ee5bc commit aad6df2

2 files changed

Lines changed: 65 additions & 2 deletions

File tree

src/link/link_info/vxlan.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const IFLA_VXLAN_VNIFILTER: u16 = 30;
4040
const IFLA_VXLAN_LOCALBYPASS: u16 = 31;
4141
const IFLA_VXLAN_LABEL_POLICY: u16 = 32;
4242
const IFLA_VXLAN_RESERVED_BITS: u16 = 33;
43+
const IFLA_VXLAN_MC_ROUTE: u16 = 34;
4344

4445
#[derive(Debug, PartialEq, Eq, Clone)]
4546
#[non_exhaustive]
@@ -82,6 +83,7 @@ pub enum InfoVxlan {
8283
/// reject(drop and count as error) the VxLAN packet with that reserved
8384
/// bits set to 1.
8485
ReservedBits(u64),
86+
McRoute(bool),
8587
Other(DefaultNla),
8688
}
8789

@@ -104,7 +106,8 @@ impl Nla for InfoVxlan {
104106
| Self::TtlInherit(_)
105107
| Self::Df(_)
106108
| Self::Vnifilter(_)
107-
| Self::Localbypass(_) => 1,
109+
| Self::Localbypass(_)
110+
| Self::McRoute(_) => 1,
108111
Self::Gbp(_) | Self::Gpe(_) | Self::RemCsumNoPartial(_) => 0,
109112
Self::Port(_) => 2,
110113
Self::Id(_)
@@ -149,7 +152,8 @@ impl Nla for InfoVxlan {
149152
| Self::UDPZeroCsumRX(value)
150153
| Self::RemCsumTX(value)
151154
| Self::RemCsumRX(value)
152-
| Self::TtlInherit(value) => buffer[0] = *value as u8,
155+
| Self::TtlInherit(value)
156+
| Self::McRoute(value) => buffer[0] = *value as u8,
153157
Self::Group(value) | Self::Local(value) => {
154158
buffer.copy_from_slice(&value.octets())
155159
}
@@ -201,6 +205,7 @@ impl Nla for InfoVxlan {
201205
Self::Localbypass(_) => IFLA_VXLAN_LOCALBYPASS,
202206
Self::LabelPolicy(_) => IFLA_VXLAN_LABEL_POLICY,
203207
Self::ReservedBits(_) => IFLA_VXLAN_RESERVED_BITS,
208+
Self::McRoute(_) => IFLA_VXLAN_MC_ROUTE,
204209
Self::Other(nla) => nla.kind(),
205210
}
206211
}
@@ -372,6 +377,11 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoVxlan {
372377
parse_u64_be(payload)
373378
.context("invalid IFLA_VXLAN_RESERVED_BITS value")?,
374379
),
380+
IFLA_VXLAN_MC_ROUTE => Self::McRoute(
381+
parse_u8(payload)
382+
.context("invalid IFLA_VXLAN_MC_ROUTE value")?
383+
> 0,
384+
),
375385
unknown_kind => {
376386
Self::Other(DefaultNla::parse(buf).context(format!(
377387
"Failed to parse IFLA_INFO_DATA(vxlan) NLA type: \

src/link/tests/vxlan.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,3 +446,56 @@ fn test_parsing_link_vxlan_ipv6() {
446446

447447
assert_eq!(buf, raw);
448448
}
449+
450+
// nlmon capture of netlink packet(netlink header removed) generated by command:
451+
// sudo ip link add vxlan0 type \
452+
// vxlan id 100 remote 192.0.2.1 dstport 10240 \
453+
// ttl 16 mcroute
454+
#[test]
455+
fn test_create_vxlan_with_mcroute() {
456+
let raw = vec![
457+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
458+
0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x76, 0x78, 0x6c, 0x61,
459+
0x6e, 0x30, 0x00, 0x00, 0x44, 0x00, 0x12, 0x00, 0x0a, 0x00, 0x01, 0x00,
460+
0x76, 0x78, 0x6c, 0x61, 0x6e, 0x00, 0x00, 0x00, 0x34, 0x00, 0x02, 0x00,
461+
0x05, 0x00, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x22, 0x00,
462+
0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x64, 0x00, 0x00, 0x00,
463+
0x08, 0x00, 0x02, 0x00, 0xc0, 0x00, 0x02, 0x01, 0x05, 0x00, 0x07, 0x00,
464+
0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x0f, 0x00, 0x28, 0x00, 0x00, 0x00,
465+
];
466+
467+
let expected = LinkMessage {
468+
header: LinkHeader {
469+
interface_family: AddressFamily::Unspec,
470+
index: 0,
471+
link_layer_type: LinkLayerType::Netrom,
472+
flags: LinkFlags::empty(),
473+
change_mask: LinkFlags::empty(),
474+
},
475+
attributes: vec![
476+
LinkAttribute::IfName("vxlan0".into()),
477+
LinkAttribute::LinkInfo(vec![
478+
LinkInfo::Kind(InfoKind::Vxlan),
479+
LinkInfo::Data(InfoData::Vxlan(vec![
480+
InfoVxlan::Ttl(16),
481+
InfoVxlan::McRoute(true),
482+
InfoVxlan::Id(100),
483+
InfoVxlan::Group(Ipv4Addr::from_str("192.0.2.1").unwrap()),
484+
InfoVxlan::Learning(true),
485+
InfoVxlan::Port(10240),
486+
])),
487+
]),
488+
],
489+
};
490+
491+
assert_eq!(
492+
expected,
493+
LinkMessage::parse(&LinkMessageBuffer::new(&raw)).unwrap()
494+
);
495+
496+
let mut buf = vec![0; expected.buffer_len()];
497+
498+
expected.emit(&mut buf);
499+
500+
assert_eq!(buf, raw);
501+
}

0 commit comments

Comments
 (0)