Skip to content

Support for External Jumbo Frames (RFD 689)#10472

Open
rcgoodfellow wants to merge 11 commits into
mainfrom
ry/opte-984
Open

Support for External Jumbo Frames (RFD 689)#10472
rcgoodfellow wants to merge 11 commits into
mainfrom
ry/opte-984

Conversation

@rcgoodfellow
Copy link
Copy Markdown
Contributor

@rcgoodfellow rcgoodfellow commented May 20, 2026

Implements the Omicron side of RFD 689.

Depends on:

A CLI/SDK build to drive this new functionality is here

Docs for this new feature are here

Some other fixes included here.

  • Updates lldpd to fix client/server version mismatch.
  • Don't squash lldpd 404 errors into 500 Oxide API errors.
  • Add support for static IPv4 routes over IPv6 nexthops (this was an oversight in initial IPv6 routing support and something I needed for my testing setup).

Testing

Lab Environment Performance

I've tested this on berlin. When the fleet level jumbo flag is set and instances have opted into jumbo, they come up with an 8500 byte MTU in linux. The numbers I see for TCP from berlin running through one of the external d4x4 routers is.

  • 1500 MTU
    • ~6 gbps single stream
    • ~10 gbps 16 streams (-P 16 on the iperf3 client)
  • 8500 MTU
    • ~12 gbps single stream
    • ~30 gbps 16 streams

For UDP

  • 1500 MTU
    • ~1 gbps single stream
    • ~3 gbps 16 streams
  • 8500 MTU
    • ~3 gbps single stream
    • ~11 gbps 16 streams

I also tested that a pair of clients with and without jumbo enabled can communicate over both TCP and UDP.

Control Bits

The fleet-level jumbo enable and instance-level jumbo enable have been tested in combination. For an instance to have jumbo frames enabled, both the fleet level setting and the instance level setting must be set to true. I've tested all combinations of these settings with an instance restart in between changes to pick up the setting, and things behave as expected.

Comment thread openapi/nexus/nexus-2026052000.0.0-7e307e.json Outdated
Comment thread sled-agent/src/services.rs
Comment thread tools/install_opte.sh
curl -fL -o "$P5P_PATH" "$P5P_URL"

RC=0
pfexec pkg install -g "$P5P_PATH" driver/network/opte || RC=$?
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This pattern was not working for me in a4x2 with Helios 3. The new form does work.

@rcgoodfellow rcgoodfellow marked this pull request as ready for review May 24, 2026 05:39
@rcgoodfellow rcgoodfellow changed the title implement RFD 689 Support for Jumbo Frames (RFD 689) May 24, 2026
@rcgoodfellow rcgoodfellow changed the title Support for Jumbo Frames (RFD 689) Support for External Jumbo Frames (RFD 689) May 26, 2026
@rcgoodfellow rcgoodfellow requested a review from FelixMcFelix May 26, 2026 19:22
Copy link
Copy Markdown
Contributor

@FelixMcFelix FelixMcFelix left a comment

Choose a reason for hiding this comment

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

Thanks Ry, I mainly have questions around the organisation of versioned types.

Comment thread nexus/src/app/instance.rs
Comment on lines +580 to +583
let settings = self
.db_datastore
.system_networking_settings_view(opctx)
.await?;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It's been a while since I've paged some of the authz stuff in, but this datastore method first checks the user has read access to the fleet. Will a user of an instance create/update endpoint necessarily have that? If not we'd need to read the value directly or construct a new OpContext at the right auth level.

This would apply to the other callsites of this function in instance.rs as well, if it needs handling.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch. Removed the fleet read requirement from system_networking_settings_view and replace with comment explaining why there is not an opctx.authorize there.

Comment thread nexus/external-api/src/lib.rs Outdated
Comment thread nexus/external-api/src/lib.rs Outdated
query_params: Query<
PaginatedByNameOrId<latest::project::ProjectSelector>,
>,
) -> Result<HttpResponseOk<ResultsPage<Instance>>, HttpError> {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Again I haven't been on the versioned API surface much front (having had my head in illumos-gate for so long), but the bare Instance type as contrasted with latest::instance::Instance feels like it's out of the general pattern for most other endpoints:

Suggested change
) -> Result<HttpResponseOk<ResultsPage<Instance>>, HttpError> {
) -> Result<HttpResponseOk<ResultsPage<v2025_11_20_00::instance::Instance>>, HttpError> {

But looking into it it seems like any prior change to, e.g., fn instance_update has just exposed the bare Instance type. I don't know if this is maybe because it's the first time Instance itself has actually been updated since we started handling versioning this way?

My read on this is that we need to move external::Instance into versions::initial::instance, and then update those references.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah that's probably a better way to do it. Moved to this approach, the reference updates are most of what is expanding the footprint of this PR in the latest commit.

Comment thread nexus/external-api/src/lib.rs Outdated
Comment thread nexus/external-api/src/lib.rs Outdated
Comment thread nexus/src/app/instance.rs
Comment on lines +710 to +714
let settings = self
.db_datastore
.system_networking_settings_view(opctx)
.await?;
if !settings.external_jumbo_frames_opt_in_enabled {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ditto on fleet read authz.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Handled this inside system_networking_settings_view

Comment thread nexus/src/app/instance.rs
Comment on lines +1702 to +1706
let settings = self
.db_datastore
.system_networking_settings_view(opctx)
.await?;
if settings.external_jumbo_frames_opt_in_enabled {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ditto on fleet read authz.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Handled this inside system_networking_settings_view

Comment thread common/src/address.rs Outdated
/// Default Ethernet MTU for external-facing OPTE ports, in bytes. Used when
/// the per-instance jumbo-frames opt-in is unset or when the fleet-wide opt-in
/// is disabled.
pub const EXTERNAL_DEFAULT_MTU: u32 = 1500;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We're not actually reading this anywhere. Should we be sending this down rather than None? Obviously OPTE will pick the same value, but I being explicit about this as a choice the control plane is making seems beneficial to me.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed

Comment thread nexus/types/versions/src/external_jumbo_frames/instance.rs
"auto_restart_policy": {
"nullable": true,
"description": "The auto-restart policy for this instance.\n\nThis policy determines whether the instance should be automatically restarted by the control plane on failure. If this is `null`, any explicitly configured auto-restart policy will be unset, and the control plane will select the default policy when determining whether the instance can be automatically restarted.\n\nCurrently, the global default auto-restart policy is \"best-effort\", so instances with `null` auto-restart policies will be automatically restarted. However, in the future, the default policy may be configurable through other mechanisms, such as on a per-project basis. In that case, any configured default policy will be used if this is `null`.",
"description": "The auto-restart policy for this instance.",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It looks as though something's happened to lose the extra docs information here (and on a few more fields of Instance)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The extra docs are back now.

"auto_restart_policy": {
"nullable": true,
"description": "The auto-restart policy configured for this instance, or `null` if no explicit policy has been configured.\n\nThis policy determines whether the instance should be automatically restarted by the control plane on failure. If this is `null`, the control plane will use the default policy when determining whether or not to automatically restart this instance, which may or may not allow it to be restarted. The value of the `auto_restart_enabled` field indicates whether the instance will be auto-restarted, based on its current policy or the default if it has no configured policy.",
"allOf": [
{
"$ref": "#/components/schemas/InstanceAutoRestartPolicy"
}
]
},

Not sure what happened there. Maybe it was a consequence of the composition with serde flatten that was there before the review feedback edits?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants