Documentation
¶
Overview ¶
Package network defines host-local networks and attaches instances to them, assigning their addresses and naming their interfaces. It is portable: it drives the host through Host, which internal/hostnet implements.
Index ¶
- Constants
- Variables
- func Assignable(ipNet *net.IPNet, ip net.IP) bool
- func BridgeName(networkName string) string
- func CheckSubnetOverlap(n Network, networks []Network, hostSubnets []netip.Prefix) error
- func IFBName(instanceID string) string
- func MetricDescriptions() []metric.Description
- func ParseSubnet(s string) (*net.IPNet, error)
- func TAPName(instanceID string) string
- type Allocation
- type AttachOptions
- type Attachment
- type Bandwidth
- type Config
- type DNSServers
- type Host
- type Manager
- func (m *Manager) Allocate(n Network, instanceID, staticIP string) (Allocation, error)
- func (m *Manager) Allocation(network, instanceID string) (Allocation, error)
- func (m *Manager) AttachInstance(ctx context.Context, n Network, instanceID string, opts AttachOptions) (Attachment, error)
- func (m *Manager) Collect(ch chan<- prometheus.Metric)
- func (m *Manager) ConnectInstance(ctx context.Context, n Network, instanceID string) error
- func (m *Manager) Create(ctx context.Context, spec Spec) (Network, error)
- func (m *Manager) Delete(ctx context.Context, nameOrID string) error
- func (m *Manager) Describe(ch chan<- *prometheus.Desc)
- func (m *Manager) DetachInstance(ctx context.Context, n Network, instanceID string)
- func (m *Manager) EnsureDefault(subnet string) error
- func (m *Manager) Forget(network string) error
- func (m *Manager) InstanceAt(network, ip string) (string, bool)
- func (m *Manager) List(nameOrID string) ([]Allocation, error)
- func (m *Manager) Network(nameOrID string) (Network, error)
- func (m *Manager) Networks() []Network
- func (m *Manager) Reconcile(networks []string, live map[string]struct{}) (int, error)
- func (m *Manager) Release(network, instanceID string) error
- func (m *Manager) SetupBridges(ctx context.Context)
- type Network
- type PortMapping
- type Recorder
- type Spec
- type Store
Constants ¶
const ( MinMTU = 576 MaxMTU = 9000 )
The MTU range a network may have.
const ( // DefaultNameserver is the nameserver a network forwards to. DefaultNameserver = "8.8.8.8" // DefaultMTU is a network's MTU. DefaultMTU = 1500 )
Defaults applied to a network that does not specify them.
const ( ProtocolTCP = "tcp" ProtocolUDP = "udp" )
The protocols a port mapping may name.
const DefaultName = "default"
DefaultName is the name of the default network, which the daemon creates itself and an instance joins when it names no network.
Variables ¶
var ErrNoAvailableIPs = errdefs.ResourceExhausted("the network has no free addresses left")
ErrNoAvailableIPs is returned when a network's subnet has no address left to give out.
Functions ¶
func Assignable ¶
Assignable reports whether ip can be given out on ipNet: an address in it other than its network and broadcast addresses.
func BridgeName ¶
BridgeName returns the bridge name for a network: "dicer-<name>" if it fits in an interface name, otherwise "dbr-" and a hash of the name.
func CheckSubnetOverlap ¶ added in v0.4.0
CheckSubnetOverlap returns an ErrExists error if n's subnet overlaps one of networks, or one of hostSubnets, whose addresses n's would hide.
func IFBName ¶ added in v0.4.0
IFBName returns the name of the IFB device an instance's upload is shaped on: "ifb-" followed by the same hash as its TAP device's name.
func MetricDescriptions ¶ added in v0.4.0
func MetricDescriptions() []metric.Description
MetricDescriptions returns the descriptions of every metric the network manager serves, for the reference.
func ParseSubnet ¶
ParseSubnet parses a network's subnet: an IPv4 CIDR with room for at least one instance. The result is normalised, so "10.0.0.5/24" is 10.0.0.0/24.
Types ¶
type Allocation ¶ added in v0.4.0
type Allocation struct {
NetworkID string `yaml:"network_id"`
InstanceID string `yaml:"instance_id"`
IP string `yaml:"ip"`
MAC string `yaml:"mac"`
// InstanceName and TAPDevice are derived when the allocation is read
// and not stored.
InstanceName string `yaml:"-"`
TAPDevice string `yaml:"-"`
}
Allocation is one instance's address on a network, held for as long as the instance is defined.
type AttachOptions ¶ added in v0.4.0
type AttachOptions struct {
// StaticIP is the address the instance takes. Empty takes a free one.
StaticIP string
// Bandwidth limits what the instance's guest sends and receives.
Bandwidth Bandwidth
// Ports are the host ports forwarded to the instance's address.
Ports []PortMapping
// Disconnected keeps the instance's TAP device off the network's bridge
// until ConnectInstance, so that nothing the guest sends reaches the
// network. A fork needs this: it wakes with the address of the instance
// it is a copy of.
Disconnected bool
}
AttachOptions says how an instance attaches to a network.
type Attachment ¶ added in v0.4.0
type Attachment struct {
Allocation Allocation
// TAPDevice is the host's end of the guest's network interface.
TAPDevice string
// Nameservers are the nameservers the guest asks: the gateway while the
// network's DNS server runs, and its upstream nameservers otherwise.
Nameservers []string
}
Attachment is an instance's place on a network, as its VMM and guest are given it.
type Bandwidth ¶
Bandwidth limits the bytes per second an instance's guest sends and receives. Zero is unlimited.
type Config ¶
type Config struct {
// Dir is the directory the allocation tables are kept in.
Dir string
// Store keeps the network definitions. Creating, deleting and listing
// networks need it, and allocating addresses does not.
Store Store
// Host sets up the networks' bridges and the instances' TAP devices
// and published ports, and says which subnets a new network may not
// overlap. Nil leaves the host alone and skips that check.
Host Host
// DNSServers serve each network's guests their nameserver. Nil serves
// none.
DNSServers DNSServers
// Events records what happens to networks. Nil records nothing.
Events Recorder
// Logger is where the Manager logs. Nil is slog.Default().
Logger *slog.Logger
}
Config configures a Manager.
type DNSServers ¶ added in v0.4.0
type DNSServers interface {
// Serve starts serving a network, unless it already is. The network's
// bridge must be up.
Serve(ctx context.Context, nw Network) error
// Stop stops serving a network.
Stop(network string)
// Serving reports whether a network is served.
Serving(network string) bool
}
DNSServers answer the DNS queries of each network's guests, on the network's gateway address.
type Host ¶ added in v0.4.0
type Host interface {
// SetupBridge sets up a network's bridge, or makes sure it is as it
// should be when it is already there.
SetupBridge(ctx context.Context, nw *Network) error
// TeardownBridge removes a network's bridge, logging what it cannot.
TeardownBridge(ctx context.Context, nw *Network)
// Subnets returns the subnets the host's interfaces are on, which a new
// network may not overlap.
Subnets() ([]netip.Prefix, error)
// CreateTAP creates an instance's TAP device, limited to bandwidth and
// off the network's bridge. On failure the device may be left behind
// for RemoveTAP.
CreateTAP(ctx context.Context, nw *Network, instanceID string, bandwidth Bandwidth) error
// ConnectTAP puts an instance's TAP device on the network's bridge.
ConnectTAP(ctx context.Context, nw *Network, instanceID string) error
// RemoveTAP removes an instance's TAP device, logging what it cannot.
RemoveTAP(ctx context.Context, nw *Network, instanceID string)
// PublishPorts forwards host ports to the instance's address, replacing
// any it already published.
PublishPorts(ctx context.Context, nw *Network, allocation *Allocation, ports []PortMapping) error
// UnpublishPorts removes every port the instance published, logging
// what it cannot.
UnpublishPorts(ctx context.Context, instanceID string)
}
Host makes networks and their instances' attachments real on the host: bridges with their firewall rules, TAP devices and published ports. It also says which subnets the host is already on.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager creates and deletes networks, whose definitions a Store keeps, with their bridges and DNS servers, and attaches instances to them. It persists the instances' address allocations, so an instance keeps its address across restarts. Allocations are released on delete and reconciled at daemon start.
The allocation tables are read from disk once, when the Manager is made, and kept in memory, so that looking an address up -- as the networks' DNS servers do for every query -- reads no file. The Manager must be the only writer of its directory. It is safe for concurrent use.
func NewManager ¶
NewManager returns a Manager storing its allocation tables under cfg.Dir, with those already there read. One that cannot be read fails the calls about its network, not NewManager.
func (*Manager) Allocate ¶
func (m *Manager) Allocate(n Network, instanceID, staticIP string) (Allocation, error)
Allocate assigns an address to an instance, or returns the one it holds. A staticIP must be in the subnet and free.
func (*Manager) Allocation ¶ added in v0.4.0
func (m *Manager) Allocation(network, instanceID string) (Allocation, error)
Allocation returns the allocation held by an instance on a network, or an errdefs.ErrNotFound error if it holds none.
func (*Manager) AttachInstance ¶ added in v0.4.0
func (m *Manager) AttachInstance( ctx context.Context, n Network, instanceID string, opts AttachOptions, ) (Attachment, error)
AttachInstance gives an instance its address on a network, or the one it already holds, and sets up its TAP device and published ports. On failure the address is kept, and nothing is left on the host.
func (*Manager) Collect ¶ added in v0.4.0
func (m *Manager) Collect(ch chan<- prometheus.Metric)
Collect implements prometheus.Collector: each defined network's address pool, as it is now. A network whose allocations cannot be read is left out.
func (*Manager) ConnectInstance ¶ added in v0.4.0
ConnectInstance puts the TAP device of an instance attached with Disconnected on its network's bridge.
func (*Manager) Create ¶ added in v0.4.0
Create defines the network spec asks for and sets up its bridge, refusing a name that is taken and a subnet another network or the host is on. Unset gateway, MTU and nameservers take their defaults. A network whose bridge cannot be set up is not created.
func (*Manager) Delete ¶ added in v0.4.0
Delete removes a network's definition, its bridge and its allocations, refusing the default network and one an instance or snapshot is on.
func (*Manager) Describe ¶ added in v0.4.0
func (m *Manager) Describe(ch chan<- *prometheus.Desc)
Describe implements prometheus.Collector.
func (*Manager) DetachInstance ¶ added in v0.4.0
DetachInstance removes an instance's published ports and TAP device. Its address is kept, and so is the network's bridge, which lives as long as the network. Failures are logged rather than returned.
func (*Manager) EnsureDefault ¶ added in v0.4.0
EnsureDefault defines the default network on subnet, unless it already exists. An existing one is left as it is. Its bridge is set up, as every network's, by SetupBridges.
func (*Manager) Forget ¶
Forget discards a network's whole allocation table, for use when the network itself is deleted. Forgetting a network with none is not an error.
func (*Manager) InstanceAt ¶ added in v0.4.0
InstanceAt returns the ID of the instance holding ip on a network. It reports false if none does, or if the network's allocation table cannot be read.
func (*Manager) List ¶
func (m *Manager) List(nameOrID string) ([]Allocation, error)
List returns every allocation on a network, by name or ID. The slice is the caller's. A Manager without a Store, which only allocates addresses, takes the network's name alone.
func (*Manager) Reconcile ¶
Reconcile drops allocations on the given networks held by instances not in live, and returns how many it released.
func (*Manager) Release ¶
Release drops an instance's allocation. Releasing one that does not exist is not an error, so cleanup paths can call it unconditionally.
func (*Manager) SetupBridges ¶ added in v0.4.0
SetupBridges sets up every network's bridge, with its DNS server, as the daemon starts: a reboot removes them. A bridge that cannot be set up is logged, and costs only its own network's instances their start.
type Network ¶ added in v0.4.0
type Network struct {
ID string `yaml:"id"`
Name string `yaml:"name"`
Gateway string `yaml:"gateway"`
Subnet string `yaml:"subnet"`
Bridge string `yaml:"bridge"`
Nameservers []string `yaml:"nameservers,omitempty"`
MTU int `yaml:"mtu,omitempty"`
Isolated bool `yaml:"isolated,omitempty"`
// Internal stops the network's instances reaching anything beyond it:
// the outside, other networks, the host's services and upstream
// nameservers.
Internal bool `yaml:"internal,omitempty"`
CreatedAt time.Time `yaml:"created_at"`
UpdatedAt time.Time `yaml:"updated_at"`
// TotalIPs and FreeIPs count the addresses for instances. They are
// computed when the network is read and not stored.
TotalIPs int64 `yaml:"-"`
FreeIPs int64 `yaml:"-"`
}
Network is a bridged network instances attach to, with an address pool of its own.
func New ¶ added in v0.4.0
New returns the network spec asks for, with a new ID, or an invalid argument error. It does not check the subnet against other networks or the host's: see CheckSubnetOverlap.
func (Network) IPCounts ¶ added in v0.4.0
IPCounts returns how many addresses the network has for instances and how many of them are free with allocated taken. The network, broadcast and gateway addresses are excluded. Both are zero if the subnet is invalid.
func (Network) Netmask ¶ added in v0.4.0
Netmask returns the network's subnet mask in dotted-quad form.
type PortMapping ¶ added in v0.4.0
type PortMapping struct {
// HostIP is the host address to publish on. Empty means every
// non-loopback address.
HostIP string `yaml:"host_ip,omitempty" json:"host_ip,omitempty"`
HostPort uint16 `yaml:"host_port" json:"host_port"`
GuestPort uint16 `yaml:"guest_port" json:"guest_port"`
// Protocol is tcp or udp. Empty means tcp.
Protocol string `yaml:"protocol,omitempty" json:"protocol,omitempty"`
}
PortMapping publishes a guest port on the host.
func (PortMapping) EffectiveProtocol ¶ added in v0.4.0
func (p PortMapping) EffectiveProtocol() string
EffectiveProtocol returns the mapping's protocol, filling in the default.
func (PortMapping) Overlaps ¶ added in v0.4.0
func (p PortMapping) Overlaps(other PortMapping) bool
Overlaps reports whether two mappings claim the same host port. A mapping on every address overlaps one on any single address.
func (PortMapping) String ¶ added in v0.4.0
func (p PortMapping) String() string
String is the mapping as a person writes it: "[hostIP:]hostPort:guestPort/protocol".
func (PortMapping) Validate ¶ added in v0.4.0
func (p PortMapping) Validate() error
Validate returns an invalid argument error if the mapping cannot be published.
type Recorder ¶ added in v0.4.0
Recorder records what happens to networks. It is declared here, and satisfied by internal/event, so that this package reports what it does without knowing who listens.