diff --git a/addr_linux.go b/addr_linux.go index 7553a05..d8957d8 100644 --- a/addr_linux.go +++ b/addr_linux.go @@ -74,17 +74,19 @@ func (h *Handle) AddrDel(link Link, addr *Addr) error { } func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error { - base := link.Attrs() - if addr.Label != "" && !strings.HasPrefix(addr.Label, base.Name) { - return fmt.Errorf("label must begin with interface name") - } - h.ensureIndex(base) - family := nl.GetIPFamily(addr.IP) - msg := nl.NewIfAddrmsg(family) - msg.Index = uint32(base.Index) msg.Scope = uint8(addr.Scope) + if link == nil { + msg.Index = uint32(addr.LinkIndex) + } else { + base := link.Attrs() + if addr.Label != "" && !strings.HasPrefix(addr.Label, base.Name) { + return fmt.Errorf("label must begin with interface name") + } + h.ensureIndex(base) + msg.Index = uint32(base.Index) + } mask := addr.Mask if addr.Peer != nil { mask = addr.Peer.Mask diff --git a/addr_test.go b/addr_test.go index 0a43212..d45a989 100644 --- a/addr_test.go +++ b/addr_test.go @@ -145,58 +145,65 @@ func TestAddrAddReplace(t *testing.T) { tearDown := setUpNetlinkTest(t) defer tearDown() - var address = &net.IPNet{IP: net.IPv4(127, 0, 0, 2), Mask: net.CIDRMask(24, 32)} - var addr = &Addr{IPNet: address} + for _, nilLink := range []bool{false, true} { + var address = &net.IPNet{IP: net.IPv4(127, 0, 0, 2), Mask: net.CIDRMask(24, 32)} + var addr = &Addr{IPNet: address} - link, err := LinkByName("lo") - if err != nil { - t.Fatal(err) - } + link, err := LinkByName("lo") + if err != nil { + t.Fatal(err) + } - err = AddrAdd(link, addr) - if err != nil { - t.Fatal(err) - } + if nilLink { + addr.LinkIndex = link.Attrs().Index + link = nil + } - addrs, err := AddrList(link, FAMILY_ALL) - if err != nil { - t.Fatal(err) - } + err = AddrAdd(link, addr) + if err != nil { + t.Fatal(err) + } - if len(addrs) != 1 { - t.Fatal("Address not added properly") - } + addrs, err := AddrList(link, FAMILY_ALL) + if err != nil { + t.Fatal(err) + } - err = AddrAdd(link, addr) - if err == nil { - t.Fatal("Re-adding address should fail (but succeeded unexpectedly).") - } + if len(addrs) != 1 { + t.Fatal("Address not added properly") + } - err = AddrReplace(link, addr) - if err != nil { - t.Fatal("Replacing address failed.") - } + err = AddrAdd(link, addr) + if err == nil { + t.Fatal("Re-adding address should fail (but succeeded unexpectedly).") + } - addrs, err = AddrList(link, FAMILY_ALL) - if err != nil { - t.Fatal(err) - } + err = AddrReplace(link, addr) + if err != nil { + t.Fatal("Replacing address failed.") + } - if len(addrs) != 1 { - t.Fatal("Address not added properly") - } + addrs, err = AddrList(link, FAMILY_ALL) + if err != nil { + t.Fatal(err) + } - if err = AddrDel(link, addr); err != nil { - t.Fatal(err) - } + if len(addrs) != 1 { + t.Fatal("Address not added properly") + } - addrs, err = AddrList(link, FAMILY_ALL) - if err != nil { - t.Fatal(err) - } + if err = AddrDel(link, addr); err != nil { + t.Fatal(err) + } - if len(addrs) != 0 { - t.Fatal("Address not removed properly") + addrs, err = AddrList(link, FAMILY_ALL) + if err != nil { + t.Fatal(err) + } + + if len(addrs) != 0 { + t.Fatal("Address not removed properly") + } } }