diff options
author | baude <bbaude@redhat.com> | 2018-07-12 09:51:31 -0500 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2018-07-12 21:45:47 +0000 |
commit | 4f699db8dad05b770b4e02d3de67137517c3463b (patch) | |
tree | a7f474b248d283dd8805da73bf2b63ca56e4fd67 /libpod/networking_linux.go | |
parent | e615b7d67124c548a3c7b422348821204ce32775 (diff) | |
download | podman-4f699db8dad05b770b4e02d3de67137517c3463b.tar.gz podman-4f699db8dad05b770b4e02d3de67137517c3463b.tar.bz2 podman-4f699db8dad05b770b4e02d3de67137517c3463b.zip |
Support multiple networks
This is a refresh of Dan William's PR #974 with a rebase and proper
vendoring of ocicni and containernetworking/cni. It adds the ability
to define multiple networks as so:
podman run --network=net1,net2,foobar ...
Signed-off-by: baude <bbaude@redhat.com>
Closes: #1082
Approved by: baude
Diffstat (limited to 'libpod/networking_linux.go')
-rw-r--r-- | libpod/networking_linux.go | 77 |
1 files changed, 30 insertions, 47 deletions
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index 59666b534..d9eb87572 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -5,7 +5,6 @@ package libpod import ( "crypto/rand" "fmt" - "net" "os" "path/filepath" "strconv" @@ -24,21 +23,22 @@ import ( ) // Get an OCICNI network config -func getPodNetwork(id, name, nsPath string, ports []ocicni.PortMapping) ocicni.PodNetwork { +func getPodNetwork(id, name, nsPath string, networks []string, ports []ocicni.PortMapping) ocicni.PodNetwork { return ocicni.PodNetwork{ Name: name, Namespace: name, // TODO is there something else we should put here? We don't know about Kube namespaces ID: id, NetNS: nsPath, PortMappings: ports, + Networks: networks, } } // Create and configure a new network namespace for a container func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) (err error) { - podNetwork := getPodNetwork(ctr.ID(), ctr.Name(), ctrNS.Path(), ctr.config.PortMappings) + podNetwork := getPodNetwork(ctr.ID(), ctr.Name(), ctrNS.Path(), ctr.config.Networks, ctr.config.PortMappings) - result, err := r.netPlugin.SetUpPod(podNetwork) + results, err := r.netPlugin.SetUpPod(podNetwork) if err != nil { return errors.Wrapf(err, "error configuring network namespace for container %s", ctr.ID()) } @@ -50,28 +50,28 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) (err error) { } }() - logrus.Debugf("Response from CNI plugins: %v", result.String()) - - resultStruct, err := cnitypes.GetResult(result) - if err != nil { - return errors.Wrapf(err, "error parsing result from CNI plugins") + ctr.state.NetNS = ctrNS + ctr.state.NetworkStatus = make([]*cnitypes.Result, 0) + for idx, r := range results { + logrus.Debugf("[%d] CNI result: %v", idx, r.String()) + resultCurrent, err := cnitypes.GetResult(r) + if err != nil { + return errors.Wrapf(err, "error parsing CNI plugin result %q: %v", r.String(), err) + } + ctr.state.NetworkStatus = append(ctr.state.NetworkStatus, resultCurrent) } - ctr.state.NetNS = ctrNS - ctr.state.IPs = resultStruct.IPs - ctr.state.Routes = resultStruct.Routes - ctr.state.Interfaces = resultStruct.Interfaces - - // We need to temporarily use iptables to allow the container - // to resolve DNS until this issue is fixed upstream. - // https://github.com/containernetworking/plugins/pull/75 - if resultStruct.IPs != nil { - for _, ip := range resultStruct.IPs { + for _, r := range ctr.state.NetworkStatus { + // We need to temporarily use iptables to allow the container + // to resolve DNS until this issue is fixed upstream. + // https://github.com/containernetworking/plugins/pull/75 + for _, ip := range r.IPs { if ip.Address.IP.To4() != nil { iptablesDNS("-I", ip.Address.IP.String()) } } } + return nil } @@ -148,27 +148,6 @@ func joinNetNS(path string) (ns.NetNS, error) { return ns, nil } -// Get a container's IP address -func (r *Runtime) getContainerIP(ctr *Container) (net.IP, error) { - if ctr.state.NetNS == nil { - return nil, errors.Wrapf(ErrInvalidArg, "container %s has no network namespace, cannot get IP", ctr.ID()) - } - - podNetwork := getPodNetwork(ctr.ID(), ctr.Name(), ctr.state.NetNS.Path(), ctr.config.PortMappings) - - ipStr, err := r.netPlugin.GetPodNetworkStatus(podNetwork) - if err != nil { - return nil, errors.Wrapf(err, "error retrieving network status of container %s", ctr.ID()) - } - - ip := net.ParseIP(ipStr) - if ip == nil { - return nil, errors.Wrapf(ErrInternal, "error parsing IP address %s for container %s", ipStr, ctr.ID()) - } - - return ip, nil -} - // Tear down a network namespace func (r *Runtime) teardownNetNS(ctr *Container) error { if ctr.state.NetNS == nil { @@ -180,15 +159,17 @@ func (r *Runtime) teardownNetNS(ctr *Container) error { // on per IP address, we also need to try to remove the iptables rule // on cleanup. Remove when https://github.com/containernetworking/plugins/pull/75 // is merged. - for _, ip := range ctr.state.IPs { - if ip.Address.IP.To4() != nil { - iptablesDNS("-D", ip.Address.IP.String()) + for _, r := range ctr.state.NetworkStatus { + for _, ip := range r.IPs { + if ip.Address.IP.To4() != nil { + iptablesDNS("-D", ip.Address.IP.String()) + } } } logrus.Debugf("Tearing down network namespace at %s for container %s", ctr.state.NetNS.Path(), ctr.ID()) - podNetwork := getPodNetwork(ctr.ID(), ctr.Name(), ctr.state.NetNS.Path(), ctr.config.PortMappings) + podNetwork := getPodNetwork(ctr.ID(), ctr.Name(), ctr.state.NetNS.Path(), ctr.config.Networks, ctr.config.PortMappings) // The network may have already been torn down, so don't fail here, just log if err := r.netPlugin.TearDownPod(podNetwork); err != nil { @@ -232,9 +213,11 @@ func getContainerNetIO(ctr *Container) (*netlink.LinkStatistics, error) { } func (c *Container) getContainerNetworkInfo(data *inspect.ContainerInspectData) *inspect.ContainerInspectData { - if c.state.NetNS != nil { + if c.state.NetNS != nil && len(c.state.NetworkStatus) > 0 { + // Report network settings from the first pod network + result := c.state.NetworkStatus[0] // Go through our IP addresses - for _, ctrIP := range c.state.IPs { + for _, ctrIP := range result.IPs { ipWithMask := ctrIP.Address.String() splitIP := strings.Split(ipWithMask, "/") mask, _ := strconv.Atoi(splitIP[1]) @@ -253,7 +236,7 @@ func (c *Container) getContainerNetworkInfo(data *inspect.ContainerInspectData) data.NetworkSettings.SandboxKey = c.state.NetNS.Path() // Set MAC address of interface linked with network namespace path - for _, i := range c.state.Interfaces { + for _, i := range result.Interfaces { if i.Sandbox == data.NetworkSettings.SandboxKey { data.NetworkSettings.MacAddress = i.Mac } |