mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-11-03 23:40:03 +00:00 
			
		
		
		
	Update ipvs library to the new repo and upgrade library version
This commit is contained in:
		
							
								
								
									
										38
									
								
								vendor/github.com/moby/ipvs/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								vendor/github.com/moby/ipvs/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
 | 
			
		||||
*.o
 | 
			
		||||
*.a
 | 
			
		||||
*.so
 | 
			
		||||
*~
 | 
			
		||||
.gtm
 | 
			
		||||
tags
 | 
			
		||||
.DS_Store
 | 
			
		||||
 | 
			
		||||
# Folders
 | 
			
		||||
_obj
 | 
			
		||||
_test
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Architecture specific extensions/prefixes
 | 
			
		||||
*.[568vq]
 | 
			
		||||
[568vq].out
 | 
			
		||||
 | 
			
		||||
*.cgo1.go
 | 
			
		||||
*.cgo2.c
 | 
			
		||||
_cgo_defun.c
 | 
			
		||||
_cgo_gotypes.go
 | 
			
		||||
_cgo_export.*
 | 
			
		||||
 | 
			
		||||
_testmain.go
 | 
			
		||||
 | 
			
		||||
*.exe
 | 
			
		||||
*.test
 | 
			
		||||
*.prof
 | 
			
		||||
 | 
			
		||||
# Coverage
 | 
			
		||||
*.tmp
 | 
			
		||||
*.coverprofile
 | 
			
		||||
 | 
			
		||||
# IDE files and folders
 | 
			
		||||
.project
 | 
			
		||||
.settings/
 | 
			
		||||
.idea/
 | 
			
		||||
							
								
								
									
										5
									
								
								vendor/github.com/docker/libnetwork/ipvs/BUILD → vendor/github.com/moby/ipvs/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/docker/libnetwork/ipvs/BUILD → vendor/github.com/moby/ipvs/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -4,11 +4,12 @@ go_library(
 | 
			
		||||
    name = "go_default_library",
 | 
			
		||||
    srcs = [
 | 
			
		||||
        "constants.go",
 | 
			
		||||
        "doc.go",
 | 
			
		||||
        "ipvs.go",
 | 
			
		||||
        "netlink.go",
 | 
			
		||||
    ],
 | 
			
		||||
    importmap = "k8s.io/kubernetes/vendor/github.com/docker/libnetwork/ipvs",
 | 
			
		||||
    importpath = "github.com/docker/libnetwork/ipvs",
 | 
			
		||||
    importmap = "k8s.io/kubernetes/vendor/github.com/moby/ipvs",
 | 
			
		||||
    importpath = "github.com/moby/ipvs",
 | 
			
		||||
    visibility = ["//visibility:public"],
 | 
			
		||||
    deps = select({
 | 
			
		||||
        "@io_bazel_rules_go//go/platform:android": [
 | 
			
		||||
							
								
								
									
										0
									
								
								vendor/github.com/docker/libnetwork/LICENSE → vendor/github.com/moby/ipvs/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										0
									
								
								vendor/github.com/docker/libnetwork/LICENSE → vendor/github.com/moby/ipvs/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
								
								
									
										34
									
								
								vendor/github.com/moby/ipvs/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								vendor/github.com/moby/ipvs/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
# ipvs - networking for containers
 | 
			
		||||
 | 
			
		||||
 [](https://godoc.org/github.com/moby/ipvs) [](https://goreportcard.com/report/github.com/moby/ipvs)
 | 
			
		||||
 | 
			
		||||
ipvs provides a native Go implementation for communicating with IPVS kernel module using a netlink socket.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#### Using ipvs
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
import (
 | 
			
		||||
	"log"
 | 
			
		||||
 | 
			
		||||
	"github.com/moby/ipvs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	handle, err := ipvs.New("")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatalf("ipvs.New: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
	svcs, err := handle.GetServices()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatalf("handle.GetServices: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Contributing
 | 
			
		||||
 | 
			
		||||
Want to hack on ipvs? [Docker's contributions guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md) apply.
 | 
			
		||||
 | 
			
		||||
## Copyright and license
 | 
			
		||||
Code and documentation copyright 2015 Docker, inc. Code released under the Apache 2.0 license. Docs released under Creative commons.
 | 
			
		||||
							
								
								
									
										1
									
								
								vendor/github.com/moby/ipvs/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/moby/ipvs/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
package ipvs
 | 
			
		||||
							
								
								
									
										12
									
								
								vendor/github.com/moby/ipvs/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/moby/ipvs/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
module github.com/moby/ipvs
 | 
			
		||||
 | 
			
		||||
go 1.13
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	github.com/pkg/errors v0.9.1 // indirect
 | 
			
		||||
	github.com/sirupsen/logrus v1.4.2
 | 
			
		||||
	github.com/vishvananda/netlink v1.1.0
 | 
			
		||||
	github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df
 | 
			
		||||
	golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527
 | 
			
		||||
	gotest.tools/v3 v3.0.2
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										35
									
								
								vendor/github.com/moby/ipvs/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								vendor/github.com/moby/ipvs/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 | 
			
		||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
			
		||||
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
 | 
			
		||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 | 
			
		||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
 | 
			
		||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 | 
			
		||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 | 
			
		||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
			
		||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 | 
			
		||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
			
		||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 | 
			
		||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 | 
			
		||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
 | 
			
		||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 | 
			
		||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 | 
			
		||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 | 
			
		||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
 | 
			
		||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 | 
			
		||||
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
 | 
			
		||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
 | 
			
		||||
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/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 | 
			
		||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 | 
			
		||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444 h1:/d2cWp6PSamH4jDPFLyO150psQdqvtoNX8Zjg3AQ31g=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
 | 
			
		||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
			
		||||
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
 | 
			
		||||
gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E=
 | 
			
		||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
 | 
			
		||||
@@ -217,7 +217,7 @@ func execute(s *nl.NetlinkSocket, req *nl.NetlinkRequest, resType uint16) ([][]b
 | 
			
		||||
 | 
			
		||||
done:
 | 
			
		||||
	for {
 | 
			
		||||
		msgs, err := s.Receive()
 | 
			
		||||
		msgs, _, err := s.Receive()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if s.GetFd() == -1 {
 | 
			
		||||
				return nil, fmt.Errorf("Socket got closed on receive")
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								vendor/github.com/vishvananda/netlink/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/vishvananda/netlink/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -11,6 +11,7 @@ go_library(
 | 
			
		||||
        "class_linux.go",
 | 
			
		||||
        "conntrack_linux.go",
 | 
			
		||||
        "conntrack_unspecified.go",
 | 
			
		||||
        "devlink_linux.go",
 | 
			
		||||
        "filter.go",
 | 
			
		||||
        "filter_linux.go",
 | 
			
		||||
        "fou.go",
 | 
			
		||||
@@ -30,11 +31,14 @@ go_library(
 | 
			
		||||
        "netlink.go",
 | 
			
		||||
        "netlink_linux.go",
 | 
			
		||||
        "netlink_unspecified.go",
 | 
			
		||||
        "netns_linux.go",
 | 
			
		||||
        "netns_unspecified.go",
 | 
			
		||||
        "order.go",
 | 
			
		||||
        "protinfo.go",
 | 
			
		||||
        "protinfo_linux.go",
 | 
			
		||||
        "qdisc.go",
 | 
			
		||||
        "qdisc_linux.go",
 | 
			
		||||
        "rdma_link_linux.go",
 | 
			
		||||
        "route.go",
 | 
			
		||||
        "route_linux.go",
 | 
			
		||||
        "route_unspecified.go",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										3
									
								
								vendor/github.com/vishvananda/netlink/nl/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/vishvananda/netlink/nl/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -6,13 +6,16 @@ go_library(
 | 
			
		||||
        "addr_linux.go",
 | 
			
		||||
        "bridge_linux.go",
 | 
			
		||||
        "conntrack_linux.go",
 | 
			
		||||
        "devlink_linux.go",
 | 
			
		||||
        "genetlink_linux.go",
 | 
			
		||||
        "link_linux.go",
 | 
			
		||||
        "mpls_linux.go",
 | 
			
		||||
        "nl_linux.go",
 | 
			
		||||
        "nl_unspecified.go",
 | 
			
		||||
        "rdma_link_linux.go",
 | 
			
		||||
        "route_linux.go",
 | 
			
		||||
        "seg6_linux.go",
 | 
			
		||||
        "seg6local_linux.go",
 | 
			
		||||
        "syscall.go",
 | 
			
		||||
        "tc_linux.go",
 | 
			
		||||
        "xfrm_linux.go",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user