plugins/bridge: add support to set hairpin mode
authorMinhan Xia <mixia@google.com>
Tue, 5 Apr 2016 17:50:28 +0000 (10:50 -0700)
committerStefan Junker <mail@stefanjunker.de>
Thu, 19 May 2016 10:06:37 +0000 (12:06 +0200)
Documentation/bridge.md
plugins/main/bridge/bridge.go

index bda5ac5..f9c7f2c 100644 (file)
@@ -19,6 +19,7 @@ If the bridge is missing, the plugin will create one on first use and, if gatewa
        "bridge": "mynet0",
        "isGateway": true,
        "ipMasq": true,
+       "hairpinMode": true,
        "ipam": {
                "type": "host-local",
                "subnet": "10.10.0.0/16"
@@ -34,4 +35,5 @@ If the bridge is missing, the plugin will create one on first use and, if gatewa
 * `isGateway` (boolean, optional): assign an IP address to the bridge. 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.
 * `ipam` (dictionary, required): IPAM configuration to be used for this network.
index 77c5215..9082b05 100644 (file)
@@ -36,10 +36,11 @@ const defaultBrName = "cni0"
 
 type NetConf struct {
        types.NetConf
-       BrName string `json:"bridge"`
-       IsGW   bool   `json:"isGateway"`
-       IPMasq bool   `json:"ipMasq"`
-       MTU    int    `json:"mtu"`
+       BrName      string `json:"bridge"`
+       IsGW        bool   `json:"isGateway"`
+       IPMasq      bool   `json:"ipMasq"`
+       MTU         int    `json:"mtu"`
+       HairpinMode bool   `json:"hairpinMode"`
 }
 
 func init() {
@@ -123,7 +124,7 @@ func ensureBridge(brName string, mtu int) (*netlink.Bridge, error) {
        return br, nil
 }
 
-func setupVeth(netns string, br *netlink.Bridge, ifName string, mtu int) error {
+func setupVeth(netns string, br *netlink.Bridge, ifName string, mtu int, hairpinMode bool) error {
        var hostVethName string
 
        err := ns.WithNetNSPath(netns, false, func(hostNS *os.File) error {
@@ -151,6 +152,11 @@ func setupVeth(netns string, br *netlink.Bridge, ifName string, mtu int) error {
                return fmt.Errorf("failed to connect %q to bridge %v: %v", hostVethName, br.Attrs().Name, err)
        }
 
+       // set hairpin mode
+       if err = netlink.LinkSetHairpin(hostVeth, hairpinMode); err != nil {
+               return fmt.Errorf("failed to setup hairpin mode for %v: %v", hostVethName, err)
+       }
+
        return nil
 }
 
@@ -180,7 +186,7 @@ func cmdAdd(args *skel.CmdArgs) error {
                return err
        }
 
-       if err = setupVeth(args.Netns, br, args.IfName, n.MTU); err != nil {
+       if err = setupVeth(args.Netns, br, args.IfName, n.MTU, n.HairpinMode); err != nil {
                return err
        }