diff options
-rw-r--r-- | api/grpc_server.go | 22 | ||||
-rw-r--r-- | api/util.go | 27 | ||||
-rw-r--r-- | gobgp/cmd/neighbor.go | 12 | ||||
-rw-r--r-- | table/path.go | 60 | ||||
-rw-r--r-- | table/policy.go | 8 |
5 files changed, 109 insertions, 20 deletions
diff --git a/api/grpc_server.go b/api/grpc_server.go index 3b8f2fe4..1d8cca6a 100644 --- a/api/grpc_server.go +++ b/api/grpc_server.go @@ -26,13 +26,14 @@ import ( "sync" "time" + log "github.com/sirupsen/logrus" + "golang.org/x/net/context" + "google.golang.org/grpc" + "github.com/osrg/gobgp/config" "github.com/osrg/gobgp/packet/bgp" "github.com/osrg/gobgp/server" "github.com/osrg/gobgp/table" - log "github.com/sirupsen/logrus" - "golang.org/x/net/context" - "google.golang.org/grpc" ) type Server struct { @@ -345,6 +346,18 @@ func (s *Server) GetNeighbor(ctx context.Context, arg *GetNeighborRequest) (*Get return &GetNeighborResponse{Peers: p}, nil } +func NewValidationFromTableStruct(v *table.Validation) *RPKIValidation { + if v == nil { + return &RPKIValidation{} + } + return &RPKIValidation{ + Reason: RPKIValidation_Reason(v.Reason.ToInt()), + Matched: NewRoaListFromTableStructList(v.Matched), + UnmatchedAs: NewRoaListFromTableStructList(v.UnmatchedAs), + UnmatchedLength: NewRoaListFromTableStructList(v.UnmatchedLength), + } +} + func ToPathApi(path *table.Path) *Path { nlri := path.GetNlri() n, _ := nlri.Serialize() @@ -362,7 +375,8 @@ func ToPathApi(path *table.Path) *Path { Pattrs: pattrs, Age: path.GetTimestamp().Unix(), IsWithdraw: path.IsWithdraw, - Validation: int32(path.Validation().ToInt()), + Validation: int32(path.ValidationStatus().ToInt()), + ValidationDetail: NewValidationFromTableStruct(path.Validation()), Filtered: path.Filtered("") == table.POLICY_DIRECTION_IN, Family: family, Stale: path.IsStale(), diff --git a/api/util.go b/api/util.go index dabb65b7..53d4f1df 100644 --- a/api/util.go +++ b/api/util.go @@ -121,7 +121,13 @@ func (p *Path) ToNativePath(option ...ToNativeOption) (*table.Path, error) { t := time.Unix(p.Age, 0) nlri.SetPathIdentifier(p.Identifier) path := table.NewPath(info, nlri, p.IsWithdraw, pattr, t, false) - path.SetValidation(config.IntToRpkiValidationResultTypeMap[int(p.Validation)]) + path.SetValidation(&table.Validation{ + Status: config.IntToRpkiValidationResultTypeMap[int(p.Validation)], + Reason: table.IntToRpkiValidationReasonTypeMap[int(p.ValidationDetail.Reason)], + Matched: NewROAListFromApiStructList(p.ValidationDetail.Matched), + UnmatchedAs: NewROAListFromApiStructList(p.ValidationDetail.UnmatchedAs), + UnmatchedLength: NewROAListFromApiStructList(p.ValidationDetail.UnmatchedLength), + }) path.MarkStale(p.Stale) path.SetUUID(p.Uuid) if p.Filtered { @@ -130,3 +136,22 @@ func (p *Path) ToNativePath(option ...ToNativeOption) (*table.Path, error) { path.IsNexthopInvalid = p.IsNexthopInvalid return path, nil } + +func NewROAListFromApiStructList(l []*Roa) []*table.ROA { + roas := make([]*table.ROA, 0, len(l)) + for _, r := range l { + ip := net.ParseIP(r.Prefix) + rf := func(prefix string) bgp.RouteFamily { + a, _, _ := net.ParseCIDR(prefix) + if a.To4() != nil { + return bgp.RF_IPv4_UC + } else { + return bgp.RF_IPv6_UC + } + }(r.Prefix) + afi, _ := bgp.RouteFamilyToAfiSafi(rf) + roa := table.NewROA(int(afi), []byte(ip), uint8(r.Prefixlen), uint8(r.Maxlen), r.As, net.JoinHostPort(r.Conf.Address, r.Conf.RemotePort)) + roas = append(roas, roa) + } + return roas +} diff --git a/gobgp/cmd/neighbor.go b/gobgp/cmd/neighbor.go index d63e599b..3c6b5669 100644 --- a/gobgp/cmd/neighbor.go +++ b/gobgp/cmd/neighbor.go @@ -18,15 +18,17 @@ package cmd import ( "encoding/json" "fmt" - "github.com/osrg/gobgp/config" - "github.com/osrg/gobgp/packet/bgp" - "github.com/osrg/gobgp/table" - "github.com/spf13/cobra" "net" "sort" "strconv" "strings" "time" + + "github.com/spf13/cobra" + + "github.com/osrg/gobgp/config" + "github.com/osrg/gobgp/packet/bgp" + "github.com/osrg/gobgp/table" ) func getNeighbors(vrf string) (neighbors, error) { @@ -444,7 +446,7 @@ func ShowRoute(pathList []*table.Path, showAge, showBest, showLabel, showIdentif if p.IsStale() { best += "S" } - switch p.Validation() { + switch p.ValidationStatus() { case config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND: best += "N" case config.RPKI_VALIDATION_RESULT_TYPE_VALID: diff --git a/table/path.go b/table/path.go index 0ff1afce..c911ebf3 100644 --- a/table/path.go +++ b/table/path.go @@ -24,10 +24,12 @@ import ( "sort" "time" + log "github.com/sirupsen/logrus" + + uuid "github.com/satori/go.uuid" + "github.com/osrg/gobgp/config" "github.com/osrg/gobgp/packet/bgp" - "github.com/satori/go.uuid" - log "github.com/sirupsen/logrus" ) const ( @@ -57,7 +59,7 @@ type originInfo struct { source *PeerInfo timestamp time.Time noImplicitWithdraw bool - validation config.RpkiValidationResultType + validation *Validation isFromExternal bool key string uuid uuid.UUID @@ -65,6 +67,42 @@ type originInfo struct { stale bool } +type RpkiValidationReasonType string + +const ( + RPKI_VALIDATION_REASON_TYPE_NONE RpkiValidationReasonType = "none" + RPKI_VALIDATION_REASON_TYPE_AS RpkiValidationReasonType = "as" + RPKI_VALIDATION_REASON_TYPE_LENGTH RpkiValidationReasonType = "length" +) + +var RpkiValidationReasonTypeToIntMap = map[RpkiValidationReasonType]int{ + RPKI_VALIDATION_REASON_TYPE_NONE: 0, + RPKI_VALIDATION_REASON_TYPE_AS: 1, + RPKI_VALIDATION_REASON_TYPE_LENGTH: 2, +} + +func (v RpkiValidationReasonType) ToInt() int { + i, ok := RpkiValidationReasonTypeToIntMap[v] + if !ok { + return -1 + } + return i +} + +var IntToRpkiValidationReasonTypeMap = map[int]RpkiValidationReasonType{ + 0: RPKI_VALIDATION_REASON_TYPE_NONE, + 1: RPKI_VALIDATION_REASON_TYPE_AS, + 2: RPKI_VALIDATION_REASON_TYPE_LENGTH, +} + +type Validation struct { + Status config.RpkiValidationResultType + Reason RpkiValidationReasonType + Matched []*ROA + UnmatchedAs []*ROA + UnmatchedLength []*ROA +} + type FlowSpecComponents []bgp.FlowSpecComponentInterface func (c FlowSpecComponents) Len() int { @@ -306,12 +344,20 @@ func (path *Path) NoImplicitWithdraw() bool { return path.OriginInfo().noImplicitWithdraw } -func (path *Path) Validation() config.RpkiValidationResultType { +func (path *Path) Validation() *Validation { return path.OriginInfo().validation } -func (path *Path) SetValidation(r config.RpkiValidationResultType) { - path.OriginInfo().validation = r +func (path *Path) ValidationStatus() config.RpkiValidationResultType { + if v := path.OriginInfo().validation; v != nil { + return v.Status + } else { + return config.RPKI_VALIDATION_RESULT_TYPE_NONE + } +} + +func (path *Path) SetValidation(v *Validation) { + path.OriginInfo().validation = v } func (path *Path) IsFromExternal() bool { @@ -977,7 +1023,7 @@ func (path *Path) MarshalJSON() ([]byte, error) { PathAttrs: path.GetPathAttrs(), Age: path.GetTimestamp().Unix(), Withdrawal: path.IsWithdraw, - Validation: string(path.Validation()), + Validation: string(path.ValidationStatus()), SourceID: path.GetSource().ID, NeighborIP: path.GetSource().Address, Stale: path.IsStale(), diff --git a/table/policy.go b/table/policy.go index a73fa57a..6d2af2d4 100644 --- a/table/policy.go +++ b/table/policy.go @@ -26,10 +26,12 @@ import ( "strings" "sync" - "github.com/armon/go-radix" + log "github.com/sirupsen/logrus" + + radix "github.com/armon/go-radix" + "github.com/osrg/gobgp/config" "github.com/osrg/gobgp/packet/bgp" - log "github.com/sirupsen/logrus" ) type PolicyOptions struct { @@ -1701,7 +1703,7 @@ func (c *RpkiValidationCondition) Type() ConditionType { } func (c *RpkiValidationCondition) Evaluate(path *Path, _ *PolicyOptions) bool { - return c.result == path.Validation() + return c.result == path.ValidationStatus() } func (c *RpkiValidationCondition) Set() DefinedSet { |