Extract AttachContainer() function

Also move netlink and netns code from common to net

Creates interface if not already there
Adds addresses
Move the set link 'up' to after addresses are added
This commit is contained in:
Bryan Boreham committed 2016-05-25 17:29:45 +01:00
1 parent 0257274aa8
commit 85023e0a76
5 files changed
+103 -50

No files matched your search

+6 -23
View File
@@ -2,12 +2,14 @@ package common
import (
"fmt"
"github.com/vishvananda/netlink"
"github.com/vishvananda/netns"
"net"
"os"
"runtime"
"strings"
"github.com/vishvananda/netlink"
"github.com/vishvananda/netns"
weavenet "github.com/weaveworks/weave/net"
)
// Assert test is true, panic otherwise
@@ -25,25 +27,6 @@ func ErrorMessages(errors []error) string {
return strings.Join(result, "\n")
}
func WithNetNS(ns netns.NsHandle, work func() error) error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
oldNs, err := netns.Get()
if err == nil {
defer oldNs.Close()
err = netns.Set(ns)
if err == nil {
defer netns.Set(oldNs)
err = work()
}
}
return err
}
type NetDev struct {
Name string
MAC net.HardwareAddr
@@ -63,7 +46,7 @@ func FindNetDevs(processID int, match func(link netlink.Link) bool) ([]NetDev, e
}
defer ns.Close()
err = WithNetNS(ns, func() error {
err = weavenet.WithNetNS(ns, func() error {
return forEachLink(func(link netlink.Link) error {
if match(link) {
netDev, err := linkToNetDev(link)
+1 -1
View File
@@ -1,4 +1,4 @@
package common
package net
import "fmt"
import "io"
+37
View File
@@ -0,0 +1,37 @@
package net
import (
"runtime"
"github.com/vishvananda/netlink"
"github.com/vishvananda/netns"
)
func WithNetNS(ns netns.NsHandle, work func() error) error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
oldNs, err := netns.Get()
if err == nil {
defer oldNs.Close()
err = netns.Set(ns)
if err == nil {
defer netns.Set(oldNs)
err = work()
}
}
return err
}
func WithNetNSLink(ns netns.NsHandle, ifName string, work func(link netlink.Link) error) error {
return WithNetNS(ns, func() error {
link, err := netlink.LinkByName(ifName)
if err != nil {
return err
}
return work(link)
})
}
+52 -8
View File
@@ -4,9 +4,10 @@ import (
"fmt"
"net"
"github.com/j-keck/arping"
"github.com/vishvananda/netlink"
"github.com/vishvananda/netns"
"github.com/weaveworks/weave/common"
"github.com/weaveworks/weave/common/odp"
)
@@ -73,22 +74,65 @@ func CreateAndAttachVeth(localName, peerName, bridgeName string, mtu int, init f
return local, nil
}
func SetupGuest(guest netlink.Link, name string, cidrs []net.IPNet) error {
func SetupGuest(guest netlink.Link, name string) error {
var err error
if err = netlink.LinkSetName(guest, name); err != nil {
return err
}
if err = netlink.LinkSetUp(guest); err != nil {
if err = ConfigureARPCache(name); err != nil {
return err
}
if err = common.ConfigureARPCache(name); err != nil {
return nil
}
func AddAddresses(guest netlink.Link, cidrs []*net.IPNet) error {
for _, ipnet := range cidrs {
if err := netlink.AddrAdd(guest, &netlink.Addr{IPNet: ipnet}); err != nil {
return fmt.Errorf("failed to add IP address to %q: %v", guest.Attrs().Name, err)
}
arping.GratuitousArpOverIfaceByName(ipnet.IP, guest.Attrs().Name)
}
return nil
}
func interfaceExistsInNamespace(ns netns.NsHandle, ifName string) bool {
err := WithNetNS(ns, func() error {
_, err := netlink.LinkByName(ifName)
return err
})
return err == nil
}
func AttachContainer(ns netns.NsHandle, id, ifName, bridgeName string, mtu int, cidrs []*net.IPNet) error {
if !interfaceExistsInNamespace(ns, ifName) {
if len(id) > 5 {
id = id[:5]
}
name, peerName := "vethwepl"+id, "vethwg"+id
_, err := CreateAndAttachVeth(name, peerName, bridgeName, mtu, func(local, guest netlink.Link) error {
if err := netlink.LinkSetNsFd(guest, int(ns)); err != nil {
return fmt.Errorf("failed to move veth to container netns: %s", err)
}
if err := WithNetNS(ns, func() error {
return SetupGuest(guest, ifName)
}); err != nil {
return fmt.Errorf("error setting up interface: %s", err)
}
return nil
})
if err != nil {
return err
}
}
for _, ipnet := range cidrs {
if err = netlink.AddrAdd(guest, &netlink.Addr{IPNet: &ipnet}); err != nil {
return fmt.Errorf("failed to add IP address to %q: %v", name, err)
if err := WithNetNSLink(ns, ifName, func(guest netlink.Link) error {
if err := AddAddresses(guest, cidrs); err != nil {
return err
}
arping.GratuitousArpOverIfaceByName(ipnet.IP, name)
return netlink.LinkSetUp(guest)
}); err != nil {
return err
}
return nil
}
+7 -18
View File
@@ -10,7 +10,6 @@ import (
"github.com/appc/cni/pkg/ipam"
"github.com/appc/cni/pkg/skel"
"github.com/appc/cni/pkg/types"
"github.com/j-keck/arping"
"github.com/vishvananda/netlink"
"github.com/vishvananda/netns"
weaveapi "github.com/weaveworks/weave/api"
@@ -94,24 +93,14 @@ func (c *CNIPlugin) CmdAdd(args *skel.CmdArgs) error {
id = fmt.Sprintf("%x", data)
}
name, peerName := vethPair(id)
_, err = weavenet.CreateAndAttachVeth(name, peerName, conf.BrName, conf.MTU, func(local, guest netlink.Link) error {
if err = netlink.LinkSetNsFd(guest, int(ns)); err != nil {
return fmt.Errorf("failed to move veth to container netns: %s", err)
}
if err = common.WithNetNS(ns, func() error {
if err := weavenet.SetupGuest(guest, args.IfName, []net.IPNet{result.IP4.IP}); err != nil {
return err
}
return setupRoutes(guest, args.IfName, result.IP4.IP, result.IP4.Gateway, result.IP4.Routes)
}); err != nil {
return fmt.Errorf("error setting up interface: %s", err)
}
return nil
})
if err != nil {
if err := weavenet.AttachContainer(ns, id, args.IfName, conf.BrName, conf.MTU, []*net.IPNet{&result.IP4.IP}); err != nil {
return err
}
if err := weavenet.WithNetNSLink(ns, args.IfName, func(guest netlink.Link) error {
return setupRoutes(guest, args.IfName, result.IP4.IP, result.IP4.Gateway, result.IP4.Routes)
}); err != nil {
return fmt.Errorf("error setting up routes: %s", err)
}
result.DNS = conf.DNS
return result.Print()
@@ -186,7 +175,7 @@ func (c *CNIPlugin) CmdDel(args *skel.CmdArgs) error {
return err
}
defer ns.Close()
err = common.WithNetNS(ns, func() error {
err = weavenet.WithNetNS(ns, func() error {
link, err := netlink.LinkByName(args.IfName)
if err != nil {
return err