Преглед изворни кода

Fallback to dumping ifaces when name lookup fails

Older kernels don't support looking up interface by name (via netlink).
In these cases, fallback to dumping all interfaces. This patch just
pulls in latest netlink library.

Fixes #66
Eugene Yakubovich пре 10 година
родитељ
комит
a2dddf030d

+ 1 - 1
Godeps/Godeps.json

@@ -21,7 +21,7 @@
 		},
 		{
 			"ImportPath": "github.com/vishvananda/netlink",
-			"Rev": "dd2d5f17ae986599e165402a77c7e85fea606bec"
+			"Rev": "2187ba67a244c1c32f53bf88876e766bbbbcd5e6"
 		}
 	]
 }

+ 4 - 2
Godeps/_workspace/src/github.com/vishvananda/netlink/README.md

@@ -1,5 +1,7 @@
 # netlink - netlink library for go #
 
+[![Build Status](https://travis-ci.org/vishvananda/netlink.png?branch=master)](https://travis-ci.org/vishvananda/netlink)
+
 The netlink package provides a simple netlink library for go. Netlink
 is the interface a user-space program in linux uses to communicate with
 the kernel. It can be used to add and remove interfaces, set ip addresses
@@ -41,8 +43,8 @@ import (
 )
 
 func main() {
-    mybridge := &netlink.Link{Name: "mybridge", Type: "bridge"}
-    netlink, _ := netlink.LinkAdd(mybridge)
+    mybridge := &netlink.Bridge{netlink.LinkAttrs{Name: "foo"}}
+    _ := netlink.LinkAdd(mybridge)
     eth1, _ := netlink.LinkByName("eth1")
     netlink.LinkSetMaster(eth1, mybridge)
 }

+ 30 - 3
Godeps/_workspace/src/github.com/vishvananda/netlink/link_linux.go

@@ -11,6 +11,7 @@ import (
 )
 
 var native = nl.NativeEndian()
+var lookupByDump = false
 
 func ensureIndex(link *LinkAttrs) {
 	if link != nil && link.Index == 0 {
@@ -177,7 +178,7 @@ type vxlanPortRange struct {
 	Lo, Hi uint16
 }
 
-func addVxlanAttrs(vxlan *Vxlan, linkInfo *nl.RtAttr) {
+func addVxlanAttrs(vxlan* Vxlan, linkInfo *nl.RtAttr) {
 	data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
 	nl.NewRtAttrChild(data, nl.IFLA_VXLAN_ID, nl.Uint32Attr(uint32(vxlan.VxlanId)))
 	if vxlan.VtepDevIndex != 0 {
@@ -226,7 +227,7 @@ func addVxlanAttrs(vxlan *Vxlan, linkInfo *nl.RtAttr) {
 		nl.NewRtAttrChild(data, nl.IFLA_VXLAN_PORT, nl.Uint16Attr(uint16(vxlan.Port)))
 	}
 	if vxlan.PortLow > 0 || vxlan.PortHigh > 0 {
-		pr := vxlanPortRange{uint16(vxlan.PortLow), uint16(vxlan.PortHigh)}
+		pr := vxlanPortRange{ uint16(vxlan.PortLow), uint16(vxlan.PortHigh) }
 
 		buf := new(bytes.Buffer)
 		binary.Write(buf, binary.BigEndian, &pr)
@@ -314,8 +315,26 @@ func LinkDel(link Link) error {
 	return err
 }
 
+func linkByNameDump(name string) (Link, error) {
+	links, err := LinkList()
+	if err != nil {
+		return nil, err
+	}
+
+	for _, link := range links {
+		if link.Attrs().Name == name {
+			return link, nil
+		}
+	}
+	return nil, fmt.Errorf("Link %s not found", name)
+}
+
 // LinkByName finds a link by name and returns a pointer to the object.
 func LinkByName(name string) (Link, error) {
+	if lookupByDump {
+		return linkByNameDump(name)
+	}
+
 	req := nl.NewNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_ACK)
 
 	msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
@@ -324,7 +343,15 @@ func LinkByName(name string) (Link, error) {
 	nameData := nl.NewRtAttr(syscall.IFLA_IFNAME, nl.ZeroTerminated(name))
 	req.AddData(nameData)
 
-	return execGetLink(req)
+	link, err := execGetLink(req)
+	if err == syscall.EINVAL {
+		// older kernels don't support looking up via IFLA_IFNAME
+		// so fall back to dumping all links
+		lookupByDump = true
+		return linkByNameDump(name)
+	}
+
+	return link, err
 }
 
 // LinkByIndex finds a link by index and returns a pointer to the object.

+ 4 - 1
Godeps/_workspace/src/github.com/vishvananda/netlink/link_test.go

@@ -349,7 +349,7 @@ func TestLinkAddDelVxlan(t *testing.T) {
 		LinkAttrs: LinkAttrs{
 			Name: "bar",
 		},
-		VxlanId: 10,
+		VxlanId:      10,
 		VtepDevIndex: parent.Index,
 		Learning:     true,
 		L2miss:       true,
@@ -363,6 +363,9 @@ func TestLinkAddDelVxlan(t *testing.T) {
 }
 
 func TestLinkByIndex(t *testing.T) {
+	tearDown := setUpNetlinkTest(t)
+	defer tearDown()
+
 	dummy := &Dummy{LinkAttrs{Name: "dummy"}}
 	if err := LinkAdd(dummy); err != nil {
 		t.Fatal(err)

+ 9 - 6
Godeps/_workspace/src/github.com/vishvananda/netlink/neigh_test.go

@@ -20,7 +20,7 @@ func parseMAC(s string) net.HardwareAddr {
 
 func dumpContains(dump []Neigh, e arpEntry) bool {
 	for _, n := range dump {
-		if n.IP.Equal(e.ip) && (n.State & NUD_INCOMPLETE) == 0 {
+		if n.IP.Equal(e.ip) && (n.State&NUD_INCOMPLETE) == 0 {
 			return true
 		}
 	}
@@ -28,6 +28,9 @@ func dumpContains(dump []Neigh, e arpEntry) bool {
 }
 
 func TestNeighAddDel(t *testing.T) {
+	tearDown := setUpNetlinkTest(t)
+	defer tearDown()
+
 	dummy := Dummy{LinkAttrs{Name: "neigh0"}}
 	if err := LinkAdd(&dummy); err != nil {
 		t.Fatal(err)
@@ -36,11 +39,11 @@ func TestNeighAddDel(t *testing.T) {
 	ensureIndex(dummy.Attrs())
 
 	arpTable := []arpEntry{
-		{ net.ParseIP("10.99.0.1"), parseMAC("aa:bb:cc:dd:00:01") },
-		{ net.ParseIP("10.99.0.2"), parseMAC("aa:bb:cc:dd:00:02") },
-		{ net.ParseIP("10.99.0.3"), parseMAC("aa:bb:cc:dd:00:03") },
-		{ net.ParseIP("10.99.0.4"), parseMAC("aa:bb:cc:dd:00:04") },
-		{ net.ParseIP("10.99.0.5"), parseMAC("aa:bb:cc:dd:00:05") },
+		{net.ParseIP("10.99.0.1"), parseMAC("aa:bb:cc:dd:00:01")},
+		{net.ParseIP("10.99.0.2"), parseMAC("aa:bb:cc:dd:00:02")},
+		{net.ParseIP("10.99.0.3"), parseMAC("aa:bb:cc:dd:00:03")},
+		{net.ParseIP("10.99.0.4"), parseMAC("aa:bb:cc:dd:00:04")},
+		{net.ParseIP("10.99.0.5"), parseMAC("aa:bb:cc:dd:00:05")},
 	}
 
 	// Add the arpTable

+ 0 - 1
Godeps/_workspace/src/github.com/vishvananda/netlink/nl/addr_linux.go

@@ -45,4 +45,3 @@ func (msg *IfAddrmsg) Serialize() []byte {
 func (msg *IfAddrmsg) Len() int {
 	return syscall.SizeofIfAddrmsg
 }
-

+ 2 - 2
Godeps/_workspace/src/github.com/vishvananda/netlink/nl/nl_linux.go

@@ -4,8 +4,8 @@ package nl
 import (
 	"bytes"
 	"encoding/binary"
-	"net"
 	"fmt"
+	"net"
 	"sync/atomic"
 	"syscall"
 	"unsafe"
@@ -304,7 +304,7 @@ func Subscribe(protocol int, groups ...uint) (*NetlinkSocket, error) {
 	s.lsa.Family = syscall.AF_NETLINK
 
 	for _, g := range groups {
-		s.lsa.Groups |= (1 << (g-1))
+		s.lsa.Groups |= (1 << (g - 1))
 	}
 
 	if err := syscall.Bind(fd, &s.lsa); err != nil {

+ 0 - 1
Godeps/_workspace/src/github.com/vishvananda/netlink/nl/route_linux.go

@@ -31,4 +31,3 @@ func DeserializeRtMsg(b []byte) *RtMsg {
 func (msg *RtMsg) Serialize() []byte {
 	return (*(*[syscall.SizeofRtMsg]byte)(unsafe.Pointer(msg)))[:]
 }
-

+ 0 - 1
Godeps/_workspace/src/github.com/vishvananda/netlink/nl/xfrm_policy_linux.go

@@ -117,4 +117,3 @@ func DeserializeXfrmUserTmpl(b []byte) *XfrmUserTmpl {
 func (msg *XfrmUserTmpl) Serialize() []byte {
 	return (*(*[SizeofXfrmUserTmpl]byte)(unsafe.Pointer(msg)))[:]
 }
-

+ 0 - 1
Godeps/_workspace/src/github.com/vishvananda/netlink/nl/xfrm_state_linux.go

@@ -219,4 +219,3 @@ func DeserializeXfrmEncapTmpl(b []byte) *XfrmEncapTmpl {
 func (msg *XfrmEncapTmpl) Serialize() []byte {
 	return (*(*[SizeofXfrmEncapTmpl]byte)(unsafe.Pointer(msg)))[:]
 }
-