diff options
Diffstat (limited to 'libpod/network/cni/run.go')
-rw-r--r-- | libpod/network/cni/run.go | 273 |
1 files changed, 0 insertions, 273 deletions
diff --git a/libpod/network/cni/run.go b/libpod/network/cni/run.go deleted file mode 100644 index d0ff49b73..000000000 --- a/libpod/network/cni/run.go +++ /dev/null @@ -1,273 +0,0 @@ -// +build linux - -package cni - -import ( - "context" - "net" - "os" - "strings" - - "github.com/containernetworking/cni/libcni" - cnitypes "github.com/containernetworking/cni/pkg/types" - types040 "github.com/containernetworking/cni/pkg/types/040" - "github.com/containernetworking/plugins/pkg/ns" - "github.com/containers/podman/v3/libpod/define" - "github.com/containers/podman/v3/libpod/network/internal/util" - "github.com/containers/podman/v3/libpod/network/types" - "github.com/hashicorp/go-multierror" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" - "github.com/vishvananda/netlink" -) - -// Setup will setup the container network namespace. It returns -// a map of StatusBlocks, the key is the network name. -func (n *cniNetwork) Setup(namespacePath string, options types.SetupOptions) (map[string]types.StatusBlock, error) { - n.lock.Lock() - defer n.lock.Unlock() - err := n.loadNetworks() - if err != nil { - return nil, err - } - - err = util.ValidateSetupOptions(n, namespacePath, options) - if err != nil { - return nil, err - } - - // set the loopback adapter up in the container netns - err = ns.WithNetNSPath(namespacePath, func(_ ns.NetNS) error { - link, err := netlink.LinkByName("lo") - if err == nil { - err = netlink.LinkSetUp(link) - } - return err - }) - if err != nil { - return nil, errors.Wrapf(err, "failed to set the loopback adapter up") - } - - var retErr error - teardownOpts := options - teardownOpts.Networks = map[string]types.PerNetworkOptions{} - // make sure to teardown the already connected networks on error - defer func() { - if retErr != nil { - if len(teardownOpts.Networks) > 0 { - err := n.teardown(namespacePath, types.TeardownOptions(teardownOpts)) - if err != nil { - logrus.Warn(err) - } - } - } - }() - - ports, err := convertSpecgenPortsToCNIPorts(options.PortMappings) - if err != nil { - return nil, err - } - - results := make(map[string]types.StatusBlock, len(options.Networks)) - for name, netOpts := range options.Networks { - network := n.networks[name] - rt := getRuntimeConfig(namespacePath, options.ContainerName, options.ContainerID, name, ports, netOpts) - - // If we have more than one static ip we need parse the ips via runtime config, - // make sure to add the ips capability to the first plugin otherwise it doesn't get the ips - if len(netOpts.StaticIPs) > 0 && !network.cniNet.Plugins[0].Network.Capabilities["ips"] { - caps := make(map[string]interface{}) - caps["capabilities"] = map[string]bool{"ips": true} - network.cniNet.Plugins[0], retErr = libcni.InjectConf(network.cniNet.Plugins[0], caps) - if retErr != nil { - return nil, retErr - } - } - - var res cnitypes.Result - res, retErr = n.cniConf.AddNetworkList(context.Background(), network.cniNet, rt) - // Add this network to teardown opts since it is now connected. - // Also add this if an errors was returned since we want to call teardown on this regardless. - teardownOpts.Networks[name] = netOpts - if retErr != nil { - return nil, retErr - } - - logrus.Debugf("cni result for container %s network %s: %v", options.ContainerID, name, res) - var status types.StatusBlock - status, retErr = CNIResultToStatus(res) - if retErr != nil { - return nil, retErr - } - results[name] = status - } - return results, nil -} - -// CNIResultToStatus convert the cni result to status block -// nolint:golint -func CNIResultToStatus(res cnitypes.Result) (types.StatusBlock, error) { - result := types.StatusBlock{} - cniResult, err := types040.GetResult(res) - if err != nil { - return result, err - } - nameservers := make([]net.IP, 0, len(cniResult.DNS.Nameservers)) - for _, nameserver := range cniResult.DNS.Nameservers { - ip := net.ParseIP(nameserver) - if ip == nil { - return result, errors.Errorf("failed to parse cni nameserver ip %s", nameserver) - } - nameservers = append(nameservers, ip) - } - result.DNSServerIPs = nameservers - result.DNSSearchDomains = cniResult.DNS.Search - - interfaces := make(map[string]types.NetInterface) - for _, ip := range cniResult.IPs { - if ip.Interface == nil { - // we do no expect ips without an interface - continue - } - if len(cniResult.Interfaces) <= *ip.Interface { - return result, errors.Errorf("invalid cni result, interface index %d out of range", *ip.Interface) - } - cniInt := cniResult.Interfaces[*ip.Interface] - netInt, ok := interfaces[cniInt.Name] - if ok { - netInt.Subnets = append(netInt.Subnets, types.NetAddress{ - IPNet: types.IPNet{IPNet: ip.Address}, - Gateway: ip.Gateway, - }) - interfaces[cniInt.Name] = netInt - } else { - mac, err := net.ParseMAC(cniInt.Mac) - if err != nil { - return result, err - } - interfaces[cniInt.Name] = types.NetInterface{ - MacAddress: types.HardwareAddr(mac), - Subnets: []types.NetAddress{{ - IPNet: types.IPNet{IPNet: ip.Address}, - Gateway: ip.Gateway, - }}, - } - } - } - result.Interfaces = interfaces - return result, nil -} - -func getRuntimeConfig(netns, conName, conID, networkName string, ports []cniPortMapEntry, opts types.PerNetworkOptions) *libcni.RuntimeConf { - rt := &libcni.RuntimeConf{ - ContainerID: conID, - NetNS: netns, - IfName: opts.InterfaceName, - Args: [][2]string{ - {"IgnoreUnknown", "1"}, - // Do not set the K8S env vars, see https://github.com/containers/podman/issues/12083. - // Only K8S_POD_NAME is used by dnsname to get the container name. - {"K8S_POD_NAME", conName}, - }, - CapabilityArgs: map[string]interface{}{}, - } - - // Propagate environment CNI_ARGS - for _, kvpairs := range strings.Split(os.Getenv("CNI_ARGS"), ";") { - if keyval := strings.SplitN(kvpairs, "=", 2); len(keyval) == 2 { - rt.Args = append(rt.Args, [2]string{keyval[0], keyval[1]}) - } - } - - // Add mac address to cni args - if len(opts.StaticMAC) > 0 { - rt.Args = append(rt.Args, [2]string{"MAC", opts.StaticMAC.String()}) - } - - if len(opts.StaticIPs) == 1 { - // Add a single IP to the args field. CNI plugins < 1.0.0 - // do not support multiple ips via capability args. - rt.Args = append(rt.Args, [2]string{"IP", opts.StaticIPs[0].String()}) - } else if len(opts.StaticIPs) > 1 { - // Set the static ips in the capability args - // to support more than one static ip per network. - rt.CapabilityArgs["ips"] = opts.StaticIPs - } - - // Set network aliases for the dnsname plugin. - if len(opts.Aliases) > 0 { - rt.CapabilityArgs["aliases"] = map[string][]string{ - networkName: opts.Aliases, - } - } - - // Set PortMappings in Capabilities - if len(ports) > 0 { - rt.CapabilityArgs["portMappings"] = ports - } - - return rt -} - -// Teardown will teardown the container network namespace. -func (n *cniNetwork) Teardown(namespacePath string, options types.TeardownOptions) error { - n.lock.Lock() - defer n.lock.Unlock() - err := n.loadNetworks() - if err != nil { - return err - } - return n.teardown(namespacePath, options) -} - -func (n *cniNetwork) teardown(namespacePath string, options types.TeardownOptions) error { - // Note: An empty namespacePath is allowed because some plugins - // still need teardown, for example ipam should remove used ip allocations. - - ports, err := convertSpecgenPortsToCNIPorts(options.PortMappings) - if err != nil { - return err - } - - var multiErr *multierror.Error - for name, netOpts := range options.Networks { - rt := getRuntimeConfig(namespacePath, options.ContainerName, options.ContainerID, name, ports, netOpts) - - cniConfList, newRt, err := getCachedNetworkConfig(n.cniConf, name, rt) - if err == nil { - rt = newRt - } else { - logrus.Warnf("Failed to load cached network config: %v, falling back to loading network %s from disk", err, name) - network := n.networks[name] - if network == nil { - multiErr = multierror.Append(multiErr, errors.Wrapf(define.ErrNoSuchNetwork, "network %s", name)) - continue - } - cniConfList = network.cniNet - } - - err = n.cniConf.DelNetworkList(context.Background(), cniConfList, rt) - if err != nil { - multiErr = multierror.Append(multiErr, err) - } - } - return multiErr.ErrorOrNil() -} - -func getCachedNetworkConfig(cniConf *libcni.CNIConfig, name string, rt *libcni.RuntimeConf) (*libcni.NetworkConfigList, *libcni.RuntimeConf, error) { - cniConfList := &libcni.NetworkConfigList{ - Name: name, - } - confBytes, rt, err := cniConf.GetNetworkListCachedConfig(cniConfList, rt) - if err != nil { - return nil, nil, err - } else if confBytes == nil { - return nil, nil, errors.Errorf("network %s not found in CNI cache", name) - } - - cniConfList, err = libcni.ConfListFromBytes(confBytes) - if err != nil { - return nil, nil, err - } - return cniConfList, rt, nil -} |