From 0b5fc5d36ac7c52e38150934c1f91c03f12ee804 Mon Sep 17 00:00:00 2001 From: changluyi <47097611+changluyi@users.noreply.github.com> Date: Wed, 12 Apr 2023 13:04:05 +0800 Subject: [PATCH] broadcast free arp when pod is setup (#2638) * broadcase free arp when pod is setup --- pkg/daemon/ovs_linux.go | 6 ++++++ pkg/util/arp.go | 36 ++++++++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/pkg/daemon/ovs_linux.go b/pkg/daemon/ovs_linux.go index 910175ce5d7..37adfd74d06 100644 --- a/pkg/daemon/ovs_linux.go +++ b/pkg/daemon/ovs_linux.go @@ -843,6 +843,12 @@ func configureNic(link, ip string, macAddr net.HardwareAddr, mtu int, detectIPCo return fmt.Errorf("IP address %s has already been used by host with MAC %s", ip, mac) } } + if addr.IP.To4() != nil && !detectIPConflict { + // when detectIPConflict is true, free arp is already broadcast in the step of announcement + if err := util.AnnounceArpAddress(link, addr.IP.String(), macAddr, 1, 1*time.Second); err != nil { + klog.Warningf("failed to broadcast free arp with err %v ", err) + } + } klog.Infof("add ip address %s to %s", ip, link) if err = netlink.AddrAdd(nodeLink, &addr); err != nil { diff --git a/pkg/util/arp.go b/pkg/util/arp.go index 62d36c8a22d..18bfe4df872 100644 --- a/pkg/util/arp.go +++ b/pkg/util/arp.go @@ -199,17 +199,45 @@ func ArpDetectIPConflict(nic, ip string, mac net.HardwareAddr) (net.HardwareAddr // Announcement is identical to the ARP Probe described above, // except that now the sender and target IP addresses are both // set to the host's newly selected IPv4 address. - if pkt, err = arp.NewPacket(arp.OperationRequest, mac, tpa, tha, tpa); err != nil { + if err = AnnounceArpAddress(nic, ip, mac, announceNum, announceInterval); err != nil { return nil, err } + return nil, nil +} + +func AnnounceArpAddress(nic, ip string, mac net.HardwareAddr, announceNum int, announceInterval time.Duration) error { + klog.Infof("announce arp address nic %s , ip %s, with mac %v ", nic, ip, mac) + netInterface, err := net.InterfaceByName(nic) + if err != nil { + return err + } + + client, err := arp.Dial(netInterface) + if err != nil { + return err + } + defer client.Close() + + tpa, err := netip.ParseAddr(ip) + if err != nil { + klog.Errorf("failed to parse IP address %s: %v ", ip, err) + return err + } + tha := net.HardwareAddr{0, 0, 0, 0, 0, 0} + pkt, err := arp.NewPacket(arp.OperationRequest, mac, tpa, tha, tpa) + if err != nil { + return err + } + + dstMac := net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff} for i := 0; i < announceNum; i++ { c := time.NewTimer(announceInterval) if err = client.SetDeadline(time.Now().Add(announceInterval)); err != nil { - return nil, err + return err } if err = client.WriteTo(pkt, dstMac); err != nil { - return nil, err + return err } if i == announceNum-1 { // the last one, no need to wait @@ -219,5 +247,5 @@ func ArpDetectIPConflict(nic, ip string, mac net.HardwareAddr) (net.HardwareAddr } } - return nil, nil + return nil }