in google_guest_agent/addresses.go [276:437]
func (a *addressMgr) Set(ctx context.Context) error {
config := cfg.Get()
if runtime.GOOS == "windows" {
a.applyWSFCFilter(config)
}
// Guest Agent does not manage interfaces on Windows.
if runtime.GOOS != "windows" {
// Setup network interfaces.
err := network.SetupInterfaces(ctx, config, newMetadata)
if err != nil {
return fmt.Errorf("failed to setup network interfaces: %v", err)
}
}
if !config.NetworkInterfaces.IPForwarding {
return nil
}
logger.Debugf("Add routes for aliases, forwarded IP and target-instance IPs")
// Add routes for IP aliases, forwarded and target-instance IPs.
for _, ni := range newMetadata.Instance.NetworkInterfaces {
iface, err := network.GetInterfaceByMAC(ni.Mac)
if err != nil {
if !slices.Contains(badMAC, ni.Mac) {
logger.Errorf("Error getting interface: %s", err)
badMAC = append(badMAC, ni.Mac)
}
continue
}
wantIPs := ni.ForwardedIps
wantIPs = append(wantIPs, ni.ForwardedIpv6s...)
if config.IPForwarding.TargetInstanceIPs {
wantIPs = append(wantIPs, ni.TargetInstanceIps...)
}
// IP Aliases are not supported on windows.
if runtime.GOOS != "windows" && config.IPForwarding.IPAliases {
wantIPs = append(wantIPs, ni.IPAliases...)
}
var forwardedIPs []string
var configuredIPs []string
if runtime.GOOS == "windows" {
addrs, err := iface.Addrs()
if err != nil {
logger.Errorf("Error getting addresses for interface %s: %s", iface.Name, err)
}
for _, addr := range addrs {
configuredIPs = append(configuredIPs, strings.TrimSuffix(addr.String(), "/32"))
}
regFwdIPs, err := getForwardsFromRegistry(ni.Mac)
if err != nil {
logger.Errorf("Error getting forwards from registry: %s", err)
continue
}
for _, ip := range configuredIPs {
// Only add to `forwardedIPs` if it is recorded in the registry.
if slices.Contains(regFwdIPs, ip) {
forwardedIPs = append(forwardedIPs, ip)
}
}
} else {
forwardedIPs, err = getLocalRoutes(ctx, config, iface.Name)
if err != nil {
logger.Errorf("Error getting routes: %v", err)
continue
}
}
// Trims any '/32' suffix for consistency.
trimSuffix := func(entries []string) []string {
var res []string
for _, entry := range entries {
res = append(res, strings.TrimSuffix(entry, "/32"))
}
return res
}
forwardedIPs = trimSuffix(forwardedIPs)
wantIPs = trimSuffix(wantIPs)
toAdd, toRm := compareRoutes(forwardedIPs, wantIPs)
if len(toAdd) != 0 || len(toRm) != 0 {
var msg string
msg = fmt.Sprintf("Changing forwarded IPs for %s from %q to %q by", ni.Mac, forwardedIPs, wantIPs)
if len(toAdd) != 0 {
msg += fmt.Sprintf(" adding %q", toAdd)
}
if len(toRm) != 0 {
if len(toAdd) != 0 {
msg += " and"
}
msg += fmt.Sprintf(" removing %q", toRm)
}
logger.Infof(msg)
}
var registryEntries []string
for _, ip := range wantIPs {
// If the IP is not in toAdd, add to registry list and continue.
if !slices.Contains(toAdd, ip) {
registryEntries = append(registryEntries, ip)
continue
}
var err error
if runtime.GOOS == "windows" {
// Don't addAddress if this is already configured.
if !slices.Contains(configuredIPs, ip) {
// In case of forwardedIpv6 we get IPV6 CIDR and Parse IP will return nil.
netip := net.ParseIP(ip)
if netip != nil && !isIPv6(netip) {
// Retains existing behavior for ipv4 addresses.
err = addAddress(netip, net.IPv4Mask(255, 255, 255, 255), uint32(iface.Index))
} else {
err = addIpv6Address(ip, uint32(iface.Index))
}
}
} else {
err = addLocalRoute(ctx, config, ip, iface.Name)
}
if err == nil {
registryEntries = append(registryEntries, ip)
} else {
logger.Errorf("error adding route: %v", err)
}
}
for _, ip := range toRm {
var err error
if runtime.GOOS == "windows" {
if !slices.Contains(configuredIPs, ip) {
continue
}
netip := net.ParseIP(ip)
// In case of forwardedIpv6 we get IPV6 CIDR and Parse IP will return nil.
if netip != nil && !isIPv6(netip) {
// Retains existing behavior for ipv4 addresses.
err = removeAddress(netip, net.IPv4Mask(255, 255, 255, 255), uint32(iface.Index))
} else {
err = removeIpv6Address(ip, uint32(iface.Index))
}
} else {
err = removeLocalRoute(ctx, config, ip, iface.Name)
}
if err != nil {
logger.Errorf("error removing route: %v", err)
// Add IPs we fail to remove to registry to maintain accurate record.
registryEntries = append(registryEntries, ip)
}
}
if runtime.GOOS == "windows" {
if err := writeRegMultiString(addressKey, ni.Mac, registryEntries); err != nil {
logger.Errorf("error writing registry: %s", err)
}
}
}
logger.Infof("Completed adding/removing routes for aliases, forwarded IP and target-instance IPs")
return nil
}