瀏覽代碼

Merge pull request #330 from thaJeztah/19.03_backport_bump_libnetwork

[19.03 backport] bump libnetwork to 92d1fbe1eb0883cf11d283cea8e658275146411d
Andrew Hsu 5 年之前
父節點
當前提交
c416072ced
共有 100 個文件被更改,包括 3362 次插入976 次删除
  1. 1 1
      hack/dockerfile/install/proxy.installer
  2. 10 9
      vendor.conf
  3. 0 3
      vendor/github.com/docker/libnetwork/README.md
  4. 14 6
      vendor/github.com/docker/libnetwork/controller.go
  5. 1 1
      vendor/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_rawsockaddr_data_int8.go
  6. 1 1
      vendor/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_rawsockaddr_data_uint8.go
  7. 1 1
      vendor/github.com/docker/libnetwork/drivers/bridge/setup_ip_tables.go
  8. 33 18
      vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_network.go
  9. 9 2
      vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_store.go
  10. 33 18
      vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_network.go
  11. 10 2
      vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_store.go
  12. 3 3
      vendor/github.com/docker/libnetwork/drivers/overlay/ostweaks_linux.go
  13. 12 12
      vendor/github.com/docker/libnetwork/drivers/overlay/ov_network.go
  14. 5 2
      vendor/github.com/docker/libnetwork/drivers/windows/windows.go
  15. 2 0
      vendor/github.com/docker/libnetwork/drivers_windows.go
  16. 32 2
      vendor/github.com/docker/libnetwork/firewall_linux.go
  17. 6 4
      vendor/github.com/docker/libnetwork/iptables/iptables.go
  18. 5 6
      vendor/github.com/docker/libnetwork/ipvs/ipvs.go
  19. 27 12
      vendor/github.com/docker/libnetwork/ipvs/netlink.go
  20. 8 3
      vendor/github.com/docker/libnetwork/network.go
  21. 2 16
      vendor/github.com/docker/libnetwork/ns/init_linux.go
  22. 1 1
      vendor/github.com/docker/libnetwork/osl/namespace_linux.go
  23. 9 9
      vendor/github.com/docker/libnetwork/portmapper/mapper.go
  24. 1 1
      vendor/github.com/docker/libnetwork/portmapper/proxy.go
  25. 1 1
      vendor/github.com/docker/libnetwork/resolver.go
  26. 2 2
      vendor/github.com/docker/libnetwork/types/types.go
  27. 52 47
      vendor/github.com/docker/libnetwork/vendor.conf
  28. 354 0
      vendor/github.com/hashicorp/errwrap/LICENSE
  29. 89 0
      vendor/github.com/hashicorp/errwrap/README.md
  30. 169 0
      vendor/github.com/hashicorp/errwrap/errwrap.go
  31. 1 0
      vendor/github.com/hashicorp/errwrap/go.mod
  32. 6 0
      vendor/github.com/hashicorp/go-multierror/README.md
  33. 15 4
      vendor/github.com/hashicorp/go-multierror/append.go
  34. 26 0
      vendor/github.com/hashicorp/go-multierror/flatten.go
  35. 6 2
      vendor/github.com/hashicorp/go-multierror/format.go
  36. 3 0
      vendor/github.com/hashicorp/go-multierror/go.mod
  37. 2 2
      vendor/github.com/hashicorp/go-multierror/multierror.go
  38. 37 0
      vendor/github.com/hashicorp/go-multierror/prefix.go
  39. 16 0
      vendor/github.com/hashicorp/go-multierror/sort.go
  40. 8 0
      vendor/github.com/hashicorp/go-sockaddr/go.mod
  41. 32 9
      vendor/github.com/hashicorp/go-sockaddr/ifaddrs.go
  42. 34 0
      vendor/github.com/hashicorp/go-sockaddr/route_info_android.go
  43. 2 0
      vendor/github.com/hashicorp/go-sockaddr/route_info_linux.go
  44. 27 0
      vendor/github.com/ishidawataru/sctp/GO_LICENSE
  45. 218 0
      vendor/github.com/ishidawataru/sctp/ipsock_linux.go
  46. 56 32
      vendor/github.com/ishidawataru/sctp/sctp.go
  47. 60 51
      vendor/github.com/ishidawataru/sctp/sctp_linux.go
  48. 12 0
      vendor/github.com/ishidawataru/sctp/sctp_unsupported.go
  49. 1 0
      vendor/github.com/vishvananda/netlink/README.md
  50. 66 28
      vendor/github.com/vishvananda/netlink/addr_linux.go
  51. 37 46
      vendor/github.com/vishvananda/netlink/bpf_linux.go
  52. 12 12
      vendor/github.com/vishvananda/netlink/bridge_linux.go
  53. 13 12
      vendor/github.com/vishvananda/netlink/class_linux.go
  54. 7 7
      vendor/github.com/vishvananda/netlink/conntrack_linux.go
  55. 16 1
      vendor/github.com/vishvananda/netlink/filter.go
  56. 47 9
      vendor/github.com/vishvananda/netlink/filter_linux.go
  57. 21 0
      vendor/github.com/vishvananda/netlink/fou.go
  58. 215 0
      vendor/github.com/vishvananda/netlink/fou_linux.go
  59. 15 0
      vendor/github.com/vishvananda/netlink/fou_unspecified.go
  60. 4 3
      vendor/github.com/vishvananda/netlink/genetlink_linux.go
  61. 8 7
      vendor/github.com/vishvananda/netlink/gtp_linux.go
  62. 9 9
      vendor/github.com/vishvananda/netlink/handle_linux.go
  63. 36 0
      vendor/github.com/vishvananda/netlink/handle_unspecified.go
  64. 98 0
      vendor/github.com/vishvananda/netlink/ioctl_linux.go
  65. 85 38
      vendor/github.com/vishvananda/netlink/link.go
  66. 309 165
      vendor/github.com/vishvananda/netlink/link_linux.go
  67. 2 0
      vendor/github.com/vishvananda/netlink/neigh.go
  68. 24 10
      vendor/github.com/vishvananda/netlink/neigh_linux.go
  69. 7 6
      vendor/github.com/vishvananda/netlink/nl/addr_linux.go
  70. 17 25
      vendor/github.com/vishvananda/netlink/nl/link_linux.go
  71. 121 115
      vendor/github.com/vishvananda/netlink/nl/nl_linux.go
  72. 20 19
      vendor/github.com/vishvananda/netlink/nl/route_linux.go
  73. 111 0
      vendor/github.com/vishvananda/netlink/nl/seg6_linux.go
  74. 10 0
      vendor/github.com/vishvananda/netlink/nl/syscall.go
  75. 35 0
      vendor/github.com/vishvananda/netlink/nl/tc_linux.go
  76. 5 4
      vendor/github.com/vishvananda/netlink/protinfo_linux.go
  77. 60 0
      vendor/github.com/vishvananda/netlink/qdisc.go
  78. 129 11
      vendor/github.com/vishvananda/netlink/qdisc_linux.go
  79. 2 0
      vendor/github.com/vishvananda/netlink/route.go
  80. 190 55
      vendor/github.com/vishvananda/netlink/route_linux.go
  81. 1 0
      vendor/github.com/vishvananda/netlink/rule.go
  82. 30 20
      vendor/github.com/vishvananda/netlink/rule_linux.go
  83. 4 4
      vendor/github.com/vishvananda/netlink/socket_linux.go
  84. 7 6
      vendor/github.com/vishvananda/netlink/xfrm.go
  85. 3 4
      vendor/github.com/vishvananda/netlink/xfrm_monitor_linux.go
  86. 9 10
      vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go
  87. 24 3
      vendor/github.com/vishvananda/netlink/xfrm_state.go
  88. 26 13
      vendor/github.com/vishvananda/netlink/xfrm_state_linux.go
  89. 3 2
      vendor/github.com/vishvananda/netns/README.md
  90. 15 2
      vendor/github.com/vishvananda/netns/netns.go
  91. 33 5
      vendor/github.com/vishvananda/netns/netns_linux.go
  92. 0 7
      vendor/github.com/vishvananda/netns/netns_linux_386.go
  93. 0 7
      vendor/github.com/vishvananda/netns/netns_linux_amd64.go
  94. 0 7
      vendor/github.com/vishvananda/netns/netns_linux_arm.go
  95. 0 7
      vendor/github.com/vishvananda/netns/netns_linux_arm64.go
  96. 0 7
      vendor/github.com/vishvananda/netns/netns_linux_ppc64le.go
  97. 0 7
      vendor/github.com/vishvananda/netns/netns_linux_s390x.go
  98. 8 0
      vendor/github.com/vishvananda/netns/netns_unspecified.go
  99. 1 0
      vendor/go.etcd.io/bbolt/README.md
  100. 12 0
      vendor/go.etcd.io/bbolt/bolt_riscv64.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=92d1fbe1eb0883cf11d283cea8e658275146411d
 
 install_proxy() {
 	case "$1" in

+ 10 - 9
vendor.conf

@@ -14,8 +14,8 @@ github.com/mattn/go-shellwords                      a72fbe27a1b0ed0df2f027549450
 github.com/sirupsen/logrus                          8bdbc7bcc01dcbb8ec23dc8a28e332258d25251f # v1.4.1
 github.com/tchap/go-patricia                        a7f0089c6f496e8e70402f61733606daa326cac5 # v2.3.0
 github.com/vdemeester/shakers                       24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3 # v0.1.0
-golang.org/x/net                                    eb5bcb51f2a31c7d5141d810b70815c05d9c9146
-golang.org/x/sys                                    4b34438f7a67ee5f45cc6132e2bad873a20324e9
+golang.org/x/net                                    f3200d17e092c607f615320ecaad13d87ad9a2b3
+golang.org/x/sys                                    4c4f7f33c9ed00de01c4c741d2177abfcfe19307
 github.com/docker/go-units                          519db1ee28dcc9fd2474ae59fca29a810482bfb1 # v0.4.0
 github.com/docker/go-connections                    7395e3f8aa162843a74ed6d48e79627d9792ac55 # v0.4.0
 golang.org/x/text                                   f21a4dfb5e38f5895301dc265a8def02365cc3d0 # v0.3.0
@@ -39,19 +39,20 @@ 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                        92d1fbe1eb0883cf11d283cea8e658275146411d
 github.com/docker/go-events                         9461782956ad83b30282bf90e31fa6a70c255ba9
 github.com/armon/go-radix                           e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
 github.com/armon/go-metrics                         eb0af217e5e9747e41dd5303755356b62d28e3ec
 github.com/hashicorp/go-msgpack                     71c2886f5a673a35f909803f38ece5810165097b
 github.com/hashicorp/memberlist                     3d8438da9589e7b608a83ffac1ef8211486bcb7c
 github.com/sean-/seed                               e2103e2c35297fb7e17febb81e49b312087a2372
-github.com/hashicorp/go-sockaddr                    6d291a969b86c4b633730bfc6b8b9d64c3aafed9
-github.com/hashicorp/go-multierror                  fcdddc395df1ddf4247c69bd436e84cfa0733f7e
+github.com/hashicorp/errwrap                        8a6fb523712970c966eefc6b39ed2c5e74880354 # v1.0.0
+github.com/hashicorp/go-sockaddr                    c7188e74f6acae5a989bdc959aa779f8b9f42faf # v1.0.2
+github.com/hashicorp/go-multierror                  886a7fbe3eb1c874d46f623bfa70af45f425b3d1 # v1.0.0
 github.com/hashicorp/serf                           598c54895cc5a7b1a24a398d635e8c0ea0959870
 github.com/docker/libkv                             458977154600b9f23984d9f4b82e79570b5ae12b
-github.com/vishvananda/netns                        604eaf189ee867d8c147fafc28def2394e878d25
-github.com/vishvananda/netlink                      b2de5d10e38ecce8607e6b438b6d174f389a004e
+github.com/vishvananda/netns                        7109fa855b0ff1ebef7fbd2f6aa613e8db7cfbc0
+github.com/vishvananda/netlink                      a2ad57a690f3caf3015351d2d6e1c0b95c349752
 
 # When updating, consider updating TOMLV_COMMIT in hack/dockerfile/install/tomlv.installer accordingly
 github.com/BurntSushi/toml                          3012a1dbe2e4bd1391d42b32f0577cb7bbc7f005 # v0.3.1
@@ -62,8 +63,8 @@ github.com/coreos/go-semver                         8ab6407b697782a06568d4b7f1db
 github.com/ugorji/go                                b4c50a2b199d93b13dc15e78929cfb23bfdf21ab # v1.1.1
 github.com/hashicorp/consul                         9a9cc9341bb487651a0399e3fc5e1e8a42e62dd9 # v0.5.2
 github.com/miekg/dns                                e57bf427e68187a27e22adceac868350d7a7079b # v1.0.7
-github.com/ishidawataru/sctp                        07191f837fedd2f13d1ec7b5f885f0f3ec54b1cb
-go.etcd.io/bbolt                                    7ee3ded59d4835e10f3e7d0f7603c42aa5e83820 # v1.3.1-etcd.8
+github.com/ishidawataru/sctp                        6e2cb1366111dcf547c13531e3a263a067715847
+go.etcd.io/bbolt                                    a0458a2b35708eef59eb5f620ceb3cd1c01a824d # v1.3.3
 
 # get graph and distribution packages
 github.com/docker/distribution                      0d3efadf0154c2b8a4e7b6621fff9809655cc580

+ 0 - 3
vendor/github.com/docker/libnetwork/README.md

@@ -89,9 +89,6 @@ func main() {
 }
 ```
 
-## Future
-Please refer to [roadmap](ROADMAP.md) for more information.
-
 ## Contributing
 
 Want to hack on libnetwork? [Docker's contributions guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md) apply.

+ 14 - 6
vendor/github.com/docker/libnetwork/controller.go

@@ -706,9 +706,10 @@ const overlayDSROptionString = "dsr"
 // are network specific and modeled in a generic way.
 func (c *controller) NewNetwork(networkType, name string, id string, options ...NetworkOption) (Network, error) {
 	var (
-		cap *driverapi.Capability
-		err error
-		t   *network
+		cap            *driverapi.Capability
+		err            error
+		t              *network
+		skipCfgEpCount bool
 	)
 
 	if id != "" {
@@ -801,8 +802,9 @@ func (c *controller) NewNetwork(networkType, name string, id string, options ...
 		if err = t.applyConfigurationTo(network); err != nil {
 			return nil, types.InternalErrorf("Failed to apply configuration: %v", err)
 		}
+		network.generic[netlabel.Internal] = network.internal
 		defer func() {
-			if err == nil {
+			if err == nil && !skipCfgEpCount {
 				if err := t.getEpCnt().IncEndpointCnt(); err != nil {
 					logrus.Warnf("Failed to update reference count for configuration network %q on creation of network %q: %v",
 						t.Name(), network.Name(), err)
@@ -823,7 +825,13 @@ func (c *controller) NewNetwork(networkType, name string, id string, options ...
 
 	err = c.addNetwork(network)
 	if err != nil {
-		return nil, err
+		if strings.Contains(err.Error(), "restoring existing network") {
+			// This error can be ignored and set this boolean
+			// value to skip a refcount increment for configOnly networks
+			skipCfgEpCount = true
+		} else {
+			return nil, err
+		}
 	}
 	defer func() {
 		if err != nil {
@@ -1298,7 +1306,7 @@ func (c *controller) loadIPAMDriver(name string) error {
 	}
 
 	if err != nil {
-		if err == plugins.ErrNotFound {
+		if errors.Cause(err) == plugins.ErrNotFound {
 			return types.NotFoundErrorf(err.Error())
 		}
 		return err

+ 1 - 1
vendor/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_notarm.go → vendor/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_rawsockaddr_data_int8.go

@@ -1,4 +1,4 @@
-// +build !arm,!ppc64,!ppc64le
+// +build !arm,!ppc64,!ppc64le,!riscv64
 
 package bridge
 

+ 1 - 1
vendor/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_armppc64.go → vendor/github.com/docker/libnetwork/drivers/bridge/netlink_deprecated_linux_rawsockaddr_data_uint8.go

@@ -1,4 +1,4 @@
-// +build arm ppc64 ppc64le
+// +build arm ppc64 ppc64le riscv64
 
 package bridge
 

+ 1 - 1
vendor/github.com/docker/libnetwork/drivers/bridge/setup_ip_tables.go

@@ -302,7 +302,7 @@ func setINC(iface string, enable bool) error {
 				if i == 1 {
 					// Rollback the rule installed on first chain
 					if err2 := iptables.ProgramRule(iptables.Filter, chains[0], iptables.Delete, rules[0]); err2 != nil {
-						logrus.Warn("Failed to rollback iptables rule after failure (%v): %v", err, err2)
+						logrus.Warnf("Failed to rollback iptables rule after failure (%v): %v", err, err2)
 					}
 				}
 				return fmt.Errorf(msg)

+ 33 - 18
vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_network.go

@@ -60,10 +60,14 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
 		// empty parent and --internal are handled the same. Set here to update k/v
 		config.Internal = true
 	}
-	err = d.createNetwork(config)
+	foundExisting, err := d.createNetwork(config)
 	if err != nil {
 		return err
 	}
+
+	if foundExisting {
+		return types.InternalMaskableErrorf("restoring existing network %s", config.ID)
+	}
 	// update persistent db, rollback on fail
 	err = d.storeUpdate(config)
 	if err != nil {
@@ -76,12 +80,18 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
 }
 
 // createNetwork is used by new network callbacks and persistent network cache
-func (d *driver) createNetwork(config *configuration) error {
+func (d *driver) createNetwork(config *configuration) (bool, error) {
+	foundExisting := false
 	networkList := d.getNetworks()
 	for _, nw := range networkList {
 		if config.Parent == nw.config.Parent {
-			return fmt.Errorf("network %s is already using parent interface %s",
-				getDummyName(stringid.TruncateID(nw.config.ID)), config.Parent)
+			if config.ID != nw.config.ID {
+				return false, fmt.Errorf("network %s is already using parent interface %s",
+					getDummyName(stringid.TruncateID(nw.config.ID)), config.Parent)
+			}
+			logrus.Debugf("Create Network for the same ID %s\n", config.ID)
+			foundExisting = true
+			break
 		}
 	}
 	if !parentExists(config.Parent) {
@@ -89,9 +99,10 @@ func (d *driver) createNetwork(config *configuration) error {
 		if config.Internal {
 			err := createDummyLink(config.Parent, getDummyName(stringid.TruncateID(config.ID)))
 			if err != nil {
-				return err
+				return false, err
 			}
 			config.CreatedSlaveLink = true
+
 			// notify the user in logs they have limited communications
 			if config.Parent == getDummyName(stringid.TruncateID(config.ID)) {
 				logrus.Debugf("Empty -o parent= and --internal flags limit communications to other containers inside of network: %s",
@@ -102,22 +113,24 @@ func (d *driver) createNetwork(config *configuration) error {
 			//  a valid example is 'eth0.10' for a parent iface 'eth0' with a vlan id '10'
 			err := createVlanLink(config.Parent)
 			if err != nil {
-				return err
+				return false, err
 			}
 			// if driver created the networks slave link, record it for future deletion
 			config.CreatedSlaveLink = true
 		}
 	}
-	n := &network{
-		id:        config.ID,
-		driver:    d,
-		endpoints: endpointTable{},
-		config:    config,
+	if !foundExisting {
+		n := &network{
+			id:        config.ID,
+			driver:    d,
+			endpoints: endpointTable{},
+			config:    config,
+		}
+		// add the network
+		d.addNetwork(n)
 	}
-	// add the *network
-	d.addNetwork(n)
 
-	return nil
+	return foundExisting, nil
 }
 
 // DeleteNetwork the network for the specified driver type
@@ -182,10 +195,12 @@ func parseNetworkOptions(id string, option options.Generic) (*configuration, err
 		}
 	}
 	// setting the parent to "" will trigger an isolated network dummy parent link
-	if _, ok := option[netlabel.Internal]; ok {
-		config.Internal = true
-		// empty --parent= and --internal are handled the same.
-		config.Parent = ""
+	if val, ok := option[netlabel.Internal]; ok {
+		if internal, ok := val.(bool); ok && internal {
+			config.Internal = true
+			// empty --parent= and --internal are handled the same.
+			config.Parent = ""
+		}
 	}
 	return config, nil
 }

+ 9 - 2
vendor/github.com/docker/libnetwork/drivers/ipvlan/ipvlan_store.go

@@ -55,7 +55,14 @@ func (d *driver) initStore(option map[string]interface{}) error {
 			return types.InternalErrorf("ipvlan driver failed to initialize data store: %v", err)
 		}
 
-		return d.populateNetworks()
+		err = d.populateNetworks()
+		if err != nil {
+			return err
+		}
+		err = d.populateEndpoints()
+		if err != nil {
+			return err
+		}
 	}
 
 	return nil
@@ -73,7 +80,7 @@ func (d *driver) populateNetworks() error {
 	}
 	for _, kvo := range kvol {
 		config := kvo.(*configuration)
-		if err = d.createNetwork(config); err != nil {
+		if _, err = d.createNetwork(config); err != nil {
 			logrus.Warnf("could not create ipvlan network for id %s from persistent state", config.ID)
 		}
 	}

+ 33 - 18
vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_network.go

@@ -64,10 +64,15 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
 		// empty parent and --internal are handled the same. Set here to update k/v
 		config.Internal = true
 	}
-	err = d.createNetwork(config)
+	foundExisting, err := d.createNetwork(config)
 	if err != nil {
 		return err
 	}
+
+	if foundExisting {
+		return types.InternalMaskableErrorf("restoring existing network %s", config.ID)
+	}
+
 	// update persistent db, rollback on fail
 	err = d.storeUpdate(config)
 	if err != nil {
@@ -80,12 +85,18 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
 }
 
 // createNetwork is used by new network callbacks and persistent network cache
-func (d *driver) createNetwork(config *configuration) error {
+func (d *driver) createNetwork(config *configuration) (bool, error) {
+	foundExisting := false
 	networkList := d.getNetworks()
 	for _, nw := range networkList {
 		if config.Parent == nw.config.Parent {
-			return fmt.Errorf("network %s is already using parent interface %s",
-				getDummyName(stringid.TruncateID(nw.config.ID)), config.Parent)
+			if config.ID != nw.config.ID {
+				return false, fmt.Errorf("network %s is already using parent interface %s",
+					getDummyName(stringid.TruncateID(nw.config.ID)), config.Parent)
+			}
+			logrus.Debugf("Create Network for the same ID %s\n", config.ID)
+			foundExisting = true
+			break
 		}
 	}
 	if !parentExists(config.Parent) {
@@ -93,7 +104,7 @@ func (d *driver) createNetwork(config *configuration) error {
 		if config.Internal {
 			err := createDummyLink(config.Parent, getDummyName(stringid.TruncateID(config.ID)))
 			if err != nil {
-				return err
+				return false, err
 			}
 			config.CreatedSlaveLink = true
 			// notify the user in logs they have limited communications
@@ -106,22 +117,24 @@ func (d *driver) createNetwork(config *configuration) error {
 			//  a valid example is 'eth0.10' for a parent iface 'eth0' with a vlan id '10'
 			err := createVlanLink(config.Parent)
 			if err != nil {
-				return err
+				return false, err
 			}
 			// if driver created the networks slave link, record it for future deletion
 			config.CreatedSlaveLink = true
 		}
 	}
-	n := &network{
-		id:        config.ID,
-		driver:    d,
-		endpoints: endpointTable{},
-		config:    config,
+	if !foundExisting {
+		n := &network{
+			id:        config.ID,
+			driver:    d,
+			endpoints: endpointTable{},
+			config:    config,
+		}
+		// add the network
+		d.addNetwork(n)
 	}
-	// add the *network
-	d.addNetwork(n)
 
-	return nil
+	return foundExisting, nil
 }
 
 // DeleteNetwork deletes the network for the specified driver type
@@ -186,10 +199,12 @@ func parseNetworkOptions(id string, option options.Generic) (*configuration, err
 		}
 	}
 	// setting the parent to "" will trigger an isolated network dummy parent link
-	if _, ok := option[netlabel.Internal]; ok {
-		config.Internal = true
-		// empty --parent= and --internal are handled the same.
-		config.Parent = ""
+	if val, ok := option[netlabel.Internal]; ok {
+		if internal, ok := val.(bool); ok && internal {
+			config.Internal = true
+			// empty --parent= and --internal are handled the same.
+			config.Parent = ""
+		}
 	}
 
 	return config, nil

+ 10 - 2
vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_store.go

@@ -55,7 +55,15 @@ func (d *driver) initStore(option map[string]interface{}) error {
 			return types.InternalErrorf("macvlan driver failed to initialize data store: %v", err)
 		}
 
-		return d.populateNetworks()
+		err = d.populateNetworks()
+		if err != nil {
+			return err
+		}
+		err = d.populateEndpoints()
+		if err != nil {
+			return err
+		}
+
 	}
 
 	return nil
@@ -73,7 +81,7 @@ func (d *driver) populateNetworks() error {
 	}
 	for _, kvo := range kvol {
 		config := kvo.(*configuration)
-		if err = d.createNetwork(config); err != nil {
+		if _, err = d.createNetwork(config); err != nil {
 			logrus.Warnf("Could not create macvlan network for id %s from persistent state", config.ID)
 		}
 	}

+ 3 - 3
vendor/github.com/docker/libnetwork/drivers/overlay/ostweaks_linux.go

@@ -7,9 +7,9 @@ import (
 )
 
 var ovConfig = map[string]*kernel.OSValue{
-	"net.ipv4.neigh.default.gc_thresh1": {"8192", checkHigher},
-	"net.ipv4.neigh.default.gc_thresh2": {"49152", checkHigher},
-	"net.ipv4.neigh.default.gc_thresh3": {"65536", checkHigher},
+	"net.ipv4.neigh.default.gc_thresh1": {Value: "8192", CheckFn: checkHigher},
+	"net.ipv4.neigh.default.gc_thresh2": {Value: "49152", CheckFn: checkHigher},
+	"net.ipv4.neigh.default.gc_thresh3": {Value: "65536", CheckFn: checkHigher},
 }
 
 func checkHigher(val1, val2 string) bool {

+ 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
 			}
 

+ 5 - 2
vendor/github.com/docker/libnetwork/drivers/windows/windows.go

@@ -111,7 +111,10 @@ const (
 
 // IsBuiltinLocalDriver validates if network-type is a builtin local-scoped driver
 func IsBuiltinLocalDriver(networkType string) bool {
-	if "l2bridge" == networkType || "l2tunnel" == networkType || "nat" == networkType || "ics" == networkType || "transparent" == networkType {
+	if "l2bridge" == networkType || "l2tunnel" == networkType ||
+		"nat" == networkType || "ics" == networkType ||
+		"transparent" == networkType || "internal" == networkType ||
+		"private" == networkType {
 		return true
 	}
 
@@ -433,7 +436,7 @@ func convertQosPolicies(qosPolicies []types.QosPolicy) ([]json.RawMessage, error
 	// understood by the HCS.
 	for _, elem := range qosPolicies {
 		encodedPolicy, err := json.Marshal(hcsshim.QosPolicy{
-			Type: "QOS",
+			Type:                            "QOS",
 			MaximumOutgoingBandwidthInBytes: elem.MaxEgressBandwidth,
 		})
 

+ 2 - 0
vendor/github.com/docker/libnetwork/drivers_windows.go

@@ -16,6 +16,8 @@ func getInitializers(experimental bool) []initializer {
 		{windows.GetInit("l2bridge"), "l2bridge"},
 		{windows.GetInit("l2tunnel"), "l2tunnel"},
 		{windows.GetInit("nat"), "nat"},
+		{windows.GetInit("internal"), "internal"},
+		{windows.GetInit("private"), "private"},
 		{windows.GetInit("ics"), "ics"},
 	}
 }

+ 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.

+ 6 - 4
vendor/github.com/docker/libnetwork/iptables/iptables.go

@@ -72,11 +72,13 @@ func (e ChainError) Error() string {
 }
 
 func probe() {
-	if out, err := exec.Command("modprobe", "-va", "nf_nat").CombinedOutput(); err != nil {
-		logrus.Warnf("Running modprobe nf_nat failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err)
+	path, err := exec.LookPath("iptables")
+	if err != nil {
+		logrus.Warnf("Failed to find iptables: %v", err)
+		return
 	}
-	if out, err := exec.Command("modprobe", "-va", "xt_conntrack").CombinedOutput(); err != nil {
-		logrus.Warnf("Running modprobe xt_conntrack failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err)
+	if out, err := exec.Command(path, "--wait", "-t", "nat", "-L", "-n").CombinedOutput(); err != nil {
+		logrus.Warnf("Running iptables --wait -t nat -L -n failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err)
 	}
 }
 

+ 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
 	}

+ 27 - 12
vendor/github.com/docker/libnetwork/ipvs/netlink.go

@@ -315,6 +315,7 @@ func assembleStats(msg []byte) (SvcStats, error) {
 func assembleService(attrs []syscall.NetlinkRouteAttr) (*Service, error) {
 
 	var s Service
+	var addressBytes []byte
 
 	for _, attr := range attrs {
 
@@ -327,11 +328,7 @@ func assembleService(attrs []syscall.NetlinkRouteAttr) (*Service, error) {
 		case ipvsSvcAttrProtocol:
 			s.Protocol = native.Uint16(attr.Value)
 		case ipvsSvcAttrAddress:
-			ip, err := parseIP(attr.Value, s.AddressFamily)
-			if err != nil {
-				return nil, err
-			}
-			s.Address = ip
+			addressBytes = attr.Value
 		case ipvsSvcAttrPort:
 			s.Port = binary.BigEndian.Uint16(attr.Value)
 		case ipvsSvcAttrFWMark:
@@ -353,6 +350,16 @@ func assembleService(attrs []syscall.NetlinkRouteAttr) (*Service, error) {
 		}
 
 	}
+
+	// parse Address after parse AddressFamily incase of parseIP error
+	if addressBytes != nil {
+		ip, err := parseIP(addressBytes, s.AddressFamily)
+		if err != nil {
+			return nil, err
+		}
+		s.Address = ip
+	}
+
 	return &s, nil
 }
 
@@ -416,18 +423,18 @@ func (i *Handle) doCmdWithoutAttr(cmd uint8) ([][]byte, error) {
 func assembleDestination(attrs []syscall.NetlinkRouteAttr) (*Destination, error) {
 
 	var d Destination
+	var addressBytes []byte
 
 	for _, attr := range attrs {
 
 		attrType := int(attr.Attr.Type)
 
 		switch attrType {
+
+		case ipvsDestAttrAddressFamily:
+			d.AddressFamily = native.Uint16(attr.Value)
 		case ipvsDestAttrAddress:
-			ip, err := parseIP(attr.Value, syscall.AF_INET)
-			if err != nil {
-				return nil, err
-			}
-			d.Address = ip
+			addressBytes = attr.Value
 		case ipvsDestAttrPort:
 			d.Port = binary.BigEndian.Uint16(attr.Value)
 		case ipvsDestAttrForwardingMethod:
@@ -438,8 +445,6 @@ func assembleDestination(attrs []syscall.NetlinkRouteAttr) (*Destination, error)
 			d.UpperThreshold = native.Uint32(attr.Value)
 		case ipvsDestAttrLowerThreshold:
 			d.LowerThreshold = native.Uint32(attr.Value)
-		case ipvsDestAttrAddressFamily:
-			d.AddressFamily = native.Uint16(attr.Value)
 		case ipvsDestAttrActiveConnections:
 			d.ActiveConnections = int(native.Uint16(attr.Value))
 		case ipvsDestAttrInactiveConnections:
@@ -452,6 +457,16 @@ func assembleDestination(attrs []syscall.NetlinkRouteAttr) (*Destination, error)
 			d.Stats = DstStats(stats)
 		}
 	}
+
+	// parse Address after parse AddressFamily incase of parseIP error
+	if addressBytes != nil {
+		ip, err := parseIP(addressBytes, d.AddressFamily)
+		if err != nil {
+			return nil, err
+		}
+		d.Address = ip
+	}
+
 	return &d, nil
 }
 

+ 8 - 3
vendor/github.com/docker/libnetwork/network.go

@@ -1054,7 +1054,7 @@ func (n *network) delete(force bool, rmLBEndpoint bool) error {
 					t.Name(), n.Name(), err)
 			}
 		} else {
-			logrus.Warnf("Could not find configuration network %q during removal of network %q", n.configOnly, n.Name())
+			logrus.Warnf("Could not find configuration network %q during removal of network %q", n.configFrom, n.Name())
 		}
 	}
 
@@ -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 {

+ 2 - 16
vendor/github.com/docker/libnetwork/ns/init_linux.go

@@ -76,12 +76,8 @@ func NlHandle() *netlink.Handle {
 func getSupportedNlFamilies() []int {
 	fams := []int{syscall.NETLINK_ROUTE}
 	// NETLINK_XFRM test
-	if err := loadXfrmModules(); err != nil {
-		if checkXfrmSocket() != nil {
-			logrus.Warnf("Could not load necessary modules for IPSEC rules: %v", err)
-		} else {
-			fams = append(fams, syscall.NETLINK_XFRM)
-		}
+	if err := checkXfrmSocket(); err != nil {
+		logrus.Warnf("Could not load necessary modules for IPSEC rules: %v", err)
 	} else {
 		fams = append(fams, syscall.NETLINK_XFRM)
 	}
@@ -99,16 +95,6 @@ func getSupportedNlFamilies() []int {
 	return fams
 }
 
-func loadXfrmModules() error {
-	if out, err := exec.Command("modprobe", "-va", "xfrm_user").CombinedOutput(); err != nil {
-		return fmt.Errorf("Running modprobe xfrm_user failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err)
-	}
-	if out, err := exec.Command("modprobe", "-va", "xfrm_algo").CombinedOutput(); err != nil {
-		return fmt.Errorf("Running modprobe xfrm_algo failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err)
-	}
-	return nil
-}
-
 // API check on required xfrm modules (xfrm_user, xfrm_algo)
 func checkXfrmSocket() error {
 	fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_XFRM)

+ 1 - 1
vendor/github.com/docker/libnetwork/osl/namespace_linux.go

@@ -40,7 +40,7 @@ var (
 	loadBalancerConfig = map[string]*kernel.OSValue{
 		// expires connection from the IPVS connection table when the backend is not available
 		// more info: https://github.com/torvalds/linux/blob/master/Documentation/networking/ipvs-sysctl.txt#L126:1
-		"net.ipv4.vs.expire_nodest_conn": {"1", nil},
+		"net.ipv4.vs.expire_nodest_conn": {Value: "1", CheckFn: nil},
 	}
 )
 

+ 9 - 9
vendor/github.com/docker/libnetwork/portmapper/mapper.go

@@ -115,16 +115,16 @@ func (pm *PortMapper) MapRange(container net.Addr, hostIP net.IP, hostPortStart,
 
 		m = &mapping{
 			proto:     proto,
-			host:      &sctp.SCTPAddr{IP: []net.IP{hostIP}, Port: allocatedHostPort},
+			host:      &sctp.SCTPAddr{IPAddrs: []net.IPAddr{{IP: hostIP}}, Port: allocatedHostPort},
 			container: container,
 		}
 
 		if useProxy {
 			sctpAddr := container.(*sctp.SCTPAddr)
-			if len(sctpAddr.IP) == 0 {
+			if len(sctpAddr.IPAddrs) == 0 {
 				return nil, ErrSCTPAddrNoIP
 			}
-			m.userlandProxy, err = newProxy(proto, hostIP, allocatedHostPort, sctpAddr.IP[0], sctpAddr.Port, pm.proxyPath)
+			m.userlandProxy, err = newProxy(proto, hostIP, allocatedHostPort, sctpAddr.IPAddrs[0].IP, sctpAddr.Port, pm.proxyPath)
 			if err != nil {
 				return nil, err
 			}
@@ -210,10 +210,10 @@ func (pm *PortMapper) Unmap(host net.Addr) error {
 	case *net.UDPAddr:
 		return pm.Allocator.ReleasePort(a.IP, "udp", a.Port)
 	case *sctp.SCTPAddr:
-		if len(a.IP) == 0 {
+		if len(a.IPAddrs) == 0 {
 			return ErrSCTPAddrNoIP
 		}
-		return pm.Allocator.ReleasePort(a.IP[0], "sctp", a.Port)
+		return pm.Allocator.ReleasePort(a.IPAddrs[0].IP, "sctp", a.Port)
 	}
 	return ErrUnknownBackendAddressType
 }
@@ -239,11 +239,11 @@ func getKey(a net.Addr) string {
 	case *net.UDPAddr:
 		return fmt.Sprintf("%s:%d/%s", t.IP.String(), t.Port, "udp")
 	case *sctp.SCTPAddr:
-		if len(t.IP) == 0 {
+		if len(t.IPAddrs) == 0 {
 			logrus.Error(ErrSCTPAddrNoIP)
 			return ""
 		}
-		return fmt.Sprintf("%s:%d/%s", t.IP[0].String(), t.Port, "sctp")
+		return fmt.Sprintf("%s:%d/%s", t.IPAddrs[0].IP.String(), t.Port, "sctp")
 	}
 	return ""
 }
@@ -255,11 +255,11 @@ func getIPAndPort(a net.Addr) (net.IP, int) {
 	case *net.UDPAddr:
 		return t.IP, t.Port
 	case *sctp.SCTPAddr:
-		if len(t.IP) == 0 {
+		if len(t.IPAddrs) == 0 {
 			logrus.Error(ErrSCTPAddrNoIP)
 			return nil, 0
 		}
-		return t.IP[0], t.Port
+		return t.IPAddrs[0].IP, t.Port
 	}
 	return nil, 0
 }

+ 1 - 1
vendor/github.com/docker/libnetwork/portmapper/proxy.go

@@ -90,7 +90,7 @@ func newDummyProxy(proto string, hostIP net.IP, hostPort int) (userlandProxy, er
 		addr := &net.UDPAddr{IP: hostIP, Port: hostPort}
 		return &dummyProxy{addr: addr}, nil
 	case "sctp":
-		addr := &sctp.SCTPAddr{IP: []net.IP{hostIP}, Port: hostPort}
+		addr := &sctp.SCTPAddr{IPAddrs: []net.IPAddr{{IP: hostIP}}, Port: hostPort}
 		return &dummyProxy{addr: addr}, nil
 	default:
 		return nil, fmt.Errorf("Unknown addr type: %s", proto)

+ 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)

+ 2 - 2
vendor/github.com/docker/libnetwork/types/types.go

@@ -99,7 +99,7 @@ func (p PortBinding) HostAddr() (net.Addr, error) {
 	case TCP:
 		return &net.TCPAddr{IP: p.HostIP, Port: int(p.HostPort)}, nil
 	case SCTP:
-		return &sctp.SCTPAddr{IP: []net.IP{p.HostIP}, Port: int(p.HostPort)}, nil
+		return &sctp.SCTPAddr{IPAddrs: []net.IPAddr{{IP: p.HostIP}}, Port: int(p.HostPort)}, nil
 	default:
 		return nil, ErrInvalidProtocolBinding(p.Proto.String())
 	}
@@ -113,7 +113,7 @@ func (p PortBinding) ContainerAddr() (net.Addr, error) {
 	case TCP:
 		return &net.TCPAddr{IP: p.IP, Port: int(p.Port)}, nil
 	case SCTP:
-		return &sctp.SCTPAddr{IP: []net.IP{p.IP}, Port: int(p.Port)}, nil
+		return &sctp.SCTPAddr{IPAddrs: []net.IPAddr{{IP: p.IP}}, Port: int(p.Port)}, nil
 	default:
 		return nil, ErrInvalidProtocolBinding(p.Proto.String())
 	}

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

@@ -1,50 +1,55 @@
-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/errwrap            8a6fb523712970c966eefc6b39ed2c5e74880354 # v1.0.0
+github.com/hashicorp/go-msgpack         71c2886f5a673a35f909803f38ece5810165097b
+github.com/hashicorp/go-multierror      886a7fbe3eb1c874d46f623bfa70af45f425b3d1 # v1.0.0
+github.com/hashicorp/memberlist         3d8438da9589e7b608a83ffac1ef8211486bcb7c
+github.com/sean-/seed                   e2103e2c35297fb7e17febb81e49b312087a2372
+github.com/hashicorp/go-sockaddr        c7188e74f6acae5a989bdc959aa779f8b9f42faf # v1.0.2
+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            7109fa855b0ff1ebef7fbd2f6aa613e8db7cfbc0
+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            6e2cb1366111dcf547c13531e3a263a067715847
+
+gotest.tools                            b6e20af1ed078cd01a6413b734051a292450b4cb # v2.1.0
+github.com/google/go-cmp                3af367b6b30c263d47e8895973edcca9a49cf029 # v0.2.0

+ 354 - 0
vendor/github.com/hashicorp/errwrap/LICENSE

@@ -0,0 +1,354 @@
+Mozilla Public License, version 2.0
+
+1. Definitions
+
+1.1. “Contributor”
+
+     means each individual or legal entity that creates, contributes to the
+     creation of, or owns Covered Software.
+
+1.2. “Contributor Version”
+
+     means the combination of the Contributions of others (if any) used by a
+     Contributor and that particular Contributor’s Contribution.
+
+1.3. “Contribution”
+
+     means Covered Software of a particular Contributor.
+
+1.4. “Covered Software”
+
+     means Source Code Form to which the initial Contributor has attached the
+     notice in Exhibit A, the Executable Form of such Source Code Form, and
+     Modifications of such Source Code Form, in each case including portions
+     thereof.
+
+1.5. “Incompatible With Secondary Licenses”
+     means
+
+     a. that the initial Contributor has attached the notice described in
+        Exhibit B to the Covered Software; or
+
+     b. that the Covered Software was made available under the terms of version
+        1.1 or earlier of the License, but not also under the terms of a
+        Secondary License.
+
+1.6. “Executable Form”
+
+     means any form of the work other than Source Code Form.
+
+1.7. “Larger Work”
+
+     means a work that combines Covered Software with other material, in a separate
+     file or files, that is not Covered Software.
+
+1.8. “License”
+
+     means this document.
+
+1.9. “Licensable”
+
+     means having the right to grant, to the maximum extent possible, whether at the
+     time of the initial grant or subsequently, any and all of the rights conveyed by
+     this License.
+
+1.10. “Modifications”
+
+     means any of the following:
+
+     a. any file in Source Code Form that results from an addition to, deletion
+        from, or modification of the contents of Covered Software; or
+
+     b. any new file in Source Code Form that contains any Covered Software.
+
+1.11. “Patent Claims” of a Contributor
+
+      means any patent claim(s), including without limitation, method, process,
+      and apparatus claims, in any patent Licensable by such Contributor that
+      would be infringed, but for the grant of the License, by the making,
+      using, selling, offering for sale, having made, import, or transfer of
+      either its Contributions or its Contributor Version.
+
+1.12. “Secondary License”
+
+      means either the GNU General Public License, Version 2.0, the GNU Lesser
+      General Public License, Version 2.1, the GNU Affero General Public
+      License, Version 3.0, or any later versions of those licenses.
+
+1.13. “Source Code Form”
+
+      means the form of the work preferred for making modifications.
+
+1.14. “You” (or “Your”)
+
+      means an individual or a legal entity exercising rights under this
+      License. For legal entities, “You” includes any entity that controls, is
+      controlled by, or is under common control with You. For purposes of this
+      definition, “control” means (a) the power, direct or indirect, to cause
+      the direction or management of such entity, whether by contract or
+      otherwise, or (b) ownership of more than fifty percent (50%) of the
+      outstanding shares or beneficial ownership of such entity.
+
+
+2. License Grants and Conditions
+
+2.1. Grants
+
+     Each Contributor hereby grants You a world-wide, royalty-free,
+     non-exclusive license:
+
+     a. under intellectual property rights (other than patent or trademark)
+        Licensable by such Contributor to use, reproduce, make available,
+        modify, display, perform, distribute, and otherwise exploit its
+        Contributions, either on an unmodified basis, with Modifications, or as
+        part of a Larger Work; and
+
+     b. under Patent Claims of such Contributor to make, use, sell, offer for
+        sale, have made, import, and otherwise transfer either its Contributions
+        or its Contributor Version.
+
+2.2. Effective Date
+
+     The licenses granted in Section 2.1 with respect to any Contribution become
+     effective for each Contribution on the date the Contributor first distributes
+     such Contribution.
+
+2.3. Limitations on Grant Scope
+
+     The licenses granted in this Section 2 are the only rights granted under this
+     License. No additional rights or licenses will be implied from the distribution
+     or licensing of Covered Software under this License. Notwithstanding Section
+     2.1(b) above, no patent license is granted by a Contributor:
+
+     a. for any code that a Contributor has removed from Covered Software; or
+
+     b. for infringements caused by: (i) Your and any other third party’s
+        modifications of Covered Software, or (ii) the combination of its
+        Contributions with other software (except as part of its Contributor
+        Version); or
+
+     c. under Patent Claims infringed by Covered Software in the absence of its
+        Contributions.
+
+     This License does not grant any rights in the trademarks, service marks, or
+     logos of any Contributor (except as may be necessary to comply with the
+     notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+     No Contributor makes additional grants as a result of Your choice to
+     distribute the Covered Software under a subsequent version of this License
+     (see Section 10.2) or under the terms of a Secondary License (if permitted
+     under the terms of Section 3.3).
+
+2.5. Representation
+
+     Each Contributor represents that the Contributor believes its Contributions
+     are its original creation(s) or it has sufficient rights to grant the
+     rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+     This License is not intended to limit any rights You have under applicable
+     copyright doctrines of fair use, fair dealing, or other equivalents.
+
+2.7. Conditions
+
+     Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
+     Section 2.1.
+
+
+3. Responsibilities
+
+3.1. Distribution of Source Form
+
+     All distribution of Covered Software in Source Code Form, including any
+     Modifications that You create or to which You contribute, must be under the
+     terms of this License. You must inform recipients that the Source Code Form
+     of the Covered Software is governed by the terms of this License, and how
+     they can obtain a copy of this License. You may not attempt to alter or
+     restrict the recipients’ rights in the Source Code Form.
+
+3.2. Distribution of Executable Form
+
+     If You distribute Covered Software in Executable Form then:
+
+     a. such Covered Software must also be made available in Source Code Form,
+        as described in Section 3.1, and You must inform recipients of the
+        Executable Form how they can obtain a copy of such Source Code Form by
+        reasonable means in a timely manner, at a charge no more than the cost
+        of distribution to the recipient; and
+
+     b. You may distribute such Executable Form under the terms of this License,
+        or sublicense it under different terms, provided that the license for
+        the Executable Form does not attempt to limit or alter the recipients’
+        rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+     You may create and distribute a Larger Work under terms of Your choice,
+     provided that You also comply with the requirements of this License for the
+     Covered Software. If the Larger Work is a combination of Covered Software
+     with a work governed by one or more Secondary Licenses, and the Covered
+     Software is not Incompatible With Secondary Licenses, this License permits
+     You to additionally distribute such Covered Software under the terms of
+     such Secondary License(s), so that the recipient of the Larger Work may, at
+     their option, further distribute the Covered Software under the terms of
+     either this License or such Secondary License(s).
+
+3.4. Notices
+
+     You may not remove or alter the substance of any license notices (including
+     copyright notices, patent notices, disclaimers of warranty, or limitations
+     of liability) contained within the Source Code Form of the Covered
+     Software, except that You may alter any license notices to the extent
+     required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+     You may choose to offer, and to charge a fee for, warranty, support,
+     indemnity or liability obligations to one or more recipients of Covered
+     Software. However, You may do so only on Your own behalf, and not on behalf
+     of any Contributor. You must make it absolutely clear that any such
+     warranty, support, indemnity, or liability obligation is offered by You
+     alone, and You hereby agree to indemnify every Contributor for any
+     liability incurred by such Contributor as a result of warranty, support,
+     indemnity or liability terms You offer. You may include additional
+     disclaimers of warranty and limitations of liability specific to any
+     jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+
+   If it is impossible for You to comply with any of the terms of this License
+   with respect to some or all of the Covered Software due to statute, judicial
+   order, or regulation then You must: (a) comply with the terms of this License
+   to the maximum extent possible; and (b) describe the limitations and the code
+   they affect. Such description must be placed in a text file included with all
+   distributions of the Covered Software under this License. Except to the
+   extent prohibited by statute or regulation, such description must be
+   sufficiently detailed for a recipient of ordinary skill to be able to
+   understand it.
+
+5. Termination
+
+5.1. The rights granted under this License will terminate automatically if You
+     fail to comply with any of its terms. However, if You become compliant,
+     then the rights granted under this License from a particular Contributor
+     are reinstated (a) provisionally, unless and until such Contributor
+     explicitly and finally terminates Your grants, and (b) on an ongoing basis,
+     if such Contributor fails to notify You of the non-compliance by some
+     reasonable means prior to 60 days after You have come back into compliance.
+     Moreover, Your grants from a particular Contributor are reinstated on an
+     ongoing basis if such Contributor notifies You of the non-compliance by
+     some reasonable means, this is the first time You have received notice of
+     non-compliance with this License from such Contributor, and You become
+     compliant prior to 30 days after Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+     infringement claim (excluding declaratory judgment actions, counter-claims,
+     and cross-claims) alleging that a Contributor Version directly or
+     indirectly infringes any patent, then the rights granted to You by any and
+     all Contributors for the Covered Software under Section 2.1 of this License
+     shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
+     license agreements (excluding distributors and resellers) which have been
+     validly granted by You or Your distributors under this License prior to
+     termination shall survive termination.
+
+6. Disclaimer of Warranty
+
+   Covered Software is provided under this License on an “as is” basis, without
+   warranty of any kind, either expressed, implied, or statutory, including,
+   without limitation, warranties that the Covered Software is free of defects,
+   merchantable, fit for a particular purpose or non-infringing. The entire
+   risk as to the quality and performance of the Covered Software is with You.
+   Should any Covered Software prove defective in any respect, You (not any
+   Contributor) assume the cost of any necessary servicing, repair, or
+   correction. This disclaimer of warranty constitutes an essential part of this
+   License. No use of  any Covered Software is authorized under this License
+   except under this disclaimer.
+
+7. Limitation of Liability
+
+   Under no circumstances and under no legal theory, whether tort (including
+   negligence), contract, or otherwise, shall any Contributor, or anyone who
+   distributes Covered Software as permitted above, be liable to You for any
+   direct, indirect, special, incidental, or consequential damages of any
+   character including, without limitation, damages for lost profits, loss of
+   goodwill, work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses, even if such party shall have been
+   informed of the possibility of such damages. This limitation of liability
+   shall not apply to liability for death or personal injury resulting from such
+   party’s negligence to the extent applicable law prohibits such limitation.
+   Some jurisdictions do not allow the exclusion or limitation of incidental or
+   consequential damages, so this exclusion and limitation may not apply to You.
+
+8. Litigation
+
+   Any litigation relating to this License may be brought only in the courts of
+   a jurisdiction where the defendant maintains its principal place of business
+   and such litigation shall be governed by laws of that jurisdiction, without
+   reference to its conflict-of-law provisions. Nothing in this Section shall
+   prevent a party’s ability to bring cross-claims or counter-claims.
+
+9. Miscellaneous
+
+   This License represents the complete agreement concerning the subject matter
+   hereof. If any provision of this License is held to be unenforceable, such
+   provision shall be reformed only to the extent necessary to make it
+   enforceable. Any law or regulation which provides that the language of a
+   contract shall be construed against the drafter shall not be used to construe
+   this License against a Contributor.
+
+
+10. Versions of the License
+
+10.1. New Versions
+
+      Mozilla Foundation is the license steward. Except as provided in Section
+      10.3, no one other than the license steward has the right to modify or
+      publish new versions of this License. Each version will be given a
+      distinguishing version number.
+
+10.2. Effect of New Versions
+
+      You may distribute the Covered Software under the terms of the version of
+      the License under which You originally received the Covered Software, or
+      under the terms of any subsequent version published by the license
+      steward.
+
+10.3. Modified Versions
+
+      If you create software not governed by this License, and you want to
+      create a new license for such software, you may create and use a modified
+      version of this License if you rename the license and remove any
+      references to the name of the license steward (except to note that such
+      modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
+      If You choose to distribute Source Code Form that is Incompatible With
+      Secondary Licenses under the terms of this version of the License, the
+      notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+
+      This Source Code Form is subject to the
+      terms of the Mozilla Public License, v.
+      2.0. If a copy of the MPL was not
+      distributed with this file, You can
+      obtain one at
+      http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular file, then
+You may include the notice in a location (such as a LICENSE file in a relevant
+directory) where a recipient would be likely to look for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - “Incompatible With Secondary Licenses” Notice
+
+      This Source Code Form is “Incompatible
+      With Secondary Licenses”, as defined by
+      the Mozilla Public License, v. 2.0.
+

+ 89 - 0
vendor/github.com/hashicorp/errwrap/README.md

@@ -0,0 +1,89 @@
+# errwrap
+
+`errwrap` is a package for Go that formalizes the pattern of wrapping errors
+and checking if an error contains another error.
+
+There is a common pattern in Go of taking a returned `error` value and
+then wrapping it (such as with `fmt.Errorf`) before returning it. The problem
+with this pattern is that you completely lose the original `error` structure.
+
+Arguably the _correct_ approach is that you should make a custom structure
+implementing the `error` interface, and have the original error as a field
+on that structure, such [as this example](http://golang.org/pkg/os/#PathError).
+This is a good approach, but you have to know the entire chain of possible
+rewrapping that happens, when you might just care about one.
+
+`errwrap` formalizes this pattern (it doesn't matter what approach you use
+above) by giving a single interface for wrapping errors, checking if a specific
+error is wrapped, and extracting that error.
+
+## Installation and Docs
+
+Install using `go get github.com/hashicorp/errwrap`.
+
+Full documentation is available at
+http://godoc.org/github.com/hashicorp/errwrap
+
+## Usage
+
+#### Basic Usage
+
+Below is a very basic example of its usage:
+
+```go
+// A function that always returns an error, but wraps it, like a real
+// function might.
+func tryOpen() error {
+	_, err := os.Open("/i/dont/exist")
+	if err != nil {
+		return errwrap.Wrapf("Doesn't exist: {{err}}", err)
+	}
+
+	return nil
+}
+
+func main() {
+	err := tryOpen()
+
+	// We can use the Contains helpers to check if an error contains
+	// another error. It is safe to do this with a nil error, or with
+	// an error that doesn't even use the errwrap package.
+	if errwrap.Contains(err, "does not exist") {
+		// Do something
+	}
+	if errwrap.ContainsType(err, new(os.PathError)) {
+		// Do something
+	}
+
+	// Or we can use the associated `Get` functions to just extract
+	// a specific error. This would return nil if that specific error doesn't
+	// exist.
+	perr := errwrap.GetType(err, new(os.PathError))
+}
+```
+
+#### Custom Types
+
+If you're already making custom types that properly wrap errors, then
+you can get all the functionality of `errwraps.Contains` and such by
+implementing the `Wrapper` interface with just one function. Example:
+
+```go
+type AppError {
+  Code ErrorCode
+  Err  error
+}
+
+func (e *AppError) WrappedErrors() []error {
+  return []error{e.Err}
+}
+```
+
+Now this works:
+
+```go
+err := &AppError{Err: fmt.Errorf("an error")}
+if errwrap.ContainsType(err, fmt.Errorf("")) {
+	// This will work!
+}
+```

+ 169 - 0
vendor/github.com/hashicorp/errwrap/errwrap.go

@@ -0,0 +1,169 @@
+// Package errwrap implements methods to formalize error wrapping in Go.
+//
+// All of the top-level functions that take an `error` are built to be able
+// to take any error, not just wrapped errors. This allows you to use errwrap
+// without having to type-check and type-cast everywhere.
+package errwrap
+
+import (
+	"errors"
+	"reflect"
+	"strings"
+)
+
+// WalkFunc is the callback called for Walk.
+type WalkFunc func(error)
+
+// Wrapper is an interface that can be implemented by custom types to
+// have all the Contains, Get, etc. functions in errwrap work.
+//
+// When Walk reaches a Wrapper, it will call the callback for every
+// wrapped error in addition to the wrapper itself. Since all the top-level
+// functions in errwrap use Walk, this means that all those functions work
+// with your custom type.
+type Wrapper interface {
+	WrappedErrors() []error
+}
+
+// Wrap defines that outer wraps inner, returning an error type that
+// can be cleanly used with the other methods in this package, such as
+// Contains, GetAll, etc.
+//
+// This function won't modify the error message at all (the outer message
+// will be used).
+func Wrap(outer, inner error) error {
+	return &wrappedError{
+		Outer: outer,
+		Inner: inner,
+	}
+}
+
+// Wrapf wraps an error with a formatting message. This is similar to using
+// `fmt.Errorf` to wrap an error. If you're using `fmt.Errorf` to wrap
+// errors, you should replace it with this.
+//
+// format is the format of the error message. The string '{{err}}' will
+// be replaced with the original error message.
+func Wrapf(format string, err error) error {
+	outerMsg := "<nil>"
+	if err != nil {
+		outerMsg = err.Error()
+	}
+
+	outer := errors.New(strings.Replace(
+		format, "{{err}}", outerMsg, -1))
+
+	return Wrap(outer, err)
+}
+
+// Contains checks if the given error contains an error with the
+// message msg. If err is not a wrapped error, this will always return
+// false unless the error itself happens to match this msg.
+func Contains(err error, msg string) bool {
+	return len(GetAll(err, msg)) > 0
+}
+
+// ContainsType checks if the given error contains an error with
+// the same concrete type as v. If err is not a wrapped error, this will
+// check the err itself.
+func ContainsType(err error, v interface{}) bool {
+	return len(GetAllType(err, v)) > 0
+}
+
+// Get is the same as GetAll but returns the deepest matching error.
+func Get(err error, msg string) error {
+	es := GetAll(err, msg)
+	if len(es) > 0 {
+		return es[len(es)-1]
+	}
+
+	return nil
+}
+
+// GetType is the same as GetAllType but returns the deepest matching error.
+func GetType(err error, v interface{}) error {
+	es := GetAllType(err, v)
+	if len(es) > 0 {
+		return es[len(es)-1]
+	}
+
+	return nil
+}
+
+// GetAll gets all the errors that might be wrapped in err with the
+// given message. The order of the errors is such that the outermost
+// matching error (the most recent wrap) is index zero, and so on.
+func GetAll(err error, msg string) []error {
+	var result []error
+
+	Walk(err, func(err error) {
+		if err.Error() == msg {
+			result = append(result, err)
+		}
+	})
+
+	return result
+}
+
+// GetAllType gets all the errors that are the same type as v.
+//
+// The order of the return value is the same as described in GetAll.
+func GetAllType(err error, v interface{}) []error {
+	var result []error
+
+	var search string
+	if v != nil {
+		search = reflect.TypeOf(v).String()
+	}
+	Walk(err, func(err error) {
+		var needle string
+		if err != nil {
+			needle = reflect.TypeOf(err).String()
+		}
+
+		if needle == search {
+			result = append(result, err)
+		}
+	})
+
+	return result
+}
+
+// Walk walks all the wrapped errors in err and calls the callback. If
+// err isn't a wrapped error, this will be called once for err. If err
+// is a wrapped error, the callback will be called for both the wrapper
+// that implements error as well as the wrapped error itself.
+func Walk(err error, cb WalkFunc) {
+	if err == nil {
+		return
+	}
+
+	switch e := err.(type) {
+	case *wrappedError:
+		cb(e.Outer)
+		Walk(e.Inner, cb)
+	case Wrapper:
+		cb(err)
+
+		for _, err := range e.WrappedErrors() {
+			Walk(err, cb)
+		}
+	default:
+		cb(err)
+	}
+}
+
+// wrappedError is an implementation of error that has both the
+// outer and inner errors.
+type wrappedError struct {
+	Outer error
+	Inner error
+}
+
+func (w *wrappedError) Error() string {
+	return w.Outer.Error()
+}
+
+func (w *wrappedError) WrappedErrors() []error {
+	return []error{w.Outer, w.Inner}
+}

+ 1 - 0
vendor/github.com/hashicorp/errwrap/go.mod

@@ -0,0 +1 @@
+module github.com/hashicorp/errwrap

+ 6 - 0
vendor/github.com/hashicorp/go-multierror/README.md

@@ -1,5 +1,11 @@
 # go-multierror
 
+[![Build Status](http://img.shields.io/travis/hashicorp/go-multierror.svg?style=flat-square)][travis]
+[![Go Documentation](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)][godocs]
+
+[travis]: https://travis-ci.org/hashicorp/go-multierror
+[godocs]: https://godoc.org/github.com/hashicorp/go-multierror
+
 `go-multierror` is a package for Go that provides a mechanism for
 representing a list of `error` values as a single `error`.
 

+ 15 - 4
vendor/github.com/hashicorp/go-multierror/append.go

@@ -14,7 +14,20 @@ func Append(err error, errs ...error) *Error {
 			err = new(Error)
 		}
 
-		err.Errors = append(err.Errors, errs...)
+		// Go through each error and flatten
+		for _, e := range errs {
+			switch e := e.(type) {
+			case *Error:
+				if e != nil {
+					err.Errors = append(err.Errors, e.Errors...)
+				}
+			default:
+				if e != nil {
+					err.Errors = append(err.Errors, e)
+				}
+			}
+		}
+
 		return err
 	default:
 		newErrs := make([]error, 0, len(errs)+1)
@@ -23,8 +36,6 @@ func Append(err error, errs ...error) *Error {
 		}
 		newErrs = append(newErrs, errs...)
 
-		return &Error{
-			Errors: newErrs,
-		}
+		return Append(&Error{}, newErrs...)
 	}
 }

+ 26 - 0
vendor/github.com/hashicorp/go-multierror/flatten.go

@@ -0,0 +1,26 @@
+package multierror
+
+// Flatten flattens the given error, merging any *Errors together into
+// a single *Error.
+func Flatten(err error) error {
+	// If it isn't an *Error, just return the error as-is
+	if _, ok := err.(*Error); !ok {
+		return err
+	}
+
+	// Otherwise, make the result and flatten away!
+	flatErr := new(Error)
+	flatten(err, flatErr)
+	return flatErr
+}
+
+func flatten(err error, flatErr *Error) {
+	switch err := err.(type) {
+	case *Error:
+		for _, e := range err.Errors {
+			flatten(e, flatErr)
+		}
+	default:
+		flatErr.Errors = append(flatErr.Errors, err)
+	}
+}

+ 6 - 2
vendor/github.com/hashicorp/go-multierror/format.go

@@ -12,12 +12,16 @@ type ErrorFormatFunc func([]error) string
 // ListFormatFunc is a basic formatter that outputs the number of errors
 // that occurred along with a bullet point list of the errors.
 func ListFormatFunc(es []error) string {
+	if len(es) == 1 {
+		return fmt.Sprintf("1 error occurred:\n\t* %s\n\n", es[0])
+	}
+
 	points := make([]string, len(es))
 	for i, err := range es {
 		points[i] = fmt.Sprintf("* %s", err)
 	}
 
 	return fmt.Sprintf(
-		"%d error(s) occurred:\n\n%s",
-		len(es), strings.Join(points, "\n"))
+		"%d errors occurred:\n\t%s\n\n",
+		len(es), strings.Join(points, "\n\t"))
 }

+ 3 - 0
vendor/github.com/hashicorp/go-multierror/go.mod

@@ -0,0 +1,3 @@
+module github.com/hashicorp/go-multierror
+
+require github.com/hashicorp/errwrap v1.0.0

+ 2 - 2
vendor/github.com/hashicorp/go-multierror/multierror.go

@@ -40,11 +40,11 @@ func (e *Error) GoString() string {
 }
 
 // WrappedErrors returns the list of errors that this Error is wrapping.
-// It is an implementatin of the errwrap.Wrapper interface so that
+// It is an implementation of the errwrap.Wrapper interface so that
 // multierror.Error can be used with that library.
 //
 // This method is not safe to be called concurrently and is no different
-// than accessing the Errors field directly. It is implementd only to
+// than accessing the Errors field directly. It is implemented only to
 // satisfy the errwrap.Wrapper interface.
 func (e *Error) WrappedErrors() []error {
 	return e.Errors

+ 37 - 0
vendor/github.com/hashicorp/go-multierror/prefix.go

@@ -0,0 +1,37 @@
+package multierror
+
+import (
+	"fmt"
+
+	"github.com/hashicorp/errwrap"
+)
+
+// Prefix is a helper function that will prefix some text
+// to the given error. If the error is a multierror.Error, then
+// it will be prefixed to each wrapped error.
+//
+// This is useful to use when appending multiple multierrors
+// together in order to give better scoping.
+func Prefix(err error, prefix string) error {
+	if err == nil {
+		return nil
+	}
+
+	format := fmt.Sprintf("%s {{err}}", prefix)
+	switch err := err.(type) {
+	case *Error:
+		// Typed nils can reach here, so initialize if we are nil
+		if err == nil {
+			err = new(Error)
+		}
+
+		// Wrap each of the errors
+		for i, e := range err.Errors {
+			err.Errors[i] = errwrap.Wrapf(format, e)
+		}
+
+		return err
+	default:
+		return errwrap.Wrapf(format, err)
+	}
+}

+ 16 - 0
vendor/github.com/hashicorp/go-multierror/sort.go

@@ -0,0 +1,16 @@
+package multierror
+
+// Len implements sort.Interface function for length
+func (err Error) Len() int {
+	return len(err.Errors)
+}
+
+// Swap implements sort.Interface function for swapping elements
+func (err Error) Swap(i, j int) {
+	err.Errors[i], err.Errors[j] = err.Errors[j], err.Errors[i]
+}
+
+// Less implements sort.Interface function for determining order
+func (err Error) Less(i, j int) bool {
+	return err.Errors[i].Error() < err.Errors[j].Error()
+}

+ 8 - 0
vendor/github.com/hashicorp/go-sockaddr/go.mod

@@ -0,0 +1,8 @@
+module github.com/hashicorp/go-sockaddr
+
+require (
+	github.com/hashicorp/errwrap v1.0.0
+	github.com/mitchellh/cli v1.0.0
+	github.com/mitchellh/go-wordwrap v1.0.0
+	github.com/ryanuber/columnize v2.1.0+incompatible
+)

+ 32 - 9
vendor/github.com/hashicorp/go-sockaddr/ifaddrs.go

@@ -1197,23 +1197,46 @@ func parseDefaultIfNameFromRoute(routeOut string) (string, error) {
 // parseDefaultIfNameFromIPCmd parses the default interface from ip(8) for
 // Linux.
 func parseDefaultIfNameFromIPCmd(routeOut string) (string, error) {
+	parsedLines := parseIfNameFromIPCmd(routeOut)
+	for _, parsedLine := range parsedLines {
+		if parsedLine[0] == "default" &&
+			parsedLine[1] == "via" &&
+			parsedLine[3] == "dev" {
+			ifName := strings.TrimSpace(parsedLine[4])
+			return ifName, nil
+		}
+	}
+
+	return "", errors.New("No default interface found")
+}
+
+// parseDefaultIfNameFromIPCmdAndroid parses the default interface from ip(8) for
+// Android.
+func parseDefaultIfNameFromIPCmdAndroid(routeOut string) (string, error) {
+	parsedLines := parseIfNameFromIPCmd(routeOut)
+	if (len(parsedLines) > 0) {
+		ifName := strings.TrimSpace(parsedLines[0][4])
+		return ifName, nil
+	}
+
+	return "", errors.New("No default interface found")
+}
+
+
+// parseIfNameFromIPCmd parses interfaces from ip(8) for
+// Linux.
+func parseIfNameFromIPCmd(routeOut string) [][]string {
 	lines := strings.Split(routeOut, "\n")
 	re := whitespaceRE.Copy()
+	parsedLines := make([][]string, 0, len(lines))
 	for _, line := range lines {
 		kvs := re.Split(line, -1)
 		if len(kvs) < 5 {
 			continue
 		}
-
-		if kvs[0] == "default" &&
-			kvs[1] == "via" &&
-			kvs[3] == "dev" {
-			ifName := strings.TrimSpace(kvs[4])
-			return ifName, nil
-		}
+		parsedLines = append(parsedLines, kvs)
 	}
-
-	return "", errors.New("No default interface found")
+	return parsedLines
 }
 
 // parseDefaultIfNameWindows parses the default interface from `netstat -rn` and

+ 34 - 0
vendor/github.com/hashicorp/go-sockaddr/route_info_android.go

@@ -0,0 +1,34 @@
+package sockaddr
+
+import (
+	"errors"
+	"os/exec"
+)
+
+type routeInfo struct {
+	cmds map[string][]string
+}
+
+// NewRouteInfo returns a Android-specific implementation of the RouteInfo
+// interface.
+func NewRouteInfo() (routeInfo, error) {
+	return routeInfo{
+		cmds: map[string][]string{"ip": {"/system/bin/ip", "route", "get", "8.8.8.8"}},
+	}, nil
+}
+
+// GetDefaultInterfaceName returns the interface name attached to the default
+// route on the default interface.
+func (ri routeInfo) GetDefaultInterfaceName() (string, error) {
+	out, err := exec.Command(ri.cmds["ip"][0], ri.cmds["ip"][1:]...).Output()
+	if err != nil {
+		return "", err
+	}
+
+
+	var ifName string
+	if ifName, err = parseDefaultIfNameFromIPCmdAndroid(string(out)); err != nil {
+		return "", errors.New("No default interface found")
+	}
+	return ifName, nil
+}

+ 2 - 0
vendor/github.com/hashicorp/go-sockaddr/route_info_linux.go

@@ -1,3 +1,5 @@
+// +build !android
+
 package sockaddr
 
 import (

+ 27 - 0
vendor/github.com/ishidawataru/sctp/GO_LICENSE

@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 218 - 0
vendor/github.com/ishidawataru/sctp/ipsock_linux.go

@@ -0,0 +1,218 @@
+package sctp
+
+import (
+	"net"
+	"os"
+	"sync"
+	"syscall"
+)
+
+//from https://github.com/golang/go
+// Boolean to int.
+func boolint(b bool) int {
+	if b {
+		return 1
+	}
+	return 0
+}
+
+//from https://github.com/golang/go
+func ipToSockaddr(family int, ip net.IP, port int, zone string) (syscall.Sockaddr, error) {
+	switch family {
+	case syscall.AF_INET:
+		if len(ip) == 0 {
+			ip = net.IPv4zero
+		}
+		ip4 := ip.To4()
+		if ip4 == nil {
+			return nil, &net.AddrError{Err: "non-IPv4 address", Addr: ip.String()}
+		}
+		sa := &syscall.SockaddrInet4{Port: port}
+		copy(sa.Addr[:], ip4)
+		return sa, nil
+	case syscall.AF_INET6:
+		// In general, an IP wildcard address, which is either
+		// "0.0.0.0" or "::", means the entire IP addressing
+		// space. For some historical reason, it is used to
+		// specify "any available address" on some operations
+		// of IP node.
+		//
+		// When the IP node supports IPv4-mapped IPv6 address,
+		// we allow an listener to listen to the wildcard
+		// address of both IP addressing spaces by specifying
+		// IPv6 wildcard address.
+		if len(ip) == 0 || ip.Equal(net.IPv4zero) {
+			ip = net.IPv6zero
+		}
+		// We accept any IPv6 address including IPv4-mapped
+		// IPv6 address.
+		ip6 := ip.To16()
+		if ip6 == nil {
+			return nil, &net.AddrError{Err: "non-IPv6 address", Addr: ip.String()}
+		}
+		//we set ZoneId to 0, as currently we use this functon only to probe the IP capabilities of the host
+		//if real Zone handling is required, the zone cache implementation in golang/net should be pulled here
+		sa := &syscall.SockaddrInet6{Port: port, ZoneId: 0}
+		copy(sa.Addr[:], ip6)
+		return sa, nil
+	}
+	return nil, &net.AddrError{Err: "invalid address family", Addr: ip.String()}
+}
+
+//from https://github.com/golang/go
+func sockaddr(a *net.TCPAddr, family int) (syscall.Sockaddr, error) {
+	if a == nil {
+		return nil, nil
+	}
+	return ipToSockaddr(family, a.IP, a.Port, a.Zone)
+}
+
+//from https://github.com/golang/go
+type ipStackCapabilities struct {
+	sync.Once             // guards following
+	ipv4Enabled           bool
+	ipv6Enabled           bool
+	ipv4MappedIPv6Enabled bool
+}
+
+//from https://github.com/golang/go
+var ipStackCaps ipStackCapabilities
+
+//from https://github.com/golang/go
+// supportsIPv4 reports whether the platform supports IPv4 networking
+// functionality.
+func supportsIPv4() bool {
+	ipStackCaps.Once.Do(ipStackCaps.probe)
+	return ipStackCaps.ipv4Enabled
+}
+
+//from https://github.com/golang/go
+// supportsIPv6 reports whether the platform supports IPv6 networking
+// functionality.
+func supportsIPv6() bool {
+	ipStackCaps.Once.Do(ipStackCaps.probe)
+	return ipStackCaps.ipv6Enabled
+}
+
+//from https://github.com/golang/go
+// supportsIPv4map reports whether the platform supports mapping an
+// IPv4 address inside an IPv6 address at transport layer
+// protocols. See RFC 4291, RFC 4038 and RFC 3493.
+func supportsIPv4map() bool {
+	ipStackCaps.Once.Do(ipStackCaps.probe)
+	return ipStackCaps.ipv4MappedIPv6Enabled
+}
+
+//from https://github.com/golang/go
+// Probe probes IPv4, IPv6 and IPv4-mapped IPv6 communication
+// capabilities which are controlled by the IPV6_V6ONLY socket option
+// and kernel configuration.
+//
+// Should we try to use the IPv4 socket interface if we're only
+// dealing with IPv4 sockets? As long as the host system understands
+// IPv4-mapped IPv6, it's okay to pass IPv4-mapeed IPv6 addresses to
+// the IPv6 interface. That simplifies our code and is most
+// general. Unfortunately, we need to run on kernels built without
+// IPv6 support too. So probe the kernel to figure it out.
+func (p *ipStackCapabilities) probe() {
+	s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
+	switch err {
+	case syscall.EAFNOSUPPORT, syscall.EPROTONOSUPPORT:
+	case nil:
+		syscall.Close(s)
+		p.ipv4Enabled = true
+	}
+	var probes = []struct {
+		laddr net.TCPAddr
+		value int
+	}{
+		// IPv6 communication capability
+		{laddr: net.TCPAddr{IP: net.IPv6loopback}, value: 1},
+		// IPv4-mapped IPv6 address communication capability
+		{laddr: net.TCPAddr{IP: net.IPv4(127, 0, 0, 1)}, value: 0},
+	}
+
+	for i := range probes {
+		s, err := syscall.Socket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
+		if err != nil {
+			continue
+		}
+		defer syscall.Close(s)
+		syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, probes[i].value)
+		sa, err := sockaddr(&(probes[i].laddr), syscall.AF_INET6)
+		if err != nil {
+			continue
+		}
+		if err := syscall.Bind(s, sa); err != nil {
+			continue
+		}
+		if i == 0 {
+			p.ipv6Enabled = true
+		} else {
+			p.ipv4MappedIPv6Enabled = true
+		}
+	}
+}
+
+//from https://github.com/golang/go
+//Change: we check the first IP address in the list of candidate SCTP IP addresses
+func (a *SCTPAddr) isWildcard() bool {
+	if a == nil {
+		return true
+	}
+	if 0 == len(a.IPAddrs) {
+		return true
+	}
+
+	return a.IPAddrs[0].IP.IsUnspecified()
+}
+
+func (a *SCTPAddr) family() int {
+	if a != nil {
+		for _, ip := range a.IPAddrs {
+			if ip.IP.To4() == nil {
+				return syscall.AF_INET6
+			}
+		}
+	}
+	return syscall.AF_INET
+}
+
+//from https://github.com/golang/go
+func favoriteAddrFamily(network string, laddr *SCTPAddr, raddr *SCTPAddr, mode string) (family int, ipv6only bool) {
+	switch network[len(network)-1] {
+	case '4':
+		return syscall.AF_INET, false
+	case '6':
+		return syscall.AF_INET6, true
+	}
+
+	if mode == "listen" && (laddr == nil || laddr.isWildcard()) {
+		if supportsIPv4map() || !supportsIPv4() {
+			return syscall.AF_INET6, false
+		}
+		if laddr == nil {
+			return syscall.AF_INET, false
+		}
+		return laddr.family(), false
+	}
+
+	if (laddr == nil || laddr.family() == syscall.AF_INET) &&
+		(raddr == nil || raddr.family() == syscall.AF_INET) {
+		return syscall.AF_INET, false
+	}
+	return syscall.AF_INET6, false
+}
+
+//from https://github.com/golang/go
+//Changes: it is for SCTP only
+func setDefaultSockopts(s int, family int, ipv6only bool) error {
+	if family == syscall.AF_INET6 {
+		// Allow both IP versions even if the OS default
+		// is otherwise. Note that some operating systems
+		// never admit this option.
+		syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, boolint(ipv6only))
+	}
+	// Allow broadcast.
+	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1))
+}

+ 56 - 32
vendor/github.com/ishidawataru/sctp/sctp.go

@@ -197,37 +197,58 @@ func htons(h uint16) uint16 {
 
 var ntohs = htons
 
-func setNumOstreams(fd, num int) error {
-	param := InitMsg{
-		NumOstreams: uint16(num),
-	}
-	optlen := unsafe.Sizeof(param)
-	_, _, err := setsockopt(fd, SCTP_INITMSG, uintptr(unsafe.Pointer(&param)), uintptr(optlen))
+// setInitOpts sets options for an SCTP association initialization
+// see https://tools.ietf.org/html/rfc4960#page-25
+func setInitOpts(fd int, options InitMsg) error {
+	optlen := unsafe.Sizeof(options)
+	_, _, err := setsockopt(fd, SCTP_INITMSG, uintptr(unsafe.Pointer(&options)), uintptr(optlen))
 	return err
 }
 
+func setNumOstreams(fd, num int) error {
+	return setInitOpts(fd, InitMsg{NumOstreams: uint16(num)})
+}
+
 type SCTPAddr struct {
-	IP   []net.IP
-	Port int
+	IPAddrs []net.IPAddr
+	Port    int
 }
 
 func (a *SCTPAddr) ToRawSockAddrBuf() []byte {
-	buf := []byte{}
 	p := htons(uint16(a.Port))
-	for _, ip := range a.IP {
-		if ip.To4() != nil {
+	if len(a.IPAddrs) == 0 { // if a.IPAddrs list is empty - fall back to IPv4 zero addr
+		s := syscall.RawSockaddrInet4{
+			Family: syscall.AF_INET,
+			Port:   p,
+		}
+		copy(s.Addr[:], net.IPv4zero)
+		return toBuf(s)
+	}
+	buf := []byte{}
+	for _, ip := range a.IPAddrs {
+		ipBytes := ip.IP
+		if len(ipBytes) == 0 {
+			ipBytes = net.IPv4zero
+		}
+		if ip4 := ipBytes.To4(); ip4 != nil {
 			s := syscall.RawSockaddrInet4{
 				Family: syscall.AF_INET,
 				Port:   p,
 			}
-			copy(s.Addr[:], ip.To4())
+			copy(s.Addr[:], ip4)
 			buf = append(buf, toBuf(s)...)
 		} else {
+			var scopeid uint32
+			ifi, err := net.InterfaceByName(ip.Zone)
+			if err == nil {
+				scopeid = uint32(ifi.Index)
+			}
 			s := syscall.RawSockaddrInet6{
-				Family: syscall.AF_INET6,
-				Port:   p,
+				Family:   syscall.AF_INET6,
+				Port:     p,
+				Scope_id: scopeid,
 			}
-			copy(s.Addr[:], ip)
+			copy(s.Addr[:], ipBytes)
 			buf = append(buf, toBuf(s)...)
 		}
 	}
@@ -237,15 +258,15 @@ func (a *SCTPAddr) ToRawSockAddrBuf() []byte {
 func (a *SCTPAddr) String() string {
 	var b bytes.Buffer
 
-	for n, i := range a.IP {
-		if a.IP[n].To4() != nil {
+	for n, i := range a.IPAddrs {
+		if i.IP.To4() != nil {
 			b.WriteString(i.String())
-		} else if a.IP[n].To16() != nil {
+		} else if i.IP.To16() != nil {
 			b.WriteRune('[')
 			b.WriteString(i.String())
 			b.WriteRune(']')
 		}
-		if n < len(a.IP)-1 {
+		if n < len(a.IPAddrs)-1 {
 			b.WriteRune('/')
 		}
 	}
@@ -260,6 +281,7 @@ func ResolveSCTPAddr(network, addrs string) (*SCTPAddr, error) {
 	tcpnet := ""
 	switch network {
 	case "", "sctp":
+		tcpnet = "tcp"
 	case "sctp4":
 		tcpnet = "tcp4"
 	case "sctp6":
@@ -271,26 +293,26 @@ func ResolveSCTPAddr(network, addrs string) (*SCTPAddr, error) {
 	if len(elems) == 0 {
 		return nil, fmt.Errorf("invalid input: %s", addrs)
 	}
-	ipaddrs := make([]net.IP, 0, len(elems))
+	ipaddrs := make([]net.IPAddr, 0, len(elems))
 	for _, e := range elems[:len(elems)-1] {
 		tcpa, err := net.ResolveTCPAddr(tcpnet, e+":")
 		if err != nil {
 			return nil, err
 		}
-		ipaddrs = append(ipaddrs, tcpa.IP)
+		ipaddrs = append(ipaddrs, net.IPAddr{IP: tcpa.IP, Zone: tcpa.Zone})
 	}
 	tcpa, err := net.ResolveTCPAddr(tcpnet, elems[len(elems)-1])
 	if err != nil {
 		return nil, err
 	}
 	if tcpa.IP != nil {
-		ipaddrs = append(ipaddrs, tcpa.IP)
+		ipaddrs = append(ipaddrs, net.IPAddr{IP: tcpa.IP, Zone: tcpa.Zone})
 	} else {
 		ipaddrs = nil
 	}
 	return &SCTPAddr{
-		IP:   ipaddrs,
-		Port: tcpa.Port,
+		IPAddrs: ipaddrs,
+		Port:    tcpa.Port,
 	}, nil
 }
 
@@ -357,15 +379,12 @@ func (c *SCTPConn) Read(b []byte) (int, error) {
 }
 
 func (c *SCTPConn) SetInitMsg(numOstreams, maxInstreams, maxAttempts, maxInitTimeout int) error {
-	param := InitMsg{
+	return setInitOpts(c.fd(), InitMsg{
 		NumOstreams:    uint16(numOstreams),
 		MaxInstreams:   uint16(maxInstreams),
 		MaxAttempts:    uint16(maxAttempts),
 		MaxInitTimeout: uint16(maxInitTimeout),
-	}
-	optlen := unsafe.Sizeof(param)
-	_, _, err := setsockopt(c.fd(), SCTP_INITMSG, uintptr(unsafe.Pointer(&param)), uintptr(optlen))
-	return err
+	})
 }
 
 func (c *SCTPConn) SubscribeEvents(flags int) error {
@@ -473,7 +492,7 @@ func (c *SCTPConn) GetDefaultSentParam() (*SndRcvInfo, error) {
 
 func resolveFromRawAddr(ptr unsafe.Pointer, n int) (*SCTPAddr, error) {
 	addr := &SCTPAddr{
-		IP: make([]net.IP, n),
+		IPAddrs: make([]net.IPAddr, n),
 	}
 
 	switch family := (*(*syscall.RawSockaddrAny)(ptr)).Addr.Family; family {
@@ -484,7 +503,7 @@ func resolveFromRawAddr(ptr unsafe.Pointer, n int) (*SCTPAddr, error) {
 		for i := 0; i < n; i++ {
 			a := *(*syscall.RawSockaddrInet4)(unsafe.Pointer(
 				uintptr(ptr) + size*uintptr(i)))
-			addr.IP[i] = a.Addr[:]
+			addr.IPAddrs[i] = net.IPAddr{IP: a.Addr[:]}
 		}
 	case syscall.AF_INET6:
 		addr.Port = int(ntohs(uint16((*(*syscall.RawSockaddrInet4)(ptr)).Port)))
@@ -493,7 +512,12 @@ func resolveFromRawAddr(ptr unsafe.Pointer, n int) (*SCTPAddr, error) {
 		for i := 0; i < n; i++ {
 			a := *(*syscall.RawSockaddrInet6)(unsafe.Pointer(
 				uintptr(ptr) + size*uintptr(i)))
-			addr.IP[i] = a.Addr[:]
+			var zone string
+			ifi, err := net.InterfaceByIndex(int(a.Scope_id))
+			if err == nil {
+				zone = ifi.Name
+			}
+			addr.IPAddrs[i] = net.IPAddr{IP: a.Addr[:], Zone: zone}
 		}
 	default:
 		return nil, fmt.Errorf("unknown address family: %d", family)

+ 60 - 51
vendor/github.com/ishidawataru/sctp/sctp_linux.go

@@ -3,7 +3,6 @@
 package sctp
 
 import (
-	"fmt"
 	"io"
 	"net"
 	"sync/atomic"
@@ -115,31 +114,14 @@ func (c *SCTPConn) Close() error {
 	return syscall.EBADF
 }
 
+// ListenSCTP - start listener on specified address/port
 func ListenSCTP(net string, laddr *SCTPAddr) (*SCTPListener, error) {
-	af := syscall.AF_INET
-	switch net {
-	case "sctp":
-		hasv6 := func(addr *SCTPAddr) bool {
-			if addr == nil {
-				return false
-			}
-			for _, ip := range addr.IP {
-				if ip.To4() == nil {
-					return true
-				}
-			}
-			return false
-		}
-		if hasv6(laddr) {
-			af = syscall.AF_INET6
-		}
-	case "sctp4":
-	case "sctp6":
-		af = syscall.AF_INET6
-	default:
-		return nil, fmt.Errorf("invalid net: %s", net)
-	}
+	return ListenSCTPExt(net, laddr, InitMsg{NumOstreams: SCTP_MAX_STREAM})
+}
 
+// ListenSCTPExt - start listener on specified address/port with given SCTP options
+func ListenSCTPExt(network string, laddr *SCTPAddr, options InitMsg) (*SCTPListener, error) {
+	af, ipv6only := favoriteAddrFamily(network, laddr, nil, "listen")
 	sock, err := syscall.Socket(
 		af,
 		syscall.SOCK_STREAM,
@@ -148,11 +130,30 @@ func ListenSCTP(net string, laddr *SCTPAddr) (*SCTPListener, error) {
 	if err != nil {
 		return nil, err
 	}
-	err = setNumOstreams(sock, SCTP_MAX_STREAM)
+
+	// close socket on error
+	defer func() {
+		if err != nil {
+			syscall.Close(sock)
+		}
+	}()
+	if err = setDefaultSockopts(sock, af, ipv6only); err != nil {
+		return nil, err
+	}
+	err = setInitOpts(sock, options)
 	if err != nil {
 		return nil, err
 	}
-	if laddr != nil && len(laddr.IP) != 0 {
+
+	if laddr != nil {
+		// If IP address and/or port was not provided so far, let's use the unspecified IPv4 or IPv6 address
+		if len(laddr.IPAddrs) == 0 {
+			if af == syscall.AF_INET {
+				laddr.IPAddrs = append(laddr.IPAddrs, net.IPAddr{IP: net.IPv4zero})
+			} else if af == syscall.AF_INET6 {
+				laddr.IPAddrs = append(laddr.IPAddrs, net.IPAddr{IP: net.IPv6zero})
+			}
+		}
 		err := SCTPBind(sock, laddr, SCTP_BINDX_ADD_ADDR)
 		if err != nil {
 			return nil, err
@@ -167,40 +168,30 @@ func ListenSCTP(net string, laddr *SCTPAddr) (*SCTPListener, error) {
 	}, nil
 }
 
-func (ln *SCTPListener) Accept() (net.Conn, error) {
+// AcceptSCTP waits for and returns the next SCTP connection to the listener.
+func (ln *SCTPListener) AcceptSCTP() (*SCTPConn, error) {
 	fd, _, err := syscall.Accept4(ln.fd, 0)
 	return NewSCTPConn(fd, nil), err
 }
 
+// Accept waits for and returns the next connection connection to the listener.
+func (ln *SCTPListener) Accept() (net.Conn, error) {
+	return ln.AcceptSCTP()
+}
+
 func (ln *SCTPListener) Close() error {
 	syscall.Shutdown(ln.fd, syscall.SHUT_RDWR)
 	return syscall.Close(ln.fd)
 }
 
+// DialSCTP - bind socket to laddr (if given) and connect to raddr
 func DialSCTP(net string, laddr, raddr *SCTPAddr) (*SCTPConn, error) {
-	af := syscall.AF_INET
-	switch net {
-	case "sctp":
-		hasv6 := func(addr *SCTPAddr) bool {
-			if addr == nil {
-				return false
-			}
-			for _, ip := range addr.IP {
-				if ip.To4() == nil {
-					return true
-				}
-			}
-			return false
-		}
-		if hasv6(laddr) || hasv6(raddr) {
-			af = syscall.AF_INET6
-		}
-	case "sctp4":
-	case "sctp6":
-		af = syscall.AF_INET6
-	default:
-		return nil, fmt.Errorf("invalid net: %s", net)
-	}
+	return DialSCTPExt(net, laddr, raddr, InitMsg{NumOstreams: SCTP_MAX_STREAM})
+}
+
+// DialSCTPExt - same as DialSCTP but with given SCTP options
+func DialSCTPExt(network string, laddr, raddr *SCTPAddr, options InitMsg) (*SCTPConn, error) {
+	af, ipv6only := favoriteAddrFamily(network, laddr, raddr, "dial")
 	sock, err := syscall.Socket(
 		af,
 		syscall.SOCK_STREAM,
@@ -209,11 +200,29 @@ func DialSCTP(net string, laddr, raddr *SCTPAddr) (*SCTPConn, error) {
 	if err != nil {
 		return nil, err
 	}
-	err = setNumOstreams(sock, SCTP_MAX_STREAM)
+
+	// close socket on error
+	defer func() {
+		if err != nil {
+			syscall.Close(sock)
+		}
+	}()
+	if err = setDefaultSockopts(sock, af, ipv6only); err != nil {
+		return nil, err
+	}
+	err = setInitOpts(sock, options)
 	if err != nil {
 		return nil, err
 	}
 	if laddr != nil {
+		// If IP address and/or port was not provided so far, let's use the unspecified IPv4 or IPv6 address
+		if len(laddr.IPAddrs) == 0 {
+			if af == syscall.AF_INET {
+				laddr.IPAddrs = append(laddr.IPAddrs, net.IPAddr{IP: net.IPv4zero})
+			} else if af == syscall.AF_INET6 {
+				laddr.IPAddrs = append(laddr.IPAddrs, net.IPAddr{IP: net.IPv6zero})
+			}
+		}
 		err := SCTPBind(sock, laddr, SCTP_BINDX_ADD_ADDR)
 		if err != nil {
 			return nil, err

+ 12 - 0
vendor/github.com/ishidawataru/sctp/sctp_unsupported.go

@@ -34,10 +34,18 @@ func ListenSCTP(net string, laddr *SCTPAddr) (*SCTPListener, error) {
 	return nil, ErrUnsupported
 }
 
+func ListenSCTPExt(net string, laddr *SCTPAddr, options InitMsg) (*SCTPListener, error) {
+	return nil, ErrUnsupported
+}
+
 func (ln *SCTPListener) Accept() (net.Conn, error) {
 	return nil, ErrUnsupported
 }
 
+func (ln *SCTPListener) AcceptSCTP() (*SCTPConn, error) {
+	return nil, ErrUnsupported
+}
+
 func (ln *SCTPListener) Close() error {
 	return ErrUnsupported
 }
@@ -45,3 +53,7 @@ func (ln *SCTPListener) Close() error {
 func DialSCTP(net string, laddr, raddr *SCTPAddr) (*SCTPConn, error) {
 	return nil, ErrUnsupported
 }
+
+func DialSCTPExt(network string, laddr, raddr *SCTPAddr, options InitMsg) (*SCTPConn, error) {
+	return nil, ErrUnsupported
+}

+ 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))

+ 3 - 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() {
@@ -38,7 +39,7 @@ func main() {
     newns, _ := netns.New()
     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)
 }

+ 33 - 5
vendor/github.com/vishvananda/netns/netns_linux.go

@@ -7,14 +7,29 @@ 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,
+	"mips64le":  4344,
+	"ppc64":   350,
+	"ppc64le": 350,
+	"riscv64": 268,
+	"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 */
@@ -39,7 +54,8 @@ func Set(ns NsHandle) (err error) {
 	return Setns(ns, CLONE_NEWNET)
 }
 
-// New creates a new network namespace and returns a handle to it.
+// New creates a new network namespace, sets it as current and returns
+// a handle to it.
 func New() (ns NsHandle, err error) {
 	if err := syscall.Unshare(CLONE_NEWNET); err != nil {
 		return -1, err
@@ -125,7 +141,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 +185,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
 }

+ 1 - 0
vendor/go.etcd.io/bbolt/README.md

@@ -929,6 +929,7 @@ Below is a list of public, open source projects that use Bolt:
 * [ipxed](https://github.com/kelseyhightower/ipxed) - Web interface and api for ipxed.
 * [Ironsmith](https://github.com/timshannon/ironsmith) - A simple, script-driven continuous integration (build - > test -> release) tool, with no external dependencies
 * [Kala](https://github.com/ajvb/kala) - Kala is a modern job scheduler optimized to run on a single node. It is persistent, JSON over HTTP API, ISO 8601 duration notation, and dependent jobs.
+* [Key Value Access Langusge (KVAL)](https://github.com/kval-access-language) - A proposed grammar for key-value datastores offering a bbolt binding.
 * [LedisDB](https://github.com/siddontang/ledisdb) - A high performance NoSQL, using Bolt as optional storage.
 * [lru](https://github.com/crowdriff/lru) - Easy to use Bolt-backed Least-Recently-Used (LRU) read-through cache with chainable remote stores.
 * [mbuckets](https://github.com/abhigupta912/mbuckets) - A Bolt wrapper that allows easy operations on multi level (nested) buckets.

+ 12 - 0
vendor/go.etcd.io/bbolt/bolt_riscv64.go

@@ -0,0 +1,12 @@
+// +build riscv64
+
+package bbolt
+
+// maxMapSize represents the largest mmap size supported by Bolt.
+const maxMapSize = 0xFFFFFFFFFFFF // 256TB
+
+// maxAllocSize is the size used when creating array pointers.
+const maxAllocSize = 0x7FFFFFFF
+
+// Are unaligned load/stores broken on this arch?
+var brokenUnaligned = true

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