Refactored and added more tests.Cleaned up netlink.

I've added more tests. We now have almost 55% coverage.
I've also reorganized netlink_linux codebase and moved
the non-RTNETLINK functions at the bottom. I've also
added some comments to some functions.

Docker-DCO-1.1-Signed-off-by: Milos Gajdos <milosgajdos83@gmail.com> (github: milosgajdos83)
This commit is contained in:
Milos Gajdos 2014-09-20 01:54:19 +01:00
parent 185328a426
commit 4fe2c7a4db
2 changed files with 411 additions and 230 deletions

View File

@ -18,6 +18,7 @@ const (
IFLA_INFO_DATA = 2
VETH_INFO_PEER = 1
IFLA_NET_NS_FD = 28
IFLA_ADDRESS = 1
SIOC_BRADDBR = 0x89a0
SIOC_BRDELBR = 0x89a1
SIOC_BRADDIF = 0x89a2
@ -375,10 +376,19 @@ outer:
return nil
}
// Add a new route table entry.
func AddRoute(destination, source, gateway, device string) error {
if destination == "" && source == "" && gateway == "" {
return fmt.Errorf("one of destination, source or gateway must not be blank")
func zeroTerminated(s string) []byte {
return []byte(s + "\000")
}
func nonZeroTerminated(s string) []byte {
return []byte(s)
}
// Add a new network link of a specified type.
// This is identical to running: ip add link $name type $linkType
func NetworkLinkAdd(name string, linkType string) error {
if name == "" || linkType == "" {
return fmt.Errorf("Neither link name nor link type can be empty!")
}
s, err := getNetlinkSocket()
@ -387,101 +397,58 @@ func AddRoute(destination, source, gateway, device string) error {
}
defer s.Close()
wb := newNetlinkRequest(syscall.RTM_NEWROUTE, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
msg := newRtMsg()
currentFamily := -1
var rtAttrs []*RtAttr
if destination != "" {
destIP, destNet, err := net.ParseCIDR(destination)
if err != nil {
return fmt.Errorf("destination CIDR %s couldn't be parsed", destination)
}
destFamily := getIpFamily(destIP)
currentFamily = destFamily
destLen, bits := destNet.Mask.Size()
if destLen == 0 && bits == 0 {
return fmt.Errorf("destination CIDR %s generated a non-canonical Mask", destination)
}
msg.Family = uint8(destFamily)
msg.Dst_len = uint8(destLen)
var destData []byte
if destFamily == syscall.AF_INET {
destData = destIP.To4()
} else {
destData = destIP.To16()
}
rtAttrs = append(rtAttrs, newRtAttr(syscall.RTA_DST, destData))
}
if source != "" {
srcIP, srcNet, err := net.ParseCIDR(source)
if err != nil {
return fmt.Errorf("source CIDR %s couldn't be parsed", source)
}
srcFamily := getIpFamily(srcIP)
if currentFamily != -1 && currentFamily != srcFamily {
return fmt.Errorf("source and destination ip were not the same IP family")
}
currentFamily = srcFamily
srcLen, bits := srcNet.Mask.Size()
if srcLen == 0 && bits == 0 {
return fmt.Errorf("source CIDR %s generated a non-canonical Mask", source)
}
msg.Family = uint8(srcFamily)
msg.Src_len = uint8(srcLen)
var srcData []byte
if srcFamily == syscall.AF_INET {
srcData = srcIP.To4()
} else {
srcData = srcIP.To16()
}
rtAttrs = append(rtAttrs, newRtAttr(syscall.RTA_SRC, srcData))
}
if gateway != "" {
gwIP := net.ParseIP(gateway)
if gwIP == nil {
return fmt.Errorf("gateway IP %s couldn't be parsed", gateway)
}
gwFamily := getIpFamily(gwIP)
if currentFamily != -1 && currentFamily != gwFamily {
return fmt.Errorf("gateway, source, and destination ip were not the same IP family")
}
msg.Family = uint8(gwFamily)
var gwData []byte
if gwFamily == syscall.AF_INET {
gwData = gwIP.To4()
} else {
gwData = gwIP.To16()
}
rtAttrs = append(rtAttrs, newRtAttr(syscall.RTA_GATEWAY, gwData))
}
wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
msg := newIfInfomsg(syscall.AF_UNSPEC)
wb.AddData(msg)
for _, attr := range rtAttrs {
wb.AddData(attr)
}
iface, err := net.InterfaceByName(device)
if err != nil {
return err
}
wb.AddData(uint32Attr(syscall.RTA_OIF, uint32(iface.Index)))
linkInfo := newRtAttr(syscall.IFLA_LINKINFO, nil)
newRtAttrChild(linkInfo, IFLA_INFO_KIND, nonZeroTerminated(linkType))
wb.AddData(linkInfo)
nameData := newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(name))
wb.AddData(nameData)
if err := s.Send(wb); err != nil {
return err
}
return s.HandleAck(wb.Seq)
}
// Add a new default gateway. Identical to:
// ip route add default via $ip
func AddDefaultGw(ip, device string) error {
return AddRoute("", "", ip, device)
// Delete a network link.
// This is identical to running: ip link del $name
func NetworkLinkDel(name string) error {
if name == "" {
return fmt.Errorf("Network link name can not be empty!")
}
s, err := getNetlinkSocket()
if err != nil {
return err
}
defer s.Close()
iface, err := net.InterfaceByName(name)
if err != nil {
return err
}
wb := newNetlinkRequest(syscall.RTM_DELLINK, syscall.NLM_F_ACK)
msg := newIfInfomsg(syscall.AF_UNSPEC)
msg.Index = int32(iface.Index)
wb.AddData(msg)
if err := s.Send(wb); err != nil {
return err
}
return s.HandleAck(wb.Seq)
}
// Bring up a particular network interface
// Bring up a particular network interface.
// This is identical to running: ip link set dev $name up
func NetworkLinkUp(iface *net.Interface) error {
s, err := getNetlinkSocket()
if err != nil {
@ -492,9 +459,9 @@ func NetworkLinkUp(iface *net.Interface) error {
wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_ACK)
msg := newIfInfomsg(syscall.AF_UNSPEC)
msg.Change = syscall.IFF_UP
msg.Flags = syscall.IFF_UP
msg.Index = int32(iface.Index)
msg.Flags = syscall.IFF_UP
msg.Change = syscall.IFF_UP
wb.AddData(msg)
if err := s.Send(wb); err != nil {
@ -504,6 +471,8 @@ func NetworkLinkUp(iface *net.Interface) error {
return s.HandleAck(wb.Seq)
}
// Bring down a particular network interface.
// This is identical to running: ip link set $name down
func NetworkLinkDown(iface *net.Interface) error {
s, err := getNetlinkSocket()
if err != nil {
@ -514,9 +483,9 @@ func NetworkLinkDown(iface *net.Interface) error {
wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_ACK)
msg := newIfInfomsg(syscall.AF_UNSPEC)
msg.Change = syscall.IFF_UP
msg.Flags = 0 & ^syscall.IFF_UP
msg.Index = int32(iface.Index)
msg.Flags = 0 & ^syscall.IFF_UP
msg.Change = DEFAULT_CHANGE
wb.AddData(msg)
if err := s.Send(wb); err != nil {
@ -526,6 +495,53 @@ func NetworkLinkDown(iface *net.Interface) error {
return s.HandleAck(wb.Seq)
}
// Set link layer address ie. MAC Address.
// This is identical to running: ip link set dev $name address $macaddress
func NetworkSetMacAddress(iface *net.Interface, macaddr string) error {
s, err := getNetlinkSocket()
if err != nil {
return err
}
defer s.Close()
hwaddr, err := net.ParseMAC(macaddr)
if err != nil {
return err
}
var (
MULTICAST byte = 0x1
LOCALOUI byte = 0x2
)
if hwaddr[0]&0x1 == MULTICAST || hwaddr[0]&0x2 != LOCALOUI {
return fmt.Errorf("Incorrect Local MAC Address specified: %s", macaddr)
}
wb := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
msg := newIfInfomsg(syscall.AF_UNSPEC)
msg.Index = int32(iface.Index)
msg.Change = DEFAULT_CHANGE
wb.AddData(msg)
macdata := make([]byte, 6)
copy(macdata, hwaddr)
data := newRtAttr(IFLA_ADDRESS, macdata)
wb.AddData(data)
if err := s.Send(wb); err != nil {
return err
}
return s.HandleAck(wb.Seq)
}
// Set link Maximum Transmission Unit
// This is identical to running: ip link set dev $name mtu $MTU
// bridge is a bitch here https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=292088
// https://bugzilla.redhat.com/show_bug.cgi?id=697021
// There is a discussion about how to deal with ifcs joining bridge with MTU > 1500
// Regular network nterfaces do seem to work though!
func NetworkSetMTU(iface *net.Interface, mtu int) error {
s, err := getNetlinkSocket()
if err != nil {
@ -549,8 +565,7 @@ func NetworkSetMTU(iface *net.Interface, mtu int) error {
return s.HandleAck(wb.Seq)
}
// same as ip link set $name master $master
func NetworkSetMaster(iface, master *net.Interface) error {
func networkMasterAction(iface *net.Interface, rtattr *RtAttr) error {
s, err := getNetlinkSocket()
if err != nil {
return err
@ -565,7 +580,7 @@ func NetworkSetMaster(iface, master *net.Interface) error {
msg.Index = int32(iface.Index)
msg.Change = DEFAULT_CHANGE
wb.AddData(msg)
wb.AddData(uint32Attr(syscall.IFLA_MASTER, uint32(master.Index)))
wb.AddData(rtattr)
if err := s.Send(wb); err != nil {
return err
@ -574,6 +589,20 @@ func NetworkSetMaster(iface, master *net.Interface) error {
return s.HandleAck(wb.Seq)
}
// Add an interface to bridge.
// This is identical to running: ip link set $name master $master
func NetworkSetMaster(iface, master *net.Interface) error {
data := uint32Attr(syscall.IFLA_MASTER, uint32(master.Index))
return networkMasterAction(iface, data)
}
// Remove an interface from the bridge
// This is is identical to to running: ip link $name set nomaster
func NetworkSetNoMaster(iface *net.Interface) error {
data := uint32Attr(syscall.IFLA_MASTER, 0)
return networkMasterAction(iface, data)
}
func NetworkSetNsPid(iface *net.Interface, nspid int) error {
s, err := getNetlinkSocket()
if err != nil {
@ -679,77 +708,6 @@ func NetworkLinkAddIp(iface *net.Interface, ip net.IP, ipNet *net.IPNet) error {
)
}
func zeroTerminated(s string) []byte {
return []byte(s + "\000")
}
func nonZeroTerminated(s string) []byte {
return []byte(s)
}
// Add a new network link of a specified type. This is identical to
// running: ip add link $name type $linkType
func NetworkLinkAdd(name string, linkType string) error {
if name == "" || linkType == "" {
return fmt.Errorf("Neither link name nor link type can be empty!")
}
s, err := getNetlinkSocket()
if err != nil {
return err
}
defer s.Close()
wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
msg := newIfInfomsg(syscall.AF_UNSPEC)
wb.AddData(msg)
linkInfo := newRtAttr(syscall.IFLA_LINKINFO, nil)
newRtAttrChild(linkInfo, IFLA_INFO_KIND, nonZeroTerminated(linkType))
wb.AddData(linkInfo)
nameData := newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(name))
wb.AddData(nameData)
if err := s.Send(wb); err != nil {
return err
}
return s.HandleAck(wb.Seq)
}
// Delete a network link. This is identical to
// running: ip link del $name
func NetworkLinkDel(name string) error {
if name == "" {
return fmt.Errorf("Network link name can not be empty!")
}
s, err := getNetlinkSocket()
if err != nil {
return err
}
defer s.Close()
iface, err := net.InterfaceByName(name)
if err != nil {
return err
}
wb := newNetlinkRequest(syscall.RTM_DELLINK, syscall.NLM_F_ACK)
msg := newIfInfomsg(syscall.AF_UNSPEC)
msg.Index = int32(iface.Index)
wb.AddData(msg)
if err := s.Send(wb); err != nil {
return err
}
return s.HandleAck(wb.Seq)
}
// Returns an array of IPNet for all the currently routed subnets on ipv4
// This is similar to the first column of "ip route" output
func NetworkGetRoutes() ([]Route, error) {
@ -842,20 +800,110 @@ outer:
return res, nil
}
func getIfSocket() (fd int, err error) {
for _, socket := range []int{
syscall.AF_INET,
syscall.AF_PACKET,
syscall.AF_INET6,
} {
if fd, err = syscall.Socket(socket, syscall.SOCK_DGRAM, 0); err == nil {
break
// Add a new route table entry.
func AddRoute(destination, source, gateway, device string) error {
if destination == "" && source == "" && gateway == "" {
return fmt.Errorf("one of destination, source or gateway must not be blank")
}
s, err := getNetlinkSocket()
if err != nil {
return err
}
defer s.Close()
wb := newNetlinkRequest(syscall.RTM_NEWROUTE, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
msg := newRtMsg()
currentFamily := -1
var rtAttrs []*RtAttr
if destination != "" {
destIP, destNet, err := net.ParseCIDR(destination)
if err != nil {
return fmt.Errorf("destination CIDR %s couldn't be parsed", destination)
}
destFamily := getIpFamily(destIP)
currentFamily = destFamily
destLen, bits := destNet.Mask.Size()
if destLen == 0 && bits == 0 {
return fmt.Errorf("destination CIDR %s generated a non-canonical Mask", destination)
}
msg.Family = uint8(destFamily)
msg.Dst_len = uint8(destLen)
var destData []byte
if destFamily == syscall.AF_INET {
destData = destIP.To4()
} else {
destData = destIP.To16()
}
rtAttrs = append(rtAttrs, newRtAttr(syscall.RTA_DST, destData))
}
if err == nil {
return fd, nil
if source != "" {
srcIP, srcNet, err := net.ParseCIDR(source)
if err != nil {
return fmt.Errorf("source CIDR %s couldn't be parsed", source)
}
srcFamily := getIpFamily(srcIP)
if currentFamily != -1 && currentFamily != srcFamily {
return fmt.Errorf("source and destination ip were not the same IP family")
}
currentFamily = srcFamily
srcLen, bits := srcNet.Mask.Size()
if srcLen == 0 && bits == 0 {
return fmt.Errorf("source CIDR %s generated a non-canonical Mask", source)
}
msg.Family = uint8(srcFamily)
msg.Src_len = uint8(srcLen)
var srcData []byte
if srcFamily == syscall.AF_INET {
srcData = srcIP.To4()
} else {
srcData = srcIP.To16()
}
rtAttrs = append(rtAttrs, newRtAttr(syscall.RTA_SRC, srcData))
}
return -1, err
if gateway != "" {
gwIP := net.ParseIP(gateway)
if gwIP == nil {
return fmt.Errorf("gateway IP %s couldn't be parsed", gateway)
}
gwFamily := getIpFamily(gwIP)
if currentFamily != -1 && currentFamily != gwFamily {
return fmt.Errorf("gateway, source, and destination ip were not the same IP family")
}
msg.Family = uint8(gwFamily)
var gwData []byte
if gwFamily == syscall.AF_INET {
gwData = gwIP.To4()
} else {
gwData = gwIP.To16()
}
rtAttrs = append(rtAttrs, newRtAttr(syscall.RTA_GATEWAY, gwData))
}
wb.AddData(msg)
for _, attr := range rtAttrs {
wb.AddData(attr)
}
iface, err := net.InterfaceByName(device)
if err != nil {
return err
}
wb.AddData(uint32Attr(syscall.RTA_OIF, uint32(iface.Index)))
if err := s.Send(wb); err != nil {
return err
}
return s.HandleAck(wb.Seq)
}
// Add a new default gateway. Identical to:
// ip route add default via $ip
func AddDefaultGw(ip, device string) error {
return AddRoute("", "", ip, device)
}
func NetworkChangeName(iface *net.Interface, newName string) error {
@ -912,6 +960,25 @@ func NetworkCreateVethPair(name1, name2 string) error {
return s.HandleAck(wb.Seq)
}
// THIS CODE DOES NOT COMMUNICATE WITH KERNEL VIA RTNETLINK INTERFACE
// IT IS HERE FOR BACKWARDS COMPATIBILITY WITH OLDER LINUX KERNELS
// WHICH SHIP WITH OLDER NOT ENTIRELY FUNCTIONAL VERSION OF NETLINK
func getIfSocket() (fd int, err error) {
for _, socket := range []int{
syscall.AF_INET,
syscall.AF_PACKET,
syscall.AF_INET6,
} {
if fd, err = syscall.Socket(socket, syscall.SOCK_DGRAM, 0); err == nil {
break
}
}
if err == nil {
return fd, nil
}
return -1, err
}
// Create the actual bridge device. This is more backward-compatible than
// netlink.NetworkLinkAdd and works on RHEL 6.
func CreateBridge(name string, setMacAddr bool) error {
@ -933,7 +1000,7 @@ func CreateBridge(name string, setMacAddr bool) error {
return err
}
if setMacAddr {
return NetworkSetMacAddress(name, randMacAddr())
return SetMacAddress(name, randMacAddr())
}
return nil
}
@ -999,7 +1066,7 @@ func randMacAddr() string {
return hw.String()
}
func NetworkSetMacAddress(name, addr string) error {
func SetMacAddress(name, addr string) error {
if len(name) >= IFNAMSIZ {
return fmt.Errorf("Interface name %s too long", name)
}

View File

@ -3,9 +3,50 @@ package netlink
import (
"net"
"strings"
"syscall"
"testing"
)
type testLink struct {
name string
linkType string
}
func addLink(t *testing.T, name string, linkType string) {
if err := NetworkLinkAdd(name, linkType); err != nil {
t.Fatalf("Unable to create %s link: %s", name, err)
}
}
func readLink(t *testing.T, name string) *net.Interface {
iface, err := net.InterfaceByName(name)
if err != nil {
t.Fatalf("Could not find %s interface: %s", name, err)
}
return iface
}
func deleteLink(t *testing.T, name string) {
if err := NetworkLinkDel(name); err != nil {
t.Fatalf("Unable to delete %s link: %s", name, err)
}
}
func upLink(t *testing.T, name string) {
iface := readLink(t, name)
if err := NetworkLinkUp(iface); err != nil {
t.Fatalf("Could not bring UP %#v interface: %s", iface, err)
}
}
func downLink(t *testing.T, name string) {
iface := readLink(t, name)
if err := NetworkLinkDown(iface); err != nil {
t.Fatalf("Could not bring DOWN %#v interface: %s", iface, err)
}
}
func ipAssigned(iface *net.Interface, ip net.IP) bool {
addrs, _ := iface.Addrs()
@ -19,6 +60,106 @@ func ipAssigned(iface *net.Interface, ip net.IP) bool {
return false
}
func TestNetworkLinkAddDel(t *testing.T) {
testLinks := []testLink{
{"tstEth", "dummy"},
{"tstBr", "bridge"},
}
for _, tl := range testLinks {
addLink(t, tl.name, tl.linkType)
defer deleteLink(t, tl.name)
readLink(t, tl.name)
}
}
func TestNetworkLinkUpDown(t *testing.T) {
tl := testLink{name: "tstEth", linkType: "dummy"}
addLink(t, tl.name, tl.linkType)
defer deleteLink(t, tl.name)
upLink(t, tl.name)
ifcAfterUp := readLink(t, tl.name)
if (ifcAfterUp.Flags & syscall.IFF_UP) != syscall.IFF_UP {
t.Fatalf("Could not bring UP %#v initerface", tl)
}
downLink(t, tl.name)
ifcAfterDown := readLink(t, tl.name)
if (ifcAfterDown.Flags & syscall.IFF_UP) == syscall.IFF_UP {
t.Fatalf("Could not bring DOWN %#v initerface", tl)
}
}
func TestNetworkSetMacAddress(t *testing.T) {
tl := testLink{name: "tstEth", linkType: "dummy"}
macaddr := "22:ce:e0:99:63:6f"
addLink(t, tl.name, tl.linkType)
defer deleteLink(t, tl.name)
ifcBeforeSet := readLink(t, tl.name)
if err := NetworkSetMacAddress(ifcBeforeSet, macaddr); err != nil {
t.Fatalf("Could not set %s MAC address on %#v interface: err", macaddr, tl, err)
}
ifcAfterSet := readLink(t, tl.name)
if ifcAfterSet.HardwareAddr.String() != macaddr {
t.Fatalf("Could not set %s MAC address on %#v interface", macaddr, tl)
}
}
func TestNetworkSetMTU(t *testing.T) {
tl := testLink{name: "tstEth", linkType: "dummy"}
mtu := 1400
addLink(t, tl.name, tl.linkType)
defer deleteLink(t, tl.name)
ifcBeforeSet := readLink(t, tl.name)
if err := NetworkSetMTU(ifcBeforeSet, mtu); err != nil {
t.Fatalf("Could not set %d MTU on %#v interface: err", mtu, tl, err)
}
ifcAfterSet := readLink(t, tl.name)
if ifcAfterSet.MTU != mtu {
t.Fatalf("Could not set %d MTU on %#v interface", mtu, tl)
}
}
func TestNetworkSetMasterNoMaster(t *testing.T) {
master := testLink{"tstBr", "bridge"}
slave := testLink{"tstEth", "dummy"}
testLinks := []testLink{master, slave}
for _, tl := range testLinks {
addLink(t, tl.name, tl.linkType)
defer deleteLink(t, tl.name)
upLink(t, tl.name)
}
masterIfc := readLink(t, master.name)
slaveIfc := readLink(t, slave.name)
if err := NetworkSetMaster(slaveIfc, masterIfc); err != nil {
t.Fatalf("Could not set %#v to be the master of %#v: %s", master, slave, err)
}
// Trying to figure out a way to test which will not break on RHEL6.
// We could check for existence of /sys/class/net/tstEth/upper_tstBr
// which should point to the ../tstBr which is the UPPER device i.e. network bridge
if err := NetworkSetNoMaster(slaveIfc); err != nil {
t.Fatalf("Could not UNset %#v master of %#v: %s", master, slave, err)
}
}
func TestAddDelNetworkIp(t *testing.T) {
if testing.Short() {
return
@ -35,7 +176,7 @@ func TestAddDelNetworkIp(t *testing.T) {
}
if err := NetworkLinkAddIp(iface, ip, ipNet); err != nil {
t.Fatal(err)
t.Fatalf("Could not add IP address %s to interface %#v: %s", ip.String(), iface, err)
}
if !ipAssigned(iface, ip) {
@ -43,7 +184,7 @@ func TestAddDelNetworkIp(t *testing.T) {
}
if err := NetworkLinkDelIp(iface, ip, ipNet); err != nil {
t.Fatal(err)
t.Fatalf("Could not delete IP address %s from interface %#v: %s", ip.String(), iface, err)
}
if ipAssigned(iface, ip) {
@ -51,6 +192,28 @@ func TestAddDelNetworkIp(t *testing.T) {
}
}
func TestCreateVethPair(t *testing.T) {
if testing.Short() {
return
}
var (
name1 = "veth1"
name2 = "veth2"
)
if err := NetworkCreateVethPair(name1, name2); err != nil {
t.Fatalf("Could not create veth pair %s %s: %s", name1, name2, err)
}
defer NetworkLinkDel(name1)
readLink(t, name1)
readLink(t, name2)
}
//
// netlink package test which do not use RTNETLINK
//
func TestCreateBridgeWithMac(t *testing.T) {
if testing.Short() {
return
@ -77,55 +240,6 @@ func TestCreateBridgeWithMac(t *testing.T) {
}
}
func TestCreateBridgeLink(t *testing.T) {
if testing.Short() {
return
}
name := "mybrlink"
if err := NetworkLinkAdd(name, "bridge"); err != nil {
t.Fatal(err)
}
if _, err := net.InterfaceByName(name); err != nil {
t.Fatal(err)
}
if err := NetworkLinkDel(name); err != nil {
t.Fatal(err)
}
if _, err := net.InterfaceByName(name); err == nil {
t.Fatalf("expected error getting interface because %s bridge was deleted", name)
}
}
func TestCreateVethPair(t *testing.T) {
if testing.Short() {
return
}
var (
name1 = "veth1"
name2 = "veth2"
)
if err := NetworkCreateVethPair(name1, name2); err != nil {
t.Fatal(err)
}
defer NetworkLinkDel(name1)
if _, err := net.InterfaceByName(name1); err != nil {
t.Fatal(err)
}
if _, err := net.InterfaceByName(name2); err != nil {
t.Fatal(err)
}
}
func TestSetMACAddress(t *testing.T) {
if testing.Short() {
return
@ -139,7 +253,7 @@ func TestSetMACAddress(t *testing.T) {
}
defer NetworkLinkDel(name)
if err := NetworkSetMacAddress(name, mac); err != nil {
if err := SetMacAddress(name, mac); err != nil {
t.Fatal(err)
}