plugin

package
v2.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 31, 2026 License: GPL-3.0 Imports: 52 Imported by: 0

Documentation

Overview

Package plugin is the Docker side of docker-net-dhcp: it serves the two libnetwork contracts that make this a network plugin, /NetworkDriver.* and /IpamDriver.*, on one Unix socket in one process, beside two paths that belong to neither contract and are served on the same socket anyway: /Plugin.Health and /metrics.

Every container gets its address from the DHCP server the LAN already runs (a router, a Fritz!Box, dnsmasq), over `bridge`, `macvlan` or `ipvlan`, for IPv4 and IPv6. The protocol exchange is not here: it runs in-process on the dhcp-golib engine behind the pkg/dhcp chassis, so there is no external DHCP client to install and no client process per container. What is here is everything Docker-shaped around it: the network and endpoint lifecycle, the link and namespace work each mode needs, the renewal manager per endpoint, the state directory that lets an enabled plugin be restarted without losing what it was serving, and the counters and health document an operator reads back.

The two IPAM shapes

Docker's built-in IPAM is never the allocator: it would allocate from a subnet of its own choosing and collide with the real LAN. There are two supported ways to say so, and which one a network uses is fixed at `docker network create`:

  • `--ipam-driver null`, what 1.x and 2.0 shipped, where Docker allocates nothing and the /NetworkDriver.CreateEndpoint handler answers libnetwork with the leased address. All three modes, IPv4 and IPv6.
  • `--ipam-driver <this plugin>` (v2.1.0+, #110), where the /IpamDriver.* handlers put the lease into Docker's own address management, which is what makes `docker run --ip` and Compose `ipv4_address` work. `bridge` and `macvlan`: ipvlan (#949) is refused at network creation, because the alternative is an endpoint that fails at container start with an error naming neither. IPv6 is switched on with `-o ipv6=true` or `-o ipv6_mode=`, and CreateEndpoint reports the address (#960). A typed IPv6 `--subnet` is a pool of its own (#1132), with `ipv6_mode=dhcp` only; `--ipv6` without one stays refused. The DHCPv6 server picks the address and `--ip6` is a hint to it; a reply naming another address than `--ip6`, or one outside the subnet, is refused and released.

The exported surface is a wire contract, not a library API

Most of the types below are the JSON payloads libnetwork sends and expects, from moby's libnetwork/drivers/remote/api and libnetwork/ipams/remote/api. They are declared here because this plugin talks to the daemon over HTTP and JSON: the wire shape is the contract, and importing moby's structs would hide a rename behind a compile that still succeeded.

The one entry point meant for callers is NewPlugin, which cmd/net-dhcp calls with Options built from the plugin's environment; NewPlugin(Options{}) is a valid production configuration. This package is not built to be embedded in another program, and nothing outside this module is expected to import it: the supported interface to a running plugin is the socket.

Operator documentation lives at https://claymore666.github.io/docker-net-dhcp/.

Index

Constants

View Source
const (
	RouteTypeNextHop = 0
	RouteTypeOnLink  = 1
)

libnetwork's StaticRoute.RouteType values (moby/libnetwork docs/remote.md): 0 has a NextHop, 1 is on-link.

View Source
const (
	// HostIfnameOff leaves the host-side veth named after the endpoint.
	HostIfnameOff = ""
	// HostIfnameContainerName names it after the container, as `docker ps` prints it.
	HostIfnameContainerName = "container_name"
	// HostIfnameHostname names it after the container's hostname, which is not unique on a host.
	HostIfnameHostname = "hostname"
)

The values of the `host_ifname` network option (#978).

View Source
const (
	ModeBridge  = "bridge"
	ModeMacvlan = "macvlan"
	ModeIPvlan  = "ipvlan"
)

Network attachment modes selected by the `mode` driver option.

View Source
const (
	// ReleaseNever is the default: no path sends a DHCPRELEASE or a
	// DHCPv6 Release, which is exactly the v1.9.0 behaviour (#800).
	ReleaseNever = "never"
	// ReleaseOnStop releases when the endpoint leaves its sandbox: every `docker stop`, every `docker rm` of a
	// running container and every `docker network disconnect` (#962).
	ReleaseOnStop = "on_stop"
	// ReleaseOnRemove releases at the record's tombstone deadline, because libnetwork calls DeleteEndpoint at stop and
	// never at `docker rm` of a stopped container (#984).
	ReleaseOnRemove = "on_remove"
)

The values of the `release_lease` network option (#962); off by default, as a host does not release at power-off (#800).

View Source
const (
	MacvlanModeBridge   = "bridge"
	MacvlanModeVEPA     = "vepa"
	MacvlanModePrivate  = "private"
	MacvlanModePassthru = "passthru"
	IPvlanModeL2        = "l2"
	IPvlanModeL3        = "l3"
)

Sub-mode values of macvlan_mode and ipvlan_mode, spelled as `ip -d link` prints them (#905).

View Source
const CLIOptionsKey string = "com.docker.network.generic"

CLIOptionsKey is the key used in create network options by the CLI for custom options

View Source
const DriverName string = "net-dhcp"

DriverName is the name of the Docker Network Driver

View Source
const MinEngineAPIVersion = "1.41"

MinEngineAPIVersion is the API the floor row reported (engine-matrix run 34594749584), and nothing refuses on it (#670).

View Source
const MinEngineIfnameVersion = "29.8"

MinEngineIfnameVersion is the lowest engine measured to apply a requested interface name: 28.5.2 and 29.7.2 ignored it and 29.8.0 applied it (moby/moby#52866, #125, #670).

View Source
const MinEngineV6GatewayWaitVersion = "28.0"

MinEngineV6GatewayWaitVersion is the first engine line that waits for the link to run before it looks up the IPv6 gateway's route; 24.0.9 and 27.5.1 do not and refused 1 start in 20 each, route not found (moby osl, #1149).

View Source
const MinEngineVersion = "20.10"

MinEngineVersion is the lowest Docker Engine line the engine matrix measured the plugin on, read by scripts/engine-floor.sh from this exact declaration (#670).

View Source
const ProductionEngineVersion = "26.1.5"

ProductionEngineVersion is the engine build the maintained deployment runs, which the lane measures through the newest image of its line, 26.1.4 (#1014).

Variables

View Source
var (
	// ErrLinkLocalNoTime is a claim with no whole window left before the engine's deadline.
	ErrLinkLocalNoTime = errors.New("no time left before the engine's deadline to probe another link-local address")
	// ErrLinkLocalTooManyConflicts is RFC 3927 section 2.2.1's MAX_CONFLICTS reached.
	ErrLinkLocalTooManyConflicts = errors.New("every link-local address tried was in use (RFC 3927 section 2.2.1's MAX_CONFLICTS)")
)

Functions

func IsDHCPPlugin

func IsDHCPPlugin(driver string) bool

IsDHCPPlugin checks if a Docker network driver is an instance of this plugin

Types

type CapabilitiesResponse

type CapabilitiesResponse struct {
	Scope             string
	ConnectivityScope string
	// GwAllocChecker makes libnetwork call /NetworkDriver.GwAllocCheck, whose 404 is then a real error (#110).
	GwAllocChecker bool
}

CapabilitiesResponse returns whether or not this network is global or local

type CreateEndpointRequest

type CreateEndpointRequest struct {
	NetworkID  string
	EndpointID string
	Interface  *EndpointInterface
	Options    map[string]interface{}
	// contains filtered or unexported fields
}

CreateEndpointRequest is sent by the daemon when an endpoint should be created

type CreateEndpointResponse

type CreateEndpointResponse struct {
	Interface *EndpointInterface
}

CreateEndpointResponse is sent as a response to a CreateEndpointRequest

type CreateNetworkRequest

type CreateNetworkRequest struct {
	NetworkID string
	Options   map[string]interface{}
	IPv4Data  []*IPAMData
	IPv6Data  []*IPAMData
}

CreateNetworkRequest is sent by the daemon when a network needs to be created

type DHCPNetworkOptions

type DHCPNetworkOptions struct {
	// Mode selects the attachment strategy: bridge (the default, needs `bridge`), macvlan or ipvlan (need `parent`).
	Mode   string `mapstructure:"mode"`
	Bridge string
	Parent string `mapstructure:"parent"`
	// Gateway, if set, overrides the DHCP-supplied default gateway, e.g. to egress via a VPN router.
	Gateway string
	// IPv6 switches DHCPv6 on and equals `ipv6_mode=dhcp`; read it only through ipv6Enabled (#817).
	IPv6 bool
	// IPv4Off is stored from the engine's enable_ipv4=false at CreateNetwork and refused as an option (#1135).
	IPv4Off bool `mapstructure:"ipv4_off"`
	// IPv6Mode is off, dhcp, slaac or auto, proto.Mode6's spellings; a value disagreeing with IPv6 is refused (#817).
	IPv6Mode string `mapstructure:"ipv6_mode"`
	// IPv6AutoStrict makes `ipv6_mode=auto` fail an endpoint whose DHCPv6 server stays silent instead of falling back
	// to SLAAC and counting dhcpv6_auto_fallbacks (#817).
	IPv6AutoStrict bool `mapstructure:"ipv6_auto_strict"`
	// IPv6MainPrefix, a CIDR, picks which SLAAC address Docker is told about, since RFC 4862 section 5.5.3 forms one
	// per autonomous prefix; unset or unmatched uses the first advertised prefix (#818).
	IPv6MainPrefix string `mapstructure:"ipv6_main_prefix"`
	// IPv6Temporary puts an IA_TA (RFC 8415 section 21.5) beside the IA_NA in every Solicit and Request (#927).
	IPv6Temporary bool `mapstructure:"ipv6_temporary"`
	// IPv6PD asks for an IA_PD prefix of this length beside the address, 0 for none (RFC 8415 section 21.21, #214).
	IPv6PD int `mapstructure:"ipv6_pd"`
	// IPv6IID is how SLAAC forms the interface identifier: eui64 (unset) from the MAC, or stable-privacy per RFC 7217
	// from a secret in STATE_DIR (#1032).
	IPv6IID      string        `mapstructure:"ipv6_iid"`
	LeaseTimeout time.Duration `mapstructure:"lease_timeout"`
	// IgnoreConflicts skips CreateNetwork's check for another Docker network on this bridge or range; it is unrelated
	// to conflict_check's RFC 5227 detection on the wire.
	IgnoreConflicts bool `mapstructure:"ignore_conflicts"`
	// ConflictCheck is the RFC 5227 mode, wait, async or off, empty meaning dhcp.DefaultConflictCheck (#882, D23).
	ConflictCheck string `mapstructure:"conflict_check"`
	SkipRoutes    bool   `mapstructure:"skip_routes"`
	// PropagateDNS writes option 6 or 23 into the container's /etc/resolv.conf on every bind or renew.
	PropagateDNS bool `mapstructure:"propagate_dns"`
	// PropagateMTU sets the container link's MTU from option 26 on every bind or renew.
	PropagateMTU bool `mapstructure:"propagate_mtu"`
	// MTU, 68..65535, is set on every container link this network creates and is then its only source; 0 is unset (#1037).
	MTU int `mapstructure:"mtu"`
	// ClientID overrides the derived option 61 for every endpoint, sent with type byte 0x00; see resolveClientID
	// (#371).
	ClientID string `mapstructure:"client_id"`
	// VendorClass overrides option 60, default "docker-net-dhcp", for class-based server policy.
	VendorClass string `mapstructure:"vendor_class"`
	// UserClass is the one class value of DHCPv4 option 77 (RFC 3004), 1 to 254 octets; empty sends no option (#1120).
	UserClass string `mapstructure:"user_class"`
	// RapidCommit puts option 80 (RFC 4039) in every DISCOVER and option 14 (RFC 8415 18.2.1) in every Solicit (#1031, #926).
	RapidCommit bool `mapstructure:"rapid_commit"`
	// ValidateDHCP runs a one-shot DHCP probe on a macvlan or ipvlan parent at CreateNetwork (#108).
	ValidateDHCP bool `mapstructure:"validate_dhcp"`
	// RegisterDNS sends the hostname in option 81 (v4) and 39 (v6) with S=1; without it v6 sends no name (#261, #1029).
	RegisterDNS bool `mapstructure:"register_dns"`
	// AuditLog appends every lease event on this network to STATE_DIR/leases.jsonl (#109).
	AuditLog bool `mapstructure:"audit_log"`

	// DHCPServers is an ordered, exhaustive preference list of DHCPv4 servers, e.g. "1.1.1.1,2.2.2.2" (#111).
	DHCPServers string `mapstructure:"dhcp_servers"`
	// DenyServers lists DHCPv4 servers never to take a lease from, composed with DHCPServers by serverPolicy (#669).
	DenyServers string `mapstructure:"dhcp_deny_servers"`
	// ReleaseLease is `never` (the default, leases expire) or `on_stop` (release when the endpoint leaves) (#962).
	ReleaseLease string `mapstructure:"release_lease"`
	// HostIfname names bridge mode's host-side link: empty for `dh-` plus 12 hex, or `container_name` or `hostname`
	// (#978).
	HostIfname string `mapstructure:"host_ifname"`
	// RequireMAC refuses an endpoint whose MAC the user did not set, so a MAC-keyed reservation always matches (#1036).
	RequireMAC bool `mapstructure:"require_mac"`
	// LinkLocalFallback gives an endpoint an RFC 3927 169.254/16 address when no DHCPv4 lease arrives in time (#904).
	LinkLocalFallback bool `mapstructure:"link_local_fallback"`
	// MacvlanMode is the macvlan child's kernel mode, bridge (the default), vepa, private or passthru (#905).
	MacvlanMode string `mapstructure:"macvlan_mode"`
	// IPvlanMode is the ipvlan child's kernel mode; l2 (the default) is the only accepted value, see parseIPvlanMode
	// (#905).
	IPvlanMode string `mapstructure:"ipvlan_mode"`
	// Vlan is an 802.1Q ID; the children attach to `<parent>.<id>`, created when missing (#902).
	Vlan string `mapstructure:"vlan"`
	// ForceCreate creates a bridge-mode network with parent although the firewall check expects its frames dropped;
	// the check still runs and logs its verdict (#903).
	ForceCreate bool `mapstructure:"force_create"`
}

DHCPNetworkOptions contains options for the DHCP network driver

type DelegatedPrefixHealth added in v2.5.0

type DelegatedPrefixHealth struct {
	Prefix         string `json:"prefix"`
	PreferredUntil string `json:"preferred_until,omitempty"`
	ExpiresAt      string `json:"expires_at,omitempty"`
}

DelegatedPrefixHealth is one IA_PD prefix of an endpoint's DHCPv6 lease on /Plugin.Health (#214).

type DeleteEndpointRequest

type DeleteEndpointRequest struct {
	NetworkID  string
	EndpointID string
}

DeleteEndpointRequest is sent by the daemon when an endpoint needs to be removed

type DeleteNetworkRequest

type DeleteNetworkRequest struct {
	NetworkID string
}

DeleteNetworkRequest is sent by the daemon when a network needs to be removed

type EndpointHealth

type EndpointHealth struct {
	Endpoint string `json:"endpoint"`
	Network  string `json:"network"`
	Mode     string `json:"mode"`
	// Address is the lease the renewal client currently holds, in CIDR form.
	Address string `json:"address,omitempty"`
	// LeaseState is `bound` when the client holds the lease its last recorded event bound, `link_local` on the
	// RFC 3927 fallback (#904), `acquiring` otherwise.
	LeaseState string `json:"lease_state"`
	// RenewAt, RebindAt and ExpiresAt are T1, T2 and the lease end as RFC 3339 times; an empty
	// ExpiresAt on a bound endpoint is an infinite lease (RFC 2131 section 3.3).
	RenewAt   string `json:"renew_at,omitempty"`
	RebindAt  string `json:"rebind_at,omitempty"`
	ExpiresAt string `json:"expires_at,omitempty"`
	// IPv6TemporaryAddress is the first IA_TA address of the endpoint's DHCPv6 lease, CIDR form, empty if none (#927).
	IPv6TemporaryAddress string `json:"ipv6_temporary_address,omitempty"`
	// NAT64Prefixes are the RFC 8781 PREF64 prefixes of the last IPv6 lease or router event, absent if none (#1028).
	NAT64Prefixes []string `json:"nat64_prefixes,omitempty"`
	// The lease's still-valid IA_PD prefixes, and whether one overlapped another endpoint's when granted (#214).
	DelegatedPrefixes []DelegatedPrefixHealth `json:"delegated_prefixes,omitempty"`
	PrefixOverlap     bool                    `json:"prefix_overlap,omitempty"`
	// Server is the DHCP server that granted the lease (option 54).
	Server string `json:"server,omitempty"`
	// LastEvent is the v4 client's most recent lifecycle event, such as `bound`, `renew` or `nak`, with its time.
	LastEvent   string `json:"last_event,omitempty"`
	LastEventAt string `json:"last_event_at,omitempty"`
	// ConflictCheck is the RFC 5227 mode this client runs in and ACDPhase is where that check has got to.
	ConflictCheck string `json:"conflict_check"`
	ACDPhase      string `json:"acd_phase"`
}

EndpointHealth is one entry of /Plugin.Health's `endpoints` array, the per-container state the counters cannot show.

type EndpointInterface

type EndpointInterface struct {
	Address     string
	AddressIPv6 string
	MacAddress  string
}

EndpointInterface contains endpoint interface information

type GwAllocCheckRequest

type GwAllocCheckRequest struct {
	Options map[string]interface{}
}

GwAllocCheckRequest asks the network driver whether a gateway address is needed; it carries only driver options.

type GwAllocCheckResponse

type GwAllocCheckResponse struct {
	SkipIPv4 bool
	SkipIPv6 bool
}

GwAllocCheckResponse answers it.

type HealthCheck

type HealthCheck struct {
	Status        string `json:"status"`
	ObservedValue int64  `json:"observedValue"`
	ObservedUnit  string `json:"observedUnit"`
	// Time is when the counter behind this check last moved, not when the response was built.
	Time string `json:"time"`
	// Output is omitted for a passing check, per section 4.8.
	Output string `json:"output,omitempty"`
}

HealthCheck is one element of the `checks` object.

type HealthResponse

type HealthResponse struct {
	// Status and Checks follow draft-inadarei-api-health-check-06 sections 3.1 and 3.6; `fail` is `healthy: false`.
	Status string `json:"status"`
	// Version, Commit and Library are the build identity (pkg/buildinfo), also the net_dhcp_build_info labels.
	Version string `json:"version"`
	Commit  string `json:"commit"`
	Library string `json:"library"`
	// EngineVersion and APIVersion are what the daemon answered at startup, or `unknown` when its socket was not yet
	// serving (#383, #670).
	EngineVersion string `json:"engine_version"`
	APIVersion    string `json:"api_version"`
	Healthy       bool   `json:"healthy"`
	// InstanceID names the serving process, so two reads compare as a delta only when it matches (#405).
	InstanceID      string  `json:"instance_id"`
	UptimeSeconds   float64 `json:"uptime_seconds"`
	ActiveEndpoints int     `json:"active_endpoints"`
	// LinkLocalEndpoints counts the endpoints on the RFC 3927 fallback now, from the array's snapshot (#904).
	LinkLocalEndpoints int   `json:"link_local_endpoints"`
	PendingHints       int   `json:"pending_hints"`
	RecoveredOK        int32 `json:"recovered_ok"`
	// RecoveryFailed counts failed recoveries of a still-running container, which then has no renewal client; Healthy-affecting.
	RecoveryFailed int32 `json:"recovery_failed"`
	// RecoveryDeferred counts recoveries retried once the daemon socket came up (#383); not Healthy-affecting.
	RecoveryDeferred int32 `json:"recovery_deferred"`
	// RecoveryAbortedContainerGone counts recoveries abandoned because the container had exited (#376); not
	// Healthy-affecting.
	RecoveryAbortedContainerGone int32 `json:"recovery_aborted_container_gone"`
	// RecoveryNetworkGone counts networks removed between NetworkList and NetworkInspect (#648); not Healthy-affecting.
	RecoveryNetworkGone int32 `json:"recovery_network_gone"`
	// StaleNetworksDropped counts persisted networks Docker no longer had at start, whose file and pool binding were
	// removed (#1174); not Healthy-affecting.
	StaleNetworksDropped int32 `json:"stale_networks_dropped"`
	// RecoveryFingerprintsSkipped counts adopted endpoints with no hostname to fingerprint, so no tombstone (#721);
	// not Healthy-affecting.
	RecoveryFingerprintsSkipped int32 `json:"recovery_fingerprints_skipped"`
	// RecoveryAlreadyManaged counts endpoints a Join registered before the recovery walk (#480); not Healthy-affecting.
	RecoveryAlreadyManaged int32 `json:"recovery_already_managed"`
	// JoinStartFailures counts renewal client Start failures at Join (#317); Healthy-affecting.
	JoinStartFailures int32 `json:"join_start_failures"`
	// JoinAbortedContainerGone counts attaches abandoned because the container exited first (#373); not
	// Healthy-affecting.
	JoinAbortedContainerGone int32 `json:"join_aborted_container_gone"`
	// JoinAbortedNoContainer counts attaches no container claimed, whose address is left to expire (#566, #800,
	// #962); not Healthy-affecting.
	JoinAbortedNoContainer int32 `json:"join_aborted_no_container"`

	// JoinAttachSlow counts attaches that succeeded after outlasting AwaitTimeout (#406); not healthy-affecting.
	JoinAttachSlow int32 `json:"join_attach_slow"`

	// JoinAttachCompleted counts successful attaches, the population the three duration buckets partition.
	JoinAttachCompleted int32 `json:"join_attach_completed"`
	// JoinAttachUnder1s and JoinAttach1sToBudget with JoinAttachSlow sum to JoinAttachCompleted (#403).
	JoinAttachUnder1s    int32 `json:"join_attach_under_1s"`
	JoinAttach1sToBudget int32 `json:"join_attach_1s_to_budget"`
	// JoinAttachMsMax is the longest successful attach in milliseconds, saturating at MaxInt32 (#403).
	JoinAttachMsMax int32 `json:"join_attach_ms_max"`

	// RestartLinkUpWaited counts child links brought up after the departing link released the address (#408); not
	// healthy-affecting.
	RestartLinkUpWaited int32 `json:"restart_link_up_waited"`
	// RestartLinkUpTimeouts counts that wait outlasting its budget, failing with `address already in use` (#422); not
	// healthy-affecting.
	RestartLinkUpTimeouts int32 `json:"restart_link_up_timeouts"`

	// JoinAbortedEndpointLeft counts attaches cancelled because the endpoint left first; not healthy-affecting.
	JoinAbortedEndpointLeft int32 `json:"join_aborted_endpoint_left"`
	// JoinAbortedLinkWithdrawn counts attaches whose located link left the sandbox (#1236); not healthy-affecting.
	JoinAbortedLinkWithdrawn int32 `json:"join_aborted_link_withdrawn"`
	// TombstoneWriteFailures counts failed tombstone writes and reads refused since #724; Healthy-affecting.
	TombstoneWriteFailures int32 `json:"tombstone_write_failures"`
	// TombstoneQuarantines counts unparseable tombstone files moved aside as tombstones.json.corrupt-<ts>, since
	// something wrote garbage into stateDir (#724); Healthy-affecting.
	TombstoneQuarantines int32 `json:"tombstone_quarantines"`
	// UnsafeHostnamesRejected counts container hostnames dropped for a control character (#692); not healthy-affecting.
	UnsafeHostnamesRejected int32 `json:"unsafe_hostnames_rejected"`

	// HostnamesAppliedLate, HostnameLookupFailures and HostnameApplyFailures are the outcomes of a late v4 hostname
	// (#961).
	HostnamesAppliedLate   int32 `json:"hostnames_applied_late"`
	HostnameLookupFailures int32 `json:"hostname_lookup_failures"`
	HostnameApplyFailures  int32 `json:"hostname_apply_failures"`

	// HostIfnamesApplied, HostIfnameConflicts and HostIfnameFailures are the bridge-mode host link naming outcomes
	// (#978).
	HostIfnamesApplied  int32 `json:"host_ifnames_applied"`
	HostIfnameConflicts int32 `json:"host_ifname_conflicts"`
	HostIfnameFailures  int32 `json:"host_ifname_failures"`
	// UnsafeOptionValuesDropped counts server-chosen DHCP strings refused or truncated (#703, #704); not
	// healthy-affecting.
	UnsafeOptionValuesDropped int32 `json:"unsafe_option_values_dropped"`
	// NetworkOptionsRejected counts endpoint operations refusing a network's stored options (#705, #727); not
	// healthy-affecting.
	NetworkOptionsRejected int32 `json:"network_options_rejected"`
	// IPAMReplayHits counts stored endpoint addresses confirmed from a lease record at a daemon restart (#110).
	IPAMReplayHits int32 `json:"ipam_replay_hits"`
	// IPAMReplayMiss counts stored endpoint addresses refused because no lease record holds them (#110).
	IPAMReplayMiss int32 `json:"ipam_replay_miss"`
	// IPAMRebindAmbiguous counts address requests that met more than one removed endpoint, so the server chose (#110).
	IPAMRebindAmbiguous int32 `json:"ipam_rebind_ambiguous"`
	// IPAMReserveDuplicateMAC counts address requests refused for a hardware address already leasing (#110).
	IPAMReserveDuplicateMAC int32 `json:"ipam_reserve_duplicate_mac"`
	// IPAMStrandedRecords counts CREATED records a previous process left without an endpoint, given up at start-up
	// (#1047).
	IPAMStrandedRecords int32 `json:"ipam_stranded_records"`
	// IPAMReleaseUnknown counts released addresses no lease record holds, the normal order after a retain (#110).
	IPAMReleaseUnknown int32 `json:"ipam_release_unknown"`
	// DNSPropagationPIDMismatches counts DNS writes refused because the container PID was recycled (#688).
	DNSPropagationPIDMismatches int32 `json:"dns_propagation_pid_mismatches"`
	// NetnsPIDMismatches counts sandbox netns opens refused because the container PID was recycled (#695).
	NetnsPIDMismatches int32 `json:"netns_pid_mismatches"`
	// SandboxKeyEntries, SandboxKeyEntryFailures and SandboxPIDFallbacks count the sandbox key route, its refusals and
	// the /proc/<pid>/ns/net fallback, the evidence for whether the PID route is still needed (#725).
	SandboxKeyEntries       int32 `json:"sandbox_key_entries"`
	SandboxKeyEntryFailures int32 `json:"sandbox_key_entry_failures"`
	SandboxPIDFallbacks     int32 `json:"sandbox_pid_fallbacks"`

	// SandboxKeyNotANamespace (the expected arm under sandbox_netns_propagation=0), SandboxKeyNotPermitted (a
	// non-default `dockerd --exec-root`), SandboxKeyWrongNSType, SandboxKeyUnavailable and SandboxKeyAbsent sum to
	// SandboxKeyEntryFailures (#725).
	SandboxKeyAbsent        int32 `json:"sandbox_key_absent"`
	SandboxKeyNotPermitted  int32 `json:"sandbox_key_not_permitted"`
	SandboxKeyNotANamespace int32 `json:"sandbox_key_not_a_namespace"`
	SandboxKeyWrongNSType   int32 `json:"sandbox_key_wrong_ns_type"`
	SandboxKeyUnavailable   int32 `json:"sandbox_key_unavailable"`

	// DockerAPINonGETRefusals counts Docker API requests refused for a method other than GET (#691).
	DockerAPINonGETRefusals int32 `json:"docker_api_non_get_refusals"`
	// DHCPRoutesApplied counts option-121 routes handed to Docker, and DHCPDefaultRouteSuperseded the Joins whose
	// routes cover 0.0.0.0/0 by union, so egress bypasses the option-3 router (#700).
	DHCPRoutesApplied          int32 `json:"dhcp_routes_applied"`
	DHCPDefaultRouteSuperseded int32 `json:"dhcp_default_route_superseded"`
	// MTURefused counts option-26 MTUs outside the applied range, which leave the link MTU unchanged (#702).
	MTURefused int32 `json:"mtu_refused"`
	// TombstonesConsumed counts CreateEndpoints that gave a recreated container its previous MAC and IP (#386).
	TombstonesConsumed int32 `json:"tombstones_consumed"`
	// LeaseChanged counts renewals where the server returned a different IP than last recorded (#100).
	LeaseChanged int32 `json:"lease_changed"`
	// AddressConflicts is the sum of AddressConflictsV4 and AddressConflictsV6 over the lease's life, RFC 5227
	// sections 2.1 and 2.4 (#524); Healthy-affecting.
	AddressConflicts int32 `json:"address_conflicts"`
	// ACDProbesSent, ACDAnnouncementsSent, ACDConflictsDetected and ACDARPSendFailures are the library's RFC 5227
	// counters, which show whether a zero AddressConflicts had any probe behind it (#524, #882).
	ACDProbesSent        int32 `json:"acd_probes_sent"`
	ACDAnnouncementsSent int32 `json:"acd_announcements_sent"`
	ACDConflictsDetected int32 `json:"acd_conflicts_detected"`
	ACDARPSendFailures   int32 `json:"acd_arp_send_failures"`
	// ACDResumedUnchecked counts endpoints resumed before their RFC 5227 section 2.1 check finished, re-run on the
	// INIT-REBOOT ACK (#882); a `warn` check.
	ACDResumedUnchecked int32 `json:"acd_resumed_unchecked"`

	// SandboxNetnsVisible is the sandbox netns entries visible at request time, -1 when the directory is unreadable
	// (a missing mount) and 0 with endpoints attached when it is mounted from the wrong place (#567).
	SandboxNetnsVisible int32 `json:"sandbox_netns_visible"`

	// SandboxNetnsPropagation is 1 when a later daemon mount under the sandbox netns directory reaches this process, 0
	// when the mount is private so attaches take the PID route, and -1 when mountinfo is unreadable (#417).
	SandboxNetnsPropagation int32 `json:"sandbox_netns_propagation"`

	// SandboxNetnsInitMounts is the sandbox netns mounts in PID 1's table: -2 shared namespace, -1 unreadable, else
	// the count, and under a nested engine PID 1 is that engine's init (#417).
	SandboxNetnsInitMounts int32 `json:"sandbox_netns_init_mounts"`

	// LeasesObtained and the wire counters below are the sums of their _v4 and _v6 halves, without `_total` (#730).
	LeasesObtained int32 `json:"leases_obtained"`
	LeasesRenewed  int32 `json:"leases_renewed"`
	// RenewalsUnanswered counts renewal requests that got no answer, first moving at the RFC 2131 section 4.4.5
	// retransmission (half the time to T2, floor 60 s), measured 4h30m after T1 on a 24 h lease (#940).
	RenewalsUnanswered int32 `json:"renewals_unanswered"`
	// DHCPServerTierFallbacks counts steps down the dhcp_servers ladder, one per silent preferred entry (#111, #731).
	DHCPServerTierFallbacks int32 `json:"dhcp_server_tier_fallbacks"`
	// DHCPServerPolicyExhausted counts acquisitions no dhcp_servers entry answered (#111); not Healthy-affecting.
	DHCPServerPolicyExhausted int32 `json:"dhcp_server_policy_exhausted"`
	// DHCPServerPolicyTimeouts counts the subset of dhcp_timeouts on dhcp_servers-restricted endpoints (#731).
	DHCPServerPolicyTimeouts int32 `json:"dhcp_server_policy_timeouts"`
	DHCPTimeouts             int32 `json:"dhcp_timeouts"`
	// ClientStopFailures counts renewal clients that did not stop cleanly, not a missing release (#800, #962).
	ClientStopFailures int32 `json:"client_stop_failures"`
	// ReleasesSent and ReleaseFailures are the sums of their per-family halves, ReleaseFailures a `warn` check (#962).
	ReleasesSent    int32 `json:"releases_sent"`
	ReleaseFailures int32 `json:"release_failures"`
	// ReleasesReclaimed counts on_remove addresses a running container reused inside the restart window, so the
	// record closed without a datagram (#984).
	ReleasesReclaimed int32 `json:"releases_reclaimed"`
	// NAKsReceived counts server NAKs on renewal or rebind, each widening the lease_changed divergence (#128).
	NAKsReceived int32 `json:"naks_received"`
	// DisplacedStops counts recovery-registered managers displaced by a Join for the same endpoint.
	DisplacedStops int32 `json:"displaced_stops"`
	// ParentLinkWaits and ParentLinkWaitTimeouts count operations queued on a shared parent NIC and those that gave up
	// after parentGateBudget, since a parent is a macvlan or an ipvlan port, never both (#486, #549).
	ParentLinkWaits        int32 `json:"parent_link_waits"`
	ParentLinkWaitTimeouts int32 `json:"parent_link_wait_timeouts"`
	// LedgerWriteFailures counts failed appends to the audit_log lease ledger (#109); not Healthy-affecting.
	LedgerWriteFailures int32 `json:"ledger_write_failures"`
	// IfnameUnsupported counts custom interface names on an engine that does not apply them (#125, #670).
	IfnameUnsupported int32 `json:"ifname_unsupported"`
	// StateFileChmodFailures counts state files the startup sweep could not tighten, plus an unreadable STATE_DIR
	// (#804).
	StateFileChmodFailures int32 `json:"state_file_chmod_failures"`

	// LeaseChangedV4 and the per-family counters below are stored, and the un-suffixed field is their sum, since a
	// total recovered by subtraction can decrease and reads as a reset to Prometheus (#212, #730).
	LeaseChangedV4   int32 `json:"lease_changed_v4"`
	LeasesObtainedV4 int32 `json:"leases_obtained_v4"`
	LeasesRenewedV4  int32 `json:"leases_renewed_v4"`
	// RenewalsUnansweredV4 is the IPv4 half of RenewalsUnanswered.
	RenewalsUnansweredV4 int32 `json:"renewals_unanswered_v4"`
	DHCPTimeoutsV4       int32 `json:"dhcp_timeouts_v4"`
	NAKsReceivedV4       int32 `json:"naks_received_v4"`
	// ClientStopFailuresV4 is the v4 half of ClientStopFailures.
	ClientStopFailuresV4 int32 `json:"client_stop_failures_v4"`
	// ReleasesSentV4 and ReleaseFailuresV4 are the IPv4 `release_lease` pair (#962).
	ReleasesSentV4    int32 `json:"releases_sent_v4"`
	ReleaseFailuresV4 int32 `json:"release_failures_v4"`
	// ReleasesReclaimedV4 is the IPv4 half of ReleasesReclaimed (#984).
	ReleasesReclaimedV4 int32 `json:"releases_reclaimed_v4"`
	// AddressConflictsV4 is the RFC 5227 half, the only one comparable with the ARP-based ACD counters.
	AddressConflictsV4 int32 `json:"address_conflicts_v4"`

	// LeaseChangedV6 and the v6 fields below are written by the DHCPv6 client, so a zero means it did not happen
	// (#911).
	LeaseChangedV6   int32 `json:"lease_changed_v6"`
	LeasesObtainedV6 int32 `json:"leases_obtained_v6"`
	LeasesRenewedV6  int32 `json:"leases_renewed_v6"`
	// RenewalsUnansweredV6 counts unanswered Renew and Rebind messages (RFC 9915 sections 18.2.4 and 18.2.5).
	RenewalsUnansweredV6 int32 `json:"renewals_unanswered_v6"`
	DHCPTimeoutsV6       int32 `json:"dhcp_timeouts_v6"`
	NAKsReceivedV6       int32 `json:"naks_received_v6"`
	// AddressConflictsV6 counts addresses the kernel's DAD (RFC 4862 section 5.4) found in use, declined under RFC 9915
	// section 18.2.8; Docker's record is not updated for the replacement, as for v4 (#104).
	AddressConflictsV6 int32 `json:"address_conflicts_v6"`
	// ClientStopFailuresV6 is the v6 share of ClientStopFailures, with any release counted apart (#608, #962).
	ClientStopFailuresV6 int32 `json:"client_stop_failures_v6"`
	// ReleasesSentV6 and ReleaseFailuresV6 count DHCPv6 Release messages (RFC 9915 section 18.2.7), read per family.
	ReleasesSentV6    int32 `json:"releases_sent_v6"`
	ReleaseFailuresV6 int32 `json:"release_failures_v6"`
	// ReleasesReclaimedV6 is the DHCPv6 half of ReleasesReclaimed, a second record with its own deadline (#984).
	ReleasesReclaimedV6 int32 `json:"releases_reclaimed_v6"`
	// DHCPv6ConfigOnly counts DHCPv6 information replies on a network with the RA "other config" flag (#815).
	DHCPv6ConfigOnly int32 `json:"dhcpv6_config_only"`
	// DHCPv6NotOffered counts endpoints with no DHCPv6 address because the RA advertised no managed DHCPv6, and with
	// autoconf=0 no SLAAC address either (#821, #868).
	DHCPv6NotOffered int32 `json:"dhcpv6_not_offered"`
	// DHCPv6NoRouterAdvert counts endpoints with no DHCPv6 address because no router advertisement arrived (#868).
	DHCPv6NoRouterAdvert int32 `json:"dhcpv6_no_router_advert"`
	// DHCPv6Refused counts endpoints failed by a server Status Code other than Success (RFC 9915 21.13, #816).
	DHCPv6Refused int32 `json:"dhcpv6_refused"`
	// DHCPv6NoServer counts endpoints failed because a managed segment's DHCPv6 server never answered (#816).
	DHCPv6NoServer int32 `json:"dhcpv6_no_server"`
	// DHCPv6SLAACNoPrefix counts SLAAC endpoints failed because no advertised prefix could form an address (RFC 4862
	// 5.5.3, #816, #817).
	DHCPv6SLAACNoPrefix int32 `json:"dhcpv6_slaac_no_prefix"`

	// DHCPv6SLAACNoAddress counts SLAAC endpoints where no address formed inside the acquisition budget (#818).
	DHCPv6SLAACNoAddress int32 `json:"dhcpv6_slaac_no_address"`

	// IPv6SLAACAddresses and IPv6AddressesWithdrawn count addresses installed and removed, not endpoints (#818, #819).
	IPv6SLAACAddresses     int32 `json:"ipv6_slaac_addresses"`
	IPv6AddressesWithdrawn int32 `json:"ipv6_addresses_withdrawn"`

	// IPv6SLAACPrefixesIgnored counts prefixes skipped under RFC 4862 section 5.5.3 or the eight-address cap.
	IPv6SLAACPrefixesIgnored int32 `json:"ipv6_slaac_prefixes_ignored"`

	// IPv6MainPrefixUnmatched counts endpoints where no address fell inside ipv6_main_prefix (#819).
	IPv6MainPrefixUnmatched int32 `json:"ipv6_main_prefix_unmatched"`
	// DHCPv6AutoFallbacks counts `ipv6_mode=auto` endpoints that formed a SLAAC address after DHCPv6 went silent
	// (#817).
	DHCPv6AutoFallbacks int32 `json:"dhcpv6_auto_fallbacks"`
	// DHCPv6AbsenceRemembered counts auto attaches that skipped the Solicit on a network remembered silent (#1038).
	DHCPv6AbsenceRemembered int32 `json:"dhcpv6_absence_remembered"`
	// IPv6LinkEnableFailures counts container links IPv6 could not be enabled on before the DHCPv6 client started.
	IPv6LinkEnableFailures int32 `json:"ipv6_link_enable_failures"`
	// RouterAdvertGuardFailures counts RA guard sysctl steps that failed or read back wrong on a container link (#875).
	RouterAdvertGuardFailures int32 `json:"router_advert_guard_failures"`
	// IPv6RouterWithdrawn counts container v6 default routes removed for a Router Lifetime of 0 (#821).
	IPv6RouterWithdrawn int32 `json:"ipv6_router_withdrawn"`
	// The delegated prefix aggregates added and removed, and endpoints whose prefix overlapped another's (#214).
	IPv6PrefixRoutesInstalled int32 `json:"ipv6_prefix_routes_installed"`
	IPv6PrefixRoutesWithdrawn int32 `json:"ipv6_prefix_routes_withdrawn"`
	IPv6PrefixOverlaps        int32 `json:"ipv6_prefix_overlaps"`

	// RouterSolicitsSent and the router counters below are the library's RFC 4861 counters folded across every
	// DHCPv6 manager, solicitations under section 6.3.7 (#814).
	RouterSolicitsSent int32 `json:"router_solicits_sent"`
	// RouterAdvertsSeen counts decoded advertisements and RouterAdvertsRefused undecodable ones (#814).
	RouterAdvertsSeen    int32 `json:"router_adverts_seen"`
	RouterAdvertsRefused int32 `json:"router_adverts_refused"`
	// RouterAdvertOptionsIgnored counts refused options, not frames, in otherwise read advertisements (#814).
	RouterAdvertOptionsIgnored int32 `json:"router_advert_options_ignored"`
	// RouterTableEntriesDropped and RouterTableEntriesEvicted count the router table caps in force (RFC 8106 6.2 (d)).
	RouterTableEntriesDropped int32 `json:"router_table_entries_dropped"`
	RouterTableEntriesEvicted int32 `json:"router_table_entries_evicted"`

	// The FORCERENEW and Reconfigure counters, folded across every DHCP client, persistent and one-shot (#1119). The
	// refused ones describe the server's messages, not a fault, and are not healthy-affecting.
	ForcerenewsRenewed         int32 `json:"forcerenews_renewed"`
	ForcerenewsAlreadyRenewing int32 `json:"forcerenews_already_renewing"`
	ForcerenewsRefused         int32 `json:"forcerenews_refused"`
	ForcerenewsAckRefused      int32 `json:"forcerenews_ack_refused"`
	ReconfiguresAccepted       int32 `json:"reconfigures_accepted"`
	ReconfiguresRefused        int32 `json:"reconfigures_refused"`

	// Checks is one single-element array per named check, as the health-check draft's section 4 asks.
	Checks map[string][]HealthCheck `json:"checks"`
	// Endpoints is one entry per registered manager, kept out of /metrics as a cardinality decision.
	Endpoints []EndpointHealth `json:"endpoints"`
}

HealthResponse is the /Plugin.Health payload, whose Healthy latches false for the process's life once a counter marked Healthy-affecting below moves, and only a plugin restart clears it (#638, #724).

type IPAMData

type IPAMData struct {
	AddressSpace string
	Pool         string
	Gateway      string
	AuxAddresses map[string]interface{}
}

IPAMData contains IPv4 or IPv6 addressing information

type InfoRequest

type InfoRequest struct {
	NetworkID  string
	EndpointID string
}

InfoRequest is sent by the daemon when querying endpoint information

type InfoResponse

type InfoResponse struct {
	Value map[string]string
}

InfoResponse is endpoint information sent in response to an InfoRequest

type InterfaceName

type InterfaceName struct {
	SrcName   string
	DstPrefix string
	DstName   string
}

InterfaceName is the Join interface name, whose DstName remote drivers get from engine 29.8.0 (moby/moby#52866); 28.5.2 and 29.7.2 were measured naming the interface by DstPrefix and index (#125, #670).

type IpamAddressSpacesResponse

type IpamAddressSpacesResponse struct {
	LocalDefaultAddressSpace  string
	GlobalDefaultAddressSpace string
}

IpamAddressSpacesResponse answers /IpamDriver.GetDefaultAddressSpaces.

type IpamCapabilitiesResponse

type IpamCapabilitiesResponse struct {
	RequiresMACAddress    bool
	RequiresRequestReplay bool
}

IpamCapabilitiesResponse answers /IpamDriver.GetCapabilities.

type JoinRequest

type JoinRequest struct {
	NetworkID  string
	EndpointID string
	SandboxKey string
	Options    map[string]interface{}
}

JoinRequest is sent by the Daemon when an endpoint needs be joined to a network

type JoinResponse

type JoinResponse struct {
	InterfaceName         InterfaceName
	Gateway               string
	GatewayIPv6           string
	StaticRoutes          []*StaticRoute
	DisableGatewayService bool
}

JoinResponse is sent in response to a JoinRequest

type LeaveRequest

type LeaveRequest struct {
	NetworkID  string
	EndpointID string
}

LeaveRequest is sent by the daemon when a endpoint is leaving a network

type Options

type Options struct {
	// AwaitTimeout caps the polling helpers (sandbox readiness, link rename, netns appearance).
	AwaitTimeout time.Duration

	// DHCPv6AbsenceMemory is how long an auto network remembers a silent DHCPv6 server; nil is the default, zero is
	// off (#1038).
	DHCPv6AbsenceMemory *time.Duration

	// RequestCaptureDir tees libnetwork request bodies into that directory for replay fixtures, test builds only
	// (#644).
	RequestCaptureDir string
}

Options carries the plugin's runtime knobs from config.json's environment variables, zero meaning the default.

type Plugin

type Plugin struct {
	// contains filtered or unexported fields
}

Plugin is the DHCP network plugin.

func NewPlugin

func NewPlugin(opts Options) (*Plugin, error)

NewPlugin creates a Plugin, taking documented defaults for zero Options fields.

func (*Plugin) Close

func (p *Plugin) Close() error

Close shuts the HTTP server first, so no Join registers a manager mid-stop, then stops every DHCP client without releasing, as the containers still run and a release would invite a duplicate assignment (#800, #962).

func (*Plugin) CreateEndpoint

CreateEndpoint builds the host-side link, runs a one-shot DHCP acquisition and stashes the result for Join. A failed create gets no Join or DeleteEndpoint, so the hint is dropped here, where every path returns (#1183).

func (*Plugin) CreateNetwork

func (p *Plugin) CreateNetwork(r CreateNetworkRequest) error

CreateNetwork validates the options, the parent interface, the IPAM driver and bridge ownership.

func (*Plugin) DeleteEndpoint

func (p *Plugin) DeleteEndpoint(ctx context.Context, r DeleteEndpointRequest) error

DeleteEndpoint removes the endpoint's host-side link, best-effort in macvlan mode where the netns reaped it.

func (*Plugin) DeleteNetwork

func (p *Plugin) DeleteNetwork(r DeleteNetworkRequest) error

DeleteNetwork removes the network's state and stops its managers, since libnetwork sends no Leave for stopped containers (#46).

func (*Plugin) EndpointOperInfo

func (p *Plugin) EndpointOperInfo(ctx context.Context, r InfoRequest) (InfoResponse, error)

EndpointOperInfo retrieves some info about an existing endpoint

func (*Plugin) Join

func (p *Plugin) Join(ctx context.Context, r JoinRequest) (JoinResponse, error)

Join hands Docker the host-side link and routes, then starts the persistent DHCP client for the endpoint.

func (*Plugin) Leave

func (p *Plugin) Leave(ctx context.Context, r LeaveRequest) error

Leave stops the persistent DHCP client for an endpoint

func (*Plugin) Listen

func (p *Plugin) Listen(bindSock string) error

Listen starts the plugin server

func (*Plugin) ListenMetrics

func (p *Plugin) ListenMetrics(addr string) error

ListenMetrics starts the /metrics TCP listener, off unless METRICS_ADDR is set because the plugin runs in the host network namespace with CAP_NET_ADMIN and CAP_SYS_ADMIN (#651).

func (*Plugin) ReleaseAddress

func (p *Plugin) ReleaseAddress(req ReleaseAddressRequest) error

func (*Plugin) RequestAddress

RequestAddress dispatches on the record store, since libnetwork does not persist endpoint IPAM options (#110).

func (*Plugin) RequestPool

func (p *Plugin) RequestPool(req RequestPoolRequest) (RequestPoolResponse, error)

RequestPool answers with the canonical pool identity and writes nothing durable, so the start-up replay derives the stored PoolID (#110).

type ReleaseAddressRequest

type ReleaseAddressRequest struct {
	PoolID  string
	Address string
}

ReleaseAddressRequest gives one address back.

type ReleasePoolRequest

type ReleasePoolRequest struct {
	PoolID string
}

ReleasePoolRequest gives a pool back.

type RequestAddressRequest

type RequestAddressRequest struct {
	PoolID  string
	Address string
	Options map[string]string
}

RequestAddressRequest asks for one address out of a pool.

type RequestAddressResponse

type RequestAddressResponse struct {
	Address string
	Data    map[string]string
}

RequestAddressResponse answers it, in CIDR form.

type RequestPoolRequest

type RequestPoolRequest struct {
	AddressSpace string
	Pool         string
	SubPool      string
	Options      map[string]string
	V6           bool
}

RequestPoolRequest asks for an address pool.

type RequestPoolResponse

type RequestPoolResponse struct {
	PoolID string
	Pool   string
	Data   map[string]string
}

RequestPoolResponse answers it.

type StaticRoute

type StaticRoute struct {
	Destination string
	RouteType   int
	NextHop     string
}

StaticRoute contains static route information

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL