diff --git a/src/network/bridge.rs b/src/network/bridge.rs index cc003f92..d3dd6c35 100644 --- a/src/network/bridge.rs +++ b/src/network/bridge.rs @@ -6,6 +6,7 @@ use netlink_packet_route::link::{ InfoData, InfoKind, InfoVeth, LinkAttribute, LinkInfo, LinkMessage, }; +use crate::network::macvlan_dhcp::get_dhcp_lease; use crate::{ dns::aardvark::AardvarkEntry, error::{ErrorWrap, NetavarkError, NetavarkErrorList, NetavarkResult}, @@ -150,9 +151,31 @@ impl driver::NetworkDriver for Bridge<'_> { // interfaces map, but we only ever expect one, for response let mut interfaces: HashMap = HashMap::new(); + // if dhcp is enabled, we need to call the dhcp proxy to perform + // a dhcp lease. it will also perform the IP address assignment + // to the container interface. + let subnets = if data.ipam.dhcp_enabled { + let (subnets, dns_servers, domain_name) = get_dhcp_lease( + &data.bridge_interface_name, + &data.container_interface_name, + self.info.netns_path, + &container_veth_mac, + )?; + // do not overwrite dns servers set by dns podman flag + if !self.info.container_dns_servers.is_some() { + response.dns_server_ips = dns_servers; + } + if domain_name.is_some() { + response.dns_search_domains = domain_name; + } + subnets + } else { + data.ipam.net_addresses.clone() + }; + let interface = types::NetInterface { mac_address: container_veth_mac, - subnets: Option::from(data.ipam.net_addresses.clone()), + subnets: Option::from(subnets), }; // Add interface to interfaces (part of StatusBlock) interfaces.insert(data.container_interface_name.clone(), interface); @@ -251,6 +274,8 @@ impl driver::NetworkDriver for Bridge<'_> { let mut error_list = NetavarkErrorList::new(); + core_utils::dhcp_teardown(&self.info, netns_sock)?; + let routes = core_utils::create_route_list(&self.info.network.routes)?; for route in routes.iter() { netns_sock diff --git a/src/network/core_utils.rs b/src/network/core_utils.rs index 34f0caf3..f85bedd3 100644 --- a/src/network/core_utils.rs +++ b/src/network/core_utils.rs @@ -1,4 +1,5 @@ use crate::error::{ErrorWrap, NetavarkError, NetavarkResult}; +use crate::network::macvlan_dhcp::release_dhcp_lease; use crate::network::{constants, internal_types, types}; use crate::wrap; use ipnet::IpNet; @@ -18,7 +19,9 @@ use std::os::unix::prelude::*; use std::str::FromStr; use sysctl::{Sysctl, SysctlError}; -use super::netlink; +use super::{driver::DriverInfo, netlink}; + +use netlink_packet_route::link::LinkAttribute; pub struct CoreUtils { pub networkns: String, @@ -435,3 +438,37 @@ pub fn disable_ipv6_autoconf(if_name: &str) -> NetavarkResult<()> { }; Ok(()) } + +pub fn get_mac_address(v: Vec) -> NetavarkResult { + for nla in v.into_iter() { + if let LinkAttribute::Address(ref addr) = nla { + return Ok(CoreUtils::encode_address_to_hex(addr)); + } + } + Err(NetavarkError::msg( + "failed to get the the container mac address", + )) +} + +pub fn dhcp_teardown(info: &DriverInfo, sock: &mut netlink::Socket) -> NetavarkResult<()> { + let ipam = get_ipam_addresses(info.per_network_opts, info.network)?; + let if_name = info.per_network_opts.interface_name.clone(); + + // If we are using DHCP, we need to at least call to the proxy so that + // the proxy's cache can get updated and the current lease can be released. + if ipam.dhcp_enabled { + let dev = sock.get_link(netlink::LinkID::Name(if_name)).wrap(format!( + "get container interface {}", + &info.per_network_opts.interface_name + ))?; + + let container_mac_address = get_mac_address(dev.attributes)?; + release_dhcp_lease( + &info.network.network_interface.clone().unwrap_or_default(), + &info.per_network_opts.interface_name, + info.netns_path, + &container_mac_address, + )? + } + Ok(()) +} diff --git a/src/network/vlan.rs b/src/network/vlan.rs index f567134d..97e81351 100644 --- a/src/network/vlan.rs +++ b/src/network/vlan.rs @@ -7,7 +7,7 @@ use netlink_packet_route::link::{ }; use rand::distributions::{Alphanumeric, DistString}; -use crate::network::macvlan_dhcp::{get_dhcp_lease, release_dhcp_lease}; +use crate::network::macvlan_dhcp::get_dhcp_lease; use crate::{ dns::aardvark::AardvarkEntry, error::{ErrorWrap, NetavarkError, NetavarkResult}, @@ -20,7 +20,7 @@ use super::{ 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}, + core_utils::{self, get_ipam_addresses, get_mac_address, parse_option, CoreUtils}, driver::{self, DriverInfo}, internal_types::IPAMAddresses, netlink::{self, CreateLinkOptions}, @@ -216,33 +216,7 @@ impl driver::NetworkDriver for Vlan<'_> { &self, netlink_sockets: (&mut netlink::Socket, &mut netlink::Socket), ) -> NetavarkResult<()> { - let ipam = get_ipam_addresses(self.info.per_network_opts, self.info.network)?; - let if_name = self.info.per_network_opts.interface_name.clone(); - - // If we are using DHCP macvlan, we need to at least call to the proxy so that - // the proxy's cache can get updated and the current lease can be released. - if ipam.dhcp_enabled { - let dev = netlink_sockets - .1 - .get_link(netlink::LinkID::Name(if_name)) - .wrap(format!( - "get macvlan interface {}", - &self.info.per_network_opts.interface_name - ))?; - - let container_mac_address = get_mac_address(dev.attributes)?; - release_dhcp_lease( - &self - .info - .network - .network_interface - .clone() - .unwrap_or_default(), - &self.info.per_network_opts.interface_name, - self.info.netns_path, - &container_mac_address, - )? - } + core_utils::dhcp_teardown(&self.info, netlink_sockets.1)?; let routes = core_utils::create_route_list(&self.info.network.routes)?; for route in routes.iter() { @@ -386,17 +360,6 @@ fn setup( get_mac_address(dev.attributes) } -fn get_mac_address(v: Vec) -> NetavarkResult { - for nla in v.into_iter() { - if let LinkAttribute::Address(ref addr) = nla { - return Ok(CoreUtils::encode_address_to_hex(addr)); - } - } - Err(NetavarkError::msg( - "failed to get the the container mac address", - )) -} - fn get_default_route_interface(host: &mut netlink::Socket) -> NetavarkResult { let routes = host.dump_routes().wrap("dump routes")?;