mirror of
https://github.com/vishvananda/netlink
synced 2025-01-30 11:44:30 +00:00
Add bond slave information
This PR refers to PR@lebauce and add some changes. - Added some tests to retrieve bond slave information. - Link.BondSlave is changed to LinkSlave interface. - BondSlaveState.String() returns UPPER case. (same as iproute2) - BondSlaveMiiStatus.String() returns UPPER case. (same as iproute2)
This commit is contained in:
parent
e906d22624
commit
205a160d2e
68
link.go
68
link.go
@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Link represents a link device from netlink. Shared link attributes
|
||||
@ -45,6 +46,12 @@ type LinkAttrs struct {
|
||||
GSOMaxSegs uint32
|
||||
Vfs []VfInfo // virtual functions available on link
|
||||
Group uint32
|
||||
Slave LinkSlave
|
||||
}
|
||||
|
||||
// LinkSlave represents a slave device.
|
||||
type LinkSlave interface {
|
||||
SlaveType() string
|
||||
}
|
||||
|
||||
// VfInfo represents configuration of virtual function
|
||||
@ -749,6 +756,67 @@ func (bond *Bond) Type() string {
|
||||
return "bond"
|
||||
}
|
||||
|
||||
// BondSlaveState represents the values of the IFLA_BOND_SLAVE_STATE bond slave
|
||||
// attribute, which contains the state of the bond slave.
|
||||
type BondSlaveState uint8
|
||||
|
||||
const (
|
||||
BondStateActive = iota // Link is active.
|
||||
BondStateBackup // Link is backup.
|
||||
)
|
||||
|
||||
func (s BondSlaveState) String() string {
|
||||
switch s {
|
||||
case BondStateActive:
|
||||
return "ACTIVE"
|
||||
case BondStateBackup:
|
||||
return "BACKUP"
|
||||
default:
|
||||
return strconv.Itoa(int(s))
|
||||
}
|
||||
}
|
||||
|
||||
// BondSlaveState represents the values of the IFLA_BOND_SLAVE_MII_STATUS bond slave
|
||||
// attribute, which contains the status of MII link monitoring
|
||||
type BondSlaveMiiStatus uint8
|
||||
|
||||
const (
|
||||
BondLinkUp = iota // link is up and running.
|
||||
BondLinkFail // link has just gone down.
|
||||
BondLinkDown // link has been down for too long time.
|
||||
BondLinkBack // link is going back.
|
||||
)
|
||||
|
||||
func (s BondSlaveMiiStatus) String() string {
|
||||
switch s {
|
||||
case BondLinkUp:
|
||||
return "UP"
|
||||
case BondLinkFail:
|
||||
return "GOING_DOWN"
|
||||
case BondLinkDown:
|
||||
return "DOWN"
|
||||
case BondLinkBack:
|
||||
return "GOING_BACK"
|
||||
default:
|
||||
return strconv.Itoa(int(s))
|
||||
}
|
||||
}
|
||||
|
||||
type BondSlave struct {
|
||||
State BondSlaveState
|
||||
MiiStatus BondSlaveMiiStatus
|
||||
LinkFailureCount uint32
|
||||
PermHardwareAddr net.HardwareAddr
|
||||
QueueId uint16
|
||||
AggregatorId uint16
|
||||
AdActorOperPortState uint8
|
||||
AdPartnerOperPortState uint16
|
||||
}
|
||||
|
||||
func (b *BondSlave) SlaveType() string {
|
||||
return "bond"
|
||||
}
|
||||
|
||||
// Gretap devices must specify LocalIP and RemoteIP on create
|
||||
type Gretap struct {
|
||||
LinkAttrs
|
||||
|
@ -1476,10 +1476,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 []byte
|
||||
stats64 []byte
|
||||
linkType string
|
||||
linkSlave LinkSlave
|
||||
slaveType string
|
||||
)
|
||||
for _, attr := range attrs {
|
||||
switch attr.Attr.Type {
|
||||
@ -1585,6 +1587,21 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
case unix.IFLA_ADDRESS:
|
||||
@ -1667,6 +1684,7 @@ 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
|
||||
@ -2131,6 +2149,46 @@ func parseBondData(link Link, data []syscall.NetlinkRouteAttr) {
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
@ -2725,6 +2783,30 @@ 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)
|
||||
}
|
||||
|
||||
// VethPeerIndex get veth peer index.
|
||||
func VethPeerIndex(link *Veth) (int, error) {
|
||||
fd, err := getSocketUDP()
|
||||
|
75
link_test.go
75
link_test.go
@ -2035,6 +2035,81 @@ func TestVethPeerIndex(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLinkSlaveBond(t *testing.T) {
|
||||
minKernelRequired(t, 3, 13)
|
||||
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
const (
|
||||
bondName = "foo"
|
||||
slaveName = "fooFoo"
|
||||
)
|
||||
|
||||
bond := NewLinkBond(LinkAttrs{Name: bondName})
|
||||
bond.Mode = BOND_MODE_BALANCE_RR
|
||||
if err := LinkAdd(bond); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer LinkDel(bond)
|
||||
|
||||
slaveDummy := &Dummy{LinkAttrs{Name: slaveName}}
|
||||
if err := LinkAdd(slaveDummy); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer LinkDel(slaveDummy)
|
||||
|
||||
if err := LinkSetBondSlave(slaveDummy, bond); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
slaveLink, err := LinkByName(slaveName)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
slave := slaveLink.Attrs().Slave
|
||||
if slave == nil {
|
||||
t.Errorf("for %s expected slave is not nil.", slaveName)
|
||||
}
|
||||
|
||||
if slaveType := slave.SlaveType(); slaveType != "bond" {
|
||||
t.Errorf("for %s expected slave type is 'bond', but '%s'", slaveName, slaveType)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLinkSetBondSlaveQueueId(t *testing.T) {
|
||||
minKernelRequired(t, 3, 13)
|
||||
|
||||
tearDown := setUpNetlinkTest(t)
|
||||
defer tearDown()
|
||||
|
||||
const (
|
||||
bondName = "foo"
|
||||
slave1Name = "fooFoo"
|
||||
)
|
||||
|
||||
bond := NewLinkBond(LinkAttrs{Name: bondName})
|
||||
if err := LinkAdd(bond); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer LinkDel(bond)
|
||||
|
||||
slave := &Dummy{LinkAttrs{Name: slave1Name}}
|
||||
if err := LinkAdd(slave); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer LinkDel(slave)
|
||||
|
||||
if err := LinkSetBondSlave(slave, bond); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := pkgHandle.LinkSetBondSlaveQueueId(slave, 1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLinkSetBondSlave(t *testing.T) {
|
||||
minKernelRequired(t, 3, 13)
|
||||
|
||||
|
@ -13,7 +13,9 @@ const (
|
||||
IFLA_INFO_KIND
|
||||
IFLA_INFO_DATA
|
||||
IFLA_INFO_XSTATS
|
||||
IFLA_INFO_MAX = IFLA_INFO_XSTATS
|
||||
IFLA_INFO_SLAVE_KIND
|
||||
IFLA_INFO_SLAVE_DATA
|
||||
IFLA_INFO_MAX = IFLA_INFO_SLAVE_DATA
|
||||
)
|
||||
|
||||
const (
|
||||
@ -165,6 +167,8 @@ const (
|
||||
IFLA_BOND_SLAVE_PERM_HWADDR
|
||||
IFLA_BOND_SLAVE_QUEUE_ID
|
||||
IFLA_BOND_SLAVE_AD_AGGREGATOR_ID
|
||||
IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE
|
||||
IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE
|
||||
)
|
||||
|
||||
const (
|
||||
|
Loading…
Reference in New Issue
Block a user