summaryrefslogtreecommitdiffhomepage
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/pkg/table/policy.go222
1 files changed, 220 insertions, 2 deletions
diff --git a/internal/pkg/table/policy.go b/internal/pkg/table/policy.go
index 6e97723c..b06da47d 100644
--- a/internal/pkg/table/policy.go
+++ b/internal/pkg/table/policy.go
@@ -27,10 +27,10 @@ import (
"strings"
"sync"
+ radix "github.com/armon/go-radix"
+ api "github.com/osrg/gobgp/api"
"github.com/osrg/gobgp/internal/pkg/config"
"github.com/osrg/gobgp/pkg/packet/bgp"
-
- radix "github.com/armon/go-radix"
log "github.com/sirupsen/logrus"
)
@@ -3899,3 +3899,221 @@ type PolicyAssignment struct {
Policies []*Policy
Default RouteType
}
+
+var _regexpMedActionType = regexp.MustCompile(`([+-]?)(\d+)`)
+
+func toStatementApi(s *config.Statement) *api.Statement {
+ cs := &api.Conditions{}
+ o, _ := NewMatchOption(s.Conditions.MatchPrefixSet.MatchSetOptions)
+ if s.Conditions.MatchPrefixSet.PrefixSet != "" {
+ cs.PrefixSet = &api.MatchSet{
+ Type: api.MatchType(o),
+ Name: s.Conditions.MatchPrefixSet.PrefixSet,
+ }
+ }
+ if s.Conditions.MatchNeighborSet.NeighborSet != "" {
+ o, _ := NewMatchOption(s.Conditions.MatchNeighborSet.MatchSetOptions)
+ cs.NeighborSet = &api.MatchSet{
+ Type: api.MatchType(o),
+ Name: s.Conditions.MatchNeighborSet.NeighborSet,
+ }
+ }
+ if s.Conditions.BgpConditions.AsPathLength.Operator != "" {
+ cs.AsPathLength = &api.AsPathLength{
+ Length: s.Conditions.BgpConditions.AsPathLength.Value,
+ Type: api.AsPathLengthType(s.Conditions.BgpConditions.AsPathLength.Operator.ToInt()),
+ }
+ }
+ if s.Conditions.BgpConditions.MatchAsPathSet.AsPathSet != "" {
+ cs.AsPathSet = &api.MatchSet{
+ Type: api.MatchType(s.Conditions.BgpConditions.MatchAsPathSet.MatchSetOptions.ToInt()),
+ Name: s.Conditions.BgpConditions.MatchAsPathSet.AsPathSet,
+ }
+ }
+ if s.Conditions.BgpConditions.MatchCommunitySet.CommunitySet != "" {
+ cs.CommunitySet = &api.MatchSet{
+ Type: api.MatchType(s.Conditions.BgpConditions.MatchCommunitySet.MatchSetOptions.ToInt()),
+ Name: s.Conditions.BgpConditions.MatchCommunitySet.CommunitySet,
+ }
+ }
+ if s.Conditions.BgpConditions.MatchExtCommunitySet.ExtCommunitySet != "" {
+ cs.ExtCommunitySet = &api.MatchSet{
+ Type: api.MatchType(s.Conditions.BgpConditions.MatchExtCommunitySet.MatchSetOptions.ToInt()),
+ Name: s.Conditions.BgpConditions.MatchExtCommunitySet.ExtCommunitySet,
+ }
+ }
+ if s.Conditions.BgpConditions.MatchLargeCommunitySet.LargeCommunitySet != "" {
+ cs.LargeCommunitySet = &api.MatchSet{
+ Type: api.MatchType(s.Conditions.BgpConditions.MatchLargeCommunitySet.MatchSetOptions.ToInt()),
+ Name: s.Conditions.BgpConditions.MatchLargeCommunitySet.LargeCommunitySet,
+ }
+ }
+ if s.Conditions.BgpConditions.RouteType != "" {
+ cs.RouteType = api.Conditions_RouteType(s.Conditions.BgpConditions.RouteType.ToInt())
+ }
+ if len(s.Conditions.BgpConditions.NextHopInList) > 0 {
+ cs.NextHopInList = s.Conditions.BgpConditions.NextHopInList
+ }
+ if s.Conditions.BgpConditions.AfiSafiInList != nil {
+ afiSafiIn := make([]*api.Family, 0)
+ for _, afiSafiType := range s.Conditions.BgpConditions.AfiSafiInList {
+ if mapped, ok := bgp.AddressFamilyValueMap[string(afiSafiType)]; ok {
+ afi, safi := bgp.RouteFamilyToAfiSafi(mapped)
+ afiSafiIn = append(afiSafiIn, &api.Family{Afi: api.Family_Afi(afi), Safi: api.Family_Safi(safi)})
+ }
+ }
+ cs.AfiSafiIn = afiSafiIn
+ }
+ cs.RpkiResult = int32(s.Conditions.BgpConditions.RpkiValidationResult.ToInt())
+ as := &api.Actions{
+ RouteAction: func() api.RouteAction {
+ switch s.Actions.RouteDisposition {
+ case config.ROUTE_DISPOSITION_ACCEPT_ROUTE:
+ return api.RouteAction_ACCEPT
+ case config.ROUTE_DISPOSITION_REJECT_ROUTE:
+ return api.RouteAction_REJECT
+ }
+ return api.RouteAction_NONE
+ }(),
+ Community: func() *api.CommunityAction {
+ if len(s.Actions.BgpActions.SetCommunity.SetCommunityMethod.CommunitiesList) == 0 {
+ return nil
+ }
+ return &api.CommunityAction{
+ Type: api.CommunityActionType(config.BgpSetCommunityOptionTypeToIntMap[config.BgpSetCommunityOptionType(s.Actions.BgpActions.SetCommunity.Options)]),
+ Communities: s.Actions.BgpActions.SetCommunity.SetCommunityMethod.CommunitiesList}
+ }(),
+ Med: func() *api.MedAction {
+ medStr := strings.TrimSpace(string(s.Actions.BgpActions.SetMed))
+ if len(medStr) == 0 {
+ return nil
+ }
+ matches := _regexpMedActionType.FindStringSubmatch(medStr)
+ if len(matches) == 0 {
+ return nil
+ }
+ action := api.MedActionType_MED_REPLACE
+ switch matches[1] {
+ case "+", "-":
+ action = api.MedActionType_MED_MOD
+ }
+ value, err := strconv.ParseInt(matches[1]+matches[2], 10, 64)
+ if err != nil {
+ return nil
+ }
+ return &api.MedAction{
+ Value: value,
+ Type: action,
+ }
+ }(),
+ AsPrepend: func() *api.AsPrependAction {
+ if len(s.Actions.BgpActions.SetAsPathPrepend.As) == 0 {
+ return nil
+ }
+ var asn uint64
+ useleft := false
+ if s.Actions.BgpActions.SetAsPathPrepend.As != "last-as" {
+ asn, _ = strconv.ParseUint(s.Actions.BgpActions.SetAsPathPrepend.As, 10, 32)
+ } else {
+ useleft = true
+ }
+ return &api.AsPrependAction{
+ Asn: uint32(asn),
+ Repeat: uint32(s.Actions.BgpActions.SetAsPathPrepend.RepeatN),
+ UseLeftMost: useleft,
+ }
+ }(),
+ ExtCommunity: func() *api.CommunityAction {
+ if len(s.Actions.BgpActions.SetExtCommunity.SetExtCommunityMethod.CommunitiesList) == 0 {
+ return nil
+ }
+ return &api.CommunityAction{
+ Type: api.CommunityActionType(config.BgpSetCommunityOptionTypeToIntMap[config.BgpSetCommunityOptionType(s.Actions.BgpActions.SetExtCommunity.Options)]),
+ Communities: s.Actions.BgpActions.SetExtCommunity.SetExtCommunityMethod.CommunitiesList,
+ }
+ }(),
+ LargeCommunity: func() *api.CommunityAction {
+ if len(s.Actions.BgpActions.SetLargeCommunity.SetLargeCommunityMethod.CommunitiesList) == 0 {
+ return nil
+ }
+ return &api.CommunityAction{
+ Type: api.CommunityActionType(config.BgpSetCommunityOptionTypeToIntMap[config.BgpSetCommunityOptionType(s.Actions.BgpActions.SetLargeCommunity.Options)]),
+ Communities: s.Actions.BgpActions.SetLargeCommunity.SetLargeCommunityMethod.CommunitiesList,
+ }
+ }(),
+ Nexthop: func() *api.NexthopAction {
+ if len(string(s.Actions.BgpActions.SetNextHop)) == 0 {
+ return nil
+ }
+
+ if string(s.Actions.BgpActions.SetNextHop) == "self" {
+ return &api.NexthopAction{
+ Self: true,
+ }
+ }
+ return &api.NexthopAction{
+ Address: string(s.Actions.BgpActions.SetNextHop),
+ }
+ }(),
+ LocalPref: func() *api.LocalPrefAction {
+ if s.Actions.BgpActions.SetLocalPref == 0 {
+ return nil
+ }
+ return &api.LocalPrefAction{Value: s.Actions.BgpActions.SetLocalPref}
+ }(),
+ }
+ return &api.Statement{
+ Name: s.Name,
+ Conditions: cs,
+ Actions: as,
+ }
+}
+
+func NewAPIPolicyFromTableStruct(p *Policy) *api.Policy {
+ return ToPolicyApi(p.ToConfig())
+}
+
+func ToPolicyApi(p *config.PolicyDefinition) *api.Policy {
+ return &api.Policy{
+ Name: p.Name,
+ Statements: func() []*api.Statement {
+ l := make([]*api.Statement, 0)
+ for _, s := range p.Statements {
+ l = append(l, toStatementApi(&s))
+ }
+ return l
+ }(),
+ }
+}
+
+func NewAPIPolicyAssignmentFromTableStruct(t *PolicyAssignment) *api.PolicyAssignment {
+ return &api.PolicyAssignment{
+ Direction: func() api.PolicyDirection {
+ switch t.Type {
+ case POLICY_DIRECTION_IMPORT:
+ return api.PolicyDirection_IMPORT
+ case POLICY_DIRECTION_EXPORT:
+ return api.PolicyDirection_EXPORT
+ }
+ log.Errorf("invalid policy-type: %s", t.Type)
+ return api.PolicyDirection_UNKNOWN
+ }(),
+ DefaultAction: func() api.RouteAction {
+ switch t.Default {
+ case ROUTE_TYPE_ACCEPT:
+ return api.RouteAction_ACCEPT
+ case ROUTE_TYPE_REJECT:
+ return api.RouteAction_REJECT
+ }
+ return api.RouteAction_NONE
+ }(),
+ Name: t.Name,
+ Policies: func() []*api.Policy {
+ l := make([]*api.Policy, 0)
+ for _, p := range t.Policies {
+ l = append(l, NewAPIPolicyFromTableStruct(p))
+ }
+ return l
+ }(),
+ }
+}