summaryrefslogtreecommitdiff
path: root/libpod/networking_linux.go
diff options
context:
space:
mode:
Diffstat (limited to 'libpod/networking_linux.go')
-rw-r--r--libpod/networking_linux.go221
1 files changed, 57 insertions, 164 deletions
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index 5fb97dd73..a931774f8 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -53,41 +53,6 @@ const (
persistentCNIDir = "/var/lib/cni"
)
-// GetAllNetworkAliases returns all configured aliases for this container.
-// It also adds the container short ID as alias to match docker.
-func (c *Container) GetAllNetworkAliases() (map[string][]string, error) {
- allAliases, err := c.runtime.state.GetAllNetworkAliases(c)
- if err != nil {
- return nil, err
- }
-
- // get the all attached networks, we cannot use GetAllNetworkAliases()
- // since it returns nil if there are no aliases
- nets, _, err := c.networks()
- if err != nil {
- return nil, err
- }
-
- // add container short ID as alias to match docker
- for _, net := range nets {
- allAliases[net] = append(allAliases[net], c.config.ID[:12])
- }
- return allAliases, nil
-}
-
-// GetNetworkAliases returns configured aliases for this network.
-// It also adds the container short ID as alias to match docker.
-func (c *Container) GetNetworkAliases(netName string) ([]string, error) {
- aliases, err := c.runtime.state.GetNetworkAliases(c, netName)
- if err != nil {
- return nil, err
- }
-
- // add container short ID as alias to match docker
- aliases = append(aliases, c.config.ID[:12])
- return aliases, nil
-}
-
// convertPortMappings will remove the HostIP part from the ports when running inside podman machine.
// This is need because a HostIP of 127.0.0.1 would now allow the gvproxy forwarder to reach to open ports.
// For machine the HostIP must only be used by gvproxy and never in the VM.
@@ -104,53 +69,20 @@ func (c *Container) convertPortMappings() []types.PortMapping {
return newPorts
}
-func (c *Container) getNetworkOptions() (types.NetworkOptions, error) {
+func (c *Container) getNetworkOptions(networkOpts map[string]types.PerNetworkOptions) (types.NetworkOptions, error) {
opts := types.NetworkOptions{
ContainerID: c.config.ID,
ContainerName: getCNIPodName(c),
}
opts.PortMappings = c.convertPortMappings()
- networks, _, err := c.networks()
- if err != nil {
- return opts, err
- }
- aliases, err := c.GetAllNetworkAliases()
- if err != nil {
- return opts, err
- }
// If the container requested special network options use this instead of the config.
// This is the case for container restore or network reload.
if c.perNetworkOpts != nil {
opts.Networks = c.perNetworkOpts
- return opts, nil
- }
-
- // Update container map of interface descriptions
- if err := c.setupNetworkDescriptions(networks); err != nil {
- return opts, err
- }
-
- nets := make(map[string]types.PerNetworkOptions, len(networks))
- for i, network := range networks {
- eth, exists := c.state.NetInterfaceDescriptions.getInterfaceByName(network)
- if !exists {
- return opts, errors.Errorf("no network interface name for container %s on network %s", c.config.ID, network)
- }
- netOpts := types.PerNetworkOptions{
- InterfaceName: eth,
- Aliases: aliases[network],
- }
- // only set the static ip/mac on the first network
- if i == 0 {
- if c.config.StaticIP != nil {
- netOpts.StaticIPs = []net.IP{c.config.StaticIP}
- }
- netOpts.StaticMAC = c.config.StaticMAC
- }
- nets[network] = netOpts
+ } else {
+ opts.Networks = networkOpts
}
- opts.Networks = nets
return opts, nil
}
@@ -697,7 +629,7 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) (status map[str
if ctr.config.NetMode.IsSlirp4netns() {
return nil, r.setupSlirp4netns(ctr, ctrNS)
}
- networks, _, err := ctr.networks()
+ networks, err := ctr.networks()
if err != nil {
return nil, err
}
@@ -707,7 +639,7 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) (status map[str
return nil, nil
}
- netOpts, err := ctr.getNetworkOptions()
+ netOpts, err := ctr.getNetworkOptions(networks)
if err != nil {
return nil, err
}
@@ -862,13 +794,13 @@ func (r *Runtime) teardownCNI(ctr *Container) error {
logrus.Debugf("Tearing down network namespace at %s for container %s", ctr.state.NetNS.Path(), ctr.ID())
- networks, _, err := ctr.networks()
+ networks, err := ctr.networks()
if err != nil {
return err
}
if !ctr.config.NetMode.IsSlirp4netns() && len(networks) > 0 {
- netOpts, err := ctr.getNetworkOptions()
+ netOpts, err := ctr.getNetworkOptions(networks)
if err != nil {
return err
}
@@ -960,22 +892,17 @@ func (r *Runtime) reloadContainerNetwork(ctr *Container) (map[string]types.Statu
}
}
- aliases, err := ctr.GetAllNetworkAliases()
+ networkOpts, err := ctr.networks()
if err != nil {
return nil, err
}
// Set the same network settings as before..
netStatus := ctr.getNetworkStatus()
- netOpts := make(map[string]types.PerNetworkOptions, len(netStatus))
- for network, status := range netStatus {
- perNetOpts := types.PerNetworkOptions{}
- for name, netInt := range status.Interfaces {
- perNetOpts = types.PerNetworkOptions{
- InterfaceName: name,
- Aliases: aliases[network],
- StaticMAC: netInt.MacAddress,
- }
+ for network, perNetOpts := range networkOpts {
+ for name, netInt := range netStatus[network].Interfaces {
+ perNetOpts.InterfaceName = name
+ perNetOpts.StaticMAC = netInt.MacAddress
for _, netAddress := range netInt.Subnets {
perNetOpts.StaticIPs = append(perNetOpts.StaticIPs, netAddress.IPNet.IP)
}
@@ -983,16 +910,9 @@ func (r *Runtime) reloadContainerNetwork(ctr *Container) (map[string]types.Statu
// For now just use the first interface to get the ips this should be good enough for most cases.
break
}
- if perNetOpts.InterfaceName == "" {
- eth, exists := ctr.state.NetInterfaceDescriptions.getInterfaceByName(network)
- if !exists {
- return nil, errors.Errorf("no network interface name for container %s on network %s", ctr.config.ID, network)
- }
- perNetOpts.InterfaceName = eth
- }
- netOpts[network] = perNetOpts
+ networkOpts[network] = perNetOpts
}
- ctr.perNetworkOpts = netOpts
+ ctr.perNetworkOpts = networkOpts
return r.configureNetNS(ctr, ctr.state.NetNS)
}
@@ -1049,7 +969,7 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
settings := new(define.InspectNetworkSettings)
settings.Ports = makeInspectPortBindings(c.config.PortMappings, c.config.ExposedPorts)
- networks, isDefault, err := c.networks()
+ networks, err := c.networks()
if err != nil {
return nil, err
}
@@ -1060,14 +980,10 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
// the container joined.
if len(networks) > 0 {
settings.Networks = make(map[string]*define.InspectAdditionalNetwork, len(networks))
- for _, net := range networks {
+ for net, opts := range networks {
cniNet := new(define.InspectAdditionalNetwork)
cniNet.NetworkID = net
- aliases, err := c.GetNetworkAliases(net)
- if err != nil {
- return nil, err
- }
- cniNet.Aliases = aliases
+ cniNet.Aliases = opts.Aliases
settings.Networks[net] = cniNet
}
}
@@ -1092,7 +1008,7 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
settings.Networks = make(map[string]*define.InspectAdditionalNetwork)
- for _, name := range networks {
+ for name, opts := range networks {
result := netStatus[name]
addedNet := new(define.InspectAdditionalNetwork)
addedNet.NetworkID = name
@@ -1101,19 +1017,17 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
if err != nil {
return nil, err
}
-
- aliases, err := c.GetNetworkAliases(name)
- if err != nil {
- return nil, err
- }
- addedNet.Aliases = aliases
+ addedNet.Aliases = opts.Aliases
addedNet.InspectBasicNetworkConfig = basicConfig
settings.Networks[name] = addedNet
}
- if !isDefault {
+ // if not only the default network is connected we can return here
+ // otherwise we have to populate the InspectBasicNetworkConfig settings
+ _, isDefaultNet := networks[c.runtime.config.Network.DefaultNetwork]
+ if !(len(networks) == 1 && isDefaultNet) {
return settings, nil
}
}
@@ -1135,29 +1049,6 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
return settings, nil
}
-// setupNetworkDescriptions adds networks and eth values to the container's
-// network descriptions
-func (c *Container) setupNetworkDescriptions(networks []string) error {
- // if the map is nil and we have networks
- if c.state.NetInterfaceDescriptions == nil && len(networks) > 0 {
- c.state.NetInterfaceDescriptions = make(ContainerNetworkDescriptions)
- }
- origLen := len(c.state.NetInterfaceDescriptions)
- for _, n := range networks {
- // if the network is not in the map, add it
- if _, exists := c.state.NetInterfaceDescriptions[n]; !exists {
- c.state.NetInterfaceDescriptions.add(n)
- }
- }
- // if the map changed, we need to save the container state
- if origLen != len(c.state.NetInterfaceDescriptions) {
- if err := c.save(); err != nil {
- return err
- }
- }
- return nil
-}
-
// resultToBasicNetworkConfig produces an InspectBasicNetworkConfig from a CNI
// result
func resultToBasicNetworkConfig(result types.StatusBlock) (define.InspectBasicNetworkConfig, error) {
@@ -1213,7 +1104,7 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro
c.lock.Lock()
defer c.lock.Unlock()
- networks, err := c.networksByNameIndex()
+ networks, err := c.networks()
if err != nil {
return err
}
@@ -1254,14 +1145,8 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro
ContainerName: getCNIPodName(c),
}
opts.PortMappings = c.convertPortMappings()
- eth, exists := c.state.NetInterfaceDescriptions.getInterfaceByName(netName)
- if !exists {
- return errors.Errorf("no network interface name for container %s on network %s", c.config.ID, netName)
- }
opts.Networks = map[string]types.PerNetworkOptions{
- netName: {
- InterfaceName: eth,
- },
+ netName: networks[netName],
}
if err := c.runtime.teardownNetwork(c.state.NetNS.Path(), opts); err != nil {
@@ -1285,7 +1170,7 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro
}
// ConnectNetwork connects a container to a given network
-func (c *Container) NetworkConnect(nameOrID, netName string, aliases []string) error {
+func (c *Container) NetworkConnect(nameOrID, netName string, netOpts types.PerNetworkOptions) error {
// only the bridge mode supports cni networks
if err := isBridgeNetMode(c.config.NetMode); err != nil {
return err
@@ -1294,7 +1179,7 @@ func (c *Container) NetworkConnect(nameOrID, netName string, aliases []string) e
c.lock.Lock()
defer c.lock.Unlock()
- networks, err := c.networksByNameIndex()
+ networks, err := c.networks()
if err != nil {
return err
}
@@ -1317,11 +1202,20 @@ func (c *Container) NetworkConnect(nameOrID, netName string, aliases []string) e
if err != nil {
return err
}
- if !network.DNSEnabled && len(aliases) > 0 {
+ if !network.DNSEnabled && len(netOpts.Aliases) > 0 {
return errors.Wrapf(define.ErrInvalidArg, "cannot set network aliases for network %q because dns is disabled", netName)
}
+ // always add the short id as alias for docker compat
+ netOpts.Aliases = append(netOpts.Aliases, c.config.ID[:12])
- if err := c.runtime.state.NetworkConnect(c, netName, aliases); err != nil {
+ if netOpts.InterfaceName == "" {
+ netOpts.InterfaceName = getFreeInterfaceName(networks)
+ if netOpts.InterfaceName == "" {
+ return errors.New("could not find free network interface name")
+ }
+ }
+
+ if err := c.runtime.state.NetworkConnect(c, netName, netOpts); err != nil {
return err
}
c.newNetworkEvent(events.NetworkConnect, netName)
@@ -1332,30 +1226,13 @@ func (c *Container) NetworkConnect(nameOrID, netName string, aliases []string) e
return errors.Wrapf(define.ErrNoNetwork, "unable to connect %s to %s", nameOrID, netName)
}
- ctrNetworks, _, err := c.networks()
- if err != nil {
- return err
- }
- // Update network descriptions
- if err := c.setupNetworkDescriptions(ctrNetworks); err != nil {
- return err
- }
-
opts := types.NetworkOptions{
ContainerID: c.config.ID,
ContainerName: getCNIPodName(c),
}
opts.PortMappings = c.convertPortMappings()
- eth, exists := c.state.NetInterfaceDescriptions.getInterfaceByName(netName)
- if !exists {
- return errors.Errorf("no network interface name for container %s on network %s", c.config.ID, netName)
- }
- aliases = append(aliases, c.config.ID[:12])
opts.Networks = map[string]types.PerNetworkOptions{
- netName: {
- Aliases: aliases,
- InterfaceName: eth,
- },
+ netName: netOpts,
}
results, err := c.runtime.setUpNetwork(c.state.NetNS.Path(), opts)
@@ -1385,6 +1262,22 @@ func (c *Container) NetworkConnect(nameOrID, netName string, aliases []string) e
return nil
}
+// get a free interface name for a new network
+// return an empty string if no free name was found
+func getFreeInterfaceName(networks map[string]types.PerNetworkOptions) string {
+ ifNames := make([]string, 0, len(networks))
+ for _, opts := range networks {
+ ifNames = append(ifNames, opts.InterfaceName)
+ }
+ for i := 0; i < 100000; i++ {
+ ifName := fmt.Sprintf("eth%d", i)
+ if !util.StringInSlice(ifName, ifNames) {
+ return ifName
+ }
+ }
+ return ""
+}
+
// DisconnectContainerFromNetwork removes a container from its CNI network
func (r *Runtime) DisconnectContainerFromNetwork(nameOrID, netName string, force bool) error {
ctr, err := r.LookupContainer(nameOrID)
@@ -1395,12 +1288,12 @@ func (r *Runtime) DisconnectContainerFromNetwork(nameOrID, netName string, force
}
// ConnectContainerToNetwork connects a container to a CNI network
-func (r *Runtime) ConnectContainerToNetwork(nameOrID, netName string, aliases []string) error {
+func (r *Runtime) ConnectContainerToNetwork(nameOrID, netName string, netOpts types.PerNetworkOptions) error {
ctr, err := r.LookupContainer(nameOrID)
if err != nil {
return err
}
- return ctr.NetworkConnect(nameOrID, netName, aliases)
+ return ctr.NetworkConnect(nameOrID, netName, netOpts)
}
// normalizeNetworkName takes a network name, a partial or a full network ID and returns the network name.