func setInterfaceIPv6(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error { if i.AddressIPv6() == nil { return nil } ipAddr := &netlink.Addr{IPNet: i.AddressIPv6(), Label: "", Flags: syscall.IFA_F_NODAD} return nlh.AddrAdd(iface, ipAddr) }
func setHairpinMode(nlh *netlink.Handle, link netlink.Link, enable bool) error { err := nlh.LinkSetHairpin(link, enable) if err != nil && err != syscall.EINVAL { // If error is not EINVAL something else went wrong, bail out right away return fmt.Errorf("unable to set hairpin mode on %s via netlink: %v", link.Attrs().Name, err) } // Hairpin mode successfully set up if err == nil { return nil } // The netlink method failed with EINVAL which is probably because of an older // kernel. Try one more time via the sysfs method. path := filepath.Join("/sys/class/net", link.Attrs().Name, "brport/hairpin_mode") var val []byte if enable { val = []byte{'1', '\n'} } else { val = []byte{'0', '\n'} } if err := ioutil.WriteFile(path, val, 0644); err != nil { return fmt.Errorf("unable to set hairpin mode on %s via sysfs: %v", link.Attrs().Name, err) } return nil }
func setInterfaceMaster(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error { if i.DstMaster() == "" { return nil } return nlh.LinkSetMaster(iface, &netlink.Bridge{ LinkAttrs: netlink.LinkAttrs{Name: i.DstMaster()}}) }
func setInterfaceIP(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error { if i.Address() == nil { return nil } ipAddr := &netlink.Addr{IPNet: i.Address(), Label: ""} return nlh.AddrAdd(iface, ipAddr) }
func setInterfaceLinkLocalIPs(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error { for _, llIP := range i.LinkLocalAddresses() { ipAddr := &netlink.Addr{IPNet: llIP} if err := nlh.AddrAdd(iface, ipAddr); err != nil { return err } } return nil }
func setInterfaceIPAliases(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error { for _, si := range i.IPAliases() { ipAddr := &netlink.Addr{IPNet: si} if err := nlh.AddrAdd(iface, ipAddr); err != nil { return err } } return nil }
func setInterfaceIP(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error { if i.Address() == nil { return nil } if err := checkRouteConflict(nlh, i.Address(), netlink.FAMILY_V4); err != nil { return err } ipAddr := &netlink.Addr{IPNet: i.Address(), Label: ""} return nlh.AddrAdd(iface, ipAddr) }
func setInterfaceIPv6(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error { if i.AddressIPv6() == nil { return nil } if err := checkRouteConflict(nlh, i.AddressIPv6(), netlink.FAMILY_V6); err != nil { return err } ipAddr := &netlink.Addr{IPNet: i.AddressIPv6(), Label: "", Flags: syscall.IFA_F_NODAD} return nlh.AddrAdd(iface, ipAddr) }
func setInterfaceRoutes(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error { for _, route := range i.Routes() { err := nlh.RouteAdd(&netlink.Route{ Scope: netlink.SCOPE_LINK, LinkIndex: iface.Attrs().Index, Dst: route, }) if err != nil { return err } } return nil }
func setInterfaceIPv6(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error { if i.AddressIPv6() == nil { return nil } if err := checkRouteConflict(nlh, i.AddressIPv6(), netlink.FAMILY_V6); err != nil { return err } if err := setIPv6(i.ns.path, i.DstName(), true); err != nil { return fmt.Errorf("failed to enable ipv6: %v", err) } ipAddr := &netlink.Addr{IPNet: i.AddressIPv6(), Label: "", Flags: syscall.IFA_F_NODAD} return nlh.AddrAdd(iface, ipAddr) }
func checkRouteConflict(nlh *netlink.Handle, address *net.IPNet, family int) error { routes, err := nlh.RouteList(nil, family) if err != nil { return err } for _, route := range routes { if route.Dst != nil { if route.Dst.Contains(address.IP) || address.Contains(route.Dst.IP) { return fmt.Errorf("cannot program address %v in sandbox interface because it conflicts with existing route %s", address, route) } } } return nil }
// newInterface creates a new bridge interface structure. It attempts to find // an already existing device identified by the configuration BridgeName field, // or the default bridge name when unspecified, but doesn't attempt to create // one when missing func newInterface(nlh *netlink.Handle, config *networkConfiguration) *bridgeInterface { var err error i := &bridgeInterface{nlh: nlh} // Initialize the bridge name to the default if unspecified. if config.BridgeName == "" { config.BridgeName = DefaultBridgeName } // Attempt to find an existing bridge named with the specified name. i.Link, err = nlh.LinkByName(config.BridgeName) if err != nil { logrus.Debugf("Did not find any interface with name %s: %v", config.BridgeName, err) } return i }
// newInterface creates a new bridge interface structure. It attempts to find // an already existing device identified by the configuration BridgeName field, // or the default bridge name when unspecified, but doesn't attempt to create // one when missing func newInterface(nlh *netlink.Handle, config *networkConfiguration) (*bridgeInterface, error) { var err error i := &bridgeInterface{nlh: nlh} // Initialize the bridge name to the default if unspecified. if config.BridgeName == "" { config.BridgeName = DefaultBridgeName } // Attempt to find an existing bridge named with the specified name. i.Link, err = nlh.LinkByName(config.BridgeName) if err != nil { logrus.Debugf("Did not find any interface with name %s: %v", config.BridgeName, err) } else if _, ok := i.Link.(*netlink.Bridge); !ok { return nil, fmt.Errorf("existing interface %s is not a bridge", i.Link.Attrs().Name) } return i, nil }
func addToBridge(nlh *netlink.Handle, ifaceName, bridgeName string) error { link, err := nlh.LinkByName(ifaceName) if err != nil { return fmt.Errorf("could not find interface %s: %v", ifaceName, err) } if err = nlh.LinkSetMaster(link, &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: bridgeName}}); err != nil { logrus.Debugf("Failed to add %s to bridge via netlink.Trying ioctl: %v", ifaceName, err) iface, err := net.InterfaceByName(ifaceName) if err != nil { return fmt.Errorf("could not find network interface %s: %v", ifaceName, err) } master, err := net.InterfaceByName(bridgeName) if err != nil { return fmt.Errorf("could not find bridge %s: %v", bridgeName, err) } return ioctlAddToBridge(iface, master) } return nil }
func newInfo(hnd *netlink.Handle, t *testing.T) (Sandbox, error) { veth := &netlink.Veth{ LinkAttrs: netlink.LinkAttrs{Name: vethName1, TxQLen: 0}, PeerName: vethName2} if err := hnd.LinkAdd(veth); err != nil { return nil, err } // Store the sandbox side pipe interface // This is needed for cleanup on DeleteEndpoint() intf1 := &nwIface{} intf1.srcName = vethName2 intf1.dstName = sboxIfaceName ip4, addr, err := net.ParseCIDR("192.168.1.100/24") if err != nil { return nil, err } intf1.address = addr intf1.address.IP = ip4 ip6, addrv6, err := net.ParseCIDR("2001:DB8::ABCD/48") if err != nil { return nil, err } intf1.addressIPv6 = addrv6 intf1.addressIPv6.IP = ip6 _, route, err := net.ParseCIDR("192.168.2.1/32") if err != nil { return nil, err } intf1.routes = []*net.IPNet{route} intf2 := &nwIface{} intf2.srcName = "testbridge" intf2.dstName = sboxIfaceName intf2.bridge = true veth = &netlink.Veth{ LinkAttrs: netlink.LinkAttrs{Name: vethName3, TxQLen: 0}, PeerName: vethName4} if err := hnd.LinkAdd(veth); err != nil { return nil, err } intf3 := &nwIface{} intf3.srcName = vethName4 intf3.dstName = sboxIfaceName intf3.master = "testbridge" info := &networkNamespace{iFaces: []*nwIface{intf1, intf2, intf3}} info.gw = net.ParseIP("192.168.1.1") // sinfo.GatewayIPv6 = net.ParseIP("2001:DB8::1") info.gwv6 = net.ParseIP("fe80::1") return info, nil }
func setInterfaceName(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error { return nlh.LinkSetName(iface, i.DstName()) }
func setInterfaceMAC(nlh *netlink.Handle, iface netlink.Link, i *nwIface) error { if i.MacAddress() == nil { return nil } return nlh.LinkSetHardwareAddr(iface, i.MacAddress()) }