From a5748206d198057e1cc0c09a1179ec0c6d819ebc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 May 2025 21:52:54 +0000 Subject: [PATCH] fix(deps): update module github.com/vishvananda/netlink to v1.3.1 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 +- .../vishvananda/netlink/bridge_linux.go | 185 +++++++++++++-- .../vishvananda/netlink/filter_linux.go | 66 ++++-- .../vishvananda/netlink/ipset_linux.go | 113 +++++++-- vendor/github.com/vishvananda/netlink/link.go | 22 +- .../vishvananda/netlink/link_linux.go | 145 +++++++++++- .../vishvananda/netlink/nl/bridge_linux.go | 13 ++ .../vishvananda/netlink/nl/link_linux.go | 14 ++ .../vishvananda/netlink/nl/rdma_link_linux.go | 58 +++-- .../vishvananda/netlink/nl/tc_linux.go | 17 +- .../vishvananda/netlink/protinfo.go | 4 + .../vishvananda/netlink/protinfo_linux.go | 3 + .../github.com/vishvananda/netlink/qdisc.go | 6 +- .../vishvananda/netlink/qdisc_linux.go | 4 +- .../vishvananda/netlink/rdma_link_linux.go | 215 ++++++++++++++++++ vendor/modules.txt | 2 +- 17 files changed, 773 insertions(+), 100 deletions(-) diff --git a/go.mod b/go.mod index 1301070a0d..b644f98a9b 100644 --- a/go.mod +++ b/go.mod @@ -66,7 +66,7 @@ require ( github.com/spf13/pflag v1.0.6 github.com/stretchr/testify v1.10.0 github.com/vbauerster/mpb/v8 v8.10.0 - github.com/vishvananda/netlink v1.3.1-0.20250425193846-9d88d8385bf9 + github.com/vishvananda/netlink v1.3.1 go.etcd.io/bbolt v1.4.0 golang.org/x/crypto v0.38.0 golang.org/x/net v0.40.0 diff --git a/go.sum b/go.sum index 14f5b58aaa..f32b3275be 100644 --- a/go.sum +++ b/go.sum @@ -482,8 +482,8 @@ github.com/vbatts/tar-split v0.12.1 h1:CqKoORW7BUWBe7UL/iqTVvkTBOF8UvOMKOIZykxnn github.com/vbatts/tar-split v0.12.1/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA= github.com/vbauerster/mpb/v8 v8.10.0 h1:5ZYEWM4ovaZGAibjzW4PlQNb5k+JpzMqVwgNyk+K0M8= github.com/vbauerster/mpb/v8 v8.10.0/go.mod h1:DYPFebxSahB+f7tuEUGauLQ7w8ij3wMr4clsVuJCV4I= -github.com/vishvananda/netlink v1.3.1-0.20250425193846-9d88d8385bf9 h1:ZEjCI2kamoTYIx348/Nfco4c4NPvpq972DM2HMgnBgI= -github.com/vishvananda/netlink v1.3.1-0.20250425193846-9d88d8385bf9/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4= +github.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0= +github.com/vishvananda/netlink v1.3.1/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4= github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY= github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= diff --git a/vendor/github.com/vishvananda/netlink/bridge_linux.go b/vendor/github.com/vishvananda/netlink/bridge_linux.go index fa5766b801..ec941e5c78 100644 --- a/vendor/github.com/vishvananda/netlink/bridge_linux.go +++ b/vendor/github.com/vishvananda/netlink/bridge_linux.go @@ -3,11 +3,102 @@ package netlink import ( "errors" "fmt" + "syscall" "github.com/vishvananda/netlink/nl" "golang.org/x/sys/unix" ) +// BridgeVlanTunnelShow gets vlanid-tunnelid mapping. +// Equivalent to: `bridge vlan tunnelshow` +// +// If the returned error is [ErrDumpInterrupted], results may be inconsistent +// or incomplete. +func BridgeVlanTunnelShow() ([]nl.TunnelInfo, error) { + return pkgHandle.BridgeVlanTunnelShow() +} + +func (h *Handle) BridgeVlanTunnelShow() ([]nl.TunnelInfo, error) { + req := h.newNetlinkRequest(unix.RTM_GETLINK, unix.NLM_F_DUMP) + msg := nl.NewIfInfomsg(unix.AF_BRIDGE) + req.AddData(msg) + req.AddData(nl.NewRtAttr(unix.IFLA_EXT_MASK, nl.Uint32Attr(uint32(nl.RTEXT_FILTER_BRVLAN)))) + + msgs, executeErr := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWLINK) + if executeErr != nil && !errors.Is(executeErr, ErrDumpInterrupted) { + return nil, executeErr + } + ret := make([]nl.TunnelInfo, 0) + for _, m := range msgs { + msg := nl.DeserializeIfInfomsg(m) + + attrs, err := nl.ParseRouteAttr(m[msg.Len():]) + if err != nil { + return nil, err + } + for _, attr := range attrs { + switch attr.Attr.Type { + case unix.IFLA_AF_SPEC: + nestedAttrs, err := nl.ParseRouteAttr(attr.Value) + if err != nil { + return nil, fmt.Errorf("failed to parse nested attr %v", err) + } + for _, nestAttr := range nestedAttrs { + switch nestAttr.Attr.Type { + case nl.IFLA_BRIDGE_VLAN_TUNNEL_INFO: + ret, err = parseTunnelInfo(&nestAttr, ret) + if err != nil { + return nil, fmt.Errorf("failed to parse tunnelinfo %v", err) + } + } + } + } + } + } + return ret, executeErr +} + +func parseTunnelInfo(nestAttr *syscall.NetlinkRouteAttr, results []nl.TunnelInfo) ([]nl.TunnelInfo, error) { + tunnelInfos, err := nl.ParseRouteAttr(nestAttr.Value) + if err != nil { + return nil, fmt.Errorf("failed to parse nested attr %v", err) + } + var tunnelId uint32 + var vid uint16 + var flag uint16 + for _, tunnelInfo := range tunnelInfos { + switch tunnelInfo.Attr.Type { + case nl.IFLA_BRIDGE_VLAN_TUNNEL_ID: + tunnelId = native.Uint32(tunnelInfo.Value) + case nl.IFLA_BRIDGE_VLAN_TUNNEL_VID: + vid = native.Uint16(tunnelInfo.Value) + case nl.IFLA_BRIDGE_VLAN_TUNNEL_FLAGS: + flag = native.Uint16(tunnelInfo.Value) + } + } + + if flag == nl.BRIDGE_VLAN_INFO_RANGE_END { + lastTi := results[len(results)-1] + vni := lastTi.TunId + 1 + for i := lastTi.Vid + 1; i < vid; i++ { + t := nl.TunnelInfo{ + TunId: vni, + Vid: i, + } + results = append(results, t) + vni++ + } + } + + t := nl.TunnelInfo{ + TunId: tunnelId, + Vid: vid, + } + + results = append(results, t) + return results, nil +} + // BridgeVlanList gets a map of device id to bridge vlan infos. // Equivalent to: `bridge vlan show` // @@ -61,6 +152,38 @@ func (h *Handle) BridgeVlanList() (map[int32][]*nl.BridgeVlanInfo, error) { return ret, executeErr } +// BridgeVlanAddTunnelInfo adds a new vlan filter entry +// Equivalent to: `bridge vlan add dev DEV vid VID tunnel_info id TUNID [ self ] [ master ]` +func BridgeVlanAddTunnelInfo(link Link, vid uint16, tunid uint32, self, master bool) error { + return pkgHandle.BridgeVlanAddTunnelInfo(link, vid, 0, tunid, 0, self, master) +} + +// BridgeVlanAddRangeTunnelInfoRange adds a new vlan filter entry +// Equivalent to: `bridge vlan add dev DEV vid VID-VIDEND tunnel_info id VIN-VINEND [ self ] [ master ]` +func BridgeVlanAddRangeTunnelInfoRange(link Link, vid, vidEnd uint16, tunid, tunidEnd uint32, self, master bool) error { + return pkgHandle.BridgeVlanAddTunnelInfo(link, vid, vidEnd, tunid, tunidEnd, self, master) +} + +func (h *Handle) BridgeVlanAddTunnelInfo(link Link, vid, vidEnd uint16, tunid, tunidEnd uint32, self, master bool) error { + return h.bridgeVlanModify(unix.RTM_SETLINK, link, vid, vidEnd, tunid, tunidEnd, false, false, self, master) +} + +// BridgeVlanDelTunnelInfo adds a new vlan filter entry +// Equivalent to: `bridge vlan del dev DEV vid VID tunnel_info id TUNID [ self ] [ master ]` +func BridgeVlanDelTunnelInfo(link Link, vid uint16, tunid uint32, self, master bool) error { + return pkgHandle.BridgeVlanDelTunnelInfo(link, vid, 0, tunid, 0, self, master) +} + +// BridgeVlanDelRangeTunnelInfoRange adds a new vlan filter entry +// Equivalent to: `bridge vlan del dev DEV vid VID-VIDEND tunnel_info id VIN-VINEND [ self ] [ master ]` +func BridgeVlanDelRangeTunnelInfoRange(link Link, vid, vidEnd uint16, tunid, tunidEnd uint32, self, master bool) error { + return pkgHandle.BridgeVlanDelTunnelInfo(link, vid, vidEnd, tunid, tunidEnd, self, master) +} + +func (h *Handle) BridgeVlanDelTunnelInfo(link Link, vid, vidEnd uint16, tunid, tunidEnd uint32, self, master bool) error { + return h.bridgeVlanModify(unix.RTM_DELLINK, link, vid, vidEnd, tunid, tunidEnd, false, false, self, master) +} + // BridgeVlanAdd adds a new vlan filter entry // Equivalent to: `bridge vlan add dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]` func BridgeVlanAdd(link Link, vid uint16, pvid, untagged, self, master bool) error { @@ -70,7 +193,7 @@ func BridgeVlanAdd(link Link, vid uint16, pvid, untagged, self, master bool) err // BridgeVlanAdd adds a new vlan filter entry // Equivalent to: `bridge vlan add dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]` func (h *Handle) BridgeVlanAdd(link Link, vid uint16, pvid, untagged, self, master bool) error { - return h.bridgeVlanModify(unix.RTM_SETLINK, link, vid, 0, pvid, untagged, self, master) + return h.bridgeVlanModify(unix.RTM_SETLINK, link, vid, 0, 0, 0, pvid, untagged, self, master) } // BridgeVlanAddRange adds a new vlan filter entry @@ -82,7 +205,7 @@ func BridgeVlanAddRange(link Link, vid, vidEnd uint16, pvid, untagged, self, mas // BridgeVlanAddRange adds a new vlan filter entry // Equivalent to: `bridge vlan add dev DEV vid VID-VIDEND [ pvid ] [ untagged ] [ self ] [ master ]` func (h *Handle) BridgeVlanAddRange(link Link, vid, vidEnd uint16, pvid, untagged, self, master bool) error { - return h.bridgeVlanModify(unix.RTM_SETLINK, link, vid, vidEnd, pvid, untagged, self, master) + return h.bridgeVlanModify(unix.RTM_SETLINK, link, vid, vidEnd, 0, 0, pvid, untagged, self, master) } // BridgeVlanDel adds a new vlan filter entry @@ -94,7 +217,7 @@ func BridgeVlanDel(link Link, vid uint16, pvid, untagged, self, master bool) err // BridgeVlanDel adds a new vlan filter entry // Equivalent to: `bridge vlan del dev DEV vid VID [ pvid ] [ untagged ] [ self ] [ master ]` func (h *Handle) BridgeVlanDel(link Link, vid uint16, pvid, untagged, self, master bool) error { - return h.bridgeVlanModify(unix.RTM_DELLINK, link, vid, 0, pvid, untagged, self, master) + return h.bridgeVlanModify(unix.RTM_DELLINK, link, vid, 0, 0, 0, pvid, untagged, self, master) } // BridgeVlanDelRange adds a new vlan filter entry @@ -106,10 +229,10 @@ func BridgeVlanDelRange(link Link, vid, vidEnd uint16, pvid, untagged, self, mas // BridgeVlanDelRange adds a new vlan filter entry // Equivalent to: `bridge vlan del dev DEV vid VID-VIDEND [ pvid ] [ untagged ] [ self ] [ master ]` func (h *Handle) BridgeVlanDelRange(link Link, vid, vidEnd uint16, pvid, untagged, self, master bool) error { - return h.bridgeVlanModify(unix.RTM_DELLINK, link, vid, vidEnd, pvid, untagged, self, master) + return h.bridgeVlanModify(unix.RTM_DELLINK, link, vid, vidEnd, 0, 0, pvid, untagged, self, master) } -func (h *Handle) bridgeVlanModify(cmd int, link Link, vid, vidEnd uint16, pvid, untagged, self, master bool) error { +func (h *Handle) bridgeVlanModify(cmd int, link Link, vid, vidEnd uint16, tunid, tunidEnd uint32, pvid, untagged, self, master bool) error { base := link.Attrs() h.ensureIndex(base) req := h.newNetlinkRequest(cmd, unix.NLM_F_ACK) @@ -129,25 +252,45 @@ func (h *Handle) bridgeVlanModify(cmd int, link Link, vid, vidEnd uint16, pvid, if flags > 0 { br.AddRtAttr(nl.IFLA_BRIDGE_FLAGS, nl.Uint16Attr(flags)) } - vlanInfo := &nl.BridgeVlanInfo{Vid: vid} - if pvid { - vlanInfo.Flags |= nl.BRIDGE_VLAN_INFO_PVID - } - if untagged { - vlanInfo.Flags |= nl.BRIDGE_VLAN_INFO_UNTAGGED - } - if vidEnd != 0 { - vlanEndInfo := &nl.BridgeVlanInfo{Vid: vidEnd} - vlanEndInfo.Flags = vlanInfo.Flags + if tunid != 0 { + if tunidEnd != 0 { + tiStart := br.AddRtAttr(nl.IFLA_BRIDGE_VLAN_TUNNEL_INFO, nil) + tiStart.AddRtAttr(nl.IFLA_BRIDGE_VLAN_TUNNEL_ID, nl.Uint32Attr(tunid)) + tiStart.AddRtAttr(nl.IFLA_BRIDGE_VLAN_TUNNEL_VID, nl.Uint16Attr(vid)) + tiStart.AddRtAttr(nl.IFLA_BRIDGE_VLAN_TUNNEL_FLAGS, nl.Uint16Attr(nl.BRIDGE_VLAN_INFO_RANGE_BEGIN)) - vlanInfo.Flags |= nl.BRIDGE_VLAN_INFO_RANGE_BEGIN - br.AddRtAttr(nl.IFLA_BRIDGE_VLAN_INFO, vlanInfo.Serialize()) + tiEnd := br.AddRtAttr(nl.IFLA_BRIDGE_VLAN_TUNNEL_INFO, nil) + tiEnd.AddRtAttr(nl.IFLA_BRIDGE_VLAN_TUNNEL_ID, nl.Uint32Attr(tunidEnd)) + tiEnd.AddRtAttr(nl.IFLA_BRIDGE_VLAN_TUNNEL_VID, nl.Uint16Attr(vidEnd)) + tiEnd.AddRtAttr(nl.IFLA_BRIDGE_VLAN_TUNNEL_FLAGS, nl.Uint16Attr(nl.BRIDGE_VLAN_INFO_RANGE_END)) + } else { + ti := br.AddRtAttr(nl.IFLA_BRIDGE_VLAN_TUNNEL_INFO, nil) + ti.AddRtAttr(nl.IFLA_BRIDGE_VLAN_TUNNEL_ID, nl.Uint32Attr(tunid)) + ti.AddRtAttr(nl.IFLA_BRIDGE_VLAN_TUNNEL_VID, nl.Uint16Attr(vid)) + ti.AddRtAttr(nl.IFLA_BRIDGE_VLAN_TUNNEL_FLAGS, nl.Uint16Attr(0)) + } + } else { + vlanInfo := &nl.BridgeVlanInfo{Vid: vid} + if pvid { + vlanInfo.Flags |= nl.BRIDGE_VLAN_INFO_PVID + } + if untagged { + vlanInfo.Flags |= nl.BRIDGE_VLAN_INFO_UNTAGGED + } - vlanEndInfo.Flags |= nl.BRIDGE_VLAN_INFO_RANGE_END - br.AddRtAttr(nl.IFLA_BRIDGE_VLAN_INFO, vlanEndInfo.Serialize()) - } else { - br.AddRtAttr(nl.IFLA_BRIDGE_VLAN_INFO, vlanInfo.Serialize()) + if vidEnd != 0 { + vlanEndInfo := &nl.BridgeVlanInfo{Vid: vidEnd} + vlanEndInfo.Flags = vlanInfo.Flags + + vlanInfo.Flags |= nl.BRIDGE_VLAN_INFO_RANGE_BEGIN + br.AddRtAttr(nl.IFLA_BRIDGE_VLAN_INFO, vlanInfo.Serialize()) + + vlanEndInfo.Flags |= nl.BRIDGE_VLAN_INFO_RANGE_END + br.AddRtAttr(nl.IFLA_BRIDGE_VLAN_INFO, vlanEndInfo.Serialize()) + } else { + br.AddRtAttr(nl.IFLA_BRIDGE_VLAN_INFO, vlanInfo.Serialize()) + } } req.AddData(br) diff --git a/vendor/github.com/vishvananda/netlink/filter_linux.go b/vendor/github.com/vishvananda/netlink/filter_linux.go index 231b57341d..255e591d81 100644 --- a/vendor/github.com/vishvananda/netlink/filter_linux.go +++ b/vendor/github.com/vishvananda/netlink/filter_linux.go @@ -54,25 +54,30 @@ func (filter *U32) Type() string { type Flower struct { FilterAttrs - 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 - SrcMac net.HardwareAddr - DestMac net.HardwareAddr - VlanId uint16 - SkipHw bool - SkipSw bool - IPProto *nl.IPProto - DestPort uint16 - SrcPort uint16 + ClassId uint32 + 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 + SrcMac net.HardwareAddr + DestMac net.HardwareAddr + VlanId uint16 + SkipHw bool + SkipSw bool + IPProto *nl.IPProto + DestPort uint16 + SrcPort uint16 + SrcPortRangeMin uint16 + SrcPortRangeMax uint16 + DstPortRangeMin uint16 + DstPortRangeMax uint16 Actions []Action } @@ -171,6 +176,19 @@ func (filter *Flower) encode(parent *nl.RtAttr) error { } } } + if filter.SrcPortRangeMin != 0 && filter.SrcPortRangeMax != 0 { + parent.AddRtAttr(nl.TCA_FLOWER_KEY_PORT_SRC_MIN, htons(filter.SrcPortRangeMin)) + parent.AddRtAttr(nl.TCA_FLOWER_KEY_PORT_SRC_MAX, htons(filter.SrcPortRangeMax)) + } + + if filter.DstPortRangeMin != 0 && filter.DstPortRangeMax != 0 { + parent.AddRtAttr(nl.TCA_FLOWER_KEY_PORT_DST_MIN, htons(filter.DstPortRangeMin)) + parent.AddRtAttr(nl.TCA_FLOWER_KEY_PORT_DST_MAX, htons(filter.DstPortRangeMax)) + } + + if filter.ClassId != 0 { + parent.AddRtAttr(nl.TCA_FLOWER_CLASSID, nl.Uint32Attr(filter.ClassId)) + } var flags uint32 = 0 if filter.SkipHw { @@ -247,6 +265,16 @@ func (filter *Flower) decode(data []syscall.NetlinkRouteAttr) error { if skipHw != 0 { filter.SkipHw = true } + case nl.TCA_FLOWER_KEY_PORT_SRC_MIN: + filter.SrcPortRangeMin = ntohs(datum.Value) + case nl.TCA_FLOWER_KEY_PORT_SRC_MAX: + filter.SrcPortRangeMax = ntohs(datum.Value) + case nl.TCA_FLOWER_KEY_PORT_DST_MIN: + filter.DstPortRangeMin = ntohs(datum.Value) + case nl.TCA_FLOWER_KEY_PORT_DST_MAX: + filter.DstPortRangeMax = ntohs(datum.Value) + case nl.TCA_FLOWER_CLASSID: + filter.ClassId = native.Uint32(datum.Value) } } return nil diff --git a/vendor/github.com/vishvananda/netlink/ipset_linux.go b/vendor/github.com/vishvananda/netlink/ipset_linux.go index f4c05229fa..7730992ee3 100644 --- a/vendor/github.com/vishvananda/netlink/ipset_linux.go +++ b/vendor/github.com/vishvananda/netlink/ipset_linux.go @@ -147,9 +147,11 @@ 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))) + cadtFlags := optionsToBitflag(options) + revision := options.Revision if revision == 0 { - revision = getIpsetDefaultWithTypeName(typename) + revision = getIpsetDefaultRevision(typename, cadtFlags) } req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_REVISION, nl.Uint8Attr(revision))) @@ -181,18 +183,6 @@ func (h *Handle) IpsetCreate(setname, typename string, options IpsetCreateOption data.AddChild(&nl.Uint32Attribute{Type: nl.IPSET_ATTR_TIMEOUT | nl.NLA_F_NET_BYTEORDER, Value: *timeout}) } - var cadtFlags uint32 - - if options.Comments { - cadtFlags |= nl.IPSET_FLAG_WITH_COMMENT - } - if options.Counters { - cadtFlags |= nl.IPSET_FLAG_WITH_COUNTERS - } - if options.Skbinfo { - cadtFlags |= nl.IPSET_FLAG_WITH_SKBINFO - } - if cadtFlags != 0 { data.AddChild(&nl.Uint32Attribute{Type: nl.IPSET_ATTR_CADT_FLAGS | nl.NLA_F_NET_BYTEORDER, Value: cadtFlags}) } @@ -395,14 +385,89 @@ func (h *Handle) newIpsetRequest(cmd int) *nl.NetlinkRequest { return req } -func getIpsetDefaultWithTypeName(typename string) uint8 { +// NOTE: This can't just take typename into account, it also has to take desired +// feature support into account, on a per-set-type basis, to return the correct revision, see e.g. +// https://github.com/Olipro/ipset/blob/9f145b49100104d6570fe5c31a5236816ebb4f8f/kernel/net/netfilter/ipset/ip_set_hash_ipport.c#L30 +// +// This means that whenever a new "type" of ipset is added, returning the "correct" default revision +// requires adding a new case here for that type, and consulting the ipset C code to figure out the correct +// combination of type name, feature bit flags, and revision ranges. +// +// Care should be taken as some types share the same revision ranges for the same features, and others do not. +// When in doubt, mimic the C code. +func getIpsetDefaultRevision(typename string, featureFlags uint32) uint8 { switch typename { case "hash:ip,port", - "hash:ip,port,ip", - "hash:ip,port,net", + "hash:ip,port,ip": + // Taken from + // - ipset/kernel/net/netfilter/ipset/ip_set_hash_ipport.c + // - ipset/kernel/net/netfilter/ipset/ip_set_hash_ipportip.c + if (featureFlags & nl.IPSET_FLAG_WITH_SKBINFO) != 0 { + return 5 + } + + if (featureFlags & nl.IPSET_FLAG_WITH_FORCEADD) != 0 { + return 4 + } + + if (featureFlags & nl.IPSET_FLAG_WITH_COMMENT) != 0 { + return 3 + } + + if (featureFlags & nl.IPSET_FLAG_WITH_COUNTERS) != 0 { + return 2 + } + + // the min revision this library supports for this type + return 1 + + case "hash:ip,port,net", "hash:net,port": + // Taken from + // - ipset/kernel/net/netfilter/ipset/ip_set_hash_ipportnet.c + // - ipset/kernel/net/netfilter/ipset/ip_set_hash_netport.c + if (featureFlags & nl.IPSET_FLAG_WITH_SKBINFO) != 0 { + return 7 + } + + if (featureFlags & nl.IPSET_FLAG_WITH_FORCEADD) != 0 { + return 6 + } + + if (featureFlags & nl.IPSET_FLAG_WITH_COMMENT) != 0 { + return 5 + } + + if (featureFlags & nl.IPSET_FLAG_WITH_COUNTERS) != 0 { + return 4 + } + + if (featureFlags & nl.IPSET_FLAG_NOMATCH) != 0 { + return 3 + } + // the min revision this library supports for this type + return 2 + + case "hash:ip": + // Taken from + // - ipset/kernel/net/netfilter/ipset/ip_set_hash_ip.c + if (featureFlags & nl.IPSET_FLAG_WITH_SKBINFO) != 0 { + return 4 + } + + if (featureFlags & nl.IPSET_FLAG_WITH_FORCEADD) != 0 { + return 3 + } + + if (featureFlags & nl.IPSET_FLAG_WITH_COMMENT) != 0 { + return 2 + } + + // the min revision this library supports for this type return 1 } + + // can't map the correct revision for this type. return 0 } @@ -579,3 +644,19 @@ func parseIPSetEntry(data []byte) (entry IPSetEntry) { } return } + +func optionsToBitflag(options IpsetCreateOptions) uint32 { + var cadtFlags uint32 + + if options.Comments { + cadtFlags |= nl.IPSET_FLAG_WITH_COMMENT + } + if options.Counters { + cadtFlags |= nl.IPSET_FLAG_WITH_COUNTERS + } + if options.Skbinfo { + cadtFlags |= nl.IPSET_FLAG_WITH_SKBINFO + } + + return cadtFlags +} diff --git a/vendor/github.com/vishvananda/netlink/link.go b/vendor/github.com/vishvananda/netlink/link.go index ef0f6c9956..42cb38bddb 100644 --- a/vendor/github.com/vishvananda/netlink/link.go +++ b/vendor/github.com/vishvananda/netlink/link.go @@ -290,8 +290,15 @@ func (bridge *Bridge) Type() string { // Vlan links have ParentIndex set in their Attrs() type Vlan struct { LinkAttrs - VlanId int - VlanProtocol VlanProtocol + VlanId int + VlanProtocol VlanProtocol + IngressQosMap map[uint32]uint32 + EgressQosMap map[uint32]uint32 + ReorderHdr *bool + Gvrp *bool + LooseBinding *bool + Mvrp *bool + BridgeBinding *bool } func (vlan *Vlan) Attrs() *LinkAttrs { @@ -426,6 +433,17 @@ type Veth struct { PeerName string // veth on create only PeerHardwareAddr net.HardwareAddr PeerNamespace interface{} + PeerTxQLen int + PeerNumTxQueues uint32 + PeerNumRxQueues uint32 + PeerMTU uint32 +} + +func NewVeth(attr LinkAttrs) *Veth { + return &Veth{ + LinkAttrs: attr, + PeerTxQLen: -1, + } } func (veth *Veth) Attrs() *LinkAttrs { diff --git a/vendor/github.com/vishvananda/netlink/link_linux.go b/vendor/github.com/vishvananda/netlink/link_linux.go index c9ff980c62..e26efb449a 100644 --- a/vendor/github.com/vishvananda/netlink/link_linux.go +++ b/vendor/github.com/vishvananda/netlink/link_linux.go @@ -1683,6 +1683,73 @@ func (h *Handle) linkModify(link Link, flags int) error { native.PutUint16(b, uint16(link.VlanId)) data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) data.AddRtAttr(nl.IFLA_VLAN_ID, b) + var vlanFlags uint32 + var vlanFlagsMask uint32 + if link.ReorderHdr != nil { + vlanFlagsMask |= nl.VLAN_FLAG_REORDER_HDR + if *link.ReorderHdr { + vlanFlags |= nl.VLAN_FLAG_REORDER_HDR + } else { + vlanFlags &= ^uint32(nl.VLAN_FLAG_REORDER_HDR) + } + } + if link.Gvrp != nil { + vlanFlagsMask |= nl.VLAN_FLAG_GVRP + if *link.Gvrp { + vlanFlags |= nl.VLAN_FLAG_GVRP + } else { + vlanFlags &= ^uint32(nl.VLAN_FLAG_GVRP) + } + } + if link.Mvrp != nil { + vlanFlagsMask |= nl.VLAN_FLAG_MVRP + if *link.Mvrp { + vlanFlags |= nl.VLAN_FLAG_MVRP + } else { + vlanFlags &= ^uint32(nl.VLAN_FLAG_MVRP) + } + } + if link.LooseBinding != nil { + vlanFlagsMask |= nl.VLAN_FLAG_LOOSE_BINDING + if *link.LooseBinding { + vlanFlags |= nl.VLAN_FLAG_LOOSE_BINDING + } else { + vlanFlags &= ^uint32(nl.VLAN_FLAG_LOOSE_BINDING) + } + } + if link.BridgeBinding != nil { + vlanFlagsMask |= nl.VLAN_FLAG_BRIDGE_BINDING + if *link.BridgeBinding { + vlanFlags |= nl.VLAN_FLAG_BRIDGE_BINDING + } else { + vlanFlags &= ^uint32(nl.VLAN_FLAG_BRIDGE_BINDING) + } + } + + buf := &bytes.Buffer{} + buf.Write(nl.Uint32Attr(vlanFlags)) + buf.Write(nl.Uint32Attr(vlanFlagsMask)) + data.AddRtAttr(nl.IFLA_VLAN_FLAGS, buf.Bytes()) + + if link.IngressQosMap != nil { + ingressMap := data.AddRtAttr(nl.IFLA_VLAN_INGRESS_QOS, nil) + for from, to := range link.IngressQosMap { + buf := &bytes.Buffer{} + buf.Write(nl.Uint32Attr(from)) + buf.Write(nl.Uint32Attr(to)) + ingressMap.AddRtAttr(nl.IFLA_VLAN_QOS_MAPPING, buf.Bytes()) + } + } + + if link.EgressQosMap != nil { + egressMap := data.AddRtAttr(nl.IFLA_VLAN_EGRESS_QOS, nil) + for from, to := range link.EgressQosMap { + buf := &bytes.Buffer{} + buf.Write(nl.Uint32Attr(from)) + buf.Write(nl.Uint32Attr(to)) + egressMap.AddRtAttr(nl.IFLA_VLAN_QOS_MAPPING, buf.Bytes()) + } + } if link.VlanProtocol != VLAN_PROTOCOL_UNKNOWN { data.AddRtAttr(nl.IFLA_VLAN_PROTOCOL, htons(uint16(link.VlanProtocol))) @@ -1696,16 +1763,25 @@ func (h *Handle) linkModify(link Link, flags int) error { peer := data.AddRtAttr(nl.VETH_INFO_PEER, nil) nl.NewIfInfomsgChild(peer, unix.AF_UNSPEC) peer.AddRtAttr(unix.IFLA_IFNAME, nl.ZeroTerminated(link.PeerName)) - if base.TxQLen >= 0 { + + if link.PeerTxQLen >= 0 { + peer.AddRtAttr(unix.IFLA_TXQLEN, nl.Uint32Attr(uint32(link.PeerTxQLen))) + } else if base.TxQLen >= 0 { peer.AddRtAttr(unix.IFLA_TXQLEN, nl.Uint32Attr(uint32(base.TxQLen))) } - if base.NumTxQueues > 0 { + if link.PeerNumTxQueues > 0 { + peer.AddRtAttr(unix.IFLA_NUM_TX_QUEUES, nl.Uint32Attr(link.PeerNumTxQueues)) + } else if base.NumTxQueues > 0 { peer.AddRtAttr(unix.IFLA_NUM_TX_QUEUES, nl.Uint32Attr(uint32(base.NumTxQueues))) } - if base.NumRxQueues > 0 { + if link.PeerNumRxQueues > 0 { + peer.AddRtAttr(unix.IFLA_NUM_RX_QUEUES, nl.Uint32Attr(link.PeerNumRxQueues)) + } else if base.NumRxQueues > 0 { peer.AddRtAttr(unix.IFLA_NUM_RX_QUEUES, nl.Uint32Attr(uint32(base.NumRxQueues))) } - if base.MTU > 0 { + if link.PeerMTU > 0 { + peer.AddRtAttr(unix.IFLA_MTU, nl.Uint32Attr(link.PeerMTU)) + } else if base.MTU > 0 { peer.AddRtAttr(unix.IFLA_MTU, nl.Uint32Attr(uint32(base.MTU))) } if link.PeerHardwareAddr != nil { @@ -2544,6 +2620,14 @@ func (h *Handle) LinkSetLearning(link Link, mode bool) error { return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_LEARNING) } +func LinkSetVlanTunnel(link Link, mode bool) error { + return pkgHandle.LinkSetVlanTunnel(link, mode) +} + +func (h *Handle) LinkSetVlanTunnel(link Link, mode bool) error { + return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_VLAN_TUNNEL) +} + func LinkSetRootBlock(link Link, mode bool) error { return pkgHandle.LinkSetRootBlock(link, mode) } @@ -2784,12 +2868,65 @@ func parseNetkitData(link Link, data []syscall.NetlinkRouteAttr) { } } +func parseVlanQosMap(data []byte) map[uint32]uint32 { + values, err := nl.ParseRouteAttr(data) + if err != nil { + return nil + } + + qosMap := make(map[uint32]uint32) + + for _, value := range values { + switch value.Attr.Type { + case nl.IFLA_VLAN_QOS_MAPPING: + from := native.Uint32(value.Value[:4]) + to := native.Uint32(value.Value[4:]) + qosMap[from] = to + } + } + + return qosMap +} + func parseVlanData(link Link, data []syscall.NetlinkRouteAttr) { vlan := link.(*Vlan) for _, datum := range data { switch datum.Attr.Type { case nl.IFLA_VLAN_ID: vlan.VlanId = int(native.Uint16(datum.Value[0:2])) + case nl.IFLA_VLAN_FLAGS: + flags := native.Uint32(datum.Value[0:4]) + trueVal := true + falseVal := false + if flags&nl.VLAN_FLAG_REORDER_HDR != 0 { + vlan.ReorderHdr = &trueVal + } else { + vlan.ReorderHdr = &falseVal + } + if flags&nl.VLAN_FLAG_GVRP != 0 { + vlan.Gvrp = &trueVal + } else { + vlan.Gvrp = &falseVal + } + if flags&nl.VLAN_FLAG_LOOSE_BINDING != 0 { + vlan.LooseBinding = &trueVal + } else { + vlan.LooseBinding = &falseVal + } + if flags&nl.VLAN_FLAG_MVRP != 0 { + vlan.Mvrp = &trueVal + } else { + vlan.Mvrp = &falseVal + } + if flags&nl.VLAN_FLAG_BRIDGE_BINDING != 0 { + vlan.BridgeBinding = &trueVal + } else { + vlan.BridgeBinding = &falseVal + } + case nl.IFLA_VLAN_EGRESS_QOS: + vlan.EgressQosMap = parseVlanQosMap(datum.Value) + case nl.IFLA_VLAN_INGRESS_QOS: + vlan.IngressQosMap = parseVlanQosMap(datum.Value) case nl.IFLA_VLAN_PROTOCOL: vlan.VlanProtocol = VlanProtocol(int(ntohs(datum.Value[0:2]))) } diff --git a/vendor/github.com/vishvananda/netlink/nl/bridge_linux.go b/vendor/github.com/vishvananda/netlink/nl/bridge_linux.go index 34e78ba8da..2441d1ca96 100644 --- a/vendor/github.com/vishvananda/netlink/nl/bridge_linux.go +++ b/vendor/github.com/vishvananda/netlink/nl/bridge_linux.go @@ -26,6 +26,14 @@ const ( IFLA_BRIDGE_FLAGS = iota IFLA_BRIDGE_MODE IFLA_BRIDGE_VLAN_INFO + IFLA_BRIDGE_VLAN_TUNNEL_INFO +) + +const ( + IFLA_BRIDGE_VLAN_TUNNEL_UNSPEC = iota + IFLA_BRIDGE_VLAN_TUNNEL_ID + IFLA_BRIDGE_VLAN_TUNNEL_VID + IFLA_BRIDGE_VLAN_TUNNEL_FLAGS ) const ( @@ -41,6 +49,11 @@ const ( // __u16 vid; // }; +type TunnelInfo struct { + TunId uint32 + Vid uint16 +} + type BridgeVlanInfo struct { Flags uint16 Vid uint16 diff --git a/vendor/github.com/vishvananda/netlink/nl/link_linux.go b/vendor/github.com/vishvananda/netlink/nl/link_linux.go index 2925e8a227..716c2a9a13 100644 --- a/vendor/github.com/vishvananda/netlink/nl/link_linux.go +++ b/vendor/github.com/vishvananda/netlink/nl/link_linux.go @@ -31,6 +31,20 @@ const ( IFLA_VLAN_MAX = IFLA_VLAN_PROTOCOL ) +const ( + IFLA_VLAN_QOS_UNSPEC = iota + IFLA_VLAN_QOS_MAPPING + IFLA_VLAN_QOS_MAX = IFLA_VLAN_QOS_MAPPING +) + +const ( + VLAN_FLAG_REORDER_HDR = 1 << iota + VLAN_FLAG_GVRP + VLAN_FLAG_LOOSE_BINDING + VLAN_FLAG_MVRP + VLAN_FLAG_BRIDGE_BINDING +) + const ( IFLA_NETKIT_UNSPEC = iota IFLA_NETKIT_PEER_INFO 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 ce43ee1550..0244836288 100644 --- a/vendor/github.com/vishvananda/netlink/nl/rdma_link_linux.go +++ b/vendor/github.com/vishvananda/netlink/nl/rdma_link_linux.go @@ -9,31 +9,41 @@ 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 + 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 + RDMA_NLDEV_CMD_RES_GET = 9 + RDMA_NLDEV_CMD_STAT_GET = 17 ) const ( - RDMA_NLDEV_ATTR_DEV_INDEX = 1 - RDMA_NLDEV_ATTR_DEV_NAME = 2 - RDMA_NLDEV_ATTR_PORT_INDEX = 3 - RDMA_NLDEV_ATTR_CAP_FLAGS = 4 - RDMA_NLDEV_ATTR_FW_VERSION = 5 - RDMA_NLDEV_ATTR_NODE_GUID = 6 - RDMA_NLDEV_ATTR_SYS_IMAGE_GUID = 7 - RDMA_NLDEV_ATTR_SUBNET_PREFIX = 8 - RDMA_NLDEV_ATTR_LID = 9 - RDMA_NLDEV_ATTR_SM_LID = 10 - RDMA_NLDEV_ATTR_LMC = 11 - RDMA_NLDEV_ATTR_PORT_STATE = 12 - RDMA_NLDEV_ATTR_PORT_PHYS_STATE = 13 - RDMA_NLDEV_ATTR_DEV_NODE_TYPE = 14 - RDMA_NLDEV_ATTR_NDEV_NAME = 51 - RDMA_NLDEV_ATTR_LINK_TYPE = 65 - RDMA_NLDEV_SYS_ATTR_NETNS_MODE = 66 - RDMA_NLDEV_NET_NS_FD = 68 + RDMA_NLDEV_ATTR_DEV_INDEX = 1 + RDMA_NLDEV_ATTR_DEV_NAME = 2 + RDMA_NLDEV_ATTR_PORT_INDEX = 3 + RDMA_NLDEV_ATTR_CAP_FLAGS = 4 + RDMA_NLDEV_ATTR_FW_VERSION = 5 + RDMA_NLDEV_ATTR_NODE_GUID = 6 + RDMA_NLDEV_ATTR_SYS_IMAGE_GUID = 7 + RDMA_NLDEV_ATTR_SUBNET_PREFIX = 8 + RDMA_NLDEV_ATTR_LID = 9 + RDMA_NLDEV_ATTR_SM_LID = 10 + RDMA_NLDEV_ATTR_LMC = 11 + RDMA_NLDEV_ATTR_PORT_STATE = 12 + RDMA_NLDEV_ATTR_PORT_PHYS_STATE = 13 + RDMA_NLDEV_ATTR_DEV_NODE_TYPE = 14 + RDMA_NLDEV_ATTR_RES_SUMMARY = 15 + RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY = 16 + RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME = 17 + RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR = 18 + 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 + RDMA_NLDEV_ATTR_STAT_HWCOUNTERS = 80 + RDMA_NLDEV_ATTR_STAT_HWCOUNTER_ENTRY = 81 + RDMA_NLDEV_ATTR_STAT_HWCOUNTER_ENTRY_NAME = 82 + RDMA_NLDEV_ATTR_STAT_HWCOUNTER_ENTRY_VALUE = 83 ) diff --git a/vendor/github.com/vishvananda/netlink/nl/tc_linux.go b/vendor/github.com/vishvananda/netlink/nl/tc_linux.go index 50f4a6d098..67666816e0 100644 --- a/vendor/github.com/vishvananda/netlink/nl/tc_linux.go +++ b/vendor/github.com/vishvananda/netlink/nl/tc_linux.go @@ -1123,6 +1123,13 @@ const ( TCA_FLOWER_KEY_ENC_OPTS TCA_FLOWER_KEY_ENC_OPTS_MASK + TCA_FLOWER_IN_HW_COUNT + + TCA_FLOWER_KEY_PORT_SRC_MIN /* be16 */ + TCA_FLOWER_KEY_PORT_SRC_MAX /* be16 */ + TCA_FLOWER_KEY_PORT_DST_MIN /* be16 */ + TCA_FLOWER_KEY_PORT_DST_MAX /* be16 */ + __TCA_FLOWER_MAX ) @@ -1138,11 +1145,11 @@ const TCA_CLS_FLAGS_SKIP_SW = 1 << 1 /* don't use filter in SW */ // }; type TcSfqQopt struct { - Quantum uint8 + Quantum uint32 Perturb int32 Limit uint32 - Divisor uint8 - Flows uint8 + Divisor uint32 + Flows uint32 } func (x *TcSfqQopt) Len() int { @@ -1580,7 +1587,7 @@ func (p *TcPedit) SetIPv6Dst(ip6 net.IP) { } func (p *TcPedit) SetIPv4Src(ip net.IP) { - u32 := NativeEndian().Uint32(ip[:4]) + u32 := NativeEndian().Uint32(ip.To4()) tKey := TcPeditKey{} tKeyEx := TcPeditKeyEx{} @@ -1596,7 +1603,7 @@ func (p *TcPedit) SetIPv4Src(ip net.IP) { } func (p *TcPedit) SetIPv4Dst(ip net.IP) { - u32 := NativeEndian().Uint32(ip[:4]) + u32 := NativeEndian().Uint32(ip.To4()) tKey := TcPeditKey{} tKeyEx := TcPeditKeyEx{} diff --git a/vendor/github.com/vishvananda/netlink/protinfo.go b/vendor/github.com/vishvananda/netlink/protinfo.go index 0163cba3a8..02f066e0a0 100644 --- a/vendor/github.com/vishvananda/netlink/protinfo.go +++ b/vendor/github.com/vishvananda/netlink/protinfo.go @@ -16,6 +16,7 @@ type Protinfo struct { ProxyArpWiFi bool Isolated bool NeighSuppress bool + VlanTunnel bool } // String returns a list of enabled flags @@ -55,6 +56,9 @@ func (prot *Protinfo) String() string { if prot.NeighSuppress { boolStrings = append(boolStrings, "NeighSuppress") } + if prot.VlanTunnel { + boolStrings = append(boolStrings, "VlanTunnel") + } return strings.Join(boolStrings, " ") } diff --git a/vendor/github.com/vishvananda/netlink/protinfo_linux.go b/vendor/github.com/vishvananda/netlink/protinfo_linux.go index aa51e3b470..c7d7b566e2 100644 --- a/vendor/github.com/vishvananda/netlink/protinfo_linux.go +++ b/vendor/github.com/vishvananda/netlink/protinfo_linux.go @@ -77,7 +77,10 @@ func parseProtinfo(infos []syscall.NetlinkRouteAttr) (pi Protinfo) { pi.Isolated = byteToBool(info.Value[0]) case nl.IFLA_BRPORT_NEIGH_SUPPRESS: pi.NeighSuppress = byteToBool(info.Value[0]) + case nl.IFLA_BRPORT_VLAN_TUNNEL: + pi.VlanTunnel = byteToBool(info.Value[0]) } + } return } diff --git a/vendor/github.com/vishvananda/netlink/qdisc.go b/vendor/github.com/vishvananda/netlink/qdisc.go index 067743d390..1cde43c94d 100644 --- a/vendor/github.com/vishvananda/netlink/qdisc.go +++ b/vendor/github.com/vishvananda/netlink/qdisc.go @@ -374,10 +374,10 @@ func (qdisc *FqCodel) Type() string { type Sfq struct { QdiscAttrs // TODO: Only the simplified options for SFQ are handled here. Support for the extended one can be added later. - Quantum uint8 - Perturb uint8 + Quantum uint32 + Perturb int32 Limit uint32 - Divisor uint8 + Divisor uint32 } func (sfq *Sfq) String() string { diff --git a/vendor/github.com/vishvananda/netlink/qdisc_linux.go b/vendor/github.com/vishvananda/netlink/qdisc_linux.go index 22cf0e5825..0a2a5891cc 100644 --- a/vendor/github.com/vishvananda/netlink/qdisc_linux.go +++ b/vendor/github.com/vishvananda/netlink/qdisc_linux.go @@ -321,7 +321,7 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error { case *Sfq: opt := nl.TcSfqQoptV1{} opt.TcSfqQopt.Quantum = qdisc.Quantum - opt.TcSfqQopt.Perturb = int32(qdisc.Perturb) + opt.TcSfqQopt.Perturb = qdisc.Perturb opt.TcSfqQopt.Limit = qdisc.Limit opt.TcSfqQopt.Divisor = qdisc.Divisor @@ -683,7 +683,7 @@ func parseSfqData(qdisc Qdisc, value []byte) error { sfq := qdisc.(*Sfq) opt := nl.DeserializeTcSfqQoptV1(value) sfq.Quantum = opt.TcSfqQopt.Quantum - sfq.Perturb = uint8(opt.TcSfqQopt.Perturb) + sfq.Perturb = opt.TcSfqQopt.Perturb sfq.Limit = opt.TcSfqQopt.Limit sfq.Divisor = opt.TcSfqQopt.Divisor diff --git a/vendor/github.com/vishvananda/netlink/rdma_link_linux.go b/vendor/github.com/vishvananda/netlink/rdma_link_linux.go index 9bb7507321..2e774e5aef 100644 --- a/vendor/github.com/vishvananda/netlink/rdma_link_linux.go +++ b/vendor/github.com/vishvananda/netlink/rdma_link_linux.go @@ -18,6 +18,7 @@ type RdmaLinkAttrs struct { FirmwareVersion string NodeGuid string SysImageGuid string + NumPorts uint32 } // Link represents a rdma device from netlink. @@ -69,6 +70,11 @@ func executeOneGetRdmaLink(data []byte) (*RdmaLink, error) { r := bytes.NewReader(value) binary.Read(r, nl.NativeEndian(), &sysGuid) link.Attrs.SysImageGuid = uint64ToGuidString(sysGuid) + case nl.RDMA_NLDEV_ATTR_PORT_INDEX: + var availablePort uint32 + r := bytes.NewReader(value) + binary.Read(r, nl.NativeEndian(), &availablePort) + link.Attrs.NumPorts = availablePort } if (len % 4) != 0 { // Skip pad bytes @@ -345,3 +351,212 @@ func (h *Handle) RdmaLinkAdd(linkName string, linkType string, netdev string) er _, err := req.Execute(unix.NETLINK_RDMA, 0) return err } + +// RdmaResource represents a rdma device resource tracking summaries +type RdmaResource struct { + Index uint32 + Name string + RdmaResourceSummaryEntries map[string]uint64 +} + +// RdmaResourceList list rdma resource tracking information +// Returns all rdma devices resource tracking summary on success or returns error +// otherwise. +// Equivalent to: `rdma resource' +func RdmaResourceList() ([]*RdmaResource, error) { + return pkgHandle.RdmaResourceList() +} + +// RdmaResourceList list rdma resource tracking information +// Returns all rdma devices resource tracking summary on success or returns error +// otherwise. +// Equivalent to: `rdma resource' +func (h *Handle) RdmaResourceList() ([]*RdmaResource, error) { + proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_RES_GET) + req := h.newNetlinkRequest(proto, unix.NLM_F_ACK|unix.NLM_F_DUMP) + + msgs, err := req.Execute(unix.NETLINK_RDMA, 0) + if err != nil { + return nil, err + } + if len(msgs) == 0 { + return nil, fmt.Errorf("No valid response from kernel") + } + var rdmaResources []*RdmaResource + for _, msg := range msgs { + res, err := executeOneGetRdmaResourceList(msg) + if err != nil { + return nil, err + } + rdmaResources = append(rdmaResources, res) + } + return rdmaResources, nil +} + +func parseRdmaCounters(counterType uint16, data []byte) (map[string]uint64, error) { + var counterKeyType, counterValueType uint16 + switch counterType { + case nl.RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY: + counterKeyType = nl.RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME + counterValueType = nl.RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR + case nl.RDMA_NLDEV_ATTR_STAT_HWCOUNTER_ENTRY: + counterKeyType = nl.RDMA_NLDEV_ATTR_STAT_HWCOUNTER_ENTRY_NAME + counterValueType = nl.RDMA_NLDEV_ATTR_STAT_HWCOUNTER_ENTRY_VALUE + default: + return nil, fmt.Errorf("Invalid counter type: %d", counterType) + } + counters := make(map[string]uint64) + reader := bytes.NewReader(data) + + for reader.Len() >= 4 { + _, attrType, _, value := parseNfAttrTLV(reader) + if attrType != counterType { + return nil, fmt.Errorf("Invalid resource summary entry type; %d", attrType) + } + + summaryReader := bytes.NewReader(value) + for summaryReader.Len() >= 4 { + _, attrType, len, value := parseNfAttrTLV(summaryReader) + if attrType != counterKeyType { + return nil, fmt.Errorf("Invalid resource summary entry name type; %d", attrType) + } + name := string(value[0 : len-1]) + // Skip pad bytes + if (len % 4) != 0 { + summaryReader.Seek(int64(4-(len%4)), seekCurrent) + } + _, attrType, len, value = parseNfAttrTLV(summaryReader) + if attrType != counterValueType { + return nil, fmt.Errorf("Invalid resource summary entry value type; %d", attrType) + } + counters[name] = native.Uint64(value) + } + } + return counters, nil +} + +func executeOneGetRdmaResourceList(data []byte) (*RdmaResource, error) { + var res RdmaResource + reader := bytes.NewReader(data) + for reader.Len() >= 4 { + _, attrType, len, value := parseNfAttrTLV(reader) + + switch attrType { + case nl.RDMA_NLDEV_ATTR_DEV_INDEX: + var Index uint32 + r := bytes.NewReader(value) + binary.Read(r, nl.NativeEndian(), &Index) + res.Index = Index + case nl.RDMA_NLDEV_ATTR_DEV_NAME: + res.Name = string(value[0 : len-1]) + case nl.RDMA_NLDEV_ATTR_RES_SUMMARY: + var err error + res.RdmaResourceSummaryEntries, err = parseRdmaCounters(nl.RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY, value) + if err != nil { + return nil, err + } + } + if (len % 4) != 0 { + // Skip pad bytes + reader.Seek(int64(4-(len%4)), seekCurrent) + } + } + return &res, nil +} + +// RdmaPortStatistic represents a rdma port statistic counter +type RdmaPortStatistic struct { + PortIndex uint32 + Statistics map[string]uint64 +} + +// RdmaDeviceStatistic represents a rdma device statistic counter +type RdmaDeviceStatistic struct { + RdmaPortStatistics []*RdmaPortStatistic +} + +// RdmaStatistic get rdma device statistic counters +// Returns rdma device statistic counters on success or returns error +// otherwise. +// Equivalent to: `rdma statistic show link [DEV]' +func RdmaStatistic(link *RdmaLink) (*RdmaDeviceStatistic, error) { + return pkgHandle.RdmaStatistic(link) +} + +// RdmaStatistic get rdma device statistic counters +// Returns rdma device statistic counters on success or returns error +// otherwise. +// Equivalent to: `rdma statistic show link [DEV]' +func (h *Handle) RdmaStatistic(link *RdmaLink) (*RdmaDeviceStatistic, error) { + rdmaLinkStatistic := make([]*RdmaPortStatistic, 0) + for portIndex := uint32(1); portIndex <= link.Attrs.NumPorts; portIndex++ { + portStatistic, err := h.RdmaPortStatisticList(link, portIndex) + if err != nil { + return nil, err + } + rdmaLinkStatistic = append(rdmaLinkStatistic, portStatistic) + } + return &RdmaDeviceStatistic{RdmaPortStatistics: rdmaLinkStatistic}, nil +} + +// RdmaPortStatisticList get rdma device port statistic counters +// Returns rdma device port statistic counters on success or returns error +// otherwise. +// Equivalent to: `rdma statistic show link [DEV/PORT]' +func RdmaPortStatisticList(link *RdmaLink, port uint32) (*RdmaPortStatistic, error) { + return pkgHandle.RdmaPortStatisticList(link, port) +} + +// RdmaPortStatisticList get rdma device port statistic counters +// Returns rdma device port statistic counters on success or returns error +// otherwise. +// Equivalent to: `rdma statistic show link [DEV/PORT]' +func (h *Handle) RdmaPortStatisticList(link *RdmaLink, port uint32) (*RdmaPortStatistic, error) { + proto := getProtoField(nl.RDMA_NL_NLDEV, nl.RDMA_NLDEV_CMD_STAT_GET) + req := h.newNetlinkRequest(proto, unix.NLM_F_ACK|unix.NLM_F_REQUEST) + b := make([]byte, 4) + native.PutUint32(b, link.Attrs.Index) + data := nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_DEV_INDEX, b) + req.AddData(data) + + b = make([]byte, 4) + native.PutUint32(b, port) + data = nl.NewRtAttr(nl.RDMA_NLDEV_ATTR_PORT_INDEX, b) + req.AddData(data) + + msgs, err := req.Execute(unix.NETLINK_RDMA, 0) + if err != nil { + return nil, err + } + if len(msgs) != 1 { + return nil, fmt.Errorf("No valid response from kernel") + } + return executeOneGetRdmaPortStatistics(msgs[0]) +} + +func executeOneGetRdmaPortStatistics(data []byte) (*RdmaPortStatistic, error) { + var stat RdmaPortStatistic + reader := bytes.NewReader(data) + for reader.Len() >= 4 { + _, attrType, len, value := parseNfAttrTLV(reader) + + switch attrType { + case nl.RDMA_NLDEV_ATTR_PORT_INDEX: + var Index uint32 + r := bytes.NewReader(value) + binary.Read(r, nl.NativeEndian(), &Index) + stat.PortIndex = Index + case nl.RDMA_NLDEV_ATTR_STAT_HWCOUNTERS: + var err error + stat.Statistics, err = parseRdmaCounters(nl.RDMA_NLDEV_ATTR_STAT_HWCOUNTER_ENTRY, value) + if err != nil { + return nil, err + } + } + if (len % 4) != 0 { + // Skip pad bytes + reader.Seek(int64(4-(len%4)), seekCurrent) + } + } + return &stat, nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 77b5dc8d64..2b3a8efebc 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -996,7 +996,7 @@ github.com/vbauerster/mpb/v8 github.com/vbauerster/mpb/v8/cwriter github.com/vbauerster/mpb/v8/decor github.com/vbauerster/mpb/v8/internal -# github.com/vishvananda/netlink v1.3.1-0.20250425193846-9d88d8385bf9 +# github.com/vishvananda/netlink v1.3.1 ## explicit; go 1.12 github.com/vishvananda/netlink github.com/vishvananda/netlink/nl