Merge pull request #375 from aaithal/complieOnNonLinuxPlatforms
pkg/ns: refactored so that builds succeed on non-linux platforms
This commit is contained in:
commit
94e02e0768
54
Godeps/Godeps.json
generated
54
Godeps/Godeps.json
generated
@ -1,7 +1,7 @@
|
||||
{
|
||||
"ImportPath": "github.com/containernetworking/cni",
|
||||
"GoVersion": "go1.6",
|
||||
"GodepVersion": "v75",
|
||||
"GodepVersion": "v79",
|
||||
"Packages": [
|
||||
"./..."
|
||||
],
|
||||
@ -39,46 +39,6 @@
|
||||
"Comment": "v1.2.0-29-g7f8ab55",
|
||||
"Rev": "7f8ab55aaf3b86885aa55b762e803744d1674700"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/onsi/ginkgo/ginkgo",
|
||||
"Comment": "v1.2.0-29-g7f8ab55",
|
||||
"Rev": "7f8ab55aaf3b86885aa55b762e803744d1674700"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/onsi/ginkgo/ginkgo/convert",
|
||||
"Comment": "v1.2.0-29-g7f8ab55",
|
||||
"Rev": "7f8ab55aaf3b86885aa55b762e803744d1674700"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/onsi/ginkgo/ginkgo/interrupthandler",
|
||||
"Comment": "v1.2.0-29-g7f8ab55",
|
||||
"Rev": "7f8ab55aaf3b86885aa55b762e803744d1674700"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/onsi/ginkgo/ginkgo/nodot",
|
||||
"Comment": "v1.2.0-29-g7f8ab55",
|
||||
"Rev": "7f8ab55aaf3b86885aa55b762e803744d1674700"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/onsi/ginkgo/ginkgo/testrunner",
|
||||
"Comment": "v1.2.0-29-g7f8ab55",
|
||||
"Rev": "7f8ab55aaf3b86885aa55b762e803744d1674700"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/onsi/ginkgo/ginkgo/testsuite",
|
||||
"Comment": "v1.2.0-29-g7f8ab55",
|
||||
"Rev": "7f8ab55aaf3b86885aa55b762e803744d1674700"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/onsi/ginkgo/ginkgo/watch",
|
||||
"Comment": "v1.2.0-29-g7f8ab55",
|
||||
"Rev": "7f8ab55aaf3b86885aa55b762e803744d1674700"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/onsi/ginkgo/integration",
|
||||
"Comment": "v1.2.0-29-g7f8ab55",
|
||||
"Rev": "7f8ab55aaf3b86885aa55b762e803744d1674700"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/onsi/ginkgo/internal/codelocation",
|
||||
"Comment": "v1.2.0-29-g7f8ab55",
|
||||
@ -216,19 +176,19 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vishvananda/netlink",
|
||||
"Rev": "a1f8555521646b5a9800f39c5fd477597697135c"
|
||||
"Rev": "fe3b5664d23a11b52ba59bece4ff29c52772a56b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vishvananda/netlink/nl",
|
||||
"Rev": "a1f8555521646b5a9800f39c5fd477597697135c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/sys/unix",
|
||||
"Rev": "076b546753157f758b316e59bcb51e6807c04057"
|
||||
"Rev": "fe3b5664d23a11b52ba59bece4ff29c52772a56b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/vishvananda/netns",
|
||||
"Rev": "8ba1072b58e0c2a240eb5f6120165c7776c3e7b8"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/sys/unix",
|
||||
"Rev": "076b546753157f758b316e59bcb51e6807c04057"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -25,23 +25,3 @@ func AddDefaultRoute(gw net.IP, dev netlink.Link) error {
|
||||
_, defNet, _ := net.ParseCIDR("0.0.0.0/0")
|
||||
return AddRoute(defNet, gw, dev)
|
||||
}
|
||||
|
||||
// AddRoute adds a universally-scoped route to a device.
|
||||
func AddRoute(ipn *net.IPNet, gw net.IP, dev netlink.Link) error {
|
||||
return netlink.RouteAdd(&netlink.Route{
|
||||
LinkIndex: dev.Attrs().Index,
|
||||
Scope: netlink.SCOPE_UNIVERSE,
|
||||
Dst: ipn,
|
||||
Gw: gw,
|
||||
})
|
||||
}
|
||||
|
||||
// AddHostRoute adds a host-scoped route to a device.
|
||||
func AddHostRoute(ipn *net.IPNet, gw net.IP, dev netlink.Link) error {
|
||||
return netlink.RouteAdd(&netlink.Route{
|
||||
LinkIndex: dev.Attrs().Index,
|
||||
Scope: netlink.SCOPE_HOST,
|
||||
Dst: ipn,
|
||||
Gw: gw,
|
||||
})
|
||||
}
|
||||
|
41
pkg/ip/route_linux.go
Normal file
41
pkg/ip/route_linux.go
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright 2015-2017 CNI authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package ip
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/vishvananda/netlink"
|
||||
)
|
||||
|
||||
// AddRoute adds a universally-scoped route to a device.
|
||||
func AddRoute(ipn *net.IPNet, gw net.IP, dev netlink.Link) error {
|
||||
return netlink.RouteAdd(&netlink.Route{
|
||||
LinkIndex: dev.Attrs().Index,
|
||||
Scope: netlink.SCOPE_UNIVERSE,
|
||||
Dst: ipn,
|
||||
Gw: gw,
|
||||
})
|
||||
}
|
||||
|
||||
// AddHostRoute adds a host-scoped route to a device.
|
||||
func AddHostRoute(ipn *net.IPNet, gw net.IP, dev netlink.Link) error {
|
||||
return netlink.RouteAdd(&netlink.Route{
|
||||
LinkIndex: dev.Attrs().Index,
|
||||
Scope: netlink.SCOPE_HOST,
|
||||
Dst: ipn,
|
||||
Gw: gw,
|
||||
})
|
||||
}
|
34
pkg/ip/route_unspecified.go
Normal file
34
pkg/ip/route_unspecified.go
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright 2015-2017 CNI authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build !linux
|
||||
|
||||
package ip
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
"github.com/vishvananda/netlink"
|
||||
)
|
||||
|
||||
// AddRoute adds a universally-scoped route to a device.
|
||||
func AddRoute(ipn *net.IPNet, gw net.IP, dev netlink.Link) error {
|
||||
return types.NotImplementedError
|
||||
}
|
||||
|
||||
// AddHostRoute adds a host-scoped route to a device.
|
||||
func AddHostRoute(ipn *net.IPNet, gw net.IP, dev netlink.Link) error {
|
||||
return types.NotImplementedError
|
||||
}
|
131
pkg/ns/ns.go
131
pkg/ns/ns.go
@ -15,15 +15,11 @@
|
||||
package ns
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
type NetNS interface {
|
||||
@ -65,18 +61,6 @@ type netNS struct {
|
||||
// netNS implements the NetNS interface
|
||||
var _ NetNS = &netNS{}
|
||||
|
||||
func getCurrentThreadNetNSPath() string {
|
||||
// /proc/self/ns/net returns the namespace of the main thread, not
|
||||
// of whatever thread this goroutine is running on. Make sure we
|
||||
// use the thread's net namespace since the thread is switching around
|
||||
return fmt.Sprintf("/proc/%d/task/%d/ns/net", os.Getpid(), unix.Gettid())
|
||||
}
|
||||
|
||||
// Returns an object representing the current OS thread's network namespace
|
||||
func GetCurrentNS() (NetNS, error) {
|
||||
return GetNS(getCurrentThreadNetNSPath())
|
||||
}
|
||||
|
||||
const (
|
||||
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/magic.h
|
||||
NSFS_MAGIC = 0x6e736673
|
||||
@ -125,82 +109,6 @@ func GetNS(nspath string) (NetNS, error) {
|
||||
return &netNS{file: fd}, nil
|
||||
}
|
||||
|
||||
// Creates a new persistent network namespace and returns an object
|
||||
// representing that namespace, without switching to it
|
||||
func NewNS() (NetNS, error) {
|
||||
const nsRunDir = "/var/run/netns"
|
||||
|
||||
b := make([]byte, 16)
|
||||
_, err := rand.Reader.Read(b)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate random netns name: %v", err)
|
||||
}
|
||||
|
||||
err = os.MkdirAll(nsRunDir, 0755)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// create an empty file at the mount point
|
||||
nsName := fmt.Sprintf("cni-%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
|
||||
nsPath := path.Join(nsRunDir, nsName)
|
||||
mountPointFd, err := os.Create(nsPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mountPointFd.Close()
|
||||
|
||||
// Ensure the mount point is cleaned up on errors; if the namespace
|
||||
// was successfully mounted this will have no effect because the file
|
||||
// is in-use
|
||||
defer os.RemoveAll(nsPath)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
|
||||
// do namespace work in a dedicated goroutine, so that we can safely
|
||||
// Lock/Unlock OSThread without upsetting the lock/unlock state of
|
||||
// the caller of this function
|
||||
var fd *os.File
|
||||
go (func() {
|
||||
defer wg.Done()
|
||||
runtime.LockOSThread()
|
||||
|
||||
var origNS NetNS
|
||||
origNS, err = GetNS(getCurrentThreadNetNSPath())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer origNS.Close()
|
||||
|
||||
// create a new netns on the current thread
|
||||
err = unix.Unshare(unix.CLONE_NEWNET)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer origNS.Set()
|
||||
|
||||
// bind mount the new netns from the current thread onto the mount point
|
||||
err = unix.Mount(getCurrentThreadNetNSPath(), nsPath, "none", unix.MS_BIND, "")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fd, err = os.Open(nsPath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
})()
|
||||
wg.Wait()
|
||||
|
||||
if err != nil {
|
||||
unix.Unmount(nsPath, unix.MNT_DETACH)
|
||||
return nil, fmt.Errorf("failed to create namespace: %v", err)
|
||||
}
|
||||
|
||||
return &netNS{file: fd, mounted: true}, nil
|
||||
}
|
||||
|
||||
func (ns *netNS) Path() string {
|
||||
return ns.file.Name()
|
||||
}
|
||||
@ -216,36 +124,13 @@ func (ns *netNS) errorIfClosed() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ns *netNS) Close() error {
|
||||
if err := ns.errorIfClosed(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ns.file.Close(); err != nil {
|
||||
return fmt.Errorf("Failed to close %q: %v", ns.file.Name(), err)
|
||||
}
|
||||
ns.closed = true
|
||||
|
||||
if ns.mounted {
|
||||
if err := unix.Unmount(ns.file.Name(), unix.MNT_DETACH); err != nil {
|
||||
return fmt.Errorf("Failed to unmount namespace %s: %v", ns.file.Name(), err)
|
||||
}
|
||||
if err := os.RemoveAll(ns.file.Name()); err != nil {
|
||||
return fmt.Errorf("Failed to clean up namespace %s: %v", ns.file.Name(), err)
|
||||
}
|
||||
ns.mounted = false
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ns *netNS) Do(toRun func(NetNS) error) error {
|
||||
if err := ns.errorIfClosed(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
containedCall := func(hostNS NetNS) error {
|
||||
threadNS, err := GetNS(getCurrentThreadNetNSPath())
|
||||
threadNS, err := GetCurrentNS()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open current netns: %v", err)
|
||||
}
|
||||
@ -261,7 +146,7 @@ func (ns *netNS) Do(toRun func(NetNS) error) error {
|
||||
}
|
||||
|
||||
// save a handle to current network namespace
|
||||
hostNS, err := GetNS(getCurrentThreadNetNSPath())
|
||||
hostNS, err := GetCurrentNS()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to open current namespace: %v", err)
|
||||
}
|
||||
@ -281,18 +166,6 @@ func (ns *netNS) Do(toRun func(NetNS) error) error {
|
||||
return innerError
|
||||
}
|
||||
|
||||
func (ns *netNS) Set() error {
|
||||
if err := ns.errorIfClosed(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, _, err := unix.Syscall(unix.SYS_SETNS, ns.Fd(), uintptr(unix.CLONE_NEWNET), 0); err != 0 {
|
||||
return fmt.Errorf("Error switching to ns %v: %v", ns.file.Name(), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// WithNetNSPath executes the passed closure under the given network
|
||||
// namespace, restoring the original namespace afterwards.
|
||||
func WithNetNSPath(nspath string, toRun func(NetNS) error) error {
|
||||
|
149
pkg/ns/ns_linux.go
Normal file
149
pkg/ns/ns_linux.go
Normal file
@ -0,0 +1,149 @@
|
||||
// Copyright 2015-2017 CNI authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package ns
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// Returns an object representing the current OS thread's network namespace
|
||||
func GetCurrentNS() (NetNS, error) {
|
||||
return GetNS(getCurrentThreadNetNSPath())
|
||||
}
|
||||
|
||||
func getCurrentThreadNetNSPath() string {
|
||||
// /proc/self/ns/net returns the namespace of the main thread, not
|
||||
// of whatever thread this goroutine is running on. Make sure we
|
||||
// use the thread's net namespace since the thread is switching around
|
||||
return fmt.Sprintf("/proc/%d/task/%d/ns/net", os.Getpid(), unix.Gettid())
|
||||
}
|
||||
|
||||
// Creates a new persistent network namespace and returns an object
|
||||
// representing that namespace, without switching to it
|
||||
func NewNS() (NetNS, error) {
|
||||
const nsRunDir = "/var/run/netns"
|
||||
|
||||
b := make([]byte, 16)
|
||||
_, err := rand.Reader.Read(b)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate random netns name: %v", err)
|
||||
}
|
||||
|
||||
err = os.MkdirAll(nsRunDir, 0755)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// create an empty file at the mount point
|
||||
nsName := fmt.Sprintf("cni-%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
|
||||
nsPath := path.Join(nsRunDir, nsName)
|
||||
mountPointFd, err := os.Create(nsPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mountPointFd.Close()
|
||||
|
||||
// Ensure the mount point is cleaned up on errors; if the namespace
|
||||
// was successfully mounted this will have no effect because the file
|
||||
// is in-use
|
||||
defer os.RemoveAll(nsPath)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
|
||||
// do namespace work in a dedicated goroutine, so that we can safely
|
||||
// Lock/Unlock OSThread without upsetting the lock/unlock state of
|
||||
// the caller of this function
|
||||
var fd *os.File
|
||||
go (func() {
|
||||
defer wg.Done()
|
||||
runtime.LockOSThread()
|
||||
|
||||
var origNS NetNS
|
||||
origNS, err = GetNS(getCurrentThreadNetNSPath())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer origNS.Close()
|
||||
|
||||
// create a new netns on the current thread
|
||||
err = unix.Unshare(unix.CLONE_NEWNET)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer origNS.Set()
|
||||
|
||||
// bind mount the new netns from the current thread onto the mount point
|
||||
err = unix.Mount(getCurrentThreadNetNSPath(), nsPath, "none", unix.MS_BIND, "")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fd, err = os.Open(nsPath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
})()
|
||||
wg.Wait()
|
||||
|
||||
if err != nil {
|
||||
unix.Unmount(nsPath, unix.MNT_DETACH)
|
||||
return nil, fmt.Errorf("failed to create namespace: %v", err)
|
||||
}
|
||||
|
||||
return &netNS{file: fd, mounted: true}, nil
|
||||
}
|
||||
|
||||
func (ns *netNS) Close() error {
|
||||
if err := ns.errorIfClosed(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ns.file.Close(); err != nil {
|
||||
return fmt.Errorf("Failed to close %q: %v", ns.file.Name(), err)
|
||||
}
|
||||
ns.closed = true
|
||||
|
||||
if ns.mounted {
|
||||
if err := unix.Unmount(ns.file.Name(), unix.MNT_DETACH); err != nil {
|
||||
return fmt.Errorf("Failed to unmount namespace %s: %v", ns.file.Name(), err)
|
||||
}
|
||||
if err := os.RemoveAll(ns.file.Name()); err != nil {
|
||||
return fmt.Errorf("Failed to clean up namespace %s: %v", ns.file.Name(), err)
|
||||
}
|
||||
ns.mounted = false
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ns *netNS) Set() error {
|
||||
if err := ns.errorIfClosed(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, _, err := unix.Syscall(unix.SYS_SETNS, ns.Fd(), uintptr(unix.CLONE_NEWNET), 0); err != 0 {
|
||||
return fmt.Errorf("Error switching to ns %v: %v", ns.file.Name(), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
36
pkg/ns/ns_unspecified.go
Normal file
36
pkg/ns/ns_unspecified.go
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright 2015-2017 CNI authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build !linux
|
||||
|
||||
package ns
|
||||
|
||||
import "github.com/containernetworking/cni/pkg/types"
|
||||
|
||||
// Returns an object representing the current OS thread's network namespace
|
||||
func GetCurrentNS() (NetNS, error) {
|
||||
return nil, types.NotImplementedError
|
||||
}
|
||||
|
||||
func NewNS() (NetNS, error) {
|
||||
return nil, types.NotImplementedError
|
||||
}
|
||||
|
||||
func (ns *netNS) Close() error {
|
||||
return types.NotImplementedError
|
||||
}
|
||||
|
||||
func (ns *netNS) Set() error {
|
||||
return types.NotImplementedError
|
||||
}
|
@ -16,6 +16,7 @@ package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
@ -178,3 +179,6 @@ func prettyPrint(obj interface{}) error {
|
||||
_, err = os.Stdout.Write(data)
|
||||
return err
|
||||
}
|
||||
|
||||
// NotImplementedError is used to indicate that a method is not implemented for the given platform
|
||||
var NotImplementedError = errors.New("Not Implemented")
|
||||
|
2
vendor/github.com/vishvananda/netlink/Makefile
generated
vendored
2
vendor/github.com/vishvananda/netlink/Makefile
generated
vendored
@ -21,7 +21,7 @@ $(call testdirs,$(DIRS)):
|
||||
sudo -E go test -test.parallel 4 -timeout 60s -v github.com/vishvananda/netlink/$@
|
||||
|
||||
$(call fmt,$(call testdirs,$(DIRS))):
|
||||
! gofmt -l $(subst fmt-,,$@)/*.go | grep ''
|
||||
! gofmt -l $(subst fmt-,,$@)/*.go | grep -q .
|
||||
|
||||
.PHONY: fmt
|
||||
fmt: $(call fmt,$(call testdirs,$(DIRS)))
|
||||
|
15
vendor/github.com/vishvananda/netlink/addr.go
generated
vendored
15
vendor/github.com/vishvananda/netlink/addr.go
generated
vendored
@ -10,9 +10,11 @@ import (
|
||||
// include a mask, so it stores the address as a net.IPNet.
|
||||
type Addr struct {
|
||||
*net.IPNet
|
||||
Label string
|
||||
Flags int
|
||||
Scope int
|
||||
Label string
|
||||
Flags int
|
||||
Scope int
|
||||
Peer *net.IPNet
|
||||
Broadcast net.IP
|
||||
}
|
||||
|
||||
// String returns $ip/$netmask $label
|
||||
@ -43,3 +45,10 @@ func (a Addr) Equal(x Addr) bool {
|
||||
// ignore label for comparison
|
||||
return a.IP.Equal(x.IP) && sizea == sizeb
|
||||
}
|
||||
|
||||
func (a Addr) PeerEqual(x Addr) bool {
|
||||
sizea, _ := a.Peer.Mask.Size()
|
||||
sizeb, _ := x.Peer.Mask.Size()
|
||||
// ignore label for comparison
|
||||
return a.Peer.IP.Equal(x.Peer.IP) && sizea == sizeb
|
||||
}
|
||||
|
26
vendor/github.com/vishvananda/netlink/addr_linux.go
generated
vendored
26
vendor/github.com/vishvananda/netlink/addr_linux.go
generated
vendored
@ -56,17 +56,27 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error
|
||||
msg.Prefixlen = uint8(prefixlen)
|
||||
req.AddData(msg)
|
||||
|
||||
var addrData []byte
|
||||
var localAddrData []byte
|
||||
if family == FAMILY_V4 {
|
||||
addrData = addr.IP.To4()
|
||||
localAddrData = addr.IP.To4()
|
||||
} else {
|
||||
addrData = addr.IP.To16()
|
||||
localAddrData = addr.IP.To16()
|
||||
}
|
||||
|
||||
localData := nl.NewRtAttr(syscall.IFA_LOCAL, addrData)
|
||||
localData := nl.NewRtAttr(syscall.IFA_LOCAL, localAddrData)
|
||||
req.AddData(localData)
|
||||
var peerAddrData []byte
|
||||
if addr.Peer != nil {
|
||||
if family == FAMILY_V4 {
|
||||
peerAddrData = addr.Peer.IP.To4()
|
||||
} else {
|
||||
peerAddrData = addr.Peer.IP.To16()
|
||||
}
|
||||
} else {
|
||||
peerAddrData = localAddrData
|
||||
}
|
||||
|
||||
addressData := nl.NewRtAttr(syscall.IFA_ADDRESS, addrData)
|
||||
addressData := nl.NewRtAttr(syscall.IFA_ADDRESS, peerAddrData)
|
||||
req.AddData(addressData)
|
||||
|
||||
if addr.Flags != 0 {
|
||||
@ -80,6 +90,10 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error
|
||||
}
|
||||
}
|
||||
|
||||
if addr.Broadcast != nil {
|
||||
req.AddData(nl.NewRtAttr(syscall.IFA_BROADCAST, addr.Broadcast))
|
||||
}
|
||||
|
||||
if addr.Label != "" {
|
||||
labelData := nl.NewRtAttr(syscall.IFA_LABEL, nl.ZeroTerminated(addr.Label))
|
||||
req.AddData(labelData)
|
||||
@ -161,11 +175,13 @@ func parseAddr(m []byte) (addr Addr, family, index int, err error) {
|
||||
IP: attr.Value,
|
||||
Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
|
||||
}
|
||||
addr.Peer = dst
|
||||
case syscall.IFA_LOCAL:
|
||||
local = &net.IPNet{
|
||||
IP: attr.Value,
|
||||
Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
|
||||
}
|
||||
addr.IPNet = local
|
||||
case syscall.IFA_LABEL:
|
||||
addr.Label = string(attr.Value[:len(attr.Value)-1])
|
||||
case IFA_FLAGS:
|
||||
|
25
vendor/github.com/vishvananda/netlink/handle_linux.go
generated
vendored
25
vendor/github.com/vishvananda/netlink/handle_linux.go
generated
vendored
@ -1,7 +1,9 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
"github.com/vishvananda/netns"
|
||||
@ -33,6 +35,29 @@ func NewHandle(nlFamilies ...int) (*Handle, error) {
|
||||
return newHandle(netns.None(), netns.None(), nlFamilies...)
|
||||
}
|
||||
|
||||
// SetSocketTimeout sets the send and receive timeout for each socket in the
|
||||
// netlink handle. Although the socket timeout has granularity of one
|
||||
// microsecond, the effective granularity is floored by the kernel timer tick,
|
||||
// which default value is four milliseconds.
|
||||
func (h *Handle) SetSocketTimeout(to time.Duration) error {
|
||||
if to < time.Microsecond {
|
||||
return fmt.Errorf("invalid timeout, minimul value is %s", time.Microsecond)
|
||||
}
|
||||
tv := syscall.NsecToTimeval(to.Nanoseconds())
|
||||
for _, sh := range h.sockets {
|
||||
fd := sh.Socket.GetFd()
|
||||
err := syscall.SetsockoptTimeval(fd, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &tv)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = syscall.SetsockoptTimeval(fd, syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, &tv)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewHandle returns a netlink handle on the network namespace
|
||||
// specified by ns. If ns=netns.None(), current network namespace
|
||||
// will be assumed
|
||||
|
218
vendor/github.com/vishvananda/netlink/handle_unspecified.go
generated
vendored
Normal file
218
vendor/github.com/vishvananda/netlink/handle_unspecified.go
generated
vendored
Normal file
@ -0,0 +1,218 @@
|
||||
// +build !linux
|
||||
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/vishvananda/netns"
|
||||
)
|
||||
|
||||
type Handle struct{}
|
||||
|
||||
func NewHandle(nlFamilies ...int) (*Handle, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
func NewHandleAt(ns netns.NsHandle, nlFamilies ...int) (*Handle, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
func NewHandleAtFrom(newNs, curNs netns.NsHandle) (*Handle, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) Delete() {}
|
||||
|
||||
func (h *Handle) SupportsNetlinkFamily(nlFamily int) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *Handle) SetSocketTimeout(to time.Duration) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) SetPromiscOn(link Link) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) SetPromiscOff(link Link) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetUp(link Link) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetDown(link Link) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetMTU(link Link, mtu int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetName(link Link, name string) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetAlias(link Link, name string) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetHardwareAddr(link Link, hwaddr net.HardwareAddr) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetVfHardwareAddr(link Link, vf int, hwaddr net.HardwareAddr) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetVfVlan(link Link, vf, vlan int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetVfTxRate(link Link, vf, rate int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetMaster(link Link, master *Bridge) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetNoMaster(link Link) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetMasterByIndex(link Link, masterIndex int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetNsPid(link Link, nspid int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetNsFd(link Link, fd int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkAdd(link Link) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkDel(link Link) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkByName(name string) (Link, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkByAlias(alias string) (Link, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkByIndex(index int) (Link, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkList() ([]Link, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetHairpin(link Link, mode bool) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetGuard(link Link, mode bool) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetFastLeave(link Link, mode bool) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetLearning(link Link, mode bool) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetRootBlock(link Link, mode bool) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetFlood(link Link, mode bool) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) setProtinfoAttr(link Link, mode bool, attr int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) AddrAdd(link Link, addr *Addr) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) AddrDel(link Link, addr *Addr) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) AddrList(link Link, family int) ([]Addr, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) ClassDel(class Class) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) ClassChange(class Class) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) ClassReplace(class Class) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) ClassAdd(class Class) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) FilterDel(filter Filter) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) FilterAdd(filter Filter) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) NeighAdd(neigh *Neigh) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) NeighSet(neigh *Neigh) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) NeighAppend(neigh *Neigh) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) NeighDel(neigh *Neigh) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) NeighList(linkIndex, family int) ([]Neigh, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) NeighProxyList(linkIndex, family int) ([]Neigh, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
152
vendor/github.com/vishvananda/netlink/link.go
generated
vendored
152
vendor/github.com/vishvananda/netlink/link.go
generated
vendored
@ -35,6 +35,41 @@ type LinkAttrs struct {
|
||||
Promisc int
|
||||
Xdp *LinkXdp
|
||||
EncapType string
|
||||
Protinfo *Protinfo
|
||||
OperState LinkOperState
|
||||
}
|
||||
|
||||
// LinkOperState represents the values of the IFLA_OPERSTATE link
|
||||
// attribute, which contains the RFC2863 state of the interface.
|
||||
type LinkOperState uint8
|
||||
|
||||
const (
|
||||
OperUnknown = iota // Status can't be determined.
|
||||
OperNotPresent // Some component is missing.
|
||||
OperDown // Down.
|
||||
OperLowerLayerDown // Down due to state of lower layer.
|
||||
OperTesting // In some test mode.
|
||||
OperDormant // Not up but pending an external event.
|
||||
OperUp // Up, ready to send packets.
|
||||
)
|
||||
|
||||
func (s LinkOperState) String() string {
|
||||
switch s {
|
||||
case OperNotPresent:
|
||||
return "not-present"
|
||||
case OperDown:
|
||||
return "down"
|
||||
case OperLowerLayerDown:
|
||||
return "lower-layer-down"
|
||||
case OperTesting:
|
||||
return "testing"
|
||||
case OperDormant:
|
||||
return "dormant"
|
||||
case OperUp:
|
||||
return "up"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// NewLinkAttrs returns LinkAttrs structure filled with default values
|
||||
@ -44,10 +79,12 @@ func NewLinkAttrs() LinkAttrs {
|
||||
}
|
||||
}
|
||||
|
||||
type LinkStatistics LinkStatistics64
|
||||
|
||||
/*
|
||||
Ref: struct rtnl_link_stats {...}
|
||||
*/
|
||||
type LinkStatistics struct {
|
||||
type LinkStatistics32 struct {
|
||||
RxPackets uint32
|
||||
TxPackets uint32
|
||||
RxBytes uint32
|
||||
@ -73,6 +110,63 @@ type LinkStatistics struct {
|
||||
TxCompressed uint32
|
||||
}
|
||||
|
||||
func (s32 LinkStatistics32) to64() *LinkStatistics64 {
|
||||
return &LinkStatistics64{
|
||||
RxPackets: uint64(s32.RxPackets),
|
||||
TxPackets: uint64(s32.TxPackets),
|
||||
RxBytes: uint64(s32.RxBytes),
|
||||
TxBytes: uint64(s32.TxBytes),
|
||||
RxErrors: uint64(s32.RxErrors),
|
||||
TxErrors: uint64(s32.TxErrors),
|
||||
RxDropped: uint64(s32.RxDropped),
|
||||
TxDropped: uint64(s32.TxDropped),
|
||||
Multicast: uint64(s32.Multicast),
|
||||
Collisions: uint64(s32.Collisions),
|
||||
RxLengthErrors: uint64(s32.RxLengthErrors),
|
||||
RxOverErrors: uint64(s32.RxOverErrors),
|
||||
RxCrcErrors: uint64(s32.RxCrcErrors),
|
||||
RxFrameErrors: uint64(s32.RxFrameErrors),
|
||||
RxFifoErrors: uint64(s32.RxFifoErrors),
|
||||
RxMissedErrors: uint64(s32.RxMissedErrors),
|
||||
TxAbortedErrors: uint64(s32.TxAbortedErrors),
|
||||
TxCarrierErrors: uint64(s32.TxCarrierErrors),
|
||||
TxFifoErrors: uint64(s32.TxFifoErrors),
|
||||
TxHeartbeatErrors: uint64(s32.TxHeartbeatErrors),
|
||||
TxWindowErrors: uint64(s32.TxWindowErrors),
|
||||
RxCompressed: uint64(s32.RxCompressed),
|
||||
TxCompressed: uint64(s32.TxCompressed),
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Ref: struct rtnl_link_stats64 {...}
|
||||
*/
|
||||
type LinkStatistics64 struct {
|
||||
RxPackets uint64
|
||||
TxPackets uint64
|
||||
RxBytes uint64
|
||||
TxBytes uint64
|
||||
RxErrors uint64
|
||||
TxErrors uint64
|
||||
RxDropped uint64
|
||||
TxDropped uint64
|
||||
Multicast uint64
|
||||
Collisions uint64
|
||||
RxLengthErrors uint64
|
||||
RxOverErrors uint64
|
||||
RxCrcErrors uint64
|
||||
RxFrameErrors uint64
|
||||
RxFifoErrors uint64
|
||||
RxMissedErrors uint64
|
||||
TxAbortedErrors uint64
|
||||
TxCarrierErrors uint64
|
||||
TxFifoErrors uint64
|
||||
TxHeartbeatErrors uint64
|
||||
TxWindowErrors uint64
|
||||
RxCompressed uint64
|
||||
TxCompressed uint64
|
||||
}
|
||||
|
||||
type LinkXdp struct {
|
||||
Fd int
|
||||
Attached bool
|
||||
@ -301,31 +395,31 @@ func StringToBondMode(s string) BondMode {
|
||||
|
||||
// Possible BondMode
|
||||
const (
|
||||
BOND_MODE_802_3AD BondMode = iota
|
||||
BOND_MODE_BALANCE_RR
|
||||
BOND_MODE_BALANCE_RR BondMode = iota
|
||||
BOND_MODE_ACTIVE_BACKUP
|
||||
BOND_MODE_BALANCE_XOR
|
||||
BOND_MODE_BROADCAST
|
||||
BOND_MODE_802_3AD
|
||||
BOND_MODE_BALANCE_TLB
|
||||
BOND_MODE_BALANCE_ALB
|
||||
BOND_MODE_UNKNOWN
|
||||
)
|
||||
|
||||
var bondModeToString = map[BondMode]string{
|
||||
BOND_MODE_802_3AD: "802.3ad",
|
||||
BOND_MODE_BALANCE_RR: "balance-rr",
|
||||
BOND_MODE_ACTIVE_BACKUP: "active-backup",
|
||||
BOND_MODE_BALANCE_XOR: "balance-xor",
|
||||
BOND_MODE_BROADCAST: "broadcast",
|
||||
BOND_MODE_802_3AD: "802.3ad",
|
||||
BOND_MODE_BALANCE_TLB: "balance-tlb",
|
||||
BOND_MODE_BALANCE_ALB: "balance-alb",
|
||||
}
|
||||
var StringToBondModeMap = map[string]BondMode{
|
||||
"802.3ad": BOND_MODE_802_3AD,
|
||||
"balance-rr": BOND_MODE_BALANCE_RR,
|
||||
"active-backup": BOND_MODE_ACTIVE_BACKUP,
|
||||
"balance-xor": BOND_MODE_BALANCE_XOR,
|
||||
"broadcast": BOND_MODE_BROADCAST,
|
||||
"802.3ad": BOND_MODE_802_3AD,
|
||||
"balance-tlb": BOND_MODE_BALANCE_TLB,
|
||||
"balance-alb": BOND_MODE_BALANCE_ALB,
|
||||
}
|
||||
@ -589,6 +683,54 @@ func (gretap *Gretap) Type() string {
|
||||
return "gretap"
|
||||
}
|
||||
|
||||
type Iptun struct {
|
||||
LinkAttrs
|
||||
Ttl uint8
|
||||
Tos uint8
|
||||
PMtuDisc uint8
|
||||
Link uint32
|
||||
Local net.IP
|
||||
Remote net.IP
|
||||
}
|
||||
|
||||
func (iptun *Iptun) Attrs() *LinkAttrs {
|
||||
return &iptun.LinkAttrs
|
||||
}
|
||||
|
||||
func (iptun *Iptun) Type() string {
|
||||
return "ipip"
|
||||
}
|
||||
|
||||
type Vti struct {
|
||||
LinkAttrs
|
||||
IKey uint32
|
||||
OKey uint32
|
||||
Link uint32
|
||||
Local net.IP
|
||||
Remote net.IP
|
||||
}
|
||||
|
||||
func (vti *Vti) Attrs() *LinkAttrs {
|
||||
return &vti.LinkAttrs
|
||||
}
|
||||
|
||||
func (iptun *Vti) Type() string {
|
||||
return "vti"
|
||||
}
|
||||
|
||||
type Vrf struct {
|
||||
LinkAttrs
|
||||
Table uint32
|
||||
}
|
||||
|
||||
func (vrf *Vrf) Attrs() *LinkAttrs {
|
||||
return &vrf.LinkAttrs
|
||||
}
|
||||
|
||||
func (vrf *Vrf) Type() string {
|
||||
return "vrf"
|
||||
}
|
||||
|
||||
// iproute2 supported devices;
|
||||
// vlan | veth | vcan | dummy | ifb | macvlan | macvtap |
|
||||
// bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan |
|
||||
|
214
vendor/github.com/vishvananda/netlink/link_linux.go
generated
vendored
214
vendor/github.com/vishvananda/netlink/link_linux.go
generated
vendored
@ -13,7 +13,11 @@ import (
|
||||
"github.com/vishvananda/netns"
|
||||
)
|
||||
|
||||
const SizeofLinkStats = 0x5c
|
||||
const (
|
||||
SizeofLinkStats32 = 0x5c
|
||||
SizeofLinkStats64 = 0xd8
|
||||
IFLA_STATS64 = 0x17 // syscall pkg does not contain this one
|
||||
)
|
||||
|
||||
const (
|
||||
TUNTAP_MODE_TUN TuntapMode = syscall.IFF_TUN
|
||||
@ -25,7 +29,6 @@ const (
|
||||
TUNTAP_ONE_QUEUE TuntapFlag = syscall.IFF_ONE_QUEUE
|
||||
)
|
||||
|
||||
var native = nl.NativeEndian()
|
||||
var lookupByDump = false
|
||||
|
||||
var macvlanModes = [...]uint32{
|
||||
@ -298,6 +301,36 @@ func (h *Handle) LinkSetVfVlan(link Link, vf, vlan int) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// LinkSetVfTxRate sets the tx rate of a vf for the link.
|
||||
// Equivalent to: `ip link set $link vf $vf rate $rate`
|
||||
func LinkSetVfTxRate(link Link, vf, rate int) error {
|
||||
return pkgHandle.LinkSetVfTxRate(link, vf, rate)
|
||||
}
|
||||
|
||||
// LinkSetVfTxRate sets the tx rate of a vf for the link.
|
||||
// Equivalent to: `ip link set $link vf $vf rate $rate`
|
||||
func (h *Handle) LinkSetVfTxRate(link Link, vf, rate int) error {
|
||||
base := link.Attrs()
|
||||
h.ensureIndex(base)
|
||||
req := h.newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
|
||||
|
||||
msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
|
||||
msg.Index = int32(base.Index)
|
||||
req.AddData(msg)
|
||||
|
||||
data := nl.NewRtAttr(nl.IFLA_VFINFO_LIST, nil)
|
||||
info := nl.NewRtAttrChild(data, nl.IFLA_VF_INFO, nil)
|
||||
vfmsg := nl.VfTxRate{
|
||||
Vf: uint32(vf),
|
||||
Rate: uint32(rate),
|
||||
}
|
||||
nl.NewRtAttrChild(info, nl.IFLA_VF_TX_RATE, vfmsg.Serialize())
|
||||
req.AddData(data)
|
||||
|
||||
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
// LinkSetMaster sets the master of the link device.
|
||||
// Equivalent to: `ip link set $link master $master`
|
||||
func LinkSetMaster(link Link, master *Bridge) error {
|
||||
@ -753,6 +786,12 @@ func (h *Handle) LinkAdd(link Link) error {
|
||||
}
|
||||
} else if gretap, ok := link.(*Gretap); ok {
|
||||
addGretapAttrs(gretap, linkInfo)
|
||||
} else if iptun, ok := link.(*Iptun); ok {
|
||||
addIptunAttrs(iptun, linkInfo)
|
||||
} else if vti, ok := link.(*Vti); ok {
|
||||
addVtiAttrs(vti, linkInfo)
|
||||
} else if vrf, ok := link.(*Vrf); ok {
|
||||
addVrfAttrs(vrf, linkInfo)
|
||||
}
|
||||
|
||||
req.AddData(linkInfo)
|
||||
@ -919,7 +958,7 @@ func execGetLink(req *nl.NetlinkRequest) (Link, error) {
|
||||
return nil, fmt.Errorf("Link not found")
|
||||
|
||||
case len(msgs) == 1:
|
||||
return linkDeserialize(msgs[0])
|
||||
return LinkDeserialize(nil, msgs[0])
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("More than one link found")
|
||||
@ -928,7 +967,7 @@ func execGetLink(req *nl.NetlinkRequest) (Link, error) {
|
||||
|
||||
// linkDeserialize deserializes a raw message received from netlink into
|
||||
// a link object.
|
||||
func linkDeserialize(m []byte) (Link, error) {
|
||||
func LinkDeserialize(hdr *syscall.NlMsghdr, m []byte) (Link, error) {
|
||||
msg := nl.DeserializeIfInfomsg(m)
|
||||
|
||||
attrs, err := nl.ParseRouteAttr(m[msg.Len():])
|
||||
@ -940,8 +979,12 @@ func linkDeserialize(m []byte) (Link, error) {
|
||||
if msg.Flags&syscall.IFF_PROMISC != 0 {
|
||||
base.Promisc = 1
|
||||
}
|
||||
var link Link
|
||||
linkType := ""
|
||||
var (
|
||||
link Link
|
||||
stats32 []byte
|
||||
stats64 []byte
|
||||
linkType string
|
||||
)
|
||||
for _, attr := range attrs {
|
||||
switch attr.Attr.Type {
|
||||
case syscall.IFLA_LINKINFO:
|
||||
@ -976,6 +1019,12 @@ func linkDeserialize(m []byte) (Link, error) {
|
||||
link = &Macvtap{}
|
||||
case "gretap":
|
||||
link = &Gretap{}
|
||||
case "ipip":
|
||||
link = &Iptun{}
|
||||
case "vti":
|
||||
link = &Vti{}
|
||||
case "vrf":
|
||||
link = &Vrf{}
|
||||
default:
|
||||
link = &GenericLink{LinkType: linkType}
|
||||
}
|
||||
@ -999,6 +1048,12 @@ func linkDeserialize(m []byte) (Link, error) {
|
||||
parseMacvtapData(link, data)
|
||||
case "gretap":
|
||||
parseGretapData(link, data)
|
||||
case "ipip":
|
||||
parseIptunData(link, data)
|
||||
case "vti":
|
||||
parseVtiData(link, data)
|
||||
case "vrf":
|
||||
parseVrfData(link, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1025,15 +1080,35 @@ func linkDeserialize(m []byte) (Link, error) {
|
||||
case syscall.IFLA_IFALIAS:
|
||||
base.Alias = string(attr.Value[:len(attr.Value)-1])
|
||||
case syscall.IFLA_STATS:
|
||||
base.Statistics = parseLinkStats(attr.Value[:])
|
||||
stats32 = attr.Value[:]
|
||||
case IFLA_STATS64:
|
||||
stats64 = attr.Value[:]
|
||||
case nl.IFLA_XDP:
|
||||
xdp, err := parseLinkXdp(attr.Value[:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
base.Xdp = xdp
|
||||
case syscall.IFLA_PROTINFO | syscall.NLA_F_NESTED:
|
||||
if hdr != nil && hdr.Type == syscall.RTM_NEWLINK &&
|
||||
msg.Family == syscall.AF_BRIDGE {
|
||||
attrs, err := nl.ParseRouteAttr(attr.Value[:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
base.Protinfo = parseProtinfo(attrs)
|
||||
}
|
||||
case syscall.IFLA_OPERSTATE:
|
||||
base.OperState = LinkOperState(uint8(attr.Value[0]))
|
||||
}
|
||||
}
|
||||
|
||||
if stats64 != nil {
|
||||
base.Statistics = parseLinkStats64(stats64)
|
||||
} else if stats32 != nil {
|
||||
base.Statistics = parseLinkStats32(stats32)
|
||||
}
|
||||
|
||||
// Links that don't have IFLA_INFO_KIND are hardware devices
|
||||
if link == nil {
|
||||
link = &Device{}
|
||||
@ -1066,7 +1141,7 @@ func (h *Handle) LinkList() ([]Link, error) {
|
||||
|
||||
var res []Link
|
||||
for _, m := range msgs {
|
||||
link, err := linkDeserialize(m)
|
||||
link, err := LinkDeserialize(nil, m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1115,7 +1190,7 @@ func linkSubscribe(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-cha
|
||||
}
|
||||
for _, m := range msgs {
|
||||
ifmsg := nl.DeserializeIfInfomsg(m.Data)
|
||||
link, err := linkDeserialize(m.Data)
|
||||
link, err := LinkDeserialize(&m.Header, m.Data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -1367,26 +1442,6 @@ func linkFlags(rawFlags uint32) net.Flags {
|
||||
return f
|
||||
}
|
||||
|
||||
func htonl(val uint32) []byte {
|
||||
bytes := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(bytes, val)
|
||||
return bytes
|
||||
}
|
||||
|
||||
func htons(val uint16) []byte {
|
||||
bytes := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(bytes, val)
|
||||
return bytes
|
||||
}
|
||||
|
||||
func ntohl(buf []byte) uint32 {
|
||||
return binary.BigEndian.Uint32(buf)
|
||||
}
|
||||
|
||||
func ntohs(buf []byte) uint16 {
|
||||
return binary.BigEndian.Uint16(buf)
|
||||
}
|
||||
|
||||
func addGretapAttrs(gretap *Gretap, linkInfo *nl.RtAttr) {
|
||||
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
||||
|
||||
@ -1460,8 +1515,12 @@ func parseGretapData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||
}
|
||||
}
|
||||
|
||||
func parseLinkStats(data []byte) *LinkStatistics {
|
||||
return (*LinkStatistics)(unsafe.Pointer(&data[0:SizeofLinkStats][0]))
|
||||
func parseLinkStats32(data []byte) *LinkStatistics {
|
||||
return (*LinkStatistics)((*LinkStatistics32)(unsafe.Pointer(&data[0:SizeofLinkStats32][0])).to64())
|
||||
}
|
||||
|
||||
func parseLinkStats64(data []byte) *LinkStatistics {
|
||||
return (*LinkStatistics)((*LinkStatistics64)(unsafe.Pointer(&data[0:SizeofLinkStats64][0])))
|
||||
}
|
||||
|
||||
func addXdpAttrs(xdp *LinkXdp, req *nl.NetlinkRequest) {
|
||||
@ -1488,3 +1547,96 @@ func parseLinkXdp(data []byte) (*LinkXdp, error) {
|
||||
}
|
||||
return xdp, nil
|
||||
}
|
||||
|
||||
func addIptunAttrs(iptun *Iptun, linkInfo *nl.RtAttr) {
|
||||
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
||||
|
||||
ip := iptun.Local.To4()
|
||||
if ip != nil {
|
||||
nl.NewRtAttrChild(data, nl.IFLA_IPTUN_LOCAL, []byte(ip))
|
||||
}
|
||||
|
||||
ip = iptun.Remote.To4()
|
||||
if ip != nil {
|
||||
nl.NewRtAttrChild(data, nl.IFLA_IPTUN_REMOTE, []byte(ip))
|
||||
}
|
||||
|
||||
if iptun.Link != 0 {
|
||||
nl.NewRtAttrChild(data, nl.IFLA_IPTUN_LINK, nl.Uint32Attr(iptun.Link))
|
||||
}
|
||||
nl.NewRtAttrChild(data, nl.IFLA_IPTUN_PMTUDISC, nl.Uint8Attr(iptun.PMtuDisc))
|
||||
nl.NewRtAttrChild(data, nl.IFLA_IPTUN_TTL, nl.Uint8Attr(iptun.Ttl))
|
||||
nl.NewRtAttrChild(data, nl.IFLA_IPTUN_TOS, nl.Uint8Attr(iptun.Tos))
|
||||
}
|
||||
|
||||
func parseIptunData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||
iptun := link.(*Iptun)
|
||||
for _, datum := range data {
|
||||
switch datum.Attr.Type {
|
||||
case nl.IFLA_IPTUN_LOCAL:
|
||||
iptun.Local = net.IP(datum.Value[0:4])
|
||||
case nl.IFLA_IPTUN_REMOTE:
|
||||
iptun.Remote = net.IP(datum.Value[0:4])
|
||||
case nl.IFLA_IPTUN_TTL:
|
||||
iptun.Ttl = uint8(datum.Value[0])
|
||||
case nl.IFLA_IPTUN_TOS:
|
||||
iptun.Tos = uint8(datum.Value[0])
|
||||
case nl.IFLA_IPTUN_PMTUDISC:
|
||||
iptun.PMtuDisc = uint8(datum.Value[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func addVtiAttrs(vti *Vti, linkInfo *nl.RtAttr) {
|
||||
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
||||
|
||||
ip := vti.Local.To4()
|
||||
if ip != nil {
|
||||
nl.NewRtAttrChild(data, nl.IFLA_VTI_LOCAL, []byte(ip))
|
||||
}
|
||||
|
||||
ip = vti.Remote.To4()
|
||||
if ip != nil {
|
||||
nl.NewRtAttrChild(data, nl.IFLA_VTI_REMOTE, []byte(ip))
|
||||
}
|
||||
|
||||
if vti.Link != 0 {
|
||||
nl.NewRtAttrChild(data, nl.IFLA_VTI_LINK, nl.Uint32Attr(vti.Link))
|
||||
}
|
||||
|
||||
nl.NewRtAttrChild(data, nl.IFLA_VTI_IKEY, htonl(vti.IKey))
|
||||
nl.NewRtAttrChild(data, nl.IFLA_VTI_OKEY, htonl(vti.OKey))
|
||||
}
|
||||
|
||||
func parseVtiData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||
vti := link.(*Vti)
|
||||
for _, datum := range data {
|
||||
switch datum.Attr.Type {
|
||||
case nl.IFLA_VTI_LOCAL:
|
||||
vti.Local = net.IP(datum.Value[0:4])
|
||||
case nl.IFLA_VTI_REMOTE:
|
||||
vti.Remote = net.IP(datum.Value[0:4])
|
||||
case nl.IFLA_VTI_IKEY:
|
||||
vti.IKey = ntohl(datum.Value[0:4])
|
||||
case nl.IFLA_VTI_OKEY:
|
||||
vti.OKey = ntohl(datum.Value[0:4])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func addVrfAttrs(vrf *Vrf, linkInfo *nl.RtAttr) {
|
||||
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
||||
b := make([]byte, 4)
|
||||
native.PutUint32(b, uint32(vrf.Table))
|
||||
nl.NewRtAttrChild(data, nl.IFLA_VRF_TABLE, b)
|
||||
}
|
||||
|
||||
func parseVrfData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||
vrf := link.(*Vrf)
|
||||
for _, datum := range data {
|
||||
switch datum.Attr.Type {
|
||||
case nl.IFLA_VRF_TABLE:
|
||||
vrf.Table = native.Uint32(datum.Value[0:4])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
10
vendor/github.com/vishvananda/netlink/netlink.go
generated
vendored
10
vendor/github.com/vishvananda/netlink/netlink.go
generated
vendored
@ -8,7 +8,15 @@
|
||||
// interface that is loosly modeled on the iproute2 cli.
|
||||
package netlink
|
||||
|
||||
import "net"
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrNotImplemented is returned when a requested feature is not implemented.
|
||||
ErrNotImplemented = errors.New("not implemented")
|
||||
)
|
||||
|
||||
// ParseIPNet parses a string in ip/net format and returns a net.IPNet.
|
||||
// This is valuable because addresses in netlink are often IPNets and
|
||||
|
7
vendor/github.com/vishvananda/netlink/netlink_linux.go
generated
vendored
7
vendor/github.com/vishvananda/netlink/netlink_linux.go
generated
vendored
@ -4,7 +4,8 @@ import "github.com/vishvananda/netlink/nl"
|
||||
|
||||
// Family type definitions
|
||||
const (
|
||||
FAMILY_ALL = nl.FAMILY_ALL
|
||||
FAMILY_V4 = nl.FAMILY_V4
|
||||
FAMILY_V6 = nl.FAMILY_V6
|
||||
FAMILY_ALL = nl.FAMILY_ALL
|
||||
FAMILY_V4 = nl.FAMILY_V4
|
||||
FAMILY_V6 = nl.FAMILY_V6
|
||||
FAMILY_MPLS = nl.FAMILY_MPLS
|
||||
)
|
||||
|
108
vendor/github.com/vishvananda/netlink/netlink_unspecified.go
generated
vendored
108
vendor/github.com/vishvananda/netlink/netlink_unspecified.go
generated
vendored
@ -2,43 +2,109 @@
|
||||
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
import "net"
|
||||
|
||||
var (
|
||||
ErrNotImplemented = errors.New("not implemented")
|
||||
)
|
||||
|
||||
func LinkSetUp(link *Link) error {
|
||||
func LinkSetUp(link Link) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetDown(link *Link) error {
|
||||
func LinkSetDown(link Link) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetMTU(link *Link, mtu int) error {
|
||||
func LinkSetMTU(link Link, mtu int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetMaster(link *Link, master *Link) error {
|
||||
func LinkSetMaster(link Link, master *Link) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetNsPid(link *Link, nspid int) error {
|
||||
func LinkSetNsPid(link Link, nspid int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetNsFd(link *Link, fd int) error {
|
||||
func LinkSetNsFd(link Link, fd int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkAdd(link *Link) error {
|
||||
func LinkSetName(link Link, name string) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkDel(link *Link) error {
|
||||
func LinkSetAlias(link Link, name string) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetHardwareAddr(link Link, hwaddr net.HardwareAddr) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetVfHardwareAddr(link Link, vf int, hwaddr net.HardwareAddr) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetVfVlan(link Link, vf, vlan int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetVfTxRate(link Link, vf, rate int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetNoMaster(link Link) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetMasterByIndex(link Link, masterIndex int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetXdpFd(link Link, fd int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkByName(name string) (Link, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkByAlias(alias string) (Link, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkByIndex(index int) (Link, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetHairpin(link Link, mode bool) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetGuard(link Link, mode bool) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetFastLeave(link Link, mode bool) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetLearning(link Link, mode bool) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetRootBlock(link Link, mode bool) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetFlood(link Link, mode bool) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkAdd(link Link) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkDel(link Link) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
@ -70,15 +136,15 @@ func LinkList() ([]Link, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
func AddrAdd(link *Link, addr *Addr) error {
|
||||
func AddrAdd(link Link, addr *Addr) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func AddrDel(link *Link, addr *Addr) error {
|
||||
func AddrDel(link Link, addr *Addr) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func AddrList(link *Link, family int) ([]Addr, error) {
|
||||
func AddrList(link Link, family int) ([]Addr, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
@ -90,7 +156,7 @@ func RouteDel(route *Route) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func RouteList(link *Link, family int) ([]Route, error) {
|
||||
func RouteList(link Link, family int) ([]Route, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
@ -141,3 +207,7 @@ func NeighList(linkIndex, family int) ([]Neigh, error) {
|
||||
func NeighDeserialize(m []byte) (*Neigh, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
func SocketGet(local, remote net.Addr) (*Socket, error) {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
34
vendor/github.com/vishvananda/netlink/nl/link_linux.go
generated
vendored
34
vendor/github.com/vishvananda/netlink/nl/link_linux.go
generated
vendored
@ -418,3 +418,37 @@ const (
|
||||
IFLA_XDP_ATTACHED /* read-only bool indicating if prog is attached */
|
||||
IFLA_XDP_MAX = IFLA_XDP_ATTACHED
|
||||
)
|
||||
|
||||
const (
|
||||
IFLA_IPTUN_UNSPEC = iota
|
||||
IFLA_IPTUN_LINK
|
||||
IFLA_IPTUN_LOCAL
|
||||
IFLA_IPTUN_REMOTE
|
||||
IFLA_IPTUN_TTL
|
||||
IFLA_IPTUN_TOS
|
||||
IFLA_IPTUN_ENCAP_LIMIT
|
||||
IFLA_IPTUN_FLOWINFO
|
||||
IFLA_IPTUN_FLAGS
|
||||
IFLA_IPTUN_PROTO
|
||||
IFLA_IPTUN_PMTUDISC
|
||||
IFLA_IPTUN_6RD_PREFIX
|
||||
IFLA_IPTUN_6RD_RELAY_PREFIX
|
||||
IFLA_IPTUN_6RD_PREFIXLEN
|
||||
IFLA_IPTUN_6RD_RELAY_PREFIXLEN
|
||||
IFLA_IPTUN_MAX = IFLA_IPTUN_6RD_RELAY_PREFIXLEN
|
||||
)
|
||||
|
||||
const (
|
||||
IFLA_VTI_UNSPEC = iota
|
||||
IFLA_VTI_LINK
|
||||
IFLA_VTI_IKEY
|
||||
IFLA_VTI_OKEY
|
||||
IFLA_VTI_LOCAL
|
||||
IFLA_VTI_REMOTE
|
||||
IFLA_VTI_MAX = IFLA_VTI_REMOTE
|
||||
)
|
||||
|
||||
const (
|
||||
IFLA_VRF_UNSPEC = iota
|
||||
IFLA_VRF_TABLE
|
||||
)
|
||||
|
36
vendor/github.com/vishvananda/netlink/nl/mpls_linux.go
generated
vendored
Normal file
36
vendor/github.com/vishvananda/netlink/nl/mpls_linux.go
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
package nl
|
||||
|
||||
import "encoding/binary"
|
||||
|
||||
const (
|
||||
MPLS_LS_LABEL_SHIFT = 12
|
||||
MPLS_LS_S_SHIFT = 8
|
||||
)
|
||||
|
||||
func EncodeMPLSStack(labels ...int) []byte {
|
||||
b := make([]byte, 4*len(labels))
|
||||
for idx, label := range labels {
|
||||
l := label << MPLS_LS_LABEL_SHIFT
|
||||
if idx == len(labels)-1 {
|
||||
l |= 1 << MPLS_LS_S_SHIFT
|
||||
}
|
||||
binary.BigEndian.PutUint32(b[idx*4:], uint32(l))
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func DecodeMPLSStack(buf []byte) []int {
|
||||
if len(buf)%4 != 0 {
|
||||
return nil
|
||||
}
|
||||
stack := make([]int, 0, len(buf)/4)
|
||||
for len(buf) > 0 {
|
||||
l := binary.BigEndian.Uint32(buf[:4])
|
||||
buf = buf[4:]
|
||||
stack = append(stack, int(l)>>MPLS_LS_LABEL_SHIFT)
|
||||
if (l>>MPLS_LS_S_SHIFT)&1 > 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return stack
|
||||
}
|
14
vendor/github.com/vishvananda/netlink/nl/nl_linux.go
generated
vendored
14
vendor/github.com/vishvananda/netlink/nl/nl_linux.go
generated
vendored
@ -17,9 +17,10 @@ import (
|
||||
|
||||
const (
|
||||
// Family type definitions
|
||||
FAMILY_ALL = syscall.AF_UNSPEC
|
||||
FAMILY_V4 = syscall.AF_INET
|
||||
FAMILY_V6 = syscall.AF_INET6
|
||||
FAMILY_ALL = syscall.AF_UNSPEC
|
||||
FAMILY_V4 = syscall.AF_INET
|
||||
FAMILY_V6 = syscall.AF_INET6
|
||||
FAMILY_MPLS = AF_MPLS
|
||||
)
|
||||
|
||||
// SupportedNlFamilies contains the list of netlink families this netlink package supports
|
||||
@ -656,6 +657,13 @@ func Uint32Attr(v uint32) []byte {
|
||||
return bytes
|
||||
}
|
||||
|
||||
func Uint64Attr(v uint64) []byte {
|
||||
native := NativeEndian()
|
||||
bytes := make([]byte, 8)
|
||||
native.PutUint64(bytes, v)
|
||||
return bytes
|
||||
}
|
||||
|
||||
func ParseRouteAttr(b []byte) ([]syscall.NetlinkRouteAttr, error) {
|
||||
var attrs []syscall.NetlinkRouteAttr
|
||||
for len(b) >= syscall.SizeofRtAttr {
|
||||
|
11
vendor/github.com/vishvananda/netlink/nl/nl_unspecified.go
generated
vendored
Normal file
11
vendor/github.com/vishvananda/netlink/nl/nl_unspecified.go
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
// +build !linux
|
||||
|
||||
package nl
|
||||
|
||||
import "encoding/binary"
|
||||
|
||||
var SupportedNlFamilies = []int{}
|
||||
|
||||
func NativeEndian() binary.ByteOrder {
|
||||
return nil
|
||||
}
|
30
vendor/github.com/vishvananda/netlink/nl/route_linux.go
generated
vendored
30
vendor/github.com/vishvananda/netlink/nl/route_linux.go
generated
vendored
@ -43,12 +43,38 @@ func (msg *RtMsg) Serialize() []byte {
|
||||
|
||||
type RtNexthop struct {
|
||||
syscall.RtNexthop
|
||||
Children []NetlinkRequestData
|
||||
}
|
||||
|
||||
func DeserializeRtNexthop(b []byte) *RtNexthop {
|
||||
return (*RtNexthop)(unsafe.Pointer(&b[0:syscall.SizeofRtNexthop][0]))
|
||||
}
|
||||
|
||||
func (msg *RtNexthop) Serialize() []byte {
|
||||
return (*(*[syscall.SizeofRtNexthop]byte)(unsafe.Pointer(msg)))[:]
|
||||
func (msg *RtNexthop) Len() int {
|
||||
if len(msg.Children) == 0 {
|
||||
return syscall.SizeofRtNexthop
|
||||
}
|
||||
|
||||
l := 0
|
||||
for _, child := range msg.Children {
|
||||
l += rtaAlignOf(child.Len())
|
||||
}
|
||||
l += syscall.SizeofRtNexthop
|
||||
return rtaAlignOf(l)
|
||||
}
|
||||
|
||||
func (msg *RtNexthop) Serialize() []byte {
|
||||
length := msg.Len()
|
||||
msg.RtNexthop.Len = uint16(length)
|
||||
buf := make([]byte, length)
|
||||
copy(buf, (*(*[syscall.SizeofRtNexthop]byte)(unsafe.Pointer(msg)))[:])
|
||||
next := rtaAlignOf(syscall.SizeofRtNexthop)
|
||||
if len(msg.Children) > 0 {
|
||||
for _, child := range msg.Children {
|
||||
childBuf := child.Serialize()
|
||||
copy(buf[next:], childBuf)
|
||||
next += rtaAlignOf(len(childBuf))
|
||||
}
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
31
vendor/github.com/vishvananda/netlink/nl/syscall.go
generated
vendored
31
vendor/github.com/vishvananda/netlink/nl/syscall.go
generated
vendored
@ -35,3 +35,34 @@ const (
|
||||
FR_ACT_UNREACHABLE /* Drop with ENETUNREACH */
|
||||
FR_ACT_PROHIBIT /* Drop with EACCES */
|
||||
)
|
||||
|
||||
// socket diags related
|
||||
const (
|
||||
SOCK_DIAG_BY_FAMILY = 20 /* linux.sock_diag.h */
|
||||
TCPDIAG_NOCOOKIE = 0xFFFFFFFF /* TCPDIAG_NOCOOKIE in net/ipv4/tcp_diag.h*/
|
||||
)
|
||||
|
||||
const (
|
||||
AF_MPLS = 28
|
||||
)
|
||||
|
||||
const (
|
||||
RTA_NEWDST = 0x13
|
||||
RTA_ENCAP_TYPE = 0x15
|
||||
RTA_ENCAP = 0x16
|
||||
)
|
||||
|
||||
// RTA_ENCAP subtype
|
||||
const (
|
||||
MPLS_IPTUNNEL_UNSPEC = iota
|
||||
MPLS_IPTUNNEL_DST
|
||||
)
|
||||
|
||||
// light weight tunnel encap types
|
||||
const (
|
||||
LWTUNNEL_ENCAP_NONE = iota
|
||||
LWTUNNEL_ENCAP_MPLS
|
||||
LWTUNNEL_ENCAP_IP
|
||||
LWTUNNEL_ENCAP_ILA
|
||||
LWTUNNEL_ENCAP_IP6
|
||||
)
|
||||
|
72
vendor/github.com/vishvananda/netlink/nl/xfrm_linux.go
generated
vendored
72
vendor/github.com/vishvananda/netlink/nl/xfrm_linux.go
generated
vendored
@ -11,34 +11,40 @@ const (
|
||||
XFRM_INF = ^uint64(0)
|
||||
)
|
||||
|
||||
type XfrmMsgType uint8
|
||||
|
||||
type XfrmMsg interface {
|
||||
Type() XfrmMsgType
|
||||
}
|
||||
|
||||
// Message Types
|
||||
const (
|
||||
XFRM_MSG_BASE = 0x10
|
||||
XFRM_MSG_NEWSA = 0x10
|
||||
XFRM_MSG_DELSA = 0x11
|
||||
XFRM_MSG_GETSA = 0x12
|
||||
XFRM_MSG_NEWPOLICY = 0x13
|
||||
XFRM_MSG_DELPOLICY = 0x14
|
||||
XFRM_MSG_GETPOLICY = 0x15
|
||||
XFRM_MSG_ALLOCSPI = 0x16
|
||||
XFRM_MSG_ACQUIRE = 0x17
|
||||
XFRM_MSG_EXPIRE = 0x18
|
||||
XFRM_MSG_UPDPOLICY = 0x19
|
||||
XFRM_MSG_UPDSA = 0x1a
|
||||
XFRM_MSG_POLEXPIRE = 0x1b
|
||||
XFRM_MSG_FLUSHSA = 0x1c
|
||||
XFRM_MSG_FLUSHPOLICY = 0x1d
|
||||
XFRM_MSG_NEWAE = 0x1e
|
||||
XFRM_MSG_GETAE = 0x1f
|
||||
XFRM_MSG_REPORT = 0x20
|
||||
XFRM_MSG_MIGRATE = 0x21
|
||||
XFRM_MSG_NEWSADINFO = 0x22
|
||||
XFRM_MSG_GETSADINFO = 0x23
|
||||
XFRM_MSG_NEWSPDINFO = 0x24
|
||||
XFRM_MSG_GETSPDINFO = 0x25
|
||||
XFRM_MSG_MAPPING = 0x26
|
||||
XFRM_MSG_MAX = 0x26
|
||||
XFRM_NR_MSGTYPES = 0x17
|
||||
XFRM_MSG_BASE XfrmMsgType = 0x10
|
||||
XFRM_MSG_NEWSA = 0x10
|
||||
XFRM_MSG_DELSA = 0x11
|
||||
XFRM_MSG_GETSA = 0x12
|
||||
XFRM_MSG_NEWPOLICY = 0x13
|
||||
XFRM_MSG_DELPOLICY = 0x14
|
||||
XFRM_MSG_GETPOLICY = 0x15
|
||||
XFRM_MSG_ALLOCSPI = 0x16
|
||||
XFRM_MSG_ACQUIRE = 0x17
|
||||
XFRM_MSG_EXPIRE = 0x18
|
||||
XFRM_MSG_UPDPOLICY = 0x19
|
||||
XFRM_MSG_UPDSA = 0x1a
|
||||
XFRM_MSG_POLEXPIRE = 0x1b
|
||||
XFRM_MSG_FLUSHSA = 0x1c
|
||||
XFRM_MSG_FLUSHPOLICY = 0x1d
|
||||
XFRM_MSG_NEWAE = 0x1e
|
||||
XFRM_MSG_GETAE = 0x1f
|
||||
XFRM_MSG_REPORT = 0x20
|
||||
XFRM_MSG_MIGRATE = 0x21
|
||||
XFRM_MSG_NEWSADINFO = 0x22
|
||||
XFRM_MSG_GETSADINFO = 0x23
|
||||
XFRM_MSG_NEWSPDINFO = 0x24
|
||||
XFRM_MSG_GETSPDINFO = 0x25
|
||||
XFRM_MSG_MAPPING = 0x26
|
||||
XFRM_MSG_MAX = 0x26
|
||||
XFRM_NR_MSGTYPES = 0x17
|
||||
)
|
||||
|
||||
// Attribute types
|
||||
@ -81,6 +87,20 @@ const (
|
||||
SizeofXfrmMark = 0x08
|
||||
)
|
||||
|
||||
// Netlink groups
|
||||
const (
|
||||
XFRMNLGRP_NONE = 0x0
|
||||
XFRMNLGRP_ACQUIRE = 0x1
|
||||
XFRMNLGRP_EXPIRE = 0x2
|
||||
XFRMNLGRP_SA = 0x3
|
||||
XFRMNLGRP_POLICY = 0x4
|
||||
XFRMNLGRP_AEVENTS = 0x5
|
||||
XFRMNLGRP_REPORT = 0x6
|
||||
XFRMNLGRP_MIGRATE = 0x7
|
||||
XFRMNLGRP_MAPPING = 0x8
|
||||
__XFRMNLGRP_MAX = 0x9
|
||||
)
|
||||
|
||||
// typedef union {
|
||||
// __be32 a4;
|
||||
// __be32 a6[4];
|
||||
|
32
vendor/github.com/vishvananda/netlink/nl/xfrm_monitor_linux.go
generated
vendored
Normal file
32
vendor/github.com/vishvananda/netlink/nl/xfrm_monitor_linux.go
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
package nl
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
SizeofXfrmUserExpire = 0xe8
|
||||
)
|
||||
|
||||
// struct xfrm_user_expire {
|
||||
// struct xfrm_usersa_info state;
|
||||
// __u8 hard;
|
||||
// };
|
||||
|
||||
type XfrmUserExpire struct {
|
||||
XfrmUsersaInfo XfrmUsersaInfo
|
||||
Hard uint8
|
||||
Pad [7]byte
|
||||
}
|
||||
|
||||
func (msg *XfrmUserExpire) Len() int {
|
||||
return SizeofXfrmUserExpire
|
||||
}
|
||||
|
||||
func DeserializeXfrmUserExpire(b []byte) *XfrmUserExpire {
|
||||
return (*XfrmUserExpire)(unsafe.Pointer(&b[0:SizeofXfrmUserExpire][0]))
|
||||
}
|
||||
|
||||
func (msg *XfrmUserExpire) Serialize() []byte {
|
||||
return (*(*[SizeofXfrmUserExpire]byte)(unsafe.Pointer(msg)))[:]
|
||||
}
|
78
vendor/github.com/vishvananda/netlink/nl/xfrm_state_linux.go
generated
vendored
78
vendor/github.com/vishvananda/netlink/nl/xfrm_state_linux.go
generated
vendored
@ -5,14 +5,27 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
SizeofXfrmUsersaId = 0x18
|
||||
SizeofXfrmStats = 0x0c
|
||||
SizeofXfrmUsersaInfo = 0xe0
|
||||
SizeofXfrmAlgo = 0x44
|
||||
SizeofXfrmAlgoAuth = 0x48
|
||||
SizeofXfrmAlgoAEAD = 0x48
|
||||
SizeofXfrmEncapTmpl = 0x18
|
||||
SizeofXfrmUsersaFlush = 0x8
|
||||
SizeofXfrmUsersaId = 0x18
|
||||
SizeofXfrmStats = 0x0c
|
||||
SizeofXfrmUsersaInfo = 0xe0
|
||||
SizeofXfrmUserSpiInfo = 0xe8
|
||||
SizeofXfrmAlgo = 0x44
|
||||
SizeofXfrmAlgoAuth = 0x48
|
||||
SizeofXfrmAlgoAEAD = 0x48
|
||||
SizeofXfrmEncapTmpl = 0x18
|
||||
SizeofXfrmUsersaFlush = 0x8
|
||||
SizeofXfrmReplayStateEsn = 0x18
|
||||
)
|
||||
|
||||
const (
|
||||
XFRM_STATE_NOECN = 1
|
||||
XFRM_STATE_DECAP_DSCP = 2
|
||||
XFRM_STATE_NOPMTUDISC = 4
|
||||
XFRM_STATE_WILDRECV = 8
|
||||
XFRM_STATE_ICMP = 16
|
||||
XFRM_STATE_AF_UNSPEC = 32
|
||||
XFRM_STATE_ALIGN4 = 64
|
||||
XFRM_STATE_ESN = 128
|
||||
)
|
||||
|
||||
// struct xfrm_usersa_id {
|
||||
@ -120,6 +133,30 @@ func (msg *XfrmUsersaInfo) Serialize() []byte {
|
||||
return (*(*[SizeofXfrmUsersaInfo]byte)(unsafe.Pointer(msg)))[:]
|
||||
}
|
||||
|
||||
// struct xfrm_userspi_info {
|
||||
// struct xfrm_usersa_info info;
|
||||
// __u32 min;
|
||||
// __u32 max;
|
||||
// };
|
||||
|
||||
type XfrmUserSpiInfo struct {
|
||||
XfrmUsersaInfo XfrmUsersaInfo
|
||||
Min uint32
|
||||
Max uint32
|
||||
}
|
||||
|
||||
func (msg *XfrmUserSpiInfo) Len() int {
|
||||
return SizeofXfrmUserSpiInfo
|
||||
}
|
||||
|
||||
func DeserializeXfrmUserSpiInfo(b []byte) *XfrmUserSpiInfo {
|
||||
return (*XfrmUserSpiInfo)(unsafe.Pointer(&b[0:SizeofXfrmUserSpiInfo][0]))
|
||||
}
|
||||
|
||||
func (msg *XfrmUserSpiInfo) Serialize() []byte {
|
||||
return (*(*[SizeofXfrmUserSpiInfo]byte)(unsafe.Pointer(msg)))[:]
|
||||
}
|
||||
|
||||
// struct xfrm_algo {
|
||||
// char alg_name[64];
|
||||
// unsigned int alg_key_len; /* in bits */
|
||||
@ -270,3 +307,28 @@ func DeserializeXfrmUsersaFlush(b []byte) *XfrmUsersaFlush {
|
||||
func (msg *XfrmUsersaFlush) Serialize() []byte {
|
||||
return (*(*[SizeofXfrmUsersaFlush]byte)(unsafe.Pointer(msg)))[:]
|
||||
}
|
||||
|
||||
// struct xfrm_replay_state_esn {
|
||||
// unsigned int bmp_len;
|
||||
// __u32 oseq;
|
||||
// __u32 seq;
|
||||
// __u32 oseq_hi;
|
||||
// __u32 seq_hi;
|
||||
// __u32 replay_window;
|
||||
// __u32 bmp[0];
|
||||
// };
|
||||
|
||||
type XfrmReplayStateEsn struct {
|
||||
BmpLen uint32
|
||||
OSeq uint32
|
||||
Seq uint32
|
||||
OSeqHi uint32
|
||||
SeqHi uint32
|
||||
ReplayWindow uint32
|
||||
Bmp []uint32
|
||||
}
|
||||
|
||||
func (msg *XfrmReplayStateEsn) Serialize() []byte {
|
||||
// We deliberately do not pass Bmp, as it gets set by the kernel.
|
||||
return (*(*[SizeofXfrmReplayStateEsn]byte)(unsafe.Pointer(msg)))[:]
|
||||
}
|
||||
|
32
vendor/github.com/vishvananda/netlink/order.go
generated
vendored
Normal file
32
vendor/github.com/vishvananda/netlink/order.go
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
)
|
||||
|
||||
var (
|
||||
native = nl.NativeEndian()
|
||||
networkOrder = binary.BigEndian
|
||||
)
|
||||
|
||||
func htonl(val uint32) []byte {
|
||||
bytes := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(bytes, val)
|
||||
return bytes
|
||||
}
|
||||
|
||||
func htons(val uint16) []byte {
|
||||
bytes := make([]byte, 2)
|
||||
binary.BigEndian.PutUint16(bytes, val)
|
||||
return bytes
|
||||
}
|
||||
|
||||
func ntohl(buf []byte) uint32 {
|
||||
return binary.BigEndian.Uint32(buf)
|
||||
}
|
||||
|
||||
func ntohs(buf []byte) uint16 {
|
||||
return binary.BigEndian.Uint16(buf)
|
||||
}
|
5
vendor/github.com/vishvananda/netlink/protinfo.go
generated
vendored
5
vendor/github.com/vishvananda/netlink/protinfo.go
generated
vendored
@ -46,8 +46,5 @@ func boolToByte(x bool) []byte {
|
||||
}
|
||||
|
||||
func byteToBool(x byte) bool {
|
||||
if uint8(x) != 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return uint8(x) != 0
|
||||
}
|
||||
|
40
vendor/github.com/vishvananda/netlink/protinfo_linux.go
generated
vendored
40
vendor/github.com/vishvananda/netlink/protinfo_linux.go
generated
vendored
@ -40,25 +40,31 @@ func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) {
|
||||
if err != nil {
|
||||
return pi, err
|
||||
}
|
||||
var pi Protinfo
|
||||
for _, info := range infos {
|
||||
switch info.Attr.Type {
|
||||
case nl.IFLA_BRPORT_MODE:
|
||||
pi.Hairpin = byteToBool(info.Value[0])
|
||||
case nl.IFLA_BRPORT_GUARD:
|
||||
pi.Guard = byteToBool(info.Value[0])
|
||||
case nl.IFLA_BRPORT_FAST_LEAVE:
|
||||
pi.FastLeave = byteToBool(info.Value[0])
|
||||
case nl.IFLA_BRPORT_PROTECT:
|
||||
pi.RootBlock = byteToBool(info.Value[0])
|
||||
case nl.IFLA_BRPORT_LEARNING:
|
||||
pi.Learning = byteToBool(info.Value[0])
|
||||
case nl.IFLA_BRPORT_UNICAST_FLOOD:
|
||||
pi.Flood = byteToBool(info.Value[0])
|
||||
}
|
||||
}
|
||||
pi = *parseProtinfo(infos)
|
||||
|
||||
return pi, nil
|
||||
}
|
||||
}
|
||||
return pi, fmt.Errorf("Device with index %d not found", base.Index)
|
||||
}
|
||||
|
||||
func parseProtinfo(infos []syscall.NetlinkRouteAttr) *Protinfo {
|
||||
var pi Protinfo
|
||||
for _, info := range infos {
|
||||
switch info.Attr.Type {
|
||||
case nl.IFLA_BRPORT_MODE:
|
||||
pi.Hairpin = byteToBool(info.Value[0])
|
||||
case nl.IFLA_BRPORT_GUARD:
|
||||
pi.Guard = byteToBool(info.Value[0])
|
||||
case nl.IFLA_BRPORT_FAST_LEAVE:
|
||||
pi.FastLeave = byteToBool(info.Value[0])
|
||||
case nl.IFLA_BRPORT_PROTECT:
|
||||
pi.RootBlock = byteToBool(info.Value[0])
|
||||
case nl.IFLA_BRPORT_LEARNING:
|
||||
pi.Learning = byteToBool(info.Value[0])
|
||||
case nl.IFLA_BRPORT_UNICAST_FLOOD:
|
||||
pi.Flood = byteToBool(info.Value[0])
|
||||
}
|
||||
}
|
||||
return &pi
|
||||
}
|
||||
|
9
vendor/github.com/vishvananda/netlink/qdisc.go
generated
vendored
9
vendor/github.com/vishvananda/netlink/qdisc.go
generated
vendored
@ -187,10 +187,11 @@ func (qdisc *Netem) Type() string {
|
||||
// Tbf is a classless qdisc that rate limits based on tokens
|
||||
type Tbf struct {
|
||||
QdiscAttrs
|
||||
// TODO: handle 64bit rate properly
|
||||
Rate uint64
|
||||
Limit uint32
|
||||
Buffer uint32
|
||||
Rate uint64
|
||||
Limit uint32
|
||||
Buffer uint32
|
||||
Peakrate uint64
|
||||
Minburst uint32
|
||||
// TODO: handle other settings
|
||||
}
|
||||
|
||||
|
18
vendor/github.com/vishvananda/netlink/qdisc_linux.go
generated
vendored
18
vendor/github.com/vishvananda/netlink/qdisc_linux.go
generated
vendored
@ -168,11 +168,20 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
|
||||
options = nl.NewRtAttr(nl.TCA_OPTIONS, tcmap.Serialize())
|
||||
} else if tbf, ok := qdisc.(*Tbf); ok {
|
||||
opt := nl.TcTbfQopt{}
|
||||
// TODO: handle rate > uint32
|
||||
opt.Rate.Rate = uint32(tbf.Rate)
|
||||
opt.Peakrate.Rate = uint32(tbf.Peakrate)
|
||||
opt.Limit = tbf.Limit
|
||||
opt.Buffer = tbf.Buffer
|
||||
nl.NewRtAttrChild(options, nl.TCA_TBF_PARMS, opt.Serialize())
|
||||
if tbf.Rate >= uint64(1<<32) {
|
||||
nl.NewRtAttrChild(options, nl.TCA_TBF_RATE64, nl.Uint64Attr(tbf.Rate))
|
||||
}
|
||||
if tbf.Peakrate >= uint64(1<<32) {
|
||||
nl.NewRtAttrChild(options, nl.TCA_TBF_PRATE64, nl.Uint64Attr(tbf.Peakrate))
|
||||
}
|
||||
if tbf.Peakrate > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_TBF_PBURST, nl.Uint32Attr(tbf.Minburst))
|
||||
}
|
||||
} else if htb, ok := qdisc.(*Htb); ok {
|
||||
opt := nl.TcHtbGlob{}
|
||||
opt.Version = htb.Version
|
||||
@ -418,10 +427,15 @@ func parseTbfData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
|
||||
case nl.TCA_TBF_PARMS:
|
||||
opt := nl.DeserializeTcTbfQopt(datum.Value)
|
||||
tbf.Rate = uint64(opt.Rate.Rate)
|
||||
tbf.Peakrate = uint64(opt.Peakrate.Rate)
|
||||
tbf.Limit = opt.Limit
|
||||
tbf.Buffer = opt.Buffer
|
||||
case nl.TCA_TBF_RATE64:
|
||||
tbf.Rate = native.Uint64(datum.Value[0:4])
|
||||
tbf.Rate = native.Uint64(datum.Value[0:8])
|
||||
case nl.TCA_TBF_PRATE64:
|
||||
tbf.Peakrate = native.Uint64(datum.Value[0:8])
|
||||
case nl.TCA_TBF_PBURST:
|
||||
tbf.Minburst = native.Uint32(datum.Value[0:4])
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
62
vendor/github.com/vishvananda/netlink/route.go
generated
vendored
62
vendor/github.com/vishvananda/netlink/route.go
generated
vendored
@ -3,6 +3,7 @@ package netlink
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Scope is an enum representing a route scope.
|
||||
@ -10,6 +11,20 @@ type Scope uint8
|
||||
|
||||
type NextHopFlag int
|
||||
|
||||
type Destination interface {
|
||||
Family() int
|
||||
Decode([]byte) error
|
||||
Encode() ([]byte, error)
|
||||
String() string
|
||||
}
|
||||
|
||||
type Encap interface {
|
||||
Type() int
|
||||
Decode([]byte) error
|
||||
Encode() ([]byte, error)
|
||||
String() string
|
||||
}
|
||||
|
||||
// Route represents a netlink route.
|
||||
type Route struct {
|
||||
LinkIndex int
|
||||
@ -25,15 +40,36 @@ type Route struct {
|
||||
Type int
|
||||
Tos int
|
||||
Flags int
|
||||
MPLSDst *int
|
||||
NewDst Destination
|
||||
Encap Encap
|
||||
}
|
||||
|
||||
func (r Route) String() string {
|
||||
if len(r.MultiPath) > 0 {
|
||||
return fmt.Sprintf("{Dst: %s Src: %s Gw: %s Flags: %s Table: %d}", r.Dst,
|
||||
r.Src, r.MultiPath, r.ListFlags(), r.Table)
|
||||
elems := []string{}
|
||||
if len(r.MultiPath) == 0 {
|
||||
elems = append(elems, fmt.Sprintf("Ifindex: %d", r.LinkIndex))
|
||||
}
|
||||
return fmt.Sprintf("{Ifindex: %d Dst: %s Src: %s Gw: %s Flags: %s Table: %d}", r.LinkIndex, r.Dst,
|
||||
r.Src, r.Gw, r.ListFlags(), r.Table)
|
||||
if r.MPLSDst != nil {
|
||||
elems = append(elems, fmt.Sprintf("Dst: %d", r.MPLSDst))
|
||||
} else {
|
||||
elems = append(elems, fmt.Sprintf("Dst: %s", r.Dst))
|
||||
}
|
||||
if r.NewDst != nil {
|
||||
elems = append(elems, fmt.Sprintf("NewDst: %s", r.NewDst))
|
||||
}
|
||||
if r.Encap != nil {
|
||||
elems = append(elems, fmt.Sprintf("Encap: %s", r.Encap))
|
||||
}
|
||||
elems = append(elems, fmt.Sprintf("Src: %s", r.Src))
|
||||
if len(r.MultiPath) > 0 {
|
||||
elems = append(elems, fmt.Sprintf("Gw: %s", r.MultiPath))
|
||||
} else {
|
||||
elems = append(elems, fmt.Sprintf("Gw: %s", r.Gw))
|
||||
}
|
||||
elems = append(elems, fmt.Sprintf("Flags: %s", r.ListFlags()))
|
||||
elems = append(elems, fmt.Sprintf("Table: %d", r.Table))
|
||||
return fmt.Sprintf("{%s}", strings.Join(elems, " "))
|
||||
}
|
||||
|
||||
func (r *Route) SetFlag(flag NextHopFlag) {
|
||||
@ -59,8 +95,22 @@ type NexthopInfo struct {
|
||||
LinkIndex int
|
||||
Hops int
|
||||
Gw net.IP
|
||||
Flags int
|
||||
NewDst Destination
|
||||
Encap Encap
|
||||
}
|
||||
|
||||
func (n *NexthopInfo) String() string {
|
||||
return fmt.Sprintf("{Ifindex: %d Weight: %d, Gw: %s}", n.LinkIndex, n.Hops+1, n.Gw)
|
||||
elems := []string{}
|
||||
elems = append(elems, fmt.Sprintf("Ifindex: %d", n.LinkIndex))
|
||||
if n.NewDst != nil {
|
||||
elems = append(elems, fmt.Sprintf("NewDst: %s", n.NewDst))
|
||||
}
|
||||
if n.Encap != nil {
|
||||
elems = append(elems, fmt.Sprintf("Encap: %s", n.Encap))
|
||||
}
|
||||
elems = append(elems, fmt.Sprintf("Weight: %d", n.Hops+1))
|
||||
elems = append(elems, fmt.Sprintf("Gw: %d", n.Gw))
|
||||
elems = append(elems, fmt.Sprintf("Flags: %s", n.ListFlags()))
|
||||
return fmt.Sprintf("{%s}", strings.Join(elems, " "))
|
||||
}
|
||||
|
257
vendor/github.com/vishvananda/netlink/route_linux.go
generated
vendored
257
vendor/github.com/vishvananda/netlink/route_linux.go
generated
vendored
@ -3,6 +3,7 @@ package netlink
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
@ -42,16 +43,92 @@ var testFlags = []flagString{
|
||||
{f: FLAG_PERVASIVE, s: "pervasive"},
|
||||
}
|
||||
|
||||
func (r *Route) ListFlags() []string {
|
||||
func listFlags(flag int) []string {
|
||||
var flags []string
|
||||
for _, tf := range testFlags {
|
||||
if r.Flags&int(tf.f) != 0 {
|
||||
if flag&int(tf.f) != 0 {
|
||||
flags = append(flags, tf.s)
|
||||
}
|
||||
}
|
||||
return flags
|
||||
}
|
||||
|
||||
func (r *Route) ListFlags() []string {
|
||||
return listFlags(r.Flags)
|
||||
}
|
||||
|
||||
func (n *NexthopInfo) ListFlags() []string {
|
||||
return listFlags(n.Flags)
|
||||
}
|
||||
|
||||
type MPLSDestination struct {
|
||||
Labels []int
|
||||
}
|
||||
|
||||
func (d *MPLSDestination) Family() int {
|
||||
return nl.FAMILY_MPLS
|
||||
}
|
||||
|
||||
func (d *MPLSDestination) Decode(buf []byte) error {
|
||||
d.Labels = nl.DecodeMPLSStack(buf)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *MPLSDestination) Encode() ([]byte, error) {
|
||||
return nl.EncodeMPLSStack(d.Labels...), nil
|
||||
}
|
||||
|
||||
func (d *MPLSDestination) String() string {
|
||||
s := make([]string, 0, len(d.Labels))
|
||||
for _, l := range d.Labels {
|
||||
s = append(s, fmt.Sprintf("%d", l))
|
||||
}
|
||||
return strings.Join(s, "/")
|
||||
}
|
||||
|
||||
type MPLSEncap struct {
|
||||
Labels []int
|
||||
}
|
||||
|
||||
func (e *MPLSEncap) Type() int {
|
||||
return nl.LWTUNNEL_ENCAP_MPLS
|
||||
}
|
||||
|
||||
func (e *MPLSEncap) Decode(buf []byte) error {
|
||||
if len(buf) < 4 {
|
||||
return fmt.Errorf("Lack of bytes")
|
||||
}
|
||||
native := nl.NativeEndian()
|
||||
l := native.Uint16(buf)
|
||||
if len(buf) < int(l) {
|
||||
return fmt.Errorf("Lack of bytes")
|
||||
}
|
||||
buf = buf[:l]
|
||||
typ := native.Uint16(buf[2:])
|
||||
if typ != nl.MPLS_IPTUNNEL_DST {
|
||||
return fmt.Errorf("Unknown MPLS Encap Type: %d", typ)
|
||||
}
|
||||
e.Labels = nl.DecodeMPLSStack(buf[4:])
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *MPLSEncap) Encode() ([]byte, error) {
|
||||
s := nl.EncodeMPLSStack(e.Labels...)
|
||||
native := nl.NativeEndian()
|
||||
hdr := make([]byte, 4)
|
||||
native.PutUint16(hdr, uint16(len(s)+4))
|
||||
native.PutUint16(hdr[2:], nl.MPLS_IPTUNNEL_DST)
|
||||
return append(hdr, s...), nil
|
||||
}
|
||||
|
||||
func (e *MPLSEncap) String() string {
|
||||
s := make([]string, 0, len(e.Labels))
|
||||
for _, l := range e.Labels {
|
||||
s = append(s, fmt.Sprintf("%d", l))
|
||||
}
|
||||
return strings.Join(s, "/")
|
||||
}
|
||||
|
||||
// RouteAdd will add a route to the system.
|
||||
// Equivalent to: `ip route add $route`
|
||||
func RouteAdd(route *Route) error {
|
||||
@ -61,7 +138,22 @@ func RouteAdd(route *Route) error {
|
||||
// RouteAdd will add a route to the system.
|
||||
// Equivalent to: `ip route add $route`
|
||||
func (h *Handle) RouteAdd(route *Route) error {
|
||||
req := h.newNetlinkRequest(syscall.RTM_NEWROUTE, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
||||
flags := syscall.NLM_F_CREATE | syscall.NLM_F_EXCL | syscall.NLM_F_ACK
|
||||
req := h.newNetlinkRequest(syscall.RTM_NEWROUTE, flags)
|
||||
return h.routeHandle(route, req, nl.NewRtMsg())
|
||||
}
|
||||
|
||||
// RouteReplace will add a route to the system.
|
||||
// Equivalent to: `ip route replace $route`
|
||||
func RouteReplace(route *Route) error {
|
||||
return pkgHandle.RouteReplace(route)
|
||||
}
|
||||
|
||||
// RouteReplace will add a route to the system.
|
||||
// Equivalent to: `ip route replace $route`
|
||||
func (h *Handle) RouteReplace(route *Route) error {
|
||||
flags := syscall.NLM_F_CREATE | syscall.NLM_F_REPLACE | syscall.NLM_F_ACK
|
||||
req := h.newNetlinkRequest(syscall.RTM_NEWROUTE, flags)
|
||||
return h.routeHandle(route, req, nl.NewRtMsg())
|
||||
}
|
||||
|
||||
@ -79,7 +171,7 @@ func (h *Handle) RouteDel(route *Route) error {
|
||||
}
|
||||
|
||||
func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg) error {
|
||||
if (route.Dst == nil || route.Dst.IP == nil) && route.Src == nil && route.Gw == nil {
|
||||
if (route.Dst == nil || route.Dst.IP == nil) && route.Src == nil && route.Gw == nil && route.MPLSDst == nil {
|
||||
return fmt.Errorf("one of Dst.IP, Src, or Gw must not be nil")
|
||||
}
|
||||
|
||||
@ -98,6 +190,33 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
|
||||
dstData = route.Dst.IP.To16()
|
||||
}
|
||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_DST, dstData))
|
||||
} else if route.MPLSDst != nil {
|
||||
family = nl.FAMILY_MPLS
|
||||
msg.Dst_len = uint8(20)
|
||||
msg.Type = syscall.RTN_UNICAST
|
||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_DST, nl.EncodeMPLSStack(*route.MPLSDst)))
|
||||
}
|
||||
|
||||
if route.NewDst != nil {
|
||||
if family != -1 && family != route.NewDst.Family() {
|
||||
return fmt.Errorf("new destination and destination are not the same address family")
|
||||
}
|
||||
buf, err := route.NewDst.Encode()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(nl.RTA_NEWDST, buf))
|
||||
}
|
||||
|
||||
if route.Encap != nil {
|
||||
buf := make([]byte, 2)
|
||||
native.PutUint16(buf, uint16(route.Encap.Type()))
|
||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(nl.RTA_ENCAP_TYPE, buf))
|
||||
buf, err := route.Encap.Encode()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(nl.RTA_ENCAP, buf))
|
||||
}
|
||||
|
||||
if route.Src != nil {
|
||||
@ -138,26 +257,43 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
|
||||
RtNexthop: syscall.RtNexthop{
|
||||
Hops: uint8(nh.Hops),
|
||||
Ifindex: int32(nh.LinkIndex),
|
||||
Len: uint16(syscall.SizeofRtNexthop),
|
||||
Flags: uint8(nh.Flags),
|
||||
},
|
||||
}
|
||||
var gwData []byte
|
||||
children := []nl.NetlinkRequestData{}
|
||||
if nh.Gw != nil {
|
||||
gwFamily := nl.GetIPFamily(nh.Gw)
|
||||
if family != -1 && family != gwFamily {
|
||||
return fmt.Errorf("gateway, source, and destination ip are not the same IP family")
|
||||
}
|
||||
var gw *nl.RtAttr
|
||||
if gwFamily == FAMILY_V4 {
|
||||
gw = nl.NewRtAttr(syscall.RTA_GATEWAY, []byte(nh.Gw.To4()))
|
||||
children = append(children, nl.NewRtAttr(syscall.RTA_GATEWAY, []byte(nh.Gw.To4())))
|
||||
} else {
|
||||
gw = nl.NewRtAttr(syscall.RTA_GATEWAY, []byte(nh.Gw.To16()))
|
||||
children = append(children, nl.NewRtAttr(syscall.RTA_GATEWAY, []byte(nh.Gw.To16())))
|
||||
}
|
||||
gwData = gw.Serialize()
|
||||
rtnh.Len += uint16(len(gwData))
|
||||
}
|
||||
if nh.NewDst != nil {
|
||||
if family != -1 && family != nh.NewDst.Family() {
|
||||
return fmt.Errorf("new destination and destination are not the same address family")
|
||||
}
|
||||
buf, err := nh.NewDst.Encode()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
children = append(children, nl.NewRtAttr(nl.RTA_NEWDST, buf))
|
||||
}
|
||||
if nh.Encap != nil {
|
||||
buf := make([]byte, 2)
|
||||
native.PutUint16(buf, uint16(nh.Encap.Type()))
|
||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(nl.RTA_ENCAP_TYPE, buf))
|
||||
buf, err := nh.Encap.Encode()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
children = append(children, nl.NewRtAttr(nl.RTA_ENCAP, buf))
|
||||
}
|
||||
rtnh.Children = children
|
||||
buf = append(buf, rtnh.Serialize()...)
|
||||
buf = append(buf, gwData...)
|
||||
}
|
||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_MULTIPATH, buf))
|
||||
}
|
||||
@ -283,14 +419,22 @@ func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64)
|
||||
continue
|
||||
case filterMask&RT_FILTER_SRC != 0 && !route.Src.Equal(filter.Src):
|
||||
continue
|
||||
case filterMask&RT_FILTER_DST != 0 && filter.Dst != nil:
|
||||
if route.Dst == nil {
|
||||
continue
|
||||
}
|
||||
aMaskLen, aMaskBits := route.Dst.Mask.Size()
|
||||
bMaskLen, bMaskBits := filter.Dst.Mask.Size()
|
||||
if !(route.Dst.IP.Equal(filter.Dst.IP) && aMaskLen == bMaskLen && aMaskBits == bMaskBits) {
|
||||
continue
|
||||
case filterMask&RT_FILTER_DST != 0:
|
||||
if filter.MPLSDst == nil || route.MPLSDst == nil || (*filter.MPLSDst) != (*route.MPLSDst) {
|
||||
if filter.Dst == nil {
|
||||
if route.Dst != nil {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
if route.Dst == nil {
|
||||
continue
|
||||
}
|
||||
aMaskLen, aMaskBits := route.Dst.Mask.Size()
|
||||
bMaskLen, bMaskBits := filter.Dst.Mask.Size()
|
||||
if !(route.Dst.IP.Equal(filter.Dst.IP) && aMaskLen == bMaskLen && aMaskBits == bMaskBits) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -316,6 +460,7 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||
}
|
||||
|
||||
native := nl.NativeEndian()
|
||||
var encap, encapType syscall.NetlinkRouteAttr
|
||||
for _, attr := range attrs {
|
||||
switch attr.Attr.Type {
|
||||
case syscall.RTA_GATEWAY:
|
||||
@ -323,9 +468,17 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||
case syscall.RTA_PREFSRC:
|
||||
route.Src = net.IP(attr.Value)
|
||||
case syscall.RTA_DST:
|
||||
route.Dst = &net.IPNet{
|
||||
IP: attr.Value,
|
||||
Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attr.Value)),
|
||||
if msg.Family == nl.FAMILY_MPLS {
|
||||
stack := nl.DecodeMPLSStack(attr.Value)
|
||||
if len(stack) == 0 || len(stack) > 1 {
|
||||
return route, fmt.Errorf("invalid MPLS RTA_DST")
|
||||
}
|
||||
route.MPLSDst = &stack[0]
|
||||
} else {
|
||||
route.Dst = &net.IPNet{
|
||||
IP: attr.Value,
|
||||
Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attr.Value)),
|
||||
}
|
||||
}
|
||||
case syscall.RTA_OIF:
|
||||
route.LinkIndex = int(native.Uint32(attr.Value[0:4]))
|
||||
@ -347,17 +500,47 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||
info := &NexthopInfo{
|
||||
LinkIndex: int(nh.RtNexthop.Ifindex),
|
||||
Hops: int(nh.RtNexthop.Hops),
|
||||
Flags: int(nh.RtNexthop.Flags),
|
||||
}
|
||||
attrs, err := nl.ParseRouteAttr(value[syscall.SizeofRtNexthop:int(nh.RtNexthop.Len)])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
var encap, encapType syscall.NetlinkRouteAttr
|
||||
for _, attr := range attrs {
|
||||
switch attr.Attr.Type {
|
||||
case syscall.RTA_GATEWAY:
|
||||
info.Gw = net.IP(attr.Value)
|
||||
case nl.RTA_NEWDST:
|
||||
var d Destination
|
||||
switch msg.Family {
|
||||
case nl.FAMILY_MPLS:
|
||||
d = &MPLSDestination{}
|
||||
}
|
||||
if err := d.Decode(attr.Value); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
info.NewDst = d
|
||||
case nl.RTA_ENCAP_TYPE:
|
||||
encapType = attr
|
||||
case nl.RTA_ENCAP:
|
||||
encap = attr
|
||||
}
|
||||
}
|
||||
|
||||
if len(encap.Value) != 0 && len(encapType.Value) != 0 {
|
||||
typ := int(native.Uint16(encapType.Value[0:2]))
|
||||
var e Encap
|
||||
switch typ {
|
||||
case nl.LWTUNNEL_ENCAP_MPLS:
|
||||
e = &MPLSEncap{}
|
||||
if err := e.Decode(encap.Value); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
info.Encap = e
|
||||
}
|
||||
|
||||
return info, value[int(nh.RtNexthop.Len):], nil
|
||||
}
|
||||
rest := attr.Value
|
||||
@ -369,8 +552,36 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||
route.MultiPath = append(route.MultiPath, info)
|
||||
rest = buf
|
||||
}
|
||||
case nl.RTA_NEWDST:
|
||||
var d Destination
|
||||
switch msg.Family {
|
||||
case nl.FAMILY_MPLS:
|
||||
d = &MPLSDestination{}
|
||||
}
|
||||
if err := d.Decode(attr.Value); err != nil {
|
||||
return route, err
|
||||
}
|
||||
route.NewDst = d
|
||||
case nl.RTA_ENCAP_TYPE:
|
||||
encapType = attr
|
||||
case nl.RTA_ENCAP:
|
||||
encap = attr
|
||||
}
|
||||
}
|
||||
|
||||
if len(encap.Value) != 0 && len(encapType.Value) != 0 {
|
||||
typ := int(native.Uint16(encapType.Value[0:2]))
|
||||
var e Encap
|
||||
switch typ {
|
||||
case nl.LWTUNNEL_ENCAP_MPLS:
|
||||
e = &MPLSEncap{}
|
||||
if err := e.Decode(encap.Value); err != nil {
|
||||
return route, err
|
||||
}
|
||||
}
|
||||
route.Encap = e
|
||||
}
|
||||
|
||||
return route, nil
|
||||
}
|
||||
|
||||
|
4
vendor/github.com/vishvananda/netlink/route_unspecified.go
generated
vendored
4
vendor/github.com/vishvananda/netlink/route_unspecified.go
generated
vendored
@ -5,3 +5,7 @@ package netlink
|
||||
func (r *Route) ListFlags() []string {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
func (n *NexthopInfo) ListFlags() []string {
|
||||
return []string{}
|
||||
}
|
||||
|
27
vendor/github.com/vishvananda/netlink/socket.go
generated
vendored
Normal file
27
vendor/github.com/vishvananda/netlink/socket.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
package netlink
|
||||
|
||||
import "net"
|
||||
|
||||
// SocketID identifies a single socket.
|
||||
type SocketID struct {
|
||||
SourcePort uint16
|
||||
DestinationPort uint16
|
||||
Source net.IP
|
||||
Destination net.IP
|
||||
Interface uint32
|
||||
Cookie [2]uint32
|
||||
}
|
||||
|
||||
// Socket represents a netlink socket.
|
||||
type Socket struct {
|
||||
Family uint8
|
||||
State uint8
|
||||
Timer uint8
|
||||
Retrans uint8
|
||||
ID SocketID
|
||||
Expires uint32
|
||||
RQueue uint32
|
||||
WQueue uint32
|
||||
UID uint32
|
||||
INode uint32
|
||||
}
|
159
vendor/github.com/vishvananda/netlink/socket_linux.go
generated
vendored
Normal file
159
vendor/github.com/vishvananda/netlink/socket_linux.go
generated
vendored
Normal file
@ -0,0 +1,159 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"syscall"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
)
|
||||
|
||||
const (
|
||||
sizeofSocketID = 0x30
|
||||
sizeofSocketRequest = sizeofSocketID + 0x8
|
||||
sizeofSocket = sizeofSocketID + 0x18
|
||||
)
|
||||
|
||||
type socketRequest struct {
|
||||
Family uint8
|
||||
Protocol uint8
|
||||
Ext uint8
|
||||
pad uint8
|
||||
States uint32
|
||||
ID SocketID
|
||||
}
|
||||
|
||||
type writeBuffer struct {
|
||||
Bytes []byte
|
||||
pos int
|
||||
}
|
||||
|
||||
func (b *writeBuffer) Write(c byte) {
|
||||
b.Bytes[b.pos] = c
|
||||
b.pos++
|
||||
}
|
||||
|
||||
func (b *writeBuffer) Next(n int) []byte {
|
||||
s := b.Bytes[b.pos : b.pos+n]
|
||||
b.pos += n
|
||||
return s
|
||||
}
|
||||
|
||||
func (r *socketRequest) Serialize() []byte {
|
||||
b := writeBuffer{Bytes: make([]byte, sizeofSocketRequest)}
|
||||
b.Write(r.Family)
|
||||
b.Write(r.Protocol)
|
||||
b.Write(r.Ext)
|
||||
b.Write(r.pad)
|
||||
native.PutUint32(b.Next(4), r.States)
|
||||
networkOrder.PutUint16(b.Next(2), r.ID.SourcePort)
|
||||
networkOrder.PutUint16(b.Next(2), r.ID.DestinationPort)
|
||||
copy(b.Next(4), r.ID.Source.To4())
|
||||
b.Next(12)
|
||||
copy(b.Next(4), r.ID.Destination.To4())
|
||||
b.Next(12)
|
||||
native.PutUint32(b.Next(4), r.ID.Interface)
|
||||
native.PutUint32(b.Next(4), r.ID.Cookie[0])
|
||||
native.PutUint32(b.Next(4), r.ID.Cookie[1])
|
||||
return b.Bytes
|
||||
}
|
||||
|
||||
func (r *socketRequest) Len() int { return sizeofSocketRequest }
|
||||
|
||||
type readBuffer struct {
|
||||
Bytes []byte
|
||||
pos int
|
||||
}
|
||||
|
||||
func (b *readBuffer) Read() byte {
|
||||
c := b.Bytes[b.pos]
|
||||
b.pos++
|
||||
return c
|
||||
}
|
||||
|
||||
func (b *readBuffer) Next(n int) []byte {
|
||||
s := b.Bytes[b.pos : b.pos+n]
|
||||
b.pos += n
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Socket) deserialize(b []byte) error {
|
||||
if len(b) < sizeofSocket {
|
||||
return fmt.Errorf("socket data short read (%d); want %d", len(b), sizeofSocket)
|
||||
}
|
||||
rb := readBuffer{Bytes: b}
|
||||
s.Family = rb.Read()
|
||||
s.State = rb.Read()
|
||||
s.Timer = rb.Read()
|
||||
s.Retrans = rb.Read()
|
||||
s.ID.SourcePort = networkOrder.Uint16(rb.Next(2))
|
||||
s.ID.DestinationPort = networkOrder.Uint16(rb.Next(2))
|
||||
s.ID.Source = net.IPv4(rb.Read(), rb.Read(), rb.Read(), rb.Read())
|
||||
rb.Next(12)
|
||||
s.ID.Destination = net.IPv4(rb.Read(), rb.Read(), rb.Read(), rb.Read())
|
||||
rb.Next(12)
|
||||
s.ID.Interface = native.Uint32(rb.Next(4))
|
||||
s.ID.Cookie[0] = native.Uint32(rb.Next(4))
|
||||
s.ID.Cookie[1] = native.Uint32(rb.Next(4))
|
||||
s.Expires = native.Uint32(rb.Next(4))
|
||||
s.RQueue = native.Uint32(rb.Next(4))
|
||||
s.WQueue = native.Uint32(rb.Next(4))
|
||||
s.UID = native.Uint32(rb.Next(4))
|
||||
s.INode = native.Uint32(rb.Next(4))
|
||||
return nil
|
||||
}
|
||||
|
||||
// SocketGet returns the Socket identified by its local and remote addresses.
|
||||
func SocketGet(local, remote net.Addr) (*Socket, error) {
|
||||
localTCP, ok := local.(*net.TCPAddr)
|
||||
if !ok {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
remoteTCP, ok := remote.(*net.TCPAddr)
|
||||
if !ok {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
localIP := localTCP.IP.To4()
|
||||
if localIP == nil {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
remoteIP := remoteTCP.IP.To4()
|
||||
if remoteIP == nil {
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
s, err := nl.Subscribe(syscall.NETLINK_INET_DIAG)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer s.Close()
|
||||
req := nl.NewNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, 0)
|
||||
req.AddData(&socketRequest{
|
||||
Family: syscall.AF_INET,
|
||||
Protocol: syscall.IPPROTO_TCP,
|
||||
ID: SocketID{
|
||||
SourcePort: uint16(localTCP.Port),
|
||||
DestinationPort: uint16(remoteTCP.Port),
|
||||
Source: localIP,
|
||||
Destination: remoteIP,
|
||||
Cookie: [2]uint32{nl.TCPDIAG_NOCOOKIE, nl.TCPDIAG_NOCOOKIE},
|
||||
},
|
||||
})
|
||||
s.Send(req)
|
||||
msgs, err := s.Receive()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(msgs) == 0 {
|
||||
return nil, errors.New("no message nor error from netlink")
|
||||
}
|
||||
if len(msgs) > 2 {
|
||||
return nil, fmt.Errorf("multiple (%d) matching sockets", len(msgs))
|
||||
}
|
||||
sock := &Socket{}
|
||||
if err := sock.deserialize(msgs[0].Data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return sock, nil
|
||||
}
|
98
vendor/github.com/vishvananda/netlink/xfrm_monitor_linux.go
generated
vendored
Normal file
98
vendor/github.com/vishvananda/netlink/xfrm_monitor_linux.go
generated
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
|
||||
"github.com/vishvananda/netns"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
)
|
||||
|
||||
type XfrmMsg interface {
|
||||
Type() nl.XfrmMsgType
|
||||
}
|
||||
|
||||
type XfrmMsgExpire struct {
|
||||
XfrmState *XfrmState
|
||||
Hard bool
|
||||
}
|
||||
|
||||
func (ue *XfrmMsgExpire) Type() nl.XfrmMsgType {
|
||||
return nl.XFRM_MSG_EXPIRE
|
||||
}
|
||||
|
||||
func parseXfrmMsgExpire(b []byte) *XfrmMsgExpire {
|
||||
var e XfrmMsgExpire
|
||||
|
||||
msg := nl.DeserializeXfrmUserExpire(b)
|
||||
e.XfrmState = xfrmStateFromXfrmUsersaInfo(&msg.XfrmUsersaInfo)
|
||||
e.Hard = msg.Hard == 1
|
||||
|
||||
return &e
|
||||
}
|
||||
|
||||
func XfrmMonitor(ch chan<- XfrmMsg, done <-chan struct{}, errorChan chan<- error,
|
||||
types ...nl.XfrmMsgType) error {
|
||||
|
||||
groups, err := xfrmMcastGroups(types)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
s, err := nl.SubscribeAt(netns.None(), netns.None(), syscall.NETLINK_XFRM, groups...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if done != nil {
|
||||
go func() {
|
||||
<-done
|
||||
s.Close()
|
||||
}()
|
||||
|
||||
}
|
||||
|
||||
go func() {
|
||||
defer close(ch)
|
||||
for {
|
||||
msgs, err := s.Receive()
|
||||
if err != nil {
|
||||
errorChan <- err
|
||||
return
|
||||
}
|
||||
for _, m := range msgs {
|
||||
switch m.Header.Type {
|
||||
case nl.XFRM_MSG_EXPIRE:
|
||||
ch <- parseXfrmMsgExpire(m.Data)
|
||||
default:
|
||||
errorChan <- fmt.Errorf("unsupported msg type: %x", m.Header.Type)
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func xfrmMcastGroups(types []nl.XfrmMsgType) ([]uint, error) {
|
||||
groups := make([]uint, 0)
|
||||
|
||||
if len(types) == 0 {
|
||||
return nil, fmt.Errorf("no xfrm msg type specified")
|
||||
}
|
||||
|
||||
for _, t := range types {
|
||||
var group uint
|
||||
|
||||
switch t {
|
||||
case nl.XFRM_MSG_EXPIRE:
|
||||
group = nl.XFRMNLGRP_EXPIRE
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported group: %x", t)
|
||||
}
|
||||
|
||||
groups = append(groups, group)
|
||||
}
|
||||
|
||||
return groups, nil
|
||||
}
|
5
vendor/github.com/vishvananda/netlink/xfrm_state.go
generated
vendored
5
vendor/github.com/vishvananda/netlink/xfrm_state.go
generated
vendored
@ -83,11 +83,12 @@ type XfrmState struct {
|
||||
Crypt *XfrmStateAlgo
|
||||
Aead *XfrmStateAlgo
|
||||
Encap *XfrmStateEncap
|
||||
ESN bool
|
||||
}
|
||||
|
||||
func (sa XfrmState) String() string {
|
||||
return fmt.Sprintf("Dst: %v, Src: %v, Proto: %s, Mode: %s, SPI: 0x%x, ReqID: 0x%x, ReplayWindow: %d, Mark: %v, Auth: %v, Crypt: %v, Aead: %v,Encap: %v",
|
||||
sa.Dst, sa.Src, sa.Proto, sa.Mode, sa.Spi, sa.Reqid, sa.ReplayWindow, sa.Mark, sa.Auth, sa.Crypt, sa.Aead, sa.Encap)
|
||||
return fmt.Sprintf("Dst: %v, Src: %v, Proto: %s, Mode: %s, SPI: 0x%x, ReqID: 0x%x, ReplayWindow: %d, Mark: %v, Auth: %v, Crypt: %v, Aead: %v, Encap: %v, ESN: %t",
|
||||
sa.Dst, sa.Src, sa.Proto, sa.Mode, sa.Spi, sa.Reqid, sa.ReplayWindow, sa.Mark, sa.Auth, sa.Crypt, sa.Aead, sa.Encap, sa.ESN)
|
||||
}
|
||||
func (sa XfrmState) Print(stats bool) string {
|
||||
if !stats {
|
||||
|
112
vendor/github.com/vishvananda/netlink/xfrm_state_linux.go
generated
vendored
112
vendor/github.com/vishvananda/netlink/xfrm_state_linux.go
generated
vendored
@ -60,6 +60,21 @@ func writeMark(m *XfrmMark) []byte {
|
||||
return mark.Serialize()
|
||||
}
|
||||
|
||||
func writeReplayEsn(replayWindow int) []byte {
|
||||
replayEsn := &nl.XfrmReplayStateEsn{
|
||||
OSeq: 0,
|
||||
Seq: 0,
|
||||
OSeqHi: 0,
|
||||
SeqHi: 0,
|
||||
ReplayWindow: uint32(replayWindow),
|
||||
}
|
||||
|
||||
// taken from iproute2/ip/xfrm_state.c:
|
||||
replayEsn.BmpLen = uint32((replayWindow + (4 * 8) - 1) / (4 * 8))
|
||||
|
||||
return replayEsn.Serialize()
|
||||
}
|
||||
|
||||
// XfrmStateAdd will add an xfrm state to the system.
|
||||
// Equivalent to: `ip xfrm state add $state`
|
||||
func XfrmStateAdd(state *XfrmState) error {
|
||||
@ -72,6 +87,12 @@ func (h *Handle) XfrmStateAdd(state *XfrmState) error {
|
||||
return h.xfrmStateAddOrUpdate(state, nl.XFRM_MSG_NEWSA)
|
||||
}
|
||||
|
||||
// XfrmStateAllocSpi will allocate an xfrm state in the system.
|
||||
// Equivalent to: `ip xfrm state allocspi`
|
||||
func XfrmStateAllocSpi(state *XfrmState) (*XfrmState, error) {
|
||||
return pkgHandle.xfrmStateAllocSpi(state)
|
||||
}
|
||||
|
||||
// XfrmStateUpdate will update an xfrm state to the system.
|
||||
// Equivalent to: `ip xfrm state update $state`
|
||||
func XfrmStateUpdate(state *XfrmState) error {
|
||||
@ -85,21 +106,23 @@ func (h *Handle) XfrmStateUpdate(state *XfrmState) error {
|
||||
}
|
||||
|
||||
func (h *Handle) xfrmStateAddOrUpdate(state *XfrmState, nlProto int) error {
|
||||
|
||||
// A state with spi 0 can't be deleted so don't allow it to be set
|
||||
if state.Spi == 0 {
|
||||
return fmt.Errorf("Spi must be set when adding xfrm state.")
|
||||
}
|
||||
req := h.newNetlinkRequest(nlProto, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
||||
|
||||
msg := &nl.XfrmUsersaInfo{}
|
||||
msg.Family = uint16(nl.GetIPFamily(state.Dst))
|
||||
msg.Id.Daddr.FromIP(state.Dst)
|
||||
msg.Saddr.FromIP(state.Src)
|
||||
msg.Id.Proto = uint8(state.Proto)
|
||||
msg.Mode = uint8(state.Mode)
|
||||
msg.Id.Spi = nl.Swap32(uint32(state.Spi))
|
||||
msg.Reqid = uint32(state.Reqid)
|
||||
msg.ReplayWindow = uint8(state.ReplayWindow)
|
||||
msg := xfrmUsersaInfoFromXfrmState(state)
|
||||
|
||||
if state.ESN {
|
||||
if state.ReplayWindow == 0 {
|
||||
return fmt.Errorf("ESN flag set without ReplayWindow")
|
||||
}
|
||||
msg.Flags |= nl.XFRM_STATE_ESN
|
||||
msg.ReplayWindow = 0
|
||||
}
|
||||
|
||||
limitsToLft(state.Limits, &msg.Lft)
|
||||
req.AddData(msg)
|
||||
|
||||
@ -129,11 +152,44 @@ func (h *Handle) xfrmStateAddOrUpdate(state *XfrmState, nlProto int) error {
|
||||
out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(state.Mark))
|
||||
req.AddData(out)
|
||||
}
|
||||
if state.ESN {
|
||||
out := nl.NewRtAttr(nl.XFRMA_REPLAY_ESN_VAL, writeReplayEsn(state.ReplayWindow))
|
||||
req.AddData(out)
|
||||
}
|
||||
|
||||
_, err := req.Execute(syscall.NETLINK_XFRM, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
func (h *Handle) xfrmStateAllocSpi(state *XfrmState) (*XfrmState, error) {
|
||||
req := h.newNetlinkRequest(nl.XFRM_MSG_ALLOCSPI,
|
||||
syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
||||
|
||||
msg := &nl.XfrmUserSpiInfo{}
|
||||
msg.XfrmUsersaInfo = *(xfrmUsersaInfoFromXfrmState(state))
|
||||
// 1-255 is reserved by IANA for future use
|
||||
msg.Min = 0x100
|
||||
msg.Max = 0xffffffff
|
||||
req.AddData(msg)
|
||||
|
||||
if state.Mark != nil {
|
||||
out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(state.Mark))
|
||||
req.AddData(out)
|
||||
}
|
||||
|
||||
msgs, err := req.Execute(syscall.NETLINK_XFRM, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s, err := parseXfrmState(msgs[0], FAMILY_ALL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s, err
|
||||
}
|
||||
|
||||
// XfrmStateDel will delete an xfrm state from the system. Note that
|
||||
// the Algos are ignored when matching the state to delete.
|
||||
// Equivalent to: `ip xfrm state del $state`
|
||||
@ -241,14 +297,7 @@ func (h *Handle) xfrmStateGetOrDelete(state *XfrmState, nlProto int) (*XfrmState
|
||||
|
||||
var familyError = fmt.Errorf("family error")
|
||||
|
||||
func parseXfrmState(m []byte, family int) (*XfrmState, error) {
|
||||
msg := nl.DeserializeXfrmUsersaInfo(m)
|
||||
|
||||
// This is mainly for the state dump
|
||||
if family != FAMILY_ALL && family != int(msg.Family) {
|
||||
return nil, familyError
|
||||
}
|
||||
|
||||
func xfrmStateFromXfrmUsersaInfo(msg *nl.XfrmUsersaInfo) *XfrmState {
|
||||
var state XfrmState
|
||||
|
||||
state.Dst = msg.Id.Daddr.ToIP()
|
||||
@ -260,6 +309,19 @@ func parseXfrmState(m []byte, family int) (*XfrmState, error) {
|
||||
state.ReplayWindow = int(msg.ReplayWindow)
|
||||
lftToLimits(&msg.Lft, &state.Limits)
|
||||
|
||||
return &state
|
||||
}
|
||||
|
||||
func parseXfrmState(m []byte, family int) (*XfrmState, error) {
|
||||
msg := nl.DeserializeXfrmUsersaInfo(m)
|
||||
|
||||
// This is mainly for the state dump
|
||||
if family != FAMILY_ALL && family != int(msg.Family) {
|
||||
return nil, familyError
|
||||
}
|
||||
|
||||
state := xfrmStateFromXfrmUsersaInfo(msg)
|
||||
|
||||
attrs, err := nl.ParseRouteAttr(m[nl.SizeofXfrmUsersaInfo:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -310,7 +372,7 @@ func parseXfrmState(m []byte, family int) (*XfrmState, error) {
|
||||
}
|
||||
}
|
||||
|
||||
return &state, nil
|
||||
return state, nil
|
||||
}
|
||||
|
||||
// XfrmStateFlush will flush the xfrm state on the system.
|
||||
@ -366,3 +428,17 @@ func limitsToLft(lmts XfrmStateLimits, lft *nl.XfrmLifetimeCfg) {
|
||||
func lftToLimits(lft *nl.XfrmLifetimeCfg, lmts *XfrmStateLimits) {
|
||||
*lmts = *(*XfrmStateLimits)(unsafe.Pointer(lft))
|
||||
}
|
||||
|
||||
func xfrmUsersaInfoFromXfrmState(state *XfrmState) *nl.XfrmUsersaInfo {
|
||||
msg := &nl.XfrmUsersaInfo{}
|
||||
msg.Family = uint16(nl.GetIPFamily(state.Dst))
|
||||
msg.Id.Daddr.FromIP(state.Dst)
|
||||
msg.Saddr.FromIP(state.Src)
|
||||
msg.Id.Proto = uint8(state.Proto)
|
||||
msg.Mode = uint8(state.Mode)
|
||||
msg.Id.Spi = nl.Swap32(uint32(state.Spi))
|
||||
msg.Reqid = uint32(state.Reqid)
|
||||
msg.ReplayWindow = uint8(state.ReplayWindow)
|
||||
|
||||
return msg
|
||||
}
|
||||
|
3
vendor/golang.org/x/sys/AUTHORS
generated
vendored
Normal file
3
vendor/golang.org/x/sys/AUTHORS
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# This source code refers to The Go Authors for copyright purposes.
|
||||
# The master list of authors is in the main Go distribution,
|
||||
# visible at http://tip.golang.org/AUTHORS.
|
3
vendor/golang.org/x/sys/CONTRIBUTORS
generated
vendored
Normal file
3
vendor/golang.org/x/sys/CONTRIBUTORS
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# This source code was written by the Go contributors.
|
||||
# The master list of contributors is in the main Go distribution,
|
||||
# visible at http://tip.golang.org/CONTRIBUTORS.
|
0
vendor/golang.org/x/sys/unix/mkall.sh
generated
vendored
Normal file → Executable file
0
vendor/golang.org/x/sys/unix/mkall.sh
generated
vendored
Normal file → Executable file
0
vendor/golang.org/x/sys/unix/mkerrors.sh
generated
vendored
Normal file → Executable file
0
vendor/golang.org/x/sys/unix/mkerrors.sh
generated
vendored
Normal file → Executable file
0
vendor/golang.org/x/sys/unix/mksyscall.pl
generated
vendored
Normal file → Executable file
0
vendor/golang.org/x/sys/unix/mksyscall.pl
generated
vendored
Normal file → Executable file
0
vendor/golang.org/x/sys/unix/mksyscall_solaris.pl
generated
vendored
Normal file → Executable file
0
vendor/golang.org/x/sys/unix/mksyscall_solaris.pl
generated
vendored
Normal file → Executable file
0
vendor/golang.org/x/sys/unix/mksysctl_openbsd.pl
generated
vendored
Normal file → Executable file
0
vendor/golang.org/x/sys/unix/mksysctl_openbsd.pl
generated
vendored
Normal file → Executable file
0
vendor/golang.org/x/sys/unix/mksysnum_darwin.pl
generated
vendored
Normal file → Executable file
0
vendor/golang.org/x/sys/unix/mksysnum_darwin.pl
generated
vendored
Normal file → Executable file
0
vendor/golang.org/x/sys/unix/mksysnum_dragonfly.pl
generated
vendored
Normal file → Executable file
0
vendor/golang.org/x/sys/unix/mksysnum_dragonfly.pl
generated
vendored
Normal file → Executable file
0
vendor/golang.org/x/sys/unix/mksysnum_freebsd.pl
generated
vendored
Normal file → Executable file
0
vendor/golang.org/x/sys/unix/mksysnum_freebsd.pl
generated
vendored
Normal file → Executable file
0
vendor/golang.org/x/sys/unix/mksysnum_linux.pl
generated
vendored
Normal file → Executable file
0
vendor/golang.org/x/sys/unix/mksysnum_linux.pl
generated
vendored
Normal file → Executable file
0
vendor/golang.org/x/sys/unix/mksysnum_netbsd.pl
generated
vendored
Normal file → Executable file
0
vendor/golang.org/x/sys/unix/mksysnum_netbsd.pl
generated
vendored
Normal file → Executable file
0
vendor/golang.org/x/sys/unix/mksysnum_openbsd.pl
generated
vendored
Normal file → Executable file
0
vendor/golang.org/x/sys/unix/mksysnum_openbsd.pl
generated
vendored
Normal file → Executable file
Loading…
x
Reference in New Issue
Block a user