diff --git a/pkg/utils/packet.go b/pkg/utils/packet.go index e162e3be..b1e82f57 100644 --- a/pkg/utils/packet.go +++ b/pkg/utils/packet.go @@ -200,22 +200,34 @@ func AnnounceIPs(ifName string, ipConfigs []*current.IPConfig) error { } // For all the IP addresses assigned by IPAM, we will send either a GARP (IPv4) or Unsolicited NA (IPv6). - for _, ipc := range ipConfigs { - var err error - if IsIPv6(ipc.Address.IP) { - /* As per RFC 4861, sending unsolicited neighbor advertisements should be considered as a performance - * optimization. It does not reliably update caches in all nodes. The Neighbor Unreachability Detection - * algorithm is more reliable although it may take slightly longer to update. - */ - err = SendUnsolicitedNeighborAdvertisement(ipc.Address.IP, linkObj) - } else if IsIPv4(ipc.Address.IP) { - err = SendGratuitousArp(ipc.Address.IP, linkObj) - } else { - return fmt.Errorf("the IP %s on interface %q is neither IPv4 or IPv6", ipc.Address.IP.String(), ifName) - } + // + // Note that SendUnsolicitedNeighborAdvertisement() can wait for tentative + // IPv6 addresses. It is thus slower. We iterate over the addresses twice + // (i_af loop), and first announce IPv4 addresses. + for i_af := 0; i_af < 2; i_af++ { + for _, ipc := range ipConfigs { + var err error + if IsIPv6(ipc.Address.IP) { + /* As per RFC 4861, sending unsolicited neighbor advertisements should be considered as a performance + * optimization. It does not reliably update caches in all nodes. The Neighbor Unreachability Detection + * algorithm is more reliable although it may take slightly longer to update. + */ + if i_af == 0 { + continue + } + err = SendUnsolicitedNeighborAdvertisement(ipc.Address.IP, linkObj) + } else if IsIPv4(ipc.Address.IP) { + if i_af == 1 { + continue + } + err = SendGratuitousArp(ipc.Address.IP, linkObj) + } else { + return fmt.Errorf("the IP %s on interface %q is neither IPv4 or IPv6", ipc.Address.IP.String(), ifName) + } - if err != nil { - return fmt.Errorf("failed to send GARP/NA message for ip %s on interface %q: %v", ipc.Address.IP.String(), ifName, err) + if err != nil { + return fmt.Errorf("failed to send GARP/NA message for ip %s on interface %q: %v", ipc.Address.IP.String(), ifName, err) + } } } return nil