func()

in plugins/vpc-branch-pat-eni/plugin/commands.go [521:624]


func (plugin *Plugin) createTapLink(
	bridgeName string,
	vethLinkName string,
	tapLinkName string,
	uid int,
	gid int) error {

	// Create the bridge link.
	la := netlink.NewLinkAttrs()
	la.Name = bridgeName
	la.MTU = vpc.JumboFrameMTU
	bridge := &netlink.Bridge{LinkAttrs: la}
	log.Infof("Creating tap bridge %+v.", bridge)
	err := netlink.LinkAdd(bridge)
	if err != nil {
		log.Errorf("Failed to create tap bridge %s: %v.", bridgeName, err)
		return err
	}

	// Set bridge link MTU.
	err = netlink.LinkSetMTU(bridge, vpc.JumboFrameMTU)
	if err != nil {
		log.Errorf("Failed to set tap bridge %s link MTU: %v.",
			bridgeName, err)
		return err
	}

	// Connect veth link to the bridge.
	la = netlink.NewLinkAttrs()
	la.Name = vethLinkName
	vethLink := &netlink.Dummy{LinkAttrs: la}
	err = netlink.LinkSetMaster(vethLink, bridge)
	if err != nil {
		log.Errorf("Failed to set veth link %s master to %s: %v.",
			vethLinkName, bridgeName, err)
		return err
	}

	// Create the tap link.
	la = netlink.NewLinkAttrs()
	la.Name = tapLinkName
	la.MasterIndex = bridge.Index
	la.MTU = vpc.JumboFrameMTU
	tapLink := &netlink.Tuntap{
		LinkAttrs: la,
		Mode:      netlink.TUNTAP_MODE_TAP,
		Flags:     netlink.TUNTAP_ONE_QUEUE | netlink.TUNTAP_VNET_HDR,
		Queues:    1,
	}

	log.Infof("Creating tap link %+v.", tapLink)
	err = netlink.LinkAdd(tapLink)
	if err != nil {
		log.Errorf("Failed to add tap link %s: %v.", tapLinkName, err)
		return err
	}

	// Set tap link MTU.
	err = netlink.LinkSetMTU(tapLink, vpc.JumboFrameMTU)
	if err != nil {
		log.Errorf("Failed to set tap link %s MTU: %v.", tapLinkName, err)
		return err
	}

	// Set tap link ownership.
	log.Infof("Setting tap link %s owner to uid %d and gid %d.", tapLinkName, uid, gid)
	fd := int(tapLink.Fds[0].Fd())
	err = unix.IoctlSetInt(fd, unix.TUNSETOWNER, uid)
	if err != nil {
		log.Errorf("Failed to set tap link %s uid: %v.", tapLinkName, err)
		return err
	}
	err = unix.IoctlSetInt(fd, unix.TUNSETGROUP, gid)
	if err != nil {
		log.Errorf("Failed to set tap link %s gid: %v.", tapLinkName, err)
		return err
	}

	// Set the bridge link operational state up
	log.Infof("Setting bridge link %s state up.", bridgeName)
	err = netlink.LinkSetUp(bridge)
	if err != nil {
		log.Errorf("Failed to set bridge link %s state: %v.", bridgeName, err)
		return err
	}

	// Set tap link operational state up.
	log.Infof("Setting tap link %s state up.", tapLinkName)
	err = netlink.LinkSetUp(tapLink)
	if err != nil {
		log.Errorf("Failed to set tap link %s state: %v.", tapLinkName, err)
		return err
	}

	// Set the veth peer link operational state up.
	log.Infof("Setting veth peer link %s state up.", vethLinkName)
	err = netlink.LinkSetUp(vethLink)
	if err != nil {
		log.Errorf("Failed to set veth peer %s link state: %v.", vethLinkName, err)
		return err
	}

	return nil
}