From e4e78f0be9f4218b18c28b47cea48859f548517c Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Wed, 24 May 2023 16:26:00 +0200 Subject: [PATCH] macvlan: add bclim option Expose the netlink IFLA_MACVLAN_BC_CUTOFF option as bclim like the ip command does. We still need c/common and podman patches to allow this option for podman network create. Also I created a PR[1] upstream in the netlink lib to allow setting these options directly instead of using the DefaultNla work around as I do here. TODO: Add a test but for now this option is not in a released version of iproute so there is no way to check for it right now. [1] https://github.com/rust-netlink/netlink-packet-route/pull/32 This is needed for https://bugzilla.redhat.com/show_bug.cgi?id=2183896 Signed-off-by: Paul Holzinger --- Cargo.lock | 1 + Cargo.toml | 1 + src/network/constants.rs | 1 + src/network/vlan.rs | 45 +++++++++++++++++++++++++++++++--------- 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7183197fe..5ef3321da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1219,6 +1219,7 @@ dependencies = [ "mozim", "netlink-packet-core", "netlink-packet-route", + "netlink-packet-utils", "netlink-sys", "nispor", "nix 0.26.2", diff --git a/Cargo.toml b/Cargo.toml index 959f8c065..2c6a7c57e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,6 +49,7 @@ zbus = { version = "3.12.0" } nix = "0.26.2" rand = "0.8.5" sha2 = "0.10.6" +netlink-packet-utils = "0.5" netlink-packet-route = "0.15" netlink-packet-core = "0.5" fs2 = "0.4.3" diff --git a/src/network/constants.rs b/src/network/constants.rs index cd7a1ced1..9e5e51ed4 100644 --- a/src/network/constants.rs +++ b/src/network/constants.rs @@ -17,6 +17,7 @@ pub const OPTION_MTU: &str = "mtu"; pub const OPTION_MODE: &str = "mode"; pub const OPTION_METRIC: &str = "metric"; pub const OPTION_NO_DEFAULT_ROUTE: &str = "no_default_route"; +pub const OPTION_BCLIM: &str = "bclim"; /// 100 is the default metric for most Linux networking tools. pub const DEFAULT_METRIC: u32 = 100; diff --git a/src/network/vlan.rs b/src/network/vlan.rs index 48347a7f7..acaa6fb04 100644 --- a/src/network/vlan.rs +++ b/src/network/vlan.rs @@ -2,6 +2,7 @@ use log::{debug, error}; use std::{collections::HashMap, net::IpAddr, os::unix::prelude::RawFd}; use netlink_packet_route::nlas::link::{InfoData, InfoIpVlan, InfoKind, InfoMacVlan, Nla}; +use netlink_packet_utils::nla::DefaultNla; use rand::distributions::{Alphanumeric, DistString}; use crate::network::macvlan_dhcp::{get_dhcp_lease, release_dhcp_lease}; @@ -14,7 +15,7 @@ use crate::{ use super::{ constants::{ - NO_CONTAINER_INTERFACE_ERROR, OPTION_METRIC, OPTION_MODE, OPTION_MTU, + NO_CONTAINER_INTERFACE_ERROR, OPTION_BCLIM, OPTION_METRIC, OPTION_MODE, OPTION_MTU, OPTION_NO_DEFAULT_ROUTE, }, core_utils::{self, get_ipam_addresses, parse_option, CoreUtils}, @@ -30,6 +31,9 @@ enum KindData { mac_address: Option>, /// macvlan mode mode: u32, + + // IFLA_MACVLAN_BC_CUTOFF option if set + bclim: Option, }, IpVlan { /// ipvlan mode @@ -117,13 +121,17 @@ impl driver::NetworkDriver for Vlan<'_> { super::constants::DRIVER_IPVLAN => KindData::IpVlan { mode: CoreUtils::get_ipvlan_mode_from_string(mode.as_deref())?, }, - super::constants::DRIVER_MACVLAN => KindData::MacVlan { - mode: CoreUtils::get_macvlan_mode_from_string(mode.as_deref())?, - mac_address: match &self.info.per_network_opts.static_mac { - Some(mac) => Some(CoreUtils::decode_address_from_hex(mac)?), - None => None, - }, - }, + super::constants::DRIVER_MACVLAN => { + let bclim = parse_option(&self.info.network.options, OPTION_BCLIM)?; + KindData::MacVlan { + mode: CoreUtils::get_macvlan_mode_from_string(mode.as_deref())?, + mac_address: match &self.info.per_network_opts.static_mac { + Some(mac) => Some(CoreUtils::decode_address_from_hex(mac)?), + None => None, + }, + bclim, + } + } other => { return Err(NetavarkError::msg(format!( "unsupported VLAN type {}", @@ -268,13 +276,30 @@ fn setup( opts.info_data = Some(InfoData::IpVlan(vec![InfoIpVlan::Mode(*mode)])); opts } - KindData::MacVlan { mode, mac_address } => { + KindData::MacVlan { + mode, + mac_address, + bclim, + } => { let mut opts = CreateLinkOptions::new(if_name.to_string(), InfoKind::MacVlan); opts.mac = mac_address.clone().unwrap_or_default(); opts.mtu = data.mtu; opts.netns = netns_fd; opts.link = link.header.index; - opts.info_data = Some(InfoData::MacVlan(vec![InfoMacVlan::Mode(*mode)])); + + let mut mv_opts = vec![InfoMacVlan::Mode(*mode)]; + if let Some(bclim) = bclim { + debug!("setting macvlan bclim to {bclim}"); + // TODO: change this to use the upstream const when available + // https://github.com/rust-netlink/netlink-packet-route/pull/32 + // IFLA_MACVLAN_BC_CUTOFF const in the kernel is 9 + mv_opts.push(InfoMacVlan::Other(DefaultNla::new( + 9, + bclim.to_ne_bytes().to_vec(), + ))) + } + + opts.info_data = Some(InfoData::MacVlan(mv_opts)); opts } };