Example #1
0
// setLinkOptions validates and sets link's various options passed in as LinkOptions.
func setLinkOptions(ifc *net.Interface, opts LinkOptions) error {
	macaddr, mtu, flags, ns := opts.MacAddr, opts.MTU, opts.Flags, opts.Ns

	// if MTU is passed in LinkOptions
	if mtu != 0 {
		if err := validMtu(mtu); err != nil {
			return err
		}

		if err := netlink.NetworkSetMTU(ifc, mtu); err != nil {
			return fmt.Errorf("Unable to set MTU: %s", err)
		}
	}

	// if MacAddress is passed in LinkOptions
	if macaddr != "" {
		if err := validMacAddress(macaddr); err != nil {
			return err
		}

		if err := netlink.NetworkSetMacAddress(ifc, macaddr); err != nil {
			return fmt.Errorf("Unable to set MAC Address: %s", err)
		}
	}

	// if ns is passed in LinkOptions
	if ns != 0 {
		if err := validNs(ns); err != nil {
			return err
		}

		if err := netlink.NetworkSetNsPid(ifc, ns); err != nil {
			return fmt.Errorf("Unable to set Network namespace: %s", err)
		}
	}

	// if flags is passed in LinkOptions
	if flags != 0 {
		if err := validFlags(flags); err != nil {
			return err
		}

		if ns != 0 && (ns != 1 || ns != os.Getpid()) {
			if (flags & syscall.IFF_UP) == syscall.IFF_UP {
				origNs, _ := NetNsHandle(os.Getpid())
				defer syscall.Close(int(origNs))
				defer system.Setns(origNs, syscall.CLONE_NEWNET)

				if err := SetNetNsToPid(ns); err != nil {
					return fmt.Errorf("Switching to %d network namespace failed: %s", ns, err)
				}

				if err := netlink.NetworkLinkUp(ifc); err != nil {
					return fmt.Errorf("Unable to bring %s interface UP: %s", ifc.Name, ns)
				}
			}
		} else {
			if err := netlink.NetworkLinkUp(ifc); err != nil {
				return fmt.Errorf("Could not bring up network link %s: %s", ifc.Name, err)
			}
		}
	}

	return nil
}
Example #2
0
// NewVlanLinkWithOptions creates vlan network link and sets some of its network parameters
// to values passed in as VlanOptions
//
// It is equivalent of running:
//		ip link add name ${vlan name} link ${master interface} address ${macaddress} type vlan id ${tag}
// NewVlanLinkWithOptions returns Vlaner which is initialized to a pointer of type VlanLink if the
// vlan link was created successfully on the Linux host. It accepts VlanOptions which allow you to set
// link's options. It returns error if the link could not be created.
func NewVlanLinkWithOptions(masterDev string, opts VlanOptions) (Vlaner, error) {
	id := opts.Id
	macaddr := opts.MacAddr

	if ok, err := NetInterfaceNameValid(masterDev); !ok {
		return nil, err
	}

	if _, err := net.InterfaceByName(masterDev); err != nil {
		return nil, fmt.Errorf("Master VLAN device %s does not exist on the host", masterDev)
	}

	vlanDev := opts.VlanDev
	if vlanDev != "" {
		if ok, err := NetInterfaceNameValid(vlanDev); !ok {
			return nil, err
		}

		if _, err := net.InterfaceByName(vlanDev); err == nil {
			return nil, fmt.Errorf("VLAN device %s already assigned on the host", vlanDev)
		}
	} else {
		return nil, fmt.Errorf("VLAN device name can not be empty!")
	}

	if id == 0 {
		return nil, fmt.Errorf("Incorrect VLAN tag specified: %d", id)
	}

	if err := netlink.NetworkLinkAddVlan(masterDev, vlanDev, id); err != nil {
		return nil, err
	}

	vlanIfc, err := net.InterfaceByName(vlanDev)
	if err != nil {
		return nil, fmt.Errorf("Could not find the new interface: %s", err)
	}

	if macaddr != "" {
		if _, err = net.ParseMAC(macaddr); err == nil {
			if err := netlink.NetworkSetMacAddress(vlanIfc, macaddr); err != nil {
				if errDel := DeleteLink(vlanIfc.Name); err != nil {
					return nil, fmt.Errorf("Incorrect options specified! Attempt to delete the link failed: %s",
						errDel)
				}
			}
		}
	}

	masterIfc, err := net.InterfaceByName(masterDev)
	if err != nil {
		return nil, fmt.Errorf("Could not find the new interface: %s", err)
	}

	return &VlanLink{
		Link: Link{
			ifc: vlanIfc,
		},
		masterIfc: masterIfc,
		id:        id,
	}, nil
}
Example #3
0
// SetLinkMacAddress sets link's MAC address.
// It is equivalent of running: ip link set dev ${interface name} address ${address}
func (l *Link) SetLinkMacAddress(macaddr string) error {
	return netlink.NetworkSetMacAddress(l.NetInterface(), macaddr)
}
Example #4
0
// NewMacVlanLinkWithOptions creates macvlan network link and sets som of its network parameters
// passed in as MacVlanOptions.
//
// It is equivalent of running:
// 		ip link add name ${macvlan name} link ${master interface} address ${macaddress} type macvlan mode ${mode}
// NewMacVlanLinkWithOptions returns MacVlaner which is initialized to a pointer of type MacVlanLink if the
// macvlan link was created successfully on the Linux host. It returns error if the macvlan link could not be created.
func NewMacVlanLinkWithOptions(masterDev string, opts MacVlanOptions) (MacVlaner, error) {
	macVlanDev := opts.MacVlanDev
	mode := opts.Mode
	macaddr := opts.MacAddr

	if ok, err := NetInterfaceNameValid(masterDev); !ok {
		return nil, err
	}

	if _, err := net.InterfaceByName(masterDev); err != nil {
		return nil, fmt.Errorf("Master MAC VLAN device %s does not exist on the host", masterDev)
	}

	if macVlanDev != "" {
		if ok, err := NetInterfaceNameValid(macVlanDev); !ok {
			return nil, err
		}

		if _, err := net.InterfaceByName(macVlanDev); err == nil {
			return nil, fmt.Errorf("MAC VLAN device %s already assigned on the host", macVlanDev)
		}
	} else {
		macVlanDev = makeNetInterfaceName("mc")
	}

	if mode != "" {
		if _, ok := MacVlanModes[mode]; !ok {
			return nil, fmt.Errorf("Unsupported MacVlan mode specified: %s", mode)
		}
	} else {
		mode = "bridge"
	}

	if err := netlink.NetworkLinkAddMacVlan(masterDev, macVlanDev, opts.Mode); err != nil {
		return nil, err
	}

	macVlanIfc, err := net.InterfaceByName(macVlanDev)
	if err != nil {
		return nil, fmt.Errorf("Could not find the new interface: %s", err)
	}

	if macaddr != "" {
		if _, err = net.ParseMAC(macaddr); err == nil {
			if err := netlink.NetworkSetMacAddress(macVlanIfc, macaddr); err != nil {
				if errDel := DeleteLink(macVlanIfc.Name); err != nil {
					return nil, fmt.Errorf("Incorrect options specified. Attempt to delete the link failed: %s",
						errDel)
				}
			}
		}
	}

	masterIfc, err := net.InterfaceByName(masterDev)
	if err != nil {
		return nil, fmt.Errorf("Could not find the new interface: %s", err)
	}

	return &MacVlanLink{
		Link: Link{
			ifc: macVlanIfc,
		},
		masterIfc: masterIfc,
		mode:      mode,
	}, nil
}