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
}