Skip to content

Commit

Permalink
Announce fir IPv4 addresses (GARP) before IPv6 NA
Browse files Browse the repository at this point in the history
To announce IPv6 addresses, SendUnsolicitedNeighborAdvertisement()
possibly needs to wait for tentative IPv6 addresses to become usable
(DAD). This can take more than a second.

Change the loop over all addresses, to iterate them twice, and on the
first run announce IPv4 addresses. IPv4 addresses  don't need to be
affected by this waiting.

Note that utils.AnnounceIPs() is called towards the end of whatever the
command invocation is doing. This reordering, ensures that we
potentially announce IPv4 addresses earlier.
  • Loading branch information
thom311 committed Jul 30, 2024
1 parent d6ec1df commit 2525cb5
Showing 1 changed file with 27 additions and 15 deletions.
42 changes: 27 additions & 15 deletions pkg/utils/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -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++ {

Check failure on line 207 in pkg/utils/packet.go

View workflow job for this annotation

GitHub Actions / Lint

var-naming: don't use underscores in Go names; var i_af should be iAf (revive)
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
Expand Down

0 comments on commit 2525cb5

Please sign in to comment.