diff options
author | Naoto Hanaue <hanaue.naoto@po.ntts.co.jp> | 2015-03-20 15:30:39 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-03-24 22:26:42 +0900 |
commit | 5902ba02e8f804da9363bc99654e0e8292f006c7 (patch) | |
tree | e6137816bb806f0f339d05ba2c189bca76e45450 | |
parent | dd1600a08288e3276526c0c266df41c57d19bc8a (diff) |
policy: support ipv6 and add test code
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | policy/policy.go | 76 | ||||
-rw-r--r-- | policy/policy_test.go | 241 |
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) +} |