net_util: add support for IPv6 addresses on tap interfaces

Allow tap interfaces to be configured with an IPv6 address. The change
is fairly straightforward: we need to update the API types and CLI
parsing to accept either an IPv6 or IPv4 and then match on the IP
address type when the tap device is configured.

For IPv6 addresses, the netmask (prefix) must be provided at the same
time as the address itself (in the SIOCSIFADDR ioctl). They cannot be
configured separately. So we remove the separate "set_netmask" function
and convert "set_ip_addr" to also accept a netmask. For IPv4 addresses,
the IP address and netmask were already always set together, so this
should have no functional impact for users of IPv4 addresses.

Signed-off-by: Gregory Anders <ganders@cloudflare.com>
This commit is contained in:
Gregory Anders
2025-05-02 13:04:53 -05:00
committed by Rob Bradford
parent 1454d39b28
commit dce82a34d0
12 changed files with 219 additions and 66 deletions

View File

@@ -935,9 +935,11 @@ components:
ip:
type: string
default: "192.168.249.1"
description: IPv4 or IPv6 address
mask:
type: string
default: "255.255.255.0"
description: Must be a valid IPv4 netmask if ip is an IPv4 address or a valid IPv6 netmask if ip is an IPv6 address.
mac:
type: string
host_mac:

View File

@@ -3138,7 +3138,7 @@ impl Drop for VmConfig {
#[cfg(test)]
mod tests {
use std::fs::File;
use std::net::Ipv4Addr;
use std::net::{IpAddr, Ipv4Addr};
use std::os::unix::io::AsRawFd;
use net_util::MacAddr;
@@ -3468,8 +3468,8 @@ mod tests {
fn net_fixture() -> NetConfig {
NetConfig {
tap: None,
ip: Ipv4Addr::new(192, 168, 249, 1),
mask: Ipv4Addr::new(255, 255, 255, 0),
ip: IpAddr::V4(Ipv4Addr::new(192, 168, 249, 1)),
mask: IpAddr::V4(Ipv4Addr::new(255, 255, 255, 0)),
mac: MacAddr::parse_str("de:ad:be:ef:12:34").unwrap(),
host_mac: Some(MacAddr::parse_str("12:34:de:ad:be:ef").unwrap()),
mtu: None,

View File

@@ -67,13 +67,14 @@ const TUNGETFEATURES: u64 = 0x8004_54cf;
// See include/uapi/linux/sockios.h in the kernel code.
const SIOCGIFFLAGS: u64 = 0x8913;
const SIOCGIFHWADDR: u64 = 0x8927;
const SIOCSIFFLAGS: u64 = 0x8914;
const SIOCSIFADDR: u64 = 0x8916;
const SIOCSIFNETMASK: u64 = 0x891c;
const SIOCGIFMTU: u64 = 0x8921;
const SIOCSIFMTU: u64 = 0x8922;
const SIOCSIFHWADDR: u64 = 0x8924;
const SIOCSIFNETMASK: u64 = 0x891c;
const SIOCGIFHWADDR: u64 = 0x8927;
const SIOCGIFINDEX: u64 = 0x8933;
// See include/uapi/linux/vfio.h in the kernel code.
const VFIO_GET_API_VERSION: u64 = 0x3b64;
@@ -303,6 +304,7 @@ fn create_vmm_ioctl_seccomp_rule_common(
and![Cond::new(1, ArgLen::Dword, Eq, SIOCGIFFLAGS)?],
and![Cond::new(1, ArgLen::Dword, Eq, SIOCGIFHWADDR)?],
and![Cond::new(1, ArgLen::Dword, Eq, SIOCGIFMTU)?],
and![Cond::new(1, ArgLen::Dword, Eq, SIOCGIFINDEX)?],
and![Cond::new(1, ArgLen::Dword, Eq, SIOCSIFADDR)?],
and![Cond::new(1, ArgLen::Dword, Eq, SIOCSIFFLAGS)?],
and![Cond::new(1, ArgLen::Dword, Eq, SIOCSIFHWADDR)?],
@@ -672,6 +674,7 @@ fn vmm_thread_rules(
or![
and![Cond::new(0, ArgLen::Dword, Eq, libc::AF_UNIX as u64)?],
and![Cond::new(0, ArgLen::Dword, Eq, libc::AF_INET as u64)?],
and![Cond::new(0, ArgLen::Dword, Eq, libc::AF_INET6 as u64)?],
],
),
(libc::SYS_socketpair, vec![]),

View File

@@ -2,7 +2,7 @@
//
// SPDX-License-Identifier: Apache-2.0
//
use std::net::Ipv4Addr;
use std::net::{IpAddr, Ipv4Addr};
use std::path::PathBuf;
use std::{fs, result};
@@ -301,9 +301,9 @@ pub struct NetConfig {
#[serde(default = "default_netconfig_tap")]
pub tap: Option<String>,
#[serde(default = "default_netconfig_ip")]
pub ip: Ipv4Addr,
pub ip: IpAddr,
#[serde(default = "default_netconfig_mask")]
pub mask: Ipv4Addr,
pub mask: IpAddr,
#[serde(default = "default_netconfig_mac")]
pub mac: MacAddr,
#[serde(default)]
@@ -349,12 +349,12 @@ pub fn default_netconfig_tap() -> Option<String> {
None
}
pub fn default_netconfig_ip() -> Ipv4Addr {
Ipv4Addr::new(192, 168, 249, 1)
pub fn default_netconfig_ip() -> IpAddr {
IpAddr::V4(Ipv4Addr::new(192, 168, 249, 1))
}
pub fn default_netconfig_mask() -> Ipv4Addr {
Ipv4Addr::new(255, 255, 255, 0)
pub fn default_netconfig_mask() -> IpAddr {
IpAddr::V4(Ipv4Addr::new(255, 255, 255, 0))
}
pub fn default_netconfig_mac() -> MacAddr {