Repository: scionproto/scion
Pull request #3640 (2020-01-29 08:23:25)

Adapt pathpol.Path interface to snet.Path
Adapt `pathpol.Path` so that `snet.Path` is compliant. Rename `Key` to `Fingerprint` and use `snet.PathInterface`  instead of the equivalent/redundant `pathpol.PathInterface` type.

This allows to create `pathpol.Pathset` from `snet.Path` objects without intermediate wrappers, and thereby makes application access to `pathpol.Filter` a bit more convenient.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/scionproto/scion/3640)
<!-- Reviewable:end -->



Patch:
diff --git a/go/cs/segutil/filter.go b/go/cs/segutil/filter.go
index 151826541..6d110a003 100644
--- a/go/cs/segutil/filter.go
+++ b/go/cs/segutil/filter.go
@@ -58,7 +58,7 @@ func segsToPs(segs seg.Segments, dir Direction) pathpol.PathSet {
 	ps := make(pathpol.PathSet, len(segs))
 	for _, seg := range segs {
 		sw := wrap(seg, dir)
-		ps[sw.Key()] = sw
+		ps[sw.Fingerprint()] = sw
 	}
 	return ps
 }
@@ -73,13 +73,13 @@ func psToSegs(ps pathpol.PathSet) seg.Segments {
 }
 
 type segWrap struct {
-	intfs   []pathpol.PathInterface
+	intfs   []snet.PathInterface
 	key     snet.PathFingerprint
 	origSeg *seg.PathSegment
 }
 
 func wrap(seg *seg.PathSegment, dir Direction) segWrap {
-	intfs := make([]pathpol.PathInterface, 0, len(seg.ASEntries))
+	intfs := make([]snet.PathInterface, 0, len(seg.ASEntries))
 	keyParts := make([]string, 0, len(seg.ASEntries))
 	for _, asEntry := range seg.ASEntries {
 		for _, hopEntry := range asEntry.HopEntries {
@@ -109,8 +109,8 @@ func wrap(seg *seg.PathSegment, dir Direction) segWrap {
 	}
 }
 
-func (s segWrap) Interfaces() []pathpol.PathInterface { return s.intfs }
-func (s segWrap) Key() snet.PathFingerprint           { return s.key }
+func (s segWrap) Interfaces() []snet.PathInterface  { return s.intfs }
+func (s segWrap) Fingerprint() snet.PathFingerprint { return s.key }
 
 type pathInterface struct {
 	ia   addr.IA
diff --git a/go/lib/pathpol/acl.go b/go/lib/pathpol/acl.go
index e4c715787..96d12b303 100644
--- a/go/lib/pathpol/acl.go
+++ b/go/lib/pathpol/acl.go
@@ -21,6 +21,7 @@ import (
 	"strings"
 
 	"github.com/scionproto/scion/go/lib/common"
+	"github.com/scionproto/scion/go/lib/snet"
 )
 
 var (
@@ -72,7 +73,7 @@ func (a *ACL) evalPath(path Path) ACLAction {
 	return Allow
 }
 
-func (a *ACL) evalInterface(iface PathInterface, ingress bool) ACLAction {
+func (a *ACL) evalInterface(iface snet.PathInterface, ingress bool) ACLAction {
 	for _, aclEntry := range a.Entries {
 		if aclEntry.Rule == nil || aclEntry.Rule.pathIFMatch(iface, ingress) {
 			return aclEntry.Action
diff --git a/go/lib/pathpol/hop_pred.go b/go/lib/pathpol/hop_pred.go
index 214e2e94b..509ad12a6 100644
--- a/go/lib/pathpol/hop_pred.go
+++ b/go/lib/pathpol/hop_pred.go
@@ -24,6 +24,7 @@ import (
 	"github.com/scionproto/scion/go/lib/addr"
 	"github.com/scionproto/scion/go/lib/common"
 	"github.com/scionproto/scion/go/lib/serrors"
+	"github.com/scionproto/scion/go/lib/snet"
 )
 
 // A HopPredicate specifies a hop in the ACL or Sequence of the path policy,
@@ -86,7 +87,7 @@ func HopPredicateFromString(str string) (*HopPredicate, error) {
 
 // pathIFMatch takes a PathInterface and a bool indicating if the ingress
 // interface needs to be matching. It returns true if the HopPredicate matches the PathInterface
-func (hp *HopPredicate) pathIFMatch(pi PathInterface, in bool) bool {
+func (hp *HopPredicate) pathIFMatch(pi snet.PathInterface, in bool) bool {
 	if hp.ISD != 0 && pi.IA().I != hp.ISD {
 		return false
 	}
diff --git a/go/lib/pathpol/pathset.go b/go/lib/pathpol/pathset.go
index 9978971c2..eb7eb2643 100644
--- a/go/lib/pathpol/pathset.go
+++ b/go/lib/pathpol/pathset.go
@@ -15,8 +15,6 @@
 package pathpol
 
 import (
-	"github.com/scionproto/scion/go/lib/addr"
-	"github.com/scionproto/scion/go/lib/common"
 	"github.com/scionproto/scion/go/lib/snet"
 )
 
@@ -26,15 +24,7 @@ type PathSet map[snet.PathFingerprint]Path
 // Path describes a path or a partial path, e.g. a segment.
 type Path interface {
 	// Interfaces returns all the interfaces of this path.
-	Interfaces() []PathInterface
+	Interfaces() []snet.PathInterface
 	// Returns a string that uniquely identifies this path.
-	Key() snet.PathFingerprint
-}
-
-// PathInterface is an interface on the path.
-type PathInterface interface {
-	// ID is the ID of the interface.
-	ID() common.IFIDType
-	// IA is the ISD AS identifier of the interface.
-	IA() addr.IA
+	Fingerprint() snet.PathFingerprint
 }
diff --git a/go/lib/snet/path.go b/go/lib/snet/path.go
index 9d54b1de7..cdaea52b8 100644
--- a/go/lib/snet/path.go
+++ b/go/lib/snet/path.go
@@ -68,7 +68,9 @@ type Path interface {
 // that packages which can not depend on snet can still implement the snet.Path
 // interface.
 type PathInterface interface {
+	// ID is the ID of the interface.
 	ID() common.IFIDType
+	// IA is the ISD AS identifier of the interface.
 	IA() addr.IA
 }
 
diff --git a/go/sciond/internal/fetcher/filter.go b/go/sciond/internal/fetcher/filter.go
index 09a174e0d..4b8c21f18 100644
--- a/go/sciond/internal/fetcher/filter.go
+++ b/go/sciond/internal/fetcher/filter.go
@@ -38,7 +38,7 @@ func pathsToPs(paths []*combinator.Path) pathpol.PathSet {
 	ps := make(pathpol.PathSet, len(paths))
 	for _, path := range paths {
 		wp := newPathWrap(path)
-		ps[wp.Key()] = wp
+		ps[wp.Fingerprint()] = wp
 	}
 	return ps
 }
@@ -53,12 +53,12 @@ func psToPaths(ps pathpol.PathSet) []*combinator.Path {
 
 type pathWrap struct {
 	key      snet.PathFingerprint
-	intfs    []pathpol.PathInterface
+	intfs    []snet.PathInterface
 	origPath *combinator.Path
 }
 
 func newPathWrap(p *combinator.Path) pathWrap {
-	intfs := make([]pathpol.PathInterface, 0, len(p.Interfaces))
+	intfs := make([]snet.PathInterface, 0, len(p.Interfaces))
 	keyParts := make([]string, 0, len(p.Interfaces))
 	for _, intf := range p.Interfaces {
 		intfs = append(intfs, intf)
@@ -71,5 +71,5 @@ func newPathWrap(p *combinator.Path) pathWrap {
 	}
 }
 
-func (p pathWrap) Interfaces() []pathpol.PathInterface { return p.intfs }
-func (p pathWrap) Key() snet.PathFingerprint           { return p.key }
+func (p pathWrap) Interfaces() []snet.PathInterface  { return p.intfs }
+func (p pathWrap) Fingerprint() snet.PathFingerprint { return p.key }
diff --git a/go/sig/internal/pathmgr/pathmgr.go b/go/sig/internal/pathmgr/pathmgr.go
index 900aa66ed..cddd9c65e 100644
--- a/go/sig/internal/pathmgr/pathmgr.go
+++ b/go/sig/internal/pathmgr/pathmgr.go
@@ -266,23 +266,10 @@ func matches(path snet.Path, predicatePI sciond.PathInterface) bool {
 	return false
 }
 
-type pathWrap struct {
-	snet.Path
-}
-
-func (p pathWrap) Key() snet.PathFingerprint { return p.Fingerprint() }
-func (p pathWrap) Interfaces() []pathpol.PathInterface {
-	intfs := make([]pathpol.PathInterface, 0, len(p.Path.Interfaces()))
-	for _, intf := range p.Path.Interfaces() {
-		intfs = append(intfs, intf)
-	}
-	return intfs
-}
-
 func apsToPs(aps spathmeta.AppPathSet) pathpol.PathSet {
 	ps := make(pathpol.PathSet, len(aps))
 	for key, path := range aps {
-		ps[key] = pathWrap{Path: path}
+		ps[key] = path
 	}
 	return ps
 }
@@ -290,8 +277,7 @@ func apsToPs(aps spathmeta.AppPathSet) pathpol.PathSet {
 func psToAps(ps pathpol.PathSet) spathmeta.AppPathSet {
 	aps := make(spathmeta.AppPathSet)
 	for _, path := range ps {
-		ap := path.(pathWrap).Path
-		aps[ap.Fingerprint()] = ap
+		aps[path.Fingerprint()] = path.(snet.Path)
 	}
 	return aps
 }


Test patch:
diff --git a/go/lib/pathpol/policy_test.go b/go/lib/pathpol/policy_test.go
index 007e7acd5..ce4a8e86a 100644
--- a/go/lib/pathpol/policy_test.go
+++ b/go/lib/pathpol/policy_test.go
@@ -1,4 +1,4 @@
-// Copyright 2018 ETH Zurich
+// Copyright 2017 ETH Zurich
 // Copyright 2019 ETH Zurich, Anapaya Systems
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
@@ -630,7 +630,7 @@ func (p PathProvider) GetPaths(src, dst addr.IA) PathSet {
 	result := make(PathSet)
 	paths := p.g.GetPaths(src.String(), dst.String())
 	for _, ifids := range paths {
-		pathIntfs := make([]PathInterface, 0, len(ifids))
+		pathIntfs := make([]snet.PathInterface, 0, len(ifids))
 		var key strings.Builder
 		for _, ifid := range ifids {
 			ia := p.g.GetParent(ifid)
@@ -646,15 +646,15 @@ func (p PathProvider) GetPaths(src, dst addr.IA) PathSet {
 }
 
 type testPath struct {
-	interfaces []PathInterface
+	interfaces []snet.PathInterface
 	key        snet.PathFingerprint
 }
 
-func (p *testPath) Interfaces() []PathInterface {
+func (p *testPath) Interfaces() []snet.PathInterface {
 	return p.interfaces
 }
 
-func (p *testPath) Key() snet.PathFingerprint { return p.key }
+func (p *testPath) Fingerprint() snet.PathFingerprint { return p.key }
 
 type testPathIntf struct {
 	ia   addr.IA