Skip to content

Commit

Permalink
Merge pull request #50 from steveeJ/gwfix
Browse files Browse the repository at this point in the history
bridge: add isDefaultGateway field
  • Loading branch information
steveej committed May 20, 2016
2 parents d30040f + 8afda5f commit 20fa3d3
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 7 deletions.
3 changes: 2 additions & 1 deletion Documentation/bridge.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ If the bridge is missing, the plugin will create one on first use and, if gatewa
"name": "mynet",
"type": "bridge",
"bridge": "mynet0",
"isGateway": true,
"isDefaultGateway": true,
"ipMasq": true,
"hairpinMode": true,
"ipam": {
Expand All @@ -33,6 +33,7 @@ If the bridge is missing, the plugin will create one on first use and, if gatewa
* `type` (string, required): "bridge".
* `bridge` (string, optional): name of the bridge to use/create. Defaults to "cni0".
* `isGateway` (boolean, optional): assign an IP address to the bridge. Defaults to false.
* `isDefaultGateway` (boolean, optional): Sets isGateway to true and makes the assigned IP the default route. Defaults to false.
* `ipMasq` (boolean, optional): set up IP Masquerade on the host for traffic originating from this network and destined outside of it. Defaults to false.
* `mtu` (integer, optional): explicitly set MTU to the specified value. Defaults to the value chosen by the kernel.
* `hairpinMode` (boolean, optional): set hairpin mode for interfaces on the bridge. Defaults to false.
Expand Down
37 changes: 34 additions & 3 deletions plugins/main/bridge/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type NetConf struct {
types.NetConf
BrName string `json:"bridge"`
IsGW bool `json:"isGateway"`
IsDefaultGW bool `json:"isDefaultGateway"`
IPMasq bool `json:"ipMasq"`
MTU int `json:"mtu"`
HairpinMode bool `json:"hairpinMode"`
Expand Down Expand Up @@ -185,6 +186,10 @@ func cmdAdd(args *skel.CmdArgs) error {
return err
}

if n.IsDefaultGW {
n.IsGW = true
}

br, err := setupBridge(n)
if err != nil {
return err
Expand All @@ -206,6 +211,7 @@ func cmdAdd(args *skel.CmdArgs) error {
return err
}

// TODO: make this optional when IPv6 is supported
if result.IP4 == nil {
return errors.New("IPAM plugin returned missing IPv4 config")
}
Expand All @@ -214,10 +220,35 @@ func cmdAdd(args *skel.CmdArgs) error {
result.IP4.Gateway = calcGatewayIP(&result.IP4.IP)
}

err = netns.Do(func(_ ns.NetNS) error {
if err := netns.Do(func(_ ns.NetNS) error {
// set the default gateway if requested
if n.IsDefaultGW {
_, defaultNet, err := net.ParseCIDR("0.0.0.0/0")
if err != nil {
return err
}

for _, route := range result.IP4.Routes {
if defaultNet.String() == route.Dst.String() {
if route.GW != nil && !route.GW.Equal(result.IP4.Gateway) {
return fmt.Errorf(
"isDefaultGateway ineffective because IPAM sets default route via %q",
route.GW,
)
}
}
}

result.IP4.Routes = append(
result.IP4.Routes,
types.Route{Dst: *defaultNet, GW: result.IP4.Gateway},
)

// TODO: IPV6
}

return ipam.ConfigureIface(args.IfName, result)
})
if err != nil {
}); err != nil {
return err
}

Expand Down
20 changes: 17 additions & 3 deletions plugins/main/bridge/bridge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ var _ = Describe("bridge Operations", func() {
Expect(err).NotTo(HaveOccurred())
})

It("configures and deconfigures a bridge and veth with ADD/DEL", func() {
It("configures and deconfigures a bridge and veth with default route with ADD/DEL", func() {
const BRNAME = "cni0"
const IFNAME = "eth0"

Expand All @@ -127,7 +127,7 @@ var _ = Describe("bridge Operations", func() {
"name": "mynet",
"type": "bridge",
"bridge": "%s",
"isGateway": true,
"isDefaultGateway": true,
"ipMasq": false,
"ipam": {
"type": "host-local",
Expand Down Expand Up @@ -189,13 +189,27 @@ var _ = Describe("bridge Operations", func() {
})
Expect(err).NotTo(HaveOccurred())

// Find the veth peer in the container namespace
// Find the veth peer in the container namespace and the default route
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))

// Ensure the default route
routes, err := netlink.RouteList(link, 0)
Expect(err).NotTo(HaveOccurred())

var defaultRouteFound bool
for _, route := range routes {
defaultRouteFound = (route.Dst == nil && route.Src == nil && route.Gw.Equal(gwaddr))
if defaultRouteFound {
break
}
}
Expect(defaultRouteFound).To(Equal(true))

return nil
})
Expect(err).NotTo(HaveOccurred())
Expand Down

0 comments on commit 20fa3d3

Please sign in to comment.