Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move underlay NICs back into H/W Classification #504

Merged
merged 33 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
173f5d3
WIP: Deliver packets via DLS client to escape S/W
FelixMcFelix Apr 24, 2024
94c5264
WIP: Put the promisc callback on the right mac client.
FelixMcFelix Apr 24, 2024
8ffd7c3
Merge branch 'master' into goodbye-all-of-classification
FelixMcFelix Jun 14, 2024
c34e257
Fixup for real!
FelixMcFelix Jun 14, 2024
b542fac
Found the bug.
FelixMcFelix Jun 17, 2024
dff4a58
Reorganisation, cleanup.
FelixMcFelix Jun 17, 2024
360955c
Clippy.
FelixMcFelix Jun 17, 2024
1da884e
Refactoring, newtype for DLS Link IDs
FelixMcFelix Jun 17, 2024
54182c9
Comment tweaks etc.
FelixMcFelix Jun 17, 2024
bb25fde
More commentary.
FelixMcFelix Jun 17, 2024
3dc09de
Should now have the correct attach/detach refs
FelixMcFelix Jun 19, 2024
c84ec5a
Simplify creation/cleanup.
FelixMcFelix Jun 19, 2024
7a4b068
Hmm.
FelixMcFelix Jun 19, 2024
0434f15
Dls, not Dld.
FelixMcFelix Jun 19, 2024
d7d416a
Cleanup.
FelixMcFelix Jun 19, 2024
303057b
Finalist tweaks
FelixMcFelix Jun 19, 2024
94819d5
Accidentally the wrong type.
FelixMcFelix Jun 20, 2024
bf35bf2
Review feedback: nits.
FelixMcFelix Jul 10, 2024
2e4d9c3
Merge branch 'master' into goodbye-all-of-classification
FelixMcFelix Jul 10, 2024
95a213d
Alloc/free dld_str_t from the kmem cache.
FelixMcFelix Aug 1, 2024
bb3cb41
Initial CTF reading from within opteadm.
FelixMcFelix Aug 1, 2024
d0d3986
Live verification of dld_str_s against runtime CTF
FelixMcFelix Aug 1, 2024
4fbcb4b
Remove some debug-fmt.
FelixMcFelix Aug 1, 2024
b682a16
Use live-running DLD (/system) rather than drv
FelixMcFelix Aug 2, 2024
984da1a
Update in tandem with stlouis#577.
FelixMcFelix Aug 6, 2024
dfb6ef4
Swap to upstreamed ctf-bindgen.
FelixMcFelix Aug 8, 2024
35b0187
Help CI along a little bit.
FelixMcFelix Aug 8, 2024
4074b11
Merge branch 'master' into goodbye-all-of-classification
FelixMcFelix Aug 8, 2024
b7e96a2
Back to `main` for ctf-bindgen
FelixMcFelix Aug 8, 2024
942a56e
Undo private access workarounds for ctf-bindgen
FelixMcFelix Aug 8, 2024
77ea7c8
Comment fixups.
FelixMcFelix Aug 8, 2024
ced9d52
No more reliance on `dld_str_t` internals
FelixMcFelix Aug 15, 2024
d3e5867
Uncork opte#532 while we're here.
FelixMcFelix Aug 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 82 additions & 4 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ license = "MPL-2.0"
repository = "https://github.com/oxidecomputer/opte"

[workspace.dependencies]
# Internal crates
derror-macro = { path = "crates/derror-macro" }
illumos-sys-hdrs = { path = "crates/illumos-sys-hdrs" }
kstat-macro = { path = "crates/kstat-macro" }
Expand All @@ -46,6 +45,7 @@ cfg-if = "1"
clap = { version = "4", features = ["derive", "string", "wrap_help"] }
crc32fast = { version = "1", default-features = false }
criterion = "0.5"
ctf-bindgen = { git = "https://github.com/oxidecomputer/ctf-bindgen", rev = "96d2a532335d46bd42732161725188a4d67f6644", default-features = false }
ctor = "0.2"
darling = "0.20"
dyn-clone = "1.0"
Expand Down
5 changes: 4 additions & 1 deletion bin/opteadm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use opte::api::NoResp;
use opte::api::OpteCmd;
use opte::api::SetXdeUnderlayReq;
use opte::engine::ioctl::{self as api};
use opte_ioctl::fetch_fragile_types;
use opte_ioctl::run_cmd_ioctl;
use opte_ioctl::Error;
use oxide_vpc::api::AddFwRuleReq;
Expand Down Expand Up @@ -99,7 +100,9 @@ impl OpteAdm {
u1: &str,
u2: &str,
) -> Result<NoResp, Error> {
let req = SetXdeUnderlayReq { u1: u1.into(), u2: u2.into() };
let illumos_state = fetch_fragile_types()?;
let req =
SetXdeUnderlayReq { u1: u1.into(), u2: u2.into(), illumos_state };
let cmd = OpteCmd::SetXdeUnderlay;
run_cmd_ioctl(self.device.as_raw_fd(), cmd, Some(&req))
}
Expand Down
37 changes: 36 additions & 1 deletion crates/opte-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ extern crate std;
#[macro_use]
extern crate alloc;

use alloc::collections::BTreeMap;
use alloc::string::String;
use core::fmt;
use core::fmt::Display;
Expand Down Expand Up @@ -47,7 +48,7 @@ pub use ulp::*;
///
/// We rely on CI and the check-api-version.sh script to verify that
/// this number is incremented anytime the oxide-api code changes.
pub const API_VERSION: u64 = 33;
pub const API_VERSION: u64 = 34;

/// Major version of the OPTE package.
pub const MAJOR_VERSION: u64 = 0;
Expand Down Expand Up @@ -86,6 +87,40 @@ impl Display for Direction {
pub struct SetXdeUnderlayReq {
pub u1: String,
pub u2: String,

// There are limited/no CTF utilities available in the
// kernel, but there are non-committed (and private) interfaces
// we need to use in the short term. We need to be certain that
// the aspects we care about match the live system.
// Ideally we would build against a fixed proto area and limit
// ourselves to known compatible bits -- but that will require
// heavy build system rework.
pub illumos_state: FragileInternals,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct FragileInternals {
pub dld_str_s: StructDef,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct StructField {
pub bit_offset: u64,
pub ty: FieldType,
// TODO: size is not required for the one aspect we need this
// for, which is reading one pointer offset in a struct defn.
}

#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
pub enum FieldType {
Pointer,
Other(Option<String>),
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct StructDef {
pub size: u64,
pub fields: BTreeMap<String, StructField>,
}

/// Clear the underlay devices used by the xde kernel module
Expand Down
1 change: 1 addition & 0 deletions lib/opte-ioctl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ license.workspace = true
repository.workspace = true

[dependencies]
ctf-bindgen.workspace = true
opte = { workspace = true, default-features = false, features = ["api"] }
oxide-vpc = { workspace = true, default-features = false, features = ["api"] }

Expand Down
65 changes: 64 additions & 1 deletion lib/opte-ioctl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@

// Copyright 2024 Oxide Computer Company

use ctf_bindgen::Ctf;
use ctf_bindgen::TypeInfo;
use ctf_bindgen::TypeRepr;
use opte::api::ClearXdeUnderlayReq;
use opte::api::CmdOk;
use opte::api::Direction;
use opte::api::FieldType;
use opte::api::FragileInternals;
use opte::api::NoResp;
use opte::api::OpteCmd;
use opte::api::OpteCmdIoctl;
pub use opte::api::OpteError;
use opte::api::SetXdeUnderlayReq;
use opte::api::StructDef;
use opte::api::StructField;
use opte::api::API_VERSION;
use opte::api::XDE_IOC_OPTE_CMD;
use oxide_vpc::api::AddRouterEntryReq;
Expand All @@ -36,6 +43,7 @@ use oxide_vpc::api::SetVirt2PhysReq;
use oxide_vpc::api::VpcCfg;
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::collections::BTreeMap;
use std::fs::File;
use std::fs::OpenOptions;
use std::os::unix::io::AsRawFd;
Expand Down Expand Up @@ -71,6 +79,9 @@ pub enum Error {

#[error("command {0:?} failed: {1:?}")]
CommandError(OpteCmd, OpteError),

#[error("failed to fetch local type information: {0:?}")]
CtfError(String),
}

impl From<std::io::Error> for Error {
Expand Down Expand Up @@ -185,7 +196,9 @@ impl OpteHdl {
u1: &str,
u2: &str,
) -> Result<NoResp, Error> {
let req = SetXdeUnderlayReq { u1: u1.into(), u2: u2.into() };
let illumos_state = fetch_fragile_types()?;
let req =
SetXdeUnderlayReq { u1: u1.into(), u2: u2.into(), illumos_state };
let cmd = OpteCmd::SetXdeUnderlay;
run_cmd_ioctl(self.device.as_raw_fd(), cmd, Some(&req))
}
Expand Down Expand Up @@ -362,6 +375,56 @@ where
Err(Error::MaxAttempts(cmd, MAX_ITERATIONS))
}

pub fn fetch_fragile_types() -> Result<FragileInternals, Error> {
let dld_ctf = Ctf::from_file("/system/object/dld/object")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😮 TIL objfs

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I learned that trick from Robert! I think it'll be short-lived if we use your below suggestion. I'll preserve a copy of this branch since we could end up needing these tricks again (although I hope we do not).

.map_err(|e| Error::CtfError(e.to_string()))?;

let Some(dld) = dld_ctf.find_type_by_name("dld_str_s") else {
return Err(Error::CtfError(
"failed to find symbol 'dld_str_s'".into(),
));
};

if let TypeRepr::Struct(ref fields) = dld.repr {
let mut processed_fields = BTreeMap::new();
for field in fields {
let field_name = dld_ctf.string_at(field.name_offset);
let ty = match dld_ctf.resolve_type(field.type_offset) {
Some(t) => match t.repr {
TypeRepr::Othertype => FieldType::Pointer,
_ => FieldType::Other(Some(
dld_ctf.string_at(t.name_offset).into(),
)),
},
None => FieldType::Other(None),
};

processed_fields.insert(
field_name.into(),
StructField { bit_offset: u64::from(field.offset), ty },
);
}

// invariant: struct should store info as size
let TypeInfo::Size(size) = dld.info else {
return Err(Error::CtfError(
"struct recorded info as 'type'\
rather than 'size'"
.into(),
));
};

Ok(FragileInternals {
dld_str_s: StructDef {
size: size.into(),
fields: processed_fields,
},
})
} else {
Err(Error::CtfError("symbol 'dld_str_s' is not of type struct".into()))
}
}

unsafe fn ioctl<T>(
fd: libc::c_int,
req: libc::c_int,
Expand Down
2 changes: 1 addition & 1 deletion xde-tests/tests/loopback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fn test_xde_loopback() -> Result<()> {
let topol = xde_tests::two_node_topology()?;

// Now we should be able to ping b from a on the overlay.
&topol.nodes[0]
_ = &topol.nodes[0]
.zone
.zone
.zexec(&format!("ping {}", &topol.nodes[1].port.ip()))?;
Expand Down
Loading