-
Notifications
You must be signed in to change notification settings - Fork 349
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove stale LRSRs from default and network scopped cluster router #4679
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
package util | ||
|
||
import ( | ||
"fmt" | ||
"net" | ||
"testing" | ||
|
||
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/config" | ||
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/nbdb" | ||
libovsdbtest "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/testing/libovsdb" | ||
"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/types" | ||
) | ||
|
||
func TestCreateDefaultRouteToExternal(t *testing.T) { | ||
nodeName := "ovn-control-plane" | ||
_, cidr4, _ := net.ParseCIDR("10.128.0.0/14") | ||
config.Default.ClusterSubnets = []config.CIDRNetworkEntry{{cidr4, 24}} | ||
expectedStaticRoute := &nbdb.LogicalRouterStaticRoute{ | ||
Nexthop: "100.64.0.1", | ||
IPPrefix: "10.128.0.0/14", | ||
Policy: &nbdb.LogicalRouterStaticRoutePolicySrcIP, | ||
UUID: "route1-UUID", | ||
} | ||
unexpectedStaticRoute := &nbdb.LogicalRouterStaticRoute{ | ||
Nexthop: "100.66.0.1", | ||
IPPrefix: "10.128.0.0/14", | ||
Policy: &nbdb.LogicalRouterStaticRoutePolicySrcIP, | ||
UUID: "route2-UUID", | ||
} | ||
initialOVNClusterRouter := &nbdb.LogicalRouter{ | ||
UUID: types.OVNClusterRouter + "-UUID", | ||
Name: types.OVNClusterRouter, | ||
StaticRoutes: []string{"route2-UUID"}, | ||
} | ||
expectedOVNClusterRouter := &nbdb.LogicalRouter{ | ||
UUID: types.OVNClusterRouter + "-UUID", | ||
Name: types.OVNClusterRouter, | ||
StaticRoutes: []string{"route1-UUID"}, | ||
} | ||
expectedLogicalRouterPort := &nbdb.LogicalRouterPort{ | ||
Name: types.GWRouterToJoinSwitchPrefix + types.GWRouterPrefix + nodeName, | ||
UUID: types.GWRouterToJoinSwitchPrefix + types.GWRouterPrefix + nodeName + "-UUID", | ||
Networks: []string{"100.64.0.1/16"}, | ||
} | ||
GRName := "GR_" + nodeName | ||
expectedOVNGatewayRouter := &nbdb.LogicalRouter{ | ||
UUID: GRName + "-UUID", | ||
Name: GRName, | ||
Ports: []string{types.GWRouterToJoinSwitchPrefix + types.GWRouterPrefix + nodeName + "-UUID"}, | ||
} | ||
|
||
tests := []struct { | ||
desc string | ||
initialNbdb libovsdbtest.TestSetup | ||
expectedNbdb libovsdbtest.TestSetup | ||
}{ | ||
{ | ||
desc: "removes stale static route and creates new route with current gateway router logical port IP", | ||
initialNbdb: libovsdbtest.TestSetup{ | ||
NBData: []libovsdbtest.TestData{ | ||
unexpectedStaticRoute, | ||
initialOVNClusterRouter, | ||
expectedLogicalRouterPort, | ||
expectedOVNGatewayRouter, | ||
}, | ||
}, | ||
expectedNbdb: libovsdbtest.TestSetup{ | ||
NBData: []libovsdbtest.TestData{ | ||
expectedStaticRoute, | ||
expectedOVNClusterRouter, | ||
expectedLogicalRouterPort, | ||
expectedOVNGatewayRouter, | ||
}, | ||
}, | ||
}, | ||
} | ||
for i, tc := range tests { | ||
t.Run(fmt.Sprintf("%d:%s", i, tc.desc), func(t *testing.T) { | ||
nbClient, cleanup, err := libovsdbtest.NewNBTestHarness(tc.initialNbdb, nil) | ||
if err != nil { | ||
t.Fatal(fmt.Errorf("test: \"%s\" failed to create test harness: %v", tc.desc, err)) | ||
} | ||
t.Cleanup(cleanup.Cleanup) | ||
|
||
var e error | ||
if e = CreateDefaultRouteToExternal(nbClient, types.OVNClusterRouter, GRName); e != nil { | ||
t.Fatal(fmt.Errorf("failed to create pod to external catch-all reroute for gateway router %s, err: %v", GRName, e)) | ||
} | ||
matcher := libovsdbtest.HaveDataIgnoringUUIDs(tc.expectedNbdb.NBData) | ||
success, err := matcher.Match(nbClient) | ||
if !success { | ||
t.Fatal(fmt.Errorf("test: \"%s\" didn't match expected with actual, err: %v", tc.desc, matcher.FailureMessage(nbClient))) | ||
} | ||
if err != nil { | ||
t.Fatal(fmt.Errorf("test: \"%s\" encountered error: %v", tc.desc, err)) | ||
} | ||
}) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -515,7 +515,6 @@ func (gw *GatewayManager) GatewayInit( | |
// to the same gateway router | ||
// | ||
// This can be removed once https://bugzilla.redhat.com/show_bug.cgi?id=1891516 is fixed. | ||
// FIXME(trozet): if LRP IP is changed, we do not remove stale instances of these routes | ||
for _, gwLRPIP := range gwLRPIPs { | ||
lrsr := nbdb.LogicalRouterStaticRoute{ | ||
IPPrefix: gwLRPIP.String(), | ||
|
@@ -526,13 +525,23 @@ func (gw *GatewayManager) GatewayInit( | |
types.NetworkExternalID: gw.netInfo.GetNetworkName(), | ||
types.TopologyExternalID: gw.netInfo.TopologyType(), | ||
} | ||
if !config.OVNKubernetesFeature.EnableInterconnect { | ||
lrsr.ExternalIDs["nodeName"] = nodeName | ||
} | ||
} else if !config.OVNKubernetesFeature.EnableInterconnect { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was it intentional that you override all ExternalIDs in case of non-secondary networks?
|
||
lrsr.ExternalIDs = map[string]string{ | ||
"nodeName": nodeName, | ||
} | ||
} | ||
p := func(item *nbdb.LogicalRouterStaticRoute) bool { | ||
return item.IPPrefix == lrsr.IPPrefix && | ||
libovsdbops.PolicyEqualPredicate(lrsr.Policy, item.Policy) | ||
} | ||
|
||
if gw.clusterRouterName != "" { | ||
if err = gw.deleteStaleJoinSubnetRoutes(nodeName, gwLRPIP.String()); err != nil { | ||
klog.Errorf("Could not remove stale static route %v", err) | ||
} | ||
err := libovsdbops.CreateOrReplaceLogicalRouterStaticRouteWithPredicate(gw.nbClient, | ||
gw.clusterRouterName, &lrsr, p, &lrsr.Nexthop) | ||
if err != nil { | ||
|
@@ -575,7 +584,6 @@ func (gw *GatewayManager) GatewayInit( | |
// towards join switch. | ||
mgmtIfAddr := util.GetNodeManagementIfAddr(hostSubnet) | ||
gw.staticRouteCleanup([]net.IP{mgmtIfAddr.IP}) | ||
|
||
if err := libovsdbops.CreateOrReplaceLogicalRouterStaticRouteWithPredicate( | ||
gw.nbClient, | ||
gw.clusterRouterName, | ||
|
@@ -1093,6 +1101,38 @@ func (gw *GatewayManager) staticRouteCleanup(nextHops []net.IP) { | |
} | ||
} | ||
|
||
// deleteStaleJoinSubnetRoutes removes static routes referencing old join switch IP as either NextHop or IPPrefix. | ||
// It acts on following LRSRs: | ||
// 100.64.0.4 100.64.0.4 dst-ip | ||
func (gw *GatewayManager) deleteStaleJoinSubnetRoutes(nodeName, gwLRPIP string) error { | ||
p := func(lrsr *nbdb.LogicalRouterStaticRoute) bool { | ||
if lrsr.Nexthop != gwLRPIP && utilnet.IPFamilyOfString(lrsr.Nexthop) == utilnet.IPFamilyOfString(gwLRPIP) && | ||
lrsr.Nexthop == lrsr.IPPrefix { | ||
networkName, isSecondaryNetwork := lrsr.ExternalIDs[types.NetworkExternalID] | ||
if isSecondaryNetwork && networkName == gw.netInfo.GetNetworkName() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This nested if/elseif block could be simplified. |
||
if !config.OVNKubernetesFeature.EnableInterconnect && lrsr.ExternalIDs["nodeName"] == nodeName { | ||
return true | ||
} else if config.OVNKubernetesFeature.EnableInterconnect { | ||
return true | ||
} | ||
} else if !isSecondaryNetwork { | ||
if !config.OVNKubernetesFeature.EnableInterconnect && lrsr.ExternalIDs["nodeName"] == nodeName { | ||
return true | ||
} else if config.OVNKubernetesFeature.EnableInterconnect { | ||
return true | ||
} | ||
} | ||
} | ||
return false | ||
} | ||
|
||
err := libovsdbops.DeleteLogicalRouterStaticRoutesWithPredicate(gw.nbClient, gw.clusterRouterName, p) | ||
if err != nil && !errors.Is(err, libovsdbclient.ErrNotFound) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think that |
||
return fmt.Errorf("failed to delete static route from router %s: %v", gw.clusterRouterName, err) | ||
} | ||
return nil | ||
} | ||
|
||
// policyRouteCleanup cleans up all policies on cluster router that have a nextHop | ||
// in the provided list. | ||
// - if the LRP exists and has the len(nexthops) > 1: it removes | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding the test!!
Would you mind adding one for the first commit too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure