@@ -2,6 +2,7 @@ package reconciler
2
2
3
3
import (
4
4
"context"
5
+ "errors"
5
6
"fmt"
6
7
"net"
7
8
"sort"
@@ -65,6 +66,15 @@ func (r *reconcile) reconcileLayer3(l3vnis []networkv1alpha1.VRFRouteConfigurati
65
66
return allConfigs [i ].VNI < allConfigs [j ].VNI
66
67
})
67
68
69
+ // Create FRR configuration and reload it
70
+ err = r .configureFRR (allConfigs )
71
+ if err != nil {
72
+ if ! errors .Is (err , & frr.ConfigurationError {}) {
73
+ return err
74
+ }
75
+ r .Logger .Error (err , "failed to configure FRR" )
76
+ }
77
+
68
78
created , deletedVRF , err := r .reconcileL3Netlink (l3Configs )
69
79
if err != nil {
70
80
r .Logger .Error (err , "error reconciling Netlink" )
@@ -75,54 +85,40 @@ func (r *reconcile) reconcileLayer3(l3vnis []networkv1alpha1.VRFRouteConfigurati
75
85
if err != nil {
76
86
return err
77
87
}
78
- reloadTwice := deletedVRF || deletedTaas
79
88
80
- // We wait here for two seconds to let FRR settle after updating netlink devices
81
- time . Sleep ( defaultSleep )
82
-
83
- err = r .configureFRR ( allConfigs , reloadTwice )
84
- if err != nil {
85
- return err
89
+ // When a BGP VRF is deleted there is a leftover running configuration after reload
90
+ // A second reload fixes this.
91
+ if deletedVRF || deletedTaas {
92
+ if err : = r .reloadFRR (); err != nil {
93
+ return fmt . Errorf ( "failed to reload FRR: %w" , err )
94
+ }
86
95
}
87
96
88
- // Make sure that all created netlink VRFs are up after FRR reload
97
+ // We wait here for two seconds to let FRR settle after updating netlink devices
89
98
time .Sleep (defaultSleep )
99
+
90
100
for _ , info := range created {
91
101
if err := r .netlinkManager .UpL3 (info ); err != nil {
92
- r .Logger .Error (err , "error setting L3 to state UP" )
93
- return fmt .Errorf ("error setting L3 to state UP: %w" , err )
102
+ r .Logger .Error (err , "error setting L3 to state UP" , "interface" , info )
94
103
}
95
104
}
96
105
return nil
97
106
}
98
107
99
- func (r * reconcile ) configureFRR (vrfConfigs []frr.VRFConfiguration , reloadTwice bool ) error {
108
+ func (r * reconcile ) configureFRR (vrfConfigs []frr.VRFConfiguration ) error {
100
109
changed , err := r .frrManager .Configure (frr.Configuration {
101
110
VRFs : vrfConfigs ,
102
111
ASN : r .config .ServerASN ,
103
112
}, r .netlinkManager , r .config )
104
113
if err != nil {
105
- r .Logger .Error (err , "error updating FRR configuration" )
106
114
return fmt .Errorf ("error updating FRR configuration: %w" , err )
107
115
}
108
116
109
- if changed || r . dirtyFRRConfig {
117
+ if changed {
110
118
err := r .reloadFRR ()
111
119
if err != nil {
112
- r .dirtyFRRConfig = true
113
120
return err
114
121
}
115
-
116
- // When a BGP VRF is deleted there is a leftover running configuration after reload
117
- // A second reload fixes this.
118
- if reloadTwice {
119
- err := r .reloadFRR ()
120
- if err != nil {
121
- r .dirtyFRRConfig = true
122
- return err
123
- }
124
- }
125
- r .dirtyFRRConfig = false
126
122
}
127
123
return nil
128
124
}
@@ -249,20 +245,12 @@ func (r *reconcile) reconcileL3Netlink(vrfConfigs []frr.VRFConfiguration) ([]nl.
249
245
}
250
246
251
247
// Check for VRFs that are configured on the host but no longer in Kubernetes
252
- toDelete := []nl.VRFInformation {}
253
- for i := range existing {
254
- stillExists := false
255
- for j := range vrfConfigs {
256
- if vrfConfigs [j ].Name == existing [i ].Name && vrfConfigs [j ].VNI == existing [i ].VNI {
257
- stillExists = true
258
- existing [i ].MTU = vrfConfigs [j ].MTU
259
- break
260
- }
261
- }
262
- if ! stillExists || existing [i ].MarkForDelete {
263
- toDelete = append (toDelete , existing [i ])
264
- } else if err := r .reconcileExisting (existing [i ]); err != nil {
265
- r .Logger .Error (err , "error reconciling existing VRF" , "vrf" , existing [i ].Name , "vni" , strconv .Itoa (existing [i ].VNI ))
248
+ preexisting , toDelete := r .gatherInterfacesInfo (vrfConfigs , existing )
249
+
250
+ // Make sure that all previously configured L3 interfaces are up
251
+ for _ , info := range preexisting {
252
+ if err := r .netlinkManager .UpL3 (info ); err != nil {
253
+ r .Logger .Error (err , "failed to set L3 up" , "interface" , info .Name )
266
254
}
267
255
}
268
256
@@ -289,6 +277,30 @@ func (r *reconcile) reconcileL3Netlink(vrfConfigs []frr.VRFConfiguration) ([]nl.
289
277
return toCreate , len (toDelete ) > 0 , nil
290
278
}
291
279
280
+ func (r * reconcile ) gatherInterfacesInfo (vrfConfigs []frr.VRFConfiguration , existing []nl.VRFInformation ) (preexisting , toDelete []nl.VRFInformation ) {
281
+ // Check for VRFs that are configured on the host but no longer in Kubernetes
282
+ for i := range existing {
283
+ stillExists := false
284
+ for j := range vrfConfigs {
285
+ if vrfConfigs [j ].Name == existing [i ].Name && vrfConfigs [j ].VNI == existing [i ].VNI {
286
+ stillExists = true
287
+ existing [i ].MTU = vrfConfigs [j ].MTU
288
+ if ! existing [i ].MarkForDelete {
289
+ preexisting = append (preexisting , existing [i ])
290
+ }
291
+ break
292
+ }
293
+ }
294
+ if ! stillExists || existing [i ].MarkForDelete {
295
+ toDelete = append (toDelete , existing [i ])
296
+ } else if err := r .reconcileExisting (existing [i ]); err != nil {
297
+ r .Logger .Error (err , "error reconciling existing VRF" , "vrf" , existing [i ].Name , "vni" , strconv .Itoa (existing [i ].VNI ))
298
+ }
299
+ }
300
+
301
+ return preexisting , toDelete
302
+ }
303
+
292
304
func (r * reconcile ) reconcileTaasNetlink (vrfConfigs []frr.VRFConfiguration ) (bool , error ) {
293
305
existing , err := r .netlinkManager .ListTaas ()
294
306
if err != nil {
0 commit comments