diff --git a/internal/pkg/table/policy.go b/internal/pkg/table/policy.go index 5af89a514..589921315 100644 --- a/internal/pkg/table/policy.go +++ b/internal/pkg/table/policy.go @@ -4556,7 +4556,12 @@ func (r *RoutingPolicy) DeletePolicy(x *Policy, all, preserve bool, activeId []s err = y.Remove(x) } if err == nil && !preserve { - for _, st := range y.Statements { + statements := x.Statements + if all { + statements = y.Statements + } + + for _, st := range statements { if !r.statementInUse(st) { r.logger.Debug("delete unused statement", slog.String("Topic", "Policy"), diff --git a/internal/pkg/table/policy_test.go b/internal/pkg/table/policy_test.go index e6519a8de..c3b5e198e 100644 --- a/internal/pkg/table/policy_test.go +++ b/internal/pkg/table/policy_test.go @@ -50,6 +50,97 @@ func TestGetPolicy(t *testing.T) { assert.Equal(t, len(r.GetPolicy("unknown")), 0) } +func TestDeletePolicyPreserve(t *testing.T) { + r := NewRoutingPolicy(logger) + + statements := []*Statement{ + {Name: "st1"}, + {Name: "st2"}, + {Name: "st3"}, + {Name: "st4"}, + {Name: "st5"}, + } + + for _, st := range statements { + err := r.AddStatement(st) + require.NoError(t, err) + } + + policies := []*Policy{ + { + Name: "p1", + Statements: []*Statement{ + {Name: "st1"}, + {Name: "st2"}, + {Name: "st3"}, + }, + }, + { + Name: "p2", + Statements: []*Statement{ + {Name: "st2"}, + {Name: "st3"}, + }, + }, + { + Name: "p3", + Statements: []*Statement{ + {Name: "st4"}, + }, + }, + { + Name: "p4", + Statements: []*Statement{ + {Name: "st5"}, + }, + }, + } + + for _, p := range policies { + err := r.AddPolicy(p, true) + require.NoError(t, err) + } + + policy := &Policy{ + Name: "p1", + Statements: []*Statement{ + {Name: "st1"}, + {Name: "st2"}, + }, + } + err := r.DeletePolicy(policy, false, false, nil) + require.NoError(t, err) + + assert.Len(t, r.GetStatement("st1"), 0, "preserve=false") + assert.Len(t, r.GetStatement("st2"), 1, "p2 still uses st2") + + policy = &Policy{ + Name: "p2", + } + err = r.DeletePolicy(policy, true, false, nil) + require.NoError(t, err) + + assert.Len(t, r.GetStatement("st2"), 0, "preserve=false") + assert.Len(t, r.GetStatement("st3"), 1, "p1 still uses st3") + + policy = &Policy{ + Name: "p3", + Statements: []*Statement{{Name: "st4"}}, + } + err = r.DeletePolicy(policy, false, true, nil) + require.NoError(t, err) + + assert.Len(t, r.GetStatement("st4"), 1, "preserve=true") + + policy = &Policy{ + Name: "p4", + } + err = r.DeletePolicy(policy, true, true, nil) + require.NoError(t, err) + + assert.Len(t, r.GetStatement("st5"), 1, "preserve=true") +} + func TestPrefixCalcurateNoRange(t *testing.T) { // create path peer := &PeerInfo{AS: 65001, Address: netip.MustParseAddr("10.0.0.1")}