func()

in google_guest_agent/network/manager/dhclient_linux.go [238:325]


func (n *dhclient) SetupVlanInterface(ctx context.Context, config *cfg.Sections, nics *Interfaces) error {
	logger.Debugf("vlans: %+v", nics.VlanInterfaces)

	sysInterfaces, err := net.Interfaces()
	if err != nil {
		return fmt.Errorf("failed to list systems interfaces: %+v", err)
	}

	interfaceMap := map[string]net.Interface{}
	for _, curr := range sysInterfaces {
		interfaceMap[curr.Name] = curr
	}

	var keepMe []string

	for _, curr := range nics.VlanInterfaces {
		logger.Debugf("vlan(%d) parent interface: %s", curr.Vlan, curr.ParentInterfaceID)

		// For dhclient/native implementation we use a "gcp." prefix to the interface name
		// so we can determine it is a guest agent managed vlan interface.
		iface := fmt.Sprintf("gcp.%s.%d", curr.ParentInterfaceID, curr.Vlan)
		existingIface, found := interfaceMap[iface]

		// If the interface already exists and has the same configuration just keep it.
		if found && existingIface.HardwareAddr.String() == curr.Mac &&
			existingIface.MTU == curr.MTU {
			keepMe = append(keepMe, iface)
			continue
		}

		// Generic description of the interface.
		ifaceDesc := InterfaceConfig{iface, curr.ParentInterfaceID, curr.MTU, curr.Mac, curr.Vlan}

		// If the vlan interface exists but the configuration has changed we recreate it.
		if found {
			if err := deleteLinkCmd.RunQuiet(ctx, ifaceDesc); err != nil {
				return err
			}
		}

		if err := vlanIfaceCommonSet.RunQuiet(ctx, ifaceDesc); err != nil {
			return err
		}

		batches := make(map[any][]run.CommandSet)

		if curr.IP != "" {
			// ipv4 specific configurations.
			ipv4Config := IPConfig{
				InterfaceConfig: ifaceDesc,
				IPVersion:       ipv4,
				Address:         curr.IP,
				Gateway:         curr.Gateway,
			}
			batches[ipv4Config] = []run.CommandSet{ipAddressSet, commonRouteSet, ipv4RouteCommand}
		}

		for i, ipv6Address := range curr.IPv6 {
			// ipv6 specific configurations.
			ipv6Config := IPConfig{
				InterfaceConfig: ifaceDesc,
				IPVersion:       ipv6,
				Address:         ipv6Address,
				Gateway:         curr.GatewayIPv6,
			}
			batches[ipv6Config] = []run.CommandSet{ipAddressSet}
			if i == 0 {
				batches[ipv6Config] = append(batches[ipv6Config], commonRouteSet)
			}
		}

		for data, batch := range batches {
			for _, curr := range batch {
				if err := curr.RunQuiet(ctx, data); err != nil {
					return err
				}
			}
		}

		keepMe = append(keepMe, iface)
	}

	if err := n.removeVlanInterfaces(ctx, keepMe); err != nil {
		return fmt.Errorf("failed to remove uninstalled vlan interfaces: %+v", err)
	}

	return nil
}