summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--policy/policy.go76
-rw-r--r--policy/policy_test.go241
2 files changed, 271 insertions, 46 deletions
diff --git a/policy/policy.go b/policy/policy.go
index fe1eb79c..73ffc74d 100644
--- a/policy/policy.go
+++ b/policy/policy.go
@@ -59,7 +59,16 @@ func NewPolicy(name string, pd config.PolicyDefinition, ds config.DefinedSets) *
for _, ps := range ds.PrefixSetList {
if ps.PrefixSetName == prefixSetName {
for _, pl := range ps.PrefixList {
- prefixList = append(prefixList, NewPrefix(pl.Address, pl.Masklength, pl.MasklengthRange))
+ prefix, e := NewPrefix(pl.Address, pl.Masklength, pl.MasklengthRange)
+ if e != nil {
+ log.WithFields(log.Fields{
+ "Topic": "Policy",
+ "prefix": prefix,
+ "msg": e,
+ }).Warn("failed to generate a NewPrefix from configration.")
+ continue
+ }
+ prefixList = append(prefixList, prefix)
}
}
}
@@ -210,11 +219,12 @@ type ModificationActions struct {
type Prefix struct {
Address net.IP
+ AddressFamily bgp.RouteFamily
Masklength uint8
MasklengthRange map[MaskLengthRangeType]uint8
}
-func NewPrefix(addr net.IP, maskLen uint8, maskRange string) Prefix {
+func NewPrefix(addr net.IP, maskLen uint8, maskRange string) (Prefix, error) {
mlr := make(map[MaskLengthRangeType]uint8)
p := Prefix{
Address: addr,
@@ -222,41 +232,36 @@ func NewPrefix(addr net.IP, maskLen uint8, maskRange string) Prefix {
MasklengthRange: make(map[MaskLengthRangeType]uint8),
}
+ if ipv4Family := addr.To4(); ipv4Family != nil {
+ p.AddressFamily, _ = bgp.GetRouteFamily("ipv4-unicast")
+ } else if ipv6Family := addr.To16(); ipv6Family != nil {
+ p.AddressFamily, _ = bgp.GetRouteFamily("ipv6-unicast")
+ } else {
+ return p, fmt.Errorf("can not determine the address family.")
+ }
+
// TODO: validate mask length by using regexp
idx := strings.Index(maskRange, "..")
if idx == -1 {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Address": addr,
- "Masklength": maskLen,
- }).Warn("mask length range of condition is invalid format. mask length is not defined.")
- return p
+ return p, fmt.Errorf("mask length range of condition is invalid format. mask length is not defined.")
}
if idx != 0 {
min, e := strconv.ParseUint(maskRange[:idx], 10, 8)
if e != nil {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Error": e,
- }).Error("failed to parse the min length of mask length range")
- return p
+ return p, e
}
mlr[MASK_LENGTH_RANGE_MIN] = uint8(min)
}
if idx != len(maskRange)-1 {
max, e := strconv.ParseUint(maskRange[idx+2:], 10, 8)
if e != nil {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Error": e,
- }).Error("failed to parse the max length of mask length range")
- return p
+ return p, e
}
mlr[MASK_LENGTH_RANGE_MAX] = uint8(max)
}
p.MasklengthRange = mlr
- return p
+ return p, nil
}
//compare path and condition of policy
@@ -285,24 +290,35 @@ func (p *Policy) Apply(path table.Path) (bool, RouteType, table.Path) {
}
func IpPrefixCalculate(path table.Path, cPrefix Prefix) bool {
- pAddr := path.GetNlri().(*bgp.NLRInfo).IPAddrPrefix.Prefix
- pMaskLen := path.GetNlri().(*bgp.NLRInfo).IPAddrPrefix.Length
+ rf := path.GetRouteFamily()
+ log.Debug("path routefamily : ", rf.String())
+ var pAddr net.IP
+ var pMasklen uint8
+
+ if rf != cPrefix.AddressFamily {
+ return false
+ }
+
+ switch rf {
+ case bgp.RF_IPv4_UC:
+ pAddr = path.GetNlri().(*bgp.NLRInfo).IPAddrPrefix.Prefix
+ pMasklen = path.GetNlri().(*bgp.NLRInfo).IPAddrPrefix.Length
+ case bgp.RF_IPv6_UC:
+ pAddr = path.GetNlri().(*bgp.IPv6AddrPrefix).Prefix
+ pMasklen = path.GetNlri().(*bgp.IPv6AddrPrefix).Length
+ default:
+ return false
+ }
+
cp := fmt.Sprintf("%s/%d", cPrefix.Address, cPrefix.Masklength)
rMin, okMin := cPrefix.MasklengthRange[MASK_LENGTH_RANGE_MIN]
rMax, okMax := cPrefix.MasklengthRange[MASK_LENGTH_RANGE_MAX]
-
- //TODO add conditional processing by RouteFamily.
-
if !okMin && !okMax {
- if pAddr.Equal(cPrefix.Address) && pMaskLen == cPrefix.Masklength {
+ if pAddr.Equal(cPrefix.Address) && pMasklen == cPrefix.Masklength {
return true
} else {
return false
}
- } else if !okMin {
- rMin = uint8(0)
- } else if !okMax {
- rMax = uint8(32)
}
_, ipNet, e := net.ParseCIDR(cp)
@@ -314,7 +330,7 @@ func IpPrefixCalculate(path table.Path, cPrefix Prefix) bool {
}).Error("failed to parse the prefix of condition")
return false
}
- if ipNet.Contains(pAddr) && (rMin <= pMaskLen && pMaskLen <= rMax) {
+ if ipNet.Contains(pAddr) && (rMin <= pMasklen && pMasklen <= rMax) {
return true
}
return false
diff --git a/policy/policy_test.go b/policy/policy_test.go
index 212371b8..d77a7b7c 100644
--- a/policy/policy_test.go
+++ b/policy/policy_test.go
@@ -41,18 +41,18 @@ func TestPrefixCalcurateNoRange(t *testing.T) {
msg := table.NewProcessMessage(updateMsg, peer)
path := msg.ToPathList()[0]
// test
- pl1 := NewPrefix(net.ParseIP("10.10.0.0"), 24, "")
+ pl1, _ := NewPrefix(net.ParseIP("10.10.0.0"), 24, "")
match1 := IpPrefixCalculate(path, pl1)
assert.Equal(t, match1, false)
- pl2 := NewPrefix(net.ParseIP("10.10.0.101"), 24, "")
+ pl2, _ := NewPrefix(net.ParseIP("10.10.0.101"), 24, "")
match2 := IpPrefixCalculate(path, pl2)
assert.Equal(t, match2, true)
- pl3 := NewPrefix(net.ParseIP("10.10.0.0"), 16, "21..24")
+ pl3, _ := NewPrefix(net.ParseIP("10.10.0.0"), 16, "21..24")
match3 := IpPrefixCalculate(path, pl3)
assert.Equal(t, match3, true)
}
-func TestPrefixCalcurateInAddress(t *testing.T) {
+func TestPrefixCalcurateAddress(t *testing.T) {
// creatae path
peer := &table.PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
origin := bgp.NewPathAttributeOrigin(0)
@@ -67,15 +67,15 @@ func TestPrefixCalcurateInAddress(t *testing.T) {
msg := table.NewProcessMessage(updateMsg, peer)
path := msg.ToPathList()[0]
// test
- pl1 := NewPrefix(net.ParseIP("10.11.0.0"), 16, "21..24")
+ pl1, _ := NewPrefix(net.ParseIP("10.11.0.0"), 16, "21..24")
match1 := IpPrefixCalculate(path, pl1)
assert.Equal(t, match1, false)
- pl2 := NewPrefix(net.ParseIP("10.10.0.0"), 16, "21..24")
+ pl2, _ := NewPrefix(net.ParseIP("10.10.0.0"), 16, "21..24")
match2 := IpPrefixCalculate(path, pl2)
assert.Equal(t, match2, true)
}
-func TestPrefixCalcurateInLength(t *testing.T) {
+func TestPrefixCalcurateLength(t *testing.T) {
// creatae path
peer := &table.PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
origin := bgp.NewPathAttributeOrigin(0)
@@ -90,15 +90,15 @@ func TestPrefixCalcurateInLength(t *testing.T) {
msg := table.NewProcessMessage(updateMsg, peer)
path := msg.ToPathList()[0]
// test
- pl1 := NewPrefix(net.ParseIP("10.10.64.0"), 24, "21..24")
+ pl1, _ := NewPrefix(net.ParseIP("10.10.64.0"), 24, "21..24")
match1 := IpPrefixCalculate(path, pl1)
assert.Equal(t, match1, false)
- pl2 := NewPrefix(net.ParseIP("10.10.64.0"), 16, "21..24")
+ pl2, _ := NewPrefix(net.ParseIP("10.10.64.0"), 16, "21..24")
match2 := IpPrefixCalculate(path, pl2)
assert.Equal(t, match2, true)
}
-func TestPrefixCalcurateInLengthRange(t *testing.T) {
+func TestPrefixCalcurateLengthRange(t *testing.T) {
// creatae path
peer := &table.PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
origin := bgp.NewPathAttributeOrigin(0)
@@ -113,18 +113,121 @@ func TestPrefixCalcurateInLengthRange(t *testing.T) {
msg := table.NewProcessMessage(updateMsg, peer)
path := msg.ToPathList()[0]
// test
- pl1 := NewPrefix(net.ParseIP("10.10.0.0"), 16, "21..23")
+ pl1, _ := NewPrefix(net.ParseIP("10.10.0.0"), 16, "21..23")
match1 := IpPrefixCalculate(path, pl1)
assert.Equal(t, match1, false)
- pl2 := NewPrefix(net.ParseIP("10.10.0.0"), 16, "25..26")
+ pl2, _ := NewPrefix(net.ParseIP("10.10.0.0"), 16, "25..26")
match2 := IpPrefixCalculate(path, pl2)
assert.Equal(t, match2, false)
- pl3 := NewPrefix(net.ParseIP("10.10.0.0"), 16, "21..24")
+ pl3, _ := NewPrefix(net.ParseIP("10.10.0.0"), 16, "21..24")
match3 := IpPrefixCalculate(path, pl3)
assert.Equal(t, match3, true)
}
-func TestPolicyNotMatchL(t *testing.T) {
+func TestPrefixCalcurateNoRangeIPv6(t *testing.T) {
+ log.SetLevel(log.DebugLevel)
+ // creatae path
+ peer := &table.PeerInfo{AS: 65001, Address: net.ParseIP("2001::192:168:50:1")}
+ origin := bgp.NewPathAttributeOrigin(0)
+ aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
+ aspath := bgp.NewPathAttributeAsPath(aspathParam)
+ mpnlri := []bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")}
+ mpreach := bgp.NewPathAttributeMpReachNLRI("2001::192:168:50:1", mpnlri)
+ med := bgp.NewPathAttributeMultiExitDisc(0)
+ pathAttributes := []bgp.PathAttributeInterface{mpreach, origin, aspath, med}
+ nlri := []bgp.NLRInfo{}
+ withdrawnRoutes := []bgp.WithdrawnRoute{}
+ updateMsg := bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes, nlri)
+ msg := table.NewProcessMessage(updateMsg, peer)
+ path := msg.ToPathList()[0]
+ // test
+ pl1, _ := NewPrefix(net.ParseIP("2001:123:123::"), 48, "")
+ match1 := IpPrefixCalculate(path, pl1)
+ assert.Equal(t, match1, false)
+ pl2, _ := NewPrefix(net.ParseIP("2001:123:123:1::"), 64, "")
+ match2 := IpPrefixCalculate(path, pl2)
+ assert.Equal(t, match2, true)
+ pl3, _ := NewPrefix(net.ParseIP("2001:123:123::"), 48, "64..80")
+ match3 := IpPrefixCalculate(path, pl3)
+ assert.Equal(t, match3, true)
+}
+
+func TestPrefixCalcurateAddressIPv6(t *testing.T) {
+ // creatae path
+ peer := &table.PeerInfo{AS: 65001, Address: net.ParseIP("2001::192:168:50:1")}
+ origin := bgp.NewPathAttributeOrigin(0)
+ aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
+ aspath := bgp.NewPathAttributeAsPath(aspathParam)
+ mpnlri := []bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")}
+ mpreach := bgp.NewPathAttributeMpReachNLRI("2001::192:168:50:1", mpnlri)
+ med := bgp.NewPathAttributeMultiExitDisc(0)
+ pathAttributes := []bgp.PathAttributeInterface{mpreach, origin, aspath, med}
+ nlri := []bgp.NLRInfo{}
+ withdrawnRoutes := []bgp.WithdrawnRoute{}
+ updateMsg := bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes, nlri)
+ msg := table.NewProcessMessage(updateMsg, peer)
+ path := msg.ToPathList()[0]
+ // test
+ pl1, _ := NewPrefix(net.ParseIP("2001:123:128::"), 48, "64..80")
+ match1 := IpPrefixCalculate(path, pl1)
+ assert.Equal(t, match1, false)
+ pl2, _ := NewPrefix(net.ParseIP("2001:123:123::"), 48, "64..80")
+ match2 := IpPrefixCalculate(path, pl2)
+ assert.Equal(t, match2, true)
+}
+
+func TestPrefixCalcurateLengthIPv6(t *testing.T) {
+ // creatae path
+ peer := &table.PeerInfo{AS: 65001, Address: net.ParseIP("2001::192:168:50:1")}
+ origin := bgp.NewPathAttributeOrigin(0)
+ aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
+ aspath := bgp.NewPathAttributeAsPath(aspathParam)
+ mpnlri := []bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")}
+ mpreach := bgp.NewPathAttributeMpReachNLRI("2001::192:168:50:1", mpnlri)
+ med := bgp.NewPathAttributeMultiExitDisc(0)
+ pathAttributes := []bgp.PathAttributeInterface{mpreach, origin, aspath, med}
+ nlri := []bgp.NLRInfo{}
+ withdrawnRoutes := []bgp.WithdrawnRoute{}
+ updateMsg := bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes, nlri)
+ msg := table.NewProcessMessage(updateMsg, peer)
+ path := msg.ToPathList()[0]
+ // test
+ pl1, _ := NewPrefix(net.ParseIP("2001:123:123:64::"), 64, "64..80")
+ match1 := IpPrefixCalculate(path, pl1)
+ assert.Equal(t, match1, false)
+ pl2, _ := NewPrefix(net.ParseIP("2001:123:123:64::"), 48, "64..80")
+ match2 := IpPrefixCalculate(path, pl2)
+ assert.Equal(t, match2, true)
+}
+
+func TestPrefixCalcurateLengthRangeIPv6(t *testing.T) {
+ // creatae path
+ peer := &table.PeerInfo{AS: 65001, Address: net.ParseIP("2001::192:168:50:1")}
+ origin := bgp.NewPathAttributeOrigin(0)
+ aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
+ aspath := bgp.NewPathAttributeAsPath(aspathParam)
+ mpnlri := []bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")}
+ mpreach := bgp.NewPathAttributeMpReachNLRI("2001::192:168:50:1", mpnlri)
+ med := bgp.NewPathAttributeMultiExitDisc(0)
+ pathAttributes := []bgp.PathAttributeInterface{mpreach, origin, aspath, med}
+ nlri := []bgp.NLRInfo{}
+ withdrawnRoutes := []bgp.WithdrawnRoute{}
+ updateMsg := bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes, nlri)
+ msg := table.NewProcessMessage(updateMsg, peer)
+ path := msg.ToPathList()[0]
+ // test
+ pl1, _ := NewPrefix(net.ParseIP("2001:123:123::"), 48, "62..63")
+ match1 := IpPrefixCalculate(path, pl1)
+ assert.Equal(t, match1, false)
+ pl2, _ := NewPrefix(net.ParseIP("2001:123:123::"), 48, "65..66")
+ match2 := IpPrefixCalculate(path, pl2)
+ assert.Equal(t, match2, false)
+ pl3, _ := NewPrefix(net.ParseIP("2001:123:123::"), 48, "63..65")
+ match3 := IpPrefixCalculate(path, pl3)
+ assert.Equal(t, match3, true)
+}
+
+func TestPolicyNotMatch(t *testing.T) {
// creatae path
peer := &table.PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
origin := bgp.NewPathAttributeOrigin(0)
@@ -301,7 +404,7 @@ func TestPolicyMatchAndAccept(t *testing.T) {
assert.Equal(t, newPath, path)
}
-func TestPolicyRejectOnlyPrefixList(t *testing.T) {
+func TestPolicyRejectOnlyPrefixSet(t *testing.T) {
// creatae path
peer := &table.PeerInfo{AS: 65001, Address: net.ParseIP("10.0.1.1")}
origin := bgp.NewPathAttributeOrigin(0)
@@ -372,7 +475,7 @@ func TestPolicyRejectOnlyPrefixList(t *testing.T) {
assert.Equal(t, newPath2, nil)
}
-func TestPolicyRejectOnlyNeighborList(t *testing.T) {
+func TestPolicyRejectOnlyNeighborSet(t *testing.T) {
// creatae path
peer := &table.PeerInfo{AS: 65001, Address: net.ParseIP("10.0.1.1")}
origin := bgp.NewPathAttributeOrigin(0)
@@ -440,3 +543,109 @@ func TestPolicyRejectOnlyNeighborList(t *testing.T) {
assert.Equal(t, pType2, ROUTE_TYPE_NONE)
assert.Equal(t, newPath2, nil)
}
+
+func TestPolicyDifferentRoutefamilyOfPathAndPolicy(t *testing.T) {
+ // creatae path ipv4
+ peerIPv4 := &table.PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
+ originIPv4 := bgp.NewPathAttributeOrigin(0)
+ aspathParamIPv4 := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
+ aspathIPv4 := bgp.NewPathAttributeAsPath(aspathParamIPv4)
+ nexthopIPv4 := bgp.NewPathAttributeNextHop("10.0.0.1")
+ medIPv4 := bgp.NewPathAttributeMultiExitDisc(0)
+ pathAttributesIPv4 := []bgp.PathAttributeInterface{originIPv4, aspathIPv4, nexthopIPv4, medIPv4}
+ nlriIPv4 := []bgp.NLRInfo{*bgp.NewNLRInfo(24, "10.10.0.101")}
+ withdrawnRoutesIPv4 := []bgp.WithdrawnRoute{}
+ updateMsgIPv4 := bgp.NewBGPUpdateMessage(withdrawnRoutesIPv4, pathAttributesIPv4, nlriIPv4)
+ msgIPv4 := table.NewProcessMessage(updateMsgIPv4, peerIPv4)
+ pathIPv4 := msgIPv4.ToPathList()[0]
+ // creatae path ipv6
+ peerIPv6 := &table.PeerInfo{AS: 65001, Address: net.ParseIP("2001::192:168:50:1")}
+ originIPv6 := bgp.NewPathAttributeOrigin(0)
+ aspathParamIPv6 := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
+ aspathIPv6 := bgp.NewPathAttributeAsPath(aspathParamIPv6)
+ mpnlriIPv6 := []bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")}
+ mpreachIPv6 := bgp.NewPathAttributeMpReachNLRI("2001::192:168:50:1", mpnlriIPv6)
+ medIPv6 := bgp.NewPathAttributeMultiExitDisc(0)
+ pathAttributesIPv6 := []bgp.PathAttributeInterface{mpreachIPv6, originIPv6, aspathIPv6, medIPv6}
+ nlriIPv6 := []bgp.NLRInfo{}
+ withdrawnRoutesIPv6 := []bgp.WithdrawnRoute{}
+ updateMsgIPv6 := bgp.NewBGPUpdateMessage(withdrawnRoutesIPv6, pathAttributesIPv6, nlriIPv6)
+ msgIPv6 := table.NewProcessMessage(updateMsgIPv6, peerIPv6)
+ pathIPv6 := msgIPv6.ToPathList()[0]
+ // create policy
+ psIPv4 := config.PrefixSet{
+ PrefixSetName: "psIPv4",
+ PrefixList: []config.Prefix{
+ config.Prefix{
+ Address: net.ParseIP("10.10.0.0"),
+ Masklength: 16,
+ MasklengthRange: "21..24",
+ }},
+ }
+ nsIPv4 := config.NeighborSet{
+ NeighborSetName: "nsIPv4",
+ NeighborInfoList: []config.NeighborInfo{
+ config.NeighborInfo{
+ Address: net.ParseIP("10.0.0.1"),
+ }},
+ }
+ psIPv6 := config.PrefixSet{
+ PrefixSetName: "psIPv6",
+ PrefixList: []config.Prefix{
+ config.Prefix{
+ Address: net.ParseIP("2001:123:123::"),
+ Masklength: 48,
+ MasklengthRange: "64..80",
+ }},
+ }
+ nsIPv6 := config.NeighborSet{
+ NeighborSetName: "nsIPv6",
+ NeighborInfoList: []config.NeighborInfo{
+ config.NeighborInfo{
+ Address: net.ParseIP("2001::192:168:50:1"),
+ }},
+ }
+ ds := config.DefinedSets{
+ PrefixSetList: []config.PrefixSet{psIPv4, psIPv6},
+ NeighborSetList: []config.NeighborSet{nsIPv4, nsIPv6},
+ }
+ stIPv4 := config.Statement{
+ Name: "statement1",
+ Conditions: config.Conditions{
+ MatchPrefixSet: "psIPv4",
+ MatchNeighborSet: "nsIPv4",
+ MatchSetOptions: config.MATCH_SET_OPTIONS_TYPE_ALL,
+ },
+ Actions: config.Actions{
+ AcceptRoute: false,
+ RejectRoute: true,
+ },
+ }
+ stIPv6 := config.Statement{
+ Name: "statement2",
+ Conditions: config.Conditions{
+ MatchPrefixSet: "psIPv6",
+ MatchNeighborSet: "nsIPv6",
+ MatchSetOptions: config.MATCH_SET_OPTIONS_TYPE_ALL,
+ },
+ Actions: config.Actions{
+ AcceptRoute: false,
+ RejectRoute: true,
+ },
+ }
+ pd := config.PolicyDefinition{"pd1", []config.Statement{stIPv4, stIPv6}}
+ pl := config.RoutingPolicy{ds, []config.PolicyDefinition{pd}}
+ //test
+ pName := "pd1"
+ df := pl.DefinedSets
+ p := NewPolicy(pName, pl.PolicyDefinitionList[0], df)
+ match1, pType1, newPath1 := p.Apply(pathIPv4)
+ assert.Equal(t, match1, true)
+ assert.Equal(t, pType1, ROUTE_TYPE_REJECT)
+ assert.Equal(t, newPath1, nil)
+
+ match2, pType2, newPath2 := p.Apply(pathIPv6)
+ assert.Equal(t, match2, true)
+ assert.Equal(t, pType2, ROUTE_TYPE_REJECT)
+ assert.Equal(t, newPath2, nil)
+}