Skip to content

Commit 77c1c58

Browse files
committed
Merge pull request #803 from aboch/pm
Libnetwork to program container interface's MAC
2 parents 5718b0b + 48d1403 commit 77c1c58

7 files changed

Lines changed: 46 additions & 62 deletions

File tree

drivers/bridge/bridge.go

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -951,28 +951,19 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
951951
}
952952
}
953953

954-
// Create the sandbox side pipe interface
954+
// Store the sandbox side pipe interface parameters
955955
endpoint.srcName = containerIfName
956956
endpoint.macAddress = ifInfo.MacAddress()
957957
endpoint.addr = ifInfo.Address()
958958
endpoint.addrv6 = ifInfo.AddressIPv6()
959959

960-
// Down the interface before configuring mac address.
961-
if err = netlink.LinkSetDown(sbox); err != nil {
962-
return fmt.Errorf("could not set link down for container interface %s: %v", containerIfName, err)
963-
}
964-
965-
// Set the sbox's MAC. If specified, use the one configured by user, otherwise generate one based on IP.
960+
// Set the sbox's MAC if not provided. If specified, use the one configured by user, otherwise generate one based on IP.
966961
if endpoint.macAddress == nil {
967962
endpoint.macAddress = electMacAddress(epConfig, endpoint.addr.IP)
968-
if err := ifInfo.SetMacAddress(endpoint.macAddress); err != nil {
963+
if err = ifInfo.SetMacAddress(endpoint.macAddress); err != nil {
969964
return err
970965
}
971966
}
972-
err = netlink.LinkSetHardwareAddr(sbox, endpoint.macAddress)
973-
if err != nil {
974-
return fmt.Errorf("could not set mac address for container interface %s: %v", containerIfName, err)
975-
}
976967

977968
// Up the host interface after finishing all netlink configuration
978969
if err = netlink.LinkSetUp(host); err != nil {
@@ -999,7 +990,7 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo,
999990
}
1000991

1001992
endpoint.addrv6 = &net.IPNet{IP: ip6, Mask: network.Mask}
1002-
if err := ifInfo.SetIPAddress(endpoint.addrv6); err != nil {
993+
if err = ifInfo.SetIPAddress(endpoint.addrv6); err != nil {
1003994
return err
1004995
}
1005996
}

drivers/bridge/bridge_test.go

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package bridge
22

33
import (
4-
"bytes"
54
"fmt"
65
"net"
76
"regexp"
@@ -13,7 +12,6 @@ import (
1312
"github.com/docker/libnetwork/netlabel"
1413
"github.com/docker/libnetwork/testutils"
1514
"github.com/docker/libnetwork/types"
16-
"github.com/vishvananda/netlink"
1715
)
1816

1917
func getIPv4Data(t *testing.T) []driverapi.IPAMData {
@@ -506,50 +504,6 @@ func testQueryEndpointInfo(t *testing.T, ulPxyEnabled bool) {
506504
}
507505
}
508506

509-
func TestCreateLinkWithOptions(t *testing.T) {
510-
defer testutils.SetupTestOSContext(t)()
511-
d := newDriver()
512-
513-
if err := d.configure(nil); err != nil {
514-
t.Fatalf("Failed to setup driver config: %v", err)
515-
}
516-
517-
netconfig := &networkConfiguration{BridgeName: DefaultBridgeName}
518-
netOptions := make(map[string]interface{})
519-
netOptions[netlabel.GenericData] = netconfig
520-
521-
ipdList := getIPv4Data(t)
522-
err := d.CreateNetwork("net1", netOptions, ipdList, nil)
523-
if err != nil {
524-
t.Fatalf("Failed to create bridge: %v", err)
525-
}
526-
527-
mac := net.HardwareAddr([]byte{0x1e, 0x67, 0x66, 0x44, 0x55, 0x66})
528-
epOptions := make(map[string]interface{})
529-
epOptions[netlabel.MacAddress] = mac
530-
531-
te := newTestEndpoint(ipdList[0].Pool, 11)
532-
err = d.CreateEndpoint("net1", "ep", te.Interface(), epOptions)
533-
if err != nil {
534-
t.Fatalf("Failed to create an endpoint: %s", err.Error())
535-
}
536-
537-
err = d.Join("net1", "ep", "sbox", te, nil)
538-
if err != nil {
539-
t.Fatalf("Failed to join the endpoint: %v", err)
540-
}
541-
542-
ifaceName := te.iface.srcName
543-
veth, err := netlink.LinkByName(ifaceName)
544-
if err != nil {
545-
t.Fatal(err)
546-
}
547-
548-
if !bytes.Equal(mac, veth.Attrs().HardwareAddr) {
549-
t.Fatalf("Failed to parse and program endpoint configuration")
550-
}
551-
}
552-
553507
func getExposedPorts() []types.TransportPort {
554508
return []types.TransportPort{
555509
{Proto: types.TCP, Port: uint16(5000)},

drivers/remote/driver_test.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package remote
22

33
import (
4+
"bytes"
45
"encoding/json"
56
"fmt"
67
"io"
@@ -292,7 +293,7 @@ func TestRemoteDriver(t *testing.T) {
292293
dst: "vethdst",
293294
address: "192.168.5.7/16",
294295
addressIPv6: "2001:DB8::5:7/48",
295-
macAddress: "",
296+
macAddress: "ab:cd:ef:ee:ee:ee",
296297
gateway: "192.168.0.1",
297298
gatewayIPv6: "2001:DB8::1",
298299
hostsPath: "/here/comes/the/host/path",
@@ -328,7 +329,9 @@ func TestRemoteDriver(t *testing.T) {
328329
})
329330
handle(t, mux, "CreateEndpoint", func(msg map[string]interface{}) interface{} {
330331
iface := map[string]interface{}{
331-
"MacAddress": ep.macAddress,
332+
"MacAddress": ep.macAddress,
333+
"Address": ep.address,
334+
"AddressIPv6": ep.addressIPv6,
332335
}
333336
return map[string]interface{}{
334337
"Interface": iface,
@@ -403,11 +406,19 @@ func TestRemoteDriver(t *testing.T) {
403406
}
404407

405408
endID := "dummy-endpoint"
406-
err = d.CreateEndpoint(netID, endID, ep, map[string]interface{}{})
409+
ifInfo := &testEndpoint{}
410+
err = d.CreateEndpoint(netID, endID, ifInfo, map[string]interface{}{})
407411
if err != nil {
408412
t.Fatal(err)
409413
}
410414

415+
if !bytes.Equal(ep.MacAddress(), ifInfo.MacAddress()) || !types.CompareIPNet(ep.Address(), ifInfo.Address()) ||
416+
!types.CompareIPNet(ep.AddressIPv6(), ifInfo.AddressIPv6()) {
417+
t.Fatalf("Unexpected InterfaceInfo data. Expected (%s, %s, %s). Got (%v, %v, %v)",
418+
ep.MacAddress(), ep.Address(), ep.AddressIPv6(),
419+
ifInfo.MacAddress(), ifInfo.Address(), ifInfo.AddressIPv6())
420+
}
421+
411422
joinOpts := map[string]interface{}{"foo": "fooValue"}
412423
err = d.Join(netID, endID, "sandbox-key", ep, joinOpts)
413424
if err != nil {

osl/interface_linux.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type nwIface struct {
2121
dstName string
2222
master string
2323
dstMaster string
24+
mac net.HardwareAddr
2425
address *net.IPNet
2526
addressIPv6 *net.IPNet
2627
routes []*net.IPNet
@@ -64,6 +65,13 @@ func (i *nwIface) Master() string {
6465
return i.master
6566
}
6667

68+
func (i *nwIface) MacAddress() net.HardwareAddr {
69+
i.Lock()
70+
defer i.Unlock()
71+
72+
return types.GetMacCopy(i.mac)
73+
}
74+
6775
func (i *nwIface) Address() *net.IPNet {
6876
i.Lock()
6977
defer i.Unlock()
@@ -304,6 +312,7 @@ func configureInterface(iface netlink.Link, i *nwIface) error {
304312
ErrMessage string
305313
}{
306314
{setInterfaceName, fmt.Sprintf("error renaming interface %q to %q", ifaceName, i.DstName())},
315+
{setInterfaceMAC, fmt.Sprintf("error setting interface %q MAC to %q", ifaceName, i.MacAddress())},
307316
{setInterfaceIP, fmt.Sprintf("error setting interface %q IP to %q", ifaceName, i.Address())},
308317
{setInterfaceIPv6, fmt.Sprintf("error setting interface %q IPv6 to %q", ifaceName, i.AddressIPv6())},
309318
{setInterfaceMaster, fmt.Sprintf("error setting interface %q master to %q", ifaceName, i.DstMaster())},
@@ -326,6 +335,13 @@ func setInterfaceMaster(iface netlink.Link, i *nwIface) error {
326335
LinkAttrs: netlink.LinkAttrs{Name: i.DstMaster()}})
327336
}
328337

338+
func setInterfaceMAC(iface netlink.Link, i *nwIface) error {
339+
if i.MacAddress() == nil {
340+
return nil
341+
}
342+
return netlink.LinkSetHardwareAddr(iface, i.MacAddress())
343+
}
344+
329345
func setInterfaceIP(iface netlink.Link, i *nwIface) error {
330346
if i.Address() == nil {
331347
return nil

osl/options_linux.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ func (n *networkNamespace) Master(name string) IfaceOption {
4242
}
4343
}
4444

45+
func (n *networkNamespace) MacAddress(mac net.HardwareAddr) IfaceOption {
46+
return func(i *nwIface) {
47+
i.mac = mac
48+
}
49+
}
50+
4551
func (n *networkNamespace) Address(addr *net.IPNet) IfaceOption {
4652
return func(i *nwIface) {
4753
i.address = addr

osl/sandbox.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ type IfaceOptionSetter interface {
7676
// Bridge returns an option setter to set if the interface is a bridge.
7777
Bridge(bool) IfaceOption
7878

79+
// MacAddress returns an option setter to set the MAC address.
80+
MacAddress(net.HardwareAddr) IfaceOption
81+
7982
// Address returns an option setter to set IPv4 address.
8083
Address(*net.IPNet) IfaceOption
8184

sandbox.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,9 @@ func (sb *sandbox) populateNetworkResources(ep *endpoint) error {
613613
if i.addrv6 != nil && i.addrv6.IP.To16() != nil {
614614
ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().AddressIPv6(i.addrv6))
615615
}
616+
if i.mac != nil {
617+
ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().MacAddress(i.mac))
618+
}
616619

617620
if err := sb.osSbox.AddInterface(i.srcName, i.dstPrefix, ifaceOptions...); err != nil {
618621
return fmt.Errorf("failed to add interface %s to sandbox: %v", i.srcName, err)

0 commit comments

Comments
 (0)