@@ -135,56 +135,55 @@ func (c *Controller) handleAddOrUpdateVpcEgressGateway(key string) error {
135135 gw .Status .Workload .Nodes = nil
136136 nodeNexthopIPv4 := make (map [string ]string , int (gw .Spec .Replicas ))
137137 nodeNexthopIPv6 := make (map [string ]string , int (gw .Spec .Replicas ))
138- if ! util .DeploymentIsReady (deploy ) {
138+ ready := util .DeploymentIsReady (deploy )
139+ if ! ready {
139140 gw .Status .Ready = false
140141 msg := fmt .Sprintf ("Waiting for %s %s to be ready" , deploy .Kind , deploy .Name )
141142 gw .Status .Conditions .SetCondition (kubeovnv1 .Ready , corev1 .ConditionFalse , "Processing" , msg , gw .Generation )
142- } else {
143- // get the pods of the deployment to collect the pod IPs
144- podSelector , err := metav1 .LabelSelectorAsSelector (deploy .Spec .Selector )
145- if err != nil {
146- err = fmt .Errorf ("failed to get pod selector of deployment %s/%s: %w" , deploy .Namespace , deploy .Name , err )
147- klog .Error (err )
148- return err
149- }
143+ }
144+ // get the pods of the deployment to collect the pod IPs
145+ podSelector , err := metav1 .LabelSelectorAsSelector (deploy .Spec .Selector )
146+ if err != nil {
147+ err = fmt .Errorf ("failed to get pod selector of deployment %s/%s: %w" , deploy .Namespace , deploy .Name , err )
148+ klog .Error (err )
149+ return err
150+ }
151+
152+ pods , err := c .podsLister .Pods (deploy .Namespace ).List (podSelector )
153+ if err != nil {
154+ err = fmt .Errorf ("failed to list pods of deployment %s/%s: %w" , deploy .Namespace , deploy .Name , err )
155+ klog .Error (err )
156+ return err
157+ }
150158
151- pods , err := c .podsLister .Pods (deploy .Namespace ).List (podSelector )
159+ // update gateway status including the internal/external IPs and the nodes where the pods are running
160+ gw .Status .Workload .Nodes = make ([]string , 0 , len (pods ))
161+ for _ , pod := range pods {
162+ if len (pod .Status .PodIPs ) == 0 {
163+ continue
164+ }
165+ extIPs , err := util .PodAttachmentIPs (pod , attachmentNetworkName )
152166 if err != nil {
153- err = fmt .Errorf ("failed to list pods of deployment %s/%s: %w" , deploy .Namespace , deploy .Name , err )
154167 klog .Error (err )
155- return err
168+ continue
156169 }
157170
158- // update gateway status including the internal/external IPs and the nodes where the pods are running
159- gw .Status .Workload .Nodes = make ([]string , 0 , len (pods ))
160- for _ , pod := range pods {
161- gw .Status .Workload .Nodes = append (gw .Status .Workload .Nodes , pod .Spec .NodeName )
162- ips := util .PodIPs (* pod )
163- ipv4 , ipv6 := util .SplitIpsByProtocol (ips )
164- if len (ipv4 ) != 0 {
165- nodeNexthopIPv4 [pod .Spec .NodeName ] = ipv4 [0 ]
166- }
167- if len (ipv6 ) != 0 {
168- nodeNexthopIPv6 [pod .Spec .NodeName ] = ipv6 [0 ]
169- }
170- gw .Status .InternalIPs = append (gw .Status .InternalIPs , strings .Join (ips , "," ))
171- extIPs , err := util .PodAttachmentIPs (pod , attachmentNetworkName )
172- if err != nil {
173- klog .Error (err )
174- gw .Status .ExternalIPs = append (gw .Status .ExternalIPs , "<unknown>" )
175- continue
176- }
177- gw .Status .ExternalIPs = append (gw .Status .ExternalIPs , strings .Join (extIPs , "," ))
171+ ips := util .PodIPs (* pod )
172+ ipv4 , ipv6 := util .SplitIpsByProtocol (ips )
173+ if len (ipv4 ) != 0 {
174+ nodeNexthopIPv4 [pod .Spec .NodeName ] = ipv4 [0 ]
175+ }
176+ if len (ipv6 ) != 0 {
177+ nodeNexthopIPv6 [pod .Spec .NodeName ] = ipv6 [0 ]
178178 }
179+ gw .Status .InternalIPs = append (gw .Status .InternalIPs , strings .Join (ips , "," ))
180+ gw .Status .ExternalIPs = append (gw .Status .ExternalIPs , strings .Join (extIPs , "," ))
181+ gw .Status .Workload .Nodes = append (gw .Status .Workload .Nodes , pod .Spec .NodeName )
179182 }
180183 if gw , err = c .updateVpcEgressGatewayStatus (gw ); err != nil {
181184 klog .Error (err )
182185 return err
183186 }
184- if len (gw .Status .Workload .Nodes ) == 0 {
185- // the workload is not ready yet
186- return nil
187- }
188187
189188 // reconcile OVN routes
190189 if err = c .reconcileVpcEgressGatewayOVNRoutes (gw , 4 , vpc .Status .Router , vpc .Status .BFDPort .Name , bfdIPv4 , nodeNexthopIPv4 , ipv4Src ); err != nil {
@@ -196,11 +195,13 @@ func (c *Controller) handleAddOrUpdateVpcEgressGateway(key string) error {
196195 return err
197196 }
198197
199- gw .Status .Ready = true
200- gw .Status .Phase = kubeovnv1 .PhaseCompleted
201- gw .Status .Conditions .SetReady ("ReconcileSuccess" , gw .Generation )
202- if _ , err = c .updateVpcEgressGatewayStatus (gw ); err != nil {
203- return err
198+ if ready {
199+ gw .Status .Ready = true
200+ gw .Status .Phase = kubeovnv1 .PhaseCompleted
201+ gw .Status .Conditions .SetReady ("ReconcileSuccess" , gw .Generation )
202+ if _ , err = c .updateVpcEgressGatewayStatus (gw ); err != nil {
203+ return err
204+ }
204205 }
205206
206207 return nil
@@ -606,17 +607,14 @@ func (c *Controller) reconcileVpcEgressGatewayOVNRoutes(gw *kubeovnv1.VpcEgressG
606607
607608 // reconcile OVN BFD entries
608609 bfdIDs := set .New [string ]()
610+ staleBFDIDs := set .New [string ]()
609611 bfdDstIPs := set .New (slices .Collect (maps .Values (nextHops ))... )
610612 bfdMap := make (map [string ]string , bfdDstIPs .Len ())
611613 for _ , bfd := range bfdList {
612614 if bfdIP == "" || bfd .LogicalPort != lrpName || ! bfdDstIPs .Has (bfd .DstIP ) {
613- if err = c .OVNNbClient .DeleteBFD (bfd .UUID ); err != nil {
614- err = fmt .Errorf ("failed to delete bfd %s: %w" , bfd .UUID , err )
615- klog .Error (err )
616- return err
617- }
615+ staleBFDIDs .Insert (bfd .UUID )
618616 }
619- if bfdIP == "" || bfd .LogicalPort == lrpName && bfdDstIPs .Has (bfd .DstIP ) {
617+ if bfdIP == "" || ( bfd .LogicalPort == lrpName && bfdDstIPs .Has (bfd .DstIP ) ) {
620618 // TODO: update min_rx, min_tx and multiplier
621619 if bfdIP != "" {
622620 bfdIDs .Insert (bfd .UUID )
@@ -746,6 +744,47 @@ func (c *Controller) reconcileVpcEgressGatewayOVNRoutes(gw *kubeovnv1.VpcEgressG
746744 }
747745 }
748746
747+ if gw .Spec .BFD .Enabled {
748+ // drop traffic if no nexthop is available
749+ if policies , err = c .OVNNbClient .ListLogicalRouterPolicies (lrName , util .EgressGatewayDropPolicyPriority , externalIDs , false ); err != nil {
750+ klog .Error (err )
751+ return err
752+ }
753+ matches = set .New (
754+ fmt .Sprintf ("ip%d.src == $%s_ip%d" , af , pgName , af ),
755+ fmt .Sprintf ("ip%d.src == $%s" , af , asName ),
756+ )
757+ for _ , policy := range policies {
758+ if matches .Has (policy .Match ) {
759+ matches .Delete (policy .Match )
760+ continue
761+ }
762+ if err = c .OVNNbClient .DeleteLogicalRouterPolicyByUUID (lrName , policy .UUID ); err != nil {
763+ err = fmt .Errorf ("failed to delete ovn lr policy %q: %w" , policy .Match , err )
764+ klog .Error (err )
765+ return err
766+ }
767+ }
768+ for _ , match := range matches .UnsortedList () {
769+ if err = c .OVNNbClient .AddLogicalRouterPolicy (lrName , util .EgressGatewayDropPolicyPriority , match ,
770+ ovnnb .LogicalRouterPolicyActionDrop , nil , nil , externalIDs ); err != nil {
771+ klog .Error (err )
772+ return err
773+ }
774+ }
775+ } else if err = c .OVNNbClient .DeleteLogicalRouterPolicies (lrName , util .EgressGatewayDropPolicyPriority , externalIDs ); err != nil {
776+ klog .Error (err )
777+ return err
778+ }
779+
780+ for _ , bfdID := range staleBFDIDs .UnsortedList () {
781+ if err = c .OVNNbClient .DeleteBFD (bfdID ); err != nil {
782+ err = fmt .Errorf ("failed to delete bfd %s: %w" , bfdID , err )
783+ klog .Error (err )
784+ return err
785+ }
786+ }
787+
749788 return nil
750789}
751790
0 commit comments