mirror of
https://github.com/rancher/plugins.git
synced 2025-09-06 19:00:03 +00:00
Update github.com/vishvananda/netlink to v1.1.0
Latest version allows to set a VRF device as master and not only a bridge one. Signed-off-by: Federico Paolinelli <fpaoline@redhat.com>
This commit is contained in:
571
vendor/github.com/vishvananda/netlink/link_linux.go
generated
vendored
571
vendor/github.com/vishvananda/netlink/link_linux.go
generated
vendored
@@ -4,8 +4,10 @@ import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
@@ -17,7 +19,7 @@ import (
|
||||
|
||||
const (
|
||||
SizeofLinkStats32 = 0x5c
|
||||
SizeofLinkStats64 = 0xd8
|
||||
SizeofLinkStats64 = 0xb8
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -32,6 +34,12 @@ const (
|
||||
TUNTAP_MULTI_QUEUE_DEFAULTS TuntapFlag = TUNTAP_MULTI_QUEUE | TUNTAP_NO_PI
|
||||
)
|
||||
|
||||
const (
|
||||
VF_LINK_STATE_AUTO uint32 = 0
|
||||
VF_LINK_STATE_ENABLE uint32 = 1
|
||||
VF_LINK_STATE_DISABLE uint32 = 2
|
||||
)
|
||||
|
||||
var lookupByDump = false
|
||||
|
||||
var macvlanModes = [...]uint32{
|
||||
@@ -465,6 +473,37 @@ func (h *Handle) LinkSetVfVlan(link Link, vf, vlan int) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// LinkSetVfVlanQos sets the vlan and qos priority of a vf for the link.
|
||||
// Equivalent to: `ip link set $link vf $vf vlan $vlan qos $qos`
|
||||
func LinkSetVfVlanQos(link Link, vf, vlan, qos int) error {
|
||||
return pkgHandle.LinkSetVfVlanQos(link, vf, vlan, qos)
|
||||
}
|
||||
|
||||
// LinkSetVfVlanQos sets the vlan and qos priority of a vf for the link.
|
||||
// Equivalent to: `ip link set $link vf $vf vlan $vlan qos $qos`
|
||||
func (h *Handle) LinkSetVfVlanQos(link Link, vf, vlan, qos int) error {
|
||||
base := link.Attrs()
|
||||
h.ensureIndex(base)
|
||||
req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
|
||||
|
||||
msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
|
||||
msg.Index = int32(base.Index)
|
||||
req.AddData(msg)
|
||||
|
||||
data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil)
|
||||
info := nl.NewRtAttrChild(data, 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())
|
||||
req.AddData(data)
|
||||
|
||||
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
// LinkSetVfTxRate sets the tx rate of a vf for the link.
|
||||
// Equivalent to: `ip link set $link vf $vf rate $rate`
|
||||
func LinkSetVfTxRate(link Link, vf, rate int) error {
|
||||
@@ -495,13 +534,74 @@ func (h *Handle) LinkSetVfTxRate(link Link, vf, rate int) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// LinkSetVfRate sets the min and max tx rate of a vf for the link.
|
||||
// Equivalent to: `ip link set $link vf $vf min_tx_rate $min_rate max_tx_rate $max_rate`
|
||||
func LinkSetVfRate(link Link, vf, minRate, maxRate int) error {
|
||||
return pkgHandle.LinkSetVfRate(link, vf, minRate, maxRate)
|
||||
}
|
||||
|
||||
// LinkSetVfRate sets the min and max tx rate of a vf for the link.
|
||||
// Equivalent to: `ip link set $link vf $vf min_tx_rate $min_rate max_tx_rate $max_rate`
|
||||
func (h *Handle) LinkSetVfRate(link Link, vf, minRate, maxRate int) error {
|
||||
base := link.Attrs()
|
||||
h.ensureIndex(base)
|
||||
req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
|
||||
|
||||
msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
|
||||
msg.Index = int32(base.Index)
|
||||
req.AddData(msg)
|
||||
|
||||
data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil)
|
||||
info := data.AddRtAttr(nl.IFLA_VF_INFO, nil)
|
||||
vfmsg := nl.VfRate{
|
||||
Vf: uint32(vf),
|
||||
MinTxRate: uint32(minRate),
|
||||
MaxTxRate: uint32(maxRate),
|
||||
}
|
||||
info.AddRtAttr(nl.IFLA_VF_RATE, vfmsg.Serialize())
|
||||
req.AddData(data)
|
||||
|
||||
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
// LinkSetVfState enables/disables virtual link state on a vf.
|
||||
// Equivalent to: `ip link set $link vf $vf state $state`
|
||||
func LinkSetVfState(link Link, vf int, state uint32) error {
|
||||
return pkgHandle.LinkSetVfState(link, vf, state)
|
||||
}
|
||||
|
||||
// LinkSetVfState enables/disables virtual link state on a vf.
|
||||
// Equivalent to: `ip link set $link vf $vf state $state`
|
||||
func (h *Handle) LinkSetVfState(link Link, vf int, state uint32) error {
|
||||
base := link.Attrs()
|
||||
h.ensureIndex(base)
|
||||
req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
|
||||
|
||||
msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
|
||||
msg.Index = int32(base.Index)
|
||||
req.AddData(msg)
|
||||
|
||||
data := nl.NewRtAttr(unix.IFLA_VFINFO_LIST, nil)
|
||||
info := data.AddRtAttr(nl.IFLA_VF_INFO, nil)
|
||||
vfmsg := nl.VfLinkState{
|
||||
Vf: uint32(vf),
|
||||
LinkState: state,
|
||||
}
|
||||
info.AddRtAttr(nl.IFLA_VF_LINK_STATE, vfmsg.Serialize())
|
||||
req.AddData(data)
|
||||
|
||||
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
// LinkSetVfSpoofchk enables/disables spoof check on a vf for the link.
|
||||
// Equivalent to: `ip link set $link vf $vf spoofchk $check`
|
||||
func LinkSetVfSpoofchk(link Link, vf int, check bool) error {
|
||||
return pkgHandle.LinkSetVfSpoofchk(link, vf, check)
|
||||
}
|
||||
|
||||
// LinkSetVfSpookfchk enables/disables spoof check on a vf for the link.
|
||||
// LinkSetVfSpoofchk enables/disables spoof check on a vf for the link.
|
||||
// Equivalent to: `ip link set $link vf $vf spoofchk $check`
|
||||
func (h *Handle) LinkSetVfSpoofchk(link Link, vf int, check bool) error {
|
||||
var setting uint32
|
||||
@@ -581,7 +681,7 @@ func (h *Handle) LinkSetVfGUID(link Link, vf int, vfGuid net.HardwareAddr, guidT
|
||||
var guid uint64
|
||||
|
||||
buf := bytes.NewBuffer(vfGuid)
|
||||
err = binary.Read(buf, binary.LittleEndian, &guid)
|
||||
err = binary.Read(buf, binary.BigEndian, &guid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -609,13 +709,13 @@ func (h *Handle) LinkSetVfGUID(link Link, vf int, vfGuid net.HardwareAddr, guidT
|
||||
|
||||
// LinkSetMaster sets the master of the link device.
|
||||
// Equivalent to: `ip link set $link master $master`
|
||||
func LinkSetMaster(link Link, master *Bridge) error {
|
||||
func LinkSetMaster(link Link, master Link) error {
|
||||
return pkgHandle.LinkSetMaster(link, master)
|
||||
}
|
||||
|
||||
// LinkSetMaster sets the master of the link device.
|
||||
// Equivalent to: `ip link set $link master $master`
|
||||
func (h *Handle) LinkSetMaster(link Link, master *Bridge) error {
|
||||
func (h *Handle) LinkSetMaster(link Link, master Link) error {
|
||||
index := 0
|
||||
if master != nil {
|
||||
masterBase := master.Attrs()
|
||||
@@ -1086,8 +1186,8 @@ func (h *Handle) linkModify(link Link, flags int) error {
|
||||
native.PutUint32(b, uint32(base.ParentIndex))
|
||||
data := nl.NewRtAttr(unix.IFLA_LINK, b)
|
||||
req.AddData(data)
|
||||
} else if link.Type() == "ipvlan" {
|
||||
return fmt.Errorf("Can't create ipvlan link without ParentIndex")
|
||||
} else if link.Type() == "ipvlan" || link.Type() == "ipoib" {
|
||||
return fmt.Errorf("Can't create %s link without ParentIndex", link.Type())
|
||||
}
|
||||
|
||||
nameData := nl.NewRtAttr(unix.IFLA_IFNAME, nl.ZeroTerminated(base.Name))
|
||||
@@ -1118,14 +1218,29 @@ func (h *Handle) linkModify(link Link, flags int) error {
|
||||
req.AddData(rxqueues)
|
||||
}
|
||||
|
||||
if base.GSOMaxSegs > 0 {
|
||||
gsoAttr := nl.NewRtAttr(unix.IFLA_GSO_MAX_SEGS, nl.Uint32Attr(base.GSOMaxSegs))
|
||||
req.AddData(gsoAttr)
|
||||
}
|
||||
|
||||
if base.GSOMaxSize > 0 {
|
||||
gsoAttr := nl.NewRtAttr(unix.IFLA_GSO_MAX_SIZE, nl.Uint32Attr(base.GSOMaxSize))
|
||||
req.AddData(gsoAttr)
|
||||
}
|
||||
|
||||
if base.Group > 0 {
|
||||
groupAttr := nl.NewRtAttr(unix.IFLA_GROUP, nl.Uint32Attr(base.Group))
|
||||
req.AddData(groupAttr)
|
||||
}
|
||||
|
||||
if base.Namespace != nil {
|
||||
var attr *nl.RtAttr
|
||||
switch base.Namespace.(type) {
|
||||
switch ns := base.Namespace.(type) {
|
||||
case NsPid:
|
||||
val := nl.Uint32Attr(uint32(base.Namespace.(NsPid)))
|
||||
val := nl.Uint32Attr(uint32(ns))
|
||||
attr = nl.NewRtAttr(unix.IFLA_NET_NS_PID, val)
|
||||
case NsFd:
|
||||
val := nl.Uint32Attr(uint32(base.Namespace.(NsFd)))
|
||||
val := nl.Uint32Attr(uint32(ns))
|
||||
attr = nl.NewRtAttr(unix.IFLA_NET_NS_FD, val)
|
||||
}
|
||||
|
||||
@@ -1145,6 +1260,10 @@ 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)
|
||||
|
||||
if link.VlanProtocol != VLAN_PROTOCOL_UNKNOWN {
|
||||
data.AddRtAttr(nl.IFLA_VLAN_PROTOCOL, htons(uint16(link.VlanProtocol)))
|
||||
}
|
||||
case *Veth:
|
||||
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
|
||||
peer := data.AddRtAttr(nl.VETH_INFO_PEER, nil)
|
||||
@@ -1156,7 +1275,9 @@ func (h *Handle) linkModify(link Link, flags int) error {
|
||||
if base.MTU > 0 {
|
||||
peer.AddRtAttr(unix.IFLA_MTU, nl.Uint32Attr(uint32(base.MTU)))
|
||||
}
|
||||
|
||||
if link.PeerHardwareAddr != nil {
|
||||
peer.AddRtAttr(unix.IFLA_ADDRESS, []byte(link.PeerHardwareAddr))
|
||||
}
|
||||
case *Vxlan:
|
||||
addVxlanAttrs(link, linkInfo)
|
||||
case *Bond:
|
||||
@@ -1164,6 +1285,7 @@ func (h *Handle) linkModify(link Link, flags int) error {
|
||||
case *IPVlan:
|
||||
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)
|
||||
@@ -1178,6 +1300,8 @@ func (h *Handle) linkModify(link Link, flags int) error {
|
||||
addGretapAttrs(link, linkInfo)
|
||||
case *Iptun:
|
||||
addIptunAttrs(link, linkInfo)
|
||||
case *Ip6tnl:
|
||||
addIp6tnlAttrs(link, linkInfo)
|
||||
case *Sittun:
|
||||
addSittunAttrs(link, linkInfo)
|
||||
case *Gretun:
|
||||
@@ -1190,6 +1314,10 @@ func (h *Handle) linkModify(link Link, flags int) error {
|
||||
addBridgeAttrs(link, linkInfo)
|
||||
case *GTP:
|
||||
addGTPAttrs(link, linkInfo)
|
||||
case *Xfrmi:
|
||||
addXfrmiAttrs(link, linkInfo)
|
||||
case *IPoIB:
|
||||
addIPoIBAttrs(link, linkInfo)
|
||||
}
|
||||
|
||||
req.AddData(linkInfo)
|
||||
@@ -1386,10 +1514,12 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
|
||||
base.Promisc = 1
|
||||
}
|
||||
var (
|
||||
link Link
|
||||
stats32 []byte
|
||||
stats64 []byte
|
||||
linkType string
|
||||
link Link
|
||||
stats32 *LinkStatistics32
|
||||
stats64 *LinkStatistics64
|
||||
linkType string
|
||||
linkSlave LinkSlave
|
||||
slaveType string
|
||||
)
|
||||
for _, attr := range attrs {
|
||||
switch attr.Attr.Type {
|
||||
@@ -1429,6 +1559,8 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
|
||||
link = &Gretap{}
|
||||
case "ipip":
|
||||
link = &Iptun{}
|
||||
case "ip6tnl":
|
||||
link = &Ip6tnl{}
|
||||
case "sit":
|
||||
link = &Sittun{}
|
||||
case "gre":
|
||||
@@ -1441,6 +1573,12 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
|
||||
link = &Vrf{}
|
||||
case "gtp":
|
||||
link = >P{}
|
||||
case "xfrm":
|
||||
link = &Xfrmi{}
|
||||
case "tun":
|
||||
link = &Tuntap{}
|
||||
case "ipoib":
|
||||
link = &IPoIB{}
|
||||
default:
|
||||
link = &GenericLink{LinkType: linkType}
|
||||
}
|
||||
@@ -1468,6 +1606,8 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
|
||||
parseGretapData(link, data)
|
||||
case "ipip":
|
||||
parseIptunData(link, data)
|
||||
case "ip6tnl":
|
||||
parseIp6tnlData(link, data)
|
||||
case "sit":
|
||||
parseSittunData(link, data)
|
||||
case "gre":
|
||||
@@ -1482,6 +1622,27 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
|
||||
parseBridgeData(link, data)
|
||||
case "gtp":
|
||||
parseGTPData(link, data)
|
||||
case "xfrm":
|
||||
parseXfrmiData(link, data)
|
||||
case "tun":
|
||||
parseTuntapData(link, data)
|
||||
case "ipoib":
|
||||
parseIPoIBData(link, data)
|
||||
}
|
||||
case nl.IFLA_INFO_SLAVE_KIND:
|
||||
slaveType = string(info.Value[:len(info.Value)-1])
|
||||
switch slaveType {
|
||||
case "bond":
|
||||
linkSlave = &BondSlave{}
|
||||
}
|
||||
case nl.IFLA_INFO_SLAVE_DATA:
|
||||
switch slaveType {
|
||||
case "bond":
|
||||
data, err := nl.ParseRouteAttr(info.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
parseBondSlaveData(linkSlave, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1508,9 +1669,15 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
|
||||
case unix.IFLA_IFALIAS:
|
||||
base.Alias = string(attr.Value[:len(attr.Value)-1])
|
||||
case unix.IFLA_STATS:
|
||||
stats32 = attr.Value[:]
|
||||
stats32 = new(LinkStatistics32)
|
||||
if err := binary.Read(bytes.NewBuffer(attr.Value[:]), nl.NativeEndian(), stats32); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case unix.IFLA_STATS64:
|
||||
stats64 = attr.Value[:]
|
||||
stats64 = new(LinkStatistics64)
|
||||
if err := binary.Read(bytes.NewBuffer(attr.Value[:]), nl.NativeEndian(), stats64); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case unix.IFLA_XDP:
|
||||
xdp, err := parseLinkXdp(attr.Value[:])
|
||||
if err != nil {
|
||||
@@ -1531,6 +1698,10 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
|
||||
base.OperState = LinkOperState(uint8(attr.Value[0]))
|
||||
case unix.IFLA_LINK_NETNSID:
|
||||
base.NetNsID = int(native.Uint32(attr.Value[0:4]))
|
||||
case unix.IFLA_GSO_MAX_SIZE:
|
||||
base.GSOMaxSize = native.Uint32(attr.Value[0:4])
|
||||
case unix.IFLA_GSO_MAX_SEGS:
|
||||
base.GSOMaxSegs = native.Uint32(attr.Value[0:4])
|
||||
case unix.IFLA_VFINFO_LIST:
|
||||
data, err := nl.ParseRouteAttr(attr.Value)
|
||||
if err != nil {
|
||||
@@ -1541,13 +1712,19 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
|
||||
return nil, err
|
||||
}
|
||||
base.Vfs = vfs
|
||||
case unix.IFLA_NUM_TX_QUEUES:
|
||||
base.NumTxQueues = int(native.Uint32(attr.Value[0:4]))
|
||||
case unix.IFLA_NUM_RX_QUEUES:
|
||||
base.NumRxQueues = int(native.Uint32(attr.Value[0:4]))
|
||||
case unix.IFLA_GROUP:
|
||||
base.Group = native.Uint32(attr.Value[0:4])
|
||||
}
|
||||
}
|
||||
|
||||
if stats64 != nil {
|
||||
base.Statistics = parseLinkStats64(stats64)
|
||||
base.Statistics = (*LinkStatistics)(stats64)
|
||||
} else if stats32 != nil {
|
||||
base.Statistics = parseLinkStats32(stats32)
|
||||
base.Statistics = (*LinkStatistics)(stats32.to64())
|
||||
}
|
||||
|
||||
// Links that don't have IFLA_INFO_KIND are hardware devices
|
||||
@@ -1555,10 +1732,59 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
|
||||
link = &Device{}
|
||||
}
|
||||
*link.Attrs() = base
|
||||
link.Attrs().Slave = linkSlave
|
||||
|
||||
// If the tuntap attributes are not updated by netlink due to
|
||||
// an older driver, use sysfs
|
||||
if link != nil && linkType == "tun" {
|
||||
tuntap := link.(*Tuntap)
|
||||
|
||||
if tuntap.Mode == 0 {
|
||||
ifname := tuntap.Attrs().Name
|
||||
if flags, err := readSysPropAsInt64(ifname, "tun_flags"); err == nil {
|
||||
|
||||
if flags&unix.IFF_TUN != 0 {
|
||||
tuntap.Mode = unix.IFF_TUN
|
||||
} else if flags&unix.IFF_TAP != 0 {
|
||||
tuntap.Mode = unix.IFF_TAP
|
||||
}
|
||||
|
||||
tuntap.NonPersist = false
|
||||
if flags&unix.IFF_PERSIST == 0 {
|
||||
tuntap.NonPersist = true
|
||||
}
|
||||
}
|
||||
|
||||
// The sysfs interface for owner/group returns -1 for root user, instead of returning 0.
|
||||
// So explicitly check for negative value, before assigning the owner uid/gid.
|
||||
if owner, err := readSysPropAsInt64(ifname, "owner"); err == nil && owner > 0 {
|
||||
tuntap.Owner = uint32(owner)
|
||||
}
|
||||
|
||||
if group, err := readSysPropAsInt64(ifname, "group"); err == nil && group > 0 {
|
||||
tuntap.Group = uint32(group)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return link, nil
|
||||
}
|
||||
|
||||
func readSysPropAsInt64(ifname, prop string) (int64, error) {
|
||||
fname := fmt.Sprintf("/sys/class/net/%s/%s", ifname, prop)
|
||||
contents, err := ioutil.ReadFile(fname)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
num, err := strconv.ParseInt(strings.TrimSpace(string(contents)), 0, 64)
|
||||
if err == nil {
|
||||
return num, nil
|
||||
}
|
||||
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// LinkList gets a list of link devices.
|
||||
// Equivalent to: `ip link show`
|
||||
func LinkList() ([]Link, error) {
|
||||
@@ -1655,13 +1881,19 @@ func linkSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-c
|
||||
go func() {
|
||||
defer close(ch)
|
||||
for {
|
||||
msgs, err := s.Receive()
|
||||
msgs, from, err := s.Receive()
|
||||
if err != nil {
|
||||
if cberr != nil {
|
||||
cberr(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if from.Pid != nl.PidKernel {
|
||||
if cberr != nil {
|
||||
cberr(fmt.Errorf("Wrong sender portid %d, expected %d", from.Pid, nl.PidKernel))
|
||||
}
|
||||
continue
|
||||
}
|
||||
for _, m := range msgs {
|
||||
if m.Header.Type == unix.NLMSG_DONE {
|
||||
continue
|
||||
@@ -1804,12 +2036,43 @@ func (h *Handle) LinkSetTxQLen(link Link, qlen int) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// LinkSetGroup sets the link group id which can be used to perform mass actions
|
||||
// with iproute2 as well use it as a reference in nft filters.
|
||||
// Equivalent to: `ip link set $link group $id`
|
||||
func LinkSetGroup(link Link, group int) error {
|
||||
return pkgHandle.LinkSetGroup(link, group)
|
||||
}
|
||||
|
||||
// LinkSetGroup sets the link group id which can be used to perform mass actions
|
||||
// with iproute2 as well use it as a reference in nft filters.
|
||||
// Equivalent to: `ip link set $link group $id`
|
||||
func (h *Handle) LinkSetGroup(link Link, group int) error {
|
||||
base := link.Attrs()
|
||||
h.ensureIndex(base)
|
||||
req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
|
||||
|
||||
msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
|
||||
msg.Index = int32(base.Index)
|
||||
req.AddData(msg)
|
||||
|
||||
b := make([]byte, 4)
|
||||
native.PutUint32(b, uint32(group))
|
||||
|
||||
data := nl.NewRtAttr(unix.IFLA_GROUP, b)
|
||||
req.AddData(data)
|
||||
|
||||
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
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_PROTOCOL:
|
||||
vlan.VlanProtocol = VlanProtocol(int(ntohs(datum.Value[0:2])))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1891,7 +2154,7 @@ func parseBondData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||
case nl.IFLA_BOND_ARP_INTERVAL:
|
||||
bond.ArpInterval = int(native.Uint32(data[i].Value[0:4]))
|
||||
case nl.IFLA_BOND_ARP_IP_TARGET:
|
||||
// TODO: implement
|
||||
bond.ArpIpTargets = parseBondArpIpTargets(data[i].Value)
|
||||
case nl.IFLA_BOND_ARP_VALIDATE:
|
||||
bond.ArpValidate = BondArpValidate(native.Uint32(data[i].Value[0:4]))
|
||||
case nl.IFLA_BOND_ARP_ALL_TARGETS:
|
||||
@@ -1934,12 +2197,75 @@ func parseBondData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||
}
|
||||
}
|
||||
|
||||
func parseBondArpIpTargets(value []byte) []net.IP {
|
||||
data, err := nl.ParseRouteAttr(value)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
targets := []net.IP{}
|
||||
for i := range data {
|
||||
target := net.IP(data[i].Value)
|
||||
if ip := target.To4(); ip != nil {
|
||||
targets = append(targets, ip)
|
||||
continue
|
||||
}
|
||||
if ip := target.To16(); ip != nil {
|
||||
targets = append(targets, ip)
|
||||
}
|
||||
}
|
||||
|
||||
return targets
|
||||
}
|
||||
|
||||
func addBondSlaveAttrs(bondSlave *BondSlave, linkInfo *nl.RtAttr) {
|
||||
data := linkInfo.AddRtAttr(nl.IFLA_INFO_SLAVE_DATA, nil)
|
||||
|
||||
data.AddRtAttr(nl.IFLA_BOND_SLAVE_STATE, nl.Uint8Attr(uint8(bondSlave.State)))
|
||||
data.AddRtAttr(nl.IFLA_BOND_SLAVE_MII_STATUS, nl.Uint8Attr(uint8(bondSlave.MiiStatus)))
|
||||
data.AddRtAttr(nl.IFLA_BOND_SLAVE_LINK_FAILURE_COUNT, nl.Uint32Attr(bondSlave.LinkFailureCount))
|
||||
data.AddRtAttr(nl.IFLA_BOND_SLAVE_QUEUE_ID, nl.Uint16Attr(bondSlave.QueueId))
|
||||
data.AddRtAttr(nl.IFLA_BOND_SLAVE_AD_AGGREGATOR_ID, nl.Uint16Attr(bondSlave.AggregatorId))
|
||||
data.AddRtAttr(nl.IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE, nl.Uint8Attr(bondSlave.AdActorOperPortState))
|
||||
data.AddRtAttr(nl.IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE, nl.Uint16Attr(bondSlave.AdPartnerOperPortState))
|
||||
|
||||
if mac := bondSlave.PermHardwareAddr; mac != nil {
|
||||
data.AddRtAttr(nl.IFLA_BOND_SLAVE_PERM_HWADDR, []byte(mac))
|
||||
}
|
||||
}
|
||||
|
||||
func parseBondSlaveData(slave LinkSlave, data []syscall.NetlinkRouteAttr) {
|
||||
bondSlave := slave.(*BondSlave)
|
||||
for i := range data {
|
||||
switch data[i].Attr.Type {
|
||||
case nl.IFLA_BOND_SLAVE_STATE:
|
||||
bondSlave.State = BondSlaveState(data[i].Value[0])
|
||||
case nl.IFLA_BOND_SLAVE_MII_STATUS:
|
||||
bondSlave.MiiStatus = BondSlaveMiiStatus(data[i].Value[0])
|
||||
case nl.IFLA_BOND_SLAVE_LINK_FAILURE_COUNT:
|
||||
bondSlave.LinkFailureCount = native.Uint32(data[i].Value[0:4])
|
||||
case nl.IFLA_BOND_SLAVE_PERM_HWADDR:
|
||||
bondSlave.PermHardwareAddr = net.HardwareAddr(data[i].Value[0:6])
|
||||
case nl.IFLA_BOND_SLAVE_QUEUE_ID:
|
||||
bondSlave.QueueId = native.Uint16(data[i].Value[0:2])
|
||||
case nl.IFLA_BOND_SLAVE_AD_AGGREGATOR_ID:
|
||||
bondSlave.AggregatorId = native.Uint16(data[i].Value[0:2])
|
||||
case nl.IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE:
|
||||
bondSlave.AdActorOperPortState = uint8(data[i].Value[0])
|
||||
case nl.IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE:
|
||||
bondSlave.AdPartnerOperPortState = native.Uint16(data[i].Value[0:2])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func parseIPVlanData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||
ipv := link.(*IPVlan)
|
||||
for _, datum := range data {
|
||||
if datum.Attr.Type == nl.IFLA_IPVLAN_MODE {
|
||||
switch datum.Attr.Type {
|
||||
case nl.IFLA_IPVLAN_MODE:
|
||||
ipv.Mode = IPVlanMode(native.Uint32(datum.Value[0:4]))
|
||||
return
|
||||
case nl.IFLA_IPVLAN_FLAG:
|
||||
ipv.Flag = IPVlanFlag(native.Uint32(datum.Value[0:4]))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2081,9 +2407,7 @@ func parseGretapData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||
case nl.IFLA_GRE_ENCAP_FLAGS:
|
||||
gre.EncapFlags = native.Uint16(datum.Value[0:2])
|
||||
case nl.IFLA_GRE_COLLECT_METADATA:
|
||||
if len(datum.Value) > 0 {
|
||||
gre.FlowBased = int8(datum.Value[0]) != 0
|
||||
}
|
||||
gre.FlowBased = true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2165,14 +2489,6 @@ func parseGretunData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||
}
|
||||
}
|
||||
|
||||
func parseLinkStats32(data []byte) *LinkStatistics {
|
||||
return (*LinkStatistics)((*LinkStatistics32)(unsafe.Pointer(&data[0:SizeofLinkStats32][0])).to64())
|
||||
}
|
||||
|
||||
func parseLinkStats64(data []byte) *LinkStatistics {
|
||||
return (*LinkStatistics)((*LinkStatistics64)(unsafe.Pointer(&data[0:SizeofLinkStats64][0])))
|
||||
}
|
||||
|
||||
func addXdpAttrs(xdp *LinkXdp, req *nl.NetlinkRequest) {
|
||||
attrs := nl.NewRtAttr(unix.IFLA_XDP|unix.NLA_F_NESTED, nil)
|
||||
b := make([]byte, 4)
|
||||
@@ -2266,6 +2582,55 @@ func parseIptunData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||
}
|
||||
}
|
||||
|
||||
func addIp6tnlAttrs(ip6tnl *Ip6tnl, linkInfo *nl.RtAttr) {
|
||||
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
|
||||
|
||||
if ip6tnl.Link != 0 {
|
||||
data.AddRtAttr(nl.IFLA_IPTUN_LINK, nl.Uint32Attr(ip6tnl.Link))
|
||||
}
|
||||
|
||||
ip := ip6tnl.Local.To16()
|
||||
if ip != nil {
|
||||
data.AddRtAttr(nl.IFLA_IPTUN_LOCAL, []byte(ip))
|
||||
}
|
||||
|
||||
ip = ip6tnl.Remote.To16()
|
||||
if ip != nil {
|
||||
data.AddRtAttr(nl.IFLA_IPTUN_REMOTE, []byte(ip))
|
||||
}
|
||||
|
||||
data.AddRtAttr(nl.IFLA_IPTUN_TTL, nl.Uint8Attr(ip6tnl.Ttl))
|
||||
data.AddRtAttr(nl.IFLA_IPTUN_TOS, nl.Uint8Attr(ip6tnl.Tos))
|
||||
data.AddRtAttr(nl.IFLA_IPTUN_ENCAP_LIMIT, nl.Uint8Attr(ip6tnl.EncapLimit))
|
||||
data.AddRtAttr(nl.IFLA_IPTUN_FLAGS, nl.Uint32Attr(ip6tnl.Flags))
|
||||
data.AddRtAttr(nl.IFLA_IPTUN_PROTO, nl.Uint8Attr(ip6tnl.Proto))
|
||||
data.AddRtAttr(nl.IFLA_IPTUN_FLOWINFO, nl.Uint32Attr(ip6tnl.FlowInfo))
|
||||
}
|
||||
|
||||
func parseIp6tnlData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||
ip6tnl := link.(*Ip6tnl)
|
||||
for _, datum := range data {
|
||||
switch datum.Attr.Type {
|
||||
case nl.IFLA_IPTUN_LOCAL:
|
||||
ip6tnl.Local = net.IP(datum.Value[:16])
|
||||
case nl.IFLA_IPTUN_REMOTE:
|
||||
ip6tnl.Remote = net.IP(datum.Value[:16])
|
||||
case nl.IFLA_IPTUN_TTL:
|
||||
ip6tnl.Ttl = uint8(datum.Value[0])
|
||||
case nl.IFLA_IPTUN_TOS:
|
||||
ip6tnl.Tos = uint8(datum.Value[0])
|
||||
case nl.IFLA_IPTUN_ENCAP_LIMIT:
|
||||
ip6tnl.EncapLimit = uint8(datum.Value[0])
|
||||
case nl.IFLA_IPTUN_FLAGS:
|
||||
ip6tnl.Flags = native.Uint32(datum.Value[:4])
|
||||
case nl.IFLA_IPTUN_PROTO:
|
||||
ip6tnl.Proto = uint8(datum.Value[0])
|
||||
case nl.IFLA_IPTUN_FLOWINFO:
|
||||
ip6tnl.FlowInfo = native.Uint32(datum.Value[:4])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func addSittunAttrs(sittun *Sittun, linkInfo *nl.RtAttr) {
|
||||
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
|
||||
|
||||
@@ -2483,11 +2848,34 @@ func parseVfInfo(data []syscall.NetlinkRouteAttr, id int) VfInfo {
|
||||
case nl.IFLA_VF_LINK_STATE:
|
||||
ls := nl.DeserializeVfLinkState(element.Value[:])
|
||||
vf.LinkState = ls.LinkState
|
||||
case nl.IFLA_VF_RATE:
|
||||
vfr := nl.DeserializeVfRate(element.Value[:])
|
||||
vf.MaxTxRate = vfr.MaxTxRate
|
||||
vf.MinTxRate = vfr.MinTxRate
|
||||
}
|
||||
}
|
||||
return vf
|
||||
}
|
||||
|
||||
func addXfrmiAttrs(xfrmi *Xfrmi, linkInfo *nl.RtAttr) {
|
||||
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
|
||||
data.AddRtAttr(nl.IFLA_XFRM_LINK, nl.Uint32Attr(uint32(xfrmi.ParentIndex)))
|
||||
data.AddRtAttr(nl.IFLA_XFRM_IF_ID, nl.Uint32Attr(xfrmi.Ifid))
|
||||
|
||||
}
|
||||
|
||||
func parseXfrmiData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||
xfrmi := link.(*Xfrmi)
|
||||
for _, datum := range data {
|
||||
switch datum.Attr.Type {
|
||||
case nl.IFLA_XFRM_LINK:
|
||||
xfrmi.ParentIndex = int(native.Uint32(datum.Value))
|
||||
case nl.IFLA_XFRM_IF_ID:
|
||||
xfrmi.Ifid = native.Uint32(datum.Value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LinkSetBondSlave add slave to bond link via ioctl interface.
|
||||
func LinkSetBondSlave(link Link, master *Bond) error {
|
||||
fd, err := getSocketUDP()
|
||||
@@ -2505,6 +2893,52 @@ func LinkSetBondSlave(link Link, master *Bond) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// LinkSetBondSlaveQueueId modify bond slave queue-id.
|
||||
func (h *Handle) LinkSetBondSlaveQueueId(link Link, queueId uint16) error {
|
||||
base := link.Attrs()
|
||||
h.ensureIndex(base)
|
||||
req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
|
||||
|
||||
msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
|
||||
msg.Index = int32(base.Index)
|
||||
req.AddData(msg)
|
||||
|
||||
linkInfo := nl.NewRtAttr(unix.IFLA_LINKINFO, nil)
|
||||
data := linkInfo.AddRtAttr(nl.IFLA_INFO_SLAVE_DATA, nil)
|
||||
data.AddRtAttr(nl.IFLA_BOND_SLAVE_QUEUE_ID, nl.Uint16Attr(queueId))
|
||||
|
||||
req.AddData(linkInfo)
|
||||
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
// LinkSetBondSlaveQueueId modify bond slave queue-id.
|
||||
func LinkSetBondSlaveQueueId(link Link, queueId uint16) error {
|
||||
return pkgHandle.LinkSetBondSlaveQueueId(link, queueId)
|
||||
}
|
||||
|
||||
func vethStatsSerialize(stats ethtoolStats) ([]byte, error) {
|
||||
statsSize := int(unsafe.Sizeof(stats)) + int(stats.nStats)*int(unsafe.Sizeof(uint64(0)))
|
||||
b := make([]byte, 0, statsSize)
|
||||
buf := bytes.NewBuffer(b)
|
||||
err := binary.Write(buf, nl.NativeEndian(), stats)
|
||||
return buf.Bytes()[:statsSize], err
|
||||
}
|
||||
|
||||
type vethEthtoolStats struct {
|
||||
Cmd uint32
|
||||
NStats uint32
|
||||
Peer uint64
|
||||
// Newer kernels have XDP stats in here, but we only care
|
||||
// to extract the peer ifindex here.
|
||||
}
|
||||
|
||||
func vethStatsDeserialize(b []byte) (vethEthtoolStats, error) {
|
||||
var stats = vethEthtoolStats{}
|
||||
err := binary.Read(bytes.NewReader(b), nl.NativeEndian(), &stats)
|
||||
return stats, err
|
||||
}
|
||||
|
||||
// VethPeerIndex get veth peer index.
|
||||
func VethPeerIndex(link *Veth) (int, error) {
|
||||
fd, err := getSocketUDP()
|
||||
@@ -2519,25 +2953,66 @@ func VethPeerIndex(link *Veth) (int, error) {
|
||||
return -1, fmt.Errorf("SIOCETHTOOL request for %q failed, errno=%v", link.Attrs().Name, errno)
|
||||
}
|
||||
|
||||
gstrings := ðtoolGstrings{
|
||||
cmd: ETHTOOL_GSTRINGS,
|
||||
stringSet: ETH_SS_STATS,
|
||||
length: sSet.data[0],
|
||||
stats := ethtoolStats{
|
||||
cmd: ETHTOOL_GSTATS,
|
||||
nStats: sSet.data[0],
|
||||
}
|
||||
ifreq.Data = uintptr(unsafe.Pointer(gstrings))
|
||||
|
||||
buffer, err := vethStatsSerialize(stats)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
ifreq.Data = uintptr(unsafe.Pointer(&buffer[0]))
|
||||
_, _, errno = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), SIOCETHTOOL, uintptr(unsafe.Pointer(ifreq)))
|
||||
if errno != 0 {
|
||||
return -1, fmt.Errorf("SIOCETHTOOL request for %q failed, errno=%v", link.Attrs().Name, errno)
|
||||
}
|
||||
|
||||
stats := ðtoolStats{
|
||||
cmd: ETHTOOL_GSTATS,
|
||||
nStats: gstrings.length,
|
||||
vstats, err := vethStatsDeserialize(buffer)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
ifreq.Data = uintptr(unsafe.Pointer(stats))
|
||||
_, _, errno = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), SIOCETHTOOL, uintptr(unsafe.Pointer(ifreq)))
|
||||
if errno != 0 {
|
||||
return -1, fmt.Errorf("SIOCETHTOOL request for %q failed, errno=%v", link.Attrs().Name, errno)
|
||||
}
|
||||
return int(stats.data[0]), nil
|
||||
|
||||
return int(vstats.Peer), nil
|
||||
}
|
||||
|
||||
func parseTuntapData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||
tuntap := link.(*Tuntap)
|
||||
for _, datum := range data {
|
||||
switch datum.Attr.Type {
|
||||
case nl.IFLA_TUN_OWNER:
|
||||
tuntap.Owner = native.Uint32(datum.Value)
|
||||
case nl.IFLA_TUN_GROUP:
|
||||
tuntap.Group = native.Uint32(datum.Value)
|
||||
case nl.IFLA_TUN_TYPE:
|
||||
tuntap.Mode = TuntapMode(uint8(datum.Value[0]))
|
||||
case nl.IFLA_TUN_PERSIST:
|
||||
tuntap.NonPersist = false
|
||||
if uint8(datum.Value[0]) == 0 {
|
||||
tuntap.NonPersist = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func parseIPoIBData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||
ipoib := link.(*IPoIB)
|
||||
for _, datum := range data {
|
||||
switch datum.Attr.Type {
|
||||
case nl.IFLA_IPOIB_PKEY:
|
||||
ipoib.Pkey = uint16(native.Uint16(datum.Value))
|
||||
case nl.IFLA_IPOIB_MODE:
|
||||
ipoib.Mode = IPoIBMode(native.Uint16(datum.Value))
|
||||
case nl.IFLA_IPOIB_UMCAST:
|
||||
ipoib.Umcast = uint16(native.Uint16(datum.Value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func addIPoIBAttrs(ipoib *IPoIB, linkInfo *nl.RtAttr) {
|
||||
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
|
||||
data.AddRtAttr(nl.IFLA_IPOIB_PKEY, nl.Uint16Attr(uint16(ipoib.Pkey)))
|
||||
data.AddRtAttr(nl.IFLA_IPOIB_MODE, nl.Uint16Attr(uint16(ipoib.Mode)))
|
||||
data.AddRtAttr(nl.IFLA_IPOIB_UMCAST, nl.Uint16Attr(uint16(ipoib.Umcast)))
|
||||
}
|
||||
|
Reference in New Issue
Block a user