func setupNetworking(c *Config) error { if c.IP == "" { return nil } // loopback iface, err := net.InterfaceByName("lo") if err != nil { return fmt.Errorf("Unable to set up networking: %v", err) } if err := netlink.NetworkLinkUp(iface); err != nil { return fmt.Errorf("Unable to set up networking: %v", err) } if iface, err = net.InterfaceByName("eth0"); err != nil { return fmt.Errorf("Unable to set up networking: %v", err) } ip, ipNet, err := net.ParseCIDR(c.IP) if err != nil { return fmt.Errorf("Unable to set up networking: %v", err) } if err := netlink.NetworkLinkAddIp(iface, ip, ipNet); err != nil { return fmt.Errorf("Unable to set up networking: %v", err) } if c.Gateway != "" { if err := netlink.AddDefaultGw(c.Gateway, "eth0"); err != nil { return fmt.Errorf("Unable to set up networking: %v", err) } } if err := netlink.NetworkLinkUp(iface); err != nil { return fmt.Errorf("Unable to set up networking: %v", err) } return nil }
func setupNetworking(args *ContainerInitArgs) error { // loopback iface, err := net.InterfaceByName("lo") if err != nil { return fmt.Errorf("Unable to set up networking: %v", err) } if err := netlink.NetworkLinkUp(iface); err != nil { return fmt.Errorf("Unable to set up networking: %v", err) } if args.ip != "" { if iface, err = net.InterfaceByName("eth0"); err != nil { return fmt.Errorf("Unable to set up networking: %v", err) } ip, ipNet, err := net.ParseCIDR(args.ip) if err != nil { return fmt.Errorf("Unable to set up networking: %v", err) } if err := netlink.NetworkLinkAddIp(iface, ip, ipNet); err != nil { return fmt.Errorf("Unable to set up networking: %v", err) } if args.gateway != "" { if err := netlink.AddDefaultGw(args.gateway, "eth0"); err != nil { return fmt.Errorf("Unable to set up networking: %v", err) } } if err := netlink.NetworkLinkUp(iface); err != nil { return fmt.Errorf("Unable to set up networking: %v", err) } } return nil }
// NewLinkWithOptions creates new network link on Linux host and sets some of its network // parameters passed in as LinkOptions // // Calling NewLinkWithOptions is equivalent of running following commands one after another if // particular option is passed in as a parameter: // ip link add name ${ifcName} type dummy // ip link set dev ${ifcName} address ${MAC address} // ip link set dev ${ifcName} mtu ${MTU value} // ip link set dev ${ifcName} up // NewLinkWithOptions returns Linker which is initialized to a pointer of type Link if the network // link with given LinkOptions was created successfully on the Linux host. // It attempts to delete the link if any of the LinkOptions are incorrect or if setting the options // failed and returns error. func NewLinkWithOptions(ifcName string, opts LinkOptions) (Linker, error) { if ok, err := NetInterfaceNameValid(ifcName); !ok { return nil, err } if _, err := net.InterfaceByName(ifcName); err == nil { return nil, fmt.Errorf("Interface name %s already assigned on the host", ifcName) } if err := netlink.NetworkLinkAdd(ifcName, "dummy"); err != nil { return nil, fmt.Errorf("Could not create new link %s: %s", ifcName, err) } newIfc, err := net.InterfaceByName(ifcName) if err != nil { return nil, fmt.Errorf("Could not find the new interface: %s", err) } if (opts != LinkOptions{}) { errOpts := setLinkOptions(newIfc, opts) if errOpts != nil { if errDel := DeleteLink(newIfc.Name); err != nil { return nil, fmt.Errorf("Incorrect options specified: %s. Attempt to delete the link failed: %s", errOpts, errDel) } return nil, fmt.Errorf("Could not set link options: %s", errOpts) } } return &Link{ ifc: newIfc, }, nil }
// NewMacVtapLink creates macvtap network link // // It is equivalent of running: // ip link add name mvt${RANDOM STRING} link ${master interface} type macvtap // NewMacVtapLink returns MacVtaper which is initialized to a pointer of type MacVtapLink if the // macvtap link was created successfully on the Linux host. Newly created link is assigned // a random name starting with "mvt". It sets the macvlan mode to "bridge" which is a default. // It returns error if the link could not be created. func NewMacVtapLink(masterDev string) (MacVtaper, error) { macVtapDev := makeNetInterfaceName("mvt") if ok, err := NetInterfaceNameValid(masterDev); !ok { return nil, err } if _, err := net.InterfaceByName(masterDev); err != nil { return nil, fmt.Errorf("Master MAC VTAP device %s does not exist on the host", masterDev) } if err := netlink.NetworkLinkAddMacVtap(masterDev, macVtapDev, default_mode); err != nil { return nil, err } macVtapIfc, err := net.InterfaceByName(macVtapDev) if err != nil { return nil, fmt.Errorf("Could not find the new interface: %s", err) } masterIfc, err := net.InterfaceByName(masterDev) if err != nil { return nil, fmt.Errorf("Could not find the new interface: %s", err) } return &MacVtapLink{ MacVlanLink: &MacVlanLink{ Link: Link{ ifc: macVtapIfc, }, masterIfc: masterIfc, mode: default_mode, }, }, nil }
// attach a container network interface to an external network func (v *veth) attach(n *configs.Network) (err error) { bridge, err := net.InterfaceByName(n.Bridge) if err != nil { return err } host, err := net.InterfaceByName(n.HostInterfaceName) if err != nil { return err } if err := netlink.AddToBridge(host, bridge); err != nil { return err } if err := netlink.NetworkSetMTU(host, n.Mtu); err != nil { return err } if n.HairpinMode { if err := netlink.SetHairpinMode(host, true); err != nil { return err } } if err := netlink.NetworkLinkUp(host); err != nil { return err } return nil }
// NewVethPair creates a pair of veth network links. // // It is equivalent of running: // ip link add name veth${RANDOM STRING} type veth peer name veth${RANDOM STRING}. // NewVethPair returns Vether which is initialized to a pointer of type VethPair if the // veth link was successfully created on Linux host. Newly created pair of veth links // are assigned random names starting with "veth". // NewVethPair returns error if the veth pair could not be created. func NewVethPair() (Vether, error) { ifcName := makeNetInterfaceName("veth") peerName := makeNetInterfaceName("veth") if err := netlink.NetworkCreateVethPair(ifcName, peerName, 0); err != nil { return nil, err } newIfc, err := net.InterfaceByName(ifcName) if err != nil { return nil, fmt.Errorf("Could not find the new interface: %s", err) } peerIfc, err := net.InterfaceByName(peerName) if err != nil { return nil, fmt.Errorf("Could not find the new interface: %s", err) } return &VethPair{ Link: Link{ ifc: newIfc, }, peerIfc: peerIfc, }, nil }
// Create creates a bridge device and returns the interface. // If the device already exists, returns the existing interface. func (Bridge) Create(name string, ip net.IP, subnet *net.IPNet) (intf *net.Interface, err error) { netlinkMu.Lock() defer netlinkMu.Unlock() if intf, _ := net.InterfaceByName(name); intf != nil { return intf, nil } link := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: name}} if err := netlink.LinkAdd(link); err != nil && err.Error() != "file exists" { return nil, fmt.Errorf("devices: create bridge: %v", err) } hAddr, _ := net.ParseMAC(randMacAddr()) err = netlink.LinkSetHardwareAddr(link, hAddr) if err != nil { return nil, fmt.Errorf("devices: set hardware address: %v", err) } if intf, err = net.InterfaceByName(name); err != nil { return nil, fmt.Errorf("devices: look up created bridge interface: %v", err) } addr := &netlink.Addr{IPNet: &net.IPNet{IP: ip, Mask: subnet.Mask}} if err = netlink.AddrAdd(link, addr); err != nil && err.Error() != "file exists" { return nil, fmt.Errorf("devices: add IP to bridge: %v", err) } return intf, nil }
func (mon *Monitor) Run(m *monitor.Monitor) { memory := GetMemoryStats() lanEth, _ := net.InterfaceByName("eth1") wanEth, _ := net.InterfaceByName("eth0") iData := InterfaceData{lanEth, wanEth} mon1 := HWMon{"hwmon0", []string{"2", "3"}} mon2 := HWMon{"hwmon1", []string{"1"}} temps1, err := mon1.Temperatures() if err != nil { panic(err) } temps2, err := mon2.Temperatures() if err != nil { panic(err) } allTemps := make(map[string]float64) for key, value := range temps1 { allTemps[key] = value } for key, value := range temps2 { allTemps[key] = value } data := Data{memory, iData, allTemps} m.SendData(&data) }
// // netlink package tests which do not use RTNETLINK // func TestCreateBridgeWithMac(t *testing.T) { if testing.Short() { return } name := "testbridge" if err := CreateBridge(name, true); err != nil { t.Fatal(err) } if _, err := net.InterfaceByName(name); err != nil { t.Fatal(err) } // cleanup and tests if err := DeleteBridge(name); err != nil { t.Fatal(err) } if _, err := net.InterfaceByName(name); err == nil { t.Fatalf("expected error getting interface because %s bridge was deleted", name) } }
// NewBridge creates new network bridge on Linux host. // // It is equivalent of running: ip link add name br${RANDOM STRING} type bridge // NewBridge returns Bridger which is initialized to a pointer of type Bridge if the // bridge was created successfully on the Linux host. Newly created bridge is assigned // a random name starting with "br". // It returns error if the bridge could not be created. func NewBridge() (Bridger, error) { brDev := makeNetInterfaceName("br") if ok, err := NetInterfaceNameValid(brDev); !ok { return nil, err } if _, err := net.InterfaceByName(brDev); err == nil { return nil, fmt.Errorf("Interface name %s already assigned on the host", brDev) } if err := netlink.NetworkLinkAdd(brDev, "bridge"); err != nil { return nil, err } newIfc, err := net.InterfaceByName(brDev) if err != nil { return nil, fmt.Errorf("Could not find the new interface: %s", err) } return &Bridge{ Link: Link{ ifc: newIfc, }, }, nil }
func GetTapFd(tapname, bridge string) (device string, tapFile *os.File, err error) { var ( req ifReq errno syscall.Errno ) tapFile, err = os.OpenFile("/dev/net/tun", os.O_RDWR, 0) if err != nil { return "", nil, err } req.Flags = CIFF_TAP | CIFF_NO_PI | CIFF_ONE_QUEUE if tapname != "" { copy(req.Name[:len(req.Name)-1], []byte(tapname)) } _, _, errno = syscall.Syscall(syscall.SYS_IOCTL, tapFile.Fd(), uintptr(syscall.TUNSETIFF), uintptr(unsafe.Pointer(&req))) if errno != 0 { err = fmt.Errorf("create tap device failed\n") tapFile.Close() return "", nil, err } device = strings.Trim(string(req.Name[:]), "\x00") tapIface, err := net.InterfaceByName(device) if err != nil { glog.Errorf("get interface by name %s failed %s", device, err) tapFile.Close() return "", nil, err } bIface, err := net.InterfaceByName(bridge) if err != nil { glog.Errorf("get interface by name %s failed", bridge) tapFile.Close() return "", nil, err } err = AddToBridge(tapIface, bIface) if err != nil { glog.Errorf("Add to bridge failed %s %s", bridge, device) tapFile.Close() return "", nil, err } err = NetworkLinkUp(tapIface) if err != nil { glog.Errorf("Link up device %s failed", device) tapFile.Close() return "", nil, err } return device, tapFile, nil }
func (v *veth) initialize(config *network) error { peer := config.TempVethPeerName if peer == "" { return fmt.Errorf("peer is not specified") } child, err := net.InterfaceByName(peer) if err != nil { return err } if err := netlink.NetworkLinkDown(child); err != nil { return err } if err := netlink.NetworkChangeName(child, config.Name); err != nil { return err } // get the interface again after we changed the name as the index also changes. if child, err = net.InterfaceByName(config.Name); err != nil { return err } if config.MacAddress != "" { if err := netlink.NetworkSetMacAddress(child, config.MacAddress); err != nil { return err } } ip, ipNet, err := net.ParseCIDR(config.Address) if err != nil { return err } if err := netlink.NetworkLinkAddIp(child, ip, ipNet); err != nil { return err } if config.IPv6Address != "" { if ip, ipNet, err = net.ParseCIDR(config.IPv6Address); err != nil { return err } if err := netlink.NetworkLinkAddIp(child, ip, ipNet); err != nil { return err } } if err := netlink.NetworkSetMTU(child, config.Mtu); err != nil { return err } if err := netlink.NetworkLinkUp(child); err != nil { return err } if config.Gateway != "" { if err := netlink.AddDefaultGw(config.Gateway, config.Name); err != nil { return err } } if config.IPv6Gateway != "" { if err := netlink.AddDefaultGw(config.IPv6Gateway, config.Name); err != nil { return err } } return nil }
func ExternalIp(config *config.ClusterConfig) (string, string, error) { mgmtIp := "" dataIp := "" if config.MgtIface != "" { iface, err := net.InterfaceByName(config.MgtIface) if err != nil { return "", "", errors.New("Invalid management network " + "interface specified.") } mgmtIp, err = ifaceToIp(iface) if err != nil { return "", "", err } } if config.DataIface != "" { iface, err := net.InterfaceByName(config.DataIface) if err != nil { return "", "", errors.New("Invalid data network interface " + "specified.") } dataIp, err = ifaceToIp(iface) if err != nil { return "", "", err } } if mgmtIp != "" && dataIp != "" { return mgmtIp, dataIp, nil } else if mgmtIp != "" { // dataIp is empty return mgmtIp, mgmtIp, nil } else if dataIp != "" { // mgmtIp is empty return dataIp, dataIp, nil } // both are empty, try to pick first available interface for both // No network interface specified, pick first default. ifaces, err := net.Interfaces() if err != nil { return "", "", err } for _, iface := range ifaces { if iface.Flags&net.FlagUp == 0 { continue // interface down } if iface.Flags&net.FlagLoopback != 0 { continue // loopback interface } mgmtIp, err = ifaceToIp(&iface) return mgmtIp, mgmtIp, err } return "", "", errors.New("Node not connected to the network.") }
func Test_NewVethPairWithOptions(t *testing.T) { for _, tt := range vethOptionTests { tl := &testLink{} if err := tl.prepTestLink(tt.hostIfc, ""); err != nil { t.Skipf("NewVlanLink test requries external command: %v", err) } veth, err := NewVethPairWithOptions(tt.hostIfc, tt.vethOptions) if err != nil { t.Fatalf("NewVethPairWithOptions(%s, %v) failed to run: %s", tt.hostIfc, tt.vethOptions, err) } if _, err := net.InterfaceByName(tt.hostIfc); err != nil { t.Fatalf("Could not find %s on the host: %s", tt.hostIfc, err) } if _, err := net.InterfaceByName(tt.vethOptions.PeerName); err != nil { t.Fatalf("Could not find %s on the host: %s", tt.vethOptions.PeerName, err) } vethIfcName := veth.NetInterface().Name if vethIfcName != tt.hostIfc { tl.teardown() t.Fatalf("NewVethPairWithOptions(%s, %v) failed: expected host ifc %s, returned %s", tt.hostIfc, tt.vethOptions, tt.hostIfc, vethIfcName) } vethPeerName := veth.PeerNetInterface().Name if vethPeerName != tt.vethOptions.PeerName { tl.teardown() t.Fatalf("NewVethPairWithOptions(%s, %v) failed: expected peer ifc %s, returned %s", tt.hostIfc, tt.vethOptions, tt.vethOptions.PeerName, vethPeerName) } testRes, err := linkInfo(tt.hostIfc, "veth") if err != nil { tl.teardown() t.Fatalf("Failed to list %s operation mode: %s", tt.hostIfc, err) } if testRes.linkType != "veth" { tl.teardown() t.Fatalf("NewVethPairWithOptions(%s, %v) failed: expected linktype veth, returned %s", tt.hostIfc, tt.vethOptions, testRes.linkType) } if err := tl.teardown(); err != nil { t.Fatalf("testLink.teardown failed: %v", err) } else { time.Sleep(10 * time.Millisecond) } } }
func SetInterfaceMaster(name, master string) error { iface, err := net.InterfaceByName(name) if err != nil { return err } masterIface, err := net.InterfaceByName(master) if err != nil { return err } return netlink.NetworkSetMaster(iface, masterIface) }
func LoopbackInterface() (lo *net.Interface, err error) { lo, err = net.InterfaceByName("lo0") if err != nil { lo, err = net.InterfaceByName("lo") if err != nil { Error.Printf("could not find `lo0` or `lo`: `%s`", err) return } } return }
func createVethPair(handle string, wshdPID int, containerIP string, containerIPAddressMask int, containerMTU int) (string, error) { hostIfName := fmt.Sprintf("o-%s-0", handle) containerIfName := fmt.Sprintf("o-%s-1", handle) vethCreator := devices.VethCreator{} hostIf, containerIf, err := vethCreator.Create(hostIfName, containerIfName) if err != nil { if !strings.Contains(err.Error(), "Network interface already exists") { return "", err } hostIf, err = net.InterfaceByName(hostIfName) if err != nil { return "", err } containerIf, err = net.InterfaceByName(containerIfName) if err != nil && !strings.Contains(err.Error(), "no such network interface") { return "", err } } link := devices.Link{} if containerIf != nil { err = link.SetNs(containerIf, wshdPID) if err != nil { return "", err } fmt.Printf("container if: %+v\n", containerIf) } if hostIf != nil { fmt.Printf("host if: %+v\n", hostIf) } err = runInNamespace(handle, fmt.Sprintf("ip addr add %s/%d dev %s", containerIP, containerIPAddressMask, containerIfName)) if err != nil && !strings.Contains(err.Error(), "RTNETLINK answers: File exists") { return "", err } err = runInNamespace(handle, fmt.Sprintf("ip link set %s up", containerIfName)) if err != nil { return "", err } err = runInNamespace(handle, fmt.Sprintf("ip link set dev %s mtu %d", containerIfName, containerMTU)) if err != nil { return "", err } return hostIfName, nil }
func attachVlanInterface(name, bridgeName string) error { int1, err := net.InterfaceByName(name) if err != nil { return err } int2, err := net.InterfaceByName(bridgeName) if err != nil { return err } return dnetlink.NetworkSetMaster(int1, int2) }
func addToBridge(ifaceName, bridgeName string) error { iface, err := net.InterfaceByName(ifaceName) if err != nil { return fmt.Errorf("could not find interface %s: %v", ifaceName, err) } master, err := net.InterfaceByName(bridgeName) if err != nil { return fmt.Errorf("could not find bridge %s: %v", bridgeName, err) } return bri.AddToBridge(iface, master) }
func (v *veth) detach(n *configs.Network) (err error) { bridge, err := net.InterfaceByName(n.Bridge) if err != nil { return err } host, err := net.InterfaceByName(n.HostInterfaceName) if err != nil { return err } if err := netlink.DelFromBridge(host, bridge); err != nil { return err } return nil }
// NewVethPairWithOptions creates a pair of veth network links. // // It is equivalent of running: // ip link add name ${first device name} type veth peer name ${second device name} // NewVethPairWithOptions returns Vether which is initialized to a pointer of type VethPair if the // veth link was successfully created on the Linux host. It accepts VethOptions which allow you to set // peer interface name. It returns error if the veth pair could not be created. func NewVethPairWithOptions(ifcName string, opts VethOptions) (Vether, error) { peerName := opts.PeerName txQLen := opts.TxQueueLen if ok, err := NetInterfaceNameValid(ifcName); !ok { return nil, err } if _, err := net.InterfaceByName(ifcName); err == nil { return nil, fmt.Errorf("Interface name %s already assigned on the host", ifcName) } if peerName != "" { if ok, err := NetInterfaceNameValid(peerName); !ok { return nil, err } if _, err := net.InterfaceByName(peerName); err == nil { return nil, fmt.Errorf("Interface name %s already assigned on the host", peerName) } } else { peerName = makeNetInterfaceName("veth") } if txQLen < 0 { return nil, fmt.Errorf("TX queue length must be a positive integer: %d", txQLen) } if err := netlink.NetworkCreateVethPair(ifcName, peerName, txQLen); err != nil { return nil, err } newIfc, err := net.InterfaceByName(ifcName) if err != nil { return nil, fmt.Errorf("Could not find the new interface: %s", err) } peerIfc, err := net.InterfaceByName(peerName) if err != nil { return nil, fmt.Errorf("Could not find the new interface: %s", err) } return &VethPair{ Link: Link{ ifc: newIfc, }, peerIfc: peerIfc, }, nil }
// Return the IPv4 address of a network interface func getIfaceAddr(name string) (net.Addr, error) { iface, err := net.InterfaceByName(name) if err != nil { return nil, err } addrs, err := iface.Addrs() if err != nil { return nil, err } var addrs4 []net.Addr for _, addr := range addrs { ip := (addr.(*net.IPNet)).IP if ip4 := ip.To4(); len(ip4) == net.IPv4len { addrs4 = append(addrs4, addr) } } switch { case len(addrs4) == 0: return nil, fmt.Errorf("Interface %v has no IP addresses", name) case len(addrs4) > 1: fmt.Printf("Interface %v has more than 1 IPv4 address. Defaulting to using %v\n", name, (addrs4[0].(*net.IPNet)).IP) } return addrs4[0], nil }
func Test_NewBridge(t *testing.T) { tl := &testLink{} br, err := NewBridge() if err != nil { t.Fatalf("NewBridge() failed to run: %s", err) } brName := br.NetInterface().Name if err := tl.prepTestLink(brName, "bridge"); err != nil { t.Skipf("NewBridge test requries external command: %v", err) } if _, err := net.InterfaceByName(brName); err != nil { tl.teardown() t.Fatalf("Could not find %s on the host: %s", brName, err) } testRes, err := linkInfo(brName, "bridge") if err != nil { tl.teardown() t.Fatalf("Failed to list %s operation mode: %s", brName, err) } if testRes.linkType != "bridge" { tl.teardown() t.Fatalf("NewBridge() failed: expected linktype bridge, returned %s", testRes.linkType) } if err := tl.teardown(); err != nil { t.Fatalf("testLink.teardown failed: %v", err) } else { time.Sleep(10 * time.Millisecond) } }
func getBindAddr(ifaceName string) (string, error) { iface, err := net.InterfaceByName(ifaceName) if err != nil { return "", fmt.Errorf("failed to find interface %s: %v", ifaceName, err) } addrs, err := iface.Addrs() if err != nil { return "", fmt.Errorf("failed to get interface addresses: %v", err) } for _, a := range addrs { addr, ok := a.(*net.IPNet) if !ok { continue } addrIP := addr.IP if addrIP.IsLinkLocalUnicast() { continue } return addrIP.String(), nil } return "", fmt.Errorf("failed to get bind address") }
func Start(serverMode bool, bootstrap bool, bindInterface string, dataDir string) error { bindAddress := "" if bindInterface != "" { intf, err := net.InterfaceByName(bindInterface) if err != nil { log.Printf("Error : %v", err) return err } addrs, err := intf.Addrs() if err == nil { for i := 0; i < len(addrs); i++ { addr := addrs[i].String() ip, _, _ := net.ParseCIDR(addr) if ip != nil && ip.To4() != nil { bindAddress = ip.To4().String() } } } } errCh := make(chan int) watchForExistingRegisteredUpdates() go RegisterForNodeUpdates(listener) go startConsul(serverMode, bootstrap, bindAddress, dataDir, errCh) select { case <-errCh: return errors.New("Error starting Consul Agent") case <-time.After(time.Second * 5): } return nil }
func GetIPv6LinkLocalNeighborAddress(ifname string) (string, error) { ifi, err := net.InterfaceByName(ifname) if err != nil { return "", err } neighs, err := netlink.NeighList(ifi.Index, netlink.FAMILY_V6) if err != nil { return "", err } cnt := 0 var addr net.IP for _, neigh := range neighs { local, err := isLocalLinkLocalAddress(ifi.Index, neigh.IP) if err != nil { return "", err } if neigh.IP.IsLinkLocalUnicast() && !local { addr = neigh.IP cnt += 1 } } if cnt == 0 { return "", fmt.Errorf("no ipv6 link-local neighbor found") } else if cnt > 1 { return "", fmt.Errorf("found %d link-local neighbors. only support p2p link", cnt) } return fmt.Sprintf("%s%%%s", addr, ifname), nil }
// Take in an interface name ("lo", "eth0", "any") passed from either // a config setting, by using the -listenInterface flag on client or // -interface flag on server from the command line and return the IP // address associated with it. // If no interface is provided use the default loopback interface (127.0.0.1). // If "any" is passed then listen on 0.0.0.0 for client (invalid with server) func GetInterfaceIPAddress(listenInterface string) (string, error) { var ip net.IP if listenInterface == "" { ip = net.ParseIP("127.0.0.1") return ip.String(), nil } else if listenInterface == "any" { ip = net.ParseIP("0.0.0.0") return ip.String(), nil } else { availableInterfaces, err := net.InterfaceByName(listenInterface) if err != nil { return "", common.ContextError(err) } addrs, err := availableInterfaces.Addrs() if err != nil { return "", common.ContextError(err) } for _, addr := range addrs { iptype := addr.(*net.IPNet) if iptype == nil { continue } // TODO: IPv6 support ip = iptype.IP.To4() if ip == nil { continue } return ip.String(), nil } } return "", common.ContextError(errors.New("Could not find IP address of specified interface")) }
func open(c *Conn) error { var err error c.file, err = os.OpenFile("/dev/net/tun", os.O_RDWR, 0) if err != nil { return err } ifr := &ifReq{} ifr.Flags = iff_TUN | iff_NO_PI | iff_TUN_EXCL _, _, e := syscall.Syscall(syscall.SYS_IOCTL, c.file.Fd(), tunSETIFF, uintptr(unsafe.Pointer(ifr))) if e != 0 { return syscall.Errno(e) } i := 0 for ifr.Name[i] != 0 { i++ } s := string(ifr.Name[:i]) ifi, err := net.InterfaceByName(s) if err != nil { c.file.Close() return err } c.ifindex = ifi.Index return nil }
// Add MAC VLAN network interface with masterDev as its upper device // This is identical to running: // ip link add name $name link $masterdev type macvlan mode $mode func networkLinkMacVlan(dev_type string, mcvln *MacVlanLink) error { s, err := getNetlinkSocket() if err != nil { return err } defer s.Close() wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) masterDevIfc, err := net.InterfaceByName(mcvln.MasterDev) if err != nil { return err } msg := newIfInfomsg(syscall.AF_UNSPEC) wb.AddData(msg) nest1 := newRtAttr(syscall.IFLA_LINKINFO, nil) newRtAttrChild(nest1, IFLA_INFO_KIND, nonZeroTerminated(dev_type)) nest2 := newRtAttrChild(nest1, IFLA_INFO_DATA, nil) macVlanData := make([]byte, 4) native.PutUint32(macVlanData, mcvln.Mode()) newRtAttrChild(nest2, IFLA_MACVLAN_MODE, macVlanData) wb.AddData(nest1) wb.AddData(uint32Attr(syscall.IFLA_LINK, uint32(masterDevIfc.Index))) wb.AddData(newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(mcvln.SlaveDev))) if err := s.Send(wb); err != nil { return err } return s.HandleAck(wb.Seq) }
// Add a new VLAN interface with masterDev as its upper device // This is identical to running: // ip link add name $name link $masterdev type vlan id $id func NetworkLinkAddVlan(masterDev, vlanDev string, vlanId uint16) error { s, err := getNetlinkSocket() if err != nil { return err } defer s.Close() wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) masterDevIfc, err := net.InterfaceByName(masterDev) if err != nil { return err } msg := newIfInfomsg(syscall.AF_UNSPEC) wb.AddData(msg) nest1 := newRtAttr(syscall.IFLA_LINKINFO, nil) newRtAttrChild(nest1, IFLA_INFO_KIND, nonZeroTerminated("vlan")) nest2 := newRtAttrChild(nest1, IFLA_INFO_DATA, nil) vlanData := make([]byte, 2) native.PutUint16(vlanData, vlanId) newRtAttrChild(nest2, IFLA_VLAN_ID, vlanData) wb.AddData(nest1) wb.AddData(uint32Attr(syscall.IFLA_LINK, uint32(masterDevIfc.Index))) wb.AddData(newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(vlanDev))) if err := s.Send(wb); err != nil { return err } return s.HandleAck(wb.Seq) }