mirror of https://github.com/containers/podman.git
fix(deps): update module github.com/vishvananda/netlink to v1.3.1
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This commit is contained in:
parent
811aabd3b0
commit
a5748206d1
2
go.mod
2
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
|
||||
|
|
4
go.sum
4
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=
|
||||
|
|
|
@ -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())
|
||||
|
||||
vlanEndInfo.Flags |= nl.BRIDGE_VLAN_INFO_RANGE_END
|
||||
br.AddRtAttr(nl.IFLA_BRIDGE_VLAN_INFO, vlanEndInfo.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 {
|
||||
br.AddRtAttr(nl.IFLA_BRIDGE_VLAN_INFO, vlanInfo.Serialize())
|
||||
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
|
||||
|
||||
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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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])))
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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{}
|
||||
|
|
|
@ -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, " ")
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue