Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 8 additions & 4 deletions internal/config/cell.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,14 @@ type GalacticCellConfig struct {
// exec agent. Galactic drops traffic to them unless it is addressed to the
// guest's link-local address.
//
// Set it only once every node in the cell runs a Galactic that supports
// host-only ports. An older tap plugin ignores the list and leaves the
// ports open, and a newer one whose datapath is not loaded refuses the
// attachment.
// Set it only once every node in the cell runs a Galactic that installs
// galactic-tap-host-only. The conflist names that plugin, so a node
// without it fails the attachment rather than leaving the ports open, as
// does a node whose datapath is not loaded.
//
// Rolling a node back to a Galactic without that plugin also fails DEL
// for sandboxes whose conflist names it, so their teardown retries until
// the plugin is installed again.
HypervisorHostOnlyPorts []uint16 `json:"hypervisorHostOnlyPorts,omitempty"`
}

Expand Down
8 changes: 8 additions & 0 deletions internal/galactic/galactic/galactic.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ const (
// PluginTap is the master plugin for virtual machine guests.
PluginTap = "galactic-tap"

// PluginTapHostOnly is the tap plugin under the name only a node that
// enforces hostOnlyPorts installs, so an older node fails ADD instead of
// starting the guest with those ports open.
PluginTapHostOnly = "galactic-tap-host-only"

// PluginBGP publishes the attachment into BGP and SRv6.
PluginBGP = "galactic-bgp"

Expand Down Expand Up @@ -138,6 +143,9 @@ func Conflist(
DAN: dan,
HostOnlyPorts: hostOnlyPorts,
}
if plugin == PluginTap && len(hostOnlyPorts) > 0 {
master.Type = PluginTapHostOnly
}
if len(addresses) > 0 {
master.IPAM = &IPAM{Type: PluginIPAM, Addresses: addresses}
}
Expand Down
7 changes: 7 additions & 0 deletions internal/galactic/galactic/galactic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,13 @@ func TestConflistCarriesHostOnlyPorts(t *testing.T) {
if _, present := masterStanza(t, open)["hostOnlyPorts"]; present {
t.Errorf("attachment without host-only ports carries the field: %s", open)
}
if got := masterStanza(t, fenced)["type"]; got != PluginTapHostOnly {
t.Errorf("fenced attachment: plugin %v, want %q so a node that cannot enforce the ports fails ADD",
got, PluginTapHostOnly)
}
if got := masterStanza(t, open)["type"]; got != PluginTap {
t.Errorf("attachment without host-only ports: plugin %v, want %q", got, PluginTap)
}
}

func masterStanza(t *testing.T, raw string) map[string]any {
Expand Down
Loading