summaryrefslogtreecommitdiffhomepage
path: root/table/policy.go
diff options
context:
space:
mode:
Diffstat (limited to 'table/policy.go')
-rw-r--r--table/policy.go152
1 files changed, 139 insertions, 13 deletions
diff --git a/table/policy.go b/table/policy.go
index b3799e35..6e5a94b2 100644
--- a/table/policy.go
+++ b/table/policy.go
@@ -64,11 +64,23 @@ type PolicyDirection int
const (
POLICY_DIRECTION_NONE PolicyDirection = iota
+ POLICY_DIRECTION_IN
POLICY_DIRECTION_IMPORT
POLICY_DIRECTION_EXPORT
- POLICY_DIRECTION_IN
)
+func (d PolicyDirection) String() string {
+ switch d {
+ case POLICY_DIRECTION_IN:
+ return "in"
+ case POLICY_DIRECTION_IMPORT:
+ return "import"
+ case POLICY_DIRECTION_EXPORT:
+ return "export"
+ }
+ return fmt.Sprintf("unknown(%d)", d)
+}
+
type MatchOption int
const (
@@ -2597,10 +2609,115 @@ func NewPolicy(c config.PolicyDefinition, dmap DefinedSetMap) (*Policy, error) {
}, nil
}
+type Assignment struct {
+ inPolicies []*Policy
+ defaultInPolicy RouteType
+ importPolicies []*Policy
+ defaultImportPolicy RouteType
+ exportPolicies []*Policy
+ defaultExportPolicy RouteType
+}
+
type RoutingPolicy struct {
DefinedSetMap DefinedSetMap
PolicyMap map[string]*Policy
StatementMap map[string]*Statement
+ AssignmentMap map[string]*Assignment
+}
+
+func (r *RoutingPolicy) ApplyPolicy(id string, dir PolicyDirection, before *Path) *Path {
+ if before == nil {
+ return nil
+ }
+ if filtered := before.Filtered(id); filtered > POLICY_DIRECTION_NONE && filtered < dir {
+ return nil
+ }
+ result := ROUTE_TYPE_NONE
+ after := before
+ for _, p := range r.GetPolicy(id, dir) {
+ result, after = p.Apply(before)
+ if result != ROUTE_TYPE_NONE {
+ break
+ }
+ }
+ if result == ROUTE_TYPE_NONE {
+ result = r.GetDefaultPolicy(id, dir)
+ }
+ switch result {
+ case ROUTE_TYPE_ACCEPT:
+ return after
+ default:
+ return nil
+ }
+}
+
+func (r *RoutingPolicy) GetPolicy(id string, dir PolicyDirection) []*Policy {
+ a, ok := r.AssignmentMap[id]
+ if !ok {
+ return nil
+ }
+ switch dir {
+ case POLICY_DIRECTION_IN:
+ return a.inPolicies
+ case POLICY_DIRECTION_IMPORT:
+ return a.importPolicies
+ case POLICY_DIRECTION_EXPORT:
+ return a.exportPolicies
+ default:
+ return nil
+ }
+}
+
+func (r *RoutingPolicy) GetDefaultPolicy(id string, dir PolicyDirection) RouteType {
+ a, ok := r.AssignmentMap[id]
+ if !ok {
+ return ROUTE_TYPE_NONE
+ }
+ switch dir {
+ case POLICY_DIRECTION_IN:
+ return a.defaultInPolicy
+ case POLICY_DIRECTION_IMPORT:
+ return a.defaultImportPolicy
+ case POLICY_DIRECTION_EXPORT:
+ return a.defaultExportPolicy
+ default:
+ return ROUTE_TYPE_NONE
+ }
+
+}
+
+func (r *RoutingPolicy) SetPolicy(id string, dir PolicyDirection, policies []*Policy) error {
+ a, ok := r.AssignmentMap[id]
+ if !ok {
+ a = &Assignment{}
+ }
+ switch dir {
+ case POLICY_DIRECTION_IN:
+ a.inPolicies = policies
+ case POLICY_DIRECTION_IMPORT:
+ a.importPolicies = policies
+ case POLICY_DIRECTION_EXPORT:
+ a.exportPolicies = policies
+ }
+ r.AssignmentMap[id] = a
+ return nil
+}
+
+func (r *RoutingPolicy) SetDefaultPolicy(id string, dir PolicyDirection, typ RouteType) error {
+ a, ok := r.AssignmentMap[id]
+ if !ok {
+ a = &Assignment{}
+ }
+ switch dir {
+ case POLICY_DIRECTION_IN:
+ a.defaultInPolicy = typ
+ case POLICY_DIRECTION_IMPORT:
+ a.defaultImportPolicy = typ
+ case POLICY_DIRECTION_EXPORT:
+ a.defaultExportPolicy = typ
+ }
+ r.AssignmentMap[id] = a
+ return nil
}
func (r *RoutingPolicy) GetAssignmentFromConfig(dir PolicyDirection, a config.ApplyPolicy) ([]*Policy, RouteType, error) {
@@ -2660,14 +2777,14 @@ func (r *RoutingPolicy) StatementInUse(x *Statement) bool {
return false
}
-func NewRoutingPolicy(c config.RoutingPolicy) (*RoutingPolicy, error) {
+func (r *RoutingPolicy) Reload(c config.RoutingPolicy) error {
dmap := make(map[DefinedType]map[string]DefinedSet)
dmap[DEFINED_TYPE_PREFIX] = make(map[string]DefinedSet)
d := c.DefinedSets
for _, x := range d.PrefixSets.PrefixSetList {
y, err := NewPrefixSet(x)
if err != nil {
- return nil, err
+ return err
}
dmap[DEFINED_TYPE_PREFIX][y.Name()] = y
}
@@ -2675,7 +2792,7 @@ func NewRoutingPolicy(c config.RoutingPolicy) (*RoutingPolicy, error) {
for _, x := range d.NeighborSets.NeighborSetList {
y, err := NewNeighborSet(x)
if err != nil {
- return nil, err
+ return err
}
dmap[DEFINED_TYPE_NEIGHBOR][y.Name()] = y
}
@@ -2692,7 +2809,7 @@ func NewRoutingPolicy(c config.RoutingPolicy) (*RoutingPolicy, error) {
for _, x := range bd.AsPathSets.AsPathSetList {
y, err := NewAsPathSet(x)
if err != nil {
- return nil, err
+ return err
}
dmap[DEFINED_TYPE_AS_PATH][y.Name()] = y
}
@@ -2700,7 +2817,7 @@ func NewRoutingPolicy(c config.RoutingPolicy) (*RoutingPolicy, error) {
for _, x := range bd.CommunitySets.CommunitySetList {
y, err := NewCommunitySet(x)
if err != nil {
- return nil, err
+ return err
}
dmap[DEFINED_TYPE_COMMUNITY][y.Name()] = y
}
@@ -2708,7 +2825,7 @@ func NewRoutingPolicy(c config.RoutingPolicy) (*RoutingPolicy, error) {
for _, x := range bd.ExtCommunitySets.ExtCommunitySetList {
y, err := NewExtCommunitySet(x)
if err != nil {
- return nil, err
+ return err
}
dmap[DEFINED_TYPE_EXT_COMMUNITY][y.Name()] = y
}
@@ -2717,22 +2834,31 @@ func NewRoutingPolicy(c config.RoutingPolicy) (*RoutingPolicy, error) {
for _, x := range c.PolicyDefinitions.PolicyDefinitionList {
y, err := NewPolicy(x, dmap)
if err != nil {
- return nil, err
+ return err
}
pmap[y.Name()] = y
for _, s := range y.Statements {
_, ok := smap[s.Name]
if ok {
- return nil, fmt.Errorf("duplicated statement name. statement name must be unique.")
+ return fmt.Errorf("duplicated statement name. statement name must be unique.")
}
smap[s.Name] = s
}
}
+ r.DefinedSetMap = dmap
+ r.PolicyMap = pmap
+ r.StatementMap = smap
+ r.AssignmentMap = make(map[string]*Assignment)
+ return nil
+}
+
+func NewRoutingPolicy() *RoutingPolicy {
return &RoutingPolicy{
- DefinedSetMap: dmap,
- PolicyMap: pmap,
- StatementMap: smap,
- }, nil
+ DefinedSetMap: make(map[DefinedType]map[string]DefinedSet),
+ PolicyMap: make(map[string]*Policy),
+ StatementMap: make(map[string]*Statement),
+ AssignmentMap: make(map[string]*Assignment),
+ }
}
func CanImportToVrf(v *Vrf, path *Path) bool {