diff --git a/net/netdev.go b/net/netdev.go index 1c777d29..35480cbf 100644 --- a/net/netdev.go +++ b/net/netdev.go @@ -1,54 +1,20 @@ package net import ( + "encoding/json" "fmt" "net" "os" - "regexp" "strconv" - "strings" "github.com/vishvananda/netlink" "github.com/vishvananda/netns" ) -var netdevRegExp = regexp.MustCompile(`^([^ ]+?) ([^ ]+?) \[([^]]*)\]$`) - type Dev struct { - Name string - MAC net.HardwareAddr - CIDRs []*net.IPNet -} - -func (d Dev) String() string { - return fmt.Sprintf("%s %s %s", d.Name, d.MAC, d.CIDRs) -} - -func ParseNetDev(netdev string) (Dev, error) { - match := netdevRegExp.FindStringSubmatch(netdev) - if match == nil { - return Dev{}, fmt.Errorf("invalid netdev: %s", netdev) - } - - iface := match[1] - mac, err := net.ParseMAC(match[2]) - if err != nil { - return Dev{}, fmt.Errorf("cannot parse mac %s: %s", match[2], err) - } - - var cidrs []*net.IPNet - for _, cidr := range strings.Split(match[3], " ") { - if cidr != "" { - ip, ipnet, err := net.ParseCIDR(cidr) - if err != nil { - return Dev{}, fmt.Errorf("cannot parse cidr %s: %s", cidr, err) - } - ipnet.IP = ip - cidrs = append(cidrs, ipnet) - } - } - - return Dev{Name: iface, MAC: mac, CIDRs: cidrs}, nil + Name string `json:"Name,omitempty"` + MAC net.HardwareAddr `json:"MAC,omitempty"` + CIDRs []*net.IPNet `json:"CIDRs,omitempty"` } func LinkToNetDev(link netlink.Link) (Dev, error) { @@ -125,26 +91,17 @@ func GetNetDevsByVethPeerIds(processID int, peerIDs []int) ([]Dev, error) { } var netdevs []Dev - peersStr := make([]string, len(peerIDs)) for i, id := range peerIDs { peersStr[i] = strconv.Itoa(id) } - netdevsStr, err := WithNetNSByPid(processID, "list-netdevs", strings.Join(peersStr, ",")) + nds, err := WithNetNSByPid(processID, "list-netdevs", peersStr...) if err != nil { return nil, fmt.Errorf("list-netdevs failed: %s", err) } - for _, netdevStr := range strings.Split(netdevsStr, "\n") { - if netdevStr != "" { - netdev, err := ParseNetDev(netdevStr) - if err != nil { - return nil, fmt.Errorf("cannot parse netdev %s: %s", netdevStr, err) - } - netdevs = append(netdevs, netdev) - } - } + err = json.Unmarshal(nds, &netdevs) - return netdevs, nil + return netdevs, err } // Get the weave bridge interface. diff --git a/net/netns.go b/net/netns.go index 5e9e205f..f3a8816a 100644 --- a/net/netns.go +++ b/net/netns.go @@ -59,7 +59,7 @@ func WithNetNSLinkUnsafe(ns netns.NsHandle, ifName string, work func(link netlin // A safe version of WithNetNS* which creates a process executing // "nsenter --net= weaveutil [args]". -func WithNetNS(nsPath string, cmd string, args ...string) (string, error) { +func WithNetNS(nsPath string, cmd string, args ...string) ([]byte, error) { var stdout, stderr bytes.Buffer args = append([]string{"--net=" + nsPath, "weaveutil", cmd}, args...) @@ -67,13 +67,13 @@ func WithNetNS(nsPath string, cmd string, args ...string) (string, error) { c.Stdout = &stdout c.Stderr = &stderr if err := c.Run(); err != nil { - return "", fmt.Errorf("%s: %s", string(stderr.Bytes()), err) + return nil, fmt.Errorf("%s: %s", string(stderr.Bytes()), err) } - return string(stdout.Bytes()), nil + return stdout.Bytes(), nil } -func WithNetNSByPid(pid int, cmd string, args ...string) (string, error) { +func WithNetNSByPid(pid int, cmd string, args ...string) ([]byte, error) { return WithNetNS(NSPathByPid(pid), cmd, args...) } diff --git a/prog/weaveutil/netdev.go b/prog/weaveutil/netdev.go index a2f29fb0..d35e395b 100644 --- a/prog/weaveutil/netdev.go +++ b/prog/weaveutil/netdev.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "fmt" "strconv" "strings" @@ -97,12 +98,12 @@ func configureARP(args []string) error { // listNetDevs outputs network ifaces identified by the given indexes // in the format of weavenet.Dev. func listNetDevs(args []string) error { - if len(args) != 1 { - cmdUsage("list-netdevs", "[,]") + if len(args) == 0 { + cmdUsage("list-netdevs", "[ ]") } indexes := make(map[int]struct{}) - for _, index := range strings.Split(args[0], ",") { + for _, index := range args { if index != "" { id, err := strconv.Atoi(index) if err != nil { @@ -117,15 +118,23 @@ func listNetDevs(args []string) error { return err } + var netdevs []weavenet.Dev + for _, link := range links { if _, found := indexes[link.Attrs().Index]; found { netdev, err := weavenet.LinkToNetDev(link) if err != nil { return err } - fmt.Println(netdev) + netdevs = append(netdevs, netdev) } } + nds, err := json.Marshal(netdevs) + if err != nil { + return err + } + fmt.Println(string(nds)) + return nil }