@@ -89,6 +89,10 @@ type UserDefinedNetworkGateway struct {
8989
9090 // gwInterfaceIndex holds the link index of gateway interface
9191 gwInterfaceIndex int
92+
93+ // save BGP state at the start of reconciliation loop run to handle it consistently throughout the run
94+ isNetworkAdvertisedToDefaultVRF bool
95+ isNetworkAdvertised bool
9296}
9397
9498// UTILS Needed for UDN (also leveraged for default netInfo) in bridgeConfiguration
@@ -366,18 +370,18 @@ func (udng *UserDefinedNetworkGateway) AddNetwork() error {
366370 return fmt .Errorf ("could not add VRF %s routes for network %s, err: %v" , vrfDeviceName , udng .GetNetworkName (), err )
367371 }
368372
369- isNetworkAdvertised := util . IsPodNetworkAdvertisedAtNode ( udng .NetInfo , udng . node . Name )
373+ udng .updateAdvertisementStatus ( )
370374
371375 // create the iprules for this network
372- if err = udng .updateUDNVRFIPRules (isNetworkAdvertised ); err != nil {
376+ if err = udng .updateUDNVRFIPRules (); err != nil {
373377 return fmt .Errorf ("failed to update IP rules for network %s: %w" , udng .GetNetworkName (), err )
374378 }
375379
376- if err = udng .updateAdvertisedUDNIsolationRules (isNetworkAdvertised ); err != nil {
380+ if err = udng .updateAdvertisedUDNIsolationRules (); err != nil {
377381 return fmt .Errorf ("failed to update isolation rules for network %s: %w" , udng .GetNetworkName (), err )
378382 }
379383
380- if err := udng .updateUDNVRFIPRoute (isNetworkAdvertised ); err != nil {
384+ if err := udng .updateUDNVRFIPRoute (); err != nil {
381385 return fmt .Errorf ("failed to update ip routes for network %s: %w" , udng .GetNetworkName (), err )
382386 }
383387
@@ -455,18 +459,16 @@ func (udng *UserDefinedNetworkGateway) DelNetwork() error {
455459 }
456460 }
457461
458- if util .IsPodNetworkAdvertisedAtNode (udng .NetInfo , udng .node .Name ) {
459- err := udng .updateAdvertisedUDNIsolationRules (false )
460- if err != nil {
461- return fmt .Errorf ("failed to remove advertised UDN isolation rules for network %s: %w" , udng .GetNetworkName (), err )
462- }
462+ err := udng .deleteAdvertisedUDNIsolationRules ()
463+ if err != nil {
464+ return fmt .Errorf ("failed to remove advertised UDN isolation rules for network %s: %w" , udng .GetNetworkName (), err )
463465 }
464466
465467 if err := udng .delMarkChain (); err != nil {
466468 return err
467469 }
468470 // delete the management port interface for this network
469- err : = udng .deleteUDNManagementPort ()
471+ err = udng .deleteUDNManagementPort ()
470472 if err != nil {
471473 return err
472474 }
@@ -622,8 +624,7 @@ func (udng *UserDefinedNetworkGateway) computeRoutesForUDN(mpLink netlink.Link)
622624
623625 // Route2: Add default route: default via 172.18.0.1 dev breth0 mtu 1400
624626 // necessary for UDN CNI and host-networked pods default traffic to go to node's gatewayIP
625- isNetworkAdvertised := util .IsPodNetworkAdvertisedAtNode (udng .NetInfo , udng .node .Name )
626- defaultRoute , err := udng .getDefaultRoute (isNetworkAdvertised )
627+ defaultRoute , err := udng .getDefaultRouteWithAdvertisedCheck ()
627628 if err != nil {
628629 return nil , fmt .Errorf ("unable to add default route for network %s, err: %v" , udng .GetNetworkName (), err )
629630 }
@@ -724,15 +725,7 @@ func (udng *UserDefinedNetworkGateway) computeRoutesForUDN(mpLink netlink.Link)
724725 return retVal , nil
725726}
726727
727- func (udng * UserDefinedNetworkGateway ) getDefaultRoute (isNetworkAdvertised bool ) ([]netlink.Route , error ) {
728- vrfs := udng .GetPodNetworkAdvertisedOnNodeVRFs (udng .node .Name )
729- // If the network is advertised on a non default VRF then we should only consider routes received from external BGP
730- // device and not send any traffic based on default route similar to one present in default VRF. This is more important
731- // for VRF-Lite usecase where we need traffic to leave from vlan device instead of default gateway interface.
732- if isNetworkAdvertised && ! slices .Contains (vrfs , types .DefaultNetworkName ) {
733- return nil , nil
734- }
735-
728+ func (udng * UserDefinedNetworkGateway ) getDefaultRoute () ([]netlink.Route , error ) {
736729 networkMTU := udng .NetInfo .MTU ()
737730 if networkMTU == 0 {
738731 networkMTU = config .Default .MTU
@@ -757,6 +750,16 @@ func (udng *UserDefinedNetworkGateway) getDefaultRoute(isNetworkAdvertised bool)
757750 return retVal , nil
758751}
759752
753+ func (udng * UserDefinedNetworkGateway ) getDefaultRouteWithAdvertisedCheck () ([]netlink.Route , error ) {
754+ // If the network is advertised on a non default VRF then we should only consider routes received from external BGP
755+ // device and not send any traffic based on default route similar to one present in default VRF. This is more important
756+ // for VRF-Lite usecase where we need traffic to leave from vlan device instead of default gateway interface.
757+ if udng .isNetworkAdvertised && ! udng .isNetworkAdvertisedToDefaultVRF {
758+ return nil , nil
759+ }
760+ return udng .getDefaultRoute ()
761+ }
762+
760763// getV4MasqueradeIP returns the V4 management port masqueradeIP for this network
761764func (udng * UserDefinedNetworkGateway ) getV4MasqueradeIP () (* net.IPNet , error ) {
762765 if ! config .IPv4Mode {
@@ -789,12 +792,15 @@ func (udng *UserDefinedNetworkGateway) getV6MasqueradeIP() (*net.IPNet, error) {
789792// 2000: from all to 169.254.0.12 lookup 1007
790793// 2000: from all fwmark 0x1002 lookup 1009
791794// 2000: from all to 169.254.0.14 lookup 1009
792- // If the network is advertised, an example of the rules we set for a network is:
795+ // If the network is advertised to the default VRF , an example of the rules we set for a network is:
793796// 2000: from all fwmark 0x1001 lookup 1007
794797// 2000: from all to 10.132.0.0/14 lookup 1007
795798// 2000: from all fwmark 0x1001 lookup 1009
796799// 2000: from all to 10.134.0.0/14 lookup 1009
797- func (udng * UserDefinedNetworkGateway ) constructUDNVRFIPRules (isNetworkAdvertised bool ) ([]netlink.Rule , []netlink.Rule , error ) {
800+ // If the network is advertised ot a non-default VRF, an example of the rules we set for a network is:
801+ // 2000: from all fwmark 0x1001 lookup 1007
802+ // 2000: from all fwmark 0x1001 lookup 1009
803+ func (udng * UserDefinedNetworkGateway ) constructUDNVRFIPRules () ([]netlink.Rule , []netlink.Rule , error ) {
798804 var addIPRules []netlink.Rule
799805 var delIPRules []netlink.Rule
800806 var masqIPRules []netlink.Rule
@@ -827,12 +833,18 @@ func (udng *UserDefinedNetworkGateway) constructUDNVRFIPRules(isNetworkAdvertise
827833 }
828834 }
829835 switch {
830- case ! isNetworkAdvertised :
831- addIPRules = append (addIPRules , masqIPRules ... )
832- delIPRules = append (delIPRules , subnetIPRules ... )
833- default :
836+ case udng .isNetworkAdvertisedToDefaultVRF :
837+ // the network is advertised to the default VRF
838+ delIPRules = append (delIPRules , masqIPRules ... )
834839 addIPRules = append (addIPRules , subnetIPRules ... )
840+ case udng .isNetworkAdvertised :
841+ // the network is advertised to a non-default VRF
835842 delIPRules = append (delIPRules , masqIPRules ... )
843+ delIPRules = append (delIPRules , subnetIPRules ... )
844+ default :
845+ // the network is not advertised
846+ delIPRules = append (delIPRules , subnetIPRules ... )
847+ addIPRules = append (addIPRules , masqIPRules ... )
836848 }
837849 return addIPRules , delIPRules , nil
838850}
@@ -928,19 +940,20 @@ func (udng *UserDefinedNetworkGateway) doReconcile() error {
928940 return fmt .Errorf ("openflow manager with default bridge configuration has not been provided for network %s" , udng .GetNetworkName ())
929941 }
930942
943+ udng .updateAdvertisementStatus ()
944+
931945 // update bridge configuration
932- isNetworkAdvertised := util .IsPodNetworkAdvertisedAtNode (udng .NetInfo , udng .node .Name )
933946 netConfig := udng .openflowManager .defaultBridge .getNetworkBridgeConfig (udng .GetNetworkName ())
934947 if netConfig == nil {
935948 return fmt .Errorf ("missing bridge configuration for network %s" , udng .GetNetworkName ())
936949 }
937- netConfig .advertised .Store (isNetworkAdvertised )
950+ netConfig .advertised .Store (udng . isNetworkAdvertised )
938951
939- if err := udng .updateUDNVRFIPRules (isNetworkAdvertised ); err != nil {
952+ if err := udng .updateUDNVRFIPRules (); err != nil {
940953 return fmt .Errorf ("error while updating ip rule for UDN %s: %s" , udng .GetNetworkName (), err )
941954 }
942955
943- if err := udng .updateUDNVRFIPRoute (isNetworkAdvertised ); err != nil {
956+ if err := udng .updateUDNVRFIPRoute (); err != nil {
944957 return fmt .Errorf ("error while updating ip route for UDN %s: %s" , udng .GetNetworkName (), err )
945958 }
946959
@@ -954,16 +967,16 @@ func (udng *UserDefinedNetworkGateway) doReconcile() error {
954967 // let's sync these flows immediately
955968 udng .openflowManager .requestFlowSync ()
956969
957- if err := udng .updateAdvertisedUDNIsolationRules (isNetworkAdvertised ); err != nil {
970+ if err := udng .updateAdvertisedUDNIsolationRules (); err != nil {
958971 return fmt .Errorf ("error while updating advertised UDN isolation rules for network %s: %w" , udng .GetNetworkName (), err )
959972 }
960973 return nil
961974}
962975
963976// updateUDNVRFIPRules updates IP rules for a network depending on whether the
964- // network is advertised or not
965- func (udng * UserDefinedNetworkGateway ) updateUDNVRFIPRules (isNetworkAdvertised bool ) error {
966- addIPRules , deleteIPRules , err := udng .constructUDNVRFIPRules (isNetworkAdvertised )
977+ // network is advertised to the default VRF or not
978+ func (udng * UserDefinedNetworkGateway ) updateUDNVRFIPRules () error {
979+ addIPRules , deleteIPRules , err := udng .constructUDNVRFIPRules ()
967980 if err != nil {
968981 return fmt .Errorf ("unable to get iprules for network %s, err: %v" , udng .GetNetworkName (), err )
969982 }
@@ -982,30 +995,40 @@ func (udng *UserDefinedNetworkGateway) updateUDNVRFIPRules(isNetworkAdvertised b
982995}
983996
984997// Add or remove default route from a vrf device based on the network is
985- // advertised on its own network or default network
986- func (udng * UserDefinedNetworkGateway ) updateUDNVRFIPRoute (isNetworkAdvertised bool ) error {
987- vrfs := udng .GetPodNetworkAdvertisedOnNodeVRFs (udng .node .Name )
988- if isNetworkAdvertised && ! slices .Contains (vrfs , types .DefaultNetworkName ) {
998+ // advertised on its own network or the default network
999+ func (udng * UserDefinedNetworkGateway ) updateUDNVRFIPRoute () error {
1000+ vrfName := util .GetNetworkVRFName (udng .NetInfo )
1001+
1002+ switch {
1003+ case udng .isNetworkAdvertised && ! udng .isNetworkAdvertisedToDefaultVRF :
1004+ // Remove default route for networks advertised to non-default VRF
9891005 if err := udng .removeDefaultRouteFromVRF (); err != nil {
990- return fmt .Errorf ("error while removing default route from VRF %s corresponding to network %s: %s " ,
991- util . GetNetworkVRFName ( udng . NetInfo ) , udng .GetNetworkName (), err )
1006+ return fmt .Errorf ("failed to remove default route from VRF %s for network %s: %v " ,
1007+ vrfName , udng .GetNetworkName (), err )
9921008 }
993- } else if ! isNetworkAdvertised || slices .Contains (vrfs , types .DefaultNetworkName ) {
994- defaultRoute , err := udng .getDefaultRoute (isNetworkAdvertised )
1009+
1010+ default :
1011+ // Add default route for networks that are either:
1012+ // - not advertised
1013+ // - advertised to default VRF
1014+ defaultRoute , err := udng .getDefaultRouteWithAdvertisedCheck ()
9951015 if err != nil {
996- return fmt .Errorf ("unable to get default route for network %s, err: %v" , udng .GetNetworkName (), err )
1016+ return fmt .Errorf ("failed to get default route for network %s: %v" ,
1017+ udng .GetNetworkName (), err )
9971018 }
998- if err = udng .vrfManager .AddVRFRoutes (util .GetNetworkVRFName (udng .NetInfo ), defaultRoute ); err != nil {
999- return fmt .Errorf ("error while adding default route to VRF %s corresponding to network %s, err: %v" ,
1000- util .GetNetworkVRFName (udng .NetInfo ), udng .GetNetworkName (), err )
1019+
1020+ if err = udng .vrfManager .AddVRFRoutes (vrfName , defaultRoute ); err != nil {
1021+ return fmt .Errorf ("failed to add default route to VRF %s for network %s: %v" ,
1022+ vrfName , udng .GetNetworkName (), err )
10011023 }
10021024 }
1025+
10031026 return nil
10041027}
10051028
10061029func (udng * UserDefinedNetworkGateway ) removeDefaultRouteFromVRF () error {
10071030 vrfDeviceName := util .GetNetworkVRFName (udng .NetInfo )
1008- defaultRoute , err := udng .getDefaultRoute (false )
1031+ defaultRoute , err := udng .getDefaultRoute ()
10091032 if err != nil {
10101033 return fmt .Errorf ("unable to get default route for network %s, err: %v" , udng .GetNetworkName (), err )
10111034 }
@@ -1034,39 +1057,22 @@ func (udng *UserDefinedNetworkGateway) removeDefaultRouteFromVRF() error {
10341057// comment "advertised UDNs V4 subnets"
10351058// elements = { 10.10.0.0/16 comment "cluster_udn_l3network" }
10361059// }
1037- func (udng * UserDefinedNetworkGateway ) updateAdvertisedUDNIsolationRules (isNetworkAdvertised bool ) error {
1060+ func (udng * UserDefinedNetworkGateway ) updateAdvertisedUDNIsolationRules () error {
1061+ switch {
1062+ case udng .isNetworkAdvertised :
1063+ return udng .addAdvertisedUDNIsolationRules ()
1064+ default :
1065+ return udng .deleteAdvertisedUDNIsolationRules ()
1066+ }
1067+ }
1068+
1069+ func (udng * UserDefinedNetworkGateway ) addAdvertisedUDNIsolationRules () error {
10381070 nft , err := nodenft .GetNFTablesHelper ()
10391071 if err != nil {
10401072 return fmt .Errorf ("failed to get nftables helper: %v" , err )
10411073 }
10421074 tx := nft .NewTransaction ()
10431075
1044- if ! isNetworkAdvertised {
1045- existingV4 , err := nft .ListElements (context .TODO (), "set" , nftablesAdvertisedUDNsSetV4 )
1046- if err != nil {
1047- if ! knftables .IsNotFound (err ) {
1048- return fmt .Errorf ("could not list existing items in %s set: %w" , nftablesAdvertisedUDNsSetV4 , err )
1049- }
1050- }
1051- existingV6 , err := nft .ListElements (context .TODO (), "set" , nftablesAdvertisedUDNsSetV6 )
1052- if err != nil {
1053- if ! knftables .IsNotFound (err ) {
1054- return fmt .Errorf ("could not list existing items in %s set: %w" , nftablesAdvertisedUDNsSetV6 , err )
1055- }
1056- }
1057-
1058- for _ , elem := range append (existingV4 , existingV6 ... ) {
1059- if elem .Comment != nil && * elem .Comment == udng .GetNetworkName () {
1060- tx .Delete (elem )
1061- }
1062- }
1063-
1064- if tx .NumOperations () == 0 {
1065- return nil
1066- }
1067- return nft .Run (context .TODO (), tx )
1068- }
1069-
10701076 for _ , udnNet := range udng .Subnets () {
10711077 set := nftablesAdvertisedUDNsSetV4
10721078 if utilnet .IsIPv6CIDR (udnNet .CIDR ) {
@@ -1085,3 +1091,41 @@ func (udng *UserDefinedNetworkGateway) updateAdvertisedUDNIsolationRules(isNetwo
10851091 }
10861092 return nft .Run (context .TODO (), tx )
10871093}
1094+
1095+ func (udng * UserDefinedNetworkGateway ) deleteAdvertisedUDNIsolationRules () error {
1096+ nft , err := nodenft .GetNFTablesHelper ()
1097+ if err != nil {
1098+ return fmt .Errorf ("failed to get nftables helper: %v" , err )
1099+ }
1100+ tx := nft .NewTransaction ()
1101+
1102+ existingV4 , err := nft .ListElements (context .TODO (), "set" , nftablesAdvertisedUDNsSetV4 )
1103+ if err != nil {
1104+ if ! knftables .IsNotFound (err ) {
1105+ return fmt .Errorf ("could not list existing items in %s set: %w" , nftablesAdvertisedUDNsSetV4 , err )
1106+ }
1107+ }
1108+ existingV6 , err := nft .ListElements (context .TODO (), "set" , nftablesAdvertisedUDNsSetV6 )
1109+ if err != nil {
1110+ if ! knftables .IsNotFound (err ) {
1111+ return fmt .Errorf ("could not list existing items in %s set: %w" , nftablesAdvertisedUDNsSetV6 , err )
1112+ }
1113+ }
1114+
1115+ for _ , elem := range append (existingV4 , existingV6 ... ) {
1116+ if elem .Comment != nil && * elem .Comment == udng .GetNetworkName () {
1117+ tx .Delete (elem )
1118+ }
1119+ }
1120+
1121+ if tx .NumOperations () == 0 {
1122+ return nil
1123+ }
1124+ return nft .Run (context .TODO (), tx )
1125+ }
1126+
1127+ func (udng * UserDefinedNetworkGateway ) updateAdvertisementStatus () {
1128+ vrfs := udng .GetPodNetworkAdvertisedOnNodeVRFs (udng .node .Name )
1129+ udng .isNetworkAdvertised = len (vrfs ) > 0
1130+ udng .isNetworkAdvertisedToDefaultVRF = slices .Contains (vrfs , types .DefaultNetworkName )
1131+ }
0 commit comments