Compare commits

..

6 Commits

Author SHA1 Message Date
72b62babee Merge pull request #141 from squeed/missing-mac
pkg/ip: re-fetch the created link to return creation-time parameters
2018-04-12 11:09:35 +02:00
26dafaa097 plugins/ptp: test for valid data in Interfaces field 2018-04-11 15:19:20 +02:00
13e6a4b2ba plugins/bridge: Make stricter assertions about the return data 2018-04-11 15:10:39 +02:00
00b072dd0b pkg/ip: re-fetch the created link to return creation-time parameters
Fixes: #140
2018-04-11 15:04:38 +02:00
dd8ff8a5cf Merge pull request #113 from nyren/master
Explicitly enable IPv6 sysctl
2018-02-14 16:11:11 +00:00
08ec2995ba Explicitly enable IPv6 sysctl
If CNI is about to configure an IPv6 address, make sure IPv6 is not
disabled through the "disable_ipv6" sysctl setting.

This is a workaround for Docker 17.06 and later which sets
disable_ipv6=1 for all interfaces even if ipv6 is enabled in Docker.
2018-02-13 20:11:06 +01:00
4 changed files with 58 additions and 2 deletions

View File

@ -42,8 +42,14 @@ func makeVethPair(name, peer string, mtu int) (netlink.Link, error) {
if err := netlink.LinkAdd(veth); err != nil {
return nil, err
}
// Re-fetch the link to get its creation-time parameters, e.g. index and mac
veth2, err := netlink.LinkByName(name)
if err != nil {
netlink.LinkDel(veth) // try and clean up the link if possible.
return nil, err
}
return veth, nil
return veth2, nil
}
func peerExists(name string) bool {

View File

@ -21,10 +21,15 @@ import (
"github.com/containernetworking/cni/pkg/types/current"
"github.com/containernetworking/plugins/pkg/ip"
"github.com/containernetworking/plugins/pkg/utils/sysctl"
"github.com/vishvananda/netlink"
)
const (
DisableIPv6SysctlTemplate = "net.ipv6.conf.%s.disable_ipv6"
)
// ConfigureIface takes the result of IPAM plugin and
// applies to the ifName interface
func ConfigureIface(ifName string, res *current.Result) error {
@ -42,6 +47,7 @@ func ConfigureIface(ifName string, res *current.Result) error {
}
var v4gw, v6gw net.IP
var has_enabled_ipv6 bool = false
for _, ipc := range res.IPs {
if ipc.Interface == nil {
continue
@ -52,6 +58,30 @@ func ConfigureIface(ifName string, res *current.Result) error {
return fmt.Errorf("failed to add IP addr %v to %q: invalid interface index", ipc, ifName)
}
// Make sure sysctl "disable_ipv6" is 0 if we are about to add
// an IPv6 address to the interface
if !has_enabled_ipv6 && ipc.Version == "6" {
// Enabled IPv6 for loopback "lo" and the interface
// being configured
for _, iface := range [2]string{"lo", ifName} {
ipv6SysctlValueName := fmt.Sprintf(DisableIPv6SysctlTemplate, iface)
// Read current sysctl value
value, err := sysctl.Sysctl(ipv6SysctlValueName)
if err != nil || value == "0" {
// FIXME: log warning if unable to read sysctl value
continue
}
// Write sysctl to enable IPv6
_, err = sysctl.Sysctl(ipv6SysctlValueName, "0")
if err != nil {
return fmt.Errorf("failed to enable IPv6 for interface %q (%s=%s): %v", iface, ipv6SysctlValueName, value, err)
}
}
has_enabled_ipv6 = true
}
addr := &netlink.Addr{IPNet: &ipc.Address, Label: ""}
if err = netlink.AddrAdd(link, addr); err != nil {
return fmt.Errorf("failed to add IP addr %v to %q: %v", ipc, ifName, err)

View File

@ -257,7 +257,14 @@ func (tester *testerV03x) cmdAddTest(tc testCase) {
Expect(len(result.Interfaces)).To(Equal(3))
Expect(result.Interfaces[0].Name).To(Equal(BRNAME))
Expect(result.Interfaces[0].Mac).To(HaveLen(17))
Expect(result.Interfaces[1].Name).To(HavePrefix("veth"))
Expect(result.Interfaces[1].Mac).To(HaveLen(17))
Expect(result.Interfaces[2].Name).To(Equal(IFNAME))
Expect(result.Interfaces[2].Mac).To(HaveLen(17)) //mac is random
Expect(result.Interfaces[2].Sandbox).To(Equal(tester.targetNS.Path()))
// Make sure bridge link exists
link, err := netlink.LinkByName(result.Interfaces[0].Name)

View File

@ -78,12 +78,14 @@ var _ = Describe("ptp Operations", func() {
// Make sure ptp link exists in the target namespace
// Then, ping the gateway
seenIPs := 0
wantMac := ""
err = targetNs.Do(func(ns.NetNS) error {
defer GinkgoRecover()
link, err := netlink.LinkByName(IFNAME)
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().Name).To(Equal(IFNAME))
wantMac = link.Attrs().HardwareAddr.String()
for _, ipc := range res.IPs {
if *ipc.Interface != 1 {
@ -105,6 +107,17 @@ var _ = Describe("ptp Operations", func() {
Expect(seenIPs).To(Equal(numIPs))
// make sure the interfaces are correct
Expect(res.Interfaces).To(HaveLen(2))
Expect(res.Interfaces[0].Name).To(HavePrefix("veth"))
Expect(res.Interfaces[0].Mac).To(HaveLen(17))
Expect(res.Interfaces[0].Sandbox).To(BeEmpty())
Expect(res.Interfaces[1].Name).To(Equal(IFNAME))
Expect(res.Interfaces[1].Mac).To(Equal(wantMac))
Expect(res.Interfaces[1].Sandbox).To(Equal(targetNs.Path()))
// Call the plugins with the DEL command, deleting the veth endpoints
err = originalNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()