diff --git a/dist/images/start-ovs.sh b/dist/images/start-ovs.sh
index a8b660cc174eabdf949fc665e9d8f78fb8323870..0ca0b51ea96aed52f18cf9fdbc4d75d9a756b925 100755
--- a/dist/images/start-ovs.sh
+++ b/dist/images/start-ovs.sh
@@ -49,6 +49,5 @@ fi
 # Set remote ovn-sb for ovn-controller to connect to
 ovs-vsctl set open . external-ids:ovn-remote=tcp:${OVN_SB_SERVICE_HOST}:${OVN_SB_SERVICE_PORT}
 ovs-vsctl set open . external-ids:ovn-encap-type=geneve
-ovs-vsctl set open . external-ids:ovn-encap-ip=${POD_IP}
 
 tail -f /var/log/openvswitch/ovs-vswitchd.log
diff --git a/docs/install.md b/docs/install.md
index 380c8a8c40a1840a4e0a4720f4002966cbc66c87..f1a69c8f925824eaa8dc0c6b622bc6110fc717ef 100644
--- a/docs/install.md
+++ b/docs/install.md
@@ -50,6 +50,15 @@ For high-available ovn db, see [high available](high-available.md)
     --kubeconfig: Path to kubeconfig file with authorization and master location information. If not set use the inCluster token
 ```
 
+### Daemon Configuration
+
+```bash
+    --iface: The iface used to inter-host pod communication, default: the default route iface
+    --mtu: The MTU used by pod iface, default: iface MTU - 55
+    --service-cluster-ip-range: The kubernetes service cluster ip range, default: 10.96.0.0/12
+    --kubeconfig: Path to kubeconfig file with authorization and master location information. If not set use the inCluster token
+```
+
 ## To uninstall
 
 1. Remove Kubernetes resources:
diff --git a/pkg/daemon/config.go b/pkg/daemon/config.go
index 5bc038567f25e2e88cb3a7fada8b32d0779ffc7b..2d5c64ee2b7303b45203abf5b3c05fc4ab7f3959 100644
--- a/pkg/daemon/config.go
+++ b/pkg/daemon/config.go
@@ -1,13 +1,21 @@
 package daemon
 
 import (
+	"errors"
 	"flag"
 	"fmt"
 	"io/ioutil"
+	"net"
 	"os"
+	"os/exec"
+	"strings"
+	"syscall"
 
+	"github.com/alauda/kube-ovn/pkg/util"
 	"github.com/sirupsen/logrus"
 	"github.com/spf13/pflag"
+	"github.com/vishvananda/netlink"
+
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/rest"
 	"k8s.io/client-go/tools/clientcmd"
@@ -16,6 +24,8 @@ import (
 
 // Configuration is the daemon conf
 type Configuration struct {
+	Iface                 string
+	MTU                   int
 	BindSocket            string
 	OvsSocket             string
 	KubeConfigFile        string
@@ -29,11 +39,13 @@ type Configuration struct {
 // TODO: validate configuration
 func ParseFlags() (*Configuration, error) {
 	var (
+		argIface                 = pflag.String("iface", "", "The iface used to inter-host pod communication, default: the default route iface")
+		argMTU                   = pflag.Int("mtu", 0, "The MTU used by pod iface, default: iface MTU - 55")
 		argBindSocket            = pflag.String("bind-socket", "/var/run/cniserver.sock", "The socket daemon bind to.")
 		argOvsSocket             = pflag.String("ovs-socket", "", "The socket to local ovs-server")
 		argKubeConfigFile        = pflag.String("kubeconfig", "", "Path to kubeconfig file with authorization and master location information. If not set use the inCluster token.")
-		argServiceClusterIPRange = pflag.String("service-cluster-ip-range", "10.96.0.0/12", "The kubernetes service cluster ip range")
-		argPprofPort             = pflag.Int("pprof-port", 10665, "The port to get profiling data, default 10665")
+		argServiceClusterIPRange = pflag.String("service-cluster-ip-range", "10.96.0.0/12", "The kubernetes service cluster ip range, default: 10.96.0.0/12")
+		argPprofPort             = pflag.Int("pprof-port", 10665, "The port to get profiling data, default: 10665")
 	)
 
 	// mute log for ipset lib
@@ -64,6 +76,8 @@ func ParseFlags() (*Configuration, error) {
 	}
 
 	config := &Configuration{
+		Iface:                 *argIface,
+		MTU:                   *argMTU,
 		BindSocket:            *argBindSocket,
 		OvsSocket:             *argOvsSocket,
 		KubeConfigFile:        *argKubeConfigFile,
@@ -71,12 +85,39 @@ func ParseFlags() (*Configuration, error) {
 		NodeName:              nodeName,
 		ServiceClusterIPRange: *argServiceClusterIPRange,
 	}
-	err := config.initKubeClient()
+
+	if config.Iface == "" {
+		iface, err := getDefaultGatewayIface()
+		if err != nil {
+			return nil, err
+		} else {
+			config.Iface = iface
+		}
+	}
+	iface, err := net.InterfaceByName(config.Iface)
 	if err != nil {
 		return nil, err
 	}
-	klog.Infof("bind socket: %s", config.BindSocket)
-	klog.Infof("ovs socket at %s", config.OvsSocket)
+	if config.MTU == 0 {
+		config.MTU = iface.MTU - util.GeneveHeaderLength
+	}
+
+	addrs, err := iface.Addrs()
+	if err != nil {
+		return nil, fmt.Errorf("failed to get iface addr. %v", err)
+	}
+	if len(addrs) == 0 {
+		return nil, fmt.Errorf("iface %s has no ip address", config.Iface)
+	}
+	if err := setEncapIP(strings.Split(addrs[0].String(), "/")[0]); err != nil {
+		return nil, err
+	}
+
+	err = config.initKubeClient()
+	if err != nil {
+		return nil, err
+	}
+	klog.Infof("daemon config: %v", config)
 	return config, nil
 }
 
@@ -106,3 +147,34 @@ func (config *Configuration) initKubeClient() error {
 	config.KubeClient = kubeClient
 	return nil
 }
+
+func getDefaultGatewayIface() (string, error) {
+	routes, err := netlink.RouteList(nil, syscall.AF_INET)
+	if err != nil {
+		return "", err
+	}
+
+	for _, route := range routes {
+		if route.Dst == nil || route.Dst.String() == "0.0.0.0/0" {
+			if route.LinkIndex <= 0 {
+				return "", errors.New("found default route but could not determine interface")
+			}
+			iface, err := net.InterfaceByIndex(route.LinkIndex)
+			if err != nil {
+				return "", fmt.Errorf("failed to get iface %v", err)
+			}
+			return iface.Name, nil
+		}
+	}
+
+	return "", errors.New("unable to find default route")
+}
+
+func setEncapIP(ip string) error {
+	raw, err := exec.Command(
+		"ovs-vsctl", "set", "open", ".", fmt.Sprintf("external-ids:ovn-encap-ip=%s", ip)).CombinedOutput()
+	if err != nil {
+		return fmt.Errorf("failed to set ovn-encap-ip, %s", string(raw))
+	}
+	return nil
+}
diff --git a/pkg/daemon/init.go b/pkg/daemon/init.go
index 1527fe321670a1eaecd7f9a8dacfde56f8ef1682..71bb27c71bcb731309a8f340c3ab2d556e414ff3 100644
--- a/pkg/daemon/init.go
+++ b/pkg/daemon/init.go
@@ -33,5 +33,5 @@ func InitNodeGateway(config *Configuration) error {
 			break
 		}
 	}
-	return configureNodeNic(portName, ipAddr, macAddr, gw)
+	return configureNodeNic(portName, ipAddr, macAddr, gw, config.MTU)
 }
diff --git a/pkg/daemon/ovs.go b/pkg/daemon/ovs.go
index 18e28f98659ab708fcddeb7b6eb5c6ad9fa085b5..a1dfadb08101b937f596a3c4d0819cf854296328 100644
--- a/pkg/daemon/ovs.go
+++ b/pkg/daemon/ovs.go
@@ -18,7 +18,7 @@ func (csh cniServerHandler) configureNic(podName, podNamespace, netns, container
 	// NOTE: DO NOT use ovs internal type interface for container.
 	// Kubernetes will detect 'eth0' nic in pod, so the nic name in pod must be 'eth0'.
 	// When renaming internal interface to 'eth0', ovs will delete and recreate this interface.
-	veth := netlink.Veth{LinkAttrs: netlink.LinkAttrs{Name: hostNicName, MTU: 1400}, PeerName: containerNicName}
+	veth := netlink.Veth{LinkAttrs: netlink.LinkAttrs{Name: hostNicName, MTU: csh.Config.MTU}, PeerName: containerNicName}
 	defer func() {
 		// Remove veth link in case any error during creating pod network.
 		if err != nil {
@@ -164,7 +164,7 @@ func configureContainerNic(nicName, ipAddr, gateway string, macAddr net.Hardware
 	})
 }
 
-func configureNodeNic(portName, ip, mac, gw string) error {
+func configureNodeNic(portName, ip, mac, gw string, mtu int) error {
 	macAddr, err := net.ParseMAC(mac)
 	if err != nil {
 		return fmt.Errorf("failed to parse mac %s %v", macAddr, err)
@@ -199,7 +199,7 @@ func configureNodeNic(portName, ip, mac, gw string) error {
 		return fmt.Errorf("can not set mac address to node nic %v", err)
 	}
 
-	err = netlink.LinkSetMTU(nodeLink, 1400)
+	err = netlink.LinkSetMTU(nodeLink, mtu)
 	if err != nil {
 		return fmt.Errorf("can not set mtu %v", err)
 	}
diff --git a/pkg/util/const.go b/pkg/util/const.go
index 87df53c11436012a2a79365f2f0d76477b4117e4..76417f56f0d99aa49ec80a7ad5db7cd705a567d1 100644
--- a/pkg/util/const.go
+++ b/pkg/util/const.go
@@ -41,4 +41,7 @@ const (
 	GWCentralizedMode = "centralized"
 	GWNode            = "ovn.kubernetes.io/gateway_node"
 	GWNat             = "ovn.kubernetes.io/gateway_nat"
+
+	// Refer to http://www.openvswitch.org/support/dist-docs/ovn-architecture.7.html "Tunnel Encapsulations"
+	GeneveHeaderLength = 55
 )