Skip to content

Commit

Permalink
Allow placing veth peer into a namespace
Browse files Browse the repository at this point in the history
Creating a veth pair across namespaces now is a multistep process.
Doing it in one shot with this change is clearer as current
namespace never sees peer IF. Also, moving peer into a namespace
may be rather slow, so better avoided.
  • Loading branch information
const86 authored and vishvananda committed Sep 14, 2020
1 parent 872fbf2 commit 3374423
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 5 deletions.
1 change: 1 addition & 0 deletions link.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ type Veth struct {
LinkAttrs
PeerName string // veth on create only
PeerHardwareAddr net.HardwareAddr
PeerNamespace interface{}
}

func (veth *Veth) Attrs() *LinkAttrs {
Expand Down
10 changes: 10 additions & 0 deletions link_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -1345,6 +1345,16 @@ func (h *Handle) linkModify(link Link, flags int) error {
if link.PeerHardwareAddr != nil {
peer.AddRtAttr(unix.IFLA_ADDRESS, []byte(link.PeerHardwareAddr))
}
if link.PeerNamespace != nil {
switch ns := link.PeerNamespace.(type) {
case NsPid:
val := nl.Uint32Attr(uint32(ns))
peer.AddRtAttr(unix.IFLA_NET_NS_PID, val)
case NsFd:
val := nl.Uint32Attr(uint32(ns))
peer.AddRtAttr(unix.IFLA_NET_NS_FD, val)
}
}
case *Vxlan:
addVxlanAttrs(link, linkInfo)
case *Bond:
Expand Down
115 changes: 110 additions & 5 deletions link_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1024,7 +1024,7 @@ func TestLinkSetNs(t *testing.T) {
}
defer newns.Close()

link := &Veth{LinkAttrs{Name: "foo"}, "bar", nil}
link := &Veth{LinkAttrs{Name: "foo"}, "bar", nil, nil}
if err := LinkAdd(link); err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -1079,6 +1079,111 @@ func TestLinkAddDelWireguard(t *testing.T) {
testLinkAddDel(t, &Wireguard{LinkAttrs: LinkAttrs{Name: "wg0"}})
}

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

basens, err := netns.Get()
if err != nil {
t.Fatal("Failed to get basens")
}
defer basens.Close()

newns, err := netns.New()
if err != nil {
t.Fatal("Failed to create newns")
}
defer newns.Close()

link := &Veth{LinkAttrs{Name: "foo"}, "bar", nil, NsFd(basens)}
if err := LinkAdd(link); err != nil {
t.Fatal(err)
}

_, err = LinkByName("bar")
if err == nil {
t.Fatal("Link bar is in newns")
}

err = netns.Set(basens)
if err != nil {
t.Fatal("Failed to set basens")
}

_, err = LinkByName("bar")
if err != nil {
t.Fatal("Link bar is not in basens")
}

err = netns.Set(newns)
if err != nil {
t.Fatal("Failed to set newns")
}

_, err = LinkByName("foo")
if err != nil {
t.Fatal("Link foo is not in newns")
}
}

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

basens, err := netns.Get()
if err != nil {
t.Fatal("Failed to get basens")
}
defer basens.Close()

onens, err := netns.New()
if err != nil {
t.Fatal("Failed to create newns")
}
defer onens.Close()

twons, err := netns.New()
if err != nil {
t.Fatal("Failed to create twons")
}
defer twons.Close()

link := &Veth{LinkAttrs{Name: "foo", Namespace: NsFd(onens)}, "bar", nil, NsFd(basens)}
if err := LinkAdd(link); err != nil {
t.Fatal(err)
}

_, err = LinkByName("foo")
if err == nil {
t.Fatal("Link foo is in twons")
}

_, err = LinkByName("bar")
if err == nil {
t.Fatal("Link bar is in twons")
}

err = netns.Set(basens)
if err != nil {
t.Fatal("Failed to set basens")
}

_, err = LinkByName("bar")
if err != nil {
t.Fatal("Link bar is not in basens")
}

err = netns.Set(onens)
if err != nil {
t.Fatal("Failed to set onens")
}

_, err = LinkByName("foo")
if err != nil {
t.Fatal("Link foo is not in onens")
}
}

func TestLinkAddDelVxlan(t *testing.T) {
tearDown := setUpNetlinkTest(t)
defer tearDown()
Expand Down Expand Up @@ -1468,7 +1573,7 @@ func TestLinkSubscribe(t *testing.T) {
t.Fatal(err)
}

link := &Veth{LinkAttrs{Name: "foo", TxQLen: testTxQLen, MTU: 1400}, "bar", nil}
link := &Veth{LinkAttrs{Name: "foo", TxQLen: testTxQLen, MTU: 1400}, "bar", nil, nil}
if err := LinkAdd(link); err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -1515,7 +1620,7 @@ func TestLinkSubscribeWithOptions(t *testing.T) {
t.Fatal(err)
}

link := &Veth{LinkAttrs{Name: "foo", TxQLen: testTxQLen, MTU: 1400}, "bar", nil}
link := &Veth{LinkAttrs{Name: "foo", TxQLen: testTxQLen, MTU: 1400}, "bar", nil, nil}
if err := LinkAdd(link); err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -1549,7 +1654,7 @@ func TestLinkSubscribeAt(t *testing.T) {
t.Fatal(err)
}

link := &Veth{LinkAttrs{Name: "test", TxQLen: testTxQLen, MTU: 1400}, "bar", nil}
link := &Veth{LinkAttrs{Name: "test", TxQLen: testTxQLen, MTU: 1400}, "bar", nil, nil}
if err := nh.LinkAdd(link); err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -1591,7 +1696,7 @@ func TestLinkSubscribeListExisting(t *testing.T) {
}
defer nh.Delete()

link := &Veth{LinkAttrs{Name: "test", TxQLen: testTxQLen, MTU: 1400}, "bar", nil}
link := &Veth{LinkAttrs{Name: "test", TxQLen: testTxQLen, MTU: 1400}, "bar", nil, nil}
if err := nh.LinkAdd(link); err != nil {
t.Fatal(err)
}
Expand Down

0 comments on commit 3374423

Please sign in to comment.