aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/vishvananda/netlink
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/vishvananda/netlink')
-rw-r--r--vendor/github.com/vishvananda/netlink/.travis.yml20
-rw-r--r--vendor/github.com/vishvananda/netlink/README.md2
-rw-r--r--vendor/github.com/vishvananda/netlink/addr_linux.go6
-rw-r--r--vendor/github.com/vishvananda/netlink/bpf_linux.go24
-rw-r--r--vendor/github.com/vishvananda/netlink/class_linux.go8
-rw-r--r--vendor/github.com/vishvananda/netlink/conntrack_linux.go143
-rw-r--r--vendor/github.com/vishvananda/netlink/devlink_linux.go353
-rw-r--r--vendor/github.com/vishvananda/netlink/filter.go62
-rw-r--r--vendor/github.com/vishvananda/netlink/filter_linux.go306
-rw-r--r--vendor/github.com/vishvananda/netlink/handle_linux.go14
-rw-r--r--vendor/github.com/vishvananda/netlink/handle_unspecified.go2
-rw-r--r--vendor/github.com/vishvananda/netlink/ipset_linux.go167
-rw-r--r--vendor/github.com/vishvananda/netlink/link.go73
-rw-r--r--vendor/github.com/vishvananda/netlink/link_linux.go182
-rw-r--r--vendor/github.com/vishvananda/netlink/neigh.go1
-rw-r--r--vendor/github.com/vishvananda/netlink/neigh_linux.go34
-rw-r--r--vendor/github.com/vishvananda/netlink/netlink_unspecified.go16
-rw-r--r--vendor/github.com/vishvananda/netlink/netns_linux.go6
-rw-r--r--vendor/github.com/vishvananda/netlink/nl/conntrack_linux.go1
-rw-r--r--vendor/github.com/vishvananda/netlink/nl/devlink_linux.go55
-rw-r--r--vendor/github.com/vishvananda/netlink/nl/link_linux.go9
-rw-r--r--vendor/github.com/vishvananda/netlink/nl/lwt_linux.go29
-rw-r--r--vendor/github.com/vishvananda/netlink/nl/nl_linux.go53
-rw-r--r--vendor/github.com/vishvananda/netlink/nl/rdma_link_linux.go4
-rw-r--r--vendor/github.com/vishvananda/netlink/nl/seg6_linux.go4
-rw-r--r--vendor/github.com/vishvananda/netlink/nl/syscall.go2
-rw-r--r--vendor/github.com/vishvananda/netlink/nl/tc_linux.go105
-rw-r--r--vendor/github.com/vishvananda/netlink/proc_event.go217
-rw-r--r--vendor/github.com/vishvananda/netlink/qdisc_linux.go9
-rw-r--r--vendor/github.com/vishvananda/netlink/rdma_link_linux.go51
-rw-r--r--vendor/github.com/vishvananda/netlink/route.go4
-rw-r--r--vendor/github.com/vishvananda/netlink/route_linux.go237
-rw-r--r--vendor/github.com/vishvananda/netlink/rule.go13
-rw-r--r--vendor/github.com/vishvananda/netlink/rule_linux.go5
-rw-r--r--vendor/github.com/vishvananda/netlink/socket_linux.go76
-rw-r--r--vendor/github.com/vishvananda/netlink/xfrm_state_linux.go2
36 files changed, 2008 insertions, 287 deletions
diff --git a/vendor/github.com/vishvananda/netlink/.travis.yml b/vendor/github.com/vishvananda/netlink/.travis.yml
deleted file mode 100644
index 80219c69d..000000000
--- a/vendor/github.com/vishvananda/netlink/.travis.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-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
- # modprobe ip_gre or else the first gre device can't be deleted
- - sudo modprobe ip_gre
- # modprobe nf_conntrack for the conntrack testing
- - sudo modprobe nf_conntrack
- - sudo modprobe nf_conntrack_netlink
- - sudo modprobe nf_conntrack_ipv4
- - sudo modprobe nf_conntrack_ipv6
- - sudo modprobe sch_hfsc
- - sudo modprobe sch_sfq
-install:
- - go get -v -t ./...
-go_import_path: github.com/vishvananda/netlink
diff --git a/vendor/github.com/vishvananda/netlink/README.md b/vendor/github.com/vishvananda/netlink/README.md
index a88e2f418..0128bc67d 100644
--- a/vendor/github.com/vishvananda/netlink/README.md
+++ b/vendor/github.com/vishvananda/netlink/README.md
@@ -1,6 +1,6 @@
# netlink - netlink library for go #
-[![Build Status](https://travis-ci.org/vishvananda/netlink.png?branch=master)](https://travis-ci.org/vishvananda/netlink) [![GoDoc](https://godoc.org/github.com/vishvananda/netlink?status.svg)](https://godoc.org/github.com/vishvananda/netlink)
+![Build Status](https://github.com/vishvananda/netlink/actions/workflows/main.yml/badge.svg) [![GoDoc](https://godoc.org/github.com/vishvananda/netlink?status.svg)](https://godoc.org/github.com/vishvananda/netlink)
The netlink package provides a simple netlink library for go. Netlink
is the interface a user-space program in linux uses to communicate with
diff --git a/vendor/github.com/vishvananda/netlink/addr_linux.go b/vendor/github.com/vishvananda/netlink/addr_linux.go
index 71da251ca..e4a167dda 100644
--- a/vendor/github.com/vishvananda/netlink/addr_linux.go
+++ b/vendor/github.com/vishvananda/netlink/addr_linux.go
@@ -268,7 +268,7 @@ func parseAddr(m []byte) (addr Addr, family int, err error) {
// But obviously, as there are IPv6 PtP addresses, too,
// IFA_LOCAL should also be handled for IPv6.
if local != nil {
- if family == FAMILY_V4 && local.IP.Equal(dst.IP) {
+ if family == FAMILY_V4 && dst != nil && local.IP.Equal(dst.IP) {
addr.IPNet = dst
} else {
addr.IPNet = local
@@ -357,7 +357,8 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c
msgs, from, err := s.Receive()
if err != nil {
if cberr != nil {
- cberr(err)
+ cberr(fmt.Errorf("Receive failed: %v",
+ err))
}
return
}
@@ -372,7 +373,6 @@ func addrSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- AddrUpdate, done <-c
continue
}
if m.Header.Type == unix.NLMSG_ERROR {
- native := nl.NativeEndian()
error := int32(native.Uint32(m.Data[0:4]))
if error == 0 {
continue
diff --git a/vendor/github.com/vishvananda/netlink/bpf_linux.go b/vendor/github.com/vishvananda/netlink/bpf_linux.go
index 6631626bf..96befbfe0 100644
--- a/vendor/github.com/vishvananda/netlink/bpf_linux.go
+++ b/vendor/github.com/vishvananda/netlink/bpf_linux.go
@@ -16,6 +16,30 @@ const (
BPF_PROG_TYPE_SCHED_ACT
BPF_PROG_TYPE_TRACEPOINT
BPF_PROG_TYPE_XDP
+ BPF_PROG_TYPE_PERF_EVENT
+ BPF_PROG_TYPE_CGROUP_SKB
+ BPF_PROG_TYPE_CGROUP_SOCK
+ BPF_PROG_TYPE_LWT_IN
+ BPF_PROG_TYPE_LWT_OUT
+ BPF_PROG_TYPE_LWT_XMIT
+ BPF_PROG_TYPE_SOCK_OPS
+ BPF_PROG_TYPE_SK_SKB
+ BPF_PROG_TYPE_CGROUP_DEVICE
+ BPF_PROG_TYPE_SK_MSG
+ BPF_PROG_TYPE_RAW_TRACEPOINT
+ BPF_PROG_TYPE_CGROUP_SOCK_ADDR
+ BPF_PROG_TYPE_LWT_SEG6LOCAL
+ BPF_PROG_TYPE_LIRC_MODE2
+ BPF_PROG_TYPE_SK_REUSEPORT
+ BPF_PROG_TYPE_FLOW_DISSECTOR
+ BPF_PROG_TYPE_CGROUP_SYSCTL
+ BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE
+ BPF_PROG_TYPE_CGROUP_SOCKOPT
+ BPF_PROG_TYPE_TRACING
+ BPF_PROG_TYPE_STRUCT_OPS
+ BPF_PROG_TYPE_EXT
+ BPF_PROG_TYPE_LSM
+ BPF_PROG_TYPE_SK_LOOKUP
)
type BPFAttr struct {
diff --git a/vendor/github.com/vishvananda/netlink/class_linux.go b/vendor/github.com/vishvananda/netlink/class_linux.go
index 029568a3f..6f542ba4e 100644
--- a/vendor/github.com/vishvananda/netlink/class_linux.go
+++ b/vendor/github.com/vishvananda/netlink/class_linux.go
@@ -191,9 +191,9 @@ func classPayload(req *nl.NetlinkRequest, class Class) error {
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))
+ options.AddRtAttr(nl.TCA_HFSC_RSC, nl.SerializeHfscCurve(&opt.Rsc))
+ options.AddRtAttr(nl.TCA_HFSC_FSC, nl.SerializeHfscCurve(&opt.Fsc))
+ options.AddRtAttr(nl.TCA_HFSC_USC, nl.SerializeHfscCurve(&opt.Usc))
}
req.AddData(options)
return nil
@@ -341,7 +341,6 @@ func parseHfscClassData(class Class, data []syscall.NetlinkRouteAttr) (bool, err
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
@@ -363,7 +362,6 @@ func parseTcStats(data []byte) (*ClassStatistics, error) {
func parseGnetStats(data []byte, gnetStats interface{}) error {
buf := &bytes.Buffer{}
buf.Write(data)
- native := nl.NativeEndian()
return binary.Read(buf, native, gnetStats)
}
diff --git a/vendor/github.com/vishvananda/netlink/conntrack_linux.go b/vendor/github.com/vishvananda/netlink/conntrack_linux.go
index ab91f4e55..03ea1b98f 100644
--- a/vendor/github.com/vishvananda/netlink/conntrack_linux.go
+++ b/vendor/github.com/vishvananda/netlink/conntrack_linux.go
@@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"net"
+ "time"
"github.com/vishvananda/netlink/nl"
"golang.org/x/sys/unix"
@@ -145,16 +146,23 @@ type ConntrackFlow struct {
Forward ipTuple
Reverse ipTuple
Mark uint32
+ TimeStart uint64
+ TimeStop uint64
+ TimeOut uint32
}
func (s *ConntrackFlow) String() string {
// conntrack cmd output:
// udp 17 src=127.0.0.1 dst=127.0.0.1 sport=4001 dport=1234 packets=5 bytes=532 [UNREPLIED] src=127.0.0.1 dst=127.0.0.1 sport=1234 dport=4001 packets=10 bytes=1078 mark=0
- return fmt.Sprintf("%s\t%d src=%s dst=%s sport=%d dport=%d packets=%d bytes=%d\tsrc=%s dst=%s sport=%d dport=%d packets=%d bytes=%d mark=%d",
+ // start=2019-07-26 01:26:21.557800506 +0000 UTC stop=1970-01-01 00:00:00 +0000 UTC timeout=30(sec)
+ start := time.Unix(0, int64(s.TimeStart))
+ stop := time.Unix(0, int64(s.TimeStop))
+ timeout := int32(s.TimeOut)
+ 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=0x%x start=%v stop=%v timeout=%d(sec)",
nl.L4ProtoMap[s.Forward.Protocol], s.Forward.Protocol,
s.Forward.SrcIP.String(), s.Forward.DstIP.String(), s.Forward.SrcPort, s.Forward.DstPort, s.Forward.Packets, s.Forward.Bytes,
s.Reverse.SrcIP.String(), s.Reverse.DstIP.String(), s.Reverse.SrcPort, s.Reverse.DstPort, s.Reverse.Packets, s.Reverse.Bytes,
- s.Mark)
+ s.Mark, start, stop, timeout)
}
// This method parse the ip tuple structure
@@ -174,25 +182,43 @@ func parseIpTuple(reader *bytes.Reader, tpl *ipTuple) uint8 {
tpl.DstIP = v
}
}
- // Skip the next 4 bytes nl.NLA_F_NESTED|nl.CTA_TUPLE_PROTO
- reader.Seek(4, seekCurrent)
- _, t, _, v := parseNfAttrTLV(reader)
+ // Get total length of nested protocol-specific info.
+ _, _, protoInfoTotalLen := parseNfAttrTL(reader)
+ _, t, l, v := parseNfAttrTLV(reader)
+ // Track the number of bytes read.
+ protoInfoBytesRead := uint16(nl.SizeofNfattr) + l
if t == nl.CTA_PROTO_NUM {
tpl.Protocol = uint8(v[0])
}
- // Skip some padding 3 bytes
+ // We only parse TCP & UDP headers. Skip the others.
+ if tpl.Protocol != 6 && tpl.Protocol != 17 {
+ // skip the rest
+ bytesRemaining := protoInfoTotalLen - protoInfoBytesRead
+ reader.Seek(int64(bytesRemaining), seekCurrent)
+ return tpl.Protocol
+ }
+ // Skip 3 bytes of padding
reader.Seek(3, seekCurrent)
+ protoInfoBytesRead += 3
for i := 0; i < 2; i++ {
_, t, _ := parseNfAttrTL(reader)
+ protoInfoBytesRead += uint16(nl.SizeofNfattr)
switch t {
case nl.CTA_PROTO_SRC_PORT:
parseBERaw16(reader, &tpl.SrcPort)
+ protoInfoBytesRead += 2
case nl.CTA_PROTO_DST_PORT:
parseBERaw16(reader, &tpl.DstPort)
+ protoInfoBytesRead += 2
}
- // Skip some padding 2 byte
+ // Skip 2 bytes of padding
reader.Seek(2, seekCurrent)
+ protoInfoBytesRead += 2
}
+ // Skip any remaining/unknown parts of the message
+ bytesRemaining := protoInfoTotalLen - protoInfoBytesRead
+ reader.Seek(int64(bytesRemaining), seekCurrent)
+
return tpl.Protocol
}
@@ -211,10 +237,14 @@ func parseNfAttrTL(r *bytes.Reader) (isNested bool, attrType, len uint16) {
binary.Read(r, nl.NativeEndian(), &attrType)
isNested = (attrType & nl.NLA_F_NESTED) == nl.NLA_F_NESTED
attrType = attrType & (nl.NLA_F_NESTED - 1)
-
return isNested, attrType, len
}
+func skipNfAttrValue(r *bytes.Reader, len uint16) {
+ len = (len + nl.NLA_ALIGNTO - 1) & ^(nl.NLA_ALIGNTO - 1)
+ r.Seek(int64(len), seekCurrent)
+}
+
func parseBERaw16(r *bytes.Reader, v *uint16) {
binary.Read(r, binary.BigEndian, v)
}
@@ -241,6 +271,36 @@ func parseByteAndPacketCounters(r *bytes.Reader) (bytes, packets uint64) {
return
}
+// when the flow is alive, only the timestamp_start is returned in structure
+func parseTimeStamp(r *bytes.Reader, readSize uint16) (tstart, tstop uint64) {
+ var numTimeStamps int
+ oneItem := nl.SizeofNfattr + 8 // 4 bytes attr header + 8 bytes timestamp
+ if readSize == uint16(oneItem) {
+ numTimeStamps = 1
+ } else if readSize == 2*uint16(oneItem) {
+ numTimeStamps = 2
+ } else {
+ return
+ }
+ for i := 0; i < numTimeStamps; i++ {
+ switch _, t, _ := parseNfAttrTL(r); t {
+ case nl.CTA_TIMESTAMP_START:
+ parseBERaw64(r, &tstart)
+ case nl.CTA_TIMESTAMP_STOP:
+ parseBERaw64(r, &tstop)
+ default:
+ return
+ }
+ }
+ return
+
+}
+
+func parseTimeOut(r *bytes.Reader) (ttimeout uint32) {
+ parseBERaw32(r, &ttimeout)
+ return
+}
+
func parseConnectionMark(r *bytes.Reader) (mark uint32) {
parseBERaw32(r, &mark)
return
@@ -266,25 +326,37 @@ func parseRawData(data []byte) *ConntrackFlow {
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 {
+ if nested, t, l = 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 {
+ if nested, t, l = parseNfAttrTL(reader); nested && t == nl.CTA_TUPLE_IP {
parseIpTuple(reader, &s.Reverse)
} else {
// Header not recognized skip it
- reader.Seek(int64(l), seekCurrent)
+ skipNfAttrValue(reader, l)
}
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)
+ case nl.CTA_TIMESTAMP:
+ s.TimeStart, s.TimeStop = parseTimeStamp(reader, l)
+ case nl.CTA_PROTOINFO:
+ skipNfAttrValue(reader, l)
+ default:
+ skipNfAttrValue(reader, l)
}
} else {
switch t {
case nl.CTA_MARK:
s.Mark = parseConnectionMark(reader)
+ case nl.CTA_TIMEOUT:
+ s.TimeOut = parseTimeOut(reader)
+ case nl.CTA_STATUS, nl.CTA_USE, nl.CTA_ID:
+ skipNfAttrValue(reader, l)
+ default:
+ skipNfAttrValue(reader, l)
}
}
}
@@ -346,23 +418,34 @@ type CustomConntrackFilter interface {
}
type ConntrackFilter struct {
- ipFilter map[ConntrackFilterType]net.IP
+ ipNetFilter map[ConntrackFilterType]*net.IPNet
portFilter map[ConntrackFilterType]uint16
protoFilter uint8
}
-// AddIP adds an IP to the conntrack filter
-func (f *ConntrackFilter) AddIP(tp ConntrackFilterType, ip net.IP) error {
- if f.ipFilter == nil {
- f.ipFilter = make(map[ConntrackFilterType]net.IP)
+// AddIPNet adds a IP subnet to the conntrack filter
+func (f *ConntrackFilter) AddIPNet(tp ConntrackFilterType, ipNet *net.IPNet) error {
+ if ipNet == nil {
+ return fmt.Errorf("Filter attribute empty")
}
- if _, ok := f.ipFilter[tp]; ok {
+ if f.ipNetFilter == nil {
+ f.ipNetFilter = make(map[ConntrackFilterType]*net.IPNet)
+ }
+ if _, ok := f.ipNetFilter[tp]; ok {
return errors.New("Filter attribute already present")
}
- f.ipFilter[tp] = ip
+ f.ipNetFilter[tp] = ipNet
return nil
}
+// AddIP adds an IP to the conntrack filter
+func (f *ConntrackFilter) AddIP(tp ConntrackFilterType, ip net.IP) error {
+ if ip == nil {
+ return fmt.Errorf("Filter attribute empty")
+ }
+ return f.AddIPNet(tp, NewIPNet(ip))
+}
+
// AddPort adds a Port to the conntrack filter if the Layer 4 protocol allows it
func (f *ConntrackFilter) AddPort(tp ConntrackFilterType, port uint16) error {
switch f.protoFilter {
@@ -394,7 +477,7 @@ func (f *ConntrackFilter) AddProtocol(proto uint8) error {
// 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 && len(f.portFilter) == 0 && f.protoFilter == 0 {
+ if len(f.ipNetFilter) == 0 && len(f.portFilter) == 0 && f.protoFilter == 0 {
// empty filter always not match
return false
}
@@ -408,30 +491,30 @@ func (f *ConntrackFilter) MatchConntrackFlow(flow *ConntrackFlow) bool {
match := true
// IP conntrack filter
- if len(f.ipFilter) > 0 {
+ if len(f.ipNetFilter) > 0 {
// -orig-src ip Source address from original direction
- if elem, found := f.ipFilter[ConntrackOrigSrcIP]; found {
- match = match && elem.Equal(flow.Forward.SrcIP)
+ if elem, found := f.ipNetFilter[ConntrackOrigSrcIP]; found {
+ match = match && elem.Contains(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)
+ if elem, found := f.ipNetFilter[ConntrackOrigDstIP]; match && found {
+ match = match && elem.Contains(flow.Forward.DstIP)
}
// -src-nat ip Source NAT ip
- if elem, found := f.ipFilter[ConntrackReplySrcIP]; match && found {
- match = match && elem.Equal(flow.Reverse.SrcIP)
+ if elem, found := f.ipNetFilter[ConntrackReplySrcIP]; match && found {
+ match = match && elem.Contains(flow.Reverse.SrcIP)
}
// -dst-nat ip Destination NAT ip
- if elem, found := f.ipFilter[ConntrackReplyDstIP]; match && found {
- match = match && elem.Equal(flow.Reverse.DstIP)
+ if elem, found := f.ipNetFilter[ConntrackReplyDstIP]; match && found {
+ match = match && elem.Contains(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))
+ if elem, found := f.ipNetFilter[ConntrackReplyAnyIP]; match && found {
+ match = match && (elem.Contains(flow.Reverse.SrcIP) || elem.Contains(flow.Reverse.DstIP))
}
}
diff --git a/vendor/github.com/vishvananda/netlink/devlink_linux.go b/vendor/github.com/vishvananda/netlink/devlink_linux.go
index 7d57080e8..358b232c6 100644
--- a/vendor/github.com/vishvananda/netlink/devlink_linux.go
+++ b/vendor/github.com/vishvananda/netlink/devlink_linux.go
@@ -1,9 +1,11 @@
package netlink
import (
+ "fmt"
+ "net"
+ "strings"
"syscall"
- "fmt"
"github.com/vishvananda/netlink/nl"
"golang.org/x/sys/unix"
)
@@ -27,6 +29,20 @@ type DevlinkDevice struct {
Attrs DevlinkDevAttrs
}
+// DevlinkPortFn represents port function and its attributes
+type DevlinkPortFn struct {
+ HwAddr net.HardwareAddr
+ State uint8
+ OpState uint8
+}
+
+// DevlinkPortFnSetAttrs represents attributes to set
+type DevlinkPortFnSetAttrs struct {
+ FnAttrs DevlinkPortFn
+ HwAddrValid bool
+ StateValid bool
+}
+
// DevlinkPort represents port and its attributes
type DevlinkPort struct {
BusName string
@@ -37,6 +53,35 @@ type DevlinkPort struct {
NetdevIfIndex uint32
RdmaDeviceName string
PortFlavour uint16
+ Fn *DevlinkPortFn
+}
+
+type DevLinkPortAddAttrs struct {
+ Controller uint32
+ SfNumber uint32
+ PortIndex uint32
+ PfNumber uint16
+ SfNumberValid bool
+ PortIndexValid bool
+ ControllerValid bool
+}
+
+// DevlinkDeviceInfo represents devlink info
+type DevlinkDeviceInfo struct {
+ Driver string
+ SerialNumber string
+ BoardID string
+ FwApp string
+ FwAppBoundleID string
+ FwAppName string
+ FwBoundleID string
+ FwMgmt string
+ FwMgmtAPI string
+ FwMgmtBuild string
+ FwNetlist string
+ FwNetlistBuild string
+ FwPsidAPI string
+ FwUndi string
}
func parseDevLinkDeviceList(msgs [][]byte) ([]*DevlinkDevice, error) {
@@ -107,9 +152,9 @@ 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)
+ d.BusName = string(a.Value[:len(a.Value)-1])
case nl.DEVLINK_ATTR_DEV_NAME:
- d.DeviceName = string(a.Value)
+ d.DeviceName = string(a.Value[:len(a.Value)-1])
case nl.DEVLINK_ATTR_ESWITCH_MODE:
d.Attrs.Eswitch.Mode = parseEswitchMode(native.Uint16(a.Value))
case nl.DEVLINK_ATTR_ESWITCH_INLINE_MODE:
@@ -138,12 +183,12 @@ func (h *Handle) getEswitchAttrs(family *GenlFamily, dev *DevlinkDevice) {
req := h.newNetlinkRequest(int(family.ID), unix.NLM_F_REQUEST|unix.NLM_F_ACK)
req.AddData(msg)
- b := make([]byte, len(dev.BusName))
+ b := make([]byte, len(dev.BusName)+1)
copy(b, dev.BusName)
data := nl.NewRtAttr(nl.DEVLINK_ATTR_BUS_NAME, b)
req.AddData(data)
- b = make([]byte, len(dev.DeviceName))
+ b = make([]byte, len(dev.DeviceName)+1)
copy(b, dev.DeviceName)
data = nl.NewRtAttr(nl.DEVLINK_ATTR_DEV_NAME, b)
req.AddData(data)
@@ -287,21 +332,33 @@ 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)
+ port.BusName = string(a.Value[:len(a.Value)-1])
case nl.DEVLINK_ATTR_DEV_NAME:
- port.DeviceName = string(a.Value)
+ port.DeviceName = string(a.Value[:len(a.Value)-1])
case nl.DEVLINK_ATTR_PORT_INDEX:
port.PortIndex = native.Uint32(a.Value)
case nl.DEVLINK_ATTR_PORT_TYPE:
port.PortType = native.Uint16(a.Value)
case nl.DEVLINK_ATTR_PORT_NETDEV_NAME:
- port.NetdeviceName = string(a.Value)
+ port.NetdeviceName = string(a.Value[:len(a.Value)-1])
case nl.DEVLINK_ATTR_PORT_NETDEV_IFINDEX:
port.NetdevIfIndex = native.Uint32(a.Value)
case nl.DEVLINK_ATTR_PORT_IBDEV_NAME:
- port.RdmaDeviceName = string(a.Value)
+ port.RdmaDeviceName = string(a.Value[:len(a.Value)-1])
case nl.DEVLINK_ATTR_PORT_FLAVOUR:
port.PortFlavour = native.Uint16(a.Value)
+ case nl.DEVLINK_ATTR_PORT_FUNCTION:
+ port.Fn = &DevlinkPortFn{}
+ for nested := range nl.ParseAttributes(a.Value) {
+ switch nested.Type {
+ case nl.DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR:
+ port.Fn.HwAddr = nested.Value[:]
+ case nl.DEVLINK_PORT_FN_ATTR_STATE:
+ port.Fn.State = uint8(nested.Value[0])
+ case nl.DEVLINK_PORT_FN_ATTR_OPSTATE:
+ port.Fn.OpState = uint8(nested.Value[0])
+ }
+ }
}
}
return nil
@@ -391,3 +448,281 @@ func (h *Handle) DevLinkGetPortByIndex(Bus string, Device string, PortIndex uint
func DevLinkGetPortByIndex(Bus string, Device string, PortIndex uint32) (*DevlinkPort, error) {
return pkgHandle.DevLinkGetPortByIndex(Bus, Device, PortIndex)
}
+
+// DevLinkPortAdd adds a devlink port and returns a port on success
+// otherwise returns nil port and an error code.
+func (h *Handle) DevLinkPortAdd(Bus string, Device string, Flavour uint16, Attrs DevLinkPortAddAttrs) (*DevlinkPort, error) {
+ _, req, err := h.createCmdReq(nl.DEVLINK_CMD_PORT_NEW, Bus, Device)
+ if err != nil {
+ return nil, err
+ }
+
+ req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_FLAVOUR, nl.Uint16Attr(Flavour)))
+
+ req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_PCI_PF_NUMBER, nl.Uint16Attr(Attrs.PfNumber)))
+ if Flavour == nl.DEVLINK_PORT_FLAVOUR_PCI_SF && Attrs.SfNumberValid {
+ req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_PCI_SF_NUMBER, nl.Uint32Attr(Attrs.SfNumber)))
+ }
+ if Attrs.PortIndexValid {
+ req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_INDEX, nl.Uint32Attr(Attrs.PortIndex)))
+ }
+ if Attrs.ControllerValid {
+ req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_CONTROLLER_NUMBER, nl.Uint32Attr(Attrs.Controller)))
+ }
+ respmsg, err := req.Execute(unix.NETLINK_GENERIC, 0)
+ if err != nil {
+ return nil, err
+ }
+ port, err := parseDevlinkPortMsg(respmsg)
+ return port, err
+}
+
+// DevLinkPortAdd adds a devlink port and returns a port on success
+// otherwise returns nil port and an error code.
+func DevLinkPortAdd(Bus string, Device string, Flavour uint16, Attrs DevLinkPortAddAttrs) (*DevlinkPort, error) {
+ return pkgHandle.DevLinkPortAdd(Bus, Device, Flavour, Attrs)
+}
+
+// DevLinkPortDel deletes a devlink port and returns success or error code.
+func (h *Handle) DevLinkPortDel(Bus string, Device string, PortIndex uint32) error {
+ _, req, err := h.createCmdReq(nl.DEVLINK_CMD_PORT_DEL, Bus, Device)
+ if err != nil {
+ return err
+ }
+
+ req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_INDEX, nl.Uint32Attr(PortIndex)))
+ _, err = req.Execute(unix.NETLINK_GENERIC, 0)
+ return err
+}
+
+// DevLinkPortDel deletes a devlink port and returns success or error code.
+func DevLinkPortDel(Bus string, Device string, PortIndex uint32) error {
+ return pkgHandle.DevLinkPortDel(Bus, Device, PortIndex)
+}
+
+// DevlinkPortFnSet sets one or more port function attributes specified by the attribute mask.
+// It returns 0 on success or error code.
+func (h *Handle) DevlinkPortFnSet(Bus string, Device string, PortIndex uint32, FnAttrs DevlinkPortFnSetAttrs) error {
+ _, req, err := h.createCmdReq(nl.DEVLINK_CMD_PORT_SET, Bus, Device)
+ if err != nil {
+ return err
+ }
+
+ req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_INDEX, nl.Uint32Attr(PortIndex)))
+
+ fnAttr := nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_FUNCTION|unix.NLA_F_NESTED, nil)
+
+ if FnAttrs.HwAddrValid {
+ fnAttr.AddRtAttr(nl.DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, []byte(FnAttrs.FnAttrs.HwAddr))
+ }
+
+ if FnAttrs.StateValid {
+ fnAttr.AddRtAttr(nl.DEVLINK_PORT_FN_ATTR_STATE, nl.Uint8Attr(FnAttrs.FnAttrs.State))
+ }
+ req.AddData(fnAttr)
+
+ _, err = req.Execute(unix.NETLINK_GENERIC, 0)
+ return err
+}
+
+// DevlinkPortFnSet sets one or more port function attributes specified by the attribute mask.
+// It returns 0 on success or error code.
+func DevlinkPortFnSet(Bus string, Device string, PortIndex uint32, FnAttrs DevlinkPortFnSetAttrs) error {
+ return pkgHandle.DevlinkPortFnSet(Bus, Device, PortIndex, FnAttrs)
+}
+
+// devlinkInfoGetter is function that is responsible for getting devlink info message
+// this is introduced for test purpose
+type devlinkInfoGetter func(bus, device string) ([]byte, error)
+
+// DevlinkGetDeviceInfoByName returns devlink info for selected device,
+// otherwise returns an error code.
+// Equivalent to: `devlink dev info $dev`
+func (h *Handle) DevlinkGetDeviceInfoByName(Bus string, Device string, getInfoMsg devlinkInfoGetter) (*DevlinkDeviceInfo, error) {
+ info, err := h.DevlinkGetDeviceInfoByNameAsMap(Bus, Device, getInfoMsg)
+ if err != nil {
+ return nil, err
+ }
+
+ return parseInfoData(info), nil
+}
+
+// DevlinkGetDeviceInfoByName returns devlink info for selected device,
+// otherwise returns an error code.
+// Equivalent to: `devlink dev info $dev`
+func DevlinkGetDeviceInfoByName(Bus string, Device string) (*DevlinkDeviceInfo, error) {
+ return pkgHandle.DevlinkGetDeviceInfoByName(Bus, Device, pkgHandle.getDevlinkInfoMsg)
+}
+
+// DevlinkGetDeviceInfoByNameAsMap returns devlink info for selected device as a map,
+// otherwise returns an error code.
+// Equivalent to: `devlink dev info $dev`
+func (h *Handle) DevlinkGetDeviceInfoByNameAsMap(Bus string, Device string, getInfoMsg devlinkInfoGetter) (map[string]string, error) {
+ response, err := getInfoMsg(Bus, Device)
+ if err != nil {
+ return nil, err
+ }
+
+ info, err := parseInfoMsg(response)
+ if err != nil {
+ return nil, err
+ }
+
+ return info, nil
+}
+
+// DevlinkGetDeviceInfoByNameAsMap returns devlink info for selected device as a map,
+// otherwise returns an error code.
+// Equivalent to: `devlink dev info $dev`
+func DevlinkGetDeviceInfoByNameAsMap(Bus string, Device string) (map[string]string, error) {
+ return pkgHandle.DevlinkGetDeviceInfoByNameAsMap(Bus, Device, pkgHandle.getDevlinkInfoMsg)
+}
+
+// GetDevlinkInfo returns devlink info for target device,
+// otherwise returns an error code.
+func (d *DevlinkDevice) GetDevlinkInfo() (*DevlinkDeviceInfo, error) {
+ return pkgHandle.DevlinkGetDeviceInfoByName(d.BusName, d.DeviceName, pkgHandle.getDevlinkInfoMsg)
+}
+
+// GetDevlinkInfoAsMap returns devlink info for target device as a map,
+// otherwise returns an error code.
+func (d *DevlinkDevice) GetDevlinkInfoAsMap() (map[string]string, error) {
+ return pkgHandle.DevlinkGetDeviceInfoByNameAsMap(d.BusName, d.DeviceName, pkgHandle.getDevlinkInfoMsg)
+}
+
+func (h *Handle) getDevlinkInfoMsg(bus, device string) ([]byte, error) {
+ _, req, err := h.createCmdReq(nl.DEVLINK_CMD_INFO_GET, bus, device)
+ if err != nil {
+ return nil, err
+ }
+
+ response, err := req.Execute(unix.NETLINK_GENERIC, 0)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(response) < 1 {
+ return nil, fmt.Errorf("getDevlinkInfoMsg: message too short")
+ }
+
+ return response[0], nil
+}
+
+func parseInfoMsg(msg []byte) (map[string]string, error) {
+ if len(msg) < nl.SizeofGenlmsg {
+ return nil, fmt.Errorf("parseInfoMsg: message too short")
+ }
+
+ info := make(map[string]string)
+ err := collectInfoData(msg[nl.SizeofGenlmsg:], info)
+
+ if err != nil {
+ return nil, err
+ }
+
+ return info, nil
+}
+
+func collectInfoData(msg []byte, data map[string]string) error {
+ attrs, err := nl.ParseRouteAttr(msg)
+ if err != nil {
+ return err
+ }
+
+ for _, attr := range attrs {
+ switch attr.Attr.Type {
+ case nl.DEVLINK_ATTR_INFO_DRIVER_NAME:
+ data["driver"] = parseInfoValue(attr.Value)
+ case nl.DEVLINK_ATTR_INFO_SERIAL_NUMBER:
+ data["serialNumber"] = parseInfoValue(attr.Value)
+ case nl.DEVLINK_ATTR_INFO_VERSION_RUNNING, nl.DEVLINK_ATTR_INFO_VERSION_FIXED,
+ nl.DEVLINK_ATTR_INFO_VERSION_STORED:
+ key, value, err := getNestedInfoData(attr.Value)
+ if err != nil {
+ return err
+ }
+ data[key] = value
+ }
+ }
+
+ if len(data) == 0 {
+ return fmt.Errorf("collectInfoData: could not read attributes")
+ }
+
+ return nil
+}
+
+func getNestedInfoData(msg []byte) (string, string, error) {
+ nestedAttrs, err := nl.ParseRouteAttr(msg)
+
+ var key, value string
+
+ if err != nil {
+ return "", "", err
+ }
+
+ if len(nestedAttrs) != 2 {
+ return "", "", fmt.Errorf("getNestedInfoData: too few attributes in nested structure")
+ }
+
+ for _, nestedAttr := range nestedAttrs {
+ switch nestedAttr.Attr.Type {
+ case nl.DEVLINK_ATTR_INFO_VERSION_NAME:
+ key = parseInfoValue(nestedAttr.Value)
+ case nl.DEVLINK_ATTR_INFO_VERSION_VALUE:
+ value = parseInfoValue(nestedAttr.Value)
+ }
+ }
+
+ if key == "" {
+ return "", "", fmt.Errorf("getNestedInfoData: key not found")
+ }
+
+ if value == "" {
+ return "", "", fmt.Errorf("getNestedInfoData: value not found")
+ }
+
+ return key, value, nil
+}
+
+func parseInfoData(data map[string]string) *DevlinkDeviceInfo {
+ info := new(DevlinkDeviceInfo)
+ for key, value := range data {
+ switch key {
+ case "driver":
+ info.Driver = value
+ case "serialNumber":
+ info.SerialNumber = value
+ case "board.id":
+ info.BoardID = value
+ case "fw.app":
+ info.FwApp = value
+ case "fw.app.bundle_id":
+ info.FwAppBoundleID = value
+ case "fw.app.name":
+ info.FwAppName = value
+ case "fw.bundle_id":
+ info.FwBoundleID = value
+ case "fw.mgmt":
+ info.FwMgmt = value
+ case "fw.mgmt.api":
+ info.FwMgmtAPI = value
+ case "fw.mgmt.build":
+ info.FwMgmtBuild = value
+ case "fw.netlist":
+ info.FwNetlist = value
+ case "fw.netlist.build":
+ info.FwNetlistBuild = value
+ case "fw.psid.api":
+ info.FwPsidAPI = value
+ case "fw.undi":
+ info.FwUndi = value
+ }
+ }
+ return info
+}
+
+func parseInfoValue(value []byte) string {
+ v := strings.ReplaceAll(string(value), "\x00", "")
+ return strings.TrimSpace(v)
+}
diff --git a/vendor/github.com/vishvananda/netlink/filter.go b/vendor/github.com/vishvananda/netlink/filter.go
index 2dc34b995..413abdb47 100644
--- a/vendor/github.com/vishvananda/netlink/filter.go
+++ b/vendor/github.com/vishvananda/netlink/filter.go
@@ -260,6 +260,40 @@ func NewSkbEditAction() *SkbEditAction {
}
}
+type PoliceAction struct {
+ ActionAttrs
+ Rate uint32 // in byte per second
+ Burst uint32 // in byte
+ RCellLog int
+ Mtu uint32
+ Mpu uint16 // in byte
+ PeakRate uint32 // in byte per second
+ PCellLog int
+ AvRate uint32 // in byte per second
+ Overhead uint16
+ LinkLayer int
+ ExceedAction TcPolAct
+ NotExceedAction TcPolAct
+}
+
+func (action *PoliceAction) Type() string {
+ return "police"
+}
+
+func (action *PoliceAction) Attrs() *ActionAttrs {
+ return &action.ActionAttrs
+}
+
+func NewPoliceAction() *PoliceAction {
+ return &PoliceAction{
+ RCellLog: -1,
+ PCellLog: -1,
+ LinkLayer: 1, // ETHERNET
+ ExceedAction: TC_POLICE_RECLASSIFY,
+ NotExceedAction: TC_POLICE_OK,
+ }
+}
+
// MatchAll filters match all packets
type MatchAll struct {
FilterAttrs
@@ -275,20 +309,20 @@ func (filter *MatchAll) Type() string {
return "matchall"
}
-type FilterFwAttrs struct {
- ClassId uint32
- InDev string
- Mask uint32
- Index uint32
- Buffer uint32
- Mtu uint32
- Mpu uint16
- Rate uint32
- AvRate uint32
- PeakRate uint32
- Action TcPolAct
- Overhead uint16
- LinkLayer int
+type FwFilter struct {
+ FilterAttrs
+ ClassId uint32
+ InDev string
+ Mask uint32
+ Police *PoliceAction
+}
+
+func (filter *FwFilter) Attrs() *FilterAttrs {
+ return &filter.FilterAttrs
+}
+
+func (filter *FwFilter) Type() string {
+ return "fw"
}
type BpfFilter struct {
diff --git a/vendor/github.com/vishvananda/netlink/filter_linux.go b/vendor/github.com/vishvananda/netlink/filter_linux.go
index 2cd46266c..3cfea4586 100644
--- a/vendor/github.com/vishvananda/netlink/filter_linux.go
+++ b/vendor/github.com/vishvananda/netlink/filter_linux.go
@@ -6,6 +6,7 @@ import (
"encoding/hex"
"errors"
"fmt"
+ "net"
"syscall"
"github.com/vishvananda/netlink/nl"
@@ -50,74 +51,129 @@ 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
-type Fw struct {
+type Flower struct {
FilterAttrs
- ClassId uint32
- // TODO remove nl type from interface
- Police nl.TcPolice
- InDev string
- // TODO Action
- Mask uint32
- AvRate uint32
- Rtab [256]uint32
- Ptab [256]uint32
-}
-
-func NewFw(attrs FilterAttrs, fattrs FilterFwAttrs) (*Fw, error) {
- var rtab [256]uint32
- var ptab [256]uint32
- rcellLog := -1
- pcellLog := -1
- avrate := fattrs.AvRate / 8
- police := nl.TcPolice{}
- police.Rate.Rate = fattrs.Rate / 8
- police.PeakRate.Rate = fattrs.PeakRate / 8
- buffer := fattrs.Buffer
- linklayer := nl.LINKLAYER_ETHERNET
+ DestIP net.IP
+ DestIPMask net.IPMask
+ SrcIP net.IP
+ SrcIPMask net.IPMask
+ EthType uint16
+ EncDestIP net.IP
+ EncDestIPMask net.IPMask
+ EncSrcIP net.IP
+ EncSrcIPMask net.IPMask
+ EncDestPort uint16
+ EncKeyId uint32
+
+ Actions []Action
+}
- if fattrs.LinkLayer != nl.LINKLAYER_UNSPEC {
- linklayer = fattrs.LinkLayer
- }
+func (filter *Flower) Attrs() *FilterAttrs {
+ return &filter.FilterAttrs
+}
- police.Action = int32(fattrs.Action)
- if police.Rate.Rate != 0 {
- police.Rate.Mpu = fattrs.Mpu
- police.Rate.Overhead = fattrs.Overhead
- if CalcRtable(&police.Rate, rtab[:], rcellLog, fattrs.Mtu, linklayer) < 0 {
- return nil, errors.New("TBF: failed to calculate rate table")
- }
- police.Burst = Xmittime(uint64(police.Rate.Rate), uint32(buffer))
+func (filter *Flower) Type() string {
+ return "flower"
+}
+
+func (filter *Flower) encodeIP(parent *nl.RtAttr, ip net.IP, mask net.IPMask, v4Type, v6Type int, v4MaskType, v6MaskType int) {
+ ipType := v4Type
+ maskType := v4MaskType
+
+ encodeMask := mask
+ if mask == nil {
+ encodeMask = net.CIDRMask(32, 32)
}
- police.Mtu = fattrs.Mtu
- if police.PeakRate.Rate != 0 {
- police.PeakRate.Mpu = fattrs.Mpu
- police.PeakRate.Overhead = fattrs.Overhead
- if CalcRtable(&police.PeakRate, ptab[:], pcellLog, fattrs.Mtu, linklayer) < 0 {
- return nil, errors.New("POLICE: failed to calculate peak rate table")
- }
+ v4IP := ip.To4()
+ if v4IP == nil {
+ ipType = v6Type
+ maskType = v6MaskType
+ if mask == nil {
+ encodeMask = net.CIDRMask(128, 128)
+ }
+ } else {
+ ip = v4IP
}
- return &Fw{
- FilterAttrs: attrs,
- ClassId: fattrs.ClassId,
- InDev: fattrs.InDev,
- Mask: fattrs.Mask,
- Police: police,
- AvRate: avrate,
- Rtab: rtab,
- Ptab: ptab,
- }, nil
+ parent.AddRtAttr(ipType, ip)
+ parent.AddRtAttr(maskType, encodeMask)
}
-func (filter *Fw) Attrs() *FilterAttrs {
- return &filter.FilterAttrs
+func (filter *Flower) encode(parent *nl.RtAttr) error {
+ if filter.EthType != 0 {
+ parent.AddRtAttr(nl.TCA_FLOWER_KEY_ETH_TYPE, htons(filter.EthType))
+ }
+ if filter.SrcIP != nil {
+ filter.encodeIP(parent, filter.SrcIP, filter.SrcIPMask,
+ nl.TCA_FLOWER_KEY_IPV4_SRC, nl.TCA_FLOWER_KEY_IPV6_SRC,
+ nl.TCA_FLOWER_KEY_IPV4_SRC_MASK, nl.TCA_FLOWER_KEY_IPV6_SRC_MASK)
+ }
+ if filter.DestIP != nil {
+ filter.encodeIP(parent, filter.DestIP, filter.DestIPMask,
+ nl.TCA_FLOWER_KEY_IPV4_DST, nl.TCA_FLOWER_KEY_IPV6_DST,
+ nl.TCA_FLOWER_KEY_IPV4_DST_MASK, nl.TCA_FLOWER_KEY_IPV6_DST_MASK)
+ }
+ if filter.EncSrcIP != nil {
+ filter.encodeIP(parent, filter.EncSrcIP, filter.EncSrcIPMask,
+ nl.TCA_FLOWER_KEY_ENC_IPV4_SRC, nl.TCA_FLOWER_KEY_ENC_IPV6_SRC,
+ nl.TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK, nl.TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK)
+ }
+ if filter.EncDestIP != nil {
+ filter.encodeIP(parent, filter.EncDestIP, filter.EncSrcIPMask,
+ nl.TCA_FLOWER_KEY_ENC_IPV4_DST, nl.TCA_FLOWER_KEY_ENC_IPV6_DST,
+ nl.TCA_FLOWER_KEY_ENC_IPV4_DST_MASK, nl.TCA_FLOWER_KEY_ENC_IPV6_DST_MASK)
+ }
+ if filter.EncDestPort != 0 {
+ parent.AddRtAttr(nl.TCA_FLOWER_KEY_ENC_UDP_DST_PORT, htons(filter.EncDestPort))
+ }
+ if filter.EncKeyId != 0 {
+ parent.AddRtAttr(nl.TCA_FLOWER_KEY_ENC_KEY_ID, htonl(filter.EncKeyId))
+ }
+
+ actionsAttr := parent.AddRtAttr(nl.TCA_FLOWER_ACT, nil)
+ if err := EncodeActions(actionsAttr, filter.Actions); err != nil {
+ return err
+ }
+ return nil
}
-func (filter *Fw) Type() string {
- return "fw"
+func (filter *Flower) decode(data []syscall.NetlinkRouteAttr) error {
+ for _, datum := range data {
+ switch datum.Attr.Type {
+ case nl.TCA_FLOWER_KEY_ETH_TYPE:
+ filter.EthType = ntohs(datum.Value)
+ case nl.TCA_FLOWER_KEY_IPV4_SRC, nl.TCA_FLOWER_KEY_IPV6_SRC:
+ filter.SrcIP = datum.Value
+ case nl.TCA_FLOWER_KEY_IPV4_SRC_MASK, nl.TCA_FLOWER_KEY_IPV6_SRC_MASK:
+ filter.SrcIPMask = datum.Value
+ case nl.TCA_FLOWER_KEY_IPV4_DST, nl.TCA_FLOWER_KEY_IPV6_DST:
+ filter.DestIP = datum.Value
+ case nl.TCA_FLOWER_KEY_IPV4_DST_MASK, nl.TCA_FLOWER_KEY_IPV6_DST_MASK:
+ filter.DestIPMask = datum.Value
+ case nl.TCA_FLOWER_KEY_ENC_IPV4_SRC, nl.TCA_FLOWER_KEY_ENC_IPV6_SRC:
+ filter.EncSrcIP = datum.Value
+ case nl.TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK, nl.TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK:
+ filter.EncSrcIPMask = datum.Value
+ case nl.TCA_FLOWER_KEY_ENC_IPV4_DST, nl.TCA_FLOWER_KEY_ENC_IPV6_DST:
+ filter.EncDestIP = datum.Value
+ case nl.TCA_FLOWER_KEY_ENC_IPV4_DST_MASK, nl.TCA_FLOWER_KEY_ENC_IPV6_DST_MASK:
+ filter.EncDestIPMask = datum.Value
+ case nl.TCA_FLOWER_KEY_ENC_UDP_DST_PORT:
+ filter.EncDestPort = ntohs(datum.Value)
+ case nl.TCA_FLOWER_KEY_ENC_KEY_ID:
+ filter.EncKeyId = ntohl(datum.Value)
+ case nl.TCA_FLOWER_ACT:
+ tables, err := nl.ParseRouteAttr(datum.Value)
+ if err != nil {
+ return err
+ }
+ filter.Actions, err = parseActions(tables)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ return nil
}
// FilterDel will delete a filter from the system.
@@ -169,7 +225,6 @@ func (h *Handle) FilterReplace(filter Filter) error {
}
func (h *Handle) filterModify(filter Filter, flags int) error {
- native = nl.NativeEndian()
req := h.newNetlinkRequest(unix.RTM_NEWTFILTER, flags|unix.NLM_F_ACK)
base := filter.Attrs()
msg := &nl.TcMsg{
@@ -237,7 +292,7 @@ func (h *Handle) filterModify(filter Filter, flags int) error {
if err := EncodeActions(actionsAttr, filter.Actions); err != nil {
return err
}
- case *Fw:
+ case *FwFilter:
if filter.Mask != 0 {
b := make([]byte, 4)
native.PutUint32(b, filter.Mask)
@@ -246,17 +301,10 @@ func (h *Handle) filterModify(filter Filter, flags int) error {
if filter.InDev != "" {
options.AddRtAttr(nl.TCA_FW_INDEV, nl.ZeroTerminated(filter.InDev))
}
- if (filter.Police != nl.TcPolice{}) {
-
+ if filter.Police != nil {
police := options.AddRtAttr(nl.TCA_FW_POLICE, nil)
- police.AddRtAttr(nl.TCA_POLICE_TBF, filter.Police.Serialize())
- if (filter.Police.Rate != nl.TcRateSpec{}) {
- payload := SerializeRtab(filter.Rtab)
- police.AddRtAttr(nl.TCA_POLICE_RATE, payload)
- }
- if (filter.Police.PeakRate != nl.TcRateSpec{}) {
- payload := SerializeRtab(filter.Ptab)
- police.AddRtAttr(nl.TCA_POLICE_PEAKRATE, payload)
+ if err := encodePolice(police, filter.Police); err != nil {
+ return err
}
}
if filter.ClassId != 0 {
@@ -287,6 +335,10 @@ func (h *Handle) filterModify(filter Filter, flags int) error {
if filter.ClassId != 0 {
options.AddRtAttr(nl.TCA_MATCHALL_CLASSID, nl.Uint32Attr(filter.ClassId))
}
+ case *Flower:
+ if err := filter.encode(options); err != nil {
+ return err
+ }
}
req.AddData(options)
@@ -350,11 +402,13 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
case "u32":
filter = &U32{}
case "fw":
- filter = &Fw{}
+ filter = &FwFilter{}
case "bpf":
filter = &BpfFilter{}
case "matchall":
filter = &MatchAll{}
+ case "flower":
+ filter = &Flower{}
default:
filter = &GenericFilter{FilterType: filterType}
}
@@ -384,6 +438,11 @@ func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
if err != nil {
return nil, err
}
+ case "flower":
+ detailed, err = parseFlowerData(filter, data)
+ if err != nil {
+ return nil, err
+ }
default:
detailed = true
}
@@ -415,6 +474,53 @@ func toAttrs(tcgen *nl.TcGen, attrs *ActionAttrs) {
attrs.Bindcnt = int(tcgen.Bindcnt)
}
+func encodePolice(attr *nl.RtAttr, action *PoliceAction) error {
+ var rtab [256]uint32
+ var ptab [256]uint32
+ police := nl.TcPolice{}
+ police.Index = uint32(action.Attrs().Index)
+ police.Bindcnt = int32(action.Attrs().Bindcnt)
+ police.Capab = uint32(action.Attrs().Capab)
+ police.Refcnt = int32(action.Attrs().Refcnt)
+ police.Rate.Rate = action.Rate
+ police.PeakRate.Rate = action.PeakRate
+ police.Action = int32(action.ExceedAction)
+
+ if police.Rate.Rate != 0 {
+ police.Rate.Mpu = action.Mpu
+ police.Rate.Overhead = action.Overhead
+ if CalcRtable(&police.Rate, rtab[:], action.RCellLog, action.Mtu, action.LinkLayer) < 0 {
+ return errors.New("TBF: failed to calculate rate table")
+ }
+ police.Burst = Xmittime(uint64(police.Rate.Rate), action.Burst)
+ }
+
+ police.Mtu = action.Mtu
+ if police.PeakRate.Rate != 0 {
+ police.PeakRate.Mpu = action.Mpu
+ police.PeakRate.Overhead = action.Overhead
+ if CalcRtable(&police.PeakRate, ptab[:], action.PCellLog, action.Mtu, action.LinkLayer) < 0 {
+ return errors.New("POLICE: failed to calculate peak rate table")
+ }
+ }
+
+ attr.AddRtAttr(nl.TCA_POLICE_TBF, police.Serialize())
+ if police.Rate.Rate != 0 {
+ attr.AddRtAttr(nl.TCA_POLICE_RATE, SerializeRtab(rtab))
+ }
+ if police.PeakRate.Rate != 0 {
+ attr.AddRtAttr(nl.TCA_POLICE_PEAKRATE, SerializeRtab(ptab))
+ }
+ if action.AvRate != 0 {
+ attr.AddRtAttr(nl.TCA_POLICE_AVRATE, nl.Uint32Attr(action.AvRate))
+ }
+ if action.NotExceedAction != 0 {
+ attr.AddRtAttr(nl.TCA_POLICE_RESULT, nl.Uint32Attr(uint32(action.NotExceedAction)))
+ }
+
+ return nil
+}
+
func EncodeActions(attr *nl.RtAttr, actions []Action) error {
tabIndex := int(nl.TCA_ACT_TAB)
@@ -422,6 +528,14 @@ func EncodeActions(attr *nl.RtAttr, actions []Action) error {
switch action := action.(type) {
default:
return fmt.Errorf("unknown action type %s", action.Type())
+ case *PoliceAction:
+ table := attr.AddRtAttr(tabIndex, nil)
+ tabIndex++
+ table.AddRtAttr(nl.TCA_ACT_KIND, nl.ZeroTerminated("police"))
+ aopts := table.AddRtAttr(nl.TCA_ACT_OPTIONS, nil)
+ if err := encodePolice(aopts, action); err != nil {
+ return err
+ }
case *MirredAction:
table := attr.AddRtAttr(tabIndex, nil)
tabIndex++
@@ -516,6 +630,29 @@ func EncodeActions(attr *nl.RtAttr, actions []Action) error {
return nil
}
+func parsePolice(data syscall.NetlinkRouteAttr, police *PoliceAction) {
+ switch data.Attr.Type {
+ case nl.TCA_POLICE_RESULT:
+ police.NotExceedAction = TcPolAct(native.Uint32(data.Value[0:4]))
+ case nl.TCA_POLICE_AVRATE:
+ police.AvRate = native.Uint32(data.Value[0:4])
+ case nl.TCA_POLICE_TBF:
+ p := *nl.DeserializeTcPolice(data.Value)
+ police.ActionAttrs = ActionAttrs{}
+ police.Attrs().Index = int(p.Index)
+ police.Attrs().Bindcnt = int(p.Bindcnt)
+ police.Attrs().Capab = int(p.Capab)
+ police.Attrs().Refcnt = int(p.Refcnt)
+ police.ExceedAction = TcPolAct(p.Action)
+ police.Rate = p.Rate.Rate
+ police.PeakRate = p.PeakRate.Rate
+ police.Burst = Xmitsize(uint64(p.Rate.Rate), p.Burst)
+ police.Mtu = p.Mtu
+ police.LinkLayer = int(p.Rate.Linklayer) & nl.TC_LINKLAYER_MASK
+ police.Overhead = p.Rate.Overhead
+ }
+}
+
func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
var actions []Action
for _, table := range tables {
@@ -544,6 +681,8 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
action = &TunnelKeyAction{}
case "skbedit":
action = &SkbEditAction{}
+ case "police":
+ action = &PoliceAction{}
default:
break nextattr
}
@@ -622,6 +761,8 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
gen := *nl.DeserializeTcGen(adatum.Value)
toAttrs(&gen, action.Attrs())
}
+ case "police":
+ parsePolice(adatum, action.(*PoliceAction))
}
}
}
@@ -632,7 +773,6 @@ func parseActions(tables []syscall.NetlinkRouteAttr) ([]Action, error) {
}
func parseU32Data(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
- native = nl.NativeEndian()
u32 := filter.(*U32)
detailed := false
for _, datum := range data {
@@ -678,8 +818,7 @@ func parseU32Data(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error)
}
func parseFwData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
- native = nl.NativeEndian()
- fw := filter.(*Fw)
+ fw := filter.(*FwFilter)
detailed := true
for _, datum := range data {
switch datum.Attr.Type {
@@ -690,24 +829,18 @@ func parseFwData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
case nl.TCA_FW_INDEV:
fw.InDev = string(datum.Value[:len(datum.Value)-1])
case nl.TCA_FW_POLICE:
+ var police PoliceAction
adata, _ := nl.ParseRouteAttr(datum.Value)
for _, aattr := range adata {
- switch aattr.Attr.Type {
- case nl.TCA_POLICE_TBF:
- fw.Police = *nl.DeserializeTcPolice(aattr.Value)
- case nl.TCA_POLICE_RATE:
- fw.Rtab = DeserializeRtab(aattr.Value)
- case nl.TCA_POLICE_PEAKRATE:
- fw.Ptab = DeserializeRtab(aattr.Value)
- }
+ parsePolice(aattr, &police)
}
+ fw.Police = &police
}
}
return detailed, nil
}
func parseBpfData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
- native = nl.NativeEndian()
bpf := filter.(*BpfFilter)
detailed := true
for _, datum := range data {
@@ -733,7 +866,6 @@ func parseBpfData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error)
}
func parseMatchAllData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
- native = nl.NativeEndian()
matchall := filter.(*MatchAll)
detailed := true
for _, datum := range data {
@@ -754,6 +886,10 @@ func parseMatchAllData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, er
return detailed, nil
}
+func parseFlowerData(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error) {
+ return true, filter.(*Flower).decode(data)
+}
+
func AlignToAtm(size uint) uint {
var linksize, cells int
cells = int(size / nl.ATM_CELL_PAYLOAD)
@@ -801,14 +937,12 @@ func CalcRtable(rate *nl.TcRateSpec, rtab []uint32, cellLog int, mtu uint32, lin
func DeserializeRtab(b []byte) [256]uint32 {
var rtab [256]uint32
- native := nl.NativeEndian()
r := bytes.NewReader(b)
_ = binary.Read(r, native, &rtab)
return rtab
}
func SerializeRtab(rtab [256]uint32) []byte {
- native := nl.NativeEndian()
var w bytes.Buffer
_ = binary.Write(&w, native, rtab)
return w.Bytes()
diff --git a/vendor/github.com/vishvananda/netlink/handle_linux.go b/vendor/github.com/vishvananda/netlink/handle_linux.go
index 65356679d..c02bfb7e6 100644
--- a/vendor/github.com/vishvananda/netlink/handle_linux.go
+++ b/vendor/github.com/vishvananda/netlink/handle_linux.go
@@ -15,7 +15,7 @@ var pkgHandle = &Handle{}
// Handle is an handle for the netlink requests on a
// specific network namespace. All the requests on the
// same netlink family share the same netlink socket,
-// which gets released when the handle is deleted.
+// which gets released when the handle is Close'd.
type Handle struct {
sockets map[int]*nl.SocketHandle
lookupByDump bool
@@ -136,14 +136,22 @@ func newHandle(newNs, curNs netns.NsHandle, nlFamilies ...int) (*Handle, error)
return h, nil
}
-// Delete releases the resources allocated to this handle
-func (h *Handle) Delete() {
+// Close releases the resources allocated to this handle
+func (h *Handle) Close() {
for _, sh := range h.sockets {
sh.Close()
}
h.sockets = nil
}
+// Delete releases the resources allocated to this handle
+//
+// Deprecated: use Close instead which is in line with typical resource release
+// patterns for files and other resources.
+func (h *Handle) Delete() {
+ h.Close()
+}
+
func (h *Handle) newNetlinkRequest(proto, flags int) *nl.NetlinkRequest {
// Do this so that package API still use nl package variable nextSeqNr
if h.sockets == nil {
diff --git a/vendor/github.com/vishvananda/netlink/handle_unspecified.go b/vendor/github.com/vishvananda/netlink/handle_unspecified.go
index 3a6db8137..cc94a4e00 100644
--- a/vendor/github.com/vishvananda/netlink/handle_unspecified.go
+++ b/vendor/github.com/vishvananda/netlink/handle_unspecified.go
@@ -23,6 +23,8 @@ func NewHandleAtFrom(newNs, curNs netns.NsHandle) (*Handle, error) {
return nil, ErrNotImplemented
}
+func (h *Handle) Close() {}
+
func (h *Handle) Delete() {}
func (h *Handle) SupportsNetlinkFamily(nlFamily int) bool {
diff --git a/vendor/github.com/vishvananda/netlink/ipset_linux.go b/vendor/github.com/vishvananda/netlink/ipset_linux.go
index 2adc2440a..1f4eae81c 100644
--- a/vendor/github.com/vishvananda/netlink/ipset_linux.go
+++ b/vendor/github.com/vishvananda/netlink/ipset_linux.go
@@ -1,6 +1,7 @@
package netlink
import (
+ "encoding/binary"
"log"
"net"
"syscall"
@@ -11,12 +12,19 @@ import (
// 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
+ Comment string
+ MAC net.HardwareAddr
+ IP net.IP
+ CIDR uint8
+ Timeout *uint32
+ Packets *uint64
+ Bytes *uint64
+ Protocol *uint8
+ Port *uint16
+ IP2 net.IP
+ CIDR2 uint8
+ IFace string
+ Mark *uint32
Replace bool // replace existing entry
}
@@ -32,6 +40,12 @@ type IPSetResult struct {
SetName string
TypeName string
Comment string
+ MarkMask uint32
+
+ IPFrom net.IP
+ IPTo net.IP
+ PortFrom uint16
+ PortTo uint16
HashSize uint32
NumEntries uint32
@@ -52,6 +66,12 @@ type IpsetCreateOptions struct {
Counters bool
Comments bool
Skbinfo bool
+
+ Revision uint8
+ IPFrom net.IP
+ IPTo net.IP
+ PortFrom uint16
+ PortTo uint16
}
// IpsetProtocol returns the ipset protocol version from the kernel
@@ -86,12 +106,12 @@ func IpsetListAll() ([]IPSetResult, error) {
// IpsetAdd adds an entry to an existing ipset.
func IpsetAdd(setname string, entry *IPSetEntry) error {
- return pkgHandle.ipsetAddDel(nl.IPSET_CMD_ADD, setname, entry)
+ return pkgHandle.IpsetAdd(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)
+ return pkgHandle.IpsetDel(setname, entry)
}
func (h *Handle) IpsetProtocol() (protocol uint8, minVersion uint8, err error) {
@@ -114,11 +134,30 @@ func (h *Handle) IpsetCreate(setname, typename string, options IpsetCreateOption
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
+
+ revision := options.Revision
+ if revision == 0 {
+ revision = getIpsetDefaultWithTypeName(typename)
+ }
+ req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_REVISION, nl.Uint8Attr(revision)))
data := nl.NewRtAttr(nl.IPSET_ATTR_DATA|int(nl.NLA_F_NESTED), nil)
+ var family uint8
+ switch typename {
+ case "hash:mac":
+ case "bitmap:port":
+ buf := make([]byte, 4)
+ binary.BigEndian.PutUint16(buf, options.PortFrom)
+ binary.BigEndian.PutUint16(buf[2:], options.PortTo)
+ data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_PORT_FROM|int(nl.NLA_F_NET_BYTEORDER), buf[:2]))
+ data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_PORT_TO|int(nl.NLA_F_NET_BYTEORDER), buf[2:]))
+ default:
+ family = unix.AF_INET
+ }
+
+ req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_FAMILY, nl.Uint8Attr(family)))
+
if timeout := options.Timeout; timeout != nil {
data.AddChild(&nl.Uint32Attribute{Type: nl.IPSET_ATTR_TIMEOUT | nl.NLA_F_NET_BYTEORDER, Value: *timeout})
}
@@ -187,6 +226,16 @@ func (h *Handle) IpsetListAll() ([]IPSetResult, error) {
return result, nil
}
+// IpsetAdd adds an entry to an existing ipset.
+func (h *Handle) IpsetAdd(setname string, entry *IPSetEntry) error {
+ return h.ipsetAddDel(nl.IPSET_CMD_ADD, setname, entry)
+}
+
+// IpsetDel deletes an entry from an existing ipset.
+func (h *Handle) IpsetDel(setname string, entry *IPSetEntry) error {
+ return h.ipsetAddDel(nl.IPSET_CMD_DEL, setname, entry)
+}
+
func (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)))
@@ -204,15 +253,49 @@ func (h *Handle) ipsetAddDel(nlCmd int, setname string, entry *IPSetEntry) error
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()))
}
+ if entry.MAC != nil {
+ data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_ETHER, entry.MAC))
+ }
+
+ if entry.CIDR != 0 {
+ data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_CIDR, nl.Uint8Attr(entry.CIDR)))
+ }
+
+ if entry.IP2 != nil {
+ nestedData := nl.NewRtAttr(nl.IPSET_ATTR_IP|int(nl.NLA_F_NET_BYTEORDER), entry.IP2)
+ data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_IP2|int(nl.NLA_F_NESTED), nestedData.Serialize()))
+ }
+
+ if entry.CIDR2 != 0 {
+ data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_CIDR2, nl.Uint8Attr(entry.CIDR2)))
+ }
+
+ if entry.Port != nil {
+ if entry.Protocol == nil {
+ // use tcp protocol as default
+ val := uint8(unix.IPPROTO_TCP)
+ entry.Protocol = &val
+ }
+ data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_PROTO, nl.Uint8Attr(*entry.Protocol)))
+ buf := make([]byte, 2)
+ binary.BigEndian.PutUint16(buf, *entry.Port)
+ data.AddChild(nl.NewRtAttr(int(nl.IPSET_ATTR_PORT|nl.NLA_F_NET_BYTEORDER), buf))
+ }
+
+ if entry.IFace != "" {
+ data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_IFACE, nl.ZeroTerminated(entry.IFace)))
+ }
+
+ if entry.Mark != nil {
+ data.AddChild(&nl.Uint32Attribute{Type: nl.IPSET_ATTR_MARK | nl.NLA_F_NET_BYTEORDER, Value: *entry.Mark})
+ }
+
data.AddChild(&nl.Uint32Attribute{Type: nl.IPSET_ATTR_LINENO | nl.NLA_F_NET_BYTEORDER, Value: 0})
req.AddData(data)
@@ -235,6 +318,17 @@ func (h *Handle) newIpsetRequest(cmd int) *nl.NetlinkRequest {
return req
}
+func getIpsetDefaultWithTypeName(typename string) uint8 {
+ switch typename {
+ case "hash:ip,port",
+ "hash:ip,port,ip",
+ "hash:ip,port,net",
+ "hash:net,port":
+ return 1
+ }
+ return 0
+}
+
func ipsetExecute(req *nl.NetlinkRequest) (msgs [][]byte, err error) {
msgs, err = req.Execute(unix.NETLINK_NETFILTER, 0)
@@ -278,6 +372,8 @@ func (result *IPSetResult) unserialize(msg []byte) {
result.parseAttrADT(attr.Value)
case nl.IPSET_ATTR_PROTOCOL_MIN:
result.ProtocolMinVersion = attr.Value[0]
+ case nl.IPSET_ATTR_MARKMASK:
+ result.MarkMask = attr.Uint32()
default:
log.Printf("unknown ipset attribute from kernel: %+v %v", attr, attr.Type&nl.NLA_TYPE_MASK)
}
@@ -307,12 +403,31 @@ func (result *IPSetResult) parseAttrData(data []byte) {
switch nested.Type {
case nl.IPSET_ATTR_IP | nl.NLA_F_NET_BYTEORDER:
result.Entries = append(result.Entries, IPSetEntry{IP: nested.Value})
+ case nl.IPSET_ATTR_IP:
+ result.IPFrom = nested.Value
+ default:
+ log.Printf("unknown nested ipset data attribute from kernel: %+v %v", nested, nested.Type&nl.NLA_TYPE_MASK)
+ }
+ }
+ case nl.IPSET_ATTR_IP_TO | nl.NLA_F_NESTED:
+ for nested := range nl.ParseAttributes(attr.Value) {
+ switch nested.Type {
+ case nl.IPSET_ATTR_IP:
+ result.IPTo = nested.Value
+ default:
+ log.Printf("unknown nested ipset data attribute from kernel: %+v %v", nested, nested.Type&nl.NLA_TYPE_MASK)
}
}
+ case nl.IPSET_ATTR_PORT_FROM | nl.NLA_F_NET_BYTEORDER:
+ result.PortFrom = networkOrder.Uint16(attr.Value)
+ case nl.IPSET_ATTR_PORT_TO | nl.NLA_F_NET_BYTEORDER:
+ result.PortTo = networkOrder.Uint16(attr.Value)
case nl.IPSET_ATTR_CADT_LINENO | nl.NLA_F_NET_BYTEORDER:
result.LineNo = attr.Uint32()
case nl.IPSET_ATTR_COMMENT:
result.Comment = nl.BytesToString(attr.Value)
+ case nl.IPSET_ATTR_MARKMASK:
+ result.MarkMask = attr.Uint32()
default:
log.Printf("unknown ipset data attribute from kernel: %+v %v", attr, attr.Type&nl.NLA_TYPE_MASK)
}
@@ -357,6 +472,30 @@ func parseIPSetEntry(data []byte) (entry IPSetEntry) {
log.Printf("unknown nested ADT attribute from kernel: %+v", attr)
}
}
+ case nl.IPSET_ATTR_IP2 | nl.NLA_F_NESTED:
+ for attr := range nl.ParseAttributes(attr.Value) {
+ switch attr.Type {
+ case nl.IPSET_ATTR_IP:
+ entry.IP2 = net.IP(attr.Value)
+ default:
+ log.Printf("unknown nested ADT attribute from kernel: %+v", attr)
+ }
+ }
+ case nl.IPSET_ATTR_CIDR:
+ entry.CIDR = attr.Value[0]
+ case nl.IPSET_ATTR_CIDR2:
+ entry.CIDR2 = attr.Value[0]
+ case nl.IPSET_ATTR_PORT | nl.NLA_F_NET_BYTEORDER:
+ val := networkOrder.Uint16(attr.Value)
+ entry.Port = &val
+ case nl.IPSET_ATTR_PROTO:
+ val := attr.Value[0]
+ entry.Protocol = &val
+ case nl.IPSET_ATTR_IFACE:
+ entry.IFace = nl.BytesToString(attr.Value)
+ case nl.IPSET_ATTR_MARK | nl.NLA_F_NET_BYTEORDER:
+ val := attr.Uint32()
+ entry.Mark = &val
default:
log.Printf("unknown ADT attribute from kernel: %+v", attr)
}
diff --git a/vendor/github.com/vishvananda/netlink/link.go b/vendor/github.com/vishvananda/netlink/link.go
index 32ca7cd64..82d0360eb 100644
--- a/vendor/github.com/vishvananda/netlink/link.go
+++ b/vendor/github.com/vishvananda/netlink/link.go
@@ -35,10 +35,13 @@ type LinkAttrs struct {
Alias string
Statistics *LinkStatistics
Promisc int
+ Allmulti int
+ Multi int
Xdp *LinkXdp
EncapType string
Protinfo *Protinfo
OperState LinkOperState
+ PhysSwitchID int
NetNsID int
NumTxQueues int
NumRxQueues int
@@ -456,6 +459,19 @@ func (ipvlan *IPVlan) Type() string {
return "ipvlan"
}
+// IPVtap - IPVtap is a virtual interfaces based on ipvlan
+type IPVtap struct {
+ IPVlan
+}
+
+func (ipvtap *IPVtap) Attrs() *LinkAttrs {
+ return &ipvtap.LinkAttrs
+}
+
+func (ipvtap IPVtap) Type() string {
+ return "ipvtap"
+}
+
// VlanProtocol type
type VlanProtocol int
@@ -946,6 +962,14 @@ func (b *BondSlave) SlaveType() string {
return "bond"
}
+type VrfSlave struct {
+ Table uint32
+}
+
+func (v *VrfSlave) SlaveType() string {
+ return "vrf"
+}
+
// Geneve devices must specify RemoteIP and ID (VNI) on create
// https://github.com/torvalds/linux/blob/47ec5303d73ea344e84f46660fff693c57641386/drivers/net/geneve.c#L1209-L1223
type Geneve struct {
@@ -1049,6 +1073,37 @@ func (ip6tnl *Ip6tnl) Type() string {
return "ip6tnl"
}
+// from https://elixir.bootlin.com/linux/v5.15.4/source/include/uapi/linux/if_tunnel.h#L84
+type TunnelEncapType uint16
+
+const (
+ None TunnelEncapType = iota
+ FOU
+ GUE
+)
+
+// from https://elixir.bootlin.com/linux/v5.15.4/source/include/uapi/linux/if_tunnel.h#L91
+type TunnelEncapFlag uint16
+
+const (
+ CSum TunnelEncapFlag = 1 << 0
+ CSum6 = 1 << 1
+ RemCSum = 1 << 2
+)
+
+// from https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/ip6_tunnel.h#L12
+type IP6TunnelFlag uint16
+
+const (
+ IP6_TNL_F_IGN_ENCAP_LIMIT IP6TunnelFlag = 1 // don't add encapsulation limit if one isn't present in inner packet
+ IP6_TNL_F_USE_ORIG_TCLASS = 2 // copy the traffic class field from the inner packet
+ IP6_TNL_F_USE_ORIG_FLOWLABEL = 4 // copy the flowlabel from the inner packet
+ IP6_TNL_F_MIP6_DEV = 8 // being used for Mobile IPv6
+ IP6_TNL_F_RCV_DSCP_COPY = 10 // copy DSCP from the outer packet
+ IP6_TNL_F_USE_ORIG_FWMARK = 20 // copy fwmark from inner packet
+ IP6_TNL_F_ALLOW_LOCAL_REMOTE = 40 // allow remote endpoint on the local node
+)
+
type Sittun struct {
LinkAttrs
Link uint32
@@ -1260,11 +1315,27 @@ func (ipoib *IPoIB) Type() string {
return "ipoib"
}
+type BareUDP struct {
+ LinkAttrs
+ Port uint16
+ EtherType uint16
+ SrcPortMin uint16
+ MultiProto bool
+}
+
+func (bareudp *BareUDP) Attrs() *LinkAttrs {
+ return &bareudp.LinkAttrs
+}
+
+func (bareudp *BareUDP) Type() string {
+ return "bareudp"
+}
+
// iproute2 supported devices;
// vlan | veth | vcan | dummy | ifb | macvlan | macvtap |
// bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan |
// gre | gretap | ip6gre | ip6gretap | vti | vti6 | nlmon |
-// bond_slave | ipvlan | xfrm
+// bond_slave | ipvlan | xfrm | bareudp
// LinkNotFoundError wraps the various not found errors when
// getting/reading links. This is intended for better error
diff --git a/vendor/github.com/vishvananda/netlink/link_linux.go b/vendor/github.com/vishvananda/netlink/link_linux.go
index 3b959299c..aa998e311 100644
--- a/vendor/github.com/vishvananda/netlink/link_linux.go
+++ b/vendor/github.com/vishvananda/netlink/link_linux.go
@@ -55,8 +55,6 @@ const (
VF_LINK_STATE_DISABLE uint32 = 2
)
-var lookupByDump = false
-
var macvlanModes = [...]uint32{
0,
nl.MACVLAN_MODE_PRIVATE,
@@ -153,7 +151,6 @@ func (h *Handle) LinkSetAllmulticastOn(link Link) error {
msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
msg.Change = unix.IFF_ALLMULTI
msg.Flags = unix.IFF_ALLMULTI
-
msg.Index = int32(base.Index)
req.AddData(msg)
@@ -183,6 +180,51 @@ func (h *Handle) LinkSetAllmulticastOff(link Link) error {
return err
}
+// LinkSetMulticastOn enables the reception of multicast packets for the link device.
+// Equivalent to: `ip link set $link multicast on`
+func LinkSetMulticastOn(link Link) error {
+ return pkgHandle.LinkSetMulticastOn(link)
+}
+
+// LinkSetMulticastOn enables the reception of multicast packets for the link device.
+// Equivalent to: `ip link set $link multicast on`
+func (h *Handle) LinkSetMulticastOn(link Link) error {
+ base := link.Attrs()
+ h.ensureIndex(base)
+ req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK)
+
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
+ msg.Change = unix.IFF_MULTICAST
+ msg.Flags = unix.IFF_MULTICAST
+ msg.Index = int32(base.Index)
+ req.AddData(msg)
+
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0)
+ return err
+}
+
+// LinkSetAllmulticastOff disables the reception of multicast packets for the link device.
+// Equivalent to: `ip link set $link multicast off`
+func LinkSetMulticastOff(link Link) error {
+ return pkgHandle.LinkSetMulticastOff(link)
+}
+
+// LinkSetAllmulticastOff disables the reception of multicast packets for the link device.
+// Equivalent to: `ip link set $link multicast off`
+func (h *Handle) LinkSetMulticastOff(link Link) error {
+ base := link.Attrs()
+ h.ensureIndex(base)
+ req := h.newNetlinkRequest(unix.RTM_NEWLINK, unix.NLM_F_ACK)
+
+ msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
+ msg.Change = unix.IFF_MULTICAST
+ msg.Index = int32(base.Index)
+ req.AddData(msg)
+
+ _, err := req.Execute(unix.NETLINK_ROUTE, 0)
+ return err
+}
+
func MacvlanMACAddrAdd(link Link, addr net.HardwareAddr) error {
return pkgHandle.MacvlanMACAddrAdd(link, addr)
}
@@ -547,13 +589,13 @@ func (h *Handle) LinkSetVfVlanQos(link Link, vf, vlan, qos int) error {
req.AddData(msg)
data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil)
- info := nl.NewRtAttrChild(data, nl.IFLA_VF_INFO, nil)
+ info := data.AddRtAttr(nl.IFLA_VF_INFO, nil)
vfmsg := nl.VfVlan{
Vf: uint32(vf),
Vlan: uint32(vlan),
Qos: uint32(qos),
}
- nl.NewRtAttrChild(info, nl.IFLA_VF_VLAN, vfmsg.Serialize())
+ info.AddRtAttr(nl.IFLA_VF_VLAN, vfmsg.Serialize())
req.AddData(data)
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
@@ -1104,6 +1146,10 @@ func (h *Handle) LinkAdd(link Link) error {
return h.linkModify(link, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)
}
+func LinkModify(link Link) error {
+ return pkgHandle.LinkModify(link)
+}
+
func (h *Handle) LinkModify(link Link) error {
return h.linkModify(link, unix.NLM_F_REQUEST|unix.NLM_F_ACK)
}
@@ -1218,9 +1264,26 @@ func (h *Handle) linkModify(link Link, flags int) error {
}
+ control := func(file *os.File, f func(fd uintptr)) error {
+ name := file.Name()
+ conn, err := file.SyscallConn()
+ if err != nil {
+ return fmt.Errorf("SyscallConn() failed on %s: %v", name, err)
+ }
+ if err := conn.Control(f); err != nil {
+ return fmt.Errorf("Failed to get file descriptor for %s: %v", name, err)
+ }
+ return nil
+ }
+
// only persist interface if NonPersist is NOT set
if !tuntap.NonPersist {
- _, _, errno := unix.Syscall(unix.SYS_IOCTL, fds[0].Fd(), uintptr(unix.TUNSETPERSIST), 1)
+ var errno syscall.Errno
+ if err := control(fds[0], func(fd uintptr) {
+ _, _, errno = unix.Syscall(unix.SYS_IOCTL, fd, uintptr(unix.TUNSETPERSIST), 1)
+ }); err != nil {
+ return err
+ }
if errno != 0 {
cleanupFds(fds)
return fmt.Errorf("Tuntap IOCTL TUNSETPERSIST failed, errno %v", errno)
@@ -1237,7 +1300,10 @@ func (h *Handle) linkModify(link Link, flags int) error {
// un-persist (e.g. allow the interface to be removed) the tuntap
// should not hurt if not set prior, condition might be not needed
if !tuntap.NonPersist {
- _, _, _ = unix.Syscall(unix.SYS_IOCTL, fds[0].Fd(), uintptr(unix.TUNSETPERSIST), 0)
+ // ignore error
+ _ = control(fds[0], func(fd uintptr) {
+ _, _, _ = unix.Syscall(unix.SYS_IOCTL, fd, uintptr(unix.TUNSETPERSIST), 0)
+ })
}
cleanupFds(fds)
return err
@@ -1409,6 +1475,10 @@ func (h *Handle) linkModify(link Link, flags int) error {
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
data.AddRtAttr(nl.IFLA_IPVLAN_MODE, nl.Uint16Attr(uint16(link.Mode)))
data.AddRtAttr(nl.IFLA_IPVLAN_FLAG, nl.Uint16Attr(uint16(link.Flag)))
+ case *IPVtap:
+ data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
+ data.AddRtAttr(nl.IFLA_IPVLAN_MODE, nl.Uint16Attr(uint16(link.Mode)))
+ data.AddRtAttr(nl.IFLA_IPVLAN_FLAG, nl.Uint16Attr(uint16(link.Flag)))
case *Macvlan:
if link.Mode != MACVLAN_MODE_DEFAULT {
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
@@ -1443,6 +1513,8 @@ func (h *Handle) linkModify(link Link, flags int) error {
addXfrmiAttrs(link, linkInfo)
case *IPoIB:
addIPoIBAttrs(link, linkInfo)
+ case *BareUDP:
+ addBareUDPAttrs(link, linkInfo)
}
req.AddData(linkInfo)
@@ -1624,7 +1696,7 @@ func execGetLink(req *nl.NetlinkRequest) (Link, error) {
}
}
-// linkDeserialize deserializes a raw message received from netlink into
+// LinkDeserialize deserializes a raw message received from netlink into
// a link object.
func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
msg := nl.DeserializeIfInfomsg(m)
@@ -1639,9 +1711,17 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
base.RawFlags = msg.Flags
base.Flags = linkFlags(msg.Flags)
base.EncapType = msg.EncapType()
+ base.NetNsID = -1
if msg.Flags&unix.IFF_PROMISC != 0 {
base.Promisc = 1
}
+ if msg.Flags&unix.IFF_ALLMULTI != 0 {
+ base.Allmulti = 1
+ }
+ if msg.Flags&unix.IFF_MULTICAST != 0 {
+ base.Multi = 1
+ }
+
var (
link Link
stats32 *LinkStatistics32
@@ -1680,6 +1760,8 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
link = &Bond{}
case "ipvlan":
link = &IPVlan{}
+ case "ipvtap":
+ link = &IPVtap{}
case "macvlan":
link = &Macvlan{}
case "macvtap":
@@ -1714,6 +1796,8 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
link = &IPoIB{}
case "can":
link = &Can{}
+ case "bareudp":
+ link = &BareUDP{}
default:
link = &GenericLink{LinkType: linkType}
}
@@ -1731,6 +1815,8 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
parseBondData(link, data)
case "ipvlan":
parseIPVlanData(link, data)
+ case "ipvtap":
+ parseIPVtapData(link, data)
case "macvlan":
parseMacvlanData(link, data)
case "macvtap":
@@ -1767,13 +1853,19 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
parseIPoIBData(link, data)
case "can":
parseCanData(link, data)
+ case "bareudp":
+ parseBareUDPData(link, data)
}
+
case nl.IFLA_INFO_SLAVE_KIND:
slaveType = string(info.Value[:len(info.Value)-1])
switch slaveType {
case "bond":
linkSlave = &BondSlave{}
+ case "vrf":
+ linkSlave = &VrfSlave{}
}
+
case nl.IFLA_INFO_SLAVE_DATA:
switch slaveType {
case "bond":
@@ -1782,6 +1874,12 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
return nil, err
}
parseBondSlaveData(linkSlave, data)
+ case "vrf":
+ data, err := nl.ParseRouteAttr(info.Value)
+ if err != nil {
+ return nil, err
+ }
+ parseVrfSlaveData(linkSlave, data)
}
}
}
@@ -1835,6 +1933,8 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
}
case unix.IFLA_OPERSTATE:
base.OperState = LinkOperState(uint8(attr.Value[0]))
+ case unix.IFLA_PHYS_SWITCH_ID:
+ base.PhysSwitchID = int(native.Uint32(attr.Value[0:4]))
case unix.IFLA_LINK_NETNSID:
base.NetNsID = int(native.Uint32(attr.Value[0:4]))
case unix.IFLA_GSO_MAX_SIZE:
@@ -2023,7 +2123,8 @@ func linkSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-c
msgs, from, err := s.Receive()
if err != nil {
if cberr != nil {
- cberr(err)
+ cberr(fmt.Errorf("Receive failed: %v",
+ err))
}
return
}
@@ -2038,15 +2139,15 @@ func linkSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-c
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))
+ cberr(fmt.Errorf("error message: %v",
+ syscall.Errno(-error)))
}
- return
+ continue
}
ifmsg := nl.DeserializeIfInfomsg(m.Data)
header := unix.NlMsghdr(m.Header)
@@ -2055,7 +2156,7 @@ func linkSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-c
if cberr != nil {
cberr(err)
}
- return
+ continue
}
ch <- LinkUpdate{IfInfomsg: *ifmsg, Header: header, Link: link}
}
@@ -2404,6 +2505,16 @@ func parseBondSlaveData(slave LinkSlave, data []syscall.NetlinkRouteAttr) {
}
}
+func parseVrfSlaveData(slave LinkSlave, data []syscall.NetlinkRouteAttr) {
+ vrfSlave := slave.(*VrfSlave)
+ for i := range data {
+ switch data[i].Attr.Type {
+ case nl.IFLA_BOND_SLAVE_STATE:
+ vrfSlave.Table = native.Uint32(data[i].Value[0:4])
+ }
+ }
+}
+
func parseIPVlanData(link Link, data []syscall.NetlinkRouteAttr) {
ipv := link.(*IPVlan)
for _, datum := range data {
@@ -2416,6 +2527,18 @@ func parseIPVlanData(link Link, data []syscall.NetlinkRouteAttr) {
}
}
+func parseIPVtapData(link Link, data []syscall.NetlinkRouteAttr) {
+ ipv := link.(*IPVtap)
+ for _, datum := range data {
+ switch datum.Attr.Type {
+ case nl.IFLA_IPVLAN_MODE:
+ ipv.Mode = IPVlanMode(native.Uint32(datum.Value[0:4]))
+ case nl.IFLA_IPVLAN_FLAG:
+ ipv.Flag = IPVlanFlag(native.Uint32(datum.Value[0:4]))
+ }
+ }
+}
+
func parseMacvtapData(link Link, data []syscall.NetlinkRouteAttr) {
macv := link.(*Macvtap)
parseMacvlanData(&macv.Macvlan, data)
@@ -2756,6 +2879,10 @@ func addIptunAttrs(iptun *Iptun, linkInfo *nl.RtAttr) {
func parseIptunData(link Link, data []syscall.NetlinkRouteAttr) {
iptun := link.(*Iptun)
for _, datum := range data {
+ // NOTE: same with vxlan, ip tunnel may also has null datum.Value
+ if len(datum.Value) == 0 {
+ continue
+ }
switch datum.Attr.Type {
case nl.IFLA_IPTUN_LOCAL:
iptun.Local = net.IP(datum.Value[0:4])
@@ -3303,3 +3430,32 @@ func addIPoIBAttrs(ipoib *IPoIB, linkInfo *nl.RtAttr) {
data.AddRtAttr(nl.IFLA_IPOIB_MODE, nl.Uint16Attr(uint16(ipoib.Mode)))
data.AddRtAttr(nl.IFLA_IPOIB_UMCAST, nl.Uint16Attr(uint16(ipoib.Umcast)))
}
+
+func addBareUDPAttrs(bareudp *BareUDP, linkInfo *nl.RtAttr) {
+ data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
+
+ data.AddRtAttr(nl.IFLA_BAREUDP_PORT, nl.Uint16Attr(nl.Swap16(bareudp.Port)))
+ data.AddRtAttr(nl.IFLA_BAREUDP_ETHERTYPE, nl.Uint16Attr(nl.Swap16(bareudp.EtherType)))
+ if bareudp.SrcPortMin != 0 {
+ data.AddRtAttr(nl.IFLA_BAREUDP_SRCPORT_MIN, nl.Uint16Attr(bareudp.SrcPortMin))
+ }
+ if bareudp.MultiProto {
+ data.AddRtAttr(nl.IFLA_BAREUDP_MULTIPROTO_MODE, []byte{})
+ }
+}
+
+func parseBareUDPData(link Link, data []syscall.NetlinkRouteAttr) {
+ bareudp := link.(*BareUDP)
+ for _, attr := range data {
+ switch attr.Attr.Type {
+ case nl.IFLA_BAREUDP_PORT:
+ bareudp.Port = binary.BigEndian.Uint16(attr.Value)
+ case nl.IFLA_BAREUDP_ETHERTYPE:
+ bareudp.EtherType = binary.BigEndian.Uint16(attr.Value)
+ case nl.IFLA_BAREUDP_SRCPORT_MIN:
+ bareudp.SrcPortMin = native.Uint16(attr.Value)
+ case nl.IFLA_BAREUDP_MULTIPROTO_MODE:
+ bareudp.MultiProto = true
+ }
+ }
+}
diff --git a/vendor/github.com/vishvananda/netlink/neigh.go b/vendor/github.com/vishvananda/netlink/neigh.go
index 379e5655f..32d722e88 100644
--- a/vendor/github.com/vishvananda/netlink/neigh.go
+++ b/vendor/github.com/vishvananda/netlink/neigh.go
@@ -12,6 +12,7 @@ type Neigh struct {
State int
Type int
Flags int
+ FlagsExt int
IP net.IP
HardwareAddr net.HardwareAddr
LLIPAddr net.IP //Used in the case of NHRP
diff --git a/vendor/github.com/vishvananda/netlink/neigh_linux.go b/vendor/github.com/vishvananda/netlink/neigh_linux.go
index fb220d141..4c1e76635 100644
--- a/vendor/github.com/vishvananda/netlink/neigh_linux.go
+++ b/vendor/github.com/vishvananda/netlink/neigh_linux.go
@@ -24,7 +24,11 @@ const (
NDA_MASTER
NDA_LINK_NETNSID
NDA_SRC_VNI
- NDA_MAX = NDA_SRC_VNI
+ NDA_PROTOCOL
+ NDA_NH_ID
+ NDA_FDB_EXT_ATTRS
+ NDA_FLAGS_EXT
+ NDA_MAX = NDA_FLAGS_EXT
)
// Neighbor Cache Entry States.
@@ -42,11 +46,19 @@ const (
// Neighbor Flags
const (
- NTF_USE = 0x01
- NTF_SELF = 0x02
- NTF_MASTER = 0x04
- NTF_PROXY = 0x08
- NTF_ROUTER = 0x80
+ NTF_USE = 0x01
+ NTF_SELF = 0x02
+ NTF_MASTER = 0x04
+ NTF_PROXY = 0x08
+ NTF_EXT_LEARNED = 0x10
+ NTF_OFFLOADED = 0x20
+ NTF_STICKY = 0x40
+ NTF_ROUTER = 0x80
+)
+
+// Extended Neighbor Flags
+const (
+ NTF_EXT_MANAGED = 0x00000001
)
// Ndmsg is for adding, removing or receiving information about a neighbor table entry
@@ -162,11 +174,16 @@ func neighHandle(neigh *Neigh, req *nl.NetlinkRequest) error {
if neigh.LLIPAddr != nil {
llIPData := nl.NewRtAttr(NDA_LLADDR, neigh.LLIPAddr.To4())
req.AddData(llIPData)
- } else if neigh.Flags != NTF_PROXY || neigh.HardwareAddr != nil {
+ } else if neigh.HardwareAddr != nil {
hwData := nl.NewRtAttr(NDA_LLADDR, []byte(neigh.HardwareAddr))
req.AddData(hwData)
}
+ if neigh.FlagsExt != 0 {
+ flagsExtData := nl.NewRtAttr(NDA_FLAGS_EXT, nl.Uint32Attr(uint32(neigh.FlagsExt)))
+ req.AddData(flagsExtData)
+ }
+
if neigh.Vlan != 0 {
vlanData := nl.NewRtAttr(NDA_VLAN, nl.Uint16Attr(uint16(neigh.Vlan)))
req.AddData(vlanData)
@@ -305,6 +322,8 @@ func NeighDeserialize(m []byte) (*Neigh, error) {
} else {
neigh.HardwareAddr = net.HardwareAddr(attr.Value)
}
+ case NDA_FLAGS_EXT:
+ neigh.FlagsExt = int(native.Uint32(attr.Value[0:4]))
case NDA_VLAN:
neigh.Vlan = int(native.Uint16(attr.Value[0:2]))
case NDA_VNI:
@@ -408,7 +427,6 @@ func neighSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- NeighUpdate, done <
continue
}
if m.Header.Type == unix.NLMSG_ERROR {
- native := nl.NativeEndian()
error := int32(native.Uint32(m.Data[0:4]))
if error == 0 {
continue
diff --git a/vendor/github.com/vishvananda/netlink/netlink_unspecified.go b/vendor/github.com/vishvananda/netlink/netlink_unspecified.go
index 71436f25c..98d2c0dbf 100644
--- a/vendor/github.com/vishvananda/netlink/netlink_unspecified.go
+++ b/vendor/github.com/vishvananda/netlink/netlink_unspecified.go
@@ -180,14 +180,30 @@ func RouteAdd(route *Route) error {
return ErrNotImplemented
}
+func RouteAppend(route *Route) error {
+ return ErrNotImplemented
+}
+
func RouteDel(route *Route) error {
return ErrNotImplemented
}
+func RouteGet(destination net.IP) ([]Route, error) {
+ return nil, ErrNotImplemented
+}
+
func RouteList(link Link, family int) ([]Route, error) {
return nil, ErrNotImplemented
}
+func RouteListFiltered(family int, filter *Route, filterMask uint64) ([]Route, error) {
+ return nil, ErrNotImplemented
+}
+
+func RouteReplace(route *Route) error {
+ return ErrNotImplemented
+}
+
func XfrmPolicyAdd(policy *XfrmPolicy) error {
return ErrNotImplemented
}
diff --git a/vendor/github.com/vishvananda/netlink/netns_linux.go b/vendor/github.com/vishvananda/netlink/netns_linux.go
index 77cf6f469..2eb29c7ce 100644
--- a/vendor/github.com/vishvananda/netlink/netns_linux.go
+++ b/vendor/github.com/vishvananda/netlink/netns_linux.go
@@ -87,7 +87,7 @@ func (h *Handle) getNetNsId(attrType int, val uint32) (int, error) {
rtgen := nl.NewRtGenMsg()
req.AddData(rtgen)
- b := make([]byte, 4, 4)
+ b := make([]byte, 4)
native.PutUint32(b, val)
attr := nl.NewRtAttr(attrType, b)
req.AddData(attr)
@@ -126,12 +126,12 @@ func (h *Handle) setNetNsId(attrType int, val uint32, newnsid uint32) error {
rtgen := nl.NewRtGenMsg()
req.AddData(rtgen)
- b := make([]byte, 4, 4)
+ b := make([]byte, 4)
native.PutUint32(b, val)
attr := nl.NewRtAttr(attrType, b)
req.AddData(attr)
- b1 := make([]byte, 4, 4)
+ b1 := make([]byte, 4)
native.PutUint32(b1, newnsid)
attr1 := nl.NewRtAttr(NETNSA_NSID, b1)
req.AddData(attr1)
diff --git a/vendor/github.com/vishvananda/netlink/nl/conntrack_linux.go b/vendor/github.com/vishvananda/netlink/nl/conntrack_linux.go
index 14924027e..183601803 100644
--- a/vendor/github.com/vishvananda/netlink/nl/conntrack_linux.go
+++ b/vendor/github.com/vishvananda/netlink/nl/conntrack_linux.go
@@ -44,6 +44,7 @@ const (
NLA_F_NESTED uint16 = (1 << 15) // #define NLA_F_NESTED (1 << 15)
NLA_F_NET_BYTEORDER uint16 = (1 << 14) // #define NLA_F_NESTED (1 << 14)
NLA_TYPE_MASK = ^(NLA_F_NESTED | NLA_F_NET_BYTEORDER)
+ NLA_ALIGNTO uint16 = 4 // #define NLA_ALIGNTO 4
)
// enum ctattr_type {
diff --git a/vendor/github.com/vishvananda/netlink/nl/devlink_linux.go b/vendor/github.com/vishvananda/netlink/nl/devlink_linux.go
index aa6155e21..2995da492 100644
--- a/vendor/github.com/vishvananda/netlink/nl/devlink_linux.go
+++ b/vendor/github.com/vishvananda/netlink/nl/devlink_linux.go
@@ -11,22 +11,37 @@ const (
const (
DEVLINK_CMD_GET = 1
DEVLINK_CMD_PORT_GET = 5
+ DEVLINK_CMD_PORT_SET = 6
+ DEVLINK_CMD_PORT_NEW = 7
+ DEVLINK_CMD_PORT_DEL = 8
DEVLINK_CMD_ESWITCH_GET = 29
DEVLINK_CMD_ESWITCH_SET = 30
+ DEVLINK_CMD_INFO_GET = 51
)
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
+ 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
+ DEVLINK_ATTR_INFO_DRIVER_NAME = 98
+ DEVLINK_ATTR_INFO_SERIAL_NUMBER = 99
+ DEVLINK_ATTR_INFO_VERSION_FIXED = 100
+ DEVLINK_ATTR_INFO_VERSION_RUNNING = 101
+ DEVLINK_ATTR_INFO_VERSION_STORED = 102
+ DEVLINK_ATTR_INFO_VERSION_NAME = 103
+ DEVLINK_ATTR_INFO_VERSION_VALUE = 104
+ DEVLINK_ATTR_PORT_PCI_PF_NUMBER = 127
+ DEVLINK_ATTR_PORT_FUNCTION = 145
+ DEVLINK_ATTR_PORT_CONTROLLER_NUMBER = 150
+ DEVLINK_ATTR_PORT_PCI_SF_NUMBER = 164
)
const (
@@ -53,6 +68,8 @@ const (
DEVLINK_PORT_FLAVOUR_PCI_PF = 3
DEVLINK_PORT_FLAVOUR_PCI_VF = 4
DEVLINK_PORT_FLAVOUR_VIRTUAL = 5
+ DEVLINK_PORT_FLAVOUR_UNUSED = 6
+ DEVLINK_PORT_FLAVOUR_PCI_SF = 7
)
const (
@@ -61,3 +78,19 @@ const (
DEVLINK_PORT_TYPE_ETH = 2
DEVLINK_PORT_TYPE_IB = 3
)
+
+const (
+ DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR = 1
+ DEVLINK_PORT_FN_ATTR_STATE = 2
+ DEVLINK_PORT_FN_ATTR_OPSTATE = 3
+)
+
+const (
+ DEVLINK_PORT_FN_STATE_INACTIVE = 0
+ DEVLINK_PORT_FN_STATE_ACTIVE = 1
+)
+
+const (
+ DEVLINK_PORT_FN_OPSTATE_DETACHED = 0
+ DEVLINK_PORT_FN_OPSTATE_ATTACHED = 1
+)
diff --git a/vendor/github.com/vishvananda/netlink/nl/link_linux.go b/vendor/github.com/vishvananda/netlink/nl/link_linux.go
index c72cc436e..e10edbc09 100644
--- a/vendor/github.com/vishvananda/netlink/nl/link_linux.go
+++ b/vendor/github.com/vishvananda/netlink/nl/link_linux.go
@@ -709,3 +709,12 @@ const (
IFLA_CAN_BITRATE_MAX
IFLA_CAN_MAX = IFLA_CAN_BITRATE_MAX
)
+
+const (
+ IFLA_BAREUDP_UNSPEC = iota
+ IFLA_BAREUDP_PORT
+ IFLA_BAREUDP_ETHERTYPE
+ IFLA_BAREUDP_SRCPORT_MIN
+ IFLA_BAREUDP_MULTIPROTO_MODE
+ IFLA_BAREUDP_MAX = IFLA_BAREUDP_MULTIPROTO_MODE
+)
diff --git a/vendor/github.com/vishvananda/netlink/nl/lwt_linux.go b/vendor/github.com/vishvananda/netlink/nl/lwt_linux.go
new file mode 100644
index 000000000..bafd593c4
--- /dev/null
+++ b/vendor/github.com/vishvananda/netlink/nl/lwt_linux.go
@@ -0,0 +1,29 @@
+package nl
+
+const (
+ LWT_BPF_PROG_UNSPEC = iota
+ LWT_BPF_PROG_FD
+ LWT_BPF_PROG_NAME
+ __LWT_BPF_PROG_MAX
+)
+
+const (
+ LWT_BPF_PROG_MAX = __LWT_BPF_PROG_MAX - 1
+)
+
+const (
+ LWT_BPF_UNSPEC = iota
+ LWT_BPF_IN
+ LWT_BPF_OUT
+ LWT_BPF_XMIT
+ LWT_BPF_XMIT_HEADROOM
+ __LWT_BPF_MAX
+)
+
+const (
+ LWT_BPF_MAX = __LWT_BPF_MAX - 1
+)
+
+const (
+ LWT_BPF_MAX_HEADROOM = 256
+)
diff --git a/vendor/github.com/vishvananda/netlink/nl/nl_linux.go b/vendor/github.com/vishvananda/netlink/nl/nl_linux.go
index dcd4b9469..a49f67570 100644
--- a/vendor/github.com/vishvananda/netlink/nl/nl_linux.go
+++ b/vendor/github.com/vishvananda/netlink/nl/nl_linux.go
@@ -27,7 +27,8 @@ const (
// tc rules or filters, or other more memory requiring data.
RECEIVE_BUFFER_SIZE = 65536
// Kernel netlink pid
- PidKernel uint32 = 0
+ PidKernel uint32 = 0
+ SizeofCnMsgOp = 0x18
)
// SupportedNlFamilies contains the list of netlink families this netlink package supports
@@ -85,6 +86,56 @@ type NetlinkRequestData interface {
Serialize() []byte
}
+const (
+ PROC_CN_MCAST_LISTEN = 1
+ PROC_CN_MCAST_IGNORE
+)
+
+type CbID struct {
+ Idx uint32
+ Val uint32
+}
+
+type CnMsg struct {
+ ID CbID
+ Seq uint32
+ Ack uint32
+ Length uint16
+ Flags uint16
+}
+
+type CnMsgOp struct {
+ CnMsg
+ // here we differ from the C header
+ Op uint32
+}
+
+func NewCnMsg(idx, val, op uint32) *CnMsgOp {
+ var cm CnMsgOp
+
+ cm.ID.Idx = idx
+ cm.ID.Val = val
+
+ cm.Ack = 0
+ cm.Seq = 1
+ cm.Length = uint16(binary.Size(op))
+ cm.Op = op
+
+ return &cm
+}
+
+func (msg *CnMsgOp) Serialize() []byte {
+ return (*(*[SizeofCnMsgOp]byte)(unsafe.Pointer(msg)))[:]
+}
+
+func DeserializeCnMsgOp(b []byte) *CnMsgOp {
+ return (*CnMsgOp)(unsafe.Pointer(&b[0:SizeofCnMsgOp][0]))
+}
+
+func (msg *CnMsgOp) Len() int {
+ return SizeofCnMsgOp
+}
+
// IfInfomsg is related to links, but it is used for list requests as well
type IfInfomsg struct {
unix.IfInfomsg
diff --git a/vendor/github.com/vishvananda/netlink/nl/rdma_link_linux.go b/vendor/github.com/vishvananda/netlink/nl/rdma_link_linux.go
index 1224b747d..ce43ee155 100644
--- a/vendor/github.com/vishvananda/netlink/nl/rdma_link_linux.go
+++ b/vendor/github.com/vishvananda/netlink/nl/rdma_link_linux.go
@@ -11,6 +11,8 @@ const (
const (
RDMA_NLDEV_CMD_GET = 1
RDMA_NLDEV_CMD_SET = 2
+ RDMA_NLDEV_CMD_NEWLINK = 3
+ RDMA_NLDEV_CMD_DELLINK = 4
RDMA_NLDEV_CMD_SYS_GET = 6
RDMA_NLDEV_CMD_SYS_SET = 7
)
@@ -30,6 +32,8 @@ const (
RDMA_NLDEV_ATTR_PORT_STATE = 12
RDMA_NLDEV_ATTR_PORT_PHYS_STATE = 13
RDMA_NLDEV_ATTR_DEV_NODE_TYPE = 14
+ RDMA_NLDEV_ATTR_NDEV_NAME = 51
+ RDMA_NLDEV_ATTR_LINK_TYPE = 65
RDMA_NLDEV_SYS_ATTR_NETNS_MODE = 66
RDMA_NLDEV_NET_NS_FD = 68
)
diff --git a/vendor/github.com/vishvananda/netlink/nl/seg6_linux.go b/vendor/github.com/vishvananda/netlink/nl/seg6_linux.go
index 5774cbb15..fe88285f2 100644
--- a/vendor/github.com/vishvananda/netlink/nl/seg6_linux.go
+++ b/vendor/github.com/vishvananda/netlink/nl/seg6_linux.go
@@ -23,7 +23,7 @@ func (s1 *IPv6SrHdr) Equal(s2 IPv6SrHdr) bool {
return false
}
for i := range s1.Segments {
- if s1.Segments[i].Equal(s2.Segments[i]) != true {
+ if !s1.Segments[i].Equal(s2.Segments[i]) {
return false
}
}
@@ -89,7 +89,7 @@ func DecodeSEG6Encap(buf []byte) (int, []net.IP, error) {
}
buf = buf[12:]
if len(buf)%16 != 0 {
- err := fmt.Errorf("DecodeSEG6Encap: error parsing Segment List (buf len: %d)\n", len(buf))
+ err := fmt.Errorf("DecodeSEG6Encap: error parsing Segment List (buf len: %d)", len(buf))
return mode, nil, err
}
for len(buf) > 0 {
diff --git a/vendor/github.com/vishvananda/netlink/nl/syscall.go b/vendor/github.com/vishvananda/netlink/nl/syscall.go
index 4a01e6e59..bdf6ba639 100644
--- a/vendor/github.com/vishvananda/netlink/nl/syscall.go
+++ b/vendor/github.com/vishvananda/netlink/nl/syscall.go
@@ -1,6 +1,6 @@
package nl
-// syscall package lack of rule atributes type.
+// syscall package lack of rule attributes type.
// Thus there are defined below
const (
FRA_UNSPEC = iota
diff --git a/vendor/github.com/vishvananda/netlink/nl/tc_linux.go b/vendor/github.com/vishvananda/netlink/nl/tc_linux.go
index c24d53eb7..002beda92 100644
--- a/vendor/github.com/vishvananda/netlink/nl/tc_linux.go
+++ b/vendor/github.com/vishvananda/netlink/nl/tc_linux.go
@@ -882,6 +882,111 @@ const (
TCA_HFSC_USC
)
+const (
+ TCA_FLOWER_UNSPEC = iota
+ TCA_FLOWER_CLASSID
+ TCA_FLOWER_INDEV
+ TCA_FLOWER_ACT
+ TCA_FLOWER_KEY_ETH_DST /* ETH_ALEN */
+ TCA_FLOWER_KEY_ETH_DST_MASK /* ETH_ALEN */
+ TCA_FLOWER_KEY_ETH_SRC /* ETH_ALEN */
+ TCA_FLOWER_KEY_ETH_SRC_MASK /* ETH_ALEN */
+ TCA_FLOWER_KEY_ETH_TYPE /* be16 */
+ TCA_FLOWER_KEY_IP_PROTO /* u8 */
+ TCA_FLOWER_KEY_IPV4_SRC /* be32 */
+ TCA_FLOWER_KEY_IPV4_SRC_MASK /* be32 */
+ TCA_FLOWER_KEY_IPV4_DST /* be32 */
+ TCA_FLOWER_KEY_IPV4_DST_MASK /* be32 */
+ TCA_FLOWER_KEY_IPV6_SRC /* struct in6_addr */
+ TCA_FLOWER_KEY_IPV6_SRC_MASK /* struct in6_addr */
+ TCA_FLOWER_KEY_IPV6_DST /* struct in6_addr */
+ TCA_FLOWER_KEY_IPV6_DST_MASK /* struct in6_addr */
+ TCA_FLOWER_KEY_TCP_SRC /* be16 */
+ TCA_FLOWER_KEY_TCP_DST /* be16 */
+ TCA_FLOWER_KEY_UDP_SRC /* be16 */
+ TCA_FLOWER_KEY_UDP_DST /* be16 */
+
+ TCA_FLOWER_FLAGS
+ TCA_FLOWER_KEY_VLAN_ID /* be16 */
+ TCA_FLOWER_KEY_VLAN_PRIO /* u8 */
+ TCA_FLOWER_KEY_VLAN_ETH_TYPE /* be16 */
+
+ TCA_FLOWER_KEY_ENC_KEY_ID /* be32 */
+ TCA_FLOWER_KEY_ENC_IPV4_SRC /* be32 */
+ TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK /* be32 */
+ TCA_FLOWER_KEY_ENC_IPV4_DST /* be32 */
+ TCA_FLOWER_KEY_ENC_IPV4_DST_MASK /* be32 */
+ TCA_FLOWER_KEY_ENC_IPV6_SRC /* struct in6_addr */
+ TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK /* struct in6_addr */
+ TCA_FLOWER_KEY_ENC_IPV6_DST /* struct in6_addr */
+ TCA_FLOWER_KEY_ENC_IPV6_DST_MASK /* struct in6_addr */
+
+ TCA_FLOWER_KEY_TCP_SRC_MASK /* be16 */
+ TCA_FLOWER_KEY_TCP_DST_MASK /* be16 */
+ TCA_FLOWER_KEY_UDP_SRC_MASK /* be16 */
+ TCA_FLOWER_KEY_UDP_DST_MASK /* be16 */
+ TCA_FLOWER_KEY_SCTP_SRC_MASK /* be16 */
+ TCA_FLOWER_KEY_SCTP_DST_MASK /* be16 */
+
+ TCA_FLOWER_KEY_SCTP_SRC /* be16 */
+ TCA_FLOWER_KEY_SCTP_DST /* be16 */
+
+ TCA_FLOWER_KEY_ENC_UDP_SRC_PORT /* be16 */
+ TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK /* be16 */
+ TCA_FLOWER_KEY_ENC_UDP_DST_PORT /* be16 */
+ TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK /* be16 */
+
+ TCA_FLOWER_KEY_FLAGS /* be32 */
+ TCA_FLOWER_KEY_FLAGS_MASK /* be32 */
+
+ TCA_FLOWER_KEY_ICMPV4_CODE /* u8 */
+ TCA_FLOWER_KEY_ICMPV4_CODE_MASK /* u8 */
+ TCA_FLOWER_KEY_ICMPV4_TYPE /* u8 */
+ TCA_FLOWER_KEY_ICMPV4_TYPE_MASK /* u8 */
+ TCA_FLOWER_KEY_ICMPV6_CODE /* u8 */
+ TCA_FLOWER_KEY_ICMPV6_CODE_MASK /* u8 */
+ TCA_FLOWER_KEY_ICMPV6_TYPE /* u8 */
+ TCA_FLOWER_KEY_ICMPV6_TYPE_MASK /* u8 */
+
+ TCA_FLOWER_KEY_ARP_SIP /* be32 */
+ TCA_FLOWER_KEY_ARP_SIP_MASK /* be32 */
+ TCA_FLOWER_KEY_ARP_TIP /* be32 */
+ TCA_FLOWER_KEY_ARP_TIP_MASK /* be32 */
+ TCA_FLOWER_KEY_ARP_OP /* u8 */
+ TCA_FLOWER_KEY_ARP_OP_MASK /* u8 */
+ TCA_FLOWER_KEY_ARP_SHA /* ETH_ALEN */
+ TCA_FLOWER_KEY_ARP_SHA_MASK /* ETH_ALEN */
+ TCA_FLOWER_KEY_ARP_THA /* ETH_ALEN */
+ TCA_FLOWER_KEY_ARP_THA_MASK /* ETH_ALEN */
+
+ TCA_FLOWER_KEY_MPLS_TTL /* u8 - 8 bits */
+ TCA_FLOWER_KEY_MPLS_BOS /* u8 - 1 bit */
+ TCA_FLOWER_KEY_MPLS_TC /* u8 - 3 bits */
+ TCA_FLOWER_KEY_MPLS_LABEL /* be32 - 20 bits */
+
+ TCA_FLOWER_KEY_TCP_FLAGS /* be16 */
+ TCA_FLOWER_KEY_TCP_FLAGS_MASK /* be16 */
+
+ TCA_FLOWER_KEY_IP_TOS /* u8 */
+ TCA_FLOWER_KEY_IP_TOS_MASK /* u8 */
+ TCA_FLOWER_KEY_IP_TTL /* u8 */
+ TCA_FLOWER_KEY_IP_TTL_MASK /* u8 */
+
+ TCA_FLOWER_KEY_CVLAN_ID /* be16 */
+ TCA_FLOWER_KEY_CVLAN_PRIO /* u8 */
+ TCA_FLOWER_KEY_CVLAN_ETH_TYPE /* be16 */
+
+ TCA_FLOWER_KEY_ENC_IP_TOS /* u8 */
+ TCA_FLOWER_KEY_ENC_IP_TOS_MASK /* u8 */
+ TCA_FLOWER_KEY_ENC_IP_TTL /* u8 */
+ TCA_FLOWER_KEY_ENC_IP_TTL_MASK /* u8 */
+
+ TCA_FLOWER_KEY_ENC_OPTS
+ TCA_FLOWER_KEY_ENC_OPTS_MASK
+
+ __TCA_FLOWER_MAX
+)
+
// struct tc_sfq_qopt {
// unsigned quantum; /* Bytes per round allocated to flow */
// int perturb_period; /* Period of hash perturbation */
diff --git a/vendor/github.com/vishvananda/netlink/proc_event.go b/vendor/github.com/vishvananda/netlink/proc_event.go
new file mode 100644
index 000000000..53bc59a6e
--- /dev/null
+++ b/vendor/github.com/vishvananda/netlink/proc_event.go
@@ -0,0 +1,217 @@
+package netlink
+
+import (
+ "bytes"
+ "encoding/binary"
+ "fmt"
+ "os"
+ "syscall"
+
+ "github.com/vishvananda/netlink/nl"
+ "github.com/vishvananda/netns"
+ "golang.org/x/sys/unix"
+)
+
+const CN_IDX_PROC = 0x1
+
+const (
+ PROC_EVENT_NONE = 0x00000000
+ PROC_EVENT_FORK = 0x00000001
+ PROC_EVENT_EXEC = 0x00000002
+ PROC_EVENT_UID = 0x00000004
+ PROC_EVENT_GID = 0x00000040
+ PROC_EVENT_SID = 0x00000080
+ PROC_EVENT_PTRACE = 0x00000100
+ PROC_EVENT_COMM = 0x00000200
+ PROC_EVENT_COREDUMP = 0x40000000
+ PROC_EVENT_EXIT = 0x80000000
+)
+
+const (
+ CN_VAL_PROC = 0x1
+ PROC_CN_MCAST_LISTEN = 0x1
+)
+
+type ProcEventMsg interface {
+ Pid() uint32
+ Tgid() uint32
+}
+
+type ProcEventHeader struct {
+ What uint32
+ CPU uint32
+ Timestamp uint64
+}
+
+type ProcEvent struct {
+ ProcEventHeader
+ Msg ProcEventMsg
+}
+
+func (pe *ProcEvent) setHeader(h ProcEventHeader) {
+ pe.What = h.What
+ pe.CPU = h.CPU
+ pe.Timestamp = h.Timestamp
+}
+
+type ExitProcEvent struct {
+ ProcessPid uint32
+ ProcessTgid uint32
+ ExitCode uint32
+ ExitSignal uint32
+ ParentPid uint32
+ ParentTgid uint32
+}
+
+type ExitProcEvent2 struct {
+ ProcessPid uint32
+ ProcessTgid uint32
+ ExitCode uint32
+ ExitSignal uint32
+ ParentPid uint32
+ ParentTgid uint32
+}
+
+func (e *ExitProcEvent) Pid() uint32 {
+ return e.ProcessPid
+}
+
+func (e *ExitProcEvent) Tgid() uint32 {
+ return e.ProcessTgid
+}
+
+type ExecProcEvent struct {
+ ProcessPid uint32
+ ProcessTgid uint32
+}
+
+func (e *ExecProcEvent) Pid() uint32 {
+ return e.ProcessPid
+}
+
+func (e *ExecProcEvent) Tgid() uint32 {
+ return e.ProcessTgid
+}
+
+type ForkProcEvent struct {
+ ParentPid uint32
+ ParentTgid uint32
+ ChildPid uint32
+ ChildTgid uint32
+}
+
+func (e *ForkProcEvent) Pid() uint32 {
+ return e.ParentPid
+}
+
+func (e *ForkProcEvent) Tgid() uint32 {
+ return e.ParentTgid
+}
+
+type CommProcEvent struct {
+ ProcessPid uint32
+ ProcessTgid uint32
+ Comm [16]byte
+}
+
+func (e *CommProcEvent) Pid() uint32 {
+ return e.ProcessPid
+}
+
+func (e *CommProcEvent) Tgid() uint32 {
+ return e.ProcessTgid
+}
+
+func ProcEventMonitor(ch chan<- ProcEvent, done <-chan struct{}, errorChan chan<- error) error {
+ h, err := NewHandle()
+ if err != nil {
+ return err
+ }
+ defer h.Delete()
+
+ s, err := nl.SubscribeAt(netns.None(), netns.None(), unix.NETLINK_CONNECTOR, CN_IDX_PROC)
+ if err != nil {
+ return err
+ }
+
+ var nlmsg nl.NetlinkRequest
+
+ nlmsg.Pid = uint32(os.Getpid())
+ nlmsg.Type = unix.NLMSG_DONE
+ nlmsg.Len = uint32(unix.SizeofNlMsghdr)
+
+ cm := nl.NewCnMsg(CN_IDX_PROC, CN_VAL_PROC, PROC_CN_MCAST_LISTEN)
+ nlmsg.AddData(cm)
+
+ s.Send(&nlmsg)
+
+ if done != nil {
+ go func() {
+ <-done
+ s.Close()
+ }()
+ }
+
+ go func() {
+ defer close(ch)
+ for {
+ msgs, from, err := s.Receive()
+ if err != nil {
+ errorChan <- err
+ return
+ }
+ if from.Pid != nl.PidKernel {
+ errorChan <- fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel)
+ return
+ }
+
+ for _, m := range msgs {
+ e := parseNetlinkMessage(m)
+ if e != nil {
+ ch <- *e
+ }
+ }
+
+ }
+ }()
+
+ return nil
+}
+
+func parseNetlinkMessage(m syscall.NetlinkMessage) *ProcEvent {
+ if m.Header.Type == unix.NLMSG_DONE {
+ buf := bytes.NewBuffer(m.Data)
+ msg := &nl.CnMsg{}
+ hdr := &ProcEventHeader{}
+ binary.Read(buf, nl.NativeEndian(), msg)
+ binary.Read(buf, nl.NativeEndian(), hdr)
+
+ pe := &ProcEvent{}
+ pe.setHeader(*hdr)
+ switch hdr.What {
+ case PROC_EVENT_EXIT:
+ event := &ExitProcEvent{}
+ binary.Read(buf, nl.NativeEndian(), event)
+ pe.Msg = event
+ return pe
+ case PROC_EVENT_FORK:
+ event := &ForkProcEvent{}
+ binary.Read(buf, nl.NativeEndian(), event)
+ pe.Msg = event
+ return pe
+ case PROC_EVENT_EXEC:
+ event := &ExecProcEvent{}
+ binary.Read(buf, nl.NativeEndian(), event)
+ pe.Msg = event
+ return pe
+ case PROC_EVENT_COMM:
+ event := &CommProcEvent{}
+ binary.Read(buf, nl.NativeEndian(), event)
+ pe.Msg = event
+ return pe
+ }
+ return nil
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/vishvananda/netlink/qdisc_linux.go b/vendor/github.com/vishvananda/netlink/qdisc_linux.go
index edc4b726a..e182e1cfe 100644
--- a/vendor/github.com/vishvananda/netlink/qdisc_linux.go
+++ b/vendor/github.com/vishvananda/netlink/qdisc_linux.go
@@ -468,7 +468,6 @@ func parsePrioData(qdisc Qdisc, value []byte) error {
}
func parseHtbData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
- native = nl.NativeEndian()
htb := qdisc.(*Htb)
for _, datum := range data {
switch datum.Attr.Type {
@@ -488,7 +487,6 @@ func parseHtbData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
}
func parseFqCodelData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
- native = nl.NativeEndian()
fqCodel := qdisc.(*FqCodel)
for _, datum := range data {
@@ -518,13 +516,11 @@ func parseFqCodelData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
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)
for _, datum := range data {
switch datum.Attr.Type {
@@ -589,7 +585,6 @@ func parseNetemData(qdisc Qdisc, value []byte) error {
}
func parseTbfData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
- native = nl.NativeEndian()
tbf := qdisc.(*Tbf)
for _, datum := range data {
switch datum.Attr.Type {
@@ -711,3 +706,7 @@ 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))))
}
+
+func Xmitsize(rate uint64, ticks uint32) uint32 {
+ return uint32((float64(rate) * float64(tick2Time(ticks))) / TIME_UNITS_PER_SEC)
+}
diff --git a/vendor/github.com/vishvananda/netlink/rdma_link_linux.go b/vendor/github.com/vishvananda/netlink/rdma_link_linux.go
index ff014ca4c..036399db6 100644
--- a/vendor/github.com/vishvananda/netlink/rdma_link_linux.go
+++ b/vendor/github.com/vishvananda/netlink/rdma_link_linux.go
@@ -278,3 +278,54 @@ func (h *Handle) RdmaLinkSetNsFd(link *RdmaLink, fd uint32) error {
return execRdmaSetLink(req)
}
+
+// RdmaLinkDel deletes an rdma link
+//
+// Similar to: rdma link delete NAME
+// REF: https://man7.org/linux/man-pages/man8/rdma-link.8.html
+func RdmaLinkDel(name string) error {
+ return pkgHandle.RdmaLinkDel(name)
+}
+
+// RdmaLinkDel deletes an rdma link.
+func (h *Handle) RdmaLinkDel(name string) error {
+ link, err := h.RdmaLinkByName(name)
+ if err != nil {
+ return err
+ }
+
+ proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_DELLINK)
+ req := h.newNetlinkRequest(proto, unix.NLM_F_ACK)
+
+ b := make([]byte, 4)
+ native.PutUint32(b, link.Attrs.Index)
+ req.AddData(nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_DEV_INDEX, b))
+
+ _, err = req.Execute(unix.NETLINK_RDMA, 0)
+ return err
+}
+
+// RdmaLinkAdd adds an rdma link for the specified type to the network device.
+// Similar to: rdma link add NAME type TYPE netdev NETDEV
+// NAME - specifies the new name of the rdma link to add
+// TYPE - specifies which rdma type to use. Link types:
+// rxe - Soft RoCE driver
+// siw - Soft iWARP driver
+// NETDEV - specifies the network device to which the link is bound
+//
+// REF: https://man7.org/linux/man-pages/man8/rdma-link.8.html
+func RdmaLinkAdd(linkName, linkType, netdev string) error {
+ return pkgHandle.RdmaLinkAdd(linkName, linkType, netdev)
+}
+
+// RdmaLinkAdd adds an rdma link for the specified type to the network device.
+func (h *Handle) RdmaLinkAdd(linkName string, linkType string, netdev string) error {
+ proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_NEWLINK)
+ req := h.newNetlinkRequest(proto, unix.NLM_F_ACK)
+
+ req.AddData(nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_DEV_NAME, nl.ZeroTerminated(linkName)))
+ req.AddData(nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_LINK_TYPE, nl.ZeroTerminated(linkType)))
+ req.AddData(nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_NDEV_NAME, nl.ZeroTerminated(netdev)))
+ _, err := req.Execute(unix.NETLINK_RDMA, 0)
+ return err
+}
diff --git a/vendor/github.com/vishvananda/netlink/route.go b/vendor/github.com/vishvananda/netlink/route.go
index 845f41808..ffad5d398 100644
--- a/vendor/github.com/vishvananda/netlink/route.go
+++ b/vendor/github.com/vishvananda/netlink/route.go
@@ -41,6 +41,7 @@ type Route struct {
MultiPath []*NexthopInfo
Protocol RouteProtocol
Priority int
+ Family int
Table int
Type int
Tos int
@@ -49,6 +50,7 @@ type Route struct {
NewDst Destination
Encap Encap
Via Destination
+ Realm int
MTU int
Window int
Rtt int
@@ -94,6 +96,7 @@ func (r Route) String() string {
}
elems = append(elems, fmt.Sprintf("Flags: %s", r.ListFlags()))
elems = append(elems, fmt.Sprintf("Table: %d", r.Table))
+ elems = append(elems, fmt.Sprintf("Realm: %d", r.Realm))
return fmt.Sprintf("{%s}", strings.Join(elems, " "))
}
@@ -107,6 +110,7 @@ func (r Route) Equal(x Route) bool {
nexthopInfoSlice(r.MultiPath).Equal(x.MultiPath) &&
r.Protocol == x.Protocol &&
r.Priority == x.Priority &&
+ r.Realm == x.Realm &&
r.Table == x.Table &&
r.Type == x.Type &&
r.Tos == x.Tos &&
diff --git a/vendor/github.com/vishvananda/netlink/route_linux.go b/vendor/github.com/vishvananda/netlink/route_linux.go
index 32641cb0d..b059d4a9e 100644
--- a/vendor/github.com/vishvananda/netlink/route_linux.go
+++ b/vendor/github.com/vishvananda/netlink/route_linux.go
@@ -56,6 +56,7 @@ const (
RT_FILTER_PRIORITY
RT_FILTER_MARK
RT_FILTER_MASK
+ RT_FILTER_REALM
)
const (
@@ -151,7 +152,6 @@ func (e *MPLSEncap) Decode(buf []byte) error {
if len(buf) < 4 {
return fmt.Errorf("lack of bytes")
}
- native := nl.NativeEndian()
l := native.Uint16(buf)
if len(buf) < int(l) {
return fmt.Errorf("lack of bytes")
@@ -167,7 +167,6 @@ func (e *MPLSEncap) Decode(buf []byte) error {
func (e *MPLSEncap) Encode() ([]byte, error) {
s := nl.EncodeMPLSStack(e.Labels...)
- native := nl.NativeEndian()
hdr := make([]byte, 4)
native.PutUint16(hdr, uint16(len(s)+4))
native.PutUint16(hdr[2:], nl.MPLS_IPTUNNEL_DST)
@@ -223,7 +222,6 @@ func (e *SEG6Encap) Decode(buf []byte) error {
if len(buf) < 4 {
return fmt.Errorf("lack of bytes")
}
- native := nl.NativeEndian()
// Get Length(l) & Type(typ) : 2 + 2 bytes
l := native.Uint16(buf)
if len(buf) < int(l) {
@@ -243,7 +241,6 @@ func (e *SEG6Encap) Decode(buf []byte) error {
}
func (e *SEG6Encap) Encode() ([]byte, error) {
s, err := nl.EncodeSEG6Encap(e.Mode, e.Segments)
- native := nl.NativeEndian()
hdr := make([]byte, 4)
native.PutUint16(hdr, uint16(len(s)+4))
native.PutUint16(hdr[2:], nl.SEG6_IPTUNNEL_SRH)
@@ -253,7 +250,7 @@ func (e *SEG6Encap) String() string {
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]))
+ segs = append(segs, e.Segments[i-1].String())
}
str := fmt.Sprintf("mode %s segs %d [ %s ]", nl.SEG6EncapModeString(e.Mode),
len(e.Segments), strings.Join(segs, " "))
@@ -304,7 +301,6 @@ func (e *SEG6LocalEncap) Decode(buf []byte) error {
if err != nil {
return err
}
- native := nl.NativeEndian()
for _, attr := range attrs {
switch attr.Attr.Type {
case nl.SEG6_LOCAL_ACTION:
@@ -334,7 +330,6 @@ func (e *SEG6LocalEncap) Decode(buf []byte) error {
}
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)
@@ -425,7 +420,7 @@ func (e *SEG6LocalEncap) String() string {
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]))
+ segs = append(segs, e.Segments[i-1].String())
}
strs = append(strs, fmt.Sprintf("segs %d [ %s ]", len(e.Segments), strings.Join(segs, " ")))
}
@@ -466,6 +461,152 @@ func (e *SEG6LocalEncap) Equal(x Encap) bool {
return true
}
+// Encap BPF definitions
+type bpfObj struct {
+ progFd int
+ progName string
+}
+type BpfEncap struct {
+ progs [nl.LWT_BPF_MAX]bpfObj
+ headroom int
+}
+
+// SetProg adds a bpf function to the route via netlink RTA_ENCAP. The fd must be a bpf
+// program loaded with bpf(type=BPF_PROG_TYPE_LWT_*) matching the direction the program should
+// be applied to (LWT_BPF_IN, LWT_BPF_OUT, LWT_BPF_XMIT).
+func (e *BpfEncap) SetProg(mode, progFd int, progName string) error {
+ if progFd <= 0 {
+ return fmt.Errorf("lwt bpf SetProg: invalid fd")
+ }
+ if mode <= nl.LWT_BPF_UNSPEC || mode >= nl.LWT_BPF_XMIT_HEADROOM {
+ return fmt.Errorf("lwt bpf SetProg:invalid mode")
+ }
+ e.progs[mode].progFd = progFd
+ e.progs[mode].progName = fmt.Sprintf("%s[fd:%d]", progName, progFd)
+ return nil
+}
+
+// SetXmitHeadroom sets the xmit headroom (LWT_BPF_MAX_HEADROOM) via netlink RTA_ENCAP.
+// maximum headroom is LWT_BPF_MAX_HEADROOM
+func (e *BpfEncap) SetXmitHeadroom(headroom int) error {
+ if headroom > nl.LWT_BPF_MAX_HEADROOM || headroom < 0 {
+ return fmt.Errorf("invalid headroom size. range is 0 - %d", nl.LWT_BPF_MAX_HEADROOM)
+ }
+ e.headroom = headroom
+ return nil
+}
+
+func (e *BpfEncap) Type() int {
+ return nl.LWTUNNEL_ENCAP_BPF
+}
+func (e *BpfEncap) Decode(buf []byte) error {
+ if len(buf) < 4 {
+ return fmt.Errorf("lwt bpf decode: lack of bytes")
+ }
+ native := nl.NativeEndian()
+ attrs, err := nl.ParseRouteAttr(buf)
+ if err != nil {
+ return fmt.Errorf("lwt bpf decode: failed parsing attribute. err: %v", err)
+ }
+ for _, attr := range attrs {
+ if int(attr.Attr.Type) < 1 {
+ // nl.LWT_BPF_UNSPEC
+ continue
+ }
+ if int(attr.Attr.Type) > nl.LWT_BPF_MAX {
+ return fmt.Errorf("lwt bpf decode: received unknown attribute type: %d", attr.Attr.Type)
+ }
+ switch int(attr.Attr.Type) {
+ case nl.LWT_BPF_MAX_HEADROOM:
+ e.headroom = int(native.Uint32(attr.Value))
+ default:
+ bpfO := bpfObj{}
+ parsedAttrs, err := nl.ParseRouteAttr(attr.Value)
+ if err != nil {
+ return fmt.Errorf("lwt bpf decode: failed parsing route attribute")
+ }
+ for _, parsedAttr := range parsedAttrs {
+ switch int(parsedAttr.Attr.Type) {
+ case nl.LWT_BPF_PROG_FD:
+ bpfO.progFd = int(native.Uint32(parsedAttr.Value))
+ case nl.LWT_BPF_PROG_NAME:
+ bpfO.progName = string(parsedAttr.Value)
+ default:
+ return fmt.Errorf("lwt bpf decode: received unknown attribute: type: %d, len: %d", parsedAttr.Attr.Type, parsedAttr.Attr.Len)
+ }
+ }
+ e.progs[attr.Attr.Type] = bpfO
+ }
+ }
+ return nil
+}
+
+func (e *BpfEncap) Encode() ([]byte, error) {
+ buf := make([]byte, 0)
+ native = nl.NativeEndian()
+ for index, attr := range e.progs {
+ nlMsg := nl.NewRtAttr(index, []byte{})
+ if attr.progFd != 0 {
+ nlMsg.AddRtAttr(nl.LWT_BPF_PROG_FD, nl.Uint32Attr(uint32(attr.progFd)))
+ }
+ if attr.progName != "" {
+ nlMsg.AddRtAttr(nl.LWT_BPF_PROG_NAME, nl.ZeroTerminated(attr.progName))
+ }
+ if nlMsg.Len() > 4 {
+ buf = append(buf, nlMsg.Serialize()...)
+ }
+ }
+ if len(buf) <= 4 {
+ return nil, fmt.Errorf("lwt bpf encode: bpf obj definitions returned empty buffer")
+ }
+ if e.headroom > 0 {
+ hRoom := nl.NewRtAttr(nl.LWT_BPF_XMIT_HEADROOM, nl.Uint32Attr(uint32(e.headroom)))
+ buf = append(buf, hRoom.Serialize()...)
+ }
+ return buf, nil
+}
+
+func (e *BpfEncap) String() string {
+ progs := make([]string, 0)
+ for index, obj := range e.progs {
+ empty := bpfObj{}
+ switch index {
+ case nl.LWT_BPF_IN:
+ if obj != empty {
+ progs = append(progs, fmt.Sprintf("in: %s", obj.progName))
+ }
+ case nl.LWT_BPF_OUT:
+ if obj != empty {
+ progs = append(progs, fmt.Sprintf("out: %s", obj.progName))
+ }
+ case nl.LWT_BPF_XMIT:
+ if obj != empty {
+ progs = append(progs, fmt.Sprintf("xmit: %s", obj.progName))
+ }
+ }
+ }
+ if e.headroom > 0 {
+ progs = append(progs, fmt.Sprintf("xmit headroom: %d", e.headroom))
+ }
+ return strings.Join(progs, " ")
+}
+
+func (e *BpfEncap) Equal(x Encap) bool {
+ o, ok := x.(*BpfEncap)
+ if !ok {
+ return false
+ }
+ if e.headroom != o.headroom {
+ return false
+ }
+ for i := range o.progs {
+ if o.progs[i] != e.progs[i] {
+ return false
+ }
+ }
+ return true
+}
+
type Via struct {
AddrFamily int
Addr net.IP
@@ -504,7 +645,6 @@ func (v *Via) Encode() ([]byte, error) {
}
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))
}
@@ -552,14 +692,14 @@ func (h *Handle) RouteAppend(route *Route) error {
// RouteAddEcmp will add a route to the system.
func RouteAddEcmp(route *Route) error {
- return pkgHandle.RouteAddEcmp(route)
+ 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())
+ 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.
@@ -635,7 +775,13 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
if err != nil {
return err
}
- rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_ENCAP, buf))
+ switch route.Encap.Type() {
+ case nl.LWTUNNEL_ENCAP_BPF:
+ rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_ENCAP|unix.NLA_F_NESTED, buf))
+ default:
+ rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_ENCAP, buf))
+ }
+
}
if route.Src != nil {
@@ -748,6 +894,11 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
native.PutUint32(b, uint32(route.Priority))
rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_PRIORITY, b))
}
+ if route.Realm > 0 {
+ b := make([]byte, 4)
+ native.PutUint32(b, uint32(route.Realm))
+ rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_FLOW, b))
+ }
if route.Tos > 0 {
msg.Tos = uint8(route.Tos)
}
@@ -840,10 +991,7 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
req.AddData(attr)
}
- var (
- b = make([]byte, 4)
- native = nl.NativeEndian()
- )
+ b := make([]byte, 4)
native.PutUint32(b, uint32(route.LinkIndex))
req.AddData(nl.NewRtAttr(unix.RTA_OIF, b))
@@ -919,6 +1067,8 @@ func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64)
continue
case filterMask&RT_FILTER_TOS != 0 && route.Tos != filter.Tos:
continue
+ case filterMask&RT_FILTER_REALM != 0 && route.Realm != filter.Realm:
+ continue
case filterMask&RT_FILTER_OIF != 0 && route.LinkIndex != filter.LinkIndex:
continue
case filterMask&RT_FILTER_IIF != 0 && route.ILinkIndex != filter.ILinkIndex:
@@ -956,9 +1106,9 @@ func deserializeRoute(m []byte) (Route, error) {
Type: int(msg.Type),
Tos: int(msg.Tos),
Flags: int(msg.Flags),
+ Family: int(msg.Family),
}
- native := nl.NativeEndian()
var encap, encapType syscall.NetlinkRouteAttr
for _, attr := range attrs {
switch attr.Attr.Type {
@@ -985,6 +1135,8 @@ func deserializeRoute(m []byte) (Route, error) {
route.ILinkIndex = int(native.Uint32(attr.Value[0:4]))
case unix.RTA_PRIORITY:
route.Priority = int(native.Uint32(attr.Value[0:4]))
+ case unix.RTA_FLOW:
+ route.Realm = int(native.Uint32(attr.Value[0:4]))
case unix.RTA_TABLE:
route.Table = int(native.Uint32(attr.Value[0:4]))
case unix.RTA_MULTIPATH:
@@ -1140,6 +1292,11 @@ func deserializeRoute(m []byte) (Route, error) {
if err := e.Decode(encap.Value); err != nil {
return route, err
}
+ case nl.LWTUNNEL_ENCAP_BPF:
+ e = &BpfEncap{}
+ if err := e.Decode(encap.Value); err != nil {
+ return route, err
+ }
}
route.Encap = e
}
@@ -1150,6 +1307,8 @@ func deserializeRoute(m []byte) (Route, error) {
// RouteGetOptions contains a set of options to use with
// RouteGetWithOptions
type RouteGetOptions struct {
+ Iif string
+ Oif string
VrfName string
SrcAddr net.IP
}
@@ -1198,10 +1357,31 @@ func (h *Handle) RouteGetWithOptions(destination net.IP, options *RouteGetOption
if err != nil {
return nil, err
}
- var (
- b = make([]byte, 4)
- native = nl.NativeEndian()
- )
+ b := make([]byte, 4)
+ native.PutUint32(b, uint32(link.Attrs().Index))
+
+ req.AddData(nl.NewRtAttr(unix.RTA_OIF, b))
+ }
+
+ if len(options.Iif) > 0 {
+ link, err := LinkByName(options.Iif)
+ if err != nil {
+ return nil, err
+ }
+
+ b := make([]byte, 4)
+ native.PutUint32(b, uint32(link.Attrs().Index))
+
+ req.AddData(nl.NewRtAttr(unix.RTA_IIF, b))
+ }
+
+ if len(options.Oif) > 0 {
+ link, err := LinkByName(options.Oif)
+ if err != nil {
+ return nil, err
+ }
+
+ b := make([]byte, 4)
native.PutUint32(b, uint32(link.Attrs().Index))
req.AddData(nl.NewRtAttr(unix.RTA_OIF, b))
@@ -1298,7 +1478,8 @@ func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <
msgs, from, err := s.Receive()
if err != nil {
if cberr != nil {
- cberr(err)
+ cberr(fmt.Errorf("Receive failed: %v",
+ err))
}
return
}
@@ -1313,22 +1494,22 @@ func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <
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))
+ cberr(fmt.Errorf("error message: %v",
+ syscall.Errno(-error)))
}
- return
+ continue
}
route, err := deserializeRoute(m.Data)
if err != nil {
if cberr != nil {
cberr(err)
}
- return
+ continue
}
ch <- RouteUpdate{Type: m.Header.Type, Route: route}
}
diff --git a/vendor/github.com/vishvananda/netlink/rule.go b/vendor/github.com/vishvananda/netlink/rule.go
index 95f2facfb..9b7b0af49 100644
--- a/vendor/github.com/vishvananda/netlink/rule.go
+++ b/vendor/github.com/vishvananda/netlink/rule.go
@@ -28,7 +28,18 @@ type Rule struct {
}
func (r Rule) String() string {
- return fmt.Sprintf("ip rule %d: from %s table %d", r.Priority, r.Src, r.Table)
+ from := "all"
+ if r.Src != nil && r.Src.String() != "<nil>" {
+ from = r.Src.String()
+ }
+
+ to := "all"
+ if r.Dst != nil && r.Dst.String() != "<nil>" {
+ to = r.Dst.String()
+ }
+
+ return fmt.Sprintf("ip rule %d: from %s to %s table %d",
+ r.Priority, from, to, r.Table)
}
// NewRule return empty rules.
diff --git a/vendor/github.com/vishvananda/netlink/rule_linux.go b/vendor/github.com/vishvananda/netlink/rule_linux.go
index 40474f30e..9c426cbd3 100644
--- a/vendor/github.com/vishvananda/netlink/rule_linux.go
+++ b/vendor/github.com/vishvananda/netlink/rule_linux.go
@@ -97,8 +97,6 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
req.AddData(rtAttrs[i])
}
- native := nl.NativeEndian()
-
if rule.Priority >= 0 {
b := make([]byte, 4)
native.PutUint32(b, uint32(rule.Priority))
@@ -199,7 +197,6 @@ func (h *Handle) RuleListFiltered(family int, filter *Rule, filterMask uint64) (
return nil, err
}
- native := nl.NativeEndian()
var res = make([]Rule, 0)
for i := range msgs {
msg := nl.DeserializeRtMsg(msgs[i])
@@ -232,7 +229,7 @@ func (h *Handle) RuleListFiltered(family int, filter *Rule, filterMask uint64) (
case nl.FRA_FWMASK:
rule.Mask = int(native.Uint32(attrs[j].Value[0:4]))
case nl.FRA_TUN_ID:
- rule.TunID = uint(native.Uint64(attrs[j].Value[0:4]))
+ rule.TunID = uint(native.Uint64(attrs[j].Value[0:8]))
case nl.FRA_IIFNAME:
rule.IifName = string(attrs[j].Value[:len(attrs[j].Value)-1])
case nl.FRA_OIFNAME:
diff --git a/vendor/github.com/vishvananda/netlink/socket_linux.go b/vendor/github.com/vishvananda/netlink/socket_linux.go
index 9b0f4a081..b881fe496 100644
--- a/vendor/github.com/vishvananda/netlink/socket_linux.go
+++ b/vendor/github.com/vishvananda/netlink/socket_linux.go
@@ -172,12 +172,56 @@ func SocketGet(local, remote net.Addr) (*Socket, error) {
return sock, nil
}
-// SocketDiagTCPInfo requests INET_DIAG_INFO for TCP protocol for specified family type.
+// SocketDiagTCPInfo requests INET_DIAG_INFO for TCP protocol for specified family type and return with extension TCP info.
func SocketDiagTCPInfo(family uint8) ([]*InetDiagTCPInfoResp, error) {
- s, err := nl.Subscribe(unix.NETLINK_INET_DIAG)
+ var result []*InetDiagTCPInfoResp
+ err := socketDiagTCPExecutor(family, func(m syscall.NetlinkMessage) error {
+ sockInfo := &Socket{}
+ if err := sockInfo.deserialize(m.Data); err != nil {
+ return err
+ }
+ attrs, err := nl.ParseRouteAttr(m.Data[sizeofSocket:])
+ if err != nil {
+ return err
+ }
+
+ res, err := attrsToInetDiagTCPInfoResp(attrs, sockInfo)
+ if err != nil {
+ return err
+ }
+
+ result = append(result, res)
+ return nil
+ })
+ if err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
+// SocketDiagTCP requests INET_DIAG_INFO for TCP protocol for specified family type and return related socket.
+func SocketDiagTCP(family uint8) ([]*Socket, error) {
+ var result []*Socket
+ err := socketDiagTCPExecutor(family, func(m syscall.NetlinkMessage) error {
+ sockInfo := &Socket{}
+ if err := sockInfo.deserialize(m.Data); err != nil {
+ return err
+ }
+ result = append(result, sockInfo)
+ return nil
+ })
if err != nil {
return nil, err
}
+ return result, nil
+}
+
+// socketDiagTCPExecutor requests INET_DIAG_INFO for TCP protocol for specified family type.
+func socketDiagTCPExecutor(family uint8, receiver func(syscall.NetlinkMessage) error) error {
+ s, err := nl.Subscribe(unix.NETLINK_INET_DIAG)
+ if err != nil {
+ return err
+ }
defer s.Close()
req := nl.NewNetlinkRequest(nl.SOCK_DIAG_BY_FAMILY, unix.NLM_F_DUMP)
@@ -189,18 +233,17 @@ func SocketDiagTCPInfo(family uint8) ([]*InetDiagTCPInfoResp, error) {
})
s.Send(req)
- var result []*InetDiagTCPInfoResp
loop:
for {
msgs, from, err := s.Receive()
if err != nil {
- return nil, err
+ return err
}
if from.Pid != nl.PidKernel {
- return nil, fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel)
+ return 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")
+ return errors.New("no message nor error from netlink")
}
for _, m := range msgs {
@@ -208,28 +251,15 @@ loop:
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)
+ return syscall.Errno(-error)
}
- sockInfo := &Socket{}
- if err := sockInfo.deserialize(m.Data); err != nil {
- return nil, err
+ if err := receiver(m); err != nil {
+ return 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
+ return nil
}
func attrsToInetDiagTCPInfoResp(attrs []syscall.NetlinkRouteAttr, sockInfo *Socket) (*InetDiagTCPInfoResp, error) {
diff --git a/vendor/github.com/vishvananda/netlink/xfrm_state_linux.go b/vendor/github.com/vishvananda/netlink/xfrm_state_linux.go
index 5b1b6c31a..3b37b87d3 100644
--- a/vendor/github.com/vishvananda/netlink/xfrm_state_linux.go
+++ b/vendor/github.com/vishvananda/netlink/xfrm_state_linux.go
@@ -111,7 +111,7 @@ func (h *Handle) xfrmStateAddOrUpdate(state *XfrmState, nlProto int) error {
// A state with spi 0 can't be deleted so don't allow it to be set
if state.Spi == 0 {
- return fmt.Errorf("Spi must be set when adding xfrm state.")
+ return fmt.Errorf("Spi must be set when adding xfrm state")
}
req := h.newNetlinkRequest(nlProto, unix.NLM_F_CREATE|unix.NLM_F_EXCL|unix.NLM_F_ACK)