Skip to content

Commit 1d29ef6

Browse files
authored
support for tunneled routing (#381)
1 parent dd2b7b0 commit 1d29ef6

File tree

34 files changed

+803
-259
lines changed

34 files changed

+803
-259
lines changed

.github/buildomat/jobs/oxide-vpc.sh

100644100755
File mode changed.

.github/buildomat/jobs/test.sh

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22
#:
33
#: name = "test"
44
#: variety = "basic"
5-
#: target = "lab-2.0-opte-0.23"
5+
#: target = "helios-2.0"
66
#: rust_toolchain = "stable"
77
#: output_rules = [
88
#: "/work/*.log",
99
#: ]
10-
#: skip_clone = true
1110
#:
1211
#: [dependencies.xde]
1312
#: job = "opte-xde"
@@ -22,6 +21,8 @@
2221

2322
set -o xtrace
2423

24+
pfexec pkg install brand/sparse opte
25+
2526
if [[ -z $BUILDOMAT_JOB_ID ]]; then
2627
echo Note: if you are running this locally, you must run the xde.sh job first
2728
echo to have the artifacts at the expected spot.
@@ -37,6 +38,30 @@ function cleanup {
3738
}
3839
trap cleanup EXIT
3940

41+
function get_artifact {
42+
repo=$1
43+
series=$2
44+
commit=$3
45+
name=$4
46+
url=https://buildomat.eng.oxide.computer/public/file/oxidecomputer
47+
48+
mkdir -p download
49+
pushd download
50+
if [[ ! -f $name ]]; then
51+
curl -fOL $url/$repo/$series/$commit/$name
52+
fi
53+
popd
54+
}
55+
56+
banner "collect"
57+
get_artifact softnpu image 88f5f1334364e5580fe778c44ac0746a35927351 softnpu
58+
get_artifact sidecar-lite release 3fff53ae549ab1348b680845693e66b224bb5d2f libsidecar_lite.so
59+
get_artifact sidecar-lite release 3fff53ae549ab1348b680845693e66b224bb5d2f scadm
60+
61+
if [[ $DOWNLOAD_ONLY -eq 1 ]]; then
62+
exit 0;
63+
fi
64+
4065
uname -a
4166
cat /etc/versions/build
4267

.github/buildomat/jobs/xde.sh

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@
1717
#: "=/work/xde.conf",
1818
#: ]
1919
#:
20+
#: [[publish]]
21+
#: series = "module"
22+
#: name = "xde"
23+
#: from_output = "/work/release/xde"
24+
#
25+
#: [[publish]]
26+
#: series = "module"
27+
#: name = "xde.sha256"
28+
#: from_output = "/work/release/xde.sha256"
2029

2130
set -o errexit
2231
set -o pipefail
@@ -69,10 +78,12 @@ header "check style"
6978
ptime -m cargo +nightly-2023-10-23 fmt -p xde -p xde-link -- --check
7079

7180
header "analyze"
72-
ptime -m cargo clippy -- --allow clippy::uninlined-format-args
81+
ptime -m cargo clippy -- \
82+
--allow clippy::uninlined-format-args --allow clippy::bad_bit_mask
7383

7484
pushd xde-link
75-
ptime -m cargo clippy -- --allow clippy::uninlined-format-args
85+
ptime -m cargo clippy -- \
86+
--allow clippy::uninlined-format-args --allow clippy::bad_bit_mask
7687
popd
7788

7889
header "build xde (debug)"

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
*.html
22
target
3+
download

Cargo.lock

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ version_check = "0.9"
6060
zerocopy = { version = "0.7", features = ["derive"] }
6161
zone = { git = "https://github.com/oxidecomputer/zone" }
6262
ztest = { git = "https://github.com/oxidecomputer/falcon", branch = "main" }
63+
poptrie = { git = "https://github.com/oxidecomputer/poptrie", branch = "multipath" }
6364

6465
[profile.release]
6566
debug = 2

bin/opteadm/src/bin/opteadm.rs

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use opteadm::OpteAdm;
2424
use opteadm::COMMIT_COUNT;
2525
use oxide_vpc::api::AddRouterEntryReq;
2626
use oxide_vpc::api::Address;
27-
use oxide_vpc::api::BoundaryServices;
27+
use oxide_vpc::api::ClearVirt2BoundaryReq;
2828
use oxide_vpc::api::DhcpCfg;
2929
use oxide_vpc::api::ExternalIpCfg;
3030
use oxide_vpc::api::Filters as FirewallFilters;
@@ -42,15 +42,20 @@ use oxide_vpc::api::RouterTarget;
4242
use oxide_vpc::api::SNat4Cfg;
4343
use oxide_vpc::api::SNat6Cfg;
4444
use oxide_vpc::api::SetExternalIpsReq;
45+
use oxide_vpc::api::SetVirt2BoundaryReq;
4546
use oxide_vpc::api::SetVirt2PhysReq;
47+
use oxide_vpc::api::TunnelEndpoint;
4648
use oxide_vpc::api::VpcCfg;
49+
use oxide_vpc::engine::overlay::BOUNDARY_SERVICES_VNI;
50+
use oxide_vpc::engine::print::print_v2b;
4751
use oxide_vpc::engine::print::print_v2p;
4852
use std::io;
4953
use std::str::FromStr;
5054

5155
/// Administer the Oxide Packet Transformation Engine (OPTE)
5256
#[derive(Debug, Parser)]
5357
#[command(version=opte_pkg_version())]
58+
#[allow(clippy::large_enum_variant)]
5459
enum Command {
5560
/// List all ports.
5661
ListPorts,
@@ -96,6 +101,9 @@ enum Command {
96101
/// Dump virtual to physical address mapping
97102
DumpV2P,
98103

104+
/// Dump virtual to boundary address mapping
105+
DumpV2B,
106+
99107
/// Add a firewall rule
100108
AddFwRule {
101109
#[arg(short)]
@@ -162,19 +170,6 @@ enum Command {
162170
#[arg(long)]
163171
gateway_ip: IpAddr,
164172

165-
/// The IP address for Boundary Services, where packets destined to
166-
/// off-rack networks are sent.
167-
#[arg(long)]
168-
bsvc_addr: Ipv6Addr,
169-
170-
/// The VNI used for Boundary Services.
171-
#[arg(long)]
172-
bsvc_vni: Vni,
173-
174-
/// The MAC address for Boundary Services.
175-
#[arg(long, default_value = "00:00:00:00:00:00")]
176-
bsvc_mac: MacAddr,
177-
178173
/// The VNI for the VPC to which the guest belongs.
179174
#[arg(long)]
180175
vpc_vni: Vni,
@@ -203,6 +198,12 @@ enum Command {
203198
/// Set a virtual-to-physical mapping
204199
SetV2P { vpc_ip: IpAddr, vpc_mac: MacAddr, underlay_ip: Ipv6Addr, vni: Vni },
205200

201+
/// Set a virtual-to-boundary mapping
202+
SetV2B { prefix: IpCidr, tunnel_endpoint: Vec<Ipv6Addr> },
203+
204+
/// Clear a virtual-to-boundary mapping
205+
ClearV2B { prefix: IpCidr, tunnel_endpoint: Vec<Ipv6Addr> },
206+
206207
/// Add a new router entry, either IPv4 or IPv6.
207208
AddRouterEntry {
208209
/// The OPTE port to which the route is added
@@ -511,6 +512,11 @@ fn main() -> anyhow::Result<()> {
511512
print_v2p(&hdl.dump_v2p()?);
512513
}
513514

515+
Command::DumpV2B => {
516+
let hdl = opteadm::OpteAdm::open(OpteAdm::XDE_CTL)?;
517+
print_v2b(&hdl.dump_v2b()?);
518+
}
519+
514520
Command::AddFwRule { port, direction, filters, action, priority } => {
515521
let rule = FirewallRule {
516522
direction,
@@ -541,9 +547,6 @@ fn main() -> anyhow::Result<()> {
541547
vpc_subnet,
542548
gateway_mac,
543549
gateway_ip,
544-
bsvc_addr,
545-
bsvc_vni,
546-
bsvc_mac,
547550
vpc_vni,
548551
src_underlay_addr,
549552
dhcp,
@@ -595,11 +598,6 @@ fn main() -> anyhow::Result<()> {
595598
gateway_mac,
596599
vni: vpc_vni,
597600
phys_ip: src_underlay_addr,
598-
boundary_services: BoundaryServices {
599-
ip: bsvc_addr,
600-
vni: bsvc_vni,
601-
mac: bsvc_mac,
602-
},
603601
};
604602

605603
hdl.create_xde(&name, cfg, dhcp.into(), passthrough)?;
@@ -624,6 +622,32 @@ fn main() -> anyhow::Result<()> {
624622
hdl.set_v2p(&req)?;
625623
}
626624

625+
Command::SetV2B { prefix, tunnel_endpoint } => {
626+
let hdl = opteadm::OpteAdm::open(OpteAdm::XDE_CTL)?;
627+
let tep = tunnel_endpoint
628+
.into_iter()
629+
.map(|ip| TunnelEndpoint {
630+
ip,
631+
vni: Vni::new(BOUNDARY_SERVICES_VNI).unwrap(),
632+
})
633+
.collect();
634+
let req = SetVirt2BoundaryReq { vip: prefix, tep };
635+
hdl.set_v2b(&req)?;
636+
}
637+
638+
Command::ClearV2B { prefix, tunnel_endpoint } => {
639+
let hdl = opteadm::OpteAdm::open(OpteAdm::XDE_CTL)?;
640+
let tep = tunnel_endpoint
641+
.into_iter()
642+
.map(|ip| TunnelEndpoint {
643+
ip,
644+
vni: Vni::new(BOUNDARY_SERVICES_VNI).unwrap(),
645+
})
646+
.collect();
647+
let req = ClearVirt2BoundaryReq { vip: prefix, tep };
648+
hdl.clear_v2b(&req)?;
649+
}
650+
627651
Command::AddRouterEntry { port, dest, target } => {
628652
let req = AddRouterEntryReq { port_name: port, dest, target };
629653
hdl.add_router_entry(&req)?;

bin/opteadm/src/lib.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use opte_ioctl::run_cmd_ioctl;
1414
use opte_ioctl::Error;
1515
use oxide_vpc::api::AddFwRuleReq;
1616
use oxide_vpc::api::AddRouterEntryReq;
17+
use oxide_vpc::api::ClearVirt2BoundaryReq;
1718
use oxide_vpc::api::CreateXdeReq;
1819
use oxide_vpc::api::DeleteXdeReq;
1920
use oxide_vpc::api::DhcpCfg;
@@ -22,6 +23,7 @@ use oxide_vpc::api::ListPortsResp;
2223
use oxide_vpc::api::RemFwRuleReq;
2324
use oxide_vpc::api::SetExternalIpsReq;
2425
use oxide_vpc::api::SetFwRulesReq;
26+
use oxide_vpc::api::SetVirt2BoundaryReq;
2527
use oxide_vpc::api::SetVirt2PhysReq;
2628
use oxide_vpc::api::VpcCfg;
2729
use oxide_vpc::engine::overlay;
@@ -226,6 +228,29 @@ impl OpteAdm {
226228
)
227229
}
228230

231+
pub fn set_v2b(&self, req: &SetVirt2BoundaryReq) -> Result<NoResp, Error> {
232+
let cmd = OpteCmd::SetVirt2Boundary;
233+
run_cmd_ioctl(self.device.as_raw_fd(), cmd, Some(&req))
234+
}
235+
236+
pub fn clear_v2b(
237+
&self,
238+
req: &ClearVirt2BoundaryReq,
239+
) -> Result<NoResp, Error> {
240+
let cmd = OpteCmd::ClearVirt2Boundary;
241+
run_cmd_ioctl(self.device.as_raw_fd(), cmd, Some(&req))
242+
}
243+
244+
/// Dump the Virtual-to-Boundary mappings.
245+
pub fn dump_v2b(&self) -> Result<overlay::DumpVirt2BoundaryResp, Error> {
246+
let cmd = OpteCmd::DumpVirt2Boundary;
247+
run_cmd_ioctl(
248+
self.device.as_raw_fd(),
249+
cmd,
250+
Some(&overlay::DumpVirt2BoundaryReq { unused: 99 }),
251+
)
252+
}
253+
229254
pub fn add_router_entry(
230255
&self,
231256
req: &AddRouterEntryReq,

crates/opte-api/src/cmd.rs

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,26 @@ pub const XDE_IOC_OPTE_CMD: i32 = XDE_IOC as i32 | 0x01;
2020
#[derive(Clone, Copy, Debug)]
2121
#[repr(C)]
2222
pub enum OpteCmd {
23-
ListPorts = 1, // list all ports
24-
AddFwRule = 20, // add firewall rule
25-
RemFwRule = 21, // remove firewall rule
26-
SetFwRules = 22, // set/replace all firewall rules at once
27-
DumpTcpFlows = 30, // dump TCP flows
28-
DumpLayer = 31, // dump the specified Layer
29-
DumpUft = 32, // dump the Unified Flow Table
30-
ListLayers = 33, // list the layers on a given port
31-
ClearUft = 40, // clear the UFT
32-
ClearLft = 41, // clear the given Layer's Flow Table
33-
SetVirt2Phys = 50, // set a v2p mapping
34-
DumpVirt2Phys = 51, // dump the v2p mappings
35-
AddRouterEntry = 60, // add a router entry for IP dest
36-
CreateXde = 70, // create a new xde device
37-
DeleteXde = 71, // delete an xde device
38-
SetXdeUnderlay = 72, // set xde underlay devices
39-
SetExternalIps = 80, // set xde external IPs for a port
23+
ListPorts = 1, // list all ports
24+
AddFwRule = 20, // add firewall rule
25+
RemFwRule = 21, // remove firewall rule
26+
SetFwRules = 22, // set/replace all firewall rules at once
27+
DumpTcpFlows = 30, // dump TCP flows
28+
DumpLayer = 31, // dump the specified Layer
29+
DumpUft = 32, // dump the Unified Flow Table
30+
ListLayers = 33, // list the layers on a given port
31+
ClearUft = 40, // clear the UFT
32+
ClearLft = 41, // clear the given Layer's Flow Table
33+
SetVirt2Phys = 50, // set a v2p mapping
34+
DumpVirt2Phys = 51, // dump the v2p mappings
35+
SetVirt2Boundary = 52, // set a v2b mapping
36+
ClearVirt2Boundary = 53, // clear a v2b mapping
37+
DumpVirt2Boundary = 54, // dump the v2b mappings
38+
AddRouterEntry = 60, // add a router entry for IP dest
39+
CreateXde = 70, // create a new xde device
40+
DeleteXde = 71, // delete an xde device
41+
SetXdeUnderlay = 72, // set xde underlay devices
42+
SetExternalIps = 80, // set xde external IPs for a port
4043
}
4144

4245
impl TryFrom<c_int> for OpteCmd {
@@ -56,6 +59,9 @@ impl TryFrom<c_int> for OpteCmd {
5659
41 => Ok(Self::ClearLft),
5760
50 => Ok(Self::SetVirt2Phys),
5861
51 => Ok(Self::DumpVirt2Phys),
62+
52 => Ok(Self::SetVirt2Boundary),
63+
53 => Ok(Self::ClearVirt2Boundary),
64+
54 => Ok(Self::DumpVirt2Boundary),
5965
60 => Ok(Self::AddRouterEntry),
6066
70 => Ok(Self::CreateXde),
6167
71 => Ok(Self::DeleteXde),

0 commit comments

Comments
 (0)