From b24c1f304eae70cfb3903d6f390c8a088607c7f8 Mon Sep 17 00:00:00 2001 From: Rakesh Kelkar Date: Thu, 28 Sep 2017 14:51:24 -0700 Subject: [PATCH 1/7] update flannel plugin to support calling out to wincni for hostgw (l2bridge) --- plugins/meta/flannel/flannel.go | 88 +++++++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 4 deletions(-) diff --git a/plugins/meta/flannel/flannel.go b/plugins/meta/flannel/flannel.go index 6ec0e8fcf..2dd1e0e46 100644 --- a/plugins/meta/flannel/flannel.go +++ b/plugins/meta/flannel/flannel.go @@ -26,6 +26,7 @@ import ( "net" "os" "path/filepath" + "runtime" "strconv" "strings" @@ -33,6 +34,7 @@ import ( "github.com/containernetworking/cni/pkg/skel" "github.com/containernetworking/cni/pkg/types" "github.com/containernetworking/cni/pkg/version" + "math/big" ) const ( @@ -45,6 +47,7 @@ type NetConf struct { SubnetFile string `json:"subnetFile"` DataDir string `json:"dataDir"` Delegate map[string]interface{} `json:"delegate"` + WindowsDelegate map[string]interface{} `json:"windowsDelegate"` } type subnetEnv struct { @@ -188,6 +191,10 @@ func cmdAdd(args *skel.CmdArgs) error { return err } + if runtime.GOOS == "windows" { + return cmdAddWindows(args.ContainerID, n, fenv) + } + if n.Delegate == nil { n.Delegate = make(map[string]interface{}) } else { @@ -204,10 +211,6 @@ func cmdAdd(args *skel.CmdArgs) error { n.Delegate["name"] = n.Name - if !hasKey(n.Delegate, "type") { - n.Delegate["type"] = "bridge" - } - if !hasKey(n.Delegate, "ipMasq") { // if flannel is not doing ipmasq, we should ipmasq := !*fenv.ipmasq @@ -241,6 +244,83 @@ func cmdAdd(args *skel.CmdArgs) error { return delegateAdd(args.ContainerID, n.DataDir, n.Delegate) } +func cmdAddWindows(containerID string, n *NetConf, fenv *subnetEnv) error { + if n.WindowsDelegate == nil { + n.WindowsDelegate = make(map[string]interface{}) + } else { + if hasKey(n.WindowsDelegate, "type") && !isString(n.WindowsDelegate["type"]) { + return fmt.Errorf("'delegate' dictionary, if present, must have (string) 'type' field") + } + if hasKey(n.WindowsDelegate, "name") { + return fmt.Errorf("'windowsDelegate' dictionary must not have 'name' field, it'll be set by flannel") + } + if hasKey(n.WindowsDelegate, "ipam") { + return fmt.Errorf("'windowsDelegate' dictionary must not have 'ipam' field, it'll be set by flannel") + } + } + + // TODO: rakesh: not required once Flannel starts creating the network (then we dont rely on CNI so can set any name) + n.WindowsDelegate["name"] = "l2bridge" + n.WindowsDelegate["hnsNetworkType"] = "l2bridge" + + if !hasKey(n.WindowsDelegate, "type") { + n.WindowsDelegate["type"] = "wincni.exe" + } + + if !hasKey(n.WindowsDelegate, "cniVersion") { + n.WindowsDelegate["cniVersion"] = "0.2.0" + } + + // TODO: rakesh: figure out what to do for ipmasq! + if !hasKey(n.WindowsDelegate, "ipMasq") { + // if flannel is not doing ipmasq, we should + ipmasq := !*fenv.ipmasq + n.WindowsDelegate["ipMasq"] = ipmasq + } + + // TODO: rakesh: does HNS support this? + if !hasKey(n.WindowsDelegate, "mtu") { + mtu := fenv.mtu + n.WindowsDelegate["mtu"] = mtu + } + + if n.CNIVersion != "" { + n.WindowsDelegate["cniVersion"] = n.CNIVersion + } + + // TODO: rakesh: for now CNI is IPAM - but once host-local works default to that (for overlay) + n.WindowsDelegate["ipam"] = map[string]interface{}{ + "subnet": fenv.sn.String(), + "routes": []types.Route{ + types.Route{ + GW: calcGatewayIPforWindows(fenv.sn), + Dst: net.IPNet { IP:net.IPv4zero, Mask:net.IPv4Mask(0, 0, 0, 0)}, + }, + }, + } + + return delegateAdd(containerID, n.DataDir, n.WindowsDelegate) +} + +func calcGatewayIPforWindows(ipn *net.IPNet) net.IP { + // HNS currently requires x.x.x.2 + // TODO: rakesh: file a bug somewhere to remove this when HNS the HNS limitation is fixed + nid := ipn.IP.Mask(ipn.Mask) + i := ipToInt(nid) + return intToIP(i.Add(i, big.NewInt(2))) +} + +func ipToInt(ip net.IP) *big.Int { + if v := ip.To4(); v != nil { + return big.NewInt(0).SetBytes(v) + } + return big.NewInt(0).SetBytes(ip.To16()) +} + +func intToIP(i *big.Int) net.IP { + return net.IP(i.Bytes()) +} + func cmdDel(args *skel.CmdArgs) error { nc, err := loadFlannelNetConf(args.StdinData) if err != nil { From 8307b65476e30f4d384e40fbf433162ae83203ec Mon Sep 17 00:00:00 2001 From: Rakesh Kelkar Date: Thu, 28 Sep 2017 15:08:46 -0700 Subject: [PATCH 2/7] fix type for linux and merge cniVersion logic for windows --- plugins/meta/flannel/flannel.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/plugins/meta/flannel/flannel.go b/plugins/meta/flannel/flannel.go index 2dd1e0e46..a5ef6b677 100644 --- a/plugins/meta/flannel/flannel.go +++ b/plugins/meta/flannel/flannel.go @@ -211,6 +211,10 @@ func cmdAdd(args *skel.CmdArgs) error { n.Delegate["name"] = n.Name + if !hasKey(n.Delegate, "type") { + n.Delegate["type"] = "bridge" + } + if !hasKey(n.Delegate, "ipMasq") { // if flannel is not doing ipmasq, we should ipmasq := !*fenv.ipmasq @@ -249,7 +253,7 @@ func cmdAddWindows(containerID string, n *NetConf, fenv *subnetEnv) error { n.WindowsDelegate = make(map[string]interface{}) } else { if hasKey(n.WindowsDelegate, "type") && !isString(n.WindowsDelegate["type"]) { - return fmt.Errorf("'delegate' dictionary, if present, must have (string) 'type' field") + return fmt.Errorf("'windowsDelegate' dictionary, if present, must have (string) 'type' field") } if hasKey(n.WindowsDelegate, "name") { return fmt.Errorf("'windowsDelegate' dictionary must not have 'name' field, it'll be set by flannel") @@ -267,10 +271,6 @@ func cmdAddWindows(containerID string, n *NetConf, fenv *subnetEnv) error { n.WindowsDelegate["type"] = "wincni.exe" } - if !hasKey(n.WindowsDelegate, "cniVersion") { - n.WindowsDelegate["cniVersion"] = "0.2.0" - } - // TODO: rakesh: figure out what to do for ipmasq! if !hasKey(n.WindowsDelegate, "ipMasq") { // if flannel is not doing ipmasq, we should @@ -284,6 +284,7 @@ func cmdAddWindows(containerID string, n *NetConf, fenv *subnetEnv) error { n.WindowsDelegate["mtu"] = mtu } + n.WindowsDelegate["cniVersion"] = "0.2.0" if n.CNIVersion != "" { n.WindowsDelegate["cniVersion"] = n.CNIVersion } From 0b115bb79b0a5344d154f7b7639c36bbbf7a0ffc Mon Sep 17 00:00:00 2001 From: Rakesh Kelkar Date: Fri, 29 Sep 2017 20:18:33 -0700 Subject: [PATCH 3/7] add support for ipmasq --- plugins/meta/flannel/flannel.go | 64 +++++++++++++++----- plugins/meta/flannel/flannel_windows_test.go | 26 ++++++++ 2 files changed, 74 insertions(+), 16 deletions(-) create mode 100644 plugins/meta/flannel/flannel_windows_test.go diff --git a/plugins/meta/flannel/flannel.go b/plugins/meta/flannel/flannel.go index a5ef6b677..74c062f18 100644 --- a/plugins/meta/flannel/flannel.go +++ b/plugins/meta/flannel/flannel.go @@ -263,33 +263,19 @@ func cmdAddWindows(containerID string, n *NetConf, fenv *subnetEnv) error { } } - // TODO: rakesh: not required once Flannel starts creating the network (then we dont rely on CNI so can set any name) - n.WindowsDelegate["name"] = "l2bridge" - n.WindowsDelegate["hnsNetworkType"] = "l2bridge" + n.WindowsDelegate["name"] = n.Name if !hasKey(n.WindowsDelegate, "type") { n.WindowsDelegate["type"] = "wincni.exe" } - // TODO: rakesh: figure out what to do for ipmasq! - if !hasKey(n.WindowsDelegate, "ipMasq") { - // if flannel is not doing ipmasq, we should - ipmasq := !*fenv.ipmasq - n.WindowsDelegate["ipMasq"] = ipmasq - } - - // TODO: rakesh: does HNS support this? - if !hasKey(n.WindowsDelegate, "mtu") { - mtu := fenv.mtu - n.WindowsDelegate["mtu"] = mtu - } + updateOutboundNat(&n.WindowsDelegate, fenv) n.WindowsDelegate["cniVersion"] = "0.2.0" if n.CNIVersion != "" { n.WindowsDelegate["cniVersion"] = n.CNIVersion } - // TODO: rakesh: for now CNI is IPAM - but once host-local works default to that (for overlay) n.WindowsDelegate["ipam"] = map[string]interface{}{ "subnet": fenv.sn.String(), "routes": []types.Route{ @@ -303,6 +289,52 @@ func cmdAddWindows(containerID string, n *NetConf, fenv *subnetEnv) error { return delegateAdd(containerID, n.DataDir, n.WindowsDelegate) } +func updateOutboundNat(windowsDelegate *map[string]interface{}, fenv *subnetEnv) error { + if hasKey(*windowsDelegate, "AdditionalArgs") { + addlArgs := (*windowsDelegate)["AdditionalArgs"] + switch at := addlArgs.(type) { + case []interface{}: + for _, policy := range at { + switch pt := policy.(type) { + case map[string]interface{}: + if hasKey(pt, "Value") { + policyValue := pt["Value"] + switch pv := policyValue.(type) { + case map[string]interface{}: + if hasKey(pv, "Type") { + if strings.EqualFold(pv["Type"].(string), "OutBoundNAT") { + // keep what the user configured + return nil + } + } + } + + } + } + } + default: + return fmt.Errorf("invalid config, WindowsDelegate.AdditionalArgs must be an array") + } + } + + ipmasq := !*fenv.ipmasq + if ipmasq { + (*windowsDelegate)["AdditionalArgs"] = []interface {}{ + map[string]interface{}{ + "Name": "EndpointPolicy", + "Value": map[string]interface{}{ + "Type": "OutBoundNAT", + "ExceptionList": []string{ + fenv.nw.String(), + }, + }, + }, + } + } + + return nil +} + func calcGatewayIPforWindows(ipn *net.IPNet) net.IP { // HNS currently requires x.x.x.2 // TODO: rakesh: file a bug somewhere to remove this when HNS the HNS limitation is fixed diff --git a/plugins/meta/flannel/flannel_windows_test.go b/plugins/meta/flannel/flannel_windows_test.go new file mode 100644 index 000000000..ccdffde55 --- /dev/null +++ b/plugins/meta/flannel/flannel_windows_test.go @@ -0,0 +1,26 @@ +// Copyright 2015 CNI authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package main + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "testing" +) + +func TestFlannel(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Flannel Suite") +} From 979edd1df65cab0d688ff3e394438852c2f299c0 Mon Sep 17 00:00:00 2001 From: Rakesh Kelkar Date: Fri, 29 Sep 2017 20:18:47 -0700 Subject: [PATCH 4/7] add tests for windows fns --- plugins/meta/flannel/flannel_windows_test.go | 74 ++++++++++++++++++-- 1 file changed, 68 insertions(+), 6 deletions(-) diff --git a/plugins/meta/flannel/flannel_windows_test.go b/plugins/meta/flannel/flannel_windows_test.go index ccdffde55..3412679e1 100644 --- a/plugins/meta/flannel/flannel_windows_test.go +++ b/plugins/meta/flannel/flannel_windows_test.go @@ -14,13 +14,75 @@ package main import ( - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - "testing" + "net" + "github.com/stretchr/testify/assert" ) -func TestFlannel(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Flannel Suite") +func TestFlannelSetsWindowsOutboutNat(t *testing.T) { + // given a subnet config that requests ipmasq + _, nw, _ := net.ParseCIDR("192.168.0.0/16") + _, sn, _ := net.ParseCIDR("192.168.10.0/24") + ipmasq := true + fenv := &subnetEnv{ + nw: nw, + sn: sn, + ipmasq: &ipmasq, + } + + // apply it + delegate := make(map[string]interface{}) + err := updateOutboundNat(&delegate, fenv) + + // verify it got applied + assert.Nil(t, err) + assert.True(t, hasKey(delegate, "AdditionalArgs")) + + addlArgs := (delegate["AdditionalArgs"]).([]interface{}) + assert.Equal(t, 1, len(addlArgs)) + + policy := addlArgs[0].(map[string]interface{}) + assert.True(t, hasKey(policy, "Name")) + assert.True(t, hasKey(policy, "Value")) + assert.Equal(t, "EndpointPolicy", policy["Name"]) + + value := policy["Value"].(map[string]interface{}) + assert.True(t, hasKey(value, "Type")) + assert.True(t, hasKey(value, "ExceptionList")) + assert.Equal(t, "OutBoundNAT", value["Type"]) + + exceptionList := value["ExceptionList"].([]interface{}) + assert.Equal(t, 1, len(exceptionList)) + assert.Equal(t, nw.String(), exceptionList[0].(string)) +} + +func TestFlannelSkipsIfOutboutNatAlreadySet(t *testing.T) { + + // given a subnet config that requests ipmasq + _, nw, _ := net.ParseCIDR("192.168.0.0/16") + _, sn, _ := net.ParseCIDR("192.168.10.0/24") + ipmasq := true + fenv := &subnetEnv{ + nw: nw, + sn: sn, + ipmasq: &ipmasq, + } + + // first set it + delegate := make(map[string]interface{}) + err := updateOutboundNat(&delegate, fenv) + assert.Nil(t, err) + + // then attempt to update it + _, nw2, _ := net.ParseCIDR("10.244.0.0/16") + fenv.nw = nw2 + err = updateOutboundNat(&delegate, fenv) + + // but it stays the same! + addlArgs := (delegate["AdditionalArgs"]).([]interface{}) + policy := addlArgs[0].(map[string]interface{}) + value := policy["Value"].(map[string]interface{}) + exceptionList := value["ExceptionList"].([]interface{}) + assert.Equal(t, nw.String(), exceptionList[0].(string)) + assert.NotEqual(t, nw2.String(), exceptionList[0].(string)) } From ad39caa729abcceb26d05fb89292eee3d5ae7e65 Mon Sep 17 00:00:00 2001 From: Rakesh Kelkar Date: Sat, 30 Sep 2017 09:53:02 -0700 Subject: [PATCH 5/7] for windows always set outboundNat in CNI --- plugins/meta/flannel/flannel.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/meta/flannel/flannel.go b/plugins/meta/flannel/flannel.go index 74c062f18..e9f08a9c7 100644 --- a/plugins/meta/flannel/flannel.go +++ b/plugins/meta/flannel/flannel.go @@ -317,14 +317,15 @@ func updateOutboundNat(windowsDelegate *map[string]interface{}, fenv *subnetEnv) } } - ipmasq := !*fenv.ipmasq + // Get Windows CNI to setup ipmasq + ipmasq := *fenv.ipmasq if ipmasq { (*windowsDelegate)["AdditionalArgs"] = []interface {}{ map[string]interface{}{ "Name": "EndpointPolicy", "Value": map[string]interface{}{ "Type": "OutBoundNAT", - "ExceptionList": []string{ + "ExceptionList": []interface{}{ fenv.nw.String(), }, }, From 16f009c1a3c14ba2641f788c112c232273fa64d9 Mon Sep 17 00:00:00 2001 From: Rakesh Kelkar Date: Sat, 30 Sep 2017 10:51:02 -0700 Subject: [PATCH 6/7] simplify outboundnat logic and get it to append instead of overwriting existing settings --- plugins/meta/flannel/flannel.go | 87 +++++++++++--------- plugins/meta/flannel/flannel_windows_test.go | 14 ++-- 2 files changed, 53 insertions(+), 48 deletions(-) diff --git a/plugins/meta/flannel/flannel.go b/plugins/meta/flannel/flannel.go index e9f08a9c7..1a0e9553c 100644 --- a/plugins/meta/flannel/flannel.go +++ b/plugins/meta/flannel/flannel.go @@ -44,10 +44,10 @@ const ( type NetConf struct { types.NetConf - SubnetFile string `json:"subnetFile"` - DataDir string `json:"dataDir"` - Delegate map[string]interface{} `json:"delegate"` - WindowsDelegate map[string]interface{} `json:"windowsDelegate"` + SubnetFile string `json:"subnetFile"` + DataDir string `json:"dataDir"` + Delegate map[string]interface{} `json:"delegate"` + WindowsDelegate map[string]interface{} `json:"windowsDelegate"` } type subnetEnv struct { @@ -280,8 +280,8 @@ func cmdAddWindows(containerID string, n *NetConf, fenv *subnetEnv) error { "subnet": fenv.sn.String(), "routes": []types.Route{ types.Route{ - GW: calcGatewayIPforWindows(fenv.sn), - Dst: net.IPNet { IP:net.IPv4zero, Mask:net.IPv4Mask(0, 0, 0, 0)}, + GW: calcGatewayIPforWindows(fenv.sn), + Dst: net.IPNet{IP: net.IPv4zero, Mask: net.IPv4Mask(0, 0, 0, 0)}, }, }, } @@ -289,51 +289,58 @@ func cmdAddWindows(containerID string, n *NetConf, fenv *subnetEnv) error { return delegateAdd(containerID, n.DataDir, n.WindowsDelegate) } -func updateOutboundNat(windowsDelegate *map[string]interface{}, fenv *subnetEnv) error { - if hasKey(*windowsDelegate, "AdditionalArgs") { - addlArgs := (*windowsDelegate)["AdditionalArgs"] - switch at := addlArgs.(type) { - case []interface{}: - for _, policy := range at { - switch pt := policy.(type) { - case map[string]interface{}: - if hasKey(pt, "Value") { - policyValue := pt["Value"] - switch pv := policyValue.(type) { - case map[string]interface{}: - if hasKey(pv, "Type") { - if strings.EqualFold(pv["Type"].(string), "OutBoundNAT") { - // keep what the user configured - return nil - } +func updateOutboundNat(windowsDelegate *map[string]interface{}, fenv *subnetEnv) { + if !*fenv.ipmasq { + return + } + + if !hasKey(*windowsDelegate, "AdditionalArgs") { + (*windowsDelegate)["AdditionalArgs"] = []interface{}{} + } + addlArgs := (*windowsDelegate)["AdditionalArgs"].([]interface{}) + nwToNat := fenv.nw.String() + for _, policy := range addlArgs { + pt := policy.(map[string]interface{}) + if hasKey(pt, "Value") { + policyValue := pt["Value"] + switch pv := policyValue.(type) { + case map[string]interface{}: + if hasKey(pv, "Type") { + if strings.EqualFold(pv["Type"].(string), "OutBoundNAT") { + if !hasKey(pv, "ExceptionList") { + // add the exception since there weren't any + pv["ExceptionList"] = []interface{}{nwToNat} + return + } + + nets := pv["ExceptionList"].([]interface{}) + for _, net := range nets { + if net.(string) == nwToNat { + // found it - do nothing + return } } + // its not in the list of exceptions, add it + pv["ExceptionList"] = append(nets, nwToNat) + return } } } - default: - return fmt.Errorf("invalid config, WindowsDelegate.AdditionalArgs must be an array") } } - // Get Windows CNI to setup ipmasq - ipmasq := *fenv.ipmasq - if ipmasq { - (*windowsDelegate)["AdditionalArgs"] = []interface {}{ - map[string]interface{}{ - "Name": "EndpointPolicy", - "Value": map[string]interface{}{ - "Type": "OutBoundNAT", - "ExceptionList": []interface{}{ - fenv.nw.String(), - }, - }, + // didn't find the policy, add it + natEntry := map[string]interface{}{ + "Name": "EndpointPolicy", + "Value": map[string]interface{}{ + "Type": "OutBoundNAT", + "ExceptionList": []interface{}{ + nwToNat, }, - } + }, } - - return nil + (*windowsDelegate)["AdditionalArgs"] = append(addlArgs, natEntry) } func calcGatewayIPforWindows(ipn *net.IPNet) net.IP { diff --git a/plugins/meta/flannel/flannel_windows_test.go b/plugins/meta/flannel/flannel_windows_test.go index 3412679e1..9d128dfee 100644 --- a/plugins/meta/flannel/flannel_windows_test.go +++ b/plugins/meta/flannel/flannel_windows_test.go @@ -19,7 +19,7 @@ import ( "github.com/stretchr/testify/assert" ) -func TestFlannelSetsWindowsOutboutNat(t *testing.T) { +func TestFlannelSetsWindowsOutboundNatWhenNotSet(t *testing.T) { // given a subnet config that requests ipmasq _, nw, _ := net.ParseCIDR("192.168.0.0/16") _, sn, _ := net.ParseCIDR("192.168.10.0/24") @@ -32,10 +32,9 @@ func TestFlannelSetsWindowsOutboutNat(t *testing.T) { // apply it delegate := make(map[string]interface{}) - err := updateOutboundNat(&delegate, fenv) + updateOutboundNat(&delegate, fenv) // verify it got applied - assert.Nil(t, err) assert.True(t, hasKey(delegate, "AdditionalArgs")) addlArgs := (delegate["AdditionalArgs"]).([]interface{}) @@ -56,7 +55,7 @@ func TestFlannelSetsWindowsOutboutNat(t *testing.T) { assert.Equal(t, nw.String(), exceptionList[0].(string)) } -func TestFlannelSkipsIfOutboutNatAlreadySet(t *testing.T) { +func TestFlannelAppendsOutboundNatToExistingPolicy(t *testing.T) { // given a subnet config that requests ipmasq _, nw, _ := net.ParseCIDR("192.168.0.0/16") @@ -70,13 +69,12 @@ func TestFlannelSkipsIfOutboutNatAlreadySet(t *testing.T) { // first set it delegate := make(map[string]interface{}) - err := updateOutboundNat(&delegate, fenv) - assert.Nil(t, err) + updateOutboundNat(&delegate, fenv) // then attempt to update it _, nw2, _ := net.ParseCIDR("10.244.0.0/16") fenv.nw = nw2 - err = updateOutboundNat(&delegate, fenv) + updateOutboundNat(&delegate, fenv) // but it stays the same! addlArgs := (delegate["AdditionalArgs"]).([]interface{}) @@ -84,5 +82,5 @@ func TestFlannelSkipsIfOutboutNatAlreadySet(t *testing.T) { value := policy["Value"].(map[string]interface{}) exceptionList := value["ExceptionList"].([]interface{}) assert.Equal(t, nw.String(), exceptionList[0].(string)) - assert.NotEqual(t, nw2.String(), exceptionList[0].(string)) + assert.Equal(t, nw2.String(), exceptionList[1].(string)) } From 9bbdfedc4fedf2ac0bca4a0fe8093da95c501a35 Mon Sep 17 00:00:00 2001 From: Rakesh Kelkar Date: Tue, 3 Oct 2017 22:15:03 -0700 Subject: [PATCH 7/7] remove Dst attrib --- plugins/meta/flannel/flannel.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/plugins/meta/flannel/flannel.go b/plugins/meta/flannel/flannel.go index 1a0e9553c..044defd3d 100644 --- a/plugins/meta/flannel/flannel.go +++ b/plugins/meta/flannel/flannel.go @@ -278,13 +278,12 @@ func cmdAddWindows(containerID string, n *NetConf, fenv *subnetEnv) error { n.WindowsDelegate["ipam"] = map[string]interface{}{ "subnet": fenv.sn.String(), - "routes": []types.Route{ - types.Route{ - GW: calcGatewayIPforWindows(fenv.sn), - Dst: net.IPNet{IP: net.IPv4zero, Mask: net.IPv4Mask(0, 0, 0, 0)}, + "routes": []interface{}{ + map[string]interface{}{ + "GW": calcGatewayIPforWindows(fenv.sn), + }, }, - }, - } + } return delegateAdd(containerID, n.DataDir, n.WindowsDelegate) }