mirror of
https://github.com/clearlinux/libnetwork.git
synced 2026-05-14 02:23:34 +00:00
Merge pull request #193 from mrjana/cnm
Modify driver Join api to only allow dst prefix
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user