add SetVfHardwareAddr and SetVfVlan to link

This commit is contained in:
Vishvananda Ishaya 2016-02-15 14:31:32 -08:00
parent b495efb88c
commit 377a621360
3 changed files with 459 additions and 0 deletions

View File

@ -142,6 +142,54 @@ func LinkSetHardwareAddr(link Link, hwaddr net.HardwareAddr) error {
return err
}
// LinkSetVfHardwareAddr sets the hardware address of a vf for the link.
// Equivalent to: `ip link set $link vf $vf mac $hwaddr`
func LinkSetVfHardwareAddr(link Link, vf int, hwaddr net.HardwareAddr) error {
base := link.Attrs()
ensureIndex(base)
req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
msg.Index = int32(base.Index)
req.AddData(msg)
data := nl.NewRtAttr(nl.IFLA_VFINFO_LIST, nil)
info := nl.NewRtAttrChild(data, nl.IFLA_VF_INFO, nil)
vfmsg := nl.VfMac{
Vf: uint32(vf),
}
copy(vfmsg.Mac[:], []byte(hwaddr))
nl.NewRtAttrChild(info, nl.IFLA_VF_MAC, vfmsg.Serialize())
req.AddData(data)
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
return err
}
// LinkSetVfVlan sets the vlan of a vf for the link.
// Equivalent to: `ip link set $link vf $vf vlan $vlan`
func LinkSetVfVlan(link Link, vf, vlan int) error {
base := link.Attrs()
ensureIndex(base)
req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
msg.Index = int32(base.Index)
req.AddData(msg)
data := nl.NewRtAttr(nl.IFLA_VFINFO_LIST, nil)
info := nl.NewRtAttrChild(data, nl.IFLA_VF_INFO, nil)
vfmsg := nl.VfVlan{
Vf: uint32(vf),
Vlan: uint32(vlan),
}
nl.NewRtAttrChild(info, nl.IFLA_VF_VLAN, vfmsg.Serialize())
req.AddData(data)
_, err := req.Execute(syscall.NETLINK_ROUTE, 0)
return err
}
// LinkSetMaster sets the master of the link device.
// Equivalent to: `ip link set $link master $master`
func LinkSetMaster(link Link, master *Bridge) error {

View File

@ -1,7 +1,13 @@
package nl
import (
"unsafe"
)
const (
DEFAULT_CHANGE = 0xFFFFFFFF
// doesn't exist in syscall
IFLA_VFINFO_LIST = 0x16
)
const (
@ -182,3 +188,209 @@ const (
GRE_FLAGS = 0x00F8
GRE_VERSION = 0x0007
)
const (
IFLA_VF_INFO_UNSPEC = iota
IFLA_VF_INFO
IFLA_VF_INFO_MAX = IFLA_VF_INFO
)
const (
IFLA_VF_UNSPEC = iota
IFLA_VF_MAC /* Hardware queue specific attributes */
IFLA_VF_VLAN
IFLA_VF_TX_RATE /* Max TX Bandwidth Allocation */
IFLA_VF_SPOOFCHK /* Spoof Checking on/off switch */
IFLA_VF_LINK_STATE /* link state enable/disable/auto switch */
IFLA_VF_RATE /* Min and Max TX Bandwidth Allocation */
IFLA_VF_RSS_QUERY_EN /* RSS Redirection Table and Hash Key query
* on/off switch
*/
IFLA_VF_STATS /* network device statistics */
IFLA_VF_MAX = IFLA_VF_STATS
)
const (
IFLA_VF_LINK_STATE_AUTO = iota /* link state of the uplink */
IFLA_VF_LINK_STATE_ENABLE /* link always up */
IFLA_VF_LINK_STATE_DISABLE /* link always down */
IFLA_VF_LINK_STATE_MAX = IFLA_VF_LINK_STATE_DISABLE
)
const (
IFLA_VF_STATS_RX_PACKETS = iota
IFLA_VF_STATS_TX_PACKETS
IFLA_VF_STATS_RX_BYTES
IFLA_VF_STATS_TX_BYTES
IFLA_VF_STATS_BROADCAST
IFLA_VF_STATS_MULTICAST
IFLA_VF_STATS_MAX = IFLA_VF_STATS_MULTICAST
)
const (
SizeofVfMac = 0x24
SizeofVfVlan = 0x0c
SizeofVfTxRate = 0x08
SizeofVfRate = 0x0c
SizeofVfSpoofchk = 0x08
SizeofVfLinkState = 0x08
SizeofVfRssQueryEn = 0x08
)
// struct ifla_vf_mac {
// __u32 vf;
// __u8 mac[32]; /* MAX_ADDR_LEN */
// };
type VfMac struct {
Vf uint32
Mac [32]byte
}
func (msg *VfMac) Len() int {
return SizeofVfMac
}
func DeserializeVfMac(b []byte) *VfMac {
return (*VfMac)(unsafe.Pointer(&b[0:SizeofVfMac][0]))
}
func (msg *VfMac) Serialize() []byte {
return (*(*[SizeofVfMac]byte)(unsafe.Pointer(msg)))[:]
}
// struct ifla_vf_vlan {
// __u32 vf;
// __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */
// __u32 qos;
// };
type VfVlan struct {
Vf uint32
Vlan uint32
Qos uint32
}
func (msg *VfVlan) Len() int {
return SizeofVfVlan
}
func DeserializeVfVlan(b []byte) *VfVlan {
return (*VfVlan)(unsafe.Pointer(&b[0:SizeofVfVlan][0]))
}
func (msg *VfVlan) Serialize() []byte {
return (*(*[SizeofVfVlan]byte)(unsafe.Pointer(msg)))[:]
}
// struct ifla_vf_tx_rate {
// __u32 vf;
// __u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */
// };
type VfTxRate struct {
Vf uint32
Rate uint32
}
func (msg *VfTxRate) Len() int {
return SizeofVfTxRate
}
func DeserializeVfTxRate(b []byte) *VfTxRate {
return (*VfTxRate)(unsafe.Pointer(&b[0:SizeofVfTxRate][0]))
}
func (msg *VfTxRate) Serialize() []byte {
return (*(*[SizeofVfTxRate]byte)(unsafe.Pointer(msg)))[:]
}
// struct ifla_vf_rate {
// __u32 vf;
// __u32 min_tx_rate; /* Min Bandwidth in Mbps */
// __u32 max_tx_rate; /* Max Bandwidth in Mbps */
// };
type VfRate struct {
Vf uint32
MinTxRate uint32
MaxTxRate uint32
}
func (msg *VfRate) Len() int {
return SizeofVfRate
}
func DeserializeVfRate(b []byte) *VfRate {
return (*VfRate)(unsafe.Pointer(&b[0:SizeofVfRate][0]))
}
func (msg *VfRate) Serialize() []byte {
return (*(*[SizeofVfRate]byte)(unsafe.Pointer(msg)))[:]
}
// struct ifla_vf_spoofchk {
// __u32 vf;
// __u32 setting;
// };
type VfSpoofchk struct {
Vf uint32
Setting uint32
}
func (msg *VfSpoofchk) Len() int {
return SizeofVfSpoofchk
}
func DeserializeVfSpoofchk(b []byte) *VfSpoofchk {
return (*VfSpoofchk)(unsafe.Pointer(&b[0:SizeofVfSpoofchk][0]))
}
func (msg *VfSpoofchk) Serialize() []byte {
return (*(*[SizeofVfSpoofchk]byte)(unsafe.Pointer(msg)))[:]
}
// struct ifla_vf_link_state {
// __u32 vf;
// __u32 link_state;
// };
type VfLinkState struct {
Vf uint32
LinkState uint32
}
func (msg *VfLinkState) Len() int {
return SizeofVfLinkState
}
func DeserializeVfLinkState(b []byte) *VfLinkState {
return (*VfLinkState)(unsafe.Pointer(&b[0:SizeofVfLinkState][0]))
}
func (msg *VfLinkState) Serialize() []byte {
return (*(*[SizeofVfLinkState]byte)(unsafe.Pointer(msg)))[:]
}
// struct ifla_vf_rss_query_en {
// __u32 vf;
// __u32 setting;
// };
type VfRssQueryEn struct {
Vf uint32
Setting uint32
}
func (msg *VfRssQueryEn) Len() int {
return SizeofVfRssQueryEn
}
func DeserializeVfRssQueryEn(b []byte) *VfRssQueryEn {
return (*VfRssQueryEn)(unsafe.Pointer(&b[0:SizeofVfRssQueryEn][0]))
}
func (msg *VfRssQueryEn) Serialize() []byte {
return (*(*[SizeofVfRssQueryEn]byte)(unsafe.Pointer(msg)))[:]
}

199
nl/link_linux_test.go Normal file
View File

@ -0,0 +1,199 @@
package nl
import (
"bytes"
"crypto/rand"
"encoding/binary"
"testing"
)
func (msg *VfMac) write(b []byte) {
native := NativeEndian()
native.PutUint32(b[0:4], uint32(msg.Vf))
copy(b[4:36], msg.Mac[:])
}
func (msg *VfMac) serializeSafe() []byte {
length := SizeofVfMac
b := make([]byte, length)
msg.write(b)
return b
}
func deserializeVfMacSafe(b []byte) *VfMac {
var msg = VfMac{}
binary.Read(bytes.NewReader(b[0:SizeofVfMac]), NativeEndian(), &msg)
return &msg
}
func TestVfMacDeserializeSerialize(t *testing.T) {
var orig = make([]byte, SizeofVfMac)
rand.Read(orig)
safemsg := deserializeVfMacSafe(orig)
msg := DeserializeVfMac(orig)
testDeserializeSerialize(t, orig, safemsg, msg)
}
func (msg *VfVlan) write(b []byte) {
native := NativeEndian()
native.PutUint32(b[0:4], uint32(msg.Vf))
native.PutUint32(b[4:8], uint32(msg.Vlan))
native.PutUint32(b[8:12], uint32(msg.Qos))
}
func (msg *VfVlan) serializeSafe() []byte {
length := SizeofVfVlan
b := make([]byte, length)
msg.write(b)
return b
}
func deserializeVfVlanSafe(b []byte) *VfVlan {
var msg = VfVlan{}
binary.Read(bytes.NewReader(b[0:SizeofVfVlan]), NativeEndian(), &msg)
return &msg
}
func TestVfVlanDeserializeSerialize(t *testing.T) {
var orig = make([]byte, SizeofVfVlan)
rand.Read(orig)
safemsg := deserializeVfVlanSafe(orig)
msg := DeserializeVfVlan(orig)
testDeserializeSerialize(t, orig, safemsg, msg)
}
func (msg *VfTxRate) write(b []byte) {
native := NativeEndian()
native.PutUint32(b[0:4], uint32(msg.Vf))
native.PutUint32(b[4:8], uint32(msg.Rate))
}
func (msg *VfTxRate) serializeSafe() []byte {
length := SizeofVfTxRate
b := make([]byte, length)
msg.write(b)
return b
}
func deserializeVfTxRateSafe(b []byte) *VfTxRate {
var msg = VfTxRate{}
binary.Read(bytes.NewReader(b[0:SizeofVfTxRate]), NativeEndian(), &msg)
return &msg
}
func TestVfTxRateDeserializeSerialize(t *testing.T) {
var orig = make([]byte, SizeofVfTxRate)
rand.Read(orig)
safemsg := deserializeVfTxRateSafe(orig)
msg := DeserializeVfTxRate(orig)
testDeserializeSerialize(t, orig, safemsg, msg)
}
func (msg *VfRate) write(b []byte) {
native := NativeEndian()
native.PutUint32(b[0:4], uint32(msg.Vf))
native.PutUint32(b[4:8], uint32(msg.MinTxRate))
native.PutUint32(b[8:12], uint32(msg.MaxTxRate))
}
func (msg *VfRate) serializeSafe() []byte {
length := SizeofVfRate
b := make([]byte, length)
msg.write(b)
return b
}
func deserializeVfRateSafe(b []byte) *VfRate {
var msg = VfRate{}
binary.Read(bytes.NewReader(b[0:SizeofVfRate]), NativeEndian(), &msg)
return &msg
}
func TestVfRateDeserializeSerialize(t *testing.T) {
var orig = make([]byte, SizeofVfRate)
rand.Read(orig)
safemsg := deserializeVfRateSafe(orig)
msg := DeserializeVfRate(orig)
testDeserializeSerialize(t, orig, safemsg, msg)
}
func (msg *VfSpoofchk) write(b []byte) {
native := NativeEndian()
native.PutUint32(b[0:4], uint32(msg.Vf))
native.PutUint32(b[4:8], uint32(msg.Setting))
}
func (msg *VfSpoofchk) serializeSafe() []byte {
length := SizeofVfSpoofchk
b := make([]byte, length)
msg.write(b)
return b
}
func deserializeVfSpoofchkSafe(b []byte) *VfSpoofchk {
var msg = VfSpoofchk{}
binary.Read(bytes.NewReader(b[0:SizeofVfSpoofchk]), NativeEndian(), &msg)
return &msg
}
func TestVfSpoofchkDeserializeSerialize(t *testing.T) {
var orig = make([]byte, SizeofVfSpoofchk)
rand.Read(orig)
safemsg := deserializeVfSpoofchkSafe(orig)
msg := DeserializeVfSpoofchk(orig)
testDeserializeSerialize(t, orig, safemsg, msg)
}
func (msg *VfLinkState) write(b []byte) {
native := NativeEndian()
native.PutUint32(b[0:4], uint32(msg.Vf))
native.PutUint32(b[4:8], uint32(msg.LinkState))
}
func (msg *VfLinkState) serializeSafe() []byte {
length := SizeofVfLinkState
b := make([]byte, length)
msg.write(b)
return b
}
func deserializeVfLinkStateSafe(b []byte) *VfLinkState {
var msg = VfLinkState{}
binary.Read(bytes.NewReader(b[0:SizeofVfLinkState]), NativeEndian(), &msg)
return &msg
}
func TestVfLinkStateDeserializeSerialize(t *testing.T) {
var orig = make([]byte, SizeofVfLinkState)
rand.Read(orig)
safemsg := deserializeVfLinkStateSafe(orig)
msg := DeserializeVfLinkState(orig)
testDeserializeSerialize(t, orig, safemsg, msg)
}
func (msg *VfRssQueryEn) write(b []byte) {
native := NativeEndian()
native.PutUint32(b[0:4], uint32(msg.Vf))
native.PutUint32(b[4:8], uint32(msg.Setting))
}
func (msg *VfRssQueryEn) serializeSafe() []byte {
length := SizeofVfRssQueryEn
b := make([]byte, length)
msg.write(b)
return b
}
func deserializeVfRssQueryEnSafe(b []byte) *VfRssQueryEn {
var msg = VfRssQueryEn{}
binary.Read(bytes.NewReader(b[0:SizeofVfRssQueryEn]), NativeEndian(), &msg)
return &msg
}
func TestVfRssQueryEnDeserializeSerialize(t *testing.T) {
var orig = make([]byte, SizeofVfRssQueryEn)
rand.Read(orig)
safemsg := deserializeVfRssQueryEnSafe(orig)
msg := DeserializeVfRssQueryEn(orig)
testDeserializeSerialize(t, orig, safemsg, msg)
}