Пример #1
0
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)
			}
		}
	}
}
Пример #2
0
// 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)
}
Пример #3
0
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
}
Пример #4
0
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
}
Пример #5
0
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)
	}
}
Пример #6
0
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
}
Пример #7
0
// 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
}
Пример #8
0
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
}
Пример #9
0
Файл: utils.go Проект: brb/weave
// 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
}
Пример #10
0
// 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
}
Пример #11
0
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
}
Пример #12
0
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)
	}
}
Пример #13
0
func linkListing() {
	links, err := netlink.LinkList()
	if err != nil {
		panic(err)
	}

	fmt.Println("Interface listing:")
	for _, link := range links {
		fmt.Println(link.Attrs().Name)
	}
}
Пример #14
0
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
}
Пример #15
0
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
}
Пример #16
0
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
}
Пример #17
0
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
}
Пример #18
0
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")
}
Пример #19
0
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
}
Пример #20
0
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)
}
Пример #21
0
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
}
Пример #22
0
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()
}
Пример #24
0
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
}
Пример #25
0
			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))
Пример #26
0
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
}
Пример #27
0
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
}
Пример #28
0
// 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
}