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",
|
"ImportPath": "github.com/containernetworking/cni",
|
||||||
"GoVersion": "go1.6",
|
"GoVersion": "go1.6",
|
||||||
"GodepVersion": "v75",
|
"GodepVersion": "v79",
|
||||||
"Packages": [
|
"Packages": [
|
||||||
"./..."
|
"./..."
|
||||||
],
|
],
|
||||||
@ -39,46 +39,6 @@
|
|||||||
"Comment": "v1.2.0-29-g7f8ab55",
|
"Comment": "v1.2.0-29-g7f8ab55",
|
||||||
"Rev": "7f8ab55aaf3b86885aa55b762e803744d1674700"
|
"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",
|
"ImportPath": "github.com/onsi/ginkgo/internal/codelocation",
|
||||||
"Comment": "v1.2.0-29-g7f8ab55",
|
"Comment": "v1.2.0-29-g7f8ab55",
|
||||||
@ -216,19 +176,19 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/vishvananda/netlink",
|
"ImportPath": "github.com/vishvananda/netlink",
|
||||||
"Rev": "a1f8555521646b5a9800f39c5fd477597697135c"
|
"Rev": "fe3b5664d23a11b52ba59bece4ff29c52772a56b"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/vishvananda/netlink/nl",
|
"ImportPath": "github.com/vishvananda/netlink/nl",
|
||||||
"Rev": "a1f8555521646b5a9800f39c5fd477597697135c"
|
"Rev": "fe3b5664d23a11b52ba59bece4ff29c52772a56b"
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "golang.org/x/sys/unix",
|
|
||||||
"Rev": "076b546753157f758b316e59bcb51e6807c04057"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/vishvananda/netns",
|
"ImportPath": "github.com/vishvananda/netns",
|
||||||
"Rev": "8ba1072b58e0c2a240eb5f6120165c7776c3e7b8"
|
"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")
|
_, defNet, _ := net.ParseCIDR("0.0.0.0/0")
|
||||||
return AddRoute(defNet, gw, dev)
|
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
|
package ns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type NetNS interface {
|
type NetNS interface {
|
||||||
@ -65,18 +61,6 @@ type netNS struct {
|
|||||||
// netNS implements the NetNS interface
|
// netNS implements the NetNS interface
|
||||||
var _ NetNS = &netNS{}
|
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 (
|
const (
|
||||||
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/magic.h
|
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/magic.h
|
||||||
NSFS_MAGIC = 0x6e736673
|
NSFS_MAGIC = 0x6e736673
|
||||||
@ -125,82 +109,6 @@ func GetNS(nspath string) (NetNS, error) {
|
|||||||
return &netNS{file: fd}, nil
|
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 {
|
func (ns *netNS) Path() string {
|
||||||
return ns.file.Name()
|
return ns.file.Name()
|
||||||
}
|
}
|
||||||
@ -216,36 +124,13 @@ func (ns *netNS) errorIfClosed() error {
|
|||||||
return nil
|
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 {
|
func (ns *netNS) Do(toRun func(NetNS) error) error {
|
||||||
if err := ns.errorIfClosed(); err != nil {
|
if err := ns.errorIfClosed(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
containedCall := func(hostNS NetNS) error {
|
containedCall := func(hostNS NetNS) error {
|
||||||
threadNS, err := GetNS(getCurrentThreadNetNSPath())
|
threadNS, err := GetCurrentNS()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to open current netns: %v", err)
|
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
|
// save a handle to current network namespace
|
||||||
hostNS, err := GetNS(getCurrentThreadNetNSPath())
|
hostNS, err := GetCurrentNS()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to open current namespace: %v", err)
|
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
|
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
|
// WithNetNSPath executes the passed closure under the given network
|
||||||
// namespace, restoring the original namespace afterwards.
|
// namespace, restoring the original namespace afterwards.
|
||||||
func WithNetNSPath(nspath string, toRun func(NetNS) error) error {
|
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 (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
@ -178,3 +179,6 @@ func prettyPrint(obj interface{}) error {
|
|||||||
_, err = os.Stdout.Write(data)
|
_, err = os.Stdout.Write(data)
|
||||||
return err
|
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/$@
|
sudo -E go test -test.parallel 4 -timeout 60s -v github.com/vishvananda/netlink/$@
|
||||||
|
|
||||||
$(call fmt,$(call testdirs,$(DIRS))):
|
$(call fmt,$(call testdirs,$(DIRS))):
|
||||||
! gofmt -l $(subst fmt-,,$@)/*.go | grep ''
|
! gofmt -l $(subst fmt-,,$@)/*.go | grep -q .
|
||||||
|
|
||||||
.PHONY: fmt
|
.PHONY: fmt
|
||||||
fmt: $(call fmt,$(call testdirs,$(DIRS)))
|
fmt: $(call fmt,$(call testdirs,$(DIRS)))
|
||||||
|
9
vendor/github.com/vishvananda/netlink/addr.go
generated
vendored
9
vendor/github.com/vishvananda/netlink/addr.go
generated
vendored
@ -13,6 +13,8 @@ type Addr struct {
|
|||||||
Label string
|
Label string
|
||||||
Flags int
|
Flags int
|
||||||
Scope int
|
Scope int
|
||||||
|
Peer *net.IPNet
|
||||||
|
Broadcast net.IP
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns $ip/$netmask $label
|
// String returns $ip/$netmask $label
|
||||||
@ -43,3 +45,10 @@ func (a Addr) Equal(x Addr) bool {
|
|||||||
// ignore label for comparison
|
// ignore label for comparison
|
||||||
return a.IP.Equal(x.IP) && sizea == sizeb
|
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)
|
msg.Prefixlen = uint8(prefixlen)
|
||||||
req.AddData(msg)
|
req.AddData(msg)
|
||||||
|
|
||||||
var addrData []byte
|
var localAddrData []byte
|
||||||
if family == FAMILY_V4 {
|
if family == FAMILY_V4 {
|
||||||
addrData = addr.IP.To4()
|
localAddrData = addr.IP.To4()
|
||||||
} else {
|
} 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)
|
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)
|
req.AddData(addressData)
|
||||||
|
|
||||||
if addr.Flags != 0 {
|
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 != "" {
|
if addr.Label != "" {
|
||||||
labelData := nl.NewRtAttr(syscall.IFA_LABEL, nl.ZeroTerminated(addr.Label))
|
labelData := nl.NewRtAttr(syscall.IFA_LABEL, nl.ZeroTerminated(addr.Label))
|
||||||
req.AddData(labelData)
|
req.AddData(labelData)
|
||||||
@ -161,11 +175,13 @@ func parseAddr(m []byte) (addr Addr, family, index int, err error) {
|
|||||||
IP: attr.Value,
|
IP: attr.Value,
|
||||||
Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
|
Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
|
||||||
}
|
}
|
||||||
|
addr.Peer = dst
|
||||||
case syscall.IFA_LOCAL:
|
case syscall.IFA_LOCAL:
|
||||||
local = &net.IPNet{
|
local = &net.IPNet{
|
||||||
IP: attr.Value,
|
IP: attr.Value,
|
||||||
Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
|
Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
|
||||||
}
|
}
|
||||||
|
addr.IPNet = local
|
||||||
case syscall.IFA_LABEL:
|
case syscall.IFA_LABEL:
|
||||||
addr.Label = string(attr.Value[:len(attr.Value)-1])
|
addr.Label = string(attr.Value[:len(attr.Value)-1])
|
||||||
case IFA_FLAGS:
|
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
|
package netlink
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
"github.com/vishvananda/netns"
|
"github.com/vishvananda/netns"
|
||||||
@ -33,6 +35,29 @@ func NewHandle(nlFamilies ...int) (*Handle, error) {
|
|||||||
return newHandle(netns.None(), netns.None(), nlFamilies...)
|
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
|
// NewHandle returns a netlink handle on the network namespace
|
||||||
// specified by ns. If ns=netns.None(), current network namespace
|
// specified by ns. If ns=netns.None(), current network namespace
|
||||||
// will be assumed
|
// 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
|
Promisc int
|
||||||
Xdp *LinkXdp
|
Xdp *LinkXdp
|
||||||
EncapType string
|
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
|
// NewLinkAttrs returns LinkAttrs structure filled with default values
|
||||||
@ -44,10 +79,12 @@ func NewLinkAttrs() LinkAttrs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LinkStatistics LinkStatistics64
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Ref: struct rtnl_link_stats {...}
|
Ref: struct rtnl_link_stats {...}
|
||||||
*/
|
*/
|
||||||
type LinkStatistics struct {
|
type LinkStatistics32 struct {
|
||||||
RxPackets uint32
|
RxPackets uint32
|
||||||
TxPackets uint32
|
TxPackets uint32
|
||||||
RxBytes uint32
|
RxBytes uint32
|
||||||
@ -73,6 +110,63 @@ type LinkStatistics struct {
|
|||||||
TxCompressed uint32
|
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 {
|
type LinkXdp struct {
|
||||||
Fd int
|
Fd int
|
||||||
Attached bool
|
Attached bool
|
||||||
@ -301,31 +395,31 @@ func StringToBondMode(s string) BondMode {
|
|||||||
|
|
||||||
// Possible BondMode
|
// Possible BondMode
|
||||||
const (
|
const (
|
||||||
BOND_MODE_802_3AD BondMode = iota
|
BOND_MODE_BALANCE_RR BondMode = iota
|
||||||
BOND_MODE_BALANCE_RR
|
|
||||||
BOND_MODE_ACTIVE_BACKUP
|
BOND_MODE_ACTIVE_BACKUP
|
||||||
BOND_MODE_BALANCE_XOR
|
BOND_MODE_BALANCE_XOR
|
||||||
BOND_MODE_BROADCAST
|
BOND_MODE_BROADCAST
|
||||||
|
BOND_MODE_802_3AD
|
||||||
BOND_MODE_BALANCE_TLB
|
BOND_MODE_BALANCE_TLB
|
||||||
BOND_MODE_BALANCE_ALB
|
BOND_MODE_BALANCE_ALB
|
||||||
BOND_MODE_UNKNOWN
|
BOND_MODE_UNKNOWN
|
||||||
)
|
)
|
||||||
|
|
||||||
var bondModeToString = map[BondMode]string{
|
var bondModeToString = map[BondMode]string{
|
||||||
BOND_MODE_802_3AD: "802.3ad",
|
|
||||||
BOND_MODE_BALANCE_RR: "balance-rr",
|
BOND_MODE_BALANCE_RR: "balance-rr",
|
||||||
BOND_MODE_ACTIVE_BACKUP: "active-backup",
|
BOND_MODE_ACTIVE_BACKUP: "active-backup",
|
||||||
BOND_MODE_BALANCE_XOR: "balance-xor",
|
BOND_MODE_BALANCE_XOR: "balance-xor",
|
||||||
BOND_MODE_BROADCAST: "broadcast",
|
BOND_MODE_BROADCAST: "broadcast",
|
||||||
|
BOND_MODE_802_3AD: "802.3ad",
|
||||||
BOND_MODE_BALANCE_TLB: "balance-tlb",
|
BOND_MODE_BALANCE_TLB: "balance-tlb",
|
||||||
BOND_MODE_BALANCE_ALB: "balance-alb",
|
BOND_MODE_BALANCE_ALB: "balance-alb",
|
||||||
}
|
}
|
||||||
var StringToBondModeMap = map[string]BondMode{
|
var StringToBondModeMap = map[string]BondMode{
|
||||||
"802.3ad": BOND_MODE_802_3AD,
|
|
||||||
"balance-rr": BOND_MODE_BALANCE_RR,
|
"balance-rr": BOND_MODE_BALANCE_RR,
|
||||||
"active-backup": BOND_MODE_ACTIVE_BACKUP,
|
"active-backup": BOND_MODE_ACTIVE_BACKUP,
|
||||||
"balance-xor": BOND_MODE_BALANCE_XOR,
|
"balance-xor": BOND_MODE_BALANCE_XOR,
|
||||||
"broadcast": BOND_MODE_BROADCAST,
|
"broadcast": BOND_MODE_BROADCAST,
|
||||||
|
"802.3ad": BOND_MODE_802_3AD,
|
||||||
"balance-tlb": BOND_MODE_BALANCE_TLB,
|
"balance-tlb": BOND_MODE_BALANCE_TLB,
|
||||||
"balance-alb": BOND_MODE_BALANCE_ALB,
|
"balance-alb": BOND_MODE_BALANCE_ALB,
|
||||||
}
|
}
|
||||||
@ -589,6 +683,54 @@ func (gretap *Gretap) Type() string {
|
|||||||
return "gretap"
|
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;
|
// iproute2 supported devices;
|
||||||
// vlan | veth | vcan | dummy | ifb | macvlan | macvtap |
|
// vlan | veth | vcan | dummy | ifb | macvlan | macvtap |
|
||||||
// bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan |
|
// 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"
|
"github.com/vishvananda/netns"
|
||||||
)
|
)
|
||||||
|
|
||||||
const SizeofLinkStats = 0x5c
|
const (
|
||||||
|
SizeofLinkStats32 = 0x5c
|
||||||
|
SizeofLinkStats64 = 0xd8
|
||||||
|
IFLA_STATS64 = 0x17 // syscall pkg does not contain this one
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
TUNTAP_MODE_TUN TuntapMode = syscall.IFF_TUN
|
TUNTAP_MODE_TUN TuntapMode = syscall.IFF_TUN
|
||||||
@ -25,7 +29,6 @@ const (
|
|||||||
TUNTAP_ONE_QUEUE TuntapFlag = syscall.IFF_ONE_QUEUE
|
TUNTAP_ONE_QUEUE TuntapFlag = syscall.IFF_ONE_QUEUE
|
||||||
)
|
)
|
||||||
|
|
||||||
var native = nl.NativeEndian()
|
|
||||||
var lookupByDump = false
|
var lookupByDump = false
|
||||||
|
|
||||||
var macvlanModes = [...]uint32{
|
var macvlanModes = [...]uint32{
|
||||||
@ -298,6 +301,36 @@ func (h *Handle) LinkSetVfVlan(link Link, vf, vlan int) error {
|
|||||||
return err
|
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.
|
// LinkSetMaster sets the master of the link device.
|
||||||
// Equivalent to: `ip link set $link master $master`
|
// Equivalent to: `ip link set $link master $master`
|
||||||
func LinkSetMaster(link Link, master *Bridge) error {
|
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 {
|
} else if gretap, ok := link.(*Gretap); ok {
|
||||||
addGretapAttrs(gretap, linkInfo)
|
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)
|
req.AddData(linkInfo)
|
||||||
@ -919,7 +958,7 @@ func execGetLink(req *nl.NetlinkRequest) (Link, error) {
|
|||||||
return nil, fmt.Errorf("Link not found")
|
return nil, fmt.Errorf("Link not found")
|
||||||
|
|
||||||
case len(msgs) == 1:
|
case len(msgs) == 1:
|
||||||
return linkDeserialize(msgs[0])
|
return LinkDeserialize(nil, msgs[0])
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("More than one link found")
|
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
|
// linkDeserialize deserializes a raw message received from netlink into
|
||||||
// a link object.
|
// a link object.
|
||||||
func linkDeserialize(m []byte) (Link, error) {
|
func LinkDeserialize(hdr *syscall.NlMsghdr, m []byte) (Link, error) {
|
||||||
msg := nl.DeserializeIfInfomsg(m)
|
msg := nl.DeserializeIfInfomsg(m)
|
||||||
|
|
||||||
attrs, err := nl.ParseRouteAttr(m[msg.Len():])
|
attrs, err := nl.ParseRouteAttr(m[msg.Len():])
|
||||||
@ -940,8 +979,12 @@ func linkDeserialize(m []byte) (Link, error) {
|
|||||||
if msg.Flags&syscall.IFF_PROMISC != 0 {
|
if msg.Flags&syscall.IFF_PROMISC != 0 {
|
||||||
base.Promisc = 1
|
base.Promisc = 1
|
||||||
}
|
}
|
||||||
var link Link
|
var (
|
||||||
linkType := ""
|
link Link
|
||||||
|
stats32 []byte
|
||||||
|
stats64 []byte
|
||||||
|
linkType string
|
||||||
|
)
|
||||||
for _, attr := range attrs {
|
for _, attr := range attrs {
|
||||||
switch attr.Attr.Type {
|
switch attr.Attr.Type {
|
||||||
case syscall.IFLA_LINKINFO:
|
case syscall.IFLA_LINKINFO:
|
||||||
@ -976,6 +1019,12 @@ func linkDeserialize(m []byte) (Link, error) {
|
|||||||
link = &Macvtap{}
|
link = &Macvtap{}
|
||||||
case "gretap":
|
case "gretap":
|
||||||
link = &Gretap{}
|
link = &Gretap{}
|
||||||
|
case "ipip":
|
||||||
|
link = &Iptun{}
|
||||||
|
case "vti":
|
||||||
|
link = &Vti{}
|
||||||
|
case "vrf":
|
||||||
|
link = &Vrf{}
|
||||||
default:
|
default:
|
||||||
link = &GenericLink{LinkType: linkType}
|
link = &GenericLink{LinkType: linkType}
|
||||||
}
|
}
|
||||||
@ -999,6 +1048,12 @@ func linkDeserialize(m []byte) (Link, error) {
|
|||||||
parseMacvtapData(link, data)
|
parseMacvtapData(link, data)
|
||||||
case "gretap":
|
case "gretap":
|
||||||
parseGretapData(link, data)
|
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:
|
case syscall.IFLA_IFALIAS:
|
||||||
base.Alias = string(attr.Value[:len(attr.Value)-1])
|
base.Alias = string(attr.Value[:len(attr.Value)-1])
|
||||||
case syscall.IFLA_STATS:
|
case syscall.IFLA_STATS:
|
||||||
base.Statistics = parseLinkStats(attr.Value[:])
|
stats32 = attr.Value[:]
|
||||||
|
case IFLA_STATS64:
|
||||||
|
stats64 = attr.Value[:]
|
||||||
case nl.IFLA_XDP:
|
case nl.IFLA_XDP:
|
||||||
xdp, err := parseLinkXdp(attr.Value[:])
|
xdp, err := parseLinkXdp(attr.Value[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
base.Xdp = xdp
|
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
|
// Links that don't have IFLA_INFO_KIND are hardware devices
|
||||||
if link == nil {
|
if link == nil {
|
||||||
link = &Device{}
|
link = &Device{}
|
||||||
@ -1066,7 +1141,7 @@ func (h *Handle) LinkList() ([]Link, error) {
|
|||||||
|
|
||||||
var res []Link
|
var res []Link
|
||||||
for _, m := range msgs {
|
for _, m := range msgs {
|
||||||
link, err := linkDeserialize(m)
|
link, err := LinkDeserialize(nil, m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1115,7 +1190,7 @@ func linkSubscribe(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-cha
|
|||||||
}
|
}
|
||||||
for _, m := range msgs {
|
for _, m := range msgs {
|
||||||
ifmsg := nl.DeserializeIfInfomsg(m.Data)
|
ifmsg := nl.DeserializeIfInfomsg(m.Data)
|
||||||
link, err := linkDeserialize(m.Data)
|
link, err := LinkDeserialize(&m.Header, m.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1367,26 +1442,6 @@ func linkFlags(rawFlags uint32) net.Flags {
|
|||||||
return f
|
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) {
|
func addGretapAttrs(gretap *Gretap, linkInfo *nl.RtAttr) {
|
||||||
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
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 {
|
func parseLinkStats32(data []byte) *LinkStatistics {
|
||||||
return (*LinkStatistics)(unsafe.Pointer(&data[0:SizeofLinkStats][0]))
|
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) {
|
func addXdpAttrs(xdp *LinkXdp, req *nl.NetlinkRequest) {
|
||||||
@ -1488,3 +1547,96 @@ func parseLinkXdp(data []byte) (*LinkXdp, error) {
|
|||||||
}
|
}
|
||||||
return xdp, nil
|
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.
|
// interface that is loosly modeled on the iproute2 cli.
|
||||||
package netlink
|
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.
|
// ParseIPNet parses a string in ip/net format and returns a net.IPNet.
|
||||||
// This is valuable because addresses in netlink are often IPNets and
|
// This is valuable because addresses in netlink are often IPNets and
|
||||||
|
1
vendor/github.com/vishvananda/netlink/netlink_linux.go
generated
vendored
1
vendor/github.com/vishvananda/netlink/netlink_linux.go
generated
vendored
@ -7,4 +7,5 @@ const (
|
|||||||
FAMILY_ALL = nl.FAMILY_ALL
|
FAMILY_ALL = nl.FAMILY_ALL
|
||||||
FAMILY_V4 = nl.FAMILY_V4
|
FAMILY_V4 = nl.FAMILY_V4
|
||||||
FAMILY_V6 = nl.FAMILY_V6
|
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
|
package netlink
|
||||||
|
|
||||||
import (
|
import "net"
|
||||||
"errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
func LinkSetUp(link Link) error {
|
||||||
ErrNotImplemented = errors.New("not implemented")
|
|
||||||
)
|
|
||||||
|
|
||||||
func LinkSetUp(link *Link) error {
|
|
||||||
return ErrNotImplemented
|
return ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
func LinkSetDown(link *Link) error {
|
func LinkSetDown(link Link) error {
|
||||||
return ErrNotImplemented
|
return ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
func LinkSetMTU(link *Link, mtu int) error {
|
func LinkSetMTU(link Link, mtu int) error {
|
||||||
return ErrNotImplemented
|
return ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
func LinkSetMaster(link *Link, master *Link) error {
|
func LinkSetMaster(link Link, master *Link) error {
|
||||||
return ErrNotImplemented
|
return ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
func LinkSetNsPid(link *Link, nspid int) error {
|
func LinkSetNsPid(link Link, nspid int) error {
|
||||||
return ErrNotImplemented
|
return ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
func LinkSetNsFd(link *Link, fd int) error {
|
func LinkSetNsFd(link Link, fd int) error {
|
||||||
return ErrNotImplemented
|
return ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
func LinkAdd(link *Link) error {
|
func LinkSetName(link Link, name string) error {
|
||||||
return ErrNotImplemented
|
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
|
return ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,15 +136,15 @@ func LinkList() ([]Link, error) {
|
|||||||
return nil, ErrNotImplemented
|
return nil, ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddrAdd(link *Link, addr *Addr) error {
|
func AddrAdd(link Link, addr *Addr) error {
|
||||||
return ErrNotImplemented
|
return ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddrDel(link *Link, addr *Addr) error {
|
func AddrDel(link Link, addr *Addr) error {
|
||||||
return ErrNotImplemented
|
return ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddrList(link *Link, family int) ([]Addr, error) {
|
func AddrList(link Link, family int) ([]Addr, error) {
|
||||||
return nil, ErrNotImplemented
|
return nil, ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +156,7 @@ func RouteDel(route *Route) error {
|
|||||||
return ErrNotImplemented
|
return ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
func RouteList(link *Link, family int) ([]Route, error) {
|
func RouteList(link Link, family int) ([]Route, error) {
|
||||||
return nil, ErrNotImplemented
|
return nil, ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,3 +207,7 @@ func NeighList(linkIndex, family int) ([]Neigh, error) {
|
|||||||
func NeighDeserialize(m []byte) (*Neigh, error) {
|
func NeighDeserialize(m []byte) (*Neigh, error) {
|
||||||
return nil, ErrNotImplemented
|
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_ATTACHED /* read-only bool indicating if prog is attached */
|
||||||
IFLA_XDP_MAX = IFLA_XDP_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
|
||||||
|
}
|
8
vendor/github.com/vishvananda/netlink/nl/nl_linux.go
generated
vendored
8
vendor/github.com/vishvananda/netlink/nl/nl_linux.go
generated
vendored
@ -20,6 +20,7 @@ const (
|
|||||||
FAMILY_ALL = syscall.AF_UNSPEC
|
FAMILY_ALL = syscall.AF_UNSPEC
|
||||||
FAMILY_V4 = syscall.AF_INET
|
FAMILY_V4 = syscall.AF_INET
|
||||||
FAMILY_V6 = syscall.AF_INET6
|
FAMILY_V6 = syscall.AF_INET6
|
||||||
|
FAMILY_MPLS = AF_MPLS
|
||||||
)
|
)
|
||||||
|
|
||||||
// SupportedNlFamilies contains the list of netlink families this netlink package supports
|
// SupportedNlFamilies contains the list of netlink families this netlink package supports
|
||||||
@ -656,6 +657,13 @@ func Uint32Attr(v uint32) []byte {
|
|||||||
return bytes
|
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) {
|
func ParseRouteAttr(b []byte) ([]syscall.NetlinkRouteAttr, error) {
|
||||||
var attrs []syscall.NetlinkRouteAttr
|
var attrs []syscall.NetlinkRouteAttr
|
||||||
for len(b) >= syscall.SizeofRtAttr {
|
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 {
|
type RtNexthop struct {
|
||||||
syscall.RtNexthop
|
syscall.RtNexthop
|
||||||
|
Children []NetlinkRequestData
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeserializeRtNexthop(b []byte) *RtNexthop {
|
func DeserializeRtNexthop(b []byte) *RtNexthop {
|
||||||
return (*RtNexthop)(unsafe.Pointer(&b[0:syscall.SizeofRtNexthop][0]))
|
return (*RtNexthop)(unsafe.Pointer(&b[0:syscall.SizeofRtNexthop][0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (msg *RtNexthop) Serialize() []byte {
|
func (msg *RtNexthop) Len() int {
|
||||||
return (*(*[syscall.SizeofRtNexthop]byte)(unsafe.Pointer(msg)))[:]
|
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_UNREACHABLE /* Drop with ENETUNREACH */
|
||||||
FR_ACT_PROHIBIT /* Drop with EACCES */
|
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
|
||||||
|
)
|
||||||
|
22
vendor/github.com/vishvananda/netlink/nl/xfrm_linux.go
generated
vendored
22
vendor/github.com/vishvananda/netlink/nl/xfrm_linux.go
generated
vendored
@ -11,9 +11,15 @@ const (
|
|||||||
XFRM_INF = ^uint64(0)
|
XFRM_INF = ^uint64(0)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type XfrmMsgType uint8
|
||||||
|
|
||||||
|
type XfrmMsg interface {
|
||||||
|
Type() XfrmMsgType
|
||||||
|
}
|
||||||
|
|
||||||
// Message Types
|
// Message Types
|
||||||
const (
|
const (
|
||||||
XFRM_MSG_BASE = 0x10
|
XFRM_MSG_BASE XfrmMsgType = 0x10
|
||||||
XFRM_MSG_NEWSA = 0x10
|
XFRM_MSG_NEWSA = 0x10
|
||||||
XFRM_MSG_DELSA = 0x11
|
XFRM_MSG_DELSA = 0x11
|
||||||
XFRM_MSG_GETSA = 0x12
|
XFRM_MSG_GETSA = 0x12
|
||||||
@ -81,6 +87,20 @@ const (
|
|||||||
SizeofXfrmMark = 0x08
|
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 {
|
// typedef union {
|
||||||
// __be32 a4;
|
// __be32 a4;
|
||||||
// __be32 a6[4];
|
// __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)))[:]
|
||||||
|
}
|
62
vendor/github.com/vishvananda/netlink/nl/xfrm_state_linux.go
generated
vendored
62
vendor/github.com/vishvananda/netlink/nl/xfrm_state_linux.go
generated
vendored
@ -8,11 +8,24 @@ const (
|
|||||||
SizeofXfrmUsersaId = 0x18
|
SizeofXfrmUsersaId = 0x18
|
||||||
SizeofXfrmStats = 0x0c
|
SizeofXfrmStats = 0x0c
|
||||||
SizeofXfrmUsersaInfo = 0xe0
|
SizeofXfrmUsersaInfo = 0xe0
|
||||||
|
SizeofXfrmUserSpiInfo = 0xe8
|
||||||
SizeofXfrmAlgo = 0x44
|
SizeofXfrmAlgo = 0x44
|
||||||
SizeofXfrmAlgoAuth = 0x48
|
SizeofXfrmAlgoAuth = 0x48
|
||||||
SizeofXfrmAlgoAEAD = 0x48
|
SizeofXfrmAlgoAEAD = 0x48
|
||||||
SizeofXfrmEncapTmpl = 0x18
|
SizeofXfrmEncapTmpl = 0x18
|
||||||
SizeofXfrmUsersaFlush = 0x8
|
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 {
|
// struct xfrm_usersa_id {
|
||||||
@ -120,6 +133,30 @@ func (msg *XfrmUsersaInfo) Serialize() []byte {
|
|||||||
return (*(*[SizeofXfrmUsersaInfo]byte)(unsafe.Pointer(msg)))[:]
|
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 {
|
// struct xfrm_algo {
|
||||||
// char alg_name[64];
|
// char alg_name[64];
|
||||||
// unsigned int alg_key_len; /* in bits */
|
// unsigned int alg_key_len; /* in bits */
|
||||||
@ -270,3 +307,28 @@ func DeserializeXfrmUsersaFlush(b []byte) *XfrmUsersaFlush {
|
|||||||
func (msg *XfrmUsersaFlush) Serialize() []byte {
|
func (msg *XfrmUsersaFlush) Serialize() []byte {
|
||||||
return (*(*[SizeofXfrmUsersaFlush]byte)(unsafe.Pointer(msg)))[:]
|
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 {
|
func byteToBool(x byte) bool {
|
||||||
if uint8(x) != 0 {
|
return uint8(x) != 0
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
14
vendor/github.com/vishvananda/netlink/protinfo_linux.go
generated
vendored
14
vendor/github.com/vishvananda/netlink/protinfo_linux.go
generated
vendored
@ -40,6 +40,15 @@ func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return pi, err
|
return pi, err
|
||||||
}
|
}
|
||||||
|
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
|
var pi Protinfo
|
||||||
for _, info := range infos {
|
for _, info := range infos {
|
||||||
switch info.Attr.Type {
|
switch info.Attr.Type {
|
||||||
@ -57,8 +66,5 @@ func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) {
|
|||||||
pi.Flood = byteToBool(info.Value[0])
|
pi.Flood = byteToBool(info.Value[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pi, nil
|
return &pi
|
||||||
}
|
|
||||||
}
|
|
||||||
return pi, fmt.Errorf("Device with index %d not found", base.Index)
|
|
||||||
}
|
}
|
||||||
|
3
vendor/github.com/vishvananda/netlink/qdisc.go
generated
vendored
3
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
|
// Tbf is a classless qdisc that rate limits based on tokens
|
||||||
type Tbf struct {
|
type Tbf struct {
|
||||||
QdiscAttrs
|
QdiscAttrs
|
||||||
// TODO: handle 64bit rate properly
|
|
||||||
Rate uint64
|
Rate uint64
|
||||||
Limit uint32
|
Limit uint32
|
||||||
Buffer uint32
|
Buffer uint32
|
||||||
|
Peakrate uint64
|
||||||
|
Minburst uint32
|
||||||
// TODO: handle other settings
|
// 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())
|
options = nl.NewRtAttr(nl.TCA_OPTIONS, tcmap.Serialize())
|
||||||
} else if tbf, ok := qdisc.(*Tbf); ok {
|
} else if tbf, ok := qdisc.(*Tbf); ok {
|
||||||
opt := nl.TcTbfQopt{}
|
opt := nl.TcTbfQopt{}
|
||||||
// TODO: handle rate > uint32
|
|
||||||
opt.Rate.Rate = uint32(tbf.Rate)
|
opt.Rate.Rate = uint32(tbf.Rate)
|
||||||
|
opt.Peakrate.Rate = uint32(tbf.Peakrate)
|
||||||
opt.Limit = tbf.Limit
|
opt.Limit = tbf.Limit
|
||||||
opt.Buffer = tbf.Buffer
|
opt.Buffer = tbf.Buffer
|
||||||
nl.NewRtAttrChild(options, nl.TCA_TBF_PARMS, opt.Serialize())
|
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 {
|
} else if htb, ok := qdisc.(*Htb); ok {
|
||||||
opt := nl.TcHtbGlob{}
|
opt := nl.TcHtbGlob{}
|
||||||
opt.Version = htb.Version
|
opt.Version = htb.Version
|
||||||
@ -418,10 +427,15 @@ func parseTbfData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
|
|||||||
case nl.TCA_TBF_PARMS:
|
case nl.TCA_TBF_PARMS:
|
||||||
opt := nl.DeserializeTcTbfQopt(datum.Value)
|
opt := nl.DeserializeTcTbfQopt(datum.Value)
|
||||||
tbf.Rate = uint64(opt.Rate.Rate)
|
tbf.Rate = uint64(opt.Rate.Rate)
|
||||||
|
tbf.Peakrate = uint64(opt.Peakrate.Rate)
|
||||||
tbf.Limit = opt.Limit
|
tbf.Limit = opt.Limit
|
||||||
tbf.Buffer = opt.Buffer
|
tbf.Buffer = opt.Buffer
|
||||||
case nl.TCA_TBF_RATE64:
|
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
|
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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Scope is an enum representing a route scope.
|
// Scope is an enum representing a route scope.
|
||||||
@ -10,6 +11,20 @@ type Scope uint8
|
|||||||
|
|
||||||
type NextHopFlag int
|
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.
|
// Route represents a netlink route.
|
||||||
type Route struct {
|
type Route struct {
|
||||||
LinkIndex int
|
LinkIndex int
|
||||||
@ -25,15 +40,36 @@ type Route struct {
|
|||||||
Type int
|
Type int
|
||||||
Tos int
|
Tos int
|
||||||
Flags int
|
Flags int
|
||||||
|
MPLSDst *int
|
||||||
|
NewDst Destination
|
||||||
|
Encap Encap
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r Route) String() string {
|
func (r Route) String() string {
|
||||||
if len(r.MultiPath) > 0 {
|
elems := []string{}
|
||||||
return fmt.Sprintf("{Dst: %s Src: %s Gw: %s Flags: %s Table: %d}", r.Dst,
|
if len(r.MultiPath) == 0 {
|
||||||
r.Src, r.MultiPath, r.ListFlags(), r.Table)
|
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,
|
if r.MPLSDst != nil {
|
||||||
r.Src, r.Gw, r.ListFlags(), r.Table)
|
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) {
|
func (r *Route) SetFlag(flag NextHopFlag) {
|
||||||
@ -59,8 +95,22 @@ type NexthopInfo struct {
|
|||||||
LinkIndex int
|
LinkIndex int
|
||||||
Hops int
|
Hops int
|
||||||
Gw net.IP
|
Gw net.IP
|
||||||
|
Flags int
|
||||||
|
NewDst Destination
|
||||||
|
Encap Encap
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NexthopInfo) String() string {
|
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, " "))
|
||||||
}
|
}
|
||||||
|
237
vendor/github.com/vishvananda/netlink/route_linux.go
generated
vendored
237
vendor/github.com/vishvananda/netlink/route_linux.go
generated
vendored
@ -3,6 +3,7 @@ package netlink
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink/nl"
|
"github.com/vishvananda/netlink/nl"
|
||||||
@ -42,16 +43,92 @@ var testFlags = []flagString{
|
|||||||
{f: FLAG_PERVASIVE, s: "pervasive"},
|
{f: FLAG_PERVASIVE, s: "pervasive"},
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Route) ListFlags() []string {
|
func listFlags(flag int) []string {
|
||||||
var flags []string
|
var flags []string
|
||||||
for _, tf := range testFlags {
|
for _, tf := range testFlags {
|
||||||
if r.Flags&int(tf.f) != 0 {
|
if flag&int(tf.f) != 0 {
|
||||||
flags = append(flags, tf.s)
|
flags = append(flags, tf.s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return flags
|
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.
|
// RouteAdd will add a route to the system.
|
||||||
// Equivalent to: `ip route add $route`
|
// Equivalent to: `ip route add $route`
|
||||||
func RouteAdd(route *Route) error {
|
func RouteAdd(route *Route) error {
|
||||||
@ -61,7 +138,22 @@ func RouteAdd(route *Route) error {
|
|||||||
// RouteAdd will add a route to the system.
|
// RouteAdd will add a route to the system.
|
||||||
// Equivalent to: `ip route add $route`
|
// Equivalent to: `ip route add $route`
|
||||||
func (h *Handle) RouteAdd(route *Route) error {
|
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())
|
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 {
|
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")
|
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()
|
dstData = route.Dst.IP.To16()
|
||||||
}
|
}
|
||||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_DST, dstData))
|
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 {
|
if route.Src != nil {
|
||||||
@ -138,26 +257,43 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
|
|||||||
RtNexthop: syscall.RtNexthop{
|
RtNexthop: syscall.RtNexthop{
|
||||||
Hops: uint8(nh.Hops),
|
Hops: uint8(nh.Hops),
|
||||||
Ifindex: int32(nh.LinkIndex),
|
Ifindex: int32(nh.LinkIndex),
|
||||||
Len: uint16(syscall.SizeofRtNexthop),
|
Flags: uint8(nh.Flags),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
var gwData []byte
|
children := []nl.NetlinkRequestData{}
|
||||||
if nh.Gw != nil {
|
if nh.Gw != nil {
|
||||||
gwFamily := nl.GetIPFamily(nh.Gw)
|
gwFamily := nl.GetIPFamily(nh.Gw)
|
||||||
if family != -1 && family != gwFamily {
|
if family != -1 && family != gwFamily {
|
||||||
return fmt.Errorf("gateway, source, and destination ip are not the same IP family")
|
return fmt.Errorf("gateway, source, and destination ip are not the same IP family")
|
||||||
}
|
}
|
||||||
var gw *nl.RtAttr
|
|
||||||
if gwFamily == FAMILY_V4 {
|
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 {
|
} 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, rtnh.Serialize()...)
|
||||||
buf = append(buf, gwData...)
|
|
||||||
}
|
}
|
||||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_MULTIPATH, buf))
|
rtAttrs = append(rtAttrs, nl.NewRtAttr(syscall.RTA_MULTIPATH, buf))
|
||||||
}
|
}
|
||||||
@ -283,7 +419,13 @@ func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64)
|
|||||||
continue
|
continue
|
||||||
case filterMask&RT_FILTER_SRC != 0 && !route.Src.Equal(filter.Src):
|
case filterMask&RT_FILTER_SRC != 0 && !route.Src.Equal(filter.Src):
|
||||||
continue
|
continue
|
||||||
case filterMask&RT_FILTER_DST != 0 && filter.Dst != nil:
|
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 {
|
if route.Dst == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -294,6 +436,8 @@ func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
res = append(res, route)
|
res = append(res, route)
|
||||||
}
|
}
|
||||||
return res, nil
|
return res, nil
|
||||||
@ -316,6 +460,7 @@ func deserializeRoute(m []byte) (Route, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
native := nl.NativeEndian()
|
native := nl.NativeEndian()
|
||||||
|
var encap, encapType syscall.NetlinkRouteAttr
|
||||||
for _, attr := range attrs {
|
for _, attr := range attrs {
|
||||||
switch attr.Attr.Type {
|
switch attr.Attr.Type {
|
||||||
case syscall.RTA_GATEWAY:
|
case syscall.RTA_GATEWAY:
|
||||||
@ -323,10 +468,18 @@ func deserializeRoute(m []byte) (Route, error) {
|
|||||||
case syscall.RTA_PREFSRC:
|
case syscall.RTA_PREFSRC:
|
||||||
route.Src = net.IP(attr.Value)
|
route.Src = net.IP(attr.Value)
|
||||||
case syscall.RTA_DST:
|
case syscall.RTA_DST:
|
||||||
|
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{
|
route.Dst = &net.IPNet{
|
||||||
IP: attr.Value,
|
IP: attr.Value,
|
||||||
Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attr.Value)),
|
Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attr.Value)),
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case syscall.RTA_OIF:
|
case syscall.RTA_OIF:
|
||||||
route.LinkIndex = int(native.Uint32(attr.Value[0:4]))
|
route.LinkIndex = int(native.Uint32(attr.Value[0:4]))
|
||||||
case syscall.RTA_IIF:
|
case syscall.RTA_IIF:
|
||||||
@ -347,17 +500,47 @@ func deserializeRoute(m []byte) (Route, error) {
|
|||||||
info := &NexthopInfo{
|
info := &NexthopInfo{
|
||||||
LinkIndex: int(nh.RtNexthop.Ifindex),
|
LinkIndex: int(nh.RtNexthop.Ifindex),
|
||||||
Hops: int(nh.RtNexthop.Hops),
|
Hops: int(nh.RtNexthop.Hops),
|
||||||
|
Flags: int(nh.RtNexthop.Flags),
|
||||||
}
|
}
|
||||||
attrs, err := nl.ParseRouteAttr(value[syscall.SizeofRtNexthop:int(nh.RtNexthop.Len)])
|
attrs, err := nl.ParseRouteAttr(value[syscall.SizeofRtNexthop:int(nh.RtNexthop.Len)])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
var encap, encapType syscall.NetlinkRouteAttr
|
||||||
for _, attr := range attrs {
|
for _, attr := range attrs {
|
||||||
switch attr.Attr.Type {
|
switch attr.Attr.Type {
|
||||||
case syscall.RTA_GATEWAY:
|
case syscall.RTA_GATEWAY:
|
||||||
info.Gw = net.IP(attr.Value)
|
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
|
return info, value[int(nh.RtNexthop.Len):], nil
|
||||||
}
|
}
|
||||||
rest := attr.Value
|
rest := attr.Value
|
||||||
@ -369,8 +552,36 @@ func deserializeRoute(m []byte) (Route, error) {
|
|||||||
route.MultiPath = append(route.MultiPath, info)
|
route.MultiPath = append(route.MultiPath, info)
|
||||||
rest = buf
|
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
|
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 {
|
func (r *Route) ListFlags() []string {
|
||||||
return []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
|
Crypt *XfrmStateAlgo
|
||||||
Aead *XfrmStateAlgo
|
Aead *XfrmStateAlgo
|
||||||
Encap *XfrmStateEncap
|
Encap *XfrmStateEncap
|
||||||
|
ESN bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sa XfrmState) String() string {
|
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",
|
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.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 {
|
func (sa XfrmState) Print(stats bool) string {
|
||||||
if !stats {
|
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()
|
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.
|
// XfrmStateAdd will add an xfrm state to the system.
|
||||||
// Equivalent to: `ip xfrm state add $state`
|
// Equivalent to: `ip xfrm state add $state`
|
||||||
func XfrmStateAdd(state *XfrmState) error {
|
func XfrmStateAdd(state *XfrmState) error {
|
||||||
@ -72,6 +87,12 @@ func (h *Handle) XfrmStateAdd(state *XfrmState) error {
|
|||||||
return h.xfrmStateAddOrUpdate(state, nl.XFRM_MSG_NEWSA)
|
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.
|
// XfrmStateUpdate will update an xfrm state to the system.
|
||||||
// Equivalent to: `ip xfrm state update $state`
|
// Equivalent to: `ip xfrm state update $state`
|
||||||
func XfrmStateUpdate(state *XfrmState) error {
|
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 {
|
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
|
// A state with spi 0 can't be deleted so don't allow it to be set
|
||||||
if state.Spi == 0 {
|
if state.Spi == 0 {
|
||||||
return fmt.Errorf("Spi must be set when adding xfrm state.")
|
return fmt.Errorf("Spi must be set when adding xfrm state.")
|
||||||
}
|
}
|
||||||
req := h.newNetlinkRequest(nlProto, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
req := h.newNetlinkRequest(nlProto, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
||||||
|
|
||||||
msg := &nl.XfrmUsersaInfo{}
|
msg := xfrmUsersaInfoFromXfrmState(state)
|
||||||
msg.Family = uint16(nl.GetIPFamily(state.Dst))
|
|
||||||
msg.Id.Daddr.FromIP(state.Dst)
|
if state.ESN {
|
||||||
msg.Saddr.FromIP(state.Src)
|
if state.ReplayWindow == 0 {
|
||||||
msg.Id.Proto = uint8(state.Proto)
|
return fmt.Errorf("ESN flag set without ReplayWindow")
|
||||||
msg.Mode = uint8(state.Mode)
|
}
|
||||||
msg.Id.Spi = nl.Swap32(uint32(state.Spi))
|
msg.Flags |= nl.XFRM_STATE_ESN
|
||||||
msg.Reqid = uint32(state.Reqid)
|
msg.ReplayWindow = 0
|
||||||
msg.ReplayWindow = uint8(state.ReplayWindow)
|
}
|
||||||
|
|
||||||
limitsToLft(state.Limits, &msg.Lft)
|
limitsToLft(state.Limits, &msg.Lft)
|
||||||
req.AddData(msg)
|
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))
|
out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(state.Mark))
|
||||||
req.AddData(out)
|
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)
|
_, err := req.Execute(syscall.NETLINK_XFRM, 0)
|
||||||
return err
|
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
|
// XfrmStateDel will delete an xfrm state from the system. Note that
|
||||||
// the Algos are ignored when matching the state to delete.
|
// the Algos are ignored when matching the state to delete.
|
||||||
// Equivalent to: `ip xfrm state del $state`
|
// 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")
|
var familyError = fmt.Errorf("family error")
|
||||||
|
|
||||||
func parseXfrmState(m []byte, family int) (*XfrmState, error) {
|
func xfrmStateFromXfrmUsersaInfo(msg *nl.XfrmUsersaInfo) *XfrmState {
|
||||||
msg := nl.DeserializeXfrmUsersaInfo(m)
|
|
||||||
|
|
||||||
// This is mainly for the state dump
|
|
||||||
if family != FAMILY_ALL && family != int(msg.Family) {
|
|
||||||
return nil, familyError
|
|
||||||
}
|
|
||||||
|
|
||||||
var state XfrmState
|
var state XfrmState
|
||||||
|
|
||||||
state.Dst = msg.Id.Daddr.ToIP()
|
state.Dst = msg.Id.Daddr.ToIP()
|
||||||
@ -260,6 +309,19 @@ func parseXfrmState(m []byte, family int) (*XfrmState, error) {
|
|||||||
state.ReplayWindow = int(msg.ReplayWindow)
|
state.ReplayWindow = int(msg.ReplayWindow)
|
||||||
lftToLimits(&msg.Lft, &state.Limits)
|
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:])
|
attrs, err := nl.ParseRouteAttr(m[nl.SizeofXfrmUsersaInfo:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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.
|
// 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) {
|
func lftToLimits(lft *nl.XfrmLifetimeCfg, lmts *XfrmStateLimits) {
|
||||||
*lmts = *(*XfrmStateLimits)(unsafe.Pointer(lft))
|
*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