Merge pull request #193 from mrjana/cnm

Modify driver Join api to only allow dst prefix
This commit is contained in:
Madhu Venugopal
2015-05-21 13:58:22 -07:00
8 changed files with 108 additions and 28 deletions

View File

@@ -83,8 +83,8 @@ type InterfaceInfo interface {
// InterfaceNameInfo provides a go interface for the drivers to assign names
// to interfaces.
type InterfaceNameInfo interface {
// SetNames method assigns the srcName and dstName for the interface.
SetNames(srcName, dstName string) error
// SetNames method assigns the srcName and dstPrefix for the interface.
SetNames(srcName, dstPrefix string) error
// ID returns the numerical id that was assigned to the interface by the driver
// CreateEndpoint.

View File

@@ -21,7 +21,7 @@ const (
networkType = "bridge"
vethPrefix = "veth"
vethLen = 7
containerVeth = "eth0"
containerVethPrefix = "eth"
maxAllocatePortAttempts = 10
ifaceID = 1
)
@@ -545,7 +545,7 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn
// Create the sandbox side pipe interface
intf := &sandbox.Interface{}
intf.SrcName = name2
intf.DstName = containerVeth
intf.DstName = containerVethPrefix
intf.Address = ipv4Addr
if config.EnableIPv6 {

View File

@@ -291,7 +291,7 @@ func (ep *endpoint) Join(containerID string, options ...EndpointOption) (*Contai
for _, i := range ifaces {
iface := &sandbox.Interface{
SrcName: i.srcName,
DstName: i.dstName,
DstName: i.dstPrefix,
Address: &i.addr,
}
if i.addrv6.IP.To16() != nil {

View File

@@ -40,12 +40,12 @@ type InterfaceInfo interface {
}
type endpointInterface struct {
id int
mac net.HardwareAddr
addr net.IPNet
addrv6 net.IPNet
srcName string
dstName string
id int
mac net.HardwareAddr
addr net.IPNet
addrv6 net.IPNet
srcName string
dstPrefix string
}
type endpointJoinInfo struct {
@@ -130,9 +130,9 @@ func (i *endpointInterface) AddressIPv6() net.IPNet {
return (*types.GetIPNetCopy(&i.addrv6))
}
func (i *endpointInterface) SetNames(srcName string, dstName string) error {
func (i *endpointInterface) SetNames(srcName string, dstPrefix string) error {
i.srcName = srcName
i.dstName = dstName
i.dstPrefix = dstPrefix
return nil
}

View File

@@ -23,6 +23,7 @@ import (
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/options"
"github.com/docker/libnetwork/types"
"github.com/vishvananda/netlink"
"github.com/vishvananda/netns"
)
@@ -730,6 +731,35 @@ func TestNetworkQuery(t *testing.T) {
const containerID = "valid_container"
func checkSandbox(t *testing.T, info libnetwork.EndpointInfo) {
origns, err := netns.Get()
if err != nil {
t.Fatalf("Could not get the current netns: %v", err)
}
defer origns.Close()
key := info.SandboxKey()
f, err := os.OpenFile(key, os.O_RDONLY, 0)
if err != nil {
t.Fatalf("Failed to open network namespace path %q: %v", key, err)
}
defer f.Close()
runtime.LockOSThread()
defer runtime.UnlockOSThread()
nsFD := f.Fd()
if err = netns.Set(netns.NsHandle(nsFD)); err != nil {
t.Fatalf("Setting to the namespace pointed to by the sandbox %s failed: %v", key, err)
}
defer netns.Set(origns)
_, err = netlink.LinkByName("eth0")
if err != nil {
t.Fatalf("Could not find the interface eth0 inside the sandbox: %v", err)
}
}
func TestEndpointJoin(t *testing.T) {
if !netutils.IsRunningInContainer() {
defer netutils.SetupTestNetNS(t)()
@@ -786,6 +816,8 @@ func TestEndpointJoin(t *testing.T) {
if info.SandboxKey() == "" {
t.Fatalf("Expected an non-empty sandbox key for a joined endpoint. Instead found a empty sandbox key")
}
checkSandbox(t, info)
}
func TestEndpointJoinInvalidContainerId(t *testing.T) {

View File

@@ -20,8 +20,10 @@ var once sync.Once
// interface. It represents a linux network namespace, and moves an interface
// into it when called on method AddInterface or sets the gateway etc.
type networkNamespace struct {
path string
sinfo *Info
path string
sinfo *Info
nextIfIndex int
sync.Mutex
}
func createBasePath() {
@@ -167,6 +169,11 @@ func (n *networkNamespace) RemoveInterface(i *Interface) error {
}
func (n *networkNamespace) AddInterface(i *Interface) error {
n.Lock()
i.DstName = fmt.Sprintf("%s%d", i.DstName, n.nextIfIndex)
n.nextIfIndex++
n.Unlock()
runtime.LockOSThread()
defer runtime.UnlockOSThread()
@@ -214,7 +221,10 @@ func (n *networkNamespace) AddInterface(i *Interface) error {
return err
}
n.Lock()
n.sinfo.Interfaces = append(n.sinfo.Interfaces, i)
n.Unlock()
return nil
}

View File

@@ -20,7 +20,9 @@ type Sandbox interface {
// Add an existing Interface to this sandbox. The operation will rename
// from the Interface SrcName to DstName as it moves, and reconfigure the
// interface according to the specified settings.
// interface according to the specified settings. The caller is expected
// to only provide a prefix for DstName. The AddInterface api will auto-generate
// an appropriate suffix for the DstName to disambiguate.
AddInterface(*Interface) error
// Remove an interface from the sandbox by renamin to original name
@@ -62,7 +64,9 @@ type Interface struct {
SrcName string
// The name that will be assigned to the interface once moves inside a
// network namespace.
// network namespace. When the caller passes in a DstName, it is only
// expected to pass a prefix. The name will modified with an appropriately
// auto-generated suffix.
DstName string
// IPv4 address for the interface.

View File

@@ -15,6 +15,8 @@ import (
const (
vethName1 = "wierdlongname1"
vethName2 = "wierdlongname2"
vethName3 = "wierdlongname3"
vethName4 = "wierdlongname4"
sboxIfaceName = "containername"
)
@@ -36,33 +38,59 @@ func newInfo(t *testing.T) (*Info, error) {
veth := &netlink.Veth{
LinkAttrs: netlink.LinkAttrs{Name: vethName1, TxQLen: 0},
PeerName: vethName2}
err := netlink.LinkAdd(veth)
if err != nil {
if err := netlink.LinkAdd(veth); err != nil {
return nil, err
}
// Store the sandbox side pipe interface
// This is needed for cleanup on DeleteEndpoint()
intf := &Interface{}
intf.SrcName = vethName2
intf.DstName = sboxIfaceName
intf1 := &Interface{}
intf1.SrcName = vethName2
intf1.DstName = sboxIfaceName
ip4, addr, err := net.ParseCIDR("192.168.1.100/24")
if err != nil {
return nil, err
}
intf.Address = addr
intf.Address.IP = ip4
intf1.Address = addr
intf1.Address.IP = ip4
// ip6, addrv6, err := net.ParseCIDR("2001:DB8::ABCD/48")
ip6, addrv6, err := net.ParseCIDR("fe80::2/64")
if err != nil {
return nil, err
}
intf.AddressIPv6 = addrv6
intf.AddressIPv6.IP = ip6
intf1.AddressIPv6 = addrv6
intf1.AddressIPv6.IP = ip6
sinfo := &Info{Interfaces: []*Interface{intf}}
veth = &netlink.Veth{
LinkAttrs: netlink.LinkAttrs{Name: vethName3, TxQLen: 0},
PeerName: vethName4}
if err := netlink.LinkAdd(veth); err != nil {
return nil, err
}
intf2 := &Interface{}
intf2.SrcName = vethName4
intf2.DstName = sboxIfaceName
ip4, addr, err = net.ParseCIDR("192.168.2.100/24")
if err != nil {
return nil, err
}
intf2.Address = addr
intf2.Address.IP = ip4
// ip6, addrv6, err := net.ParseCIDR("2001:DB8::ABCD/48")
ip6, addrv6, err = net.ParseCIDR("fe80::3/64")
if err != nil {
return nil, err
}
intf2.AddressIPv6 = addrv6
intf2.AddressIPv6.IP = ip6
sinfo := &Info{Interfaces: []*Interface{intf1, intf2}}
sinfo.Gateway = net.ParseIP("192.168.1.1")
// sinfo.GatewayIPv6 = net.ParseIP("2001:DB8::1")
sinfo.GatewayIPv6 = net.ParseIP("fe80::1")
@@ -97,7 +125,13 @@ func verifySandbox(t *testing.T, s Sandbox) {
}
defer netns.Set(origns)
_, err = netlink.LinkByName(sboxIfaceName)
_, err = netlink.LinkByName(sboxIfaceName + "0")
if err != nil {
t.Fatalf("Could not find the interface %s inside the sandbox: %v", sboxIfaceName,
err)
}
_, err = netlink.LinkByName(sboxIfaceName + "1")
if err != nil {
t.Fatalf("Could not find the interface %s inside the sandbox: %v", sboxIfaceName,
err)