func()

in google_guest_agent/network/manager/dhclient_linux.go [180:235]


func (n *dhclient) SetupEthernetInterface(ctx context.Context, config *cfg.Sections, nics *Interfaces) error {
	dhcpCommand := config.NetworkInterfaces.DHCPCommand
	if dhcpCommand != "" {
		tokens := strings.Split(dhcpCommand, " ")
		return run.Quiet(ctx, tokens[0], tokens[1:]...)
	}

	// Get all interfaces separated by ipv4 and ipv6.
	googleInterfaces, googleIpv6Interfaces := interfaceListsIpv4Ipv6(nics.EthernetInterfaces)
	obtainIpv4Interfaces, obtainIpv6Interfaces, releaseIpv6Interfaces, err := partitionInterfaces(ctx, googleInterfaces, googleIpv6Interfaces)
	if err != nil {
		return fmt.Errorf("error partitioning interfaces: %v", err)
	}

	// Release IPv6 leases.
	for _, iface := range releaseIpv6Interfaces {
		if err := runDhclient(ctx, ipv6, iface, true); err != nil {
			logger.Errorf("failed to run dhclient: %+x", err)
		}
	}

	// Setup IPV4.
	for _, iface := range obtainIpv4Interfaces {
		if err := runDhclient(ctx, ipv4, iface, false); err != nil {
			logger.Errorf("failed to run dhclient: %+x", err)
		}
	}

	if len(obtainIpv6Interfaces) == 0 {
		return nil
	}

	// Wait for tentative IPs to resolve as part of SLAAC for primary network interface.
	tentative := []string{"-6", "-o", "a", "s", "dev", googleInterfaces[0], "scope", "link", "tentative"}
	for i := 0; i < 5; i++ {
		res := run.WithOutput(ctx, "ip", tentative...)
		if res.ExitCode == 0 && res.StdOut == "" {
			break
		}
		time.Sleep(1 * time.Second)
	}

	// Setup IPv6.
	for _, iface := range obtainIpv6Interfaces {
		// Set appropriate system values.
		val := fmt.Sprintf("net.ipv6.conf.%s.accept_ra_rt_info_max_plen=128", iface)
		if err := run.Quiet(ctx, "sysctl", val); err != nil {
			return err
		}

		if err := runDhclient(ctx, ipv6, iface, false); err != nil {
			logger.Errorf("failed to run dhclient: %+x", err)
		}
	}
	return nil
}