Skip to content

Commit

Permalink
Add scope and flags support for netlink address
Browse files Browse the repository at this point in the history
  • Loading branch information
krhubert committed Nov 26, 2015
1 parent a57a12c commit 87df994
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 1 deletion.
5 changes: 4 additions & 1 deletion addr.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import (
// include a mask, so it stores the address as a net.IPNet.
type Addr struct {
*net.IPNet
Label string
Label string
Flags int
Scope int
FlagsMask int
}

// String returns $ip/$netmask $label
Expand Down
14 changes: 14 additions & 0 deletions addr_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import (
"github.com/vishvananda/netlink/nl"
)

// IFA_FLAGS is a u32 attribute.
const IFA_FLAGS = 0x8

// AddrAdd will add an IP address to a link device.
// Equivalent to: `ip addr add $addr dev $link`
func AddrAdd(link Link, addr *Addr) error {
Expand All @@ -35,6 +38,7 @@ func addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error {

msg := nl.NewIfAddrmsg(family)
msg.Index = uint32(base.Index)
msg.Scope = uint8(addr.Scope)
prefixlen, _ := addr.Mask.Size()
msg.Prefixlen = uint8(prefixlen)
req.AddData(msg)
Expand All @@ -52,6 +56,13 @@ func addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error {
addressData := nl.NewRtAttr(syscall.IFA_ADDRESS, addrData)
req.AddData(addressData)

if addr.FlagsMask != 0 {
b := make([]byte, 4)
native.PutUint32(b, uint32(addr.Flags))
flagsData := nl.NewRtAttr(IFA_FLAGS, b)
req.AddData(flagsData)
}

if addr.Label != "" {
labelData := nl.NewRtAttr(syscall.IFA_LABEL, nl.ZeroTerminated(addr.Label))
req.AddData(labelData)
Expand Down Expand Up @@ -111,6 +122,8 @@ func AddrList(link Link, family int) ([]Addr, error) {
}
case syscall.IFA_LABEL:
addr.Label = string(attr.Value[:len(attr.Value)-1])
case IFA_FLAGS:
addr.Flags = int(native.Uint32(attr.Value[0:4]))
}
}

Expand All @@ -120,6 +133,7 @@ func AddrList(link Link, family int) ([]Addr, error) {
} else {
addr.IPNet = dst
}
addr.Scope = int(msg.Scope)

res = append(res, addr)
}
Expand Down
95 changes: 95 additions & 0 deletions addr_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package netlink

import (
"net"
"syscall"
"testing"
)

Expand Down Expand Up @@ -43,3 +45,96 @@ func TestAddrAddDel(t *testing.T) {
t.Fatal("Address not removed properly")
}
}

func TestAddrAddDelScope(t *testing.T) {
tearDown := setUpNetlinkTest(t)
defer tearDown()

link, err := LinkByName("lo")
if err != nil {
t.Fatal(err)
}

addr := &Addr{
IPNet: &net.IPNet{
IP: net.IPv4(127, 1, 1, 1),
Mask: net.CIDRMask(24, 32),
},
Scope: syscall.RT_SCOPE_LINK,
}
if err = AddrAdd(link, addr); err != nil {
t.Fatal(err)
}

addrs, err := AddrList(link, FAMILY_ALL)
if err != nil {
t.Fatal(err)
}

if len(addrs) != 1 || !addr.Equal(addrs[0]) {
t.Fatal("Address not added properly")
}

if addrs[0].Scope != addr.Scope {
t.Fatal("Address scope not added properly")
}

if err = AddrDel(link, addr); err != nil {
t.Fatal(err)
}
addrs, err = AddrList(link, FAMILY_ALL)
if err != nil {
t.Fatal(err)
}

if len(addrs) != 0 {
t.Fatal("Address not removed properly")
}
}

func TestAddrAddDelFlags(t *testing.T) {
tearDown := setUpNetlinkTest(t)
defer tearDown()

link, err := LinkByName("lo")
if err != nil {
t.Fatal(err)
}

addr := &Addr{
IPNet: &net.IPNet{
IP: net.IPv4(127, 1, 1, 1),
Mask: net.CIDRMask(24, 32),
},
Flags: syscall.IFA_F_PERMANENT,
FlagsMask: syscall.IFA_F_PERMANENT,
}
if err = AddrAdd(link, addr); err != nil {
t.Fatal(err)
}

addrs, err := AddrList(link, FAMILY_ALL)
if err != nil {
t.Fatal(err)
}

if len(addrs) != 1 || !addr.Equal(addrs[0]) {
t.Fatal("Address not added properly")
}

if addrs[0].Flags != addr.Flags {
t.Fatal("Address flags not set properly")
}

if err = AddrDel(link, addr); err != nil {
t.Fatal(err)
}
addrs, err = AddrList(link, FAMILY_ALL)
if err != nil {
t.Fatal(err)
}

if len(addrs) != 0 {
t.Fatal("Address not removed properly")
}
}

0 comments on commit 87df994

Please sign in to comment.