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:
Federico Paolinelli
2020-09-04 16:33:07 +02:00
parent 8d0d8a9547
commit 362f5d626a
271 changed files with 25100 additions and 90453 deletions

View File

@@ -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 = &GTP{}
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 := &ethtoolGstrings{
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 := &ethtoolStats{
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)))
}