Skip to content

Commit

Permalink
Add EUI on IPv6 L2VNIs for IPv6 ND
Browse files Browse the repository at this point in the history
  • Loading branch information
chdxD1 committed Nov 15, 2024
1 parent c334ded commit bb2d255
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 17 deletions.
28 changes: 15 additions & 13 deletions pkg/nl/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func (n *Manager) createVRF(vrfName string, table int) (*netlink.Vrf, error) {
if err := n.toolkit.LinkAdd(&netlinkVrf); err != nil {
return nil, fmt.Errorf("error adding link: %w", err)
}
if err := n.disableEUIAutogeneration(vrfName); err != nil {
if err := n.setEUIAutogeneration(vrfName, false); err != nil {
return nil, err
}
if err := n.toolkit.LinkSetUp(&netlinkVrf); err != nil {
Expand All @@ -36,7 +36,7 @@ func (n *Manager) createVRF(vrfName string, table int) (*netlink.Vrf, error) {
return &netlinkVrf, nil
}

func (n *Manager) createBridge(bridgeName string, macAddress *net.HardwareAddr, masterIdx, mtu int, underlayRMAC bool) (*netlink.Bridge, error) {
func (n *Manager) createBridge(bridgeName string, macAddress *net.HardwareAddr, masterIdx, mtu int, underlayRMAC, assignEUI bool) (*netlink.Bridge, error) {
netlinkBridge := netlink.Bridge{
LinkAttrs: netlink.LinkAttrs{
Name: bridgeName,
Expand Down Expand Up @@ -64,7 +64,7 @@ func (n *Manager) createBridge(bridgeName string, macAddress *net.HardwareAddr,
if err := n.toolkit.LinkAdd(&netlinkBridge); err != nil {
return nil, fmt.Errorf("error adding link: %w", err)
}
if err := n.disableEUIAutogeneration(bridgeName); err != nil {
if err := n.setEUIAutogeneration(bridgeName, assignEUI); err != nil {
return nil, fmt.Errorf("error disabling EUI autogeneration: %w", err)
}

Expand Down Expand Up @@ -109,21 +109,25 @@ func (n *Manager) createVXLAN(vxlanName string, bridgeIdx, vni, mtu int, hairpin
return nil, fmt.Errorf("error setting link's hairpin mode: %w", err)
}
}
if err := n.disableEUIAutogeneration(vxlanName); err != nil {
if err := n.setEUIAutogeneration(vxlanName, false); err != nil {
return nil, err
}

return &netlinkVXLAN, nil
}

func (*Manager) disableEUIAutogeneration(intfName string) error {
func (*Manager) setEUIAutogeneration(intfName string, generateEUI bool) error {
fileName := fmt.Sprintf("%s/ipv6/conf/%s/addr_gen_mode", procSysNetPath, intfName)
file, err := os.OpenFile(fileName, os.O_WRONLY, 0)
if err != nil {
return fmt.Errorf("error opening file: %w", err)
}
defer file.Close()
if _, err := file.WriteString("1\n"); err != nil {
value := "1"
if generateEUI {
value = "0"
}
if _, err := fmt.Fprintf(file, "%s\n", value); err != nil {
return fmt.Errorf("error writing to file: %w", err)
}
return nil
Expand All @@ -142,13 +146,11 @@ func (n *Manager) createLink(vethName, peerName string, masterIdx, mtu int, gene
return nil, fmt.Errorf("error adding link: %w", err)
}

if !generateEUI {
if err := n.disableEUIAutogeneration(vethName); err != nil {
return nil, err
}
if err := n.disableEUIAutogeneration(peerName); err != nil {
return nil, err
}
if err := n.setEUIAutogeneration(vethName, generateEUI); err != nil {
return nil, err
}
if err := n.setEUIAutogeneration(peerName, generateEUI); err != nil {
return nil, err
}

return &netlinkVeth, nil
Expand Down
33 changes: 30 additions & 3 deletions pkg/nl/layer2.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func (n *Manager) CreateL2(info *Layer2Information) error {
}

func (n *Manager) setupBridge(info *Layer2Information, masterIdx int) (*netlink.Bridge, error) {
bridge, err := n.createBridge(fmt.Sprintf("%s%d", layer2Prefix, info.VlanID), info.AnycastMAC, masterIdx, info.MTU, false)
bridge, err := n.createBridge(fmt.Sprintf("%s%d", layer2Prefix, info.VlanID), info.AnycastMAC, masterIdx, info.MTU, false, len(info.AnycastGateways) > 0)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -247,7 +247,29 @@ func (n *Manager) reconcileIPAddresses(intf netlink.Link, current, desired []*ne
return nil
}

func (n *Manager) reconcileEUIAutogeneration(intfName string, intf netlink.Link, desired []*netlink.Addr) error {
enableEUI := len(desired) > 0
if err := n.setEUIAutogeneration(intfName, enableEUI); err != nil {
return fmt.Errorf("error setting EUI autogeneration: %w", err)
}
if !enableEUI {
addresses, err := n.toolkit.AddrList(intf, unix.AF_INET6)
if err != nil {
return fmt.Errorf("error listing link's IPv6 addresses: %w", err)
}
for i := range addresses {
if addresses[i].IP.IsLinkLocalUnicast() {
if err := n.toolkit.AddrDel(intf, &addresses[i]); err != nil {
return fmt.Errorf("error removing link local IPv6 address: %w", err)
}
}
}
}
return nil
}

func (n *Manager) ReconcileL2(current, desired *Layer2Information) error {
bridgeName := fmt.Sprintf("%s%d", layer2Prefix, current.VlanID)
if len(desired.AnycastGateways) > 0 && desired.AnycastMAC == nil {
return fmt.Errorf("anycastGateways require anycastMAC to be set")
}
Expand Down Expand Up @@ -282,7 +304,7 @@ func (n *Manager) ReconcileL2(current, desired *Layer2Information) error {
return err
}

if err := n.configureBridge(fmt.Sprintf("%s%d", layer2Prefix, current.VlanID)); err != nil {
if err := n.configureBridge(bridgeName); err != nil {
return err
}

Expand All @@ -291,7 +313,12 @@ func (n *Manager) ReconcileL2(current, desired *Layer2Information) error {
}

// Add/Remove anycast gateways
return n.reconcileIPAddresses(current.bridge, current.AnycastGateways, desired.AnycastGateways)
if err := n.reconcileIPAddresses(current.bridge, current.AnycastGateways, desired.AnycastGateways); err != nil {
return err
}

// Reconcile EUI Autogeneration
return n.reconcileEUIAutogeneration(bridgeName, current.bridge, desired.AnycastGateways)
}

func (n *Manager) setMTU(current, desired *Layer2Information) error {
Expand Down
2 changes: 1 addition & 1 deletion pkg/nl/layer3.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (n *Manager) CreateL3(info VRFInformation) error {
return err
}

bridge, err := n.createBridge(bridgePrefix+info.Name, nil, vrf.Attrs().Index, defaultMtu, true)
bridge, err := n.createBridge(bridgePrefix+info.Name, nil, vrf.Attrs().Index, defaultMtu, true, false)
if err != nil {
return err
}
Expand Down

0 comments on commit bb2d255

Please sign in to comment.