Skip to content

Commit

Permalink
Add link netkit
Browse files Browse the repository at this point in the history
This commit introduces the LinkNetkit type into LinkAttributes,
facilitating Netkit data's encoding to and decoding from the LinkInfo.Data field.

This addition prioritizes backward compatibility and introduces necessary condition checks.
For decoding, if the LinkInfo kind is netkit, the data within LinkInfo.Data is decoded to the Netkit field.
During encoding, Netkit data is encoded into LinkInfo.Data with LinkInfo.Kind set as netkit.
Concurrent settings of LinkInfo and Netkit during encoding trigger an error to maintain integrity.

Signed-off-by: Birol Bilgin <[email protected]>
  • Loading branch information
brlbil committed Apr 3, 2024
1 parent e96eaa2 commit 4a21d97
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 0 deletions.
12 changes: 12 additions & 0 deletions internal/unix/types_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ const (
IFLA_INFO_SLAVE_KIND = linux.IFLA_INFO_SLAVE_KIND
IFLA_INFO_DATA = linux.IFLA_INFO_DATA
IFLA_INFO_SLAVE_DATA = linux.IFLA_INFO_SLAVE_DATA
IFLA_NETKIT_UNSPEC = linux.IFLA_NETKIT_UNSPEC
IFLA_NETKIT_PEER_INFO = linux.IFLA_NETKIT_PEER_INFO
IFLA_NETKIT_PRIMARY = linux.IFLA_NETKIT_PRIMARY
IFLA_NETKIT_POLICY = linux.IFLA_NETKIT_POLICY
IFLA_NETKIT_PEER_POLICY = linux.IFLA_NETKIT_PEER_POLICY
IFLA_NETKIT_MODE = linux.IFLA_NETKIT_MODE
IFLA_XDP = linux.IFLA_XDP
IFLA_XDP_FD = linux.IFLA_XDP_FD
IFLA_XDP_ATTACHED = linux.IFLA_XDP_ATTACHED
Expand Down Expand Up @@ -147,4 +153,10 @@ const (
FRA_IP_PROTO = linux.FRA_IP_PROTO
FRA_SPORT_RANGE = linux.FRA_SPORT_RANGE
FRA_DPORT_RANGE = linux.FRA_DPORT_RANGE
NETKIT_NEXT = linux.NETKIT_NEXT
NETKIT_PASS = linux.NETKIT_PASS
NETKIT_DROP = linux.NETKIT_DROP
NETKIT_REDIRECT = linux.NETKIT_REDIRECT
NETKIT_L2 = linux.NETKIT_L2
NETKIT_L3 = linux.NETKIT_L3
)
12 changes: 12 additions & 0 deletions internal/unix/types_other.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ const (
IFLA_INFO_SLAVE_KIND = 0x4
IFLA_INFO_DATA = 0x2
IFLA_INFO_SLAVE_DATA = 0x5
IFLA_NETKIT_UNSPEC = 0x0
IFLA_NETKIT_PEER_INFO = 0x1
IFLA_NETKIT_PRIMARY = 0x2
IFLA_NETKIT_POLICY = 0x3
IFLA_NETKIT_PEER_POLICY = 0x4
IFLA_NETKIT_MODE = 0x5
IFLA_XDP = 0x2b
IFLA_XDP_FD = 0x1
IFLA_XDP_ATTACHED = 0x2
Expand Down Expand Up @@ -143,4 +149,10 @@ const (
FRA_IP_PROTO = 0x16
FRA_SPORT_RANGE = 0x17
FRA_DPORT_RANGE = 0x18
NETKIT_NEXT = -0x1
NETKIT_PASS = 0x0
NETKIT_DROP = 0x2
NETKIT_REDIRECT = 0x7
NETKIT_L2 = 0x0
NETKIT_L3 = 0x1
)
82 changes: 82 additions & 0 deletions link.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ type LinkAttributes struct {
TxQueueLen *uint32 // Interface transmit queue len in number of packets
Type uint32 // Link type
XDP *LinkXDP // Express Data Patch Information
Netkit *LinkNetkit // Netkit link Information
}

// OperationalState represents an interface's operational state.
Expand Down Expand Up @@ -285,6 +286,18 @@ func (a *LinkAttributes) decode(ad *netlink.AttributeDecoder) error {
case unix.IFLA_LINKINFO:
a.Info = &LinkInfo{}
ad.Nested(a.Info.decode)
switch a.Info.Kind {
case "netkit":
a.Netkit = &LinkNetkit{}
dec, err := netlink.NewAttributeDecoder(a.Info.Data)
if err != nil {
return err
}
dec.ByteOrder = ad.ByteOrder
if err := a.Netkit.decode(dec); err != nil {
return err
}
}
case unix.IFLA_LINKMODE:
v := ad.Uint8()
a.LinkMode = &v
Expand Down Expand Up @@ -351,6 +364,33 @@ func (a *LinkAttributes) encode(ae *netlink.AttributeEncoder) error {
ae.Uint8(unix.IFLA_OPERSTATE, uint8(a.OperationalState))
}

if a.Netkit != nil {
if a.Info != nil {
return errors.New("fields Netkit and Info cannot be set at the same time")
}

if a.Address != nil || a.Netkit.PeerInfo.Attributes.Address != nil {
return errors.New("netkit does not support setting Ethernet address")
}

nae := netlink.NewAttributeEncoder()
nae.ByteOrder = ae.ByteOrder

err := a.Netkit.encode(nae)
if err != nil {
return err
}
b, err := nae.Encode()
if err != nil {
return err
}

a.Info = &LinkInfo{
Kind: "netkit",
Data: b,
}
}

if a.Info != nil {
nae := netlink.NewAttributeEncoder()
nae.ByteOrder = ae.ByteOrder
Expand Down Expand Up @@ -584,6 +624,48 @@ func (i *LinkInfo) encode(ae *netlink.AttributeEncoder) error {
return nil
}

// LinkNetkit holds netkit link specific information
type LinkNetkit struct {
Mode uint32
Policy int32
PeerPolicy int32
Primary bool
PeerInfo *LinkMessage
}

func (n *LinkNetkit) decode(ad *netlink.AttributeDecoder) error {
for ad.Next() {
switch ad.Type() {
case unix.IFLA_NETKIT_MODE:
n.Mode = ad.Uint32()
case unix.IFLA_NETKIT_POLICY:
n.Policy = ad.Int32()
case unix.IFLA_NETKIT_PEER_POLICY:
n.PeerPolicy = ad.Int32()
case unix.IFLA_NETKIT_PRIMARY:
n.Primary = ad.Uint8() != 0
}
}
return nil
}

func (n *LinkNetkit) encode(ae *netlink.AttributeEncoder) error {
ae.Uint32(unix.IFLA_NETKIT_MODE, n.Mode)
ae.Int32(unix.IFLA_NETKIT_POLICY, n.Policy)
ae.Int32(unix.IFLA_NETKIT_PEER_POLICY, n.PeerPolicy)
if n.PeerInfo != nil {
n.PeerInfo.Family = unix.AF_UNSPEC
// we need to set the netkit.peerInfo.Flags and .Change according to primary link
// however we do not have this information here
b, err := n.PeerInfo.MarshalBinary()
if err != nil {
return err
}
ae.Bytes(unix.IFLA_NETKIT_PEER_INFO, b)
}
return nil
}

// LinkXDP holds Express Data Path specific information
type LinkXDP struct {
FD int32
Expand Down

0 comments on commit 4a21d97

Please sign in to comment.