var v4gw, v6gw net.IP
for _, ipc := range res.IPs {
- if int(ipc.Interface) >= len(res.Interfaces) || res.Interfaces[ipc.Interface].Name != ifName {
+ if ipc.Interface == nil {
+ continue
+ }
+ intIdx := *ipc.Interface
+ if intIdx < 0 || intIdx >= len(res.Interfaces) || res.Interfaces[intIdx].Name != ifName {
// IP address is for a different interface
return fmt.Errorf("failed to add IP addr %v to %q: invalid interface index", ipc, ifName)
}
IPs: []*current.IPConfig{
{
Version: "4",
- Interface: 0,
+ Interface: current.Int(0),
Address: *ipv4,
Gateway: ipgw4,
},
{
Version: "6",
- Interface: 0,
+ Interface: current.Int(0),
Address: *ipv6,
Gateway: ipgw6,
},
})
It("returns an error when the interface index doesn't match the link name", func() {
- result.IPs[0].Interface = 1
+ result.IPs[0].Interface = current.Int(1)
err := originalNS.Do(func(ns.NetNS) error {
return ConfigureIface(LINK_NAME, result)
})
})
It("returns an error when the interface index is too big", func() {
- result.IPs[0].Interface = 2
+ result.IPs[0].Interface = current.Int(2)
+ err := originalNS.Do(func(ns.NetNS) error {
+ return ConfigureIface(LINK_NAME, result)
+ })
+ Expect(err).To(HaveOccurred())
+ })
+
+ It("returns an error when the interface index is too small", func() {
+ result.IPs[0].Interface = current.Int(-1)
err := originalNS.Do(func(ns.NetNS) error {
return ConfigureIface(LINK_NAME, result)
})
})
Expect(err).To(HaveOccurred())
})
+
+ It("does not panic when interface is not specified", func() {
+ result = ¤t.Result{
+ Interfaces: []*current.Interface{
+ {
+ Name: "eth0",
+ Mac: "00:11:22:33:44:55",
+ Sandbox: "/proc/3553/ns/net",
+ },
+ {
+ Name: "fake0",
+ Mac: "00:33:44:55:66:77",
+ Sandbox: "/proc/1234/ns/net",
+ },
+ },
+ IPs: []*current.IPConfig{
+ {
+ Version: "4",
+ Address: *ipv4,
+ Gateway: ipgw4,
+ },
+ {
+ Version: "6",
+ Address: *ipv6,
+ Gateway: ipgw6,
+ },
+ },
+ }
+ err := originalNS.Do(func(ns.NetNS) error {
+ return ConfigureIface(LINK_NAME, result)
+ })
+ Expect(err).NotTo(HaveOccurred())
+ })
})
// Gomega is cranky about slices with different caps
Expect(*result.IPs[0]).To(Equal(
current.IPConfig{
- Version: "4",
- Interface: 0,
- Address: mustCIDR("10.1.2.2/24"),
- Gateway: net.ParseIP("10.1.2.1"),
+ Version: "4",
+ Address: mustCIDR("10.1.2.2/24"),
+ Gateway: net.ParseIP("10.1.2.1"),
}))
Expect(*result.IPs[1]).To(Equal(
current.IPConfig{
- Version: "6",
- Interface: 0,
- Address: mustCIDR("2001:db8:1::2/64"),
- Gateway: net.ParseIP("2001:db8:1::1"),
+ Version: "6",
+ Address: mustCIDR("2001:db8:1::2/64"),
+ Gateway: net.ParseIP("2001:db8:1::1"),
},
))
Expect(len(result.IPs)).To(Equal(2))
Expect(result.Routes).To(Equal([]*types.Route{
- &types.Route{Dst: mustCIDR("0.0.0.0/0"), GW: nil},
- &types.Route{Dst: mustCIDR("::/0"), GW: nil},
- &types.Route{Dst: mustCIDR("192.168.0.0/16"), GW: net.ParseIP("1.1.1.1")},
- &types.Route{Dst: mustCIDR("2001:db8:2::0/64"), GW: net.ParseIP("2001:db8:3::1")},
+ {Dst: mustCIDR("0.0.0.0/0"), GW: nil},
+ {Dst: mustCIDR("::/0"), GW: nil},
+ {Dst: mustCIDR("192.168.0.0/16"), GW: net.ParseIP("1.1.1.1")},
+ {Dst: mustCIDR("2001:db8:2::0/64"), GW: net.ParseIP("2001:db8:3::1")},
}))
ipFilePath1 := filepath.Join(tmpDir, "mynet", "10.1.2.2")
defaultNet.Mask = net.IPMask(defaultNet.IP)
// All IPs currently refer to the container interface
- ipc.Interface = 2
+ ipc.Interface = current.Int(2)
// If not provided, calculate the gateway address corresponding
// to the selected IP address
}
for _, ipc := range result.IPs {
// All addresses belong to the ipvlan interface
- ipc.Interface = 0
+ ipc.Interface = current.Int(0)
}
result.Interfaces = []*current.Interface{ipvlanInterface}
for _, ipc := range result.IPs {
// All addresses apply to the container macvlan interface
- ipc.Interface = 0
+ ipc.Interface = current.Int(0)
}
err = netns.Do(func(_ ns.NetNS) error {
for _, ipc := range pr.IPs {
// All addresses apply to the container veth interface
- ipc.Interface = 1
+ ipc.Interface = current.Int(1)
}
pr.Interfaces = []*current.Interface{hostInterface, containerInterface}
}
for _, ipc := range result.IPs {
// All addresses belong to the vlan interface
- ipc.Interface = 0
+ ipc.Interface = current.Int(0)
}
result.Interfaces = []*current.Interface{vlanInterface}
}
// Skip known non-sandbox interfaces
- intIdx := ip.Interface
- if intIdx >= 0 && intIdx < len(conf.PrevResult.Interfaces) && conf.PrevResult.Interfaces[intIdx].Name != ifName {
- continue
+ if ip.Interface != nil {
+ intIdx := *ip.Interface
+ if intIdx >= 0 &&
+ intIdx < len(conf.PrevResult.Interfaces) &&
+ (conf.PrevResult.Interfaces[intIdx].Name != ifName ||
+ conf.PrevResult.Interfaces[intIdx].Sandbox == "") {
+ continue
+ }
}
switch ip.Version {
case "6":
var contIP net.IP
for _, ip := range result.IPs {
- if result.Interfaces[ip.Interface].Sandbox == "" {
+ intfIndex := *ip.Interface
+ if result.Interfaces[intfIndex].Sandbox == "" {
continue
}
contIP = ip.Address.IP
_, err := parseConfig(configBytes, "container")
Expect(err).To(MatchError("Invalid host port number: 0"))
})
+
+ It("Does not fail on missing prevResult interface index", func() {
+ configBytes := []byte(`{
+ "name": "test",
+ "type": "portmap",
+ "cniVersion": "0.3.1",
+ "runtimeConfig": {
+ "portMappings": [
+ { "hostPort": 8080, "containerPort": 80, "protocol": "tcp"}
+ ]
+ },
+ "conditionsV4": ["a", "b"],
+ "prevResult": {
+ "interfaces": [
+ {"name": "host"}
+ ],
+ "ips": [
+ {
+ "version": "4",
+ "address": "10.0.0.1/24",
+ "gateway": "10.0.0.1"
+ }
+ ]
+ }
+}`)
+ _, err := parseConfig(configBytes, "container")
+ Expect(err).NotTo(HaveOccurred())
+ })
})
Describe("Generating chains", func() {
}
} else {
for _, ip := range conf.PrevResult.IPs {
- intIdx := ip.Interface
+ if ip.Interface == nil {
+ continue
+ }
+ intIdx := *ip.Interface
// Every IP is indexed in to the interfaces array, with "-1" standing
// for an unknown interface (which we'll assume to be Container-side
// Skip all IPs we know belong to an interface with the wrong name.