aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Gimenez <fgimenez@redhat.com>2021-11-15 10:43:42 +0100
committerFederico Gimenez <fgimenez@redhat.com>2021-11-18 17:04:49 +0100
commit2e5d3e8fb34ba3ab42d53da9ba39b71e1f53bb75 (patch)
tree628cc3eb762c7af5383eff731c6e599d5fa6576e
parent9b964945d661d4f97b4a97f2f67d33f9dcd11e50 (diff)
downloadpodman-2e5d3e8fb34ba3ab42d53da9ba39b71e1f53bb75.tar.gz
podman-2e5d3e8fb34ba3ab42d53da9ba39b71e1f53bb75.tar.bz2
podman-2e5d3e8fb34ba3ab42d53da9ba39b71e1f53bb75.zip
Introduce Address type to be used in secondary IPv4 and IPv6 inspect data
structure. Resolves a discrepancy between the types used in inspect for docker and podman. This causes a panic when using the docker client against podman when the secondary IP fields in the `NetworkSettings` inspect field are populated. Fixes containers#12165 Signed-off-by: Federico Gimenez <fgimenez@redhat.com>
-rw-r--r--libpod/define/container_inspect.go10
-rw-r--r--libpod/networking_linux.go4
-rw-r--r--libpod/networking_linux_test.go217
3 files changed, 226 insertions, 5 deletions
diff --git a/libpod/define/container_inspect.go b/libpod/define/container_inspect.go
index 7decb18a8..9b73dbded 100644
--- a/libpod/define/container_inspect.go
+++ b/libpod/define/container_inspect.go
@@ -542,6 +542,12 @@ type InspectContainerHostConfig struct {
CgroupConf map[string]string `json:"CgroupConf"`
}
+// Address represents an IP address.
+type Address struct {
+ Addr string
+ PrefixLength int
+}
+
// InspectBasicNetworkConfig holds basic configuration information (e.g. IP
// addresses, MAC address, subnet masks, etc) that are common for all networks
// (both additional and main).
@@ -556,7 +562,7 @@ type InspectBasicNetworkConfig struct {
IPPrefixLen int `json:"IPPrefixLen"`
// SecondaryIPAddresses is a list of extra IP Addresses that the
// container has been assigned in this network.
- SecondaryIPAddresses []string `json:"SecondaryIPAddresses,omitempty"`
+ SecondaryIPAddresses []Address `json:"SecondaryIPAddresses,omitempty"`
// IPv6Gateway is the IPv6 gateway this network will use.
IPv6Gateway string `json:"IPv6Gateway"`
// GlobalIPv6Address is the global-scope IPv6 Address for this network.
@@ -565,7 +571,7 @@ type InspectBasicNetworkConfig struct {
GlobalIPv6PrefixLen int `json:"GlobalIPv6PrefixLen"`
// SecondaryIPv6Addresses is a list of extra IPv6 Addresses that the
// container has been assigned in this network.
- SecondaryIPv6Addresses []string `json:"SecondaryIPv6Addresses,omitempty"`
+ SecondaryIPv6Addresses []Address `json:"SecondaryIPv6Addresses,omitempty"`
// MacAddress is the MAC address for the interface in this network.
MacAddress string `json:"MacAddress"`
// AdditionalMacAddresses is a set of additional MAC Addresses beyond
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index 9be600bb4..4150509d7 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -1133,7 +1133,7 @@ func resultToBasicNetworkConfig(result types.StatusBlock) (define.InspectBasicNe
config.IPPrefixLen = size
config.Gateway = netAddress.Gateway.String()
} else {
- config.SecondaryIPAddresses = append(config.SecondaryIPAddresses, netAddress.IPNet.IP.String())
+ config.SecondaryIPAddresses = append(config.SecondaryIPAddresses, define.Address{Addr: netAddress.IPNet.IP.String(), PrefixLength: size})
}
} else {
//ipv6
@@ -1142,7 +1142,7 @@ func resultToBasicNetworkConfig(result types.StatusBlock) (define.InspectBasicNe
config.GlobalIPv6PrefixLen = size
config.IPv6Gateway = netAddress.Gateway.String()
} else {
- config.SecondaryIPv6Addresses = append(config.SecondaryIPv6Addresses, netAddress.IPNet.IP.String())
+ config.SecondaryIPv6Addresses = append(config.SecondaryIPv6Addresses, define.Address{Addr: netAddress.IPNet.IP.String(), PrefixLength: size})
}
}
}
diff --git a/libpod/networking_linux_test.go b/libpod/networking_linux_test.go
index 06bf05723..d925b69f7 100644
--- a/libpod/networking_linux_test.go
+++ b/libpod/networking_linux_test.go
@@ -2,10 +2,14 @@ package libpod
import (
"fmt"
+ "net"
+ "reflect"
"testing"
- "github.com/containers/podman/v3/libpod/network/types"
"github.com/stretchr/testify/assert"
+
+ "github.com/containers/podman/v3/libpod/define"
+ "github.com/containers/podman/v3/libpod/network/types"
)
func Test_ocicniPortsToNetTypesPorts(t *testing.T) {
@@ -234,6 +238,217 @@ func Test_ocicniPortsToNetTypesPorts(t *testing.T) {
}
}
+func Test_resultToBasicNetworkConfig(t *testing.T) {
+ testCases := []struct {
+ description string
+ expectError bool
+ inputResult types.StatusBlock
+ expectedNetworkConfig define.InspectBasicNetworkConfig
+ }{
+ {
+ description: "single secondary IPv4 address is shown as define.Address",
+ inputResult: types.StatusBlock{
+ Interfaces: map[string]types.NetInterface{
+ "eth1": {
+ Subnets: []types.NetAddress{
+ {
+ Gateway: net.ParseIP("172.26.0.1"),
+ IPNet: types.IPNet{
+ IPNet: net.IPNet{
+ IP: net.ParseIP("172.26.0.2"),
+ Mask: net.CIDRMask(20, 32),
+ },
+ },
+ },
+ {
+ IPNet: types.IPNet{
+ IPNet: net.IPNet{
+ IP: net.ParseIP("172.26.0.3"),
+ Mask: net.CIDRMask(10, 32),
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ expectedNetworkConfig: define.InspectBasicNetworkConfig{
+ IPAddress: "172.26.0.2",
+ IPPrefixLen: 20,
+ Gateway: "172.26.0.1",
+ SecondaryIPAddresses: []define.Address{
+ {
+ Addr: "172.26.0.3",
+ PrefixLength: 10,
+ },
+ },
+ },
+ },
+ {
+ description: "multiple secondary IPv4 addresses are shown as define.Address",
+ inputResult: types.StatusBlock{
+ Interfaces: map[string]types.NetInterface{
+ "eth1": {
+ Subnets: []types.NetAddress{
+ {
+ Gateway: net.ParseIP("172.26.0.1"),
+ IPNet: types.IPNet{
+ IPNet: net.IPNet{
+ IP: net.ParseIP("172.26.0.2"),
+ Mask: net.CIDRMask(20, 32),
+ },
+ },
+ },
+ {
+ IPNet: types.IPNet{
+ IPNet: net.IPNet{
+ IP: net.ParseIP("172.26.0.3"),
+ Mask: net.CIDRMask(10, 32),
+ },
+ },
+ },
+ {
+ IPNet: types.IPNet{
+ IPNet: net.IPNet{
+ IP: net.ParseIP("172.26.0.4"),
+ Mask: net.CIDRMask(24, 32),
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ expectedNetworkConfig: define.InspectBasicNetworkConfig{
+ IPAddress: "172.26.0.2",
+ IPPrefixLen: 20,
+ Gateway: "172.26.0.1",
+ SecondaryIPAddresses: []define.Address{
+ {
+ Addr: "172.26.0.3",
+ PrefixLength: 10,
+ },
+ {
+ Addr: "172.26.0.4",
+ PrefixLength: 24,
+ },
+ },
+ },
+ },
+ {
+ description: "single secondary IPv6 address is shown as define.Address",
+ inputResult: types.StatusBlock{
+ Interfaces: map[string]types.NetInterface{
+ "eth1": {
+ Subnets: []types.NetAddress{
+ {
+ Gateway: net.ParseIP("ff02::fb"),
+ IPNet: types.IPNet{
+ IPNet: net.IPNet{
+ IP: net.ParseIP("ff02::fc"),
+ Mask: net.CIDRMask(20, 128),
+ },
+ },
+ },
+ {
+ IPNet: types.IPNet{
+ IPNet: net.IPNet{
+ IP: net.ParseIP("ff02::fd"),
+ Mask: net.CIDRMask(10, 128),
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ expectedNetworkConfig: define.InspectBasicNetworkConfig{
+ GlobalIPv6Address: "ff02::fc",
+ GlobalIPv6PrefixLen: 20,
+ IPv6Gateway: "ff02::fb",
+ SecondaryIPv6Addresses: []define.Address{
+ {
+ Addr: "ff02::fd",
+ PrefixLength: 10,
+ },
+ },
+ },
+ },
+ {
+ description: "multiple secondary IPv6 addresses are shown as define.Address",
+ inputResult: types.StatusBlock{
+ Interfaces: map[string]types.NetInterface{
+ "eth1": {
+ Subnets: []types.NetAddress{
+ {
+ Gateway: net.ParseIP("ff02::fb"),
+ IPNet: types.IPNet{
+ IPNet: net.IPNet{
+ IP: net.ParseIP("ff02::fc"),
+ Mask: net.CIDRMask(20, 128),
+ },
+ },
+ },
+ {
+ IPNet: types.IPNet{
+ IPNet: net.IPNet{
+ IP: net.ParseIP("ff02::fd"),
+ Mask: net.CIDRMask(10, 128),
+ },
+ },
+ },
+ {
+ IPNet: types.IPNet{
+ IPNet: net.IPNet{
+ IP: net.ParseIP("ff02::fe"),
+ Mask: net.CIDRMask(24, 128),
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ expectedNetworkConfig: define.InspectBasicNetworkConfig{
+ GlobalIPv6Address: "ff02::fc",
+ GlobalIPv6PrefixLen: 20,
+ IPv6Gateway: "ff02::fb",
+ SecondaryIPv6Addresses: []define.Address{
+ {
+ Addr: "ff02::fd",
+ PrefixLength: 10,
+ },
+ {
+ Addr: "ff02::fe",
+ PrefixLength: 24,
+ },
+ },
+ },
+ },
+ }
+
+ for _, tcl := range testCases {
+ tc := tcl
+ t.Run(tc.description, func(t *testing.T) {
+ t.Parallel()
+ actualNetworkConfig, err := resultToBasicNetworkConfig(tc.inputResult)
+
+ if tc.expectError && err == nil {
+ t.Fatalf("Expected error didn't happen")
+ }
+
+ if !tc.expectError && err != nil {
+ t.Fatalf("Unexpected error happened: %v", err)
+ }
+
+ if !reflect.DeepEqual(tc.expectedNetworkConfig, actualNetworkConfig) {
+ t.Fatalf(
+ "Expected networkConfig %+v didn't match actual value %+v", tc.expectedNetworkConfig, actualNetworkConfig)
+ }
+ })
+ }
+}
+
func benchmarkOCICNIPortsToNetTypesPorts(b *testing.B, ports []types.OCICNIPortMapping) {
for n := 0; n < b.N; n++ {
ocicniPortsToNetTypesPorts(ports)