mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	bump: github.com/vishvananda/netlink to v1.3.0
Signed-off-by: Daman Arora <aroradaman@gmail.com>
This commit is contained in:
		
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							@@ -57,7 +57,7 @@ require (
 | 
				
			|||||||
	github.com/spf13/cobra v1.8.1
 | 
						github.com/spf13/cobra v1.8.1
 | 
				
			||||||
	github.com/spf13/pflag v1.0.5
 | 
						github.com/spf13/pflag v1.0.5
 | 
				
			||||||
	github.com/stretchr/testify v1.9.0
 | 
						github.com/stretchr/testify v1.9.0
 | 
				
			||||||
	github.com/vishvananda/netlink v1.1.0
 | 
						github.com/vishvananda/netlink v1.3.0
 | 
				
			||||||
	github.com/vishvananda/netns v0.0.4
 | 
						github.com/vishvananda/netns v0.0.4
 | 
				
			||||||
	go.etcd.io/etcd/api/v3 v3.5.14
 | 
						go.etcd.io/etcd/api/v3 v3.5.14
 | 
				
			||||||
	go.etcd.io/etcd/client/pkg/v3 v3.5.14
 | 
						go.etcd.io/etcd/client/pkg/v3 v3.5.14
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										8
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								go.sum
									
									
									
									
									
								
							@@ -572,9 +572,8 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7
 | 
				
			|||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk=
 | 
					github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk=
 | 
				
			||||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
 | 
					github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
 | 
				
			||||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
 | 
					github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
 | 
				
			||||||
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
 | 
					github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQdrZk=
 | 
				
			||||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
 | 
					github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs=
 | 
				
			||||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
 | 
					 | 
				
			||||||
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
 | 
					github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
 | 
				
			||||||
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
 | 
					github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
 | 
				
			||||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
 | 
					github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
 | 
				
			||||||
@@ -699,7 +698,6 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
 | 
				
			|||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					 | 
				
			||||||
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
@@ -715,6 +713,8 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc
 | 
				
			|||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
					golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
					golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
				
			||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
					golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
				
			||||||
 | 
					golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
				
			||||||
 | 
					golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
				
			||||||
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
 | 
					golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
 | 
				
			||||||
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 | 
					golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 | 
				
			||||||
golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=
 | 
					golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								vendor/github.com/vishvananda/netlink/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/vishvananda/netlink/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1 +1,2 @@
 | 
				
			|||||||
.idea/
 | 
					.idea/
 | 
				
			||||||
 | 
					.vscode/
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								vendor/github.com/vishvananda/netlink/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/github.com/vishvananda/netlink/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,19 +0,0 @@
 | 
				
			|||||||
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
 | 
					 | 
				
			||||||
  # modprobe ip_gre or else the first gre device can't be deleted
 | 
					 | 
				
			||||||
  - sudo modprobe ip_gre
 | 
					 | 
				
			||||||
  # modprobe nf_conntrack for the conntrack testing
 | 
					 | 
				
			||||||
  - sudo modprobe nf_conntrack
 | 
					 | 
				
			||||||
  - 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
 | 
					 | 
				
			||||||
							
								
								
									
										2
									
								
								vendor/github.com/vishvananda/netlink/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/vishvananda/netlink/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,6 +1,6 @@
 | 
				
			|||||||
# netlink - netlink library for go #
 | 
					# netlink - netlink library for go #
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[](https://travis-ci.org/vishvananda/netlink) [](https://godoc.org/github.com/vishvananda/netlink)
 | 
					 [](https://godoc.org/github.com/vishvananda/netlink)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The netlink package provides a simple netlink library for go. Netlink
 | 
					The netlink package provides a simple netlink library for go. Netlink
 | 
				
			||||||
is the interface a user-space program in linux uses to communicate with
 | 
					is the interface a user-space program in linux uses to communicate with
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								vendor/github.com/vishvananda/netlink/addr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/vishvananda/netlink/addr.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -17,6 +17,7 @@ type Addr struct {
 | 
				
			|||||||
	Broadcast   net.IP
 | 
						Broadcast   net.IP
 | 
				
			||||||
	PreferedLft int
 | 
						PreferedLft int
 | 
				
			||||||
	ValidLft    int
 | 
						ValidLft    int
 | 
				
			||||||
 | 
						LinkIndex   int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// String returns $ip/$netmask $label
 | 
					// String returns $ip/$netmask $label
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										84
									
								
								vendor/github.com/vishvananda/netlink/addr_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										84
									
								
								vendor/github.com/vishvananda/netlink/addr_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -11,9 +11,6 @@ import (
 | 
				
			|||||||
	"golang.org/x/sys/unix"
 | 
						"golang.org/x/sys/unix"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// IFA_FLAGS is a u32 attribute.
 | 
					 | 
				
			||||||
const IFA_FLAGS = 0x8
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// AddrAdd will add an IP address to a link device.
 | 
					// AddrAdd will add an IP address to a link device.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Equivalent to: `ip addr add $addr dev $link`
 | 
					// Equivalent to: `ip addr add $addr dev $link`
 | 
				
			||||||
@@ -77,17 +74,19 @@ func (h *Handle) AddrDel(link Link, addr *Addr) error {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error {
 | 
					func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error {
 | 
				
			||||||
 | 
						family := nl.GetIPFamily(addr.IP)
 | 
				
			||||||
 | 
						msg := nl.NewIfAddrmsg(family)
 | 
				
			||||||
 | 
						msg.Scope = uint8(addr.Scope)
 | 
				
			||||||
 | 
						if link == nil {
 | 
				
			||||||
 | 
							msg.Index = uint32(addr.LinkIndex)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
		base := link.Attrs()
 | 
							base := link.Attrs()
 | 
				
			||||||
		if addr.Label != "" && !strings.HasPrefix(addr.Label, base.Name) {
 | 
							if addr.Label != "" && !strings.HasPrefix(addr.Label, base.Name) {
 | 
				
			||||||
			return fmt.Errorf("label must begin with interface name")
 | 
								return fmt.Errorf("label must begin with interface name")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		h.ensureIndex(base)
 | 
							h.ensureIndex(base)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	family := nl.GetIPFamily(addr.IP)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	msg := nl.NewIfAddrmsg(family)
 | 
					 | 
				
			||||||
		msg.Index = uint32(base.Index)
 | 
							msg.Index = uint32(base.Index)
 | 
				
			||||||
	msg.Scope = uint8(addr.Scope)
 | 
						}
 | 
				
			||||||
	mask := addr.Mask
 | 
						mask := addr.Mask
 | 
				
			||||||
	if addr.Peer != nil {
 | 
						if addr.Peer != nil {
 | 
				
			||||||
		mask = addr.Peer.Mask
 | 
							mask = addr.Peer.Mask
 | 
				
			||||||
@@ -125,7 +124,7 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error
 | 
				
			|||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			b := make([]byte, 4)
 | 
								b := make([]byte, 4)
 | 
				
			||||||
			native.PutUint32(b, uint32(addr.Flags))
 | 
								native.PutUint32(b, uint32(addr.Flags))
 | 
				
			||||||
			flagsData := nl.NewRtAttr(IFA_FLAGS, b)
 | 
								flagsData := nl.NewRtAttr(unix.IFA_FLAGS, b)
 | 
				
			||||||
			req.AddData(flagsData)
 | 
								req.AddData(flagsData)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -156,10 +155,10 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error
 | 
				
			|||||||
	// value should be "forever". To compensate for that, only add the attributes if at least one of the values is
 | 
						// value should be "forever". To compensate for that, only add the attributes if at least one of the values is
 | 
				
			||||||
	// non-zero, which means the caller has explicitly set them
 | 
						// non-zero, which means the caller has explicitly set them
 | 
				
			||||||
	if addr.ValidLft > 0 || addr.PreferedLft > 0 {
 | 
						if addr.ValidLft > 0 || addr.PreferedLft > 0 {
 | 
				
			||||||
		cachedata := nl.IfaCacheInfo{
 | 
							cachedata := nl.IfaCacheInfo{unix.IfaCacheinfo{
 | 
				
			||||||
			IfaValid:    uint32(addr.ValidLft),
 | 
								Valid:    uint32(addr.ValidLft),
 | 
				
			||||||
			IfaPrefered: uint32(addr.PreferedLft),
 | 
								Prefered: uint32(addr.PreferedLft),
 | 
				
			||||||
		}
 | 
							}}
 | 
				
			||||||
		req.AddData(nl.NewRtAttr(unix.IFA_CACHEINFO, cachedata.Serialize()))
 | 
							req.AddData(nl.NewRtAttr(unix.IFA_CACHEINFO, cachedata.Serialize()))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -179,7 +178,7 @@ func AddrList(link Link, family int) ([]Addr, error) {
 | 
				
			|||||||
// The list can be filtered by link and ip family.
 | 
					// The list can be filtered by link and ip family.
 | 
				
			||||||
func (h *Handle) AddrList(link Link, family int) ([]Addr, error) {
 | 
					func (h *Handle) AddrList(link Link, family int) ([]Addr, error) {
 | 
				
			||||||
	req := h.newNetlinkRequest(unix.RTM_GETADDR, unix.NLM_F_DUMP)
 | 
						req := h.newNetlinkRequest(unix.RTM_GETADDR, unix.NLM_F_DUMP)
 | 
				
			||||||
	msg := nl.NewIfInfomsg(family)
 | 
						msg := nl.NewIfAddrmsg(family)
 | 
				
			||||||
	req.AddData(msg)
 | 
						req.AddData(msg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWADDR)
 | 
						msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWADDR)
 | 
				
			||||||
@@ -196,12 +195,12 @@ func (h *Handle) AddrList(link Link, family int) ([]Addr, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	var res []Addr
 | 
						var res []Addr
 | 
				
			||||||
	for _, m := range msgs {
 | 
						for _, m := range msgs {
 | 
				
			||||||
		addr, msgFamily, ifindex, err := parseAddr(m)
 | 
							addr, msgFamily, err := parseAddr(m)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return res, err
 | 
								return res, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if link != nil && ifindex != indexFilter {
 | 
							if link != nil && addr.LinkIndex != indexFilter {
 | 
				
			||||||
			// Ignore messages from other interfaces
 | 
								// Ignore messages from other interfaces
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -216,11 +215,11 @@ func (h *Handle) AddrList(link Link, family int) ([]Addr, error) {
 | 
				
			|||||||
	return res, nil
 | 
						return res, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseAddr(m []byte) (addr Addr, family, index int, err error) {
 | 
					func parseAddr(m []byte) (addr Addr, family int, err error) {
 | 
				
			||||||
	msg := nl.DeserializeIfAddrmsg(m)
 | 
						msg := nl.DeserializeIfAddrmsg(m)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	family = -1
 | 
						family = -1
 | 
				
			||||||
	index = -1
 | 
						addr.LinkIndex = -1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	attrs, err1 := nl.ParseRouteAttr(m[msg.Len():])
 | 
						attrs, err1 := nl.ParseRouteAttr(m[msg.Len():])
 | 
				
			||||||
	if err1 != nil {
 | 
						if err1 != nil {
 | 
				
			||||||
@@ -229,7 +228,7 @@ func parseAddr(m []byte) (addr Addr, family, index int, err error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	family = int(msg.Family)
 | 
						family = int(msg.Family)
 | 
				
			||||||
	index = int(msg.Index)
 | 
						addr.LinkIndex = int(msg.Index)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var local, dst *net.IPNet
 | 
						var local, dst *net.IPNet
 | 
				
			||||||
	for _, attr := range attrs {
 | 
						for _, attr := range attrs {
 | 
				
			||||||
@@ -254,12 +253,12 @@ func parseAddr(m []byte) (addr Addr, family, index int, err error) {
 | 
				
			|||||||
			addr.Broadcast = attr.Value
 | 
								addr.Broadcast = attr.Value
 | 
				
			||||||
		case unix.IFA_LABEL:
 | 
							case unix.IFA_LABEL:
 | 
				
			||||||
			addr.Label = string(attr.Value[:len(attr.Value)-1])
 | 
								addr.Label = string(attr.Value[:len(attr.Value)-1])
 | 
				
			||||||
		case IFA_FLAGS:
 | 
							case unix.IFA_FLAGS:
 | 
				
			||||||
			addr.Flags = int(native.Uint32(attr.Value[0:4]))
 | 
								addr.Flags = int(native.Uint32(attr.Value[0:4]))
 | 
				
			||||||
		case nl.IFA_CACHEINFO:
 | 
							case unix.IFA_CACHEINFO:
 | 
				
			||||||
			ci := nl.DeserializeIfaCacheInfo(attr.Value)
 | 
								ci := nl.DeserializeIfaCacheInfo(attr.Value)
 | 
				
			||||||
			addr.PreferedLft = int(ci.IfaPrefered)
 | 
								addr.PreferedLft = int(ci.Prefered)
 | 
				
			||||||
			addr.ValidLft = int(ci.IfaValid)
 | 
								addr.ValidLft = int(ci.Valid)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -271,7 +270,7 @@ func parseAddr(m []byte) (addr Addr, family, index int, err error) {
 | 
				
			|||||||
	// But obviously, as there are IPv6 PtP addresses, too,
 | 
						// But obviously, as there are IPv6 PtP addresses, too,
 | 
				
			||||||
	// IFA_LOCAL should also be handled for IPv6.
 | 
						// IFA_LOCAL should also be handled for IPv6.
 | 
				
			||||||
	if local != nil {
 | 
						if local != nil {
 | 
				
			||||||
		if family == FAMILY_V4 && local.IP.Equal(dst.IP) {
 | 
							if family == FAMILY_V4 && dst != nil && local.IP.Equal(dst.IP) {
 | 
				
			||||||
			addr.IPNet = dst
 | 
								addr.IPNet = dst
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			addr.IPNet = local
 | 
								addr.IPNet = local
 | 
				
			||||||
@@ -299,13 +298,13 @@ type AddrUpdate struct {
 | 
				
			|||||||
// AddrSubscribe takes a chan down which notifications will be sent
 | 
					// AddrSubscribe takes a chan down which notifications will be sent
 | 
				
			||||||
// when addresses change.  Close the 'done' chan to stop subscription.
 | 
					// when addresses change.  Close the 'done' chan to stop subscription.
 | 
				
			||||||
func AddrSubscribe(ch chan<- AddrUpdate, done <-chan struct{}) error {
 | 
					func AddrSubscribe(ch chan<- AddrUpdate, done <-chan struct{}) error {
 | 
				
			||||||
	return addrSubscribeAt(netns.None(), netns.None(), ch, done, nil, false, 0)
 | 
						return addrSubscribeAt(netns.None(), netns.None(), ch, done, nil, false, 0, nil, false)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AddrSubscribeAt works like AddrSubscribe plus it allows the caller
 | 
					// AddrSubscribeAt works like AddrSubscribe plus it allows the caller
 | 
				
			||||||
// to choose the network namespace in which to subscribe (ns).
 | 
					// to choose the network namespace in which to subscribe (ns).
 | 
				
			||||||
func AddrSubscribeAt(ns netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}) error {
 | 
					func AddrSubscribeAt(ns netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}) error {
 | 
				
			||||||
	return addrSubscribeAt(ns, netns.None(), ch, done, nil, false, 0)
 | 
						return addrSubscribeAt(ns, netns.None(), ch, done, nil, false, 0, nil, false)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AddrSubscribeOptions contains a set of options to use with
 | 
					// AddrSubscribeOptions contains a set of options to use with
 | 
				
			||||||
@@ -315,6 +314,8 @@ type AddrSubscribeOptions struct {
 | 
				
			|||||||
	ErrorCallback          func(error)
 | 
						ErrorCallback          func(error)
 | 
				
			||||||
	ListExisting           bool
 | 
						ListExisting           bool
 | 
				
			||||||
	ReceiveBufferSize      int
 | 
						ReceiveBufferSize      int
 | 
				
			||||||
 | 
						ReceiveBufferForceSize bool
 | 
				
			||||||
 | 
						ReceiveTimeout         *unix.Timeval
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AddrSubscribeWithOptions work like AddrSubscribe but enable to
 | 
					// AddrSubscribeWithOptions work like AddrSubscribe but enable to
 | 
				
			||||||
@@ -325,26 +326,33 @@ func AddrSubscribeWithOptions(ch chan<- AddrUpdate, done <-chan struct{}, option
 | 
				
			|||||||
		none := netns.None()
 | 
							none := netns.None()
 | 
				
			||||||
		options.Namespace = &none
 | 
							options.Namespace = &none
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return addrSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting, options.ReceiveBufferSize)
 | 
						return addrSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting,
 | 
				
			||||||
 | 
							options.ReceiveBufferSize, options.ReceiveTimeout, options.ReceiveBufferForceSize)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}, cberr func(error), listExisting bool, rcvbuf int) error {
 | 
					func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}, cberr func(error), listExisting bool,
 | 
				
			||||||
 | 
						rcvbuf int, rcvTimeout *unix.Timeval, rcvBufForce bool) error {
 | 
				
			||||||
	s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_IPV4_IFADDR, unix.RTNLGRP_IPV6_IFADDR)
 | 
						s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_IPV4_IFADDR, unix.RTNLGRP_IPV6_IFADDR)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if rcvTimeout != nil {
 | 
				
			||||||
 | 
							if err := s.SetReceiveTimeout(rcvTimeout); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if rcvbuf != 0 {
 | 
				
			||||||
 | 
							err = s.SetReceiveBufferSize(rcvbuf, rcvBufForce)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if done != nil {
 | 
						if done != nil {
 | 
				
			||||||
		go func() {
 | 
							go func() {
 | 
				
			||||||
			<-done
 | 
								<-done
 | 
				
			||||||
			s.Close()
 | 
								s.Close()
 | 
				
			||||||
		}()
 | 
							}()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if rcvbuf != 0 {
 | 
					 | 
				
			||||||
		err = pkgHandle.SetSocketReceiveBufferSize(rcvbuf, false)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if listExisting {
 | 
						if listExisting {
 | 
				
			||||||
		req := pkgHandle.newNetlinkRequest(unix.RTM_GETADDR,
 | 
							req := pkgHandle.newNetlinkRequest(unix.RTM_GETADDR,
 | 
				
			||||||
			unix.NLM_F_DUMP)
 | 
								unix.NLM_F_DUMP)
 | 
				
			||||||
@@ -360,7 +368,8 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c
 | 
				
			|||||||
			msgs, from, err := s.Receive()
 | 
								msgs, from, err := s.Receive()
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				if cberr != nil {
 | 
									if cberr != nil {
 | 
				
			||||||
					cberr(err)
 | 
										cberr(fmt.Errorf("Receive failed: %v",
 | 
				
			||||||
 | 
											err))
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -375,7 +384,6 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c
 | 
				
			|||||||
					continue
 | 
										continue
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				if m.Header.Type == unix.NLMSG_ERROR {
 | 
									if m.Header.Type == unix.NLMSG_ERROR {
 | 
				
			||||||
					native := nl.NativeEndian()
 | 
					 | 
				
			||||||
					error := int32(native.Uint32(m.Data[0:4]))
 | 
										error := int32(native.Uint32(m.Data[0:4]))
 | 
				
			||||||
					if error == 0 {
 | 
										if error == 0 {
 | 
				
			||||||
						continue
 | 
											continue
 | 
				
			||||||
@@ -394,7 +402,7 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c
 | 
				
			|||||||
					continue
 | 
										continue
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				addr, _, ifindex, err := parseAddr(m.Data)
 | 
									addr, _, err := parseAddr(m.Data)
 | 
				
			||||||
				if err != nil {
 | 
									if err != nil {
 | 
				
			||||||
					if cberr != nil {
 | 
										if cberr != nil {
 | 
				
			||||||
						cberr(fmt.Errorf("could not parse address: %v", err))
 | 
											cberr(fmt.Errorf("could not parse address: %v", err))
 | 
				
			||||||
@@ -403,7 +411,7 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				ch <- AddrUpdate{LinkAddress: *addr.IPNet,
 | 
									ch <- AddrUpdate{LinkAddress: *addr.IPNet,
 | 
				
			||||||
					LinkIndex:   ifindex,
 | 
										LinkIndex:   addr.LinkIndex,
 | 
				
			||||||
					NewAddr:     msgType == unix.RTM_NEWADDR,
 | 
										NewAddr:     msgType == unix.RTM_NEWADDR,
 | 
				
			||||||
					Flags:       addr.Flags,
 | 
										Flags:       addr.Flags,
 | 
				
			||||||
					Scope:       addr.Scope,
 | 
										Scope:       addr.Scope,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										24
									
								
								vendor/github.com/vishvananda/netlink/bpf_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								vendor/github.com/vishvananda/netlink/bpf_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -16,6 +16,30 @@ const (
 | 
				
			|||||||
	BPF_PROG_TYPE_SCHED_ACT
 | 
						BPF_PROG_TYPE_SCHED_ACT
 | 
				
			||||||
	BPF_PROG_TYPE_TRACEPOINT
 | 
						BPF_PROG_TYPE_TRACEPOINT
 | 
				
			||||||
	BPF_PROG_TYPE_XDP
 | 
						BPF_PROG_TYPE_XDP
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_PERF_EVENT
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_CGROUP_SKB
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_CGROUP_SOCK
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_LWT_IN
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_LWT_OUT
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_LWT_XMIT
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_SOCK_OPS
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_SK_SKB
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_CGROUP_DEVICE
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_SK_MSG
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_RAW_TRACEPOINT
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_CGROUP_SOCK_ADDR
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_LWT_SEG6LOCAL
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_LIRC_MODE2
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_SK_REUSEPORT
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_FLOW_DISSECTOR
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_CGROUP_SYSCTL
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_CGROUP_SOCKOPT
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_TRACING
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_STRUCT_OPS
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_EXT
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_LSM
 | 
				
			||||||
 | 
						BPF_PROG_TYPE_SK_LOOKUP
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type BPFAttr struct {
 | 
					type BPFAttr struct {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										43
									
								
								vendor/github.com/vishvananda/netlink/bridge_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								vendor/github.com/vishvananda/netlink/bridge_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -63,7 +63,19 @@ func BridgeVlanAdd(link Link, vid uint16, pvid, untagged, self, master bool) err
 | 
				
			|||||||
// BridgeVlanAdd adds a new vlan filter entry
 | 
					// BridgeVlanAdd adds a new vlan filter entry
 | 
				
			||||||
// Equivalent to: `bridge vlan add dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]`
 | 
					// Equivalent to: `bridge vlan add dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]`
 | 
				
			||||||
func (h *Handle) BridgeVlanAdd(link Link, vid uint16, pvid, untagged, self, master bool) error {
 | 
					func (h *Handle) BridgeVlanAdd(link Link, vid uint16, pvid, untagged, self, master bool) error {
 | 
				
			||||||
	return h.bridgeVlanModify(unix.RTM_SETLINK, link, vid, pvid, untagged, self, master)
 | 
						return h.bridgeVlanModify(unix.RTM_SETLINK, link, vid, 0, pvid, untagged, self, master)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// BridgeVlanAddRange adds a new vlan filter entry
 | 
				
			||||||
 | 
					// Equivalent to: `bridge vlan add dev DEV vid VID-VIDEND [ pvid ] [ untagged ] [ self ] [ master ]`
 | 
				
			||||||
 | 
					func BridgeVlanAddRange(link Link, vid, vidEnd uint16, pvid, untagged, self, master bool) error {
 | 
				
			||||||
 | 
						return pkgHandle.BridgeVlanAddRange(link, vid, vidEnd, pvid, untagged, self, master)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// BridgeVlanAddRange adds a new vlan filter entry
 | 
				
			||||||
 | 
					// Equivalent to: `bridge vlan add dev DEV vid VID-VIDEND [ pvid ] [ untagged ] [ self ] [ master ]`
 | 
				
			||||||
 | 
					func (h *Handle) BridgeVlanAddRange(link Link, vid, vidEnd uint16, pvid, untagged, self, master bool) error {
 | 
				
			||||||
 | 
						return h.bridgeVlanModify(unix.RTM_SETLINK, link, vid, vidEnd, pvid, untagged, self, master)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// BridgeVlanDel adds a new vlan filter entry
 | 
					// BridgeVlanDel adds a new vlan filter entry
 | 
				
			||||||
@@ -75,10 +87,22 @@ func BridgeVlanDel(link Link, vid uint16, pvid, untagged, self, master bool) err
 | 
				
			|||||||
// BridgeVlanDel adds a new vlan filter entry
 | 
					// BridgeVlanDel adds a new vlan filter entry
 | 
				
			||||||
// Equivalent to: `bridge vlan del dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]`
 | 
					// Equivalent to: `bridge vlan del dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]`
 | 
				
			||||||
func (h *Handle) BridgeVlanDel(link Link, vid uint16, pvid, untagged, self, master bool) error {
 | 
					func (h *Handle) BridgeVlanDel(link Link, vid uint16, pvid, untagged, self, master bool) error {
 | 
				
			||||||
	return h.bridgeVlanModify(unix.RTM_DELLINK, link, vid, pvid, untagged, self, master)
 | 
						return h.bridgeVlanModify(unix.RTM_DELLINK, link, vid, 0, pvid, untagged, self, master)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (h *Handle) bridgeVlanModify(cmd int, link Link, vid uint16, pvid, untagged, self, master bool) error {
 | 
					// BridgeVlanDelRange adds a new vlan filter entry
 | 
				
			||||||
 | 
					// Equivalent to: `bridge vlan del dev DEV vid VID-VIDEND [ pvid ] [ untagged ] [ self ] [ master ]`
 | 
				
			||||||
 | 
					func BridgeVlanDelRange(link Link, vid, vidEnd uint16, pvid, untagged, self, master bool) error {
 | 
				
			||||||
 | 
						return pkgHandle.BridgeVlanDelRange(link, vid, vidEnd, pvid, untagged, self, master)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// BridgeVlanDelRange adds a new vlan filter entry
 | 
				
			||||||
 | 
					// Equivalent to: `bridge vlan del dev DEV vid VID-VIDEND [ pvid ] [ untagged ] [ self ] [ master ]`
 | 
				
			||||||
 | 
					func (h *Handle) BridgeVlanDelRange(link Link, vid, vidEnd uint16, pvid, untagged, self, master bool) error {
 | 
				
			||||||
 | 
						return h.bridgeVlanModify(unix.RTM_DELLINK, link, vid, vidEnd, pvid, untagged, self, master)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) bridgeVlanModify(cmd int, link Link, vid, vidEnd uint16, pvid, untagged, self, master bool) error {
 | 
				
			||||||
	base := link.Attrs()
 | 
						base := link.Attrs()
 | 
				
			||||||
	h.ensureIndex(base)
 | 
						h.ensureIndex(base)
 | 
				
			||||||
	req := h.newNetlinkRequest(cmd, unix.NLM_F_ACK)
 | 
						req := h.newNetlinkRequest(cmd, unix.NLM_F_ACK)
 | 
				
			||||||
@@ -105,7 +129,20 @@ func (h *Handle) bridgeVlanModify(cmd int, link Link, vid uint16, pvid, untagged
 | 
				
			|||||||
	if untagged {
 | 
						if untagged {
 | 
				
			||||||
		vlanInfo.Flags |= nl.BRIDGE_VLAN_INFO_UNTAGGED
 | 
							vlanInfo.Flags |= nl.BRIDGE_VLAN_INFO_UNTAGGED
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if vidEnd != 0 {
 | 
				
			||||||
 | 
							vlanEndInfo := &nl.BridgeVlanInfo{Vid: vidEnd}
 | 
				
			||||||
 | 
							vlanEndInfo.Flags = vlanInfo.Flags
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							vlanInfo.Flags |= nl.BRIDGE_VLAN_INFO_RANGE_BEGIN
 | 
				
			||||||
		br.AddRtAttr(nl.IFLA_BRIDGE_VLAN_INFO, vlanInfo.Serialize())
 | 
							br.AddRtAttr(nl.IFLA_BRIDGE_VLAN_INFO, vlanInfo.Serialize())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							vlanEndInfo.Flags |= nl.BRIDGE_VLAN_INFO_RANGE_END
 | 
				
			||||||
 | 
							br.AddRtAttr(nl.IFLA_BRIDGE_VLAN_INFO, vlanEndInfo.Serialize())
 | 
				
			||||||
 | 
						} else { 
 | 
				
			||||||
 | 
							br.AddRtAttr(nl.IFLA_BRIDGE_VLAN_INFO, vlanInfo.Serialize())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	req.AddData(br)
 | 
						req.AddData(br)
 | 
				
			||||||
	_, err := req.Execute(unix.NETLINK_ROUTE, 0)
 | 
						_, err := req.Execute(unix.NETLINK_ROUTE, 0)
 | 
				
			||||||
	return err
 | 
						return err
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										22
									
								
								vendor/github.com/vishvananda/netlink/chain.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/vishvananda/netlink/chain.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					package netlink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Chain contains the attributes of a Chain
 | 
				
			||||||
 | 
					type Chain struct {
 | 
				
			||||||
 | 
						Parent uint32
 | 
				
			||||||
 | 
						Chain  uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c Chain) String() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("{Parent: %d, Chain: %d}", c.Parent, c.Chain)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewChain(parent uint32, chain uint32) Chain {
 | 
				
			||||||
 | 
						return Chain{
 | 
				
			||||||
 | 
							Parent: parent,
 | 
				
			||||||
 | 
							Chain:  chain,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										112
									
								
								vendor/github.com/vishvananda/netlink/chain_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								vendor/github.com/vishvananda/netlink/chain_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,112 @@
 | 
				
			|||||||
 | 
					package netlink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/vishvananda/netlink/nl"
 | 
				
			||||||
 | 
						"golang.org/x/sys/unix"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ChainDel will delete a chain from the system.
 | 
				
			||||||
 | 
					func ChainDel(link Link, chain Chain) error {
 | 
				
			||||||
 | 
						// Equivalent to: `tc chain del $chain`
 | 
				
			||||||
 | 
						return pkgHandle.ChainDel(link, chain)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ChainDel will delete a chain from the system.
 | 
				
			||||||
 | 
					// Equivalent to: `tc chain del $chain`
 | 
				
			||||||
 | 
					func (h *Handle) ChainDel(link Link, chain Chain) error {
 | 
				
			||||||
 | 
						return h.chainModify(unix.RTM_DELCHAIN, 0, link, chain)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ChainAdd will add a chain to the system.
 | 
				
			||||||
 | 
					// Equivalent to: `tc chain add`
 | 
				
			||||||
 | 
					func ChainAdd(link Link, chain Chain) error {
 | 
				
			||||||
 | 
						return pkgHandle.ChainAdd(link, chain)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ChainAdd will add a chain to the system.
 | 
				
			||||||
 | 
					// Equivalent to: `tc chain add`
 | 
				
			||||||
 | 
					func (h *Handle) ChainAdd(link Link, chain Chain) error {
 | 
				
			||||||
 | 
						return h.chainModify(
 | 
				
			||||||
 | 
							unix.RTM_NEWCHAIN,
 | 
				
			||||||
 | 
							unix.NLM_F_CREATE|unix.NLM_F_EXCL,
 | 
				
			||||||
 | 
							link,
 | 
				
			||||||
 | 
							chain)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) chainModify(cmd, flags int, link Link, chain Chain) error {
 | 
				
			||||||
 | 
						req := h.newNetlinkRequest(cmd, flags|unix.NLM_F_ACK)
 | 
				
			||||||
 | 
						index := int32(0)
 | 
				
			||||||
 | 
						if link != nil {
 | 
				
			||||||
 | 
							base := link.Attrs()
 | 
				
			||||||
 | 
							h.ensureIndex(base)
 | 
				
			||||||
 | 
							index = int32(base.Index)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						msg := &nl.TcMsg{
 | 
				
			||||||
 | 
							Family:  nl.FAMILY_ALL,
 | 
				
			||||||
 | 
							Ifindex: index,
 | 
				
			||||||
 | 
							Parent:  chain.Parent,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						req.AddData(msg)
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.TCA_CHAIN, nl.Uint32Attr(chain.Chain)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err := req.Execute(unix.NETLINK_ROUTE, 0)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ChainList gets a list of chains in the system.
 | 
				
			||||||
 | 
					// Equivalent to: `tc chain list`.
 | 
				
			||||||
 | 
					// The list can be filtered by link.
 | 
				
			||||||
 | 
					func ChainList(link Link, parent uint32) ([]Chain, error) {
 | 
				
			||||||
 | 
						return pkgHandle.ChainList(link, parent)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ChainList gets a list of chains in the system.
 | 
				
			||||||
 | 
					// Equivalent to: `tc chain list`.
 | 
				
			||||||
 | 
					// The list can be filtered by link.
 | 
				
			||||||
 | 
					func (h *Handle) ChainList(link Link, parent uint32) ([]Chain, error) {
 | 
				
			||||||
 | 
						req := h.newNetlinkRequest(unix.RTM_GETCHAIN, unix.NLM_F_DUMP)
 | 
				
			||||||
 | 
						index := int32(0)
 | 
				
			||||||
 | 
						if link != nil {
 | 
				
			||||||
 | 
							base := link.Attrs()
 | 
				
			||||||
 | 
							h.ensureIndex(base)
 | 
				
			||||||
 | 
							index = int32(base.Index)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						msg := &nl.TcMsg{
 | 
				
			||||||
 | 
							Family:  nl.FAMILY_ALL,
 | 
				
			||||||
 | 
							Ifindex: index,
 | 
				
			||||||
 | 
							Parent:  parent,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						req.AddData(msg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWCHAIN)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var res []Chain
 | 
				
			||||||
 | 
						for _, m := range msgs {
 | 
				
			||||||
 | 
							msg := nl.DeserializeTcMsg(m)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							attrs, err := nl.ParseRouteAttr(m[msg.Len():])
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// skip chains from other interfaces
 | 
				
			||||||
 | 
							if link != nil && msg.Ifindex != index {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							var chain Chain
 | 
				
			||||||
 | 
							for _, attr := range attrs {
 | 
				
			||||||
 | 
								switch attr.Attr.Type {
 | 
				
			||||||
 | 
								case nl.TCA_CHAIN:
 | 
				
			||||||
 | 
									chain.Chain = native.Uint32(attr.Value)
 | 
				
			||||||
 | 
									chain.Parent = parent
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							res = append(res, chain)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return res, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										58
									
								
								vendor/github.com/vishvananda/netlink/class.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										58
									
								
								vendor/github.com/vishvananda/netlink/class.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -47,6 +47,7 @@ type ClassStatistics struct {
 | 
				
			|||||||
	Basic   *GnetStatsBasic
 | 
						Basic   *GnetStatsBasic
 | 
				
			||||||
	Queue   *GnetStatsQueue
 | 
						Queue   *GnetStatsQueue
 | 
				
			||||||
	RateEst *GnetStatsRateEst
 | 
						RateEst *GnetStatsRateEst
 | 
				
			||||||
 | 
						BasicHw *GnetStatsBasic // Hardward statistics added in kernel 4.20
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewClassStatistics Construct a ClassStatistics struct which fields are all initialized by 0.
 | 
					// NewClassStatistics Construct a ClassStatistics struct which fields are all initialized by 0.
 | 
				
			||||||
@@ -55,6 +56,7 @@ func NewClassStatistics() *ClassStatistics {
 | 
				
			|||||||
		Basic:   &GnetStatsBasic{},
 | 
							Basic:   &GnetStatsBasic{},
 | 
				
			||||||
		Queue:   &GnetStatsQueue{},
 | 
							Queue:   &GnetStatsQueue{},
 | 
				
			||||||
		RateEst: &GnetStatsRateEst{},
 | 
							RateEst: &GnetStatsRateEst{},
 | 
				
			||||||
 | 
							BasicHw: &GnetStatsBasic{},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -132,7 +134,10 @@ func (class *GenericClass) Type() string {
 | 
				
			|||||||
	return class.ClassType
 | 
						return class.ClassType
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ServiceCurve is the way the HFSC curve are represented
 | 
					// ServiceCurve is a nondecreasing function of some time unit, returning the amount of service
 | 
				
			||||||
 | 
					// (an allowed or allocated amount of bandwidth) at some specific point in time. The purpose of it
 | 
				
			||||||
 | 
					// should be subconsciously obvious: if a class was allowed to transfer not less than the amount
 | 
				
			||||||
 | 
					// specified by its service curve, then the service curve is not violated.
 | 
				
			||||||
type ServiceCurve struct {
 | 
					type ServiceCurve struct {
 | 
				
			||||||
	m1 uint32
 | 
						m1 uint32
 | 
				
			||||||
	d  uint32
 | 
						d  uint32
 | 
				
			||||||
@@ -144,6 +149,21 @@ func (c *ServiceCurve) Attrs() (uint32, uint32, uint32) {
 | 
				
			|||||||
	return c.m1, c.d, c.m2
 | 
						return c.m1, c.d, c.m2
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Burst returns the burst rate (m1) of the curve
 | 
				
			||||||
 | 
					func (c *ServiceCurve) Burst() uint32 {
 | 
				
			||||||
 | 
						return c.m1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Delay return the delay (d) of the curve
 | 
				
			||||||
 | 
					func (c *ServiceCurve) Delay() uint32 {
 | 
				
			||||||
 | 
						return c.d
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Rate returns the rate (m2) of the curve
 | 
				
			||||||
 | 
					func (c *ServiceCurve) Rate() uint32 {
 | 
				
			||||||
 | 
						return c.m2
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// HfscClass is a representation of the HFSC class
 | 
					// HfscClass is a representation of the HFSC class
 | 
				
			||||||
type HfscClass struct {
 | 
					type HfscClass struct {
 | 
				
			||||||
	ClassAttrs
 | 
						ClassAttrs
 | 
				
			||||||
@@ -152,35 +172,44 @@ type HfscClass struct {
 | 
				
			|||||||
	Usc ServiceCurve
 | 
						Usc ServiceCurve
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SetUsc sets the Usc curve
 | 
					// SetUsc sets the USC curve. The bandwidth (m1 and m2) is specified in bits and the delay in
 | 
				
			||||||
 | 
					// seconds.
 | 
				
			||||||
func (hfsc *HfscClass) SetUsc(m1 uint32, d uint32, m2 uint32) {
 | 
					func (hfsc *HfscClass) SetUsc(m1 uint32, d uint32, m2 uint32) {
 | 
				
			||||||
	hfsc.Usc = ServiceCurve{m1: m1 / 8, d: d, m2: m2 / 8}
 | 
						hfsc.Usc = ServiceCurve{m1: m1, d: d, m2: m2}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SetFsc sets the Fsc curve
 | 
					// SetFsc sets the Fsc curve. The bandwidth (m1 and m2) is specified in bits and the delay in
 | 
				
			||||||
 | 
					// seconds.
 | 
				
			||||||
func (hfsc *HfscClass) SetFsc(m1 uint32, d uint32, m2 uint32) {
 | 
					func (hfsc *HfscClass) SetFsc(m1 uint32, d uint32, m2 uint32) {
 | 
				
			||||||
	hfsc.Fsc = ServiceCurve{m1: m1 / 8, d: d, m2: m2 / 8}
 | 
						hfsc.Fsc = ServiceCurve{m1: m1, d: d, m2: m2}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SetRsc sets the Rsc curve
 | 
					// SetRsc sets the Rsc curve. The bandwidth (m1 and m2) is specified in bits and the delay in
 | 
				
			||||||
 | 
					// seconds.
 | 
				
			||||||
func (hfsc *HfscClass) SetRsc(m1 uint32, d uint32, m2 uint32) {
 | 
					func (hfsc *HfscClass) SetRsc(m1 uint32, d uint32, m2 uint32) {
 | 
				
			||||||
	hfsc.Rsc = ServiceCurve{m1: m1 / 8, d: d, m2: m2 / 8}
 | 
						hfsc.Rsc = ServiceCurve{m1: m1, d: d, m2: m2}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SetSC implements the SC from the tc CLI
 | 
					// SetSC implements the SC from the `tc` CLI. This function behaves the same as if one would set the
 | 
				
			||||||
 | 
					// USC through the `tc` command-line tool. This means bandwidth (m1 and m2) is specified in bits and
 | 
				
			||||||
 | 
					// the delay in ms.
 | 
				
			||||||
func (hfsc *HfscClass) SetSC(m1 uint32, d uint32, m2 uint32) {
 | 
					func (hfsc *HfscClass) SetSC(m1 uint32, d uint32, m2 uint32) {
 | 
				
			||||||
	hfsc.Rsc = ServiceCurve{m1: m1 / 8, d: d, m2: m2 / 8}
 | 
						hfsc.SetRsc(m1, d, m2)
 | 
				
			||||||
	hfsc.Fsc = ServiceCurve{m1: m1 / 8, d: d, m2: m2 / 8}
 | 
						hfsc.SetFsc(m1, d, m2)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SetUL implements the UL from the tc CLI
 | 
					// SetUL implements the UL from the `tc` CLI. This function behaves the same as if one would set the
 | 
				
			||||||
 | 
					// USC through the `tc` command-line tool. This means bandwidth (m1 and m2) is specified in bits and
 | 
				
			||||||
 | 
					// the delay in ms.
 | 
				
			||||||
func (hfsc *HfscClass) SetUL(m1 uint32, d uint32, m2 uint32) {
 | 
					func (hfsc *HfscClass) SetUL(m1 uint32, d uint32, m2 uint32) {
 | 
				
			||||||
	hfsc.Usc = ServiceCurve{m1: m1 / 8, d: d, m2: m2 / 8}
 | 
						hfsc.SetUsc(m1, d, m2)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SetLS implements the LS from the tc CLI
 | 
					// SetLS implements the LS from the `tc` CLI. This function behaves the same as if one would set the
 | 
				
			||||||
 | 
					// USC through the `tc` command-line tool. This means bandwidth (m1 and m2) is specified in bits and
 | 
				
			||||||
 | 
					// the delay in ms.
 | 
				
			||||||
func (hfsc *HfscClass) SetLS(m1 uint32, d uint32, m2 uint32) {
 | 
					func (hfsc *HfscClass) SetLS(m1 uint32, d uint32, m2 uint32) {
 | 
				
			||||||
	hfsc.Fsc = ServiceCurve{m1: m1 / 8, d: d, m2: m2 / 8}
 | 
						hfsc.SetFsc(m1, d, m2)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewHfscClass returns a new HFSC struct with the set parameters
 | 
					// NewHfscClass returns a new HFSC struct with the set parameters
 | 
				
			||||||
@@ -193,6 +222,7 @@ func NewHfscClass(attrs ClassAttrs) *HfscClass {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// String() returns a string that contains the information and attributes of the HFSC class
 | 
				
			||||||
func (hfsc *HfscClass) String() string {
 | 
					func (hfsc *HfscClass) String() string {
 | 
				
			||||||
	return fmt.Sprintf(
 | 
						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}}}",
 | 
							"{%s -- {RSC: {m1=%d d=%d m2=%d}} {FSC: {m1=%d d=%d m2=%d}} {USC: {m1=%d d=%d m2=%d}}}",
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										40
									
								
								vendor/github.com/vishvananda/netlink/class_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										40
									
								
								vendor/github.com/vishvananda/netlink/class_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -43,12 +43,12 @@ func NewHtbClass(attrs ClassAttrs, cattrs HtbClassAttrs) *HtbClass {
 | 
				
			|||||||
	if buffer == 0 {
 | 
						if buffer == 0 {
 | 
				
			||||||
		buffer = uint32(float64(rate)/Hz() + float64(mtu))
 | 
							buffer = uint32(float64(rate)/Hz() + float64(mtu))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	buffer = uint32(Xmittime(rate, buffer))
 | 
						buffer = Xmittime(rate, buffer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if cbuffer == 0 {
 | 
						if cbuffer == 0 {
 | 
				
			||||||
		cbuffer = uint32(float64(ceil)/Hz() + float64(mtu))
 | 
							cbuffer = uint32(float64(ceil)/Hz() + float64(mtu))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	cbuffer = uint32(Xmittime(ceil, cbuffer))
 | 
						cbuffer = Xmittime(ceil, cbuffer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return &HtbClass{
 | 
						return &HtbClass{
 | 
				
			||||||
		ClassAttrs: attrs,
 | 
							ClassAttrs: attrs,
 | 
				
			||||||
@@ -56,9 +56,9 @@ func NewHtbClass(attrs ClassAttrs, cattrs HtbClassAttrs) *HtbClass {
 | 
				
			|||||||
		Ceil:       ceil,
 | 
							Ceil:       ceil,
 | 
				
			||||||
		Buffer:     buffer,
 | 
							Buffer:     buffer,
 | 
				
			||||||
		Cbuffer:    cbuffer,
 | 
							Cbuffer:    cbuffer,
 | 
				
			||||||
		Quantum:    10,
 | 
					 | 
				
			||||||
		Level:      0,
 | 
							Level:      0,
 | 
				
			||||||
		Prio:       0,
 | 
							Prio:       cattrs.Prio,
 | 
				
			||||||
 | 
							Quantum:    cattrs.Quantum,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -176,12 +176,21 @@ func classPayload(req *nl.NetlinkRequest, class Class) error {
 | 
				
			|||||||
		options.AddRtAttr(nl.TCA_HTB_PARMS, opt.Serialize())
 | 
							options.AddRtAttr(nl.TCA_HTB_PARMS, opt.Serialize())
 | 
				
			||||||
		options.AddRtAttr(nl.TCA_HTB_RTAB, SerializeRtab(rtab))
 | 
							options.AddRtAttr(nl.TCA_HTB_RTAB, SerializeRtab(rtab))
 | 
				
			||||||
		options.AddRtAttr(nl.TCA_HTB_CTAB, SerializeRtab(ctab))
 | 
							options.AddRtAttr(nl.TCA_HTB_CTAB, SerializeRtab(ctab))
 | 
				
			||||||
 | 
							if htb.Rate >= uint64(1<<32) {
 | 
				
			||||||
 | 
								options.AddRtAttr(nl.TCA_HTB_RATE64, nl.Uint64Attr(htb.Rate))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if htb.Ceil >= uint64(1<<32) {
 | 
				
			||||||
 | 
								options.AddRtAttr(nl.TCA_HTB_CEIL64, nl.Uint64Attr(htb.Ceil))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	case "hfsc":
 | 
						case "hfsc":
 | 
				
			||||||
		hfsc := class.(*HfscClass)
 | 
							hfsc := class.(*HfscClass)
 | 
				
			||||||
		opt := nl.HfscCopt{}
 | 
							opt := nl.HfscCopt{}
 | 
				
			||||||
		opt.Rsc.Set(hfsc.Rsc.Attrs())
 | 
							rm1, rd, rm2 := hfsc.Rsc.Attrs()
 | 
				
			||||||
		opt.Fsc.Set(hfsc.Fsc.Attrs())
 | 
							opt.Rsc.Set(rm1/8, rd, rm2/8)
 | 
				
			||||||
		opt.Usc.Set(hfsc.Usc.Attrs())
 | 
							fm1, fd, fm2 := hfsc.Fsc.Attrs()
 | 
				
			||||||
 | 
							opt.Fsc.Set(fm1/8, fd, fm2/8)
 | 
				
			||||||
 | 
							um1, ud, um2 := hfsc.Usc.Attrs()
 | 
				
			||||||
 | 
							opt.Usc.Set(um1/8, ud, um2/8)
 | 
				
			||||||
		options.AddRtAttr(nl.TCA_HFSC_RSC, nl.SerializeHfscCurve(&opt.Rsc))
 | 
							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_FSC, nl.SerializeHfscCurve(&opt.Fsc))
 | 
				
			||||||
		options.AddRtAttr(nl.TCA_HFSC_USC, nl.SerializeHfscCurve(&opt.Usc))
 | 
							options.AddRtAttr(nl.TCA_HFSC_USC, nl.SerializeHfscCurve(&opt.Usc))
 | 
				
			||||||
@@ -303,6 +312,10 @@ func parseHtbClassData(class Class, data []syscall.NetlinkRouteAttr) (bool, erro
 | 
				
			|||||||
			htb.Quantum = opt.Quantum
 | 
								htb.Quantum = opt.Quantum
 | 
				
			||||||
			htb.Level = opt.Level
 | 
								htb.Level = opt.Level
 | 
				
			||||||
			htb.Prio = opt.Prio
 | 
								htb.Prio = opt.Prio
 | 
				
			||||||
 | 
							case nl.TCA_HTB_RATE64:
 | 
				
			||||||
 | 
								htb.Rate = native.Uint64(datum.Value[0:8])
 | 
				
			||||||
 | 
							case nl.TCA_HTB_CEIL64:
 | 
				
			||||||
 | 
								htb.Ceil = native.Uint64(datum.Value[0:8])
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return detailed, nil
 | 
						return detailed, nil
 | 
				
			||||||
@@ -315,11 +328,11 @@ func parseHfscClassData(class Class, data []syscall.NetlinkRouteAttr) (bool, err
 | 
				
			|||||||
		m1, d, m2 := nl.DeserializeHfscCurve(datum.Value).Attrs()
 | 
							m1, d, m2 := nl.DeserializeHfscCurve(datum.Value).Attrs()
 | 
				
			||||||
		switch datum.Attr.Type {
 | 
							switch datum.Attr.Type {
 | 
				
			||||||
		case nl.TCA_HFSC_RSC:
 | 
							case nl.TCA_HFSC_RSC:
 | 
				
			||||||
			hfsc.Rsc = ServiceCurve{m1: m1, d: d, m2: m2}
 | 
								hfsc.Rsc = ServiceCurve{m1: m1 * 8, d: d, m2: m2 * 8}
 | 
				
			||||||
		case nl.TCA_HFSC_FSC:
 | 
							case nl.TCA_HFSC_FSC:
 | 
				
			||||||
			hfsc.Fsc = ServiceCurve{m1: m1, d: d, m2: m2}
 | 
								hfsc.Fsc = ServiceCurve{m1: m1 * 8, d: d, m2: m2 * 8}
 | 
				
			||||||
		case nl.TCA_HFSC_USC:
 | 
							case nl.TCA_HFSC_USC:
 | 
				
			||||||
			hfsc.Usc = ServiceCurve{m1: m1, d: d, m2: m2}
 | 
								hfsc.Usc = ServiceCurve{m1: m1 * 8, d: d, m2: m2 * 8}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return detailed, nil
 | 
						return detailed, nil
 | 
				
			||||||
@@ -328,7 +341,6 @@ func parseHfscClassData(class Class, data []syscall.NetlinkRouteAttr) (bool, err
 | 
				
			|||||||
func parseTcStats(data []byte) (*ClassStatistics, error) {
 | 
					func parseTcStats(data []byte) (*ClassStatistics, error) {
 | 
				
			||||||
	buf := &bytes.Buffer{}
 | 
						buf := &bytes.Buffer{}
 | 
				
			||||||
	buf.Write(data)
 | 
						buf.Write(data)
 | 
				
			||||||
	native := nl.NativeEndian()
 | 
					 | 
				
			||||||
	tcStats := &tcStats{}
 | 
						tcStats := &tcStats{}
 | 
				
			||||||
	if err := binary.Read(buf, native, tcStats); err != nil {
 | 
						if err := binary.Read(buf, native, tcStats); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
@@ -350,7 +362,6 @@ func parseTcStats(data []byte) (*ClassStatistics, error) {
 | 
				
			|||||||
func parseGnetStats(data []byte, gnetStats interface{}) error {
 | 
					func parseGnetStats(data []byte, gnetStats interface{}) error {
 | 
				
			||||||
	buf := &bytes.Buffer{}
 | 
						buf := &bytes.Buffer{}
 | 
				
			||||||
	buf.Write(data)
 | 
						buf.Write(data)
 | 
				
			||||||
	native := nl.NativeEndian()
 | 
					 | 
				
			||||||
	return binary.Read(buf, native, gnetStats)
 | 
						return binary.Read(buf, native, gnetStats)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -377,6 +388,11 @@ func parseTcStats2(data []byte) (*ClassStatistics, error) {
 | 
				
			|||||||
				return nil, fmt.Errorf("Failed to parse ClassStatistics.RateEst with: %v\n%s",
 | 
									return nil, fmt.Errorf("Failed to parse ClassStatistics.RateEst with: %v\n%s",
 | 
				
			||||||
					err, hex.Dump(datum.Value))
 | 
										err, hex.Dump(datum.Value))
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							case nl.TCA_STATS_BASIC_HW:
 | 
				
			||||||
 | 
								if err := parseGnetStats(datum.Value, stats.BasicHw); err != nil {
 | 
				
			||||||
 | 
									return nil, fmt.Errorf("Failed to parse ClassStatistics.BasicHw with: %v\n%s",
 | 
				
			||||||
 | 
										err, hex.Dump(datum.Value))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										574
									
								
								vendor/github.com/vishvananda/netlink/conntrack_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										574
									
								
								vendor/github.com/vishvananda/netlink/conntrack_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -6,6 +6,7 @@ import (
 | 
				
			|||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/vishvananda/netlink/nl"
 | 
						"github.com/vishvananda/netlink/nl"
 | 
				
			||||||
	"golang.org/x/sys/unix"
 | 
						"golang.org/x/sys/unix"
 | 
				
			||||||
@@ -54,10 +55,30 @@ func ConntrackTableFlush(table ConntrackTableType) error {
 | 
				
			|||||||
	return pkgHandle.ConntrackTableFlush(table)
 | 
						return pkgHandle.ConntrackTableFlush(table)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ConntrackCreate creates a new conntrack flow in the desired table
 | 
				
			||||||
 | 
					// conntrack -I [table]		Create a conntrack or expectation
 | 
				
			||||||
 | 
					func ConntrackCreate(table ConntrackTableType, family InetFamily, flow *ConntrackFlow) error {
 | 
				
			||||||
 | 
						return pkgHandle.ConntrackCreate(table, family, flow)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ConntrackUpdate updates an existing conntrack flow in the desired table using the handle
 | 
				
			||||||
 | 
					// conntrack -U [table]		Update a conntrack
 | 
				
			||||||
 | 
					func ConntrackUpdate(table ConntrackTableType, family InetFamily, flow *ConntrackFlow) error {
 | 
				
			||||||
 | 
						return pkgHandle.ConntrackUpdate(table, family, flow)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter
 | 
					// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter
 | 
				
			||||||
// conntrack -D [table] parameters         Delete conntrack or expectation
 | 
					// conntrack -D [table] parameters         Delete conntrack or expectation
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Deprecated: use [ConntrackDeleteFilter] instead.
 | 
				
			||||||
func ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter CustomConntrackFilter) (uint, error) {
 | 
					func ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter CustomConntrackFilter) (uint, error) {
 | 
				
			||||||
	return pkgHandle.ConntrackDeleteFilter(table, family, filter)
 | 
						return pkgHandle.ConntrackDeleteFilters(table, family, filter)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ConntrackDeleteFilters deletes entries on the specified table matching any of the specified filters
 | 
				
			||||||
 | 
					// conntrack -D [table] parameters         Delete conntrack or expectation
 | 
				
			||||||
 | 
					func ConntrackDeleteFilters(table ConntrackTableType, family InetFamily, filters ...CustomConntrackFilter) (uint, error) {
 | 
				
			||||||
 | 
						return pkgHandle.ConntrackDeleteFilters(table, family, filters...)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ConntrackTableList returns the flow list of a table of a specific family using the netlink handle passed
 | 
					// ConntrackTableList returns the flow list of a table of a specific family using the netlink handle passed
 | 
				
			||||||
@@ -86,9 +107,51 @@ func (h *Handle) ConntrackTableFlush(table ConntrackTableType) error {
 | 
				
			|||||||
	return err
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ConntrackCreate creates a new conntrack flow in the desired table using the handle
 | 
				
			||||||
 | 
					// conntrack -I [table]		Create a conntrack or expectation
 | 
				
			||||||
 | 
					func (h *Handle) ConntrackCreate(table ConntrackTableType, family InetFamily, flow *ConntrackFlow) error {
 | 
				
			||||||
 | 
						req := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_NEW, unix.NLM_F_ACK|unix.NLM_F_CREATE)
 | 
				
			||||||
 | 
						attr, err := flow.toNlData()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, a := range attr {
 | 
				
			||||||
 | 
							req.AddData(a)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err = req.Execute(unix.NETLINK_NETFILTER, 0)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ConntrackUpdate updates an existing conntrack flow in the desired table using the handle
 | 
				
			||||||
 | 
					// conntrack -U [table]		Update a conntrack
 | 
				
			||||||
 | 
					func (h *Handle) ConntrackUpdate(table ConntrackTableType, family InetFamily, flow *ConntrackFlow) error {
 | 
				
			||||||
 | 
						req := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_NEW, unix.NLM_F_ACK|unix.NLM_F_REPLACE)
 | 
				
			||||||
 | 
						attr, err := flow.toNlData()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, a := range attr {
 | 
				
			||||||
 | 
							req.AddData(a)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err = req.Execute(unix.NETLINK_NETFILTER, 0)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter using the netlink handle passed
 | 
					// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter using the netlink handle passed
 | 
				
			||||||
// conntrack -D [table] parameters         Delete conntrack or expectation
 | 
					// conntrack -D [table] parameters         Delete conntrack or expectation
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Deprecated: use [Handle.ConntrackDeleteFilters] instead.
 | 
				
			||||||
func (h *Handle) ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter CustomConntrackFilter) (uint, error) {
 | 
					func (h *Handle) ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter CustomConntrackFilter) (uint, error) {
 | 
				
			||||||
 | 
						return h.ConntrackDeleteFilters(table, family, filter)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ConntrackDeleteFilters deletes entries on the specified table matching any of the specified filters using the netlink handle passed
 | 
				
			||||||
 | 
					// conntrack -D [table] parameters         Delete conntrack or expectation
 | 
				
			||||||
 | 
					func (h *Handle) ConntrackDeleteFilters(table ConntrackTableType, family InetFamily, filters ...CustomConntrackFilter) (uint, error) {
 | 
				
			||||||
	res, err := h.dumpConntrackTable(table, family)
 | 
						res, err := h.dumpConntrackTable(table, family)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return 0, err
 | 
							return 0, err
 | 
				
			||||||
@@ -97,12 +160,16 @@ func (h *Handle) ConntrackDeleteFilter(table ConntrackTableType, family InetFami
 | 
				
			|||||||
	var matched uint
 | 
						var matched uint
 | 
				
			||||||
	for _, dataRaw := range res {
 | 
						for _, dataRaw := range res {
 | 
				
			||||||
		flow := parseRawData(dataRaw)
 | 
							flow := parseRawData(dataRaw)
 | 
				
			||||||
 | 
							for _, filter := range filters {
 | 
				
			||||||
			if match := filter.MatchConntrackFlow(flow); match {
 | 
								if match := filter.MatchConntrackFlow(flow); match {
 | 
				
			||||||
				req2 := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_DELETE, unix.NLM_F_ACK)
 | 
									req2 := h.newConntrackRequest(table, family, nl.IPCTNL_MSG_CT_DELETE, unix.NLM_F_ACK)
 | 
				
			||||||
				// skip the first 4 byte that are the netfilter header, the newConntrackRequest is adding it already
 | 
									// skip the first 4 byte that are the netfilter header, the newConntrackRequest is adding it already
 | 
				
			||||||
				req2.AddRawData(dataRaw[4:])
 | 
									req2.AddRawData(dataRaw[4:])
 | 
				
			||||||
				req2.Execute(unix.NETLINK_NETFILTER, 0)
 | 
									req2.Execute(unix.NETLINK_NETFILTER, 0)
 | 
				
			||||||
				matched++
 | 
									matched++
 | 
				
			||||||
 | 
									// flow is already deleted, no need to match on other filters and continue to the next flow.
 | 
				
			||||||
 | 
									break
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -127,10 +194,44 @@ func (h *Handle) dumpConntrackTable(table ConntrackTableType, family InetFamily)
 | 
				
			|||||||
	return req.Execute(unix.NETLINK_NETFILTER, 0)
 | 
						return req.Execute(unix.NETLINK_NETFILTER, 0)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ProtoInfo wraps an L4-protocol structure - roughly corresponds to the
 | 
				
			||||||
 | 
					// __nfct_protoinfo union found in libnetfilter_conntrack/include/internal/object.h.
 | 
				
			||||||
 | 
					// Currently, only protocol names, and TCP state is supported.
 | 
				
			||||||
 | 
					type ProtoInfo interface {
 | 
				
			||||||
 | 
						Protocol() string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ProtoInfoTCP corresponds to the `tcp` struct of the __nfct_protoinfo union.
 | 
				
			||||||
 | 
					// Only TCP state is currently supported.
 | 
				
			||||||
 | 
					type ProtoInfoTCP struct {
 | 
				
			||||||
 | 
						State uint8
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					// Protocol returns "tcp".
 | 
				
			||||||
 | 
					func (*ProtoInfoTCP) Protocol() string {return "tcp"}
 | 
				
			||||||
 | 
					func (p *ProtoInfoTCP) toNlData() ([]*nl.RtAttr, error) {
 | 
				
			||||||
 | 
						ctProtoInfo := nl.NewRtAttr(unix.NLA_F_NESTED | nl.CTA_PROTOINFO, []byte{})
 | 
				
			||||||
 | 
						ctProtoInfoTCP := nl.NewRtAttr(unix.NLA_F_NESTED|nl.CTA_PROTOINFO_TCP, []byte{})
 | 
				
			||||||
 | 
						ctProtoInfoTCPState := nl.NewRtAttr(nl.CTA_PROTOINFO_TCP_STATE, nl.Uint8Attr(p.State))
 | 
				
			||||||
 | 
						ctProtoInfoTCP.AddChild(ctProtoInfoTCPState)
 | 
				
			||||||
 | 
						ctProtoInfo.AddChild(ctProtoInfoTCP)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return []*nl.RtAttr{ctProtoInfo}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ProtoInfoSCTP only supports the protocol name.
 | 
				
			||||||
 | 
					type ProtoInfoSCTP struct {}
 | 
				
			||||||
 | 
					// Protocol returns "sctp".
 | 
				
			||||||
 | 
					func (*ProtoInfoSCTP) Protocol() string {return "sctp"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ProtoInfoDCCP only supports the protocol name.
 | 
				
			||||||
 | 
					type ProtoInfoDCCP struct {}
 | 
				
			||||||
 | 
					// Protocol returns "dccp".
 | 
				
			||||||
 | 
					func (*ProtoInfoDCCP) Protocol() string {return "dccp"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// The full conntrack flow structure is very complicated and can be found in the file:
 | 
					// The full conntrack flow structure is very complicated and can be found in the file:
 | 
				
			||||||
// http://git.netfilter.org/libnetfilter_conntrack/tree/include/internal/object.h
 | 
					// 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
 | 
					// For the time being, the structure below allows to parse and extract the base information of a flow
 | 
				
			||||||
type ipTuple struct {
 | 
					type IPTuple struct {
 | 
				
			||||||
	Bytes    uint64
 | 
						Bytes    uint64
 | 
				
			||||||
	DstIP    net.IP
 | 
						DstIP    net.IP
 | 
				
			||||||
	DstPort  uint16
 | 
						DstPort  uint16
 | 
				
			||||||
@@ -140,21 +241,150 @@ type ipTuple struct {
 | 
				
			|||||||
	SrcPort  uint16
 | 
						SrcPort  uint16
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// toNlData generates the inner fields of a nested tuple netlink datastructure
 | 
				
			||||||
 | 
					// does not generate the "nested"-flagged outer message.
 | 
				
			||||||
 | 
					func (t *IPTuple) toNlData(family uint8) ([]*nl.RtAttr, error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var srcIPsFlag, dstIPsFlag int
 | 
				
			||||||
 | 
						if family == nl.FAMILY_V4 {
 | 
				
			||||||
 | 
							srcIPsFlag = nl.CTA_IP_V4_SRC
 | 
				
			||||||
 | 
							dstIPsFlag = nl.CTA_IP_V4_DST
 | 
				
			||||||
 | 
						} else if family == nl.FAMILY_V6 {
 | 
				
			||||||
 | 
							srcIPsFlag = nl.CTA_IP_V6_SRC
 | 
				
			||||||
 | 
							dstIPsFlag = nl.CTA_IP_V6_DST
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return []*nl.RtAttr{}, fmt.Errorf("couldn't generate netlink message for tuple due to unrecognized FamilyType '%d'", family)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctTupleIP := nl.NewRtAttr(unix.NLA_F_NESTED|nl.CTA_TUPLE_IP, nil)
 | 
				
			||||||
 | 
						ctTupleIPSrc := nl.NewRtAttr(srcIPsFlag, t.SrcIP)
 | 
				
			||||||
 | 
						ctTupleIP.AddChild(ctTupleIPSrc)
 | 
				
			||||||
 | 
						ctTupleIPDst := nl.NewRtAttr(dstIPsFlag, t.DstIP)
 | 
				
			||||||
 | 
						ctTupleIP.AddChild(ctTupleIPDst)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctTupleProto := nl.NewRtAttr(unix.NLA_F_NESTED|nl.CTA_TUPLE_PROTO, nil)
 | 
				
			||||||
 | 
						ctTupleProtoNum := nl.NewRtAttr(nl.CTA_PROTO_NUM, []byte{t.Protocol})
 | 
				
			||||||
 | 
						ctTupleProto.AddChild(ctTupleProtoNum)
 | 
				
			||||||
 | 
						ctTupleProtoSrcPort := nl.NewRtAttr(nl.CTA_PROTO_SRC_PORT, nl.BEUint16Attr(t.SrcPort))
 | 
				
			||||||
 | 
						ctTupleProto.AddChild(ctTupleProtoSrcPort)
 | 
				
			||||||
 | 
						ctTupleProtoDstPort := nl.NewRtAttr(nl.CTA_PROTO_DST_PORT, nl.BEUint16Attr(t.DstPort))
 | 
				
			||||||
 | 
						ctTupleProto.AddChild(ctTupleProtoDstPort, )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return []*nl.RtAttr{ctTupleIP, ctTupleProto}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ConntrackFlow struct {
 | 
					type ConntrackFlow struct {
 | 
				
			||||||
	FamilyType uint8
 | 
						FamilyType uint8
 | 
				
			||||||
	Forward    ipTuple
 | 
						Forward    IPTuple
 | 
				
			||||||
	Reverse    ipTuple
 | 
						Reverse    IPTuple
 | 
				
			||||||
	Mark       uint32
 | 
						Mark       uint32
 | 
				
			||||||
 | 
						Zone       uint16
 | 
				
			||||||
 | 
						TimeStart  uint64
 | 
				
			||||||
 | 
						TimeStop   uint64
 | 
				
			||||||
 | 
						TimeOut    uint32
 | 
				
			||||||
 | 
						Labels     []byte
 | 
				
			||||||
 | 
						ProtoInfo  ProtoInfo
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *ConntrackFlow) String() string {
 | 
					func (s *ConntrackFlow) String() string {
 | 
				
			||||||
	// conntrack cmd output:
 | 
						// conntrack cmd output:
 | 
				
			||||||
	// 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
 | 
						// 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 labels=0x00000000050012ac4202010000000000 zone=100
 | 
				
			||||||
	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",
 | 
						//             start=2019-07-26 01:26:21.557800506 +0000 UTC stop=1970-01-01 00:00:00 +0000 UTC timeout=30(sec)
 | 
				
			||||||
 | 
						start := time.Unix(0, int64(s.TimeStart))
 | 
				
			||||||
 | 
						stop := time.Unix(0, int64(s.TimeStop))
 | 
				
			||||||
 | 
						timeout := int32(s.TimeOut)
 | 
				
			||||||
 | 
						res := 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=0x%x ",
 | 
				
			||||||
		nl.L4ProtoMap[s.Forward.Protocol], s.Forward.Protocol,
 | 
							nl.L4ProtoMap[s.Forward.Protocol], s.Forward.Protocol,
 | 
				
			||||||
		s.Forward.SrcIP.String(), s.Forward.DstIP.String(), s.Forward.SrcPort, s.Forward.DstPort, s.Forward.Packets, s.Forward.Bytes,
 | 
							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.Reverse.SrcIP.String(), s.Reverse.DstIP.String(), s.Reverse.SrcPort, s.Reverse.DstPort, s.Reverse.Packets, s.Reverse.Bytes,
 | 
				
			||||||
		s.Mark)
 | 
							s.Mark)
 | 
				
			||||||
 | 
						if len(s.Labels) > 0 {
 | 
				
			||||||
 | 
							res += fmt.Sprintf("labels=0x%x ", s.Labels)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if s.Zone != 0 {
 | 
				
			||||||
 | 
							res += fmt.Sprintf("zone=%d ", s.Zone)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						res += fmt.Sprintf("start=%v stop=%v timeout=%d(sec)", start, stop, timeout)
 | 
				
			||||||
 | 
						return res
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// toNlData generates netlink messages representing the flow.
 | 
				
			||||||
 | 
					func (s *ConntrackFlow) toNlData() ([]*nl.RtAttr, error) {
 | 
				
			||||||
 | 
						var payload []*nl.RtAttr
 | 
				
			||||||
 | 
						// The message structure is built as follows:
 | 
				
			||||||
 | 
						//	<len, NLA_F_NESTED|CTA_TUPLE_ORIG>
 | 
				
			||||||
 | 
						//		<len, NLA_F_NESTED|CTA_TUPLE_IP>
 | 
				
			||||||
 | 
						//			<len, [CTA_IP_V4_SRC|CTA_IP_V6_SRC]>
 | 
				
			||||||
 | 
						//			<IP>
 | 
				
			||||||
 | 
						//			<len, [CTA_IP_V4_DST|CTA_IP_V6_DST]>
 | 
				
			||||||
 | 
						//			<IP>
 | 
				
			||||||
 | 
						//		<len, NLA_F_NESTED|nl.CTA_TUPLE_PROTO>
 | 
				
			||||||
 | 
						//			<len, CTA_PROTO_NUM>
 | 
				
			||||||
 | 
						//			<uint8>
 | 
				
			||||||
 | 
						//			<len, CTA_PROTO_SRC_PORT>
 | 
				
			||||||
 | 
						//			<BEuint16>
 | 
				
			||||||
 | 
						//			<len, CTA_PROTO_DST_PORT>
 | 
				
			||||||
 | 
						//			<BEuint16>
 | 
				
			||||||
 | 
						// 	<len, NLA_F_NESTED|CTA_TUPLE_REPLY>
 | 
				
			||||||
 | 
						//		<len, NLA_F_NESTED|CTA_TUPLE_IP>
 | 
				
			||||||
 | 
						//			<len, [CTA_IP_V4_SRC|CTA_IP_V6_SRC]>
 | 
				
			||||||
 | 
						//			<IP>
 | 
				
			||||||
 | 
						//			<len, [CTA_IP_V4_DST|CTA_IP_V6_DST]>
 | 
				
			||||||
 | 
						//			<IP>
 | 
				
			||||||
 | 
						//		<len, NLA_F_NESTED|nl.CTA_TUPLE_PROTO>
 | 
				
			||||||
 | 
						//			<len, CTA_PROTO_NUM>
 | 
				
			||||||
 | 
						//			<uint8>
 | 
				
			||||||
 | 
						//			<len, CTA_PROTO_SRC_PORT>
 | 
				
			||||||
 | 
						//			<BEuint16>
 | 
				
			||||||
 | 
						//			<len, CTA_PROTO_DST_PORT>
 | 
				
			||||||
 | 
						//			<BEuint16>
 | 
				
			||||||
 | 
						//	<len, CTA_STATUS>
 | 
				
			||||||
 | 
						//	<uint64>
 | 
				
			||||||
 | 
						//	<len, CTA_MARK>
 | 
				
			||||||
 | 
						//	<BEuint64>
 | 
				
			||||||
 | 
						//	<len, CTA_TIMEOUT>
 | 
				
			||||||
 | 
						//	<BEuint64>
 | 
				
			||||||
 | 
						//	<len, NLA_F_NESTED|CTA_PROTOINFO>
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
						// CTA_TUPLE_ORIG
 | 
				
			||||||
 | 
						ctTupleOrig := nl.NewRtAttr(unix.NLA_F_NESTED|nl.CTA_TUPLE_ORIG, nil)
 | 
				
			||||||
 | 
						forwardFlowAttrs, err := s.Forward.toNlData(s.FamilyType)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("couldn't generate netlink data for conntrack forward flow: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, a := range forwardFlowAttrs {
 | 
				
			||||||
 | 
							ctTupleOrig.AddChild(a)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// CTA_TUPLE_REPLY
 | 
				
			||||||
 | 
						ctTupleReply := nl.NewRtAttr(unix.NLA_F_NESTED|nl.CTA_TUPLE_REPLY, nil)
 | 
				
			||||||
 | 
						reverseFlowAttrs, err := s.Reverse.toNlData(s.FamilyType)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("couldn't generate netlink data for conntrack reverse flow: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, a := range reverseFlowAttrs {
 | 
				
			||||||
 | 
							ctTupleReply.AddChild(a)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctMark := nl.NewRtAttr(nl.CTA_MARK, nl.BEUint32Attr(s.Mark))
 | 
				
			||||||
 | 
						ctTimeout := nl.NewRtAttr(nl.CTA_TIMEOUT, nl.BEUint32Attr(s.TimeOut))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						payload = append(payload, ctTupleOrig, ctTupleReply, ctMark, ctTimeout)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if s.ProtoInfo != nil {
 | 
				
			||||||
 | 
							switch p := s.ProtoInfo.(type) {
 | 
				
			||||||
 | 
							case *ProtoInfoTCP:
 | 
				
			||||||
 | 
								attrs, err := p.toNlData()
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return nil, fmt.Errorf("couldn't generate netlink data for conntrack flow's TCP protoinfo: %w", err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								payload = append(payload, attrs...)
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								return nil, errors.New("couldn't generate netlink data for conntrack: field 'ProtoInfo' only supports TCP or nil")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return payload, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// This method parse the ip tuple structure
 | 
					// This method parse the ip tuple structure
 | 
				
			||||||
@@ -164,7 +394,7 @@ func (s *ConntrackFlow) String() string {
 | 
				
			|||||||
// <len, NLA_F_NESTED|nl.CTA_TUPLE_PROTO, 1 byte for the protocol, 3 bytes of padding>
 | 
					// <len, NLA_F_NESTED|nl.CTA_TUPLE_PROTO, 1 byte for the protocol, 3 bytes of padding>
 | 
				
			||||||
// <len, CTA_PROTO_SRC_PORT, 2 bytes for the source port, 2 bytes of padding>
 | 
					// <len, CTA_PROTO_SRC_PORT, 2 bytes for the source port, 2 bytes of padding>
 | 
				
			||||||
// <len, CTA_PROTO_DST_PORT, 2 bytes for the source port, 2 bytes of padding>
 | 
					// <len, CTA_PROTO_DST_PORT, 2 bytes for the source port, 2 bytes of padding>
 | 
				
			||||||
func parseIpTuple(reader *bytes.Reader, tpl *ipTuple) uint8 {
 | 
					func parseIpTuple(reader *bytes.Reader, tpl *IPTuple) uint8 {
 | 
				
			||||||
	for i := 0; i < 2; i++ {
 | 
						for i := 0; i < 2; i++ {
 | 
				
			||||||
		_, t, _, v := parseNfAttrTLV(reader)
 | 
							_, t, _, v := parseNfAttrTLV(reader)
 | 
				
			||||||
		switch t {
 | 
							switch t {
 | 
				
			||||||
@@ -174,25 +404,43 @@ func parseIpTuple(reader *bytes.Reader, tpl *ipTuple) uint8 {
 | 
				
			|||||||
			tpl.DstIP = v
 | 
								tpl.DstIP = v
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Skip the next 4 bytes  nl.NLA_F_NESTED|nl.CTA_TUPLE_PROTO
 | 
						// Get total length of nested protocol-specific info.
 | 
				
			||||||
	reader.Seek(4, seekCurrent)
 | 
						_, _, protoInfoTotalLen := parseNfAttrTL(reader)
 | 
				
			||||||
	_, t, _, v := parseNfAttrTLV(reader)
 | 
						_, t, l, v := parseNfAttrTLV(reader)
 | 
				
			||||||
 | 
						// Track the number of bytes read.
 | 
				
			||||||
 | 
						protoInfoBytesRead := uint16(nl.SizeofNfattr) + l
 | 
				
			||||||
	if t == nl.CTA_PROTO_NUM {
 | 
						if t == nl.CTA_PROTO_NUM {
 | 
				
			||||||
		tpl.Protocol = uint8(v[0])
 | 
							tpl.Protocol = uint8(v[0])
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Skip some padding 3 bytes
 | 
						// We only parse TCP & UDP headers. Skip the others.
 | 
				
			||||||
 | 
						if tpl.Protocol != unix.IPPROTO_TCP && tpl.Protocol != unix.IPPROTO_UDP {
 | 
				
			||||||
 | 
							// skip the rest
 | 
				
			||||||
 | 
							bytesRemaining := protoInfoTotalLen - protoInfoBytesRead
 | 
				
			||||||
 | 
							reader.Seek(int64(bytesRemaining), seekCurrent)
 | 
				
			||||||
 | 
							return tpl.Protocol
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// Skip 3 bytes of padding
 | 
				
			||||||
	reader.Seek(3, seekCurrent)
 | 
						reader.Seek(3, seekCurrent)
 | 
				
			||||||
 | 
						protoInfoBytesRead += 3
 | 
				
			||||||
	for i := 0; i < 2; i++ {
 | 
						for i := 0; i < 2; i++ {
 | 
				
			||||||
		_, t, _ := parseNfAttrTL(reader)
 | 
							_, t, _ := parseNfAttrTL(reader)
 | 
				
			||||||
 | 
							protoInfoBytesRead += uint16(nl.SizeofNfattr)
 | 
				
			||||||
		switch t {
 | 
							switch t {
 | 
				
			||||||
		case nl.CTA_PROTO_SRC_PORT:
 | 
							case nl.CTA_PROTO_SRC_PORT:
 | 
				
			||||||
			parseBERaw16(reader, &tpl.SrcPort)
 | 
								parseBERaw16(reader, &tpl.SrcPort)
 | 
				
			||||||
 | 
								protoInfoBytesRead += 2
 | 
				
			||||||
		case nl.CTA_PROTO_DST_PORT:
 | 
							case nl.CTA_PROTO_DST_PORT:
 | 
				
			||||||
			parseBERaw16(reader, &tpl.DstPort)
 | 
								parseBERaw16(reader, &tpl.DstPort)
 | 
				
			||||||
 | 
								protoInfoBytesRead += 2
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// Skip some padding 2 byte
 | 
							// Skip 2 bytes of padding
 | 
				
			||||||
		reader.Seek(2, seekCurrent)
 | 
							reader.Seek(2, seekCurrent)
 | 
				
			||||||
 | 
							protoInfoBytesRead += 2
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						// Skip any remaining/unknown parts of the message
 | 
				
			||||||
 | 
						bytesRemaining := protoInfoTotalLen - protoInfoBytesRead
 | 
				
			||||||
 | 
						reader.Seek(int64(bytesRemaining), seekCurrent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return tpl.Protocol
 | 
						return tpl.Protocol
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -211,10 +459,18 @@ func parseNfAttrTL(r *bytes.Reader) (isNested bool, attrType, len uint16) {
 | 
				
			|||||||
	binary.Read(r, nl.NativeEndian(), &attrType)
 | 
						binary.Read(r, nl.NativeEndian(), &attrType)
 | 
				
			||||||
	isNested = (attrType & nl.NLA_F_NESTED) == nl.NLA_F_NESTED
 | 
						isNested = (attrType & nl.NLA_F_NESTED) == nl.NLA_F_NESTED
 | 
				
			||||||
	attrType = attrType & (nl.NLA_F_NESTED - 1)
 | 
						attrType = attrType & (nl.NLA_F_NESTED - 1)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return isNested, attrType, len
 | 
						return isNested, attrType, len
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// skipNfAttrValue seeks `r` past attr of length `len`.
 | 
				
			||||||
 | 
					// Maintains buffer alignment.
 | 
				
			||||||
 | 
					// Returns length of the seek performed.
 | 
				
			||||||
 | 
					func skipNfAttrValue(r *bytes.Reader, len uint16) uint16 {
 | 
				
			||||||
 | 
						len = (len + nl.NLA_ALIGNTO - 1) & ^(nl.NLA_ALIGNTO - 1)
 | 
				
			||||||
 | 
						r.Seek(int64(len), seekCurrent)
 | 
				
			||||||
 | 
						return len
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseBERaw16(r *bytes.Reader, v *uint16) {
 | 
					func parseBERaw16(r *bytes.Reader, v *uint16) {
 | 
				
			||||||
	binary.Read(r, binary.BigEndian, v)
 | 
						binary.Read(r, binary.BigEndian, v)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -227,6 +483,10 @@ func parseBERaw64(r *bytes.Reader, v *uint64) {
 | 
				
			|||||||
	binary.Read(r, binary.BigEndian, v)
 | 
						binary.Read(r, binary.BigEndian, v)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseRaw32(r *bytes.Reader, v *uint32) {
 | 
				
			||||||
 | 
						binary.Read(r, nl.NativeEndian(), v)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseByteAndPacketCounters(r *bytes.Reader) (bytes, packets uint64) {
 | 
					func parseByteAndPacketCounters(r *bytes.Reader) (bytes, packets uint64) {
 | 
				
			||||||
	for i := 0; i < 2; i++ {
 | 
						for i := 0; i < 2; i++ {
 | 
				
			||||||
		switch _, t, _ := parseNfAttrTL(r); t {
 | 
							switch _, t, _ := parseNfAttrTL(r); t {
 | 
				
			||||||
@@ -241,11 +501,107 @@ func parseByteAndPacketCounters(r *bytes.Reader) (bytes, packets uint64) {
 | 
				
			|||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// when the flow is alive, only the timestamp_start is returned in structure
 | 
				
			||||||
 | 
					func parseTimeStamp(r *bytes.Reader, readSize uint16) (tstart, tstop uint64) {
 | 
				
			||||||
 | 
						var numTimeStamps int
 | 
				
			||||||
 | 
						oneItem := nl.SizeofNfattr + 8 // 4 bytes attr header + 8 bytes timestamp
 | 
				
			||||||
 | 
						if readSize == uint16(oneItem) {
 | 
				
			||||||
 | 
							numTimeStamps = 1
 | 
				
			||||||
 | 
						} else if readSize == 2*uint16(oneItem) {
 | 
				
			||||||
 | 
							numTimeStamps = 2
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for i := 0; i < numTimeStamps; i++ {
 | 
				
			||||||
 | 
							switch _, t, _ := parseNfAttrTL(r); t {
 | 
				
			||||||
 | 
							case nl.CTA_TIMESTAMP_START:
 | 
				
			||||||
 | 
								parseBERaw64(r, &tstart)
 | 
				
			||||||
 | 
							case nl.CTA_TIMESTAMP_STOP:
 | 
				
			||||||
 | 
								parseBERaw64(r, &tstop)
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseProtoInfoTCPState(r *bytes.Reader) (s uint8) {
 | 
				
			||||||
 | 
						binary.Read(r, binary.BigEndian, &s)
 | 
				
			||||||
 | 
						r.Seek(nl.SizeofNfattr - 1, seekCurrent)
 | 
				
			||||||
 | 
						return s
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// parseProtoInfoTCP reads the entire nested protoinfo structure, but only parses the state attr.
 | 
				
			||||||
 | 
					func parseProtoInfoTCP(r *bytes.Reader, attrLen uint16) (*ProtoInfoTCP) {
 | 
				
			||||||
 | 
						p := new(ProtoInfoTCP)
 | 
				
			||||||
 | 
						bytesRead := 0
 | 
				
			||||||
 | 
						for bytesRead < int(attrLen) {
 | 
				
			||||||
 | 
							_, t, l := parseNfAttrTL(r)
 | 
				
			||||||
 | 
							bytesRead += nl.SizeofNfattr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							switch t {
 | 
				
			||||||
 | 
							case nl.CTA_PROTOINFO_TCP_STATE:
 | 
				
			||||||
 | 
								p.State = parseProtoInfoTCPState(r)
 | 
				
			||||||
 | 
								bytesRead += nl.SizeofNfattr
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								bytesRead += int(skipNfAttrValue(r, l))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return p
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseProtoInfo(r *bytes.Reader, attrLen uint16) (p ProtoInfo) {
 | 
				
			||||||
 | 
						bytesRead := 0
 | 
				
			||||||
 | 
						for bytesRead < int(attrLen) {
 | 
				
			||||||
 | 
							_, t, l := parseNfAttrTL(r)
 | 
				
			||||||
 | 
							bytesRead += nl.SizeofNfattr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							switch t {
 | 
				
			||||||
 | 
							case nl.CTA_PROTOINFO_TCP:
 | 
				
			||||||
 | 
								p = parseProtoInfoTCP(r, l)
 | 
				
			||||||
 | 
								bytesRead += int(l)
 | 
				
			||||||
 | 
							// No inner fields of DCCP / SCTP currently supported.
 | 
				
			||||||
 | 
							case nl.CTA_PROTOINFO_DCCP:
 | 
				
			||||||
 | 
								p = new(ProtoInfoDCCP)
 | 
				
			||||||
 | 
								skipped := skipNfAttrValue(r, l)
 | 
				
			||||||
 | 
								bytesRead += int(skipped)
 | 
				
			||||||
 | 
							case nl.CTA_PROTOINFO_SCTP:
 | 
				
			||||||
 | 
								p = new(ProtoInfoSCTP)
 | 
				
			||||||
 | 
								skipped := skipNfAttrValue(r, l)
 | 
				
			||||||
 | 
								bytesRead += int(skipped)
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								skipped := skipNfAttrValue(r, l)
 | 
				
			||||||
 | 
								bytesRead += int(skipped)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return p
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseTimeOut(r *bytes.Reader) (ttimeout uint32) {
 | 
				
			||||||
 | 
						parseBERaw32(r, &ttimeout)
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseConnectionMark(r *bytes.Reader) (mark uint32) {
 | 
					func parseConnectionMark(r *bytes.Reader) (mark uint32) {
 | 
				
			||||||
	parseBERaw32(r, &mark)
 | 
						parseBERaw32(r, &mark)
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseConnectionLabels(r *bytes.Reader) (label []byte) {
 | 
				
			||||||
 | 
						label = make([]byte, 16) // netfilter defines 128 bit labels value
 | 
				
			||||||
 | 
						binary.Read(r, nl.NativeEndian(), &label)
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseConnectionZone(r *bytes.Reader) (zone uint16) {
 | 
				
			||||||
 | 
						parseBERaw16(r, &zone)
 | 
				
			||||||
 | 
						r.Seek(2, seekCurrent)
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseRawData(data []byte) *ConntrackFlow {
 | 
					func parseRawData(data []byte) *ConntrackFlow {
 | 
				
			||||||
	s := &ConntrackFlow{}
 | 
						s := &ConntrackFlow{}
 | 
				
			||||||
	// First there is the Nfgenmsg header
 | 
						// First there is the Nfgenmsg header
 | 
				
			||||||
@@ -266,25 +622,41 @@ func parseRawData(data []byte) *ConntrackFlow {
 | 
				
			|||||||
		if nested, t, l := parseNfAttrTL(reader); nested {
 | 
							if nested, t, l := parseNfAttrTL(reader); nested {
 | 
				
			||||||
			switch t {
 | 
								switch t {
 | 
				
			||||||
			case nl.CTA_TUPLE_ORIG:
 | 
								case nl.CTA_TUPLE_ORIG:
 | 
				
			||||||
				if nested, t, _ = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP {
 | 
									if nested, t, l = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP {
 | 
				
			||||||
					parseIpTuple(reader, &s.Forward)
 | 
										parseIpTuple(reader, &s.Forward)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			case nl.CTA_TUPLE_REPLY:
 | 
								case nl.CTA_TUPLE_REPLY:
 | 
				
			||||||
				if nested, t, _ = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP {
 | 
									if nested, t, l = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP {
 | 
				
			||||||
					parseIpTuple(reader, &s.Reverse)
 | 
										parseIpTuple(reader, &s.Reverse)
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					// Header not recognized skip it
 | 
										// Header not recognized skip it
 | 
				
			||||||
					reader.Seek(int64(l), seekCurrent)
 | 
										skipNfAttrValue(reader, l)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			case nl.CTA_COUNTERS_ORIG:
 | 
								case nl.CTA_COUNTERS_ORIG:
 | 
				
			||||||
				s.Forward.Bytes, s.Forward.Packets = parseByteAndPacketCounters(reader)
 | 
									s.Forward.Bytes, s.Forward.Packets = parseByteAndPacketCounters(reader)
 | 
				
			||||||
			case nl.CTA_COUNTERS_REPLY:
 | 
								case nl.CTA_COUNTERS_REPLY:
 | 
				
			||||||
				s.Reverse.Bytes, s.Reverse.Packets = parseByteAndPacketCounters(reader)
 | 
									s.Reverse.Bytes, s.Reverse.Packets = parseByteAndPacketCounters(reader)
 | 
				
			||||||
 | 
								case nl.CTA_TIMESTAMP:
 | 
				
			||||||
 | 
									s.TimeStart, s.TimeStop = parseTimeStamp(reader, l)
 | 
				
			||||||
 | 
								case nl.CTA_PROTOINFO:
 | 
				
			||||||
 | 
									s.ProtoInfo = parseProtoInfo(reader, l)
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									skipNfAttrValue(reader, l)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			switch t {
 | 
								switch t {
 | 
				
			||||||
			case nl.CTA_MARK:
 | 
								case nl.CTA_MARK:
 | 
				
			||||||
				s.Mark = parseConnectionMark(reader)
 | 
									s.Mark = parseConnectionMark(reader)
 | 
				
			||||||
 | 
									case nl.CTA_LABELS:
 | 
				
			||||||
 | 
									s.Labels = parseConnectionLabels(reader)
 | 
				
			||||||
 | 
								case nl.CTA_TIMEOUT:
 | 
				
			||||||
 | 
									s.TimeOut = parseTimeOut(reader)
 | 
				
			||||||
 | 
								case nl.CTA_ID, nl.CTA_STATUS, nl.CTA_USE:
 | 
				
			||||||
 | 
									skipNfAttrValue(reader, l)
 | 
				
			||||||
 | 
								case nl.CTA_ZONE:
 | 
				
			||||||
 | 
									s.Zone = parseConnectionZone(reader)
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									skipNfAttrValue(reader, l)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -318,6 +690,11 @@ func parseRawData(data []byte) *ConntrackFlow {
 | 
				
			|||||||
//   --mask-src ip                 Source mask address
 | 
					//   --mask-src ip                 Source mask address
 | 
				
			||||||
//   --mask-dst ip                 Destination mask address
 | 
					//   --mask-dst ip                 Destination mask address
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Layer 4 Protocol common parameters and options:
 | 
				
			||||||
 | 
					// TCP, UDP, SCTP, UDPLite and DCCP
 | 
				
			||||||
 | 
					//    --sport, --orig-port-src port    Source port in original direction
 | 
				
			||||||
 | 
					//    --dport, --orig-port-dst port    Destination port in original direction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Filter types
 | 
					// Filter types
 | 
				
			||||||
type ConntrackFilterType uint8
 | 
					type ConntrackFilterType uint8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -327,9 +704,13 @@ const (
 | 
				
			|||||||
	ConntrackReplySrcIP                          // --reply-src ip  Reply Source IP
 | 
						ConntrackReplySrcIP                          // --reply-src ip  Reply Source IP
 | 
				
			||||||
	ConntrackReplyDstIP                          // --reply-dst ip  Reply Destination IP
 | 
						ConntrackReplyDstIP                          // --reply-dst ip  Reply Destination IP
 | 
				
			||||||
	ConntrackReplyAnyIP                          // Match source or destination reply IP
 | 
						ConntrackReplyAnyIP                          // Match source or destination reply IP
 | 
				
			||||||
 | 
						ConntrackOrigSrcPort                         // --orig-port-src port    Source port in original direction
 | 
				
			||||||
 | 
						ConntrackOrigDstPort                         // --orig-port-dst port    Destination port in original direction
 | 
				
			||||||
 | 
						ConntrackMatchLabels                         // --label label1,label2   Labels used in entry
 | 
				
			||||||
 | 
						ConntrackUnmatchLabels                       // --label label1,label2   Labels not used in entry
 | 
				
			||||||
	ConntrackNatSrcIP      = ConntrackReplySrcIP // deprecated use instead ConntrackReplySrcIP
 | 
						ConntrackNatSrcIP      = ConntrackReplySrcIP // deprecated use instead ConntrackReplySrcIP
 | 
				
			||||||
	ConntrackNatDstIP      = ConntrackReplyDstIP // deprecated use instead ConntrackReplyDstIP
 | 
						ConntrackNatDstIP      = ConntrackReplyDstIP // deprecated use instead ConntrackReplyDstIP
 | 
				
			||||||
	ConntrackNatAnyIP   = ConntrackReplyAnyIP // deprecated use instaed ConntrackReplyAnyIP
 | 
						ConntrackNatAnyIP      = ConntrackReplyAnyIP // deprecated use instead ConntrackReplyAnyIP
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type CustomConntrackFilter interface {
 | 
					type CustomConntrackFilter interface {
 | 
				
			||||||
@@ -339,53 +720,180 @@ type CustomConntrackFilter interface {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ConntrackFilter struct {
 | 
					type ConntrackFilter struct {
 | 
				
			||||||
	ipFilter map[ConntrackFilterType]net.IP
 | 
						ipNetFilter map[ConntrackFilterType]*net.IPNet
 | 
				
			||||||
 | 
						portFilter  map[ConntrackFilterType]uint16
 | 
				
			||||||
 | 
						protoFilter uint8
 | 
				
			||||||
 | 
						labelFilter map[ConntrackFilterType][][]byte
 | 
				
			||||||
 | 
						zoneFilter  *uint16
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// AddIPNet adds a IP subnet to the conntrack filter
 | 
				
			||||||
 | 
					func (f *ConntrackFilter) AddIPNet(tp ConntrackFilterType, ipNet *net.IPNet) error {
 | 
				
			||||||
 | 
						if ipNet == nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("Filter attribute empty")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if f.ipNetFilter == nil {
 | 
				
			||||||
 | 
							f.ipNetFilter = make(map[ConntrackFilterType]*net.IPNet)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if _, ok := f.ipNetFilter[tp]; ok {
 | 
				
			||||||
 | 
							return errors.New("Filter attribute already present")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						f.ipNetFilter[tp] = ipNet
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AddIP adds an IP to the conntrack filter
 | 
					// AddIP adds an IP to the conntrack filter
 | 
				
			||||||
func (f *ConntrackFilter) AddIP(tp ConntrackFilterType, ip net.IP) error {
 | 
					func (f *ConntrackFilter) AddIP(tp ConntrackFilterType, ip net.IP) error {
 | 
				
			||||||
	if f.ipFilter == nil {
 | 
						if ip == nil {
 | 
				
			||||||
		f.ipFilter = make(map[ConntrackFilterType]net.IP)
 | 
							return fmt.Errorf("Filter attribute empty")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if _, ok := f.ipFilter[tp]; ok {
 | 
						return f.AddIPNet(tp, NewIPNet(ip))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// AddPort adds a Port to the conntrack filter if the Layer 4 protocol allows it
 | 
				
			||||||
 | 
					func (f *ConntrackFilter) AddPort(tp ConntrackFilterType, port uint16) error {
 | 
				
			||||||
 | 
						switch f.protoFilter {
 | 
				
			||||||
 | 
						// TCP, UDP, DCCP, SCTP, UDPLite
 | 
				
			||||||
 | 
						case 6, 17, 33, 132, 136:
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return fmt.Errorf("Filter attribute not available without a valid Layer 4 protocol: %d", f.protoFilter)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if f.portFilter == nil {
 | 
				
			||||||
 | 
							f.portFilter = make(map[ConntrackFilterType]uint16)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if _, ok := f.portFilter[tp]; ok {
 | 
				
			||||||
		return errors.New("Filter attribute already present")
 | 
							return errors.New("Filter attribute already present")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	f.ipFilter[tp] = ip
 | 
						f.portFilter[tp] = port
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// AddProtocol adds the Layer 4 protocol to the conntrack filter
 | 
				
			||||||
 | 
					func (f *ConntrackFilter) AddProtocol(proto uint8) error {
 | 
				
			||||||
 | 
						if f.protoFilter != 0 {
 | 
				
			||||||
 | 
							return errors.New("Filter attribute already present")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						f.protoFilter = proto
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// AddLabels adds the provided list (zero or more) of labels to the conntrack filter
 | 
				
			||||||
 | 
					// ConntrackFilterType here can be either:
 | 
				
			||||||
 | 
					//  1. ConntrackMatchLabels: This matches every flow that has a label value (len(flow.Labels) > 0)
 | 
				
			||||||
 | 
					//     against the list of provided labels. If `flow.Labels` contains ALL the provided labels
 | 
				
			||||||
 | 
					//     it is considered a match. This can be used when you want to match flows that contain
 | 
				
			||||||
 | 
					//     one or more labels.
 | 
				
			||||||
 | 
					//  2. ConntrackUnmatchLabels:  This matches every flow that has a label value (len(flow.Labels) > 0)
 | 
				
			||||||
 | 
					//     against the list of provided labels. If `flow.Labels` does NOT contain ALL the provided labels
 | 
				
			||||||
 | 
					//     it is considered a match. This can be used when you want to match flows that don't contain
 | 
				
			||||||
 | 
					//     one or more labels.
 | 
				
			||||||
 | 
					func (f *ConntrackFilter) AddLabels(tp ConntrackFilterType, labels [][]byte) error {
 | 
				
			||||||
 | 
						if len(labels) == 0 {
 | 
				
			||||||
 | 
							return errors.New("Invalid length for provided labels")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if f.labelFilter == nil {
 | 
				
			||||||
 | 
							f.labelFilter = make(map[ConntrackFilterType][][]byte)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if _, ok := f.labelFilter[tp]; ok {
 | 
				
			||||||
 | 
							return errors.New("Filter attribute already present")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						f.labelFilter[tp] = labels
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// AddZone adds a zone to the conntrack filter
 | 
				
			||||||
 | 
					func (f *ConntrackFilter) AddZone(zone uint16) error {
 | 
				
			||||||
 | 
						if f.zoneFilter != nil {
 | 
				
			||||||
 | 
							return errors.New("Filter attribute already present")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						f.zoneFilter = &zone
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MatchConntrackFlow applies the filter to the flow and returns true if the flow matches the filter
 | 
					// MatchConntrackFlow applies the filter to the flow and returns true if the flow matches the filter
 | 
				
			||||||
// false otherwise
 | 
					// false otherwise
 | 
				
			||||||
func (f *ConntrackFilter) MatchConntrackFlow(flow *ConntrackFlow) bool {
 | 
					func (f *ConntrackFilter) MatchConntrackFlow(flow *ConntrackFlow) bool {
 | 
				
			||||||
	if len(f.ipFilter) == 0 {
 | 
						if len(f.ipNetFilter) == 0 && len(f.portFilter) == 0 && f.protoFilter == 0 && len(f.labelFilter) == 0 && f.zoneFilter == nil {
 | 
				
			||||||
		// empty filter always not match
 | 
							// empty filter always not match
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// -p, --protonum proto          Layer 4 Protocol, eg. 'tcp'
 | 
				
			||||||
 | 
						if f.protoFilter != 0 && flow.Forward.Protocol != f.protoFilter {
 | 
				
			||||||
 | 
							// different Layer 4 protocol always not match
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Conntrack zone filter
 | 
				
			||||||
 | 
						if f.zoneFilter != nil && *f.zoneFilter != flow.Zone {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	match := true
 | 
						match := true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// IP conntrack filter
 | 
				
			||||||
 | 
						if len(f.ipNetFilter) > 0 {
 | 
				
			||||||
		// -orig-src ip   Source address from original direction
 | 
							// -orig-src ip   Source address from original direction
 | 
				
			||||||
	if elem, found := f.ipFilter[ConntrackOrigSrcIP]; found {
 | 
							if elem, found := f.ipNetFilter[ConntrackOrigSrcIP]; found {
 | 
				
			||||||
		match = match && elem.Equal(flow.Forward.SrcIP)
 | 
								match = match && elem.Contains(flow.Forward.SrcIP)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// -orig-dst ip   Destination address from original direction
 | 
							// -orig-dst ip   Destination address from original direction
 | 
				
			||||||
	if elem, found := f.ipFilter[ConntrackOrigDstIP]; match && found {
 | 
							if elem, found := f.ipNetFilter[ConntrackOrigDstIP]; match && found {
 | 
				
			||||||
		match = match && elem.Equal(flow.Forward.DstIP)
 | 
								match = match && elem.Contains(flow.Forward.DstIP)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// -src-nat ip    Source NAT ip
 | 
							// -src-nat ip    Source NAT ip
 | 
				
			||||||
	if elem, found := f.ipFilter[ConntrackReplySrcIP]; match && found {
 | 
							if elem, found := f.ipNetFilter[ConntrackReplySrcIP]; match && found {
 | 
				
			||||||
		match = match && elem.Equal(flow.Reverse.SrcIP)
 | 
								match = match && elem.Contains(flow.Reverse.SrcIP)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// -dst-nat ip    Destination NAT ip
 | 
							// -dst-nat ip    Destination NAT ip
 | 
				
			||||||
	if elem, found := f.ipFilter[ConntrackReplyDstIP]; match && found {
 | 
							if elem, found := f.ipNetFilter[ConntrackReplyDstIP]; match && found {
 | 
				
			||||||
		match = match && elem.Equal(flow.Reverse.DstIP)
 | 
								match = match && elem.Contains(flow.Reverse.DstIP)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Match source or destination reply IP
 | 
							// Match source or destination reply IP
 | 
				
			||||||
	if elem, found := f.ipFilter[ConntrackReplyAnyIP]; match && found {
 | 
							if elem, found := f.ipNetFilter[ConntrackReplyAnyIP]; match && found {
 | 
				
			||||||
		match = match && (elem.Equal(flow.Reverse.SrcIP) || elem.Equal(flow.Reverse.DstIP))
 | 
								match = match && (elem.Contains(flow.Reverse.SrcIP) || elem.Contains(flow.Reverse.DstIP))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Layer 4 Port filter
 | 
				
			||||||
 | 
						if len(f.portFilter) > 0 {
 | 
				
			||||||
 | 
							// -orig-port-src port	Source port from original direction
 | 
				
			||||||
 | 
							if elem, found := f.portFilter[ConntrackOrigSrcPort]; match && found {
 | 
				
			||||||
 | 
								match = match && elem == flow.Forward.SrcPort
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// -orig-port-dst port	Destination port from original direction
 | 
				
			||||||
 | 
							if elem, found := f.portFilter[ConntrackOrigDstPort]; match && found {
 | 
				
			||||||
 | 
								match = match && elem == flow.Forward.DstPort
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Label filter
 | 
				
			||||||
 | 
						if len(f.labelFilter) > 0 {
 | 
				
			||||||
 | 
							if len(flow.Labels) > 0 {
 | 
				
			||||||
 | 
								// --label label1,label2 in conn entry;
 | 
				
			||||||
 | 
								// every label passed should be contained in flow.Labels for a match to be true
 | 
				
			||||||
 | 
								if elem, found := f.labelFilter[ConntrackMatchLabels]; match && found {
 | 
				
			||||||
 | 
									for _, label := range elem {
 | 
				
			||||||
 | 
										match = match && (bytes.Contains(flow.Labels, label))
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								// --label label1,label2 in conn entry;
 | 
				
			||||||
 | 
								// every label passed should be not contained in flow.Labels for a match to be true
 | 
				
			||||||
 | 
								if elem, found := f.labelFilter[ConntrackUnmatchLabels]; match && found {
 | 
				
			||||||
 | 
									for _, label := range elem {
 | 
				
			||||||
 | 
										match = match && !(bytes.Contains(flow.Labels, label))
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								// flow doesn't contain labels, so it doesn't contain or notContain any provided matches
 | 
				
			||||||
 | 
								match = false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return match
 | 
						return match
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										19
									
								
								vendor/github.com/vishvananda/netlink/conntrack_unspecified.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/github.com/vishvananda/netlink/conntrack_unspecified.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -11,6 +11,9 @@ type InetFamily uint8
 | 
				
			|||||||
// ConntrackFlow placeholder
 | 
					// ConntrackFlow placeholder
 | 
				
			||||||
type ConntrackFlow struct{}
 | 
					type ConntrackFlow struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CustomConntrackFilter placeholder
 | 
				
			||||||
 | 
					type CustomConntrackFilter struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ConntrackFilter placeholder
 | 
					// ConntrackFilter placeholder
 | 
				
			||||||
type ConntrackFilter struct{}
 | 
					type ConntrackFilter struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -29,10 +32,18 @@ func ConntrackTableFlush(table ConntrackTableType) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter
 | 
					// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter
 | 
				
			||||||
// conntrack -D [table] parameters         Delete conntrack or expectation
 | 
					// conntrack -D [table] parameters         Delete conntrack or expectation
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Deprecated: use [ConntrackDeleteFilter] instead.
 | 
				
			||||||
func ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter *ConntrackFilter) (uint, error) {
 | 
					func ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter *ConntrackFilter) (uint, error) {
 | 
				
			||||||
	return 0, ErrNotImplemented
 | 
						return 0, ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ConntrackDeleteFilters deletes entries on the specified table matching any of the specified filters
 | 
				
			||||||
 | 
					// conntrack -D [table] parameters         Delete conntrack or expectation
 | 
				
			||||||
 | 
					func ConntrackDeleteFilters(table ConntrackTableType, family InetFamily, filters ...CustomConntrackFilter) (uint, error) {
 | 
				
			||||||
 | 
						return 0, ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ConntrackTableList returns the flow list of a table of a specific family using the netlink handle passed
 | 
					// ConntrackTableList returns the flow list of a table of a specific family using the netlink handle passed
 | 
				
			||||||
// conntrack -L [table] [options]          List conntrack or expectation table
 | 
					// conntrack -L [table] [options]          List conntrack or expectation table
 | 
				
			||||||
func (h *Handle) ConntrackTableList(table ConntrackTableType, family InetFamily) ([]*ConntrackFlow, error) {
 | 
					func (h *Handle) ConntrackTableList(table ConntrackTableType, family InetFamily) ([]*ConntrackFlow, error) {
 | 
				
			||||||
@@ -48,6 +59,14 @@ func (h *Handle) ConntrackTableFlush(table ConntrackTableType) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter using the netlink handle passed
 | 
					// ConntrackDeleteFilter deletes entries on the specified table on the base of the filter using the netlink handle passed
 | 
				
			||||||
// conntrack -D [table] parameters         Delete conntrack or expectation
 | 
					// conntrack -D [table] parameters         Delete conntrack or expectation
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Deprecated: use [Handle.ConntrackDeleteFilters] instead.
 | 
				
			||||||
func (h *Handle) ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter *ConntrackFilter) (uint, error) {
 | 
					func (h *Handle) ConntrackDeleteFilter(table ConntrackTableType, family InetFamily, filter *ConntrackFilter) (uint, error) {
 | 
				
			||||||
	return 0, ErrNotImplemented
 | 
						return 0, ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ConntrackDeleteFilters deletes entries on the specified table matching any of the specified filters using the netlink handle passed
 | 
				
			||||||
 | 
					// conntrack -D [table] parameters         Delete conntrack or expectation
 | 
				
			||||||
 | 
					func (h *Handle) ConntrackDeleteFilters(table ConntrackTableType, family InetFamily, filters ...CustomConntrackFilter) (uint, error) {
 | 
				
			||||||
 | 
						return 0, ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										897
									
								
								vendor/github.com/vishvananda/netlink/devlink_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										897
									
								
								vendor/github.com/vishvananda/netlink/devlink_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,9 +1,11 @@
 | 
				
			|||||||
package netlink
 | 
					package netlink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
	"syscall"
 | 
						"syscall"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"github.com/vishvananda/netlink/nl"
 | 
						"github.com/vishvananda/netlink/nl"
 | 
				
			||||||
	"golang.org/x/sys/unix"
 | 
						"golang.org/x/sys/unix"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -27,6 +29,325 @@ type DevlinkDevice struct {
 | 
				
			|||||||
	Attrs      DevlinkDevAttrs
 | 
						Attrs      DevlinkDevAttrs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkPortFn represents port function and its attributes
 | 
				
			||||||
 | 
					type DevlinkPortFn struct {
 | 
				
			||||||
 | 
						HwAddr  net.HardwareAddr
 | 
				
			||||||
 | 
						State   uint8
 | 
				
			||||||
 | 
						OpState uint8
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkPortFnSetAttrs represents attributes to set
 | 
				
			||||||
 | 
					type DevlinkPortFnSetAttrs struct {
 | 
				
			||||||
 | 
						FnAttrs     DevlinkPortFn
 | 
				
			||||||
 | 
						HwAddrValid bool
 | 
				
			||||||
 | 
						StateValid  bool
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkPort represents port and its attributes
 | 
				
			||||||
 | 
					type DevlinkPort struct {
 | 
				
			||||||
 | 
						BusName        string
 | 
				
			||||||
 | 
						DeviceName     string
 | 
				
			||||||
 | 
						PortIndex      uint32
 | 
				
			||||||
 | 
						PortType       uint16
 | 
				
			||||||
 | 
						NetdeviceName  string
 | 
				
			||||||
 | 
						NetdevIfIndex  uint32
 | 
				
			||||||
 | 
						RdmaDeviceName string
 | 
				
			||||||
 | 
						PortFlavour    uint16
 | 
				
			||||||
 | 
						Fn             *DevlinkPortFn
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type DevLinkPortAddAttrs struct {
 | 
				
			||||||
 | 
						Controller      uint32
 | 
				
			||||||
 | 
						SfNumber        uint32
 | 
				
			||||||
 | 
						PortIndex       uint32
 | 
				
			||||||
 | 
						PfNumber        uint16
 | 
				
			||||||
 | 
						SfNumberValid   bool
 | 
				
			||||||
 | 
						PortIndexValid  bool
 | 
				
			||||||
 | 
						ControllerValid bool
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkDeviceInfo represents devlink info
 | 
				
			||||||
 | 
					type DevlinkDeviceInfo struct {
 | 
				
			||||||
 | 
						Driver         string
 | 
				
			||||||
 | 
						SerialNumber   string
 | 
				
			||||||
 | 
						BoardID        string
 | 
				
			||||||
 | 
						FwApp          string
 | 
				
			||||||
 | 
						FwAppBoundleID string
 | 
				
			||||||
 | 
						FwAppName      string
 | 
				
			||||||
 | 
						FwBoundleID    string
 | 
				
			||||||
 | 
						FwMgmt         string
 | 
				
			||||||
 | 
						FwMgmtAPI      string
 | 
				
			||||||
 | 
						FwMgmtBuild    string
 | 
				
			||||||
 | 
						FwNetlist      string
 | 
				
			||||||
 | 
						FwNetlistBuild string
 | 
				
			||||||
 | 
						FwPsidAPI      string
 | 
				
			||||||
 | 
						FwUndi         string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkResource represents a device resource
 | 
				
			||||||
 | 
					type DevlinkResource struct {
 | 
				
			||||||
 | 
						Name            string
 | 
				
			||||||
 | 
						ID              uint64
 | 
				
			||||||
 | 
						Size            uint64
 | 
				
			||||||
 | 
						SizeNew         uint64
 | 
				
			||||||
 | 
						SizeMin         uint64
 | 
				
			||||||
 | 
						SizeMax         uint64
 | 
				
			||||||
 | 
						SizeGranularity uint64
 | 
				
			||||||
 | 
						PendingChange   bool
 | 
				
			||||||
 | 
						Unit            uint8
 | 
				
			||||||
 | 
						SizeValid       bool
 | 
				
			||||||
 | 
						OCCValid        bool
 | 
				
			||||||
 | 
						OCCSize         uint64
 | 
				
			||||||
 | 
						Parent          *DevlinkResource
 | 
				
			||||||
 | 
						Children        []DevlinkResource
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// parseAttributes parses provided Netlink Attributes and populates DevlinkResource, returns error if occured
 | 
				
			||||||
 | 
					func (dlr *DevlinkResource) parseAttributes(attrs map[uint16]syscall.NetlinkRouteAttr) error {
 | 
				
			||||||
 | 
						var attr syscall.NetlinkRouteAttr
 | 
				
			||||||
 | 
						var ok bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// mandatory attributes
 | 
				
			||||||
 | 
						attr, ok = attrs[nl.DEVLINK_ATTR_RESOURCE_ID]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return fmt.Errorf("missing resource id")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						dlr.ID = native.Uint64(attr.Value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						attr, ok = attrs[nl.DEVLINK_ATTR_RESOURCE_NAME]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return fmt.Errorf("missing resource name")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						dlr.Name = nl.BytesToString(attr.Value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						attr, ok = attrs[nl.DEVLINK_ATTR_RESOURCE_SIZE]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return fmt.Errorf("missing resource size")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						dlr.Size = native.Uint64(attr.Value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						attr, ok = attrs[nl.DEVLINK_ATTR_RESOURCE_SIZE_GRAN]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return fmt.Errorf("missing resource size granularity")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						dlr.SizeGranularity = native.Uint64(attr.Value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						attr, ok = attrs[nl.DEVLINK_ATTR_RESOURCE_UNIT]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return fmt.Errorf("missing resource unit")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						dlr.Unit = uint8(attr.Value[0])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						attr, ok = attrs[nl.DEVLINK_ATTR_RESOURCE_SIZE_MIN]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return fmt.Errorf("missing resource size min")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						dlr.SizeMin = native.Uint64(attr.Value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						attr, ok = attrs[nl.DEVLINK_ATTR_RESOURCE_SIZE_MAX]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return fmt.Errorf("missing resource size max")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						dlr.SizeMax = native.Uint64(attr.Value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// optional attributes
 | 
				
			||||||
 | 
						attr, ok = attrs[nl.DEVLINK_ATTR_RESOURCE_OCC]
 | 
				
			||||||
 | 
						if ok {
 | 
				
			||||||
 | 
							dlr.OCCSize = native.Uint64(attr.Value)
 | 
				
			||||||
 | 
							dlr.OCCValid = true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						attr, ok = attrs[nl.DEVLINK_ATTR_RESOURCE_SIZE_VALID]
 | 
				
			||||||
 | 
						if ok {
 | 
				
			||||||
 | 
							dlr.SizeValid = uint8(attr.Value[0]) != 0
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dlr.SizeNew = dlr.Size
 | 
				
			||||||
 | 
						attr, ok = attrs[nl.DEVLINK_ATTR_RESOURCE_SIZE_NEW]
 | 
				
			||||||
 | 
						if ok {
 | 
				
			||||||
 | 
							dlr.SizeNew = native.Uint64(attr.Value)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dlr.PendingChange = dlr.Size != dlr.SizeNew
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						attr, ok = attrs[nl.DEVLINK_ATTR_RESOURCE_LIST]
 | 
				
			||||||
 | 
						if ok {
 | 
				
			||||||
 | 
							// handle nested resoruces recursively
 | 
				
			||||||
 | 
							subResources, err := nl.ParseRouteAttr(attr.Value)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for _, subresource := range subResources {
 | 
				
			||||||
 | 
								resource := DevlinkResource{Parent: dlr}
 | 
				
			||||||
 | 
								attrs, err := nl.ParseRouteAttrAsMap(subresource.Value)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								err = resource.parseAttributes(attrs)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return fmt.Errorf("failed to parse child resource, parent:%s. %w", dlr.Name, err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								dlr.Children = append(dlr.Children, resource)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkResources represents all devlink resources of a devlink device
 | 
				
			||||||
 | 
					type DevlinkResources struct {
 | 
				
			||||||
 | 
						Bus       string
 | 
				
			||||||
 | 
						Device    string
 | 
				
			||||||
 | 
						Resources []DevlinkResource
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// parseAttributes parses provided Netlink Attributes and populates DevlinkResources, returns error if occured
 | 
				
			||||||
 | 
					func (dlrs *DevlinkResources) parseAttributes(attrs map[uint16]syscall.NetlinkRouteAttr) error {
 | 
				
			||||||
 | 
						var attr syscall.NetlinkRouteAttr
 | 
				
			||||||
 | 
						var ok bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Bus
 | 
				
			||||||
 | 
						attr, ok = attrs[nl.DEVLINK_ATTR_BUS_NAME]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return fmt.Errorf("missing bus name")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						dlrs.Bus = nl.BytesToString(attr.Value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Device
 | 
				
			||||||
 | 
						attr, ok = attrs[nl.DEVLINK_ATTR_DEV_NAME]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return fmt.Errorf("missing device name")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						dlrs.Device = nl.BytesToString(attr.Value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Resource List
 | 
				
			||||||
 | 
						attr, ok = attrs[nl.DEVLINK_ATTR_RESOURCE_LIST]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return fmt.Errorf("missing resource list")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						resourceAttrs, err := nl.ParseRouteAttr(attr.Value)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, resourceAttr := range resourceAttrs {
 | 
				
			||||||
 | 
							resource := DevlinkResource{}
 | 
				
			||||||
 | 
							attrs, err := nl.ParseRouteAttrAsMap(resourceAttr.Value)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							err = resource.parseAttributes(attrs)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return fmt.Errorf("failed to parse root resoruces, %w", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							dlrs.Resources = append(dlrs.Resources, resource)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkParam represents parameter of the device
 | 
				
			||||||
 | 
					type DevlinkParam struct {
 | 
				
			||||||
 | 
						Name      string
 | 
				
			||||||
 | 
						IsGeneric bool
 | 
				
			||||||
 | 
						Type      uint8 // possible values are in nl.DEVLINK_PARAM_TYPE_* constants
 | 
				
			||||||
 | 
						Values    []DevlinkParamValue
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkParamValue contains values of the parameter
 | 
				
			||||||
 | 
					// Data field contains specific type which can be casted by unsing info from the DevlinkParam.Type field
 | 
				
			||||||
 | 
					type DevlinkParamValue struct {
 | 
				
			||||||
 | 
						rawData []byte
 | 
				
			||||||
 | 
						Data    interface{}
 | 
				
			||||||
 | 
						CMODE   uint8 // possible values are in nl.DEVLINK_PARAM_CMODE_* constants
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// parseAttributes parses provided Netlink Attributes and populates DevlinkParam, returns error if occured
 | 
				
			||||||
 | 
					func (dlp *DevlinkParam) parseAttributes(attrs []syscall.NetlinkRouteAttr) error {
 | 
				
			||||||
 | 
						var valuesList [][]syscall.NetlinkRouteAttr
 | 
				
			||||||
 | 
						for _, attr := range attrs {
 | 
				
			||||||
 | 
							switch attr.Attr.Type {
 | 
				
			||||||
 | 
							case nl.DEVLINK_ATTR_PARAM:
 | 
				
			||||||
 | 
								nattrs, err := nl.ParseRouteAttr(attr.Value)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								for _, nattr := range nattrs {
 | 
				
			||||||
 | 
									switch nattr.Attr.Type {
 | 
				
			||||||
 | 
									case nl.DEVLINK_ATTR_PARAM_NAME:
 | 
				
			||||||
 | 
										dlp.Name = nl.BytesToString(nattr.Value)
 | 
				
			||||||
 | 
									case nl.DEVLINK_ATTR_PARAM_GENERIC:
 | 
				
			||||||
 | 
										dlp.IsGeneric = true
 | 
				
			||||||
 | 
									case nl.DEVLINK_ATTR_PARAM_TYPE:
 | 
				
			||||||
 | 
										if len(nattr.Value) == 1 {
 | 
				
			||||||
 | 
											dlp.Type = nattr.Value[0]
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									case nl.DEVLINK_ATTR_PARAM_VALUES_LIST:
 | 
				
			||||||
 | 
										nnattrs, err := nl.ParseRouteAttr(nattr.Value)
 | 
				
			||||||
 | 
										if err != nil {
 | 
				
			||||||
 | 
											return err
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										valuesList = append(valuesList, nnattrs)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, valAttr := range valuesList {
 | 
				
			||||||
 | 
							v := DevlinkParamValue{}
 | 
				
			||||||
 | 
							if err := v.parseAttributes(valAttr, dlp.Type); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							dlp.Values = append(dlp.Values, v)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (dlpv *DevlinkParamValue) parseAttributes(attrs []syscall.NetlinkRouteAttr, paramType uint8) error {
 | 
				
			||||||
 | 
						for _, attr := range attrs {
 | 
				
			||||||
 | 
							nattrs, err := nl.ParseRouteAttr(attr.Value)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							var rawData []byte
 | 
				
			||||||
 | 
							for _, nattr := range nattrs {
 | 
				
			||||||
 | 
								switch nattr.Attr.Type {
 | 
				
			||||||
 | 
								case nl.DEVLINK_ATTR_PARAM_VALUE_DATA:
 | 
				
			||||||
 | 
									rawData = nattr.Value
 | 
				
			||||||
 | 
								case nl.DEVLINK_ATTR_PARAM_VALUE_CMODE:
 | 
				
			||||||
 | 
									if len(nattr.Value) == 1 {
 | 
				
			||||||
 | 
										dlpv.CMODE = nattr.Value[0]
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							switch paramType {
 | 
				
			||||||
 | 
							case nl.DEVLINK_PARAM_TYPE_U8:
 | 
				
			||||||
 | 
								dlpv.Data = uint8(0)
 | 
				
			||||||
 | 
								if rawData != nil && len(rawData) == 1 {
 | 
				
			||||||
 | 
									dlpv.Data = uint8(rawData[0])
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							case nl.DEVLINK_PARAM_TYPE_U16:
 | 
				
			||||||
 | 
								dlpv.Data = uint16(0)
 | 
				
			||||||
 | 
								if rawData != nil {
 | 
				
			||||||
 | 
									dlpv.Data = native.Uint16(rawData)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							case nl.DEVLINK_PARAM_TYPE_U32:
 | 
				
			||||||
 | 
								dlpv.Data = uint32(0)
 | 
				
			||||||
 | 
								if rawData != nil {
 | 
				
			||||||
 | 
									dlpv.Data = native.Uint32(rawData)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							case nl.DEVLINK_PARAM_TYPE_STRING:
 | 
				
			||||||
 | 
								dlpv.Data = ""
 | 
				
			||||||
 | 
								if rawData != nil {
 | 
				
			||||||
 | 
									dlpv.Data = nl.BytesToString(rawData)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							case nl.DEVLINK_PARAM_TYPE_BOOL:
 | 
				
			||||||
 | 
								dlpv.Data = rawData != nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseDevLinkDeviceList(msgs [][]byte) ([]*DevlinkDevice, error) {
 | 
					func parseDevLinkDeviceList(msgs [][]byte) ([]*DevlinkDevice, error) {
 | 
				
			||||||
	devices := make([]*DevlinkDevice, 0, len(msgs))
 | 
						devices := make([]*DevlinkDevice, 0, len(msgs))
 | 
				
			||||||
	for _, m := range msgs {
 | 
						for _, m := range msgs {
 | 
				
			||||||
@@ -95,9 +416,9 @@ func (d *DevlinkDevice) parseAttributes(attrs []syscall.NetlinkRouteAttr) error
 | 
				
			|||||||
	for _, a := range attrs {
 | 
						for _, a := range attrs {
 | 
				
			||||||
		switch a.Attr.Type {
 | 
							switch a.Attr.Type {
 | 
				
			||||||
		case nl.DEVLINK_ATTR_BUS_NAME:
 | 
							case nl.DEVLINK_ATTR_BUS_NAME:
 | 
				
			||||||
			d.BusName = string(a.Value)
 | 
								d.BusName = string(a.Value[:len(a.Value)-1])
 | 
				
			||||||
		case nl.DEVLINK_ATTR_DEV_NAME:
 | 
							case nl.DEVLINK_ATTR_DEV_NAME:
 | 
				
			||||||
			d.DeviceName = string(a.Value)
 | 
								d.DeviceName = string(a.Value[:len(a.Value)-1])
 | 
				
			||||||
		case nl.DEVLINK_ATTR_ESWITCH_MODE:
 | 
							case nl.DEVLINK_ATTR_ESWITCH_MODE:
 | 
				
			||||||
			d.Attrs.Eswitch.Mode = parseEswitchMode(native.Uint16(a.Value))
 | 
								d.Attrs.Eswitch.Mode = parseEswitchMode(native.Uint16(a.Value))
 | 
				
			||||||
		case nl.DEVLINK_ATTR_ESWITCH_INLINE_MODE:
 | 
							case nl.DEVLINK_ATTR_ESWITCH_INLINE_MODE:
 | 
				
			||||||
@@ -126,12 +447,12 @@ func (h *Handle) getEswitchAttrs(family *GenlFamily, dev *DevlinkDevice) {
 | 
				
			|||||||
	req := h.newNetlinkRequest(int(family.ID), unix.NLM_F_REQUEST|unix.NLM_F_ACK)
 | 
						req := h.newNetlinkRequest(int(family.ID), unix.NLM_F_REQUEST|unix.NLM_F_ACK)
 | 
				
			||||||
	req.AddData(msg)
 | 
						req.AddData(msg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b := make([]byte, len(dev.BusName))
 | 
						b := make([]byte, len(dev.BusName)+1)
 | 
				
			||||||
	copy(b, dev.BusName)
 | 
						copy(b, dev.BusName)
 | 
				
			||||||
	data := nl.NewRtAttr(nl.DEVLINK_ATTR_BUS_NAME, b)
 | 
						data := nl.NewRtAttr(nl.DEVLINK_ATTR_BUS_NAME, b)
 | 
				
			||||||
	req.AddData(data)
 | 
						req.AddData(data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b = make([]byte, len(dev.DeviceName))
 | 
						b = make([]byte, len(dev.DeviceName)+1)
 | 
				
			||||||
	copy(b, dev.DeviceName)
 | 
						copy(b, dev.DeviceName)
 | 
				
			||||||
	data = nl.NewRtAttr(nl.DEVLINK_ATTR_DEV_NAME, b)
 | 
						data = nl.NewRtAttr(nl.DEVLINK_ATTR_DEV_NAME, b)
 | 
				
			||||||
	req.AddData(data)
 | 
						req.AddData(data)
 | 
				
			||||||
@@ -270,3 +591,569 @@ func (h *Handle) DevLinkSetEswitchMode(Dev *DevlinkDevice, NewMode string) error
 | 
				
			|||||||
func DevLinkSetEswitchMode(Dev *DevlinkDevice, NewMode string) error {
 | 
					func DevLinkSetEswitchMode(Dev *DevlinkDevice, NewMode string) error {
 | 
				
			||||||
	return pkgHandle.DevLinkSetEswitchMode(Dev, NewMode)
 | 
						return pkgHandle.DevLinkSetEswitchMode(Dev, NewMode)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (port *DevlinkPort) parseAttributes(attrs []syscall.NetlinkRouteAttr) error {
 | 
				
			||||||
 | 
						for _, a := range attrs {
 | 
				
			||||||
 | 
							switch a.Attr.Type {
 | 
				
			||||||
 | 
							case nl.DEVLINK_ATTR_BUS_NAME:
 | 
				
			||||||
 | 
								port.BusName = string(a.Value[:len(a.Value)-1])
 | 
				
			||||||
 | 
							case nl.DEVLINK_ATTR_DEV_NAME:
 | 
				
			||||||
 | 
								port.DeviceName = string(a.Value[:len(a.Value)-1])
 | 
				
			||||||
 | 
							case nl.DEVLINK_ATTR_PORT_INDEX:
 | 
				
			||||||
 | 
								port.PortIndex = native.Uint32(a.Value)
 | 
				
			||||||
 | 
							case nl.DEVLINK_ATTR_PORT_TYPE:
 | 
				
			||||||
 | 
								port.PortType = native.Uint16(a.Value)
 | 
				
			||||||
 | 
							case nl.DEVLINK_ATTR_PORT_NETDEV_NAME:
 | 
				
			||||||
 | 
								port.NetdeviceName = string(a.Value[:len(a.Value)-1])
 | 
				
			||||||
 | 
							case nl.DEVLINK_ATTR_PORT_NETDEV_IFINDEX:
 | 
				
			||||||
 | 
								port.NetdevIfIndex = native.Uint32(a.Value)
 | 
				
			||||||
 | 
							case nl.DEVLINK_ATTR_PORT_IBDEV_NAME:
 | 
				
			||||||
 | 
								port.RdmaDeviceName = string(a.Value[:len(a.Value)-1])
 | 
				
			||||||
 | 
							case nl.DEVLINK_ATTR_PORT_FLAVOUR:
 | 
				
			||||||
 | 
								port.PortFlavour = native.Uint16(a.Value)
 | 
				
			||||||
 | 
							case nl.DEVLINK_ATTR_PORT_FUNCTION:
 | 
				
			||||||
 | 
								port.Fn = &DevlinkPortFn{}
 | 
				
			||||||
 | 
								for nested := range nl.ParseAttributes(a.Value) {
 | 
				
			||||||
 | 
									switch nested.Type {
 | 
				
			||||||
 | 
									case nl.DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR:
 | 
				
			||||||
 | 
										port.Fn.HwAddr = nested.Value[:]
 | 
				
			||||||
 | 
									case nl.DEVLINK_PORT_FN_ATTR_STATE:
 | 
				
			||||||
 | 
										port.Fn.State = uint8(nested.Value[0])
 | 
				
			||||||
 | 
									case nl.DEVLINK_PORT_FN_ATTR_OPSTATE:
 | 
				
			||||||
 | 
										port.Fn.OpState = uint8(nested.Value[0])
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseDevLinkAllPortList(msgs [][]byte) ([]*DevlinkPort, error) {
 | 
				
			||||||
 | 
						ports := make([]*DevlinkPort, 0, len(msgs))
 | 
				
			||||||
 | 
						for _, m := range msgs {
 | 
				
			||||||
 | 
							attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:])
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							port := &DevlinkPort{}
 | 
				
			||||||
 | 
							if err = port.parseAttributes(attrs); err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ports = append(ports, port)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ports, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevLinkGetPortList provides a pointer to devlink ports and nil error,
 | 
				
			||||||
 | 
					// otherwise returns an error code.
 | 
				
			||||||
 | 
					func (h *Handle) DevLinkGetAllPortList() ([]*DevlinkPort, error) {
 | 
				
			||||||
 | 
						f, err := h.GenlFamilyGet(nl.GENL_DEVLINK_NAME)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						msg := &nl.Genlmsg{
 | 
				
			||||||
 | 
							Command: nl.DEVLINK_CMD_PORT_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
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ports, err := parseDevLinkAllPortList(msgs)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ports, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevLinkGetPortList provides a pointer to devlink ports and nil error,
 | 
				
			||||||
 | 
					// otherwise returns an error code.
 | 
				
			||||||
 | 
					func DevLinkGetAllPortList() ([]*DevlinkPort, error) {
 | 
				
			||||||
 | 
						return pkgHandle.DevLinkGetAllPortList()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseDevlinkPortMsg(msgs [][]byte) (*DevlinkPort, error) {
 | 
				
			||||||
 | 
						m := msgs[0]
 | 
				
			||||||
 | 
						attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:])
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						port := &DevlinkPort{}
 | 
				
			||||||
 | 
						if err = port.parseAttributes(attrs); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return port, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevLinkGetPortByIndexprovides a pointer to devlink device and nil error,
 | 
				
			||||||
 | 
					// otherwise returns an error code.
 | 
				
			||||||
 | 
					func (h *Handle) DevLinkGetPortByIndex(Bus string, Device string, PortIndex uint32) (*DevlinkPort, error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, req, err := h.createCmdReq(nl.DEVLINK_CMD_PORT_GET, Bus, Device)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_INDEX, nl.Uint32Attr(PortIndex)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						respmsg, err := req.Execute(unix.NETLINK_GENERIC, 0)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						port, err := parseDevlinkPortMsg(respmsg)
 | 
				
			||||||
 | 
						return port, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkGetDeviceResources returns devlink device resources
 | 
				
			||||||
 | 
					func DevlinkGetDeviceResources(bus string, device string) (*DevlinkResources, error) {
 | 
				
			||||||
 | 
						return pkgHandle.DevlinkGetDeviceResources(bus, device)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkGetDeviceResources returns devlink device resources
 | 
				
			||||||
 | 
					func (h *Handle) DevlinkGetDeviceResources(bus string, device string) (*DevlinkResources, error) {
 | 
				
			||||||
 | 
						_, req, err := h.createCmdReq(nl.DEVLINK_CMD_RESOURCE_DUMP, bus, device)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						respmsg, err := req.Execute(unix.NETLINK_GENERIC, 0)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var resources DevlinkResources
 | 
				
			||||||
 | 
						for _, m := range respmsg {
 | 
				
			||||||
 | 
							attrs, err := nl.ParseRouteAttrAsMap(m[nl.SizeofGenlmsg:])
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							resources.parseAttributes(attrs)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &resources, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkGetDeviceParams returns parameters for devlink device
 | 
				
			||||||
 | 
					// Equivalent to: `devlink dev param show <bus>/<device>`
 | 
				
			||||||
 | 
					func (h *Handle) DevlinkGetDeviceParams(bus string, device string) ([]*DevlinkParam, error) {
 | 
				
			||||||
 | 
						_, req, err := h.createCmdReq(nl.DEVLINK_CMD_PARAM_GET, bus, device)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						req.Flags |= unix.NLM_F_DUMP
 | 
				
			||||||
 | 
						respmsg, err := req.Execute(unix.NETLINK_GENERIC, 0)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var params []*DevlinkParam
 | 
				
			||||||
 | 
						for _, m := range respmsg {
 | 
				
			||||||
 | 
							attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:])
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							p := &DevlinkParam{}
 | 
				
			||||||
 | 
							if err := p.parseAttributes(attrs); err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							params = append(params, p)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return params, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkGetDeviceParams returns parameters for devlink device
 | 
				
			||||||
 | 
					// Equivalent to: `devlink dev param show <bus>/<device>`
 | 
				
			||||||
 | 
					func DevlinkGetDeviceParams(bus string, device string) ([]*DevlinkParam, error) {
 | 
				
			||||||
 | 
						return pkgHandle.DevlinkGetDeviceParams(bus, device)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkGetDeviceParamByName returns specific parameter for devlink device
 | 
				
			||||||
 | 
					// Equivalent to: `devlink dev param show <bus>/<device> name <param>`
 | 
				
			||||||
 | 
					func (h *Handle) DevlinkGetDeviceParamByName(bus string, device string, param string) (*DevlinkParam, error) {
 | 
				
			||||||
 | 
						_, req, err := h.createCmdReq(nl.DEVLINK_CMD_PARAM_GET, bus, device)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PARAM_NAME, nl.ZeroTerminated(param)))
 | 
				
			||||||
 | 
						respmsg, err := req.Execute(unix.NETLINK_GENERIC, 0)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(respmsg) == 0 {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("unexpected response")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						attrs, err := nl.ParseRouteAttr(respmsg[0][nl.SizeofGenlmsg:])
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						p := &DevlinkParam{}
 | 
				
			||||||
 | 
						if err := p.parseAttributes(attrs); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return p, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkGetDeviceParamByName returns specific parameter for devlink device
 | 
				
			||||||
 | 
					// Equivalent to: `devlink dev param show <bus>/<device> name <param>`
 | 
				
			||||||
 | 
					func DevlinkGetDeviceParamByName(bus string, device string, param string) (*DevlinkParam, error) {
 | 
				
			||||||
 | 
						return pkgHandle.DevlinkGetDeviceParamByName(bus, device, param)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkSetDeviceParam set specific parameter for devlink device
 | 
				
			||||||
 | 
					// Equivalent to: `devlink dev param set <bus>/<device> name <param> cmode <cmode> value <value>`
 | 
				
			||||||
 | 
					// cmode argument should contain valid cmode value as uint8, modes are define in nl.DEVLINK_PARAM_CMODE_* constants
 | 
				
			||||||
 | 
					// value argument should have one of the following types: uint8, uint16, uint32, string, bool
 | 
				
			||||||
 | 
					func (h *Handle) DevlinkSetDeviceParam(bus string, device string, param string, cmode uint8, value interface{}) error {
 | 
				
			||||||
 | 
						// retrive the param type
 | 
				
			||||||
 | 
						p, err := h.DevlinkGetDeviceParamByName(bus, device, param)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("failed to get device param: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						paramType := p.Type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, req, err := h.createCmdReq(nl.DEVLINK_CMD_PARAM_SET, bus, device)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PARAM_TYPE, nl.Uint8Attr(paramType)))
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PARAM_NAME, nl.ZeroTerminated(param)))
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PARAM_VALUE_CMODE, nl.Uint8Attr(cmode)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var valueAsBytes []byte
 | 
				
			||||||
 | 
						switch paramType {
 | 
				
			||||||
 | 
						case nl.DEVLINK_PARAM_TYPE_U8:
 | 
				
			||||||
 | 
							v, ok := value.(uint8)
 | 
				
			||||||
 | 
							if !ok {
 | 
				
			||||||
 | 
								return fmt.Errorf("unepected value type required: uint8, actual: %T", value)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							valueAsBytes = nl.Uint8Attr(v)
 | 
				
			||||||
 | 
						case nl.DEVLINK_PARAM_TYPE_U16:
 | 
				
			||||||
 | 
							v, ok := value.(uint16)
 | 
				
			||||||
 | 
							if !ok {
 | 
				
			||||||
 | 
								return fmt.Errorf("unepected value type required: uint16, actual: %T", value)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							valueAsBytes = nl.Uint16Attr(v)
 | 
				
			||||||
 | 
						case nl.DEVLINK_PARAM_TYPE_U32:
 | 
				
			||||||
 | 
							v, ok := value.(uint32)
 | 
				
			||||||
 | 
							if !ok {
 | 
				
			||||||
 | 
								return fmt.Errorf("unepected value type required: uint32, actual: %T", value)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							valueAsBytes = nl.Uint32Attr(v)
 | 
				
			||||||
 | 
						case nl.DEVLINK_PARAM_TYPE_STRING:
 | 
				
			||||||
 | 
							v, ok := value.(string)
 | 
				
			||||||
 | 
							if !ok {
 | 
				
			||||||
 | 
								return fmt.Errorf("unepected value type required: string, actual: %T", value)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							valueAsBytes = nl.ZeroTerminated(v)
 | 
				
			||||||
 | 
						case nl.DEVLINK_PARAM_TYPE_BOOL:
 | 
				
			||||||
 | 
							v, ok := value.(bool)
 | 
				
			||||||
 | 
							if !ok {
 | 
				
			||||||
 | 
								return fmt.Errorf("unepected value type required: bool, actual: %T", value)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if v {
 | 
				
			||||||
 | 
								valueAsBytes = []byte{}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return fmt.Errorf("unsupported parameter type: %d", paramType)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if valueAsBytes != nil {
 | 
				
			||||||
 | 
							req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PARAM_VALUE_DATA, valueAsBytes))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, err = req.Execute(unix.NETLINK_GENERIC, 0)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkSetDeviceParam set specific parameter for devlink device
 | 
				
			||||||
 | 
					// Equivalent to: `devlink dev param set <bus>/<device> name <param> cmode <cmode> value <value>`
 | 
				
			||||||
 | 
					// cmode argument should contain valid cmode value as uint8, modes are define in nl.DEVLINK_PARAM_CMODE_* constants
 | 
				
			||||||
 | 
					// value argument should have one of the following types: uint8, uint16, uint32, string, bool
 | 
				
			||||||
 | 
					func DevlinkSetDeviceParam(bus string, device string, param string, cmode uint8, value interface{}) error {
 | 
				
			||||||
 | 
						return pkgHandle.DevlinkSetDeviceParam(bus, device, param, cmode, value)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevLinkGetPortByIndex provides a pointer to devlink portand nil error,
 | 
				
			||||||
 | 
					// otherwise returns an error code.
 | 
				
			||||||
 | 
					func DevLinkGetPortByIndex(Bus string, Device string, PortIndex uint32) (*DevlinkPort, error) {
 | 
				
			||||||
 | 
						return pkgHandle.DevLinkGetPortByIndex(Bus, Device, PortIndex)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevLinkPortAdd adds a devlink port and returns a port on success
 | 
				
			||||||
 | 
					// otherwise returns nil port and an error code.
 | 
				
			||||||
 | 
					func (h *Handle) DevLinkPortAdd(Bus string, Device string, Flavour uint16, Attrs DevLinkPortAddAttrs) (*DevlinkPort, error) {
 | 
				
			||||||
 | 
						_, req, err := h.createCmdReq(nl.DEVLINK_CMD_PORT_NEW, Bus, Device)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_FLAVOUR, nl.Uint16Attr(Flavour)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_PCI_PF_NUMBER, nl.Uint16Attr(Attrs.PfNumber)))
 | 
				
			||||||
 | 
						if Flavour == nl.DEVLINK_PORT_FLAVOUR_PCI_SF && Attrs.SfNumberValid {
 | 
				
			||||||
 | 
							req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_PCI_SF_NUMBER, nl.Uint32Attr(Attrs.SfNumber)))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if Attrs.PortIndexValid {
 | 
				
			||||||
 | 
							req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_INDEX, nl.Uint32Attr(Attrs.PortIndex)))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if Attrs.ControllerValid {
 | 
				
			||||||
 | 
							req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_CONTROLLER_NUMBER, nl.Uint32Attr(Attrs.Controller)))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						respmsg, err := req.Execute(unix.NETLINK_GENERIC, 0)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						port, err := parseDevlinkPortMsg(respmsg)
 | 
				
			||||||
 | 
						return port, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevLinkPortAdd adds a devlink port and returns a port on success
 | 
				
			||||||
 | 
					// otherwise returns nil port and an error code.
 | 
				
			||||||
 | 
					func DevLinkPortAdd(Bus string, Device string, Flavour uint16, Attrs DevLinkPortAddAttrs) (*DevlinkPort, error) {
 | 
				
			||||||
 | 
						return pkgHandle.DevLinkPortAdd(Bus, Device, Flavour, Attrs)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevLinkPortDel deletes a devlink port and returns success or error code.
 | 
				
			||||||
 | 
					func (h *Handle) DevLinkPortDel(Bus string, Device string, PortIndex uint32) error {
 | 
				
			||||||
 | 
						_, req, err := h.createCmdReq(nl.DEVLINK_CMD_PORT_DEL, Bus, Device)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_INDEX, nl.Uint32Attr(PortIndex)))
 | 
				
			||||||
 | 
						_, err = req.Execute(unix.NETLINK_GENERIC, 0)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevLinkPortDel deletes a devlink port and returns success or error code.
 | 
				
			||||||
 | 
					func DevLinkPortDel(Bus string, Device string, PortIndex uint32) error {
 | 
				
			||||||
 | 
						return pkgHandle.DevLinkPortDel(Bus, Device, PortIndex)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkPortFnSet sets one or more port function attributes specified by the attribute mask.
 | 
				
			||||||
 | 
					// It returns 0 on success or error code.
 | 
				
			||||||
 | 
					func (h *Handle) DevlinkPortFnSet(Bus string, Device string, PortIndex uint32, FnAttrs DevlinkPortFnSetAttrs) error {
 | 
				
			||||||
 | 
						_, req, err := h.createCmdReq(nl.DEVLINK_CMD_PORT_SET, Bus, Device)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_INDEX, nl.Uint32Attr(PortIndex)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fnAttr := nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_FUNCTION|unix.NLA_F_NESTED, nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if FnAttrs.HwAddrValid {
 | 
				
			||||||
 | 
							fnAttr.AddRtAttr(nl.DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, []byte(FnAttrs.FnAttrs.HwAddr))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if FnAttrs.StateValid {
 | 
				
			||||||
 | 
							fnAttr.AddRtAttr(nl.DEVLINK_PORT_FN_ATTR_STATE, nl.Uint8Attr(FnAttrs.FnAttrs.State))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						req.AddData(fnAttr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err = req.Execute(unix.NETLINK_GENERIC, 0)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkPortFnSet sets one or more port function attributes specified by the attribute mask.
 | 
				
			||||||
 | 
					// It returns 0 on success or error code.
 | 
				
			||||||
 | 
					func DevlinkPortFnSet(Bus string, Device string, PortIndex uint32, FnAttrs DevlinkPortFnSetAttrs) error {
 | 
				
			||||||
 | 
						return pkgHandle.DevlinkPortFnSet(Bus, Device, PortIndex, FnAttrs)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// devlinkInfoGetter is function that is responsible for getting devlink info message
 | 
				
			||||||
 | 
					// this is introduced for test purpose
 | 
				
			||||||
 | 
					type devlinkInfoGetter func(bus, device string) ([]byte, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkGetDeviceInfoByName returns devlink info for selected device,
 | 
				
			||||||
 | 
					// otherwise returns an error code.
 | 
				
			||||||
 | 
					// Equivalent to: `devlink dev info $dev`
 | 
				
			||||||
 | 
					func (h *Handle) DevlinkGetDeviceInfoByName(Bus string, Device string, getInfoMsg devlinkInfoGetter) (*DevlinkDeviceInfo, error) {
 | 
				
			||||||
 | 
						info, err := h.DevlinkGetDeviceInfoByNameAsMap(Bus, Device, getInfoMsg)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return parseInfoData(info), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkGetDeviceInfoByName returns devlink info for selected device,
 | 
				
			||||||
 | 
					// otherwise returns an error code.
 | 
				
			||||||
 | 
					// Equivalent to: `devlink dev info $dev`
 | 
				
			||||||
 | 
					func DevlinkGetDeviceInfoByName(Bus string, Device string) (*DevlinkDeviceInfo, error) {
 | 
				
			||||||
 | 
						return pkgHandle.DevlinkGetDeviceInfoByName(Bus, Device, pkgHandle.getDevlinkInfoMsg)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkGetDeviceInfoByNameAsMap returns devlink info for selected device as a map,
 | 
				
			||||||
 | 
					// otherwise returns an error code.
 | 
				
			||||||
 | 
					// Equivalent to: `devlink dev info $dev`
 | 
				
			||||||
 | 
					func (h *Handle) DevlinkGetDeviceInfoByNameAsMap(Bus string, Device string, getInfoMsg devlinkInfoGetter) (map[string]string, error) {
 | 
				
			||||||
 | 
						response, err := getInfoMsg(Bus, Device)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						info, err := parseInfoMsg(response)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return info, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DevlinkGetDeviceInfoByNameAsMap returns devlink info for selected device as a map,
 | 
				
			||||||
 | 
					// otherwise returns an error code.
 | 
				
			||||||
 | 
					// Equivalent to: `devlink dev info $dev`
 | 
				
			||||||
 | 
					func DevlinkGetDeviceInfoByNameAsMap(Bus string, Device string) (map[string]string, error) {
 | 
				
			||||||
 | 
						return pkgHandle.DevlinkGetDeviceInfoByNameAsMap(Bus, Device, pkgHandle.getDevlinkInfoMsg)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetDevlinkInfo returns devlink info for target device,
 | 
				
			||||||
 | 
					// otherwise returns an error code.
 | 
				
			||||||
 | 
					func (d *DevlinkDevice) GetDevlinkInfo() (*DevlinkDeviceInfo, error) {
 | 
				
			||||||
 | 
						return pkgHandle.DevlinkGetDeviceInfoByName(d.BusName, d.DeviceName, pkgHandle.getDevlinkInfoMsg)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetDevlinkInfoAsMap returns devlink info for target device as a map,
 | 
				
			||||||
 | 
					// otherwise returns an error code.
 | 
				
			||||||
 | 
					func (d *DevlinkDevice) GetDevlinkInfoAsMap() (map[string]string, error) {
 | 
				
			||||||
 | 
						return pkgHandle.DevlinkGetDeviceInfoByNameAsMap(d.BusName, d.DeviceName, pkgHandle.getDevlinkInfoMsg)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) getDevlinkInfoMsg(bus, device string) ([]byte, error) {
 | 
				
			||||||
 | 
						_, req, err := h.createCmdReq(nl.DEVLINK_CMD_INFO_GET, bus, device)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						response, err := req.Execute(unix.NETLINK_GENERIC, 0)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(response) < 1 {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("getDevlinkInfoMsg: message too short")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return response[0], nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseInfoMsg(msg []byte) (map[string]string, error) {
 | 
				
			||||||
 | 
						if len(msg) < nl.SizeofGenlmsg {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("parseInfoMsg: message too short")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						info := make(map[string]string)
 | 
				
			||||||
 | 
						err := collectInfoData(msg[nl.SizeofGenlmsg:], info)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return info, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func collectInfoData(msg []byte, data map[string]string) error {
 | 
				
			||||||
 | 
						attrs, err := nl.ParseRouteAttr(msg)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, attr := range attrs {
 | 
				
			||||||
 | 
							switch attr.Attr.Type {
 | 
				
			||||||
 | 
							case nl.DEVLINK_ATTR_INFO_DRIVER_NAME:
 | 
				
			||||||
 | 
								data["driver"] = parseInfoValue(attr.Value)
 | 
				
			||||||
 | 
							case nl.DEVLINK_ATTR_INFO_SERIAL_NUMBER:
 | 
				
			||||||
 | 
								data["serialNumber"] = parseInfoValue(attr.Value)
 | 
				
			||||||
 | 
							case nl.DEVLINK_ATTR_INFO_VERSION_RUNNING, nl.DEVLINK_ATTR_INFO_VERSION_FIXED,
 | 
				
			||||||
 | 
								nl.DEVLINK_ATTR_INFO_VERSION_STORED:
 | 
				
			||||||
 | 
								key, value, err := getNestedInfoData(attr.Value)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								data[key] = value
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(data) == 0 {
 | 
				
			||||||
 | 
							return fmt.Errorf("collectInfoData: could not read attributes")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getNestedInfoData(msg []byte) (string, string, error) {
 | 
				
			||||||
 | 
						nestedAttrs, err := nl.ParseRouteAttr(msg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var key, value string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(nestedAttrs) != 2 {
 | 
				
			||||||
 | 
							return "", "", fmt.Errorf("getNestedInfoData: too few attributes in nested structure")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, nestedAttr := range nestedAttrs {
 | 
				
			||||||
 | 
							switch nestedAttr.Attr.Type {
 | 
				
			||||||
 | 
							case nl.DEVLINK_ATTR_INFO_VERSION_NAME:
 | 
				
			||||||
 | 
								key = parseInfoValue(nestedAttr.Value)
 | 
				
			||||||
 | 
							case nl.DEVLINK_ATTR_INFO_VERSION_VALUE:
 | 
				
			||||||
 | 
								value = parseInfoValue(nestedAttr.Value)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if key == "" {
 | 
				
			||||||
 | 
							return "", "", fmt.Errorf("getNestedInfoData: key not found")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if value == "" {
 | 
				
			||||||
 | 
							return "", "", fmt.Errorf("getNestedInfoData: value not found")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return key, value, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseInfoData(data map[string]string) *DevlinkDeviceInfo {
 | 
				
			||||||
 | 
						info := new(DevlinkDeviceInfo)
 | 
				
			||||||
 | 
						for key, value := range data {
 | 
				
			||||||
 | 
							switch key {
 | 
				
			||||||
 | 
							case "driver":
 | 
				
			||||||
 | 
								info.Driver = value
 | 
				
			||||||
 | 
							case "serialNumber":
 | 
				
			||||||
 | 
								info.SerialNumber = value
 | 
				
			||||||
 | 
							case "board.id":
 | 
				
			||||||
 | 
								info.BoardID = value
 | 
				
			||||||
 | 
							case "fw.app":
 | 
				
			||||||
 | 
								info.FwApp = value
 | 
				
			||||||
 | 
							case "fw.app.bundle_id":
 | 
				
			||||||
 | 
								info.FwAppBoundleID = value
 | 
				
			||||||
 | 
							case "fw.app.name":
 | 
				
			||||||
 | 
								info.FwAppName = value
 | 
				
			||||||
 | 
							case "fw.bundle_id":
 | 
				
			||||||
 | 
								info.FwBoundleID = value
 | 
				
			||||||
 | 
							case "fw.mgmt":
 | 
				
			||||||
 | 
								info.FwMgmt = value
 | 
				
			||||||
 | 
							case "fw.mgmt.api":
 | 
				
			||||||
 | 
								info.FwMgmtAPI = value
 | 
				
			||||||
 | 
							case "fw.mgmt.build":
 | 
				
			||||||
 | 
								info.FwMgmtBuild = value
 | 
				
			||||||
 | 
							case "fw.netlist":
 | 
				
			||||||
 | 
								info.FwNetlist = value
 | 
				
			||||||
 | 
							case "fw.netlist.build":
 | 
				
			||||||
 | 
								info.FwNetlistBuild = value
 | 
				
			||||||
 | 
							case "fw.psid.api":
 | 
				
			||||||
 | 
								info.FwPsidAPI = value
 | 
				
			||||||
 | 
							case "fw.undi":
 | 
				
			||||||
 | 
								info.FwUndi = value
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return info
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseInfoValue(value []byte) string {
 | 
				
			||||||
 | 
						v := strings.ReplaceAll(string(value), "\x00", "")
 | 
				
			||||||
 | 
						return strings.TrimSpace(v)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										160
									
								
								vendor/github.com/vishvananda/netlink/filter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										160
									
								
								vendor/github.com/vishvananda/netlink/filter.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -19,6 +19,7 @@ type FilterAttrs struct {
 | 
				
			|||||||
	Parent    uint32
 | 
						Parent    uint32
 | 
				
			||||||
	Priority  uint16 // lower is higher priority
 | 
						Priority  uint16 // lower is higher priority
 | 
				
			||||||
	Protocol  uint16 // unix.ETH_P_*
 | 
						Protocol  uint16 // unix.ETH_P_*
 | 
				
			||||||
 | 
						Chain     *uint32
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (q FilterAttrs) String() string {
 | 
					func (q FilterAttrs) String() string {
 | 
				
			||||||
@@ -27,6 +28,11 @@ func (q FilterAttrs) String() string {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type TcAct int32
 | 
					type TcAct int32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						TC_ACT_EXT_SHIFT    = 28
 | 
				
			||||||
 | 
						TC_ACT_EXT_VAL_MASK = (1 << TC_ACT_EXT_SHIFT) - 1
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	TC_ACT_UNSPEC     TcAct = -1
 | 
						TC_ACT_UNSPEC     TcAct = -1
 | 
				
			||||||
	TC_ACT_OK         TcAct = 0
 | 
						TC_ACT_OK         TcAct = 0
 | 
				
			||||||
@@ -40,6 +46,22 @@ const (
 | 
				
			|||||||
	TC_ACT_JUMP       TcAct = 0x10000000
 | 
						TC_ACT_JUMP       TcAct = 0x10000000
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getTcActExt(local int32) int32 {
 | 
				
			||||||
 | 
						return local << TC_ACT_EXT_SHIFT
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getTcActGotoChain() TcAct {
 | 
				
			||||||
 | 
						return TcAct(getTcActExt(2))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getTcActExtOpcode(combined int32) int32 {
 | 
				
			||||||
 | 
						return combined & (^TC_ACT_EXT_VAL_MASK)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TcActExtCmp(combined int32, opcode int32) bool {
 | 
				
			||||||
 | 
						return getTcActExtOpcode(combined) == opcode
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (a TcAct) String() string {
 | 
					func (a TcAct) String() string {
 | 
				
			||||||
	switch a {
 | 
						switch a {
 | 
				
			||||||
	case TC_ACT_UNSPEC:
 | 
						case TC_ACT_UNSPEC:
 | 
				
			||||||
@@ -63,6 +85,9 @@ func (a TcAct) String() string {
 | 
				
			|||||||
	case TC_ACT_JUMP:
 | 
						case TC_ACT_JUMP:
 | 
				
			||||||
		return "jump"
 | 
							return "jump"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if TcActExtCmp(int32(a), int32(getTcActGotoChain())) {
 | 
				
			||||||
 | 
							return "goto"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return fmt.Sprintf("0x%x", int32(a))
 | 
						return fmt.Sprintf("0x%x", int32(a))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -98,12 +123,27 @@ type ActionAttrs struct {
 | 
				
			|||||||
	Action     TcAct
 | 
						Action     TcAct
 | 
				
			||||||
	Refcnt     int
 | 
						Refcnt     int
 | 
				
			||||||
	Bindcnt    int
 | 
						Bindcnt    int
 | 
				
			||||||
 | 
						Statistics *ActionStatistic
 | 
				
			||||||
 | 
						Timestamp  *ActionTimestamp
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (q ActionAttrs) String() string {
 | 
					func (q ActionAttrs) String() string {
 | 
				
			||||||
	return fmt.Sprintf("{Index: %d, Capab: %x, Action: %s, Refcnt: %d, Bindcnt: %d}", q.Index, q.Capab, q.Action.String(), q.Refcnt, q.Bindcnt)
 | 
						return fmt.Sprintf("{Index: %d, Capab: %x, Action: %s, Refcnt: %d, Bindcnt: %d}", q.Index, q.Capab, q.Action.String(), q.Refcnt, q.Bindcnt)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ActionTimestamp struct {
 | 
				
			||||||
 | 
						Installed uint64
 | 
				
			||||||
 | 
						LastUsed  uint64
 | 
				
			||||||
 | 
						Expires   uint64
 | 
				
			||||||
 | 
						FirstUsed uint64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (t ActionTimestamp) String() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("Installed %d LastUsed %d Expires %d FirstUsed %d", t.Installed, t.LastUsed, t.Expires, t.FirstUsed)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ActionStatistic ClassStatistics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Action represents an action in any supported filter.
 | 
					// Action represents an action in any supported filter.
 | 
				
			||||||
type Action interface {
 | 
					type Action interface {
 | 
				
			||||||
	Attrs() *ActionAttrs
 | 
						Attrs() *ActionAttrs
 | 
				
			||||||
@@ -112,6 +152,7 @@ type Action interface {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type GenericAction struct {
 | 
					type GenericAction struct {
 | 
				
			||||||
	ActionAttrs
 | 
						ActionAttrs
 | 
				
			||||||
 | 
						Chain int32
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (action *GenericAction) Type() string {
 | 
					func (action *GenericAction) Type() string {
 | 
				
			||||||
@@ -157,6 +198,39 @@ func NewConnmarkAction() *ConnmarkAction {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CsumUpdateFlags uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						TCA_CSUM_UPDATE_FLAG_IPV4HDR CsumUpdateFlags = 1
 | 
				
			||||||
 | 
						TCA_CSUM_UPDATE_FLAG_ICMP    CsumUpdateFlags = 2
 | 
				
			||||||
 | 
						TCA_CSUM_UPDATE_FLAG_IGMP    CsumUpdateFlags = 4
 | 
				
			||||||
 | 
						TCA_CSUM_UPDATE_FLAG_TCP     CsumUpdateFlags = 8
 | 
				
			||||||
 | 
						TCA_CSUM_UPDATE_FLAG_UDP     CsumUpdateFlags = 16
 | 
				
			||||||
 | 
						TCA_CSUM_UPDATE_FLAG_UDPLITE CsumUpdateFlags = 32
 | 
				
			||||||
 | 
						TCA_CSUM_UPDATE_FLAG_SCTP    CsumUpdateFlags = 64
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CsumAction struct {
 | 
				
			||||||
 | 
						ActionAttrs
 | 
				
			||||||
 | 
						UpdateFlags CsumUpdateFlags
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (action *CsumAction) Type() string {
 | 
				
			||||||
 | 
						return "csum"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (action *CsumAction) Attrs() *ActionAttrs {
 | 
				
			||||||
 | 
						return &action.ActionAttrs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewCsumAction() *CsumAction {
 | 
				
			||||||
 | 
						return &CsumAction{
 | 
				
			||||||
 | 
							ActionAttrs: ActionAttrs{
 | 
				
			||||||
 | 
								Action: TC_ACT_PIPE,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type MirredAct uint8
 | 
					type MirredAct uint8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (a MirredAct) String() string {
 | 
					func (a MirredAct) String() string {
 | 
				
			||||||
@@ -217,6 +291,7 @@ type TunnelKeyAction struct {
 | 
				
			|||||||
	SrcAddr  net.IP
 | 
						SrcAddr  net.IP
 | 
				
			||||||
	DstAddr  net.IP
 | 
						DstAddr  net.IP
 | 
				
			||||||
	KeyID    uint32
 | 
						KeyID    uint32
 | 
				
			||||||
 | 
						DestPort uint16
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (action *TunnelKeyAction) Type() string {
 | 
					func (action *TunnelKeyAction) Type() string {
 | 
				
			||||||
@@ -241,6 +316,7 @@ type SkbEditAction struct {
 | 
				
			|||||||
	PType        *uint16
 | 
						PType        *uint16
 | 
				
			||||||
	Priority     *uint32
 | 
						Priority     *uint32
 | 
				
			||||||
	Mark         *uint32
 | 
						Mark         *uint32
 | 
				
			||||||
 | 
						Mask         *uint32
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (action *SkbEditAction) Type() string {
 | 
					func (action *SkbEditAction) Type() string {
 | 
				
			||||||
@@ -259,6 +335,40 @@ func NewSkbEditAction() *SkbEditAction {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type PoliceAction struct {
 | 
				
			||||||
 | 
						ActionAttrs
 | 
				
			||||||
 | 
						Rate            uint32 // in byte per second
 | 
				
			||||||
 | 
						Burst           uint32 // in byte
 | 
				
			||||||
 | 
						RCellLog        int
 | 
				
			||||||
 | 
						Mtu             uint32
 | 
				
			||||||
 | 
						Mpu             uint16 // in byte
 | 
				
			||||||
 | 
						PeakRate        uint32 // in byte per second
 | 
				
			||||||
 | 
						PCellLog        int
 | 
				
			||||||
 | 
						AvRate          uint32 // in byte per second
 | 
				
			||||||
 | 
						Overhead        uint16
 | 
				
			||||||
 | 
						LinkLayer       int
 | 
				
			||||||
 | 
						ExceedAction    TcPolAct
 | 
				
			||||||
 | 
						NotExceedAction TcPolAct
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (action *PoliceAction) Type() string {
 | 
				
			||||||
 | 
						return "police"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (action *PoliceAction) Attrs() *ActionAttrs {
 | 
				
			||||||
 | 
						return &action.ActionAttrs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewPoliceAction() *PoliceAction {
 | 
				
			||||||
 | 
						return &PoliceAction{
 | 
				
			||||||
 | 
							RCellLog:        -1,
 | 
				
			||||||
 | 
							PCellLog:        -1,
 | 
				
			||||||
 | 
							LinkLayer:       1, // ETHERNET
 | 
				
			||||||
 | 
							ExceedAction:    TC_POLICE_RECLASSIFY,
 | 
				
			||||||
 | 
							NotExceedAction: TC_POLICE_OK,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MatchAll filters match all packets
 | 
					// MatchAll filters match all packets
 | 
				
			||||||
type MatchAll struct {
 | 
					type MatchAll struct {
 | 
				
			||||||
	FilterAttrs
 | 
						FilterAttrs
 | 
				
			||||||
@@ -274,20 +384,21 @@ func (filter *MatchAll) Type() string {
 | 
				
			|||||||
	return "matchall"
 | 
						return "matchall"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type FilterFwAttrs struct {
 | 
					type FwFilter struct {
 | 
				
			||||||
 | 
						FilterAttrs
 | 
				
			||||||
	ClassId uint32
 | 
						ClassId uint32
 | 
				
			||||||
	InDev   string
 | 
						InDev   string
 | 
				
			||||||
	Mask    uint32
 | 
						Mask    uint32
 | 
				
			||||||
	Index     uint32
 | 
						Police  *PoliceAction
 | 
				
			||||||
	Buffer    uint32
 | 
						Actions []Action
 | 
				
			||||||
	Mtu       uint32
 | 
					}
 | 
				
			||||||
	Mpu       uint16
 | 
					
 | 
				
			||||||
	Rate      uint32
 | 
					func (filter *FwFilter) Attrs() *FilterAttrs {
 | 
				
			||||||
	AvRate    uint32
 | 
						return &filter.FilterAttrs
 | 
				
			||||||
	PeakRate  uint32
 | 
					}
 | 
				
			||||||
	Action    TcPolAct
 | 
					
 | 
				
			||||||
	Overhead  uint16
 | 
					func (filter *FwFilter) Type() string {
 | 
				
			||||||
	LinkLayer int
 | 
						return "fw"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type BpfFilter struct {
 | 
					type BpfFilter struct {
 | 
				
			||||||
@@ -322,3 +433,30 @@ func (filter *GenericFilter) Attrs() *FilterAttrs {
 | 
				
			|||||||
func (filter *GenericFilter) Type() string {
 | 
					func (filter *GenericFilter) Type() string {
 | 
				
			||||||
	return filter.FilterType
 | 
						return filter.FilterType
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type PeditAction struct {
 | 
				
			||||||
 | 
						ActionAttrs
 | 
				
			||||||
 | 
						Proto      uint8
 | 
				
			||||||
 | 
						SrcMacAddr net.HardwareAddr
 | 
				
			||||||
 | 
						DstMacAddr net.HardwareAddr
 | 
				
			||||||
 | 
						SrcIP      net.IP
 | 
				
			||||||
 | 
						DstIP      net.IP
 | 
				
			||||||
 | 
						SrcPort    uint16
 | 
				
			||||||
 | 
						DstPort    uint16
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (p *PeditAction) Attrs() *ActionAttrs {
 | 
				
			||||||
 | 
						return &p.ActionAttrs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (p *PeditAction) Type() string {
 | 
				
			||||||
 | 
						return "pedit"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewPeditAction() *PeditAction {
 | 
				
			||||||
 | 
						return &PeditAction{
 | 
				
			||||||
 | 
							ActionAttrs: ActionAttrs{
 | 
				
			||||||
 | 
								Action: TC_ACT_PIPE,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										545
									
								
								vendor/github.com/vishvananda/netlink/filter_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										545
									
								
								vendor/github.com/vishvananda/netlink/filter_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -37,9 +37,11 @@ type U32 struct {
 | 
				
			|||||||
	ClassId    uint32
 | 
						ClassId    uint32
 | 
				
			||||||
	Divisor    uint32 // Divisor MUST be power of 2.
 | 
						Divisor    uint32 // Divisor MUST be power of 2.
 | 
				
			||||||
	Hash       uint32
 | 
						Hash       uint32
 | 
				
			||||||
 | 
						Link       uint32
 | 
				
			||||||
	RedirIndex int
 | 
						RedirIndex int
 | 
				
			||||||
	Sel        *TcU32Sel
 | 
						Sel        *TcU32Sel
 | 
				
			||||||
	Actions    []Action
 | 
						Actions    []Action
 | 
				
			||||||
 | 
						Police     *PoliceAction
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (filter *U32) Attrs() *FilterAttrs {
 | 
					func (filter *U32) Attrs() *FilterAttrs {
 | 
				
			||||||
@@ -50,74 +52,185 @@ func (filter *U32) Type() string {
 | 
				
			|||||||
	return "u32"
 | 
						return "u32"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Fw filter filters on firewall marks
 | 
					type Flower struct {
 | 
				
			||||||
// NOTE: this is in filter_linux because it refers to nl.TcPolice which
 | 
					 | 
				
			||||||
//       is defined in nl/tc_linux.go
 | 
					 | 
				
			||||||
type Fw struct {
 | 
					 | 
				
			||||||
	FilterAttrs
 | 
						FilterAttrs
 | 
				
			||||||
	ClassId uint32
 | 
						DestIP        net.IP
 | 
				
			||||||
	// TODO remove nl type from interface
 | 
						DestIPMask    net.IPMask
 | 
				
			||||||
	Police nl.TcPolice
 | 
						SrcIP         net.IP
 | 
				
			||||||
	InDev  string
 | 
						SrcIPMask     net.IPMask
 | 
				
			||||||
	// TODO Action
 | 
						EthType       uint16
 | 
				
			||||||
	Mask   uint32
 | 
						EncDestIP     net.IP
 | 
				
			||||||
	AvRate uint32
 | 
						EncDestIPMask net.IPMask
 | 
				
			||||||
	Rtab   [256]uint32
 | 
						EncSrcIP      net.IP
 | 
				
			||||||
	Ptab   [256]uint32
 | 
						EncSrcIPMask  net.IPMask
 | 
				
			||||||
 | 
						EncDestPort   uint16
 | 
				
			||||||
 | 
						EncKeyId      uint32
 | 
				
			||||||
 | 
						SkipHw        bool
 | 
				
			||||||
 | 
						SkipSw        bool
 | 
				
			||||||
 | 
						IPProto       *nl.IPProto
 | 
				
			||||||
 | 
						DestPort      uint16
 | 
				
			||||||
 | 
						SrcPort       uint16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Actions []Action
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewFw(attrs FilterAttrs, fattrs FilterFwAttrs) (*Fw, error) {
 | 
					func (filter *Flower) Attrs() *FilterAttrs {
 | 
				
			||||||
	var rtab [256]uint32
 | 
					 | 
				
			||||||
	var ptab [256]uint32
 | 
					 | 
				
			||||||
	rcellLog := -1
 | 
					 | 
				
			||||||
	pcellLog := -1
 | 
					 | 
				
			||||||
	avrate := fattrs.AvRate / 8
 | 
					 | 
				
			||||||
	police := nl.TcPolice{}
 | 
					 | 
				
			||||||
	police.Rate.Rate = fattrs.Rate / 8
 | 
					 | 
				
			||||||
	police.PeakRate.Rate = fattrs.PeakRate / 8
 | 
					 | 
				
			||||||
	buffer := fattrs.Buffer
 | 
					 | 
				
			||||||
	linklayer := nl.LINKLAYER_ETHERNET
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if fattrs.LinkLayer != nl.LINKLAYER_UNSPEC {
 | 
					 | 
				
			||||||
		linklayer = fattrs.LinkLayer
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	police.Action = int32(fattrs.Action)
 | 
					 | 
				
			||||||
	if police.Rate.Rate != 0 {
 | 
					 | 
				
			||||||
		police.Rate.Mpu = fattrs.Mpu
 | 
					 | 
				
			||||||
		police.Rate.Overhead = fattrs.Overhead
 | 
					 | 
				
			||||||
		if CalcRtable(&police.Rate, rtab[:], rcellLog, fattrs.Mtu, linklayer) < 0 {
 | 
					 | 
				
			||||||
			return nil, errors.New("TBF: failed to calculate rate table")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		police.Burst = uint32(Xmittime(uint64(police.Rate.Rate), uint32(buffer)))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	police.Mtu = fattrs.Mtu
 | 
					 | 
				
			||||||
	if police.PeakRate.Rate != 0 {
 | 
					 | 
				
			||||||
		police.PeakRate.Mpu = fattrs.Mpu
 | 
					 | 
				
			||||||
		police.PeakRate.Overhead = fattrs.Overhead
 | 
					 | 
				
			||||||
		if CalcRtable(&police.PeakRate, ptab[:], pcellLog, fattrs.Mtu, linklayer) < 0 {
 | 
					 | 
				
			||||||
			return nil, errors.New("POLICE: failed to calculate peak rate table")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &Fw{
 | 
					 | 
				
			||||||
		FilterAttrs: attrs,
 | 
					 | 
				
			||||||
		ClassId:     fattrs.ClassId,
 | 
					 | 
				
			||||||
		InDev:       fattrs.InDev,
 | 
					 | 
				
			||||||
		Mask:        fattrs.Mask,
 | 
					 | 
				
			||||||
		Police:      police,
 | 
					 | 
				
			||||||
		AvRate:      avrate,
 | 
					 | 
				
			||||||
		Rtab:        rtab,
 | 
					 | 
				
			||||||
		Ptab:        ptab,
 | 
					 | 
				
			||||||
	}, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (filter *Fw) Attrs() *FilterAttrs {
 | 
					 | 
				
			||||||
	return &filter.FilterAttrs
 | 
						return &filter.FilterAttrs
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (filter *Fw) Type() string {
 | 
					func (filter *Flower) Type() string {
 | 
				
			||||||
	return "fw"
 | 
						return "flower"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (filter *Flower) encodeIP(parent *nl.RtAttr, ip net.IP, mask net.IPMask, v4Type, v6Type int, v4MaskType, v6MaskType int) {
 | 
				
			||||||
 | 
						ipType := v4Type
 | 
				
			||||||
 | 
						maskType := v4MaskType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						encodeMask := mask
 | 
				
			||||||
 | 
						if mask == nil {
 | 
				
			||||||
 | 
							encodeMask = net.CIDRMask(32, 32)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						v4IP := ip.To4()
 | 
				
			||||||
 | 
						if v4IP == nil {
 | 
				
			||||||
 | 
							ipType = v6Type
 | 
				
			||||||
 | 
							maskType = v6MaskType
 | 
				
			||||||
 | 
							if mask == nil {
 | 
				
			||||||
 | 
								encodeMask = net.CIDRMask(128, 128)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							ip = v4IP
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parent.AddRtAttr(ipType, ip)
 | 
				
			||||||
 | 
						parent.AddRtAttr(maskType, encodeMask)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (filter *Flower) encode(parent *nl.RtAttr) error {
 | 
				
			||||||
 | 
						if filter.EthType != 0 {
 | 
				
			||||||
 | 
							parent.AddRtAttr(nl.TCA_FLOWER_KEY_ETH_TYPE, htons(filter.EthType))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if filter.SrcIP != nil {
 | 
				
			||||||
 | 
							filter.encodeIP(parent, filter.SrcIP, filter.SrcIPMask,
 | 
				
			||||||
 | 
								nl.TCA_FLOWER_KEY_IPV4_SRC, nl.TCA_FLOWER_KEY_IPV6_SRC,
 | 
				
			||||||
 | 
								nl.TCA_FLOWER_KEY_IPV4_SRC_MASK, nl.TCA_FLOWER_KEY_IPV6_SRC_MASK)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if filter.DestIP != nil {
 | 
				
			||||||
 | 
							filter.encodeIP(parent, filter.DestIP, filter.DestIPMask,
 | 
				
			||||||
 | 
								nl.TCA_FLOWER_KEY_IPV4_DST, nl.TCA_FLOWER_KEY_IPV6_DST,
 | 
				
			||||||
 | 
								nl.TCA_FLOWER_KEY_IPV4_DST_MASK, nl.TCA_FLOWER_KEY_IPV6_DST_MASK)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if filter.EncSrcIP != nil {
 | 
				
			||||||
 | 
							filter.encodeIP(parent, filter.EncSrcIP, filter.EncSrcIPMask,
 | 
				
			||||||
 | 
								nl.TCA_FLOWER_KEY_ENC_IPV4_SRC, nl.TCA_FLOWER_KEY_ENC_IPV6_SRC,
 | 
				
			||||||
 | 
								nl.TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK, nl.TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if filter.EncDestIP != nil {
 | 
				
			||||||
 | 
							filter.encodeIP(parent, filter.EncDestIP, filter.EncSrcIPMask,
 | 
				
			||||||
 | 
								nl.TCA_FLOWER_KEY_ENC_IPV4_DST, nl.TCA_FLOWER_KEY_ENC_IPV6_DST,
 | 
				
			||||||
 | 
								nl.TCA_FLOWER_KEY_ENC_IPV4_DST_MASK, nl.TCA_FLOWER_KEY_ENC_IPV6_DST_MASK)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if filter.EncDestPort != 0 {
 | 
				
			||||||
 | 
							parent.AddRtAttr(nl.TCA_FLOWER_KEY_ENC_UDP_DST_PORT, htons(filter.EncDestPort))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if filter.EncKeyId != 0 {
 | 
				
			||||||
 | 
							parent.AddRtAttr(nl.TCA_FLOWER_KEY_ENC_KEY_ID, htonl(filter.EncKeyId))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if filter.IPProto != nil {
 | 
				
			||||||
 | 
							ipproto := *filter.IPProto
 | 
				
			||||||
 | 
							parent.AddRtAttr(nl.TCA_FLOWER_KEY_IP_PROTO, ipproto.Serialize())
 | 
				
			||||||
 | 
							if filter.SrcPort != 0 {
 | 
				
			||||||
 | 
								switch ipproto {
 | 
				
			||||||
 | 
								case nl.IPPROTO_TCP:
 | 
				
			||||||
 | 
									parent.AddRtAttr(nl.TCA_FLOWER_KEY_TCP_SRC, htons(filter.SrcPort))
 | 
				
			||||||
 | 
								case nl.IPPROTO_UDP:
 | 
				
			||||||
 | 
									parent.AddRtAttr(nl.TCA_FLOWER_KEY_UDP_SRC, htons(filter.SrcPort))
 | 
				
			||||||
 | 
								case nl.IPPROTO_SCTP:
 | 
				
			||||||
 | 
									parent.AddRtAttr(nl.TCA_FLOWER_KEY_SCTP_SRC, htons(filter.SrcPort))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if filter.DestPort != 0 {
 | 
				
			||||||
 | 
								switch ipproto {
 | 
				
			||||||
 | 
								case nl.IPPROTO_TCP:
 | 
				
			||||||
 | 
									parent.AddRtAttr(nl.TCA_FLOWER_KEY_TCP_DST, htons(filter.DestPort))
 | 
				
			||||||
 | 
								case nl.IPPROTO_UDP:
 | 
				
			||||||
 | 
									parent.AddRtAttr(nl.TCA_FLOWER_KEY_UDP_DST, htons(filter.DestPort))
 | 
				
			||||||
 | 
								case nl.IPPROTO_SCTP:
 | 
				
			||||||
 | 
									parent.AddRtAttr(nl.TCA_FLOWER_KEY_SCTP_DST, htons(filter.DestPort))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var flags uint32 = 0
 | 
				
			||||||
 | 
						if filter.SkipHw {
 | 
				
			||||||
 | 
							flags |= nl.TCA_CLS_FLAGS_SKIP_HW
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if filter.SkipSw {
 | 
				
			||||||
 | 
							flags |= nl.TCA_CLS_FLAGS_SKIP_SW
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						parent.AddRtAttr(nl.TCA_FLOWER_FLAGS, htonl(flags))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						actionsAttr := parent.AddRtAttr(nl.TCA_FLOWER_ACT, nil)
 | 
				
			||||||
 | 
						if err := EncodeActions(actionsAttr, filter.Actions); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (filter *Flower) decode(data []syscall.NetlinkRouteAttr) error {
 | 
				
			||||||
 | 
						for _, datum := range data {
 | 
				
			||||||
 | 
							switch datum.Attr.Type {
 | 
				
			||||||
 | 
							case nl.TCA_FLOWER_KEY_ETH_TYPE:
 | 
				
			||||||
 | 
								filter.EthType = ntohs(datum.Value)
 | 
				
			||||||
 | 
							case nl.TCA_FLOWER_KEY_IPV4_SRC, nl.TCA_FLOWER_KEY_IPV6_SRC:
 | 
				
			||||||
 | 
								filter.SrcIP = datum.Value
 | 
				
			||||||
 | 
							case nl.TCA_FLOWER_KEY_IPV4_SRC_MASK, nl.TCA_FLOWER_KEY_IPV6_SRC_MASK:
 | 
				
			||||||
 | 
								filter.SrcIPMask = datum.Value
 | 
				
			||||||
 | 
							case nl.TCA_FLOWER_KEY_IPV4_DST, nl.TCA_FLOWER_KEY_IPV6_DST:
 | 
				
			||||||
 | 
								filter.DestIP = datum.Value
 | 
				
			||||||
 | 
							case nl.TCA_FLOWER_KEY_IPV4_DST_MASK, nl.TCA_FLOWER_KEY_IPV6_DST_MASK:
 | 
				
			||||||
 | 
								filter.DestIPMask = datum.Value
 | 
				
			||||||
 | 
							case nl.TCA_FLOWER_KEY_ENC_IPV4_SRC, nl.TCA_FLOWER_KEY_ENC_IPV6_SRC:
 | 
				
			||||||
 | 
								filter.EncSrcIP = datum.Value
 | 
				
			||||||
 | 
							case nl.TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK, nl.TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK:
 | 
				
			||||||
 | 
								filter.EncSrcIPMask = datum.Value
 | 
				
			||||||
 | 
							case nl.TCA_FLOWER_KEY_ENC_IPV4_DST, nl.TCA_FLOWER_KEY_ENC_IPV6_DST:
 | 
				
			||||||
 | 
								filter.EncDestIP = datum.Value
 | 
				
			||||||
 | 
							case nl.TCA_FLOWER_KEY_ENC_IPV4_DST_MASK, nl.TCA_FLOWER_KEY_ENC_IPV6_DST_MASK:
 | 
				
			||||||
 | 
								filter.EncDestIPMask = datum.Value
 | 
				
			||||||
 | 
							case nl.TCA_FLOWER_KEY_ENC_UDP_DST_PORT:
 | 
				
			||||||
 | 
								filter.EncDestPort = ntohs(datum.Value)
 | 
				
			||||||
 | 
							case nl.TCA_FLOWER_KEY_ENC_KEY_ID:
 | 
				
			||||||
 | 
								filter.EncKeyId = ntohl(datum.Value)
 | 
				
			||||||
 | 
							case nl.TCA_FLOWER_KEY_IP_PROTO:
 | 
				
			||||||
 | 
								val := new(nl.IPProto)
 | 
				
			||||||
 | 
								*val = nl.IPProto(datum.Value[0])
 | 
				
			||||||
 | 
								filter.IPProto = val
 | 
				
			||||||
 | 
							case nl.TCA_FLOWER_KEY_TCP_SRC, nl.TCA_FLOWER_KEY_UDP_SRC, nl.TCA_FLOWER_KEY_SCTP_SRC:
 | 
				
			||||||
 | 
								filter.SrcPort = ntohs(datum.Value)
 | 
				
			||||||
 | 
							case nl.TCA_FLOWER_KEY_TCP_DST, nl.TCA_FLOWER_KEY_UDP_DST, nl.TCA_FLOWER_KEY_SCTP_DST:
 | 
				
			||||||
 | 
								filter.DestPort = ntohs(datum.Value)
 | 
				
			||||||
 | 
							case nl.TCA_FLOWER_ACT:
 | 
				
			||||||
 | 
								tables, err := nl.ParseRouteAttr(datum.Value)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								filter.Actions, err = parseActions(tables)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							case nl.TCA_FLOWER_FLAGS:
 | 
				
			||||||
 | 
								attr := nl.DeserializeUint32Bitfield(datum.Value)
 | 
				
			||||||
 | 
								skipSw := attr.Value & nl.TCA_CLS_FLAGS_SKIP_HW
 | 
				
			||||||
 | 
								skipHw := attr.Value & nl.TCA_CLS_FLAGS_SKIP_SW
 | 
				
			||||||
 | 
								if skipSw != 0 {
 | 
				
			||||||
 | 
									filter.SkipSw = true
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if skipHw != 0 {
 | 
				
			||||||
 | 
									filter.SkipHw = true
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// FilterDel will delete a filter from the system.
 | 
					// FilterDel will delete a filter from the system.
 | 
				
			||||||
@@ -129,19 +242,7 @@ func FilterDel(filter Filter) error {
 | 
				
			|||||||
// FilterDel will delete a filter from the system.
 | 
					// FilterDel will delete a filter from the system.
 | 
				
			||||||
// Equivalent to: `tc filter del $filter`
 | 
					// Equivalent to: `tc filter del $filter`
 | 
				
			||||||
func (h *Handle) FilterDel(filter Filter) error {
 | 
					func (h *Handle) FilterDel(filter Filter) error {
 | 
				
			||||||
	req := h.newNetlinkRequest(unix.RTM_DELTFILTER, unix.NLM_F_ACK)
 | 
						return h.filterModify(filter, unix.RTM_DELTFILTER, 0)
 | 
				
			||||||
	base := filter.Attrs()
 | 
					 | 
				
			||||||
	msg := &nl.TcMsg{
 | 
					 | 
				
			||||||
		Family:  nl.FAMILY_ALL,
 | 
					 | 
				
			||||||
		Ifindex: int32(base.LinkIndex),
 | 
					 | 
				
			||||||
		Handle:  base.Handle,
 | 
					 | 
				
			||||||
		Parent:  base.Parent,
 | 
					 | 
				
			||||||
		Info:    MakeHandle(base.Priority, nl.Swap16(base.Protocol)),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	req.AddData(msg)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_, err := req.Execute(unix.NETLINK_ROUTE, 0)
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// FilterAdd will add a filter to the system.
 | 
					// FilterAdd will add a filter to the system.
 | 
				
			||||||
@@ -153,7 +254,7 @@ func FilterAdd(filter Filter) error {
 | 
				
			|||||||
// FilterAdd will add a filter to the system.
 | 
					// FilterAdd will add a filter to the system.
 | 
				
			||||||
// Equivalent to: `tc filter add $filter`
 | 
					// Equivalent to: `tc filter add $filter`
 | 
				
			||||||
func (h *Handle) FilterAdd(filter Filter) error {
 | 
					func (h *Handle) FilterAdd(filter Filter) error {
 | 
				
			||||||
	return h.filterModify(filter, unix.NLM_F_CREATE|unix.NLM_F_EXCL)
 | 
						return h.filterModify(filter, unix.RTM_NEWTFILTER, unix.NLM_F_CREATE|unix.NLM_F_EXCL)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// FilterReplace will replace a filter.
 | 
					// FilterReplace will replace a filter.
 | 
				
			||||||
@@ -165,12 +266,11 @@ func FilterReplace(filter Filter) error {
 | 
				
			|||||||
// FilterReplace will replace a filter.
 | 
					// FilterReplace will replace a filter.
 | 
				
			||||||
// Equivalent to: `tc filter replace $filter`
 | 
					// Equivalent to: `tc filter replace $filter`
 | 
				
			||||||
func (h *Handle) FilterReplace(filter Filter) error {
 | 
					func (h *Handle) FilterReplace(filter Filter) error {
 | 
				
			||||||
	return h.filterModify(filter, unix.NLM_F_CREATE)
 | 
						return h.filterModify(filter, unix.RTM_NEWTFILTER, unix.NLM_F_CREATE)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (h *Handle) filterModify(filter Filter, flags int) error {
 | 
					func (h *Handle) filterModify(filter Filter, proto, flags int) error {
 | 
				
			||||||
	native = nl.NativeEndian()
 | 
						req := h.newNetlinkRequest(proto, flags|unix.NLM_F_ACK)
 | 
				
			||||||
	req := h.newNetlinkRequest(unix.RTM_NEWTFILTER, flags|unix.NLM_F_ACK)
 | 
					 | 
				
			||||||
	base := filter.Attrs()
 | 
						base := filter.Attrs()
 | 
				
			||||||
	msg := &nl.TcMsg{
 | 
						msg := &nl.TcMsg{
 | 
				
			||||||
		Family:  nl.FAMILY_ALL,
 | 
							Family:  nl.FAMILY_ALL,
 | 
				
			||||||
@@ -180,6 +280,9 @@ func (h *Handle) filterModify(filter Filter, flags int) error {
 | 
				
			|||||||
		Info:    MakeHandle(base.Priority, nl.Swap16(base.Protocol)),
 | 
							Info:    MakeHandle(base.Priority, nl.Swap16(base.Protocol)),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	req.AddData(msg)
 | 
						req.AddData(msg)
 | 
				
			||||||
 | 
						if filter.Attrs().Chain != nil {
 | 
				
			||||||
 | 
							req.AddData(nl.NewRtAttr(nl.TCA_CHAIN, nl.Uint32Attr(*filter.Attrs().Chain)))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(filter.Type())))
 | 
						req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(filter.Type())))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	options := nl.NewRtAttr(nl.TCA_OPTIONS, nil)
 | 
						options := nl.NewRtAttr(nl.TCA_OPTIONS, nil)
 | 
				
			||||||
@@ -226,6 +329,15 @@ func (h *Handle) filterModify(filter Filter, flags int) error {
 | 
				
			|||||||
		if filter.Hash != 0 {
 | 
							if filter.Hash != 0 {
 | 
				
			||||||
			options.AddRtAttr(nl.TCA_U32_HASH, nl.Uint32Attr(filter.Hash))
 | 
								options.AddRtAttr(nl.TCA_U32_HASH, nl.Uint32Attr(filter.Hash))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if filter.Link != 0 {
 | 
				
			||||||
 | 
								options.AddRtAttr(nl.TCA_U32_LINK, nl.Uint32Attr(filter.Link))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if filter.Police != nil {
 | 
				
			||||||
 | 
								police := options.AddRtAttr(nl.TCA_U32_POLICE, nil)
 | 
				
			||||||
 | 
								if err := encodePolice(police, filter.Police); err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		actionsAttr := options.AddRtAttr(nl.TCA_U32_ACT, nil)
 | 
							actionsAttr := options.AddRtAttr(nl.TCA_U32_ACT, nil)
 | 
				
			||||||
		// backwards compatibility
 | 
							// backwards compatibility
 | 
				
			||||||
		if filter.RedirIndex != 0 {
 | 
							if filter.RedirIndex != 0 {
 | 
				
			||||||
@@ -234,7 +346,7 @@ func (h *Handle) filterModify(filter Filter, flags int) error {
 | 
				
			|||||||
		if err := EncodeActions(actionsAttr, filter.Actions); err != nil {
 | 
							if err := EncodeActions(actionsAttr, filter.Actions); err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	case *Fw:
 | 
						case *FwFilter:
 | 
				
			||||||
		if filter.Mask != 0 {
 | 
							if filter.Mask != 0 {
 | 
				
			||||||
			b := make([]byte, 4)
 | 
								b := make([]byte, 4)
 | 
				
			||||||
			native.PutUint32(b, filter.Mask)
 | 
								native.PutUint32(b, filter.Mask)
 | 
				
			||||||
@@ -243,17 +355,10 @@ func (h *Handle) filterModify(filter Filter, flags int) error {
 | 
				
			|||||||
		if filter.InDev != "" {
 | 
							if filter.InDev != "" {
 | 
				
			||||||
			options.AddRtAttr(nl.TCA_FW_INDEV, nl.ZeroTerminated(filter.InDev))
 | 
								options.AddRtAttr(nl.TCA_FW_INDEV, nl.ZeroTerminated(filter.InDev))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (filter.Police != nl.TcPolice{}) {
 | 
							if filter.Police != nil {
 | 
				
			||||||
 | 
					 | 
				
			||||||
			police := options.AddRtAttr(nl.TCA_FW_POLICE, nil)
 | 
								police := options.AddRtAttr(nl.TCA_FW_POLICE, nil)
 | 
				
			||||||
			police.AddRtAttr(nl.TCA_POLICE_TBF, filter.Police.Serialize())
 | 
								if err := encodePolice(police, filter.Police); err != nil {
 | 
				
			||||||
			if (filter.Police.Rate != nl.TcRateSpec{}) {
 | 
									return err
 | 
				
			||||||
				payload := SerializeRtab(filter.Rtab)
 | 
					 | 
				
			||||||
				police.AddRtAttr(nl.TCA_POLICE_RATE, payload)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (filter.Police.PeakRate != nl.TcRateSpec{}) {
 | 
					 | 
				
			||||||
				payload := SerializeRtab(filter.Ptab)
 | 
					 | 
				
			||||||
				police.AddRtAttr(nl.TCA_POLICE_PEAKRATE, payload)
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if filter.ClassId != 0 {
 | 
							if filter.ClassId != 0 {
 | 
				
			||||||
@@ -261,6 +366,10 @@ func (h *Handle) filterModify(filter Filter, flags int) error {
 | 
				
			|||||||
			native.PutUint32(b, filter.ClassId)
 | 
								native.PutUint32(b, filter.ClassId)
 | 
				
			||||||
			options.AddRtAttr(nl.TCA_FW_CLASSID, b)
 | 
								options.AddRtAttr(nl.TCA_FW_CLASSID, b)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							actionsAttr := options.AddRtAttr(nl.TCA_FW_ACT, nil)
 | 
				
			||||||
 | 
							if err := EncodeActions(actionsAttr, filter.Actions); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	case *BpfFilter:
 | 
						case *BpfFilter:
 | 
				
			||||||
		var bpfFlags uint32
 | 
							var bpfFlags uint32
 | 
				
			||||||
		if filter.ClassId != 0 {
 | 
							if filter.ClassId != 0 {
 | 
				
			||||||
@@ -284,8 +393,11 @@ func (h *Handle) filterModify(filter Filter, flags int) error {
 | 
				
			|||||||
		if filter.ClassId != 0 {
 | 
							if filter.ClassId != 0 {
 | 
				
			||||||
			options.AddRtAttr(nl.TCA_MATCHALL_CLASSID, nl.Uint32Attr(filter.ClassId))
 | 
								options.AddRtAttr(nl.TCA_MATCHALL_CLASSID, nl.Uint32Attr(filter.ClassId))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						case *Flower:
 | 
				
			||||||
 | 
							if err := filter.encode(options); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	req.AddData(options)
 | 
						req.AddData(options)
 | 
				
			||||||
	_, err := req.Execute(unix.NETLINK_ROUTE, 0)
 | 
						_, err := req.Execute(unix.NETLINK_ROUTE, 0)
 | 
				
			||||||
	return err
 | 
						return err
 | 
				
			||||||
@@ -347,11 +459,13 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
 | 
				
			|||||||
				case "u32":
 | 
									case "u32":
 | 
				
			||||||
					filter = &U32{}
 | 
										filter = &U32{}
 | 
				
			||||||
				case "fw":
 | 
									case "fw":
 | 
				
			||||||
					filter = &Fw{}
 | 
										filter = &FwFilter{}
 | 
				
			||||||
				case "bpf":
 | 
									case "bpf":
 | 
				
			||||||
					filter = &BpfFilter{}
 | 
										filter = &BpfFilter{}
 | 
				
			||||||
				case "matchall":
 | 
									case "matchall":
 | 
				
			||||||
					filter = &MatchAll{}
 | 
										filter = &MatchAll{}
 | 
				
			||||||
 | 
									case "flower":
 | 
				
			||||||
 | 
										filter = &Flower{}
 | 
				
			||||||
				default:
 | 
									default:
 | 
				
			||||||
					filter = &GenericFilter{FilterType: filterType}
 | 
										filter = &GenericFilter{FilterType: filterType}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -381,9 +495,18 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
 | 
				
			|||||||
					if err != nil {
 | 
										if err != nil {
 | 
				
			||||||
						return nil, err
 | 
											return nil, err
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
									case "flower":
 | 
				
			||||||
 | 
										detailed, err = parseFlowerData(filter, data)
 | 
				
			||||||
 | 
										if err != nil {
 | 
				
			||||||
 | 
											return nil, err
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
				default:
 | 
									default:
 | 
				
			||||||
					detailed = true
 | 
										detailed = true
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
								case nl.TCA_CHAIN:
 | 
				
			||||||
 | 
									val := new(uint32)
 | 
				
			||||||
 | 
									*val = native.Uint32(attr.Value)
 | 
				
			||||||
 | 
									base.Chain = val
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// only return the detailed version of the filter
 | 
							// only return the detailed version of the filter
 | 
				
			||||||
@@ -412,6 +535,61 @@ func toAttrs(tcgen *nl.TcGen, attrs *ActionAttrs) {
 | 
				
			|||||||
	attrs.Bindcnt = int(tcgen.Bindcnt)
 | 
						attrs.Bindcnt = int(tcgen.Bindcnt)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func toTimeStamp(tcf *nl.Tcf) *ActionTimestamp {
 | 
				
			||||||
 | 
						return &ActionTimestamp{
 | 
				
			||||||
 | 
							Installed: tcf.Install,
 | 
				
			||||||
 | 
							LastUsed:  tcf.LastUse,
 | 
				
			||||||
 | 
							Expires:   tcf.Expires,
 | 
				
			||||||
 | 
							FirstUsed: tcf.FirstUse}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func encodePolice(attr *nl.RtAttr, action *PoliceAction) error {
 | 
				
			||||||
 | 
						var rtab [256]uint32
 | 
				
			||||||
 | 
						var ptab [256]uint32
 | 
				
			||||||
 | 
						police := nl.TcPolice{}
 | 
				
			||||||
 | 
						police.Index = uint32(action.Attrs().Index)
 | 
				
			||||||
 | 
						police.Bindcnt = int32(action.Attrs().Bindcnt)
 | 
				
			||||||
 | 
						police.Capab = uint32(action.Attrs().Capab)
 | 
				
			||||||
 | 
						police.Refcnt = int32(action.Attrs().Refcnt)
 | 
				
			||||||
 | 
						police.Rate.Rate = action.Rate
 | 
				
			||||||
 | 
						police.PeakRate.Rate = action.PeakRate
 | 
				
			||||||
 | 
						police.Action = int32(action.ExceedAction)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if police.Rate.Rate != 0 {
 | 
				
			||||||
 | 
							police.Rate.Mpu = action.Mpu
 | 
				
			||||||
 | 
							police.Rate.Overhead = action.Overhead
 | 
				
			||||||
 | 
							if CalcRtable(&police.Rate, rtab[:], action.RCellLog, action.Mtu, action.LinkLayer) < 0 {
 | 
				
			||||||
 | 
								return errors.New("TBF: failed to calculate rate table")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							police.Burst = Xmittime(uint64(police.Rate.Rate), action.Burst)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						police.Mtu = action.Mtu
 | 
				
			||||||
 | 
						if police.PeakRate.Rate != 0 {
 | 
				
			||||||
 | 
							police.PeakRate.Mpu = action.Mpu
 | 
				
			||||||
 | 
							police.PeakRate.Overhead = action.Overhead
 | 
				
			||||||
 | 
							if CalcRtable(&police.PeakRate, ptab[:], action.PCellLog, action.Mtu, action.LinkLayer) < 0 {
 | 
				
			||||||
 | 
								return errors.New("POLICE: failed to calculate peak rate table")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						attr.AddRtAttr(nl.TCA_POLICE_TBF, police.Serialize())
 | 
				
			||||||
 | 
						if police.Rate.Rate != 0 {
 | 
				
			||||||
 | 
							attr.AddRtAttr(nl.TCA_POLICE_RATE, SerializeRtab(rtab))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if police.PeakRate.Rate != 0 {
 | 
				
			||||||
 | 
							attr.AddRtAttr(nl.TCA_POLICE_PEAKRATE, SerializeRtab(ptab))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if action.AvRate != 0 {
 | 
				
			||||||
 | 
							attr.AddRtAttr(nl.TCA_POLICE_AVRATE, nl.Uint32Attr(action.AvRate))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if action.NotExceedAction != 0 {
 | 
				
			||||||
 | 
							attr.AddRtAttr(nl.TCA_POLICE_RESULT, nl.Uint32Attr(uint32(action.NotExceedAction)))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func EncodeActions(attr *nl.RtAttr, actions []Action) error {
 | 
					func EncodeActions(attr *nl.RtAttr, actions []Action) error {
 | 
				
			||||||
	tabIndex := int(nl.TCA_ACT_TAB)
 | 
						tabIndex := int(nl.TCA_ACT_TAB)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -419,6 +597,14 @@ func EncodeActions(attr *nl.RtAttr, actions []Action) error {
 | 
				
			|||||||
		switch action := action.(type) {
 | 
							switch action := action.(type) {
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			return fmt.Errorf("unknown action type %s", action.Type())
 | 
								return fmt.Errorf("unknown action type %s", action.Type())
 | 
				
			||||||
 | 
							case *PoliceAction:
 | 
				
			||||||
 | 
								table := attr.AddRtAttr(tabIndex, nil)
 | 
				
			||||||
 | 
								tabIndex++
 | 
				
			||||||
 | 
								table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("police"))
 | 
				
			||||||
 | 
								aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
 | 
				
			||||||
 | 
								if err := encodePolice(aopts, action); err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		case *MirredAction:
 | 
							case *MirredAction:
 | 
				
			||||||
			table := attr.AddRtAttr(tabIndex, nil)
 | 
								table := attr.AddRtAttr(tabIndex, nil)
 | 
				
			||||||
			tabIndex++
 | 
								tabIndex++
 | 
				
			||||||
@@ -456,6 +642,9 @@ func EncodeActions(attr *nl.RtAttr, actions []Action) error {
 | 
				
			|||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					return fmt.Errorf("invalid dst addr %s for tunnel_key action", action.DstAddr)
 | 
										return fmt.Errorf("invalid dst addr %s for tunnel_key action", action.DstAddr)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
									if action.DestPort != 0 {
 | 
				
			||||||
 | 
										aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_DST_PORT, htons(action.DestPort))
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		case *SkbEditAction:
 | 
							case *SkbEditAction:
 | 
				
			||||||
			table := attr.AddRtAttr(tabIndex, nil)
 | 
								table := attr.AddRtAttr(tabIndex, nil)
 | 
				
			||||||
@@ -477,6 +666,9 @@ func EncodeActions(attr *nl.RtAttr, actions []Action) error {
 | 
				
			|||||||
			if action.Mark != nil {
 | 
								if action.Mark != nil {
 | 
				
			||||||
				aopts.AddRtAttr(nl.TCA_SKBEDIT_MARK, nl.Uint32Attr(*action.Mark))
 | 
									aopts.AddRtAttr(nl.TCA_SKBEDIT_MARK, nl.Uint32Attr(*action.Mark))
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								if action.Mask != nil {
 | 
				
			||||||
 | 
									aopts.AddRtAttr(nl.TCA_SKBEDIT_MASK, nl.Uint32Attr(*action.Mask))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		case *ConnmarkAction:
 | 
							case *ConnmarkAction:
 | 
				
			||||||
			table := attr.AddRtAttr(tabIndex, nil)
 | 
								table := attr.AddRtAttr(tabIndex, nil)
 | 
				
			||||||
			tabIndex++
 | 
								tabIndex++
 | 
				
			||||||
@@ -487,6 +679,16 @@ func EncodeActions(attr *nl.RtAttr, actions []Action) error {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			toTcGen(action.Attrs(), &connmark.TcGen)
 | 
								toTcGen(action.Attrs(), &connmark.TcGen)
 | 
				
			||||||
			aopts.AddRtAttr(nl.TCA_CONNMARK_PARMS, connmark.Serialize())
 | 
								aopts.AddRtAttr(nl.TCA_CONNMARK_PARMS, connmark.Serialize())
 | 
				
			||||||
 | 
							case *CsumAction:
 | 
				
			||||||
 | 
								table := attr.AddRtAttr(tabIndex, nil)
 | 
				
			||||||
 | 
								tabIndex++
 | 
				
			||||||
 | 
								table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("csum"))
 | 
				
			||||||
 | 
								aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
 | 
				
			||||||
 | 
								csum := nl.TcCsum{
 | 
				
			||||||
 | 
									UpdateFlags: uint32(action.UpdateFlags),
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								toTcGen(action.Attrs(), &csum.TcGen)
 | 
				
			||||||
 | 
								aopts.AddRtAttr(nl.TCA_CSUM_PARMS, csum.Serialize())
 | 
				
			||||||
		case *BpfAction:
 | 
							case *BpfAction:
 | 
				
			||||||
			table := attr.AddRtAttr(tabIndex, nil)
 | 
								table := attr.AddRtAttr(tabIndex, nil)
 | 
				
			||||||
			tabIndex++
 | 
								tabIndex++
 | 
				
			||||||
@@ -505,16 +707,64 @@ func EncodeActions(attr *nl.RtAttr, actions []Action) error {
 | 
				
			|||||||
			gen := nl.TcGen{}
 | 
								gen := nl.TcGen{}
 | 
				
			||||||
			toTcGen(action.Attrs(), &gen)
 | 
								toTcGen(action.Attrs(), &gen)
 | 
				
			||||||
			aopts.AddRtAttr(nl.TCA_GACT_PARMS, gen.Serialize())
 | 
								aopts.AddRtAttr(nl.TCA_GACT_PARMS, gen.Serialize())
 | 
				
			||||||
 | 
							case *PeditAction:
 | 
				
			||||||
 | 
								table := attr.AddRtAttr(tabIndex, nil)
 | 
				
			||||||
 | 
								tabIndex++
 | 
				
			||||||
 | 
								pedit := nl.TcPedit{}
 | 
				
			||||||
 | 
								if action.SrcMacAddr != nil {
 | 
				
			||||||
 | 
									pedit.SetEthSrc(action.SrcMacAddr)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if action.DstMacAddr != nil {
 | 
				
			||||||
 | 
									pedit.SetEthDst(action.DstMacAddr)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if action.SrcIP != nil {
 | 
				
			||||||
 | 
									pedit.SetSrcIP(action.SrcIP)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if action.DstIP != nil {
 | 
				
			||||||
 | 
									pedit.SetDstIP(action.DstIP)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if action.SrcPort != 0 {
 | 
				
			||||||
 | 
									pedit.SetSrcPort(action.SrcPort, action.Proto)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if action.DstPort != 0 {
 | 
				
			||||||
 | 
									pedit.SetDstPort(action.DstPort, action.Proto)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								pedit.Encode(table)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parsePolice(data syscall.NetlinkRouteAttr, police *PoliceAction) {
 | 
				
			||||||
 | 
						switch data.Attr.Type {
 | 
				
			||||||
 | 
						case nl.TCA_POLICE_RESULT:
 | 
				
			||||||
 | 
							police.NotExceedAction = TcPolAct(native.Uint32(data.Value[0:4]))
 | 
				
			||||||
 | 
						case nl.TCA_POLICE_AVRATE:
 | 
				
			||||||
 | 
							police.AvRate = native.Uint32(data.Value[0:4])
 | 
				
			||||||
 | 
						case nl.TCA_POLICE_TBF:
 | 
				
			||||||
 | 
							p := *nl.DeserializeTcPolice(data.Value)
 | 
				
			||||||
 | 
							police.ActionAttrs = ActionAttrs{}
 | 
				
			||||||
 | 
							police.Attrs().Index = int(p.Index)
 | 
				
			||||||
 | 
							police.Attrs().Bindcnt = int(p.Bindcnt)
 | 
				
			||||||
 | 
							police.Attrs().Capab = int(p.Capab)
 | 
				
			||||||
 | 
							police.Attrs().Refcnt = int(p.Refcnt)
 | 
				
			||||||
 | 
							police.ExceedAction = TcPolAct(p.Action)
 | 
				
			||||||
 | 
							police.Rate = p.Rate.Rate
 | 
				
			||||||
 | 
							police.PeakRate = p.PeakRate.Rate
 | 
				
			||||||
 | 
							police.Burst = Xmitsize(uint64(p.Rate.Rate), p.Burst)
 | 
				
			||||||
 | 
							police.Mtu = p.Mtu
 | 
				
			||||||
 | 
							police.LinkLayer = int(p.Rate.Linklayer) & nl.TC_LINKLAYER_MASK
 | 
				
			||||||
 | 
							police.Overhead = p.Rate.Overhead
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
 | 
					func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
 | 
				
			||||||
	var actions []Action
 | 
						var actions []Action
 | 
				
			||||||
	for _, table := range tables {
 | 
						for _, table := range tables {
 | 
				
			||||||
		var action Action
 | 
							var action Action
 | 
				
			||||||
		var actionType string
 | 
							var actionType string
 | 
				
			||||||
 | 
							var actionnStatistic *ActionStatistic
 | 
				
			||||||
 | 
							var actionTimestamp *ActionTimestamp
 | 
				
			||||||
		aattrs, err := nl.ParseRouteAttr(table.Value)
 | 
							aattrs, err := nl.ParseRouteAttr(table.Value)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
@@ -532,12 +782,18 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
 | 
				
			|||||||
					action = &BpfAction{}
 | 
										action = &BpfAction{}
 | 
				
			||||||
				case "connmark":
 | 
									case "connmark":
 | 
				
			||||||
					action = &ConnmarkAction{}
 | 
										action = &ConnmarkAction{}
 | 
				
			||||||
 | 
									case "csum":
 | 
				
			||||||
 | 
										action = &CsumAction{}
 | 
				
			||||||
				case "gact":
 | 
									case "gact":
 | 
				
			||||||
					action = &GenericAction{}
 | 
										action = &GenericAction{}
 | 
				
			||||||
				case "tunnel_key":
 | 
									case "tunnel_key":
 | 
				
			||||||
					action = &TunnelKeyAction{}
 | 
										action = &TunnelKeyAction{}
 | 
				
			||||||
				case "skbedit":
 | 
									case "skbedit":
 | 
				
			||||||
					action = &SkbEditAction{}
 | 
										action = &SkbEditAction{}
 | 
				
			||||||
 | 
									case "police":
 | 
				
			||||||
 | 
										action = &PoliceAction{}
 | 
				
			||||||
 | 
									case "pedit":
 | 
				
			||||||
 | 
										action = &PeditAction{}
 | 
				
			||||||
				default:
 | 
									default:
 | 
				
			||||||
					break nextattr
 | 
										break nextattr
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -556,7 +812,11 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
 | 
				
			|||||||
							toAttrs(&mirred.TcGen, action.Attrs())
 | 
												toAttrs(&mirred.TcGen, action.Attrs())
 | 
				
			||||||
							action.(*MirredAction).Ifindex = int(mirred.Ifindex)
 | 
												action.(*MirredAction).Ifindex = int(mirred.Ifindex)
 | 
				
			||||||
							action.(*MirredAction).MirredAction = MirredAct(mirred.Eaction)
 | 
												action.(*MirredAction).MirredAction = MirredAct(mirred.Eaction)
 | 
				
			||||||
 | 
											case nl.TCA_MIRRED_TM:
 | 
				
			||||||
 | 
												tcTs := nl.DeserializeTcf(adatum.Value)
 | 
				
			||||||
 | 
												actionTimestamp = toTimeStamp(tcTs)
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					case "tunnel_key":
 | 
										case "tunnel_key":
 | 
				
			||||||
						switch adatum.Attr.Type {
 | 
											switch adatum.Attr.Type {
 | 
				
			||||||
						case nl.TCA_TUNNEL_KEY_PARMS:
 | 
											case nl.TCA_TUNNEL_KEY_PARMS:
 | 
				
			||||||
@@ -566,12 +826,15 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
 | 
				
			|||||||
							action.(*TunnelKeyAction).Action = TunnelKeyAct(tun.Action)
 | 
												action.(*TunnelKeyAction).Action = TunnelKeyAct(tun.Action)
 | 
				
			||||||
						case nl.TCA_TUNNEL_KEY_ENC_KEY_ID:
 | 
											case nl.TCA_TUNNEL_KEY_ENC_KEY_ID:
 | 
				
			||||||
							action.(*TunnelKeyAction).KeyID = networkOrder.Uint32(adatum.Value[0:4])
 | 
												action.(*TunnelKeyAction).KeyID = networkOrder.Uint32(adatum.Value[0:4])
 | 
				
			||||||
						case nl.TCA_TUNNEL_KEY_ENC_IPV6_SRC:
 | 
											case nl.TCA_TUNNEL_KEY_ENC_IPV6_SRC, nl.TCA_TUNNEL_KEY_ENC_IPV4_SRC:
 | 
				
			||||||
						case nl.TCA_TUNNEL_KEY_ENC_IPV4_SRC:
 | 
												action.(*TunnelKeyAction).SrcAddr = adatum.Value[:]
 | 
				
			||||||
							action.(*TunnelKeyAction).SrcAddr = net.IP(adatum.Value[:])
 | 
											case nl.TCA_TUNNEL_KEY_ENC_IPV6_DST, nl.TCA_TUNNEL_KEY_ENC_IPV4_DST:
 | 
				
			||||||
						case nl.TCA_TUNNEL_KEY_ENC_IPV6_DST:
 | 
												action.(*TunnelKeyAction).DstAddr = adatum.Value[:]
 | 
				
			||||||
						case nl.TCA_TUNNEL_KEY_ENC_IPV4_DST:
 | 
											case nl.TCA_TUNNEL_KEY_ENC_DST_PORT:
 | 
				
			||||||
							action.(*TunnelKeyAction).DstAddr = net.IP(adatum.Value[:])
 | 
												action.(*TunnelKeyAction).DestPort = ntohs(adatum.Value)
 | 
				
			||||||
 | 
											case nl.TCA_TUNNEL_KEY_TM:
 | 
				
			||||||
 | 
												tcTs := nl.DeserializeTcf(adatum.Value)
 | 
				
			||||||
 | 
												actionTimestamp = toTimeStamp(tcTs)
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					case "skbedit":
 | 
										case "skbedit":
 | 
				
			||||||
						switch adatum.Attr.Type {
 | 
											switch adatum.Attr.Type {
 | 
				
			||||||
@@ -582,6 +845,9 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
 | 
				
			|||||||
						case nl.TCA_SKBEDIT_MARK:
 | 
											case nl.TCA_SKBEDIT_MARK:
 | 
				
			||||||
							mark := native.Uint32(adatum.Value[0:4])
 | 
												mark := native.Uint32(adatum.Value[0:4])
 | 
				
			||||||
							action.(*SkbEditAction).Mark = &mark
 | 
												action.(*SkbEditAction).Mark = &mark
 | 
				
			||||||
 | 
											case nl.TCA_SKBEDIT_MASK:
 | 
				
			||||||
 | 
												mask := native.Uint32(adatum.Value[0:4])
 | 
				
			||||||
 | 
												action.(*SkbEditAction).Mask = &mask
 | 
				
			||||||
						case nl.TCA_SKBEDIT_PRIORITY:
 | 
											case nl.TCA_SKBEDIT_PRIORITY:
 | 
				
			||||||
							priority := native.Uint32(adatum.Value[0:4])
 | 
												priority := native.Uint32(adatum.Value[0:4])
 | 
				
			||||||
							action.(*SkbEditAction).Priority = &priority
 | 
												action.(*SkbEditAction).Priority = &priority
 | 
				
			||||||
@@ -591,6 +857,9 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
 | 
				
			|||||||
						case nl.TCA_SKBEDIT_QUEUE_MAPPING:
 | 
											case nl.TCA_SKBEDIT_QUEUE_MAPPING:
 | 
				
			||||||
							mapping := native.Uint16(adatum.Value[0:2])
 | 
												mapping := native.Uint16(adatum.Value[0:2])
 | 
				
			||||||
							action.(*SkbEditAction).QueueMapping = &mapping
 | 
												action.(*SkbEditAction).QueueMapping = &mapping
 | 
				
			||||||
 | 
											case nl.TCA_SKBEDIT_TM:
 | 
				
			||||||
 | 
												tcTs := nl.DeserializeTcf(adatum.Value)
 | 
				
			||||||
 | 
												actionTimestamp = toTimeStamp(tcTs)
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					case "bpf":
 | 
										case "bpf":
 | 
				
			||||||
						switch adatum.Attr.Type {
 | 
											switch adatum.Attr.Type {
 | 
				
			||||||
@@ -601,6 +870,9 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
 | 
				
			|||||||
							action.(*BpfAction).Fd = int(native.Uint32(adatum.Value[0:4]))
 | 
												action.(*BpfAction).Fd = int(native.Uint32(adatum.Value[0:4]))
 | 
				
			||||||
						case nl.TCA_ACT_BPF_NAME:
 | 
											case nl.TCA_ACT_BPF_NAME:
 | 
				
			||||||
							action.(*BpfAction).Name = string(adatum.Value[:len(adatum.Value)-1])
 | 
												action.(*BpfAction).Name = string(adatum.Value[:len(adatum.Value)-1])
 | 
				
			||||||
 | 
											case nl.TCA_ACT_BPF_TM:
 | 
				
			||||||
 | 
												tcTs := nl.DeserializeTcf(adatum.Value)
 | 
				
			||||||
 | 
												actionTimestamp = toTimeStamp(tcTs)
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					case "connmark":
 | 
										case "connmark":
 | 
				
			||||||
						switch adatum.Attr.Type {
 | 
											switch adatum.Attr.Type {
 | 
				
			||||||
@@ -609,24 +881,53 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
 | 
				
			|||||||
							action.(*ConnmarkAction).ActionAttrs = ActionAttrs{}
 | 
												action.(*ConnmarkAction).ActionAttrs = ActionAttrs{}
 | 
				
			||||||
							toAttrs(&connmark.TcGen, action.Attrs())
 | 
												toAttrs(&connmark.TcGen, action.Attrs())
 | 
				
			||||||
							action.(*ConnmarkAction).Zone = connmark.Zone
 | 
												action.(*ConnmarkAction).Zone = connmark.Zone
 | 
				
			||||||
 | 
											case nl.TCA_CONNMARK_TM:
 | 
				
			||||||
 | 
												tcTs := nl.DeserializeTcf(adatum.Value)
 | 
				
			||||||
 | 
												actionTimestamp = toTimeStamp(tcTs)
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										case "csum":
 | 
				
			||||||
 | 
											switch adatum.Attr.Type {
 | 
				
			||||||
 | 
											case nl.TCA_CSUM_PARMS:
 | 
				
			||||||
 | 
												csum := *nl.DeserializeTcCsum(adatum.Value)
 | 
				
			||||||
 | 
												action.(*CsumAction).ActionAttrs = ActionAttrs{}
 | 
				
			||||||
 | 
												toAttrs(&csum.TcGen, action.Attrs())
 | 
				
			||||||
 | 
												action.(*CsumAction).UpdateFlags = CsumUpdateFlags(csum.UpdateFlags)
 | 
				
			||||||
 | 
											case nl.TCA_CSUM_TM:
 | 
				
			||||||
 | 
												tcTs := nl.DeserializeTcf(adatum.Value)
 | 
				
			||||||
 | 
												actionTimestamp = toTimeStamp(tcTs)
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					case "gact":
 | 
										case "gact":
 | 
				
			||||||
						switch adatum.Attr.Type {
 | 
											switch adatum.Attr.Type {
 | 
				
			||||||
						case nl.TCA_GACT_PARMS:
 | 
											case nl.TCA_GACT_PARMS:
 | 
				
			||||||
							gen := *nl.DeserializeTcGen(adatum.Value)
 | 
												gen := *nl.DeserializeTcGen(adatum.Value)
 | 
				
			||||||
							toAttrs(&gen, action.Attrs())
 | 
												toAttrs(&gen, action.Attrs())
 | 
				
			||||||
 | 
												if action.Attrs().Action.String() == "goto" {
 | 
				
			||||||
 | 
													action.(*GenericAction).Chain = TC_ACT_EXT_VAL_MASK & gen.Action
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
											case nl.TCA_GACT_TM:
 | 
				
			||||||
 | 
												tcTs := nl.DeserializeTcf(adatum.Value)
 | 
				
			||||||
 | 
												actionTimestamp = toTimeStamp(tcTs)
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										case "police":
 | 
				
			||||||
 | 
											parsePolice(adatum, action.(*PoliceAction))
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
								case nl.TCA_ACT_STATS:
 | 
				
			||||||
 | 
									s, err := parseTcStats2(aattr.Value)
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										return nil, err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									actionnStatistic = (*ActionStatistic)(s)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		}
 | 
							action.Attrs().Statistics = actionnStatistic
 | 
				
			||||||
 | 
							action.Attrs().Timestamp = actionTimestamp
 | 
				
			||||||
		actions = append(actions, action)
 | 
							actions = append(actions, action)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return actions, nil
 | 
						return actions, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseU32Data(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
 | 
					func parseU32Data(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
 | 
				
			||||||
	native = nl.NativeEndian()
 | 
					 | 
				
			||||||
	u32 := filter.(*U32)
 | 
						u32 := filter.(*U32)
 | 
				
			||||||
	detailed := false
 | 
						detailed := false
 | 
				
			||||||
	for _, datum := range data {
 | 
						for _, datum := range data {
 | 
				
			||||||
@@ -658,20 +959,28 @@ func parseU32Data(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error)
 | 
				
			|||||||
					u32.RedirIndex = int(action.Ifindex)
 | 
										u32.RedirIndex = int(action.Ifindex)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							case nl.TCA_U32_POLICE:
 | 
				
			||||||
 | 
								var police PoliceAction
 | 
				
			||||||
 | 
								adata, _ := nl.ParseRouteAttr(datum.Value)
 | 
				
			||||||
 | 
								for _, aattr := range adata {
 | 
				
			||||||
 | 
									parsePolice(aattr, &police)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								u32.Police = &police
 | 
				
			||||||
		case nl.TCA_U32_CLASSID:
 | 
							case nl.TCA_U32_CLASSID:
 | 
				
			||||||
			u32.ClassId = native.Uint32(datum.Value)
 | 
								u32.ClassId = native.Uint32(datum.Value)
 | 
				
			||||||
		case nl.TCA_U32_DIVISOR:
 | 
							case nl.TCA_U32_DIVISOR:
 | 
				
			||||||
			u32.Divisor = native.Uint32(datum.Value)
 | 
								u32.Divisor = native.Uint32(datum.Value)
 | 
				
			||||||
		case nl.TCA_U32_HASH:
 | 
							case nl.TCA_U32_HASH:
 | 
				
			||||||
			u32.Hash = native.Uint32(datum.Value)
 | 
								u32.Hash = native.Uint32(datum.Value)
 | 
				
			||||||
 | 
							case nl.TCA_U32_LINK:
 | 
				
			||||||
 | 
								u32.Link = native.Uint32(datum.Value)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return detailed, nil
 | 
						return detailed, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseFwData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
 | 
					func parseFwData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
 | 
				
			||||||
	native = nl.NativeEndian()
 | 
						fw := filter.(*FwFilter)
 | 
				
			||||||
	fw := filter.(*Fw)
 | 
					 | 
				
			||||||
	detailed := true
 | 
						detailed := true
 | 
				
			||||||
	for _, datum := range data {
 | 
						for _, datum := range data {
 | 
				
			||||||
		switch datum.Attr.Type {
 | 
							switch datum.Attr.Type {
 | 
				
			||||||
@@ -682,16 +991,20 @@ func parseFwData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
 | 
				
			|||||||
		case nl.TCA_FW_INDEV:
 | 
							case nl.TCA_FW_INDEV:
 | 
				
			||||||
			fw.InDev = string(datum.Value[:len(datum.Value)-1])
 | 
								fw.InDev = string(datum.Value[:len(datum.Value)-1])
 | 
				
			||||||
		case nl.TCA_FW_POLICE:
 | 
							case nl.TCA_FW_POLICE:
 | 
				
			||||||
 | 
								var police PoliceAction
 | 
				
			||||||
			adata, _ := nl.ParseRouteAttr(datum.Value)
 | 
								adata, _ := nl.ParseRouteAttr(datum.Value)
 | 
				
			||||||
			for _, aattr := range adata {
 | 
								for _, aattr := range adata {
 | 
				
			||||||
				switch aattr.Attr.Type {
 | 
									parsePolice(aattr, &police)
 | 
				
			||||||
				case nl.TCA_POLICE_TBF:
 | 
					 | 
				
			||||||
					fw.Police = *nl.DeserializeTcPolice(aattr.Value)
 | 
					 | 
				
			||||||
				case nl.TCA_POLICE_RATE:
 | 
					 | 
				
			||||||
					fw.Rtab = DeserializeRtab(aattr.Value)
 | 
					 | 
				
			||||||
				case nl.TCA_POLICE_PEAKRATE:
 | 
					 | 
				
			||||||
					fw.Ptab = DeserializeRtab(aattr.Value)
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								fw.Police = &police
 | 
				
			||||||
 | 
							case nl.TCA_FW_ACT:
 | 
				
			||||||
 | 
								tables, err := nl.ParseRouteAttr(datum.Value)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return detailed, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								fw.Actions, err = parseActions(tables)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return detailed, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -699,7 +1012,6 @@ func parseFwData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseBpfData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
 | 
					func parseBpfData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
 | 
				
			||||||
	native = nl.NativeEndian()
 | 
					 | 
				
			||||||
	bpf := filter.(*BpfFilter)
 | 
						bpf := filter.(*BpfFilter)
 | 
				
			||||||
	detailed := true
 | 
						detailed := true
 | 
				
			||||||
	for _, datum := range data {
 | 
						for _, datum := range data {
 | 
				
			||||||
@@ -718,14 +1030,13 @@ func parseBpfData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error)
 | 
				
			|||||||
		case nl.TCA_BPF_ID:
 | 
							case nl.TCA_BPF_ID:
 | 
				
			||||||
			bpf.Id = int(native.Uint32(datum.Value[0:4]))
 | 
								bpf.Id = int(native.Uint32(datum.Value[0:4]))
 | 
				
			||||||
		case nl.TCA_BPF_TAG:
 | 
							case nl.TCA_BPF_TAG:
 | 
				
			||||||
			bpf.Tag = hex.EncodeToString(datum.Value[:len(datum.Value)-1])
 | 
								bpf.Tag = hex.EncodeToString(datum.Value)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return detailed, nil
 | 
						return detailed, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseMatchAllData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
 | 
					func parseMatchAllData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
 | 
				
			||||||
	native = nl.NativeEndian()
 | 
					 | 
				
			||||||
	matchall := filter.(*MatchAll)
 | 
						matchall := filter.(*MatchAll)
 | 
				
			||||||
	detailed := true
 | 
						detailed := true
 | 
				
			||||||
	for _, datum := range data {
 | 
						for _, datum := range data {
 | 
				
			||||||
@@ -746,6 +1057,10 @@ func parseMatchAllData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, er
 | 
				
			|||||||
	return detailed, nil
 | 
						return detailed, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseFlowerData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
 | 
				
			||||||
 | 
						return true, filter.(*Flower).decode(data)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func AlignToAtm(size uint) uint {
 | 
					func AlignToAtm(size uint) uint {
 | 
				
			||||||
	var linksize, cells int
 | 
						var linksize, cells int
 | 
				
			||||||
	cells = int(size / nl.ATM_CELL_PAYLOAD)
 | 
						cells = int(size / nl.ATM_CELL_PAYLOAD)
 | 
				
			||||||
@@ -783,7 +1098,7 @@ func CalcRtable(rate *nl.TcRateSpec, rtab []uint32, cellLog int, mtu uint32, lin
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	for i := 0; i < 256; i++ {
 | 
						for i := 0; i < 256; i++ {
 | 
				
			||||||
		sz = AdjustSize(uint((i+1)<<uint32(cellLog)), uint(mpu), linklayer)
 | 
							sz = AdjustSize(uint((i+1)<<uint32(cellLog)), uint(mpu), linklayer)
 | 
				
			||||||
		rtab[i] = uint32(Xmittime(uint64(bps), uint32(sz)))
 | 
							rtab[i] = Xmittime(uint64(bps), uint32(sz))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	rate.CellAlign = -1
 | 
						rate.CellAlign = -1
 | 
				
			||||||
	rate.CellLog = uint8(cellLog)
 | 
						rate.CellLog = uint8(cellLog)
 | 
				
			||||||
@@ -793,14 +1108,12 @@ func CalcRtable(rate *nl.TcRateSpec, rtab []uint32, cellLog int, mtu uint32, lin
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func DeserializeRtab(b []byte) [256]uint32 {
 | 
					func DeserializeRtab(b []byte) [256]uint32 {
 | 
				
			||||||
	var rtab [256]uint32
 | 
						var rtab [256]uint32
 | 
				
			||||||
	native := nl.NativeEndian()
 | 
					 | 
				
			||||||
	r := bytes.NewReader(b)
 | 
						r := bytes.NewReader(b)
 | 
				
			||||||
	_ = binary.Read(r, native, &rtab)
 | 
						_ = binary.Read(r, native, &rtab)
 | 
				
			||||||
	return rtab
 | 
						return rtab
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func SerializeRtab(rtab [256]uint32) []byte {
 | 
					func SerializeRtab(rtab [256]uint32) []byte {
 | 
				
			||||||
	native := nl.NativeEndian()
 | 
					 | 
				
			||||||
	var w bytes.Buffer
 | 
						var w bytes.Buffer
 | 
				
			||||||
	_ = binary.Write(&w, native, rtab)
 | 
						_ = binary.Write(&w, native, rtab)
 | 
				
			||||||
	return w.Bytes()
 | 
						return w.Bytes()
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										45
									
								
								vendor/github.com/vishvananda/netlink/handle_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										45
									
								
								vendor/github.com/vishvananda/netlink/handle_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -15,12 +15,28 @@ var pkgHandle = &Handle{}
 | 
				
			|||||||
// Handle is an handle for the netlink requests on a
 | 
					// Handle is an handle for the netlink requests on a
 | 
				
			||||||
// specific network namespace. All the requests on the
 | 
					// specific network namespace. All the requests on the
 | 
				
			||||||
// same netlink family share the same netlink socket,
 | 
					// same netlink family share the same netlink socket,
 | 
				
			||||||
// which gets released when the handle is deleted.
 | 
					// which gets released when the handle is Close'd.
 | 
				
			||||||
type Handle struct {
 | 
					type Handle struct {
 | 
				
			||||||
	sockets      map[int]*nl.SocketHandle
 | 
						sockets      map[int]*nl.SocketHandle
 | 
				
			||||||
	lookupByDump bool
 | 
						lookupByDump bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetSocketTimeout configures timeout for default netlink sockets
 | 
				
			||||||
 | 
					func SetSocketTimeout(to time.Duration) error {
 | 
				
			||||||
 | 
						if to < time.Microsecond {
 | 
				
			||||||
 | 
							return fmt.Errorf("invalid timeout, minimul value is %s", time.Microsecond)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						nl.SocketTimeoutTv = unix.NsecToTimeval(to.Nanoseconds())
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetSocketTimeout returns the timeout value used by default netlink sockets
 | 
				
			||||||
 | 
					func GetSocketTimeout() time.Duration {
 | 
				
			||||||
 | 
						nsec := unix.TimevalToNsec(nl.SocketTimeoutTv)
 | 
				
			||||||
 | 
						return time.Duration(nsec) * time.Nanosecond
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SupportsNetlinkFamily reports whether the passed netlink family is supported by this Handle
 | 
					// SupportsNetlinkFamily reports whether the passed netlink family is supported by this Handle
 | 
				
			||||||
func (h *Handle) SupportsNetlinkFamily(nlFamily int) bool {
 | 
					func (h *Handle) SupportsNetlinkFamily(nlFamily int) bool {
 | 
				
			||||||
	_, ok := h.sockets[nlFamily]
 | 
						_, ok := h.sockets[nlFamily]
 | 
				
			||||||
@@ -91,6 +107,21 @@ func (h *Handle) GetSocketReceiveBufferSize() ([]int, error) {
 | 
				
			|||||||
	return results, nil
 | 
						return results, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetStrictCheck sets the strict check socket option for each socket in the netlink handle. Returns early if any set operation fails
 | 
				
			||||||
 | 
					func (h *Handle) SetStrictCheck(state bool) error {
 | 
				
			||||||
 | 
						for _, sh := range h.sockets {
 | 
				
			||||||
 | 
							var stateInt int = 0
 | 
				
			||||||
 | 
							if state {
 | 
				
			||||||
 | 
								stateInt = 1
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							err := unix.SetsockoptInt(sh.Socket.GetFd(), unix.SOL_NETLINK, unix.NETLINK_GET_STRICT_CHK, stateInt)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewHandleAt 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
 | 
					// specified by ns. If ns=netns.None(), current network namespace
 | 
				
			||||||
// will be assumed
 | 
					// will be assumed
 | 
				
			||||||
@@ -120,14 +151,22 @@ func newHandle(newNs, curNs netns.NsHandle, nlFamilies ...int) (*Handle, error)
 | 
				
			|||||||
	return h, nil
 | 
						return h, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Delete releases the resources allocated to this handle
 | 
					// Close releases the resources allocated to this handle
 | 
				
			||||||
func (h *Handle) Delete() {
 | 
					func (h *Handle) Close() {
 | 
				
			||||||
	for _, sh := range h.sockets {
 | 
						for _, sh := range h.sockets {
 | 
				
			||||||
		sh.Close()
 | 
							sh.Close()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	h.sockets = nil
 | 
						h.sockets = nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Delete releases the resources allocated to this handle
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Deprecated: use Close instead which is in line with typical resource release
 | 
				
			||||||
 | 
					// patterns for files and other resources.
 | 
				
			||||||
 | 
					func (h *Handle) Delete() {
 | 
				
			||||||
 | 
						h.Close()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (h *Handle) newNetlinkRequest(proto, flags int) *nl.NetlinkRequest {
 | 
					func (h *Handle) newNetlinkRequest(proto, flags int) *nl.NetlinkRequest {
 | 
				
			||||||
	// Do this so that package API still use nl package variable nextSeqNr
 | 
						// Do this so that package API still use nl package variable nextSeqNr
 | 
				
			||||||
	if h.sockets == nil {
 | 
						if h.sockets == nil {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										32
									
								
								vendor/github.com/vishvananda/netlink/handle_unspecified.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								vendor/github.com/vishvananda/netlink/handle_unspecified.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -23,6 +23,8 @@ func NewHandleAtFrom(newNs, curNs netns.NsHandle) (*Handle, error) {
 | 
				
			|||||||
	return nil, ErrNotImplemented
 | 
						return nil, ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) Close() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (h *Handle) Delete() {}
 | 
					func (h *Handle) Delete() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (h *Handle) SupportsNetlinkFamily(nlFamily int) bool {
 | 
					func (h *Handle) SupportsNetlinkFamily(nlFamily int) bool {
 | 
				
			||||||
@@ -77,6 +79,10 @@ func (h *Handle) LinkSetVfVlanQos(link Link, vf, vlan, qos int) error {
 | 
				
			|||||||
	return ErrNotImplemented
 | 
						return ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) LinkSetVfVlanQosProto(link Link, vf, vlan, qos, proto int) error {
 | 
				
			||||||
 | 
						return ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (h *Handle) LinkSetVfTxRate(link Link, vf, rate int) error {
 | 
					func (h *Handle) LinkSetVfTxRate(link Link, vf, rate int) error {
 | 
				
			||||||
	return ErrNotImplemented
 | 
						return ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -85,7 +91,7 @@ func (h *Handle) LinkSetVfRate(link Link, vf, minRate, maxRate int) error {
 | 
				
			|||||||
	return ErrNotImplemented
 | 
						return ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (h *Handle) LinkSetMaster(link Link, master *Bridge) error {
 | 
					func (h *Handle) LinkSetMaster(link Link, master Link) error {
 | 
				
			||||||
	return ErrNotImplemented
 | 
						return ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -161,6 +167,22 @@ func (h *Handle) LinkSetGroup(link Link, group int) error {
 | 
				
			|||||||
	return ErrNotImplemented
 | 
						return ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) LinkSetGSOMaxSize(link Link, maxSize int) error {
 | 
				
			||||||
 | 
						return ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) LinkSetGROMaxSize(link Link, maxSize int) error {
 | 
				
			||||||
 | 
						return ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) LinkSetGSOIPv4MaxSize(link Link, maxSize int) error {
 | 
				
			||||||
 | 
						return ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) LinkSetGROIPv4MaxSize(link Link, maxSize int) error {
 | 
				
			||||||
 | 
						return ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (h *Handle) setProtinfoAttr(link Link, mode bool, attr int) error {
 | 
					func (h *Handle) setProtinfoAttr(link Link, mode bool, attr int) error {
 | 
				
			||||||
	return ErrNotImplemented
 | 
						return ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -237,6 +259,14 @@ func (h *Handle) RouteAdd(route *Route) error {
 | 
				
			|||||||
	return ErrNotImplemented
 | 
						return ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) RouteAppend(route *Route) error {
 | 
				
			||||||
 | 
						return ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) RouteChange(route *Route) error {
 | 
				
			||||||
 | 
						return ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (h *Handle) RouteDel(route *Route) error {
 | 
					func (h *Handle) RouteDel(route *Route) error {
 | 
				
			||||||
	return ErrNotImplemented
 | 
						return ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										40
									
								
								vendor/github.com/vishvananda/netlink/inet_diag.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								vendor/github.com/vishvananda/netlink/inet_diag.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					package netlink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// INET_DIAG constatns
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						INET_DIAG_NONE = iota
 | 
				
			||||||
 | 
						INET_DIAG_MEMINFO
 | 
				
			||||||
 | 
						INET_DIAG_INFO
 | 
				
			||||||
 | 
						INET_DIAG_VEGASINFO
 | 
				
			||||||
 | 
						INET_DIAG_CONG
 | 
				
			||||||
 | 
						INET_DIAG_TOS
 | 
				
			||||||
 | 
						INET_DIAG_TCLASS
 | 
				
			||||||
 | 
						INET_DIAG_SKMEMINFO
 | 
				
			||||||
 | 
						INET_DIAG_SHUTDOWN
 | 
				
			||||||
 | 
						INET_DIAG_DCTCPINFO
 | 
				
			||||||
 | 
						INET_DIAG_PROTOCOL
 | 
				
			||||||
 | 
						INET_DIAG_SKV6ONLY
 | 
				
			||||||
 | 
						INET_DIAG_LOCALS
 | 
				
			||||||
 | 
						INET_DIAG_PEERS
 | 
				
			||||||
 | 
						INET_DIAG_PAD
 | 
				
			||||||
 | 
						INET_DIAG_MARK
 | 
				
			||||||
 | 
						INET_DIAG_BBRINFO
 | 
				
			||||||
 | 
						INET_DIAG_CLASS_ID
 | 
				
			||||||
 | 
						INET_DIAG_MD5SIG
 | 
				
			||||||
 | 
						INET_DIAG_ULP_INFO
 | 
				
			||||||
 | 
						INET_DIAG_SK_BPF_STORAGES
 | 
				
			||||||
 | 
						INET_DIAG_CGROUP_ID
 | 
				
			||||||
 | 
						INET_DIAG_SOCKOPT
 | 
				
			||||||
 | 
						INET_DIAG_MAX
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type InetDiagTCPInfoResp struct {
 | 
				
			||||||
 | 
						InetDiagMsg *Socket
 | 
				
			||||||
 | 
						TCPInfo     *TCPInfo
 | 
				
			||||||
 | 
						TCPBBRInfo  *TCPBBRInfo
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type InetDiagUDPInfoResp struct {
 | 
				
			||||||
 | 
						InetDiagMsg *Socket
 | 
				
			||||||
 | 
						Memory      *MemInfo
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										581
									
								
								vendor/github.com/vishvananda/netlink/ipset_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										581
									
								
								vendor/github.com/vishvananda/netlink/ipset_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,581 @@
 | 
				
			|||||||
 | 
					package netlink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/binary"
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
 | 
						"syscall"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/vishvananda/netlink/nl"
 | 
				
			||||||
 | 
						"golang.org/x/sys/unix"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IPSetEntry is used for adding, updating, retreiving and deleting entries
 | 
				
			||||||
 | 
					type IPSetEntry struct {
 | 
				
			||||||
 | 
						Comment  string
 | 
				
			||||||
 | 
						MAC      net.HardwareAddr
 | 
				
			||||||
 | 
						IP       net.IP
 | 
				
			||||||
 | 
						CIDR     uint8
 | 
				
			||||||
 | 
						Timeout  *uint32
 | 
				
			||||||
 | 
						Packets  *uint64
 | 
				
			||||||
 | 
						Bytes    *uint64
 | 
				
			||||||
 | 
						Protocol *uint8
 | 
				
			||||||
 | 
						Port     *uint16
 | 
				
			||||||
 | 
						IP2      net.IP
 | 
				
			||||||
 | 
						CIDR2    uint8
 | 
				
			||||||
 | 
						IFace    string
 | 
				
			||||||
 | 
						Mark     *uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Replace bool // replace existing entry
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IPSetResult is the result of a dump request for a set
 | 
				
			||||||
 | 
					type IPSetResult struct {
 | 
				
			||||||
 | 
						Nfgenmsg           *nl.Nfgenmsg
 | 
				
			||||||
 | 
						Protocol           uint8
 | 
				
			||||||
 | 
						ProtocolMinVersion uint8
 | 
				
			||||||
 | 
						Revision           uint8
 | 
				
			||||||
 | 
						Family             uint8
 | 
				
			||||||
 | 
						Flags              uint8
 | 
				
			||||||
 | 
						SetName            string
 | 
				
			||||||
 | 
						TypeName           string
 | 
				
			||||||
 | 
						Comment            string
 | 
				
			||||||
 | 
						MarkMask           uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						IPFrom   net.IP
 | 
				
			||||||
 | 
						IPTo     net.IP
 | 
				
			||||||
 | 
						PortFrom uint16
 | 
				
			||||||
 | 
						PortTo   uint16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						HashSize     uint32
 | 
				
			||||||
 | 
						NumEntries   uint32
 | 
				
			||||||
 | 
						MaxElements  uint32
 | 
				
			||||||
 | 
						References   uint32
 | 
				
			||||||
 | 
						SizeInMemory uint32
 | 
				
			||||||
 | 
						CadtFlags    uint32
 | 
				
			||||||
 | 
						Timeout      *uint32
 | 
				
			||||||
 | 
						LineNo       uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Entries []IPSetEntry
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IpsetCreateOptions is the options struct for creating a new ipset
 | 
				
			||||||
 | 
					type IpsetCreateOptions struct {
 | 
				
			||||||
 | 
						Replace  bool // replace existing ipset
 | 
				
			||||||
 | 
						Timeout  *uint32
 | 
				
			||||||
 | 
						Counters bool
 | 
				
			||||||
 | 
						Comments bool
 | 
				
			||||||
 | 
						Skbinfo  bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Family      uint8
 | 
				
			||||||
 | 
						Revision    uint8
 | 
				
			||||||
 | 
						IPFrom      net.IP
 | 
				
			||||||
 | 
						IPTo        net.IP
 | 
				
			||||||
 | 
						PortFrom    uint16
 | 
				
			||||||
 | 
						PortTo      uint16
 | 
				
			||||||
 | 
						MaxElements uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IpsetProtocol returns the ipset protocol version from the kernel
 | 
				
			||||||
 | 
					func IpsetProtocol() (uint8, uint8, error) {
 | 
				
			||||||
 | 
						return pkgHandle.IpsetProtocol()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IpsetCreate creates a new ipset
 | 
				
			||||||
 | 
					func IpsetCreate(setname, typename string, options IpsetCreateOptions) error {
 | 
				
			||||||
 | 
						return pkgHandle.IpsetCreate(setname, typename, options)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IpsetDestroy destroys an existing ipset
 | 
				
			||||||
 | 
					func IpsetDestroy(setname string) error {
 | 
				
			||||||
 | 
						return pkgHandle.IpsetDestroy(setname)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IpsetFlush flushes an existing ipset
 | 
				
			||||||
 | 
					func IpsetFlush(setname string) error {
 | 
				
			||||||
 | 
						return pkgHandle.IpsetFlush(setname)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IpsetSwap swaps two ipsets.
 | 
				
			||||||
 | 
					func IpsetSwap(setname, othersetname string) error {
 | 
				
			||||||
 | 
						return pkgHandle.IpsetSwap(setname, othersetname)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IpsetList dumps an specific ipset.
 | 
				
			||||||
 | 
					func IpsetList(setname string) (*IPSetResult, error) {
 | 
				
			||||||
 | 
						return pkgHandle.IpsetList(setname)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IpsetListAll dumps all ipsets.
 | 
				
			||||||
 | 
					func IpsetListAll() ([]IPSetResult, error) {
 | 
				
			||||||
 | 
						return pkgHandle.IpsetListAll()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IpsetAdd adds an entry to an existing ipset.
 | 
				
			||||||
 | 
					func IpsetAdd(setname string, entry *IPSetEntry) error {
 | 
				
			||||||
 | 
						return pkgHandle.IpsetAdd(setname, entry)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IpsetDel deletes an entry from an existing ipset.
 | 
				
			||||||
 | 
					func IpsetDel(setname string, entry *IPSetEntry) error {
 | 
				
			||||||
 | 
						return pkgHandle.IpsetDel(setname, entry)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IpsetTest tests whether an entry is in a set or not.
 | 
				
			||||||
 | 
					func IpsetTest(setname string, entry *IPSetEntry) (bool, error) {
 | 
				
			||||||
 | 
						return pkgHandle.IpsetTest(setname, entry)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) IpsetProtocol() (protocol uint8, minVersion uint8, err error) {
 | 
				
			||||||
 | 
						req := h.newIpsetRequest(nl.IPSET_CMD_PROTOCOL)
 | 
				
			||||||
 | 
						msgs, err := req.Execute(unix.NETLINK_NETFILTER, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0, 0, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						response := ipsetUnserialize(msgs)
 | 
				
			||||||
 | 
						return response.Protocol, response.ProtocolMinVersion, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) IpsetCreate(setname, typename string, options IpsetCreateOptions) error {
 | 
				
			||||||
 | 
						req := h.newIpsetRequest(nl.IPSET_CMD_CREATE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !options.Replace {
 | 
				
			||||||
 | 
							req.Flags |= unix.NLM_F_EXCL
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_SETNAME, nl.ZeroTerminated(setname)))
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_TYPENAME, nl.ZeroTerminated(typename)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						revision := options.Revision
 | 
				
			||||||
 | 
						if revision == 0 {
 | 
				
			||||||
 | 
							revision = getIpsetDefaultWithTypeName(typename)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_REVISION, nl.Uint8Attr(revision)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						data := nl.NewRtAttr(nl.IPSET_ATTR_DATA|int(nl.NLA_F_NESTED), nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var family uint8
 | 
				
			||||||
 | 
						switch typename {
 | 
				
			||||||
 | 
						case "hash:mac":
 | 
				
			||||||
 | 
						case "bitmap:port":
 | 
				
			||||||
 | 
							buf := make([]byte, 4)
 | 
				
			||||||
 | 
							binary.BigEndian.PutUint16(buf, options.PortFrom)
 | 
				
			||||||
 | 
							binary.BigEndian.PutUint16(buf[2:], options.PortTo)
 | 
				
			||||||
 | 
							data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_PORT_FROM|int(nl.NLA_F_NET_BYTEORDER), buf[:2]))
 | 
				
			||||||
 | 
							data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_PORT_TO|int(nl.NLA_F_NET_BYTEORDER), buf[2:]))
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							family = options.Family
 | 
				
			||||||
 | 
							if family == 0 {
 | 
				
			||||||
 | 
								family = unix.AF_INET
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_FAMILY, nl.Uint8Attr(family)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if options.MaxElements != 0 {
 | 
				
			||||||
 | 
							data.AddChild(&nl.Uint32Attribute{Type: nl.IPSET_ATTR_MAXELEM | nl.NLA_F_NET_BYTEORDER, Value: options.MaxElements})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if timeout := options.Timeout; timeout != nil {
 | 
				
			||||||
 | 
							data.AddChild(&nl.Uint32Attribute{Type: nl.IPSET_ATTR_TIMEOUT | nl.NLA_F_NET_BYTEORDER, Value: *timeout})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var cadtFlags uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if options.Comments {
 | 
				
			||||||
 | 
							cadtFlags |= nl.IPSET_FLAG_WITH_COMMENT
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if options.Counters {
 | 
				
			||||||
 | 
							cadtFlags |= nl.IPSET_FLAG_WITH_COUNTERS
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if options.Skbinfo {
 | 
				
			||||||
 | 
							cadtFlags |= nl.IPSET_FLAG_WITH_SKBINFO
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if cadtFlags != 0 {
 | 
				
			||||||
 | 
							data.AddChild(&nl.Uint32Attribute{Type: nl.IPSET_ATTR_CADT_FLAGS | nl.NLA_F_NET_BYTEORDER, Value: cadtFlags})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						req.AddData(data)
 | 
				
			||||||
 | 
						_, err := ipsetExecute(req)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) IpsetDestroy(setname string) error {
 | 
				
			||||||
 | 
						req := h.newIpsetRequest(nl.IPSET_CMD_DESTROY)
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_SETNAME, nl.ZeroTerminated(setname)))
 | 
				
			||||||
 | 
						_, err := ipsetExecute(req)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) IpsetFlush(setname string) error {
 | 
				
			||||||
 | 
						req := h.newIpsetRequest(nl.IPSET_CMD_FLUSH)
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_SETNAME, nl.ZeroTerminated(setname)))
 | 
				
			||||||
 | 
						_, err := ipsetExecute(req)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) IpsetSwap(setname, othersetname string) error {
 | 
				
			||||||
 | 
						req := h.newIpsetRequest(nl.IPSET_CMD_SWAP)
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_SETNAME, nl.ZeroTerminated(setname)))
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_TYPENAME, nl.ZeroTerminated(othersetname)))
 | 
				
			||||||
 | 
						_, err := ipsetExecute(req)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) IpsetList(name string) (*IPSetResult, error) {
 | 
				
			||||||
 | 
						req := h.newIpsetRequest(nl.IPSET_CMD_LIST)
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_SETNAME, nl.ZeroTerminated(name)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						msgs, err := ipsetExecute(req)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						result := ipsetUnserialize(msgs)
 | 
				
			||||||
 | 
						return &result, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) IpsetListAll() ([]IPSetResult, error) {
 | 
				
			||||||
 | 
						req := h.newIpsetRequest(nl.IPSET_CMD_LIST)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						msgs, err := ipsetExecute(req)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						result := make([]IPSetResult, len(msgs))
 | 
				
			||||||
 | 
						for i, msg := range msgs {
 | 
				
			||||||
 | 
							result[i].unserialize(msg)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IpsetAdd adds an entry to an existing ipset.
 | 
				
			||||||
 | 
					func (h *Handle) IpsetAdd(setname string, entry *IPSetEntry) error {
 | 
				
			||||||
 | 
						return h.ipsetAddDel(nl.IPSET_CMD_ADD, setname, entry)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IpsetDel deletes an entry from an existing ipset.
 | 
				
			||||||
 | 
					func (h *Handle) IpsetDel(setname string, entry *IPSetEntry) error {
 | 
				
			||||||
 | 
						return h.ipsetAddDel(nl.IPSET_CMD_DEL, setname, entry)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func encodeIP(ip net.IP) (*nl.RtAttr, error) {
 | 
				
			||||||
 | 
						typ := int(nl.NLA_F_NET_BYTEORDER)
 | 
				
			||||||
 | 
						if ip4 := ip.To4(); ip4 != nil {
 | 
				
			||||||
 | 
							typ |= nl.IPSET_ATTR_IPADDR_IPV4
 | 
				
			||||||
 | 
							ip = ip4
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							typ |= nl.IPSET_ATTR_IPADDR_IPV6
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nl.NewRtAttr(typ, ip), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func buildEntryData(entry *IPSetEntry) (*nl.RtAttr, error) {
 | 
				
			||||||
 | 
						data := nl.NewRtAttr(nl.IPSET_ATTR_DATA|int(nl.NLA_F_NESTED), nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if entry.Comment != "" {
 | 
				
			||||||
 | 
							data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_COMMENT, nl.ZeroTerminated(entry.Comment)))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if entry.Timeout != nil {
 | 
				
			||||||
 | 
							data.AddChild(&nl.Uint32Attribute{Type: nl.IPSET_ATTR_TIMEOUT | nl.NLA_F_NET_BYTEORDER, Value: *entry.Timeout})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if entry.IP != nil {
 | 
				
			||||||
 | 
							nestedData, err := encodeIP(entry.IP)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_IP|int(nl.NLA_F_NESTED), nestedData.Serialize()))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if entry.MAC != nil {
 | 
				
			||||||
 | 
							data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_ETHER, entry.MAC))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if entry.CIDR != 0 {
 | 
				
			||||||
 | 
							data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_CIDR, nl.Uint8Attr(entry.CIDR)))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if entry.IP2 != nil {
 | 
				
			||||||
 | 
							nestedData, err := encodeIP(entry.IP2)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_IP2|int(nl.NLA_F_NESTED), nestedData.Serialize()))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if entry.CIDR2 != 0 {
 | 
				
			||||||
 | 
							data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_CIDR2, nl.Uint8Attr(entry.CIDR2)))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if entry.Port != nil {
 | 
				
			||||||
 | 
							if entry.Protocol == nil {
 | 
				
			||||||
 | 
								// use tcp protocol as default
 | 
				
			||||||
 | 
								val := uint8(unix.IPPROTO_TCP)
 | 
				
			||||||
 | 
								entry.Protocol = &val
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_PROTO, nl.Uint8Attr(*entry.Protocol)))
 | 
				
			||||||
 | 
							buf := make([]byte, 2)
 | 
				
			||||||
 | 
							binary.BigEndian.PutUint16(buf, *entry.Port)
 | 
				
			||||||
 | 
							data.AddChild(nl.NewRtAttr(int(nl.IPSET_ATTR_PORT|nl.NLA_F_NET_BYTEORDER), buf))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if entry.IFace != "" {
 | 
				
			||||||
 | 
							data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_IFACE, nl.ZeroTerminated(entry.IFace)))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if entry.Mark != nil {
 | 
				
			||||||
 | 
							data.AddChild(&nl.Uint32Attribute{Type: nl.IPSET_ATTR_MARK | nl.NLA_F_NET_BYTEORDER, Value: *entry.Mark})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return data, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) ipsetAddDel(nlCmd int, setname string, entry *IPSetEntry) error {
 | 
				
			||||||
 | 
						req := h.newIpsetRequest(nlCmd)
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_SETNAME, nl.ZeroTerminated(setname)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !entry.Replace {
 | 
				
			||||||
 | 
							req.Flags |= unix.NLM_F_EXCL
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						data, err := buildEntryData(entry)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						data.AddChild(&nl.Uint32Attribute{Type: nl.IPSET_ATTR_LINENO | nl.NLA_F_NET_BYTEORDER, Value: 0})
 | 
				
			||||||
 | 
						req.AddData(data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err = ipsetExecute(req)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) IpsetTest(setname string, entry *IPSetEntry) (bool, error) {
 | 
				
			||||||
 | 
						req := h.newIpsetRequest(nl.IPSET_CMD_TEST)
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_SETNAME, nl.ZeroTerminated(setname)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !entry.Replace {
 | 
				
			||||||
 | 
							req.Flags |= unix.NLM_F_EXCL
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						data, err := buildEntryData(entry)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return false, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						req.AddData(data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err = ipsetExecute(req)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							if err == nl.IPSetError(nl.IPSET_ERR_EXIST) {
 | 
				
			||||||
 | 
								// not exist
 | 
				
			||||||
 | 
								return false, nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return false, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) newIpsetRequest(cmd int) *nl.NetlinkRequest {
 | 
				
			||||||
 | 
						req := h.newNetlinkRequest(cmd|(unix.NFNL_SUBSYS_IPSET<<8), nl.GetIpsetFlags(cmd))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Add the netfilter header
 | 
				
			||||||
 | 
						msg := &nl.Nfgenmsg{
 | 
				
			||||||
 | 
							NfgenFamily: uint8(unix.AF_NETLINK),
 | 
				
			||||||
 | 
							Version:     nl.NFNETLINK_V0,
 | 
				
			||||||
 | 
							ResId:       0,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						req.AddData(msg)
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_PROTOCOL, nl.Uint8Attr(nl.IPSET_PROTOCOL)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return req
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getIpsetDefaultWithTypeName(typename string) uint8 {
 | 
				
			||||||
 | 
						switch typename {
 | 
				
			||||||
 | 
						case "hash:ip,port",
 | 
				
			||||||
 | 
							"hash:ip,port,ip",
 | 
				
			||||||
 | 
							"hash:ip,port,net",
 | 
				
			||||||
 | 
							"hash:net,port":
 | 
				
			||||||
 | 
							return 1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ipsetExecute(req *nl.NetlinkRequest) (msgs [][]byte, err error) {
 | 
				
			||||||
 | 
						msgs, err = req.Execute(unix.NETLINK_NETFILTER, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							if errno := int(err.(syscall.Errno)); errno >= nl.IPSET_ERR_PRIVATE {
 | 
				
			||||||
 | 
								err = nl.IPSetError(uintptr(errno))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ipsetUnserialize(msgs [][]byte) (result IPSetResult) {
 | 
				
			||||||
 | 
						for _, msg := range msgs {
 | 
				
			||||||
 | 
							result.unserialize(msg)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return result
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (result *IPSetResult) unserialize(msg []byte) {
 | 
				
			||||||
 | 
						result.Nfgenmsg = nl.DeserializeNfgenmsg(msg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for attr := range nl.ParseAttributes(msg[4:]) {
 | 
				
			||||||
 | 
							switch attr.Type {
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_PROTOCOL:
 | 
				
			||||||
 | 
								result.Protocol = attr.Value[0]
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_SETNAME:
 | 
				
			||||||
 | 
								result.SetName = nl.BytesToString(attr.Value)
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_COMMENT:
 | 
				
			||||||
 | 
								result.Comment = nl.BytesToString(attr.Value)
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_TYPENAME:
 | 
				
			||||||
 | 
								result.TypeName = nl.BytesToString(attr.Value)
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_REVISION:
 | 
				
			||||||
 | 
								result.Revision = attr.Value[0]
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_FAMILY:
 | 
				
			||||||
 | 
								result.Family = attr.Value[0]
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_FLAGS:
 | 
				
			||||||
 | 
								result.Flags = attr.Value[0]
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_DATA | nl.NLA_F_NESTED:
 | 
				
			||||||
 | 
								result.parseAttrData(attr.Value)
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_ADT | nl.NLA_F_NESTED:
 | 
				
			||||||
 | 
								result.parseAttrADT(attr.Value)
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_PROTOCOL_MIN:
 | 
				
			||||||
 | 
								result.ProtocolMinVersion = attr.Value[0]
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_MARKMASK:
 | 
				
			||||||
 | 
								result.MarkMask = attr.Uint32()
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								log.Printf("unknown ipset attribute from kernel: %+v %v", attr, attr.Type&nl.NLA_TYPE_MASK)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (result *IPSetResult) parseAttrData(data []byte) {
 | 
				
			||||||
 | 
						for attr := range nl.ParseAttributes(data) {
 | 
				
			||||||
 | 
							switch attr.Type {
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_HASHSIZE | nl.NLA_F_NET_BYTEORDER:
 | 
				
			||||||
 | 
								result.HashSize = attr.Uint32()
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_MAXELEM | nl.NLA_F_NET_BYTEORDER:
 | 
				
			||||||
 | 
								result.MaxElements = attr.Uint32()
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_TIMEOUT | nl.NLA_F_NET_BYTEORDER:
 | 
				
			||||||
 | 
								val := attr.Uint32()
 | 
				
			||||||
 | 
								result.Timeout = &val
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_ELEMENTS | nl.NLA_F_NET_BYTEORDER:
 | 
				
			||||||
 | 
								result.NumEntries = attr.Uint32()
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_REFERENCES | nl.NLA_F_NET_BYTEORDER:
 | 
				
			||||||
 | 
								result.References = attr.Uint32()
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_MEMSIZE | nl.NLA_F_NET_BYTEORDER:
 | 
				
			||||||
 | 
								result.SizeInMemory = attr.Uint32()
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_CADT_FLAGS | nl.NLA_F_NET_BYTEORDER:
 | 
				
			||||||
 | 
								result.CadtFlags = attr.Uint32()
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_IP | nl.NLA_F_NESTED:
 | 
				
			||||||
 | 
								for nested := range nl.ParseAttributes(attr.Value) {
 | 
				
			||||||
 | 
									switch nested.Type {
 | 
				
			||||||
 | 
									case nl.IPSET_ATTR_IP | nl.NLA_F_NET_BYTEORDER:
 | 
				
			||||||
 | 
										result.Entries = append(result.Entries, IPSetEntry{IP: nested.Value})
 | 
				
			||||||
 | 
									case nl.IPSET_ATTR_IP:
 | 
				
			||||||
 | 
										result.IPFrom = nested.Value
 | 
				
			||||||
 | 
									default:
 | 
				
			||||||
 | 
										log.Printf("unknown nested ipset data attribute from kernel: %+v %v", nested, nested.Type&nl.NLA_TYPE_MASK)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_IP_TO | nl.NLA_F_NESTED:
 | 
				
			||||||
 | 
								for nested := range nl.ParseAttributes(attr.Value) {
 | 
				
			||||||
 | 
									switch nested.Type {
 | 
				
			||||||
 | 
									case nl.IPSET_ATTR_IP:
 | 
				
			||||||
 | 
										result.IPTo = nested.Value
 | 
				
			||||||
 | 
									default:
 | 
				
			||||||
 | 
										log.Printf("unknown nested ipset data attribute from kernel: %+v %v", nested, nested.Type&nl.NLA_TYPE_MASK)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_PORT_FROM | nl.NLA_F_NET_BYTEORDER:
 | 
				
			||||||
 | 
								result.PortFrom = networkOrder.Uint16(attr.Value)
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_PORT_TO | nl.NLA_F_NET_BYTEORDER:
 | 
				
			||||||
 | 
								result.PortTo = networkOrder.Uint16(attr.Value)
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_CADT_LINENO | nl.NLA_F_NET_BYTEORDER:
 | 
				
			||||||
 | 
								result.LineNo = attr.Uint32()
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_COMMENT:
 | 
				
			||||||
 | 
								result.Comment = nl.BytesToString(attr.Value)
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_MARKMASK:
 | 
				
			||||||
 | 
								result.MarkMask = attr.Uint32()
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								log.Printf("unknown ipset data attribute from kernel: %+v %v", attr, attr.Type&nl.NLA_TYPE_MASK)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (result *IPSetResult) parseAttrADT(data []byte) {
 | 
				
			||||||
 | 
						for attr := range nl.ParseAttributes(data) {
 | 
				
			||||||
 | 
							switch attr.Type {
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_DATA | nl.NLA_F_NESTED:
 | 
				
			||||||
 | 
								result.Entries = append(result.Entries, parseIPSetEntry(attr.Value))
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								log.Printf("unknown ADT attribute from kernel: %+v %v", attr, attr.Type&nl.NLA_TYPE_MASK)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseIPSetEntry(data []byte) (entry IPSetEntry) {
 | 
				
			||||||
 | 
						for attr := range nl.ParseAttributes(data) {
 | 
				
			||||||
 | 
							switch attr.Type {
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_TIMEOUT | nl.NLA_F_NET_BYTEORDER:
 | 
				
			||||||
 | 
								val := attr.Uint32()
 | 
				
			||||||
 | 
								entry.Timeout = &val
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_BYTES | nl.NLA_F_NET_BYTEORDER:
 | 
				
			||||||
 | 
								val := attr.Uint64()
 | 
				
			||||||
 | 
								entry.Bytes = &val
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_PACKETS | nl.NLA_F_NET_BYTEORDER:
 | 
				
			||||||
 | 
								val := attr.Uint64()
 | 
				
			||||||
 | 
								entry.Packets = &val
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_ETHER:
 | 
				
			||||||
 | 
								entry.MAC = net.HardwareAddr(attr.Value)
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_IP:
 | 
				
			||||||
 | 
								entry.IP = net.IP(attr.Value)
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_COMMENT:
 | 
				
			||||||
 | 
								entry.Comment = nl.BytesToString(attr.Value)
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_IP | nl.NLA_F_NESTED:
 | 
				
			||||||
 | 
								for attr := range nl.ParseAttributes(attr.Value) {
 | 
				
			||||||
 | 
									switch attr.Type {
 | 
				
			||||||
 | 
									case nl.IPSET_ATTR_IPADDR_IPV4, nl.IPSET_ATTR_IPADDR_IPV6:
 | 
				
			||||||
 | 
										entry.IP = net.IP(attr.Value)
 | 
				
			||||||
 | 
									default:
 | 
				
			||||||
 | 
										log.Printf("unknown nested ADT attribute from kernel: %+v", attr)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_IP2 | nl.NLA_F_NESTED:
 | 
				
			||||||
 | 
								for attr := range nl.ParseAttributes(attr.Value) {
 | 
				
			||||||
 | 
									switch attr.Type {
 | 
				
			||||||
 | 
									case nl.IPSET_ATTR_IPADDR_IPV4, nl.IPSET_ATTR_IPADDR_IPV6:
 | 
				
			||||||
 | 
										entry.IP2 = net.IP(attr.Value)
 | 
				
			||||||
 | 
									default:
 | 
				
			||||||
 | 
										log.Printf("unknown nested ADT attribute from kernel: %+v", attr)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_CIDR:
 | 
				
			||||||
 | 
								entry.CIDR = attr.Value[0]
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_CIDR2:
 | 
				
			||||||
 | 
								entry.CIDR2 = attr.Value[0]
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_PORT | nl.NLA_F_NET_BYTEORDER:
 | 
				
			||||||
 | 
								val := networkOrder.Uint16(attr.Value)
 | 
				
			||||||
 | 
								entry.Port = &val
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_PROTO:
 | 
				
			||||||
 | 
								val := attr.Value[0]
 | 
				
			||||||
 | 
								entry.Protocol = &val
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_IFACE:
 | 
				
			||||||
 | 
								entry.IFace = nl.BytesToString(attr.Value)
 | 
				
			||||||
 | 
							case nl.IPSET_ATTR_MARK | nl.NLA_F_NET_BYTEORDER:
 | 
				
			||||||
 | 
								val := attr.Uint32()
 | 
				
			||||||
 | 
								entry.Mark = &val
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								log.Printf("unknown ADT attribute from kernel: %+v", attr)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										381
									
								
								vendor/github.com/vishvananda/netlink/link.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										381
									
								
								vendor/github.com/vishvananda/netlink/link.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -33,19 +33,29 @@ type LinkAttrs struct {
 | 
				
			|||||||
	MasterIndex    int         // must be the index of a bridge
 | 
						MasterIndex    int         // must be the index of a bridge
 | 
				
			||||||
	Namespace      interface{} // nil | NsPid | NsFd
 | 
						Namespace      interface{} // nil | NsPid | NsFd
 | 
				
			||||||
	Alias          string
 | 
						Alias          string
 | 
				
			||||||
 | 
						AltNames       []string
 | 
				
			||||||
	Statistics     *LinkStatistics
 | 
						Statistics     *LinkStatistics
 | 
				
			||||||
	Promisc        int
 | 
						Promisc        int
 | 
				
			||||||
 | 
						Allmulti       int
 | 
				
			||||||
 | 
						Multi          int
 | 
				
			||||||
	Xdp            *LinkXdp
 | 
						Xdp            *LinkXdp
 | 
				
			||||||
	EncapType      string
 | 
						EncapType      string
 | 
				
			||||||
	Protinfo       *Protinfo
 | 
						Protinfo       *Protinfo
 | 
				
			||||||
	OperState      LinkOperState
 | 
						OperState      LinkOperState
 | 
				
			||||||
 | 
						PhysSwitchID   int
 | 
				
			||||||
	NetNsID        int
 | 
						NetNsID        int
 | 
				
			||||||
	NumTxQueues    int
 | 
						NumTxQueues    int
 | 
				
			||||||
	NumRxQueues    int
 | 
						NumRxQueues    int
 | 
				
			||||||
	GSOMaxSize   uint32
 | 
						TSOMaxSegs     uint32
 | 
				
			||||||
 | 
						TSOMaxSize     uint32
 | 
				
			||||||
	GSOMaxSegs     uint32
 | 
						GSOMaxSegs     uint32
 | 
				
			||||||
 | 
						GSOMaxSize     uint32
 | 
				
			||||||
 | 
						GROMaxSize     uint32
 | 
				
			||||||
 | 
						GSOIPv4MaxSize uint32
 | 
				
			||||||
 | 
						GROIPv4MaxSize uint32
 | 
				
			||||||
	Vfs            []VfInfo // virtual functions available on link
 | 
						Vfs            []VfInfo // virtual functions available on link
 | 
				
			||||||
	Group          uint32
 | 
						Group          uint32
 | 
				
			||||||
 | 
						PermHWAddr     net.HardwareAddr
 | 
				
			||||||
	Slave          LinkSlave
 | 
						Slave          LinkSlave
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -60,11 +70,23 @@ type VfInfo struct {
 | 
				
			|||||||
	Mac       net.HardwareAddr
 | 
						Mac       net.HardwareAddr
 | 
				
			||||||
	Vlan      int
 | 
						Vlan      int
 | 
				
			||||||
	Qos       int
 | 
						Qos       int
 | 
				
			||||||
 | 
						VlanProto int
 | 
				
			||||||
	TxRate    int // IFLA_VF_TX_RATE  Max TxRate
 | 
						TxRate    int // IFLA_VF_TX_RATE  Max TxRate
 | 
				
			||||||
	Spoofchk  bool
 | 
						Spoofchk  bool
 | 
				
			||||||
	LinkState uint32
 | 
						LinkState uint32
 | 
				
			||||||
	MaxTxRate uint32 // IFLA_VF_RATE Max TxRate
 | 
						MaxTxRate uint32 // IFLA_VF_RATE Max TxRate
 | 
				
			||||||
	MinTxRate uint32 // IFLA_VF_RATE Min TxRate
 | 
						MinTxRate uint32 // IFLA_VF_RATE Min TxRate
 | 
				
			||||||
 | 
						RxPackets uint64
 | 
				
			||||||
 | 
						TxPackets uint64
 | 
				
			||||||
 | 
						RxBytes   uint64
 | 
				
			||||||
 | 
						TxBytes   uint64
 | 
				
			||||||
 | 
						Multicast uint64
 | 
				
			||||||
 | 
						Broadcast uint64
 | 
				
			||||||
 | 
						RxDropped uint64
 | 
				
			||||||
 | 
						TxDropped uint64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						RssQuery uint32
 | 
				
			||||||
 | 
						Trust    uint32
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// LinkOperState represents the values of the IFLA_OPERSTATE link
 | 
					// LinkOperState represents the values of the IFLA_OPERSTATE link
 | 
				
			||||||
@@ -103,6 +125,7 @@ func (s LinkOperState) String() string {
 | 
				
			|||||||
// NewLinkAttrs returns LinkAttrs structure filled with default values
 | 
					// NewLinkAttrs returns LinkAttrs structure filled with default values
 | 
				
			||||||
func NewLinkAttrs() LinkAttrs {
 | 
					func NewLinkAttrs() LinkAttrs {
 | 
				
			||||||
	return LinkAttrs{
 | 
						return LinkAttrs{
 | 
				
			||||||
 | 
							NetNsID: -1,
 | 
				
			||||||
		TxQLen:  -1,
 | 
							TxQLen:  -1,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -198,6 +221,7 @@ type LinkStatistics64 struct {
 | 
				
			|||||||
type LinkXdp struct {
 | 
					type LinkXdp struct {
 | 
				
			||||||
	Fd         int
 | 
						Fd         int
 | 
				
			||||||
	Attached   bool
 | 
						Attached   bool
 | 
				
			||||||
 | 
						AttachMode uint32
 | 
				
			||||||
	Flags      uint32
 | 
						Flags      uint32
 | 
				
			||||||
	ProgId     uint32
 | 
						ProgId     uint32
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -246,8 +270,11 @@ func (ifb *Ifb) Type() string {
 | 
				
			|||||||
type Bridge struct {
 | 
					type Bridge struct {
 | 
				
			||||||
	LinkAttrs
 | 
						LinkAttrs
 | 
				
			||||||
	MulticastSnooping *bool
 | 
						MulticastSnooping *bool
 | 
				
			||||||
 | 
						AgeingTime        *uint32
 | 
				
			||||||
	HelloTime         *uint32
 | 
						HelloTime         *uint32
 | 
				
			||||||
	VlanFiltering     *bool
 | 
						VlanFiltering     *bool
 | 
				
			||||||
 | 
						VlanDefaultPVID   *uint16
 | 
				
			||||||
 | 
						GroupFwdMask      *uint16
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (bridge *Bridge) Attrs() *LinkAttrs {
 | 
					func (bridge *Bridge) Attrs() *LinkAttrs {
 | 
				
			||||||
@@ -291,6 +318,9 @@ type Macvlan struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// MACAddrs is only populated for Macvlan SOURCE links
 | 
						// MACAddrs is only populated for Macvlan SOURCE links
 | 
				
			||||||
	MACAddrs []net.HardwareAddr
 | 
						MACAddrs []net.HardwareAddr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BCQueueLen     uint32
 | 
				
			||||||
 | 
						UsedBCQueueLen uint32
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (macvlan *Macvlan) Attrs() *LinkAttrs {
 | 
					func (macvlan *Macvlan) Attrs() *LinkAttrs {
 | 
				
			||||||
@@ -333,11 +363,52 @@ func (tuntap *Tuntap) Type() string {
 | 
				
			|||||||
	return "tuntap"
 | 
						return "tuntap"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type NetkitMode uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						NETKIT_MODE_L2 NetkitMode = iota
 | 
				
			||||||
 | 
						NETKIT_MODE_L3
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type NetkitPolicy int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						NETKIT_POLICY_FORWARD   NetkitPolicy = 0
 | 
				
			||||||
 | 
						NETKIT_POLICY_BLACKHOLE NetkitPolicy = 2
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (n *Netkit) IsPrimary() bool {
 | 
				
			||||||
 | 
						return n.isPrimary
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetPeerAttrs will not take effect if trying to modify an existing netkit device
 | 
				
			||||||
 | 
					func (n *Netkit) SetPeerAttrs(Attrs *LinkAttrs) {
 | 
				
			||||||
 | 
						n.peerLinkAttrs = *Attrs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Netkit struct {
 | 
				
			||||||
 | 
						LinkAttrs
 | 
				
			||||||
 | 
						Mode          NetkitMode
 | 
				
			||||||
 | 
						Policy        NetkitPolicy
 | 
				
			||||||
 | 
						PeerPolicy    NetkitPolicy
 | 
				
			||||||
 | 
						isPrimary     bool
 | 
				
			||||||
 | 
						peerLinkAttrs LinkAttrs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (n *Netkit) Attrs() *LinkAttrs {
 | 
				
			||||||
 | 
						return &n.LinkAttrs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (n *Netkit) Type() string {
 | 
				
			||||||
 | 
						return "netkit"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Veth devices must specify PeerName on create
 | 
					// Veth devices must specify PeerName on create
 | 
				
			||||||
type Veth struct {
 | 
					type Veth struct {
 | 
				
			||||||
	LinkAttrs
 | 
						LinkAttrs
 | 
				
			||||||
	PeerName         string // veth on create only
 | 
						PeerName         string // veth on create only
 | 
				
			||||||
	PeerHardwareAddr net.HardwareAddr
 | 
						PeerHardwareAddr net.HardwareAddr
 | 
				
			||||||
 | 
						PeerNamespace    interface{}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (veth *Veth) Attrs() *LinkAttrs {
 | 
					func (veth *Veth) Attrs() *LinkAttrs {
 | 
				
			||||||
@@ -348,6 +419,19 @@ func (veth *Veth) Type() string {
 | 
				
			|||||||
	return "veth"
 | 
						return "veth"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Wireguard represent links of type "wireguard", see https://www.wireguard.com/
 | 
				
			||||||
 | 
					type Wireguard struct {
 | 
				
			||||||
 | 
						LinkAttrs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (wg *Wireguard) Attrs() *LinkAttrs {
 | 
				
			||||||
 | 
						return &wg.LinkAttrs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (wg *Wireguard) Type() string {
 | 
				
			||||||
 | 
						return "wireguard"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GenericLink links represent types that are not currently understood
 | 
					// GenericLink links represent types that are not currently understood
 | 
				
			||||||
// by this netlink library.
 | 
					// by this netlink library.
 | 
				
			||||||
type GenericLink struct {
 | 
					type GenericLink struct {
 | 
				
			||||||
@@ -428,6 +512,19 @@ func (ipvlan *IPVlan) Type() string {
 | 
				
			|||||||
	return "ipvlan"
 | 
						return "ipvlan"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IPVtap - IPVtap is a virtual interfaces based on ipvlan
 | 
				
			||||||
 | 
					type IPVtap struct {
 | 
				
			||||||
 | 
						IPVlan
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ipvtap *IPVtap) Attrs() *LinkAttrs {
 | 
				
			||||||
 | 
						return &ipvtap.LinkAttrs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ipvtap IPVtap) Type() string {
 | 
				
			||||||
 | 
						return "ipvtap"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// VlanProtocol type
 | 
					// VlanProtocol type
 | 
				
			||||||
type VlanProtocol int
 | 
					type VlanProtocol int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -527,6 +624,27 @@ const (
 | 
				
			|||||||
	BOND_ARP_VALIDATE_ALL
 | 
						BOND_ARP_VALIDATE_ALL
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var bondArpValidateToString = map[BondArpValidate]string{
 | 
				
			||||||
 | 
						BOND_ARP_VALIDATE_NONE:   "none",
 | 
				
			||||||
 | 
						BOND_ARP_VALIDATE_ACTIVE: "active",
 | 
				
			||||||
 | 
						BOND_ARP_VALIDATE_BACKUP: "backup",
 | 
				
			||||||
 | 
						BOND_ARP_VALIDATE_ALL:    "none",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					var StringToBondArpValidateMap = map[string]BondArpValidate{
 | 
				
			||||||
 | 
						"none":   BOND_ARP_VALIDATE_NONE,
 | 
				
			||||||
 | 
						"active": BOND_ARP_VALIDATE_ACTIVE,
 | 
				
			||||||
 | 
						"backup": BOND_ARP_VALIDATE_BACKUP,
 | 
				
			||||||
 | 
						"all":    BOND_ARP_VALIDATE_ALL,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (b BondArpValidate) String() string {
 | 
				
			||||||
 | 
						s, ok := bondArpValidateToString[b]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return fmt.Sprintf("BondArpValidate(%d)", b)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// BondPrimaryReselect type
 | 
					// BondPrimaryReselect type
 | 
				
			||||||
type BondPrimaryReselect int
 | 
					type BondPrimaryReselect int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -537,6 +655,25 @@ const (
 | 
				
			|||||||
	BOND_PRIMARY_RESELECT_FAILURE
 | 
						BOND_PRIMARY_RESELECT_FAILURE
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var bondPrimaryReselectToString = map[BondPrimaryReselect]string{
 | 
				
			||||||
 | 
						BOND_PRIMARY_RESELECT_ALWAYS:  "always",
 | 
				
			||||||
 | 
						BOND_PRIMARY_RESELECT_BETTER:  "better",
 | 
				
			||||||
 | 
						BOND_PRIMARY_RESELECT_FAILURE: "failure",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					var StringToBondPrimaryReselectMap = map[string]BondPrimaryReselect{
 | 
				
			||||||
 | 
						"always":  BOND_PRIMARY_RESELECT_ALWAYS,
 | 
				
			||||||
 | 
						"better":  BOND_PRIMARY_RESELECT_BETTER,
 | 
				
			||||||
 | 
						"failure": BOND_PRIMARY_RESELECT_FAILURE,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (b BondPrimaryReselect) String() string {
 | 
				
			||||||
 | 
						s, ok := bondPrimaryReselectToString[b]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return fmt.Sprintf("BondPrimaryReselect(%d)", b)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// BondArpAllTargets type
 | 
					// BondArpAllTargets type
 | 
				
			||||||
type BondArpAllTargets int
 | 
					type BondArpAllTargets int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -546,6 +683,23 @@ const (
 | 
				
			|||||||
	BOND_ARP_ALL_TARGETS_ALL
 | 
						BOND_ARP_ALL_TARGETS_ALL
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var bondArpAllTargetsToString = map[BondArpAllTargets]string{
 | 
				
			||||||
 | 
						BOND_ARP_ALL_TARGETS_ANY: "any",
 | 
				
			||||||
 | 
						BOND_ARP_ALL_TARGETS_ALL: "all",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					var StringToBondArpAllTargetsMap = map[string]BondArpAllTargets{
 | 
				
			||||||
 | 
						"any": BOND_ARP_ALL_TARGETS_ANY,
 | 
				
			||||||
 | 
						"all": BOND_ARP_ALL_TARGETS_ALL,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (b BondArpAllTargets) String() string {
 | 
				
			||||||
 | 
						s, ok := bondArpAllTargetsToString[b]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return fmt.Sprintf("BondArpAllTargets(%d)", b)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// BondFailOverMac type
 | 
					// BondFailOverMac type
 | 
				
			||||||
type BondFailOverMac int
 | 
					type BondFailOverMac int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -556,6 +710,25 @@ const (
 | 
				
			|||||||
	BOND_FAIL_OVER_MAC_FOLLOW
 | 
						BOND_FAIL_OVER_MAC_FOLLOW
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var bondFailOverMacToString = map[BondFailOverMac]string{
 | 
				
			||||||
 | 
						BOND_FAIL_OVER_MAC_NONE:   "none",
 | 
				
			||||||
 | 
						BOND_FAIL_OVER_MAC_ACTIVE: "active",
 | 
				
			||||||
 | 
						BOND_FAIL_OVER_MAC_FOLLOW: "follow",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					var StringToBondFailOverMacMap = map[string]BondFailOverMac{
 | 
				
			||||||
 | 
						"none":   BOND_FAIL_OVER_MAC_NONE,
 | 
				
			||||||
 | 
						"active": BOND_FAIL_OVER_MAC_ACTIVE,
 | 
				
			||||||
 | 
						"follow": BOND_FAIL_OVER_MAC_FOLLOW,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (b BondFailOverMac) String() string {
 | 
				
			||||||
 | 
						s, ok := bondFailOverMacToString[b]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return fmt.Sprintf("BondFailOverMac(%d)", b)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// BondXmitHashPolicy type
 | 
					// BondXmitHashPolicy type
 | 
				
			||||||
type BondXmitHashPolicy int
 | 
					type BondXmitHashPolicy int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -583,6 +756,7 @@ const (
 | 
				
			|||||||
	BOND_XMIT_HASH_POLICY_LAYER2_3
 | 
						BOND_XMIT_HASH_POLICY_LAYER2_3
 | 
				
			||||||
	BOND_XMIT_HASH_POLICY_ENCAP2_3
 | 
						BOND_XMIT_HASH_POLICY_ENCAP2_3
 | 
				
			||||||
	BOND_XMIT_HASH_POLICY_ENCAP3_4
 | 
						BOND_XMIT_HASH_POLICY_ENCAP3_4
 | 
				
			||||||
 | 
						BOND_XMIT_HASH_POLICY_VLAN_SRCMAC
 | 
				
			||||||
	BOND_XMIT_HASH_POLICY_UNKNOWN
 | 
						BOND_XMIT_HASH_POLICY_UNKNOWN
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -592,6 +766,7 @@ var bondXmitHashPolicyToString = map[BondXmitHashPolicy]string{
 | 
				
			|||||||
	BOND_XMIT_HASH_POLICY_LAYER2_3: "layer2+3",
 | 
						BOND_XMIT_HASH_POLICY_LAYER2_3: "layer2+3",
 | 
				
			||||||
	BOND_XMIT_HASH_POLICY_ENCAP2_3: "encap2+3",
 | 
						BOND_XMIT_HASH_POLICY_ENCAP2_3: "encap2+3",
 | 
				
			||||||
	BOND_XMIT_HASH_POLICY_ENCAP3_4: "encap3+4",
 | 
						BOND_XMIT_HASH_POLICY_ENCAP3_4: "encap3+4",
 | 
				
			||||||
 | 
						BOND_XMIT_HASH_POLICY_VLAN_SRCMAC: "vlan+srcmac",
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
var StringToBondXmitHashPolicyMap = map[string]BondXmitHashPolicy{
 | 
					var StringToBondXmitHashPolicyMap = map[string]BondXmitHashPolicy{
 | 
				
			||||||
	"layer2":   BOND_XMIT_HASH_POLICY_LAYER2,
 | 
						"layer2":   BOND_XMIT_HASH_POLICY_LAYER2,
 | 
				
			||||||
@@ -599,6 +774,7 @@ var StringToBondXmitHashPolicyMap = map[string]BondXmitHashPolicy{
 | 
				
			|||||||
	"layer2+3": BOND_XMIT_HASH_POLICY_LAYER2_3,
 | 
						"layer2+3": BOND_XMIT_HASH_POLICY_LAYER2_3,
 | 
				
			||||||
	"encap2+3": BOND_XMIT_HASH_POLICY_ENCAP2_3,
 | 
						"encap2+3": BOND_XMIT_HASH_POLICY_ENCAP2_3,
 | 
				
			||||||
	"encap3+4": BOND_XMIT_HASH_POLICY_ENCAP3_4,
 | 
						"encap3+4": BOND_XMIT_HASH_POLICY_ENCAP3_4,
 | 
				
			||||||
 | 
						"vlan+srcmac": BOND_XMIT_HASH_POLICY_VLAN_SRCMAC,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// BondLacpRate type
 | 
					// BondLacpRate type
 | 
				
			||||||
@@ -647,6 +823,25 @@ const (
 | 
				
			|||||||
	BOND_AD_SELECT_COUNT
 | 
						BOND_AD_SELECT_COUNT
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var bondAdSelectToString = map[BondAdSelect]string{
 | 
				
			||||||
 | 
						BOND_AD_SELECT_STABLE:    "stable",
 | 
				
			||||||
 | 
						BOND_AD_SELECT_BANDWIDTH: "bandwidth",
 | 
				
			||||||
 | 
						BOND_AD_SELECT_COUNT:     "count",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					var StringToBondAdSelectMap = map[string]BondAdSelect{
 | 
				
			||||||
 | 
						"stable":    BOND_AD_SELECT_STABLE,
 | 
				
			||||||
 | 
						"bandwidth": BOND_AD_SELECT_BANDWIDTH,
 | 
				
			||||||
 | 
						"count":     BOND_AD_SELECT_COUNT,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (b BondAdSelect) String() string {
 | 
				
			||||||
 | 
						s, ok := bondAdSelectToString[b]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return fmt.Sprintf("BondAdSelect(%d)", b)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return s
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// BondAdInfo represents ad info for bond
 | 
					// BondAdInfo represents ad info for bond
 | 
				
			||||||
type BondAdInfo struct {
 | 
					type BondAdInfo struct {
 | 
				
			||||||
	AggregatorId int
 | 
						AggregatorId int
 | 
				
			||||||
@@ -678,7 +873,7 @@ type Bond struct {
 | 
				
			|||||||
	AllSlavesActive int
 | 
						AllSlavesActive int
 | 
				
			||||||
	MinLinks        int
 | 
						MinLinks        int
 | 
				
			||||||
	LpInterval      int
 | 
						LpInterval      int
 | 
				
			||||||
	PackersPerSlave int
 | 
						PacketsPerSlave int
 | 
				
			||||||
	LacpRate        BondLacpRate
 | 
						LacpRate        BondLacpRate
 | 
				
			||||||
	AdSelect        BondAdSelect
 | 
						AdSelect        BondAdSelect
 | 
				
			||||||
	// looking at iproute tool AdInfo can only be retrived. It can't be set.
 | 
						// looking at iproute tool AdInfo can only be retrived. It can't be set.
 | 
				
			||||||
@@ -711,7 +906,7 @@ func NewLinkBond(atr LinkAttrs) *Bond {
 | 
				
			|||||||
		AllSlavesActive: -1,
 | 
							AllSlavesActive: -1,
 | 
				
			||||||
		MinLinks:        -1,
 | 
							MinLinks:        -1,
 | 
				
			||||||
		LpInterval:      -1,
 | 
							LpInterval:      -1,
 | 
				
			||||||
		PackersPerSlave: -1,
 | 
							PacketsPerSlave: -1,
 | 
				
			||||||
		LacpRate:        -1,
 | 
							LacpRate:        -1,
 | 
				
			||||||
		AdSelect:        -1,
 | 
							AdSelect:        -1,
 | 
				
			||||||
		AdActorSysPrio:  -1,
 | 
							AdActorSysPrio:  -1,
 | 
				
			||||||
@@ -761,8 +956,10 @@ func (bond *Bond) Type() string {
 | 
				
			|||||||
type BondSlaveState uint8
 | 
					type BondSlaveState uint8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	BondStateActive = iota // Link is active.
 | 
						//BondStateActive Link is active.
 | 
				
			||||||
	BondStateBackup        // Link is backup.
 | 
						BondStateActive BondSlaveState = iota
 | 
				
			||||||
 | 
						//BondStateBackup Link is backup.
 | 
				
			||||||
 | 
						BondStateBackup
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s BondSlaveState) String() string {
 | 
					func (s BondSlaveState) String() string {
 | 
				
			||||||
@@ -776,15 +973,19 @@ func (s BondSlaveState) String() string {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// BondSlaveState represents the values of the IFLA_BOND_SLAVE_MII_STATUS bond slave
 | 
					// BondSlaveMiiStatus represents the values of the IFLA_BOND_SLAVE_MII_STATUS bond slave
 | 
				
			||||||
// attribute, which contains the status of MII link monitoring
 | 
					// attribute, which contains the status of MII link monitoring
 | 
				
			||||||
type BondSlaveMiiStatus uint8
 | 
					type BondSlaveMiiStatus uint8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	BondLinkUp   = iota // link is up and running.
 | 
						//BondLinkUp link is up and running.
 | 
				
			||||||
	BondLinkFail        // link has just gone down.
 | 
						BondLinkUp BondSlaveMiiStatus = iota
 | 
				
			||||||
	BondLinkDown        // link has been down for too long time.
 | 
						//BondLinkFail link has just gone down.
 | 
				
			||||||
	BondLinkBack        // link is going back.
 | 
						BondLinkFail
 | 
				
			||||||
 | 
						//BondLinkDown link has been down for too long time.
 | 
				
			||||||
 | 
						BondLinkDown
 | 
				
			||||||
 | 
						//BondLinkBack link is going back.
 | 
				
			||||||
 | 
						BondLinkBack
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s BondSlaveMiiStatus) String() string {
 | 
					func (s BondSlaveMiiStatus) String() string {
 | 
				
			||||||
@@ -817,6 +1018,49 @@ func (b *BondSlave) SlaveType() string {
 | 
				
			|||||||
	return "bond"
 | 
						return "bond"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type VrfSlave struct {
 | 
				
			||||||
 | 
						Table uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (v *VrfSlave) SlaveType() string {
 | 
				
			||||||
 | 
						return "vrf"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Geneve devices must specify RemoteIP and ID (VNI) on create
 | 
				
			||||||
 | 
					// https://github.com/torvalds/linux/blob/47ec5303d73ea344e84f46660fff693c57641386/drivers/net/geneve.c#L1209-L1223
 | 
				
			||||||
 | 
					type Geneve struct {
 | 
				
			||||||
 | 
						LinkAttrs
 | 
				
			||||||
 | 
						ID                uint32 // vni
 | 
				
			||||||
 | 
						Remote            net.IP
 | 
				
			||||||
 | 
						Ttl               uint8
 | 
				
			||||||
 | 
						Tos               uint8
 | 
				
			||||||
 | 
						Dport             uint16
 | 
				
			||||||
 | 
						UdpCsum           uint8
 | 
				
			||||||
 | 
						UdpZeroCsum6Tx    uint8
 | 
				
			||||||
 | 
						UdpZeroCsum6Rx    uint8
 | 
				
			||||||
 | 
						Link              uint32
 | 
				
			||||||
 | 
						FlowBased         bool
 | 
				
			||||||
 | 
						InnerProtoInherit bool
 | 
				
			||||||
 | 
						Df                GeneveDf
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (geneve *Geneve) Attrs() *LinkAttrs {
 | 
				
			||||||
 | 
						return &geneve.LinkAttrs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (geneve *Geneve) Type() string {
 | 
				
			||||||
 | 
						return "geneve"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type GeneveDf uint8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						GENEVE_DF_UNSET GeneveDf = iota
 | 
				
			||||||
 | 
						GENEVE_DF_SET
 | 
				
			||||||
 | 
						GENEVE_DF_INHERIT
 | 
				
			||||||
 | 
						GENEVE_DF_MAX
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Gretap devices must specify LocalIP and RemoteIP on create
 | 
					// Gretap devices must specify LocalIP and RemoteIP on create
 | 
				
			||||||
type Gretap struct {
 | 
					type Gretap struct {
 | 
				
			||||||
	LinkAttrs
 | 
						LinkAttrs
 | 
				
			||||||
@@ -861,6 +1105,7 @@ type Iptun struct {
 | 
				
			|||||||
	EncapType  uint16
 | 
						EncapType  uint16
 | 
				
			||||||
	EncapFlags uint16
 | 
						EncapFlags uint16
 | 
				
			||||||
	FlowBased  bool
 | 
						FlowBased  bool
 | 
				
			||||||
 | 
						Proto      uint8
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (iptun *Iptun) Attrs() *LinkAttrs {
 | 
					func (iptun *Iptun) Attrs() *LinkAttrs {
 | 
				
			||||||
@@ -878,10 +1123,15 @@ type Ip6tnl struct {
 | 
				
			|||||||
	Remote     net.IP
 | 
						Remote     net.IP
 | 
				
			||||||
	Ttl        uint8
 | 
						Ttl        uint8
 | 
				
			||||||
	Tos        uint8
 | 
						Tos        uint8
 | 
				
			||||||
	EncapLimit uint8
 | 
					 | 
				
			||||||
	Flags      uint32
 | 
						Flags      uint32
 | 
				
			||||||
	Proto      uint8
 | 
						Proto      uint8
 | 
				
			||||||
	FlowInfo   uint32
 | 
						FlowInfo   uint32
 | 
				
			||||||
 | 
						EncapLimit uint8
 | 
				
			||||||
 | 
						EncapType  uint16
 | 
				
			||||||
 | 
						EncapFlags uint16
 | 
				
			||||||
 | 
						EncapSport uint16
 | 
				
			||||||
 | 
						EncapDport uint16
 | 
				
			||||||
 | 
						FlowBased  bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ip6tnl *Ip6tnl) Attrs() *LinkAttrs {
 | 
					func (ip6tnl *Ip6tnl) Attrs() *LinkAttrs {
 | 
				
			||||||
@@ -892,14 +1142,47 @@ func (ip6tnl *Ip6tnl) Type() string {
 | 
				
			|||||||
	return "ip6tnl"
 | 
						return "ip6tnl"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// from https://elixir.bootlin.com/linux/v5.15.4/source/include/uapi/linux/if_tunnel.h#L84
 | 
				
			||||||
 | 
					type TunnelEncapType uint16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						None TunnelEncapType = iota
 | 
				
			||||||
 | 
						FOU
 | 
				
			||||||
 | 
						GUE
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// from https://elixir.bootlin.com/linux/v5.15.4/source/include/uapi/linux/if_tunnel.h#L91
 | 
				
			||||||
 | 
					type TunnelEncapFlag uint16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						CSum    TunnelEncapFlag = 1 << 0
 | 
				
			||||||
 | 
						CSum6                   = 1 << 1
 | 
				
			||||||
 | 
						RemCSum                 = 1 << 2
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// from https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/ip6_tunnel.h#L12
 | 
				
			||||||
 | 
					type IP6TunnelFlag uint16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						IP6_TNL_F_IGN_ENCAP_LIMIT    IP6TunnelFlag = 1  // don't add encapsulation limit if one isn't present in inner packet
 | 
				
			||||||
 | 
						IP6_TNL_F_USE_ORIG_TCLASS                  = 2  // copy the traffic class field from the inner packet
 | 
				
			||||||
 | 
						IP6_TNL_F_USE_ORIG_FLOWLABEL               = 4  // copy the flowlabel from the inner packet
 | 
				
			||||||
 | 
						IP6_TNL_F_MIP6_DEV                         = 8  // being used for Mobile IPv6
 | 
				
			||||||
 | 
						IP6_TNL_F_RCV_DSCP_COPY                    = 10 // copy DSCP from the outer packet
 | 
				
			||||||
 | 
						IP6_TNL_F_USE_ORIG_FWMARK                  = 20 // copy fwmark from inner packet
 | 
				
			||||||
 | 
						IP6_TNL_F_ALLOW_LOCAL_REMOTE               = 40 // allow remote endpoint on the local node
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Sittun struct {
 | 
					type Sittun struct {
 | 
				
			||||||
	LinkAttrs
 | 
						LinkAttrs
 | 
				
			||||||
	Link       uint32
 | 
						Link       uint32
 | 
				
			||||||
	Local      net.IP
 | 
					 | 
				
			||||||
	Remote     net.IP
 | 
					 | 
				
			||||||
	Ttl        uint8
 | 
						Ttl        uint8
 | 
				
			||||||
	Tos        uint8
 | 
						Tos        uint8
 | 
				
			||||||
	PMtuDisc   uint8
 | 
						PMtuDisc   uint8
 | 
				
			||||||
 | 
						Proto      uint8
 | 
				
			||||||
 | 
						Local      net.IP
 | 
				
			||||||
 | 
						Remote     net.IP
 | 
				
			||||||
 | 
						EncapLimit uint8
 | 
				
			||||||
	EncapType  uint16
 | 
						EncapType  uint16
 | 
				
			||||||
	EncapFlags uint16
 | 
						EncapFlags uint16
 | 
				
			||||||
	EncapSport uint16
 | 
						EncapSport uint16
 | 
				
			||||||
@@ -950,6 +1233,7 @@ type Gretun struct {
 | 
				
			|||||||
	EncapFlags uint16
 | 
						EncapFlags uint16
 | 
				
			||||||
	EncapSport uint16
 | 
						EncapSport uint16
 | 
				
			||||||
	EncapDport uint16
 | 
						EncapDport uint16
 | 
				
			||||||
 | 
						FlowBased  bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (gretun *Gretun) Attrs() *LinkAttrs {
 | 
					func (gretun *Gretun) Attrs() *LinkAttrs {
 | 
				
			||||||
@@ -993,6 +1277,7 @@ func (gtp *GTP) Type() string {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Virtual XFRM Interfaces
 | 
					// Virtual XFRM Interfaces
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
//	Named "xfrmi" to prevent confusion with XFRM objects
 | 
					//	Named "xfrmi" to prevent confusion with XFRM objects
 | 
				
			||||||
type Xfrmi struct {
 | 
					type Xfrmi struct {
 | 
				
			||||||
	LinkAttrs
 | 
						LinkAttrs
 | 
				
			||||||
@@ -1034,6 +1319,58 @@ var StringToIPoIBMode = map[string]IPoIBMode{
 | 
				
			|||||||
	"connected": IPOIB_MODE_CONNECTED,
 | 
						"connected": IPOIB_MODE_CONNECTED,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						CAN_STATE_ERROR_ACTIVE = iota
 | 
				
			||||||
 | 
						CAN_STATE_ERROR_WARNING
 | 
				
			||||||
 | 
						CAN_STATE_ERROR_PASSIVE
 | 
				
			||||||
 | 
						CAN_STATE_BUS_OFF
 | 
				
			||||||
 | 
						CAN_STATE_STOPPED
 | 
				
			||||||
 | 
						CAN_STATE_SLEEPING
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Can struct {
 | 
				
			||||||
 | 
						LinkAttrs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BitRate            uint32
 | 
				
			||||||
 | 
						SamplePoint        uint32
 | 
				
			||||||
 | 
						TimeQuanta         uint32
 | 
				
			||||||
 | 
						PropagationSegment uint32
 | 
				
			||||||
 | 
						PhaseSegment1      uint32
 | 
				
			||||||
 | 
						PhaseSegment2      uint32
 | 
				
			||||||
 | 
						SyncJumpWidth      uint32
 | 
				
			||||||
 | 
						BitRatePreScaler   uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Name                string
 | 
				
			||||||
 | 
						TimeSegment1Min     uint32
 | 
				
			||||||
 | 
						TimeSegment1Max     uint32
 | 
				
			||||||
 | 
						TimeSegment2Min     uint32
 | 
				
			||||||
 | 
						TimeSegment2Max     uint32
 | 
				
			||||||
 | 
						SyncJumpWidthMax    uint32
 | 
				
			||||||
 | 
						BitRatePreScalerMin uint32
 | 
				
			||||||
 | 
						BitRatePreScalerMax uint32
 | 
				
			||||||
 | 
						BitRatePreScalerInc uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ClockFrequency uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						State uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Mask  uint32
 | 
				
			||||||
 | 
						Flags uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TxError uint16
 | 
				
			||||||
 | 
						RxError uint16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						RestartMs uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (can *Can) Attrs() *LinkAttrs {
 | 
				
			||||||
 | 
						return &can.LinkAttrs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (can *Can) Type() string {
 | 
				
			||||||
 | 
						return "can"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type IPoIB struct {
 | 
					type IPoIB struct {
 | 
				
			||||||
	LinkAttrs
 | 
						LinkAttrs
 | 
				
			||||||
	Pkey   uint16
 | 
						Pkey   uint16
 | 
				
			||||||
@@ -1049,11 +1386,27 @@ func (ipoib *IPoIB) Type() string {
 | 
				
			|||||||
	return "ipoib"
 | 
						return "ipoib"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type BareUDP struct {
 | 
				
			||||||
 | 
						LinkAttrs
 | 
				
			||||||
 | 
						Port       uint16
 | 
				
			||||||
 | 
						EtherType  uint16
 | 
				
			||||||
 | 
						SrcPortMin uint16
 | 
				
			||||||
 | 
						MultiProto bool
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (bareudp *BareUDP) Attrs() *LinkAttrs {
 | 
				
			||||||
 | 
						return &bareudp.LinkAttrs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (bareudp *BareUDP) Type() string {
 | 
				
			||||||
 | 
						return "bareudp"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// iproute2 supported devices;
 | 
					// iproute2 supported devices;
 | 
				
			||||||
// vlan | veth | vcan | dummy | ifb | macvlan | macvtap |
 | 
					// vlan | veth | vcan | dummy | ifb | macvlan | macvtap |
 | 
				
			||||||
// bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan |
 | 
					// bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan |
 | 
				
			||||||
// gre | gretap | ip6gre | ip6gretap | vti | vti6 | nlmon |
 | 
					// gre | gretap | ip6gre | ip6gretap | vti | vti6 | nlmon |
 | 
				
			||||||
// bond_slave | ipvlan | xfrm
 | 
					// bond_slave | ipvlan | xfrm | bareudp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// LinkNotFoundError wraps the various not found errors when
 | 
					// LinkNotFoundError wraps the various not found errors when
 | 
				
			||||||
// getting/reading links. This is intended for better error
 | 
					// getting/reading links. This is intended for better error
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1079
									
								
								vendor/github.com/vishvananda/netlink/link_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1079
									
								
								vendor/github.com/vishvananda/netlink/link_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1
									
								
								vendor/github.com/vishvananda/netlink/neigh.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/vishvananda/netlink/neigh.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -12,6 +12,7 @@ type Neigh struct {
 | 
				
			|||||||
	State        int
 | 
						State        int
 | 
				
			||||||
	Type         int
 | 
						Type         int
 | 
				
			||||||
	Flags        int
 | 
						Flags        int
 | 
				
			||||||
 | 
						FlagsExt     int
 | 
				
			||||||
	IP           net.IP
 | 
						IP           net.IP
 | 
				
			||||||
	HardwareAddr net.HardwareAddr
 | 
						HardwareAddr net.HardwareAddr
 | 
				
			||||||
	LLIPAddr     net.IP //Used in the case of NHRP
 | 
						LLIPAddr     net.IP //Used in the case of NHRP
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										75
									
								
								vendor/github.com/vishvananda/netlink/neigh_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										75
									
								
								vendor/github.com/vishvananda/netlink/neigh_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -24,7 +24,11 @@ const (
 | 
				
			|||||||
	NDA_MASTER
 | 
						NDA_MASTER
 | 
				
			||||||
	NDA_LINK_NETNSID
 | 
						NDA_LINK_NETNSID
 | 
				
			||||||
	NDA_SRC_VNI
 | 
						NDA_SRC_VNI
 | 
				
			||||||
	NDA_MAX = NDA_SRC_VNI
 | 
						NDA_PROTOCOL
 | 
				
			||||||
 | 
						NDA_NH_ID
 | 
				
			||||||
 | 
						NDA_FDB_EXT_ATTRS
 | 
				
			||||||
 | 
						NDA_FLAGS_EXT
 | 
				
			||||||
 | 
						NDA_MAX = NDA_FLAGS_EXT
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Neighbor Cache Entry States.
 | 
					// Neighbor Cache Entry States.
 | 
				
			||||||
@@ -46,9 +50,17 @@ const (
 | 
				
			|||||||
	NTF_SELF        = 0x02
 | 
						NTF_SELF        = 0x02
 | 
				
			||||||
	NTF_MASTER      = 0x04
 | 
						NTF_MASTER      = 0x04
 | 
				
			||||||
	NTF_PROXY       = 0x08
 | 
						NTF_PROXY       = 0x08
 | 
				
			||||||
 | 
						NTF_EXT_LEARNED = 0x10
 | 
				
			||||||
 | 
						NTF_OFFLOADED   = 0x20
 | 
				
			||||||
 | 
						NTF_STICKY      = 0x40
 | 
				
			||||||
	NTF_ROUTER      = 0x80
 | 
						NTF_ROUTER      = 0x80
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Extended Neighbor Flags
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						NTF_EXT_MANAGED = 0x00000001
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Ndmsg is for adding, removing or receiving information about a neighbor table entry
 | 
					// Ndmsg is for adding, removing or receiving information about a neighbor table entry
 | 
				
			||||||
type Ndmsg struct {
 | 
					type Ndmsg struct {
 | 
				
			||||||
	Family uint8
 | 
						Family uint8
 | 
				
			||||||
@@ -162,11 +174,16 @@ func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error {
 | 
				
			|||||||
	if neigh.LLIPAddr != nil {
 | 
						if neigh.LLIPAddr != nil {
 | 
				
			||||||
		llIPData := nl.NewRtAttr(NDA_LLADDR, neigh.LLIPAddr.To4())
 | 
							llIPData := nl.NewRtAttr(NDA_LLADDR, neigh.LLIPAddr.To4())
 | 
				
			||||||
		req.AddData(llIPData)
 | 
							req.AddData(llIPData)
 | 
				
			||||||
	} else if neigh.Flags != NTF_PROXY || neigh.HardwareAddr != nil {
 | 
						} else if neigh.HardwareAddr != nil {
 | 
				
			||||||
		hwData := nl.NewRtAttr(NDA_LLADDR, []byte(neigh.HardwareAddr))
 | 
							hwData := nl.NewRtAttr(NDA_LLADDR, []byte(neigh.HardwareAddr))
 | 
				
			||||||
		req.AddData(hwData)
 | 
							req.AddData(hwData)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if neigh.FlagsExt != 0 {
 | 
				
			||||||
 | 
							flagsExtData := nl.NewRtAttr(NDA_FLAGS_EXT, nl.Uint32Attr(uint32(neigh.FlagsExt)))
 | 
				
			||||||
 | 
							req.AddData(flagsExtData)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if neigh.Vlan != 0 {
 | 
						if neigh.Vlan != 0 {
 | 
				
			||||||
		vlanData := nl.NewRtAttr(NDA_VLAN, nl.Uint16Attr(uint16(neigh.Vlan)))
 | 
							vlanData := nl.NewRtAttr(NDA_VLAN, nl.Uint16Attr(uint16(neigh.Vlan)))
 | 
				
			||||||
		req.AddData(vlanData)
 | 
							req.AddData(vlanData)
 | 
				
			||||||
@@ -243,6 +260,18 @@ func (h *Handle) NeighListExecute(msg Ndmsg) ([]Neigh, error) {
 | 
				
			|||||||
			// Ignore messages from other interfaces
 | 
								// Ignore messages from other interfaces
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if msg.Family != 0 && ndm.Family != msg.Family {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if msg.State != 0 && ndm.State != msg.State {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if msg.Type != 0 && ndm.Type != msg.Type {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if msg.Flags != 0 && ndm.Flags != msg.Flags {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		neigh, err := NeighDeserialize(m)
 | 
							neigh, err := NeighDeserialize(m)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
@@ -293,6 +322,8 @@ func NeighDeserialize(m []byte) (*Neigh, error) {
 | 
				
			|||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				neigh.HardwareAddr = net.HardwareAddr(attr.Value)
 | 
									neigh.HardwareAddr = net.HardwareAddr(attr.Value)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							case NDA_FLAGS_EXT:
 | 
				
			||||||
 | 
								neigh.FlagsExt = int(native.Uint32(attr.Value[0:4]))
 | 
				
			||||||
		case NDA_VLAN:
 | 
							case NDA_VLAN:
 | 
				
			||||||
			neigh.Vlan = int(native.Uint16(attr.Value[0:2]))
 | 
								neigh.Vlan = int(native.Uint16(attr.Value[0:2]))
 | 
				
			||||||
		case NDA_VNI:
 | 
							case NDA_VNI:
 | 
				
			||||||
@@ -308,13 +339,13 @@ func NeighDeserialize(m []byte) (*Neigh, error) {
 | 
				
			|||||||
// NeighSubscribe takes a chan down which notifications will be sent
 | 
					// NeighSubscribe takes a chan down which notifications will be sent
 | 
				
			||||||
// when neighbors are added or deleted. Close the 'done' chan to stop subscription.
 | 
					// when neighbors are added or deleted. Close the 'done' chan to stop subscription.
 | 
				
			||||||
func NeighSubscribe(ch chan<- NeighUpdate, done <-chan struct{}) error {
 | 
					func NeighSubscribe(ch chan<- NeighUpdate, done <-chan struct{}) error {
 | 
				
			||||||
	return neighSubscribeAt(netns.None(), netns.None(), ch, done, nil, false)
 | 
						return neighSubscribeAt(netns.None(), netns.None(), ch, done, nil, false, 0, nil, false)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NeighSubscribeAt works like NeighSubscribe plus it allows the caller
 | 
					// NeighSubscribeAt works like NeighSubscribe plus it allows the caller
 | 
				
			||||||
// to choose the network namespace in which to subscribe (ns).
 | 
					// to choose the network namespace in which to subscribe (ns).
 | 
				
			||||||
func NeighSubscribeAt(ns netns.NsHandle, ch chan<- NeighUpdate, done <-chan struct{}) error {
 | 
					func NeighSubscribeAt(ns netns.NsHandle, ch chan<- NeighUpdate, done <-chan struct{}) error {
 | 
				
			||||||
	return neighSubscribeAt(ns, netns.None(), ch, done, nil, false)
 | 
						return neighSubscribeAt(ns, netns.None(), ch, done, nil, false, 0, nil, false)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NeighSubscribeOptions contains a set of options to use with
 | 
					// NeighSubscribeOptions contains a set of options to use with
 | 
				
			||||||
@@ -323,6 +354,11 @@ type NeighSubscribeOptions struct {
 | 
				
			|||||||
	Namespace     *netns.NsHandle
 | 
						Namespace     *netns.NsHandle
 | 
				
			||||||
	ErrorCallback func(error)
 | 
						ErrorCallback func(error)
 | 
				
			||||||
	ListExisting  bool
 | 
						ListExisting  bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// max size is based on value of /proc/sys/net/core/rmem_max
 | 
				
			||||||
 | 
						ReceiveBufferSize      int
 | 
				
			||||||
 | 
						ReceiveBufferForceSize bool
 | 
				
			||||||
 | 
						ReceiveTimeout         *unix.Timeval
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NeighSubscribeWithOptions work like NeighSubscribe but enable to
 | 
					// NeighSubscribeWithOptions work like NeighSubscribe but enable to
 | 
				
			||||||
@@ -333,16 +369,17 @@ func NeighSubscribeWithOptions(ch chan<- NeighUpdate, done <-chan struct{}, opti
 | 
				
			|||||||
		none := netns.None()
 | 
							none := netns.None()
 | 
				
			||||||
		options.Namespace = &none
 | 
							options.Namespace = &none
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return neighSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting)
 | 
						return neighSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting,
 | 
				
			||||||
 | 
							options.ReceiveBufferSize, options.ReceiveTimeout, options.ReceiveBufferForceSize)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func neighSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- NeighUpdate, done <-chan struct{}, cberr func(error), listExisting bool) error {
 | 
					func neighSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- NeighUpdate, done <-chan struct{}, cberr func(error), listExisting bool,
 | 
				
			||||||
 | 
						rcvbuf int, rcvTimeout *unix.Timeval, rcvbufForce bool) error {
 | 
				
			||||||
	s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_NEIGH)
 | 
						s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_NEIGH)
 | 
				
			||||||
	makeRequest := func(family int) error {
 | 
						makeRequest := func(family int) error {
 | 
				
			||||||
		req := pkgHandle.newNetlinkRequest(unix.RTM_GETNEIGH,
 | 
							req := pkgHandle.newNetlinkRequest(unix.RTM_GETNEIGH, unix.NLM_F_DUMP)
 | 
				
			||||||
			unix.NLM_F_DUMP)
 | 
							ndmsg := &Ndmsg{Family: uint8(family)}
 | 
				
			||||||
		infmsg := nl.NewIfInfomsg(family)
 | 
							req.AddData(ndmsg)
 | 
				
			||||||
		req.AddData(infmsg)
 | 
					 | 
				
			||||||
		if err := s.Send(req); err != nil {
 | 
							if err := s.Send(req); err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -351,6 +388,17 @@ func neighSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- NeighUpdate, done <
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if rcvTimeout != nil {
 | 
				
			||||||
 | 
							if err := s.SetReceiveTimeout(rcvTimeout); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if rcvbuf != 0 {
 | 
				
			||||||
 | 
							err = s.SetReceiveBufferSize(rcvbuf, rcvbufForce)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if done != nil {
 | 
						if done != nil {
 | 
				
			||||||
		go func() {
 | 
							go func() {
 | 
				
			||||||
			<-done
 | 
								<-done
 | 
				
			||||||
@@ -396,13 +444,12 @@ func neighSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- NeighUpdate, done <
 | 
				
			|||||||
					continue
 | 
										continue
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				if m.Header.Type == unix.NLMSG_ERROR {
 | 
									if m.Header.Type == unix.NLMSG_ERROR {
 | 
				
			||||||
					native := nl.NativeEndian()
 | 
										nError := int32(native.Uint32(m.Data[0:4]))
 | 
				
			||||||
					error := int32(native.Uint32(m.Data[0:4]))
 | 
										if nError == 0 {
 | 
				
			||||||
					if error == 0 {
 | 
					 | 
				
			||||||
						continue
 | 
											continue
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					if cberr != nil {
 | 
										if cberr != nil {
 | 
				
			||||||
						cberr(syscall.Errno(-error))
 | 
											cberr(syscall.Errno(-nError))
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					return
 | 
										return
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										54
									
								
								vendor/github.com/vishvananda/netlink/netlink_unspecified.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										54
									
								
								vendor/github.com/vishvananda/netlink/netlink_unspecified.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -16,7 +16,7 @@ func LinkSetMTU(link Link, mtu int) error {
 | 
				
			|||||||
	return ErrNotImplemented
 | 
						return ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func LinkSetMaster(link Link, master *Bridge) error {
 | 
					func LinkSetMaster(link Link, master Link) error {
 | 
				
			||||||
	return ErrNotImplemented
 | 
						return ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -52,6 +52,10 @@ func LinkSetVfVlanQos(link Link, vf, vlan, qos int) error {
 | 
				
			|||||||
	return ErrNotImplemented
 | 
						return ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func LinkSetVfVlanQosProto(link Link, vf, vlan, qos, proto int) error {
 | 
				
			||||||
 | 
						return ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func LinkSetVfTxRate(link Link, vf, rate int) error {
 | 
					func LinkSetVfTxRate(link Link, vf, rate int) error {
 | 
				
			||||||
	return ErrNotImplemented
 | 
						return ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -72,6 +76,10 @@ func LinkSetXdpFd(link Link, fd int) error {
 | 
				
			|||||||
	return ErrNotImplemented
 | 
						return ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func LinkSetXdpFdWithFlags(link Link, fd, flags int) error {
 | 
				
			||||||
 | 
						return ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func LinkSetARPOff(link Link) error {
 | 
					func LinkSetARPOff(link Link) error {
 | 
				
			||||||
	return ErrNotImplemented
 | 
						return ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -120,6 +128,22 @@ func LinkSetTxQLen(link Link, qlen int) error {
 | 
				
			|||||||
	return ErrNotImplemented
 | 
						return ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func LinkSetGSOMaxSize(link Link, maxSize int) error {
 | 
				
			||||||
 | 
						return ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func LinkSetGROMaxSize(link Link, maxSize int) error {
 | 
				
			||||||
 | 
						return ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func LinkSetGSOIPv4MaxSize(link Link, maxSize int) error {
 | 
				
			||||||
 | 
						return ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func LinkSetGROIPv4MaxSize(link Link, maxSize int) error {
 | 
				
			||||||
 | 
						return ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func LinkAdd(link Link) error {
 | 
					func LinkAdd(link Link) error {
 | 
				
			||||||
	return ErrNotImplemented
 | 
						return ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -176,14 +200,34 @@ func RouteAdd(route *Route) error {
 | 
				
			|||||||
	return ErrNotImplemented
 | 
						return ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func RouteAppend(route *Route) error {
 | 
				
			||||||
 | 
						return ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func RouteChange(route *Route) error {
 | 
				
			||||||
 | 
						return ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func RouteDel(route *Route) error {
 | 
					func RouteDel(route *Route) error {
 | 
				
			||||||
	return ErrNotImplemented
 | 
						return ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func RouteGet(destination net.IP) ([]Route, error) {
 | 
				
			||||||
 | 
						return nil, ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func RouteList(link Link, family int) ([]Route, error) {
 | 
					func RouteList(link Link, family int) ([]Route, error) {
 | 
				
			||||||
	return nil, ErrNotImplemented
 | 
						return nil, ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func RouteListFiltered(family int, filter *Route, filterMask uint64) ([]Route, error) {
 | 
				
			||||||
 | 
						return nil, ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func RouteReplace(route *Route) error {
 | 
				
			||||||
 | 
						return ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func XfrmPolicyAdd(policy *XfrmPolicy) error {
 | 
					func XfrmPolicyAdd(policy *XfrmPolicy) error {
 | 
				
			||||||
	return ErrNotImplemented
 | 
						return ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -196,6 +240,10 @@ func XfrmPolicyList(family int) ([]XfrmPolicy, error) {
 | 
				
			|||||||
	return nil, ErrNotImplemented
 | 
						return nil, ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func XfrmPolicyGet(policy *XfrmPolicy) (*XfrmPolicy, error) {
 | 
				
			||||||
 | 
						return nil, ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func XfrmStateAdd(policy *XfrmState) error {
 | 
					func XfrmStateAdd(policy *XfrmState) error {
 | 
				
			||||||
	return ErrNotImplemented
 | 
						return ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -235,3 +283,7 @@ func NeighDeserialize(m []byte) (*Neigh, error) {
 | 
				
			|||||||
func SocketGet(local, remote net.Addr) (*Socket, error) {
 | 
					func SocketGet(local, remote net.Addr) (*Socket, error) {
 | 
				
			||||||
	return nil, ErrNotImplemented
 | 
						return nil, ErrNotImplemented
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func SocketDestroy(local, remote net.Addr) (*Socket, error) {
 | 
				
			||||||
 | 
						return nil, ErrNotImplemented
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								vendor/github.com/vishvananda/netlink/netns_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/vishvananda/netlink/netns_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -87,7 +87,7 @@ func (h *Handle) getNetNsId(attrType int, val uint32) (int, error) {
 | 
				
			|||||||
	rtgen := nl.NewRtGenMsg()
 | 
						rtgen := nl.NewRtGenMsg()
 | 
				
			||||||
	req.AddData(rtgen)
 | 
						req.AddData(rtgen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b := make([]byte, 4, 4)
 | 
						b := make([]byte, 4)
 | 
				
			||||||
	native.PutUint32(b, val)
 | 
						native.PutUint32(b, val)
 | 
				
			||||||
	attr := nl.NewRtAttr(attrType, b)
 | 
						attr := nl.NewRtAttr(attrType, b)
 | 
				
			||||||
	req.AddData(attr)
 | 
						req.AddData(attr)
 | 
				
			||||||
@@ -126,12 +126,12 @@ func (h *Handle) setNetNsId(attrType int, val uint32, newnsid uint32) error {
 | 
				
			|||||||
	rtgen := nl.NewRtGenMsg()
 | 
						rtgen := nl.NewRtGenMsg()
 | 
				
			||||||
	req.AddData(rtgen)
 | 
						req.AddData(rtgen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b := make([]byte, 4, 4)
 | 
						b := make([]byte, 4)
 | 
				
			||||||
	native.PutUint32(b, val)
 | 
						native.PutUint32(b, val)
 | 
				
			||||||
	attr := nl.NewRtAttr(attrType, b)
 | 
						attr := nl.NewRtAttr(attrType, b)
 | 
				
			||||||
	req.AddData(attr)
 | 
						req.AddData(attr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b1 := make([]byte, 4, 4)
 | 
						b1 := make([]byte, 4)
 | 
				
			||||||
	native.PutUint32(b1, newnsid)
 | 
						native.PutUint32(b1, newnsid)
 | 
				
			||||||
	attr1 := nl.NewRtAttr(NETNSA_NSID, b1)
 | 
						attr1 := nl.NewRtAttr(NETNSA_NSID, b1)
 | 
				
			||||||
	req.AddData(attr1)
 | 
						req.AddData(attr1)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								vendor/github.com/vishvananda/netlink/nl/addr_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/vishvananda/netlink/nl/addr_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -54,24 +54,18 @@ func (msg *IfAddrmsg) Len() int {
 | 
				
			|||||||
// 	__u32	tstamp; /* updated timestamp, hundredths of seconds */
 | 
					// 	__u32	tstamp; /* updated timestamp, hundredths of seconds */
 | 
				
			||||||
// };
 | 
					// };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const IFA_CACHEINFO = 6
 | 
					 | 
				
			||||||
const SizeofIfaCacheInfo = 0x10
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type IfaCacheInfo struct {
 | 
					type IfaCacheInfo struct {
 | 
				
			||||||
	IfaPrefered uint32
 | 
						unix.IfaCacheinfo
 | 
				
			||||||
	IfaValid    uint32
 | 
					 | 
				
			||||||
	Cstamp      uint32
 | 
					 | 
				
			||||||
	Tstamp      uint32
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (msg *IfaCacheInfo) Len() int {
 | 
					func (msg *IfaCacheInfo) Len() int {
 | 
				
			||||||
	return SizeofIfaCacheInfo
 | 
						return unix.SizeofIfaCacheinfo
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func DeserializeIfaCacheInfo(b []byte) *IfaCacheInfo {
 | 
					func DeserializeIfaCacheInfo(b []byte) *IfaCacheInfo {
 | 
				
			||||||
	return (*IfaCacheInfo)(unsafe.Pointer(&b[0:SizeofIfaCacheInfo][0]))
 | 
						return (*IfaCacheInfo)(unsafe.Pointer(&b[0:unix.SizeofIfaCacheinfo][0]))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (msg *IfaCacheInfo) Serialize() []byte {
 | 
					func (msg *IfaCacheInfo) Serialize() []byte {
 | 
				
			||||||
	return (*(*[SizeofIfaCacheInfo]byte)(unsafe.Pointer(msg)))[:]
 | 
						return (*(*[unix.SizeofIfaCacheinfo]byte)(unsafe.Pointer(msg)))[:]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										45
									
								
								vendor/github.com/vishvananda/netlink/nl/conntrack_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										45
									
								
								vendor/github.com/vishvananda/netlink/nl/conntrack_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -15,6 +15,38 @@ var L4ProtoMap = map[uint8]string{
 | 
				
			|||||||
	17: "udp",
 | 
						17: "udp",
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// From https://git.netfilter.org/libnetfilter_conntrack/tree/include/libnetfilter_conntrack/libnetfilter_conntrack_tcp.h
 | 
				
			||||||
 | 
					//	 enum tcp_state {
 | 
				
			||||||
 | 
					//		TCP_CONNTRACK_NONE,
 | 
				
			||||||
 | 
					//		TCP_CONNTRACK_SYN_SENT,
 | 
				
			||||||
 | 
					//		TCP_CONNTRACK_SYN_RECV,
 | 
				
			||||||
 | 
					//		TCP_CONNTRACK_ESTABLISHED,
 | 
				
			||||||
 | 
					//		TCP_CONNTRACK_FIN_WAIT,
 | 
				
			||||||
 | 
					//		TCP_CONNTRACK_CLOSE_WAIT,
 | 
				
			||||||
 | 
					//		TCP_CONNTRACK_LAST_ACK,
 | 
				
			||||||
 | 
					//		TCP_CONNTRACK_TIME_WAIT,
 | 
				
			||||||
 | 
					//		TCP_CONNTRACK_CLOSE,
 | 
				
			||||||
 | 
					//		TCP_CONNTRACK_LISTEN,		/* obsolete */
 | 
				
			||||||
 | 
					//	#define TCP_CONNTRACK_SYN_SENT2		TCP_CONNTRACK_LISTEN
 | 
				
			||||||
 | 
					//		TCP_CONNTRACK_MAX,
 | 
				
			||||||
 | 
					//		TCP_CONNTRACK_IGNORE
 | 
				
			||||||
 | 
					//	 };
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
							TCP_CONNTRACK_NONE = 0
 | 
				
			||||||
 | 
							TCP_CONNTRACK_SYN_SENT = 1
 | 
				
			||||||
 | 
							TCP_CONNTRACK_SYN_RECV = 2
 | 
				
			||||||
 | 
							TCP_CONNTRACK_ESTABLISHED = 3
 | 
				
			||||||
 | 
							TCP_CONNTRACK_FIN_WAIT = 4
 | 
				
			||||||
 | 
							TCP_CONNTRACK_CLOSE_WAIT = 5
 | 
				
			||||||
 | 
							TCP_CONNTRACK_LAST_ACK = 6
 | 
				
			||||||
 | 
							TCP_CONNTRACK_TIME_WAIT = 7
 | 
				
			||||||
 | 
							TCP_CONNTRACK_CLOSE = 8
 | 
				
			||||||
 | 
							TCP_CONNTRACK_LISTEN = 9
 | 
				
			||||||
 | 
							TCP_CONNTRACK_SYN_SENT2 = 9
 | 
				
			||||||
 | 
							TCP_CONNTRACK_MAX = 10
 | 
				
			||||||
 | 
							TCP_CONNTRACK_IGNORE = 11
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// All the following constants are coming from:
 | 
					// All the following constants are coming from:
 | 
				
			||||||
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/netfilter/nfnetlink_conntrack.h
 | 
					// https://github.com/torvalds/linux/blob/master/include/uapi/linux/netfilter/nfnetlink_conntrack.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -31,6 +63,7 @@ var L4ProtoMap = map[uint8]string{
 | 
				
			|||||||
// 	IPCTNL_MSG_MAX
 | 
					// 	IPCTNL_MSG_MAX
 | 
				
			||||||
// };
 | 
					// };
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
 | 
						IPCTNL_MSG_CT_NEW = 0
 | 
				
			||||||
	IPCTNL_MSG_CT_GET    = 1
 | 
						IPCTNL_MSG_CT_GET    = 1
 | 
				
			||||||
	IPCTNL_MSG_CT_DELETE = 2
 | 
						IPCTNL_MSG_CT_DELETE = 2
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -40,9 +73,11 @@ const (
 | 
				
			|||||||
	NFNETLINK_V0 = 0
 | 
						NFNETLINK_V0 = 0
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// #define NLA_F_NESTED (1 << 15)
 | 
					 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	NLA_F_NESTED = (1 << 15)
 | 
						NLA_F_NESTED        uint16 = (1 << 15) // #define NLA_F_NESTED (1 << 15)
 | 
				
			||||||
 | 
						NLA_F_NET_BYTEORDER uint16 = (1 << 14) // #define NLA_F_NESTED (1 << 14)
 | 
				
			||||||
 | 
						NLA_TYPE_MASK              = ^(NLA_F_NESTED | NLA_F_NET_BYTEORDER)
 | 
				
			||||||
 | 
						NLA_ALIGNTO         uint16 = 4 // #define NLA_ALIGNTO 4
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// enum ctattr_type {
 | 
					// enum ctattr_type {
 | 
				
			||||||
@@ -86,7 +121,10 @@ const (
 | 
				
			|||||||
	CTA_COUNTERS_REPLY = 10
 | 
						CTA_COUNTERS_REPLY = 10
 | 
				
			||||||
	CTA_USE            = 11
 | 
						CTA_USE            = 11
 | 
				
			||||||
	CTA_ID             = 12
 | 
						CTA_ID             = 12
 | 
				
			||||||
 | 
						CTA_ZONE           = 18
 | 
				
			||||||
	CTA_TIMESTAMP      = 20
 | 
						CTA_TIMESTAMP      = 20
 | 
				
			||||||
 | 
						CTA_LABELS         = 22
 | 
				
			||||||
 | 
						CTA_LABELS_MASK    = 23
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// enum ctattr_tuple {
 | 
					// enum ctattr_tuple {
 | 
				
			||||||
@@ -147,7 +185,10 @@ const (
 | 
				
			|||||||
// };
 | 
					// };
 | 
				
			||||||
// #define CTA_PROTOINFO_MAX (__CTA_PROTOINFO_MAX - 1)
 | 
					// #define CTA_PROTOINFO_MAX (__CTA_PROTOINFO_MAX - 1)
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
 | 
						CTA_PROTOINFO_UNSPEC = 0
 | 
				
			||||||
	CTA_PROTOINFO_TCP = 1
 | 
						CTA_PROTOINFO_TCP = 1
 | 
				
			||||||
 | 
						CTA_PROTOINFO_DCCP = 2
 | 
				
			||||||
 | 
						CTA_PROTOINFO_SCTP = 3
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// enum ctattr_protoinfo_tcp {
 | 
					// enum ctattr_protoinfo_tcp {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										102
									
								
								vendor/github.com/vishvananda/netlink/nl/devlink_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										102
									
								
								vendor/github.com/vishvananda/netlink/nl/devlink_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -10,16 +10,55 @@ const (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	DEVLINK_CMD_GET           = 1
 | 
						DEVLINK_CMD_GET           = 1
 | 
				
			||||||
 | 
						DEVLINK_CMD_PORT_GET      = 5
 | 
				
			||||||
 | 
						DEVLINK_CMD_PORT_SET      = 6
 | 
				
			||||||
 | 
						DEVLINK_CMD_PORT_NEW      = 7
 | 
				
			||||||
 | 
						DEVLINK_CMD_PORT_DEL      = 8
 | 
				
			||||||
	DEVLINK_CMD_ESWITCH_GET   = 29
 | 
						DEVLINK_CMD_ESWITCH_GET   = 29
 | 
				
			||||||
	DEVLINK_CMD_ESWITCH_SET   = 30
 | 
						DEVLINK_CMD_ESWITCH_SET   = 30
 | 
				
			||||||
 | 
						DEVLINK_CMD_RESOURCE_DUMP = 36
 | 
				
			||||||
 | 
						DEVLINK_CMD_PARAM_GET     = 38
 | 
				
			||||||
 | 
						DEVLINK_CMD_PARAM_SET     = 39
 | 
				
			||||||
 | 
						DEVLINK_CMD_INFO_GET      = 51
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	DEVLINK_ATTR_BUS_NAME                   = 1
 | 
						DEVLINK_ATTR_BUS_NAME                   = 1
 | 
				
			||||||
	DEVLINK_ATTR_DEV_NAME                   = 2
 | 
						DEVLINK_ATTR_DEV_NAME                   = 2
 | 
				
			||||||
 | 
						DEVLINK_ATTR_PORT_INDEX                 = 3
 | 
				
			||||||
 | 
						DEVLINK_ATTR_PORT_TYPE                  = 4
 | 
				
			||||||
 | 
						DEVLINK_ATTR_PORT_NETDEV_IFINDEX        = 6
 | 
				
			||||||
 | 
						DEVLINK_ATTR_PORT_NETDEV_NAME           = 7
 | 
				
			||||||
 | 
						DEVLINK_ATTR_PORT_IBDEV_NAME            = 8
 | 
				
			||||||
	DEVLINK_ATTR_ESWITCH_MODE               = 25
 | 
						DEVLINK_ATTR_ESWITCH_MODE               = 25
 | 
				
			||||||
	DEVLINK_ATTR_ESWITCH_INLINE_MODE        = 26
 | 
						DEVLINK_ATTR_ESWITCH_INLINE_MODE        = 26
 | 
				
			||||||
	DEVLINK_ATTR_ESWITCH_ENCAP_MODE         = 62
 | 
						DEVLINK_ATTR_ESWITCH_ENCAP_MODE         = 62
 | 
				
			||||||
 | 
						DEVLINK_ATTR_RESOURCE_LIST              = 63 /* nested */
 | 
				
			||||||
 | 
						DEVLINK_ATTR_RESOURCE                   = 64 /* nested */
 | 
				
			||||||
 | 
						DEVLINK_ATTR_RESOURCE_NAME              = 65 /* string */
 | 
				
			||||||
 | 
						DEVLINK_ATTR_RESOURCE_ID                = 66 /* u64 */
 | 
				
			||||||
 | 
						DEVLINK_ATTR_RESOURCE_SIZE              = 67 /* u64 */
 | 
				
			||||||
 | 
						DEVLINK_ATTR_RESOURCE_SIZE_NEW          = 68 /* u64 */
 | 
				
			||||||
 | 
						DEVLINK_ATTR_RESOURCE_SIZE_VALID        = 69 /* u8 */
 | 
				
			||||||
 | 
						DEVLINK_ATTR_RESOURCE_SIZE_MIN          = 70 /* u64 */
 | 
				
			||||||
 | 
						DEVLINK_ATTR_RESOURCE_SIZE_MAX          = 71 /* u64 */
 | 
				
			||||||
 | 
						DEVLINK_ATTR_RESOURCE_SIZE_GRAN         = 72 /* u64 */
 | 
				
			||||||
 | 
						DEVLINK_ATTR_RESOURCE_UNIT              = 73 /* u8 */
 | 
				
			||||||
 | 
						DEVLINK_ATTR_RESOURCE_OCC               = 74 /* u64 */
 | 
				
			||||||
 | 
						DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID    = 75 /* u64 */
 | 
				
			||||||
 | 
						DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS = 76 /* u64 */
 | 
				
			||||||
 | 
						DEVLINK_ATTR_PORT_FLAVOUR               = 77
 | 
				
			||||||
 | 
						DEVLINK_ATTR_INFO_DRIVER_NAME           = 98
 | 
				
			||||||
 | 
						DEVLINK_ATTR_INFO_SERIAL_NUMBER         = 99
 | 
				
			||||||
 | 
						DEVLINK_ATTR_INFO_VERSION_FIXED         = 100
 | 
				
			||||||
 | 
						DEVLINK_ATTR_INFO_VERSION_RUNNING       = 101
 | 
				
			||||||
 | 
						DEVLINK_ATTR_INFO_VERSION_STORED        = 102
 | 
				
			||||||
 | 
						DEVLINK_ATTR_INFO_VERSION_NAME          = 103
 | 
				
			||||||
 | 
						DEVLINK_ATTR_INFO_VERSION_VALUE         = 104
 | 
				
			||||||
 | 
						DEVLINK_ATTR_PORT_PCI_PF_NUMBER         = 127
 | 
				
			||||||
 | 
						DEVLINK_ATTR_PORT_FUNCTION              = 145
 | 
				
			||||||
 | 
						DEVLINK_ATTR_PORT_CONTROLLER_NUMBER     = 150
 | 
				
			||||||
 | 
						DEVLINK_ATTR_PORT_PCI_SF_NUMBER         = 164
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -38,3 +77,66 @@ const (
 | 
				
			|||||||
	DEVLINK_ESWITCH_ENCAP_MODE_NONE  = 0
 | 
						DEVLINK_ESWITCH_ENCAP_MODE_NONE  = 0
 | 
				
			||||||
	DEVLINK_ESWITCH_ENCAP_MODE_BASIC = 1
 | 
						DEVLINK_ESWITCH_ENCAP_MODE_BASIC = 1
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						DEVLINK_PORT_FLAVOUR_PHYSICAL = 0
 | 
				
			||||||
 | 
						DEVLINK_PORT_FLAVOUR_CPU      = 1
 | 
				
			||||||
 | 
						DEVLINK_PORT_FLAVOUR_DSA      = 2
 | 
				
			||||||
 | 
						DEVLINK_PORT_FLAVOUR_PCI_PF   = 3
 | 
				
			||||||
 | 
						DEVLINK_PORT_FLAVOUR_PCI_VF   = 4
 | 
				
			||||||
 | 
						DEVLINK_PORT_FLAVOUR_VIRTUAL  = 5
 | 
				
			||||||
 | 
						DEVLINK_PORT_FLAVOUR_UNUSED   = 6
 | 
				
			||||||
 | 
						DEVLINK_PORT_FLAVOUR_PCI_SF   = 7
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						DEVLINK_PORT_TYPE_NOTSET = 0
 | 
				
			||||||
 | 
						DEVLINK_PORT_TYPE_AUTO   = 1
 | 
				
			||||||
 | 
						DEVLINK_PORT_TYPE_ETH    = 2
 | 
				
			||||||
 | 
						DEVLINK_PORT_TYPE_IB     = 3
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR = 1
 | 
				
			||||||
 | 
						DEVLINK_PORT_FN_ATTR_STATE         = 2
 | 
				
			||||||
 | 
						DEVLINK_PORT_FN_ATTR_OPSTATE       = 3
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						DEVLINK_PORT_FN_STATE_INACTIVE = 0
 | 
				
			||||||
 | 
						DEVLINK_PORT_FN_STATE_ACTIVE   = 1
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						DEVLINK_PORT_FN_OPSTATE_DETACHED = 0
 | 
				
			||||||
 | 
						DEVLINK_PORT_FN_OPSTATE_ATTACHED = 1
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						DEVLINK_RESOURCE_UNIT_ENTRY uint8 = 0
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						DEVLINK_ATTR_PARAM             = iota + 80 /* nested */
 | 
				
			||||||
 | 
						DEVLINK_ATTR_PARAM_NAME                    /* string */
 | 
				
			||||||
 | 
						DEVLINK_ATTR_PARAM_GENERIC                 /* flag */
 | 
				
			||||||
 | 
						DEVLINK_ATTR_PARAM_TYPE                    /* u8 */
 | 
				
			||||||
 | 
						DEVLINK_ATTR_PARAM_VALUES_LIST             /* nested */
 | 
				
			||||||
 | 
						DEVLINK_ATTR_PARAM_VALUE                   /* nested */
 | 
				
			||||||
 | 
						DEVLINK_ATTR_PARAM_VALUE_DATA              /* dynamic */
 | 
				
			||||||
 | 
						DEVLINK_ATTR_PARAM_VALUE_CMODE             /* u8 */
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						DEVLINK_PARAM_TYPE_U8     = 1
 | 
				
			||||||
 | 
						DEVLINK_PARAM_TYPE_U16    = 2
 | 
				
			||||||
 | 
						DEVLINK_PARAM_TYPE_U32    = 3
 | 
				
			||||||
 | 
						DEVLINK_PARAM_TYPE_STRING = 5
 | 
				
			||||||
 | 
						DEVLINK_PARAM_TYPE_BOOL   = 6
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						DEVLINK_PARAM_CMODE_RUNTIME = iota
 | 
				
			||||||
 | 
						DEVLINK_PARAM_CMODE_DRIVERINIT
 | 
				
			||||||
 | 
						DEVLINK_PARAM_CMODE_PERMANENT
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										21
									
								
								vendor/github.com/vishvananda/netlink/nl/ip6tnl_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/vishvananda/netlink/nl/ip6tnl_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					package nl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// id's of route attribute from https://elixir.bootlin.com/linux/v5.17.3/source/include/uapi/linux/lwtunnel.h#L38
 | 
				
			||||||
 | 
					// the value's size are specified in https://elixir.bootlin.com/linux/v5.17.3/source/net/ipv4/ip_tunnel_core.c#L928
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						LWTUNNEL_IP6_UNSPEC = iota
 | 
				
			||||||
 | 
						LWTUNNEL_IP6_ID
 | 
				
			||||||
 | 
						LWTUNNEL_IP6_DST
 | 
				
			||||||
 | 
						LWTUNNEL_IP6_SRC
 | 
				
			||||||
 | 
						LWTUNNEL_IP6_HOPLIMIT
 | 
				
			||||||
 | 
						LWTUNNEL_IP6_TC
 | 
				
			||||||
 | 
						LWTUNNEL_IP6_FLAGS
 | 
				
			||||||
 | 
						LWTUNNEL_IP6_PAD // not implemented
 | 
				
			||||||
 | 
						LWTUNNEL_IP6_OPTS // not implemented
 | 
				
			||||||
 | 
						__LWTUNNEL_IP6_MAX
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										227
									
								
								vendor/github.com/vishvananda/netlink/nl/ipset_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										227
									
								
								vendor/github.com/vishvananda/netlink/nl/ipset_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,227 @@
 | 
				
			|||||||
 | 
					package nl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"golang.org/x/sys/unix"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						/* The protocol version */
 | 
				
			||||||
 | 
						IPSET_PROTOCOL = 6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* The max length of strings including NUL: set and type identifiers */
 | 
				
			||||||
 | 
						IPSET_MAXNAMELEN = 32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* The maximum permissible comment length we will accept over netlink */
 | 
				
			||||||
 | 
						IPSET_MAX_COMMENT_SIZE = 255
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						_                  = iota
 | 
				
			||||||
 | 
						IPSET_CMD_PROTOCOL /* 1: Return protocol version */
 | 
				
			||||||
 | 
						IPSET_CMD_CREATE   /* 2: Create a new (empty) set */
 | 
				
			||||||
 | 
						IPSET_CMD_DESTROY  /* 3: Destroy a (empty) set */
 | 
				
			||||||
 | 
						IPSET_CMD_FLUSH    /* 4: Remove all elements from a set */
 | 
				
			||||||
 | 
						IPSET_CMD_RENAME   /* 5: Rename a set */
 | 
				
			||||||
 | 
						IPSET_CMD_SWAP     /* 6: Swap two sets */
 | 
				
			||||||
 | 
						IPSET_CMD_LIST     /* 7: List sets */
 | 
				
			||||||
 | 
						IPSET_CMD_SAVE     /* 8: Save sets */
 | 
				
			||||||
 | 
						IPSET_CMD_ADD      /* 9: Add an element to a set */
 | 
				
			||||||
 | 
						IPSET_CMD_DEL      /* 10: Delete an element from a set */
 | 
				
			||||||
 | 
						IPSET_CMD_TEST     /* 11: Test an element in a set */
 | 
				
			||||||
 | 
						IPSET_CMD_HEADER   /* 12: Get set header data only */
 | 
				
			||||||
 | 
						IPSET_CMD_TYPE     /* 13: Get set type */
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Attributes at command level */
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						_                       = iota
 | 
				
			||||||
 | 
						IPSET_ATTR_PROTOCOL     /* 1: Protocol version */
 | 
				
			||||||
 | 
						IPSET_ATTR_SETNAME      /* 2: Name of the set */
 | 
				
			||||||
 | 
						IPSET_ATTR_TYPENAME     /* 3: Typename */
 | 
				
			||||||
 | 
						IPSET_ATTR_REVISION     /* 4: Settype revision */
 | 
				
			||||||
 | 
						IPSET_ATTR_FAMILY       /* 5: Settype family */
 | 
				
			||||||
 | 
						IPSET_ATTR_FLAGS        /* 6: Flags at command level */
 | 
				
			||||||
 | 
						IPSET_ATTR_DATA         /* 7: Nested attributes */
 | 
				
			||||||
 | 
						IPSET_ATTR_ADT          /* 8: Multiple data containers */
 | 
				
			||||||
 | 
						IPSET_ATTR_LINENO       /* 9: Restore lineno */
 | 
				
			||||||
 | 
						IPSET_ATTR_PROTOCOL_MIN /* 10: Minimal supported version number */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						IPSET_ATTR_SETNAME2     = IPSET_ATTR_TYPENAME     /* Setname at rename/swap */
 | 
				
			||||||
 | 
						IPSET_ATTR_REVISION_MIN = IPSET_ATTR_PROTOCOL_MIN /* type rev min */
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* CADT specific attributes */
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						IPSET_ATTR_IP          = 1
 | 
				
			||||||
 | 
						IPSET_ATTR_IP_FROM     = 1
 | 
				
			||||||
 | 
						IPSET_ATTR_IP_TO       = 2
 | 
				
			||||||
 | 
						IPSET_ATTR_CIDR        = 3
 | 
				
			||||||
 | 
						IPSET_ATTR_PORT        = 4
 | 
				
			||||||
 | 
						IPSET_ATTR_PORT_FROM   = 4
 | 
				
			||||||
 | 
						IPSET_ATTR_PORT_TO     = 5
 | 
				
			||||||
 | 
						IPSET_ATTR_TIMEOUT     = 6
 | 
				
			||||||
 | 
						IPSET_ATTR_PROTO       = 7
 | 
				
			||||||
 | 
						IPSET_ATTR_CADT_FLAGS  = 8
 | 
				
			||||||
 | 
						IPSET_ATTR_CADT_LINENO = IPSET_ATTR_LINENO /* 9 */
 | 
				
			||||||
 | 
						IPSET_ATTR_MARK        = 10
 | 
				
			||||||
 | 
						IPSET_ATTR_MARKMASK    = 11
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Reserve empty slots */
 | 
				
			||||||
 | 
						IPSET_ATTR_CADT_MAX = 16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Create-only specific attributes */
 | 
				
			||||||
 | 
						IPSET_ATTR_GC = 3 + iota
 | 
				
			||||||
 | 
						IPSET_ATTR_HASHSIZE
 | 
				
			||||||
 | 
						IPSET_ATTR_MAXELEM
 | 
				
			||||||
 | 
						IPSET_ATTR_NETMASK
 | 
				
			||||||
 | 
						IPSET_ATTR_PROBES
 | 
				
			||||||
 | 
						IPSET_ATTR_RESIZE
 | 
				
			||||||
 | 
						IPSET_ATTR_SIZE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Kernel-only */
 | 
				
			||||||
 | 
						IPSET_ATTR_ELEMENTS
 | 
				
			||||||
 | 
						IPSET_ATTR_REFERENCES
 | 
				
			||||||
 | 
						IPSET_ATTR_MEMSIZE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SET_ATTR_CREATE_MAX
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						IPSET_ATTR_IPADDR_IPV4 = 1
 | 
				
			||||||
 | 
						IPSET_ATTR_IPADDR_IPV6 = 2
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ADT specific attributes */
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						IPSET_ATTR_ETHER = IPSET_ATTR_CADT_MAX + iota + 1
 | 
				
			||||||
 | 
						IPSET_ATTR_NAME
 | 
				
			||||||
 | 
						IPSET_ATTR_NAMEREF
 | 
				
			||||||
 | 
						IPSET_ATTR_IP2
 | 
				
			||||||
 | 
						IPSET_ATTR_CIDR2
 | 
				
			||||||
 | 
						IPSET_ATTR_IP2_TO
 | 
				
			||||||
 | 
						IPSET_ATTR_IFACE
 | 
				
			||||||
 | 
						IPSET_ATTR_BYTES
 | 
				
			||||||
 | 
						IPSET_ATTR_PACKETS
 | 
				
			||||||
 | 
						IPSET_ATTR_COMMENT
 | 
				
			||||||
 | 
						IPSET_ATTR_SKBMARK
 | 
				
			||||||
 | 
						IPSET_ATTR_SKBPRIO
 | 
				
			||||||
 | 
						IPSET_ATTR_SKBQUEUE
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Flags at CADT attribute level, upper half of cmdattrs */
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						IPSET_FLAG_BIT_BEFORE        = 0
 | 
				
			||||||
 | 
						IPSET_FLAG_BEFORE            = (1 << IPSET_FLAG_BIT_BEFORE)
 | 
				
			||||||
 | 
						IPSET_FLAG_BIT_PHYSDEV       = 1
 | 
				
			||||||
 | 
						IPSET_FLAG_PHYSDEV           = (1 << IPSET_FLAG_BIT_PHYSDEV)
 | 
				
			||||||
 | 
						IPSET_FLAG_BIT_NOMATCH       = 2
 | 
				
			||||||
 | 
						IPSET_FLAG_NOMATCH           = (1 << IPSET_FLAG_BIT_NOMATCH)
 | 
				
			||||||
 | 
						IPSET_FLAG_BIT_WITH_COUNTERS = 3
 | 
				
			||||||
 | 
						IPSET_FLAG_WITH_COUNTERS     = (1 << IPSET_FLAG_BIT_WITH_COUNTERS)
 | 
				
			||||||
 | 
						IPSET_FLAG_BIT_WITH_COMMENT  = 4
 | 
				
			||||||
 | 
						IPSET_FLAG_WITH_COMMENT      = (1 << IPSET_FLAG_BIT_WITH_COMMENT)
 | 
				
			||||||
 | 
						IPSET_FLAG_BIT_WITH_FORCEADD = 5
 | 
				
			||||||
 | 
						IPSET_FLAG_WITH_FORCEADD     = (1 << IPSET_FLAG_BIT_WITH_FORCEADD)
 | 
				
			||||||
 | 
						IPSET_FLAG_BIT_WITH_SKBINFO  = 6
 | 
				
			||||||
 | 
						IPSET_FLAG_WITH_SKBINFO      = (1 << IPSET_FLAG_BIT_WITH_SKBINFO)
 | 
				
			||||||
 | 
						IPSET_FLAG_CADT_MAX          = 15
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						IPSET_ERR_PRIVATE = 4096 + iota
 | 
				
			||||||
 | 
						IPSET_ERR_PROTOCOL
 | 
				
			||||||
 | 
						IPSET_ERR_FIND_TYPE
 | 
				
			||||||
 | 
						IPSET_ERR_MAX_SETS
 | 
				
			||||||
 | 
						IPSET_ERR_BUSY
 | 
				
			||||||
 | 
						IPSET_ERR_EXIST_SETNAME2
 | 
				
			||||||
 | 
						IPSET_ERR_TYPE_MISMATCH
 | 
				
			||||||
 | 
						IPSET_ERR_EXIST
 | 
				
			||||||
 | 
						IPSET_ERR_INVALID_CIDR
 | 
				
			||||||
 | 
						IPSET_ERR_INVALID_NETMASK
 | 
				
			||||||
 | 
						IPSET_ERR_INVALID_FAMILY
 | 
				
			||||||
 | 
						IPSET_ERR_TIMEOUT
 | 
				
			||||||
 | 
						IPSET_ERR_REFERENCED
 | 
				
			||||||
 | 
						IPSET_ERR_IPADDR_IPV4
 | 
				
			||||||
 | 
						IPSET_ERR_IPADDR_IPV6
 | 
				
			||||||
 | 
						IPSET_ERR_COUNTER
 | 
				
			||||||
 | 
						IPSET_ERR_COMMENT
 | 
				
			||||||
 | 
						IPSET_ERR_INVALID_MARKMASK
 | 
				
			||||||
 | 
						IPSET_ERR_SKBINFO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Type specific error codes */
 | 
				
			||||||
 | 
						IPSET_ERR_TYPE_SPECIFIC = 4352
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type IPSetError uintptr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e IPSetError) Error() string {
 | 
				
			||||||
 | 
						switch int(e) {
 | 
				
			||||||
 | 
						case IPSET_ERR_PRIVATE:
 | 
				
			||||||
 | 
							return "private"
 | 
				
			||||||
 | 
						case IPSET_ERR_PROTOCOL:
 | 
				
			||||||
 | 
							return "invalid protocol"
 | 
				
			||||||
 | 
						case IPSET_ERR_FIND_TYPE:
 | 
				
			||||||
 | 
							return "invalid type"
 | 
				
			||||||
 | 
						case IPSET_ERR_MAX_SETS:
 | 
				
			||||||
 | 
							return "max sets reached"
 | 
				
			||||||
 | 
						case IPSET_ERR_BUSY:
 | 
				
			||||||
 | 
							return "busy"
 | 
				
			||||||
 | 
						case IPSET_ERR_EXIST_SETNAME2:
 | 
				
			||||||
 | 
							return "exist_setname2"
 | 
				
			||||||
 | 
						case IPSET_ERR_TYPE_MISMATCH:
 | 
				
			||||||
 | 
							return "type mismatch"
 | 
				
			||||||
 | 
						case IPSET_ERR_EXIST:
 | 
				
			||||||
 | 
							return "exist"
 | 
				
			||||||
 | 
						case IPSET_ERR_INVALID_CIDR:
 | 
				
			||||||
 | 
							return "invalid cidr"
 | 
				
			||||||
 | 
						case IPSET_ERR_INVALID_NETMASK:
 | 
				
			||||||
 | 
							return "invalid netmask"
 | 
				
			||||||
 | 
						case IPSET_ERR_INVALID_FAMILY:
 | 
				
			||||||
 | 
							return "invalid family"
 | 
				
			||||||
 | 
						case IPSET_ERR_TIMEOUT:
 | 
				
			||||||
 | 
							return "timeout"
 | 
				
			||||||
 | 
						case IPSET_ERR_REFERENCED:
 | 
				
			||||||
 | 
							return "referenced"
 | 
				
			||||||
 | 
						case IPSET_ERR_IPADDR_IPV4:
 | 
				
			||||||
 | 
							return "invalid ipv4 address"
 | 
				
			||||||
 | 
						case IPSET_ERR_IPADDR_IPV6:
 | 
				
			||||||
 | 
							return "invalid ipv6 address"
 | 
				
			||||||
 | 
						case IPSET_ERR_COUNTER:
 | 
				
			||||||
 | 
							return "invalid counter"
 | 
				
			||||||
 | 
						case IPSET_ERR_COMMENT:
 | 
				
			||||||
 | 
							return "invalid comment"
 | 
				
			||||||
 | 
						case IPSET_ERR_INVALID_MARKMASK:
 | 
				
			||||||
 | 
							return "invalid markmask"
 | 
				
			||||||
 | 
						case IPSET_ERR_SKBINFO:
 | 
				
			||||||
 | 
							return "skbinfo"
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return "errno " + strconv.Itoa(int(e))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func GetIpsetFlags(cmd int) int {
 | 
				
			||||||
 | 
						switch cmd {
 | 
				
			||||||
 | 
						case IPSET_CMD_CREATE:
 | 
				
			||||||
 | 
							return unix.NLM_F_REQUEST | unix.NLM_F_ACK | unix.NLM_F_CREATE
 | 
				
			||||||
 | 
						case IPSET_CMD_DESTROY,
 | 
				
			||||||
 | 
							IPSET_CMD_FLUSH,
 | 
				
			||||||
 | 
							IPSET_CMD_RENAME,
 | 
				
			||||||
 | 
							IPSET_CMD_SWAP,
 | 
				
			||||||
 | 
							IPSET_CMD_TEST:
 | 
				
			||||||
 | 
							return unix.NLM_F_REQUEST | unix.NLM_F_ACK
 | 
				
			||||||
 | 
						case IPSET_CMD_LIST,
 | 
				
			||||||
 | 
							IPSET_CMD_SAVE:
 | 
				
			||||||
 | 
							return unix.NLM_F_REQUEST | unix.NLM_F_ACK | unix.NLM_F_ROOT | unix.NLM_F_MATCH | unix.NLM_F_DUMP
 | 
				
			||||||
 | 
						case IPSET_CMD_ADD,
 | 
				
			||||||
 | 
							IPSET_CMD_DEL:
 | 
				
			||||||
 | 
							return unix.NLM_F_REQUEST | unix.NLM_F_ACK
 | 
				
			||||||
 | 
						case IPSET_CMD_HEADER,
 | 
				
			||||||
 | 
							IPSET_CMD_TYPE,
 | 
				
			||||||
 | 
							IPSET_CMD_PROTOCOL:
 | 
				
			||||||
 | 
							return unix.NLM_F_REQUEST
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return 0
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										214
									
								
								vendor/github.com/vishvananda/netlink/nl/link_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										214
									
								
								vendor/github.com/vishvananda/netlink/nl/link_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,6 +1,9 @@
 | 
				
			|||||||
package nl
 | 
					package nl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"encoding/binary"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
	"unsafe"
 | 
						"unsafe"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -28,6 +31,16 @@ const (
 | 
				
			|||||||
	IFLA_VLAN_MAX = IFLA_VLAN_PROTOCOL
 | 
						IFLA_VLAN_MAX = IFLA_VLAN_PROTOCOL
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						IFLA_NETKIT_UNSPEC = iota
 | 
				
			||||||
 | 
						IFLA_NETKIT_PEER_INFO
 | 
				
			||||||
 | 
						IFLA_NETKIT_PRIMARY
 | 
				
			||||||
 | 
						IFLA_NETKIT_POLICY
 | 
				
			||||||
 | 
						IFLA_NETKIT_PEER_POLICY
 | 
				
			||||||
 | 
						IFLA_NETKIT_MODE
 | 
				
			||||||
 | 
						IFLA_NETKIT_MAX = IFLA_NETKIT_MODE
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	VETH_INFO_UNSPEC = iota
 | 
						VETH_INFO_UNSPEC = iota
 | 
				
			||||||
	VETH_INFO_PEER
 | 
						VETH_INFO_PEER
 | 
				
			||||||
@@ -83,7 +96,37 @@ const (
 | 
				
			|||||||
	IFLA_BRPORT_PROXYARP
 | 
						IFLA_BRPORT_PROXYARP
 | 
				
			||||||
	IFLA_BRPORT_LEARNING_SYNC
 | 
						IFLA_BRPORT_LEARNING_SYNC
 | 
				
			||||||
	IFLA_BRPORT_PROXYARP_WIFI
 | 
						IFLA_BRPORT_PROXYARP_WIFI
 | 
				
			||||||
	IFLA_BRPORT_MAX = IFLA_BRPORT_PROXYARP_WIFI
 | 
						IFLA_BRPORT_ROOT_ID
 | 
				
			||||||
 | 
						IFLA_BRPORT_BRIDGE_ID
 | 
				
			||||||
 | 
						IFLA_BRPORT_DESIGNATED_PORT
 | 
				
			||||||
 | 
						IFLA_BRPORT_DESIGNATED_COST
 | 
				
			||||||
 | 
						IFLA_BRPORT_ID
 | 
				
			||||||
 | 
						IFLA_BRPORT_NO
 | 
				
			||||||
 | 
						IFLA_BRPORT_TOPOLOGY_CHANGE_ACK
 | 
				
			||||||
 | 
						IFLA_BRPORT_CONFIG_PENDING
 | 
				
			||||||
 | 
						IFLA_BRPORT_MESSAGE_AGE_TIMER
 | 
				
			||||||
 | 
						IFLA_BRPORT_FORWARD_DELAY_TIMER
 | 
				
			||||||
 | 
						IFLA_BRPORT_HOLD_TIMER
 | 
				
			||||||
 | 
						IFLA_BRPORT_FLUSH
 | 
				
			||||||
 | 
						IFLA_BRPORT_MULTICAST_ROUTER
 | 
				
			||||||
 | 
						IFLA_BRPORT_PAD
 | 
				
			||||||
 | 
						IFLA_BRPORT_MCAST_FLOOD
 | 
				
			||||||
 | 
						IFLA_BRPORT_MCAST_TO_UCAST
 | 
				
			||||||
 | 
						IFLA_BRPORT_VLAN_TUNNEL
 | 
				
			||||||
 | 
						IFLA_BRPORT_BCAST_FLOOD
 | 
				
			||||||
 | 
						IFLA_BRPORT_GROUP_FWD_MASK
 | 
				
			||||||
 | 
						IFLA_BRPORT_NEIGH_SUPPRESS
 | 
				
			||||||
 | 
						IFLA_BRPORT_ISOLATED
 | 
				
			||||||
 | 
						IFLA_BRPORT_BACKUP_PORT
 | 
				
			||||||
 | 
						IFLA_BRPORT_MRP_RING_OPEN
 | 
				
			||||||
 | 
						IFLA_BRPORT_MRP_IN_OPEN
 | 
				
			||||||
 | 
						IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT
 | 
				
			||||||
 | 
						IFLA_BRPORT_MCAST_EHT_HOSTS_CNT
 | 
				
			||||||
 | 
						IFLA_BRPORT_LOCKED
 | 
				
			||||||
 | 
						IFLA_BRPORT_MAB
 | 
				
			||||||
 | 
						IFLA_BRPORT_MCAST_N_GROUPS
 | 
				
			||||||
 | 
						IFLA_BRPORT_MCAST_MAX_GROUPS
 | 
				
			||||||
 | 
						IFLA_BRPORT_MAX = IFLA_BRPORT_MCAST_MAX_GROUPS
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -101,7 +144,9 @@ const (
 | 
				
			|||||||
	IFLA_MACVLAN_MACADDR
 | 
						IFLA_MACVLAN_MACADDR
 | 
				
			||||||
	IFLA_MACVLAN_MACADDR_DATA
 | 
						IFLA_MACVLAN_MACADDR_DATA
 | 
				
			||||||
	IFLA_MACVLAN_MACADDR_COUNT
 | 
						IFLA_MACVLAN_MACADDR_COUNT
 | 
				
			||||||
	IFLA_MACVLAN_MAX = IFLA_MACVLAN_FLAGS
 | 
						IFLA_MACVLAN_BC_QUEUE_LEN
 | 
				
			||||||
 | 
						IFLA_MACVLAN_BC_QUEUE_LEN_USED
 | 
				
			||||||
 | 
						IFLA_MACVLAN_MAX = IFLA_MACVLAN_BC_QUEUE_LEN_USED
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -171,6 +216,25 @@ const (
 | 
				
			|||||||
	IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE
 | 
						IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						IFLA_GENEVE_UNSPEC = iota
 | 
				
			||||||
 | 
						IFLA_GENEVE_ID     // vni
 | 
				
			||||||
 | 
						IFLA_GENEVE_REMOTE
 | 
				
			||||||
 | 
						IFLA_GENEVE_TTL
 | 
				
			||||||
 | 
						IFLA_GENEVE_TOS
 | 
				
			||||||
 | 
						IFLA_GENEVE_PORT // destination port
 | 
				
			||||||
 | 
						IFLA_GENEVE_COLLECT_METADATA
 | 
				
			||||||
 | 
						IFLA_GENEVE_REMOTE6
 | 
				
			||||||
 | 
						IFLA_GENEVE_UDP_CSUM
 | 
				
			||||||
 | 
						IFLA_GENEVE_UDP_ZERO_CSUM6_TX
 | 
				
			||||||
 | 
						IFLA_GENEVE_UDP_ZERO_CSUM6_RX
 | 
				
			||||||
 | 
						IFLA_GENEVE_LABEL
 | 
				
			||||||
 | 
						IFLA_GENEVE_TTL_INHERIT
 | 
				
			||||||
 | 
						IFLA_GENEVE_DF
 | 
				
			||||||
 | 
						IFLA_GENEVE_INNER_PROTO_INHERIT
 | 
				
			||||||
 | 
						IFLA_GENEVE_MAX = IFLA_GENEVE_INNER_PROTO_INHERIT
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	IFLA_GRE_UNSPEC = iota
 | 
						IFLA_GRE_UNSPEC = iota
 | 
				
			||||||
	IFLA_GRE_LINK
 | 
						IFLA_GRE_LINK
 | 
				
			||||||
@@ -226,9 +290,17 @@ const (
 | 
				
			|||||||
	IFLA_VF_TRUST        /* Trust state of VF */
 | 
						IFLA_VF_TRUST        /* Trust state of VF */
 | 
				
			||||||
	IFLA_VF_IB_NODE_GUID /* VF Infiniband node GUID */
 | 
						IFLA_VF_IB_NODE_GUID /* VF Infiniband node GUID */
 | 
				
			||||||
	IFLA_VF_IB_PORT_GUID /* VF Infiniband port GUID */
 | 
						IFLA_VF_IB_PORT_GUID /* VF Infiniband port GUID */
 | 
				
			||||||
 | 
						IFLA_VF_VLAN_LIST    /* nested list of vlans, option for QinQ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	IFLA_VF_MAX = IFLA_VF_IB_PORT_GUID
 | 
						IFLA_VF_MAX = IFLA_VF_IB_PORT_GUID
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						IFLA_VF_VLAN_INFO_UNSPEC = iota
 | 
				
			||||||
 | 
						IFLA_VF_VLAN_INFO        /* VLAN ID, QoS and VLAN protocol */
 | 
				
			||||||
 | 
						__IFLA_VF_VLAN_INFO_MAX
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	IFLA_VF_LINK_STATE_AUTO    = iota /* link state of the uplink */
 | 
						IFLA_VF_LINK_STATE_AUTO    = iota /* link state of the uplink */
 | 
				
			||||||
	IFLA_VF_LINK_STATE_ENABLE         /* link always up */
 | 
						IFLA_VF_LINK_STATE_ENABLE         /* link always up */
 | 
				
			||||||
@@ -243,12 +315,15 @@ const (
 | 
				
			|||||||
	IFLA_VF_STATS_TX_BYTES
 | 
						IFLA_VF_STATS_TX_BYTES
 | 
				
			||||||
	IFLA_VF_STATS_BROADCAST
 | 
						IFLA_VF_STATS_BROADCAST
 | 
				
			||||||
	IFLA_VF_STATS_MULTICAST
 | 
						IFLA_VF_STATS_MULTICAST
 | 
				
			||||||
	IFLA_VF_STATS_MAX = IFLA_VF_STATS_MULTICAST
 | 
						IFLA_VF_STATS_RX_DROPPED
 | 
				
			||||||
 | 
						IFLA_VF_STATS_TX_DROPPED
 | 
				
			||||||
 | 
						IFLA_VF_STATS_MAX = IFLA_VF_STATS_TX_DROPPED
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	SizeofVfMac        = 0x24
 | 
						SizeofVfMac        = 0x24
 | 
				
			||||||
	SizeofVfVlan       = 0x0c
 | 
						SizeofVfVlan       = 0x0c
 | 
				
			||||||
 | 
						SizeofVfVlanInfo   = 0x10
 | 
				
			||||||
	SizeofVfTxRate     = 0x08
 | 
						SizeofVfTxRate     = 0x08
 | 
				
			||||||
	SizeofVfRate       = 0x0c
 | 
						SizeofVfRate       = 0x0c
 | 
				
			||||||
	SizeofVfSpoofchk   = 0x08
 | 
						SizeofVfSpoofchk   = 0x08
 | 
				
			||||||
@@ -304,6 +379,49 @@ func (msg *VfVlan) Serialize() []byte {
 | 
				
			|||||||
	return (*(*[SizeofVfVlan]byte)(unsafe.Pointer(msg)))[:]
 | 
						return (*(*[SizeofVfVlan]byte)(unsafe.Pointer(msg)))[:]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func DeserializeVfVlanList(b []byte) ([]*VfVlanInfo, error) {
 | 
				
			||||||
 | 
						var vfVlanInfoList []*VfVlanInfo
 | 
				
			||||||
 | 
						attrs, err := ParseRouteAttr(b)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, element := range attrs {
 | 
				
			||||||
 | 
							if element.Attr.Type == IFLA_VF_VLAN_INFO {
 | 
				
			||||||
 | 
								vfVlanInfoList = append(vfVlanInfoList, DeserializeVfVlanInfo(element.Value))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(vfVlanInfoList) == 0 {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("VF vlan list is defined but no vf vlan info elements were found")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return vfVlanInfoList, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// struct ifla_vf_vlan_info {
 | 
				
			||||||
 | 
					//   __u32 vf;
 | 
				
			||||||
 | 
					//   __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */
 | 
				
			||||||
 | 
					//   __u32 qos;
 | 
				
			||||||
 | 
					//   __be16 vlan_proto; /* VLAN protocol either 802.1Q or 802.1ad */
 | 
				
			||||||
 | 
					// };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type VfVlanInfo struct {
 | 
				
			||||||
 | 
						VfVlan
 | 
				
			||||||
 | 
						VlanProto uint16
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func DeserializeVfVlanInfo(b []byte) *VfVlanInfo {
 | 
				
			||||||
 | 
						return &VfVlanInfo{
 | 
				
			||||||
 | 
							*(*VfVlan)(unsafe.Pointer(&b[0:SizeofVfVlan][0])),
 | 
				
			||||||
 | 
							binary.BigEndian.Uint16(b[SizeofVfVlan:SizeofVfVlanInfo]),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (msg *VfVlanInfo) Serialize() []byte {
 | 
				
			||||||
 | 
						return (*(*[SizeofVfVlanInfo]byte)(unsafe.Pointer(msg)))[:]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// struct ifla_vf_tx_rate {
 | 
					// struct ifla_vf_tx_rate {
 | 
				
			||||||
//   __u32 vf;
 | 
					//   __u32 vf;
 | 
				
			||||||
//   __u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */
 | 
					//   __u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */
 | 
				
			||||||
@@ -326,6 +444,59 @@ func (msg *VfTxRate) Serialize() []byte {
 | 
				
			|||||||
	return (*(*[SizeofVfTxRate]byte)(unsafe.Pointer(msg)))[:]
 | 
						return (*(*[SizeofVfTxRate]byte)(unsafe.Pointer(msg)))[:]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//struct ifla_vf_stats {
 | 
				
			||||||
 | 
					//	__u64 rx_packets;
 | 
				
			||||||
 | 
					//	__u64 tx_packets;
 | 
				
			||||||
 | 
					//	__u64 rx_bytes;
 | 
				
			||||||
 | 
					//	__u64 tx_bytes;
 | 
				
			||||||
 | 
					//	__u64 broadcast;
 | 
				
			||||||
 | 
					//	__u64 multicast;
 | 
				
			||||||
 | 
					//};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type VfStats struct {
 | 
				
			||||||
 | 
						RxPackets uint64
 | 
				
			||||||
 | 
						TxPackets uint64
 | 
				
			||||||
 | 
						RxBytes   uint64
 | 
				
			||||||
 | 
						TxBytes   uint64
 | 
				
			||||||
 | 
						Multicast uint64
 | 
				
			||||||
 | 
						Broadcast uint64
 | 
				
			||||||
 | 
						RxDropped uint64
 | 
				
			||||||
 | 
						TxDropped uint64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func DeserializeVfStats(b []byte) VfStats {
 | 
				
			||||||
 | 
						var vfstat VfStats
 | 
				
			||||||
 | 
						stats, err := ParseRouteAttr(b)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return vfstat
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var valueVar uint64
 | 
				
			||||||
 | 
						for _, stat := range stats {
 | 
				
			||||||
 | 
							if err := binary.Read(bytes.NewBuffer(stat.Value), NativeEndian(), &valueVar); err != nil {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							switch stat.Attr.Type {
 | 
				
			||||||
 | 
							case IFLA_VF_STATS_RX_PACKETS:
 | 
				
			||||||
 | 
								vfstat.RxPackets = valueVar
 | 
				
			||||||
 | 
							case IFLA_VF_STATS_TX_PACKETS:
 | 
				
			||||||
 | 
								vfstat.TxPackets = valueVar
 | 
				
			||||||
 | 
							case IFLA_VF_STATS_RX_BYTES:
 | 
				
			||||||
 | 
								vfstat.RxBytes = valueVar
 | 
				
			||||||
 | 
							case IFLA_VF_STATS_TX_BYTES:
 | 
				
			||||||
 | 
								vfstat.TxBytes = valueVar
 | 
				
			||||||
 | 
							case IFLA_VF_STATS_MULTICAST:
 | 
				
			||||||
 | 
								vfstat.Multicast = valueVar
 | 
				
			||||||
 | 
							case IFLA_VF_STATS_BROADCAST:
 | 
				
			||||||
 | 
								vfstat.Broadcast = valueVar
 | 
				
			||||||
 | 
							case IFLA_VF_STATS_RX_DROPPED:
 | 
				
			||||||
 | 
								vfstat.RxDropped = valueVar
 | 
				
			||||||
 | 
							case IFLA_VF_STATS_TX_DROPPED:
 | 
				
			||||||
 | 
								vfstat.TxDropped = valueVar
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return vfstat
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// struct ifla_vf_rate {
 | 
					// struct ifla_vf_rate {
 | 
				
			||||||
//   __u32 vf;
 | 
					//   __u32 vf;
 | 
				
			||||||
//   __u32 min_tx_rate; /* Min Bandwidth in Mbps */
 | 
					//   __u32 min_tx_rate; /* Min Bandwidth in Mbps */
 | 
				
			||||||
@@ -478,6 +649,14 @@ const (
 | 
				
			|||||||
	IFLA_XDP_MAX      = IFLA_XDP_PROG_ID
 | 
						IFLA_XDP_MAX      = IFLA_XDP_PROG_ID
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// XDP program attach mode (used as dump value for IFLA_XDP_ATTACHED)
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						XDP_ATTACHED_NONE = iota
 | 
				
			||||||
 | 
						XDP_ATTACHED_DRV
 | 
				
			||||||
 | 
						XDP_ATTACHED_SKB
 | 
				
			||||||
 | 
						XDP_ATTACHED_HW
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	IFLA_IPTUN_UNSPEC = iota
 | 
						IFLA_IPTUN_UNSPEC = iota
 | 
				
			||||||
	IFLA_IPTUN_LINK
 | 
						IFLA_IPTUN_LINK
 | 
				
			||||||
@@ -608,3 +787,32 @@ const (
 | 
				
			|||||||
	IFLA_IPOIB_UMCAST
 | 
						IFLA_IPOIB_UMCAST
 | 
				
			||||||
	IFLA_IPOIB_MAX = IFLA_IPOIB_UMCAST
 | 
						IFLA_IPOIB_MAX = IFLA_IPOIB_UMCAST
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						IFLA_CAN_UNSPEC = iota
 | 
				
			||||||
 | 
						IFLA_CAN_BITTIMING
 | 
				
			||||||
 | 
						IFLA_CAN_BITTIMING_CONST
 | 
				
			||||||
 | 
						IFLA_CAN_CLOCK
 | 
				
			||||||
 | 
						IFLA_CAN_STATE
 | 
				
			||||||
 | 
						IFLA_CAN_CTRLMODE
 | 
				
			||||||
 | 
						IFLA_CAN_RESTART_MS
 | 
				
			||||||
 | 
						IFLA_CAN_RESTART
 | 
				
			||||||
 | 
						IFLA_CAN_BERR_COUNTER
 | 
				
			||||||
 | 
						IFLA_CAN_DATA_BITTIMING
 | 
				
			||||||
 | 
						IFLA_CAN_DATA_BITTIMING_CONST
 | 
				
			||||||
 | 
						IFLA_CAN_TERMINATION
 | 
				
			||||||
 | 
						IFLA_CAN_TERMINATION_CONST
 | 
				
			||||||
 | 
						IFLA_CAN_BITRATE_CONST
 | 
				
			||||||
 | 
						IFLA_CAN_DATA_BITRATE_CONST
 | 
				
			||||||
 | 
						IFLA_CAN_BITRATE_MAX
 | 
				
			||||||
 | 
						IFLA_CAN_MAX = IFLA_CAN_BITRATE_MAX
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						IFLA_BAREUDP_UNSPEC = iota
 | 
				
			||||||
 | 
						IFLA_BAREUDP_PORT
 | 
				
			||||||
 | 
						IFLA_BAREUDP_ETHERTYPE
 | 
				
			||||||
 | 
						IFLA_BAREUDP_SRCPORT_MIN
 | 
				
			||||||
 | 
						IFLA_BAREUDP_MULTIPROTO_MODE
 | 
				
			||||||
 | 
						IFLA_BAREUDP_MAX = IFLA_BAREUDP_MULTIPROTO_MODE
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										29
									
								
								vendor/github.com/vishvananda/netlink/nl/lwt_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/vishvananda/netlink/nl/lwt_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					package nl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						LWT_BPF_PROG_UNSPEC = iota
 | 
				
			||||||
 | 
						LWT_BPF_PROG_FD
 | 
				
			||||||
 | 
						LWT_BPF_PROG_NAME
 | 
				
			||||||
 | 
						__LWT_BPF_PROG_MAX
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						LWT_BPF_PROG_MAX = __LWT_BPF_PROG_MAX - 1
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						LWT_BPF_UNSPEC = iota
 | 
				
			||||||
 | 
						LWT_BPF_IN
 | 
				
			||||||
 | 
						LWT_BPF_OUT
 | 
				
			||||||
 | 
						LWT_BPF_XMIT
 | 
				
			||||||
 | 
						LWT_BPF_XMIT_HEADROOM
 | 
				
			||||||
 | 
						__LWT_BPF_MAX
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						LWT_BPF_MAX = __LWT_BPF_MAX - 1
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						LWT_BPF_MAX_HEADROOM = 256
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
							
								
								
									
										322
									
								
								vendor/github.com/vishvananda/netlink/nl/nl_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										322
									
								
								vendor/github.com/vishvananda/netlink/nl/nl_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -6,6 +6,7 @@ import (
 | 
				
			|||||||
	"encoding/binary"
 | 
						"encoding/binary"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
	"runtime"
 | 
						"runtime"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
	"sync/atomic"
 | 
						"sync/atomic"
 | 
				
			||||||
@@ -28,6 +29,7 @@ const (
 | 
				
			|||||||
	RECEIVE_BUFFER_SIZE = 65536
 | 
						RECEIVE_BUFFER_SIZE = 65536
 | 
				
			||||||
	// Kernel netlink pid
 | 
						// Kernel netlink pid
 | 
				
			||||||
	PidKernel     uint32 = 0
 | 
						PidKernel     uint32 = 0
 | 
				
			||||||
 | 
						SizeofCnMsgOp        = 0x18
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SupportedNlFamilies contains the list of netlink families this netlink package supports
 | 
					// SupportedNlFamilies contains the list of netlink families this netlink package supports
 | 
				
			||||||
@@ -35,6 +37,12 @@ var SupportedNlFamilies = []int{unix.NETLINK_ROUTE, unix.NETLINK_XFRM, unix.NETL
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var nextSeqNr uint32
 | 
					var nextSeqNr uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Default netlink socket timeout, 60s
 | 
				
			||||||
 | 
					var SocketTimeoutTv = unix.Timeval{Sec: 60, Usec: 0}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ErrorMessageReporting is the default error message reporting configuration for the new netlink sockets
 | 
				
			||||||
 | 
					var EnableErrorMessageReporting bool = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// GetIPFamily returns the family type of a net.IP.
 | 
					// GetIPFamily returns the family type of a net.IP.
 | 
				
			||||||
func GetIPFamily(ip net.IP) int {
 | 
					func GetIPFamily(ip net.IP) int {
 | 
				
			||||||
	if len(ip) <= net.IPv4len {
 | 
						if len(ip) <= net.IPv4len {
 | 
				
			||||||
@@ -77,11 +85,69 @@ func Swap32(i uint32) uint32 {
 | 
				
			|||||||
	return (i&0xff000000)>>24 | (i&0xff0000)>>8 | (i&0xff00)<<8 | (i&0xff)<<24
 | 
						return (i&0xff000000)>>24 | (i&0xff0000)>>8 | (i&0xff00)<<8 | (i&0xff)<<24
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						NLMSGERR_ATTR_UNUSED = 0
 | 
				
			||||||
 | 
						NLMSGERR_ATTR_MSG    = 1
 | 
				
			||||||
 | 
						NLMSGERR_ATTR_OFFS   = 2
 | 
				
			||||||
 | 
						NLMSGERR_ATTR_COOKIE = 3
 | 
				
			||||||
 | 
						NLMSGERR_ATTR_POLICY = 4
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type NetlinkRequestData interface {
 | 
					type NetlinkRequestData interface {
 | 
				
			||||||
	Len() int
 | 
						Len() int
 | 
				
			||||||
	Serialize() []byte
 | 
						Serialize() []byte
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						PROC_CN_MCAST_LISTEN = 1
 | 
				
			||||||
 | 
						PROC_CN_MCAST_IGNORE
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CbID struct {
 | 
				
			||||||
 | 
						Idx uint32
 | 
				
			||||||
 | 
						Val uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CnMsg struct {
 | 
				
			||||||
 | 
						ID     CbID
 | 
				
			||||||
 | 
						Seq    uint32
 | 
				
			||||||
 | 
						Ack    uint32
 | 
				
			||||||
 | 
						Length uint16
 | 
				
			||||||
 | 
						Flags  uint16
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CnMsgOp struct {
 | 
				
			||||||
 | 
						CnMsg
 | 
				
			||||||
 | 
						// here we differ from the C header
 | 
				
			||||||
 | 
						Op uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewCnMsg(idx, val, op uint32) *CnMsgOp {
 | 
				
			||||||
 | 
						var cm CnMsgOp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cm.ID.Idx = idx
 | 
				
			||||||
 | 
						cm.ID.Val = val
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cm.Ack = 0
 | 
				
			||||||
 | 
						cm.Seq = 1
 | 
				
			||||||
 | 
						cm.Length = uint16(binary.Size(op))
 | 
				
			||||||
 | 
						cm.Op = op
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &cm
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (msg *CnMsgOp) Serialize() []byte {
 | 
				
			||||||
 | 
						return (*(*[SizeofCnMsgOp]byte)(unsafe.Pointer(msg)))[:]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func DeserializeCnMsgOp(b []byte) *CnMsgOp {
 | 
				
			||||||
 | 
						return (*CnMsgOp)(unsafe.Pointer(&b[0:SizeofCnMsgOp][0]))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (msg *CnMsgOp) Len() int {
 | 
				
			||||||
 | 
						return SizeofCnMsgOp
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// IfInfomsg is related to links, but it is used for list requests as well
 | 
					// IfInfomsg is related to links, but it is used for list requests as well
 | 
				
			||||||
type IfInfomsg struct {
 | 
					type IfInfomsg struct {
 | 
				
			||||||
	unix.IfInfomsg
 | 
						unix.IfInfomsg
 | 
				
			||||||
@@ -249,6 +315,12 @@ func (msg *IfInfomsg) EncapType() string {
 | 
				
			|||||||
	return fmt.Sprintf("unknown%d", msg.Type)
 | 
						return fmt.Sprintf("unknown%d", msg.Type)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Round the length of a netlink message up to align it properly.
 | 
				
			||||||
 | 
					// Taken from syscall/netlink_linux.go by The Go Authors under BSD-style license.
 | 
				
			||||||
 | 
					func nlmAlignOf(msglen int) int {
 | 
				
			||||||
 | 
						return (msglen + syscall.NLMSG_ALIGNTO - 1) & ^(syscall.NLMSG_ALIGNTO - 1)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func rtaAlignOf(attrlen int) int {
 | 
					func rtaAlignOf(attrlen int) int {
 | 
				
			||||||
	return (attrlen + unix.RTA_ALIGNTO - 1) & ^(unix.RTA_ALIGNTO - 1)
 | 
						return (attrlen + unix.RTA_ALIGNTO - 1) & ^(unix.RTA_ALIGNTO - 1)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -259,6 +331,42 @@ func NewIfInfomsgChild(parent *RtAttr, family int) *IfInfomsg {
 | 
				
			|||||||
	return msg
 | 
						return msg
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Uint32Bitfield struct {
 | 
				
			||||||
 | 
						Value    uint32
 | 
				
			||||||
 | 
						Selector uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (a *Uint32Bitfield) Serialize() []byte {
 | 
				
			||||||
 | 
						return (*(*[SizeofUint32Bitfield]byte)(unsafe.Pointer(a)))[:]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func DeserializeUint32Bitfield(data []byte) *Uint32Bitfield {
 | 
				
			||||||
 | 
						return (*Uint32Bitfield)(unsafe.Pointer(&data[0:SizeofUint32Bitfield][0]))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Uint32Attribute struct {
 | 
				
			||||||
 | 
						Type  uint16
 | 
				
			||||||
 | 
						Value uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (a *Uint32Attribute) Serialize() []byte {
 | 
				
			||||||
 | 
						native := NativeEndian()
 | 
				
			||||||
 | 
						buf := make([]byte, rtaAlignOf(8))
 | 
				
			||||||
 | 
						native.PutUint16(buf[0:2], 8)
 | 
				
			||||||
 | 
						native.PutUint16(buf[2:4], a.Type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if a.Type&NLA_F_NET_BYTEORDER != 0 {
 | 
				
			||||||
 | 
							binary.BigEndian.PutUint32(buf[4:], a.Value)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							native.PutUint32(buf[4:], a.Value)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return buf
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (a *Uint32Attribute) Len() int {
 | 
				
			||||||
 | 
						return 8
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Extend RtAttr to handle data and children
 | 
					// Extend RtAttr to handle data and children
 | 
				
			||||||
type RtAttr struct {
 | 
					type RtAttr struct {
 | 
				
			||||||
	unix.RtAttr
 | 
						unix.RtAttr
 | 
				
			||||||
@@ -381,10 +489,30 @@ func (req *NetlinkRequest) AddRawData(data []byte) {
 | 
				
			|||||||
	req.RawData = append(req.RawData, data...)
 | 
						req.RawData = append(req.RawData, data...)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Execute the request against a the given sockType.
 | 
					// Execute the request against the given sockType.
 | 
				
			||||||
// Returns a list of netlink messages in serialized format, optionally filtered
 | 
					// Returns a list of netlink messages in serialized format, optionally filtered
 | 
				
			||||||
// by resType.
 | 
					// by resType.
 | 
				
			||||||
func (req *NetlinkRequest) Execute(sockType int, resType uint16) ([][]byte, error) {
 | 
					func (req *NetlinkRequest) Execute(sockType int, resType uint16) ([][]byte, error) {
 | 
				
			||||||
 | 
						var res [][]byte
 | 
				
			||||||
 | 
						err := req.ExecuteIter(sockType, resType, func(msg []byte) bool {
 | 
				
			||||||
 | 
							res = append(res, msg)
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return res, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ExecuteIter executes the request against the given sockType.
 | 
				
			||||||
 | 
					// Calls the provided callback func once for each netlink message.
 | 
				
			||||||
 | 
					// If the callback returns false, it is not called again, but
 | 
				
			||||||
 | 
					// the remaining messages are consumed/discarded.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Thread safety: ExecuteIter holds a lock on the socket until
 | 
				
			||||||
 | 
					// it finishes iteration so the callback must not call back into
 | 
				
			||||||
 | 
					// the netlink API.
 | 
				
			||||||
 | 
					func (req *NetlinkRequest) ExecuteIter(sockType int, resType uint16, f func(msg []byte) bool) error {
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		s   *NetlinkSocket
 | 
							s   *NetlinkSocket
 | 
				
			||||||
		err error
 | 
							err error
 | 
				
			||||||
@@ -401,8 +529,21 @@ func (req *NetlinkRequest) Execute(sockType int, resType uint16) ([][]byte, erro
 | 
				
			|||||||
	if s == nil {
 | 
						if s == nil {
 | 
				
			||||||
		s, err = getNetlinkSocket(sockType)
 | 
							s, err = getNetlinkSocket(sockType)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err := s.SetSendTimeout(&SocketTimeoutTv); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if err := s.SetReceiveTimeout(&SocketTimeoutTv); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if EnableErrorMessageReporting {
 | 
				
			||||||
 | 
								if err := s.SetExtAck(true); err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		defer s.Close()
 | 
							defer s.Close()
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		s.Lock()
 | 
							s.Lock()
 | 
				
			||||||
@@ -410,56 +551,94 @@ func (req *NetlinkRequest) Execute(sockType int, resType uint16) ([][]byte, erro
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := s.Send(req); err != nil {
 | 
						if err := s.Send(req); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pid, err := s.GetPid()
 | 
						pid, err := s.GetPid()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var res [][]byte
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
done:
 | 
					done:
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
		msgs, from, err := s.Receive()
 | 
							msgs, from, err := s.Receive()
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if from.Pid != PidKernel {
 | 
							if from.Pid != PidKernel {
 | 
				
			||||||
			return nil, fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, PidKernel)
 | 
								return fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, PidKernel)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		for _, m := range msgs {
 | 
							for _, m := range msgs {
 | 
				
			||||||
			if m.Header.Seq != req.Seq {
 | 
								if m.Header.Seq != req.Seq {
 | 
				
			||||||
				if sharedSocket {
 | 
									if sharedSocket {
 | 
				
			||||||
					continue
 | 
										continue
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				return nil, fmt.Errorf("Wrong Seq nr %d, expected %d", m.Header.Seq, req.Seq)
 | 
									return fmt.Errorf("Wrong Seq nr %d, expected %d", m.Header.Seq, req.Seq)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if m.Header.Pid != pid {
 | 
								if m.Header.Pid != pid {
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if m.Header.Type == unix.NLMSG_DONE {
 | 
					
 | 
				
			||||||
 | 
								if m.Header.Flags&unix.NLM_F_DUMP_INTR != 0 {
 | 
				
			||||||
 | 
									return syscall.Errno(unix.EINTR)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if m.Header.Type == unix.NLMSG_DONE || m.Header.Type == unix.NLMSG_ERROR {
 | 
				
			||||||
 | 
									// NLMSG_DONE might have no payload, if so assume no error.
 | 
				
			||||||
 | 
									if m.Header.Type == unix.NLMSG_DONE && len(m.Data) == 0 {
 | 
				
			||||||
					break done
 | 
										break done
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			if m.Header.Type == unix.NLMSG_ERROR {
 | 
					
 | 
				
			||||||
				native := NativeEndian()
 | 
									native := NativeEndian()
 | 
				
			||||||
				error := int32(native.Uint32(m.Data[0:4]))
 | 
									errno := int32(native.Uint32(m.Data[0:4]))
 | 
				
			||||||
				if error == 0 {
 | 
									if errno == 0 {
 | 
				
			||||||
					break done
 | 
										break done
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				return nil, syscall.Errno(-error)
 | 
									var err error
 | 
				
			||||||
 | 
									err = syscall.Errno(-errno)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									unreadData := m.Data[4:]
 | 
				
			||||||
 | 
									if m.Header.Flags&unix.NLM_F_ACK_TLVS != 0 && len(unreadData) > syscall.SizeofNlMsghdr {
 | 
				
			||||||
 | 
										// Skip the echoed request message.
 | 
				
			||||||
 | 
										echoReqH := (*syscall.NlMsghdr)(unsafe.Pointer(&unreadData[0]))
 | 
				
			||||||
 | 
										unreadData = unreadData[nlmAlignOf(int(echoReqH.Len)):]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										// Annotate `err` using nlmsgerr attributes.
 | 
				
			||||||
 | 
										for len(unreadData) >= syscall.SizeofRtAttr {
 | 
				
			||||||
 | 
											attr := (*syscall.RtAttr)(unsafe.Pointer(&unreadData[0]))
 | 
				
			||||||
 | 
											attrData := unreadData[syscall.SizeofRtAttr:attr.Len]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											switch attr.Type {
 | 
				
			||||||
 | 
											case NLMSGERR_ATTR_MSG:
 | 
				
			||||||
 | 
												err = fmt.Errorf("%w: %s", err, unix.ByteSliceToString(attrData))
 | 
				
			||||||
 | 
											default:
 | 
				
			||||||
 | 
												// TODO: handle other NLMSGERR_ATTR types
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											unreadData = unreadData[rtaAlignOf(int(attr.Len)):]
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if resType != 0 && m.Header.Type != resType {
 | 
								if resType != 0 && m.Header.Type != resType {
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			res = append(res, m.Data)
 | 
								if cont := f(m.Data); !cont {
 | 
				
			||||||
 | 
									// Drain the rest of the messages from the kernel but don't
 | 
				
			||||||
 | 
									// pass them to the iterator func.
 | 
				
			||||||
 | 
									f = dummyMsgIterFunc
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			if m.Header.Flags&unix.NLM_F_MULTI == 0 {
 | 
								if m.Header.Flags&unix.NLM_F_MULTI == 0 {
 | 
				
			||||||
				break done
 | 
									break done
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return res, nil
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func dummyMsgIterFunc(msg []byte) bool {
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Create a new netlink request from proto and flags
 | 
					// Create a new netlink request from proto and flags
 | 
				
			||||||
@@ -478,6 +657,7 @@ func NewNetlinkRequest(proto, flags int) *NetlinkRequest {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type NetlinkSocket struct {
 | 
					type NetlinkSocket struct {
 | 
				
			||||||
	fd   int32
 | 
						fd   int32
 | 
				
			||||||
 | 
						file *os.File
 | 
				
			||||||
	lsa  unix.SockaddrNetlink
 | 
						lsa  unix.SockaddrNetlink
 | 
				
			||||||
	sync.Mutex
 | 
						sync.Mutex
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -487,8 +667,13 @@ func getNetlinkSocket(protocol int) (*NetlinkSocket, error) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						err = unix.SetNonblock(fd, true)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	s := &NetlinkSocket{
 | 
						s := &NetlinkSocket{
 | 
				
			||||||
		fd:   int32(fd),
 | 
							fd:   int32(fd),
 | 
				
			||||||
 | 
							file: os.NewFile(uintptr(fd), "netlink"),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	s.lsa.Family = unix.AF_NETLINK
 | 
						s.lsa.Family = unix.AF_NETLINK
 | 
				
			||||||
	if err := unix.Bind(fd, &s.lsa); err != nil {
 | 
						if err := unix.Bind(fd, &s.lsa); err != nil {
 | 
				
			||||||
@@ -519,12 +704,14 @@ func GetNetlinkSocketAt(newNs, curNs netns.NsHandle, protocol int) (*NetlinkSock
 | 
				
			|||||||
// In case of success, the caller is expected to execute the returned function
 | 
					// In case of success, the caller is expected to execute the returned function
 | 
				
			||||||
// at the end of the code that needs to be executed in the network namespace.
 | 
					// at the end of the code that needs to be executed in the network namespace.
 | 
				
			||||||
// Example:
 | 
					// Example:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
//	func jobAt(...) error {
 | 
					//	func jobAt(...) error {
 | 
				
			||||||
//	     d, err := executeInNetns(...)
 | 
					//	     d, err := executeInNetns(...)
 | 
				
			||||||
//	     if err != nil { return err}
 | 
					//	     if err != nil { return err}
 | 
				
			||||||
//	     defer d()
 | 
					//	     defer d()
 | 
				
			||||||
//	     < code which needs to be executed in specific netns>
 | 
					//	     < code which needs to be executed in specific netns>
 | 
				
			||||||
//	 }
 | 
					//	 }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
// TODO: his function probably belongs to netns pkg.
 | 
					// TODO: his function probably belongs to netns pkg.
 | 
				
			||||||
func executeInNetns(newNs, curNs netns.NsHandle) (func(), error) {
 | 
					func executeInNetns(newNs, curNs netns.NsHandle) (func(), error) {
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
@@ -573,8 +760,13 @@ func Subscribe(protocol int, groups ...uint) (*NetlinkSocket, error) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						err = unix.SetNonblock(fd, true)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	s := &NetlinkSocket{
 | 
						s := &NetlinkSocket{
 | 
				
			||||||
		fd:   int32(fd),
 | 
							fd:   int32(fd),
 | 
				
			||||||
 | 
							file: os.NewFile(uintptr(fd), "netlink"),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	s.lsa.Family = unix.AF_NETLINK
 | 
						s.lsa.Family = unix.AF_NETLINK
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -603,33 +795,36 @@ func SubscribeAt(newNs, curNs netns.NsHandle, protocol int, groups ...uint) (*Ne
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *NetlinkSocket) Close() {
 | 
					func (s *NetlinkSocket) Close() {
 | 
				
			||||||
	fd := int(atomic.SwapInt32(&s.fd, -1))
 | 
						s.file.Close()
 | 
				
			||||||
	unix.Close(fd)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *NetlinkSocket) GetFd() int {
 | 
					func (s *NetlinkSocket) GetFd() int {
 | 
				
			||||||
	return int(atomic.LoadInt32(&s.fd))
 | 
						return int(s.fd)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *NetlinkSocket) Send(request *NetlinkRequest) error {
 | 
					func (s *NetlinkSocket) Send(request *NetlinkRequest) error {
 | 
				
			||||||
	fd := int(atomic.LoadInt32(&s.fd))
 | 
						return unix.Sendto(int(s.fd), request.Serialize(), 0, &s.lsa)
 | 
				
			||||||
	if fd < 0 {
 | 
					 | 
				
			||||||
		return fmt.Errorf("Send called on a closed socket")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := unix.Sendto(fd, request.Serialize(), 0, &s.lsa); err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, *unix.SockaddrNetlink, error) {
 | 
					func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, *unix.SockaddrNetlink, error) {
 | 
				
			||||||
	fd := int(atomic.LoadInt32(&s.fd))
 | 
						rawConn, err := s.file.SyscallConn()
 | 
				
			||||||
	if fd < 0 {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, nil, fmt.Errorf("Receive called on a closed socket")
 | 
							return nil, nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var (
 | 
				
			||||||
 | 
							fromAddr *unix.SockaddrNetlink
 | 
				
			||||||
 | 
							rb       [RECEIVE_BUFFER_SIZE]byte
 | 
				
			||||||
 | 
							nr       int
 | 
				
			||||||
 | 
							from     unix.Sockaddr
 | 
				
			||||||
 | 
							innerErr error
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						err = rawConn.Read(func(fd uintptr) (done bool) {
 | 
				
			||||||
 | 
							nr, from, innerErr = unix.Recvfrom(int(fd), rb[:], 0)
 | 
				
			||||||
 | 
							return innerErr != unix.EWOULDBLOCK
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if innerErr != nil {
 | 
				
			||||||
 | 
							err = innerErr
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	var fromAddr *unix.SockaddrNetlink
 | 
					 | 
				
			||||||
	var rb [RECEIVE_BUFFER_SIZE]byte
 | 
					 | 
				
			||||||
	nr, from, err := unix.Recvfrom(fd, rb[:], 0)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -640,8 +835,9 @@ func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, *unix.SockaddrNetli
 | 
				
			|||||||
	if nr < unix.NLMSG_HDRLEN {
 | 
						if nr < unix.NLMSG_HDRLEN {
 | 
				
			||||||
		return nil, nil, fmt.Errorf("Got short response from netlink")
 | 
							return nil, nil, fmt.Errorf("Got short response from netlink")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	rb2 := make([]byte, nr)
 | 
						msgLen := nlmAlignOf(nr)
 | 
				
			||||||
	copy(rb2, rb[:nr])
 | 
						rb2 := make([]byte, msgLen)
 | 
				
			||||||
 | 
						copy(rb2, rb[:msgLen])
 | 
				
			||||||
	nl, err := syscall.ParseNetlinkMessage(rb2)
 | 
						nl, err := syscall.ParseNetlinkMessage(rb2)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, nil, err
 | 
							return nil, nil, err
 | 
				
			||||||
@@ -663,9 +859,27 @@ func (s *NetlinkSocket) SetReceiveTimeout(timeout *unix.Timeval) error {
 | 
				
			|||||||
	return unix.SetsockoptTimeval(int(s.fd), unix.SOL_SOCKET, unix.SO_RCVTIMEO, timeout)
 | 
						return unix.SetsockoptTimeval(int(s.fd), unix.SOL_SOCKET, unix.SO_RCVTIMEO, timeout)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetReceiveBufferSize allows to set a receive buffer size on the socket
 | 
				
			||||||
 | 
					func (s *NetlinkSocket) SetReceiveBufferSize(size int, force bool) error {
 | 
				
			||||||
 | 
						opt := unix.SO_RCVBUF
 | 
				
			||||||
 | 
						if force {
 | 
				
			||||||
 | 
							opt = unix.SO_RCVBUFFORCE
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return unix.SetsockoptInt(int(s.fd), unix.SOL_SOCKET, opt, size)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetExtAck requests error messages to be reported on the socket
 | 
				
			||||||
 | 
					func (s *NetlinkSocket) SetExtAck(enable bool) error {
 | 
				
			||||||
 | 
						var enableN int
 | 
				
			||||||
 | 
						if enable {
 | 
				
			||||||
 | 
							enableN = 1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return unix.SetsockoptInt(int(s.fd), unix.SOL_NETLINK, unix.NETLINK_EXT_ACK, enableN)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *NetlinkSocket) GetPid() (uint32, error) {
 | 
					func (s *NetlinkSocket) GetPid() (uint32, error) {
 | 
				
			||||||
	fd := int(atomic.LoadInt32(&s.fd))
 | 
						lsa, err := unix.Getsockname(int(s.fd))
 | 
				
			||||||
	lsa, err := unix.Getsockname(fd)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return 0, err
 | 
							return 0, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -709,6 +923,12 @@ func Uint16Attr(v uint16) []byte {
 | 
				
			|||||||
	return bytes
 | 
						return bytes
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func BEUint16Attr(v uint16) []byte {
 | 
				
			||||||
 | 
						bytes := make([]byte, 2)
 | 
				
			||||||
 | 
						binary.BigEndian.PutUint16(bytes, v)
 | 
				
			||||||
 | 
						return bytes
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Uint32Attr(v uint32) []byte {
 | 
					func Uint32Attr(v uint32) []byte {
 | 
				
			||||||
	native := NativeEndian()
 | 
						native := NativeEndian()
 | 
				
			||||||
	bytes := make([]byte, 4)
 | 
						bytes := make([]byte, 4)
 | 
				
			||||||
@@ -716,6 +936,12 @@ func Uint32Attr(v uint32) []byte {
 | 
				
			|||||||
	return bytes
 | 
						return bytes
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func BEUint32Attr(v uint32) []byte {
 | 
				
			||||||
 | 
						bytes := make([]byte, 4)
 | 
				
			||||||
 | 
						binary.BigEndian.PutUint32(bytes, v)
 | 
				
			||||||
 | 
						return bytes
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Uint64Attr(v uint64) []byte {
 | 
					func Uint64Attr(v uint64) []byte {
 | 
				
			||||||
	native := NativeEndian()
 | 
						native := NativeEndian()
 | 
				
			||||||
	bytes := make([]byte, 8)
 | 
						bytes := make([]byte, 8)
 | 
				
			||||||
@@ -723,6 +949,12 @@ func Uint64Attr(v uint64) []byte {
 | 
				
			|||||||
	return bytes
 | 
						return bytes
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func BEUint64Attr(v uint64) []byte {
 | 
				
			||||||
 | 
						bytes := make([]byte, 8)
 | 
				
			||||||
 | 
						binary.BigEndian.PutUint64(bytes, v)
 | 
				
			||||||
 | 
						return bytes
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ParseRouteAttr(b []byte) ([]syscall.NetlinkRouteAttr, error) {
 | 
					func ParseRouteAttr(b []byte) ([]syscall.NetlinkRouteAttr, error) {
 | 
				
			||||||
	var attrs []syscall.NetlinkRouteAttr
 | 
						var attrs []syscall.NetlinkRouteAttr
 | 
				
			||||||
	for len(b) >= unix.SizeofRtAttr {
 | 
						for len(b) >= unix.SizeofRtAttr {
 | 
				
			||||||
@@ -737,6 +969,22 @@ func ParseRouteAttr(b []byte) ([]syscall.NetlinkRouteAttr, error) {
 | 
				
			|||||||
	return attrs, nil
 | 
						return attrs, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ParseRouteAttrAsMap parses provided buffer that contains raw RtAttrs and returns a map of parsed
 | 
				
			||||||
 | 
					// atttributes indexed by attribute type or error if occured.
 | 
				
			||||||
 | 
					func ParseRouteAttrAsMap(b []byte) (map[uint16]syscall.NetlinkRouteAttr, error) {
 | 
				
			||||||
 | 
						attrMap := make(map[uint16]syscall.NetlinkRouteAttr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						attrs, err := ParseRouteAttr(b)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, attr := range attrs {
 | 
				
			||||||
 | 
							attrMap[attr.Attr.Type] = attr
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return attrMap, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func netlinkRouteAttrAndValue(b []byte) (*unix.RtAttr, []byte, int, error) {
 | 
					func netlinkRouteAttrAndValue(b []byte) (*unix.RtAttr, []byte, int, error) {
 | 
				
			||||||
	a := (*unix.RtAttr)(unsafe.Pointer(&b[0]))
 | 
						a := (*unix.RtAttr)(unsafe.Pointer(&b[0]))
 | 
				
			||||||
	if int(a.Len) < unix.SizeofRtAttr || int(a.Len) > len(b) {
 | 
						if int(a.Len) < unix.SizeofRtAttr || int(a.Len) > len(b) {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										79
									
								
								vendor/github.com/vishvananda/netlink/nl/parse_attr_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								vendor/github.com/vishvananda/netlink/nl/parse_attr_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
				
			|||||||
 | 
					package nl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/binary"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Attribute struct {
 | 
				
			||||||
 | 
						Type  uint16
 | 
				
			||||||
 | 
						Value []byte
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ParseAttributes(data []byte) <-chan Attribute {
 | 
				
			||||||
 | 
						native := NativeEndian()
 | 
				
			||||||
 | 
						result := make(chan Attribute)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						go func() {
 | 
				
			||||||
 | 
							i := 0
 | 
				
			||||||
 | 
							for i+4 < len(data) {
 | 
				
			||||||
 | 
								length := int(native.Uint16(data[i : i+2]))
 | 
				
			||||||
 | 
								attrType := native.Uint16(data[i+2 : i+4])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if length < 4 {
 | 
				
			||||||
 | 
									log.Printf("attribute 0x%02x has invalid length of %d bytes", attrType, length)
 | 
				
			||||||
 | 
									break
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if len(data) < i+length {
 | 
				
			||||||
 | 
									log.Printf("attribute 0x%02x of length %d is truncated, only %d bytes remaining", attrType, length, len(data)-i)
 | 
				
			||||||
 | 
									break
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								result <- Attribute{
 | 
				
			||||||
 | 
									Type:  attrType,
 | 
				
			||||||
 | 
									Value: data[i+4 : i+length],
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								i += rtaAlignOf(length)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							close(result)
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func PrintAttributes(data []byte) {
 | 
				
			||||||
 | 
						printAttributes(data, 0)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func printAttributes(data []byte, level int) {
 | 
				
			||||||
 | 
						for attr := range ParseAttributes(data) {
 | 
				
			||||||
 | 
							for i := 0; i < level; i++ {
 | 
				
			||||||
 | 
								print("> ")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							nested := attr.Type&NLA_F_NESTED != 0
 | 
				
			||||||
 | 
							fmt.Printf("type=%d nested=%v len=%v %v\n", attr.Type&NLA_TYPE_MASK, nested, len(attr.Value), attr.Value)
 | 
				
			||||||
 | 
							if nested {
 | 
				
			||||||
 | 
								printAttributes(attr.Value, level+1)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Uint32 returns the uint32 value respecting the NET_BYTEORDER flag
 | 
				
			||||||
 | 
					func (attr *Attribute) Uint32() uint32 {
 | 
				
			||||||
 | 
						if attr.Type&NLA_F_NET_BYTEORDER != 0 {
 | 
				
			||||||
 | 
							return binary.BigEndian.Uint32(attr.Value)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return NativeEndian().Uint32(attr.Value)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Uint64 returns the uint64 value respecting the NET_BYTEORDER flag
 | 
				
			||||||
 | 
					func (attr *Attribute) Uint64() uint64 {
 | 
				
			||||||
 | 
						if attr.Type&NLA_F_NET_BYTEORDER != 0 {
 | 
				
			||||||
 | 
							return binary.BigEndian.Uint64(attr.Value)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return NativeEndian().Uint64(attr.Value)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										4
									
								
								vendor/github.com/vishvananda/netlink/nl/rdma_link_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/vishvananda/netlink/nl/rdma_link_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -11,6 +11,8 @@ const (
 | 
				
			|||||||
const (
 | 
					const (
 | 
				
			||||||
	RDMA_NLDEV_CMD_GET     = 1
 | 
						RDMA_NLDEV_CMD_GET     = 1
 | 
				
			||||||
	RDMA_NLDEV_CMD_SET     = 2
 | 
						RDMA_NLDEV_CMD_SET     = 2
 | 
				
			||||||
 | 
						RDMA_NLDEV_CMD_NEWLINK = 3
 | 
				
			||||||
 | 
						RDMA_NLDEV_CMD_DELLINK = 4
 | 
				
			||||||
	RDMA_NLDEV_CMD_SYS_GET = 6
 | 
						RDMA_NLDEV_CMD_SYS_GET = 6
 | 
				
			||||||
	RDMA_NLDEV_CMD_SYS_SET = 7
 | 
						RDMA_NLDEV_CMD_SYS_SET = 7
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -30,6 +32,8 @@ const (
 | 
				
			|||||||
	RDMA_NLDEV_ATTR_PORT_STATE      = 12
 | 
						RDMA_NLDEV_ATTR_PORT_STATE      = 12
 | 
				
			||||||
	RDMA_NLDEV_ATTR_PORT_PHYS_STATE = 13
 | 
						RDMA_NLDEV_ATTR_PORT_PHYS_STATE = 13
 | 
				
			||||||
	RDMA_NLDEV_ATTR_DEV_NODE_TYPE   = 14
 | 
						RDMA_NLDEV_ATTR_DEV_NODE_TYPE   = 14
 | 
				
			||||||
 | 
						RDMA_NLDEV_ATTR_NDEV_NAME       = 51
 | 
				
			||||||
 | 
						RDMA_NLDEV_ATTR_LINK_TYPE       = 65
 | 
				
			||||||
	RDMA_NLDEV_SYS_ATTR_NETNS_MODE  = 66
 | 
						RDMA_NLDEV_SYS_ATTR_NETNS_MODE  = 66
 | 
				
			||||||
	RDMA_NLDEV_NET_NS_FD            = 68
 | 
						RDMA_NLDEV_NET_NS_FD            = 68
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								vendor/github.com/vishvananda/netlink/nl/route_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/vishvananda/netlink/nl/route_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -48,7 +48,9 @@ type RtNexthop struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func DeserializeRtNexthop(b []byte) *RtNexthop {
 | 
					func DeserializeRtNexthop(b []byte) *RtNexthop {
 | 
				
			||||||
	return (*RtNexthop)(unsafe.Pointer(&b[0:unix.SizeofRtNexthop][0]))
 | 
						return &RtNexthop{
 | 
				
			||||||
 | 
							RtNexthop: *((*unix.RtNexthop)(unsafe.Pointer(&b[0:unix.SizeofRtNexthop][0]))),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (msg *RtNexthop) Len() int {
 | 
					func (msg *RtNexthop) Len() int {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								vendor/github.com/vishvananda/netlink/nl/seg6_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/vishvananda/netlink/nl/seg6_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -23,7 +23,7 @@ func (s1 *IPv6SrHdr) Equal(s2 IPv6SrHdr) bool {
 | 
				
			|||||||
		return false
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for i := range s1.Segments {
 | 
						for i := range s1.Segments {
 | 
				
			||||||
		if s1.Segments[i].Equal(s2.Segments[i]) != true {
 | 
							if !s1.Segments[i].Equal(s2.Segments[i]) {
 | 
				
			||||||
			return false
 | 
								return false
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -89,7 +89,7 @@ func DecodeSEG6Encap(buf []byte) (int, []net.IP, error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	buf = buf[12:]
 | 
						buf = buf[12:]
 | 
				
			||||||
	if len(buf)%16 != 0 {
 | 
						if len(buf)%16 != 0 {
 | 
				
			||||||
		err := fmt.Errorf("DecodeSEG6Encap: error parsing Segment List (buf len: %d)\n", len(buf))
 | 
							err := fmt.Errorf("DecodeSEG6Encap: error parsing Segment List (buf len: %d)", len(buf))
 | 
				
			||||||
		return mode, nil, err
 | 
							return mode, nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for len(buf) > 0 {
 | 
						for len(buf) > 0 {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								vendor/github.com/vishvananda/netlink/nl/seg6local_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/vishvananda/netlink/nl/seg6local_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -12,6 +12,7 @@ const (
 | 
				
			|||||||
	SEG6_LOCAL_NH6
 | 
						SEG6_LOCAL_NH6
 | 
				
			||||||
	SEG6_LOCAL_IIF
 | 
						SEG6_LOCAL_IIF
 | 
				
			||||||
	SEG6_LOCAL_OIF
 | 
						SEG6_LOCAL_OIF
 | 
				
			||||||
 | 
						SEG6_LOCAL_BPF
 | 
				
			||||||
	__SEG6_LOCAL_MAX
 | 
						__SEG6_LOCAL_MAX
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -34,6 +35,7 @@ const (
 | 
				
			|||||||
	SEG6_LOCAL_ACTION_END_S                    // 12
 | 
						SEG6_LOCAL_ACTION_END_S                    // 12
 | 
				
			||||||
	SEG6_LOCAL_ACTION_END_AS                   // 13
 | 
						SEG6_LOCAL_ACTION_END_AS                   // 13
 | 
				
			||||||
	SEG6_LOCAL_ACTION_END_AM                   // 14
 | 
						SEG6_LOCAL_ACTION_END_AM                   // 14
 | 
				
			||||||
 | 
						SEG6_LOCAL_ACTION_END_BPF                  // 15
 | 
				
			||||||
	__SEG6_LOCAL_ACTION_MAX
 | 
						__SEG6_LOCAL_ACTION_MAX
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -71,6 +73,8 @@ func SEG6LocalActionString(action int) string {
 | 
				
			|||||||
		return "End.AS"
 | 
							return "End.AS"
 | 
				
			||||||
	case SEG6_LOCAL_ACTION_END_AM:
 | 
						case SEG6_LOCAL_ACTION_END_AM:
 | 
				
			||||||
		return "End.AM"
 | 
							return "End.AM"
 | 
				
			||||||
 | 
						case SEG6_LOCAL_ACTION_END_BPF:
 | 
				
			||||||
 | 
							return "End.BPF"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return "unknown"
 | 
						return "unknown"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								vendor/github.com/vishvananda/netlink/nl/syscall.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/vishvananda/netlink/nl/syscall.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,6 +1,6 @@
 | 
				
			|||||||
package nl
 | 
					package nl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// syscall package lack of rule atributes type.
 | 
					// syscall package lack of rule attributes type.
 | 
				
			||||||
// Thus there are defined below
 | 
					// Thus there are defined below
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	FRA_UNSPEC  = iota
 | 
						FRA_UNSPEC  = iota
 | 
				
			||||||
@@ -21,6 +21,13 @@ const (
 | 
				
			|||||||
	FRA_TABLE  /* Extended table id */
 | 
						FRA_TABLE  /* Extended table id */
 | 
				
			||||||
	FRA_FWMASK /* mask for netfilter mark */
 | 
						FRA_FWMASK /* mask for netfilter mark */
 | 
				
			||||||
	FRA_OIFNAME
 | 
						FRA_OIFNAME
 | 
				
			||||||
 | 
						FRA_PAD
 | 
				
			||||||
 | 
						FRA_L3MDEV      /* iif or oif is l3mdev goto its table */
 | 
				
			||||||
 | 
						FRA_UID_RANGE   /* UID range */
 | 
				
			||||||
 | 
						FRA_PROTOCOL    /* Originator of the rule */
 | 
				
			||||||
 | 
						FRA_IP_PROTO    /* ip proto */
 | 
				
			||||||
 | 
						FRA_SPORT_RANGE /* sport */
 | 
				
			||||||
 | 
						FRA_DPORT_RANGE /* dport */
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ip rule netlink request types
 | 
					// ip rule netlink request types
 | 
				
			||||||
@@ -39,6 +46,7 @@ const (
 | 
				
			|||||||
// socket diags related
 | 
					// socket diags related
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	SOCK_DIAG_BY_FAMILY = 20         /* linux.sock_diag.h */
 | 
						SOCK_DIAG_BY_FAMILY = 20         /* linux.sock_diag.h */
 | 
				
			||||||
 | 
						SOCK_DESTROY	    = 21
 | 
				
			||||||
	TCPDIAG_NOCOOKIE    = 0xFFFFFFFF /* TCPDIAG_NOCOOKIE in net/ipv4/tcp_diag.h*/
 | 
						TCPDIAG_NOCOOKIE    = 0xFFFFFFFF /* TCPDIAG_NOCOOKIE in net/ipv4/tcp_diag.h*/
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										747
									
								
								vendor/github.com/vishvananda/netlink/nl/tc_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										747
									
								
								vendor/github.com/vishvananda/netlink/nl/tc_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,8 +1,13 @@
 | 
				
			|||||||
package nl
 | 
					package nl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
	"encoding/binary"
 | 
						"encoding/binary"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
	"unsafe"
 | 
						"unsafe"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"golang.org/x/sys/unix"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// LinkLayer
 | 
					// LinkLayer
 | 
				
			||||||
@@ -42,7 +47,14 @@ const (
 | 
				
			|||||||
	TCA_FCNT
 | 
						TCA_FCNT
 | 
				
			||||||
	TCA_STATS2
 | 
						TCA_STATS2
 | 
				
			||||||
	TCA_STAB
 | 
						TCA_STAB
 | 
				
			||||||
	TCA_MAX = TCA_STAB
 | 
						TCA_PAD
 | 
				
			||||||
 | 
						TCA_DUMP_INVISIBLE
 | 
				
			||||||
 | 
						TCA_CHAIN
 | 
				
			||||||
 | 
						TCA_HW_OFFLOAD
 | 
				
			||||||
 | 
						TCA_INGRESS_BLOCK
 | 
				
			||||||
 | 
						TCA_EGRESS_BLOCK
 | 
				
			||||||
 | 
						TCA_DUMP_FLAGS
 | 
				
			||||||
 | 
						TCA_MAX = TCA_DUMP_FLAGS
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -56,6 +68,12 @@ const (
 | 
				
			|||||||
	TCA_ACT_OPTIONS
 | 
						TCA_ACT_OPTIONS
 | 
				
			||||||
	TCA_ACT_INDEX
 | 
						TCA_ACT_INDEX
 | 
				
			||||||
	TCA_ACT_STATS
 | 
						TCA_ACT_STATS
 | 
				
			||||||
 | 
						TCA_ACT_PAD
 | 
				
			||||||
 | 
						TCA_ACT_COOKIE
 | 
				
			||||||
 | 
						TCA_ACT_FLAGS
 | 
				
			||||||
 | 
						TCA_ACT_HW_STATS
 | 
				
			||||||
 | 
						TCA_ACT_USED_HW_STATS
 | 
				
			||||||
 | 
						TCA_ACT_IN_HW_COUNT
 | 
				
			||||||
	TCA_ACT_MAX
 | 
						TCA_ACT_MAX
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -71,7 +89,11 @@ const (
 | 
				
			|||||||
	TCA_STATS_RATE_EST
 | 
						TCA_STATS_RATE_EST
 | 
				
			||||||
	TCA_STATS_QUEUE
 | 
						TCA_STATS_QUEUE
 | 
				
			||||||
	TCA_STATS_APP
 | 
						TCA_STATS_APP
 | 
				
			||||||
	TCA_STATS_MAX = TCA_STATS_APP
 | 
						TCA_STATS_RATE_EST64
 | 
				
			||||||
 | 
						TCA_STATS_PAD
 | 
				
			||||||
 | 
						TCA_STATS_BASIC_HW
 | 
				
			||||||
 | 
						TCA_STATS_PKT64
 | 
				
			||||||
 | 
						TCA_STATS_MAX = TCA_STATS_PKT64
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -83,17 +105,23 @@ const (
 | 
				
			|||||||
	SizeofTcNetemCorr    = 0x0c
 | 
						SizeofTcNetemCorr    = 0x0c
 | 
				
			||||||
	SizeofTcNetemReorder = 0x08
 | 
						SizeofTcNetemReorder = 0x08
 | 
				
			||||||
	SizeofTcNetemCorrupt = 0x08
 | 
						SizeofTcNetemCorrupt = 0x08
 | 
				
			||||||
 | 
						SizeOfTcNetemRate    = 0x10
 | 
				
			||||||
	SizeofTcTbfQopt      = 2*SizeofTcRateSpec + 0x0c
 | 
						SizeofTcTbfQopt      = 2*SizeofTcRateSpec + 0x0c
 | 
				
			||||||
	SizeofTcHtbCopt      = 2*SizeofTcRateSpec + 0x14
 | 
						SizeofTcHtbCopt      = 2*SizeofTcRateSpec + 0x14
 | 
				
			||||||
	SizeofTcHtbGlob      = 0x14
 | 
						SizeofTcHtbGlob      = 0x14
 | 
				
			||||||
	SizeofTcU32Key       = 0x10
 | 
						SizeofTcU32Key       = 0x10
 | 
				
			||||||
	SizeofTcU32Sel       = 0x10 // without keys
 | 
						SizeofTcU32Sel       = 0x10 // without keys
 | 
				
			||||||
	SizeofTcGen          = 0x14
 | 
						SizeofTcGen          = 0x16
 | 
				
			||||||
	SizeofTcConnmark     = SizeofTcGen + 0x04
 | 
						SizeofTcConnmark     = SizeofTcGen + 0x04
 | 
				
			||||||
 | 
						SizeofTcCsum         = SizeofTcGen + 0x04
 | 
				
			||||||
	SizeofTcMirred       = SizeofTcGen + 0x08
 | 
						SizeofTcMirred       = SizeofTcGen + 0x08
 | 
				
			||||||
	SizeofTcTunnelKey    = SizeofTcGen + 0x04
 | 
						SizeofTcTunnelKey    = SizeofTcGen + 0x04
 | 
				
			||||||
	SizeofTcSkbEdit      = SizeofTcGen
 | 
						SizeofTcSkbEdit      = SizeofTcGen
 | 
				
			||||||
	SizeofTcPolice       = 2*SizeofTcRateSpec + 0x20
 | 
						SizeofTcPolice       = 2*SizeofTcRateSpec + 0x20
 | 
				
			||||||
 | 
						SizeofTcSfqQopt      = 0x0b
 | 
				
			||||||
 | 
						SizeofTcSfqRedStats  = 0x18
 | 
				
			||||||
 | 
						SizeofTcSfqQoptV1    = SizeofTcSfqQopt + SizeofTcSfqRedStats + 0x1c
 | 
				
			||||||
 | 
						SizeofUint32Bitfield = 0x8
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// struct tcmsg {
 | 
					// struct tcmsg {
 | 
				
			||||||
@@ -127,6 +155,18 @@ func (x *TcMsg) Serialize() []byte {
 | 
				
			|||||||
	return (*(*[SizeofTcMsg]byte)(unsafe.Pointer(x)))[:]
 | 
						return (*(*[SizeofTcMsg]byte)(unsafe.Pointer(x)))[:]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Tcf struct {
 | 
				
			||||||
 | 
						Install  uint64
 | 
				
			||||||
 | 
						LastUse  uint64
 | 
				
			||||||
 | 
						Expires  uint64
 | 
				
			||||||
 | 
						FirstUse uint64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func DeserializeTcf(b []byte) *Tcf {
 | 
				
			||||||
 | 
						const size = int(unsafe.Sizeof(Tcf{}))
 | 
				
			||||||
 | 
						return (*Tcf)(unsafe.Pointer(&b[0:size][0]))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// struct tcamsg {
 | 
					// struct tcamsg {
 | 
				
			||||||
//   unsigned char tca_family;
 | 
					//   unsigned char tca_family;
 | 
				
			||||||
//   unsigned char tca__pad1;
 | 
					//   unsigned char tca__pad1;
 | 
				
			||||||
@@ -333,6 +373,26 @@ func (x *TcNetemCorrupt) Serialize() []byte {
 | 
				
			|||||||
	return (*(*[SizeofTcNetemCorrupt]byte)(unsafe.Pointer(x)))[:]
 | 
						return (*(*[SizeofTcNetemCorrupt]byte)(unsafe.Pointer(x)))[:]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TcNetemRate is a struct that represents the rate of a netem qdisc
 | 
				
			||||||
 | 
					type TcNetemRate struct {
 | 
				
			||||||
 | 
						Rate           uint32
 | 
				
			||||||
 | 
						PacketOverhead int32
 | 
				
			||||||
 | 
						CellSize       uint32
 | 
				
			||||||
 | 
						CellOverhead   int32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (msg *TcNetemRate) Len() int {
 | 
				
			||||||
 | 
						return SizeofTcRateSpec
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func DeserializeTcNetemRate(b []byte) *TcNetemRate {
 | 
				
			||||||
 | 
						return (*TcNetemRate)(unsafe.Pointer(&b[0:SizeofTcRateSpec][0]))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (msg *TcNetemRate) Serialize() []byte {
 | 
				
			||||||
 | 
						return (*(*[SizeOfTcNetemRate]byte)(unsafe.Pointer(msg)))[:]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// struct tc_tbf_qopt {
 | 
					// struct tc_tbf_qopt {
 | 
				
			||||||
//   struct tc_ratespec rate;
 | 
					//   struct tc_ratespec rate;
 | 
				
			||||||
//   struct tc_ratespec peakrate;
 | 
					//   struct tc_ratespec peakrate;
 | 
				
			||||||
@@ -691,6 +751,36 @@ func (x *TcConnmark) Serialize() []byte {
 | 
				
			|||||||
	return (*(*[SizeofTcConnmark]byte)(unsafe.Pointer(x)))[:]
 | 
						return (*(*[SizeofTcConnmark]byte)(unsafe.Pointer(x)))[:]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						TCA_CSUM_UNSPEC = iota
 | 
				
			||||||
 | 
						TCA_CSUM_PARMS
 | 
				
			||||||
 | 
						TCA_CSUM_TM
 | 
				
			||||||
 | 
						TCA_CSUM_PAD
 | 
				
			||||||
 | 
						TCA_CSUM_MAX = TCA_CSUM_PAD
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// struct tc_csum {
 | 
				
			||||||
 | 
					//   tc_gen;
 | 
				
			||||||
 | 
					//   __u32 update_flags;
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type TcCsum struct {
 | 
				
			||||||
 | 
						TcGen
 | 
				
			||||||
 | 
						UpdateFlags uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (msg *TcCsum) Len() int {
 | 
				
			||||||
 | 
						return SizeofTcCsum
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func DeserializeTcCsum(b []byte) *TcCsum {
 | 
				
			||||||
 | 
						return (*TcCsum)(unsafe.Pointer(&b[0:SizeofTcCsum][0]))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (x *TcCsum) Serialize() []byte {
 | 
				
			||||||
 | 
						return (*(*[SizeofTcCsum]byte)(unsafe.Pointer(x)))[:]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	TCA_ACT_MIRRED = 8
 | 
						TCA_ACT_MIRRED = 8
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -735,7 +825,13 @@ const (
 | 
				
			|||||||
	TCA_TUNNEL_KEY_ENC_IPV6_SRC
 | 
						TCA_TUNNEL_KEY_ENC_IPV6_SRC
 | 
				
			||||||
	TCA_TUNNEL_KEY_ENC_IPV6_DST
 | 
						TCA_TUNNEL_KEY_ENC_IPV6_DST
 | 
				
			||||||
	TCA_TUNNEL_KEY_ENC_KEY_ID
 | 
						TCA_TUNNEL_KEY_ENC_KEY_ID
 | 
				
			||||||
	TCA_TUNNEL_KEY_MAX = TCA_TUNNEL_KEY_ENC_KEY_ID
 | 
						TCA_TUNNEL_KEY_PAD
 | 
				
			||||||
 | 
						TCA_TUNNEL_KEY_ENC_DST_PORT
 | 
				
			||||||
 | 
						TCA_TUNNEL_KEY_NO_CSUM
 | 
				
			||||||
 | 
						TCA_TUNNEL_KEY_ENC_OPTS
 | 
				
			||||||
 | 
						TCA_TUNNEL_KEY_ENC_TOS
 | 
				
			||||||
 | 
						TCA_TUNNEL_KEY_ENC_TTL
 | 
				
			||||||
 | 
						TCA_TUNNEL_KEY_MAX
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type TcTunnelKey struct {
 | 
					type TcTunnelKey struct {
 | 
				
			||||||
@@ -764,7 +860,8 @@ const (
 | 
				
			|||||||
	TCA_SKBEDIT_MARK
 | 
						TCA_SKBEDIT_MARK
 | 
				
			||||||
	TCA_SKBEDIT_PAD
 | 
						TCA_SKBEDIT_PAD
 | 
				
			||||||
	TCA_SKBEDIT_PTYPE
 | 
						TCA_SKBEDIT_PTYPE
 | 
				
			||||||
	TCA_SKBEDIT_MAX = TCA_SKBEDIT_MARK
 | 
						TCA_SKBEDIT_MASK
 | 
				
			||||||
 | 
						TCA_SKBEDIT_MAX
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type TcSkbEdit struct {
 | 
					type TcSkbEdit struct {
 | 
				
			||||||
@@ -851,6 +948,10 @@ const (
 | 
				
			|||||||
	TCA_FQ_FLOW_REFILL_DELAY  // flow credit refill delay in usec
 | 
						TCA_FQ_FLOW_REFILL_DELAY  // flow credit refill delay in usec
 | 
				
			||||||
	TCA_FQ_ORPHAN_MASK        // mask applied to orphaned skb hashes
 | 
						TCA_FQ_ORPHAN_MASK        // mask applied to orphaned skb hashes
 | 
				
			||||||
	TCA_FQ_LOW_RATE_THRESHOLD // per packet delay under this rate
 | 
						TCA_FQ_LOW_RATE_THRESHOLD // per packet delay under this rate
 | 
				
			||||||
 | 
						TCA_FQ_CE_THRESHOLD       // DCTCP-like CE-marking threshold
 | 
				
			||||||
 | 
						TCA_FQ_TIMER_SLACK        // timer slack
 | 
				
			||||||
 | 
						TCA_FQ_HORIZON            // time horizon in us
 | 
				
			||||||
 | 
						TCA_FQ_HORIZON_DROP       // drop packets beyond horizon, or cap their EDT
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -872,3 +973,639 @@ const (
 | 
				
			|||||||
	TCA_HFSC_FSC
 | 
						TCA_HFSC_FSC
 | 
				
			||||||
	TCA_HFSC_USC
 | 
						TCA_HFSC_USC
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						TCA_FLOWER_UNSPEC = iota
 | 
				
			||||||
 | 
						TCA_FLOWER_CLASSID
 | 
				
			||||||
 | 
						TCA_FLOWER_INDEV
 | 
				
			||||||
 | 
						TCA_FLOWER_ACT
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ETH_DST       /* ETH_ALEN */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ETH_DST_MASK  /* ETH_ALEN */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ETH_SRC       /* ETH_ALEN */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ETH_SRC_MASK  /* ETH_ALEN */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ETH_TYPE      /* be16 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_IP_PROTO      /* u8 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_IPV4_SRC      /* be32 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_IPV4_SRC_MASK /* be32 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_IPV4_DST      /* be32 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_IPV4_DST_MASK /* be32 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_IPV6_SRC      /* struct in6_addr */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_IPV6_SRC_MASK /* struct in6_addr */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_IPV6_DST      /* struct in6_addr */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_IPV6_DST_MASK /* struct in6_addr */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_TCP_SRC       /* be16 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_TCP_DST       /* be16 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_UDP_SRC       /* be16 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_UDP_DST       /* be16 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TCA_FLOWER_FLAGS
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_VLAN_ID       /* be16 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_VLAN_PRIO     /* u8   */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_VLAN_ETH_TYPE /* be16 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ENC_KEY_ID        /* be32 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ENC_IPV4_SRC      /* be32 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK /* be32 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ENC_IPV4_DST      /* be32 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ENC_IPV4_DST_MASK /* be32 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ENC_IPV6_SRC      /* struct in6_addr */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK /* struct in6_addr */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ENC_IPV6_DST      /* struct in6_addr */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ENC_IPV6_DST_MASK /* struct in6_addr */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_TCP_SRC_MASK  /* be16 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_TCP_DST_MASK  /* be16 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_UDP_SRC_MASK  /* be16 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_UDP_DST_MASK  /* be16 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_SCTP_SRC_MASK /* be16 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_SCTP_DST_MASK /* be16 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_SCTP_SRC /* be16 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_SCTP_DST /* be16 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ENC_UDP_SRC_PORT      /* be16 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK /* be16 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ENC_UDP_DST_PORT      /* be16 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK /* be16 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_FLAGS      /* be32 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_FLAGS_MASK /* be32 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ICMPV4_CODE      /* u8 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ICMPV4_CODE_MASK /* u8 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ICMPV4_TYPE      /* u8 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ICMPV4_TYPE_MASK /* u8 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ICMPV6_CODE      /* u8 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ICMPV6_CODE_MASK /* u8 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ICMPV6_TYPE      /* u8 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ICMPV6_TYPE_MASK /* u8 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ARP_SIP      /* be32 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ARP_SIP_MASK /* be32 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ARP_TIP      /* be32 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ARP_TIP_MASK /* be32 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ARP_OP       /* u8 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ARP_OP_MASK  /* u8 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ARP_SHA      /* ETH_ALEN */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ARP_SHA_MASK /* ETH_ALEN */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ARP_THA      /* ETH_ALEN */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ARP_THA_MASK /* ETH_ALEN */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_MPLS_TTL   /* u8 - 8 bits */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_MPLS_BOS   /* u8 - 1 bit */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_MPLS_TC    /* u8 - 3 bits */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_MPLS_LABEL /* be32 - 20 bits */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_TCP_FLAGS      /* be16 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_TCP_FLAGS_MASK /* be16 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_IP_TOS      /* u8 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_IP_TOS_MASK /* u8 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_IP_TTL      /* u8 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_IP_TTL_MASK /* u8 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_CVLAN_ID       /* be16 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_CVLAN_PRIO     /* u8   */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_CVLAN_ETH_TYPE /* be16 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ENC_IP_TOS      /* u8 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ENC_IP_TOS_MASK /* u8 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ENC_IP_TTL      /* u8 */
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ENC_IP_TTL_MASK /* u8 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ENC_OPTS
 | 
				
			||||||
 | 
						TCA_FLOWER_KEY_ENC_OPTS_MASK
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						__TCA_FLOWER_MAX
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const TCA_CLS_FLAGS_SKIP_HW = 1 << 0 /* don't offload filter to HW */
 | 
				
			||||||
 | 
					const TCA_CLS_FLAGS_SKIP_SW = 1 << 1 /* don't use filter in SW */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// struct tc_sfq_qopt {
 | 
				
			||||||
 | 
					// 	unsigned	quantum;	/* Bytes per round allocated to flow */
 | 
				
			||||||
 | 
					// 	int		perturb_period;	/* Period of hash perturbation */
 | 
				
			||||||
 | 
					// 	__u32		limit;		/* Maximal packets in queue */
 | 
				
			||||||
 | 
					// 	unsigned	divisor;	/* Hash divisor  */
 | 
				
			||||||
 | 
					// 	unsigned	flows;		/* Maximal number of flows  */
 | 
				
			||||||
 | 
					// };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type TcSfqQopt struct {
 | 
				
			||||||
 | 
						Quantum uint8
 | 
				
			||||||
 | 
						Perturb int32
 | 
				
			||||||
 | 
						Limit   uint32
 | 
				
			||||||
 | 
						Divisor uint8
 | 
				
			||||||
 | 
						Flows   uint8
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (x *TcSfqQopt) Len() int {
 | 
				
			||||||
 | 
						return SizeofTcSfqQopt
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func DeserializeTcSfqQopt(b []byte) *TcSfqQopt {
 | 
				
			||||||
 | 
						return (*TcSfqQopt)(unsafe.Pointer(&b[0:SizeofTcSfqQopt][0]))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (x *TcSfqQopt) Serialize() []byte {
 | 
				
			||||||
 | 
						return (*(*[SizeofTcSfqQopt]byte)(unsafe.Pointer(x)))[:]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//	struct tc_sfqred_stats {
 | 
				
			||||||
 | 
					//		__u32           prob_drop;      /* Early drops, below max threshold */
 | 
				
			||||||
 | 
					//		__u32           forced_drop;	/* Early drops, after max threshold */
 | 
				
			||||||
 | 
					//		__u32           prob_mark;      /* Marked packets, below max threshold */
 | 
				
			||||||
 | 
					//		__u32           forced_mark;    /* Marked packets, after max threshold */
 | 
				
			||||||
 | 
					//		__u32           prob_mark_head; /* Marked packets, below max threshold */
 | 
				
			||||||
 | 
					//		__u32           forced_mark_head;/* Marked packets, after max threshold */
 | 
				
			||||||
 | 
					//	};
 | 
				
			||||||
 | 
					type TcSfqRedStats struct {
 | 
				
			||||||
 | 
						ProbDrop       uint32
 | 
				
			||||||
 | 
						ForcedDrop     uint32
 | 
				
			||||||
 | 
						ProbMark       uint32
 | 
				
			||||||
 | 
						ForcedMark     uint32
 | 
				
			||||||
 | 
						ProbMarkHead   uint32
 | 
				
			||||||
 | 
						ForcedMarkHead uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (x *TcSfqRedStats) Len() int {
 | 
				
			||||||
 | 
						return SizeofTcSfqRedStats
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func DeserializeTcSfqRedStats(b []byte) *TcSfqRedStats {
 | 
				
			||||||
 | 
						return (*TcSfqRedStats)(unsafe.Pointer(&b[0:SizeofTcSfqRedStats][0]))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (x *TcSfqRedStats) Serialize() []byte {
 | 
				
			||||||
 | 
						return (*(*[SizeofTcSfqRedStats]byte)(unsafe.Pointer(x)))[:]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//	struct tc_sfq_qopt_v1 {
 | 
				
			||||||
 | 
					//		struct tc_sfq_qopt v0;
 | 
				
			||||||
 | 
					//		unsigned int	depth;		/* max number of packets per flow */
 | 
				
			||||||
 | 
					//		unsigned int	headdrop;
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// /* SFQRED parameters */
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//	__u32		limit;		/* HARD maximal flow queue length (bytes) */
 | 
				
			||||||
 | 
					//	__u32		qth_min;	/* Min average length threshold (bytes) */
 | 
				
			||||||
 | 
					//	__u32		qth_max;	/* Max average length threshold (bytes) */
 | 
				
			||||||
 | 
					//	unsigned char   Wlog;		/* log(W)		*/
 | 
				
			||||||
 | 
					//	unsigned char   Plog;		/* log(P_max/(qth_max-qth_min))	*/
 | 
				
			||||||
 | 
					//	unsigned char   Scell_log;	/* cell size for idle damping */
 | 
				
			||||||
 | 
					//	unsigned char	flags;
 | 
				
			||||||
 | 
					//	__u32		max_P;		/* probability, high resolution */
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// /* SFQRED stats */
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//		struct tc_sfqred_stats stats;
 | 
				
			||||||
 | 
					//	};
 | 
				
			||||||
 | 
					type TcSfqQoptV1 struct {
 | 
				
			||||||
 | 
						TcSfqQopt
 | 
				
			||||||
 | 
						Depth    uint32
 | 
				
			||||||
 | 
						HeadDrop uint32
 | 
				
			||||||
 | 
						Limit    uint32
 | 
				
			||||||
 | 
						QthMin   uint32
 | 
				
			||||||
 | 
						QthMax   uint32
 | 
				
			||||||
 | 
						Wlog     byte
 | 
				
			||||||
 | 
						Plog     byte
 | 
				
			||||||
 | 
						ScellLog byte
 | 
				
			||||||
 | 
						Flags    byte
 | 
				
			||||||
 | 
						MaxP     uint32
 | 
				
			||||||
 | 
						TcSfqRedStats
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (x *TcSfqQoptV1) Len() int {
 | 
				
			||||||
 | 
						return SizeofTcSfqQoptV1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func DeserializeTcSfqQoptV1(b []byte) *TcSfqQoptV1 {
 | 
				
			||||||
 | 
						return (*TcSfqQoptV1)(unsafe.Pointer(&b[0:SizeofTcSfqQoptV1][0]))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (x *TcSfqQoptV1) Serialize() []byte {
 | 
				
			||||||
 | 
						return (*(*[SizeofTcSfqQoptV1]byte)(unsafe.Pointer(x)))[:]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IPProto represents Flower ip_proto attribute
 | 
				
			||||||
 | 
					type IPProto uint8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						IPPROTO_TCP    IPProto = unix.IPPROTO_TCP
 | 
				
			||||||
 | 
						IPPROTO_UDP    IPProto = unix.IPPROTO_UDP
 | 
				
			||||||
 | 
						IPPROTO_SCTP   IPProto = unix.IPPROTO_SCTP
 | 
				
			||||||
 | 
						IPPROTO_ICMP   IPProto = unix.IPPROTO_ICMP
 | 
				
			||||||
 | 
						IPPROTO_ICMPV6 IPProto = unix.IPPROTO_ICMPV6
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (i IPProto) Serialize() []byte {
 | 
				
			||||||
 | 
						arr := make([]byte, 1)
 | 
				
			||||||
 | 
						arr[0] = byte(i)
 | 
				
			||||||
 | 
						return arr
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (i IPProto) String() string {
 | 
				
			||||||
 | 
						switch i {
 | 
				
			||||||
 | 
						case IPPROTO_TCP:
 | 
				
			||||||
 | 
							return "tcp"
 | 
				
			||||||
 | 
						case IPPROTO_UDP:
 | 
				
			||||||
 | 
							return "udp"
 | 
				
			||||||
 | 
						case IPPROTO_SCTP:
 | 
				
			||||||
 | 
							return "sctp"
 | 
				
			||||||
 | 
						case IPPROTO_ICMP:
 | 
				
			||||||
 | 
							return "icmp"
 | 
				
			||||||
 | 
						case IPPROTO_ICMPV6:
 | 
				
			||||||
 | 
							return "icmpv6"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return fmt.Sprintf("%d", i)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						MaxOffs        = 128
 | 
				
			||||||
 | 
						SizeOfPeditSel = 24
 | 
				
			||||||
 | 
						SizeOfPeditKey = 24
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TCA_PEDIT_KEY_EX_HTYPE = 1
 | 
				
			||||||
 | 
						TCA_PEDIT_KEY_EX_CMD   = 2
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						TCA_PEDIT_UNSPEC = iota
 | 
				
			||||||
 | 
						TCA_PEDIT_TM
 | 
				
			||||||
 | 
						TCA_PEDIT_PARMS
 | 
				
			||||||
 | 
						TCA_PEDIT_PAD
 | 
				
			||||||
 | 
						TCA_PEDIT_PARMS_EX
 | 
				
			||||||
 | 
						TCA_PEDIT_KEYS_EX
 | 
				
			||||||
 | 
						TCA_PEDIT_KEY_EX
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// /* TCA_PEDIT_KEY_EX_HDR_TYPE_NETWROK is a special case for legacy users. It
 | 
				
			||||||
 | 
					//  * means no specific header type - offset is relative to the network layer
 | 
				
			||||||
 | 
					//  */
 | 
				
			||||||
 | 
					type PeditHeaderType uint16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK = iota
 | 
				
			||||||
 | 
						TCA_PEDIT_KEY_EX_HDR_TYPE_ETH
 | 
				
			||||||
 | 
						TCA_PEDIT_KEY_EX_HDR_TYPE_IP4
 | 
				
			||||||
 | 
						TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
 | 
				
			||||||
 | 
						TCA_PEDIT_KEY_EX_HDR_TYPE_TCP
 | 
				
			||||||
 | 
						TCA_PEDIT_KEY_EX_HDR_TYPE_UDP
 | 
				
			||||||
 | 
						__PEDIT_HDR_TYPE_MAX
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type PeditCmd uint16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						TCA_PEDIT_KEY_EX_CMD_SET = 0
 | 
				
			||||||
 | 
						TCA_PEDIT_KEY_EX_CMD_ADD = 1
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type TcPeditSel struct {
 | 
				
			||||||
 | 
						TcGen
 | 
				
			||||||
 | 
						NKeys uint8
 | 
				
			||||||
 | 
						Flags uint8
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func DeserializeTcPeditKey(b []byte) *TcPeditKey {
 | 
				
			||||||
 | 
						return (*TcPeditKey)(unsafe.Pointer(&b[0:SizeOfPeditKey][0]))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func DeserializeTcPedit(b []byte) (*TcPeditSel, []TcPeditKey) {
 | 
				
			||||||
 | 
						x := &TcPeditSel{}
 | 
				
			||||||
 | 
						copy((*(*[SizeOfPeditSel]byte)(unsafe.Pointer(x)))[:SizeOfPeditSel], b)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var keys []TcPeditKey
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next := SizeOfPeditKey
 | 
				
			||||||
 | 
						var i uint8
 | 
				
			||||||
 | 
						for i = 0; i < x.NKeys; i++ {
 | 
				
			||||||
 | 
							keys = append(keys, *DeserializeTcPeditKey(b[next:]))
 | 
				
			||||||
 | 
							next += SizeOfPeditKey
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return x, keys
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type TcPeditKey struct {
 | 
				
			||||||
 | 
						Mask    uint32
 | 
				
			||||||
 | 
						Val     uint32
 | 
				
			||||||
 | 
						Off     uint32
 | 
				
			||||||
 | 
						At      uint32
 | 
				
			||||||
 | 
						OffMask uint32
 | 
				
			||||||
 | 
						Shift   uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type TcPeditKeyEx struct {
 | 
				
			||||||
 | 
						HeaderType PeditHeaderType
 | 
				
			||||||
 | 
						Cmd        PeditCmd
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type TcPedit struct {
 | 
				
			||||||
 | 
						Sel    TcPeditSel
 | 
				
			||||||
 | 
						Keys   []TcPeditKey
 | 
				
			||||||
 | 
						KeysEx []TcPeditKeyEx
 | 
				
			||||||
 | 
						Extend uint8
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (p *TcPedit) Encode(parent *RtAttr) {
 | 
				
			||||||
 | 
						parent.AddRtAttr(TCA_ACT_KIND, ZeroTerminated("pedit"))
 | 
				
			||||||
 | 
						actOpts := parent.AddRtAttr(TCA_ACT_OPTIONS, nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bbuf := bytes.NewBuffer(make([]byte, 0, int(unsafe.Sizeof(p.Sel)+unsafe.Sizeof(p.Keys))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bbuf.Write((*(*[SizeOfPeditSel]byte)(unsafe.Pointer(&p.Sel)))[:])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i := uint8(0); i < p.Sel.NKeys; i++ {
 | 
				
			||||||
 | 
							bbuf.Write((*(*[SizeOfPeditKey]byte)(unsafe.Pointer(&p.Keys[i])))[:])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						actOpts.AddRtAttr(TCA_PEDIT_PARMS_EX, bbuf.Bytes())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						exAttrs := actOpts.AddRtAttr(int(TCA_PEDIT_KEYS_EX|NLA_F_NESTED), nil)
 | 
				
			||||||
 | 
						for i := uint8(0); i < p.Sel.NKeys; i++ {
 | 
				
			||||||
 | 
							keyAttr := exAttrs.AddRtAttr(int(TCA_PEDIT_KEY_EX|NLA_F_NESTED), nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							htypeBuf := make([]byte, 2)
 | 
				
			||||||
 | 
							cmdBuf := make([]byte, 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							NativeEndian().PutUint16(htypeBuf, uint16(p.KeysEx[i].HeaderType))
 | 
				
			||||||
 | 
							NativeEndian().PutUint16(cmdBuf, uint16(p.KeysEx[i].Cmd))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							keyAttr.AddRtAttr(TCA_PEDIT_KEY_EX_HTYPE, htypeBuf)
 | 
				
			||||||
 | 
							keyAttr.AddRtAttr(TCA_PEDIT_KEY_EX_CMD, cmdBuf)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (p *TcPedit) SetEthDst(mac net.HardwareAddr) {
 | 
				
			||||||
 | 
						u32 := NativeEndian().Uint32(mac)
 | 
				
			||||||
 | 
						u16 := NativeEndian().Uint16(mac[4:])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey := TcPeditKey{}
 | 
				
			||||||
 | 
						tKeyEx := TcPeditKeyEx{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey.Val = u32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_ETH
 | 
				
			||||||
 | 
						tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Keys = append(p.Keys, tKey)
 | 
				
			||||||
 | 
						p.KeysEx = append(p.KeysEx, tKeyEx)
 | 
				
			||||||
 | 
						p.Sel.NKeys++
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey = TcPeditKey{}
 | 
				
			||||||
 | 
						tKeyEx = TcPeditKeyEx{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey.Val = uint32(u16)
 | 
				
			||||||
 | 
						tKey.Mask = 0xffff0000
 | 
				
			||||||
 | 
						tKey.Off = 4
 | 
				
			||||||
 | 
						tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_ETH
 | 
				
			||||||
 | 
						tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Keys = append(p.Keys, tKey)
 | 
				
			||||||
 | 
						p.KeysEx = append(p.KeysEx, tKeyEx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Sel.NKeys++
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (p *TcPedit) SetEthSrc(mac net.HardwareAddr) {
 | 
				
			||||||
 | 
						u16 := NativeEndian().Uint16(mac)
 | 
				
			||||||
 | 
						u32 := NativeEndian().Uint32(mac[2:])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey := TcPeditKey{}
 | 
				
			||||||
 | 
						tKeyEx := TcPeditKeyEx{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey.Val = uint32(u16) << 16
 | 
				
			||||||
 | 
						tKey.Mask = 0x0000ffff
 | 
				
			||||||
 | 
						tKey.Off = 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_ETH
 | 
				
			||||||
 | 
						tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Keys = append(p.Keys, tKey)
 | 
				
			||||||
 | 
						p.KeysEx = append(p.KeysEx, tKeyEx)
 | 
				
			||||||
 | 
						p.Sel.NKeys++
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey = TcPeditKey{}
 | 
				
			||||||
 | 
						tKeyEx = TcPeditKeyEx{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey.Val = u32
 | 
				
			||||||
 | 
						tKey.Mask = 0
 | 
				
			||||||
 | 
						tKey.Off = 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_ETH
 | 
				
			||||||
 | 
						tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Keys = append(p.Keys, tKey)
 | 
				
			||||||
 | 
						p.KeysEx = append(p.KeysEx, tKeyEx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Sel.NKeys++
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (p *TcPedit) SetIPv6Src(ip6 net.IP) {
 | 
				
			||||||
 | 
						u32 := NativeEndian().Uint32(ip6[:4])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey := TcPeditKey{}
 | 
				
			||||||
 | 
						tKeyEx := TcPeditKeyEx{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey.Val = u32
 | 
				
			||||||
 | 
						tKey.Off = 8
 | 
				
			||||||
 | 
						tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
 | 
				
			||||||
 | 
						tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Keys = append(p.Keys, tKey)
 | 
				
			||||||
 | 
						p.KeysEx = append(p.KeysEx, tKeyEx)
 | 
				
			||||||
 | 
						p.Sel.NKeys++
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u32 = NativeEndian().Uint32(ip6[4:8])
 | 
				
			||||||
 | 
						tKey = TcPeditKey{}
 | 
				
			||||||
 | 
						tKeyEx = TcPeditKeyEx{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey.Val = u32
 | 
				
			||||||
 | 
						tKey.Off = 12
 | 
				
			||||||
 | 
						tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
 | 
				
			||||||
 | 
						tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Keys = append(p.Keys, tKey)
 | 
				
			||||||
 | 
						p.KeysEx = append(p.KeysEx, tKeyEx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Sel.NKeys++
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u32 = NativeEndian().Uint32(ip6[8:12])
 | 
				
			||||||
 | 
						tKey = TcPeditKey{}
 | 
				
			||||||
 | 
						tKeyEx = TcPeditKeyEx{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey.Val = u32
 | 
				
			||||||
 | 
						tKey.Off = 16
 | 
				
			||||||
 | 
						tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
 | 
				
			||||||
 | 
						tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Keys = append(p.Keys, tKey)
 | 
				
			||||||
 | 
						p.KeysEx = append(p.KeysEx, tKeyEx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Sel.NKeys++
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u32 = NativeEndian().Uint32(ip6[12:16])
 | 
				
			||||||
 | 
						tKey = TcPeditKey{}
 | 
				
			||||||
 | 
						tKeyEx = TcPeditKeyEx{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey.Val = u32
 | 
				
			||||||
 | 
						tKey.Off = 20
 | 
				
			||||||
 | 
						tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
 | 
				
			||||||
 | 
						tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Keys = append(p.Keys, tKey)
 | 
				
			||||||
 | 
						p.KeysEx = append(p.KeysEx, tKeyEx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Sel.NKeys++
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (p *TcPedit) SetDstIP(ip net.IP) {
 | 
				
			||||||
 | 
						if ip.To4() != nil {
 | 
				
			||||||
 | 
							p.SetIPv4Dst(ip)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							p.SetIPv6Dst(ip)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (p *TcPedit) SetSrcIP(ip net.IP) {
 | 
				
			||||||
 | 
						if ip.To4() != nil {
 | 
				
			||||||
 | 
							p.SetIPv4Src(ip)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							p.SetIPv6Src(ip)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (p *TcPedit) SetIPv6Dst(ip6 net.IP) {
 | 
				
			||||||
 | 
						u32 := NativeEndian().Uint32(ip6[:4])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey := TcPeditKey{}
 | 
				
			||||||
 | 
						tKeyEx := TcPeditKeyEx{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey.Val = u32
 | 
				
			||||||
 | 
						tKey.Off = 24
 | 
				
			||||||
 | 
						tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
 | 
				
			||||||
 | 
						tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Keys = append(p.Keys, tKey)
 | 
				
			||||||
 | 
						p.KeysEx = append(p.KeysEx, tKeyEx)
 | 
				
			||||||
 | 
						p.Sel.NKeys++
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u32 = NativeEndian().Uint32(ip6[4:8])
 | 
				
			||||||
 | 
						tKey = TcPeditKey{}
 | 
				
			||||||
 | 
						tKeyEx = TcPeditKeyEx{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey.Val = u32
 | 
				
			||||||
 | 
						tKey.Off = 28
 | 
				
			||||||
 | 
						tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
 | 
				
			||||||
 | 
						tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Keys = append(p.Keys, tKey)
 | 
				
			||||||
 | 
						p.KeysEx = append(p.KeysEx, tKeyEx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Sel.NKeys++
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u32 = NativeEndian().Uint32(ip6[8:12])
 | 
				
			||||||
 | 
						tKey = TcPeditKey{}
 | 
				
			||||||
 | 
						tKeyEx = TcPeditKeyEx{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey.Val = u32
 | 
				
			||||||
 | 
						tKey.Off = 32
 | 
				
			||||||
 | 
						tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
 | 
				
			||||||
 | 
						tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Keys = append(p.Keys, tKey)
 | 
				
			||||||
 | 
						p.KeysEx = append(p.KeysEx, tKeyEx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Sel.NKeys++
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u32 = NativeEndian().Uint32(ip6[12:16])
 | 
				
			||||||
 | 
						tKey = TcPeditKey{}
 | 
				
			||||||
 | 
						tKeyEx = TcPeditKeyEx{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey.Val = u32
 | 
				
			||||||
 | 
						tKey.Off = 36
 | 
				
			||||||
 | 
						tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP6
 | 
				
			||||||
 | 
						tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Keys = append(p.Keys, tKey)
 | 
				
			||||||
 | 
						p.KeysEx = append(p.KeysEx, tKeyEx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Sel.NKeys++
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (p *TcPedit) SetIPv4Src(ip net.IP) {
 | 
				
			||||||
 | 
						u32 := NativeEndian().Uint32(ip[:4])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey := TcPeditKey{}
 | 
				
			||||||
 | 
						tKeyEx := TcPeditKeyEx{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey.Val = u32
 | 
				
			||||||
 | 
						tKey.Off = 12
 | 
				
			||||||
 | 
						tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP4
 | 
				
			||||||
 | 
						tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Keys = append(p.Keys, tKey)
 | 
				
			||||||
 | 
						p.KeysEx = append(p.KeysEx, tKeyEx)
 | 
				
			||||||
 | 
						p.Sel.NKeys++
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (p *TcPedit) SetIPv4Dst(ip net.IP) {
 | 
				
			||||||
 | 
						u32 := NativeEndian().Uint32(ip[:4])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey := TcPeditKey{}
 | 
				
			||||||
 | 
						tKeyEx := TcPeditKeyEx{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey.Val = u32
 | 
				
			||||||
 | 
						tKey.Off = 16
 | 
				
			||||||
 | 
						tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_IP4
 | 
				
			||||||
 | 
						tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.Keys = append(p.Keys, tKey)
 | 
				
			||||||
 | 
						p.KeysEx = append(p.KeysEx, tKeyEx)
 | 
				
			||||||
 | 
						p.Sel.NKeys++
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetDstPort only tcp and udp are supported to set port
 | 
				
			||||||
 | 
					func (p *TcPedit) SetDstPort(dstPort uint16, protocol uint8) {
 | 
				
			||||||
 | 
						tKey := TcPeditKey{}
 | 
				
			||||||
 | 
						tKeyEx := TcPeditKeyEx{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch protocol {
 | 
				
			||||||
 | 
						case unix.IPPROTO_TCP:
 | 
				
			||||||
 | 
							tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_TCP
 | 
				
			||||||
 | 
						case unix.IPPROTO_UDP:
 | 
				
			||||||
 | 
							tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_UDP
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey.Val = uint32(Swap16(dstPort)) << 16
 | 
				
			||||||
 | 
						tKey.Mask = 0x0000ffff
 | 
				
			||||||
 | 
						p.Keys = append(p.Keys, tKey)
 | 
				
			||||||
 | 
						p.KeysEx = append(p.KeysEx, tKeyEx)
 | 
				
			||||||
 | 
						p.Sel.NKeys++
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetSrcPort only tcp and udp are supported to set port
 | 
				
			||||||
 | 
					func (p *TcPedit) SetSrcPort(srcPort uint16, protocol uint8) {
 | 
				
			||||||
 | 
						tKey := TcPeditKey{}
 | 
				
			||||||
 | 
						tKeyEx := TcPeditKeyEx{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch protocol {
 | 
				
			||||||
 | 
						case unix.IPPROTO_TCP:
 | 
				
			||||||
 | 
							tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_TCP
 | 
				
			||||||
 | 
						case unix.IPPROTO_UDP:
 | 
				
			||||||
 | 
							tKeyEx.HeaderType = TCA_PEDIT_KEY_EX_HDR_TYPE_UDP
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKeyEx.Cmd = TCA_PEDIT_KEY_EX_CMD_SET
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tKey.Val = uint32(Swap16(srcPort))
 | 
				
			||||||
 | 
						tKey.Mask = 0xffff0000
 | 
				
			||||||
 | 
						p.Keys = append(p.Keys, tKey)
 | 
				
			||||||
 | 
						p.KeysEx = append(p.KeysEx, tKeyEx)
 | 
				
			||||||
 | 
						p.Sel.NKeys++
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										41
									
								
								vendor/github.com/vishvananda/netlink/nl/vdpa_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								vendor/github.com/vishvananda/netlink/nl/vdpa_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					package nl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						VDPA_GENL_NAME    = "vdpa"
 | 
				
			||||||
 | 
						VDPA_GENL_VERSION = 0x1
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						VDPA_CMD_UNSPEC = iota
 | 
				
			||||||
 | 
						VDPA_CMD_MGMTDEV_NEW
 | 
				
			||||||
 | 
						VDPA_CMD_MGMTDEV_GET /* can dump */
 | 
				
			||||||
 | 
						VDPA_CMD_DEV_NEW
 | 
				
			||||||
 | 
						VDPA_CMD_DEV_DEL
 | 
				
			||||||
 | 
						VDPA_CMD_DEV_GET        /* can dump */
 | 
				
			||||||
 | 
						VDPA_CMD_DEV_CONFIG_GET /* can dump */
 | 
				
			||||||
 | 
						VDPA_CMD_DEV_VSTATS_GET
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						VDPA_ATTR_UNSPEC = iota
 | 
				
			||||||
 | 
						VDPA_ATTR_MGMTDEV_BUS_NAME
 | 
				
			||||||
 | 
						VDPA_ATTR_MGMTDEV_DEV_NAME
 | 
				
			||||||
 | 
						VDPA_ATTR_MGMTDEV_SUPPORTED_CLASSES
 | 
				
			||||||
 | 
						VDPA_ATTR_DEV_NAME
 | 
				
			||||||
 | 
						VDPA_ATTR_DEV_ID
 | 
				
			||||||
 | 
						VDPA_ATTR_DEV_VENDOR_ID
 | 
				
			||||||
 | 
						VDPA_ATTR_DEV_MAX_VQS
 | 
				
			||||||
 | 
						VDPA_ATTR_DEV_MAX_VQ_SIZE
 | 
				
			||||||
 | 
						VDPA_ATTR_DEV_MIN_VQ_SIZE
 | 
				
			||||||
 | 
						VDPA_ATTR_DEV_NET_CFG_MACADDR
 | 
				
			||||||
 | 
						VDPA_ATTR_DEV_NET_STATUS
 | 
				
			||||||
 | 
						VDPA_ATTR_DEV_NET_CFG_MAX_VQP
 | 
				
			||||||
 | 
						VDPA_ATTR_DEV_NET_CFG_MTU
 | 
				
			||||||
 | 
						VDPA_ATTR_DEV_NEGOTIATED_FEATURES
 | 
				
			||||||
 | 
						VDPA_ATTR_DEV_MGMTDEV_MAX_VQS
 | 
				
			||||||
 | 
						VDPA_ATTR_DEV_SUPPORTED_FEATURES
 | 
				
			||||||
 | 
						VDPA_ATTR_DEV_QUEUE_INDEX
 | 
				
			||||||
 | 
						VDPA_ATTR_DEV_VENDOR_ATTR_NAME
 | 
				
			||||||
 | 
						VDPA_ATTR_DEV_VENDOR_ATTR_VALUE
 | 
				
			||||||
 | 
						VDPA_ATTR_DEV_FEATURES
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
							
								
								
									
										10
									
								
								vendor/github.com/vishvananda/netlink/nl/xfrm_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/vishvananda/netlink/nl/xfrm_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -131,7 +131,15 @@ func (x *XfrmAddress) ToIP() net.IP {
 | 
				
			|||||||
	return ip
 | 
						return ip
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (x *XfrmAddress) ToIPNet(prefixlen uint8) *net.IPNet {
 | 
					// family is only used when x and prefixlen are both 0
 | 
				
			||||||
 | 
					func (x *XfrmAddress) ToIPNet(prefixlen uint8, family uint16) *net.IPNet {
 | 
				
			||||||
 | 
						empty := [SizeofXfrmAddress]byte{}
 | 
				
			||||||
 | 
						if bytes.Equal(x[:], empty[:]) && prefixlen == 0 {
 | 
				
			||||||
 | 
							if family == FAMILY_V6 {
 | 
				
			||||||
 | 
								return &net.IPNet{IP: net.ParseIP("::"), Mask: net.CIDRMask(int(prefixlen), 128)}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return &net.IPNet{IP: net.ParseIP("0.0.0.0"), Mask: net.CIDRMask(int(prefixlen), 32)}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	ip := x.ToIP()
 | 
						ip := x.ToIP()
 | 
				
			||||||
	if GetIPFamily(ip) == FAMILY_V4 {
 | 
						if GetIPFamily(ip) == FAMILY_V4 {
 | 
				
			||||||
		return &net.IPNet{IP: ip, Mask: net.CIDRMask(int(prefixlen), 32)}
 | 
							return &net.IPNet{IP: ip, Mask: net.CIDRMask(int(prefixlen), 32)}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										29
									
								
								vendor/github.com/vishvananda/netlink/nl/xfrm_state_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/vishvananda/netlink/nl/xfrm_state_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -13,8 +13,9 @@ const (
 | 
				
			|||||||
	SizeofXfrmAlgoAuth       = 0x48
 | 
						SizeofXfrmAlgoAuth       = 0x48
 | 
				
			||||||
	SizeofXfrmAlgoAEAD       = 0x48
 | 
						SizeofXfrmAlgoAEAD       = 0x48
 | 
				
			||||||
	SizeofXfrmEncapTmpl      = 0x18
 | 
						SizeofXfrmEncapTmpl      = 0x18
 | 
				
			||||||
	SizeofXfrmUsersaFlush    = 0x8
 | 
						SizeofXfrmUsersaFlush    = 0x1
 | 
				
			||||||
	SizeofXfrmReplayStateEsn = 0x18
 | 
						SizeofXfrmReplayStateEsn = 0x18
 | 
				
			||||||
 | 
						SizeofXfrmReplayState    = 0x0c
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -28,6 +29,11 @@ const (
 | 
				
			|||||||
	XFRM_STATE_ESN        = 128
 | 
						XFRM_STATE_ESN        = 128
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						XFRM_SA_XFLAG_DONT_ENCAP_DSCP = 1
 | 
				
			||||||
 | 
						XFRM_SA_XFLAG_OSEQ_MAY_WRAP   = 2
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// struct xfrm_usersa_id {
 | 
					// struct xfrm_usersa_id {
 | 
				
			||||||
//   xfrm_address_t      daddr;
 | 
					//   xfrm_address_t      daddr;
 | 
				
			||||||
//   __be32        spi;
 | 
					//   __be32        spi;
 | 
				
			||||||
@@ -103,6 +109,7 @@ func (msg *XfrmStats) Serialize() []byte {
 | 
				
			|||||||
// };
 | 
					// };
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// #define XFRM_SA_XFLAG_DONT_ENCAP_DSCP 1
 | 
					// #define XFRM_SA_XFLAG_DONT_ENCAP_DSCP 1
 | 
				
			||||||
 | 
					// #define XFRM_SA_XFLAG_OSEQ_MAY_WRAP   2
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type XfrmUsersaInfo struct {
 | 
					type XfrmUsersaInfo struct {
 | 
				
			||||||
@@ -332,3 +339,23 @@ func (msg *XfrmReplayStateEsn) Serialize() []byte {
 | 
				
			|||||||
	// We deliberately do not pass Bmp, as it gets set by the kernel.
 | 
						// We deliberately do not pass Bmp, as it gets set by the kernel.
 | 
				
			||||||
	return (*(*[SizeofXfrmReplayStateEsn]byte)(unsafe.Pointer(msg)))[:]
 | 
						return (*(*[SizeofXfrmReplayStateEsn]byte)(unsafe.Pointer(msg)))[:]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// struct xfrm_replay_state {
 | 
				
			||||||
 | 
					//     __u32   oseq;
 | 
				
			||||||
 | 
					//     __u32   seq;
 | 
				
			||||||
 | 
					//     __u32   bitmap;
 | 
				
			||||||
 | 
					// };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type XfrmReplayState struct {
 | 
				
			||||||
 | 
						OSeq   uint32
 | 
				
			||||||
 | 
						Seq    uint32
 | 
				
			||||||
 | 
						BitMap uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func DeserializeXfrmReplayState(b []byte) *XfrmReplayState {
 | 
				
			||||||
 | 
						return (*XfrmReplayState)(unsafe.Pointer(&b[0:SizeofXfrmReplayState][0]))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (msg *XfrmReplayState) Serialize() []byte {
 | 
				
			||||||
 | 
						return (*(*[SizeofXfrmReplayState]byte)(unsafe.Pointer(msg)))[:]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										208
									
								
								vendor/github.com/vishvananda/netlink/proc_event_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								vendor/github.com/vishvananda/netlink/proc_event_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,208 @@
 | 
				
			|||||||
 | 
					package netlink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"encoding/binary"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"syscall"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/vishvananda/netlink/nl"
 | 
				
			||||||
 | 
						"github.com/vishvananda/netns"
 | 
				
			||||||
 | 
						"golang.org/x/sys/unix"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const CN_IDX_PROC = 0x1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						PROC_EVENT_NONE     = 0x00000000
 | 
				
			||||||
 | 
						PROC_EVENT_FORK     = 0x00000001
 | 
				
			||||||
 | 
						PROC_EVENT_EXEC     = 0x00000002
 | 
				
			||||||
 | 
						PROC_EVENT_UID      = 0x00000004
 | 
				
			||||||
 | 
						PROC_EVENT_GID      = 0x00000040
 | 
				
			||||||
 | 
						PROC_EVENT_SID      = 0x00000080
 | 
				
			||||||
 | 
						PROC_EVENT_PTRACE   = 0x00000100
 | 
				
			||||||
 | 
						PROC_EVENT_COMM     = 0x00000200
 | 
				
			||||||
 | 
						PROC_EVENT_COREDUMP = 0x40000000
 | 
				
			||||||
 | 
						PROC_EVENT_EXIT     = 0x80000000
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						CN_VAL_PROC          = 0x1
 | 
				
			||||||
 | 
						PROC_CN_MCAST_LISTEN = 0x1
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ProcEventMsg interface {
 | 
				
			||||||
 | 
						Pid() uint32
 | 
				
			||||||
 | 
						Tgid() uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ProcEventHeader struct {
 | 
				
			||||||
 | 
						What      uint32
 | 
				
			||||||
 | 
						CPU       uint32
 | 
				
			||||||
 | 
						Timestamp uint64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ProcEvent struct {
 | 
				
			||||||
 | 
						ProcEventHeader
 | 
				
			||||||
 | 
						Msg ProcEventMsg
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (pe *ProcEvent) setHeader(h ProcEventHeader) {
 | 
				
			||||||
 | 
						pe.What = h.What
 | 
				
			||||||
 | 
						pe.CPU = h.CPU
 | 
				
			||||||
 | 
						pe.Timestamp = h.Timestamp
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ExitProcEvent struct {
 | 
				
			||||||
 | 
						ProcessPid  uint32
 | 
				
			||||||
 | 
						ProcessTgid uint32
 | 
				
			||||||
 | 
						ExitCode    uint32
 | 
				
			||||||
 | 
						ExitSignal  uint32
 | 
				
			||||||
 | 
						ParentPid   uint32
 | 
				
			||||||
 | 
						ParentTgid  uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e *ExitProcEvent) Pid() uint32 {
 | 
				
			||||||
 | 
						return e.ProcessPid
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e *ExitProcEvent) Tgid() uint32 {
 | 
				
			||||||
 | 
						return e.ProcessTgid
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ExecProcEvent struct {
 | 
				
			||||||
 | 
						ProcessPid  uint32
 | 
				
			||||||
 | 
						ProcessTgid uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e *ExecProcEvent) Pid() uint32 {
 | 
				
			||||||
 | 
						return e.ProcessPid
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e *ExecProcEvent) Tgid() uint32 {
 | 
				
			||||||
 | 
						return e.ProcessTgid
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ForkProcEvent struct {
 | 
				
			||||||
 | 
						ParentPid  uint32
 | 
				
			||||||
 | 
						ParentTgid uint32
 | 
				
			||||||
 | 
						ChildPid   uint32
 | 
				
			||||||
 | 
						ChildTgid  uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e *ForkProcEvent) Pid() uint32 {
 | 
				
			||||||
 | 
						return e.ParentPid
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e *ForkProcEvent) Tgid() uint32 {
 | 
				
			||||||
 | 
						return e.ParentTgid
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CommProcEvent struct {
 | 
				
			||||||
 | 
						ProcessPid  uint32
 | 
				
			||||||
 | 
						ProcessTgid uint32
 | 
				
			||||||
 | 
						Comm        [16]byte
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e *CommProcEvent) Pid() uint32 {
 | 
				
			||||||
 | 
						return e.ProcessPid
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e *CommProcEvent) Tgid() uint32 {
 | 
				
			||||||
 | 
						return e.ProcessTgid
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ProcEventMonitor(ch chan<- ProcEvent, done <-chan struct{}, errorChan chan<- error) error {
 | 
				
			||||||
 | 
						h, err := NewHandle()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer h.Delete()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						s, err := nl.SubscribeAt(netns.None(), netns.None(), unix.NETLINK_CONNECTOR, CN_IDX_PROC)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var nlmsg nl.NetlinkRequest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						nlmsg.Pid = uint32(os.Getpid())
 | 
				
			||||||
 | 
						nlmsg.Type = unix.NLMSG_DONE
 | 
				
			||||||
 | 
						nlmsg.Len = uint32(unix.SizeofNlMsghdr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cm := nl.NewCnMsg(CN_IDX_PROC, CN_VAL_PROC, PROC_CN_MCAST_LISTEN)
 | 
				
			||||||
 | 
						nlmsg.AddData(cm)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						s.Send(&nlmsg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if done != nil {
 | 
				
			||||||
 | 
							go func() {
 | 
				
			||||||
 | 
								<-done
 | 
				
			||||||
 | 
								s.Close()
 | 
				
			||||||
 | 
							}()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						go func() {
 | 
				
			||||||
 | 
							defer close(ch)
 | 
				
			||||||
 | 
							for {
 | 
				
			||||||
 | 
								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 {
 | 
				
			||||||
 | 
									e := parseNetlinkMessage(m)
 | 
				
			||||||
 | 
									if e != nil {
 | 
				
			||||||
 | 
										ch <- *e
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseNetlinkMessage(m syscall.NetlinkMessage) *ProcEvent {
 | 
				
			||||||
 | 
						if m.Header.Type == unix.NLMSG_DONE {
 | 
				
			||||||
 | 
							buf := bytes.NewBuffer(m.Data)
 | 
				
			||||||
 | 
							msg := &nl.CnMsg{}
 | 
				
			||||||
 | 
							hdr := &ProcEventHeader{}
 | 
				
			||||||
 | 
							binary.Read(buf, nl.NativeEndian(), msg)
 | 
				
			||||||
 | 
							binary.Read(buf, nl.NativeEndian(), hdr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							pe := &ProcEvent{}
 | 
				
			||||||
 | 
							pe.setHeader(*hdr)
 | 
				
			||||||
 | 
							switch hdr.What {
 | 
				
			||||||
 | 
							case PROC_EVENT_EXIT:
 | 
				
			||||||
 | 
								event := &ExitProcEvent{}
 | 
				
			||||||
 | 
								binary.Read(buf, nl.NativeEndian(), event)
 | 
				
			||||||
 | 
								pe.Msg = event
 | 
				
			||||||
 | 
								return pe
 | 
				
			||||||
 | 
							case PROC_EVENT_FORK:
 | 
				
			||||||
 | 
								event := &ForkProcEvent{}
 | 
				
			||||||
 | 
								binary.Read(buf, nl.NativeEndian(), event)
 | 
				
			||||||
 | 
								pe.Msg = event
 | 
				
			||||||
 | 
								return pe
 | 
				
			||||||
 | 
							case PROC_EVENT_EXEC:
 | 
				
			||||||
 | 
								event := &ExecProcEvent{}
 | 
				
			||||||
 | 
								binary.Read(buf, nl.NativeEndian(), event)
 | 
				
			||||||
 | 
								pe.Msg = event
 | 
				
			||||||
 | 
								return pe
 | 
				
			||||||
 | 
							case PROC_EVENT_COMM:
 | 
				
			||||||
 | 
								event := &CommProcEvent{}
 | 
				
			||||||
 | 
								binary.Read(buf, nl.NativeEndian(), event)
 | 
				
			||||||
 | 
								pe.Msg = event
 | 
				
			||||||
 | 
								return pe
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										8
									
								
								vendor/github.com/vishvananda/netlink/protinfo.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/vishvananda/netlink/protinfo.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -14,6 +14,8 @@ type Protinfo struct {
 | 
				
			|||||||
	Flood         bool
 | 
						Flood         bool
 | 
				
			||||||
	ProxyArp      bool
 | 
						ProxyArp      bool
 | 
				
			||||||
	ProxyArpWiFi  bool
 | 
						ProxyArpWiFi  bool
 | 
				
			||||||
 | 
						Isolated      bool
 | 
				
			||||||
 | 
						NeighSuppress bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// String returns a list of enabled flags
 | 
					// String returns a list of enabled flags
 | 
				
			||||||
@@ -47,6 +49,12 @@ func (prot *Protinfo) String() string {
 | 
				
			|||||||
	if prot.ProxyArpWiFi {
 | 
						if prot.ProxyArpWiFi {
 | 
				
			||||||
		boolStrings = append(boolStrings, "ProxyArpWiFi")
 | 
							boolStrings = append(boolStrings, "ProxyArpWiFi")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if prot.Isolated {
 | 
				
			||||||
 | 
							boolStrings = append(boolStrings, "Isolated")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if prot.NeighSuppress {
 | 
				
			||||||
 | 
							boolStrings = append(boolStrings, "NeighSuppress")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return strings.Join(boolStrings, " ")
 | 
						return strings.Join(boolStrings, " ")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								vendor/github.com/vishvananda/netlink/protinfo_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/vishvananda/netlink/protinfo_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -68,6 +68,10 @@ func parseProtinfo(infos []syscall.NetlinkRouteAttr) (pi Protinfo) {
 | 
				
			|||||||
			pi.ProxyArp = byteToBool(info.Value[0])
 | 
								pi.ProxyArp = byteToBool(info.Value[0])
 | 
				
			||||||
		case nl.IFLA_BRPORT_PROXYARP_WIFI:
 | 
							case nl.IFLA_BRPORT_PROXYARP_WIFI:
 | 
				
			||||||
			pi.ProxyArpWiFi = byteToBool(info.Value[0])
 | 
								pi.ProxyArpWiFi = byteToBool(info.Value[0])
 | 
				
			||||||
 | 
							case nl.IFLA_BRPORT_ISOLATED:
 | 
				
			||||||
 | 
								pi.Isolated = byteToBool(info.Value[0])
 | 
				
			||||||
 | 
							case nl.IFLA_BRPORT_NEIGH_SUPPRESS:
 | 
				
			||||||
 | 
								pi.NeighSuppress = byteToBool(info.Value[0])
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										62
									
								
								vendor/github.com/vishvananda/netlink/qdisc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										62
									
								
								vendor/github.com/vishvananda/netlink/qdisc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -17,11 +17,19 @@ const (
 | 
				
			|||||||
	HANDLE_MIN_EGRESS  = 0xFFFFFFF3
 | 
						HANDLE_MIN_EGRESS  = 0xFFFFFFF3
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						HORIZON_DROP_POLICY_CAP     = 0
 | 
				
			||||||
 | 
						HORIZON_DROP_POLICY_DROP    = 1
 | 
				
			||||||
 | 
						HORIZON_DROP_POLICY_DEFAULT = 255
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Qdisc interface {
 | 
					type Qdisc interface {
 | 
				
			||||||
	Attrs() *QdiscAttrs
 | 
						Attrs() *QdiscAttrs
 | 
				
			||||||
	Type() string
 | 
						Type() string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type QdiscStatistics ClassStatistics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// QdiscAttrs represents a netlink qdisc. A qdisc is associated with a link,
 | 
					// QdiscAttrs represents a netlink qdisc. A qdisc is associated with a link,
 | 
				
			||||||
// has a handle, a parent and a refcnt. The root qdisc of a device should
 | 
					// has a handle, a parent and a refcnt. The root qdisc of a device should
 | 
				
			||||||
// have parent == HANDLE_ROOT.
 | 
					// have parent == HANDLE_ROOT.
 | 
				
			||||||
@@ -30,6 +38,8 @@ type QdiscAttrs struct {
 | 
				
			|||||||
	Handle       uint32
 | 
						Handle       uint32
 | 
				
			||||||
	Parent       uint32
 | 
						Parent       uint32
 | 
				
			||||||
	Refcnt       uint32 // read only
 | 
						Refcnt       uint32 // read only
 | 
				
			||||||
 | 
						IngressBlock *uint32
 | 
				
			||||||
 | 
						Statistics   *QdiscStatistics
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (q QdiscAttrs) String() string {
 | 
					func (q QdiscAttrs) String() string {
 | 
				
			||||||
@@ -113,6 +123,7 @@ type Htb struct {
 | 
				
			|||||||
	Defcls       uint32
 | 
						Defcls       uint32
 | 
				
			||||||
	Debug        uint32
 | 
						Debug        uint32
 | 
				
			||||||
	DirectPkts   uint32
 | 
						DirectPkts   uint32
 | 
				
			||||||
 | 
						DirectQlen   *uint32
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewHtb(attrs QdiscAttrs) *Htb {
 | 
					func NewHtb(attrs QdiscAttrs) *Htb {
 | 
				
			||||||
@@ -123,6 +134,7 @@ func NewHtb(attrs QdiscAttrs) *Htb {
 | 
				
			|||||||
		Rate2Quantum: 10,
 | 
							Rate2Quantum: 10,
 | 
				
			||||||
		Debug:        0,
 | 
							Debug:        0,
 | 
				
			||||||
		DirectPkts:   0,
 | 
							DirectPkts:   0,
 | 
				
			||||||
 | 
							DirectQlen:   nil,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -150,6 +162,7 @@ type NetemQdiscAttrs struct {
 | 
				
			|||||||
	ReorderCorr   float32 // in %
 | 
						ReorderCorr   float32 // in %
 | 
				
			||||||
	CorruptProb   float32 // in %
 | 
						CorruptProb   float32 // in %
 | 
				
			||||||
	CorruptCorr   float32 // in %
 | 
						CorruptCorr   float32 // in %
 | 
				
			||||||
 | 
						Rate64        uint64
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (q NetemQdiscAttrs) String() string {
 | 
					func (q NetemQdiscAttrs) String() string {
 | 
				
			||||||
@@ -174,6 +187,7 @@ type Netem struct {
 | 
				
			|||||||
	ReorderCorr   uint32
 | 
						ReorderCorr   uint32
 | 
				
			||||||
	CorruptProb   uint32
 | 
						CorruptProb   uint32
 | 
				
			||||||
	CorruptCorr   uint32
 | 
						CorruptCorr   uint32
 | 
				
			||||||
 | 
						Rate64        uint64
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (netem *Netem) String() string {
 | 
					func (netem *Netem) String() string {
 | 
				
			||||||
@@ -210,6 +224,19 @@ func (qdisc *Tbf) Type() string {
 | 
				
			|||||||
	return "tbf"
 | 
						return "tbf"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Clsact is a qdisc for adding filters
 | 
				
			||||||
 | 
					type Clsact struct {
 | 
				
			||||||
 | 
						QdiscAttrs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (qdisc *Clsact) Attrs() *QdiscAttrs {
 | 
				
			||||||
 | 
						return &qdisc.QdiscAttrs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (qdisc *Clsact) Type() string {
 | 
				
			||||||
 | 
						return "clsact"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Ingress is a qdisc for adding ingress filters
 | 
					// Ingress is a qdisc for adding ingress filters
 | 
				
			||||||
type Ingress struct {
 | 
					type Ingress struct {
 | 
				
			||||||
	QdiscAttrs
 | 
						QdiscAttrs
 | 
				
			||||||
@@ -281,12 +308,14 @@ type Fq struct {
 | 
				
			|||||||
	Buckets           uint32
 | 
						Buckets           uint32
 | 
				
			||||||
	FlowRefillDelay   uint32
 | 
						FlowRefillDelay   uint32
 | 
				
			||||||
	LowRateThreshold  uint32
 | 
						LowRateThreshold  uint32
 | 
				
			||||||
 | 
						Horizon           uint32
 | 
				
			||||||
 | 
						HorizonDropPolicy uint8
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (fq *Fq) String() string {
 | 
					func (fq *Fq) String() string {
 | 
				
			||||||
	return fmt.Sprintf(
 | 
						return fmt.Sprintf(
 | 
				
			||||||
		"{PacketLimit: %v, FlowPacketLimit: %v, Quantum: %v, InitialQuantum: %v, Pacing: %v, FlowDefaultRate: %v, FlowMaxRate: %v, Buckets: %v, FlowRefillDelay: %v,  LowRateThreshold: %v}",
 | 
							"{PacketLimit: %v, FlowPacketLimit: %v, Quantum: %v, InitialQuantum: %v, Pacing: %v, FlowDefaultRate: %v, FlowMaxRate: %v, Buckets: %v, FlowRefillDelay: %v,  LowRateThreshold: %v, Horizon: %v, HorizonDropPolicy: %v}",
 | 
				
			||||||
		fq.PacketLimit, fq.FlowPacketLimit, fq.Quantum, fq.InitialQuantum, fq.Pacing, fq.FlowDefaultRate, fq.FlowMaxRate, fq.Buckets, fq.FlowRefillDelay, fq.LowRateThreshold,
 | 
							fq.PacketLimit, fq.FlowPacketLimit, fq.Quantum, fq.InitialQuantum, fq.Pacing, fq.FlowDefaultRate, fq.FlowMaxRate, fq.Buckets, fq.FlowRefillDelay, fq.LowRateThreshold, fq.Horizon, fq.HorizonDropPolicy,
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -294,6 +323,7 @@ func NewFq(attrs QdiscAttrs) *Fq {
 | 
				
			|||||||
	return &Fq{
 | 
						return &Fq{
 | 
				
			||||||
		QdiscAttrs:        attrs,
 | 
							QdiscAttrs:        attrs,
 | 
				
			||||||
		Pacing:            1,
 | 
							Pacing:            1,
 | 
				
			||||||
 | 
							HorizonDropPolicy: HORIZON_DROP_POLICY_DEFAULT,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -314,7 +344,9 @@ type FqCodel struct {
 | 
				
			|||||||
	ECN           uint32
 | 
						ECN           uint32
 | 
				
			||||||
	Flows         uint32
 | 
						Flows         uint32
 | 
				
			||||||
	Quantum       uint32
 | 
						Quantum       uint32
 | 
				
			||||||
	// There are some more attributes here, but support for them seems not ubiquitous
 | 
						CEThreshold   uint32
 | 
				
			||||||
 | 
						DropBatchSize uint32
 | 
				
			||||||
 | 
						MemoryLimit   uint32
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (fqcodel *FqCodel) String() string {
 | 
					func (fqcodel *FqCodel) String() string {
 | 
				
			||||||
@@ -338,3 +370,27 @@ func (qdisc *FqCodel) Attrs() *QdiscAttrs {
 | 
				
			|||||||
func (qdisc *FqCodel) Type() string {
 | 
					func (qdisc *FqCodel) Type() string {
 | 
				
			||||||
	return "fq_codel"
 | 
						return "fq_codel"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Sfq struct {
 | 
				
			||||||
 | 
						QdiscAttrs
 | 
				
			||||||
 | 
						// TODO: Only the simplified options for SFQ are handled here. Support for the extended one can be added later.
 | 
				
			||||||
 | 
						Quantum uint8
 | 
				
			||||||
 | 
						Perturb uint8
 | 
				
			||||||
 | 
						Limit   uint32
 | 
				
			||||||
 | 
						Divisor uint8
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (sfq *Sfq) String() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf(
 | 
				
			||||||
 | 
							"{%v -- Quantum: %v, Perturb: %v, Limit: %v, Divisor: %v}",
 | 
				
			||||||
 | 
							sfq.Attrs(), sfq.Quantum, sfq.Perturb, sfq.Limit, sfq.Divisor,
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (qdisc *Sfq) Attrs() *QdiscAttrs {
 | 
				
			||||||
 | 
						return &qdisc.QdiscAttrs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (qdisc *Sfq) Type() string {
 | 
				
			||||||
 | 
						return "sfq"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										148
									
								
								vendor/github.com/vishvananda/netlink/qdisc_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										148
									
								
								vendor/github.com/vishvananda/netlink/qdisc_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -5,6 +5,7 @@ import (
 | 
				
			|||||||
	"io/ioutil"
 | 
						"io/ioutil"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
						"sync"
 | 
				
			||||||
	"syscall"
 | 
						"syscall"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/vishvananda/netlink/nl"
 | 
						"github.com/vishvananda/netlink/nl"
 | 
				
			||||||
@@ -17,6 +18,7 @@ func NewNetem(attrs QdiscAttrs, nattrs NetemQdiscAttrs) *Netem {
 | 
				
			|||||||
	var lossCorr, delayCorr, duplicateCorr uint32
 | 
						var lossCorr, delayCorr, duplicateCorr uint32
 | 
				
			||||||
	var reorderProb, reorderCorr uint32
 | 
						var reorderProb, reorderCorr uint32
 | 
				
			||||||
	var corruptProb, corruptCorr uint32
 | 
						var corruptProb, corruptCorr uint32
 | 
				
			||||||
 | 
						var rate64 uint64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	latency := nattrs.Latency
 | 
						latency := nattrs.Latency
 | 
				
			||||||
	loss := Percentage2u32(nattrs.Loss)
 | 
						loss := Percentage2u32(nattrs.Loss)
 | 
				
			||||||
@@ -57,6 +59,7 @@ func NewNetem(attrs QdiscAttrs, nattrs NetemQdiscAttrs) *Netem {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	corruptProb = Percentage2u32(nattrs.CorruptProb)
 | 
						corruptProb = Percentage2u32(nattrs.CorruptProb)
 | 
				
			||||||
	corruptCorr = Percentage2u32(nattrs.CorruptCorr)
 | 
						corruptCorr = Percentage2u32(nattrs.CorruptCorr)
 | 
				
			||||||
 | 
						rate64 = nattrs.Rate64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return &Netem{
 | 
						return &Netem{
 | 
				
			||||||
		QdiscAttrs:    attrs,
 | 
							QdiscAttrs:    attrs,
 | 
				
			||||||
@@ -73,6 +76,7 @@ func NewNetem(attrs QdiscAttrs, nattrs NetemQdiscAttrs) *Netem {
 | 
				
			|||||||
		ReorderCorr:   reorderCorr,
 | 
							ReorderCorr:   reorderCorr,
 | 
				
			||||||
		CorruptProb:   corruptProb,
 | 
							CorruptProb:   corruptProb,
 | 
				
			||||||
		CorruptCorr:   corruptCorr,
 | 
							CorruptCorr:   corruptCorr,
 | 
				
			||||||
 | 
							Rate64:        rate64,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -159,6 +163,9 @@ func (h *Handle) qdiscModify(cmd, flags int, qdisc Qdisc) error {
 | 
				
			|||||||
func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
 | 
					func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(qdisc.Type())))
 | 
						req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(qdisc.Type())))
 | 
				
			||||||
 | 
						if qdisc.Attrs().IngressBlock != nil {
 | 
				
			||||||
 | 
							req.AddData(nl.NewRtAttr(nl.TCA_INGRESS_BLOCK, nl.Uint32Attr(*qdisc.Attrs().IngressBlock)))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	options := nl.NewRtAttr(nl.TCA_OPTIONS, nil)
 | 
						options := nl.NewRtAttr(nl.TCA_OPTIONS, nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -194,7 +201,9 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
 | 
				
			|||||||
		opt.Debug = qdisc.Debug
 | 
							opt.Debug = qdisc.Debug
 | 
				
			||||||
		opt.DirectPkts = qdisc.DirectPkts
 | 
							opt.DirectPkts = qdisc.DirectPkts
 | 
				
			||||||
		options.AddRtAttr(nl.TCA_HTB_INIT, opt.Serialize())
 | 
							options.AddRtAttr(nl.TCA_HTB_INIT, opt.Serialize())
 | 
				
			||||||
		// options.AddRtAttr(nl.TCA_HTB_DIRECT_QLEN, opt.Serialize())
 | 
							if qdisc.DirectQlen != nil {
 | 
				
			||||||
 | 
								options.AddRtAttr(nl.TCA_HTB_DIRECT_QLEN, nl.Uint32Attr(*qdisc.DirectQlen))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	case *Hfsc:
 | 
						case *Hfsc:
 | 
				
			||||||
		opt := nl.TcHfscOpt{}
 | 
							opt := nl.TcHfscOpt{}
 | 
				
			||||||
		opt.Defcls = qdisc.Defcls
 | 
							opt.Defcls = qdisc.Defcls
 | 
				
			||||||
@@ -231,6 +240,19 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
 | 
				
			|||||||
		if reorder.Probability > 0 {
 | 
							if reorder.Probability > 0 {
 | 
				
			||||||
			options.AddRtAttr(nl.TCA_NETEM_REORDER, reorder.Serialize())
 | 
								options.AddRtAttr(nl.TCA_NETEM_REORDER, reorder.Serialize())
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							// Rate
 | 
				
			||||||
 | 
							if qdisc.Rate64 > 0 {
 | 
				
			||||||
 | 
								rate := nl.TcNetemRate{}
 | 
				
			||||||
 | 
								if qdisc.Rate64 >= uint64(1<<32) {
 | 
				
			||||||
 | 
									options.AddRtAttr(nl.TCA_NETEM_RATE64, nl.Uint64Attr(qdisc.Rate64))
 | 
				
			||||||
 | 
									rate.Rate = ^uint32(0)
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									rate.Rate = uint32(qdisc.Rate64)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								options.AddRtAttr(nl.TCA_NETEM_RATE, rate.Serialize())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						case *Clsact:
 | 
				
			||||||
 | 
							options = nil
 | 
				
			||||||
	case *Ingress:
 | 
						case *Ingress:
 | 
				
			||||||
		// ingress filters must use the proper handle
 | 
							// ingress filters must use the proper handle
 | 
				
			||||||
		if qdisc.Attrs().Parent != HANDLE_INGRESS {
 | 
							if qdisc.Attrs().Parent != HANDLE_INGRESS {
 | 
				
			||||||
@@ -250,13 +272,24 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
 | 
				
			|||||||
		if qdisc.Quantum > 0 {
 | 
							if qdisc.Quantum > 0 {
 | 
				
			||||||
			options.AddRtAttr(nl.TCA_FQ_CODEL_QUANTUM, nl.Uint32Attr((uint32(qdisc.Quantum))))
 | 
								options.AddRtAttr(nl.TCA_FQ_CODEL_QUANTUM, nl.Uint32Attr((uint32(qdisc.Quantum))))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if qdisc.CEThreshold > 0 {
 | 
				
			||||||
 | 
								options.AddRtAttr(nl.TCA_FQ_CODEL_CE_THRESHOLD, nl.Uint32Attr(qdisc.CEThreshold))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if qdisc.DropBatchSize > 0 {
 | 
				
			||||||
 | 
								options.AddRtAttr(nl.TCA_FQ_CODEL_DROP_BATCH_SIZE, nl.Uint32Attr(qdisc.DropBatchSize))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if qdisc.MemoryLimit > 0 {
 | 
				
			||||||
 | 
								options.AddRtAttr(nl.TCA_FQ_CODEL_MEMORY_LIMIT, nl.Uint32Attr(qdisc.MemoryLimit))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	case *Fq:
 | 
						case *Fq:
 | 
				
			||||||
		options.AddRtAttr(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 {
 | 
							if qdisc.Buckets > 0 {
 | 
				
			||||||
			options.AddRtAttr(nl.TCA_FQ_BUCKETS_LOG, nl.Uint32Attr((uint32(qdisc.Buckets))))
 | 
								options.AddRtAttr(nl.TCA_FQ_BUCKETS_LOG, nl.Uint32Attr((uint32(qdisc.Buckets))))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if qdisc.PacketLimit > 0 {
 | 
				
			||||||
 | 
								options.AddRtAttr(nl.TCA_FQ_PLIMIT, nl.Uint32Attr((uint32(qdisc.PacketLimit))))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		if qdisc.LowRateThreshold > 0 {
 | 
							if qdisc.LowRateThreshold > 0 {
 | 
				
			||||||
			options.AddRtAttr(nl.TCA_FQ_LOW_RATE_THRESHOLD, nl.Uint32Attr((uint32(qdisc.LowRateThreshold))))
 | 
								options.AddRtAttr(nl.TCA_FQ_LOW_RATE_THRESHOLD, nl.Uint32Attr((uint32(qdisc.LowRateThreshold))))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -278,6 +311,20 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
 | 
				
			|||||||
		if qdisc.FlowDefaultRate > 0 {
 | 
							if qdisc.FlowDefaultRate > 0 {
 | 
				
			||||||
			options.AddRtAttr(nl.TCA_FQ_FLOW_DEFAULT_RATE, nl.Uint32Attr((uint32(qdisc.FlowDefaultRate))))
 | 
								options.AddRtAttr(nl.TCA_FQ_FLOW_DEFAULT_RATE, nl.Uint32Attr((uint32(qdisc.FlowDefaultRate))))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if qdisc.Horizon > 0 {
 | 
				
			||||||
 | 
								options.AddRtAttr(nl.TCA_FQ_HORIZON, nl.Uint32Attr(qdisc.Horizon))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if qdisc.HorizonDropPolicy != HORIZON_DROP_POLICY_DEFAULT {
 | 
				
			||||||
 | 
								options.AddRtAttr(nl.TCA_FQ_HORIZON_DROP, nl.Uint8Attr(qdisc.HorizonDropPolicy))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						case *Sfq:
 | 
				
			||||||
 | 
							opt := nl.TcSfqQoptV1{}
 | 
				
			||||||
 | 
							opt.TcSfqQopt.Quantum = qdisc.Quantum
 | 
				
			||||||
 | 
							opt.TcSfqQopt.Perturb = int32(qdisc.Perturb)
 | 
				
			||||||
 | 
							opt.TcSfqQopt.Limit = qdisc.Limit
 | 
				
			||||||
 | 
							opt.TcSfqQopt.Divisor = qdisc.Divisor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							options = nl.NewRtAttr(nl.TCA_OPTIONS, opt.Serialize())
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		options = nil
 | 
							options = nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -362,6 +409,10 @@ func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
 | 
				
			|||||||
					qdisc = &FqCodel{}
 | 
										qdisc = &FqCodel{}
 | 
				
			||||||
				case "netem":
 | 
									case "netem":
 | 
				
			||||||
					qdisc = &Netem{}
 | 
										qdisc = &Netem{}
 | 
				
			||||||
 | 
									case "sfq":
 | 
				
			||||||
 | 
										qdisc = &Sfq{}
 | 
				
			||||||
 | 
									case "clsact":
 | 
				
			||||||
 | 
										qdisc = &Clsact{}
 | 
				
			||||||
				default:
 | 
									default:
 | 
				
			||||||
					qdisc = &GenericQdisc{QdiscType: qdiscType}
 | 
										qdisc = &GenericQdisc{QdiscType: qdiscType}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -417,9 +468,29 @@ func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
 | 
				
			|||||||
					if err := parseNetemData(qdisc, attr.Value); err != nil {
 | 
										if err := parseNetemData(qdisc, attr.Value); err != nil {
 | 
				
			||||||
						return nil, err
 | 
											return nil, err
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
									case "sfq":
 | 
				
			||||||
 | 
										if err := parseSfqData(qdisc, attr.Value); err != nil {
 | 
				
			||||||
 | 
											return nil, err
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					// no options for ingress
 | 
										// no options for ingress
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
								case nl.TCA_INGRESS_BLOCK:
 | 
				
			||||||
 | 
									ingressBlock := new(uint32)
 | 
				
			||||||
 | 
									*ingressBlock = native.Uint32(attr.Value)
 | 
				
			||||||
 | 
									base.IngressBlock = ingressBlock
 | 
				
			||||||
 | 
								case nl.TCA_STATS:
 | 
				
			||||||
 | 
									s, err := parseTcStats(attr.Value)
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										return nil, err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									base.Statistics = (*QdiscStatistics)(s)
 | 
				
			||||||
 | 
								case nl.TCA_STATS2:
 | 
				
			||||||
 | 
									s, err := parseTcStats2(attr.Value)
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										return nil, err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									base.Statistics = (*QdiscStatistics)(s)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		*qdisc.Attrs() = base
 | 
							*qdisc.Attrs() = base
 | 
				
			||||||
@@ -446,7 +517,6 @@ func parsePrioData(qdisc Qdisc, value []byte) error {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseHtbData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
 | 
					func parseHtbData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
 | 
				
			||||||
	native = nl.NativeEndian()
 | 
					 | 
				
			||||||
	htb := qdisc.(*Htb)
 | 
						htb := qdisc.(*Htb)
 | 
				
			||||||
	for _, datum := range data {
 | 
						for _, datum := range data {
 | 
				
			||||||
		switch datum.Attr.Type {
 | 
							switch datum.Attr.Type {
 | 
				
			||||||
@@ -458,15 +528,14 @@ func parseHtbData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
 | 
				
			|||||||
			htb.Debug = opt.Debug
 | 
								htb.Debug = opt.Debug
 | 
				
			||||||
			htb.DirectPkts = opt.DirectPkts
 | 
								htb.DirectPkts = opt.DirectPkts
 | 
				
			||||||
		case nl.TCA_HTB_DIRECT_QLEN:
 | 
							case nl.TCA_HTB_DIRECT_QLEN:
 | 
				
			||||||
			// TODO
 | 
								directQlen := native.Uint32(datum.Value)
 | 
				
			||||||
			//htb.DirectQlen = native.uint32(datum.Value)
 | 
								htb.DirectQlen = &directQlen
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseFqCodelData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
 | 
					func parseFqCodelData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
 | 
				
			||||||
	native = nl.NativeEndian()
 | 
					 | 
				
			||||||
	fqCodel := qdisc.(*FqCodel)
 | 
						fqCodel := qdisc.(*FqCodel)
 | 
				
			||||||
	for _, datum := range data {
 | 
						for _, datum := range data {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -483,6 +552,12 @@ func parseFqCodelData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
 | 
				
			|||||||
			fqCodel.Flows = native.Uint32(datum.Value)
 | 
								fqCodel.Flows = native.Uint32(datum.Value)
 | 
				
			||||||
		case nl.TCA_FQ_CODEL_QUANTUM:
 | 
							case nl.TCA_FQ_CODEL_QUANTUM:
 | 
				
			||||||
			fqCodel.Quantum = native.Uint32(datum.Value)
 | 
								fqCodel.Quantum = native.Uint32(datum.Value)
 | 
				
			||||||
 | 
							case nl.TCA_FQ_CODEL_CE_THRESHOLD:
 | 
				
			||||||
 | 
								fqCodel.CEThreshold = native.Uint32(datum.Value)
 | 
				
			||||||
 | 
							case nl.TCA_FQ_CODEL_DROP_BATCH_SIZE:
 | 
				
			||||||
 | 
								fqCodel.DropBatchSize = native.Uint32(datum.Value)
 | 
				
			||||||
 | 
							case nl.TCA_FQ_CODEL_MEMORY_LIMIT:
 | 
				
			||||||
 | 
								fqCodel.MemoryLimit = native.Uint32(datum.Value)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
@@ -490,13 +565,11 @@ func parseFqCodelData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func parseHfscData(qdisc Qdisc, data []byte) error {
 | 
					func parseHfscData(qdisc Qdisc, data []byte) error {
 | 
				
			||||||
	Hfsc := qdisc.(*Hfsc)
 | 
						Hfsc := qdisc.(*Hfsc)
 | 
				
			||||||
	native = nl.NativeEndian()
 | 
					 | 
				
			||||||
	Hfsc.Defcls = native.Uint16(data)
 | 
						Hfsc.Defcls = native.Uint16(data)
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseFqData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
 | 
					func parseFqData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
 | 
				
			||||||
	native = nl.NativeEndian()
 | 
					 | 
				
			||||||
	fq := qdisc.(*Fq)
 | 
						fq := qdisc.(*Fq)
 | 
				
			||||||
	for _, datum := range data {
 | 
						for _, datum := range data {
 | 
				
			||||||
		switch datum.Attr.Type {
 | 
							switch datum.Attr.Type {
 | 
				
			||||||
@@ -522,6 +595,11 @@ func parseFqData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
 | 
				
			|||||||
			fq.FlowMaxRate = native.Uint32(datum.Value)
 | 
								fq.FlowMaxRate = native.Uint32(datum.Value)
 | 
				
			||||||
		case nl.TCA_FQ_FLOW_DEFAULT_RATE:
 | 
							case nl.TCA_FQ_FLOW_DEFAULT_RATE:
 | 
				
			||||||
			fq.FlowDefaultRate = native.Uint32(datum.Value)
 | 
								fq.FlowDefaultRate = native.Uint32(datum.Value)
 | 
				
			||||||
 | 
							case nl.TCA_FQ_HORIZON:
 | 
				
			||||||
 | 
								fq.Horizon = native.Uint32(datum.Value)
 | 
				
			||||||
 | 
							case nl.TCA_FQ_HORIZON_DROP:
 | 
				
			||||||
 | 
								fq.HorizonDropPolicy = datum.Value[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
@@ -540,6 +618,8 @@ func parseNetemData(qdisc Qdisc, value []byte) error {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						var rate *nl.TcNetemRate
 | 
				
			||||||
 | 
						var rate64 uint64
 | 
				
			||||||
	for _, datum := range data {
 | 
						for _, datum := range data {
 | 
				
			||||||
		switch datum.Attr.Type {
 | 
							switch datum.Attr.Type {
 | 
				
			||||||
		case nl.TCA_NETEM_CORR:
 | 
							case nl.TCA_NETEM_CORR:
 | 
				
			||||||
@@ -555,13 +635,23 @@ func parseNetemData(qdisc Qdisc, value []byte) error {
 | 
				
			|||||||
			opt := nl.DeserializeTcNetemReorder(datum.Value)
 | 
								opt := nl.DeserializeTcNetemReorder(datum.Value)
 | 
				
			||||||
			netem.ReorderProb = opt.Probability
 | 
								netem.ReorderProb = opt.Probability
 | 
				
			||||||
			netem.ReorderCorr = opt.Correlation
 | 
								netem.ReorderCorr = opt.Correlation
 | 
				
			||||||
 | 
							case nl.TCA_NETEM_RATE:
 | 
				
			||||||
 | 
								rate = nl.DeserializeTcNetemRate(datum.Value)
 | 
				
			||||||
 | 
							case nl.TCA_NETEM_RATE64:
 | 
				
			||||||
 | 
								rate64 = native.Uint64(datum.Value)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if rate != nil {
 | 
				
			||||||
 | 
							netem.Rate64 = uint64(rate.Rate)
 | 
				
			||||||
 | 
							if rate64 > 0 {
 | 
				
			||||||
 | 
								netem.Rate64 = rate64
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseTbfData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
 | 
					func parseTbfData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
 | 
				
			||||||
	native = nl.NativeEndian()
 | 
					 | 
				
			||||||
	tbf := qdisc.(*Tbf)
 | 
						tbf := qdisc.(*Tbf)
 | 
				
			||||||
	for _, datum := range data {
 | 
						for _, datum := range data {
 | 
				
			||||||
		switch datum.Attr.Type {
 | 
							switch datum.Attr.Type {
 | 
				
			||||||
@@ -582,6 +672,17 @@ func parseTbfData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseSfqData(qdisc Qdisc, value []byte) error {
 | 
				
			||||||
 | 
						sfq := qdisc.(*Sfq)
 | 
				
			||||||
 | 
						opt := nl.DeserializeTcSfqQoptV1(value)
 | 
				
			||||||
 | 
						sfq.Quantum = opt.TcSfqQopt.Quantum
 | 
				
			||||||
 | 
						sfq.Perturb = uint8(opt.TcSfqQopt.Perturb)
 | 
				
			||||||
 | 
						sfq.Limit = opt.TcSfqQopt.Limit
 | 
				
			||||||
 | 
						sfq.Divisor = opt.TcSfqQopt.Divisor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	TIME_UNITS_PER_SEC = 1000000
 | 
						TIME_UNITS_PER_SEC = 1000000
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -590,6 +691,9 @@ var (
 | 
				
			|||||||
	tickInUsec  float64
 | 
						tickInUsec  float64
 | 
				
			||||||
	clockFactor float64
 | 
						clockFactor float64
 | 
				
			||||||
	hz          float64
 | 
						hz          float64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Without this, the go race detector may report races.
 | 
				
			||||||
 | 
						initClockMutex sync.Mutex
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func initClock() {
 | 
					func initClock() {
 | 
				
			||||||
@@ -598,10 +702,10 @@ func initClock() {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	parts := strings.Split(strings.TrimSpace(string(data)), " ")
 | 
						parts := strings.Split(strings.TrimSpace(string(data)), " ")
 | 
				
			||||||
	if len(parts) < 3 {
 | 
						if len(parts) < 4 {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	var vals [3]uint64
 | 
						var vals [4]uint64
 | 
				
			||||||
	for i := range vals {
 | 
						for i := range vals {
 | 
				
			||||||
		val, err := strconv.ParseUint(parts[i], 16, 32)
 | 
							val, err := strconv.ParseUint(parts[i], 16, 32)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
@@ -615,10 +719,17 @@ func initClock() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	clockFactor = float64(vals[2]) / TIME_UNITS_PER_SEC
 | 
						clockFactor = float64(vals[2]) / TIME_UNITS_PER_SEC
 | 
				
			||||||
	tickInUsec = float64(vals[0]) / float64(vals[1]) * clockFactor
 | 
						tickInUsec = float64(vals[0]) / float64(vals[1]) * clockFactor
 | 
				
			||||||
	hz = float64(vals[0])
 | 
						if vals[2] == 1000000 {
 | 
				
			||||||
 | 
							// ref https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/tree/lib/utils.c#n963
 | 
				
			||||||
 | 
							hz = float64(vals[3])
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							hz = 100
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TickInUsec() float64 {
 | 
					func TickInUsec() float64 {
 | 
				
			||||||
 | 
						initClockMutex.Lock()
 | 
				
			||||||
 | 
						defer initClockMutex.Unlock()
 | 
				
			||||||
	if tickInUsec == 0.0 {
 | 
						if tickInUsec == 0.0 {
 | 
				
			||||||
		initClock()
 | 
							initClock()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -626,6 +737,8 @@ func TickInUsec() float64 {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ClockFactor() float64 {
 | 
					func ClockFactor() float64 {
 | 
				
			||||||
 | 
						initClockMutex.Lock()
 | 
				
			||||||
 | 
						defer initClockMutex.Unlock()
 | 
				
			||||||
	if clockFactor == 0.0 {
 | 
						if clockFactor == 0.0 {
 | 
				
			||||||
		initClock()
 | 
							initClock()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -633,6 +746,8 @@ func ClockFactor() float64 {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Hz() float64 {
 | 
					func Hz() float64 {
 | 
				
			||||||
 | 
						initClockMutex.Lock()
 | 
				
			||||||
 | 
						defer initClockMutex.Unlock()
 | 
				
			||||||
	if hz == 0.0 {
 | 
						if hz == 0.0 {
 | 
				
			||||||
		initClock()
 | 
							initClock()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -663,6 +778,11 @@ func latency(rate uint64, limit, buffer uint32) float64 {
 | 
				
			|||||||
	return TIME_UNITS_PER_SEC*(float64(limit)/float64(rate)) - float64(tick2Time(buffer))
 | 
						return TIME_UNITS_PER_SEC*(float64(limit)/float64(rate)) - float64(tick2Time(buffer))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Xmittime(rate uint64, size uint32) float64 {
 | 
					func Xmittime(rate uint64, size uint32) uint32 {
 | 
				
			||||||
	return TickInUsec() * TIME_UNITS_PER_SEC * (float64(size) / float64(rate))
 | 
						// https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/tree/tc/tc_core.c#n62
 | 
				
			||||||
 | 
						return time2Tick(uint32(TIME_UNITS_PER_SEC * (float64(size) / float64(rate))))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func Xmitsize(rate uint64, ticks uint32) uint32 {
 | 
				
			||||||
 | 
						return uint32((float64(rate) * float64(tick2Time(ticks))) / TIME_UNITS_PER_SEC)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										97
									
								
								vendor/github.com/vishvananda/netlink/rdma_link_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										97
									
								
								vendor/github.com/vishvananda/netlink/rdma_link_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -77,28 +77,39 @@ func executeOneGetRdmaLink(data []byte) (*RdmaLink, error) {
 | 
				
			|||||||
	return &link, nil
 | 
						return &link, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func execRdmaGetLink(req *nl.NetlinkRequest, name string) (*RdmaLink, error) {
 | 
					func execRdmaSetLink(req *nl.NetlinkRequest) error {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err := req.Execute(unix.NETLINK_RDMA, 0)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RdmaLinkList gets a list of RDMA link devices.
 | 
				
			||||||
 | 
					// Equivalent to: `rdma dev show`
 | 
				
			||||||
 | 
					func RdmaLinkList() ([]*RdmaLink, error) {
 | 
				
			||||||
 | 
						return pkgHandle.RdmaLinkList()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RdmaLinkList gets a list of RDMA link devices.
 | 
				
			||||||
 | 
					// Equivalent to: `rdma dev show`
 | 
				
			||||||
 | 
					func (h *Handle) RdmaLinkList() ([]*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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	msgs, err := req.Execute(unix.NETLINK_RDMA, 0)
 | 
						msgs, err := req.Execute(unix.NETLINK_RDMA, 0)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var res []*RdmaLink
 | 
				
			||||||
	for _, m := range msgs {
 | 
						for _, m := range msgs {
 | 
				
			||||||
		link, err := executeOneGetRdmaLink(m)
 | 
							link, err := executeOneGetRdmaLink(m)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if link.Attrs.Name == name {
 | 
							res = append(res, link)
 | 
				
			||||||
			return link, nil
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil, fmt.Errorf("Rdma device %v not found", name)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
func execRdmaSetLink(req *nl.NetlinkRequest) error {
 | 
						return res, nil
 | 
				
			||||||
 | 
					 | 
				
			||||||
	_, err := req.Execute(unix.NETLINK_RDMA, 0)
 | 
					 | 
				
			||||||
	return err
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RdmaLinkByName finds a link by name and returns a pointer to the object if
 | 
					// RdmaLinkByName finds a link by name and returns a pointer to the object if
 | 
				
			||||||
@@ -110,11 +121,16 @@ func RdmaLinkByName(name string) (*RdmaLink, error) {
 | 
				
			|||||||
// RdmaLinkByName finds a link by name and returns a pointer to the object if
 | 
					// RdmaLinkByName finds a link by name and returns a pointer to the object if
 | 
				
			||||||
// found and nil error, otherwise returns error code.
 | 
					// found and nil error, otherwise returns error code.
 | 
				
			||||||
func (h *Handle) RdmaLinkByName(name string) (*RdmaLink, error) {
 | 
					func (h *Handle) RdmaLinkByName(name string) (*RdmaLink, error) {
 | 
				
			||||||
 | 
						links, err := h.RdmaLinkList()
 | 
				
			||||||
	proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_GET)
 | 
						if err != nil {
 | 
				
			||||||
	req := h.newNetlinkRequest(proto, unix.NLM_F_ACK|unix.NLM_F_DUMP)
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return execRdmaGetLink(req, name)
 | 
						for _, link := range links {
 | 
				
			||||||
 | 
							if link.Attrs.Name == name {
 | 
				
			||||||
 | 
								return link, nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil, fmt.Errorf("Rdma device %v not found", name)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RdmaLinkSetName sets the name of the rdma link device. Return nil on success
 | 
					// RdmaLinkSetName sets the name of the rdma link device. Return nil on success
 | 
				
			||||||
@@ -262,3 +278,54 @@ func (h *Handle) RdmaLinkSetNsFd(link *RdmaLink, fd uint32) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return execRdmaSetLink(req)
 | 
						return execRdmaSetLink(req)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RdmaLinkDel deletes an rdma link
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Similar to: rdma link delete NAME
 | 
				
			||||||
 | 
					// REF: https://man7.org/linux/man-pages/man8/rdma-link.8.html
 | 
				
			||||||
 | 
					func RdmaLinkDel(name string) error {
 | 
				
			||||||
 | 
						return pkgHandle.RdmaLinkDel(name)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RdmaLinkDel deletes an rdma link.
 | 
				
			||||||
 | 
					func (h *Handle) RdmaLinkDel(name string) error {
 | 
				
			||||||
 | 
						link, err := h.RdmaLinkByName(name)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_DELLINK)
 | 
				
			||||||
 | 
						req := h.newNetlinkRequest(proto, unix.NLM_F_ACK)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						b := make([]byte, 4)
 | 
				
			||||||
 | 
						native.PutUint32(b, link.Attrs.Index)
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_DEV_INDEX, b))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err = req.Execute(unix.NETLINK_RDMA, 0)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RdmaLinkAdd adds an rdma link for the specified type to the network device.
 | 
				
			||||||
 | 
					// Similar to: rdma link add NAME type TYPE netdev NETDEV
 | 
				
			||||||
 | 
					//	NAME - specifies the new name of the rdma link to add
 | 
				
			||||||
 | 
					//	TYPE - specifies which rdma type to use.  Link types:
 | 
				
			||||||
 | 
					//		rxe - Soft RoCE driver
 | 
				
			||||||
 | 
					//		siw - Soft iWARP driver
 | 
				
			||||||
 | 
					//	NETDEV - specifies the network device to which the link is bound
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// REF: https://man7.org/linux/man-pages/man8/rdma-link.8.html
 | 
				
			||||||
 | 
					func RdmaLinkAdd(linkName, linkType, netdev string) error {
 | 
				
			||||||
 | 
						return pkgHandle.RdmaLinkAdd(linkName, linkType, netdev)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RdmaLinkAdd adds an rdma link for the specified type to the network device.
 | 
				
			||||||
 | 
					func (h *Handle) RdmaLinkAdd(linkName string, linkType string, netdev string) error {
 | 
				
			||||||
 | 
						proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_NEWLINK)
 | 
				
			||||||
 | 
						req := h.newNetlinkRequest(proto, unix.NLM_F_ACK)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_DEV_NAME, nl.ZeroTerminated(linkName)))
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_LINK_TYPE, nl.ZeroTerminated(linkType)))
 | 
				
			||||||
 | 
						req.AddData(nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_NDEV_NAME, nl.ZeroTerminated(netdev)))
 | 
				
			||||||
 | 
						_, err := req.Execute(unix.NETLINK_RDMA, 0)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										56
									
								
								vendor/github.com/vishvananda/netlink/route.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										56
									
								
								vendor/github.com/vishvananda/netlink/route.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -11,6 +11,24 @@ type Scope uint8
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type NextHopFlag int
 | 
					type NextHopFlag int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						RT_FILTER_PROTOCOL uint64 = 1 << (1 + iota)
 | 
				
			||||||
 | 
						RT_FILTER_SCOPE
 | 
				
			||||||
 | 
						RT_FILTER_TYPE
 | 
				
			||||||
 | 
						RT_FILTER_TOS
 | 
				
			||||||
 | 
						RT_FILTER_IIF
 | 
				
			||||||
 | 
						RT_FILTER_OIF
 | 
				
			||||||
 | 
						RT_FILTER_DST
 | 
				
			||||||
 | 
						RT_FILTER_SRC
 | 
				
			||||||
 | 
						RT_FILTER_GW
 | 
				
			||||||
 | 
						RT_FILTER_TABLE
 | 
				
			||||||
 | 
						RT_FILTER_HOPLIMIT
 | 
				
			||||||
 | 
						RT_FILTER_PRIORITY
 | 
				
			||||||
 | 
						RT_FILTER_MARK
 | 
				
			||||||
 | 
						RT_FILTER_MASK
 | 
				
			||||||
 | 
						RT_FILTER_REALM
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Destination interface {
 | 
					type Destination interface {
 | 
				
			||||||
	Family() int
 | 
						Family() int
 | 
				
			||||||
	Decode([]byte) error
 | 
						Decode([]byte) error
 | 
				
			||||||
@@ -27,6 +45,9 @@ type Encap interface {
 | 
				
			|||||||
	Equal(Encap) bool
 | 
						Equal(Encap) bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//Protocol describe what was the originator of the route
 | 
				
			||||||
 | 
					type RouteProtocol int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Route represents a netlink route.
 | 
					// Route represents a netlink route.
 | 
				
			||||||
type Route struct {
 | 
					type Route struct {
 | 
				
			||||||
	LinkIndex        int
 | 
						LinkIndex        int
 | 
				
			||||||
@@ -36,8 +57,9 @@ type Route struct {
 | 
				
			|||||||
	Src              net.IP
 | 
						Src              net.IP
 | 
				
			||||||
	Gw               net.IP
 | 
						Gw               net.IP
 | 
				
			||||||
	MultiPath        []*NexthopInfo
 | 
						MultiPath        []*NexthopInfo
 | 
				
			||||||
	Protocol   int
 | 
						Protocol         RouteProtocol
 | 
				
			||||||
	Priority         int
 | 
						Priority         int
 | 
				
			||||||
 | 
						Family           int
 | 
				
			||||||
	Table            int
 | 
						Table            int
 | 
				
			||||||
	Type             int
 | 
						Type             int
 | 
				
			||||||
	Tos              int
 | 
						Tos              int
 | 
				
			||||||
@@ -45,9 +67,24 @@ type Route struct {
 | 
				
			|||||||
	MPLSDst          *int
 | 
						MPLSDst          *int
 | 
				
			||||||
	NewDst           Destination
 | 
						NewDst           Destination
 | 
				
			||||||
	Encap            Encap
 | 
						Encap            Encap
 | 
				
			||||||
 | 
						Via              Destination
 | 
				
			||||||
 | 
						Realm            int
 | 
				
			||||||
	MTU              int
 | 
						MTU              int
 | 
				
			||||||
 | 
						Window           int
 | 
				
			||||||
 | 
						Rtt              int
 | 
				
			||||||
 | 
						RttVar           int
 | 
				
			||||||
 | 
						Ssthresh         int
 | 
				
			||||||
 | 
						Cwnd             int
 | 
				
			||||||
	AdvMSS           int
 | 
						AdvMSS           int
 | 
				
			||||||
 | 
						Reordering       int
 | 
				
			||||||
	Hoplimit         int
 | 
						Hoplimit         int
 | 
				
			||||||
 | 
						InitCwnd         int
 | 
				
			||||||
 | 
						Features         int
 | 
				
			||||||
 | 
						RtoMin           int
 | 
				
			||||||
 | 
						InitRwnd         int
 | 
				
			||||||
 | 
						QuickACK         int
 | 
				
			||||||
 | 
						Congctl          string
 | 
				
			||||||
 | 
						FastOpenNoCookie int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r Route) String() string {
 | 
					func (r Route) String() string {
 | 
				
			||||||
@@ -66,6 +103,9 @@ func (r Route) String() string {
 | 
				
			|||||||
	if r.Encap != nil {
 | 
						if r.Encap != nil {
 | 
				
			||||||
		elems = append(elems, fmt.Sprintf("Encap: %s", r.Encap))
 | 
							elems = append(elems, fmt.Sprintf("Encap: %s", r.Encap))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if r.Via != nil {
 | 
				
			||||||
 | 
							elems = append(elems, fmt.Sprintf("Via: %s", r.Via))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	elems = append(elems, fmt.Sprintf("Src: %s", r.Src))
 | 
						elems = append(elems, fmt.Sprintf("Src: %s", r.Src))
 | 
				
			||||||
	if len(r.MultiPath) > 0 {
 | 
						if len(r.MultiPath) > 0 {
 | 
				
			||||||
		elems = append(elems, fmt.Sprintf("Gw: %s", r.MultiPath))
 | 
							elems = append(elems, fmt.Sprintf("Gw: %s", r.MultiPath))
 | 
				
			||||||
@@ -74,6 +114,7 @@ func (r Route) String() string {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	elems = append(elems, fmt.Sprintf("Flags: %s", r.ListFlags()))
 | 
						elems = append(elems, fmt.Sprintf("Flags: %s", r.ListFlags()))
 | 
				
			||||||
	elems = append(elems, fmt.Sprintf("Table: %d", r.Table))
 | 
						elems = append(elems, fmt.Sprintf("Table: %d", r.Table))
 | 
				
			||||||
 | 
						elems = append(elems, fmt.Sprintf("Realm: %d", r.Realm))
 | 
				
			||||||
	return fmt.Sprintf("{%s}", strings.Join(elems, " "))
 | 
						return fmt.Sprintf("{%s}", strings.Join(elems, " "))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -87,6 +128,7 @@ func (r Route) Equal(x Route) bool {
 | 
				
			|||||||
		nexthopInfoSlice(r.MultiPath).Equal(x.MultiPath) &&
 | 
							nexthopInfoSlice(r.MultiPath).Equal(x.MultiPath) &&
 | 
				
			||||||
		r.Protocol == x.Protocol &&
 | 
							r.Protocol == x.Protocol &&
 | 
				
			||||||
		r.Priority == x.Priority &&
 | 
							r.Priority == x.Priority &&
 | 
				
			||||||
 | 
							r.Realm == x.Realm &&
 | 
				
			||||||
		r.Table == x.Table &&
 | 
							r.Table == x.Table &&
 | 
				
			||||||
		r.Type == x.Type &&
 | 
							r.Type == x.Type &&
 | 
				
			||||||
		r.Tos == x.Tos &&
 | 
							r.Tos == x.Tos &&
 | 
				
			||||||
@@ -94,6 +136,7 @@ func (r Route) Equal(x Route) bool {
 | 
				
			|||||||
		r.Flags == x.Flags &&
 | 
							r.Flags == x.Flags &&
 | 
				
			||||||
		(r.MPLSDst == x.MPLSDst || (r.MPLSDst != nil && x.MPLSDst != nil && *r.MPLSDst == *x.MPLSDst)) &&
 | 
							(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))) &&
 | 
							(r.NewDst == x.NewDst || (r.NewDst != nil && r.NewDst.Equal(x.NewDst))) &&
 | 
				
			||||||
 | 
							(r.Via == x.Via || (r.Via != nil && r.Via.Equal(x.Via))) &&
 | 
				
			||||||
		(r.Encap == x.Encap || (r.Encap != nil && r.Encap.Equal(x.Encap)))
 | 
							(r.Encap == x.Encap || (r.Encap != nil && r.Encap.Equal(x.Encap)))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -111,8 +154,15 @@ type flagString struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RouteUpdate is sent when a route changes - type is RTM_NEWROUTE or RTM_DELROUTE
 | 
					// RouteUpdate is sent when a route changes - type is RTM_NEWROUTE or RTM_DELROUTE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NlFlags is only non-zero for RTM_NEWROUTE, the following flags can be set:
 | 
				
			||||||
 | 
					//   - unix.NLM_F_REPLACE - Replace existing matching config object with this request
 | 
				
			||||||
 | 
					//   - unix.NLM_F_EXCL - Don't replace the config object if it already exists
 | 
				
			||||||
 | 
					//   - unix.NLM_F_CREATE - Create config object if it doesn't already exist
 | 
				
			||||||
 | 
					//   - unix.NLM_F_APPEND - Add to the end of the object list
 | 
				
			||||||
type RouteUpdate struct {
 | 
					type RouteUpdate struct {
 | 
				
			||||||
	Type    uint16
 | 
						Type    uint16
 | 
				
			||||||
 | 
						NlFlags uint16
 | 
				
			||||||
	Route
 | 
						Route
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -123,6 +173,7 @@ type NexthopInfo struct {
 | 
				
			|||||||
	Flags     int
 | 
						Flags     int
 | 
				
			||||||
	NewDst    Destination
 | 
						NewDst    Destination
 | 
				
			||||||
	Encap     Encap
 | 
						Encap     Encap
 | 
				
			||||||
 | 
						Via       Destination
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (n *NexthopInfo) String() string {
 | 
					func (n *NexthopInfo) String() string {
 | 
				
			||||||
@@ -134,6 +185,9 @@ func (n *NexthopInfo) String() string {
 | 
				
			|||||||
	if n.Encap != nil {
 | 
						if n.Encap != nil {
 | 
				
			||||||
		elems = append(elems, fmt.Sprintf("Encap: %s", n.Encap))
 | 
							elems = append(elems, fmt.Sprintf("Encap: %s", n.Encap))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if n.Via != nil {
 | 
				
			||||||
 | 
							elems = append(elems, fmt.Sprintf("Via: %s", n.Via))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	elems = append(elems, fmt.Sprintf("Weight: %d", n.Hops+1))
 | 
						elems = append(elems, fmt.Sprintf("Weight: %d", n.Hops+1))
 | 
				
			||||||
	elems = append(elems, fmt.Sprintf("Gw: %s", n.Gw))
 | 
						elems = append(elems, fmt.Sprintf("Gw: %s", n.Gw))
 | 
				
			||||||
	elems = append(elems, fmt.Sprintf("Flags: %s", n.ListFlags()))
 | 
						elems = append(elems, fmt.Sprintf("Flags: %s", n.ListFlags()))
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										932
									
								
								vendor/github.com/vishvananda/netlink/route_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										932
									
								
								vendor/github.com/vishvananda/netlink/route_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										10
									
								
								vendor/github.com/vishvananda/netlink/route_unspecified.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/vishvananda/netlink/route_unspecified.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -2,6 +2,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
package netlink
 | 
					package netlink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "strconv"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *Route) ListFlags() []string {
 | 
					func (r *Route) ListFlags() []string {
 | 
				
			||||||
	return []string{}
 | 
						return []string{}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -9,3 +11,11 @@ func (r *Route) ListFlags() []string {
 | 
				
			|||||||
func (n *NexthopInfo) ListFlags() []string {
 | 
					func (n *NexthopInfo) ListFlags() []string {
 | 
				
			||||||
	return []string{}
 | 
						return []string{}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s Scope) String() string {
 | 
				
			||||||
 | 
						return "unknown"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (p RouteProtocol) String() string {
 | 
				
			||||||
 | 
						return strconv.Itoa(int(p))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										50
									
								
								vendor/github.com/vishvananda/netlink/rule.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										50
									
								
								vendor/github.com/vishvananda/netlink/rule.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -10,8 +10,9 @@ type Rule struct {
 | 
				
			|||||||
	Priority          int
 | 
						Priority          int
 | 
				
			||||||
	Family            int
 | 
						Family            int
 | 
				
			||||||
	Table             int
 | 
						Table             int
 | 
				
			||||||
	Mark              int
 | 
						Mark              uint32
 | 
				
			||||||
	Mask              int
 | 
						Mask              *uint32
 | 
				
			||||||
 | 
						Tos               uint
 | 
				
			||||||
	TunID             uint
 | 
						TunID             uint
 | 
				
			||||||
	Goto              int
 | 
						Goto              int
 | 
				
			||||||
	Src               *net.IPNet
 | 
						Src               *net.IPNet
 | 
				
			||||||
@@ -22,10 +23,27 @@ type Rule struct {
 | 
				
			|||||||
	SuppressIfgroup   int
 | 
						SuppressIfgroup   int
 | 
				
			||||||
	SuppressPrefixlen int
 | 
						SuppressPrefixlen int
 | 
				
			||||||
	Invert            bool
 | 
						Invert            bool
 | 
				
			||||||
 | 
						Dport             *RulePortRange
 | 
				
			||||||
 | 
						Sport             *RulePortRange
 | 
				
			||||||
 | 
						IPProto           int
 | 
				
			||||||
 | 
						UIDRange          *RuleUIDRange
 | 
				
			||||||
 | 
						Protocol          uint8
 | 
				
			||||||
 | 
						Type              uint8
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r Rule) String() string {
 | 
					func (r Rule) String() string {
 | 
				
			||||||
	return fmt.Sprintf("ip rule %d: from %s table %d", r.Priority, r.Src, r.Table)
 | 
						from := "all"
 | 
				
			||||||
 | 
						if r.Src != nil && r.Src.String() != "<nil>" {
 | 
				
			||||||
 | 
							from = r.Src.String()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						to := "all"
 | 
				
			||||||
 | 
						if r.Dst != nil && r.Dst.String() != "<nil>" {
 | 
				
			||||||
 | 
							to = r.Dst.String()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return fmt.Sprintf("ip rule %d: from %s to %s table %d %s",
 | 
				
			||||||
 | 
							r.Priority, from, to, r.Table, r.typeString())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewRule return empty rules.
 | 
					// NewRule return empty rules.
 | 
				
			||||||
@@ -34,9 +52,31 @@ func NewRule() *Rule {
 | 
				
			|||||||
		SuppressIfgroup:   -1,
 | 
							SuppressIfgroup:   -1,
 | 
				
			||||||
		SuppressPrefixlen: -1,
 | 
							SuppressPrefixlen: -1,
 | 
				
			||||||
		Priority:          -1,
 | 
							Priority:          -1,
 | 
				
			||||||
		Mark:              -1,
 | 
							Mark:              0,
 | 
				
			||||||
		Mask:              -1,
 | 
							Mask:              nil,
 | 
				
			||||||
		Goto:              -1,
 | 
							Goto:              -1,
 | 
				
			||||||
		Flow:              -1,
 | 
							Flow:              -1,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewRulePortRange creates rule sport/dport range.
 | 
				
			||||||
 | 
					func NewRulePortRange(start, end uint16) *RulePortRange {
 | 
				
			||||||
 | 
						return &RulePortRange{Start: start, End: end}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RulePortRange represents rule sport/dport range.
 | 
				
			||||||
 | 
					type RulePortRange struct {
 | 
				
			||||||
 | 
						Start uint16
 | 
				
			||||||
 | 
						End   uint16
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewRuleUIDRange creates rule uid range.
 | 
				
			||||||
 | 
					func NewRuleUIDRange(start, end uint32) *RuleUIDRange {
 | 
				
			||||||
 | 
						return &RuleUIDRange{Start: start, End: end}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RuleUIDRange represents rule uid range.
 | 
				
			||||||
 | 
					type RuleUIDRange struct {
 | 
				
			||||||
 | 
						Start uint32
 | 
				
			||||||
 | 
						End   uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										159
									
								
								vendor/github.com/vishvananda/netlink/rule_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										159
									
								
								vendor/github.com/vishvananda/netlink/rule_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,6 +1,7 @@
 | 
				
			|||||||
package netlink
 | 
					package netlink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -42,8 +43,8 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
 | 
				
			|||||||
	msg.Protocol = unix.RTPROT_BOOT
 | 
						msg.Protocol = unix.RTPROT_BOOT
 | 
				
			||||||
	msg.Scope = unix.RT_SCOPE_UNIVERSE
 | 
						msg.Scope = unix.RT_SCOPE_UNIVERSE
 | 
				
			||||||
	msg.Table = unix.RT_TABLE_UNSPEC
 | 
						msg.Table = unix.RT_TABLE_UNSPEC
 | 
				
			||||||
	msg.Type = unix.RTN_UNSPEC
 | 
						msg.Type = rule.Type // usually 0, same as unix.RTN_UNSPEC
 | 
				
			||||||
	if req.NlMsghdr.Flags&unix.NLM_F_CREATE > 0 {
 | 
						if msg.Type == 0 && req.NlMsghdr.Flags&unix.NLM_F_CREATE > 0 {
 | 
				
			||||||
		msg.Type = unix.RTN_UNICAST
 | 
							msg.Type = unix.RTN_UNICAST
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if rule.Invert {
 | 
						if rule.Invert {
 | 
				
			||||||
@@ -55,6 +56,9 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
 | 
				
			|||||||
	if rule.Table >= 0 && rule.Table < 256 {
 | 
						if rule.Table >= 0 && rule.Table < 256 {
 | 
				
			||||||
		msg.Table = uint8(rule.Table)
 | 
							msg.Table = uint8(rule.Table)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if rule.Tos != 0 {
 | 
				
			||||||
 | 
							msg.Tos = uint8(rule.Tos)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var dstFamily uint8
 | 
						var dstFamily uint8
 | 
				
			||||||
	var rtAttrs []*nl.RtAttr
 | 
						var rtAttrs []*nl.RtAttr
 | 
				
			||||||
@@ -93,21 +97,19 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
 | 
				
			|||||||
		req.AddData(rtAttrs[i])
 | 
							req.AddData(rtAttrs[i])
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	native := nl.NativeEndian()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if rule.Priority >= 0 {
 | 
						if rule.Priority >= 0 {
 | 
				
			||||||
		b := make([]byte, 4)
 | 
							b := make([]byte, 4)
 | 
				
			||||||
		native.PutUint32(b, uint32(rule.Priority))
 | 
							native.PutUint32(b, uint32(rule.Priority))
 | 
				
			||||||
		req.AddData(nl.NewRtAttr(nl.FRA_PRIORITY, b))
 | 
							req.AddData(nl.NewRtAttr(nl.FRA_PRIORITY, b))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if rule.Mark >= 0 {
 | 
						if rule.Mark != 0 || rule.Mask != nil {
 | 
				
			||||||
		b := make([]byte, 4)
 | 
							b := make([]byte, 4)
 | 
				
			||||||
		native.PutUint32(b, uint32(rule.Mark))
 | 
							native.PutUint32(b, rule.Mark)
 | 
				
			||||||
		req.AddData(nl.NewRtAttr(nl.FRA_FWMARK, b))
 | 
							req.AddData(nl.NewRtAttr(nl.FRA_FWMARK, b))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if rule.Mask >= 0 {
 | 
						if rule.Mask != nil {
 | 
				
			||||||
		b := make([]byte, 4)
 | 
							b := make([]byte, 4)
 | 
				
			||||||
		native.PutUint32(b, uint32(rule.Mask))
 | 
							native.PutUint32(b, *rule.Mask)
 | 
				
			||||||
		req.AddData(nl.NewRtAttr(nl.FRA_FWMASK, b))
 | 
							req.AddData(nl.NewRtAttr(nl.FRA_FWMASK, b))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if rule.Flow >= 0 {
 | 
						if rule.Flow >= 0 {
 | 
				
			||||||
@@ -138,10 +140,10 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if rule.IifName != "" {
 | 
						if rule.IifName != "" {
 | 
				
			||||||
		req.AddData(nl.NewRtAttr(nl.FRA_IIFNAME, []byte(rule.IifName)))
 | 
							req.AddData(nl.NewRtAttr(nl.FRA_IIFNAME, []byte(rule.IifName+"\x00")))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if rule.OifName != "" {
 | 
						if rule.OifName != "" {
 | 
				
			||||||
		req.AddData(nl.NewRtAttr(nl.FRA_OIFNAME, []byte(rule.OifName)))
 | 
							req.AddData(nl.NewRtAttr(nl.FRA_OIFNAME, []byte(rule.OifName+"\x00")))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if rule.Goto >= 0 {
 | 
						if rule.Goto >= 0 {
 | 
				
			||||||
		msg.Type = nl.FR_ACT_GOTO
 | 
							msg.Type = nl.FR_ACT_GOTO
 | 
				
			||||||
@@ -150,6 +152,31 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
 | 
				
			|||||||
		req.AddData(nl.NewRtAttr(nl.FRA_GOTO, b))
 | 
							req.AddData(nl.NewRtAttr(nl.FRA_GOTO, b))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if rule.IPProto > 0 {
 | 
				
			||||||
 | 
							b := make([]byte, 4)
 | 
				
			||||||
 | 
							native.PutUint32(b, uint32(rule.IPProto))
 | 
				
			||||||
 | 
							req.AddData(nl.NewRtAttr(nl.FRA_IP_PROTO, b))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if rule.Dport != nil {
 | 
				
			||||||
 | 
							b := rule.Dport.toRtAttrData()
 | 
				
			||||||
 | 
							req.AddData(nl.NewRtAttr(nl.FRA_DPORT_RANGE, b))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if rule.Sport != nil {
 | 
				
			||||||
 | 
							b := rule.Sport.toRtAttrData()
 | 
				
			||||||
 | 
							req.AddData(nl.NewRtAttr(nl.FRA_SPORT_RANGE, b))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if rule.UIDRange != nil {
 | 
				
			||||||
 | 
							b := rule.UIDRange.toRtAttrData()
 | 
				
			||||||
 | 
							req.AddData(nl.NewRtAttr(nl.FRA_UID_RANGE, b))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if rule.Protocol > 0 {
 | 
				
			||||||
 | 
							req.AddData(nl.NewRtAttr(nl.FRA_PROTOCOL, nl.Uint8Attr(rule.Protocol)))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err := req.Execute(unix.NETLINK_ROUTE, 0)
 | 
						_, err := req.Execute(unix.NETLINK_ROUTE, 0)
 | 
				
			||||||
	return err
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -163,6 +190,19 @@ func RuleList(family int) ([]Rule, error) {
 | 
				
			|||||||
// RuleList lists rules in the system.
 | 
					// RuleList lists rules in the system.
 | 
				
			||||||
// Equivalent to: ip rule list
 | 
					// Equivalent to: ip rule list
 | 
				
			||||||
func (h *Handle) RuleList(family int) ([]Rule, error) {
 | 
					func (h *Handle) RuleList(family int) ([]Rule, error) {
 | 
				
			||||||
 | 
						return h.RuleListFiltered(family, nil, 0)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RuleListFiltered gets a list of rules in the system filtered by the
 | 
				
			||||||
 | 
					// specified rule template `filter`.
 | 
				
			||||||
 | 
					// Equivalent to: ip rule list
 | 
				
			||||||
 | 
					func RuleListFiltered(family int, filter *Rule, filterMask uint64) ([]Rule, error) {
 | 
				
			||||||
 | 
						return pkgHandle.RuleListFiltered(family, filter, filterMask)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RuleListFiltered lists rules in the system.
 | 
				
			||||||
 | 
					// Equivalent to: ip rule list
 | 
				
			||||||
 | 
					func (h *Handle) RuleListFiltered(family int, filter *Rule, filterMask uint64) ([]Rule, error) {
 | 
				
			||||||
	req := h.newNetlinkRequest(unix.RTM_GETRULE, unix.NLM_F_DUMP|unix.NLM_F_REQUEST)
 | 
						req := h.newNetlinkRequest(unix.RTM_GETRULE, unix.NLM_F_DUMP|unix.NLM_F_REQUEST)
 | 
				
			||||||
	msg := nl.NewIfInfomsg(family)
 | 
						msg := nl.NewIfInfomsg(family)
 | 
				
			||||||
	req.AddData(msg)
 | 
						req.AddData(msg)
 | 
				
			||||||
@@ -172,7 +212,6 @@ func (h *Handle) RuleList(family int) ([]Rule, error) {
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	native := nl.NativeEndian()
 | 
					 | 
				
			||||||
	var res = make([]Rule, 0)
 | 
						var res = make([]Rule, 0)
 | 
				
			||||||
	for i := range msgs {
 | 
						for i := range msgs {
 | 
				
			||||||
		msg := nl.DeserializeRtMsg(msgs[i])
 | 
							msg := nl.DeserializeRtMsg(msgs[i])
 | 
				
			||||||
@@ -182,8 +221,11 @@ func (h *Handle) RuleList(family int) ([]Rule, error) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rule := NewRule()
 | 
							rule := NewRule()
 | 
				
			||||||
 | 
							rule.Priority = 0 // The default priority from kernel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rule.Invert = msg.Flags&FibRuleInvert > 0
 | 
							rule.Invert = msg.Flags&FibRuleInvert > 0
 | 
				
			||||||
 | 
							rule.Family = int(msg.Family)
 | 
				
			||||||
 | 
							rule.Tos = uint(msg.Tos)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for j := range attrs {
 | 
							for j := range attrs {
 | 
				
			||||||
			switch attrs[j].Attr.Type {
 | 
								switch attrs[j].Attr.Type {
 | 
				
			||||||
@@ -200,11 +242,12 @@ func (h *Handle) RuleList(family int) ([]Rule, error) {
 | 
				
			|||||||
					Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attrs[j].Value)),
 | 
										Mask: net.CIDRMask(int(msg.Dst_len), 8*len(attrs[j].Value)),
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			case nl.FRA_FWMARK:
 | 
								case nl.FRA_FWMARK:
 | 
				
			||||||
				rule.Mark = int(native.Uint32(attrs[j].Value[0:4]))
 | 
									rule.Mark = native.Uint32(attrs[j].Value[0:4])
 | 
				
			||||||
			case nl.FRA_FWMASK:
 | 
								case nl.FRA_FWMASK:
 | 
				
			||||||
				rule.Mask = int(native.Uint32(attrs[j].Value[0:4]))
 | 
									mask := native.Uint32(attrs[j].Value[0:4])
 | 
				
			||||||
 | 
									rule.Mask = &mask
 | 
				
			||||||
			case nl.FRA_TUN_ID:
 | 
								case nl.FRA_TUN_ID:
 | 
				
			||||||
				rule.TunID = uint(native.Uint64(attrs[j].Value[0:4]))
 | 
									rule.TunID = uint(native.Uint64(attrs[j].Value[0:8]))
 | 
				
			||||||
			case nl.FRA_IIFNAME:
 | 
								case nl.FRA_IIFNAME:
 | 
				
			||||||
				rule.IifName = string(attrs[j].Value[:len(attrs[j].Value)-1])
 | 
									rule.IifName = string(attrs[j].Value[:len(attrs[j].Value)-1])
 | 
				
			||||||
			case nl.FRA_OIFNAME:
 | 
								case nl.FRA_OIFNAME:
 | 
				
			||||||
@@ -225,10 +268,98 @@ func (h *Handle) RuleList(family int) ([]Rule, error) {
 | 
				
			|||||||
				rule.Goto = int(native.Uint32(attrs[j].Value[0:4]))
 | 
									rule.Goto = int(native.Uint32(attrs[j].Value[0:4]))
 | 
				
			||||||
			case nl.FRA_PRIORITY:
 | 
								case nl.FRA_PRIORITY:
 | 
				
			||||||
				rule.Priority = int(native.Uint32(attrs[j].Value[0:4]))
 | 
									rule.Priority = int(native.Uint32(attrs[j].Value[0:4]))
 | 
				
			||||||
 | 
								case nl.FRA_IP_PROTO:
 | 
				
			||||||
 | 
									rule.IPProto = int(native.Uint32(attrs[j].Value[0:4]))
 | 
				
			||||||
 | 
								case nl.FRA_DPORT_RANGE:
 | 
				
			||||||
 | 
									rule.Dport = NewRulePortRange(native.Uint16(attrs[j].Value[0:2]), native.Uint16(attrs[j].Value[2:4]))
 | 
				
			||||||
 | 
								case nl.FRA_SPORT_RANGE:
 | 
				
			||||||
 | 
									rule.Sport = NewRulePortRange(native.Uint16(attrs[j].Value[0:2]), native.Uint16(attrs[j].Value[2:4]))
 | 
				
			||||||
 | 
								case nl.FRA_UID_RANGE:
 | 
				
			||||||
 | 
									rule.UIDRange = NewRuleUIDRange(native.Uint32(attrs[j].Value[0:4]), native.Uint32(attrs[j].Value[4:8]))
 | 
				
			||||||
 | 
								case nl.FRA_PROTOCOL:
 | 
				
			||||||
 | 
									rule.Protocol = uint8(attrs[j].Value[0])
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if filter != nil {
 | 
				
			||||||
 | 
								switch {
 | 
				
			||||||
 | 
								case filterMask&RT_FILTER_SRC != 0 &&
 | 
				
			||||||
 | 
									(rule.Src == nil || rule.Src.String() != filter.Src.String()):
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								case filterMask&RT_FILTER_DST != 0 &&
 | 
				
			||||||
 | 
									(rule.Dst == nil || rule.Dst.String() != filter.Dst.String()):
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								case filterMask&RT_FILTER_TABLE != 0 &&
 | 
				
			||||||
 | 
									filter.Table != unix.RT_TABLE_UNSPEC && rule.Table != filter.Table:
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								case filterMask&RT_FILTER_TOS != 0 && rule.Tos != filter.Tos:
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								case filterMask&RT_FILTER_PRIORITY != 0 && rule.Priority != filter.Priority:
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								case filterMask&RT_FILTER_MARK != 0 && rule.Mark != filter.Mark:
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								case filterMask&RT_FILTER_MASK != 0 && !ptrEqual(rule.Mask, filter.Mask):
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		res = append(res, *rule)
 | 
							res = append(res, *rule)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return res, nil
 | 
						return res, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (pr *RulePortRange) toRtAttrData() []byte {
 | 
				
			||||||
 | 
						b := [][]byte{make([]byte, 2), make([]byte, 2)}
 | 
				
			||||||
 | 
						native.PutUint16(b[0], pr.Start)
 | 
				
			||||||
 | 
						native.PutUint16(b[1], pr.End)
 | 
				
			||||||
 | 
						return bytes.Join(b, []byte{})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (pr *RuleUIDRange) toRtAttrData() []byte {
 | 
				
			||||||
 | 
						b := [][]byte{make([]byte, 4), make([]byte, 4)}
 | 
				
			||||||
 | 
						native.PutUint32(b[0], pr.Start)
 | 
				
			||||||
 | 
						native.PutUint32(b[1], pr.End)
 | 
				
			||||||
 | 
						return bytes.Join(b, []byte{})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ptrEqual(a, b *uint32) bool {
 | 
				
			||||||
 | 
						if a == b {
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (a == nil) || (b == nil) {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return *a == *b
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r Rule) typeString() string {
 | 
				
			||||||
 | 
						switch r.Type {
 | 
				
			||||||
 | 
						case unix.RTN_UNSPEC: // zero
 | 
				
			||||||
 | 
							return ""
 | 
				
			||||||
 | 
						case unix.RTN_UNICAST:
 | 
				
			||||||
 | 
							return ""
 | 
				
			||||||
 | 
						case unix.RTN_LOCAL:
 | 
				
			||||||
 | 
							return "local"
 | 
				
			||||||
 | 
						case unix.RTN_BROADCAST:
 | 
				
			||||||
 | 
							return "broadcast"
 | 
				
			||||||
 | 
						case unix.RTN_ANYCAST:
 | 
				
			||||||
 | 
							return "anycast"
 | 
				
			||||||
 | 
						case unix.RTN_MULTICAST:
 | 
				
			||||||
 | 
							return "multicast"
 | 
				
			||||||
 | 
						case unix.RTN_BLACKHOLE:
 | 
				
			||||||
 | 
							return "blackhole"
 | 
				
			||||||
 | 
						case unix.RTN_UNREACHABLE:
 | 
				
			||||||
 | 
							return "unreachable"
 | 
				
			||||||
 | 
						case unix.RTN_PROHIBIT:
 | 
				
			||||||
 | 
							return "prohibit"
 | 
				
			||||||
 | 
						case unix.RTN_THROW:
 | 
				
			||||||
 | 
							return "throw"
 | 
				
			||||||
 | 
						case unix.RTN_NAT:
 | 
				
			||||||
 | 
							return "nat"
 | 
				
			||||||
 | 
						case unix.RTN_XRESOLVE:
 | 
				
			||||||
 | 
							return "xresolve"
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return fmt.Sprintf("type(0x%x)", r.Type)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										8
									
								
								vendor/github.com/vishvananda/netlink/rule_nonlinux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/vishvananda/netlink/rule_nonlinux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					//go:build !linux
 | 
				
			||||||
 | 
					// +build !linux
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package netlink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r Rule) typeString() string {
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										77
									
								
								vendor/github.com/vishvananda/netlink/socket.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										77
									
								
								vendor/github.com/vishvananda/netlink/socket.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -25,3 +25,80 @@ type Socket struct {
 | 
				
			|||||||
	UID     uint32
 | 
						UID     uint32
 | 
				
			||||||
	INode   uint32
 | 
						INode   uint32
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// UnixSocket represents a netlink unix socket.
 | 
				
			||||||
 | 
					type UnixSocket struct {
 | 
				
			||||||
 | 
						Type   uint8
 | 
				
			||||||
 | 
						Family uint8
 | 
				
			||||||
 | 
						State  uint8
 | 
				
			||||||
 | 
						pad    uint8
 | 
				
			||||||
 | 
						INode  uint32
 | 
				
			||||||
 | 
						Cookie [2]uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// XDPSocket represents an XDP socket (and the common diagnosis part in
 | 
				
			||||||
 | 
					// particular). Please note that in contrast to [UnixSocket] the XDPSocket type
 | 
				
			||||||
 | 
					// does not feature “State” information.
 | 
				
			||||||
 | 
					type XDPSocket struct {
 | 
				
			||||||
 | 
						// xdp_diag_msg
 | 
				
			||||||
 | 
						// https://elixir.bootlin.com/linux/v6.2/source/include/uapi/linux/xdp_diag.h#L21
 | 
				
			||||||
 | 
						Family uint8
 | 
				
			||||||
 | 
						Type   uint8
 | 
				
			||||||
 | 
						pad    uint16
 | 
				
			||||||
 | 
						Ino    uint32
 | 
				
			||||||
 | 
						Cookie [2]uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type XDPInfo struct {
 | 
				
			||||||
 | 
						// XDP_DIAG_INFO/xdp_diag_info
 | 
				
			||||||
 | 
						// https://elixir.bootlin.com/linux/v6.2/source/include/uapi/linux/xdp_diag.h#L51
 | 
				
			||||||
 | 
						Ifindex uint32
 | 
				
			||||||
 | 
						QueueID uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// XDP_DIAG_UID
 | 
				
			||||||
 | 
						UID uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// XDP_RX_RING
 | 
				
			||||||
 | 
						// https://elixir.bootlin.com/linux/v6.2/source/include/uapi/linux/xdp_diag.h#L56
 | 
				
			||||||
 | 
						RxRingEntries             uint32
 | 
				
			||||||
 | 
						TxRingEntries             uint32
 | 
				
			||||||
 | 
						UmemFillRingEntries       uint32
 | 
				
			||||||
 | 
						UmemCompletionRingEntries uint32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// XDR_DIAG_UMEM
 | 
				
			||||||
 | 
						Umem *XDPDiagUmem
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// XDR_DIAG_STATS
 | 
				
			||||||
 | 
						Stats *XDPDiagStats
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						XDP_DU_F_ZEROCOPY = 1 << iota
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// XDPDiagUmem describes the umem attached to an XDP socket.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// https://elixir.bootlin.com/linux/v6.2/source/include/uapi/linux/xdp_diag.h#L62
 | 
				
			||||||
 | 
					type XDPDiagUmem struct {
 | 
				
			||||||
 | 
						Size      uint64
 | 
				
			||||||
 | 
						ID        uint32
 | 
				
			||||||
 | 
						NumPages  uint32
 | 
				
			||||||
 | 
						ChunkSize uint32
 | 
				
			||||||
 | 
						Headroom  uint32
 | 
				
			||||||
 | 
						Ifindex   uint32
 | 
				
			||||||
 | 
						QueueID   uint32
 | 
				
			||||||
 | 
						Flags     uint32
 | 
				
			||||||
 | 
						Refs      uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// XDPDiagStats contains ring statistics for an XDP socket.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// https://elixir.bootlin.com/linux/v6.2/source/include/uapi/linux/xdp_diag.h#L74
 | 
				
			||||||
 | 
					type XDPDiagStats struct {
 | 
				
			||||||
 | 
						RxDropped     uint64
 | 
				
			||||||
 | 
						RxInvalid     uint64
 | 
				
			||||||
 | 
						RxFull        uint64
 | 
				
			||||||
 | 
						FillRingEmpty uint64
 | 
				
			||||||
 | 
						TxInvalid     uint64
 | 
				
			||||||
 | 
						TxRingEmpty   uint64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										476
									
								
								vendor/github.com/vishvananda/netlink/socket_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										476
									
								
								vendor/github.com/vishvananda/netlink/socket_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -4,6 +4,7 @@ import (
 | 
				
			|||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
 | 
						"syscall"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/vishvananda/netlink/nl"
 | 
						"github.com/vishvananda/netlink/nl"
 | 
				
			||||||
	"golang.org/x/sys/unix"
 | 
						"golang.org/x/sys/unix"
 | 
				
			||||||
@@ -13,6 +14,8 @@ const (
 | 
				
			|||||||
	sizeofSocketID          = 0x30
 | 
						sizeofSocketID          = 0x30
 | 
				
			||||||
	sizeofSocketRequest     = sizeofSocketID + 0x8
 | 
						sizeofSocketRequest     = sizeofSocketID + 0x8
 | 
				
			||||||
	sizeofSocket            = sizeofSocketID + 0x18
 | 
						sizeofSocket            = sizeofSocketID + 0x18
 | 
				
			||||||
 | 
						sizeofUnixSocketRequest = 0x18 // 24 byte
 | 
				
			||||||
 | 
						sizeofUnixSocket        = 0x10 // 16 byte
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type socketRequest struct {
 | 
					type socketRequest struct {
 | 
				
			||||||
@@ -49,10 +52,13 @@ func (r *socketRequest) Serialize() []byte {
 | 
				
			|||||||
	native.PutUint32(b.Next(4), r.States)
 | 
						native.PutUint32(b.Next(4), r.States)
 | 
				
			||||||
	networkOrder.PutUint16(b.Next(2), r.ID.SourcePort)
 | 
						networkOrder.PutUint16(b.Next(2), r.ID.SourcePort)
 | 
				
			||||||
	networkOrder.PutUint16(b.Next(2), r.ID.DestinationPort)
 | 
						networkOrder.PutUint16(b.Next(2), r.ID.DestinationPort)
 | 
				
			||||||
	copy(b.Next(4), r.ID.Source.To4())
 | 
						if r.Family == unix.AF_INET6 {
 | 
				
			||||||
	b.Next(12)
 | 
							copy(b.Next(16), r.ID.Source)
 | 
				
			||||||
	copy(b.Next(4), r.ID.Destination.To4())
 | 
							copy(b.Next(16), r.ID.Destination)
 | 
				
			||||||
	b.Next(12)
 | 
						} else {
 | 
				
			||||||
 | 
							copy(b.Next(16), r.ID.Source.To4())
 | 
				
			||||||
 | 
							copy(b.Next(16), r.ID.Destination.To4())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	native.PutUint32(b.Next(4), r.ID.Interface)
 | 
						native.PutUint32(b.Next(4), r.ID.Interface)
 | 
				
			||||||
	native.PutUint32(b.Next(4), r.ID.Cookie[0])
 | 
						native.PutUint32(b.Next(4), r.ID.Cookie[0])
 | 
				
			||||||
	native.PutUint32(b.Next(4), r.ID.Cookie[1])
 | 
						native.PutUint32(b.Next(4), r.ID.Cookie[1])
 | 
				
			||||||
@@ -61,6 +67,32 @@ func (r *socketRequest) Serialize() []byte {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (r *socketRequest) Len() int { return sizeofSocketRequest }
 | 
					func (r *socketRequest) Len() int { return sizeofSocketRequest }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// According to linux/include/uapi/linux/unix_diag.h
 | 
				
			||||||
 | 
					type unixSocketRequest struct {
 | 
				
			||||||
 | 
						Family   uint8
 | 
				
			||||||
 | 
						Protocol uint8
 | 
				
			||||||
 | 
						pad      uint16
 | 
				
			||||||
 | 
						States   uint32
 | 
				
			||||||
 | 
						INode    uint32
 | 
				
			||||||
 | 
						Show     uint32
 | 
				
			||||||
 | 
						Cookie   [2]uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r *unixSocketRequest) Serialize() []byte {
 | 
				
			||||||
 | 
						b := writeBuffer{Bytes: make([]byte, sizeofUnixSocketRequest)}
 | 
				
			||||||
 | 
						b.Write(r.Family)
 | 
				
			||||||
 | 
						b.Write(r.Protocol)
 | 
				
			||||||
 | 
						native.PutUint16(b.Next(2), r.pad)
 | 
				
			||||||
 | 
						native.PutUint32(b.Next(4), r.States)
 | 
				
			||||||
 | 
						native.PutUint32(b.Next(4), r.INode)
 | 
				
			||||||
 | 
						native.PutUint32(b.Next(4), r.Show)
 | 
				
			||||||
 | 
						native.PutUint32(b.Next(4), r.Cookie[0])
 | 
				
			||||||
 | 
						native.PutUint32(b.Next(4), r.Cookie[1])
 | 
				
			||||||
 | 
						return b.Bytes
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r *unixSocketRequest) Len() int { return sizeofUnixSocketRequest }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type readBuffer struct {
 | 
					type readBuffer struct {
 | 
				
			||||||
	Bytes []byte
 | 
						Bytes []byte
 | 
				
			||||||
	pos   int
 | 
						pos   int
 | 
				
			||||||
@@ -89,10 +121,15 @@ func (s *Socket) deserialize(b []byte) error {
 | 
				
			|||||||
	s.Retrans = rb.Read()
 | 
						s.Retrans = rb.Read()
 | 
				
			||||||
	s.ID.SourcePort = networkOrder.Uint16(rb.Next(2))
 | 
						s.ID.SourcePort = networkOrder.Uint16(rb.Next(2))
 | 
				
			||||||
	s.ID.DestinationPort = networkOrder.Uint16(rb.Next(2))
 | 
						s.ID.DestinationPort = networkOrder.Uint16(rb.Next(2))
 | 
				
			||||||
 | 
						if s.Family == unix.AF_INET6 {
 | 
				
			||||||
 | 
							s.ID.Source = net.IP(rb.Next(16))
 | 
				
			||||||
 | 
							s.ID.Destination = net.IP(rb.Next(16))
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
		s.ID.Source = net.IPv4(rb.Read(), rb.Read(), rb.Read(), rb.Read())
 | 
							s.ID.Source = net.IPv4(rb.Read(), rb.Read(), rb.Read(), rb.Read())
 | 
				
			||||||
		rb.Next(12)
 | 
							rb.Next(12)
 | 
				
			||||||
		s.ID.Destination = net.IPv4(rb.Read(), rb.Read(), rb.Read(), rb.Read())
 | 
							s.ID.Destination = net.IPv4(rb.Read(), rb.Read(), rb.Read(), rb.Read())
 | 
				
			||||||
		rb.Next(12)
 | 
							rb.Next(12)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	s.ID.Interface = native.Uint32(rb.Next(4))
 | 
						s.ID.Interface = native.Uint32(rb.Next(4))
 | 
				
			||||||
	s.ID.Cookie[0] = native.Uint32(rb.Next(4))
 | 
						s.ID.Cookie[0] = native.Uint32(rb.Next(4))
 | 
				
			||||||
	s.ID.Cookie[1] = native.Uint32(rb.Next(4))
 | 
						s.ID.Cookie[1] = native.Uint32(rb.Next(4))
 | 
				
			||||||
@@ -104,31 +141,126 @@ func (s *Socket) deserialize(b []byte) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (u *UnixSocket) deserialize(b []byte) error {
 | 
				
			||||||
 | 
						if len(b) < sizeofUnixSocket {
 | 
				
			||||||
 | 
							return fmt.Errorf("unix diag data short read (%d); want %d", len(b), sizeofUnixSocket)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						rb := readBuffer{Bytes: b}
 | 
				
			||||||
 | 
						u.Type = rb.Read()
 | 
				
			||||||
 | 
						u.Family = rb.Read()
 | 
				
			||||||
 | 
						u.State = rb.Read()
 | 
				
			||||||
 | 
						u.pad = rb.Read()
 | 
				
			||||||
 | 
						u.INode = native.Uint32(rb.Next(4))
 | 
				
			||||||
 | 
						u.Cookie[0] = native.Uint32(rb.Next(4))
 | 
				
			||||||
 | 
						u.Cookie[1] = native.Uint32(rb.Next(4))
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SocketGet returns the Socket identified by its local and remote addresses.
 | 
					// SocketGet returns the Socket identified by its local and remote addresses.
 | 
				
			||||||
func SocketGet(local, remote net.Addr) (*Socket, error) {
 | 
					func (h *Handle) SocketGet(local, remote net.Addr) (*Socket, error) {
 | 
				
			||||||
	localTCP, ok := local.(*net.TCPAddr)
 | 
						var protocol uint8
 | 
				
			||||||
 | 
						var localIP, remoteIP net.IP
 | 
				
			||||||
 | 
						var localPort, remotePort uint16
 | 
				
			||||||
 | 
						switch l := local.(type) {
 | 
				
			||||||
 | 
						case *net.TCPAddr:
 | 
				
			||||||
 | 
							r, ok := remote.(*net.TCPAddr)
 | 
				
			||||||
		if !ok {
 | 
							if !ok {
 | 
				
			||||||
			return nil, ErrNotImplemented
 | 
								return nil, ErrNotImplemented
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							localIP = l.IP
 | 
				
			||||||
 | 
							localPort = uint16(l.Port)
 | 
				
			||||||
 | 
							remoteIP = r.IP
 | 
				
			||||||
 | 
							remotePort = uint16(r.Port)
 | 
				
			||||||
 | 
							protocol = unix.IPPROTO_TCP
 | 
				
			||||||
 | 
						case *net.UDPAddr:
 | 
				
			||||||
 | 
							r, ok := remote.(*net.UDPAddr)
 | 
				
			||||||
 | 
							if !ok {
 | 
				
			||||||
 | 
								return nil, ErrNotImplemented
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							localIP = l.IP
 | 
				
			||||||
 | 
							localPort = uint16(l.Port)
 | 
				
			||||||
 | 
							remoteIP = r.IP
 | 
				
			||||||
 | 
							remotePort = uint16(r.Port)
 | 
				
			||||||
 | 
							protocol = unix.IPPROTO_UDP
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return nil, ErrNotImplemented
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var family uint8
 | 
				
			||||||
 | 
						if localIP.To4() != nil && remoteIP.To4() != nil {
 | 
				
			||||||
 | 
							family = unix.AF_INET
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if family == 0 && localIP.To16() != nil && remoteIP.To16() != nil {
 | 
				
			||||||
 | 
							family = unix.AF_INET6
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if family == 0 {
 | 
				
			||||||
 | 
							return nil, ErrNotImplemented
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						req := h.newNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, unix.NLM_F_DUMP)
 | 
				
			||||||
 | 
						req.AddData(&socketRequest{
 | 
				
			||||||
 | 
							Family:   family,
 | 
				
			||||||
 | 
							Protocol: protocol,
 | 
				
			||||||
 | 
							States:   0xffffffff,
 | 
				
			||||||
 | 
							ID: SocketID{
 | 
				
			||||||
 | 
								SourcePort:      localPort,
 | 
				
			||||||
 | 
								DestinationPort: remotePort,
 | 
				
			||||||
 | 
								Source:          localIP,
 | 
				
			||||||
 | 
								Destination:     remoteIP,
 | 
				
			||||||
 | 
								Cookie:          [2]uint32{nl.TCPDIAG_NOCOOKIE, nl.TCPDIAG_NOCOOKIE},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						msgs, err := req.Execute(unix.NETLINK_INET_DIAG, nl.SOCK_DIAG_BY_FAMILY)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(msgs) == 0 {
 | 
				
			||||||
 | 
							return nil, errors.New("no message nor error from netlink")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(msgs) > 2 {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("multiple (%d) matching sockets", len(msgs))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sock := &Socket{}
 | 
				
			||||||
 | 
						if err := sock.deserialize(msgs[0]); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return sock, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SocketGet returns the Socket identified by its local and remote addresses.
 | 
				
			||||||
 | 
					func SocketGet(local, remote net.Addr) (*Socket, error) {
 | 
				
			||||||
 | 
						return pkgHandle.SocketGet(local, remote)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SocketDestroy kills the Socket identified by its local and remote addresses.
 | 
				
			||||||
 | 
					func (h *Handle) SocketDestroy(local, remote net.Addr) error {
 | 
				
			||||||
 | 
						localTCP, ok := local.(*net.TCPAddr)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return ErrNotImplemented
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	remoteTCP, ok := remote.(*net.TCPAddr)
 | 
						remoteTCP, ok := remote.(*net.TCPAddr)
 | 
				
			||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return nil, ErrNotImplemented
 | 
							return ErrNotImplemented
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	localIP := localTCP.IP.To4()
 | 
						localIP := localTCP.IP.To4()
 | 
				
			||||||
	if localIP == nil {
 | 
						if localIP == nil {
 | 
				
			||||||
		return nil, ErrNotImplemented
 | 
							return ErrNotImplemented
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	remoteIP := remoteTCP.IP.To4()
 | 
						remoteIP := remoteTCP.IP.To4()
 | 
				
			||||||
	if remoteIP == nil {
 | 
						if remoteIP == nil {
 | 
				
			||||||
		return nil, ErrNotImplemented
 | 
							return ErrNotImplemented
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	s, err := nl.Subscribe(unix.NETLINK_INET_DIAG)
 | 
						s, err := nl.Subscribe(unix.NETLINK_INET_DIAG)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer s.Close()
 | 
						defer s.Close()
 | 
				
			||||||
	req := nl.NewNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, 0)
 | 
						req := h.newNetlinkRequest(nl.SOCK_DESTROY, unix.NLM_F_ACK)
 | 
				
			||||||
	req.AddData(&socketRequest{
 | 
						req.AddData(&socketRequest{
 | 
				
			||||||
		Family:   unix.AF_INET,
 | 
							Family:   unix.AF_INET,
 | 
				
			||||||
		Protocol: unix.IPPROTO_TCP,
 | 
							Protocol: unix.IPPROTO_TCP,
 | 
				
			||||||
@@ -140,23 +272,319 @@ func SocketGet(local, remote net.Addr) (*Socket, error) {
 | 
				
			|||||||
			Cookie:          [2]uint32{nl.TCPDIAG_NOCOOKIE, nl.TCPDIAG_NOCOOKIE},
 | 
								Cookie:          [2]uint32{nl.TCPDIAG_NOCOOKIE, nl.TCPDIAG_NOCOOKIE},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	s.Send(req)
 | 
					
 | 
				
			||||||
	msgs, from, err := s.Receive()
 | 
						_, err = req.Execute(unix.NETLINK_INET_DIAG, 0)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SocketDestroy kills the Socket identified by its local and remote addresses.
 | 
				
			||||||
 | 
					func SocketDestroy(local, remote net.Addr) error {
 | 
				
			||||||
 | 
						return pkgHandle.SocketDestroy(local, remote)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SocketDiagTCPInfo requests INET_DIAG_INFO for TCP protocol for specified family type and return with extension TCP info.
 | 
				
			||||||
 | 
					func (h *Handle) SocketDiagTCPInfo(family uint8) ([]*InetDiagTCPInfoResp, error) {
 | 
				
			||||||
 | 
						// Construct the request
 | 
				
			||||||
 | 
						req := h.newNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, unix.NLM_F_DUMP)
 | 
				
			||||||
 | 
						req.AddData(&socketRequest{
 | 
				
			||||||
 | 
							Family:   family,
 | 
				
			||||||
 | 
							Protocol: unix.IPPROTO_TCP,
 | 
				
			||||||
 | 
							Ext:      (1 << (INET_DIAG_VEGASINFO - 1)) | (1 << (INET_DIAG_INFO - 1)),
 | 
				
			||||||
 | 
							States:   uint32(0xfff), // all states
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Do the query and parse the result
 | 
				
			||||||
 | 
						var result []*InetDiagTCPInfoResp
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						err = req.ExecuteIter(unix.NETLINK_INET_DIAG, nl.SOCK_DIAG_BY_FAMILY, func(msg []byte) bool {
 | 
				
			||||||
 | 
							sockInfo := &Socket{}
 | 
				
			||||||
 | 
							if err = sockInfo.deserialize(msg); err != nil {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							var attrs []syscall.NetlinkRouteAttr
 | 
				
			||||||
 | 
							if attrs, err = nl.ParseRouteAttr(msg[sizeofSocket:]); err != nil {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							var res *InetDiagTCPInfoResp
 | 
				
			||||||
 | 
							if res, err = attrsToInetDiagTCPInfoResp(attrs, sockInfo); err != nil {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							result = append(result, res)
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if from.Pid != nl.PidKernel {
 | 
						return result, nil
 | 
				
			||||||
		return nil, fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel)
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SocketDiagTCPInfo requests INET_DIAG_INFO for TCP protocol for specified family type and return with extension TCP info.
 | 
				
			||||||
 | 
					func SocketDiagTCPInfo(family uint8) ([]*InetDiagTCPInfoResp, error) {
 | 
				
			||||||
 | 
						return pkgHandle.SocketDiagTCPInfo(family)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SocketDiagTCP requests INET_DIAG_INFO for TCP protocol for specified family type and return related socket.
 | 
				
			||||||
 | 
					func (h *Handle) SocketDiagTCP(family uint8) ([]*Socket, error) {
 | 
				
			||||||
 | 
						// Construct the request
 | 
				
			||||||
 | 
						req := h.newNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, unix.NLM_F_DUMP)
 | 
				
			||||||
 | 
						req.AddData(&socketRequest{
 | 
				
			||||||
 | 
							Family:   family,
 | 
				
			||||||
 | 
							Protocol: unix.IPPROTO_TCP,
 | 
				
			||||||
 | 
							Ext:      (1 << (INET_DIAG_VEGASINFO - 1)) | (1 << (INET_DIAG_INFO - 1)),
 | 
				
			||||||
 | 
							States:   uint32(0xfff), // all states
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Do the query and parse the result
 | 
				
			||||||
 | 
						var result []*Socket
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						err = req.ExecuteIter(unix.NETLINK_INET_DIAG, nl.SOCK_DIAG_BY_FAMILY, func(msg []byte) bool {
 | 
				
			||||||
 | 
							sockInfo := &Socket{}
 | 
				
			||||||
 | 
							if err = sockInfo.deserialize(msg); err != nil {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	if len(msgs) == 0 {
 | 
							result = append(result, sockInfo)
 | 
				
			||||||
		return nil, errors.New("no message nor error from netlink")
 | 
							return true
 | 
				
			||||||
	}
 | 
						})
 | 
				
			||||||
	if len(msgs) > 2 {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, fmt.Errorf("multiple (%d) matching sockets", len(msgs))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	sock := &Socket{}
 | 
					 | 
				
			||||||
	if err := sock.deserialize(msgs[0].Data); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return sock, nil
 | 
						return result, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SocketDiagTCP requests INET_DIAG_INFO for TCP protocol for specified family type and return related socket.
 | 
				
			||||||
 | 
					func SocketDiagTCP(family uint8) ([]*Socket, error) {
 | 
				
			||||||
 | 
						return pkgHandle.SocketDiagTCP(family)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SocketDiagUDPInfo requests INET_DIAG_INFO for UDP protocol for specified family type and return with extension info.
 | 
				
			||||||
 | 
					func (h *Handle) SocketDiagUDPInfo(family uint8) ([]*InetDiagUDPInfoResp, error) {
 | 
				
			||||||
 | 
						// Construct the request
 | 
				
			||||||
 | 
						var extensions uint8
 | 
				
			||||||
 | 
						extensions = 1 << (INET_DIAG_VEGASINFO - 1)
 | 
				
			||||||
 | 
						extensions |= 1 << (INET_DIAG_INFO - 1)
 | 
				
			||||||
 | 
						extensions |= 1 << (INET_DIAG_MEMINFO - 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						req := h.newNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, unix.NLM_F_DUMP)
 | 
				
			||||||
 | 
						req.AddData(&socketRequest{
 | 
				
			||||||
 | 
							Family:   family,
 | 
				
			||||||
 | 
							Protocol: unix.IPPROTO_UDP,
 | 
				
			||||||
 | 
							Ext:      extensions,
 | 
				
			||||||
 | 
							States:   uint32(0xfff), // all states
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Do the query and parse the result
 | 
				
			||||||
 | 
						var result []*InetDiagUDPInfoResp
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						err = req.ExecuteIter(unix.NETLINK_INET_DIAG, nl.SOCK_DIAG_BY_FAMILY, func(msg []byte) bool {
 | 
				
			||||||
 | 
							sockInfo := &Socket{}
 | 
				
			||||||
 | 
							if err = sockInfo.deserialize(msg); err != nil {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							var attrs []syscall.NetlinkRouteAttr
 | 
				
			||||||
 | 
							if attrs, err = nl.ParseRouteAttr(msg[sizeofSocket:]); err != nil {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							var res *InetDiagUDPInfoResp
 | 
				
			||||||
 | 
							if res, err = attrsToInetDiagUDPInfoResp(attrs, sockInfo); err != nil {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							result = append(result, res)
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return result, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SocketDiagUDPInfo requests INET_DIAG_INFO for UDP protocol for specified family type and return with extension info.
 | 
				
			||||||
 | 
					func SocketDiagUDPInfo(family uint8) ([]*InetDiagUDPInfoResp, error) {
 | 
				
			||||||
 | 
						return pkgHandle.SocketDiagUDPInfo(family)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SocketDiagUDP requests INET_DIAG_INFO for UDP protocol for specified family type and return related socket.
 | 
				
			||||||
 | 
					func (h *Handle) SocketDiagUDP(family uint8) ([]*Socket, error) {
 | 
				
			||||||
 | 
						// Construct the request
 | 
				
			||||||
 | 
						req := h.newNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, unix.NLM_F_DUMP)
 | 
				
			||||||
 | 
						req.AddData(&socketRequest{
 | 
				
			||||||
 | 
							Family:   family,
 | 
				
			||||||
 | 
							Protocol: unix.IPPROTO_UDP,
 | 
				
			||||||
 | 
							Ext:      (1 << (INET_DIAG_VEGASINFO - 1)) | (1 << (INET_DIAG_INFO - 1)),
 | 
				
			||||||
 | 
							States:   uint32(0xfff), // all states
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Do the query and parse the result
 | 
				
			||||||
 | 
						var result []*Socket
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						err = req.ExecuteIter(unix.NETLINK_INET_DIAG, nl.SOCK_DIAG_BY_FAMILY, func(msg []byte) bool {
 | 
				
			||||||
 | 
							sockInfo := &Socket{}
 | 
				
			||||||
 | 
							if err = sockInfo.deserialize(msg); err != nil {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							result = append(result, sockInfo)
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return result, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SocketDiagUDP requests INET_DIAG_INFO for UDP protocol for specified family type and return related socket.
 | 
				
			||||||
 | 
					func SocketDiagUDP(family uint8) ([]*Socket, error) {
 | 
				
			||||||
 | 
						return pkgHandle.SocketDiagUDP(family)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// UnixSocketDiagInfo requests UNIX_DIAG_INFO for unix sockets and return with extension info.
 | 
				
			||||||
 | 
					func (h *Handle) UnixSocketDiagInfo() ([]*UnixDiagInfoResp, error) {
 | 
				
			||||||
 | 
						// Construct the request
 | 
				
			||||||
 | 
						var extensions uint8
 | 
				
			||||||
 | 
						extensions = 1 << UNIX_DIAG_NAME
 | 
				
			||||||
 | 
						extensions |= 1 << UNIX_DIAG_PEER
 | 
				
			||||||
 | 
						extensions |= 1 << UNIX_DIAG_RQLEN
 | 
				
			||||||
 | 
						req := h.newNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, unix.NLM_F_DUMP)
 | 
				
			||||||
 | 
						req.AddData(&unixSocketRequest{
 | 
				
			||||||
 | 
							Family: unix.AF_UNIX,
 | 
				
			||||||
 | 
							States: ^uint32(0), // all states
 | 
				
			||||||
 | 
							Show:   uint32(extensions),
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var result []*UnixDiagInfoResp
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						err = req.ExecuteIter(unix.NETLINK_INET_DIAG, nl.SOCK_DIAG_BY_FAMILY, func(msg []byte) bool {
 | 
				
			||||||
 | 
							sockInfo := &UnixSocket{}
 | 
				
			||||||
 | 
							if err = sockInfo.deserialize(msg); err != nil {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Diagnosis also delivers sockets with AF_INET family, filter those
 | 
				
			||||||
 | 
							if sockInfo.Family != unix.AF_UNIX {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							var attrs []syscall.NetlinkRouteAttr
 | 
				
			||||||
 | 
							if attrs, err = nl.ParseRouteAttr(msg[sizeofSocket:]); err != nil {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							var res *UnixDiagInfoResp
 | 
				
			||||||
 | 
							if res, err = attrsToUnixDiagInfoResp(attrs, sockInfo); err != nil {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							result = append(result, res)
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return result, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// UnixSocketDiagInfo requests UNIX_DIAG_INFO for unix sockets and return with extension info.
 | 
				
			||||||
 | 
					func UnixSocketDiagInfo() ([]*UnixDiagInfoResp, error) {
 | 
				
			||||||
 | 
						return pkgHandle.UnixSocketDiagInfo()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// UnixSocketDiag requests UNIX_DIAG_INFO for unix sockets.
 | 
				
			||||||
 | 
					func (h *Handle) UnixSocketDiag() ([]*UnixSocket, error) {
 | 
				
			||||||
 | 
						// Construct the request
 | 
				
			||||||
 | 
						req := h.newNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, unix.NLM_F_DUMP)
 | 
				
			||||||
 | 
						req.AddData(&unixSocketRequest{
 | 
				
			||||||
 | 
							Family: unix.AF_UNIX,
 | 
				
			||||||
 | 
							States: ^uint32(0), // all states
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var result []*UnixSocket
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						err = req.ExecuteIter(unix.NETLINK_INET_DIAG, nl.SOCK_DIAG_BY_FAMILY, func(msg []byte) bool {
 | 
				
			||||||
 | 
							sockInfo := &UnixSocket{}
 | 
				
			||||||
 | 
							if err = sockInfo.deserialize(msg); err != nil {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Diagnosis also delivers sockets with AF_INET family, filter those
 | 
				
			||||||
 | 
							if sockInfo.Family == unix.AF_UNIX {
 | 
				
			||||||
 | 
								result = append(result, sockInfo)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return result, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// UnixSocketDiag requests UNIX_DIAG_INFO for unix sockets.
 | 
				
			||||||
 | 
					func UnixSocketDiag() ([]*UnixSocket, error) {
 | 
				
			||||||
 | 
						return pkgHandle.UnixSocketDiag()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func attrsToInetDiagTCPInfoResp(attrs []syscall.NetlinkRouteAttr, sockInfo *Socket) (*InetDiagTCPInfoResp, error) {
 | 
				
			||||||
 | 
						info := &InetDiagTCPInfoResp{
 | 
				
			||||||
 | 
							InetDiagMsg: sockInfo,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, a := range attrs {
 | 
				
			||||||
 | 
							switch a.Attr.Type {
 | 
				
			||||||
 | 
							case INET_DIAG_INFO:
 | 
				
			||||||
 | 
								info.TCPInfo = &TCPInfo{}
 | 
				
			||||||
 | 
								if err := info.TCPInfo.deserialize(a.Value); err != nil {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							case INET_DIAG_BBRINFO:
 | 
				
			||||||
 | 
								info.TCPBBRInfo = &TCPBBRInfo{}
 | 
				
			||||||
 | 
								if err := info.TCPBBRInfo.deserialize(a.Value); err != nil {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return info, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func attrsToInetDiagUDPInfoResp(attrs []syscall.NetlinkRouteAttr, sockInfo *Socket) (*InetDiagUDPInfoResp, error) {
 | 
				
			||||||
 | 
						info := &InetDiagUDPInfoResp{
 | 
				
			||||||
 | 
							InetDiagMsg: sockInfo,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, a := range attrs {
 | 
				
			||||||
 | 
							switch a.Attr.Type {
 | 
				
			||||||
 | 
							case INET_DIAG_MEMINFO:
 | 
				
			||||||
 | 
								info.Memory = &MemInfo{}
 | 
				
			||||||
 | 
								if err := info.Memory.deserialize(a.Value); err != nil {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return info, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func attrsToUnixDiagInfoResp(attrs []syscall.NetlinkRouteAttr, sockInfo *UnixSocket) (*UnixDiagInfoResp, error) {
 | 
				
			||||||
 | 
						info := &UnixDiagInfoResp{
 | 
				
			||||||
 | 
							DiagMsg: sockInfo,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, a := range attrs {
 | 
				
			||||||
 | 
							switch a.Attr.Type {
 | 
				
			||||||
 | 
							case UNIX_DIAG_NAME:
 | 
				
			||||||
 | 
								name := string(a.Value[:a.Attr.Len])
 | 
				
			||||||
 | 
								info.Name = &name
 | 
				
			||||||
 | 
							case UNIX_DIAG_PEER:
 | 
				
			||||||
 | 
								peer := native.Uint32(a.Value)
 | 
				
			||||||
 | 
								info.Peer = &peer
 | 
				
			||||||
 | 
							case UNIX_DIAG_RQLEN:
 | 
				
			||||||
 | 
								info.Queue = &QueueInfo{
 | 
				
			||||||
 | 
									RQueue: native.Uint32(a.Value[:4]),
 | 
				
			||||||
 | 
									WQueue: native.Uint32(a.Value[4:]),
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								// default:
 | 
				
			||||||
 | 
								// 	fmt.Println("unknown unix attribute type", a.Attr.Type, "with data", a.Value)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return info, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										195
									
								
								vendor/github.com/vishvananda/netlink/socket_xdp_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										195
									
								
								vendor/github.com/vishvananda/netlink/socket_xdp_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,195 @@
 | 
				
			|||||||
 | 
					package netlink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"syscall"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/vishvananda/netlink/nl"
 | 
				
			||||||
 | 
						"golang.org/x/sys/unix"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						sizeofXDPSocketRequest = 1 + 1 + 2 + 4 + 4 + 2*4
 | 
				
			||||||
 | 
						sizeofXDPSocket        = 0x10
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// https://elixir.bootlin.com/linux/v6.2/source/include/uapi/linux/xdp_diag.h#L12
 | 
				
			||||||
 | 
					type xdpSocketRequest struct {
 | 
				
			||||||
 | 
						Family   uint8
 | 
				
			||||||
 | 
						Protocol uint8
 | 
				
			||||||
 | 
						pad      uint16
 | 
				
			||||||
 | 
						Ino      uint32
 | 
				
			||||||
 | 
						Show     uint32
 | 
				
			||||||
 | 
						Cookie   [2]uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r *xdpSocketRequest) Serialize() []byte {
 | 
				
			||||||
 | 
						b := writeBuffer{Bytes: make([]byte, sizeofSocketRequest)}
 | 
				
			||||||
 | 
						b.Write(r.Family)
 | 
				
			||||||
 | 
						b.Write(r.Protocol)
 | 
				
			||||||
 | 
						native.PutUint16(b.Next(2), r.pad)
 | 
				
			||||||
 | 
						native.PutUint32(b.Next(4), r.Ino)
 | 
				
			||||||
 | 
						native.PutUint32(b.Next(4), r.Show)
 | 
				
			||||||
 | 
						native.PutUint32(b.Next(4), r.Cookie[0])
 | 
				
			||||||
 | 
						native.PutUint32(b.Next(4), r.Cookie[1])
 | 
				
			||||||
 | 
						return b.Bytes
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r *xdpSocketRequest) Len() int { return sizeofXDPSocketRequest }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *XDPSocket) deserialize(b []byte) error {
 | 
				
			||||||
 | 
						if len(b) < sizeofXDPSocket {
 | 
				
			||||||
 | 
							return fmt.Errorf("XDP socket data short read (%d); want %d", len(b), sizeofXDPSocket)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						rb := readBuffer{Bytes: b}
 | 
				
			||||||
 | 
						s.Family = rb.Read()
 | 
				
			||||||
 | 
						s.Type = rb.Read()
 | 
				
			||||||
 | 
						s.pad = native.Uint16(rb.Next(2))
 | 
				
			||||||
 | 
						s.Ino = native.Uint32(rb.Next(4))
 | 
				
			||||||
 | 
						s.Cookie[0] = native.Uint32(rb.Next(4))
 | 
				
			||||||
 | 
						s.Cookie[1] = native.Uint32(rb.Next(4))
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// XDPSocketGet returns the XDP socket identified by its inode number and/or
 | 
				
			||||||
 | 
					// socket cookie. Specify the cookie as SOCK_ANY_COOKIE if
 | 
				
			||||||
 | 
					func SocketXDPGetInfo(ino uint32, cookie uint64) (*XDPDiagInfoResp, error) {
 | 
				
			||||||
 | 
						// We have a problem here: dumping AF_XDP sockets currently does not support
 | 
				
			||||||
 | 
						// filtering. We thus need to dump all XSKs and then only filter afterwards
 | 
				
			||||||
 | 
						// :(
 | 
				
			||||||
 | 
						xsks, err := SocketDiagXDP()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						checkCookie := cookie != SOCK_ANY_COOKIE && cookie != 0
 | 
				
			||||||
 | 
						crumblingCookie := [2]uint32{uint32(cookie), uint32(cookie >> 32)}
 | 
				
			||||||
 | 
						checkIno := ino != 0
 | 
				
			||||||
 | 
						var xskinfo *XDPDiagInfoResp
 | 
				
			||||||
 | 
						for _, xsk := range xsks {
 | 
				
			||||||
 | 
							if checkIno && xsk.XDPDiagMsg.Ino != ino {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if checkCookie && xsk.XDPDiagMsg.Cookie != crumblingCookie {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if xskinfo != nil {
 | 
				
			||||||
 | 
								return nil, errors.New("multiple matching XDP sockets")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							xskinfo = xsk
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if xskinfo == nil {
 | 
				
			||||||
 | 
							return nil, errors.New("no matching XDP socket")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return xskinfo, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SocketDiagXDP requests XDP_DIAG_INFO for XDP family sockets.
 | 
				
			||||||
 | 
					func SocketDiagXDP() ([]*XDPDiagInfoResp, error) {
 | 
				
			||||||
 | 
						var result []*XDPDiagInfoResp
 | 
				
			||||||
 | 
						err := socketDiagXDPExecutor(func(m syscall.NetlinkMessage) error {
 | 
				
			||||||
 | 
							sockInfo := &XDPSocket{}
 | 
				
			||||||
 | 
							if err := sockInfo.deserialize(m.Data); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							attrs, err := nl.ParseRouteAttr(m.Data[sizeofXDPSocket:])
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							res, err := attrsToXDPDiagInfoResp(attrs, sockInfo)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							result = append(result, res)
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return result, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// socketDiagXDPExecutor requests XDP_DIAG_INFO for XDP family sockets.
 | 
				
			||||||
 | 
					func socketDiagXDPExecutor(receiver func(syscall.NetlinkMessage) error) error {
 | 
				
			||||||
 | 
						s, err := nl.Subscribe(unix.NETLINK_INET_DIAG)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer s.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						req := nl.NewNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, unix.NLM_F_DUMP)
 | 
				
			||||||
 | 
						req.AddData(&xdpSocketRequest{
 | 
				
			||||||
 | 
							Family: unix.AF_XDP,
 | 
				
			||||||
 | 
							Show:   XDP_SHOW_INFO | XDP_SHOW_RING_CFG | XDP_SHOW_UMEM | XDP_SHOW_STATS,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err := s.Send(req); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					loop:
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
 | 
							msgs, from, err := s.Receive()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if from.Pid != nl.PidKernel {
 | 
				
			||||||
 | 
								return fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if len(msgs) == 0 {
 | 
				
			||||||
 | 
								return errors.New("no message nor error from netlink")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for _, m := range msgs {
 | 
				
			||||||
 | 
								switch m.Header.Type {
 | 
				
			||||||
 | 
								case unix.NLMSG_DONE:
 | 
				
			||||||
 | 
									break loop
 | 
				
			||||||
 | 
								case unix.NLMSG_ERROR:
 | 
				
			||||||
 | 
									error := int32(native.Uint32(m.Data[0:4]))
 | 
				
			||||||
 | 
									return syscall.Errno(-error)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if err := receiver(m); err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func attrsToXDPDiagInfoResp(attrs []syscall.NetlinkRouteAttr, sockInfo *XDPSocket) (*XDPDiagInfoResp, error) {
 | 
				
			||||||
 | 
						resp := &XDPDiagInfoResp{
 | 
				
			||||||
 | 
							XDPDiagMsg: sockInfo,
 | 
				
			||||||
 | 
							XDPInfo:    &XDPInfo{},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, a := range attrs {
 | 
				
			||||||
 | 
							switch a.Attr.Type {
 | 
				
			||||||
 | 
							case XDP_DIAG_INFO:
 | 
				
			||||||
 | 
								resp.XDPInfo.Ifindex = native.Uint32(a.Value[0:4])
 | 
				
			||||||
 | 
								resp.XDPInfo.QueueID = native.Uint32(a.Value[4:8])
 | 
				
			||||||
 | 
							case XDP_DIAG_UID:
 | 
				
			||||||
 | 
								resp.XDPInfo.UID = native.Uint32(a.Value[0:4])
 | 
				
			||||||
 | 
							case XDP_DIAG_RX_RING:
 | 
				
			||||||
 | 
								resp.XDPInfo.RxRingEntries = native.Uint32(a.Value[0:4])
 | 
				
			||||||
 | 
							case XDP_DIAG_TX_RING:
 | 
				
			||||||
 | 
								resp.XDPInfo.TxRingEntries = native.Uint32(a.Value[0:4])
 | 
				
			||||||
 | 
							case XDP_DIAG_UMEM_FILL_RING:
 | 
				
			||||||
 | 
								resp.XDPInfo.UmemFillRingEntries = native.Uint32(a.Value[0:4])
 | 
				
			||||||
 | 
							case XDP_DIAG_UMEM_COMPLETION_RING:
 | 
				
			||||||
 | 
								resp.XDPInfo.UmemCompletionRingEntries = native.Uint32(a.Value[0:4])
 | 
				
			||||||
 | 
							case XDP_DIAG_UMEM:
 | 
				
			||||||
 | 
								umem := &XDPDiagUmem{}
 | 
				
			||||||
 | 
								if err := umem.deserialize(a.Value); err != nil {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								resp.XDPInfo.Umem = umem
 | 
				
			||||||
 | 
							case XDP_DIAG_STATS:
 | 
				
			||||||
 | 
								stats := &XDPDiagStats{}
 | 
				
			||||||
 | 
								if err := stats.deserialize(a.Value); err != nil {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								resp.XDPInfo.Stats = stats
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return resp, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										92
									
								
								vendor/github.com/vishvananda/netlink/tcp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								vendor/github.com/vishvananda/netlink/tcp.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
				
			|||||||
 | 
					package netlink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TCP States
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						TCP_ESTABLISHED = iota + 0x01
 | 
				
			||||||
 | 
						TCP_SYN_SENT
 | 
				
			||||||
 | 
						TCP_SYN_RECV
 | 
				
			||||||
 | 
						TCP_FIN_WAIT1
 | 
				
			||||||
 | 
						TCP_FIN_WAIT2
 | 
				
			||||||
 | 
						TCP_TIME_WAIT
 | 
				
			||||||
 | 
						TCP_CLOSE
 | 
				
			||||||
 | 
						TCP_CLOSE_WAIT
 | 
				
			||||||
 | 
						TCP_LAST_ACK
 | 
				
			||||||
 | 
						TCP_LISTEN
 | 
				
			||||||
 | 
						TCP_CLOSING
 | 
				
			||||||
 | 
						TCP_NEW_SYN_REC
 | 
				
			||||||
 | 
						TCP_MAX_STATES
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type TCPInfo struct {
 | 
				
			||||||
 | 
						State                     uint8
 | 
				
			||||||
 | 
						Ca_state                  uint8
 | 
				
			||||||
 | 
						Retransmits               uint8
 | 
				
			||||||
 | 
						Probes                    uint8
 | 
				
			||||||
 | 
						Backoff                   uint8
 | 
				
			||||||
 | 
						Options                   uint8
 | 
				
			||||||
 | 
						Snd_wscale                uint8 // no uint4
 | 
				
			||||||
 | 
						Rcv_wscale                uint8
 | 
				
			||||||
 | 
						Delivery_rate_app_limited uint8
 | 
				
			||||||
 | 
						Fastopen_client_fail      uint8
 | 
				
			||||||
 | 
						Rto                       uint32
 | 
				
			||||||
 | 
						Ato                       uint32
 | 
				
			||||||
 | 
						Snd_mss                   uint32
 | 
				
			||||||
 | 
						Rcv_mss                   uint32
 | 
				
			||||||
 | 
						Unacked                   uint32
 | 
				
			||||||
 | 
						Sacked                    uint32
 | 
				
			||||||
 | 
						Lost                      uint32
 | 
				
			||||||
 | 
						Retrans                   uint32
 | 
				
			||||||
 | 
						Fackets                   uint32
 | 
				
			||||||
 | 
						Last_data_sent            uint32
 | 
				
			||||||
 | 
						Last_ack_sent             uint32
 | 
				
			||||||
 | 
						Last_data_recv            uint32
 | 
				
			||||||
 | 
						Last_ack_recv             uint32
 | 
				
			||||||
 | 
						Pmtu                      uint32
 | 
				
			||||||
 | 
						Rcv_ssthresh              uint32
 | 
				
			||||||
 | 
						Rtt                       uint32
 | 
				
			||||||
 | 
						Rttvar                    uint32
 | 
				
			||||||
 | 
						Snd_ssthresh              uint32
 | 
				
			||||||
 | 
						Snd_cwnd                  uint32
 | 
				
			||||||
 | 
						Advmss                    uint32
 | 
				
			||||||
 | 
						Reordering                uint32
 | 
				
			||||||
 | 
						Rcv_rtt                   uint32
 | 
				
			||||||
 | 
						Rcv_space                 uint32
 | 
				
			||||||
 | 
						Total_retrans             uint32
 | 
				
			||||||
 | 
						Pacing_rate               uint64
 | 
				
			||||||
 | 
						Max_pacing_rate           uint64
 | 
				
			||||||
 | 
						Bytes_acked               uint64 /* RFC4898 tcpEStatsAppHCThruOctetsAcked */
 | 
				
			||||||
 | 
						Bytes_received            uint64 /* RFC4898 tcpEStatsAppHCThruOctetsReceived */
 | 
				
			||||||
 | 
						Segs_out                  uint32 /* RFC4898 tcpEStatsPerfSegsOut */
 | 
				
			||||||
 | 
						Segs_in                   uint32 /* RFC4898 tcpEStatsPerfSegsIn */
 | 
				
			||||||
 | 
						Notsent_bytes             uint32
 | 
				
			||||||
 | 
						Min_rtt                   uint32
 | 
				
			||||||
 | 
						Data_segs_in              uint32 /* RFC4898 tcpEStatsDataSegsIn */
 | 
				
			||||||
 | 
						Data_segs_out             uint32 /* RFC4898 tcpEStatsDataSegsOut */
 | 
				
			||||||
 | 
						Delivery_rate             uint64
 | 
				
			||||||
 | 
						Busy_time                 uint64 /* Time (usec) busy sending data */
 | 
				
			||||||
 | 
						Rwnd_limited              uint64 /* Time (usec) limited by receive window */
 | 
				
			||||||
 | 
						Sndbuf_limited            uint64 /* Time (usec) limited by send buffer */
 | 
				
			||||||
 | 
						Delivered                 uint32
 | 
				
			||||||
 | 
						Delivered_ce              uint32
 | 
				
			||||||
 | 
						Bytes_sent                uint64 /* RFC4898 tcpEStatsPerfHCDataOctetsOut */
 | 
				
			||||||
 | 
						Bytes_retrans             uint64 /* RFC4898 tcpEStatsPerfOctetsRetrans */
 | 
				
			||||||
 | 
						Dsack_dups                uint32 /* RFC4898 tcpEStatsStackDSACKDups */
 | 
				
			||||||
 | 
						Reord_seen                uint32 /* reordering events seen */
 | 
				
			||||||
 | 
						Rcv_ooopack               uint32 /* Out-of-order packets received */
 | 
				
			||||||
 | 
						Snd_wnd                   uint32 /* peer's advertised receive window after * scaling (bytes) */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type TCPBBRInfo struct {
 | 
				
			||||||
 | 
						BBRBW         uint64
 | 
				
			||||||
 | 
						BBRMinRTT     uint32
 | 
				
			||||||
 | 
						BBRPacingGain uint32
 | 
				
			||||||
 | 
						BBRCwndGain   uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// According to https://man7.org/linux/man-pages/man7/sock_diag.7.html
 | 
				
			||||||
 | 
					type MemInfo struct {
 | 
				
			||||||
 | 
						RMem uint32
 | 
				
			||||||
 | 
						WMem uint32
 | 
				
			||||||
 | 
						FMem uint32
 | 
				
			||||||
 | 
						TMem uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										368
									
								
								vendor/github.com/vishvananda/netlink/tcp_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										368
									
								
								vendor/github.com/vishvananda/netlink/tcp_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,368 @@
 | 
				
			|||||||
 | 
					package netlink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						tcpBBRInfoLen = 20
 | 
				
			||||||
 | 
						memInfoLen    = 16
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func checkDeserErr(err error) error {
 | 
				
			||||||
 | 
						if err == io.EOF {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (t *TCPInfo) deserialize(b []byte) error {
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						rb := bytes.NewBuffer(b)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t.State, err = rb.ReadByte()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return checkDeserErr(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t.Ca_state, err = rb.ReadByte()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return checkDeserErr(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t.Retransmits, err = rb.ReadByte()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return checkDeserErr(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t.Probes, err = rb.ReadByte()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return checkDeserErr(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t.Backoff, err = rb.ReadByte()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return checkDeserErr(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Options, err = rb.ReadByte()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return checkDeserErr(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						scales, err := rb.ReadByte()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return checkDeserErr(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Snd_wscale = scales >> 4  // first 4 bits
 | 
				
			||||||
 | 
						t.Rcv_wscale = scales & 0xf // last 4 bits
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rateLimAndFastOpen, err := rb.ReadByte()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return checkDeserErr(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Delivery_rate_app_limited = rateLimAndFastOpen >> 7 // get first bit
 | 
				
			||||||
 | 
						t.Fastopen_client_fail = rateLimAndFastOpen >> 5 & 3  // get next two bits
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next := rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Rto = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Ato = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Snd_mss = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Rcv_mss = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Unacked = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Sacked = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Lost = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Retrans = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Fackets = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Last_data_sent = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Last_ack_sent = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Last_data_recv = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Last_ack_recv = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Pmtu = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Rcv_ssthresh = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Rtt = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Rttvar = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Snd_ssthresh = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Snd_cwnd = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Advmss = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Reordering = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Rcv_rtt = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Rcv_space = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Total_retrans = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(8)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Pacing_rate = native.Uint64(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(8)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Max_pacing_rate = native.Uint64(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(8)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Bytes_acked = native.Uint64(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(8)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Bytes_received = native.Uint64(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Segs_out = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Segs_in = native.Uint32(next)
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Notsent_bytes = native.Uint32(next)
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Min_rtt = native.Uint32(next)
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Data_segs_in = native.Uint32(next)
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Data_segs_out = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(8)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Delivery_rate = native.Uint64(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(8)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Busy_time = native.Uint64(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(8)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Rwnd_limited = native.Uint64(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(8)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Sndbuf_limited = native.Uint64(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Delivered = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Delivered_ce = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(8)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Bytes_sent = native.Uint64(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(8)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Bytes_retrans = native.Uint64(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Dsack_dups = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Reord_seen = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Rcv_ooopack = native.Uint32(next)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						next = rb.Next(4)
 | 
				
			||||||
 | 
						if len(next) == 0 {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Snd_wnd = native.Uint32(next)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (t *TCPBBRInfo) deserialize(b []byte) error {
 | 
				
			||||||
 | 
						if len(b) != tcpBBRInfoLen {
 | 
				
			||||||
 | 
							return errors.New("Invalid length")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rb := bytes.NewBuffer(b)
 | 
				
			||||||
 | 
						t.BBRBW = native.Uint64(rb.Next(8))
 | 
				
			||||||
 | 
						t.BBRMinRTT = native.Uint32(rb.Next(4))
 | 
				
			||||||
 | 
						t.BBRPacingGain = native.Uint32(rb.Next(4))
 | 
				
			||||||
 | 
						t.BBRCwndGain = native.Uint32(rb.Next(4))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *MemInfo) deserialize(b []byte) error {
 | 
				
			||||||
 | 
						if len(b) != memInfoLen {
 | 
				
			||||||
 | 
							return errors.New("Invalid length")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rb := bytes.NewBuffer(b)
 | 
				
			||||||
 | 
						m.RMem = native.Uint32(rb.Next(4))
 | 
				
			||||||
 | 
						m.WMem = native.Uint32(rb.Next(4))
 | 
				
			||||||
 | 
						m.FMem = native.Uint32(rb.Next(4))
 | 
				
			||||||
 | 
						m.TMem = native.Uint32(rb.Next(4))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										27
									
								
								vendor/github.com/vishvananda/netlink/unix_diag.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/vishvananda/netlink/unix_diag.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					package netlink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// According to linux/include/uapi/linux/unix_diag.h
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						UNIX_DIAG_NAME = iota
 | 
				
			||||||
 | 
						UNIX_DIAG_VFS
 | 
				
			||||||
 | 
						UNIX_DIAG_PEER
 | 
				
			||||||
 | 
						UNIX_DIAG_ICONS
 | 
				
			||||||
 | 
						UNIX_DIAG_RQLEN
 | 
				
			||||||
 | 
						UNIX_DIAG_MEMINFO
 | 
				
			||||||
 | 
						UNIX_DIAG_SHUTDOWN
 | 
				
			||||||
 | 
						UNIX_DIAG_UID
 | 
				
			||||||
 | 
						UNIX_DIAG_MAX
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UnixDiagInfoResp struct {
 | 
				
			||||||
 | 
						DiagMsg  *UnixSocket
 | 
				
			||||||
 | 
						Name     *string
 | 
				
			||||||
 | 
						Peer     *uint32
 | 
				
			||||||
 | 
						Queue    *QueueInfo
 | 
				
			||||||
 | 
						Shutdown *uint8
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type QueueInfo struct {
 | 
				
			||||||
 | 
						RQueue uint32
 | 
				
			||||||
 | 
						WQueue uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										463
									
								
								vendor/github.com/vishvananda/netlink/vdpa_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										463
									
								
								vendor/github.com/vishvananda/netlink/vdpa_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,463 @@
 | 
				
			|||||||
 | 
					package netlink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
 | 
						"syscall"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"golang.org/x/sys/unix"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/vishvananda/netlink/nl"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type vdpaDevID struct {
 | 
				
			||||||
 | 
						Name string
 | 
				
			||||||
 | 
						ID   uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPADev contains info about VDPA device
 | 
				
			||||||
 | 
					type VDPADev struct {
 | 
				
			||||||
 | 
						vdpaDevID
 | 
				
			||||||
 | 
						VendorID  uint32
 | 
				
			||||||
 | 
						MaxVQS    uint32
 | 
				
			||||||
 | 
						MaxVQSize uint16
 | 
				
			||||||
 | 
						MinVQSize uint16
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPADevConfig contains configuration of the VDPA device
 | 
				
			||||||
 | 
					type VDPADevConfig struct {
 | 
				
			||||||
 | 
						vdpaDevID
 | 
				
			||||||
 | 
						Features           uint64
 | 
				
			||||||
 | 
						NegotiatedFeatures uint64
 | 
				
			||||||
 | 
						Net                VDPADevConfigNet
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPADevVStats conatins vStats for the VDPA device
 | 
				
			||||||
 | 
					type VDPADevVStats struct {
 | 
				
			||||||
 | 
						vdpaDevID
 | 
				
			||||||
 | 
						QueueIndex         uint32
 | 
				
			||||||
 | 
						Vendor             []VDPADevVStatsVendor
 | 
				
			||||||
 | 
						NegotiatedFeatures uint64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPADevVStatsVendor conatins name and value for vendor specific vstat option
 | 
				
			||||||
 | 
					type VDPADevVStatsVendor struct {
 | 
				
			||||||
 | 
						Name  string
 | 
				
			||||||
 | 
						Value uint64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPADevConfigNet conatins status and net config for the VDPA device
 | 
				
			||||||
 | 
					type VDPADevConfigNet struct {
 | 
				
			||||||
 | 
						Status VDPADevConfigNetStatus
 | 
				
			||||||
 | 
						Cfg    VDPADevConfigNetCfg
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPADevConfigNetStatus contains info about net status
 | 
				
			||||||
 | 
					type VDPADevConfigNetStatus struct {
 | 
				
			||||||
 | 
						LinkUp   bool
 | 
				
			||||||
 | 
						Announce bool
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPADevConfigNetCfg contains net config for the VDPA device
 | 
				
			||||||
 | 
					type VDPADevConfigNetCfg struct {
 | 
				
			||||||
 | 
						MACAddr net.HardwareAddr
 | 
				
			||||||
 | 
						MaxVQP  uint16
 | 
				
			||||||
 | 
						MTU     uint16
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPAMGMTDev conatins info about VDPA management device
 | 
				
			||||||
 | 
					type VDPAMGMTDev struct {
 | 
				
			||||||
 | 
						BusName           string
 | 
				
			||||||
 | 
						DevName           string
 | 
				
			||||||
 | 
						SupportedClasses  uint64
 | 
				
			||||||
 | 
						SupportedFeatures uint64
 | 
				
			||||||
 | 
						MaxVQS            uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPANewDevParams contains parameters for new VDPA device
 | 
				
			||||||
 | 
					// use SetBits to configure requried features for the device
 | 
				
			||||||
 | 
					// example:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//	VDPANewDevParams{Features: SetBits(0, VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_MAC_ADDR)}
 | 
				
			||||||
 | 
					type VDPANewDevParams struct {
 | 
				
			||||||
 | 
						MACAddr  net.HardwareAddr
 | 
				
			||||||
 | 
						MaxVQP   uint16
 | 
				
			||||||
 | 
						MTU      uint16
 | 
				
			||||||
 | 
						Features uint64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetBits set provided bits in the uint64 input value
 | 
				
			||||||
 | 
					// usage example:
 | 
				
			||||||
 | 
					// features := SetBits(0, VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_MAC_ADDR)
 | 
				
			||||||
 | 
					func SetBits(input uint64, pos ...int) uint64 {
 | 
				
			||||||
 | 
						for _, p := range pos {
 | 
				
			||||||
 | 
							input |= 1 << uint64(p)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return input
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IsBitSet check if specific bit is set in the uint64 input value
 | 
				
			||||||
 | 
					// usage example:
 | 
				
			||||||
 | 
					// hasNetClass := IsBitSet(mgmtDev, VIRTIO_ID_NET)
 | 
				
			||||||
 | 
					func IsBitSet(input uint64, pos int) bool {
 | 
				
			||||||
 | 
						val := input & (1 << uint64(pos))
 | 
				
			||||||
 | 
						return val > 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPANewDev adds new VDPA device
 | 
				
			||||||
 | 
					// Equivalent to: `vdpa dev add name <name> mgmtdev <mgmtBus>/mgmtName [params]`
 | 
				
			||||||
 | 
					func VDPANewDev(name, mgmtBus, mgmtName string, params VDPANewDevParams) error {
 | 
				
			||||||
 | 
						return pkgHandle.VDPANewDev(name, mgmtBus, mgmtName, params)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPADelDev removes VDPA device
 | 
				
			||||||
 | 
					// Equivalent to: `vdpa dev del <name>`
 | 
				
			||||||
 | 
					func VDPADelDev(name string) error {
 | 
				
			||||||
 | 
						return pkgHandle.VDPADelDev(name)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPAGetDevList returns list of VDPA devices
 | 
				
			||||||
 | 
					// Equivalent to: `vdpa dev show`
 | 
				
			||||||
 | 
					func VDPAGetDevList() ([]*VDPADev, error) {
 | 
				
			||||||
 | 
						return pkgHandle.VDPAGetDevList()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPAGetDevByName returns VDPA device selected by name
 | 
				
			||||||
 | 
					// Equivalent to: `vdpa dev show <name>`
 | 
				
			||||||
 | 
					func VDPAGetDevByName(name string) (*VDPADev, error) {
 | 
				
			||||||
 | 
						return pkgHandle.VDPAGetDevByName(name)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPAGetDevConfigList returns list of VDPA devices configurations
 | 
				
			||||||
 | 
					// Equivalent to: `vdpa dev config show`
 | 
				
			||||||
 | 
					func VDPAGetDevConfigList() ([]*VDPADevConfig, error) {
 | 
				
			||||||
 | 
						return pkgHandle.VDPAGetDevConfigList()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPAGetDevConfigByName returns VDPA device configuration selected by name
 | 
				
			||||||
 | 
					// Equivalent to: `vdpa dev config show <name>`
 | 
				
			||||||
 | 
					func VDPAGetDevConfigByName(name string) (*VDPADevConfig, error) {
 | 
				
			||||||
 | 
						return pkgHandle.VDPAGetDevConfigByName(name)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPAGetDevVStats returns vstats for VDPA device
 | 
				
			||||||
 | 
					// Equivalent to: `vdpa dev vstats show <name> qidx <queueIndex>`
 | 
				
			||||||
 | 
					func VDPAGetDevVStats(name string, queueIndex uint32) (*VDPADevVStats, error) {
 | 
				
			||||||
 | 
						return pkgHandle.VDPAGetDevVStats(name, queueIndex)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPAGetMGMTDevList returns list of mgmt devices
 | 
				
			||||||
 | 
					// Equivalent to: `vdpa mgmtdev show`
 | 
				
			||||||
 | 
					func VDPAGetMGMTDevList() ([]*VDPAMGMTDev, error) {
 | 
				
			||||||
 | 
						return pkgHandle.VDPAGetMGMTDevList()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPAGetMGMTDevByBusAndName returns mgmt devices selected by bus and name
 | 
				
			||||||
 | 
					// Equivalent to: `vdpa mgmtdev show <bus>/<name>`
 | 
				
			||||||
 | 
					func VDPAGetMGMTDevByBusAndName(bus, name string) (*VDPAMGMTDev, error) {
 | 
				
			||||||
 | 
						return pkgHandle.VDPAGetMGMTDevByBusAndName(bus, name)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type vdpaNetlinkMessage []syscall.NetlinkRouteAttr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (id *vdpaDevID) parseIDAttribute(attr syscall.NetlinkRouteAttr) {
 | 
				
			||||||
 | 
						switch attr.Attr.Type {
 | 
				
			||||||
 | 
						case nl.VDPA_ATTR_DEV_NAME:
 | 
				
			||||||
 | 
							id.Name = nl.BytesToString(attr.Value)
 | 
				
			||||||
 | 
						case nl.VDPA_ATTR_DEV_ID:
 | 
				
			||||||
 | 
							id.ID = native.Uint32(attr.Value)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (netStatus *VDPADevConfigNetStatus) parseStatusAttribute(value []byte) {
 | 
				
			||||||
 | 
						a := native.Uint16(value)
 | 
				
			||||||
 | 
						netStatus.Announce = (a & VIRTIO_NET_S_ANNOUNCE) > 0
 | 
				
			||||||
 | 
						netStatus.LinkUp = (a & VIRTIO_NET_S_LINK_UP) > 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (d *VDPADev) parseAttributes(attrs vdpaNetlinkMessage) {
 | 
				
			||||||
 | 
						for _, a := range attrs {
 | 
				
			||||||
 | 
							d.parseIDAttribute(a)
 | 
				
			||||||
 | 
							switch a.Attr.Type {
 | 
				
			||||||
 | 
							case nl.VDPA_ATTR_DEV_VENDOR_ID:
 | 
				
			||||||
 | 
								d.VendorID = native.Uint32(a.Value)
 | 
				
			||||||
 | 
							case nl.VDPA_ATTR_DEV_MAX_VQS:
 | 
				
			||||||
 | 
								d.MaxVQS = native.Uint32(a.Value)
 | 
				
			||||||
 | 
							case nl.VDPA_ATTR_DEV_MAX_VQ_SIZE:
 | 
				
			||||||
 | 
								d.MaxVQSize = native.Uint16(a.Value)
 | 
				
			||||||
 | 
							case nl.VDPA_ATTR_DEV_MIN_VQ_SIZE:
 | 
				
			||||||
 | 
								d.MinVQSize = native.Uint16(a.Value)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *VDPADevConfig) parseAttributes(attrs vdpaNetlinkMessage) {
 | 
				
			||||||
 | 
						for _, a := range attrs {
 | 
				
			||||||
 | 
							c.parseIDAttribute(a)
 | 
				
			||||||
 | 
							switch a.Attr.Type {
 | 
				
			||||||
 | 
							case nl.VDPA_ATTR_DEV_NET_CFG_MACADDR:
 | 
				
			||||||
 | 
								c.Net.Cfg.MACAddr = a.Value
 | 
				
			||||||
 | 
							case nl.VDPA_ATTR_DEV_NET_STATUS:
 | 
				
			||||||
 | 
								c.Net.Status.parseStatusAttribute(a.Value)
 | 
				
			||||||
 | 
							case nl.VDPA_ATTR_DEV_NET_CFG_MAX_VQP:
 | 
				
			||||||
 | 
								c.Net.Cfg.MaxVQP = native.Uint16(a.Value)
 | 
				
			||||||
 | 
							case nl.VDPA_ATTR_DEV_NET_CFG_MTU:
 | 
				
			||||||
 | 
								c.Net.Cfg.MTU = native.Uint16(a.Value)
 | 
				
			||||||
 | 
							case nl.VDPA_ATTR_DEV_FEATURES:
 | 
				
			||||||
 | 
								c.Features = native.Uint64(a.Value)
 | 
				
			||||||
 | 
							case nl.VDPA_ATTR_DEV_NEGOTIATED_FEATURES:
 | 
				
			||||||
 | 
								c.NegotiatedFeatures = native.Uint64(a.Value)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *VDPADevVStats) parseAttributes(attrs vdpaNetlinkMessage) {
 | 
				
			||||||
 | 
						for _, a := range attrs {
 | 
				
			||||||
 | 
							s.parseIDAttribute(a)
 | 
				
			||||||
 | 
							switch a.Attr.Type {
 | 
				
			||||||
 | 
							case nl.VDPA_ATTR_DEV_QUEUE_INDEX:
 | 
				
			||||||
 | 
								s.QueueIndex = native.Uint32(a.Value)
 | 
				
			||||||
 | 
							case nl.VDPA_ATTR_DEV_VENDOR_ATTR_NAME:
 | 
				
			||||||
 | 
								s.Vendor = append(s.Vendor, VDPADevVStatsVendor{Name: nl.BytesToString(a.Value)})
 | 
				
			||||||
 | 
							case nl.VDPA_ATTR_DEV_VENDOR_ATTR_VALUE:
 | 
				
			||||||
 | 
								if len(s.Vendor) == 0 {
 | 
				
			||||||
 | 
									break
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								s.Vendor[len(s.Vendor)-1].Value = native.Uint64(a.Value)
 | 
				
			||||||
 | 
							case nl.VDPA_ATTR_DEV_NEGOTIATED_FEATURES:
 | 
				
			||||||
 | 
								s.NegotiatedFeatures = native.Uint64(a.Value)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (d *VDPAMGMTDev) parseAttributes(attrs vdpaNetlinkMessage) {
 | 
				
			||||||
 | 
						for _, a := range attrs {
 | 
				
			||||||
 | 
							switch a.Attr.Type {
 | 
				
			||||||
 | 
							case nl.VDPA_ATTR_MGMTDEV_BUS_NAME:
 | 
				
			||||||
 | 
								d.BusName = nl.BytesToString(a.Value)
 | 
				
			||||||
 | 
							case nl.VDPA_ATTR_MGMTDEV_DEV_NAME:
 | 
				
			||||||
 | 
								d.DevName = nl.BytesToString(a.Value)
 | 
				
			||||||
 | 
							case nl.VDPA_ATTR_MGMTDEV_SUPPORTED_CLASSES:
 | 
				
			||||||
 | 
								d.SupportedClasses = native.Uint64(a.Value)
 | 
				
			||||||
 | 
							case nl.VDPA_ATTR_DEV_SUPPORTED_FEATURES:
 | 
				
			||||||
 | 
								d.SupportedFeatures = native.Uint64(a.Value)
 | 
				
			||||||
 | 
							case nl.VDPA_ATTR_DEV_MGMTDEV_MAX_VQS:
 | 
				
			||||||
 | 
								d.MaxVQS = native.Uint32(a.Value)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *Handle) vdpaRequest(command uint8, extraFlags int, attrs []*nl.RtAttr) ([]vdpaNetlinkMessage, error) {
 | 
				
			||||||
 | 
						f, err := h.GenlFamilyGet(nl.VDPA_GENL_NAME)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						req := h.newNetlinkRequest(int(f.ID), unix.NLM_F_ACK|extraFlags)
 | 
				
			||||||
 | 
						req.AddData(&nl.Genlmsg{
 | 
				
			||||||
 | 
							Command: command,
 | 
				
			||||||
 | 
							Version: nl.VDPA_GENL_VERSION,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						for _, a := range attrs {
 | 
				
			||||||
 | 
							req.AddData(a)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						resp, err := req.Execute(unix.NETLINK_GENERIC, 0)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						messages := make([]vdpaNetlinkMessage, 0, len(resp))
 | 
				
			||||||
 | 
						for _, m := range resp {
 | 
				
			||||||
 | 
							attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:])
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							messages = append(messages, attrs)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return messages, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// dump all devices if dev is nil
 | 
				
			||||||
 | 
					func (h *Handle) vdpaDevGet(dev *string) ([]*VDPADev, error) {
 | 
				
			||||||
 | 
						var extraFlags int
 | 
				
			||||||
 | 
						var attrs []*nl.RtAttr
 | 
				
			||||||
 | 
						if dev != nil {
 | 
				
			||||||
 | 
							attrs = append(attrs, nl.NewRtAttr(nl.VDPA_ATTR_DEV_NAME, nl.ZeroTerminated(*dev)))
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							extraFlags = extraFlags | unix.NLM_F_DUMP
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						messages, err := h.vdpaRequest(nl.VDPA_CMD_DEV_GET, extraFlags, attrs)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						devs := make([]*VDPADev, 0, len(messages))
 | 
				
			||||||
 | 
						for _, m := range messages {
 | 
				
			||||||
 | 
							d := &VDPADev{}
 | 
				
			||||||
 | 
							d.parseAttributes(m)
 | 
				
			||||||
 | 
							devs = append(devs, d)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return devs, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// dump all devices if dev is nil
 | 
				
			||||||
 | 
					func (h *Handle) vdpaDevConfigGet(dev *string) ([]*VDPADevConfig, error) {
 | 
				
			||||||
 | 
						var extraFlags int
 | 
				
			||||||
 | 
						var attrs []*nl.RtAttr
 | 
				
			||||||
 | 
						if dev != nil {
 | 
				
			||||||
 | 
							attrs = append(attrs, nl.NewRtAttr(nl.VDPA_ATTR_DEV_NAME, nl.ZeroTerminated(*dev)))
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							extraFlags = extraFlags | unix.NLM_F_DUMP
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						messages, err := h.vdpaRequest(nl.VDPA_CMD_DEV_CONFIG_GET, extraFlags, attrs)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						cfgs := make([]*VDPADevConfig, 0, len(messages))
 | 
				
			||||||
 | 
						for _, m := range messages {
 | 
				
			||||||
 | 
							cfg := &VDPADevConfig{}
 | 
				
			||||||
 | 
							cfg.parseAttributes(m)
 | 
				
			||||||
 | 
							cfgs = append(cfgs, cfg)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return cfgs, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// dump all devices if dev is nil
 | 
				
			||||||
 | 
					func (h *Handle) vdpaMGMTDevGet(bus, dev *string) ([]*VDPAMGMTDev, error) {
 | 
				
			||||||
 | 
						var extraFlags int
 | 
				
			||||||
 | 
						var attrs []*nl.RtAttr
 | 
				
			||||||
 | 
						if dev != nil {
 | 
				
			||||||
 | 
							attrs = append(attrs,
 | 
				
			||||||
 | 
								nl.NewRtAttr(nl.VDPA_ATTR_MGMTDEV_DEV_NAME, nl.ZeroTerminated(*dev)),
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
							if bus != nil {
 | 
				
			||||||
 | 
								attrs = append(attrs,
 | 
				
			||||||
 | 
									nl.NewRtAttr(nl.VDPA_ATTR_MGMTDEV_BUS_NAME, nl.ZeroTerminated(*bus)),
 | 
				
			||||||
 | 
								)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							extraFlags = extraFlags | unix.NLM_F_DUMP
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						messages, err := h.vdpaRequest(nl.VDPA_CMD_MGMTDEV_GET, extraFlags, attrs)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						cfgs := make([]*VDPAMGMTDev, 0, len(messages))
 | 
				
			||||||
 | 
						for _, m := range messages {
 | 
				
			||||||
 | 
							cfg := &VDPAMGMTDev{}
 | 
				
			||||||
 | 
							cfg.parseAttributes(m)
 | 
				
			||||||
 | 
							cfgs = append(cfgs, cfg)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return cfgs, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPANewDev adds new VDPA device
 | 
				
			||||||
 | 
					// Equivalent to: `vdpa dev add name <name> mgmtdev <mgmtBus>/mgmtName [params]`
 | 
				
			||||||
 | 
					func (h *Handle) VDPANewDev(name, mgmtBus, mgmtName string, params VDPANewDevParams) error {
 | 
				
			||||||
 | 
						attrs := []*nl.RtAttr{
 | 
				
			||||||
 | 
							nl.NewRtAttr(nl.VDPA_ATTR_DEV_NAME, nl.ZeroTerminated(name)),
 | 
				
			||||||
 | 
							nl.NewRtAttr(nl.VDPA_ATTR_MGMTDEV_DEV_NAME, nl.ZeroTerminated(mgmtName)),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if mgmtBus != "" {
 | 
				
			||||||
 | 
							attrs = append(attrs, nl.NewRtAttr(nl.VDPA_ATTR_MGMTDEV_BUS_NAME, nl.ZeroTerminated(mgmtBus)))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(params.MACAddr) != 0 {
 | 
				
			||||||
 | 
							attrs = append(attrs, nl.NewRtAttr(nl.VDPA_ATTR_DEV_NET_CFG_MACADDR, params.MACAddr))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if params.MaxVQP > 0 {
 | 
				
			||||||
 | 
							attrs = append(attrs, nl.NewRtAttr(nl.VDPA_ATTR_DEV_NET_CFG_MAX_VQP, nl.Uint16Attr(params.MaxVQP)))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if params.MTU > 0 {
 | 
				
			||||||
 | 
							attrs = append(attrs, nl.NewRtAttr(nl.VDPA_ATTR_DEV_NET_CFG_MTU, nl.Uint16Attr(params.MTU)))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if params.Features > 0 {
 | 
				
			||||||
 | 
							attrs = append(attrs, nl.NewRtAttr(nl.VDPA_ATTR_DEV_FEATURES, nl.Uint64Attr(params.Features)))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						_, err := h.vdpaRequest(nl.VDPA_CMD_DEV_NEW, 0, attrs)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPADelDev removes VDPA device
 | 
				
			||||||
 | 
					// Equivalent to: `vdpa dev del <name>`
 | 
				
			||||||
 | 
					func (h *Handle) VDPADelDev(name string) error {
 | 
				
			||||||
 | 
						_, err := h.vdpaRequest(nl.VDPA_CMD_DEV_DEL, 0, []*nl.RtAttr{
 | 
				
			||||||
 | 
							nl.NewRtAttr(nl.VDPA_ATTR_DEV_NAME, nl.ZeroTerminated(name))})
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPAGetDevList returns list of VDPA devices
 | 
				
			||||||
 | 
					// Equivalent to: `vdpa dev show`
 | 
				
			||||||
 | 
					func (h *Handle) VDPAGetDevList() ([]*VDPADev, error) {
 | 
				
			||||||
 | 
						return h.vdpaDevGet(nil)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPAGetDevByName returns VDPA device selected by name
 | 
				
			||||||
 | 
					// Equivalent to: `vdpa dev show <name>`
 | 
				
			||||||
 | 
					func (h *Handle) VDPAGetDevByName(name string) (*VDPADev, error) {
 | 
				
			||||||
 | 
						devs, err := h.vdpaDevGet(&name)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(devs) == 0 {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("device not found")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return devs[0], nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPAGetDevConfigList returns list of VDPA devices configurations
 | 
				
			||||||
 | 
					// Equivalent to: `vdpa dev config show`
 | 
				
			||||||
 | 
					func (h *Handle) VDPAGetDevConfigList() ([]*VDPADevConfig, error) {
 | 
				
			||||||
 | 
						return h.vdpaDevConfigGet(nil)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPAGetDevConfigByName returns VDPA device configuration selected by name
 | 
				
			||||||
 | 
					// Equivalent to: `vdpa dev config show <name>`
 | 
				
			||||||
 | 
					func (h *Handle) VDPAGetDevConfigByName(name string) (*VDPADevConfig, error) {
 | 
				
			||||||
 | 
						cfgs, err := h.vdpaDevConfigGet(&name)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(cfgs) == 0 {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("configuration not found")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return cfgs[0], nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPAGetDevVStats returns vstats for VDPA device
 | 
				
			||||||
 | 
					// Equivalent to: `vdpa dev vstats show <name> qidx <queueIndex>`
 | 
				
			||||||
 | 
					func (h *Handle) VDPAGetDevVStats(name string, queueIndex uint32) (*VDPADevVStats, error) {
 | 
				
			||||||
 | 
						messages, err := h.vdpaRequest(nl.VDPA_CMD_DEV_VSTATS_GET, 0, []*nl.RtAttr{
 | 
				
			||||||
 | 
							nl.NewRtAttr(nl.VDPA_ATTR_DEV_NAME, nl.ZeroTerminated(name)),
 | 
				
			||||||
 | 
							nl.NewRtAttr(nl.VDPA_ATTR_DEV_QUEUE_INDEX, nl.Uint32Attr(queueIndex)),
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(messages) == 0 {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("stats not found")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						stats := &VDPADevVStats{}
 | 
				
			||||||
 | 
						stats.parseAttributes(messages[0])
 | 
				
			||||||
 | 
						return stats, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPAGetMGMTDevList returns list of mgmt devices
 | 
				
			||||||
 | 
					// Equivalent to: `vdpa mgmtdev show`
 | 
				
			||||||
 | 
					func (h *Handle) VDPAGetMGMTDevList() ([]*VDPAMGMTDev, error) {
 | 
				
			||||||
 | 
						return h.vdpaMGMTDevGet(nil, nil)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// VDPAGetMGMTDevByBusAndName returns mgmt devices selected by bus and name
 | 
				
			||||||
 | 
					// Equivalent to: `vdpa mgmtdev show <bus>/<name>`
 | 
				
			||||||
 | 
					func (h *Handle) VDPAGetMGMTDevByBusAndName(bus, name string) (*VDPAMGMTDev, error) {
 | 
				
			||||||
 | 
						var busPtr *string
 | 
				
			||||||
 | 
						if bus != "" {
 | 
				
			||||||
 | 
							busPtr = &bus
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						devs, err := h.vdpaMGMTDevGet(busPtr, &name)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if len(devs) == 0 {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("mgmtdev not found")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return devs[0], nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										132
									
								
								vendor/github.com/vishvananda/netlink/virtio.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								vendor/github.com/vishvananda/netlink/virtio.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
				
			|||||||
 | 
					package netlink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// features for virtio net
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						VIRTIO_NET_F_CSUM                = 0  // Host handles pkts w/ partial csum
 | 
				
			||||||
 | 
						VIRTIO_NET_F_GUEST_CSUM          = 1  // Guest handles pkts w/ partial csum
 | 
				
			||||||
 | 
						VIRTIO_NET_F_CTRL_GUEST_OFFLOADS = 2  // Dynamic offload configuration.
 | 
				
			||||||
 | 
						VIRTIO_NET_F_MTU                 = 3  // Initial MTU advice
 | 
				
			||||||
 | 
						VIRTIO_NET_F_MAC                 = 5  // Host has given MAC address.
 | 
				
			||||||
 | 
						VIRTIO_NET_F_GUEST_TSO4          = 7  // Guest can handle TSOv4 in.
 | 
				
			||||||
 | 
						VIRTIO_NET_F_GUEST_TSO6          = 8  // Guest can handle TSOv6 in.
 | 
				
			||||||
 | 
						VIRTIO_NET_F_GUEST_ECN           = 9  // Guest can handle TSO[6] w/ ECN in.
 | 
				
			||||||
 | 
						VIRTIO_NET_F_GUEST_UFO           = 10 // Guest can handle UFO in.
 | 
				
			||||||
 | 
						VIRTIO_NET_F_HOST_TSO4           = 11 // Host can handle TSOv4 in.
 | 
				
			||||||
 | 
						VIRTIO_NET_F_HOST_TSO6           = 12 // Host can handle TSOv6 in.
 | 
				
			||||||
 | 
						VIRTIO_NET_F_HOST_ECN            = 13 // Host can handle TSO[6] w/ ECN in.
 | 
				
			||||||
 | 
						VIRTIO_NET_F_HOST_UFO            = 14 // Host can handle UFO in.
 | 
				
			||||||
 | 
						VIRTIO_NET_F_MRG_RXBUF           = 15 // Host can merge receive buffers.
 | 
				
			||||||
 | 
						VIRTIO_NET_F_STATUS              = 16 // virtio_net_config.status available
 | 
				
			||||||
 | 
						VIRTIO_NET_F_CTRL_VQ             = 17 // Control channel available
 | 
				
			||||||
 | 
						VIRTIO_NET_F_CTRL_RX             = 18 // Control channel RX mode support
 | 
				
			||||||
 | 
						VIRTIO_NET_F_CTRL_VLAN           = 19 // Control channel VLAN filtering
 | 
				
			||||||
 | 
						VIRTIO_NET_F_CTRL_RX_EXTRA       = 20 // Extra RX mode control support
 | 
				
			||||||
 | 
						VIRTIO_NET_F_GUEST_ANNOUNCE      = 21 // Guest can announce device on the* network
 | 
				
			||||||
 | 
						VIRTIO_NET_F_MQ                  = 22 // Device supports Receive Flow Steering
 | 
				
			||||||
 | 
						VIRTIO_NET_F_CTRL_MAC_ADDR       = 23 // Set MAC address
 | 
				
			||||||
 | 
						VIRTIO_NET_F_VQ_NOTF_COAL        = 52 // Device supports virtqueue notification coalescing
 | 
				
			||||||
 | 
						VIRTIO_NET_F_NOTF_COAL           = 53 // Device supports notifications coalescing
 | 
				
			||||||
 | 
						VIRTIO_NET_F_GUEST_USO4          = 54 // Guest can handle USOv4 in.
 | 
				
			||||||
 | 
						VIRTIO_NET_F_GUEST_USO6          = 55 // Guest can handle USOv6 in.
 | 
				
			||||||
 | 
						VIRTIO_NET_F_HOST_USO            = 56 // Host can handle USO in.
 | 
				
			||||||
 | 
						VIRTIO_NET_F_HASH_REPORT         = 57 // Supports hash report
 | 
				
			||||||
 | 
						VIRTIO_NET_F_GUEST_HDRLEN        = 59 // Guest provides the exact hdr_len value.
 | 
				
			||||||
 | 
						VIRTIO_NET_F_RSS                 = 60 // Supports RSS RX steering
 | 
				
			||||||
 | 
						VIRTIO_NET_F_RSC_EXT             = 61 // extended coalescing info
 | 
				
			||||||
 | 
						VIRTIO_NET_F_STANDBY             = 62 // Act as standby for another device with the same MAC.
 | 
				
			||||||
 | 
						VIRTIO_NET_F_SPEED_DUPLEX        = 63 // Device set linkspeed and duplex
 | 
				
			||||||
 | 
						VIRTIO_NET_F_GSO                 = 6  // Host handles pkts any GSO type
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// virtio net status
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						VIRTIO_NET_S_LINK_UP  = 1 // Link is up
 | 
				
			||||||
 | 
						VIRTIO_NET_S_ANNOUNCE = 2 // Announcement is needed
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// virtio config
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						// Do we get callbacks when the ring is completely used, even if we've
 | 
				
			||||||
 | 
						// suppressed them?
 | 
				
			||||||
 | 
						VIRTIO_F_NOTIFY_ON_EMPTY = 24
 | 
				
			||||||
 | 
						// Can the device handle any descriptor layout?
 | 
				
			||||||
 | 
						VIRTIO_F_ANY_LAYOUT = 27
 | 
				
			||||||
 | 
						// v1.0 compliant
 | 
				
			||||||
 | 
						VIRTIO_F_VERSION_1 = 32
 | 
				
			||||||
 | 
						// If clear - device has the platform DMA (e.g. IOMMU) bypass quirk feature.
 | 
				
			||||||
 | 
						// If set - use platform DMA tools to access the memory.
 | 
				
			||||||
 | 
						// Note the reverse polarity (compared to most other features),
 | 
				
			||||||
 | 
						// this is for compatibility with legacy systems.
 | 
				
			||||||
 | 
						VIRTIO_F_ACCESS_PLATFORM = 33
 | 
				
			||||||
 | 
						// Legacy name for VIRTIO_F_ACCESS_PLATFORM (for compatibility with old userspace)
 | 
				
			||||||
 | 
						VIRTIO_F_IOMMU_PLATFORM = VIRTIO_F_ACCESS_PLATFORM
 | 
				
			||||||
 | 
						// This feature indicates support for the packed virtqueue layout.
 | 
				
			||||||
 | 
						VIRTIO_F_RING_PACKED = 34
 | 
				
			||||||
 | 
						// Inorder feature indicates that all buffers are used by the device
 | 
				
			||||||
 | 
						// in the same order in which they have been made available.
 | 
				
			||||||
 | 
						VIRTIO_F_IN_ORDER = 35
 | 
				
			||||||
 | 
						// This feature indicates that memory accesses by the driver and the
 | 
				
			||||||
 | 
						// device are ordered in a way described by the platform.
 | 
				
			||||||
 | 
						VIRTIO_F_ORDER_PLATFORM = 36
 | 
				
			||||||
 | 
						// Does the device support Single Root I/O Virtualization?
 | 
				
			||||||
 | 
						VIRTIO_F_SR_IOV = 37
 | 
				
			||||||
 | 
						// This feature indicates that the driver passes extra data (besides
 | 
				
			||||||
 | 
						// identifying the virtqueue) in its device notifications.
 | 
				
			||||||
 | 
						VIRTIO_F_NOTIFICATION_DATA = 38
 | 
				
			||||||
 | 
						// This feature indicates that the driver uses the data provided by the device
 | 
				
			||||||
 | 
						// as a virtqueue identifier in available buffer notifications.
 | 
				
			||||||
 | 
						VIRTIO_F_NOTIF_CONFIG_DATA = 39
 | 
				
			||||||
 | 
						// This feature indicates that the driver can reset a queue individually.
 | 
				
			||||||
 | 
						VIRTIO_F_RING_RESET = 40
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// virtio device ids
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						VIRTIO_ID_NET            = 1  // virtio net
 | 
				
			||||||
 | 
						VIRTIO_ID_BLOCK          = 2  // virtio block
 | 
				
			||||||
 | 
						VIRTIO_ID_CONSOLE        = 3  // virtio console
 | 
				
			||||||
 | 
						VIRTIO_ID_RNG            = 4  // virtio rng
 | 
				
			||||||
 | 
						VIRTIO_ID_BALLOON        = 5  // virtio balloon
 | 
				
			||||||
 | 
						VIRTIO_ID_IOMEM          = 6  // virtio ioMemory
 | 
				
			||||||
 | 
						VIRTIO_ID_RPMSG          = 7  // virtio remote processor messaging
 | 
				
			||||||
 | 
						VIRTIO_ID_SCSI           = 8  // virtio scsi
 | 
				
			||||||
 | 
						VIRTIO_ID_9P             = 9  // 9p virtio console
 | 
				
			||||||
 | 
						VIRTIO_ID_MAC80211_WLAN  = 10 // virtio WLAN MAC
 | 
				
			||||||
 | 
						VIRTIO_ID_RPROC_SERIAL   = 11 // virtio remoteproc serial link
 | 
				
			||||||
 | 
						VIRTIO_ID_CAIF           = 12 // Virtio caif
 | 
				
			||||||
 | 
						VIRTIO_ID_MEMORY_BALLOON = 13 // virtio memory balloon
 | 
				
			||||||
 | 
						VIRTIO_ID_GPU            = 16 // virtio GPU
 | 
				
			||||||
 | 
						VIRTIO_ID_CLOCK          = 17 // virtio clock/timer
 | 
				
			||||||
 | 
						VIRTIO_ID_INPUT          = 18 // virtio input
 | 
				
			||||||
 | 
						VIRTIO_ID_VSOCK          = 19 // virtio vsock transport
 | 
				
			||||||
 | 
						VIRTIO_ID_CRYPTO         = 20 // virtio crypto
 | 
				
			||||||
 | 
						VIRTIO_ID_SIGNAL_DIST    = 21 // virtio signal distribution device
 | 
				
			||||||
 | 
						VIRTIO_ID_PSTORE         = 22 // virtio pstore device
 | 
				
			||||||
 | 
						VIRTIO_ID_IOMMU          = 23 // virtio IOMMU
 | 
				
			||||||
 | 
						VIRTIO_ID_MEM            = 24 // virtio mem
 | 
				
			||||||
 | 
						VIRTIO_ID_SOUND          = 25 // virtio sound
 | 
				
			||||||
 | 
						VIRTIO_ID_FS             = 26 // virtio filesystem
 | 
				
			||||||
 | 
						VIRTIO_ID_PMEM           = 27 // virtio pmem
 | 
				
			||||||
 | 
						VIRTIO_ID_RPMB           = 28 // virtio rpmb
 | 
				
			||||||
 | 
						VIRTIO_ID_MAC80211_HWSIM = 29 // virtio mac80211-hwsim
 | 
				
			||||||
 | 
						VIRTIO_ID_VIDEO_ENCODER  = 30 // virtio video encoder
 | 
				
			||||||
 | 
						VIRTIO_ID_VIDEO_DECODER  = 31 // virtio video decoder
 | 
				
			||||||
 | 
						VIRTIO_ID_SCMI           = 32 // virtio SCMI
 | 
				
			||||||
 | 
						VIRTIO_ID_NITRO_SEC_MOD  = 33 // virtio nitro secure module
 | 
				
			||||||
 | 
						VIRTIO_ID_I2C_ADAPTER    = 34 // virtio i2c adapter
 | 
				
			||||||
 | 
						VIRTIO_ID_WATCHDOG       = 35 // virtio watchdog
 | 
				
			||||||
 | 
						VIRTIO_ID_CAN            = 36 // virtio can
 | 
				
			||||||
 | 
						VIRTIO_ID_DMABUF         = 37 // virtio dmabuf
 | 
				
			||||||
 | 
						VIRTIO_ID_PARAM_SERV     = 38 // virtio parameter server
 | 
				
			||||||
 | 
						VIRTIO_ID_AUDIO_POLICY   = 39 // virtio audio policy
 | 
				
			||||||
 | 
						VIRTIO_ID_BT             = 40 // virtio bluetooth
 | 
				
			||||||
 | 
						VIRTIO_ID_GPIO           = 41 // virtio gpio
 | 
				
			||||||
 | 
						// Virtio Transitional IDs
 | 
				
			||||||
 | 
						VIRTIO_TRANS_ID_NET     = 0x1000 // transitional virtio net
 | 
				
			||||||
 | 
						VIRTIO_TRANS_ID_BLOCK   = 0x1001 // transitional virtio block
 | 
				
			||||||
 | 
						VIRTIO_TRANS_ID_BALLOON = 0x1002 // transitional virtio balloon
 | 
				
			||||||
 | 
						VIRTIO_TRANS_ID_CONSOLE = 0x1003 // transitional virtio console
 | 
				
			||||||
 | 
						VIRTIO_TRANS_ID_SCSI    = 0x1004 // transitional virtio SCSI
 | 
				
			||||||
 | 
						VIRTIO_TRANS_ID_RNG     = 0x1005 // transitional virtio rng
 | 
				
			||||||
 | 
						VIRTIO_TRANS_ID_9P      = 0x1009 // transitional virtio 9p console
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
							
								
								
									
										34
									
								
								vendor/github.com/vishvananda/netlink/xdp_diag.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								vendor/github.com/vishvananda/netlink/xdp_diag.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					package netlink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "github.com/vishvananda/netlink/nl"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const SOCK_ANY_COOKIE = uint64(nl.TCPDIAG_NOCOOKIE)<<32 + uint64(nl.TCPDIAG_NOCOOKIE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// XDP diagnosis show flag constants to request particular information elements.
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						XDP_SHOW_INFO = 1 << iota
 | 
				
			||||||
 | 
						XDP_SHOW_RING_CFG
 | 
				
			||||||
 | 
						XDP_SHOW_UMEM
 | 
				
			||||||
 | 
						XDP_SHOW_MEMINFO
 | 
				
			||||||
 | 
						XDP_SHOW_STATS
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// XDP diag element constants
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						XDP_DIAG_NONE                 = iota
 | 
				
			||||||
 | 
						XDP_DIAG_INFO                 // when using XDP_SHOW_INFO
 | 
				
			||||||
 | 
						XDP_DIAG_UID                  // when using XDP_SHOW_INFO
 | 
				
			||||||
 | 
						XDP_DIAG_RX_RING              // when using XDP_SHOW_RING_CFG
 | 
				
			||||||
 | 
						XDP_DIAG_TX_RING              // when using XDP_SHOW_RING_CFG
 | 
				
			||||||
 | 
						XDP_DIAG_UMEM                 // when using XDP_SHOW_UMEM
 | 
				
			||||||
 | 
						XDP_DIAG_UMEM_FILL_RING       // when using XDP_SHOW_UMEM
 | 
				
			||||||
 | 
						XDP_DIAG_UMEM_COMPLETION_RING // when using XDP_SHOW_UMEM
 | 
				
			||||||
 | 
						XDP_DIAG_MEMINFO              // when using XDP_SHOW_MEMINFO
 | 
				
			||||||
 | 
						XDP_DIAG_STATS                // when using XDP_SHOW_STATS
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// https://elixir.bootlin.com/linux/v6.2/source/include/uapi/linux/xdp_diag.h#L21
 | 
				
			||||||
 | 
					type XDPDiagInfoResp struct {
 | 
				
			||||||
 | 
						XDPDiagMsg *XDPSocket
 | 
				
			||||||
 | 
						XDPInfo    *XDPInfo
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										46
									
								
								vendor/github.com/vishvananda/netlink/xdp_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								vendor/github.com/vishvananda/netlink/xdp_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					package netlink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						xdrDiagUmemLen  = 8 + 8*4
 | 
				
			||||||
 | 
						xdrDiagStatsLen = 6 * 8
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (x *XDPDiagUmem) deserialize(b []byte) error {
 | 
				
			||||||
 | 
						if len(b) < xdrDiagUmemLen {
 | 
				
			||||||
 | 
							return fmt.Errorf("XDP umem diagnosis data short read (%d); want %d", len(b), xdrDiagUmemLen)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rb := bytes.NewBuffer(b)
 | 
				
			||||||
 | 
						x.Size = native.Uint64(rb.Next(8))
 | 
				
			||||||
 | 
						x.ID = native.Uint32(rb.Next(4))
 | 
				
			||||||
 | 
						x.NumPages = native.Uint32(rb.Next(4))
 | 
				
			||||||
 | 
						x.ChunkSize = native.Uint32(rb.Next(4))
 | 
				
			||||||
 | 
						x.Headroom = native.Uint32(rb.Next(4))
 | 
				
			||||||
 | 
						x.Ifindex = native.Uint32(rb.Next(4))
 | 
				
			||||||
 | 
						x.QueueID = native.Uint32(rb.Next(4))
 | 
				
			||||||
 | 
						x.Flags = native.Uint32(rb.Next(4))
 | 
				
			||||||
 | 
						x.Refs = native.Uint32(rb.Next(4))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (x *XDPDiagStats) deserialize(b []byte) error {
 | 
				
			||||||
 | 
						if len(b) < xdrDiagStatsLen {
 | 
				
			||||||
 | 
							return fmt.Errorf("XDP diagnosis statistics short read (%d); want %d", len(b), xdrDiagStatsLen)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rb := bytes.NewBuffer(b)
 | 
				
			||||||
 | 
						x.RxDropped = native.Uint64(rb.Next(8))
 | 
				
			||||||
 | 
						x.RxInvalid = native.Uint64(rb.Next(8))
 | 
				
			||||||
 | 
						x.RxFull = native.Uint64(rb.Next(8))
 | 
				
			||||||
 | 
						x.FillRingEmpty = native.Uint64(rb.Next(8))
 | 
				
			||||||
 | 
						x.TxInvalid = native.Uint64(rb.Next(8))
 | 
				
			||||||
 | 
						x.TxRingEmpty = native.Uint64(rb.Next(8))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -14,7 +14,7 @@ const (
 | 
				
			|||||||
	XFRM_PROTO_ESP       Proto = unix.IPPROTO_ESP
 | 
						XFRM_PROTO_ESP       Proto = unix.IPPROTO_ESP
 | 
				
			||||||
	XFRM_PROTO_AH        Proto = unix.IPPROTO_AH
 | 
						XFRM_PROTO_AH        Proto = unix.IPPROTO_AH
 | 
				
			||||||
	XFRM_PROTO_HAO       Proto = unix.IPPROTO_DSTOPTS
 | 
						XFRM_PROTO_HAO       Proto = unix.IPPROTO_DSTOPTS
 | 
				
			||||||
	XFRM_PROTO_COMP      Proto = 0x6c // NOTE not defined on darwin
 | 
						XFRM_PROTO_COMP      Proto = unix.IPPROTO_COMP
 | 
				
			||||||
	XFRM_PROTO_IPSEC_ANY Proto = unix.IPPROTO_RAW
 | 
						XFRM_PROTO_IPSEC_ANY Proto = unix.IPPROTO_RAW
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										96
									
								
								vendor/github.com/vishvananda/netlink/xfrm_policy.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										96
									
								
								vendor/github.com/vishvananda/netlink/xfrm_policy.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,96 +0,0 @@
 | 
				
			|||||||
package netlink
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"net"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Dir is an enum representing an ipsec template direction.
 | 
					 | 
				
			||||||
type Dir uint8
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	XFRM_DIR_IN Dir = iota
 | 
					 | 
				
			||||||
	XFRM_DIR_OUT
 | 
					 | 
				
			||||||
	XFRM_DIR_FWD
 | 
					 | 
				
			||||||
	XFRM_SOCKET_IN
 | 
					 | 
				
			||||||
	XFRM_SOCKET_OUT
 | 
					 | 
				
			||||||
	XFRM_SOCKET_FWD
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (d Dir) String() string {
 | 
					 | 
				
			||||||
	switch d {
 | 
					 | 
				
			||||||
	case XFRM_DIR_IN:
 | 
					 | 
				
			||||||
		return "dir in"
 | 
					 | 
				
			||||||
	case XFRM_DIR_OUT:
 | 
					 | 
				
			||||||
		return "dir out"
 | 
					 | 
				
			||||||
	case XFRM_DIR_FWD:
 | 
					 | 
				
			||||||
		return "dir fwd"
 | 
					 | 
				
			||||||
	case XFRM_SOCKET_IN:
 | 
					 | 
				
			||||||
		return "socket in"
 | 
					 | 
				
			||||||
	case XFRM_SOCKET_OUT:
 | 
					 | 
				
			||||||
		return "socket out"
 | 
					 | 
				
			||||||
	case XFRM_SOCKET_FWD:
 | 
					 | 
				
			||||||
		return "socket fwd"
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	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.
 | 
					 | 
				
			||||||
type XfrmPolicyTmpl struct {
 | 
					 | 
				
			||||||
	Dst   net.IP
 | 
					 | 
				
			||||||
	Src   net.IP
 | 
					 | 
				
			||||||
	Proto Proto
 | 
					 | 
				
			||||||
	Mode  Mode
 | 
					 | 
				
			||||||
	Spi   int
 | 
					 | 
				
			||||||
	Reqid int
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (t XfrmPolicyTmpl) String() string {
 | 
					 | 
				
			||||||
	return fmt.Sprintf("{Dst: %v, Src: %v, Proto: %s, Mode: %s, Spi: 0x%x, Reqid: 0x%x}",
 | 
					 | 
				
			||||||
		t.Dst, t.Src, t.Proto, t.Mode, t.Spi, t.Reqid)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// XfrmPolicy represents an ipsec policy. It represents the overlay network
 | 
					 | 
				
			||||||
// and has a list of XfrmPolicyTmpls representing the base addresses of
 | 
					 | 
				
			||||||
// the policy.
 | 
					 | 
				
			||||||
type XfrmPolicy struct {
 | 
					 | 
				
			||||||
	Dst      *net.IPNet
 | 
					 | 
				
			||||||
	Src      *net.IPNet
 | 
					 | 
				
			||||||
	Proto    Proto
 | 
					 | 
				
			||||||
	DstPort  int
 | 
					 | 
				
			||||||
	SrcPort  int
 | 
					 | 
				
			||||||
	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, 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)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										105
									
								
								vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										105
									
								
								vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,10 +1,104 @@
 | 
				
			|||||||
package netlink
 | 
					package netlink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/vishvananda/netlink/nl"
 | 
						"github.com/vishvananda/netlink/nl"
 | 
				
			||||||
	"golang.org/x/sys/unix"
 | 
						"golang.org/x/sys/unix"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Dir is an enum representing an ipsec template direction.
 | 
				
			||||||
 | 
					type Dir uint8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						XFRM_DIR_IN Dir = iota
 | 
				
			||||||
 | 
						XFRM_DIR_OUT
 | 
				
			||||||
 | 
						XFRM_DIR_FWD
 | 
				
			||||||
 | 
						XFRM_SOCKET_IN
 | 
				
			||||||
 | 
						XFRM_SOCKET_OUT
 | 
				
			||||||
 | 
						XFRM_SOCKET_FWD
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (d Dir) String() string {
 | 
				
			||||||
 | 
						switch d {
 | 
				
			||||||
 | 
						case XFRM_DIR_IN:
 | 
				
			||||||
 | 
							return "dir in"
 | 
				
			||||||
 | 
						case XFRM_DIR_OUT:
 | 
				
			||||||
 | 
							return "dir out"
 | 
				
			||||||
 | 
						case XFRM_DIR_FWD:
 | 
				
			||||||
 | 
							return "dir fwd"
 | 
				
			||||||
 | 
						case XFRM_SOCKET_IN:
 | 
				
			||||||
 | 
							return "socket in"
 | 
				
			||||||
 | 
						case XFRM_SOCKET_OUT:
 | 
				
			||||||
 | 
							return "socket out"
 | 
				
			||||||
 | 
						case XFRM_SOCKET_FWD:
 | 
				
			||||||
 | 
							return "socket fwd"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						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.
 | 
				
			||||||
 | 
					type XfrmPolicyTmpl struct {
 | 
				
			||||||
 | 
						Dst      net.IP
 | 
				
			||||||
 | 
						Src      net.IP
 | 
				
			||||||
 | 
						Proto    Proto
 | 
				
			||||||
 | 
						Mode     Mode
 | 
				
			||||||
 | 
						Spi      int
 | 
				
			||||||
 | 
						Reqid    int
 | 
				
			||||||
 | 
						Optional int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (t XfrmPolicyTmpl) String() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("{Dst: %v, Src: %v, Proto: %s, Mode: %s, Spi: 0x%x, Reqid: 0x%x}",
 | 
				
			||||||
 | 
							t.Dst, t.Src, t.Proto, t.Mode, t.Spi, t.Reqid)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// XfrmPolicy represents an ipsec policy. It represents the overlay network
 | 
				
			||||||
 | 
					// and has a list of XfrmPolicyTmpls representing the base addresses of
 | 
				
			||||||
 | 
					// the policy.
 | 
				
			||||||
 | 
					type XfrmPolicy struct {
 | 
				
			||||||
 | 
						Dst      *net.IPNet
 | 
				
			||||||
 | 
						Src      *net.IPNet
 | 
				
			||||||
 | 
						Proto    Proto
 | 
				
			||||||
 | 
						DstPort  int
 | 
				
			||||||
 | 
						SrcPort  int
 | 
				
			||||||
 | 
						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, 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)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func selFromPolicy(sel *nl.XfrmSelector, policy *XfrmPolicy) {
 | 
					func selFromPolicy(sel *nl.XfrmSelector, policy *XfrmPolicy) {
 | 
				
			||||||
	sel.Family = uint16(nl.FAMILY_V4)
 | 
						sel.Family = uint16(nl.FAMILY_V4)
 | 
				
			||||||
	if policy.Dst != nil {
 | 
						if policy.Dst != nil {
 | 
				
			||||||
@@ -75,10 +169,12 @@ func (h *Handle) xfrmPolicyAddOrUpdate(policy *XfrmPolicy, nlProto int) error {
 | 
				
			|||||||
		userTmpl := nl.DeserializeXfrmUserTmpl(tmplData[start : start+nl.SizeofXfrmUserTmpl])
 | 
							userTmpl := nl.DeserializeXfrmUserTmpl(tmplData[start : start+nl.SizeofXfrmUserTmpl])
 | 
				
			||||||
		userTmpl.XfrmId.Daddr.FromIP(tmpl.Dst)
 | 
							userTmpl.XfrmId.Daddr.FromIP(tmpl.Dst)
 | 
				
			||||||
		userTmpl.Saddr.FromIP(tmpl.Src)
 | 
							userTmpl.Saddr.FromIP(tmpl.Src)
 | 
				
			||||||
 | 
							userTmpl.Family = uint16(nl.GetIPFamily(tmpl.Dst))
 | 
				
			||||||
		userTmpl.XfrmId.Proto = uint8(tmpl.Proto)
 | 
							userTmpl.XfrmId.Proto = uint8(tmpl.Proto)
 | 
				
			||||||
		userTmpl.XfrmId.Spi = nl.Swap32(uint32(tmpl.Spi))
 | 
							userTmpl.XfrmId.Spi = nl.Swap32(uint32(tmpl.Spi))
 | 
				
			||||||
		userTmpl.Mode = uint8(tmpl.Mode)
 | 
							userTmpl.Mode = uint8(tmpl.Mode)
 | 
				
			||||||
		userTmpl.Reqid = uint32(tmpl.Reqid)
 | 
							userTmpl.Reqid = uint32(tmpl.Reqid)
 | 
				
			||||||
 | 
							userTmpl.Optional = uint8(tmpl.Optional)
 | 
				
			||||||
		userTmpl.Aalgos = ^uint32(0)
 | 
							userTmpl.Aalgos = ^uint32(0)
 | 
				
			||||||
		userTmpl.Ealgos = ^uint32(0)
 | 
							userTmpl.Ealgos = ^uint32(0)
 | 
				
			||||||
		userTmpl.Calgos = ^uint32(0)
 | 
							userTmpl.Calgos = ^uint32(0)
 | 
				
			||||||
@@ -92,8 +188,10 @@ func (h *Handle) xfrmPolicyAddOrUpdate(policy *XfrmPolicy, nlProto int) error {
 | 
				
			|||||||
		req.AddData(out)
 | 
							req.AddData(out)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if policy.Ifid != 0 {
 | 
				
			||||||
		ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(policy.Ifid)))
 | 
							ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(policy.Ifid)))
 | 
				
			||||||
		req.AddData(ifId)
 | 
							req.AddData(ifId)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err := req.Execute(unix.NETLINK_XFRM, 0)
 | 
						_, err := req.Execute(unix.NETLINK_XFRM, 0)
 | 
				
			||||||
	return err
 | 
						return err
 | 
				
			||||||
@@ -188,8 +286,10 @@ func (h *Handle) xfrmPolicyGetOrDelete(policy *XfrmPolicy, nlProto int) (*XfrmPo
 | 
				
			|||||||
		req.AddData(out)
 | 
							req.AddData(out)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if policy.Ifid != 0 {
 | 
				
			||||||
		ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(policy.Ifid)))
 | 
							ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(policy.Ifid)))
 | 
				
			||||||
		req.AddData(ifId)
 | 
							req.AddData(ifId)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	resType := nl.XFRM_MSG_NEWPOLICY
 | 
						resType := nl.XFRM_MSG_NEWPOLICY
 | 
				
			||||||
	if nlProto == nl.XFRM_MSG_DELPOLICY {
 | 
						if nlProto == nl.XFRM_MSG_DELPOLICY {
 | 
				
			||||||
@@ -218,8 +318,8 @@ func parseXfrmPolicy(m []byte, family int) (*XfrmPolicy, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	var policy XfrmPolicy
 | 
						var policy XfrmPolicy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	policy.Dst = msg.Sel.Daddr.ToIPNet(msg.Sel.PrefixlenD)
 | 
						policy.Dst = msg.Sel.Daddr.ToIPNet(msg.Sel.PrefixlenD, uint16(family))
 | 
				
			||||||
	policy.Src = msg.Sel.Saddr.ToIPNet(msg.Sel.PrefixlenS)
 | 
						policy.Src = msg.Sel.Saddr.ToIPNet(msg.Sel.PrefixlenS, uint16(family))
 | 
				
			||||||
	policy.Proto = Proto(msg.Sel.Proto)
 | 
						policy.Proto = Proto(msg.Sel.Proto)
 | 
				
			||||||
	policy.DstPort = int(nl.Swap16(msg.Sel.Dport))
 | 
						policy.DstPort = int(nl.Swap16(msg.Sel.Dport))
 | 
				
			||||||
	policy.SrcPort = int(nl.Swap16(msg.Sel.Sport))
 | 
						policy.SrcPort = int(nl.Swap16(msg.Sel.Sport))
 | 
				
			||||||
@@ -247,6 +347,7 @@ func parseXfrmPolicy(m []byte, family int) (*XfrmPolicy, error) {
 | 
				
			|||||||
				resTmpl.Mode = Mode(tmpl.Mode)
 | 
									resTmpl.Mode = Mode(tmpl.Mode)
 | 
				
			||||||
				resTmpl.Spi = int(nl.Swap32(tmpl.XfrmId.Spi))
 | 
									resTmpl.Spi = int(nl.Swap32(tmpl.XfrmId.Spi))
 | 
				
			||||||
				resTmpl.Reqid = int(tmpl.Reqid)
 | 
									resTmpl.Reqid = int(tmpl.Reqid)
 | 
				
			||||||
 | 
									resTmpl.Optional = int(tmpl.Optional)
 | 
				
			||||||
				policy.Tmpls = append(policy.Tmpls, resTmpl)
 | 
									policy.Tmpls = append(policy.Tmpls, resTmpl)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		case nl.XFRMA_MARK:
 | 
							case nl.XFRMA_MARK:
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										131
									
								
								vendor/github.com/vishvananda/netlink/xfrm_state.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										131
									
								
								vendor/github.com/vishvananda/netlink/xfrm_state.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,131 +0,0 @@
 | 
				
			|||||||
package netlink
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"net"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// XfrmStateAlgo represents the algorithm to use for the ipsec encryption.
 | 
					 | 
				
			||||||
type XfrmStateAlgo struct {
 | 
					 | 
				
			||||||
	Name        string
 | 
					 | 
				
			||||||
	Key         []byte
 | 
					 | 
				
			||||||
	TruncateLen int // Auth only
 | 
					 | 
				
			||||||
	ICVLen      int // AEAD only
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (a XfrmStateAlgo) String() string {
 | 
					 | 
				
			||||||
	base := fmt.Sprintf("{Name: %s, Key: 0x%x", a.Name, a.Key)
 | 
					 | 
				
			||||||
	if a.TruncateLen != 0 {
 | 
					 | 
				
			||||||
		base = fmt.Sprintf("%s, Truncate length: %d", base, a.TruncateLen)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if a.ICVLen != 0 {
 | 
					 | 
				
			||||||
		base = fmt.Sprintf("%s, ICV length: %d", base, a.ICVLen)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return fmt.Sprintf("%s}", base)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// EncapType is an enum representing the optional packet encapsulation.
 | 
					 | 
				
			||||||
type EncapType uint8
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	XFRM_ENCAP_ESPINUDP_NONIKE EncapType = iota + 1
 | 
					 | 
				
			||||||
	XFRM_ENCAP_ESPINUDP
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e EncapType) String() string {
 | 
					 | 
				
			||||||
	switch e {
 | 
					 | 
				
			||||||
	case XFRM_ENCAP_ESPINUDP_NONIKE:
 | 
					 | 
				
			||||||
		return "espinudp-non-ike"
 | 
					 | 
				
			||||||
	case XFRM_ENCAP_ESPINUDP:
 | 
					 | 
				
			||||||
		return "espinudp"
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return "unknown"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// XfrmStateEncap represents the encapsulation to use for the ipsec encryption.
 | 
					 | 
				
			||||||
type XfrmStateEncap struct {
 | 
					 | 
				
			||||||
	Type            EncapType
 | 
					 | 
				
			||||||
	SrcPort         int
 | 
					 | 
				
			||||||
	DstPort         int
 | 
					 | 
				
			||||||
	OriginalAddress net.IP
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (e XfrmStateEncap) String() string {
 | 
					 | 
				
			||||||
	return fmt.Sprintf("{Type: %s, Srcport: %d, DstPort: %d, OriginalAddress: %v}",
 | 
					 | 
				
			||||||
		e.Type, e.SrcPort, e.DstPort, e.OriginalAddress)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// XfrmStateLimits represents the configured limits for the state.
 | 
					 | 
				
			||||||
type XfrmStateLimits struct {
 | 
					 | 
				
			||||||
	ByteSoft    uint64
 | 
					 | 
				
			||||||
	ByteHard    uint64
 | 
					 | 
				
			||||||
	PacketSoft  uint64
 | 
					 | 
				
			||||||
	PacketHard  uint64
 | 
					 | 
				
			||||||
	TimeSoft    uint64
 | 
					 | 
				
			||||||
	TimeHard    uint64
 | 
					 | 
				
			||||||
	TimeUseSoft uint64
 | 
					 | 
				
			||||||
	TimeUseHard uint64
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// XfrmStateStats represents the current number of bytes/packets
 | 
					 | 
				
			||||||
// processed by this State, the State's installation and first use
 | 
					 | 
				
			||||||
// time and the replay window counters.
 | 
					 | 
				
			||||||
type XfrmStateStats struct {
 | 
					 | 
				
			||||||
	ReplayWindow uint32
 | 
					 | 
				
			||||||
	Replay       uint32
 | 
					 | 
				
			||||||
	Failed       uint32
 | 
					 | 
				
			||||||
	Bytes        uint64
 | 
					 | 
				
			||||||
	Packets      uint64
 | 
					 | 
				
			||||||
	AddTime      uint64
 | 
					 | 
				
			||||||
	UseTime      uint64
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// XfrmState represents the state of an ipsec policy. It optionally
 | 
					 | 
				
			||||||
// contains an XfrmStateAlgo for encryption and one for authentication.
 | 
					 | 
				
			||||||
type XfrmState struct {
 | 
					 | 
				
			||||||
	Dst          net.IP
 | 
					 | 
				
			||||||
	Src          net.IP
 | 
					 | 
				
			||||||
	Proto        Proto
 | 
					 | 
				
			||||||
	Mode         Mode
 | 
					 | 
				
			||||||
	Spi          int
 | 
					 | 
				
			||||||
	Reqid        int
 | 
					 | 
				
			||||||
	ReplayWindow int
 | 
					 | 
				
			||||||
	Limits       XfrmStateLimits
 | 
					 | 
				
			||||||
	Statistics   XfrmStateStats
 | 
					 | 
				
			||||||
	Mark         *XfrmMark
 | 
					 | 
				
			||||||
	OutputMark   int
 | 
					 | 
				
			||||||
	Ifid         int
 | 
					 | 
				
			||||||
	Auth         *XfrmStateAlgo
 | 
					 | 
				
			||||||
	Crypt        *XfrmStateAlgo
 | 
					 | 
				
			||||||
	Aead         *XfrmStateAlgo
 | 
					 | 
				
			||||||
	Encap        *XfrmStateEncap
 | 
					 | 
				
			||||||
	ESN          bool
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (sa XfrmState) String() string {
 | 
					 | 
				
			||||||
	return fmt.Sprintf("Dst: %v, Src: %v, Proto: %s, Mode: %s, SPI: 0x%x, ReqID: 0x%x, ReplayWindow: %d, Mark: %v, 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 {
 | 
					 | 
				
			||||||
		return sa.String()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	at := time.Unix(int64(sa.Statistics.AddTime), 0).Format(time.UnixDate)
 | 
					 | 
				
			||||||
	ut := "-"
 | 
					 | 
				
			||||||
	if sa.Statistics.UseTime > 0 {
 | 
					 | 
				
			||||||
		ut = time.Unix(int64(sa.Statistics.UseTime), 0).Format(time.UnixDate)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return fmt.Sprintf("%s, ByteSoft: %s, ByteHard: %s, PacketSoft: %s, PacketHard: %s, TimeSoft: %d, TimeHard: %d, TimeUseSoft: %d, TimeUseHard: %d, Bytes: %d, Packets: %d, "+
 | 
					 | 
				
			||||||
		"AddTime: %s, UseTime: %s, ReplayWindow: %d, Replay: %d, Failed: %d",
 | 
					 | 
				
			||||||
		sa.String(), printLimit(sa.Limits.ByteSoft), printLimit(sa.Limits.ByteHard), printLimit(sa.Limits.PacketSoft), printLimit(sa.Limits.PacketHard),
 | 
					 | 
				
			||||||
		sa.Limits.TimeSoft, sa.Limits.TimeHard, sa.Limits.TimeUseSoft, sa.Limits.TimeUseHard, sa.Statistics.Bytes, sa.Statistics.Packets, at, ut,
 | 
					 | 
				
			||||||
		sa.Statistics.ReplayWindow, sa.Statistics.Replay, sa.Statistics.Failed)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func printLimit(lmt uint64) string {
 | 
					 | 
				
			||||||
	if lmt == ^uint64(0) {
 | 
					 | 
				
			||||||
		return "(INF)"
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return fmt.Sprintf("%d", lmt)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										228
									
								
								vendor/github.com/vishvananda/netlink/xfrm_state_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										228
									
								
								vendor/github.com/vishvananda/netlink/xfrm_state_linux.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -2,12 +2,154 @@ package netlink
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
	"unsafe"
 | 
						"unsafe"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/vishvananda/netlink/nl"
 | 
						"github.com/vishvananda/netlink/nl"
 | 
				
			||||||
	"golang.org/x/sys/unix"
 | 
						"golang.org/x/sys/unix"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// XfrmStateAlgo represents the algorithm to use for the ipsec encryption.
 | 
				
			||||||
 | 
					type XfrmStateAlgo struct {
 | 
				
			||||||
 | 
						Name        string
 | 
				
			||||||
 | 
						Key         []byte
 | 
				
			||||||
 | 
						TruncateLen int // Auth only
 | 
				
			||||||
 | 
						ICVLen      int // AEAD only
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (a XfrmStateAlgo) String() string {
 | 
				
			||||||
 | 
						base := fmt.Sprintf("{Name: %s, Key: 0x%x", a.Name, a.Key)
 | 
				
			||||||
 | 
						if a.TruncateLen != 0 {
 | 
				
			||||||
 | 
							base = fmt.Sprintf("%s, Truncate length: %d", base, a.TruncateLen)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if a.ICVLen != 0 {
 | 
				
			||||||
 | 
							base = fmt.Sprintf("%s, ICV length: %d", base, a.ICVLen)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return fmt.Sprintf("%s}", base)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// EncapType is an enum representing the optional packet encapsulation.
 | 
				
			||||||
 | 
					type EncapType uint8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						XFRM_ENCAP_ESPINUDP_NONIKE EncapType = iota + 1
 | 
				
			||||||
 | 
						XFRM_ENCAP_ESPINUDP
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e EncapType) String() string {
 | 
				
			||||||
 | 
						switch e {
 | 
				
			||||||
 | 
						case XFRM_ENCAP_ESPINUDP_NONIKE:
 | 
				
			||||||
 | 
							return "espinudp-non-ike"
 | 
				
			||||||
 | 
						case XFRM_ENCAP_ESPINUDP:
 | 
				
			||||||
 | 
							return "espinudp"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return "unknown"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// XfrmStateEncap represents the encapsulation to use for the ipsec encryption.
 | 
				
			||||||
 | 
					type XfrmStateEncap struct {
 | 
				
			||||||
 | 
						Type            EncapType
 | 
				
			||||||
 | 
						SrcPort         int
 | 
				
			||||||
 | 
						DstPort         int
 | 
				
			||||||
 | 
						OriginalAddress net.IP
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e XfrmStateEncap) String() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("{Type: %s, Srcport: %d, DstPort: %d, OriginalAddress: %v}",
 | 
				
			||||||
 | 
							e.Type, e.SrcPort, e.DstPort, e.OriginalAddress)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// XfrmStateLimits represents the configured limits for the state.
 | 
				
			||||||
 | 
					type XfrmStateLimits struct {
 | 
				
			||||||
 | 
						ByteSoft    uint64
 | 
				
			||||||
 | 
						ByteHard    uint64
 | 
				
			||||||
 | 
						PacketSoft  uint64
 | 
				
			||||||
 | 
						PacketHard  uint64
 | 
				
			||||||
 | 
						TimeSoft    uint64
 | 
				
			||||||
 | 
						TimeHard    uint64
 | 
				
			||||||
 | 
						TimeUseSoft uint64
 | 
				
			||||||
 | 
						TimeUseHard uint64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// XfrmStateStats represents the current number of bytes/packets
 | 
				
			||||||
 | 
					// processed by this State, the State's installation and first use
 | 
				
			||||||
 | 
					// time and the replay window counters.
 | 
				
			||||||
 | 
					type XfrmStateStats struct {
 | 
				
			||||||
 | 
						ReplayWindow uint32
 | 
				
			||||||
 | 
						Replay       uint32
 | 
				
			||||||
 | 
						Failed       uint32
 | 
				
			||||||
 | 
						Bytes        uint64
 | 
				
			||||||
 | 
						Packets      uint64
 | 
				
			||||||
 | 
						AddTime      uint64
 | 
				
			||||||
 | 
						UseTime      uint64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// XfrmReplayState represents the sequence number states for
 | 
				
			||||||
 | 
					// "legacy" anti-replay mode.
 | 
				
			||||||
 | 
					type XfrmReplayState struct {
 | 
				
			||||||
 | 
						OSeq   uint32
 | 
				
			||||||
 | 
						Seq    uint32
 | 
				
			||||||
 | 
						BitMap uint32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r XfrmReplayState) String() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("{OSeq: 0x%x, Seq: 0x%x, BitMap: 0x%x}",
 | 
				
			||||||
 | 
							r.OSeq, r.Seq, r.BitMap)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// XfrmState represents the state of an ipsec policy. It optionally
 | 
				
			||||||
 | 
					// contains an XfrmStateAlgo for encryption and one for authentication.
 | 
				
			||||||
 | 
					type XfrmState struct {
 | 
				
			||||||
 | 
						Dst           net.IP
 | 
				
			||||||
 | 
						Src           net.IP
 | 
				
			||||||
 | 
						Proto         Proto
 | 
				
			||||||
 | 
						Mode          Mode
 | 
				
			||||||
 | 
						Spi           int
 | 
				
			||||||
 | 
						Reqid         int
 | 
				
			||||||
 | 
						ReplayWindow  int
 | 
				
			||||||
 | 
						Limits        XfrmStateLimits
 | 
				
			||||||
 | 
						Statistics    XfrmStateStats
 | 
				
			||||||
 | 
						Mark          *XfrmMark
 | 
				
			||||||
 | 
						OutputMark    *XfrmMark
 | 
				
			||||||
 | 
						Ifid          int
 | 
				
			||||||
 | 
						Auth          *XfrmStateAlgo
 | 
				
			||||||
 | 
						Crypt         *XfrmStateAlgo
 | 
				
			||||||
 | 
						Aead          *XfrmStateAlgo
 | 
				
			||||||
 | 
						Encap         *XfrmStateEncap
 | 
				
			||||||
 | 
						ESN           bool
 | 
				
			||||||
 | 
						DontEncapDSCP bool
 | 
				
			||||||
 | 
						OSeqMayWrap   bool
 | 
				
			||||||
 | 
						Replay        *XfrmReplayState
 | 
				
			||||||
 | 
						Selector      *XfrmPolicy
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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, OutputMark: %v, Ifid: %d, Auth: %v, Crypt: %v, Aead: %v, Encap: %v, ESN: %t, DontEncapDSCP: %t, OSeqMayWrap: %t, Replay: %v",
 | 
				
			||||||
 | 
							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, sa.DontEncapDSCP, sa.OSeqMayWrap, sa.Replay)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					func (sa XfrmState) Print(stats bool) string {
 | 
				
			||||||
 | 
						if !stats {
 | 
				
			||||||
 | 
							return sa.String()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						at := time.Unix(int64(sa.Statistics.AddTime), 0).Format(time.UnixDate)
 | 
				
			||||||
 | 
						ut := "-"
 | 
				
			||||||
 | 
						if sa.Statistics.UseTime > 0 {
 | 
				
			||||||
 | 
							ut = time.Unix(int64(sa.Statistics.UseTime), 0).Format(time.UnixDate)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return fmt.Sprintf("%s, ByteSoft: %s, ByteHard: %s, PacketSoft: %s, PacketHard: %s, TimeSoft: %d, TimeHard: %d, TimeUseSoft: %d, TimeUseHard: %d, Bytes: %d, Packets: %d, "+
 | 
				
			||||||
 | 
							"AddTime: %s, UseTime: %s, ReplayWindow: %d, Replay: %d, Failed: %d",
 | 
				
			||||||
 | 
							sa.String(), printLimit(sa.Limits.ByteSoft), printLimit(sa.Limits.ByteHard), printLimit(sa.Limits.PacketSoft), printLimit(sa.Limits.PacketHard),
 | 
				
			||||||
 | 
							sa.Limits.TimeSoft, sa.Limits.TimeHard, sa.Limits.TimeUseSoft, sa.Limits.TimeUseHard, sa.Statistics.Bytes, sa.Statistics.Packets, at, ut,
 | 
				
			||||||
 | 
							sa.Statistics.ReplayWindow, sa.Statistics.Replay, sa.Statistics.Failed)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func printLimit(lmt uint64) string {
 | 
				
			||||||
 | 
						if lmt == ^uint64(0) {
 | 
				
			||||||
 | 
							return "(INF)"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return fmt.Sprintf("%d", lmt)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
func writeStateAlgo(a *XfrmStateAlgo) []byte {
 | 
					func writeStateAlgo(a *XfrmStateAlgo) []byte {
 | 
				
			||||||
	algo := nl.XfrmAlgo{
 | 
						algo := nl.XfrmAlgo{
 | 
				
			||||||
		AlgKeyLen: uint32(len(a.Key) * 8),
 | 
							AlgKeyLen: uint32(len(a.Key) * 8),
 | 
				
			||||||
@@ -77,6 +219,14 @@ func writeReplayEsn(replayWindow int) []byte {
 | 
				
			|||||||
	return replayEsn.Serialize()
 | 
						return replayEsn.Serialize()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func writeReplay(r *XfrmReplayState) []byte {
 | 
				
			||||||
 | 
						return (&nl.XfrmReplayState{
 | 
				
			||||||
 | 
							OSeq:   r.OSeq,
 | 
				
			||||||
 | 
							Seq:    r.Seq,
 | 
				
			||||||
 | 
							BitMap: r.BitMap,
 | 
				
			||||||
 | 
						}).Serialize()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// XfrmStateAdd will add an xfrm state to the system.
 | 
					// XfrmStateAdd will add an xfrm state to the system.
 | 
				
			||||||
// Equivalent to: `ip xfrm state add $state`
 | 
					// Equivalent to: `ip xfrm state add $state`
 | 
				
			||||||
func XfrmStateAdd(state *XfrmState) error {
 | 
					func XfrmStateAdd(state *XfrmState) error {
 | 
				
			||||||
@@ -111,7 +261,7 @@ func (h *Handle) xfrmStateAddOrUpdate(state *XfrmState, nlProto int) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// A state with spi 0 can't be deleted so don't allow it to be set
 | 
						// A state with spi 0 can't be deleted so don't allow it to be set
 | 
				
			||||||
	if state.Spi == 0 {
 | 
						if state.Spi == 0 {
 | 
				
			||||||
		return fmt.Errorf("Spi must be set when adding xfrm state.")
 | 
							return fmt.Errorf("Spi must be set when adding xfrm state")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	req := h.newNetlinkRequest(nlProto, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
 | 
						req := h.newNetlinkRequest(nlProto, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -158,13 +308,34 @@ func (h *Handle) xfrmStateAddOrUpdate(state *XfrmState, nlProto int) error {
 | 
				
			|||||||
		out := nl.NewRtAttr(nl.XFRMA_REPLAY_ESN_VAL, writeReplayEsn(state.ReplayWindow))
 | 
							out := nl.NewRtAttr(nl.XFRMA_REPLAY_ESN_VAL, writeReplayEsn(state.ReplayWindow))
 | 
				
			||||||
		req.AddData(out)
 | 
							req.AddData(out)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if state.OutputMark != 0 {
 | 
						if state.OutputMark != nil {
 | 
				
			||||||
		out := nl.NewRtAttr(nl.XFRMA_OUTPUT_MARK, nl.Uint32Attr(uint32(state.OutputMark)))
 | 
							out := nl.NewRtAttr(nl.XFRMA_SET_MARK, nl.Uint32Attr(state.OutputMark.Value))
 | 
				
			||||||
 | 
							req.AddData(out)
 | 
				
			||||||
 | 
							if state.OutputMark.Mask != 0 {
 | 
				
			||||||
 | 
								out = nl.NewRtAttr(nl.XFRMA_SET_MARK_MASK, nl.Uint32Attr(state.OutputMark.Mask))
 | 
				
			||||||
 | 
								req.AddData(out)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if state.OSeqMayWrap || state.DontEncapDSCP {
 | 
				
			||||||
 | 
							var flags uint32
 | 
				
			||||||
 | 
							if state.DontEncapDSCP {
 | 
				
			||||||
 | 
								flags |= nl.XFRM_SA_XFLAG_DONT_ENCAP_DSCP
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if state.OSeqMayWrap {
 | 
				
			||||||
 | 
								flags |= nl.XFRM_SA_XFLAG_OSEQ_MAY_WRAP
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							out := nl.NewRtAttr(nl.XFRMA_SA_EXTRA_FLAGS, nl.Uint32Attr(flags))
 | 
				
			||||||
 | 
							req.AddData(out)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if state.Replay != nil {
 | 
				
			||||||
 | 
							out := nl.NewRtAttr(nl.XFRMA_REPLAY_VAL, writeReplay(state.Replay))
 | 
				
			||||||
		req.AddData(out)
 | 
							req.AddData(out)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if state.Ifid != 0 {
 | 
				
			||||||
		ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(state.Ifid)))
 | 
							ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(state.Ifid)))
 | 
				
			||||||
		req.AddData(ifId)
 | 
							req.AddData(ifId)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err := req.Execute(unix.NETLINK_XFRM, 0)
 | 
						_, err := req.Execute(unix.NETLINK_XFRM, 0)
 | 
				
			||||||
	return err
 | 
						return err
 | 
				
			||||||
@@ -180,7 +351,6 @@ func (h *Handle) xfrmStateAllocSpi(state *XfrmState) (*XfrmState, error) {
 | 
				
			|||||||
	msg.Min = 0x100
 | 
						msg.Min = 0x100
 | 
				
			||||||
	msg.Max = 0xffffffff
 | 
						msg.Max = 0xffffffff
 | 
				
			||||||
	req.AddData(msg)
 | 
						req.AddData(msg)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	if state.Mark != nil {
 | 
						if state.Mark != nil {
 | 
				
			||||||
		out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(state.Mark))
 | 
							out := nl.NewRtAttr(nl.XFRMA_MARK, writeMark(state.Mark))
 | 
				
			||||||
		req.AddData(out)
 | 
							req.AddData(out)
 | 
				
			||||||
@@ -277,8 +447,10 @@ func (h *Handle) xfrmStateGetOrDelete(state *XfrmState, nlProto int) (*XfrmState
 | 
				
			|||||||
		req.AddData(out)
 | 
							req.AddData(out)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if state.Ifid != 0 {
 | 
				
			||||||
		ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(state.Ifid)))
 | 
							ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(state.Ifid)))
 | 
				
			||||||
		req.AddData(ifId)
 | 
							req.AddData(ifId)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	resType := nl.XFRM_MSG_NEWSA
 | 
						resType := nl.XFRM_MSG_NEWSA
 | 
				
			||||||
	if nlProto == nl.XFRM_MSG_DELSA {
 | 
						if nlProto == nl.XFRM_MSG_DELSA {
 | 
				
			||||||
@@ -306,7 +478,6 @@ var familyError = fmt.Errorf("family error")
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func xfrmStateFromXfrmUsersaInfo(msg *nl.XfrmUsersaInfo) *XfrmState {
 | 
					func xfrmStateFromXfrmUsersaInfo(msg *nl.XfrmUsersaInfo) *XfrmState {
 | 
				
			||||||
	var state XfrmState
 | 
						var state XfrmState
 | 
				
			||||||
 | 
					 | 
				
			||||||
	state.Dst = msg.Id.Daddr.ToIP()
 | 
						state.Dst = msg.Id.Daddr.ToIP()
 | 
				
			||||||
	state.Src = msg.Saddr.ToIP()
 | 
						state.Src = msg.Saddr.ToIP()
 | 
				
			||||||
	state.Proto = Proto(msg.Id.Proto)
 | 
						state.Proto = Proto(msg.Id.Proto)
 | 
				
			||||||
@@ -316,20 +487,25 @@ func xfrmStateFromXfrmUsersaInfo(msg *nl.XfrmUsersaInfo) *XfrmState {
 | 
				
			|||||||
	state.ReplayWindow = int(msg.ReplayWindow)
 | 
						state.ReplayWindow = int(msg.ReplayWindow)
 | 
				
			||||||
	lftToLimits(&msg.Lft, &state.Limits)
 | 
						lftToLimits(&msg.Lft, &state.Limits)
 | 
				
			||||||
	curToStats(&msg.Curlft, &msg.Stats, &state.Statistics)
 | 
						curToStats(&msg.Curlft, &msg.Stats, &state.Statistics)
 | 
				
			||||||
 | 
						state.Selector = &XfrmPolicy{
 | 
				
			||||||
 | 
							Dst:     msg.Sel.Daddr.ToIPNet(msg.Sel.PrefixlenD, msg.Sel.Family),
 | 
				
			||||||
 | 
							Src:     msg.Sel.Saddr.ToIPNet(msg.Sel.PrefixlenS, msg.Sel.Family),
 | 
				
			||||||
 | 
							Proto:   Proto(msg.Sel.Proto),
 | 
				
			||||||
 | 
							DstPort: int(nl.Swap16(msg.Sel.Dport)),
 | 
				
			||||||
 | 
							SrcPort: int(nl.Swap16(msg.Sel.Sport)),
 | 
				
			||||||
 | 
							Ifindex: int(msg.Sel.Ifindex),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return &state
 | 
						return &state
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseXfrmState(m []byte, family int) (*XfrmState, error) {
 | 
					func parseXfrmState(m []byte, family int) (*XfrmState, error) {
 | 
				
			||||||
	msg := nl.DeserializeXfrmUsersaInfo(m)
 | 
						msg := nl.DeserializeXfrmUsersaInfo(m)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	// This is mainly for the state dump
 | 
						// This is mainly for the state dump
 | 
				
			||||||
	if family != FAMILY_ALL && family != int(msg.Family) {
 | 
						if family != FAMILY_ALL && family != int(msg.Family) {
 | 
				
			||||||
		return nil, familyError
 | 
							return nil, familyError
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	state := xfrmStateFromXfrmUsersaInfo(msg)
 | 
						state := xfrmStateFromXfrmUsersaInfo(msg)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	attrs, err := nl.ParseRouteAttr(m[nl.SizeofXfrmUsersaInfo:])
 | 
						attrs, err := nl.ParseRouteAttr(m[nl.SizeofXfrmUsersaInfo:])
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
@@ -377,10 +553,37 @@ func parseXfrmState(m []byte, family int) (*XfrmState, error) {
 | 
				
			|||||||
			state.Mark = new(XfrmMark)
 | 
								state.Mark = new(XfrmMark)
 | 
				
			||||||
			state.Mark.Value = mark.Value
 | 
								state.Mark.Value = mark.Value
 | 
				
			||||||
			state.Mark.Mask = mark.Mask
 | 
								state.Mark.Mask = mark.Mask
 | 
				
			||||||
		case nl.XFRMA_OUTPUT_MARK:
 | 
							case nl.XFRMA_SA_EXTRA_FLAGS:
 | 
				
			||||||
			state.OutputMark = int(native.Uint32(attr.Value))
 | 
								flags := native.Uint32(attr.Value)
 | 
				
			||||||
 | 
								if (flags & nl.XFRM_SA_XFLAG_DONT_ENCAP_DSCP) != 0 {
 | 
				
			||||||
 | 
									state.DontEncapDSCP = true
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (flags & nl.XFRM_SA_XFLAG_OSEQ_MAY_WRAP) != 0 {
 | 
				
			||||||
 | 
									state.OSeqMayWrap = true
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							case nl.XFRMA_SET_MARK:
 | 
				
			||||||
 | 
								if state.OutputMark == nil {
 | 
				
			||||||
 | 
									state.OutputMark = new(XfrmMark)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								state.OutputMark.Value = native.Uint32(attr.Value)
 | 
				
			||||||
 | 
							case nl.XFRMA_SET_MARK_MASK:
 | 
				
			||||||
 | 
								if state.OutputMark == nil {
 | 
				
			||||||
 | 
									state.OutputMark = new(XfrmMark)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								state.OutputMark.Mask = native.Uint32(attr.Value)
 | 
				
			||||||
 | 
								if state.OutputMark.Mask == 0xffffffff {
 | 
				
			||||||
 | 
									state.OutputMark.Mask = 0
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		case nl.XFRMA_IF_ID:
 | 
							case nl.XFRMA_IF_ID:
 | 
				
			||||||
			state.Ifid = int(native.Uint32(attr.Value))
 | 
								state.Ifid = int(native.Uint32(attr.Value))
 | 
				
			||||||
 | 
							case nl.XFRMA_REPLAY_VAL:
 | 
				
			||||||
 | 
								if state.Replay == nil {
 | 
				
			||||||
 | 
									state.Replay = new(XfrmReplayState)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								replay := nl.DeserializeXfrmReplayState(attr.Value[:])
 | 
				
			||||||
 | 
								state.Replay.OSeq = replay.OSeq
 | 
				
			||||||
 | 
								state.Replay.Seq = replay.Seq
 | 
				
			||||||
 | 
								state.Replay.BitMap = replay.BitMap
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -457,6 +660,9 @@ func xfrmUsersaInfoFromXfrmState(state *XfrmState) *nl.XfrmUsersaInfo {
 | 
				
			|||||||
	msg.Id.Spi = nl.Swap32(uint32(state.Spi))
 | 
						msg.Id.Spi = nl.Swap32(uint32(state.Spi))
 | 
				
			||||||
	msg.Reqid = uint32(state.Reqid)
 | 
						msg.Reqid = uint32(state.Reqid)
 | 
				
			||||||
	msg.ReplayWindow = uint8(state.ReplayWindow)
 | 
						msg.ReplayWindow = uint8(state.ReplayWindow)
 | 
				
			||||||
 | 
						msg.Sel = nl.XfrmSelector{}
 | 
				
			||||||
 | 
						if state.Selector != nil {
 | 
				
			||||||
 | 
							selFromPolicy(&msg.Sel, state.Selector)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return msg
 | 
						return msg
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								vendor/github.com/vishvananda/netlink/xfrm_unspecified.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/vishvananda/netlink/xfrm_unspecified.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					//go:build !linux
 | 
				
			||||||
 | 
					// +build !linux
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package netlink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type XfrmPolicy struct{}
 | 
				
			||||||
 | 
					type XfrmState struct{}
 | 
				
			||||||
							
								
								
									
										2
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							@@ -606,7 +606,7 @@ github.com/syndtr/gocapability/capability
 | 
				
			|||||||
# github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75
 | 
					# github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75
 | 
				
			||||||
## explicit; go 1.15
 | 
					## explicit; go 1.15
 | 
				
			||||||
github.com/tmc/grpc-websocket-proxy/wsproxy
 | 
					github.com/tmc/grpc-websocket-proxy/wsproxy
 | 
				
			||||||
# github.com/vishvananda/netlink v1.1.0
 | 
					# github.com/vishvananda/netlink v1.3.0
 | 
				
			||||||
## explicit; go 1.12
 | 
					## explicit; go 1.12
 | 
				
			||||||
github.com/vishvananda/netlink
 | 
					github.com/vishvananda/netlink
 | 
				
			||||||
github.com/vishvananda/netlink/nl
 | 
					github.com/vishvananda/netlink/nl
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user