mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
commit
263dd22fe3
25 changed files with 136 additions and 113 deletions
|
@ -7,6 +7,7 @@ import (
|
||||||
"github.com/docker/libnetwork/pkg/options"
|
"github.com/docker/libnetwork/pkg/options"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DriverParams are a generic structure to hold driver specific settings.
|
||||||
type DriverParams options.Generic
|
type DriverParams options.Generic
|
||||||
|
|
||||||
var drivers = map[string]struct {
|
var drivers = map[string]struct {
|
||||||
|
|
|
@ -7,10 +7,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
NetworkType = "simplebridge"
|
networkType = "simplebridge"
|
||||||
VethPrefix = "veth"
|
vethPrefix = "veth"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Configuration info for the "simplebridge" driver.
|
||||||
type Configuration struct {
|
type Configuration struct {
|
||||||
BridgeName string
|
BridgeName string
|
||||||
AddressIPv4 *net.IPNet
|
AddressIPv4 *net.IPNet
|
||||||
|
@ -22,58 +23,59 @@ type Configuration struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
libnetwork.RegisterNetworkType(NetworkType, Create, &Configuration{})
|
libnetwork.RegisterNetworkType(networkType, Create, &Configuration{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a new Network managed by the "simplebridge" driver.
|
||||||
func Create(name string, config *Configuration) (libnetwork.Network, error) {
|
func Create(name string, config *Configuration) (libnetwork.Network, error) {
|
||||||
bridgeIntfc := NewInterface(config)
|
bridgeIntfc := newInterface(config)
|
||||||
bridgeSetup := NewBridgeSetup(bridgeIntfc)
|
bridgeSetup := newBridgeSetup(bridgeIntfc)
|
||||||
|
|
||||||
// If the bridge interface doesn't exist, we need to start the setup steps
|
// If the bridge interface doesn't exist, we need to start the setup steps
|
||||||
// by creating a new device and assigning it an IPv4 address.
|
// by creating a new device and assigning it an IPv4 address.
|
||||||
bridgeAlreadyExists := bridgeIntfc.Exists()
|
bridgeAlreadyExists := bridgeIntfc.exists()
|
||||||
if !bridgeAlreadyExists {
|
if !bridgeAlreadyExists {
|
||||||
bridgeSetup.QueueStep(SetupDevice)
|
bridgeSetup.queueStep(setupDevice)
|
||||||
bridgeSetup.QueueStep(SetupBridgeIPv4)
|
bridgeSetup.queueStep(setupBridgeIPv4)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Conditionnally queue setup steps depending on configuration values.
|
// Conditionnally queue setup steps depending on configuration values.
|
||||||
for _, step := range []struct {
|
for _, step := range []struct {
|
||||||
Condition bool
|
Condition bool
|
||||||
Fn SetupStep
|
Fn setupStep
|
||||||
}{
|
}{
|
||||||
// Enable IPv6 on the bridge if required. We do this even for a
|
// Enable IPv6 on the bridge if required. We do this even for a
|
||||||
// previously existing bridge, as it may be here from a previous
|
// previously existing bridge, as it may be here from a previous
|
||||||
// installation where IPv6 wasn't supported yet and needs to be
|
// installation where IPv6 wasn't supported yet and needs to be
|
||||||
// assigned an IPv6 link-local address.
|
// assigned an IPv6 link-local address.
|
||||||
{config.EnableIPv6, SetupBridgeIPv6},
|
{config.EnableIPv6, setupBridgeIPv6},
|
||||||
|
|
||||||
// We ensure that the bridge has the expectedIPv4 and IPv6 addresses in
|
// We ensure that the bridge has the expectedIPv4 and IPv6 addresses in
|
||||||
// the case of a previously existing device.
|
// the case of a previously existing device.
|
||||||
{bridgeAlreadyExists, SetupVerifyConfiguredAddresses},
|
{bridgeAlreadyExists, setupVerifyConfiguredAddresses},
|
||||||
|
|
||||||
// Setup the bridge to allocate containers IPv4 addresses in the
|
// Setup the bridge to allocate containers IPv4 addresses in the
|
||||||
// specified subnet.
|
// specified subnet.
|
||||||
{config.FixedCIDR != nil, SetupFixedCIDRv4},
|
{config.FixedCIDR != nil, setupFixedCIDRv4},
|
||||||
|
|
||||||
// Setup the bridge to allocate containers global IPv6 addresses in the
|
// Setup the bridge to allocate containers global IPv6 addresses in the
|
||||||
// specified subnet.
|
// specified subnet.
|
||||||
{config.FixedCIDRv6 != nil, SetupFixedCIDRv6},
|
{config.FixedCIDRv6 != nil, setupFixedCIDRv6},
|
||||||
|
|
||||||
// Setup IPTables.
|
// Setup IPTables.
|
||||||
{config.EnableIPTables, SetupIPTables},
|
{config.EnableIPTables, setupIPTables},
|
||||||
|
|
||||||
// Setup IP forwarding.
|
// Setup IP forwarding.
|
||||||
{config.EnableIPForwarding, SetupIPForwarding},
|
{config.EnableIPForwarding, setupIPForwarding},
|
||||||
} {
|
} {
|
||||||
if step.Condition {
|
if step.Condition {
|
||||||
bridgeSetup.QueueStep(step.Fn)
|
bridgeSetup.queueStep(step.Fn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply the prepared list of steps, and abort at the first error.
|
// Apply the prepared list of steps, and abort at the first error.
|
||||||
bridgeSetup.QueueStep(SetupDeviceUp)
|
bridgeSetup.queueStep(setupDeviceUp)
|
||||||
if err := bridgeSetup.Apply(); err != nil {
|
if err := bridgeSetup.apply(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ func TestCreate(t *testing.T) {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if expected := NetworkType; netw.Type() != NetworkType {
|
if expected := networkType; netw.Type() != expected {
|
||||||
t.Fatalf("Expected networkType %q, got %q", expected, netw.Type())
|
t.Fatalf("Expected networkType %q, got %q", expected, netw.Type())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ func TestCreateFullOptions(t *testing.T) {
|
||||||
t.Fatalf("Failed to create bridge: %v", err)
|
t.Fatalf("Failed to create bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if expected := NetworkType; netw.Type() != NetworkType {
|
if expected := networkType; netw.Type() != expected {
|
||||||
t.Fatalf("Expected networkType %q, got %q", expected, netw.Type())
|
t.Fatalf("Expected networkType %q, got %q", expected, netw.Type())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,16 +3,23 @@ package bridge
|
||||||
import "github.com/vishvananda/netlink"
|
import "github.com/vishvananda/netlink"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// DefaultBridgeName is the default name for the bridge interface managed
|
||||||
|
// by the driver when unspecified by the caller.
|
||||||
DefaultBridgeName = "docker0"
|
DefaultBridgeName = "docker0"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Interface struct {
|
// Interface models the bridge network device.
|
||||||
|
type bridgeInterface struct {
|
||||||
Config *Configuration
|
Config *Configuration
|
||||||
Link netlink.Link
|
Link netlink.Link
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewInterface(config *Configuration) *Interface {
|
// NewInterface creates a new bridge interface structure. It attempts to find
|
||||||
i := &Interface{
|
// an already existing device identified by the Configuration BridgeName field,
|
||||||
|
// or the default bridge name when unspecified), but doesn't attempt to create
|
||||||
|
// on when missing
|
||||||
|
func newInterface(config *Configuration) *bridgeInterface {
|
||||||
|
i := &bridgeInterface{
|
||||||
Config: config,
|
Config: config,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,13 +34,13 @@ func NewInterface(config *Configuration) *Interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exists indicates if the existing bridge interface exists on the system.
|
// Exists indicates if the existing bridge interface exists on the system.
|
||||||
func (i *Interface) Exists() bool {
|
func (i *bridgeInterface) exists() bool {
|
||||||
return i.Link != nil
|
return i.Link != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Addresses returns a single IPv4 address and all IPv6 addresses for the
|
// Addresses returns a single IPv4 address and all IPv6 addresses for the
|
||||||
// bridge interface.
|
// bridge interface.
|
||||||
func (i *Interface) Addresses() (netlink.Addr, []netlink.Addr, error) {
|
func (i *bridgeInterface) addresses() (netlink.Addr, []netlink.Addr, error) {
|
||||||
v4addr, err := netlink.AddrList(i.Link, netlink.FAMILY_V4)
|
v4addr, err := netlink.AddrList(i.Link, netlink.FAMILY_V4)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return netlink.Addr{}, nil, err
|
return netlink.Addr{}, nil, err
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
func TestInterfaceDefaultName(t *testing.T) {
|
func TestInterfaceDefaultName(t *testing.T) {
|
||||||
defer libnetwork.SetupTestNetNS(t)()
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
if inf := NewInterface(&Configuration{}); inf.Config.BridgeName != DefaultBridgeName {
|
if inf := newInterface(&Configuration{}); inf.Config.BridgeName != DefaultBridgeName {
|
||||||
t.Fatalf("Expected default interface name %q, got %q", DefaultBridgeName, inf.Config.BridgeName)
|
t.Fatalf("Expected default interface name %q, got %q", DefaultBridgeName, inf.Config.BridgeName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,8 @@ func TestInterfaceDefaultName(t *testing.T) {
|
||||||
func TestAddressesEmptyInterface(t *testing.T) {
|
func TestAddressesEmptyInterface(t *testing.T) {
|
||||||
defer libnetwork.SetupTestNetNS(t)()
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
inf := NewInterface(&Configuration{})
|
inf := newInterface(&Configuration{})
|
||||||
addrv4, addrsv6, err := inf.Addresses()
|
addrv4, addrsv6, err := inf.addresses()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to get addresses of default interface: %v", err)
|
t.Fatalf("Failed to get addresses of default interface: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ func (b *bridgeNetwork) Name() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *bridgeNetwork) Type() string {
|
func (b *bridgeNetwork) Type() string {
|
||||||
return NetworkType
|
return networkType
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *bridgeNetwork) Link(name string) ([]*libnetwork.Interface, error) {
|
func (b *bridgeNetwork) Link(name string) ([]*libnetwork.Interface, error) {
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
package bridge
|
package bridge
|
||||||
|
|
||||||
type SetupStep func(*Interface) error
|
type setupStep func(*bridgeInterface) error
|
||||||
|
|
||||||
type BridgeSetup struct {
|
type bridgeSetup struct {
|
||||||
bridge *Interface
|
bridge *bridgeInterface
|
||||||
steps []SetupStep
|
steps []setupStep
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBridgeSetup(i *Interface) *BridgeSetup {
|
func newBridgeSetup(i *bridgeInterface) *bridgeSetup {
|
||||||
return &BridgeSetup{bridge: i}
|
return &bridgeSetup{bridge: i}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BridgeSetup) Apply() error {
|
func (b *bridgeSetup) apply() error {
|
||||||
for _, fn := range b.steps {
|
for _, fn := range b.steps {
|
||||||
if err := fn(b.bridge); err != nil {
|
if err := fn(b.bridge); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -20,12 +20,12 @@ func (b *BridgeSetup) Apply() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BridgeSetup) QueueStep(step SetupStep) {
|
func (b *bridgeSetup) queueStep(step setupStep) {
|
||||||
b.steps = append(b.steps, step)
|
b.steps = append(b.steps, step)
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------//
|
//---------------------------------------------------------------------------//
|
||||||
|
|
||||||
func SetupIPTables(i *Interface) error {
|
func setupIPTables(i *bridgeInterface) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,14 +11,14 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetupDevice create a new bridge interface/
|
// SetupDevice create a new bridge interface/
|
||||||
func SetupDevice(i *Interface) error {
|
func setupDevice(i *bridgeInterface) error {
|
||||||
// We only attempt to create the bridge when the requested device name is
|
// We only attempt to create the bridge when the requested device name is
|
||||||
// the default one.
|
// the default one.
|
||||||
if i.Config.BridgeName != DefaultBridgeName {
|
if i.Config.BridgeName != DefaultBridgeName {
|
||||||
return fmt.Errorf("bridge device with non default name %q must be created manually", i.Config.BridgeName)
|
return fmt.Errorf("bridge device with non default name %q must be created manually", i.Config.BridgeName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the Interface netlink.Bridge.
|
// Set the bridgeInterface netlink.Bridge.
|
||||||
i.Link = &netlink.Bridge{
|
i.Link = &netlink.Bridge{
|
||||||
LinkAttrs: netlink.LinkAttrs{
|
LinkAttrs: netlink.LinkAttrs{
|
||||||
Name: i.Config.BridgeName,
|
Name: i.Config.BridgeName,
|
||||||
|
@ -38,7 +38,7 @@ func SetupDevice(i *Interface) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetupDeviceUp ups the given bridge interface.
|
// SetupDeviceUp ups the given bridge interface.
|
||||||
func SetupDeviceUp(i *Interface) error {
|
func setupDeviceUp(i *bridgeInterface) error {
|
||||||
err := netlink.LinkSetUp(i.Link)
|
err := netlink.LinkSetUp(i.Link)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -13,34 +13,34 @@ import (
|
||||||
func TestSetupNewBridge(t *testing.T) {
|
func TestSetupNewBridge(t *testing.T) {
|
||||||
defer libnetwork.SetupTestNetNS(t)()
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
br := &Interface{
|
br := &bridgeInterface{
|
||||||
Config: &Configuration{
|
Config: &Configuration{
|
||||||
BridgeName: DefaultBridgeName,
|
BridgeName: DefaultBridgeName,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if err := SetupDevice(br); err != nil {
|
if err := setupDevice(br); err != nil {
|
||||||
t.Fatalf("Bridge creation failed: %v", err)
|
t.Fatalf("Bridge creation failed: %v", err)
|
||||||
}
|
}
|
||||||
if br.Link == nil {
|
if br.Link == nil {
|
||||||
t.Fatal("Interface link is nil (expected valid link)")
|
t.Fatal("bridgeInterface link is nil (expected valid link)")
|
||||||
}
|
}
|
||||||
if _, err := netlink.LinkByName(DefaultBridgeName); err != nil {
|
if _, err := netlink.LinkByName(DefaultBridgeName); err != nil {
|
||||||
t.Fatalf("Failed to retrieve bridge device: %v", err)
|
t.Fatalf("Failed to retrieve bridge device: %v", err)
|
||||||
}
|
}
|
||||||
if br.Link.Attrs().Flags&net.FlagUp == net.FlagUp {
|
if br.Link.Attrs().Flags&net.FlagUp == net.FlagUp {
|
||||||
t.Fatalf("Interface should be created down")
|
t.Fatalf("bridgeInterface should be created down")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetupNewNonDefaultBridge(t *testing.T) {
|
func TestSetupNewNonDefaultBridge(t *testing.T) {
|
||||||
defer libnetwork.SetupTestNetNS(t)()
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
br := &Interface{
|
br := &bridgeInterface{
|
||||||
Config: &Configuration{
|
Config: &Configuration{
|
||||||
BridgeName: "test0",
|
BridgeName: "test0",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if err := SetupDevice(br); err == nil || !strings.Contains(err.Error(), "non default name") {
|
if err := setupDevice(br); err == nil || !strings.Contains(err.Error(), "non default name") {
|
||||||
t.Fatalf("Expected bridge creation failure with \"non default name\", got: %v", err)
|
t.Fatalf("Expected bridge creation failure with \"non default name\", got: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,21 +48,21 @@ func TestSetupNewNonDefaultBridge(t *testing.T) {
|
||||||
func TestSetupDeviceUp(t *testing.T) {
|
func TestSetupDeviceUp(t *testing.T) {
|
||||||
defer libnetwork.SetupTestNetNS(t)()
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
br := &Interface{
|
br := &bridgeInterface{
|
||||||
Config: &Configuration{
|
Config: &Configuration{
|
||||||
BridgeName: DefaultBridgeName,
|
BridgeName: DefaultBridgeName,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if err := SetupDevice(br); err != nil {
|
if err := setupDevice(br); err != nil {
|
||||||
t.Fatalf("Bridge creation failed: %v", err)
|
t.Fatalf("Bridge creation failed: %v", err)
|
||||||
}
|
}
|
||||||
if err := SetupDeviceUp(br); err != nil {
|
if err := setupDeviceUp(br); err != nil {
|
||||||
t.Fatalf("Failed to up bridge device: %v", err)
|
t.Fatalf("Failed to up bridge device: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
lnk, _ := netlink.LinkByName(DefaultBridgeName)
|
lnk, _ := netlink.LinkByName(DefaultBridgeName)
|
||||||
if lnk.Attrs().Flags&net.FlagUp != net.FlagUp {
|
if lnk.Attrs().Flags&net.FlagUp != net.FlagUp {
|
||||||
t.Fatalf("Interface should be up")
|
t.Fatalf("bridgeInterface should be up")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@ import (
|
||||||
"github.com/docker/docker/daemon/networkdriver/ipallocator"
|
"github.com/docker/docker/daemon/networkdriver/ipallocator"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SetupFixedCIDRv4(i *Interface) error {
|
func setupFixedCIDRv4(i *bridgeInterface) error {
|
||||||
addrv4, _, err := i.Addresses()
|
addrv4, _, err := i.addresses()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,21 +11,21 @@ import (
|
||||||
func TestSetupFixedCIDRv4(t *testing.T) {
|
func TestSetupFixedCIDRv4(t *testing.T) {
|
||||||
defer libnetwork.SetupTestNetNS(t)()
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
br := &Interface{
|
br := &bridgeInterface{
|
||||||
Config: &Configuration{
|
Config: &Configuration{
|
||||||
BridgeName: DefaultBridgeName,
|
BridgeName: DefaultBridgeName,
|
||||||
AddressIPv4: &net.IPNet{IP: net.ParseIP("192.168.1.1"), Mask: net.CIDRMask(16, 32)},
|
AddressIPv4: &net.IPNet{IP: net.ParseIP("192.168.1.1"), Mask: net.CIDRMask(16, 32)},
|
||||||
FixedCIDR: &net.IPNet{IP: net.ParseIP("192.168.2.0"), Mask: net.CIDRMask(24, 32)},
|
FixedCIDR: &net.IPNet{IP: net.ParseIP("192.168.2.0"), Mask: net.CIDRMask(24, 32)},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if err := SetupDevice(br); err != nil {
|
if err := setupDevice(br); err != nil {
|
||||||
t.Fatalf("Bridge creation failed: %v", err)
|
t.Fatalf("Bridge creation failed: %v", err)
|
||||||
}
|
}
|
||||||
if err := SetupBridgeIPv4(br); err != nil {
|
if err := setupBridgeIPv4(br); err != nil {
|
||||||
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := SetupFixedCIDRv4(br); err != nil {
|
if err := setupFixedCIDRv4(br); err != nil {
|
||||||
t.Fatalf("Failed to setup bridge FixedCIDRv4: %v", err)
|
t.Fatalf("Failed to setup bridge FixedCIDRv4: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,21 +39,21 @@ func TestSetupFixedCIDRv4(t *testing.T) {
|
||||||
func TestSetupBadFixedCIDRv4(t *testing.T) {
|
func TestSetupBadFixedCIDRv4(t *testing.T) {
|
||||||
defer libnetwork.SetupTestNetNS(t)()
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
br := &Interface{
|
br := &bridgeInterface{
|
||||||
Config: &Configuration{
|
Config: &Configuration{
|
||||||
BridgeName: DefaultBridgeName,
|
BridgeName: DefaultBridgeName,
|
||||||
AddressIPv4: &net.IPNet{IP: net.ParseIP("192.168.1.1"), Mask: net.CIDRMask(24, 32)},
|
AddressIPv4: &net.IPNet{IP: net.ParseIP("192.168.1.1"), Mask: net.CIDRMask(24, 32)},
|
||||||
FixedCIDR: &net.IPNet{IP: net.ParseIP("192.168.2.0"), Mask: net.CIDRMask(24, 32)},
|
FixedCIDR: &net.IPNet{IP: net.ParseIP("192.168.2.0"), Mask: net.CIDRMask(24, 32)},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if err := SetupDevice(br); err != nil {
|
if err := setupDevice(br); err != nil {
|
||||||
t.Fatalf("Bridge creation failed: %v", err)
|
t.Fatalf("Bridge creation failed: %v", err)
|
||||||
}
|
}
|
||||||
if err := SetupBridgeIPv4(br); err != nil {
|
if err := setupBridgeIPv4(br); err != nil {
|
||||||
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := SetupFixedCIDRv4(br); err == nil {
|
if err := setupFixedCIDRv4(br); err == nil {
|
||||||
t.Fatal("Setup bridge FixedCIDRv4 should have failed")
|
t.Fatal("Setup bridge FixedCIDRv4 should have failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/docker/docker/daemon/networkdriver/ipallocator"
|
"github.com/docker/docker/daemon/networkdriver/ipallocator"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SetupFixedCIDRv6(i *Interface) error {
|
func setupFixedCIDRv6(i *bridgeInterface) error {
|
||||||
log.Debugf("Using IPv6 subnet: %v", i.Config.FixedCIDRv6)
|
log.Debugf("Using IPv6 subnet: %v", i.Config.FixedCIDRv6)
|
||||||
if err := ipallocator.RegisterSubnet(i.Config.FixedCIDRv6, i.Config.FixedCIDRv6); err != nil {
|
if err := ipallocator.RegisterSubnet(i.Config.FixedCIDRv6, i.Config.FixedCIDRv6); err != nil {
|
||||||
return fmt.Errorf("Setup FixedCIDRv6 failed for subnet %s in %s: %v", i.Config.FixedCIDRv6, i.Config.FixedCIDRv6, err)
|
return fmt.Errorf("Setup FixedCIDRv6 failed for subnet %s in %s: %v", i.Config.FixedCIDRv6, i.Config.FixedCIDRv6, err)
|
||||||
|
|
|
@ -11,21 +11,21 @@ import (
|
||||||
func TestSetupFixedCIDRv6(t *testing.T) {
|
func TestSetupFixedCIDRv6(t *testing.T) {
|
||||||
defer libnetwork.SetupTestNetNS(t)()
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
br := NewInterface(&Configuration{})
|
br := newInterface(&Configuration{})
|
||||||
|
|
||||||
_, br.Config.FixedCIDRv6, _ = net.ParseCIDR("2002:db8::/48")
|
_, br.Config.FixedCIDRv6, _ = net.ParseCIDR("2002:db8::/48")
|
||||||
if err := SetupDevice(br); err != nil {
|
if err := setupDevice(br); err != nil {
|
||||||
t.Fatalf("Bridge creation failed: %v", err)
|
t.Fatalf("Bridge creation failed: %v", err)
|
||||||
}
|
}
|
||||||
if err := SetupBridgeIPv4(br); err != nil {
|
if err := setupBridgeIPv4(br); err != nil {
|
||||||
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := SetupBridgeIPv6(br); err != nil {
|
if err := setupBridgeIPv6(br); err != nil {
|
||||||
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
t.Fatalf("Assign IPv4 to bridge failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := SetupFixedCIDRv6(br); err != nil {
|
if err := setupFixedCIDRv6(br); err != nil {
|
||||||
t.Fatalf("Failed to setup bridge FixedCIDRv6: %v", err)
|
t.Fatalf("Failed to setup bridge FixedCIDRv6: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,18 +6,18 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
IPV4_FORW_CONF_FILE = "/proc/sys/net/ipv4/ip_forward"
|
ipv4ForwardConf = "/proc/sys/net/ipv4/ip_forward"
|
||||||
PERM = 0644
|
ipv4ForwardConfPerm = 0644
|
||||||
)
|
)
|
||||||
|
|
||||||
func SetupIPForwarding(i *Interface) error {
|
func setupIPForwarding(i *bridgeInterface) error {
|
||||||
// Sanity Check
|
// Sanity Check
|
||||||
if i.Config.EnableIPForwarding == false {
|
if i.Config.EnableIPForwarding == false {
|
||||||
return fmt.Errorf("Unexpected request to enable IP Forwarding for: %v", *i)
|
return fmt.Errorf("Unexpected request to enable IP Forwarding for: %v", *i)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable IPv4 forwarding
|
// Enable IPv4 forwarding
|
||||||
if err := ioutil.WriteFile(IPV4_FORW_CONF_FILE, []byte{'1', '\n'}, PERM); err != nil {
|
if err := ioutil.WriteFile(ipv4ForwardConf, []byte{'1', '\n'}, ipv4ForwardConfPerm); err != nil {
|
||||||
return fmt.Errorf("Setup IP forwarding failed: %v", err)
|
return fmt.Errorf("Setup IP forwarding failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ func TestSetupIPForwarding(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create test interface with ip forwarding setting enabled
|
// Create test interface with ip forwarding setting enabled
|
||||||
br := &Interface{
|
br := &bridgeInterface{
|
||||||
Config: &Configuration{
|
Config: &Configuration{
|
||||||
BridgeName: DefaultBridgeName,
|
BridgeName: DefaultBridgeName,
|
||||||
EnableIPForwarding: true,
|
EnableIPForwarding: true,
|
||||||
|
@ -26,7 +26,7 @@ func TestSetupIPForwarding(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set IP Forwarding
|
// Set IP Forwarding
|
||||||
if err := SetupIPForwarding(br); err != nil {
|
if err := setupIPForwarding(br); err != nil {
|
||||||
t.Fatalf("Failed to setup IP forwarding: %v", err)
|
t.Fatalf("Failed to setup IP forwarding: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ func TestUnexpectedSetupIPForwarding(t *testing.T) {
|
||||||
defer reconcileIPForwardingSetting(t, procSetting)
|
defer reconcileIPForwardingSetting(t, procSetting)
|
||||||
|
|
||||||
// Create test interface without ip forwarding setting enabled
|
// Create test interface without ip forwarding setting enabled
|
||||||
br := &Interface{
|
br := &bridgeInterface{
|
||||||
Config: &Configuration{
|
Config: &Configuration{
|
||||||
BridgeName: DefaultBridgeName,
|
BridgeName: DefaultBridgeName,
|
||||||
EnableIPForwarding: false,
|
EnableIPForwarding: false,
|
||||||
|
@ -51,7 +51,7 @@ func TestUnexpectedSetupIPForwarding(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt Set IP Forwarding
|
// Attempt Set IP Forwarding
|
||||||
if err := SetupIPForwarding(br); err == nil {
|
if err := setupIPForwarding(br); err == nil {
|
||||||
t.Fatal("Setup IP forwarding was expected to fail")
|
t.Fatal("Setup IP forwarding was expected to fail")
|
||||||
} else if !strings.Contains(err.Error(), "Unexpected request") {
|
} else if !strings.Contains(err.Error(), "Unexpected request") {
|
||||||
t.Fatalf("Setup IP forwarding failed with unexpected error: %v", err)
|
t.Fatalf("Setup IP forwarding failed with unexpected error: %v", err)
|
||||||
|
@ -59,7 +59,7 @@ func TestUnexpectedSetupIPForwarding(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func readCurrentIPForwardingSetting(t *testing.T) []byte {
|
func readCurrentIPForwardingSetting(t *testing.T) []byte {
|
||||||
procSetting, err := ioutil.ReadFile(IPV4_FORW_CONF_FILE)
|
procSetting, err := ioutil.ReadFile(ipv4ForwardConf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Can't execute test: Failed to read current IP forwarding setting: %v", err)
|
t.Fatalf("Can't execute test: Failed to read current IP forwarding setting: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ func readCurrentIPForwardingSetting(t *testing.T) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeIPForwardingSetting(t *testing.T, chars []byte) {
|
func writeIPForwardingSetting(t *testing.T, chars []byte) {
|
||||||
err := ioutil.WriteFile(IPV4_FORW_CONF_FILE, chars, PERM)
|
err := ioutil.WriteFile(ipv4ForwardConf, chars, ipv4ForwardConfPerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Can't execute or cleanup after test: Failed to reset IP forwarding: %v", err)
|
t.Fatalf("Can't execute or cleanup after test: Failed to reset IP forwarding: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ func init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetupBridgeIPv4(i *Interface) error {
|
func setupBridgeIPv4(i *bridgeInterface) error {
|
||||||
bridgeIPv4, err := electBridgeIPv4(i.Config)
|
bridgeIPv4, err := electBridgeIPv4(i.Config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -8,13 +8,13 @@ import (
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
)
|
)
|
||||||
|
|
||||||
func setupTestInterface(t *testing.T) *Interface {
|
func setupTestInterface(t *testing.T) *bridgeInterface {
|
||||||
br := &Interface{
|
br := &bridgeInterface{
|
||||||
Config: &Configuration{
|
Config: &Configuration{
|
||||||
BridgeName: DefaultBridgeName,
|
BridgeName: DefaultBridgeName,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if err := SetupDevice(br); err != nil {
|
if err := setupDevice(br); err != nil {
|
||||||
t.Fatalf("Bridge creation failed: %v", err)
|
t.Fatalf("Bridge creation failed: %v", err)
|
||||||
}
|
}
|
||||||
return br
|
return br
|
||||||
|
@ -30,7 +30,7 @@ func TestSetupBridgeIPv4Fixed(t *testing.T) {
|
||||||
|
|
||||||
br := setupTestInterface(t)
|
br := setupTestInterface(t)
|
||||||
br.Config.AddressIPv4 = &net.IPNet{IP: ip, Mask: netw.Mask}
|
br.Config.AddressIPv4 = &net.IPNet{IP: ip, Mask: netw.Mask}
|
||||||
if err := SetupBridgeIPv4(br); err != nil {
|
if err := setupBridgeIPv4(br); err != nil {
|
||||||
t.Fatalf("Failed to setup bridge IPv4: %v", err)
|
t.Fatalf("Failed to setup bridge IPv4: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ func TestSetupBridgeIPv4Auto(t *testing.T) {
|
||||||
defer libnetwork.SetupTestNetNS(t)()
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
br := setupTestInterface(t)
|
br := setupTestInterface(t)
|
||||||
if err := SetupBridgeIPv4(br); err != nil {
|
if err := setupBridgeIPv4(br); err != nil {
|
||||||
t.Fatalf("Failed to setup bridge IPv4: %v", err)
|
t.Fatalf("Failed to setup bridge IPv4: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,29 +8,29 @@ import (
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
)
|
)
|
||||||
|
|
||||||
var BridgeIPv6 *net.IPNet
|
var bridgeIPv6 *net.IPNet
|
||||||
|
|
||||||
const BridgeIPv6Str = "fe80::1/64"
|
const bridgeIPv6Str = "fe80::1/64"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// We allow ourselves to panic in this special case because we indicate a
|
// We allow ourselves to panic in this special case because we indicate a
|
||||||
// failure to parse a compile-time define constant.
|
// failure to parse a compile-time define constant.
|
||||||
if ip, netw, err := net.ParseCIDR(BridgeIPv6Str); err == nil {
|
if ip, netw, err := net.ParseCIDR(bridgeIPv6Str); err == nil {
|
||||||
BridgeIPv6 = &net.IPNet{IP: ip, Mask: netw.Mask}
|
bridgeIPv6 = &net.IPNet{IP: ip, Mask: netw.Mask}
|
||||||
} else {
|
} else {
|
||||||
panic(fmt.Sprintf("Cannot parse default bridge IPv6 address %q: %v", BridgeIPv6Str, err))
|
panic(fmt.Sprintf("Cannot parse default bridge IPv6 address %q: %v", bridgeIPv6Str, err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetupBridgeIPv6(i *Interface) error {
|
func setupBridgeIPv6(i *bridgeInterface) error {
|
||||||
// Enable IPv6 on the bridge
|
// Enable IPv6 on the bridge
|
||||||
procFile := "/proc/sys/net/ipv6/conf/" + i.Config.BridgeName + "/disable_ipv6"
|
procFile := "/proc/sys/net/ipv6/conf/" + i.Config.BridgeName + "/disable_ipv6"
|
||||||
if err := ioutil.WriteFile(procFile, []byte{'0', '\n'}, 0644); err != nil {
|
if err := ioutil.WriteFile(procFile, []byte{'0', '\n'}, 0644); err != nil {
|
||||||
return fmt.Errorf("Unable to enable IPv6 addresses on bridge: %v", err)
|
return fmt.Errorf("Unable to enable IPv6 addresses on bridge: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := netlink.AddrAdd(i.Link, &netlink.Addr{BridgeIPv6, ""}); err != nil {
|
if err := netlink.AddrAdd(i.Link, &netlink.Addr{bridgeIPv6, ""}); err != nil {
|
||||||
return fmt.Errorf("Failed to add IPv6 address %s to bridge: %v", BridgeIPv6, err)
|
return fmt.Errorf("Failed to add IPv6 address %s to bridge: %v", bridgeIPv6, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -14,7 +14,7 @@ func TestSetupIPv6(t *testing.T) {
|
||||||
defer libnetwork.SetupTestNetNS(t)()
|
defer libnetwork.SetupTestNetNS(t)()
|
||||||
|
|
||||||
br := setupTestInterface(t)
|
br := setupTestInterface(t)
|
||||||
if err := SetupBridgeIPv6(br); err != nil {
|
if err := setupBridgeIPv6(br); err != nil {
|
||||||
t.Fatalf("Failed to setup bridge IPv6: %v", err)
|
t.Fatalf("Failed to setup bridge IPv6: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,14 +34,14 @@ func TestSetupIPv6(t *testing.T) {
|
||||||
|
|
||||||
var found bool
|
var found bool
|
||||||
for _, addr := range addrsv6 {
|
for _, addr := range addrsv6 {
|
||||||
if BridgeIPv6Str == addr.IPNet.String() {
|
if bridgeIPv6Str == addr.IPNet.String() {
|
||||||
found = true
|
found = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
t.Fatalf("Bridge device does not have requested IPv6 address %v", BridgeIPv6Str)
|
t.Fatalf("Bridge device does not have requested IPv6 address %v", bridgeIPv6Str)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,9 @@ import (
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SetupVerifyConfiguredAddresses(i *Interface) error {
|
func setupVerifyConfiguredAddresses(i *bridgeInterface) error {
|
||||||
// Fetch a single IPv4 and a slice of IPv6 addresses from the bridge.
|
// Fetch a single IPv4 and a slice of IPv6 addresses from the bridge.
|
||||||
addrv4, addrsv6, err := i.Addresses()
|
addrv4, addrsv6, err := i.addresses()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,8 @@ func SetupVerifyConfiguredAddresses(i *Interface) error {
|
||||||
|
|
||||||
// Verify that one of the bridge IPv6 addresses matches the requested
|
// Verify that one of the bridge IPv6 addresses matches the requested
|
||||||
// configuration.
|
// configuration.
|
||||||
if i.Config.EnableIPv6 && !findIPv6Address(netlink.Addr{IPNet: BridgeIPv6}, addrsv6) {
|
if i.Config.EnableIPv6 && !findIPv6Address(netlink.Addr{IPNet: bridgeIPv6}, addrsv6) {
|
||||||
return fmt.Errorf("Bridge IPv6 addresses do not match the expected bridge configuration %s", BridgeIPv6)
|
return fmt.Errorf("Bridge IPv6 addresses do not match the expected bridge configuration %s", bridgeIPv6)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -8,8 +8,8 @@ import (
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
)
|
)
|
||||||
|
|
||||||
func setupVerifyTest(t *testing.T) *Interface {
|
func setupVerifyTest(t *testing.T) *bridgeInterface {
|
||||||
inf := &Interface{Config: &Configuration{}}
|
inf := &bridgeInterface{Config: &Configuration{}}
|
||||||
|
|
||||||
br := netlink.Bridge{}
|
br := netlink.Bridge{}
|
||||||
br.LinkAttrs.Name = "default0"
|
br.LinkAttrs.Name = "default0"
|
||||||
|
@ -33,7 +33,7 @@ func TestSetupVerify(t *testing.T) {
|
||||||
t.Fatalf("Failed to assign IPv4 %s to interface: %v", inf.Config.AddressIPv4, err)
|
t.Fatalf("Failed to assign IPv4 %s to interface: %v", inf.Config.AddressIPv4, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := SetupVerifyConfiguredAddresses(inf); err != nil {
|
if err := setupVerifyConfiguredAddresses(inf); err != nil {
|
||||||
t.Fatalf("Address verification failed: %v", err)
|
t.Fatalf("Address verification failed: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ func TestSetupVerifyBad(t *testing.T) {
|
||||||
t.Fatalf("Failed to assign IPv4 %s to interface: %v", ipnet, err)
|
t.Fatalf("Failed to assign IPv4 %s to interface: %v", ipnet, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := SetupVerifyConfiguredAddresses(inf); err == nil {
|
if err := setupVerifyConfiguredAddresses(inf); err == nil {
|
||||||
t.Fatal("Address verification was expected to fail")
|
t.Fatal("Address verification was expected to fail")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ func TestSetupVerifyMissing(t *testing.T) {
|
||||||
inf := setupVerifyTest(t)
|
inf := setupVerifyTest(t)
|
||||||
inf.Config.AddressIPv4 = &net.IPNet{IP: addrv4, Mask: addrv4.DefaultMask()}
|
inf.Config.AddressIPv4 = &net.IPNet{IP: addrv4, Mask: addrv4.DefaultMask()}
|
||||||
|
|
||||||
if err := SetupVerifyConfiguredAddresses(inf); err == nil {
|
if err := setupVerifyConfiguredAddresses(inf); err == nil {
|
||||||
t.Fatal("Address verification was expected to fail")
|
t.Fatal("Address verification was expected to fail")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,14 +75,14 @@ func TestSetupVerifyIPv6(t *testing.T) {
|
||||||
inf.Config.AddressIPv4 = &net.IPNet{IP: addrv4, Mask: addrv4.DefaultMask()}
|
inf.Config.AddressIPv4 = &net.IPNet{IP: addrv4, Mask: addrv4.DefaultMask()}
|
||||||
inf.Config.EnableIPv6 = true
|
inf.Config.EnableIPv6 = true
|
||||||
|
|
||||||
if err := netlink.AddrAdd(inf.Link, &netlink.Addr{IPNet: BridgeIPv6}); err != nil {
|
if err := netlink.AddrAdd(inf.Link, &netlink.Addr{IPNet: bridgeIPv6}); err != nil {
|
||||||
t.Fatalf("Failed to assign IPv6 %s to interface: %v", BridgeIPv6, err)
|
t.Fatalf("Failed to assign IPv6 %s to interface: %v", bridgeIPv6, err)
|
||||||
}
|
}
|
||||||
if err := netlink.AddrAdd(inf.Link, &netlink.Addr{IPNet: inf.Config.AddressIPv4}); err != nil {
|
if err := netlink.AddrAdd(inf.Link, &netlink.Addr{IPNet: inf.Config.AddressIPv4}); err != nil {
|
||||||
t.Fatalf("Failed to assign IPv4 %s to interface: %v", inf.Config.AddressIPv4, err)
|
t.Fatalf("Failed to assign IPv4 %s to interface: %v", inf.Config.AddressIPv4, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := SetupVerifyConfiguredAddresses(inf); err != nil {
|
if err := setupVerifyConfiguredAddresses(inf); err != nil {
|
||||||
t.Fatalf("Address verification failed: %v", err)
|
t.Fatalf("Address verification failed: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ func TestSetupVerifyIPv6Missing(t *testing.T) {
|
||||||
t.Fatalf("Failed to assign IPv4 %s to interface: %v", inf.Config.AddressIPv4, err)
|
t.Fatalf("Failed to assign IPv4 %s to interface: %v", inf.Config.AddressIPv4, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := SetupVerifyConfiguredAddresses(inf); err == nil {
|
if err := setupVerifyConfiguredAddresses(inf); err == nil {
|
||||||
t.Fatal("Address verification was expected to fail")
|
t.Fatal("Address verification was expected to fail")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,13 +96,14 @@ type Namespace interface {
|
||||||
AddInterface(*Interface) error
|
AddInterface(*Interface) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new network of the specified networkType. The options are driver
|
// NewNetwork creates a new network of the specified networkType. The options
|
||||||
// specific and modeled in a generic way.
|
// are driver specific and modeled in a generic way.
|
||||||
func NewNetwork(networkType, name string, options DriverParams) (Network, error) {
|
func NewNetwork(networkType, name string, options DriverParams) (Network, error) {
|
||||||
return createNetwork(networkType, name, options)
|
return createNetwork(networkType, name, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new network namespace mounted on the specified path.
|
// NewNetworkNamespace creates a new network namespace mounted on the specified
|
||||||
|
// path.
|
||||||
func NewNetworkNamespace(path string) (Namespace, error) {
|
func NewNetworkNamespace(path string) (Namespace, error) {
|
||||||
return createNetworkNamespace(path)
|
return createNetworkNamespace(path)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// The options package provides a way to pass unstructured sets of options to a
|
// Package options provides a way to pass unstructured sets of options to a
|
||||||
// component expecting a strongly-typed configuration structure.
|
// component expecting a strongly-typed configuration structure.
|
||||||
package options
|
package options
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NoSuchFieldError is the error returned when the generic parameters hold a
|
||||||
|
// value for a field absent from the destination structure.
|
||||||
type NoSuchFieldError struct {
|
type NoSuchFieldError struct {
|
||||||
Field string
|
Field string
|
||||||
Type string
|
Type string
|
||||||
|
@ -16,6 +18,8 @@ func (e NoSuchFieldError) Error() string {
|
||||||
return fmt.Sprintf("no field %q in type %q", e.Field, e.Type)
|
return fmt.Sprintf("no field %q in type %q", e.Field, e.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CannotSetFieldError is the error returned when the generic parameters hold a
|
||||||
|
// value for a field that cannot be set in the destination structure.
|
||||||
type CannotSetFieldError struct {
|
type CannotSetFieldError struct {
|
||||||
Field string
|
Field string
|
||||||
Type string
|
Type string
|
||||||
|
@ -25,12 +29,20 @@ func (e CannotSetFieldError) Error() string {
|
||||||
return fmt.Sprintf("cannot set field %q of type %q", e.Field, e.Type)
|
return fmt.Sprintf("cannot set field %q of type %q", e.Field, e.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generic is an basic type to store arbitrary settings.
|
||||||
type Generic map[string]interface{}
|
type Generic map[string]interface{}
|
||||||
|
|
||||||
|
// NewGeneric returns a new Generic instance.
|
||||||
func NewGeneric() Generic {
|
func NewGeneric() Generic {
|
||||||
return make(Generic)
|
return make(Generic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GenerateFromModel takes the generic options, and tries to build a new
|
||||||
|
// instance of the model's type by matching keys from the generic options to
|
||||||
|
// fields in the model.
|
||||||
|
//
|
||||||
|
// The return value is of the same type than the model (including a potential
|
||||||
|
// pointer qualifier).
|
||||||
func GenerateFromModel(options Generic, model interface{}) (interface{}, error) {
|
func GenerateFromModel(options Generic, model interface{}) (interface{}, error) {
|
||||||
modType := reflect.TypeOf(model)
|
modType := reflect.TypeOf(model)
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ func setupInNS(nsPath string, settings *Interface) error {
|
||||||
|
|
||||||
// Move the executing code to the destination namespace so we can start
|
// Move the executing code to the destination namespace so we can start
|
||||||
// configure the interface.
|
// configure the interface.
|
||||||
if err := Setns(nsFD, syscall.CLONE_NEWNET); err != nil {
|
if err := setns(nsFD, syscall.CLONE_NEWNET); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ var setNsMap = map[string]uintptr{
|
||||||
"linux/s390x": 339,
|
"linux/s390x": 339,
|
||||||
}
|
}
|
||||||
|
|
||||||
func Setns(fd uintptr, flags uintptr) error {
|
func setns(fd uintptr, flags uintptr) error {
|
||||||
ns, exists := setNsMap[fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)]
|
ns, exists := setNsMap[fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)]
|
||||||
if !exists {
|
if !exists {
|
||||||
return fmt.Errorf("unsupported platform %s/%s", runtime.GOOS, runtime.GOARCH)
|
return fmt.Errorf("unsupported platform %s/%s", runtime.GOOS, runtime.GOARCH)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue