bridge: add isDefaultGateway field
authorStefan Junker <mail@stefanjunker.de>
Fri, 4 Sep 2015 20:23:43 +0000 (22:23 +0200)
committerStefan Junker <mail@stefanjunker.de>
Fri, 20 May 2016 22:38:42 +0000 (00:38 +0200)
When isDefaultGateway is true it automatically sets isGateway to true.
The default route will be added via the (bridge's) gateway IP.
If a default gateway has been configured via IPAM in the same
configuration file, the plugin will error out.

Documentation/bridge.md
plugins/main/bridge/bridge.go

index f9c7f2c..dcf52b7 100644 (file)
@@ -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": {
@@ -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.
index b866c07..6a90a4a 100644 (file)
@@ -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"`
@@ -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
@@ -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")
        }
@@ -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
        }