diff --git a/pkg/controller/subnet.go b/pkg/controller/subnet.go index 80f60ecef45..0b967a7b512 100644 --- a/pkg/controller/subnet.go +++ b/pkg/controller/subnet.go @@ -1793,6 +1793,12 @@ func (c *Controller) reconcileOvnDefaultVpcRoute(subnet *kubeovnv1.Subnet) error } } } else { + // It's diffcult to update policy route when subnet cidr is changed, add check for cidr changed situation + if err := c.reconcilePolicyRouteForCidrChangedSubnet(subnet, true); err != nil { + klog.Error(err) + return err + } + if err := c.addCommonRoutesForSubnet(subnet); err != nil { klog.Error(err) return err @@ -1821,6 +1827,11 @@ func (c *Controller) reconcileOvnDefaultVpcRoute(subnet *kubeovnv1.Subnet) error return fmt.Errorf("failed to add ecmp policy route, no gateway node exists") } + if err := c.reconcilePolicyRouteForCidrChangedSubnet(subnet, false); err != nil { + klog.Error(err) + return err + } + if subnet.Spec.EnableEcmp { if err := c.reconcileEcmpCentralizedSubnetRouteInDefaultVpc(subnet); err != nil { klog.Error(err) @@ -2957,3 +2968,67 @@ func (c *Controller) clearOldU2OResource(subnet *kubeovnv1.Subnet) error { } return nil } + +func (c *Controller) reconcilePolicyRouteForCidrChangedSubnet(subnet *kubeovnv1.Subnet, isCommonRoute bool) error { + var match string + var priority int + + if isCommonRoute { + priority = util.SubnetRouterPolicyPriority + } else { + priority = util.GatewayRouterPolicyPriority + } + + policies, err := c.OVNNbClient.ListLogicalRouterPolicies(subnet.Spec.Vpc, priority, map[string]string{ + "vendor": util.CniTypeName, + "subnet": subnet.Name, + }, true) + if err != nil { + klog.Errorf("failed to list logical router policies: %v", err) + return err + } + if len(policies) == 0 { + return nil + } + + for _, policy := range policies { + policyProtocol := kubeovnv1.ProtocolIPv4 + if strings.Contains(policy.Match, "ip6") { + policyProtocol = kubeovnv1.ProtocolIPv6 + } + + for _, cidr := range strings.Split(subnet.Spec.CIDRBlock, ",") { + if cidr == "" { + continue + } + if policyProtocol != util.CheckProtocol(cidr) { + continue + } + + af := 4 + if util.CheckProtocol(cidr) == kubeovnv1.ProtocolIPv6 { + af = 6 + } + + if isCommonRoute { + match = fmt.Sprintf("ip%d.dst == %s", af, cidr) + } else { + if subnet.Spec.GatewayType == kubeovnv1.GWCentralizedType { + match = fmt.Sprintf("ip%d.src == %s", af, cidr) + } else { + // distributed subnet does not need process gateway route policy + continue + } + } + + if policy.Match != match { + klog.Infof("delete old policy route for subnet %s with match %s priority %d, new match %v", subnet.Name, policy.Match, policy.Priority, match) + if err = c.OVNNbClient.DeleteLogicalRouterPolicyByUUID(subnet.Spec.Vpc, policy.UUID); err != nil { + klog.Errorf("failed to delete policy route for subnet %s: %v", subnet.Name, err) + return err + } + } + } + } + return nil +}