Skip to content

Commit

Permalink
add ovn0 ipv6 local link address when ipv6 mode (#4545)
Browse files Browse the repository at this point in the history
Signed-off-by: clyi <[email protected]>
  • Loading branch information
changluyi authored Sep 23, 2024
1 parent 1fe9e7c commit 55c9e06
Showing 1 changed file with 47 additions and 5 deletions.
52 changes: 47 additions & 5 deletions pkg/daemon/ovs_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,11 +259,11 @@ func configureContainerNic(nicName, ifName, ipAddr, gateway string, isDefaultRou
if err = configureAdditionalNic(ifName, ipAddr); err != nil {
return err
}
if err = configureNic(nicName, ipAddr, macAddr, mtu, detectIPConflict, false); err != nil {
if err = configureNic(nicName, ipAddr, macAddr, mtu, detectIPConflict, false, false); err != nil {
return err
}
} else {
if err = configureNic(ifName, ipAddr, macAddr, mtu, detectIPConflict, true); err != nil {
if err = configureNic(ifName, ipAddr, macAddr, mtu, detectIPConflict, true, false); err != nil {
return err
}
}
Expand Down Expand Up @@ -417,7 +417,7 @@ func configureNodeNic(portName, ip, gw, joinCIDR string, macAddr net.HardwareAdd
return errors.New(raw)
}

if err = configureNic(util.NodeNic, ip, macAddr, mtu, false, false); err != nil {
if err = configureNic(util.NodeNic, ip, macAddr, mtu, false, false, true); err != nil {
return err
}

Expand Down Expand Up @@ -598,7 +598,7 @@ func configureNodeGwNic(portName, ip, gw string, macAddr net.HardwareAddr, mtu i
klog.V(3).Infof("node external nic %q already in ns %s", util.NodeGwNic, util.NodeGwNsPath)
}
return ns.WithNetNSPath(gwNS.Path(), func(_ ns.NetNS) error {
if err = configureNic(util.NodeGwNic, ip, macAddr, mtu, true, false); err != nil {
if err = configureNic(util.NodeGwNic, ip, macAddr, mtu, true, false, false); err != nil {
klog.Errorf("failed to congigure node gw nic %s, %v", util.NodeGwNic, err)
return err
}
Expand Down Expand Up @@ -835,7 +835,30 @@ func configureMirrorLink(portName string, _ int) error {
return nil
}

func configureNic(link, ip string, macAddr net.HardwareAddr, mtu int, detectIPConflict, setUfoOff bool) error {
// Convert MAC address to EUI-64 and generate link-local IPv6 address
func macToLinkLocalIPv6(mac net.HardwareAddr) (net.IP, error) {
if len(mac) != 6 {
return nil, fmt.Errorf("invalid MAC address length")
}

// Create EUI-64 format
eui64 := make([]byte, 8)
copy(eui64[0:3], mac[0:3]) // Copy the first 3 bytes
eui64[3] = 0xff // Insert ff
eui64[4] = 0xfe // Insert fe
copy(eui64[5:], mac[3:]) // Copy the last 3 bytes

// Flip the 7th bit of the first byte
eui64[0] ^= 0x02

// Prepend the link-local prefix
linkLocalIPv6 := net.IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
copy(linkLocalIPv6[8:], eui64)

return linkLocalIPv6, nil
}

func configureNic(link, ip string, macAddr net.HardwareAddr, mtu int, detectIPConflict, setUfoOff, ipv6LinkLocalOn bool) error {
nodeLink, err := netlink.LinkByName(link)
if err != nil {
return fmt.Errorf("can not find nic %s: %v", link, err)
Expand Down Expand Up @@ -868,14 +891,32 @@ func configureNic(link, ip string, macAddr net.HardwareAddr, mtu int, detectIPCo
if err != nil {
return fmt.Errorf("can not get addr %s: %v", nodeLink, err)
}

isIPv6LinkLocalExist := false
for _, ipAddr := range ipAddrs {
if ipAddr.IP.IsLinkLocalUnicast() {
// skip 169.254.0.0/16 and fe80::/10
if util.CheckProtocol(ipAddr.IP.String()) == kubeovnv1.ProtocolIPv6 {
isIPv6LinkLocalExist = true
}
continue
}
ipDelMap[ipAddr.IPNet.String()] = ipAddr
}

if ipv6LinkLocalOn && !isIPv6LinkLocalExist {
linkLocal, err := macToLinkLocalIPv6(macAddr)
if err != nil {
return fmt.Errorf("failed to generate link-local address: %v", err)
}
ipAddMap[linkLocal.String()] = netlink.Addr{
IPNet: &net.IPNet{
IP: linkLocal,
Mask: net.CIDRMask(64, 128),
},
}
}

for _, ipStr := range strings.Split(ip, ",") {
// Do not reassign same address for link
if _, ok := ipDelMap[ipStr]; ok {
Expand All @@ -896,6 +937,7 @@ func configureNic(link, ip string, macAddr net.HardwareAddr, mtu int, detectIPCo
return fmt.Errorf("delete address %s: %v", addr, err)
}
}

for ip, addr := range ipAddMap {
if detectIPConflict && addr.IP.To4() != nil {
ip := addr.IP.String()
Expand Down

0 comments on commit 55c9e06

Please sign in to comment.