|
@@ -106,6 +106,24 @@ func LinkSetName(link Link, name string) error {
|
|
return err
|
|
return err
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// LinkSetAlias sets the alias of the link device.
|
|
|
|
+// Equivalent to: `ip link set dev $link alias $name`
|
|
|
|
+func LinkSetAlias(link Link, name string) 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(syscall.IFLA_IFALIAS, []byte(name))
|
|
|
|
+ req.AddData(data)
|
|
|
|
+
|
|
|
|
+ _, err := req.Execute(syscall.NETLINK_ROUTE, 0)
|
|
|
|
+ return err
|
|
|
|
+}
|
|
|
|
+
|
|
// LinkSetHardwareAddr sets the hardware address of the link device.
|
|
// LinkSetHardwareAddr sets the hardware address of the link device.
|
|
// Equivalent to: `ip link set $link address $hwaddr`
|
|
// Equivalent to: `ip link set $link address $hwaddr`
|
|
func LinkSetHardwareAddr(link Link, hwaddr net.HardwareAddr) error {
|
|
func LinkSetHardwareAddr(link Link, hwaddr net.HardwareAddr) error {
|
|
@@ -133,9 +151,18 @@ func LinkSetMaster(link Link, master *Bridge) error {
|
|
ensureIndex(masterBase)
|
|
ensureIndex(masterBase)
|
|
index = masterBase.Index
|
|
index = masterBase.Index
|
|
}
|
|
}
|
|
|
|
+ if index <= 0 {
|
|
|
|
+ return fmt.Errorf("Device does not exist")
|
|
|
|
+ }
|
|
return LinkSetMasterByIndex(link, index)
|
|
return LinkSetMasterByIndex(link, index)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// LinkSetNoMaster removes the master of the link device.
|
|
|
|
+// Equivalent to: `ip link set $link nomaster`
|
|
|
|
+func LinkSetNoMaster(link Link) error {
|
|
|
|
+ return LinkSetMasterByIndex(link, 0)
|
|
|
|
+}
|
|
|
|
+
|
|
// LinkSetMasterByIndex sets the master of the link device.
|
|
// LinkSetMasterByIndex sets the master of the link device.
|
|
// Equivalent to: `ip link set $link master $master`
|
|
// Equivalent to: `ip link set $link master $master`
|
|
func LinkSetMasterByIndex(link Link, masterIndex int) error {
|
|
func LinkSetMasterByIndex(link Link, masterIndex int) error {
|
|
@@ -275,6 +302,87 @@ func addVxlanAttrs(vxlan *Vxlan, linkInfo *nl.RtAttr) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func addBondAttrs(bond *Bond, linkInfo *nl.RtAttr) {
|
|
|
|
+ data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
|
|
|
+ if bond.Mode >= 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_BOND_MODE, nl.Uint8Attr(uint8(bond.Mode)))
|
|
|
|
+ }
|
|
|
|
+ if bond.ActiveSlave >= 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_BOND_ACTIVE_SLAVE, nl.Uint32Attr(uint32(bond.ActiveSlave)))
|
|
|
|
+ }
|
|
|
|
+ if bond.Miimon >= 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_BOND_MIIMON, nl.Uint32Attr(uint32(bond.Miimon)))
|
|
|
|
+ }
|
|
|
|
+ if bond.UpDelay >= 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_BOND_UPDELAY, nl.Uint32Attr(uint32(bond.UpDelay)))
|
|
|
|
+ }
|
|
|
|
+ if bond.DownDelay >= 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_BOND_DOWNDELAY, nl.Uint32Attr(uint32(bond.DownDelay)))
|
|
|
|
+ }
|
|
|
|
+ if bond.UseCarrier >= 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_BOND_USE_CARRIER, nl.Uint8Attr(uint8(bond.UseCarrier)))
|
|
|
|
+ }
|
|
|
|
+ if bond.ArpInterval >= 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_BOND_ARP_INTERVAL, nl.Uint32Attr(uint32(bond.ArpInterval)))
|
|
|
|
+ }
|
|
|
|
+ if bond.ArpIpTargets != nil {
|
|
|
|
+ msg := nl.NewRtAttrChild(data, nl.IFLA_BOND_ARP_IP_TARGET, nil)
|
|
|
|
+ for i := range bond.ArpIpTargets {
|
|
|
|
+ ip := bond.ArpIpTargets[i].To4()
|
|
|
|
+ if ip != nil {
|
|
|
|
+ nl.NewRtAttrChild(msg, i, []byte(ip))
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ ip = bond.ArpIpTargets[i].To16()
|
|
|
|
+ if ip != nil {
|
|
|
|
+ nl.NewRtAttrChild(msg, i, []byte(ip))
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if bond.ArpValidate >= 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_BOND_ARP_VALIDATE, nl.Uint32Attr(uint32(bond.ArpValidate)))
|
|
|
|
+ }
|
|
|
|
+ if bond.ArpAllTargets >= 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_BOND_ARP_ALL_TARGETS, nl.Uint32Attr(uint32(bond.ArpAllTargets)))
|
|
|
|
+ }
|
|
|
|
+ if bond.Primary >= 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_BOND_PRIMARY, nl.Uint32Attr(uint32(bond.Primary)))
|
|
|
|
+ }
|
|
|
|
+ if bond.PrimaryReselect >= 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_BOND_PRIMARY_RESELECT, nl.Uint8Attr(uint8(bond.PrimaryReselect)))
|
|
|
|
+ }
|
|
|
|
+ if bond.FailOverMac >= 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_BOND_FAIL_OVER_MAC, nl.Uint8Attr(uint8(bond.FailOverMac)))
|
|
|
|
+ }
|
|
|
|
+ if bond.XmitHashPolicy >= 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_BOND_XMIT_HASH_POLICY, nl.Uint8Attr(uint8(bond.XmitHashPolicy)))
|
|
|
|
+ }
|
|
|
|
+ if bond.ResendIgmp >= 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_BOND_RESEND_IGMP, nl.Uint32Attr(uint32(bond.ResendIgmp)))
|
|
|
|
+ }
|
|
|
|
+ if bond.NumPeerNotif >= 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_BOND_NUM_PEER_NOTIF, nl.Uint8Attr(uint8(bond.NumPeerNotif)))
|
|
|
|
+ }
|
|
|
|
+ if bond.AllSlavesActive >= 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_BOND_ALL_SLAVES_ACTIVE, nl.Uint8Attr(uint8(bond.AllSlavesActive)))
|
|
|
|
+ }
|
|
|
|
+ if bond.MinLinks >= 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_BOND_MIN_LINKS, nl.Uint32Attr(uint32(bond.MinLinks)))
|
|
|
|
+ }
|
|
|
|
+ if bond.LpInterval >= 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_BOND_LP_INTERVAL, nl.Uint32Attr(uint32(bond.LpInterval)))
|
|
|
|
+ }
|
|
|
|
+ if bond.PackersPerSlave >= 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_BOND_PACKETS_PER_SLAVE, nl.Uint32Attr(uint32(bond.PackersPerSlave)))
|
|
|
|
+ }
|
|
|
|
+ if bond.LacpRate >= 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_BOND_AD_LACP_RATE, nl.Uint8Attr(uint8(bond.LacpRate)))
|
|
|
|
+ }
|
|
|
|
+ if bond.AdSelect >= 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_BOND_AD_SELECT, nl.Uint8Attr(uint8(bond.AdSelect)))
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
// LinkAdd adds a new link device. The type and features of the device
|
|
// LinkAdd adds a new link device. The type and features of the device
|
|
// are taken fromt the parameters in the link object.
|
|
// are taken fromt the parameters in the link object.
|
|
// Equivalent to: `ip link add $link`
|
|
// Equivalent to: `ip link add $link`
|
|
@@ -328,6 +436,27 @@ func LinkAdd(link Link) error {
|
|
req := nl.NewNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
|
req := nl.NewNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
|
|
|
|
|
|
msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
|
|
msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
|
|
|
|
+ // TODO: make it shorter
|
|
|
|
+ if base.Flags&net.FlagUp != 0 {
|
|
|
|
+ msg.Change = syscall.IFF_UP
|
|
|
|
+ msg.Flags = syscall.IFF_UP
|
|
|
|
+ }
|
|
|
|
+ if base.Flags&net.FlagBroadcast != 0 {
|
|
|
|
+ msg.Change |= syscall.IFF_BROADCAST
|
|
|
|
+ msg.Flags |= syscall.IFF_BROADCAST
|
|
|
|
+ }
|
|
|
|
+ if base.Flags&net.FlagLoopback != 0 {
|
|
|
|
+ msg.Change |= syscall.IFF_LOOPBACK
|
|
|
|
+ msg.Flags |= syscall.IFF_LOOPBACK
|
|
|
|
+ }
|
|
|
|
+ if base.Flags&net.FlagPointToPoint != 0 {
|
|
|
|
+ msg.Change |= syscall.IFF_POINTOPOINT
|
|
|
|
+ msg.Flags |= syscall.IFF_POINTOPOINT
|
|
|
|
+ }
|
|
|
|
+ if base.Flags&net.FlagMulticast != 0 {
|
|
|
|
+ msg.Change |= syscall.IFF_MULTICAST
|
|
|
|
+ msg.Flags |= syscall.IFF_MULTICAST
|
|
|
|
+ }
|
|
req.AddData(msg)
|
|
req.AddData(msg)
|
|
|
|
|
|
if base.ParentIndex != 0 {
|
|
if base.ParentIndex != 0 {
|
|
@@ -388,6 +517,8 @@ func LinkAdd(link Link) error {
|
|
|
|
|
|
} else if vxlan, ok := link.(*Vxlan); ok {
|
|
} else if vxlan, ok := link.(*Vxlan); ok {
|
|
addVxlanAttrs(vxlan, linkInfo)
|
|
addVxlanAttrs(vxlan, linkInfo)
|
|
|
|
+ } else if bond, ok := link.(*Bond); ok {
|
|
|
|
+ addBondAttrs(bond, linkInfo)
|
|
} else if ipv, ok := link.(*IPVlan); ok {
|
|
} else if ipv, ok := link.(*IPVlan); ok {
|
|
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
|
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
|
nl.NewRtAttrChild(data, nl.IFLA_IPVLAN_MODE, nl.Uint16Attr(uint16(ipv.Mode)))
|
|
nl.NewRtAttrChild(data, nl.IFLA_IPVLAN_MODE, nl.Uint16Attr(uint16(ipv.Mode)))
|
|
@@ -396,6 +527,8 @@ func LinkAdd(link Link) error {
|
|
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
|
data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
|
nl.NewRtAttrChild(data, nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[macv.Mode]))
|
|
nl.NewRtAttrChild(data, nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[macv.Mode]))
|
|
}
|
|
}
|
|
|
|
+ } else if gretap, ok := link.(*Gretap); ok {
|
|
|
|
+ addGretapAttrs(gretap, linkInfo)
|
|
}
|
|
}
|
|
|
|
|
|
req.AddData(linkInfo)
|
|
req.AddData(linkInfo)
|
|
@@ -447,6 +580,20 @@ func linkByNameDump(name string) (Link, error) {
|
|
return nil, fmt.Errorf("Link %s not found", name)
|
|
return nil, fmt.Errorf("Link %s not found", name)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func linkByAliasDump(alias string) (Link, error) {
|
|
|
|
+ links, err := LinkList()
|
|
|
|
+ if err != nil {
|
|
|
|
+ return nil, err
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for _, link := range links {
|
|
|
|
+ if link.Attrs().Alias == alias {
|
|
|
|
+ return link, nil
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return nil, fmt.Errorf("Link alias %s not found", alias)
|
|
|
|
+}
|
|
|
|
+
|
|
// LinkByName finds a link by name and returns a pointer to the object.
|
|
// LinkByName finds a link by name and returns a pointer to the object.
|
|
func LinkByName(name string) (Link, error) {
|
|
func LinkByName(name string) (Link, error) {
|
|
if lookupByDump {
|
|
if lookupByDump {
|
|
@@ -472,6 +619,32 @@ func LinkByName(name string) (Link, error) {
|
|
return link, err
|
|
return link, err
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// LinkByAlias finds a link by its alias and returns a pointer to the object.
|
|
|
|
+// If there are multiple links with the alias it returns the first one
|
|
|
|
+func LinkByAlias(alias string) (Link, error) {
|
|
|
|
+ if lookupByDump {
|
|
|
|
+ return linkByAliasDump(alias)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ req := nl.NewNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_ACK)
|
|
|
|
+
|
|
|
|
+ msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
|
|
|
|
+ req.AddData(msg)
|
|
|
|
+
|
|
|
|
+ nameData := nl.NewRtAttr(syscall.IFLA_IFALIAS, nl.ZeroTerminated(alias))
|
|
|
|
+ req.AddData(nameData)
|
|
|
|
+
|
|
|
|
+ link, err := execGetLink(req)
|
|
|
|
+ if err == syscall.EINVAL {
|
|
|
|
+ // older kernels don't support looking up via IFLA_IFALIAS
|
|
|
|
+ // so fall back to dumping all links
|
|
|
|
+ lookupByDump = true
|
|
|
|
+ return linkByAliasDump(alias)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return link, err
|
|
|
|
+}
|
|
|
|
+
|
|
// LinkByIndex finds a link by index and returns a pointer to the object.
|
|
// LinkByIndex finds a link by index and returns a pointer to the object.
|
|
func LinkByIndex(index int) (Link, error) {
|
|
func LinkByIndex(index int) (Link, error) {
|
|
req := nl.NewNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_ACK)
|
|
req := nl.NewNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_ACK)
|
|
@@ -543,12 +716,16 @@ func linkDeserialize(m []byte) (Link, error) {
|
|
link = &Veth{}
|
|
link = &Veth{}
|
|
case "vxlan":
|
|
case "vxlan":
|
|
link = &Vxlan{}
|
|
link = &Vxlan{}
|
|
|
|
+ case "bond":
|
|
|
|
+ link = &Bond{}
|
|
case "ipvlan":
|
|
case "ipvlan":
|
|
link = &IPVlan{}
|
|
link = &IPVlan{}
|
|
case "macvlan":
|
|
case "macvlan":
|
|
link = &Macvlan{}
|
|
link = &Macvlan{}
|
|
case "macvtap":
|
|
case "macvtap":
|
|
link = &Macvtap{}
|
|
link = &Macvtap{}
|
|
|
|
+ case "gretap":
|
|
|
|
+ link = &Gretap{}
|
|
default:
|
|
default:
|
|
link = &GenericLink{LinkType: linkType}
|
|
link = &GenericLink{LinkType: linkType}
|
|
}
|
|
}
|
|
@@ -562,12 +739,16 @@ func linkDeserialize(m []byte) (Link, error) {
|
|
parseVlanData(link, data)
|
|
parseVlanData(link, data)
|
|
case "vxlan":
|
|
case "vxlan":
|
|
parseVxlanData(link, data)
|
|
parseVxlanData(link, data)
|
|
|
|
+ case "bond":
|
|
|
|
+ parseBondData(link, data)
|
|
case "ipvlan":
|
|
case "ipvlan":
|
|
parseIPVlanData(link, data)
|
|
parseIPVlanData(link, data)
|
|
case "macvlan":
|
|
case "macvlan":
|
|
parseMacvlanData(link, data)
|
|
parseMacvlanData(link, data)
|
|
case "macvtap":
|
|
case "macvtap":
|
|
parseMacvtapData(link, data)
|
|
parseMacvtapData(link, data)
|
|
|
|
+ case "gretap":
|
|
|
|
+ parseGretapData(link, data)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -591,6 +772,8 @@ func linkDeserialize(m []byte) (Link, error) {
|
|
base.MasterIndex = int(native.Uint32(attr.Value[0:4]))
|
|
base.MasterIndex = int(native.Uint32(attr.Value[0:4]))
|
|
case syscall.IFLA_TXQLEN:
|
|
case syscall.IFLA_TXQLEN:
|
|
base.TxQLen = int(native.Uint32(attr.Value[0:4]))
|
|
base.TxQLen = int(native.Uint32(attr.Value[0:4]))
|
|
|
|
+ case syscall.IFLA_IFALIAS:
|
|
|
|
+ base.Alias = string(attr.Value[:len(attr.Value)-1])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Links that don't have IFLA_INFO_KIND are hardware devices
|
|
// Links that don't have IFLA_INFO_KIND are hardware devices
|
|
@@ -772,6 +955,60 @@ func parseVxlanData(link Link, data []syscall.NetlinkRouteAttr) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func parseBondData(link Link, data []syscall.NetlinkRouteAttr) {
|
|
|
|
+ bond := NewLinkBond(NewLinkAttrs())
|
|
|
|
+ for i := range data {
|
|
|
|
+ switch data[i].Attr.Type {
|
|
|
|
+ case nl.IFLA_BOND_MODE:
|
|
|
|
+ bond.Mode = BondMode(data[i].Value[0])
|
|
|
|
+ case nl.IFLA_BOND_ACTIVE_SLAVE:
|
|
|
|
+ bond.ActiveSlave = int(native.Uint32(data[i].Value[0:4]))
|
|
|
|
+ case nl.IFLA_BOND_MIIMON:
|
|
|
|
+ bond.Miimon = int(native.Uint32(data[i].Value[0:4]))
|
|
|
|
+ case nl.IFLA_BOND_UPDELAY:
|
|
|
|
+ bond.UpDelay = int(native.Uint32(data[i].Value[0:4]))
|
|
|
|
+ case nl.IFLA_BOND_DOWNDELAY:
|
|
|
|
+ bond.DownDelay = int(native.Uint32(data[i].Value[0:4]))
|
|
|
|
+ case nl.IFLA_BOND_USE_CARRIER:
|
|
|
|
+ bond.UseCarrier = int(data[i].Value[0])
|
|
|
|
+ case nl.IFLA_BOND_ARP_INTERVAL:
|
|
|
|
+ bond.ArpInterval = int(native.Uint32(data[i].Value[0:4]))
|
|
|
|
+ case nl.IFLA_BOND_ARP_IP_TARGET:
|
|
|
|
+ // TODO: implement
|
|
|
|
+ case nl.IFLA_BOND_ARP_VALIDATE:
|
|
|
|
+ bond.ArpValidate = BondArpValidate(native.Uint32(data[i].Value[0:4]))
|
|
|
|
+ case nl.IFLA_BOND_ARP_ALL_TARGETS:
|
|
|
|
+ bond.ArpAllTargets = BondArpAllTargets(native.Uint32(data[i].Value[0:4]))
|
|
|
|
+ case nl.IFLA_BOND_PRIMARY:
|
|
|
|
+ bond.Primary = int(native.Uint32(data[i].Value[0:4]))
|
|
|
|
+ case nl.IFLA_BOND_PRIMARY_RESELECT:
|
|
|
|
+ bond.PrimaryReselect = BondPrimaryReselect(data[i].Value[0])
|
|
|
|
+ case nl.IFLA_BOND_FAIL_OVER_MAC:
|
|
|
|
+ bond.FailOverMac = BondFailOverMac(data[i].Value[0])
|
|
|
|
+ case nl.IFLA_BOND_XMIT_HASH_POLICY:
|
|
|
|
+ bond.XmitHashPolicy = BondXmitHashPolicy(data[i].Value[0])
|
|
|
|
+ case nl.IFLA_BOND_RESEND_IGMP:
|
|
|
|
+ bond.ResendIgmp = int(native.Uint32(data[i].Value[0:4]))
|
|
|
|
+ case nl.IFLA_BOND_NUM_PEER_NOTIF:
|
|
|
|
+ bond.NumPeerNotif = int(data[i].Value[0])
|
|
|
|
+ case nl.IFLA_BOND_ALL_SLAVES_ACTIVE:
|
|
|
|
+ bond.AllSlavesActive = int(data[i].Value[0])
|
|
|
|
+ case nl.IFLA_BOND_MIN_LINKS:
|
|
|
|
+ bond.MinLinks = int(native.Uint32(data[i].Value[0:4]))
|
|
|
|
+ case nl.IFLA_BOND_LP_INTERVAL:
|
|
|
|
+ bond.LpInterval = int(native.Uint32(data[i].Value[0:4]))
|
|
|
|
+ case nl.IFLA_BOND_PACKETS_PER_SLAVE:
|
|
|
|
+ bond.PackersPerSlave = int(native.Uint32(data[i].Value[0:4]))
|
|
|
|
+ case nl.IFLA_BOND_AD_LACP_RATE:
|
|
|
|
+ bond.LacpRate = BondLacpRate(data[i].Value[0])
|
|
|
|
+ case nl.IFLA_BOND_AD_SELECT:
|
|
|
|
+ bond.AdSelect = BondAdSelect(data[i].Value[0])
|
|
|
|
+ case nl.IFLA_BOND_AD_INFO:
|
|
|
|
+ // TODO: implement
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
func parseIPVlanData(link Link, data []syscall.NetlinkRouteAttr) {
|
|
func parseIPVlanData(link Link, data []syscall.NetlinkRouteAttr) {
|
|
ipv := link.(*IPVlan)
|
|
ipv := link.(*IPVlan)
|
|
for _, datum := range data {
|
|
for _, datum := range data {
|
|
@@ -828,3 +1065,96 @@ func linkFlags(rawFlags uint32) net.Flags {
|
|
}
|
|
}
|
|
return f
|
|
return f
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+func htonl(val uint32) []byte {
|
|
|
|
+ bytes := make([]byte, 4)
|
|
|
|
+ binary.BigEndian.PutUint32(bytes, val)
|
|
|
|
+ return bytes
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func htons(val uint16) []byte {
|
|
|
|
+ bytes := make([]byte, 2)
|
|
|
|
+ binary.BigEndian.PutUint16(bytes, val)
|
|
|
|
+ return bytes
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func ntohl(buf []byte) uint32 {
|
|
|
|
+ return binary.BigEndian.Uint32(buf)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func ntohs(buf []byte) uint16 {
|
|
|
|
+ return binary.BigEndian.Uint16(buf)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func addGretapAttrs(gretap *Gretap, linkInfo *nl.RtAttr) {
|
|
|
|
+ data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
|
|
|
|
+
|
|
|
|
+ ip := gretap.Local.To4()
|
|
|
|
+ if ip != nil {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_GRE_LOCAL, []byte(ip))
|
|
|
|
+ }
|
|
|
|
+ ip = gretap.Remote.To4()
|
|
|
|
+ if ip != nil {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_GRE_REMOTE, []byte(ip))
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if gretap.IKey != 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_GRE_IKEY, htonl(gretap.IKey))
|
|
|
|
+ gretap.IFlags |= uint16(nl.GRE_KEY)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if gretap.OKey != 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_GRE_OKEY, htonl(gretap.OKey))
|
|
|
|
+ gretap.OFlags |= uint16(nl.GRE_KEY)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_GRE_IFLAGS, htons(gretap.IFlags))
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_GRE_OFLAGS, htons(gretap.OFlags))
|
|
|
|
+
|
|
|
|
+ if gretap.Link != 0 {
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_GRE_LINK, nl.Uint32Attr(gretap.Link))
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_GRE_PMTUDISC, nl.Uint8Attr(gretap.PMtuDisc))
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_GRE_TTL, nl.Uint8Attr(gretap.Ttl))
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_GRE_TOS, nl.Uint8Attr(gretap.Tos))
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_GRE_ENCAP_TYPE, nl.Uint16Attr(gretap.EncapType))
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_GRE_ENCAP_FLAGS, nl.Uint16Attr(gretap.EncapFlags))
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_GRE_ENCAP_SPORT, htons(gretap.EncapSport))
|
|
|
|
+ nl.NewRtAttrChild(data, nl.IFLA_GRE_ENCAP_DPORT, htons(gretap.EncapDport))
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func parseGretapData(link Link, data []syscall.NetlinkRouteAttr) {
|
|
|
|
+ gre := link.(*Gretap)
|
|
|
|
+ for _, datum := range data {
|
|
|
|
+ switch datum.Attr.Type {
|
|
|
|
+ case nl.IFLA_GRE_OKEY:
|
|
|
|
+ gre.IKey = ntohl(datum.Value[0:4])
|
|
|
|
+ case nl.IFLA_GRE_IKEY:
|
|
|
|
+ gre.OKey = ntohl(datum.Value[0:4])
|
|
|
|
+ case nl.IFLA_GRE_LOCAL:
|
|
|
|
+ gre.Local = net.IP(datum.Value[0:4])
|
|
|
|
+ case nl.IFLA_GRE_REMOTE:
|
|
|
|
+ gre.Remote = net.IP(datum.Value[0:4])
|
|
|
|
+ case nl.IFLA_GRE_ENCAP_SPORT:
|
|
|
|
+ gre.EncapSport = ntohs(datum.Value[0:2])
|
|
|
|
+ case nl.IFLA_GRE_ENCAP_DPORT:
|
|
|
|
+ gre.EncapDport = ntohs(datum.Value[0:2])
|
|
|
|
+ case nl.IFLA_GRE_IFLAGS:
|
|
|
|
+ gre.IFlags = ntohs(datum.Value[0:2])
|
|
|
|
+ case nl.IFLA_GRE_OFLAGS:
|
|
|
|
+ gre.OFlags = ntohs(datum.Value[0:2])
|
|
|
|
+
|
|
|
|
+ case nl.IFLA_GRE_TTL:
|
|
|
|
+ gre.Ttl = uint8(datum.Value[0])
|
|
|
|
+ case nl.IFLA_GRE_TOS:
|
|
|
|
+ gre.Tos = uint8(datum.Value[0])
|
|
|
|
+ case nl.IFLA_GRE_PMTUDISC:
|
|
|
|
+ gre.PMtuDisc = uint8(datum.Value[0])
|
|
|
|
+ case nl.IFLA_GRE_ENCAP_TYPE:
|
|
|
|
+ gre.EncapType = native.Uint16(datum.Value[0:2])
|
|
|
|
+ case nl.IFLA_GRE_ENCAP_FLAGS:
|
|
|
|
+ gre.EncapFlags = native.Uint16(datum.Value[0:2])
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|