Skip to content

Commit 7ff26c8

Browse files
committed
mgmtfn/k8splugin: refactor to remove nsenter
Signed-off-by: Cristian Staretu <[email protected]>
1 parent 2fe25af commit 7ff26c8

File tree

1 file changed

+110
-69
lines changed

1 file changed

+110
-69
lines changed

mgmtfn/k8splugin/driver.go

Lines changed: 110 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ import (
1919
"encoding/json"
2020
"fmt"
2121
"io/ioutil"
22+
"net"
2223
"net/http"
23-
osexec "os/exec"
24+
"runtime"
2425
"strconv"
2526
"strings"
2627
"time"
@@ -35,6 +36,7 @@ import (
3536
"github.com/contiv/netplugin/utils"
3637
"github.com/contiv/netplugin/utils/netutils"
3738
"github.com/vishvananda/netlink"
39+
"github.com/vishvananda/netns"
3840
)
3941

4042
// epSpec contains the spec of the Endpoint to be created
@@ -210,131 +212,170 @@ func nsToPID(ns string) (int, error) {
210212
return strconv.Atoi(elements[2])
211213
}
212214

213-
func moveToNS(pid int, ifname string) error {
214-
// find the link
215-
link, err := getLink(ifname)
215+
func setLinkAddress(link netlink.Link, address string) error {
216+
addr, err := netlink.ParseAddr(address)
216217
if err != nil {
217-
log.Errorf("unable to find link %q. Error %q", ifname, err)
218-
return err
218+
return fmt.Errorf("failed to parse address %s: %v", address, err)
219219
}
220220

221-
// move to the desired netns
222-
err = netlink.LinkSetNsPid(link, pid)
221+
return netlink.AddrAdd(link, addr)
222+
}
223+
224+
func enterPIDNetNS(pid int) error {
225+
netNS, err := netns.GetFromPid(pid)
223226
if err != nil {
224-
log.Errorf("unable to move interface %s to pid %d. Error: %s",
225-
ifname, pid, err)
226-
return err
227+
return fmt.Errorf("failed to get the netns of pid %v: %v", pid, err)
228+
}
229+
defer netNS.Close()
230+
231+
if err = netns.Set(netNS); err != nil {
232+
return fmt.Errorf("failed to enter network namespace of pid %v: %v", pid, err)
227233
}
228234

229235
return nil
230236
}
231237

232238
// setIfAttrs sets the required attributes for the container interface
233239
func setIfAttrs(pid int, ifname, cidr, newname string) error {
240+
runtime.LockOSThread()
241+
defer runtime.UnlockOSThread()
234242

235-
nsenterPath, err := osexec.LookPath("nsenter")
243+
globalNS, err := netns.Get()
236244
if err != nil {
237-
return err
238-
}
239-
ipPath, err := osexec.LookPath("ip")
240-
if err != nil {
241-
return err
245+
return fmt.Errorf("failed to get the global network namespace: %v", err)
242246
}
243247

248+
defer func() {
249+
netns.Set(globalNS)
250+
globalNS.Close()
251+
}()
252+
244253
// find the link
245254
link, err := getLink(ifname)
246255
if err != nil {
247-
log.Errorf("unable to find link %q. Error %q", ifname, err)
248-
return err
256+
return fmt.Errorf("unable to find link %q. Error %q", ifname, err)
249257
}
250258

251259
// move to the desired netns
252-
err = netlink.LinkSetNsPid(link, pid)
253-
if err != nil {
254-
log.Errorf("unable to move interface %s to pid %d. Error: %s",
260+
if err = netlink.LinkSetNsPid(link, pid); err != nil {
261+
return fmt.Errorf("unable to move interface %s to pid %d. Error: %s",
255262
ifname, pid, err)
256-
return err
257263
}
258264

259-
// rename to the desired ifname
260-
nsPid := fmt.Sprintf("%d", pid)
261-
rename, err := osexec.Command(nsenterPath, "-t", nsPid, "-n", "-F", "--", ipPath, "link",
262-
"set", "dev", ifname, "name", newname).CombinedOutput()
265+
netNS, err := netns.GetFromPid(pid)
263266
if err != nil {
264-
log.Errorf("unable to rename interface %s to %s. Error: %s",
265-
ifname, newname, err)
266-
return nil
267+
return fmt.Errorf("failed to get the netns of pid %v: %v", pid, err)
267268
}
268-
log.Infof("Output from rename: %v", rename)
269269

270-
// set the ip address
271-
assignIP, err := osexec.Command(nsenterPath, "-t", nsPid, "-n", "-F", "--", ipPath,
272-
"address", "add", cidr, "dev", newname).CombinedOutput()
270+
if err = netns.Set(netNS); err != nil {
271+
return fmt.Errorf("failed to enter network namespace of pid %v: %v", pid, err)
272+
}
273273

274+
link, err = getLink(ifname)
274275
if err != nil {
275-
log.Errorf("unable to assign ip %s to %s. Error: %s",
276-
cidr, newname, err)
277-
return nil
276+
return fmt.Errorf("unable to find link %q. Error %q", ifname, err)
278277
}
279-
log.Infof("Output from ip assign: %v", assignIP)
280278

281-
// Finally, mark the link up
282-
bringUp, err := osexec.Command(nsenterPath, "-t", nsPid, "-n", "-F", "--", ipPath,
283-
"link", "set", "dev", newname, "up").CombinedOutput()
279+
// rename the interface from ifname to newname
280+
if err := netlink.LinkSetName(link, newname); err != nil {
281+
return fmt.Errorf("failed to rename interface %v to %v: %v",
282+
link, newname, err)
283+
}
284284

285-
if err != nil {
286-
log.Errorf("unable to assign ip %s to %s. Error: %s",
287-
cidr, newname, err)
288-
return nil
285+
// set the ip address
286+
if err = setLinkAddress(link, cidr); err != nil {
287+
return fmt.Errorf("failed to bring up link %v: %v", newname, err)
288+
}
289+
290+
// set the link up
291+
if err = netlink.LinkSetUp(link); err != nil {
292+
return fmt.Errorf("unable to bring up interface %v with address %v: %v",
293+
newname, cidr, err)
289294
}
290-
log.Debugf("Output from ip assign: %v", bringUp)
291-
return nil
292295

296+
return nil
293297
}
294298

295299
func addStaticRoute(pid int, subnet, intfName string) error {
296-
nsenterPath, err := osexec.LookPath("nsenter")
300+
runtime.LockOSThread()
301+
defer runtime.UnlockOSThread()
302+
303+
globalNS, err := netns.Get()
297304
if err != nil {
298-
return err
305+
return fmt.Errorf("failed to get the global network namespace: %v", err)
299306
}
300307

301-
ipPath, err := osexec.LookPath("ip")
302-
if err != nil {
303-
return err
308+
defer func() {
309+
netns.Set(globalNS)
310+
globalNS.Close()
311+
}()
312+
313+
if err = enterPIDNetNS(pid); err != nil {
314+
return fmt.Errorf("failed to enter network namespace of pid %v: %v", pid, err)
304315
}
305316

306-
nsPid := fmt.Sprintf("%d", pid)
307-
_, err = osexec.Command(nsenterPath, "-t", nsPid, "-n", "-F", "--", ipPath,
308-
"route", "add", subnet, "dev", intfName).CombinedOutput()
317+
parsedSubnet, err := netlink.ParseIPNet(subnet)
318+
if err != nil {
319+
return fmt.Errorf("failed to parse subnet %v", subnet)
320+
}
309321

322+
// find the link
323+
link, err := getLink(intfName)
310324
if err != nil {
311-
log.Errorf("unable to add route %s via %s. Error: %s",
312-
subnet, intfName, err)
313-
return err
325+
return fmt.Errorf("unable to find link %q. Error %q", intfName, err)
326+
}
327+
328+
r := netlink.Route{LinkIndex: link.Attrs().Index,
329+
Dst: parsedSubnet,
330+
}
331+
332+
// set static route
333+
if err = netlink.RouteAdd(&r); err != nil {
334+
return fmt.Errorf("failed to set default gw %v. Error: %v", parsedSubnet, err)
314335
}
315336

316337
return nil
317338
}
318339

319340
// setDefGw sets the default gateway for the container namespace
320341
func setDefGw(pid int, gw, intfName string) error {
321-
nsenterPath, err := osexec.LookPath("nsenter")
342+
runtime.LockOSThread()
343+
defer runtime.UnlockOSThread()
344+
345+
globalNS, err := netns.Get()
322346
if err != nil {
323-
return err
347+
return fmt.Errorf("failed to get the global network namespace: %v", err)
348+
}
349+
350+
defer func() {
351+
netns.Set(globalNS)
352+
globalNS.Close()
353+
}()
354+
355+
if err = enterPIDNetNS(pid); err != nil {
356+
return fmt.Errorf("failed to enter network namespace of pid %v: %v", pid, err)
357+
}
358+
359+
addr := net.ParseIP(gw)
360+
if addr == nil {
361+
return fmt.Errorf("failed to parse address %v", gw)
324362
}
325-
routePath, err := osexec.LookPath("route")
363+
364+
// find the link
365+
link, err := getLink(intfName)
326366
if err != nil {
327-
return err
367+
return fmt.Errorf("unable to find link %q. Error %q", intfName, err)
328368
}
369+
370+
r := netlink.Route{LinkIndex: link.Attrs().Index,
371+
Gw: addr,
372+
}
373+
329374
// set default gw
330-
nsPid := fmt.Sprintf("%d", pid)
331-
out, err := osexec.Command(nsenterPath, "-t", nsPid, "-n", "-F", "--", routePath, "add",
332-
"default", "gw", gw, intfName).CombinedOutput()
333-
if err != nil {
334-
log.Errorf("unable to set default gw %s. Error: %s - %s",
335-
gw, err, out)
336-
return nil
375+
if err = netlink.RouteAdd(&r); err != nil {
376+
return fmt.Errorf("failed to set default gw %v. Error: %v", gw, err)
337377
}
378+
338379
return nil
339380
}
340381

0 commit comments

Comments
 (0)