mirror of
https://github.com/optim-enterprises-bv/kubernetes.git
synced 2025-11-03 19:58:17 +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()))
|
||||||
|
|||||||
930
vendor/github.com/vishvananda/netlink/route_linux.go
generated
vendored
930
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
|
||||||
|
}
|
||||||
|
|||||||
472
vendor/github.com/vishvananda/netlink/socket_linux.go
generated
vendored
472
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)
|
|
||||||
}
|
}
|
||||||
if len(msgs) == 0 {
|
|
||||||
return nil, errors.New("no message nor error from netlink")
|
// 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)
|
||||||
}
|
}
|
||||||
if len(msgs) > 2 {
|
|
||||||
return nil, fmt.Errorf("multiple (%d) matching sockets", len(msgs))
|
// 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
|
||||||
}
|
}
|
||||||
sock := &Socket{}
|
result = append(result, sockInfo)
|
||||||
if err := sock.deserialize(msgs[0].Data); err != nil {
|
return true
|
||||||
|
})
|
||||||
|
if 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