1
vendor/github.com/vishvananda/netlink/.gitignore
generated
vendored
Normal file
1
vendor/github.com/vishvananda/netlink/.gitignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.idea/
|
||||
9
vendor/github.com/vishvananda/netlink/.travis.yml
generated
vendored
9
vendor/github.com/vishvananda/netlink/.travis.yml
generated
vendored
@@ -1,4 +1,8 @@
|
||||
language: go
|
||||
go:
|
||||
- "1.12.x"
|
||||
- "1.13.x"
|
||||
- "1.14.x"
|
||||
before_script:
|
||||
# make sure we keep path in tact when we sudo
|
||||
- sudo sed -i -e 's/^Defaults\tsecure_path.*$//' /etc/sudoers
|
||||
@@ -9,5 +13,8 @@ before_script:
|
||||
- sudo modprobe nf_conntrack_netlink
|
||||
- sudo modprobe nf_conntrack_ipv4
|
||||
- sudo modprobe nf_conntrack_ipv6
|
||||
- sudo modprobe sch_hfsc
|
||||
- sudo modprobe sch_sfq
|
||||
install:
|
||||
- go get github.com/vishvananda/netns
|
||||
- go get -v -t ./...
|
||||
go_import_path: github.com/vishvananda/netlink
|
||||
|
||||
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
|
||||
PreferedLft int
|
||||
ValidLft int
|
||||
LinkIndex int
|
||||
}
|
||||
|
||||
// String returns $ip/$netmask $label
|
||||
|
||||
140
vendor/github.com/vishvananda/netlink/addr_linux.go
generated
vendored
140
vendor/github.com/vishvananda/netlink/addr_linux.go
generated
vendored
@@ -11,43 +11,63 @@ import (
|
||||
"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.
|
||||
//
|
||||
// Equivalent to: `ip addr add $addr dev $link`
|
||||
//
|
||||
// If `addr` is an IPv4 address and the broadcast address is not given, it
|
||||
// will be automatically computed based on the IP mask if /30 or larger.
|
||||
func AddrAdd(link Link, addr *Addr) error {
|
||||
return pkgHandle.AddrAdd(link, addr)
|
||||
}
|
||||
|
||||
// AddrAdd will add an IP address to a link device.
|
||||
//
|
||||
// Equivalent to: `ip addr add $addr dev $link`
|
||||
//
|
||||
// If `addr` is an IPv4 address and the broadcast address is not given, it
|
||||
// will be automatically computed based on the IP mask if /30 or larger.
|
||||
func (h *Handle) AddrAdd(link Link, addr *Addr) error {
|
||||
req := h.newNetlinkRequest(unix.RTM_NEWADDR, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
|
||||
return h.addrHandle(link, addr, req)
|
||||
}
|
||||
|
||||
// AddrReplace will replace (or, if not present, add) an IP address on a link device.
|
||||
//
|
||||
// Equivalent to: `ip addr replace $addr dev $link`
|
||||
//
|
||||
// If `addr` is an IPv4 address and the broadcast address is not given, it
|
||||
// will be automatically computed based on the IP mask if /30 or larger.
|
||||
func AddrReplace(link Link, addr *Addr) error {
|
||||
return pkgHandle.AddrReplace(link, addr)
|
||||
}
|
||||
|
||||
// AddrReplace will replace (or, if not present, add) an IP address on a link device.
|
||||
//
|
||||
// Equivalent to: `ip addr replace $addr dev $link`
|
||||
//
|
||||
// If `addr` is an IPv4 address and the broadcast address is not given, it
|
||||
// will be automatically computed based on the IP mask if /30 or larger.
|
||||
func (h *Handle) AddrReplace(link Link, addr *Addr) error {
|
||||
req := h.newNetlinkRequest(unix.RTM_NEWADDR, unix.NLM_F_CREATE|unix.NLM_F_REPLACE|unix.NLM_F_ACK)
|
||||
return h.addrHandle(link, addr, req)
|
||||
}
|
||||
|
||||
// AddrDel will delete an IP address from a link device.
|
||||
//
|
||||
// Equivalent to: `ip addr del $addr dev $link`
|
||||
//
|
||||
// If `addr` is an IPv4 address and the broadcast address is not given, it
|
||||
// will be automatically computed based on the IP mask if /30 or larger.
|
||||
func AddrDel(link Link, addr *Addr) error {
|
||||
return pkgHandle.AddrDel(link, addr)
|
||||
}
|
||||
|
||||
// AddrDel will delete an IP address from a link device.
|
||||
// Equivalent to: `ip addr del $addr dev $link`
|
||||
//
|
||||
// If `addr` is an IPv4 address and the broadcast address is not given, it
|
||||
// will be automatically computed based on the IP mask if /30 or larger.
|
||||
func (h *Handle) AddrDel(link Link, addr *Addr) error {
|
||||
req := h.newNetlinkRequest(unix.RTM_DELADDR, unix.NLM_F_ACK)
|
||||
return h.addrHandle(link, addr, req)
|
||||
@@ -65,7 +85,11 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error
|
||||
msg := nl.NewIfAddrmsg(family)
|
||||
msg.Index = uint32(base.Index)
|
||||
msg.Scope = uint8(addr.Scope)
|
||||
prefixlen, masklen := addr.Mask.Size()
|
||||
mask := addr.Mask
|
||||
if addr.Peer != nil {
|
||||
mask = addr.Peer.Mask
|
||||
}
|
||||
prefixlen, masklen := mask.Size()
|
||||
msg.Prefixlen = uint8(prefixlen)
|
||||
req.AddData(msg)
|
||||
|
||||
@@ -98,20 +122,26 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error
|
||||
} else {
|
||||
b := make([]byte, 4)
|
||||
native.PutUint32(b, uint32(addr.Flags))
|
||||
flagsData := nl.NewRtAttr(IFA_FLAGS, b)
|
||||
flagsData := nl.NewRtAttr(unix.IFA_FLAGS, b)
|
||||
req.AddData(flagsData)
|
||||
}
|
||||
}
|
||||
|
||||
if family == FAMILY_V4 {
|
||||
if addr.Broadcast == nil {
|
||||
// Automatically set the broadcast address if it is unset and the
|
||||
// subnet is large enough to sensibly have one (/30 or larger).
|
||||
// See: RFC 3021
|
||||
if addr.Broadcast == nil && prefixlen < 31 {
|
||||
calcBroadcast := make(net.IP, masklen/8)
|
||||
for i := range localAddrData {
|
||||
calcBroadcast[i] = localAddrData[i] | ^addr.Mask[i]
|
||||
calcBroadcast[i] = localAddrData[i] | ^mask[i]
|
||||
}
|
||||
addr.Broadcast = calcBroadcast
|
||||
}
|
||||
req.AddData(nl.NewRtAttr(unix.IFA_BROADCAST, addr.Broadcast))
|
||||
|
||||
if addr.Broadcast != nil {
|
||||
req.AddData(nl.NewRtAttr(unix.IFA_BROADCAST, addr.Broadcast))
|
||||
}
|
||||
|
||||
if addr.Label != "" {
|
||||
labelData := nl.NewRtAttr(unix.IFA_LABEL, nl.ZeroTerminated(addr.Label))
|
||||
@@ -123,10 +153,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
|
||||
// non-zero, which means the caller has explicitly set them
|
||||
if addr.ValidLft > 0 || addr.PreferedLft > 0 {
|
||||
cachedata := nl.IfaCacheInfo{
|
||||
IfaValid: uint32(addr.ValidLft),
|
||||
IfaPrefered: uint32(addr.PreferedLft),
|
||||
}
|
||||
cachedata := nl.IfaCacheInfo{unix.IfaCacheinfo{
|
||||
Valid: uint32(addr.ValidLft),
|
||||
Prefered: uint32(addr.PreferedLft),
|
||||
}}
|
||||
req.AddData(nl.NewRtAttr(unix.IFA_CACHEINFO, cachedata.Serialize()))
|
||||
}
|
||||
|
||||
@@ -163,12 +193,12 @@ func (h *Handle) AddrList(link Link, family int) ([]Addr, error) {
|
||||
|
||||
var res []Addr
|
||||
for _, m := range msgs {
|
||||
addr, msgFamily, ifindex, err := parseAddr(m)
|
||||
addr, msgFamily, err := parseAddr(m)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
if link != nil && ifindex != indexFilter {
|
||||
if link != nil && addr.LinkIndex != indexFilter {
|
||||
// Ignore messages from other interfaces
|
||||
continue
|
||||
}
|
||||
@@ -183,11 +213,11 @@ func (h *Handle) AddrList(link Link, family int) ([]Addr, error) {
|
||||
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)
|
||||
|
||||
family = -1
|
||||
index = -1
|
||||
addr.LinkIndex = -1
|
||||
|
||||
attrs, err1 := nl.ParseRouteAttr(m[msg.Len():])
|
||||
if err1 != nil {
|
||||
@@ -196,7 +226,7 @@ func parseAddr(m []byte) (addr Addr, family, index int, err error) {
|
||||
}
|
||||
|
||||
family = int(msg.Family)
|
||||
index = int(msg.Index)
|
||||
addr.LinkIndex = int(msg.Index)
|
||||
|
||||
var local, dst *net.IPNet
|
||||
for _, attr := range attrs {
|
||||
@@ -206,32 +236,48 @@ func parseAddr(m []byte) (addr Addr, family, index int, err error) {
|
||||
IP: attr.Value,
|
||||
Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
|
||||
}
|
||||
addr.Peer = dst
|
||||
case unix.IFA_LOCAL:
|
||||
// iproute2 manual:
|
||||
// If a peer address is specified, the local address
|
||||
// cannot have a prefix length. The network prefix is
|
||||
// associated with the peer rather than with the local
|
||||
// address.
|
||||
n := 8 * len(attr.Value)
|
||||
local = &net.IPNet{
|
||||
IP: attr.Value,
|
||||
Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
|
||||
Mask: net.CIDRMask(n, n),
|
||||
}
|
||||
addr.IPNet = local
|
||||
case unix.IFA_BROADCAST:
|
||||
addr.Broadcast = attr.Value
|
||||
case unix.IFA_LABEL:
|
||||
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]))
|
||||
case nl.IFA_CACHEINFO:
|
||||
case unix.IFA_CACHEINFO:
|
||||
ci := nl.DeserializeIfaCacheInfo(attr.Value)
|
||||
addr.PreferedLft = int(ci.IfaPrefered)
|
||||
addr.ValidLft = int(ci.IfaValid)
|
||||
addr.PreferedLft = int(ci.Prefered)
|
||||
addr.ValidLft = int(ci.Valid)
|
||||
}
|
||||
}
|
||||
|
||||
// IFA_LOCAL should be there but if not, fall back to IFA_ADDRESS
|
||||
// libnl addr.c comment:
|
||||
// IPv6 sends the local address as IFA_ADDRESS with no
|
||||
// IFA_LOCAL, IPv4 sends both IFA_LOCAL and IFA_ADDRESS
|
||||
// with IFA_ADDRESS being the peer address if they differ
|
||||
//
|
||||
// But obviously, as there are IPv6 PtP addresses, too,
|
||||
// IFA_LOCAL should also be handled for IPv6.
|
||||
if local != nil {
|
||||
addr.IPNet = local
|
||||
if family == FAMILY_V4 && local.IP.Equal(dst.IP) {
|
||||
addr.IPNet = dst
|
||||
} else {
|
||||
addr.IPNet = local
|
||||
addr.Peer = dst
|
||||
}
|
||||
} else {
|
||||
addr.IPNet = dst
|
||||
}
|
||||
|
||||
addr.Scope = int(msg.Scope)
|
||||
|
||||
return
|
||||
@@ -250,21 +296,22 @@ type AddrUpdate struct {
|
||||
// AddrSubscribe takes a chan down which notifications will be sent
|
||||
// when addresses change. Close the 'done' chan to stop subscription.
|
||||
func AddrSubscribe(ch chan<- AddrUpdate, done <-chan struct{}) error {
|
||||
return addrSubscribeAt(netns.None(), netns.None(), ch, done, nil, false)
|
||||
return addrSubscribeAt(netns.None(), netns.None(), ch, done, nil, false, 0)
|
||||
}
|
||||
|
||||
// AddrSubscribeAt works like AddrSubscribe plus it allows the caller
|
||||
// to choose the network namespace in which to subscribe (ns).
|
||||
func AddrSubscribeAt(ns netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}) error {
|
||||
return addrSubscribeAt(ns, netns.None(), ch, done, nil, false)
|
||||
return addrSubscribeAt(ns, netns.None(), ch, done, nil, false, 0)
|
||||
}
|
||||
|
||||
// AddrSubscribeOptions contains a set of options to use with
|
||||
// AddrSubscribeWithOptions.
|
||||
type AddrSubscribeOptions struct {
|
||||
Namespace *netns.NsHandle
|
||||
ErrorCallback func(error)
|
||||
ListExisting bool
|
||||
Namespace *netns.NsHandle
|
||||
ErrorCallback func(error)
|
||||
ListExisting bool
|
||||
ReceiveBufferSize int
|
||||
}
|
||||
|
||||
// AddrSubscribeWithOptions work like AddrSubscribe but enable to
|
||||
@@ -275,10 +322,10 @@ func AddrSubscribeWithOptions(ch chan<- AddrUpdate, done <-chan struct{}, option
|
||||
none := netns.None()
|
||||
options.Namespace = &none
|
||||
}
|
||||
return addrSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting)
|
||||
return addrSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting, options.ReceiveBufferSize)
|
||||
}
|
||||
|
||||
func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}, cberr func(error), listExisting bool) error {
|
||||
func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-chan struct{}, cberr func(error), listExisting bool, rcvbuf int) error {
|
||||
s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_IPV4_IFADDR, unix.RTNLGRP_IPV6_IFADDR)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -289,6 +336,12 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c
|
||||
s.Close()
|
||||
}()
|
||||
}
|
||||
if rcvbuf != 0 {
|
||||
err = pkgHandle.SetSocketReceiveBufferSize(rcvbuf, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if listExisting {
|
||||
req := pkgHandle.newNetlinkRequest(unix.RTM_GETADDR,
|
||||
unix.NLM_F_DUMP)
|
||||
@@ -301,13 +354,19 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c
|
||||
go func() {
|
||||
defer close(ch)
|
||||
for {
|
||||
msgs, err := s.Receive()
|
||||
msgs, from, err := s.Receive()
|
||||
if err != nil {
|
||||
if cberr != nil {
|
||||
cberr(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if from.Pid != nl.PidKernel {
|
||||
if cberr != nil {
|
||||
cberr(fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel))
|
||||
}
|
||||
continue
|
||||
}
|
||||
for _, m := range msgs {
|
||||
if m.Header.Type == unix.NLMSG_DONE {
|
||||
continue
|
||||
@@ -319,28 +378,29 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c
|
||||
continue
|
||||
}
|
||||
if cberr != nil {
|
||||
cberr(syscall.Errno(-error))
|
||||
cberr(fmt.Errorf("error message: %v",
|
||||
syscall.Errno(-error)))
|
||||
}
|
||||
return
|
||||
continue
|
||||
}
|
||||
msgType := m.Header.Type
|
||||
if msgType != unix.RTM_NEWADDR && msgType != unix.RTM_DELADDR {
|
||||
if cberr != nil {
|
||||
cberr(fmt.Errorf("bad message type: %d", msgType))
|
||||
}
|
||||
return
|
||||
continue
|
||||
}
|
||||
|
||||
addr, _, ifindex, err := parseAddr(m.Data)
|
||||
addr, _, err := parseAddr(m.Data)
|
||||
if err != nil {
|
||||
if cberr != nil {
|
||||
cberr(fmt.Errorf("could not parse address: %v", err))
|
||||
}
|
||||
return
|
||||
continue
|
||||
}
|
||||
|
||||
ch <- AddrUpdate{LinkAddress: *addr.IPNet,
|
||||
LinkIndex: ifindex,
|
||||
LinkIndex: addr.LinkIndex,
|
||||
NewAddr: msgType == unix.RTM_NEWADDR,
|
||||
Flags: addr.Flags,
|
||||
Scope: addr.Scope,
|
||||
|
||||
9
vendor/github.com/vishvananda/netlink/bridge_linux.go
generated
vendored
9
vendor/github.com/vishvananda/netlink/bridge_linux.go
generated
vendored
@@ -96,7 +96,7 @@ func (h *Handle) bridgeVlanModify(cmd int, link Link, vid uint16, pvid, untagged
|
||||
flags |= nl.BRIDGE_FLAGS_MASTER
|
||||
}
|
||||
if flags > 0 {
|
||||
nl.NewRtAttrChild(br, nl.IFLA_BRIDGE_FLAGS, nl.Uint16Attr(flags))
|
||||
br.AddRtAttr(nl.IFLA_BRIDGE_FLAGS, nl.Uint16Attr(flags))
|
||||
}
|
||||
vlanInfo := &nl.BridgeVlanInfo{Vid: vid}
|
||||
if pvid {
|
||||
@@ -105,11 +105,8 @@ func (h *Handle) bridgeVlanModify(cmd int, link Link, vid uint16, pvid, untagged
|
||||
if untagged {
|
||||
vlanInfo.Flags |= nl.BRIDGE_VLAN_INFO_UNTAGGED
|
||||
}
|
||||
nl.NewRtAttrChild(br, nl.IFLA_BRIDGE_VLAN_INFO, vlanInfo.Serialize())
|
||||
br.AddRtAttr(nl.IFLA_BRIDGE_VLAN_INFO, vlanInfo.Serialize())
|
||||
req.AddData(br)
|
||||
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
169
vendor/github.com/vishvananda/netlink/class.go
generated
vendored
169
vendor/github.com/vishvananda/netlink/class.go
generated
vendored
@@ -4,25 +4,76 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Class interfaces for all classes
|
||||
type Class interface {
|
||||
Attrs() *ClassAttrs
|
||||
Type() string
|
||||
}
|
||||
|
||||
// Generic networking statistics for netlink users.
|
||||
// This file contains "gnet_" prefixed structs and relevant functions.
|
||||
// See Documentation/networking/getn_stats.txt in Linux source code for more details.
|
||||
|
||||
// GnetStatsBasic Ref: struct gnet_stats_basic { ... }
|
||||
type GnetStatsBasic struct {
|
||||
Bytes uint64 // number of seen bytes
|
||||
Packets uint32 // number of seen packets
|
||||
}
|
||||
|
||||
// GnetStatsRateEst Ref: struct gnet_stats_rate_est { ... }
|
||||
type GnetStatsRateEst struct {
|
||||
Bps uint32 // current byte rate
|
||||
Pps uint32 // current packet rate
|
||||
}
|
||||
|
||||
// GnetStatsRateEst64 Ref: struct gnet_stats_rate_est64 { ... }
|
||||
type GnetStatsRateEst64 struct {
|
||||
Bps uint64 // current byte rate
|
||||
Pps uint64 // current packet rate
|
||||
}
|
||||
|
||||
// GnetStatsQueue Ref: struct gnet_stats_queue { ... }
|
||||
type GnetStatsQueue struct {
|
||||
Qlen uint32 // queue length
|
||||
Backlog uint32 // backlog size of queue
|
||||
Drops uint32 // number of dropped packets
|
||||
Requeues uint32 // number of requues
|
||||
Overlimits uint32 // number of enqueues over the limit
|
||||
}
|
||||
|
||||
// ClassStatistics representation based on generic networking statistics for netlink.
|
||||
// See Documentation/networking/gen_stats.txt in Linux source code for more details.
|
||||
type ClassStatistics struct {
|
||||
Basic *GnetStatsBasic
|
||||
Queue *GnetStatsQueue
|
||||
RateEst *GnetStatsRateEst
|
||||
}
|
||||
|
||||
// NewClassStatistics Construct a ClassStatistics struct which fields are all initialized by 0.
|
||||
func NewClassStatistics() *ClassStatistics {
|
||||
return &ClassStatistics{
|
||||
Basic: &GnetStatsBasic{},
|
||||
Queue: &GnetStatsQueue{},
|
||||
RateEst: &GnetStatsRateEst{},
|
||||
}
|
||||
}
|
||||
|
||||
// ClassAttrs represents a netlink class. A filter is associated with a link,
|
||||
// has a handle and a parent. The root filter of a device should have a
|
||||
// parent == HANDLE_ROOT.
|
||||
type ClassAttrs struct {
|
||||
LinkIndex int
|
||||
Handle uint32
|
||||
Parent uint32
|
||||
Leaf uint32
|
||||
LinkIndex int
|
||||
Handle uint32
|
||||
Parent uint32
|
||||
Leaf uint32
|
||||
Statistics *ClassStatistics
|
||||
}
|
||||
|
||||
func (q ClassAttrs) String() string {
|
||||
return fmt.Sprintf("{LinkIndex: %d, Handle: %s, Parent: %s, Leaf: %d}", q.LinkIndex, HandleStr(q.Handle), HandleStr(q.Parent), q.Leaf)
|
||||
}
|
||||
|
||||
// HtbClassAttrs stores the attributes of HTB class
|
||||
type HtbClassAttrs struct {
|
||||
// TODO handle all attributes
|
||||
Rate uint64
|
||||
@@ -54,10 +105,12 @@ func (q HtbClass) String() string {
|
||||
return fmt.Sprintf("{Rate: %d, Ceil: %d, Buffer: %d, Cbuffer: %d}", q.Rate, q.Ceil, q.Buffer, q.Cbuffer)
|
||||
}
|
||||
|
||||
// Attrs returns the class attributes
|
||||
func (q *HtbClass) Attrs() *ClassAttrs {
|
||||
return &q.ClassAttrs
|
||||
}
|
||||
|
||||
// Type return the class type
|
||||
func (q *HtbClass) Type() string {
|
||||
return "htb"
|
||||
}
|
||||
@@ -69,10 +122,118 @@ type GenericClass struct {
|
||||
ClassType string
|
||||
}
|
||||
|
||||
// Attrs return the class attributes
|
||||
func (class *GenericClass) Attrs() *ClassAttrs {
|
||||
return &class.ClassAttrs
|
||||
}
|
||||
|
||||
// Type return the class type
|
||||
func (class *GenericClass) Type() string {
|
||||
return class.ClassType
|
||||
}
|
||||
|
||||
// ServiceCurve is 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 {
|
||||
m1 uint32
|
||||
d uint32
|
||||
m2 uint32
|
||||
}
|
||||
|
||||
// Attrs return the parameters of the service curve
|
||||
func (c *ServiceCurve) Attrs() (uint32, uint32, uint32) {
|
||||
return c.m1, c.d, c.m2
|
||||
}
|
||||
|
||||
// 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
|
||||
type HfscClass struct {
|
||||
ClassAttrs
|
||||
Rsc ServiceCurve
|
||||
Fsc ServiceCurve
|
||||
Usc ServiceCurve
|
||||
}
|
||||
|
||||
// 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) {
|
||||
hfsc.Usc = ServiceCurve{m1: m1, d: d, m2: m2}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
hfsc.Fsc = ServiceCurve{m1: m1, d: d, m2: m2}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
hfsc.Rsc = ServiceCurve{m1: m1, d: d, m2: m2}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
hfsc.SetRsc(m1, d, m2)
|
||||
hfsc.SetFsc(m1, d, m2)
|
||||
}
|
||||
|
||||
// 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) {
|
||||
hfsc.SetUsc(m1, d, m2)
|
||||
}
|
||||
|
||||
// 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) {
|
||||
hfsc.SetFsc(m1, d, m2)
|
||||
}
|
||||
|
||||
// NewHfscClass returns a new HFSC struct with the set parameters
|
||||
func NewHfscClass(attrs ClassAttrs) *HfscClass {
|
||||
return &HfscClass{
|
||||
ClassAttrs: attrs,
|
||||
Rsc: ServiceCurve{},
|
||||
Fsc: ServiceCurve{},
|
||||
Usc: ServiceCurve{},
|
||||
}
|
||||
}
|
||||
|
||||
// String() returns a string that contains the information and attributes of the HFSC class
|
||||
func (hfsc *HfscClass) String() string {
|
||||
return fmt.Sprintf(
|
||||
"{%s -- {RSC: {m1=%d d=%d m2=%d}} {FSC: {m1=%d d=%d m2=%d}} {USC: {m1=%d d=%d m2=%d}}}",
|
||||
hfsc.Attrs(), hfsc.Rsc.m1*8, hfsc.Rsc.d, hfsc.Rsc.m2*8, hfsc.Fsc.m1*8, hfsc.Fsc.d, hfsc.Fsc.m2*8, hfsc.Usc.m1*8, hfsc.Usc.d, hfsc.Usc.m2*8,
|
||||
)
|
||||
}
|
||||
|
||||
// Attrs return the Hfsc parameters
|
||||
func (hfsc *HfscClass) Attrs() *ClassAttrs {
|
||||
return &hfsc.ClassAttrs
|
||||
}
|
||||
|
||||
// Type return the type of the class
|
||||
func (hfsc *HfscClass) Type() string {
|
||||
return "hfsc"
|
||||
}
|
||||
|
||||
166
vendor/github.com/vishvananda/netlink/class_linux.go
generated
vendored
166
vendor/github.com/vishvananda/netlink/class_linux.go
generated
vendored
@@ -1,14 +1,34 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"syscall"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// NOTE: function is in here because it uses other linux functions
|
||||
// Internal tc_stats representation in Go struct.
|
||||
// This is for internal uses only to deserialize the payload of rtattr.
|
||||
// After the deserialization, this should be converted into the canonical stats
|
||||
// struct, ClassStatistics, in case of statistics of a class.
|
||||
// Ref: struct tc_stats { ... }
|
||||
type tcStats struct {
|
||||
Bytes uint64 // Number of enqueued bytes
|
||||
Packets uint32 // Number of enqueued packets
|
||||
Drops uint32 // Packets dropped because of lack of resources
|
||||
Overlimits uint32 // Number of throttle events when this flow goes out of allocated bandwidth
|
||||
Bps uint32 // Current flow byte rate
|
||||
Pps uint32 // Current flow packet rate
|
||||
Qlen uint32
|
||||
Backlog uint32
|
||||
}
|
||||
|
||||
// NewHtbClass NOTE: function is in here because it uses other linux functions
|
||||
func NewHtbClass(attrs ClassAttrs, cattrs HtbClassAttrs) *HtbClass {
|
||||
mtu := 1600
|
||||
rate := cattrs.Rate / 8
|
||||
@@ -23,12 +43,12 @@ func NewHtbClass(attrs ClassAttrs, cattrs HtbClassAttrs) *HtbClass {
|
||||
if buffer == 0 {
|
||||
buffer = uint32(float64(rate)/Hz() + float64(mtu))
|
||||
}
|
||||
buffer = uint32(Xmittime(rate, buffer))
|
||||
buffer = Xmittime(rate, buffer)
|
||||
|
||||
if cbuffer == 0 {
|
||||
cbuffer = uint32(float64(ceil)/Hz() + float64(mtu))
|
||||
}
|
||||
cbuffer = uint32(Xmittime(ceil, cbuffer))
|
||||
cbuffer = Xmittime(ceil, cbuffer)
|
||||
|
||||
return &HtbClass{
|
||||
ClassAttrs: attrs,
|
||||
@@ -36,9 +56,9 @@ func NewHtbClass(attrs ClassAttrs, cattrs HtbClassAttrs) *HtbClass {
|
||||
Ceil: ceil,
|
||||
Buffer: buffer,
|
||||
Cbuffer: cbuffer,
|
||||
Quantum: 10,
|
||||
Level: 0,
|
||||
Prio: 0,
|
||||
Prio: cattrs.Prio,
|
||||
Quantum: cattrs.Quantum,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +146,9 @@ func classPayload(req *nl.NetlinkRequest, class Class) error {
|
||||
req.AddData(nl.NewRtAttr(nl.TCA_KIND, nl.ZeroTerminated(class.Type())))
|
||||
|
||||
options := nl.NewRtAttr(nl.TCA_OPTIONS, nil)
|
||||
if htb, ok := class.(*HtbClass); ok {
|
||||
switch class.Type() {
|
||||
case "htb":
|
||||
htb := class.(*HtbClass)
|
||||
opt := nl.TcHtbCopt{}
|
||||
opt.Buffer = htb.Buffer
|
||||
opt.Cbuffer = htb.Cbuffer
|
||||
@@ -151,9 +173,27 @@ func classPayload(req *nl.NetlinkRequest, class Class) error {
|
||||
return errors.New("HTB: failed to calculate ceil rate table")
|
||||
}
|
||||
opt.Ceil = tcceil
|
||||
nl.NewRtAttrChild(options, nl.TCA_HTB_PARMS, opt.Serialize())
|
||||
nl.NewRtAttrChild(options, nl.TCA_HTB_RTAB, SerializeRtab(rtab))
|
||||
nl.NewRtAttrChild(options, nl.TCA_HTB_CTAB, SerializeRtab(ctab))
|
||||
options.AddRtAttr(nl.TCA_HTB_PARMS, opt.Serialize())
|
||||
options.AddRtAttr(nl.TCA_HTB_RTAB, SerializeRtab(rtab))
|
||||
options.AddRtAttr(nl.TCA_HTB_CTAB, SerializeRtab(ctab))
|
||||
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":
|
||||
hfsc := class.(*HfscClass)
|
||||
opt := nl.HfscCopt{}
|
||||
rm1, rd, rm2 := hfsc.Rsc.Attrs()
|
||||
opt.Rsc.Set(rm1/8, rd, rm2/8)
|
||||
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)
|
||||
nl.NewRtAttrChild(options, nl.TCA_HFSC_RSC, nl.SerializeHfscCurve(&opt.Rsc))
|
||||
nl.NewRtAttrChild(options, nl.TCA_HFSC_FSC, nl.SerializeHfscCurve(&opt.Fsc))
|
||||
nl.NewRtAttrChild(options, nl.TCA_HFSC_USC, nl.SerializeHfscCurve(&opt.Usc))
|
||||
}
|
||||
req.AddData(options)
|
||||
return nil
|
||||
@@ -197,9 +237,10 @@ func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) {
|
||||
}
|
||||
|
||||
base := ClassAttrs{
|
||||
LinkIndex: int(msg.Ifindex),
|
||||
Handle: msg.Handle,
|
||||
Parent: msg.Parent,
|
||||
LinkIndex: int(msg.Ifindex),
|
||||
Handle: msg.Handle,
|
||||
Parent: msg.Parent,
|
||||
Statistics: nil,
|
||||
}
|
||||
|
||||
var class Class
|
||||
@@ -211,6 +252,8 @@ func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) {
|
||||
switch classType {
|
||||
case "htb":
|
||||
class = &HtbClass{}
|
||||
case "hfsc":
|
||||
class = &HfscClass{}
|
||||
default:
|
||||
class = &GenericClass{ClassType: classType}
|
||||
}
|
||||
@@ -225,6 +268,26 @@ func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "hfsc":
|
||||
data, err := nl.ParseRouteAttr(attr.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = parseHfscClassData(class, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// For backward compatibility.
|
||||
case nl.TCA_STATS:
|
||||
base.Statistics, err = parseTcStats(attr.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case nl.TCA_STATS2:
|
||||
base.Statistics, err = parseTcStats2(attr.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -249,7 +312,86 @@ func parseHtbClassData(class Class, data []syscall.NetlinkRouteAttr) (bool, erro
|
||||
htb.Quantum = opt.Quantum
|
||||
htb.Level = opt.Level
|
||||
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
|
||||
}
|
||||
|
||||
func parseHfscClassData(class Class, data []syscall.NetlinkRouteAttr) (bool, error) {
|
||||
hfsc := class.(*HfscClass)
|
||||
detailed := false
|
||||
for _, datum := range data {
|
||||
m1, d, m2 := nl.DeserializeHfscCurve(datum.Value).Attrs()
|
||||
switch datum.Attr.Type {
|
||||
case nl.TCA_HFSC_RSC:
|
||||
hfsc.Rsc = ServiceCurve{m1: m1 * 8, d: d, m2: m2 * 8}
|
||||
case nl.TCA_HFSC_FSC:
|
||||
hfsc.Fsc = ServiceCurve{m1: m1 * 8, d: d, m2: m2 * 8}
|
||||
case nl.TCA_HFSC_USC:
|
||||
hfsc.Usc = ServiceCurve{m1: m1 * 8, d: d, m2: m2 * 8}
|
||||
}
|
||||
}
|
||||
return detailed, nil
|
||||
}
|
||||
|
||||
func parseTcStats(data []byte) (*ClassStatistics, error) {
|
||||
buf := &bytes.Buffer{}
|
||||
buf.Write(data)
|
||||
native := nl.NativeEndian()
|
||||
tcStats := &tcStats{}
|
||||
if err := binary.Read(buf, native, tcStats); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stats := NewClassStatistics()
|
||||
stats.Basic.Bytes = tcStats.Bytes
|
||||
stats.Basic.Packets = tcStats.Packets
|
||||
stats.Queue.Qlen = tcStats.Qlen
|
||||
stats.Queue.Backlog = tcStats.Backlog
|
||||
stats.Queue.Drops = tcStats.Drops
|
||||
stats.Queue.Overlimits = tcStats.Overlimits
|
||||
stats.RateEst.Bps = tcStats.Bps
|
||||
stats.RateEst.Pps = tcStats.Pps
|
||||
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
func parseGnetStats(data []byte, gnetStats interface{}) error {
|
||||
buf := &bytes.Buffer{}
|
||||
buf.Write(data)
|
||||
native := nl.NativeEndian()
|
||||
return binary.Read(buf, native, gnetStats)
|
||||
}
|
||||
|
||||
func parseTcStats2(data []byte) (*ClassStatistics, error) {
|
||||
rtAttrs, err := nl.ParseRouteAttr(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
stats := NewClassStatistics()
|
||||
for _, datum := range rtAttrs {
|
||||
switch datum.Attr.Type {
|
||||
case nl.TCA_STATS_BASIC:
|
||||
if err := parseGnetStats(datum.Value, stats.Basic); err != nil {
|
||||
return nil, fmt.Errorf("Failed to parse ClassStatistics.Basic with: %v\n%s",
|
||||
err, hex.Dump(datum.Value))
|
||||
}
|
||||
case nl.TCA_STATS_QUEUE:
|
||||
if err := parseGnetStats(datum.Value, stats.Queue); err != nil {
|
||||
return nil, fmt.Errorf("Failed to parse ClassStatistics.Queue with: %v\n%s",
|
||||
err, hex.Dump(datum.Value))
|
||||
}
|
||||
case nl.TCA_STATS_RATE_EST:
|
||||
if err := parseGnetStats(datum.Value, stats.RateEst); err != nil {
|
||||
return nil, fmt.Errorf("Failed to parse ClassStatistics.RateEst with: %v\n%s",
|
||||
err, hex.Dump(datum.Value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
217
vendor/github.com/vishvananda/netlink/conntrack_linux.go
generated
vendored
217
vendor/github.com/vishvananda/netlink/conntrack_linux.go
generated
vendored
@@ -22,11 +22,7 @@ const (
|
||||
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/netfilter/nfnetlink.h -> #define NFNL_SUBSYS_CTNETLINK_EXP 2
|
||||
ConntrackExpectTable = 2
|
||||
)
|
||||
const (
|
||||
// For Parsing Mark
|
||||
TCP_PROTO = 6
|
||||
UDP_PROTO = 17
|
||||
)
|
||||
|
||||
const (
|
||||
// backward compatibility with golang 1.6 which does not have io.SeekCurrent
|
||||
seekCurrent = 1
|
||||
@@ -135,11 +131,13 @@ func (h *Handle) dumpConntrackTable(table ConntrackTableType, family InetFamily)
|
||||
// http://git.netfilter.org/libnetfilter_conntrack/tree/include/internal/object.h
|
||||
// For the time being, the structure below allows to parse and extract the base information of a flow
|
||||
type ipTuple struct {
|
||||
SrcIP net.IP
|
||||
Bytes uint64
|
||||
DstIP net.IP
|
||||
Protocol uint8
|
||||
SrcPort uint16
|
||||
DstPort uint16
|
||||
Packets uint64
|
||||
Protocol uint8
|
||||
SrcIP net.IP
|
||||
SrcPort uint16
|
||||
}
|
||||
|
||||
type ConntrackFlow struct {
|
||||
@@ -151,11 +149,12 @@ type ConntrackFlow struct {
|
||||
|
||||
func (s *ConntrackFlow) String() string {
|
||||
// conntrack cmd output:
|
||||
// udp 17 src=127.0.0.1 dst=127.0.0.1 sport=4001 dport=1234 [UNREPLIED] src=127.0.0.1 dst=127.0.0.1 sport=1234 dport=4001 mark=0
|
||||
return fmt.Sprintf("%s\t%d src=%s dst=%s sport=%d dport=%d\tsrc=%s dst=%s sport=%d dport=%d mark=%d",
|
||||
// udp 17 src=127.0.0.1 dst=127.0.0.1 sport=4001 dport=1234 packets=5 bytes=532 [UNREPLIED] src=127.0.0.1 dst=127.0.0.1 sport=1234 dport=4001 packets=10 bytes=1078 mark=0
|
||||
return fmt.Sprintf("%s\t%d src=%s dst=%s sport=%d dport=%d packets=%d bytes=%d\tsrc=%s dst=%s sport=%d dport=%d packets=%d bytes=%d mark=%d",
|
||||
nl.L4ProtoMap[s.Forward.Protocol], s.Forward.Protocol,
|
||||
s.Forward.SrcIP.String(), s.Forward.DstIP.String(), s.Forward.SrcPort, s.Forward.DstPort,
|
||||
s.Reverse.SrcIP.String(), s.Reverse.DstIP.String(), s.Reverse.SrcPort, s.Reverse.DstPort, s.Mark)
|
||||
s.Forward.SrcIP.String(), s.Forward.DstIP.String(), s.Forward.SrcPort, s.Forward.DstPort, s.Forward.Packets, s.Forward.Bytes,
|
||||
s.Reverse.SrcIP.String(), s.Reverse.DstIP.String(), s.Reverse.SrcPort, s.Reverse.DstPort, s.Reverse.Packets, s.Reverse.Bytes,
|
||||
s.Mark)
|
||||
}
|
||||
|
||||
// This method parse the ip tuple structure
|
||||
@@ -220,9 +219,35 @@ func parseBERaw16(r *bytes.Reader, v *uint16) {
|
||||
binary.Read(r, binary.BigEndian, v)
|
||||
}
|
||||
|
||||
func parseBERaw32(r *bytes.Reader, v *uint32) {
|
||||
binary.Read(r, binary.BigEndian, v)
|
||||
}
|
||||
|
||||
func parseBERaw64(r *bytes.Reader, v *uint64) {
|
||||
binary.Read(r, binary.BigEndian, v)
|
||||
}
|
||||
|
||||
func parseByteAndPacketCounters(r *bytes.Reader) (bytes, packets uint64) {
|
||||
for i := 0; i < 2; i++ {
|
||||
switch _, t, _ := parseNfAttrTL(r); t {
|
||||
case nl.CTA_COUNTERS_BYTES:
|
||||
parseBERaw64(r, &bytes)
|
||||
case nl.CTA_COUNTERS_PACKETS:
|
||||
parseBERaw64(r, &packets)
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func parseConnectionMark(r *bytes.Reader) (mark uint32) {
|
||||
parseBERaw32(r, &mark)
|
||||
return
|
||||
}
|
||||
|
||||
func parseRawData(data []byte) *ConntrackFlow {
|
||||
s := &ConntrackFlow{}
|
||||
var proto uint8
|
||||
// First there is the Nfgenmsg header
|
||||
// consume only the family field
|
||||
reader := bytes.NewReader(data)
|
||||
@@ -238,36 +263,31 @@ func parseRawData(data []byte) *ConntrackFlow {
|
||||
// <len, NLA_F_NESTED|CTA_TUPLE_IP> 4 bytes
|
||||
// flow information of the reverse flow
|
||||
for reader.Len() > 0 {
|
||||
nested, t, l := parseNfAttrTL(reader)
|
||||
if nested && t == nl.CTA_TUPLE_ORIG {
|
||||
if nested, t, _ = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP {
|
||||
proto = parseIpTuple(reader, &s.Forward)
|
||||
if nested, t, l := parseNfAttrTL(reader); nested {
|
||||
switch t {
|
||||
case nl.CTA_TUPLE_ORIG:
|
||||
if nested, t, _ = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP {
|
||||
parseIpTuple(reader, &s.Forward)
|
||||
}
|
||||
case nl.CTA_TUPLE_REPLY:
|
||||
if nested, t, _ = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP {
|
||||
parseIpTuple(reader, &s.Reverse)
|
||||
} else {
|
||||
// Header not recognized skip it
|
||||
reader.Seek(int64(l), seekCurrent)
|
||||
}
|
||||
case nl.CTA_COUNTERS_ORIG:
|
||||
s.Forward.Bytes, s.Forward.Packets = parseByteAndPacketCounters(reader)
|
||||
case nl.CTA_COUNTERS_REPLY:
|
||||
s.Reverse.Bytes, s.Reverse.Packets = parseByteAndPacketCounters(reader)
|
||||
}
|
||||
} else if nested && t == nl.CTA_TUPLE_REPLY {
|
||||
if nested, t, _ = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP {
|
||||
parseIpTuple(reader, &s.Reverse)
|
||||
|
||||
// Got all the useful information stop parsing
|
||||
break
|
||||
} else {
|
||||
// Header not recognized skip it
|
||||
reader.Seek(int64(l), seekCurrent)
|
||||
} else {
|
||||
switch t {
|
||||
case nl.CTA_MARK:
|
||||
s.Mark = parseConnectionMark(reader)
|
||||
}
|
||||
}
|
||||
}
|
||||
if proto == TCP_PROTO {
|
||||
reader.Seek(64, seekCurrent)
|
||||
_, t, _, v := parseNfAttrTLV(reader)
|
||||
if t == nl.CTA_MARK {
|
||||
s.Mark = uint32(v[3])
|
||||
}
|
||||
} else if proto == UDP_PROTO {
|
||||
reader.Seek(16, seekCurrent)
|
||||
_, t, _, v := parseNfAttrTLV(reader)
|
||||
if t == nl.CTA_MARK {
|
||||
s.Mark = uint32(v[3])
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
@@ -285,7 +305,7 @@ func parseRawData(data []byte) *ConntrackFlow {
|
||||
// Common parameters and options:
|
||||
// -s, --src, --orig-src ip Source address from original direction
|
||||
// -d, --dst, --orig-dst ip Destination address from original direction
|
||||
// -r, --reply-src ip Source addres from reply direction
|
||||
// -r, --reply-src ip Source address from reply direction
|
||||
// -q, --reply-dst ip Destination address from reply direction
|
||||
// -p, --protonum proto Layer 4 Protocol, eg. 'tcp'
|
||||
// -f, --family proto Layer 3 Protocol, eg. 'ipv6'
|
||||
@@ -298,15 +318,25 @@ func parseRawData(data []byte) *ConntrackFlow {
|
||||
// --mask-src ip Source 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
|
||||
type ConntrackFilterType uint8
|
||||
|
||||
const (
|
||||
ConntrackOrigSrcIP = iota // -orig-src ip Source address from original direction
|
||||
ConntrackOrigDstIP // -orig-dst ip Destination address from original direction
|
||||
ConntrackNatSrcIP // -src-nat ip Source NAT ip
|
||||
ConntrackNatDstIP // -dst-nat ip Destination NAT ip
|
||||
ConntrackNatAnyIP // -any-nat ip Source or destination NAT ip
|
||||
ConntrackOrigSrcIP = iota // -orig-src ip Source address from original direction
|
||||
ConntrackOrigDstIP // -orig-dst ip Destination address from original direction
|
||||
ConntrackReplySrcIP // --reply-src ip Reply Source IP
|
||||
ConntrackReplyDstIP // --reply-dst ip Reply Destination IP
|
||||
ConntrackReplyAnyIP // Match source or destination reply IP
|
||||
ConntrackOrigSrcPort // --orig-port-src port Source port in original direction
|
||||
ConntrackOrigDstPort // --orig-port-dst port Destination port in original direction
|
||||
ConntrackNatSrcIP = ConntrackReplySrcIP // deprecated use instead ConntrackReplySrcIP
|
||||
ConntrackNatDstIP = ConntrackReplyDstIP // deprecated use instead ConntrackReplyDstIP
|
||||
ConntrackNatAnyIP = ConntrackReplyAnyIP // deprecated use instead ConntrackReplyAnyIP
|
||||
)
|
||||
|
||||
type CustomConntrackFilter interface {
|
||||
@@ -316,7 +346,9 @@ type CustomConntrackFilter interface {
|
||||
}
|
||||
|
||||
type ConntrackFilter struct {
|
||||
ipFilter map[ConntrackFilterType]net.IP
|
||||
ipFilter map[ConntrackFilterType]net.IP
|
||||
portFilter map[ConntrackFilterType]uint16
|
||||
protoFilter uint8
|
||||
}
|
||||
|
||||
// AddIP adds an IP to the conntrack filter
|
||||
@@ -331,38 +363,89 @@ func (f *ConntrackFilter) AddIP(tp ConntrackFilterType, ip net.IP) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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")
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// MatchConntrackFlow applies the filter to the flow and returns true if the flow matches the filter
|
||||
// false otherwise
|
||||
func (f *ConntrackFilter) MatchConntrackFlow(flow *ConntrackFlow) bool {
|
||||
if len(f.ipFilter) == 0 {
|
||||
if len(f.ipFilter) == 0 && len(f.portFilter) == 0 && f.protoFilter == 0 {
|
||||
// empty filter always not match
|
||||
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
|
||||
}
|
||||
|
||||
match := true
|
||||
// -orig-src ip Source address from original direction
|
||||
if elem, found := f.ipFilter[ConntrackOrigSrcIP]; found {
|
||||
match = match && elem.Equal(flow.Forward.SrcIP)
|
||||
|
||||
// IP conntrack filter
|
||||
if len(f.ipFilter) > 0 {
|
||||
// -orig-src ip Source address from original direction
|
||||
if elem, found := f.ipFilter[ConntrackOrigSrcIP]; found {
|
||||
match = match && elem.Equal(flow.Forward.SrcIP)
|
||||
}
|
||||
|
||||
// -orig-dst ip Destination address from original direction
|
||||
if elem, found := f.ipFilter[ConntrackOrigDstIP]; match && found {
|
||||
match = match && elem.Equal(flow.Forward.DstIP)
|
||||
}
|
||||
|
||||
// -src-nat ip Source NAT ip
|
||||
if elem, found := f.ipFilter[ConntrackReplySrcIP]; match && found {
|
||||
match = match && elem.Equal(flow.Reverse.SrcIP)
|
||||
}
|
||||
|
||||
// -dst-nat ip Destination NAT ip
|
||||
if elem, found := f.ipFilter[ConntrackReplyDstIP]; match && found {
|
||||
match = match && elem.Equal(flow.Reverse.DstIP)
|
||||
}
|
||||
|
||||
// Match source or destination reply IP
|
||||
if elem, found := f.ipFilter[ConntrackReplyAnyIP]; match && found {
|
||||
match = match && (elem.Equal(flow.Reverse.SrcIP) || elem.Equal(flow.Reverse.DstIP))
|
||||
}
|
||||
}
|
||||
|
||||
// -orig-dst ip Destination address from original direction
|
||||
if elem, found := f.ipFilter[ConntrackOrigDstIP]; match && found {
|
||||
match = match && elem.Equal(flow.Forward.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
|
||||
}
|
||||
|
||||
// -src-nat ip Source NAT ip
|
||||
if elem, found := f.ipFilter[ConntrackNatSrcIP]; match && found {
|
||||
match = match && elem.Equal(flow.Reverse.SrcIP)
|
||||
}
|
||||
|
||||
// -dst-nat ip Destination NAT ip
|
||||
if elem, found := f.ipFilter[ConntrackNatDstIP]; match && found {
|
||||
match = match && elem.Equal(flow.Reverse.DstIP)
|
||||
}
|
||||
|
||||
// -any-nat ip Source or destination NAT ip
|
||||
if elem, found := f.ipFilter[ConntrackNatAnyIP]; match && found {
|
||||
match = match && (elem.Equal(flow.Reverse.SrcIP) || elem.Equal(flow.Reverse.DstIP))
|
||||
// -orig-port-dst port Destination port from original direction
|
||||
if elem, found := f.portFilter[ConntrackOrigDstPort]; match && found {
|
||||
match = match && elem == flow.Forward.DstPort
|
||||
}
|
||||
}
|
||||
|
||||
return match
|
||||
|
||||
393
vendor/github.com/vishvananda/netlink/devlink_linux.go
generated
vendored
Normal file
393
vendor/github.com/vishvananda/netlink/devlink_linux.go
generated
vendored
Normal file
@@ -0,0 +1,393 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
"fmt"
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// DevlinkDevEswitchAttr represents device's eswitch attributes
|
||||
type DevlinkDevEswitchAttr struct {
|
||||
Mode string
|
||||
InlineMode string
|
||||
EncapMode string
|
||||
}
|
||||
|
||||
// DevlinkDevAttrs represents device attributes
|
||||
type DevlinkDevAttrs struct {
|
||||
Eswitch DevlinkDevEswitchAttr
|
||||
}
|
||||
|
||||
// DevlinkDevice represents device and its attributes
|
||||
type DevlinkDevice struct {
|
||||
BusName string
|
||||
DeviceName string
|
||||
Attrs DevlinkDevAttrs
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
func parseDevLinkDeviceList(msgs [][]byte) ([]*DevlinkDevice, error) {
|
||||
devices := make([]*DevlinkDevice, 0, len(msgs))
|
||||
for _, m := range msgs {
|
||||
attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dev := &DevlinkDevice{}
|
||||
if err = dev.parseAttributes(attrs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
devices = append(devices, dev)
|
||||
}
|
||||
return devices, nil
|
||||
}
|
||||
|
||||
func eswitchStringToMode(modeName string) (uint16, error) {
|
||||
if modeName == "legacy" {
|
||||
return nl.DEVLINK_ESWITCH_MODE_LEGACY, nil
|
||||
} else if modeName == "switchdev" {
|
||||
return nl.DEVLINK_ESWITCH_MODE_SWITCHDEV, nil
|
||||
} else {
|
||||
return 0xffff, fmt.Errorf("invalid switchdev mode")
|
||||
}
|
||||
}
|
||||
|
||||
func parseEswitchMode(mode uint16) string {
|
||||
var eswitchMode = map[uint16]string{
|
||||
nl.DEVLINK_ESWITCH_MODE_LEGACY: "legacy",
|
||||
nl.DEVLINK_ESWITCH_MODE_SWITCHDEV: "switchdev",
|
||||
}
|
||||
if eswitchMode[mode] == "" {
|
||||
return "unknown"
|
||||
} else {
|
||||
return eswitchMode[mode]
|
||||
}
|
||||
}
|
||||
|
||||
func parseEswitchInlineMode(inlinemode uint8) string {
|
||||
var eswitchInlineMode = map[uint8]string{
|
||||
nl.DEVLINK_ESWITCH_INLINE_MODE_NONE: "none",
|
||||
nl.DEVLINK_ESWITCH_INLINE_MODE_LINK: "link",
|
||||
nl.DEVLINK_ESWITCH_INLINE_MODE_NETWORK: "network",
|
||||
nl.DEVLINK_ESWITCH_INLINE_MODE_TRANSPORT: "transport",
|
||||
}
|
||||
if eswitchInlineMode[inlinemode] == "" {
|
||||
return "unknown"
|
||||
} else {
|
||||
return eswitchInlineMode[inlinemode]
|
||||
}
|
||||
}
|
||||
|
||||
func parseEswitchEncapMode(encapmode uint8) string {
|
||||
var eswitchEncapMode = map[uint8]string{
|
||||
nl.DEVLINK_ESWITCH_ENCAP_MODE_NONE: "disable",
|
||||
nl.DEVLINK_ESWITCH_ENCAP_MODE_BASIC: "enable",
|
||||
}
|
||||
if eswitchEncapMode[encapmode] == "" {
|
||||
return "unknown"
|
||||
} else {
|
||||
return eswitchEncapMode[encapmode]
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DevlinkDevice) parseAttributes(attrs []syscall.NetlinkRouteAttr) error {
|
||||
for _, a := range attrs {
|
||||
switch a.Attr.Type {
|
||||
case nl.DEVLINK_ATTR_BUS_NAME:
|
||||
d.BusName = string(a.Value)
|
||||
case nl.DEVLINK_ATTR_DEV_NAME:
|
||||
d.DeviceName = string(a.Value)
|
||||
case nl.DEVLINK_ATTR_ESWITCH_MODE:
|
||||
d.Attrs.Eswitch.Mode = parseEswitchMode(native.Uint16(a.Value))
|
||||
case nl.DEVLINK_ATTR_ESWITCH_INLINE_MODE:
|
||||
d.Attrs.Eswitch.InlineMode = parseEswitchInlineMode(uint8(a.Value[0]))
|
||||
case nl.DEVLINK_ATTR_ESWITCH_ENCAP_MODE:
|
||||
d.Attrs.Eswitch.EncapMode = parseEswitchEncapMode(uint8(a.Value[0]))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dev *DevlinkDevice) parseEswitchAttrs(msgs [][]byte) {
|
||||
m := msgs[0]
|
||||
attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
dev.parseAttributes(attrs)
|
||||
}
|
||||
|
||||
func (h *Handle) getEswitchAttrs(family *GenlFamily, dev *DevlinkDevice) {
|
||||
msg := &nl.Genlmsg{
|
||||
Command: nl.DEVLINK_CMD_ESWITCH_GET,
|
||||
Version: nl.GENL_DEVLINK_VERSION,
|
||||
}
|
||||
req := h.newNetlinkRequest(int(family.ID), unix.NLM_F_REQUEST|unix.NLM_F_ACK)
|
||||
req.AddData(msg)
|
||||
|
||||
b := make([]byte, len(dev.BusName))
|
||||
copy(b, dev.BusName)
|
||||
data := nl.NewRtAttr(nl.DEVLINK_ATTR_BUS_NAME, b)
|
||||
req.AddData(data)
|
||||
|
||||
b = make([]byte, len(dev.DeviceName))
|
||||
copy(b, dev.DeviceName)
|
||||
data = nl.NewRtAttr(nl.DEVLINK_ATTR_DEV_NAME, b)
|
||||
req.AddData(data)
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
dev.parseEswitchAttrs(msgs)
|
||||
}
|
||||
|
||||
// DevLinkGetDeviceList provides a pointer to devlink devices and nil error,
|
||||
// otherwise returns an error code.
|
||||
func (h *Handle) DevLinkGetDeviceList() ([]*DevlinkDevice, error) {
|
||||
f, err := h.GenlFamilyGet(nl.GENL_DEVLINK_NAME)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
msg := &nl.Genlmsg{
|
||||
Command: nl.DEVLINK_CMD_GET,
|
||||
Version: nl.GENL_DEVLINK_VERSION,
|
||||
}
|
||||
req := h.newNetlinkRequest(int(f.ID),
|
||||
unix.NLM_F_REQUEST|unix.NLM_F_ACK|unix.NLM_F_DUMP)
|
||||
req.AddData(msg)
|
||||
msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
devices, err := parseDevLinkDeviceList(msgs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, d := range devices {
|
||||
h.getEswitchAttrs(f, d)
|
||||
}
|
||||
return devices, nil
|
||||
}
|
||||
|
||||
// DevLinkGetDeviceList provides a pointer to devlink devices and nil error,
|
||||
// otherwise returns an error code.
|
||||
func DevLinkGetDeviceList() ([]*DevlinkDevice, error) {
|
||||
return pkgHandle.DevLinkGetDeviceList()
|
||||
}
|
||||
|
||||
func parseDevlinkDevice(msgs [][]byte) (*DevlinkDevice, error) {
|
||||
m := msgs[0]
|
||||
attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dev := &DevlinkDevice{}
|
||||
if err = dev.parseAttributes(attrs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dev, nil
|
||||
}
|
||||
|
||||
func (h *Handle) createCmdReq(cmd uint8, bus string, device string) (*GenlFamily, *nl.NetlinkRequest, error) {
|
||||
f, err := h.GenlFamilyGet(nl.GENL_DEVLINK_NAME)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
msg := &nl.Genlmsg{
|
||||
Command: cmd,
|
||||
Version: nl.GENL_DEVLINK_VERSION,
|
||||
}
|
||||
req := h.newNetlinkRequest(int(f.ID),
|
||||
unix.NLM_F_REQUEST|unix.NLM_F_ACK)
|
||||
req.AddData(msg)
|
||||
|
||||
b := make([]byte, len(bus)+1)
|
||||
copy(b, bus)
|
||||
data := nl.NewRtAttr(nl.DEVLINK_ATTR_BUS_NAME, b)
|
||||
req.AddData(data)
|
||||
|
||||
b = make([]byte, len(device)+1)
|
||||
copy(b, device)
|
||||
data = nl.NewRtAttr(nl.DEVLINK_ATTR_DEV_NAME, b)
|
||||
req.AddData(data)
|
||||
|
||||
return f, req, nil
|
||||
}
|
||||
|
||||
// DevlinkGetDeviceByName provides a pointer to devlink device and nil error,
|
||||
// otherwise returns an error code.
|
||||
func (h *Handle) DevLinkGetDeviceByName(Bus string, Device string) (*DevlinkDevice, error) {
|
||||
f, req, err := h.createCmdReq(nl.DEVLINK_CMD_GET, Bus, Device)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
respmsg, err := req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dev, err := parseDevlinkDevice(respmsg)
|
||||
if err == nil {
|
||||
h.getEswitchAttrs(f, dev)
|
||||
}
|
||||
return dev, err
|
||||
}
|
||||
|
||||
// DevlinkGetDeviceByName provides a pointer to devlink device and nil error,
|
||||
// otherwise returns an error code.
|
||||
func DevLinkGetDeviceByName(Bus string, Device string) (*DevlinkDevice, error) {
|
||||
return pkgHandle.DevLinkGetDeviceByName(Bus, Device)
|
||||
}
|
||||
|
||||
// DevLinkSetEswitchMode sets eswitch mode if able to set successfully or
|
||||
// returns an error code.
|
||||
// Equivalent to: `devlink dev eswitch set $dev mode switchdev`
|
||||
// Equivalent to: `devlink dev eswitch set $dev mode legacy`
|
||||
func (h *Handle) DevLinkSetEswitchMode(Dev *DevlinkDevice, NewMode string) error {
|
||||
mode, err := eswitchStringToMode(NewMode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, req, err := h.createCmdReq(nl.DEVLINK_CMD_ESWITCH_SET, Dev.BusName, Dev.DeviceName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_ESWITCH_MODE, nl.Uint16Attr(mode)))
|
||||
|
||||
_, err = req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
// DevLinkSetEswitchMode sets eswitch mode if able to set successfully or
|
||||
// returns an error code.
|
||||
// Equivalent to: `devlink dev eswitch set $dev mode switchdev`
|
||||
// Equivalent to: `devlink dev eswitch set $dev mode legacy`
|
||||
func DevLinkSetEswitchMode(Dev *DevlinkDevice, NewMode string) error {
|
||||
return pkgHandle.DevLinkSetEswitchMode(Dev, NewMode)
|
||||
}
|
||||
|
||||
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)
|
||||
case nl.DEVLINK_ATTR_DEV_NAME:
|
||||
port.DeviceName = string(a.Value)
|
||||
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)
|
||||
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)
|
||||
case nl.DEVLINK_ATTR_PORT_FLAVOUR:
|
||||
port.PortFlavour = native.Uint16(a.Value)
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
103
vendor/github.com/vishvananda/netlink/filter.go
generated
vendored
103
vendor/github.com/vishvananda/netlink/filter.go
generated
vendored
@@ -2,6 +2,7 @@ package netlink
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
type Filter interface {
|
||||
@@ -135,6 +136,27 @@ func (action *BpfAction) Attrs() *ActionAttrs {
|
||||
return &action.ActionAttrs
|
||||
}
|
||||
|
||||
type ConnmarkAction struct {
|
||||
ActionAttrs
|
||||
Zone uint16
|
||||
}
|
||||
|
||||
func (action *ConnmarkAction) Type() string {
|
||||
return "connmark"
|
||||
}
|
||||
|
||||
func (action *ConnmarkAction) Attrs() *ActionAttrs {
|
||||
return &action.ActionAttrs
|
||||
}
|
||||
|
||||
func NewConnmarkAction() *ConnmarkAction {
|
||||
return &ConnmarkAction{
|
||||
ActionAttrs: ActionAttrs{
|
||||
Action: TC_ACT_PIPE,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type MirredAct uint8
|
||||
|
||||
func (a MirredAct) String() string {
|
||||
@@ -182,47 +204,60 @@ func NewMirredAction(redirIndex int) *MirredAction {
|
||||
}
|
||||
}
|
||||
|
||||
// Sel of the U32 filters that contains multiple TcU32Key. This is the copy
|
||||
// and the frontend representation of nl.TcU32Sel. It is serialized into canonical
|
||||
// nl.TcU32Sel with the appropriate endianness.
|
||||
type TcU32Sel struct {
|
||||
Flags uint8
|
||||
Offshift uint8
|
||||
Nkeys uint8
|
||||
Pad uint8
|
||||
Offmask uint16
|
||||
Off uint16
|
||||
Offoff int16
|
||||
Hoff int16
|
||||
Hmask uint32
|
||||
Keys []TcU32Key
|
||||
type TunnelKeyAct int8
|
||||
|
||||
const (
|
||||
TCA_TUNNEL_KEY_SET TunnelKeyAct = 1 // set tunnel key
|
||||
TCA_TUNNEL_KEY_UNSET TunnelKeyAct = 2 // unset tunnel key
|
||||
)
|
||||
|
||||
type TunnelKeyAction struct {
|
||||
ActionAttrs
|
||||
Action TunnelKeyAct
|
||||
SrcAddr net.IP
|
||||
DstAddr net.IP
|
||||
KeyID uint32
|
||||
DestPort uint16
|
||||
}
|
||||
|
||||
// TcU32Key contained of Sel in the U32 filters. This is the copy and the frontend
|
||||
// representation of nl.TcU32Key. It is serialized into chanonical nl.TcU32Sel
|
||||
// with the appropriate endianness.
|
||||
type TcU32Key struct {
|
||||
Mask uint32
|
||||
Val uint32
|
||||
Off int32
|
||||
OffMask int32
|
||||
func (action *TunnelKeyAction) Type() string {
|
||||
return "tunnel_key"
|
||||
}
|
||||
|
||||
// U32 filters on many packet related properties
|
||||
type U32 struct {
|
||||
FilterAttrs
|
||||
ClassId uint32
|
||||
RedirIndex int
|
||||
Sel *TcU32Sel
|
||||
Actions []Action
|
||||
func (action *TunnelKeyAction) Attrs() *ActionAttrs {
|
||||
return &action.ActionAttrs
|
||||
}
|
||||
|
||||
func (filter *U32) Attrs() *FilterAttrs {
|
||||
return &filter.FilterAttrs
|
||||
func NewTunnelKeyAction() *TunnelKeyAction {
|
||||
return &TunnelKeyAction{
|
||||
ActionAttrs: ActionAttrs{
|
||||
Action: TC_ACT_PIPE,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (filter *U32) Type() string {
|
||||
return "u32"
|
||||
type SkbEditAction struct {
|
||||
ActionAttrs
|
||||
QueueMapping *uint16
|
||||
PType *uint16
|
||||
Priority *uint32
|
||||
Mark *uint32
|
||||
}
|
||||
|
||||
func (action *SkbEditAction) Type() string {
|
||||
return "skbedit"
|
||||
}
|
||||
|
||||
func (action *SkbEditAction) Attrs() *ActionAttrs {
|
||||
return &action.ActionAttrs
|
||||
}
|
||||
|
||||
func NewSkbEditAction() *SkbEditAction {
|
||||
return &SkbEditAction{
|
||||
ActionAttrs: ActionAttrs{
|
||||
Action: TC_ACT_PIPE,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// MatchAll filters match all packets
|
||||
@@ -262,6 +297,8 @@ type BpfFilter struct {
|
||||
Fd int
|
||||
Name string
|
||||
DirectAction bool
|
||||
Id int
|
||||
Tag string
|
||||
}
|
||||
|
||||
func (filter *BpfFilter) Type() string {
|
||||
|
||||
252
vendor/github.com/vishvananda/netlink/filter_linux.go
generated
vendored
252
vendor/github.com/vishvananda/netlink/filter_linux.go
generated
vendored
@@ -3,10 +3,10 @@ package netlink
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
"golang.org/x/sys/unix"
|
||||
@@ -20,6 +20,36 @@ const (
|
||||
TC_U32_EAT = nl.TC_U32_EAT
|
||||
)
|
||||
|
||||
// Sel of the U32 filters that contains multiple TcU32Key. This is the type
|
||||
// alias and the frontend representation of nl.TcU32Sel. It is serialized into
|
||||
// canonical nl.TcU32Sel with the appropriate endianness.
|
||||
type TcU32Sel = nl.TcU32Sel
|
||||
|
||||
// TcU32Key contained of Sel in the U32 filters. This is the type alias and the
|
||||
// frontend representation of nl.TcU32Key. It is serialized into chanonical
|
||||
// nl.TcU32Sel with the appropriate endianness.
|
||||
type TcU32Key = nl.TcU32Key
|
||||
|
||||
// U32 filters on many packet related properties
|
||||
type U32 struct {
|
||||
FilterAttrs
|
||||
ClassId uint32
|
||||
Divisor uint32 // Divisor MUST be power of 2.
|
||||
Hash uint32
|
||||
Link uint32
|
||||
RedirIndex int
|
||||
Sel *TcU32Sel
|
||||
Actions []Action
|
||||
}
|
||||
|
||||
func (filter *U32) Attrs() *FilterAttrs {
|
||||
return &filter.FilterAttrs
|
||||
}
|
||||
|
||||
func (filter *U32) Type() string {
|
||||
return "u32"
|
||||
}
|
||||
|
||||
// Fw filter filters on firewall marks
|
||||
// NOTE: this is in filter_linux because it refers to nl.TcPolice which
|
||||
// is defined in nl/tc_linux.go
|
||||
@@ -59,7 +89,7 @@ func NewFw(attrs FilterAttrs, fattrs FilterFwAttrs) (*Fw, error) {
|
||||
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.Burst = Xmittime(uint64(police.Rate.Rate), uint32(buffer))
|
||||
}
|
||||
police.Mtu = fattrs.Mtu
|
||||
if police.PeakRate.Rate != 0 {
|
||||
@@ -123,8 +153,24 @@ func FilterAdd(filter Filter) error {
|
||||
// FilterAdd will add a filter to the system.
|
||||
// Equivalent to: `tc filter add $filter`
|
||||
func (h *Handle) FilterAdd(filter Filter) error {
|
||||
return h.filterModify(filter, unix.NLM_F_CREATE|unix.NLM_F_EXCL)
|
||||
}
|
||||
|
||||
// FilterReplace will replace a filter.
|
||||
// Equivalent to: `tc filter replace $filter`
|
||||
func FilterReplace(filter Filter) error {
|
||||
return pkgHandle.FilterReplace(filter)
|
||||
}
|
||||
|
||||
// FilterReplace will replace a filter.
|
||||
// Equivalent to: `tc filter replace $filter`
|
||||
func (h *Handle) FilterReplace(filter Filter) error {
|
||||
return h.filterModify(filter, unix.NLM_F_CREATE)
|
||||
}
|
||||
|
||||
func (h *Handle) filterModify(filter Filter, flags int) error {
|
||||
native = nl.NativeEndian()
|
||||
req := h.newNetlinkRequest(unix.RTM_NEWTFILTER, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
|
||||
req := h.newNetlinkRequest(unix.RTM_NEWTFILTER, flags|unix.NLM_F_ACK)
|
||||
base := filter.Attrs()
|
||||
msg := &nl.TcMsg{
|
||||
Family: nl.FAMILY_ALL,
|
||||
@@ -140,8 +186,7 @@ func (h *Handle) FilterAdd(filter Filter) error {
|
||||
|
||||
switch filter := filter.(type) {
|
||||
case *U32:
|
||||
// Convert TcU32Sel into nl.TcU32Sel as it is without copy.
|
||||
sel := (*nl.TcU32Sel)(unsafe.Pointer(filter.Sel))
|
||||
sel := filter.Sel
|
||||
if sel == nil {
|
||||
// match all
|
||||
sel = &nl.TcU32Sel{
|
||||
@@ -168,11 +213,23 @@ func (h *Handle) FilterAdd(filter Filter) error {
|
||||
}
|
||||
}
|
||||
sel.Nkeys = uint8(len(sel.Keys))
|
||||
nl.NewRtAttrChild(options, nl.TCA_U32_SEL, sel.Serialize())
|
||||
options.AddRtAttr(nl.TCA_U32_SEL, sel.Serialize())
|
||||
if filter.ClassId != 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_U32_CLASSID, nl.Uint32Attr(filter.ClassId))
|
||||
options.AddRtAttr(nl.TCA_U32_CLASSID, nl.Uint32Attr(filter.ClassId))
|
||||
}
|
||||
actionsAttr := nl.NewRtAttrChild(options, nl.TCA_U32_ACT, nil)
|
||||
if filter.Divisor != 0 {
|
||||
if (filter.Divisor-1)&filter.Divisor != 0 {
|
||||
return fmt.Errorf("illegal divisor %d. Must be a power of 2", filter.Divisor)
|
||||
}
|
||||
options.AddRtAttr(nl.TCA_U32_DIVISOR, nl.Uint32Attr(filter.Divisor))
|
||||
}
|
||||
if filter.Hash != 0 {
|
||||
options.AddRtAttr(nl.TCA_U32_HASH, nl.Uint32Attr(filter.Hash))
|
||||
}
|
||||
if filter.Link != 0 {
|
||||
options.AddRtAttr(nl.TCA_U32_LINK, nl.Uint32Attr(filter.Link))
|
||||
}
|
||||
actionsAttr := options.AddRtAttr(nl.TCA_U32_ACT, nil)
|
||||
// backwards compatibility
|
||||
if filter.RedirIndex != 0 {
|
||||
filter.Actions = append([]Action{NewMirredAction(filter.RedirIndex)}, filter.Actions...)
|
||||
@@ -184,51 +241,51 @@ func (h *Handle) FilterAdd(filter Filter) error {
|
||||
if filter.Mask != 0 {
|
||||
b := make([]byte, 4)
|
||||
native.PutUint32(b, filter.Mask)
|
||||
nl.NewRtAttrChild(options, nl.TCA_FW_MASK, b)
|
||||
options.AddRtAttr(nl.TCA_FW_MASK, b)
|
||||
}
|
||||
if filter.InDev != "" {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FW_INDEV, nl.ZeroTerminated(filter.InDev))
|
||||
options.AddRtAttr(nl.TCA_FW_INDEV, nl.ZeroTerminated(filter.InDev))
|
||||
}
|
||||
if (filter.Police != nl.TcPolice{}) {
|
||||
|
||||
police := nl.NewRtAttrChild(options, nl.TCA_FW_POLICE, nil)
|
||||
nl.NewRtAttrChild(police, nl.TCA_POLICE_TBF, filter.Police.Serialize())
|
||||
police := options.AddRtAttr(nl.TCA_FW_POLICE, nil)
|
||||
police.AddRtAttr(nl.TCA_POLICE_TBF, filter.Police.Serialize())
|
||||
if (filter.Police.Rate != nl.TcRateSpec{}) {
|
||||
payload := SerializeRtab(filter.Rtab)
|
||||
nl.NewRtAttrChild(police, nl.TCA_POLICE_RATE, payload)
|
||||
police.AddRtAttr(nl.TCA_POLICE_RATE, payload)
|
||||
}
|
||||
if (filter.Police.PeakRate != nl.TcRateSpec{}) {
|
||||
payload := SerializeRtab(filter.Ptab)
|
||||
nl.NewRtAttrChild(police, nl.TCA_POLICE_PEAKRATE, payload)
|
||||
police.AddRtAttr(nl.TCA_POLICE_PEAKRATE, payload)
|
||||
}
|
||||
}
|
||||
if filter.ClassId != 0 {
|
||||
b := make([]byte, 4)
|
||||
native.PutUint32(b, filter.ClassId)
|
||||
nl.NewRtAttrChild(options, nl.TCA_FW_CLASSID, b)
|
||||
options.AddRtAttr(nl.TCA_FW_CLASSID, b)
|
||||
}
|
||||
case *BpfFilter:
|
||||
var bpfFlags uint32
|
||||
if filter.ClassId != 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_BPF_CLASSID, nl.Uint32Attr(filter.ClassId))
|
||||
options.AddRtAttr(nl.TCA_BPF_CLASSID, nl.Uint32Attr(filter.ClassId))
|
||||
}
|
||||
if filter.Fd >= 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_BPF_FD, nl.Uint32Attr((uint32(filter.Fd))))
|
||||
options.AddRtAttr(nl.TCA_BPF_FD, nl.Uint32Attr((uint32(filter.Fd))))
|
||||
}
|
||||
if filter.Name != "" {
|
||||
nl.NewRtAttrChild(options, nl.TCA_BPF_NAME, nl.ZeroTerminated(filter.Name))
|
||||
options.AddRtAttr(nl.TCA_BPF_NAME, nl.ZeroTerminated(filter.Name))
|
||||
}
|
||||
if filter.DirectAction {
|
||||
bpfFlags |= nl.TCA_BPF_FLAG_ACT_DIRECT
|
||||
}
|
||||
nl.NewRtAttrChild(options, nl.TCA_BPF_FLAGS, nl.Uint32Attr(bpfFlags))
|
||||
options.AddRtAttr(nl.TCA_BPF_FLAGS, nl.Uint32Attr(bpfFlags))
|
||||
case *MatchAll:
|
||||
actionsAttr := nl.NewRtAttrChild(options, nl.TCA_MATCHALL_ACT, nil)
|
||||
actionsAttr := options.AddRtAttr(nl.TCA_MATCHALL_ACT, nil)
|
||||
if err := EncodeActions(actionsAttr, filter.Actions); err != nil {
|
||||
return err
|
||||
}
|
||||
if filter.ClassId != 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_MATCHALL_CLASSID, nl.Uint32Attr(filter.ClassId))
|
||||
options.AddRtAttr(nl.TCA_MATCHALL_CLASSID, nl.Uint32Attr(filter.ClassId))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,34 +423,94 @@ func EncodeActions(attr *nl.RtAttr, actions []Action) error {
|
||||
default:
|
||||
return fmt.Errorf("unknown action type %s", action.Type())
|
||||
case *MirredAction:
|
||||
table := nl.NewRtAttrChild(attr, tabIndex, nil)
|
||||
table := attr.AddRtAttr(tabIndex, nil)
|
||||
tabIndex++
|
||||
nl.NewRtAttrChild(table, nl.TCA_ACT_KIND, nl.ZeroTerminated("mirred"))
|
||||
aopts := nl.NewRtAttrChild(table, nl.TCA_ACT_OPTIONS, nil)
|
||||
table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("mirred"))
|
||||
aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
|
||||
mirred := nl.TcMirred{
|
||||
Eaction: int32(action.MirredAction),
|
||||
Ifindex: uint32(action.Ifindex),
|
||||
}
|
||||
toTcGen(action.Attrs(), &mirred.TcGen)
|
||||
nl.NewRtAttrChild(aopts, nl.TCA_MIRRED_PARMS, mirred.Serialize())
|
||||
aopts.AddRtAttr(nl.TCA_MIRRED_PARMS, mirred.Serialize())
|
||||
case *TunnelKeyAction:
|
||||
table := attr.AddRtAttr(tabIndex, nil)
|
||||
tabIndex++
|
||||
table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("tunnel_key"))
|
||||
aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
|
||||
tun := nl.TcTunnelKey{
|
||||
Action: int32(action.Action),
|
||||
}
|
||||
toTcGen(action.Attrs(), &tun.TcGen)
|
||||
aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_PARMS, tun.Serialize())
|
||||
if action.Action == TCA_TUNNEL_KEY_SET {
|
||||
aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_KEY_ID, htonl(action.KeyID))
|
||||
if v4 := action.SrcAddr.To4(); v4 != nil {
|
||||
aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_IPV4_SRC, v4[:])
|
||||
} else if v6 := action.SrcAddr.To16(); v6 != nil {
|
||||
aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_IPV6_SRC, v6[:])
|
||||
} else {
|
||||
return fmt.Errorf("invalid src addr %s for tunnel_key action", action.SrcAddr)
|
||||
}
|
||||
if v4 := action.DstAddr.To4(); v4 != nil {
|
||||
aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_IPV4_DST, v4[:])
|
||||
} else if v6 := action.DstAddr.To16(); v6 != nil {
|
||||
aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_IPV6_DST, v6[:])
|
||||
} else {
|
||||
return fmt.Errorf("invalid dst addr %s for tunnel_key action", action.DstAddr)
|
||||
}
|
||||
if action.DestPort != 0 {
|
||||
aopts.AddRtAttr(nl.TCA_TUNNEL_KEY_ENC_DST_PORT, htons(action.DestPort))
|
||||
}
|
||||
}
|
||||
case *SkbEditAction:
|
||||
table := attr.AddRtAttr(tabIndex, nil)
|
||||
tabIndex++
|
||||
table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("skbedit"))
|
||||
aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
|
||||
skbedit := nl.TcSkbEdit{}
|
||||
toTcGen(action.Attrs(), &skbedit.TcGen)
|
||||
aopts.AddRtAttr(nl.TCA_SKBEDIT_PARMS, skbedit.Serialize())
|
||||
if action.QueueMapping != nil {
|
||||
aopts.AddRtAttr(nl.TCA_SKBEDIT_QUEUE_MAPPING, nl.Uint16Attr(*action.QueueMapping))
|
||||
}
|
||||
if action.Priority != nil {
|
||||
aopts.AddRtAttr(nl.TCA_SKBEDIT_PRIORITY, nl.Uint32Attr(*action.Priority))
|
||||
}
|
||||
if action.PType != nil {
|
||||
aopts.AddRtAttr(nl.TCA_SKBEDIT_PTYPE, nl.Uint16Attr(*action.PType))
|
||||
}
|
||||
if action.Mark != nil {
|
||||
aopts.AddRtAttr(nl.TCA_SKBEDIT_MARK, nl.Uint32Attr(*action.Mark))
|
||||
}
|
||||
case *ConnmarkAction:
|
||||
table := attr.AddRtAttr(tabIndex, nil)
|
||||
tabIndex++
|
||||
table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("connmark"))
|
||||
aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
|
||||
connmark := nl.TcConnmark{
|
||||
Zone: action.Zone,
|
||||
}
|
||||
toTcGen(action.Attrs(), &connmark.TcGen)
|
||||
aopts.AddRtAttr(nl.TCA_CONNMARK_PARMS, connmark.Serialize())
|
||||
case *BpfAction:
|
||||
table := nl.NewRtAttrChild(attr, tabIndex, nil)
|
||||
table := attr.AddRtAttr(tabIndex, nil)
|
||||
tabIndex++
|
||||
nl.NewRtAttrChild(table, nl.TCA_ACT_KIND, nl.ZeroTerminated("bpf"))
|
||||
aopts := nl.NewRtAttrChild(table, nl.TCA_ACT_OPTIONS, nil)
|
||||
table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("bpf"))
|
||||
aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
|
||||
gen := nl.TcGen{}
|
||||
toTcGen(action.Attrs(), &gen)
|
||||
nl.NewRtAttrChild(aopts, nl.TCA_ACT_BPF_PARMS, gen.Serialize())
|
||||
nl.NewRtAttrChild(aopts, nl.TCA_ACT_BPF_FD, nl.Uint32Attr(uint32(action.Fd)))
|
||||
nl.NewRtAttrChild(aopts, nl.TCA_ACT_BPF_NAME, nl.ZeroTerminated(action.Name))
|
||||
aopts.AddRtAttr(nl.TCA_ACT_BPF_PARMS, gen.Serialize())
|
||||
aopts.AddRtAttr(nl.TCA_ACT_BPF_FD, nl.Uint32Attr(uint32(action.Fd)))
|
||||
aopts.AddRtAttr(nl.TCA_ACT_BPF_NAME, nl.ZeroTerminated(action.Name))
|
||||
case *GenericAction:
|
||||
table := nl.NewRtAttrChild(attr, tabIndex, nil)
|
||||
table := attr.AddRtAttr(tabIndex, nil)
|
||||
tabIndex++
|
||||
nl.NewRtAttrChild(table, nl.TCA_ACT_KIND, nl.ZeroTerminated("gact"))
|
||||
aopts := nl.NewRtAttrChild(table, nl.TCA_ACT_OPTIONS, nil)
|
||||
table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("gact"))
|
||||
aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
|
||||
gen := nl.TcGen{}
|
||||
toTcGen(action.Attrs(), &gen)
|
||||
nl.NewRtAttrChild(aopts, nl.TCA_GACT_PARMS, gen.Serialize())
|
||||
aopts.AddRtAttr(nl.TCA_GACT_PARMS, gen.Serialize())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -419,8 +536,14 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
|
||||
action = &MirredAction{}
|
||||
case "bpf":
|
||||
action = &BpfAction{}
|
||||
case "connmark":
|
||||
action = &ConnmarkAction{}
|
||||
case "gact":
|
||||
action = &GenericAction{}
|
||||
case "tunnel_key":
|
||||
action = &TunnelKeyAction{}
|
||||
case "skbedit":
|
||||
action = &SkbEditAction{}
|
||||
default:
|
||||
break nextattr
|
||||
}
|
||||
@@ -435,11 +558,46 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
|
||||
switch adatum.Attr.Type {
|
||||
case nl.TCA_MIRRED_PARMS:
|
||||
mirred := *nl.DeserializeTcMirred(adatum.Value)
|
||||
toAttrs(&mirred.TcGen, action.Attrs())
|
||||
action.(*MirredAction).ActionAttrs = ActionAttrs{}
|
||||
toAttrs(&mirred.TcGen, action.Attrs())
|
||||
action.(*MirredAction).Ifindex = int(mirred.Ifindex)
|
||||
action.(*MirredAction).MirredAction = MirredAct(mirred.Eaction)
|
||||
}
|
||||
case "tunnel_key":
|
||||
switch adatum.Attr.Type {
|
||||
case nl.TCA_TUNNEL_KEY_PARMS:
|
||||
tun := *nl.DeserializeTunnelKey(adatum.Value)
|
||||
action.(*TunnelKeyAction).ActionAttrs = ActionAttrs{}
|
||||
toAttrs(&tun.TcGen, action.Attrs())
|
||||
action.(*TunnelKeyAction).Action = TunnelKeyAct(tun.Action)
|
||||
case nl.TCA_TUNNEL_KEY_ENC_KEY_ID:
|
||||
action.(*TunnelKeyAction).KeyID = networkOrder.Uint32(adatum.Value[0:4])
|
||||
case nl.TCA_TUNNEL_KEY_ENC_IPV6_SRC, nl.TCA_TUNNEL_KEY_ENC_IPV4_SRC:
|
||||
action.(*TunnelKeyAction).SrcAddr = adatum.Value[:]
|
||||
case nl.TCA_TUNNEL_KEY_ENC_IPV6_DST, nl.TCA_TUNNEL_KEY_ENC_IPV4_DST:
|
||||
action.(*TunnelKeyAction).DstAddr = adatum.Value[:]
|
||||
case nl.TCA_TUNNEL_KEY_ENC_DST_PORT:
|
||||
action.(*TunnelKeyAction).DestPort = ntohs(adatum.Value)
|
||||
}
|
||||
case "skbedit":
|
||||
switch adatum.Attr.Type {
|
||||
case nl.TCA_SKBEDIT_PARMS:
|
||||
skbedit := *nl.DeserializeSkbEdit(adatum.Value)
|
||||
action.(*SkbEditAction).ActionAttrs = ActionAttrs{}
|
||||
toAttrs(&skbedit.TcGen, action.Attrs())
|
||||
case nl.TCA_SKBEDIT_MARK:
|
||||
mark := native.Uint32(adatum.Value[0:4])
|
||||
action.(*SkbEditAction).Mark = &mark
|
||||
case nl.TCA_SKBEDIT_PRIORITY:
|
||||
priority := native.Uint32(adatum.Value[0:4])
|
||||
action.(*SkbEditAction).Priority = &priority
|
||||
case nl.TCA_SKBEDIT_PTYPE:
|
||||
ptype := native.Uint16(adatum.Value[0:2])
|
||||
action.(*SkbEditAction).PType = &ptype
|
||||
case nl.TCA_SKBEDIT_QUEUE_MAPPING:
|
||||
mapping := native.Uint16(adatum.Value[0:2])
|
||||
action.(*SkbEditAction).QueueMapping = &mapping
|
||||
}
|
||||
case "bpf":
|
||||
switch adatum.Attr.Type {
|
||||
case nl.TCA_ACT_BPF_PARMS:
|
||||
@@ -450,6 +608,14 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
|
||||
case nl.TCA_ACT_BPF_NAME:
|
||||
action.(*BpfAction).Name = string(adatum.Value[:len(adatum.Value)-1])
|
||||
}
|
||||
case "connmark":
|
||||
switch adatum.Attr.Type {
|
||||
case nl.TCA_CONNMARK_PARMS:
|
||||
connmark := *nl.DeserializeTcConnmark(adatum.Value)
|
||||
action.(*ConnmarkAction).ActionAttrs = ActionAttrs{}
|
||||
toAttrs(&connmark.TcGen, action.Attrs())
|
||||
action.(*ConnmarkAction).Zone = connmark.Zone
|
||||
}
|
||||
case "gact":
|
||||
switch adatum.Attr.Type {
|
||||
case nl.TCA_GACT_PARMS:
|
||||
@@ -474,7 +640,7 @@ func parseU32Data(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error)
|
||||
case nl.TCA_U32_SEL:
|
||||
detailed = true
|
||||
sel := nl.DeserializeTcU32Sel(datum.Value)
|
||||
u32.Sel = (*TcU32Sel)(unsafe.Pointer(sel))
|
||||
u32.Sel = sel
|
||||
if native != networkOrder {
|
||||
// Handle the endianness of attributes
|
||||
u32.Sel.Offmask = native.Uint16(htons(sel.Offmask))
|
||||
@@ -500,6 +666,12 @@ func parseU32Data(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error)
|
||||
}
|
||||
case nl.TCA_U32_CLASSID:
|
||||
u32.ClassId = native.Uint32(datum.Value)
|
||||
case nl.TCA_U32_DIVISOR:
|
||||
u32.Divisor = native.Uint32(datum.Value)
|
||||
case nl.TCA_U32_HASH:
|
||||
u32.Hash = native.Uint32(datum.Value)
|
||||
case nl.TCA_U32_LINK:
|
||||
u32.Link = native.Uint32(datum.Value)
|
||||
}
|
||||
}
|
||||
return detailed, nil
|
||||
@@ -551,6 +723,10 @@ func parseBpfData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error)
|
||||
if (flags & nl.TCA_BPF_FLAG_ACT_DIRECT) != 0 {
|
||||
bpf.DirectAction = true
|
||||
}
|
||||
case nl.TCA_BPF_ID:
|
||||
bpf.Id = int(native.Uint32(datum.Value[0:4]))
|
||||
case nl.TCA_BPF_TAG:
|
||||
bpf.Tag = hex.EncodeToString(datum.Value[:len(datum.Value)-1])
|
||||
}
|
||||
}
|
||||
return detailed, nil
|
||||
@@ -615,7 +791,7 @@ func CalcRtable(rate *nl.TcRateSpec, rtab []uint32, cellLog int, mtu uint32, lin
|
||||
}
|
||||
for i := 0; i < 256; i++ {
|
||||
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.CellLog = uint8(cellLog)
|
||||
|
||||
6
vendor/github.com/vishvananda/netlink/fou_linux.go
generated
vendored
6
vendor/github.com/vishvananda/netlink/fou_linux.go
generated
vendored
@@ -90,11 +90,7 @@ func (h *Handle) FouAdd(f Fou) error {
|
||||
req.AddRawData(raw)
|
||||
|
||||
_, err = req.Execute(unix.NETLINK_GENERIC, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func FouDel(f Fou) error {
|
||||
|
||||
3
vendor/github.com/vishvananda/netlink/genetlink_linux.go
generated
vendored
3
vendor/github.com/vishvananda/netlink/genetlink_linux.go
generated
vendored
@@ -157,6 +157,9 @@ func (h *Handle) GenlFamilyGet(name string) (*GenlFamily, error) {
|
||||
return nil, err
|
||||
}
|
||||
families, err := parseFamilies(msgs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(families) != 1 {
|
||||
return nil, fmt.Errorf("invalid response for GENL_CTRL_CMD_GETFAMILY")
|
||||
}
|
||||
|
||||
18
vendor/github.com/vishvananda/netlink/handle_linux.go
generated
vendored
18
vendor/github.com/vishvananda/netlink/handle_linux.go
generated
vendored
@@ -21,6 +21,22 @@ type Handle struct {
|
||||
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
|
||||
func (h *Handle) SupportsNetlinkFamily(nlFamily int) bool {
|
||||
_, ok := h.sockets[nlFamily]
|
||||
@@ -91,7 +107,7 @@ func (h *Handle) GetSocketReceiveBufferSize() ([]int, error) {
|
||||
return results, nil
|
||||
}
|
||||
|
||||
// NewHandle returns a netlink handle on the network namespace
|
||||
// NewHandleAt returns a netlink handle on the network namespace
|
||||
// specified by ns. If ns=netns.None(), current network namespace
|
||||
// will be assumed
|
||||
func NewHandleAt(ns netns.NsHandle, nlFamilies ...int) (*Handle, error) {
|
||||
|
||||
18
vendor/github.com/vishvananda/netlink/handle_unspecified.go
generated
vendored
18
vendor/github.com/vishvananda/netlink/handle_unspecified.go
generated
vendored
@@ -73,11 +73,19 @@ func (h *Handle) LinkSetVfVlan(link Link, vf, vlan int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetVfVlanQos(link Link, vf, vlan, qos int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetVfTxRate(link Link, vf, rate int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetMaster(link Link, master *Bridge) error {
|
||||
func (h *Handle) LinkSetVfRate(link Link, vf, minRate, maxRate int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetMaster(link Link, master Link) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
@@ -149,6 +157,10 @@ func (h *Handle) LinkSetTxQLen(link Link, qlen int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) LinkSetGroup(link Link, group int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) setProtinfoAttr(link Link, mode bool, attr int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
@@ -225,6 +237,10 @@ func (h *Handle) RouteAdd(route *Route) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) RouteAppend(route *Route) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (h *Handle) RouteDel(route *Route) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
31
vendor/github.com/vishvananda/netlink/inet_diag.go
generated
vendored
Normal file
31
vendor/github.com/vishvananda/netlink/inet_diag.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
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_MAX
|
||||
)
|
||||
|
||||
type InetDiagTCPInfoResp struct {
|
||||
InetDiagMsg *Socket
|
||||
TCPInfo *TCPInfo
|
||||
TCPBBRInfo *TCPBBRInfo
|
||||
}
|
||||
10
vendor/github.com/vishvananda/netlink/ioctl_linux.go
generated
vendored
10
vendor/github.com/vishvananda/netlink/ioctl_linux.go
generated
vendored
@@ -56,18 +56,10 @@ type ethtoolSset struct {
|
||||
data [1]uint32
|
||||
}
|
||||
|
||||
// ethtoolGstrings is string set for data tagging
|
||||
type ethtoolGstrings struct {
|
||||
cmd uint32
|
||||
stringSet uint32
|
||||
length uint32
|
||||
data [32]byte
|
||||
}
|
||||
|
||||
type ethtoolStats struct {
|
||||
cmd uint32
|
||||
nStats uint32
|
||||
data [1]uint64
|
||||
// Followed by nStats * []uint64.
|
||||
}
|
||||
|
||||
// newIocltSlaveReq returns filled IfreqSlave with proper interface names
|
||||
|
||||
365
vendor/github.com/vishvananda/netlink/ipset_linux.go
generated
vendored
Normal file
365
vendor/github.com/vishvananda/netlink/ipset_linux.go
generated
vendored
Normal file
@@ -0,0 +1,365 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"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
|
||||
Timeout *uint32
|
||||
Packets *uint64
|
||||
Bytes *uint64
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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.ipsetAddDel(nl.IPSET_CMD_ADD, setname, entry)
|
||||
}
|
||||
|
||||
// IpsetDel deletes an entry from an existing ipset.
|
||||
func IpsetDel(setname string, entry *IPSetEntry) error {
|
||||
return pkgHandle.ipsetAddDel(nl.IPSET_CMD_DEL, 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)))
|
||||
req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_REVISION, nl.Uint8Attr(0)))
|
||||
req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_FAMILY, nl.Uint8Attr(2))) // 2 == inet
|
||||
|
||||
data := nl.NewRtAttr(nl.IPSET_ATTR_DATA|int(nl.NLA_F_NESTED), nil)
|
||||
|
||||
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) 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
|
||||
}
|
||||
|
||||
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.Comment != "" {
|
||||
req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_COMMENT, nl.ZeroTerminated(entry.Comment)))
|
||||
}
|
||||
|
||||
data := nl.NewRtAttr(nl.IPSET_ATTR_DATA|int(nl.NLA_F_NESTED), nil)
|
||||
|
||||
if !entry.Replace {
|
||||
req.Flags |= unix.NLM_F_EXCL
|
||||
}
|
||||
|
||||
if entry.Timeout != nil {
|
||||
data.AddChild(&nl.Uint32Attribute{Type: nl.IPSET_ATTR_TIMEOUT | nl.NLA_F_NET_BYTEORDER, Value: *entry.Timeout})
|
||||
}
|
||||
if entry.MAC != nil {
|
||||
nestedData := nl.NewRtAttr(nl.IPSET_ATTR_ETHER|int(nl.NLA_F_NET_BYTEORDER), entry.MAC)
|
||||
data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_ETHER|int(nl.NLA_F_NESTED), nestedData.Serialize()))
|
||||
}
|
||||
if entry.IP != nil {
|
||||
nestedData := nl.NewRtAttr(nl.IPSET_ATTR_IP|int(nl.NLA_F_NET_BYTEORDER), entry.IP)
|
||||
data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_IP|int(nl.NLA_F_NESTED), nestedData.Serialize()))
|
||||
}
|
||||
|
||||
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) 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 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]
|
||||
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_CADT_LINENO | nl.NLA_F_NET_BYTEORDER:
|
||||
result.LineNo = attr.Uint32()
|
||||
case nl.IPSET_ATTR_COMMENT:
|
||||
result.Comment = nl.BytesToString(attr.Value)
|
||||
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_IP:
|
||||
entry.IP = net.IP(attr.Value)
|
||||
default:
|
||||
log.Printf("unknown nested ADT attribute from kernel: %+v", attr)
|
||||
}
|
||||
}
|
||||
default:
|
||||
log.Printf("unknown ADT attribute from kernel: %+v", attr)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
469
vendor/github.com/vishvananda/netlink/link.go
generated
vendored
469
vendor/github.com/vishvananda/netlink/link.go
generated
vendored
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Link represents a link device from netlink. Shared link attributes
|
||||
@@ -41,6 +42,40 @@ type LinkAttrs struct {
|
||||
NetNsID int
|
||||
NumTxQueues int
|
||||
NumRxQueues int
|
||||
GSOMaxSize uint32
|
||||
GSOMaxSegs uint32
|
||||
Vfs []VfInfo // virtual functions available on link
|
||||
Group uint32
|
||||
Slave LinkSlave
|
||||
}
|
||||
|
||||
// LinkSlave represents a slave device.
|
||||
type LinkSlave interface {
|
||||
SlaveType() string
|
||||
}
|
||||
|
||||
// VfInfo represents configuration of virtual function
|
||||
type VfInfo struct {
|
||||
ID int
|
||||
Mac net.HardwareAddr
|
||||
Vlan int
|
||||
Qos int
|
||||
TxRate int // IFLA_VF_TX_RATE Max TxRate
|
||||
Spoofchk bool
|
||||
LinkState uint32
|
||||
MaxTxRate uint32 // IFLA_VF_RATE Max TxRate
|
||||
MinTxRate uint32 // IFLA_VF_RATE Min TxRate
|
||||
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
|
||||
@@ -79,7 +114,8 @@ func (s LinkOperState) String() string {
|
||||
// NewLinkAttrs returns LinkAttrs structure filled with default values
|
||||
func NewLinkAttrs() LinkAttrs {
|
||||
return LinkAttrs{
|
||||
TxQLen: -1,
|
||||
NetNsID: -1,
|
||||
TxQLen: -1,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,10 +208,11 @@ type LinkStatistics64 struct {
|
||||
}
|
||||
|
||||
type LinkXdp struct {
|
||||
Fd int
|
||||
Attached bool
|
||||
Flags uint32
|
||||
ProgId uint32
|
||||
Fd int
|
||||
Attached bool
|
||||
AttachMode uint32
|
||||
Flags uint32
|
||||
ProgId uint32
|
||||
}
|
||||
|
||||
// Device links cannot be created via netlink. These links
|
||||
@@ -222,7 +259,9 @@ func (ifb *Ifb) Type() string {
|
||||
type Bridge struct {
|
||||
LinkAttrs
|
||||
MulticastSnooping *bool
|
||||
AgeingTime *uint32
|
||||
HelloTime *uint32
|
||||
VlanFiltering *bool
|
||||
}
|
||||
|
||||
func (bridge *Bridge) Attrs() *LinkAttrs {
|
||||
@@ -236,7 +275,8 @@ func (bridge *Bridge) Type() string {
|
||||
// Vlan links have ParentIndex set in their Attrs()
|
||||
type Vlan struct {
|
||||
LinkAttrs
|
||||
VlanId int
|
||||
VlanId int
|
||||
VlanProtocol VlanProtocol
|
||||
}
|
||||
|
||||
func (vlan *Vlan) Attrs() *LinkAttrs {
|
||||
@@ -290,10 +330,13 @@ type TuntapFlag uint16
|
||||
// Tuntap links created via /dev/tun/tap, but can be destroyed via netlink
|
||||
type Tuntap struct {
|
||||
LinkAttrs
|
||||
Mode TuntapMode
|
||||
Flags TuntapFlag
|
||||
Queues int
|
||||
Fds []*os.File
|
||||
Mode TuntapMode
|
||||
Flags TuntapFlag
|
||||
NonPersist bool
|
||||
Queues int
|
||||
Fds []*os.File
|
||||
Owner uint32
|
||||
Group uint32
|
||||
}
|
||||
|
||||
func (tuntap *Tuntap) Attrs() *LinkAttrs {
|
||||
@@ -307,7 +350,9 @@ func (tuntap *Tuntap) Type() string {
|
||||
// Veth devices must specify PeerName on create
|
||||
type Veth struct {
|
||||
LinkAttrs
|
||||
PeerName string // veth on create only
|
||||
PeerName string // veth on create only
|
||||
PeerHardwareAddr net.HardwareAddr
|
||||
PeerNamespace interface{}
|
||||
}
|
||||
|
||||
func (veth *Veth) Attrs() *LinkAttrs {
|
||||
@@ -318,6 +363,19 @@ func (veth *Veth) Type() string {
|
||||
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
|
||||
// by this netlink library.
|
||||
type GenericLink struct {
|
||||
@@ -376,9 +434,18 @@ const (
|
||||
IPVLAN_MODE_MAX
|
||||
)
|
||||
|
||||
type IPVlanFlag uint16
|
||||
|
||||
const (
|
||||
IPVLAN_FLAG_BRIDGE IPVlanFlag = iota
|
||||
IPVLAN_FLAG_PRIVATE
|
||||
IPVLAN_FLAG_VEPA
|
||||
)
|
||||
|
||||
type IPVlan struct {
|
||||
LinkAttrs
|
||||
Mode IPVlanMode
|
||||
Flag IPVlanFlag
|
||||
}
|
||||
|
||||
func (ipvlan *IPVlan) Attrs() *LinkAttrs {
|
||||
@@ -389,6 +456,43 @@ func (ipvlan *IPVlan) Type() string {
|
||||
return "ipvlan"
|
||||
}
|
||||
|
||||
// VlanProtocol type
|
||||
type VlanProtocol int
|
||||
|
||||
func (p VlanProtocol) String() string {
|
||||
s, ok := VlanProtocolToString[p]
|
||||
if !ok {
|
||||
return fmt.Sprintf("VlanProtocol(%d)", p)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// StringToVlanProtocol returns vlan protocol, or unknown is the s is invalid.
|
||||
func StringToVlanProtocol(s string) VlanProtocol {
|
||||
mode, ok := StringToVlanProtocolMap[s]
|
||||
if !ok {
|
||||
return VLAN_PROTOCOL_UNKNOWN
|
||||
}
|
||||
return mode
|
||||
}
|
||||
|
||||
// VlanProtocol possible values
|
||||
const (
|
||||
VLAN_PROTOCOL_UNKNOWN VlanProtocol = 0
|
||||
VLAN_PROTOCOL_8021Q VlanProtocol = 0x8100
|
||||
VLAN_PROTOCOL_8021AD VlanProtocol = 0x88A8
|
||||
)
|
||||
|
||||
var VlanProtocolToString = map[VlanProtocol]string{
|
||||
VLAN_PROTOCOL_8021Q: "802.1q",
|
||||
VLAN_PROTOCOL_8021AD: "802.1ad",
|
||||
}
|
||||
|
||||
var StringToVlanProtocolMap = map[string]VlanProtocol{
|
||||
"802.1q": VLAN_PROTOCOL_8021Q,
|
||||
"802.1ad": VLAN_PROTOCOL_8021AD,
|
||||
}
|
||||
|
||||
// BondMode type
|
||||
type BondMode int
|
||||
|
||||
@@ -400,7 +504,7 @@ func (b BondMode) String() string {
|
||||
return s
|
||||
}
|
||||
|
||||
// StringToBondMode returns bond mode, or uknonw is the s is invalid.
|
||||
// StringToBondMode returns bond mode, or unknown is the s is invalid.
|
||||
func StringToBondMode(s string) BondMode {
|
||||
mode, ok := StringToBondModeMap[s]
|
||||
if !ok {
|
||||
@@ -451,6 +555,27 @@ const (
|
||||
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
|
||||
type BondPrimaryReselect int
|
||||
|
||||
@@ -461,6 +586,25 @@ const (
|
||||
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
|
||||
type BondArpAllTargets int
|
||||
|
||||
@@ -470,6 +614,23 @@ const (
|
||||
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
|
||||
type BondFailOverMac int
|
||||
|
||||
@@ -480,6 +641,25 @@ const (
|
||||
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
|
||||
type BondXmitHashPolicy int
|
||||
|
||||
@@ -491,7 +671,7 @@ func (b BondXmitHashPolicy) String() string {
|
||||
return s
|
||||
}
|
||||
|
||||
// StringToBondXmitHashPolicy returns bond lacp arte, or uknonw is the s is invalid.
|
||||
// StringToBondXmitHashPolicy returns bond lacp arte, or unknown is the s is invalid.
|
||||
func StringToBondXmitHashPolicy(s string) BondXmitHashPolicy {
|
||||
lacp, ok := StringToBondXmitHashPolicyMap[s]
|
||||
if !ok {
|
||||
@@ -536,7 +716,7 @@ func (b BondLacpRate) String() string {
|
||||
return s
|
||||
}
|
||||
|
||||
// StringToBondLacpRate returns bond lacp arte, or uknonw is the s is invalid.
|
||||
// StringToBondLacpRate returns bond lacp arte, or unknown is the s is invalid.
|
||||
func StringToBondLacpRate(s string) BondLacpRate {
|
||||
lacp, ok := StringToBondLacpRateMap[s]
|
||||
if !ok {
|
||||
@@ -571,6 +751,25 @@ const (
|
||||
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
|
||||
type BondAdInfo struct {
|
||||
AggregatorId int
|
||||
@@ -602,7 +801,7 @@ type Bond struct {
|
||||
AllSlavesActive int
|
||||
MinLinks int
|
||||
LpInterval int
|
||||
PackersPerSlave int
|
||||
PacketsPerSlave int
|
||||
LacpRate BondLacpRate
|
||||
AdSelect BondAdSelect
|
||||
// looking at iproute tool AdInfo can only be retrived. It can't be set.
|
||||
@@ -635,7 +834,7 @@ func NewLinkBond(atr LinkAttrs) *Bond {
|
||||
AllSlavesActive: -1,
|
||||
MinLinks: -1,
|
||||
LpInterval: -1,
|
||||
PackersPerSlave: -1,
|
||||
PacketsPerSlave: -1,
|
||||
LacpRate: -1,
|
||||
AdSelect: -1,
|
||||
AdActorSysPrio: -1,
|
||||
@@ -680,6 +879,97 @@ func (bond *Bond) Type() string {
|
||||
return "bond"
|
||||
}
|
||||
|
||||
// BondSlaveState represents the values of the IFLA_BOND_SLAVE_STATE bond slave
|
||||
// attribute, which contains the state of the bond slave.
|
||||
type BondSlaveState uint8
|
||||
|
||||
const (
|
||||
//BondStateActive Link is active.
|
||||
BondStateActive BondSlaveState = iota
|
||||
//BondStateBackup Link is backup.
|
||||
BondStateBackup
|
||||
)
|
||||
|
||||
func (s BondSlaveState) String() string {
|
||||
switch s {
|
||||
case BondStateActive:
|
||||
return "ACTIVE"
|
||||
case BondStateBackup:
|
||||
return "BACKUP"
|
||||
default:
|
||||
return strconv.Itoa(int(s))
|
||||
}
|
||||
}
|
||||
|
||||
// BondSlaveMiiStatus represents the values of the IFLA_BOND_SLAVE_MII_STATUS bond slave
|
||||
// attribute, which contains the status of MII link monitoring
|
||||
type BondSlaveMiiStatus uint8
|
||||
|
||||
const (
|
||||
//BondLinkUp link is up and running.
|
||||
BondLinkUp BondSlaveMiiStatus = iota
|
||||
//BondLinkFail link has just gone down.
|
||||
BondLinkFail
|
||||
//BondLinkDown link has been down for too long time.
|
||||
BondLinkDown
|
||||
//BondLinkBack link is going back.
|
||||
BondLinkBack
|
||||
)
|
||||
|
||||
func (s BondSlaveMiiStatus) String() string {
|
||||
switch s {
|
||||
case BondLinkUp:
|
||||
return "UP"
|
||||
case BondLinkFail:
|
||||
return "GOING_DOWN"
|
||||
case BondLinkDown:
|
||||
return "DOWN"
|
||||
case BondLinkBack:
|
||||
return "GOING_BACK"
|
||||
default:
|
||||
return strconv.Itoa(int(s))
|
||||
}
|
||||
}
|
||||
|
||||
type BondSlave struct {
|
||||
State BondSlaveState
|
||||
MiiStatus BondSlaveMiiStatus
|
||||
LinkFailureCount uint32
|
||||
PermHardwareAddr net.HardwareAddr
|
||||
QueueId uint16
|
||||
AggregatorId uint16
|
||||
AdActorOperPortState uint8
|
||||
AdPartnerOperPortState uint16
|
||||
}
|
||||
|
||||
func (b *BondSlave) SlaveType() string {
|
||||
return "bond"
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
func (geneve *Geneve) Attrs() *LinkAttrs {
|
||||
return &geneve.LinkAttrs
|
||||
}
|
||||
|
||||
func (geneve *Geneve) Type() string {
|
||||
return "geneve"
|
||||
}
|
||||
|
||||
// Gretap devices must specify LocalIP and RemoteIP on create
|
||||
type Gretap struct {
|
||||
LinkAttrs
|
||||
@@ -734,14 +1024,41 @@ func (iptun *Iptun) Type() string {
|
||||
return "ipip"
|
||||
}
|
||||
|
||||
type Sittun struct {
|
||||
type Ip6tnl struct {
|
||||
LinkAttrs
|
||||
Link uint32
|
||||
Local net.IP
|
||||
Remote net.IP
|
||||
Ttl uint8
|
||||
Tos uint8
|
||||
Flags uint32
|
||||
Proto uint8
|
||||
FlowInfo uint32
|
||||
EncapLimit uint8
|
||||
EncapType uint16
|
||||
EncapFlags uint16
|
||||
EncapSport uint16
|
||||
EncapDport uint16
|
||||
}
|
||||
|
||||
func (ip6tnl *Ip6tnl) Attrs() *LinkAttrs {
|
||||
return &ip6tnl.LinkAttrs
|
||||
}
|
||||
|
||||
func (ip6tnl *Ip6tnl) Type() string {
|
||||
return "ip6tnl"
|
||||
}
|
||||
|
||||
type Sittun struct {
|
||||
LinkAttrs
|
||||
Link uint32
|
||||
Ttl uint8
|
||||
Tos uint8
|
||||
PMtuDisc uint8
|
||||
Proto uint8
|
||||
Local net.IP
|
||||
Remote net.IP
|
||||
EncapLimit uint8
|
||||
EncapType uint16
|
||||
EncapFlags uint16
|
||||
EncapSport uint16
|
||||
@@ -769,7 +1086,10 @@ func (vti *Vti) Attrs() *LinkAttrs {
|
||||
return &vti.LinkAttrs
|
||||
}
|
||||
|
||||
func (iptun *Vti) Type() string {
|
||||
func (vti *Vti) Type() string {
|
||||
if vti.Local.To4() == nil {
|
||||
return "vti6"
|
||||
}
|
||||
return "vti"
|
||||
}
|
||||
|
||||
@@ -831,11 +1151,120 @@ func (gtp *GTP) Type() string {
|
||||
return "gtp"
|
||||
}
|
||||
|
||||
// Virtual XFRM Interfaces
|
||||
// Named "xfrmi" to prevent confusion with XFRM objects
|
||||
type Xfrmi struct {
|
||||
LinkAttrs
|
||||
Ifid uint32
|
||||
}
|
||||
|
||||
func (xfrm *Xfrmi) Attrs() *LinkAttrs {
|
||||
return &xfrm.LinkAttrs
|
||||
}
|
||||
|
||||
func (xfrm *Xfrmi) Type() string {
|
||||
return "xfrm"
|
||||
}
|
||||
|
||||
// IPoIB interface
|
||||
|
||||
type IPoIBMode uint16
|
||||
|
||||
func (m *IPoIBMode) String() string {
|
||||
str, ok := iPoIBModeToString[*m]
|
||||
if !ok {
|
||||
return fmt.Sprintf("mode(%d)", *m)
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
const (
|
||||
IPOIB_MODE_DATAGRAM = iota
|
||||
IPOIB_MODE_CONNECTED
|
||||
)
|
||||
|
||||
var iPoIBModeToString = map[IPoIBMode]string{
|
||||
IPOIB_MODE_DATAGRAM: "datagram",
|
||||
IPOIB_MODE_CONNECTED: "connected",
|
||||
}
|
||||
|
||||
var StringToIPoIBMode = map[string]IPoIBMode{
|
||||
"datagram": IPOIB_MODE_DATAGRAM,
|
||||
"connected": IPOIB_MODE_CONNECTED,
|
||||
}
|
||||
|
||||
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 {
|
||||
LinkAttrs
|
||||
Pkey uint16
|
||||
Mode IPoIBMode
|
||||
Umcast uint16
|
||||
}
|
||||
|
||||
func (ipoib *IPoIB) Attrs() *LinkAttrs {
|
||||
return &ipoib.LinkAttrs
|
||||
}
|
||||
|
||||
func (ipoib *IPoIB) Type() string {
|
||||
return "ipoib"
|
||||
}
|
||||
|
||||
// iproute2 supported devices;
|
||||
// vlan | veth | vcan | dummy | ifb | macvlan | macvtap |
|
||||
// bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan |
|
||||
// gre | gretap | ip6gre | ip6gretap | vti | nlmon |
|
||||
// bond_slave | ipvlan
|
||||
// gre | gretap | ip6gre | ip6gretap | vti | vti6 | nlmon |
|
||||
// bond_slave | ipvlan | xfrm
|
||||
|
||||
// LinkNotFoundError wraps the various not found errors when
|
||||
// getting/reading links. This is intended for better error
|
||||
|
||||
1439
vendor/github.com/vishvananda/netlink/link_linux.go
generated
vendored
1439
vendor/github.com/vishvananda/netlink/link_linux.go
generated
vendored
File diff suppressed because it is too large
Load Diff
7
vendor/github.com/vishvananda/netlink/neigh.go
generated
vendored
7
vendor/github.com/vishvananda/netlink/neigh.go
generated
vendored
@@ -17,9 +17,16 @@ type Neigh struct {
|
||||
LLIPAddr net.IP //Used in the case of NHRP
|
||||
Vlan int
|
||||
VNI int
|
||||
MasterIndex int
|
||||
}
|
||||
|
||||
// String returns $ip/$hwaddr $label
|
||||
func (neigh *Neigh) String() string {
|
||||
return fmt.Sprintf("%s %s", neigh.IP, neigh.HardwareAddr)
|
||||
}
|
||||
|
||||
// NeighUpdate is sent when a neighbor changes - type is RTM_NEWNEIGH or RTM_DELNEIGH.
|
||||
type NeighUpdate struct {
|
||||
Type uint16
|
||||
Neigh
|
||||
}
|
||||
|
||||
203
vendor/github.com/vishvananda/netlink/neigh_linux.go
generated
vendored
203
vendor/github.com/vishvananda/netlink/neigh_linux.go
generated
vendored
@@ -1,10 +1,13 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
"github.com/vishvananda/netns"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
@@ -18,7 +21,10 @@ const (
|
||||
NDA_PORT
|
||||
NDA_VNI
|
||||
NDA_IFINDEX
|
||||
NDA_MAX = NDA_IFINDEX
|
||||
NDA_MASTER
|
||||
NDA_LINK_NETNSID
|
||||
NDA_SRC_VNI
|
||||
NDA_MAX = NDA_SRC_VNI
|
||||
)
|
||||
|
||||
// Neighbor Cache Entry States.
|
||||
@@ -43,6 +49,7 @@ const (
|
||||
NTF_ROUTER = 0x80
|
||||
)
|
||||
|
||||
// Ndmsg is for adding, removing or receiving information about a neighbor table entry
|
||||
type Ndmsg struct {
|
||||
Family uint8
|
||||
Index uint32
|
||||
@@ -170,45 +177,58 @@ func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error {
|
||||
req.AddData(vniData)
|
||||
}
|
||||
|
||||
if neigh.MasterIndex != 0 {
|
||||
masterData := nl.NewRtAttr(NDA_MASTER, nl.Uint32Attr(uint32(neigh.MasterIndex)))
|
||||
req.AddData(masterData)
|
||||
}
|
||||
|
||||
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
// NeighList gets a list of IP-MAC mappings in the system (ARP table).
|
||||
// NeighList returns a list of IP-MAC mappings in the system (ARP table).
|
||||
// Equivalent to: `ip neighbor show`.
|
||||
// The list can be filtered by link and ip family.
|
||||
func NeighList(linkIndex, family int) ([]Neigh, error) {
|
||||
return pkgHandle.NeighList(linkIndex, family)
|
||||
}
|
||||
|
||||
// NeighProxyList gets a list of neighbor proxies in the system.
|
||||
// NeighProxyList returns a list of neighbor proxies in the system.
|
||||
// Equivalent to: `ip neighbor show proxy`.
|
||||
// The list can be filtered by link and ip family.
|
||||
func NeighProxyList(linkIndex, family int) ([]Neigh, error) {
|
||||
return pkgHandle.NeighProxyList(linkIndex, family)
|
||||
}
|
||||
|
||||
// NeighList gets a list of IP-MAC mappings in the system (ARP table).
|
||||
// NeighList returns a list of IP-MAC mappings in the system (ARP table).
|
||||
// Equivalent to: `ip neighbor show`.
|
||||
// The list can be filtered by link and ip family.
|
||||
func (h *Handle) NeighList(linkIndex, family int) ([]Neigh, error) {
|
||||
return h.neighList(linkIndex, family, 0)
|
||||
return h.NeighListExecute(Ndmsg{
|
||||
Family: uint8(family),
|
||||
Index: uint32(linkIndex),
|
||||
})
|
||||
}
|
||||
|
||||
// NeighProxyList gets a list of neighbor proxies in the system.
|
||||
// NeighProxyList returns a list of neighbor proxies in the system.
|
||||
// Equivalent to: `ip neighbor show proxy`.
|
||||
// The list can be filtered by link, ip family.
|
||||
func (h *Handle) NeighProxyList(linkIndex, family int) ([]Neigh, error) {
|
||||
return h.neighList(linkIndex, family, NTF_PROXY)
|
||||
}
|
||||
|
||||
func (h *Handle) neighList(linkIndex, family, flags int) ([]Neigh, error) {
|
||||
req := h.newNetlinkRequest(unix.RTM_GETNEIGH, unix.NLM_F_DUMP)
|
||||
msg := Ndmsg{
|
||||
return h.NeighListExecute(Ndmsg{
|
||||
Family: uint8(family),
|
||||
Index: uint32(linkIndex),
|
||||
Flags: uint8(flags),
|
||||
}
|
||||
Flags: NTF_PROXY,
|
||||
})
|
||||
}
|
||||
|
||||
// NeighListExecute returns a list of neighbour entries filtered by link, ip family, flag and state.
|
||||
func NeighListExecute(msg Ndmsg) ([]Neigh, error) {
|
||||
return pkgHandle.NeighListExecute(msg)
|
||||
}
|
||||
|
||||
// NeighListExecute returns a list of neighbour entries filtered by link, ip family, flag and state.
|
||||
func (h *Handle) NeighListExecute(msg Ndmsg) ([]Neigh, error) {
|
||||
req := h.newNetlinkRequest(unix.RTM_GETNEIGH, unix.NLM_F_DUMP)
|
||||
req.AddData(&msg)
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWNEIGH)
|
||||
@@ -219,10 +239,22 @@ func (h *Handle) neighList(linkIndex, family, flags int) ([]Neigh, error) {
|
||||
var res []Neigh
|
||||
for _, m := range msgs {
|
||||
ndm := deserializeNdmsg(m)
|
||||
if linkIndex != 0 && int(ndm.Index) != linkIndex {
|
||||
if msg.Index != 0 && ndm.Index != msg.Index {
|
||||
// Ignore messages from other interfaces
|
||||
continue
|
||||
}
|
||||
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)
|
||||
if err != nil {
|
||||
@@ -251,14 +283,6 @@ func NeighDeserialize(m []byte) (*Neigh, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// This should be cached for perfomance
|
||||
// once per table dump
|
||||
link, err := LinkByIndex(neigh.LinkIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
encapType := link.Attrs().EncapType
|
||||
|
||||
for _, attr := range attrs {
|
||||
switch attr.Attr.Type {
|
||||
case NDA_DST:
|
||||
@@ -268,13 +292,16 @@ func NeighDeserialize(m []byte) (*Neigh, error) {
|
||||
// #define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len))
|
||||
// #define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
|
||||
attrLen := attr.Attr.Len - unix.SizeofRtAttr
|
||||
if attrLen == 4 && (encapType == "ipip" ||
|
||||
encapType == "sit" ||
|
||||
encapType == "gre") {
|
||||
if attrLen == 4 {
|
||||
neigh.LLIPAddr = net.IP(attr.Value)
|
||||
} else if attrLen == 16 &&
|
||||
encapType == "tunnel6" {
|
||||
neigh.IP = net.IP(attr.Value)
|
||||
} else if attrLen == 16 {
|
||||
// Can be IPv6 or FireWire HWAddr
|
||||
link, err := LinkByIndex(neigh.LinkIndex)
|
||||
if err == nil && link.Attrs().EncapType == "tunnel6" {
|
||||
neigh.IP = net.IP(attr.Value)
|
||||
} else {
|
||||
neigh.HardwareAddr = net.HardwareAddr(attr.Value)
|
||||
}
|
||||
} else {
|
||||
neigh.HardwareAddr = net.HardwareAddr(attr.Value)
|
||||
}
|
||||
@@ -282,8 +309,126 @@ func NeighDeserialize(m []byte) (*Neigh, error) {
|
||||
neigh.Vlan = int(native.Uint16(attr.Value[0:2]))
|
||||
case NDA_VNI:
|
||||
neigh.VNI = int(native.Uint32(attr.Value[0:4]))
|
||||
case NDA_MASTER:
|
||||
neigh.MasterIndex = int(native.Uint32(attr.Value[0:4]))
|
||||
}
|
||||
}
|
||||
|
||||
return &neigh, nil
|
||||
}
|
||||
|
||||
// NeighSubscribe takes a chan down which notifications will be sent
|
||||
// when neighbors are added or deleted. Close the 'done' chan to stop subscription.
|
||||
func NeighSubscribe(ch chan<- NeighUpdate, done <-chan struct{}) error {
|
||||
return neighSubscribeAt(netns.None(), netns.None(), ch, done, nil, false)
|
||||
}
|
||||
|
||||
// NeighSubscribeAt works like NeighSubscribe plus it allows the caller
|
||||
// to choose the network namespace in which to subscribe (ns).
|
||||
func NeighSubscribeAt(ns netns.NsHandle, ch chan<- NeighUpdate, done <-chan struct{}) error {
|
||||
return neighSubscribeAt(ns, netns.None(), ch, done, nil, false)
|
||||
}
|
||||
|
||||
// NeighSubscribeOptions contains a set of options to use with
|
||||
// NeighSubscribeWithOptions.
|
||||
type NeighSubscribeOptions struct {
|
||||
Namespace *netns.NsHandle
|
||||
ErrorCallback func(error)
|
||||
ListExisting bool
|
||||
}
|
||||
|
||||
// NeighSubscribeWithOptions work like NeighSubscribe but enable to
|
||||
// provide additional options to modify the behavior. Currently, the
|
||||
// namespace can be provided as well as an error callback.
|
||||
func NeighSubscribeWithOptions(ch chan<- NeighUpdate, done <-chan struct{}, options NeighSubscribeOptions) error {
|
||||
if options.Namespace == nil {
|
||||
none := netns.None()
|
||||
options.Namespace = &none
|
||||
}
|
||||
return neighSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting)
|
||||
}
|
||||
|
||||
func neighSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- NeighUpdate, done <-chan struct{}, cberr func(error), listExisting bool) error {
|
||||
s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_NEIGH)
|
||||
makeRequest := func(family int) error {
|
||||
req := pkgHandle.newNetlinkRequest(unix.RTM_GETNEIGH,
|
||||
unix.NLM_F_DUMP)
|
||||
infmsg := nl.NewIfInfomsg(family)
|
||||
req.AddData(infmsg)
|
||||
if err := s.Send(req); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if done != nil {
|
||||
go func() {
|
||||
<-done
|
||||
s.Close()
|
||||
}()
|
||||
}
|
||||
if listExisting {
|
||||
if err := makeRequest(unix.AF_UNSPEC); err != nil {
|
||||
return err
|
||||
}
|
||||
// We have to wait for NLMSG_DONE before making AF_BRIDGE request
|
||||
}
|
||||
go func() {
|
||||
defer close(ch)
|
||||
for {
|
||||
msgs, from, err := s.Receive()
|
||||
if err != nil {
|
||||
if cberr != nil {
|
||||
cberr(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if from.Pid != nl.PidKernel {
|
||||
if cberr != nil {
|
||||
cberr(fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel))
|
||||
}
|
||||
continue
|
||||
}
|
||||
for _, m := range msgs {
|
||||
if m.Header.Type == unix.NLMSG_DONE {
|
||||
if listExisting {
|
||||
// This will be called after handling AF_UNSPEC
|
||||
// list request, we have to wait for NLMSG_DONE
|
||||
// before making another request
|
||||
if err := makeRequest(unix.AF_BRIDGE); err != nil {
|
||||
if cberr != nil {
|
||||
cberr(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
listExisting = false
|
||||
}
|
||||
continue
|
||||
}
|
||||
if m.Header.Type == unix.NLMSG_ERROR {
|
||||
native := nl.NativeEndian()
|
||||
error := int32(native.Uint32(m.Data[0:4]))
|
||||
if error == 0 {
|
||||
continue
|
||||
}
|
||||
if cberr != nil {
|
||||
cberr(syscall.Errno(-error))
|
||||
}
|
||||
return
|
||||
}
|
||||
neigh, err := NeighDeserialize(m.Data)
|
||||
if err != nil {
|
||||
if cberr != nil {
|
||||
cberr(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
ch <- NeighUpdate{Type: m.Header.Type, Neigh: *neigh}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
3
vendor/github.com/vishvananda/netlink/netlink.go
generated
vendored
3
vendor/github.com/vishvananda/netlink/netlink.go
generated
vendored
@@ -27,7 +27,8 @@ func ParseIPNet(s string) (*net.IPNet, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &net.IPNet{IP: ip, Mask: ipNet.Mask}, nil
|
||||
ipNet.IP = ip
|
||||
return ipNet, nil
|
||||
}
|
||||
|
||||
// NewIPNet generates an IPNet from an ip address using a netmask of 32 or 128.
|
||||
|
||||
18
vendor/github.com/vishvananda/netlink/netlink_unspecified.go
generated
vendored
18
vendor/github.com/vishvananda/netlink/netlink_unspecified.go
generated
vendored
@@ -16,7 +16,7 @@ func LinkSetMTU(link Link, mtu int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetMaster(link Link, master *Bridge) error {
|
||||
func LinkSetMaster(link Link, master Link) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
@@ -48,10 +48,18 @@ func LinkSetVfVlan(link Link, vf, vlan int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetVfVlanQos(link Link, vf, vlan, qos int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetVfTxRate(link Link, vf, rate int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetVfRate(link Link, vf, minRate, maxRate int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetNoMaster(link Link) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
@@ -64,6 +72,10 @@ func LinkSetXdpFd(link Link, fd int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetXdpFdWithFlags(link Link, fd, flags int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func LinkSetARPOff(link Link) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
@@ -152,6 +164,10 @@ func AddrAdd(link Link, addr *Addr) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func AddrReplace(link Link, addr *Addr) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func AddrDel(link Link, addr *Addr) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
141
vendor/github.com/vishvananda/netlink/netns_linux.go
generated
vendored
Normal file
141
vendor/github.com/vishvananda/netlink/netns_linux.go
generated
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
package netlink
|
||||
|
||||
// Network namespace ID functions
|
||||
//
|
||||
// The kernel has a weird concept called the network namespace ID.
|
||||
// This is different from the file reference in proc (and any bind-mounted
|
||||
// namespaces, etc.)
|
||||
//
|
||||
// Instead, namespaces can be assigned a numeric ID at any time. Once set,
|
||||
// the ID is fixed. The ID can either be set manually by the user, or
|
||||
// automatically, triggered by certain kernel actions. The most common kernel
|
||||
// action that triggers namespace ID creation is moving one end of a veth pair
|
||||
// in to that namespace.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// These can be replaced by the values from sys/unix when it is next released.
|
||||
const (
|
||||
_ = iota
|
||||
NETNSA_NSID
|
||||
NETNSA_PID
|
||||
NETNSA_FD
|
||||
)
|
||||
|
||||
// GetNetNsIdByPid looks up the network namespace ID for a given pid (really thread id).
|
||||
// Returns -1 if the namespace does not have an ID set.
|
||||
func (h *Handle) GetNetNsIdByPid(pid int) (int, error) {
|
||||
return h.getNetNsId(NETNSA_PID, uint32(pid))
|
||||
}
|
||||
|
||||
// GetNetNsIdByPid looks up the network namespace ID for a given pid (really thread id).
|
||||
// Returns -1 if the namespace does not have an ID set.
|
||||
func GetNetNsIdByPid(pid int) (int, error) {
|
||||
return pkgHandle.GetNetNsIdByPid(pid)
|
||||
}
|
||||
|
||||
// SetNetNSIdByPid sets the ID of the network namespace for a given pid (really thread id).
|
||||
// The ID can only be set for namespaces without an ID already set.
|
||||
func (h *Handle) SetNetNsIdByPid(pid, nsid int) error {
|
||||
return h.setNetNsId(NETNSA_PID, uint32(pid), uint32(nsid))
|
||||
}
|
||||
|
||||
// SetNetNSIdByPid sets the ID of the network namespace for a given pid (really thread id).
|
||||
// The ID can only be set for namespaces without an ID already set.
|
||||
func SetNetNsIdByPid(pid, nsid int) error {
|
||||
return pkgHandle.SetNetNsIdByPid(pid, nsid)
|
||||
}
|
||||
|
||||
// GetNetNsIdByFd looks up the network namespace ID for a given fd.
|
||||
// fd must be an open file descriptor to a namespace file.
|
||||
// Returns -1 if the namespace does not have an ID set.
|
||||
func (h *Handle) GetNetNsIdByFd(fd int) (int, error) {
|
||||
return h.getNetNsId(NETNSA_FD, uint32(fd))
|
||||
}
|
||||
|
||||
// GetNetNsIdByFd looks up the network namespace ID for a given fd.
|
||||
// fd must be an open file descriptor to a namespace file.
|
||||
// Returns -1 if the namespace does not have an ID set.
|
||||
func GetNetNsIdByFd(fd int) (int, error) {
|
||||
return pkgHandle.GetNetNsIdByFd(fd)
|
||||
}
|
||||
|
||||
// SetNetNSIdByFd sets the ID of the network namespace for a given fd.
|
||||
// fd must be an open file descriptor to a namespace file.
|
||||
// The ID can only be set for namespaces without an ID already set.
|
||||
func (h *Handle) SetNetNsIdByFd(fd, nsid int) error {
|
||||
return h.setNetNsId(NETNSA_FD, uint32(fd), uint32(nsid))
|
||||
}
|
||||
|
||||
// SetNetNSIdByFd sets the ID of the network namespace for a given fd.
|
||||
// fd must be an open file descriptor to a namespace file.
|
||||
// The ID can only be set for namespaces without an ID already set.
|
||||
func SetNetNsIdByFd(fd, nsid int) error {
|
||||
return pkgHandle.SetNetNsIdByFd(fd, nsid)
|
||||
}
|
||||
|
||||
// getNetNsId requests the netnsid for a given type-val pair
|
||||
// type should be either NETNSA_PID or NETNSA_FD
|
||||
func (h *Handle) getNetNsId(attrType int, val uint32) (int, error) {
|
||||
req := h.newNetlinkRequest(unix.RTM_GETNSID, unix.NLM_F_REQUEST)
|
||||
|
||||
rtgen := nl.NewRtGenMsg()
|
||||
req.AddData(rtgen)
|
||||
|
||||
b := make([]byte, 4, 4)
|
||||
native.PutUint32(b, val)
|
||||
attr := nl.NewRtAttr(attrType, b)
|
||||
req.AddData(attr)
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWNSID)
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
for _, m := range msgs {
|
||||
msg := nl.DeserializeRtGenMsg(m)
|
||||
|
||||
attrs, err := nl.ParseRouteAttr(m[msg.Len():])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
for _, attr := range attrs {
|
||||
switch attr.Attr.Type {
|
||||
case NETNSA_NSID:
|
||||
return int(int32(native.Uint32(attr.Value))), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf("unexpected empty result")
|
||||
}
|
||||
|
||||
// setNetNsId sets the netnsid for a given type-val pair
|
||||
// type should be either NETNSA_PID or NETNSA_FD
|
||||
// The ID can only be set for namespaces without an ID already set
|
||||
func (h *Handle) setNetNsId(attrType int, val uint32, newnsid uint32) error {
|
||||
req := h.newNetlinkRequest(unix.RTM_NEWNSID, unix.NLM_F_REQUEST|unix.NLM_F_ACK)
|
||||
|
||||
rtgen := nl.NewRtGenMsg()
|
||||
req.AddData(rtgen)
|
||||
|
||||
b := make([]byte, 4, 4)
|
||||
native.PutUint32(b, val)
|
||||
attr := nl.NewRtAttr(attrType, b)
|
||||
req.AddData(attr)
|
||||
|
||||
b1 := make([]byte, 4, 4)
|
||||
native.PutUint32(b1, newnsid)
|
||||
attr1 := nl.NewRtAttr(NETNSA_NSID, b1)
|
||||
req.AddData(attr1)
|
||||
|
||||
_, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWNSID)
|
||||
return err
|
||||
}
|
||||
19
vendor/github.com/vishvananda/netlink/netns_unspecified.go
generated
vendored
Normal file
19
vendor/github.com/vishvananda/netlink/netns_unspecified.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// +build !linux
|
||||
|
||||
package netlink
|
||||
|
||||
func GetNetNsIdByPid(pid int) (int, error) {
|
||||
return 0, ErrNotImplemented
|
||||
}
|
||||
|
||||
func SetNetNsIdByPid(pid, nsid int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func GetNetNsIdByFd(fd int) (int, error) {
|
||||
return 0, ErrNotImplemented
|
||||
}
|
||||
|
||||
func SetNetNsIdByFd(fd, nsid int) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
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 */
|
||||
// };
|
||||
|
||||
const IFA_CACHEINFO = 6
|
||||
const SizeofIfaCacheInfo = 0x10
|
||||
|
||||
type IfaCacheInfo struct {
|
||||
IfaPrefered uint32
|
||||
IfaValid uint32
|
||||
Cstamp uint32
|
||||
Tstamp uint32
|
||||
unix.IfaCacheinfo
|
||||
}
|
||||
|
||||
func (msg *IfaCacheInfo) Len() int {
|
||||
return SizeofIfaCacheInfo
|
||||
return unix.SizeofIfaCacheinfo
|
||||
}
|
||||
|
||||
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 {
|
||||
return (*(*[SizeofIfaCacheInfo]byte)(unsafe.Pointer(msg)))[:]
|
||||
return (*(*[unix.SizeofIfaCacheinfo]byte)(unsafe.Pointer(msg)))[:]
|
||||
}
|
||||
|
||||
4
vendor/github.com/vishvananda/netlink/nl/bridge_linux.go
generated
vendored
4
vendor/github.com/vishvananda/netlink/nl/bridge_linux.go
generated
vendored
@@ -11,8 +11,8 @@ const (
|
||||
|
||||
/* Bridge Flags */
|
||||
const (
|
||||
BRIDGE_FLAGS_MASTER = iota /* Bridge command to/from master */
|
||||
BRIDGE_FLAGS_SELF /* Bridge command to/from lowerdev */
|
||||
BRIDGE_FLAGS_MASTER = iota + 1 /* Bridge command to/from master */
|
||||
BRIDGE_FLAGS_SELF /* Bridge command to/from lowerdev */
|
||||
)
|
||||
|
||||
/* Bridge management nested attributes
|
||||
|
||||
45
vendor/github.com/vishvananda/netlink/nl/conntrack_linux.go
generated
vendored
45
vendor/github.com/vishvananda/netlink/nl/conntrack_linux.go
generated
vendored
@@ -40,9 +40,10 @@ const (
|
||||
NFNETLINK_V0 = 0
|
||||
)
|
||||
|
||||
// #define NLA_F_NESTED (1 << 15)
|
||||
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)
|
||||
)
|
||||
|
||||
// enum ctattr_type {
|
||||
@@ -76,12 +77,17 @@ const (
|
||||
// __CTA_MAX
|
||||
// };
|
||||
const (
|
||||
CTA_TUPLE_ORIG = 1
|
||||
CTA_TUPLE_REPLY = 2
|
||||
CTA_STATUS = 3
|
||||
CTA_TIMEOUT = 7
|
||||
CTA_MARK = 8
|
||||
CTA_PROTOINFO = 4
|
||||
CTA_TUPLE_ORIG = 1
|
||||
CTA_TUPLE_REPLY = 2
|
||||
CTA_STATUS = 3
|
||||
CTA_PROTOINFO = 4
|
||||
CTA_TIMEOUT = 7
|
||||
CTA_MARK = 8
|
||||
CTA_COUNTERS_ORIG = 9
|
||||
CTA_COUNTERS_REPLY = 10
|
||||
CTA_USE = 11
|
||||
CTA_ID = 12
|
||||
CTA_TIMESTAMP = 20
|
||||
)
|
||||
|
||||
// enum ctattr_tuple {
|
||||
@@ -163,6 +169,29 @@ const (
|
||||
CTA_PROTOINFO_TCP_FLAGS_REPLY = 5
|
||||
)
|
||||
|
||||
// enum ctattr_counters {
|
||||
// CTA_COUNTERS_UNSPEC,
|
||||
// CTA_COUNTERS_PACKETS, /* 64bit counters */
|
||||
// CTA_COUNTERS_BYTES, /* 64bit counters */
|
||||
// CTA_COUNTERS32_PACKETS, /* old 32bit counters, unused */
|
||||
// CTA_COUNTERS32_BYTES, /* old 32bit counters, unused */
|
||||
// CTA_COUNTERS_PAD,
|
||||
// __CTA_COUNTERS_M
|
||||
// };
|
||||
// #define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1)
|
||||
const (
|
||||
CTA_COUNTERS_PACKETS = 1
|
||||
CTA_COUNTERS_BYTES = 2
|
||||
)
|
||||
|
||||
// enum CTA TIMESTAMP TLVs
|
||||
// CTA_TIMESTAMP_START /* 64bit value */
|
||||
// CTA_TIMESTAMP_STOP /* 64bit value */
|
||||
const (
|
||||
CTA_TIMESTAMP_START = 1
|
||||
CTA_TIMESTAMP_STOP = 2
|
||||
)
|
||||
|
||||
// /* General form of address family dependent message.
|
||||
// */
|
||||
// struct nfgenmsg {
|
||||
|
||||
63
vendor/github.com/vishvananda/netlink/nl/devlink_linux.go
generated
vendored
Normal file
63
vendor/github.com/vishvananda/netlink/nl/devlink_linux.go
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
package nl
|
||||
|
||||
// All the following constants are coming from:
|
||||
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/devlink.h
|
||||
|
||||
const (
|
||||
GENL_DEVLINK_VERSION = 1
|
||||
GENL_DEVLINK_NAME = "devlink"
|
||||
)
|
||||
|
||||
const (
|
||||
DEVLINK_CMD_GET = 1
|
||||
DEVLINK_CMD_PORT_GET = 5
|
||||
DEVLINK_CMD_ESWITCH_GET = 29
|
||||
DEVLINK_CMD_ESWITCH_SET = 30
|
||||
)
|
||||
|
||||
const (
|
||||
DEVLINK_ATTR_BUS_NAME = 1
|
||||
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_INLINE_MODE = 26
|
||||
DEVLINK_ATTR_ESWITCH_ENCAP_MODE = 62
|
||||
DEVLINK_ATTR_PORT_FLAVOUR = 77
|
||||
)
|
||||
|
||||
const (
|
||||
DEVLINK_ESWITCH_MODE_LEGACY = 0
|
||||
DEVLINK_ESWITCH_MODE_SWITCHDEV = 1
|
||||
)
|
||||
|
||||
const (
|
||||
DEVLINK_ESWITCH_INLINE_MODE_NONE = 0
|
||||
DEVLINK_ESWITCH_INLINE_MODE_LINK = 1
|
||||
DEVLINK_ESWITCH_INLINE_MODE_NETWORK = 2
|
||||
DEVLINK_ESWITCH_INLINE_MODE_TRANSPORT = 3
|
||||
)
|
||||
|
||||
const (
|
||||
DEVLINK_ESWITCH_ENCAP_MODE_NONE = 0
|
||||
DEVLINK_ESWITCH_ENCAP_MODE_BASIC = 1
|
||||
)
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
const (
|
||||
DEVLINK_PORT_TYPE_NOTSET = 0
|
||||
DEVLINK_PORT_TYPE_AUTO = 1
|
||||
DEVLINK_PORT_TYPE_ETH = 2
|
||||
DEVLINK_PORT_TYPE_IB = 3
|
||||
)
|
||||
222
vendor/github.com/vishvananda/netlink/nl/ipset_linux.go
generated
vendored
Normal file
222
vendor/github.com/vishvananda/netlink/nl/ipset_linux.go
generated
vendored
Normal file
@@ -0,0 +1,222 @@
|
||||
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
|
||||
)
|
||||
|
||||
/* 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
|
||||
}
|
||||
}
|
||||
175
vendor/github.com/vishvananda/netlink/nl/link_linux.go
generated
vendored
175
vendor/github.com/vishvananda/netlink/nl/link_linux.go
generated
vendored
@@ -1,6 +1,8 @@
|
||||
package nl
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
@@ -13,7 +15,9 @@ const (
|
||||
IFLA_INFO_KIND
|
||||
IFLA_INFO_DATA
|
||||
IFLA_INFO_XSTATS
|
||||
IFLA_INFO_MAX = IFLA_INFO_XSTATS
|
||||
IFLA_INFO_SLAVE_KIND
|
||||
IFLA_INFO_SLAVE_DATA
|
||||
IFLA_INFO_MAX = IFLA_INFO_SLAVE_DATA
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -87,7 +91,8 @@ const (
|
||||
const (
|
||||
IFLA_IPVLAN_UNSPEC = iota
|
||||
IFLA_IPVLAN_MODE
|
||||
IFLA_IPVLAN_MAX = IFLA_IPVLAN_MODE
|
||||
IFLA_IPVLAN_FLAG
|
||||
IFLA_IPVLAN_MAX = IFLA_IPVLAN_FLAG
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -164,6 +169,24 @@ const (
|
||||
IFLA_BOND_SLAVE_PERM_HWADDR
|
||||
IFLA_BOND_SLAVE_QUEUE_ID
|
||||
IFLA_BOND_SLAVE_AD_AGGREGATOR_ID
|
||||
IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE
|
||||
IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE
|
||||
)
|
||||
|
||||
const (
|
||||
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_MAX = IFLA_GENEVE_LABEL
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -217,9 +240,11 @@ const (
|
||||
IFLA_VF_RSS_QUERY_EN /* RSS Redirection Table and Hash Key query
|
||||
* on/off switch
|
||||
*/
|
||||
IFLA_VF_STATS /* network device statistics */
|
||||
IFLA_VF_TRUST /* Trust state of VF */
|
||||
IFLA_VF_MAX = IFLA_VF_TRUST
|
||||
IFLA_VF_STATS /* network device statistics */
|
||||
IFLA_VF_TRUST /* Trust state of VF */
|
||||
IFLA_VF_IB_NODE_GUID /* VF Infiniband node GUID */
|
||||
IFLA_VF_IB_PORT_GUID /* VF Infiniband port GUID */
|
||||
IFLA_VF_MAX = IFLA_VF_IB_PORT_GUID
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -236,7 +261,9 @@ const (
|
||||
IFLA_VF_STATS_TX_BYTES
|
||||
IFLA_VF_STATS_BROADCAST
|
||||
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 (
|
||||
@@ -248,6 +275,7 @@ const (
|
||||
SizeofVfLinkState = 0x08
|
||||
SizeofVfRssQueryEn = 0x08
|
||||
SizeofVfTrust = 0x08
|
||||
SizeofVfGUID = 0x10
|
||||
)
|
||||
|
||||
// struct ifla_vf_mac {
|
||||
@@ -318,6 +346,59 @@ func (msg *VfTxRate) Serialize() []byte {
|
||||
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 {
|
||||
// __u32 vf;
|
||||
// __u32 min_tx_rate; /* Min Bandwidth in Mbps */
|
||||
@@ -430,6 +511,30 @@ func (msg *VfTrust) Serialize() []byte {
|
||||
return (*(*[SizeofVfTrust]byte)(unsafe.Pointer(msg)))[:]
|
||||
}
|
||||
|
||||
// struct ifla_vf_guid {
|
||||
// __u32 vf;
|
||||
// __u32 rsvd;
|
||||
// __u64 guid;
|
||||
// };
|
||||
|
||||
type VfGUID struct {
|
||||
Vf uint32
|
||||
Rsvd uint32
|
||||
GUID uint64
|
||||
}
|
||||
|
||||
func (msg *VfGUID) Len() int {
|
||||
return SizeofVfGUID
|
||||
}
|
||||
|
||||
func DeserializeVfGUID(b []byte) *VfGUID {
|
||||
return (*VfGUID)(unsafe.Pointer(&b[0:SizeofVfGUID][0]))
|
||||
}
|
||||
|
||||
func (msg *VfGUID) Serialize() []byte {
|
||||
return (*(*[SizeofVfGUID]byte)(unsafe.Pointer(msg)))[:]
|
||||
}
|
||||
|
||||
const (
|
||||
XDP_FLAGS_UPDATE_IF_NOEXIST = 1 << iota
|
||||
XDP_FLAGS_SKB_MODE
|
||||
@@ -446,6 +551,14 @@ const (
|
||||
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 (
|
||||
IFLA_IPTUN_UNSPEC = iota
|
||||
IFLA_IPTUN_LINK
|
||||
@@ -546,3 +659,53 @@ const (
|
||||
GTP_ROLE_GGSN = iota
|
||||
GTP_ROLE_SGSN
|
||||
)
|
||||
|
||||
const (
|
||||
IFLA_XFRM_UNSPEC = iota
|
||||
IFLA_XFRM_LINK
|
||||
IFLA_XFRM_IF_ID
|
||||
|
||||
IFLA_XFRM_MAX = iota - 1
|
||||
)
|
||||
|
||||
const (
|
||||
IFLA_TUN_UNSPEC = iota
|
||||
IFLA_TUN_OWNER
|
||||
IFLA_TUN_GROUP
|
||||
IFLA_TUN_TYPE
|
||||
IFLA_TUN_PI
|
||||
IFLA_TUN_VNET_HDR
|
||||
IFLA_TUN_PERSIST
|
||||
IFLA_TUN_MULTI_QUEUE
|
||||
IFLA_TUN_NUM_QUEUES
|
||||
IFLA_TUN_NUM_DISABLED_QUEUES
|
||||
IFLA_TUN_MAX = IFLA_TUN_NUM_DISABLED_QUEUES
|
||||
)
|
||||
|
||||
const (
|
||||
IFLA_IPOIB_UNSPEC = iota
|
||||
IFLA_IPOIB_PKEY
|
||||
IFLA_IPOIB_MODE
|
||||
IFLA_IPOIB_UMCAST
|
||||
IFLA_IPOIB_MAX = IFLA_IPOIB_UMCAST
|
||||
)
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
105
vendor/github.com/vishvananda/netlink/nl/nl_linux.go
generated
vendored
105
vendor/github.com/vishvananda/netlink/nl/nl_linux.go
generated
vendored
@@ -21,7 +21,13 @@ const (
|
||||
FAMILY_ALL = unix.AF_UNSPEC
|
||||
FAMILY_V4 = unix.AF_INET
|
||||
FAMILY_V6 = unix.AF_INET6
|
||||
FAMILY_MPLS = AF_MPLS
|
||||
FAMILY_MPLS = unix.AF_MPLS
|
||||
// Arbitrary set value (greater than default 4k) to allow receiving
|
||||
// from kernel more verbose messages e.g. for statistics,
|
||||
// tc rules or filters, or other more memory requiring data.
|
||||
RECEIVE_BUFFER_SIZE = 65536
|
||||
// Kernel netlink pid
|
||||
PidKernel uint32 = 0
|
||||
)
|
||||
|
||||
// SupportedNlFamilies contains the list of netlink families this netlink package supports
|
||||
@@ -29,6 +35,9 @@ var SupportedNlFamilies = []int{unix.NETLINK_ROUTE, unix.NETLINK_XFRM, unix.NETL
|
||||
|
||||
var nextSeqNr uint32
|
||||
|
||||
// Default netlink socket timeout, 60s
|
||||
var SocketTimeoutTv = unix.Timeval{Sec: 60, Usec: 0}
|
||||
|
||||
// GetIPFamily returns the family type of a net.IP.
|
||||
func GetIPFamily(ip net.IP) int {
|
||||
if len(ip) <= net.IPv4len {
|
||||
@@ -42,7 +51,7 @@ func GetIPFamily(ip net.IP) int {
|
||||
|
||||
var nativeEndian binary.ByteOrder
|
||||
|
||||
// Get native endianness for the system
|
||||
// NativeEndian gets native endianness for the system
|
||||
func NativeEndian() binary.ByteOrder {
|
||||
if nativeEndian == nil {
|
||||
var x uint32 = 0x01020304
|
||||
@@ -253,6 +262,29 @@ func NewIfInfomsgChild(parent *RtAttr, family int) *IfInfomsg {
|
||||
return msg
|
||||
}
|
||||
|
||||
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
|
||||
type RtAttr struct {
|
||||
unix.RtAttr
|
||||
@@ -271,15 +303,22 @@ func NewRtAttr(attrType int, data []byte) *RtAttr {
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new RtAttr obj anc add it as a child of an existing object
|
||||
// NewRtAttrChild adds an RtAttr as a child to the parent and returns the new attribute
|
||||
//
|
||||
// Deprecated: Use AddRtAttr() on the parent object
|
||||
func NewRtAttrChild(parent *RtAttr, attrType int, data []byte) *RtAttr {
|
||||
return parent.AddRtAttr(attrType, data)
|
||||
}
|
||||
|
||||
// AddRtAttr adds an RtAttr as a child and returns the new attribute
|
||||
func (a *RtAttr) AddRtAttr(attrType int, data []byte) *RtAttr {
|
||||
attr := NewRtAttr(attrType, data)
|
||||
parent.children = append(parent.children, attr)
|
||||
a.children = append(a.children, attr)
|
||||
return attr
|
||||
}
|
||||
|
||||
// AddChild adds an existing RtAttr as a child.
|
||||
func (a *RtAttr) AddChild(attr *RtAttr) {
|
||||
// AddChild adds an existing NetlinkRequestData as a child.
|
||||
func (a *RtAttr) AddChild(attr NetlinkRequestData) {
|
||||
a.children = append(a.children, attr)
|
||||
}
|
||||
|
||||
@@ -360,16 +399,12 @@ func (req *NetlinkRequest) Serialize() []byte {
|
||||
}
|
||||
|
||||
func (req *NetlinkRequest) AddData(data NetlinkRequestData) {
|
||||
if data != nil {
|
||||
req.Data = append(req.Data, data)
|
||||
}
|
||||
req.Data = append(req.Data, data)
|
||||
}
|
||||
|
||||
// AddRawData adds raw bytes to the end of the NetlinkRequest object during serialization
|
||||
func (req *NetlinkRequest) AddRawData(data []byte) {
|
||||
if data != nil {
|
||||
req.RawData = append(req.RawData, data...)
|
||||
}
|
||||
req.RawData = append(req.RawData, data...)
|
||||
}
|
||||
|
||||
// Execute the request against a the given sockType.
|
||||
@@ -394,6 +429,14 @@ func (req *NetlinkRequest) Execute(sockType int, resType uint16) ([][]byte, erro
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.SetSendTimeout(&SocketTimeoutTv); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := s.SetReceiveTimeout(&SocketTimeoutTv); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer s.Close()
|
||||
} else {
|
||||
s.Lock()
|
||||
@@ -413,10 +456,13 @@ func (req *NetlinkRequest) Execute(sockType int, resType uint16) ([][]byte, erro
|
||||
|
||||
done:
|
||||
for {
|
||||
msgs, err := s.Receive()
|
||||
msgs, from, err := s.Receive()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if from.Pid != PidKernel {
|
||||
return nil, fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, PidKernel)
|
||||
}
|
||||
for _, m := range msgs {
|
||||
if m.Header.Seq != req.Seq {
|
||||
if sharedSocket {
|
||||
@@ -425,12 +471,9 @@ done:
|
||||
return nil, fmt.Errorf("Wrong Seq nr %d, expected %d", m.Header.Seq, req.Seq)
|
||||
}
|
||||
if m.Header.Pid != pid {
|
||||
return nil, fmt.Errorf("Wrong pid %d, expected %d", m.Header.Pid, pid)
|
||||
continue
|
||||
}
|
||||
if m.Header.Type == unix.NLMSG_DONE {
|
||||
break done
|
||||
}
|
||||
if m.Header.Type == unix.NLMSG_ERROR {
|
||||
if m.Header.Type == unix.NLMSG_DONE || m.Header.Type == unix.NLMSG_ERROR {
|
||||
native := NativeEndian()
|
||||
error := int32(native.Uint32(m.Data[0:4]))
|
||||
if error == 0 {
|
||||
@@ -610,21 +653,31 @@ func (s *NetlinkSocket) Send(request *NetlinkRequest) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, error) {
|
||||
func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, *unix.SockaddrNetlink, error) {
|
||||
fd := int(atomic.LoadInt32(&s.fd))
|
||||
if fd < 0 {
|
||||
return nil, fmt.Errorf("Receive called on a closed socket")
|
||||
return nil, nil, fmt.Errorf("Receive called on a closed socket")
|
||||
}
|
||||
rb := make([]byte, unix.Getpagesize())
|
||||
nr, _, err := unix.Recvfrom(fd, rb, 0)
|
||||
var fromAddr *unix.SockaddrNetlink
|
||||
var rb [RECEIVE_BUFFER_SIZE]byte
|
||||
nr, from, err := unix.Recvfrom(fd, rb[:], 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
fromAddr, ok := from.(*unix.SockaddrNetlink)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("Error converting to netlink sockaddr")
|
||||
}
|
||||
if nr < unix.NLMSG_HDRLEN {
|
||||
return nil, fmt.Errorf("Got short response from netlink")
|
||||
return nil, nil, fmt.Errorf("Got short response from netlink")
|
||||
}
|
||||
rb = rb[:nr]
|
||||
return syscall.ParseNetlinkMessage(rb)
|
||||
rb2 := make([]byte, nr)
|
||||
copy(rb2, rb[:nr])
|
||||
nl, err := syscall.ParseNetlinkMessage(rb2)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return nl, fromAddr, nil
|
||||
}
|
||||
|
||||
// SetSendTimeout allows to set a send timeout on the socket
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
35
vendor/github.com/vishvananda/netlink/nl/rdma_link_linux.go
generated
vendored
Normal file
35
vendor/github.com/vishvananda/netlink/nl/rdma_link_linux.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
package nl
|
||||
|
||||
const (
|
||||
RDMA_NL_GET_CLIENT_SHIFT = 10
|
||||
)
|
||||
|
||||
const (
|
||||
RDMA_NL_NLDEV = 5
|
||||
)
|
||||
|
||||
const (
|
||||
RDMA_NLDEV_CMD_GET = 1
|
||||
RDMA_NLDEV_CMD_SET = 2
|
||||
RDMA_NLDEV_CMD_SYS_GET = 6
|
||||
RDMA_NLDEV_CMD_SYS_SET = 7
|
||||
)
|
||||
|
||||
const (
|
||||
RDMA_NLDEV_ATTR_DEV_INDEX = 1
|
||||
RDMA_NLDEV_ATTR_DEV_NAME = 2
|
||||
RDMA_NLDEV_ATTR_PORT_INDEX = 3
|
||||
RDMA_NLDEV_ATTR_CAP_FLAGS = 4
|
||||
RDMA_NLDEV_ATTR_FW_VERSION = 5
|
||||
RDMA_NLDEV_ATTR_NODE_GUID = 6
|
||||
RDMA_NLDEV_ATTR_SYS_IMAGE_GUID = 7
|
||||
RDMA_NLDEV_ATTR_SUBNET_PREFIX = 8
|
||||
RDMA_NLDEV_ATTR_LID = 9
|
||||
RDMA_NLDEV_ATTR_SM_LID = 10
|
||||
RDMA_NLDEV_ATTR_LMC = 11
|
||||
RDMA_NLDEV_ATTR_PORT_STATE = 12
|
||||
RDMA_NLDEV_ATTR_PORT_PHYS_STATE = 13
|
||||
RDMA_NLDEV_ATTR_DEV_NODE_TYPE = 14
|
||||
RDMA_NLDEV_SYS_ATTR_NETNS_MODE = 66
|
||||
RDMA_NLDEV_NET_NS_FD = 68
|
||||
)
|
||||
26
vendor/github.com/vishvananda/netlink/nl/route_linux.go
generated
vendored
26
vendor/github.com/vishvananda/netlink/nl/route_linux.go
generated
vendored
@@ -79,3 +79,29 @@ func (msg *RtNexthop) Serialize() []byte {
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
type RtGenMsg struct {
|
||||
unix.RtGenmsg
|
||||
}
|
||||
|
||||
func NewRtGenMsg() *RtGenMsg {
|
||||
return &RtGenMsg{
|
||||
RtGenmsg: unix.RtGenmsg{
|
||||
Family: unix.AF_UNSPEC,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (msg *RtGenMsg) Len() int {
|
||||
return rtaAlignOf(unix.SizeofRtGenmsg)
|
||||
}
|
||||
|
||||
func DeserializeRtGenMsg(b []byte) *RtGenMsg {
|
||||
return &RtGenMsg{RtGenmsg: unix.RtGenmsg{Family: b[0]}}
|
||||
}
|
||||
|
||||
func (msg *RtGenMsg) Serialize() []byte {
|
||||
out := make([]byte, msg.Len())
|
||||
out[0] = msg.Family
|
||||
return out
|
||||
}
|
||||
|
||||
43
vendor/github.com/vishvananda/netlink/nl/seg6_linux.go
generated
vendored
43
vendor/github.com/vishvananda/netlink/nl/seg6_linux.go
generated
vendored
@@ -99,6 +99,49 @@ func DecodeSEG6Encap(buf []byte) (int, []net.IP, error) {
|
||||
return mode, srh.Segments, nil
|
||||
}
|
||||
|
||||
func DecodeSEG6Srh(buf []byte) ([]net.IP, error) {
|
||||
native := NativeEndian()
|
||||
srh := IPv6SrHdr{
|
||||
nextHdr: buf[0],
|
||||
hdrLen: buf[1],
|
||||
routingType: buf[2],
|
||||
segmentsLeft: buf[3],
|
||||
firstSegment: buf[4],
|
||||
flags: buf[5],
|
||||
reserved: native.Uint16(buf[6:8]),
|
||||
}
|
||||
buf = buf[8:]
|
||||
if len(buf)%16 != 0 {
|
||||
err := fmt.Errorf("DecodeSEG6Srh: error parsing Segment List (buf len: %d)", len(buf))
|
||||
return nil, err
|
||||
}
|
||||
for len(buf) > 0 {
|
||||
srh.Segments = append(srh.Segments, net.IP(buf[:16]))
|
||||
buf = buf[16:]
|
||||
}
|
||||
return srh.Segments, nil
|
||||
}
|
||||
func EncodeSEG6Srh(segments []net.IP) ([]byte, error) {
|
||||
nsegs := len(segments) // nsegs: number of segments
|
||||
if nsegs == 0 {
|
||||
return nil, errors.New("EncodeSEG6Srh: No Segments")
|
||||
}
|
||||
b := make([]byte, 8, 8+len(segments)*16)
|
||||
native := NativeEndian()
|
||||
b[0] = 0 // srh.nextHdr (0 when calling netlink)
|
||||
b[1] = uint8(16 * nsegs >> 3) // srh.hdrLen (in 8-octets unit)
|
||||
b[2] = IPV6_SRCRT_TYPE_4 // srh.routingType (assigned by IANA)
|
||||
b[3] = uint8(nsegs - 1) // srh.segmentsLeft
|
||||
b[4] = uint8(nsegs - 1) // srh.firstSegment
|
||||
b[5] = 0 // srh.flags (SR6_FLAG1_HMAC for srh_hmac)
|
||||
// srh.reserved: Defined as "Tag" in draft-ietf-6man-segment-routing-header-07
|
||||
native.PutUint16(b[6:], 0) // srh.reserved
|
||||
for _, netIP := range segments {
|
||||
b = append(b, netIP...) // srh.Segments
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
func SEG6EncapModeString(mode int) string {
|
||||
switch mode {
|
||||
|
||||
76
vendor/github.com/vishvananda/netlink/nl/seg6local_linux.go
generated
vendored
Normal file
76
vendor/github.com/vishvananda/netlink/nl/seg6local_linux.go
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
package nl
|
||||
|
||||
import ()
|
||||
|
||||
// seg6local parameters
|
||||
const (
|
||||
SEG6_LOCAL_UNSPEC = iota
|
||||
SEG6_LOCAL_ACTION
|
||||
SEG6_LOCAL_SRH
|
||||
SEG6_LOCAL_TABLE
|
||||
SEG6_LOCAL_NH4
|
||||
SEG6_LOCAL_NH6
|
||||
SEG6_LOCAL_IIF
|
||||
SEG6_LOCAL_OIF
|
||||
__SEG6_LOCAL_MAX
|
||||
)
|
||||
const (
|
||||
SEG6_LOCAL_MAX = __SEG6_LOCAL_MAX
|
||||
)
|
||||
|
||||
// seg6local actions
|
||||
const (
|
||||
SEG6_LOCAL_ACTION_END = iota + 1 // 1
|
||||
SEG6_LOCAL_ACTION_END_X // 2
|
||||
SEG6_LOCAL_ACTION_END_T // 3
|
||||
SEG6_LOCAL_ACTION_END_DX2 // 4
|
||||
SEG6_LOCAL_ACTION_END_DX6 // 5
|
||||
SEG6_LOCAL_ACTION_END_DX4 // 6
|
||||
SEG6_LOCAL_ACTION_END_DT6 // 7
|
||||
SEG6_LOCAL_ACTION_END_DT4 // 8
|
||||
SEG6_LOCAL_ACTION_END_B6 // 9
|
||||
SEG6_LOCAL_ACTION_END_B6_ENCAPS // 10
|
||||
SEG6_LOCAL_ACTION_END_BM // 11
|
||||
SEG6_LOCAL_ACTION_END_S // 12
|
||||
SEG6_LOCAL_ACTION_END_AS // 13
|
||||
SEG6_LOCAL_ACTION_END_AM // 14
|
||||
__SEG6_LOCAL_ACTION_MAX
|
||||
)
|
||||
const (
|
||||
SEG6_LOCAL_ACTION_MAX = __SEG6_LOCAL_ACTION_MAX - 1
|
||||
)
|
||||
|
||||
// Helper functions
|
||||
func SEG6LocalActionString(action int) string {
|
||||
switch action {
|
||||
case SEG6_LOCAL_ACTION_END:
|
||||
return "End"
|
||||
case SEG6_LOCAL_ACTION_END_X:
|
||||
return "End.X"
|
||||
case SEG6_LOCAL_ACTION_END_T:
|
||||
return "End.T"
|
||||
case SEG6_LOCAL_ACTION_END_DX2:
|
||||
return "End.DX2"
|
||||
case SEG6_LOCAL_ACTION_END_DX6:
|
||||
return "End.DX6"
|
||||
case SEG6_LOCAL_ACTION_END_DX4:
|
||||
return "End.DX4"
|
||||
case SEG6_LOCAL_ACTION_END_DT6:
|
||||
return "End.DT6"
|
||||
case SEG6_LOCAL_ACTION_END_DT4:
|
||||
return "End.DT4"
|
||||
case SEG6_LOCAL_ACTION_END_B6:
|
||||
return "End.B6"
|
||||
case SEG6_LOCAL_ACTION_END_B6_ENCAPS:
|
||||
return "End.B6.Encaps"
|
||||
case SEG6_LOCAL_ACTION_END_BM:
|
||||
return "End.BM"
|
||||
case SEG6_LOCAL_ACTION_END_S:
|
||||
return "End.S"
|
||||
case SEG6_LOCAL_ACTION_END_AS:
|
||||
return "End.AS"
|
||||
case SEG6_LOCAL_ACTION_END_AM:
|
||||
return "End.AM"
|
||||
}
|
||||
return "unknown"
|
||||
}
|
||||
18
vendor/github.com/vishvananda/netlink/nl/syscall.go
generated
vendored
18
vendor/github.com/vishvananda/netlink/nl/syscall.go
generated
vendored
@@ -21,6 +21,13 @@ const (
|
||||
FRA_TABLE /* Extended table id */
|
||||
FRA_FWMASK /* mask for netfilter mark */
|
||||
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
|
||||
@@ -42,16 +49,6 @@ const (
|
||||
TCPDIAG_NOCOOKIE = 0xFFFFFFFF /* TCPDIAG_NOCOOKIE in net/ipv4/tcp_diag.h*/
|
||||
)
|
||||
|
||||
const (
|
||||
AF_MPLS = 28
|
||||
)
|
||||
|
||||
const (
|
||||
RTA_NEWDST = 0x13
|
||||
RTA_ENCAP_TYPE = 0x15
|
||||
RTA_ENCAP = 0x16
|
||||
)
|
||||
|
||||
// RTA_ENCAP subtype
|
||||
const (
|
||||
MPLS_IPTUNNEL_UNSPEC = iota
|
||||
@@ -67,6 +64,7 @@ const (
|
||||
LWTUNNEL_ENCAP_IP6
|
||||
LWTUNNEL_ENCAP_SEG6
|
||||
LWTUNNEL_ENCAP_BPF
|
||||
LWTUNNEL_ENCAP_SEG6_LOCAL
|
||||
)
|
||||
|
||||
// routing header types
|
||||
|
||||
275
vendor/github.com/vishvananda/netlink/nl/tc_linux.go
generated
vendored
275
vendor/github.com/vishvananda/netlink/nl/tc_linux.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package nl
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
@@ -64,6 +65,15 @@ const (
|
||||
TCA_PRIO_MAX = TCA_PRIO_MQ
|
||||
)
|
||||
|
||||
const (
|
||||
TCA_STATS_UNSPEC = iota
|
||||
TCA_STATS_BASIC
|
||||
TCA_STATS_RATE_EST
|
||||
TCA_STATS_QUEUE
|
||||
TCA_STATS_APP
|
||||
TCA_STATS_MAX = TCA_STATS_APP
|
||||
)
|
||||
|
||||
const (
|
||||
SizeofTcMsg = 0x14
|
||||
SizeofTcActionMsg = 0x04
|
||||
@@ -79,8 +89,14 @@ const (
|
||||
SizeofTcU32Key = 0x10
|
||||
SizeofTcU32Sel = 0x10 // without keys
|
||||
SizeofTcGen = 0x14
|
||||
SizeofTcConnmark = SizeofTcGen + 0x04
|
||||
SizeofTcMirred = SizeofTcGen + 0x08
|
||||
SizeofTcTunnelKey = SizeofTcGen + 0x04
|
||||
SizeofTcSkbEdit = SizeofTcGen
|
||||
SizeofTcPolice = 2*SizeofTcRateSpec + 0x20
|
||||
SizeofTcSfqQopt = 0x0b
|
||||
SizeofTcSfqRedStats = 0x18
|
||||
SizeofTcSfqQoptV1 = SizeofTcSfqQopt + SizeofTcSfqRedStats + 0x1c
|
||||
)
|
||||
|
||||
// struct tcmsg {
|
||||
@@ -412,6 +428,57 @@ func (x *TcHtbGlob) Serialize() []byte {
|
||||
return (*(*[SizeofTcHtbGlob]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
// HFSC
|
||||
|
||||
type Curve struct {
|
||||
m1 uint32
|
||||
d uint32
|
||||
m2 uint32
|
||||
}
|
||||
|
||||
type HfscCopt struct {
|
||||
Rsc Curve
|
||||
Fsc Curve
|
||||
Usc Curve
|
||||
}
|
||||
|
||||
func (c *Curve) Attrs() (uint32, uint32, uint32) {
|
||||
return c.m1, c.d, c.m2
|
||||
}
|
||||
|
||||
func (c *Curve) Set(m1 uint32, d uint32, m2 uint32) {
|
||||
c.m1 = m1
|
||||
c.d = d
|
||||
c.m2 = m2
|
||||
}
|
||||
|
||||
func DeserializeHfscCurve(b []byte) *Curve {
|
||||
return &Curve{
|
||||
m1: binary.LittleEndian.Uint32(b[0:4]),
|
||||
d: binary.LittleEndian.Uint32(b[4:8]),
|
||||
m2: binary.LittleEndian.Uint32(b[8:12]),
|
||||
}
|
||||
}
|
||||
|
||||
func SerializeHfscCurve(c *Curve) (b []byte) {
|
||||
t := make([]byte, binary.MaxVarintLen32)
|
||||
binary.LittleEndian.PutUint32(t, c.m1)
|
||||
b = append(b, t[:4]...)
|
||||
binary.LittleEndian.PutUint32(t, c.d)
|
||||
b = append(b, t[:4]...)
|
||||
binary.LittleEndian.PutUint32(t, c.m2)
|
||||
b = append(b, t[:4]...)
|
||||
return b
|
||||
}
|
||||
|
||||
type TcHfscOpt struct {
|
||||
Defcls uint16
|
||||
}
|
||||
|
||||
func (x *TcHfscOpt) Serialize() []byte {
|
||||
return (*(*[2]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
const (
|
||||
TCA_U32_UNSPEC = iota
|
||||
TCA_U32_CLASSID
|
||||
@@ -586,11 +653,47 @@ const (
|
||||
TCA_BPF_FD
|
||||
TCA_BPF_NAME
|
||||
TCA_BPF_FLAGS
|
||||
TCA_BPF_MAX = TCA_BPF_FLAGS
|
||||
TCA_BPF_FLAGS_GEN
|
||||
TCA_BPF_TAG
|
||||
TCA_BPF_ID
|
||||
TCA_BPF_MAX = TCA_BPF_ID
|
||||
)
|
||||
|
||||
type TcBpf TcGen
|
||||
|
||||
const (
|
||||
TCA_ACT_CONNMARK = 14
|
||||
)
|
||||
|
||||
const (
|
||||
TCA_CONNMARK_UNSPEC = iota
|
||||
TCA_CONNMARK_PARMS
|
||||
TCA_CONNMARK_TM
|
||||
TCA_CONNMARK_MAX = TCA_CONNMARK_TM
|
||||
)
|
||||
|
||||
// struct tc_connmark {
|
||||
// tc_gen;
|
||||
// __u16 zone;
|
||||
// };
|
||||
|
||||
type TcConnmark struct {
|
||||
TcGen
|
||||
Zone uint16
|
||||
}
|
||||
|
||||
func (msg *TcConnmark) Len() int {
|
||||
return SizeofTcConnmark
|
||||
}
|
||||
|
||||
func DeserializeTcConnmark(b []byte) *TcConnmark {
|
||||
return (*TcConnmark)(unsafe.Pointer(&b[0:SizeofTcConnmark][0]))
|
||||
}
|
||||
|
||||
func (x *TcConnmark) Serialize() []byte {
|
||||
return (*(*[SizeofTcConnmark]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
const (
|
||||
TCA_ACT_MIRRED = 8
|
||||
)
|
||||
@@ -626,6 +729,69 @@ func (x *TcMirred) Serialize() []byte {
|
||||
return (*(*[SizeofTcMirred]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
const (
|
||||
TCA_TUNNEL_KEY_UNSPEC = iota
|
||||
TCA_TUNNEL_KEY_TM
|
||||
TCA_TUNNEL_KEY_PARMS
|
||||
TCA_TUNNEL_KEY_ENC_IPV4_SRC
|
||||
TCA_TUNNEL_KEY_ENC_IPV4_DST
|
||||
TCA_TUNNEL_KEY_ENC_IPV6_SRC
|
||||
TCA_TUNNEL_KEY_ENC_IPV6_DST
|
||||
TCA_TUNNEL_KEY_ENC_KEY_ID
|
||||
TCA_TUNNEL_KEY_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 {
|
||||
TcGen
|
||||
Action int32
|
||||
}
|
||||
|
||||
func (x *TcTunnelKey) Len() int {
|
||||
return SizeofTcTunnelKey
|
||||
}
|
||||
|
||||
func DeserializeTunnelKey(b []byte) *TcTunnelKey {
|
||||
return (*TcTunnelKey)(unsafe.Pointer(&b[0:SizeofTcTunnelKey][0]))
|
||||
}
|
||||
|
||||
func (x *TcTunnelKey) Serialize() []byte {
|
||||
return (*(*[SizeofTcTunnelKey]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
const (
|
||||
TCA_SKBEDIT_UNSPEC = iota
|
||||
TCA_SKBEDIT_TM
|
||||
TCA_SKBEDIT_PARMS
|
||||
TCA_SKBEDIT_PRIORITY
|
||||
TCA_SKBEDIT_QUEUE_MAPPING
|
||||
TCA_SKBEDIT_MARK
|
||||
TCA_SKBEDIT_PAD
|
||||
TCA_SKBEDIT_PTYPE
|
||||
TCA_SKBEDIT_MAX = TCA_SKBEDIT_MARK
|
||||
)
|
||||
|
||||
type TcSkbEdit struct {
|
||||
TcGen
|
||||
}
|
||||
|
||||
func (x *TcSkbEdit) Len() int {
|
||||
return SizeofTcSkbEdit
|
||||
}
|
||||
|
||||
func DeserializeSkbEdit(b []byte) *TcSkbEdit {
|
||||
return (*TcSkbEdit)(unsafe.Pointer(&b[0:SizeofTcSkbEdit][0]))
|
||||
}
|
||||
|
||||
func (x *TcSkbEdit) Serialize() []byte {
|
||||
return (*(*[SizeofTcSkbEdit]byte)(unsafe.Pointer(x)))[:]
|
||||
}
|
||||
|
||||
// struct tc_police {
|
||||
// __u32 index;
|
||||
// int action;
|
||||
@@ -708,3 +874,110 @@ const (
|
||||
TCA_FQ_CODEL_DROP_BATCH_SIZE
|
||||
TCA_FQ_CODEL_MEMORY_LIMIT
|
||||
)
|
||||
|
||||
const (
|
||||
TCA_HFSC_UNSPEC = iota
|
||||
TCA_HFSC_RSC
|
||||
TCA_HFSC_FSC
|
||||
TCA_HFSC_USC
|
||||
)
|
||||
|
||||
// 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)))[:]
|
||||
}
|
||||
|
||||
62
vendor/github.com/vishvananda/netlink/nl/xfrm_linux.go
generated
vendored
62
vendor/github.com/vishvananda/netlink/nl/xfrm_linux.go
generated
vendored
@@ -50,34 +50,44 @@ const (
|
||||
// Attribute types
|
||||
const (
|
||||
/* Netlink message attributes. */
|
||||
XFRMA_UNSPEC = 0x00
|
||||
XFRMA_ALG_AUTH = 0x01 /* struct xfrm_algo */
|
||||
XFRMA_ALG_CRYPT = 0x02 /* struct xfrm_algo */
|
||||
XFRMA_ALG_COMP = 0x03 /* struct xfrm_algo */
|
||||
XFRMA_ENCAP = 0x04 /* struct xfrm_algo + struct xfrm_encap_tmpl */
|
||||
XFRMA_TMPL = 0x05 /* 1 or more struct xfrm_user_tmpl */
|
||||
XFRMA_SA = 0x06 /* struct xfrm_usersa_info */
|
||||
XFRMA_POLICY = 0x07 /* struct xfrm_userpolicy_info */
|
||||
XFRMA_SEC_CTX = 0x08 /* struct xfrm_sec_ctx */
|
||||
XFRMA_LTIME_VAL = 0x09
|
||||
XFRMA_REPLAY_VAL = 0x0a
|
||||
XFRMA_REPLAY_THRESH = 0x0b
|
||||
XFRMA_ETIMER_THRESH = 0x0c
|
||||
XFRMA_SRCADDR = 0x0d /* xfrm_address_t */
|
||||
XFRMA_COADDR = 0x0e /* xfrm_address_t */
|
||||
XFRMA_LASTUSED = 0x0f /* unsigned long */
|
||||
XFRMA_POLICY_TYPE = 0x10 /* struct xfrm_userpolicy_type */
|
||||
XFRMA_MIGRATE = 0x11
|
||||
XFRMA_ALG_AEAD = 0x12 /* struct xfrm_algo_aead */
|
||||
XFRMA_KMADDRESS = 0x13 /* struct xfrm_user_kmaddress */
|
||||
XFRMA_ALG_AUTH_TRUNC = 0x14 /* struct xfrm_algo_auth */
|
||||
XFRMA_MARK = 0x15 /* struct xfrm_mark */
|
||||
XFRMA_TFCPAD = 0x16 /* __u32 */
|
||||
XFRMA_REPLAY_ESN_VAL = 0x17 /* struct xfrm_replay_esn */
|
||||
XFRMA_SA_EXTRA_FLAGS = 0x18 /* __u32 */
|
||||
XFRMA_MAX = 0x18
|
||||
XFRMA_UNSPEC = iota
|
||||
XFRMA_ALG_AUTH /* struct xfrm_algo */
|
||||
XFRMA_ALG_CRYPT /* struct xfrm_algo */
|
||||
XFRMA_ALG_COMP /* struct xfrm_algo */
|
||||
XFRMA_ENCAP /* struct xfrm_algo + struct xfrm_encap_tmpl */
|
||||
XFRMA_TMPL /* 1 or more struct xfrm_user_tmpl */
|
||||
XFRMA_SA /* struct xfrm_usersa_info */
|
||||
XFRMA_POLICY /* struct xfrm_userpolicy_info */
|
||||
XFRMA_SEC_CTX /* struct xfrm_sec_ctx */
|
||||
XFRMA_LTIME_VAL
|
||||
XFRMA_REPLAY_VAL
|
||||
XFRMA_REPLAY_THRESH
|
||||
XFRMA_ETIMER_THRESH
|
||||
XFRMA_SRCADDR /* xfrm_address_t */
|
||||
XFRMA_COADDR /* xfrm_address_t */
|
||||
XFRMA_LASTUSED /* unsigned long */
|
||||
XFRMA_POLICY_TYPE /* struct xfrm_userpolicy_type */
|
||||
XFRMA_MIGRATE
|
||||
XFRMA_ALG_AEAD /* struct xfrm_algo_aead */
|
||||
XFRMA_KMADDRESS /* struct xfrm_user_kmaddress */
|
||||
XFRMA_ALG_AUTH_TRUNC /* struct xfrm_algo_auth */
|
||||
XFRMA_MARK /* struct xfrm_mark */
|
||||
XFRMA_TFCPAD /* __u32 */
|
||||
XFRMA_REPLAY_ESN_VAL /* struct xfrm_replay_esn */
|
||||
XFRMA_SA_EXTRA_FLAGS /* __u32 */
|
||||
XFRMA_PROTO /* __u8 */
|
||||
XFRMA_ADDRESS_FILTER /* struct xfrm_address_filter */
|
||||
XFRMA_PAD
|
||||
XFRMA_OFFLOAD_DEV /* struct xfrm_state_offload */
|
||||
XFRMA_SET_MARK /* __u32 */
|
||||
XFRMA_SET_MARK_MASK /* __u32 */
|
||||
XFRMA_IF_ID /* __u32 */
|
||||
|
||||
XFRMA_MAX = iota - 1
|
||||
)
|
||||
|
||||
const XFRMA_OUTPUT_MARK = XFRMA_SET_MARK
|
||||
|
||||
const (
|
||||
SizeofXfrmAddress = 0x10
|
||||
SizeofXfrmSelector = 0x38
|
||||
|
||||
2
vendor/github.com/vishvananda/netlink/nl/xfrm_state_linux.go
generated
vendored
2
vendor/github.com/vishvananda/netlink/nl/xfrm_state_linux.go
generated
vendored
@@ -13,7 +13,7 @@ const (
|
||||
SizeofXfrmAlgoAuth = 0x48
|
||||
SizeofXfrmAlgoAEAD = 0x48
|
||||
SizeofXfrmEncapTmpl = 0x18
|
||||
SizeofXfrmUsersaFlush = 0x8
|
||||
SizeofXfrmUsersaFlush = 0x1
|
||||
SizeofXfrmReplayStateEsn = 0x18
|
||||
)
|
||||
|
||||
|
||||
4
vendor/github.com/vishvananda/netlink/protinfo.go
generated
vendored
4
vendor/github.com/vishvananda/netlink/protinfo.go
generated
vendored
@@ -18,6 +18,10 @@ type Protinfo struct {
|
||||
|
||||
// String returns a list of enabled flags
|
||||
func (prot *Protinfo) String() string {
|
||||
if prot == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
|
||||
var boolStrings []string
|
||||
if prot.Hairpin {
|
||||
boolStrings = append(boolStrings, "Hairpin")
|
||||
|
||||
7
vendor/github.com/vishvananda/netlink/protinfo_linux.go
generated
vendored
7
vendor/github.com/vishvananda/netlink/protinfo_linux.go
generated
vendored
@@ -41,7 +41,7 @@ func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) {
|
||||
if err != nil {
|
||||
return pi, err
|
||||
}
|
||||
pi = *parseProtinfo(infos)
|
||||
pi = parseProtinfo(infos)
|
||||
|
||||
return pi, nil
|
||||
}
|
||||
@@ -49,8 +49,7 @@ func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) {
|
||||
return pi, fmt.Errorf("Device with index %d not found", base.Index)
|
||||
}
|
||||
|
||||
func parseProtinfo(infos []syscall.NetlinkRouteAttr) *Protinfo {
|
||||
var pi Protinfo
|
||||
func parseProtinfo(infos []syscall.NetlinkRouteAttr) (pi Protinfo) {
|
||||
for _, info := range infos {
|
||||
switch info.Attr.Type {
|
||||
case nl.IFLA_BRPORT_MODE:
|
||||
@@ -71,5 +70,5 @@ func parseProtinfo(infos []syscall.NetlinkRouteAttr) *Protinfo {
|
||||
pi.ProxyArpWiFi = byteToBool(info.Value[0])
|
||||
}
|
||||
}
|
||||
return &pi
|
||||
return
|
||||
}
|
||||
|
||||
88
vendor/github.com/vishvananda/netlink/qdisc.go
generated
vendored
88
vendor/github.com/vishvananda/netlink/qdisc.go
generated
vendored
@@ -176,6 +176,13 @@ type Netem struct {
|
||||
CorruptCorr uint32
|
||||
}
|
||||
|
||||
func (netem *Netem) String() string {
|
||||
return fmt.Sprintf(
|
||||
"{Latency: %v, Limit: %v, Loss: %v, Gap: %v, Duplicate: %v, Jitter: %v}",
|
||||
netem.Latency, netem.Limit, netem.Loss, netem.Gap, netem.Duplicate, netem.Jitter,
|
||||
)
|
||||
}
|
||||
|
||||
func (qdisc *Netem) Attrs() *QdiscAttrs {
|
||||
return &qdisc.QdiscAttrs
|
||||
}
|
||||
@@ -231,6 +238,33 @@ func (qdisc *GenericQdisc) Type() string {
|
||||
return qdisc.QdiscType
|
||||
}
|
||||
|
||||
type Hfsc struct {
|
||||
QdiscAttrs
|
||||
Defcls uint16
|
||||
}
|
||||
|
||||
func NewHfsc(attrs QdiscAttrs) *Hfsc {
|
||||
return &Hfsc{
|
||||
QdiscAttrs: attrs,
|
||||
Defcls: 1,
|
||||
}
|
||||
}
|
||||
|
||||
func (hfsc *Hfsc) Attrs() *QdiscAttrs {
|
||||
return &hfsc.QdiscAttrs
|
||||
}
|
||||
|
||||
func (hfsc *Hfsc) Type() string {
|
||||
return "hfsc"
|
||||
}
|
||||
|
||||
func (hfsc *Hfsc) String() string {
|
||||
return fmt.Sprintf(
|
||||
"{%v -- default: %d}",
|
||||
hfsc.Attrs(), hfsc.Defcls,
|
||||
)
|
||||
}
|
||||
|
||||
// Fq is a classless packet scheduler meant to be mostly used for locally generated traffic.
|
||||
type Fq struct {
|
||||
QdiscAttrs
|
||||
@@ -249,6 +283,13 @@ type Fq struct {
|
||||
LowRateThreshold uint32
|
||||
}
|
||||
|
||||
func (fq *Fq) String() string {
|
||||
return fmt.Sprintf(
|
||||
"{PacketLimit: %v, FlowPacketLimit: %v, Quantum: %v, InitialQuantum: %v, Pacing: %v, FlowDefaultRate: %v, FlowMaxRate: %v, Buckets: %v, FlowRefillDelay: %v, LowRateThreshold: %v}",
|
||||
fq.PacketLimit, fq.FlowPacketLimit, fq.Quantum, fq.InitialQuantum, fq.Pacing, fq.FlowDefaultRate, fq.FlowMaxRate, fq.Buckets, fq.FlowRefillDelay, fq.LowRateThreshold,
|
||||
)
|
||||
}
|
||||
|
||||
func NewFq(attrs QdiscAttrs) *Fq {
|
||||
return &Fq{
|
||||
QdiscAttrs: attrs,
|
||||
@@ -267,13 +308,22 @@ func (qdisc *Fq) Type() string {
|
||||
// FQ_Codel (Fair Queuing Controlled Delay) is queuing discipline that combines Fair Queuing with the CoDel AQM scheme.
|
||||
type FqCodel struct {
|
||||
QdiscAttrs
|
||||
Target uint32
|
||||
Limit uint32
|
||||
Interval uint32
|
||||
ECN uint32
|
||||
Flows uint32
|
||||
Quantum uint32
|
||||
// There are some more attributes here, but support for them seems not ubiquitous
|
||||
Target uint32
|
||||
Limit uint32
|
||||
Interval uint32
|
||||
ECN uint32
|
||||
Flows uint32
|
||||
Quantum uint32
|
||||
CEThreshold uint32
|
||||
DropBatchSize uint32
|
||||
MemoryLimit uint32
|
||||
}
|
||||
|
||||
func (fqcodel *FqCodel) String() string {
|
||||
return fmt.Sprintf(
|
||||
"{%v -- Target: %v, Limit: %v, Interval: %v, ECM: %v, Flows: %v, Quantum: %v}",
|
||||
fqcodel.Attrs(), fqcodel.Target, fqcodel.Limit, fqcodel.Interval, fqcodel.ECN, fqcodel.Flows, fqcodel.Quantum,
|
||||
)
|
||||
}
|
||||
|
||||
func NewFqCodel(attrs QdiscAttrs) *FqCodel {
|
||||
@@ -290,3 +340,27 @@ func (qdisc *FqCodel) Attrs() *QdiscAttrs {
|
||||
func (qdisc *FqCodel) Type() string {
|
||||
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"
|
||||
}
|
||||
|
||||
126
vendor/github.com/vishvananda/netlink/qdisc_linux.go
generated
vendored
126
vendor/github.com/vishvananda/netlink/qdisc_linux.go
generated
vendored
@@ -175,15 +175,15 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
|
||||
opt.Peakrate.Rate = uint32(qdisc.Peakrate)
|
||||
opt.Limit = qdisc.Limit
|
||||
opt.Buffer = qdisc.Buffer
|
||||
nl.NewRtAttrChild(options, nl.TCA_TBF_PARMS, opt.Serialize())
|
||||
options.AddRtAttr(nl.TCA_TBF_PARMS, opt.Serialize())
|
||||
if qdisc.Rate >= uint64(1<<32) {
|
||||
nl.NewRtAttrChild(options, nl.TCA_TBF_RATE64, nl.Uint64Attr(qdisc.Rate))
|
||||
options.AddRtAttr(nl.TCA_TBF_RATE64, nl.Uint64Attr(qdisc.Rate))
|
||||
}
|
||||
if qdisc.Peakrate >= uint64(1<<32) {
|
||||
nl.NewRtAttrChild(options, nl.TCA_TBF_PRATE64, nl.Uint64Attr(qdisc.Peakrate))
|
||||
options.AddRtAttr(nl.TCA_TBF_PRATE64, nl.Uint64Attr(qdisc.Peakrate))
|
||||
}
|
||||
if qdisc.Peakrate > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_TBF_PBURST, nl.Uint32Attr(qdisc.Minburst))
|
||||
options.AddRtAttr(nl.TCA_TBF_PBURST, nl.Uint32Attr(qdisc.Minburst))
|
||||
}
|
||||
case *Htb:
|
||||
opt := nl.TcHtbGlob{}
|
||||
@@ -193,8 +193,12 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
|
||||
// TODO: Handle Debug properly. For now default to 0
|
||||
opt.Debug = qdisc.Debug
|
||||
opt.DirectPkts = qdisc.DirectPkts
|
||||
nl.NewRtAttrChild(options, nl.TCA_HTB_INIT, opt.Serialize())
|
||||
// nl.NewRtAttrChild(options, nl.TCA_HTB_DIRECT_QLEN, opt.Serialize())
|
||||
options.AddRtAttr(nl.TCA_HTB_INIT, opt.Serialize())
|
||||
// options.AddRtAttr(nl.TCA_HTB_DIRECT_QLEN, opt.Serialize())
|
||||
case *Hfsc:
|
||||
opt := nl.TcHfscOpt{}
|
||||
opt.Defcls = qdisc.Defcls
|
||||
options = nl.NewRtAttr(nl.TCA_OPTIONS, opt.Serialize())
|
||||
case *Netem:
|
||||
opt := nl.TcNetemQopt{}
|
||||
opt.Latency = qdisc.Latency
|
||||
@@ -211,21 +215,21 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
|
||||
corr.DupCorr = qdisc.DuplicateCorr
|
||||
|
||||
if corr.DelayCorr > 0 || corr.LossCorr > 0 || corr.DupCorr > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_NETEM_CORR, corr.Serialize())
|
||||
options.AddRtAttr(nl.TCA_NETEM_CORR, corr.Serialize())
|
||||
}
|
||||
// Corruption
|
||||
corruption := nl.TcNetemCorrupt{}
|
||||
corruption.Probability = qdisc.CorruptProb
|
||||
corruption.Correlation = qdisc.CorruptCorr
|
||||
if corruption.Probability > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_NETEM_CORRUPT, corruption.Serialize())
|
||||
options.AddRtAttr(nl.TCA_NETEM_CORRUPT, corruption.Serialize())
|
||||
}
|
||||
// Reorder
|
||||
reorder := nl.TcNetemReorder{}
|
||||
reorder.Probability = qdisc.ReorderProb
|
||||
reorder.Correlation = qdisc.ReorderCorr
|
||||
if reorder.Probability > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_NETEM_REORDER, reorder.Serialize())
|
||||
options.AddRtAttr(nl.TCA_NETEM_REORDER, reorder.Serialize())
|
||||
}
|
||||
case *Ingress:
|
||||
// ingress filters must use the proper handle
|
||||
@@ -233,50 +237,70 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
|
||||
return fmt.Errorf("Ingress filters must set Parent to HANDLE_INGRESS")
|
||||
}
|
||||
case *FqCodel:
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_ECN, nl.Uint32Attr((uint32(qdisc.ECN))))
|
||||
options.AddRtAttr(nl.TCA_FQ_CODEL_ECN, nl.Uint32Attr((uint32(qdisc.ECN))))
|
||||
if qdisc.Limit > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_LIMIT, nl.Uint32Attr((uint32(qdisc.Limit))))
|
||||
options.AddRtAttr(nl.TCA_FQ_CODEL_LIMIT, nl.Uint32Attr((uint32(qdisc.Limit))))
|
||||
}
|
||||
if qdisc.Interval > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_INTERVAL, nl.Uint32Attr((uint32(qdisc.Interval))))
|
||||
options.AddRtAttr(nl.TCA_FQ_CODEL_INTERVAL, nl.Uint32Attr((uint32(qdisc.Interval))))
|
||||
}
|
||||
if qdisc.Flows > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_FLOWS, nl.Uint32Attr((uint32(qdisc.Flows))))
|
||||
options.AddRtAttr(nl.TCA_FQ_CODEL_FLOWS, nl.Uint32Attr((uint32(qdisc.Flows))))
|
||||
}
|
||||
if qdisc.Quantum > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_CODEL_QUANTUM, nl.Uint32Attr((uint32(qdisc.Quantum))))
|
||||
options.AddRtAttr(nl.TCA_FQ_CODEL_QUANTUM, nl.Uint32Attr((uint32(qdisc.Quantum))))
|
||||
}
|
||||
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:
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_RATE_ENABLE, nl.Uint32Attr((uint32(qdisc.Pacing))))
|
||||
options.AddRtAttr(nl.TCA_FQ_RATE_ENABLE, nl.Uint32Attr((uint32(qdisc.Pacing))))
|
||||
|
||||
if qdisc.Buckets > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_BUCKETS_LOG, nl.Uint32Attr((uint32(qdisc.Buckets))))
|
||||
options.AddRtAttr(nl.TCA_FQ_BUCKETS_LOG, nl.Uint32Attr((uint32(qdisc.Buckets))))
|
||||
}
|
||||
if qdisc.LowRateThreshold > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_LOW_RATE_THRESHOLD, nl.Uint32Attr((uint32(qdisc.LowRateThreshold))))
|
||||
options.AddRtAttr(nl.TCA_FQ_LOW_RATE_THRESHOLD, nl.Uint32Attr((uint32(qdisc.LowRateThreshold))))
|
||||
}
|
||||
if qdisc.Quantum > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_QUANTUM, nl.Uint32Attr((uint32(qdisc.Quantum))))
|
||||
options.AddRtAttr(nl.TCA_FQ_QUANTUM, nl.Uint32Attr((uint32(qdisc.Quantum))))
|
||||
}
|
||||
if qdisc.InitialQuantum > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_INITIAL_QUANTUM, nl.Uint32Attr((uint32(qdisc.InitialQuantum))))
|
||||
options.AddRtAttr(nl.TCA_FQ_INITIAL_QUANTUM, nl.Uint32Attr((uint32(qdisc.InitialQuantum))))
|
||||
}
|
||||
if qdisc.FlowRefillDelay > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_FLOW_REFILL_DELAY, nl.Uint32Attr((uint32(qdisc.FlowRefillDelay))))
|
||||
options.AddRtAttr(nl.TCA_FQ_FLOW_REFILL_DELAY, nl.Uint32Attr((uint32(qdisc.FlowRefillDelay))))
|
||||
}
|
||||
if qdisc.FlowPacketLimit > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_FLOW_PLIMIT, nl.Uint32Attr((uint32(qdisc.FlowPacketLimit))))
|
||||
options.AddRtAttr(nl.TCA_FQ_FLOW_PLIMIT, nl.Uint32Attr((uint32(qdisc.FlowPacketLimit))))
|
||||
}
|
||||
if qdisc.FlowMaxRate > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_FLOW_MAX_RATE, nl.Uint32Attr((uint32(qdisc.FlowMaxRate))))
|
||||
options.AddRtAttr(nl.TCA_FQ_FLOW_MAX_RATE, nl.Uint32Attr((uint32(qdisc.FlowMaxRate))))
|
||||
}
|
||||
if qdisc.FlowDefaultRate > 0 {
|
||||
nl.NewRtAttrChild(options, nl.TCA_FQ_FLOW_DEFAULT_RATE, nl.Uint32Attr((uint32(qdisc.FlowDefaultRate))))
|
||||
options.AddRtAttr(nl.TCA_FQ_FLOW_DEFAULT_RATE, nl.Uint32Attr((uint32(qdisc.FlowDefaultRate))))
|
||||
}
|
||||
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:
|
||||
options = nil
|
||||
}
|
||||
|
||||
req.AddData(options)
|
||||
if options != nil {
|
||||
req.AddData(options)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -348,10 +372,14 @@ func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
|
||||
qdisc = &Htb{}
|
||||
case "fq":
|
||||
qdisc = &Fq{}
|
||||
case "hfsc":
|
||||
qdisc = &Hfsc{}
|
||||
case "fq_codel":
|
||||
qdisc = &FqCodel{}
|
||||
case "netem":
|
||||
qdisc = &Netem{}
|
||||
case "sfq":
|
||||
qdisc = &Sfq{}
|
||||
default:
|
||||
qdisc = &GenericQdisc{QdiscType: qdiscType}
|
||||
}
|
||||
@@ -375,6 +403,10 @@ func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
|
||||
if err := parseTbfData(qdisc, data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "hfsc":
|
||||
if err := parseHfscData(qdisc, attr.Value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "htb":
|
||||
data, err := nl.ParseRouteAttr(attr.Value)
|
||||
if err != nil {
|
||||
@@ -403,6 +435,10 @@ func (h *Handle) QdiscList(link Link) ([]Qdisc, error) {
|
||||
if err := parseNetemData(qdisc, attr.Value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "sfq":
|
||||
if err := parseSfqData(qdisc, attr.Value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// no options for ingress
|
||||
}
|
||||
@@ -469,11 +505,24 @@ func parseFqCodelData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
|
||||
fqCodel.Flows = native.Uint32(datum.Value)
|
||||
case nl.TCA_FQ_CODEL_QUANTUM:
|
||||
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
|
||||
}
|
||||
|
||||
func parseHfscData(qdisc Qdisc, data []byte) error {
|
||||
Hfsc := qdisc.(*Hfsc)
|
||||
native = nl.NativeEndian()
|
||||
Hfsc.Defcls = native.Uint16(data)
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseFqData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
|
||||
native = nl.NativeEndian()
|
||||
fq := qdisc.(*Fq)
|
||||
@@ -561,6 +610,17 @@ func parseTbfData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
|
||||
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 (
|
||||
TIME_UNITS_PER_SEC = 1000000
|
||||
)
|
||||
@@ -577,10 +637,10 @@ func initClock() {
|
||||
return
|
||||
}
|
||||
parts := strings.Split(strings.TrimSpace(string(data)), " ")
|
||||
if len(parts) < 3 {
|
||||
if len(parts) < 4 {
|
||||
return
|
||||
}
|
||||
var vals [3]uint64
|
||||
var vals [4]uint64
|
||||
for i := range vals {
|
||||
val, err := strconv.ParseUint(parts[i], 16, 32)
|
||||
if err != nil {
|
||||
@@ -594,7 +654,12 @@ func initClock() {
|
||||
}
|
||||
clockFactor = float64(vals[2]) / TIME_UNITS_PER_SEC
|
||||
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 {
|
||||
@@ -642,6 +707,7 @@ func latency(rate uint64, limit, buffer uint32) float64 {
|
||||
return TIME_UNITS_PER_SEC*(float64(limit)/float64(rate)) - float64(tick2Time(buffer))
|
||||
}
|
||||
|
||||
func Xmittime(rate uint64, size uint32) float64 {
|
||||
return TickInUsec() * TIME_UNITS_PER_SEC * (float64(size) / float64(rate))
|
||||
func Xmittime(rate uint64, size uint32) uint32 {
|
||||
// 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))))
|
||||
}
|
||||
|
||||
280
vendor/github.com/vishvananda/netlink/rdma_link_linux.go
generated
vendored
Normal file
280
vendor/github.com/vishvananda/netlink/rdma_link_linux.go
generated
vendored
Normal file
@@ -0,0 +1,280 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// LinkAttrs represents data shared by most link types
|
||||
type RdmaLinkAttrs struct {
|
||||
Index uint32
|
||||
Name string
|
||||
FirmwareVersion string
|
||||
NodeGuid string
|
||||
SysImageGuid string
|
||||
}
|
||||
|
||||
// Link represents a rdma device from netlink.
|
||||
type RdmaLink struct {
|
||||
Attrs RdmaLinkAttrs
|
||||
}
|
||||
|
||||
func getProtoField(clientType int, op int) int {
|
||||
return ((clientType << nl.RDMA_NL_GET_CLIENT_SHIFT) | op)
|
||||
}
|
||||
|
||||
func uint64ToGuidString(guid uint64) string {
|
||||
//Convert to byte array
|
||||
sysGuidBytes := new(bytes.Buffer)
|
||||
binary.Write(sysGuidBytes, binary.LittleEndian, guid)
|
||||
|
||||
//Convert to HardwareAddr
|
||||
sysGuidNet := net.HardwareAddr(sysGuidBytes.Bytes())
|
||||
|
||||
//Get the String
|
||||
return sysGuidNet.String()
|
||||
}
|
||||
|
||||
func executeOneGetRdmaLink(data []byte) (*RdmaLink, error) {
|
||||
|
||||
link := RdmaLink{}
|
||||
|
||||
reader := bytes.NewReader(data)
|
||||
for reader.Len() >= 4 {
|
||||
_, attrType, len, value := parseNfAttrTLV(reader)
|
||||
|
||||
switch attrType {
|
||||
case nl.RDMA_NLDEV_ATTR_DEV_INDEX:
|
||||
var Index uint32
|
||||
r := bytes.NewReader(value)
|
||||
binary.Read(r, nl.NativeEndian(), &Index)
|
||||
link.Attrs.Index = Index
|
||||
case nl.RDMA_NLDEV_ATTR_DEV_NAME:
|
||||
link.Attrs.Name = string(value[0 : len-1])
|
||||
case nl.RDMA_NLDEV_ATTR_FW_VERSION:
|
||||
link.Attrs.FirmwareVersion = string(value[0 : len-1])
|
||||
case nl.RDMA_NLDEV_ATTR_NODE_GUID:
|
||||
var guid uint64
|
||||
r := bytes.NewReader(value)
|
||||
binary.Read(r, nl.NativeEndian(), &guid)
|
||||
link.Attrs.NodeGuid = uint64ToGuidString(guid)
|
||||
case nl.RDMA_NLDEV_ATTR_SYS_IMAGE_GUID:
|
||||
var sysGuid uint64
|
||||
r := bytes.NewReader(value)
|
||||
binary.Read(r, nl.NativeEndian(), &sysGuid)
|
||||
link.Attrs.SysImageGuid = uint64ToGuidString(sysGuid)
|
||||
}
|
||||
if (len % 4) != 0 {
|
||||
// Skip pad bytes
|
||||
reader.Seek(int64(4-(len%4)), seekCurrent)
|
||||
}
|
||||
}
|
||||
return &link, nil
|
||||
}
|
||||
|
||||
func 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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var res []*RdmaLink
|
||||
for _, m := range msgs {
|
||||
link, err := executeOneGetRdmaLink(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res = append(res, link)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// RdmaLinkByName finds a link by name and returns a pointer to the object if
|
||||
// found and nil error, otherwise returns error code.
|
||||
func RdmaLinkByName(name string) (*RdmaLink, error) {
|
||||
return pkgHandle.RdmaLinkByName(name)
|
||||
}
|
||||
|
||||
// RdmaLinkByName finds a link by name and returns a pointer to the object if
|
||||
// found and nil error, otherwise returns error code.
|
||||
func (h *Handle) RdmaLinkByName(name string) (*RdmaLink, error) {
|
||||
links, err := h.RdmaLinkList()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
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
|
||||
// or error otherwise.
|
||||
// Equivalent to: `rdma dev set $old_devname name $name`
|
||||
func RdmaLinkSetName(link *RdmaLink, name string) error {
|
||||
return pkgHandle.RdmaLinkSetName(link, name)
|
||||
}
|
||||
|
||||
// RdmaLinkSetName sets the name of the rdma link device. Return nil on success
|
||||
// or error otherwise.
|
||||
// Equivalent to: `rdma dev set $old_devname name $name`
|
||||
func (h *Handle) RdmaLinkSetName(link *RdmaLink, name string) error {
|
||||
proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_SET)
|
||||
req := h.newNetlinkRequest(proto, unix.NLM_F_ACK)
|
||||
|
||||
b := make([]byte, 4)
|
||||
native.PutUint32(b, uint32(link.Attrs.Index))
|
||||
data := nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_DEV_INDEX, b)
|
||||
req.AddData(data)
|
||||
|
||||
b = make([]byte, len(name)+1)
|
||||
copy(b, name)
|
||||
data = nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_DEV_NAME, b)
|
||||
req.AddData(data)
|
||||
|
||||
return execRdmaSetLink(req)
|
||||
}
|
||||
|
||||
func netnsModeToString(mode uint8) string {
|
||||
switch mode {
|
||||
case 0:
|
||||
return "exclusive"
|
||||
case 1:
|
||||
return "shared"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
func executeOneGetRdmaNetnsMode(data []byte) (string, error) {
|
||||
reader := bytes.NewReader(data)
|
||||
for reader.Len() >= 4 {
|
||||
_, attrType, len, value := parseNfAttrTLV(reader)
|
||||
|
||||
switch attrType {
|
||||
case nl.RDMA_NLDEV_SYS_ATTR_NETNS_MODE:
|
||||
var mode uint8
|
||||
r := bytes.NewReader(value)
|
||||
binary.Read(r, nl.NativeEndian(), &mode)
|
||||
return netnsModeToString(mode), nil
|
||||
}
|
||||
if (len % 4) != 0 {
|
||||
// Skip pad bytes
|
||||
reader.Seek(int64(4-(len%4)), seekCurrent)
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("Invalid netns mode")
|
||||
}
|
||||
|
||||
// RdmaSystemGetNetnsMode gets the net namespace mode for RDMA subsystem
|
||||
// Returns mode string and error status as nil on success or returns error
|
||||
// otherwise.
|
||||
// Equivalent to: `rdma system show netns'
|
||||
func RdmaSystemGetNetnsMode() (string, error) {
|
||||
return pkgHandle.RdmaSystemGetNetnsMode()
|
||||
}
|
||||
|
||||
// RdmaSystemGetNetnsMode gets the net namespace mode for RDMA subsystem
|
||||
// Returns mode string and error status as nil on success or returns error
|
||||
// otherwise.
|
||||
// Equivalent to: `rdma system show netns'
|
||||
func (h *Handle) RdmaSystemGetNetnsMode() (string, error) {
|
||||
|
||||
proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_SYS_GET)
|
||||
req := h.newNetlinkRequest(proto, unix.NLM_F_ACK)
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_RDMA, 0)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(msgs) == 0 {
|
||||
return "", fmt.Errorf("No valid response from kernel")
|
||||
}
|
||||
return executeOneGetRdmaNetnsMode(msgs[0])
|
||||
}
|
||||
|
||||
func netnsModeStringToUint8(mode string) (uint8, error) {
|
||||
switch mode {
|
||||
case "exclusive":
|
||||
return 0, nil
|
||||
case "shared":
|
||||
return 1, nil
|
||||
default:
|
||||
return 0, fmt.Errorf("Invalid mode; %q", mode)
|
||||
}
|
||||
}
|
||||
|
||||
// RdmaSystemSetNetnsMode sets the net namespace mode for RDMA subsystem
|
||||
// Returns nil on success or appropriate error code.
|
||||
// Equivalent to: `rdma system set netns { shared | exclusive }'
|
||||
func RdmaSystemSetNetnsMode(NewMode string) error {
|
||||
return pkgHandle.RdmaSystemSetNetnsMode(NewMode)
|
||||
}
|
||||
|
||||
// RdmaSystemSetNetnsMode sets the net namespace mode for RDMA subsystem
|
||||
// Returns nil on success or appropriate error code.
|
||||
// Equivalent to: `rdma system set netns { shared | exclusive }'
|
||||
func (h *Handle) RdmaSystemSetNetnsMode(NewMode string) error {
|
||||
value, err := netnsModeStringToUint8(NewMode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_SYS_SET)
|
||||
req := h.newNetlinkRequest(proto, unix.NLM_F_ACK)
|
||||
|
||||
data := nl.NewRtAttr(nl.RDMA_NLDEV_SYS_ATTR_NETNS_MODE, []byte{value})
|
||||
req.AddData(data)
|
||||
|
||||
_, err = req.Execute(unix.NETLINK_RDMA, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
// RdmaLinkSetNsFd puts the RDMA device into a new network namespace. The
|
||||
// fd must be an open file descriptor to a network namespace.
|
||||
// Similar to: `rdma dev set $dev netns $ns`
|
||||
func RdmaLinkSetNsFd(link *RdmaLink, fd uint32) error {
|
||||
return pkgHandle.RdmaLinkSetNsFd(link, fd)
|
||||
}
|
||||
|
||||
// RdmaLinkSetNsFd puts the RDMA device into a new network namespace. The
|
||||
// fd must be an open file descriptor to a network namespace.
|
||||
// Similar to: `rdma dev set $dev netns $ns`
|
||||
func (h *Handle) RdmaLinkSetNsFd(link *RdmaLink, fd uint32) error {
|
||||
proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_SET)
|
||||
req := h.newNetlinkRequest(proto, unix.NLM_F_ACK)
|
||||
|
||||
data := nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_DEV_INDEX,
|
||||
nl.Uint32Attr(link.Attrs.Index))
|
||||
req.AddData(data)
|
||||
|
||||
data = nl.NewRtAttr(nl.RDMA_NLDEV_NET_NS_FD, nl.Uint32Attr(fd))
|
||||
req.AddData(data)
|
||||
|
||||
return execRdmaSetLink(req)
|
||||
}
|
||||
63
vendor/github.com/vishvananda/netlink/route.go
generated
vendored
63
vendor/github.com/vishvananda/netlink/route.go
generated
vendored
@@ -27,26 +27,44 @@ type Encap interface {
|
||||
Equal(Encap) bool
|
||||
}
|
||||
|
||||
//Protocol describe what was the originator of the route
|
||||
type RouteProtocol int
|
||||
|
||||
// Route represents a netlink route.
|
||||
type Route struct {
|
||||
LinkIndex int
|
||||
ILinkIndex int
|
||||
Scope Scope
|
||||
Dst *net.IPNet
|
||||
Src net.IP
|
||||
Gw net.IP
|
||||
MultiPath []*NexthopInfo
|
||||
Protocol int
|
||||
Priority int
|
||||
Table int
|
||||
Type int
|
||||
Tos int
|
||||
Flags int
|
||||
MPLSDst *int
|
||||
NewDst Destination
|
||||
Encap Encap
|
||||
MTU int
|
||||
AdvMSS int
|
||||
LinkIndex int
|
||||
ILinkIndex int
|
||||
Scope Scope
|
||||
Dst *net.IPNet
|
||||
Src net.IP
|
||||
Gw net.IP
|
||||
MultiPath []*NexthopInfo
|
||||
Protocol RouteProtocol
|
||||
Priority int
|
||||
Table int
|
||||
Type int
|
||||
Tos int
|
||||
Flags int
|
||||
MPLSDst *int
|
||||
NewDst Destination
|
||||
Encap Encap
|
||||
Via Destination
|
||||
MTU int
|
||||
Window int
|
||||
Rtt int
|
||||
RttVar int
|
||||
Ssthresh int
|
||||
Cwnd int
|
||||
AdvMSS int
|
||||
Reordering int
|
||||
Hoplimit int
|
||||
InitCwnd int
|
||||
Features int
|
||||
RtoMin int
|
||||
InitRwnd int
|
||||
QuickACK int
|
||||
Congctl string
|
||||
FastOpenNoCookie int
|
||||
}
|
||||
|
||||
func (r Route) String() string {
|
||||
@@ -65,6 +83,9 @@ func (r Route) String() string {
|
||||
if r.Encap != nil {
|
||||
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))
|
||||
if len(r.MultiPath) > 0 {
|
||||
elems = append(elems, fmt.Sprintf("Gw: %s", r.MultiPath))
|
||||
@@ -89,9 +110,11 @@ func (r Route) Equal(x Route) bool {
|
||||
r.Table == x.Table &&
|
||||
r.Type == x.Type &&
|
||||
r.Tos == x.Tos &&
|
||||
r.Hoplimit == x.Hoplimit &&
|
||||
r.Flags == x.Flags &&
|
||||
(r.MPLSDst == x.MPLSDst || (r.MPLSDst != nil && x.MPLSDst != nil && *r.MPLSDst == *x.MPLSDst)) &&
|
||||
(r.NewDst == x.NewDst || (r.NewDst != nil && r.NewDst.Equal(x.NewDst))) &&
|
||||
(r.Via == x.Via || (r.Via != nil && r.Via.Equal(x.Via))) &&
|
||||
(r.Encap == x.Encap || (r.Encap != nil && r.Encap.Equal(x.Encap)))
|
||||
}
|
||||
|
||||
@@ -121,6 +144,7 @@ type NexthopInfo struct {
|
||||
Flags int
|
||||
NewDst Destination
|
||||
Encap Encap
|
||||
Via Destination
|
||||
}
|
||||
|
||||
func (n *NexthopInfo) String() string {
|
||||
@@ -132,6 +156,9 @@ func (n *NexthopInfo) String() string {
|
||||
if n.Encap != nil {
|
||||
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("Gw: %s", n.Gw))
|
||||
elems = append(elems, fmt.Sprintf("Flags: %s", n.ListFlags()))
|
||||
|
||||
548
vendor/github.com/vishvananda/netlink/route_linux.go
generated
vendored
548
vendor/github.com/vishvananda/netlink/route_linux.go
generated
vendored
@@ -1,8 +1,11 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
@@ -21,6 +24,23 @@ const (
|
||||
SCOPE_NOWHERE Scope = unix.RT_SCOPE_NOWHERE
|
||||
)
|
||||
|
||||
func (s Scope) String() string {
|
||||
switch s {
|
||||
case SCOPE_UNIVERSE:
|
||||
return "universe"
|
||||
case SCOPE_SITE:
|
||||
return "site"
|
||||
case SCOPE_LINK:
|
||||
return "link"
|
||||
case SCOPE_HOST:
|
||||
return "host"
|
||||
case SCOPE_NOWHERE:
|
||||
return "nowhere"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
RT_FILTER_PROTOCOL uint64 = 1 << (1 + iota)
|
||||
RT_FILTER_SCOPE
|
||||
@@ -32,6 +52,10 @@ const (
|
||||
RT_FILTER_SRC
|
||||
RT_FILTER_GW
|
||||
RT_FILTER_TABLE
|
||||
RT_FILTER_HOPLIMIT
|
||||
RT_FILTER_PRIORITY
|
||||
RT_FILTER_MARK
|
||||
RT_FILTER_MASK
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -207,6 +231,7 @@ func (e *SEG6Encap) Decode(buf []byte) error {
|
||||
}
|
||||
buf = buf[:l] // make sure buf size upper limit is Length
|
||||
typ := native.Uint16(buf[2:])
|
||||
// LWTUNNEL_ENCAP_SEG6 has only one attr type SEG6_IPTUNNEL_SRH
|
||||
if typ != nl.SEG6_IPTUNNEL_SRH {
|
||||
return fmt.Errorf("unknown SEG6 Type: %d", typ)
|
||||
}
|
||||
@@ -259,6 +284,244 @@ func (e *SEG6Encap) Equal(x Encap) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// SEG6LocalEncap definitions
|
||||
type SEG6LocalEncap struct {
|
||||
Flags [nl.SEG6_LOCAL_MAX]bool
|
||||
Action int
|
||||
Segments []net.IP // from SRH in seg6_local_lwt
|
||||
Table int // table id for End.T and End.DT6
|
||||
InAddr net.IP
|
||||
In6Addr net.IP
|
||||
Iif int
|
||||
Oif int
|
||||
}
|
||||
|
||||
func (e *SEG6LocalEncap) Type() int {
|
||||
return nl.LWTUNNEL_ENCAP_SEG6_LOCAL
|
||||
}
|
||||
func (e *SEG6LocalEncap) Decode(buf []byte) error {
|
||||
attrs, err := nl.ParseRouteAttr(buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
native := nl.NativeEndian()
|
||||
for _, attr := range attrs {
|
||||
switch attr.Attr.Type {
|
||||
case nl.SEG6_LOCAL_ACTION:
|
||||
e.Action = int(native.Uint32(attr.Value[0:4]))
|
||||
e.Flags[nl.SEG6_LOCAL_ACTION] = true
|
||||
case nl.SEG6_LOCAL_SRH:
|
||||
e.Segments, err = nl.DecodeSEG6Srh(attr.Value[:])
|
||||
e.Flags[nl.SEG6_LOCAL_SRH] = true
|
||||
case nl.SEG6_LOCAL_TABLE:
|
||||
e.Table = int(native.Uint32(attr.Value[0:4]))
|
||||
e.Flags[nl.SEG6_LOCAL_TABLE] = true
|
||||
case nl.SEG6_LOCAL_NH4:
|
||||
e.InAddr = net.IP(attr.Value[0:4])
|
||||
e.Flags[nl.SEG6_LOCAL_NH4] = true
|
||||
case nl.SEG6_LOCAL_NH6:
|
||||
e.In6Addr = net.IP(attr.Value[0:16])
|
||||
e.Flags[nl.SEG6_LOCAL_NH6] = true
|
||||
case nl.SEG6_LOCAL_IIF:
|
||||
e.Iif = int(native.Uint32(attr.Value[0:4]))
|
||||
e.Flags[nl.SEG6_LOCAL_IIF] = true
|
||||
case nl.SEG6_LOCAL_OIF:
|
||||
e.Oif = int(native.Uint32(attr.Value[0:4]))
|
||||
e.Flags[nl.SEG6_LOCAL_OIF] = true
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
func (e *SEG6LocalEncap) Encode() ([]byte, error) {
|
||||
var err error
|
||||
native := nl.NativeEndian()
|
||||
res := make([]byte, 8)
|
||||
native.PutUint16(res, 8) // length
|
||||
native.PutUint16(res[2:], nl.SEG6_LOCAL_ACTION)
|
||||
native.PutUint32(res[4:], uint32(e.Action))
|
||||
if e.Flags[nl.SEG6_LOCAL_SRH] {
|
||||
srh, err := nl.EncodeSEG6Srh(e.Segments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
attr := make([]byte, 4)
|
||||
native.PutUint16(attr, uint16(len(srh)+4))
|
||||
native.PutUint16(attr[2:], nl.SEG6_LOCAL_SRH)
|
||||
attr = append(attr, srh...)
|
||||
res = append(res, attr...)
|
||||
}
|
||||
if e.Flags[nl.SEG6_LOCAL_TABLE] {
|
||||
attr := make([]byte, 8)
|
||||
native.PutUint16(attr, 8)
|
||||
native.PutUint16(attr[2:], nl.SEG6_LOCAL_TABLE)
|
||||
native.PutUint32(attr[4:], uint32(e.Table))
|
||||
res = append(res, attr...)
|
||||
}
|
||||
if e.Flags[nl.SEG6_LOCAL_NH4] {
|
||||
attr := make([]byte, 4)
|
||||
native.PutUint16(attr, 8)
|
||||
native.PutUint16(attr[2:], nl.SEG6_LOCAL_NH4)
|
||||
ipv4 := e.InAddr.To4()
|
||||
if ipv4 == nil {
|
||||
err = fmt.Errorf("SEG6_LOCAL_NH4 has invalid IPv4 address")
|
||||
return nil, err
|
||||
}
|
||||
attr = append(attr, ipv4...)
|
||||
res = append(res, attr...)
|
||||
}
|
||||
if e.Flags[nl.SEG6_LOCAL_NH6] {
|
||||
attr := make([]byte, 4)
|
||||
native.PutUint16(attr, 20)
|
||||
native.PutUint16(attr[2:], nl.SEG6_LOCAL_NH6)
|
||||
attr = append(attr, e.In6Addr...)
|
||||
res = append(res, attr...)
|
||||
}
|
||||
if e.Flags[nl.SEG6_LOCAL_IIF] {
|
||||
attr := make([]byte, 8)
|
||||
native.PutUint16(attr, 8)
|
||||
native.PutUint16(attr[2:], nl.SEG6_LOCAL_IIF)
|
||||
native.PutUint32(attr[4:], uint32(e.Iif))
|
||||
res = append(res, attr...)
|
||||
}
|
||||
if e.Flags[nl.SEG6_LOCAL_OIF] {
|
||||
attr := make([]byte, 8)
|
||||
native.PutUint16(attr, 8)
|
||||
native.PutUint16(attr[2:], nl.SEG6_LOCAL_OIF)
|
||||
native.PutUint32(attr[4:], uint32(e.Oif))
|
||||
res = append(res, attr...)
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
func (e *SEG6LocalEncap) String() string {
|
||||
strs := make([]string, 0, nl.SEG6_LOCAL_MAX)
|
||||
strs = append(strs, fmt.Sprintf("action %s", nl.SEG6LocalActionString(e.Action)))
|
||||
|
||||
if e.Flags[nl.SEG6_LOCAL_TABLE] {
|
||||
strs = append(strs, fmt.Sprintf("table %d", e.Table))
|
||||
}
|
||||
if e.Flags[nl.SEG6_LOCAL_NH4] {
|
||||
strs = append(strs, fmt.Sprintf("nh4 %s", e.InAddr))
|
||||
}
|
||||
if e.Flags[nl.SEG6_LOCAL_NH6] {
|
||||
strs = append(strs, fmt.Sprintf("nh6 %s", e.In6Addr))
|
||||
}
|
||||
if e.Flags[nl.SEG6_LOCAL_IIF] {
|
||||
link, err := LinkByIndex(e.Iif)
|
||||
if err != nil {
|
||||
strs = append(strs, fmt.Sprintf("iif %d", e.Iif))
|
||||
} else {
|
||||
strs = append(strs, fmt.Sprintf("iif %s", link.Attrs().Name))
|
||||
}
|
||||
}
|
||||
if e.Flags[nl.SEG6_LOCAL_OIF] {
|
||||
link, err := LinkByIndex(e.Oif)
|
||||
if err != nil {
|
||||
strs = append(strs, fmt.Sprintf("oif %d", e.Oif))
|
||||
} else {
|
||||
strs = append(strs, fmt.Sprintf("oif %s", link.Attrs().Name))
|
||||
}
|
||||
}
|
||||
if e.Flags[nl.SEG6_LOCAL_SRH] {
|
||||
segs := make([]string, 0, len(e.Segments))
|
||||
//append segment backwards (from n to 0) since seg#0 is the last segment.
|
||||
for i := len(e.Segments); i > 0; i-- {
|
||||
segs = append(segs, fmt.Sprintf("%s", e.Segments[i-1]))
|
||||
}
|
||||
strs = append(strs, fmt.Sprintf("segs %d [ %s ]", len(e.Segments), strings.Join(segs, " ")))
|
||||
}
|
||||
return strings.Join(strs, " ")
|
||||
}
|
||||
func (e *SEG6LocalEncap) Equal(x Encap) bool {
|
||||
o, ok := x.(*SEG6LocalEncap)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if e == o {
|
||||
return true
|
||||
}
|
||||
if e == nil || o == nil {
|
||||
return false
|
||||
}
|
||||
// compare all arrays first
|
||||
for i := range e.Flags {
|
||||
if e.Flags[i] != o.Flags[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if len(e.Segments) != len(o.Segments) {
|
||||
return false
|
||||
}
|
||||
for i := range e.Segments {
|
||||
if !e.Segments[i].Equal(o.Segments[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
// compare values
|
||||
if !e.InAddr.Equal(o.InAddr) || !e.In6Addr.Equal(o.In6Addr) {
|
||||
return false
|
||||
}
|
||||
if e.Action != o.Action || e.Table != o.Table || e.Iif != o.Iif || e.Oif != o.Oif {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
type Via struct {
|
||||
AddrFamily int
|
||||
Addr net.IP
|
||||
}
|
||||
|
||||
func (v *Via) Equal(x Destination) bool {
|
||||
o, ok := x.(*Via)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if v.AddrFamily == x.Family() && v.Addr.Equal(o.Addr) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (v *Via) String() string {
|
||||
return fmt.Sprintf("Family: %d, Address: %s", v.AddrFamily, v.Addr.String())
|
||||
}
|
||||
|
||||
func (v *Via) Family() int {
|
||||
return v.AddrFamily
|
||||
}
|
||||
|
||||
func (v *Via) Encode() ([]byte, error) {
|
||||
buf := &bytes.Buffer{}
|
||||
err := binary.Write(buf, native, uint16(v.AddrFamily))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = binary.Write(buf, native, v.Addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func (v *Via) Decode(b []byte) error {
|
||||
native := nl.NativeEndian()
|
||||
if len(b) < 6 {
|
||||
return fmt.Errorf("decoding failed: buffer too small (%d bytes)", len(b))
|
||||
}
|
||||
v.AddrFamily = int(native.Uint16(b[0:2]))
|
||||
if v.AddrFamily == nl.FAMILY_V4 {
|
||||
v.Addr = net.IP(b[2:6])
|
||||
return nil
|
||||
} else if v.AddrFamily == nl.FAMILY_V6 {
|
||||
if len(b) < 18 {
|
||||
return fmt.Errorf("decoding failed: buffer too small (%d bytes)", len(b))
|
||||
}
|
||||
v.Addr = net.IP(b[2:])
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("decoding failed: address family %d unknown", v.AddrFamily)
|
||||
}
|
||||
|
||||
// RouteAdd will add a route to the system.
|
||||
// Equivalent to: `ip route add $route`
|
||||
func RouteAdd(route *Route) error {
|
||||
@@ -273,6 +536,32 @@ func (h *Handle) RouteAdd(route *Route) error {
|
||||
return h.routeHandle(route, req, nl.NewRtMsg())
|
||||
}
|
||||
|
||||
// RouteAppend will append a route to the system.
|
||||
// Equivalent to: `ip route append $route`
|
||||
func RouteAppend(route *Route) error {
|
||||
return pkgHandle.RouteAppend(route)
|
||||
}
|
||||
|
||||
// RouteAppend will append a route to the system.
|
||||
// Equivalent to: `ip route append $route`
|
||||
func (h *Handle) RouteAppend(route *Route) error {
|
||||
flags := unix.NLM_F_CREATE | unix.NLM_F_APPEND | unix.NLM_F_ACK
|
||||
req := h.newNetlinkRequest(unix.RTM_NEWROUTE, flags)
|
||||
return h.routeHandle(route, req, nl.NewRtMsg())
|
||||
}
|
||||
|
||||
// RouteAddEcmp will add a route to the system.
|
||||
func RouteAddEcmp(route *Route) error {
|
||||
return pkgHandle.RouteAddEcmp(route)
|
||||
}
|
||||
|
||||
// RouteAddEcmp will add a route to the system.
|
||||
func (h *Handle) RouteAddEcmp(route *Route) error {
|
||||
flags := unix.NLM_F_CREATE | unix.NLM_F_ACK
|
||||
req := h.newNetlinkRequest(unix.RTM_NEWROUTE, flags)
|
||||
return h.routeHandle(route, req, nl.NewRtMsg())
|
||||
}
|
||||
|
||||
// RouteReplace will add a route to the system.
|
||||
// Equivalent to: `ip route replace $route`
|
||||
func RouteReplace(route *Route) error {
|
||||
@@ -335,18 +624,18 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(nl.RTA_NEWDST, buf))
|
||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_NEWDST, buf))
|
||||
}
|
||||
|
||||
if route.Encap != nil {
|
||||
buf := make([]byte, 2)
|
||||
native.PutUint16(buf, uint16(route.Encap.Type()))
|
||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(nl.RTA_ENCAP_TYPE, buf))
|
||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_ENCAP_TYPE, buf))
|
||||
buf, err := route.Encap.Encode()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(nl.RTA_ENCAP, buf))
|
||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_ENCAP, buf))
|
||||
}
|
||||
|
||||
if route.Src != nil {
|
||||
@@ -380,6 +669,14 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
|
||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_GATEWAY, gwData))
|
||||
}
|
||||
|
||||
if route.Via != nil {
|
||||
buf, err := route.Via.Encode()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to encode RTA_VIA: %v", err)
|
||||
}
|
||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_VIA, buf))
|
||||
}
|
||||
|
||||
if len(route.MultiPath) > 0 {
|
||||
buf := []byte{}
|
||||
for _, nh := range route.MultiPath {
|
||||
@@ -410,17 +707,24 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
children = append(children, nl.NewRtAttr(nl.RTA_NEWDST, buf))
|
||||
children = append(children, nl.NewRtAttr(unix.RTA_NEWDST, buf))
|
||||
}
|
||||
if nh.Encap != nil {
|
||||
buf := make([]byte, 2)
|
||||
native.PutUint16(buf, uint16(nh.Encap.Type()))
|
||||
rtAttrs = append(rtAttrs, nl.NewRtAttr(nl.RTA_ENCAP_TYPE, buf))
|
||||
children = append(children, nl.NewRtAttr(unix.RTA_ENCAP_TYPE, buf))
|
||||
buf, err := nh.Encap.Encode()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
children = append(children, nl.NewRtAttr(nl.RTA_ENCAP, buf))
|
||||
children = append(children, nl.NewRtAttr(unix.RTA_ENCAP, buf))
|
||||
}
|
||||
if nh.Via != nil {
|
||||
buf, err := nh.Via.Encode()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
children = append(children, nl.NewRtAttr(unix.RTA_VIA, buf))
|
||||
}
|
||||
rtnh.Children = children
|
||||
buf = append(buf, rtnh.Serialize()...)
|
||||
@@ -455,15 +759,70 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
|
||||
}
|
||||
|
||||
var metrics []*nl.RtAttr
|
||||
// TODO: support other rta_metric values
|
||||
if route.MTU > 0 {
|
||||
b := nl.Uint32Attr(uint32(route.MTU))
|
||||
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_MTU, b))
|
||||
}
|
||||
if route.Window > 0 {
|
||||
b := nl.Uint32Attr(uint32(route.Window))
|
||||
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_WINDOW, b))
|
||||
}
|
||||
if route.Rtt > 0 {
|
||||
b := nl.Uint32Attr(uint32(route.Rtt))
|
||||
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_RTT, b))
|
||||
}
|
||||
if route.RttVar > 0 {
|
||||
b := nl.Uint32Attr(uint32(route.RttVar))
|
||||
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_RTTVAR, b))
|
||||
}
|
||||
if route.Ssthresh > 0 {
|
||||
b := nl.Uint32Attr(uint32(route.Ssthresh))
|
||||
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_SSTHRESH, b))
|
||||
}
|
||||
if route.Cwnd > 0 {
|
||||
b := nl.Uint32Attr(uint32(route.Cwnd))
|
||||
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_CWND, b))
|
||||
}
|
||||
if route.AdvMSS > 0 {
|
||||
b := nl.Uint32Attr(uint32(route.AdvMSS))
|
||||
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_ADVMSS, b))
|
||||
}
|
||||
if route.Reordering > 0 {
|
||||
b := nl.Uint32Attr(uint32(route.Reordering))
|
||||
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_REORDERING, b))
|
||||
}
|
||||
if route.Hoplimit > 0 {
|
||||
b := nl.Uint32Attr(uint32(route.Hoplimit))
|
||||
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_HOPLIMIT, b))
|
||||
}
|
||||
if route.InitCwnd > 0 {
|
||||
b := nl.Uint32Attr(uint32(route.InitCwnd))
|
||||
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_INITCWND, b))
|
||||
}
|
||||
if route.Features > 0 {
|
||||
b := nl.Uint32Attr(uint32(route.Features))
|
||||
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_FEATURES, b))
|
||||
}
|
||||
if route.RtoMin > 0 {
|
||||
b := nl.Uint32Attr(uint32(route.RtoMin))
|
||||
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_RTO_MIN, b))
|
||||
}
|
||||
if route.InitRwnd > 0 {
|
||||
b := nl.Uint32Attr(uint32(route.InitRwnd))
|
||||
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_INITRWND, b))
|
||||
}
|
||||
if route.QuickACK > 0 {
|
||||
b := nl.Uint32Attr(uint32(route.QuickACK))
|
||||
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_QUICKACK, b))
|
||||
}
|
||||
if route.Congctl != "" {
|
||||
b := nl.ZeroTerminated(route.Congctl)
|
||||
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_CC_ALGO, b))
|
||||
}
|
||||
if route.FastOpenNoCookie > 0 {
|
||||
b := nl.Uint32Attr(uint32(route.FastOpenNoCookie))
|
||||
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_FASTOPEN_NO_COOKIE, b))
|
||||
}
|
||||
|
||||
if metrics != nil {
|
||||
attr := nl.NewRtAttr(unix.RTA_METRICS, nil)
|
||||
@@ -574,6 +933,8 @@ func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64)
|
||||
continue
|
||||
}
|
||||
}
|
||||
case filterMask&RT_FILTER_HOPLIMIT != 0 && route.Hoplimit != filter.Hoplimit:
|
||||
continue
|
||||
}
|
||||
}
|
||||
res = append(res, route)
|
||||
@@ -590,7 +951,7 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||
}
|
||||
route := Route{
|
||||
Scope: Scope(msg.Scope),
|
||||
Protocol: int(msg.Protocol),
|
||||
Protocol: RouteProtocol(int(msg.Protocol)),
|
||||
Table: int(msg.Table),
|
||||
Type: int(msg.Type),
|
||||
Tos: int(msg.Tos),
|
||||
@@ -649,7 +1010,7 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||
switch attr.Attr.Type {
|
||||
case unix.RTA_GATEWAY:
|
||||
info.Gw = net.IP(attr.Value)
|
||||
case nl.RTA_NEWDST:
|
||||
case unix.RTA_NEWDST:
|
||||
var d Destination
|
||||
switch msg.Family {
|
||||
case nl.FAMILY_MPLS:
|
||||
@@ -659,10 +1020,16 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||
return nil, nil, err
|
||||
}
|
||||
info.NewDst = d
|
||||
case nl.RTA_ENCAP_TYPE:
|
||||
case unix.RTA_ENCAP_TYPE:
|
||||
encapType = attr
|
||||
case nl.RTA_ENCAP:
|
||||
case unix.RTA_ENCAP:
|
||||
encap = attr
|
||||
case unix.RTA_VIA:
|
||||
d := &Via{}
|
||||
if err := d.Decode(attr.Value); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
info.Via = d
|
||||
}
|
||||
}
|
||||
|
||||
@@ -690,7 +1057,7 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||
route.MultiPath = append(route.MultiPath, info)
|
||||
rest = buf
|
||||
}
|
||||
case nl.RTA_NEWDST:
|
||||
case unix.RTA_NEWDST:
|
||||
var d Destination
|
||||
switch msg.Family {
|
||||
case nl.FAMILY_MPLS:
|
||||
@@ -700,9 +1067,15 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||
return route, err
|
||||
}
|
||||
route.NewDst = d
|
||||
case nl.RTA_ENCAP_TYPE:
|
||||
case unix.RTA_VIA:
|
||||
v := &Via{}
|
||||
if err := v.Decode(attr.Value); err != nil {
|
||||
return route, err
|
||||
}
|
||||
route.Via = v
|
||||
case unix.RTA_ENCAP_TYPE:
|
||||
encapType = attr
|
||||
case nl.RTA_ENCAP:
|
||||
case unix.RTA_ENCAP:
|
||||
encap = attr
|
||||
case unix.RTA_METRICS:
|
||||
metrics, err := nl.ParseRouteAttr(attr.Value)
|
||||
@@ -713,8 +1086,36 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||
switch metric.Attr.Type {
|
||||
case unix.RTAX_MTU:
|
||||
route.MTU = int(native.Uint32(metric.Value[0:4]))
|
||||
case unix.RTAX_WINDOW:
|
||||
route.Window = int(native.Uint32(metric.Value[0:4]))
|
||||
case unix.RTAX_RTT:
|
||||
route.Rtt = int(native.Uint32(metric.Value[0:4]))
|
||||
case unix.RTAX_RTTVAR:
|
||||
route.RttVar = int(native.Uint32(metric.Value[0:4]))
|
||||
case unix.RTAX_SSTHRESH:
|
||||
route.Ssthresh = int(native.Uint32(metric.Value[0:4]))
|
||||
case unix.RTAX_CWND:
|
||||
route.Cwnd = int(native.Uint32(metric.Value[0:4]))
|
||||
case unix.RTAX_ADVMSS:
|
||||
route.AdvMSS = int(native.Uint32(metric.Value[0:4]))
|
||||
case unix.RTAX_REORDERING:
|
||||
route.Reordering = int(native.Uint32(metric.Value[0:4]))
|
||||
case unix.RTAX_HOPLIMIT:
|
||||
route.Hoplimit = int(native.Uint32(metric.Value[0:4]))
|
||||
case unix.RTAX_INITCWND:
|
||||
route.InitCwnd = int(native.Uint32(metric.Value[0:4]))
|
||||
case unix.RTAX_FEATURES:
|
||||
route.Features = int(native.Uint32(metric.Value[0:4]))
|
||||
case unix.RTAX_RTO_MIN:
|
||||
route.RtoMin = int(native.Uint32(metric.Value[0:4]))
|
||||
case unix.RTAX_INITRWND:
|
||||
route.InitRwnd = int(native.Uint32(metric.Value[0:4]))
|
||||
case unix.RTAX_QUICKACK:
|
||||
route.QuickACK = int(native.Uint32(metric.Value[0:4]))
|
||||
case unix.RTAX_CC_ALGO:
|
||||
route.Congctl = nl.BytesToString(metric.Value)
|
||||
case unix.RTAX_FASTOPEN_NO_COOKIE:
|
||||
route.FastOpenNoCookie = int(native.Uint32(metric.Value[0:4]))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -734,6 +1135,11 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||
if err := e.Decode(encap.Value); err != nil {
|
||||
return route, err
|
||||
}
|
||||
case nl.LWTUNNEL_ENCAP_SEG6_LOCAL:
|
||||
e = &SEG6LocalEncap{}
|
||||
if err := e.Decode(encap.Value); err != nil {
|
||||
return route, err
|
||||
}
|
||||
}
|
||||
route.Encap = e
|
||||
}
|
||||
@@ -741,15 +1147,28 @@ func deserializeRoute(m []byte) (Route, error) {
|
||||
return route, nil
|
||||
}
|
||||
|
||||
// RouteGetOptions contains a set of options to use with
|
||||
// RouteGetWithOptions
|
||||
type RouteGetOptions struct {
|
||||
VrfName string
|
||||
SrcAddr net.IP
|
||||
}
|
||||
|
||||
// RouteGetWithOptions gets a route to a specific destination from the host system.
|
||||
// Equivalent to: 'ip route get <> vrf <VrfName>'.
|
||||
func RouteGetWithOptions(destination net.IP, options *RouteGetOptions) ([]Route, error) {
|
||||
return pkgHandle.RouteGetWithOptions(destination, options)
|
||||
}
|
||||
|
||||
// RouteGet gets a route to a specific destination from the host system.
|
||||
// Equivalent to: 'ip route get'.
|
||||
func RouteGet(destination net.IP) ([]Route, error) {
|
||||
return pkgHandle.RouteGet(destination)
|
||||
}
|
||||
|
||||
// RouteGet gets a route to a specific destination from the host system.
|
||||
// Equivalent to: 'ip route get'.
|
||||
func (h *Handle) RouteGet(destination net.IP) ([]Route, error) {
|
||||
// RouteGetWithOptions gets a route to a specific destination from the host system.
|
||||
// Equivalent to: 'ip route get <> vrf <VrfName>'.
|
||||
func (h *Handle) RouteGetWithOptions(destination net.IP, options *RouteGetOptions) ([]Route, error) {
|
||||
req := h.newNetlinkRequest(unix.RTM_GETROUTE, unix.NLM_F_REQUEST)
|
||||
family := nl.GetIPFamily(destination)
|
||||
var destinationData []byte
|
||||
@@ -764,11 +1183,42 @@ func (h *Handle) RouteGet(destination net.IP) ([]Route, error) {
|
||||
msg := &nl.RtMsg{}
|
||||
msg.Family = uint8(family)
|
||||
msg.Dst_len = bitlen
|
||||
if options != nil && options.SrcAddr != nil {
|
||||
msg.Src_len = bitlen
|
||||
}
|
||||
msg.Flags = unix.RTM_F_LOOKUP_TABLE
|
||||
req.AddData(msg)
|
||||
|
||||
rtaDst := nl.NewRtAttr(unix.RTA_DST, destinationData)
|
||||
req.AddData(rtaDst)
|
||||
|
||||
if options != nil {
|
||||
if options.VrfName != "" {
|
||||
link, err := LinkByName(options.VrfName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var (
|
||||
b = make([]byte, 4)
|
||||
native = nl.NativeEndian()
|
||||
)
|
||||
native.PutUint32(b, uint32(link.Attrs().Index))
|
||||
|
||||
req.AddData(nl.NewRtAttr(unix.RTA_OIF, b))
|
||||
}
|
||||
|
||||
if options.SrcAddr != nil {
|
||||
var srcAddr []byte
|
||||
if family == FAMILY_V4 {
|
||||
srcAddr = options.SrcAddr.To4()
|
||||
} else {
|
||||
srcAddr = options.SrcAddr.To16()
|
||||
}
|
||||
|
||||
req.AddData(nl.NewRtAttr(unix.RTA_SRC, srcAddr))
|
||||
}
|
||||
}
|
||||
|
||||
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWROUTE)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -783,7 +1233,12 @@ func (h *Handle) RouteGet(destination net.IP) ([]Route, error) {
|
||||
res = append(res, route)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// RouteGet gets a route to a specific destination from the host system.
|
||||
// Equivalent to: 'ip route get'.
|
||||
func (h *Handle) RouteGet(destination net.IP) ([]Route, error) {
|
||||
return h.RouteGetWithOptions(destination, nil)
|
||||
}
|
||||
|
||||
// RouteSubscribe takes a chan down which notifications will be sent
|
||||
@@ -840,13 +1295,19 @@ func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <
|
||||
go func() {
|
||||
defer close(ch)
|
||||
for {
|
||||
msgs, err := s.Receive()
|
||||
msgs, from, err := s.Receive()
|
||||
if err != nil {
|
||||
if cberr != nil {
|
||||
cberr(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if from.Pid != nl.PidKernel {
|
||||
if cberr != nil {
|
||||
cberr(fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel))
|
||||
}
|
||||
continue
|
||||
}
|
||||
for _, m := range msgs {
|
||||
if m.Header.Type == unix.NLMSG_DONE {
|
||||
continue
|
||||
@@ -876,3 +1337,54 @@ func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p RouteProtocol) String() string {
|
||||
switch int(p) {
|
||||
case unix.RTPROT_BABEL:
|
||||
return "babel"
|
||||
case unix.RTPROT_BGP:
|
||||
return "bgp"
|
||||
case unix.RTPROT_BIRD:
|
||||
return "bird"
|
||||
case unix.RTPROT_BOOT:
|
||||
return "boot"
|
||||
case unix.RTPROT_DHCP:
|
||||
return "dhcp"
|
||||
case unix.RTPROT_DNROUTED:
|
||||
return "dnrouted"
|
||||
case unix.RTPROT_EIGRP:
|
||||
return "eigrp"
|
||||
case unix.RTPROT_GATED:
|
||||
return "gated"
|
||||
case unix.RTPROT_ISIS:
|
||||
return "isis"
|
||||
//case unix.RTPROT_KEEPALIVED:
|
||||
// return "keepalived"
|
||||
case unix.RTPROT_KERNEL:
|
||||
return "kernel"
|
||||
case unix.RTPROT_MROUTED:
|
||||
return "mrouted"
|
||||
case unix.RTPROT_MRT:
|
||||
return "mrt"
|
||||
case unix.RTPROT_NTK:
|
||||
return "ntk"
|
||||
case unix.RTPROT_OSPF:
|
||||
return "ospf"
|
||||
case unix.RTPROT_RA:
|
||||
return "ra"
|
||||
case unix.RTPROT_REDIRECT:
|
||||
return "redirect"
|
||||
case unix.RTPROT_RIP:
|
||||
return "rip"
|
||||
case unix.RTPROT_STATIC:
|
||||
return "static"
|
||||
case unix.RTPROT_UNSPEC:
|
||||
return "unspec"
|
||||
case unix.RTPROT_XORP:
|
||||
return "xorp"
|
||||
case unix.RTPROT_ZEBRA:
|
||||
return "zebra"
|
||||
default:
|
||||
return strconv.Itoa(int(p))
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
import "strconv"
|
||||
|
||||
func (r *Route) ListFlags() []string {
|
||||
return []string{}
|
||||
}
|
||||
@@ -9,3 +11,11 @@ func (r *Route) ListFlags() []string {
|
||||
func (n *NexthopInfo) ListFlags() []string {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
func (s Scope) String() string {
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
func (p RouteProtocol) String() string {
|
||||
return strconv.Itoa(int(p))
|
||||
}
|
||||
|
||||
14
vendor/github.com/vishvananda/netlink/rule.go
generated
vendored
14
vendor/github.com/vishvananda/netlink/rule.go
generated
vendored
@@ -12,6 +12,7 @@ type Rule struct {
|
||||
Table int
|
||||
Mark int
|
||||
Mask int
|
||||
Tos uint
|
||||
TunID uint
|
||||
Goto int
|
||||
Src *net.IPNet
|
||||
@@ -22,6 +23,8 @@ type Rule struct {
|
||||
SuppressIfgroup int
|
||||
SuppressPrefixlen int
|
||||
Invert bool
|
||||
Dport *RulePortRange
|
||||
Sport *RulePortRange
|
||||
}
|
||||
|
||||
func (r Rule) String() string {
|
||||
@@ -40,3 +43,14 @@ func NewRule() *Rule {
|
||||
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
|
||||
}
|
||||
|
||||
68
vendor/github.com/vishvananda/netlink/rule_linux.go
generated
vendored
68
vendor/github.com/vishvananda/netlink/rule_linux.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
@@ -55,6 +56,9 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
|
||||
if rule.Table >= 0 && rule.Table < 256 {
|
||||
msg.Table = uint8(rule.Table)
|
||||
}
|
||||
if rule.Tos != 0 {
|
||||
msg.Tos = uint8(rule.Tos)
|
||||
}
|
||||
|
||||
var dstFamily uint8
|
||||
var rtAttrs []*nl.RtAttr
|
||||
@@ -138,18 +142,28 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
|
||||
}
|
||||
}
|
||||
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 != "" {
|
||||
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 {
|
||||
msg.Type = nl.FR_ACT_NOP
|
||||
msg.Type = nl.FR_ACT_GOTO
|
||||
b := make([]byte, 4)
|
||||
native.PutUint32(b, uint32(rule.Goto))
|
||||
req.AddData(nl.NewRtAttr(nl.FRA_GOTO, b))
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
|
||||
return err
|
||||
}
|
||||
@@ -163,6 +177,19 @@ func RuleList(family int) ([]Rule, error) {
|
||||
// RuleList lists rules in the system.
|
||||
// Equivalent to: ip rule list
|
||||
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)
|
||||
msg := nl.NewIfInfomsg(family)
|
||||
req.AddData(msg)
|
||||
@@ -184,6 +211,7 @@ func (h *Handle) RuleList(family int) ([]Rule, error) {
|
||||
rule := NewRule()
|
||||
|
||||
rule.Invert = msg.Flags&FibRuleInvert > 0
|
||||
rule.Tos = uint(msg.Tos)
|
||||
|
||||
for j := range attrs {
|
||||
switch attrs[j].Attr.Type {
|
||||
@@ -225,10 +253,44 @@ func (h *Handle) RuleList(family int) ([]Rule, error) {
|
||||
rule.Goto = int(native.Uint32(attrs[j].Value[0:4]))
|
||||
case nl.FRA_PRIORITY:
|
||||
rule.Priority = 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]))
|
||||
}
|
||||
}
|
||||
|
||||
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 && rule.Mask != filter.Mask:
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
res = append(res, *rule)
|
||||
}
|
||||
|
||||
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{})
|
||||
}
|
||||
|
||||
120
vendor/github.com/vishvananda/netlink/socket_linux.go
generated
vendored
120
vendor/github.com/vishvananda/netlink/socket_linux.go
generated
vendored
@@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"syscall"
|
||||
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
"golang.org/x/sys/unix"
|
||||
@@ -49,10 +50,15 @@ func (r *socketRequest) Serialize() []byte {
|
||||
native.PutUint32(b.Next(4), r.States)
|
||||
networkOrder.PutUint16(b.Next(2), r.ID.SourcePort)
|
||||
networkOrder.PutUint16(b.Next(2), r.ID.DestinationPort)
|
||||
copy(b.Next(4), r.ID.Source.To4())
|
||||
b.Next(12)
|
||||
copy(b.Next(4), r.ID.Destination.To4())
|
||||
b.Next(12)
|
||||
if r.Family == unix.AF_INET6 {
|
||||
copy(b.Next(16), r.ID.Source)
|
||||
copy(b.Next(16), r.ID.Destination)
|
||||
} else {
|
||||
copy(b.Next(4), r.ID.Source.To4())
|
||||
b.Next(12)
|
||||
copy(b.Next(4), r.ID.Destination.To4())
|
||||
b.Next(12)
|
||||
}
|
||||
native.PutUint32(b.Next(4), r.ID.Interface)
|
||||
native.PutUint32(b.Next(4), r.ID.Cookie[0])
|
||||
native.PutUint32(b.Next(4), r.ID.Cookie[1])
|
||||
@@ -89,10 +95,15 @@ func (s *Socket) deserialize(b []byte) error {
|
||||
s.Retrans = rb.Read()
|
||||
s.ID.SourcePort = networkOrder.Uint16(rb.Next(2))
|
||||
s.ID.DestinationPort = networkOrder.Uint16(rb.Next(2))
|
||||
s.ID.Source = net.IPv4(rb.Read(), rb.Read(), rb.Read(), rb.Read())
|
||||
rb.Next(12)
|
||||
s.ID.Destination = net.IPv4(rb.Read(), rb.Read(), rb.Read(), rb.Read())
|
||||
rb.Next(12)
|
||||
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())
|
||||
rb.Next(12)
|
||||
s.ID.Destination = net.IPv4(rb.Read(), rb.Read(), rb.Read(), rb.Read())
|
||||
rb.Next(12)
|
||||
}
|
||||
s.ID.Interface = native.Uint32(rb.Next(4))
|
||||
s.ID.Cookie[0] = native.Uint32(rb.Next(4))
|
||||
s.ID.Cookie[1] = native.Uint32(rb.Next(4))
|
||||
@@ -141,10 +152,13 @@ func SocketGet(local, remote net.Addr) (*Socket, error) {
|
||||
},
|
||||
})
|
||||
s.Send(req)
|
||||
msgs, err := s.Receive()
|
||||
msgs, from, err := s.Receive()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if from.Pid != nl.PidKernel {
|
||||
return nil, fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel)
|
||||
}
|
||||
if len(msgs) == 0 {
|
||||
return nil, errors.New("no message nor error from netlink")
|
||||
}
|
||||
@@ -157,3 +171,91 @@ func SocketGet(local, remote net.Addr) (*Socket, error) {
|
||||
}
|
||||
return sock, nil
|
||||
}
|
||||
|
||||
// SocketDiagTCPInfo requests INET_DIAG_INFO for TCP protocol for specified family type.
|
||||
func SocketDiagTCPInfo(family uint8) ([]*InetDiagTCPInfoResp, error) {
|
||||
s, err := nl.Subscribe(unix.NETLINK_INET_DIAG)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer s.Close()
|
||||
|
||||
req := nl.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 TCP states
|
||||
})
|
||||
s.Send(req)
|
||||
|
||||
var result []*InetDiagTCPInfoResp
|
||||
loop:
|
||||
for {
|
||||
msgs, from, err := s.Receive()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if from.Pid != nl.PidKernel {
|
||||
return nil, fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel)
|
||||
}
|
||||
if len(msgs) == 0 {
|
||||
return nil, errors.New("no message nor error from netlink")
|
||||
}
|
||||
|
||||
for _, m := range msgs {
|
||||
switch m.Header.Type {
|
||||
case unix.NLMSG_DONE:
|
||||
break loop
|
||||
case unix.NLMSG_ERROR:
|
||||
native := nl.NativeEndian()
|
||||
error := int32(native.Uint32(m.Data[0:4]))
|
||||
return nil, syscall.Errno(-error)
|
||||
}
|
||||
sockInfo := &Socket{}
|
||||
if err := sockInfo.deserialize(m.Data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
attrs, err := nl.ParseRouteAttr(m.Data[sizeofSocket:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res, err := attrsToInetDiagTCPInfoResp(attrs, sockInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result = append(result, res)
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func attrsToInetDiagTCPInfoResp(attrs []syscall.NetlinkRouteAttr, sockInfo *Socket) (*InetDiagTCPInfoResp, error) {
|
||||
var tcpInfo *TCPInfo
|
||||
var tcpBBRInfo *TCPBBRInfo
|
||||
for _, a := range attrs {
|
||||
if a.Attr.Type == INET_DIAG_INFO {
|
||||
tcpInfo = &TCPInfo{}
|
||||
if err := tcpInfo.deserialize(a.Value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if a.Attr.Type == INET_DIAG_BBRINFO {
|
||||
tcpBBRInfo = &TCPBBRInfo{}
|
||||
if err := tcpBBRInfo.deserialize(a.Value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return &InetDiagTCPInfoResp{
|
||||
InetDiagMsg: sockInfo,
|
||||
TCPInfo: tcpInfo,
|
||||
TCPBBRInfo: tcpBBRInfo,
|
||||
}, nil
|
||||
}
|
||||
|
||||
84
vendor/github.com/vishvananda/netlink/tcp.go
generated
vendored
Normal file
84
vendor/github.com/vishvananda/netlink/tcp.go
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
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
|
||||
}
|
||||
353
vendor/github.com/vishvananda/netlink/tcp_linux.go
generated
vendored
Normal file
353
vendor/github.com/vishvananda/netlink/tcp_linux.go
generated
vendored
Normal file
@@ -0,0 +1,353 @@
|
||||
package netlink
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
const (
|
||||
tcpBBRInfoLen = 20
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
6
vendor/github.com/vishvananda/netlink/xfrm_monitor_linux.go
generated
vendored
6
vendor/github.com/vishvananda/netlink/xfrm_monitor_linux.go
generated
vendored
@@ -54,11 +54,15 @@ func XfrmMonitor(ch chan<- XfrmMsg, done <-chan struct{}, errorChan chan<- error
|
||||
go func() {
|
||||
defer close(ch)
|
||||
for {
|
||||
msgs, err := s.Receive()
|
||||
msgs, from, err := s.Receive()
|
||||
if err != nil {
|
||||
errorChan <- err
|
||||
return
|
||||
}
|
||||
if from.Pid != nl.PidKernel {
|
||||
errorChan <- fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel)
|
||||
return
|
||||
}
|
||||
for _, m := range msgs {
|
||||
switch m.Header.Type {
|
||||
case nl.XFRM_MSG_EXPIRE:
|
||||
|
||||
39
vendor/github.com/vishvananda/netlink/xfrm_policy.go
generated
vendored
39
vendor/github.com/vishvananda/netlink/xfrm_policy.go
generated
vendored
@@ -35,16 +35,36 @@ func (d Dir) String() string {
|
||||
return fmt.Sprintf("socket %d", d-XFRM_SOCKET_IN)
|
||||
}
|
||||
|
||||
// PolicyAction is an enum representing an ipsec policy action.
|
||||
type PolicyAction uint8
|
||||
|
||||
const (
|
||||
XFRM_POLICY_ALLOW PolicyAction = 0
|
||||
XFRM_POLICY_BLOCK PolicyAction = 1
|
||||
)
|
||||
|
||||
func (a PolicyAction) String() string {
|
||||
switch a {
|
||||
case XFRM_POLICY_ALLOW:
|
||||
return "allow"
|
||||
case XFRM_POLICY_BLOCK:
|
||||
return "block"
|
||||
default:
|
||||
return fmt.Sprintf("action %d", a)
|
||||
}
|
||||
}
|
||||
|
||||
// XfrmPolicyTmpl encapsulates a rule for the base addresses of an ipsec
|
||||
// policy. These rules are matched with XfrmState to determine encryption
|
||||
// and authentication algorithms.
|
||||
type XfrmPolicyTmpl struct {
|
||||
Dst net.IP
|
||||
Src net.IP
|
||||
Proto Proto
|
||||
Mode Mode
|
||||
Spi int
|
||||
Reqid int
|
||||
Dst net.IP
|
||||
Src net.IP
|
||||
Proto Proto
|
||||
Mode Mode
|
||||
Spi int
|
||||
Reqid int
|
||||
Optional int
|
||||
}
|
||||
|
||||
func (t XfrmPolicyTmpl) String() string {
|
||||
@@ -64,11 +84,14 @@ type XfrmPolicy struct {
|
||||
Dir Dir
|
||||
Priority int
|
||||
Index int
|
||||
Action PolicyAction
|
||||
Ifindex int
|
||||
Ifid int
|
||||
Mark *XfrmMark
|
||||
Tmpls []XfrmPolicyTmpl
|
||||
}
|
||||
|
||||
func (p XfrmPolicy) String() string {
|
||||
return fmt.Sprintf("{Dst: %v, Src: %v, Proto: %s, DstPort: %d, SrcPort: %d, Dir: %s, Priority: %d, Index: %d, Mark: %s, Tmpls: %s}",
|
||||
p.Dst, p.Src, p.Proto, p.DstPort, p.SrcPort, p.Dir, p.Priority, p.Index, p.Mark, p.Tmpls)
|
||||
return fmt.Sprintf("{Dst: %v, Src: %v, Proto: %s, DstPort: %d, SrcPort: %d, Dir: %s, Priority: %d, Index: %d, Action: %s, Ifindex: %d, Ifid: %d, Mark: %s, Tmpls: %s}",
|
||||
p.Dst, p.Src, p.Proto, p.DstPort, p.SrcPort, p.Dir, p.Priority, p.Index, p.Action, p.Ifindex, p.Ifid, p.Mark, p.Tmpls)
|
||||
}
|
||||
|
||||
21
vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go
generated
vendored
21
vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go
generated
vendored
@@ -27,6 +27,7 @@ func selFromPolicy(sel *nl.XfrmSelector, policy *XfrmPolicy) {
|
||||
if sel.Sport != 0 {
|
||||
sel.SportMask = ^uint16(0)
|
||||
}
|
||||
sel.Ifindex = int32(policy.Ifindex)
|
||||
}
|
||||
|
||||
// XfrmPolicyAdd will add an xfrm policy to the system.
|
||||
@@ -61,6 +62,7 @@ func (h *Handle) xfrmPolicyAddOrUpdate(policy *XfrmPolicy, nlProto int) error {
|
||||
msg.Priority = uint32(policy.Priority)
|
||||
msg.Index = uint32(policy.Index)
|
||||
msg.Dir = uint8(policy.Dir)
|
||||
msg.Action = uint8(policy.Action)
|
||||
msg.Lft.SoftByteLimit = nl.XFRM_INF
|
||||
msg.Lft.HardByteLimit = nl.XFRM_INF
|
||||
msg.Lft.SoftPacketLimit = nl.XFRM_INF
|
||||
@@ -77,6 +79,7 @@ func (h *Handle) xfrmPolicyAddOrUpdate(policy *XfrmPolicy, nlProto int) error {
|
||||
userTmpl.XfrmId.Spi = nl.Swap32(uint32(tmpl.Spi))
|
||||
userTmpl.Mode = uint8(tmpl.Mode)
|
||||
userTmpl.Reqid = uint32(tmpl.Reqid)
|
||||
userTmpl.Optional = uint8(tmpl.Optional)
|
||||
userTmpl.Aalgos = ^uint32(0)
|
||||
userTmpl.Ealgos = ^uint32(0)
|
||||
userTmpl.Calgos = ^uint32(0)
|
||||
@@ -90,6 +93,9 @@ func (h *Handle) xfrmPolicyAddOrUpdate(policy *XfrmPolicy, nlProto int) error {
|
||||
req.AddData(out)
|
||||
}
|
||||
|
||||
ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(policy.Ifid)))
|
||||
req.AddData(ifId)
|
||||
|
||||
_, err := req.Execute(unix.NETLINK_XFRM, 0)
|
||||
return err
|
||||
}
|
||||
@@ -183,6 +189,9 @@ func (h *Handle) xfrmPolicyGetOrDelete(policy *XfrmPolicy, nlProto int) (*XfrmPo
|
||||
req.AddData(out)
|
||||
}
|
||||
|
||||
ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(policy.Ifid)))
|
||||
req.AddData(ifId)
|
||||
|
||||
resType := nl.XFRM_MSG_NEWPOLICY
|
||||
if nlProto == nl.XFRM_MSG_DELPOLICY {
|
||||
resType = 0
|
||||
@@ -197,12 +206,7 @@ func (h *Handle) xfrmPolicyGetOrDelete(policy *XfrmPolicy, nlProto int) (*XfrmPo
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p, err := parseXfrmPolicy(msgs[0], FAMILY_ALL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return p, nil
|
||||
return parseXfrmPolicy(msgs[0], FAMILY_ALL)
|
||||
}
|
||||
|
||||
func parseXfrmPolicy(m []byte, family int) (*XfrmPolicy, error) {
|
||||
@@ -220,9 +224,11 @@ func parseXfrmPolicy(m []byte, family int) (*XfrmPolicy, error) {
|
||||
policy.Proto = Proto(msg.Sel.Proto)
|
||||
policy.DstPort = int(nl.Swap16(msg.Sel.Dport))
|
||||
policy.SrcPort = int(nl.Swap16(msg.Sel.Sport))
|
||||
policy.Ifindex = int(msg.Sel.Ifindex)
|
||||
policy.Priority = int(msg.Priority)
|
||||
policy.Index = int(msg.Index)
|
||||
policy.Dir = Dir(msg.Dir)
|
||||
policy.Action = PolicyAction(msg.Action)
|
||||
|
||||
attrs, err := nl.ParseRouteAttr(m[msg.Len():])
|
||||
if err != nil {
|
||||
@@ -242,6 +248,7 @@ func parseXfrmPolicy(m []byte, family int) (*XfrmPolicy, error) {
|
||||
resTmpl.Mode = Mode(tmpl.Mode)
|
||||
resTmpl.Spi = int(nl.Swap32(tmpl.XfrmId.Spi))
|
||||
resTmpl.Reqid = int(tmpl.Reqid)
|
||||
resTmpl.Optional = int(tmpl.Optional)
|
||||
policy.Tmpls = append(policy.Tmpls, resTmpl)
|
||||
}
|
||||
case nl.XFRMA_MARK:
|
||||
@@ -249,6 +256,8 @@ func parseXfrmPolicy(m []byte, family int) (*XfrmPolicy, error) {
|
||||
policy.Mark = new(XfrmMark)
|
||||
policy.Mark.Value = mark.Value
|
||||
policy.Mark.Mask = mark.Mask
|
||||
case nl.XFRMA_IF_ID:
|
||||
policy.Ifid = int(native.Uint32(attr.Value))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
6
vendor/github.com/vishvananda/netlink/xfrm_state.go
generated
vendored
6
vendor/github.com/vishvananda/netlink/xfrm_state.go
generated
vendored
@@ -94,6 +94,8 @@ type XfrmState struct {
|
||||
Limits XfrmStateLimits
|
||||
Statistics XfrmStateStats
|
||||
Mark *XfrmMark
|
||||
OutputMark *XfrmMark
|
||||
Ifid int
|
||||
Auth *XfrmStateAlgo
|
||||
Crypt *XfrmStateAlgo
|
||||
Aead *XfrmStateAlgo
|
||||
@@ -102,8 +104,8 @@ type XfrmState struct {
|
||||
}
|
||||
|
||||
func (sa XfrmState) String() string {
|
||||
return fmt.Sprintf("Dst: %v, Src: %v, Proto: %s, Mode: %s, SPI: 0x%x, ReqID: 0x%x, ReplayWindow: %d, Mark: %v, Auth: %v, Crypt: %v, Aead: %v, Encap: %v, ESN: %t",
|
||||
sa.Dst, sa.Src, sa.Proto, sa.Mode, sa.Spi, sa.Reqid, sa.ReplayWindow, sa.Mark, sa.Auth, sa.Crypt, sa.Aead, sa.Encap, sa.ESN)
|
||||
return fmt.Sprintf("Dst: %v, Src: %v, Proto: %s, Mode: %s, SPI: 0x%x, ReqID: 0x%x, ReplayWindow: %d, Mark: %v, OutputMark: %v, 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 {
|
||||
|
||||
42
vendor/github.com/vishvananda/netlink/xfrm_state_linux.go
generated
vendored
42
vendor/github.com/vishvananda/netlink/xfrm_state_linux.go
generated
vendored
@@ -158,6 +158,17 @@ func (h *Handle) xfrmStateAddOrUpdate(state *XfrmState, nlProto int) error {
|
||||
out := nl.NewRtAttr(nl.XFRMA_REPLAY_ESN_VAL, writeReplayEsn(state.ReplayWindow))
|
||||
req.AddData(out)
|
||||
}
|
||||
if state.OutputMark != nil {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(state.Ifid)))
|
||||
req.AddData(ifId)
|
||||
|
||||
_, err := req.Execute(unix.NETLINK_XFRM, 0)
|
||||
return err
|
||||
@@ -184,12 +195,7 @@ func (h *Handle) xfrmStateAllocSpi(state *XfrmState) (*XfrmState, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s, err := parseXfrmState(msgs[0], FAMILY_ALL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s, err
|
||||
return parseXfrmState(msgs[0], FAMILY_ALL)
|
||||
}
|
||||
|
||||
// XfrmStateDel will delete an xfrm state from the system. Note that
|
||||
@@ -275,6 +281,9 @@ func (h *Handle) xfrmStateGetOrDelete(state *XfrmState, nlProto int) (*XfrmState
|
||||
req.AddData(out)
|
||||
}
|
||||
|
||||
ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(state.Ifid)))
|
||||
req.AddData(ifId)
|
||||
|
||||
resType := nl.XFRM_MSG_NEWSA
|
||||
if nlProto == nl.XFRM_MSG_DELSA {
|
||||
resType = 0
|
||||
@@ -372,6 +381,21 @@ func parseXfrmState(m []byte, family int) (*XfrmState, error) {
|
||||
state.Mark = new(XfrmMark)
|
||||
state.Mark.Value = mark.Value
|
||||
state.Mark.Mask = mark.Mask
|
||||
case nl.XFRMA_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:
|
||||
state.Ifid = int(native.Uint32(attr.Value))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,11 +418,7 @@ func (h *Handle) XfrmStateFlush(proto Proto) error {
|
||||
req.AddData(&nl.XfrmUsersaFlush{Proto: uint8(proto)})
|
||||
|
||||
_, err := req.Execute(unix.NETLINK_XFRM, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func limitsToLft(lmts XfrmStateLimits, lft *nl.XfrmLifetimeCfg) {
|
||||
|
||||
12
vendor/github.com/vishvananda/netns/README.md
generated
vendored
12
vendor/github.com/vishvananda/netns/README.md
generated
vendored
@@ -37,7 +37,6 @@ func main() {
|
||||
|
||||
// Create a new network namespace
|
||||
newns, _ := netns.New()
|
||||
netns.Set(newns)
|
||||
defer newns.Close()
|
||||
|
||||
// Do something with the network namespace
|
||||
@@ -49,3 +48,14 @@ func main() {
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## NOTE
|
||||
|
||||
The library can be safely used only with Go >= 1.10 due to [golang/go#20676](https://github.com/golang/go/issues/20676).
|
||||
|
||||
After locking a goroutine to its current OS thread with `runtime.LockOSThread()`
|
||||
and changing its network namespace, any new subsequent goroutine won't be
|
||||
scheduled on that thread while it's locked. Therefore, the new goroutine
|
||||
will run in a different namespace leading to unexpected results.
|
||||
|
||||
See [here](https://www.weave.works/blog/linux-namespaces-golang-followup) for more details.
|
||||
|
||||
19
vendor/github.com/vishvananda/netns/netns.go
generated
vendored
19
vendor/github.com/vishvananda/netns/netns.go
generated
vendored
@@ -10,7 +10,8 @@ package netns
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// NsHandle is a handle to a network namespace. It can be cast directly
|
||||
@@ -24,11 +25,11 @@ func (ns NsHandle) Equal(other NsHandle) bool {
|
||||
if ns == other {
|
||||
return true
|
||||
}
|
||||
var s1, s2 syscall.Stat_t
|
||||
if err := syscall.Fstat(int(ns), &s1); err != nil {
|
||||
var s1, s2 unix.Stat_t
|
||||
if err := unix.Fstat(int(ns), &s1); err != nil {
|
||||
return false
|
||||
}
|
||||
if err := syscall.Fstat(int(other), &s2); err != nil {
|
||||
if err := unix.Fstat(int(other), &s2); err != nil {
|
||||
return false
|
||||
}
|
||||
return (s1.Dev == s2.Dev) && (s1.Ino == s2.Ino)
|
||||
@@ -36,11 +37,11 @@ func (ns NsHandle) Equal(other NsHandle) bool {
|
||||
|
||||
// String shows the file descriptor number and its dev and inode.
|
||||
func (ns NsHandle) String() string {
|
||||
var s syscall.Stat_t
|
||||
if ns == -1 {
|
||||
return "NS(None)"
|
||||
}
|
||||
if err := syscall.Fstat(int(ns), &s); err != nil {
|
||||
var s unix.Stat_t
|
||||
if err := unix.Fstat(int(ns), &s); err != nil {
|
||||
return fmt.Sprintf("NS(%d: unknown)", ns)
|
||||
}
|
||||
return fmt.Sprintf("NS(%d: %d, %d)", ns, s.Dev, s.Ino)
|
||||
@@ -49,11 +50,11 @@ func (ns NsHandle) String() string {
|
||||
// UniqueId returns a string which uniquely identifies the namespace
|
||||
// associated with the network handle.
|
||||
func (ns NsHandle) UniqueId() string {
|
||||
var s syscall.Stat_t
|
||||
if ns == -1 {
|
||||
return "NS(none)"
|
||||
}
|
||||
if err := syscall.Fstat(int(ns), &s); err != nil {
|
||||
var s unix.Stat_t
|
||||
if err := unix.Fstat(int(ns), &s); err != nil {
|
||||
return "NS(unknown)"
|
||||
}
|
||||
return fmt.Sprintf("NS(%d:%d)", s.Dev, s.Ino)
|
||||
@@ -67,7 +68,7 @@ func (ns NsHandle) IsOpen() bool {
|
||||
// Close closes the NsHandle and resets its file descriptor to -1.
|
||||
// It is not safe to use an NsHandle after Close() is called.
|
||||
func (ns *NsHandle) Close() error {
|
||||
if err := syscall.Close(int(*ns)); err != nil {
|
||||
if err := unix.Close(int(*ns)); err != nil {
|
||||
return err
|
||||
}
|
||||
(*ns) = -1
|
||||
|
||||
106
vendor/github.com/vishvananda/netns/netns_linux.go
generated
vendored
106
vendor/github.com/vishvananda/netns/netns_linux.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// +build linux
|
||||
// +build linux,go1.10
|
||||
|
||||
package netns
|
||||
|
||||
@@ -6,44 +6,30 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// SYS_SETNS syscall allows changing the namespace of the current process.
|
||||
var SYS_SETNS = map[string]uintptr{
|
||||
"386": 346,
|
||||
"amd64": 308,
|
||||
"arm64": 268,
|
||||
"arm": 375,
|
||||
"mips": 4344,
|
||||
"mipsle": 4344,
|
||||
"ppc64": 350,
|
||||
"ppc64le": 350,
|
||||
"s390x": 339,
|
||||
}[runtime.GOARCH]
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// Deprecated: use syscall pkg instead (go >= 1.5 needed).
|
||||
const (
|
||||
CLONE_NEWUTS = 0x04000000 /* New utsname group? */
|
||||
CLONE_NEWIPC = 0x08000000 /* New ipcs */
|
||||
CLONE_NEWUSER = 0x10000000 /* New user namespace */
|
||||
CLONE_NEWPID = 0x20000000 /* New pid namespace */
|
||||
CLONE_NEWNET = 0x40000000 /* New network namespace */
|
||||
CLONE_IO = 0x80000000 /* Get io context */
|
||||
CLONE_NEWUTS = 0x04000000 /* New utsname group? */
|
||||
CLONE_NEWIPC = 0x08000000 /* New ipcs */
|
||||
CLONE_NEWUSER = 0x10000000 /* New user namespace */
|
||||
CLONE_NEWPID = 0x20000000 /* New pid namespace */
|
||||
CLONE_NEWNET = 0x40000000 /* New network namespace */
|
||||
CLONE_IO = 0x80000000 /* Get io context */
|
||||
bindMountPath = "/run/netns" /* Bind mount path for named netns */
|
||||
)
|
||||
|
||||
// Setns sets namespace using syscall. Note that this should be a method
|
||||
// in syscall but it has not been added.
|
||||
func Setns(ns NsHandle, nstype int) (err error) {
|
||||
_, _, e1 := syscall.Syscall(SYS_SETNS, uintptr(ns), uintptr(nstype), 0)
|
||||
if e1 != 0 {
|
||||
err = e1
|
||||
}
|
||||
return
|
||||
return unix.Setns(int(ns), nstype)
|
||||
}
|
||||
|
||||
// Set sets the current network namespace to the namespace represented
|
||||
@@ -52,23 +38,67 @@ func Set(ns NsHandle) (err error) {
|
||||
return Setns(ns, CLONE_NEWNET)
|
||||
}
|
||||
|
||||
// New creates a new network namespace and returns a handle to it.
|
||||
// New creates a new network namespace, sets it as current and returns
|
||||
// a handle to it.
|
||||
func New() (ns NsHandle, err error) {
|
||||
if err := syscall.Unshare(CLONE_NEWNET); err != nil {
|
||||
if err := unix.Unshare(CLONE_NEWNET); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
return Get()
|
||||
}
|
||||
|
||||
// NewNamed creates a new named network namespace and returns a handle to it
|
||||
func NewNamed(name string) (NsHandle, error) {
|
||||
if _, err := os.Stat(bindMountPath); os.IsNotExist(err) {
|
||||
err = os.MkdirAll(bindMountPath, 0755)
|
||||
if err != nil {
|
||||
return None(), err
|
||||
}
|
||||
}
|
||||
|
||||
newNs, err := New()
|
||||
if err != nil {
|
||||
return None(), err
|
||||
}
|
||||
|
||||
namedPath := path.Join(bindMountPath, name)
|
||||
|
||||
f, err := os.OpenFile(namedPath, os.O_CREATE|os.O_EXCL, 0444)
|
||||
if err != nil {
|
||||
return None(), err
|
||||
}
|
||||
f.Close()
|
||||
|
||||
nsPath := fmt.Sprintf("/proc/%d/task/%d/ns/net", os.Getpid(), syscall.Gettid())
|
||||
err = syscall.Mount(nsPath, namedPath, "bind", syscall.MS_BIND, "")
|
||||
if err != nil {
|
||||
return None(), err
|
||||
}
|
||||
|
||||
return newNs, nil
|
||||
}
|
||||
|
||||
// DeleteNamed deletes a named network namespace
|
||||
func DeleteNamed(name string) error {
|
||||
namedPath := path.Join(bindMountPath, name)
|
||||
|
||||
err := syscall.Unmount(namedPath, syscall.MNT_DETACH)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return os.Remove(namedPath)
|
||||
}
|
||||
|
||||
// Get gets a handle to the current threads network namespace.
|
||||
func Get() (NsHandle, error) {
|
||||
return GetFromThread(os.Getpid(), syscall.Gettid())
|
||||
return GetFromThread(os.Getpid(), unix.Gettid())
|
||||
}
|
||||
|
||||
// GetFromPath gets a handle to a network namespace
|
||||
// identified by the path
|
||||
func GetFromPath(path string) (NsHandle, error) {
|
||||
fd, err := syscall.Open(path, syscall.O_RDONLY, 0)
|
||||
fd, err := unix.Open(path, unix.O_RDONLY|unix.O_CLOEXEC, 0)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
@@ -188,12 +218,18 @@ func getPidForContainer(id string) (int, error) {
|
||||
filepath.Join(cgroupRoot, "system.slice", "docker-"+id+".scope", "tasks"),
|
||||
// Even more recent docker versions under cgroup/systemd/docker/<id>/
|
||||
filepath.Join(cgroupRoot, "..", "systemd", "docker", id, "tasks"),
|
||||
// Kubernetes with docker and CNI is even more different
|
||||
// Kubernetes with docker and CNI is even more different. Works for BestEffort and Burstable QoS
|
||||
filepath.Join(cgroupRoot, "..", "systemd", "kubepods", "*", "pod*", id, "tasks"),
|
||||
// Another flavor of containers location in recent kubernetes 1.11+
|
||||
filepath.Join(cgroupRoot, cgroupThis, "kubepods.slice", "kubepods-besteffort.slice", "*", "docker-"+id+".scope", "tasks"),
|
||||
// When runs inside of a container with recent kubernetes 1.11+
|
||||
filepath.Join(cgroupRoot, "kubepods.slice", "kubepods-besteffort.slice", "*", "docker-"+id+".scope", "tasks"),
|
||||
// Same as above but for Guaranteed QoS
|
||||
filepath.Join(cgroupRoot, "..", "systemd", "kubepods", "pod*", id, "tasks"),
|
||||
// Another flavor of containers location in recent kubernetes 1.11+. Works for BestEffort and Burstable QoS
|
||||
filepath.Join(cgroupRoot, cgroupThis, "kubepods.slice", "*.slice", "*", "docker-"+id+".scope", "tasks"),
|
||||
// Same as above but for Guaranteed QoS
|
||||
filepath.Join(cgroupRoot, cgroupThis, "kubepods.slice", "*", "docker-"+id+".scope", "tasks"),
|
||||
// When runs inside of a container with recent kubernetes 1.11+. Works for BestEffort and Burstable QoS
|
||||
filepath.Join(cgroupRoot, "kubepods.slice", "*.slice", "*", "docker-"+id+".scope", "tasks"),
|
||||
// Same as above but for Guaranteed QoS
|
||||
filepath.Join(cgroupRoot, "kubepods.slice", "*", "docker-"+id+".scope", "tasks"),
|
||||
}
|
||||
|
||||
var filename string
|
||||
|
||||
Reference in New Issue
Block a user