mirror of
https://github.com/jsimonetti/rtnetlink.git
synced 2026-03-27 23:11:06 +01:00
Add drivers for bridge, macvlan, vlan, vxlan and add helpers to LinkService to use them (SetMaster, RemoveMaster) Signed-off-by: Jeroen Simonetti <jeroen@simonetti.nl>
181 lines
4.3 KiB
Go
181 lines
4.3 KiB
Go
package driver
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/jsimonetti/rtnetlink/v2"
|
|
"github.com/jsimonetti/rtnetlink/v2/internal/unix"
|
|
|
|
"github.com/mdlayher/netlink"
|
|
)
|
|
|
|
// MacvlanMode represents the MACVLAN operating mode.
|
|
type MacvlanMode uint32
|
|
|
|
// MACVLAN modes.
|
|
const (
|
|
MacvlanModePrivate MacvlanMode = 0x1
|
|
MacvlanModeVEPA MacvlanMode = 0x2
|
|
MacvlanModeBridge MacvlanMode = 0x4
|
|
MacvlanModePassthru MacvlanMode = 0x8
|
|
MacvlanModeSource MacvlanMode = 0x10
|
|
)
|
|
|
|
// String returns a string representation of the MacvlanMode.
|
|
func (m MacvlanMode) String() string {
|
|
switch m {
|
|
case MacvlanModePrivate:
|
|
return "private"
|
|
case MacvlanModeVEPA:
|
|
return "vepa"
|
|
case MacvlanModeBridge:
|
|
return "bridge"
|
|
case MacvlanModePassthru:
|
|
return "passthru"
|
|
case MacvlanModeSource:
|
|
return "source"
|
|
default:
|
|
return fmt.Sprintf("unknown MacvlanMode value (%d)", m)
|
|
}
|
|
}
|
|
|
|
// MacvlanFlag represents MACVLAN flags.
|
|
type MacvlanFlag uint16
|
|
|
|
// MACVLAN flags.
|
|
const (
|
|
MacvlanFlagNopromisc MacvlanFlag = 0x1
|
|
MacvlanFlagNodst MacvlanFlag = 0x2
|
|
)
|
|
|
|
// MacvlanMacaddrMode represents the MACVLAN MAC address mode.
|
|
type MacvlanMacaddrMode uint32
|
|
|
|
// MACVLAN MAC address modes.
|
|
const (
|
|
MacvlanMacaddrAdd MacvlanMacaddrMode = 0x0
|
|
MacvlanMacaddrDel MacvlanMacaddrMode = 0x1
|
|
MacvlanMacaddrFlush MacvlanMacaddrMode = 0x2
|
|
MacvlanMacaddrSet MacvlanMacaddrMode = 0x3
|
|
)
|
|
|
|
// Macvlan represents a MACVLAN device configuration.
|
|
type Macvlan struct {
|
|
// Mode specifies the MACVLAN mode (private, vepa, bridge, passthru, source).
|
|
Mode *MacvlanMode
|
|
|
|
// Flags specifies MACVLAN flags (nopromisc, nodst).
|
|
Flags *MacvlanFlag
|
|
|
|
// MacaddrMode specifies the MAC address mode for source mode.
|
|
MacaddrMode *MacvlanMacaddrMode
|
|
|
|
// MacaddrData contains MAC addresses for source mode.
|
|
MacaddrData [][]byte
|
|
|
|
// MacaddrCount specifies the number of MAC addresses in source mode.
|
|
MacaddrCount *uint32
|
|
|
|
// BcQueueLen specifies the broadcast queue length.
|
|
BcQueueLen *uint32
|
|
|
|
// BcQueueLenUsed indicates if the broadcast queue length is being used.
|
|
BcQueueLenUsed *uint8
|
|
|
|
// BcCutoff specifies the broadcast cutoff value.
|
|
BcCutoff *int32
|
|
}
|
|
|
|
var _ rtnetlink.LinkDriver = &Macvlan{}
|
|
|
|
// New creates a new Macvlan instance.
|
|
func (m *Macvlan) New() rtnetlink.LinkDriver {
|
|
return &Macvlan{}
|
|
}
|
|
|
|
// Kind returns the MACVLAN interface kind.
|
|
func (m *Macvlan) Kind() string {
|
|
return "macvlan"
|
|
}
|
|
|
|
// Encode encodes the MACVLAN configuration into netlink attributes.
|
|
func (m *Macvlan) Encode(ae *netlink.AttributeEncoder) error {
|
|
|
|
if m.Mode != nil {
|
|
ae.Uint32(unix.IFLA_MACVLAN_MODE, uint32(*m.Mode))
|
|
}
|
|
|
|
if m.Flags != nil {
|
|
ae.Uint16(unix.IFLA_MACVLAN_FLAGS, uint16(*m.Flags))
|
|
}
|
|
|
|
if m.MacaddrMode != nil {
|
|
ae.Uint32(unix.IFLA_MACVLAN_MACADDR_MODE, uint32(*m.MacaddrMode))
|
|
}
|
|
|
|
if len(m.MacaddrData) > 0 {
|
|
ae.Nested(unix.IFLA_MACVLAN_MACADDR_DATA, func(nae *netlink.AttributeEncoder) error {
|
|
for i, mac := range m.MacaddrData {
|
|
nae.Bytes(uint16(i), mac)
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
if m.MacaddrCount != nil {
|
|
ae.Uint32(unix.IFLA_MACVLAN_MACADDR_COUNT, *m.MacaddrCount)
|
|
}
|
|
|
|
if m.BcQueueLen != nil {
|
|
ae.Uint32(unix.IFLA_MACVLAN_BC_QUEUE_LEN, *m.BcQueueLen)
|
|
}
|
|
|
|
if m.BcQueueLenUsed != nil {
|
|
ae.Uint8(unix.IFLA_MACVLAN_BC_QUEUE_LEN_USED, *m.BcQueueLenUsed)
|
|
}
|
|
|
|
if m.BcCutoff != nil {
|
|
ae.Int32(unix.IFLA_MACVLAN_BC_CUTOFF, *m.BcCutoff)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Decode decodes netlink attributes into the MACVLAN configuration.
|
|
func (m *Macvlan) Decode(ad *netlink.AttributeDecoder) error {
|
|
for ad.Next() {
|
|
switch ad.Type() {
|
|
case unix.IFLA_MACVLAN_MODE:
|
|
mode := MacvlanMode(ad.Uint32())
|
|
m.Mode = &mode
|
|
case unix.IFLA_MACVLAN_FLAGS:
|
|
flags := MacvlanFlag(ad.Uint16())
|
|
m.Flags = &flags
|
|
case unix.IFLA_MACVLAN_MACADDR_MODE:
|
|
macaddrMode := MacvlanMacaddrMode(ad.Uint32())
|
|
m.MacaddrMode = &macaddrMode
|
|
case unix.IFLA_MACVLAN_MACADDR_DATA:
|
|
ad.Nested(func(nad *netlink.AttributeDecoder) error {
|
|
for nad.Next() {
|
|
m.MacaddrData = append(m.MacaddrData, nad.Bytes())
|
|
}
|
|
return nad.Err()
|
|
})
|
|
case unix.IFLA_MACVLAN_MACADDR_COUNT:
|
|
count := ad.Uint32()
|
|
m.MacaddrCount = &count
|
|
case unix.IFLA_MACVLAN_BC_QUEUE_LEN:
|
|
qlen := ad.Uint32()
|
|
m.BcQueueLen = &qlen
|
|
case unix.IFLA_MACVLAN_BC_QUEUE_LEN_USED:
|
|
used := ad.Uint8()
|
|
m.BcQueueLenUsed = &used
|
|
case unix.IFLA_MACVLAN_BC_CUTOFF:
|
|
cutoff := ad.Int32()
|
|
m.BcCutoff = &cutoff
|
|
}
|
|
}
|
|
|
|
return ad.Err()
|
|
}
|