mirror of
https://github.com/openfaas/faasd.git
synced 2025-06-08 16:06:47 +00:00
Refactor faasd and faas-containerd merge
The use of containerd and CNI functions has been refactored to reuse the same codebase. Added all network functionality to own directory and package. Removed netlink and weave library in favor of using CNI plugin result files. Rename containers handler to functions to clear-up functionality. Signed-off-by: Carlos de Paula <me@carlosedp.com>
This commit is contained in:
parent
eb369fbb16
commit
d49011702b
15
Gopkg.lock
generated
15
Gopkg.lock
generated
@ -227,14 +227,6 @@
|
||||
revision = "6c65a5562fc06764971b7c5d05c76c75e84bdbf7"
|
||||
version = "v1.3.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:582b704bebaa06b48c29b0cec224a6058a09c86883aaddabde889cd1a5f73e1b"
|
||||
name = "github.com/google/uuid"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "0cd6bf5da1e1c83f8b45653022c74f71af0538a4"
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:cbec35fe4d5a4fba369a656a8cd65e244ea2c743007d8f6c1ccb132acf9d1296"
|
||||
name = "github.com/gorilla/mux"
|
||||
@ -375,15 +367,15 @@
|
||||
revision = "d98352740cb2c55f81556b63d4a1ec64c5a319c2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:2d9d06cb9d46dacfdbb45f8575b39fc0126d083841a29d4fbf8d97708f43107e"
|
||||
digest = "1:1314b5ef1c0b25257ea02e454291bf042478a48407cfe3ffea7e20323bbf5fdf"
|
||||
name = "github.com/vishvananda/netlink"
|
||||
packages = [
|
||||
".",
|
||||
"nl",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "a2ad57a690f3caf3015351d2d6e1c0b95c349752"
|
||||
version = "v1.0.0"
|
||||
revision = "f049be6f391489d3f374498fe0c8df8449258372"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
@ -534,7 +526,6 @@
|
||||
"github.com/containerd/containerd/namespaces",
|
||||
"github.com/containerd/containerd/oci",
|
||||
"github.com/containerd/go-cni",
|
||||
"github.com/google/uuid",
|
||||
"github.com/gorilla/mux",
|
||||
"github.com/morikuni/aec",
|
||||
"github.com/opencontainers/runtime-spec/specs-go",
|
||||
|
@ -41,7 +41,3 @@
|
||||
[[constraint]]
|
||||
name = "github.com/openfaas/faas-provider"
|
||||
version = "0.14.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/google/uuid"
|
||||
version = "1.1.1"
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/alexellis/faasd/pkg/cninetwork"
|
||||
"github.com/alexellis/faasd/pkg/provider/config"
|
||||
"github.com/alexellis/faasd/pkg/provider/handlers"
|
||||
"github.com/containerd/containerd"
|
||||
@ -52,7 +53,7 @@ func runProvider(_ *cobra.Command, _ []string) error {
|
||||
return fmt.Errorf("cannot write resolv.conf file: %s", writeResolvErr)
|
||||
}
|
||||
|
||||
cni, err := handlers.InitNetwork()
|
||||
cni, err := cninetwork.InitNetwork()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
84
cmd/up.go
84
cmd/up.go
@ -2,7 +2,6 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
@ -27,32 +26,6 @@ var upCmd = &cobra.Command{
|
||||
RunE: runUp,
|
||||
}
|
||||
|
||||
// defaultCNIConf is a CNI configuration that enables network access to containers (docker-bridge style)
|
||||
var defaultCNIConf = fmt.Sprintf(`
|
||||
{
|
||||
"cniVersion": "0.4.0",
|
||||
"name": "%s",
|
||||
"plugins": [
|
||||
{
|
||||
"type": "bridge",
|
||||
"bridge": "%s",
|
||||
"isGateway": true,
|
||||
"ipMasq": true,
|
||||
"ipam": {
|
||||
"type": "host-local",
|
||||
"subnet": "%s",
|
||||
"routes": [
|
||||
{ "dst": "0.0.0.0/0" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "firewall"
|
||||
}
|
||||
]
|
||||
}
|
||||
`, pkg.DefaultNetworkName, pkg.DefaultBridgeName, pkg.DefaultSubnet)
|
||||
|
||||
const containerSecretMountDir = "/run/secrets"
|
||||
|
||||
func runUp(_ *cobra.Command, _ []string) error {
|
||||
@ -80,10 +53,6 @@ func runUp(_ *cobra.Command, _ []string) error {
|
||||
return errors.Wrap(basicAuthErr, "cannot create basic-auth-* files")
|
||||
}
|
||||
|
||||
if makeNetworkErr := makeNetworkConfig(); makeNetworkErr != nil {
|
||||
return errors.Wrap(makeNetworkErr, "error creating network config")
|
||||
}
|
||||
|
||||
services := makeServiceDefinitions(clientSuffix)
|
||||
|
||||
start := time.Now()
|
||||
@ -301,56 +270,3 @@ func makeServiceDefinitions(archSuffix string) []pkg.Service {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func makeNetworkConfig() error {
|
||||
netConfig := path.Join(pkg.CNIConfDir, pkg.DefaultCNIConfFilename)
|
||||
log.Printf("Writing network config...\n")
|
||||
|
||||
if !dirExists(pkg.CNIConfDir) {
|
||||
if err := os.MkdirAll(pkg.CNIConfDir, 0755); err != nil {
|
||||
return fmt.Errorf("cannot create directory: %s", pkg.CNIConfDir)
|
||||
}
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(netConfig, []byte(defaultCNIConf), 644); err != nil {
|
||||
return fmt.Errorf("cannot write network config: %s", pkg.DefaultCNIConfFilename)
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func dirEmpty(dirname string) (b bool) {
|
||||
if !dirExists(dirname) {
|
||||
return
|
||||
}
|
||||
|
||||
f, err := os.Open(dirname)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer func() { _ = f.Close() }()
|
||||
|
||||
// If the first file is EOF, the directory is empty
|
||||
if _, err = f.Readdir(1); err == io.EOF {
|
||||
b = true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func dirExists(dirname string) bool {
|
||||
exists, info := pathExists(dirname)
|
||||
if !exists {
|
||||
return false
|
||||
}
|
||||
|
||||
return info.IsDir()
|
||||
}
|
||||
|
||||
func pathExists(path string) (bool, os.FileInfo) {
|
||||
info, err := os.Stat(path)
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, info
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package handlers
|
||||
package cninetwork
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -23,7 +23,8 @@ const (
|
||||
CNIConfDir = "/etc/cni/net.d"
|
||||
// NetNSPathFmt gives the path to the a process network namespace, given the pid
|
||||
NetNSPathFmt = "/proc/%d/ns/net"
|
||||
|
||||
// CNIResultsDir is the directory CNI stores allocated IP for containers
|
||||
CNIResultsDir = "/var/lib/cni/results"
|
||||
// defaultCNIConfFilename is the vanity filename of default CNI configuration file
|
||||
defaultCNIConfFilename = "10-openfaas.conflist"
|
||||
// defaultNetworkName names the "docker-bridge"-like CNI plugin-chain installed when no other CNI configuration is present.
|
||||
@ -94,8 +95,8 @@ func InitNetwork() (gocni.CNI, error) {
|
||||
|
||||
// CreateCNINetwork creates a CNI network interface and attaches it to the context
|
||||
func CreateCNINetwork(ctx context.Context, cni gocni.CNI, task containerd.Task, labels map[string]string) (*gocni.CNIResult, error) {
|
||||
id := NetID(task)
|
||||
netns := NetNamespace(task)
|
||||
id := netID(task)
|
||||
netns := netNamespace(task)
|
||||
result, err := cni.Setup(ctx, id, netns, gocni.WithLabels(labels))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Failed to setup network for task %q: %v", id, err)
|
||||
@ -116,8 +117,8 @@ func DeleteCNINetwork(ctx context.Context, cni gocni.CNI, client *containerd.Cli
|
||||
|
||||
log.Printf("[Delete] removing CNI network for: %s\n", task.ID())
|
||||
|
||||
id := NetID(task)
|
||||
netns := NetNamespace(task)
|
||||
id := netID(task)
|
||||
netns := netNamespace(task)
|
||||
|
||||
if err := cni.Remove(ctx, id, netns); err != nil {
|
||||
return errors.Wrapf(err, "Failed to remove network for task: %q, %v", id, err)
|
||||
@ -135,7 +136,7 @@ func GetIPAddress(result *gocni.CNIResult, task containerd.Task) (net.IP, error)
|
||||
// Get the IP of the created interface
|
||||
var ip net.IP
|
||||
for ifName, config := range result.Interfaces {
|
||||
if config.Sandbox == NetNamespace(task) {
|
||||
if config.Sandbox == netNamespace(task) {
|
||||
for _, ipConfig := range config.IPConfigs {
|
||||
if ifName != "lo" && ipConfig.IP.To4() != nil {
|
||||
ip = ipConfig.IP
|
||||
@ -169,13 +170,24 @@ func GetIPfromPID(pid int) (*net.IP, error) {
|
||||
return nil, fmt.Errorf("no IP found for function")
|
||||
}
|
||||
|
||||
// NetID generates the network IF based on task name and task PID
|
||||
func NetID(task containerd.Task) string {
|
||||
// CNIGateway returns the gateway for default subnet
|
||||
func CNIGateway() (string, error) {
|
||||
ip, _, err := net.ParseCIDR(defaultSubnet)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error formatting gateway for network %s", defaultSubnet)
|
||||
}
|
||||
ip = ip.To4()
|
||||
ip[3] = 1
|
||||
return ip.String(), nil
|
||||
}
|
||||
|
||||
// netID generates the network IF based on task name and task PID
|
||||
func netID(task containerd.Task) string {
|
||||
return fmt.Sprintf("%s-%d", task.ID(), task.Pid())
|
||||
}
|
||||
|
||||
// NetNamespace generates the namespace path based on task PID.
|
||||
func NetNamespace(task containerd.Task) string {
|
||||
// netNamespace generates the namespace path based on task PID.
|
||||
func netNamespace(task containerd.Task) string {
|
||||
return fmt.Sprintf(NetNSPathFmt, task.Pid())
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
// Copyright Weaveworks
|
||||
// github.com/weaveworks/weave/net
|
||||
|
||||
package handlers
|
||||
package cninetwork
|
||||
|
||||
import (
|
||||
"errors"
|
@ -1,7 +1,7 @@
|
||||
// Copyright Weaveworks
|
||||
// github.com/weaveworks/weave/net
|
||||
|
||||
package weave
|
||||
package cninetwork
|
||||
|
||||
import (
|
||||
"fmt"
|
@ -8,6 +8,7 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
cninetwork "github.com/alexellis/faasd/pkg/cninetwork"
|
||||
"github.com/alexellis/faasd/pkg/service"
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
@ -52,7 +53,7 @@ func MakeDeleteHandler(client *containerd.Client, cni gocni.CNI) func(w http.Res
|
||||
|
||||
// TODO: this needs to still happen if the task is paused
|
||||
if function.replicas != 0 {
|
||||
err = DeleteCNINetwork(ctx, cni, client, name)
|
||||
err = cninetwork.DeleteCNINetwork(ctx, cni, client, name)
|
||||
if err != nil {
|
||||
log.Printf("[Delete] error removing CNI network for %s, %s\n", name, err)
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
cninetwork "github.com/alexellis/faasd/pkg/cninetwork"
|
||||
"github.com/alexellis/faasd/pkg/service"
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/cio"
|
||||
@ -101,7 +102,7 @@ func deploy(ctx context.Context, req types.FunctionDeployment, client *container
|
||||
name,
|
||||
containerd.WithImage(image),
|
||||
containerd.WithSnapshotter(snapshotter),
|
||||
containerd.WithNewSnapshot(req.Service+"-snapshot", image),
|
||||
containerd.WithNewSnapshot(name+"-snapshot", image),
|
||||
containerd.WithNewSpec(oci.WithImageConfig(image),
|
||||
oci.WithCapabilities([]string{"CAP_NET_RAW"}),
|
||||
oci.WithMounts(mounts),
|
||||
@ -127,13 +128,13 @@ func createTask(ctx context.Context, client *containerd.Client, container contai
|
||||
log.Printf("Container ID: %s\tTask ID %s:\tTask PID: %d\t\n", name, task.ID(), task.Pid())
|
||||
|
||||
labels := map[string]string{}
|
||||
network, err := CreateCNINetwork(ctx, cni, task, labels)
|
||||
network, err := cninetwork.CreateCNINetwork(ctx, cni, task, labels)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ip, err := GetIPAddress(network, task)
|
||||
ip, err := cninetwork.GetIPAddress(network, task)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/alexellis/faasd/pkg/cninetwork"
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
)
|
||||
@ -62,11 +63,10 @@ func GetFunction(client *containerd.Client, name string) (Function, error) {
|
||||
f.pid = task.Pid()
|
||||
|
||||
// Get container IP address
|
||||
ip, getIPErr := GetIPfromPID(int(task.Pid()))
|
||||
if getIPErr != nil {
|
||||
return Function{}, getIPErr
|
||||
ip, err := cninetwork.GetIPfromPID(int(task.Pid()))
|
||||
if err != nil {
|
||||
return Function{}, err
|
||||
}
|
||||
|
||||
f.IP = ip.String()
|
||||
}
|
||||
} else {
|
@ -8,6 +8,7 @@ import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/alexellis/faasd/pkg/cninetwork"
|
||||
"github.com/alexellis/faasd/pkg/service"
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
@ -54,7 +55,7 @@ func MakeUpdateHandler(client *containerd.Client, cni gocni.CNI, secretMountPath
|
||||
|
||||
ctx := namespaces.WithNamespace(context.Background(), FunctionNamespace)
|
||||
if function.replicas != 0 {
|
||||
err = DeleteCNINetwork(ctx, cni, client, name)
|
||||
err = cninetwork.DeleteCNINetwork(ctx, cni, client, name)
|
||||
if err != nil {
|
||||
log.Printf("[Update] error removing CNI network for %s, %s\n", name, err)
|
||||
}
|
||||
|
@ -1,131 +0,0 @@
|
||||
// Copyright Weaveworks
|
||||
// github.com/weaveworks/weave/net
|
||||
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/vishvananda/netlink"
|
||||
"github.com/vishvananda/netns"
|
||||
)
|
||||
|
||||
type Dev struct {
|
||||
Name string `json:"Name,omitempty"`
|
||||
MAC net.HardwareAddr `json:"MAC,omitempty"`
|
||||
CIDRs []*net.IPNet `json:"CIDRs,omitempty"`
|
||||
}
|
||||
|
||||
func linkToNetDev(link netlink.Link) (Dev, error) {
|
||||
addrs, err := netlink.AddrList(link, netlink.FAMILY_V4)
|
||||
if err != nil {
|
||||
return Dev{}, err
|
||||
}
|
||||
|
||||
netDev := Dev{Name: link.Attrs().Name, MAC: link.Attrs().HardwareAddr}
|
||||
for _, addr := range addrs {
|
||||
netDev.CIDRs = append(netDev.CIDRs, addr.IPNet)
|
||||
}
|
||||
return netDev, nil
|
||||
}
|
||||
|
||||
// ConnectedToBridgeVethPeerIds returns peer indexes of veth links connected to
|
||||
// the given bridge. The peer index is used to query from a container netns
|
||||
// whether the container is connected to the bridge.
|
||||
func ConnectedToBridgeVethPeerIds(bridgeName string) ([]int, error) {
|
||||
var ids []int
|
||||
|
||||
br, err := netlink.LinkByName(bridgeName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
links, err := netlink.LinkList()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, link := range links {
|
||||
if _, isveth := link.(*netlink.Veth); isveth && link.Attrs().MasterIndex == br.Attrs().Index {
|
||||
peerID := link.Attrs().ParentIndex
|
||||
if peerID == 0 {
|
||||
// perhaps running on an older kernel where ParentIndex doesn't work.
|
||||
// as fall-back, assume the peers are consecutive
|
||||
peerID = link.Attrs().Index - 1
|
||||
}
|
||||
ids = append(ids, peerID)
|
||||
}
|
||||
}
|
||||
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
// Lookup the weave interface of a container
|
||||
func GetWeaveNetDevs(processID int) ([]Dev, error) {
|
||||
peerIDs, err := ConnectedToBridgeVethPeerIds("weave")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return GetNetDevsByVethPeerIds(processID, peerIDs)
|
||||
}
|
||||
|
||||
func GetNetDevsByVethPeerIds(processID int, peerIDs []int) ([]Dev, error) {
|
||||
// Bail out if this container is running in the root namespace
|
||||
netnsRoot, err := netns.GetFromPid(1)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to open root namespace: %s", err)
|
||||
}
|
||||
defer netnsRoot.Close()
|
||||
netnsContainer, err := netns.GetFromPid(processID)
|
||||
if err != nil {
|
||||
// Unable to find a namespace for this process - just return nothing
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, fmt.Errorf("unable to open process %d namespace: %s", processID, err)
|
||||
}
|
||||
defer netnsContainer.Close()
|
||||
if netnsRoot.Equal(netnsContainer) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// convert list of peerIDs into a map for faster lookup
|
||||
indexes := make(map[int]struct{})
|
||||
for _, id := range peerIDs {
|
||||
indexes[id] = struct{}{}
|
||||
}
|
||||
|
||||
var netdevs []Dev
|
||||
err = WithNetNS(netnsContainer, func() error {
|
||||
links, err := netlink.LinkList()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, link := range links {
|
||||
if _, found := indexes[link.Attrs().Index]; found {
|
||||
netdev, err := linkToNetDev(link)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
netdevs = append(netdevs, netdev)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return netdevs, err
|
||||
}
|
||||
|
||||
// Get the weave bridge interface.
|
||||
// NB: Should be called from the root network namespace.
|
||||
func GetBridgeNetDev(bridgeName string) (Dev, error) {
|
||||
link, err := netlink.LinkByName(bridgeName)
|
||||
if err != nil {
|
||||
return Dev{}, err
|
||||
}
|
||||
|
||||
return linkToNetDev(link)
|
||||
}
|
@ -5,49 +5,31 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/alexellis/faasd/pkg/cninetwork"
|
||||
"github.com/alexellis/faasd/pkg/service"
|
||||
"github.com/alexellis/faasd/pkg/weave"
|
||||
"github.com/containerd/containerd"
|
||||
"github.com/containerd/containerd/cio"
|
||||
"github.com/containerd/containerd/containers"
|
||||
"github.com/containerd/containerd/oci"
|
||||
gocni "github.com/containerd/go-cni"
|
||||
"github.com/google/uuid"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/containerd/containerd/namespaces"
|
||||
"github.com/containerd/containerd/oci"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
const workingDirectoryPermission = 0644
|
||||
|
||||
const defaultSnapshotter = "overlayfs"
|
||||
|
||||
const (
|
||||
// CNIBinDir describes the directory where the CNI binaries are stored
|
||||
CNIBinDir = "/opt/cni/bin"
|
||||
// CNIConfDir describes the directory where the CNI plugin's configuration is stored
|
||||
CNIConfDir = "/etc/cni/net.d"
|
||||
// netNSPathFmt gives the path to the a process network namespace, given the pid
|
||||
NetNSPathFmt = "/proc/%d/ns/net"
|
||||
// defaultCNIConfFilename is the vanity filename of default CNI configuration file
|
||||
DefaultCNIConfFilename = "10-openfaas.conflist"
|
||||
// defaultNetworkName names the "docker-bridge"-like CNI plugin-chain installed when no other CNI configuration is present.
|
||||
// This value appears in iptables comments created by CNI.
|
||||
DefaultNetworkName = "openfaas-cni-bridge"
|
||||
// defaultBridgeName is the default bridge device name used in the defaultCNIConf
|
||||
DefaultBridgeName = "openfaas0"
|
||||
// defaultSubnet is the default subnet used in the defaultCNIConf -- this value is set to not collide with common container networking subnets:
|
||||
DefaultSubnet = "10.62.0.0/16"
|
||||
defaultSnapshotter = "overlayfs"
|
||||
workingDirectoryPermission = 0644
|
||||
// faasdNamespace is the containerd namespace services are created
|
||||
faasdNamespace = "default"
|
||||
)
|
||||
|
||||
type Supervisor struct {
|
||||
client *containerd.Client
|
||||
cni gocni.CNI
|
||||
}
|
||||
|
||||
func NewSupervisor(sock string) (*Supervisor, error) {
|
||||
@ -56,8 +38,14 @@ func NewSupervisor(sock string) (*Supervisor, error) {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
cni, err := cninetwork.InitNetwork()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return &Supervisor{
|
||||
client: client,
|
||||
cni: cni,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -66,10 +54,16 @@ func (s *Supervisor) Close() {
|
||||
}
|
||||
|
||||
func (s *Supervisor) Remove(svcs []Service) error {
|
||||
ctx := namespaces.WithNamespace(context.Background(), "default")
|
||||
ctx := namespaces.WithNamespace(context.Background(), faasdNamespace)
|
||||
|
||||
for _, svc := range svcs {
|
||||
err := service.Remove(ctx, s.client, svc.Name)
|
||||
err := cninetwork.DeleteCNINetwork(ctx, s.cni, s.client, svc.Name)
|
||||
if err != nil {
|
||||
log.Printf("[Delete] error removing CNI network for %s, %s\n", svc.Name, err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = service.Remove(ctx, s.client, svc.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -78,17 +72,17 @@ func (s *Supervisor) Remove(svcs []Service) error {
|
||||
}
|
||||
|
||||
func (s *Supervisor) Start(svcs []Service) error {
|
||||
ctx := namespaces.WithNamespace(context.Background(), "default")
|
||||
ctx := namespaces.WithNamespace(context.Background(), faasdNamespace)
|
||||
|
||||
wd, _ := os.Getwd()
|
||||
|
||||
ip, _, _ := net.ParseCIDR(DefaultSubnet)
|
||||
ip = ip.To4()
|
||||
ip[3] = 1
|
||||
ip.String()
|
||||
gw, err := cninetwork.CNIGateway()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hosts := fmt.Sprintf(`
|
||||
127.0.0.1 localhost
|
||||
%s faas-containerd`, ip)
|
||||
%s faas-containerd`, gw)
|
||||
|
||||
writeHostsErr := ioutil.WriteFile(path.Join(wd, "hosts"),
|
||||
[]byte(hosts), workingDirectoryPermission)
|
||||
@ -174,33 +168,18 @@ func (s *Supervisor) Start(svcs []Service) error {
|
||||
return err
|
||||
}
|
||||
|
||||
id := uuid.New().String()
|
||||
netns := fmt.Sprintf(NetNSPathFmt, task.Pid())
|
||||
|
||||
cni, err := gocni.New(gocni.WithPluginConfDir(CNIConfDir),
|
||||
gocni.WithPluginDir([]string{CNIBinDir}))
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error creating CNI instance")
|
||||
}
|
||||
|
||||
// Load the cni configuration
|
||||
if err := cni.Load(gocni.WithLoNetwork, gocni.WithConfListFile(filepath.Join(CNIConfDir, DefaultCNIConfFilename))); err != nil {
|
||||
return errors.Wrapf(err, "failed to load cni configuration: %v", err)
|
||||
}
|
||||
|
||||
labels := map[string]string{}
|
||||
network, err := cninetwork.CreateCNINetwork(ctx, s.cni, task, labels)
|
||||
|
||||
_, err = cni.Setup(ctx, id, netns, gocni.WithLabels(labels))
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to setup network for namespace %q: %v", id, err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Get the IP of the default interface.
|
||||
// defaultInterface := gocni.DefaultPrefix + "0"
|
||||
// ip := &result.Interfaces[defaultInterface].IPConfigs[0].IP
|
||||
ip := getIP(newContainer.ID(), task.Pid())
|
||||
log.Printf("%s has IP: %s\n", newContainer.ID(), ip)
|
||||
ip, err := cninetwork.GetIPAddress(network, task)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("%s has IP: %s\n", newContainer.ID(), ip.String())
|
||||
|
||||
hosts, _ := ioutil.ReadFile("hosts")
|
||||
|
||||
@ -232,23 +211,14 @@ func (s *Supervisor) Start(svcs []Service) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getIP(containerID string, taskPID uint32) string {
|
||||
// https://github.com/weaveworks/weave/blob/master/net/netdev.go
|
||||
|
||||
peerIDs, err := weave.ConnectedToBridgeVethPeerIds(DefaultBridgeName)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
func withOCIArgs(args []string) oci.SpecOpts {
|
||||
if len(args) > 0 {
|
||||
return oci.WithProcessArgs(args...)
|
||||
}
|
||||
|
||||
addrs, addrsErr := weave.GetNetDevsByVethPeerIds(int(taskPID), peerIDs)
|
||||
if addrsErr != nil {
|
||||
log.Fatal(addrsErr)
|
||||
return func(_ context.Context, _ oci.Client, _ *containers.Container, s *oci.Spec) error {
|
||||
return nil
|
||||
}
|
||||
if len(addrs) > 0 {
|
||||
return addrs[0].CIDRs[0].IP.String()
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
@ -264,15 +234,3 @@ type Mount struct {
|
||||
Src string
|
||||
Dest string
|
||||
}
|
||||
|
||||
func withOCIArgs(args []string) oci.SpecOpts {
|
||||
if len(args) > 0 {
|
||||
return oci.WithProcessArgs(args...)
|
||||
}
|
||||
|
||||
return func(_ context.Context, _ oci.Client, _ *containers.Container, s *oci.Spec) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,66 +0,0 @@
|
||||
// +build go1.10
|
||||
|
||||
// Copyright Weaveworks
|
||||
// github.com/weaveworks/weave/net
|
||||
|
||||
package weave
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"github.com/vishvananda/netlink"
|
||||
"github.com/vishvananda/netns"
|
||||
)
|
||||
|
||||
var ErrLinkNotFound = errors.New("Link not found")
|
||||
|
||||
func WithNetNS(ns netns.NsHandle, work func() error) error {
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
oldNs, err := netns.Get()
|
||||
if err == nil {
|
||||
defer oldNs.Close()
|
||||
|
||||
err = netns.Set(ns)
|
||||
if err == nil {
|
||||
defer netns.Set(oldNs)
|
||||
|
||||
err = work()
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func WithNetNSLink(ns netns.NsHandle, ifName string, work func(link netlink.Link) error) error {
|
||||
return WithNetNS(ns, func() error {
|
||||
link, err := netlink.LinkByName(ifName)
|
||||
if err != nil {
|
||||
if err.Error() == errors.New("Link not found").Error() {
|
||||
return ErrLinkNotFound
|
||||
}
|
||||
return err
|
||||
}
|
||||
return work(link)
|
||||
})
|
||||
}
|
||||
|
||||
func WithNetNSByPath(path string, work func() error) error {
|
||||
ns, err := netns.GetFromPath(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return WithNetNS(ns, work)
|
||||
}
|
||||
|
||||
func NSPathByPid(pid int) string {
|
||||
return NSPathByPidWithRoot("/", pid)
|
||||
}
|
||||
|
||||
func NSPathByPidWithRoot(root string, pid int) string {
|
||||
return filepath.Join(root, fmt.Sprintf("/proc/%d/ns/net", pid))
|
||||
}
|
9
vendor/github.com/google/uuid/.travis.yml
generated
vendored
9
vendor/github.com/google/uuid/.travis.yml
generated
vendored
@ -1,9 +0,0 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.4.3
|
||||
- 1.5.3
|
||||
- tip
|
||||
|
||||
script:
|
||||
- go test -v ./...
|
10
vendor/github.com/google/uuid/CONTRIBUTING.md
generated
vendored
10
vendor/github.com/google/uuid/CONTRIBUTING.md
generated
vendored
@ -1,10 +0,0 @@
|
||||
# How to contribute
|
||||
|
||||
We definitely welcome patches and contribution to this project!
|
||||
|
||||
### Legal requirements
|
||||
|
||||
In order to protect both you and ourselves, you will need to sign the
|
||||
[Contributor License Agreement](https://cla.developers.google.com/clas).
|
||||
|
||||
You may have already signed it for other Google projects.
|
9
vendor/github.com/google/uuid/CONTRIBUTORS
generated
vendored
9
vendor/github.com/google/uuid/CONTRIBUTORS
generated
vendored
@ -1,9 +0,0 @@
|
||||
Paul Borman <borman@google.com>
|
||||
bmatsuo
|
||||
shawnps
|
||||
theory
|
||||
jboverfelt
|
||||
dsymonds
|
||||
cd1
|
||||
wallclockbuilder
|
||||
dansouza
|
27
vendor/github.com/google/uuid/LICENSE
generated
vendored
27
vendor/github.com/google/uuid/LICENSE
generated
vendored
@ -1,27 +0,0 @@
|
||||
Copyright (c) 2009,2014 Google Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
19
vendor/github.com/google/uuid/README.md
generated
vendored
19
vendor/github.com/google/uuid/README.md
generated
vendored
@ -1,19 +0,0 @@
|
||||
# uuid 
|
||||
The uuid package generates and inspects UUIDs based on
|
||||
[RFC 4122](http://tools.ietf.org/html/rfc4122)
|
||||
and DCE 1.1: Authentication and Security Services.
|
||||
|
||||
This package is based on the github.com/pborman/uuid package (previously named
|
||||
code.google.com/p/go-uuid). It differs from these earlier packages in that
|
||||
a UUID is a 16 byte array rather than a byte slice. One loss due to this
|
||||
change is the ability to represent an invalid UUID (vs a NIL UUID).
|
||||
|
||||
###### Install
|
||||
`go get github.com/google/uuid`
|
||||
|
||||
###### Documentation
|
||||
[](http://godoc.org/github.com/google/uuid)
|
||||
|
||||
Full `go doc` style documentation for the package can be viewed online without
|
||||
installing this package by using the GoDoc site here:
|
||||
http://godoc.org/github.com/google/uuid
|
80
vendor/github.com/google/uuid/dce.go
generated
vendored
80
vendor/github.com/google/uuid/dce.go
generated
vendored
@ -1,80 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
// A Domain represents a Version 2 domain
|
||||
type Domain byte
|
||||
|
||||
// Domain constants for DCE Security (Version 2) UUIDs.
|
||||
const (
|
||||
Person = Domain(0)
|
||||
Group = Domain(1)
|
||||
Org = Domain(2)
|
||||
)
|
||||
|
||||
// NewDCESecurity returns a DCE Security (Version 2) UUID.
|
||||
//
|
||||
// The domain should be one of Person, Group or Org.
|
||||
// On a POSIX system the id should be the users UID for the Person
|
||||
// domain and the users GID for the Group. The meaning of id for
|
||||
// the domain Org or on non-POSIX systems is site defined.
|
||||
//
|
||||
// For a given domain/id pair the same token may be returned for up to
|
||||
// 7 minutes and 10 seconds.
|
||||
func NewDCESecurity(domain Domain, id uint32) (UUID, error) {
|
||||
uuid, err := NewUUID()
|
||||
if err == nil {
|
||||
uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2
|
||||
uuid[9] = byte(domain)
|
||||
binary.BigEndian.PutUint32(uuid[0:], id)
|
||||
}
|
||||
return uuid, err
|
||||
}
|
||||
|
||||
// NewDCEPerson returns a DCE Security (Version 2) UUID in the person
|
||||
// domain with the id returned by os.Getuid.
|
||||
//
|
||||
// NewDCESecurity(Person, uint32(os.Getuid()))
|
||||
func NewDCEPerson() (UUID, error) {
|
||||
return NewDCESecurity(Person, uint32(os.Getuid()))
|
||||
}
|
||||
|
||||
// NewDCEGroup returns a DCE Security (Version 2) UUID in the group
|
||||
// domain with the id returned by os.Getgid.
|
||||
//
|
||||
// NewDCESecurity(Group, uint32(os.Getgid()))
|
||||
func NewDCEGroup() (UUID, error) {
|
||||
return NewDCESecurity(Group, uint32(os.Getgid()))
|
||||
}
|
||||
|
||||
// Domain returns the domain for a Version 2 UUID. Domains are only defined
|
||||
// for Version 2 UUIDs.
|
||||
func (uuid UUID) Domain() Domain {
|
||||
return Domain(uuid[9])
|
||||
}
|
||||
|
||||
// ID returns the id for a Version 2 UUID. IDs are only defined for Version 2
|
||||
// UUIDs.
|
||||
func (uuid UUID) ID() uint32 {
|
||||
return binary.BigEndian.Uint32(uuid[0:4])
|
||||
}
|
||||
|
||||
func (d Domain) String() string {
|
||||
switch d {
|
||||
case Person:
|
||||
return "Person"
|
||||
case Group:
|
||||
return "Group"
|
||||
case Org:
|
||||
return "Org"
|
||||
}
|
||||
return fmt.Sprintf("Domain%d", int(d))
|
||||
}
|
12
vendor/github.com/google/uuid/doc.go
generated
vendored
12
vendor/github.com/google/uuid/doc.go
generated
vendored
@ -1,12 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package uuid generates and inspects UUIDs.
|
||||
//
|
||||
// UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security
|
||||
// Services.
|
||||
//
|
||||
// A UUID is a 16 byte (128 bit) array. UUIDs may be used as keys to
|
||||
// maps or compared directly.
|
||||
package uuid
|
1
vendor/github.com/google/uuid/go.mod
generated
vendored
1
vendor/github.com/google/uuid/go.mod
generated
vendored
@ -1 +0,0 @@
|
||||
module github.com/google/uuid
|
53
vendor/github.com/google/uuid/hash.go
generated
vendored
53
vendor/github.com/google/uuid/hash.go
generated
vendored
@ -1,53 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"crypto/sha1"
|
||||
"hash"
|
||||
)
|
||||
|
||||
// Well known namespace IDs and UUIDs
|
||||
var (
|
||||
NameSpaceDNS = Must(Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8"))
|
||||
NameSpaceURL = Must(Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8"))
|
||||
NameSpaceOID = Must(Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8"))
|
||||
NameSpaceX500 = Must(Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8"))
|
||||
Nil UUID // empty UUID, all zeros
|
||||
)
|
||||
|
||||
// NewHash returns a new UUID derived from the hash of space concatenated with
|
||||
// data generated by h. The hash should be at least 16 byte in length. The
|
||||
// first 16 bytes of the hash are used to form the UUID. The version of the
|
||||
// UUID will be the lower 4 bits of version. NewHash is used to implement
|
||||
// NewMD5 and NewSHA1.
|
||||
func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID {
|
||||
h.Reset()
|
||||
h.Write(space[:])
|
||||
h.Write(data)
|
||||
s := h.Sum(nil)
|
||||
var uuid UUID
|
||||
copy(uuid[:], s)
|
||||
uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4)
|
||||
uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant
|
||||
return uuid
|
||||
}
|
||||
|
||||
// NewMD5 returns a new MD5 (Version 3) UUID based on the
|
||||
// supplied name space and data. It is the same as calling:
|
||||
//
|
||||
// NewHash(md5.New(), space, data, 3)
|
||||
func NewMD5(space UUID, data []byte) UUID {
|
||||
return NewHash(md5.New(), space, data, 3)
|
||||
}
|
||||
|
||||
// NewSHA1 returns a new SHA1 (Version 5) UUID based on the
|
||||
// supplied name space and data. It is the same as calling:
|
||||
//
|
||||
// NewHash(sha1.New(), space, data, 5)
|
||||
func NewSHA1(space UUID, data []byte) UUID {
|
||||
return NewHash(sha1.New(), space, data, 5)
|
||||
}
|
37
vendor/github.com/google/uuid/marshal.go
generated
vendored
37
vendor/github.com/google/uuid/marshal.go
generated
vendored
@ -1,37 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import "fmt"
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
func (uuid UUID) MarshalText() ([]byte, error) {
|
||||
var js [36]byte
|
||||
encodeHex(js[:], uuid)
|
||||
return js[:], nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
func (uuid *UUID) UnmarshalText(data []byte) error {
|
||||
id, err := ParseBytes(data)
|
||||
if err == nil {
|
||||
*uuid = id
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// MarshalBinary implements encoding.BinaryMarshaler.
|
||||
func (uuid UUID) MarshalBinary() ([]byte, error) {
|
||||
return uuid[:], nil
|
||||
}
|
||||
|
||||
// UnmarshalBinary implements encoding.BinaryUnmarshaler.
|
||||
func (uuid *UUID) UnmarshalBinary(data []byte) error {
|
||||
if len(data) != 16 {
|
||||
return fmt.Errorf("invalid UUID (got %d bytes)", len(data))
|
||||
}
|
||||
copy(uuid[:], data)
|
||||
return nil
|
||||
}
|
90
vendor/github.com/google/uuid/node.go
generated
vendored
90
vendor/github.com/google/uuid/node.go
generated
vendored
@ -1,90 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
nodeMu sync.Mutex
|
||||
ifname string // name of interface being used
|
||||
nodeID [6]byte // hardware for version 1 UUIDs
|
||||
zeroID [6]byte // nodeID with only 0's
|
||||
)
|
||||
|
||||
// NodeInterface returns the name of the interface from which the NodeID was
|
||||
// derived. The interface "user" is returned if the NodeID was set by
|
||||
// SetNodeID.
|
||||
func NodeInterface() string {
|
||||
defer nodeMu.Unlock()
|
||||
nodeMu.Lock()
|
||||
return ifname
|
||||
}
|
||||
|
||||
// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs.
|
||||
// If name is "" then the first usable interface found will be used or a random
|
||||
// Node ID will be generated. If a named interface cannot be found then false
|
||||
// is returned.
|
||||
//
|
||||
// SetNodeInterface never fails when name is "".
|
||||
func SetNodeInterface(name string) bool {
|
||||
defer nodeMu.Unlock()
|
||||
nodeMu.Lock()
|
||||
return setNodeInterface(name)
|
||||
}
|
||||
|
||||
func setNodeInterface(name string) bool {
|
||||
iname, addr := getHardwareInterface(name) // null implementation for js
|
||||
if iname != "" && addr != nil {
|
||||
ifname = iname
|
||||
copy(nodeID[:], addr)
|
||||
return true
|
||||
}
|
||||
|
||||
// We found no interfaces with a valid hardware address. If name
|
||||
// does not specify a specific interface generate a random Node ID
|
||||
// (section 4.1.6)
|
||||
if name == "" {
|
||||
ifname = "random"
|
||||
randomBits(nodeID[:])
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// NodeID returns a slice of a copy of the current Node ID, setting the Node ID
|
||||
// if not already set.
|
||||
func NodeID() []byte {
|
||||
defer nodeMu.Unlock()
|
||||
nodeMu.Lock()
|
||||
if nodeID == zeroID {
|
||||
setNodeInterface("")
|
||||
}
|
||||
nid := nodeID
|
||||
return nid[:]
|
||||
}
|
||||
|
||||
// SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes
|
||||
// of id are used. If id is less than 6 bytes then false is returned and the
|
||||
// Node ID is not set.
|
||||
func SetNodeID(id []byte) bool {
|
||||
if len(id) < 6 {
|
||||
return false
|
||||
}
|
||||
defer nodeMu.Unlock()
|
||||
nodeMu.Lock()
|
||||
copy(nodeID[:], id)
|
||||
ifname = "user"
|
||||
return true
|
||||
}
|
||||
|
||||
// NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is
|
||||
// not valid. The NodeID is only well defined for version 1 and 2 UUIDs.
|
||||
func (uuid UUID) NodeID() []byte {
|
||||
var node [6]byte
|
||||
copy(node[:], uuid[10:])
|
||||
return node[:]
|
||||
}
|
12
vendor/github.com/google/uuid/node_js.go
generated
vendored
12
vendor/github.com/google/uuid/node_js.go
generated
vendored
@ -1,12 +0,0 @@
|
||||
// Copyright 2017 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build js
|
||||
|
||||
package uuid
|
||||
|
||||
// getHardwareInterface returns nil values for the JS version of the code.
|
||||
// This remvoves the "net" dependency, because it is not used in the browser.
|
||||
// Using the "net" library inflates the size of the transpiled JS code by 673k bytes.
|
||||
func getHardwareInterface(name string) (string, []byte) { return "", nil }
|
33
vendor/github.com/google/uuid/node_net.go
generated
vendored
33
vendor/github.com/google/uuid/node_net.go
generated
vendored
@ -1,33 +0,0 @@
|
||||
// Copyright 2017 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !js
|
||||
|
||||
package uuid
|
||||
|
||||
import "net"
|
||||
|
||||
var interfaces []net.Interface // cached list of interfaces
|
||||
|
||||
// getHardwareInterface returns the name and hardware address of interface name.
|
||||
// If name is "" then the name and hardware address of one of the system's
|
||||
// interfaces is returned. If no interfaces are found (name does not exist or
|
||||
// there are no interfaces) then "", nil is returned.
|
||||
//
|
||||
// Only addresses of at least 6 bytes are returned.
|
||||
func getHardwareInterface(name string) (string, []byte) {
|
||||
if interfaces == nil {
|
||||
var err error
|
||||
interfaces, err = net.Interfaces()
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
}
|
||||
for _, ifs := range interfaces {
|
||||
if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) {
|
||||
return ifs.Name, ifs.HardwareAddr
|
||||
}
|
||||
}
|
||||
return "", nil
|
||||
}
|
59
vendor/github.com/google/uuid/sql.go
generated
vendored
59
vendor/github.com/google/uuid/sql.go
generated
vendored
@ -1,59 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Scan implements sql.Scanner so UUIDs can be read from databases transparently
|
||||
// Currently, database types that map to string and []byte are supported. Please
|
||||
// consult database-specific driver documentation for matching types.
|
||||
func (uuid *UUID) Scan(src interface{}) error {
|
||||
switch src := src.(type) {
|
||||
case nil:
|
||||
return nil
|
||||
|
||||
case string:
|
||||
// if an empty UUID comes from a table, we return a null UUID
|
||||
if src == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// see Parse for required string format
|
||||
u, err := Parse(src)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Scan: %v", err)
|
||||
}
|
||||
|
||||
*uuid = u
|
||||
|
||||
case []byte:
|
||||
// if an empty UUID comes from a table, we return a null UUID
|
||||
if len(src) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// assumes a simple slice of bytes if 16 bytes
|
||||
// otherwise attempts to parse
|
||||
if len(src) != 16 {
|
||||
return uuid.Scan(string(src))
|
||||
}
|
||||
copy((*uuid)[:], src)
|
||||
|
||||
default:
|
||||
return fmt.Errorf("Scan: unable to scan type %T into UUID", src)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value implements sql.Valuer so that UUIDs can be written to databases
|
||||
// transparently. Currently, UUIDs map to strings. Please consult
|
||||
// database-specific driver documentation for matching types.
|
||||
func (uuid UUID) Value() (driver.Value, error) {
|
||||
return uuid.String(), nil
|
||||
}
|
123
vendor/github.com/google/uuid/time.go
generated
vendored
123
vendor/github.com/google/uuid/time.go
generated
vendored
@ -1,123 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// A Time represents a time as the number of 100's of nanoseconds since 15 Oct
|
||||
// 1582.
|
||||
type Time int64
|
||||
|
||||
const (
|
||||
lillian = 2299160 // Julian day of 15 Oct 1582
|
||||
unix = 2440587 // Julian day of 1 Jan 1970
|
||||
epoch = unix - lillian // Days between epochs
|
||||
g1582 = epoch * 86400 // seconds between epochs
|
||||
g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs
|
||||
)
|
||||
|
||||
var (
|
||||
timeMu sync.Mutex
|
||||
lasttime uint64 // last time we returned
|
||||
clockSeq uint16 // clock sequence for this run
|
||||
|
||||
timeNow = time.Now // for testing
|
||||
)
|
||||
|
||||
// UnixTime converts t the number of seconds and nanoseconds using the Unix
|
||||
// epoch of 1 Jan 1970.
|
||||
func (t Time) UnixTime() (sec, nsec int64) {
|
||||
sec = int64(t - g1582ns100)
|
||||
nsec = (sec % 10000000) * 100
|
||||
sec /= 10000000
|
||||
return sec, nsec
|
||||
}
|
||||
|
||||
// GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and
|
||||
// clock sequence as well as adjusting the clock sequence as needed. An error
|
||||
// is returned if the current time cannot be determined.
|
||||
func GetTime() (Time, uint16, error) {
|
||||
defer timeMu.Unlock()
|
||||
timeMu.Lock()
|
||||
return getTime()
|
||||
}
|
||||
|
||||
func getTime() (Time, uint16, error) {
|
||||
t := timeNow()
|
||||
|
||||
// If we don't have a clock sequence already, set one.
|
||||
if clockSeq == 0 {
|
||||
setClockSequence(-1)
|
||||
}
|
||||
now := uint64(t.UnixNano()/100) + g1582ns100
|
||||
|
||||
// If time has gone backwards with this clock sequence then we
|
||||
// increment the clock sequence
|
||||
if now <= lasttime {
|
||||
clockSeq = ((clockSeq + 1) & 0x3fff) | 0x8000
|
||||
}
|
||||
lasttime = now
|
||||
return Time(now), clockSeq, nil
|
||||
}
|
||||
|
||||
// ClockSequence returns the current clock sequence, generating one if not
|
||||
// already set. The clock sequence is only used for Version 1 UUIDs.
|
||||
//
|
||||
// The uuid package does not use global static storage for the clock sequence or
|
||||
// the last time a UUID was generated. Unless SetClockSequence is used, a new
|
||||
// random clock sequence is generated the first time a clock sequence is
|
||||
// requested by ClockSequence, GetTime, or NewUUID. (section 4.2.1.1)
|
||||
func ClockSequence() int {
|
||||
defer timeMu.Unlock()
|
||||
timeMu.Lock()
|
||||
return clockSequence()
|
||||
}
|
||||
|
||||
func clockSequence() int {
|
||||
if clockSeq == 0 {
|
||||
setClockSequence(-1)
|
||||
}
|
||||
return int(clockSeq & 0x3fff)
|
||||
}
|
||||
|
||||
// SetClockSequence sets the clock sequence to the lower 14 bits of seq. Setting to
|
||||
// -1 causes a new sequence to be generated.
|
||||
func SetClockSequence(seq int) {
|
||||
defer timeMu.Unlock()
|
||||
timeMu.Lock()
|
||||
setClockSequence(seq)
|
||||
}
|
||||
|
||||
func setClockSequence(seq int) {
|
||||
if seq == -1 {
|
||||
var b [2]byte
|
||||
randomBits(b[:]) // clock sequence
|
||||
seq = int(b[0])<<8 | int(b[1])
|
||||
}
|
||||
oldSeq := clockSeq
|
||||
clockSeq = uint16(seq&0x3fff) | 0x8000 // Set our variant
|
||||
if oldSeq != clockSeq {
|
||||
lasttime = 0
|
||||
}
|
||||
}
|
||||
|
||||
// Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in
|
||||
// uuid. The time is only defined for version 1 and 2 UUIDs.
|
||||
func (uuid UUID) Time() Time {
|
||||
time := int64(binary.BigEndian.Uint32(uuid[0:4]))
|
||||
time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32
|
||||
time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48
|
||||
return Time(time)
|
||||
}
|
||||
|
||||
// ClockSequence returns the clock sequence encoded in uuid.
|
||||
// The clock sequence is only well defined for version 1 and 2 UUIDs.
|
||||
func (uuid UUID) ClockSequence() int {
|
||||
return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff
|
||||
}
|
43
vendor/github.com/google/uuid/util.go
generated
vendored
43
vendor/github.com/google/uuid/util.go
generated
vendored
@ -1,43 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
// randomBits completely fills slice b with random data.
|
||||
func randomBits(b []byte) {
|
||||
if _, err := io.ReadFull(rander, b); err != nil {
|
||||
panic(err.Error()) // rand should never fail
|
||||
}
|
||||
}
|
||||
|
||||
// xvalues returns the value of a byte as a hexadecimal digit or 255.
|
||||
var xvalues = [256]byte{
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
|
||||
255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
}
|
||||
|
||||
// xtob converts hex characters x1 and x2 into a byte.
|
||||
func xtob(x1, x2 byte) (byte, bool) {
|
||||
b1 := xvalues[x1]
|
||||
b2 := xvalues[x2]
|
||||
return (b1 << 4) | b2, b1 != 255 && b2 != 255
|
||||
}
|
245
vendor/github.com/google/uuid/uuid.go
generated
vendored
245
vendor/github.com/google/uuid/uuid.go
generated
vendored
@ -1,245 +0,0 @@
|
||||
// Copyright 2018 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC
|
||||
// 4122.
|
||||
type UUID [16]byte
|
||||
|
||||
// A Version represents a UUID's version.
|
||||
type Version byte
|
||||
|
||||
// A Variant represents a UUID's variant.
|
||||
type Variant byte
|
||||
|
||||
// Constants returned by Variant.
|
||||
const (
|
||||
Invalid = Variant(iota) // Invalid UUID
|
||||
RFC4122 // The variant specified in RFC4122
|
||||
Reserved // Reserved, NCS backward compatibility.
|
||||
Microsoft // Reserved, Microsoft Corporation backward compatibility.
|
||||
Future // Reserved for future definition.
|
||||
)
|
||||
|
||||
var rander = rand.Reader // random function
|
||||
|
||||
// Parse decodes s into a UUID or returns an error. Both the standard UUID
|
||||
// forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and
|
||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the
|
||||
// Microsoft encoding {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} and the raw hex
|
||||
// encoding: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
|
||||
func Parse(s string) (UUID, error) {
|
||||
var uuid UUID
|
||||
switch len(s) {
|
||||
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
case 36:
|
||||
|
||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
case 36 + 9:
|
||||
if strings.ToLower(s[:9]) != "urn:uuid:" {
|
||||
return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9])
|
||||
}
|
||||
s = s[9:]
|
||||
|
||||
// {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
|
||||
case 36 + 2:
|
||||
s = s[1:]
|
||||
|
||||
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
case 32:
|
||||
var ok bool
|
||||
for i := range uuid {
|
||||
uuid[i], ok = xtob(s[i*2], s[i*2+1])
|
||||
if !ok {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
}
|
||||
return uuid, nil
|
||||
default:
|
||||
return uuid, fmt.Errorf("invalid UUID length: %d", len(s))
|
||||
}
|
||||
// s is now at least 36 bytes long
|
||||
// it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
for i, x := range [16]int{
|
||||
0, 2, 4, 6,
|
||||
9, 11,
|
||||
14, 16,
|
||||
19, 21,
|
||||
24, 26, 28, 30, 32, 34} {
|
||||
v, ok := xtob(s[x], s[x+1])
|
||||
if !ok {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
uuid[i] = v
|
||||
}
|
||||
return uuid, nil
|
||||
}
|
||||
|
||||
// ParseBytes is like Parse, except it parses a byte slice instead of a string.
|
||||
func ParseBytes(b []byte) (UUID, error) {
|
||||
var uuid UUID
|
||||
switch len(b) {
|
||||
case 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
case 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
if !bytes.Equal(bytes.ToLower(b[:9]), []byte("urn:uuid:")) {
|
||||
return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9])
|
||||
}
|
||||
b = b[9:]
|
||||
case 36 + 2: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
|
||||
b = b[1:]
|
||||
case 32: // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
var ok bool
|
||||
for i := 0; i < 32; i += 2 {
|
||||
uuid[i/2], ok = xtob(b[i], b[i+1])
|
||||
if !ok {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
}
|
||||
return uuid, nil
|
||||
default:
|
||||
return uuid, fmt.Errorf("invalid UUID length: %d", len(b))
|
||||
}
|
||||
// s is now at least 36 bytes long
|
||||
// it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
if b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
for i, x := range [16]int{
|
||||
0, 2, 4, 6,
|
||||
9, 11,
|
||||
14, 16,
|
||||
19, 21,
|
||||
24, 26, 28, 30, 32, 34} {
|
||||
v, ok := xtob(b[x], b[x+1])
|
||||
if !ok {
|
||||
return uuid, errors.New("invalid UUID format")
|
||||
}
|
||||
uuid[i] = v
|
||||
}
|
||||
return uuid, nil
|
||||
}
|
||||
|
||||
// MustParse is like Parse but panics if the string cannot be parsed.
|
||||
// It simplifies safe initialization of global variables holding compiled UUIDs.
|
||||
func MustParse(s string) UUID {
|
||||
uuid, err := Parse(s)
|
||||
if err != nil {
|
||||
panic(`uuid: Parse(` + s + `): ` + err.Error())
|
||||
}
|
||||
return uuid
|
||||
}
|
||||
|
||||
// FromBytes creates a new UUID from a byte slice. Returns an error if the slice
|
||||
// does not have a length of 16. The bytes are copied from the slice.
|
||||
func FromBytes(b []byte) (uuid UUID, err error) {
|
||||
err = uuid.UnmarshalBinary(b)
|
||||
return uuid, err
|
||||
}
|
||||
|
||||
// Must returns uuid if err is nil and panics otherwise.
|
||||
func Must(uuid UUID, err error) UUID {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return uuid
|
||||
}
|
||||
|
||||
// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
// , or "" if uuid is invalid.
|
||||
func (uuid UUID) String() string {
|
||||
var buf [36]byte
|
||||
encodeHex(buf[:], uuid)
|
||||
return string(buf[:])
|
||||
}
|
||||
|
||||
// URN returns the RFC 2141 URN form of uuid,
|
||||
// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid.
|
||||
func (uuid UUID) URN() string {
|
||||
var buf [36 + 9]byte
|
||||
copy(buf[:], "urn:uuid:")
|
||||
encodeHex(buf[9:], uuid)
|
||||
return string(buf[:])
|
||||
}
|
||||
|
||||
func encodeHex(dst []byte, uuid UUID) {
|
||||
hex.Encode(dst, uuid[:4])
|
||||
dst[8] = '-'
|
||||
hex.Encode(dst[9:13], uuid[4:6])
|
||||
dst[13] = '-'
|
||||
hex.Encode(dst[14:18], uuid[6:8])
|
||||
dst[18] = '-'
|
||||
hex.Encode(dst[19:23], uuid[8:10])
|
||||
dst[23] = '-'
|
||||
hex.Encode(dst[24:], uuid[10:])
|
||||
}
|
||||
|
||||
// Variant returns the variant encoded in uuid.
|
||||
func (uuid UUID) Variant() Variant {
|
||||
switch {
|
||||
case (uuid[8] & 0xc0) == 0x80:
|
||||
return RFC4122
|
||||
case (uuid[8] & 0xe0) == 0xc0:
|
||||
return Microsoft
|
||||
case (uuid[8] & 0xe0) == 0xe0:
|
||||
return Future
|
||||
default:
|
||||
return Reserved
|
||||
}
|
||||
}
|
||||
|
||||
// Version returns the version of uuid.
|
||||
func (uuid UUID) Version() Version {
|
||||
return Version(uuid[6] >> 4)
|
||||
}
|
||||
|
||||
func (v Version) String() string {
|
||||
if v > 15 {
|
||||
return fmt.Sprintf("BAD_VERSION_%d", v)
|
||||
}
|
||||
return fmt.Sprintf("VERSION_%d", v)
|
||||
}
|
||||
|
||||
func (v Variant) String() string {
|
||||
switch v {
|
||||
case RFC4122:
|
||||
return "RFC4122"
|
||||
case Reserved:
|
||||
return "Reserved"
|
||||
case Microsoft:
|
||||
return "Microsoft"
|
||||
case Future:
|
||||
return "Future"
|
||||
case Invalid:
|
||||
return "Invalid"
|
||||
}
|
||||
return fmt.Sprintf("BadVariant%d", int(v))
|
||||
}
|
||||
|
||||
// SetRand sets the random number generator to r, which implements io.Reader.
|
||||
// If r.Read returns an error when the package requests random data then
|
||||
// a panic will be issued.
|
||||
//
|
||||
// Calling SetRand with nil sets the random number generator to the default
|
||||
// generator.
|
||||
func SetRand(r io.Reader) {
|
||||
if r == nil {
|
||||
rander = rand.Reader
|
||||
return
|
||||
}
|
||||
rander = r
|
||||
}
|
44
vendor/github.com/google/uuid/version1.go
generated
vendored
44
vendor/github.com/google/uuid/version1.go
generated
vendored
@ -1,44 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
// NewUUID returns a Version 1 UUID based on the current NodeID and clock
|
||||
// sequence, and the current time. If the NodeID has not been set by SetNodeID
|
||||
// or SetNodeInterface then it will be set automatically. If the NodeID cannot
|
||||
// be set NewUUID returns nil. If clock sequence has not been set by
|
||||
// SetClockSequence then it will be set automatically. If GetTime fails to
|
||||
// return the current NewUUID returns nil and an error.
|
||||
//
|
||||
// In most cases, New should be used.
|
||||
func NewUUID() (UUID, error) {
|
||||
nodeMu.Lock()
|
||||
if nodeID == zeroID {
|
||||
setNodeInterface("")
|
||||
}
|
||||
nodeMu.Unlock()
|
||||
|
||||
var uuid UUID
|
||||
now, seq, err := GetTime()
|
||||
if err != nil {
|
||||
return uuid, err
|
||||
}
|
||||
|
||||
timeLow := uint32(now & 0xffffffff)
|
||||
timeMid := uint16((now >> 32) & 0xffff)
|
||||
timeHi := uint16((now >> 48) & 0x0fff)
|
||||
timeHi |= 0x1000 // Version 1
|
||||
|
||||
binary.BigEndian.PutUint32(uuid[0:], timeLow)
|
||||
binary.BigEndian.PutUint16(uuid[4:], timeMid)
|
||||
binary.BigEndian.PutUint16(uuid[6:], timeHi)
|
||||
binary.BigEndian.PutUint16(uuid[8:], seq)
|
||||
copy(uuid[10:], nodeID[:])
|
||||
|
||||
return uuid, nil
|
||||
}
|
38
vendor/github.com/google/uuid/version4.go
generated
vendored
38
vendor/github.com/google/uuid/version4.go
generated
vendored
@ -1,38 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package uuid
|
||||
|
||||
import "io"
|
||||
|
||||
// New creates a new random UUID or panics. New is equivalent to
|
||||
// the expression
|
||||
//
|
||||
// uuid.Must(uuid.NewRandom())
|
||||
func New() UUID {
|
||||
return Must(NewRandom())
|
||||
}
|
||||
|
||||
// NewRandom returns a Random (Version 4) UUID.
|
||||
//
|
||||
// The strength of the UUIDs is based on the strength of the crypto/rand
|
||||
// package.
|
||||
//
|
||||
// A note about uniqueness derived from the UUID Wikipedia entry:
|
||||
//
|
||||
// Randomly generated UUIDs have 122 random bits. One's annual risk of being
|
||||
// hit by a meteorite is estimated to be one chance in 17 billion, that
|
||||
// means the probability is about 0.00000000006 (6 × 10−11),
|
||||
// equivalent to the odds of creating a few tens of trillions of UUIDs in a
|
||||
// year and having one duplicate.
|
||||
func NewRandom() (UUID, error) {
|
||||
var uuid UUID
|
||||
_, err := io.ReadFull(rander, uuid[:])
|
||||
if err != nil {
|
||||
return Nil, err
|
||||
}
|
||||
uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4
|
||||
uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10
|
||||
return uuid, nil
|
||||
}
|
1
vendor/github.com/vishvananda/netlink/.gitignore
generated
vendored
Normal file
1
vendor/github.com/vishvananda/netlink/.gitignore
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
.idea/
|
6
vendor/github.com/vishvananda/netlink/.travis.yml
generated
vendored
6
vendor/github.com/vishvananda/netlink/.travis.yml
generated
vendored
@ -1,4 +1,8 @@
|
||||
language: go
|
||||
go:
|
||||
- "1.10.x"
|
||||
- "1.11.x"
|
||||
- "1.12.x"
|
||||
before_script:
|
||||
# make sure we keep path in tact when we sudo
|
||||
- sudo sed -i -e 's/^Defaults\tsecure_path.*$//' /etc/sudoers
|
||||
@ -9,5 +13,7 @@ before_script:
|
||||
- sudo modprobe nf_conntrack_netlink
|
||||
- sudo modprobe nf_conntrack_ipv4
|
||||
- sudo modprobe nf_conntrack_ipv6
|
||||
- sudo modprobe sch_hfsc
|
||||
install:
|
||||
- go get github.com/vishvananda/netns
|
||||
go_import_path: github.com/vishvananda/netlink
|
||||
|
105
vendor/github.com/vishvananda/netlink/addr_linux.go
generated
vendored
105
vendor/github.com/vishvananda/netlink/addr_linux.go
generated
vendored
@ -15,39 +15,62 @@ import (
|
||||
const IFA_FLAGS = 0x8
|
||||
|
||||
// AddrAdd will add an IP address to a link device.
|
||||
//
|
||||
// Equivalent to: `ip addr add $addr dev $link`
|
||||
//
|
||||
// If `addr` is an IPv4 address and the broadcast address is not given, it
|
||||
// will be automatically computed based on the IP mask if /30 or larger.
|
||||
func AddrAdd(link Link, addr *Addr) error {
|
||||
return pkgHandle.AddrAdd(link, addr)
|
||||
}
|
||||
|
||||
// AddrAdd will add an IP address to a link device.
|
||||
//
|
||||
// Equivalent to: `ip addr add $addr dev $link`
|
||||
//
|
||||
// If `addr` is an IPv4 address and the broadcast address is not given, it
|
||||
// will be automatically computed based on the IP mask if /30 or larger.
|
||||
func (h *Handle) AddrAdd(link Link, addr *Addr) error {
|
||||
req := h.newNetlinkRequest(unix.RTM_NEWADDR, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
|
||||
return h.addrHandle(link, addr, req)
|
||||
}
|
||||
|
||||
// AddrReplace will replace (or, if not present, add) an IP address on a link device.
|
||||
//
|
||||
// Equivalent to: `ip addr replace $addr dev $link`
|
||||
//
|
||||
// If `addr` is an IPv4 address and the broadcast address is not given, it
|
||||
// will be automatically computed based on the IP mask if /30 or larger.
|
||||
func AddrReplace(link Link, addr *Addr) error {
|
||||
return pkgHandle.AddrReplace(link, addr)
|
||||
}
|
||||
|
||||
// AddrReplace will replace (or, if not present, add) an IP address on a link device.
|
||||
//
|
||||
// Equivalent to: `ip addr replace $addr dev $link`
|
||||
//
|
||||
// If `addr` is an IPv4 address and the broadcast address is not given, it
|
||||
// will be automatically computed based on the IP mask if /30 or larger.
|
||||
func (h *Handle) AddrReplace(link Link, addr *Addr) error {
|
||||
req := h.newNetlinkRequest(unix.RTM_NEWADDR, unix.NLM_F_CREATE|unix.NLM_F_REPLACE|unix.NLM_F_ACK)
|
||||
return h.addrHandle(link, addr, req)
|
||||
}
|
||||
|
||||
// AddrDel will delete an IP address from a link device.
|
||||
//
|
||||
// Equivalent to: `ip addr del $addr dev $link`
|
||||
//
|
||||
// If `addr` is an IPv4 address and the broadcast address is not given, it
|
||||
// will be automatically computed based on the IP mask if /30 or larger.
|
||||
func AddrDel(link Link, addr *Addr) error {
|
||||
return pkgHandle.AddrDel(link, addr)
|
||||
}
|
||||
|
||||
// AddrDel will delete an IP address from a link device.
|
||||
// Equivalent to: `ip addr del $addr dev $link`
|
||||
//
|
||||
// If `addr` is an IPv4 address and the broadcast address is not given, it
|
||||
// will be automatically computed based on the IP mask if /30 or larger.
|
||||
func (h *Handle) AddrDel(link Link, addr *Addr) error {
|
||||
req := h.newNetlinkRequest(unix.RTM_DELADDR, unix.NLM_F_ACK)
|
||||
return h.addrHandle(link, addr, req)
|
||||
@ -65,7 +88,11 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error
|
||||
msg := nl.NewIfAddrmsg(family)
|
||||
msg.Index = uint32(base.Index)
|
||||
msg.Scope = uint8(addr.Scope)
|
||||
prefixlen, masklen := addr.Mask.Size()
|
||||
mask := addr.Mask
|
||||
if addr.Peer != nil {
|
||||
mask = addr.Peer.Mask
|
||||
}
|
||||
prefixlen, masklen := mask.Size()
|
||||
msg.Prefixlen = uint8(prefixlen)
|
||||
req.AddData(msg)
|
||||
|
||||
@ -104,14 +131,20 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error
|
||||
}
|
||||
|
||||
if family == FAMILY_V4 {
|
||||
if addr.Broadcast == nil {
|
||||
// Automatically set the broadcast address if it is unset and the
|
||||
// subnet is large enough to sensibly have one (/30 or larger).
|
||||
// See: RFC 3021
|
||||
if addr.Broadcast == nil && prefixlen < 31 {
|
||||
calcBroadcast := make(net.IP, masklen/8)
|
||||
for i := range localAddrData {
|
||||
calcBroadcast[i] = localAddrData[i] | ^addr.Mask[i]
|
||||
calcBroadcast[i] = localAddrData[i] | ^mask[i]
|
||||
}
|
||||
addr.Broadcast = calcBroadcast
|
||||
}
|
||||
req.AddData(nl.NewRtAttr(unix.IFA_BROADCAST, addr.Broadcast))
|
||||
|
||||
if addr.Broadcast != nil {
|
||||
req.AddData(nl.NewRtAttr(unix.IFA_BROADCAST, addr.Broadcast))
|
||||
}
|
||||
|
||||
if addr.Label != "" {
|
||||
labelData := nl.NewRtAttr(unix.IFA_LABEL, nl.ZeroTerminated(addr.Label))
|
||||
@ -206,13 +239,17 @@ func parseAddr(m []byte) (addr Addr, family, index int, err error) {
|
||||
IP: attr.Value,
|
||||
Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
|
||||
}
|
||||
addr.Peer = dst
|
||||
case unix.IFA_LOCAL:
|
||||
// iproute2 manual:
|
||||
// If a peer address is specified, the local address
|
||||
// cannot have a prefix length. The network prefix is
|
||||
// associated with the peer rather than with the local
|
||||
// address.
|
||||
n := 8 * len(attr.Value)
|
||||
local = &net.IPNet{
|
||||
IP: attr.Value,
|
||||
Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
|
||||
Mask: net.CIDRMask(n, n),
|
||||
}
|
||||
addr.IPNet = local
|
||||
case unix.IFA_BROADCAST:
|
||||
addr.Broadcast = attr.Value
|
||||
case unix.IFA_LABEL:
|
||||
@ -226,12 +263,24 @@ func parseAddr(m []byte) (addr Addr, family, index int, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
// IFA_LOCAL should be there but if not, fall back to IFA_ADDRESS
|
||||
// libnl addr.c comment:
|
||||
// IPv6 sends the local address as IFA_ADDRESS with no
|
||||
// IFA_LOCAL, IPv4 sends both IFA_LOCAL and IFA_ADDRESS
|
||||
// with IFA_ADDRESS being the peer address if they differ
|
||||
//
|
||||
// But obviously, as there are IPv6 PtP addresses, too,
|
||||
// IFA_LOCAL should also be handled for IPv6.
|
||||
if local != nil {
|
||||
addr.IPNet = local
|
||||
if family == FAMILY_V4 && local.IP.Equal(dst.IP) {
|
||||
addr.IPNet = dst
|
||||
} else {
|
||||
addr.IPNet = local
|
||||
addr.Peer = dst
|
||||
}
|
||||
} else {
|
||||
addr.IPNet = dst
|
||||
}
|
||||
|
||||
addr.Scope = int(msg.Scope)
|
||||
|
||||
return
|
||||
@ -250,21 +299,22 @@ type AddrUpdate struct {
|
||||
// AddrSubscribe takes a chan down which notifications will be sent
|
||||
// when addresses change. Close the 'done' chan to stop subscription.
|
||||
func AddrSubscribe(ch chan<- AddrUpdate, done <-chan struct{}) error {
|
||||
return addrSubscribeAt(netns.None(), netns.None(), ch, done, nil, false)
|
||||
return addrSubscribeAt(netns.None(), netns.None(), ch, done, nil, false, 0)
|
||||
}
|
||||
|
||||
// AddrSubscribeAt works like AddrSubscribe plus it allows the caller
|
||||
// to choose the network namespace in which to subscribe (ns).
|
||||
func AddrSubscribeAt(ns netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}) error {
|
||||
return addrSubscribeAt(ns, netns.None(), ch, done, nil, false)
|
||||
return addrSubscribeAt(ns, netns.None(), ch, done, nil, false, 0)
|
||||
}
|
||||
|
||||
// AddrSubscribeOptions contains a set of options to use with
|
||||
// AddrSubscribeWithOptions.
|
||||
type AddrSubscribeOptions struct {
|
||||
Namespace *netns.NsHandle
|
||||
ErrorCallback func(error)
|
||||
ListExisting bool
|
||||
Namespace *netns.NsHandle
|
||||
ErrorCallback func(error)
|
||||
ListExisting bool
|
||||
ReceiveBufferSize int
|
||||
}
|
||||
|
||||
// AddrSubscribeWithOptions work like AddrSubscribe but enable to
|
||||
@ -275,10 +325,10 @@ func AddrSubscribeWithOptions(ch chan<- AddrUpdate, done <-chan struct{}, option
|
||||
none := netns.None()
|
||||
options.Namespace = &none
|
||||
}
|
||||
return addrSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting)
|
||||
return addrSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting, options.ReceiveBufferSize)
|
||||
}
|
||||
|
||||
func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}, cberr func(error), listExisting bool) error {
|
||||
func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}, cberr func(error), listExisting bool, rcvbuf int) error {
|
||||
s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_IPV4_IFADDR, unix.RTNLGRP_IPV6_IFADDR)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -289,6 +339,12 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c
|
||||
s.Close()
|
||||
}()
|
||||
}
|
||||
if rcvbuf != 0 {
|
||||
err = pkgHandle.SetSocketReceiveBufferSize(rcvbuf, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if listExisting {
|
||||
req := pkgHandle.newNetlinkRequest(unix.RTM_GETADDR,
|
||||
unix.NLM_F_DUMP)
|
||||
@ -301,13 +357,19 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c
|
||||
go func() {
|
||||
defer close(ch)
|
||||
for {
|
||||
msgs, err := s.Receive()
|
||||
msgs, from, err := s.Receive()
|
||||
if err != nil {
|
||||
if cberr != nil {
|
||||
cberr(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if from.Pid != nl.PidKernel {
|
||||
if cberr != nil {
|
||||
cberr(fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel))
|
||||
}
|
||||
continue
|
||||
}
|
||||
for _, m := range msgs {
|
||||
if m.Header.Type == unix.NLMSG_DONE {
|
||||
continue
|
||||
@ -319,16 +381,17 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c
|
||||
continue
|
||||
}
|
||||
if cberr != nil {
|
||||
cberr(syscall.Errno(-error))
|
||||
cberr(fmt.Errorf("error message: %v",
|
||||
syscall.Errno(-error)))
|
||||
}
|
||||
return
|
||||
continue
|
||||
}
|
||||
msgType := m.Header.Type
|
||||
if msgType != unix.RTM_NEWADDR && msgType != unix.RTM_DELADDR {
|
||||
if cberr != nil {
|
||||
cberr(fmt.Errorf("bad message type: %d", msgType))
|
||||
}
|
||||
return
|
||||
continue
|
||||
}
|
||||
|
||||
addr, _, ifindex, err := parseAddr(m.Data)
|
||||
@ -336,7 +399,7 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c
|
||||
if cberr != nil {
|
||||
cberr(fmt.Errorf("could not parse address: %v", err))
|
||||
}
|
||||
return
|
||||
continue
|
||||
}
|
||||
|
||||
ch <- AddrUpdate{LinkAddress: *addr.IPNet,
|
||||
|
9
vendor/github.com/vishvananda/netlink/bridge_linux.go
generated
vendored
9
vendor/github.com/vishvananda/netlink/bridge_linux.go
generated
vendored
@ -96,7 +96,7 @@ func (h *Handle) bridgeVlanModify(cmd int, link Link, vid uint16, pvid, untagged
|
||||
flags |= nl.BRIDGE_FLAGS_MASTER
|
||||
}
|
||||
if flags > 0 {
|
||||
nl.NewRtAttrChild(br, nl.IFLA_BRIDGE_FLAGS, nl.Uint16Attr(flags))
|
||||
br.AddRtAttr(nl.IFLA_BRIDGE_FLAGS, nl.Uint16Attr(flags))
|
||||
}
|
||||
vlanInfo := &nl.BridgeVlanInfo{Vid: vid}
|
||||
if pvid {
|
||||
@ -105,11 +105,8 @@ func (h *Handle) bridgeVlanModify(cmd int, link Link, vid uint16, pvid, untagged
|
||||
if untagged {
|
||||
vlanInfo.Flags |= nl.BRIDGE_VLAN_INFO_UNTAGGED
|
||||
}
|
||||
nl.NewRtAttrChild(br, nl.IFLA_BRIDGE_VLAN_INFO, vlanInfo.Serialize())
|
||||
br.AddRtAttr(nl.IFLA_BRIDGE_VLAN_INFO, vlanInfo.Serialize())
|
||||
req.AddData(br)
|
||||
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
141
vendor/github.com/vishvananda/netlink/class.go
generated
vendored
141
vendor/github.com/vishvananda/netlink/class.go
generated
vendored
@ -4,25 +4,76 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Class interfaces for all classes
|
||||
type Class interface {
|
||||
Attrs() *ClassAttrs
|
||||
Type() string
|
||||
}
|
||||
|
||||
// Generic networking statistics for netlink users.
|
||||
// This file contains "gnet_" prefixed structs and relevant functions.
|
||||
// See Documentation/networking/getn_stats.txt in Linux source code for more details.
|
||||
|
||||
// GnetStatsBasic Ref: struct gnet_stats_basic { ... }
|
||||
type GnetStatsBasic struct {
|
||||
Bytes uint64 // number of seen bytes
|
||||
Packets uint32 // number of seen packets
|
||||
}
|
||||
|
||||
// GnetStatsRateEst Ref: struct gnet_stats_rate_est { ... }
|
||||
type GnetStatsRateEst struct {
|
||||
Bps uint32 // current byte rate
|
||||
Pps uint32 // current packet rate
|
||||
}
|
||||
|
||||
// GnetStatsRateEst64 Ref: struct gnet_stats_rate_est64 { ... }
|
||||
type GnetStatsRateEst64 struct {
|
||||
Bps uint64 // current byte rate
|
||||
Pps uint64 // current packet rate
|
||||
}
|
||||
|
||||
// GnetStatsQueue Ref: struct gnet_stats_queue { ... }
|
||||
type GnetStatsQueue struct {
|
||||
Qlen uint32 // queue length
|
||||
Backlog uint32 // backlog size of queue
|
||||
Drops uint32 // number of dropped packets
|
||||
Requeues uint32 // number of requues
|
||||
Overlimits uint32 // number of enqueues over the limit
|
||||
}
|
||||
|
||||
// ClassStatistics representation based on generic networking statistics for netlink.
|
||||
// See Documentation/networking/gen_stats.txt in Linux source code for more details.
|
||||
type ClassStatistics struct {
|
||||
Basic *GnetStatsBasic
|
||||
Queue *GnetStatsQueue
|
||||
RateEst *GnetStatsRateEst
|
||||
}
|
||||
|
||||
// NewClassStatistics Construct a ClassStatistics struct which fields are all initialized by 0.
|
||||
func NewClassStatistics() *ClassStatistics {
|
||||
return &ClassStatistics{
|
||||
Basic: &GnetStatsBasic{},
|
||||
Queue: &GnetStatsQueue{},
|
||||
RateEst: &GnetStatsRateEst{},
|
||||
}
|
||||
}
|
||||
|
||||
// ClassAttrs represents a netlink class. A filter is associated with a link,
|
||||
// has a handle and a parent. The root filter of a device should have a
|
||||
// parent == HANDLE_ROOT.
|
||||
type ClassAttrs struct {
|
||||
LinkIndex int
|
||||
Handle uint32
|
||||
Parent uint32
|
||||
Leaf uint32
|
||||
LinkIndex int
|
||||
Handle uint32
|
||||
Parent uint32
|
||||
Leaf uint32
|
||||
Statistics *ClassStatistics
|
||||
}
|
||||
|
||||
func (q ClassAttrs) String() string {
|
||||
return fmt.Sprintf("{LinkIndex: %d, Handle: %s, Parent: %s, Leaf: %d}", q.LinkIndex, HandleStr(q.Handle), HandleStr(q.Parent), q.Leaf)
|
||||
}
|
||||
|
||||
// HtbClassAttrs stores the attributes of HTB class
|
||||
type HtbClassAttrs struct {
|
||||
// TODO handle all attributes
|
||||
Rate uint64
|
||||
@ -54,10 +105,12 @@ func (q HtbClass) String() string {
|
||||
return fmt.Sprintf("{Rate: %d, Ceil: %d, Buffer: %d, Cbuffer: %d}", q.Rate, q.Ceil, q.Buffer, q.Cbuffer)
|
||||
}
|
||||
|
||||
// Attrs returns the class attributes
|
||||
func (q *HtbClass) Attrs() *ClassAttrs {
|
||||
return &q.ClassAttrs
|
||||
}
|
||||
|
||||
// Type return the class type
|
||||
func (q *HtbClass) Type() string {
|
||||
return "htb"
|
||||
}
|
||||
@ -69,10 +122,90 @@ type GenericClass struct {
|
||||
ClassType string
|
||||
}
|
||||
|
||||
// Attrs return the class attributes
|
||||
func (class *GenericClass) Attrs() *ClassAttrs {
|
||||
return &class.ClassAttrs
|
||||
}
|
||||
|
||||
// Type return the class type
|
||||
func (class *GenericClass) Type() string {
|
||||
return class.ClassType
|
||||
}
|
||||
|
||||
// ServiceCurve is the way the HFSC curve are represented
|
||||
type ServiceCurve struct {
|
||||
m1 uint32
|
||||
d uint32
|
||||
m2 uint32
|
||||
}
|
||||
|
||||
// Attrs return the parameters of the service curve
|
||||
func (c *ServiceCurve) Attrs() (uint32, uint32, uint32) {
|
||||
return c.m1, c.d, c.m2
|
||||
}
|
||||
|
||||
// HfscClass is a representation of the HFSC class
|
||||
type HfscClass struct {
|
||||
ClassAttrs
|
||||
Rsc ServiceCurve
|
||||
Fsc ServiceCurve
|
||||
Usc ServiceCurve
|
||||
}
|
||||
|
||||
// SetUsc sets the Usc curve
|
||||
func (hfsc *HfscClass) SetUsc(m1 uint32, d uint32, m2 uint32) {
|
||||
hfsc.Usc = ServiceCurve{m1: m1 / 8, d: d, m2: m2 / 8}
|
||||
}
|
||||
|
||||
// SetFsc sets the Fsc curve
|
||||
func (hfsc *HfscClass) SetFsc(m1 uint32, d uint32, m2 uint32) {
|
||||
hfsc.Fsc = ServiceCurve{m1: m1 / 8, d: d, m2: m2 / 8}
|
||||
}
|
||||
|
||||
// SetRsc sets the Rsc curve
|
||||
func (hfsc *HfscClass) SetRsc(m1 uint32, d uint32, m2 uint32) {
|
||||
hfsc.Rsc = ServiceCurve{m1: m1 / 8, d: d, m2: m2 / 8}
|
||||
}
|
||||
|
||||
// SetSC implements the SC from the tc CLI
|
||||
func (hfsc *HfscClass) SetSC(m1 uint32, d uint32, m2 uint32) {
|
||||
hfsc.Rsc = ServiceCurve{m1: m1 / 8, d: d, m2: m2 / 8}
|
||||
hfsc.Fsc = ServiceCurve{m1: m1 / 8, d: d, m2: m2 / 8}
|
||||
}
|
||||
|
||||
// SetUL implements the UL from the tc CLI
|
||||
func (hfsc *HfscClass) SetUL(m1 uint32, d uint32, m2 uint32) {
|
||||
hfsc.Usc = ServiceCurve{m1: m1 / 8, d: d, m2: m2 / 8}
|
||||
}
|
||||
|
||||
// SetLS implements the LS from the tc CLI
|
||||
func (hfsc *HfscClass) SetLS(m1 uint32, d uint32, m2 uint32) {
|
||||
hfsc.Fsc = ServiceCurve{m1: m1 / 8, d: d, m2: m2 / 8}
|
||||
}
|
||||
|
||||
// NewHfscClass returns a new HFSC struct with the set parameters
|
||||
func NewHfscClass(attrs ClassAttrs) *HfscClass {
|
||||
return &HfscClass{
|
||||
ClassAttrs: attrs,
|
||||
Rsc: ServiceCurve{},
|
||||
Fsc: ServiceCurve{},
|
||||
Usc: ServiceCurve{},
|
||||
}
|
||||
}
|
||||
|
||||
func (hfsc *HfscClass) String() string {
|
||||
return fmt.Sprintf(
|
||||
"{%s -- {RSC: {m1=%d d=%d m2=%d}} {FSC: {m1=%d d=%d m2=%d}} {USC: {m1=%d d=%d m2=%d}}}",
|
||||
hfsc.Attrs(), hfsc.Rsc.m1*8, hfsc.Rsc.d, hfsc.Rsc.m2*8, hfsc.Fsc.m1*8, hfsc.Fsc.d, hfsc.Fsc.m2*8, hfsc.Usc.m1*8, hfsc.Usc.d, hfsc.Usc.m2*8,
|
||||
)
|
||||
}
|
||||
|
||||
// Attrs return the Hfsc parameters
|
||||
func (hfsc *HfscClass) Attrs() *ClassAttrs {
|
||||
return &hfsc.ClassAttrs
|
||||
}
|
||||
|
||||
// Type return the type of the class
|
||||
func (hfsc *HfscClass) Type() string {
|
||||
return "hfsc"
|
||||
}
|
||||
|
145
vendor/github.com/vishvananda/netlink/class_linux.go
generated
vendored
145
vendor/github.com/vishvananda/netlink/class_linux.go
generated
vendored
@ -1,14 +1,34 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"syscall"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// NOTE: function is in here because it uses other linux functions
|
||||
// Internal tc_stats representation in Go struct.
|
||||
// This is for internal uses only to deserialize the payload of rtattr.
|
||||
// After the deserialization, this should be converted into the canonical stats
|
||||
// struct, ClassStatistics, in case of statistics of a class.
|
||||
// Ref: struct tc_stats { ... }
|
||||
type tcStats struct {
|
||||
Bytes uint64 // Number of enqueued bytes
|
||||
Packets uint32 // Number of enqueued packets
|
||||
Drops uint32 // Packets dropped because of lack of resources
|
||||
Overlimits uint32 // Number of throttle events when this flow goes out of allocated bandwidth
|
||||
Bps uint32 // Current flow byte rate
|
||||
Pps uint32 // Current flow packet rate
|
||||
Qlen uint32
|
||||
Backlog uint32
|
||||
}
|
||||
|
||||
// NewHtbClass NOTE: function is in here because it uses other linux functions
|
||||
func NewHtbClass(attrs ClassAttrs, cattrs HtbClassAttrs) *HtbClass {
|
||||
mtu := 1600
|
||||
rate := cattrs.Rate / 8
|
||||
@ -126,7 +146,9 @@ func classPayload(req *nl.NetlinkRequest, class Class) error {
|
||||
req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(class.Type())))
|
||||
|
||||
options := nl.NewRtAttr(nl.TCA_OPTIONS, nil)
|
||||
if htb, ok := class.(*HtbClass); ok {
|
||||
switch class.Type() {
|
||||
case "htb":
|
||||
htb := class.(*HtbClass)
|
||||
opt := nl.TcHtbCopt{}
|
||||
opt.Buffer = htb.Buffer
|
||||
opt.Cbuffer = htb.Cbuffer
|
||||
@ -151,9 +173,18 @@ func classPayload(req *nl.NetlinkRequest, class Class) error {
|
||||
return errors.New("HTB: failed to calculate ceil rate table")
|
||||
}
|
||||
opt.Ceil = tcceil
|
||||
nl.NewRtAttrChild(options, nl.TCA_HTB_PARMS, opt.Serialize())
|
||||
nl.NewRtAttrChild(options, nl.TCA_HTB_RTAB, SerializeRtab(rtab))
|
||||
nl.NewRtAttrChild(options, nl.TCA_HTB_CTAB, SerializeRtab(ctab))
|
||||
options.AddRtAttr(nl.TCA_HTB_PARMS, opt.Serialize())
|
||||
options.AddRtAttr(nl.TCA_HTB_RTAB, SerializeRtab(rtab))
|
||||
options.AddRtAttr(nl.TCA_HTB_CTAB, SerializeRtab(ctab))
|
||||
case "hfsc":
|
||||
hfsc := class.(*HfscClass)
|
||||
opt := nl.HfscCopt{}
|
||||
opt.Rsc.Set(hfsc.Rsc.Attrs())
|
||||
opt.Fsc.Set(hfsc.Fsc.Attrs())
|
||||
opt.Usc.Set(hfsc.Usc.Attrs())
|
||||
options.AddRtAttr(nl.TCA_HFSC_RSC, nl.SerializeHfscCurve(&opt.Rsc))
|
||||
options.AddRtAttr(nl.TCA_HFSC_FSC, nl.SerializeHfscCurve(&opt.Fsc))
|
||||
options.AddRtAttr(nl.TCA_HFSC_USC, nl.SerializeHfscCurve(&opt.Usc))
|
||||
}
|
||||
req.AddData(options)
|
||||
return nil
|
||||
@ -197,9 +228,10 @@ func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) {
|
||||
}
|
||||
|
||||
base := ClassAttrs{
|
||||
LinkIndex: int(msg.Ifindex),
|
||||
Handle: msg.Handle,
|
||||
Parent: msg.Parent,
|
||||
LinkIndex: int(msg.Ifindex),
|
||||
Handle: msg.Handle,
|
||||
Parent: msg.Parent,
|
||||
Statistics: nil,
|
||||
}
|
||||
|
||||
var class Class
|
||||
@ -211,6 +243,8 @@ func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) {
|
||||
switch classType {
|
||||
case "htb":
|
||||
class = &HtbClass{}
|
||||
case "hfsc":
|
||||
class = &HfscClass{}
|
||||
default:
|
||||
class = &GenericClass{ClassType: classType}
|
||||
}
|
||||
@ -225,6 +259,26 @@ func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "hfsc":
|
||||
data, err := nl.ParseRouteAttr(attr.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = parseHfscClassData(class, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// For backward compatibility.
|
||||
case nl.TCA_STATS:
|
||||
base.Statistics, err = parseTcStats(attr.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case nl.TCA_STATS2:
|
||||
base.Statistics, err = parseTcStats2(attr.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -253,3 +307,78 @@ func parseHtbClassData(class Class, data []syscall.NetlinkRouteAttr) (bool, erro
|
||||
}
|
||||
return detailed, nil
|
||||
}
|
||||
|
||||
func parseHfscClassData(class Class, data []syscall.NetlinkRouteAttr) (bool, error) {
|
||||
hfsc := class.(*HfscClass)
|
||||
detailed := false
|
||||
for _, datum := range data {
|
||||
m1, d, m2 := nl.DeserializeHfscCurve(datum.Value).Attrs()
|
||||
switch datum.Attr.Type {
|
||||
case nl.TCA_HFSC_RSC:
|
||||
hfsc.Rsc = ServiceCurve{m1: m1, d: d, m2: m2}
|
||||
case nl.TCA_HFSC_FSC:
|
||||
hfsc.Fsc = ServiceCurve{m1: m1, d: d, m2: m2}
|
||||
case nl.TCA_HFSC_USC:
|
||||
hfsc.Usc = ServiceCurve{m1: m1, d: d, m2: m2}
|
||||
}
|
||||
}
|
||||
return detailed, nil
|
||||
}
|
||||
|
||||
func parseTcStats(data []byte) (*ClassStatistics, error) {
|
||||
buf := &bytes.Buffer{}
|
||||
buf.Write(data)
|
||||
native := nl.NativeEndian()
|
||||
tcStats := &tcStats{}
|
||||
if err := binary.Read(buf, native, tcStats); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stats := NewClassStatistics()
|
||||
stats.Basic.Bytes = tcStats.Bytes
|
||||
stats.Basic.Packets = tcStats.Packets
|
||||
stats.Queue.Qlen = tcStats.Qlen
|
||||
stats.Queue.Backlog = tcStats.Backlog
|
||||
stats.Queue.Drops = tcStats.Drops
|
||||
stats.Queue.Overlimits = tcStats.Overlimits
|
||||
stats.RateEst.Bps = tcStats.Bps
|
||||
stats.RateEst.Pps = tcStats.Pps
|
||||
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
func parseGnetStats(data []byte, gnetStats interface{}) error {
|
||||
buf := &bytes.Buffer{}
|
||||
buf.Write(data)
|
||||
native := nl.NativeEndian()
|
||||
return binary.Read(buf, native, gnetStats)
|
||||
}
|
||||
|
||||
func parseTcStats2(data []byte) (*ClassStatistics, error) {
|
||||
rtAttrs, err := nl.ParseRouteAttr(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
stats := NewClassStatistics()
|
||||
for _, datum := range rtAttrs {
|
||||
switch datum.Attr.Type {
|
||||
case nl.TCA_STATS_BASIC:
|
||||
if err := parseGnetStats(datum.Value, stats.Basic); err != nil {
|
||||
return nil, fmt.Errorf("Failed to parse ClassStatistics.Basic with: %v\n%s",
|
||||
err, hex.Dump(datum.Value))
|
||||
}
|
||||
case nl.TCA_STATS_QUEUE:
|
||||
if err := parseGnetStats(datum.Value, stats.Queue); err != nil {
|
||||
return nil, fmt.Errorf("Failed to parse ClassStatistics.Queue with: %v\n%s",
|
||||
err, hex.Dump(datum.Value))
|
||||
}
|
||||
case nl.TCA_STATS_RATE_EST:
|
||||
if err := parseGnetStats(datum.Value, stats.RateEst); err != nil {
|
||||
return nil, fmt.Errorf("Failed to parse ClassStatistics.RateEst with: %v\n%s",
|
||||
err, hex.Dump(datum.Value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return stats, nil
|
||||
}
|
||||
|
121
vendor/github.com/vishvananda/netlink/conntrack_linux.go
generated
vendored
121
vendor/github.com/vishvananda/netlink/conntrack_linux.go
generated
vendored
@ -22,11 +22,7 @@ const (
|
||||
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/netfilter/nfnetlink.h -> #define NFNL_SUBSYS_CTNETLINK_EXP 2
|
||||
ConntrackExpectTable = 2
|
||||
)
|
||||
const (
|
||||
// For Parsing Mark
|
||||
TCP_PROTO = 6
|
||||
UDP_PROTO = 17
|
||||
)
|
||||
|
||||
const (
|
||||
// backward compatibility with golang 1.6 which does not have io.SeekCurrent
|
||||
seekCurrent = 1
|
||||
@ -135,11 +131,13 @@ func (h *Handle) dumpConntrackTable(table ConntrackTableType, family InetFamily)
|
||||
// http://git.netfilter.org/libnetfilter_conntrack/tree/include/internal/object.h
|
||||
// For the time being, the structure below allows to parse and extract the base information of a flow
|
||||
type ipTuple struct {
|
||||
SrcIP net.IP
|
||||
Bytes uint64
|
||||
DstIP net.IP
|
||||
Protocol uint8
|
||||
SrcPort uint16
|
||||
DstPort uint16
|
||||
Packets uint64
|
||||
Protocol uint8
|
||||
SrcIP net.IP
|
||||
SrcPort uint16
|
||||
}
|
||||
|
||||
type ConntrackFlow struct {
|
||||
@ -151,11 +149,12 @@ type ConntrackFlow struct {
|
||||
|
||||
func (s *ConntrackFlow) String() string {
|
||||
// conntrack cmd output:
|
||||
// udp 17 src=127.0.0.1 dst=127.0.0.1 sport=4001 dport=1234 [UNREPLIED] src=127.0.0.1 dst=127.0.0.1 sport=1234 dport=4001 mark=0
|
||||
return fmt.Sprintf("%s\t%d src=%s dst=%s sport=%d dport=%d\tsrc=%s dst=%s sport=%d dport=%d mark=%d",
|
||||
// udp 17 src=127.0.0.1 dst=127.0.0.1 sport=4001 dport=1234 packets=5 bytes=532 [UNREPLIED] src=127.0.0.1 dst=127.0.0.1 sport=1234 dport=4001 packets=10 bytes=1078 mark=0
|
||||
return fmt.Sprintf("%s\t%d src=%s dst=%s sport=%d dport=%d packets=%d bytes=%d\tsrc=%s dst=%s sport=%d dport=%d packets=%d bytes=%d mark=%d",
|
||||
nl.L4ProtoMap[s.Forward.Protocol], s.Forward.Protocol,
|
||||
s.Forward.SrcIP.String(), s.Forward.DstIP.String(), s.Forward.SrcPort, s.Forward.DstPort,
|
||||
s.Reverse.SrcIP.String(), s.Reverse.DstIP.String(), s.Reverse.SrcPort, s.Reverse.DstPort, s.Mark)
|
||||
s.Forward.SrcIP.String(), s.Forward.DstIP.String(), s.Forward.SrcPort, s.Forward.DstPort, s.Forward.Packets, s.Forward.Bytes,
|
||||
s.Reverse.SrcIP.String(), s.Reverse.DstIP.String(), s.Reverse.SrcPort, s.Reverse.DstPort, s.Reverse.Packets, s.Reverse.Bytes,
|
||||
s.Mark)
|
||||
}
|
||||
|
||||
// This method parse the ip tuple structure
|
||||
@ -220,9 +219,35 @@ func parseBERaw16(r *bytes.Reader, v *uint16) {
|
||||
binary.Read(r, binary.BigEndian, v)
|
||||
}
|
||||
|
||||
func parseBERaw32(r *bytes.Reader, v *uint32) {
|
||||
binary.Read(r, binary.BigEndian, v)
|
||||
}
|
||||
|
||||
func parseBERaw64(r *bytes.Reader, v *uint64) {
|
||||
binary.Read(r, binary.BigEndian, v)
|
||||
}
|
||||
|
||||
func parseByteAndPacketCounters(r *bytes.Reader) (bytes, packets uint64) {
|
||||
for i := 0; i < 2; i++ {
|
||||
switch _, t, _ := parseNfAttrTL(r); t {
|
||||
case nl.CTA_COUNTERS_BYTES:
|
||||
parseBERaw64(r, &bytes)
|
||||
case nl.CTA_COUNTERS_PACKETS:
|
||||
parseBERaw64(r, &packets)
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func parseConnectionMark(r *bytes.Reader) (mark uint32) {
|
||||
parseBERaw32(r, &mark)
|
||||
return
|
||||
}
|
||||
|
||||
func parseRawData(data []byte) *ConntrackFlow {
|
||||
s := &ConntrackFlow{}
|
||||
var proto uint8
|
||||
// First there is the Nfgenmsg header
|
||||
// consume only the family field
|
||||
reader := bytes.NewReader(data)
|
||||
@ -238,36 +263,31 @@ func parseRawData(data []byte) *ConntrackFlow {
|
||||
// <len, NLA_F_NESTED|CTA_TUPLE_IP> 4 bytes
|
||||
// flow information of the reverse flow
|
||||
for reader.Len() > 0 {
|
||||
nested, t, l := parseNfAttrTL(reader)
|
||||
if nested && t == nl.CTA_TUPLE_ORIG {
|
||||
if nested, t, _ = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP {
|
||||
proto = parseIpTuple(reader, &s.Forward)
|
||||
if nested, t, l := parseNfAttrTL(reader); nested {
|
||||
switch t {
|
||||
case nl.CTA_TUPLE_ORIG:
|
||||
if nested, t, _ = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP {
|
||||
parseIpTuple(reader, &s.Forward)
|
||||
}
|
||||
case nl.CTA_TUPLE_REPLY:
|
||||
if nested, t, _ = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP {
|
||||
parseIpTuple(reader, &s.Reverse)
|
||||
} else {
|
||||
// Header not recognized skip it
|
||||
reader.Seek(int64(l), seekCurrent)
|
||||
}
|
||||
case nl.CTA_COUNTERS_ORIG:
|
||||
s.Forward.Bytes, s.Forward.Packets = parseByteAndPacketCounters(reader)
|
||||
case nl.CTA_COUNTERS_REPLY:
|
||||
s.Reverse.Bytes, s.Reverse.Packets = parseByteAndPacketCounters(reader)
|
||||
}
|
||||
} else if nested && t == nl.CTA_TUPLE_REPLY {
|
||||
if nested, t, _ = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP {
|
||||
parseIpTuple(reader, &s.Reverse)
|
||||
|
||||
// Got all the useful information stop parsing
|
||||
break
|
||||
} else {
|
||||
// Header not recognized skip it
|
||||
reader.Seek(int64(l), seekCurrent)
|
||||
} else {
|
||||
switch t {
|
||||
case nl.CTA_MARK:
|
||||
s.Mark = parseConnectionMark(reader)
|
||||
}
|
||||
}
|
||||
}
|
||||
if proto == TCP_PROTO {
|
||||
reader.Seek(64, seekCurrent)
|
||||
_, t, _, v := parseNfAttrTLV(reader)
|
||||
if t == nl.CTA_MARK {
|
||||
s.Mark = uint32(v[3])
|
||||
}
|
||||
} else if proto == UDP_PROTO {
|
||||
reader.Seek(16, seekCurrent)
|
||||
_, t, _, v := parseNfAttrTLV(reader)
|
||||
if t == nl.CTA_MARK {
|
||||
s.Mark = uint32(v[3])
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
@ -285,7 +305,7 @@ func parseRawData(data []byte) *ConntrackFlow {
|
||||
// Common parameters and options:
|
||||
// -s, --src, --orig-src ip Source address from original direction
|
||||
// -d, --dst, --orig-dst ip Destination address from original direction
|
||||
// -r, --reply-src ip Source addres from reply direction
|
||||
// -r, --reply-src ip Source address from reply direction
|
||||
// -q, --reply-dst ip Destination address from reply direction
|
||||
// -p, --protonum proto Layer 4 Protocol, eg. 'tcp'
|
||||
// -f, --family proto Layer 3 Protocol, eg. 'ipv6'
|
||||
@ -302,11 +322,14 @@ func parseRawData(data []byte) *ConntrackFlow {
|
||||
type ConntrackFilterType uint8
|
||||
|
||||
const (
|
||||
ConntrackOrigSrcIP = iota // -orig-src ip Source address from original direction
|
||||
ConntrackOrigDstIP // -orig-dst ip Destination address from original direction
|
||||
ConntrackNatSrcIP // -src-nat ip Source NAT ip
|
||||
ConntrackNatDstIP // -dst-nat ip Destination NAT ip
|
||||
ConntrackNatAnyIP // -any-nat ip Source or destination NAT ip
|
||||
ConntrackOrigSrcIP = iota // -orig-src ip Source address from original direction
|
||||
ConntrackOrigDstIP // -orig-dst ip Destination address from original direction
|
||||
ConntrackReplySrcIP // --reply-src ip Reply Source IP
|
||||
ConntrackReplyDstIP // --reply-dst ip Reply Destination IP
|
||||
ConntrackReplyAnyIP // Match source or destination reply IP
|
||||
ConntrackNatSrcIP = ConntrackReplySrcIP // deprecated use instead ConntrackReplySrcIP
|
||||
ConntrackNatDstIP = ConntrackReplyDstIP // deprecated use instead ConntrackReplyDstIP
|
||||
ConntrackNatAnyIP = ConntrackReplyAnyIP // deprecated use instaed ConntrackReplyAnyIP
|
||||
)
|
||||
|
||||
type CustomConntrackFilter interface {
|
||||
@ -351,17 +374,17 @@ func (f *ConntrackFilter) MatchConntrackFlow(flow *ConntrackFlow) bool {
|
||||
}
|
||||
|
||||
// -src-nat ip Source NAT ip
|
||||
if elem, found := f.ipFilter[ConntrackNatSrcIP]; match && found {
|
||||
if elem, found := f.ipFilter[ConntrackReplySrcIP]; match && found {
|
||||
match = match && elem.Equal(flow.Reverse.SrcIP)
|
||||
}
|
||||
|
||||
// -dst-nat ip Destination NAT ip
|
||||
if elem, found := f.ipFilter[ConntrackNatDstIP]; match && found {
|
||||
if elem, found := f.ipFilter[ConntrackReplyDstIP]; match && found {
|
||||
match = match && elem.Equal(flow.Reverse.DstIP)
|
||||
}
|
||||
|
||||
// -any-nat ip Source or destination NAT ip
|
||||
if elem, found := f.ipFilter[ConntrackNatAnyIP]; match && found {
|
||||
// Match source or destination reply IP
|
||||
if elem, found := f.ipFilter[ConntrackReplyAnyIP]; match && found {
|
||||
match = match && (elem.Equal(flow.Reverse.SrcIP) || elem.Equal(flow.Reverse.DstIP))
|
||||
}
|
||||
|
||||
|
272
vendor/github.com/vishvananda/netlink/devlink_linux.go
generated
vendored
Normal file
272
vendor/github.com/vishvananda/netlink/devlink_linux.go
generated
vendored
Normal file
@ -0,0 +1,272 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
"fmt"
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// DevlinkDevEswitchAttr represents device's eswitch attributes
|
||||
type DevlinkDevEswitchAttr struct {
|
||||
Mode string
|
||||
InlineMode string
|
||||
EncapMode string
|
||||
}
|
||||
|
||||
// DevlinkDevAttrs represents device attributes
|
||||
type DevlinkDevAttrs struct {
|
||||
Eswitch DevlinkDevEswitchAttr
|
||||
}
|
||||
|
||||
// DevlinkDevice represents device and its attributes
|
||||
type DevlinkDevice struct {
|
||||
BusName string
|
||||
DeviceName string
|
||||
Attrs DevlinkDevAttrs
|
||||
}
|
||||
|
||||
func parseDevLinkDeviceList(msgs [][]byte) ([]*DevlinkDevice, error) {
|
||||
devices := make([]*DevlinkDevice, 0, len(msgs))
|
||||
for _, m := range msgs {
|
||||
attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dev := &DevlinkDevice{}
|
||||
if err = dev.parseAttributes(attrs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
devices = append(devices, dev)
|
||||
}
|
||||
return devices, nil
|
||||
}
|
||||
|
||||
func eswitchStringToMode(modeName string) (uint16, error) {
|
||||
if modeName == "legacy" {
|
||||
return nl.DEVLINK_ESWITCH_MODE_LEGACY, nil
|
||||
} else if modeName == "switchdev" {
|
||||
return nl.DEVLINK_ESWITCH_MODE_SWITCHDEV, nil
|
||||
} else {
|
||||
return 0xffff, fmt.Errorf("invalid switchdev mode")
|
||||
}
|
||||
}
|
||||
|
||||
func parseEswitchMode(mode uint16) string {
|
||||
var eswitchMode = map[uint16]string{
|
||||
nl.DEVLINK_ESWITCH_MODE_LEGACY: "legacy",
|
||||
nl.DEVLINK_ESWITCH_MODE_SWITCHDEV: "switchdev",
|
||||
}
|
||||
if eswitchMode[mode] == "" {
|
||||
return "unknown"
|
||||
} else {
|
||||
return eswitchMode[mode]
|
||||
}
|
||||
}
|
||||
|
||||
func parseEswitchInlineMode(inlinemode uint8) string {
|
||||
var eswitchInlineMode = map[uint8]string{
|
||||
nl.DEVLINK_ESWITCH_INLINE_MODE_NONE: "none",
|
||||
nl.DEVLINK_ESWITCH_INLINE_MODE_LINK: "link",
|
||||
nl.DEVLINK_ESWITCH_INLINE_MODE_NETWORK: "network",
|
||||
nl.DEVLINK_ESWITCH_INLINE_MODE_TRANSPORT: "transport",
|
||||
}
|
||||
if eswitchInlineMode[inlinemode] == "" {
|
||||
return "unknown"
|
||||
} else {
|
||||
return eswitchInlineMode[inlinemode]
|
||||
}
|
||||
}
|
||||
|
||||
func parseEswitchEncapMode(encapmode uint8) string {
|
||||
var eswitchEncapMode = map[uint8]string{
|
||||
nl.DEVLINK_ESWITCH_ENCAP_MODE_NONE: "disable",
|
||||
nl.DEVLINK_ESWITCH_ENCAP_MODE_BASIC: "enable",
|
||||
}
|
||||
if eswitchEncapMode[encapmode] == "" {
|
||||
return "unknown"
|
||||
} else {
|
||||
return eswitchEncapMode[encapmode]
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DevlinkDevice) parseAttributes(attrs []syscall.NetlinkRouteAttr) error {
|
||||
for _, a := range attrs {
|
||||
switch a.Attr.Type {
|
||||
case nl.DEVLINK_ATTR_BUS_NAME:
|
||||
d.BusName = string(a.Value)
|
||||
case nl.DEVLINK_ATTR_DEV_NAME:
|
||||
d.DeviceName = string(a.Value)
|
||||
case nl.DEVLINK_ATTR_ESWITCH_MODE:
|
||||
d.Attrs.Eswitch.Mode = parseEswitchMode(native.Uint16(a.Value))
|
||||
case nl.DEVLINK_ATTR_ESWITCH_INLINE_MODE:
|
||||
d.Attrs.Eswitch.InlineMode = parseEswitchInlineMode(uint8(a.Value[0]))
|
||||
case nl.DEVLINK_ATTR_ESWITCH_ENCAP_MODE:
|
||||
d.Attrs.Eswitch.EncapMode = parseEswitchEncapMode(uint8(a.Value[0]))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dev *DevlinkDevice) parseEswitchAttrs(msgs [][]byte) {
|
||||
m := msgs[0]
|
||||
attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
dev.parseAttributes(attrs)
|
||||
}
|
||||
|
||||
func (h *Handle) getEswitchAttrs(family *GenlFamily, dev *DevlinkDevice) {
|
||||
msg := &nl.Genlmsg{
|
||||
Command: nl.DEVLINK_CMD_ESWITCH_GET,
|
||||
Version: nl.GENL_DEVLINK_VERSION,
|
||||
}
|
||||
req := h.newNetlinkRequest(int(family.ID), unix.NLM_F_REQUEST|unix.NLM_F_ACK)
|
||||
req.AddData(msg)
|
||||
|
||||
b := make([]byte, len(dev.BusName))
|
||||
copy(b, dev.BusName)
|
||||
data := nl.NewRtAttr(nl.DEVLINK_ATTR_BUS_NAME, b)
|
||||
req.AddData(data)
|
||||
|
||||
b = make([]byte, len(dev.DeviceName))
|
||||
copy(b, dev.DeviceName)
|
||||
data = nl.NewRtAttr(nl.DEVLINK_ATTR_DEV_NAME, b)
|
||||
req.AddData(data)
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
dev.parseEswitchAttrs(msgs)
|
||||
}
|
||||
|
||||
// DevLinkGetDeviceList provides a pointer to devlink devices and nil error,
|
||||
// otherwise returns an error code.
|
||||
func (h *Handle) DevLinkGetDeviceList() ([]*DevlinkDevice, error) {
|
||||
f, err := h.GenlFamilyGet(nl.GENL_DEVLINK_NAME)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
msg := &nl.Genlmsg{
|
||||
Command: nl.DEVLINK_CMD_GET,
|
||||
Version: nl.GENL_DEVLINK_VERSION,
|
||||
}
|
||||
req := h.newNetlinkRequest(int(f.ID),
|
||||
unix.NLM_F_REQUEST|unix.NLM_F_ACK|unix.NLM_F_DUMP)
|
||||
req.AddData(msg)
|
||||
msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
devices, err := parseDevLinkDeviceList(msgs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, d := range devices {
|
||||
h.getEswitchAttrs(f, d)
|
||||
}
|
||||
return devices, nil
|
||||
}
|
||||
|
||||
// DevLinkGetDeviceList provides a pointer to devlink devices and nil error,
|
||||
// otherwise returns an error code.
|
||||
func DevLinkGetDeviceList() ([]*DevlinkDevice, error) {
|
||||
return pkgHandle.DevLinkGetDeviceList()
|
||||
}
|
||||
|
||||
func parseDevlinkDevice(msgs [][]byte) (*DevlinkDevice, error) {
|
||||
m := msgs[0]
|
||||
attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dev := &DevlinkDevice{}
|
||||
if err = dev.parseAttributes(attrs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dev, nil
|
||||
}
|
||||
|
||||
func (h *Handle) createCmdReq(cmd uint8, bus string, device string) (*GenlFamily, *nl.NetlinkRequest, error) {
|
||||
f, err := h.GenlFamilyGet(nl.GENL_DEVLINK_NAME)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
msg := &nl.Genlmsg{
|
||||
Command: cmd,
|
||||
Version: nl.GENL_DEVLINK_VERSION,
|
||||
}
|
||||
req := h.newNetlinkRequest(int(f.ID),
|
||||
unix.NLM_F_REQUEST|unix.NLM_F_ACK)
|
||||
req.AddData(msg)
|
||||
|
||||
b := make([]byte, len(bus)+1)
|
||||
copy(b, bus)
|
||||
data := nl.NewRtAttr(nl.DEVLINK_ATTR_BUS_NAME, b)
|
||||
req.AddData(data)
|
||||
|
||||
b = make([]byte, len(device)+1)
|
||||
copy(b, device)
|
||||
data = nl.NewRtAttr(nl.DEVLINK_ATTR_DEV_NAME, b)
|
||||
req.AddData(data)
|
||||
|
||||
return f, req, nil
|
||||
}
|
||||
|
||||
// DevlinkGetDeviceByName provides a pointer to devlink device and nil error,
|
||||
// otherwise returns an error code.
|
||||
func (h *Handle) DevLinkGetDeviceByName(Bus string, Device string) (*DevlinkDevice, error) {
|
||||
f, req, err := h.createCmdReq(nl.DEVLINK_CMD_GET, Bus, Device)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
respmsg, err := req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dev, err := parseDevlinkDevice(respmsg)
|
||||
if err == nil {
|
||||
h.getEswitchAttrs(f, dev)
|
||||
}
|
||||
return dev, err
|
||||
}
|
||||
|
||||
// DevlinkGetDeviceByName provides a pointer to devlink device and nil error,
|
||||
// otherwise returns an error code.
|
||||
func DevLinkGetDeviceByName(Bus string, Device string) (*DevlinkDevice, error) {
|
||||
return pkgHandle.DevLinkGetDeviceByName(Bus, Device)
|
||||
}
|
||||
|
||||
// DevLinkSetEswitchMode sets eswitch mode if able to set successfully or
|
||||
// returns an error code.
|
||||
// Equivalent to: `devlink dev eswitch set $dev mode switchdev`
|
||||
// Equivalent to: `devlink dev eswitch set $dev mode legacy`
|
||||
func (h *Handle) DevLinkSetEswitchMode(Dev *DevlinkDevice, NewMode string) error {
|
||||
mode, err := eswitchStringToMode(NewMode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, req, err := h.createCmdReq(nl.DEVLINK_CMD_ESWITCH_SET, Dev.BusName, Dev.DeviceName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_ESWITCH_MODE, nl.Uint16Attr(mode)))
|
||||
|
||||
_, err = req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
// DevLinkSetEswitchMode sets eswitch mode if able to set successfully or
|
||||
// returns an error code.
|
||||
// Equivalent to: `devlink dev eswitch set $dev mode switchdev`
|
||||
// Equivalent to: `devlink dev eswitch set $dev mode legacy`
|
||||
func DevLinkSetEswitchMode(Dev *DevlinkDevice, NewMode string) error {
|
||||
return pkgHandle.DevLinkSetEswitchMode(Dev, NewMode)
|
||||
}
|
102
vendor/github.com/vishvananda/netlink/filter.go
generated
vendored
102
vendor/github.com/vishvananda/netlink/filter.go
generated
vendored
@ -2,6 +2,7 @@ package netlink
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
type Filter interface {
|
||||
@ -135,6 +136,27 @@ func (action *BpfAction) Attrs() *ActionAttrs {
|
||||
return &action.ActionAttrs
|
||||
}
|
||||
|
||||
type ConnmarkAction struct {
|
||||
ActionAttrs
|
||||
Zone uint16
|
||||
}
|
||||
|
||||
func (action *ConnmarkAction) Type() string {
|
||||
return "connmark"
|
||||
}
|
||||
|
||||
func (action *ConnmarkAction) Attrs() *ActionAttrs {
|
||||
return &action.ActionAttrs
|
||||
}
|
||||
|
||||
func NewConnmarkAction() *ConnmarkAction {
|
||||
return &ConnmarkAction{
|
||||
ActionAttrs: ActionAttrs{
|
||||
Action: TC_ACT_PIPE,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type MirredAct uint8
|
||||
|
||||
func (a MirredAct) String() string {
|
||||
@ -182,47 +204,59 @@ func NewMirredAction(redirIndex int) *MirredAction {
|
||||
}
|
||||
}
|
||||
|
||||
// Sel of the U32 filters that contains multiple TcU32Key. This is the copy
|
||||
// and the frontend representation of nl.TcU32Sel. It is serialized into canonical
|
||||
// nl.TcU32Sel with the appropriate endianness.
|
||||
type TcU32Sel struct {
|
||||
Flags uint8
|
||||
Offshift uint8
|
||||
Nkeys uint8
|
||||
Pad uint8
|
||||
Offmask uint16
|
||||
Off uint16
|
||||
Offoff int16
|
||||
Hoff int16
|
||||
Hmask uint32
|
||||
Keys []TcU32Key
|
||||
type TunnelKeyAct int8
|
||||
|
||||
const (
|
||||
TCA_TUNNEL_KEY_SET TunnelKeyAct = 1 // set tunnel key
|
||||
TCA_TUNNEL_KEY_UNSET TunnelKeyAct = 2 // unset tunnel key
|
||||
)
|
||||
|
||||
type TunnelKeyAction struct {
|
||||
ActionAttrs
|
||||
Action TunnelKeyAct
|
||||
SrcAddr net.IP
|
||||
DstAddr net.IP
|
||||
KeyID uint32
|
||||
}
|
||||
|
||||
// TcU32Key contained of Sel in the U32 filters. This is the copy and the frontend
|
||||
// representation of nl.TcU32Key. It is serialized into chanonical nl.TcU32Sel
|
||||
// with the appropriate endianness.
|
||||
type TcU32Key struct {
|
||||
Mask uint32
|
||||
Val uint32
|
||||
Off int32
|
||||
OffMask int32
|
||||
func (action *TunnelKeyAction) Type() string {
|
||||
return "tunnel_key"
|
||||
}
|
||||
|
||||
// U32 filters on many packet related properties
|
||||
type U32 struct {
|
||||
FilterAttrs
|
||||
ClassId uint32
|
||||
RedirIndex int
|
||||
Sel *TcU32Sel
|
||||
Actions []Action
|
||||
func (action *TunnelKeyAction) Attrs() *ActionAttrs {
|
||||
return &action.ActionAttrs
|
||||
}
|
||||
|
||||
func (filter *U32) Attrs() *FilterAttrs {
|
||||
return &filter.FilterAttrs
|
||||
func NewTunnelKeyAction() *TunnelKeyAction {
|
||||
return &TunnelKeyAction{
|
||||
ActionAttrs: ActionAttrs{
|
||||
Action: TC_ACT_PIPE,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (filter *U32) Type() string {
|
||||
return "u32"
|
||||
type SkbEditAction struct {
|
||||
ActionAttrs
|
||||
QueueMapping *uint16
|
||||
PType *uint16
|
||||
Priority *uint32
|
||||
Mark *uint32
|
||||
}
|
||||
|
||||
func (action *SkbEditAction) Type() string {
|
||||
return "skbedit"
|
||||
}
|
||||
|
||||
func (action *SkbEditAction) Attrs() *ActionAttrs {
|
||||
return &action.ActionAttrs
|
||||
}
|
||||
|
||||
func NewSkbEditAction() *SkbEditAction {
|
||||
return &SkbEditAction{
|
||||
ActionAttrs: ActionAttrs{
|
||||
Action: TC_ACT_PIPE,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// MatchAll filters match all packets
|
||||
@ -262,6 +296,8 @@ type BpfFilter struct {
|
||||
Fd int
|
||||
Name string
|
||||
DirectAction bool
|
||||
Id int
|
||||
Tag string
|
||||
}
|
||||
|
||||
func (filter *BpfFilter) Type() string {
|
||||
|
240
vendor/github.com/vishvananda/netlink/filter_linux.go
generated
vendored
240
vendor/github.com/vishvananda/netlink/filter_linux.go
generated
vendored
@ -3,10 +3,11 @@ package netlink
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
"golang.org/x/sys/unix"
|
||||
@ -20,6 +21,35 @@ const (
|
||||
TC_U32_EAT = nl.TC_U32_EAT
|
||||
)
|
||||
|
||||
// Sel of the U32 filters that contains multiple TcU32Key. This is the type
|
||||
// alias and the frontend representation of nl.TcU32Sel. It is serialized into
|
||||
// canonical nl.TcU32Sel with the appropriate endianness.
|
||||
type TcU32Sel = nl.TcU32Sel
|
||||
|
||||
// TcU32Key contained of Sel in the U32 filters. This is the type alias and the
|
||||
// frontend representation of nl.TcU32Key. It is serialized into chanonical
|
||||
// nl.TcU32Sel with the appropriate endianness.
|
||||
type TcU32Key = nl.TcU32Key
|
||||
|
||||
// U32 filters on many packet related properties
|
||||
type U32 struct {
|
||||
FilterAttrs
|
||||
ClassId uint32
|
||||
Divisor uint32 // Divisor MUST be power of 2.
|
||||
Hash uint32
|
||||
RedirIndex int
|
||||
Sel *TcU32Sel
|
||||
Actions []Action
|
||||
}
|
||||
|
||||
func (filter *U32) Attrs() *FilterAttrs {
|
||||
return &filter.FilterAttrs
|
||||
}
|
||||
|
||||
func (filter *U32) Type() string {
|
||||
return "u32"
|
||||
}
|
||||
|
||||
// Fw filter filters on firewall marks
|
||||
// NOTE: this is in filter_linux because it refers to nl.TcPolice which
|
||||
// is defined in nl/tc_linux.go
|
||||
@ -123,8 +153,24 @@ func FilterAdd(filter Filter) error {
|
||||
// FilterAdd will add a filter to the system.
|
||||
// Equivalent to: `tc filter add $filter`
|
||||
func (h *Handle) FilterAdd(filter Filter) error {
|
||||
return h.filterModify(filter, unix.NLM_F_CREATE|unix.NLM_F_EXCL)
|
||||
}
|
||||
|
||||
// FilterReplace will replace a filter.
|
||||
// Equivalent to: `tc filter replace $filter`
|
||||
func FilterReplace(filter Filter) error {
|
||||
return pkgHandle.FilterReplace(filter)
|
||||
}
|
||||
|
||||
// FilterReplace will replace a filter.
|
||||
// Equivalent to: `tc filter replace $filter`
|
||||
func (h *Handle) FilterReplace(filter Filter) error {
|
||||
return h.filterModify(filter, unix.NLM_F_CREATE)
|
||||
}
|
||||
|
||||
func (h *Handle) filterModify(filter Filter, flags int) error {
|
||||
native = nl.NativeEndian()
|
||||
req := h.newNetlinkRequest(unix.RTM_NEWTFILTER, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
|
||||
req := h.newNetlinkRequest(unix.RTM_NEWTFILTER, flags|unix.NLM_F_ACK)
|
||||
base := filter.Attrs()
|
||||
msg := &nl.TcMsg{
|
||||
Family: nl.FAMILY_ALL,
|
||||
@ -140,8 +186,7 @@ func (h *Handle) FilterAdd(filter Filter) error {
|
||||
|
||||
switch filter := filter.(type) {
|
||||
case *U32:
|
||||
// Convert TcU32Sel into nl.TcU32Sel as it is without copy.
|
||||
sel := (*nl.TcU32Sel)(unsafe.Pointer(filter.Sel))
|
||||
sel := filter.Sel
|
||||
if sel == nil {
|
||||
// match all
|
||||
sel = &nl.TcU32Sel{
|
||||
@ -168,11 +213,20 @@ func (h *Handle) FilterAdd(filter Filter) error {
|
||||
}
|
||||
}
|
||||
sel.Nkeys = uint8(len(sel.Keys))
|
||||
nl.NewRtAttrChild(options, nl.TCA_U32_SEL, sel.Serialize())
|
||||
options.AddRtAttr(nl.TCA_U32_SEL, sel.Serialize())
|
||||
if filter.ClassId != 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_U32_CLASSID, nl.Uint32Attr(filter.ClassId))
|
||||
options.AddRtAttr(nl.TCA_U32_CLASSID, nl.Uint32Attr(filter.ClassId))
|
||||
}
|
||||
actionsAttr := nl.NewRtAttrChild(options, nl.TCA_U32_ACT, nil)
|
||||
if filter.Divisor != 0 {
|
||||
if (filter.Divisor-1)&filter.Divisor != 0 {
|
||||
return fmt.Errorf("illegal divisor %d. Must be a power of 2", filter.Divisor)
|
||||
}
|
||||
options.AddRtAttr(nl.TCA_U32_DIVISOR, nl.Uint32Attr(filter.Divisor))
|
||||
}
|
||||
if filter.Hash != 0 {
|
||||
options.AddRtAttr(nl.TCA_U32_HASH, nl.Uint32Attr(filter.Hash))
|
||||
}
|
||||
actionsAttr := options.AddRtAttr(nl.TCA_U32_ACT, nil)
|
||||
// backwards compatibility
|
||||
if filter.RedirIndex != 0 {
|
||||
filter.Actions = append([]Action{NewMirredAction(filter.RedirIndex)}, filter.Actions...)
|
||||
@ -184,51 +238,51 @@ func (h *Handle) FilterAdd(filter Filter) error {
|
||||
if filter.Mask != 0 {
|
||||
b := make([]byte, 4)
|
||||
native.PutUint32(b, filter.Mask)
|
||||
nl.NewRtAttrChild(options, nl.TCA_FW_MASK, b)
|
||||
options.AddRtAttr(nl.TCA_FW_MASK, b)
|
||||
}
|
||||
if filter.InDev != "" {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FW_INDEV, nl.ZeroTerminated(filter.InDev))
|
||||
options.AddRtAttr(nl.TCA_FW_INDEV, nl.ZeroTerminated(filter.InDev))
|
||||
}
|
||||
if (filter.Police != nl.TcPolice{}) {
|
||||
|
||||
police := nl.NewRtAttrChild(options, nl.TCA_FW_POLICE, nil)
|
||||
nl.NewRtAttrChild(police, nl.TCA_POLICE_TBF, filter.Police.Serialize())
|
||||
police := options.AddRtAttr(nl.TCA_FW_POLICE, nil)
|
||||
police.AddRtAttr(nl.TCA_POLICE_TBF, filter.Police.Serialize())
|
||||
if (filter.Police.Rate != nl.TcRateSpec{}) {
|
||||
payload := SerializeRtab(filter.Rtab)
|
||||
nl.NewRtAttrChild(police, nl.TCA_POLICE_RATE, payload)
|
||||
police.AddRtAttr(nl.TCA_POLICE_RATE, payload)
|
||||
}
|
||||
if (filter.Police.PeakRate != nl.TcRateSpec{}) {
|
||||
payload := SerializeRtab(filter.Ptab)
|
||||
nl.NewRtAttrChild(police, nl.TCA_POLICE_PEAKRATE, payload)
|
||||
police.AddRtAttr(nl.TCA_POLICE_PEAKRATE, payload)
|
||||
}
|
||||
}
|
||||
if filter.ClassId != 0 {
|
||||
b := make([]byte, 4)
|
||||
native.PutUint32(b, filter.ClassId)
|
||||
nl.NewRtAttrChild(options, nl.TCA_FW_CLASSID, b)
|
||||
options.AddRtAttr(nl.TCA_FW_CLASSID, b)
|
||||
}
|
||||
case *BpfFilter:
|
||||
var bpfFlags uint32
|
||||
if filter.ClassId != 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_BPF_CLASSID, nl.Uint32Attr(filter.ClassId))
|
||||
options.AddRtAttr(nl.TCA_BPF_CLASSID, nl.Uint32Attr(filter.ClassId))
|
||||
}
|
||||
if filter.Fd >= 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_BPF_FD, nl.Uint32Attr((uint32(filter.Fd))))
|
||||
options.AddRtAttr(nl.TCA_BPF_FD, nl.Uint32Attr((uint32(filter.Fd))))
|
||||
}
|
||||
if filter.Name != "" {
|
||||
nl.NewRtAttrChild(options, nl.TCA_BPF_NAME, nl.ZeroTerminated(filter.Name))
|
||||
options.AddRtAttr(nl.TCA_BPF_NAME, nl.ZeroTerminated(filter.Name))
|
||||
}
|
||||
if filter.DirectAction {
|
||||
bpfFlags |= nl.TCA_BPF_FLAG_ACT_DIRECT
|
||||
}
|
||||
nl.NewRtAttrChild(options, nl.TCA_BPF_FLAGS, nl.Uint32Attr(bpfFlags))
|
||||
options.AddRtAttr(nl.TCA_BPF_FLAGS, nl.Uint32Attr(bpfFlags))
|
||||
case *MatchAll:
|
||||
actionsAttr := nl.NewRtAttrChild(options, nl.TCA_MATCHALL_ACT, nil)
|
||||
actionsAttr := options.AddRtAttr(nl.TCA_MATCHALL_ACT, nil)
|
||||
if err := EncodeActions(actionsAttr, filter.Actions); err != nil {
|
||||
return err
|
||||
}
|
||||
if filter.ClassId != 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_MATCHALL_CLASSID, nl.Uint32Attr(filter.ClassId))
|
||||
options.AddRtAttr(nl.TCA_MATCHALL_CLASSID, nl.Uint32Attr(filter.ClassId))
|
||||
}
|
||||
}
|
||||
|
||||
@ -366,34 +420,91 @@ func EncodeActions(attr *nl.RtAttr, actions []Action) error {
|
||||
default:
|
||||
return fmt.Errorf("unknown action type %s", action.Type())
|
||||
case *MirredAction:
|
||||
table := nl.NewRtAttrChild(attr, tabIndex, nil)
|
||||
table := attr.AddRtAttr(tabIndex, nil)
|
||||
tabIndex++
|
||||
nl.NewRtAttrChild(table, nl.TCA_ACT_KIND, nl.ZeroTerminated("mirred"))
|
||||
aopts := nl.NewRtAttrChild(table, nl.TCA_ACT_OPTIONS, nil)
|
||||
table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("mirred"))
|
||||
aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
|
||||
mirred := nl.TcMirred{
|
||||
Eaction: int32(action.MirredAction),
|
||||
Ifindex: uint32(action.Ifindex),
|
||||
}
|
||||
toTcGen(action.Attrs(), &mirred.TcGen)
|
||||
nl.NewRtAttrChild(aopts, nl.TCA_MIRRED_PARMS, mirred.Serialize())
|
||||
aopts.AddRtAttr(nl.TCA_MIRRED_PARMS, mirred.Serialize())
|
||||
case *TunnelKeyAction:
|
||||
table := attr.AddRtAttr(tabIndex, nil)
|
||||
tabIndex++
|
||||
table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("tunnel_key"))
|
||||
aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
|
||||
tun := nl.TcTunnelKey{
|
||||
Action: int32(action.Action),
|
||||
}
|
||||
toTcGen(action.Attrs(), &tun.TcGen)
|
||||
aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_PARMS, tun.Serialize())
|
||||
if action.Action == TCA_TUNNEL_KEY_SET {
|
||||
aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_KEY_ID, htonl(action.KeyID))
|
||||
if v4 := action.SrcAddr.To4(); v4 != nil {
|
||||
aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_IPV4_SRC, v4[:])
|
||||
} else if v6 := action.SrcAddr.To16(); v6 != nil {
|
||||
aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_IPV6_SRC, v6[:])
|
||||
} else {
|
||||
return fmt.Errorf("invalid src addr %s for tunnel_key action", action.SrcAddr)
|
||||
}
|
||||
if v4 := action.DstAddr.To4(); v4 != nil {
|
||||
aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_IPV4_DST, v4[:])
|
||||
} else if v6 := action.DstAddr.To16(); v6 != nil {
|
||||
aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_IPV6_DST, v6[:])
|
||||
} else {
|
||||
return fmt.Errorf("invalid dst addr %s for tunnel_key action", action.DstAddr)
|
||||
}
|
||||
}
|
||||
case *SkbEditAction:
|
||||
table := attr.AddRtAttr(tabIndex, nil)
|
||||
tabIndex++
|
||||
table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("skbedit"))
|
||||
aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
|
||||
skbedit := nl.TcSkbEdit{}
|
||||
toTcGen(action.Attrs(), &skbedit.TcGen)
|
||||
aopts.AddRtAttr(nl.TCA_SKBEDIT_PARMS, skbedit.Serialize())
|
||||
if action.QueueMapping != nil {
|
||||
aopts.AddRtAttr(nl.TCA_SKBEDIT_QUEUE_MAPPING, nl.Uint16Attr(*action.QueueMapping))
|
||||
}
|
||||
if action.Priority != nil {
|
||||
aopts.AddRtAttr(nl.TCA_SKBEDIT_PRIORITY, nl.Uint32Attr(*action.Priority))
|
||||
}
|
||||
if action.PType != nil {
|
||||
aopts.AddRtAttr(nl.TCA_SKBEDIT_PTYPE, nl.Uint16Attr(*action.PType))
|
||||
}
|
||||
if action.Mark != nil {
|
||||
aopts.AddRtAttr(nl.TCA_SKBEDIT_MARK, nl.Uint32Attr(*action.Mark))
|
||||
}
|
||||
case *ConnmarkAction:
|
||||
table := attr.AddRtAttr(tabIndex, nil)
|
||||
tabIndex++
|
||||
table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("connmark"))
|
||||
aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
|
||||
connmark := nl.TcConnmark{
|
||||
Zone: action.Zone,
|
||||
}
|
||||
toTcGen(action.Attrs(), &connmark.TcGen)
|
||||
aopts.AddRtAttr(nl.TCA_CONNMARK_PARMS, connmark.Serialize())
|
||||
case *BpfAction:
|
||||
table := nl.NewRtAttrChild(attr, tabIndex, nil)
|
||||
table := attr.AddRtAttr(tabIndex, nil)
|
||||
tabIndex++
|
||||
nl.NewRtAttrChild(table, nl.TCA_ACT_KIND, nl.ZeroTerminated("bpf"))
|
||||
aopts := nl.NewRtAttrChild(table, nl.TCA_ACT_OPTIONS, nil)
|
||||
table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("bpf"))
|
||||
aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
|
||||
gen := nl.TcGen{}
|
||||
toTcGen(action.Attrs(), &gen)
|
||||
nl.NewRtAttrChild(aopts, nl.TCA_ACT_BPF_PARMS, gen.Serialize())
|
||||
nl.NewRtAttrChild(aopts, nl.TCA_ACT_BPF_FD, nl.Uint32Attr(uint32(action.Fd)))
|
||||
nl.NewRtAttrChild(aopts, nl.TCA_ACT_BPF_NAME, nl.ZeroTerminated(action.Name))
|
||||
aopts.AddRtAttr(nl.TCA_ACT_BPF_PARMS, gen.Serialize())
|
||||
aopts.AddRtAttr(nl.TCA_ACT_BPF_FD, nl.Uint32Attr(uint32(action.Fd)))
|
||||
aopts.AddRtAttr(nl.TCA_ACT_BPF_NAME, nl.ZeroTerminated(action.Name))
|
||||
case *GenericAction:
|
||||
table := nl.NewRtAttrChild(attr, tabIndex, nil)
|
||||
table := attr.AddRtAttr(tabIndex, nil)
|
||||
tabIndex++
|
||||
nl.NewRtAttrChild(table, nl.TCA_ACT_KIND, nl.ZeroTerminated("gact"))
|
||||
aopts := nl.NewRtAttrChild(table, nl.TCA_ACT_OPTIONS, nil)
|
||||
table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("gact"))
|
||||
aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
|
||||
gen := nl.TcGen{}
|
||||
toTcGen(action.Attrs(), &gen)
|
||||
nl.NewRtAttrChild(aopts, nl.TCA_GACT_PARMS, gen.Serialize())
|
||||
aopts.AddRtAttr(nl.TCA_GACT_PARMS, gen.Serialize())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@ -419,8 +530,14 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
|
||||
action = &MirredAction{}
|
||||
case "bpf":
|
||||
action = &BpfAction{}
|
||||
case "connmark":
|
||||
action = &ConnmarkAction{}
|
||||
case "gact":
|
||||
action = &GenericAction{}
|
||||
case "tunnel_key":
|
||||
action = &TunnelKeyAction{}
|
||||
case "skbedit":
|
||||
action = &SkbEditAction{}
|
||||
default:
|
||||
break nextattr
|
||||
}
|
||||
@ -435,11 +552,46 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
|
||||
switch adatum.Attr.Type {
|
||||
case nl.TCA_MIRRED_PARMS:
|
||||
mirred := *nl.DeserializeTcMirred(adatum.Value)
|
||||
toAttrs(&mirred.TcGen, action.Attrs())
|
||||
action.(*MirredAction).ActionAttrs = ActionAttrs{}
|
||||
toAttrs(&mirred.TcGen, action.Attrs())
|
||||
action.(*MirredAction).Ifindex = int(mirred.Ifindex)
|
||||
action.(*MirredAction).MirredAction = MirredAct(mirred.Eaction)
|
||||
}
|
||||
case "tunnel_key":
|
||||
switch adatum.Attr.Type {
|
||||
case nl.TCA_TUNNEL_KEY_PARMS:
|
||||
tun := *nl.DeserializeTunnelKey(adatum.Value)
|
||||
action.(*TunnelKeyAction).ActionAttrs = ActionAttrs{}
|
||||
toAttrs(&tun.TcGen, action.Attrs())
|
||||
action.(*TunnelKeyAction).Action = TunnelKeyAct(tun.Action)
|
||||
case nl.TCA_TUNNEL_KEY_ENC_KEY_ID:
|
||||
action.(*TunnelKeyAction).KeyID = networkOrder.Uint32(adatum.Value[0:4])
|
||||
case nl.TCA_TUNNEL_KEY_ENC_IPV6_SRC:
|
||||
case nl.TCA_TUNNEL_KEY_ENC_IPV4_SRC:
|
||||
action.(*TunnelKeyAction).SrcAddr = net.IP(adatum.Value[:])
|
||||
case nl.TCA_TUNNEL_KEY_ENC_IPV6_DST:
|
||||
case nl.TCA_TUNNEL_KEY_ENC_IPV4_DST:
|
||||
action.(*TunnelKeyAction).DstAddr = net.IP(adatum.Value[:])
|
||||
}
|
||||
case "skbedit":
|
||||
switch adatum.Attr.Type {
|
||||
case nl.TCA_SKBEDIT_PARMS:
|
||||
skbedit := *nl.DeserializeSkbEdit(adatum.Value)
|
||||
action.(*SkbEditAction).ActionAttrs = ActionAttrs{}
|
||||
toAttrs(&skbedit.TcGen, action.Attrs())
|
||||
case nl.TCA_SKBEDIT_MARK:
|
||||
mark := native.Uint32(adatum.Value[0:4])
|
||||
action.(*SkbEditAction).Mark = &mark
|
||||
case nl.TCA_SKBEDIT_PRIORITY:
|
||||
priority := native.Uint32(adatum.Value[0:4])
|
||||
action.(*SkbEditAction).Priority = &priority
|
||||
case nl.TCA_SKBEDIT_PTYPE:
|
||||
ptype := native.Uint16(adatum.Value[0:2])
|
||||
action.(*SkbEditAction).PType = &ptype
|
||||
case nl.TCA_SKBEDIT_QUEUE_MAPPING:
|
||||
mapping := native.Uint16(adatum.Value[0:2])
|
||||
action.(*SkbEditAction).QueueMapping = &mapping
|
||||
}
|
||||
case "bpf":
|
||||
switch adatum.Attr.Type {
|
||||
case nl.TCA_ACT_BPF_PARMS:
|
||||
@ -450,6 +602,14 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
|
||||
case nl.TCA_ACT_BPF_NAME:
|
||||
action.(*BpfAction).Name = string(adatum.Value[:len(adatum.Value)-1])
|
||||
}
|
||||
case "connmark":
|
||||
switch adatum.Attr.Type {
|
||||
case nl.TCA_CONNMARK_PARMS:
|
||||
connmark := *nl.DeserializeTcConnmark(adatum.Value)
|
||||
action.(*ConnmarkAction).ActionAttrs = ActionAttrs{}
|
||||
toAttrs(&connmark.TcGen, action.Attrs())
|
||||
action.(*ConnmarkAction).Zone = connmark.Zone
|
||||
}
|
||||
case "gact":
|
||||
switch adatum.Attr.Type {
|
||||
case nl.TCA_GACT_PARMS:
|
||||
@ -474,7 +634,7 @@ func parseU32Data(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error)
|
||||
case nl.TCA_U32_SEL:
|
||||
detailed = true
|
||||
sel := nl.DeserializeTcU32Sel(datum.Value)
|
||||
u32.Sel = (*TcU32Sel)(unsafe.Pointer(sel))
|
||||
u32.Sel = sel
|
||||
if native != networkOrder {
|
||||
// Handle the endianness of attributes
|
||||
u32.Sel.Offmask = native.Uint16(htons(sel.Offmask))
|
||||
@ -500,6 +660,10 @@ func parseU32Data(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error)
|
||||
}
|
||||
case nl.TCA_U32_CLASSID:
|
||||
u32.ClassId = native.Uint32(datum.Value)
|
||||
case nl.TCA_U32_DIVISOR:
|
||||
u32.Divisor = native.Uint32(datum.Value)
|
||||
case nl.TCA_U32_HASH:
|
||||
u32.Hash = native.Uint32(datum.Value)
|
||||
}
|
||||
}
|
||||
return detailed, nil
|
||||
@ -551,6 +715,10 @@ func parseBpfData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error)
|
||||
if (flags & nl.TCA_BPF_FLAG_ACT_DIRECT) != 0 {
|
||||
bpf.DirectAction = true
|
||||
}
|
||||
case nl.TCA_BPF_ID:
|
||||
bpf.Id = int(native.Uint32(datum.Value[0:4]))
|
||||
case nl.TCA_BPF_TAG:
|
||||
bpf.Tag = hex.EncodeToString(datum.Value[:len(datum.Value)-1])
|
||||
}
|
||||
}
|
||||
return detailed, nil
|
||||
|
6
vendor/github.com/vishvananda/netlink/fou_linux.go
generated
vendored
6
vendor/github.com/vishvananda/netlink/fou_linux.go
generated
vendored
@ -90,11 +90,7 @@ func (h *Handle) FouAdd(f Fou) error {
|
||||
req.AddRawData(raw)
|
||||
|
||||
_, err = req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func FouDel(f Fou) error {
|
||||
|
3
vendor/github.com/vishvananda/netlink/genetlink_linux.go
generated
vendored
3
vendor/github.com/vishvananda/netlink/genetlink_linux.go
generated
vendored
@ -157,6 +157,9 @@ func (h *Handle) GenlFamilyGet(name string) (*GenlFamily, error) {
|
||||
return nil, err
|
||||
}
|
||||
families, err := parseFamilies(msgs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(families) != 1 {
|
||||
return nil, fmt.Errorf("invalid response for GENL_CTRL_CMD_GETFAMILY")
|
||||
}
|
||||
|
8
vendor/github.com/vishvananda/netlink/go.mod
generated
vendored
Normal file
8
vendor/github.com/vishvananda/netlink/go.mod
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
module github.com/vishvananda/netlink
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df
|
||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444
|
||||
)
|
4
vendor/github.com/vishvananda/netlink/go.sum
generated
vendored
Normal file
4
vendor/github.com/vishvananda/netlink/go.sum
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444 h1:/d2cWp6PSamH4jDPFLyO150psQdqvtoNX8Zjg3AQ31g=
|
||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
2
vendor/github.com/vishvananda/netlink/handle_linux.go
generated
vendored
2
vendor/github.com/vishvananda/netlink/handle_linux.go
generated
vendored
@ -91,7 +91,7 @@ func (h *Handle) GetSocketReceiveBufferSize() ([]int, error) {
|
||||
return results, nil
|
||||
}
|
||||
|
||||
// NewHandle returns a netlink handle on the network namespace
|
||||
// NewHandleAt returns a netlink handle on the network namespace
|
||||
// specified by ns. If ns=netns.None(), current network namespace
|
||||
// will be assumed
|
||||
func NewHandleAt(ns netns.NsHandle, nlFamilies ...int) (*Handle, error) {
|
||||
|
12
vendor/github.com/vishvananda/netlink/handle_unspecified.go
generated
vendored
12
vendor/github.com/vishvananda/netlink/handle_unspecified.go
generated
vendored
@ -73,10 +73,18 @@ func (h *Handle) LinkSetVfVlan(link Link, vf, vlan int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetVfVlanQos(link Link, vf, vlan, qos int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetVfTxRate(link Link, vf, rate int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetVfRate(link Link, vf, minRate, maxRate int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetMaster(link Link, master *Bridge) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
@ -149,6 +157,10 @@ func (h *Handle) LinkSetTxQLen(link Link, qlen int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetGroup(link Link, group int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) setProtinfoAttr(link Link, mode bool, attr int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
10
vendor/github.com/vishvananda/netlink/ioctl_linux.go
generated
vendored
10
vendor/github.com/vishvananda/netlink/ioctl_linux.go
generated
vendored
@ -56,18 +56,10 @@ type ethtoolSset struct {
|
||||
data [1]uint32
|
||||
}
|
||||
|
||||
// ethtoolGstrings is string set for data tagging
|
||||
type ethtoolGstrings struct {
|
||||
cmd uint32
|
||||
stringSet uint32
|
||||
length uint32
|
||||
data [32]byte
|
||||
}
|
||||
|
||||
type ethtoolStats struct {
|
||||
cmd uint32
|
||||
nStats uint32
|
||||
data [1]uint64
|
||||
// Followed by nStats * []uint64.
|
||||
}
|
||||
|
||||
// newIocltSlaveReq returns filled IfreqSlave with proper interface names
|
||||
|
242
vendor/github.com/vishvananda/netlink/link.go
generated
vendored
242
vendor/github.com/vishvananda/netlink/link.go
generated
vendored
@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Link represents a link device from netlink. Shared link attributes
|
||||
@ -41,6 +42,29 @@ type LinkAttrs struct {
|
||||
NetNsID int
|
||||
NumTxQueues int
|
||||
NumRxQueues int
|
||||
GSOMaxSize uint32
|
||||
GSOMaxSegs uint32
|
||||
Vfs []VfInfo // virtual functions available on link
|
||||
Group uint32
|
||||
Slave LinkSlave
|
||||
}
|
||||
|
||||
// LinkSlave represents a slave device.
|
||||
type LinkSlave interface {
|
||||
SlaveType() string
|
||||
}
|
||||
|
||||
// VfInfo represents configuration of virtual function
|
||||
type VfInfo struct {
|
||||
ID int
|
||||
Mac net.HardwareAddr
|
||||
Vlan int
|
||||
Qos int
|
||||
TxRate int // IFLA_VF_TX_RATE Max TxRate
|
||||
Spoofchk bool
|
||||
LinkState uint32
|
||||
MaxTxRate uint32 // IFLA_VF_RATE Max TxRate
|
||||
MinTxRate uint32 // IFLA_VF_RATE Min TxRate
|
||||
}
|
||||
|
||||
// LinkOperState represents the values of the IFLA_OPERSTATE link
|
||||
@ -223,6 +247,7 @@ type Bridge struct {
|
||||
LinkAttrs
|
||||
MulticastSnooping *bool
|
||||
HelloTime *uint32
|
||||
VlanFiltering *bool
|
||||
}
|
||||
|
||||
func (bridge *Bridge) Attrs() *LinkAttrs {
|
||||
@ -236,7 +261,8 @@ func (bridge *Bridge) Type() string {
|
||||
// Vlan links have ParentIndex set in their Attrs()
|
||||
type Vlan struct {
|
||||
LinkAttrs
|
||||
VlanId int
|
||||
VlanId int
|
||||
VlanProtocol VlanProtocol
|
||||
}
|
||||
|
||||
func (vlan *Vlan) Attrs() *LinkAttrs {
|
||||
@ -290,10 +316,13 @@ type TuntapFlag uint16
|
||||
// Tuntap links created via /dev/tun/tap, but can be destroyed via netlink
|
||||
type Tuntap struct {
|
||||
LinkAttrs
|
||||
Mode TuntapMode
|
||||
Flags TuntapFlag
|
||||
Queues int
|
||||
Fds []*os.File
|
||||
Mode TuntapMode
|
||||
Flags TuntapFlag
|
||||
NonPersist bool
|
||||
Queues int
|
||||
Fds []*os.File
|
||||
Owner uint32
|
||||
Group uint32
|
||||
}
|
||||
|
||||
func (tuntap *Tuntap) Attrs() *LinkAttrs {
|
||||
@ -307,7 +336,8 @@ func (tuntap *Tuntap) Type() string {
|
||||
// Veth devices must specify PeerName on create
|
||||
type Veth struct {
|
||||
LinkAttrs
|
||||
PeerName string // veth on create only
|
||||
PeerName string // veth on create only
|
||||
PeerHardwareAddr net.HardwareAddr
|
||||
}
|
||||
|
||||
func (veth *Veth) Attrs() *LinkAttrs {
|
||||
@ -376,9 +406,18 @@ const (
|
||||
IPVLAN_MODE_MAX
|
||||
)
|
||||
|
||||
type IPVlanFlag uint16
|
||||
|
||||
const (
|
||||
IPVLAN_FLAG_BRIDGE IPVlanFlag = iota
|
||||
IPVLAN_FLAG_PRIVATE
|
||||
IPVLAN_FLAG_VEPA
|
||||
)
|
||||
|
||||
type IPVlan struct {
|
||||
LinkAttrs
|
||||
Mode IPVlanMode
|
||||
Flag IPVlanFlag
|
||||
}
|
||||
|
||||
func (ipvlan *IPVlan) Attrs() *LinkAttrs {
|
||||
@ -389,6 +428,43 @@ func (ipvlan *IPVlan) Type() string {
|
||||
return "ipvlan"
|
||||
}
|
||||
|
||||
// VlanProtocol type
|
||||
type VlanProtocol int
|
||||
|
||||
func (p VlanProtocol) String() string {
|
||||
s, ok := VlanProtocolToString[p]
|
||||
if !ok {
|
||||
return fmt.Sprintf("VlanProtocol(%d)", p)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// StringToVlanProtocol returns vlan protocol, or unknown is the s is invalid.
|
||||
func StringToVlanProtocol(s string) VlanProtocol {
|
||||
mode, ok := StringToVlanProtocolMap[s]
|
||||
if !ok {
|
||||
return VLAN_PROTOCOL_UNKNOWN
|
||||
}
|
||||
return mode
|
||||
}
|
||||
|
||||
// VlanProtocol possible values
|
||||
const (
|
||||
VLAN_PROTOCOL_UNKNOWN VlanProtocol = 0
|
||||
VLAN_PROTOCOL_8021Q VlanProtocol = 0x8100
|
||||
VLAN_PROTOCOL_8021AD VlanProtocol = 0x88A8
|
||||
)
|
||||
|
||||
var VlanProtocolToString = map[VlanProtocol]string{
|
||||
VLAN_PROTOCOL_8021Q: "802.1q",
|
||||
VLAN_PROTOCOL_8021AD: "802.1ad",
|
||||
}
|
||||
|
||||
var StringToVlanProtocolMap = map[string]VlanProtocol{
|
||||
"802.1q": VLAN_PROTOCOL_8021Q,
|
||||
"802.1ad": VLAN_PROTOCOL_8021AD,
|
||||
}
|
||||
|
||||
// BondMode type
|
||||
type BondMode int
|
||||
|
||||
@ -400,7 +476,7 @@ func (b BondMode) String() string {
|
||||
return s
|
||||
}
|
||||
|
||||
// StringToBondMode returns bond mode, or uknonw is the s is invalid.
|
||||
// StringToBondMode returns bond mode, or unknown is the s is invalid.
|
||||
func StringToBondMode(s string) BondMode {
|
||||
mode, ok := StringToBondModeMap[s]
|
||||
if !ok {
|
||||
@ -491,7 +567,7 @@ func (b BondXmitHashPolicy) String() string {
|
||||
return s
|
||||
}
|
||||
|
||||
// StringToBondXmitHashPolicy returns bond lacp arte, or uknonw is the s is invalid.
|
||||
// StringToBondXmitHashPolicy returns bond lacp arte, or unknown is the s is invalid.
|
||||
func StringToBondXmitHashPolicy(s string) BondXmitHashPolicy {
|
||||
lacp, ok := StringToBondXmitHashPolicyMap[s]
|
||||
if !ok {
|
||||
@ -536,7 +612,7 @@ func (b BondLacpRate) String() string {
|
||||
return s
|
||||
}
|
||||
|
||||
// StringToBondLacpRate returns bond lacp arte, or uknonw is the s is invalid.
|
||||
// StringToBondLacpRate returns bond lacp arte, or unknown is the s is invalid.
|
||||
func StringToBondLacpRate(s string) BondLacpRate {
|
||||
lacp, ok := StringToBondLacpRateMap[s]
|
||||
if !ok {
|
||||
@ -680,6 +756,67 @@ func (bond *Bond) Type() string {
|
||||
return "bond"
|
||||
}
|
||||
|
||||
// BondSlaveState represents the values of the IFLA_BOND_SLAVE_STATE bond slave
|
||||
// attribute, which contains the state of the bond slave.
|
||||
type BondSlaveState uint8
|
||||
|
||||
const (
|
||||
BondStateActive = iota // Link is active.
|
||||
BondStateBackup // Link is backup.
|
||||
)
|
||||
|
||||
func (s BondSlaveState) String() string {
|
||||
switch s {
|
||||
case BondStateActive:
|
||||
return "ACTIVE"
|
||||
case BondStateBackup:
|
||||
return "BACKUP"
|
||||
default:
|
||||
return strconv.Itoa(int(s))
|
||||
}
|
||||
}
|
||||
|
||||
// BondSlaveState represents the values of the IFLA_BOND_SLAVE_MII_STATUS bond slave
|
||||
// attribute, which contains the status of MII link monitoring
|
||||
type BondSlaveMiiStatus uint8
|
||||
|
||||
const (
|
||||
BondLinkUp = iota // link is up and running.
|
||||
BondLinkFail // link has just gone down.
|
||||
BondLinkDown // link has been down for too long time.
|
||||
BondLinkBack // link is going back.
|
||||
)
|
||||
|
||||
func (s BondSlaveMiiStatus) String() string {
|
||||
switch s {
|
||||
case BondLinkUp:
|
||||
return "UP"
|
||||
case BondLinkFail:
|
||||
return "GOING_DOWN"
|
||||
case BondLinkDown:
|
||||
return "DOWN"
|
||||
case BondLinkBack:
|
||||
return "GOING_BACK"
|
||||
default:
|
||||
return strconv.Itoa(int(s))
|
||||
}
|
||||
}
|
||||
|
||||
type BondSlave struct {
|
||||
State BondSlaveState
|
||||
MiiStatus BondSlaveMiiStatus
|
||||
LinkFailureCount uint32
|
||||
PermHardwareAddr net.HardwareAddr
|
||||
QueueId uint16
|
||||
AggregatorId uint16
|
||||
AdActorOperPortState uint8
|
||||
AdPartnerOperPortState uint16
|
||||
}
|
||||
|
||||
func (b *BondSlave) SlaveType() string {
|
||||
return "bond"
|
||||
}
|
||||
|
||||
// Gretap devices must specify LocalIP and RemoteIP on create
|
||||
type Gretap struct {
|
||||
LinkAttrs
|
||||
@ -734,6 +871,27 @@ func (iptun *Iptun) Type() string {
|
||||
return "ipip"
|
||||
}
|
||||
|
||||
type Ip6tnl struct {
|
||||
LinkAttrs
|
||||
Link uint32
|
||||
Local net.IP
|
||||
Remote net.IP
|
||||
Ttl uint8
|
||||
Tos uint8
|
||||
EncapLimit uint8
|
||||
Flags uint32
|
||||
Proto uint8
|
||||
FlowInfo uint32
|
||||
}
|
||||
|
||||
func (ip6tnl *Ip6tnl) Attrs() *LinkAttrs {
|
||||
return &ip6tnl.LinkAttrs
|
||||
}
|
||||
|
||||
func (ip6tnl *Ip6tnl) Type() string {
|
||||
return "ip6tnl"
|
||||
}
|
||||
|
||||
type Sittun struct {
|
||||
LinkAttrs
|
||||
Link uint32
|
||||
@ -769,7 +927,10 @@ func (vti *Vti) Attrs() *LinkAttrs {
|
||||
return &vti.LinkAttrs
|
||||
}
|
||||
|
||||
func (iptun *Vti) Type() string {
|
||||
func (vti *Vti) Type() string {
|
||||
if vti.Local.To4() == nil {
|
||||
return "vti6"
|
||||
}
|
||||
return "vti"
|
||||
}
|
||||
|
||||
@ -831,11 +992,68 @@ func (gtp *GTP) Type() string {
|
||||
return "gtp"
|
||||
}
|
||||
|
||||
// Virtual XFRM Interfaces
|
||||
// Named "xfrmi" to prevent confusion with XFRM objects
|
||||
type Xfrmi struct {
|
||||
LinkAttrs
|
||||
Ifid uint32
|
||||
}
|
||||
|
||||
func (xfrm *Xfrmi) Attrs() *LinkAttrs {
|
||||
return &xfrm.LinkAttrs
|
||||
}
|
||||
|
||||
func (xfrm *Xfrmi) Type() string {
|
||||
return "xfrm"
|
||||
}
|
||||
|
||||
// IPoIB interface
|
||||
|
||||
type IPoIBMode uint16
|
||||
|
||||
func (m *IPoIBMode) String() string {
|
||||
str, ok := iPoIBModeToString[*m]
|
||||
if !ok {
|
||||
return fmt.Sprintf("mode(%d)", *m)
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
const (
|
||||
IPOIB_MODE_DATAGRAM = iota
|
||||
IPOIB_MODE_CONNECTED
|
||||
)
|
||||
|
||||
var iPoIBModeToString = map[IPoIBMode]string{
|
||||
IPOIB_MODE_DATAGRAM: "datagram",
|
||||
IPOIB_MODE_CONNECTED: "connected",
|
||||
}
|
||||
|
||||
var StringToIPoIBMode = map[string]IPoIBMode{
|
||||
"datagram": IPOIB_MODE_DATAGRAM,
|
||||
"connected": IPOIB_MODE_CONNECTED,
|
||||
}
|
||||
|
||||
type IPoIB struct {
|
||||
LinkAttrs
|
||||
Pkey uint16
|
||||
Mode IPoIBMode
|
||||
Umcast uint16
|
||||
}
|
||||
|
||||
func (ipoib *IPoIB) Attrs() *LinkAttrs {
|
||||
return &ipoib.LinkAttrs
|
||||
}
|
||||
|
||||
func (ipoib *IPoIB) Type() string {
|
||||
return "ipoib"
|
||||
}
|
||||
|
||||
// iproute2 supported devices;
|
||||
// vlan | veth | vcan | dummy | ifb | macvlan | macvtap |
|
||||
// bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan |
|
||||
// gre | gretap | ip6gre | ip6gretap | vti | nlmon |
|
||||
// bond_slave | ipvlan
|
||||
// gre | gretap | ip6gre | ip6gretap | vti | vti6 | nlmon |
|
||||
// bond_slave | ipvlan | xfrm
|
||||
|
||||
// LinkNotFoundError wraps the various not found errors when
|
||||
// getting/reading links. This is intended for better error
|
||||
|
1124
vendor/github.com/vishvananda/netlink/link_linux.go
generated
vendored
1124
vendor/github.com/vishvananda/netlink/link_linux.go
generated
vendored
File diff suppressed because it is too large
Load Diff
7
vendor/github.com/vishvananda/netlink/neigh.go
generated
vendored
7
vendor/github.com/vishvananda/netlink/neigh.go
generated
vendored
@ -17,9 +17,16 @@ type Neigh struct {
|
||||
LLIPAddr net.IP //Used in the case of NHRP
|
||||
Vlan int
|
||||
VNI int
|
||||
MasterIndex int
|
||||
}
|
||||
|
||||
// String returns $ip/$hwaddr $label
|
||||
func (neigh *Neigh) String() string {
|
||||
return fmt.Sprintf("%s %s", neigh.IP, neigh.HardwareAddr)
|
||||
}
|
||||
|
||||
// NeighUpdate is sent when a neighbor changes - type is RTM_NEWNEIGH or RTM_DELNEIGH.
|
||||
type NeighUpdate struct {
|
||||
Type uint16
|
||||
Neigh
|
||||
}
|
||||
|
191
vendor/github.com/vishvananda/netlink/neigh_linux.go
generated
vendored
191
vendor/github.com/vishvananda/netlink/neigh_linux.go
generated
vendored
@ -1,10 +1,13 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
"github.com/vishvananda/netns"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
@ -18,7 +21,10 @@ const (
|
||||
NDA_PORT
|
||||
NDA_VNI
|
||||
NDA_IFINDEX
|
||||
NDA_MAX = NDA_IFINDEX
|
||||
NDA_MASTER
|
||||
NDA_LINK_NETNSID
|
||||
NDA_SRC_VNI
|
||||
NDA_MAX = NDA_SRC_VNI
|
||||
)
|
||||
|
||||
// Neighbor Cache Entry States.
|
||||
@ -43,6 +49,7 @@ const (
|
||||
NTF_ROUTER = 0x80
|
||||
)
|
||||
|
||||
// Ndmsg is for adding, removing or receiving information about a neighbor table entry
|
||||
type Ndmsg struct {
|
||||
Family uint8
|
||||
Index uint32
|
||||
@ -170,45 +177,58 @@ func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error {
|
||||
req.AddData(vniData)
|
||||
}
|
||||
|
||||
if neigh.MasterIndex != 0 {
|
||||
masterData := nl.NewRtAttr(NDA_MASTER, nl.Uint32Attr(uint32(neigh.MasterIndex)))
|
||||
req.AddData(masterData)
|
||||
}
|
||||
|
||||
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
// NeighList gets a list of IP-MAC mappings in the system (ARP table).
|
||||
// NeighList returns a list of IP-MAC mappings in the system (ARP table).
|
||||
// Equivalent to: `ip neighbor show`.
|
||||
// The list can be filtered by link and ip family.
|
||||
func NeighList(linkIndex, family int) ([]Neigh, error) {
|
||||
return pkgHandle.NeighList(linkIndex, family)
|
||||
}
|
||||
|
||||
// NeighProxyList gets a list of neighbor proxies in the system.
|
||||
// NeighProxyList returns a list of neighbor proxies in the system.
|
||||
// Equivalent to: `ip neighbor show proxy`.
|
||||
// The list can be filtered by link and ip family.
|
||||
func NeighProxyList(linkIndex, family int) ([]Neigh, error) {
|
||||
return pkgHandle.NeighProxyList(linkIndex, family)
|
||||
}
|
||||
|
||||
// NeighList gets a list of IP-MAC mappings in the system (ARP table).
|
||||
// NeighList returns a list of IP-MAC mappings in the system (ARP table).
|
||||
// Equivalent to: `ip neighbor show`.
|
||||
// The list can be filtered by link and ip family.
|
||||
func (h *Handle) NeighList(linkIndex, family int) ([]Neigh, error) {
|
||||
return h.neighList(linkIndex, family, 0)
|
||||
return h.NeighListExecute(Ndmsg{
|
||||
Family: uint8(family),
|
||||
Index: uint32(linkIndex),
|
||||
})
|
||||
}
|
||||
|
||||
// NeighProxyList gets a list of neighbor proxies in the system.
|
||||
// NeighProxyList returns a list of neighbor proxies in the system.
|
||||
// Equivalent to: `ip neighbor show proxy`.
|
||||
// The list can be filtered by link, ip family.
|
||||
func (h *Handle) NeighProxyList(linkIndex, family int) ([]Neigh, error) {
|
||||
return h.neighList(linkIndex, family, NTF_PROXY)
|
||||
}
|
||||
|
||||
func (h *Handle) neighList(linkIndex, family, flags int) ([]Neigh, error) {
|
||||
req := h.newNetlinkRequest(unix.RTM_GETNEIGH, unix.NLM_F_DUMP)
|
||||
msg := Ndmsg{
|
||||
return h.NeighListExecute(Ndmsg{
|
||||
Family: uint8(family),
|
||||
Index: uint32(linkIndex),
|
||||
Flags: uint8(flags),
|
||||
}
|
||||
Flags: NTF_PROXY,
|
||||
})
|
||||
}
|
||||
|
||||
// NeighListExecute returns a list of neighbour entries filtered by link, ip family, flag and state.
|
||||
func NeighListExecute(msg Ndmsg) ([]Neigh, error) {
|
||||
return pkgHandle.NeighListExecute(msg)
|
||||
}
|
||||
|
||||
// NeighListExecute returns a list of neighbour entries filtered by link, ip family, flag and state.
|
||||
func (h *Handle) NeighListExecute(msg Ndmsg) ([]Neigh, error) {
|
||||
req := h.newNetlinkRequest(unix.RTM_GETNEIGH, unix.NLM_F_DUMP)
|
||||
req.AddData(&msg)
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWNEIGH)
|
||||
@ -219,7 +239,7 @@ func (h *Handle) neighList(linkIndex, family, flags int) ([]Neigh, error) {
|
||||
var res []Neigh
|
||||
for _, m := range msgs {
|
||||
ndm := deserializeNdmsg(m)
|
||||
if linkIndex != 0 && int(ndm.Index) != linkIndex {
|
||||
if msg.Index != 0 && ndm.Index != msg.Index {
|
||||
// Ignore messages from other interfaces
|
||||
continue
|
||||
}
|
||||
@ -251,14 +271,6 @@ func NeighDeserialize(m []byte) (*Neigh, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// This should be cached for perfomance
|
||||
// once per table dump
|
||||
link, err := LinkByIndex(neigh.LinkIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
encapType := link.Attrs().EncapType
|
||||
|
||||
for _, attr := range attrs {
|
||||
switch attr.Attr.Type {
|
||||
case NDA_DST:
|
||||
@ -268,13 +280,16 @@ func NeighDeserialize(m []byte) (*Neigh, error) {
|
||||
// #define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len))
|
||||
// #define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
|
||||
attrLen := attr.Attr.Len - unix.SizeofRtAttr
|
||||
if attrLen == 4 && (encapType == "ipip" ||
|
||||
encapType == "sit" ||
|
||||
encapType == "gre") {
|
||||
if attrLen == 4 {
|
||||
neigh.LLIPAddr = net.IP(attr.Value)
|
||||
} else if attrLen == 16 &&
|
||||
encapType == "tunnel6" {
|
||||
neigh.IP = net.IP(attr.Value)
|
||||
} else if attrLen == 16 {
|
||||
// Can be IPv6 or FireWire HWAddr
|
||||
link, err := LinkByIndex(neigh.LinkIndex)
|
||||
if err == nil && link.Attrs().EncapType == "tunnel6" {
|
||||
neigh.IP = net.IP(attr.Value)
|
||||
} else {
|
||||
neigh.HardwareAddr = net.HardwareAddr(attr.Value)
|
||||
}
|
||||
} else {
|
||||
neigh.HardwareAddr = net.HardwareAddr(attr.Value)
|
||||
}
|
||||
@ -282,8 +297,126 @@ func NeighDeserialize(m []byte) (*Neigh, error) {
|
||||
neigh.Vlan = int(native.Uint16(attr.Value[0:2]))
|
||||
case NDA_VNI:
|
||||
neigh.VNI = int(native.Uint32(attr.Value[0:4]))
|
||||
case NDA_MASTER:
|
||||
neigh.MasterIndex = int(native.Uint32(attr.Value[0:4]))
|
||||
}
|
||||
}
|
||||
|
||||
return &neigh, nil
|
||||
}
|
||||
|
||||
// NeighSubscribe takes a chan down which notifications will be sent
|
||||
// when neighbors are added or deleted. Close the 'done' chan to stop subscription.
|
||||
func NeighSubscribe(ch chan<- NeighUpdate, done <-chan struct{}) error {
|
||||
return neighSubscribeAt(netns.None(), netns.None(), ch, done, nil, false)
|
||||
}
|
||||
|
||||
// NeighSubscribeAt works like NeighSubscribe plus it allows the caller
|
||||
// to choose the network namespace in which to subscribe (ns).
|
||||
func NeighSubscribeAt(ns netns.NsHandle, ch chan<- NeighUpdate, done <-chan struct{}) error {
|
||||
return neighSubscribeAt(ns, netns.None(), ch, done, nil, false)
|
||||
}
|
||||
|
||||
// NeighSubscribeOptions contains a set of options to use with
|
||||
// NeighSubscribeWithOptions.
|
||||
type NeighSubscribeOptions struct {
|
||||
Namespace *netns.NsHandle
|
||||
ErrorCallback func(error)
|
||||
ListExisting bool
|
||||
}
|
||||
|
||||
// NeighSubscribeWithOptions work like NeighSubscribe but enable to
|
||||
// provide additional options to modify the behavior. Currently, the
|
||||
// namespace can be provided as well as an error callback.
|
||||
func NeighSubscribeWithOptions(ch chan<- NeighUpdate, done <-chan struct{}, options NeighSubscribeOptions) error {
|
||||
if options.Namespace == nil {
|
||||
none := netns.None()
|
||||
options.Namespace = &none
|
||||
}
|
||||
return neighSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting)
|
||||
}
|
||||
|
||||
func neighSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- NeighUpdate, done <-chan struct{}, cberr func(error), listExisting bool) error {
|
||||
s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_NEIGH)
|
||||
makeRequest := func(family int) error {
|
||||
req := pkgHandle.newNetlinkRequest(unix.RTM_GETNEIGH,
|
||||
unix.NLM_F_DUMP)
|
||||
infmsg := nl.NewIfInfomsg(family)
|
||||
req.AddData(infmsg)
|
||||
if err := s.Send(req); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if done != nil {
|
||||
go func() {
|
||||
<-done
|
||||
s.Close()
|
||||
}()
|
||||
}
|
||||
if listExisting {
|
||||
if err := makeRequest(unix.AF_UNSPEC); err != nil {
|
||||
return err
|
||||
}
|
||||
// We have to wait for NLMSG_DONE before making AF_BRIDGE request
|
||||
}
|
||||
go func() {
|
||||
defer close(ch)
|
||||
for {
|
||||
msgs, from, err := s.Receive()
|
||||
if err != nil {
|
||||
if cberr != nil {
|
||||
cberr(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if from.Pid != nl.PidKernel {
|
||||
if cberr != nil {
|
||||
cberr(fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel))
|
||||
}
|
||||
continue
|
||||
}
|
||||
for _, m := range msgs {
|
||||
if m.Header.Type == unix.NLMSG_DONE {
|
||||
if listExisting {
|
||||
// This will be called after handling AF_UNSPEC
|
||||
// list request, we have to wait for NLMSG_DONE
|
||||
// before making another request
|
||||
if err := makeRequest(unix.AF_BRIDGE); err != nil {
|
||||
if cberr != nil {
|
||||
cberr(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
listExisting = false
|
||||
}
|
||||
continue
|
||||
}
|
||||
if m.Header.Type == unix.NLMSG_ERROR {
|
||||
native := nl.NativeEndian()
|
||||
error := int32(native.Uint32(m.Data[0:4]))
|
||||
if error == 0 {
|
||||
continue
|
||||
}
|
||||
if cberr != nil {
|
||||
cberr(syscall.Errno(-error))
|
||||
}
|
||||
return
|
||||
}
|
||||
neigh, err := NeighDeserialize(m.Data)
|
||||
if err != nil {
|
||||
if cberr != nil {
|
||||
cberr(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
ch <- NeighUpdate{Type: m.Header.Type, Neigh: *neigh}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
3
vendor/github.com/vishvananda/netlink/netlink.go
generated
vendored
3
vendor/github.com/vishvananda/netlink/netlink.go
generated
vendored
@ -27,7 +27,8 @@ func ParseIPNet(s string) (*net.IPNet, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &net.IPNet{IP: ip, Mask: ipNet.Mask}, nil
|
||||
ipNet.IP = ip
|
||||
return ipNet, nil
|
||||
}
|
||||
|
||||
// NewIPNet generates an IPNet from an ip address using a netmask of 32 or 128.
|
||||
|
12
vendor/github.com/vishvananda/netlink/netlink_unspecified.go
generated
vendored
12
vendor/github.com/vishvananda/netlink/netlink_unspecified.go
generated
vendored
@ -48,10 +48,18 @@ func LinkSetVfVlan(link Link, vf, vlan int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetVfVlanQos(link Link, vf, vlan, qos int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetVfTxRate(link Link, vf, rate int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetVfRate(link Link, vf, minRate, maxRate int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetNoMaster(link Link) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
@ -152,6 +160,10 @@ func AddrAdd(link Link, addr *Addr) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func AddrReplace(link Link, addr *Addr) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func AddrDel(link Link, addr *Addr) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
141
vendor/github.com/vishvananda/netlink/netns_linux.go
generated
vendored
Normal file
141
vendor/github.com/vishvananda/netlink/netns_linux.go
generated
vendored
Normal file
@ -0,0 +1,141 @@
|
||||
package netlink
|
||||
|
||||
// Network namespace ID functions
|
||||
//
|
||||
// The kernel has a weird concept called the network namespace ID.
|
||||
// This is different from the file reference in proc (and any bind-mounted
|
||||
// namespaces, etc.)
|
||||
//
|
||||
// Instead, namespaces can be assigned a numeric ID at any time. Once set,
|
||||
// the ID is fixed. The ID can either be set manually by the user, or
|
||||
// automatically, triggered by certain kernel actions. The most common kernel
|
||||
// action that triggers namespace ID creation is moving one end of a veth pair
|
||||
// in to that namespace.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// These can be replaced by the values from sys/unix when it is next released.
|
||||
const (
|
||||
_ = iota
|
||||
NETNSA_NSID
|
||||
NETNSA_PID
|
||||
NETNSA_FD
|
||||
)
|
||||
|
||||
// GetNetNsIdByPid looks up the network namespace ID for a given pid (really thread id).
|
||||
// Returns -1 if the namespace does not have an ID set.
|
||||
func (h *Handle) GetNetNsIdByPid(pid int) (int, error) {
|
||||
return h.getNetNsId(NETNSA_PID, uint32(pid))
|
||||
}
|
||||
|
||||
// GetNetNsIdByPid looks up the network namespace ID for a given pid (really thread id).
|
||||
// Returns -1 if the namespace does not have an ID set.
|
||||
func GetNetNsIdByPid(pid int) (int, error) {
|
||||
return pkgHandle.GetNetNsIdByPid(pid)
|
||||
}
|
||||
|
||||
// SetNetNSIdByPid sets the ID of the network namespace for a given pid (really thread id).
|
||||
// The ID can only be set for namespaces without an ID already set.
|
||||
func (h *Handle) SetNetNsIdByPid(pid, nsid int) error {
|
||||
return h.setNetNsId(NETNSA_PID, uint32(pid), uint32(nsid))
|
||||
}
|
||||
|
||||
// SetNetNSIdByPid sets the ID of the network namespace for a given pid (really thread id).
|
||||
// The ID can only be set for namespaces without an ID already set.
|
||||
func SetNetNsIdByPid(pid, nsid int) error {
|
||||
return pkgHandle.SetNetNsIdByPid(pid, nsid)
|
||||
}
|
||||
|
||||
// GetNetNsIdByFd looks up the network namespace ID for a given fd.
|
||||
// fd must be an open file descriptor to a namespace file.
|
||||
// Returns -1 if the namespace does not have an ID set.
|
||||
func (h *Handle) GetNetNsIdByFd(fd int) (int, error) {
|
||||
return h.getNetNsId(NETNSA_FD, uint32(fd))
|
||||
}
|
||||
|
||||
// GetNetNsIdByFd looks up the network namespace ID for a given fd.
|
||||
// fd must be an open file descriptor to a namespace file.
|
||||
// Returns -1 if the namespace does not have an ID set.
|
||||
func GetNetNsIdByFd(fd int) (int, error) {
|
||||
return pkgHandle.GetNetNsIdByFd(fd)
|
||||
}
|
||||
|
||||
// SetNetNSIdByFd sets the ID of the network namespace for a given fd.
|
||||
// fd must be an open file descriptor to a namespace file.
|
||||
// The ID can only be set for namespaces without an ID already set.
|
||||
func (h *Handle) SetNetNsIdByFd(fd, nsid int) error {
|
||||
return h.setNetNsId(NETNSA_FD, uint32(fd), uint32(nsid))
|
||||
}
|
||||
|
||||
// SetNetNSIdByFd sets the ID of the network namespace for a given fd.
|
||||
// fd must be an open file descriptor to a namespace file.
|
||||
// The ID can only be set for namespaces without an ID already set.
|
||||
func SetNetNsIdByFd(fd, nsid int) error {
|
||||
return pkgHandle.SetNetNsIdByFd(fd, nsid)
|
||||
}
|
||||
|
||||
// getNetNsId requests the netnsid for a given type-val pair
|
||||
// type should be either NETNSA_PID or NETNSA_FD
|
||||
func (h *Handle) getNetNsId(attrType int, val uint32) (int, error) {
|
||||
req := h.newNetlinkRequest(unix.RTM_GETNSID, unix.NLM_F_REQUEST)
|
||||
|
||||
rtgen := nl.NewRtGenMsg()
|
||||
req.AddData(rtgen)
|
||||
|
||||
b := make([]byte, 4, 4)
|
||||
native.PutUint32(b, val)
|
||||
attr := nl.NewRtAttr(attrType, b)
|
||||
req.AddData(attr)
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWNSID)
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
for _, m := range msgs {
|
||||
msg := nl.DeserializeRtGenMsg(m)
|
||||
|
||||
attrs, err := nl.ParseRouteAttr(m[msg.Len():])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
for _, attr := range attrs {
|
||||
switch attr.Attr.Type {
|
||||
case NETNSA_NSID:
|
||||
return int(int32(native.Uint32(attr.Value))), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf("unexpected empty result")
|
||||
}
|
||||
|
||||
// setNetNsId sets the netnsid for a given type-val pair
|
||||
// type should be either NETNSA_PID or NETNSA_FD
|
||||
// The ID can only be set for namespaces without an ID already set
|
||||
func (h *Handle) setNetNsId(attrType int, val uint32, newnsid uint32) error {
|
||||
req := h.newNetlinkRequest(unix.RTM_NEWNSID, unix.NLM_F_REQUEST|unix.NLM_F_ACK)
|
||||
|
||||
rtgen := nl.NewRtGenMsg()
|
||||
req.AddData(rtgen)
|
||||
|
||||
b := make([]byte, 4, 4)
|
||||
native.PutUint32(b, val)
|
||||
attr := nl.NewRtAttr(attrType, b)
|
||||
req.AddData(attr)
|
||||
|
||||
b1 := make([]byte, 4, 4)
|
||||
native.PutUint32(b1, newnsid)
|
||||
attr1 := nl.NewRtAttr(NETNSA_NSID, b1)
|
||||
req.AddData(attr1)
|
||||
|
||||
_, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWNSID)
|
||||
return err
|
||||
}
|
19
vendor/github.com/vishvananda/netlink/netns_unspecified.go
generated
vendored
Normal file
19
vendor/github.com/vishvananda/netlink/netns_unspecified.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
// +build !linux
|
||||
|
||||
package netlink
|
||||
|
||||
func GetNetNsIdByPid(pid int) (int, error) {
|
||||
return 0, ErrNotImplemented
|
||||
}
|
||||
|
||||
func SetNetNsIdByPid(pid, nsid int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func GetNetNsIdByFd(fd int) (int, error) {
|
||||
return 0, ErrNotImplemented
|
||||
}
|
||||
|
||||
func SetNetNsIdByFd(fd, nsid int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
4
vendor/github.com/vishvananda/netlink/nl/bridge_linux.go
generated
vendored
4
vendor/github.com/vishvananda/netlink/nl/bridge_linux.go
generated
vendored
@ -11,8 +11,8 @@ const (
|
||||
|
||||
/* Bridge Flags */
|
||||
const (
|
||||
BRIDGE_FLAGS_MASTER = iota /* Bridge command to/from master */
|
||||
BRIDGE_FLAGS_SELF /* Bridge command to/from lowerdev */
|
||||
BRIDGE_FLAGS_MASTER = iota + 1 /* Bridge command to/from master */
|
||||
BRIDGE_FLAGS_SELF /* Bridge command to/from lowerdev */
|
||||
)
|
||||
|
||||
/* Bridge management nested attributes
|
||||
|
40
vendor/github.com/vishvananda/netlink/nl/conntrack_linux.go
generated
vendored
40
vendor/github.com/vishvananda/netlink/nl/conntrack_linux.go
generated
vendored
@ -76,12 +76,17 @@ const (
|
||||
// __CTA_MAX
|
||||
// };
|
||||
const (
|
||||
CTA_TUPLE_ORIG = 1
|
||||
CTA_TUPLE_REPLY = 2
|
||||
CTA_STATUS = 3
|
||||
CTA_TIMEOUT = 7
|
||||
CTA_MARK = 8
|
||||
CTA_PROTOINFO = 4
|
||||
CTA_TUPLE_ORIG = 1
|
||||
CTA_TUPLE_REPLY = 2
|
||||
CTA_STATUS = 3
|
||||
CTA_PROTOINFO = 4
|
||||
CTA_TIMEOUT = 7
|
||||
CTA_MARK = 8
|
||||
CTA_COUNTERS_ORIG = 9
|
||||
CTA_COUNTERS_REPLY = 10
|
||||
CTA_USE = 11
|
||||
CTA_ID = 12
|
||||
CTA_TIMESTAMP = 20
|
||||
)
|
||||
|
||||
// enum ctattr_tuple {
|
||||
@ -163,6 +168,29 @@ const (
|
||||
CTA_PROTOINFO_TCP_FLAGS_REPLY = 5
|
||||
)
|
||||
|
||||
// enum ctattr_counters {
|
||||
// CTA_COUNTERS_UNSPEC,
|
||||
// CTA_COUNTERS_PACKETS, /* 64bit counters */
|
||||
// CTA_COUNTERS_BYTES, /* 64bit counters */
|
||||
// CTA_COUNTERS32_PACKETS, /* old 32bit counters, unused */
|
||||
// CTA_COUNTERS32_BYTES, /* old 32bit counters, unused */
|
||||
// CTA_COUNTERS_PAD,
|
||||
// __CTA_COUNTERS_M
|
||||
// };
|
||||
// #define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1)
|
||||
const (
|
||||
CTA_COUNTERS_PACKETS = 1
|
||||
CTA_COUNTERS_BYTES = 2
|
||||
)
|
||||
|
||||
// enum CTA TIMESTAMP TLVs
|
||||
// CTA_TIMESTAMP_START /* 64bit value */
|
||||
// CTA_TIMESTAMP_STOP /* 64bit value */
|
||||
const (
|
||||
CTA_TIMESTAMP_START = 1
|
||||
CTA_TIMESTAMP_STOP = 2
|
||||
)
|
||||
|
||||
// /* General form of address family dependent message.
|
||||
// */
|
||||
// struct nfgenmsg {
|
||||
|
40
vendor/github.com/vishvananda/netlink/nl/devlink_linux.go
generated
vendored
Normal file
40
vendor/github.com/vishvananda/netlink/nl/devlink_linux.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
package nl
|
||||
|
||||
// All the following constants are coming from:
|
||||
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/devlink.h
|
||||
|
||||
const (
|
||||
GENL_DEVLINK_VERSION = 1
|
||||
GENL_DEVLINK_NAME = "devlink"
|
||||
)
|
||||
|
||||
const (
|
||||
DEVLINK_CMD_GET = 1
|
||||
DEVLINK_CMD_ESWITCH_GET = 29
|
||||
DEVLINK_CMD_ESWITCH_SET = 30
|
||||
)
|
||||
|
||||
const (
|
||||
DEVLINK_ATTR_BUS_NAME = 1
|
||||
DEVLINK_ATTR_DEV_NAME = 2
|
||||
DEVLINK_ATTR_ESWITCH_MODE = 25
|
||||
DEVLINK_ATTR_ESWITCH_INLINE_MODE = 26
|
||||
DEVLINK_ATTR_ESWITCH_ENCAP_MODE = 62
|
||||
)
|
||||
|
||||
const (
|
||||
DEVLINK_ESWITCH_MODE_LEGACY = 0
|
||||
DEVLINK_ESWITCH_MODE_SWITCHDEV = 1
|
||||
)
|
||||
|
||||
const (
|
||||
DEVLINK_ESWITCH_INLINE_MODE_NONE = 0
|
||||
DEVLINK_ESWITCH_INLINE_MODE_LINK = 1
|
||||
DEVLINK_ESWITCH_INLINE_MODE_NETWORK = 2
|
||||
DEVLINK_ESWITCH_INLINE_MODE_TRANSPORT = 3
|
||||
)
|
||||
|
||||
const (
|
||||
DEVLINK_ESWITCH_ENCAP_MODE_NONE = 0
|
||||
DEVLINK_ESWITCH_ENCAP_MODE_BASIC = 1
|
||||
)
|
72
vendor/github.com/vishvananda/netlink/nl/link_linux.go
generated
vendored
72
vendor/github.com/vishvananda/netlink/nl/link_linux.go
generated
vendored
@ -13,7 +13,9 @@ const (
|
||||
IFLA_INFO_KIND
|
||||
IFLA_INFO_DATA
|
||||
IFLA_INFO_XSTATS
|
||||
IFLA_INFO_MAX = IFLA_INFO_XSTATS
|
||||
IFLA_INFO_SLAVE_KIND
|
||||
IFLA_INFO_SLAVE_DATA
|
||||
IFLA_INFO_MAX = IFLA_INFO_SLAVE_DATA
|
||||
)
|
||||
|
||||
const (
|
||||
@ -87,7 +89,8 @@ const (
|
||||
const (
|
||||
IFLA_IPVLAN_UNSPEC = iota
|
||||
IFLA_IPVLAN_MODE
|
||||
IFLA_IPVLAN_MAX = IFLA_IPVLAN_MODE
|
||||
IFLA_IPVLAN_FLAG
|
||||
IFLA_IPVLAN_MAX = IFLA_IPVLAN_FLAG
|
||||
)
|
||||
|
||||
const (
|
||||
@ -164,6 +167,8 @@ const (
|
||||
IFLA_BOND_SLAVE_PERM_HWADDR
|
||||
IFLA_BOND_SLAVE_QUEUE_ID
|
||||
IFLA_BOND_SLAVE_AD_AGGREGATOR_ID
|
||||
IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE
|
||||
IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE
|
||||
)
|
||||
|
||||
const (
|
||||
@ -217,9 +222,11 @@ const (
|
||||
IFLA_VF_RSS_QUERY_EN /* RSS Redirection Table and Hash Key query
|
||||
* on/off switch
|
||||
*/
|
||||
IFLA_VF_STATS /* network device statistics */
|
||||
IFLA_VF_TRUST /* Trust state of VF */
|
||||
IFLA_VF_MAX = IFLA_VF_TRUST
|
||||
IFLA_VF_STATS /* network device statistics */
|
||||
IFLA_VF_TRUST /* Trust state of VF */
|
||||
IFLA_VF_IB_NODE_GUID /* VF Infiniband node GUID */
|
||||
IFLA_VF_IB_PORT_GUID /* VF Infiniband port GUID */
|
||||
IFLA_VF_MAX = IFLA_VF_IB_PORT_GUID
|
||||
)
|
||||
|
||||
const (
|
||||
@ -248,6 +255,7 @@ const (
|
||||
SizeofVfLinkState = 0x08
|
||||
SizeofVfRssQueryEn = 0x08
|
||||
SizeofVfTrust = 0x08
|
||||
SizeofVfGUID = 0x10
|
||||
)
|
||||
|
||||
// struct ifla_vf_mac {
|
||||
@ -430,6 +438,30 @@ func (msg *VfTrust) Serialize() []byte {
|
||||
return (*(*[SizeofVfTrust]byte)(unsafe.Pointer(msg)))[:]
|
||||
}
|
||||
|
||||
// struct ifla_vf_guid {
|
||||
// __u32 vf;
|
||||
// __u32 rsvd;
|
||||
// __u64 guid;
|
||||
// };
|
||||
|
||||
type VfGUID struct {
|
||||
Vf uint32
|
||||
Rsvd uint32
|
||||
GUID uint64
|
||||
}
|
||||
|
||||
func (msg *VfGUID) Len() int {
|
||||
return SizeofVfGUID
|
||||
}
|
||||
|
||||
func DeserializeVfGUID(b []byte) *VfGUID {
|
||||
return (*VfGUID)(unsafe.Pointer(&b[0:SizeofVfGUID][0]))
|
||||
}
|
||||
|
||||
func (msg *VfGUID) Serialize() []byte {
|
||||
return (*(*[SizeofVfGUID]byte)(unsafe.Pointer(msg)))[:]
|
||||
}
|
||||
|
||||
const (
|
||||
XDP_FLAGS_UPDATE_IF_NOEXIST = 1 << iota
|
||||
XDP_FLAGS_SKB_MODE
|
||||
@ -546,3 +578,33 @@ const (
|
||||
GTP_ROLE_GGSN = iota
|
||||
GTP_ROLE_SGSN
|
||||
)
|
||||
|
||||
const (
|
||||
IFLA_XFRM_UNSPEC = iota
|
||||
IFLA_XFRM_LINK
|
||||
IFLA_XFRM_IF_ID
|
||||
|
||||
IFLA_XFRM_MAX = iota - 1
|
||||
)
|
||||
|
||||
const (
|
||||
IFLA_TUN_UNSPEC = iota
|
||||
IFLA_TUN_OWNER
|
||||
IFLA_TUN_GROUP
|
||||
IFLA_TUN_TYPE
|
||||
IFLA_TUN_PI
|
||||
IFLA_TUN_VNET_HDR
|
||||
IFLA_TUN_PERSIST
|
||||
IFLA_TUN_MULTI_QUEUE
|
||||
IFLA_TUN_NUM_QUEUES
|
||||
IFLA_TUN_NUM_DISABLED_QUEUES
|
||||
IFLA_TUN_MAX = IFLA_TUN_NUM_DISABLED_QUEUES
|
||||
)
|
||||
|
||||
const (
|
||||
IFLA_IPOIB_UNSPEC = iota
|
||||
IFLA_IPOIB_PKEY
|
||||
IFLA_IPOIB_MODE
|
||||
IFLA_IPOIB_UMCAST
|
||||
IFLA_IPOIB_MAX = IFLA_IPOIB_UMCAST
|
||||
)
|
||||
|
66
vendor/github.com/vishvananda/netlink/nl/nl_linux.go
generated
vendored
66
vendor/github.com/vishvananda/netlink/nl/nl_linux.go
generated
vendored
@ -21,7 +21,13 @@ const (
|
||||
FAMILY_ALL = unix.AF_UNSPEC
|
||||
FAMILY_V4 = unix.AF_INET
|
||||
FAMILY_V6 = unix.AF_INET6
|
||||
FAMILY_MPLS = AF_MPLS
|
||||
FAMILY_MPLS = unix.AF_MPLS
|
||||
// Arbitrary set value (greater than default 4k) to allow receiving
|
||||
// from kernel more verbose messages e.g. for statistics,
|
||||
// tc rules or filters, or other more memory requiring data.
|
||||
RECEIVE_BUFFER_SIZE = 65536
|
||||
// Kernel netlink pid
|
||||
PidKernel uint32 = 0
|
||||
)
|
||||
|
||||
// SupportedNlFamilies contains the list of netlink families this netlink package supports
|
||||
@ -42,7 +48,7 @@ func GetIPFamily(ip net.IP) int {
|
||||
|
||||
var nativeEndian binary.ByteOrder
|
||||
|
||||
// Get native endianness for the system
|
||||
// NativeEndian gets native endianness for the system
|
||||
func NativeEndian() binary.ByteOrder {
|
||||
if nativeEndian == nil {
|
||||
var x uint32 = 0x01020304
|
||||
@ -271,15 +277,22 @@ func NewRtAttr(attrType int, data []byte) *RtAttr {
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new RtAttr obj anc add it as a child of an existing object
|
||||
// NewRtAttrChild adds an RtAttr as a child to the parent and returns the new attribute
|
||||
//
|
||||
// Deprecated: Use AddRtAttr() on the parent object
|
||||
func NewRtAttrChild(parent *RtAttr, attrType int, data []byte) *RtAttr {
|
||||
return parent.AddRtAttr(attrType, data)
|
||||
}
|
||||
|
||||
// AddRtAttr adds an RtAttr as a child and returns the new attribute
|
||||
func (a *RtAttr) AddRtAttr(attrType int, data []byte) *RtAttr {
|
||||
attr := NewRtAttr(attrType, data)
|
||||
parent.children = append(parent.children, attr)
|
||||
a.children = append(a.children, attr)
|
||||
return attr
|
||||
}
|
||||
|
||||
// AddChild adds an existing RtAttr as a child.
|
||||
func (a *RtAttr) AddChild(attr *RtAttr) {
|
||||
// AddChild adds an existing NetlinkRequestData as a child.
|
||||
func (a *RtAttr) AddChild(attr NetlinkRequestData) {
|
||||
a.children = append(a.children, attr)
|
||||
}
|
||||
|
||||
@ -360,16 +373,12 @@ func (req *NetlinkRequest) Serialize() []byte {
|
||||
}
|
||||
|
||||
func (req *NetlinkRequest) AddData(data NetlinkRequestData) {
|
||||
if data != nil {
|
||||
req.Data = append(req.Data, data)
|
||||
}
|
||||
req.Data = append(req.Data, data)
|
||||
}
|
||||
|
||||
// AddRawData adds raw bytes to the end of the NetlinkRequest object during serialization
|
||||
func (req *NetlinkRequest) AddRawData(data []byte) {
|
||||
if data != nil {
|
||||
req.RawData = append(req.RawData, data...)
|
||||
}
|
||||
req.RawData = append(req.RawData, data...)
|
||||
}
|
||||
|
||||
// Execute the request against a the given sockType.
|
||||
@ -413,10 +422,13 @@ func (req *NetlinkRequest) Execute(sockType int, resType uint16) ([][]byte, erro
|
||||
|
||||
done:
|
||||
for {
|
||||
msgs, err := s.Receive()
|
||||
msgs, from, err := s.Receive()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if from.Pid != PidKernel {
|
||||
return nil, fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, PidKernel)
|
||||
}
|
||||
for _, m := range msgs {
|
||||
if m.Header.Seq != req.Seq {
|
||||
if sharedSocket {
|
||||
@ -425,7 +437,7 @@ done:
|
||||
return nil, fmt.Errorf("Wrong Seq nr %d, expected %d", m.Header.Seq, req.Seq)
|
||||
}
|
||||
if m.Header.Pid != pid {
|
||||
return nil, fmt.Errorf("Wrong pid %d, expected %d", m.Header.Pid, pid)
|
||||
continue
|
||||
}
|
||||
if m.Header.Type == unix.NLMSG_DONE {
|
||||
break done
|
||||
@ -610,21 +622,31 @@ func (s *NetlinkSocket) Send(request *NetlinkRequest) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, error) {
|
||||
func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, *unix.SockaddrNetlink, error) {
|
||||
fd := int(atomic.LoadInt32(&s.fd))
|
||||
if fd < 0 {
|
||||
return nil, fmt.Errorf("Receive called on a closed socket")
|
||||
return nil, nil, fmt.Errorf("Receive called on a closed socket")
|
||||
}
|
||||
rb := make([]byte, unix.Getpagesize())
|
||||
nr, _, err := unix.Recvfrom(fd, rb, 0)
|
||||
var fromAddr *unix.SockaddrNetlink
|
||||
var rb [RECEIVE_BUFFER_SIZE]byte
|
||||
nr, from, err := unix.Recvfrom(fd, rb[:], 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
fromAddr, ok := from.(*unix.SockaddrNetlink)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("Error converting to netlink sockaddr")
|
||||
}
|
||||
if nr < unix.NLMSG_HDRLEN {
|
||||
return nil, fmt.Errorf("Got short response from netlink")
|
||||
return nil, nil, fmt.Errorf("Got short response from netlink")
|
||||
}
|
||||
rb = rb[:nr]
|
||||
return syscall.ParseNetlinkMessage(rb)
|
||||
rb2 := make([]byte, nr)
|
||||
copy(rb2, rb[:nr])
|
||||
nl, err := syscall.ParseNetlinkMessage(rb2)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return nl, fromAddr, nil
|
||||
}
|
||||
|
||||
// SetSendTimeout allows to set a send timeout on the socket
|
||||
|
35
vendor/github.com/vishvananda/netlink/nl/rdma_link_linux.go
generated
vendored
Normal file
35
vendor/github.com/vishvananda/netlink/nl/rdma_link_linux.go
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
package nl
|
||||
|
||||
const (
|
||||
RDMA_NL_GET_CLIENT_SHIFT = 10
|
||||
)
|
||||
|
||||
const (
|
||||
RDMA_NL_NLDEV = 5
|
||||
)
|
||||
|
||||
const (
|
||||
RDMA_NLDEV_CMD_GET = 1
|
||||
RDMA_NLDEV_CMD_SET = 2
|
||||
RDMA_NLDEV_CMD_SYS_GET = 6
|
||||
RDMA_NLDEV_CMD_SYS_SET = 7
|
||||
)
|
||||
|
||||
const (
|
||||
RDMA_NLDEV_ATTR_DEV_INDEX = 1
|
||||
RDMA_NLDEV_ATTR_DEV_NAME = 2
|
||||
RDMA_NLDEV_ATTR_PORT_INDEX = 3
|
||||
RDMA_NLDEV_ATTR_CAP_FLAGS = 4
|
||||
RDMA_NLDEV_ATTR_FW_VERSION = 5
|
||||
RDMA_NLDEV_ATTR_NODE_GUID = 6
|
||||
RDMA_NLDEV_ATTR_SYS_IMAGE_GUID = 7
|
||||
RDMA_NLDEV_ATTR_SUBNET_PREFIX = 8
|
||||
RDMA_NLDEV_ATTR_LID = 9
|
||||
RDMA_NLDEV_ATTR_SM_LID = 10
|
||||
RDMA_NLDEV_ATTR_LMC = 11
|
||||
RDMA_NLDEV_ATTR_PORT_STATE = 12
|
||||
RDMA_NLDEV_ATTR_PORT_PHYS_STATE = 13
|
||||
RDMA_NLDEV_ATTR_DEV_NODE_TYPE = 14
|
||||
RDMA_NLDEV_SYS_ATTR_NETNS_MODE = 66
|
||||
RDMA_NLDEV_NET_NS_FD = 68
|
||||
)
|
26
vendor/github.com/vishvananda/netlink/nl/route_linux.go
generated
vendored
26
vendor/github.com/vishvananda/netlink/nl/route_linux.go
generated
vendored
@ -79,3 +79,29 @@ func (msg *RtNexthop) Serialize() []byte {
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
type RtGenMsg struct {
|
||||
unix.RtGenmsg
|
||||
}
|
||||
|
||||
func NewRtGenMsg() *RtGenMsg {
|
||||
return &RtGenMsg{
|
||||
RtGenmsg: unix.RtGenmsg{
|
||||
Family: unix.AF_UNSPEC,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (msg *RtGenMsg) Len() int {
|
||||
return rtaAlignOf(unix.SizeofRtGenmsg)
|
||||
}
|
||||
|
||||
func DeserializeRtGenMsg(b []byte) *RtGenMsg {
|
||||
return &RtGenMsg{RtGenmsg: unix.RtGenmsg{Family: b[0]}}
|
||||
}
|
||||
|
||||
func (msg *RtGenMsg) Serialize() []byte {
|
||||
out := make([]byte, msg.Len())
|
||||
out[0] = msg.Family
|
||||
return out
|
||||
}
|
||||
|
43
vendor/github.com/vishvananda/netlink/nl/seg6_linux.go
generated
vendored
43
vendor/github.com/vishvananda/netlink/nl/seg6_linux.go
generated
vendored
@ -99,6 +99,49 @@ func DecodeSEG6Encap(buf []byte) (int, []net.IP, error) {
|
||||
return mode, srh.Segments, nil
|
||||
}
|
||||
|
||||
func DecodeSEG6Srh(buf []byte) ([]net.IP, error) {
|
||||
native := NativeEndian()
|
||||
srh := IPv6SrHdr{
|
||||
nextHdr: buf[0],
|
||||
hdrLen: buf[1],
|
||||
routingType: buf[2],
|
||||
segmentsLeft: buf[3],
|
||||
firstSegment: buf[4],
|
||||
flags: buf[5],
|
||||
reserved: native.Uint16(buf[6:8]),
|
||||
}
|
||||
buf = buf[8:]
|
||||
if len(buf)%16 != 0 {
|
||||
err := fmt.Errorf("DecodeSEG6Srh: error parsing Segment List (buf len: %d)", len(buf))
|
||||
return nil, err
|
||||
}
|
||||
for len(buf) > 0 {
|
||||
srh.Segments = append(srh.Segments, net.IP(buf[:16]))
|
||||
buf = buf[16:]
|
||||
}
|
||||
return srh.Segments, nil
|
||||
}
|
||||
func EncodeSEG6Srh(segments []net.IP) ([]byte, error) {
|
||||
nsegs := len(segments) // nsegs: number of segments
|
||||
if nsegs == 0 {
|
||||
return nil, errors.New("EncodeSEG6Srh: No Segments")
|
||||
}
|
||||
b := make([]byte, 8, 8+len(segments)*16)
|
||||
native := NativeEndian()
|
||||
b[0] = 0 // srh.nextHdr (0 when calling netlink)
|
||||
b[1] = uint8(16 * nsegs >> 3) // srh.hdrLen (in 8-octets unit)
|
||||
b[2] = IPV6_SRCRT_TYPE_4 // srh.routingType (assigned by IANA)
|
||||
b[3] = uint8(nsegs - 1) // srh.segmentsLeft
|
||||
b[4] = uint8(nsegs - 1) // srh.firstSegment
|
||||
b[5] = 0 // srh.flags (SR6_FLAG1_HMAC for srh_hmac)
|
||||
// srh.reserved: Defined as "Tag" in draft-ietf-6man-segment-routing-header-07
|
||||
native.PutUint16(b[6:], 0) // srh.reserved
|
||||
for _, netIP := range segments {
|
||||
b = append(b, netIP...) // srh.Segments
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
func SEG6EncapModeString(mode int) string {
|
||||
switch mode {
|
||||
|
76
vendor/github.com/vishvananda/netlink/nl/seg6local_linux.go
generated
vendored
Normal file
76
vendor/github.com/vishvananda/netlink/nl/seg6local_linux.go
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
package nl
|
||||
|
||||
import ()
|
||||
|
||||
// seg6local parameters
|
||||
const (
|
||||
SEG6_LOCAL_UNSPEC = iota
|
||||
SEG6_LOCAL_ACTION
|
||||
SEG6_LOCAL_SRH
|
||||
SEG6_LOCAL_TABLE
|
||||
SEG6_LOCAL_NH4
|
||||
SEG6_LOCAL_NH6
|
||||
SEG6_LOCAL_IIF
|
||||
SEG6_LOCAL_OIF
|
||||
__SEG6_LOCAL_MAX
|
||||
)
|
||||
const (
|
||||
SEG6_LOCAL_MAX = __SEG6_LOCAL_MAX
|
||||
)
|
||||
|
||||
// seg6local actions
|
||||
const (
|
||||
SEG6_LOCAL_ACTION_END = iota + 1 // 1
|
||||
SEG6_LOCAL_ACTION_END_X // 2
|
||||
SEG6_LOCAL_ACTION_END_T // 3
|
||||
SEG6_LOCAL_ACTION_END_DX2 // 4
|
||||
SEG6_LOCAL_ACTION_END_DX6 // 5
|
||||
SEG6_LOCAL_ACTION_END_DX4 // 6
|
||||
SEG6_LOCAL_ACTION_END_DT6 // 7
|
||||
SEG6_LOCAL_ACTION_END_DT4 // 8
|
||||
SEG6_LOCAL_ACTION_END_B6 // 9
|
||||
SEG6_LOCAL_ACTION_END_B6_ENCAPS // 10
|
||||
SEG6_LOCAL_ACTION_END_BM // 11
|
||||
SEG6_LOCAL_ACTION_END_S // 12
|
||||
SEG6_LOCAL_ACTION_END_AS // 13
|
||||
SEG6_LOCAL_ACTION_END_AM // 14
|
||||
__SEG6_LOCAL_ACTION_MAX
|
||||
)
|
||||
const (
|
||||
SEG6_LOCAL_ACTION_MAX = __SEG6_LOCAL_ACTION_MAX - 1
|
||||
)
|
||||
|
||||
// Helper functions
|
||||
func SEG6LocalActionString(action int) string {
|
||||
switch action {
|
||||
case SEG6_LOCAL_ACTION_END:
|
||||
return "End"
|
||||
case SEG6_LOCAL_ACTION_END_X:
|
||||
return "End.X"
|
||||
case SEG6_LOCAL_ACTION_END_T:
|
||||
return "End.T"
|
||||
case SEG6_LOCAL_ACTION_END_DX2:
|
||||
return "End.DX2"
|
||||
case SEG6_LOCAL_ACTION_END_DX6:
|
||||
return "End.DX6"
|
||||
case SEG6_LOCAL_ACTION_END_DX4:
|
||||
return "End.DX4"
|
||||
case SEG6_LOCAL_ACTION_END_DT6:
|
||||
return "End.DT6"
|
||||
case SEG6_LOCAL_ACTION_END_DT4:
|
||||
return "End.DT4"
|
||||
case SEG6_LOCAL_ACTION_END_B6:
|
||||
return "End.B6"
|
||||
case SEG6_LOCAL_ACTION_END_B6_ENCAPS:
|
||||
return "End.B6.Encaps"
|
||||
case SEG6_LOCAL_ACTION_END_BM:
|
||||
return "End.BM"
|
||||
case SEG6_LOCAL_ACTION_END_S:
|
||||
return "End.S"
|
||||
case SEG6_LOCAL_ACTION_END_AS:
|
||||
return "End.AS"
|
||||
case SEG6_LOCAL_ACTION_END_AM:
|
||||
return "End.AM"
|
||||
}
|
||||
return "unknown"
|
||||
}
|
11
vendor/github.com/vishvananda/netlink/nl/syscall.go
generated
vendored
11
vendor/github.com/vishvananda/netlink/nl/syscall.go
generated
vendored
@ -42,16 +42,6 @@ const (
|
||||
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
|
||||
@ -67,6 +57,7 @@ const (
|
||||
LWTUNNEL_ENCAP_IP6
|
||||
LWTUNNEL_ENCAP_SEG6
|
||||
LWTUNNEL_ENCAP_BPF
|
||||
LWTUNNEL_ENCAP_SEG6_LOCAL
|
||||
)
|
||||
|
||||
// routing header types
|
||||
|
166
vendor/github.com/vishvananda/netlink/nl/tc_linux.go
generated
vendored
166
vendor/github.com/vishvananda/netlink/nl/tc_linux.go
generated
vendored
@ -1,6 +1,7 @@
|
||||
package nl
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
@ -64,6 +65,15 @@ const (
|
||||
TCA_PRIO_MAX = TCA_PRIO_MQ
|
||||
)
|
||||
|
||||
const (
|
||||
TCA_STATS_UNSPEC = iota
|
||||
TCA_STATS_BASIC
|
||||
TCA_STATS_RATE_EST
|
||||
TCA_STATS_QUEUE
|
||||
TCA_STATS_APP
|
||||
TCA_STATS_MAX = TCA_STATS_APP
|
||||
)
|
||||
|
||||
const (
|
||||
SizeofTcMsg = 0x14
|
||||
SizeofTcActionMsg = 0x04
|
||||
@ -79,7 +89,10 @@ const (
|
||||
SizeofTcU32Key = 0x10
|
||||
SizeofTcU32Sel = 0x10 // without keys
|
||||
SizeofTcGen = 0x14
|
||||
SizeofTcConnmark = SizeofTcGen + 0x04
|
||||
SizeofTcMirred = SizeofTcGen + 0x08
|
||||
SizeofTcTunnelKey = SizeofTcGen + 0x04
|
||||
SizeofTcSkbEdit = SizeofTcGen
|
||||
SizeofTcPolice = 2*SizeofTcRateSpec + 0x20
|
||||
)
|
||||
|
||||
@ -412,6 +425,57 @@ func (x *TcHtbGlob) Serialize() []byte {
|
||||
return (*(*[SizeofTcHtbGlob]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
// HFSC
|
||||
|
||||
type Curve struct {
|
||||
m1 uint32
|
||||
d uint32
|
||||
m2 uint32
|
||||
}
|
||||
|
||||
type HfscCopt struct {
|
||||
Rsc Curve
|
||||
Fsc Curve
|
||||
Usc Curve
|
||||
}
|
||||
|
||||
func (c *Curve) Attrs() (uint32, uint32, uint32) {
|
||||
return c.m1, c.d, c.m2
|
||||
}
|
||||
|
||||
func (c *Curve) Set(m1 uint32, d uint32, m2 uint32) {
|
||||
c.m1 = m1
|
||||
c.d = d
|
||||
c.m2 = m2
|
||||
}
|
||||
|
||||
func DeserializeHfscCurve(b []byte) *Curve {
|
||||
return &Curve{
|
||||
m1: binary.LittleEndian.Uint32(b[0:4]),
|
||||
d: binary.LittleEndian.Uint32(b[4:8]),
|
||||
m2: binary.LittleEndian.Uint32(b[8:12]),
|
||||
}
|
||||
}
|
||||
|
||||
func SerializeHfscCurve(c *Curve) (b []byte) {
|
||||
t := make([]byte, binary.MaxVarintLen32)
|
||||
binary.LittleEndian.PutUint32(t, c.m1)
|
||||
b = append(b, t[:4]...)
|
||||
binary.LittleEndian.PutUint32(t, c.d)
|
||||
b = append(b, t[:4]...)
|
||||
binary.LittleEndian.PutUint32(t, c.m2)
|
||||
b = append(b, t[:4]...)
|
||||
return b
|
||||
}
|
||||
|
||||
type TcHfscOpt struct {
|
||||
Defcls uint16
|
||||
}
|
||||
|
||||
func (x *TcHfscOpt) Serialize() []byte {
|
||||
return (*(*[2]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
const (
|
||||
TCA_U32_UNSPEC = iota
|
||||
TCA_U32_CLASSID
|
||||
@ -586,11 +650,47 @@ const (
|
||||
TCA_BPF_FD
|
||||
TCA_BPF_NAME
|
||||
TCA_BPF_FLAGS
|
||||
TCA_BPF_MAX = TCA_BPF_FLAGS
|
||||
TCA_BPF_FLAGS_GEN
|
||||
TCA_BPF_TAG
|
||||
TCA_BPF_ID
|
||||
TCA_BPF_MAX = TCA_BPF_ID
|
||||
)
|
||||
|
||||
type TcBpf TcGen
|
||||
|
||||
const (
|
||||
TCA_ACT_CONNMARK = 14
|
||||
)
|
||||
|
||||
const (
|
||||
TCA_CONNMARK_UNSPEC = iota
|
||||
TCA_CONNMARK_PARMS
|
||||
TCA_CONNMARK_TM
|
||||
TCA_CONNMARK_MAX = TCA_CONNMARK_TM
|
||||
)
|
||||
|
||||
// struct tc_connmark {
|
||||
// tc_gen;
|
||||
// __u16 zone;
|
||||
// };
|
||||
|
||||
type TcConnmark struct {
|
||||
TcGen
|
||||
Zone uint16
|
||||
}
|
||||
|
||||
func (msg *TcConnmark) Len() int {
|
||||
return SizeofTcConnmark
|
||||
}
|
||||
|
||||
func DeserializeTcConnmark(b []byte) *TcConnmark {
|
||||
return (*TcConnmark)(unsafe.Pointer(&b[0:SizeofTcConnmark][0]))
|
||||
}
|
||||
|
||||
func (x *TcConnmark) Serialize() []byte {
|
||||
return (*(*[SizeofTcConnmark]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
const (
|
||||
TCA_ACT_MIRRED = 8
|
||||
)
|
||||
@ -626,6 +726,63 @@ func (x *TcMirred) Serialize() []byte {
|
||||
return (*(*[SizeofTcMirred]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
const (
|
||||
TCA_TUNNEL_KEY_UNSPEC = iota
|
||||
TCA_TUNNEL_KEY_TM
|
||||
TCA_TUNNEL_KEY_PARMS
|
||||
TCA_TUNNEL_KEY_ENC_IPV4_SRC
|
||||
TCA_TUNNEL_KEY_ENC_IPV4_DST
|
||||
TCA_TUNNEL_KEY_ENC_IPV6_SRC
|
||||
TCA_TUNNEL_KEY_ENC_IPV6_DST
|
||||
TCA_TUNNEL_KEY_ENC_KEY_ID
|
||||
TCA_TUNNEL_KEY_MAX = TCA_TUNNEL_KEY_ENC_KEY_ID
|
||||
)
|
||||
|
||||
type TcTunnelKey struct {
|
||||
TcGen
|
||||
Action int32
|
||||
}
|
||||
|
||||
func (x *TcTunnelKey) Len() int {
|
||||
return SizeofTcTunnelKey
|
||||
}
|
||||
|
||||
func DeserializeTunnelKey(b []byte) *TcTunnelKey {
|
||||
return (*TcTunnelKey)(unsafe.Pointer(&b[0:SizeofTcTunnelKey][0]))
|
||||
}
|
||||
|
||||
func (x *TcTunnelKey) Serialize() []byte {
|
||||
return (*(*[SizeofTcTunnelKey]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
const (
|
||||
TCA_SKBEDIT_UNSPEC = iota
|
||||
TCA_SKBEDIT_TM
|
||||
TCA_SKBEDIT_PARMS
|
||||
TCA_SKBEDIT_PRIORITY
|
||||
TCA_SKBEDIT_QUEUE_MAPPING
|
||||
TCA_SKBEDIT_MARK
|
||||
TCA_SKBEDIT_PAD
|
||||
TCA_SKBEDIT_PTYPE
|
||||
TCA_SKBEDIT_MAX = TCA_SKBEDIT_MARK
|
||||
)
|
||||
|
||||
type TcSkbEdit struct {
|
||||
TcGen
|
||||
}
|
||||
|
||||
func (x *TcSkbEdit) Len() int {
|
||||
return SizeofTcSkbEdit
|
||||
}
|
||||
|
||||
func DeserializeSkbEdit(b []byte) *TcSkbEdit {
|
||||
return (*TcSkbEdit)(unsafe.Pointer(&b[0:SizeofTcSkbEdit][0]))
|
||||
}
|
||||
|
||||
func (x *TcSkbEdit) Serialize() []byte {
|
||||
return (*(*[SizeofTcSkbEdit]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
// struct tc_police {
|
||||
// __u32 index;
|
||||
// int action;
|
||||
@ -708,3 +865,10 @@ const (
|
||||
TCA_FQ_CODEL_DROP_BATCH_SIZE
|
||||
TCA_FQ_CODEL_MEMORY_LIMIT
|
||||
)
|
||||
|
||||
const (
|
||||
TCA_HFSC_UNSPEC = iota
|
||||
TCA_HFSC_RSC
|
||||
TCA_HFSC_FSC
|
||||
TCA_HFSC_USC
|
||||
)
|
||||
|
62
vendor/github.com/vishvananda/netlink/nl/xfrm_linux.go
generated
vendored
62
vendor/github.com/vishvananda/netlink/nl/xfrm_linux.go
generated
vendored
@ -50,34 +50,44 @@ const (
|
||||
// Attribute types
|
||||
const (
|
||||
/* Netlink message attributes. */
|
||||
XFRMA_UNSPEC = 0x00
|
||||
XFRMA_ALG_AUTH = 0x01 /* struct xfrm_algo */
|
||||
XFRMA_ALG_CRYPT = 0x02 /* struct xfrm_algo */
|
||||
XFRMA_ALG_COMP = 0x03 /* struct xfrm_algo */
|
||||
XFRMA_ENCAP = 0x04 /* struct xfrm_algo + struct xfrm_encap_tmpl */
|
||||
XFRMA_TMPL = 0x05 /* 1 or more struct xfrm_user_tmpl */
|
||||
XFRMA_SA = 0x06 /* struct xfrm_usersa_info */
|
||||
XFRMA_POLICY = 0x07 /* struct xfrm_userpolicy_info */
|
||||
XFRMA_SEC_CTX = 0x08 /* struct xfrm_sec_ctx */
|
||||
XFRMA_LTIME_VAL = 0x09
|
||||
XFRMA_REPLAY_VAL = 0x0a
|
||||
XFRMA_REPLAY_THRESH = 0x0b
|
||||
XFRMA_ETIMER_THRESH = 0x0c
|
||||
XFRMA_SRCADDR = 0x0d /* xfrm_address_t */
|
||||
XFRMA_COADDR = 0x0e /* xfrm_address_t */
|
||||
XFRMA_LASTUSED = 0x0f /* unsigned long */
|
||||
XFRMA_POLICY_TYPE = 0x10 /* struct xfrm_userpolicy_type */
|
||||
XFRMA_MIGRATE = 0x11
|
||||
XFRMA_ALG_AEAD = 0x12 /* struct xfrm_algo_aead */
|
||||
XFRMA_KMADDRESS = 0x13 /* struct xfrm_user_kmaddress */
|
||||
XFRMA_ALG_AUTH_TRUNC = 0x14 /* struct xfrm_algo_auth */
|
||||
XFRMA_MARK = 0x15 /* struct xfrm_mark */
|
||||
XFRMA_TFCPAD = 0x16 /* __u32 */
|
||||
XFRMA_REPLAY_ESN_VAL = 0x17 /* struct xfrm_replay_esn */
|
||||
XFRMA_SA_EXTRA_FLAGS = 0x18 /* __u32 */
|
||||
XFRMA_MAX = 0x18
|
||||
XFRMA_UNSPEC = iota
|
||||
XFRMA_ALG_AUTH /* struct xfrm_algo */
|
||||
XFRMA_ALG_CRYPT /* struct xfrm_algo */
|
||||
XFRMA_ALG_COMP /* struct xfrm_algo */
|
||||
XFRMA_ENCAP /* struct xfrm_algo + struct xfrm_encap_tmpl */
|
||||
XFRMA_TMPL /* 1 or more struct xfrm_user_tmpl */
|
||||
XFRMA_SA /* struct xfrm_usersa_info */
|
||||
XFRMA_POLICY /* struct xfrm_userpolicy_info */
|
||||
XFRMA_SEC_CTX /* struct xfrm_sec_ctx */
|
||||
XFRMA_LTIME_VAL
|
||||
XFRMA_REPLAY_VAL
|
||||
XFRMA_REPLAY_THRESH
|
||||
XFRMA_ETIMER_THRESH
|
||||
XFRMA_SRCADDR /* xfrm_address_t */
|
||||
XFRMA_COADDR /* xfrm_address_t */
|
||||
XFRMA_LASTUSED /* unsigned long */
|
||||
XFRMA_POLICY_TYPE /* struct xfrm_userpolicy_type */
|
||||
XFRMA_MIGRATE
|
||||
XFRMA_ALG_AEAD /* struct xfrm_algo_aead */
|
||||
XFRMA_KMADDRESS /* struct xfrm_user_kmaddress */
|
||||
XFRMA_ALG_AUTH_TRUNC /* struct xfrm_algo_auth */
|
||||
XFRMA_MARK /* struct xfrm_mark */
|
||||
XFRMA_TFCPAD /* __u32 */
|
||||
XFRMA_REPLAY_ESN_VAL /* struct xfrm_replay_esn */
|
||||
XFRMA_SA_EXTRA_FLAGS /* __u32 */
|
||||
XFRMA_PROTO /* __u8 */
|
||||
XFRMA_ADDRESS_FILTER /* struct xfrm_address_filter */
|
||||
XFRMA_PAD
|
||||
XFRMA_OFFLOAD_DEV /* struct xfrm_state_offload */
|
||||
XFRMA_SET_MARK /* __u32 */
|
||||
XFRMA_SET_MARK_MASK /* __u32 */
|
||||
XFRMA_IF_ID /* __u32 */
|
||||
|
||||
XFRMA_MAX = iota - 1
|
||||
)
|
||||
|
||||
const XFRMA_OUTPUT_MARK = XFRMA_SET_MARK
|
||||
|
||||
const (
|
||||
SizeofXfrmAddress = 0x10
|
||||
SizeofXfrmSelector = 0x38
|
||||
|
4
vendor/github.com/vishvananda/netlink/protinfo.go
generated
vendored
4
vendor/github.com/vishvananda/netlink/protinfo.go
generated
vendored
@ -18,6 +18,10 @@ type Protinfo struct {
|
||||
|
||||
// String returns a list of enabled flags
|
||||
func (prot *Protinfo) String() string {
|
||||
if prot == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
|
||||
var boolStrings []string
|
||||
if prot.Hairpin {
|
||||
boolStrings = append(boolStrings, "Hairpin")
|
||||
|
7
vendor/github.com/vishvananda/netlink/protinfo_linux.go
generated
vendored
7
vendor/github.com/vishvananda/netlink/protinfo_linux.go
generated
vendored
@ -41,7 +41,7 @@ func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) {
|
||||
if err != nil {
|
||||
return pi, err
|
||||
}
|
||||
pi = *parseProtinfo(infos)
|
||||
pi = parseProtinfo(infos)
|
||||
|
||||
return pi, nil
|
||||
}
|
||||
@ -49,8 +49,7 @@ func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) {
|
||||
return pi, fmt.Errorf("Device with index %d not found", base.Index)
|
||||
}
|
||||
|
||||
func parseProtinfo(infos []syscall.NetlinkRouteAttr) *Protinfo {
|
||||
var pi Protinfo
|
||||
func parseProtinfo(infos []syscall.NetlinkRouteAttr) (pi Protinfo) {
|
||||
for _, info := range infos {
|
||||
switch info.Attr.Type {
|
||||
case nl.IFLA_BRPORT_MODE:
|
||||
@ -71,5 +70,5 @@ func parseProtinfo(infos []syscall.NetlinkRouteAttr) *Protinfo {
|
||||
pi.ProxyArpWiFi = byteToBool(info.Value[0])
|
||||
}
|
||||
}
|
||||
return &pi
|
||||
return
|
||||
}
|
||||
|
48
vendor/github.com/vishvananda/netlink/qdisc.go
generated
vendored
48
vendor/github.com/vishvananda/netlink/qdisc.go
generated
vendored
@ -176,6 +176,13 @@ type Netem struct {
|
||||
CorruptCorr uint32
|
||||
}
|
||||
|
||||
func (netem *Netem) String() string {
|
||||
return fmt.Sprintf(
|
||||
"{Latency: %v, Limit: %v, Loss: %v, Gap: %v, Duplicate: %v, Jitter: %v}",
|
||||
netem.Latency, netem.Limit, netem.Loss, netem.Gap, netem.Duplicate, netem.Jitter,
|
||||
)
|
||||
}
|
||||
|
||||
func (qdisc *Netem) Attrs() *QdiscAttrs {
|
||||
return &qdisc.QdiscAttrs
|
||||
}
|
||||
@ -231,6 +238,33 @@ func (qdisc *GenericQdisc) Type() string {
|
||||
return qdisc.QdiscType
|
||||
}
|
||||
|
||||
type Hfsc struct {
|
||||
QdiscAttrs
|
||||
Defcls uint16
|
||||
}
|
||||
|
||||
func NewHfsc(attrs QdiscAttrs) *Hfsc {
|
||||
return &Hfsc{
|
||||
QdiscAttrs: attrs,
|
||||
Defcls: 1,
|
||||
}
|
||||
}
|
||||
|
||||
func (hfsc *Hfsc) Attrs() *QdiscAttrs {
|
||||
return &hfsc.QdiscAttrs
|
||||
}
|
||||
|
||||
func (hfsc *Hfsc) Type() string {
|
||||
return "hfsc"
|
||||
}
|
||||
|
||||
func (hfsc *Hfsc) String() string {
|
||||
return fmt.Sprintf(
|
||||
"{%v -- default: %d}",
|
||||
hfsc.Attrs(), hfsc.Defcls,
|
||||
)
|
||||
}
|
||||
|
||||
// Fq is a classless packet scheduler meant to be mostly used for locally generated traffic.
|
||||
type Fq struct {
|
||||
QdiscAttrs
|
||||
@ -249,6 +283,13 @@ type Fq struct {
|
||||
LowRateThreshold uint32
|
||||
}
|
||||
|
||||
func (fq *Fq) String() string {
|
||||
return fmt.Sprintf(
|
||||
"{PacketLimit: %v, FlowPacketLimit: %v, Quantum: %v, InitialQuantum: %v, Pacing: %v, FlowDefaultRate: %v, FlowMaxRate: %v, Buckets: %v, FlowRefillDelay: %v, LowRateThreshold: %v}",
|
||||
fq.PacketLimit, fq.FlowPacketLimit, fq.Quantum, fq.InitialQuantum, fq.Pacing, fq.FlowDefaultRate, fq.FlowMaxRate, fq.Buckets, fq.FlowRefillDelay, fq.LowRateThreshold,
|
||||
)
|
||||
}
|
||||
|
||||
func NewFq(attrs QdiscAttrs) *Fq {
|
||||
return &Fq{
|
||||
QdiscAttrs: attrs,
|
||||
@ -276,6 +317,13 @@ type FqCodel struct {
|
||||
// There are some more attributes here, but support for them seems not ubiquitous
|
||||
}
|
||||
|
||||
func (fqcodel *FqCodel) String() string {
|
||||
return fmt.Sprintf(
|
||||
"{%v -- Target: %v, Limit: %v, Interval: %v, ECM: %v, Flows: %v, Quantum: %v}",
|
||||
fqcodel.Attrs(), fqcodel.Target, fqcodel.Limit, fqcodel.Interval, fqcodel.ECN, fqcodel.Flows, fqcodel.Quantum,
|
||||
)
|
||||
}
|
||||
|
||||
func NewFqCodel(attrs QdiscAttrs) *FqCodel {
|
||||
return &FqCodel{
|
||||
QdiscAttrs: attrs,
|
||||
|
69
vendor/github.com/vishvananda/netlink/qdisc_linux.go
generated
vendored
69
vendor/github.com/vishvananda/netlink/qdisc_linux.go
generated
vendored
@ -175,15 +175,15 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
|
||||
opt.Peakrate.Rate = uint32(qdisc.Peakrate)
|
||||
opt.Limit = qdisc.Limit
|
||||
opt.Buffer = qdisc.Buffer
|
||||
nl.NewRtAttrChild(options, nl.TCA_TBF_PARMS, opt.Serialize())
|
||||
options.AddRtAttr(nl.TCA_TBF_PARMS, opt.Serialize())
|
||||
if qdisc.Rate >= uint64(1<<32) {
|
||||
nl.NewRtAttrChild(options, nl.TCA_TBF_RATE64, nl.Uint64Attr(qdisc.Rate))
|
||||
options.AddRtAttr(nl.TCA_TBF_RATE64, nl.Uint64Attr(qdisc.Rate))
|
||||
}
|
||||
if qdisc.Peakrate >= uint64(1<<32) {
|
||||
nl.NewRtAttrChild(options, nl.TCA_TBF_PRATE64, nl.Uint64Attr(qdisc.Peakrate))
|
||||
options.AddRtAttr(nl.TCA_TBF_PRATE64, nl.Uint64Attr(qdisc.Peakrate))
|
||||
}
|
||||
if qdisc.Peakrate > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_TBF_PBURST, nl.Uint32Attr(qdisc.Minburst))
|
||||
options.AddRtAttr(nl.TCA_TBF_PBURST, nl.Uint32Attr(qdisc.Minburst))
|
||||
}
|
||||
case *Htb:
|
||||
opt := nl.TcHtbGlob{}
|
||||
@ -193,8 +193,12 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
|
||||
// TODO: Handle Debug properly. For now default to 0
|
||||
opt.Debug = qdisc.Debug
|
||||
opt.DirectPkts = qdisc.DirectPkts
|
||||
nl.NewRtAttrChild(options, nl.TCA_HTB_INIT, opt.Serialize())
|
||||
// nl.NewRtAttrChild(options, nl.TCA_HTB_DIRECT_QLEN, opt.Serialize())
|
||||
options.AddRtAttr(nl.TCA_HTB_INIT, opt.Serialize())
|
||||
// options.AddRtAttr(nl.TCA_HTB_DIRECT_QLEN, opt.Serialize())
|
||||
case *Hfsc:
|
||||
opt := nl.TcHfscOpt{}
|
||||
opt.Defcls = qdisc.Defcls
|
||||
options = nl.NewRtAttr(nl.TCA_OPTIONS, opt.Serialize())
|
||||
case *Netem:
|
||||
opt := nl.TcNetemQopt{}
|
||||
opt.Latency = qdisc.Latency
|
||||
@ -211,21 +215,21 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
|
||||
corr.DupCorr = qdisc.DuplicateCorr
|
||||
|
||||
if corr.DelayCorr > 0 || corr.LossCorr > 0 || corr.DupCorr > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_NETEM_CORR, corr.Serialize())
|
||||
options.AddRtAttr(nl.TCA_NETEM_CORR, corr.Serialize())
|
||||
}
|
||||
// Corruption
|
||||
corruption := nl.TcNetemCorrupt{}
|
||||
corruption.Probability = qdisc.CorruptProb
|
||||
corruption.Correlation = qdisc.CorruptCorr
|
||||
if corruption.Probability > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_NETEM_CORRUPT, corruption.Serialize())
|
||||
options.AddRtAttr(nl.TCA_NETEM_CORRUPT, corruption.Serialize())
|
||||
}
|
||||
// Reorder
|
||||
reorder := nl.TcNetemReorder{}
|
||||
reorder.Probability = qdisc.ReorderProb
|
||||
reorder.Correlation = qdisc.ReorderCorr
|
||||
if reorder.Probability > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_NETEM_REORDER, reorder.Serialize())
|
||||
options.AddRtAttr(nl.TCA_NETEM_REORDER, reorder.Serialize())
|
||||
}
|
||||
case *Ingress:
|
||||
// ingress filters must use the proper handle
|
||||
@ -233,50 +237,54 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
|
||||
return fmt.Errorf("Ingress filters must set Parent to HANDLE_INGRESS")
|
||||
}
|
||||
case *FqCodel:
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_ECN, nl.Uint32Attr((uint32(qdisc.ECN))))
|
||||
options.AddRtAttr(nl.TCA_FQ_CODEL_ECN, nl.Uint32Attr((uint32(qdisc.ECN))))
|
||||
if qdisc.Limit > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_LIMIT, nl.Uint32Attr((uint32(qdisc.Limit))))
|
||||
options.AddRtAttr(nl.TCA_FQ_CODEL_LIMIT, nl.Uint32Attr((uint32(qdisc.Limit))))
|
||||
}
|
||||
if qdisc.Interval > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_INTERVAL, nl.Uint32Attr((uint32(qdisc.Interval))))
|
||||
options.AddRtAttr(nl.TCA_FQ_CODEL_INTERVAL, nl.Uint32Attr((uint32(qdisc.Interval))))
|
||||
}
|
||||
if qdisc.Flows > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_FLOWS, nl.Uint32Attr((uint32(qdisc.Flows))))
|
||||
options.AddRtAttr(nl.TCA_FQ_CODEL_FLOWS, nl.Uint32Attr((uint32(qdisc.Flows))))
|
||||
}
|
||||
if qdisc.Quantum > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_QUANTUM, nl.Uint32Attr((uint32(qdisc.Quantum))))
|
||||
options.AddRtAttr(nl.TCA_FQ_CODEL_QUANTUM, nl.Uint32Attr((uint32(qdisc.Quantum))))
|
||||
}
|
||||
|
||||
case *Fq:
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_RATE_ENABLE, nl.Uint32Attr((uint32(qdisc.Pacing))))
|
||||
options.AddRtAttr(nl.TCA_FQ_RATE_ENABLE, nl.Uint32Attr((uint32(qdisc.Pacing))))
|
||||
|
||||
if qdisc.Buckets > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_BUCKETS_LOG, nl.Uint32Attr((uint32(qdisc.Buckets))))
|
||||
options.AddRtAttr(nl.TCA_FQ_BUCKETS_LOG, nl.Uint32Attr((uint32(qdisc.Buckets))))
|
||||
}
|
||||
if qdisc.LowRateThreshold > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_LOW_RATE_THRESHOLD, nl.Uint32Attr((uint32(qdisc.LowRateThreshold))))
|
||||
options.AddRtAttr(nl.TCA_FQ_LOW_RATE_THRESHOLD, nl.Uint32Attr((uint32(qdisc.LowRateThreshold))))
|
||||
}
|
||||
if qdisc.Quantum > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_QUANTUM, nl.Uint32Attr((uint32(qdisc.Quantum))))
|
||||
options.AddRtAttr(nl.TCA_FQ_QUANTUM, nl.Uint32Attr((uint32(qdisc.Quantum))))
|
||||
}
|
||||
if qdisc.InitialQuantum > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_INITIAL_QUANTUM, nl.Uint32Attr((uint32(qdisc.InitialQuantum))))
|
||||
options.AddRtAttr(nl.TCA_FQ_INITIAL_QUANTUM, nl.Uint32Attr((uint32(qdisc.InitialQuantum))))
|
||||
}
|
||||
if qdisc.FlowRefillDelay > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_FLOW_REFILL_DELAY, nl.Uint32Attr((uint32(qdisc.FlowRefillDelay))))
|
||||
options.AddRtAttr(nl.TCA_FQ_FLOW_REFILL_DELAY, nl.Uint32Attr((uint32(qdisc.FlowRefillDelay))))
|
||||
}
|
||||
if qdisc.FlowPacketLimit > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_FLOW_PLIMIT, nl.Uint32Attr((uint32(qdisc.FlowPacketLimit))))
|
||||
options.AddRtAttr(nl.TCA_FQ_FLOW_PLIMIT, nl.Uint32Attr((uint32(qdisc.FlowPacketLimit))))
|
||||
}
|
||||
if qdisc.FlowMaxRate > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_FLOW_MAX_RATE, nl.Uint32Attr((uint32(qdisc.FlowMaxRate))))
|
||||
options.AddRtAttr(nl.TCA_FQ_FLOW_MAX_RATE, nl.Uint32Attr((uint32(qdisc.FlowMaxRate))))
|
||||
}
|
||||
if qdisc.FlowDefaultRate > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_FLOW_DEFAULT_RATE, nl.Uint32Attr((uint32(qdisc.FlowDefaultRate))))
|
||||
options.AddRtAttr(nl.TCA_FQ_FLOW_DEFAULT_RATE, nl.Uint32Attr((uint32(qdisc.FlowDefaultRate))))
|
||||
}
|
||||
default:
|
||||
options = nil
|
||||
}
|
||||
|
||||
req.AddData(options)
|
||||
if options != nil {
|
||||
req.AddData(options)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -348,6 +356,8 @@ func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
|
||||
qdisc = &Htb{}
|
||||
case "fq":
|
||||
qdisc = &Fq{}
|
||||
case "hfsc":
|
||||
qdisc = &Hfsc{}
|
||||
case "fq_codel":
|
||||
qdisc = &FqCodel{}
|
||||
case "netem":
|
||||
@ -375,6 +385,10 @@ func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
|
||||
if err := parseTbfData(qdisc, data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "hfsc":
|
||||
if err := parseHfscData(qdisc, attr.Value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "htb":
|
||||
data, err := nl.ParseRouteAttr(attr.Value)
|
||||
if err != nil {
|
||||
@ -474,6 +488,13 @@ func parseFqCodelData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseHfscData(qdisc Qdisc, data []byte) error {
|
||||
Hfsc := qdisc.(*Hfsc)
|
||||
native = nl.NativeEndian()
|
||||
Hfsc.Defcls = native.Uint16(data)
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseFqData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
|
||||
native = nl.NativeEndian()
|
||||
fq := qdisc.(*Fq)
|
||||
|
264
vendor/github.com/vishvananda/netlink/rdma_link_linux.go
generated
vendored
Normal file
264
vendor/github.com/vishvananda/netlink/rdma_link_linux.go
generated
vendored
Normal file
@ -0,0 +1,264 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// LinkAttrs represents data shared by most link types
|
||||
type RdmaLinkAttrs struct {
|
||||
Index uint32
|
||||
Name string
|
||||
FirmwareVersion string
|
||||
NodeGuid string
|
||||
SysImageGuid string
|
||||
}
|
||||
|
||||
// Link represents a rdma device from netlink.
|
||||
type RdmaLink struct {
|
||||
Attrs RdmaLinkAttrs
|
||||
}
|
||||
|
||||
func getProtoField(clientType int, op int) int {
|
||||
return ((clientType << nl.RDMA_NL_GET_CLIENT_SHIFT) | op)
|
||||
}
|
||||
|
||||
func uint64ToGuidString(guid uint64) string {
|
||||
//Convert to byte array
|
||||
sysGuidBytes := new(bytes.Buffer)
|
||||
binary.Write(sysGuidBytes, binary.LittleEndian, guid)
|
||||
|
||||
//Convert to HardwareAddr
|
||||
sysGuidNet := net.HardwareAddr(sysGuidBytes.Bytes())
|
||||
|
||||
//Get the String
|
||||
return sysGuidNet.String()
|
||||
}
|
||||
|
||||
func executeOneGetRdmaLink(data []byte) (*RdmaLink, error) {
|
||||
|
||||
link := RdmaLink{}
|
||||
|
||||
reader := bytes.NewReader(data)
|
||||
for reader.Len() >= 4 {
|
||||
_, attrType, len, value := parseNfAttrTLV(reader)
|
||||
|
||||
switch attrType {
|
||||
case nl.RDMA_NLDEV_ATTR_DEV_INDEX:
|
||||
var Index uint32
|
||||
r := bytes.NewReader(value)
|
||||
binary.Read(r, nl.NativeEndian(), &Index)
|
||||
link.Attrs.Index = Index
|
||||
case nl.RDMA_NLDEV_ATTR_DEV_NAME:
|
||||
link.Attrs.Name = string(value[0 : len-1])
|
||||
case nl.RDMA_NLDEV_ATTR_FW_VERSION:
|
||||
link.Attrs.FirmwareVersion = string(value[0 : len-1])
|
||||
case nl.RDMA_NLDEV_ATTR_NODE_GUID:
|
||||
var guid uint64
|
||||
r := bytes.NewReader(value)
|
||||
binary.Read(r, nl.NativeEndian(), &guid)
|
||||
link.Attrs.NodeGuid = uint64ToGuidString(guid)
|
||||
case nl.RDMA_NLDEV_ATTR_SYS_IMAGE_GUID:
|
||||
var sysGuid uint64
|
||||
r := bytes.NewReader(value)
|
||||
binary.Read(r, nl.NativeEndian(), &sysGuid)
|
||||
link.Attrs.SysImageGuid = uint64ToGuidString(sysGuid)
|
||||
}
|
||||
if (len % 4) != 0 {
|
||||
// Skip pad bytes
|
||||
reader.Seek(int64(4-(len%4)), seekCurrent)
|
||||
}
|
||||
}
|
||||
return &link, nil
|
||||
}
|
||||
|
||||
func execRdmaGetLink(req *nl.NetlinkRequest, name string) (*RdmaLink, error) {
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_RDMA, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, m := range msgs {
|
||||
link, err := executeOneGetRdmaLink(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if link.Attrs.Name == name {
|
||||
return link, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("Rdma device %v not found", name)
|
||||
}
|
||||
|
||||
func execRdmaSetLink(req *nl.NetlinkRequest) error {
|
||||
|
||||
_, err := req.Execute(unix.NETLINK_RDMA, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
// RdmaLinkByName finds a link by name and returns a pointer to the object if
|
||||
// found and nil error, otherwise returns error code.
|
||||
func RdmaLinkByName(name string) (*RdmaLink, error) {
|
||||
return pkgHandle.RdmaLinkByName(name)
|
||||
}
|
||||
|
||||
// RdmaLinkByName finds a link by name and returns a pointer to the object if
|
||||
// found and nil error, otherwise returns error code.
|
||||
func (h *Handle) RdmaLinkByName(name string) (*RdmaLink, error) {
|
||||
|
||||
proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_GET)
|
||||
req := h.newNetlinkRequest(proto, unix.NLM_F_ACK|unix.NLM_F_DUMP)
|
||||
|
||||
return execRdmaGetLink(req, name)
|
||||
}
|
||||
|
||||
// RdmaLinkSetName sets the name of the rdma link device. Return nil on success
|
||||
// or error otherwise.
|
||||
// Equivalent to: `rdma dev set $old_devname name $name`
|
||||
func RdmaLinkSetName(link *RdmaLink, name string) error {
|
||||
return pkgHandle.RdmaLinkSetName(link, name)
|
||||
}
|
||||
|
||||
// RdmaLinkSetName sets the name of the rdma link device. Return nil on success
|
||||
// or error otherwise.
|
||||
// Equivalent to: `rdma dev set $old_devname name $name`
|
||||
func (h *Handle) RdmaLinkSetName(link *RdmaLink, name string) error {
|
||||
proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_SET)
|
||||
req := h.newNetlinkRequest(proto, unix.NLM_F_ACK)
|
||||
|
||||
b := make([]byte, 4)
|
||||
native.PutUint32(b, uint32(link.Attrs.Index))
|
||||
data := nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_DEV_INDEX, b)
|
||||
req.AddData(data)
|
||||
|
||||
b = make([]byte, len(name)+1)
|
||||
copy(b, name)
|
||||
data = nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_DEV_NAME, b)
|
||||
req.AddData(data)
|
||||
|
||||
return execRdmaSetLink(req)
|
||||
}
|
||||
|
||||
func netnsModeToString(mode uint8) string {
|
||||
switch mode {
|
||||
case 0:
|
||||
return "exclusive"
|
||||
case 1:
|
||||
return "shared"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
func executeOneGetRdmaNetnsMode(data []byte) (string, error) {
|
||||
reader := bytes.NewReader(data)
|
||||
for reader.Len() >= 4 {
|
||||
_, attrType, len, value := parseNfAttrTLV(reader)
|
||||
|
||||
switch attrType {
|
||||
case nl.RDMA_NLDEV_SYS_ATTR_NETNS_MODE:
|
||||
var mode uint8
|
||||
r := bytes.NewReader(value)
|
||||
binary.Read(r, nl.NativeEndian(), &mode)
|
||||
return netnsModeToString(mode), nil
|
||||
}
|
||||
if (len % 4) != 0 {
|
||||
// Skip pad bytes
|
||||
reader.Seek(int64(4-(len%4)), seekCurrent)
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("Invalid netns mode")
|
||||
}
|
||||
|
||||
// RdmaSystemGetNetnsMode gets the net namespace mode for RDMA subsystem
|
||||
// Returns mode string and error status as nil on success or returns error
|
||||
// otherwise.
|
||||
// Equivalent to: `rdma system show netns'
|
||||
func RdmaSystemGetNetnsMode() (string, error) {
|
||||
return pkgHandle.RdmaSystemGetNetnsMode()
|
||||
}
|
||||
|
||||
// RdmaSystemGetNetnsMode gets the net namespace mode for RDMA subsystem
|
||||
// Returns mode string and error status as nil on success or returns error
|
||||
// otherwise.
|
||||
// Equivalent to: `rdma system show netns'
|
||||
func (h *Handle) RdmaSystemGetNetnsMode() (string, error) {
|
||||
|
||||
proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_SYS_GET)
|
||||
req := h.newNetlinkRequest(proto, unix.NLM_F_ACK)
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_RDMA, 0)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(msgs) == 0 {
|
||||
return "", fmt.Errorf("No valid response from kernel")
|
||||
}
|
||||
return executeOneGetRdmaNetnsMode(msgs[0])
|
||||
}
|
||||
|
||||
func netnsModeStringToUint8(mode string) (uint8, error) {
|
||||
switch mode {
|
||||
case "exclusive":
|
||||
return 0, nil
|
||||
case "shared":
|
||||
return 1, nil
|
||||
default:
|
||||
return 0, fmt.Errorf("Invalid mode; %q", mode)
|
||||
}
|
||||
}
|
||||
|
||||
// RdmaSystemSetNetnsMode sets the net namespace mode for RDMA subsystem
|
||||
// Returns nil on success or appropriate error code.
|
||||
// Equivalent to: `rdma system set netns { shared | exclusive }'
|
||||
func RdmaSystemSetNetnsMode(NewMode string) error {
|
||||
return pkgHandle.RdmaSystemSetNetnsMode(NewMode)
|
||||
}
|
||||
|
||||
// RdmaSystemSetNetnsMode sets the net namespace mode for RDMA subsystem
|
||||
// Returns nil on success or appropriate error code.
|
||||
// Equivalent to: `rdma system set netns { shared | exclusive }'
|
||||
func (h *Handle) RdmaSystemSetNetnsMode(NewMode string) error {
|
||||
value, err := netnsModeStringToUint8(NewMode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_SYS_SET)
|
||||
req := h.newNetlinkRequest(proto, unix.NLM_F_ACK)
|
||||
|
||||
data := nl.NewRtAttr(nl.RDMA_NLDEV_SYS_ATTR_NETNS_MODE, []byte{value})
|
||||
req.AddData(data)
|
||||
|
||||
_, err = req.Execute(unix.NETLINK_RDMA, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
// RdmaLinkSetNsFd puts the RDMA device into a new network namespace. The
|
||||
// fd must be an open file descriptor to a network namespace.
|
||||
// Similar to: `rdma dev set $dev netns $ns`
|
||||
func RdmaLinkSetNsFd(link *RdmaLink, fd uint32) error {
|
||||
return pkgHandle.RdmaLinkSetNsFd(link, fd)
|
||||
}
|
||||
|
||||
// RdmaLinkSetNsFd puts the RDMA device into a new network namespace. The
|
||||
// fd must be an open file descriptor to a network namespace.
|
||||
// Similar to: `rdma dev set $dev netns $ns`
|
||||
func (h *Handle) RdmaLinkSetNsFd(link *RdmaLink, fd uint32) error {
|
||||
proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_SET)
|
||||
req := h.newNetlinkRequest(proto, unix.NLM_F_ACK)
|
||||
|
||||
data := nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_DEV_INDEX,
|
||||
nl.Uint32Attr(link.Attrs.Index))
|
||||
req.AddData(data)
|
||||
|
||||
data = nl.NewRtAttr(nl.RDMA_NLDEV_NET_NS_FD, nl.Uint32Attr(fd))
|
||||
req.AddData(data)
|
||||
|
||||
return execRdmaSetLink(req)
|
||||
}
|
2
vendor/github.com/vishvananda/netlink/route.go
generated
vendored
2
vendor/github.com/vishvananda/netlink/route.go
generated
vendored
@ -47,6 +47,7 @@ type Route struct {
|
||||
Encap Encap
|
||||
MTU int
|
||||
AdvMSS int
|
||||
Hoplimit int
|
||||
}
|
||||
|
||||
func (r Route) String() string {
|
||||
@ -89,6 +90,7 @@ func (r Route) Equal(x Route) bool {
|
||||
r.Table == x.Table &&
|
||||
r.Type == x.Type &&
|
||||
r.Tos == x.Tos &&
|
||||
r.Hoplimit == x.Hoplimit &&
|
||||
r.Flags == x.Flags &&
|
||||
(r.MPLSDst == x.MPLSDst || (r.MPLSDst != nil && x.MPLSDst != nil && *r.MPLSDst == *x.MPLSDst)) &&
|
||||
(r.NewDst == x.NewDst || (r.NewDst != nil && r.NewDst.Equal(x.NewDst))) &&
|
||||
|
229
vendor/github.com/vishvananda/netlink/route_linux.go
generated
vendored
229
vendor/github.com/vishvananda/netlink/route_linux.go
generated
vendored
@ -32,6 +32,7 @@ const (
|
||||
RT_FILTER_SRC
|
||||
RT_FILTER_GW
|
||||
RT_FILTER_TABLE
|
||||
RT_FILTER_HOPLIMIT
|
||||
)
|
||||
|
||||
const (
|
||||
@ -207,6 +208,7 @@ func (e *SEG6Encap) Decode(buf []byte) error {
|
||||
}
|
||||
buf = buf[:l] // make sure buf size upper limit is Length
|
||||
typ := native.Uint16(buf[2:])
|
||||
// LWTUNNEL_ENCAP_SEG6 has only one attr type SEG6_IPTUNNEL_SRH
|
||||
if typ != nl.SEG6_IPTUNNEL_SRH {
|
||||
return fmt.Errorf("unknown SEG6 Type: %d", typ)
|
||||
}
|
||||
@ -259,6 +261,188 @@ func (e *SEG6Encap) Equal(x Encap) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// SEG6LocalEncap definitions
|
||||
type SEG6LocalEncap struct {
|
||||
Flags [nl.SEG6_LOCAL_MAX]bool
|
||||
Action int
|
||||
Segments []net.IP // from SRH in seg6_local_lwt
|
||||
Table int // table id for End.T and End.DT6
|
||||
InAddr net.IP
|
||||
In6Addr net.IP
|
||||
Iif int
|
||||
Oif int
|
||||
}
|
||||
|
||||
func (e *SEG6LocalEncap) Type() int {
|
||||
return nl.LWTUNNEL_ENCAP_SEG6_LOCAL
|
||||
}
|
||||
func (e *SEG6LocalEncap) Decode(buf []byte) error {
|
||||
attrs, err := nl.ParseRouteAttr(buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
native := nl.NativeEndian()
|
||||
for _, attr := range attrs {
|
||||
switch attr.Attr.Type {
|
||||
case nl.SEG6_LOCAL_ACTION:
|
||||
e.Action = int(native.Uint32(attr.Value[0:4]))
|
||||
e.Flags[nl.SEG6_LOCAL_ACTION] = true
|
||||
case nl.SEG6_LOCAL_SRH:
|
||||
e.Segments, err = nl.DecodeSEG6Srh(attr.Value[:])
|
||||
e.Flags[nl.SEG6_LOCAL_SRH] = true
|
||||
case nl.SEG6_LOCAL_TABLE:
|
||||
e.Table = int(native.Uint32(attr.Value[0:4]))
|
||||
e.Flags[nl.SEG6_LOCAL_TABLE] = true
|
||||
case nl.SEG6_LOCAL_NH4:
|
||||
e.InAddr = net.IP(attr.Value[0:4])
|
||||
e.Flags[nl.SEG6_LOCAL_NH4] = true
|
||||
case nl.SEG6_LOCAL_NH6:
|
||||
e.In6Addr = net.IP(attr.Value[0:16])
|
||||
e.Flags[nl.SEG6_LOCAL_NH6] = true
|
||||
case nl.SEG6_LOCAL_IIF:
|
||||
e.Iif = int(native.Uint32(attr.Value[0:4]))
|
||||
e.Flags[nl.SEG6_LOCAL_IIF] = true
|
||||
case nl.SEG6_LOCAL_OIF:
|
||||
e.Oif = int(native.Uint32(attr.Value[0:4]))
|
||||
e.Flags[nl.SEG6_LOCAL_OIF] = true
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
func (e *SEG6LocalEncap) Encode() ([]byte, error) {
|
||||
var err error
|
||||
native := nl.NativeEndian()
|
||||
res := make([]byte, 8)
|
||||
native.PutUint16(res, 8) // length
|
||||
native.PutUint16(res[2:], nl.SEG6_LOCAL_ACTION)
|
||||
native.PutUint32(res[4:], uint32(e.Action))
|
||||
if e.Flags[nl.SEG6_LOCAL_SRH] {
|
||||
srh, err := nl.EncodeSEG6Srh(e.Segments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
attr := make([]byte, 4)
|
||||
native.PutUint16(attr, uint16(len(srh)+4))
|
||||
native.PutUint16(attr[2:], nl.SEG6_LOCAL_SRH)
|
||||
attr = append(attr, srh...)
|
||||
res = append(res, attr...)
|
||||
}
|
||||
if e.Flags[nl.SEG6_LOCAL_TABLE] {
|
||||
attr := make([]byte, 8)
|
||||
native.PutUint16(attr, 8)
|
||||
native.PutUint16(attr[2:], nl.SEG6_LOCAL_TABLE)
|
||||
native.PutUint32(attr[4:], uint32(e.Table))
|
||||
res = append(res, attr...)
|
||||
}
|
||||
if e.Flags[nl.SEG6_LOCAL_NH4] {
|
||||
attr := make([]byte, 4)
|
||||
native.PutUint16(attr, 8)
|
||||
native.PutUint16(attr[2:], nl.SEG6_LOCAL_NH4)
|
||||
ipv4 := e.InAddr.To4()
|
||||
if ipv4 == nil {
|
||||
err = fmt.Errorf("SEG6_LOCAL_NH4 has invalid IPv4 address")
|
||||
return nil, err
|
||||
}
|
||||
attr = append(attr, ipv4...)
|
||||
res = append(res, attr...)
|
||||
}
|
||||
if e.Flags[nl.SEG6_LOCAL_NH6] {
|
||||
attr := make([]byte, 4)
|
||||
native.PutUint16(attr, 20)
|
||||
native.PutUint16(attr[2:], nl.SEG6_LOCAL_NH6)
|
||||
attr = append(attr, e.In6Addr...)
|
||||
res = append(res, attr...)
|
||||
}
|
||||
if e.Flags[nl.SEG6_LOCAL_IIF] {
|
||||
attr := make([]byte, 8)
|
||||
native.PutUint16(attr, 8)
|
||||
native.PutUint16(attr[2:], nl.SEG6_LOCAL_IIF)
|
||||
native.PutUint32(attr[4:], uint32(e.Iif))
|
||||
res = append(res, attr...)
|
||||
}
|
||||
if e.Flags[nl.SEG6_LOCAL_OIF] {
|
||||
attr := make([]byte, 8)
|
||||
native.PutUint16(attr, 8)
|
||||
native.PutUint16(attr[2:], nl.SEG6_LOCAL_OIF)
|
||||
native.PutUint32(attr[4:], uint32(e.Oif))
|
||||
res = append(res, attr...)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
func (e *SEG6LocalEncap) String() string {
|
||||
strs := make([]string, 0, nl.SEG6_LOCAL_MAX)
|
||||
strs = append(strs, fmt.Sprintf("action %s", nl.SEG6LocalActionString(e.Action)))
|
||||
|
||||
if e.Flags[nl.SEG6_LOCAL_TABLE] {
|
||||
strs = append(strs, fmt.Sprintf("table %d", e.Table))
|
||||
}
|
||||
if e.Flags[nl.SEG6_LOCAL_NH4] {
|
||||
strs = append(strs, fmt.Sprintf("nh4 %s", e.InAddr))
|
||||
}
|
||||
if e.Flags[nl.SEG6_LOCAL_NH6] {
|
||||
strs = append(strs, fmt.Sprintf("nh6 %s", e.In6Addr))
|
||||
}
|
||||
if e.Flags[nl.SEG6_LOCAL_IIF] {
|
||||
link, err := LinkByIndex(e.Iif)
|
||||
if err != nil {
|
||||
strs = append(strs, fmt.Sprintf("iif %d", e.Iif))
|
||||
} else {
|
||||
strs = append(strs, fmt.Sprintf("iif %s", link.Attrs().Name))
|
||||
}
|
||||
}
|
||||
if e.Flags[nl.SEG6_LOCAL_OIF] {
|
||||
link, err := LinkByIndex(e.Oif)
|
||||
if err != nil {
|
||||
strs = append(strs, fmt.Sprintf("oif %d", e.Oif))
|
||||
} else {
|
||||
strs = append(strs, fmt.Sprintf("oif %s", link.Attrs().Name))
|
||||
}
|
||||
}
|
||||
if e.Flags[nl.SEG6_LOCAL_SRH] {
|
||||
segs := make([]string, 0, len(e.Segments))
|
||||
//append segment backwards (from n to 0) since seg#0 is the last segment.
|
||||
for i := len(e.Segments); i > 0; i-- {
|
||||
segs = append(segs, fmt.Sprintf("%s", e.Segments[i-1]))
|
||||
}
|
||||
strs = append(strs, fmt.Sprintf("segs %d [ %s ]", len(e.Segments), strings.Join(segs, " ")))
|
||||
}
|
||||
return strings.Join(strs, " ")
|
||||
}
|
||||
func (e *SEG6LocalEncap) Equal(x Encap) bool {
|
||||
o, ok := x.(*SEG6LocalEncap)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if e == o {
|
||||
return true
|
||||
}
|
||||
if e == nil || o == nil {
|
||||
return false
|
||||
}
|
||||
// compare all arrays first
|
||||
for i := range e.Flags {
|
||||
if e.Flags[i] != o.Flags[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if len(e.Segments) != len(o.Segments) {
|
||||
return false
|
||||
}
|
||||
for i := range e.Segments {
|
||||
if !e.Segments[i].Equal(o.Segments[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
// compare values
|
||||
if !e.InAddr.Equal(o.InAddr) || !e.In6Addr.Equal(o.In6Addr) {
|
||||
return false
|
||||
}
|
||||
if e.Action != o.Action || e.Table != o.Table || e.Iif != o.Iif || e.Oif != o.Oif {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// RouteAdd will add a route to the system.
|
||||
// Equivalent to: `ip route add $route`
|
||||
func RouteAdd(route *Route) error {
|
||||
@ -335,18 +519,18 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(nl.RTA_NEWDST, buf))
|
||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.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))
|
||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_ENCAP_TYPE, buf))
|
||||
buf, err := route.Encap.Encode()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(nl.RTA_ENCAP, buf))
|
||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_ENCAP, buf))
|
||||
}
|
||||
|
||||
if route.Src != nil {
|
||||
@ -410,17 +594,17 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
children = append(children, nl.NewRtAttr(nl.RTA_NEWDST, buf))
|
||||
children = append(children, nl.NewRtAttr(unix.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))
|
||||
children = append(children, nl.NewRtAttr(unix.RTA_ENCAP_TYPE, buf))
|
||||
buf, err := nh.Encap.Encode()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
children = append(children, nl.NewRtAttr(nl.RTA_ENCAP, buf))
|
||||
children = append(children, nl.NewRtAttr(unix.RTA_ENCAP, buf))
|
||||
}
|
||||
rtnh.Children = children
|
||||
buf = append(buf, rtnh.Serialize()...)
|
||||
@ -464,6 +648,10 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
|
||||
b := nl.Uint32Attr(uint32(route.AdvMSS))
|
||||
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_ADVMSS, b))
|
||||
}
|
||||
if route.Hoplimit > 0 {
|
||||
b := nl.Uint32Attr(uint32(route.Hoplimit))
|
||||
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_HOPLIMIT, b))
|
||||
}
|
||||
|
||||
if metrics != nil {
|
||||
attr := nl.NewRtAttr(unix.RTA_METRICS, nil)
|
||||
@ -574,6 +762,8 @@ func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64)
|
||||
continue
|
||||
}
|
||||
}
|
||||
case filterMask&RT_FILTER_HOPLIMIT != 0 && route.Hoplimit != filter.Hoplimit:
|
||||
continue
|
||||
}
|
||||
}
|
||||
res = append(res, route)
|
||||
@ -649,7 +839,7 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||
switch attr.Attr.Type {
|
||||
case unix.RTA_GATEWAY:
|
||||
info.Gw = net.IP(attr.Value)
|
||||
case nl.RTA_NEWDST:
|
||||
case unix.RTA_NEWDST:
|
||||
var d Destination
|
||||
switch msg.Family {
|
||||
case nl.FAMILY_MPLS:
|
||||
@ -659,9 +849,9 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||
return nil, nil, err
|
||||
}
|
||||
info.NewDst = d
|
||||
case nl.RTA_ENCAP_TYPE:
|
||||
case unix.RTA_ENCAP_TYPE:
|
||||
encapType = attr
|
||||
case nl.RTA_ENCAP:
|
||||
case unix.RTA_ENCAP:
|
||||
encap = attr
|
||||
}
|
||||
}
|
||||
@ -690,7 +880,7 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||
route.MultiPath = append(route.MultiPath, info)
|
||||
rest = buf
|
||||
}
|
||||
case nl.RTA_NEWDST:
|
||||
case unix.RTA_NEWDST:
|
||||
var d Destination
|
||||
switch msg.Family {
|
||||
case nl.FAMILY_MPLS:
|
||||
@ -700,9 +890,9 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||
return route, err
|
||||
}
|
||||
route.NewDst = d
|
||||
case nl.RTA_ENCAP_TYPE:
|
||||
case unix.RTA_ENCAP_TYPE:
|
||||
encapType = attr
|
||||
case nl.RTA_ENCAP:
|
||||
case unix.RTA_ENCAP:
|
||||
encap = attr
|
||||
case unix.RTA_METRICS:
|
||||
metrics, err := nl.ParseRouteAttr(attr.Value)
|
||||
@ -715,6 +905,8 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||
route.MTU = int(native.Uint32(metric.Value[0:4]))
|
||||
case unix.RTAX_ADVMSS:
|
||||
route.AdvMSS = int(native.Uint32(metric.Value[0:4]))
|
||||
case unix.RTAX_HOPLIMIT:
|
||||
route.Hoplimit = int(native.Uint32(metric.Value[0:4]))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -734,6 +926,11 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||
if err := e.Decode(encap.Value); err != nil {
|
||||
return route, err
|
||||
}
|
||||
case nl.LWTUNNEL_ENCAP_SEG6_LOCAL:
|
||||
e = &SEG6LocalEncap{}
|
||||
if err := e.Decode(encap.Value); err != nil {
|
||||
return route, err
|
||||
}
|
||||
}
|
||||
route.Encap = e
|
||||
}
|
||||
@ -840,13 +1037,19 @@ func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <
|
||||
go func() {
|
||||
defer close(ch)
|
||||
for {
|
||||
msgs, err := s.Receive()
|
||||
msgs, from, err := s.Receive()
|
||||
if err != nil {
|
||||
if cberr != nil {
|
||||
cberr(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if from.Pid != nl.PidKernel {
|
||||
if cberr != nil {
|
||||
cberr(fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel))
|
||||
}
|
||||
continue
|
||||
}
|
||||
for _, m := range msgs {
|
||||
if m.Header.Type == unix.NLMSG_DONE {
|
||||
continue
|
||||
|
2
vendor/github.com/vishvananda/netlink/rule_linux.go
generated
vendored
2
vendor/github.com/vishvananda/netlink/rule_linux.go
generated
vendored
@ -144,7 +144,7 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
|
||||
req.AddData(nl.NewRtAttr(nl.FRA_OIFNAME, []byte(rule.OifName)))
|
||||
}
|
||||
if rule.Goto >= 0 {
|
||||
msg.Type = nl.FR_ACT_NOP
|
||||
msg.Type = nl.FR_ACT_GOTO
|
||||
b := make([]byte, 4)
|
||||
native.PutUint32(b, uint32(rule.Goto))
|
||||
req.AddData(nl.NewRtAttr(nl.FRA_GOTO, b))
|
||||
|
5
vendor/github.com/vishvananda/netlink/socket_linux.go
generated
vendored
5
vendor/github.com/vishvananda/netlink/socket_linux.go
generated
vendored
@ -141,10 +141,13 @@ func SocketGet(local, remote net.Addr) (*Socket, error) {
|
||||
},
|
||||
})
|
||||
s.Send(req)
|
||||
msgs, err := s.Receive()
|
||||
msgs, from, err := s.Receive()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if from.Pid != nl.PidKernel {
|
||||
return nil, fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel)
|
||||
}
|
||||
if len(msgs) == 0 {
|
||||
return nil, errors.New("no message nor error from netlink")
|
||||
}
|
||||
|
6
vendor/github.com/vishvananda/netlink/xfrm_monitor_linux.go
generated
vendored
6
vendor/github.com/vishvananda/netlink/xfrm_monitor_linux.go
generated
vendored
@ -54,11 +54,15 @@ func XfrmMonitor(ch chan<- XfrmMsg, done <-chan struct{}, errorChan chan<- error
|
||||
go func() {
|
||||
defer close(ch)
|
||||
for {
|
||||
msgs, err := s.Receive()
|
||||
msgs, from, err := s.Receive()
|
||||
if err != nil {
|
||||
errorChan <- err
|
||||
return
|
||||
}
|
||||
if from.Pid != nl.PidKernel {
|
||||
errorChan <- fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel)
|
||||
return
|
||||
}
|
||||
for _, m := range msgs {
|
||||
switch m.Header.Type {
|
||||
case nl.XFRM_MSG_EXPIRE:
|
||||
|
26
vendor/github.com/vishvananda/netlink/xfrm_policy.go
generated
vendored
26
vendor/github.com/vishvananda/netlink/xfrm_policy.go
generated
vendored
@ -35,6 +35,25 @@ func (d Dir) String() string {
|
||||
return fmt.Sprintf("socket %d", d-XFRM_SOCKET_IN)
|
||||
}
|
||||
|
||||
// PolicyAction is an enum representing an ipsec policy action.
|
||||
type PolicyAction uint8
|
||||
|
||||
const (
|
||||
XFRM_POLICY_ALLOW PolicyAction = 0
|
||||
XFRM_POLICY_BLOCK PolicyAction = 1
|
||||
)
|
||||
|
||||
func (a PolicyAction) String() string {
|
||||
switch a {
|
||||
case XFRM_POLICY_ALLOW:
|
||||
return "allow"
|
||||
case XFRM_POLICY_BLOCK:
|
||||
return "block"
|
||||
default:
|
||||
return fmt.Sprintf("action %d", a)
|
||||
}
|
||||
}
|
||||
|
||||
// XfrmPolicyTmpl encapsulates a rule for the base addresses of an ipsec
|
||||
// policy. These rules are matched with XfrmState to determine encryption
|
||||
// and authentication algorithms.
|
||||
@ -64,11 +83,14 @@ type XfrmPolicy struct {
|
||||
Dir Dir
|
||||
Priority int
|
||||
Index int
|
||||
Action PolicyAction
|
||||
Ifindex int
|
||||
Ifid int
|
||||
Mark *XfrmMark
|
||||
Tmpls []XfrmPolicyTmpl
|
||||
}
|
||||
|
||||
func (p XfrmPolicy) String() string {
|
||||
return fmt.Sprintf("{Dst: %v, Src: %v, Proto: %s, DstPort: %d, SrcPort: %d, Dir: %s, Priority: %d, Index: %d, Mark: %s, Tmpls: %s}",
|
||||
p.Dst, p.Src, p.Proto, p.DstPort, p.SrcPort, p.Dir, p.Priority, p.Index, p.Mark, p.Tmpls)
|
||||
return fmt.Sprintf("{Dst: %v, Src: %v, Proto: %s, DstPort: %d, SrcPort: %d, Dir: %s, Priority: %d, Index: %d, Action: %s, Ifindex: %d, Ifid: %d, Mark: %s, Tmpls: %s}",
|
||||
p.Dst, p.Src, p.Proto, p.DstPort, p.SrcPort, p.Dir, p.Priority, p.Index, p.Action, p.Ifindex, p.Ifid, p.Mark, p.Tmpls)
|
||||
}
|
||||
|
19
vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go
generated
vendored
19
vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go
generated
vendored
@ -27,6 +27,7 @@ func selFromPolicy(sel *nl.XfrmSelector, policy *XfrmPolicy) {
|
||||
if sel.Sport != 0 {
|
||||
sel.SportMask = ^uint16(0)
|
||||
}
|
||||
sel.Ifindex = int32(policy.Ifindex)
|
||||
}
|
||||
|
||||
// XfrmPolicyAdd will add an xfrm policy to the system.
|
||||
@ -61,6 +62,7 @@ func (h *Handle) xfrmPolicyAddOrUpdate(policy *XfrmPolicy, nlProto int) error {
|
||||
msg.Priority = uint32(policy.Priority)
|
||||
msg.Index = uint32(policy.Index)
|
||||
msg.Dir = uint8(policy.Dir)
|
||||
msg.Action = uint8(policy.Action)
|
||||
msg.Lft.SoftByteLimit = nl.XFRM_INF
|
||||
msg.Lft.HardByteLimit = nl.XFRM_INF
|
||||
msg.Lft.SoftPacketLimit = nl.XFRM_INF
|
||||
@ -90,6 +92,9 @@ func (h *Handle) xfrmPolicyAddOrUpdate(policy *XfrmPolicy, nlProto int) error {
|
||||
req.AddData(out)
|
||||
}
|
||||
|
||||
ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(policy.Ifid)))
|
||||
req.AddData(ifId)
|
||||
|
||||
_, err := req.Execute(unix.NETLINK_XFRM, 0)
|
||||
return err
|
||||
}
|
||||
@ -183,6 +188,9 @@ func (h *Handle) xfrmPolicyGetOrDelete(policy *XfrmPolicy, nlProto int) (*XfrmPo
|
||||
req.AddData(out)
|
||||
}
|
||||
|
||||
ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(policy.Ifid)))
|
||||
req.AddData(ifId)
|
||||
|
||||
resType := nl.XFRM_MSG_NEWPOLICY
|
||||
if nlProto == nl.XFRM_MSG_DELPOLICY {
|
||||
resType = 0
|
||||
@ -197,12 +205,7 @@ func (h *Handle) xfrmPolicyGetOrDelete(policy *XfrmPolicy, nlProto int) (*XfrmPo
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p, err := parseXfrmPolicy(msgs[0], FAMILY_ALL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return p, nil
|
||||
return parseXfrmPolicy(msgs[0], FAMILY_ALL)
|
||||
}
|
||||
|
||||
func parseXfrmPolicy(m []byte, family int) (*XfrmPolicy, error) {
|
||||
@ -220,9 +223,11 @@ func parseXfrmPolicy(m []byte, family int) (*XfrmPolicy, error) {
|
||||
policy.Proto = Proto(msg.Sel.Proto)
|
||||
policy.DstPort = int(nl.Swap16(msg.Sel.Dport))
|
||||
policy.SrcPort = int(nl.Swap16(msg.Sel.Sport))
|
||||
policy.Ifindex = int(msg.Sel.Ifindex)
|
||||
policy.Priority = int(msg.Priority)
|
||||
policy.Index = int(msg.Index)
|
||||
policy.Dir = Dir(msg.Dir)
|
||||
policy.Action = PolicyAction(msg.Action)
|
||||
|
||||
attrs, err := nl.ParseRouteAttr(m[msg.Len():])
|
||||
if err != nil {
|
||||
@ -249,6 +254,8 @@ func parseXfrmPolicy(m []byte, family int) (*XfrmPolicy, error) {
|
||||
policy.Mark = new(XfrmMark)
|
||||
policy.Mark.Value = mark.Value
|
||||
policy.Mark.Mask = mark.Mask
|
||||
case nl.XFRMA_IF_ID:
|
||||
policy.Ifid = int(native.Uint32(attr.Value))
|
||||
}
|
||||
}
|
||||
|
||||
|
6
vendor/github.com/vishvananda/netlink/xfrm_state.go
generated
vendored
6
vendor/github.com/vishvananda/netlink/xfrm_state.go
generated
vendored
@ -94,6 +94,8 @@ type XfrmState struct {
|
||||
Limits XfrmStateLimits
|
||||
Statistics XfrmStateStats
|
||||
Mark *XfrmMark
|
||||
OutputMark int
|
||||
Ifid int
|
||||
Auth *XfrmStateAlgo
|
||||
Crypt *XfrmStateAlgo
|
||||
Aead *XfrmStateAlgo
|
||||
@ -102,8 +104,8 @@ type XfrmState struct {
|
||||
}
|
||||
|
||||
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, ESN: %t",
|
||||
sa.Dst, sa.Src, sa.Proto, sa.Mode, sa.Spi, sa.Reqid, sa.ReplayWindow, sa.Mark, sa.Auth, sa.Crypt, sa.Aead, sa.Encap, sa.ESN)
|
||||
return fmt.Sprintf("Dst: %v, Src: %v, Proto: %s, Mode: %s, SPI: 0x%x, ReqID: 0x%x, ReplayWindow: %d, Mark: %v, OutputMark: %d, Ifid: %d, 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.OutputMark, sa.Ifid, sa.Auth, sa.Crypt, sa.Aead, sa.Encap, sa.ESN)
|
||||
}
|
||||
func (sa XfrmState) Print(stats bool) string {
|
||||
if !stats {
|
||||
|
27
vendor/github.com/vishvananda/netlink/xfrm_state_linux.go
generated
vendored
27
vendor/github.com/vishvananda/netlink/xfrm_state_linux.go
generated
vendored
@ -158,6 +158,13 @@ func (h *Handle) xfrmStateAddOrUpdate(state *XfrmState, nlProto int) error {
|
||||
out := nl.NewRtAttr(nl.XFRMA_REPLAY_ESN_VAL, writeReplayEsn(state.ReplayWindow))
|
||||
req.AddData(out)
|
||||
}
|
||||
if state.OutputMark != 0 {
|
||||
out := nl.NewRtAttr(nl.XFRMA_OUTPUT_MARK, nl.Uint32Attr(uint32(state.OutputMark)))
|
||||
req.AddData(out)
|
||||
}
|
||||
|
||||
ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(state.Ifid)))
|
||||
req.AddData(ifId)
|
||||
|
||||
_, err := req.Execute(unix.NETLINK_XFRM, 0)
|
||||
return err
|
||||
@ -184,12 +191,7 @@ func (h *Handle) xfrmStateAllocSpi(state *XfrmState) (*XfrmState, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s, err := parseXfrmState(msgs[0], FAMILY_ALL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s, err
|
||||
return parseXfrmState(msgs[0], FAMILY_ALL)
|
||||
}
|
||||
|
||||
// XfrmStateDel will delete an xfrm state from the system. Note that
|
||||
@ -275,6 +277,9 @@ func (h *Handle) xfrmStateGetOrDelete(state *XfrmState, nlProto int) (*XfrmState
|
||||
req.AddData(out)
|
||||
}
|
||||
|
||||
ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(state.Ifid)))
|
||||
req.AddData(ifId)
|
||||
|
||||
resType := nl.XFRM_MSG_NEWSA
|
||||
if nlProto == nl.XFRM_MSG_DELSA {
|
||||
resType = 0
|
||||
@ -372,6 +377,10 @@ func parseXfrmState(m []byte, family int) (*XfrmState, error) {
|
||||
state.Mark = new(XfrmMark)
|
||||
state.Mark.Value = mark.Value
|
||||
state.Mark.Mask = mark.Mask
|
||||
case nl.XFRMA_OUTPUT_MARK:
|
||||
state.OutputMark = int(native.Uint32(attr.Value))
|
||||
case nl.XFRMA_IF_ID:
|
||||
state.Ifid = int(native.Uint32(attr.Value))
|
||||
}
|
||||
}
|
||||
|
||||
@ -394,11 +403,7 @@ func (h *Handle) XfrmStateFlush(proto Proto) error {
|
||||
req.AddData(&nl.XfrmUsersaFlush{Proto: uint8(proto)})
|
||||
|
||||
_, err := req.Execute(unix.NETLINK_XFRM, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func limitsToLft(lmts XfrmStateLimits, lft *nl.XfrmLifetimeCfg) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user