diff options
-rw-r--r-- | policy/policy.go | 274 | ||||
-rw-r--r-- | policy/policy_test.go | 435 | ||||
-rw-r--r-- | table/destination.go | 20 | ||||
-rw-r--r-- | table/destination_test.go | 10 | ||||
-rw-r--r-- | table/message.go | 10 | ||||
-rw-r--r-- | table/path.go | 16 | ||||
-rw-r--r-- | table/path_test.go | 10 | ||||
-rw-r--r-- | table/table.go | 8 | ||||
-rw-r--r-- | table/table_manager.go | 10 | ||||
-rw-r--r-- | table/table_test.go | 24 |
10 files changed, 763 insertions, 54 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) +} diff --git a/table/destination.go b/table/destination.go index f805d5e3..a79daa2b 100644 --- a/table/destination.go +++ b/table/destination.go @@ -182,7 +182,7 @@ func (dd *DestinationDefault) removeOldPathsFromSource(source *PeerInfo) []Path tempKnownPathList := make([]Path, 0) for _, path := range dd.knownPathList { - if path.getSource() == source { + if path.GetSource() == source { removePaths = append(removePaths, path) } else { tempKnownPathList = append(tempKnownPathList, path) @@ -301,7 +301,7 @@ func (dest *DestinationDefault) removeWithdrawls() { for _, path := range dest.knownPathList { // We have a match if the source are same. // TODO add GetSource to Path interface - if path.getSource() == withdraw.getSource() { + if path.GetSource() == withdraw.GetSource() { isFound = true matches[path.String()] = path wMatches[withdraw.String()] = withdraw @@ -400,7 +400,7 @@ func (dest *DestinationDefault) removeOldPaths() { // version num. as newPaths are implicit withdrawal of old // paths and when doing RouteRefresh (not EnhancedRouteRefresh) // we get same paths again. - if newPath.getSource() == path.getSource() { + if newPath.GetSource() == path.GetSource() { oldPaths = append(oldPaths, path) break } @@ -596,17 +596,17 @@ func compareByLocalOrigin(path1, path2 Path) Path { // """ // # If both paths are from same sources we cannot compare them here. log.Debugf("enter compareByLocalOrigin") - if path1.getSource() == path2.getSource() { + if path1.GetSource() == path2.GetSource() { return nil } // # Here we consider prefix from NC as locally originating static route. // # Hence it is preferred. - if path1.getSource() == nil { + if path1.GetSource() == nil { return path1 } - if path2.getSource() == nil { + if path2.GetSource() == nil { return path2 } return nil @@ -726,10 +726,10 @@ func compareByASNumber(localAsn uint32, path1, path2 Path) Path { log.Debugf("enter compareByASNumber") getPathSourceAsn := func(path Path) uint32 { var asn uint32 - if path.getSource() == nil { + if path.GetSource() == nil { asn = localAsn } else { - asn = path.getSource().AS + asn = path.GetSource().AS } return asn } @@ -786,8 +786,8 @@ func compareByRouterID(localAsn uint32, path1, path2 Path) (Path, error) { } } - pathSource1 := path1.getSource() - pathSource2 := path2.getSource() + pathSource1 := path1.GetSource() + pathSource2 := path2.GetSource() // If both paths are from NC we have same router Id, hence cannot compare. if pathSource1 == nil && pathSource2 == nil { diff --git a/table/destination_test.go b/table/destination_test.go index 5dbab4d0..7205876a 100644 --- a/table/destination_test.go +++ b/table/destination_test.go @@ -28,14 +28,14 @@ func TestDestinationNewIPv4(t *testing.T) { peerD := DestCreatePeer() msgD := DestCreateMSG(peerD) pathD := DestCreatePath(msgD) - ipv4d := NewIPv4Destination(pathD[0].getNlri()) + ipv4d := NewIPv4Destination(pathD[0].GetNlri()) assert.NotNil(t, ipv4d) } func TestDestinationNewIPv6(t *testing.T) { peerD := DestCreatePeer() msgD := DestCreateMSG(peerD) pathD := DestCreatePath(msgD) - ipv6d := NewIPv6Destination(pathD[0].getNlri()) + ipv6d := NewIPv6Destination(pathD[0].GetNlri()) assert.NotNil(t, ipv6d) } @@ -83,7 +83,7 @@ func TestDestinationSetBestPath(t *testing.T) { peerD := DestCreatePeer() msgD := DestCreateMSG(peerD) pathD := DestCreatePath(msgD) - ipv4d := NewIPv4Destination(pathD[0].getNlri()) + ipv4d := NewIPv4Destination(pathD[0].GetNlri()) ipv4d.setBestPath(pathD[0]) r_pathD := ipv4d.getBestPath() assert.Equal(t, r_pathD, pathD[0]) @@ -92,7 +92,7 @@ func TestDestinationGetBestPath(t *testing.T) { peerD := DestCreatePeer() msgD := DestCreateMSG(peerD) pathD := DestCreatePath(msgD) - ipv4d := NewIPv4Destination(pathD[0].getNlri()) + ipv4d := NewIPv4Destination(pathD[0].GetNlri()) ipv4d.setBestPath(pathD[0]) r_pathD := ipv4d.getBestPath() assert.Equal(t, r_pathD, pathD[0]) @@ -101,7 +101,7 @@ func TestDestinationCalculate(t *testing.T) { peerD := DestCreatePeer() msgD := DestCreateMSG(peerD) pathD := DestCreatePath(msgD) - ipv4d := NewIPv4Destination(pathD[0].getNlri()) + ipv4d := NewIPv4Destination(pathD[0].GetNlri()) //best path selection ipv4d.addNewPath(pathD[0]) ipv4d.addNewPath(pathD[1]) diff --git a/table/message.go b/table/message.go index 10bf0afd..223aeabc 100644 --- a/table/message.go +++ b/table/message.go @@ -143,7 +143,7 @@ func createUpdateMsgFromPath(path Path, msg *bgp.BGPMessage) *bgp.BGPMessage { if rf == bgp.RF_IPv4_UC { if path.IsWithdraw() { - draw := path.getNlri().(*bgp.WithdrawnRoute) + draw := path.GetNlri().(*bgp.WithdrawnRoute) if msg != nil { u := msg.Body.(*bgp.BGPUpdate) u.WithdrawnRoutes = append(u.WithdrawnRoutes, *draw) @@ -152,7 +152,7 @@ func createUpdateMsgFromPath(path Path, msg *bgp.BGPMessage) *bgp.BGPMessage { return bgp.NewBGPUpdateMessage([]bgp.WithdrawnRoute{*draw}, []bgp.PathAttributeInterface{}, []bgp.NLRInfo{}) } } else { - nlri := path.getNlri().(*bgp.NLRInfo) + nlri := path.GetNlri().(*bgp.NLRInfo) if msg != nil { u := msg.Body.(*bgp.BGPUpdate) u.NLRI = append(u.NLRI, *nlri) @@ -167,7 +167,7 @@ func createUpdateMsgFromPath(path Path, msg *bgp.BGPMessage) *bgp.BGPMessage { idx, _ := path.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI) u := msg.Body.(*bgp.BGPUpdate) unreach := u.PathAttributes[idx].(*bgp.PathAttributeMpUnreachNLRI) - unreach.Value = append(unreach.Value, path.getNlri()) + unreach.Value = append(unreach.Value, path.GetNlri()) } else { clonedAttrs := cloneAttrSlice(path.getPathAttrs()) idx, attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI) @@ -181,7 +181,7 @@ func createUpdateMsgFromPath(path Path, msg *bgp.BGPMessage) *bgp.BGPMessage { u := msg.Body.(*bgp.BGPUpdate) reachAttr := u.PathAttributes[idx].(*bgp.PathAttributeMpReachNLRI) u.PathAttributes[idx] = bgp.NewPathAttributeMpReachNLRI(reachAttr.Nexthop.String(), - append(reachAttr.Value, path.getNlri())) + append(reachAttr.Value, path.GetNlri())) } else { // we don't need to clone here but we // might merge path to this message in @@ -221,7 +221,7 @@ func isMergeable(p1 Path, p2 Path) bool { if p1.GetRouteFamily() != bgp.RF_IPv4_UC { return false } - if p1.getSource() == p2.getSource() && isSamePathAttrs(p1.getPathAttrs(), p2.getPathAttrs()) { + if p1.GetSource() == p2.GetSource() && isSamePathAttrs(p1.getPathAttrs(), p2.getPathAttrs()) { return true } return false diff --git a/table/path.go b/table/path.go index 63da8c40..e4daa9de 100644 --- a/table/path.go +++ b/table/path.go @@ -33,12 +33,12 @@ type Path interface { updatePathAttrs(global *config.Global, peer *config.Neighbor) GetRouteFamily() bgp.RouteFamily setSource(source *PeerInfo) - getSource() *PeerInfo + GetSource() *PeerInfo setNexthop(nexthop net.IP) GetNexthop() net.IP setWithdraw(withdraw bool) IsWithdraw() bool - getNlri() bgp.AddrPrefixInterface + GetNlri() bgp.AddrPrefixInterface getPrefix() string setMedSetByTargetNeighbor(medSetByTargetNeighbor bool) getMedSetByTargetNeighbor() bool @@ -217,7 +217,7 @@ func (pd *PathDefault) GetRouteFamily() bgp.RouteFamily { func (pd *PathDefault) setSource(source *PeerInfo) { pd.source = source } -func (pd *PathDefault) getSource() *PeerInfo { +func (pd *PathDefault) GetSource() *PeerInfo { return pd.source } @@ -237,7 +237,7 @@ func (pd *PathDefault) IsWithdraw() bool { return pd.withdraw } -func (pd *PathDefault) getNlri() bgp.AddrPrefixInterface { +func (pd *PathDefault) GetNlri() bgp.AddrPrefixInterface { return pd.nlri } @@ -282,7 +282,7 @@ func (pd *PathDefault) getPathAttr(pattrType bgp.BGPAttrType) (int, bgp.PathAttr // return Path's string representation func (pi *PathDefault) String() string { - str := fmt.Sprintf("IPv4Path Source: %v, ", pi.getSource()) + str := fmt.Sprintf("IPv4Path Source: %v, ", pi.GetSource()) str = str + fmt.Sprintf(" NLRI: %s, ", pi.getPrefix()) str = str + fmt.Sprintf(" nexthop: %s, ", pi.GetNexthop().String()) str = str + fmt.Sprintf(" withdraw: %s, ", pi.IsWithdraw()) @@ -383,7 +383,7 @@ func (ipv6p *IPv6Path) getPrefix() string { // return IPv6Path's string representation func (ipv6p *IPv6Path) String() string { - str := fmt.Sprintf("IPv6Path Source: %v, ", ipv6p.getSource()) + str := fmt.Sprintf("IPv6Path Source: %v, ", ipv6p.GetSource()) str = str + fmt.Sprintf(" NLRI: %s, ", ipv6p.getPrefix()) str = str + fmt.Sprintf(" nexthop: %s, ", ipv6p.GetNexthop().String()) str = str + fmt.Sprintf(" withdraw: %s, ", ipv6p.IsWithdraw()) @@ -439,7 +439,7 @@ func (ipv4vpnp *IPv4VPNPath) getPrefix() string { // return IPv4VPNPath's string representation func (ipv4vpnp *IPv4VPNPath) String() string { - str := fmt.Sprintf("IPv4VPNPath Source: %v, ", ipv4vpnp.getSource()) + str := fmt.Sprintf("IPv4VPNPath Source: %v, ", ipv4vpnp.GetSource()) str = str + fmt.Sprintf(" NLRI: %s, ", ipv4vpnp.getPrefix()) str = str + fmt.Sprintf(" nexthop: %s, ", ipv4vpnp.GetNexthop().String()) str = str + fmt.Sprintf(" withdraw: %s, ", ipv4vpnp.IsWithdraw()) @@ -496,7 +496,7 @@ func (evpnp *EVPNPath) getPrefix() string { // return EVPNPath's string representation func (evpnp *EVPNPath) String() string { - str := fmt.Sprintf("EVPNPath Source: %v, ", evpnp.getSource()) + str := fmt.Sprintf("EVPNPath Source: %v, ", evpnp.GetSource()) str = str + fmt.Sprintf(" NLRI: %s, ", evpnp.getPrefix()) str = str + fmt.Sprintf(" nexthop: %s, ", evpnp.GetNexthop().String()) str = str + fmt.Sprintf(" withdraw: %s, ", evpnp.IsWithdraw()) diff --git a/table/path_test.go b/table/path_test.go index 2dc0c3de..d7d6a660 100644 --- a/table/path_test.go +++ b/table/path_test.go @@ -14,14 +14,14 @@ func TestPathNewIPv4(t *testing.T) { peerP := PathCreatePeer() msgP := PathCreateMSG(peerP) pathP := PathCreatePath(msgP) - ipv4p := NewIPv4Path(pathP[0].getSource(), pathP[0].getNlri(), true, pathP[0].getPathAttrs(), pathP[0].getMedSetByTargetNeighbor(), time.Now()) + ipv4p := NewIPv4Path(pathP[0].GetSource(), pathP[0].GetNlri(), true, pathP[0].getPathAttrs(), pathP[0].getMedSetByTargetNeighbor(), time.Now()) assert.NotNil(t, ipv4p) } func TestPathNewIPv6(t *testing.T) { peerP := PathCreatePeer() msgP := PathCreateMSG(peerP) pathP := PathCreatePath(msgP) - ipv6p := NewIPv6Path(pathP[0].getSource(), pathP[0].getNlri(), true, pathP[0].getPathAttrs(), pathP[0].getMedSetByTargetNeighbor(), time.Now()) + ipv6p := NewIPv6Path(pathP[0].GetSource(), pathP[0].GetNlri(), true, pathP[0].getPathAttrs(), pathP[0].getMedSetByTargetNeighbor(), time.Now()) assert.NotNil(t, ipv6p) } @@ -67,7 +67,7 @@ func TestPathSetSource(t *testing.T) { pd := &PathDefault{} pr := &PeerInfo{AS: 65000} pd.setSource(pr) - r_pr := pd.getSource() + r_pr := pd.GetSource() assert.Equal(t, r_pr, pr) } @@ -75,7 +75,7 @@ func TestPathGetSource(t *testing.T) { pd := &PathDefault{} pr := &PeerInfo{AS: 65001} pd.setSource(pr) - r_pr := pd.getSource() + r_pr := pd.GetSource() assert.Equal(t, r_pr, pr) } @@ -116,7 +116,7 @@ func TestPathGetNlri(t *testing.T) { pd := &PathDefault{ nlri: nlri, } - r_nlri := pd.getNlri() + r_nlri := pd.GetNlri() assert.Equal(t, r_nlri, nlri) } diff --git a/table/table.go b/table/table.go index 47e42fbb..656f132c 100644 --- a/table/table.go +++ b/table/table.go @@ -101,8 +101,8 @@ func insert(table Table, path Path) Destination { var dest Destination table.validatePath(path) - table.validateNlri(path.getNlri()) - dest = getOrCreateDest(table, path.getNlri()) + table.validateNlri(path.GetNlri()) + dest = getOrCreateDest(table, path.GetNlri()) if path.IsWithdraw() { // withdraw insert @@ -136,7 +136,7 @@ func (td *TableDefault) DeleteDestByPeer(peerInfo *PeerInfo) []Destination { for _, dest := range td.destinations { newKnownPathList := make([]Path, 0) for _, p := range dest.getKnownPathList() { - if p.getSource() != peerInfo { + if p.GetSource() != peerInfo { newKnownPathList = append(newKnownPathList, p) } } @@ -174,7 +174,7 @@ func (td *TableDefault) validatePath(path Path) { log.WithFields(log.Fields{ "Topic": "Table", "Key": td.ROUTE_FAMILY, - "Prefix": path.getNlri().String(), + "Prefix": path.GetNlri().String(), "ReceivedRf": path.GetRouteFamily().String(), }).Error("Invalid path. RouteFamily mismatch") } diff --git a/table/table_manager.go b/table/table_manager.go index 7722ce19..90f243c2 100644 --- a/table/table_manager.go +++ b/table/table_manager.go @@ -177,7 +177,7 @@ func (manager *TableManager) calculate(destinationList []Destination) ([]Path, e "Topic": "table", "Owner": manager.owner, "Key": destination.getNlri().String(), - "peer": newBestPath.getSource().Address, + "peer": newBestPath.GetSource().Address, "next_hop": newBestPath.GetNexthop().String(), "reason": reason, }).Debug("best path is not changed") @@ -198,7 +198,7 @@ func (manager *TableManager) calculate(destinationList []Destination) ([]Path, e "Topic": "table", "Owner": manager.owner, "Key": destination.getNlri().String(), - "peer": currentBestPath.getSource().Address, + "peer": currentBestPath.GetSource().Address, "next_hop": currentBestPath.GetNexthop().String(), }).Debug("best path is lost") @@ -219,8 +219,8 @@ func (manager *TableManager) calculate(destinationList []Destination) ([]Path, e log.WithFields(log.Fields{ "Topic": "table", "Owner": manager.owner, - "Key": newBestPath.getNlri().String(), - "peer": newBestPath.getSource().Address, + "Key": newBestPath.GetNlri().String(), + "peer": newBestPath.GetSource().Address, "next_hop": newBestPath.GetNexthop(), "reason": reason, }).Debug("new best path") @@ -343,7 +343,7 @@ func (adj *AdjRib) UpdateOut(pathList []Path) { func (adj *AdjRib) getPathList(rib map[string]*ReceivedRoute) []Path { trie := patricia.NewTrie() for _, rr := range rib { - key := rr.path.getNlri().String() + key := rr.path.GetNlri().String() trie.Insert(cidr2prefix(key), rr.path) } diff --git a/table/table_test.go b/table/table_test.go index 4a7a3a23..81e377f6 100644 --- a/table/table_test.go +++ b/table/table_test.go @@ -42,13 +42,13 @@ func TestTableDeleteDestByNlri(t *testing.T) { pathT := TableCreatePath(msgT) ipv4t := NewIPv4Table(0) for _, path := range pathT { - tableKey := ipv4t.tableKey(path.getNlri()) - dest := ipv4t.createDest(path.getNlri()) + tableKey := ipv4t.tableKey(path.GetNlri()) + dest := ipv4t.createDest(path.GetNlri()) ipv4t.setDestination(tableKey, dest) } - tableKey := ipv4t.tableKey(pathT[0].getNlri()) + tableKey := ipv4t.tableKey(pathT[0].GetNlri()) gdest := ipv4t.getDestination(tableKey) - rdest := deleteDestByNlri(ipv4t, pathT[0].getNlri()) + rdest := deleteDestByNlri(ipv4t, pathT[0].GetNlri()) assert.Equal(t, rdest, gdest) } @@ -58,12 +58,12 @@ func TestTableDeleteDest(t *testing.T) { pathT := TableCreatePath(msgT) ipv4t := NewIPv4Table(0) for _, path := range pathT { - tableKey := ipv4t.tableKey(path.getNlri()) - dest := ipv4t.createDest(path.getNlri()) + tableKey := ipv4t.tableKey(path.GetNlri()) + dest := ipv4t.createDest(path.GetNlri()) ipv4t.setDestination(tableKey, dest) } - tableKey := ipv4t.tableKey(pathT[0].getNlri()) - dest := ipv4t.createDest(pathT[0].getNlri()) + tableKey := ipv4t.tableKey(pathT[0].GetNlri()) + dest := ipv4t.createDest(pathT[0].GetNlri()) ipv4t.setDestination(tableKey, dest) deleteDest(ipv4t, dest) gdest := ipv4t.getDestination(tableKey) @@ -83,8 +83,8 @@ func TestTableSetDestinations(t *testing.T) { ipv4t := NewIPv4Table(0) destinations := make(map[string]Destination) for _, path := range pathT { - tableKey := ipv4t.tableKey(path.getNlri()) - dest := ipv4t.createDest(path.getNlri()) + tableKey := ipv4t.tableKey(path.GetNlri()) + dest := ipv4t.createDest(path.GetNlri()) destinations[tableKey] = dest } ipv4t.setDestinations(destinations) @@ -98,8 +98,8 @@ func TestTableGetDestinations(t *testing.T) { ipv4t := NewIPv4Table(0) destinations := make(map[string]Destination) for _, path := range pathT { - tableKey := ipv4t.tableKey(path.getNlri()) - dest := ipv4t.createDest(path.getNlri()) + tableKey := ipv4t.tableKey(path.GetNlri()) + dest := ipv4t.createDest(path.GetNlri()) destinations[tableKey] = dest } ipv4t.setDestinations(destinations) |