Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Commit

Permalink
macvlan: Assign random MAC address
Browse files Browse the repository at this point in the history
Macvtap interfaces require mac addresses to be unique even
though they may be in a separate namespace. Hence use a randomly
generate MAC address.

Signed-off-by: Archana Shinde <[email protected]>
  • Loading branch information
amshinde committed Oct 2, 2018
1 parent 8847af8 commit 581ff17
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 8 deletions.
37 changes: 31 additions & 6 deletions virtcontainers/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package virtcontainers

import (
cryptoRand "crypto/rand"
"encoding/hex"
"encoding/json"
"fmt"
Expand Down Expand Up @@ -1345,7 +1346,10 @@ func createVirtualNetworkEndpoint(idx int, ifName string, interworkingModel NetI
return &VirtualEndpoint{}, fmt.Errorf("invalid network endpoint index: %d", idx)
}

netPair := createNetworkInterfacePair(idx, ifName, interworkingModel)
netPair, err := createNetworkInterfacePair(idx, ifName, interworkingModel)
if err != nil {
return nil, err
}

endpoint := &VirtualEndpoint{
// TODO This is too specific. We may need to create multiple
Expand All @@ -1366,7 +1370,10 @@ func createBridgedMacvlanNetworkEndpoint(idx int, ifName string, interworkingMod
return &BridgedMacvlanEndpoint{}, fmt.Errorf("invalid network endpoint index: %d", idx)
}

netPair := createNetworkInterfacePair(idx, ifName, interworkingModel)
netPair, err := createNetworkInterfacePair(idx, ifName, interworkingModel)
if err != nil {
return nil, err
}

endpoint := &BridgedMacvlanEndpoint{
NetPair: netPair,
Expand Down Expand Up @@ -1466,26 +1473,44 @@ func generateInterfacesAndRoutes(networkNS NetworkNamespace) ([]*grpc.Interface,
return ifaces, routes, nil
}

func createNetworkInterfacePair(idx int, ifName string, interworkingModel NetInterworkingModel) NetworkInterfacePair {
func createNetworkInterfacePair(idx int, ifName string, interworkingModel NetInterworkingModel) (NetworkInterfacePair, error) {
uniqueID := uuid.Generate().String()

hardAddr := net.HardwareAddr{0x02, 0x00, 0xCA, 0xFE, byte(idx >> 8), byte(idx)}
randomMacAddr, err := generateRandomPrivateMacAddr()
if err != nil {
return NetworkInterfacePair{}, fmt.Errorf("Could not generate random mac address: %s", err)
}

netPair := NetworkInterfacePair{
ID: uniqueID,
Name: fmt.Sprintf("br%d_kata", idx),
VirtIface: NetworkInterface{
Name: fmt.Sprintf("eth%d", idx),
HardAddr: hardAddr.String(),
HardAddr: randomMacAddr,
},
TAPIface: NetworkInterface{
Name: fmt.Sprintf("tap%d_kata", idx),
},
NetInterworkingModel: interworkingModel,
}

return netPair
return netPair, nil
}

func generateRandomPrivateMacAddr() (string, error) {
buf := make([]byte, 6)
_, err := cryptoRand.Read(buf)
if err != nil {
return "", err
}

// Set the local bit for local addresses
// Addresses in this range are local mac addresses:
// x2-xx-xx-xx-xx-xx , x6-xx-xx-xx-xx-xx , xA-xx-xx-xx-xx-xx , xE-xx-xx-xx-xx-xx
buf[0] = (buf[0] | 2) & 0xfe

hardAddr := net.HardwareAddr(buf)
return hardAddr.String(), nil
}

func networkInfoFromLink(handle *netlink.Handle, link netlink.Link) (NetworkInfo, error) {
Expand Down
10 changes: 8 additions & 2 deletions virtcontainers/network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,11 @@ func TestCreateVirtualNetworkEndpoint(t *testing.T) {
// the resulting ID will be random - so let's overwrite to test the rest of the flow
result.NetPair.ID = "uniqueTestID-4"

// the resulting mac address will be random - so lets overwrite it
result.NetPair.VirtIface.HardAddr = macAddr.String()

if reflect.DeepEqual(result, expected) == false {
t.Fatal()
t.Fatalf("\nGot: %+v, \n\nExpected: %+v", result, expected)
}
}

Expand Down Expand Up @@ -262,8 +265,11 @@ func TestCreateVirtualNetworkEndpointChooseIfaceName(t *testing.T) {
// the resulting ID will be random - so let's overwrite to test the rest of the flow
result.NetPair.ID = "uniqueTestID-4"

// the resulting mac address will be random - so lets overwrite it
result.NetPair.VirtIface.HardAddr = macAddr.String()

if reflect.DeepEqual(result, expected) == false {
t.Fatal()
t.Fatalf("\nGot: %+v, \n\nExpected: %+v", result, expected)
}
}

Expand Down

0 comments on commit 581ff17

Please sign in to comment.