Browse Source

Merge pull request #41189 from thaJeztah/bump_libnetwork

vendor: libnetwork 9e99af28df21367340c95a3863e31808d689c92a
Tibor Vass 5 years ago
parent
commit
d78b22cdf5

+ 1 - 1
hack/dockerfile/install/proxy.installer

@@ -3,7 +3,7 @@
 # LIBNETWORK_COMMIT is used to build the docker-userland-proxy binary. When
 # updating the binary version, consider updating github.com/docker/libnetwork
 # in vendor.conf accordingly
-: "${LIBNETWORK_COMMIT:=2e24aed516bd5c836e11378bb457dd612aa868ed}"
+: "${LIBNETWORK_COMMIT:=9e99af28df21367340c95a3863e31808d689c92a}"
 
 install_proxy() {
 	case "$1" in

+ 1 - 1
vendor.conf

@@ -41,7 +41,7 @@ github.com/grpc-ecosystem/go-grpc-middleware        3c51f7f332123e8be5a157c0802a
 # libnetwork
 
 # When updating, also update LIBNETWORK_COMMIT in hack/dockerfile/install/proxy.installer accordingly
-github.com/docker/libnetwork                        2e24aed516bd5c836e11378bb457dd612aa868ed
+github.com/docker/libnetwork                        9e99af28df21367340c95a3863e31808d689c92a
 github.com/docker/go-events                         e31b211e4f1cd09aa76fe4ac244571fab96ae47f
 github.com/armon/go-radix                           e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
 github.com/armon/go-metrics                         eb0af217e5e9747e41dd5303755356b62d28e3ec

+ 1 - 6
vendor/github.com/docker/libnetwork/controller.go

@@ -1020,12 +1020,7 @@ func (c *controller) addNetwork(n *network) error {
 func (c *controller) Networks() []Network {
 	var list []Network
 
-	networks, err := c.getNetworksFromStore()
-	if err != nil {
-		logrus.Error(err)
-	}
-
-	for _, n := range networks {
+	for _, n := range c.getNetworksFromStore() {
 		if n.inDelete {
 			continue
 		}

+ 6 - 0
vendor/github.com/docker/libnetwork/drivers/bridge/bridge.go

@@ -689,6 +689,12 @@ func (d *driver) createNetwork(config *networkConfiguration) (err error) {
 	bridgeAlreadyExists := bridgeIface.exists()
 	if !bridgeAlreadyExists {
 		bridgeSetup.queueStep(setupDevice)
+		bridgeSetup.queueStep(setupDefaultSysctl)
+	}
+
+	// For the default bridge, set expected sysctls
+	if config.DefaultBridge {
+		bridgeSetup.queueStep(setupDefaultSysctl)
 	}
 
 	// Even if a bridge exists try to setup IPv4.

+ 19 - 0
vendor/github.com/docker/libnetwork/drivers/bridge/setup_device.go

@@ -2,6 +2,9 @@ package bridge
 
 import (
 	"fmt"
+	"io/ioutil"
+	"os"
+	"path/filepath"
 
 	"github.com/docker/docker/pkg/parsers/kernel"
 	"github.com/docker/libnetwork/netutils"
@@ -49,6 +52,22 @@ func setupDevice(config *networkConfiguration, i *bridgeInterface) error {
 	return err
 }
 
+func setupDefaultSysctl(config *networkConfiguration, i *bridgeInterface) error {
+	// Disable IPv6 router advertisements originating on the bridge
+	sysPath := filepath.Join("/proc/sys/net/ipv6/conf/", config.BridgeName, "accept_ra")
+	if _, err := os.Stat(sysPath); err != nil {
+		logrus.
+			WithField("bridge", config.BridgeName).
+			WithField("syspath", sysPath).
+			Info("failed to read ipv6 net.ipv6.conf.<bridge>.accept_ra")
+		return nil
+	}
+	if err := ioutil.WriteFile(sysPath, []byte{'0', '\n'}, 0644); err != nil {
+		logrus.WithError(err).Warn("unable to disable IPv6 router advertisement")
+	}
+	return nil
+}
+
 // SetupDeviceUp ups the given bridge interface.
 func setupDeviceUp(config *networkConfiguration, i *bridgeInterface) error {
 	err := i.nlh.LinkSetUp(i.Link)

+ 146 - 10
vendor/github.com/docker/libnetwork/iptables/firewalld.go

@@ -19,20 +19,46 @@ const (
 	// Ebtables point to bridge table
 	Ebtables IPV = "eb"
 )
+
 const (
-	dbusInterface = "org.fedoraproject.FirewallD1"
-	dbusPath      = "/org/fedoraproject/FirewallD1"
+	dbusInterface  = "org.fedoraproject.FirewallD1"
+	dbusPath       = "/org/fedoraproject/FirewallD1"
+	dbusConfigPath = "/org/fedoraproject/FirewallD1/config"
+	dockerZone     = "docker"
 )
 
 // Conn is a connection to firewalld dbus endpoint.
 type Conn struct {
-	sysconn *dbus.Conn
-	sysobj  dbus.BusObject
-	signal  chan *dbus.Signal
+	sysconn    *dbus.Conn
+	sysObj     dbus.BusObject
+	sysConfObj dbus.BusObject
+	signal     chan *dbus.Signal
+}
+
+// ZoneSettings holds the firewalld zone settings, documented in
+// https://firewalld.org/documentation/man-pages/firewalld.dbus.html
+type ZoneSettings struct {
+	version            string
+	name               string
+	description        string
+	unused             bool
+	target             string
+	services           []string
+	ports              [][]interface{}
+	icmpBlocks         []string
+	masquerade         bool
+	forwardPorts       [][]interface{}
+	interfaces         []string
+	sourceAddresses    []string
+	richRules          []string
+	protocols          []string
+	sourcePorts        [][]interface{}
+	icmpBlockInversion bool
 }
 
 var (
-	connection       *Conn
+	connection *Conn
+
 	firewalldRunning bool      // is Firewalld service running
 	onReloaded       []*func() // callbacks when Firewalld has been reloaded
 )
@@ -51,6 +77,9 @@ func FirewalldInit() error {
 	}
 	if connection != nil {
 		go signalHandler()
+		if err := setupDockerZone(); err != nil {
+			return err
+		}
 	}
 
 	return nil
@@ -76,8 +105,8 @@ func (c *Conn) initConnection() error {
 	}
 
 	// This never fails, even if the service is not running atm.
-	c.sysobj = c.sysconn.Object(dbusInterface, dbus.ObjectPath(dbusPath))
-
+	c.sysObj = c.sysconn.Object(dbusInterface, dbus.ObjectPath(dbusPath))
+	c.sysConfObj = c.sysconn.Object(dbusInterface, dbus.ObjectPath(dbusConfigPath))
 	rule := fmt.Sprintf("type='signal',path='%s',interface='%s',sender='%s',member='Reloaded'",
 		dbusPath, dbusInterface, dbusInterface)
 	c.sysconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, rule)
@@ -150,7 +179,7 @@ func checkRunning() bool {
 	var err error
 
 	if connection != nil {
-		err = connection.sysobj.Call(dbusInterface+".getDefaultZone", 0).Store(&zone)
+		err = connection.sysObj.Call(dbusInterface+".getDefaultZone", 0).Store(&zone)
 		return err == nil
 	}
 	return false
@@ -160,8 +189,115 @@ func checkRunning() bool {
 func Passthrough(ipv IPV, args ...string) ([]byte, error) {
 	var output string
 	logrus.Debugf("Firewalld passthrough: %s, %s", ipv, args)
-	if err := connection.sysobj.Call(dbusInterface+".direct.passthrough", 0, ipv, args).Store(&output); err != nil {
+	if err := connection.sysObj.Call(dbusInterface+".direct.passthrough", 0, ipv, args).Store(&output); err != nil {
 		return nil, err
 	}
 	return []byte(output), nil
 }
+
+// getDockerZoneSettings converts the ZoneSettings struct into a interface slice
+func getDockerZoneSettings() []interface{} {
+	settings := ZoneSettings{
+		version:     "1.0",
+		name:        dockerZone,
+		description: "zone for docker bridge network interfaces",
+		target:      "ACCEPT",
+	}
+	slice := []interface{}{
+		settings.version,
+		settings.name,
+		settings.description,
+		settings.unused,
+		settings.target,
+		settings.services,
+		settings.ports,
+		settings.icmpBlocks,
+		settings.masquerade,
+		settings.forwardPorts,
+		settings.interfaces,
+		settings.sourceAddresses,
+		settings.richRules,
+		settings.protocols,
+		settings.sourcePorts,
+		settings.icmpBlockInversion,
+	}
+	return slice
+
+}
+
+// setupDockerZone creates a zone called docker in firewalld which includes docker interfaces to allow
+// container networking
+func setupDockerZone() error {
+	var zones []string
+	// Check if zone exists
+	if err := connection.sysObj.Call(dbusInterface+".zone.getZones", 0).Store(&zones); err != nil {
+		return err
+	}
+	if contains(zones, dockerZone) {
+		logrus.Infof("Firewalld: %s zone already exists, returning", dockerZone)
+		return nil
+	}
+	logrus.Debugf("Firewalld: creating %s zone", dockerZone)
+
+	settings := getDockerZoneSettings()
+	// Permanent
+	if err := connection.sysConfObj.Call(dbusInterface+".config.addZone", 0, dockerZone, settings).Err; err != nil {
+		return err
+	}
+	// Reload for change to take effect
+	if err := connection.sysObj.Call(dbusInterface+".reload", 0).Err; err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// AddInterfaceFirewalld adds the interface to the trusted zone
+func AddInterfaceFirewalld(intf string) error {
+	var intfs []string
+	// Check if interface is already added to the zone
+	if err := connection.sysObj.Call(dbusInterface+".zone.getInterfaces", 0, dockerZone).Store(&intfs); err != nil {
+		return err
+	}
+	// Return if interface is already part of the zone
+	if contains(intfs, intf) {
+		logrus.Infof("Firewalld: interface %s already part of %s zone, returning", intf, dockerZone)
+		return nil
+	}
+
+	logrus.Debugf("Firewalld: adding %s interface to %s zone", intf, dockerZone)
+	// Runtime
+	if err := connection.sysObj.Call(dbusInterface+".zone.addInterface", 0, dockerZone, intf).Err; err != nil {
+		return err
+	}
+	return nil
+}
+
+// DelInterfaceFirewalld removes the interface from the trusted zone
+func DelInterfaceFirewalld(intf string) error {
+	var intfs []string
+	// Check if interface is part of the zone
+	if err := connection.sysObj.Call(dbusInterface+".zone.getInterfaces", 0, dockerZone).Store(&intfs); err != nil {
+		return err
+	}
+	// Remove interface if it exists
+	if !contains(intfs, intf) {
+		return fmt.Errorf("Firewalld: unable to find interface %s in %s zone", intf, dockerZone)
+	}
+
+	logrus.Debugf("Firewalld: removing %s interface from %s zone", intf, dockerZone)
+	// Runtime
+	if err := connection.sysObj.Call(dbusInterface+".zone.removeInterface", 0, dockerZone, intf).Err; err != nil {
+		return err
+	}
+	return nil
+}
+
+func contains(list []string, val string) bool {
+	for _, v := range list {
+		if v == val {
+			return true
+		}
+	}
+	return false
+}

+ 13 - 0
vendor/github.com/docker/libnetwork/iptables/iptables.go

@@ -146,6 +146,19 @@ func ProgramChain(c *ChainInfo, bridgeName string, hairpinMode, enable bool) err
 		return errors.New("Could not program chain, missing chain name")
 	}
 
+	// Either add or remove the interface from the firewalld zone
+	if firewalldRunning {
+		if enable {
+			if err := AddInterfaceFirewalld(bridgeName); err != nil {
+				return err
+			}
+		} else {
+			if err := DelInterfaceFirewalld(bridgeName); err != nil {
+				return err
+			}
+		}
+	}
+
 	switch c.Table {
 	case Nat:
 		preroute := []string{

+ 2 - 1
vendor/github.com/docker/libnetwork/network.go

@@ -1181,7 +1181,8 @@ func (n *network) createEndpoint(name string, options ...EndpointOption) (Endpoi
 	ep.locator = n.getController().clusterHostID()
 	ep.network, err = ep.getNetworkFromStore()
 	if err != nil {
-		return nil, fmt.Errorf("failed to get network during CreateEndpoint: %v", err)
+		logrus.Errorf("failed to get network during CreateEndpoint: %v", err)
+		return nil, err
 	}
 	n = ep.network
 

+ 8 - 21
vendor/github.com/docker/libnetwork/store.go

@@ -80,16 +80,12 @@ func (c *controller) getStores() []datastore.DataStore {
 }
 
 func (c *controller) getNetworkFromStore(nid string) (*network, error) {
-	ns, err := c.getNetworksFromStore()
-	if err != nil {
-		return nil, err
-	}
-	for _, n := range ns {
+	for _, n := range c.getNetworksFromStore() {
 		if n.id == nid {
 			return n, nil
 		}
 	}
-	return nil, fmt.Errorf("network %s not found", nid)
+	return nil, ErrNoSuchNetwork(nid)
 }
 
 func (c *controller) getNetworksForScope(scope string) ([]*network, error) {
@@ -128,12 +124,11 @@ func (c *controller) getNetworksForScope(scope string) ([]*network, error) {
 	return nl, nil
 }
 
-func (c *controller) getNetworksFromStore() ([]*network, error) {
+func (c *controller) getNetworksFromStore() []*network {
 	var nl []*network
 
 	for _, store := range c.getStores() {
-		kvol, err := store.List(datastore.Key(datastore.NetworkKeyPrefix),
-			&network{ctrlr: c})
+		kvol, err := store.List(datastore.Key(datastore.NetworkKeyPrefix), &network{ctrlr: c})
 		// Continue searching in the next store if no keys found in this store
 		if err != nil {
 			if err != datastore.ErrKeyNotFound {
@@ -143,10 +138,8 @@ func (c *controller) getNetworksFromStore() ([]*network, error) {
 		}
 
 		kvep, err := store.Map(datastore.Key(epCntKeyPrefix), &endpointCnt{})
-		if err != nil {
-			if err != datastore.ErrKeyNotFound {
-				logrus.Warnf("failed to get endpoint_count map for scope %s: %v", store.Scope(), err)
-			}
+		if err != nil && err != datastore.ErrKeyNotFound {
+			logrus.Warnf("failed to get endpoint_count map for scope %s: %v", store.Scope(), err)
 		}
 
 		for _, kvo := range kvol {
@@ -168,7 +161,7 @@ func (c *controller) getNetworksFromStore() ([]*network, error) {
 		}
 	}
 
-	return nl, nil
+	return nl
 }
 
 func (n *network) getEndpointFromStore(eid string) (*endpoint, error) {
@@ -455,13 +448,7 @@ func (c *controller) startWatch() {
 }
 
 func (c *controller) networkCleanup() {
-	networks, err := c.getNetworksFromStore()
-	if err != nil {
-		logrus.Warnf("Could not retrieve networks from store(s) during network cleanup: %v", err)
-		return
-	}
-
-	for _, n := range networks {
+	for _, n := range c.getNetworksFromStore() {
 		if n.inDelete {
 			logrus.Infof("Removing stale network %s (%s)", n.Name(), n.ID())
 			if err := n.delete(true, true); err != nil {