summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--table/policy.go329
1 files changed, 329 insertions, 0 deletions
diff --git a/table/policy.go b/table/policy.go
index 696b28e0..51d5a0c7 100644
--- a/table/policy.go
+++ b/table/policy.go
@@ -177,6 +177,23 @@ func (p *Prefix) ToApiStruct() *api.Prefix {
}
}
+func NewPrefixFromApiStruct(a *api.Prefix) (*Prefix, error) {
+ addr, prefix, err := net.ParseCIDR(a.IpPrefix)
+ if err != nil {
+ return nil, err
+ }
+ rf := bgp.RF_IPv4_UC
+ if addr.To4() == nil {
+ rf = bgp.RF_IPv6_UC
+ }
+ return &Prefix{
+ Prefix: prefix,
+ AddressFamily: rf,
+ MasklengthRangeMin: uint8(a.MaskLengthMin),
+ MasklengthRangeMax: uint8(a.MaskLengthMax),
+ }, nil
+}
+
func NewPrefix(c config.Prefix) (*Prefix, error) {
addr, prefix, err := net.ParseCIDR(c.IpPrefix)
if err != nil {
@@ -241,6 +258,24 @@ func (s *PrefixSet) ToApiStruct() *api.PrefixSet {
}
}
+func NewPrefixSetFromApiStruct(a *api.PrefixSet) (*PrefixSet, error) {
+ if a.Name == "" {
+ return nil, fmt.Errorf("empty prefix set name")
+ }
+ list := make([]*Prefix, 0, len(a.List))
+ for _, x := range a.List {
+ y, err := NewPrefixFromApiStruct(x)
+ if err != nil {
+ return nil, err
+ }
+ list = append(list, y)
+ }
+ return &PrefixSet{
+ name: a.Name,
+ list: list,
+ }, nil
+}
+
func NewPrefixSet(c config.PrefixSet) (*PrefixSet, error) {
name := c.PrefixSetName
if name == "" {
@@ -287,6 +322,24 @@ func (s *NeighborSet) ToApiStruct() *api.MatchSet {
}
}
+func NewNeighborSetFromApiStruct(a *api.MatchSet) (*NeighborSet, error) {
+ if a.Name == "" {
+ return nil, fmt.Errorf("empty neighbor set name")
+ }
+ list := make([]net.IP, 0, len(a.List))
+ for _, x := range a.List {
+ addr := net.ParseIP(x)
+ if addr == nil {
+ return nil, fmt.Errorf("invalid ip address format: %s", x)
+ }
+ list = append(list, addr)
+ }
+ return &NeighborSet{
+ name: a.Name,
+ list: list,
+ }, nil
+}
+
func NewNeighborSet(c config.NeighborSet) (*NeighborSet, error) {
name := c.NeighborSetName
if name == "" {
@@ -333,6 +386,17 @@ func (s *AsPathSet) Type() DefinedType {
return DEFINED_TYPE_AS_PATH
}
+func NewAsPathSetFromApiStruct(a *api.MatchSet) (*AsPathSet, error) {
+ c := config.AsPathSet{
+ AsPathSetName: a.Name,
+ AsPathList: make([]config.AsPath, 0, len(a.List)),
+ }
+ for _, x := range a.List {
+ c.AsPathList = append(c.AsPathList, config.AsPath{x})
+ }
+ return NewAsPathSet(c)
+}
+
func NewAsPathSet(c config.AsPathSet) (*AsPathSet, error) {
name := c.AsPathSetName
if name == "" {
@@ -440,6 +504,17 @@ func parseExtCommunityRegexp(arg string) (bgp.ExtendedCommunityAttrSubType, *reg
return subtype, exp, err
}
+func NewCommunitySetFromApiStruct(a *api.MatchSet) (*CommunitySet, error) {
+ c := config.CommunitySet{
+ CommunitySetName: a.Name,
+ CommunityList: make([]config.Community, 0, len(a.List)),
+ }
+ for _, x := range a.List {
+ c.CommunityList = append(c.CommunityList, config.Community{x})
+ }
+ return NewCommunitySet(c)
+}
+
func NewCommunitySet(c config.CommunitySet) (*CommunitySet, error) {
name := c.CommunitySetName
if name == "" {
@@ -473,6 +548,17 @@ func (s *ExtCommunitySet) Type() DefinedType {
return DEFINED_TYPE_EXT_COMMUNITY
}
+func NewExtCommunitySetFromApiStruct(a *api.MatchSet) (*ExtCommunitySet, error) {
+ c := config.ExtCommunitySet{
+ ExtCommunitySetName: a.Name,
+ ExtCommunityList: make([]config.ExtCommunity, 0, len(a.List)),
+ }
+ for _, x := range a.List {
+ c.ExtCommunityList = append(c.ExtCommunityList, config.ExtCommunity{x})
+ }
+ return NewExtCommunitySet(c)
+}
+
func NewExtCommunitySet(c config.ExtCommunitySet) (*ExtCommunitySet, error) {
name := c.ExtCommunitySetName
if name == "" {
@@ -554,6 +640,17 @@ func (c *PrefixCondition) ToApiStruct() *api.PrefixSet {
return s
}
+func NewPrefixConditionFromApiStruct(a *api.PrefixSet) (*PrefixCondition, error) {
+ s, err := NewPrefixSetFromApiStruct(a)
+ if err != nil {
+ return nil, err
+ }
+ return &PrefixCondition{
+ set: s,
+ option: MatchOption(a.Option),
+ }, nil
+}
+
func NewPrefixCondition(c config.MatchPrefixSet, m map[string]DefinedSet) (*PrefixCondition, error) {
if c.PrefixSet == "" {
return nil, nil
@@ -630,6 +727,17 @@ func (c *NeighborCondition) ToApiStruct() *api.MatchSet {
return s
}
+func NewNeighborConditionFromApiStruct(a *api.MatchSet) (*NeighborCondition, error) {
+ s, err := NewNeighborSetFromApiStruct(a)
+ if err != nil {
+ return nil, err
+ }
+ return &NeighborCondition{
+ set: s,
+ option: MatchOption(a.Option),
+ }, nil
+}
+
func NewNeighborCondition(c config.MatchNeighborSet, m map[string]DefinedSet) (*NeighborCondition, error) {
if c.NeighborSet == "" {
return nil, nil
@@ -698,6 +806,17 @@ func (c *AsPathCondition) Evaluate(path *Path) bool {
return result
}
+func NewAsPathConditionFromApiStruct(a *api.MatchSet) (*AsPathCondition, error) {
+ s, err := NewAsPathSetFromApiStruct(a)
+ if err != nil {
+ return nil, err
+ }
+ return &AsPathCondition{
+ set: s,
+ option: MatchOption(a.Option),
+ }, nil
+}
+
func NewAsPathCondition(c config.MatchAsPathSet, m map[string]DefinedSet) (*AsPathCondition, error) {
if c.AsPathSet == "" {
return nil, nil
@@ -769,6 +888,17 @@ func (c *CommunityCondition) Evaluate(path *Path) bool {
return result
}
+func NewCommunityConditionFromApiStruct(a *api.MatchSet) (*CommunityCondition, error) {
+ s, err := NewCommunitySetFromApiStruct(a)
+ if err != nil {
+ return nil, err
+ }
+ return &CommunityCondition{
+ set: s,
+ option: MatchOption(a.Option),
+ }, nil
+}
+
func NewCommunityCondition(c config.MatchCommunitySet, m map[string]DefinedSet) (*CommunityCondition, error) {
if c.CommunitySet == "" {
return nil, nil
@@ -846,6 +976,17 @@ func (c *ExtCommunityCondition) Evaluate(path *Path) bool {
return result
}
+func NewExtCommunityConditionFromApiStruct(a *api.MatchSet) (*ExtCommunityCondition, error) {
+ s, err := NewExtCommunitySetFromApiStruct(a)
+ if err != nil {
+ return nil, err
+ }
+ return &ExtCommunityCondition{
+ set: s,
+ option: MatchOption(a.Option),
+ }, nil
+}
+
func NewExtCommunityCondition(c config.MatchExtCommunitySet, m map[string]DefinedSet) (*ExtCommunityCondition, error) {
if c.ExtCommunitySet == "" {
return nil, nil
@@ -905,6 +1046,13 @@ func (c *AsPathLengthCondition) ToApiStruct() *api.AsPathLength {
}
}
+func NewAsPathLengthConditionFromApiStruct(a *api.AsPathLength) (*AsPathLengthCondition, error) {
+ return &AsPathLengthCondition{
+ length: a.Length,
+ operator: AttributeComparison(a.Type),
+ }, nil
+}
+
func NewAsPathLengthCondition(c config.AsPathLength) (*AsPathLengthCondition, error) {
if c.Value == 0 && c.Operator == "" {
return nil, nil
@@ -934,6 +1082,11 @@ func (c *RpkiValidationCondition) Evaluate(path *Path) bool {
return c.result == path.Validation
}
+func NewRpkiValidationConditionFromApiStruct(a int32) (*RpkiValidationCondition, error) {
+ typ := config.RpkiValidationResultType(a)
+ return NewRpkiValidationCondition(typ)
+}
+
func NewRpkiValidationCondition(c config.RpkiValidationResultType) (*RpkiValidationCondition, error) {
if c == config.RPKI_VALIDATION_RESULT_TYPE_NONE {
return nil, nil
@@ -966,6 +1119,19 @@ func (a *RoutingAction) ToApiStruct() api.RouteAction {
}
}
+func NewRoutingActionFromApiStruct(a api.RouteAction) (*RoutingAction, error) {
+ if a == api.RouteAction_NONE {
+ return nil, nil
+ }
+ accept := false
+ if a == api.RouteAction_ACCEPT {
+ accept = true
+ }
+ return &RoutingAction{
+ AcceptRoute: accept,
+ }, nil
+}
+
func NewRoutingAction(c config.RouteDisposition) (*RoutingAction, error) {
if c.AcceptRoute == c.RejectRoute && c.AcceptRoute {
return nil, fmt.Errorf("invalid route disposition")
@@ -1060,6 +1226,37 @@ func (a *CommunityAction) ToApiStruct() *api.CommunityAction {
}
}
+func NewCommunityActionFromApiStruct(a *api.CommunityAction) (*CommunityAction, error) {
+ var list []uint32
+ var removeList []*regexp.Regexp
+ op := config.BgpSetCommunityOptionType(a.Option)
+ if op == config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE {
+ removeList = make([]*regexp.Regexp, 0, len(a.Communities))
+ } else {
+ list = make([]uint32, 0, len(a.Communities))
+ }
+ for _, x := range a.Communities {
+ if op == config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE {
+ exp, err := parseCommunityRegexp(x)
+ if err != nil {
+ return nil, err
+ }
+ removeList = append(removeList, exp)
+ } else {
+ comm, err := ParseCommunity(x)
+ if err != nil {
+ return nil, err
+ }
+ list = append(list, comm)
+ }
+ }
+ return &CommunityAction{
+ action: op,
+ list: list,
+ removeList: removeList,
+ }, nil
+}
+
func NewCommunityAction(c config.SetCommunity) (*CommunityAction, error) {
a, ok := CommunityOptionValueMap[strings.ToLower(c.Options)]
if !ok {
@@ -1140,6 +1337,42 @@ func (a *ExtCommunityAction) ToApiStruct() *api.CommunityAction {
}
}
+func NewExtCommunityActionFromApiStruct(a *api.CommunityAction) (*ExtCommunityAction, error) {
+ var list []bgp.ExtendedCommunityInterface
+ var removeList []*regexp.Regexp
+ subtypeList := make([]bgp.ExtendedCommunityAttrSubType, 0, len(a.Communities))
+ op := config.BgpSetCommunityOptionType(a.Option)
+ if op == config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE {
+ removeList = make([]*regexp.Regexp, 0, len(a.Communities))
+ } else {
+ list = make([]bgp.ExtendedCommunityInterface, 0, len(a.Communities))
+ }
+ for _, x := range a.Communities {
+ if op == config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE {
+ subtype, exp, err := parseExtCommunityRegexp(x)
+ if err != nil {
+ return nil, err
+ }
+ removeList = append(removeList, exp)
+ subtypeList = append(subtypeList, subtype)
+ } else {
+ comm, err := parseExtCommunity(x)
+ if err != nil {
+ return nil, err
+ }
+ list = append(list, comm)
+ _, subtype := comm.GetTypes()
+ subtypeList = append(subtypeList, subtype)
+ }
+ }
+ return &ExtCommunityAction{
+ action: op,
+ list: list,
+ removeList: removeList,
+ subtypeList: subtypeList,
+ }, nil
+}
+
func NewExtCommunityAction(c config.SetExtCommunity) (*ExtCommunityAction, error) {
a, ok := CommunityOptionValueMap[strings.ToLower(c.Options)]
if !ok {
@@ -1220,6 +1453,13 @@ func (a *MedAction) ToApiStruct() *api.MedAction {
}
}
+func NewMedActionFromApiStruct(a *api.MedAction) (*MedAction, error) {
+ return &MedAction{
+ action: MedActionType(a.Type),
+ value: int(a.Value),
+ }, nil
+}
+
func NewMedAction(c config.BgpSetMedType) (*MedAction, error) {
if string(c) == "" {
return nil, nil
@@ -1289,6 +1529,14 @@ func (a *AsPathPrependAction) ToApiStruct() *api.AsPrependAction {
}
}
+func NewAsPathPrependActionFromApiStruct(a *api.AsPrependAction) (*AsPathPrependAction, error) {
+ return &AsPathPrependAction{
+ asn: a.Asn,
+ useLeftMost: a.UseLeftMost,
+ repeat: uint8(a.Repeat),
+ }, nil
+}
+
// NewAsPathPrependAction creates AsPathPrependAction object.
// If ASN cannot be parsed, nil will be returned.
func NewAsPathPrependAction(action config.SetAsPathPrepend) (*AsPathPrependAction, error) {
@@ -1398,6 +1646,87 @@ func (s *Statement) ToApiStruct() *api.Statement {
}
}
+func NewStatementFromApiStruct(a api.Statement) (*Statement, error) {
+ if a.Name == "" {
+ return nil, fmt.Errorf("empty statement name")
+ }
+ var ra Action
+ var as []Action
+ var cs []Condition
+ var err error
+ if a.Conditions != nil {
+ cfs := []func() (Condition, error){
+ func() (Condition, error) {
+ return NewPrefixConditionFromApiStruct(a.Conditions.PrefixSet)
+ },
+ func() (Condition, error) {
+ return NewNeighborConditionFromApiStruct(a.Conditions.NeighborSet)
+ },
+ func() (Condition, error) {
+ return NewAsPathLengthConditionFromApiStruct(a.Conditions.AsPathLength)
+ },
+ func() (Condition, error) {
+ return NewRpkiValidationConditionFromApiStruct(a.Conditions.RpkiResult)
+ },
+ func() (Condition, error) {
+ return NewAsPathConditionFromApiStruct(a.Conditions.AsPathSet)
+ },
+ func() (Condition, error) {
+ return NewCommunityConditionFromApiStruct(a.Conditions.CommunitySet)
+ },
+ func() (Condition, error) {
+ return NewExtCommunityConditionFromApiStruct(a.Conditions.ExtCommunitySet)
+ },
+ }
+ cs = make([]Condition, 0, len(cfs))
+ for _, f := range cfs {
+ c, err := f()
+ if err != nil {
+ return nil, err
+ }
+ if !reflect.ValueOf(c).IsNil() {
+ cs = append(cs, c)
+ }
+ }
+ }
+ if a.Actions != nil {
+ ra, err = NewRoutingActionFromApiStruct(a.Actions.RouteAction)
+ if err != nil {
+ return nil, err
+ }
+ afs := []func() (Action, error){
+ func() (Action, error) {
+ return NewCommunityActionFromApiStruct(a.Actions.Community)
+ },
+ func() (Action, error) {
+ return NewExtCommunityActionFromApiStruct(a.Actions.ExtCommunity)
+ },
+ func() (Action, error) {
+ return NewMedActionFromApiStruct(a.Actions.Med)
+ },
+ func() (Action, error) {
+ return NewAsPathPrependActionFromApiStruct(a.Actions.AsPrepend)
+ },
+ }
+ as = make([]Action, 0, len(afs))
+ for _, f := range afs {
+ a, err := f()
+ if err != nil {
+ return nil, err
+ }
+ if !reflect.ValueOf(a).IsNil() {
+ as = append(as, a)
+ }
+ }
+ }
+ return &Statement{
+ Name: a.Name,
+ Conditions: cs,
+ RouteAction: ra,
+ ModActions: as,
+ }, nil
+}
+
func NewStatement(c config.Statement, dmap DefinedSetMap) (*Statement, error) {
if c.Name == "" {
return nil, fmt.Errorf("empty statement name")