summaryrefslogtreecommitdiff
path: root/libpod/network/cni/run.go
diff options
context:
space:
mode:
Diffstat (limited to 'libpod/network/cni/run.go')
-rw-r--r--libpod/network/cni/run.go273
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
-}