瀏覽代碼

Merge pull request #39054 from thaJeztah/bump_libnetwork2

bump libnetwork. vishvananda/netlink 1.0, vishvananda/netns
Tibor Vass 6 年之前
父節點
當前提交
9e6f83bee1
共有 58 個文件被更改,包括 2004 次插入766 次删除
  1. 1 1
      hack/dockerfile/install/proxy.installer
  2. 3 3
      vendor.conf
  3. 12 12
      vendor/github.com/docker/libnetwork/drivers/overlay/ov_network.go
  4. 32 2
      vendor/github.com/docker/libnetwork/firewall_linux.go
  5. 5 6
      vendor/github.com/docker/libnetwork/ipvs/ipvs.go
  6. 7 2
      vendor/github.com/docker/libnetwork/network.go
  7. 1 1
      vendor/github.com/docker/libnetwork/resolver.go
  8. 51 47
      vendor/github.com/docker/libnetwork/vendor.conf
  9. 1 0
      vendor/github.com/vishvananda/netlink/README.md
  10. 66 28
      vendor/github.com/vishvananda/netlink/addr_linux.go
  11. 37 46
      vendor/github.com/vishvananda/netlink/bpf_linux.go
  12. 12 12
      vendor/github.com/vishvananda/netlink/bridge_linux.go
  13. 13 12
      vendor/github.com/vishvananda/netlink/class_linux.go
  14. 7 7
      vendor/github.com/vishvananda/netlink/conntrack_linux.go
  15. 16 1
      vendor/github.com/vishvananda/netlink/filter.go
  16. 47 9
      vendor/github.com/vishvananda/netlink/filter_linux.go
  17. 21 0
      vendor/github.com/vishvananda/netlink/fou.go
  18. 215 0
      vendor/github.com/vishvananda/netlink/fou_linux.go
  19. 15 0
      vendor/github.com/vishvananda/netlink/fou_unspecified.go
  20. 4 3
      vendor/github.com/vishvananda/netlink/genetlink_linux.go
  21. 8 7
      vendor/github.com/vishvananda/netlink/gtp_linux.go
  22. 9 9
      vendor/github.com/vishvananda/netlink/handle_linux.go
  23. 36 0
      vendor/github.com/vishvananda/netlink/handle_unspecified.go
  24. 98 0
      vendor/github.com/vishvananda/netlink/ioctl_linux.go
  25. 85 38
      vendor/github.com/vishvananda/netlink/link.go
  26. 309 165
      vendor/github.com/vishvananda/netlink/link_linux.go
  27. 2 0
      vendor/github.com/vishvananda/netlink/neigh.go
  28. 24 10
      vendor/github.com/vishvananda/netlink/neigh_linux.go
  29. 7 6
      vendor/github.com/vishvananda/netlink/nl/addr_linux.go
  30. 17 25
      vendor/github.com/vishvananda/netlink/nl/link_linux.go
  31. 121 115
      vendor/github.com/vishvananda/netlink/nl/nl_linux.go
  32. 20 19
      vendor/github.com/vishvananda/netlink/nl/route_linux.go
  33. 111 0
      vendor/github.com/vishvananda/netlink/nl/seg6_linux.go
  34. 10 0
      vendor/github.com/vishvananda/netlink/nl/syscall.go
  35. 35 0
      vendor/github.com/vishvananda/netlink/nl/tc_linux.go
  36. 5 4
      vendor/github.com/vishvananda/netlink/protinfo_linux.go
  37. 60 0
      vendor/github.com/vishvananda/netlink/qdisc.go
  38. 129 11
      vendor/github.com/vishvananda/netlink/qdisc_linux.go
  39. 2 0
      vendor/github.com/vishvananda/netlink/route.go
  40. 190 55
      vendor/github.com/vishvananda/netlink/route_linux.go
  41. 1 0
      vendor/github.com/vishvananda/netlink/rule.go
  42. 30 20
      vendor/github.com/vishvananda/netlink/rule_linux.go
  43. 4 4
      vendor/github.com/vishvananda/netlink/socket_linux.go
  44. 7 6
      vendor/github.com/vishvananda/netlink/xfrm.go
  45. 3 4
      vendor/github.com/vishvananda/netlink/xfrm_monitor_linux.go
  46. 9 10
      vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go
  47. 24 3
      vendor/github.com/vishvananda/netlink/xfrm_state.go
  48. 26 13
      vendor/github.com/vishvananda/netlink/xfrm_state_linux.go
  49. 4 2
      vendor/github.com/vishvananda/netns/README.md
  50. 15 2
      vendor/github.com/vishvananda/netns/netns.go
  51. 29 4
      vendor/github.com/vishvananda/netns/netns_linux.go
  52. 0 7
      vendor/github.com/vishvananda/netns/netns_linux_386.go
  53. 0 7
      vendor/github.com/vishvananda/netns/netns_linux_amd64.go
  54. 0 7
      vendor/github.com/vishvananda/netns/netns_linux_arm.go
  55. 0 7
      vendor/github.com/vishvananda/netns/netns_linux_arm64.go
  56. 0 7
      vendor/github.com/vishvananda/netns/netns_linux_ppc64le.go
  57. 0 7
      vendor/github.com/vishvananda/netns/netns_linux_s390x.go
  58. 8 0
      vendor/github.com/vishvananda/netns/netns_unspecified.go

+ 1 - 1
hack/dockerfile/install/proxy.installer

@@ -3,7 +3,7 @@
 # LIBNETWORK_COMMIT is used to build the docker-userland-proxy binary. When
 # updating the binary version, consider updating github.com/docker/libnetwork
 # in vendor.conf accordingly
-LIBNETWORK_COMMIT=fc5a7d91d54cc98f64fc28f9e288b46a0bee756c
+LIBNETWORK_COMMIT=62a13ae87c6058bdc000fcccbf7e0f9f7525e2a9
 
 install_proxy() {
 	case "$1" in

+ 3 - 3
vendor.conf

@@ -39,7 +39,7 @@ github.com/gofrs/flock                              7f43ea2e6a643ad441fc12d0ecc0
 # libnetwork
 
 # When updating, also update LIBNETWORK_COMMIT in hack/dockerfile/install/proxy.installer accordingly
-github.com/docker/libnetwork                        fc5a7d91d54cc98f64fc28f9e288b46a0bee756c
+github.com/docker/libnetwork                        62a13ae87c6058bdc000fcccbf7e0f9f7525e2a9
 github.com/docker/go-events                         9461782956ad83b30282bf90e31fa6a70c255ba9
 github.com/armon/go-radix                           e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
 github.com/armon/go-metrics                         eb0af217e5e9747e41dd5303755356b62d28e3ec
@@ -50,8 +50,8 @@ github.com/hashicorp/go-sockaddr                    6d291a969b86c4b633730bfc6b8b
 github.com/hashicorp/go-multierror                  fcdddc395df1ddf4247c69bd436e84cfa0733f7e
 github.com/hashicorp/serf                           598c54895cc5a7b1a24a398d635e8c0ea0959870
 github.com/docker/libkv                             458977154600b9f23984d9f4b82e79570b5ae12b
-github.com/vishvananda/netns                        604eaf189ee867d8c147fafc28def2394e878d25
-github.com/vishvananda/netlink                      b2de5d10e38ecce8607e6b438b6d174f389a004e
+github.com/vishvananda/netns                        13995c7128ccc8e51e9a6bd2b551020a27180abd
+github.com/vishvananda/netlink                      a2ad57a690f3caf3015351d2d6e1c0b95c349752 # v1.0.0
 
 # When updating, consider updating TOMLV_COMMIT in hack/dockerfile/install/tomlv.installer accordingly
 github.com/BurntSushi/toml                          3012a1dbe2e4bd1391d42b32f0577cb7bbc7f005 # v0.3.1

+ 12 - 12
vendor/github.com/docker/libnetwork/drivers/overlay/ov_network.go

@@ -12,7 +12,6 @@ import (
 	"strconv"
 	"strings"
 	"sync"
-	"syscall"
 
 	"github.com/docker/docker/pkg/reexec"
 	"github.com/docker/libnetwork/datastore"
@@ -27,6 +26,7 @@ import (
 	"github.com/vishvananda/netlink"
 	"github.com/vishvananda/netlink/nl"
 	"github.com/vishvananda/netns"
+	"golang.org/x/sys/unix"
 )
 
 var (
@@ -97,18 +97,18 @@ func setDefaultVlan() {
 	}
 
 	// make sure the sysfs mount doesn't propagate back
-	if err = syscall.Unshare(syscall.CLONE_NEWNS); err != nil {
+	if err = unix.Unshare(unix.CLONE_NEWNS); err != nil {
 		logrus.Errorf("unshare failed, %v", err)
 		os.Exit(1)
 	}
 
-	flag := syscall.MS_PRIVATE | syscall.MS_REC
-	if err = syscall.Mount("", "/", "", uintptr(flag), ""); err != nil {
+	flag := unix.MS_PRIVATE | unix.MS_REC
+	if err = unix.Mount("", "/", "", uintptr(flag), ""); err != nil {
 		logrus.Errorf("root mount failed, %v", err)
 		os.Exit(1)
 	}
 
-	if err = syscall.Mount("sysfs", "/sys", "sysfs", 0, ""); err != nil {
+	if err = unix.Mount("sysfs", "/sys", "sysfs", 0, ""); err != nil {
 		logrus.Errorf("mounting sysfs failed, %v", err)
 		os.Exit(1)
 	}
@@ -427,7 +427,7 @@ func populateVNITbl() {
 			}
 			defer ns.Close()
 
-			nlh, err := netlink.NewHandleAt(ns, syscall.NETLINK_ROUTE)
+			nlh, err := netlink.NewHandleAt(ns, unix.NETLINK_ROUTE)
 			if err != nil {
 				logrus.Errorf("Could not open netlink handle during vni population for ns %s: %v", path, err)
 				return nil
@@ -583,7 +583,7 @@ func (n *network) setupSubnetSandbox(s *subnet, brName, vxlanName string) error
 
 		if ok {
 			deleteVxlanByVNI(path, s.vni)
-			if err := syscall.Unmount(path, syscall.MNT_FORCE); err != nil {
+			if err := unix.Unmount(path, unix.MNT_FORCE); err != nil {
 				logrus.Errorf("unmount of %s failed: %v", path, err)
 			}
 			os.Remove(path)
@@ -693,7 +693,7 @@ func (n *network) cleanupStaleSandboxes() {
 			if strings.Contains(n.id, pattern) {
 				// Delete all vnis
 				deleteVxlanByVNI(path, 0)
-				syscall.Unmount(path, syscall.MNT_DETACH)
+				unix.Unmount(path, unix.MNT_DETACH)
 				os.Remove(path)
 
 				// Now that we have destroyed this
@@ -755,12 +755,12 @@ func (n *network) initSandbox(restore bool) error {
 
 	var nlSock *nl.NetlinkSocket
 	sbox.InvokeFunc(func() {
-		nlSock, err = nl.Subscribe(syscall.NETLINK_ROUTE, syscall.RTNLGRP_NEIGH)
+		nlSock, err = nl.Subscribe(unix.NETLINK_ROUTE, unix.RTNLGRP_NEIGH)
 		if err != nil {
 			return
 		}
 		// set the receive timeout to not remain stuck on the RecvFrom if the fd gets closed
-		tv := syscall.NsecToTimeval(soTimeout.Nanoseconds())
+		tv := unix.NsecToTimeval(soTimeout.Nanoseconds())
 		err = nlSock.SetReceiveTimeout(&tv)
 	})
 	n.nlSocket = nlSock
@@ -803,7 +803,7 @@ func (n *network) watchMiss(nlSock *nl.NetlinkSocket, nsPath string) {
 				return
 			}
 			// When the receive timeout expires the receive will return EAGAIN
-			if err == syscall.EAGAIN {
+			if err == unix.EAGAIN {
 				// we continue here to avoid spam for timeouts
 				continue
 			}
@@ -812,7 +812,7 @@ func (n *network) watchMiss(nlSock *nl.NetlinkSocket, nsPath string) {
 		}
 
 		for _, msg := range msgs {
-			if msg.Header.Type != syscall.RTM_GETNEIGH && msg.Header.Type != syscall.RTM_NEWNEIGH {
+			if msg.Header.Type != unix.RTM_GETNEIGH && msg.Header.Type != unix.RTM_NEWNEIGH {
 				continue
 			}
 

+ 32 - 2
vendor/github.com/docker/libnetwork/firewall_linux.go

@@ -2,6 +2,7 @@ package libnetwork
 
 import (
 	"github.com/docker/libnetwork/iptables"
+	"github.com/docker/libnetwork/netlabel"
 	"github.com/sirupsen/logrus"
 )
 
@@ -9,15 +10,44 @@ const userChain = "DOCKER-USER"
 
 func (c *controller) arrangeUserFilterRule() {
 	c.Lock()
-	arrangeUserFilterRule()
+
+	if c.hasIPTablesEnabled() {
+		arrangeUserFilterRule()
+	}
+
 	c.Unlock()
+
 	iptables.OnReloaded(func() {
 		c.Lock()
-		arrangeUserFilterRule()
+
+		if c.hasIPTablesEnabled() {
+			arrangeUserFilterRule()
+		}
+
 		c.Unlock()
 	})
 }
 
+func (c *controller) hasIPTablesEnabled() bool {
+	// Locking c should be handled in the calling method.
+	if c.cfg == nil || c.cfg.Daemon.DriverCfg[netlabel.GenericData] == nil {
+		return false
+	}
+
+	genericData, ok := c.cfg.Daemon.DriverCfg[netlabel.GenericData]
+	if !ok {
+		return false
+	}
+
+	optMap := genericData.(map[string]interface{})
+	enabled, ok := optMap["EnableIPTables"].(bool)
+	if !ok {
+		return false
+	}
+
+	return enabled
+}
+
 // This chain allow users to configure firewall policies in a way that persists
 // docker operations/restarts. Docker will not delete or modify any pre-existing
 // rules from the DOCKER-USER filter chain.

+ 5 - 6
vendor/github.com/docker/libnetwork/ipvs/ipvs.go

@@ -3,14 +3,13 @@
 package ipvs
 
 import (
+	"fmt"
 	"net"
-	"syscall"
 	"time"
 
-	"fmt"
-
 	"github.com/vishvananda/netlink/nl"
 	"github.com/vishvananda/netns"
+	"golang.org/x/sys/unix"
 )
 
 const (
@@ -98,16 +97,16 @@ func New(path string) (*Handle, error) {
 	}
 	defer n.Close()
 
-	sock, err := nl.GetNetlinkSocketAt(n, netns.None(), syscall.NETLINK_GENERIC)
+	sock, err := nl.GetNetlinkSocketAt(n, netns.None(), unix.NETLINK_GENERIC)
 	if err != nil {
 		return nil, err
 	}
 	// Add operation timeout to avoid deadlocks
-	tv := syscall.NsecToTimeval(netlinkSendSocketTimeout.Nanoseconds())
+	tv := unix.NsecToTimeval(netlinkSendSocketTimeout.Nanoseconds())
 	if err := sock.SetSendTimeout(&tv); err != nil {
 		return nil, err
 	}
-	tv = syscall.NsecToTimeval(netlinkRecvSocketsTimeout.Nanoseconds())
+	tv = unix.NsecToTimeval(netlinkRecvSocketsTimeout.Nanoseconds())
 	if err := sock.SetReceiveTimeout(&tv); err != nil {
 		return nil, err
 	}

+ 7 - 2
vendor/github.com/docker/libnetwork/network.go

@@ -1381,14 +1381,18 @@ func delIPToName(ipMap setmatrix.SetMatrix, name, serviceID string, ip net.IP) {
 }
 
 func addNameToIP(svcMap setmatrix.SetMatrix, name, serviceID string, epIP net.IP) {
-	svcMap.Insert(name, svcMapEntry{
+	// Since DNS name resolution is case-insensitive, Use the lower-case form
+	// of the name as the key into svcMap
+	lowerCaseName := strings.ToLower(name)
+	svcMap.Insert(lowerCaseName, svcMapEntry{
 		ip:        epIP.String(),
 		serviceID: serviceID,
 	})
 }
 
 func delNameToIP(svcMap setmatrix.SetMatrix, name, serviceID string, epIP net.IP) {
-	svcMap.Remove(name, svcMapEntry{
+	lowerCaseName := strings.ToLower(name)
+	svcMap.Remove(lowerCaseName, svcMapEntry{
 		ip:        epIP.String(),
 		serviceID: serviceID,
 	})
@@ -1956,6 +1960,7 @@ func (n *network) ResolveName(req string, ipType int) ([]net.IP, bool) {
 	}
 
 	req = strings.TrimSuffix(req, ".")
+	req = strings.ToLower(req)
 	ipSet, ok := sr.svcMap.Get(req)
 
 	if ipType == types.IPv6 {

+ 1 - 1
vendor/github.com/docker/libnetwork/resolver.go

@@ -366,8 +366,8 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
 	if query == nil || len(query.Question) == 0 {
 		return
 	}
-	name := query.Question[0].Name
 
+	name := query.Question[0].Name
 	switch query.Question[0].Qtype {
 	case dns.TypeA:
 		resp, err = r.handleIPQuery(name, query, types.IPv4)

+ 51 - 47
vendor/github.com/docker/libnetwork/vendor.conf

@@ -1,50 +1,54 @@
-github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109
-github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
-github.com/Microsoft/go-winio v0.4.11
-github.com/Microsoft/hcsshim v0.7.3
-github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
-github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
-github.com/codegangsta/cli a65b733b303f0055f8d324d805f393cd3e7a7904
-github.com/containerd/continuity d3c23511c1bf5851696cba83143d9cbcd666869b
-github.com/coreos/etcd v3.2.1
-github.com/coreos/go-semver v0.2.0
-github.com/deckarep/golang-set ef32fa3046d9f249d399f98ebaf9be944430fd1d
-go.etcd.io/bbolt v1.3.1-etcd.8
+github.com/Azure/go-ansiterm            d6e3b3328b783f23731bc4d058875b0371ff8109
+github.com/BurntSushi/toml              3012a1dbe2e4bd1391d42b32f0577cb7bbc7f005 # v0.3.1
+github.com/Microsoft/go-winio           c599b533b43b1363d7d7c6cfda5ede70ed73ff13
+github.com/Microsoft/hcsshim            ba3d6667710fa905116f39a19d059c4c1016be7c
+github.com/armon/go-metrics             eb0af217e5e9747e41dd5303755356b62d28e3ec
+github.com/armon/go-radix               e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
+github.com/codegangsta/cli              a65b733b303f0055f8d324d805f393cd3e7a7904
+github.com/containerd/continuity        004b46473808b3e7a4a3049c20e4376c91eb966d
+github.com/coreos/etcd                  fca8add78a9d926166eb739b8e4a124434025ba3 # v3.3.9
+github.com/coreos/go-semver             8ab6407b697782a06568d4b7f1db25550ec2e4c6 # v0.2.0
+github.com/deckarep/golang-set          ef32fa3046d9f249d399f98ebaf9be944430fd1d
+go.etcd.io/bbolt                        7ee3ded59d4835e10f3e7d0f7603c42aa5e83820 # v1.3.1-etcd.8
 
-github.com/docker/docker 162ba6016def672690ee4a1f3978368853a1e149
-github.com/docker/go-connections 7beb39f0b969b075d1325fecb092faf27fd357b6
-github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
-github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1
-github.com/docker/libkv 458977154600b9f23984d9f4b82e79570b5ae12b
+github.com/docker/docker                dbe4a30928d418e0570891a09703bcbc0e4997a1
+github.com/docker/distribution          0d3efadf0154c2b8a4e7b6621fff9809655cc580
+github.com/docker/go-connections        7395e3f8aa162843a74ed6d48e79627d9792ac55 # v0.4.0
+github.com/docker/go-events             9461782956ad83b30282bf90e31fa6a70c255ba9
+github.com/docker/go-units              47565b4f722fb6ceae66b95f853feed578a4a51c # v0.3.3
+github.com/docker/libkv                 458977154600b9f23984d9f4b82e79570b5ae12b
 
-github.com/godbus/dbus v4.0.0
-github.com/gogo/protobuf v1.0.0
-github.com/gorilla/context v1.1
-github.com/gorilla/mux v1.1
-github.com/hashicorp/consul v0.5.2
-github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b
-github.com/hashicorp/go-multierror fcdddc395df1ddf4247c69bd436e84cfa0733f7e
-github.com/hashicorp/memberlist 3d8438da9589e7b608a83ffac1ef8211486bcb7c
-github.com/sean-/seed e2103e2c35297fb7e17febb81e49b312087a2372
-github.com/hashicorp/go-sockaddr 6d291a969b86c4b633730bfc6b8b9d64c3aafed9
-github.com/hashicorp/serf 598c54895cc5a7b1a24a398d635e8c0ea0959870
-github.com/mattn/go-shellwords v1.0.3
-github.com/miekg/dns v1.0.7
-github.com/opencontainers/go-digest v1.0.0-rc1
-github.com/opencontainers/image-spec v1.0.1
-github.com/opencontainers/runc 96ec2177ae841256168fcf76954f7177af9446eb
-github.com/opencontainers/runtime-spec v1.0.1
-github.com/samuel/go-zookeeper d0e0d8e11f318e000a8cc434616d69e329edc374
-github.com/sirupsen/logrus v1.0.3
-github.com/ugorji/go f1f1a805ed361a0e078bb537e4ea78cd37dcf065
-github.com/vishvananda/netlink b2de5d10e38ecce8607e6b438b6d174f389a004e
-github.com/vishvananda/netns 604eaf189ee867d8c147fafc28def2394e878d25
-golang.org/x/crypto 1a580b3eff7814fc9b40602fd35256c63b50f491
-golang.org/x/net 0ed95abb35c445290478a5348a7b38bb154135fd
-golang.org/x/sys 37707fdb30a5b38865cfb95e5aab41707daec7fd
-golang.org/x/sync fd80eb99c8f653c847d294a001bdf2a3a6f768f5
-github.com/pkg/errors 839d9e913e063e28dfd0e6c7b7512793e0a48be9
-github.com/ishidawataru/sctp 07191f837fedd2f13d1ec7b5f885f0f3ec54b1cb
+github.com/gogo/protobuf                ba06b47c162d49f2af050fb4c75bcbc86a159d5c # v1.2.1
+github.com/golang/protobuf              aa810b61a9c79d51363740d207bb46cf8e620ed5 # v1.2.0
+google.golang.org/grpc                  7a6a684ca69eb4cae85ad0a484f2e531598c047b # v1.12.2
+google.golang.org/genproto              694d95ba50e67b2e363f3483057db5d4910c18f9
 
-gotest.tools v2.1.0
-github.com/google/go-cmp v0.2.0
+github.com/godbus/dbus                  5f6efc7ef2759c81b7ba876593971bfce311eab3 # v4.0.0
+github.com/gorilla/mux                  c5c6c98bc25355028a63748a498942a6398ccd22 # v1.7.1
+github.com/hashicorp/consul             9a9cc9341bb487651a0399e3fc5e1e8a42e62dd9 # v0.5.2
+github.com/hashicorp/go-msgpack         71c2886f5a673a35f909803f38ece5810165097b
+github.com/hashicorp/go-multierror      fcdddc395df1ddf4247c69bd436e84cfa0733f7e
+github.com/hashicorp/memberlist         3d8438da9589e7b608a83ffac1ef8211486bcb7c
+github.com/sean-/seed                   e2103e2c35297fb7e17febb81e49b312087a2372
+github.com/hashicorp/go-sockaddr        6d291a969b86c4b633730bfc6b8b9d64c3aafed9
+github.com/hashicorp/serf               598c54895cc5a7b1a24a398d635e8c0ea0959870
+github.com/mattn/go-shellwords          02e3cf038dcea8290e44424da473dd12be796a8a # v1.0.3
+github.com/miekg/dns                    e57bf427e68187a27e22adceac868350d7a7079b # v1.0.7
+github.com/opencontainers/go-digest     279bed98673dd5bef374d3b6e4b09e2af76183bf # v1.0.0-rc1
+github.com/opencontainers/image-spec    d60099175f88c47cd379c4738d158884749ed235 # v1.0.1
+github.com/opencontainers/runc          2b18fe1d885ee5083ef9f0838fee39b62d653e30
+github.com/opencontainers/runtime-spec  29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db
+github.com/samuel/go-zookeeper          d0e0d8e11f318e000a8cc434616d69e329edc374
+github.com/sirupsen/logrus              f006c2ac4710855cf0f916dd6b77acf6b048dc6e # v1.0.3
+github.com/ugorji/go                    b4c50a2b199d93b13dc15e78929cfb23bfdf21ab # v1.1.1
+github.com/vishvananda/netlink          a2ad57a690f3caf3015351d2d6e1c0b95c349752 # v1.0.0
+github.com/vishvananda/netns            13995c7128ccc8e51e9a6bd2b551020a27180abd
+golang.org/x/crypto                     b7391e95e576cacdcdd422573063bc057239113d
+golang.org/x/net                        a680a1efc54dd51c040b3b5ce4939ea3cf2ea0d1
+golang.org/x/sys                        d455e41777fca6e8a5a79e34a14b8368bc11d9ba
+golang.org/x/sync                       1d60e4601c6fd243af51cc01ddf169918a5407ca
+github.com/pkg/errors                   ba968bfe8b2f7e042a574c888954fccecfa385b4 # v0.8.1
+github.com/ishidawataru/sctp            07191f837fedd2f13d1ec7b5f885f0f3ec54b1cb
+
+gotest.tools                            b6e20af1ed078cd01a6413b734051a292450b4cb # v2.1.0
+github.com/google/go-cmp                3af367b6b30c263d47e8895973edcca9a49cf029 # v0.2.0

+ 1 - 0
vendor/github.com/vishvananda/netlink/README.md

@@ -89,3 +89,4 @@ There are also a few pieces of low level netlink functionality that still
 need to be implemented. Routing rules are not in place and some of the
 more advanced link types. Hopefully there is decent structure and testing
 in place to make these fairly straightforward to add.
+

+ 66 - 28
vendor/github.com/vishvananda/netlink/addr_linux.go

@@ -8,6 +8,7 @@ import (
 
 	"github.com/vishvananda/netlink/nl"
 	"github.com/vishvananda/netns"
+	"golang.org/x/sys/unix"
 )
 
 // IFA_FLAGS is a u32 attribute.
@@ -22,7 +23,7 @@ func AddrAdd(link Link, addr *Addr) error {
 // AddrAdd will add an IP address to a link device.
 // Equivalent to: `ip addr add $addr dev $link`
 func (h *Handle) AddrAdd(link Link, addr *Addr) error {
-	req := h.newNetlinkRequest(syscall.RTM_NEWADDR, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
+	req := h.newNetlinkRequest(unix.RTM_NEWADDR, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
 	return h.addrHandle(link, addr, req)
 }
 
@@ -35,7 +36,7 @@ func AddrReplace(link Link, addr *Addr) error {
 // AddrReplace will replace (or, if not present, add) an IP address on a link device.
 // Equivalent to: `ip addr replace $addr dev $link`
 func (h *Handle) AddrReplace(link Link, addr *Addr) error {
-	req := h.newNetlinkRequest(syscall.RTM_NEWADDR, syscall.NLM_F_CREATE|syscall.NLM_F_REPLACE|syscall.NLM_F_ACK)
+	req := h.newNetlinkRequest(unix.RTM_NEWADDR, unix.NLM_F_CREATE|unix.NLM_F_REPLACE|unix.NLM_F_ACK)
 	return h.addrHandle(link, addr, req)
 }
 
@@ -48,7 +49,7 @@ func AddrDel(link Link, addr *Addr) error {
 // AddrDel will delete an IP address from a link device.
 // Equivalent to: `ip addr del $addr dev $link`
 func (h *Handle) AddrDel(link Link, addr *Addr) error {
-	req := h.newNetlinkRequest(syscall.RTM_DELADDR, syscall.NLM_F_ACK)
+	req := h.newNetlinkRequest(unix.RTM_DELADDR, unix.NLM_F_ACK)
 	return h.addrHandle(link, addr, req)
 }
 
@@ -75,7 +76,7 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error
 		localAddrData = addr.IP.To16()
 	}
 
-	localData := nl.NewRtAttr(syscall.IFA_LOCAL, localAddrData)
+	localData := nl.NewRtAttr(unix.IFA_LOCAL, localAddrData)
 	req.AddData(localData)
 	var peerAddrData []byte
 	if addr.Peer != nil {
@@ -88,7 +89,7 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error
 		peerAddrData = localAddrData
 	}
 
-	addressData := nl.NewRtAttr(syscall.IFA_ADDRESS, peerAddrData)
+	addressData := nl.NewRtAttr(unix.IFA_ADDRESS, peerAddrData)
 	req.AddData(addressData)
 
 	if addr.Flags != 0 {
@@ -102,21 +103,34 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error
 		}
 	}
 
-	if addr.Broadcast == nil {
-		calcBroadcast := make(net.IP, masklen/8)
-		for i := range localAddrData {
-			calcBroadcast[i] = localAddrData[i] | ^addr.Mask[i]
+	if family == FAMILY_V4 {
+		if addr.Broadcast == nil {
+			calcBroadcast := make(net.IP, masklen/8)
+			for i := range localAddrData {
+				calcBroadcast[i] = localAddrData[i] | ^addr.Mask[i]
+			}
+			addr.Broadcast = calcBroadcast
+		}
+		req.AddData(nl.NewRtAttr(unix.IFA_BROADCAST, addr.Broadcast))
+
+		if addr.Label != "" {
+			labelData := nl.NewRtAttr(unix.IFA_LABEL, nl.ZeroTerminated(addr.Label))
+			req.AddData(labelData)
 		}
-		addr.Broadcast = calcBroadcast
 	}
-	req.AddData(nl.NewRtAttr(syscall.IFA_BROADCAST, addr.Broadcast))
 
-	if addr.Label != "" {
-		labelData := nl.NewRtAttr(syscall.IFA_LABEL, nl.ZeroTerminated(addr.Label))
-		req.AddData(labelData)
+	// 0 is the default value for these attributes. However, 0 means "expired", while the least-surprising default
+	// value should be "forever". To compensate for that, only add the attributes if at least one of the values is
+	// non-zero, which means the caller has explicitly set them
+	if addr.ValidLft > 0 || addr.PreferedLft > 0 {
+		cachedata := nl.IfaCacheInfo{
+			IfaValid:    uint32(addr.ValidLft),
+			IfaPrefered: uint32(addr.PreferedLft),
+		}
+		req.AddData(nl.NewRtAttr(unix.IFA_CACHEINFO, cachedata.Serialize()))
 	}
 
-	_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
+	_, err := req.Execute(unix.NETLINK_ROUTE, 0)
 	return err
 }
 
@@ -131,11 +145,11 @@ func AddrList(link Link, family int) ([]Addr, error) {
 // Equivalent to: `ip addr show`.
 // The list can be filtered by link and ip family.
 func (h *Handle) AddrList(link Link, family int) ([]Addr, error) {
-	req := h.newNetlinkRequest(syscall.RTM_GETADDR, syscall.NLM_F_DUMP)
+	req := h.newNetlinkRequest(unix.RTM_GETADDR, unix.NLM_F_DUMP)
 	msg := nl.NewIfInfomsg(family)
 	req.AddData(msg)
 
-	msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWADDR)
+	msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWADDR)
 	if err != nil {
 		return nil, err
 	}
@@ -187,21 +201,21 @@ func parseAddr(m []byte) (addr Addr, family, index int, err error) {
 	var local, dst *net.IPNet
 	for _, attr := range attrs {
 		switch attr.Attr.Type {
-		case syscall.IFA_ADDRESS:
+		case unix.IFA_ADDRESS:
 			dst = &net.IPNet{
 				IP:   attr.Value,
 				Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
 			}
 			addr.Peer = dst
-		case syscall.IFA_LOCAL:
+		case unix.IFA_LOCAL:
 			local = &net.IPNet{
 				IP:   attr.Value,
 				Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
 			}
 			addr.IPNet = local
-		case syscall.IFA_BROADCAST:
+		case unix.IFA_BROADCAST:
 			addr.Broadcast = attr.Value
-		case syscall.IFA_LABEL:
+		case unix.IFA_LABEL:
 			addr.Label = string(attr.Value[:len(attr.Value)-1])
 		case IFA_FLAGS:
 			addr.Flags = int(native.Uint32(attr.Value[0:4]))
@@ -236,13 +250,13 @@ type AddrUpdate struct {
 // AddrSubscribe takes a chan down which notifications will be sent
 // when addresses change.  Close the 'done' chan to stop subscription.
 func AddrSubscribe(ch chan<- AddrUpdate, done <-chan struct{}) error {
-	return addrSubscribeAt(netns.None(), netns.None(), ch, done, nil)
+	return addrSubscribeAt(netns.None(), netns.None(), ch, done, nil, false)
 }
 
 // AddrSubscribeAt works like AddrSubscribe plus it allows the caller
 // to choose the network namespace in which to subscribe (ns).
 func AddrSubscribeAt(ns netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}) error {
-	return addrSubscribeAt(ns, netns.None(), ch, done, nil)
+	return addrSubscribeAt(ns, netns.None(), ch, done, nil, false)
 }
 
 // AddrSubscribeOptions contains a set of options to use with
@@ -250,6 +264,7 @@ func AddrSubscribeAt(ns netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct
 type AddrSubscribeOptions struct {
 	Namespace     *netns.NsHandle
 	ErrorCallback func(error)
+	ListExisting  bool
 }
 
 // AddrSubscribeWithOptions work like AddrSubscribe but enable to
@@ -260,11 +275,11 @@ func AddrSubscribeWithOptions(ch chan<- AddrUpdate, done <-chan struct{}, option
 		none := netns.None()
 		options.Namespace = &none
 	}
-	return addrSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback)
+	return addrSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting)
 }
 
-func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}, cberr func(error)) error {
-	s, err := nl.SubscribeAt(newNs, curNs, syscall.NETLINK_ROUTE, syscall.RTNLGRP_IPV4_IFADDR, syscall.RTNLGRP_IPV6_IFADDR)
+func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}, cberr func(error), listExisting bool) error {
+	s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_IPV4_IFADDR, unix.RTNLGRP_IPV6_IFADDR)
 	if err != nil {
 		return err
 	}
@@ -274,6 +289,15 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c
 			s.Close()
 		}()
 	}
+	if listExisting {
+		req := pkgHandle.newNetlinkRequest(unix.RTM_GETADDR,
+			unix.NLM_F_DUMP)
+		infmsg := nl.NewIfInfomsg(unix.AF_UNSPEC)
+		req.AddData(infmsg)
+		if err := s.Send(req); err != nil {
+			return err
+		}
+	}
 	go func() {
 		defer close(ch)
 		for {
@@ -285,8 +309,22 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c
 				return
 			}
 			for _, m := range msgs {
+				if m.Header.Type == unix.NLMSG_DONE {
+					continue
+				}
+				if m.Header.Type == unix.NLMSG_ERROR {
+					native := nl.NativeEndian()
+					error := int32(native.Uint32(m.Data[0:4]))
+					if error == 0 {
+						continue
+					}
+					if cberr != nil {
+						cberr(syscall.Errno(-error))
+					}
+					return
+				}
 				msgType := m.Header.Type
-				if msgType != syscall.RTM_NEWADDR && msgType != syscall.RTM_DELADDR {
+				if msgType != unix.RTM_NEWADDR && msgType != unix.RTM_DELADDR {
 					if cberr != nil {
 						cberr(fmt.Errorf("bad message type: %d", msgType))
 					}
@@ -303,7 +341,7 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c
 
 				ch <- AddrUpdate{LinkAddress: *addr.IPNet,
 					LinkIndex:   ifindex,
-					NewAddr:     msgType == syscall.RTM_NEWADDR,
+					NewAddr:     msgType == unix.RTM_NEWADDR,
 					Flags:       addr.Flags,
 					Scope:       addr.Scope,
 					PreferedLft: addr.PreferedLft,

+ 37 - 46
vendor/github.com/vishvananda/netlink/bpf_linux.go

@@ -1,49 +1,12 @@
 package netlink
 
-/*
-#include <asm/types.h>
-#include <asm/unistd.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <unistd.h>
+import (
+	"unsafe"
 
-static int load_simple_bpf(int prog_type, int ret) {
-#ifdef __NR_bpf
-	// { return ret; }
-	__u64 __attribute__((aligned(8))) insns[] = {
-		0x00000000000000b7ull | ((__u64)ret<<32),
-		0x0000000000000095ull,
-	};
-	__u8 __attribute__((aligned(8))) license[] = "ASL2";
-	// Copied from a header file since libc is notoriously slow to update.
-	// The call will succeed or fail and that will be our indication on
-	// whether or not it is supported.
-	struct {
-		__u32 prog_type;
-		__u32 insn_cnt;
-		__u64 insns;
-		__u64 license;
-		__u32 log_level;
-		__u32 log_size;
-		__u64 log_buf;
-		__u32 kern_version;
-	} __attribute__((aligned(8))) attr = {
-		.prog_type = prog_type,
-		.insn_cnt = 2,
-		.insns = (uintptr_t)&insns,
-		.license = (uintptr_t)&license,
-	};
-	return syscall(__NR_bpf, 5, &attr, sizeof(attr));
-#else
-	errno = EINVAL;
-	return -1;
-#endif
-}
-*/
-import "C"
+	"golang.org/x/sys/unix"
+)
 
-type BpfProgType C.int
+type BpfProgType uint32
 
 const (
 	BPF_PROG_TYPE_UNSPEC BpfProgType = iota
@@ -55,8 +18,36 @@ const (
 	BPF_PROG_TYPE_XDP
 )
 
-// loadSimpleBpf loads a trivial bpf program for testing purposes
-func loadSimpleBpf(progType BpfProgType, ret int) (int, error) {
-	fd, err := C.load_simple_bpf(C.int(progType), C.int(ret))
-	return int(fd), err
+type BPFAttr struct {
+	ProgType    uint32
+	InsnCnt     uint32
+	Insns       uintptr
+	License     uintptr
+	LogLevel    uint32
+	LogSize     uint32
+	LogBuf      uintptr
+	KernVersion uint32
+}
+
+// loadSimpleBpf loads a trivial bpf program for testing purposes.
+func loadSimpleBpf(progType BpfProgType, ret uint32) (int, error) {
+	insns := []uint64{
+		0x00000000000000b7 | (uint64(ret) << 32),
+		0x0000000000000095,
+	}
+	license := []byte{'A', 'S', 'L', '2', '\x00'}
+	attr := BPFAttr{
+		ProgType: uint32(progType),
+		InsnCnt:  uint32(len(insns)),
+		Insns:    uintptr(unsafe.Pointer(&insns[0])),
+		License:  uintptr(unsafe.Pointer(&license[0])),
+	}
+	fd, _, errno := unix.Syscall(unix.SYS_BPF,
+		5, /* bpf cmd */
+		uintptr(unsafe.Pointer(&attr)),
+		unsafe.Sizeof(attr))
+	if errno != 0 {
+		return 0, errno
+	}
+	return int(fd), nil
 }

+ 12 - 12
vendor/github.com/vishvananda/netlink/bridge_linux.go

@@ -2,9 +2,9 @@ package netlink
 
 import (
 	"fmt"
-	"syscall"
 
 	"github.com/vishvananda/netlink/nl"
+	"golang.org/x/sys/unix"
 )
 
 // BridgeVlanList gets a map of device id to bridge vlan infos.
@@ -16,12 +16,12 @@ func BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) {
 // BridgeVlanList gets a map of device id to bridge vlan infos.
 // Equivalent to: `bridge vlan show`
 func (h *Handle) BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) {
-	req := h.newNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_DUMP)
-	msg := nl.NewIfInfomsg(syscall.AF_BRIDGE)
+	req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_DUMP)
+	msg := nl.NewIfInfomsg(unix.AF_BRIDGE)
 	req.AddData(msg)
-	req.AddData(nl.NewRtAttr(nl.IFLA_EXT_MASK, nl.Uint32Attr(uint32(nl.RTEXT_FILTER_BRVLAN))))
+	req.AddData(nl.NewRtAttr(unix.IFLA_EXT_MASK, nl.Uint32Attr(uint32(nl.RTEXT_FILTER_BRVLAN))))
 
-	msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWLINK)
+	msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWLINK)
 	if err != nil {
 		return nil, err
 	}
@@ -35,7 +35,7 @@ func (h *Handle) BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) {
 		}
 		for _, attr := range attrs {
 			switch attr.Attr.Type {
-			case nl.IFLA_AF_SPEC:
+			case unix.IFLA_AF_SPEC:
 				//nested attr
 				nestAttrs, err := nl.ParseRouteAttr(attr.Value)
 				if err != nil {
@@ -63,7 +63,7 @@ func BridgeVlanAdd(link Link, vid uint16, pvid, untagged, self, master bool) err
 // BridgeVlanAdd adds a new vlan filter entry
 // Equivalent to: `bridge vlan add dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]`
 func (h *Handle) BridgeVlanAdd(link Link, vid uint16, pvid, untagged, self, master bool) error {
-	return h.bridgeVlanModify(syscall.RTM_SETLINK, link, vid, pvid, untagged, self, master)
+	return h.bridgeVlanModify(unix.RTM_SETLINK, link, vid, pvid, untagged, self, master)
 }
 
 // BridgeVlanDel adds a new vlan filter entry
@@ -75,19 +75,19 @@ func BridgeVlanDel(link Link, vid uint16, pvid, untagged, self, master bool) err
 // BridgeVlanDel adds a new vlan filter entry
 // Equivalent to: `bridge vlan del dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]`
 func (h *Handle) BridgeVlanDel(link Link, vid uint16, pvid, untagged, self, master bool) error {
-	return h.bridgeVlanModify(syscall.RTM_DELLINK, link, vid, pvid, untagged, self, master)
+	return h.bridgeVlanModify(unix.RTM_DELLINK, link, vid, pvid, untagged, self, master)
 }
 
 func (h *Handle) bridgeVlanModify(cmd int, link Link, vid uint16, pvid, untagged, self, master bool) error {
 	base := link.Attrs()
 	h.ensureIndex(base)
-	req := h.newNetlinkRequest(cmd, syscall.NLM_F_ACK)
+	req := h.newNetlinkRequest(cmd, unix.NLM_F_ACK)
 
-	msg := nl.NewIfInfomsg(syscall.AF_BRIDGE)
+	msg := nl.NewIfInfomsg(unix.AF_BRIDGE)
 	msg.Index = int32(base.Index)
 	req.AddData(msg)
 
-	br := nl.NewRtAttr(nl.IFLA_AF_SPEC, nil)
+	br := nl.NewRtAttr(unix.IFLA_AF_SPEC, nil)
 	var flags uint16
 	if self {
 		flags |= nl.BRIDGE_FLAGS_SELF
@@ -107,7 +107,7 @@ func (h *Handle) bridgeVlanModify(cmd int, link Link, vid uint16, pvid, untagged
 	}
 	nl.NewRtAttrChild(br, nl.IFLA_BRIDGE_VLAN_INFO, vlanInfo.Serialize())
 	req.AddData(br)
-	_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
+	_, err := req.Execute(unix.NETLINK_ROUTE, 0)
 	if err != nil {
 		return err
 	}

+ 13 - 12
vendor/github.com/vishvananda/netlink/class_linux.go

@@ -5,6 +5,7 @@ import (
 	"syscall"
 
 	"github.com/vishvananda/netlink/nl"
+	"golang.org/x/sys/unix"
 )
 
 // NOTE: function is in here because it uses other linux functions
@@ -50,7 +51,7 @@ func ClassDel(class Class) error {
 // ClassDel will delete a class from the system.
 // Equivalent to: `tc class del $class`
 func (h *Handle) ClassDel(class Class) error {
-	return h.classModify(syscall.RTM_DELTCLASS, 0, class)
+	return h.classModify(unix.RTM_DELTCLASS, 0, class)
 }
 
 // ClassChange will change a class in place
@@ -64,7 +65,7 @@ func ClassChange(class Class) error {
 // Equivalent to: `tc class change $class`
 // The parent and handle MUST NOT be changed.
 func (h *Handle) ClassChange(class Class) error {
-	return h.classModify(syscall.RTM_NEWTCLASS, 0, class)
+	return h.classModify(unix.RTM_NEWTCLASS, 0, class)
 }
 
 // ClassReplace will replace a class to the system.
@@ -82,7 +83,7 @@ func ClassReplace(class Class) error {
 // If a class already exist with this parent/handle pair, the class is changed.
 // If a class does not already exist with this parent/handle, a new class is created.
 func (h *Handle) ClassReplace(class Class) error {
-	return h.classModify(syscall.RTM_NEWTCLASS, syscall.NLM_F_CREATE, class)
+	return h.classModify(unix.RTM_NEWTCLASS, unix.NLM_F_CREATE, class)
 }
 
 // ClassAdd will add a class to the system.
@@ -95,14 +96,14 @@ func ClassAdd(class Class) error {
 // Equivalent to: `tc class add $class`
 func (h *Handle) ClassAdd(class Class) error {
 	return h.classModify(
-		syscall.RTM_NEWTCLASS,
-		syscall.NLM_F_CREATE|syscall.NLM_F_EXCL,
+		unix.RTM_NEWTCLASS,
+		unix.NLM_F_CREATE|unix.NLM_F_EXCL,
 		class,
 	)
 }
 
 func (h *Handle) classModify(cmd, flags int, class Class) error {
-	req := h.newNetlinkRequest(cmd, flags|syscall.NLM_F_ACK)
+	req := h.newNetlinkRequest(cmd, flags|unix.NLM_F_ACK)
 	base := class.Attrs()
 	msg := &nl.TcMsg{
 		Family:  nl.FAMILY_ALL,
@@ -112,12 +113,12 @@ func (h *Handle) classModify(cmd, flags int, class Class) error {
 	}
 	req.AddData(msg)
 
-	if cmd != syscall.RTM_DELTCLASS {
+	if cmd != unix.RTM_DELTCLASS {
 		if err := classPayload(req, class); err != nil {
 			return err
 		}
 	}
-	_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
+	_, err := req.Execute(unix.NETLINK_ROUTE, 0)
 	return err
 }
 
@@ -141,12 +142,12 @@ func classPayload(req *nl.NetlinkRequest, class Class) error {
 		var rtab [256]uint32
 		var ctab [256]uint32
 		tcrate := nl.TcRateSpec{Rate: uint32(htb.Rate)}
-		if CalcRtable(&tcrate, rtab, cellLog, uint32(mtu), linklayer) < 0 {
+		if CalcRtable(&tcrate, rtab[:], cellLog, uint32(mtu), linklayer) < 0 {
 			return errors.New("HTB: failed to calculate rate table")
 		}
 		opt.Rate = tcrate
 		tcceil := nl.TcRateSpec{Rate: uint32(htb.Ceil)}
-		if CalcRtable(&tcceil, ctab, ccellLog, uint32(mtu), linklayer) < 0 {
+		if CalcRtable(&tcceil, ctab[:], ccellLog, uint32(mtu), linklayer) < 0 {
 			return errors.New("HTB: failed to calculate ceil rate table")
 		}
 		opt.Ceil = tcceil
@@ -169,7 +170,7 @@ func ClassList(link Link, parent uint32) ([]Class, error) {
 // Equivalent to: `tc class show`.
 // Generally returns nothing if link and parent are not specified.
 func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) {
-	req := h.newNetlinkRequest(syscall.RTM_GETTCLASS, syscall.NLM_F_DUMP)
+	req := h.newNetlinkRequest(unix.RTM_GETTCLASS, unix.NLM_F_DUMP)
 	msg := &nl.TcMsg{
 		Family: nl.FAMILY_ALL,
 		Parent: parent,
@@ -181,7 +182,7 @@ func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) {
 	}
 	req.AddData(msg)
 
-	msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWTCLASS)
+	msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWTCLASS)
 	if err != nil {
 		return nil, err
 	}

+ 7 - 7
vendor/github.com/vishvananda/netlink/conntrack_linux.go

@@ -6,9 +6,9 @@ import (
 	"errors"
 	"fmt"
 	"net"
-	"syscall"
 
 	"github.com/vishvananda/netlink/nl"
+	"golang.org/x/sys/unix"
 )
 
 // ConntrackTableType Conntrack table for the netlink operation
@@ -85,8 +85,8 @@ func (h *Handle) ConntrackTableList(table ConntrackTableType, family InetFamily)
 // conntrack -F [table]            Flush table
 // The flush operation applies to all the family types
 func (h *Handle) ConntrackTableFlush(table ConntrackTableType) error {
-	req := h.newConntrackRequest(table, syscall.AF_INET, nl.IPCTNL_MSG_CT_DELETE, syscall.NLM_F_ACK)
-	_, err := req.Execute(syscall.NETLINK_NETFILTER, 0)
+	req := h.newConntrackRequest(table, unix.AF_INET, nl.IPCTNL_MSG_CT_DELETE, unix.NLM_F_ACK)
+	_, err := req.Execute(unix.NETLINK_NETFILTER, 0)
 	return err
 }
 
@@ -102,10 +102,10 @@ func (h *Handle) ConntrackDeleteFilter(table ConntrackTableType, family InetFami
 	for _, dataRaw := range res {
 		flow := parseRawData(dataRaw)
 		if match := filter.MatchConntrackFlow(flow); match {
-			req2 := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_DELETE, syscall.NLM_F_ACK)
+			req2 := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_DELETE, unix.NLM_F_ACK)
 			// skip the first 4 byte that are the netfilter header, the newConntrackRequest is adding it already
 			req2.AddRawData(dataRaw[4:])
-			req2.Execute(syscall.NETLINK_NETFILTER, 0)
+			req2.Execute(unix.NETLINK_NETFILTER, 0)
 			matched++
 		}
 	}
@@ -127,8 +127,8 @@ func (h *Handle) newConntrackRequest(table ConntrackTableType, family InetFamily
 }
 
 func (h *Handle) dumpConntrackTable(table ConntrackTableType, family InetFamily) ([][]byte, error) {
-	req := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_GET, syscall.NLM_F_DUMP)
-	return req.Execute(syscall.NETLINK_NETFILTER, 0)
+	req := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_GET, unix.NLM_F_DUMP)
+	return req.Execute(unix.NETLINK_NETFILTER, 0)
 }
 
 // The full conntrack flow structure is very complicated and can be found in the file:

+ 16 - 1
vendor/github.com/vishvananda/netlink/filter.go

@@ -17,7 +17,7 @@ type FilterAttrs struct {
 	Handle    uint32
 	Parent    uint32
 	Priority  uint16 // lower is higher priority
-	Protocol  uint16 // syscall.ETH_P_*
+	Protocol  uint16 // unix.ETH_P_*
 }
 
 func (q FilterAttrs) String() string {
@@ -225,6 +225,21 @@ func (filter *U32) Type() string {
 	return "u32"
 }
 
+// MatchAll filters match all packets
+type MatchAll struct {
+	FilterAttrs
+	ClassId uint32
+	Actions []Action
+}
+
+func (filter *MatchAll) Attrs() *FilterAttrs {
+	return &filter.FilterAttrs
+}
+
+func (filter *MatchAll) Type() string {
+	return "matchall"
+}
+
 type FilterFwAttrs struct {
 	ClassId   uint32
 	InDev     string

+ 47 - 9
vendor/github.com/vishvananda/netlink/filter_linux.go

@@ -9,6 +9,7 @@ import (
 	"unsafe"
 
 	"github.com/vishvananda/netlink/nl"
+	"golang.org/x/sys/unix"
 )
 
 // Constants used in TcU32Sel.Flags.
@@ -55,7 +56,7 @@ func NewFw(attrs FilterAttrs, fattrs FilterFwAttrs) (*Fw, error) {
 	if police.Rate.Rate != 0 {
 		police.Rate.Mpu = fattrs.Mpu
 		police.Rate.Overhead = fattrs.Overhead
-		if CalcRtable(&police.Rate, rtab, rcellLog, fattrs.Mtu, linklayer) < 0 {
+		if CalcRtable(&police.Rate, rtab[:], rcellLog, fattrs.Mtu, linklayer) < 0 {
 			return nil, errors.New("TBF: failed to calculate rate table")
 		}
 		police.Burst = uint32(Xmittime(uint64(police.Rate.Rate), uint32(buffer)))
@@ -64,7 +65,7 @@ func NewFw(attrs FilterAttrs, fattrs FilterFwAttrs) (*Fw, error) {
 	if police.PeakRate.Rate != 0 {
 		police.PeakRate.Mpu = fattrs.Mpu
 		police.PeakRate.Overhead = fattrs.Overhead
-		if CalcRtable(&police.PeakRate, ptab, pcellLog, fattrs.Mtu, linklayer) < 0 {
+		if CalcRtable(&police.PeakRate, ptab[:], pcellLog, fattrs.Mtu, linklayer) < 0 {
 			return nil, errors.New("POLICE: failed to calculate peak rate table")
 		}
 	}
@@ -98,7 +99,7 @@ func FilterDel(filter Filter) error {
 // FilterDel will delete a filter from the system.
 // Equivalent to: `tc filter del $filter`
 func (h *Handle) FilterDel(filter Filter) error {
-	req := h.newNetlinkRequest(syscall.RTM_DELTFILTER, syscall.NLM_F_ACK)
+	req := h.newNetlinkRequest(unix.RTM_DELTFILTER, unix.NLM_F_ACK)
 	base := filter.Attrs()
 	msg := &nl.TcMsg{
 		Family:  nl.FAMILY_ALL,
@@ -109,7 +110,7 @@ func (h *Handle) FilterDel(filter Filter) error {
 	}
 	req.AddData(msg)
 
-	_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
+	_, err := req.Execute(unix.NETLINK_ROUTE, 0)
 	return err
 }
 
@@ -123,7 +124,7 @@ func FilterAdd(filter Filter) error {
 // Equivalent to: `tc filter add $filter`
 func (h *Handle) FilterAdd(filter Filter) error {
 	native = nl.NativeEndian()
-	req := h.newNetlinkRequest(syscall.RTM_NEWTFILTER, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
+	req := h.newNetlinkRequest(unix.RTM_NEWTFILTER, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
 	base := filter.Attrs()
 	msg := &nl.TcMsg{
 		Family:  nl.FAMILY_ALL,
@@ -221,10 +222,18 @@ func (h *Handle) FilterAdd(filter Filter) error {
 			bpfFlags |= nl.TCA_BPF_FLAG_ACT_DIRECT
 		}
 		nl.NewRtAttrChild(options, nl.TCA_BPF_FLAGS, nl.Uint32Attr(bpfFlags))
+	case *MatchAll:
+		actionsAttr := nl.NewRtAttrChild(options, nl.TCA_MATCHALL_ACT, nil)
+		if err := EncodeActions(actionsAttr, filter.Actions); err != nil {
+			return err
+		}
+		if filter.ClassId != 0 {
+			nl.NewRtAttrChild(options, nl.TCA_MATCHALL_CLASSID, nl.Uint32Attr(filter.ClassId))
+		}
 	}
 
 	req.AddData(options)
-	_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
+	_, err := req.Execute(unix.NETLINK_ROUTE, 0)
 	return err
 }
 
@@ -239,7 +248,7 @@ func FilterList(link Link, parent uint32) ([]Filter, error) {
 // Equivalent to: `tc filter show`.
 // Generally returns nothing if link and parent are not specified.
 func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
-	req := h.newNetlinkRequest(syscall.RTM_GETTFILTER, syscall.NLM_F_DUMP)
+	req := h.newNetlinkRequest(unix.RTM_GETTFILTER, unix.NLM_F_DUMP)
 	msg := &nl.TcMsg{
 		Family: nl.FAMILY_ALL,
 		Parent: parent,
@@ -251,7 +260,7 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
 	}
 	req.AddData(msg)
 
-	msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWTFILTER)
+	msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWTFILTER)
 	if err != nil {
 		return nil, err
 	}
@@ -287,6 +296,8 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
 					filter = &Fw{}
 				case "bpf":
 					filter = &BpfFilter{}
+				case "matchall":
+					filter = &MatchAll{}
 				default:
 					filter = &GenericFilter{FilterType: filterType}
 				}
@@ -311,6 +322,11 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
 					if err != nil {
 						return nil, err
 					}
+				case "matchall":
+					detailed, err = parseMatchAllData(filter, data)
+					if err != nil {
+						return nil, err
+					}
 				default:
 					detailed = true
 				}
@@ -540,6 +556,28 @@ func parseBpfData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error)
 	return detailed, nil
 }
 
+func parseMatchAllData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
+	native = nl.NativeEndian()
+	matchall := filter.(*MatchAll)
+	detailed := true
+	for _, datum := range data {
+		switch datum.Attr.Type {
+		case nl.TCA_MATCHALL_CLASSID:
+			matchall.ClassId = native.Uint32(datum.Value[0:4])
+		case nl.TCA_MATCHALL_ACT:
+			tables, err := nl.ParseRouteAttr(datum.Value)
+			if err != nil {
+				return detailed, err
+			}
+			matchall.Actions, err = parseActions(tables)
+			if err != nil {
+				return detailed, err
+			}
+		}
+	}
+	return detailed, nil
+}
+
 func AlignToAtm(size uint) uint {
 	var linksize, cells int
 	cells = int(size / nl.ATM_CELL_PAYLOAD)
@@ -562,7 +600,7 @@ func AdjustSize(sz uint, mpu uint, linklayer int) uint {
 	}
 }
 
-func CalcRtable(rate *nl.TcRateSpec, rtab [256]uint32, cellLog int, mtu uint32, linklayer int) int {
+func CalcRtable(rate *nl.TcRateSpec, rtab []uint32, cellLog int, mtu uint32, linklayer int) int {
 	bps := rate.Rate
 	mpu := rate.Mpu
 	var sz uint

+ 21 - 0
vendor/github.com/vishvananda/netlink/fou.go

@@ -0,0 +1,21 @@
+package netlink
+
+import (
+	"errors"
+)
+
+var (
+	// ErrAttrHeaderTruncated is returned when a netlink attribute's header is
+	// truncated.
+	ErrAttrHeaderTruncated = errors.New("attribute header truncated")
+	// ErrAttrBodyTruncated is returned when a netlink attribute's body is
+	// truncated.
+	ErrAttrBodyTruncated = errors.New("attribute body truncated")
+)
+
+type Fou struct {
+	Family    int
+	Port      int
+	Protocol  int
+	EncapType int
+}

+ 215 - 0
vendor/github.com/vishvananda/netlink/fou_linux.go

@@ -0,0 +1,215 @@
+// +build linux
+
+package netlink
+
+import (
+	"encoding/binary"
+	"errors"
+
+	"github.com/vishvananda/netlink/nl"
+	"golang.org/x/sys/unix"
+)
+
+const (
+	FOU_GENL_NAME = "fou"
+)
+
+const (
+	FOU_CMD_UNSPEC uint8 = iota
+	FOU_CMD_ADD
+	FOU_CMD_DEL
+	FOU_CMD_GET
+	FOU_CMD_MAX = FOU_CMD_GET
+)
+
+const (
+	FOU_ATTR_UNSPEC = iota
+	FOU_ATTR_PORT
+	FOU_ATTR_AF
+	FOU_ATTR_IPPROTO
+	FOU_ATTR_TYPE
+	FOU_ATTR_REMCSUM_NOPARTIAL
+	FOU_ATTR_MAX = FOU_ATTR_REMCSUM_NOPARTIAL
+)
+
+const (
+	FOU_ENCAP_UNSPEC = iota
+	FOU_ENCAP_DIRECT
+	FOU_ENCAP_GUE
+	FOU_ENCAP_MAX = FOU_ENCAP_GUE
+)
+
+var fouFamilyId int
+
+func FouFamilyId() (int, error) {
+	if fouFamilyId != 0 {
+		return fouFamilyId, nil
+	}
+
+	fam, err := GenlFamilyGet(FOU_GENL_NAME)
+	if err != nil {
+		return -1, err
+	}
+
+	fouFamilyId = int(fam.ID)
+	return fouFamilyId, nil
+}
+
+func FouAdd(f Fou) error {
+	return pkgHandle.FouAdd(f)
+}
+
+func (h *Handle) FouAdd(f Fou) error {
+	fam_id, err := FouFamilyId()
+	if err != nil {
+		return err
+	}
+
+	// setting ip protocol conflicts with encapsulation type GUE
+	if f.EncapType == FOU_ENCAP_GUE && f.Protocol != 0 {
+		return errors.New("GUE encapsulation doesn't specify an IP protocol")
+	}
+
+	req := h.newNetlinkRequest(fam_id, unix.NLM_F_ACK)
+
+	// int to byte for port
+	bp := make([]byte, 2)
+	binary.BigEndian.PutUint16(bp[0:2], uint16(f.Port))
+
+	attrs := []*nl.RtAttr{
+		nl.NewRtAttr(FOU_ATTR_PORT, bp),
+		nl.NewRtAttr(FOU_ATTR_TYPE, []byte{uint8(f.EncapType)}),
+		nl.NewRtAttr(FOU_ATTR_AF, []byte{uint8(f.Family)}),
+		nl.NewRtAttr(FOU_ATTR_IPPROTO, []byte{uint8(f.Protocol)}),
+	}
+	raw := []byte{FOU_CMD_ADD, 1, 0, 0}
+	for _, a := range attrs {
+		raw = append(raw, a.Serialize()...)
+	}
+
+	req.AddRawData(raw)
+
+	_, err = req.Execute(unix.NETLINK_GENERIC, 0)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func FouDel(f Fou) error {
+	return pkgHandle.FouDel(f)
+}
+
+func (h *Handle) FouDel(f Fou) error {
+	fam_id, err := FouFamilyId()
+	if err != nil {
+		return err
+	}
+
+	req := h.newNetlinkRequest(fam_id, unix.NLM_F_ACK)
+
+	// int to byte for port
+	bp := make([]byte, 2)
+	binary.BigEndian.PutUint16(bp[0:2], uint16(f.Port))
+
+	attrs := []*nl.RtAttr{
+		nl.NewRtAttr(FOU_ATTR_PORT, bp),
+		nl.NewRtAttr(FOU_ATTR_AF, []byte{uint8(f.Family)}),
+	}
+	raw := []byte{FOU_CMD_DEL, 1, 0, 0}
+	for _, a := range attrs {
+		raw = append(raw, a.Serialize()...)
+	}
+
+	req.AddRawData(raw)
+
+	_, err = req.Execute(unix.NETLINK_GENERIC, 0)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func FouList(fam int) ([]Fou, error) {
+	return pkgHandle.FouList(fam)
+}
+
+func (h *Handle) FouList(fam int) ([]Fou, error) {
+	fam_id, err := FouFamilyId()
+	if err != nil {
+		return nil, err
+	}
+
+	req := h.newNetlinkRequest(fam_id, unix.NLM_F_DUMP)
+
+	attrs := []*nl.RtAttr{
+		nl.NewRtAttr(FOU_ATTR_AF, []byte{uint8(fam)}),
+	}
+	raw := []byte{FOU_CMD_GET, 1, 0, 0}
+	for _, a := range attrs {
+		raw = append(raw, a.Serialize()...)
+	}
+
+	req.AddRawData(raw)
+
+	msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
+	if err != nil {
+		return nil, err
+	}
+
+	fous := make([]Fou, 0, len(msgs))
+	for _, m := range msgs {
+		f, err := deserializeFouMsg(m)
+		if err != nil {
+			return fous, err
+		}
+
+		fous = append(fous, f)
+	}
+
+	return fous, nil
+}
+
+func deserializeFouMsg(msg []byte) (Fou, error) {
+	// we'll skip to byte 4 to first attribute
+	msg = msg[3:]
+	var shift int
+	fou := Fou{}
+
+	for {
+		// attribute header is at least 16 bits
+		if len(msg) < 4 {
+			return fou, ErrAttrHeaderTruncated
+		}
+
+		lgt := int(binary.BigEndian.Uint16(msg[0:2]))
+		if len(msg) < lgt+4 {
+			return fou, ErrAttrBodyTruncated
+		}
+		attr := binary.BigEndian.Uint16(msg[2:4])
+
+		shift = lgt + 3
+		switch attr {
+		case FOU_ATTR_AF:
+			fou.Family = int(msg[5])
+		case FOU_ATTR_PORT:
+			fou.Port = int(binary.BigEndian.Uint16(msg[5:7]))
+			// port is 2 bytes
+			shift = lgt + 2
+		case FOU_ATTR_IPPROTO:
+			fou.Protocol = int(msg[5])
+		case FOU_ATTR_TYPE:
+			fou.EncapType = int(msg[5])
+		}
+
+		msg = msg[shift:]
+
+		if len(msg) < 4 {
+			break
+		}
+	}
+
+	return fou, nil
+}

+ 15 - 0
vendor/github.com/vishvananda/netlink/fou_unspecified.go

@@ -0,0 +1,15 @@
+// +build !linux
+
+package netlink
+
+func FouAdd(f Fou) error {
+	return ErrNotImplemented
+}
+
+func FouDel(f Fou) error {
+	return ErrNotImplemented
+}
+
+func FouList(fam int) ([]Fou, error) {
+	return nil, ErrNotImplemented
+}

+ 4 - 3
vendor/github.com/vishvananda/netlink/genetlink_linux.go

@@ -5,6 +5,7 @@ import (
 	"syscall"
 
 	"github.com/vishvananda/netlink/nl"
+	"golang.org/x/sys/unix"
 )
 
 type GenlOp struct {
@@ -130,9 +131,9 @@ func (h *Handle) GenlFamilyList() ([]*GenlFamily, error) {
 		Command: nl.GENL_CTRL_CMD_GETFAMILY,
 		Version: nl.GENL_CTRL_VERSION,
 	}
-	req := h.newNetlinkRequest(nl.GENL_ID_CTRL, syscall.NLM_F_DUMP)
+	req := h.newNetlinkRequest(nl.GENL_ID_CTRL, unix.NLM_F_DUMP)
 	req.AddData(msg)
-	msgs, err := req.Execute(syscall.NETLINK_GENERIC, 0)
+	msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
 	if err != nil {
 		return nil, err
 	}
@@ -151,7 +152,7 @@ func (h *Handle) GenlFamilyGet(name string) (*GenlFamily, error) {
 	req := h.newNetlinkRequest(nl.GENL_ID_CTRL, 0)
 	req.AddData(msg)
 	req.AddData(nl.NewRtAttr(nl.GENL_CTRL_ATTR_FAMILY_NAME, nl.ZeroTerminated(name)))
-	msgs, err := req.Execute(syscall.NETLINK_GENERIC, 0)
+	msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
 	if err != nil {
 		return nil, err
 	}

+ 8 - 7
vendor/github.com/vishvananda/netlink/gtp_linux.go

@@ -7,6 +7,7 @@ import (
 	"syscall"
 
 	"github.com/vishvananda/netlink/nl"
+	"golang.org/x/sys/unix"
 )
 
 type PDP struct {
@@ -82,9 +83,9 @@ func (h *Handle) GTPPDPList() ([]*PDP, error) {
 		Command: nl.GENL_GTP_CMD_GETPDP,
 		Version: nl.GENL_GTP_VERSION,
 	}
-	req := h.newNetlinkRequest(int(f.ID), syscall.NLM_F_DUMP)
+	req := h.newNetlinkRequest(int(f.ID), unix.NLM_F_DUMP)
 	req.AddData(msg)
-	msgs, err := req.Execute(syscall.NETLINK_GENERIC, 0)
+	msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
 	if err != nil {
 		return nil, err
 	}
@@ -96,7 +97,7 @@ func GTPPDPList() ([]*PDP, error) {
 }
 
 func gtpPDPGet(req *nl.NetlinkRequest) (*PDP, error) {
-	msgs, err := req.Execute(syscall.NETLINK_GENERIC, 0)
+	msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
 	if err != nil {
 		return nil, err
 	}
@@ -182,7 +183,7 @@ func (h *Handle) GTPPDPAdd(link Link, pdp *PDP) error {
 		Command: nl.GENL_GTP_CMD_NEWPDP,
 		Version: nl.GENL_GTP_VERSION,
 	}
-	req := h.newNetlinkRequest(int(f.ID), syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
+	req := h.newNetlinkRequest(int(f.ID), unix.NLM_F_EXCL|unix.NLM_F_ACK)
 	req.AddData(msg)
 	req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_VERSION, nl.Uint32Attr(pdp.Version)))
 	req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_LINK, nl.Uint32Attr(uint32(link.Attrs().Index))))
@@ -199,7 +200,7 @@ func (h *Handle) GTPPDPAdd(link Link, pdp *PDP) error {
 	default:
 		return fmt.Errorf("unsupported GTP version: %d", pdp.Version)
 	}
-	_, err = req.Execute(syscall.NETLINK_GENERIC, 0)
+	_, err = req.Execute(unix.NETLINK_GENERIC, 0)
 	return err
 }
 
@@ -216,7 +217,7 @@ func (h *Handle) GTPPDPDel(link Link, pdp *PDP) error {
 		Command: nl.GENL_GTP_CMD_DELPDP,
 		Version: nl.GENL_GTP_VERSION,
 	}
-	req := h.newNetlinkRequest(int(f.ID), syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
+	req := h.newNetlinkRequest(int(f.ID), unix.NLM_F_EXCL|unix.NLM_F_ACK)
 	req.AddData(msg)
 	req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_VERSION, nl.Uint32Attr(pdp.Version)))
 	req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_LINK, nl.Uint32Attr(uint32(link.Attrs().Index))))
@@ -229,7 +230,7 @@ func (h *Handle) GTPPDPDel(link Link, pdp *PDP) error {
 	default:
 		return fmt.Errorf("unsupported GTP version: %d", pdp.Version)
 	}
-	_, err = req.Execute(syscall.NETLINK_GENERIC, 0)
+	_, err = req.Execute(unix.NETLINK_GENERIC, 0)
 	return err
 }
 

+ 9 - 9
vendor/github.com/vishvananda/netlink/handle_linux.go

@@ -2,11 +2,11 @@ package netlink
 
 import (
 	"fmt"
-	"syscall"
 	"time"
 
 	"github.com/vishvananda/netlink/nl"
 	"github.com/vishvananda/netns"
+	"golang.org/x/sys/unix"
 )
 
 // Empty handle used by the netlink package methods
@@ -43,7 +43,7 @@ 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())
+	tv := unix.NsecToTimeval(to.Nanoseconds())
 	for _, sh := range h.sockets {
 		if err := sh.Socket.SetSendTimeout(&tv); err != nil {
 			return err
@@ -59,13 +59,13 @@ func (h *Handle) SetSocketTimeout(to time.Duration) error {
 // socket in the netlink handle. The maximum value is capped by
 // /proc/sys/net/core/rmem_max.
 func (h *Handle) SetSocketReceiveBufferSize(size int, force bool) error {
-	opt := syscall.SO_RCVBUF
+	opt := unix.SO_RCVBUF
 	if force {
-		opt = syscall.SO_RCVBUFFORCE
+		opt = unix.SO_RCVBUFFORCE
 	}
 	for _, sh := range h.sockets {
 		fd := sh.Socket.GetFd()
-		err := syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, opt, size)
+		err := unix.SetsockoptInt(fd, unix.SOL_SOCKET, opt, size)
 		if err != nil {
 			return err
 		}
@@ -81,7 +81,7 @@ func (h *Handle) GetSocketReceiveBufferSize() ([]int, error) {
 	i := 0
 	for _, sh := range h.sockets {
 		fd := sh.Socket.GetFd()
-		size, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_RCVBUF)
+		size, err := unix.GetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_RCVBUF)
 		if err != nil {
 			return nil, err
 		}
@@ -134,10 +134,10 @@ func (h *Handle) newNetlinkRequest(proto, flags int) *nl.NetlinkRequest {
 		return nl.NewNetlinkRequest(proto, flags)
 	}
 	return &nl.NetlinkRequest{
-		NlMsghdr: syscall.NlMsghdr{
-			Len:   uint32(syscall.SizeofNlMsghdr),
+		NlMsghdr: unix.NlMsghdr{
+			Len:   uint32(unix.SizeofNlMsghdr),
 			Type:  uint16(proto),
-			Flags: syscall.NLM_F_REQUEST | uint16(flags),
+			Flags: unix.NLM_F_REQUEST | uint16(flags),
 		},
 		Sockets: h.sockets,
 	}

+ 36 - 0
vendor/github.com/vishvananda/netlink/handle_unspecified.go

@@ -220,3 +220,39 @@ func (h *Handle) NeighList(linkIndex, family int) ([]Neigh, error) {
 func (h *Handle) NeighProxyList(linkIndex, family int) ([]Neigh, error) {
 	return nil, ErrNotImplemented
 }
+
+func (h *Handle) RouteAdd(route *Route) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) RouteDel(route *Route) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) RouteGet(destination net.IP) ([]Route, error) {
+	return nil, ErrNotImplemented
+}
+
+func (h *Handle) RouteList(link Link, family int) ([]Route, error) {
+	return nil, ErrNotImplemented
+}
+
+func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64) ([]Route, error) {
+	return nil, ErrNotImplemented
+}
+
+func (h *Handle) RouteReplace(route *Route) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) RuleAdd(rule *Rule) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) RuleDel(rule *Rule) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) RuleList(family int) ([]Rule, error) {
+	return nil, ErrNotImplemented
+}

+ 98 - 0
vendor/github.com/vishvananda/netlink/ioctl_linux.go

@@ -0,0 +1,98 @@
+package netlink
+
+import (
+	"syscall"
+	"unsafe"
+
+	"golang.org/x/sys/unix"
+)
+
+// ioctl for statistics.
+const (
+	// ETHTOOL_GSSET_INFO gets string set info
+	ETHTOOL_GSSET_INFO = 0x00000037
+	// SIOCETHTOOL is Ethtool interface
+	SIOCETHTOOL = 0x8946
+	// ETHTOOL_GSTRINGS gets specified string set
+	ETHTOOL_GSTRINGS = 0x0000001b
+	// ETHTOOL_GSTATS gets NIC-specific statistics
+	ETHTOOL_GSTATS = 0x0000001d
+)
+
+// string set id.
+const (
+	// ETH_SS_TEST is self-test result names, for use with %ETHTOOL_TEST
+	ETH_SS_TEST = iota
+	// ETH_SS_STATS statistic names, for use with %ETHTOOL_GSTATS
+	ETH_SS_STATS
+	// ETH_SS_PRIV_FLAGS are driver private flag names
+	ETH_SS_PRIV_FLAGS
+	// _ETH_SS_NTUPLE_FILTERS is deprecated
+	_ETH_SS_NTUPLE_FILTERS
+	// ETH_SS_FEATURES are device feature names
+	ETH_SS_FEATURES
+	// ETH_SS_RSS_HASH_FUNCS is RSS hush function names
+	ETH_SS_RSS_HASH_FUNCS
+)
+
+// IfreqSlave is a struct for ioctl bond manipulation syscalls.
+// It is used to assign slave to bond interface with Name.
+type IfreqSlave struct {
+	Name  [unix.IFNAMSIZ]byte
+	Slave [unix.IFNAMSIZ]byte
+}
+
+// Ifreq is a struct for ioctl ethernet manipulation syscalls.
+type Ifreq struct {
+	Name [unix.IFNAMSIZ]byte
+	Data uintptr
+}
+
+// ethtoolSset is a string set information
+type ethtoolSset struct {
+	cmd      uint32
+	reserved uint32
+	mask     uint64
+	data     [1]uint32
+}
+
+// ethtoolGstrings is string set for data tagging
+type ethtoolGstrings struct {
+	cmd       uint32
+	stringSet uint32
+	length    uint32
+	data      [32]byte
+}
+
+type ethtoolStats struct {
+	cmd    uint32
+	nStats uint32
+	data   [1]uint64
+}
+
+// newIocltSlaveReq returns filled IfreqSlave with proper interface names
+// It is used by ioctl to assign slave to bond master
+func newIocltSlaveReq(slave, master string) *IfreqSlave {
+	ifreq := &IfreqSlave{}
+	copy(ifreq.Name[:unix.IFNAMSIZ-1], master)
+	copy(ifreq.Slave[:unix.IFNAMSIZ-1], slave)
+	return ifreq
+}
+
+// newIocltStringSetReq creates request to get interface string set
+func newIocltStringSetReq(linkName string) (*Ifreq, *ethtoolSset) {
+	e := &ethtoolSset{
+		cmd:  ETHTOOL_GSSET_INFO,
+		mask: 1 << ETH_SS_STATS,
+	}
+
+	ifreq := &Ifreq{Data: uintptr(unsafe.Pointer(e))}
+	copy(ifreq.Name[:unix.IFNAMSIZ-1], linkName)
+	return ifreq, e
+}
+
+// getSocketUDP returns file descriptor to new UDP socket
+// It is used for communication with ioctl interface.
+func getSocketUDP() (int, error) {
+	return syscall.Socket(unix.AF_INET, unix.SOCK_DGRAM, 0)
+}

+ 85 - 38
vendor/github.com/vishvananda/netlink/link.go

@@ -3,6 +3,7 @@ package netlink
 import (
 	"fmt"
 	"net"
+	"os"
 )
 
 // Link represents a link device from netlink. Shared link attributes
@@ -38,6 +39,8 @@ type LinkAttrs struct {
 	Protinfo     *Protinfo
 	OperState    LinkOperState
 	NetNsID      int
+	NumTxQueues  int
+	NumRxQueues  int
 }
 
 // LinkOperState represents the values of the IFLA_OPERSTATE link
@@ -259,6 +262,9 @@ const (
 type Macvlan struct {
 	LinkAttrs
 	Mode MacvlanMode
+
+	// MACAddrs is only populated for Macvlan SOURCE links
+	MACAddrs []net.HardwareAddr
 }
 
 func (macvlan *Macvlan) Attrs() *LinkAttrs {
@@ -284,8 +290,10 @@ type TuntapFlag uint16
 // Tuntap links created via /dev/tun/tap, but can be destroyed via netlink
 type Tuntap struct {
 	LinkAttrs
-	Mode  TuntapMode
-	Flags TuntapFlag
+	Mode   TuntapMode
+	Flags  TuntapFlag
+	Queues int
+	Fds    []*os.File
 }
 
 func (tuntap *Tuntap) Attrs() *LinkAttrs {
@@ -327,26 +335,28 @@ func (generic *GenericLink) Type() string {
 
 type Vxlan struct {
 	LinkAttrs
-	VxlanId      int
-	VtepDevIndex int
-	SrcAddr      net.IP
-	Group        net.IP
-	TTL          int
-	TOS          int
-	Learning     bool
-	Proxy        bool
-	RSC          bool
-	L2miss       bool
-	L3miss       bool
-	UDPCSum      bool
-	NoAge        bool
-	GBP          bool
-	FlowBased    bool
-	Age          int
-	Limit        int
-	Port         int
-	PortLow      int
-	PortHigh     int
+	VxlanId        int
+	VtepDevIndex   int
+	SrcAddr        net.IP
+	Group          net.IP
+	TTL            int
+	TOS            int
+	Learning       bool
+	Proxy          bool
+	RSC            bool
+	L2miss         bool
+	L3miss         bool
+	UDPCSum        bool
+	UDP6ZeroCSumTx bool
+	UDP6ZeroCSumRx bool
+	NoAge          bool
+	GBP            bool
+	FlowBased      bool
+	Age            int
+	Limit          int
+	Port           int
+	PortLow        int
+	PortHigh       int
 }
 
 func (vxlan *Vxlan) Attrs() *LinkAttrs {
@@ -695,17 +705,25 @@ func (gretap *Gretap) Attrs() *LinkAttrs {
 }
 
 func (gretap *Gretap) Type() string {
+	if gretap.Local.To4() == nil {
+		return "ip6gretap"
+	}
 	return "gretap"
 }
 
 type Iptun struct {
 	LinkAttrs
-	Ttl      uint8
-	Tos      uint8
-	PMtuDisc uint8
-	Link     uint32
-	Local    net.IP
-	Remote   net.IP
+	Ttl        uint8
+	Tos        uint8
+	PMtuDisc   uint8
+	Link       uint32
+	Local      net.IP
+	Remote     net.IP
+	EncapSport uint16
+	EncapDport uint16
+	EncapType  uint16
+	EncapFlags uint16
+	FlowBased  bool
 }
 
 func (iptun *Iptun) Attrs() *LinkAttrs {
@@ -716,6 +734,28 @@ func (iptun *Iptun) Type() string {
 	return "ipip"
 }
 
+type Sittun struct {
+	LinkAttrs
+	Link       uint32
+	Local      net.IP
+	Remote     net.IP
+	Ttl        uint8
+	Tos        uint8
+	PMtuDisc   uint8
+	EncapType  uint16
+	EncapFlags uint16
+	EncapSport uint16
+	EncapDport uint16
+}
+
+func (sittun *Sittun) Attrs() *LinkAttrs {
+	return &sittun.LinkAttrs
+}
+
+func (sittun *Sittun) Type() string {
+	return "sit"
+}
+
 type Vti struct {
 	LinkAttrs
 	IKey   uint32
@@ -735,16 +775,20 @@ func (iptun *Vti) Type() string {
 
 type Gretun struct {
 	LinkAttrs
-	Link     uint32
-	IFlags   uint16
-	OFlags   uint16
-	IKey     uint32
-	OKey     uint32
-	Local    net.IP
-	Remote   net.IP
-	Ttl      uint8
-	Tos      uint8
-	PMtuDisc uint8
+	Link       uint32
+	IFlags     uint16
+	OFlags     uint16
+	IKey       uint32
+	OKey       uint32
+	Local      net.IP
+	Remote     net.IP
+	Ttl        uint8
+	Tos        uint8
+	PMtuDisc   uint8
+	EncapType  uint16
+	EncapFlags uint16
+	EncapSport uint16
+	EncapDport uint16
 }
 
 func (gretun *Gretun) Attrs() *LinkAttrs {
@@ -752,6 +796,9 @@ func (gretun *Gretun) Attrs() *LinkAttrs {
 }
 
 func (gretun *Gretun) Type() string {
+	if gretun.Local.To4() == nil {
+		return "ip6gre"
+	}
 	return "gre"
 }
 

File diff suppressed because it is too large
+ 309 - 165
vendor/github.com/vishvananda/netlink/link_linux.go


+ 2 - 0
vendor/github.com/vishvananda/netlink/neigh.go

@@ -15,6 +15,8 @@ type Neigh struct {
 	IP           net.IP
 	HardwareAddr net.HardwareAddr
 	LLIPAddr     net.IP //Used in the case of NHRP
+	Vlan         int
+	VNI          int
 }
 
 // String returns $ip/$hwaddr $label

+ 24 - 10
vendor/github.com/vishvananda/netlink/neigh_linux.go

@@ -2,10 +2,10 @@ package netlink
 
 import (
 	"net"
-	"syscall"
 	"unsafe"
 
 	"github.com/vishvananda/netlink/nl"
+	"golang.org/x/sys/unix"
 )
 
 const (
@@ -73,7 +73,7 @@ func NeighAdd(neigh *Neigh) error {
 // NeighAdd will add an IP to MAC mapping to the ARP table
 // Equivalent to: `ip neigh add ....`
 func (h *Handle) NeighAdd(neigh *Neigh) error {
-	return h.neighAdd(neigh, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL)
+	return h.neighAdd(neigh, unix.NLM_F_CREATE|unix.NLM_F_EXCL)
 }
 
 // NeighSet will add or replace an IP to MAC mapping to the ARP table
@@ -85,7 +85,7 @@ func NeighSet(neigh *Neigh) error {
 // NeighSet will add or replace an IP to MAC mapping to the ARP table
 // Equivalent to: `ip neigh replace....`
 func (h *Handle) NeighSet(neigh *Neigh) error {
-	return h.neighAdd(neigh, syscall.NLM_F_CREATE|syscall.NLM_F_REPLACE)
+	return h.neighAdd(neigh, unix.NLM_F_CREATE|unix.NLM_F_REPLACE)
 }
 
 // NeighAppend will append an entry to FDB
@@ -97,7 +97,7 @@ func NeighAppend(neigh *Neigh) error {
 // NeighAppend will append an entry to FDB
 // Equivalent to: `bridge fdb append...`
 func (h *Handle) NeighAppend(neigh *Neigh) error {
-	return h.neighAdd(neigh, syscall.NLM_F_CREATE|syscall.NLM_F_APPEND)
+	return h.neighAdd(neigh, unix.NLM_F_CREATE|unix.NLM_F_APPEND)
 }
 
 // NeighAppend will append an entry to FDB
@@ -109,7 +109,7 @@ func neighAdd(neigh *Neigh, mode int) error {
 // NeighAppend will append an entry to FDB
 // Equivalent to: `bridge fdb append...`
 func (h *Handle) neighAdd(neigh *Neigh, mode int) error {
-	req := h.newNetlinkRequest(syscall.RTM_NEWNEIGH, mode|syscall.NLM_F_ACK)
+	req := h.newNetlinkRequest(unix.RTM_NEWNEIGH, mode|unix.NLM_F_ACK)
 	return neighHandle(neigh, req)
 }
 
@@ -122,7 +122,7 @@ func NeighDel(neigh *Neigh) error {
 // NeighDel will delete an IP address from a link device.
 // Equivalent to: `ip addr del $addr dev $link`
 func (h *Handle) NeighDel(neigh *Neigh) error {
-	req := h.newNetlinkRequest(syscall.RTM_DELNEIGH, syscall.NLM_F_ACK)
+	req := h.newNetlinkRequest(unix.RTM_DELNEIGH, unix.NLM_F_ACK)
 	return neighHandle(neigh, req)
 }
 
@@ -160,7 +160,17 @@ func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error {
 		req.AddData(hwData)
 	}
 
-	_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
+	if neigh.Vlan != 0 {
+		vlanData := nl.NewRtAttr(NDA_VLAN, nl.Uint16Attr(uint16(neigh.Vlan)))
+		req.AddData(vlanData)
+	}
+
+	if neigh.VNI != 0 {
+		vniData := nl.NewRtAttr(NDA_VNI, nl.Uint32Attr(uint32(neigh.VNI)))
+		req.AddData(vniData)
+	}
+
+	_, err := req.Execute(unix.NETLINK_ROUTE, 0)
 	return err
 }
 
@@ -193,7 +203,7 @@ func (h *Handle) NeighProxyList(linkIndex, family int) ([]Neigh, error) {
 }
 
 func (h *Handle) neighList(linkIndex, family, flags int) ([]Neigh, error) {
-	req := h.newNetlinkRequest(syscall.RTM_GETNEIGH, syscall.NLM_F_DUMP)
+	req := h.newNetlinkRequest(unix.RTM_GETNEIGH, unix.NLM_F_DUMP)
 	msg := Ndmsg{
 		Family: uint8(family),
 		Index:  uint32(linkIndex),
@@ -201,7 +211,7 @@ func (h *Handle) neighList(linkIndex, family, flags int) ([]Neigh, error) {
 	}
 	req.AddData(&msg)
 
-	msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWNEIGH)
+	msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWNEIGH)
 	if err != nil {
 		return nil, err
 	}
@@ -257,7 +267,7 @@ func NeighDeserialize(m []byte) (*Neigh, error) {
 			// BUG: Is this a bug in the netlink library?
 			// #define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len))
 			// #define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
-			attrLen := attr.Attr.Len - syscall.SizeofRtAttr
+			attrLen := attr.Attr.Len - unix.SizeofRtAttr
 			if attrLen == 4 && (encapType == "ipip" ||
 				encapType == "sit" ||
 				encapType == "gre") {
@@ -268,6 +278,10 @@ func NeighDeserialize(m []byte) (*Neigh, error) {
 			} else {
 				neigh.HardwareAddr = net.HardwareAddr(attr.Value)
 			}
+		case NDA_VLAN:
+			neigh.Vlan = int(native.Uint16(attr.Value[0:2]))
+		case NDA_VNI:
+			neigh.VNI = int(native.Uint32(attr.Value[0:4]))
 		}
 	}
 

+ 7 - 6
vendor/github.com/vishvananda/netlink/nl/addr_linux.go

@@ -1,17 +1,18 @@
 package nl
 
 import (
-	"syscall"
 	"unsafe"
+
+	"golang.org/x/sys/unix"
 )
 
 type IfAddrmsg struct {
-	syscall.IfAddrmsg
+	unix.IfAddrmsg
 }
 
 func NewIfAddrmsg(family int) *IfAddrmsg {
 	return &IfAddrmsg{
-		IfAddrmsg: syscall.IfAddrmsg{
+		IfAddrmsg: unix.IfAddrmsg{
 			Family: uint8(family),
 		},
 	}
@@ -35,15 +36,15 @@ func NewIfAddrmsg(family int) *IfAddrmsg {
 // SizeofIfAddrmsg     = 0x8
 
 func DeserializeIfAddrmsg(b []byte) *IfAddrmsg {
-	return (*IfAddrmsg)(unsafe.Pointer(&b[0:syscall.SizeofIfAddrmsg][0]))
+	return (*IfAddrmsg)(unsafe.Pointer(&b[0:unix.SizeofIfAddrmsg][0]))
 }
 
 func (msg *IfAddrmsg) Serialize() []byte {
-	return (*(*[syscall.SizeofIfAddrmsg]byte)(unsafe.Pointer(msg)))[:]
+	return (*(*[unix.SizeofIfAddrmsg]byte)(unsafe.Pointer(msg)))[:]
 }
 
 func (msg *IfAddrmsg) Len() int {
-	return syscall.SizeofIfAddrmsg
+	return unix.SizeofIfAddrmsg
 }
 
 // struct ifa_cacheinfo {

+ 17 - 25
vendor/github.com/vishvananda/netlink/nl/link_linux.go

@@ -1,35 +1,11 @@
 package nl
 
 import (
-	"syscall"
 	"unsafe"
 )
 
 const (
 	DEFAULT_CHANGE = 0xFFFFFFFF
-	// doesn't exist in syscall
-	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 (
@@ -118,6 +94,10 @@ const (
 	IFLA_MACVLAN_UNSPEC = iota
 	IFLA_MACVLAN_MODE
 	IFLA_MACVLAN_FLAGS
+	IFLA_MACVLAN_MACADDR_MODE
+	IFLA_MACVLAN_MACADDR
+	IFLA_MACVLAN_MACADDR_DATA
+	IFLA_MACVLAN_MACADDR_COUNT
 	IFLA_MACVLAN_MAX = IFLA_MACVLAN_FLAGS
 )
 
@@ -129,6 +109,13 @@ const (
 	MACVLAN_MODE_SOURCE   = 16
 )
 
+const (
+	MACVLAN_MACADDR_ADD = iota
+	MACVLAN_MACADDR_DEL
+	MACVLAN_MACADDR_FLUSH
+	MACVLAN_MACADDR_SET
+)
+
 const (
 	IFLA_BOND_UNSPEC = iota
 	IFLA_BOND_MODE
@@ -475,7 +462,12 @@ const (
 	IFLA_IPTUN_6RD_RELAY_PREFIX
 	IFLA_IPTUN_6RD_PREFIXLEN
 	IFLA_IPTUN_6RD_RELAY_PREFIXLEN
-	IFLA_IPTUN_MAX = IFLA_IPTUN_6RD_RELAY_PREFIXLEN
+	IFLA_IPTUN_ENCAP_TYPE
+	IFLA_IPTUN_ENCAP_FLAGS
+	IFLA_IPTUN_ENCAP_SPORT
+	IFLA_IPTUN_ENCAP_DPORT
+	IFLA_IPTUN_COLLECT_METADATA
+	IFLA_IPTUN_MAX = IFLA_IPTUN_COLLECT_METADATA
 )
 
 const (

+ 121 - 115
vendor/github.com/vishvananda/netlink/nl/nl_linux.go

@@ -13,18 +13,19 @@ import (
 	"unsafe"
 
 	"github.com/vishvananda/netns"
+	"golang.org/x/sys/unix"
 )
 
 const (
 	// Family type definitions
-	FAMILY_ALL  = syscall.AF_UNSPEC
-	FAMILY_V4   = syscall.AF_INET
-	FAMILY_V6   = syscall.AF_INET6
+	FAMILY_ALL  = unix.AF_UNSPEC
+	FAMILY_V4   = unix.AF_INET
+	FAMILY_V6   = unix.AF_INET6
 	FAMILY_MPLS = AF_MPLS
 )
 
 // SupportedNlFamilies contains the list of netlink families this netlink package supports
-var SupportedNlFamilies = []int{syscall.NETLINK_ROUTE, syscall.NETLINK_XFRM, syscall.NETLINK_NETFILTER}
+var SupportedNlFamilies = []int{unix.NETLINK_ROUTE, unix.NETLINK_XFRM, unix.NETLINK_NETFILTER}
 
 var nextSeqNr uint32
 
@@ -77,161 +78,161 @@ type NetlinkRequestData interface {
 
 // IfInfomsg is related to links, but it is used for list requests as well
 type IfInfomsg struct {
-	syscall.IfInfomsg
+	unix.IfInfomsg
 }
 
 // Create an IfInfomsg with family specified
 func NewIfInfomsg(family int) *IfInfomsg {
 	return &IfInfomsg{
-		IfInfomsg: syscall.IfInfomsg{
+		IfInfomsg: unix.IfInfomsg{
 			Family: uint8(family),
 		},
 	}
 }
 
 func DeserializeIfInfomsg(b []byte) *IfInfomsg {
-	return (*IfInfomsg)(unsafe.Pointer(&b[0:syscall.SizeofIfInfomsg][0]))
+	return (*IfInfomsg)(unsafe.Pointer(&b[0:unix.SizeofIfInfomsg][0]))
 }
 
 func (msg *IfInfomsg) Serialize() []byte {
-	return (*(*[syscall.SizeofIfInfomsg]byte)(unsafe.Pointer(msg)))[:]
+	return (*(*[unix.SizeofIfInfomsg]byte)(unsafe.Pointer(msg)))[:]
 }
 
 func (msg *IfInfomsg) Len() int {
-	return syscall.SizeofIfInfomsg
+	return unix.SizeofIfInfomsg
 }
 
 func (msg *IfInfomsg) EncapType() string {
 	switch msg.Type {
 	case 0:
 		return "generic"
-	case syscall.ARPHRD_ETHER:
+	case unix.ARPHRD_ETHER:
 		return "ether"
-	case syscall.ARPHRD_EETHER:
+	case unix.ARPHRD_EETHER:
 		return "eether"
-	case syscall.ARPHRD_AX25:
+	case unix.ARPHRD_AX25:
 		return "ax25"
-	case syscall.ARPHRD_PRONET:
+	case unix.ARPHRD_PRONET:
 		return "pronet"
-	case syscall.ARPHRD_CHAOS:
+	case unix.ARPHRD_CHAOS:
 		return "chaos"
-	case syscall.ARPHRD_IEEE802:
+	case unix.ARPHRD_IEEE802:
 		return "ieee802"
-	case syscall.ARPHRD_ARCNET:
+	case unix.ARPHRD_ARCNET:
 		return "arcnet"
-	case syscall.ARPHRD_APPLETLK:
+	case unix.ARPHRD_APPLETLK:
 		return "atalk"
-	case syscall.ARPHRD_DLCI:
+	case unix.ARPHRD_DLCI:
 		return "dlci"
-	case syscall.ARPHRD_ATM:
+	case unix.ARPHRD_ATM:
 		return "atm"
-	case syscall.ARPHRD_METRICOM:
+	case unix.ARPHRD_METRICOM:
 		return "metricom"
-	case syscall.ARPHRD_IEEE1394:
+	case unix.ARPHRD_IEEE1394:
 		return "ieee1394"
-	case syscall.ARPHRD_INFINIBAND:
+	case unix.ARPHRD_INFINIBAND:
 		return "infiniband"
-	case syscall.ARPHRD_SLIP:
+	case unix.ARPHRD_SLIP:
 		return "slip"
-	case syscall.ARPHRD_CSLIP:
+	case unix.ARPHRD_CSLIP:
 		return "cslip"
-	case syscall.ARPHRD_SLIP6:
+	case unix.ARPHRD_SLIP6:
 		return "slip6"
-	case syscall.ARPHRD_CSLIP6:
+	case unix.ARPHRD_CSLIP6:
 		return "cslip6"
-	case syscall.ARPHRD_RSRVD:
+	case unix.ARPHRD_RSRVD:
 		return "rsrvd"
-	case syscall.ARPHRD_ADAPT:
+	case unix.ARPHRD_ADAPT:
 		return "adapt"
-	case syscall.ARPHRD_ROSE:
+	case unix.ARPHRD_ROSE:
 		return "rose"
-	case syscall.ARPHRD_X25:
+	case unix.ARPHRD_X25:
 		return "x25"
-	case syscall.ARPHRD_HWX25:
+	case unix.ARPHRD_HWX25:
 		return "hwx25"
-	case syscall.ARPHRD_PPP:
+	case unix.ARPHRD_PPP:
 		return "ppp"
-	case syscall.ARPHRD_HDLC:
+	case unix.ARPHRD_HDLC:
 		return "hdlc"
-	case syscall.ARPHRD_LAPB:
+	case unix.ARPHRD_LAPB:
 		return "lapb"
-	case syscall.ARPHRD_DDCMP:
+	case unix.ARPHRD_DDCMP:
 		return "ddcmp"
-	case syscall.ARPHRD_RAWHDLC:
+	case unix.ARPHRD_RAWHDLC:
 		return "rawhdlc"
-	case syscall.ARPHRD_TUNNEL:
+	case unix.ARPHRD_TUNNEL:
 		return "ipip"
-	case syscall.ARPHRD_TUNNEL6:
+	case unix.ARPHRD_TUNNEL6:
 		return "tunnel6"
-	case syscall.ARPHRD_FRAD:
+	case unix.ARPHRD_FRAD:
 		return "frad"
-	case syscall.ARPHRD_SKIP:
+	case unix.ARPHRD_SKIP:
 		return "skip"
-	case syscall.ARPHRD_LOOPBACK:
+	case unix.ARPHRD_LOOPBACK:
 		return "loopback"
-	case syscall.ARPHRD_LOCALTLK:
+	case unix.ARPHRD_LOCALTLK:
 		return "ltalk"
-	case syscall.ARPHRD_FDDI:
+	case unix.ARPHRD_FDDI:
 		return "fddi"
-	case syscall.ARPHRD_BIF:
+	case unix.ARPHRD_BIF:
 		return "bif"
-	case syscall.ARPHRD_SIT:
+	case unix.ARPHRD_SIT:
 		return "sit"
-	case syscall.ARPHRD_IPDDP:
+	case unix.ARPHRD_IPDDP:
 		return "ip/ddp"
-	case syscall.ARPHRD_IPGRE:
+	case unix.ARPHRD_IPGRE:
 		return "gre"
-	case syscall.ARPHRD_PIMREG:
+	case unix.ARPHRD_PIMREG:
 		return "pimreg"
-	case syscall.ARPHRD_HIPPI:
+	case unix.ARPHRD_HIPPI:
 		return "hippi"
-	case syscall.ARPHRD_ASH:
+	case unix.ARPHRD_ASH:
 		return "ash"
-	case syscall.ARPHRD_ECONET:
+	case unix.ARPHRD_ECONET:
 		return "econet"
-	case syscall.ARPHRD_IRDA:
+	case unix.ARPHRD_IRDA:
 		return "irda"
-	case syscall.ARPHRD_FCPP:
+	case unix.ARPHRD_FCPP:
 		return "fcpp"
-	case syscall.ARPHRD_FCAL:
+	case unix.ARPHRD_FCAL:
 		return "fcal"
-	case syscall.ARPHRD_FCPL:
+	case unix.ARPHRD_FCPL:
 		return "fcpl"
-	case syscall.ARPHRD_FCFABRIC:
+	case unix.ARPHRD_FCFABRIC:
 		return "fcfb0"
-	case syscall.ARPHRD_FCFABRIC + 1:
+	case unix.ARPHRD_FCFABRIC + 1:
 		return "fcfb1"
-	case syscall.ARPHRD_FCFABRIC + 2:
+	case unix.ARPHRD_FCFABRIC + 2:
 		return "fcfb2"
-	case syscall.ARPHRD_FCFABRIC + 3:
+	case unix.ARPHRD_FCFABRIC + 3:
 		return "fcfb3"
-	case syscall.ARPHRD_FCFABRIC + 4:
+	case unix.ARPHRD_FCFABRIC + 4:
 		return "fcfb4"
-	case syscall.ARPHRD_FCFABRIC + 5:
+	case unix.ARPHRD_FCFABRIC + 5:
 		return "fcfb5"
-	case syscall.ARPHRD_FCFABRIC + 6:
+	case unix.ARPHRD_FCFABRIC + 6:
 		return "fcfb6"
-	case syscall.ARPHRD_FCFABRIC + 7:
+	case unix.ARPHRD_FCFABRIC + 7:
 		return "fcfb7"
-	case syscall.ARPHRD_FCFABRIC + 8:
+	case unix.ARPHRD_FCFABRIC + 8:
 		return "fcfb8"
-	case syscall.ARPHRD_FCFABRIC + 9:
+	case unix.ARPHRD_FCFABRIC + 9:
 		return "fcfb9"
-	case syscall.ARPHRD_FCFABRIC + 10:
+	case unix.ARPHRD_FCFABRIC + 10:
 		return "fcfb10"
-	case syscall.ARPHRD_FCFABRIC + 11:
+	case unix.ARPHRD_FCFABRIC + 11:
 		return "fcfb11"
-	case syscall.ARPHRD_FCFABRIC + 12:
+	case unix.ARPHRD_FCFABRIC + 12:
 		return "fcfb12"
-	case syscall.ARPHRD_IEEE802_TR:
+	case unix.ARPHRD_IEEE802_TR:
 		return "tr"
-	case syscall.ARPHRD_IEEE80211:
+	case unix.ARPHRD_IEEE80211:
 		return "ieee802.11"
-	case syscall.ARPHRD_IEEE80211_PRISM:
+	case unix.ARPHRD_IEEE80211_PRISM:
 		return "ieee802.11/prism"
-	case syscall.ARPHRD_IEEE80211_RADIOTAP:
+	case unix.ARPHRD_IEEE80211_RADIOTAP:
 		return "ieee802.11/radiotap"
-	case syscall.ARPHRD_IEEE802154:
+	case unix.ARPHRD_IEEE802154:
 		return "ieee802.15.4"
 
 	case 65534:
@@ -243,7 +244,7 @@ func (msg *IfInfomsg) EncapType() string {
 }
 
 func rtaAlignOf(attrlen int) int {
-	return (attrlen + syscall.RTA_ALIGNTO - 1) & ^(syscall.RTA_ALIGNTO - 1)
+	return (attrlen + unix.RTA_ALIGNTO - 1) & ^(unix.RTA_ALIGNTO - 1)
 }
 
 func NewIfInfomsgChild(parent *RtAttr, family int) *IfInfomsg {
@@ -254,7 +255,7 @@ func NewIfInfomsgChild(parent *RtAttr, family int) *IfInfomsg {
 
 // Extend RtAttr to handle data and children
 type RtAttr struct {
-	syscall.RtAttr
+	unix.RtAttr
 	Data     []byte
 	children []NetlinkRequestData
 }
@@ -262,7 +263,7 @@ type RtAttr struct {
 // Create a new Extended RtAttr object
 func NewRtAttr(attrType int, data []byte) *RtAttr {
 	return &RtAttr{
-		RtAttr: syscall.RtAttr{
+		RtAttr: unix.RtAttr{
 			Type: uint16(attrType),
 		},
 		children: []NetlinkRequestData{},
@@ -277,16 +278,21 @@ func NewRtAttrChild(parent *RtAttr, attrType int, data []byte) *RtAttr {
 	return attr
 }
 
+// AddChild adds an existing RtAttr as a child.
+func (a *RtAttr) AddChild(attr *RtAttr) {
+	a.children = append(a.children, attr)
+}
+
 func (a *RtAttr) Len() int {
 	if len(a.children) == 0 {
-		return (syscall.SizeofRtAttr + len(a.Data))
+		return (unix.SizeofRtAttr + len(a.Data))
 	}
 
 	l := 0
 	for _, child := range a.children {
 		l += rtaAlignOf(child.Len())
 	}
-	l += syscall.SizeofRtAttr
+	l += unix.SizeofRtAttr
 	return rtaAlignOf(l + len(a.Data))
 }
 
@@ -319,7 +325,7 @@ func (a *RtAttr) Serialize() []byte {
 }
 
 type NetlinkRequest struct {
-	syscall.NlMsghdr
+	unix.NlMsghdr
 	Data    []NetlinkRequestData
 	RawData []byte
 	Sockets map[int]*SocketHandle
@@ -327,7 +333,7 @@ type NetlinkRequest struct {
 
 // Serialize the Netlink Request into a byte array
 func (req *NetlinkRequest) Serialize() []byte {
-	length := syscall.SizeofNlMsghdr
+	length := unix.SizeofNlMsghdr
 	dataBytes := make([][]byte, len(req.Data))
 	for i, data := range req.Data {
 		dataBytes[i] = data.Serialize()
@@ -337,8 +343,8 @@ func (req *NetlinkRequest) Serialize() []byte {
 
 	req.Len = uint32(length)
 	b := make([]byte, length)
-	hdr := (*(*[syscall.SizeofNlMsghdr]byte)(unsafe.Pointer(req)))[:]
-	next := syscall.SizeofNlMsghdr
+	hdr := (*(*[unix.SizeofNlMsghdr]byte)(unsafe.Pointer(req)))[:]
+	next := unix.SizeofNlMsghdr
 	copy(b[0:next], hdr)
 	for _, data := range dataBytes {
 		for _, dataByte := range data {
@@ -421,10 +427,10 @@ done:
 			if m.Header.Pid != pid {
 				return nil, fmt.Errorf("Wrong pid %d, expected %d", m.Header.Pid, pid)
 			}
-			if m.Header.Type == syscall.NLMSG_DONE {
+			if m.Header.Type == unix.NLMSG_DONE {
 				break done
 			}
-			if m.Header.Type == syscall.NLMSG_ERROR {
+			if m.Header.Type == unix.NLMSG_ERROR {
 				native := NativeEndian()
 				error := int32(native.Uint32(m.Data[0:4]))
 				if error == 0 {
@@ -436,7 +442,7 @@ done:
 				continue
 			}
 			res = append(res, m.Data)
-			if m.Header.Flags&syscall.NLM_F_MULTI == 0 {
+			if m.Header.Flags&unix.NLM_F_MULTI == 0 {
 				break done
 			}
 		}
@@ -449,10 +455,10 @@ done:
 // the message is serialized
 func NewNetlinkRequest(proto, flags int) *NetlinkRequest {
 	return &NetlinkRequest{
-		NlMsghdr: syscall.NlMsghdr{
-			Len:   uint32(syscall.SizeofNlMsghdr),
+		NlMsghdr: unix.NlMsghdr{
+			Len:   uint32(unix.SizeofNlMsghdr),
 			Type:  uint16(proto),
-			Flags: syscall.NLM_F_REQUEST | uint16(flags),
+			Flags: unix.NLM_F_REQUEST | uint16(flags),
 			Seq:   atomic.AddUint32(&nextSeqNr, 1),
 		},
 	}
@@ -460,21 +466,21 @@ func NewNetlinkRequest(proto, flags int) *NetlinkRequest {
 
 type NetlinkSocket struct {
 	fd  int32
-	lsa syscall.SockaddrNetlink
+	lsa unix.SockaddrNetlink
 	sync.Mutex
 }
 
 func getNetlinkSocket(protocol int) (*NetlinkSocket, error) {
-	fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW|syscall.SOCK_CLOEXEC, protocol)
+	fd, err := unix.Socket(unix.AF_NETLINK, unix.SOCK_RAW|unix.SOCK_CLOEXEC, protocol)
 	if err != nil {
 		return nil, err
 	}
 	s := &NetlinkSocket{
 		fd: int32(fd),
 	}
-	s.lsa.Family = syscall.AF_NETLINK
-	if err := syscall.Bind(fd, &s.lsa); err != nil {
-		syscall.Close(fd)
+	s.lsa.Family = unix.AF_NETLINK
+	if err := unix.Bind(fd, &s.lsa); err != nil {
+		unix.Close(fd)
 		return nil, err
 	}
 
@@ -551,21 +557,21 @@ func executeInNetns(newNs, curNs netns.NsHandle) (func(), error) {
 // Returns the netlink socket on which Receive() method can be called
 // to retrieve the messages from the kernel.
 func Subscribe(protocol int, groups ...uint) (*NetlinkSocket, error) {
-	fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, protocol)
+	fd, err := unix.Socket(unix.AF_NETLINK, unix.SOCK_RAW, protocol)
 	if err != nil {
 		return nil, err
 	}
 	s := &NetlinkSocket{
 		fd: int32(fd),
 	}
-	s.lsa.Family = syscall.AF_NETLINK
+	s.lsa.Family = unix.AF_NETLINK
 
 	for _, g := range groups {
 		s.lsa.Groups |= (1 << (g - 1))
 	}
 
-	if err := syscall.Bind(fd, &s.lsa); err != nil {
-		syscall.Close(fd)
+	if err := unix.Bind(fd, &s.lsa); err != nil {
+		unix.Close(fd)
 		return nil, err
 	}
 
@@ -586,7 +592,7 @@ func SubscribeAt(newNs, curNs netns.NsHandle, protocol int, groups ...uint) (*Ne
 
 func (s *NetlinkSocket) Close() {
 	fd := int(atomic.SwapInt32(&s.fd, -1))
-	syscall.Close(fd)
+	unix.Close(fd)
 }
 
 func (s *NetlinkSocket) GetFd() int {
@@ -598,7 +604,7 @@ func (s *NetlinkSocket) Send(request *NetlinkRequest) error {
 	if fd < 0 {
 		return fmt.Errorf("Send called on a closed socket")
 	}
-	if err := syscall.Sendto(fd, request.Serialize(), 0, &s.lsa); err != nil {
+	if err := unix.Sendto(fd, request.Serialize(), 0, &s.lsa); err != nil {
 		return err
 	}
 	return nil
@@ -609,12 +615,12 @@ func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, error) {
 	if fd < 0 {
 		return nil, fmt.Errorf("Receive called on a closed socket")
 	}
-	rb := make([]byte, syscall.Getpagesize())
-	nr, _, err := syscall.Recvfrom(fd, rb, 0)
+	rb := make([]byte, unix.Getpagesize())
+	nr, _, err := unix.Recvfrom(fd, rb, 0)
 	if err != nil {
 		return nil, err
 	}
-	if nr < syscall.NLMSG_HDRLEN {
+	if nr < unix.NLMSG_HDRLEN {
 		return nil, fmt.Errorf("Got short response from netlink")
 	}
 	rb = rb[:nr]
@@ -622,27 +628,27 @@ func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, error) {
 }
 
 // SetSendTimeout allows to set a send timeout on the socket
-func (s *NetlinkSocket) SetSendTimeout(timeout *syscall.Timeval) error {
+func (s *NetlinkSocket) SetSendTimeout(timeout *unix.Timeval) error {
 	// Set a send timeout of SOCKET_SEND_TIMEOUT, this will allow the Send to periodically unblock and avoid that a routine
 	// remains stuck on a send on a closed fd
-	return syscall.SetsockoptTimeval(int(s.fd), syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, timeout)
+	return unix.SetsockoptTimeval(int(s.fd), unix.SOL_SOCKET, unix.SO_SNDTIMEO, timeout)
 }
 
 // SetReceiveTimeout allows to set a receive timeout on the socket
-func (s *NetlinkSocket) SetReceiveTimeout(timeout *syscall.Timeval) error {
+func (s *NetlinkSocket) SetReceiveTimeout(timeout *unix.Timeval) error {
 	// Set a read timeout of SOCKET_READ_TIMEOUT, this will allow the Read to periodically unblock and avoid that a routine
 	// remains stuck on a recvmsg on a closed fd
-	return syscall.SetsockoptTimeval(int(s.fd), syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, timeout)
+	return unix.SetsockoptTimeval(int(s.fd), unix.SOL_SOCKET, unix.SO_RCVTIMEO, timeout)
 }
 
 func (s *NetlinkSocket) GetPid() (uint32, error) {
 	fd := int(atomic.LoadInt32(&s.fd))
-	lsa, err := syscall.Getsockname(fd)
+	lsa, err := unix.Getsockname(fd)
 	if err != nil {
 		return 0, err
 	}
 	switch v := lsa.(type) {
-	case *syscall.SockaddrNetlink:
+	case *unix.SockaddrNetlink:
 		return v.Pid, nil
 	}
 	return 0, fmt.Errorf("Wrong socket type")
@@ -697,24 +703,24 @@ func Uint64Attr(v uint64) []byte {
 
 func ParseRouteAttr(b []byte) ([]syscall.NetlinkRouteAttr, error) {
 	var attrs []syscall.NetlinkRouteAttr
-	for len(b) >= syscall.SizeofRtAttr {
+	for len(b) >= unix.SizeofRtAttr {
 		a, vbuf, alen, err := netlinkRouteAttrAndValue(b)
 		if err != nil {
 			return nil, err
 		}
-		ra := syscall.NetlinkRouteAttr{Attr: *a, Value: vbuf[:int(a.Len)-syscall.SizeofRtAttr]}
+		ra := syscall.NetlinkRouteAttr{Attr: syscall.RtAttr(*a), Value: vbuf[:int(a.Len)-unix.SizeofRtAttr]}
 		attrs = append(attrs, ra)
 		b = b[alen:]
 	}
 	return attrs, nil
 }
 
-func netlinkRouteAttrAndValue(b []byte) (*syscall.RtAttr, []byte, int, error) {
-	a := (*syscall.RtAttr)(unsafe.Pointer(&b[0]))
-	if int(a.Len) < syscall.SizeofRtAttr || int(a.Len) > len(b) {
-		return nil, nil, 0, syscall.EINVAL
+func netlinkRouteAttrAndValue(b []byte) (*unix.RtAttr, []byte, int, error) {
+	a := (*unix.RtAttr)(unsafe.Pointer(&b[0]))
+	if int(a.Len) < unix.SizeofRtAttr || int(a.Len) > len(b) {
+		return nil, nil, 0, unix.EINVAL
 	}
-	return a, b[syscall.SizeofRtAttr:], rtaAlignOf(int(a.Len)), nil
+	return a, b[unix.SizeofRtAttr:], rtaAlignOf(int(a.Len)), nil
 }
 
 // SocketHandle contains the netlink socket and the associated

+ 20 - 19
vendor/github.com/vishvananda/netlink/nl/route_linux.go

@@ -1,65 +1,66 @@
 package nl
 
 import (
-	"syscall"
 	"unsafe"
+
+	"golang.org/x/sys/unix"
 )
 
 type RtMsg struct {
-	syscall.RtMsg
+	unix.RtMsg
 }
 
 func NewRtMsg() *RtMsg {
 	return &RtMsg{
-		RtMsg: syscall.RtMsg{
-			Table:    syscall.RT_TABLE_MAIN,
-			Scope:    syscall.RT_SCOPE_UNIVERSE,
-			Protocol: syscall.RTPROT_BOOT,
-			Type:     syscall.RTN_UNICAST,
+		RtMsg: unix.RtMsg{
+			Table:    unix.RT_TABLE_MAIN,
+			Scope:    unix.RT_SCOPE_UNIVERSE,
+			Protocol: unix.RTPROT_BOOT,
+			Type:     unix.RTN_UNICAST,
 		},
 	}
 }
 
 func NewRtDelMsg() *RtMsg {
 	return &RtMsg{
-		RtMsg: syscall.RtMsg{
-			Table: syscall.RT_TABLE_MAIN,
-			Scope: syscall.RT_SCOPE_NOWHERE,
+		RtMsg: unix.RtMsg{
+			Table: unix.RT_TABLE_MAIN,
+			Scope: unix.RT_SCOPE_NOWHERE,
 		},
 	}
 }
 
 func (msg *RtMsg) Len() int {
-	return syscall.SizeofRtMsg
+	return unix.SizeofRtMsg
 }
 
 func DeserializeRtMsg(b []byte) *RtMsg {
-	return (*RtMsg)(unsafe.Pointer(&b[0:syscall.SizeofRtMsg][0]))
+	return (*RtMsg)(unsafe.Pointer(&b[0:unix.SizeofRtMsg][0]))
 }
 
 func (msg *RtMsg) Serialize() []byte {
-	return (*(*[syscall.SizeofRtMsg]byte)(unsafe.Pointer(msg)))[:]
+	return (*(*[unix.SizeofRtMsg]byte)(unsafe.Pointer(msg)))[:]
 }
 
 type RtNexthop struct {
-	syscall.RtNexthop
+	unix.RtNexthop
 	Children []NetlinkRequestData
 }
 
 func DeserializeRtNexthop(b []byte) *RtNexthop {
-	return (*RtNexthop)(unsafe.Pointer(&b[0:syscall.SizeofRtNexthop][0]))
+	return (*RtNexthop)(unsafe.Pointer(&b[0:unix.SizeofRtNexthop][0]))
 }
 
 func (msg *RtNexthop) Len() int {
 	if len(msg.Children) == 0 {
-		return syscall.SizeofRtNexthop
+		return unix.SizeofRtNexthop
 	}
 
 	l := 0
 	for _, child := range msg.Children {
 		l += rtaAlignOf(child.Len())
 	}
-	l += syscall.SizeofRtNexthop
+	l += unix.SizeofRtNexthop
 	return rtaAlignOf(l)
 }
 
@@ -67,8 +68,8 @@ func (msg *RtNexthop) Serialize() []byte {
 	length := msg.Len()
 	msg.RtNexthop.Len = uint16(length)
 	buf := make([]byte, length)
-	copy(buf, (*(*[syscall.SizeofRtNexthop]byte)(unsafe.Pointer(msg)))[:])
-	next := rtaAlignOf(syscall.SizeofRtNexthop)
+	copy(buf, (*(*[unix.SizeofRtNexthop]byte)(unsafe.Pointer(msg)))[:])
+	next := rtaAlignOf(unix.SizeofRtNexthop)
 	if len(msg.Children) > 0 {
 		for _, child := range msg.Children {
 			childBuf := child.Serialize()

+ 111 - 0
vendor/github.com/vishvananda/netlink/nl/seg6_linux.go

@@ -0,0 +1,111 @@
+package nl
+
+import (
+	"errors"
+	"fmt"
+	"net"
+)
+
+type IPv6SrHdr struct {
+	nextHdr      uint8
+	hdrLen       uint8
+	routingType  uint8
+	segmentsLeft uint8
+	firstSegment uint8
+	flags        uint8
+	reserved     uint16
+
+	Segments []net.IP
+}
+
+func (s1 *IPv6SrHdr) Equal(s2 IPv6SrHdr) bool {
+	if len(s1.Segments) != len(s2.Segments) {
+		return false
+	}
+	for i := range s1.Segments {
+		if s1.Segments[i].Equal(s2.Segments[i]) != true {
+			return false
+		}
+	}
+	return s1.nextHdr == s2.nextHdr &&
+		s1.hdrLen == s2.hdrLen &&
+		s1.routingType == s2.routingType &&
+		s1.segmentsLeft == s2.segmentsLeft &&
+		s1.firstSegment == s2.firstSegment &&
+		s1.flags == s2.flags
+	// reserved doesn't need to be identical.
+}
+
+// seg6 encap mode
+const (
+	SEG6_IPTUN_MODE_INLINE = iota
+	SEG6_IPTUN_MODE_ENCAP
+)
+
+// number of nested RTATTR
+// from include/uapi/linux/seg6_iptunnel.h
+const (
+	SEG6_IPTUNNEL_UNSPEC = iota
+	SEG6_IPTUNNEL_SRH
+	__SEG6_IPTUNNEL_MAX
+)
+const (
+	SEG6_IPTUNNEL_MAX = __SEG6_IPTUNNEL_MAX - 1
+)
+
+func EncodeSEG6Encap(mode int, segments []net.IP) ([]byte, error) {
+	nsegs := len(segments) // nsegs: number of segments
+	if nsegs == 0 {
+		return nil, errors.New("EncodeSEG6Encap: No Segment in srh")
+	}
+	b := make([]byte, 12, 12+len(segments)*16)
+	native := NativeEndian()
+	native.PutUint32(b, uint32(mode))
+	b[4] = 0                      // srh.nextHdr (0 when calling netlink)
+	b[5] = uint8(16 * nsegs >> 3) // srh.hdrLen (in 8-octets unit)
+	b[6] = IPV6_SRCRT_TYPE_4      // srh.routingType (assigned by IANA)
+	b[7] = uint8(nsegs - 1)       // srh.segmentsLeft
+	b[8] = uint8(nsegs - 1)       // srh.firstSegment
+	b[9] = 0                      // srh.flags (SR6_FLAG1_HMAC for srh_hmac)
+	// srh.reserved: Defined as "Tag" in draft-ietf-6man-segment-routing-header-07
+	native.PutUint16(b[10:], 0) // srh.reserved
+	for _, netIP := range segments {
+		b = append(b, netIP...) // srh.Segments
+	}
+	return b, nil
+}
+
+func DecodeSEG6Encap(buf []byte) (int, []net.IP, error) {
+	native := NativeEndian()
+	mode := int(native.Uint32(buf))
+	srh := IPv6SrHdr{
+		nextHdr:      buf[4],
+		hdrLen:       buf[5],
+		routingType:  buf[6],
+		segmentsLeft: buf[7],
+		firstSegment: buf[8],
+		flags:        buf[9],
+		reserved:     native.Uint16(buf[10:12]),
+	}
+	buf = buf[12:]
+	if len(buf)%16 != 0 {
+		err := fmt.Errorf("DecodeSEG6Encap: error parsing Segment List (buf len: %d)\n", len(buf))
+		return mode, nil, err
+	}
+	for len(buf) > 0 {
+		srh.Segments = append(srh.Segments, net.IP(buf[:16]))
+		buf = buf[16:]
+	}
+	return mode, srh.Segments, nil
+}
+
+// Helper functions
+func SEG6EncapModeString(mode int) string {
+	switch mode {
+	case SEG6_IPTUN_MODE_INLINE:
+		return "inline"
+	case SEG6_IPTUN_MODE_ENCAP:
+		return "encap"
+	}
+	return "unknown"
+}

+ 10 - 0
vendor/github.com/vishvananda/netlink/nl/syscall.go

@@ -65,4 +65,14 @@ const (
 	LWTUNNEL_ENCAP_IP
 	LWTUNNEL_ENCAP_ILA
 	LWTUNNEL_ENCAP_IP6
+	LWTUNNEL_ENCAP_SEG6
+	LWTUNNEL_ENCAP_BPF
+)
+
+// routing header types
+const (
+	IPV6_SRCRT_STRICT = 0x01 // Deprecated; will be removed
+	IPV6_SRCRT_TYPE_0 = 0    // Deprecated; will be removed
+	IPV6_SRCRT_TYPE_2 = 2    // IPv6 type 2 Routing Header
+	IPV6_SRCRT_TYPE_4 = 4    // Segment Routing with IPv6
 )

+ 35 - 0
vendor/github.com/vishvananda/netlink/nl/tc_linux.go

@@ -673,3 +673,38 @@ const (
 	TCA_FW_MASK
 	TCA_FW_MAX = TCA_FW_MASK
 )
+
+const (
+	TCA_MATCHALL_UNSPEC = iota
+	TCA_MATCHALL_CLASSID
+	TCA_MATCHALL_ACT
+	TCA_MATCHALL_FLAGS
+)
+
+const (
+	TCA_FQ_UNSPEC             = iota
+	TCA_FQ_PLIMIT             // limit of total number of packets in queue
+	TCA_FQ_FLOW_PLIMIT        // limit of packets per flow
+	TCA_FQ_QUANTUM            // RR quantum
+	TCA_FQ_INITIAL_QUANTUM    // RR quantum for new flow
+	TCA_FQ_RATE_ENABLE        // enable/disable rate limiting
+	TCA_FQ_FLOW_DEFAULT_RATE  // obsolete do not use
+	TCA_FQ_FLOW_MAX_RATE      // per flow max rate
+	TCA_FQ_BUCKETS_LOG        // log2(number of buckets)
+	TCA_FQ_FLOW_REFILL_DELAY  // flow credit refill delay in usec
+	TCA_FQ_ORPHAN_MASK        // mask applied to orphaned skb hashes
+	TCA_FQ_LOW_RATE_THRESHOLD // per packet delay under this rate
+)
+
+const (
+	TCA_FQ_CODEL_UNSPEC = iota
+	TCA_FQ_CODEL_TARGET
+	TCA_FQ_CODEL_LIMIT
+	TCA_FQ_CODEL_INTERVAL
+	TCA_FQ_CODEL_ECN
+	TCA_FQ_CODEL_FLOWS
+	TCA_FQ_CODEL_QUANTUM
+	TCA_FQ_CODEL_CE_THRESHOLD
+	TCA_FQ_CODEL_DROP_BATCH_SIZE
+	TCA_FQ_CODEL_MEMORY_LIMIT
+)

+ 5 - 4
vendor/github.com/vishvananda/netlink/protinfo_linux.go

@@ -5,6 +5,7 @@ import (
 	"syscall"
 
 	"github.com/vishvananda/netlink/nl"
+	"golang.org/x/sys/unix"
 )
 
 func LinkGetProtinfo(link Link) (Protinfo, error) {
@@ -15,10 +16,10 @@ func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) {
 	base := link.Attrs()
 	h.ensureIndex(base)
 	var pi Protinfo
-	req := h.newNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_DUMP)
-	msg := nl.NewIfInfomsg(syscall.AF_BRIDGE)
+	req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_DUMP)
+	msg := nl.NewIfInfomsg(unix.AF_BRIDGE)
 	req.AddData(msg)
-	msgs, err := req.Execute(syscall.NETLINK_ROUTE, 0)
+	msgs, err := req.Execute(unix.NETLINK_ROUTE, 0)
 	if err != nil {
 		return pi, err
 	}
@@ -33,7 +34,7 @@ func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) {
 			return pi, err
 		}
 		for _, attr := range attrs {
-			if attr.Attr.Type != syscall.IFLA_PROTINFO|syscall.NLA_F_NESTED {
+			if attr.Attr.Type != unix.IFLA_PROTINFO|unix.NLA_F_NESTED {
 				continue
 			}
 			infos, err := nl.ParseRouteAttr(attr.Value)

+ 60 - 0
vendor/github.com/vishvananda/netlink/qdisc.go

@@ -230,3 +230,63 @@ func (qdisc *GenericQdisc) Attrs() *QdiscAttrs {
 func (qdisc *GenericQdisc) Type() string {
 	return qdisc.QdiscType
 }
+
+// Fq is a classless packet scheduler meant to be mostly used for locally generated traffic.
+type Fq struct {
+	QdiscAttrs
+	PacketLimit     uint32
+	FlowPacketLimit uint32
+	// In bytes
+	Quantum        uint32
+	InitialQuantum uint32
+	// called RateEnable under the hood
+	Pacing          uint32
+	FlowDefaultRate uint32
+	FlowMaxRate     uint32
+	// called BucketsLog under the hood
+	Buckets          uint32
+	FlowRefillDelay  uint32
+	LowRateThreshold uint32
+}
+
+func NewFq(attrs QdiscAttrs) *Fq {
+	return &Fq{
+		QdiscAttrs: attrs,
+		Pacing:     1,
+	}
+}
+
+func (qdisc *Fq) Attrs() *QdiscAttrs {
+	return &qdisc.QdiscAttrs
+}
+
+func (qdisc *Fq) Type() string {
+	return "fq"
+}
+
+// FQ_Codel (Fair Queuing Controlled Delay) is queuing discipline that combines Fair Queuing with the CoDel AQM scheme.
+type FqCodel struct {
+	QdiscAttrs
+	Target   uint32
+	Limit    uint32
+	Interval uint32
+	ECN      uint32
+	Flows    uint32
+	Quantum  uint32
+	// There are some more attributes here, but support for them seems not ubiquitous
+}
+
+func NewFqCodel(attrs QdiscAttrs) *FqCodel {
+	return &FqCodel{
+		QdiscAttrs: attrs,
+		ECN:        1,
+	}
+}
+
+func (qdisc *FqCodel) Attrs() *QdiscAttrs {
+	return &qdisc.QdiscAttrs
+}
+
+func (qdisc *FqCodel) Type() string {
+	return "fq_codel"
+}

+ 129 - 11
vendor/github.com/vishvananda/netlink/qdisc_linux.go

@@ -8,6 +8,7 @@ import (
 	"syscall"
 
 	"github.com/vishvananda/netlink/nl"
+	"golang.org/x/sys/unix"
 )
 
 // NOTE function is here because it uses other linux functions
@@ -84,7 +85,7 @@ func QdiscDel(qdisc Qdisc) error {
 // QdiscDel will delete a qdisc from the system.
 // Equivalent to: `tc qdisc del $qdisc`
 func (h *Handle) QdiscDel(qdisc Qdisc) error {
-	return h.qdiscModify(syscall.RTM_DELQDISC, 0, qdisc)
+	return h.qdiscModify(unix.RTM_DELQDISC, 0, qdisc)
 }
 
 // QdiscChange will change a qdisc in place
@@ -98,7 +99,7 @@ func QdiscChange(qdisc Qdisc) error {
 // Equivalent to: `tc qdisc change $qdisc`
 // The parent and handle MUST NOT be changed.
 func (h *Handle) QdiscChange(qdisc Qdisc) error {
-	return h.qdiscModify(syscall.RTM_NEWQDISC, 0, qdisc)
+	return h.qdiscModify(unix.RTM_NEWQDISC, 0, qdisc)
 }
 
 // QdiscReplace will replace a qdisc to the system.
@@ -113,8 +114,8 @@ func QdiscReplace(qdisc Qdisc) error {
 // The handle MUST change.
 func (h *Handle) QdiscReplace(qdisc Qdisc) error {
 	return h.qdiscModify(
-		syscall.RTM_NEWQDISC,
-		syscall.NLM_F_CREATE|syscall.NLM_F_REPLACE,
+		unix.RTM_NEWQDISC,
+		unix.NLM_F_CREATE|unix.NLM_F_REPLACE,
 		qdisc)
 }
 
@@ -128,13 +129,13 @@ func QdiscAdd(qdisc Qdisc) error {
 // Equivalent to: `tc qdisc add $qdisc`
 func (h *Handle) QdiscAdd(qdisc Qdisc) error {
 	return h.qdiscModify(
-		syscall.RTM_NEWQDISC,
-		syscall.NLM_F_CREATE|syscall.NLM_F_EXCL,
+		unix.RTM_NEWQDISC,
+		unix.NLM_F_CREATE|unix.NLM_F_EXCL,
 		qdisc)
 }
 
 func (h *Handle) qdiscModify(cmd, flags int, qdisc Qdisc) error {
-	req := h.newNetlinkRequest(cmd, flags|syscall.NLM_F_ACK)
+	req := h.newNetlinkRequest(cmd, flags|unix.NLM_F_ACK)
 	base := qdisc.Attrs()
 	msg := &nl.TcMsg{
 		Family:  nl.FAMILY_ALL,
@@ -145,13 +146,13 @@ func (h *Handle) qdiscModify(cmd, flags int, qdisc Qdisc) error {
 	req.AddData(msg)
 
 	// When deleting don't bother building the rest of the netlink payload
-	if cmd != syscall.RTM_DELQDISC {
+	if cmd != unix.RTM_DELQDISC {
 		if err := qdiscPayload(req, qdisc); err != nil {
 			return err
 		}
 	}
 
-	_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
+	_, err := req.Execute(unix.NETLINK_ROUTE, 0)
 	return err
 }
 
@@ -231,6 +232,48 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
 		if qdisc.Attrs().Parent != HANDLE_INGRESS {
 			return fmt.Errorf("Ingress filters must set Parent to HANDLE_INGRESS")
 		}
+	case *FqCodel:
+		nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_ECN, nl.Uint32Attr((uint32(qdisc.ECN))))
+		if qdisc.Limit > 0 {
+			nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_LIMIT, nl.Uint32Attr((uint32(qdisc.Limit))))
+		}
+		if qdisc.Interval > 0 {
+			nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_INTERVAL, nl.Uint32Attr((uint32(qdisc.Interval))))
+		}
+		if qdisc.Flows > 0 {
+			nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_FLOWS, nl.Uint32Attr((uint32(qdisc.Flows))))
+		}
+		if qdisc.Quantum > 0 {
+			nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_QUANTUM, nl.Uint32Attr((uint32(qdisc.Quantum))))
+		}
+
+	case *Fq:
+		nl.NewRtAttrChild(options, nl.TCA_FQ_RATE_ENABLE, nl.Uint32Attr((uint32(qdisc.Pacing))))
+
+		if qdisc.Buckets > 0 {
+			nl.NewRtAttrChild(options, nl.TCA_FQ_BUCKETS_LOG, nl.Uint32Attr((uint32(qdisc.Buckets))))
+		}
+		if qdisc.LowRateThreshold > 0 {
+			nl.NewRtAttrChild(options, nl.TCA_FQ_LOW_RATE_THRESHOLD, nl.Uint32Attr((uint32(qdisc.LowRateThreshold))))
+		}
+		if qdisc.Quantum > 0 {
+			nl.NewRtAttrChild(options, nl.TCA_FQ_QUANTUM, nl.Uint32Attr((uint32(qdisc.Quantum))))
+		}
+		if qdisc.InitialQuantum > 0 {
+			nl.NewRtAttrChild(options, nl.TCA_FQ_INITIAL_QUANTUM, nl.Uint32Attr((uint32(qdisc.InitialQuantum))))
+		}
+		if qdisc.FlowRefillDelay > 0 {
+			nl.NewRtAttrChild(options, nl.TCA_FQ_FLOW_REFILL_DELAY, nl.Uint32Attr((uint32(qdisc.FlowRefillDelay))))
+		}
+		if qdisc.FlowPacketLimit > 0 {
+			nl.NewRtAttrChild(options, nl.TCA_FQ_FLOW_PLIMIT, nl.Uint32Attr((uint32(qdisc.FlowPacketLimit))))
+		}
+		if qdisc.FlowMaxRate > 0 {
+			nl.NewRtAttrChild(options, nl.TCA_FQ_FLOW_MAX_RATE, nl.Uint32Attr((uint32(qdisc.FlowMaxRate))))
+		}
+		if qdisc.FlowDefaultRate > 0 {
+			nl.NewRtAttrChild(options, nl.TCA_FQ_FLOW_DEFAULT_RATE, nl.Uint32Attr((uint32(qdisc.FlowDefaultRate))))
+		}
 	}
 
 	req.AddData(options)
@@ -248,7 +291,7 @@ func QdiscList(link Link) ([]Qdisc, error) {
 // Equivalent to: `tc qdisc show`.
 // The list can be filtered by link.
 func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
-	req := h.newNetlinkRequest(syscall.RTM_GETQDISC, syscall.NLM_F_DUMP)
+	req := h.newNetlinkRequest(unix.RTM_GETQDISC, unix.NLM_F_DUMP)
 	index := int32(0)
 	if link != nil {
 		base := link.Attrs()
@@ -261,7 +304,7 @@ func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
 	}
 	req.AddData(msg)
 
-	msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWQDISC)
+	msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWQDISC)
 	if err != nil {
 		return nil, err
 	}
@@ -303,6 +346,10 @@ func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
 					qdisc = &Ingress{}
 				case "htb":
 					qdisc = &Htb{}
+				case "fq":
+					qdisc = &Fq{}
+				case "fq_codel":
+					qdisc = &FqCodel{}
 				case "netem":
 					qdisc = &Netem{}
 				default:
@@ -336,6 +383,22 @@ func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
 					if err := parseHtbData(qdisc, data); err != nil {
 						return nil, err
 					}
+				case "fq":
+					data, err := nl.ParseRouteAttr(attr.Value)
+					if err != nil {
+						return nil, err
+					}
+					if err := parseFqData(qdisc, data); err != nil {
+						return nil, err
+					}
+				case "fq_codel":
+					data, err := nl.ParseRouteAttr(attr.Value)
+					if err != nil {
+						return nil, err
+					}
+					if err := parseFqCodelData(qdisc, data); err != nil {
+						return nil, err
+					}
 				case "netem":
 					if err := parseNetemData(qdisc, attr.Value); err != nil {
 						return nil, err
@@ -388,6 +451,61 @@ func parseHtbData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
 	return nil
 }
 
+func parseFqCodelData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
+	native = nl.NativeEndian()
+	fqCodel := qdisc.(*FqCodel)
+	for _, datum := range data {
+
+		switch datum.Attr.Type {
+		case nl.TCA_FQ_CODEL_TARGET:
+			fqCodel.Target = native.Uint32(datum.Value)
+		case nl.TCA_FQ_CODEL_LIMIT:
+			fqCodel.Limit = native.Uint32(datum.Value)
+		case nl.TCA_FQ_CODEL_INTERVAL:
+			fqCodel.Interval = native.Uint32(datum.Value)
+		case nl.TCA_FQ_CODEL_ECN:
+			fqCodel.ECN = native.Uint32(datum.Value)
+		case nl.TCA_FQ_CODEL_FLOWS:
+			fqCodel.Flows = native.Uint32(datum.Value)
+		case nl.TCA_FQ_CODEL_QUANTUM:
+			fqCodel.Quantum = native.Uint32(datum.Value)
+		}
+	}
+	return nil
+}
+
+func parseFqData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
+	native = nl.NativeEndian()
+	fq := qdisc.(*Fq)
+	for _, datum := range data {
+		switch datum.Attr.Type {
+		case nl.TCA_FQ_BUCKETS_LOG:
+			fq.Buckets = native.Uint32(datum.Value)
+		case nl.TCA_FQ_LOW_RATE_THRESHOLD:
+			fq.LowRateThreshold = native.Uint32(datum.Value)
+		case nl.TCA_FQ_QUANTUM:
+			fq.Quantum = native.Uint32(datum.Value)
+		case nl.TCA_FQ_RATE_ENABLE:
+			fq.Pacing = native.Uint32(datum.Value)
+		case nl.TCA_FQ_INITIAL_QUANTUM:
+			fq.InitialQuantum = native.Uint32(datum.Value)
+		case nl.TCA_FQ_ORPHAN_MASK:
+			// TODO
+		case nl.TCA_FQ_FLOW_REFILL_DELAY:
+			fq.FlowRefillDelay = native.Uint32(datum.Value)
+		case nl.TCA_FQ_FLOW_PLIMIT:
+			fq.FlowPacketLimit = native.Uint32(datum.Value)
+		case nl.TCA_FQ_PLIMIT:
+			fq.PacketLimit = native.Uint32(datum.Value)
+		case nl.TCA_FQ_FLOW_MAX_RATE:
+			fq.FlowMaxRate = native.Uint32(datum.Value)
+		case nl.TCA_FQ_FLOW_DEFAULT_RATE:
+			fq.FlowDefaultRate = native.Uint32(datum.Value)
+		}
+	}
+	return nil
+}
+
 func parseNetemData(qdisc Qdisc, value []byte) error {
 	netem := qdisc.(*Netem)
 	opt := nl.DeserializeTcNetemQopt(value)

+ 2 - 0
vendor/github.com/vishvananda/netlink/route.go

@@ -45,6 +45,8 @@ type Route struct {
 	MPLSDst    *int
 	NewDst     Destination
 	Encap      Encap
+	MTU        int
+	AdvMSS     int
 }
 
 func (r Route) String() string {

+ 190 - 55
vendor/github.com/vishvananda/netlink/route_linux.go

@@ -8,16 +8,17 @@ import (
 
 	"github.com/vishvananda/netlink/nl"
 	"github.com/vishvananda/netns"
+	"golang.org/x/sys/unix"
 )
 
 // RtAttr is shared so it is in netlink_linux.go
 
 const (
-	SCOPE_UNIVERSE Scope = syscall.RT_SCOPE_UNIVERSE
-	SCOPE_SITE     Scope = syscall.RT_SCOPE_SITE
-	SCOPE_LINK     Scope = syscall.RT_SCOPE_LINK
-	SCOPE_HOST     Scope = syscall.RT_SCOPE_HOST
-	SCOPE_NOWHERE  Scope = syscall.RT_SCOPE_NOWHERE
+	SCOPE_UNIVERSE Scope = unix.RT_SCOPE_UNIVERSE
+	SCOPE_SITE     Scope = unix.RT_SCOPE_SITE
+	SCOPE_LINK     Scope = unix.RT_SCOPE_LINK
+	SCOPE_HOST     Scope = unix.RT_SCOPE_HOST
+	SCOPE_NOWHERE  Scope = unix.RT_SCOPE_NOWHERE
 )
 
 const (
@@ -34,8 +35,8 @@ const (
 )
 
 const (
-	FLAG_ONLINK    NextHopFlag = syscall.RTNH_F_ONLINK
-	FLAG_PERVASIVE NextHopFlag = syscall.RTNH_F_PERVASIVE
+	FLAG_ONLINK    NextHopFlag = unix.RTNH_F_ONLINK
+	FLAG_PERVASIVE NextHopFlag = unix.RTNH_F_PERVASIVE
 )
 
 var testFlags = []flagString{
@@ -124,17 +125,17 @@ func (e *MPLSEncap) Type() int {
 
 func (e *MPLSEncap) Decode(buf []byte) error {
 	if len(buf) < 4 {
-		return fmt.Errorf("Lack of bytes")
+		return fmt.Errorf("lack of bytes")
 	}
 	native := nl.NativeEndian()
 	l := native.Uint16(buf)
 	if len(buf) < int(l) {
-		return fmt.Errorf("Lack of bytes")
+		return fmt.Errorf("lack of bytes")
 	}
 	buf = buf[:l]
 	typ := native.Uint16(buf[2:])
 	if typ != nl.MPLS_IPTUNNEL_DST {
-		return fmt.Errorf("Unknown MPLS Encap Type: %d", typ)
+		return fmt.Errorf("unknown MPLS Encap Type: %d", typ)
 	}
 	e.Labels = nl.DecodeMPLSStack(buf[4:])
 	return nil
@@ -185,6 +186,79 @@ func (e *MPLSEncap) Equal(x Encap) bool {
 	return true
 }
 
+// SEG6 definitions
+type SEG6Encap struct {
+	Mode     int
+	Segments []net.IP
+}
+
+func (e *SEG6Encap) Type() int {
+	return nl.LWTUNNEL_ENCAP_SEG6
+}
+func (e *SEG6Encap) Decode(buf []byte) error {
+	if len(buf) < 4 {
+		return fmt.Errorf("lack of bytes")
+	}
+	native := nl.NativeEndian()
+	// Get Length(l) & Type(typ) : 2 + 2 bytes
+	l := native.Uint16(buf)
+	if len(buf) < int(l) {
+		return fmt.Errorf("lack of bytes")
+	}
+	buf = buf[:l] // make sure buf size upper limit is Length
+	typ := native.Uint16(buf[2:])
+	if typ != nl.SEG6_IPTUNNEL_SRH {
+		return fmt.Errorf("unknown SEG6 Type: %d", typ)
+	}
+
+	var err error
+	e.Mode, e.Segments, err = nl.DecodeSEG6Encap(buf[4:])
+
+	return err
+}
+func (e *SEG6Encap) Encode() ([]byte, error) {
+	s, err := nl.EncodeSEG6Encap(e.Mode, e.Segments)
+	native := nl.NativeEndian()
+	hdr := make([]byte, 4)
+	native.PutUint16(hdr, uint16(len(s)+4))
+	native.PutUint16(hdr[2:], nl.SEG6_IPTUNNEL_SRH)
+	return append(hdr, s...), err
+}
+func (e *SEG6Encap) String() string {
+	segs := make([]string, 0, len(e.Segments))
+	// append segment backwards (from n to 0) since seg#0 is the last segment.
+	for i := len(e.Segments); i > 0; i-- {
+		segs = append(segs, fmt.Sprintf("%s", e.Segments[i-1]))
+	}
+	str := fmt.Sprintf("mode %s segs %d [ %s ]", nl.SEG6EncapModeString(e.Mode),
+		len(e.Segments), strings.Join(segs, " "))
+	return str
+}
+func (e *SEG6Encap) Equal(x Encap) bool {
+	o, ok := x.(*SEG6Encap)
+	if !ok {
+		return false
+	}
+	if e == o {
+		return true
+	}
+	if e == nil || o == nil {
+		return false
+	}
+	if e.Mode != o.Mode {
+		return false
+	}
+	if len(e.Segments) != len(o.Segments) {
+		return false
+	}
+	for i := range e.Segments {
+		if !e.Segments[i].Equal(o.Segments[i]) {
+			return false
+		}
+	}
+	return true
+}
+
 // RouteAdd will add a route to the system.
 // Equivalent to: `ip route add $route`
 func RouteAdd(route *Route) error {
@@ -194,8 +268,8 @@ func RouteAdd(route *Route) error {
 // RouteAdd will add a route to the system.
 // Equivalent to: `ip route add $route`
 func (h *Handle) RouteAdd(route *Route) error {
-	flags := syscall.NLM_F_CREATE | syscall.NLM_F_EXCL | syscall.NLM_F_ACK
-	req := h.newNetlinkRequest(syscall.RTM_NEWROUTE, flags)
+	flags := unix.NLM_F_CREATE | unix.NLM_F_EXCL | unix.NLM_F_ACK
+	req := h.newNetlinkRequest(unix.RTM_NEWROUTE, flags)
 	return h.routeHandle(route, req, nl.NewRtMsg())
 }
 
@@ -208,8 +282,8 @@ func RouteReplace(route *Route) error {
 // RouteReplace will add a route to the system.
 // Equivalent to: `ip route replace $route`
 func (h *Handle) RouteReplace(route *Route) error {
-	flags := syscall.NLM_F_CREATE | syscall.NLM_F_REPLACE | syscall.NLM_F_ACK
-	req := h.newNetlinkRequest(syscall.RTM_NEWROUTE, flags)
+	flags := unix.NLM_F_CREATE | unix.NLM_F_REPLACE | unix.NLM_F_ACK
+	req := h.newNetlinkRequest(unix.RTM_NEWROUTE, flags)
 	return h.routeHandle(route, req, nl.NewRtMsg())
 }
 
@@ -222,7 +296,7 @@ func RouteDel(route *Route) error {
 // RouteDel will delete a route from the system.
 // Equivalent to: `ip route del $route`
 func (h *Handle) RouteDel(route *Route) error {
-	req := h.newNetlinkRequest(syscall.RTM_DELROUTE, syscall.NLM_F_ACK)
+	req := h.newNetlinkRequest(unix.RTM_DELROUTE, unix.NLM_F_ACK)
 	return h.routeHandle(route, req, nl.NewRtDelMsg())
 }
 
@@ -245,12 +319,12 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
 		} else {
 			dstData = route.Dst.IP.To16()
 		}
-		rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_DST, dstData))
+		rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_DST, dstData))
 	} else if route.MPLSDst != nil {
 		family = nl.FAMILY_MPLS
 		msg.Dst_len = uint8(20)
-		msg.Type = syscall.RTN_UNICAST
-		rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_DST, nl.EncodeMPLSStack(*route.MPLSDst)))
+		msg.Type = unix.RTN_UNICAST
+		rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_DST, nl.EncodeMPLSStack(*route.MPLSDst)))
 	}
 
 	if route.NewDst != nil {
@@ -288,7 +362,7 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
 			srcData = route.Src.To16()
 		}
 		// The commonly used src ip for routes is actually PREFSRC
-		rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_PREFSRC, srcData))
+		rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_PREFSRC, srcData))
 	}
 
 	if route.Gw != nil {
@@ -303,14 +377,14 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
 		} else {
 			gwData = route.Gw.To16()
 		}
-		rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_GATEWAY, gwData))
+		rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_GATEWAY, gwData))
 	}
 
 	if len(route.MultiPath) > 0 {
 		buf := []byte{}
 		for _, nh := range route.MultiPath {
 			rtnh := &nl.RtNexthop{
-				RtNexthop: syscall.RtNexthop{
+				RtNexthop: unix.RtNexthop{
 					Hops:    uint8(nh.Hops),
 					Ifindex: int32(nh.LinkIndex),
 					Flags:   uint8(nh.Flags),
@@ -323,9 +397,9 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
 					return fmt.Errorf("gateway, source, and destination ip are not the same IP family")
 				}
 				if gwFamily == FAMILY_V4 {
-					children = append(children, nl.NewRtAttr(syscall.RTA_GATEWAY, []byte(nh.Gw.To4())))
+					children = append(children, nl.NewRtAttr(unix.RTA_GATEWAY, []byte(nh.Gw.To4())))
 				} else {
-					children = append(children, nl.NewRtAttr(syscall.RTA_GATEWAY, []byte(nh.Gw.To16())))
+					children = append(children, nl.NewRtAttr(unix.RTA_GATEWAY, []byte(nh.Gw.To16())))
 				}
 			}
 			if nh.NewDst != nil {
@@ -351,15 +425,15 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
 			rtnh.Children = children
 			buf = append(buf, rtnh.Serialize()...)
 		}
-		rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_MULTIPATH, buf))
+		rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_MULTIPATH, buf))
 	}
 
 	if route.Table > 0 {
 		if route.Table >= 256 {
-			msg.Table = syscall.RT_TABLE_UNSPEC
+			msg.Table = unix.RT_TABLE_UNSPEC
 			b := make([]byte, 4)
 			native.PutUint32(b, uint32(route.Table))
-			rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_TABLE, b))
+			rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_TABLE, b))
 		} else {
 			msg.Table = uint8(route.Table)
 		}
@@ -368,7 +442,7 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
 	if route.Priority > 0 {
 		b := make([]byte, 4)
 		native.PutUint32(b, uint32(route.Priority))
-		rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_PRIORITY, b))
+		rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_PRIORITY, b))
 	}
 	if route.Tos > 0 {
 		msg.Tos = uint8(route.Tos)
@@ -380,6 +454,25 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
 		msg.Type = uint8(route.Type)
 	}
 
+	var metrics []*nl.RtAttr
+	// TODO: support other rta_metric values
+	if route.MTU > 0 {
+		b := nl.Uint32Attr(uint32(route.MTU))
+		metrics = append(metrics, nl.NewRtAttr(unix.RTAX_MTU, b))
+	}
+	if route.AdvMSS > 0 {
+		b := nl.Uint32Attr(uint32(route.AdvMSS))
+		metrics = append(metrics, nl.NewRtAttr(unix.RTAX_ADVMSS, b))
+	}
+
+	if metrics != nil {
+		attr := nl.NewRtAttr(unix.RTA_METRICS, nil)
+		for _, metric := range metrics {
+			attr.AddChild(metric)
+		}
+		rtAttrs = append(rtAttrs, attr)
+	}
+
 	msg.Flags = uint32(route.Flags)
 	msg.Scope = uint8(route.Scope)
 	msg.Family = uint8(family)
@@ -394,9 +487,9 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
 	)
 	native.PutUint32(b, uint32(route.LinkIndex))
 
-	req.AddData(nl.NewRtAttr(syscall.RTA_OIF, b))
+	req.AddData(nl.NewRtAttr(unix.RTA_OIF, b))
 
-	_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
+	_, err := req.Execute(unix.NETLINK_ROUTE, 0)
 	return err
 }
 
@@ -429,11 +522,11 @@ func RouteListFiltered(family int, filter *Route, filterMask uint64) ([]Route, e
 // RouteListFiltered gets a list of routes in the system filtered with specified rules.
 // All rules must be defined in RouteFilter struct
 func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64) ([]Route, error) {
-	req := h.newNetlinkRequest(syscall.RTM_GETROUTE, syscall.NLM_F_DUMP)
+	req := h.newNetlinkRequest(unix.RTM_GETROUTE, unix.NLM_F_DUMP)
 	infmsg := nl.NewIfInfomsg(family)
 	req.AddData(infmsg)
 
-	msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWROUTE)
+	msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWROUTE)
 	if err != nil {
 		return nil, err
 	}
@@ -441,11 +534,11 @@ func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64)
 	var res []Route
 	for _, m := range msgs {
 		msg := nl.DeserializeRtMsg(m)
-		if msg.Flags&syscall.RTM_F_CLONED != 0 {
+		if msg.Flags&unix.RTM_F_CLONED != 0 {
 			// Ignore cloned routes
 			continue
 		}
-		if msg.Table != syscall.RT_TABLE_MAIN {
+		if msg.Table != unix.RT_TABLE_MAIN {
 			if filter == nil || filter != nil && filterMask&RT_FILTER_TABLE == 0 {
 				// Ignore non-main tables
 				continue
@@ -457,7 +550,7 @@ func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64)
 		}
 		if filter != nil {
 			switch {
-			case filterMask&RT_FILTER_TABLE != 0 && filter.Table != syscall.RT_TABLE_UNSPEC && route.Table != filter.Table:
+			case filterMask&RT_FILTER_TABLE != 0 && filter.Table != unix.RT_TABLE_UNSPEC && route.Table != filter.Table:
 				continue
 			case filterMask&RT_FILTER_PROTOCOL != 0 && route.Protocol != filter.Protocol:
 				continue
@@ -508,11 +601,11 @@ func deserializeRoute(m []byte) (Route, error) {
 	var encap, encapType syscall.NetlinkRouteAttr
 	for _, attr := range attrs {
 		switch attr.Attr.Type {
-		case syscall.RTA_GATEWAY:
+		case unix.RTA_GATEWAY:
 			route.Gw = net.IP(attr.Value)
-		case syscall.RTA_PREFSRC:
+		case unix.RTA_PREFSRC:
 			route.Src = net.IP(attr.Value)
-		case syscall.RTA_DST:
+		case unix.RTA_DST:
 			if msg.Family == nl.FAMILY_MPLS {
 				stack := nl.DecodeMPLSStack(attr.Value)
 				if len(stack) == 0 || len(stack) > 1 {
@@ -525,36 +618,36 @@ func deserializeRoute(m []byte) (Route, error) {
 					Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attr.Value)),
 				}
 			}
-		case syscall.RTA_OIF:
+		case unix.RTA_OIF:
 			route.LinkIndex = int(native.Uint32(attr.Value[0:4]))
-		case syscall.RTA_IIF:
+		case unix.RTA_IIF:
 			route.ILinkIndex = int(native.Uint32(attr.Value[0:4]))
-		case syscall.RTA_PRIORITY:
+		case unix.RTA_PRIORITY:
 			route.Priority = int(native.Uint32(attr.Value[0:4]))
-		case syscall.RTA_TABLE:
+		case unix.RTA_TABLE:
 			route.Table = int(native.Uint32(attr.Value[0:4]))
-		case syscall.RTA_MULTIPATH:
+		case unix.RTA_MULTIPATH:
 			parseRtNexthop := func(value []byte) (*NexthopInfo, []byte, error) {
-				if len(value) < syscall.SizeofRtNexthop {
-					return nil, nil, fmt.Errorf("Lack of bytes")
+				if len(value) < unix.SizeofRtNexthop {
+					return nil, nil, fmt.Errorf("lack of bytes")
 				}
 				nh := nl.DeserializeRtNexthop(value)
 				if len(value) < int(nh.RtNexthop.Len) {
-					return nil, nil, fmt.Errorf("Lack of bytes")
+					return nil, nil, fmt.Errorf("lack of bytes")
 				}
 				info := &NexthopInfo{
 					LinkIndex: int(nh.RtNexthop.Ifindex),
 					Hops:      int(nh.RtNexthop.Hops),
 					Flags:     int(nh.RtNexthop.Flags),
 				}
-				attrs, err := nl.ParseRouteAttr(value[syscall.SizeofRtNexthop:int(nh.RtNexthop.Len)])
+				attrs, err := nl.ParseRouteAttr(value[unix.SizeofRtNexthop:int(nh.RtNexthop.Len)])
 				if err != nil {
 					return nil, nil, err
 				}
 				var encap, encapType syscall.NetlinkRouteAttr
 				for _, attr := range attrs {
 					switch attr.Attr.Type {
-					case syscall.RTA_GATEWAY:
+					case unix.RTA_GATEWAY:
 						info.Gw = net.IP(attr.Value)
 					case nl.RTA_NEWDST:
 						var d Destination
@@ -611,6 +704,19 @@ func deserializeRoute(m []byte) (Route, error) {
 			encapType = attr
 		case nl.RTA_ENCAP:
 			encap = attr
+		case unix.RTA_METRICS:
+			metrics, err := nl.ParseRouteAttr(attr.Value)
+			if err != nil {
+				return route, err
+			}
+			for _, metric := range metrics {
+				switch metric.Attr.Type {
+				case unix.RTAX_MTU:
+					route.MTU = int(native.Uint32(metric.Value[0:4]))
+				case unix.RTAX_ADVMSS:
+					route.AdvMSS = int(native.Uint32(metric.Value[0:4]))
+				}
+			}
 		}
 	}
 
@@ -623,6 +729,11 @@ func deserializeRoute(m []byte) (Route, error) {
 			if err := e.Decode(encap.Value); err != nil {
 				return route, err
 			}
+		case nl.LWTUNNEL_ENCAP_SEG6:
+			e = &SEG6Encap{}
+			if err := e.Decode(encap.Value); err != nil {
+				return route, err
+			}
 		}
 		route.Encap = e
 	}
@@ -639,7 +750,7 @@ func RouteGet(destination net.IP) ([]Route, error) {
 // RouteGet gets a route to a specific destination from the host system.
 // Equivalent to: 'ip route get'.
 func (h *Handle) RouteGet(destination net.IP) ([]Route, error) {
-	req := h.newNetlinkRequest(syscall.RTM_GETROUTE, syscall.NLM_F_REQUEST)
+	req := h.newNetlinkRequest(unix.RTM_GETROUTE, unix.NLM_F_REQUEST)
 	family := nl.GetIPFamily(destination)
 	var destinationData []byte
 	var bitlen uint8
@@ -655,10 +766,10 @@ func (h *Handle) RouteGet(destination net.IP) ([]Route, error) {
 	msg.Dst_len = bitlen
 	req.AddData(msg)
 
-	rtaDst := nl.NewRtAttr(syscall.RTA_DST, destinationData)
+	rtaDst := nl.NewRtAttr(unix.RTA_DST, destinationData)
 	req.AddData(rtaDst)
 
-	msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWROUTE)
+	msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWROUTE)
 	if err != nil {
 		return nil, err
 	}
@@ -678,13 +789,13 @@ func (h *Handle) RouteGet(destination net.IP) ([]Route, error) {
 // RouteSubscribe takes a chan down which notifications will be sent
 // when routes are added or deleted. Close the 'done' chan to stop subscription.
 func RouteSubscribe(ch chan<- RouteUpdate, done <-chan struct{}) error {
-	return routeSubscribeAt(netns.None(), netns.None(), ch, done, nil)
+	return routeSubscribeAt(netns.None(), netns.None(), ch, done, nil, false)
 }
 
 // RouteSubscribeAt works like RouteSubscribe plus it allows the caller
 // to choose the network namespace in which to subscribe (ns).
 func RouteSubscribeAt(ns netns.NsHandle, ch chan<- RouteUpdate, done <-chan struct{}) error {
-	return routeSubscribeAt(ns, netns.None(), ch, done, nil)
+	return routeSubscribeAt(ns, netns.None(), ch, done, nil, false)
 }
 
 // RouteSubscribeOptions contains a set of options to use with
@@ -692,6 +803,7 @@ func RouteSubscribeAt(ns netns.NsHandle, ch chan<- RouteUpdate, done <-chan stru
 type RouteSubscribeOptions struct {
 	Namespace     *netns.NsHandle
 	ErrorCallback func(error)
+	ListExisting  bool
 }
 
 // RouteSubscribeWithOptions work like RouteSubscribe but enable to
@@ -702,11 +814,11 @@ func RouteSubscribeWithOptions(ch chan<- RouteUpdate, done <-chan struct{}, opti
 		none := netns.None()
 		options.Namespace = &none
 	}
-	return routeSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback)
+	return routeSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting)
 }
 
-func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <-chan struct{}, cberr func(error)) error {
-	s, err := nl.SubscribeAt(newNs, curNs, syscall.NETLINK_ROUTE, syscall.RTNLGRP_IPV4_ROUTE, syscall.RTNLGRP_IPV6_ROUTE)
+func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <-chan struct{}, cberr func(error), listExisting bool) error {
+	s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_IPV4_ROUTE, unix.RTNLGRP_IPV6_ROUTE)
 	if err != nil {
 		return err
 	}
@@ -716,6 +828,15 @@ func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <
 			s.Close()
 		}()
 	}
+	if listExisting {
+		req := pkgHandle.newNetlinkRequest(unix.RTM_GETROUTE,
+			unix.NLM_F_DUMP)
+		infmsg := nl.NewIfInfomsg(unix.AF_UNSPEC)
+		req.AddData(infmsg)
+		if err := s.Send(req); err != nil {
+			return err
+		}
+	}
 	go func() {
 		defer close(ch)
 		for {
@@ -727,6 +848,20 @@ func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <
 				return
 			}
 			for _, m := range msgs {
+				if m.Header.Type == unix.NLMSG_DONE {
+					continue
+				}
+				if m.Header.Type == unix.NLMSG_ERROR {
+					native := nl.NativeEndian()
+					error := int32(native.Uint32(m.Data[0:4]))
+					if error == 0 {
+						continue
+					}
+					if cberr != nil {
+						cberr(syscall.Errno(-error))
+					}
+					return
+				}
 				route, err := deserializeRoute(m.Data)
 				if err != nil {
 					if cberr != nil {

+ 1 - 0
vendor/github.com/vishvananda/netlink/rule.go

@@ -21,6 +21,7 @@ type Rule struct {
 	OifName           string
 	SuppressIfgroup   int
 	SuppressPrefixlen int
+	Invert            bool
 }
 
 func (r Rule) String() string {

+ 30 - 20
vendor/github.com/vishvananda/netlink/rule_linux.go

@@ -3,11 +3,13 @@ package netlink
 import (
 	"fmt"
 	"net"
-	"syscall"
 
 	"github.com/vishvananda/netlink/nl"
+	"golang.org/x/sys/unix"
 )
 
+const FibRuleInvert = 0x2
+
 // RuleAdd adds a rule to the system.
 // Equivalent to: ip rule add
 func RuleAdd(rule *Rule) error {
@@ -17,7 +19,7 @@ func RuleAdd(rule *Rule) error {
 // RuleAdd adds a rule to the system.
 // Equivalent to: ip rule add
 func (h *Handle) RuleAdd(rule *Rule) error {
-	req := h.newNetlinkRequest(syscall.RTM_NEWRULE, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
+	req := h.newNetlinkRequest(unix.RTM_NEWRULE, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
 	return ruleHandle(rule, req)
 }
 
@@ -30,18 +32,31 @@ func RuleDel(rule *Rule) error {
 // RuleDel deletes a rule from the system.
 // Equivalent to: ip rule del
 func (h *Handle) RuleDel(rule *Rule) error {
-	req := h.newNetlinkRequest(syscall.RTM_DELRULE, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
+	req := h.newNetlinkRequest(unix.RTM_DELRULE, unix.NLM_F_ACK)
 	return ruleHandle(rule, req)
 }
 
 func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
 	msg := nl.NewRtMsg()
-	msg.Family = syscall.AF_INET
+	msg.Family = unix.AF_INET
+	msg.Protocol = unix.RTPROT_BOOT
+	msg.Scope = unix.RT_SCOPE_UNIVERSE
+	msg.Table = unix.RT_TABLE_UNSPEC
+	msg.Type = unix.RTN_UNSPEC
+	if req.NlMsghdr.Flags&unix.NLM_F_CREATE > 0 {
+		msg.Type = unix.RTN_UNICAST
+	}
+	if rule.Invert {
+		msg.Flags |= FibRuleInvert
+	}
 	if rule.Family != 0 {
 		msg.Family = uint8(rule.Family)
 	}
-	var dstFamily uint8
+	if rule.Table >= 0 && rule.Table < 256 {
+		msg.Table = uint8(rule.Table)
+	}
 
+	var dstFamily uint8
 	var rtAttrs []*nl.RtAttr
 	if rule.Dst != nil && rule.Dst.IP != nil {
 		dstLen, _ := rule.Dst.Mask.Size()
@@ -49,12 +64,12 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
 		msg.Family = uint8(nl.GetIPFamily(rule.Dst.IP))
 		dstFamily = msg.Family
 		var dstData []byte
-		if msg.Family == syscall.AF_INET {
+		if msg.Family == unix.AF_INET {
 			dstData = rule.Dst.IP.To4()
 		} else {
 			dstData = rule.Dst.IP.To16()
 		}
-		rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_DST, dstData))
+		rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_DST, dstData))
 	}
 
 	if rule.Src != nil && rule.Src.IP != nil {
@@ -65,19 +80,12 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
 		srcLen, _ := rule.Src.Mask.Size()
 		msg.Src_len = uint8(srcLen)
 		var srcData []byte
-		if msg.Family == syscall.AF_INET {
+		if msg.Family == unix.AF_INET {
 			srcData = rule.Src.IP.To4()
 		} else {
 			srcData = rule.Src.IP.To16()
 		}
-		rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_SRC, srcData))
-	}
-
-	if rule.Table >= 0 {
-		msg.Table = uint8(rule.Table)
-		if rule.Table >= 256 {
-			msg.Table = syscall.RT_TABLE_UNSPEC
-		}
+		rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_SRC, srcData))
 	}
 
 	req.AddData(msg)
@@ -142,7 +150,7 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
 		req.AddData(nl.NewRtAttr(nl.FRA_GOTO, b))
 	}
 
-	_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
+	_, err := req.Execute(unix.NETLINK_ROUTE, 0)
 	return err
 }
 
@@ -155,11 +163,11 @@ func RuleList(family int) ([]Rule, error) {
 // RuleList lists rules in the system.
 // Equivalent to: ip rule list
 func (h *Handle) RuleList(family int) ([]Rule, error) {
-	req := h.newNetlinkRequest(syscall.RTM_GETRULE, syscall.NLM_F_DUMP|syscall.NLM_F_REQUEST)
+	req := h.newNetlinkRequest(unix.RTM_GETRULE, unix.NLM_F_DUMP|unix.NLM_F_REQUEST)
 	msg := nl.NewIfInfomsg(family)
 	req.AddData(msg)
 
-	msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWRULE)
+	msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWRULE)
 	if err != nil {
 		return nil, err
 	}
@@ -175,9 +183,11 @@ func (h *Handle) RuleList(family int) ([]Rule, error) {
 
 		rule := NewRule()
 
+		rule.Invert = msg.Flags&FibRuleInvert > 0
+
 		for j := range attrs {
 			switch attrs[j].Attr.Type {
-			case syscall.RTA_TABLE:
+			case unix.RTA_TABLE:
 				rule.Table = int(native.Uint32(attrs[j].Value[0:4]))
 			case nl.FRA_SRC:
 				rule.Src = &net.IPNet{

+ 4 - 4
vendor/github.com/vishvananda/netlink/socket_linux.go

@@ -4,9 +4,9 @@ import (
 	"errors"
 	"fmt"
 	"net"
-	"syscall"
 
 	"github.com/vishvananda/netlink/nl"
+	"golang.org/x/sys/unix"
 )
 
 const (
@@ -123,15 +123,15 @@ func SocketGet(local, remote net.Addr) (*Socket, error) {
 		return nil, ErrNotImplemented
 	}
 
-	s, err := nl.Subscribe(syscall.NETLINK_INET_DIAG)
+	s, err := nl.Subscribe(unix.NETLINK_INET_DIAG)
 	if err != nil {
 		return nil, err
 	}
 	defer s.Close()
 	req := nl.NewNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, 0)
 	req.AddData(&socketRequest{
-		Family:   syscall.AF_INET,
-		Protocol: syscall.IPPROTO_TCP,
+		Family:   unix.AF_INET,
+		Protocol: unix.IPPROTO_TCP,
 		ID: SocketID{
 			SourcePort:      uint16(localTCP.Port),
 			DestinationPort: uint16(remoteTCP.Port),

+ 7 - 6
vendor/github.com/vishvananda/netlink/xfrm.go

@@ -2,19 +2,20 @@ package netlink
 
 import (
 	"fmt"
-	"syscall"
+
+	"golang.org/x/sys/unix"
 )
 
 // Proto is an enum representing an ipsec protocol.
 type Proto uint8
 
 const (
-	XFRM_PROTO_ROUTE2    Proto = syscall.IPPROTO_ROUTING
-	XFRM_PROTO_ESP       Proto = syscall.IPPROTO_ESP
-	XFRM_PROTO_AH        Proto = syscall.IPPROTO_AH
-	XFRM_PROTO_HAO       Proto = syscall.IPPROTO_DSTOPTS
+	XFRM_PROTO_ROUTE2    Proto = unix.IPPROTO_ROUTING
+	XFRM_PROTO_ESP       Proto = unix.IPPROTO_ESP
+	XFRM_PROTO_AH        Proto = unix.IPPROTO_AH
+	XFRM_PROTO_HAO       Proto = unix.IPPROTO_DSTOPTS
 	XFRM_PROTO_COMP      Proto = 0x6c // NOTE not defined on darwin
-	XFRM_PROTO_IPSEC_ANY Proto = syscall.IPPROTO_RAW
+	XFRM_PROTO_IPSEC_ANY Proto = unix.IPPROTO_RAW
 )
 
 func (p Proto) String() string {

+ 3 - 4
vendor/github.com/vishvananda/netlink/xfrm_monitor_linux.go

@@ -2,11 +2,10 @@ package netlink
 
 import (
 	"fmt"
-	"syscall"
-
-	"github.com/vishvananda/netns"
 
 	"github.com/vishvananda/netlink/nl"
+	"github.com/vishvananda/netns"
+	"golang.org/x/sys/unix"
 )
 
 type XfrmMsg interface {
@@ -39,7 +38,7 @@ func XfrmMonitor(ch chan<- XfrmMsg, done <-chan struct{}, errorChan chan<- error
 	if err != nil {
 		return nil
 	}
-	s, err := nl.SubscribeAt(netns.None(), netns.None(), syscall.NETLINK_XFRM, groups...)
+	s, err := nl.SubscribeAt(netns.None(), netns.None(), unix.NETLINK_XFRM, groups...)
 	if err != nil {
 		return err
 	}

+ 9 - 10
vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go

@@ -1,9 +1,8 @@
 package netlink
 
 import (
-	"syscall"
-
 	"github.com/vishvananda/netlink/nl"
+	"golang.org/x/sys/unix"
 )
 
 func selFromPolicy(sel *nl.XfrmSelector, policy *XfrmPolicy) {
@@ -55,7 +54,7 @@ func (h *Handle) XfrmPolicyUpdate(policy *XfrmPolicy) error {
 }
 
 func (h *Handle) xfrmPolicyAddOrUpdate(policy *XfrmPolicy, nlProto int) error {
-	req := h.newNetlinkRequest(nlProto, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
+	req := h.newNetlinkRequest(nlProto, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
 
 	msg := &nl.XfrmUserpolicyInfo{}
 	selFromPolicy(&msg.Sel, policy)
@@ -91,7 +90,7 @@ func (h *Handle) xfrmPolicyAddOrUpdate(policy *XfrmPolicy, nlProto int) error {
 		req.AddData(out)
 	}
 
-	_, err := req.Execute(syscall.NETLINK_XFRM, 0)
+	_, err := req.Execute(unix.NETLINK_XFRM, 0)
 	return err
 }
 
@@ -121,12 +120,12 @@ func XfrmPolicyList(family int) ([]XfrmPolicy, error) {
 // Equivalent to: `ip xfrm policy show`.
 // The list can be filtered by ip family.
 func (h *Handle) XfrmPolicyList(family int) ([]XfrmPolicy, error) {
-	req := h.newNetlinkRequest(nl.XFRM_MSG_GETPOLICY, syscall.NLM_F_DUMP)
+	req := h.newNetlinkRequest(nl.XFRM_MSG_GETPOLICY, unix.NLM_F_DUMP)
 
 	msg := nl.NewIfInfomsg(family)
 	req.AddData(msg)
 
-	msgs, err := req.Execute(syscall.NETLINK_XFRM, nl.XFRM_MSG_NEWPOLICY)
+	msgs, err := req.Execute(unix.NETLINK_XFRM, nl.XFRM_MSG_NEWPOLICY)
 	if err != nil {
 		return nil, err
 	}
@@ -165,13 +164,13 @@ func XfrmPolicyFlush() error {
 // XfrmPolicyFlush will flush the policies on the system.
 // Equivalent to: `ip xfrm policy flush`
 func (h *Handle) XfrmPolicyFlush() error {
-	req := h.newNetlinkRequest(nl.XFRM_MSG_FLUSHPOLICY, syscall.NLM_F_ACK)
-	_, err := req.Execute(syscall.NETLINK_XFRM, 0)
+	req := h.newNetlinkRequest(nl.XFRM_MSG_FLUSHPOLICY, unix.NLM_F_ACK)
+	_, err := req.Execute(unix.NETLINK_XFRM, 0)
 	return err
 }
 
 func (h *Handle) xfrmPolicyGetOrDelete(policy *XfrmPolicy, nlProto int) (*XfrmPolicy, error) {
-	req := h.newNetlinkRequest(nlProto, syscall.NLM_F_ACK)
+	req := h.newNetlinkRequest(nlProto, unix.NLM_F_ACK)
 
 	msg := &nl.XfrmUserpolicyId{}
 	selFromPolicy(&msg.Sel, policy)
@@ -189,7 +188,7 @@ func (h *Handle) xfrmPolicyGetOrDelete(policy *XfrmPolicy, nlProto int) (*XfrmPo
 		resType = 0
 	}
 
-	msgs, err := req.Execute(syscall.NETLINK_XFRM, uint16(resType))
+	msgs, err := req.Execute(unix.NETLINK_XFRM, uint16(resType))
 	if err != nil {
 		return nil, err
 	}

+ 24 - 3
vendor/github.com/vishvananda/netlink/xfrm_state.go

@@ -3,6 +3,7 @@ package netlink
 import (
 	"fmt"
 	"net"
+	"time"
 )
 
 // XfrmStateAlgo represents the algorithm to use for the ipsec encryption.
@@ -67,6 +68,19 @@ type XfrmStateLimits struct {
 	TimeUseHard uint64
 }
 
+// XfrmStateStats represents the current number of bytes/packets
+// processed by this State, the State's installation and first use
+// time and the replay window counters.
+type XfrmStateStats struct {
+	ReplayWindow uint32
+	Replay       uint32
+	Failed       uint32
+	Bytes        uint64
+	Packets      uint64
+	AddTime      uint64
+	UseTime      uint64
+}
+
 // XfrmState represents the state of an ipsec policy. It optionally
 // contains an XfrmStateAlgo for encryption and one for authentication.
 type XfrmState struct {
@@ -78,6 +92,7 @@ type XfrmState struct {
 	Reqid        int
 	ReplayWindow int
 	Limits       XfrmStateLimits
+	Statistics   XfrmStateStats
 	Mark         *XfrmMark
 	Auth         *XfrmStateAlgo
 	Crypt        *XfrmStateAlgo
@@ -94,10 +109,16 @@ func (sa XfrmState) Print(stats bool) string {
 	if !stats {
 		return sa.String()
 	}
-
-	return fmt.Sprintf("%s, ByteSoft: %s, ByteHard: %s, PacketSoft: %s, PacketHard: %s, TimeSoft: %d, TimeHard: %d, TimeUseSoft: %d, TimeUseHard: %d",
+	at := time.Unix(int64(sa.Statistics.AddTime), 0).Format(time.UnixDate)
+	ut := "-"
+	if sa.Statistics.UseTime > 0 {
+		ut = time.Unix(int64(sa.Statistics.UseTime), 0).Format(time.UnixDate)
+	}
+	return fmt.Sprintf("%s, ByteSoft: %s, ByteHard: %s, PacketSoft: %s, PacketHard: %s, TimeSoft: %d, TimeHard: %d, TimeUseSoft: %d, TimeUseHard: %d, Bytes: %d, Packets: %d, "+
+		"AddTime: %s, UseTime: %s, ReplayWindow: %d, Replay: %d, Failed: %d",
 		sa.String(), printLimit(sa.Limits.ByteSoft), printLimit(sa.Limits.ByteHard), printLimit(sa.Limits.PacketSoft), printLimit(sa.Limits.PacketHard),
-		sa.Limits.TimeSoft, sa.Limits.TimeHard, sa.Limits.TimeUseSoft, sa.Limits.TimeUseHard)
+		sa.Limits.TimeSoft, sa.Limits.TimeHard, sa.Limits.TimeUseSoft, sa.Limits.TimeUseHard, sa.Statistics.Bytes, sa.Statistics.Packets, at, ut,
+		sa.Statistics.ReplayWindow, sa.Statistics.Replay, sa.Statistics.Failed)
 }
 
 func printLimit(lmt uint64) string {

+ 26 - 13
vendor/github.com/vishvananda/netlink/xfrm_state_linux.go

@@ -2,10 +2,10 @@ package netlink
 
 import (
 	"fmt"
-	"syscall"
 	"unsafe"
 
 	"github.com/vishvananda/netlink/nl"
+	"golang.org/x/sys/unix"
 )
 
 func writeStateAlgo(a *XfrmStateAlgo) []byte {
@@ -69,8 +69,10 @@ func writeReplayEsn(replayWindow int) []byte {
 		ReplayWindow: uint32(replayWindow),
 	}
 
-	// taken from iproute2/ip/xfrm_state.c:
-	replayEsn.BmpLen = uint32((replayWindow + (4 * 8) - 1) / (4 * 8))
+	// Linux stores the bitmap to identify the already received sequence packets in blocks of uint32 elements.
+	// Therefore bitmap length is the minimum number of uint32 elements needed. The following is a ceiling operation.
+	bytesPerElem := int(unsafe.Sizeof(replayEsn.BmpLen)) // Any uint32 variable is good for this
+	replayEsn.BmpLen = uint32((replayWindow + (bytesPerElem * 8) - 1) / (bytesPerElem * 8))
 
 	return replayEsn.Serialize()
 }
@@ -111,7 +113,7 @@ func (h *Handle) xfrmStateAddOrUpdate(state *XfrmState, nlProto int) error {
 	if state.Spi == 0 {
 		return fmt.Errorf("Spi must be set when adding xfrm state.")
 	}
-	req := h.newNetlinkRequest(nlProto, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
+	req := h.newNetlinkRequest(nlProto, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
 
 	msg := xfrmUsersaInfoFromXfrmState(state)
 
@@ -157,13 +159,13 @@ func (h *Handle) xfrmStateAddOrUpdate(state *XfrmState, nlProto int) error {
 		req.AddData(out)
 	}
 
-	_, err := req.Execute(syscall.NETLINK_XFRM, 0)
+	_, err := req.Execute(unix.NETLINK_XFRM, 0)
 	return err
 }
 
 func (h *Handle) xfrmStateAllocSpi(state *XfrmState) (*XfrmState, error) {
 	req := h.newNetlinkRequest(nl.XFRM_MSG_ALLOCSPI,
-		syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
+		unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
 
 	msg := &nl.XfrmUserSpiInfo{}
 	msg.XfrmUsersaInfo = *(xfrmUsersaInfoFromXfrmState(state))
@@ -177,7 +179,7 @@ func (h *Handle) xfrmStateAllocSpi(state *XfrmState) (*XfrmState, error) {
 		req.AddData(out)
 	}
 
-	msgs, err := req.Execute(syscall.NETLINK_XFRM, 0)
+	msgs, err := req.Execute(unix.NETLINK_XFRM, 0)
 	if err != nil {
 		return nil, err
 	}
@@ -216,9 +218,9 @@ func XfrmStateList(family int) ([]XfrmState, error) {
 // Equivalent to: `ip xfrm state show`.
 // The list can be filtered by ip family.
 func (h *Handle) XfrmStateList(family int) ([]XfrmState, error) {
-	req := h.newNetlinkRequest(nl.XFRM_MSG_GETSA, syscall.NLM_F_DUMP)
+	req := h.newNetlinkRequest(nl.XFRM_MSG_GETSA, unix.NLM_F_DUMP)
 
-	msgs, err := req.Execute(syscall.NETLINK_XFRM, nl.XFRM_MSG_NEWSA)
+	msgs, err := req.Execute(unix.NETLINK_XFRM, nl.XFRM_MSG_NEWSA)
 	if err != nil {
 		return nil, err
 	}
@@ -255,7 +257,7 @@ func (h *Handle) XfrmStateGet(state *XfrmState) (*XfrmState, error) {
 }
 
 func (h *Handle) xfrmStateGetOrDelete(state *XfrmState, nlProto int) (*XfrmState, error) {
-	req := h.newNetlinkRequest(nlProto, syscall.NLM_F_ACK)
+	req := h.newNetlinkRequest(nlProto, unix.NLM_F_ACK)
 
 	msg := &nl.XfrmUsersaId{}
 	msg.Family = uint16(nl.GetIPFamily(state.Dst))
@@ -278,7 +280,7 @@ func (h *Handle) xfrmStateGetOrDelete(state *XfrmState, nlProto int) (*XfrmState
 		resType = 0
 	}
 
-	msgs, err := req.Execute(syscall.NETLINK_XFRM, uint16(resType))
+	msgs, err := req.Execute(unix.NETLINK_XFRM, uint16(resType))
 	if err != nil {
 		return nil, err
 	}
@@ -308,6 +310,7 @@ func xfrmStateFromXfrmUsersaInfo(msg *nl.XfrmUsersaInfo) *XfrmState {
 	state.Reqid = int(msg.Reqid)
 	state.ReplayWindow = int(msg.ReplayWindow)
 	lftToLimits(&msg.Lft, &state.Limits)
+	curToStats(&msg.Curlft, &msg.Stats, &state.Statistics)
 
 	return &state
 }
@@ -386,11 +389,11 @@ func XfrmStateFlush(proto Proto) error {
 // proto = 0 means any transformation protocols
 // Equivalent to: `ip xfrm state flush [ proto XFRM-PROTO ]`
 func (h *Handle) XfrmStateFlush(proto Proto) error {
-	req := h.newNetlinkRequest(nl.XFRM_MSG_FLUSHSA, syscall.NLM_F_ACK)
+	req := h.newNetlinkRequest(nl.XFRM_MSG_FLUSHSA, unix.NLM_F_ACK)
 
 	req.AddData(&nl.XfrmUsersaFlush{Proto: uint8(proto)})
 
-	_, err := req.Execute(syscall.NETLINK_XFRM, 0)
+	_, err := req.Execute(unix.NETLINK_XFRM, 0)
 	if err != nil {
 		return err
 	}
@@ -429,6 +432,16 @@ func lftToLimits(lft *nl.XfrmLifetimeCfg, lmts *XfrmStateLimits) {
 	*lmts = *(*XfrmStateLimits)(unsafe.Pointer(lft))
 }
 
+func curToStats(cur *nl.XfrmLifetimeCur, wstats *nl.XfrmStats, stats *XfrmStateStats) {
+	stats.Bytes = cur.Bytes
+	stats.Packets = cur.Packets
+	stats.AddTime = cur.AddTime
+	stats.UseTime = cur.UseTime
+	stats.ReplayWindow = wstats.ReplayWindow
+	stats.Replay = wstats.Replay
+	stats.Failed = wstats.IntegrityFailed
+}
+
 func xfrmUsersaInfoFromXfrmState(state *XfrmState) *nl.XfrmUsersaInfo {
 	msg := &nl.XfrmUsersaInfo{}
 	msg.Family = uint16(nl.GetIPFamily(state.Dst))

+ 4 - 2
vendor/github.com/vishvananda/netns/README.md

@@ -20,9 +20,10 @@ Testing (requires root):
 package main
 
 import (
+    "fmt"
     "net"
     "runtime"
-    "github.com/vishvananada/netns"
+    "github.com/vishvananda/netns"
 )
 
 func main() {
@@ -36,9 +37,10 @@ func main() {
 
     // Create a new network namespace
     newns, _ := netns.New()
+    netns.Set(newns)
     defer newns.Close()
 
-    // Do something with tne network namespace
+    // Do something with the network namespace
     ifaces, _ := net.Interfaces()
     fmt.Printf("Interfaces: %v\n", ifaces)
 

+ 15 - 2
vendor/github.com/vishvananda/netns/netns.go

@@ -19,7 +19,7 @@ type NsHandle int
 
 // Equal determines if two network handles refer to the same network
 // namespace. This is done by comparing the device and inode that the
-// file descripors point to.
+// file descriptors point to.
 func (ns NsHandle) Equal(other NsHandle) bool {
 	if ns == other {
 		return true
@@ -46,6 +46,19 @@ func (ns NsHandle) String() string {
 	return fmt.Sprintf("NS(%d: %d, %d)", ns, s.Dev, s.Ino)
 }
 
+// UniqueId returns a string which uniquely identifies the namespace
+// associated with the network handle.
+func (ns NsHandle) UniqueId() string {
+	var s syscall.Stat_t
+	if ns == -1 {
+		return "NS(none)"
+	}
+	if err := syscall.Fstat(int(ns), &s); err != nil {
+		return "NS(unknown)"
+	}
+	return fmt.Sprintf("NS(%d:%d)", s.Dev, s.Ino)
+}
+
 // IsOpen returns true if Close() has not been called.
 func (ns NsHandle) IsOpen() bool {
 	return ns != -1
@@ -61,7 +74,7 @@ func (ns *NsHandle) Close() error {
 	return nil
 }
 
-// Get an empty (closed) NsHandle
+// None gets an empty (closed) NsHandle.
 func None() NsHandle {
 	return NsHandle(-1)
 }

+ 29 - 4
vendor/github.com/vishvananda/netns/netns_linux.go

@@ -7,14 +7,27 @@ import (
 	"io/ioutil"
 	"os"
 	"path/filepath"
+	"runtime"
 	"strconv"
 	"strings"
 	"syscall"
 )
 
+// SYS_SETNS syscall allows changing the namespace of the current process.
+var SYS_SETNS = map[string]uintptr{
+	"386":     346,
+	"amd64":   308,
+	"arm64":   268,
+	"arm":     375,
+	"mips":    4344,
+	"mipsle":  4344,
+	"ppc64":   350,
+	"ppc64le": 350,
+	"s390x":   339,
+}[runtime.GOARCH]
+
+// Deprecated: use syscall pkg instead (go >= 1.5 needed).
 const (
-	// These constants belong in the syscall library but have not been
-	// added yet.
 	CLONE_NEWUTS  = 0x04000000 /* New utsname group? */
 	CLONE_NEWIPC  = 0x08000000 /* New ipcs */
 	CLONE_NEWUSER = 0x10000000 /* New user namespace */
@@ -125,7 +138,9 @@ func getThisCgroup(cgroupType string) (string, error) {
 		return "", fmt.Errorf("docker pid not found in /var/run/docker.pid")
 	}
 	pid, err := strconv.Atoi(result[0])
-
+	if err != nil {
+		return "", err
+	}
 	output, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cgroup", pid))
 	if err != nil {
 		return "", err
@@ -167,8 +182,18 @@ func getPidForContainer(id string) (int, error) {
 		filepath.Join(cgroupRoot, cgroupThis, id, "tasks"),
 		// With more recent lxc versions use, cgroup will be in lxc/
 		filepath.Join(cgroupRoot, cgroupThis, "lxc", id, "tasks"),
-		// With more recent dockee, cgroup will be in docker/
+		// With more recent docker, cgroup will be in docker/
 		filepath.Join(cgroupRoot, cgroupThis, "docker", id, "tasks"),
+		// Even more recent docker versions under systemd use docker-<id>.scope/
+		filepath.Join(cgroupRoot, "system.slice", "docker-"+id+".scope", "tasks"),
+		// Even more recent docker versions under cgroup/systemd/docker/<id>/
+		filepath.Join(cgroupRoot, "..", "systemd", "docker", id, "tasks"),
+		// Kubernetes with docker and CNI is even more different
+		filepath.Join(cgroupRoot, "..", "systemd", "kubepods", "*", "pod*", id, "tasks"),
+		// Another flavor of containers location in recent kubernetes 1.11+
+		filepath.Join(cgroupRoot, cgroupThis, "kubepods.slice", "kubepods-besteffort.slice", "*", "docker-"+id+".scope", "tasks"),
+		// When runs inside of a container with recent kubernetes 1.11+
+		filepath.Join(cgroupRoot, "kubepods.slice", "kubepods-besteffort.slice", "*", "docker-"+id+".scope", "tasks"),
 	}
 
 	var filename string

+ 0 - 7
vendor/github.com/vishvananda/netns/netns_linux_386.go

@@ -1,7 +0,0 @@
-// +build linux,386
-
-package netns
-
-const (
-	SYS_SETNS = 346
-)

+ 0 - 7
vendor/github.com/vishvananda/netns/netns_linux_amd64.go

@@ -1,7 +0,0 @@
-// +build linux,amd64
-
-package netns
-
-const (
-	SYS_SETNS = 308
-)

+ 0 - 7
vendor/github.com/vishvananda/netns/netns_linux_arm.go

@@ -1,7 +0,0 @@
-// +build linux,arm
-
-package netns
-
-const (
-	SYS_SETNS = 375
-)

+ 0 - 7
vendor/github.com/vishvananda/netns/netns_linux_arm64.go

@@ -1,7 +0,0 @@
-// +build linux,arm64
-
-package netns
-
-const (
-	SYS_SETNS = 268
-)

+ 0 - 7
vendor/github.com/vishvananda/netns/netns_linux_ppc64le.go

@@ -1,7 +0,0 @@
-// +build linux,ppc64le
-
-package netns
-
-const (
-	SYS_SETNS = 350
-)

+ 0 - 7
vendor/github.com/vishvananda/netns/netns_linux_s390x.go

@@ -1,7 +0,0 @@
-// +build linux,s390x
-
-package netns
-
-const (
-	SYS_SETNS = 339
-)

+ 8 - 0
vendor/github.com/vishvananda/netns/netns_unspecified.go

@@ -22,6 +22,10 @@ func Get() (NsHandle, error) {
 	return -1, ErrNotImplemented
 }
 
+func GetFromPath(path string) (NsHandle, error) {
+	return -1, ErrNotImplemented
+}
+
 func GetFromName(name string) (NsHandle, error) {
 	return -1, ErrNotImplemented
 }
@@ -30,6 +34,10 @@ func GetFromPid(pid int) (NsHandle, error) {
 	return -1, ErrNotImplemented
 }
 
+func GetFromThread(pid, tid int) (NsHandle, error) {
+	return -1, ErrNotImplemented
+}
+
 func GetFromDocker(id string) (NsHandle, error) {
 	return -1, ErrNotImplemented
 }

Some files were not shown because too many files changed in this diff