summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--server/rpki.go27
-rw-r--r--server/rpki_test.go161
-rw-r--r--server/server.go5
-rw-r--r--table/path.go8
4 files changed, 183 insertions, 18 deletions
diff --git a/server/rpki.go b/server/rpki.go
index 1e743af9..a26f155f 100644
--- a/server/rpki.go
+++ b/server/rpki.go
@@ -41,6 +41,7 @@ type roa struct {
}
type roaClient struct {
+ AS uint32
roas map[bgp.RouteFamily]*radix.Tree
outgoing chan []byte
config config.RpkiServers
@@ -175,7 +176,23 @@ func (c *roaClient) handleGRPC(grpcReq *GrpcRequest) {
}
}
-func validateOne(tree *radix.Tree, cidr string, as uint32) config.RpkiValidationResultType {
+func validatePath(ownAs uint32, tree *radix.Tree, cidr string, asPath *bgp.PathAttributeAsPath) config.RpkiValidationResultType {
+ var as uint32
+ if asPath == nil || len(asPath.Value) == 0 {
+ return config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND
+ }
+ asParam := asPath.Value[len(asPath.Value)-1].(*bgp.As4PathParam)
+ switch asParam.Type {
+ case bgp.BGP_ASPATH_ATTR_TYPE_SEQ:
+ if len(asParam.AS) == 0 {
+ return config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND
+ }
+ as = asParam.AS[len(asParam.AS)-1]
+ case bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET, bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ:
+ as = ownAs
+ default:
+ return config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND
+ }
_, n, _ := net.ParseCIDR(cidr)
ones, _ := n.Mask.Size()
prefixLen := uint8(ones)
@@ -209,17 +226,21 @@ func validateOne(tree *radix.Tree, cidr string, as uint32) config.RpkiValidation
}
func (c *roaClient) validate(pathList []*table.Path) {
+ if c.roas[bgp.RF_IPv4_UC].Len() == 0 && c.roas[bgp.RF_IPv6_UC].Len() == 0 {
+ return
+ }
for _, path := range pathList {
if tree, ok := c.roas[path.GetRouteFamily()]; ok {
- path.Validation = validateOne(tree, path.GetNlri().String(), path.GetSourceAs())
+ path.Validation = validatePath(c.AS, tree, path.GetNlri().String(), path.GetAsPath())
}
}
}
-func newROAClient(conf config.RpkiServers) (*roaClient, error) {
+func newROAClient(as uint32, conf config.RpkiServers) (*roaClient, error) {
var url string
c := &roaClient{
+ AS: as,
roas: make(map[bgp.RouteFamily]*radix.Tree),
config: conf,
}
diff --git a/server/rpki_test.go b/server/rpki_test.go
index 9dd135ec..590a6a72 100644
--- a/server/rpki_test.go
+++ b/server/rpki_test.go
@@ -18,33 +18,168 @@ package server
import (
"github.com/armon/go-radix"
"github.com/osrg/gobgp/config"
+ "github.com/osrg/gobgp/packet"
"github.com/stretchr/testify/assert"
"net"
+ "strconv"
+ "strings"
"testing"
)
-func TestValidate(t *testing.T) {
+func strToASParam(str string) *bgp.PathAttributeAsPath {
+ toList := func(asstr, sep string) []uint32 {
+ as := make([]uint32, 0)
+ l := strings.Split(asstr, sep)
+ for _, s := range l {
+ v, _ := strconv.ParseUint(s, 10, 32)
+ as = append(as, uint32(v))
+ }
+ return as
+ }
+ var atype uint8
+ var as []uint32
+ if strings.HasPrefix(str, "{") {
+ atype = bgp.BGP_ASPATH_ATTR_TYPE_SET
+ as = toList(str[1:len(str)-1], ",")
+ } else if strings.HasPrefix(str, "(") {
+ atype = bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET
+ as = toList(str[1:len(str)-1], " ")
+ } else {
+ atype = bgp.BGP_ASPATH_ATTR_TYPE_SEQ
+ as = toList(str, " ")
+ }
+
+ return bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{bgp.NewAs4PathParam(atype, as)})
+}
+
+func validateOne(tree *radix.Tree, cidr, aspathStr string) config.RpkiValidationResultType {
+ return validatePath(65500, tree, cidr, strToASParam(aspathStr))
+}
+
+func TestValidate0(t *testing.T) {
assert := assert.New(t)
tree := radix.New()
addROA(tree, 100, net.ParseIP("192.168.0.0"), 24, 32)
addROA(tree, 200, net.ParseIP("192.168.0.0"), 24, 24)
- r1 := validateOne(tree, "192.168.0.0/24", 100)
- assert.Equal(r1, config.RPKI_VALIDATION_RESULT_TYPE_VALID)
+ var r config.RpkiValidationResultType
+
+ r = validateOne(tree, "192.168.0.0/24", "100")
+ assert.Equal(r, config.RPKI_VALIDATION_RESULT_TYPE_VALID)
+
+ r = validateOne(tree, "192.168.0.0/24", "100 200")
+ assert.Equal(r, config.RPKI_VALIDATION_RESULT_TYPE_VALID)
+
+ r = validateOne(tree, "192.168.0.0/24", "300")
+ assert.Equal(r, config.RPKI_VALIDATION_RESULT_TYPE_INVALID)
+
+ r = validateOne(tree, "192.168.0.0/25", "100")
+ assert.Equal(r, config.RPKI_VALIDATION_RESULT_TYPE_VALID)
+
+ r = validateOne(tree, "192.168.0.0/25", "200")
+ assert.Equal(r, config.RPKI_VALIDATION_RESULT_TYPE_INVALID)
+
+ r = validateOne(tree, "192.168.0.0/25", "300")
+ assert.Equal(r, config.RPKI_VALIDATION_RESULT_TYPE_INVALID)
+}
+
+func TestValidate2(t *testing.T) {
+ assert := assert.New(t)
+
+ tree := radix.New()
+
+ var r config.RpkiValidationResultType
+
+ r = validateOne(tree, "10.0.0.0/16", "65000")
+ assert.Equal(r, config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND)
+
+ r = validateOne(tree, "10.0.0.0/16", "65001")
+ assert.Equal(r, config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND)
+}
+
+func TestValidate3(t *testing.T) {
+ assert := assert.New(t)
+
+ tree1 := radix.New()
+ addROA(tree1, 65000, net.ParseIP("10.0.0.0"), 16, 16)
+
+ var r config.RpkiValidationResultType
+
+ r = validateOne(tree1, "10.0.0.0/8", "65000")
+ assert.Equal(r, config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND)
+
+ r = validateOne(tree1, "10.0.0.0/17", "65000")
+ assert.Equal(r, config.RPKI_VALIDATION_RESULT_TYPE_INVALID)
+
+ tree2 := radix.New()
+ addROA(tree2, 65000, net.ParseIP("10.0.0.0"), 16, 24)
+
+ r = validateOne(tree2, "10.0.0.0/17", "65000")
+ assert.Equal(r, config.RPKI_VALIDATION_RESULT_TYPE_VALID)
+}
+
+func TestValidate4(t *testing.T) {
+ assert := assert.New(t)
+
+ tree := radix.New()
+ addROA(tree, 65000, net.ParseIP("10.0.0.0"), 16, 16)
+ addROA(tree, 65001, net.ParseIP("10.0.0.0"), 16, 16)
+
+ var r config.RpkiValidationResultType
+
+ r = validateOne(tree, "10.0.0.0/16", "65000")
+ assert.Equal(r, config.RPKI_VALIDATION_RESULT_TYPE_VALID)
+
+ r = validateOne(tree, "10.0.0.0/16", "65001")
+ assert.Equal(r, config.RPKI_VALIDATION_RESULT_TYPE_VALID)
+}
+
+func TestValidate5(t *testing.T) {
+ assert := assert.New(t)
+
+ tree := radix.New()
+ addROA(tree, 65000, net.ParseIP("10.0.0.0"), 17, 17)
+ addROA(tree, 65000, net.ParseIP("10.0.128.0"), 17, 17)
+
+ var r config.RpkiValidationResultType
- r2 := validateOne(tree, "192.168.0.0/24", 200)
- assert.Equal(r2, config.RPKI_VALIDATION_RESULT_TYPE_VALID)
+ r = validateOne(tree, "10.0.0.0/16", "65000")
+ assert.Equal(r, config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND)
+}
+
+func TestValidate6(t *testing.T) {
+ assert := assert.New(t)
+
+ tree := radix.New()
+ addROA(tree, 0, net.ParseIP("10.0.0.0"), 8, 32)
+
+ var r config.RpkiValidationResultType
+
+ r = validateOne(tree, "10.0.0.0/7", "65000")
+ assert.Equal(r, config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND)
+
+ r = validateOne(tree, "10.0.0.0/8", "65000")
+ assert.Equal(r, config.RPKI_VALIDATION_RESULT_TYPE_INVALID)
+
+ r = validateOne(tree, "10.0.0.0/24", "65000")
+ assert.Equal(r, config.RPKI_VALIDATION_RESULT_TYPE_INVALID)
+}
+
+func TestValidate7(t *testing.T) {
+ assert := assert.New(t)
+
+ tree := radix.New()
+ addROA(tree, 65000, net.ParseIP("10.0.0.0"), 16, 24)
- r3 := validateOne(tree, "192.168.0.0/24", 300)
- assert.Equal(r3, config.RPKI_VALIDATION_RESULT_TYPE_INVALID)
+ var r config.RpkiValidationResultType
- r4 := validateOne(tree, "192.168.0.0/25", 100)
- assert.Equal(r4, config.RPKI_VALIDATION_RESULT_TYPE_VALID)
+ r = validateOne(tree, "10.0.0.0/24", "{65000}")
+ assert.Equal(r, config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND)
- r5 := validateOne(tree, "192.168.0.0/25", 200)
- assert.Equal(r5, config.RPKI_VALIDATION_RESULT_TYPE_INVALID)
+ r = validateOne(tree, "10.0.0.0/24", "{65001}")
+ assert.Equal(r, config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND)
- r6 := validateOne(tree, "192.168.0.0/25", 300)
- assert.Equal(r6, config.RPKI_VALIDATION_RESULT_TYPE_INVALID)
+ r = validateOne(tree, "10.0.0.0/24", "{65000,65001}")
+ assert.Equal(r, config.RPKI_VALIDATION_RESULT_TYPE_NOT_FOUND)
}
diff --git a/server/server.go b/server/server.go
index 60aa4d3d..a14f8395 100644
--- a/server/server.go
+++ b/server/server.go
@@ -112,7 +112,6 @@ func NewBgpServer(port int) *BgpServer {
b.policyUpdateCh = make(chan config.RoutingPolicy)
b.neighborMap = make(map[string]*Peer)
b.listenPort = port
- b.roaClient, _ = newROAClient(config.RpkiServers{})
return &b
}
@@ -144,6 +143,8 @@ func (server *BgpServer) Serve() {
g := <-server.globalTypeCh
server.bgpConfig.Global = g
+ server.roaClient, _ = newROAClient(g.GlobalConfig.As, config.RpkiServers{})
+
if g.Mrt.FileName != "" {
d, err := newDumper(g.Mrt.FileName)
if err != nil {
@@ -302,7 +303,7 @@ func (server *BgpServer) Serve() {
select {
case c := <-server.rpkiConfigCh:
- server.roaClient, _ = newROAClient(c)
+ server.roaClient, _ = newROAClient(server.bgpConfig.Global.GlobalConfig.As, c)
case c := <-server.bmpConfigCh:
server.bmpClient, _ = newBMPClient(c, server.bmpConnCh)
case c := <-server.bmpConnCh:
diff --git a/table/path.go b/table/path.go
index 3cebdb96..5e914975 100644
--- a/table/path.go
+++ b/table/path.go
@@ -327,6 +327,14 @@ func (path *Path) getPrefix() string {
return path.nlri.String()
}
+func (path *Path) GetAsPath() *bgp.PathAttributeAsPath {
+ _, attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
+ if attr != nil {
+ return attr.(*bgp.PathAttributeAsPath)
+ }
+ return nil
+}
+
// GetAsPathLen returns the number of AS_PATH
func (path *Path) GetAsPathLen() int {