-
Notifications
You must be signed in to change notification settings - Fork 11
Move underlay NICs back into H/W Classification #504
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
Merged
Merged
Changes from all 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 94c5264
WIP: Put the promisc callback on the right mac client.
FelixMcFelix 8ffd7c3
Merge branch 'master' into goodbye-all-of-classification
FelixMcFelix c34e257
Fixup for real!
FelixMcFelix b542fac
Found the bug.
FelixMcFelix dff4a58
Reorganisation, cleanup.
FelixMcFelix 360955c
Clippy.
FelixMcFelix 1da884e
Refactoring, newtype for DLS Link IDs
FelixMcFelix 54182c9
Comment tweaks etc.
FelixMcFelix bb25fde
More commentary.
FelixMcFelix 3dc09de
Should now have the correct attach/detach refs
FelixMcFelix c84ec5a
Simplify creation/cleanup.
FelixMcFelix 7a4b068
Hmm.
FelixMcFelix 0434f15
Dls, not Dld.
FelixMcFelix d7d416a
Cleanup.
FelixMcFelix 303057b
Finalist tweaks
FelixMcFelix 94819d5
Accidentally the wrong type.
FelixMcFelix bf35bf2
Review feedback: nits.
FelixMcFelix 2e4d9c3
Merge branch 'master' into goodbye-all-of-classification
FelixMcFelix 95a213d
Alloc/free dld_str_t from the kmem cache.
FelixMcFelix bb3cb41
Initial CTF reading from within opteadm.
FelixMcFelix d0d3986
Live verification of dld_str_s against runtime CTF
FelixMcFelix 4fbcb4b
Remove some debug-fmt.
FelixMcFelix b682a16
Use live-running DLD (/system) rather than drv
FelixMcFelix 984da1a
Update in tandem with stlouis#577.
FelixMcFelix dfb6ef4
Swap to upstreamed ctf-bindgen.
FelixMcFelix 35b0187
Help CI along a little bit.
FelixMcFelix 4074b11
Merge branch 'master' into goodbye-all-of-classification
FelixMcFelix b7e96a2
Back to `main` for ctf-bindgen
FelixMcFelix 942a56e
Undo private access workarounds for ctf-bindgen
FelixMcFelix 77ea7c8
Comment fixups.
FelixMcFelix ced9d52
No more reliance on `dld_str_t` internals
FelixMcFelix d3e5867
Uncork opte#532 while we're here.
FelixMcFelix File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,258 @@ | ||
| // This Source Code Form is subject to the terms of the Mozilla Public | ||
| // License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| // file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
|
|
||
| // Copyright 2024 Oxide Computer Company | ||
|
|
||
| //! Safe abstractions around DLS public and private functions. | ||
|
|
||
| pub mod sys; | ||
|
|
||
| use crate::mac::mac_client_handle; | ||
| use crate::mac::MacClient; | ||
| use crate::mac::MacPerimeterHandle; | ||
| use crate::mac::MacTxFlags; | ||
| use crate::mac::MAC_DROP_ON_NO_DESC; | ||
| use core::ffi::CStr; | ||
| use core::fmt::Display; | ||
| use core::ptr; | ||
| use core::ptr::NonNull; | ||
| use illumos_sys_hdrs::c_int; | ||
| use illumos_sys_hdrs::datalink_id_t; | ||
| use illumos_sys_hdrs::uintptr_t; | ||
| use illumos_sys_hdrs::ENOENT; | ||
| use opte::engine::packet::Packet; | ||
| use opte::engine::packet::PacketState; | ||
| pub use sys::*; | ||
|
|
||
| /// An integer ID used by DLS to refer to a given link. | ||
| #[derive(Clone, Copy, Debug, Eq, PartialEq)] | ||
| pub struct LinkId(datalink_id_t); | ||
|
|
||
| impl LinkId { | ||
| /// Request the link ID for a device using its name. | ||
| pub fn from_name(name: impl AsRef<CStr>) -> Result<Self, LinkError> { | ||
| let mut link_id = 0; | ||
|
|
||
| unsafe { | ||
| match dls_mgmt_get_linkid(name.as_ref().as_ptr(), &mut link_id) { | ||
| 0 => Ok(LinkId(link_id)), | ||
| ENOENT => Err(LinkError::NotFound), | ||
| err => Err(LinkError::Other(err)), | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl From<LinkId> for datalink_id_t { | ||
| fn from(val: LinkId) -> Self { | ||
| val.0 | ||
| } | ||
| } | ||
|
|
||
| /// Errors encountered while querying DLS for a `LinkId`. | ||
| pub enum LinkError { | ||
| NotFound, | ||
| Other(i32), | ||
| } | ||
|
|
||
| impl Display for LinkError { | ||
| fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { | ||
| match self { | ||
| LinkError::NotFound => write!(f, "link not found"), | ||
| LinkError::Other(e) => write!(f, "unknown error ({e})"), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// A hold on an existing link managed by DLS. | ||
| #[derive(Debug)] | ||
| struct DlsLink { | ||
| inner: Option<DlsLinkInner>, | ||
| link: LinkId, | ||
| } | ||
|
|
||
| #[derive(Debug)] | ||
| struct DlsLinkInner { | ||
| dlp: *mut dls_link, | ||
| dlh: dls_dl_handle, | ||
| } | ||
|
|
||
| impl DlsLink { | ||
| /// Place a hold on an existing link. | ||
| fn hold(mph: &MacPerimeterHandle) -> Result<Self, c_int> { | ||
| let mut dlp = ptr::null_mut(); | ||
| let mut dlh = ptr::null_mut(); | ||
| let link = mph.link_id(); | ||
|
|
||
| let res = unsafe { dls_devnet_hold(link.into(), &mut dlh) }; | ||
| if res != 0 { | ||
| return Err(res); | ||
| } | ||
|
|
||
| let res = unsafe { dls_link_hold(dls_devnet_mac(dlh), &mut dlp) }; | ||
|
luqmana marked this conversation as resolved.
|
||
| if res == 0 { | ||
| Ok(Self { inner: Some(DlsLinkInner { dlp, dlh }), link }) | ||
| } else { | ||
| unsafe { dls_devnet_rele(dlh) }; | ||
| Err(res) | ||
| } | ||
| } | ||
|
|
||
| /// Release a hold on a given link. | ||
| /// | ||
| /// This operation requires that you acquire the MAC perimeter | ||
| /// for the target device. | ||
| fn release(mut self, mph: &MacPerimeterHandle) { | ||
| if let Some(inner) = self.inner.take() { | ||
| if mph.link_id() != self.link { | ||
| panic!("Tried to free link hold with the wrong MAC perimeter: saw {:?}, wanted {:?}", | ||
| mph.link_id(), self.link); | ||
| } | ||
| unsafe { | ||
| dls_link_rele(inner.dlp); | ||
| dls_devnet_rele(inner.dlh); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// Convert a hold into a `DlsStream` for packet Rx/Tx. | ||
| fn open_stream( | ||
| mut self, | ||
| mph: &MacPerimeterHandle, | ||
| ) -> Result<DlsStream, c_int> { | ||
| let Some(inner) = self.inner.as_ref() else { | ||
| panic!("attempted to open a DlsStream on freed link") | ||
| }; | ||
|
|
||
| if mph.link_id() != self.link { | ||
| panic!("Tried to open stream with the wrong MAC perimeter: saw {:?}, wanted {:?}", | ||
| mph.link_id(), self.link); | ||
| } | ||
|
|
||
| // NOTE: this is a stlouis-only way to create a dld_str_t. It | ||
| // is virtually identical to the clean-slate state from the kmemcache, | ||
| // with no rq/wq set. | ||
| let dld_str = NonNull::new(unsafe { dld_str_create_detached() }); | ||
| let Some(dld_str) = dld_str else { | ||
| self.release(mph); | ||
| return Err(-1); | ||
| }; | ||
|
|
||
| let res = unsafe { dls_open(inner.dlp, inner.dlh, dld_str.as_ptr()) }; | ||
| if res == 0 { | ||
| // DLP is held/consumed by dls_open. | ||
| _ = self.inner.take(); | ||
| Ok(DlsStream { | ||
| inner: Some(DlsStreamInner { dld_str }), | ||
| link: mph.link_id(), | ||
| } | ||
| .into()) | ||
| } else { | ||
| self.release(mph); | ||
| Err(res) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl Drop for DlsLink { | ||
| fn drop(&mut self) { | ||
| if self.inner.take().is_some() { | ||
| opte::engine::err!( | ||
| "dropped hold on link {:?} without releasing!!", | ||
| self.link | ||
| ); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// A DLS message stream on a target link, allowing packet | ||
| /// Rx and Tx. | ||
| #[derive(Debug)] | ||
| pub struct DlsStream { | ||
| inner: Option<DlsStreamInner>, | ||
| link: LinkId, | ||
| } | ||
|
|
||
| #[derive(Debug)] | ||
| struct DlsStreamInner { | ||
| dld_str: NonNull<dld_str_s>, | ||
| } | ||
|
|
||
| impl DlsStream { | ||
| pub fn open(link_id: LinkId) -> Result<Self, c_int> { | ||
| let perim = MacPerimeterHandle::from_linkid(link_id)?; | ||
| let link_handle = DlsLink::hold(&perim)?; | ||
| link_handle.open_stream(&perim) | ||
| } | ||
|
|
||
| /// Returns the ID of the link this stream belongs to. | ||
| pub fn link_id(&self) -> LinkId { | ||
| self.link | ||
| } | ||
|
|
||
| /// Send the [`Packet`] on this client, dropping if there is no | ||
| /// descriptor available | ||
| /// | ||
| /// This function always consumes the [`Packet`]. | ||
| /// | ||
| /// XXX The underlying mac_tx() function accepts a packet chain, | ||
| /// but for now we pass only a single packet at a time. | ||
| pub fn tx_drop_on_no_desc( | ||
| &self, | ||
| pkt: Packet<impl PacketState>, | ||
| hint: uintptr_t, | ||
| flags: MacTxFlags, | ||
| ) { | ||
| let Some(inner) = self.inner.as_ref() else { | ||
| // XXX: probably handle or signal an error here. | ||
| return; | ||
| }; | ||
| // We must unwrap the raw `mblk_t` out of the `pkt` here, | ||
| // otherwise the mblk_t would be dropped at the end of this | ||
| // function along with `pkt`. | ||
| let mut raw_flags = flags.bits(); | ||
| raw_flags |= MAC_DROP_ON_NO_DESC; | ||
| unsafe { | ||
| str_mdata_fastpath_put( | ||
| inner.dld_str.as_ptr(), | ||
| pkt.unwrap_mblk(), | ||
| hint, | ||
| raw_flags, | ||
| ) | ||
| }; | ||
| } | ||
| } | ||
|
|
||
| impl MacClient for DlsStream { | ||
| fn mac_client_handle(&self) -> Result<*mut mac_client_handle, c_int> { | ||
| let Some(inner) = self.inner.as_ref() else { | ||
| return Err(-1); | ||
| }; | ||
|
|
||
| Ok(unsafe { dld_str_mac_client_handle(inner.dld_str.as_ptr()) }) | ||
| } | ||
| } | ||
|
|
||
| impl Drop for DlsStream { | ||
| fn drop(&mut self) { | ||
| if let Some(inner) = self.inner.take() { | ||
| match MacPerimeterHandle::from_linkid(self.link) { | ||
| Ok(_perim) => unsafe { | ||
| // NOTE: this is a stlouis-only way to free this | ||
| // dld_str_t. It will handle the remainder of the | ||
| // cleanup for which dld_str_detach would have been | ||
| // responsible. | ||
| dls_close(inner.dld_str.as_ptr()); | ||
| dld_str_destroy_detached(inner.dld_str.as_ptr()); | ||
| }, | ||
| Err(e) => opte::engine::err!( | ||
| "couldn't acquire MAC perimeter (err {}): \ | ||
| dropped stream on link {:?} without releasing", | ||
| e, | ||
| self.link, | ||
| ), | ||
| } | ||
| } | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.