func createSlaveInterfaces(netCfg *NetworkConfig) { links, err := netlink.LinkList() if err != nil { log.Errorf("Failed to list links: %v", err) return } for _, link := range links { match, ok := findMatch(link, netCfg) if !ok { continue } vlanDefs, err := ParseVlanDefinitions(match.Vlans) if err != nil { log.Errorf("Failed to create vlans on device %s: %v", link.Attrs().Name, err) continue } for _, vlanDef := range vlanDefs { if _, err = NewVlan(link, vlanDef.Name, vlanDef.Id); err != nil { log.Errorf("Failed to create vlans on device %s, id %d: %v", link.Attrs().Name, vlanDef.Id, err) } } } }
// Address specific func handleAddr(update netlink.AddrUpdate, callback func(supervisor.NetlinkUpdate)) { if update.NewAddr { fmt.Printf("[Add a address]") } else { fmt.Printf("[Delete a address]") } if update.LinkAddress.IP.To4() != nil { fmt.Printf("[IPv4]\t%+v\n", update) } else { // We would not like to handle IPv6 at present. fmt.Printf("[IPv6]\t%+v\n", update) return } netlinkUpdate := supervisor.NetlinkUpdate{} netlinkUpdate.Addr = update netlinkUpdate.UpdateType = supervisor.UpdateTypeAddr links, err := netlink.LinkList() if err != nil { glog.Error(err) } for _, link := range links { if link.Attrs().Index == update.LinkIndex && link.Type() == "veth" { netlinkUpdate.Veth = link.(*netlink.Veth) break } } callback(netlinkUpdate) }
func resourceLXCBridgeDelete(d *schema.ResourceData, meta interface{}) error { bridgeIndex, err := strconv.Atoi(d.Id()) if err != nil { return fmt.Errorf("Internal error reading resource ID: %v", err) } bridge, err := netlink.LinkByIndex(bridgeIndex) if err != nil { return fmt.Errorf("Unable to find bridge %v: %v", bridgeIndex, err) } links, err := netlink.LinkList() if err != nil { return fmt.Errorf("Error listing interfaces: %v", err) } bridgeEmpty := true for _, link := range links { if link.Attrs().MasterIndex == bridge.Attrs().Index { bridgeEmpty = false log.Printf("[INFO] Link %s is still attached to bridge %s", link.Attrs().Name, bridge.Attrs().Name) } } if bridgeEmpty == false { return fmt.Errorf("Unable to delete bridge %s. Interfaces are still attached to it.", bridge.Attrs().Name) } else { if err := netlink.LinkDel(bridge); err != nil { return fmt.Errorf("Error deleting bridge: %s", err) } } return nil }
func NewNetlinkMonitor(g canvas.Graph, r *Renderer, modules *bpf.BpfTable) (res *NetlinkMonitor, err error) { nlmon := &NetlinkMonitor{ updates: make(chan netlink.LinkUpdate), done: make(chan struct{}), flush: make(chan struct{}), nodes: make(map[int]*ExtInterface), g: g, r: r, modules: modules, } err = netlink.LinkSubscribe(nlmon.updates, nlmon.done) defer func() { if err != nil { nlmon.Close() } }() if err != nil { return } links, err := netlink.LinkList() if err != nil { return } for _, link := range links { nlmon.handleNewlink(link) } Debug.Println("NewNetlinkMonitor DONE") go nlmon.ParseLinkUpdates() res = nlmon return }
func waitForIface() (netlink.Link, error) { logrus.Debugf("Starting to wait for network interface") start := time.Now() for { fmt.Printf(".") if time.Since(start) > 5*time.Second { fmt.Printf("\n") return nil, fmt.Errorf("failed to find veth interface in 5 seconds") } // get list of all interfaces lst, err := netlink.LinkList() if err != nil { fmt.Printf("\n") return nil, err } for _, l := range lst { // if we found "veth" interface - it's time to continue setup if l.Type() == "veth" { fmt.Printf("\n") return l, nil } } time.Sleep(100 * time.Millisecond) } }
func RunDhcp(netCfg *NetworkConfig, setHostname, setDns bool) error { populateDefault(netCfg) links, err := netlink.LinkList() if err != nil { return err } dhcpLinks := map[string]string{} for _, link := range links { if match, ok := findMatch(link, netCfg); ok && match.DHCP { dhcpLinks[link.Attrs().Name] = match.DHCPArgs } } //run dhcp wg := sync.WaitGroup{} for iface, args := range dhcpLinks { wg.Add(1) go func(iface, args string) { runDhcp(netCfg, iface, args, setHostname, setDns) wg.Done() }(iface, args) } wg.Wait() return err }
// GetNetlinkAddrList returns a list of local IP addresses func GetNetlinkAddrList() ([]string, error) { var addrList []string // get the link list linkList, err := netlink.LinkList() if err != nil { return addrList, err } log.Debugf("Got link list(%d): %+v", len(linkList), linkList) // Loop thru each interface and add its ip addr to list for _, link := range linkList { if strings.HasPrefix(link.Attrs().Name, "docker") || strings.HasPrefix(link.Attrs().Name, "veth") || strings.HasPrefix(link.Attrs().Name, "vport") || strings.HasPrefix(link.Attrs().Name, "lo") { continue } addrs, err := netlink.AddrList(link, netlink.FAMILY_V4) if err != nil { return addrList, err } for _, addr := range addrs { addrList = append(addrList, addr.IP.String()) } } return addrList, err }
func ApplyNetworkConfigs(netCfg *NetworkConfig) error { populateDefault(netCfg) log.Debugf("Config: %#v", netCfg) runCmds(netCfg.PreCmds, "") createInterfaces(netCfg) createSlaveInterfaces(netCfg) links, err := netlink.LinkList() if err != nil { return err } //apply network config for _, link := range links { linkName := link.Attrs().Name if match, ok := findMatch(link, netCfg); ok && !match.DHCP { if err := applyInterfaceConfig(link, match); err != nil { log.Errorf("Failed to apply settings to %s : %v", linkName, err) } } } runCmds(netCfg.PostCmds, "") return err }
// Search the network namespace of a process for interfaces matching a predicate func FindNetDevs(procPath string, processID int, match func(string) bool) ([]NetDev, error) { var netDevs []NetDev ns, err := netns.GetFromPath(fmt.Sprintf("%s/%d/ns/net", procPath, processID)) if err != nil { return nil, err } defer ns.Close() err = WithNetNS(ns, func() error { links, err := netlink.LinkList() if err != nil { return err } for _, link := range links { if match(link.Attrs().Name) { addrs, err := netlink.AddrList(link, netlink.FAMILY_V4) if err != nil { return err } netDev := NetDev{MAC: link.Attrs().HardwareAddr} for _, addr := range addrs { netDev.CIDRs = append(netDev.CIDRs, addr.IPNet) } netDevs = append(netDevs, netDev) } } return nil }) return netDevs, err }
// Returns a list of routes func RouteMap() *map[string]Route { links, _ := netlink.LinkList() linksMap := make(map[int]string) for _, l := range links { attrs := *l.Attrs() linksMap[attrs.Index] = attrs.Name } routes := make(map[string]Route) routeList, _ := netlink.RouteList(nil, netlink.FAMILY_V4) for _, r := range routeList { if_ := linksMap[r.LinkIndex] rdst := r.Dst var dst string if rdst != nil { dst = rdst.String() } else { dst = "default" } route := Route{ Via: r.Gw, Dev: if_, Src: r.Src, } routes[dst] = route } return &routes }
func GetBridgeFromIndex(idx int) (string, error) { var attr, bridge *netlink.LinkAttrs links, err := netlink.LinkList() if err != nil { glog.Error(err) return "", err } for _, link := range links { if link.Type() != "veth" { continue } if link.Attrs().Index == idx { attr = link.Attrs() break } } if attr == nil { return "", fmt.Errorf("cann't find nic whose ifindex is %d", idx) } for _, link := range links { if link.Type() != "bridge" && link.Type() != "openvswitch" { continue } if link.Attrs().Index == attr.MasterIndex { bridge = link.Attrs() break } } if bridge == nil { return "", fmt.Errorf("cann't find bridge contains nic whose ifindex is %d", idx) } if bridge.Name == "ovs-system" { veth, err := netlink.LinkByIndex(idx) if err != nil { return "", err } out, err := exec.Command("ovs-vsctl", "port-to-br", veth.Attrs().Name).CombinedOutput() if err != nil { return "", err } bridge.Name = strings.TrimSpace(string(out)) } glog.Infof("find bridge %s", bridge.Name) return bridge.Name, nil }
func (u *NetLinkProbe) initialize() { links, err := netlink.LinkList() if err != nil { logging.GetLogger().Errorf("Unable to list interfaces: %s", err.Error()) return } for _, link := range links { u.addLinkToTopology(link) } }
func linkListing() { links, err := netlink.LinkList() if err != nil { panic(err) } fmt.Println("Interface listing:") for _, link := range links { fmt.Println(link.Attrs().Name) } }
func IsVethExists(vethHostName string) (bool, error) { links, err := netlink.LinkList() if err != nil { return false, errors.Wrap(err, "Veth existing check error") } for _, link := range links { if link.Attrs().Name == vethHostName { return true, nil } } return false, nil }
func forEachLink(f func(netlink.Link) error) error { links, err := netlink.LinkList() if err != nil { return err } for _, link := range links { if err := f(link); err != nil { return err } } return nil }
func (d *Driver) cleanup(netID string) { links, err := d.getLinks(netID) if err != nil { log.Errorf("Error getting links: %v", err) return } VxlanIndex := links.Vxlan.LinkAttrs.Index allLinks, err := netlink.LinkList() if err != nil { log.Errorf("Error getting all links: %v", err) return } // Do nothing if other interfaces are slaves of the vxlan interface for _, link := range allLinks { if link.Attrs().MasterIndex == VxlanIndex { log.Debugf("Interface still attached to vxlan: %v", link) return } } // Do nothing if there are other containers in this network netResource, err := d.docker.NetworkInspect(context.Background(), netID) if err != nil { log.Errorf("Error inspecting network: %v", err) return } netName := netResource.Name containers, err := d.docker.ContainerList(context.Background(), dockertypes.ContainerListOptions{}) if err != nil { log.Errorf("Error getting containers: %v", err) return } for _, container := range containers { if _, ok := container.NetworkSettings.Networks[netName]; ok { log.Debugf("Other containers are still connected to this network") return } } log.Debugf("No interfaces attached to vxlan: deleting vxlan interface.") err = d.deleteNics(netID) if err != nil { log.Errorf("Error deleting nics: %v", err) } return }
func (adapter *HostAdapter) Interfaces() <-chan Interface { ch := make(chan Interface) go func() { defer close(ch) links, err := netlink.LinkList() if err != nil { return } for _, link := range links { ch <- &HostInterface{ id: link.Attrs().Index, name: link.Attrs().Name, } } }() return ch }
func getLinkIndex(ip net.IP) (int, error) { links, err := netlink.LinkList() if err != nil { return -1, fmt.Errorf("Failed to get links") } for _, link := range links { addrs, err := netlink.AddrList(link, netlink.FAMILY_ALL) if err != nil { return -1, fmt.Errorf("Failed to get addrs") } for _, addr := range addrs { if addr.IP.Equal(ip) { return link.Attrs().Index, nil } } } return -1, fmt.Errorf("Could not find address") }
func ApplyNetworkConfigs(netCfg *NetworkConfig) error { populateDefault(netCfg) log.Debugf("Config: %#v", netCfg) runCmds(netCfg.PreCmds, "") createInterfaces(netCfg) createSlaveInterfaces(netCfg) links, err := netlink.LinkList() if err != nil { return err } dhcpLinks := map[string]string{} //apply network config for _, link := range links { linkName := link.Attrs().Name if match, ok := findMatch(link, netCfg); ok { if match.DHCP { dhcpLinks[link.Attrs().Name] = match.DHCPArgs } else if err = applyInterfaceConfig(link, match); err != nil { log.Errorf("Failed to apply settings to %s : %v", linkName, err) } } } //run dhcp wg := sync.WaitGroup{} for iface, args := range dhcpLinks { wg.Add(1) go func(iface, args string) { runDhcp(iface, args) wg.Done() }(iface, args) } wg.Wait() runCmds(netCfg.PostCmds, "") return err }
func deleteVxlanByVNI(vni uint32) error { defer osl.InitOSContext()() links, err := netlink.LinkList() if err != nil { return fmt.Errorf("failed to list interfaces while deleting vxlan interface by vni: %v", err) } for _, l := range links { if l.Type() == "vxlan" && l.(*netlink.Vxlan).VxlanId == int(vni) { err = netlink.LinkDel(l) if err != nil { return fmt.Errorf("error deleting vxlan interface with id %d: %v", vni, err) } return nil } } return fmt.Errorf("could not find a vxlan interface to delete with id %d", vni) }
func collectionInterfaceInfo() []supervisor.InterfaceInfo { infos := []supervisor.InterfaceInfo{} links, err := netlink.LinkList() if err != nil { glog.Error(err) return infos } for _, link := range links { if link.Type() != "veth" { // lo is here too continue } addrs, err := netlink.AddrList(link, netlink.FAMILY_V4) if err != nil { glog.Error(err) return infos } for _, addr := range addrs { info := supervisor.InterfaceInfo{ Ip: addr.IPNet.String(), Index: link.Attrs().Index, PeerIndex: link.Attrs().ParentIndex, } glog.Infof("get interface %v", info) infos = append(infos, info) } // set link down, tap device take over it netlink.LinkSetDown(link) } return infos }
func (c *Cluster) resolveSystemAddr() (net.IP, error) { // Use the system's only device IP address, or fail if there are // multiple addresses to choose from. interfaces, err := netlink.LinkList() if err != nil { return nil, err } var systemAddr net.IP var systemInterface string for _, intf := range interfaces { // Skip non device or inactive interfaces if intf.Type() != "device" || intf.Attrs().Flags&net.FlagUp == 0 { continue } addrs, err := netlink.AddrList(intf, netlink.FAMILY_ALL) if err != nil { continue } var interfaceAddr4, interfaceAddr6 net.IP for _, addr := range addrs { ipAddr := addr.IPNet.IP // Skip loopback and link-local addresses if !ipAddr.IsGlobalUnicast() { continue } if ipAddr.To4() != nil { if interfaceAddr4 != nil { return nil, errMultipleIPs(intf.Attrs().Name, intf.Attrs().Name, interfaceAddr4, ipAddr) } interfaceAddr4 = ipAddr } else { if interfaceAddr6 != nil { return nil, errMultipleIPs(intf.Attrs().Name, intf.Attrs().Name, interfaceAddr6, ipAddr) } interfaceAddr6 = ipAddr } } // In the case that this interface has exactly one IPv4 address // and exactly one IPv6 address, favor IPv4 over IPv6. if interfaceAddr4 != nil { if systemAddr != nil { return nil, errMultipleIPs(systemInterface, intf.Attrs().Name, systemAddr, interfaceAddr4) } systemAddr = interfaceAddr4 systemInterface = intf.Attrs().Name } else if interfaceAddr6 != nil { if systemAddr != nil { return nil, errMultipleIPs(systemInterface, intf.Attrs().Name, systemAddr, interfaceAddr6) } systemAddr = interfaceAddr6 systemInterface = intf.Attrs().Name } } if systemAddr == nil { return nil, errNoIP } return systemAddr, nil }
func (*nl) LinkList() ([]netlink.Link, error) { return netlink.LinkList() }
func (c *Cluster) resolveSystemAddr() (net.IP, error) { // Use the system's only device IP address, or fail if there are // multiple addresses to choose from. interfaces, err := netlink.LinkList() if err != nil { return nil, err } var ( systemAddr net.IP systemInterface string deviceFound bool ) for _, intf := range interfaces { // Skip non device or inactive interfaces if intf.Type() != "device" || intf.Attrs().Flags&net.FlagUp == 0 { continue } addrs, err := netlink.AddrList(intf, netlink.FAMILY_ALL) if err != nil { continue } var interfaceAddr4, interfaceAddr6 net.IP for _, addr := range addrs { ipAddr := addr.IPNet.IP // Skip loopback and link-local addresses if !ipAddr.IsGlobalUnicast() { continue } // At least one non-loopback device is found and it is administratively up deviceFound = true if ipAddr.To4() != nil { if interfaceAddr4 != nil { return nil, errMultipleIPs(intf.Attrs().Name, intf.Attrs().Name, interfaceAddr4, ipAddr) } interfaceAddr4 = ipAddr } else { if interfaceAddr6 != nil { return nil, errMultipleIPs(intf.Attrs().Name, intf.Attrs().Name, interfaceAddr6, ipAddr) } interfaceAddr6 = ipAddr } } // In the case that this interface has exactly one IPv4 address // and exactly one IPv6 address, favor IPv4 over IPv6. if interfaceAddr4 != nil { if systemAddr != nil { return nil, errMultipleIPs(systemInterface, intf.Attrs().Name, systemAddr, interfaceAddr4) } systemAddr = interfaceAddr4 systemInterface = intf.Attrs().Name } else if interfaceAddr6 != nil { if systemAddr != nil { return nil, errMultipleIPs(systemInterface, intf.Attrs().Name, systemAddr, interfaceAddr6) } systemAddr = interfaceAddr6 systemInterface = intf.Attrs().Name } } if systemAddr == nil { if !deviceFound { // If no non-loopback device type interface is found, // fall back to the regular auto-detection mechanism. // This is to cover the case where docker is running // inside a container (eths are in fact veths). return c.resolveSystemAddrViaSubnetCheck() } return nil, errNoIP } return systemAddr, nil }
addrs, err := netlink.AddrList(link, syscall.AF_INET) Expect(err).NotTo(HaveOccurred()) Expect(len(addrs)).To(BeNumerically(">", 0)) found := false subnetPrefix, subnetBits := subnet.Mask.Size() for _, a := range addrs { aPrefix, aBits := a.IPNet.Mask.Size() if a.IPNet.IP.Equal(gwaddr) && aPrefix == subnetPrefix && aBits == subnetBits { found = true break } } Expect(found).To(Equal(true)) // Check for the veth link in the main namespace links, err := netlink.LinkList() Expect(err).NotTo(HaveOccurred()) Expect(len(links)).To(Equal(3)) // Bridge, veth, and loopback for _, l := range links { switch { case l.Attrs().Name == BRNAME: { _, isBridge := l.(*netlink.Bridge) Expect(isBridge).To(Equal(true)) hwAddr := fmt.Sprintf("%s", l.Attrs().HardwareAddr) Expect(hwAddr).To(HavePrefix(hwaddr.PrivateMACPrefixString)) } case l.Attrs().Name != BRNAME && l.Attrs().Name != "lo": { _, isVeth := l.(*netlink.Veth) Expect(isVeth).To(Equal(true))
func ApplyNetworkConfigs(netCfg *config.NetworkConfig) error { if err := createInterfaces(netCfg); err != nil { return err } links, err := netlink.LinkList() if err != nil { return err } //apply network config for _, link := range links { linkName := link.Attrs().Name var match config.InterfaceConfig for key, netConf := range netCfg.Interfaces { if netConf.Match == "" { netConf.Match = key } if netConf.Match == "" { continue } if len(netConf.Match) > 4 && strings.ToLower(netConf.Match[:3]) == "mac" { haAddr, err := net.ParseMAC(netConf.Match[4:]) if err != nil { return err } if bytes.Compare(haAddr, link.Attrs().HardwareAddr) == 0 { // MAC address match is used over all other matches match = netConf break } } // "" means match has not been found if match.Match == "" && matches(linkName, netConf.Match) { match = netConf } if netConf.Match == linkName { // Found exact match, use it over wildcard match match = netConf } } if match.Match != "" { err = applyNetConf(link, match) if err != nil { log.Errorf("Failed to apply settings to %s : %v", linkName, err) } } } if err != nil { return err } //post run if netCfg.PostRun != nil { return docker.StartAndWait(config.DOCKER_SYSTEM_HOST, netCfg.PostRun) } return nil }
func ApplyNetworkConfigs(netCfg *NetworkConfig) error { log.Debugf("Config: %#v", netCfg) if err := createInterfaces(netCfg); err != nil { return err } links, err := netlink.LinkList() if err != nil { return err } dhcpLinks := []string{} //apply network config for _, link := range links { linkName := link.Attrs().Name var match InterfaceConfig for key, netConf := range netCfg.Interfaces { if netConf.Match == "" { netConf.Match = key } if netConf.Match == "" { continue } if len(netConf.Match) > 4 && strings.ToLower(netConf.Match[:3]) == "mac" { haAddr, err := net.ParseMAC(netConf.Match[4:]) if err != nil { return err } if bytes.Compare(haAddr, link.Attrs().HardwareAddr) == 0 { // MAC address match is used over all other matches match = netConf break } } // "" means match has not been found if match.Match == "" && matches(linkName, netConf.Match) { match = netConf } if netConf.Match == linkName { // Found exact match, use it over wildcard match match = netConf } } if match.Match != "" { if match.DHCP { dhcpLinks = append(dhcpLinks, link.Attrs().Name) } else if err = applyNetConf(link, match); err != nil { log.Errorf("Failed to apply settings to %s : %v", linkName, err) } } } if len(dhcpLinks) > 0 { log.Infof("Running DHCP on %v", dhcpLinks) dhcpcdArgs := append([]string{"-MA4", "-e", "force_hostname=true"}, dhcpLinks...) cmd := exec.Command("dhcpcd", dhcpcdArgs...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { log.Error(err) } } if err != nil { return err } return nil }
// configureNetwork handles iterating the local interfaces, matching it to an // interface configuration, and configuring it. It will also handle configuring // the default gateway after all interfaces are configured. func (r *runner) configureNetwork() error { r.log.Info("Configuring network...") links, err := netlink.LinkList() if err != nil { return fmt.Errorf("failed to list network interfaces: %v", err) } for _, link := range links { linkName := link.Attrs().Name r.log.Debugf("Configuring %s...", linkName) // look for a matching network config entry var netconf *kurmaNetworkInterface for _, n := range r.config.NetworkConfig.Interfaces { if linkName == n.Device { netconf = n break } if match, _ := regexp.MatchString(n.Device, linkName); match { netconf = n break } } // handle if none are found if netconf == nil { r.log.Warn("- no matching network configuraton found") continue } // configure it if err := configureInterface(link, netconf); err != nil { r.log.Warnf("- %s", err.Error()) } } // configure the gateway if r.config.NetworkConfig.Gateway != "" { gateway := net.ParseIP(r.config.NetworkConfig.Gateway) if gateway == nil { r.log.Warnf("Failed to configure gatway to %q", r.config.NetworkConfig.Gateway) } route := &netlink.Route{ Scope: netlink.SCOPE_UNIVERSE, Gw: gateway, } if err := netlink.RouteAdd(route); err != nil { r.log.Warnf("Failed to configure gateway: %v", err) return nil } r.log.Infof("Configured gatway to %s", r.config.NetworkConfig.Gateway) } // configure DNS if len(r.config.NetworkConfig.DNS) > 0 { // write the resolv.conf if err := os.RemoveAll("/etc/resolv.conf"); err != nil { r.log.Errorf("failed to cleanup old resolv.conf: %v", err) return nil } f, err := os.OpenFile("/etc/resolv.conf", os.O_CREATE, os.FileMode(0644)) if err != nil { r.log.Errorf("failed to open /etc/resolv.conf: %v", err) return nil } defer f.Close() for _, ns := range r.config.NetworkConfig.DNS { if _, err := fmt.Fprintf(f, "nameserver %s\n", ns); err != nil { r.log.Errorf("failed to write to resolv.conf: %v", err) return nil } } } return nil }