Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions netlink/link_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ type LinkInfo struct {
MTU uint
TxQLen uint
ParentIndex int
MacAddress net.HardwareAddr
IPAddr net.IP
}

func (linkInfo *LinkInfo) Info() *LinkInfo {
Expand Down Expand Up @@ -123,6 +125,11 @@ func (Netlink) AddLink(link Link) error {
req.addPayload(newAttributeUint32(unix.IFLA_LINK, uint32(info.ParentIndex)))
}

// Set the mac address on the interface
if info.MacAddress != nil {
req.addPayload(newRtAttr(unix.IFLA_ADDRESS, []byte(info.MacAddress)))
}

// Set link info.
attrLinkInfo := newAttribute(unix.IFLA_LINKINFO, nil)
attrLinkInfo.addNested(newAttributeString(IFLA_INFO_KIND, info.Type))
Expand Down Expand Up @@ -415,8 +422,8 @@ func (Netlink) SetLinkHairpin(bridgeName string, on bool) error {
return s.sendAndWaitForAck(req)
}

// AddOrRemoveStaticArp sets/removes static arp entry based on mode
func (Netlink) AddOrRemoveStaticArp(mode int, name string, ipaddr net.IP, mac net.HardwareAddr, isProxy bool) error {
// SetOrRemoveLinkAddress sets/removes static arp entry based on mode
func (Netlink) SetOrRemoveLinkAddress(linkInfo LinkInfo, mode, linkState int) error {
s, err := getSocket()
if err != nil {
return err
Expand All @@ -426,39 +433,33 @@ func (Netlink) AddOrRemoveStaticArp(mode int, name string, ipaddr net.IP, mac ne
state := 0
if mode == ADD {
req = newRequest(unix.RTM_NEWNEIGH, unix.NLM_F_CREATE|unix.NLM_F_REPLACE|unix.NLM_F_ACK)
state = NUD_PERMANENT
} else {
req = newRequest(unix.RTM_DELNEIGH, unix.NLM_F_ACK)
state = NUD_INCOMPLETE
}
state = linkState

iface, err := net.InterfaceByName(name)
iface, err := net.InterfaceByName(linkInfo.Name)
if err != nil {
return err
}

msg := neighMsg{
Family: uint8(GetIPAddressFamily(ipaddr)),
Family: uint8(GetIPAddressFamily(linkInfo.IPAddr)),
Index: uint32(iface.Index),
State: uint16(state),
}

// NTF_PROXY is for setting neighbor proxy
if isProxy {
msg.Flags = msg.Flags | NTF_PROXY
}

req.addPayload(&msg)

ipData := ipaddr.To4()
ipData := linkInfo.IPAddr.To4()
if ipData == nil {
ipData = ipaddr.To16()
ipData = linkInfo.IPAddr.To16()
}

dstData := newRtAttr(NDA_DST, ipData)
req.addPayload(dstData)

hwData := newRtAttr(NDA_LLADDR, []byte(mac))
hwData := newRtAttr(NDA_LLADDR, []byte(linkInfo.MacAddress))
req.addPayload(hwData)

return s.sendAndWaitForAck(req)
Expand Down
2 changes: 1 addition & 1 deletion netlink/mocknetlink.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func (f *MockNetlink) SetLinkHairpin(string, bool) error {
return f.error()
}

func (f *MockNetlink) AddOrRemoveStaticArp(int, string, net.IP, net.HardwareAddr, bool) error {
func (f *MockNetlink) SetOrRemoveLinkAddress(LinkInfo, int, int) error {
return f.error()
}

Expand Down
16 changes: 14 additions & 2 deletions netlink/netlink_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,12 +284,24 @@ func TestAddRemoveStaticArp(t *testing.T) {
mac, _ := net.ParseMAC("aa:b3:4d:5e:e2:4a")
nl := NewNetlink()

err = nl.AddOrRemoveStaticArp(ADD, ifName, ip, mac, false)
linkInfo := LinkInfo{
Name: ifName,
IPAddr: ip,
MacAddress: mac,
}

err = nl.SetOrRemoveLinkAddress(linkInfo, ADD, NUD_PERMANENT)
if err != nil {
t.Errorf("ret val %v", err)
}

err = nl.AddOrRemoveStaticArp(REMOVE, ifName, ip, mac, false)
linkInfo = LinkInfo{
Name: ifName,
IPAddr: ip,
MacAddress: mac,
}

err = nl.SetOrRemoveLinkAddress(linkInfo, REMOVE, NUD_INCOMPLETE)
if err != nil {
t.Errorf("ret val %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion netlink/netlink_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (Netlink) SetLinkHairpin(bridgeName string, on bool) error {
return nil
}

func (Netlink) AddOrRemoveStaticArp(mode int, name string, ipaddr net.IP, mac net.HardwareAddr, isProxy bool) error {
func (Netlink) SetOrRemoveLinkAddress(linkInfo LinkInfo, mode, linkState int) error {
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion netlink/netlinkinterface.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type NetlinkInterface interface {
SetLinkAddress(ifName string, hwAddress net.HardwareAddr) error
SetLinkPromisc(ifName string, on bool) error
SetLinkHairpin(bridgeName string, on bool) error
AddOrRemoveStaticArp(mode int, name string, ipaddr net.IP, mac net.HardwareAddr, isProxy bool) error
SetOrRemoveLinkAddress(linkInfo LinkInfo, mode, linkState int) error
AddIPAddress(ifName string, ipAddress net.IP, ipNet *net.IPNet) error
DeleteIPAddress(ifName string, ipAddress net.IP, ipNet *net.IPNet) error
GetIPRoute(filter *Route) ([]*Route, error)
Expand Down
1 change: 1 addition & 0 deletions netlink/socket.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2017 Microsoft. All rights reserved.
// MIT License

//go:build linux
// +build linux

package netlink
Expand Down
25 changes: 20 additions & 5 deletions network/bridge_endpointclient_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func NewLinuxBridgeEndpointClient(
}

func (client *LinuxBridgeEndpointClient) AddEndpoints(epInfo *EndpointInfo) error {
if err := client.nuc.CreateEndpoint(client.hostVethName, client.containerVethName); err != nil {
if err := client.nuc.CreateEndpoint(client.hostVethName, client.containerVethName, nil); err != nil {
return err
}

Expand Down Expand Up @@ -98,7 +98,13 @@ func (client *LinuxBridgeEndpointClient) AddEndpointRules(epInfo *EndpointInfo)

if client.mode != opModeTunnel && ipAddr.IP.To4() != nil {
log.Printf("[net] Adding static arp for IP address %v and MAC %v in VM", ipAddr.String(), client.containerMac.String())
if err := client.netlink.AddOrRemoveStaticArp(netlink.ADD, client.bridgeName, ipAddr.IP, client.containerMac, false); err != nil {
linkInfo := netlink.LinkInfo{
Name: client.bridgeName,
IPAddr: ipAddr.IP,
MacAddress: client.containerMac,
}

if err := client.netlink.SetOrRemoveLinkAddress(linkInfo, netlink.ADD, netlink.NUD_PERMANENT); err != nil {
log.Printf("Failed setting arp in vm: %v", err)
}
}
Expand Down Expand Up @@ -136,7 +142,12 @@ func (client *LinuxBridgeEndpointClient) DeleteEndpointRules(ep *endpoint) {

if client.mode != opModeTunnel && ipAddr.IP.To4() != nil {
log.Printf("[net] Removing static arp for IP address %v and MAC %v from VM", ipAddr.String(), ep.MacAddress.String())
err := client.netlink.AddOrRemoveStaticArp(netlink.REMOVE, client.bridgeName, ipAddr.IP, ep.MacAddress, false)
linkInfo := netlink.LinkInfo{
Name: client.bridgeName,
IPAddr: ipAddr.IP,
MacAddress: ep.MacAddress,
}
err := client.netlink.SetOrRemoveLinkAddress(linkInfo, netlink.REMOVE, netlink.NUD_INCOMPLETE)
if err != nil {
log.Printf("Failed removing arp from vm: %v", err)
}
Expand Down Expand Up @@ -290,8 +301,12 @@ func (client *LinuxBridgeEndpointClient) setIPV6NeighEntry(epInfo *EndpointInfo)
log.Printf("[net] Add neigh entry for host gw ip")
hardwareAddr, _ := net.ParseMAC(defaultHostGwMac)
hostGwIp := net.ParseIP(defaultV6HostGw)
if err := client.netlink.AddOrRemoveStaticArp(netlink.ADD, client.containerVethName,
hostGwIp, hardwareAddr, false); err != nil {
linkInfo := netlink.LinkInfo{
Name: client.containerVethName,
IPAddr: hostGwIp,
MacAddress: hardwareAddr,
}
if err := client.netlink.SetOrRemoveLinkAddress(linkInfo, netlink.ADD, netlink.NUD_PERMANENT); err != nil {
log.Printf("Failed setting neigh entry in container: %v", err)
return err
}
Expand Down
7 changes: 4 additions & 3 deletions network/networkutils/networkutils_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,14 @@ func NewNetworkUtils(nl netlink.NetlinkInterface, plClient platform.ExecClient)
}
}

func (nu NetworkUtils) CreateEndpoint(hostVethName, containerVethName string) error {
func (nu NetworkUtils) CreateEndpoint(hostVethName, containerVethName string, macAddress net.HardwareAddr) error {
log.Printf("[net] Creating veth pair %v %v.", hostVethName, containerVethName)

link := netlink.VEthLink{
LinkInfo: netlink.LinkInfo{
Type: netlink.LINK_TYPE_VETH,
Name: hostVethName,
Type: netlink.LINK_TYPE_VETH,
Name: hostVethName,
MacAddress: macAddress,
},
PeerName: containerVethName,
}
Expand Down
2 changes: 1 addition & 1 deletion network/ovs_endpointclient_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func NewOVSEndpointClient(

func (client *OVSEndpointClient) AddEndpoints(epInfo *EndpointInfo) error {
epc := networkutils.NewNetworkUtils(client.netlink, client.plClient)
if err := epc.CreateEndpoint(client.hostVethName, client.containerVethName); err != nil {
if err := epc.CreateEndpoint(client.hostVethName, client.containerVethName, nil); err != nil {
return err
}

Expand Down
2 changes: 1 addition & 1 deletion network/ovsinfravnet/infravnet_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func NewInfraVnetClient(hostIfName, contIfName string, nl netlink.NetlinkInterfa
func (client *OVSInfraVnetClient) CreateInfraVnetEndpoint(bridgeName string) error {
ovs := ovsctl.NewOvsctl()
epc := networkutils.NewNetworkUtils(client.netlink, client.plClient)
if err := epc.CreateEndpoint(client.hostInfraVethName, client.ContainerInfraVethName); err != nil {
if err := epc.CreateEndpoint(client.hostInfraVethName, client.ContainerInfraVethName, nil); err != nil {
log.Printf("Creating infraep failed with error %v", err)
return err
}
Expand Down
34 changes: 29 additions & 5 deletions network/snat/snat_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func (client *Client) CreateSnatEndpoint() error {

epc := networkutils.NewNetworkUtils(client.netlink, client.plClient)
// Create veth pair to tie one end to container and other end to linux bridge
if err := epc.CreateEndpoint(client.hostSnatVethName, client.containerSnatVethName); err != nil {
if err := epc.CreateEndpoint(client.hostSnatVethName, client.containerSnatVethName, nil); err != nil {
log.Printf("Creating Snat Endpoint failed with error %v", err)
return newErrorSnatClient(err.Error())
}
Expand Down Expand Up @@ -209,7 +209,13 @@ func (client *Client) AllowInboundFromHostToNC() error {

// Add static arp entry for localIP to prevent arp going out of VM
log.Printf("Adding static arp entry for ip %s mac %s", containerIP, snatContainerVeth.HardwareAddr.String())
err = client.netlink.AddOrRemoveStaticArp(netlink.ADD, SnatBridgeName, containerIP, snatContainerVeth.HardwareAddr, false)
linkInfo := netlink.LinkInfo{
Name: SnatBridgeName,
IPAddr: containerIP,
MacAddress: snatContainerVeth.HardwareAddr,
}

err = client.netlink.SetOrRemoveLinkAddress(linkInfo, netlink.ADD, netlink.NUD_PERMANENT)
if err != nil {
log.Printf("AllowInboundFromHostToNC: Error adding static arp entry for ip %s mac %s: %v", containerIP, snatContainerVeth.HardwareAddr.String(), err)
return newErrorSnatClient(err.Error())
Expand All @@ -230,7 +236,13 @@ func (client *Client) DeleteInboundFromHostToNC() error {

// Remove static arp entry added for container local IP
log.Printf("Removing static arp entry for ip %s ", containerIP)
err = client.netlink.AddOrRemoveStaticArp(netlink.REMOVE, SnatBridgeName, containerIP, nil, false)
linkInfo := netlink.LinkInfo{
Name: SnatBridgeName,
IPAddr: containerIP,
MacAddress: nil,
}

err = client.netlink.SetOrRemoveLinkAddress(linkInfo, netlink.REMOVE, netlink.NUD_INCOMPLETE)
if err != nil {
log.Printf("AllowInboundFromHostToNC: Error removing static arp entry for ip %s: %v", containerIP, err)
}
Expand Down Expand Up @@ -288,7 +300,13 @@ func (client *Client) AllowInboundFromNCToHost() error {

// Add static arp entry for localIP to prevent arp going out of VM
log.Printf("Adding static arp entry for ip %s mac %s", containerIP, snatContainerVeth.HardwareAddr.String())
err = client.netlink.AddOrRemoveStaticArp(netlink.ADD, SnatBridgeName, containerIP, snatContainerVeth.HardwareAddr, false)
linkInfo := netlink.LinkInfo{
Name: SnatBridgeName,
IPAddr: containerIP,
MacAddress: snatContainerVeth.HardwareAddr,
}

err = client.netlink.SetOrRemoveLinkAddress(linkInfo, netlink.ADD, netlink.NUD_PERMANENT)
if err != nil {
log.Printf("AllowInboundFromNCToHost: Error adding static arp entry for ip %s mac %s: %v", containerIP, snatContainerVeth.HardwareAddr.String(), err)
}
Expand All @@ -308,7 +326,13 @@ func (client *Client) DeleteInboundFromNCToHost() error {

// Remove static arp entry added for container local IP
log.Printf("Removing static arp entry for ip %s ", containerIP)
err = client.netlink.AddOrRemoveStaticArp(netlink.REMOVE, SnatBridgeName, containerIP, nil, false)
linkInfo := netlink.LinkInfo{
Name: SnatBridgeName,
IPAddr: containerIP,
MacAddress: nil,
}

err = client.netlink.SetOrRemoveLinkAddress(linkInfo, netlink.REMOVE, netlink.NUD_INCOMPLETE)
if err != nil {
log.Printf("DeleteInboundFromNCToHost: Error removing static arp entry for ip %s: %v", containerIP, err)
}
Expand Down
47 changes: 30 additions & 17 deletions network/transparent_endpointclient_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@ import (
)

const (
virtualGwIPString = "169.254.1.1/32"
defaultGwCidr = "0.0.0.0/0"
defaultGw = "0.0.0.0"
virtualv6GwString = "fe80::1234:5678:9abc/128"
defaultv6Cidr = "::/0"
ipv4Bits = 32
ipv6Bits = 128
ipv4FullMask = 32
ipv6FullMask = 128
virtualGwIPString = "169.254.1.1/32"
defaultGwCidr = "0.0.0.0/0"
defaultGw = "0.0.0.0"
virtualv6GwString = "fe80::1234:5678:9abc/128"
defaultv6Cidr = "::/0"
ipv4Bits = 32
ipv6Bits = 128
ipv4FullMask = 32
ipv6FullMask = 128
defaultHostVethHwAddr = "aa:aa:aa:aa:aa:aa"
)

var errorTransparentEndpointClient = errors.New("TransparentEndpointClient Error")
Expand Down Expand Up @@ -89,7 +90,12 @@ func (client *TransparentEndpointClient) AddEndpoints(epInfo *EndpointInfo) erro
return newErrorTransparentEndpointClient(err.Error())
}

if err = client.netUtilsClient.CreateEndpoint(client.hostVethName, client.containerVethName); err != nil {
mac, err := net.ParseMAC(defaultHostVethHwAddr)
if err != nil {
log.Printf("[net] Failed to parse the mac addrress %v", defaultHostVethHwAddr)
}

if err = client.netUtilsClient.CreateEndpoint(client.hostVethName, client.containerVethName, mac); err != nil {
return newErrorTransparentEndpointClient(err.Error())
}

Expand Down Expand Up @@ -246,11 +252,13 @@ func (client *TransparentEndpointClient) ConfigureContainerInterfacesAndRoutes(e
// arp -s 169.254.1.1 e3:45:f4:ac:34:12 - add static arp entry for virtualgwip to hostveth interface mac
log.Printf("[net] Adding static arp for IP address %v and MAC %v in Container namespace",
virtualGwNet.String(), client.hostVethMac)
if err := client.netlink.AddOrRemoveStaticArp(netlink.ADD,
client.containerVethName,
virtualGwNet.IP,
client.hostVethMac,
false); err != nil {
linkInfo := netlink.LinkInfo{
Name: client.containerVethName,
IPAddr: virtualGwNet.IP,
MacAddress: client.hostVethMac,
}

if err := client.netlink.SetOrRemoveLinkAddress(linkInfo, netlink.ADD, netlink.NUD_PROBE); err != nil {
return fmt.Errorf("Adding arp in container failed: %w", err)
}

Expand Down Expand Up @@ -292,8 +300,13 @@ func (client *TransparentEndpointClient) setupIPV6Routes() error {
func (client *TransparentEndpointClient) setIPV6NeighEntry() error {
log.Printf("[net] Add v6 neigh entry for default gw ip")
hostGwIP, _, _ := net.ParseCIDR(virtualv6GwString)
if err := client.netlink.AddOrRemoveStaticArp(netlink.ADD, client.containerVethName,
hostGwIP, client.hostVethMac, false); err != nil {
linkInfo := netlink.LinkInfo{
Name: client.containerVethName,
IPAddr: hostGwIP,
MacAddress: client.hostVethMac,
}

if err := client.netlink.SetOrRemoveLinkAddress(linkInfo, netlink.ADD, netlink.NUD_PROBE); err != nil {
log.Printf("Failed setting neigh entry in container: %+v", err)
return fmt.Errorf("Failed setting neigh entry in container: %w", err)
}
Expand Down
10 changes: 8 additions & 2 deletions network/transparent_vlan_endpointclient_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ func (client *TransparentVlanEndpointClient) PopulateVM(epInfo *EndpointInfo) er
}
client.vnetNSFileDescriptor = vnetNS

if err = client.netUtilsClient.CreateEndpoint(client.vnetVethName, client.containerVethName); err != nil {
if err = client.netUtilsClient.CreateEndpoint(client.vnetVethName, client.containerVethName, nil); err != nil {
return errors.Wrap(err, "failed to create veth pair")
}
// Disable RA for veth pair, and delete if any failure
Expand Down Expand Up @@ -403,7 +403,13 @@ func (client *TransparentVlanEndpointClient) AddDefaultArp(interfaceName, destMa
if err != nil {
return errors.Wrap(err, "unable to parse mac")
}
if err := client.netlink.AddOrRemoveStaticArp(netlink.ADD, interfaceName, virtualGwNet.IP, hardwareAddr, false); err != nil {
linkInfo := netlink.LinkInfo{
Name: interfaceName,
IPAddr: virtualGwNet.IP,
MacAddress: hardwareAddr,
}

if err := client.netlink.SetOrRemoveLinkAddress(linkInfo, netlink.ADD, netlink.NUD_PERMANENT); err != nil {
return fmt.Errorf("adding arp entry failed: %w", err)
}
return nil
Expand Down