diff options
author | Naoto Hanaue <hanaue.naoto@po.ntts.co.jp> | 2015-03-24 19:38:27 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-03-24 19:38:27 +0900 |
commit | 8fb175eb2c3079613a7970e85d1648207c9d829b (patch) | |
tree | abb0646208b9d4598a60aab0f04878599e9978c0 /policy | |
parent | 8d7b670b4ff6cab9e7065ed869b94e42446ecb93 (diff) |
policy: add prefix filter
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Diffstat (limited to 'policy')
-rw-r--r-- | policy/policy.go | 274 | ||||
-rw-r--r-- | policy/policy_test.go | 435 |
2 files changed, 709 insertions, 0 deletions
diff --git a/policy/policy.go b/policy/policy.go new file mode 100644 index 00000000..9bb4bc8c --- /dev/null +++ b/policy/policy.go @@ -0,0 +1,274 @@ +// Copyright (C) 2014,2015 Nippon Telegraph and Telephone Corporation. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +// implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package policy + +import ( + "fmt" + log "github.com/Sirupsen/logrus" + "github.com/osrg/gobgp/config" + "github.com/osrg/gobgp/packet" + "github.com/osrg/gobgp/table" + "net" + "strconv" + "strings" +) + +type RouteType int + +const ( + ROUTE_TYPE_NONE = iota + ROUTE_TYPE_ACCEPT + ROUTE_TYPE_REJECT +) + +type MaskLengthRangeType int + +const ( + MASK_LENGTH_RANGE_MIN = iota + MASK_LENGTH_RANGE_MAX +) + +type Policy struct { + Name string + Statements []Statement +} + +func NewPolicy(name string, pd config.PolicyDefinition, cdf config.DefinedSets) *Policy { + cst := pd.StatementList + st := make([]Statement, 0) + p := &Policy{ + Name: name, + Statements: st, + } + for _, cs := range cst { + pName := cs.Conditions.MatchPrefixSet + npl := make([]Prefix, 0) + for _, psl := range cdf.PrefixSetList { + if psl.PrefixSetName == pName { + for _, ps := range psl.PrefixList { + npl = append(npl, NewPrefix(ps.Address, ps.Masklength, ps.MasklengthRange)) + } + } + } + nName := cs.Conditions.MatchNeighborSet + nnl := make([]net.IP, 0) + for _, nsl := range cdf.NeighborSetList { + if nsl.NeighborSetName == nName { + for _, nl := range nsl.NeighborInfoList { + nnl = append(nnl, nl.Address) + } + } + } + con := Conditions{ + PrefixList: npl, + NeighborList: nnl, + } + act := Actions{ + AcceptRoute: cs.Actions.AcceptRoute, + RejectRoute: cs.Actions.RejectRoute, + } + s := Statement{ + Name: cs.Name, + Conditions: con, + Actions: act, + } + st = append(st, s) + } + p.Statements = st + return p +} + +type Statement struct { + Name string + Conditions Conditions + Actions Actions +} + +type Conditions struct { + //CallPolicy string + PrefixList []Prefix + NeighborList []net.IP +} + +type Actions struct { + AcceptRoute bool + RejectRoute bool +} + +type Prefix struct { + Address net.IP + Masklength uint8 + MasklengthRange map[MaskLengthRangeType]uint8 +} + +func NewPrefix(addr net.IP, maskLen uint8, maskRange string) Prefix { + mlr := make(map[MaskLengthRangeType]uint8) + p := Prefix{ + Address: addr, + Masklength: maskLen, + MasklengthRange: make(map[MaskLengthRangeType]uint8), + } + 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") + return p + } + 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 + } + 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 + } + mlr[MASK_LENGTH_RANGE_MAX] = uint8(max) + } + p.MasklengthRange = mlr + return p +} + +//compare path and condition of policy +//and, subsequent comparison skip if that matches the conditions. +func (p *Policy) Apply(path table.Path) (bool, RouteType, table.Path) { + for _, statement := range p.Statements { + matchPrefix := false + matchNeighbor := false + if len(statement.Conditions.PrefixList) <= 0 && len(statement.Conditions.NeighborList) <= 0 { + return false, ROUTE_TYPE_NONE, nil + } else if len(statement.Conditions.PrefixList) <= 0 && len(statement.Conditions.NeighborList) > 0 { + matchPrefix = true + matchNeighbor = statement.compareNeighbor(path) + } else if len(statement.Conditions.NeighborList) <= 0 && len(statement.Conditions.PrefixList) > 0 { + matchPrefix = statement.comparePrefix(path) + matchNeighbor = true + } else { + matchPrefix = statement.comparePrefix(path) + matchNeighbor = statement.compareNeighbor(path) + } + an := statement.Actions + + //if match the one of the prefix list and match to any of tye neighbor list, + //determines that matches the conditions of the statement + if matchPrefix && matchNeighbor { + if an.AcceptRoute { + // accept the path + // and return the path updated in acction definition + // TODO update path using acction definition. + // implementation waiting for yang. + newPath := path + log.WithFields(log.Fields{ + "Topic": "Policy", + "Type": "ROUTE_ACCEPT", + "OldPath": path, + "NewPath": newPath, + }).Debug("Apply policy to path") + return true, ROUTE_TYPE_ACCEPT, newPath + + } else { + // reject the path + // and return the path updated in acction definition + // TODO update path using acction definition. + // implementation waiting for yang. + newPath := path + log.WithFields(log.Fields{ + "Topic": "Policy", + "Type": "ROUTE_REJECT", + "OldPath": path, + "NewPath": newPath, + }).Debug("Apply policy to path") + return true, ROUTE_TYPE_REJECT, nil + } + } + } + return false, ROUTE_TYPE_NONE, nil +} + +//compare prefix of condition policy and nlri of path +//and, subsequent comparison skip if that matches the conditions. +func (s *Statement) comparePrefix(path table.Path) bool { + for _, cp := range s.Conditions.PrefixList { + if IpPrefixCalcurate(path, cp) { + return true + } + } + return false +} + +//compare neighbor ipaddress of condition policy and source of path +//and, subsequent comparison skip if that matches the conditions. +func (s *Statement) compareNeighbor(path table.Path) bool { + for _, neighbor := range s.Conditions.NeighborList { + cAddr := neighbor + pAddr := path.GetSource().Address + if pAddr.Equal(cAddr) { + return true + } + + } + return false +} + +func IpPrefixCalcurate(path table.Path, cPrefix Prefix) bool { + pAddr := path.GetNlri().(*bgp.NLRInfo).IPAddrPrefix.Prefix + pMaskLen := path.GetNlri().(*bgp.NLRInfo).IPAddrPrefix.Length + 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 { + return true + } else { + return false + } + } else if !okMin { + rMin = uint8(0) + } else if !okMax { + rMax = uint8(32) + } + + _, ipNet, e := net.ParseCIDR(cp) + if e != nil { + log.WithFields(log.Fields{ + "Topic": "Policy", + "Prefix": ipNet, + "Error": e, + }).Error("failed to parse the prefix of condition") + return false + } + if ipNet.Contains(pAddr) && (rMin <= pMaskLen && pMaskLen <= rMax) { + return true + } + return false +} diff --git a/policy/policy_test.go b/policy/policy_test.go new file mode 100644 index 00000000..34c6c5ef --- /dev/null +++ b/policy/policy_test.go @@ -0,0 +1,435 @@ +// Copyright (C) 2014,2015 Nippon Telegraph and Telephone Corporation. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +// implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package policy + +import ( + "github.com/osrg/gobgp/config" + "github.com/osrg/gobgp/packet" + "github.com/osrg/gobgp/table" + "github.com/stretchr/testify/assert" + "net" + "testing" +) + +func TestPrefixCalcurateNoRange(t *testing.T) { + // creatae path + peer := &table.PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")} + origin := bgp.NewPathAttributeOrigin(0) + aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})} + aspath := bgp.NewPathAttributeAsPath(aspathParam) + nexthop := bgp.NewPathAttributeNextHop("10.0.0.1") + med := bgp.NewPathAttributeMultiExitDisc(0) + pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med} + nlri := []bgp.NLRInfo{*bgp.NewNLRInfo(24, "10.10.0.101")} + withdrawnRoutes := []bgp.WithdrawnRoute{} + updateMsg := bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes, nlri) + msg := table.NewProcessMessage(updateMsg, peer) + path := msg.ToPathList()[0] + // test + pl1 := NewPrefix(net.ParseIP("10.10.0.0"), 24, "") + match1 := IpPrefixCalcurate(path, pl1) + assert.Equal(t, match1, false) + pl2 := NewPrefix(net.ParseIP("10.10.0.101"), 24, "") + match2 := IpPrefixCalcurate(path, pl2) + assert.Equal(t, match2, true) + pl3 := NewPrefix(net.ParseIP("10.10.0.0"), 16, "21..24") + match3 := IpPrefixCalcurate(path, pl3) + assert.Equal(t, match3, true) +} + +func TestPrefixCalcurateInAddress(t *testing.T) { + // creatae path + peer := &table.PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")} + origin := bgp.NewPathAttributeOrigin(0) + aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})} + aspath := bgp.NewPathAttributeAsPath(aspathParam) + nexthop := bgp.NewPathAttributeNextHop("10.0.0.1") + med := bgp.NewPathAttributeMultiExitDisc(0) + pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med} + nlri := []bgp.NLRInfo{*bgp.NewNLRInfo(24, "10.10.0.101")} + withdrawnRoutes := []bgp.WithdrawnRoute{} + updateMsg := bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes, nlri) + msg := table.NewProcessMessage(updateMsg, peer) + path := msg.ToPathList()[0] + // test + pl1 := NewPrefix(net.ParseIP("10.11.0.0"), 16, "21..24") + match1 := IpPrefixCalcurate(path, pl1) + assert.Equal(t, match1, false) + pl2 := NewPrefix(net.ParseIP("10.10.0.0"), 16, "21..24") + match2 := IpPrefixCalcurate(path, pl2) + assert.Equal(t, match2, true) +} + +func TestPrefixCalcurateInLength(t *testing.T) { + // creatae path + peer := &table.PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")} + origin := bgp.NewPathAttributeOrigin(0) + aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})} + aspath := bgp.NewPathAttributeAsPath(aspathParam) + nexthop := bgp.NewPathAttributeNextHop("10.0.0.1") + med := bgp.NewPathAttributeMultiExitDisc(0) + pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med} + nlri := []bgp.NLRInfo{*bgp.NewNLRInfo(24, "10.10.0.101")} + withdrawnRoutes := []bgp.WithdrawnRoute{} + updateMsg := bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes, nlri) + msg := table.NewProcessMessage(updateMsg, peer) + path := msg.ToPathList()[0] + // test + pl1 := NewPrefix(net.ParseIP("10.10.64.0"), 24, "21..24") + match1 := IpPrefixCalcurate(path, pl1) + assert.Equal(t, match1, false) + pl2 := NewPrefix(net.ParseIP("10.10.64.0"), 16, "21..24") + match2 := IpPrefixCalcurate(path, pl2) + assert.Equal(t, match2, true) +} + +func TestPrefixCalcurateInLengthRange(t *testing.T) { + // creatae path + peer := &table.PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")} + origin := bgp.NewPathAttributeOrigin(0) + aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})} + aspath := bgp.NewPathAttributeAsPath(aspathParam) + nexthop := bgp.NewPathAttributeNextHop("10.0.0.1") + med := bgp.NewPathAttributeMultiExitDisc(0) + pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med} + nlri := []bgp.NLRInfo{*bgp.NewNLRInfo(24, "10.10.0.101")} + withdrawnRoutes := []bgp.WithdrawnRoute{} + updateMsg := bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes, nlri) + msg := table.NewProcessMessage(updateMsg, peer) + path := msg.ToPathList()[0] + // test + pl1 := NewPrefix(net.ParseIP("10.10.0.0"), 16, "21..23") + match1 := IpPrefixCalcurate(path, pl1) + assert.Equal(t, match1, false) + pl2 := NewPrefix(net.ParseIP("10.10.0.0"), 16, "25..26") + match2 := IpPrefixCalcurate(path, pl2) + assert.Equal(t, match2, false) + pl3 := NewPrefix(net.ParseIP("10.10.0.0"), 16, "21..24") + match3 := IpPrefixCalcurate(path, pl3) + assert.Equal(t, match3, true) +} + +func TestPolicyNotMatchL(t *testing.T) { + // creatae path + peer := &table.PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")} + origin := bgp.NewPathAttributeOrigin(0) + aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})} + aspath := bgp.NewPathAttributeAsPath(aspathParam) + nexthop := bgp.NewPathAttributeNextHop("10.0.0.1") + med := bgp.NewPathAttributeMultiExitDisc(0) + pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med} + nlri := []bgp.NLRInfo{*bgp.NewNLRInfo(24, "10.10.0.101")} + withdrawnRoutes := []bgp.WithdrawnRoute{} + updateMsg := bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes, nlri) + msg := table.NewProcessMessage(updateMsg, peer) + path := msg.ToPathList()[0] + // create policy + ps := config.PrefixSet{ + PrefixSetName: "ps1", + PrefixList: []config.Prefix{ + config.Prefix{ + Address: net.ParseIP("10.3.0.0"), + Masklength: 16, + MasklengthRange: "21..24", + }}, + } + ns := config.NeighborSet{ + NeighborSetName: "ns1", + NeighborInfoList: []config.NeighborInfo{ + config.NeighborInfo{ + Address: net.ParseIP("10.0.0.1"), + }}, + } + ds := config.DefinedSets{ + PrefixSetList: []config.PrefixSet{ps}, + NeighborSetList: []config.NeighborSet{ns}, + } + s := config.Statement{ + Name: "statement1", + Conditions: config.Conditions{ + MatchPrefixSet: "ps1", + MatchNeighborSet: "ns1", + }, + Actions: config.Actions{ + AcceptRoute: false, + RejectRoute: true, + }, + } + pd := config.PolicyDefinition{"pd1", []config.Statement{s}} + pl := config.RoutingPolicy{ds, []config.PolicyDefinition{pd}} + //test + pName := "pd1" + df := pl.DefinedSets + p := NewPolicy(pName, pl.PolicyDefinitionList[0], df) + match, pType, newPath := p.Apply(path) + assert.Equal(t, match, false) + assert.Equal(t, pType, ROUTE_TYPE_NONE) + assert.Equal(t, newPath, nil) +} + +func TestPolicyMatchAndReject(t *testing.T) { + // creatae path + peer := &table.PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")} + origin := bgp.NewPathAttributeOrigin(0) + aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})} + aspath := bgp.NewPathAttributeAsPath(aspathParam) + nexthop := bgp.NewPathAttributeNextHop("10.0.0.1") + med := bgp.NewPathAttributeMultiExitDisc(0) + pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med} + nlri := []bgp.NLRInfo{*bgp.NewNLRInfo(24, "10.10.0.101")} + withdrawnRoutes := []bgp.WithdrawnRoute{} + updateMsg := bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes, nlri) + msg := table.NewProcessMessage(updateMsg, peer) + path := msg.ToPathList()[0] + // create policy + ps := config.PrefixSet{ + PrefixSetName: "ps1", + PrefixList: []config.Prefix{ + config.Prefix{ + Address: net.ParseIP("10.10.0.0"), + Masklength: 16, + MasklengthRange: "21..24", + }}, + } + ns := config.NeighborSet{ + NeighborSetName: "ns1", + NeighborInfoList: []config.NeighborInfo{ + config.NeighborInfo{ + Address: net.ParseIP("10.0.0.1"), + }}, + } + ds := config.DefinedSets{ + PrefixSetList: []config.PrefixSet{ps}, + NeighborSetList: []config.NeighborSet{ns}, + } + s := config.Statement{ + Name: "statement1", + Conditions: config.Conditions{ + MatchPrefixSet: "ps1", + MatchNeighborSet: "ns1", + }, + Actions: config.Actions{ + AcceptRoute: false, + RejectRoute: true, + }, + } + pd := config.PolicyDefinition{"pd1", []config.Statement{s}} + pl := config.RoutingPolicy{ds, []config.PolicyDefinition{pd}} + //test + pName := "pd1" + df := pl.DefinedSets + p := NewPolicy(pName, pl.PolicyDefinitionList[0], df) + match, pType, newPath := p.Apply(path) + assert.Equal(t, match, true) + assert.Equal(t, pType, ROUTE_TYPE_REJECT) + assert.Equal(t, newPath, nil) +} + +func TestPolicyMatchAndAccept(t *testing.T) { + // creatae path + peer := &table.PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")} + origin := bgp.NewPathAttributeOrigin(0) + aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})} + aspath := bgp.NewPathAttributeAsPath(aspathParam) + nexthop := bgp.NewPathAttributeNextHop("10.0.0.1") + med := bgp.NewPathAttributeMultiExitDisc(0) + pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med} + nlri := []bgp.NLRInfo{*bgp.NewNLRInfo(24, "10.10.0.101")} + withdrawnRoutes := []bgp.WithdrawnRoute{} + updateMsg := bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes, nlri) + msg := table.NewProcessMessage(updateMsg, peer) + path := msg.ToPathList()[0] + // create policy + ps := config.PrefixSet{ + PrefixSetName: "ps1", + PrefixList: []config.Prefix{ + config.Prefix{ + Address: net.ParseIP("10.10.0.0"), + Masklength: 16, + MasklengthRange: "21..24", + }}, + } + ns := config.NeighborSet{ + NeighborSetName: "ns1", + NeighborInfoList: []config.NeighborInfo{ + config.NeighborInfo{ + Address: net.ParseIP("10.0.0.1"), + }}, + } + ds := config.DefinedSets{ + PrefixSetList: []config.PrefixSet{ps}, + NeighborSetList: []config.NeighborSet{ns}, + } + s := config.Statement{ + Name: "statement1", + Conditions: config.Conditions{ + MatchPrefixSet: "ps1", + MatchNeighborSet: "ns1", + }, + Actions: config.Actions{ + AcceptRoute: true, + RejectRoute: false, + }, + } + pd := config.PolicyDefinition{"pd1", []config.Statement{s}} + pl := config.RoutingPolicy{ds, []config.PolicyDefinition{pd}} + //test + pName := "pd1" + df := pl.DefinedSets + p := NewPolicy(pName, pl.PolicyDefinitionList[0], df) + match, pType, newPath := p.Apply(path) + assert.Equal(t, match, true) + assert.Equal(t, pType, ROUTE_TYPE_ACCEPT) + assert.Equal(t, newPath, path) +} + +func TestPolicyRejectOnlyPrefixList(t *testing.T) { + // creatae path + peer := &table.PeerInfo{AS: 65001, Address: net.ParseIP("10.0.1.1")} + origin := bgp.NewPathAttributeOrigin(0) + aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})} + aspath := bgp.NewPathAttributeAsPath(aspathParam) + nexthop := bgp.NewPathAttributeNextHop("10.0.1.1") + med := bgp.NewPathAttributeMultiExitDisc(0) + pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med} + nlri := []bgp.NLRInfo{*bgp.NewNLRInfo(24, "10.10.1.101")} + withdrawnRoutes := []bgp.WithdrawnRoute{} + updateMsg := bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes, nlri) + msg := table.NewProcessMessage(updateMsg, peer) + path1 := msg.ToPathList()[0] + + peer = &table.PeerInfo{AS: 65002, Address: net.ParseIP("10.0.2.2")} + origin = bgp.NewPathAttributeOrigin(0) + aspathParam = []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65002})} + aspath = bgp.NewPathAttributeAsPath(aspathParam) + nexthop = bgp.NewPathAttributeNextHop("10.0.2.2") + med = bgp.NewPathAttributeMultiExitDisc(0) + pathAttributes = []bgp.PathAttributeInterface{origin, aspath, nexthop, med} + nlri = []bgp.NLRInfo{*bgp.NewNLRInfo(24, "10.10.2.102")} + withdrawnRoutes = []bgp.WithdrawnRoute{} + updateMsg = bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes, nlri) + msg = table.NewProcessMessage(updateMsg, peer) + path2 := msg.ToPathList()[0] + + // create policy + ps := config.PrefixSet{ + PrefixSetName: "ps1", + PrefixList: []config.Prefix{ + config.Prefix{ + Address: net.ParseIP("10.10.1.0"), + Masklength: 24, + MasklengthRange: "21..24", + }}, + } + ds := config.DefinedSets{ + PrefixSetList: []config.PrefixSet{ps}, + NeighborSetList: []config.NeighborSet{}, + } + s := config.Statement{ + Name: "statement1", + Conditions: config.Conditions{ + MatchPrefixSet: "ps1", + MatchNeighborSet: "ns1", + }, + Actions: config.Actions{ + AcceptRoute: false, + RejectRoute: true, + }, + } + pd := config.PolicyDefinition{"pd1", []config.Statement{s}} + pl := config.RoutingPolicy{ds, []config.PolicyDefinition{pd}} + //test + pName := "pd1" + df := pl.DefinedSets + p := NewPolicy(pName, pl.PolicyDefinitionList[0], df) + match, pType, newPath := p.Apply(path1) + assert.Equal(t, match, true) + assert.Equal(t, pType, ROUTE_TYPE_REJECT) + assert.Equal(t, newPath, nil) + + match2, pType2, newPath2 := p.Apply(path2) + assert.Equal(t, match2, false) + assert.Equal(t, pType2, ROUTE_TYPE_NONE) + assert.Equal(t, newPath2, nil) +} + +func TestPolicyRejectOnlyNeighborList(t *testing.T) { + // creatae path + peer := &table.PeerInfo{AS: 65001, Address: net.ParseIP("10.0.1.1")} + origin := bgp.NewPathAttributeOrigin(0) + aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})} + aspath := bgp.NewPathAttributeAsPath(aspathParam) + nexthop := bgp.NewPathAttributeNextHop("10.0.1.1") + med := bgp.NewPathAttributeMultiExitDisc(0) + pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med} + nlri := []bgp.NLRInfo{*bgp.NewNLRInfo(24, "10.10.1.101")} + withdrawnRoutes := []bgp.WithdrawnRoute{} + updateMsg := bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes, nlri) + msg := table.NewProcessMessage(updateMsg, peer) + path1 := msg.ToPathList()[0] + + peer = &table.PeerInfo{AS: 65002, Address: net.ParseIP("10.0.2.2")} + origin = bgp.NewPathAttributeOrigin(0) + aspathParam = []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65002})} + aspath = bgp.NewPathAttributeAsPath(aspathParam) + nexthop = bgp.NewPathAttributeNextHop("10.0.2.2") + med = bgp.NewPathAttributeMultiExitDisc(0) + pathAttributes = []bgp.PathAttributeInterface{origin, aspath, nexthop, med} + nlri = []bgp.NLRInfo{*bgp.NewNLRInfo(24, "10.10.2.102")} + withdrawnRoutes = []bgp.WithdrawnRoute{} + updateMsg = bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes, nlri) + msg = table.NewProcessMessage(updateMsg, peer) + path2 := msg.ToPathList()[0] + + // create policy + ns := config.NeighborSet{ + NeighborSetName: "ns1", + NeighborInfoList: []config.NeighborInfo{ + config.NeighborInfo{ + Address: net.ParseIP("10.0.1.1"), + }}, + } + ds := config.DefinedSets{ + PrefixSetList: []config.PrefixSet{}, + NeighborSetList: []config.NeighborSet{ns}, + } + s := config.Statement{ + Name: "statement1", + Conditions: config.Conditions{ + MatchPrefixSet: "ps1", + MatchNeighborSet: "ns1", + }, + Actions: config.Actions{ + AcceptRoute: false, + RejectRoute: true, + }, + } + pd := config.PolicyDefinition{"pd1", []config.Statement{s}} + pl := config.RoutingPolicy{ds, []config.PolicyDefinition{pd}} + //test + pName := "pd1" + df := pl.DefinedSets + p := NewPolicy(pName, pl.PolicyDefinitionList[0], df) + match, pType, newPath := p.Apply(path1) + assert.Equal(t, match, true) + assert.Equal(t, pType, ROUTE_TYPE_REJECT) + assert.Equal(t, newPath, nil) + + match2, pType2, newPath2 := p.Apply(path2) + assert.Equal(t, match2, false) + assert.Equal(t, pType2, ROUTE_TYPE_NONE) + assert.Equal(t, newPath2, nil) +} |