diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index dcf43368f3..e9da6037dc 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -1,7 +1,6 @@ { "ImportPath": "github.com/docker/libnetwork", "GoVersion": "go1.5", - "GodepVersion": "v74", "Packages": [ "./..." ], @@ -111,11 +110,11 @@ "Comment": "v1.4.1-11716-g24076ed", "Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" }, - { - "ImportPath": "github.com/docker/docker/pkg/locker", - "Comment": "v1.4.1-11716-g24076ed", - "Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" - }, + { + "ImportPath": "github.com/docker/docker/pkg/locker", + "Comment": "v1.4.1-11716-g24076ed", + "Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" + }, { "ImportPath": "github.com/docker/docker/pkg/mflag", "Comment": "v1.4.1-11716-g24076ed", @@ -212,33 +211,33 @@ }, { "ImportPath": "github.com/docker/libkv", - "Comment": "v0.1.0-35-g7283ef2", - "Rev": "7283ef27ed32fe267388510a91709b307bb9942c" + "Comment": "v0.2.1-5-g1d84310", + "Rev": "1d8431073ae03cdaedb198a89722f3aab6d418ef" }, { "ImportPath": "github.com/docker/libkv/store", - "Comment": "v0.1.0-35-g7283ef2", - "Rev": "7283ef27ed32fe267388510a91709b307bb9942c" + "Comment": "v0.2.1-5-g1d84310", + "Rev": "1d8431073ae03cdaedb198a89722f3aab6d418ef" }, { "ImportPath": "github.com/docker/libkv/store/boltdb", - "Comment": "v0.1.0-35-g7283ef2", - "Rev": "7283ef27ed32fe267388510a91709b307bb9942c" + "Comment": "v0.2.1-5-g1d84310", + "Rev": "1d8431073ae03cdaedb198a89722f3aab6d418ef" }, { "ImportPath": "github.com/docker/libkv/store/consul", - "Comment": "v0.1.0-35-g7283ef2", - "Rev": "7283ef27ed32fe267388510a91709b307bb9942c" + "Comment": "v0.2.1-5-g1d84310", + "Rev": "1d8431073ae03cdaedb198a89722f3aab6d418ef" }, { "ImportPath": "github.com/docker/libkv/store/etcd", - "Comment": "v0.1.0-35-g7283ef2", - "Rev": "7283ef27ed32fe267388510a91709b307bb9942c" + "Comment": "v0.2.1-5-g1d84310", + "Rev": "1d8431073ae03cdaedb198a89722f3aab6d418ef" }, { "ImportPath": "github.com/docker/libkv/store/zookeeper", - "Comment": "v0.1.0-35-g7283ef2", - "Rev": "7283ef27ed32fe267388510a91709b307bb9942c" + "Comment": "v0.2.1-5-g1d84310", + "Rev": "1d8431073ae03cdaedb198a89722f3aab6d418ef" }, { "ImportPath": "github.com/godbus/dbus", @@ -404,11 +403,11 @@ }, { "ImportPath": "github.com/vishvananda/netlink", - "Rev": "e73bad418fd727ed3a02830b1af1ad0283a1de6c" + "Rev": "17ea11b5a11c5614597c65a671105e8ee58c4d04" }, { "ImportPath": "github.com/vishvananda/netlink/nl", - "Rev": "e73bad418fd727ed3a02830b1af1ad0283a1de6c" + "Rev": "17ea11b5a11c5614597c65a671105e8ee58c4d04" }, { "ImportPath": "github.com/vishvananda/netns", diff --git a/Godeps/_workspace/src/github.com/docker/libkv/.travis.yml b/Godeps/_workspace/src/github.com/docker/libkv/.travis.yml index f7cecbdf9c..a7a3bcffc7 100644 --- a/Godeps/_workspace/src/github.com/docker/libkv/.travis.yml +++ b/Godeps/_workspace/src/github.com/docker/libkv/.travis.yml @@ -1,7 +1,7 @@ language: go go: - - 1.5.3 + - 1.7.1 # let us have speedy Docker-based Travis workers sudo: false @@ -16,7 +16,7 @@ before_install: before_script: - script/travis_consul.sh 0.6.3 - - script/travis_etcd.sh 2.2.5 + - script/travis_etcd.sh 3.0.0 - script/travis_zk.sh 3.5.1-alpha script: diff --git a/Godeps/_workspace/src/github.com/docker/libkv/MAINTAINERS b/Godeps/_workspace/src/github.com/docker/libkv/MAINTAINERS index 4dd59c7e27..4a8bbc6135 100644 --- a/Godeps/_workspace/src/github.com/docker/libkv/MAINTAINERS +++ b/Godeps/_workspace/src/github.com/docker/libkv/MAINTAINERS @@ -11,7 +11,6 @@ [Org] [Org."Core maintainers"] people = [ - "abronan", "aluzzardi", "sanimej", "vieux", @@ -25,11 +24,6 @@ # ADD YOURSELF HERE IN ALPHABETICAL ORDER - [people.abronan] - Name = "Alexandre Beslic" - Email = "abronan@docker.com" - GitHub = "abronan" - [people.aluzzardi] Name = "Andrea Luzzardi" Email = "al@docker.com" diff --git a/Godeps/_workspace/src/github.com/docker/libkv/store/boltdb/boltdb.go b/Godeps/_workspace/src/github.com/docker/libkv/store/boltdb/boltdb.go index 4026e0a20c..cdfd74f878 100644 --- a/Godeps/_workspace/src/github.com/docker/libkv/store/boltdb/boltdb.go +++ b/Godeps/_workspace/src/github.com/docker/libkv/store/boltdb/boltdb.go @@ -59,6 +59,7 @@ func New(endpoints []string, options *store.Config) (store.Store, error) { db *bolt.DB err error boltOptions *bolt.Options + timeout = transientTimeout ) if len(endpoints) > 1 { @@ -82,11 +83,15 @@ func New(endpoints []string, options *store.Config) (store.Store, error) { } } + if options.ConnectionTimeout != 0 { + timeout = options.ConnectionTimeout + } + b := &BoltDB{ client: db, path: endpoints[0], boltBucket: []byte(options.Bucket), - timeout: transientTimeout, + timeout: timeout, PersistConnection: options.PersistConnection, } diff --git a/Godeps/_workspace/src/github.com/docker/libkv/store/zookeeper/zookeeper.go b/Godeps/_workspace/src/github.com/docker/libkv/store/zookeeper/zookeeper.go index 8a44ad318a..ff8d4ebe0f 100644 --- a/Godeps/_workspace/src/github.com/docker/libkv/store/zookeeper/zookeeper.go +++ b/Godeps/_workspace/src/github.com/docker/libkv/store/zookeeper/zookeeper.go @@ -252,7 +252,7 @@ func (s *Zookeeper) List(directory string) ([]*store.KVPair, error) { pair, err := s.Get(strings.TrimSuffix(directory, "/") + s.normalize(key)) if err != nil { // If node is not found: List is out of date, retry - if err == zk.ErrNoNode { + if err == store.ErrKeyNotFound { return s.List(directory) } return nil, err diff --git a/Godeps/_workspace/src/github.com/vishvananda/netlink/bpf_linux.go b/Godeps/_workspace/src/github.com/vishvananda/netlink/bpf_linux.go index acd9490131..533743987a 100644 --- a/Godeps/_workspace/src/github.com/vishvananda/netlink/bpf_linux.go +++ b/Godeps/_workspace/src/github.com/vishvananda/netlink/bpf_linux.go @@ -8,11 +8,11 @@ package netlink #include #include -static int load_simple_bpf(int prog_type) { +static int load_simple_bpf(int prog_type, int ret) { #ifdef __NR_bpf - // { return 1; } + // { return ret; } __u64 __attribute__((aligned(8))) insns[] = { - 0x00000001000000b7ull, + 0x00000000000000b7ull | ((__u64)ret<<32), 0x0000000000000095ull, }; __u8 __attribute__((aligned(8))) license[] = "ASL2"; @@ -51,10 +51,12 @@ const ( BPF_PROG_TYPE_KPROBE BPF_PROG_TYPE_SCHED_CLS BPF_PROG_TYPE_SCHED_ACT + BPF_PROG_TYPE_TRACEPOINT + BPF_PROG_TYPE_XDP ) // loadSimpleBpf loads a trivial bpf program for testing purposes -func loadSimpleBpf(progType BpfProgType) (int, error) { - fd, err := C.load_simple_bpf(C.int(progType)) +func loadSimpleBpf(progType BpfProgType, ret int) (int, error) { + fd, err := C.load_simple_bpf(C.int(progType), C.int(ret)) return int(fd), err } diff --git a/Godeps/_workspace/src/github.com/vishvananda/netlink/filter.go b/Godeps/_workspace/src/github.com/vishvananda/netlink/filter.go index 116aeba06e..bc8a1e9614 100644 --- a/Godeps/_workspace/src/github.com/vishvananda/netlink/filter.go +++ b/Godeps/_workspace/src/github.com/vishvananda/netlink/filter.go @@ -60,7 +60,7 @@ func (a TcAct) String() string { case TC_ACT_JUMP: return "jump" } - return fmt.Sprintf("0x%x", a) + return fmt.Sprintf("0x%x", int32(a)) } type TcPolAct int32 @@ -86,7 +86,7 @@ func (a TcPolAct) String() string { case TC_POLICE_PIPE: return "pipe" } - return fmt.Sprintf("0x%x", a) + return fmt.Sprintf("0x%x", int32(a)) } type ActionAttrs struct { diff --git a/Godeps/_workspace/src/github.com/vishvananda/netlink/handle_linux.go b/Godeps/_workspace/src/github.com/vishvananda/netlink/handle_linux.go index 5377988752..a04ceae6b6 100644 --- a/Godeps/_workspace/src/github.com/vishvananda/netlink/handle_linux.go +++ b/Godeps/_workspace/src/github.com/vishvananda/netlink/handle_linux.go @@ -1,7 +1,9 @@ package netlink import ( + "fmt" "syscall" + "time" "github.com/vishvananda/netlink/nl" "github.com/vishvananda/netns" @@ -33,6 +35,29 @@ func NewHandle(nlFamilies ...int) (*Handle, error) { return newHandle(netns.None(), netns.None(), nlFamilies...) } +// SetSocketTimeout sets the send and receive timeout for each socket in the +// netlink handle. Although the socket timeout has granularity of one +// microsecond, the effective granularity is floored by the kernel timer tick, +// which default value is four milliseconds. +func (h *Handle) SetSocketTimeout(to time.Duration) error { + if to < time.Microsecond { + return fmt.Errorf("invalid timeout, minimul value is %s", time.Microsecond) + } + tv := syscall.NsecToTimeval(to.Nanoseconds()) + for _, sh := range h.sockets { + fd := sh.Socket.GetFd() + err := syscall.SetsockoptTimeval(fd, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &tv) + if err != nil { + return err + } + err = syscall.SetsockoptTimeval(fd, syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, &tv) + if err != nil { + return err + } + } + return nil +} + // NewHandle returns a netlink handle on the network namespace // specified by ns. If ns=netns.None(), current network namespace // will be assumed diff --git a/Godeps/_workspace/src/github.com/vishvananda/netlink/link.go b/Godeps/_workspace/src/github.com/vishvananda/netlink/link.go index 9dbc221506..0e160a9fbb 100644 --- a/Godeps/_workspace/src/github.com/vishvananda/netlink/link.go +++ b/Godeps/_workspace/src/github.com/vishvananda/netlink/link.go @@ -26,11 +26,15 @@ type LinkAttrs struct { Name string HardwareAddr net.HardwareAddr Flags net.Flags + RawFlags uint32 ParentIndex int // index of the parent link device MasterIndex int // must be the index of a bridge Namespace interface{} // nil | NsPid | NsFd Alias string Statistics *LinkStatistics + Promisc int + Xdp *LinkXdp + EncapType string } // NewLinkAttrs returns LinkAttrs structure filled with default values @@ -69,6 +73,11 @@ type LinkStatistics struct { TxCompressed uint32 } +type LinkXdp struct { + Fd int + Attached bool +} + // Device links cannot be created via netlink. These links // are links created by udev like 'lo' and 'etho0' type Device struct { @@ -171,11 +180,13 @@ func (macvtap Macvtap) Type() string { } type TuntapMode uint16 +type TuntapFlag uint16 // Tuntap links created via /dev/tun/tap, but can be destroyed via netlink type Tuntap struct { LinkAttrs - Mode TuntapMode + Mode TuntapMode + Flags TuntapFlag } func (tuntap *Tuntap) Attrs() *LinkAttrs { @@ -251,6 +262,7 @@ type IPVlanMode uint16 const ( IPVLAN_MODE_L2 IPVlanMode = iota IPVLAN_MODE_L3 + IPVLAN_MODE_L3S IPVLAN_MODE_MAX ) diff --git a/Godeps/_workspace/src/github.com/vishvananda/netlink/link_linux.go b/Godeps/_workspace/src/github.com/vishvananda/netlink/link_linux.go index cfa5bf3e6c..ff45cde81a 100644 --- a/Godeps/_workspace/src/github.com/vishvananda/netlink/link_linux.go +++ b/Godeps/_workspace/src/github.com/vishvananda/netlink/link_linux.go @@ -16,8 +16,13 @@ import ( const SizeofLinkStats = 0x5c const ( - TUNTAP_MODE_TUN TuntapMode = syscall.IFF_TUN - TUNTAP_MODE_TAP TuntapMode = syscall.IFF_TAP + TUNTAP_MODE_TUN TuntapMode = syscall.IFF_TUN + TUNTAP_MODE_TAP TuntapMode = syscall.IFF_TAP + TUNTAP_DEFAULTS TuntapFlag = syscall.IFF_TUN_EXCL | syscall.IFF_ONE_QUEUE + TUNTAP_VNET_HDR TuntapFlag = syscall.IFF_VNET_HDR + TUNTAP_TUN_EXCL TuntapFlag = syscall.IFF_TUN_EXCL + TUNTAP_NO_PI TuntapFlag = syscall.IFF_NO_PI + TUNTAP_ONE_QUEUE TuntapFlag = syscall.IFF_ONE_QUEUE ) var native = nl.NativeEndian() @@ -50,6 +55,44 @@ func (h *Handle) ensureIndex(link *LinkAttrs) { } } +func (h *Handle) SetPromiscOn(link Link) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) + + msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) + msg.Change = syscall.IFF_PROMISC + msg.Flags = syscall.IFF_UP + msg.Index = int32(base.Index) + req.AddData(msg) + + _, err := req.Execute(syscall.NETLINK_ROUTE, 0) + return err +} + +func SetPromiscOn(link Link) error { + return pkgHandle.SetPromiscOn(link) +} + +func (h *Handle) SetPromiscOff(link Link) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) + + msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) + msg.Change = syscall.IFF_PROMISC + msg.Flags = 0 & ^syscall.IFF_UP + msg.Index = int32(base.Index) + req.AddData(msg) + + _, err := req.Execute(syscall.NETLINK_ROUTE, 0) + return err +} + +func SetPromiscOff(link Link) error { + return pkgHandle.SetPromiscOff(link) +} + // LinkSetUp enables the link device. // Equivalent to: `ip link set $link up` func LinkSetUp(link Link) error { @@ -255,6 +298,36 @@ func (h *Handle) LinkSetVfVlan(link Link, vf, vlan int) error { return err } +// LinkSetVfTxRate sets the tx rate of a vf for the link. +// Equivalent to: `ip link set $link vf $vf rate $rate` +func LinkSetVfTxRate(link Link, vf, rate int) error { + return pkgHandle.LinkSetVfTxRate(link, vf, rate) +} + +// LinkSetVfTxRate sets the tx rate of a vf for the link. +// Equivalent to: `ip link set $link vf $vf rate $rate` +func (h *Handle) LinkSetVfTxRate(link Link, vf, rate int) error { + base := link.Attrs() + h.ensureIndex(base) + req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) + + msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) + msg.Index = int32(base.Index) + req.AddData(msg) + + data := nl.NewRtAttr(nl.IFLA_VFINFO_LIST, nil) + info := nl.NewRtAttrChild(data, nl.IFLA_VF_INFO, nil) + vfmsg := nl.VfTxRate{ + Vf: uint32(vf), + Rate: uint32(rate), + } + nl.NewRtAttrChild(info, nl.IFLA_VF_TX_RATE, vfmsg.Serialize()) + req.AddData(data) + + _, err := req.Execute(syscall.NETLINK_ROUTE, 0) + return err +} + // LinkSetMaster sets the master of the link device. // Equivalent to: `ip link set $link master $master` func LinkSetMaster(link Link, master *Bridge) error { @@ -373,6 +446,23 @@ func (h *Handle) LinkSetNsFd(link Link, fd int) error { return err } +// LinkSetXdpFd adds a bpf function to the driver. The fd must be a bpf +// program loaded with bpf(type=BPF_PROG_TYPE_XDP) +func LinkSetXdpFd(link Link, fd int) error { + base := link.Attrs() + ensureIndex(base) + req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) + + msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) + msg.Index = int32(base.Index) + req.AddData(msg) + + addXdpAttrs(&LinkXdp{Fd: fd}, req) + + _, err := req.Execute(syscall.NETLINK_ROUTE, 0) + return err +} + func boolAttr(val bool) []byte { var v uint8 if val { @@ -552,9 +642,7 @@ func (h *Handle) LinkAdd(link Link) error { if tuntap, ok := link.(*Tuntap); ok { // TODO: support user // TODO: support group - // TODO: support non- one_queue - // TODO: support pi | vnet_hdr | multi_queue - // TODO: support non- exclusive + // TODO: multi_queue // TODO: support non- persistent if tuntap.Mode < syscall.IFF_TUN || tuntap.Mode > syscall.IFF_TAP { return fmt.Errorf("Tuntap.Mode %v unknown!", tuntap.Mode) @@ -565,10 +653,13 @@ func (h *Handle) LinkAdd(link Link) error { } defer file.Close() var req ifReq - req.Flags |= syscall.IFF_ONE_QUEUE - req.Flags |= syscall.IFF_TUN_EXCL - copy(req.Name[:15], base.Name) + if tuntap.Flags == 0 { + req.Flags = uint16(TUNTAP_DEFAULTS) + } else { + req.Flags = uint16(tuntap.Flags) + } req.Flags |= uint16(tuntap.Mode) + copy(req.Name[:15], base.Name) _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, file.Fd(), uintptr(syscall.TUNSETIFF), uintptr(unsafe.Pointer(&req))) if errno != 0 { return fmt.Errorf("Tuntap IOCTL TUNSETIFF failed, errno %v", errno) @@ -649,6 +740,10 @@ func (h *Handle) LinkAdd(link Link) error { req.AddData(attr) } + if base.Xdp != nil { + addXdpAttrs(base.Xdp, req) + } + linkInfo := nl.NewRtAttr(syscall.IFLA_LINKINFO, nil) nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_KIND, nl.NonZeroTerminated(link.Type())) @@ -871,7 +966,10 @@ func linkDeserialize(m []byte) (Link, error) { return nil, err } - base := LinkAttrs{Index: int(msg.Index), Flags: linkFlags(msg.Flags)} + base := LinkAttrs{Index: int(msg.Index), RawFlags: msg.Flags, Flags: linkFlags(msg.Flags), EncapType: msg.EncapType()} + if msg.Flags&syscall.IFF_PROMISC != 0 { + base.Promisc = 1 + } var link Link linkType := "" for _, attr := range attrs { @@ -958,6 +1056,12 @@ func linkDeserialize(m []byte) (Link, error) { base.Alias = string(attr.Value[:len(attr.Value)-1]) case syscall.IFLA_STATS: base.Statistics = parseLinkStats(attr.Value[:]) + case nl.IFLA_XDP: + xdp, err := parseLinkXdp(attr.Value[:]) + if err != nil { + return nil, err + } + base.Xdp = xdp } } // Links that don't have IFLA_INFO_KIND are hardware devices @@ -1389,3 +1493,28 @@ func parseGretapData(link Link, data []syscall.NetlinkRouteAttr) { func parseLinkStats(data []byte) *LinkStatistics { return (*LinkStatistics)(unsafe.Pointer(&data[0:SizeofLinkStats][0])) } + +func addXdpAttrs(xdp *LinkXdp, req *nl.NetlinkRequest) { + attrs := nl.NewRtAttr(nl.IFLA_XDP|syscall.NLA_F_NESTED, nil) + b := make([]byte, 4) + native.PutUint32(b, uint32(xdp.Fd)) + nl.NewRtAttrChild(attrs, nl.IFLA_XDP_FD, b) + req.AddData(attrs) +} + +func parseLinkXdp(data []byte) (*LinkXdp, error) { + attrs, err := nl.ParseRouteAttr(data) + if err != nil { + return nil, err + } + xdp := &LinkXdp{} + for _, attr := range attrs { + switch attr.Attr.Type { + case nl.IFLA_XDP_FD: + xdp.Fd = int(native.Uint32(attr.Value[0:4])) + case nl.IFLA_XDP_ATTACHED: + xdp.Attached = attr.Value[0] != 0 + } + } + return xdp, nil +} diff --git a/Godeps/_workspace/src/github.com/vishvananda/netlink/neigh_linux.go b/Godeps/_workspace/src/github.com/vishvananda/netlink/neigh_linux.go index 9b6cd2c256..f069db2573 100644 --- a/Godeps/_workspace/src/github.com/vishvananda/netlink/neigh_linux.go +++ b/Godeps/_workspace/src/github.com/vishvananda/netlink/neigh_linux.go @@ -151,8 +151,10 @@ func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error { dstData := nl.NewRtAttr(NDA_DST, ipData) req.AddData(dstData) - hwData := nl.NewRtAttr(NDA_LLADDR, []byte(neigh.HardwareAddr)) - req.AddData(hwData) + if neigh.Flags != NTF_PROXY || neigh.HardwareAddr != nil { + hwData := nl.NewRtAttr(NDA_LLADDR, []byte(neigh.HardwareAddr)) + req.AddData(hwData) + } _, err := req.Execute(syscall.NETLINK_ROUTE, 0) return err @@ -165,14 +167,33 @@ func NeighList(linkIndex, family int) ([]Neigh, error) { return pkgHandle.NeighList(linkIndex, family) } +// NeighProxyList gets a list of neighbor proxies in the system. +// Equivalent to: `ip neighbor show proxy`. +// The list can be filtered by link and ip family. +func NeighProxyList(linkIndex, family int) ([]Neigh, error) { + return pkgHandle.NeighProxyList(linkIndex, family) +} + // NeighList gets a list of IP-MAC mappings in the system (ARP table). // Equivalent to: `ip neighbor show`. // The list can be filtered by link and ip family. func (h *Handle) NeighList(linkIndex, family int) ([]Neigh, error) { + return h.neighList(linkIndex, family, 0) +} + +// NeighProxyList gets a list of neighbor proxies in the system. +// Equivalent to: `ip neighbor show proxy`. +// The list can be filtered by link, ip family. +func (h *Handle) NeighProxyList(linkIndex, family int) ([]Neigh, error) { + return h.neighList(linkIndex, family, NTF_PROXY) +} + +func (h *Handle) neighList(linkIndex, family, flags int) ([]Neigh, error) { req := h.newNetlinkRequest(syscall.RTM_GETNEIGH, syscall.NLM_F_DUMP) msg := Ndmsg{ Family: uint8(family), Index: uint32(linkIndex), + Flags: uint8(flags), } req.AddData(&msg) diff --git a/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/link_linux.go b/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/link_linux.go index b7f50646d2..115f60bb3b 100644 --- a/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/link_linux.go +++ b/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/link_linux.go @@ -1,13 +1,35 @@ package nl import ( + "syscall" "unsafe" ) const ( DEFAULT_CHANGE = 0xFFFFFFFF // doesn't exist in syscall - IFLA_VFINFO_LIST = 0x16 + IFLA_VFINFO_LIST = syscall.IFLA_IFALIAS + 1 + iota + IFLA_STATS64 + IFLA_VF_PORTS + IFLA_PORT_SELF + IFLA_AF_SPEC + IFLA_GROUP + IFLA_NET_NS_FD + IFLA_EXT_MASK + IFLA_PROMISCUITY + IFLA_NUM_TX_QUEUES + IFLA_NUM_RX_QUEUES + IFLA_CARRIER + IFLA_PHYS_PORT_ID + IFLA_CARRIER_CHANGES + IFLA_PHYS_SWITCH_ID + IFLA_LINK_NETNSID + IFLA_PHYS_PORT_NAME + IFLA_PROTO_DOWN + IFLA_GSO_MAX_SEGS + IFLA_GSO_MAX_SIZE + IFLA_PAD + IFLA_XDP ) const ( @@ -89,11 +111,6 @@ const ( IFLA_IPVLAN_MAX = IFLA_IPVLAN_MODE ) -const ( - // not defined in syscall - IFLA_NET_NS_FD = 28 -) - const ( IFLA_MACVLAN_UNSPEC = iota IFLA_MACVLAN_MODE @@ -394,3 +411,10 @@ func DeserializeVfRssQueryEn(b []byte) *VfRssQueryEn { func (msg *VfRssQueryEn) Serialize() []byte { return (*(*[SizeofVfRssQueryEn]byte)(unsafe.Pointer(msg)))[:] } + +const ( + IFLA_XDP_UNSPEC = iota + IFLA_XDP_FD /* fd of xdp program to attach, or -1 to remove */ + IFLA_XDP_ATTACHED /* read-only bool indicating if prog is attached */ + IFLA_XDP_MAX = IFLA_XDP_ATTACHED +) diff --git a/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/nl_linux.go b/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/nl_linux.go index 17683a7556..d46fff281f 100644 --- a/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/nl_linux.go +++ b/Godeps/_workspace/src/github.com/vishvananda/netlink/nl/nl_linux.go @@ -100,6 +100,147 @@ func (msg *IfInfomsg) Len() int { return syscall.SizeofIfInfomsg } +func (msg *IfInfomsg) EncapType() string { + switch msg.Type { + case 0: + return "generic" + case syscall.ARPHRD_ETHER: + return "ether" + case syscall.ARPHRD_EETHER: + return "eether" + case syscall.ARPHRD_AX25: + return "ax25" + case syscall.ARPHRD_PRONET: + return "pronet" + case syscall.ARPHRD_CHAOS: + return "chaos" + case syscall.ARPHRD_IEEE802: + return "ieee802" + case syscall.ARPHRD_ARCNET: + return "arcnet" + case syscall.ARPHRD_APPLETLK: + return "atalk" + case syscall.ARPHRD_DLCI: + return "dlci" + case syscall.ARPHRD_ATM: + return "atm" + case syscall.ARPHRD_METRICOM: + return "metricom" + case syscall.ARPHRD_IEEE1394: + return "ieee1394" + case syscall.ARPHRD_INFINIBAND: + return "infiniband" + case syscall.ARPHRD_SLIP: + return "slip" + case syscall.ARPHRD_CSLIP: + return "cslip" + case syscall.ARPHRD_SLIP6: + return "slip6" + case syscall.ARPHRD_CSLIP6: + return "cslip6" + case syscall.ARPHRD_RSRVD: + return "rsrvd" + case syscall.ARPHRD_ADAPT: + return "adapt" + case syscall.ARPHRD_ROSE: + return "rose" + case syscall.ARPHRD_X25: + return "x25" + case syscall.ARPHRD_HWX25: + return "hwx25" + case syscall.ARPHRD_PPP: + return "ppp" + case syscall.ARPHRD_HDLC: + return "hdlc" + case syscall.ARPHRD_LAPB: + return "lapb" + case syscall.ARPHRD_DDCMP: + return "ddcmp" + case syscall.ARPHRD_RAWHDLC: + return "rawhdlc" + case syscall.ARPHRD_TUNNEL: + return "ipip" + case syscall.ARPHRD_TUNNEL6: + return "tunnel6" + case syscall.ARPHRD_FRAD: + return "frad" + case syscall.ARPHRD_SKIP: + return "skip" + case syscall.ARPHRD_LOOPBACK: + return "loopback" + case syscall.ARPHRD_LOCALTLK: + return "ltalk" + case syscall.ARPHRD_FDDI: + return "fddi" + case syscall.ARPHRD_BIF: + return "bif" + case syscall.ARPHRD_SIT: + return "sit" + case syscall.ARPHRD_IPDDP: + return "ip/ddp" + case syscall.ARPHRD_IPGRE: + return "gre" + case syscall.ARPHRD_PIMREG: + return "pimreg" + case syscall.ARPHRD_HIPPI: + return "hippi" + case syscall.ARPHRD_ASH: + return "ash" + case syscall.ARPHRD_ECONET: + return "econet" + case syscall.ARPHRD_IRDA: + return "irda" + case syscall.ARPHRD_FCPP: + return "fcpp" + case syscall.ARPHRD_FCAL: + return "fcal" + case syscall.ARPHRD_FCPL: + return "fcpl" + case syscall.ARPHRD_FCFABRIC: + return "fcfb0" + case syscall.ARPHRD_FCFABRIC + 1: + return "fcfb1" + case syscall.ARPHRD_FCFABRIC + 2: + return "fcfb2" + case syscall.ARPHRD_FCFABRIC + 3: + return "fcfb3" + case syscall.ARPHRD_FCFABRIC + 4: + return "fcfb4" + case syscall.ARPHRD_FCFABRIC + 5: + return "fcfb5" + case syscall.ARPHRD_FCFABRIC + 6: + return "fcfb6" + case syscall.ARPHRD_FCFABRIC + 7: + return "fcfb7" + case syscall.ARPHRD_FCFABRIC + 8: + return "fcfb8" + case syscall.ARPHRD_FCFABRIC + 9: + return "fcfb9" + case syscall.ARPHRD_FCFABRIC + 10: + return "fcfb10" + case syscall.ARPHRD_FCFABRIC + 11: + return "fcfb11" + case syscall.ARPHRD_FCFABRIC + 12: + return "fcfb12" + case syscall.ARPHRD_IEEE802_TR: + return "tr" + case syscall.ARPHRD_IEEE80211: + return "ieee802.11" + case syscall.ARPHRD_IEEE80211_PRISM: + return "ieee802.11/prism" + case syscall.ARPHRD_IEEE80211_RADIOTAP: + return "ieee802.11/radiotap" + case syscall.ARPHRD_IEEE802154: + return "ieee802.15.4" + + case 65534: + return "none" + case 65535: + return "void" + } + return fmt.Sprintf("unknown%d", msg.Type) +} + func rtaAlignOf(attrlen int) int { return (attrlen + syscall.RTA_ALIGNTO - 1) & ^(syscall.RTA_ALIGNTO - 1) } diff --git a/Godeps/_workspace/src/github.com/vishvananda/netlink/route_linux.go b/Godeps/_workspace/src/github.com/vishvananda/netlink/route_linux.go index 6ba3ea1264..b749ddb2c7 100644 --- a/Godeps/_workspace/src/github.com/vishvananda/netlink/route_linux.go +++ b/Godeps/_workspace/src/github.com/vishvananda/netlink/route_linux.go @@ -153,7 +153,7 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg } else { gw = nl.NewRtAttr(syscall.RTA_GATEWAY, []byte(nh.Gw.To16())) } - gwData := gw.Serialize() + gwData = gw.Serialize() rtnh.Len += uint16(len(gwData)) } buf = append(buf, rtnh.Serialize()...) diff --git a/Godeps/_workspace/src/github.com/vishvananda/netlink/rule_linux.go b/Godeps/_workspace/src/github.com/vishvananda/netlink/rule_linux.go index 58fac557c0..f9cdc855f1 100644 --- a/Godeps/_workspace/src/github.com/vishvananda/netlink/rule_linux.go +++ b/Godeps/_workspace/src/github.com/vishvananda/netlink/rule_linux.go @@ -82,41 +82,46 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error { req.AddData(rtAttrs[i]) } - var ( - b = make([]byte, 4) - native = nl.NativeEndian() - ) + native := nl.NativeEndian() if rule.Priority >= 0 { + b := make([]byte, 4) native.PutUint32(b, uint32(rule.Priority)) req.AddData(nl.NewRtAttr(nl.FRA_PRIORITY, b)) } if rule.Mark >= 0 { + b := make([]byte, 4) native.PutUint32(b, uint32(rule.Mark)) req.AddData(nl.NewRtAttr(nl.FRA_FWMARK, b)) } if rule.Mask >= 0 { + b := make([]byte, 4) native.PutUint32(b, uint32(rule.Mask)) req.AddData(nl.NewRtAttr(nl.FRA_FWMASK, b)) } if rule.Flow >= 0 { + b := make([]byte, 4) native.PutUint32(b, uint32(rule.Flow)) req.AddData(nl.NewRtAttr(nl.FRA_FLOW, b)) } if rule.TunID > 0 { + b := make([]byte, 4) native.PutUint32(b, uint32(rule.TunID)) req.AddData(nl.NewRtAttr(nl.FRA_TUN_ID, b)) } if rule.Table >= 256 { + b := make([]byte, 4) native.PutUint32(b, uint32(rule.Table)) req.AddData(nl.NewRtAttr(nl.FRA_TABLE, b)) } if msg.Table > 0 { if rule.SuppressPrefixlen >= 0 { + b := make([]byte, 4) native.PutUint32(b, uint32(rule.SuppressPrefixlen)) req.AddData(nl.NewRtAttr(nl.FRA_SUPPRESS_PREFIXLEN, b)) } if rule.SuppressIfgroup >= 0 { + b := make([]byte, 4) native.PutUint32(b, uint32(rule.SuppressIfgroup)) req.AddData(nl.NewRtAttr(nl.FRA_SUPPRESS_IFGROUP, b)) } @@ -129,6 +134,7 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error { } if rule.Goto >= 0 { msg.Type = nl.FR_ACT_NOP + b := make([]byte, 4) native.PutUint32(b, uint32(rule.Goto)) req.AddData(nl.NewRtAttr(nl.FRA_GOTO, b)) } diff --git a/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_state_linux.go b/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_state_linux.go index b100f71bd1..7b0b2e7585 100644 --- a/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_state_linux.go +++ b/Godeps/_workspace/src/github.com/vishvananda/netlink/xfrm_state_linux.go @@ -213,7 +213,7 @@ func (h *Handle) xfrmStateGetOrDelete(state *XfrmState, nlProto int) (*XfrmState req.AddData(out) } if state.Src != nil { - out := nl.NewRtAttr(nl.XFRMA_SRCADDR, state.Src) + out := nl.NewRtAttr(nl.XFRMA_SRCADDR, state.Src.To16()) req.AddData(out) } diff --git a/agent.go b/agent.go index 4c8980b2e1..f589d7bee2 100644 --- a/agent.go +++ b/agent.go @@ -328,22 +328,26 @@ func (c *controller) agentDriverNotify(d driverapi.Driver) { } func (c *controller) agentClose() { - if c.agent == nil { + // Acquire current agent instance and reset its pointer + // then run closing functions + c.Lock() + agent := c.agent + c.agent = nil + c.Unlock() + + if agent == nil { return } - for _, cancelFuncs := range c.agent.driverCancelFuncs { + for _, cancelFuncs := range agent.driverCancelFuncs { for _, cancel := range cancelFuncs { cancel() } } - c.agent.epTblCancel() - c.agent.networkDB.Close() + agent.epTblCancel() - c.Lock() - c.agent = nil - c.Unlock() + agent.networkDB.Close() } func (n *network) isClusterEligible() bool { diff --git a/api/api_test.go b/api/api_test.go index b1241188aa..8a81094599 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -228,9 +228,7 @@ func TestCreateDeleteNetwork(t *testing.T) { dops := map[string]string{ bridge.BridgeName: "abc", } - nops := map[string]string{ - netlabel.EnableIPv6: "true", - } + nops := map[string]string{} nc := networkCreate{Name: "network_1", NetworkType: bridgeNetType, DriverOpts: dops, NetworkOpts: nops} goodBody, err := json.Marshal(nc) if err != nil { @@ -1815,9 +1813,7 @@ func TestEndToEnd(t *testing.T) { bridge.BridgeName: "cdef", netlabel.DriverMTU: "1460", } - nops := map[string]string{ - netlabel.EnableIPv6: "true", - } + nops := map[string]string{} // Create network nc := networkCreate{Name: "network-fiftyfive", NetworkType: bridgeNetType, DriverOpts: dops, NetworkOpts: nops} diff --git a/client/client.go b/client/client.go index c5713b01b3..e240f8f6f4 100644 --- a/client/client.go +++ b/client/client.go @@ -65,7 +65,7 @@ func (cli *NetworkCli) Cmd(chain string, args ...string) error { if len(args) > 0 { method, exists := cli.getMethod(args[0]) if !exists { - return fmt.Errorf("%s: '%s' is not a %s command. See '%s --help'.\n", chain, args[0], chain, chain) + return fmt.Errorf("%s: '%s' is not a %s command. See '%s --help'", chain, args[0], chain, chain) } return method(chain, args[1:]...) } diff --git a/cmd/dnet/dnet.go b/cmd/dnet/dnet.go index aefc4f2db0..834991a030 100644 --- a/cmd/dnet/dnet.go +++ b/cmd/dnet/dnet.go @@ -245,7 +245,7 @@ type NetworkOrchestration struct { func (d *dnetConnection) dnetDaemon(cfgFile string) error { if err := startTestDriver(); err != nil { - return fmt.Errorf("failed to start test driver: %v\n", err) + return fmt.Errorf("failed to start test driver: %v", err) } cfg, err := d.parseConfig(cfgFile) diff --git a/datastore/datastore.go b/datastore/datastore.go index b045eab28a..3d5911680d 100644 --- a/datastore/datastore.go +++ b/datastore/datastore.go @@ -6,6 +6,7 @@ import ( "reflect" "strings" "sync" + "time" "github.com/docker/libkv" "github.com/docker/libkv/store" @@ -134,7 +135,8 @@ func makeDefaultScopes() map[string]*ScopeCfg { Provider: string(store.BOLTDB), Address: defaultPrefix + "/local-kv.db", Config: &store.Config{ - Bucket: "libnetwork", + Bucket: "libnetwork", + ConnectionTimeout: time.Minute, }, }, } diff --git a/default_gateway.go b/default_gateway.go index 2f2e284ff1..b7ba0fd027 100644 --- a/default_gateway.go +++ b/default_gateway.go @@ -107,7 +107,7 @@ func (sb *sandbox) needDefaultGW() bool { return false } for _, r := range ep.StaticRoutes() { - if r.Destination.String() == "0.0.0.0/0" { + if r.Destination != nil && r.Destination.String() == "0.0.0.0/0" { return false } } diff --git a/drivers/overlay/ov_endpoint.go b/drivers/overlay/ov_endpoint.go index 7dcc530119..a87a2292aa 100644 --- a/drivers/overlay/ov_endpoint.go +++ b/drivers/overlay/ov_endpoint.go @@ -77,7 +77,7 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, } if s := n.getSubnetforIP(ep.addr); s == nil { - return fmt.Errorf("no matching subnet for IP %q in network %q\n", ep.addr, nid) + return fmt.Errorf("no matching subnet for IP %q in network %q", ep.addr, nid) } if ep.mac == nil { diff --git a/drivers/overlay/ov_network.go b/drivers/overlay/ov_network.go index b5af0f4b04..4e08835aad 100644 --- a/drivers/overlay/ov_network.go +++ b/drivers/overlay/ov_network.go @@ -308,6 +308,11 @@ func populateVNITbl() { } defer nlh.Delete() + err = nlh.SetSocketTimeout(soTimeout) + if err != nil { + logrus.Warnf("Failed to set the timeout on the netlink handle sockets for vni table population: %v", err) + } + links, err := nlh.LinkList() if err != nil { logrus.Errorf("Failed to list interfaces during vni population for ns %s: %v", path, err) diff --git a/drivers/overlay/ov_utils.go b/drivers/overlay/ov_utils.go index a702e760af..8a01914fa4 100644 --- a/drivers/overlay/ov_utils.go +++ b/drivers/overlay/ov_utils.go @@ -13,6 +13,8 @@ import ( "github.com/vishvananda/netns" ) +var soTimeout = ns.NetlinkSocketsTimeout + func validateID(nid, eid string) error { if nid == "" { return fmt.Errorf("invalid network id") @@ -134,6 +136,10 @@ func deleteVxlanByVNI(path string, vni uint32) error { return fmt.Errorf("failed to get netlink handle for ns %s: %v", path, err) } defer nlh.Delete() + err = nlh.SetSocketTimeout(soTimeout) + if err != nil { + logrus.Warnf("Failed to set the timeout on the netlink handle sockets for vxlan deletion: %v", err) + } } links, err := nlh.LinkList() diff --git a/drivers/overlay/peerdb.go b/drivers/overlay/peerdb.go index 517909a816..f44b3aef67 100644 --- a/drivers/overlay/peerdb.go +++ b/drivers/overlay/peerdb.go @@ -277,7 +277,7 @@ func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask, s := n.getSubnetforIP(IP) if s == nil { - return fmt.Errorf("couldn't find the subnet %q in network %q\n", IP.String(), n.id) + return fmt.Errorf("couldn't find the subnet %q in network %q", IP.String(), n.id) } if err := n.obtainVxlanID(s); err != nil { diff --git a/endpoint_info.go b/endpoint_info.go index 1042ddaa8f..97fa64f94b 100644 --- a/endpoint_info.go +++ b/endpoint_info.go @@ -114,12 +114,12 @@ func (epi *endpointInterface) UnmarshalJSON(b []byte) error { } } if v, ok := epMap["llAddrs"]; ok { - list := v.([]string) + list := v.([]interface{}) epi.llAddrs = make([]*net.IPNet, 0, len(list)) for _, llS := range list { - ll, err := types.ParseCIDR(llS) + ll, err := types.ParseCIDR(llS.(string)) if err != nil { - return types.InternalErrorf("failed to decode endpoint interface link-local address (%s) after json unmarshal: %v", llS, err) + return types.InternalErrorf("failed to decode endpoint interface link-local address (%v) after json unmarshal: %v", llS, err) } epi.llAddrs = append(epi.llAddrs, ll) } diff --git a/ipam/allocator.go b/ipam/allocator.go index c059d447d7..de396c7d06 100644 --- a/ipam/allocator.go +++ b/ipam/allocator.go @@ -406,7 +406,7 @@ func (a *Allocator) getPredefinedPool(as string, ipV6 bool) (*net.IPNet, error) } } - return nil, types.NotFoundErrorf("could not find an available predefined network") + return nil, types.NotFoundErrorf("could not find an available, non-overlapping IPv%d address pool among the defaults to assign to the network", v) } // RequestAddress returns an address from the specified pool ID diff --git a/iptables/iptables.go b/iptables/iptables.go index f6ddaed775..113db4c04c 100644 --- a/iptables/iptables.go +++ b/iptables/iptables.go @@ -123,7 +123,7 @@ func NewChain(name string, table Table, hairpinMode bool) (*ChainInfo, error) { // ProgramChain is used to add rules to a chain func ProgramChain(c *ChainInfo, bridgeName string, hairpinMode, enable bool) error { if c.Name == "" { - return fmt.Errorf("Could not program chain, missing chain name.") + return fmt.Errorf("Could not program chain, missing chain name") } switch c.Table { @@ -159,7 +159,7 @@ func ProgramChain(c *ChainInfo, bridgeName string, hairpinMode, enable bool) err } case Filter: if bridgeName == "" { - return fmt.Errorf("Could not program chain %s/%s, missing bridge name.", + return fmt.Errorf("Could not program chain %s/%s, missing bridge name", c.Table, c.Name) } link := []string{ diff --git a/libnetwork_internal_test.go b/libnetwork_internal_test.go index 9eb7f6bab5..78c6bca9b7 100644 --- a/libnetwork_internal_test.go +++ b/libnetwork_internal_test.go @@ -172,6 +172,12 @@ func TestEndpointMarshalling(t *testing.T) { } nw6.IP = ip + var lla []*net.IPNet + for _, nw := range []string{"169.254.0.1/16", "169.254.1.1/16", "169.254.2.2/16"} { + ll, _ := types.ParseCIDR(nw) + lla = append(lla, ll) + } + e := &endpoint{ name: "Bau", id: "efghijklmno", @@ -188,6 +194,7 @@ func TestEndpointMarshalling(t *testing.T) { dstPrefix: "eth", v4PoolID: "poolpool", v6PoolID: "poolv6", + llAddrs: lla, }, } @@ -215,7 +222,7 @@ func compareEndpointInterface(a, b *endpointInterface) bool { return false } return a.srcName == b.srcName && a.dstPrefix == b.dstPrefix && a.v4PoolID == b.v4PoolID && a.v6PoolID == b.v6PoolID && - types.CompareIPNet(a.addr, b.addr) && types.CompareIPNet(a.addrv6, b.addrv6) + types.CompareIPNet(a.addr, b.addr) && types.CompareIPNet(a.addrv6, b.addrv6) && compareNwLists(a.llAddrs, b.llAddrs) } func compareIpamConfList(listA, listB []*IpamConf) bool { @@ -282,6 +289,18 @@ func compareAddresses(a, b map[string]*net.IPNet) bool { return true } +func compareNwLists(a, b []*net.IPNet) bool { + if len(a) != len(b) { + return false + } + for k := range a { + if !types.CompareIPNet(a[k], b[k]) { + return false + } + } + return true +} + func TestAuxAddresses(t *testing.T) { c, err := New() if err != nil { diff --git a/network.go b/network.go index 9f5a3088be..25629d1b9c 100644 --- a/network.go +++ b/network.go @@ -1254,9 +1254,6 @@ func (n *network) ipamAllocateVersion(ipVer int, ipam ipamapi.Ipam) error { } if len(*cfgList) == 0 { - if ipVer == 6 { - return nil - } *cfgList = []*IpamConf{{}} } diff --git a/ns/init_linux.go b/ns/init_linux.go index 78529c7fbe..208b9d2f30 100644 --- a/ns/init_linux.go +++ b/ns/init_linux.go @@ -7,6 +7,7 @@ import ( "strings" "sync" "syscall" + "time" log "github.com/Sirupsen/logrus" "github.com/vishvananda/netlink" @@ -17,6 +18,8 @@ var ( initNs netns.NsHandle initNl *netlink.Handle initOnce sync.Once + // NetlinkSocketsTimeout represents the default timeout duration for the sockets + NetlinkSocketsTimeout = 3 * time.Second ) // Init initializes a new network namespace @@ -30,6 +33,10 @@ func Init() { if err != nil { log.Errorf("could not create netlink handle on initial namespace: %v", err) } + err = initNl.SetSocketTimeout(NetlinkSocketsTimeout) + if err != nil { + log.Warnf("Failed to set the timeout on the default netlink handle sockets: %v", err) + } } // SetNamespace sets the initial namespace handler diff --git a/osl/namespace_linux.go b/osl/namespace_linux.go index d3f88191f0..d7c51b9f83 100644 --- a/osl/namespace_linux.go +++ b/osl/namespace_linux.go @@ -211,6 +211,11 @@ func NewSandbox(key string, osCreate, isRestore bool) (Sandbox, error) { return nil, fmt.Errorf("failed to create a netlink handle: %v", err) } + err = n.nlHandle.SetSocketTimeout(ns.NetlinkSocketsTimeout) + if err != nil { + log.Warnf("Failed to set the timeout on the sandbox netlink handle sockets: %v", err) + } + if err = n.loopbackUp(); err != nil { n.nlHandle.Delete() return nil, err @@ -253,6 +258,11 @@ func GetSandboxForExternalKey(basePath string, key string) (Sandbox, error) { return nil, fmt.Errorf("failed to create a netlink handle: %v", err) } + err = n.nlHandle.SetSocketTimeout(ns.NetlinkSocketsTimeout) + if err != nil { + log.Warnf("Failed to set the timeout on the sandbox netlink handle sockets: %v", err) + } + if err = n.loopbackUp(); err != nil { n.nlHandle.Delete() return nil, err diff --git a/osl/neigh_linux.go b/osl/neigh_linux.go index a7669a111b..673522ad63 100644 --- a/osl/neigh_linux.go +++ b/osl/neigh_linux.go @@ -80,6 +80,7 @@ func (n *networkNamespace) DeleteNeighbor(dstIP net.IP, dstMac net.HardwareAddr, for i, nh := range n.neighbors { if nh.dstIP.Equal(dstIP) && bytes.Equal(nh.dstMac, dstMac) { n.neighbors = append(n.neighbors[:i], n.neighbors[i+1:]...) + break } } n.Unlock() diff --git a/resolver.go b/resolver.go index 85b87ffb18..4daf8d867b 100644 --- a/resolver.go +++ b/resolver.go @@ -63,6 +63,7 @@ type resolver struct { count int32 tStamp time.Time queryLock sync.Mutex + startCh chan struct{} } func init() { @@ -72,8 +73,9 @@ func init() { // NewResolver creates a new instance of the Resolver func NewResolver(sb *sandbox) Resolver { return &resolver{ - sb: sb, - err: fmt.Errorf("setup not done yet"), + sb: sb, + err: fmt.Errorf("setup not done yet"), + startCh: make(chan struct{}, 1), } } @@ -107,6 +109,9 @@ func (r *resolver) SetupFunc() func() { } func (r *resolver) Start() error { + r.startCh <- struct{}{} + defer func() { <-r.startCh }() + // make sure the resolver has been setup before starting if r.err != nil { return r.err @@ -131,6 +136,9 @@ func (r *resolver) Start() error { } func (r *resolver) Stop() { + r.startCh <- struct{}{} + defer func() { <-r.startCh }() + if r.server != nil { r.server.Shutdown() } diff --git a/sandbox.go b/sandbox.go index 8ab73429b8..1df8b490da 100644 --- a/sandbox.go +++ b/sandbox.go @@ -437,7 +437,13 @@ func (sb *sandbox) ResolveIP(ip string) string { } func (sb *sandbox) execFunc(f func()) error { - return sb.osSbox.InvokeFunc(f) + sb.Lock() + osSbox := sb.osSbox + sb.Unlock() + if osSbox != nil { + return osSbox.InvokeFunc(f) + } + return fmt.Errorf("osl sandbox unavailable in ExecFunc for %v", sb.ContainerID()) } func (sb *sandbox) ResolveService(name string) ([]*net.SRV, []net.IP, error) {