full diffs:
- https://github.com/docker/libnetwork/compare/fc5a7d91d54cc98f64fc28f9e288b46a0bee756c...62a13ae87c6058bdc000fcccbf7e0f9f7525e2a9
- https://github.com/vishvananda/netlink/compare/b2de5d10e38ecce8607e6b438b6d174f389a004e...v1.0.0
- https://github.com/vishvananda/netns/compare/604eaf189ee867d8c147fafc28def2394e878d25...13995c7128ccc8e51e9a6bd2b551020a27180abd
notable changes in libnetwork:
- docker/libnetwork#2366 Bump vishvananda/netlink to 1.0.0
- docker/libnetwork#2339 controller: Check if IPTables is enabled for arrangeUserFilterRule
- addresses docker/libnetwork#2158 dockerd when run with --iptables=false modifies iptables by adding DOCKER-USER
- addresses moby/moby#35777 With iptables=false dockerd still creates DOCKER-USER chain and rules
- addresses docker/for-linux#136 dockerd --iptables=false adds DOCKER-USER chain and modify FORWARD chain anyway
- docker/libnetwork#2394 Make DNS records and queries case-insensitive
- addresses moby/moby#28689 Embedded DNS is case-sensitive
- addresses moby/moby#21169 hostnames with new networking are case-sensitive
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 344b093258fcb2195fa393081e5224a6c766c798)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
| ... | ... |
@@ -3,7 +3,7 @@ |
| 3 | 3 |
# LIBNETWORK_COMMIT is used to build the docker-userland-proxy binary. When |
| 4 | 4 |
# updating the binary version, consider updating github.com/docker/libnetwork |
| 5 | 5 |
# in vendor.conf accordingly |
| 6 |
-LIBNETWORK_COMMIT=fc5a7d91d54cc98f64fc28f9e288b46a0bee756c |
|
| 6 |
+LIBNETWORK_COMMIT=62a13ae87c6058bdc000fcccbf7e0f9f7525e2a9 |
|
| 7 | 7 |
|
| 8 | 8 |
install_proxy() {
|
| 9 | 9 |
case "$1" in |
| ... | ... |
@@ -39,7 +39,7 @@ github.com/gofrs/flock 7f43ea2e6a643ad441fc12d0ecc0 |
| 39 | 39 |
# libnetwork |
| 40 | 40 |
|
| 41 | 41 |
# When updating, also update LIBNETWORK_COMMIT in hack/dockerfile/install/proxy.installer accordingly |
| 42 |
-github.com/docker/libnetwork fc5a7d91d54cc98f64fc28f9e288b46a0bee756c |
|
| 42 |
+github.com/docker/libnetwork 62a13ae87c6058bdc000fcccbf7e0f9f7525e2a9 |
|
| 43 | 43 |
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9 |
| 44 | 44 |
github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80 |
| 45 | 45 |
github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec |
| ... | ... |
@@ -50,8 +50,8 @@ github.com/hashicorp/go-sockaddr 6d291a969b86c4b633730bfc6b8b |
| 50 | 50 |
github.com/hashicorp/go-multierror fcdddc395df1ddf4247c69bd436e84cfa0733f7e |
| 51 | 51 |
github.com/hashicorp/serf 598c54895cc5a7b1a24a398d635e8c0ea0959870 |
| 52 | 52 |
github.com/docker/libkv 458977154600b9f23984d9f4b82e79570b5ae12b |
| 53 |
-github.com/vishvananda/netns 604eaf189ee867d8c147fafc28def2394e878d25 |
|
| 54 |
-github.com/vishvananda/netlink b2de5d10e38ecce8607e6b438b6d174f389a004e |
|
| 53 |
+github.com/vishvananda/netns 13995c7128ccc8e51e9a6bd2b551020a27180abd |
|
| 54 |
+github.com/vishvananda/netlink a2ad57a690f3caf3015351d2d6e1c0b95c349752 # v1.0.0 |
|
| 55 | 55 |
|
| 56 | 56 |
# When updating, consider updating TOMLV_COMMIT in hack/dockerfile/install/tomlv.installer accordingly |
| 57 | 57 |
github.com/BurntSushi/toml 3012a1dbe2e4bd1391d42b32f0577cb7bbc7f005 # v0.3.1 |
| ... | ... |
@@ -12,7 +12,6 @@ import ( |
| 12 | 12 |
"strconv" |
| 13 | 13 |
"strings" |
| 14 | 14 |
"sync" |
| 15 |
- "syscall" |
|
| 16 | 15 |
|
| 17 | 16 |
"github.com/docker/docker/pkg/reexec" |
| 18 | 17 |
"github.com/docker/libnetwork/datastore" |
| ... | ... |
@@ -27,6 +26,7 @@ import ( |
| 27 | 27 |
"github.com/vishvananda/netlink" |
| 28 | 28 |
"github.com/vishvananda/netlink/nl" |
| 29 | 29 |
"github.com/vishvananda/netns" |
| 30 |
+ "golang.org/x/sys/unix" |
|
| 30 | 31 |
) |
| 31 | 32 |
|
| 32 | 33 |
var ( |
| ... | ... |
@@ -97,18 +97,18 @@ func setDefaultVlan() {
|
| 97 | 97 |
} |
| 98 | 98 |
|
| 99 | 99 |
// make sure the sysfs mount doesn't propagate back |
| 100 |
- if err = syscall.Unshare(syscall.CLONE_NEWNS); err != nil {
|
|
| 100 |
+ if err = unix.Unshare(unix.CLONE_NEWNS); err != nil {
|
|
| 101 | 101 |
logrus.Errorf("unshare failed, %v", err)
|
| 102 | 102 |
os.Exit(1) |
| 103 | 103 |
} |
| 104 | 104 |
|
| 105 |
- flag := syscall.MS_PRIVATE | syscall.MS_REC |
|
| 106 |
- if err = syscall.Mount("", "/", "", uintptr(flag), ""); err != nil {
|
|
| 105 |
+ flag := unix.MS_PRIVATE | unix.MS_REC |
|
| 106 |
+ if err = unix.Mount("", "/", "", uintptr(flag), ""); err != nil {
|
|
| 107 | 107 |
logrus.Errorf("root mount failed, %v", err)
|
| 108 | 108 |
os.Exit(1) |
| 109 | 109 |
} |
| 110 | 110 |
|
| 111 |
- if err = syscall.Mount("sysfs", "/sys", "sysfs", 0, ""); err != nil {
|
|
| 111 |
+ if err = unix.Mount("sysfs", "/sys", "sysfs", 0, ""); err != nil {
|
|
| 112 | 112 |
logrus.Errorf("mounting sysfs failed, %v", err)
|
| 113 | 113 |
os.Exit(1) |
| 114 | 114 |
} |
| ... | ... |
@@ -427,7 +427,7 @@ func populateVNITbl() {
|
| 427 | 427 |
} |
| 428 | 428 |
defer ns.Close() |
| 429 | 429 |
|
| 430 |
- nlh, err := netlink.NewHandleAt(ns, syscall.NETLINK_ROUTE) |
|
| 430 |
+ nlh, err := netlink.NewHandleAt(ns, unix.NETLINK_ROUTE) |
|
| 431 | 431 |
if err != nil {
|
| 432 | 432 |
logrus.Errorf("Could not open netlink handle during vni population for ns %s: %v", path, err)
|
| 433 | 433 |
return nil |
| ... | ... |
@@ -583,7 +583,7 @@ func (n *network) setupSubnetSandbox(s *subnet, brName, vxlanName string) error |
| 583 | 583 |
|
| 584 | 584 |
if ok {
|
| 585 | 585 |
deleteVxlanByVNI(path, s.vni) |
| 586 |
- if err := syscall.Unmount(path, syscall.MNT_FORCE); err != nil {
|
|
| 586 |
+ if err := unix.Unmount(path, unix.MNT_FORCE); err != nil {
|
|
| 587 | 587 |
logrus.Errorf("unmount of %s failed: %v", path, err)
|
| 588 | 588 |
} |
| 589 | 589 |
os.Remove(path) |
| ... | ... |
@@ -693,7 +693,7 @@ func (n *network) cleanupStaleSandboxes() {
|
| 693 | 693 |
if strings.Contains(n.id, pattern) {
|
| 694 | 694 |
// Delete all vnis |
| 695 | 695 |
deleteVxlanByVNI(path, 0) |
| 696 |
- syscall.Unmount(path, syscall.MNT_DETACH) |
|
| 696 |
+ unix.Unmount(path, unix.MNT_DETACH) |
|
| 697 | 697 |
os.Remove(path) |
| 698 | 698 |
|
| 699 | 699 |
// Now that we have destroyed this |
| ... | ... |
@@ -755,12 +755,12 @@ func (n *network) initSandbox(restore bool) error {
|
| 755 | 755 |
|
| 756 | 756 |
var nlSock *nl.NetlinkSocket |
| 757 | 757 |
sbox.InvokeFunc(func() {
|
| 758 |
- nlSock, err = nl.Subscribe(syscall.NETLINK_ROUTE, syscall.RTNLGRP_NEIGH) |
|
| 758 |
+ nlSock, err = nl.Subscribe(unix.NETLINK_ROUTE, unix.RTNLGRP_NEIGH) |
|
| 759 | 759 |
if err != nil {
|
| 760 | 760 |
return |
| 761 | 761 |
} |
| 762 | 762 |
// set the receive timeout to not remain stuck on the RecvFrom if the fd gets closed |
| 763 |
- tv := syscall.NsecToTimeval(soTimeout.Nanoseconds()) |
|
| 763 |
+ tv := unix.NsecToTimeval(soTimeout.Nanoseconds()) |
|
| 764 | 764 |
err = nlSock.SetReceiveTimeout(&tv) |
| 765 | 765 |
}) |
| 766 | 766 |
n.nlSocket = nlSock |
| ... | ... |
@@ -803,7 +803,7 @@ func (n *network) watchMiss(nlSock *nl.NetlinkSocket, nsPath string) {
|
| 803 | 803 |
return |
| 804 | 804 |
} |
| 805 | 805 |
// When the receive timeout expires the receive will return EAGAIN |
| 806 |
- if err == syscall.EAGAIN {
|
|
| 806 |
+ if err == unix.EAGAIN {
|
|
| 807 | 807 |
// we continue here to avoid spam for timeouts |
| 808 | 808 |
continue |
| 809 | 809 |
} |
| ... | ... |
@@ -812,7 +812,7 @@ func (n *network) watchMiss(nlSock *nl.NetlinkSocket, nsPath string) {
|
| 812 | 812 |
} |
| 813 | 813 |
|
| 814 | 814 |
for _, msg := range msgs {
|
| 815 |
- if msg.Header.Type != syscall.RTM_GETNEIGH && msg.Header.Type != syscall.RTM_NEWNEIGH {
|
|
| 815 |
+ if msg.Header.Type != unix.RTM_GETNEIGH && msg.Header.Type != unix.RTM_NEWNEIGH {
|
|
| 816 | 816 |
continue |
| 817 | 817 |
} |
| 818 | 818 |
|
| ... | ... |
@@ -2,6 +2,7 @@ package libnetwork |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"github.com/docker/libnetwork/iptables" |
| 5 |
+ "github.com/docker/libnetwork/netlabel" |
|
| 5 | 6 |
"github.com/sirupsen/logrus" |
| 6 | 7 |
) |
| 7 | 8 |
|
| ... | ... |
@@ -9,15 +10,44 @@ const userChain = "DOCKER-USER" |
| 9 | 9 |
|
| 10 | 10 |
func (c *controller) arrangeUserFilterRule() {
|
| 11 | 11 |
c.Lock() |
| 12 |
- arrangeUserFilterRule() |
|
| 12 |
+ |
|
| 13 |
+ if c.hasIPTablesEnabled() {
|
|
| 14 |
+ arrangeUserFilterRule() |
|
| 15 |
+ } |
|
| 16 |
+ |
|
| 13 | 17 |
c.Unlock() |
| 18 |
+ |
|
| 14 | 19 |
iptables.OnReloaded(func() {
|
| 15 | 20 |
c.Lock() |
| 16 |
- arrangeUserFilterRule() |
|
| 21 |
+ |
|
| 22 |
+ if c.hasIPTablesEnabled() {
|
|
| 23 |
+ arrangeUserFilterRule() |
|
| 24 |
+ } |
|
| 25 |
+ |
|
| 17 | 26 |
c.Unlock() |
| 18 | 27 |
}) |
| 19 | 28 |
} |
| 20 | 29 |
|
| 30 |
+func (c *controller) hasIPTablesEnabled() bool {
|
|
| 31 |
+ // Locking c should be handled in the calling method. |
|
| 32 |
+ if c.cfg == nil || c.cfg.Daemon.DriverCfg[netlabel.GenericData] == nil {
|
|
| 33 |
+ return false |
|
| 34 |
+ } |
|
| 35 |
+ |
|
| 36 |
+ genericData, ok := c.cfg.Daemon.DriverCfg[netlabel.GenericData] |
|
| 37 |
+ if !ok {
|
|
| 38 |
+ return false |
|
| 39 |
+ } |
|
| 40 |
+ |
|
| 41 |
+ optMap := genericData.(map[string]interface{})
|
|
| 42 |
+ enabled, ok := optMap["EnableIPTables"].(bool) |
|
| 43 |
+ if !ok {
|
|
| 44 |
+ return false |
|
| 45 |
+ } |
|
| 46 |
+ |
|
| 47 |
+ return enabled |
|
| 48 |
+} |
|
| 49 |
+ |
|
| 21 | 50 |
// This chain allow users to configure firewall policies in a way that persists |
| 22 | 51 |
// docker operations/restarts. Docker will not delete or modify any pre-existing |
| 23 | 52 |
// rules from the DOCKER-USER filter chain. |
| ... | ... |
@@ -3,14 +3,13 @@ |
| 3 | 3 |
package ipvs |
| 4 | 4 |
|
| 5 | 5 |
import ( |
| 6 |
+ "fmt" |
|
| 6 | 7 |
"net" |
| 7 |
- "syscall" |
|
| 8 | 8 |
"time" |
| 9 | 9 |
|
| 10 |
- "fmt" |
|
| 11 |
- |
|
| 12 | 10 |
"github.com/vishvananda/netlink/nl" |
| 13 | 11 |
"github.com/vishvananda/netns" |
| 12 |
+ "golang.org/x/sys/unix" |
|
| 14 | 13 |
) |
| 15 | 14 |
|
| 16 | 15 |
const ( |
| ... | ... |
@@ -98,16 +97,16 @@ func New(path string) (*Handle, error) {
|
| 98 | 98 |
} |
| 99 | 99 |
defer n.Close() |
| 100 | 100 |
|
| 101 |
- sock, err := nl.GetNetlinkSocketAt(n, netns.None(), syscall.NETLINK_GENERIC) |
|
| 101 |
+ sock, err := nl.GetNetlinkSocketAt(n, netns.None(), unix.NETLINK_GENERIC) |
|
| 102 | 102 |
if err != nil {
|
| 103 | 103 |
return nil, err |
| 104 | 104 |
} |
| 105 | 105 |
// Add operation timeout to avoid deadlocks |
| 106 |
- tv := syscall.NsecToTimeval(netlinkSendSocketTimeout.Nanoseconds()) |
|
| 106 |
+ tv := unix.NsecToTimeval(netlinkSendSocketTimeout.Nanoseconds()) |
|
| 107 | 107 |
if err := sock.SetSendTimeout(&tv); err != nil {
|
| 108 | 108 |
return nil, err |
| 109 | 109 |
} |
| 110 |
- tv = syscall.NsecToTimeval(netlinkRecvSocketsTimeout.Nanoseconds()) |
|
| 110 |
+ tv = unix.NsecToTimeval(netlinkRecvSocketsTimeout.Nanoseconds()) |
|
| 111 | 111 |
if err := sock.SetReceiveTimeout(&tv); err != nil {
|
| 112 | 112 |
return nil, err |
| 113 | 113 |
} |
| ... | ... |
@@ -1381,14 +1381,18 @@ func delIPToName(ipMap setmatrix.SetMatrix, name, serviceID string, ip net.IP) {
|
| 1381 | 1381 |
} |
| 1382 | 1382 |
|
| 1383 | 1383 |
func addNameToIP(svcMap setmatrix.SetMatrix, name, serviceID string, epIP net.IP) {
|
| 1384 |
- svcMap.Insert(name, svcMapEntry{
|
|
| 1384 |
+ // Since DNS name resolution is case-insensitive, Use the lower-case form |
|
| 1385 |
+ // of the name as the key into svcMap |
|
| 1386 |
+ lowerCaseName := strings.ToLower(name) |
|
| 1387 |
+ svcMap.Insert(lowerCaseName, svcMapEntry{
|
|
| 1385 | 1388 |
ip: epIP.String(), |
| 1386 | 1389 |
serviceID: serviceID, |
| 1387 | 1390 |
}) |
| 1388 | 1391 |
} |
| 1389 | 1392 |
|
| 1390 | 1393 |
func delNameToIP(svcMap setmatrix.SetMatrix, name, serviceID string, epIP net.IP) {
|
| 1391 |
- svcMap.Remove(name, svcMapEntry{
|
|
| 1394 |
+ lowerCaseName := strings.ToLower(name) |
|
| 1395 |
+ svcMap.Remove(lowerCaseName, svcMapEntry{
|
|
| 1392 | 1396 |
ip: epIP.String(), |
| 1393 | 1397 |
serviceID: serviceID, |
| 1394 | 1398 |
}) |
| ... | ... |
@@ -1956,6 +1960,7 @@ func (n *network) ResolveName(req string, ipType int) ([]net.IP, bool) {
|
| 1956 | 1956 |
} |
| 1957 | 1957 |
|
| 1958 | 1958 |
req = strings.TrimSuffix(req, ".") |
| 1959 |
+ req = strings.ToLower(req) |
|
| 1959 | 1960 |
ipSet, ok := sr.svcMap.Get(req) |
| 1960 | 1961 |
|
| 1961 | 1962 |
if ipType == types.IPv6 {
|
| ... | ... |
@@ -366,8 +366,8 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
|
| 366 | 366 |
if query == nil || len(query.Question) == 0 {
|
| 367 | 367 |
return |
| 368 | 368 |
} |
| 369 |
- name := query.Question[0].Name |
|
| 370 | 369 |
|
| 370 |
+ name := query.Question[0].Name |
|
| 371 | 371 |
switch query.Question[0].Qtype {
|
| 372 | 372 |
case dns.TypeA: |
| 373 | 373 |
resp, err = r.handleIPQuery(name, query, types.IPv4) |
| ... | ... |
@@ -1,50 +1,54 @@ |
| 1 |
-github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109 |
|
| 2 |
-github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895 |
|
| 3 |
-github.com/Microsoft/go-winio v0.4.11 |
|
| 4 |
-github.com/Microsoft/hcsshim v0.7.3 |
|
| 5 |
-github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec |
|
| 6 |
-github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80 |
|
| 7 |
-github.com/codegangsta/cli a65b733b303f0055f8d324d805f393cd3e7a7904 |
|
| 8 |
-github.com/containerd/continuity d3c23511c1bf5851696cba83143d9cbcd666869b |
|
| 9 |
-github.com/coreos/etcd v3.2.1 |
|
| 10 |
-github.com/coreos/go-semver v0.2.0 |
|
| 11 |
-github.com/deckarep/golang-set ef32fa3046d9f249d399f98ebaf9be944430fd1d |
|
| 12 |
-go.etcd.io/bbolt v1.3.1-etcd.8 |
|
| 1 |
+github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109 |
|
| 2 |
+github.com/BurntSushi/toml 3012a1dbe2e4bd1391d42b32f0577cb7bbc7f005 # v0.3.1 |
|
| 3 |
+github.com/Microsoft/go-winio c599b533b43b1363d7d7c6cfda5ede70ed73ff13 |
|
| 4 |
+github.com/Microsoft/hcsshim ba3d6667710fa905116f39a19d059c4c1016be7c |
|
| 5 |
+github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec |
|
| 6 |
+github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80 |
|
| 7 |
+github.com/codegangsta/cli a65b733b303f0055f8d324d805f393cd3e7a7904 |
|
| 8 |
+github.com/containerd/continuity 004b46473808b3e7a4a3049c20e4376c91eb966d |
|
| 9 |
+github.com/coreos/etcd fca8add78a9d926166eb739b8e4a124434025ba3 # v3.3.9 |
|
| 10 |
+github.com/coreos/go-semver 8ab6407b697782a06568d4b7f1db25550ec2e4c6 # v0.2.0 |
|
| 11 |
+github.com/deckarep/golang-set ef32fa3046d9f249d399f98ebaf9be944430fd1d |
|
| 12 |
+go.etcd.io/bbolt 7ee3ded59d4835e10f3e7d0f7603c42aa5e83820 # v1.3.1-etcd.8 |
|
| 13 | 13 |
|
| 14 |
-github.com/docker/docker 162ba6016def672690ee4a1f3978368853a1e149 |
|
| 15 |
-github.com/docker/go-connections 7beb39f0b969b075d1325fecb092faf27fd357b6 |
|
| 16 |
-github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9 |
|
| 17 |
-github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1 |
|
| 18 |
-github.com/docker/libkv 458977154600b9f23984d9f4b82e79570b5ae12b |
|
| 14 |
+github.com/docker/docker dbe4a30928d418e0570891a09703bcbc0e4997a1 |
|
| 15 |
+github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580 |
|
| 16 |
+github.com/docker/go-connections 7395e3f8aa162843a74ed6d48e79627d9792ac55 # v0.4.0 |
|
| 17 |
+github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9 |
|
| 18 |
+github.com/docker/go-units 47565b4f722fb6ceae66b95f853feed578a4a51c # v0.3.3 |
|
| 19 |
+github.com/docker/libkv 458977154600b9f23984d9f4b82e79570b5ae12b |
|
| 19 | 20 |
|
| 20 |
-github.com/godbus/dbus v4.0.0 |
|
| 21 |
-github.com/gogo/protobuf v1.0.0 |
|
| 22 |
-github.com/gorilla/context v1.1 |
|
| 23 |
-github.com/gorilla/mux v1.1 |
|
| 24 |
-github.com/hashicorp/consul v0.5.2 |
|
| 25 |
-github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b |
|
| 26 |
-github.com/hashicorp/go-multierror fcdddc395df1ddf4247c69bd436e84cfa0733f7e |
|
| 27 |
-github.com/hashicorp/memberlist 3d8438da9589e7b608a83ffac1ef8211486bcb7c |
|
| 28 |
-github.com/sean-/seed e2103e2c35297fb7e17febb81e49b312087a2372 |
|
| 29 |
-github.com/hashicorp/go-sockaddr 6d291a969b86c4b633730bfc6b8b9d64c3aafed9 |
|
| 30 |
-github.com/hashicorp/serf 598c54895cc5a7b1a24a398d635e8c0ea0959870 |
|
| 31 |
-github.com/mattn/go-shellwords v1.0.3 |
|
| 32 |
-github.com/miekg/dns v1.0.7 |
|
| 33 |
-github.com/opencontainers/go-digest v1.0.0-rc1 |
|
| 34 |
-github.com/opencontainers/image-spec v1.0.1 |
|
| 35 |
-github.com/opencontainers/runc 96ec2177ae841256168fcf76954f7177af9446eb |
|
| 36 |
-github.com/opencontainers/runtime-spec v1.0.1 |
|
| 37 |
-github.com/samuel/go-zookeeper d0e0d8e11f318e000a8cc434616d69e329edc374 |
|
| 38 |
-github.com/sirupsen/logrus v1.0.3 |
|
| 39 |
-github.com/ugorji/go f1f1a805ed361a0e078bb537e4ea78cd37dcf065 |
|
| 40 |
-github.com/vishvananda/netlink b2de5d10e38ecce8607e6b438b6d174f389a004e |
|
| 41 |
-github.com/vishvananda/netns 604eaf189ee867d8c147fafc28def2394e878d25 |
|
| 42 |
-golang.org/x/crypto 1a580b3eff7814fc9b40602fd35256c63b50f491 |
|
| 43 |
-golang.org/x/net 0ed95abb35c445290478a5348a7b38bb154135fd |
|
| 44 |
-golang.org/x/sys 37707fdb30a5b38865cfb95e5aab41707daec7fd |
|
| 45 |
-golang.org/x/sync fd80eb99c8f653c847d294a001bdf2a3a6f768f5 |
|
| 46 |
-github.com/pkg/errors 839d9e913e063e28dfd0e6c7b7512793e0a48be9 |
|
| 47 |
-github.com/ishidawataru/sctp 07191f837fedd2f13d1ec7b5f885f0f3ec54b1cb |
|
| 21 |
+github.com/gogo/protobuf ba06b47c162d49f2af050fb4c75bcbc86a159d5c # v1.2.1 |
|
| 22 |
+github.com/golang/protobuf aa810b61a9c79d51363740d207bb46cf8e620ed5 # v1.2.0 |
|
| 23 |
+google.golang.org/grpc 7a6a684ca69eb4cae85ad0a484f2e531598c047b # v1.12.2 |
|
| 24 |
+google.golang.org/genproto 694d95ba50e67b2e363f3483057db5d4910c18f9 |
|
| 48 | 25 |
|
| 49 |
-gotest.tools v2.1.0 |
|
| 50 |
-github.com/google/go-cmp v0.2.0 |
|
| 26 |
+github.com/godbus/dbus 5f6efc7ef2759c81b7ba876593971bfce311eab3 # v4.0.0 |
|
| 27 |
+github.com/gorilla/mux c5c6c98bc25355028a63748a498942a6398ccd22 # v1.7.1 |
|
| 28 |
+github.com/hashicorp/consul 9a9cc9341bb487651a0399e3fc5e1e8a42e62dd9 # v0.5.2 |
|
| 29 |
+github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b |
|
| 30 |
+github.com/hashicorp/go-multierror fcdddc395df1ddf4247c69bd436e84cfa0733f7e |
|
| 31 |
+github.com/hashicorp/memberlist 3d8438da9589e7b608a83ffac1ef8211486bcb7c |
|
| 32 |
+github.com/sean-/seed e2103e2c35297fb7e17febb81e49b312087a2372 |
|
| 33 |
+github.com/hashicorp/go-sockaddr 6d291a969b86c4b633730bfc6b8b9d64c3aafed9 |
|
| 34 |
+github.com/hashicorp/serf 598c54895cc5a7b1a24a398d635e8c0ea0959870 |
|
| 35 |
+github.com/mattn/go-shellwords 02e3cf038dcea8290e44424da473dd12be796a8a # v1.0.3 |
|
| 36 |
+github.com/miekg/dns e57bf427e68187a27e22adceac868350d7a7079b # v1.0.7 |
|
| 37 |
+github.com/opencontainers/go-digest 279bed98673dd5bef374d3b6e4b09e2af76183bf # v1.0.0-rc1 |
|
| 38 |
+github.com/opencontainers/image-spec d60099175f88c47cd379c4738d158884749ed235 # v1.0.1 |
|
| 39 |
+github.com/opencontainers/runc 2b18fe1d885ee5083ef9f0838fee39b62d653e30 |
|
| 40 |
+github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db |
|
| 41 |
+github.com/samuel/go-zookeeper d0e0d8e11f318e000a8cc434616d69e329edc374 |
|
| 42 |
+github.com/sirupsen/logrus f006c2ac4710855cf0f916dd6b77acf6b048dc6e # v1.0.3 |
|
| 43 |
+github.com/ugorji/go b4c50a2b199d93b13dc15e78929cfb23bfdf21ab # v1.1.1 |
|
| 44 |
+github.com/vishvananda/netlink a2ad57a690f3caf3015351d2d6e1c0b95c349752 # v1.0.0 |
|
| 45 |
+github.com/vishvananda/netns 13995c7128ccc8e51e9a6bd2b551020a27180abd |
|
| 46 |
+golang.org/x/crypto b7391e95e576cacdcdd422573063bc057239113d |
|
| 47 |
+golang.org/x/net a680a1efc54dd51c040b3b5ce4939ea3cf2ea0d1 |
|
| 48 |
+golang.org/x/sys d455e41777fca6e8a5a79e34a14b8368bc11d9ba |
|
| 49 |
+golang.org/x/sync 1d60e4601c6fd243af51cc01ddf169918a5407ca |
|
| 50 |
+github.com/pkg/errors ba968bfe8b2f7e042a574c888954fccecfa385b4 # v0.8.1 |
|
| 51 |
+github.com/ishidawataru/sctp 07191f837fedd2f13d1ec7b5f885f0f3ec54b1cb |
|
| 52 |
+ |
|
| 53 |
+gotest.tools b6e20af1ed078cd01a6413b734051a292450b4cb # v2.1.0 |
|
| 54 |
+github.com/google/go-cmp 3af367b6b30c263d47e8895973edcca9a49cf029 # v0.2.0 |
| ... | ... |
@@ -89,3 +89,4 @@ There are also a few pieces of low level netlink functionality that still |
| 89 | 89 |
need to be implemented. Routing rules are not in place and some of the |
| 90 | 90 |
more advanced link types. Hopefully there is decent structure and testing |
| 91 | 91 |
in place to make these fairly straightforward to add. |
| 92 |
+ |
| ... | ... |
@@ -8,6 +8,7 @@ import ( |
| 8 | 8 |
|
| 9 | 9 |
"github.com/vishvananda/netlink/nl" |
| 10 | 10 |
"github.com/vishvananda/netns" |
| 11 |
+ "golang.org/x/sys/unix" |
|
| 11 | 12 |
) |
| 12 | 13 |
|
| 13 | 14 |
// IFA_FLAGS is a u32 attribute. |
| ... | ... |
@@ -22,7 +23,7 @@ func AddrAdd(link Link, addr *Addr) error {
|
| 22 | 22 |
// AddrAdd will add an IP address to a link device. |
| 23 | 23 |
// Equivalent to: `ip addr add $addr dev $link` |
| 24 | 24 |
func (h *Handle) AddrAdd(link Link, addr *Addr) error {
|
| 25 |
- req := h.newNetlinkRequest(syscall.RTM_NEWADDR, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) |
|
| 25 |
+ req := h.newNetlinkRequest(unix.RTM_NEWADDR, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK) |
|
| 26 | 26 |
return h.addrHandle(link, addr, req) |
| 27 | 27 |
} |
| 28 | 28 |
|
| ... | ... |
@@ -35,7 +36,7 @@ func AddrReplace(link Link, addr *Addr) error {
|
| 35 | 35 |
// AddrReplace will replace (or, if not present, add) an IP address on a link device. |
| 36 | 36 |
// Equivalent to: `ip addr replace $addr dev $link` |
| 37 | 37 |
func (h *Handle) AddrReplace(link Link, addr *Addr) error {
|
| 38 |
- req := h.newNetlinkRequest(syscall.RTM_NEWADDR, syscall.NLM_F_CREATE|syscall.NLM_F_REPLACE|syscall.NLM_F_ACK) |
|
| 38 |
+ req := h.newNetlinkRequest(unix.RTM_NEWADDR, unix.NLM_F_CREATE|unix.NLM_F_REPLACE|unix.NLM_F_ACK) |
|
| 39 | 39 |
return h.addrHandle(link, addr, req) |
| 40 | 40 |
} |
| 41 | 41 |
|
| ... | ... |
@@ -48,7 +49,7 @@ func AddrDel(link Link, addr *Addr) error {
|
| 48 | 48 |
// AddrDel will delete an IP address from a link device. |
| 49 | 49 |
// Equivalent to: `ip addr del $addr dev $link` |
| 50 | 50 |
func (h *Handle) AddrDel(link Link, addr *Addr) error {
|
| 51 |
- req := h.newNetlinkRequest(syscall.RTM_DELADDR, syscall.NLM_F_ACK) |
|
| 51 |
+ req := h.newNetlinkRequest(unix.RTM_DELADDR, unix.NLM_F_ACK) |
|
| 52 | 52 |
return h.addrHandle(link, addr, req) |
| 53 | 53 |
} |
| 54 | 54 |
|
| ... | ... |
@@ -75,7 +76,7 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error |
| 75 | 75 |
localAddrData = addr.IP.To16() |
| 76 | 76 |
} |
| 77 | 77 |
|
| 78 |
- localData := nl.NewRtAttr(syscall.IFA_LOCAL, localAddrData) |
|
| 78 |
+ localData := nl.NewRtAttr(unix.IFA_LOCAL, localAddrData) |
|
| 79 | 79 |
req.AddData(localData) |
| 80 | 80 |
var peerAddrData []byte |
| 81 | 81 |
if addr.Peer != nil {
|
| ... | ... |
@@ -88,7 +89,7 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error |
| 88 | 88 |
peerAddrData = localAddrData |
| 89 | 89 |
} |
| 90 | 90 |
|
| 91 |
- addressData := nl.NewRtAttr(syscall.IFA_ADDRESS, peerAddrData) |
|
| 91 |
+ addressData := nl.NewRtAttr(unix.IFA_ADDRESS, peerAddrData) |
|
| 92 | 92 |
req.AddData(addressData) |
| 93 | 93 |
|
| 94 | 94 |
if addr.Flags != 0 {
|
| ... | ... |
@@ -102,21 +103,34 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error |
| 102 | 102 |
} |
| 103 | 103 |
} |
| 104 | 104 |
|
| 105 |
- if addr.Broadcast == nil {
|
|
| 106 |
- calcBroadcast := make(net.IP, masklen/8) |
|
| 107 |
- for i := range localAddrData {
|
|
| 108 |
- calcBroadcast[i] = localAddrData[i] | ^addr.Mask[i] |
|
| 105 |
+ if family == FAMILY_V4 {
|
|
| 106 |
+ if addr.Broadcast == nil {
|
|
| 107 |
+ calcBroadcast := make(net.IP, masklen/8) |
|
| 108 |
+ for i := range localAddrData {
|
|
| 109 |
+ calcBroadcast[i] = localAddrData[i] | ^addr.Mask[i] |
|
| 110 |
+ } |
|
| 111 |
+ addr.Broadcast = calcBroadcast |
|
| 112 |
+ } |
|
| 113 |
+ req.AddData(nl.NewRtAttr(unix.IFA_BROADCAST, addr.Broadcast)) |
|
| 114 |
+ |
|
| 115 |
+ if addr.Label != "" {
|
|
| 116 |
+ labelData := nl.NewRtAttr(unix.IFA_LABEL, nl.ZeroTerminated(addr.Label)) |
|
| 117 |
+ req.AddData(labelData) |
|
| 109 | 118 |
} |
| 110 |
- addr.Broadcast = calcBroadcast |
|
| 111 | 119 |
} |
| 112 |
- req.AddData(nl.NewRtAttr(syscall.IFA_BROADCAST, addr.Broadcast)) |
|
| 113 | 120 |
|
| 114 |
- if addr.Label != "" {
|
|
| 115 |
- labelData := nl.NewRtAttr(syscall.IFA_LABEL, nl.ZeroTerminated(addr.Label)) |
|
| 116 |
- req.AddData(labelData) |
|
| 121 |
+ // 0 is the default value for these attributes. However, 0 means "expired", while the least-surprising default |
|
| 122 |
+ // value should be "forever". To compensate for that, only add the attributes if at least one of the values is |
|
| 123 |
+ // non-zero, which means the caller has explicitly set them |
|
| 124 |
+ if addr.ValidLft > 0 || addr.PreferedLft > 0 {
|
|
| 125 |
+ cachedata := nl.IfaCacheInfo{
|
|
| 126 |
+ IfaValid: uint32(addr.ValidLft), |
|
| 127 |
+ IfaPrefered: uint32(addr.PreferedLft), |
|
| 128 |
+ } |
|
| 129 |
+ req.AddData(nl.NewRtAttr(unix.IFA_CACHEINFO, cachedata.Serialize())) |
|
| 117 | 130 |
} |
| 118 | 131 |
|
| 119 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 132 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 120 | 133 |
return err |
| 121 | 134 |
} |
| 122 | 135 |
|
| ... | ... |
@@ -131,11 +145,11 @@ func AddrList(link Link, family int) ([]Addr, error) {
|
| 131 | 131 |
// Equivalent to: `ip addr show`. |
| 132 | 132 |
// The list can be filtered by link and ip family. |
| 133 | 133 |
func (h *Handle) AddrList(link Link, family int) ([]Addr, error) {
|
| 134 |
- req := h.newNetlinkRequest(syscall.RTM_GETADDR, syscall.NLM_F_DUMP) |
|
| 134 |
+ req := h.newNetlinkRequest(unix.RTM_GETADDR, unix.NLM_F_DUMP) |
|
| 135 | 135 |
msg := nl.NewIfInfomsg(family) |
| 136 | 136 |
req.AddData(msg) |
| 137 | 137 |
|
| 138 |
- msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWADDR) |
|
| 138 |
+ msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWADDR) |
|
| 139 | 139 |
if err != nil {
|
| 140 | 140 |
return nil, err |
| 141 | 141 |
} |
| ... | ... |
@@ -187,21 +201,21 @@ func parseAddr(m []byte) (addr Addr, family, index int, err error) {
|
| 187 | 187 |
var local, dst *net.IPNet |
| 188 | 188 |
for _, attr := range attrs {
|
| 189 | 189 |
switch attr.Attr.Type {
|
| 190 |
- case syscall.IFA_ADDRESS: |
|
| 190 |
+ case unix.IFA_ADDRESS: |
|
| 191 | 191 |
dst = &net.IPNet{
|
| 192 | 192 |
IP: attr.Value, |
| 193 | 193 |
Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)), |
| 194 | 194 |
} |
| 195 | 195 |
addr.Peer = dst |
| 196 |
- case syscall.IFA_LOCAL: |
|
| 196 |
+ case unix.IFA_LOCAL: |
|
| 197 | 197 |
local = &net.IPNet{
|
| 198 | 198 |
IP: attr.Value, |
| 199 | 199 |
Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)), |
| 200 | 200 |
} |
| 201 | 201 |
addr.IPNet = local |
| 202 |
- case syscall.IFA_BROADCAST: |
|
| 202 |
+ case unix.IFA_BROADCAST: |
|
| 203 | 203 |
addr.Broadcast = attr.Value |
| 204 |
- case syscall.IFA_LABEL: |
|
| 204 |
+ case unix.IFA_LABEL: |
|
| 205 | 205 |
addr.Label = string(attr.Value[:len(attr.Value)-1]) |
| 206 | 206 |
case IFA_FLAGS: |
| 207 | 207 |
addr.Flags = int(native.Uint32(attr.Value[0:4])) |
| ... | ... |
@@ -236,13 +250,13 @@ type AddrUpdate struct {
|
| 236 | 236 |
// AddrSubscribe takes a chan down which notifications will be sent |
| 237 | 237 |
// when addresses change. Close the 'done' chan to stop subscription. |
| 238 | 238 |
func AddrSubscribe(ch chan<- AddrUpdate, done <-chan struct{}) error {
|
| 239 |
- return addrSubscribeAt(netns.None(), netns.None(), ch, done, nil) |
|
| 239 |
+ return addrSubscribeAt(netns.None(), netns.None(), ch, done, nil, false) |
|
| 240 | 240 |
} |
| 241 | 241 |
|
| 242 | 242 |
// AddrSubscribeAt works like AddrSubscribe plus it allows the caller |
| 243 | 243 |
// to choose the network namespace in which to subscribe (ns). |
| 244 | 244 |
func AddrSubscribeAt(ns netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}) error {
|
| 245 |
- return addrSubscribeAt(ns, netns.None(), ch, done, nil) |
|
| 245 |
+ return addrSubscribeAt(ns, netns.None(), ch, done, nil, false) |
|
| 246 | 246 |
} |
| 247 | 247 |
|
| 248 | 248 |
// AddrSubscribeOptions contains a set of options to use with |
| ... | ... |
@@ -250,6 +264,7 @@ func AddrSubscribeAt(ns netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct |
| 250 | 250 |
type AddrSubscribeOptions struct {
|
| 251 | 251 |
Namespace *netns.NsHandle |
| 252 | 252 |
ErrorCallback func(error) |
| 253 |
+ ListExisting bool |
|
| 253 | 254 |
} |
| 254 | 255 |
|
| 255 | 256 |
// AddrSubscribeWithOptions work like AddrSubscribe but enable to |
| ... | ... |
@@ -260,11 +275,11 @@ func AddrSubscribeWithOptions(ch chan<- AddrUpdate, done <-chan struct{}, option
|
| 260 | 260 |
none := netns.None() |
| 261 | 261 |
options.Namespace = &none |
| 262 | 262 |
} |
| 263 |
- return addrSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback) |
|
| 263 |
+ return addrSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting) |
|
| 264 | 264 |
} |
| 265 | 265 |
|
| 266 |
-func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}, cberr func(error)) error {
|
|
| 267 |
- s, err := nl.SubscribeAt(newNs, curNs, syscall.NETLINK_ROUTE, syscall.RTNLGRP_IPV4_IFADDR, syscall.RTNLGRP_IPV6_IFADDR) |
|
| 266 |
+func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}, cberr func(error), listExisting bool) error {
|
|
| 267 |
+ s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_IPV4_IFADDR, unix.RTNLGRP_IPV6_IFADDR) |
|
| 268 | 268 |
if err != nil {
|
| 269 | 269 |
return err |
| 270 | 270 |
} |
| ... | ... |
@@ -274,6 +289,15 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c |
| 274 | 274 |
s.Close() |
| 275 | 275 |
}() |
| 276 | 276 |
} |
| 277 |
+ if listExisting {
|
|
| 278 |
+ req := pkgHandle.newNetlinkRequest(unix.RTM_GETADDR, |
|
| 279 |
+ unix.NLM_F_DUMP) |
|
| 280 |
+ infmsg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 281 |
+ req.AddData(infmsg) |
|
| 282 |
+ if err := s.Send(req); err != nil {
|
|
| 283 |
+ return err |
|
| 284 |
+ } |
|
| 285 |
+ } |
|
| 277 | 286 |
go func() {
|
| 278 | 287 |
defer close(ch) |
| 279 | 288 |
for {
|
| ... | ... |
@@ -285,8 +309,22 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c |
| 285 | 285 |
return |
| 286 | 286 |
} |
| 287 | 287 |
for _, m := range msgs {
|
| 288 |
+ if m.Header.Type == unix.NLMSG_DONE {
|
|
| 289 |
+ continue |
|
| 290 |
+ } |
|
| 291 |
+ if m.Header.Type == unix.NLMSG_ERROR {
|
|
| 292 |
+ native := nl.NativeEndian() |
|
| 293 |
+ error := int32(native.Uint32(m.Data[0:4])) |
|
| 294 |
+ if error == 0 {
|
|
| 295 |
+ continue |
|
| 296 |
+ } |
|
| 297 |
+ if cberr != nil {
|
|
| 298 |
+ cberr(syscall.Errno(-error)) |
|
| 299 |
+ } |
|
| 300 |
+ return |
|
| 301 |
+ } |
|
| 288 | 302 |
msgType := m.Header.Type |
| 289 |
- if msgType != syscall.RTM_NEWADDR && msgType != syscall.RTM_DELADDR {
|
|
| 303 |
+ if msgType != unix.RTM_NEWADDR && msgType != unix.RTM_DELADDR {
|
|
| 290 | 304 |
if cberr != nil {
|
| 291 | 305 |
cberr(fmt.Errorf("bad message type: %d", msgType))
|
| 292 | 306 |
} |
| ... | ... |
@@ -303,7 +341,7 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c |
| 303 | 303 |
|
| 304 | 304 |
ch <- AddrUpdate{LinkAddress: *addr.IPNet,
|
| 305 | 305 |
LinkIndex: ifindex, |
| 306 |
- NewAddr: msgType == syscall.RTM_NEWADDR, |
|
| 306 |
+ NewAddr: msgType == unix.RTM_NEWADDR, |
|
| 307 | 307 |
Flags: addr.Flags, |
| 308 | 308 |
Scope: addr.Scope, |
| 309 | 309 |
PreferedLft: addr.PreferedLft, |
| ... | ... |
@@ -1,49 +1,12 @@ |
| 1 | 1 |
package netlink |
| 2 | 2 |
|
| 3 |
-/* |
|
| 4 |
-#include <asm/types.h> |
|
| 5 |
-#include <asm/unistd.h> |
|
| 6 |
-#include <errno.h> |
|
| 7 |
-#include <stdio.h> |
|
| 8 |
-#include <stdint.h> |
|
| 9 |
-#include <unistd.h> |
|
| 3 |
+import ( |
|
| 4 |
+ "unsafe" |
|
| 10 | 5 |
|
| 11 |
-static int load_simple_bpf(int prog_type, int ret) {
|
|
| 12 |
-#ifdef __NR_bpf |
|
| 13 |
- // { return ret; }
|
|
| 14 |
- __u64 __attribute__((aligned(8))) insns[] = {
|
|
| 15 |
- 0x00000000000000b7ull | ((__u64)ret<<32), |
|
| 16 |
- 0x0000000000000095ull, |
|
| 17 |
- }; |
|
| 18 |
- __u8 __attribute__((aligned(8))) license[] = "ASL2"; |
|
| 19 |
- // Copied from a header file since libc is notoriously slow to update. |
|
| 20 |
- // The call will succeed or fail and that will be our indication on |
|
| 21 |
- // whether or not it is supported. |
|
| 22 |
- struct {
|
|
| 23 |
- __u32 prog_type; |
|
| 24 |
- __u32 insn_cnt; |
|
| 25 |
- __u64 insns; |
|
| 26 |
- __u64 license; |
|
| 27 |
- __u32 log_level; |
|
| 28 |
- __u32 log_size; |
|
| 29 |
- __u64 log_buf; |
|
| 30 |
- __u32 kern_version; |
|
| 31 |
- } __attribute__((aligned(8))) attr = {
|
|
| 32 |
- .prog_type = prog_type, |
|
| 33 |
- .insn_cnt = 2, |
|
| 34 |
- .insns = (uintptr_t)&insns, |
|
| 35 |
- .license = (uintptr_t)&license, |
|
| 36 |
- }; |
|
| 37 |
- return syscall(__NR_bpf, 5, &attr, sizeof(attr)); |
|
| 38 |
-#else |
|
| 39 |
- errno = EINVAL; |
|
| 40 |
- return -1; |
|
| 41 |
-#endif |
|
| 42 |
-} |
|
| 43 |
-*/ |
|
| 44 |
-import "C" |
|
| 6 |
+ "golang.org/x/sys/unix" |
|
| 7 |
+) |
|
| 45 | 8 |
|
| 46 |
-type BpfProgType C.int |
|
| 9 |
+type BpfProgType uint32 |
|
| 47 | 10 |
|
| 48 | 11 |
const ( |
| 49 | 12 |
BPF_PROG_TYPE_UNSPEC BpfProgType = iota |
| ... | ... |
@@ -55,8 +18,36 @@ const ( |
| 55 | 55 |
BPF_PROG_TYPE_XDP |
| 56 | 56 |
) |
| 57 | 57 |
|
| 58 |
-// loadSimpleBpf loads a trivial bpf program for testing purposes |
|
| 59 |
-func loadSimpleBpf(progType BpfProgType, ret int) (int, error) {
|
|
| 60 |
- fd, err := C.load_simple_bpf(C.int(progType), C.int(ret)) |
|
| 61 |
- return int(fd), err |
|
| 58 |
+type BPFAttr struct {
|
|
| 59 |
+ ProgType uint32 |
|
| 60 |
+ InsnCnt uint32 |
|
| 61 |
+ Insns uintptr |
|
| 62 |
+ License uintptr |
|
| 63 |
+ LogLevel uint32 |
|
| 64 |
+ LogSize uint32 |
|
| 65 |
+ LogBuf uintptr |
|
| 66 |
+ KernVersion uint32 |
|
| 67 |
+} |
|
| 68 |
+ |
|
| 69 |
+// loadSimpleBpf loads a trivial bpf program for testing purposes. |
|
| 70 |
+func loadSimpleBpf(progType BpfProgType, ret uint32) (int, error) {
|
|
| 71 |
+ insns := []uint64{
|
|
| 72 |
+ 0x00000000000000b7 | (uint64(ret) << 32), |
|
| 73 |
+ 0x0000000000000095, |
|
| 74 |
+ } |
|
| 75 |
+ license := []byte{'A', 'S', 'L', '2', '\x00'}
|
|
| 76 |
+ attr := BPFAttr{
|
|
| 77 |
+ ProgType: uint32(progType), |
|
| 78 |
+ InsnCnt: uint32(len(insns)), |
|
| 79 |
+ Insns: uintptr(unsafe.Pointer(&insns[0])), |
|
| 80 |
+ License: uintptr(unsafe.Pointer(&license[0])), |
|
| 81 |
+ } |
|
| 82 |
+ fd, _, errno := unix.Syscall(unix.SYS_BPF, |
|
| 83 |
+ 5, /* bpf cmd */ |
|
| 84 |
+ uintptr(unsafe.Pointer(&attr)), |
|
| 85 |
+ unsafe.Sizeof(attr)) |
|
| 86 |
+ if errno != 0 {
|
|
| 87 |
+ return 0, errno |
|
| 88 |
+ } |
|
| 89 |
+ return int(fd), nil |
|
| 62 | 90 |
} |
| ... | ... |
@@ -2,9 +2,9 @@ package netlink |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"fmt" |
| 5 |
- "syscall" |
|
| 6 | 5 |
|
| 7 | 6 |
"github.com/vishvananda/netlink/nl" |
| 7 |
+ "golang.org/x/sys/unix" |
|
| 8 | 8 |
) |
| 9 | 9 |
|
| 10 | 10 |
// BridgeVlanList gets a map of device id to bridge vlan infos. |
| ... | ... |
@@ -16,12 +16,12 @@ func BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) {
|
| 16 | 16 |
// BridgeVlanList gets a map of device id to bridge vlan infos. |
| 17 | 17 |
// Equivalent to: `bridge vlan show` |
| 18 | 18 |
func (h *Handle) BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) {
|
| 19 |
- req := h.newNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_DUMP) |
|
| 20 |
- msg := nl.NewIfInfomsg(syscall.AF_BRIDGE) |
|
| 19 |
+ req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_DUMP) |
|
| 20 |
+ msg := nl.NewIfInfomsg(unix.AF_BRIDGE) |
|
| 21 | 21 |
req.AddData(msg) |
| 22 |
- req.AddData(nl.NewRtAttr(nl.IFLA_EXT_MASK, nl.Uint32Attr(uint32(nl.RTEXT_FILTER_BRVLAN)))) |
|
| 22 |
+ req.AddData(nl.NewRtAttr(unix.IFLA_EXT_MASK, nl.Uint32Attr(uint32(nl.RTEXT_FILTER_BRVLAN)))) |
|
| 23 | 23 |
|
| 24 |
- msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWLINK) |
|
| 24 |
+ msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWLINK) |
|
| 25 | 25 |
if err != nil {
|
| 26 | 26 |
return nil, err |
| 27 | 27 |
} |
| ... | ... |
@@ -35,7 +35,7 @@ func (h *Handle) BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) {
|
| 35 | 35 |
} |
| 36 | 36 |
for _, attr := range attrs {
|
| 37 | 37 |
switch attr.Attr.Type {
|
| 38 |
- case nl.IFLA_AF_SPEC: |
|
| 38 |
+ case unix.IFLA_AF_SPEC: |
|
| 39 | 39 |
//nested attr |
| 40 | 40 |
nestAttrs, err := nl.ParseRouteAttr(attr.Value) |
| 41 | 41 |
if err != nil {
|
| ... | ... |
@@ -63,7 +63,7 @@ func BridgeVlanAdd(link Link, vid uint16, pvid, untagged, self, master bool) err |
| 63 | 63 |
// BridgeVlanAdd adds a new vlan filter entry |
| 64 | 64 |
// Equivalent to: `bridge vlan add dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]` |
| 65 | 65 |
func (h *Handle) BridgeVlanAdd(link Link, vid uint16, pvid, untagged, self, master bool) error {
|
| 66 |
- return h.bridgeVlanModify(syscall.RTM_SETLINK, link, vid, pvid, untagged, self, master) |
|
| 66 |
+ return h.bridgeVlanModify(unix.RTM_SETLINK, link, vid, pvid, untagged, self, master) |
|
| 67 | 67 |
} |
| 68 | 68 |
|
| 69 | 69 |
// BridgeVlanDel adds a new vlan filter entry |
| ... | ... |
@@ -75,19 +75,19 @@ func BridgeVlanDel(link Link, vid uint16, pvid, untagged, self, master bool) err |
| 75 | 75 |
// BridgeVlanDel adds a new vlan filter entry |
| 76 | 76 |
// Equivalent to: `bridge vlan del dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]` |
| 77 | 77 |
func (h *Handle) BridgeVlanDel(link Link, vid uint16, pvid, untagged, self, master bool) error {
|
| 78 |
- return h.bridgeVlanModify(syscall.RTM_DELLINK, link, vid, pvid, untagged, self, master) |
|
| 78 |
+ return h.bridgeVlanModify(unix.RTM_DELLINK, link, vid, pvid, untagged, self, master) |
|
| 79 | 79 |
} |
| 80 | 80 |
|
| 81 | 81 |
func (h *Handle) bridgeVlanModify(cmd int, link Link, vid uint16, pvid, untagged, self, master bool) error {
|
| 82 | 82 |
base := link.Attrs() |
| 83 | 83 |
h.ensureIndex(base) |
| 84 |
- req := h.newNetlinkRequest(cmd, syscall.NLM_F_ACK) |
|
| 84 |
+ req := h.newNetlinkRequest(cmd, unix.NLM_F_ACK) |
|
| 85 | 85 |
|
| 86 |
- msg := nl.NewIfInfomsg(syscall.AF_BRIDGE) |
|
| 86 |
+ msg := nl.NewIfInfomsg(unix.AF_BRIDGE) |
|
| 87 | 87 |
msg.Index = int32(base.Index) |
| 88 | 88 |
req.AddData(msg) |
| 89 | 89 |
|
| 90 |
- br := nl.NewRtAttr(nl.IFLA_AF_SPEC, nil) |
|
| 90 |
+ br := nl.NewRtAttr(unix.IFLA_AF_SPEC, nil) |
|
| 91 | 91 |
var flags uint16 |
| 92 | 92 |
if self {
|
| 93 | 93 |
flags |= nl.BRIDGE_FLAGS_SELF |
| ... | ... |
@@ -107,7 +107,7 @@ func (h *Handle) bridgeVlanModify(cmd int, link Link, vid uint16, pvid, untagged |
| 107 | 107 |
} |
| 108 | 108 |
nl.NewRtAttrChild(br, nl.IFLA_BRIDGE_VLAN_INFO, vlanInfo.Serialize()) |
| 109 | 109 |
req.AddData(br) |
| 110 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 110 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 111 | 111 |
if err != nil {
|
| 112 | 112 |
return err |
| 113 | 113 |
} |
| ... | ... |
@@ -5,6 +5,7 @@ import ( |
| 5 | 5 |
"syscall" |
| 6 | 6 |
|
| 7 | 7 |
"github.com/vishvananda/netlink/nl" |
| 8 |
+ "golang.org/x/sys/unix" |
|
| 8 | 9 |
) |
| 9 | 10 |
|
| 10 | 11 |
// NOTE: function is in here because it uses other linux functions |
| ... | ... |
@@ -50,7 +51,7 @@ func ClassDel(class Class) error {
|
| 50 | 50 |
// ClassDel will delete a class from the system. |
| 51 | 51 |
// Equivalent to: `tc class del $class` |
| 52 | 52 |
func (h *Handle) ClassDel(class Class) error {
|
| 53 |
- return h.classModify(syscall.RTM_DELTCLASS, 0, class) |
|
| 53 |
+ return h.classModify(unix.RTM_DELTCLASS, 0, class) |
|
| 54 | 54 |
} |
| 55 | 55 |
|
| 56 | 56 |
// ClassChange will change a class in place |
| ... | ... |
@@ -64,7 +65,7 @@ func ClassChange(class Class) error {
|
| 64 | 64 |
// Equivalent to: `tc class change $class` |
| 65 | 65 |
// The parent and handle MUST NOT be changed. |
| 66 | 66 |
func (h *Handle) ClassChange(class Class) error {
|
| 67 |
- return h.classModify(syscall.RTM_NEWTCLASS, 0, class) |
|
| 67 |
+ return h.classModify(unix.RTM_NEWTCLASS, 0, class) |
|
| 68 | 68 |
} |
| 69 | 69 |
|
| 70 | 70 |
// ClassReplace will replace a class to the system. |
| ... | ... |
@@ -82,7 +83,7 @@ func ClassReplace(class Class) error {
|
| 82 | 82 |
// If a class already exist with this parent/handle pair, the class is changed. |
| 83 | 83 |
// If a class does not already exist with this parent/handle, a new class is created. |
| 84 | 84 |
func (h *Handle) ClassReplace(class Class) error {
|
| 85 |
- return h.classModify(syscall.RTM_NEWTCLASS, syscall.NLM_F_CREATE, class) |
|
| 85 |
+ return h.classModify(unix.RTM_NEWTCLASS, unix.NLM_F_CREATE, class) |
|
| 86 | 86 |
} |
| 87 | 87 |
|
| 88 | 88 |
// ClassAdd will add a class to the system. |
| ... | ... |
@@ -95,14 +96,14 @@ func ClassAdd(class Class) error {
|
| 95 | 95 |
// Equivalent to: `tc class add $class` |
| 96 | 96 |
func (h *Handle) ClassAdd(class Class) error {
|
| 97 | 97 |
return h.classModify( |
| 98 |
- syscall.RTM_NEWTCLASS, |
|
| 99 |
- syscall.NLM_F_CREATE|syscall.NLM_F_EXCL, |
|
| 98 |
+ unix.RTM_NEWTCLASS, |
|
| 99 |
+ unix.NLM_F_CREATE|unix.NLM_F_EXCL, |
|
| 100 | 100 |
class, |
| 101 | 101 |
) |
| 102 | 102 |
} |
| 103 | 103 |
|
| 104 | 104 |
func (h *Handle) classModify(cmd, flags int, class Class) error {
|
| 105 |
- req := h.newNetlinkRequest(cmd, flags|syscall.NLM_F_ACK) |
|
| 105 |
+ req := h.newNetlinkRequest(cmd, flags|unix.NLM_F_ACK) |
|
| 106 | 106 |
base := class.Attrs() |
| 107 | 107 |
msg := &nl.TcMsg{
|
| 108 | 108 |
Family: nl.FAMILY_ALL, |
| ... | ... |
@@ -112,12 +113,12 @@ func (h *Handle) classModify(cmd, flags int, class Class) error {
|
| 112 | 112 |
} |
| 113 | 113 |
req.AddData(msg) |
| 114 | 114 |
|
| 115 |
- if cmd != syscall.RTM_DELTCLASS {
|
|
| 115 |
+ if cmd != unix.RTM_DELTCLASS {
|
|
| 116 | 116 |
if err := classPayload(req, class); err != nil {
|
| 117 | 117 |
return err |
| 118 | 118 |
} |
| 119 | 119 |
} |
| 120 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 120 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 121 | 121 |
return err |
| 122 | 122 |
} |
| 123 | 123 |
|
| ... | ... |
@@ -141,12 +142,12 @@ func classPayload(req *nl.NetlinkRequest, class Class) error {
|
| 141 | 141 |
var rtab [256]uint32 |
| 142 | 142 |
var ctab [256]uint32 |
| 143 | 143 |
tcrate := nl.TcRateSpec{Rate: uint32(htb.Rate)}
|
| 144 |
- if CalcRtable(&tcrate, rtab, cellLog, uint32(mtu), linklayer) < 0 {
|
|
| 144 |
+ if CalcRtable(&tcrate, rtab[:], cellLog, uint32(mtu), linklayer) < 0 {
|
|
| 145 | 145 |
return errors.New("HTB: failed to calculate rate table")
|
| 146 | 146 |
} |
| 147 | 147 |
opt.Rate = tcrate |
| 148 | 148 |
tcceil := nl.TcRateSpec{Rate: uint32(htb.Ceil)}
|
| 149 |
- if CalcRtable(&tcceil, ctab, ccellLog, uint32(mtu), linklayer) < 0 {
|
|
| 149 |
+ if CalcRtable(&tcceil, ctab[:], ccellLog, uint32(mtu), linklayer) < 0 {
|
|
| 150 | 150 |
return errors.New("HTB: failed to calculate ceil rate table")
|
| 151 | 151 |
} |
| 152 | 152 |
opt.Ceil = tcceil |
| ... | ... |
@@ -169,7 +170,7 @@ func ClassList(link Link, parent uint32) ([]Class, error) {
|
| 169 | 169 |
// Equivalent to: `tc class show`. |
| 170 | 170 |
// Generally returns nothing if link and parent are not specified. |
| 171 | 171 |
func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) {
|
| 172 |
- req := h.newNetlinkRequest(syscall.RTM_GETTCLASS, syscall.NLM_F_DUMP) |
|
| 172 |
+ req := h.newNetlinkRequest(unix.RTM_GETTCLASS, unix.NLM_F_DUMP) |
|
| 173 | 173 |
msg := &nl.TcMsg{
|
| 174 | 174 |
Family: nl.FAMILY_ALL, |
| 175 | 175 |
Parent: parent, |
| ... | ... |
@@ -181,7 +182,7 @@ func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) {
|
| 181 | 181 |
} |
| 182 | 182 |
req.AddData(msg) |
| 183 | 183 |
|
| 184 |
- msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWTCLASS) |
|
| 184 |
+ msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWTCLASS) |
|
| 185 | 185 |
if err != nil {
|
| 186 | 186 |
return nil, err |
| 187 | 187 |
} |
| ... | ... |
@@ -6,9 +6,9 @@ import ( |
| 6 | 6 |
"errors" |
| 7 | 7 |
"fmt" |
| 8 | 8 |
"net" |
| 9 |
- "syscall" |
|
| 10 | 9 |
|
| 11 | 10 |
"github.com/vishvananda/netlink/nl" |
| 11 |
+ "golang.org/x/sys/unix" |
|
| 12 | 12 |
) |
| 13 | 13 |
|
| 14 | 14 |
// ConntrackTableType Conntrack table for the netlink operation |
| ... | ... |
@@ -85,8 +85,8 @@ func (h *Handle) ConntrackTableList(table ConntrackTableType, family InetFamily) |
| 85 | 85 |
// conntrack -F [table] Flush table |
| 86 | 86 |
// The flush operation applies to all the family types |
| 87 | 87 |
func (h *Handle) ConntrackTableFlush(table ConntrackTableType) error {
|
| 88 |
- req := h.newConntrackRequest(table, syscall.AF_INET, nl.IPCTNL_MSG_CT_DELETE, syscall.NLM_F_ACK) |
|
| 89 |
- _, err := req.Execute(syscall.NETLINK_NETFILTER, 0) |
|
| 88 |
+ req := h.newConntrackRequest(table, unix.AF_INET, nl.IPCTNL_MSG_CT_DELETE, unix.NLM_F_ACK) |
|
| 89 |
+ _, err := req.Execute(unix.NETLINK_NETFILTER, 0) |
|
| 90 | 90 |
return err |
| 91 | 91 |
} |
| 92 | 92 |
|
| ... | ... |
@@ -102,10 +102,10 @@ func (h *Handle) ConntrackDeleteFilter(table ConntrackTableType, family InetFami |
| 102 | 102 |
for _, dataRaw := range res {
|
| 103 | 103 |
flow := parseRawData(dataRaw) |
| 104 | 104 |
if match := filter.MatchConntrackFlow(flow); match {
|
| 105 |
- req2 := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_DELETE, syscall.NLM_F_ACK) |
|
| 105 |
+ req2 := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_DELETE, unix.NLM_F_ACK) |
|
| 106 | 106 |
// skip the first 4 byte that are the netfilter header, the newConntrackRequest is adding it already |
| 107 | 107 |
req2.AddRawData(dataRaw[4:]) |
| 108 |
- req2.Execute(syscall.NETLINK_NETFILTER, 0) |
|
| 108 |
+ req2.Execute(unix.NETLINK_NETFILTER, 0) |
|
| 109 | 109 |
matched++ |
| 110 | 110 |
} |
| 111 | 111 |
} |
| ... | ... |
@@ -127,8 +127,8 @@ func (h *Handle) newConntrackRequest(table ConntrackTableType, family InetFamily |
| 127 | 127 |
} |
| 128 | 128 |
|
| 129 | 129 |
func (h *Handle) dumpConntrackTable(table ConntrackTableType, family InetFamily) ([][]byte, error) {
|
| 130 |
- req := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_GET, syscall.NLM_F_DUMP) |
|
| 131 |
- return req.Execute(syscall.NETLINK_NETFILTER, 0) |
|
| 130 |
+ req := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_GET, unix.NLM_F_DUMP) |
|
| 131 |
+ return req.Execute(unix.NETLINK_NETFILTER, 0) |
|
| 132 | 132 |
} |
| 133 | 133 |
|
| 134 | 134 |
// The full conntrack flow structure is very complicated and can be found in the file: |
| ... | ... |
@@ -17,7 +17,7 @@ type FilterAttrs struct {
|
| 17 | 17 |
Handle uint32 |
| 18 | 18 |
Parent uint32 |
| 19 | 19 |
Priority uint16 // lower is higher priority |
| 20 |
- Protocol uint16 // syscall.ETH_P_* |
|
| 20 |
+ Protocol uint16 // unix.ETH_P_* |
|
| 21 | 21 |
} |
| 22 | 22 |
|
| 23 | 23 |
func (q FilterAttrs) String() string {
|
| ... | ... |
@@ -225,6 +225,21 @@ func (filter *U32) Type() string {
|
| 225 | 225 |
return "u32" |
| 226 | 226 |
} |
| 227 | 227 |
|
| 228 |
+// MatchAll filters match all packets |
|
| 229 |
+type MatchAll struct {
|
|
| 230 |
+ FilterAttrs |
|
| 231 |
+ ClassId uint32 |
|
| 232 |
+ Actions []Action |
|
| 233 |
+} |
|
| 234 |
+ |
|
| 235 |
+func (filter *MatchAll) Attrs() *FilterAttrs {
|
|
| 236 |
+ return &filter.FilterAttrs |
|
| 237 |
+} |
|
| 238 |
+ |
|
| 239 |
+func (filter *MatchAll) Type() string {
|
|
| 240 |
+ return "matchall" |
|
| 241 |
+} |
|
| 242 |
+ |
|
| 228 | 243 |
type FilterFwAttrs struct {
|
| 229 | 244 |
ClassId uint32 |
| 230 | 245 |
InDev string |
| ... | ... |
@@ -9,6 +9,7 @@ import ( |
| 9 | 9 |
"unsafe" |
| 10 | 10 |
|
| 11 | 11 |
"github.com/vishvananda/netlink/nl" |
| 12 |
+ "golang.org/x/sys/unix" |
|
| 12 | 13 |
) |
| 13 | 14 |
|
| 14 | 15 |
// Constants used in TcU32Sel.Flags. |
| ... | ... |
@@ -55,7 +56,7 @@ func NewFw(attrs FilterAttrs, fattrs FilterFwAttrs) (*Fw, error) {
|
| 55 | 55 |
if police.Rate.Rate != 0 {
|
| 56 | 56 |
police.Rate.Mpu = fattrs.Mpu |
| 57 | 57 |
police.Rate.Overhead = fattrs.Overhead |
| 58 |
- if CalcRtable(&police.Rate, rtab, rcellLog, fattrs.Mtu, linklayer) < 0 {
|
|
| 58 |
+ if CalcRtable(&police.Rate, rtab[:], rcellLog, fattrs.Mtu, linklayer) < 0 {
|
|
| 59 | 59 |
return nil, errors.New("TBF: failed to calculate rate table")
|
| 60 | 60 |
} |
| 61 | 61 |
police.Burst = uint32(Xmittime(uint64(police.Rate.Rate), uint32(buffer))) |
| ... | ... |
@@ -64,7 +65,7 @@ func NewFw(attrs FilterAttrs, fattrs FilterFwAttrs) (*Fw, error) {
|
| 64 | 64 |
if police.PeakRate.Rate != 0 {
|
| 65 | 65 |
police.PeakRate.Mpu = fattrs.Mpu |
| 66 | 66 |
police.PeakRate.Overhead = fattrs.Overhead |
| 67 |
- if CalcRtable(&police.PeakRate, ptab, pcellLog, fattrs.Mtu, linklayer) < 0 {
|
|
| 67 |
+ if CalcRtable(&police.PeakRate, ptab[:], pcellLog, fattrs.Mtu, linklayer) < 0 {
|
|
| 68 | 68 |
return nil, errors.New("POLICE: failed to calculate peak rate table")
|
| 69 | 69 |
} |
| 70 | 70 |
} |
| ... | ... |
@@ -98,7 +99,7 @@ func FilterDel(filter Filter) error {
|
| 98 | 98 |
// FilterDel will delete a filter from the system. |
| 99 | 99 |
// Equivalent to: `tc filter del $filter` |
| 100 | 100 |
func (h *Handle) FilterDel(filter Filter) error {
|
| 101 |
- req := h.newNetlinkRequest(syscall.RTM_DELTFILTER, syscall.NLM_F_ACK) |
|
| 101 |
+ req := h.newNetlinkRequest(unix.RTM_DELTFILTER, unix.NLM_F_ACK) |
|
| 102 | 102 |
base := filter.Attrs() |
| 103 | 103 |
msg := &nl.TcMsg{
|
| 104 | 104 |
Family: nl.FAMILY_ALL, |
| ... | ... |
@@ -109,7 +110,7 @@ func (h *Handle) FilterDel(filter Filter) error {
|
| 109 | 109 |
} |
| 110 | 110 |
req.AddData(msg) |
| 111 | 111 |
|
| 112 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 112 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 113 | 113 |
return err |
| 114 | 114 |
} |
| 115 | 115 |
|
| ... | ... |
@@ -123,7 +124,7 @@ func FilterAdd(filter Filter) error {
|
| 123 | 123 |
// Equivalent to: `tc filter add $filter` |
| 124 | 124 |
func (h *Handle) FilterAdd(filter Filter) error {
|
| 125 | 125 |
native = nl.NativeEndian() |
| 126 |
- req := h.newNetlinkRequest(syscall.RTM_NEWTFILTER, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) |
|
| 126 |
+ req := h.newNetlinkRequest(unix.RTM_NEWTFILTER, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK) |
|
| 127 | 127 |
base := filter.Attrs() |
| 128 | 128 |
msg := &nl.TcMsg{
|
| 129 | 129 |
Family: nl.FAMILY_ALL, |
| ... | ... |
@@ -221,10 +222,18 @@ func (h *Handle) FilterAdd(filter Filter) error {
|
| 221 | 221 |
bpfFlags |= nl.TCA_BPF_FLAG_ACT_DIRECT |
| 222 | 222 |
} |
| 223 | 223 |
nl.NewRtAttrChild(options, nl.TCA_BPF_FLAGS, nl.Uint32Attr(bpfFlags)) |
| 224 |
+ case *MatchAll: |
|
| 225 |
+ actionsAttr := nl.NewRtAttrChild(options, nl.TCA_MATCHALL_ACT, nil) |
|
| 226 |
+ if err := EncodeActions(actionsAttr, filter.Actions); err != nil {
|
|
| 227 |
+ return err |
|
| 228 |
+ } |
|
| 229 |
+ if filter.ClassId != 0 {
|
|
| 230 |
+ nl.NewRtAttrChild(options, nl.TCA_MATCHALL_CLASSID, nl.Uint32Attr(filter.ClassId)) |
|
| 231 |
+ } |
|
| 224 | 232 |
} |
| 225 | 233 |
|
| 226 | 234 |
req.AddData(options) |
| 227 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 235 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 228 | 236 |
return err |
| 229 | 237 |
} |
| 230 | 238 |
|
| ... | ... |
@@ -239,7 +248,7 @@ func FilterList(link Link, parent uint32) ([]Filter, error) {
|
| 239 | 239 |
// Equivalent to: `tc filter show`. |
| 240 | 240 |
// Generally returns nothing if link and parent are not specified. |
| 241 | 241 |
func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
|
| 242 |
- req := h.newNetlinkRequest(syscall.RTM_GETTFILTER, syscall.NLM_F_DUMP) |
|
| 242 |
+ req := h.newNetlinkRequest(unix.RTM_GETTFILTER, unix.NLM_F_DUMP) |
|
| 243 | 243 |
msg := &nl.TcMsg{
|
| 244 | 244 |
Family: nl.FAMILY_ALL, |
| 245 | 245 |
Parent: parent, |
| ... | ... |
@@ -251,7 +260,7 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
|
| 251 | 251 |
} |
| 252 | 252 |
req.AddData(msg) |
| 253 | 253 |
|
| 254 |
- msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWTFILTER) |
|
| 254 |
+ msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWTFILTER) |
|
| 255 | 255 |
if err != nil {
|
| 256 | 256 |
return nil, err |
| 257 | 257 |
} |
| ... | ... |
@@ -287,6 +296,8 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
|
| 287 | 287 |
filter = &Fw{}
|
| 288 | 288 |
case "bpf": |
| 289 | 289 |
filter = &BpfFilter{}
|
| 290 |
+ case "matchall": |
|
| 291 |
+ filter = &MatchAll{}
|
|
| 290 | 292 |
default: |
| 291 | 293 |
filter = &GenericFilter{FilterType: filterType}
|
| 292 | 294 |
} |
| ... | ... |
@@ -311,6 +322,11 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
|
| 311 | 311 |
if err != nil {
|
| 312 | 312 |
return nil, err |
| 313 | 313 |
} |
| 314 |
+ case "matchall": |
|
| 315 |
+ detailed, err = parseMatchAllData(filter, data) |
|
| 316 |
+ if err != nil {
|
|
| 317 |
+ return nil, err |
|
| 318 |
+ } |
|
| 314 | 319 |
default: |
| 315 | 320 |
detailed = true |
| 316 | 321 |
} |
| ... | ... |
@@ -540,6 +556,28 @@ func parseBpfData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) |
| 540 | 540 |
return detailed, nil |
| 541 | 541 |
} |
| 542 | 542 |
|
| 543 |
+func parseMatchAllData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
|
|
| 544 |
+ native = nl.NativeEndian() |
|
| 545 |
+ matchall := filter.(*MatchAll) |
|
| 546 |
+ detailed := true |
|
| 547 |
+ for _, datum := range data {
|
|
| 548 |
+ switch datum.Attr.Type {
|
|
| 549 |
+ case nl.TCA_MATCHALL_CLASSID: |
|
| 550 |
+ matchall.ClassId = native.Uint32(datum.Value[0:4]) |
|
| 551 |
+ case nl.TCA_MATCHALL_ACT: |
|
| 552 |
+ tables, err := nl.ParseRouteAttr(datum.Value) |
|
| 553 |
+ if err != nil {
|
|
| 554 |
+ return detailed, err |
|
| 555 |
+ } |
|
| 556 |
+ matchall.Actions, err = parseActions(tables) |
|
| 557 |
+ if err != nil {
|
|
| 558 |
+ return detailed, err |
|
| 559 |
+ } |
|
| 560 |
+ } |
|
| 561 |
+ } |
|
| 562 |
+ return detailed, nil |
|
| 563 |
+} |
|
| 564 |
+ |
|
| 543 | 565 |
func AlignToAtm(size uint) uint {
|
| 544 | 566 |
var linksize, cells int |
| 545 | 567 |
cells = int(size / nl.ATM_CELL_PAYLOAD) |
| ... | ... |
@@ -562,7 +600,7 @@ func AdjustSize(sz uint, mpu uint, linklayer int) uint {
|
| 562 | 562 |
} |
| 563 | 563 |
} |
| 564 | 564 |
|
| 565 |
-func CalcRtable(rate *nl.TcRateSpec, rtab [256]uint32, cellLog int, mtu uint32, linklayer int) int {
|
|
| 565 |
+func CalcRtable(rate *nl.TcRateSpec, rtab []uint32, cellLog int, mtu uint32, linklayer int) int {
|
|
| 566 | 566 |
bps := rate.Rate |
| 567 | 567 |
mpu := rate.Mpu |
| 568 | 568 |
var sz uint |
| 569 | 569 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,21 @@ |
| 0 |
+package netlink |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "errors" |
|
| 4 |
+) |
|
| 5 |
+ |
|
| 6 |
+var ( |
|
| 7 |
+ // ErrAttrHeaderTruncated is returned when a netlink attribute's header is |
|
| 8 |
+ // truncated. |
|
| 9 |
+ ErrAttrHeaderTruncated = errors.New("attribute header truncated")
|
|
| 10 |
+ // ErrAttrBodyTruncated is returned when a netlink attribute's body is |
|
| 11 |
+ // truncated. |
|
| 12 |
+ ErrAttrBodyTruncated = errors.New("attribute body truncated")
|
|
| 13 |
+) |
|
| 14 |
+ |
|
| 15 |
+type Fou struct {
|
|
| 16 |
+ Family int |
|
| 17 |
+ Port int |
|
| 18 |
+ Protocol int |
|
| 19 |
+ EncapType int |
|
| 20 |
+} |
| 0 | 21 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,215 @@ |
| 0 |
+// +build linux |
|
| 1 |
+ |
|
| 2 |
+package netlink |
|
| 3 |
+ |
|
| 4 |
+import ( |
|
| 5 |
+ "encoding/binary" |
|
| 6 |
+ "errors" |
|
| 7 |
+ |
|
| 8 |
+ "github.com/vishvananda/netlink/nl" |
|
| 9 |
+ "golang.org/x/sys/unix" |
|
| 10 |
+) |
|
| 11 |
+ |
|
| 12 |
+const ( |
|
| 13 |
+ FOU_GENL_NAME = "fou" |
|
| 14 |
+) |
|
| 15 |
+ |
|
| 16 |
+const ( |
|
| 17 |
+ FOU_CMD_UNSPEC uint8 = iota |
|
| 18 |
+ FOU_CMD_ADD |
|
| 19 |
+ FOU_CMD_DEL |
|
| 20 |
+ FOU_CMD_GET |
|
| 21 |
+ FOU_CMD_MAX = FOU_CMD_GET |
|
| 22 |
+) |
|
| 23 |
+ |
|
| 24 |
+const ( |
|
| 25 |
+ FOU_ATTR_UNSPEC = iota |
|
| 26 |
+ FOU_ATTR_PORT |
|
| 27 |
+ FOU_ATTR_AF |
|
| 28 |
+ FOU_ATTR_IPPROTO |
|
| 29 |
+ FOU_ATTR_TYPE |
|
| 30 |
+ FOU_ATTR_REMCSUM_NOPARTIAL |
|
| 31 |
+ FOU_ATTR_MAX = FOU_ATTR_REMCSUM_NOPARTIAL |
|
| 32 |
+) |
|
| 33 |
+ |
|
| 34 |
+const ( |
|
| 35 |
+ FOU_ENCAP_UNSPEC = iota |
|
| 36 |
+ FOU_ENCAP_DIRECT |
|
| 37 |
+ FOU_ENCAP_GUE |
|
| 38 |
+ FOU_ENCAP_MAX = FOU_ENCAP_GUE |
|
| 39 |
+) |
|
| 40 |
+ |
|
| 41 |
+var fouFamilyId int |
|
| 42 |
+ |
|
| 43 |
+func FouFamilyId() (int, error) {
|
|
| 44 |
+ if fouFamilyId != 0 {
|
|
| 45 |
+ return fouFamilyId, nil |
|
| 46 |
+ } |
|
| 47 |
+ |
|
| 48 |
+ fam, err := GenlFamilyGet(FOU_GENL_NAME) |
|
| 49 |
+ if err != nil {
|
|
| 50 |
+ return -1, err |
|
| 51 |
+ } |
|
| 52 |
+ |
|
| 53 |
+ fouFamilyId = int(fam.ID) |
|
| 54 |
+ return fouFamilyId, nil |
|
| 55 |
+} |
|
| 56 |
+ |
|
| 57 |
+func FouAdd(f Fou) error {
|
|
| 58 |
+ return pkgHandle.FouAdd(f) |
|
| 59 |
+} |
|
| 60 |
+ |
|
| 61 |
+func (h *Handle) FouAdd(f Fou) error {
|
|
| 62 |
+ fam_id, err := FouFamilyId() |
|
| 63 |
+ if err != nil {
|
|
| 64 |
+ return err |
|
| 65 |
+ } |
|
| 66 |
+ |
|
| 67 |
+ // setting ip protocol conflicts with encapsulation type GUE |
|
| 68 |
+ if f.EncapType == FOU_ENCAP_GUE && f.Protocol != 0 {
|
|
| 69 |
+ return errors.New("GUE encapsulation doesn't specify an IP protocol")
|
|
| 70 |
+ } |
|
| 71 |
+ |
|
| 72 |
+ req := h.newNetlinkRequest(fam_id, unix.NLM_F_ACK) |
|
| 73 |
+ |
|
| 74 |
+ // int to byte for port |
|
| 75 |
+ bp := make([]byte, 2) |
|
| 76 |
+ binary.BigEndian.PutUint16(bp[0:2], uint16(f.Port)) |
|
| 77 |
+ |
|
| 78 |
+ attrs := []*nl.RtAttr{
|
|
| 79 |
+ nl.NewRtAttr(FOU_ATTR_PORT, bp), |
|
| 80 |
+ nl.NewRtAttr(FOU_ATTR_TYPE, []byte{uint8(f.EncapType)}),
|
|
| 81 |
+ nl.NewRtAttr(FOU_ATTR_AF, []byte{uint8(f.Family)}),
|
|
| 82 |
+ nl.NewRtAttr(FOU_ATTR_IPPROTO, []byte{uint8(f.Protocol)}),
|
|
| 83 |
+ } |
|
| 84 |
+ raw := []byte{FOU_CMD_ADD, 1, 0, 0}
|
|
| 85 |
+ for _, a := range attrs {
|
|
| 86 |
+ raw = append(raw, a.Serialize()...) |
|
| 87 |
+ } |
|
| 88 |
+ |
|
| 89 |
+ req.AddRawData(raw) |
|
| 90 |
+ |
|
| 91 |
+ _, err = req.Execute(unix.NETLINK_GENERIC, 0) |
|
| 92 |
+ if err != nil {
|
|
| 93 |
+ return err |
|
| 94 |
+ } |
|
| 95 |
+ |
|
| 96 |
+ return nil |
|
| 97 |
+} |
|
| 98 |
+ |
|
| 99 |
+func FouDel(f Fou) error {
|
|
| 100 |
+ return pkgHandle.FouDel(f) |
|
| 101 |
+} |
|
| 102 |
+ |
|
| 103 |
+func (h *Handle) FouDel(f Fou) error {
|
|
| 104 |
+ fam_id, err := FouFamilyId() |
|
| 105 |
+ if err != nil {
|
|
| 106 |
+ return err |
|
| 107 |
+ } |
|
| 108 |
+ |
|
| 109 |
+ req := h.newNetlinkRequest(fam_id, unix.NLM_F_ACK) |
|
| 110 |
+ |
|
| 111 |
+ // int to byte for port |
|
| 112 |
+ bp := make([]byte, 2) |
|
| 113 |
+ binary.BigEndian.PutUint16(bp[0:2], uint16(f.Port)) |
|
| 114 |
+ |
|
| 115 |
+ attrs := []*nl.RtAttr{
|
|
| 116 |
+ nl.NewRtAttr(FOU_ATTR_PORT, bp), |
|
| 117 |
+ nl.NewRtAttr(FOU_ATTR_AF, []byte{uint8(f.Family)}),
|
|
| 118 |
+ } |
|
| 119 |
+ raw := []byte{FOU_CMD_DEL, 1, 0, 0}
|
|
| 120 |
+ for _, a := range attrs {
|
|
| 121 |
+ raw = append(raw, a.Serialize()...) |
|
| 122 |
+ } |
|
| 123 |
+ |
|
| 124 |
+ req.AddRawData(raw) |
|
| 125 |
+ |
|
| 126 |
+ _, err = req.Execute(unix.NETLINK_GENERIC, 0) |
|
| 127 |
+ if err != nil {
|
|
| 128 |
+ return err |
|
| 129 |
+ } |
|
| 130 |
+ |
|
| 131 |
+ return nil |
|
| 132 |
+} |
|
| 133 |
+ |
|
| 134 |
+func FouList(fam int) ([]Fou, error) {
|
|
| 135 |
+ return pkgHandle.FouList(fam) |
|
| 136 |
+} |
|
| 137 |
+ |
|
| 138 |
+func (h *Handle) FouList(fam int) ([]Fou, error) {
|
|
| 139 |
+ fam_id, err := FouFamilyId() |
|
| 140 |
+ if err != nil {
|
|
| 141 |
+ return nil, err |
|
| 142 |
+ } |
|
| 143 |
+ |
|
| 144 |
+ req := h.newNetlinkRequest(fam_id, unix.NLM_F_DUMP) |
|
| 145 |
+ |
|
| 146 |
+ attrs := []*nl.RtAttr{
|
|
| 147 |
+ nl.NewRtAttr(FOU_ATTR_AF, []byte{uint8(fam)}),
|
|
| 148 |
+ } |
|
| 149 |
+ raw := []byte{FOU_CMD_GET, 1, 0, 0}
|
|
| 150 |
+ for _, a := range attrs {
|
|
| 151 |
+ raw = append(raw, a.Serialize()...) |
|
| 152 |
+ } |
|
| 153 |
+ |
|
| 154 |
+ req.AddRawData(raw) |
|
| 155 |
+ |
|
| 156 |
+ msgs, err := req.Execute(unix.NETLINK_GENERIC, 0) |
|
| 157 |
+ if err != nil {
|
|
| 158 |
+ return nil, err |
|
| 159 |
+ } |
|
| 160 |
+ |
|
| 161 |
+ fous := make([]Fou, 0, len(msgs)) |
|
| 162 |
+ for _, m := range msgs {
|
|
| 163 |
+ f, err := deserializeFouMsg(m) |
|
| 164 |
+ if err != nil {
|
|
| 165 |
+ return fous, err |
|
| 166 |
+ } |
|
| 167 |
+ |
|
| 168 |
+ fous = append(fous, f) |
|
| 169 |
+ } |
|
| 170 |
+ |
|
| 171 |
+ return fous, nil |
|
| 172 |
+} |
|
| 173 |
+ |
|
| 174 |
+func deserializeFouMsg(msg []byte) (Fou, error) {
|
|
| 175 |
+ // we'll skip to byte 4 to first attribute |
|
| 176 |
+ msg = msg[3:] |
|
| 177 |
+ var shift int |
|
| 178 |
+ fou := Fou{}
|
|
| 179 |
+ |
|
| 180 |
+ for {
|
|
| 181 |
+ // attribute header is at least 16 bits |
|
| 182 |
+ if len(msg) < 4 {
|
|
| 183 |
+ return fou, ErrAttrHeaderTruncated |
|
| 184 |
+ } |
|
| 185 |
+ |
|
| 186 |
+ lgt := int(binary.BigEndian.Uint16(msg[0:2])) |
|
| 187 |
+ if len(msg) < lgt+4 {
|
|
| 188 |
+ return fou, ErrAttrBodyTruncated |
|
| 189 |
+ } |
|
| 190 |
+ attr := binary.BigEndian.Uint16(msg[2:4]) |
|
| 191 |
+ |
|
| 192 |
+ shift = lgt + 3 |
|
| 193 |
+ switch attr {
|
|
| 194 |
+ case FOU_ATTR_AF: |
|
| 195 |
+ fou.Family = int(msg[5]) |
|
| 196 |
+ case FOU_ATTR_PORT: |
|
| 197 |
+ fou.Port = int(binary.BigEndian.Uint16(msg[5:7])) |
|
| 198 |
+ // port is 2 bytes |
|
| 199 |
+ shift = lgt + 2 |
|
| 200 |
+ case FOU_ATTR_IPPROTO: |
|
| 201 |
+ fou.Protocol = int(msg[5]) |
|
| 202 |
+ case FOU_ATTR_TYPE: |
|
| 203 |
+ fou.EncapType = int(msg[5]) |
|
| 204 |
+ } |
|
| 205 |
+ |
|
| 206 |
+ msg = msg[shift:] |
|
| 207 |
+ |
|
| 208 |
+ if len(msg) < 4 {
|
|
| 209 |
+ break |
|
| 210 |
+ } |
|
| 211 |
+ } |
|
| 212 |
+ |
|
| 213 |
+ return fou, nil |
|
| 214 |
+} |
| 0 | 215 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,15 @@ |
| 0 |
+// +build !linux |
|
| 1 |
+ |
|
| 2 |
+package netlink |
|
| 3 |
+ |
|
| 4 |
+func FouAdd(f Fou) error {
|
|
| 5 |
+ return ErrNotImplemented |
|
| 6 |
+} |
|
| 7 |
+ |
|
| 8 |
+func FouDel(f Fou) error {
|
|
| 9 |
+ return ErrNotImplemented |
|
| 10 |
+} |
|
| 11 |
+ |
|
| 12 |
+func FouList(fam int) ([]Fou, error) {
|
|
| 13 |
+ return nil, ErrNotImplemented |
|
| 14 |
+} |
| ... | ... |
@@ -5,6 +5,7 @@ import ( |
| 5 | 5 |
"syscall" |
| 6 | 6 |
|
| 7 | 7 |
"github.com/vishvananda/netlink/nl" |
| 8 |
+ "golang.org/x/sys/unix" |
|
| 8 | 9 |
) |
| 9 | 10 |
|
| 10 | 11 |
type GenlOp struct {
|
| ... | ... |
@@ -130,9 +131,9 @@ func (h *Handle) GenlFamilyList() ([]*GenlFamily, error) {
|
| 130 | 130 |
Command: nl.GENL_CTRL_CMD_GETFAMILY, |
| 131 | 131 |
Version: nl.GENL_CTRL_VERSION, |
| 132 | 132 |
} |
| 133 |
- req := h.newNetlinkRequest(nl.GENL_ID_CTRL, syscall.NLM_F_DUMP) |
|
| 133 |
+ req := h.newNetlinkRequest(nl.GENL_ID_CTRL, unix.NLM_F_DUMP) |
|
| 134 | 134 |
req.AddData(msg) |
| 135 |
- msgs, err := req.Execute(syscall.NETLINK_GENERIC, 0) |
|
| 135 |
+ msgs, err := req.Execute(unix.NETLINK_GENERIC, 0) |
|
| 136 | 136 |
if err != nil {
|
| 137 | 137 |
return nil, err |
| 138 | 138 |
} |
| ... | ... |
@@ -151,7 +152,7 @@ func (h *Handle) GenlFamilyGet(name string) (*GenlFamily, error) {
|
| 151 | 151 |
req := h.newNetlinkRequest(nl.GENL_ID_CTRL, 0) |
| 152 | 152 |
req.AddData(msg) |
| 153 | 153 |
req.AddData(nl.NewRtAttr(nl.GENL_CTRL_ATTR_FAMILY_NAME, nl.ZeroTerminated(name))) |
| 154 |
- msgs, err := req.Execute(syscall.NETLINK_GENERIC, 0) |
|
| 154 |
+ msgs, err := req.Execute(unix.NETLINK_GENERIC, 0) |
|
| 155 | 155 |
if err != nil {
|
| 156 | 156 |
return nil, err |
| 157 | 157 |
} |
| ... | ... |
@@ -7,6 +7,7 @@ import ( |
| 7 | 7 |
"syscall" |
| 8 | 8 |
|
| 9 | 9 |
"github.com/vishvananda/netlink/nl" |
| 10 |
+ "golang.org/x/sys/unix" |
|
| 10 | 11 |
) |
| 11 | 12 |
|
| 12 | 13 |
type PDP struct {
|
| ... | ... |
@@ -82,9 +83,9 @@ func (h *Handle) GTPPDPList() ([]*PDP, error) {
|
| 82 | 82 |
Command: nl.GENL_GTP_CMD_GETPDP, |
| 83 | 83 |
Version: nl.GENL_GTP_VERSION, |
| 84 | 84 |
} |
| 85 |
- req := h.newNetlinkRequest(int(f.ID), syscall.NLM_F_DUMP) |
|
| 85 |
+ req := h.newNetlinkRequest(int(f.ID), unix.NLM_F_DUMP) |
|
| 86 | 86 |
req.AddData(msg) |
| 87 |
- msgs, err := req.Execute(syscall.NETLINK_GENERIC, 0) |
|
| 87 |
+ msgs, err := req.Execute(unix.NETLINK_GENERIC, 0) |
|
| 88 | 88 |
if err != nil {
|
| 89 | 89 |
return nil, err |
| 90 | 90 |
} |
| ... | ... |
@@ -96,7 +97,7 @@ func GTPPDPList() ([]*PDP, error) {
|
| 96 | 96 |
} |
| 97 | 97 |
|
| 98 | 98 |
func gtpPDPGet(req *nl.NetlinkRequest) (*PDP, error) {
|
| 99 |
- msgs, err := req.Execute(syscall.NETLINK_GENERIC, 0) |
|
| 99 |
+ msgs, err := req.Execute(unix.NETLINK_GENERIC, 0) |
|
| 100 | 100 |
if err != nil {
|
| 101 | 101 |
return nil, err |
| 102 | 102 |
} |
| ... | ... |
@@ -182,7 +183,7 @@ func (h *Handle) GTPPDPAdd(link Link, pdp *PDP) error {
|
| 182 | 182 |
Command: nl.GENL_GTP_CMD_NEWPDP, |
| 183 | 183 |
Version: nl.GENL_GTP_VERSION, |
| 184 | 184 |
} |
| 185 |
- req := h.newNetlinkRequest(int(f.ID), syscall.NLM_F_EXCL|syscall.NLM_F_ACK) |
|
| 185 |
+ req := h.newNetlinkRequest(int(f.ID), unix.NLM_F_EXCL|unix.NLM_F_ACK) |
|
| 186 | 186 |
req.AddData(msg) |
| 187 | 187 |
req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_VERSION, nl.Uint32Attr(pdp.Version))) |
| 188 | 188 |
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 {
|
| 199 | 199 |
default: |
| 200 | 200 |
return fmt.Errorf("unsupported GTP version: %d", pdp.Version)
|
| 201 | 201 |
} |
| 202 |
- _, err = req.Execute(syscall.NETLINK_GENERIC, 0) |
|
| 202 |
+ _, err = req.Execute(unix.NETLINK_GENERIC, 0) |
|
| 203 | 203 |
return err |
| 204 | 204 |
} |
| 205 | 205 |
|
| ... | ... |
@@ -216,7 +217,7 @@ func (h *Handle) GTPPDPDel(link Link, pdp *PDP) error {
|
| 216 | 216 |
Command: nl.GENL_GTP_CMD_DELPDP, |
| 217 | 217 |
Version: nl.GENL_GTP_VERSION, |
| 218 | 218 |
} |
| 219 |
- req := h.newNetlinkRequest(int(f.ID), syscall.NLM_F_EXCL|syscall.NLM_F_ACK) |
|
| 219 |
+ req := h.newNetlinkRequest(int(f.ID), unix.NLM_F_EXCL|unix.NLM_F_ACK) |
|
| 220 | 220 |
req.AddData(msg) |
| 221 | 221 |
req.AddData(nl.NewRtAttr(nl.GENL_GTP_ATTR_VERSION, nl.Uint32Attr(pdp.Version))) |
| 222 | 222 |
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 {
|
| 229 | 229 |
default: |
| 230 | 230 |
return fmt.Errorf("unsupported GTP version: %d", pdp.Version)
|
| 231 | 231 |
} |
| 232 |
- _, err = req.Execute(syscall.NETLINK_GENERIC, 0) |
|
| 232 |
+ _, err = req.Execute(unix.NETLINK_GENERIC, 0) |
|
| 233 | 233 |
return err |
| 234 | 234 |
} |
| 235 | 235 |
|
| ... | ... |
@@ -2,11 +2,11 @@ package netlink |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"fmt" |
| 5 |
- "syscall" |
|
| 6 | 5 |
"time" |
| 7 | 6 |
|
| 8 | 7 |
"github.com/vishvananda/netlink/nl" |
| 9 | 8 |
"github.com/vishvananda/netns" |
| 9 |
+ "golang.org/x/sys/unix" |
|
| 10 | 10 |
) |
| 11 | 11 |
|
| 12 | 12 |
// Empty handle used by the netlink package methods |
| ... | ... |
@@ -43,7 +43,7 @@ func (h *Handle) SetSocketTimeout(to time.Duration) error {
|
| 43 | 43 |
if to < time.Microsecond {
|
| 44 | 44 |
return fmt.Errorf("invalid timeout, minimul value is %s", time.Microsecond)
|
| 45 | 45 |
} |
| 46 |
- tv := syscall.NsecToTimeval(to.Nanoseconds()) |
|
| 46 |
+ tv := unix.NsecToTimeval(to.Nanoseconds()) |
|
| 47 | 47 |
for _, sh := range h.sockets {
|
| 48 | 48 |
if err := sh.Socket.SetSendTimeout(&tv); err != nil {
|
| 49 | 49 |
return err |
| ... | ... |
@@ -59,13 +59,13 @@ func (h *Handle) SetSocketTimeout(to time.Duration) error {
|
| 59 | 59 |
// socket in the netlink handle. The maximum value is capped by |
| 60 | 60 |
// /proc/sys/net/core/rmem_max. |
| 61 | 61 |
func (h *Handle) SetSocketReceiveBufferSize(size int, force bool) error {
|
| 62 |
- opt := syscall.SO_RCVBUF |
|
| 62 |
+ opt := unix.SO_RCVBUF |
|
| 63 | 63 |
if force {
|
| 64 |
- opt = syscall.SO_RCVBUFFORCE |
|
| 64 |
+ opt = unix.SO_RCVBUFFORCE |
|
| 65 | 65 |
} |
| 66 | 66 |
for _, sh := range h.sockets {
|
| 67 | 67 |
fd := sh.Socket.GetFd() |
| 68 |
- err := syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, opt, size) |
|
| 68 |
+ err := unix.SetsockoptInt(fd, unix.SOL_SOCKET, opt, size) |
|
| 69 | 69 |
if err != nil {
|
| 70 | 70 |
return err |
| 71 | 71 |
} |
| ... | ... |
@@ -81,7 +81,7 @@ func (h *Handle) GetSocketReceiveBufferSize() ([]int, error) {
|
| 81 | 81 |
i := 0 |
| 82 | 82 |
for _, sh := range h.sockets {
|
| 83 | 83 |
fd := sh.Socket.GetFd() |
| 84 |
- size, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_RCVBUF) |
|
| 84 |
+ size, err := unix.GetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_RCVBUF) |
|
| 85 | 85 |
if err != nil {
|
| 86 | 86 |
return nil, err |
| 87 | 87 |
} |
| ... | ... |
@@ -134,10 +134,10 @@ func (h *Handle) newNetlinkRequest(proto, flags int) *nl.NetlinkRequest {
|
| 134 | 134 |
return nl.NewNetlinkRequest(proto, flags) |
| 135 | 135 |
} |
| 136 | 136 |
return &nl.NetlinkRequest{
|
| 137 |
- NlMsghdr: syscall.NlMsghdr{
|
|
| 138 |
- Len: uint32(syscall.SizeofNlMsghdr), |
|
| 137 |
+ NlMsghdr: unix.NlMsghdr{
|
|
| 138 |
+ Len: uint32(unix.SizeofNlMsghdr), |
|
| 139 | 139 |
Type: uint16(proto), |
| 140 |
- Flags: syscall.NLM_F_REQUEST | uint16(flags), |
|
| 140 |
+ Flags: unix.NLM_F_REQUEST | uint16(flags), |
|
| 141 | 141 |
}, |
| 142 | 142 |
Sockets: h.sockets, |
| 143 | 143 |
} |
| ... | ... |
@@ -220,3 +220,39 @@ func (h *Handle) NeighList(linkIndex, family int) ([]Neigh, error) {
|
| 220 | 220 |
func (h *Handle) NeighProxyList(linkIndex, family int) ([]Neigh, error) {
|
| 221 | 221 |
return nil, ErrNotImplemented |
| 222 | 222 |
} |
| 223 |
+ |
|
| 224 |
+func (h *Handle) RouteAdd(route *Route) error {
|
|
| 225 |
+ return ErrNotImplemented |
|
| 226 |
+} |
|
| 227 |
+ |
|
| 228 |
+func (h *Handle) RouteDel(route *Route) error {
|
|
| 229 |
+ return ErrNotImplemented |
|
| 230 |
+} |
|
| 231 |
+ |
|
| 232 |
+func (h *Handle) RouteGet(destination net.IP) ([]Route, error) {
|
|
| 233 |
+ return nil, ErrNotImplemented |
|
| 234 |
+} |
|
| 235 |
+ |
|
| 236 |
+func (h *Handle) RouteList(link Link, family int) ([]Route, error) {
|
|
| 237 |
+ return nil, ErrNotImplemented |
|
| 238 |
+} |
|
| 239 |
+ |
|
| 240 |
+func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64) ([]Route, error) {
|
|
| 241 |
+ return nil, ErrNotImplemented |
|
| 242 |
+} |
|
| 243 |
+ |
|
| 244 |
+func (h *Handle) RouteReplace(route *Route) error {
|
|
| 245 |
+ return ErrNotImplemented |
|
| 246 |
+} |
|
| 247 |
+ |
|
| 248 |
+func (h *Handle) RuleAdd(rule *Rule) error {
|
|
| 249 |
+ return ErrNotImplemented |
|
| 250 |
+} |
|
| 251 |
+ |
|
| 252 |
+func (h *Handle) RuleDel(rule *Rule) error {
|
|
| 253 |
+ return ErrNotImplemented |
|
| 254 |
+} |
|
| 255 |
+ |
|
| 256 |
+func (h *Handle) RuleList(family int) ([]Rule, error) {
|
|
| 257 |
+ return nil, ErrNotImplemented |
|
| 258 |
+} |
| 223 | 259 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,98 @@ |
| 0 |
+package netlink |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "syscall" |
|
| 4 |
+ "unsafe" |
|
| 5 |
+ |
|
| 6 |
+ "golang.org/x/sys/unix" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+// ioctl for statistics. |
|
| 10 |
+const ( |
|
| 11 |
+ // ETHTOOL_GSSET_INFO gets string set info |
|
| 12 |
+ ETHTOOL_GSSET_INFO = 0x00000037 |
|
| 13 |
+ // SIOCETHTOOL is Ethtool interface |
|
| 14 |
+ SIOCETHTOOL = 0x8946 |
|
| 15 |
+ // ETHTOOL_GSTRINGS gets specified string set |
|
| 16 |
+ ETHTOOL_GSTRINGS = 0x0000001b |
|
| 17 |
+ // ETHTOOL_GSTATS gets NIC-specific statistics |
|
| 18 |
+ ETHTOOL_GSTATS = 0x0000001d |
|
| 19 |
+) |
|
| 20 |
+ |
|
| 21 |
+// string set id. |
|
| 22 |
+const ( |
|
| 23 |
+ // ETH_SS_TEST is self-test result names, for use with %ETHTOOL_TEST |
|
| 24 |
+ ETH_SS_TEST = iota |
|
| 25 |
+ // ETH_SS_STATS statistic names, for use with %ETHTOOL_GSTATS |
|
| 26 |
+ ETH_SS_STATS |
|
| 27 |
+ // ETH_SS_PRIV_FLAGS are driver private flag names |
|
| 28 |
+ ETH_SS_PRIV_FLAGS |
|
| 29 |
+ // _ETH_SS_NTUPLE_FILTERS is deprecated |
|
| 30 |
+ _ETH_SS_NTUPLE_FILTERS |
|
| 31 |
+ // ETH_SS_FEATURES are device feature names |
|
| 32 |
+ ETH_SS_FEATURES |
|
| 33 |
+ // ETH_SS_RSS_HASH_FUNCS is RSS hush function names |
|
| 34 |
+ ETH_SS_RSS_HASH_FUNCS |
|
| 35 |
+) |
|
| 36 |
+ |
|
| 37 |
+// IfreqSlave is a struct for ioctl bond manipulation syscalls. |
|
| 38 |
+// It is used to assign slave to bond interface with Name. |
|
| 39 |
+type IfreqSlave struct {
|
|
| 40 |
+ Name [unix.IFNAMSIZ]byte |
|
| 41 |
+ Slave [unix.IFNAMSIZ]byte |
|
| 42 |
+} |
|
| 43 |
+ |
|
| 44 |
+// Ifreq is a struct for ioctl ethernet manipulation syscalls. |
|
| 45 |
+type Ifreq struct {
|
|
| 46 |
+ Name [unix.IFNAMSIZ]byte |
|
| 47 |
+ Data uintptr |
|
| 48 |
+} |
|
| 49 |
+ |
|
| 50 |
+// ethtoolSset is a string set information |
|
| 51 |
+type ethtoolSset struct {
|
|
| 52 |
+ cmd uint32 |
|
| 53 |
+ reserved uint32 |
|
| 54 |
+ mask uint64 |
|
| 55 |
+ data [1]uint32 |
|
| 56 |
+} |
|
| 57 |
+ |
|
| 58 |
+// ethtoolGstrings is string set for data tagging |
|
| 59 |
+type ethtoolGstrings struct {
|
|
| 60 |
+ cmd uint32 |
|
| 61 |
+ stringSet uint32 |
|
| 62 |
+ length uint32 |
|
| 63 |
+ data [32]byte |
|
| 64 |
+} |
|
| 65 |
+ |
|
| 66 |
+type ethtoolStats struct {
|
|
| 67 |
+ cmd uint32 |
|
| 68 |
+ nStats uint32 |
|
| 69 |
+ data [1]uint64 |
|
| 70 |
+} |
|
| 71 |
+ |
|
| 72 |
+// newIocltSlaveReq returns filled IfreqSlave with proper interface names |
|
| 73 |
+// It is used by ioctl to assign slave to bond master |
|
| 74 |
+func newIocltSlaveReq(slave, master string) *IfreqSlave {
|
|
| 75 |
+ ifreq := &IfreqSlave{}
|
|
| 76 |
+ copy(ifreq.Name[:unix.IFNAMSIZ-1], master) |
|
| 77 |
+ copy(ifreq.Slave[:unix.IFNAMSIZ-1], slave) |
|
| 78 |
+ return ifreq |
|
| 79 |
+} |
|
| 80 |
+ |
|
| 81 |
+// newIocltStringSetReq creates request to get interface string set |
|
| 82 |
+func newIocltStringSetReq(linkName string) (*Ifreq, *ethtoolSset) {
|
|
| 83 |
+ e := ðtoolSset{
|
|
| 84 |
+ cmd: ETHTOOL_GSSET_INFO, |
|
| 85 |
+ mask: 1 << ETH_SS_STATS, |
|
| 86 |
+ } |
|
| 87 |
+ |
|
| 88 |
+ ifreq := &Ifreq{Data: uintptr(unsafe.Pointer(e))}
|
|
| 89 |
+ copy(ifreq.Name[:unix.IFNAMSIZ-1], linkName) |
|
| 90 |
+ return ifreq, e |
|
| 91 |
+} |
|
| 92 |
+ |
|
| 93 |
+// getSocketUDP returns file descriptor to new UDP socket |
|
| 94 |
+// It is used for communication with ioctl interface. |
|
| 95 |
+func getSocketUDP() (int, error) {
|
|
| 96 |
+ return syscall.Socket(unix.AF_INET, unix.SOCK_DGRAM, 0) |
|
| 97 |
+} |
| ... | ... |
@@ -3,6 +3,7 @@ package netlink |
| 3 | 3 |
import ( |
| 4 | 4 |
"fmt" |
| 5 | 5 |
"net" |
| 6 |
+ "os" |
|
| 6 | 7 |
) |
| 7 | 8 |
|
| 8 | 9 |
// Link represents a link device from netlink. Shared link attributes |
| ... | ... |
@@ -38,6 +39,8 @@ type LinkAttrs struct {
|
| 38 | 38 |
Protinfo *Protinfo |
| 39 | 39 |
OperState LinkOperState |
| 40 | 40 |
NetNsID int |
| 41 |
+ NumTxQueues int |
|
| 42 |
+ NumRxQueues int |
|
| 41 | 43 |
} |
| 42 | 44 |
|
| 43 | 45 |
// LinkOperState represents the values of the IFLA_OPERSTATE link |
| ... | ... |
@@ -259,6 +262,9 @@ const ( |
| 259 | 259 |
type Macvlan struct {
|
| 260 | 260 |
LinkAttrs |
| 261 | 261 |
Mode MacvlanMode |
| 262 |
+ |
|
| 263 |
+ // MACAddrs is only populated for Macvlan SOURCE links |
|
| 264 |
+ MACAddrs []net.HardwareAddr |
|
| 262 | 265 |
} |
| 263 | 266 |
|
| 264 | 267 |
func (macvlan *Macvlan) Attrs() *LinkAttrs {
|
| ... | ... |
@@ -284,8 +290,10 @@ type TuntapFlag uint16 |
| 284 | 284 |
// Tuntap links created via /dev/tun/tap, but can be destroyed via netlink |
| 285 | 285 |
type Tuntap struct {
|
| 286 | 286 |
LinkAttrs |
| 287 |
- Mode TuntapMode |
|
| 288 |
- Flags TuntapFlag |
|
| 287 |
+ Mode TuntapMode |
|
| 288 |
+ Flags TuntapFlag |
|
| 289 |
+ Queues int |
|
| 290 |
+ Fds []*os.File |
|
| 289 | 291 |
} |
| 290 | 292 |
|
| 291 | 293 |
func (tuntap *Tuntap) Attrs() *LinkAttrs {
|
| ... | ... |
@@ -327,26 +335,28 @@ func (generic *GenericLink) Type() string {
|
| 327 | 327 |
|
| 328 | 328 |
type Vxlan struct {
|
| 329 | 329 |
LinkAttrs |
| 330 |
- VxlanId int |
|
| 331 |
- VtepDevIndex int |
|
| 332 |
- SrcAddr net.IP |
|
| 333 |
- Group net.IP |
|
| 334 |
- TTL int |
|
| 335 |
- TOS int |
|
| 336 |
- Learning bool |
|
| 337 |
- Proxy bool |
|
| 338 |
- RSC bool |
|
| 339 |
- L2miss bool |
|
| 340 |
- L3miss bool |
|
| 341 |
- UDPCSum bool |
|
| 342 |
- NoAge bool |
|
| 343 |
- GBP bool |
|
| 344 |
- FlowBased bool |
|
| 345 |
- Age int |
|
| 346 |
- Limit int |
|
| 347 |
- Port int |
|
| 348 |
- PortLow int |
|
| 349 |
- PortHigh int |
|
| 330 |
+ VxlanId int |
|
| 331 |
+ VtepDevIndex int |
|
| 332 |
+ SrcAddr net.IP |
|
| 333 |
+ Group net.IP |
|
| 334 |
+ TTL int |
|
| 335 |
+ TOS int |
|
| 336 |
+ Learning bool |
|
| 337 |
+ Proxy bool |
|
| 338 |
+ RSC bool |
|
| 339 |
+ L2miss bool |
|
| 340 |
+ L3miss bool |
|
| 341 |
+ UDPCSum bool |
|
| 342 |
+ UDP6ZeroCSumTx bool |
|
| 343 |
+ UDP6ZeroCSumRx bool |
|
| 344 |
+ NoAge bool |
|
| 345 |
+ GBP bool |
|
| 346 |
+ FlowBased bool |
|
| 347 |
+ Age int |
|
| 348 |
+ Limit int |
|
| 349 |
+ Port int |
|
| 350 |
+ PortLow int |
|
| 351 |
+ PortHigh int |
|
| 350 | 352 |
} |
| 351 | 353 |
|
| 352 | 354 |
func (vxlan *Vxlan) Attrs() *LinkAttrs {
|
| ... | ... |
@@ -695,17 +705,25 @@ func (gretap *Gretap) Attrs() *LinkAttrs {
|
| 695 | 695 |
} |
| 696 | 696 |
|
| 697 | 697 |
func (gretap *Gretap) Type() string {
|
| 698 |
+ if gretap.Local.To4() == nil {
|
|
| 699 |
+ return "ip6gretap" |
|
| 700 |
+ } |
|
| 698 | 701 |
return "gretap" |
| 699 | 702 |
} |
| 700 | 703 |
|
| 701 | 704 |
type Iptun struct {
|
| 702 | 705 |
LinkAttrs |
| 703 |
- Ttl uint8 |
|
| 704 |
- Tos uint8 |
|
| 705 |
- PMtuDisc uint8 |
|
| 706 |
- Link uint32 |
|
| 707 |
- Local net.IP |
|
| 708 |
- Remote net.IP |
|
| 706 |
+ Ttl uint8 |
|
| 707 |
+ Tos uint8 |
|
| 708 |
+ PMtuDisc uint8 |
|
| 709 |
+ Link uint32 |
|
| 710 |
+ Local net.IP |
|
| 711 |
+ Remote net.IP |
|
| 712 |
+ EncapSport uint16 |
|
| 713 |
+ EncapDport uint16 |
|
| 714 |
+ EncapType uint16 |
|
| 715 |
+ EncapFlags uint16 |
|
| 716 |
+ FlowBased bool |
|
| 709 | 717 |
} |
| 710 | 718 |
|
| 711 | 719 |
func (iptun *Iptun) Attrs() *LinkAttrs {
|
| ... | ... |
@@ -716,6 +734,28 @@ func (iptun *Iptun) Type() string {
|
| 716 | 716 |
return "ipip" |
| 717 | 717 |
} |
| 718 | 718 |
|
| 719 |
+type Sittun struct {
|
|
| 720 |
+ LinkAttrs |
|
| 721 |
+ Link uint32 |
|
| 722 |
+ Local net.IP |
|
| 723 |
+ Remote net.IP |
|
| 724 |
+ Ttl uint8 |
|
| 725 |
+ Tos uint8 |
|
| 726 |
+ PMtuDisc uint8 |
|
| 727 |
+ EncapType uint16 |
|
| 728 |
+ EncapFlags uint16 |
|
| 729 |
+ EncapSport uint16 |
|
| 730 |
+ EncapDport uint16 |
|
| 731 |
+} |
|
| 732 |
+ |
|
| 733 |
+func (sittun *Sittun) Attrs() *LinkAttrs {
|
|
| 734 |
+ return &sittun.LinkAttrs |
|
| 735 |
+} |
|
| 736 |
+ |
|
| 737 |
+func (sittun *Sittun) Type() string {
|
|
| 738 |
+ return "sit" |
|
| 739 |
+} |
|
| 740 |
+ |
|
| 719 | 741 |
type Vti struct {
|
| 720 | 742 |
LinkAttrs |
| 721 | 743 |
IKey uint32 |
| ... | ... |
@@ -735,16 +775,20 @@ func (iptun *Vti) Type() string {
|
| 735 | 735 |
|
| 736 | 736 |
type Gretun struct {
|
| 737 | 737 |
LinkAttrs |
| 738 |
- Link uint32 |
|
| 739 |
- IFlags uint16 |
|
| 740 |
- OFlags uint16 |
|
| 741 |
- IKey uint32 |
|
| 742 |
- OKey uint32 |
|
| 743 |
- Local net.IP |
|
| 744 |
- Remote net.IP |
|
| 745 |
- Ttl uint8 |
|
| 746 |
- Tos uint8 |
|
| 747 |
- PMtuDisc uint8 |
|
| 738 |
+ Link uint32 |
|
| 739 |
+ IFlags uint16 |
|
| 740 |
+ OFlags uint16 |
|
| 741 |
+ IKey uint32 |
|
| 742 |
+ OKey uint32 |
|
| 743 |
+ Local net.IP |
|
| 744 |
+ Remote net.IP |
|
| 745 |
+ Ttl uint8 |
|
| 746 |
+ Tos uint8 |
|
| 747 |
+ PMtuDisc uint8 |
|
| 748 |
+ EncapType uint16 |
|
| 749 |
+ EncapFlags uint16 |
|
| 750 |
+ EncapSport uint16 |
|
| 751 |
+ EncapDport uint16 |
|
| 748 | 752 |
} |
| 749 | 753 |
|
| 750 | 754 |
func (gretun *Gretun) Attrs() *LinkAttrs {
|
| ... | ... |
@@ -752,6 +796,9 @@ func (gretun *Gretun) Attrs() *LinkAttrs {
|
| 752 | 752 |
} |
| 753 | 753 |
|
| 754 | 754 |
func (gretun *Gretun) Type() string {
|
| 755 |
+ if gretun.Local.To4() == nil {
|
|
| 756 |
+ return "ip6gre" |
|
| 757 |
+ } |
|
| 755 | 758 |
return "gre" |
| 756 | 759 |
} |
| 757 | 760 |
|
| ... | ... |
@@ -11,22 +11,24 @@ import ( |
| 11 | 11 |
|
| 12 | 12 |
"github.com/vishvananda/netlink/nl" |
| 13 | 13 |
"github.com/vishvananda/netns" |
| 14 |
+ "golang.org/x/sys/unix" |
|
| 14 | 15 |
) |
| 15 | 16 |
|
| 16 | 17 |
const ( |
| 17 | 18 |
SizeofLinkStats32 = 0x5c |
| 18 | 19 |
SizeofLinkStats64 = 0xd8 |
| 19 |
- IFLA_STATS64 = 0x17 // syscall pkg does not contain this one |
|
| 20 | 20 |
) |
| 21 | 21 |
|
| 22 | 22 |
const ( |
| 23 |
- TUNTAP_MODE_TUN TuntapMode = syscall.IFF_TUN |
|
| 24 |
- TUNTAP_MODE_TAP TuntapMode = syscall.IFF_TAP |
|
| 25 |
- TUNTAP_DEFAULTS TuntapFlag = syscall.IFF_TUN_EXCL | syscall.IFF_ONE_QUEUE |
|
| 26 |
- TUNTAP_VNET_HDR TuntapFlag = syscall.IFF_VNET_HDR |
|
| 27 |
- TUNTAP_TUN_EXCL TuntapFlag = syscall.IFF_TUN_EXCL |
|
| 28 |
- TUNTAP_NO_PI TuntapFlag = syscall.IFF_NO_PI |
|
| 29 |
- TUNTAP_ONE_QUEUE TuntapFlag = syscall.IFF_ONE_QUEUE |
|
| 23 |
+ TUNTAP_MODE_TUN TuntapMode = unix.IFF_TUN |
|
| 24 |
+ TUNTAP_MODE_TAP TuntapMode = unix.IFF_TAP |
|
| 25 |
+ TUNTAP_DEFAULTS TuntapFlag = unix.IFF_TUN_EXCL | unix.IFF_ONE_QUEUE |
|
| 26 |
+ TUNTAP_VNET_HDR TuntapFlag = unix.IFF_VNET_HDR |
|
| 27 |
+ TUNTAP_TUN_EXCL TuntapFlag = unix.IFF_TUN_EXCL |
|
| 28 |
+ TUNTAP_NO_PI TuntapFlag = unix.IFF_NO_PI |
|
| 29 |
+ TUNTAP_ONE_QUEUE TuntapFlag = unix.IFF_ONE_QUEUE |
|
| 30 |
+ TUNTAP_MULTI_QUEUE TuntapFlag = unix.IFF_MULTI_QUEUE |
|
| 31 |
+ TUNTAP_MULTI_QUEUE_DEFAULTS TuntapFlag = TUNTAP_MULTI_QUEUE | TUNTAP_NO_PI |
|
| 30 | 32 |
) |
| 31 | 33 |
|
| 32 | 34 |
var lookupByDump = false |
| ... | ... |
@@ -61,15 +63,15 @@ func (h *Handle) ensureIndex(link *LinkAttrs) {
|
| 61 | 61 |
func (h *Handle) LinkSetARPOff(link Link) error {
|
| 62 | 62 |
base := link.Attrs() |
| 63 | 63 |
h.ensureIndex(base) |
| 64 |
- req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) |
|
| 64 |
+ req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) |
|
| 65 | 65 |
|
| 66 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 67 |
- msg.Change |= syscall.IFF_NOARP |
|
| 68 |
- msg.Flags |= syscall.IFF_NOARP |
|
| 66 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 67 |
+ msg.Change |= unix.IFF_NOARP |
|
| 68 |
+ msg.Flags |= unix.IFF_NOARP |
|
| 69 | 69 |
msg.Index = int32(base.Index) |
| 70 | 70 |
req.AddData(msg) |
| 71 | 71 |
|
| 72 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 72 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 73 | 73 |
return err |
| 74 | 74 |
} |
| 75 | 75 |
|
| ... | ... |
@@ -80,15 +82,15 @@ func LinkSetARPOff(link Link) error {
|
| 80 | 80 |
func (h *Handle) LinkSetARPOn(link Link) error {
|
| 81 | 81 |
base := link.Attrs() |
| 82 | 82 |
h.ensureIndex(base) |
| 83 |
- req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) |
|
| 83 |
+ req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) |
|
| 84 | 84 |
|
| 85 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 86 |
- msg.Change |= syscall.IFF_NOARP |
|
| 87 |
- msg.Flags &= ^uint32(syscall.IFF_NOARP) |
|
| 85 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 86 |
+ msg.Change |= unix.IFF_NOARP |
|
| 87 |
+ msg.Flags &= ^uint32(unix.IFF_NOARP) |
|
| 88 | 88 |
msg.Index = int32(base.Index) |
| 89 | 89 |
req.AddData(msg) |
| 90 | 90 |
|
| 91 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 91 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 92 | 92 |
return err |
| 93 | 93 |
} |
| 94 | 94 |
|
| ... | ... |
@@ -99,15 +101,84 @@ func LinkSetARPOn(link Link) error {
|
| 99 | 99 |
func (h *Handle) SetPromiscOn(link Link) error {
|
| 100 | 100 |
base := link.Attrs() |
| 101 | 101 |
h.ensureIndex(base) |
| 102 |
- req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) |
|
| 102 |
+ req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) |
|
| 103 | 103 |
|
| 104 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 105 |
- msg.Change = syscall.IFF_PROMISC |
|
| 106 |
- msg.Flags = syscall.IFF_PROMISC |
|
| 104 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 105 |
+ msg.Change = unix.IFF_PROMISC |
|
| 106 |
+ msg.Flags = unix.IFF_PROMISC |
|
| 107 | 107 |
msg.Index = int32(base.Index) |
| 108 | 108 |
req.AddData(msg) |
| 109 | 109 |
|
| 110 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 110 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 111 |
+ return err |
|
| 112 |
+} |
|
| 113 |
+ |
|
| 114 |
+func MacvlanMACAddrAdd(link Link, addr net.HardwareAddr) error {
|
|
| 115 |
+ return pkgHandle.MacvlanMACAddrAdd(link, addr) |
|
| 116 |
+} |
|
| 117 |
+ |
|
| 118 |
+func (h *Handle) MacvlanMACAddrAdd(link Link, addr net.HardwareAddr) error {
|
|
| 119 |
+ return h.macvlanMACAddrChange(link, []net.HardwareAddr{addr}, nl.MACVLAN_MACADDR_ADD)
|
|
| 120 |
+} |
|
| 121 |
+ |
|
| 122 |
+func MacvlanMACAddrDel(link Link, addr net.HardwareAddr) error {
|
|
| 123 |
+ return pkgHandle.MacvlanMACAddrDel(link, addr) |
|
| 124 |
+} |
|
| 125 |
+ |
|
| 126 |
+func (h *Handle) MacvlanMACAddrDel(link Link, addr net.HardwareAddr) error {
|
|
| 127 |
+ return h.macvlanMACAddrChange(link, []net.HardwareAddr{addr}, nl.MACVLAN_MACADDR_DEL)
|
|
| 128 |
+} |
|
| 129 |
+ |
|
| 130 |
+func MacvlanMACAddrFlush(link Link) error {
|
|
| 131 |
+ return pkgHandle.MacvlanMACAddrFlush(link) |
|
| 132 |
+} |
|
| 133 |
+ |
|
| 134 |
+func (h *Handle) MacvlanMACAddrFlush(link Link) error {
|
|
| 135 |
+ return h.macvlanMACAddrChange(link, nil, nl.MACVLAN_MACADDR_FLUSH) |
|
| 136 |
+} |
|
| 137 |
+ |
|
| 138 |
+func MacvlanMACAddrSet(link Link, addrs []net.HardwareAddr) error {
|
|
| 139 |
+ return pkgHandle.MacvlanMACAddrSet(link, addrs) |
|
| 140 |
+} |
|
| 141 |
+ |
|
| 142 |
+func (h *Handle) MacvlanMACAddrSet(link Link, addrs []net.HardwareAddr) error {
|
|
| 143 |
+ return h.macvlanMACAddrChange(link, addrs, nl.MACVLAN_MACADDR_SET) |
|
| 144 |
+} |
|
| 145 |
+ |
|
| 146 |
+func (h *Handle) macvlanMACAddrChange(link Link, addrs []net.HardwareAddr, mode uint32) error {
|
|
| 147 |
+ base := link.Attrs() |
|
| 148 |
+ h.ensureIndex(base) |
|
| 149 |
+ req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK) |
|
| 150 |
+ |
|
| 151 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 152 |
+ msg.Index = int32(base.Index) |
|
| 153 |
+ req.AddData(msg) |
|
| 154 |
+ |
|
| 155 |
+ linkInfo := nl.NewRtAttr(unix.IFLA_LINKINFO, nil) |
|
| 156 |
+ nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_KIND, nl.NonZeroTerminated(link.Type())) |
|
| 157 |
+ inner := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) |
|
| 158 |
+ |
|
| 159 |
+ // IFLA_MACVLAN_MACADDR_MODE = mode |
|
| 160 |
+ b := make([]byte, 4) |
|
| 161 |
+ native.PutUint32(b, mode) |
|
| 162 |
+ nl.NewRtAttrChild(inner, nl.IFLA_MACVLAN_MACADDR_MODE, b) |
|
| 163 |
+ |
|
| 164 |
+ // populate message with MAC addrs, if necessary |
|
| 165 |
+ switch mode {
|
|
| 166 |
+ case nl.MACVLAN_MACADDR_ADD, nl.MACVLAN_MACADDR_DEL: |
|
| 167 |
+ if len(addrs) == 1 {
|
|
| 168 |
+ nl.NewRtAttrChild(inner, nl.IFLA_MACVLAN_MACADDR, []byte(addrs[0])) |
|
| 169 |
+ } |
|
| 170 |
+ case nl.MACVLAN_MACADDR_SET: |
|
| 171 |
+ mad := nl.NewRtAttrChild(inner, nl.IFLA_MACVLAN_MACADDR_DATA, nil) |
|
| 172 |
+ for _, addr := range addrs {
|
|
| 173 |
+ nl.NewRtAttrChild(mad, nl.IFLA_MACVLAN_MACADDR, []byte(addr)) |
|
| 174 |
+ } |
|
| 175 |
+ } |
|
| 176 |
+ |
|
| 177 |
+ req.AddData(linkInfo) |
|
| 178 |
+ |
|
| 179 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 111 | 180 |
return err |
| 112 | 181 |
} |
| 113 | 182 |
|
| ... | ... |
@@ -118,7 +189,7 @@ func BridgeSetMcastSnoop(link Link, on bool) error {
|
| 118 | 118 |
func (h *Handle) BridgeSetMcastSnoop(link Link, on bool) error {
|
| 119 | 119 |
bridge := link.(*Bridge) |
| 120 | 120 |
bridge.MulticastSnooping = &on |
| 121 |
- return h.linkModify(bridge, syscall.NLM_F_ACK) |
|
| 121 |
+ return h.linkModify(bridge, unix.NLM_F_ACK) |
|
| 122 | 122 |
} |
| 123 | 123 |
|
| 124 | 124 |
func SetPromiscOn(link Link) error {
|
| ... | ... |
@@ -128,15 +199,15 @@ func SetPromiscOn(link Link) error {
|
| 128 | 128 |
func (h *Handle) SetPromiscOff(link Link) error {
|
| 129 | 129 |
base := link.Attrs() |
| 130 | 130 |
h.ensureIndex(base) |
| 131 |
- req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) |
|
| 131 |
+ req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) |
|
| 132 | 132 |
|
| 133 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 134 |
- msg.Change = syscall.IFF_PROMISC |
|
| 135 |
- msg.Flags = 0 & ^syscall.IFF_PROMISC |
|
| 133 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 134 |
+ msg.Change = unix.IFF_PROMISC |
|
| 135 |
+ msg.Flags = 0 & ^unix.IFF_PROMISC |
|
| 136 | 136 |
msg.Index = int32(base.Index) |
| 137 | 137 |
req.AddData(msg) |
| 138 | 138 |
|
| 139 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 139 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 140 | 140 |
return err |
| 141 | 141 |
} |
| 142 | 142 |
|
| ... | ... |
@@ -155,15 +226,15 @@ func LinkSetUp(link Link) error {
|
| 155 | 155 |
func (h *Handle) LinkSetUp(link Link) error {
|
| 156 | 156 |
base := link.Attrs() |
| 157 | 157 |
h.ensureIndex(base) |
| 158 |
- req := h.newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_ACK) |
|
| 158 |
+ req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK) |
|
| 159 | 159 |
|
| 160 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 161 |
- msg.Change = syscall.IFF_UP |
|
| 162 |
- msg.Flags = syscall.IFF_UP |
|
| 160 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 161 |
+ msg.Change = unix.IFF_UP |
|
| 162 |
+ msg.Flags = unix.IFF_UP |
|
| 163 | 163 |
msg.Index = int32(base.Index) |
| 164 | 164 |
req.AddData(msg) |
| 165 | 165 |
|
| 166 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 166 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 167 | 167 |
return err |
| 168 | 168 |
} |
| 169 | 169 |
|
| ... | ... |
@@ -178,15 +249,15 @@ func LinkSetDown(link Link) error {
|
| 178 | 178 |
func (h *Handle) LinkSetDown(link Link) error {
|
| 179 | 179 |
base := link.Attrs() |
| 180 | 180 |
h.ensureIndex(base) |
| 181 |
- req := h.newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_ACK) |
|
| 181 |
+ req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK) |
|
| 182 | 182 |
|
| 183 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 184 |
- msg.Change = syscall.IFF_UP |
|
| 185 |
- msg.Flags = 0 & ^syscall.IFF_UP |
|
| 183 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 184 |
+ msg.Change = unix.IFF_UP |
|
| 185 |
+ msg.Flags = 0 & ^unix.IFF_UP |
|
| 186 | 186 |
msg.Index = int32(base.Index) |
| 187 | 187 |
req.AddData(msg) |
| 188 | 188 |
|
| 189 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 189 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 190 | 190 |
return err |
| 191 | 191 |
} |
| 192 | 192 |
|
| ... | ... |
@@ -201,19 +272,19 @@ func LinkSetMTU(link Link, mtu int) error {
|
| 201 | 201 |
func (h *Handle) LinkSetMTU(link Link, mtu int) error {
|
| 202 | 202 |
base := link.Attrs() |
| 203 | 203 |
h.ensureIndex(base) |
| 204 |
- req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) |
|
| 204 |
+ req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) |
|
| 205 | 205 |
|
| 206 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 206 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 207 | 207 |
msg.Index = int32(base.Index) |
| 208 | 208 |
req.AddData(msg) |
| 209 | 209 |
|
| 210 | 210 |
b := make([]byte, 4) |
| 211 | 211 |
native.PutUint32(b, uint32(mtu)) |
| 212 | 212 |
|
| 213 |
- data := nl.NewRtAttr(syscall.IFLA_MTU, b) |
|
| 213 |
+ data := nl.NewRtAttr(unix.IFLA_MTU, b) |
|
| 214 | 214 |
req.AddData(data) |
| 215 | 215 |
|
| 216 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 216 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 217 | 217 |
return err |
| 218 | 218 |
} |
| 219 | 219 |
|
| ... | ... |
@@ -228,16 +299,16 @@ func LinkSetName(link Link, name string) error {
|
| 228 | 228 |
func (h *Handle) LinkSetName(link Link, name string) error {
|
| 229 | 229 |
base := link.Attrs() |
| 230 | 230 |
h.ensureIndex(base) |
| 231 |
- req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) |
|
| 231 |
+ req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) |
|
| 232 | 232 |
|
| 233 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 233 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 234 | 234 |
msg.Index = int32(base.Index) |
| 235 | 235 |
req.AddData(msg) |
| 236 | 236 |
|
| 237 |
- data := nl.NewRtAttr(syscall.IFLA_IFNAME, []byte(name)) |
|
| 237 |
+ data := nl.NewRtAttr(unix.IFLA_IFNAME, []byte(name)) |
|
| 238 | 238 |
req.AddData(data) |
| 239 | 239 |
|
| 240 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 240 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 241 | 241 |
return err |
| 242 | 242 |
} |
| 243 | 243 |
|
| ... | ... |
@@ -252,16 +323,16 @@ func LinkSetAlias(link Link, name string) error {
|
| 252 | 252 |
func (h *Handle) LinkSetAlias(link Link, name string) error {
|
| 253 | 253 |
base := link.Attrs() |
| 254 | 254 |
h.ensureIndex(base) |
| 255 |
- req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) |
|
| 255 |
+ req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) |
|
| 256 | 256 |
|
| 257 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 257 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 258 | 258 |
msg.Index = int32(base.Index) |
| 259 | 259 |
req.AddData(msg) |
| 260 | 260 |
|
| 261 |
- data := nl.NewRtAttr(syscall.IFLA_IFALIAS, []byte(name)) |
|
| 261 |
+ data := nl.NewRtAttr(unix.IFLA_IFALIAS, []byte(name)) |
|
| 262 | 262 |
req.AddData(data) |
| 263 | 263 |
|
| 264 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 264 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 265 | 265 |
return err |
| 266 | 266 |
} |
| 267 | 267 |
|
| ... | ... |
@@ -276,16 +347,16 @@ func LinkSetHardwareAddr(link Link, hwaddr net.HardwareAddr) error {
|
| 276 | 276 |
func (h *Handle) LinkSetHardwareAddr(link Link, hwaddr net.HardwareAddr) error {
|
| 277 | 277 |
base := link.Attrs() |
| 278 | 278 |
h.ensureIndex(base) |
| 279 |
- req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) |
|
| 279 |
+ req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) |
|
| 280 | 280 |
|
| 281 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 281 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 282 | 282 |
msg.Index = int32(base.Index) |
| 283 | 283 |
req.AddData(msg) |
| 284 | 284 |
|
| 285 |
- data := nl.NewRtAttr(syscall.IFLA_ADDRESS, []byte(hwaddr)) |
|
| 285 |
+ data := nl.NewRtAttr(unix.IFLA_ADDRESS, []byte(hwaddr)) |
|
| 286 | 286 |
req.AddData(data) |
| 287 | 287 |
|
| 288 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 288 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 289 | 289 |
return err |
| 290 | 290 |
} |
| 291 | 291 |
|
| ... | ... |
@@ -300,13 +371,13 @@ func LinkSetVfHardwareAddr(link Link, vf int, hwaddr net.HardwareAddr) error {
|
| 300 | 300 |
func (h *Handle) LinkSetVfHardwareAddr(link Link, vf int, hwaddr net.HardwareAddr) error {
|
| 301 | 301 |
base := link.Attrs() |
| 302 | 302 |
h.ensureIndex(base) |
| 303 |
- req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) |
|
| 303 |
+ req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) |
|
| 304 | 304 |
|
| 305 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 305 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 306 | 306 |
msg.Index = int32(base.Index) |
| 307 | 307 |
req.AddData(msg) |
| 308 | 308 |
|
| 309 |
- data := nl.NewRtAttr(nl.IFLA_VFINFO_LIST, nil) |
|
| 309 |
+ data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil) |
|
| 310 | 310 |
info := nl.NewRtAttrChild(data, nl.IFLA_VF_INFO, nil) |
| 311 | 311 |
vfmsg := nl.VfMac{
|
| 312 | 312 |
Vf: uint32(vf), |
| ... | ... |
@@ -315,7 +386,7 @@ func (h *Handle) LinkSetVfHardwareAddr(link Link, vf int, hwaddr net.HardwareAdd |
| 315 | 315 |
nl.NewRtAttrChild(info, nl.IFLA_VF_MAC, vfmsg.Serialize()) |
| 316 | 316 |
req.AddData(data) |
| 317 | 317 |
|
| 318 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 318 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 319 | 319 |
return err |
| 320 | 320 |
} |
| 321 | 321 |
|
| ... | ... |
@@ -330,13 +401,13 @@ func LinkSetVfVlan(link Link, vf, vlan int) error {
|
| 330 | 330 |
func (h *Handle) LinkSetVfVlan(link Link, vf, vlan int) error {
|
| 331 | 331 |
base := link.Attrs() |
| 332 | 332 |
h.ensureIndex(base) |
| 333 |
- req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) |
|
| 333 |
+ req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) |
|
| 334 | 334 |
|
| 335 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 335 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 336 | 336 |
msg.Index = int32(base.Index) |
| 337 | 337 |
req.AddData(msg) |
| 338 | 338 |
|
| 339 |
- data := nl.NewRtAttr(nl.IFLA_VFINFO_LIST, nil) |
|
| 339 |
+ data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil) |
|
| 340 | 340 |
info := nl.NewRtAttrChild(data, nl.IFLA_VF_INFO, nil) |
| 341 | 341 |
vfmsg := nl.VfVlan{
|
| 342 | 342 |
Vf: uint32(vf), |
| ... | ... |
@@ -345,7 +416,7 @@ func (h *Handle) LinkSetVfVlan(link Link, vf, vlan int) error {
|
| 345 | 345 |
nl.NewRtAttrChild(info, nl.IFLA_VF_VLAN, vfmsg.Serialize()) |
| 346 | 346 |
req.AddData(data) |
| 347 | 347 |
|
| 348 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 348 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 349 | 349 |
return err |
| 350 | 350 |
} |
| 351 | 351 |
|
| ... | ... |
@@ -360,13 +431,13 @@ func LinkSetVfTxRate(link Link, vf, rate int) error {
|
| 360 | 360 |
func (h *Handle) LinkSetVfTxRate(link Link, vf, rate int) error {
|
| 361 | 361 |
base := link.Attrs() |
| 362 | 362 |
h.ensureIndex(base) |
| 363 |
- req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) |
|
| 363 |
+ req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) |
|
| 364 | 364 |
|
| 365 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 365 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 366 | 366 |
msg.Index = int32(base.Index) |
| 367 | 367 |
req.AddData(msg) |
| 368 | 368 |
|
| 369 |
- data := nl.NewRtAttr(nl.IFLA_VFINFO_LIST, nil) |
|
| 369 |
+ data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil) |
|
| 370 | 370 |
info := nl.NewRtAttrChild(data, nl.IFLA_VF_INFO, nil) |
| 371 | 371 |
vfmsg := nl.VfTxRate{
|
| 372 | 372 |
Vf: uint32(vf), |
| ... | ... |
@@ -375,7 +446,7 @@ func (h *Handle) LinkSetVfTxRate(link Link, vf, rate int) error {
|
| 375 | 375 |
nl.NewRtAttrChild(info, nl.IFLA_VF_TX_RATE, vfmsg.Serialize()) |
| 376 | 376 |
req.AddData(data) |
| 377 | 377 |
|
| 378 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 378 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 379 | 379 |
return err |
| 380 | 380 |
} |
| 381 | 381 |
|
| ... | ... |
@@ -391,13 +462,13 @@ func (h *Handle) LinkSetVfSpoofchk(link Link, vf int, check bool) error {
|
| 391 | 391 |
var setting uint32 |
| 392 | 392 |
base := link.Attrs() |
| 393 | 393 |
h.ensureIndex(base) |
| 394 |
- req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) |
|
| 394 |
+ req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) |
|
| 395 | 395 |
|
| 396 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 396 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 397 | 397 |
msg.Index = int32(base.Index) |
| 398 | 398 |
req.AddData(msg) |
| 399 | 399 |
|
| 400 |
- data := nl.NewRtAttr(nl.IFLA_VFINFO_LIST, nil) |
|
| 400 |
+ data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil) |
|
| 401 | 401 |
info := nl.NewRtAttrChild(data, nl.IFLA_VF_INFO, nil) |
| 402 | 402 |
if check {
|
| 403 | 403 |
setting = 1 |
| ... | ... |
@@ -409,7 +480,7 @@ func (h *Handle) LinkSetVfSpoofchk(link Link, vf int, check bool) error {
|
| 409 | 409 |
nl.NewRtAttrChild(info, nl.IFLA_VF_SPOOFCHK, vfmsg.Serialize()) |
| 410 | 410 |
req.AddData(data) |
| 411 | 411 |
|
| 412 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 412 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 413 | 413 |
return err |
| 414 | 414 |
} |
| 415 | 415 |
|
| ... | ... |
@@ -425,13 +496,13 @@ func (h *Handle) LinkSetVfTrust(link Link, vf int, state bool) error {
|
| 425 | 425 |
var setting uint32 |
| 426 | 426 |
base := link.Attrs() |
| 427 | 427 |
h.ensureIndex(base) |
| 428 |
- req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) |
|
| 428 |
+ req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) |
|
| 429 | 429 |
|
| 430 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 430 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 431 | 431 |
msg.Index = int32(base.Index) |
| 432 | 432 |
req.AddData(msg) |
| 433 | 433 |
|
| 434 |
- data := nl.NewRtAttr(nl.IFLA_VFINFO_LIST, nil) |
|
| 434 |
+ data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil) |
|
| 435 | 435 |
info := nl.NewRtAttrChild(data, nl.IFLA_VF_INFO, nil) |
| 436 | 436 |
if state {
|
| 437 | 437 |
setting = 1 |
| ... | ... |
@@ -443,7 +514,7 @@ func (h *Handle) LinkSetVfTrust(link Link, vf int, state bool) error {
|
| 443 | 443 |
nl.NewRtAttrChild(info, nl.IFLA_VF_TRUST, vfmsg.Serialize()) |
| 444 | 444 |
req.AddData(data) |
| 445 | 445 |
|
| 446 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 446 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 447 | 447 |
return err |
| 448 | 448 |
} |
| 449 | 449 |
|
| ... | ... |
@@ -491,19 +562,19 @@ func LinkSetMasterByIndex(link Link, masterIndex int) error {
|
| 491 | 491 |
func (h *Handle) LinkSetMasterByIndex(link Link, masterIndex int) error {
|
| 492 | 492 |
base := link.Attrs() |
| 493 | 493 |
h.ensureIndex(base) |
| 494 |
- req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) |
|
| 494 |
+ req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) |
|
| 495 | 495 |
|
| 496 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 496 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 497 | 497 |
msg.Index = int32(base.Index) |
| 498 | 498 |
req.AddData(msg) |
| 499 | 499 |
|
| 500 | 500 |
b := make([]byte, 4) |
| 501 | 501 |
native.PutUint32(b, uint32(masterIndex)) |
| 502 | 502 |
|
| 503 |
- data := nl.NewRtAttr(syscall.IFLA_MASTER, b) |
|
| 503 |
+ data := nl.NewRtAttr(unix.IFLA_MASTER, b) |
|
| 504 | 504 |
req.AddData(data) |
| 505 | 505 |
|
| 506 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 506 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 507 | 507 |
return err |
| 508 | 508 |
} |
| 509 | 509 |
|
| ... | ... |
@@ -520,19 +591,19 @@ func LinkSetNsPid(link Link, nspid int) error {
|
| 520 | 520 |
func (h *Handle) LinkSetNsPid(link Link, nspid int) error {
|
| 521 | 521 |
base := link.Attrs() |
| 522 | 522 |
h.ensureIndex(base) |
| 523 |
- req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) |
|
| 523 |
+ req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) |
|
| 524 | 524 |
|
| 525 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 525 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 526 | 526 |
msg.Index = int32(base.Index) |
| 527 | 527 |
req.AddData(msg) |
| 528 | 528 |
|
| 529 | 529 |
b := make([]byte, 4) |
| 530 | 530 |
native.PutUint32(b, uint32(nspid)) |
| 531 | 531 |
|
| 532 |
- data := nl.NewRtAttr(syscall.IFLA_NET_NS_PID, b) |
|
| 532 |
+ data := nl.NewRtAttr(unix.IFLA_NET_NS_PID, b) |
|
| 533 | 533 |
req.AddData(data) |
| 534 | 534 |
|
| 535 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 535 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 536 | 536 |
return err |
| 537 | 537 |
} |
| 538 | 538 |
|
| ... | ... |
@@ -549,19 +620,19 @@ func LinkSetNsFd(link Link, fd int) error {
|
| 549 | 549 |
func (h *Handle) LinkSetNsFd(link Link, fd int) error {
|
| 550 | 550 |
base := link.Attrs() |
| 551 | 551 |
h.ensureIndex(base) |
| 552 |
- req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) |
|
| 552 |
+ req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) |
|
| 553 | 553 |
|
| 554 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 554 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 555 | 555 |
msg.Index = int32(base.Index) |
| 556 | 556 |
req.AddData(msg) |
| 557 | 557 |
|
| 558 | 558 |
b := make([]byte, 4) |
| 559 | 559 |
native.PutUint32(b, uint32(fd)) |
| 560 | 560 |
|
| 561 |
- data := nl.NewRtAttr(nl.IFLA_NET_NS_FD, b) |
|
| 561 |
+ data := nl.NewRtAttr(unix.IFLA_NET_NS_FD, b) |
|
| 562 | 562 |
req.AddData(data) |
| 563 | 563 |
|
| 564 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 564 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 565 | 565 |
return err |
| 566 | 566 |
} |
| 567 | 567 |
|
| ... | ... |
@@ -576,15 +647,15 @@ func LinkSetXdpFd(link Link, fd int) error {
|
| 576 | 576 |
func LinkSetXdpFdWithFlags(link Link, fd, flags int) error {
|
| 577 | 577 |
base := link.Attrs() |
| 578 | 578 |
ensureIndex(base) |
| 579 |
- req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) |
|
| 579 |
+ req := nl.NewNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) |
|
| 580 | 580 |
|
| 581 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 581 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 582 | 582 |
msg.Index = int32(base.Index) |
| 583 | 583 |
req.AddData(msg) |
| 584 | 584 |
|
| 585 | 585 |
addXdpAttrs(&LinkXdp{Fd: fd, Flags: uint32(flags)}, req)
|
| 586 | 586 |
|
| 587 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 587 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 588 | 588 |
return err |
| 589 | 589 |
} |
| 590 | 590 |
|
| ... | ... |
@@ -642,6 +713,8 @@ func addVxlanAttrs(vxlan *Vxlan, linkInfo *nl.RtAttr) {
|
| 642 | 642 |
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_RSC, boolAttr(vxlan.RSC)) |
| 643 | 643 |
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_L2MISS, boolAttr(vxlan.L2miss)) |
| 644 | 644 |
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_L3MISS, boolAttr(vxlan.L3miss)) |
| 645 |
+ nl.NewRtAttrChild(data, nl.IFLA_VXLAN_UDP_ZERO_CSUM6_TX, boolAttr(vxlan.UDP6ZeroCSumTx)) |
|
| 646 |
+ nl.NewRtAttrChild(data, nl.IFLA_VXLAN_UDP_ZERO_CSUM6_RX, boolAttr(vxlan.UDP6ZeroCSumRx)) |
|
| 645 | 647 |
|
| 646 | 648 |
if vxlan.UDPCSum {
|
| 647 | 649 |
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_UDP_CSUM, boolAttr(vxlan.UDPCSum)) |
| ... | ... |
@@ -766,6 +839,12 @@ func addBondAttrs(bond *Bond, linkInfo *nl.RtAttr) {
|
| 766 | 766 |
} |
| 767 | 767 |
} |
| 768 | 768 |
|
| 769 |
+func cleanupFds(fds []*os.File) {
|
|
| 770 |
+ for _, f := range fds {
|
|
| 771 |
+ f.Close() |
|
| 772 |
+ } |
|
| 773 |
+} |
|
| 774 |
+ |
|
| 769 | 775 |
// LinkAdd adds a new link device. The type and features of the device |
| 770 | 776 |
// are taken from the parameters in the link object. |
| 771 | 777 |
// Equivalent to: `ip link add $link` |
| ... | ... |
@@ -777,7 +856,7 @@ func LinkAdd(link Link) error {
|
| 777 | 777 |
// are taken fromt the parameters in the link object. |
| 778 | 778 |
// Equivalent to: `ip link add $link` |
| 779 | 779 |
func (h *Handle) LinkAdd(link Link) error {
|
| 780 |
- return h.linkModify(link, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) |
|
| 780 |
+ return h.linkModify(link, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK) |
|
| 781 | 781 |
} |
| 782 | 782 |
|
| 783 | 783 |
func (h *Handle) linkModify(link Link, flags int) error {
|
| ... | ... |
@@ -791,104 +870,155 @@ func (h *Handle) linkModify(link Link, flags int) error {
|
| 791 | 791 |
if tuntap, ok := link.(*Tuntap); ok {
|
| 792 | 792 |
// TODO: support user |
| 793 | 793 |
// TODO: support group |
| 794 |
- // TODO: multi_queue |
|
| 795 | 794 |
// TODO: support non- persistent |
| 796 |
- if tuntap.Mode < syscall.IFF_TUN || tuntap.Mode > syscall.IFF_TAP {
|
|
| 795 |
+ if tuntap.Mode < unix.IFF_TUN || tuntap.Mode > unix.IFF_TAP {
|
|
| 797 | 796 |
return fmt.Errorf("Tuntap.Mode %v unknown!", tuntap.Mode)
|
| 798 | 797 |
} |
| 799 |
- file, err := os.OpenFile("/dev/net/tun", os.O_RDWR, 0)
|
|
| 800 |
- if err != nil {
|
|
| 801 |
- return err |
|
| 802 |
- } |
|
| 803 |
- defer file.Close() |
|
| 798 |
+ |
|
| 799 |
+ queues := tuntap.Queues |
|
| 800 |
+ |
|
| 801 |
+ var fds []*os.File |
|
| 804 | 802 |
var req ifReq |
| 805 |
- if tuntap.Flags == 0 {
|
|
| 806 |
- req.Flags = uint16(TUNTAP_DEFAULTS) |
|
| 803 |
+ copy(req.Name[:15], base.Name) |
|
| 804 |
+ |
|
| 805 |
+ req.Flags = uint16(tuntap.Flags) |
|
| 806 |
+ |
|
| 807 |
+ if queues == 0 { //Legacy compatibility
|
|
| 808 |
+ queues = 1 |
|
| 809 |
+ if tuntap.Flags == 0 {
|
|
| 810 |
+ req.Flags = uint16(TUNTAP_DEFAULTS) |
|
| 811 |
+ } |
|
| 807 | 812 |
} else {
|
| 808 |
- req.Flags = uint16(tuntap.Flags) |
|
| 813 |
+ // For best peformance set Flags to TUNTAP_MULTI_QUEUE_DEFAULTS | TUNTAP_VNET_HDR |
|
| 814 |
+ // when a) KVM has support for this ABI and |
|
| 815 |
+ // b) the value of the flag is queryable using the TUNGETIFF ioctl |
|
| 816 |
+ if tuntap.Flags == 0 {
|
|
| 817 |
+ req.Flags = uint16(TUNTAP_MULTI_QUEUE_DEFAULTS) |
|
| 818 |
+ } |
|
| 809 | 819 |
} |
| 820 |
+ |
|
| 810 | 821 |
req.Flags |= uint16(tuntap.Mode) |
| 811 |
- copy(req.Name[:15], base.Name) |
|
| 812 |
- _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, file.Fd(), uintptr(syscall.TUNSETIFF), uintptr(unsafe.Pointer(&req))) |
|
| 813 |
- if errno != 0 {
|
|
| 814 |
- return fmt.Errorf("Tuntap IOCTL TUNSETIFF failed, errno %v", errno)
|
|
| 822 |
+ |
|
| 823 |
+ for i := 0; i < queues; i++ {
|
|
| 824 |
+ localReq := req |
|
| 825 |
+ file, err := os.OpenFile("/dev/net/tun", os.O_RDWR, 0)
|
|
| 826 |
+ if err != nil {
|
|
| 827 |
+ cleanupFds(fds) |
|
| 828 |
+ return err |
|
| 829 |
+ } |
|
| 830 |
+ |
|
| 831 |
+ fds = append(fds, file) |
|
| 832 |
+ _, _, errno := unix.Syscall(unix.SYS_IOCTL, file.Fd(), uintptr(unix.TUNSETIFF), uintptr(unsafe.Pointer(&localReq))) |
|
| 833 |
+ if errno != 0 {
|
|
| 834 |
+ cleanupFds(fds) |
|
| 835 |
+ return fmt.Errorf("Tuntap IOCTL TUNSETIFF failed [%d], errno %v", i, errno)
|
|
| 836 |
+ } |
|
| 815 | 837 |
} |
| 816 |
- _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, file.Fd(), uintptr(syscall.TUNSETPERSIST), 1) |
|
| 838 |
+ |
|
| 839 |
+ _, _, errno := unix.Syscall(unix.SYS_IOCTL, fds[0].Fd(), uintptr(unix.TUNSETPERSIST), 1) |
|
| 817 | 840 |
if errno != 0 {
|
| 841 |
+ cleanupFds(fds) |
|
| 818 | 842 |
return fmt.Errorf("Tuntap IOCTL TUNSETPERSIST failed, errno %v", errno)
|
| 819 | 843 |
} |
| 844 |
+ |
|
| 820 | 845 |
h.ensureIndex(base) |
| 821 | 846 |
|
| 822 | 847 |
// can't set master during create, so set it afterwards |
| 823 | 848 |
if base.MasterIndex != 0 {
|
| 824 | 849 |
// TODO: verify MasterIndex is actually a bridge? |
| 825 |
- return h.LinkSetMasterByIndex(link, base.MasterIndex) |
|
| 850 |
+ err := h.LinkSetMasterByIndex(link, base.MasterIndex) |
|
| 851 |
+ if err != nil {
|
|
| 852 |
+ _, _, _ = unix.Syscall(unix.SYS_IOCTL, fds[0].Fd(), uintptr(unix.TUNSETPERSIST), 0) |
|
| 853 |
+ cleanupFds(fds) |
|
| 854 |
+ return err |
|
| 855 |
+ } |
|
| 856 |
+ } |
|
| 857 |
+ |
|
| 858 |
+ if tuntap.Queues == 0 {
|
|
| 859 |
+ cleanupFds(fds) |
|
| 860 |
+ } else {
|
|
| 861 |
+ tuntap.Fds = fds |
|
| 826 | 862 |
} |
| 863 |
+ |
|
| 827 | 864 |
return nil |
| 828 | 865 |
} |
| 829 | 866 |
|
| 830 |
- req := h.newNetlinkRequest(syscall.RTM_NEWLINK, flags) |
|
| 867 |
+ req := h.newNetlinkRequest(unix.RTM_NEWLINK, flags) |
|
| 831 | 868 |
|
| 832 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 869 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 833 | 870 |
// TODO: make it shorter |
| 834 | 871 |
if base.Flags&net.FlagUp != 0 {
|
| 835 |
- msg.Change = syscall.IFF_UP |
|
| 836 |
- msg.Flags = syscall.IFF_UP |
|
| 872 |
+ msg.Change = unix.IFF_UP |
|
| 873 |
+ msg.Flags = unix.IFF_UP |
|
| 837 | 874 |
} |
| 838 | 875 |
if base.Flags&net.FlagBroadcast != 0 {
|
| 839 |
- msg.Change |= syscall.IFF_BROADCAST |
|
| 840 |
- msg.Flags |= syscall.IFF_BROADCAST |
|
| 876 |
+ msg.Change |= unix.IFF_BROADCAST |
|
| 877 |
+ msg.Flags |= unix.IFF_BROADCAST |
|
| 841 | 878 |
} |
| 842 | 879 |
if base.Flags&net.FlagLoopback != 0 {
|
| 843 |
- msg.Change |= syscall.IFF_LOOPBACK |
|
| 844 |
- msg.Flags |= syscall.IFF_LOOPBACK |
|
| 880 |
+ msg.Change |= unix.IFF_LOOPBACK |
|
| 881 |
+ msg.Flags |= unix.IFF_LOOPBACK |
|
| 845 | 882 |
} |
| 846 | 883 |
if base.Flags&net.FlagPointToPoint != 0 {
|
| 847 |
- msg.Change |= syscall.IFF_POINTOPOINT |
|
| 848 |
- msg.Flags |= syscall.IFF_POINTOPOINT |
|
| 884 |
+ msg.Change |= unix.IFF_POINTOPOINT |
|
| 885 |
+ msg.Flags |= unix.IFF_POINTOPOINT |
|
| 849 | 886 |
} |
| 850 | 887 |
if base.Flags&net.FlagMulticast != 0 {
|
| 851 |
- msg.Change |= syscall.IFF_MULTICAST |
|
| 852 |
- msg.Flags |= syscall.IFF_MULTICAST |
|
| 888 |
+ msg.Change |= unix.IFF_MULTICAST |
|
| 889 |
+ msg.Flags |= unix.IFF_MULTICAST |
|
| 853 | 890 |
} |
| 891 |
+ if base.Index != 0 {
|
|
| 892 |
+ msg.Index = int32(base.Index) |
|
| 893 |
+ } |
|
| 894 |
+ |
|
| 854 | 895 |
req.AddData(msg) |
| 855 | 896 |
|
| 856 | 897 |
if base.ParentIndex != 0 {
|
| 857 | 898 |
b := make([]byte, 4) |
| 858 | 899 |
native.PutUint32(b, uint32(base.ParentIndex)) |
| 859 |
- data := nl.NewRtAttr(syscall.IFLA_LINK, b) |
|
| 900 |
+ data := nl.NewRtAttr(unix.IFLA_LINK, b) |
|
| 860 | 901 |
req.AddData(data) |
| 861 | 902 |
} else if link.Type() == "ipvlan" {
|
| 862 | 903 |
return fmt.Errorf("Can't create ipvlan link without ParentIndex")
|
| 863 | 904 |
} |
| 864 | 905 |
|
| 865 |
- nameData := nl.NewRtAttr(syscall.IFLA_IFNAME, nl.ZeroTerminated(base.Name)) |
|
| 906 |
+ nameData := nl.NewRtAttr(unix.IFLA_IFNAME, nl.ZeroTerminated(base.Name)) |
|
| 866 | 907 |
req.AddData(nameData) |
| 867 | 908 |
|
| 868 | 909 |
if base.MTU > 0 {
|
| 869 |
- mtu := nl.NewRtAttr(syscall.IFLA_MTU, nl.Uint32Attr(uint32(base.MTU))) |
|
| 910 |
+ mtu := nl.NewRtAttr(unix.IFLA_MTU, nl.Uint32Attr(uint32(base.MTU))) |
|
| 870 | 911 |
req.AddData(mtu) |
| 871 | 912 |
} |
| 872 | 913 |
|
| 873 | 914 |
if base.TxQLen >= 0 {
|
| 874 |
- qlen := nl.NewRtAttr(syscall.IFLA_TXQLEN, nl.Uint32Attr(uint32(base.TxQLen))) |
|
| 915 |
+ qlen := nl.NewRtAttr(unix.IFLA_TXQLEN, nl.Uint32Attr(uint32(base.TxQLen))) |
|
| 875 | 916 |
req.AddData(qlen) |
| 876 | 917 |
} |
| 877 | 918 |
|
| 878 | 919 |
if base.HardwareAddr != nil {
|
| 879 |
- hwaddr := nl.NewRtAttr(syscall.IFLA_ADDRESS, []byte(base.HardwareAddr)) |
|
| 920 |
+ hwaddr := nl.NewRtAttr(unix.IFLA_ADDRESS, []byte(base.HardwareAddr)) |
|
| 880 | 921 |
req.AddData(hwaddr) |
| 881 | 922 |
} |
| 882 | 923 |
|
| 924 |
+ if base.NumTxQueues > 0 {
|
|
| 925 |
+ txqueues := nl.NewRtAttr(unix.IFLA_NUM_TX_QUEUES, nl.Uint32Attr(uint32(base.NumTxQueues))) |
|
| 926 |
+ req.AddData(txqueues) |
|
| 927 |
+ } |
|
| 928 |
+ |
|
| 929 |
+ if base.NumRxQueues > 0 {
|
|
| 930 |
+ rxqueues := nl.NewRtAttr(unix.IFLA_NUM_RX_QUEUES, nl.Uint32Attr(uint32(base.NumRxQueues))) |
|
| 931 |
+ req.AddData(rxqueues) |
|
| 932 |
+ } |
|
| 933 |
+ |
|
| 883 | 934 |
if base.Namespace != nil {
|
| 884 | 935 |
var attr *nl.RtAttr |
| 885 | 936 |
switch base.Namespace.(type) {
|
| 886 | 937 |
case NsPid: |
| 887 | 938 |
val := nl.Uint32Attr(uint32(base.Namespace.(NsPid))) |
| 888 |
- attr = nl.NewRtAttr(syscall.IFLA_NET_NS_PID, val) |
|
| 939 |
+ attr = nl.NewRtAttr(unix.IFLA_NET_NS_PID, val) |
|
| 889 | 940 |
case NsFd: |
| 890 | 941 |
val := nl.Uint32Attr(uint32(base.Namespace.(NsFd))) |
| 891 |
- attr = nl.NewRtAttr(nl.IFLA_NET_NS_FD, val) |
|
| 942 |
+ attr = nl.NewRtAttr(unix.IFLA_NET_NS_FD, val) |
|
| 892 | 943 |
} |
| 893 | 944 |
|
| 894 | 945 |
req.AddData(attr) |
| ... | ... |
@@ -898,7 +1028,7 @@ func (h *Handle) linkModify(link Link, flags int) error {
|
| 898 | 898 |
addXdpAttrs(base.Xdp, req) |
| 899 | 899 |
} |
| 900 | 900 |
|
| 901 |
- linkInfo := nl.NewRtAttr(syscall.IFLA_LINKINFO, nil) |
|
| 901 |
+ linkInfo := nl.NewRtAttr(unix.IFLA_LINKINFO, nil) |
|
| 902 | 902 |
nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_KIND, nl.NonZeroTerminated(link.Type())) |
| 903 | 903 |
|
| 904 | 904 |
switch link := link.(type) {
|
| ... | ... |
@@ -910,13 +1040,13 @@ func (h *Handle) linkModify(link Link, flags int) error {
|
| 910 | 910 |
case *Veth: |
| 911 | 911 |
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) |
| 912 | 912 |
peer := nl.NewRtAttrChild(data, nl.VETH_INFO_PEER, nil) |
| 913 |
- nl.NewIfInfomsgChild(peer, syscall.AF_UNSPEC) |
|
| 914 |
- nl.NewRtAttrChild(peer, syscall.IFLA_IFNAME, nl.ZeroTerminated(link.PeerName)) |
|
| 913 |
+ nl.NewIfInfomsgChild(peer, unix.AF_UNSPEC) |
|
| 914 |
+ nl.NewRtAttrChild(peer, unix.IFLA_IFNAME, nl.ZeroTerminated(link.PeerName)) |
|
| 915 | 915 |
if base.TxQLen >= 0 {
|
| 916 |
- nl.NewRtAttrChild(peer, syscall.IFLA_TXQLEN, nl.Uint32Attr(uint32(base.TxQLen))) |
|
| 916 |
+ nl.NewRtAttrChild(peer, unix.IFLA_TXQLEN, nl.Uint32Attr(uint32(base.TxQLen))) |
|
| 917 | 917 |
} |
| 918 | 918 |
if base.MTU > 0 {
|
| 919 |
- nl.NewRtAttrChild(peer, syscall.IFLA_MTU, nl.Uint32Attr(uint32(base.MTU))) |
|
| 919 |
+ nl.NewRtAttrChild(peer, unix.IFLA_MTU, nl.Uint32Attr(uint32(base.MTU))) |
|
| 920 | 920 |
} |
| 921 | 921 |
|
| 922 | 922 |
case *Vxlan: |
| ... | ... |
@@ -940,6 +1070,8 @@ func (h *Handle) linkModify(link Link, flags int) error {
|
| 940 | 940 |
addGretapAttrs(link, linkInfo) |
| 941 | 941 |
case *Iptun: |
| 942 | 942 |
addIptunAttrs(link, linkInfo) |
| 943 |
+ case *Sittun: |
|
| 944 |
+ addSittunAttrs(link, linkInfo) |
|
| 943 | 945 |
case *Gretun: |
| 944 | 946 |
addGretunAttrs(link, linkInfo) |
| 945 | 947 |
case *Vti: |
| ... | ... |
@@ -954,7 +1086,7 @@ func (h *Handle) linkModify(link Link, flags int) error {
|
| 954 | 954 |
|
| 955 | 955 |
req.AddData(linkInfo) |
| 956 | 956 |
|
| 957 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 957 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 958 | 958 |
if err != nil {
|
| 959 | 959 |
return err |
| 960 | 960 |
} |
| ... | ... |
@@ -984,13 +1116,13 @@ func (h *Handle) LinkDel(link Link) error {
|
| 984 | 984 |
|
| 985 | 985 |
h.ensureIndex(base) |
| 986 | 986 |
|
| 987 |
- req := h.newNetlinkRequest(syscall.RTM_DELLINK, syscall.NLM_F_ACK) |
|
| 987 |
+ req := h.newNetlinkRequest(unix.RTM_DELLINK, unix.NLM_F_ACK) |
|
| 988 | 988 |
|
| 989 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 989 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 990 | 990 |
msg.Index = int32(base.Index) |
| 991 | 991 |
req.AddData(msg) |
| 992 | 992 |
|
| 993 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 993 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 994 | 994 |
return err |
| 995 | 995 |
} |
| 996 | 996 |
|
| ... | ... |
@@ -1033,16 +1165,16 @@ func (h *Handle) LinkByName(name string) (Link, error) {
|
| 1033 | 1033 |
return h.linkByNameDump(name) |
| 1034 | 1034 |
} |
| 1035 | 1035 |
|
| 1036 |
- req := h.newNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_ACK) |
|
| 1036 |
+ req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_ACK) |
|
| 1037 | 1037 |
|
| 1038 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 1038 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 1039 | 1039 |
req.AddData(msg) |
| 1040 | 1040 |
|
| 1041 |
- nameData := nl.NewRtAttr(syscall.IFLA_IFNAME, nl.ZeroTerminated(name)) |
|
| 1041 |
+ nameData := nl.NewRtAttr(unix.IFLA_IFNAME, nl.ZeroTerminated(name)) |
|
| 1042 | 1042 |
req.AddData(nameData) |
| 1043 | 1043 |
|
| 1044 | 1044 |
link, err := execGetLink(req) |
| 1045 |
- if err == syscall.EINVAL {
|
|
| 1045 |
+ if err == unix.EINVAL {
|
|
| 1046 | 1046 |
// older kernels don't support looking up via IFLA_IFNAME |
| 1047 | 1047 |
// so fall back to dumping all links |
| 1048 | 1048 |
h.lookupByDump = true |
| ... | ... |
@@ -1065,16 +1197,16 @@ func (h *Handle) LinkByAlias(alias string) (Link, error) {
|
| 1065 | 1065 |
return h.linkByAliasDump(alias) |
| 1066 | 1066 |
} |
| 1067 | 1067 |
|
| 1068 |
- req := h.newNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_ACK) |
|
| 1068 |
+ req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_ACK) |
|
| 1069 | 1069 |
|
| 1070 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 1070 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 1071 | 1071 |
req.AddData(msg) |
| 1072 | 1072 |
|
| 1073 |
- nameData := nl.NewRtAttr(syscall.IFLA_IFALIAS, nl.ZeroTerminated(alias)) |
|
| 1073 |
+ nameData := nl.NewRtAttr(unix.IFLA_IFALIAS, nl.ZeroTerminated(alias)) |
|
| 1074 | 1074 |
req.AddData(nameData) |
| 1075 | 1075 |
|
| 1076 | 1076 |
link, err := execGetLink(req) |
| 1077 |
- if err == syscall.EINVAL {
|
|
| 1077 |
+ if err == unix.EINVAL {
|
|
| 1078 | 1078 |
// older kernels don't support looking up via IFLA_IFALIAS |
| 1079 | 1079 |
// so fall back to dumping all links |
| 1080 | 1080 |
h.lookupByDump = true |
| ... | ... |
@@ -1091,9 +1223,9 @@ func LinkByIndex(index int) (Link, error) {
|
| 1091 | 1091 |
|
| 1092 | 1092 |
// LinkByIndex finds a link by index and returns a pointer to the object. |
| 1093 | 1093 |
func (h *Handle) LinkByIndex(index int) (Link, error) {
|
| 1094 |
- req := h.newNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_ACK) |
|
| 1094 |
+ req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_ACK) |
|
| 1095 | 1095 |
|
| 1096 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 1096 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 1097 | 1097 |
msg.Index = int32(index) |
| 1098 | 1098 |
req.AddData(msg) |
| 1099 | 1099 |
|
| ... | ... |
@@ -1101,10 +1233,10 @@ func (h *Handle) LinkByIndex(index int) (Link, error) {
|
| 1101 | 1101 |
} |
| 1102 | 1102 |
|
| 1103 | 1103 |
func execGetLink(req *nl.NetlinkRequest) (Link, error) {
|
| 1104 |
- msgs, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 1104 |
+ msgs, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 1105 | 1105 |
if err != nil {
|
| 1106 | 1106 |
if errno, ok := err.(syscall.Errno); ok {
|
| 1107 |
- if errno == syscall.ENODEV {
|
|
| 1107 |
+ if errno == unix.ENODEV {
|
|
| 1108 | 1108 |
return nil, LinkNotFoundError{fmt.Errorf("Link not found")}
|
| 1109 | 1109 |
} |
| 1110 | 1110 |
} |
| ... | ... |
@@ -1125,7 +1257,7 @@ func execGetLink(req *nl.NetlinkRequest) (Link, error) {
|
| 1125 | 1125 |
|
| 1126 | 1126 |
// linkDeserialize deserializes a raw message received from netlink into |
| 1127 | 1127 |
// a link object. |
| 1128 |
-func LinkDeserialize(hdr *syscall.NlMsghdr, m []byte) (Link, error) {
|
|
| 1128 |
+func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
|
|
| 1129 | 1129 |
msg := nl.DeserializeIfInfomsg(m) |
| 1130 | 1130 |
|
| 1131 | 1131 |
attrs, err := nl.ParseRouteAttr(m[msg.Len():]) |
| ... | ... |
@@ -1134,7 +1266,7 @@ func LinkDeserialize(hdr *syscall.NlMsghdr, m []byte) (Link, error) {
|
| 1134 | 1134 |
} |
| 1135 | 1135 |
|
| 1136 | 1136 |
base := LinkAttrs{Index: int(msg.Index), RawFlags: msg.Flags, Flags: linkFlags(msg.Flags), EncapType: msg.EncapType()}
|
| 1137 |
- if msg.Flags&syscall.IFF_PROMISC != 0 {
|
|
| 1137 |
+ if msg.Flags&unix.IFF_PROMISC != 0 {
|
|
| 1138 | 1138 |
base.Promisc = 1 |
| 1139 | 1139 |
} |
| 1140 | 1140 |
var ( |
| ... | ... |
@@ -1145,7 +1277,7 @@ func LinkDeserialize(hdr *syscall.NlMsghdr, m []byte) (Link, error) {
|
| 1145 | 1145 |
) |
| 1146 | 1146 |
for _, attr := range attrs {
|
| 1147 | 1147 |
switch attr.Attr.Type {
|
| 1148 |
- case syscall.IFLA_LINKINFO: |
|
| 1148 |
+ case unix.IFLA_LINKINFO: |
|
| 1149 | 1149 |
infos, err := nl.ParseRouteAttr(attr.Value) |
| 1150 | 1150 |
if err != nil {
|
| 1151 | 1151 |
return nil, err |
| ... | ... |
@@ -1177,10 +1309,16 @@ func LinkDeserialize(hdr *syscall.NlMsghdr, m []byte) (Link, error) {
|
| 1177 | 1177 |
link = &Macvtap{}
|
| 1178 | 1178 |
case "gretap": |
| 1179 | 1179 |
link = &Gretap{}
|
| 1180 |
+ case "ip6gretap": |
|
| 1181 |
+ link = &Gretap{}
|
|
| 1180 | 1182 |
case "ipip": |
| 1181 | 1183 |
link = &Iptun{}
|
| 1184 |
+ case "sit": |
|
| 1185 |
+ link = &Sittun{}
|
|
| 1182 | 1186 |
case "gre": |
| 1183 | 1187 |
link = &Gretun{}
|
| 1188 |
+ case "ip6gre": |
|
| 1189 |
+ link = &Gretun{}
|
|
| 1184 | 1190 |
case "vti": |
| 1185 | 1191 |
link = &Vti{}
|
| 1186 | 1192 |
case "vrf": |
| ... | ... |
@@ -1210,10 +1348,16 @@ func LinkDeserialize(hdr *syscall.NlMsghdr, m []byte) (Link, error) {
|
| 1210 | 1210 |
parseMacvtapData(link, data) |
| 1211 | 1211 |
case "gretap": |
| 1212 | 1212 |
parseGretapData(link, data) |
| 1213 |
+ case "ip6gretap": |
|
| 1214 |
+ parseGretapData(link, data) |
|
| 1213 | 1215 |
case "ipip": |
| 1214 | 1216 |
parseIptunData(link, data) |
| 1217 |
+ case "sit": |
|
| 1218 |
+ parseSittunData(link, data) |
|
| 1215 | 1219 |
case "gre": |
| 1216 | 1220 |
parseGretunData(link, data) |
| 1221 |
+ case "ip6gre": |
|
| 1222 |
+ parseGretunData(link, data) |
|
| 1217 | 1223 |
case "vti": |
| 1218 | 1224 |
parseVtiData(link, data) |
| 1219 | 1225 |
case "vrf": |
| ... | ... |
@@ -1225,7 +1369,7 @@ func LinkDeserialize(hdr *syscall.NlMsghdr, m []byte) (Link, error) {
|
| 1225 | 1225 |
} |
| 1226 | 1226 |
} |
| 1227 | 1227 |
} |
| 1228 |
- case syscall.IFLA_ADDRESS: |
|
| 1228 |
+ case unix.IFLA_ADDRESS: |
|
| 1229 | 1229 |
var nonzero bool |
| 1230 | 1230 |
for _, b := range attr.Value {
|
| 1231 | 1231 |
if b != 0 {
|
| ... | ... |
@@ -1235,40 +1379,40 @@ func LinkDeserialize(hdr *syscall.NlMsghdr, m []byte) (Link, error) {
|
| 1235 | 1235 |
if nonzero {
|
| 1236 | 1236 |
base.HardwareAddr = attr.Value[:] |
| 1237 | 1237 |
} |
| 1238 |
- case syscall.IFLA_IFNAME: |
|
| 1238 |
+ case unix.IFLA_IFNAME: |
|
| 1239 | 1239 |
base.Name = string(attr.Value[:len(attr.Value)-1]) |
| 1240 |
- case syscall.IFLA_MTU: |
|
| 1240 |
+ case unix.IFLA_MTU: |
|
| 1241 | 1241 |
base.MTU = int(native.Uint32(attr.Value[0:4])) |
| 1242 |
- case syscall.IFLA_LINK: |
|
| 1242 |
+ case unix.IFLA_LINK: |
|
| 1243 | 1243 |
base.ParentIndex = int(native.Uint32(attr.Value[0:4])) |
| 1244 |
- case syscall.IFLA_MASTER: |
|
| 1244 |
+ case unix.IFLA_MASTER: |
|
| 1245 | 1245 |
base.MasterIndex = int(native.Uint32(attr.Value[0:4])) |
| 1246 |
- case syscall.IFLA_TXQLEN: |
|
| 1246 |
+ case unix.IFLA_TXQLEN: |
|
| 1247 | 1247 |
base.TxQLen = int(native.Uint32(attr.Value[0:4])) |
| 1248 |
- case syscall.IFLA_IFALIAS: |
|
| 1248 |
+ case unix.IFLA_IFALIAS: |
|
| 1249 | 1249 |
base.Alias = string(attr.Value[:len(attr.Value)-1]) |
| 1250 |
- case syscall.IFLA_STATS: |
|
| 1250 |
+ case unix.IFLA_STATS: |
|
| 1251 | 1251 |
stats32 = attr.Value[:] |
| 1252 |
- case IFLA_STATS64: |
|
| 1252 |
+ case unix.IFLA_STATS64: |
|
| 1253 | 1253 |
stats64 = attr.Value[:] |
| 1254 |
- case nl.IFLA_XDP: |
|
| 1254 |
+ case unix.IFLA_XDP: |
|
| 1255 | 1255 |
xdp, err := parseLinkXdp(attr.Value[:]) |
| 1256 | 1256 |
if err != nil {
|
| 1257 | 1257 |
return nil, err |
| 1258 | 1258 |
} |
| 1259 | 1259 |
base.Xdp = xdp |
| 1260 |
- case syscall.IFLA_PROTINFO | syscall.NLA_F_NESTED: |
|
| 1261 |
- if hdr != nil && hdr.Type == syscall.RTM_NEWLINK && |
|
| 1262 |
- msg.Family == syscall.AF_BRIDGE {
|
|
| 1260 |
+ case unix.IFLA_PROTINFO | unix.NLA_F_NESTED: |
|
| 1261 |
+ if hdr != nil && hdr.Type == unix.RTM_NEWLINK && |
|
| 1262 |
+ msg.Family == unix.AF_BRIDGE {
|
|
| 1263 | 1263 |
attrs, err := nl.ParseRouteAttr(attr.Value[:]) |
| 1264 | 1264 |
if err != nil {
|
| 1265 | 1265 |
return nil, err |
| 1266 | 1266 |
} |
| 1267 | 1267 |
base.Protinfo = parseProtinfo(attrs) |
| 1268 | 1268 |
} |
| 1269 |
- case syscall.IFLA_OPERSTATE: |
|
| 1269 |
+ case unix.IFLA_OPERSTATE: |
|
| 1270 | 1270 |
base.OperState = LinkOperState(uint8(attr.Value[0])) |
| 1271 |
- case nl.IFLA_LINK_NETNSID: |
|
| 1271 |
+ case unix.IFLA_LINK_NETNSID: |
|
| 1272 | 1272 |
base.NetNsID = int(native.Uint32(attr.Value[0:4])) |
| 1273 | 1273 |
} |
| 1274 | 1274 |
} |
| ... | ... |
@@ -1299,12 +1443,12 @@ func LinkList() ([]Link, error) {
|
| 1299 | 1299 |
func (h *Handle) LinkList() ([]Link, error) {
|
| 1300 | 1300 |
// NOTE(vish): This duplicates functionality in net/iface_linux.go, but we need |
| 1301 | 1301 |
// to get the message ourselves to parse link type. |
| 1302 |
- req := h.newNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_DUMP) |
|
| 1302 |
+ req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_DUMP) |
|
| 1303 | 1303 |
|
| 1304 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 1304 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 1305 | 1305 |
req.AddData(msg) |
| 1306 | 1306 |
|
| 1307 |
- msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWLINK) |
|
| 1307 |
+ msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWLINK) |
|
| 1308 | 1308 |
if err != nil {
|
| 1309 | 1309 |
return nil, err |
| 1310 | 1310 |
} |
| ... | ... |
@@ -1324,20 +1468,20 @@ func (h *Handle) LinkList() ([]Link, error) {
|
| 1324 | 1324 |
// LinkUpdate is used to pass information back from LinkSubscribe() |
| 1325 | 1325 |
type LinkUpdate struct {
|
| 1326 | 1326 |
nl.IfInfomsg |
| 1327 |
- Header syscall.NlMsghdr |
|
| 1327 |
+ Header unix.NlMsghdr |
|
| 1328 | 1328 |
Link |
| 1329 | 1329 |
} |
| 1330 | 1330 |
|
| 1331 | 1331 |
// LinkSubscribe takes a chan down which notifications will be sent |
| 1332 | 1332 |
// when links change. Close the 'done' chan to stop subscription. |
| 1333 | 1333 |
func LinkSubscribe(ch chan<- LinkUpdate, done <-chan struct{}) error {
|
| 1334 |
- return linkSubscribeAt(netns.None(), netns.None(), ch, done, nil) |
|
| 1334 |
+ return linkSubscribeAt(netns.None(), netns.None(), ch, done, nil, false) |
|
| 1335 | 1335 |
} |
| 1336 | 1336 |
|
| 1337 | 1337 |
// LinkSubscribeAt works like LinkSubscribe plus it allows the caller |
| 1338 | 1338 |
// to choose the network namespace in which to subscribe (ns). |
| 1339 | 1339 |
func LinkSubscribeAt(ns netns.NsHandle, ch chan<- LinkUpdate, done <-chan struct{}) error {
|
| 1340 |
- return linkSubscribeAt(ns, netns.None(), ch, done, nil) |
|
| 1340 |
+ return linkSubscribeAt(ns, netns.None(), ch, done, nil, false) |
|
| 1341 | 1341 |
} |
| 1342 | 1342 |
|
| 1343 | 1343 |
// LinkSubscribeOptions contains a set of options to use with |
| ... | ... |
@@ -1345,6 +1489,7 @@ func LinkSubscribeAt(ns netns.NsHandle, ch chan<- LinkUpdate, done <-chan struct |
| 1345 | 1345 |
type LinkSubscribeOptions struct {
|
| 1346 | 1346 |
Namespace *netns.NsHandle |
| 1347 | 1347 |
ErrorCallback func(error) |
| 1348 |
+ ListExisting bool |
|
| 1348 | 1349 |
} |
| 1349 | 1350 |
|
| 1350 | 1351 |
// LinkSubscribeWithOptions work like LinkSubscribe but enable to |
| ... | ... |
@@ -1355,11 +1500,11 @@ func LinkSubscribeWithOptions(ch chan<- LinkUpdate, done <-chan struct{}, option
|
| 1355 | 1355 |
none := netns.None() |
| 1356 | 1356 |
options.Namespace = &none |
| 1357 | 1357 |
} |
| 1358 |
- return linkSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback) |
|
| 1358 |
+ return linkSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting) |
|
| 1359 | 1359 |
} |
| 1360 | 1360 |
|
| 1361 |
-func linkSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-chan struct{}, cberr func(error)) error {
|
|
| 1362 |
- s, err := nl.SubscribeAt(newNs, curNs, syscall.NETLINK_ROUTE, syscall.RTNLGRP_LINK) |
|
| 1361 |
+func linkSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-chan struct{}, cberr func(error), listExisting bool) error {
|
|
| 1362 |
+ s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_LINK) |
|
| 1363 | 1363 |
if err != nil {
|
| 1364 | 1364 |
return err |
| 1365 | 1365 |
} |
| ... | ... |
@@ -1369,6 +1514,15 @@ func linkSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-c |
| 1369 | 1369 |
s.Close() |
| 1370 | 1370 |
}() |
| 1371 | 1371 |
} |
| 1372 |
+ if listExisting {
|
|
| 1373 |
+ req := pkgHandle.newNetlinkRequest(unix.RTM_GETLINK, |
|
| 1374 |
+ unix.NLM_F_DUMP) |
|
| 1375 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 1376 |
+ req.AddData(msg) |
|
| 1377 |
+ if err := s.Send(req); err != nil {
|
|
| 1378 |
+ return err |
|
| 1379 |
+ } |
|
| 1380 |
+ } |
|
| 1372 | 1381 |
go func() {
|
| 1373 | 1382 |
defer close(ch) |
| 1374 | 1383 |
for {
|
| ... | ... |
@@ -1380,15 +1534,30 @@ func linkSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-c |
| 1380 | 1380 |
return |
| 1381 | 1381 |
} |
| 1382 | 1382 |
for _, m := range msgs {
|
| 1383 |
+ if m.Header.Type == unix.NLMSG_DONE {
|
|
| 1384 |
+ continue |
|
| 1385 |
+ } |
|
| 1386 |
+ if m.Header.Type == unix.NLMSG_ERROR {
|
|
| 1387 |
+ native := nl.NativeEndian() |
|
| 1388 |
+ error := int32(native.Uint32(m.Data[0:4])) |
|
| 1389 |
+ if error == 0 {
|
|
| 1390 |
+ continue |
|
| 1391 |
+ } |
|
| 1392 |
+ if cberr != nil {
|
|
| 1393 |
+ cberr(syscall.Errno(-error)) |
|
| 1394 |
+ } |
|
| 1395 |
+ return |
|
| 1396 |
+ } |
|
| 1383 | 1397 |
ifmsg := nl.DeserializeIfInfomsg(m.Data) |
| 1384 |
- link, err := LinkDeserialize(&m.Header, m.Data) |
|
| 1398 |
+ header := unix.NlMsghdr(m.Header) |
|
| 1399 |
+ link, err := LinkDeserialize(&header, m.Data) |
|
| 1385 | 1400 |
if err != nil {
|
| 1386 | 1401 |
if cberr != nil {
|
| 1387 | 1402 |
cberr(err) |
| 1388 | 1403 |
} |
| 1389 | 1404 |
return |
| 1390 | 1405 |
} |
| 1391 |
- ch <- LinkUpdate{IfInfomsg: *ifmsg, Header: m.Header, Link: link}
|
|
| 1406 |
+ ch <- LinkUpdate{IfInfomsg: *ifmsg, Header: header, Link: link}
|
|
| 1392 | 1407 |
} |
| 1393 | 1408 |
} |
| 1394 | 1409 |
}() |
| ... | ... |
@@ -1463,16 +1632,16 @@ func (h *Handle) LinkSetBrProxyArpWiFi(link Link, mode bool) error {
|
| 1463 | 1463 |
func (h *Handle) setProtinfoAttr(link Link, mode bool, attr int) error {
|
| 1464 | 1464 |
base := link.Attrs() |
| 1465 | 1465 |
h.ensureIndex(base) |
| 1466 |
- req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) |
|
| 1466 |
+ req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) |
|
| 1467 | 1467 |
|
| 1468 |
- msg := nl.NewIfInfomsg(syscall.AF_BRIDGE) |
|
| 1468 |
+ msg := nl.NewIfInfomsg(unix.AF_BRIDGE) |
|
| 1469 | 1469 |
msg.Index = int32(base.Index) |
| 1470 | 1470 |
req.AddData(msg) |
| 1471 | 1471 |
|
| 1472 |
- br := nl.NewRtAttr(syscall.IFLA_PROTINFO|syscall.NLA_F_NESTED, nil) |
|
| 1472 |
+ br := nl.NewRtAttr(unix.IFLA_PROTINFO|unix.NLA_F_NESTED, nil) |
|
| 1473 | 1473 |
nl.NewRtAttrChild(br, attr, boolToByte(mode)) |
| 1474 | 1474 |
req.AddData(br) |
| 1475 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 1475 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 1476 | 1476 |
if err != nil {
|
| 1477 | 1477 |
return err |
| 1478 | 1478 |
} |
| ... | ... |
@@ -1490,19 +1659,19 @@ func LinkSetTxQLen(link Link, qlen int) error {
|
| 1490 | 1490 |
func (h *Handle) LinkSetTxQLen(link Link, qlen int) error {
|
| 1491 | 1491 |
base := link.Attrs() |
| 1492 | 1492 |
h.ensureIndex(base) |
| 1493 |
- req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) |
|
| 1493 |
+ req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK) |
|
| 1494 | 1494 |
|
| 1495 |
- msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) |
|
| 1495 |
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 1496 | 1496 |
msg.Index = int32(base.Index) |
| 1497 | 1497 |
req.AddData(msg) |
| 1498 | 1498 |
|
| 1499 | 1499 |
b := make([]byte, 4) |
| 1500 | 1500 |
native.PutUint32(b, uint32(qlen)) |
| 1501 | 1501 |
|
| 1502 |
- data := nl.NewRtAttr(syscall.IFLA_TXQLEN, b) |
|
| 1502 |
+ data := nl.NewRtAttr(unix.IFLA_TXQLEN, b) |
|
| 1503 | 1503 |
req.AddData(data) |
| 1504 | 1504 |
|
| 1505 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 1505 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 1506 | 1506 |
return err |
| 1507 | 1507 |
} |
| 1508 | 1508 |
|
| ... | ... |
@@ -1548,6 +1717,10 @@ func parseVxlanData(link Link, data []syscall.NetlinkRouteAttr) {
|
| 1548 | 1548 |
vxlan.L3miss = int8(datum.Value[0]) != 0 |
| 1549 | 1549 |
case nl.IFLA_VXLAN_UDP_CSUM: |
| 1550 | 1550 |
vxlan.UDPCSum = int8(datum.Value[0]) != 0 |
| 1551 |
+ case nl.IFLA_VXLAN_UDP_ZERO_CSUM6_TX: |
|
| 1552 |
+ vxlan.UDP6ZeroCSumTx = int8(datum.Value[0]) != 0 |
|
| 1553 |
+ case nl.IFLA_VXLAN_UDP_ZERO_CSUM6_RX: |
|
| 1554 |
+ vxlan.UDP6ZeroCSumRx = int8(datum.Value[0]) != 0 |
|
| 1551 | 1555 |
case nl.IFLA_VXLAN_GBP: |
| 1552 | 1556 |
vxlan.GBP = true |
| 1553 | 1557 |
case nl.IFLA_VXLAN_FLOWBASED: |
| ... | ... |
@@ -1650,7 +1823,8 @@ func parseMacvtapData(link Link, data []syscall.NetlinkRouteAttr) {
|
| 1650 | 1650 |
func parseMacvlanData(link Link, data []syscall.NetlinkRouteAttr) {
|
| 1651 | 1651 |
macv := link.(*Macvlan) |
| 1652 | 1652 |
for _, datum := range data {
|
| 1653 |
- if datum.Attr.Type == nl.IFLA_MACVLAN_MODE {
|
|
| 1653 |
+ switch datum.Attr.Type {
|
|
| 1654 |
+ case nl.IFLA_MACVLAN_MODE: |
|
| 1654 | 1655 |
switch native.Uint32(datum.Value[0:4]) {
|
| 1655 | 1656 |
case nl.MACVLAN_MODE_PRIVATE: |
| 1656 | 1657 |
macv.Mode = MACVLAN_MODE_PRIVATE |
| ... | ... |
@@ -1663,7 +1837,16 @@ func parseMacvlanData(link Link, data []syscall.NetlinkRouteAttr) {
|
| 1663 | 1663 |
case nl.MACVLAN_MODE_SOURCE: |
| 1664 | 1664 |
macv.Mode = MACVLAN_MODE_SOURCE |
| 1665 | 1665 |
} |
| 1666 |
- return |
|
| 1666 |
+ case nl.IFLA_MACVLAN_MACADDR_COUNT: |
|
| 1667 |
+ macv.MACAddrs = make([]net.HardwareAddr, 0, int(native.Uint32(datum.Value[0:4]))) |
|
| 1668 |
+ case nl.IFLA_MACVLAN_MACADDR_DATA: |
|
| 1669 |
+ macs, err := nl.ParseRouteAttr(datum.Value[:]) |
|
| 1670 |
+ if err != nil {
|
|
| 1671 |
+ panic(fmt.Sprintf("failed to ParseRouteAttr for IFLA_MACVLAN_MACADDR_DATA: %v", err))
|
|
| 1672 |
+ } |
|
| 1673 |
+ for _, macDatum := range macs {
|
|
| 1674 |
+ macv.MACAddrs = append(macv.MACAddrs, net.HardwareAddr(macDatum.Value[0:6])) |
|
| 1675 |
+ } |
|
| 1667 | 1676 |
} |
| 1668 | 1677 |
} |
| 1669 | 1678 |
} |
| ... | ... |
@@ -1671,19 +1854,19 @@ func parseMacvlanData(link Link, data []syscall.NetlinkRouteAttr) {
|
| 1671 | 1671 |
// copied from pkg/net_linux.go |
| 1672 | 1672 |
func linkFlags(rawFlags uint32) net.Flags {
|
| 1673 | 1673 |
var f net.Flags |
| 1674 |
- if rawFlags&syscall.IFF_UP != 0 {
|
|
| 1674 |
+ if rawFlags&unix.IFF_UP != 0 {
|
|
| 1675 | 1675 |
f |= net.FlagUp |
| 1676 | 1676 |
} |
| 1677 |
- if rawFlags&syscall.IFF_BROADCAST != 0 {
|
|
| 1677 |
+ if rawFlags&unix.IFF_BROADCAST != 0 {
|
|
| 1678 | 1678 |
f |= net.FlagBroadcast |
| 1679 | 1679 |
} |
| 1680 |
- if rawFlags&syscall.IFF_LOOPBACK != 0 {
|
|
| 1680 |
+ if rawFlags&unix.IFF_LOOPBACK != 0 {
|
|
| 1681 | 1681 |
f |= net.FlagLoopback |
| 1682 | 1682 |
} |
| 1683 |
- if rawFlags&syscall.IFF_POINTOPOINT != 0 {
|
|
| 1683 |
+ if rawFlags&unix.IFF_POINTOPOINT != 0 {
|
|
| 1684 | 1684 |
f |= net.FlagPointToPoint |
| 1685 | 1685 |
} |
| 1686 |
- if rawFlags&syscall.IFF_MULTICAST != 0 {
|
|
| 1686 |
+ if rawFlags&unix.IFF_MULTICAST != 0 {
|
|
| 1687 | 1687 |
f |= net.FlagMulticast |
| 1688 | 1688 |
} |
| 1689 | 1689 |
return f |
| ... | ... |
@@ -1698,12 +1881,17 @@ func addGretapAttrs(gretap *Gretap, linkInfo *nl.RtAttr) {
|
| 1698 | 1698 |
return |
| 1699 | 1699 |
} |
| 1700 | 1700 |
|
| 1701 |
- ip := gretap.Local.To4() |
|
| 1702 |
- if ip != nil {
|
|
| 1701 |
+ if ip := gretap.Local; ip != nil {
|
|
| 1702 |
+ if ip.To4() != nil {
|
|
| 1703 |
+ ip = ip.To4() |
|
| 1704 |
+ } |
|
| 1703 | 1705 |
nl.NewRtAttrChild(data, nl.IFLA_GRE_LOCAL, []byte(ip)) |
| 1704 | 1706 |
} |
| 1705 |
- ip = gretap.Remote.To4() |
|
| 1706 |
- if ip != nil {
|
|
| 1707 |
+ |
|
| 1708 |
+ if ip := gretap.Remote; ip != nil {
|
|
| 1709 |
+ if ip.To4() != nil {
|
|
| 1710 |
+ ip = ip.To4() |
|
| 1711 |
+ } |
|
| 1707 | 1712 |
nl.NewRtAttrChild(data, nl.IFLA_GRE_REMOTE, []byte(ip)) |
| 1708 | 1713 |
} |
| 1709 | 1714 |
|
| ... | ... |
@@ -1742,9 +1930,9 @@ func parseGretapData(link Link, data []syscall.NetlinkRouteAttr) {
|
| 1742 | 1742 |
case nl.IFLA_GRE_IKEY: |
| 1743 | 1743 |
gre.OKey = ntohl(datum.Value[0:4]) |
| 1744 | 1744 |
case nl.IFLA_GRE_LOCAL: |
| 1745 |
- gre.Local = net.IP(datum.Value[0:4]) |
|
| 1745 |
+ gre.Local = net.IP(datum.Value[0:16]) |
|
| 1746 | 1746 |
case nl.IFLA_GRE_REMOTE: |
| 1747 |
- gre.Remote = net.IP(datum.Value[0:4]) |
|
| 1747 |
+ gre.Remote = net.IP(datum.Value[0:16]) |
|
| 1748 | 1748 |
case nl.IFLA_GRE_ENCAP_SPORT: |
| 1749 | 1749 |
gre.EncapSport = ntohs(datum.Value[0:2]) |
| 1750 | 1750 |
case nl.IFLA_GRE_ENCAP_DPORT: |
| ... | ... |
@@ -1765,7 +1953,9 @@ func parseGretapData(link Link, data []syscall.NetlinkRouteAttr) {
|
| 1765 | 1765 |
case nl.IFLA_GRE_ENCAP_FLAGS: |
| 1766 | 1766 |
gre.EncapFlags = native.Uint16(datum.Value[0:2]) |
| 1767 | 1767 |
case nl.IFLA_GRE_COLLECT_METADATA: |
| 1768 |
- gre.FlowBased = int8(datum.Value[0]) != 0 |
|
| 1768 |
+ if len(datum.Value) > 0 {
|
|
| 1769 |
+ gre.FlowBased = int8(datum.Value[0]) != 0 |
|
| 1770 |
+ } |
|
| 1769 | 1771 |
} |
| 1770 | 1772 |
} |
| 1771 | 1773 |
} |
| ... | ... |
@@ -1773,12 +1963,17 @@ func parseGretapData(link Link, data []syscall.NetlinkRouteAttr) {
|
| 1773 | 1773 |
func addGretunAttrs(gre *Gretun, linkInfo *nl.RtAttr) {
|
| 1774 | 1774 |
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) |
| 1775 | 1775 |
|
| 1776 |
- ip := gre.Local.To4() |
|
| 1777 |
- if ip != nil {
|
|
| 1776 |
+ if ip := gre.Local; ip != nil {
|
|
| 1777 |
+ if ip.To4() != nil {
|
|
| 1778 |
+ ip = ip.To4() |
|
| 1779 |
+ } |
|
| 1778 | 1780 |
nl.NewRtAttrChild(data, nl.IFLA_GRE_LOCAL, []byte(ip)) |
| 1779 | 1781 |
} |
| 1780 |
- ip = gre.Remote.To4() |
|
| 1781 |
- if ip != nil {
|
|
| 1782 |
+ |
|
| 1783 |
+ if ip := gre.Remote; ip != nil {
|
|
| 1784 |
+ if ip.To4() != nil {
|
|
| 1785 |
+ ip = ip.To4() |
|
| 1786 |
+ } |
|
| 1782 | 1787 |
nl.NewRtAttrChild(data, nl.IFLA_GRE_REMOTE, []byte(ip)) |
| 1783 | 1788 |
} |
| 1784 | 1789 |
|
| ... | ... |
@@ -1802,6 +1997,10 @@ func addGretunAttrs(gre *Gretun, linkInfo *nl.RtAttr) {
|
| 1802 | 1802 |
nl.NewRtAttrChild(data, nl.IFLA_GRE_PMTUDISC, nl.Uint8Attr(gre.PMtuDisc)) |
| 1803 | 1803 |
nl.NewRtAttrChild(data, nl.IFLA_GRE_TTL, nl.Uint8Attr(gre.Ttl)) |
| 1804 | 1804 |
nl.NewRtAttrChild(data, nl.IFLA_GRE_TOS, nl.Uint8Attr(gre.Tos)) |
| 1805 |
+ nl.NewRtAttrChild(data, nl.IFLA_GRE_ENCAP_TYPE, nl.Uint16Attr(gre.EncapType)) |
|
| 1806 |
+ nl.NewRtAttrChild(data, nl.IFLA_GRE_ENCAP_FLAGS, nl.Uint16Attr(gre.EncapFlags)) |
|
| 1807 |
+ nl.NewRtAttrChild(data, nl.IFLA_GRE_ENCAP_SPORT, htons(gre.EncapSport)) |
|
| 1808 |
+ nl.NewRtAttrChild(data, nl.IFLA_GRE_ENCAP_DPORT, htons(gre.EncapDport)) |
|
| 1805 | 1809 |
} |
| 1806 | 1810 |
|
| 1807 | 1811 |
func parseGretunData(link Link, data []syscall.NetlinkRouteAttr) {
|
| ... | ... |
@@ -1813,9 +2012,9 @@ func parseGretunData(link Link, data []syscall.NetlinkRouteAttr) {
|
| 1813 | 1813 |
case nl.IFLA_GRE_IKEY: |
| 1814 | 1814 |
gre.OKey = ntohl(datum.Value[0:4]) |
| 1815 | 1815 |
case nl.IFLA_GRE_LOCAL: |
| 1816 |
- gre.Local = net.IP(datum.Value[0:4]) |
|
| 1816 |
+ gre.Local = net.IP(datum.Value[0:16]) |
|
| 1817 | 1817 |
case nl.IFLA_GRE_REMOTE: |
| 1818 |
- gre.Remote = net.IP(datum.Value[0:4]) |
|
| 1818 |
+ gre.Remote = net.IP(datum.Value[0:16]) |
|
| 1819 | 1819 |
case nl.IFLA_GRE_IFLAGS: |
| 1820 | 1820 |
gre.IFlags = ntohs(datum.Value[0:2]) |
| 1821 | 1821 |
case nl.IFLA_GRE_OFLAGS: |
| ... | ... |
@@ -1827,6 +2026,14 @@ func parseGretunData(link Link, data []syscall.NetlinkRouteAttr) {
|
| 1827 | 1827 |
gre.Tos = uint8(datum.Value[0]) |
| 1828 | 1828 |
case nl.IFLA_GRE_PMTUDISC: |
| 1829 | 1829 |
gre.PMtuDisc = uint8(datum.Value[0]) |
| 1830 |
+ case nl.IFLA_GRE_ENCAP_TYPE: |
|
| 1831 |
+ gre.EncapType = native.Uint16(datum.Value[0:2]) |
|
| 1832 |
+ case nl.IFLA_GRE_ENCAP_FLAGS: |
|
| 1833 |
+ gre.EncapFlags = native.Uint16(datum.Value[0:2]) |
|
| 1834 |
+ case nl.IFLA_GRE_ENCAP_SPORT: |
|
| 1835 |
+ gre.EncapSport = ntohs(datum.Value[0:2]) |
|
| 1836 |
+ case nl.IFLA_GRE_ENCAP_DPORT: |
|
| 1837 |
+ gre.EncapDport = ntohs(datum.Value[0:2]) |
|
| 1830 | 1838 |
} |
| 1831 | 1839 |
} |
| 1832 | 1840 |
} |
| ... | ... |
@@ -1840,11 +2047,12 @@ func parseLinkStats64(data []byte) *LinkStatistics {
|
| 1840 | 1840 |
} |
| 1841 | 1841 |
|
| 1842 | 1842 |
func addXdpAttrs(xdp *LinkXdp, req *nl.NetlinkRequest) {
|
| 1843 |
- attrs := nl.NewRtAttr(nl.IFLA_XDP|syscall.NLA_F_NESTED, nil) |
|
| 1843 |
+ attrs := nl.NewRtAttr(unix.IFLA_XDP|unix.NLA_F_NESTED, nil) |
|
| 1844 | 1844 |
b := make([]byte, 4) |
| 1845 | 1845 |
native.PutUint32(b, uint32(xdp.Fd)) |
| 1846 | 1846 |
nl.NewRtAttrChild(attrs, nl.IFLA_XDP_FD, b) |
| 1847 | 1847 |
if xdp.Flags != 0 {
|
| 1848 |
+ b := make([]byte, 4) |
|
| 1848 | 1849 |
native.PutUint32(b, xdp.Flags) |
| 1849 | 1850 |
nl.NewRtAttrChild(attrs, nl.IFLA_XDP_FLAGS, b) |
| 1850 | 1851 |
} |
| ... | ... |
@@ -1873,6 +2081,12 @@ func parseLinkXdp(data []byte) (*LinkXdp, error) {
|
| 1873 | 1873 |
} |
| 1874 | 1874 |
|
| 1875 | 1875 |
func addIptunAttrs(iptun *Iptun, linkInfo *nl.RtAttr) {
|
| 1876 |
+ if iptun.FlowBased {
|
|
| 1877 |
+ // In flow based mode, no other attributes need to be configured |
|
| 1878 |
+ nl.NewRtAttrChild(linkInfo, nl.IFLA_IPTUN_COLLECT_METADATA, boolAttr(iptun.FlowBased)) |
|
| 1879 |
+ return |
|
| 1880 |
+ } |
|
| 1881 |
+ |
|
| 1876 | 1882 |
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) |
| 1877 | 1883 |
|
| 1878 | 1884 |
ip := iptun.Local.To4() |
| ... | ... |
@@ -1891,6 +2105,10 @@ func addIptunAttrs(iptun *Iptun, linkInfo *nl.RtAttr) {
|
| 1891 | 1891 |
nl.NewRtAttrChild(data, nl.IFLA_IPTUN_PMTUDISC, nl.Uint8Attr(iptun.PMtuDisc)) |
| 1892 | 1892 |
nl.NewRtAttrChild(data, nl.IFLA_IPTUN_TTL, nl.Uint8Attr(iptun.Ttl)) |
| 1893 | 1893 |
nl.NewRtAttrChild(data, nl.IFLA_IPTUN_TOS, nl.Uint8Attr(iptun.Tos)) |
| 1894 |
+ nl.NewRtAttrChild(data, nl.IFLA_IPTUN_ENCAP_TYPE, nl.Uint16Attr(iptun.EncapType)) |
|
| 1895 |
+ nl.NewRtAttrChild(data, nl.IFLA_IPTUN_ENCAP_FLAGS, nl.Uint16Attr(iptun.EncapFlags)) |
|
| 1896 |
+ nl.NewRtAttrChild(data, nl.IFLA_IPTUN_ENCAP_SPORT, htons(iptun.EncapSport)) |
|
| 1897 |
+ nl.NewRtAttrChild(data, nl.IFLA_IPTUN_ENCAP_DPORT, htons(iptun.EncapDport)) |
|
| 1894 | 1898 |
} |
| 1895 | 1899 |
|
| 1896 | 1900 |
func parseIptunData(link Link, data []syscall.NetlinkRouteAttr) {
|
| ... | ... |
@@ -1907,6 +2125,72 @@ func parseIptunData(link Link, data []syscall.NetlinkRouteAttr) {
|
| 1907 | 1907 |
iptun.Tos = uint8(datum.Value[0]) |
| 1908 | 1908 |
case nl.IFLA_IPTUN_PMTUDISC: |
| 1909 | 1909 |
iptun.PMtuDisc = uint8(datum.Value[0]) |
| 1910 |
+ case nl.IFLA_IPTUN_ENCAP_SPORT: |
|
| 1911 |
+ iptun.EncapSport = ntohs(datum.Value[0:2]) |
|
| 1912 |
+ case nl.IFLA_IPTUN_ENCAP_DPORT: |
|
| 1913 |
+ iptun.EncapDport = ntohs(datum.Value[0:2]) |
|
| 1914 |
+ case nl.IFLA_IPTUN_ENCAP_TYPE: |
|
| 1915 |
+ iptun.EncapType = native.Uint16(datum.Value[0:2]) |
|
| 1916 |
+ case nl.IFLA_IPTUN_ENCAP_FLAGS: |
|
| 1917 |
+ iptun.EncapFlags = native.Uint16(datum.Value[0:2]) |
|
| 1918 |
+ case nl.IFLA_IPTUN_COLLECT_METADATA: |
|
| 1919 |
+ iptun.FlowBased = int8(datum.Value[0]) != 0 |
|
| 1920 |
+ } |
|
| 1921 |
+ } |
|
| 1922 |
+} |
|
| 1923 |
+ |
|
| 1924 |
+func addSittunAttrs(sittun *Sittun, linkInfo *nl.RtAttr) {
|
|
| 1925 |
+ data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil) |
|
| 1926 |
+ |
|
| 1927 |
+ if sittun.Link != 0 {
|
|
| 1928 |
+ nl.NewRtAttrChild(data, nl.IFLA_IPTUN_LINK, nl.Uint32Attr(sittun.Link)) |
|
| 1929 |
+ } |
|
| 1930 |
+ |
|
| 1931 |
+ ip := sittun.Local.To4() |
|
| 1932 |
+ if ip != nil {
|
|
| 1933 |
+ nl.NewRtAttrChild(data, nl.IFLA_IPTUN_LOCAL, []byte(ip)) |
|
| 1934 |
+ } |
|
| 1935 |
+ |
|
| 1936 |
+ ip = sittun.Remote.To4() |
|
| 1937 |
+ if ip != nil {
|
|
| 1938 |
+ nl.NewRtAttrChild(data, nl.IFLA_IPTUN_REMOTE, []byte(ip)) |
|
| 1939 |
+ } |
|
| 1940 |
+ |
|
| 1941 |
+ if sittun.Ttl > 0 {
|
|
| 1942 |
+ // Would otherwise fail on 3.10 kernel |
|
| 1943 |
+ nl.NewRtAttrChild(data, nl.IFLA_IPTUN_TTL, nl.Uint8Attr(sittun.Ttl)) |
|
| 1944 |
+ } |
|
| 1945 |
+ |
|
| 1946 |
+ nl.NewRtAttrChild(data, nl.IFLA_IPTUN_TOS, nl.Uint8Attr(sittun.Tos)) |
|
| 1947 |
+ nl.NewRtAttrChild(data, nl.IFLA_IPTUN_PMTUDISC, nl.Uint8Attr(sittun.PMtuDisc)) |
|
| 1948 |
+ nl.NewRtAttrChild(data, nl.IFLA_IPTUN_ENCAP_TYPE, nl.Uint16Attr(sittun.EncapType)) |
|
| 1949 |
+ nl.NewRtAttrChild(data, nl.IFLA_IPTUN_ENCAP_FLAGS, nl.Uint16Attr(sittun.EncapFlags)) |
|
| 1950 |
+ nl.NewRtAttrChild(data, nl.IFLA_IPTUN_ENCAP_SPORT, htons(sittun.EncapSport)) |
|
| 1951 |
+ nl.NewRtAttrChild(data, nl.IFLA_IPTUN_ENCAP_DPORT, htons(sittun.EncapDport)) |
|
| 1952 |
+} |
|
| 1953 |
+ |
|
| 1954 |
+func parseSittunData(link Link, data []syscall.NetlinkRouteAttr) {
|
|
| 1955 |
+ sittun := link.(*Sittun) |
|
| 1956 |
+ for _, datum := range data {
|
|
| 1957 |
+ switch datum.Attr.Type {
|
|
| 1958 |
+ case nl.IFLA_IPTUN_LOCAL: |
|
| 1959 |
+ sittun.Local = net.IP(datum.Value[0:4]) |
|
| 1960 |
+ case nl.IFLA_IPTUN_REMOTE: |
|
| 1961 |
+ sittun.Remote = net.IP(datum.Value[0:4]) |
|
| 1962 |
+ case nl.IFLA_IPTUN_TTL: |
|
| 1963 |
+ sittun.Ttl = uint8(datum.Value[0]) |
|
| 1964 |
+ case nl.IFLA_IPTUN_TOS: |
|
| 1965 |
+ sittun.Tos = uint8(datum.Value[0]) |
|
| 1966 |
+ case nl.IFLA_IPTUN_PMTUDISC: |
|
| 1967 |
+ sittun.PMtuDisc = uint8(datum.Value[0]) |
|
| 1968 |
+ case nl.IFLA_IPTUN_ENCAP_TYPE: |
|
| 1969 |
+ sittun.EncapType = native.Uint16(datum.Value[0:2]) |
|
| 1970 |
+ case nl.IFLA_IPTUN_ENCAP_FLAGS: |
|
| 1971 |
+ sittun.EncapFlags = native.Uint16(datum.Value[0:2]) |
|
| 1972 |
+ case nl.IFLA_IPTUN_ENCAP_SPORT: |
|
| 1973 |
+ sittun.EncapSport = ntohs(datum.Value[0:2]) |
|
| 1974 |
+ case nl.IFLA_IPTUN_ENCAP_DPORT: |
|
| 1975 |
+ sittun.EncapDport = ntohs(datum.Value[0:2]) |
|
| 1910 | 1976 |
} |
| 1911 | 1977 |
} |
| 1912 | 1978 |
} |
| ... | ... |
@@ -2014,3 +2298,57 @@ func parseGTPData(link Link, data []syscall.NetlinkRouteAttr) {
|
| 2014 | 2014 |
} |
| 2015 | 2015 |
} |
| 2016 | 2016 |
} |
| 2017 |
+ |
|
| 2018 |
+// LinkSetBondSlave add slave to bond link via ioctl interface. |
|
| 2019 |
+func LinkSetBondSlave(link Link, master *Bond) error {
|
|
| 2020 |
+ fd, err := getSocketUDP() |
|
| 2021 |
+ if err != nil {
|
|
| 2022 |
+ return err |
|
| 2023 |
+ } |
|
| 2024 |
+ defer syscall.Close(fd) |
|
| 2025 |
+ |
|
| 2026 |
+ ifreq := newIocltSlaveReq(link.Attrs().Name, master.Attrs().Name) |
|
| 2027 |
+ |
|
| 2028 |
+ _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), unix.SIOCBONDENSLAVE, uintptr(unsafe.Pointer(ifreq))) |
|
| 2029 |
+ if errno != 0 {
|
|
| 2030 |
+ return fmt.Errorf("Failed to enslave %q to %q, errno=%v", link.Attrs().Name, master.Attrs().Name, errno)
|
|
| 2031 |
+ } |
|
| 2032 |
+ return nil |
|
| 2033 |
+} |
|
| 2034 |
+ |
|
| 2035 |
+// VethPeerIndex get veth peer index. |
|
| 2036 |
+func VethPeerIndex(link *Veth) (int, error) {
|
|
| 2037 |
+ fd, err := getSocketUDP() |
|
| 2038 |
+ if err != nil {
|
|
| 2039 |
+ return -1, err |
|
| 2040 |
+ } |
|
| 2041 |
+ defer syscall.Close(fd) |
|
| 2042 |
+ |
|
| 2043 |
+ ifreq, sSet := newIocltStringSetReq(link.Name) |
|
| 2044 |
+ _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), SIOCETHTOOL, uintptr(unsafe.Pointer(ifreq))) |
|
| 2045 |
+ if errno != 0 {
|
|
| 2046 |
+ return -1, fmt.Errorf("SIOCETHTOOL request for %q failed, errno=%v", link.Attrs().Name, errno)
|
|
| 2047 |
+ } |
|
| 2048 |
+ |
|
| 2049 |
+ gstrings := ðtoolGstrings{
|
|
| 2050 |
+ cmd: ETHTOOL_GSTRINGS, |
|
| 2051 |
+ stringSet: ETH_SS_STATS, |
|
| 2052 |
+ length: sSet.data[0], |
|
| 2053 |
+ } |
|
| 2054 |
+ ifreq.Data = uintptr(unsafe.Pointer(gstrings)) |
|
| 2055 |
+ _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), SIOCETHTOOL, uintptr(unsafe.Pointer(ifreq))) |
|
| 2056 |
+ if errno != 0 {
|
|
| 2057 |
+ return -1, fmt.Errorf("SIOCETHTOOL request for %q failed, errno=%v", link.Attrs().Name, errno)
|
|
| 2058 |
+ } |
|
| 2059 |
+ |
|
| 2060 |
+ stats := ðtoolStats{
|
|
| 2061 |
+ cmd: ETHTOOL_GSTATS, |
|
| 2062 |
+ nStats: gstrings.length, |
|
| 2063 |
+ } |
|
| 2064 |
+ ifreq.Data = uintptr(unsafe.Pointer(stats)) |
|
| 2065 |
+ _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), SIOCETHTOOL, uintptr(unsafe.Pointer(ifreq))) |
|
| 2066 |
+ if errno != 0 {
|
|
| 2067 |
+ return -1, fmt.Errorf("SIOCETHTOOL request for %q failed, errno=%v", link.Attrs().Name, errno)
|
|
| 2068 |
+ } |
|
| 2069 |
+ return int(stats.data[0]), nil |
|
| 2070 |
+} |
| ... | ... |
@@ -2,10 +2,10 @@ package netlink |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"net" |
| 5 |
- "syscall" |
|
| 6 | 5 |
"unsafe" |
| 7 | 6 |
|
| 8 | 7 |
"github.com/vishvananda/netlink/nl" |
| 8 |
+ "golang.org/x/sys/unix" |
|
| 9 | 9 |
) |
| 10 | 10 |
|
| 11 | 11 |
const ( |
| ... | ... |
@@ -73,7 +73,7 @@ func NeighAdd(neigh *Neigh) error {
|
| 73 | 73 |
// NeighAdd will add an IP to MAC mapping to the ARP table |
| 74 | 74 |
// Equivalent to: `ip neigh add ....` |
| 75 | 75 |
func (h *Handle) NeighAdd(neigh *Neigh) error {
|
| 76 |
- return h.neighAdd(neigh, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL) |
|
| 76 |
+ return h.neighAdd(neigh, unix.NLM_F_CREATE|unix.NLM_F_EXCL) |
|
| 77 | 77 |
} |
| 78 | 78 |
|
| 79 | 79 |
// NeighSet will add or replace an IP to MAC mapping to the ARP table |
| ... | ... |
@@ -85,7 +85,7 @@ func NeighSet(neigh *Neigh) error {
|
| 85 | 85 |
// NeighSet will add or replace an IP to MAC mapping to the ARP table |
| 86 | 86 |
// Equivalent to: `ip neigh replace....` |
| 87 | 87 |
func (h *Handle) NeighSet(neigh *Neigh) error {
|
| 88 |
- return h.neighAdd(neigh, syscall.NLM_F_CREATE|syscall.NLM_F_REPLACE) |
|
| 88 |
+ return h.neighAdd(neigh, unix.NLM_F_CREATE|unix.NLM_F_REPLACE) |
|
| 89 | 89 |
} |
| 90 | 90 |
|
| 91 | 91 |
// NeighAppend will append an entry to FDB |
| ... | ... |
@@ -97,7 +97,7 @@ func NeighAppend(neigh *Neigh) error {
|
| 97 | 97 |
// NeighAppend will append an entry to FDB |
| 98 | 98 |
// Equivalent to: `bridge fdb append...` |
| 99 | 99 |
func (h *Handle) NeighAppend(neigh *Neigh) error {
|
| 100 |
- return h.neighAdd(neigh, syscall.NLM_F_CREATE|syscall.NLM_F_APPEND) |
|
| 100 |
+ return h.neighAdd(neigh, unix.NLM_F_CREATE|unix.NLM_F_APPEND) |
|
| 101 | 101 |
} |
| 102 | 102 |
|
| 103 | 103 |
// NeighAppend will append an entry to FDB |
| ... | ... |
@@ -109,7 +109,7 @@ func neighAdd(neigh *Neigh, mode int) error {
|
| 109 | 109 |
// NeighAppend will append an entry to FDB |
| 110 | 110 |
// Equivalent to: `bridge fdb append...` |
| 111 | 111 |
func (h *Handle) neighAdd(neigh *Neigh, mode int) error {
|
| 112 |
- req := h.newNetlinkRequest(syscall.RTM_NEWNEIGH, mode|syscall.NLM_F_ACK) |
|
| 112 |
+ req := h.newNetlinkRequest(unix.RTM_NEWNEIGH, mode|unix.NLM_F_ACK) |
|
| 113 | 113 |
return neighHandle(neigh, req) |
| 114 | 114 |
} |
| 115 | 115 |
|
| ... | ... |
@@ -122,7 +122,7 @@ func NeighDel(neigh *Neigh) error {
|
| 122 | 122 |
// NeighDel will delete an IP address from a link device. |
| 123 | 123 |
// Equivalent to: `ip addr del $addr dev $link` |
| 124 | 124 |
func (h *Handle) NeighDel(neigh *Neigh) error {
|
| 125 |
- req := h.newNetlinkRequest(syscall.RTM_DELNEIGH, syscall.NLM_F_ACK) |
|
| 125 |
+ req := h.newNetlinkRequest(unix.RTM_DELNEIGH, unix.NLM_F_ACK) |
|
| 126 | 126 |
return neighHandle(neigh, req) |
| 127 | 127 |
} |
| 128 | 128 |
|
| ... | ... |
@@ -160,7 +160,17 @@ func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error {
|
| 160 | 160 |
req.AddData(hwData) |
| 161 | 161 |
} |
| 162 | 162 |
|
| 163 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 163 |
+ if neigh.Vlan != 0 {
|
|
| 164 |
+ vlanData := nl.NewRtAttr(NDA_VLAN, nl.Uint16Attr(uint16(neigh.Vlan))) |
|
| 165 |
+ req.AddData(vlanData) |
|
| 166 |
+ } |
|
| 167 |
+ |
|
| 168 |
+ if neigh.VNI != 0 {
|
|
| 169 |
+ vniData := nl.NewRtAttr(NDA_VNI, nl.Uint32Attr(uint32(neigh.VNI))) |
|
| 170 |
+ req.AddData(vniData) |
|
| 171 |
+ } |
|
| 172 |
+ |
|
| 173 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 164 | 174 |
return err |
| 165 | 175 |
} |
| 166 | 176 |
|
| ... | ... |
@@ -193,7 +203,7 @@ func (h *Handle) NeighProxyList(linkIndex, family int) ([]Neigh, error) {
|
| 193 | 193 |
} |
| 194 | 194 |
|
| 195 | 195 |
func (h *Handle) neighList(linkIndex, family, flags int) ([]Neigh, error) {
|
| 196 |
- req := h.newNetlinkRequest(syscall.RTM_GETNEIGH, syscall.NLM_F_DUMP) |
|
| 196 |
+ req := h.newNetlinkRequest(unix.RTM_GETNEIGH, unix.NLM_F_DUMP) |
|
| 197 | 197 |
msg := Ndmsg{
|
| 198 | 198 |
Family: uint8(family), |
| 199 | 199 |
Index: uint32(linkIndex), |
| ... | ... |
@@ -201,7 +211,7 @@ func (h *Handle) neighList(linkIndex, family, flags int) ([]Neigh, error) {
|
| 201 | 201 |
} |
| 202 | 202 |
req.AddData(&msg) |
| 203 | 203 |
|
| 204 |
- msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWNEIGH) |
|
| 204 |
+ msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWNEIGH) |
|
| 205 | 205 |
if err != nil {
|
| 206 | 206 |
return nil, err |
| 207 | 207 |
} |
| ... | ... |
@@ -257,7 +267,7 @@ func NeighDeserialize(m []byte) (*Neigh, error) {
|
| 257 | 257 |
// BUG: Is this a bug in the netlink library? |
| 258 | 258 |
// #define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len)) |
| 259 | 259 |
// #define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0)) |
| 260 |
- attrLen := attr.Attr.Len - syscall.SizeofRtAttr |
|
| 260 |
+ attrLen := attr.Attr.Len - unix.SizeofRtAttr |
|
| 261 | 261 |
if attrLen == 4 && (encapType == "ipip" || |
| 262 | 262 |
encapType == "sit" || |
| 263 | 263 |
encapType == "gre") {
|
| ... | ... |
@@ -268,6 +278,10 @@ func NeighDeserialize(m []byte) (*Neigh, error) {
|
| 268 | 268 |
} else {
|
| 269 | 269 |
neigh.HardwareAddr = net.HardwareAddr(attr.Value) |
| 270 | 270 |
} |
| 271 |
+ case NDA_VLAN: |
|
| 272 |
+ neigh.Vlan = int(native.Uint16(attr.Value[0:2])) |
|
| 273 |
+ case NDA_VNI: |
|
| 274 |
+ neigh.VNI = int(native.Uint32(attr.Value[0:4])) |
|
| 271 | 275 |
} |
| 272 | 276 |
} |
| 273 | 277 |
|
| ... | ... |
@@ -1,17 +1,18 @@ |
| 1 | 1 |
package nl |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "syscall" |
|
| 5 | 4 |
"unsafe" |
| 5 |
+ |
|
| 6 |
+ "golang.org/x/sys/unix" |
|
| 6 | 7 |
) |
| 7 | 8 |
|
| 8 | 9 |
type IfAddrmsg struct {
|
| 9 |
- syscall.IfAddrmsg |
|
| 10 |
+ unix.IfAddrmsg |
|
| 10 | 11 |
} |
| 11 | 12 |
|
| 12 | 13 |
func NewIfAddrmsg(family int) *IfAddrmsg {
|
| 13 | 14 |
return &IfAddrmsg{
|
| 14 |
- IfAddrmsg: syscall.IfAddrmsg{
|
|
| 15 |
+ IfAddrmsg: unix.IfAddrmsg{
|
|
| 15 | 16 |
Family: uint8(family), |
| 16 | 17 |
}, |
| 17 | 18 |
} |
| ... | ... |
@@ -35,15 +36,15 @@ func NewIfAddrmsg(family int) *IfAddrmsg {
|
| 35 | 35 |
// SizeofIfAddrmsg = 0x8 |
| 36 | 36 |
|
| 37 | 37 |
func DeserializeIfAddrmsg(b []byte) *IfAddrmsg {
|
| 38 |
- return (*IfAddrmsg)(unsafe.Pointer(&b[0:syscall.SizeofIfAddrmsg][0])) |
|
| 38 |
+ return (*IfAddrmsg)(unsafe.Pointer(&b[0:unix.SizeofIfAddrmsg][0])) |
|
| 39 | 39 |
} |
| 40 | 40 |
|
| 41 | 41 |
func (msg *IfAddrmsg) Serialize() []byte {
|
| 42 |
- return (*(*[syscall.SizeofIfAddrmsg]byte)(unsafe.Pointer(msg)))[:] |
|
| 42 |
+ return (*(*[unix.SizeofIfAddrmsg]byte)(unsafe.Pointer(msg)))[:] |
|
| 43 | 43 |
} |
| 44 | 44 |
|
| 45 | 45 |
func (msg *IfAddrmsg) Len() int {
|
| 46 |
- return syscall.SizeofIfAddrmsg |
|
| 46 |
+ return unix.SizeofIfAddrmsg |
|
| 47 | 47 |
} |
| 48 | 48 |
|
| 49 | 49 |
// struct ifa_cacheinfo {
|
| ... | ... |
@@ -1,35 +1,11 @@ |
| 1 | 1 |
package nl |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "syscall" |
|
| 5 | 4 |
"unsafe" |
| 6 | 5 |
) |
| 7 | 6 |
|
| 8 | 7 |
const ( |
| 9 | 8 |
DEFAULT_CHANGE = 0xFFFFFFFF |
| 10 |
- // doesn't exist in syscall |
|
| 11 |
- IFLA_VFINFO_LIST = syscall.IFLA_IFALIAS + 1 + iota |
|
| 12 |
- IFLA_STATS64 |
|
| 13 |
- IFLA_VF_PORTS |
|
| 14 |
- IFLA_PORT_SELF |
|
| 15 |
- IFLA_AF_SPEC |
|
| 16 |
- IFLA_GROUP |
|
| 17 |
- IFLA_NET_NS_FD |
|
| 18 |
- IFLA_EXT_MASK |
|
| 19 |
- IFLA_PROMISCUITY |
|
| 20 |
- IFLA_NUM_TX_QUEUES |
|
| 21 |
- IFLA_NUM_RX_QUEUES |
|
| 22 |
- IFLA_CARRIER |
|
| 23 |
- IFLA_PHYS_PORT_ID |
|
| 24 |
- IFLA_CARRIER_CHANGES |
|
| 25 |
- IFLA_PHYS_SWITCH_ID |
|
| 26 |
- IFLA_LINK_NETNSID |
|
| 27 |
- IFLA_PHYS_PORT_NAME |
|
| 28 |
- IFLA_PROTO_DOWN |
|
| 29 |
- IFLA_GSO_MAX_SEGS |
|
| 30 |
- IFLA_GSO_MAX_SIZE |
|
| 31 |
- IFLA_PAD |
|
| 32 |
- IFLA_XDP |
|
| 33 | 9 |
) |
| 34 | 10 |
|
| 35 | 11 |
const ( |
| ... | ... |
@@ -118,6 +94,10 @@ const ( |
| 118 | 118 |
IFLA_MACVLAN_UNSPEC = iota |
| 119 | 119 |
IFLA_MACVLAN_MODE |
| 120 | 120 |
IFLA_MACVLAN_FLAGS |
| 121 |
+ IFLA_MACVLAN_MACADDR_MODE |
|
| 122 |
+ IFLA_MACVLAN_MACADDR |
|
| 123 |
+ IFLA_MACVLAN_MACADDR_DATA |
|
| 124 |
+ IFLA_MACVLAN_MACADDR_COUNT |
|
| 121 | 125 |
IFLA_MACVLAN_MAX = IFLA_MACVLAN_FLAGS |
| 122 | 126 |
) |
| 123 | 127 |
|
| ... | ... |
@@ -130,6 +110,13 @@ const ( |
| 130 | 130 |
) |
| 131 | 131 |
|
| 132 | 132 |
const ( |
| 133 |
+ MACVLAN_MACADDR_ADD = iota |
|
| 134 |
+ MACVLAN_MACADDR_DEL |
|
| 135 |
+ MACVLAN_MACADDR_FLUSH |
|
| 136 |
+ MACVLAN_MACADDR_SET |
|
| 137 |
+) |
|
| 138 |
+ |
|
| 139 |
+const ( |
|
| 133 | 140 |
IFLA_BOND_UNSPEC = iota |
| 134 | 141 |
IFLA_BOND_MODE |
| 135 | 142 |
IFLA_BOND_ACTIVE_SLAVE |
| ... | ... |
@@ -475,7 +462,12 @@ const ( |
| 475 | 475 |
IFLA_IPTUN_6RD_RELAY_PREFIX |
| 476 | 476 |
IFLA_IPTUN_6RD_PREFIXLEN |
| 477 | 477 |
IFLA_IPTUN_6RD_RELAY_PREFIXLEN |
| 478 |
- IFLA_IPTUN_MAX = IFLA_IPTUN_6RD_RELAY_PREFIXLEN |
|
| 478 |
+ IFLA_IPTUN_ENCAP_TYPE |
|
| 479 |
+ IFLA_IPTUN_ENCAP_FLAGS |
|
| 480 |
+ IFLA_IPTUN_ENCAP_SPORT |
|
| 481 |
+ IFLA_IPTUN_ENCAP_DPORT |
|
| 482 |
+ IFLA_IPTUN_COLLECT_METADATA |
|
| 483 |
+ IFLA_IPTUN_MAX = IFLA_IPTUN_COLLECT_METADATA |
|
| 479 | 484 |
) |
| 480 | 485 |
|
| 481 | 486 |
const ( |
| ... | ... |
@@ -13,18 +13,19 @@ import ( |
| 13 | 13 |
"unsafe" |
| 14 | 14 |
|
| 15 | 15 |
"github.com/vishvananda/netns" |
| 16 |
+ "golang.org/x/sys/unix" |
|
| 16 | 17 |
) |
| 17 | 18 |
|
| 18 | 19 |
const ( |
| 19 | 20 |
// Family type definitions |
| 20 |
- FAMILY_ALL = syscall.AF_UNSPEC |
|
| 21 |
- FAMILY_V4 = syscall.AF_INET |
|
| 22 |
- FAMILY_V6 = syscall.AF_INET6 |
|
| 21 |
+ FAMILY_ALL = unix.AF_UNSPEC |
|
| 22 |
+ FAMILY_V4 = unix.AF_INET |
|
| 23 |
+ FAMILY_V6 = unix.AF_INET6 |
|
| 23 | 24 |
FAMILY_MPLS = AF_MPLS |
| 24 | 25 |
) |
| 25 | 26 |
|
| 26 | 27 |
// SupportedNlFamilies contains the list of netlink families this netlink package supports |
| 27 |
-var SupportedNlFamilies = []int{syscall.NETLINK_ROUTE, syscall.NETLINK_XFRM, syscall.NETLINK_NETFILTER}
|
|
| 28 |
+var SupportedNlFamilies = []int{unix.NETLINK_ROUTE, unix.NETLINK_XFRM, unix.NETLINK_NETFILTER}
|
|
| 28 | 29 |
|
| 29 | 30 |
var nextSeqNr uint32 |
| 30 | 31 |
|
| ... | ... |
@@ -77,161 +78,161 @@ type NetlinkRequestData interface {
|
| 77 | 77 |
|
| 78 | 78 |
// IfInfomsg is related to links, but it is used for list requests as well |
| 79 | 79 |
type IfInfomsg struct {
|
| 80 |
- syscall.IfInfomsg |
|
| 80 |
+ unix.IfInfomsg |
|
| 81 | 81 |
} |
| 82 | 82 |
|
| 83 | 83 |
// Create an IfInfomsg with family specified |
| 84 | 84 |
func NewIfInfomsg(family int) *IfInfomsg {
|
| 85 | 85 |
return &IfInfomsg{
|
| 86 |
- IfInfomsg: syscall.IfInfomsg{
|
|
| 86 |
+ IfInfomsg: unix.IfInfomsg{
|
|
| 87 | 87 |
Family: uint8(family), |
| 88 | 88 |
}, |
| 89 | 89 |
} |
| 90 | 90 |
} |
| 91 | 91 |
|
| 92 | 92 |
func DeserializeIfInfomsg(b []byte) *IfInfomsg {
|
| 93 |
- return (*IfInfomsg)(unsafe.Pointer(&b[0:syscall.SizeofIfInfomsg][0])) |
|
| 93 |
+ return (*IfInfomsg)(unsafe.Pointer(&b[0:unix.SizeofIfInfomsg][0])) |
|
| 94 | 94 |
} |
| 95 | 95 |
|
| 96 | 96 |
func (msg *IfInfomsg) Serialize() []byte {
|
| 97 |
- return (*(*[syscall.SizeofIfInfomsg]byte)(unsafe.Pointer(msg)))[:] |
|
| 97 |
+ return (*(*[unix.SizeofIfInfomsg]byte)(unsafe.Pointer(msg)))[:] |
|
| 98 | 98 |
} |
| 99 | 99 |
|
| 100 | 100 |
func (msg *IfInfomsg) Len() int {
|
| 101 |
- return syscall.SizeofIfInfomsg |
|
| 101 |
+ return unix.SizeofIfInfomsg |
|
| 102 | 102 |
} |
| 103 | 103 |
|
| 104 | 104 |
func (msg *IfInfomsg) EncapType() string {
|
| 105 | 105 |
switch msg.Type {
|
| 106 | 106 |
case 0: |
| 107 | 107 |
return "generic" |
| 108 |
- case syscall.ARPHRD_ETHER: |
|
| 108 |
+ case unix.ARPHRD_ETHER: |
|
| 109 | 109 |
return "ether" |
| 110 |
- case syscall.ARPHRD_EETHER: |
|
| 110 |
+ case unix.ARPHRD_EETHER: |
|
| 111 | 111 |
return "eether" |
| 112 |
- case syscall.ARPHRD_AX25: |
|
| 112 |
+ case unix.ARPHRD_AX25: |
|
| 113 | 113 |
return "ax25" |
| 114 |
- case syscall.ARPHRD_PRONET: |
|
| 114 |
+ case unix.ARPHRD_PRONET: |
|
| 115 | 115 |
return "pronet" |
| 116 |
- case syscall.ARPHRD_CHAOS: |
|
| 116 |
+ case unix.ARPHRD_CHAOS: |
|
| 117 | 117 |
return "chaos" |
| 118 |
- case syscall.ARPHRD_IEEE802: |
|
| 118 |
+ case unix.ARPHRD_IEEE802: |
|
| 119 | 119 |
return "ieee802" |
| 120 |
- case syscall.ARPHRD_ARCNET: |
|
| 120 |
+ case unix.ARPHRD_ARCNET: |
|
| 121 | 121 |
return "arcnet" |
| 122 |
- case syscall.ARPHRD_APPLETLK: |
|
| 122 |
+ case unix.ARPHRD_APPLETLK: |
|
| 123 | 123 |
return "atalk" |
| 124 |
- case syscall.ARPHRD_DLCI: |
|
| 124 |
+ case unix.ARPHRD_DLCI: |
|
| 125 | 125 |
return "dlci" |
| 126 |
- case syscall.ARPHRD_ATM: |
|
| 126 |
+ case unix.ARPHRD_ATM: |
|
| 127 | 127 |
return "atm" |
| 128 |
- case syscall.ARPHRD_METRICOM: |
|
| 128 |
+ case unix.ARPHRD_METRICOM: |
|
| 129 | 129 |
return "metricom" |
| 130 |
- case syscall.ARPHRD_IEEE1394: |
|
| 130 |
+ case unix.ARPHRD_IEEE1394: |
|
| 131 | 131 |
return "ieee1394" |
| 132 |
- case syscall.ARPHRD_INFINIBAND: |
|
| 132 |
+ case unix.ARPHRD_INFINIBAND: |
|
| 133 | 133 |
return "infiniband" |
| 134 |
- case syscall.ARPHRD_SLIP: |
|
| 134 |
+ case unix.ARPHRD_SLIP: |
|
| 135 | 135 |
return "slip" |
| 136 |
- case syscall.ARPHRD_CSLIP: |
|
| 136 |
+ case unix.ARPHRD_CSLIP: |
|
| 137 | 137 |
return "cslip" |
| 138 |
- case syscall.ARPHRD_SLIP6: |
|
| 138 |
+ case unix.ARPHRD_SLIP6: |
|
| 139 | 139 |
return "slip6" |
| 140 |
- case syscall.ARPHRD_CSLIP6: |
|
| 140 |
+ case unix.ARPHRD_CSLIP6: |
|
| 141 | 141 |
return "cslip6" |
| 142 |
- case syscall.ARPHRD_RSRVD: |
|
| 142 |
+ case unix.ARPHRD_RSRVD: |
|
| 143 | 143 |
return "rsrvd" |
| 144 |
- case syscall.ARPHRD_ADAPT: |
|
| 144 |
+ case unix.ARPHRD_ADAPT: |
|
| 145 | 145 |
return "adapt" |
| 146 |
- case syscall.ARPHRD_ROSE: |
|
| 146 |
+ case unix.ARPHRD_ROSE: |
|
| 147 | 147 |
return "rose" |
| 148 |
- case syscall.ARPHRD_X25: |
|
| 148 |
+ case unix.ARPHRD_X25: |
|
| 149 | 149 |
return "x25" |
| 150 |
- case syscall.ARPHRD_HWX25: |
|
| 150 |
+ case unix.ARPHRD_HWX25: |
|
| 151 | 151 |
return "hwx25" |
| 152 |
- case syscall.ARPHRD_PPP: |
|
| 152 |
+ case unix.ARPHRD_PPP: |
|
| 153 | 153 |
return "ppp" |
| 154 |
- case syscall.ARPHRD_HDLC: |
|
| 154 |
+ case unix.ARPHRD_HDLC: |
|
| 155 | 155 |
return "hdlc" |
| 156 |
- case syscall.ARPHRD_LAPB: |
|
| 156 |
+ case unix.ARPHRD_LAPB: |
|
| 157 | 157 |
return "lapb" |
| 158 |
- case syscall.ARPHRD_DDCMP: |
|
| 158 |
+ case unix.ARPHRD_DDCMP: |
|
| 159 | 159 |
return "ddcmp" |
| 160 |
- case syscall.ARPHRD_RAWHDLC: |
|
| 160 |
+ case unix.ARPHRD_RAWHDLC: |
|
| 161 | 161 |
return "rawhdlc" |
| 162 |
- case syscall.ARPHRD_TUNNEL: |
|
| 162 |
+ case unix.ARPHRD_TUNNEL: |
|
| 163 | 163 |
return "ipip" |
| 164 |
- case syscall.ARPHRD_TUNNEL6: |
|
| 164 |
+ case unix.ARPHRD_TUNNEL6: |
|
| 165 | 165 |
return "tunnel6" |
| 166 |
- case syscall.ARPHRD_FRAD: |
|
| 166 |
+ case unix.ARPHRD_FRAD: |
|
| 167 | 167 |
return "frad" |
| 168 |
- case syscall.ARPHRD_SKIP: |
|
| 168 |
+ case unix.ARPHRD_SKIP: |
|
| 169 | 169 |
return "skip" |
| 170 |
- case syscall.ARPHRD_LOOPBACK: |
|
| 170 |
+ case unix.ARPHRD_LOOPBACK: |
|
| 171 | 171 |
return "loopback" |
| 172 |
- case syscall.ARPHRD_LOCALTLK: |
|
| 172 |
+ case unix.ARPHRD_LOCALTLK: |
|
| 173 | 173 |
return "ltalk" |
| 174 |
- case syscall.ARPHRD_FDDI: |
|
| 174 |
+ case unix.ARPHRD_FDDI: |
|
| 175 | 175 |
return "fddi" |
| 176 |
- case syscall.ARPHRD_BIF: |
|
| 176 |
+ case unix.ARPHRD_BIF: |
|
| 177 | 177 |
return "bif" |
| 178 |
- case syscall.ARPHRD_SIT: |
|
| 178 |
+ case unix.ARPHRD_SIT: |
|
| 179 | 179 |
return "sit" |
| 180 |
- case syscall.ARPHRD_IPDDP: |
|
| 180 |
+ case unix.ARPHRD_IPDDP: |
|
| 181 | 181 |
return "ip/ddp" |
| 182 |
- case syscall.ARPHRD_IPGRE: |
|
| 182 |
+ case unix.ARPHRD_IPGRE: |
|
| 183 | 183 |
return "gre" |
| 184 |
- case syscall.ARPHRD_PIMREG: |
|
| 184 |
+ case unix.ARPHRD_PIMREG: |
|
| 185 | 185 |
return "pimreg" |
| 186 |
- case syscall.ARPHRD_HIPPI: |
|
| 186 |
+ case unix.ARPHRD_HIPPI: |
|
| 187 | 187 |
return "hippi" |
| 188 |
- case syscall.ARPHRD_ASH: |
|
| 188 |
+ case unix.ARPHRD_ASH: |
|
| 189 | 189 |
return "ash" |
| 190 |
- case syscall.ARPHRD_ECONET: |
|
| 190 |
+ case unix.ARPHRD_ECONET: |
|
| 191 | 191 |
return "econet" |
| 192 |
- case syscall.ARPHRD_IRDA: |
|
| 192 |
+ case unix.ARPHRD_IRDA: |
|
| 193 | 193 |
return "irda" |
| 194 |
- case syscall.ARPHRD_FCPP: |
|
| 194 |
+ case unix.ARPHRD_FCPP: |
|
| 195 | 195 |
return "fcpp" |
| 196 |
- case syscall.ARPHRD_FCAL: |
|
| 196 |
+ case unix.ARPHRD_FCAL: |
|
| 197 | 197 |
return "fcal" |
| 198 |
- case syscall.ARPHRD_FCPL: |
|
| 198 |
+ case unix.ARPHRD_FCPL: |
|
| 199 | 199 |
return "fcpl" |
| 200 |
- case syscall.ARPHRD_FCFABRIC: |
|
| 200 |
+ case unix.ARPHRD_FCFABRIC: |
|
| 201 | 201 |
return "fcfb0" |
| 202 |
- case syscall.ARPHRD_FCFABRIC + 1: |
|
| 202 |
+ case unix.ARPHRD_FCFABRIC + 1: |
|
| 203 | 203 |
return "fcfb1" |
| 204 |
- case syscall.ARPHRD_FCFABRIC + 2: |
|
| 204 |
+ case unix.ARPHRD_FCFABRIC + 2: |
|
| 205 | 205 |
return "fcfb2" |
| 206 |
- case syscall.ARPHRD_FCFABRIC + 3: |
|
| 206 |
+ case unix.ARPHRD_FCFABRIC + 3: |
|
| 207 | 207 |
return "fcfb3" |
| 208 |
- case syscall.ARPHRD_FCFABRIC + 4: |
|
| 208 |
+ case unix.ARPHRD_FCFABRIC + 4: |
|
| 209 | 209 |
return "fcfb4" |
| 210 |
- case syscall.ARPHRD_FCFABRIC + 5: |
|
| 210 |
+ case unix.ARPHRD_FCFABRIC + 5: |
|
| 211 | 211 |
return "fcfb5" |
| 212 |
- case syscall.ARPHRD_FCFABRIC + 6: |
|
| 212 |
+ case unix.ARPHRD_FCFABRIC + 6: |
|
| 213 | 213 |
return "fcfb6" |
| 214 |
- case syscall.ARPHRD_FCFABRIC + 7: |
|
| 214 |
+ case unix.ARPHRD_FCFABRIC + 7: |
|
| 215 | 215 |
return "fcfb7" |
| 216 |
- case syscall.ARPHRD_FCFABRIC + 8: |
|
| 216 |
+ case unix.ARPHRD_FCFABRIC + 8: |
|
| 217 | 217 |
return "fcfb8" |
| 218 |
- case syscall.ARPHRD_FCFABRIC + 9: |
|
| 218 |
+ case unix.ARPHRD_FCFABRIC + 9: |
|
| 219 | 219 |
return "fcfb9" |
| 220 |
- case syscall.ARPHRD_FCFABRIC + 10: |
|
| 220 |
+ case unix.ARPHRD_FCFABRIC + 10: |
|
| 221 | 221 |
return "fcfb10" |
| 222 |
- case syscall.ARPHRD_FCFABRIC + 11: |
|
| 222 |
+ case unix.ARPHRD_FCFABRIC + 11: |
|
| 223 | 223 |
return "fcfb11" |
| 224 |
- case syscall.ARPHRD_FCFABRIC + 12: |
|
| 224 |
+ case unix.ARPHRD_FCFABRIC + 12: |
|
| 225 | 225 |
return "fcfb12" |
| 226 |
- case syscall.ARPHRD_IEEE802_TR: |
|
| 226 |
+ case unix.ARPHRD_IEEE802_TR: |
|
| 227 | 227 |
return "tr" |
| 228 |
- case syscall.ARPHRD_IEEE80211: |
|
| 228 |
+ case unix.ARPHRD_IEEE80211: |
|
| 229 | 229 |
return "ieee802.11" |
| 230 |
- case syscall.ARPHRD_IEEE80211_PRISM: |
|
| 230 |
+ case unix.ARPHRD_IEEE80211_PRISM: |
|
| 231 | 231 |
return "ieee802.11/prism" |
| 232 |
- case syscall.ARPHRD_IEEE80211_RADIOTAP: |
|
| 232 |
+ case unix.ARPHRD_IEEE80211_RADIOTAP: |
|
| 233 | 233 |
return "ieee802.11/radiotap" |
| 234 |
- case syscall.ARPHRD_IEEE802154: |
|
| 234 |
+ case unix.ARPHRD_IEEE802154: |
|
| 235 | 235 |
return "ieee802.15.4" |
| 236 | 236 |
|
| 237 | 237 |
case 65534: |
| ... | ... |
@@ -243,7 +244,7 @@ func (msg *IfInfomsg) EncapType() string {
|
| 243 | 243 |
} |
| 244 | 244 |
|
| 245 | 245 |
func rtaAlignOf(attrlen int) int {
|
| 246 |
- return (attrlen + syscall.RTA_ALIGNTO - 1) & ^(syscall.RTA_ALIGNTO - 1) |
|
| 246 |
+ return (attrlen + unix.RTA_ALIGNTO - 1) & ^(unix.RTA_ALIGNTO - 1) |
|
| 247 | 247 |
} |
| 248 | 248 |
|
| 249 | 249 |
func NewIfInfomsgChild(parent *RtAttr, family int) *IfInfomsg {
|
| ... | ... |
@@ -254,7 +255,7 @@ func NewIfInfomsgChild(parent *RtAttr, family int) *IfInfomsg {
|
| 254 | 254 |
|
| 255 | 255 |
// Extend RtAttr to handle data and children |
| 256 | 256 |
type RtAttr struct {
|
| 257 |
- syscall.RtAttr |
|
| 257 |
+ unix.RtAttr |
|
| 258 | 258 |
Data []byte |
| 259 | 259 |
children []NetlinkRequestData |
| 260 | 260 |
} |
| ... | ... |
@@ -262,7 +263,7 @@ type RtAttr struct {
|
| 262 | 262 |
// Create a new Extended RtAttr object |
| 263 | 263 |
func NewRtAttr(attrType int, data []byte) *RtAttr {
|
| 264 | 264 |
return &RtAttr{
|
| 265 |
- RtAttr: syscall.RtAttr{
|
|
| 265 |
+ RtAttr: unix.RtAttr{
|
|
| 266 | 266 |
Type: uint16(attrType), |
| 267 | 267 |
}, |
| 268 | 268 |
children: []NetlinkRequestData{},
|
| ... | ... |
@@ -277,16 +278,21 @@ func NewRtAttrChild(parent *RtAttr, attrType int, data []byte) *RtAttr {
|
| 277 | 277 |
return attr |
| 278 | 278 |
} |
| 279 | 279 |
|
| 280 |
+// AddChild adds an existing RtAttr as a child. |
|
| 281 |
+func (a *RtAttr) AddChild(attr *RtAttr) {
|
|
| 282 |
+ a.children = append(a.children, attr) |
|
| 283 |
+} |
|
| 284 |
+ |
|
| 280 | 285 |
func (a *RtAttr) Len() int {
|
| 281 | 286 |
if len(a.children) == 0 {
|
| 282 |
- return (syscall.SizeofRtAttr + len(a.Data)) |
|
| 287 |
+ return (unix.SizeofRtAttr + len(a.Data)) |
|
| 283 | 288 |
} |
| 284 | 289 |
|
| 285 | 290 |
l := 0 |
| 286 | 291 |
for _, child := range a.children {
|
| 287 | 292 |
l += rtaAlignOf(child.Len()) |
| 288 | 293 |
} |
| 289 |
- l += syscall.SizeofRtAttr |
|
| 294 |
+ l += unix.SizeofRtAttr |
|
| 290 | 295 |
return rtaAlignOf(l + len(a.Data)) |
| 291 | 296 |
} |
| 292 | 297 |
|
| ... | ... |
@@ -319,7 +325,7 @@ func (a *RtAttr) Serialize() []byte {
|
| 319 | 319 |
} |
| 320 | 320 |
|
| 321 | 321 |
type NetlinkRequest struct {
|
| 322 |
- syscall.NlMsghdr |
|
| 322 |
+ unix.NlMsghdr |
|
| 323 | 323 |
Data []NetlinkRequestData |
| 324 | 324 |
RawData []byte |
| 325 | 325 |
Sockets map[int]*SocketHandle |
| ... | ... |
@@ -327,7 +333,7 @@ type NetlinkRequest struct {
|
| 327 | 327 |
|
| 328 | 328 |
// Serialize the Netlink Request into a byte array |
| 329 | 329 |
func (req *NetlinkRequest) Serialize() []byte {
|
| 330 |
- length := syscall.SizeofNlMsghdr |
|
| 330 |
+ length := unix.SizeofNlMsghdr |
|
| 331 | 331 |
dataBytes := make([][]byte, len(req.Data)) |
| 332 | 332 |
for i, data := range req.Data {
|
| 333 | 333 |
dataBytes[i] = data.Serialize() |
| ... | ... |
@@ -337,8 +343,8 @@ func (req *NetlinkRequest) Serialize() []byte {
|
| 337 | 337 |
|
| 338 | 338 |
req.Len = uint32(length) |
| 339 | 339 |
b := make([]byte, length) |
| 340 |
- hdr := (*(*[syscall.SizeofNlMsghdr]byte)(unsafe.Pointer(req)))[:] |
|
| 341 |
- next := syscall.SizeofNlMsghdr |
|
| 340 |
+ hdr := (*(*[unix.SizeofNlMsghdr]byte)(unsafe.Pointer(req)))[:] |
|
| 341 |
+ next := unix.SizeofNlMsghdr |
|
| 342 | 342 |
copy(b[0:next], hdr) |
| 343 | 343 |
for _, data := range dataBytes {
|
| 344 | 344 |
for _, dataByte := range data {
|
| ... | ... |
@@ -421,10 +427,10 @@ done: |
| 421 | 421 |
if m.Header.Pid != pid {
|
| 422 | 422 |
return nil, fmt.Errorf("Wrong pid %d, expected %d", m.Header.Pid, pid)
|
| 423 | 423 |
} |
| 424 |
- if m.Header.Type == syscall.NLMSG_DONE {
|
|
| 424 |
+ if m.Header.Type == unix.NLMSG_DONE {
|
|
| 425 | 425 |
break done |
| 426 | 426 |
} |
| 427 |
- if m.Header.Type == syscall.NLMSG_ERROR {
|
|
| 427 |
+ if m.Header.Type == unix.NLMSG_ERROR {
|
|
| 428 | 428 |
native := NativeEndian() |
| 429 | 429 |
error := int32(native.Uint32(m.Data[0:4])) |
| 430 | 430 |
if error == 0 {
|
| ... | ... |
@@ -436,7 +442,7 @@ done: |
| 436 | 436 |
continue |
| 437 | 437 |
} |
| 438 | 438 |
res = append(res, m.Data) |
| 439 |
- if m.Header.Flags&syscall.NLM_F_MULTI == 0 {
|
|
| 439 |
+ if m.Header.Flags&unix.NLM_F_MULTI == 0 {
|
|
| 440 | 440 |
break done |
| 441 | 441 |
} |
| 442 | 442 |
} |
| ... | ... |
@@ -449,10 +455,10 @@ done: |
| 449 | 449 |
// the message is serialized |
| 450 | 450 |
func NewNetlinkRequest(proto, flags int) *NetlinkRequest {
|
| 451 | 451 |
return &NetlinkRequest{
|
| 452 |
- NlMsghdr: syscall.NlMsghdr{
|
|
| 453 |
- Len: uint32(syscall.SizeofNlMsghdr), |
|
| 452 |
+ NlMsghdr: unix.NlMsghdr{
|
|
| 453 |
+ Len: uint32(unix.SizeofNlMsghdr), |
|
| 454 | 454 |
Type: uint16(proto), |
| 455 |
- Flags: syscall.NLM_F_REQUEST | uint16(flags), |
|
| 455 |
+ Flags: unix.NLM_F_REQUEST | uint16(flags), |
|
| 456 | 456 |
Seq: atomic.AddUint32(&nextSeqNr, 1), |
| 457 | 457 |
}, |
| 458 | 458 |
} |
| ... | ... |
@@ -460,21 +466,21 @@ func NewNetlinkRequest(proto, flags int) *NetlinkRequest {
|
| 460 | 460 |
|
| 461 | 461 |
type NetlinkSocket struct {
|
| 462 | 462 |
fd int32 |
| 463 |
- lsa syscall.SockaddrNetlink |
|
| 463 |
+ lsa unix.SockaddrNetlink |
|
| 464 | 464 |
sync.Mutex |
| 465 | 465 |
} |
| 466 | 466 |
|
| 467 | 467 |
func getNetlinkSocket(protocol int) (*NetlinkSocket, error) {
|
| 468 |
- fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW|syscall.SOCK_CLOEXEC, protocol) |
|
| 468 |
+ fd, err := unix.Socket(unix.AF_NETLINK, unix.SOCK_RAW|unix.SOCK_CLOEXEC, protocol) |
|
| 469 | 469 |
if err != nil {
|
| 470 | 470 |
return nil, err |
| 471 | 471 |
} |
| 472 | 472 |
s := &NetlinkSocket{
|
| 473 | 473 |
fd: int32(fd), |
| 474 | 474 |
} |
| 475 |
- s.lsa.Family = syscall.AF_NETLINK |
|
| 476 |
- if err := syscall.Bind(fd, &s.lsa); err != nil {
|
|
| 477 |
- syscall.Close(fd) |
|
| 475 |
+ s.lsa.Family = unix.AF_NETLINK |
|
| 476 |
+ if err := unix.Bind(fd, &s.lsa); err != nil {
|
|
| 477 |
+ unix.Close(fd) |
|
| 478 | 478 |
return nil, err |
| 479 | 479 |
} |
| 480 | 480 |
|
| ... | ... |
@@ -551,21 +557,21 @@ func executeInNetns(newNs, curNs netns.NsHandle) (func(), error) {
|
| 551 | 551 |
// Returns the netlink socket on which Receive() method can be called |
| 552 | 552 |
// to retrieve the messages from the kernel. |
| 553 | 553 |
func Subscribe(protocol int, groups ...uint) (*NetlinkSocket, error) {
|
| 554 |
- fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, protocol) |
|
| 554 |
+ fd, err := unix.Socket(unix.AF_NETLINK, unix.SOCK_RAW, protocol) |
|
| 555 | 555 |
if err != nil {
|
| 556 | 556 |
return nil, err |
| 557 | 557 |
} |
| 558 | 558 |
s := &NetlinkSocket{
|
| 559 | 559 |
fd: int32(fd), |
| 560 | 560 |
} |
| 561 |
- s.lsa.Family = syscall.AF_NETLINK |
|
| 561 |
+ s.lsa.Family = unix.AF_NETLINK |
|
| 562 | 562 |
|
| 563 | 563 |
for _, g := range groups {
|
| 564 | 564 |
s.lsa.Groups |= (1 << (g - 1)) |
| 565 | 565 |
} |
| 566 | 566 |
|
| 567 |
- if err := syscall.Bind(fd, &s.lsa); err != nil {
|
|
| 568 |
- syscall.Close(fd) |
|
| 567 |
+ if err := unix.Bind(fd, &s.lsa); err != nil {
|
|
| 568 |
+ unix.Close(fd) |
|
| 569 | 569 |
return nil, err |
| 570 | 570 |
} |
| 571 | 571 |
|
| ... | ... |
@@ -586,7 +592,7 @@ func SubscribeAt(newNs, curNs netns.NsHandle, protocol int, groups ...uint) (*Ne |
| 586 | 586 |
|
| 587 | 587 |
func (s *NetlinkSocket) Close() {
|
| 588 | 588 |
fd := int(atomic.SwapInt32(&s.fd, -1)) |
| 589 |
- syscall.Close(fd) |
|
| 589 |
+ unix.Close(fd) |
|
| 590 | 590 |
} |
| 591 | 591 |
|
| 592 | 592 |
func (s *NetlinkSocket) GetFd() int {
|
| ... | ... |
@@ -598,7 +604,7 @@ func (s *NetlinkSocket) Send(request *NetlinkRequest) error {
|
| 598 | 598 |
if fd < 0 {
|
| 599 | 599 |
return fmt.Errorf("Send called on a closed socket")
|
| 600 | 600 |
} |
| 601 |
- if err := syscall.Sendto(fd, request.Serialize(), 0, &s.lsa); err != nil {
|
|
| 601 |
+ if err := unix.Sendto(fd, request.Serialize(), 0, &s.lsa); err != nil {
|
|
| 602 | 602 |
return err |
| 603 | 603 |
} |
| 604 | 604 |
return nil |
| ... | ... |
@@ -609,12 +615,12 @@ func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, error) {
|
| 609 | 609 |
if fd < 0 {
|
| 610 | 610 |
return nil, fmt.Errorf("Receive called on a closed socket")
|
| 611 | 611 |
} |
| 612 |
- rb := make([]byte, syscall.Getpagesize()) |
|
| 613 |
- nr, _, err := syscall.Recvfrom(fd, rb, 0) |
|
| 612 |
+ rb := make([]byte, unix.Getpagesize()) |
|
| 613 |
+ nr, _, err := unix.Recvfrom(fd, rb, 0) |
|
| 614 | 614 |
if err != nil {
|
| 615 | 615 |
return nil, err |
| 616 | 616 |
} |
| 617 |
- if nr < syscall.NLMSG_HDRLEN {
|
|
| 617 |
+ if nr < unix.NLMSG_HDRLEN {
|
|
| 618 | 618 |
return nil, fmt.Errorf("Got short response from netlink")
|
| 619 | 619 |
} |
| 620 | 620 |
rb = rb[:nr] |
| ... | ... |
@@ -622,27 +628,27 @@ func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, error) {
|
| 622 | 622 |
} |
| 623 | 623 |
|
| 624 | 624 |
// SetSendTimeout allows to set a send timeout on the socket |
| 625 |
-func (s *NetlinkSocket) SetSendTimeout(timeout *syscall.Timeval) error {
|
|
| 625 |
+func (s *NetlinkSocket) SetSendTimeout(timeout *unix.Timeval) error {
|
|
| 626 | 626 |
// Set a send timeout of SOCKET_SEND_TIMEOUT, this will allow the Send to periodically unblock and avoid that a routine |
| 627 | 627 |
// remains stuck on a send on a closed fd |
| 628 |
- return syscall.SetsockoptTimeval(int(s.fd), syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, timeout) |
|
| 628 |
+ return unix.SetsockoptTimeval(int(s.fd), unix.SOL_SOCKET, unix.SO_SNDTIMEO, timeout) |
|
| 629 | 629 |
} |
| 630 | 630 |
|
| 631 | 631 |
// SetReceiveTimeout allows to set a receive timeout on the socket |
| 632 |
-func (s *NetlinkSocket) SetReceiveTimeout(timeout *syscall.Timeval) error {
|
|
| 632 |
+func (s *NetlinkSocket) SetReceiveTimeout(timeout *unix.Timeval) error {
|
|
| 633 | 633 |
// Set a read timeout of SOCKET_READ_TIMEOUT, this will allow the Read to periodically unblock and avoid that a routine |
| 634 | 634 |
// remains stuck on a recvmsg on a closed fd |
| 635 |
- return syscall.SetsockoptTimeval(int(s.fd), syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, timeout) |
|
| 635 |
+ return unix.SetsockoptTimeval(int(s.fd), unix.SOL_SOCKET, unix.SO_RCVTIMEO, timeout) |
|
| 636 | 636 |
} |
| 637 | 637 |
|
| 638 | 638 |
func (s *NetlinkSocket) GetPid() (uint32, error) {
|
| 639 | 639 |
fd := int(atomic.LoadInt32(&s.fd)) |
| 640 |
- lsa, err := syscall.Getsockname(fd) |
|
| 640 |
+ lsa, err := unix.Getsockname(fd) |
|
| 641 | 641 |
if err != nil {
|
| 642 | 642 |
return 0, err |
| 643 | 643 |
} |
| 644 | 644 |
switch v := lsa.(type) {
|
| 645 |
- case *syscall.SockaddrNetlink: |
|
| 645 |
+ case *unix.SockaddrNetlink: |
|
| 646 | 646 |
return v.Pid, nil |
| 647 | 647 |
} |
| 648 | 648 |
return 0, fmt.Errorf("Wrong socket type")
|
| ... | ... |
@@ -697,24 +703,24 @@ func Uint64Attr(v uint64) []byte {
|
| 697 | 697 |
|
| 698 | 698 |
func ParseRouteAttr(b []byte) ([]syscall.NetlinkRouteAttr, error) {
|
| 699 | 699 |
var attrs []syscall.NetlinkRouteAttr |
| 700 |
- for len(b) >= syscall.SizeofRtAttr {
|
|
| 700 |
+ for len(b) >= unix.SizeofRtAttr {
|
|
| 701 | 701 |
a, vbuf, alen, err := netlinkRouteAttrAndValue(b) |
| 702 | 702 |
if err != nil {
|
| 703 | 703 |
return nil, err |
| 704 | 704 |
} |
| 705 |
- ra := syscall.NetlinkRouteAttr{Attr: *a, Value: vbuf[:int(a.Len)-syscall.SizeofRtAttr]}
|
|
| 705 |
+ ra := syscall.NetlinkRouteAttr{Attr: syscall.RtAttr(*a), Value: vbuf[:int(a.Len)-unix.SizeofRtAttr]}
|
|
| 706 | 706 |
attrs = append(attrs, ra) |
| 707 | 707 |
b = b[alen:] |
| 708 | 708 |
} |
| 709 | 709 |
return attrs, nil |
| 710 | 710 |
} |
| 711 | 711 |
|
| 712 |
-func netlinkRouteAttrAndValue(b []byte) (*syscall.RtAttr, []byte, int, error) {
|
|
| 713 |
- a := (*syscall.RtAttr)(unsafe.Pointer(&b[0])) |
|
| 714 |
- if int(a.Len) < syscall.SizeofRtAttr || int(a.Len) > len(b) {
|
|
| 715 |
- return nil, nil, 0, syscall.EINVAL |
|
| 712 |
+func netlinkRouteAttrAndValue(b []byte) (*unix.RtAttr, []byte, int, error) {
|
|
| 713 |
+ a := (*unix.RtAttr)(unsafe.Pointer(&b[0])) |
|
| 714 |
+ if int(a.Len) < unix.SizeofRtAttr || int(a.Len) > len(b) {
|
|
| 715 |
+ return nil, nil, 0, unix.EINVAL |
|
| 716 | 716 |
} |
| 717 |
- return a, b[syscall.SizeofRtAttr:], rtaAlignOf(int(a.Len)), nil |
|
| 717 |
+ return a, b[unix.SizeofRtAttr:], rtaAlignOf(int(a.Len)), nil |
|
| 718 | 718 |
} |
| 719 | 719 |
|
| 720 | 720 |
// SocketHandle contains the netlink socket and the associated |
| ... | ... |
@@ -1,65 +1,66 @@ |
| 1 | 1 |
package nl |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "syscall" |
|
| 5 | 4 |
"unsafe" |
| 5 |
+ |
|
| 6 |
+ "golang.org/x/sys/unix" |
|
| 6 | 7 |
) |
| 7 | 8 |
|
| 8 | 9 |
type RtMsg struct {
|
| 9 |
- syscall.RtMsg |
|
| 10 |
+ unix.RtMsg |
|
| 10 | 11 |
} |
| 11 | 12 |
|
| 12 | 13 |
func NewRtMsg() *RtMsg {
|
| 13 | 14 |
return &RtMsg{
|
| 14 |
- RtMsg: syscall.RtMsg{
|
|
| 15 |
- Table: syscall.RT_TABLE_MAIN, |
|
| 16 |
- Scope: syscall.RT_SCOPE_UNIVERSE, |
|
| 17 |
- Protocol: syscall.RTPROT_BOOT, |
|
| 18 |
- Type: syscall.RTN_UNICAST, |
|
| 15 |
+ RtMsg: unix.RtMsg{
|
|
| 16 |
+ Table: unix.RT_TABLE_MAIN, |
|
| 17 |
+ Scope: unix.RT_SCOPE_UNIVERSE, |
|
| 18 |
+ Protocol: unix.RTPROT_BOOT, |
|
| 19 |
+ Type: unix.RTN_UNICAST, |
|
| 19 | 20 |
}, |
| 20 | 21 |
} |
| 21 | 22 |
} |
| 22 | 23 |
|
| 23 | 24 |
func NewRtDelMsg() *RtMsg {
|
| 24 | 25 |
return &RtMsg{
|
| 25 |
- RtMsg: syscall.RtMsg{
|
|
| 26 |
- Table: syscall.RT_TABLE_MAIN, |
|
| 27 |
- Scope: syscall.RT_SCOPE_NOWHERE, |
|
| 26 |
+ RtMsg: unix.RtMsg{
|
|
| 27 |
+ Table: unix.RT_TABLE_MAIN, |
|
| 28 |
+ Scope: unix.RT_SCOPE_NOWHERE, |
|
| 28 | 29 |
}, |
| 29 | 30 |
} |
| 30 | 31 |
} |
| 31 | 32 |
|
| 32 | 33 |
func (msg *RtMsg) Len() int {
|
| 33 |
- return syscall.SizeofRtMsg |
|
| 34 |
+ return unix.SizeofRtMsg |
|
| 34 | 35 |
} |
| 35 | 36 |
|
| 36 | 37 |
func DeserializeRtMsg(b []byte) *RtMsg {
|
| 37 |
- return (*RtMsg)(unsafe.Pointer(&b[0:syscall.SizeofRtMsg][0])) |
|
| 38 |
+ return (*RtMsg)(unsafe.Pointer(&b[0:unix.SizeofRtMsg][0])) |
|
| 38 | 39 |
} |
| 39 | 40 |
|
| 40 | 41 |
func (msg *RtMsg) Serialize() []byte {
|
| 41 |
- return (*(*[syscall.SizeofRtMsg]byte)(unsafe.Pointer(msg)))[:] |
|
| 42 |
+ return (*(*[unix.SizeofRtMsg]byte)(unsafe.Pointer(msg)))[:] |
|
| 42 | 43 |
} |
| 43 | 44 |
|
| 44 | 45 |
type RtNexthop struct {
|
| 45 |
- syscall.RtNexthop |
|
| 46 |
+ unix.RtNexthop |
|
| 46 | 47 |
Children []NetlinkRequestData |
| 47 | 48 |
} |
| 48 | 49 |
|
| 49 | 50 |
func DeserializeRtNexthop(b []byte) *RtNexthop {
|
| 50 |
- return (*RtNexthop)(unsafe.Pointer(&b[0:syscall.SizeofRtNexthop][0])) |
|
| 51 |
+ return (*RtNexthop)(unsafe.Pointer(&b[0:unix.SizeofRtNexthop][0])) |
|
| 51 | 52 |
} |
| 52 | 53 |
|
| 53 | 54 |
func (msg *RtNexthop) Len() int {
|
| 54 | 55 |
if len(msg.Children) == 0 {
|
| 55 |
- return syscall.SizeofRtNexthop |
|
| 56 |
+ return unix.SizeofRtNexthop |
|
| 56 | 57 |
} |
| 57 | 58 |
|
| 58 | 59 |
l := 0 |
| 59 | 60 |
for _, child := range msg.Children {
|
| 60 | 61 |
l += rtaAlignOf(child.Len()) |
| 61 | 62 |
} |
| 62 |
- l += syscall.SizeofRtNexthop |
|
| 63 |
+ l += unix.SizeofRtNexthop |
|
| 63 | 64 |
return rtaAlignOf(l) |
| 64 | 65 |
} |
| 65 | 66 |
|
| ... | ... |
@@ -67,8 +68,8 @@ func (msg *RtNexthop) Serialize() []byte {
|
| 67 | 67 |
length := msg.Len() |
| 68 | 68 |
msg.RtNexthop.Len = uint16(length) |
| 69 | 69 |
buf := make([]byte, length) |
| 70 |
- copy(buf, (*(*[syscall.SizeofRtNexthop]byte)(unsafe.Pointer(msg)))[:]) |
|
| 71 |
- next := rtaAlignOf(syscall.SizeofRtNexthop) |
|
| 70 |
+ copy(buf, (*(*[unix.SizeofRtNexthop]byte)(unsafe.Pointer(msg)))[:]) |
|
| 71 |
+ next := rtaAlignOf(unix.SizeofRtNexthop) |
|
| 72 | 72 |
if len(msg.Children) > 0 {
|
| 73 | 73 |
for _, child := range msg.Children {
|
| 74 | 74 |
childBuf := child.Serialize() |
| 75 | 75 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,111 @@ |
| 0 |
+package nl |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "errors" |
|
| 4 |
+ "fmt" |
|
| 5 |
+ "net" |
|
| 6 |
+) |
|
| 7 |
+ |
|
| 8 |
+type IPv6SrHdr struct {
|
|
| 9 |
+ nextHdr uint8 |
|
| 10 |
+ hdrLen uint8 |
|
| 11 |
+ routingType uint8 |
|
| 12 |
+ segmentsLeft uint8 |
|
| 13 |
+ firstSegment uint8 |
|
| 14 |
+ flags uint8 |
|
| 15 |
+ reserved uint16 |
|
| 16 |
+ |
|
| 17 |
+ Segments []net.IP |
|
| 18 |
+} |
|
| 19 |
+ |
|
| 20 |
+func (s1 *IPv6SrHdr) Equal(s2 IPv6SrHdr) bool {
|
|
| 21 |
+ if len(s1.Segments) != len(s2.Segments) {
|
|
| 22 |
+ return false |
|
| 23 |
+ } |
|
| 24 |
+ for i := range s1.Segments {
|
|
| 25 |
+ if s1.Segments[i].Equal(s2.Segments[i]) != true {
|
|
| 26 |
+ return false |
|
| 27 |
+ } |
|
| 28 |
+ } |
|
| 29 |
+ return s1.nextHdr == s2.nextHdr && |
|
| 30 |
+ s1.hdrLen == s2.hdrLen && |
|
| 31 |
+ s1.routingType == s2.routingType && |
|
| 32 |
+ s1.segmentsLeft == s2.segmentsLeft && |
|
| 33 |
+ s1.firstSegment == s2.firstSegment && |
|
| 34 |
+ s1.flags == s2.flags |
|
| 35 |
+ // reserved doesn't need to be identical. |
|
| 36 |
+} |
|
| 37 |
+ |
|
| 38 |
+// seg6 encap mode |
|
| 39 |
+const ( |
|
| 40 |
+ SEG6_IPTUN_MODE_INLINE = iota |
|
| 41 |
+ SEG6_IPTUN_MODE_ENCAP |
|
| 42 |
+) |
|
| 43 |
+ |
|
| 44 |
+// number of nested RTATTR |
|
| 45 |
+// from include/uapi/linux/seg6_iptunnel.h |
|
| 46 |
+const ( |
|
| 47 |
+ SEG6_IPTUNNEL_UNSPEC = iota |
|
| 48 |
+ SEG6_IPTUNNEL_SRH |
|
| 49 |
+ __SEG6_IPTUNNEL_MAX |
|
| 50 |
+) |
|
| 51 |
+const ( |
|
| 52 |
+ SEG6_IPTUNNEL_MAX = __SEG6_IPTUNNEL_MAX - 1 |
|
| 53 |
+) |
|
| 54 |
+ |
|
| 55 |
+func EncodeSEG6Encap(mode int, segments []net.IP) ([]byte, error) {
|
|
| 56 |
+ nsegs := len(segments) // nsegs: number of segments |
|
| 57 |
+ if nsegs == 0 {
|
|
| 58 |
+ return nil, errors.New("EncodeSEG6Encap: No Segment in srh")
|
|
| 59 |
+ } |
|
| 60 |
+ b := make([]byte, 12, 12+len(segments)*16) |
|
| 61 |
+ native := NativeEndian() |
|
| 62 |
+ native.PutUint32(b, uint32(mode)) |
|
| 63 |
+ b[4] = 0 // srh.nextHdr (0 when calling netlink) |
|
| 64 |
+ b[5] = uint8(16 * nsegs >> 3) // srh.hdrLen (in 8-octets unit) |
|
| 65 |
+ b[6] = IPV6_SRCRT_TYPE_4 // srh.routingType (assigned by IANA) |
|
| 66 |
+ b[7] = uint8(nsegs - 1) // srh.segmentsLeft |
|
| 67 |
+ b[8] = uint8(nsegs - 1) // srh.firstSegment |
|
| 68 |
+ b[9] = 0 // srh.flags (SR6_FLAG1_HMAC for srh_hmac) |
|
| 69 |
+ // srh.reserved: Defined as "Tag" in draft-ietf-6man-segment-routing-header-07 |
|
| 70 |
+ native.PutUint16(b[10:], 0) // srh.reserved |
|
| 71 |
+ for _, netIP := range segments {
|
|
| 72 |
+ b = append(b, netIP...) // srh.Segments |
|
| 73 |
+ } |
|
| 74 |
+ return b, nil |
|
| 75 |
+} |
|
| 76 |
+ |
|
| 77 |
+func DecodeSEG6Encap(buf []byte) (int, []net.IP, error) {
|
|
| 78 |
+ native := NativeEndian() |
|
| 79 |
+ mode := int(native.Uint32(buf)) |
|
| 80 |
+ srh := IPv6SrHdr{
|
|
| 81 |
+ nextHdr: buf[4], |
|
| 82 |
+ hdrLen: buf[5], |
|
| 83 |
+ routingType: buf[6], |
|
| 84 |
+ segmentsLeft: buf[7], |
|
| 85 |
+ firstSegment: buf[8], |
|
| 86 |
+ flags: buf[9], |
|
| 87 |
+ reserved: native.Uint16(buf[10:12]), |
|
| 88 |
+ } |
|
| 89 |
+ buf = buf[12:] |
|
| 90 |
+ if len(buf)%16 != 0 {
|
|
| 91 |
+ err := fmt.Errorf("DecodeSEG6Encap: error parsing Segment List (buf len: %d)\n", len(buf))
|
|
| 92 |
+ return mode, nil, err |
|
| 93 |
+ } |
|
| 94 |
+ for len(buf) > 0 {
|
|
| 95 |
+ srh.Segments = append(srh.Segments, net.IP(buf[:16])) |
|
| 96 |
+ buf = buf[16:] |
|
| 97 |
+ } |
|
| 98 |
+ return mode, srh.Segments, nil |
|
| 99 |
+} |
|
| 100 |
+ |
|
| 101 |
+// Helper functions |
|
| 102 |
+func SEG6EncapModeString(mode int) string {
|
|
| 103 |
+ switch mode {
|
|
| 104 |
+ case SEG6_IPTUN_MODE_INLINE: |
|
| 105 |
+ return "inline" |
|
| 106 |
+ case SEG6_IPTUN_MODE_ENCAP: |
|
| 107 |
+ return "encap" |
|
| 108 |
+ } |
|
| 109 |
+ return "unknown" |
|
| 110 |
+} |
| ... | ... |
@@ -65,4 +65,14 @@ const ( |
| 65 | 65 |
LWTUNNEL_ENCAP_IP |
| 66 | 66 |
LWTUNNEL_ENCAP_ILA |
| 67 | 67 |
LWTUNNEL_ENCAP_IP6 |
| 68 |
+ LWTUNNEL_ENCAP_SEG6 |
|
| 69 |
+ LWTUNNEL_ENCAP_BPF |
|
| 70 |
+) |
|
| 71 |
+ |
|
| 72 |
+// routing header types |
|
| 73 |
+const ( |
|
| 74 |
+ IPV6_SRCRT_STRICT = 0x01 // Deprecated; will be removed |
|
| 75 |
+ IPV6_SRCRT_TYPE_0 = 0 // Deprecated; will be removed |
|
| 76 |
+ IPV6_SRCRT_TYPE_2 = 2 // IPv6 type 2 Routing Header |
|
| 77 |
+ IPV6_SRCRT_TYPE_4 = 4 // Segment Routing with IPv6 |
|
| 68 | 78 |
) |
| ... | ... |
@@ -673,3 +673,38 @@ const ( |
| 673 | 673 |
TCA_FW_MASK |
| 674 | 674 |
TCA_FW_MAX = TCA_FW_MASK |
| 675 | 675 |
) |
| 676 |
+ |
|
| 677 |
+const ( |
|
| 678 |
+ TCA_MATCHALL_UNSPEC = iota |
|
| 679 |
+ TCA_MATCHALL_CLASSID |
|
| 680 |
+ TCA_MATCHALL_ACT |
|
| 681 |
+ TCA_MATCHALL_FLAGS |
|
| 682 |
+) |
|
| 683 |
+ |
|
| 684 |
+const ( |
|
| 685 |
+ TCA_FQ_UNSPEC = iota |
|
| 686 |
+ TCA_FQ_PLIMIT // limit of total number of packets in queue |
|
| 687 |
+ TCA_FQ_FLOW_PLIMIT // limit of packets per flow |
|
| 688 |
+ TCA_FQ_QUANTUM // RR quantum |
|
| 689 |
+ TCA_FQ_INITIAL_QUANTUM // RR quantum for new flow |
|
| 690 |
+ TCA_FQ_RATE_ENABLE // enable/disable rate limiting |
|
| 691 |
+ TCA_FQ_FLOW_DEFAULT_RATE // obsolete do not use |
|
| 692 |
+ TCA_FQ_FLOW_MAX_RATE // per flow max rate |
|
| 693 |
+ TCA_FQ_BUCKETS_LOG // log2(number of buckets) |
|
| 694 |
+ TCA_FQ_FLOW_REFILL_DELAY // flow credit refill delay in usec |
|
| 695 |
+ TCA_FQ_ORPHAN_MASK // mask applied to orphaned skb hashes |
|
| 696 |
+ TCA_FQ_LOW_RATE_THRESHOLD // per packet delay under this rate |
|
| 697 |
+) |
|
| 698 |
+ |
|
| 699 |
+const ( |
|
| 700 |
+ TCA_FQ_CODEL_UNSPEC = iota |
|
| 701 |
+ TCA_FQ_CODEL_TARGET |
|
| 702 |
+ TCA_FQ_CODEL_LIMIT |
|
| 703 |
+ TCA_FQ_CODEL_INTERVAL |
|
| 704 |
+ TCA_FQ_CODEL_ECN |
|
| 705 |
+ TCA_FQ_CODEL_FLOWS |
|
| 706 |
+ TCA_FQ_CODEL_QUANTUM |
|
| 707 |
+ TCA_FQ_CODEL_CE_THRESHOLD |
|
| 708 |
+ TCA_FQ_CODEL_DROP_BATCH_SIZE |
|
| 709 |
+ TCA_FQ_CODEL_MEMORY_LIMIT |
|
| 710 |
+) |
| ... | ... |
@@ -5,6 +5,7 @@ import ( |
| 5 | 5 |
"syscall" |
| 6 | 6 |
|
| 7 | 7 |
"github.com/vishvananda/netlink/nl" |
| 8 |
+ "golang.org/x/sys/unix" |
|
| 8 | 9 |
) |
| 9 | 10 |
|
| 10 | 11 |
func LinkGetProtinfo(link Link) (Protinfo, error) {
|
| ... | ... |
@@ -15,10 +16,10 @@ func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) {
|
| 15 | 15 |
base := link.Attrs() |
| 16 | 16 |
h.ensureIndex(base) |
| 17 | 17 |
var pi Protinfo |
| 18 |
- req := h.newNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_DUMP) |
|
| 19 |
- msg := nl.NewIfInfomsg(syscall.AF_BRIDGE) |
|
| 18 |
+ req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_DUMP) |
|
| 19 |
+ msg := nl.NewIfInfomsg(unix.AF_BRIDGE) |
|
| 20 | 20 |
req.AddData(msg) |
| 21 |
- msgs, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 21 |
+ msgs, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 22 | 22 |
if err != nil {
|
| 23 | 23 |
return pi, err |
| 24 | 24 |
} |
| ... | ... |
@@ -33,7 +34,7 @@ func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) {
|
| 33 | 33 |
return pi, err |
| 34 | 34 |
} |
| 35 | 35 |
for _, attr := range attrs {
|
| 36 |
- if attr.Attr.Type != syscall.IFLA_PROTINFO|syscall.NLA_F_NESTED {
|
|
| 36 |
+ if attr.Attr.Type != unix.IFLA_PROTINFO|unix.NLA_F_NESTED {
|
|
| 37 | 37 |
continue |
| 38 | 38 |
} |
| 39 | 39 |
infos, err := nl.ParseRouteAttr(attr.Value) |
| ... | ... |
@@ -230,3 +230,63 @@ func (qdisc *GenericQdisc) Attrs() *QdiscAttrs {
|
| 230 | 230 |
func (qdisc *GenericQdisc) Type() string {
|
| 231 | 231 |
return qdisc.QdiscType |
| 232 | 232 |
} |
| 233 |
+ |
|
| 234 |
+// Fq is a classless packet scheduler meant to be mostly used for locally generated traffic. |
|
| 235 |
+type Fq struct {
|
|
| 236 |
+ QdiscAttrs |
|
| 237 |
+ PacketLimit uint32 |
|
| 238 |
+ FlowPacketLimit uint32 |
|
| 239 |
+ // In bytes |
|
| 240 |
+ Quantum uint32 |
|
| 241 |
+ InitialQuantum uint32 |
|
| 242 |
+ // called RateEnable under the hood |
|
| 243 |
+ Pacing uint32 |
|
| 244 |
+ FlowDefaultRate uint32 |
|
| 245 |
+ FlowMaxRate uint32 |
|
| 246 |
+ // called BucketsLog under the hood |
|
| 247 |
+ Buckets uint32 |
|
| 248 |
+ FlowRefillDelay uint32 |
|
| 249 |
+ LowRateThreshold uint32 |
|
| 250 |
+} |
|
| 251 |
+ |
|
| 252 |
+func NewFq(attrs QdiscAttrs) *Fq {
|
|
| 253 |
+ return &Fq{
|
|
| 254 |
+ QdiscAttrs: attrs, |
|
| 255 |
+ Pacing: 1, |
|
| 256 |
+ } |
|
| 257 |
+} |
|
| 258 |
+ |
|
| 259 |
+func (qdisc *Fq) Attrs() *QdiscAttrs {
|
|
| 260 |
+ return &qdisc.QdiscAttrs |
|
| 261 |
+} |
|
| 262 |
+ |
|
| 263 |
+func (qdisc *Fq) Type() string {
|
|
| 264 |
+ return "fq" |
|
| 265 |
+} |
|
| 266 |
+ |
|
| 267 |
+// FQ_Codel (Fair Queuing Controlled Delay) is queuing discipline that combines Fair Queuing with the CoDel AQM scheme. |
|
| 268 |
+type FqCodel struct {
|
|
| 269 |
+ QdiscAttrs |
|
| 270 |
+ Target uint32 |
|
| 271 |
+ Limit uint32 |
|
| 272 |
+ Interval uint32 |
|
| 273 |
+ ECN uint32 |
|
| 274 |
+ Flows uint32 |
|
| 275 |
+ Quantum uint32 |
|
| 276 |
+ // There are some more attributes here, but support for them seems not ubiquitous |
|
| 277 |
+} |
|
| 278 |
+ |
|
| 279 |
+func NewFqCodel(attrs QdiscAttrs) *FqCodel {
|
|
| 280 |
+ return &FqCodel{
|
|
| 281 |
+ QdiscAttrs: attrs, |
|
| 282 |
+ ECN: 1, |
|
| 283 |
+ } |
|
| 284 |
+} |
|
| 285 |
+ |
|
| 286 |
+func (qdisc *FqCodel) Attrs() *QdiscAttrs {
|
|
| 287 |
+ return &qdisc.QdiscAttrs |
|
| 288 |
+} |
|
| 289 |
+ |
|
| 290 |
+func (qdisc *FqCodel) Type() string {
|
|
| 291 |
+ return "fq_codel" |
|
| 292 |
+} |
| ... | ... |
@@ -8,6 +8,7 @@ import ( |
| 8 | 8 |
"syscall" |
| 9 | 9 |
|
| 10 | 10 |
"github.com/vishvananda/netlink/nl" |
| 11 |
+ "golang.org/x/sys/unix" |
|
| 11 | 12 |
) |
| 12 | 13 |
|
| 13 | 14 |
// NOTE function is here because it uses other linux functions |
| ... | ... |
@@ -84,7 +85,7 @@ func QdiscDel(qdisc Qdisc) error {
|
| 84 | 84 |
// QdiscDel will delete a qdisc from the system. |
| 85 | 85 |
// Equivalent to: `tc qdisc del $qdisc` |
| 86 | 86 |
func (h *Handle) QdiscDel(qdisc Qdisc) error {
|
| 87 |
- return h.qdiscModify(syscall.RTM_DELQDISC, 0, qdisc) |
|
| 87 |
+ return h.qdiscModify(unix.RTM_DELQDISC, 0, qdisc) |
|
| 88 | 88 |
} |
| 89 | 89 |
|
| 90 | 90 |
// QdiscChange will change a qdisc in place |
| ... | ... |
@@ -98,7 +99,7 @@ func QdiscChange(qdisc Qdisc) error {
|
| 98 | 98 |
// Equivalent to: `tc qdisc change $qdisc` |
| 99 | 99 |
// The parent and handle MUST NOT be changed. |
| 100 | 100 |
func (h *Handle) QdiscChange(qdisc Qdisc) error {
|
| 101 |
- return h.qdiscModify(syscall.RTM_NEWQDISC, 0, qdisc) |
|
| 101 |
+ return h.qdiscModify(unix.RTM_NEWQDISC, 0, qdisc) |
|
| 102 | 102 |
} |
| 103 | 103 |
|
| 104 | 104 |
// QdiscReplace will replace a qdisc to the system. |
| ... | ... |
@@ -113,8 +114,8 @@ func QdiscReplace(qdisc Qdisc) error {
|
| 113 | 113 |
// The handle MUST change. |
| 114 | 114 |
func (h *Handle) QdiscReplace(qdisc Qdisc) error {
|
| 115 | 115 |
return h.qdiscModify( |
| 116 |
- syscall.RTM_NEWQDISC, |
|
| 117 |
- syscall.NLM_F_CREATE|syscall.NLM_F_REPLACE, |
|
| 116 |
+ unix.RTM_NEWQDISC, |
|
| 117 |
+ unix.NLM_F_CREATE|unix.NLM_F_REPLACE, |
|
| 118 | 118 |
qdisc) |
| 119 | 119 |
} |
| 120 | 120 |
|
| ... | ... |
@@ -128,13 +129,13 @@ func QdiscAdd(qdisc Qdisc) error {
|
| 128 | 128 |
// Equivalent to: `tc qdisc add $qdisc` |
| 129 | 129 |
func (h *Handle) QdiscAdd(qdisc Qdisc) error {
|
| 130 | 130 |
return h.qdiscModify( |
| 131 |
- syscall.RTM_NEWQDISC, |
|
| 132 |
- syscall.NLM_F_CREATE|syscall.NLM_F_EXCL, |
|
| 131 |
+ unix.RTM_NEWQDISC, |
|
| 132 |
+ unix.NLM_F_CREATE|unix.NLM_F_EXCL, |
|
| 133 | 133 |
qdisc) |
| 134 | 134 |
} |
| 135 | 135 |
|
| 136 | 136 |
func (h *Handle) qdiscModify(cmd, flags int, qdisc Qdisc) error {
|
| 137 |
- req := h.newNetlinkRequest(cmd, flags|syscall.NLM_F_ACK) |
|
| 137 |
+ req := h.newNetlinkRequest(cmd, flags|unix.NLM_F_ACK) |
|
| 138 | 138 |
base := qdisc.Attrs() |
| 139 | 139 |
msg := &nl.TcMsg{
|
| 140 | 140 |
Family: nl.FAMILY_ALL, |
| ... | ... |
@@ -145,13 +146,13 @@ func (h *Handle) qdiscModify(cmd, flags int, qdisc Qdisc) error {
|
| 145 | 145 |
req.AddData(msg) |
| 146 | 146 |
|
| 147 | 147 |
// When deleting don't bother building the rest of the netlink payload |
| 148 |
- if cmd != syscall.RTM_DELQDISC {
|
|
| 148 |
+ if cmd != unix.RTM_DELQDISC {
|
|
| 149 | 149 |
if err := qdiscPayload(req, qdisc); err != nil {
|
| 150 | 150 |
return err |
| 151 | 151 |
} |
| 152 | 152 |
} |
| 153 | 153 |
|
| 154 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 154 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 155 | 155 |
return err |
| 156 | 156 |
} |
| 157 | 157 |
|
| ... | ... |
@@ -231,6 +232,48 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
|
| 231 | 231 |
if qdisc.Attrs().Parent != HANDLE_INGRESS {
|
| 232 | 232 |
return fmt.Errorf("Ingress filters must set Parent to HANDLE_INGRESS")
|
| 233 | 233 |
} |
| 234 |
+ case *FqCodel: |
|
| 235 |
+ nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_ECN, nl.Uint32Attr((uint32(qdisc.ECN)))) |
|
| 236 |
+ if qdisc.Limit > 0 {
|
|
| 237 |
+ nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_LIMIT, nl.Uint32Attr((uint32(qdisc.Limit)))) |
|
| 238 |
+ } |
|
| 239 |
+ if qdisc.Interval > 0 {
|
|
| 240 |
+ nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_INTERVAL, nl.Uint32Attr((uint32(qdisc.Interval)))) |
|
| 241 |
+ } |
|
| 242 |
+ if qdisc.Flows > 0 {
|
|
| 243 |
+ nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_FLOWS, nl.Uint32Attr((uint32(qdisc.Flows)))) |
|
| 244 |
+ } |
|
| 245 |
+ if qdisc.Quantum > 0 {
|
|
| 246 |
+ nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_QUANTUM, nl.Uint32Attr((uint32(qdisc.Quantum)))) |
|
| 247 |
+ } |
|
| 248 |
+ |
|
| 249 |
+ case *Fq: |
|
| 250 |
+ nl.NewRtAttrChild(options, nl.TCA_FQ_RATE_ENABLE, nl.Uint32Attr((uint32(qdisc.Pacing)))) |
|
| 251 |
+ |
|
| 252 |
+ if qdisc.Buckets > 0 {
|
|
| 253 |
+ nl.NewRtAttrChild(options, nl.TCA_FQ_BUCKETS_LOG, nl.Uint32Attr((uint32(qdisc.Buckets)))) |
|
| 254 |
+ } |
|
| 255 |
+ if qdisc.LowRateThreshold > 0 {
|
|
| 256 |
+ nl.NewRtAttrChild(options, nl.TCA_FQ_LOW_RATE_THRESHOLD, nl.Uint32Attr((uint32(qdisc.LowRateThreshold)))) |
|
| 257 |
+ } |
|
| 258 |
+ if qdisc.Quantum > 0 {
|
|
| 259 |
+ nl.NewRtAttrChild(options, nl.TCA_FQ_QUANTUM, nl.Uint32Attr((uint32(qdisc.Quantum)))) |
|
| 260 |
+ } |
|
| 261 |
+ if qdisc.InitialQuantum > 0 {
|
|
| 262 |
+ nl.NewRtAttrChild(options, nl.TCA_FQ_INITIAL_QUANTUM, nl.Uint32Attr((uint32(qdisc.InitialQuantum)))) |
|
| 263 |
+ } |
|
| 264 |
+ if qdisc.FlowRefillDelay > 0 {
|
|
| 265 |
+ nl.NewRtAttrChild(options, nl.TCA_FQ_FLOW_REFILL_DELAY, nl.Uint32Attr((uint32(qdisc.FlowRefillDelay)))) |
|
| 266 |
+ } |
|
| 267 |
+ if qdisc.FlowPacketLimit > 0 {
|
|
| 268 |
+ nl.NewRtAttrChild(options, nl.TCA_FQ_FLOW_PLIMIT, nl.Uint32Attr((uint32(qdisc.FlowPacketLimit)))) |
|
| 269 |
+ } |
|
| 270 |
+ if qdisc.FlowMaxRate > 0 {
|
|
| 271 |
+ nl.NewRtAttrChild(options, nl.TCA_FQ_FLOW_MAX_RATE, nl.Uint32Attr((uint32(qdisc.FlowMaxRate)))) |
|
| 272 |
+ } |
|
| 273 |
+ if qdisc.FlowDefaultRate > 0 {
|
|
| 274 |
+ nl.NewRtAttrChild(options, nl.TCA_FQ_FLOW_DEFAULT_RATE, nl.Uint32Attr((uint32(qdisc.FlowDefaultRate)))) |
|
| 275 |
+ } |
|
| 234 | 276 |
} |
| 235 | 277 |
|
| 236 | 278 |
req.AddData(options) |
| ... | ... |
@@ -248,7 +291,7 @@ func QdiscList(link Link) ([]Qdisc, error) {
|
| 248 | 248 |
// Equivalent to: `tc qdisc show`. |
| 249 | 249 |
// The list can be filtered by link. |
| 250 | 250 |
func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
|
| 251 |
- req := h.newNetlinkRequest(syscall.RTM_GETQDISC, syscall.NLM_F_DUMP) |
|
| 251 |
+ req := h.newNetlinkRequest(unix.RTM_GETQDISC, unix.NLM_F_DUMP) |
|
| 252 | 252 |
index := int32(0) |
| 253 | 253 |
if link != nil {
|
| 254 | 254 |
base := link.Attrs() |
| ... | ... |
@@ -261,7 +304,7 @@ func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
|
| 261 | 261 |
} |
| 262 | 262 |
req.AddData(msg) |
| 263 | 263 |
|
| 264 |
- msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWQDISC) |
|
| 264 |
+ msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWQDISC) |
|
| 265 | 265 |
if err != nil {
|
| 266 | 266 |
return nil, err |
| 267 | 267 |
} |
| ... | ... |
@@ -303,6 +346,10 @@ func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
|
| 303 | 303 |
qdisc = &Ingress{}
|
| 304 | 304 |
case "htb": |
| 305 | 305 |
qdisc = &Htb{}
|
| 306 |
+ case "fq": |
|
| 307 |
+ qdisc = &Fq{}
|
|
| 308 |
+ case "fq_codel": |
|
| 309 |
+ qdisc = &FqCodel{}
|
|
| 306 | 310 |
case "netem": |
| 307 | 311 |
qdisc = &Netem{}
|
| 308 | 312 |
default: |
| ... | ... |
@@ -336,6 +383,22 @@ func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
|
| 336 | 336 |
if err := parseHtbData(qdisc, data); err != nil {
|
| 337 | 337 |
return nil, err |
| 338 | 338 |
} |
| 339 |
+ case "fq": |
|
| 340 |
+ data, err := nl.ParseRouteAttr(attr.Value) |
|
| 341 |
+ if err != nil {
|
|
| 342 |
+ return nil, err |
|
| 343 |
+ } |
|
| 344 |
+ if err := parseFqData(qdisc, data); err != nil {
|
|
| 345 |
+ return nil, err |
|
| 346 |
+ } |
|
| 347 |
+ case "fq_codel": |
|
| 348 |
+ data, err := nl.ParseRouteAttr(attr.Value) |
|
| 349 |
+ if err != nil {
|
|
| 350 |
+ return nil, err |
|
| 351 |
+ } |
|
| 352 |
+ if err := parseFqCodelData(qdisc, data); err != nil {
|
|
| 353 |
+ return nil, err |
|
| 354 |
+ } |
|
| 339 | 355 |
case "netem": |
| 340 | 356 |
if err := parseNetemData(qdisc, attr.Value); err != nil {
|
| 341 | 357 |
return nil, err |
| ... | ... |
@@ -388,6 +451,61 @@ func parseHtbData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
|
| 388 | 388 |
return nil |
| 389 | 389 |
} |
| 390 | 390 |
|
| 391 |
+func parseFqCodelData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
|
|
| 392 |
+ native = nl.NativeEndian() |
|
| 393 |
+ fqCodel := qdisc.(*FqCodel) |
|
| 394 |
+ for _, datum := range data {
|
|
| 395 |
+ |
|
| 396 |
+ switch datum.Attr.Type {
|
|
| 397 |
+ case nl.TCA_FQ_CODEL_TARGET: |
|
| 398 |
+ fqCodel.Target = native.Uint32(datum.Value) |
|
| 399 |
+ case nl.TCA_FQ_CODEL_LIMIT: |
|
| 400 |
+ fqCodel.Limit = native.Uint32(datum.Value) |
|
| 401 |
+ case nl.TCA_FQ_CODEL_INTERVAL: |
|
| 402 |
+ fqCodel.Interval = native.Uint32(datum.Value) |
|
| 403 |
+ case nl.TCA_FQ_CODEL_ECN: |
|
| 404 |
+ fqCodel.ECN = native.Uint32(datum.Value) |
|
| 405 |
+ case nl.TCA_FQ_CODEL_FLOWS: |
|
| 406 |
+ fqCodel.Flows = native.Uint32(datum.Value) |
|
| 407 |
+ case nl.TCA_FQ_CODEL_QUANTUM: |
|
| 408 |
+ fqCodel.Quantum = native.Uint32(datum.Value) |
|
| 409 |
+ } |
|
| 410 |
+ } |
|
| 411 |
+ return nil |
|
| 412 |
+} |
|
| 413 |
+ |
|
| 414 |
+func parseFqData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
|
|
| 415 |
+ native = nl.NativeEndian() |
|
| 416 |
+ fq := qdisc.(*Fq) |
|
| 417 |
+ for _, datum := range data {
|
|
| 418 |
+ switch datum.Attr.Type {
|
|
| 419 |
+ case nl.TCA_FQ_BUCKETS_LOG: |
|
| 420 |
+ fq.Buckets = native.Uint32(datum.Value) |
|
| 421 |
+ case nl.TCA_FQ_LOW_RATE_THRESHOLD: |
|
| 422 |
+ fq.LowRateThreshold = native.Uint32(datum.Value) |
|
| 423 |
+ case nl.TCA_FQ_QUANTUM: |
|
| 424 |
+ fq.Quantum = native.Uint32(datum.Value) |
|
| 425 |
+ case nl.TCA_FQ_RATE_ENABLE: |
|
| 426 |
+ fq.Pacing = native.Uint32(datum.Value) |
|
| 427 |
+ case nl.TCA_FQ_INITIAL_QUANTUM: |
|
| 428 |
+ fq.InitialQuantum = native.Uint32(datum.Value) |
|
| 429 |
+ case nl.TCA_FQ_ORPHAN_MASK: |
|
| 430 |
+ // TODO |
|
| 431 |
+ case nl.TCA_FQ_FLOW_REFILL_DELAY: |
|
| 432 |
+ fq.FlowRefillDelay = native.Uint32(datum.Value) |
|
| 433 |
+ case nl.TCA_FQ_FLOW_PLIMIT: |
|
| 434 |
+ fq.FlowPacketLimit = native.Uint32(datum.Value) |
|
| 435 |
+ case nl.TCA_FQ_PLIMIT: |
|
| 436 |
+ fq.PacketLimit = native.Uint32(datum.Value) |
|
| 437 |
+ case nl.TCA_FQ_FLOW_MAX_RATE: |
|
| 438 |
+ fq.FlowMaxRate = native.Uint32(datum.Value) |
|
| 439 |
+ case nl.TCA_FQ_FLOW_DEFAULT_RATE: |
|
| 440 |
+ fq.FlowDefaultRate = native.Uint32(datum.Value) |
|
| 441 |
+ } |
|
| 442 |
+ } |
|
| 443 |
+ return nil |
|
| 444 |
+} |
|
| 445 |
+ |
|
| 391 | 446 |
func parseNetemData(qdisc Qdisc, value []byte) error {
|
| 392 | 447 |
netem := qdisc.(*Netem) |
| 393 | 448 |
opt := nl.DeserializeTcNetemQopt(value) |
| ... | ... |
@@ -8,16 +8,17 @@ import ( |
| 8 | 8 |
|
| 9 | 9 |
"github.com/vishvananda/netlink/nl" |
| 10 | 10 |
"github.com/vishvananda/netns" |
| 11 |
+ "golang.org/x/sys/unix" |
|
| 11 | 12 |
) |
| 12 | 13 |
|
| 13 | 14 |
// RtAttr is shared so it is in netlink_linux.go |
| 14 | 15 |
|
| 15 | 16 |
const ( |
| 16 |
- SCOPE_UNIVERSE Scope = syscall.RT_SCOPE_UNIVERSE |
|
| 17 |
- SCOPE_SITE Scope = syscall.RT_SCOPE_SITE |
|
| 18 |
- SCOPE_LINK Scope = syscall.RT_SCOPE_LINK |
|
| 19 |
- SCOPE_HOST Scope = syscall.RT_SCOPE_HOST |
|
| 20 |
- SCOPE_NOWHERE Scope = syscall.RT_SCOPE_NOWHERE |
|
| 17 |
+ SCOPE_UNIVERSE Scope = unix.RT_SCOPE_UNIVERSE |
|
| 18 |
+ SCOPE_SITE Scope = unix.RT_SCOPE_SITE |
|
| 19 |
+ SCOPE_LINK Scope = unix.RT_SCOPE_LINK |
|
| 20 |
+ SCOPE_HOST Scope = unix.RT_SCOPE_HOST |
|
| 21 |
+ SCOPE_NOWHERE Scope = unix.RT_SCOPE_NOWHERE |
|
| 21 | 22 |
) |
| 22 | 23 |
|
| 23 | 24 |
const ( |
| ... | ... |
@@ -34,8 +35,8 @@ const ( |
| 34 | 34 |
) |
| 35 | 35 |
|
| 36 | 36 |
const ( |
| 37 |
- FLAG_ONLINK NextHopFlag = syscall.RTNH_F_ONLINK |
|
| 38 |
- FLAG_PERVASIVE NextHopFlag = syscall.RTNH_F_PERVASIVE |
|
| 37 |
+ FLAG_ONLINK NextHopFlag = unix.RTNH_F_ONLINK |
|
| 38 |
+ FLAG_PERVASIVE NextHopFlag = unix.RTNH_F_PERVASIVE |
|
| 39 | 39 |
) |
| 40 | 40 |
|
| 41 | 41 |
var testFlags = []flagString{
|
| ... | ... |
@@ -124,17 +125,17 @@ func (e *MPLSEncap) Type() int {
|
| 124 | 124 |
|
| 125 | 125 |
func (e *MPLSEncap) Decode(buf []byte) error {
|
| 126 | 126 |
if len(buf) < 4 {
|
| 127 |
- return fmt.Errorf("Lack of bytes")
|
|
| 127 |
+ return fmt.Errorf("lack of bytes")
|
|
| 128 | 128 |
} |
| 129 | 129 |
native := nl.NativeEndian() |
| 130 | 130 |
l := native.Uint16(buf) |
| 131 | 131 |
if len(buf) < int(l) {
|
| 132 |
- return fmt.Errorf("Lack of bytes")
|
|
| 132 |
+ return fmt.Errorf("lack of bytes")
|
|
| 133 | 133 |
} |
| 134 | 134 |
buf = buf[:l] |
| 135 | 135 |
typ := native.Uint16(buf[2:]) |
| 136 | 136 |
if typ != nl.MPLS_IPTUNNEL_DST {
|
| 137 |
- return fmt.Errorf("Unknown MPLS Encap Type: %d", typ)
|
|
| 137 |
+ return fmt.Errorf("unknown MPLS Encap Type: %d", typ)
|
|
| 138 | 138 |
} |
| 139 | 139 |
e.Labels = nl.DecodeMPLSStack(buf[4:]) |
| 140 | 140 |
return nil |
| ... | ... |
@@ -185,6 +186,79 @@ func (e *MPLSEncap) Equal(x Encap) bool {
|
| 185 | 185 |
return true |
| 186 | 186 |
} |
| 187 | 187 |
|
| 188 |
+// SEG6 definitions |
|
| 189 |
+type SEG6Encap struct {
|
|
| 190 |
+ Mode int |
|
| 191 |
+ Segments []net.IP |
|
| 192 |
+} |
|
| 193 |
+ |
|
| 194 |
+func (e *SEG6Encap) Type() int {
|
|
| 195 |
+ return nl.LWTUNNEL_ENCAP_SEG6 |
|
| 196 |
+} |
|
| 197 |
+func (e *SEG6Encap) Decode(buf []byte) error {
|
|
| 198 |
+ if len(buf) < 4 {
|
|
| 199 |
+ return fmt.Errorf("lack of bytes")
|
|
| 200 |
+ } |
|
| 201 |
+ native := nl.NativeEndian() |
|
| 202 |
+ // Get Length(l) & Type(typ) : 2 + 2 bytes |
|
| 203 |
+ l := native.Uint16(buf) |
|
| 204 |
+ if len(buf) < int(l) {
|
|
| 205 |
+ return fmt.Errorf("lack of bytes")
|
|
| 206 |
+ } |
|
| 207 |
+ buf = buf[:l] // make sure buf size upper limit is Length |
|
| 208 |
+ typ := native.Uint16(buf[2:]) |
|
| 209 |
+ if typ != nl.SEG6_IPTUNNEL_SRH {
|
|
| 210 |
+ return fmt.Errorf("unknown SEG6 Type: %d", typ)
|
|
| 211 |
+ } |
|
| 212 |
+ |
|
| 213 |
+ var err error |
|
| 214 |
+ e.Mode, e.Segments, err = nl.DecodeSEG6Encap(buf[4:]) |
|
| 215 |
+ |
|
| 216 |
+ return err |
|
| 217 |
+} |
|
| 218 |
+func (e *SEG6Encap) Encode() ([]byte, error) {
|
|
| 219 |
+ s, err := nl.EncodeSEG6Encap(e.Mode, e.Segments) |
|
| 220 |
+ native := nl.NativeEndian() |
|
| 221 |
+ hdr := make([]byte, 4) |
|
| 222 |
+ native.PutUint16(hdr, uint16(len(s)+4)) |
|
| 223 |
+ native.PutUint16(hdr[2:], nl.SEG6_IPTUNNEL_SRH) |
|
| 224 |
+ return append(hdr, s...), err |
|
| 225 |
+} |
|
| 226 |
+func (e *SEG6Encap) String() string {
|
|
| 227 |
+ segs := make([]string, 0, len(e.Segments)) |
|
| 228 |
+ // append segment backwards (from n to 0) since seg#0 is the last segment. |
|
| 229 |
+ for i := len(e.Segments); i > 0; i-- {
|
|
| 230 |
+ segs = append(segs, fmt.Sprintf("%s", e.Segments[i-1]))
|
|
| 231 |
+ } |
|
| 232 |
+ str := fmt.Sprintf("mode %s segs %d [ %s ]", nl.SEG6EncapModeString(e.Mode),
|
|
| 233 |
+ len(e.Segments), strings.Join(segs, " ")) |
|
| 234 |
+ return str |
|
| 235 |
+} |
|
| 236 |
+func (e *SEG6Encap) Equal(x Encap) bool {
|
|
| 237 |
+ o, ok := x.(*SEG6Encap) |
|
| 238 |
+ if !ok {
|
|
| 239 |
+ return false |
|
| 240 |
+ } |
|
| 241 |
+ if e == o {
|
|
| 242 |
+ return true |
|
| 243 |
+ } |
|
| 244 |
+ if e == nil || o == nil {
|
|
| 245 |
+ return false |
|
| 246 |
+ } |
|
| 247 |
+ if e.Mode != o.Mode {
|
|
| 248 |
+ return false |
|
| 249 |
+ } |
|
| 250 |
+ if len(e.Segments) != len(o.Segments) {
|
|
| 251 |
+ return false |
|
| 252 |
+ } |
|
| 253 |
+ for i := range e.Segments {
|
|
| 254 |
+ if !e.Segments[i].Equal(o.Segments[i]) {
|
|
| 255 |
+ return false |
|
| 256 |
+ } |
|
| 257 |
+ } |
|
| 258 |
+ return true |
|
| 259 |
+} |
|
| 260 |
+ |
|
| 188 | 261 |
// RouteAdd will add a route to the system. |
| 189 | 262 |
// Equivalent to: `ip route add $route` |
| 190 | 263 |
func RouteAdd(route *Route) error {
|
| ... | ... |
@@ -194,8 +268,8 @@ func RouteAdd(route *Route) error {
|
| 194 | 194 |
// RouteAdd will add a route to the system. |
| 195 | 195 |
// Equivalent to: `ip route add $route` |
| 196 | 196 |
func (h *Handle) RouteAdd(route *Route) error {
|
| 197 |
- flags := syscall.NLM_F_CREATE | syscall.NLM_F_EXCL | syscall.NLM_F_ACK |
|
| 198 |
- req := h.newNetlinkRequest(syscall.RTM_NEWROUTE, flags) |
|
| 197 |
+ flags := unix.NLM_F_CREATE | unix.NLM_F_EXCL | unix.NLM_F_ACK |
|
| 198 |
+ req := h.newNetlinkRequest(unix.RTM_NEWROUTE, flags) |
|
| 199 | 199 |
return h.routeHandle(route, req, nl.NewRtMsg()) |
| 200 | 200 |
} |
| 201 | 201 |
|
| ... | ... |
@@ -208,8 +282,8 @@ func RouteReplace(route *Route) error {
|
| 208 | 208 |
// RouteReplace will add a route to the system. |
| 209 | 209 |
// Equivalent to: `ip route replace $route` |
| 210 | 210 |
func (h *Handle) RouteReplace(route *Route) error {
|
| 211 |
- flags := syscall.NLM_F_CREATE | syscall.NLM_F_REPLACE | syscall.NLM_F_ACK |
|
| 212 |
- req := h.newNetlinkRequest(syscall.RTM_NEWROUTE, flags) |
|
| 211 |
+ flags := unix.NLM_F_CREATE | unix.NLM_F_REPLACE | unix.NLM_F_ACK |
|
| 212 |
+ req := h.newNetlinkRequest(unix.RTM_NEWROUTE, flags) |
|
| 213 | 213 |
return h.routeHandle(route, req, nl.NewRtMsg()) |
| 214 | 214 |
} |
| 215 | 215 |
|
| ... | ... |
@@ -222,7 +296,7 @@ func RouteDel(route *Route) error {
|
| 222 | 222 |
// RouteDel will delete a route from the system. |
| 223 | 223 |
// Equivalent to: `ip route del $route` |
| 224 | 224 |
func (h *Handle) RouteDel(route *Route) error {
|
| 225 |
- req := h.newNetlinkRequest(syscall.RTM_DELROUTE, syscall.NLM_F_ACK) |
|
| 225 |
+ req := h.newNetlinkRequest(unix.RTM_DELROUTE, unix.NLM_F_ACK) |
|
| 226 | 226 |
return h.routeHandle(route, req, nl.NewRtDelMsg()) |
| 227 | 227 |
} |
| 228 | 228 |
|
| ... | ... |
@@ -245,12 +319,12 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg |
| 245 | 245 |
} else {
|
| 246 | 246 |
dstData = route.Dst.IP.To16() |
| 247 | 247 |
} |
| 248 |
- rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_DST, dstData)) |
|
| 248 |
+ rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_DST, dstData)) |
|
| 249 | 249 |
} else if route.MPLSDst != nil {
|
| 250 | 250 |
family = nl.FAMILY_MPLS |
| 251 | 251 |
msg.Dst_len = uint8(20) |
| 252 |
- msg.Type = syscall.RTN_UNICAST |
|
| 253 |
- rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_DST, nl.EncodeMPLSStack(*route.MPLSDst))) |
|
| 252 |
+ msg.Type = unix.RTN_UNICAST |
|
| 253 |
+ rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_DST, nl.EncodeMPLSStack(*route.MPLSDst))) |
|
| 254 | 254 |
} |
| 255 | 255 |
|
| 256 | 256 |
if route.NewDst != nil {
|
| ... | ... |
@@ -288,7 +362,7 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg |
| 288 | 288 |
srcData = route.Src.To16() |
| 289 | 289 |
} |
| 290 | 290 |
// The commonly used src ip for routes is actually PREFSRC |
| 291 |
- rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_PREFSRC, srcData)) |
|
| 291 |
+ rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_PREFSRC, srcData)) |
|
| 292 | 292 |
} |
| 293 | 293 |
|
| 294 | 294 |
if route.Gw != nil {
|
| ... | ... |
@@ -303,14 +377,14 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg |
| 303 | 303 |
} else {
|
| 304 | 304 |
gwData = route.Gw.To16() |
| 305 | 305 |
} |
| 306 |
- rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_GATEWAY, gwData)) |
|
| 306 |
+ rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_GATEWAY, gwData)) |
|
| 307 | 307 |
} |
| 308 | 308 |
|
| 309 | 309 |
if len(route.MultiPath) > 0 {
|
| 310 | 310 |
buf := []byte{}
|
| 311 | 311 |
for _, nh := range route.MultiPath {
|
| 312 | 312 |
rtnh := &nl.RtNexthop{
|
| 313 |
- RtNexthop: syscall.RtNexthop{
|
|
| 313 |
+ RtNexthop: unix.RtNexthop{
|
|
| 314 | 314 |
Hops: uint8(nh.Hops), |
| 315 | 315 |
Ifindex: int32(nh.LinkIndex), |
| 316 | 316 |
Flags: uint8(nh.Flags), |
| ... | ... |
@@ -323,9 +397,9 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg |
| 323 | 323 |
return fmt.Errorf("gateway, source, and destination ip are not the same IP family")
|
| 324 | 324 |
} |
| 325 | 325 |
if gwFamily == FAMILY_V4 {
|
| 326 |
- children = append(children, nl.NewRtAttr(syscall.RTA_GATEWAY, []byte(nh.Gw.To4()))) |
|
| 326 |
+ children = append(children, nl.NewRtAttr(unix.RTA_GATEWAY, []byte(nh.Gw.To4()))) |
|
| 327 | 327 |
} else {
|
| 328 |
- children = append(children, nl.NewRtAttr(syscall.RTA_GATEWAY, []byte(nh.Gw.To16()))) |
|
| 328 |
+ children = append(children, nl.NewRtAttr(unix.RTA_GATEWAY, []byte(nh.Gw.To16()))) |
|
| 329 | 329 |
} |
| 330 | 330 |
} |
| 331 | 331 |
if nh.NewDst != nil {
|
| ... | ... |
@@ -351,15 +425,15 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg |
| 351 | 351 |
rtnh.Children = children |
| 352 | 352 |
buf = append(buf, rtnh.Serialize()...) |
| 353 | 353 |
} |
| 354 |
- rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_MULTIPATH, buf)) |
|
| 354 |
+ rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_MULTIPATH, buf)) |
|
| 355 | 355 |
} |
| 356 | 356 |
|
| 357 | 357 |
if route.Table > 0 {
|
| 358 | 358 |
if route.Table >= 256 {
|
| 359 |
- msg.Table = syscall.RT_TABLE_UNSPEC |
|
| 359 |
+ msg.Table = unix.RT_TABLE_UNSPEC |
|
| 360 | 360 |
b := make([]byte, 4) |
| 361 | 361 |
native.PutUint32(b, uint32(route.Table)) |
| 362 |
- rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_TABLE, b)) |
|
| 362 |
+ rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_TABLE, b)) |
|
| 363 | 363 |
} else {
|
| 364 | 364 |
msg.Table = uint8(route.Table) |
| 365 | 365 |
} |
| ... | ... |
@@ -368,7 +442,7 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg |
| 368 | 368 |
if route.Priority > 0 {
|
| 369 | 369 |
b := make([]byte, 4) |
| 370 | 370 |
native.PutUint32(b, uint32(route.Priority)) |
| 371 |
- rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_PRIORITY, b)) |
|
| 371 |
+ rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_PRIORITY, b)) |
|
| 372 | 372 |
} |
| 373 | 373 |
if route.Tos > 0 {
|
| 374 | 374 |
msg.Tos = uint8(route.Tos) |
| ... | ... |
@@ -380,6 +454,25 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg |
| 380 | 380 |
msg.Type = uint8(route.Type) |
| 381 | 381 |
} |
| 382 | 382 |
|
| 383 |
+ var metrics []*nl.RtAttr |
|
| 384 |
+ // TODO: support other rta_metric values |
|
| 385 |
+ if route.MTU > 0 {
|
|
| 386 |
+ b := nl.Uint32Attr(uint32(route.MTU)) |
|
| 387 |
+ metrics = append(metrics, nl.NewRtAttr(unix.RTAX_MTU, b)) |
|
| 388 |
+ } |
|
| 389 |
+ if route.AdvMSS > 0 {
|
|
| 390 |
+ b := nl.Uint32Attr(uint32(route.AdvMSS)) |
|
| 391 |
+ metrics = append(metrics, nl.NewRtAttr(unix.RTAX_ADVMSS, b)) |
|
| 392 |
+ } |
|
| 393 |
+ |
|
| 394 |
+ if metrics != nil {
|
|
| 395 |
+ attr := nl.NewRtAttr(unix.RTA_METRICS, nil) |
|
| 396 |
+ for _, metric := range metrics {
|
|
| 397 |
+ attr.AddChild(metric) |
|
| 398 |
+ } |
|
| 399 |
+ rtAttrs = append(rtAttrs, attr) |
|
| 400 |
+ } |
|
| 401 |
+ |
|
| 383 | 402 |
msg.Flags = uint32(route.Flags) |
| 384 | 403 |
msg.Scope = uint8(route.Scope) |
| 385 | 404 |
msg.Family = uint8(family) |
| ... | ... |
@@ -394,9 +487,9 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg |
| 394 | 394 |
) |
| 395 | 395 |
native.PutUint32(b, uint32(route.LinkIndex)) |
| 396 | 396 |
|
| 397 |
- req.AddData(nl.NewRtAttr(syscall.RTA_OIF, b)) |
|
| 397 |
+ req.AddData(nl.NewRtAttr(unix.RTA_OIF, b)) |
|
| 398 | 398 |
|
| 399 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 399 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 400 | 400 |
return err |
| 401 | 401 |
} |
| 402 | 402 |
|
| ... | ... |
@@ -429,11 +522,11 @@ func RouteListFiltered(family int, filter *Route, filterMask uint64) ([]Route, e |
| 429 | 429 |
// RouteListFiltered gets a list of routes in the system filtered with specified rules. |
| 430 | 430 |
// All rules must be defined in RouteFilter struct |
| 431 | 431 |
func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64) ([]Route, error) {
|
| 432 |
- req := h.newNetlinkRequest(syscall.RTM_GETROUTE, syscall.NLM_F_DUMP) |
|
| 432 |
+ req := h.newNetlinkRequest(unix.RTM_GETROUTE, unix.NLM_F_DUMP) |
|
| 433 | 433 |
infmsg := nl.NewIfInfomsg(family) |
| 434 | 434 |
req.AddData(infmsg) |
| 435 | 435 |
|
| 436 |
- msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWROUTE) |
|
| 436 |
+ msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWROUTE) |
|
| 437 | 437 |
if err != nil {
|
| 438 | 438 |
return nil, err |
| 439 | 439 |
} |
| ... | ... |
@@ -441,11 +534,11 @@ func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64) |
| 441 | 441 |
var res []Route |
| 442 | 442 |
for _, m := range msgs {
|
| 443 | 443 |
msg := nl.DeserializeRtMsg(m) |
| 444 |
- if msg.Flags&syscall.RTM_F_CLONED != 0 {
|
|
| 444 |
+ if msg.Flags&unix.RTM_F_CLONED != 0 {
|
|
| 445 | 445 |
// Ignore cloned routes |
| 446 | 446 |
continue |
| 447 | 447 |
} |
| 448 |
- if msg.Table != syscall.RT_TABLE_MAIN {
|
|
| 448 |
+ if msg.Table != unix.RT_TABLE_MAIN {
|
|
| 449 | 449 |
if filter == nil || filter != nil && filterMask&RT_FILTER_TABLE == 0 {
|
| 450 | 450 |
// Ignore non-main tables |
| 451 | 451 |
continue |
| ... | ... |
@@ -457,7 +550,7 @@ func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64) |
| 457 | 457 |
} |
| 458 | 458 |
if filter != nil {
|
| 459 | 459 |
switch {
|
| 460 |
- case filterMask&RT_FILTER_TABLE != 0 && filter.Table != syscall.RT_TABLE_UNSPEC && route.Table != filter.Table: |
|
| 460 |
+ case filterMask&RT_FILTER_TABLE != 0 && filter.Table != unix.RT_TABLE_UNSPEC && route.Table != filter.Table: |
|
| 461 | 461 |
continue |
| 462 | 462 |
case filterMask&RT_FILTER_PROTOCOL != 0 && route.Protocol != filter.Protocol: |
| 463 | 463 |
continue |
| ... | ... |
@@ -508,11 +601,11 @@ func deserializeRoute(m []byte) (Route, error) {
|
| 508 | 508 |
var encap, encapType syscall.NetlinkRouteAttr |
| 509 | 509 |
for _, attr := range attrs {
|
| 510 | 510 |
switch attr.Attr.Type {
|
| 511 |
- case syscall.RTA_GATEWAY: |
|
| 511 |
+ case unix.RTA_GATEWAY: |
|
| 512 | 512 |
route.Gw = net.IP(attr.Value) |
| 513 |
- case syscall.RTA_PREFSRC: |
|
| 513 |
+ case unix.RTA_PREFSRC: |
|
| 514 | 514 |
route.Src = net.IP(attr.Value) |
| 515 |
- case syscall.RTA_DST: |
|
| 515 |
+ case unix.RTA_DST: |
|
| 516 | 516 |
if msg.Family == nl.FAMILY_MPLS {
|
| 517 | 517 |
stack := nl.DecodeMPLSStack(attr.Value) |
| 518 | 518 |
if len(stack) == 0 || len(stack) > 1 {
|
| ... | ... |
@@ -525,36 +618,36 @@ func deserializeRoute(m []byte) (Route, error) {
|
| 525 | 525 |
Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attr.Value)), |
| 526 | 526 |
} |
| 527 | 527 |
} |
| 528 |
- case syscall.RTA_OIF: |
|
| 528 |
+ case unix.RTA_OIF: |
|
| 529 | 529 |
route.LinkIndex = int(native.Uint32(attr.Value[0:4])) |
| 530 |
- case syscall.RTA_IIF: |
|
| 530 |
+ case unix.RTA_IIF: |
|
| 531 | 531 |
route.ILinkIndex = int(native.Uint32(attr.Value[0:4])) |
| 532 |
- case syscall.RTA_PRIORITY: |
|
| 532 |
+ case unix.RTA_PRIORITY: |
|
| 533 | 533 |
route.Priority = int(native.Uint32(attr.Value[0:4])) |
| 534 |
- case syscall.RTA_TABLE: |
|
| 534 |
+ case unix.RTA_TABLE: |
|
| 535 | 535 |
route.Table = int(native.Uint32(attr.Value[0:4])) |
| 536 |
- case syscall.RTA_MULTIPATH: |
|
| 536 |
+ case unix.RTA_MULTIPATH: |
|
| 537 | 537 |
parseRtNexthop := func(value []byte) (*NexthopInfo, []byte, error) {
|
| 538 |
- if len(value) < syscall.SizeofRtNexthop {
|
|
| 539 |
- return nil, nil, fmt.Errorf("Lack of bytes")
|
|
| 538 |
+ if len(value) < unix.SizeofRtNexthop {
|
|
| 539 |
+ return nil, nil, fmt.Errorf("lack of bytes")
|
|
| 540 | 540 |
} |
| 541 | 541 |
nh := nl.DeserializeRtNexthop(value) |
| 542 | 542 |
if len(value) < int(nh.RtNexthop.Len) {
|
| 543 |
- return nil, nil, fmt.Errorf("Lack of bytes")
|
|
| 543 |
+ return nil, nil, fmt.Errorf("lack of bytes")
|
|
| 544 | 544 |
} |
| 545 | 545 |
info := &NexthopInfo{
|
| 546 | 546 |
LinkIndex: int(nh.RtNexthop.Ifindex), |
| 547 | 547 |
Hops: int(nh.RtNexthop.Hops), |
| 548 | 548 |
Flags: int(nh.RtNexthop.Flags), |
| 549 | 549 |
} |
| 550 |
- attrs, err := nl.ParseRouteAttr(value[syscall.SizeofRtNexthop:int(nh.RtNexthop.Len)]) |
|
| 550 |
+ attrs, err := nl.ParseRouteAttr(value[unix.SizeofRtNexthop:int(nh.RtNexthop.Len)]) |
|
| 551 | 551 |
if err != nil {
|
| 552 | 552 |
return nil, nil, err |
| 553 | 553 |
} |
| 554 | 554 |
var encap, encapType syscall.NetlinkRouteAttr |
| 555 | 555 |
for _, attr := range attrs {
|
| 556 | 556 |
switch attr.Attr.Type {
|
| 557 |
- case syscall.RTA_GATEWAY: |
|
| 557 |
+ case unix.RTA_GATEWAY: |
|
| 558 | 558 |
info.Gw = net.IP(attr.Value) |
| 559 | 559 |
case nl.RTA_NEWDST: |
| 560 | 560 |
var d Destination |
| ... | ... |
@@ -611,6 +704,19 @@ func deserializeRoute(m []byte) (Route, error) {
|
| 611 | 611 |
encapType = attr |
| 612 | 612 |
case nl.RTA_ENCAP: |
| 613 | 613 |
encap = attr |
| 614 |
+ case unix.RTA_METRICS: |
|
| 615 |
+ metrics, err := nl.ParseRouteAttr(attr.Value) |
|
| 616 |
+ if err != nil {
|
|
| 617 |
+ return route, err |
|
| 618 |
+ } |
|
| 619 |
+ for _, metric := range metrics {
|
|
| 620 |
+ switch metric.Attr.Type {
|
|
| 621 |
+ case unix.RTAX_MTU: |
|
| 622 |
+ route.MTU = int(native.Uint32(metric.Value[0:4])) |
|
| 623 |
+ case unix.RTAX_ADVMSS: |
|
| 624 |
+ route.AdvMSS = int(native.Uint32(metric.Value[0:4])) |
|
| 625 |
+ } |
|
| 626 |
+ } |
|
| 614 | 627 |
} |
| 615 | 628 |
} |
| 616 | 629 |
|
| ... | ... |
@@ -623,6 +729,11 @@ func deserializeRoute(m []byte) (Route, error) {
|
| 623 | 623 |
if err := e.Decode(encap.Value); err != nil {
|
| 624 | 624 |
return route, err |
| 625 | 625 |
} |
| 626 |
+ case nl.LWTUNNEL_ENCAP_SEG6: |
|
| 627 |
+ e = &SEG6Encap{}
|
|
| 628 |
+ if err := e.Decode(encap.Value); err != nil {
|
|
| 629 |
+ return route, err |
|
| 630 |
+ } |
|
| 626 | 631 |
} |
| 627 | 632 |
route.Encap = e |
| 628 | 633 |
} |
| ... | ... |
@@ -639,7 +750,7 @@ func RouteGet(destination net.IP) ([]Route, error) {
|
| 639 | 639 |
// RouteGet gets a route to a specific destination from the host system. |
| 640 | 640 |
// Equivalent to: 'ip route get'. |
| 641 | 641 |
func (h *Handle) RouteGet(destination net.IP) ([]Route, error) {
|
| 642 |
- req := h.newNetlinkRequest(syscall.RTM_GETROUTE, syscall.NLM_F_REQUEST) |
|
| 642 |
+ req := h.newNetlinkRequest(unix.RTM_GETROUTE, unix.NLM_F_REQUEST) |
|
| 643 | 643 |
family := nl.GetIPFamily(destination) |
| 644 | 644 |
var destinationData []byte |
| 645 | 645 |
var bitlen uint8 |
| ... | ... |
@@ -655,10 +766,10 @@ func (h *Handle) RouteGet(destination net.IP) ([]Route, error) {
|
| 655 | 655 |
msg.Dst_len = bitlen |
| 656 | 656 |
req.AddData(msg) |
| 657 | 657 |
|
| 658 |
- rtaDst := nl.NewRtAttr(syscall.RTA_DST, destinationData) |
|
| 658 |
+ rtaDst := nl.NewRtAttr(unix.RTA_DST, destinationData) |
|
| 659 | 659 |
req.AddData(rtaDst) |
| 660 | 660 |
|
| 661 |
- msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWROUTE) |
|
| 661 |
+ msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWROUTE) |
|
| 662 | 662 |
if err != nil {
|
| 663 | 663 |
return nil, err |
| 664 | 664 |
} |
| ... | ... |
@@ -678,13 +789,13 @@ func (h *Handle) RouteGet(destination net.IP) ([]Route, error) {
|
| 678 | 678 |
// RouteSubscribe takes a chan down which notifications will be sent |
| 679 | 679 |
// when routes are added or deleted. Close the 'done' chan to stop subscription. |
| 680 | 680 |
func RouteSubscribe(ch chan<- RouteUpdate, done <-chan struct{}) error {
|
| 681 |
- return routeSubscribeAt(netns.None(), netns.None(), ch, done, nil) |
|
| 681 |
+ return routeSubscribeAt(netns.None(), netns.None(), ch, done, nil, false) |
|
| 682 | 682 |
} |
| 683 | 683 |
|
| 684 | 684 |
// RouteSubscribeAt works like RouteSubscribe plus it allows the caller |
| 685 | 685 |
// to choose the network namespace in which to subscribe (ns). |
| 686 | 686 |
func RouteSubscribeAt(ns netns.NsHandle, ch chan<- RouteUpdate, done <-chan struct{}) error {
|
| 687 |
- return routeSubscribeAt(ns, netns.None(), ch, done, nil) |
|
| 687 |
+ return routeSubscribeAt(ns, netns.None(), ch, done, nil, false) |
|
| 688 | 688 |
} |
| 689 | 689 |
|
| 690 | 690 |
// RouteSubscribeOptions contains a set of options to use with |
| ... | ... |
@@ -692,6 +803,7 @@ func RouteSubscribeAt(ns netns.NsHandle, ch chan<- RouteUpdate, done <-chan stru |
| 692 | 692 |
type RouteSubscribeOptions struct {
|
| 693 | 693 |
Namespace *netns.NsHandle |
| 694 | 694 |
ErrorCallback func(error) |
| 695 |
+ ListExisting bool |
|
| 695 | 696 |
} |
| 696 | 697 |
|
| 697 | 698 |
// RouteSubscribeWithOptions work like RouteSubscribe but enable to |
| ... | ... |
@@ -702,11 +814,11 @@ func RouteSubscribeWithOptions(ch chan<- RouteUpdate, done <-chan struct{}, opti
|
| 702 | 702 |
none := netns.None() |
| 703 | 703 |
options.Namespace = &none |
| 704 | 704 |
} |
| 705 |
- return routeSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback) |
|
| 705 |
+ return routeSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting) |
|
| 706 | 706 |
} |
| 707 | 707 |
|
| 708 |
-func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <-chan struct{}, cberr func(error)) error {
|
|
| 709 |
- s, err := nl.SubscribeAt(newNs, curNs, syscall.NETLINK_ROUTE, syscall.RTNLGRP_IPV4_ROUTE, syscall.RTNLGRP_IPV6_ROUTE) |
|
| 708 |
+func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <-chan struct{}, cberr func(error), listExisting bool) error {
|
|
| 709 |
+ s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_IPV4_ROUTE, unix.RTNLGRP_IPV6_ROUTE) |
|
| 710 | 710 |
if err != nil {
|
| 711 | 711 |
return err |
| 712 | 712 |
} |
| ... | ... |
@@ -716,6 +828,15 @@ func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done < |
| 716 | 716 |
s.Close() |
| 717 | 717 |
}() |
| 718 | 718 |
} |
| 719 |
+ if listExisting {
|
|
| 720 |
+ req := pkgHandle.newNetlinkRequest(unix.RTM_GETROUTE, |
|
| 721 |
+ unix.NLM_F_DUMP) |
|
| 722 |
+ infmsg := nl.NewIfInfomsg(unix.AF_UNSPEC) |
|
| 723 |
+ req.AddData(infmsg) |
|
| 724 |
+ if err := s.Send(req); err != nil {
|
|
| 725 |
+ return err |
|
| 726 |
+ } |
|
| 727 |
+ } |
|
| 719 | 728 |
go func() {
|
| 720 | 729 |
defer close(ch) |
| 721 | 730 |
for {
|
| ... | ... |
@@ -727,6 +848,20 @@ func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done < |
| 727 | 727 |
return |
| 728 | 728 |
} |
| 729 | 729 |
for _, m := range msgs {
|
| 730 |
+ if m.Header.Type == unix.NLMSG_DONE {
|
|
| 731 |
+ continue |
|
| 732 |
+ } |
|
| 733 |
+ if m.Header.Type == unix.NLMSG_ERROR {
|
|
| 734 |
+ native := nl.NativeEndian() |
|
| 735 |
+ error := int32(native.Uint32(m.Data[0:4])) |
|
| 736 |
+ if error == 0 {
|
|
| 737 |
+ continue |
|
| 738 |
+ } |
|
| 739 |
+ if cberr != nil {
|
|
| 740 |
+ cberr(syscall.Errno(-error)) |
|
| 741 |
+ } |
|
| 742 |
+ return |
|
| 743 |
+ } |
|
| 730 | 744 |
route, err := deserializeRoute(m.Data) |
| 731 | 745 |
if err != nil {
|
| 732 | 746 |
if cberr != nil {
|
| ... | ... |
@@ -3,11 +3,13 @@ package netlink |
| 3 | 3 |
import ( |
| 4 | 4 |
"fmt" |
| 5 | 5 |
"net" |
| 6 |
- "syscall" |
|
| 7 | 6 |
|
| 8 | 7 |
"github.com/vishvananda/netlink/nl" |
| 8 |
+ "golang.org/x/sys/unix" |
|
| 9 | 9 |
) |
| 10 | 10 |
|
| 11 |
+const FibRuleInvert = 0x2 |
|
| 12 |
+ |
|
| 11 | 13 |
// RuleAdd adds a rule to the system. |
| 12 | 14 |
// Equivalent to: ip rule add |
| 13 | 15 |
func RuleAdd(rule *Rule) error {
|
| ... | ... |
@@ -17,7 +19,7 @@ func RuleAdd(rule *Rule) error {
|
| 17 | 17 |
// RuleAdd adds a rule to the system. |
| 18 | 18 |
// Equivalent to: ip rule add |
| 19 | 19 |
func (h *Handle) RuleAdd(rule *Rule) error {
|
| 20 |
- req := h.newNetlinkRequest(syscall.RTM_NEWRULE, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) |
|
| 20 |
+ req := h.newNetlinkRequest(unix.RTM_NEWRULE, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK) |
|
| 21 | 21 |
return ruleHandle(rule, req) |
| 22 | 22 |
} |
| 23 | 23 |
|
| ... | ... |
@@ -30,18 +32,31 @@ func RuleDel(rule *Rule) error {
|
| 30 | 30 |
// RuleDel deletes a rule from the system. |
| 31 | 31 |
// Equivalent to: ip rule del |
| 32 | 32 |
func (h *Handle) RuleDel(rule *Rule) error {
|
| 33 |
- req := h.newNetlinkRequest(syscall.RTM_DELRULE, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) |
|
| 33 |
+ req := h.newNetlinkRequest(unix.RTM_DELRULE, unix.NLM_F_ACK) |
|
| 34 | 34 |
return ruleHandle(rule, req) |
| 35 | 35 |
} |
| 36 | 36 |
|
| 37 | 37 |
func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
|
| 38 | 38 |
msg := nl.NewRtMsg() |
| 39 |
- msg.Family = syscall.AF_INET |
|
| 39 |
+ msg.Family = unix.AF_INET |
|
| 40 |
+ msg.Protocol = unix.RTPROT_BOOT |
|
| 41 |
+ msg.Scope = unix.RT_SCOPE_UNIVERSE |
|
| 42 |
+ msg.Table = unix.RT_TABLE_UNSPEC |
|
| 43 |
+ msg.Type = unix.RTN_UNSPEC |
|
| 44 |
+ if req.NlMsghdr.Flags&unix.NLM_F_CREATE > 0 {
|
|
| 45 |
+ msg.Type = unix.RTN_UNICAST |
|
| 46 |
+ } |
|
| 47 |
+ if rule.Invert {
|
|
| 48 |
+ msg.Flags |= FibRuleInvert |
|
| 49 |
+ } |
|
| 40 | 50 |
if rule.Family != 0 {
|
| 41 | 51 |
msg.Family = uint8(rule.Family) |
| 42 | 52 |
} |
| 43 |
- var dstFamily uint8 |
|
| 53 |
+ if rule.Table >= 0 && rule.Table < 256 {
|
|
| 54 |
+ msg.Table = uint8(rule.Table) |
|
| 55 |
+ } |
|
| 44 | 56 |
|
| 57 |
+ var dstFamily uint8 |
|
| 45 | 58 |
var rtAttrs []*nl.RtAttr |
| 46 | 59 |
if rule.Dst != nil && rule.Dst.IP != nil {
|
| 47 | 60 |
dstLen, _ := rule.Dst.Mask.Size() |
| ... | ... |
@@ -49,12 +64,12 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
|
| 49 | 49 |
msg.Family = uint8(nl.GetIPFamily(rule.Dst.IP)) |
| 50 | 50 |
dstFamily = msg.Family |
| 51 | 51 |
var dstData []byte |
| 52 |
- if msg.Family == syscall.AF_INET {
|
|
| 52 |
+ if msg.Family == unix.AF_INET {
|
|
| 53 | 53 |
dstData = rule.Dst.IP.To4() |
| 54 | 54 |
} else {
|
| 55 | 55 |
dstData = rule.Dst.IP.To16() |
| 56 | 56 |
} |
| 57 |
- rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_DST, dstData)) |
|
| 57 |
+ rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_DST, dstData)) |
|
| 58 | 58 |
} |
| 59 | 59 |
|
| 60 | 60 |
if rule.Src != nil && rule.Src.IP != nil {
|
| ... | ... |
@@ -65,19 +80,12 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
|
| 65 | 65 |
srcLen, _ := rule.Src.Mask.Size() |
| 66 | 66 |
msg.Src_len = uint8(srcLen) |
| 67 | 67 |
var srcData []byte |
| 68 |
- if msg.Family == syscall.AF_INET {
|
|
| 68 |
+ if msg.Family == unix.AF_INET {
|
|
| 69 | 69 |
srcData = rule.Src.IP.To4() |
| 70 | 70 |
} else {
|
| 71 | 71 |
srcData = rule.Src.IP.To16() |
| 72 | 72 |
} |
| 73 |
- rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_SRC, srcData)) |
|
| 74 |
- } |
|
| 75 |
- |
|
| 76 |
- if rule.Table >= 0 {
|
|
| 77 |
- msg.Table = uint8(rule.Table) |
|
| 78 |
- if rule.Table >= 256 {
|
|
| 79 |
- msg.Table = syscall.RT_TABLE_UNSPEC |
|
| 80 |
- } |
|
| 73 |
+ rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_SRC, srcData)) |
|
| 81 | 74 |
} |
| 82 | 75 |
|
| 83 | 76 |
req.AddData(msg) |
| ... | ... |
@@ -142,7 +150,7 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
|
| 142 | 142 |
req.AddData(nl.NewRtAttr(nl.FRA_GOTO, b)) |
| 143 | 143 |
} |
| 144 | 144 |
|
| 145 |
- _, err := req.Execute(syscall.NETLINK_ROUTE, 0) |
|
| 145 |
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0) |
|
| 146 | 146 |
return err |
| 147 | 147 |
} |
| 148 | 148 |
|
| ... | ... |
@@ -155,11 +163,11 @@ func RuleList(family int) ([]Rule, error) {
|
| 155 | 155 |
// RuleList lists rules in the system. |
| 156 | 156 |
// Equivalent to: ip rule list |
| 157 | 157 |
func (h *Handle) RuleList(family int) ([]Rule, error) {
|
| 158 |
- req := h.newNetlinkRequest(syscall.RTM_GETRULE, syscall.NLM_F_DUMP|syscall.NLM_F_REQUEST) |
|
| 158 |
+ req := h.newNetlinkRequest(unix.RTM_GETRULE, unix.NLM_F_DUMP|unix.NLM_F_REQUEST) |
|
| 159 | 159 |
msg := nl.NewIfInfomsg(family) |
| 160 | 160 |
req.AddData(msg) |
| 161 | 161 |
|
| 162 |
- msgs, err := req.Execute(syscall.NETLINK_ROUTE, syscall.RTM_NEWRULE) |
|
| 162 |
+ msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWRULE) |
|
| 163 | 163 |
if err != nil {
|
| 164 | 164 |
return nil, err |
| 165 | 165 |
} |
| ... | ... |
@@ -175,9 +183,11 @@ func (h *Handle) RuleList(family int) ([]Rule, error) {
|
| 175 | 175 |
|
| 176 | 176 |
rule := NewRule() |
| 177 | 177 |
|
| 178 |
+ rule.Invert = msg.Flags&FibRuleInvert > 0 |
|
| 179 |
+ |
|
| 178 | 180 |
for j := range attrs {
|
| 179 | 181 |
switch attrs[j].Attr.Type {
|
| 180 |
- case syscall.RTA_TABLE: |
|
| 182 |
+ case unix.RTA_TABLE: |
|
| 181 | 183 |
rule.Table = int(native.Uint32(attrs[j].Value[0:4])) |
| 182 | 184 |
case nl.FRA_SRC: |
| 183 | 185 |
rule.Src = &net.IPNet{
|
| ... | ... |
@@ -4,9 +4,9 @@ import ( |
| 4 | 4 |
"errors" |
| 5 | 5 |
"fmt" |
| 6 | 6 |
"net" |
| 7 |
- "syscall" |
|
| 8 | 7 |
|
| 9 | 8 |
"github.com/vishvananda/netlink/nl" |
| 9 |
+ "golang.org/x/sys/unix" |
|
| 10 | 10 |
) |
| 11 | 11 |
|
| 12 | 12 |
const ( |
| ... | ... |
@@ -123,15 +123,15 @@ func SocketGet(local, remote net.Addr) (*Socket, error) {
|
| 123 | 123 |
return nil, ErrNotImplemented |
| 124 | 124 |
} |
| 125 | 125 |
|
| 126 |
- s, err := nl.Subscribe(syscall.NETLINK_INET_DIAG) |
|
| 126 |
+ s, err := nl.Subscribe(unix.NETLINK_INET_DIAG) |
|
| 127 | 127 |
if err != nil {
|
| 128 | 128 |
return nil, err |
| 129 | 129 |
} |
| 130 | 130 |
defer s.Close() |
| 131 | 131 |
req := nl.NewNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, 0) |
| 132 | 132 |
req.AddData(&socketRequest{
|
| 133 |
- Family: syscall.AF_INET, |
|
| 134 |
- Protocol: syscall.IPPROTO_TCP, |
|
| 133 |
+ Family: unix.AF_INET, |
|
| 134 |
+ Protocol: unix.IPPROTO_TCP, |
|
| 135 | 135 |
ID: SocketID{
|
| 136 | 136 |
SourcePort: uint16(localTCP.Port), |
| 137 | 137 |
DestinationPort: uint16(remoteTCP.Port), |
| ... | ... |
@@ -2,19 +2,20 @@ package netlink |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"fmt" |
| 5 |
- "syscall" |
|
| 5 |
+ |
|
| 6 |
+ "golang.org/x/sys/unix" |
|
| 6 | 7 |
) |
| 7 | 8 |
|
| 8 | 9 |
// Proto is an enum representing an ipsec protocol. |
| 9 | 10 |
type Proto uint8 |
| 10 | 11 |
|
| 11 | 12 |
const ( |
| 12 |
- XFRM_PROTO_ROUTE2 Proto = syscall.IPPROTO_ROUTING |
|
| 13 |
- XFRM_PROTO_ESP Proto = syscall.IPPROTO_ESP |
|
| 14 |
- XFRM_PROTO_AH Proto = syscall.IPPROTO_AH |
|
| 15 |
- XFRM_PROTO_HAO Proto = syscall.IPPROTO_DSTOPTS |
|
| 13 |
+ XFRM_PROTO_ROUTE2 Proto = unix.IPPROTO_ROUTING |
|
| 14 |
+ XFRM_PROTO_ESP Proto = unix.IPPROTO_ESP |
|
| 15 |
+ XFRM_PROTO_AH Proto = unix.IPPROTO_AH |
|
| 16 |
+ XFRM_PROTO_HAO Proto = unix.IPPROTO_DSTOPTS |
|
| 16 | 17 |
XFRM_PROTO_COMP Proto = 0x6c // NOTE not defined on darwin |
| 17 |
- XFRM_PROTO_IPSEC_ANY Proto = syscall.IPPROTO_RAW |
|
| 18 |
+ XFRM_PROTO_IPSEC_ANY Proto = unix.IPPROTO_RAW |
|
| 18 | 19 |
) |
| 19 | 20 |
|
| 20 | 21 |
func (p Proto) String() string {
|
| ... | ... |
@@ -2,11 +2,10 @@ package netlink |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"fmt" |
| 5 |
- "syscall" |
|
| 6 |
- |
|
| 7 |
- "github.com/vishvananda/netns" |
|
| 8 | 5 |
|
| 9 | 6 |
"github.com/vishvananda/netlink/nl" |
| 7 |
+ "github.com/vishvananda/netns" |
|
| 8 |
+ "golang.org/x/sys/unix" |
|
| 10 | 9 |
) |
| 11 | 10 |
|
| 12 | 11 |
type XfrmMsg interface {
|
| ... | ... |
@@ -39,7 +38,7 @@ func XfrmMonitor(ch chan<- XfrmMsg, done <-chan struct{}, errorChan chan<- error
|
| 39 | 39 |
if err != nil {
|
| 40 | 40 |
return nil |
| 41 | 41 |
} |
| 42 |
- s, err := nl.SubscribeAt(netns.None(), netns.None(), syscall.NETLINK_XFRM, groups...) |
|
| 42 |
+ s, err := nl.SubscribeAt(netns.None(), netns.None(), unix.NETLINK_XFRM, groups...) |
|
| 43 | 43 |
if err != nil {
|
| 44 | 44 |
return err |
| 45 | 45 |
} |
| ... | ... |
@@ -1,9 +1,8 @@ |
| 1 | 1 |
package netlink |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "syscall" |
|
| 5 |
- |
|
| 6 | 4 |
"github.com/vishvananda/netlink/nl" |
| 5 |
+ "golang.org/x/sys/unix" |
|
| 7 | 6 |
) |
| 8 | 7 |
|
| 9 | 8 |
func selFromPolicy(sel *nl.XfrmSelector, policy *XfrmPolicy) {
|
| ... | ... |
@@ -55,7 +54,7 @@ func (h *Handle) XfrmPolicyUpdate(policy *XfrmPolicy) error {
|
| 55 | 55 |
} |
| 56 | 56 |
|
| 57 | 57 |
func (h *Handle) xfrmPolicyAddOrUpdate(policy *XfrmPolicy, nlProto int) error {
|
| 58 |
- req := h.newNetlinkRequest(nlProto, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) |
|
| 58 |
+ req := h.newNetlinkRequest(nlProto, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK) |
|
| 59 | 59 |
|
| 60 | 60 |
msg := &nl.XfrmUserpolicyInfo{}
|
| 61 | 61 |
selFromPolicy(&msg.Sel, policy) |
| ... | ... |
@@ -91,7 +90,7 @@ func (h *Handle) xfrmPolicyAddOrUpdate(policy *XfrmPolicy, nlProto int) error {
|
| 91 | 91 |
req.AddData(out) |
| 92 | 92 |
} |
| 93 | 93 |
|
| 94 |
- _, err := req.Execute(syscall.NETLINK_XFRM, 0) |
|
| 94 |
+ _, err := req.Execute(unix.NETLINK_XFRM, 0) |
|
| 95 | 95 |
return err |
| 96 | 96 |
} |
| 97 | 97 |
|
| ... | ... |
@@ -121,12 +120,12 @@ func XfrmPolicyList(family int) ([]XfrmPolicy, error) {
|
| 121 | 121 |
// Equivalent to: `ip xfrm policy show`. |
| 122 | 122 |
// The list can be filtered by ip family. |
| 123 | 123 |
func (h *Handle) XfrmPolicyList(family int) ([]XfrmPolicy, error) {
|
| 124 |
- req := h.newNetlinkRequest(nl.XFRM_MSG_GETPOLICY, syscall.NLM_F_DUMP) |
|
| 124 |
+ req := h.newNetlinkRequest(nl.XFRM_MSG_GETPOLICY, unix.NLM_F_DUMP) |
|
| 125 | 125 |
|
| 126 | 126 |
msg := nl.NewIfInfomsg(family) |
| 127 | 127 |
req.AddData(msg) |
| 128 | 128 |
|
| 129 |
- msgs, err := req.Execute(syscall.NETLINK_XFRM, nl.XFRM_MSG_NEWPOLICY) |
|
| 129 |
+ msgs, err := req.Execute(unix.NETLINK_XFRM, nl.XFRM_MSG_NEWPOLICY) |
|
| 130 | 130 |
if err != nil {
|
| 131 | 131 |
return nil, err |
| 132 | 132 |
} |
| ... | ... |
@@ -165,13 +164,13 @@ func XfrmPolicyFlush() error {
|
| 165 | 165 |
// XfrmPolicyFlush will flush the policies on the system. |
| 166 | 166 |
// Equivalent to: `ip xfrm policy flush` |
| 167 | 167 |
func (h *Handle) XfrmPolicyFlush() error {
|
| 168 |
- req := h.newNetlinkRequest(nl.XFRM_MSG_FLUSHPOLICY, syscall.NLM_F_ACK) |
|
| 169 |
- _, err := req.Execute(syscall.NETLINK_XFRM, 0) |
|
| 168 |
+ req := h.newNetlinkRequest(nl.XFRM_MSG_FLUSHPOLICY, unix.NLM_F_ACK) |
|
| 169 |
+ _, err := req.Execute(unix.NETLINK_XFRM, 0) |
|
| 170 | 170 |
return err |
| 171 | 171 |
} |
| 172 | 172 |
|
| 173 | 173 |
func (h *Handle) xfrmPolicyGetOrDelete(policy *XfrmPolicy, nlProto int) (*XfrmPolicy, error) {
|
| 174 |
- req := h.newNetlinkRequest(nlProto, syscall.NLM_F_ACK) |
|
| 174 |
+ req := h.newNetlinkRequest(nlProto, unix.NLM_F_ACK) |
|
| 175 | 175 |
|
| 176 | 176 |
msg := &nl.XfrmUserpolicyId{}
|
| 177 | 177 |
selFromPolicy(&msg.Sel, policy) |
| ... | ... |
@@ -189,7 +188,7 @@ func (h *Handle) xfrmPolicyGetOrDelete(policy *XfrmPolicy, nlProto int) (*XfrmPo |
| 189 | 189 |
resType = 0 |
| 190 | 190 |
} |
| 191 | 191 |
|
| 192 |
- msgs, err := req.Execute(syscall.NETLINK_XFRM, uint16(resType)) |
|
| 192 |
+ msgs, err := req.Execute(unix.NETLINK_XFRM, uint16(resType)) |
|
| 193 | 193 |
if err != nil {
|
| 194 | 194 |
return nil, err |
| 195 | 195 |
} |
| ... | ... |
@@ -3,6 +3,7 @@ package netlink |
| 3 | 3 |
import ( |
| 4 | 4 |
"fmt" |
| 5 | 5 |
"net" |
| 6 |
+ "time" |
|
| 6 | 7 |
) |
| 7 | 8 |
|
| 8 | 9 |
// XfrmStateAlgo represents the algorithm to use for the ipsec encryption. |
| ... | ... |
@@ -67,6 +68,19 @@ type XfrmStateLimits struct {
|
| 67 | 67 |
TimeUseHard uint64 |
| 68 | 68 |
} |
| 69 | 69 |
|
| 70 |
+// XfrmStateStats represents the current number of bytes/packets |
|
| 71 |
+// processed by this State, the State's installation and first use |
|
| 72 |
+// time and the replay window counters. |
|
| 73 |
+type XfrmStateStats struct {
|
|
| 74 |
+ ReplayWindow uint32 |
|
| 75 |
+ Replay uint32 |
|
| 76 |
+ Failed uint32 |
|
| 77 |
+ Bytes uint64 |
|
| 78 |
+ Packets uint64 |
|
| 79 |
+ AddTime uint64 |
|
| 80 |
+ UseTime uint64 |
|
| 81 |
+} |
|
| 82 |
+ |
|
| 70 | 83 |
// XfrmState represents the state of an ipsec policy. It optionally |
| 71 | 84 |
// contains an XfrmStateAlgo for encryption and one for authentication. |
| 72 | 85 |
type XfrmState struct {
|
| ... | ... |
@@ -78,6 +92,7 @@ type XfrmState struct {
|
| 78 | 78 |
Reqid int |
| 79 | 79 |
ReplayWindow int |
| 80 | 80 |
Limits XfrmStateLimits |
| 81 |
+ Statistics XfrmStateStats |
|
| 81 | 82 |
Mark *XfrmMark |
| 82 | 83 |
Auth *XfrmStateAlgo |
| 83 | 84 |
Crypt *XfrmStateAlgo |
| ... | ... |
@@ -94,10 +109,16 @@ func (sa XfrmState) Print(stats bool) string {
|
| 94 | 94 |
if !stats {
|
| 95 | 95 |
return sa.String() |
| 96 | 96 |
} |
| 97 |
- |
|
| 98 |
- return fmt.Sprintf("%s, ByteSoft: %s, ByteHard: %s, PacketSoft: %s, PacketHard: %s, TimeSoft: %d, TimeHard: %d, TimeUseSoft: %d, TimeUseHard: %d",
|
|
| 97 |
+ at := time.Unix(int64(sa.Statistics.AddTime), 0).Format(time.UnixDate) |
|
| 98 |
+ ut := "-" |
|
| 99 |
+ if sa.Statistics.UseTime > 0 {
|
|
| 100 |
+ ut = time.Unix(int64(sa.Statistics.UseTime), 0).Format(time.UnixDate) |
|
| 101 |
+ } |
|
| 102 |
+ return fmt.Sprintf("%s, ByteSoft: %s, ByteHard: %s, PacketSoft: %s, PacketHard: %s, TimeSoft: %d, TimeHard: %d, TimeUseSoft: %d, TimeUseHard: %d, Bytes: %d, Packets: %d, "+
|
|
| 103 |
+ "AddTime: %s, UseTime: %s, ReplayWindow: %d, Replay: %d, Failed: %d", |
|
| 99 | 104 |
sa.String(), printLimit(sa.Limits.ByteSoft), printLimit(sa.Limits.ByteHard), printLimit(sa.Limits.PacketSoft), printLimit(sa.Limits.PacketHard), |
| 100 |
- sa.Limits.TimeSoft, sa.Limits.TimeHard, sa.Limits.TimeUseSoft, sa.Limits.TimeUseHard) |
|
| 105 |
+ sa.Limits.TimeSoft, sa.Limits.TimeHard, sa.Limits.TimeUseSoft, sa.Limits.TimeUseHard, sa.Statistics.Bytes, sa.Statistics.Packets, at, ut, |
|
| 106 |
+ sa.Statistics.ReplayWindow, sa.Statistics.Replay, sa.Statistics.Failed) |
|
| 101 | 107 |
} |
| 102 | 108 |
|
| 103 | 109 |
func printLimit(lmt uint64) string {
|
| ... | ... |
@@ -2,10 +2,10 @@ package netlink |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"fmt" |
| 5 |
- "syscall" |
|
| 6 | 5 |
"unsafe" |
| 7 | 6 |
|
| 8 | 7 |
"github.com/vishvananda/netlink/nl" |
| 8 |
+ "golang.org/x/sys/unix" |
|
| 9 | 9 |
) |
| 10 | 10 |
|
| 11 | 11 |
func writeStateAlgo(a *XfrmStateAlgo) []byte {
|
| ... | ... |
@@ -69,8 +69,10 @@ func writeReplayEsn(replayWindow int) []byte {
|
| 69 | 69 |
ReplayWindow: uint32(replayWindow), |
| 70 | 70 |
} |
| 71 | 71 |
|
| 72 |
- // taken from iproute2/ip/xfrm_state.c: |
|
| 73 |
- replayEsn.BmpLen = uint32((replayWindow + (4 * 8) - 1) / (4 * 8)) |
|
| 72 |
+ // Linux stores the bitmap to identify the already received sequence packets in blocks of uint32 elements. |
|
| 73 |
+ // Therefore bitmap length is the minimum number of uint32 elements needed. The following is a ceiling operation. |
|
| 74 |
+ bytesPerElem := int(unsafe.Sizeof(replayEsn.BmpLen)) // Any uint32 variable is good for this |
|
| 75 |
+ replayEsn.BmpLen = uint32((replayWindow + (bytesPerElem * 8) - 1) / (bytesPerElem * 8)) |
|
| 74 | 76 |
|
| 75 | 77 |
return replayEsn.Serialize() |
| 76 | 78 |
} |
| ... | ... |
@@ -111,7 +113,7 @@ func (h *Handle) xfrmStateAddOrUpdate(state *XfrmState, nlProto int) error {
|
| 111 | 111 |
if state.Spi == 0 {
|
| 112 | 112 |
return fmt.Errorf("Spi must be set when adding xfrm state.")
|
| 113 | 113 |
} |
| 114 |
- req := h.newNetlinkRequest(nlProto, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) |
|
| 114 |
+ req := h.newNetlinkRequest(nlProto, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK) |
|
| 115 | 115 |
|
| 116 | 116 |
msg := xfrmUsersaInfoFromXfrmState(state) |
| 117 | 117 |
|
| ... | ... |
@@ -157,13 +159,13 @@ func (h *Handle) xfrmStateAddOrUpdate(state *XfrmState, nlProto int) error {
|
| 157 | 157 |
req.AddData(out) |
| 158 | 158 |
} |
| 159 | 159 |
|
| 160 |
- _, err := req.Execute(syscall.NETLINK_XFRM, 0) |
|
| 160 |
+ _, err := req.Execute(unix.NETLINK_XFRM, 0) |
|
| 161 | 161 |
return err |
| 162 | 162 |
} |
| 163 | 163 |
|
| 164 | 164 |
func (h *Handle) xfrmStateAllocSpi(state *XfrmState) (*XfrmState, error) {
|
| 165 | 165 |
req := h.newNetlinkRequest(nl.XFRM_MSG_ALLOCSPI, |
| 166 |
- syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) |
|
| 166 |
+ unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK) |
|
| 167 | 167 |
|
| 168 | 168 |
msg := &nl.XfrmUserSpiInfo{}
|
| 169 | 169 |
msg.XfrmUsersaInfo = *(xfrmUsersaInfoFromXfrmState(state)) |
| ... | ... |
@@ -177,7 +179,7 @@ func (h *Handle) xfrmStateAllocSpi(state *XfrmState) (*XfrmState, error) {
|
| 177 | 177 |
req.AddData(out) |
| 178 | 178 |
} |
| 179 | 179 |
|
| 180 |
- msgs, err := req.Execute(syscall.NETLINK_XFRM, 0) |
|
| 180 |
+ msgs, err := req.Execute(unix.NETLINK_XFRM, 0) |
|
| 181 | 181 |
if err != nil {
|
| 182 | 182 |
return nil, err |
| 183 | 183 |
} |
| ... | ... |
@@ -216,9 +218,9 @@ func XfrmStateList(family int) ([]XfrmState, error) {
|
| 216 | 216 |
// Equivalent to: `ip xfrm state show`. |
| 217 | 217 |
// The list can be filtered by ip family. |
| 218 | 218 |
func (h *Handle) XfrmStateList(family int) ([]XfrmState, error) {
|
| 219 |
- req := h.newNetlinkRequest(nl.XFRM_MSG_GETSA, syscall.NLM_F_DUMP) |
|
| 219 |
+ req := h.newNetlinkRequest(nl.XFRM_MSG_GETSA, unix.NLM_F_DUMP) |
|
| 220 | 220 |
|
| 221 |
- msgs, err := req.Execute(syscall.NETLINK_XFRM, nl.XFRM_MSG_NEWSA) |
|
| 221 |
+ msgs, err := req.Execute(unix.NETLINK_XFRM, nl.XFRM_MSG_NEWSA) |
|
| 222 | 222 |
if err != nil {
|
| 223 | 223 |
return nil, err |
| 224 | 224 |
} |
| ... | ... |
@@ -255,7 +257,7 @@ func (h *Handle) XfrmStateGet(state *XfrmState) (*XfrmState, error) {
|
| 255 | 255 |
} |
| 256 | 256 |
|
| 257 | 257 |
func (h *Handle) xfrmStateGetOrDelete(state *XfrmState, nlProto int) (*XfrmState, error) {
|
| 258 |
- req := h.newNetlinkRequest(nlProto, syscall.NLM_F_ACK) |
|
| 258 |
+ req := h.newNetlinkRequest(nlProto, unix.NLM_F_ACK) |
|
| 259 | 259 |
|
| 260 | 260 |
msg := &nl.XfrmUsersaId{}
|
| 261 | 261 |
msg.Family = uint16(nl.GetIPFamily(state.Dst)) |
| ... | ... |
@@ -278,7 +280,7 @@ func (h *Handle) xfrmStateGetOrDelete(state *XfrmState, nlProto int) (*XfrmState |
| 278 | 278 |
resType = 0 |
| 279 | 279 |
} |
| 280 | 280 |
|
| 281 |
- msgs, err := req.Execute(syscall.NETLINK_XFRM, uint16(resType)) |
|
| 281 |
+ msgs, err := req.Execute(unix.NETLINK_XFRM, uint16(resType)) |
|
| 282 | 282 |
if err != nil {
|
| 283 | 283 |
return nil, err |
| 284 | 284 |
} |
| ... | ... |
@@ -308,6 +310,7 @@ func xfrmStateFromXfrmUsersaInfo(msg *nl.XfrmUsersaInfo) *XfrmState {
|
| 308 | 308 |
state.Reqid = int(msg.Reqid) |
| 309 | 309 |
state.ReplayWindow = int(msg.ReplayWindow) |
| 310 | 310 |
lftToLimits(&msg.Lft, &state.Limits) |
| 311 |
+ curToStats(&msg.Curlft, &msg.Stats, &state.Statistics) |
|
| 311 | 312 |
|
| 312 | 313 |
return &state |
| 313 | 314 |
} |
| ... | ... |
@@ -386,11 +389,11 @@ func XfrmStateFlush(proto Proto) error {
|
| 386 | 386 |
// proto = 0 means any transformation protocols |
| 387 | 387 |
// Equivalent to: `ip xfrm state flush [ proto XFRM-PROTO ]` |
| 388 | 388 |
func (h *Handle) XfrmStateFlush(proto Proto) error {
|
| 389 |
- req := h.newNetlinkRequest(nl.XFRM_MSG_FLUSHSA, syscall.NLM_F_ACK) |
|
| 389 |
+ req := h.newNetlinkRequest(nl.XFRM_MSG_FLUSHSA, unix.NLM_F_ACK) |
|
| 390 | 390 |
|
| 391 | 391 |
req.AddData(&nl.XfrmUsersaFlush{Proto: uint8(proto)})
|
| 392 | 392 |
|
| 393 |
- _, err := req.Execute(syscall.NETLINK_XFRM, 0) |
|
| 393 |
+ _, err := req.Execute(unix.NETLINK_XFRM, 0) |
|
| 394 | 394 |
if err != nil {
|
| 395 | 395 |
return err |
| 396 | 396 |
} |
| ... | ... |
@@ -429,6 +432,16 @@ func lftToLimits(lft *nl.XfrmLifetimeCfg, lmts *XfrmStateLimits) {
|
| 429 | 429 |
*lmts = *(*XfrmStateLimits)(unsafe.Pointer(lft)) |
| 430 | 430 |
} |
| 431 | 431 |
|
| 432 |
+func curToStats(cur *nl.XfrmLifetimeCur, wstats *nl.XfrmStats, stats *XfrmStateStats) {
|
|
| 433 |
+ stats.Bytes = cur.Bytes |
|
| 434 |
+ stats.Packets = cur.Packets |
|
| 435 |
+ stats.AddTime = cur.AddTime |
|
| 436 |
+ stats.UseTime = cur.UseTime |
|
| 437 |
+ stats.ReplayWindow = wstats.ReplayWindow |
|
| 438 |
+ stats.Replay = wstats.Replay |
|
| 439 |
+ stats.Failed = wstats.IntegrityFailed |
|
| 440 |
+} |
|
| 441 |
+ |
|
| 432 | 442 |
func xfrmUsersaInfoFromXfrmState(state *XfrmState) *nl.XfrmUsersaInfo {
|
| 433 | 443 |
msg := &nl.XfrmUsersaInfo{}
|
| 434 | 444 |
msg.Family = uint16(nl.GetIPFamily(state.Dst)) |
| ... | ... |
@@ -20,9 +20,10 @@ Testing (requires root): |
| 20 | 20 |
package main |
| 21 | 21 |
|
| 22 | 22 |
import ( |
| 23 |
+ "fmt" |
|
| 23 | 24 |
"net" |
| 24 | 25 |
"runtime" |
| 25 |
- "github.com/vishvananada/netns" |
|
| 26 |
+ "github.com/vishvananda/netns" |
|
| 26 | 27 |
) |
| 27 | 28 |
|
| 28 | 29 |
func main() {
|
| ... | ... |
@@ -36,9 +37,10 @@ func main() {
|
| 36 | 36 |
|
| 37 | 37 |
// Create a new network namespace |
| 38 | 38 |
newns, _ := netns.New() |
| 39 |
+ netns.Set(newns) |
|
| 39 | 40 |
defer newns.Close() |
| 40 | 41 |
|
| 41 |
- // Do something with tne network namespace |
|
| 42 |
+ // Do something with the network namespace |
|
| 42 | 43 |
ifaces, _ := net.Interfaces() |
| 43 | 44 |
fmt.Printf("Interfaces: %v\n", ifaces)
|
| 44 | 45 |
|
| ... | ... |
@@ -19,7 +19,7 @@ type NsHandle int |
| 19 | 19 |
|
| 20 | 20 |
// Equal determines if two network handles refer to the same network |
| 21 | 21 |
// namespace. This is done by comparing the device and inode that the |
| 22 |
-// file descripors point to. |
|
| 22 |
+// file descriptors point to. |
|
| 23 | 23 |
func (ns NsHandle) Equal(other NsHandle) bool {
|
| 24 | 24 |
if ns == other {
|
| 25 | 25 |
return true |
| ... | ... |
@@ -46,6 +46,19 @@ func (ns NsHandle) String() string {
|
| 46 | 46 |
return fmt.Sprintf("NS(%d: %d, %d)", ns, s.Dev, s.Ino)
|
| 47 | 47 |
} |
| 48 | 48 |
|
| 49 |
+// UniqueId returns a string which uniquely identifies the namespace |
|
| 50 |
+// associated with the network handle. |
|
| 51 |
+func (ns NsHandle) UniqueId() string {
|
|
| 52 |
+ var s syscall.Stat_t |
|
| 53 |
+ if ns == -1 {
|
|
| 54 |
+ return "NS(none)" |
|
| 55 |
+ } |
|
| 56 |
+ if err := syscall.Fstat(int(ns), &s); err != nil {
|
|
| 57 |
+ return "NS(unknown)" |
|
| 58 |
+ } |
|
| 59 |
+ return fmt.Sprintf("NS(%d:%d)", s.Dev, s.Ino)
|
|
| 60 |
+} |
|
| 61 |
+ |
|
| 49 | 62 |
// IsOpen returns true if Close() has not been called. |
| 50 | 63 |
func (ns NsHandle) IsOpen() bool {
|
| 51 | 64 |
return ns != -1 |
| ... | ... |
@@ -61,7 +74,7 @@ func (ns *NsHandle) Close() error {
|
| 61 | 61 |
return nil |
| 62 | 62 |
} |
| 63 | 63 |
|
| 64 |
-// Get an empty (closed) NsHandle |
|
| 64 |
+// None gets an empty (closed) NsHandle. |
|
| 65 | 65 |
func None() NsHandle {
|
| 66 | 66 |
return NsHandle(-1) |
| 67 | 67 |
} |
| ... | ... |
@@ -7,14 +7,27 @@ import ( |
| 7 | 7 |
"io/ioutil" |
| 8 | 8 |
"os" |
| 9 | 9 |
"path/filepath" |
| 10 |
+ "runtime" |
|
| 10 | 11 |
"strconv" |
| 11 | 12 |
"strings" |
| 12 | 13 |
"syscall" |
| 13 | 14 |
) |
| 14 | 15 |
|
| 16 |
+// SYS_SETNS syscall allows changing the namespace of the current process. |
|
| 17 |
+var SYS_SETNS = map[string]uintptr{
|
|
| 18 |
+ "386": 346, |
|
| 19 |
+ "amd64": 308, |
|
| 20 |
+ "arm64": 268, |
|
| 21 |
+ "arm": 375, |
|
| 22 |
+ "mips": 4344, |
|
| 23 |
+ "mipsle": 4344, |
|
| 24 |
+ "ppc64": 350, |
|
| 25 |
+ "ppc64le": 350, |
|
| 26 |
+ "s390x": 339, |
|
| 27 |
+}[runtime.GOARCH] |
|
| 28 |
+ |
|
| 29 |
+// Deprecated: use syscall pkg instead (go >= 1.5 needed). |
|
| 15 | 30 |
const ( |
| 16 |
- // These constants belong in the syscall library but have not been |
|
| 17 |
- // added yet. |
|
| 18 | 31 |
CLONE_NEWUTS = 0x04000000 /* New utsname group? */ |
| 19 | 32 |
CLONE_NEWIPC = 0x08000000 /* New ipcs */ |
| 20 | 33 |
CLONE_NEWUSER = 0x10000000 /* New user namespace */ |
| ... | ... |
@@ -125,7 +138,9 @@ func getThisCgroup(cgroupType string) (string, error) {
|
| 125 | 125 |
return "", fmt.Errorf("docker pid not found in /var/run/docker.pid")
|
| 126 | 126 |
} |
| 127 | 127 |
pid, err := strconv.Atoi(result[0]) |
| 128 |
- |
|
| 128 |
+ if err != nil {
|
|
| 129 |
+ return "", err |
|
| 130 |
+ } |
|
| 129 | 131 |
output, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cgroup", pid))
|
| 130 | 132 |
if err != nil {
|
| 131 | 133 |
return "", err |
| ... | ... |
@@ -167,8 +182,18 @@ func getPidForContainer(id string) (int, error) {
|
| 167 | 167 |
filepath.Join(cgroupRoot, cgroupThis, id, "tasks"), |
| 168 | 168 |
// With more recent lxc versions use, cgroup will be in lxc/ |
| 169 | 169 |
filepath.Join(cgroupRoot, cgroupThis, "lxc", id, "tasks"), |
| 170 |
- // With more recent dockee, cgroup will be in docker/ |
|
| 170 |
+ // With more recent docker, cgroup will be in docker/ |
|
| 171 | 171 |
filepath.Join(cgroupRoot, cgroupThis, "docker", id, "tasks"), |
| 172 |
+ // Even more recent docker versions under systemd use docker-<id>.scope/ |
|
| 173 |
+ filepath.Join(cgroupRoot, "system.slice", "docker-"+id+".scope", "tasks"), |
|
| 174 |
+ // Even more recent docker versions under cgroup/systemd/docker/<id>/ |
|
| 175 |
+ filepath.Join(cgroupRoot, "..", "systemd", "docker", id, "tasks"), |
|
| 176 |
+ // Kubernetes with docker and CNI is even more different |
|
| 177 |
+ filepath.Join(cgroupRoot, "..", "systemd", "kubepods", "*", "pod*", id, "tasks"), |
|
| 178 |
+ // Another flavor of containers location in recent kubernetes 1.11+ |
|
| 179 |
+ filepath.Join(cgroupRoot, cgroupThis, "kubepods.slice", "kubepods-besteffort.slice", "*", "docker-"+id+".scope", "tasks"), |
|
| 180 |
+ // When runs inside of a container with recent kubernetes 1.11+ |
|
| 181 |
+ filepath.Join(cgroupRoot, "kubepods.slice", "kubepods-besteffort.slice", "*", "docker-"+id+".scope", "tasks"), |
|
| 172 | 182 |
} |
| 173 | 183 |
|
| 174 | 184 |
var filename string |
| ... | ... |
@@ -22,6 +22,10 @@ func Get() (NsHandle, error) {
|
| 22 | 22 |
return -1, ErrNotImplemented |
| 23 | 23 |
} |
| 24 | 24 |
|
| 25 |
+func GetFromPath(path string) (NsHandle, error) {
|
|
| 26 |
+ return -1, ErrNotImplemented |
|
| 27 |
+} |
|
| 28 |
+ |
|
| 25 | 29 |
func GetFromName(name string) (NsHandle, error) {
|
| 26 | 30 |
return -1, ErrNotImplemented |
| 27 | 31 |
} |
| ... | ... |
@@ -30,6 +34,10 @@ func GetFromPid(pid int) (NsHandle, error) {
|
| 30 | 30 |
return -1, ErrNotImplemented |
| 31 | 31 |
} |
| 32 | 32 |
|
| 33 |
+func GetFromThread(pid, tid int) (NsHandle, error) {
|
|
| 34 |
+ return -1, ErrNotImplemented |
|
| 35 |
+} |
|
| 36 |
+ |
|
| 33 | 37 |
func GetFromDocker(id string) (NsHandle, error) {
|
| 34 | 38 |
return -1, ErrNotImplemented |
| 35 | 39 |
} |