Skip to content

vmbus_server: preserve proxy pipe offer data - #4208

Merged
Will Wright (will-j-wright) merged 1 commit into
microsoft:mainfrom
will-j-wright:vmbus-proxy-preserve-pipe-offer-data
Aug 12, 2026
Merged

vmbus_server: preserve proxy pipe offer data#4208
Will Wright (will-j-wright) merged 1 commit into
microsoft:mainfrom
will-j-wright:vmbus-proxy-preserve-pipe-offer-data

Conversation

@will-j-wright

Copy link
Copy Markdown
Contributor

Problem

When relaying a named-pipe channel offer from vmbusproxy, vmbus_server converts the offer to ChannelType::Pipe. That type retains only whether the pipe uses byte or message mode.

Converting the resulting OfferParams to OfferParamsInternal therefore reconstructs UserDefinedData from zeroes and preserves only the pipe mode. Any additional pipe-specific offer data supplied by the channel provider is lost.

Fix

For proxy-originated pipe channels, preserve the complete original UserDefinedData after performing the normal typed conversion and pipe-mode validation.

This keeps the existing semantic channel classification while ensuring the provider-owned offer payload is relayed unchanged.

The override is intentionally limited to this boundary:

  • Native pipe offers continue to use canonical generated data.
  • Interface offers already preserve their complete user-defined payload.
  • Hyper-V socket translation remains typed and canonicalized.
  • Other channel behavior and offer flags are unchanged.

This is implemented in the proxy integration rather than From<OfferParams> because OfferParams::Pipe no longer contains the original payload, and the generic conversion is also used by native channel providers.

The change was validated with a downlevel Windows guest scenario that previously failed during boot.

Copilot AI lite review requested due to automatic review settings August 10, 2026 22:25

Copilot AI left a comment

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.

Pull request overview

This PR fixes loss of proxy-provided named-pipe offer payload data when vmbus_server relays offers from vmbusproxy. It keeps the semantic ChannelType::Pipe classification (byte vs message mode) while ensuring the full provider-owned UserDefinedData is preserved across the OfferParams -> OfferParamsInternal conversion boundary.

Changes:

  • Convert the proxy offer to OfferParamsInternal once, then override user_defined for ChannelType::Pipe with the original proxy-provided UserDefined payload.
  • Keep all other channel kinds and offer flag behavior unchanged.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@SvenGroot Sven Groot (SvenGroot) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Rather than working around this in proxyintegration, I think we should update ChannelType::Pipe to support these flags and handle them in the conversion to OfferParamsInternal so we can cleanly reconstruct user_data from the "native" OpenVMM structures.

Since I think it is possible for a pipe to include custom other offer data (though I'm not sure if that's actually used right now), ChannelType::Pipe also should allow specifying the remaining 112 bytes of custom data.

Copilot AI review requested due to automatic review settings August 10, 2026 22:58
@will-j-wright
Will Wright (will-j-wright) force-pushed the vmbus-proxy-preserve-pipe-offer-data branch from dc753cd to 951e789 Compare August 10, 2026 22:58

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated no new comments.

Suppressed comments (1)

vm/devices/vmbus/vmbus_server/src/proxyintegration.rs:576

  • The PR description says proxy-originated pipe offers should preserve the complete original UserDefinedData, but this change only extracts and re-encodes PipeFlags (last 4 bytes). OfferParamsInternal::from still starts from UserDefinedData::new_zeroed() and only writes pipe_type + pipe_flags, so any provider-defined bytes in the rest of the 120-byte payload are still discarded.
                ChannelType::Pipe {
                    message_mode,
                    pipe_flags: *offer.UserDefined.as_pipe_flags(),
                }

@github-actions

Copy link
Copy Markdown

@will-j-wright
Will Wright (will-j-wright) force-pushed the vmbus-proxy-preserve-pipe-offer-data branch from 951e789 to 39bf621 Compare August 11, 2026 20:11
Copilot AI review requested due to automatic review settings August 11, 2026 20:12

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated no new comments.

Suppressed comments (1)

vm/devices/vmbus/vmbus_core/src/protocol.rs:596

  • PipeFlags is interpreted from the trailing bytes of UserDefinedData (via UserDefinedData::as_pipe_flags*), but that encoding detail isn’t documented here. Adding a short doc comment on PipeFlags will make the implicit layout contract easier to discover and less likely to be broken by future changes.
#[derive(Inspect)]
#[bitfield(u32)]
#[derive(IntoBytes, FromBytes, Immutable, KnownLayout, PartialEq, Eq, Protobuf)]
#[mesh(transparent)]
pub struct PipeFlags {

Comment on lines +422 to +431
pub fn as_pipe_flags(&self) -> &PipeFlags {
let offset = self.0.len() - size_of::<PipeFlags>();
PipeFlags::ref_from_bytes(&self.0[offset..]).expect("from bytes should not fail")
}

pub fn as_pipe_flags_mut(&mut self) -> &mut PipeFlags {
let offset = self.0.len() - size_of::<PipeFlags>();
PipeFlags::mut_from_bytes(&mut self.0[offset..]).expect("from bytes should not fail")
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think instead of these functions, it would be better to incorporate the flags in PipeUserDefinedParameters (along with the 112-byte padding in between).

Comment thread vm/devices/vmbus/vmbus_channel/src/bus.rs
Copilot AI review requested due to automatic review settings August 11, 2026 21:16
@will-j-wright
Will Wright (will-j-wright) force-pushed the vmbus-proxy-preserve-pipe-offer-data branch from 39bf621 to 06f40d6 Compare August 11, 2026 21:16

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated no new comments.

Suppressed comments (2)

vm/devices/vmbus/vmbus_channel/src/bus.rs:331

  • ChannelType::Pipe now requires a full 112-byte user_defined payload plus pipe_flags, even though the PR description intends the passthrough to be limited to proxy-originated offers. This forces all native pipe providers to populate placeholder defaults (as seen in the updated call sites) and makes it easier for non-proxy providers to accidentally start relying on non-canonical pipe payloads.

Consider keeping the public ChannelType::Pipe API focused on the semantic classification (message_mode) and moving the proxy-only passthrough into an optional wrapper (e.g. pipe_offer: Option<PipeOfferData>), or a separate enum variant used only by the proxy integration.

        message_mode: bool,
        /// Provider-defined offer data.
        user_defined: PipeUserDefinedData,
        /// Pipe capabilities.
        pipe_flags: PipeFlags,

vm/devices/vmbus/vmbus_core/src/protocol.rs:624

  • UserDefinedData::as_pipe_params(_mut) uses ref_from_bytes(..).expect("from bytes should not fail"), but the new PipeUserDefinedParameters layout only has a size assert. Adding an alignment assert would make this invariant explicit and avoid a future runtime panic if the struct’s alignment ever changes.
static_assertions::const_assert_eq!(
    size_of::<PipeUserDefinedParameters>(),
    size_of::<UserDefinedData>()
);

@github-actions

Copy link
Copy Markdown

@will-j-wright
Will Wright (will-j-wright) merged commit 1868394 into microsoft:main Aug 12, 2026
97 of 101 checks passed
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