Allow placing veth peer into a namespace

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.
This commit is contained in:
Konstantin Baranov 2020-04-10 19:26:35 -07:00 committed by Vish (Ishaya) Abrams
parent 872fbf27a2
commit 337442361b
3 changed files with 121 additions and 5 deletions

View File

@ -341,6 +341,7 @@ type Veth struct {
LinkAttrs
PeerName string // veth on create only
PeerHardwareAddr net.HardwareAddr
PeerNamespace interface{}
}
func (veth *Veth) Attrs() *LinkAttrs {

View File

@ -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:

View File

@ -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)
}
@ -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()
@ -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)
}
@ -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)
}
@ -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)
}
@ -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)
}