Skip to content

Commit c2b16e6

Browse files
committed
mgmtfn/k8splugin: refactor to remove nsenter
Signed-off-by: Cristian Staretu <cristian.staretu@gmail.com>
1 parent 7ef229a commit c2b16e6

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
const hostGWIP = "172.20.255.254"
@@ -212,131 +214,170 @@ func nsToPID(ns string) (int, error) {
212214
return strconv.Atoi(elements[2])
213215
}
214216

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

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

231237
return nil
232238
}
233239

234240
// setIfAttrs sets the required attributes for the container interface
235241
func setIfAttrs(pid int, ifname, cidr, newname string) error {
242+
runtime.LockOSThread()
243+
defer runtime.UnlockOSThread()
236244

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

250+
defer func() {
251+
netns.Set(globalNS)
252+
globalNS.Close()
253+
}()
254+
246255
// find the link
247256
link, err := getLink(ifname)
248257
if err != nil {
249-
log.Errorf("unable to find link %q. Error %q", ifname, err)
250-
return err
258+
return fmt.Errorf("unable to find link %q. Error %q", ifname, err)
251259
}
252260

253261
// move to the desired netns
254-
err = netlink.LinkSetNsPid(link, pid)
255-
if err != nil {
256-
log.Errorf("unable to move interface %s to pid %d. Error: %s",
262+
if err = netlink.LinkSetNsPid(link, pid); err != nil {
263+
return fmt.Errorf("unable to move interface %s to pid %d. Error: %s",
257264
ifname, pid, err)
258-
return err
259265
}
260266

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

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

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

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

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

298+
return nil
295299
}
296300

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

303-
ipPath, err := osexec.LookPath("ip")
304-
if err != nil {
305-
return err
310+
defer func() {
311+
netns.Set(globalNS)
312+
globalNS.Close()
313+
}()
314+
315+
if err = enterPIDNetNS(pid); err != nil {
316+
return fmt.Errorf("failed to enter network namespace of pid %v: %v", pid, err)
306317
}
307318

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

324+
// find the link
325+
link, err := getLink(intfName)
312326
if err != nil {
313-
log.Errorf("unable to add route %s via %s. Error: %s",
314-
subnet, intfName, err)
315-
return err
327+
return fmt.Errorf("unable to find link %q. Error %q", intfName, err)
328+
}
329+
330+
r := netlink.Route{LinkIndex: link.Attrs().Index,
331+
Dst: parsedSubnet,
332+
}
333+
334+
// set static route
335+
if err = netlink.RouteAdd(&r); err != nil {
336+
return fmt.Errorf("failed to set default gw %v. Error: %v", parsedSubnet, err)
316337
}
317338

318339
return nil
319340
}
320341

321342
// setDefGw sets the default gateway for the container namespace
322343
func setDefGw(pid int, gw, intfName string) error {
323-
nsenterPath, err := osexec.LookPath("nsenter")
344+
runtime.LockOSThread()
345+
defer runtime.UnlockOSThread()
346+
347+
globalNS, err := netns.Get()
324348
if err != nil {
325-
return err
349+
return fmt.Errorf("failed to get the global network namespace: %v", err)
350+
}
351+
352+
defer func() {
353+
netns.Set(globalNS)
354+
globalNS.Close()
355+
}()
356+
357+
if err = enterPIDNetNS(pid); err != nil {
358+
return fmt.Errorf("failed to enter network namespace of pid %v: %v", pid, err)
359+
}
360+
361+
addr := net.ParseIP(gw)
362+
if addr == nil {
363+
return fmt.Errorf("failed to parse address %v", gw)
326364
}
327-
routePath, err := osexec.LookPath("route")
365+
366+
// find the link
367+
link, err := getLink(intfName)
328368
if err != nil {
329-
return err
369+
return fmt.Errorf("unable to find link %q. Error %q", intfName, err)
330370
}
371+
372+
r := netlink.Route{LinkIndex: link.Attrs().Index,
373+
Gw: addr,
374+
}
375+
331376
// set default gw
332-
nsPid := fmt.Sprintf("%d", pid)
333-
out, err := osexec.Command(nsenterPath, "-t", nsPid, "-n", "-F", "--", routePath, "add",
334-
"default", "gw", gw, intfName).CombinedOutput()
335-
if err != nil {
336-
log.Errorf("unable to set default gw %s. Error: %s - %s",
337-
gw, err, out)
338-
return nil
377+
if err = netlink.RouteAdd(&r); err != nil {
378+
return fmt.Errorf("failed to set default gw %v. Error: %v", gw, err)
339379
}
380+
340381
return nil
341382
}
342383

0 commit comments

Comments
 (0)