From 46ae81cf70c46dcbee8f7374f5714a8b8b7fe128 Mon Sep 17 00:00:00 2001 From: Adrian Chiris Date: Sun, 28 Jul 2019 15:54:18 +0300 Subject: [PATCH] Add support for IPoIB interfaces - Add a new Link type, IPoIB, that exposes the following IPoIB attributes: * IFLA_IPOIB_PKEY * IFLA_IPOIB_MODE * IFLA_IPOIB_UMCAST - Suppport Deserialize for IPoIB link attributes in LinkDeserialize() - Support IPoIB attributes in LinkAdd() --- link.go | 42 ++++++++++++++++++++++++++++++++++++++++++ link_linux.go | 31 +++++++++++++++++++++++++++++-- nl/link_linux.go | 8 ++++++++ 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/link.go b/link.go index eaf420f..3d62790 100644 --- a/link.go +++ b/link.go @@ -918,6 +918,48 @@ func (xfrm *Xfrmi) Type() string { return "xfrm" } +// IPoIB interface + +type IPoIBMode uint16 + +func (m *IPoIBMode) String() string { + str, ok := iPoIBModeToString[*m] + if !ok { + return fmt.Sprintf("mode(%d)", *m) + } + return str +} + +const ( + IPOIB_MODE_DATAGRAM = iota + IPOIB_MODE_CONNECTED +) + +var iPoIBModeToString = map[IPoIBMode]string{ + IPOIB_MODE_DATAGRAM: "datagram", + IPOIB_MODE_CONNECTED: "connected", +} + +var StringToIPoIBMode = map[string]IPoIBMode{ + "datagram": IPOIB_MODE_DATAGRAM, + "connected": IPOIB_MODE_CONNECTED, +} + +type IPoIB struct { + LinkAttrs + Pkey uint16 + Mode IPoIBMode + Umcast uint16 +} + +func (ipoib *IPoIB) Attrs() *LinkAttrs { + return &ipoib.LinkAttrs +} + +func (ipoib *IPoIB) Type() string { + return "ipoib" +} + // iproute2 supported devices; // vlan | veth | vcan | dummy | ifb | macvlan | macvtap | // bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan | diff --git a/link_linux.go b/link_linux.go index 0e59390..7ab769d 100644 --- a/link_linux.go +++ b/link_linux.go @@ -1150,8 +1150,8 @@ func (h *Handle) linkModify(link Link, flags int) error { native.PutUint32(b, uint32(base.ParentIndex)) data := nl.NewRtAttr(unix.IFLA_LINK, b) req.AddData(data) - } else if link.Type() == "ipvlan" { - return fmt.Errorf("Can't create ipvlan link without ParentIndex") + } else if link.Type() == "ipvlan" || link.Type() == "ipoib" { + return fmt.Errorf("Can't create %s link without ParentIndex", link.Type()) } nameData := nl.NewRtAttr(unix.IFLA_IFNAME, nl.ZeroTerminated(base.Name)) @@ -1278,6 +1278,8 @@ func (h *Handle) linkModify(link Link, flags int) error { addGTPAttrs(link, linkInfo) case *Xfrmi: addXfrmiAttrs(link, linkInfo) + case *IPoIB: + addIPoIBAttrs(link, linkInfo) } req.AddData(linkInfo) @@ -1533,6 +1535,8 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) { link = &Xfrmi{} case "tun": link = &Tuntap{} + case "ipoib": + link = &IPoIB{} default: link = &GenericLink{LinkType: linkType} } @@ -1578,6 +1582,8 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) { parseXfrmiData(link, data) case "tun": parseTuntapData(link, data) + case "ipoib": + parseIPoIBData(link, data) } } } @@ -2776,3 +2782,24 @@ func parseTuntapData(link Link, data []syscall.NetlinkRouteAttr) { } } } + +func parseIPoIBData(link Link, data []syscall.NetlinkRouteAttr) { + ipoib := link.(*IPoIB) + for _, datum := range data { + switch datum.Attr.Type { + case nl.IFLA_IPOIB_PKEY: + ipoib.Pkey = uint16(native.Uint16(datum.Value)) + case nl.IFLA_IPOIB_MODE: + ipoib.Mode = IPoIBMode(native.Uint16(datum.Value)) + case nl.IFLA_IPOIB_UMCAST: + ipoib.Umcast = uint16(native.Uint16(datum.Value)) + } + } +} + +func addIPoIBAttrs(ipoib *IPoIB, linkInfo *nl.RtAttr) { + data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil) + data.AddRtAttr(nl.IFLA_IPOIB_PKEY, nl.Uint16Attr(uint16(ipoib.Pkey))) + data.AddRtAttr(nl.IFLA_IPOIB_MODE, nl.Uint16Attr(uint16(ipoib.Mode))) + data.AddRtAttr(nl.IFLA_IPOIB_UMCAST, nl.Uint16Attr(uint16(ipoib.Umcast))) +} diff --git a/nl/link_linux.go b/nl/link_linux.go index 4ee92da..56e1cee 100644 --- a/nl/link_linux.go +++ b/nl/link_linux.go @@ -596,3 +596,11 @@ const ( IFLA_TUN_NUM_DISABLED_QUEUES IFLA_TUN_MAX = IFLA_TUN_NUM_DISABLED_QUEUES ) + +const ( + IFLA_IPOIB_UNSPEC = iota + IFLA_IPOIB_PKEY + IFLA_IPOIB_MODE + IFLA_IPOIB_UMCAST + IFLA_IPOIB_MAX = IFLA_IPOIB_UMCAST +)