summaryrefslogtreecommitdiff
path: root/libpod/networking_linux.go
diff options
context:
space:
mode:
authorbaude <bbaude@redhat.com>2018-07-12 09:51:31 -0500
committerAtomic Bot <atomic-devel@projectatomic.io>2018-07-12 21:45:47 +0000
commit4f699db8dad05b770b4e02d3de67137517c3463b (patch)
treea7f474b248d283dd8805da73bf2b63ca56e4fd67 /libpod/networking_linux.go
parente615b7d67124c548a3c7b422348821204ce32775 (diff)
downloadpodman-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.go77
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
}