build: update github.com/vishvananda/netlink to 1.3.0

This includes a breaking change:
acdc658b86
route.Dst is now a zero IPNet instead of nil

Signed-off-by: Etienne Champetier <e.champetier@ateme.com>
This commit is contained in:
Etienne Champetier
2024-08-16 13:07:52 -04:00
parent 5188dc8a19
commit d924f05e12
67 changed files with 5484 additions and 773 deletions

View File

@@ -345,6 +345,16 @@ func (h *Handle) BridgeSetVlanFiltering(link Link, on bool) error {
return h.linkModify(bridge, unix.NLM_F_ACK)
}
func BridgeSetVlanDefaultPVID(link Link, pvid uint16) error {
return pkgHandle.BridgeSetVlanDefaultPVID(link, pvid)
}
func (h *Handle) BridgeSetVlanDefaultPVID(link Link, pvid uint16) error {
bridge := link.(*Bridge)
bridge.VlanDefaultPVID = &pvid
return h.linkModify(bridge, unix.NLM_F_ACK)
}
func SetPromiscOn(link Link) error {
return pkgHandle.SetPromiscOn(link)
}
@@ -487,6 +497,58 @@ func (h *Handle) LinkSetAlias(link Link, name string) error {
return err
}
// LinkAddAltName adds a new alternative name for the link device.
// Equivalent to: `ip link property add $link altname $name`
func LinkAddAltName(link Link, name string) error {
return pkgHandle.LinkAddAltName(link, name)
}
// LinkAddAltName adds a new alternative name for the link device.
// Equivalent to: `ip link property add $link altname $name`
func (h *Handle) LinkAddAltName(link Link, name string) error {
base := link.Attrs()
h.ensureIndex(base)
req := h.newNetlinkRequest(unix.RTM_NEWLINKPROP, unix.NLM_F_ACK)
msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
msg.Index = int32(base.Index)
req.AddData(msg)
data := nl.NewRtAttr(unix.IFLA_PROP_LIST|unix.NLA_F_NESTED, nil)
data.AddRtAttr(unix.IFLA_ALT_IFNAME, []byte(name))
req.AddData(data)
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
return err
}
// LinkDelAltName delete an alternative name for the link device.
// Equivalent to: `ip link property del $link altname $name`
func LinkDelAltName(link Link, name string) error {
return pkgHandle.LinkDelAltName(link, name)
}
// LinkDelAltName delete an alternative name for the link device.
// Equivalent to: `ip link property del $link altname $name`
func (h *Handle) LinkDelAltName(link Link, name string) error {
base := link.Attrs()
h.ensureIndex(base)
req := h.newNetlinkRequest(unix.RTM_DELLINKPROP, unix.NLM_F_ACK)
msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
msg.Index = int32(base.Index)
req.AddData(msg)
data := nl.NewRtAttr(unix.IFLA_PROP_LIST|unix.NLA_F_NESTED, nil)
data.AddRtAttr(unix.IFLA_ALT_IFNAME, []byte(name))
req.AddData(data)
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
return err
}
// LinkSetHardwareAddr sets the hardware address of the link device.
// Equivalent to: `ip link set $link address $hwaddr`
func LinkSetHardwareAddr(link Link, hwaddr net.HardwareAddr) error {
@@ -602,6 +664,43 @@ func (h *Handle) LinkSetVfVlanQos(link Link, vf, vlan, qos int) error {
return err
}
// LinkSetVfVlanQosProto sets the vlan, qos and protocol of a vf for the link.
// Equivalent to: `ip link set $link vf $vf vlan $vlan qos $qos proto $proto`
func LinkSetVfVlanQosProto(link Link, vf, vlan, qos, proto int) error {
return pkgHandle.LinkSetVfVlanQosProto(link, vf, vlan, qos, proto)
}
// LinkSetVfVlanQosProto sets the vlan, qos and protocol of a vf for the link.
// Equivalent to: `ip link set $link vf $vf vlan $vlan qos $qos proto $proto`
func (h *Handle) LinkSetVfVlanQosProto(link Link, vf, vlan, qos, proto 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)
vfInfo := data.AddRtAttr(nl.IFLA_VF_INFO, nil)
vfVlanList := vfInfo.AddRtAttr(nl.IFLA_VF_VLAN_LIST, nil)
vfmsg := nl.VfVlanInfo{
VfVlan: nl.VfVlan{
Vf: uint32(vf),
Vlan: uint32(vlan),
Qos: uint32(qos),
},
VlanProto: (uint16(proto)>>8)&0xFF | (uint16(proto)&0xFF)<<8,
}
vfVlanList.AddRtAttr(nl.IFLA_VF_VLAN_INFO, 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 {
@@ -946,6 +1045,141 @@ func LinkSetXdpFdWithFlags(link Link, fd, flags int) error {
return err
}
// LinkSetGSOMaxSegs sets the GSO maximum segment count of the link device.
// Equivalent to: `ip link set $link gso_max_segs $maxSegs`
func LinkSetGSOMaxSegs(link Link, maxSegs int) error {
return pkgHandle.LinkSetGSOMaxSegs(link, maxSegs)
}
// LinkSetGSOMaxSegs sets the GSO maximum segment count of the link device.
// Equivalent to: `ip link set $link gso_max_segs $maxSegs`
func (h *Handle) LinkSetGSOMaxSegs(link Link, maxSize 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(maxSize))
data := nl.NewRtAttr(unix.IFLA_GSO_MAX_SEGS, b)
req.AddData(data)
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
return err
}
// LinkSetGSOMaxSize sets the IPv6 GSO maximum size of the link device.
// Equivalent to: `ip link set $link gso_max_size $maxSize`
func LinkSetGSOMaxSize(link Link, maxSize int) error {
return pkgHandle.LinkSetGSOMaxSize(link, maxSize)
}
// LinkSetGSOMaxSize sets the IPv6 GSO maximum size of the link device.
// Equivalent to: `ip link set $link gso_max_size $maxSize`
func (h *Handle) LinkSetGSOMaxSize(link Link, maxSize 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(maxSize))
data := nl.NewRtAttr(unix.IFLA_GSO_MAX_SIZE, b)
req.AddData(data)
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
return err
}
// LinkSetGROMaxSize sets the IPv6 GRO maximum size of the link device.
// Equivalent to: `ip link set $link gro_max_size $maxSize`
func LinkSetGROMaxSize(link Link, maxSize int) error {
return pkgHandle.LinkSetGROMaxSize(link, maxSize)
}
// LinkSetGROMaxSize sets the IPv6 GRO maximum size of the link device.
// Equivalent to: `ip link set $link gro_max_size $maxSize`
func (h *Handle) LinkSetGROMaxSize(link Link, maxSize 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(maxSize))
data := nl.NewRtAttr(unix.IFLA_GRO_MAX_SIZE, b)
req.AddData(data)
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
return err
}
// LinkSetGSOIPv4MaxSize sets the IPv4 GSO maximum size of the link device.
// Equivalent to: `ip link set $link gso_ipv4_max_size $maxSize`
func LinkSetGSOIPv4MaxSize(link Link, maxSize int) error {
return pkgHandle.LinkSetGSOIPv4MaxSize(link, maxSize)
}
// LinkSetGSOIPv4MaxSize sets the IPv4 GSO maximum size of the link device.
// Equivalent to: `ip link set $link gso_ipv4_max_size $maxSize`
func (h *Handle) LinkSetGSOIPv4MaxSize(link Link, maxSize 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(maxSize))
data := nl.NewRtAttr(unix.IFLA_GSO_IPV4_MAX_SIZE, b)
req.AddData(data)
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
return err
}
// LinkSetGROIPv4MaxSize sets the IPv4 GRO maximum size of the link device.
// Equivalent to: `ip link set $link gro_ipv4_max_size $maxSize`
func LinkSetGROIPv4MaxSize(link Link, maxSize int) error {
return pkgHandle.LinkSetGROIPv4MaxSize(link, maxSize)
}
// LinkSetGROIPv4MaxSize sets the IPv4 GRO maximum size of the link device.
// Equivalent to: `ip link set $link gro_ipv4_max_size $maxSize`
func (h *Handle) LinkSetGROIPv4MaxSize(link Link, maxSize 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(maxSize))
data := nl.NewRtAttr(unix.IFLA_GRO_IPV4_MAX_SIZE, b)
req.AddData(data)
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
return err
}
func boolAttr(val bool) []byte {
var v uint8
if val {
@@ -1401,6 +1635,21 @@ func (h *Handle) linkModify(link Link, flags int) error {
req.AddData(gsoAttr)
}
if base.GROMaxSize > 0 {
groAttr := nl.NewRtAttr(unix.IFLA_GRO_MAX_SIZE, nl.Uint32Attr(base.GROMaxSize))
req.AddData(groAttr)
}
if base.GSOIPv4MaxSize > 0 {
gsoAttr := nl.NewRtAttr(unix.IFLA_GSO_IPV4_MAX_SIZE, nl.Uint32Attr(base.GSOIPv4MaxSize))
req.AddData(gsoAttr)
}
if base.GROIPv4MaxSize > 0 {
groAttr := nl.NewRtAttr(unix.IFLA_GRO_IPV4_MAX_SIZE, nl.Uint32Attr(base.GROIPv4MaxSize))
req.AddData(groAttr)
}
if base.Group > 0 {
groupAttr := nl.NewRtAttr(unix.IFLA_GROUP, nl.Uint32Attr(base.Group))
req.AddData(groupAttr)
@@ -1437,6 +1686,10 @@ func (h *Handle) linkModify(link Link, flags int) error {
if link.VlanProtocol != VLAN_PROTOCOL_UNKNOWN {
data.AddRtAttr(nl.IFLA_VLAN_PROTOCOL, htons(uint16(link.VlanProtocol)))
}
case *Netkit:
if err := addNetkitAttrs(link, linkInfo, flags); err != nil {
return err
}
case *Veth:
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
peer := data.AddRtAttr(nl.VETH_INFO_PEER, nil)
@@ -1480,15 +1733,9 @@ func (h *Handle) linkModify(link Link, flags int) error {
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)
data.AddRtAttr(nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[link.Mode]))
}
addMacvlanAttrs(link, linkInfo)
case *Macvtap:
if link.Mode != MACVLAN_MODE_DEFAULT {
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
data.AddRtAttr(nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[link.Mode]))
}
addMacvtapAttrs(link, linkInfo)
case *Geneve:
addGeneveAttrs(link, linkInfo)
case *Gretap:
@@ -1569,6 +1816,13 @@ func (h *Handle) linkByNameDump(name string) (Link, error) {
if link.Attrs().Name == name {
return link, nil
}
// support finding interfaces also via altnames
for _, altName := range link.Attrs().AltNames {
if altName == name {
return link, nil
}
}
}
return nil, LinkNotFoundError{fmt.Errorf("Link %s not found", name)}
}
@@ -1607,6 +1861,9 @@ func (h *Handle) LinkByName(name string) (Link, error) {
req.AddData(attr)
nameData := nl.NewRtAttr(unix.IFLA_IFNAME, nl.ZeroTerminated(name))
if len(name) > 15 {
nameData = nl.NewRtAttr(unix.IFLA_ALT_IFNAME, nl.ZeroTerminated(name))
}
req.AddData(nameData)
link, err := execGetLink(req)
@@ -1712,9 +1969,6 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
base.Flags = linkFlags(msg.Flags)
base.EncapType = msg.EncapType()
base.NetNsID = -1
if msg.Flags&unix.IFF_PROMISC != 0 {
base.Promisc = 1
}
if msg.Flags&unix.IFF_ALLMULTI != 0 {
base.Allmulti = 1
}
@@ -1750,6 +2004,8 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
link = &Bridge{}
case "vlan":
link = &Vlan{}
case "netkit":
link = &Netkit{}
case "veth":
link = &Veth{}
case "wireguard":
@@ -1807,6 +2063,8 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
return nil, err
}
switch linkType {
case "netkit":
parseNetkitData(link, data)
case "vlan":
parseVlanData(link, data)
case "vxlan":
@@ -1897,6 +2155,8 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
base.Name = string(attr.Value[:len(attr.Value)-1])
case unix.IFLA_MTU:
base.MTU = int(native.Uint32(attr.Value[0:4]))
case unix.IFLA_PROMISCUITY:
base.Promisc = int(native.Uint32(attr.Value[0:4]))
case unix.IFLA_LINK:
base.ParentIndex = int(native.Uint32(attr.Value[0:4]))
case unix.IFLA_MASTER:
@@ -1931,16 +2191,38 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
protinfo := parseProtinfo(attrs)
base.Protinfo = &protinfo
}
case unix.IFLA_PROP_LIST | unix.NLA_F_NESTED:
attrs, err := nl.ParseRouteAttr(attr.Value[:])
if err != nil {
return nil, err
}
base.AltNames = []string{}
for _, attr := range attrs {
if attr.Attr.Type == unix.IFLA_ALT_IFNAME {
base.AltNames = append(base.AltNames, nl.BytesToString(attr.Value))
}
}
case unix.IFLA_OPERSTATE:
base.OperState = LinkOperState(uint8(attr.Value[0]))
case unix.IFLA_PHYS_SWITCH_ID:
base.PhysSwitchID = int(native.Uint32(attr.Value[0:4]))
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_TSO_MAX_SEGS:
base.TSOMaxSegs = native.Uint32(attr.Value[0:4])
case unix.IFLA_TSO_MAX_SIZE:
base.TSOMaxSize = native.Uint32(attr.Value[0:4])
case unix.IFLA_GSO_MAX_SEGS:
base.GSOMaxSegs = native.Uint32(attr.Value[0:4])
case unix.IFLA_GSO_MAX_SIZE:
base.GSOMaxSize = native.Uint32(attr.Value[0:4])
case unix.IFLA_GRO_MAX_SIZE:
base.GROMaxSize = native.Uint32(attr.Value[0:4])
case unix.IFLA_GSO_IPV4_MAX_SIZE:
base.GSOIPv4MaxSize = native.Uint32(attr.Value[0:4])
case unix.IFLA_GRO_IPV4_MAX_SIZE:
base.GROIPv4MaxSize = native.Uint32(attr.Value[0:4])
case unix.IFLA_VFINFO_LIST:
data, err := nl.ParseRouteAttr(attr.Value)
if err != nil {
@@ -1957,6 +2239,13 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
base.NumRxQueues = int(native.Uint32(attr.Value[0:4]))
case unix.IFLA_GROUP:
base.Group = native.Uint32(attr.Value[0:4])
case unix.IFLA_PERM_ADDRESS:
for _, b := range attr.Value {
if b != 0 {
base.PermHWAddr = attr.Value[:]
break
}
}
}
}
@@ -2069,21 +2358,24 @@ type LinkUpdate struct {
// LinkSubscribe takes a chan down which notifications will be sent
// when links change. Close the 'done' chan to stop subscription.
func LinkSubscribe(ch chan<- LinkUpdate, done <-chan struct{}) error {
return linkSubscribeAt(netns.None(), netns.None(), ch, done, nil, false)
return linkSubscribeAt(netns.None(), netns.None(), ch, done, nil, false, 0, nil, false)
}
// LinkSubscribeAt works like LinkSubscribe plus it allows the caller
// to choose the network namespace in which to subscribe (ns).
func LinkSubscribeAt(ns netns.NsHandle, ch chan<- LinkUpdate, done <-chan struct{}) error {
return linkSubscribeAt(ns, netns.None(), ch, done, nil, false)
return linkSubscribeAt(ns, netns.None(), ch, done, nil, false, 0, nil, false)
}
// LinkSubscribeOptions contains a set of options to use with
// LinkSubscribeWithOptions.
type LinkSubscribeOptions struct {
Namespace *netns.NsHandle
ErrorCallback func(error)
ListExisting bool
Namespace *netns.NsHandle
ErrorCallback func(error)
ListExisting bool
ReceiveBufferSize int
ReceiveBufferForceSize bool
ReceiveTimeout *unix.Timeval
}
// LinkSubscribeWithOptions work like LinkSubscribe but enable to
@@ -2094,14 +2386,27 @@ func LinkSubscribeWithOptions(ch chan<- LinkUpdate, done <-chan struct{}, option
none := netns.None()
options.Namespace = &none
}
return linkSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting)
return linkSubscribeAt(*options.Namespace, netns.None(), ch, done, options.ErrorCallback, options.ListExisting,
options.ReceiveBufferSize, options.ReceiveTimeout, options.ReceiveBufferForceSize)
}
func linkSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-chan struct{}, cberr func(error), listExisting bool) error {
func linkSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-chan struct{}, cberr func(error), listExisting bool,
rcvbuf int, rcvTimeout *unix.Timeval, rcvbufForce bool) error {
s, err := nl.SubscribeAt(newNs, curNs, unix.NETLINK_ROUTE, unix.RTNLGRP_LINK)
if err != nil {
return err
}
if rcvTimeout != nil {
if err := s.SetReceiveTimeout(rcvTimeout); err != nil {
return err
}
}
if rcvbuf != 0 {
err = s.SetReceiveBufferSize(rcvbuf, rcvbufForce)
if err != nil {
return err
}
}
if done != nil {
go func() {
<-done
@@ -2182,6 +2487,16 @@ func (h *Handle) LinkSetGuard(link Link, mode bool) error {
return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_GUARD)
}
// LinkSetBRSlaveGroupFwdMask set the group_fwd_mask of a bridge slave interface
func LinkSetBRSlaveGroupFwdMask(link Link, mask uint16) error {
return pkgHandle.LinkSetBRSlaveGroupFwdMask(link, mask)
}
// LinkSetBRSlaveGroupFwdMask set the group_fwd_mask of a bridge slave interface
func (h *Handle) LinkSetBRSlaveGroupFwdMask(link Link, mask uint16) error {
return h.setProtinfoAttrRawVal(link, nl.Uint16Attr(mask), nl.IFLA_BRPORT_GROUP_FWD_MASK)
}
func LinkSetFastLeave(link Link, mode bool) error {
return pkgHandle.LinkSetFastLeave(link, mode)
}
@@ -2214,6 +2529,14 @@ func (h *Handle) LinkSetFlood(link Link, mode bool) error {
return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_UNICAST_FLOOD)
}
func LinkSetIsolated(link Link, mode bool) error {
return pkgHandle.LinkSetIsolated(link, mode)
}
func (h *Handle) LinkSetIsolated(link Link, mode bool) error {
return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_ISOLATED)
}
func LinkSetBrProxyArp(link Link, mode bool) error {
return pkgHandle.LinkSetBrProxyArp(link, mode)
}
@@ -2230,7 +2553,15 @@ func (h *Handle) LinkSetBrProxyArpWiFi(link Link, mode bool) error {
return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_PROXYARP_WIFI)
}
func (h *Handle) setProtinfoAttr(link Link, mode bool, attr int) error {
func LinkSetBrNeighSuppress(link Link, mode bool) error {
return pkgHandle.LinkSetBrNeighSuppress(link, mode)
}
func (h *Handle) LinkSetBrNeighSuppress(link Link, mode bool) error {
return h.setProtinfoAttr(link, mode, nl.IFLA_BRPORT_NEIGH_SUPPRESS)
}
func (h *Handle) setProtinfoAttrRawVal(link Link, val []byte, attr int) error {
base := link.Attrs()
h.ensureIndex(base)
req := h.newNetlinkRequest(unix.RTM_SETLINK, unix.NLM_F_ACK)
@@ -2240,7 +2571,7 @@ func (h *Handle) setProtinfoAttr(link Link, mode bool, attr int) error {
req.AddData(msg)
br := nl.NewRtAttr(unix.IFLA_PROTINFO|unix.NLA_F_NESTED, nil)
br.AddRtAttr(attr, boolToByte(mode))
br.AddRtAttr(attr, val)
req.AddData(br)
_, err := req.Execute(unix.NETLINK_ROUTE, 0)
if err != nil {
@@ -2248,6 +2579,9 @@ func (h *Handle) setProtinfoAttr(link Link, mode bool, attr int) error {
}
return nil
}
func (h *Handle) setProtinfoAttr(link Link, mode bool, attr int) error {
return h.setProtinfoAttrRawVal(link, boolToByte(mode), attr)
}
// LinkSetTxQLen sets the transaction queue length for the link.
// Equivalent to: `ip link set $link txqlen $qlen`
@@ -2305,6 +2639,80 @@ func (h *Handle) LinkSetGroup(link Link, group int) error {
return err
}
func addNetkitAttrs(nk *Netkit, linkInfo *nl.RtAttr, flag int) error {
if nk.peerLinkAttrs.HardwareAddr != nil || nk.HardwareAddr != nil {
return fmt.Errorf("netkit doesn't support setting Ethernet")
}
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
// Kernel will return error if trying to change the mode of an existing netkit device
data.AddRtAttr(nl.IFLA_NETKIT_MODE, nl.Uint32Attr(uint32(nk.Mode)))
data.AddRtAttr(nl.IFLA_NETKIT_POLICY, nl.Uint32Attr(uint32(nk.Policy)))
data.AddRtAttr(nl.IFLA_NETKIT_PEER_POLICY, nl.Uint32Attr(uint32(nk.PeerPolicy)))
if (flag & unix.NLM_F_EXCL) == 0 {
// Modifying peer link attributes will not take effect
return nil
}
peer := data.AddRtAttr(nl.IFLA_NETKIT_PEER_INFO, nil)
msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
if nk.peerLinkAttrs.Flags&net.FlagUp != 0 {
msg.Change = unix.IFF_UP
msg.Flags = unix.IFF_UP
}
if nk.peerLinkAttrs.Index != 0 {
msg.Index = int32(nk.peerLinkAttrs.Index)
}
peer.AddChild(msg)
if nk.peerLinkAttrs.Name != "" {
peer.AddRtAttr(unix.IFLA_IFNAME, nl.ZeroTerminated(nk.peerLinkAttrs.Name))
}
if nk.peerLinkAttrs.MTU > 0 {
peer.AddRtAttr(unix.IFLA_MTU, nl.Uint32Attr(uint32(nk.peerLinkAttrs.MTU)))
}
if nk.peerLinkAttrs.GSOMaxSegs > 0 {
peer.AddRtAttr(unix.IFLA_GSO_MAX_SEGS, nl.Uint32Attr(nk.peerLinkAttrs.GSOMaxSegs))
}
if nk.peerLinkAttrs.GSOMaxSize > 0 {
peer.AddRtAttr(unix.IFLA_GSO_MAX_SIZE, nl.Uint32Attr(nk.peerLinkAttrs.GSOMaxSize))
}
if nk.peerLinkAttrs.GSOIPv4MaxSize > 0 {
peer.AddRtAttr(unix.IFLA_GSO_IPV4_MAX_SIZE, nl.Uint32Attr(nk.peerLinkAttrs.GSOIPv4MaxSize))
}
if nk.peerLinkAttrs.GROIPv4MaxSize > 0 {
peer.AddRtAttr(unix.IFLA_GRO_IPV4_MAX_SIZE, nl.Uint32Attr(nk.peerLinkAttrs.GROIPv4MaxSize))
}
if nk.peerLinkAttrs.Namespace != nil {
switch ns := nk.peerLinkAttrs.Namespace.(type) {
case NsPid:
peer.AddRtAttr(unix.IFLA_NET_NS_PID, nl.Uint32Attr(uint32(ns)))
case NsFd:
peer.AddRtAttr(unix.IFLA_NET_NS_FD, nl.Uint32Attr(uint32(ns)))
}
}
return nil
}
func parseNetkitData(link Link, data []syscall.NetlinkRouteAttr) {
netkit := link.(*Netkit)
for _, datum := range data {
switch datum.Attr.Type {
case nl.IFLA_NETKIT_PRIMARY:
isPrimary := datum.Value[0:1][0]
if isPrimary != 0 {
netkit.isPrimary = true
}
case nl.IFLA_NETKIT_MODE:
netkit.Mode = NetkitMode(native.Uint32(datum.Value[0:4]))
case nl.IFLA_NETKIT_POLICY:
netkit.Policy = NetkitPolicy(native.Uint32(datum.Value[0:4]))
case nl.IFLA_NETKIT_PEER_POLICY:
netkit.PeerPolicy = NetkitPolicy(native.Uint32(datum.Value[0:4]))
}
}
}
func parseVlanData(link Link, data []syscall.NetlinkRouteAttr) {
vlan := link.(*Vlan)
for _, datum := range data {
@@ -2539,11 +2947,30 @@ func parseIPVtapData(link Link, data []syscall.NetlinkRouteAttr) {
}
}
func addMacvtapAttrs(macvtap *Macvtap, linkInfo *nl.RtAttr) {
addMacvlanAttrs(&macvtap.Macvlan, linkInfo)
}
func parseMacvtapData(link Link, data []syscall.NetlinkRouteAttr) {
macv := link.(*Macvtap)
parseMacvlanData(&macv.Macvlan, data)
}
func addMacvlanAttrs(macvlan *Macvlan, linkInfo *nl.RtAttr) {
var data *nl.RtAttr
if macvlan.Mode != MACVLAN_MODE_DEFAULT || macvlan.BCQueueLen > 0 {
data = linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
}
if macvlan.Mode != MACVLAN_MODE_DEFAULT {
data.AddRtAttr(nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[macvlan.Mode]))
}
if macvlan.BCQueueLen > 0 {
data.AddRtAttr(nl.IFLA_MACVLAN_BC_QUEUE_LEN, nl.Uint32Attr(macvlan.BCQueueLen))
}
}
func parseMacvlanData(link Link, data []syscall.NetlinkRouteAttr) {
macv := link.(*Macvlan)
for _, datum := range data {
@@ -2571,6 +2998,10 @@ func parseMacvlanData(link Link, data []syscall.NetlinkRouteAttr) {
for _, macDatum := range macs {
macv.MACAddrs = append(macv.MACAddrs, net.HardwareAddr(macDatum.Value[0:6]))
}
case nl.IFLA_MACVLAN_BC_QUEUE_LEN:
macv.BCQueueLen = native.Uint32(datum.Value[0:4])
case nl.IFLA_MACVLAN_BC_QUEUE_LEN_USED:
macv.UsedBCQueueLen = native.Uint32(datum.Value[0:4])
}
}
}
@@ -2599,10 +3030,13 @@ func linkFlags(rawFlags uint32) net.Flags {
func addGeneveAttrs(geneve *Geneve, linkInfo *nl.RtAttr) {
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
if geneve.InnerProtoInherit {
data.AddRtAttr(nl.IFLA_GENEVE_INNER_PROTO_INHERIT, []byte{})
}
if geneve.FlowBased {
// In flow based mode, no other attributes need to be configured
linkInfo.AddRtAttr(nl.IFLA_GENEVE_COLLECT_METADATA, boolAttr(geneve.FlowBased))
return
geneve.ID = 0
data.AddRtAttr(nl.IFLA_GENEVE_COLLECT_METADATA, []byte{})
}
if ip := geneve.Remote; ip != nil {
@@ -2628,6 +3062,8 @@ func addGeneveAttrs(geneve *Geneve, linkInfo *nl.RtAttr) {
if geneve.Tos != 0 {
data.AddRtAttr(nl.IFLA_GENEVE_TOS, nl.Uint8Attr(geneve.Tos))
}
data.AddRtAttr(nl.IFLA_GENEVE_DF, nl.Uint8Attr(uint8(geneve.Df)))
}
func parseGeneveData(link Link, data []syscall.NetlinkRouteAttr) {
@@ -2644,6 +3080,10 @@ func parseGeneveData(link Link, data []syscall.NetlinkRouteAttr) {
geneve.Ttl = uint8(datum.Value[0])
case nl.IFLA_GENEVE_TOS:
geneve.Tos = uint8(datum.Value[0])
case nl.IFLA_GENEVE_COLLECT_METADATA:
geneve.FlowBased = true
case nl.IFLA_GENEVE_INNER_PROTO_INHERIT:
geneve.InnerProtoInherit = true
}
}
}
@@ -2653,7 +3093,7 @@ func addGretapAttrs(gretap *Gretap, linkInfo *nl.RtAttr) {
if gretap.FlowBased {
// In flow based mode, no other attributes need to be configured
data.AddRtAttr(nl.IFLA_GRE_COLLECT_METADATA, boolAttr(gretap.FlowBased))
data.AddRtAttr(nl.IFLA_GRE_COLLECT_METADATA, []byte{})
return
}
@@ -2736,6 +3176,12 @@ func parseGretapData(link Link, data []syscall.NetlinkRouteAttr) {
func addGretunAttrs(gre *Gretun, linkInfo *nl.RtAttr) {
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
if gre.FlowBased {
// In flow based mode, no other attributes need to be configured
data.AddRtAttr(nl.IFLA_GRE_COLLECT_METADATA, []byte{})
return
}
if ip := gre.Local; ip != nil {
if ip.To4() != nil {
ip = ip.To4()
@@ -2806,6 +3252,8 @@ func parseGretunData(link Link, data []syscall.NetlinkRouteAttr) {
gre.EncapSport = ntohs(datum.Value[0:2])
case nl.IFLA_GRE_ENCAP_DPORT:
gre.EncapDport = ntohs(datum.Value[0:2])
case nl.IFLA_GRE_COLLECT_METADATA:
gre.FlowBased = true
}
}
}
@@ -2846,14 +3294,14 @@ func parseLinkXdp(data []byte) (*LinkXdp, error) {
}
func addIptunAttrs(iptun *Iptun, linkInfo *nl.RtAttr) {
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
if iptun.FlowBased {
// In flow based mode, no other attributes need to be configured
linkInfo.AddRtAttr(nl.IFLA_IPTUN_COLLECT_METADATA, boolAttr(iptun.FlowBased))
data.AddRtAttr(nl.IFLA_IPTUN_COLLECT_METADATA, []byte{})
return
}
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
ip := iptun.Local.To4()
if ip != nil {
data.AddRtAttr(nl.IFLA_IPTUN_LOCAL, []byte(ip))
@@ -2880,10 +3328,6 @@ func addIptunAttrs(iptun *Iptun, linkInfo *nl.RtAttr) {
func parseIptunData(link Link, data []syscall.NetlinkRouteAttr) {
iptun := link.(*Iptun)
for _, datum := range data {
// NOTE: same with vxlan, ip tunnel may also has null datum.Value
if len(datum.Value) == 0 {
continue
}
switch datum.Attr.Type {
case nl.IFLA_IPTUN_LOCAL:
iptun.Local = net.IP(datum.Value[0:4])
@@ -2914,6 +3358,12 @@ func parseIptunData(link Link, data []syscall.NetlinkRouteAttr) {
func addIp6tnlAttrs(ip6tnl *Ip6tnl, linkInfo *nl.RtAttr) {
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
if ip6tnl.FlowBased {
// In flow based mode, no other attributes need to be configured
data.AddRtAttr(nl.IFLA_IPTUN_COLLECT_METADATA, []byte{})
return
}
if ip6tnl.Link != 0 {
data.AddRtAttr(nl.IFLA_IPTUN_LINK, nl.Uint32Attr(ip6tnl.Link))
}
@@ -2968,6 +3418,8 @@ func parseIp6tnlData(link Link, data []syscall.NetlinkRouteAttr) {
ip6tnl.EncapSport = ntohs(datum.Value[0:2])
case nl.IFLA_IPTUN_ENCAP_DPORT:
ip6tnl.EncapDport = ntohs(datum.Value[0:2])
case nl.IFLA_IPTUN_COLLECT_METADATA:
ip6tnl.FlowBased = true
}
}
}
@@ -3115,6 +3567,12 @@ func addBridgeAttrs(bridge *Bridge, linkInfo *nl.RtAttr) {
if bridge.VlanFiltering != nil {
data.AddRtAttr(nl.IFLA_BR_VLAN_FILTERING, boolToByte(*bridge.VlanFiltering))
}
if bridge.VlanDefaultPVID != nil {
data.AddRtAttr(nl.IFLA_BR_VLAN_DEFAULT_PVID, nl.Uint16Attr(*bridge.VlanDefaultPVID))
}
if bridge.GroupFwdMask != nil {
data.AddRtAttr(nl.IFLA_BR_GROUP_FWD_MASK, nl.Uint16Attr(*bridge.GroupFwdMask))
}
}
func parseBridgeData(bridge Link, data []syscall.NetlinkRouteAttr) {
@@ -3133,6 +3591,12 @@ func parseBridgeData(bridge Link, data []syscall.NetlinkRouteAttr) {
case nl.IFLA_BR_VLAN_FILTERING:
vlanFiltering := datum.Value[0] == 1
br.VlanFiltering = &vlanFiltering
case nl.IFLA_BR_VLAN_DEFAULT_PVID:
vlanDefaultPVID := native.Uint16(datum.Value[0:2])
br.VlanDefaultPVID = &vlanDefaultPVID
case nl.IFLA_BR_GROUP_FWD_MASK:
mask := native.Uint16(datum.Value[0:2])
br.GroupFwdMask = &mask
}
}
}
@@ -3174,12 +3638,17 @@ func parseVfInfoList(data []syscall.NetlinkRouteAttr) ([]VfInfo, error) {
if err != nil {
return nil, err
}
vfs = append(vfs, parseVfInfo(vfAttrs, i))
vf, err := parseVfInfo(vfAttrs, i)
if err != nil {
return nil, err
}
vfs = append(vfs, vf)
}
return vfs, nil
}
func parseVfInfo(data []syscall.NetlinkRouteAttr, id int) VfInfo {
func parseVfInfo(data []syscall.NetlinkRouteAttr, id int) (VfInfo, error) {
vf := VfInfo{ID: id}
for _, element := range data {
switch element.Attr.Type {
@@ -3190,6 +3659,12 @@ func parseVfInfo(data []syscall.NetlinkRouteAttr, id int) VfInfo {
vl := nl.DeserializeVfVlan(element.Value[:])
vf.Vlan = int(vl.Vlan)
vf.Qos = int(vl.Qos)
case nl.IFLA_VF_VLAN_LIST:
vfVlanInfoList, err := nl.DeserializeVfVlanList(element.Value[:])
if err != nil {
return vf, err
}
vf.VlanProto = int(vfVlanInfoList[0].VlanProto)
case nl.IFLA_VF_TX_RATE:
txr := nl.DeserializeVfTxRate(element.Value[:])
vf.TxRate = int(txr.Rate)
@@ -3223,7 +3698,7 @@ func parseVfInfo(data []syscall.NetlinkRouteAttr, id int) VfInfo {
vf.Trust = result.Setting
}
}
return vf
return vf, nil
}
func addXfrmiAttrs(xfrmi *Xfrmi, linkInfo *nl.RtAttr) {
@@ -3246,8 +3721,7 @@ func parseXfrmiData(link Link, data []syscall.NetlinkRouteAttr) {
}
}
// LinkSetBondSlave add slave to bond link via ioctl interface.
func LinkSetBondSlave(link Link, master *Bond) error {
func ioctlBondSlave(cmd uintptr, link Link, master *Bond) error {
fd, err := getSocketUDP()
if err != nil {
return err
@@ -3255,10 +3729,38 @@ func LinkSetBondSlave(link Link, master *Bond) error {
defer syscall.Close(fd)
ifreq := newIocltSlaveReq(link.Attrs().Name, master.Attrs().Name)
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), unix.SIOCBONDENSLAVE, uintptr(unsafe.Pointer(ifreq)))
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), cmd, uintptr(unsafe.Pointer(ifreq)))
if errno != 0 {
return fmt.Errorf("Failed to enslave %q to %q, errno=%v", link.Attrs().Name, master.Attrs().Name, errno)
return fmt.Errorf("errno=%v", errno)
}
return nil
}
// LinkSetBondSlaveActive sets specified slave to ACTIVE in an `active-backup` bond link via ioctl interface.
//
// Multiple calls keeps the status unchanged(shown in the unit test).
func LinkSetBondSlaveActive(link Link, master *Bond) error {
err := ioctlBondSlave(unix.SIOCBONDCHANGEACTIVE, link, master)
if err != nil {
return fmt.Errorf("Failed to set slave %q active in %q, %v", link.Attrs().Name, master.Attrs().Name, err)
}
return nil
}
// LinkSetBondSlave add slave to bond link via ioctl interface.
func LinkSetBondSlave(link Link, master *Bond) error {
err := ioctlBondSlave(unix.SIOCBONDENSLAVE, link, master)
if err != nil {
return fmt.Errorf("Failed to enslave %q to %q, %v", link.Attrs().Name, master.Attrs().Name, err)
}
return nil
}
// LinkSetBondSlave removes specified slave from bond link via ioctl interface.
func LinkDelBondSlave(link Link, master *Bond) error {
err := ioctlBondSlave(unix.SIOCBONDRELEASE, link, master)
if err != nil {
return fmt.Errorf("Failed to del slave %q from %q, %v", link.Attrs().Name, master.Attrs().Name, err)
}
return nil
}