func SetHairpinMode(name string, enabled bool) error { iface, err := net.InterfaceByName(name) if err != nil { return err } return netlink.SetHairpinMode(iface, enabled) }
// attach a container network interface to an external network func (v *veth) attach(n *configs.Network) (err error) { bridge, err := net.InterfaceByName(n.Bridge) if err != nil { return err } host, err := net.InterfaceByName(n.HostInterfaceName) if err != nil { return err } if err := netlink.AddToBridge(host, bridge); err != nil { return err } if err := netlink.NetworkSetMTU(host, n.Mtu); err != nil { return err } if n.HairpinMode { if err := netlink.SetHairpinMode(host, true); err != nil { return err } } if err := netlink.NetworkLinkUp(host); err != nil { return err } return nil }
func (v *veth) create(n *network, nspid int) (err error) { tmpName, err := v.generateTempPeerName() if err != nil { return err } n.TempVethPeerName = tmpName defer func() { if err != nil { netlink.NetworkLinkDel(n.HostInterfaceName) netlink.NetworkLinkDel(n.TempVethPeerName) } }() if n.Bridge == "" { return fmt.Errorf("bridge is not specified") } bridge, err := net.InterfaceByName(n.Bridge) if err != nil { return err } if err := netlink.NetworkCreateVethPair(n.HostInterfaceName, n.TempVethPeerName, n.TxQueueLen); err != nil { return err } host, err := net.InterfaceByName(n.HostInterfaceName) if err != nil { return err } if err := netlink.AddToBridge(host, bridge); err != nil { return err } if err := netlink.NetworkSetMTU(host, n.Mtu); err != nil { return err } if n.HairpinMode { if err := netlink.SetHairpinMode(host, true); err != nil { return err } } if err := netlink.NetworkLinkUp(host); err != nil { return err } child, err := net.InterfaceByName(n.TempVethPeerName) if err != nil { return err } return netlink.NetworkSetNsPid(child, nspid) }