Skip to content

Commit

Permalink
Merge pull request #132 from telekom/fix/reload-fixes
Browse files Browse the repository at this point in the history
Add Stable Sort for VRFs and split lines with multiple RTs into separate lines
  • Loading branch information
chdxD1 authored Jul 16, 2024
2 parents ae3762d + a06b5c6 commit 1ccefec
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 423 deletions.
29 changes: 29 additions & 0 deletions pkg/frr/configure.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@ import (
"bytes"
"fmt"
"os"
"regexp"

"github.com/telekom/das-schiff-network-operator/pkg/healthcheck"
"github.com/telekom/das-schiff-network-operator/pkg/nl"
)

var (
vrfAsnConfig = 4200065169

// Regular expressions for parsing route-target lines.
rtLinesRe = regexp.MustCompile(`(?m)^\s*route-target.*`)
rtPartsRe = regexp.MustCompile(`(?m)^(\s*route-target\s*(?:import|export)\s*)(.*)`)
rtRe = regexp.MustCompile(`(?m)(\S+)`)
)

type templateConfig struct {
Expand Down Expand Up @@ -43,6 +49,8 @@ func (m *Manager) Configure(in Configuration, nm *nl.Manager) (bool, error) {
return false, err
}

targetConfig = fixRouteTargetReload(targetConfig)

if !bytes.Equal(currentConfig, targetConfig) {
err = os.WriteFile(m.ConfigPath, targetConfig, frrPermissions)
if err != nil {
Expand Down Expand Up @@ -115,3 +123,24 @@ func renderSubtemplates(in Configuration, nlManager *nl.Manager) (*templateConfi
Hostname: hostname,
}, nil
}

// fixRouteTargetReload is a workaround for FRR's inability to reload route-targets if they are configured in a single line.
// This function splits such lines into multiple lines, each containing a single route-target.
func fixRouteTargetReload(config []byte) []byte {
return rtLinesRe.ReplaceAllFunc(config, func(s []byte) []byte {
parts := rtPartsRe.FindSubmatch(s)
if parts == nil {
return s
}
rtLine, targets := string(parts[1]), string(parts[2])
routeTargets := rtRe.FindAllString(targets, -1)
if len(routeTargets) <= 1 {
return s
}
lines := ""
for _, rt := range routeTargets {
lines += rtLine + rt + "\n"
}
return []byte(lines[:len(lines)-1])
})
}
22 changes: 20 additions & 2 deletions pkg/reconciler/layer3.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,10 @@ func (r *reconcile) reconcileLayer3(l3vnis []networkv1alpha1.VRFRouteConfigurati
l3Configs := []frr.VRFConfiguration{}
taasConfigs := []frr.VRFConfiguration{}
for key := range vrfConfigMap {
allConfigs = append(allConfigs, vrfConfigMap[key])
l3Configs = append(l3Configs, vrfConfigMap[key])
vrfConfig := vrfConfigMap[key]
stableSortVRFConfiguration(&vrfConfig)
allConfigs = append(allConfigs, vrfConfig)
l3Configs = append(l3Configs, vrfConfig)
}
for key := range vrfFromTaas {
allConfigs = append(allConfigs, vrfFromTaas[key])
Expand Down Expand Up @@ -418,3 +420,19 @@ func copyPrefixItemToFRRItem(n int, item networkv1alpha1.VrfRouteConfigurationPr
LE: item.LE,
}, nil
}

func stableSortVRFConfiguration(vrfConfig *frr.VRFConfiguration) {
// Sort all lists in VRFConfigurations that are fetched from Kubernetes and might be in random order
sort.SliceStable(vrfConfig.Export, func(i, j int) bool {
return vrfConfig.Export[i].Seq < vrfConfig.Export[j].Seq
})
sort.SliceStable(vrfConfig.Import, func(i, j int) bool {
return vrfConfig.Import[i].Seq < vrfConfig.Import[j].Seq
})
sort.SliceStable(vrfConfig.AggregateIPv4, func(i, j int) bool {
return vrfConfig.AggregateIPv4[i] < vrfConfig.AggregateIPv4[j]
})
sort.SliceStable(vrfConfig.AggregateIPv6, func(i, j int) bool {
return vrfConfig.AggregateIPv6[i] < vrfConfig.AggregateIPv6[j]
})
}
Loading

0 comments on commit 1ccefec

Please sign in to comment.