Пример #1
0
func cmdAdd(args *skel.CmdArgs) error {
	n, err := loadConf(args.StdinData)
	if err != nil {
		return err
	}

	netns, err := os.Open(args.Netns)
	if err != nil {
		return fmt.Errorf("failed to open netns %q: %v", netns, err)
	}
	defer netns.Close()

	if err = createMacvlan(n, args.IfName, netns); err != nil {
		return err
	}

	// run the IPAM plugin and get back the config to apply
	result, err := ipam.ExecAdd(n.IPAM.Type, args.StdinData)
	if err != nil {
		return err
	}
	if result.IP4 == nil {
		return errors.New("IPAM plugin returned missing IPv4 config")
	}

	err = ns.WithNetNS(netns, false, func(_ *os.File) error {
		return ipam.ConfigureIface(args.IfName, result)
	})
	if err != nil {
		return err
	}

	result.DNS = n.DNS
	return result.Print()
}
Пример #2
0
func cmdAdd(args *skel.CmdArgs) error {
	n, err := loadNetConf(args.StdinData)
	if err != nil {
		return err
	}

	br, err := setupBridge(n)
	if err != nil {
		return err
	}

	if err = setupVeth(args.Netns, br, args.IfName, n.MTU); err != nil {
		return err
	}

	// run the IPAM plugin and get back the config to apply
	result, err := ipam.ExecAdd(n.IPAM.Type, args.StdinData)
	if err != nil {
		return err
	}

	if result.IP4 == nil {
		return errors.New("IPAM plugin returned missing IPv4 config")
	}

	if result.IP4.Gateway == nil && n.IsGW {
		result.IP4.Gateway = calcGatewayIP(&result.IP4.IP)
	}

	err = ns.WithNetNSPath(args.Netns, false, func(hostNS *os.File) error {
		return ipam.ConfigureIface(args.IfName, result)
	})
	if err != nil {
		return err
	}

	if n.IsGW {
		gwn := &net.IPNet{
			IP:   result.IP4.Gateway,
			Mask: result.IP4.IP.Mask,
		}

		if err = ensureBridgeAddr(br, gwn); err != nil {
			return err
		}

		if err := ip.EnableIP4Forward(); err != nil {
			return fmt.Errorf("failed to enable forwarding: %v", err)
		}
	}

	if n.IPMasq {
		chain := "CNI-" + n.Name
		if err = ip.SetupIPMasq(ip.Network(&result.IP4.IP), chain); err != nil {
			return err
		}
	}

	return result.Print()
}
Пример #3
0
Файл: cni.go Проект: n054/weave
func (c *CNIPlugin) getIP(ipamType string, args *skel.CmdArgs) (result *types.Result, err error) {
	// Default IPAM is Weave's own
	if ipamType == "" {
		result, err = ipamplugin.NewIpam(c.weave).Allocate(args)
	} else {
		result, err = ipam.ExecAdd(ipamType, args.StdinData)
	}
	if err == nil && result.IP4 == nil {
		return nil, fmt.Errorf("IPAM plugin failed to allocate IP address")
	}
	return result, err
}
Пример #4
0
func delegateAdd(cid string, netconf map[string]interface{}) error {
	netconfBytes, err := json.Marshal(netconf)
	if err != nil {
		return fmt.Errorf("error serializing delegate netconf: %v", err)
	}

	// save the rendered netconf for cmdDel
	if err = saveScratchNetConf(cid, netconfBytes); err != nil {
		return err
	}

	result, err := ipam.ExecAdd(netconf["type"].(string), netconfBytes)
	if err != nil {
		return err
	}

	return result.Print()
}
Пример #5
0
Файл: ptp.go Проект: aanm/cni
func cmdAdd(args *skel.CmdArgs) error {
	conf := NetConf{}
	if err := json.Unmarshal(args.StdinData, &conf); err != nil {
		return fmt.Errorf("failed to load netconf: %v", err)
	}

	if err := ip.EnableIP4Forward(); err != nil {
		return fmt.Errorf("failed to enable forwarding: %v", err)
	}

	// run the IPAM plugin and get back the config to apply
	result, err := ipam.ExecAdd(conf.IPAM.Type, args.StdinData)
	if err != nil {
		return err
	}
	if result.IP4 == nil {
		return errors.New("IPAM plugin returned missing IPv4 config")
	}

	hostVethName, err := setupContainerVeth(args.Netns, args.IfName, conf.MTU, result)
	if err != nil {
		return err
	}

	if err = setupHostVeth(hostVethName, result.IP4); err != nil {
		return err
	}

	if conf.IPMasq {
		chain := utils.FormatChainName(conf.Name, args.ContainerID)
		comment := utils.FormatComment(conf.Name, args.ContainerID)
		if err = ip.SetupIPMasq(&result.IP4.IP, chain, comment); err != nil {
			return err
		}
	}

	result.DNS = conf.DNS
	return result.Print()
}
Пример #6
0
func cmdAdd(args *skel.CmdArgs) error {
	conf := NetConf{}
	if err := json.Unmarshal(args.StdinData, &conf); err != nil {
		return fmt.Errorf("failed to load netconf: %v", err)
	}

	if err := ip.EnableIP4Forward(); err != nil {
		return fmt.Errorf("failed to enable forwarding: %v", err)
	}

	// run the IPAM plugin and get back the config to apply
	result, err := ipam.ExecAdd(conf.IPAM.Type, args.StdinData)
	if err != nil {
		return err
	}
	if result.IP4 == nil {
		return errors.New("IPAM plugin returned missing IPv4 config")
	}

	hostVethName, err := setupContainerVeth(args.Netns, args.IfName, conf.MTU, result)
	if err != nil {
		return err
	}

	if err = setupHostVeth(hostVethName, result.IP4); err != nil {
		return err
	}

	if conf.IPMasq {
		h := sha512.Sum512([]byte(args.ContainerID))
		chain := fmt.Sprintf("CNI-%s-%x", conf.Name, h[:8])
		if err = ip.SetupIPMasq(&result.IP4.IP, chain); err != nil {
			return err
		}
	}

	return result.Print()
}
Пример #7
0
func cmdAdd(args *skel.CmdArgs) error {
	netConf, err := loadConf(args.StdinData)
	if err != nil {
		return fmt.Errorf("loading config: %s", err)
	}

	if args.ContainerID == "" {
		return errors.New("CNI_CONTAINERID is required")
	}

	sandboxNS, err := getSandboxNS(fmt.Sprintf("vni-%d", vni))
	if err != nil {
		return fmt.Errorf("getting vxlan sandbox: %s", err)
	}

	// run the IPAM plugin and get back the config to apply
	ipamResult, err := ipam.ExecAdd(netConf.IPAM.Type, args.StdinData)
	if err != nil {
		return fmt.Errorf("executing IPAM plugin: %s", err)
	}

	if ipamResult.IP4 == nil {
		return errors.New("IPAM plugin returned with missing IPv4 config")
	}

	linkFactory := &links.Factory{Netlinker: nl.Netlink}
	addressManager := &ip.AddressManager{Netlinker: nl.Netlink}

	containerNS := namespace.NewNamespace(args.Netns)

	containerNamespaceFile, err := containerNS.Open()
	if err != nil {
		return fmt.Errorf("opening container namespace: %s", err)
	}
	defer containerNamespaceFile.Close()

	sandboxNamespaceFile, err := sandboxNS.Open()
	if err != nil {
		return fmt.Errorf("opening sandbox namespace: %s", err)
	}
	defer sandboxNamespaceFile.Close()

	var sandboxLink netlink.Link
	err = containerNS.Execute(func(ns *os.File) error {
		var (
			containerLink netlink.Link
			err           error
		)

		sandboxLink, containerLink, err = linkFactory.CreateVethPair(args.ContainerID, args.IfName, links.VxlanVethMTU)
		if err != nil {
			return fmt.Errorf("could not create veth pair: %s", err)
		}

		err = nl.Netlink.LinkSetNsFd(sandboxLink, int(sandboxNamespaceFile.Fd()))
		if err != nil {
			return fmt.Errorf("failed to move veth peer into sandbox: %s", err)
		}

		err = addressManager.AddAddress(containerLink, &ipamResult.IP4.IP)
		if err != nil {
			return fmt.Errorf("adding address to container veth end: %s", err)
		}

		err = nl.Netlink.LinkSetUp(containerLink)
		if err != nil {
			return fmt.Errorf("upping container veth end: %s", err)
		}

		for _, route := range ipamResult.IP4.Routes {
			// TODO supporting gateway assigned to a particular route
			nlRoute := &netlink.Route{
				LinkIndex: containerLink.Attrs().Index,
				Scope:     netlink.SCOPE_UNIVERSE,
				Dst:       &route.Dst,
				Gw:        ipamResult.IP4.Gateway,
			}
			err = nl.Netlink.RouteAdd(nlRoute)
			if err != nil {
				return fmt.Errorf("adding routes: %s", err)
			}
		}

		return nil
	})
	if err != nil {
		return fmt.Errorf("configuring container namespace: %s", err)
	}

	vxlanName := fmt.Sprintf("vxlan%d", vni)

	var foundVxlanDevice bool
	err = sandboxNS.Execute(func(ns *os.File) error {
		if _, err := linkFactory.FindLink(vxlanName); err == nil {
			foundVxlanDevice = true
		}
		return nil
	})
	if err != nil {
		return fmt.Errorf("failed attempting to find vxlan device in sandbox: %s", err)
	}

	// create vxlan device within host namespace
	if foundVxlanDevice == false {
		vxlan, err := linkFactory.CreateVxlan(vxlanName, vni)
		if err != nil {
			return fmt.Errorf("creating vxlan device on host namespace: %s", err)
		}

		// move vxlan device to sandbox namespace
		err = nl.Netlink.LinkSetNsFd(vxlan, int(sandboxNamespaceFile.Fd()))
		if err != nil {
			return fmt.Errorf("moving vxland device into sandbox: %s", err)
		}
	}

	err = sandboxNS.Execute(func(ns *os.File) error {
		vxlan, err := linkFactory.FindLink(vxlanName)
		if err != nil {
			return fmt.Errorf("finding vxlan device within sandbox: %s", err)
		}

		err = nl.Netlink.LinkSetUp(vxlan)
		if err != nil {
			return fmt.Errorf("upping sandbox veth end: %s", err)
		}

		vxlan, err = linkFactory.FindLink(vxlanName)
		if err != nil {
			return fmt.Errorf("finding vxlan device within sandbox after upping: %s", err)
		}

		sandboxLink, err = nl.Netlink.LinkByName(sandboxLink.Attrs().Name)
		if err != nil {
			return fmt.Errorf("find sandbox veth end by name: %s", err)
		}

		err = nl.Netlink.LinkSetUp(sandboxLink)
		if err != nil {
			return fmt.Errorf("upping sandbox veth end: %s", err)
		}

		var bridge *netlink.Bridge
		bridgeName := fmt.Sprintf("vxlanbr%d", vni)
		link, err := linkFactory.FindLink(bridgeName)
		if err != nil {
			bridge, err = linkFactory.CreateBridge(bridgeName, &net.IPNet{
				IP:   ipamResult.IP4.Gateway,
				Mask: ipamResult.IP4.IP.Mask,
			})
			if err != nil {
				return fmt.Errorf("failed to create bridge: %s", err)
			}
		} else {
			bridge = link.(*netlink.Bridge)
		}

		err = nl.Netlink.LinkSetMaster(vxlan, bridge)
		if err != nil {
			return fmt.Errorf("slaving vxlan to bridge: %s", err)
		}

		err = nl.Netlink.LinkSetMaster(sandboxLink, bridge)
		if err != nil {
			return fmt.Errorf("slaving veth end to bridge: %s", err)
		}

		return nil
	})
	if err != nil {
		return fmt.Errorf("configuring sandbox namespace: %s", err)
	}

	return ipamResult.Print()
}