Skip to content

Commit

Permalink
Merge pull request #161 from Burning1020/add-route-flag
Browse files Browse the repository at this point in the history
vmm: Sync route flags
  • Loading branch information
abel-von authored Aug 16, 2024
2 parents f6594a1 + ab97ded commit 9ecee15
Show file tree
Hide file tree
Showing 11 changed files with 235 additions and 187 deletions.
1 change: 1 addition & 0 deletions vmm/common/src/protos/sandbox.proto
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ message Route {
string source = 4;
uint32 scope = 5;
IPFamily family = 6;
uint32 flags = 7;
}

message UpdateInterfacesRequest {
Expand Down
31 changes: 20 additions & 11 deletions vmm/sandbox/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions vmm/sandbox/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ qapi = { version = "0.8.0", features = ["qmp", "async-tokio-all"] }
qapi-spec = { version = "0.3.1" }
sandbox-derive = { path = "derive" }
api_client = { git = "https://github.com/cloud-hypervisor/cloud-hypervisor.git" }
rtnetlink = "0.13.1"
netlink-packet-route = "0.17.0"
rtnetlink = "0.14.1"
netlink-packet-route = "0.19.0"
netlink-packet-core = "0.7.0"
ttrpc = { version = "0.7", features = ["async"] }
protobuf = "3.2"
Expand Down
18 changes: 6 additions & 12 deletions vmm/sandbox/src/network/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ limitations under the License.
*/

use std::{
convert::TryInto,
fmt::{Debug, Formatter},
net::{IpAddr, Ipv4Addr, Ipv6Addr},
str::FromStr,
};

use anyhow::anyhow;
use containerd_sandbox::error::Result;
use netlink_packet_route::route::RouteAddress;
use serde_derive::{Deserialize, Serialize};

#[derive(Default, Debug, Clone, Deserialize, Serialize)]
Expand Down Expand Up @@ -141,16 +141,10 @@ impl std::fmt::Display for MacAddress {
}
}

pub fn convert_to_ip_address(addr: Vec<u8>) -> Result<IpAddr> {
if addr.len() == 4 {
let arr: &[u8; 4] = addr.as_slice().try_into().unwrap();
let address = IpAddr::from(*arr);
return Ok(address);
pub fn convert_to_ip_address(address: RouteAddress) -> Result<IpAddr> {
match address {
RouteAddress::Inet(addr) => Ok(IpAddr::V4(addr)),
RouteAddress::Inet6(addr) => Ok(IpAddr::V6(addr)),
_ => Err(anyhow!("unsupported ip address {:?}", address).into()),
}
if addr.len() == 16 {
let arr: &[u8; 16] = addr.as_slice().try_into().unwrap();
let address = IpAddr::from(*arr);
return Ok(address);
}
Err(anyhow!("ip address vec has length {}", addr.len()).into())
}
11 changes: 6 additions & 5 deletions vmm/sandbox/src/network/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

use netlink_packet_route::{AF_INET, AF_INET6};
use netlink_packet_route::AddressFamily;
use protobuf::{EnumOrUnknown, SpecialFields};
use vmm_common::api::sandbox::{IPAddress, IPFamily, Interface, Route};

Expand Down Expand Up @@ -57,12 +57,13 @@ impl From<&crate::network::Route> for Route {
gateway: r.gateway.to_string(),
device: r.device.to_string(),
source: r.source.to_string(),
scope: r.scope,
family: EnumOrUnknown::from(match r.family {
AF_INET => IPFamily::v4,
AF_INET6 => IPFamily::v6,
scope: r.scope as u32,
family: EnumOrUnknown::from(match AddressFamily::from(r.family) {
AddressFamily::Inet => IPFamily::v4,
AddressFamily::Inet6 => IPFamily::v6,
_ => IPFamily::default(),
}),
flags: r.flags,
special_fields: Default::default(),
}
}
Expand Down
56 changes: 32 additions & 24 deletions vmm/sandbox/src/network/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@ use anyhow::anyhow;
use containerd_sandbox::error::Result;
use futures_util::TryStreamExt;
use libc::{IFF_MULTI_QUEUE, IFF_NO_PI, IFF_TAP, IFF_VNET_HDR};
use netlink_packet_route::{
link::nlas::{Info, InfoData, InfoIpVlan, InfoKind, InfoMacVlan, InfoMacVtap, InfoVlan},
nlas::link::InfoVxlan,
LinkMessage,
use netlink_packet_route::link::{
InfoData, InfoIpVlan, InfoKind, InfoMacVlan, InfoMacVtap, InfoVlan, InfoVxlan, LinkFlag,
LinkInfo, LinkMessage,
};
use nix::{
ioctl_read_bad, ioctl_write_ptr_bad, libc,
Expand All @@ -44,7 +43,7 @@ use serde_derive::{Deserialize, Serialize};
use crate::{
device::{DeviceInfo, PhysicalDeviceInfo, TapDeviceInfo, VhostUserDeviceInfo},
network::{
address::{convert_to_ip_address, CniIPAddress, IpNet, MacAddress},
address::{CniIPAddress, IpNet, MacAddress},
create_netlink_handle, execute_in_netns, run_in_new_netns,
},
sandbox::KuasarSandbox,
Expand Down Expand Up @@ -98,7 +97,6 @@ pub enum LinkType {
Ipvlan(u16),
Macvlan(u32),
Macvtap(u32),
Iptun,
Tun,
VhostUser(String),
Physical(String, String),
Expand All @@ -124,7 +122,6 @@ impl Display for LinkType {
LinkType::Ipvlan(_) => "ipvlan".to_string(),
LinkType::Macvlan(_) => "macvlan".to_string(),
LinkType::Macvtap(_) => "macvtap".to_string(),
LinkType::Iptun => "iptun".to_string(),
LinkType::Tun => "tun".to_string(),
LinkType::VhostUser(_) => "vhostuser".to_string(),
LinkType::Physical(_, _) => "physical".to_string(),
Expand Down Expand Up @@ -167,7 +164,6 @@ impl From<InfoData> for LinkType {
return Self::Macvtap(*i);
}
}
InfoData::IpTun(_) => return Self::Iptun,
_ => return Self::Unkonwn,
}
Self::Unkonwn
Expand Down Expand Up @@ -210,6 +206,19 @@ pub struct NetworkInterface {
pub queue: u32,
}

// netlink-packet-route-0.19.0/src/link/link_flag.rs:26
pub(crate) struct VecLinkFlag(pub Vec<LinkFlag>);

impl From<&VecLinkFlag> for u32 {
fn from(v: &VecLinkFlag) -> u32 {
let mut d: u32 = 0;
for flag in &v.0 {
d += u32::from(*flag);
}
d
}
}

impl NetworkInterface {
pub async fn parse_from_message(
msg: LinkMessage,
Expand All @@ -218,31 +227,31 @@ impl NetworkInterface {
handle: &Handle,
) -> Result<Self> {
let mut intf = NetworkInterface {
flags: msg.header.flags,
flags: u32::from(&VecLinkFlag(msg.header.flags)),
index: msg.header.index,
..NetworkInterface::default()
};
for nla in msg.nlas.into_iter() {
use netlink_packet_route::nlas::link::Nla;
match nla {
Nla::Info(infos) => {
use netlink_packet_route::link::LinkAttribute;
for attribute in msg.attributes.into_iter() {
match attribute {
LinkAttribute::LinkInfo(infos) => {
for info in infos {
if let Info::Data(d) = info {
if let LinkInfo::Data(d) = info {
intf.r#type = d.into();
} else if let Info::Kind(InfoKind::Veth) = info {
// for veth, there is no Info::Data, but SlaveKind and SlaveData
} else if let LinkInfo::Kind(InfoKind::Veth) = info {
// for veth, there is no Info::Data, but SlaveKind and SlaveData,
// so we have to get the type from Info::Kind
intf.queue = queue;
intf.r#type = LinkType::Veth;
}
}
}
Nla::IfName(s) => {
LinkAttribute::IfName(s) => {
intf.name = s;
}
Nla::IfAlias(a) => intf.alias = a,
Nla::Mtu(m) => intf.mtu = m,
Nla::Address(u) => intf.mac_address = MacAddress(u),
LinkAttribute::IfAlias(a) => intf.alias = a,
LinkAttribute::Mtu(m) => intf.mtu = m,
LinkAttribute::Address(u) => intf.mac_address = MacAddress(u),
_ => {}
}
}
Expand All @@ -252,10 +261,9 @@ impl NetworkInterface {
.set_link_index_filter(msg.header.index)
.execute();
while let Some(msg) = addresses.try_next().await.map_err(|e| anyhow!(e))? {
use netlink_packet_route::nlas::address::Nla;
for nla in msg.nlas.into_iter() {
if let Nla::Address(addr) = nla {
let address = convert_to_ip_address(addr)?;
use netlink_packet_route::address::AddressAttribute;
for nla in msg.attributes.into_iter() {
if let AddressAttribute::Address(address) = nla {
let mask_len = msg.header.prefix_len;
if address.is_loopback() {
intf.r#type = LinkType::Loopback;
Expand Down
10 changes: 5 additions & 5 deletions vmm/sandbox/src/network/netlink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ limitations under the License.

use futures_util::StreamExt;
use netlink_packet_core::{NetlinkMessage, NLM_F_ACK, NLM_F_CREATE, NLM_F_EXCL, NLM_F_REQUEST};
use netlink_packet_route::{RtnlMessage, TcMessage};
use netlink_packet_route::{tc::TcMessage, RouteNetlinkMessage};
use rtnetlink::{try_nl, Error, Handle};

const HANDLE_INGRESS: u32 = 0xfffffff1;
Expand All @@ -42,7 +42,7 @@ impl QDiscAddRequest {
message,
} = self;

let mut req = NetlinkMessage::from(RtnlMessage::NewQueueDiscipline(message));
let mut req = NetlinkMessage::from(RouteNetlinkMessage::NewQueueDiscipline(message));
req.header.flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK;

let mut response = handle.request(req)?;
Expand All @@ -58,7 +58,7 @@ impl QDiscAddRequest {
}

pub fn ingress(mut self) -> Self {
self.message.header.parent = HANDLE_INGRESS;
self.message.header.parent = HANDLE_INGRESS.into();
self
}
}
Expand All @@ -73,7 +73,7 @@ impl TrafficFilterSetRequest {
pub(crate) fn new(handle: Handle, ifindex: i32) -> Self {
let mut message = TcMessage::default();
message.header.index = ifindex;
message.header.parent = HANDLE_TC_FILTER;
message.header.parent = HANDLE_TC_FILTER.into();

Self { handle, message }
}
Expand All @@ -84,7 +84,7 @@ impl TrafficFilterSetRequest {
message,
} = self;

let mut req = NetlinkMessage::from(RtnlMessage::NewTrafficFilter(message));
let mut req = NetlinkMessage::from(RouteNetlinkMessage::NewTrafficFilter(message));
req.header.flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK;

let mut response = handle.request(req)?;
Expand Down
Loading

0 comments on commit 9ecee15

Please sign in to comment.