Commits:
feeff4f0 Merge pull request #2380 from liskin/bridge-atomic-hwaddr
fec6476d Merge pull request #2489 from suwang48404/doc
8757597e Added document describing libnetwork traffic flow.
eaea5722 Merge pull request #2445 from kdomanski/ipv6-addr-in-hosts
1680ce71 Merge pull request #2462 from arkodg/fix-key-spi-panic
4420ee92 Fix panic in drivers/overlay/encryption.go
57178323 Merge pull request #2472 from thaJeztah/bump_golang_1.12.12
f741dc9c Update Golang 1.12.12 (CVE-2019-17596)
79c19d09 Merge pull request #2461 from suwang48404/master
94facacc Added API to set ephemeral port allocator range.
Signed-off-by: Arko Dasgupta <arko.dasgupta@docker.com>
| ... | ... |
@@ -3,7 +3,7 @@ |
| 3 | 3 |
# LIBNETWORK_COMMIT is used to build the docker-userland-proxy binary. When |
| 4 | 4 |
# updating the binary version, consider updating github.com/docker/libnetwork |
| 5 | 5 |
# in vendor.conf accordingly |
| 6 |
-: "${LIBNETWORK_COMMIT:=90afbb01e1d8acacb505a092744ea42b9f167377}"
|
|
| 6 |
+: "${LIBNETWORK_COMMIT:=feeff4f0a3fd2a2bb19cf67c826082c66ffaaed9}"
|
|
| 7 | 7 |
|
| 8 | 8 |
install_proxy() {
|
| 9 | 9 |
case "$1" in |
| ... | ... |
@@ -38,7 +38,7 @@ github.com/gofrs/flock 392e7fae8f1b0bdbd67dad7237d2 |
| 38 | 38 |
# libnetwork |
| 39 | 39 |
|
| 40 | 40 |
# When updating, also update LIBNETWORK_COMMIT in hack/dockerfile/install/proxy.installer accordingly |
| 41 |
-github.com/docker/libnetwork 90afbb01e1d8acacb505a092744ea42b9f167377 |
|
| 41 |
+github.com/docker/libnetwork feeff4f0a3fd2a2bb19cf67c826082c66ffaaed9 |
|
| 42 | 42 |
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9 |
| 43 | 43 |
github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80 |
| 44 | 44 |
github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec |
| ... | ... |
@@ -184,6 +184,16 @@ func (c *controller) handleKeyChange(keys []*types.EncryptionKey) error {
|
| 184 | 184 |
err := driver.DiscoverNew(discoverapi.EncryptionKeysUpdate, drvEnc) |
| 185 | 185 |
if err != nil {
|
| 186 | 186 |
logrus.Warnf("Failed to update datapath keys in driver %s: %v", name, err)
|
| 187 |
+ // Attempt to reconfigure keys in case of a update failure |
|
| 188 |
+ // which can arise due to a mismatch of keys |
|
| 189 |
+ // if worker nodes get temporarily disconnected |
|
| 190 |
+ logrus.Warnf("Reconfiguring datapath keys for %s", name)
|
|
| 191 |
+ drvCfgEnc := discoverapi.DriverEncryptionConfig{}
|
|
| 192 |
+ drvCfgEnc.Keys, drvCfgEnc.Tags = c.getKeys(subsysIPSec) |
|
| 193 |
+ err = driver.DiscoverNew(discoverapi.EncryptionKeysConfig, drvCfgEnc) |
|
| 194 |
+ if err != nil {
|
|
| 195 |
+ logrus.Warnf("Failed to reset datapath keys in driver %s: %v", name, err)
|
|
| 196 |
+ } |
|
| 187 | 197 |
} |
| 188 | 198 |
return false |
| 189 | 199 |
}) |
| ... | ... |
@@ -1,6 +1,7 @@ |
| 1 | 1 |
package config |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "fmt" |
|
| 4 | 5 |
"strings" |
| 5 | 6 |
|
| 6 | 7 |
"github.com/BurntSushi/toml" |
| ... | ... |
@@ -13,6 +14,7 @@ import ( |
| 13 | 13 |
"github.com/docker/libnetwork/ipamutils" |
| 14 | 14 |
"github.com/docker/libnetwork/netlabel" |
| 15 | 15 |
"github.com/docker/libnetwork/osl" |
| 16 |
+ "github.com/docker/libnetwork/portallocator" |
|
| 16 | 17 |
"github.com/sirupsen/logrus" |
| 17 | 18 |
) |
| 18 | 19 |
|
| ... | ... |
@@ -238,6 +240,23 @@ func OptionExperimental(exp bool) Option {
|
| 238 | 238 |
} |
| 239 | 239 |
} |
| 240 | 240 |
|
| 241 |
+// OptionDynamicPortRange function returns an option setter for service port allocation range |
|
| 242 |
+func OptionDynamicPortRange(in string) Option {
|
|
| 243 |
+ return func(c *Config) {
|
|
| 244 |
+ start, end := 0, 0 |
|
| 245 |
+ if len(in) > 0 {
|
|
| 246 |
+ n, err := fmt.Sscanf(in, "%d-%d", &start, &end) |
|
| 247 |
+ if n != 2 || err != nil {
|
|
| 248 |
+ logrus.Errorf("Failed to parse range string with err %v", err)
|
|
| 249 |
+ return |
|
| 250 |
+ } |
|
| 251 |
+ } |
|
| 252 |
+ if err := portallocator.Get().SetPortRange(start, end); err != nil {
|
|
| 253 |
+ logrus.Errorf("Failed to set port range with err %v", err)
|
|
| 254 |
+ } |
|
| 255 |
+ } |
|
| 256 |
+} |
|
| 257 |
+ |
|
| 241 | 258 |
// OptionNetworkControlPlaneMTU function returns an option setter for control plane MTU |
| 242 | 259 |
func OptionNetworkControlPlaneMTU(exp int) Option {
|
| 243 | 260 |
return func(c *Config) {
|
| ... | ... |
@@ -35,18 +35,17 @@ func setupDevice(config *networkConfiguration, i *bridgeInterface) error {
|
| 35 | 35 |
setMac = kv.Kernel > 3 || (kv.Kernel == 3 && kv.Major >= 3) |
| 36 | 36 |
} |
| 37 | 37 |
|
| 38 |
+ if setMac {
|
|
| 39 |
+ hwAddr := netutils.GenerateRandomMAC() |
|
| 40 |
+ i.Link.Attrs().HardwareAddr = hwAddr |
|
| 41 |
+ logrus.Debugf("Setting bridge mac address to %s", hwAddr)
|
|
| 42 |
+ } |
|
| 43 |
+ |
|
| 38 | 44 |
if err = i.nlh.LinkAdd(i.Link); err != nil {
|
| 39 | 45 |
logrus.Debugf("Failed to create bridge %s via netlink. Trying ioctl", config.BridgeName)
|
| 40 | 46 |
return ioctlCreateBridge(config.BridgeName, setMac) |
| 41 | 47 |
} |
| 42 | 48 |
|
| 43 |
- if setMac {
|
|
| 44 |
- hwAddr := netutils.GenerateRandomMAC() |
|
| 45 |
- if err = i.nlh.LinkSetHardwareAddr(i.Link, hwAddr); err != nil {
|
|
| 46 |
- return fmt.Errorf("failed to set bridge mac-address %s : %s", hwAddr, err.Error())
|
|
| 47 |
- } |
|
| 48 |
- logrus.Debugf("Setting bridge mac address to %s", hwAddr)
|
|
| 49 |
- } |
|
| 50 | 49 |
return err |
| 51 | 50 |
} |
| 52 | 51 |
|
| ... | ... |
@@ -498,11 +498,14 @@ func (ep *endpoint) sbJoin(sb *sandbox, options ...EndpointOption) (err error) {
|
| 498 | 498 |
} |
| 499 | 499 |
|
| 500 | 500 |
if doUpdateHostsFile(n, sb) {
|
| 501 |
- address := "" |
|
| 502 |
- if ip := ep.getFirstInterfaceAddress(); ip != nil {
|
|
| 503 |
- address = ip.String() |
|
| 501 |
+ var addresses []string |
|
| 502 |
+ if ip := ep.getFirstInterfaceIPv4Address(); ip != nil {
|
|
| 503 |
+ addresses = append(addresses, ip.String()) |
|
| 504 | 504 |
} |
| 505 |
- if err = sb.updateHostsFile(address); err != nil {
|
|
| 505 |
+ if ip := ep.getFirstInterfaceIPv6Address(); ip != nil {
|
|
| 506 |
+ addresses = append(addresses, ip.String()) |
|
| 507 |
+ } |
|
| 508 |
+ if err = sb.updateHostsFile(addresses); err != nil {
|
|
| 506 | 509 |
return err |
| 507 | 510 |
} |
| 508 | 511 |
} |
| ... | ... |
@@ -912,7 +915,7 @@ func (ep *endpoint) getSandbox() (*sandbox, bool) {
|
| 912 | 912 |
return ps, ok |
| 913 | 913 |
} |
| 914 | 914 |
|
| 915 |
-func (ep *endpoint) getFirstInterfaceAddress() net.IP {
|
|
| 915 |
+func (ep *endpoint) getFirstInterfaceIPv4Address() net.IP {
|
|
| 916 | 916 |
ep.Lock() |
| 917 | 917 |
defer ep.Unlock() |
| 918 | 918 |
|
| ... | ... |
@@ -923,6 +926,17 @@ func (ep *endpoint) getFirstInterfaceAddress() net.IP {
|
| 923 | 923 |
return nil |
| 924 | 924 |
} |
| 925 | 925 |
|
| 926 |
+func (ep *endpoint) getFirstInterfaceIPv6Address() net.IP {
|
|
| 927 |
+ ep.Lock() |
|
| 928 |
+ defer ep.Unlock() |
|
| 929 |
+ |
|
| 930 |
+ if ep.iface.addrv6 != nil {
|
|
| 931 |
+ return ep.iface.addrv6.IP |
|
| 932 |
+ } |
|
| 933 |
+ |
|
| 934 |
+ return nil |
|
| 935 |
+} |
|
| 936 |
+ |
|
| 926 | 937 |
// EndpointOptionGeneric function returns an option setter for a Generic option defined |
| 927 | 938 |
// in a Dictionary of Key-Value pair |
| 928 | 939 |
func EndpointOptionGeneric(generic map[string]interface{}) EndpointOption {
|
| ... | ... |
@@ -3,17 +3,36 @@ package portallocator |
| 3 | 3 |
import ( |
| 4 | 4 |
"errors" |
| 5 | 5 |
"fmt" |
| 6 |
+ "github.com/sirupsen/logrus" |
|
| 6 | 7 |
"net" |
| 7 | 8 |
"sync" |
| 8 | 9 |
) |
| 9 | 10 |
|
| 10 |
-const ( |
|
| 11 |
- // DefaultPortRangeStart indicates the first port in port range |
|
| 12 |
- DefaultPortRangeStart = 49153 |
|
| 13 |
- // DefaultPortRangeEnd indicates the last port in port range |
|
| 14 |
- DefaultPortRangeEnd = 65535 |
|
| 11 |
+var ( |
|
| 12 |
+ // defaultPortRangeStart indicates the first port in port range |
|
| 13 |
+ defaultPortRangeStart = 49153 |
|
| 14 |
+ // defaultPortRangeEnd indicates the last port in port range |
|
| 15 |
+ // consistent with default /proc/sys/net/ipv4/ip_local_port_range |
|
| 16 |
+ // upper bound on linux |
|
| 17 |
+ defaultPortRangeEnd = 60999 |
|
| 15 | 18 |
) |
| 16 | 19 |
|
| 20 |
+func sanitizePortRange(start int, end int) (newStart, newEnd int, err error) {
|
|
| 21 |
+ if start > defaultPortRangeEnd || end < defaultPortRangeStart || start > end {
|
|
| 22 |
+ return 0, 0, fmt.Errorf("Request out allowed range [%v, %v]",
|
|
| 23 |
+ defaultPortRangeStart, defaultPortRangeEnd) |
|
| 24 |
+ } |
|
| 25 |
+ err = nil |
|
| 26 |
+ newStart, newEnd = start, end |
|
| 27 |
+ if start < defaultPortRangeStart {
|
|
| 28 |
+ newStart = defaultPortRangeStart |
|
| 29 |
+ } |
|
| 30 |
+ if end > defaultPortRangeEnd {
|
|
| 31 |
+ newEnd = defaultPortRangeEnd |
|
| 32 |
+ } |
|
| 33 |
+ return |
|
| 34 |
+} |
|
| 35 |
+ |
|
| 17 | 36 |
type ipMapping map[string]protoMap |
| 18 | 37 |
|
| 19 | 38 |
var ( |
| ... | ... |
@@ -92,11 +111,19 @@ func Get() *PortAllocator {
|
| 92 | 92 |
return instance |
| 93 | 93 |
} |
| 94 | 94 |
|
| 95 |
-func newInstance() *PortAllocator {
|
|
| 95 |
+func getDefaultPortRange() (int, int) {
|
|
| 96 | 96 |
start, end, err := getDynamicPortRange() |
| 97 |
+ if err == nil {
|
|
| 98 |
+ start, end, err = sanitizePortRange(start, end) |
|
| 99 |
+ } |
|
| 97 | 100 |
if err != nil {
|
| 98 |
- start, end = DefaultPortRangeStart, DefaultPortRangeEnd |
|
| 101 |
+ start, end = defaultPortRangeStart, defaultPortRangeEnd |
|
| 99 | 102 |
} |
| 103 |
+ return start, end |
|
| 104 |
+} |
|
| 105 |
+ |
|
| 106 |
+func newInstance() *PortAllocator {
|
|
| 107 |
+ start, end := getDefaultPortRange() |
|
| 100 | 108 |
return &PortAllocator{
|
| 101 | 109 |
ipMap: ipMapping{},
|
| 102 | 110 |
Begin: start, |
| ... | ... |
@@ -170,6 +197,35 @@ func (p *PortAllocator) ReleasePort(ip net.IP, proto string, port int) error {
|
| 170 | 170 |
return nil |
| 171 | 171 |
} |
| 172 | 172 |
|
| 173 |
+// SetPortRange sets dynamic port allocation range. |
|
| 174 |
+// if both portBegin and portEnd are 0, the port range reverts to default |
|
| 175 |
+// value. Otherwise they are sanitized against the default values to |
|
| 176 |
+// ensure their validity. |
|
| 177 |
+func (p *PortAllocator) SetPortRange(portBegin, portEnd int) error {
|
|
| 178 |
+ // if begin and end is zero, revert to default values |
|
| 179 |
+ var begin, end int |
|
| 180 |
+ var err error |
|
| 181 |
+ if portBegin == 0 && portEnd == 0 {
|
|
| 182 |
+ begin, end = getDefaultPortRange() |
|
| 183 |
+ |
|
| 184 |
+ } else {
|
|
| 185 |
+ begin, end, err = sanitizePortRange(portBegin, portEnd) |
|
| 186 |
+ if err != nil {
|
|
| 187 |
+ return err |
|
| 188 |
+ } |
|
| 189 |
+ } |
|
| 190 |
+ logrus.Debugf("Setting up port allocator to range %v-%v, current %v-%v",
|
|
| 191 |
+ begin, end, p.Begin, p.End) |
|
| 192 |
+ p.mutex.Lock() |
|
| 193 |
+ defer p.mutex.Unlock() |
|
| 194 |
+ if p.Begin == begin && p.End == end {
|
|
| 195 |
+ return nil |
|
| 196 |
+ } |
|
| 197 |
+ p.ipMap = ipMapping{}
|
|
| 198 |
+ p.Begin, p.End = begin, end |
|
| 199 |
+ return nil |
|
| 200 |
+} |
|
| 201 |
+ |
|
| 173 | 202 |
func (p *PortAllocator) newPortMap() *portMap {
|
| 174 | 203 |
defaultKey := getRangeKey(p.Begin, p.End) |
| 175 | 204 |
pm := &portMap{
|
| ... | ... |
@@ -8,7 +8,7 @@ import ( |
| 8 | 8 |
|
| 9 | 9 |
func getDynamicPortRange() (start int, end int, err error) {
|
| 10 | 10 |
portRangeKernelSysctl := []string{"net.inet.ip.portrange.hifirst", "net.ip.portrange.hilast"}
|
| 11 |
- portRangeFallback := fmt.Sprintf("using fallback port range %d-%d", DefaultPortRangeStart, DefaultPortRangeEnd)
|
|
| 11 |
+ portRangeFallback := fmt.Sprintf("using fallback port range %d-%d", defaultPortRangeStart, defaultPortRangeEnd)
|
|
| 12 | 12 |
portRangeLowCmd := exec.Command("/sbin/sysctl", portRangeKernelSysctl[0])
|
| 13 | 13 |
var portRangeLowOut bytes.Buffer |
| 14 | 14 |
portRangeLowCmd.Stdout = &portRangeLowOut |
| ... | ... |
@@ -8,7 +8,7 @@ import ( |
| 8 | 8 |
|
| 9 | 9 |
func getDynamicPortRange() (start int, end int, err error) {
|
| 10 | 10 |
const portRangeKernelParam = "/proc/sys/net/ipv4/ip_local_port_range" |
| 11 |
- portRangeFallback := fmt.Sprintf("using fallback port range %d-%d", DefaultPortRangeStart, DefaultPortRangeEnd)
|
|
| 11 |
+ portRangeFallback := fmt.Sprintf("using fallback port range %d-%d", defaultPortRangeStart, defaultPortRangeEnd)
|
|
| 12 | 12 |
file, err := os.Open(portRangeKernelParam) |
| 13 | 13 |
if err != nil {
|
| 14 | 14 |
return 0, 0, fmt.Errorf("port allocator - %s due to error: %v", portRangeFallback, err)
|
| ... | ... |
@@ -1,10 +1,10 @@ |
| 1 | 1 |
package portallocator |
| 2 | 2 |
|
| 3 |
-const ( |
|
| 4 |
- StartPortRange = 60000 |
|
| 5 |
- EndPortRange = 65000 |
|
| 6 |
-) |
|
| 3 |
+func init() {
|
|
| 4 |
+ defaultPortRangeStart = 60000 |
|
| 5 |
+ defaultPortRangeEnd = 65000 |
|
| 6 |
+} |
|
| 7 | 7 |
|
| 8 | 8 |
func getDynamicPortRange() (start int, end int, err error) {
|
| 9 |
- return StartPortRange, EndPortRange, nil |
|
| 9 |
+ return defaultPortRangeStart, defaultPortRangeEnd, nil |
|
| 10 | 10 |
} |
| ... | ... |
@@ -98,8 +98,8 @@ func (sb *sandbox) buildHostsFile() error {
|
| 98 | 98 |
return etchosts.Build(sb.config.hostsPath, "", sb.config.hostName, sb.config.domainName, extraContent) |
| 99 | 99 |
} |
| 100 | 100 |
|
| 101 |
-func (sb *sandbox) updateHostsFile(ifaceIP string) error {
|
|
| 102 |
- if ifaceIP == "" {
|
|
| 101 |
+func (sb *sandbox) updateHostsFile(ifaceIPs []string) error {
|
|
| 102 |
+ if ifaceIPs == nil || len(ifaceIPs) == 0 {
|
|
| 103 | 103 |
return nil |
| 104 | 104 |
} |
| 105 | 105 |
|
| ... | ... |
@@ -120,7 +120,10 @@ func (sb *sandbox) updateHostsFile(ifaceIP string) error {
|
| 120 | 120 |
mhost = fmt.Sprintf("%s %s", fqdn, parts[0])
|
| 121 | 121 |
} |
| 122 | 122 |
|
| 123 |
- extraContent := []etchosts.Record{{Hosts: mhost, IP: ifaceIP}}
|
|
| 123 |
+ var extraContent []etchosts.Record |
|
| 124 |
+ for _, ip := range ifaceIPs {
|
|
| 125 |
+ extraContent = append(extraContent, etchosts.Record{Hosts: mhost, IP: ip})
|
|
| 126 |
+ } |
|
| 124 | 127 |
|
| 125 | 128 |
sb.addHostsEntries(extraContent) |
| 126 | 129 |
return nil |