Skip to content

Commit ab3c05e

Browse files
committed
replace linkmodify with netlink calls
Change-Id: Ie8051797546ce16b3a3ff29b85b5cfdd6be14724
1 parent bd6040f commit ab3c05e

File tree

1 file changed

+72
-23
lines changed

1 file changed

+72
-23
lines changed

pkg/driver/hostdevice.go

Lines changed: 72 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,16 @@ import (
2020
"fmt"
2121

2222
"github.com/vishvananda/netlink"
23+
"github.com/vishvananda/netlink/nl"
2324
"github.com/vishvananda/netns"
25+
"golang.org/x/sys/unix"
2426
)
2527

2628
func nsAttachNetdev(hostIfName string, containerNsPAth string, ifName string) error {
2729
hostDev, err := netlink.LinkByName(hostIfName)
2830
if err != nil {
2931
return err
3032
}
31-
attrs := netlink.NewLinkAttrs()
32-
attrs.Index = hostDev.Attrs().Index
33-
attrs.MTU = hostDev.Attrs().MTU
34-
attrs.HardwareAddr = hostDev.Attrs().HardwareAddr
35-
attrs.Name = ifName
36-
// Store the original name
37-
attrs.Alias = hostIfName
3833

3934
// Devices can be renamed only when down
4035
if err = netlink.LinkSetDown(hostDev); err != nil {
@@ -45,15 +40,46 @@ func nsAttachNetdev(hostIfName string, containerNsPAth string, ifName string) er
4540
if err != nil {
4641
return err
4742
}
48-
attrs.Namespace = netlink.NsFd(containerNs)
4943

50-
dev := &netlink.Device{
51-
LinkAttrs: attrs,
44+
attrs := hostDev.Attrs()
45+
// Store the original name
46+
attrs.Alias = hostIfName
47+
48+
// copy from netlink.LinkModify(dev) using only the parts needed
49+
flags := unix.NLM_F_REQUEST | unix.NLM_F_ACK
50+
req := nl.NewNetlinkRequest(unix.RTM_NEWLINK, flags)
51+
// Get a netlink socket in current namespace
52+
s, err := nl.GetNetlinkSocketAt(netns.None(), netns.None(), unix.NETLINK_ROUTE)
53+
if err != nil {
54+
return fmt.Errorf("could not get network namespace handle: %w", err)
5255
}
56+
req.Sockets = map[int]*nl.SocketHandle{
57+
unix.NETLINK_ROUTE: {Socket: s},
58+
}
59+
60+
msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
61+
msg.Index = int32(attrs.Index)
62+
req.AddData(msg)
63+
64+
nameData := nl.NewRtAttr(unix.IFLA_IFNAME, nl.ZeroTerminated(attrs.Name))
65+
req.AddData(nameData)
66+
67+
alias := nl.NewRtAttr(unix.IFLA_IFALIAS, []byte(attrs.Alias))
68+
req.AddData(alias)
69+
70+
mtu := nl.NewRtAttr(unix.IFLA_MTU, nl.Uint32Attr(uint32(attrs.MTU)))
71+
req.AddData(mtu)
72+
73+
val := nl.Uint32Attr(uint32(containerNs))
74+
attr := nl.NewRtAttr(unix.IFLA_NET_NS_FD, val)
75+
req.AddData(attr)
5376

54-
err = netlink.LinkModify(dev)
77+
linkInfo := nl.NewRtAttr(unix.IFLA_LINKINFO, nil)
78+
linkInfo.AddRtAttr(nl.IFLA_INFO_KIND, nil)
79+
80+
_, err = req.Execute(unix.NETLINK_ROUTE, 0)
5581
if err != nil {
56-
return fmt.Errorf("could not modify network device %s : %w", hostIfName, err)
82+
return err
5783
}
5884

5985
// to avoid golang problem with goroutines we create the socket in the
@@ -63,9 +89,9 @@ func nsAttachNetdev(hostIfName string, containerNsPAth string, ifName string) er
6389
return err
6490
}
6591

66-
nsLink, err := nhNs.LinkByName(dev.Name)
92+
nsLink, err := nhNs.LinkByName(attrs.Name)
6793
if err != nil {
68-
return fmt.Errorf("link not found for interface %s on namespace %s: %w", dev.Name, containerNsPAth, err)
94+
return fmt.Errorf("link not found for interface %s on namespace %s: %w", attrs.Name, containerNsPAth, err)
6995
}
7096

7197
err = nhNs.LinkSetUp(nsLink)
@@ -100,9 +126,7 @@ func nsDetachNetdev(containerNsPAth string, devName string) error {
100126
return err
101127
}
102128

103-
attrs := netlink.NewLinkAttrs()
104-
attrs.Index = nsLink.Attrs().Index
105-
attrs.Name = devName
129+
attrs := nsLink.Attrs()
106130
// restore the original name if it was renamed
107131
if nsLink.Attrs().Alias != "" {
108132
attrs.Name = nsLink.Attrs().Alias
@@ -114,15 +138,40 @@ func nsDetachNetdev(containerNsPAth string, devName string) error {
114138
}
115139
defer rootNs.Close()
116140

117-
attrs.Namespace = netlink.NsFd(rootNs)
118-
119-
dev := &netlink.Device{
120-
LinkAttrs: attrs,
141+
s, err := nl.GetNetlinkSocketAt(containerNs, rootNs, unix.NETLINK_ROUTE)
142+
if err != nil {
143+
return fmt.Errorf("could not get network namespace handle: %w", err)
144+
}
145+
// copy from netlink.LinkModify(dev) using only the parts needed
146+
flags := unix.NLM_F_REQUEST | unix.NLM_F_ACK
147+
req := nl.NewNetlinkRequest(unix.RTM_NEWLINK, flags)
148+
req.Sockets = map[int]*nl.SocketHandle{
149+
unix.NETLINK_ROUTE: {Socket: s},
121150
}
151+
msg := nl.NewIfInfomsg(unix.AF_UNSPEC)
152+
msg.Index = int32(attrs.Index)
153+
req.AddData(msg)
154+
155+
nameData := nl.NewRtAttr(unix.IFLA_IFNAME, nl.ZeroTerminated(attrs.Name))
156+
req.AddData(nameData)
122157

123-
err = netlink.LinkModify(dev)
158+
alias := nl.NewRtAttr(unix.IFLA_IFALIAS, []byte(attrs.Alias))
159+
req.AddData(alias)
160+
161+
mtu := nl.NewRtAttr(unix.IFLA_MTU, nl.Uint32Attr(uint32(attrs.MTU)))
162+
req.AddData(mtu)
163+
164+
val := nl.Uint32Attr(uint32(rootNs))
165+
attr := nl.NewRtAttr(unix.IFLA_NET_NS_FD, val)
166+
req.AddData(attr)
167+
168+
linkInfo := nl.NewRtAttr(unix.IFLA_LINKINFO, nil)
169+
linkInfo.AddRtAttr(nl.IFLA_INFO_KIND, nil)
170+
171+
_, err = req.Execute(unix.NETLINK_ROUTE, 0)
124172
if err != nil {
125-
return fmt.Errorf("could not modify network device %s : %w", devName, err)
173+
return err
126174
}
175+
127176
return nil
128177
}

0 commit comments

Comments
 (0)