This is a modification of erikh/netlink-remove-address PR

This is a modification of original PR by @erikh (R118)
to keep the netlink codebase more consistent and my OCD
under control :-)

Docker-DCO-1.1-Signed-off-by: Milos Gajdos <milosgajdos83@gmail.com> (github: milosgajdos83)
This commit is contained in:
Milos Gajdos 2014-08-08 02:37:38 +01:00
parent 5589d4d879
commit 356d006895
4 changed files with 82 additions and 12 deletions

View File

@ -2,9 +2,8 @@
all:
docker build -t docker/libcontainer .
test:
# we need NET_ADMIN for the netlink tests and SYS_ADMIN for mounting
docker run --rm -it --cap-add NET_ADMIN --cap-add SYS_ADMIN docker/libcontainer
test: build
docker run --rm --privileged docker/libcontainer
sh:
docker run --rm -it --cap-add NET_ADMIN --cap-add SYS_ADMIN -w /busybox docker/libcontainer nsinit exec sh

View File

@ -21,3 +21,10 @@ type Route struct {
Iface *net.Interface
Default bool
}
// An IfAddr defines IP network settings for a given network interface
type IfAddr struct {
Iface *net.Interface
IP net.IP
IPNet *net.IPNet
}

View File

@ -651,30 +651,28 @@ func NetworkSetNsFd(iface *net.Interface, fd int) error {
return s.HandleAck(wb.Seq)
}
// Add an Ip address to an interface. This is identical to:
// ip addr add $ip/$ipNet dev $iface
func NetworkLinkAddIp(iface *net.Interface, ip net.IP, ipNet *net.IPNet) error {
func networkLinkIpAction(action, flags int, ifa IfAddr) error {
s, err := getNetlinkSocket()
if err != nil {
return err
}
defer s.Close()
family := getIpFamily(ip)
family := getIpFamily(ifa.IP)
wb := newNetlinkRequest(syscall.RTM_NEWADDR, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
wb := newNetlinkRequest(action, flags)
msg := newIfAddrmsg(family)
msg.Index = uint32(iface.Index)
prefixLen, _ := ipNet.Mask.Size()
msg.Index = uint32(ifa.Iface.Index)
prefixLen, _ := ifa.IPNet.Mask.Size()
msg.Prefixlen = uint8(prefixLen)
wb.AddData(msg)
var ipData []byte
if family == syscall.AF_INET {
ipData = ip.To4()
ipData = ifa.IP.To4()
} else {
ipData = ip.To16()
ipData = ifa.IP.To16()
}
localData := newRtAttr(syscall.IFA_LOCAL, ipData)
@ -690,6 +688,26 @@ func NetworkLinkAddIp(iface *net.Interface, ip net.IP, ipNet *net.IPNet) error {
return s.HandleAck(wb.Seq)
}
// Delete an IP address from an interface. This is identical to:
// ip addr del $ip/$ipNet dev $iface
func NetworkLinkDelIp(iface *net.Interface, ip net.IP, ipNet *net.IPNet) error {
return networkLinkIpAction(
syscall.RTM_DELADDR,
syscall.NLM_F_ACK,
IfAddr{iface, ip, ipNet},
)
}
// Add an Ip address to an interface. This is identical to:
// ip addr add $ip/$ipNet dev $iface
func NetworkLinkAddIp(iface *net.Interface, ip net.IP, ipNet *net.IPNet) error {
return networkLinkIpAction(
syscall.RTM_NEWADDR,
syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK,
IfAddr{iface, ip, ipNet},
)
}
func zeroTerminated(s string) []byte {
return []byte(s + "\000")
}

View File

@ -2,9 +2,55 @@ package netlink
import (
"net"
"strings"
"testing"
)
func ipAssingned(iface *net.Interface, ip net.IP) bool {
addrs, _ := iface.Addrs()
for _, addr := range addrs {
args := strings.SplitN(addr.String(), "/", 2)
if args[0] == ip.String() {
return true
}
}
return false
}
func TestAddDelNetworkIp(t *testing.T) {
if testing.Short() {
return
}
ifaceName := "lo"
ip := net.ParseIP("127.0.1.1")
mask := net.IPv4Mask(255, 255, 255, 255)
ipNet := &net.IPNet{ip, mask}
iface, err := net.InterfaceByName(ifaceName)
if err != nil {
t.Skip("No 'lo' interface; skipping tests")
}
if err := NetworkLinkAddIp(iface, ip, ipNet); err != nil {
t.Fatal(err)
}
if !ipAssingned(iface, ip) {
t.Fatalf("Could not locate address '%s' in lo address list.", ip.String())
}
if err := NetworkLinkDelIp(iface, ip, ipNet); err != nil {
t.Fatal(err)
}
if ipAssingned(iface, ip) {
t.Fatal("Located address '%s' in lo address list after removal.", ip.String())
}
}
func TestCreateBridgeWithMac(t *testing.T) {
if testing.Short() {
return