summaryrefslogtreecommitdiff
path: root/libpod/network/types/network.go
blob: ba5e018fd0281981eb73e51e2c5195f52a02d5f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
package types

import (
	"encoding/json"
	"net"
	"time"
)

type ContainerNetwork interface {
	// NetworkCreate will take a partial filled Network and fill the
	// missing fields. It creates the Network and returns the full Network.
	NetworkCreate(Network) (Network, error)
	// NetworkRemove will remove the Network with the given name or ID.
	NetworkRemove(nameOrID string) error
	// NetworkList will return all known Networks. Optionally you can
	// supply a list of filter functions. Only if a network matches all
	// functions it is returned.
	NetworkList(...FilterFunc) ([]Network, error)
	// NetworkInspect will return the Network with the given name or ID.
	NetworkInspect(nameOrID string) (Network, error)

	// Setup will setup the container network namespace. It returns
	// a map of StatusBlocks, the key is the network name.
	Setup(namespacePath string, options SetupOptions) (map[string]StatusBlock, error)
	// Teardown will teardown the container network namespace.
	Teardown(namespacePath string, options TeardownOptions) error

	// Drivers will return the list of supported network drivers
	// for this interface.
	Drivers() []string
}

// Network describes the Network attributes.
type Network struct {
	// Name of the Network.
	Name string `json:"name"`
	// ID of the Network.
	ID string `json:"id"`
	// Driver for this Network, e.g. bridge, macvlan...
	Driver string `json:"driver"`
	// InterfaceName is the network interface name on the host.
	NetworkInterface string `json:"network_interface,omitempty"`
	// Created contains the timestamp when this network was created.
	Created time.Time `json:"created,omitempty"`
	// Subnets to use.
	Subnets []Subnet `json:"subnets,omitempty"`
	// IPv6Enabled if set to true an ipv6 subnet should be created for this net.
	IPv6Enabled bool `json:"ipv6_enabled"`
	// Internal is whether the Network should not have external routes
	// to public or other Networks.
	Internal bool `json:"internal"`
	// DNSEnabled is whether name resolution is active for container on
	// this Network.
	DNSEnabled bool `json:"dns_enabled"`
	// Labels is a set of key-value labels that have been applied to the
	// Network.
	Labels map[string]string `json:"labels,omitempty"`
	// Options is a set of key-value options that have been applied to
	// the Network.
	Options map[string]string `json:"options,omitempty"`
	// IPAMOptions contains options used for the ip assignment.
	IPAMOptions map[string]string `json:"ipam_options,omitempty"`
}

// IPNet is used as custom net.IPNet type to add Marshal/Unmarshal methods.
type IPNet struct {
	net.IPNet
}

// ParseCIDR parse a string to IPNet
func ParseCIDR(cidr string) (IPNet, error) {
	ip, net, err := net.ParseCIDR(cidr)
	if err != nil {
		return IPNet{}, err
	}
	// convert to 4 bytes if ipv4
	ipv4 := ip.To4()
	if ipv4 != nil {
		ip = ipv4
	}
	net.IP = ip
	return IPNet{*net}, err
}

func (n *IPNet) MarshalText() ([]byte, error) {
	return []byte(n.String()), nil
}

func (n *IPNet) UnmarshalText(text []byte) error {
	net, err := ParseCIDR(string(text))
	if err != nil {
		return err
	}
	*n = net
	return nil
}

// HardwareAddr is the same as net.HardwareAddr except
// that it adds the json marshal/unmarshal methods.
// This allows us to read the mac from a json string
// and a byte array.
// swagger:model MacAddress
type HardwareAddr net.HardwareAddr

func (h *HardwareAddr) String() string {
	return (*net.HardwareAddr)(h).String()
}

func (h *HardwareAddr) MarshalText() ([]byte, error) {
	return []byte((*net.HardwareAddr)(h).String()), nil
}

func (h *HardwareAddr) UnmarshalJSON(text []byte) error {
	if len(text) == 0 {
		*h = nil
		return nil
	}

	// if the json string start with a quote we got a string
	// unmarshal the string and parse the mac from this string
	if string(text[0]) == `"` {
		var macString string
		err := json.Unmarshal(text, &macString)
		if err == nil {
			mac, err := net.ParseMAC(macString)
			if err == nil {
				*h = HardwareAddr(mac)
				return nil
			}
		}
	}
	// not a string or got an error fallback to the normal parsing
	mac := make(net.HardwareAddr, 0, 6)
	// use the standard json unmarshal for backwards compat
	err := json.Unmarshal(text, &mac)
	if err != nil {
		return err
	}
	*h = HardwareAddr(mac)
	return nil
}

type Subnet struct {
	// Subnet for this Network in CIDR form.
	// swagger:strfmt string
	Subnet IPNet `json:"subnet"`
	// Gateway IP for this Network.
	// swagger:strfmt string
	Gateway net.IP `json:"gateway,omitempty"`
	// LeaseRange contains the range where IP are leased. Optional.
	LeaseRange *LeaseRange `json:"lease_range,omitempty"`
}

// LeaseRange contains the range where IP are leased.
type LeaseRange struct {
	// StartIP first IP in the subnet which should be used to assign ips.
	// swagger:strfmt string
	StartIP net.IP `json:"start_ip,omitempty"`
	// EndIP last IP in the subnet which should be used to assign ips.
	// swagger:strfmt string
	EndIP net.IP `json:"end_ip,omitempty"`
}

// StatusBlock contains the network information about a container
// connected to one Network.
type StatusBlock struct {
	// Interfaces contains the created network interface in the container.
	// The map key is the interface name.
	Interfaces map[string]NetInterface `json:"interfaces,omitempty"`
	// DNSServerIPs nameserver addresses which should be added to
	// the containers resolv.conf file.
	DNSServerIPs []net.IP `json:"dns_server_ips,omitempty"`
	// DNSSearchDomains search domains which should be added to
	// the containers resolv.conf file.
	DNSSearchDomains []string `json:"dns_search_domains,omitempty"`
}

// NetInterface contains the settings for a given network interface.
type NetInterface struct {
	// Networks list of assigned subnets with their gateway.
	Networks []NetAddress `json:"networks,omitempty"`
	// MacAddress for this Interface.
	MacAddress HardwareAddr `json:"mac_address"`
}

// NetAddress contains the subnet and gateway.
type NetAddress struct {
	// Subnet of this NetAddress. Note that the subnet contains the
	// actual ip of the net interface and not the network address.
	Subnet IPNet `json:"subnet"`
	// Gateway for the Subnet. This can be nil if there is no gateway, e.g. internal network.
	Gateway net.IP `json:"gateway,omitempty"`
}

// PerNetworkOptions are options which should be set on a per network basis.
type PerNetworkOptions struct {
	// StaticIPv4 for this container. Optional.
	StaticIPs []net.IP `json:"static_ips,omitempty"`
	// Aliases contains a list of names which the dns server should resolve
	// to this container. Should only be set when DNSEnabled is true on the Network.
	// If aliases are set but there is no dns support for this network the
	// network interface implementation should ignore this and NOT error.
	// Optional.
	Aliases []string `json:"aliases,omitempty"`
	// StaticMac for this container. Optional.
	StaticMAC HardwareAddr `json:"static_mac,omitempty"`
	// InterfaceName for this container. Required.
	InterfaceName string `json:"interface_name"`
}

// NetworkOptions for a given container.
type NetworkOptions struct {
	// ContainerID is the container id, used for iptables comments and ipam allocation.
	ContainerID string `json:"container_id"`
	// ContainerName is the container name, used as dns name.
	ContainerName string `json:"container_name"`
	// PortMappings contains the port mappings for this container
	PortMappings []PortMapping `json:"port_mappings,omitempty"`
	// Networks contains all networks with the PerNetworkOptions.
	// The map should contain at least one element.
	Networks map[string]PerNetworkOptions `json:"networks"`
}

// PortMapping is one or more ports that will be mapped into the container.
type PortMapping struct {
	// HostIP is the IP that we will bind to on the host.
	// If unset, assumed to be 0.0.0.0 (all interfaces).
	HostIP string `json:"host_ip"`
	// ContainerPort is the port number that will be exposed from the
	// container.
	// Mandatory.
	ContainerPort uint16 `json:"container_port"`
	// HostPort is the port number that will be forwarded from the host into
	// the container.
	// If omitted, a random port on the host (guaranteed to be over 1024)
	// will be assigned.
	HostPort uint16 `json:"host_port"`
	// Range is the number of ports that will be forwarded, starting at
	// HostPort and ContainerPort and counting up.
	// This is 1-indexed, so 1 is assumed to be a single port (only the
	// Hostport:Containerport mapping will be added), 2 is two ports (both
	// Hostport:Containerport and Hostport+1:Containerport+1), etc.
	// If unset, assumed to be 1 (a single port).
	// Both hostport + range and containerport + range must be less than
	// 65536.
	Range uint16 `json:"range"`
	// Protocol is the protocol forward.
	// Must be either "tcp", "udp", and "sctp", or some combination of these
	// separated by commas.
	// If unset, assumed to be TCP.
	Protocol string `json:"protocol"`
}

// OCICNIPortMapping maps to the standard CNI portmapping Capability.
// Deprecated, do not use this struct for new fields. This only exists
// for backwards compatibility.
type OCICNIPortMapping struct {
	// HostPort is the port number on the host.
	HostPort int32 `json:"hostPort"`
	// ContainerPort is the port number inside the sandbox.
	ContainerPort int32 `json:"containerPort"`
	// Protocol is the protocol of the port mapping.
	Protocol string `json:"protocol"`
	// HostIP is the host ip to use.
	HostIP string `json:"hostIP"`
}

type SetupOptions struct {
	NetworkOptions
}

type TeardownOptions struct {
	NetworkOptions
}

// FilterFunc can be passed to NetworkList to filter the networks.
type FilterFunc func(Network) bool