github.com/osrg/gobgp@v2.0.0+incompatible/internal/pkg/table/policy_test.go (about)

     1  // Copyright (C) 2014,2015 Nippon Telegraph and Telephone Corporation.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
    12  // implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  package table
    17  
    18  import (
    19  	"fmt"
    20  	"math"
    21  	"net"
    22  	"strconv"
    23  	"strings"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/osrg/gobgp/internal/pkg/config"
    28  	"github.com/osrg/gobgp/pkg/packet/bgp"
    29  
    30  	log "github.com/sirupsen/logrus"
    31  	"github.com/stretchr/testify/assert"
    32  	"github.com/stretchr/testify/require"
    33  )
    34  
    35  func TestGetStatement(t *testing.T) {
    36  	r := NewRoutingPolicy()
    37  	r.statementMap["statement1"] = &Statement{Name: "statement1"}
    38  	r.statementMap["statement2"] = &Statement{Name: "statement2"}
    39  	assert.Equal(t, len(r.GetStatement("")), 2)
    40  	assert.Equal(t, len(r.GetStatement("statement1")), 1)
    41  	assert.Equal(t, len(r.GetStatement("unknown")), 0)
    42  }
    43  
    44  func TestGetPolicy(t *testing.T) {
    45  	r := NewRoutingPolicy()
    46  	r.policyMap["p1"] = &Policy{Name: "p1"}
    47  	r.policyMap["p2"] = &Policy{Name: "p2"}
    48  	assert.Equal(t, len(r.GetPolicy("")), 2)
    49  	assert.Equal(t, len(r.GetPolicy("p1")), 1)
    50  	assert.Equal(t, len(r.GetPolicy("unknown")), 0)
    51  }
    52  func TestPrefixCalcurateNoRange(t *testing.T) {
    53  	// create path
    54  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
    55  	origin := bgp.NewPathAttributeOrigin(0)
    56  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
    57  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
    58  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
    59  	med := bgp.NewPathAttributeMultiExitDisc(0)
    60  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
    61  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.0")}
    62  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
    63  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
    64  	// test
    65  	pl1, _ := NewPrefix(config.Prefix{IpPrefix: "10.10.0.0/24", MasklengthRange: ""})
    66  	match1 := pl1.Match(path)
    67  	assert.Equal(t, true, match1)
    68  	pl2, _ := NewPrefix(config.Prefix{IpPrefix: "10.10.0.0/23", MasklengthRange: ""})
    69  	match2 := pl2.Match(path)
    70  	assert.Equal(t, false, match2)
    71  	pl3, _ := NewPrefix(config.Prefix{IpPrefix: "10.10.0.0/16", MasklengthRange: "21..24"})
    72  	match3 := pl3.Match(path)
    73  	assert.Equal(t, true, match3)
    74  }
    75  
    76  func TestPrefixCalcurateAddress(t *testing.T) {
    77  	// create path
    78  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
    79  	origin := bgp.NewPathAttributeOrigin(0)
    80  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
    81  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
    82  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
    83  	med := bgp.NewPathAttributeMultiExitDisc(0)
    84  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
    85  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
    86  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
    87  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
    88  	// test
    89  	pl1, _ := NewPrefix(config.Prefix{IpPrefix: "10.11.0.0/16", MasklengthRange: "21..24"})
    90  	match1 := pl1.Match(path)
    91  	assert.Equal(t, false, match1)
    92  	pl2, _ := NewPrefix(config.Prefix{IpPrefix: "10.10.0.0/16", MasklengthRange: "21..24"})
    93  	match2 := pl2.Match(path)
    94  	assert.Equal(t, true, match2)
    95  }
    96  
    97  func TestPrefixCalcurateLength(t *testing.T) {
    98  	// create path
    99  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
   100  	origin := bgp.NewPathAttributeOrigin(0)
   101  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
   102  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   103  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
   104  	med := bgp.NewPathAttributeMultiExitDisc(0)
   105  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   106  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   107  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   108  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   109  	// test
   110  	pl1, _ := NewPrefix(config.Prefix{IpPrefix: "10.10.64.0/24", MasklengthRange: "21..24"})
   111  	match1 := pl1.Match(path)
   112  	assert.Equal(t, false, match1)
   113  	pl2, _ := NewPrefix(config.Prefix{IpPrefix: "10.10.64.0/16", MasklengthRange: "21..24"})
   114  	match2 := pl2.Match(path)
   115  	assert.Equal(t, true, match2)
   116  }
   117  
   118  func TestPrefixCalcurateLengthRange(t *testing.T) {
   119  	// create path
   120  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
   121  	origin := bgp.NewPathAttributeOrigin(0)
   122  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
   123  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   124  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
   125  	med := bgp.NewPathAttributeMultiExitDisc(0)
   126  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   127  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   128  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   129  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   130  	// test
   131  	pl1, _ := NewPrefix(config.Prefix{IpPrefix: "10.10.0.0/16", MasklengthRange: "21..23"})
   132  	match1 := pl1.Match(path)
   133  	assert.Equal(t, false, match1)
   134  	pl2, _ := NewPrefix(config.Prefix{IpPrefix: "10.10.0.0/16", MasklengthRange: "25..26"})
   135  	match2 := pl2.Match(path)
   136  	assert.Equal(t, false, match2)
   137  	pl3, _ := NewPrefix(config.Prefix{IpPrefix: "10.10.0.0/16", MasklengthRange: "21..24"})
   138  	match3 := pl3.Match(path)
   139  	assert.Equal(t, true, match3)
   140  }
   141  
   142  func TestPrefixCalcurateNoRangeIPv6(t *testing.T) {
   143  	// create path
   144  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("2001::192:168:50:1")}
   145  	origin := bgp.NewPathAttributeOrigin(0)
   146  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
   147  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   148  	mpnlri := []bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")}
   149  	mpreach := bgp.NewPathAttributeMpReachNLRI("2001::192:168:50:1", mpnlri)
   150  	med := bgp.NewPathAttributeMultiExitDisc(0)
   151  	pathAttributes := []bgp.PathAttributeInterface{mpreach, origin, aspath, med}
   152  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nil)
   153  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   154  	// test
   155  	pl1, _ := NewPrefix(config.Prefix{IpPrefix: "2001:123:123::/48", MasklengthRange: ""})
   156  	match1 := pl1.Match(path)
   157  	assert.Equal(t, false, match1)
   158  	pl2, _ := NewPrefix(config.Prefix{IpPrefix: "2001:123:123:1::/64", MasklengthRange: ""})
   159  	match2 := pl2.Match(path)
   160  	assert.Equal(t, true, match2)
   161  	pl3, _ := NewPrefix(config.Prefix{IpPrefix: "2001:123:123::/48", MasklengthRange: "64..80"})
   162  	match3 := pl3.Match(path)
   163  	assert.Equal(t, true, match3)
   164  }
   165  
   166  func TestPrefixCalcurateAddressIPv6(t *testing.T) {
   167  	// create path
   168  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("2001::192:168:50:1")}
   169  	origin := bgp.NewPathAttributeOrigin(0)
   170  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
   171  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   172  	mpnlri := []bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")}
   173  	mpreach := bgp.NewPathAttributeMpReachNLRI("2001::192:168:50:1", mpnlri)
   174  	med := bgp.NewPathAttributeMultiExitDisc(0)
   175  	pathAttributes := []bgp.PathAttributeInterface{mpreach, origin, aspath, med}
   176  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nil)
   177  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   178  	// test
   179  	pl1, _ := NewPrefix(config.Prefix{IpPrefix: "2001:123:128::/48", MasklengthRange: "64..80"})
   180  	match1 := pl1.Match(path)
   181  	assert.Equal(t, false, match1)
   182  	pl2, _ := NewPrefix(config.Prefix{IpPrefix: "2001:123:123::/48", MasklengthRange: "64..80"})
   183  	match2 := pl2.Match(path)
   184  	assert.Equal(t, true, match2)
   185  }
   186  
   187  func TestPrefixCalcurateLengthIPv6(t *testing.T) {
   188  	// create path
   189  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("2001::192:168:50:1")}
   190  	origin := bgp.NewPathAttributeOrigin(0)
   191  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
   192  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   193  	mpnlri := []bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")}
   194  	mpreach := bgp.NewPathAttributeMpReachNLRI("2001::192:168:50:1", mpnlri)
   195  	med := bgp.NewPathAttributeMultiExitDisc(0)
   196  	pathAttributes := []bgp.PathAttributeInterface{mpreach, origin, aspath, med}
   197  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nil)
   198  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   199  	// test
   200  	pl1, _ := NewPrefix(config.Prefix{IpPrefix: "2001:123:123:64::/64", MasklengthRange: "64..80"})
   201  	match1 := pl1.Match(path)
   202  	assert.Equal(t, false, match1)
   203  	pl2, _ := NewPrefix(config.Prefix{IpPrefix: "2001:123:123:64::/48", MasklengthRange: "64..80"})
   204  	match2 := pl2.Match(path)
   205  	assert.Equal(t, true, match2)
   206  }
   207  
   208  func TestPrefixCalcurateLengthRangeIPv6(t *testing.T) {
   209  	// create path
   210  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("2001::192:168:50:1")}
   211  	origin := bgp.NewPathAttributeOrigin(0)
   212  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
   213  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   214  	mpnlri := []bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")}
   215  	mpreach := bgp.NewPathAttributeMpReachNLRI("2001::192:168:50:1", mpnlri)
   216  	med := bgp.NewPathAttributeMultiExitDisc(0)
   217  	pathAttributes := []bgp.PathAttributeInterface{mpreach, origin, aspath, med}
   218  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nil)
   219  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   220  	// test
   221  	pl1, _ := NewPrefix(config.Prefix{IpPrefix: "2001:123:123::/48", MasklengthRange: "62..63"})
   222  	match1 := pl1.Match(path)
   223  	assert.Equal(t, false, match1)
   224  	pl2, _ := NewPrefix(config.Prefix{IpPrefix: "2001:123:123::/48", MasklengthRange: "65..66"})
   225  	match2 := pl2.Match(path)
   226  	assert.Equal(t, false, match2)
   227  	pl3, _ := NewPrefix(config.Prefix{IpPrefix: "2001:123:123::/48", MasklengthRange: "63..65"})
   228  	match3 := pl3.Match(path)
   229  	assert.Equal(t, true, match3)
   230  }
   231  
   232  func TestPolicyNotMatch(t *testing.T) {
   233  	// create path
   234  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
   235  	origin := bgp.NewPathAttributeOrigin(0)
   236  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
   237  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   238  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
   239  	med := bgp.NewPathAttributeMultiExitDisc(0)
   240  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   241  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   242  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   243  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   244  
   245  	// create policy
   246  	ps := createPrefixSet("ps1", "10.3.0.0/16", "21..24")
   247  	ns := createNeighborSet("ns1", "10.0.0.1")
   248  	ds := config.DefinedSets{}
   249  	ds.PrefixSets = []config.PrefixSet{ps}
   250  	ds.NeighborSets = []config.NeighborSet{ns}
   251  	s := createStatement("statement1", "ps1", "ns1", false)
   252  	pd := createPolicyDefinition("pd1", s)
   253  	pl := createRoutingPolicy(ds, pd)
   254  
   255  	r := NewRoutingPolicy()
   256  	err := r.reload(pl)
   257  	assert.Nil(t, err)
   258  	pType, newPath := r.policyMap["pd1"].Apply(path, nil)
   259  	assert.Equal(t, ROUTE_TYPE_NONE, pType)
   260  	assert.Equal(t, newPath, path)
   261  }
   262  
   263  func TestPolicyMatchAndReject(t *testing.T) {
   264  	// create path
   265  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
   266  	origin := bgp.NewPathAttributeOrigin(0)
   267  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
   268  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   269  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
   270  	med := bgp.NewPathAttributeMultiExitDisc(0)
   271  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   272  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   273  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   274  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   275  	// create policy
   276  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
   277  	ns := createNeighborSet("ns1", "10.0.0.1")
   278  	ds := config.DefinedSets{}
   279  	ds.PrefixSets = []config.PrefixSet{ps}
   280  	ds.NeighborSets = []config.NeighborSet{ns}
   281  
   282  	s := createStatement("statement1", "ps1", "ns1", false)
   283  	pd := createPolicyDefinition("pd1", s)
   284  	pl := createRoutingPolicy(ds, pd)
   285  
   286  	r := NewRoutingPolicy()
   287  	err := r.reload(pl)
   288  	assert.Nil(t, err)
   289  	pType, newPath := r.policyMap["pd1"].Apply(path, nil)
   290  	assert.Equal(t, ROUTE_TYPE_REJECT, pType)
   291  	assert.Equal(t, newPath, path)
   292  }
   293  
   294  func TestPolicyMatchAndAccept(t *testing.T) {
   295  	// create path
   296  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
   297  	origin := bgp.NewPathAttributeOrigin(0)
   298  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
   299  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   300  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
   301  	med := bgp.NewPathAttributeMultiExitDisc(0)
   302  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   303  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   304  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   305  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   306  	// create policy
   307  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
   308  	ns := createNeighborSet("ns1", "10.0.0.1")
   309  	ds := config.DefinedSets{}
   310  	ds.PrefixSets = []config.PrefixSet{ps}
   311  	ds.NeighborSets = []config.NeighborSet{ns}
   312  
   313  	s := createStatement("statement1", "ps1", "ns1", true)
   314  	pd := createPolicyDefinition("pd1", s)
   315  	pl := createRoutingPolicy(ds, pd)
   316  
   317  	//test
   318  	r := NewRoutingPolicy()
   319  	err := r.reload(pl)
   320  	assert.Nil(t, err)
   321  	pType, newPath := r.policyMap["pd1"].Apply(path, nil)
   322  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
   323  	assert.Equal(t, path, newPath)
   324  }
   325  
   326  func TestPolicyRejectOnlyPrefixSet(t *testing.T) {
   327  	// create path
   328  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.1.1")}
   329  	origin := bgp.NewPathAttributeOrigin(0)
   330  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
   331  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   332  	nexthop := bgp.NewPathAttributeNextHop("10.0.1.1")
   333  	med := bgp.NewPathAttributeMultiExitDisc(0)
   334  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   335  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.1.101")}
   336  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   337  	path1 := ProcessMessage(updateMsg, peer, time.Now())[0]
   338  
   339  	peer = &PeerInfo{AS: 65002, Address: net.ParseIP("10.0.2.2")}
   340  	origin = bgp.NewPathAttributeOrigin(0)
   341  	aspathParam = []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65002})}
   342  	aspath = bgp.NewPathAttributeAsPath(aspathParam)
   343  	nexthop = bgp.NewPathAttributeNextHop("10.0.2.2")
   344  	med = bgp.NewPathAttributeMultiExitDisc(0)
   345  	pathAttributes = []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   346  	nlri = []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.9.2.102")}
   347  	updateMsg = bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   348  	path2 := ProcessMessage(updateMsg, peer, time.Now())[0]
   349  
   350  	// create policy
   351  	ps := createPrefixSet("ps1", "10.10.1.0/16", "21..24")
   352  	ds := config.DefinedSets{}
   353  	ds.PrefixSets = []config.PrefixSet{ps}
   354  
   355  	s := createStatement("statement1", "ps1", "", false)
   356  	pd := createPolicyDefinition("pd1", s)
   357  	pl := createRoutingPolicy(ds, pd)
   358  
   359  	//test
   360  	r := NewRoutingPolicy()
   361  	err := r.reload(pl)
   362  	assert.Nil(t, err)
   363  	p := r.policyMap["pd1"]
   364  	pType, newPath := p.Apply(path1, nil)
   365  	assert.Equal(t, ROUTE_TYPE_REJECT, pType)
   366  	assert.Equal(t, newPath, path1)
   367  
   368  	pType2, newPath2 := p.Apply(path2, nil)
   369  	assert.Equal(t, ROUTE_TYPE_NONE, pType2)
   370  	assert.Equal(t, newPath2, path2)
   371  }
   372  
   373  func TestPolicyRejectOnlyNeighborSet(t *testing.T) {
   374  	// create path
   375  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.1.1")}
   376  	origin := bgp.NewPathAttributeOrigin(0)
   377  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
   378  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   379  	nexthop := bgp.NewPathAttributeNextHop("10.0.1.1")
   380  	med := bgp.NewPathAttributeMultiExitDisc(0)
   381  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   382  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.1.101")}
   383  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   384  	path1 := ProcessMessage(updateMsg, peer, time.Now())[0]
   385  
   386  	peer = &PeerInfo{AS: 65002, Address: net.ParseIP("10.0.2.2")}
   387  	origin = bgp.NewPathAttributeOrigin(0)
   388  	aspathParam = []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65002})}
   389  	aspath = bgp.NewPathAttributeAsPath(aspathParam)
   390  	nexthop = bgp.NewPathAttributeNextHop("10.0.2.2")
   391  	med = bgp.NewPathAttributeMultiExitDisc(0)
   392  	pathAttributes = []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   393  	nlri = []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.2.102")}
   394  	updateMsg = bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   395  	path2 := ProcessMessage(updateMsg, peer, time.Now())[0]
   396  
   397  	// create policy
   398  	ns := createNeighborSet("ns1", "10.0.1.1")
   399  	ds := config.DefinedSets{}
   400  	ds.NeighborSets = []config.NeighborSet{ns}
   401  
   402  	s := createStatement("statement1", "", "ns1", false)
   403  	pd := createPolicyDefinition("pd1", s)
   404  	pl := createRoutingPolicy(ds, pd)
   405  
   406  	//test
   407  	r := NewRoutingPolicy()
   408  	err := r.reload(pl)
   409  	assert.Nil(t, err)
   410  	pType, newPath := r.policyMap["pd1"].Apply(path1, nil)
   411  	assert.Equal(t, ROUTE_TYPE_REJECT, pType)
   412  	assert.Equal(t, newPath, path1)
   413  
   414  	pType2, newPath2 := r.policyMap["pd1"].Apply(path2, nil)
   415  	assert.Equal(t, ROUTE_TYPE_NONE, pType2)
   416  	assert.Equal(t, newPath2, path2)
   417  }
   418  
   419  func TestPolicyDifferentRoutefamilyOfPathAndPolicy(t *testing.T) {
   420  	// create path ipv4
   421  	peerIPv4 := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
   422  	originIPv4 := bgp.NewPathAttributeOrigin(0)
   423  	aspathParamIPv4 := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
   424  	aspathIPv4 := bgp.NewPathAttributeAsPath(aspathParamIPv4)
   425  	nexthopIPv4 := bgp.NewPathAttributeNextHop("10.0.0.1")
   426  	medIPv4 := bgp.NewPathAttributeMultiExitDisc(0)
   427  	pathAttributesIPv4 := []bgp.PathAttributeInterface{originIPv4, aspathIPv4, nexthopIPv4, medIPv4}
   428  	nlriIPv4 := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   429  	updateMsgIPv4 := bgp.NewBGPUpdateMessage(nil, pathAttributesIPv4, nlriIPv4)
   430  	pathIPv4 := ProcessMessage(updateMsgIPv4, peerIPv4, time.Now())[0]
   431  	// create path ipv6
   432  	peerIPv6 := &PeerInfo{AS: 65001, Address: net.ParseIP("2001::192:168:50:1")}
   433  	originIPv6 := bgp.NewPathAttributeOrigin(0)
   434  	aspathParamIPv6 := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
   435  	aspathIPv6 := bgp.NewPathAttributeAsPath(aspathParamIPv6)
   436  	mpnlriIPv6 := []bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")}
   437  	mpreachIPv6 := bgp.NewPathAttributeMpReachNLRI("2001::192:168:50:1", mpnlriIPv6)
   438  	medIPv6 := bgp.NewPathAttributeMultiExitDisc(0)
   439  	pathAttributesIPv6 := []bgp.PathAttributeInterface{mpreachIPv6, originIPv6, aspathIPv6, medIPv6}
   440  	updateMsgIPv6 := bgp.NewBGPUpdateMessage(nil, pathAttributesIPv6, nil)
   441  	pathIPv6 := ProcessMessage(updateMsgIPv6, peerIPv6, time.Now())[0]
   442  	// create policy
   443  	psIPv4 := createPrefixSet("psIPv4", "10.10.0.0/16", "21..24")
   444  	nsIPv4 := createNeighborSet("nsIPv4", "10.0.0.1")
   445  
   446  	psIPv6 := createPrefixSet("psIPv6", "2001:123:123::/48", "64..80")
   447  	nsIPv6 := createNeighborSet("nsIPv6", "2001::192:168:50:1")
   448  
   449  	ds := config.DefinedSets{}
   450  	ds.PrefixSets = []config.PrefixSet{psIPv4, psIPv6}
   451  	ds.NeighborSets = []config.NeighborSet{nsIPv4, nsIPv6}
   452  
   453  	stIPv4 := createStatement("statement1", "psIPv4", "nsIPv4", false)
   454  	stIPv6 := createStatement("statement2", "psIPv6", "nsIPv6", false)
   455  
   456  	pd := createPolicyDefinition("pd1", stIPv4, stIPv6)
   457  	pl := createRoutingPolicy(ds, pd)
   458  
   459  	//test
   460  	r := NewRoutingPolicy()
   461  	err := r.reload(pl)
   462  	assert.Nil(t, err)
   463  	p := r.policyMap["pd1"]
   464  	pType1, newPath1 := p.Apply(pathIPv4, nil)
   465  	assert.Equal(t, ROUTE_TYPE_REJECT, pType1)
   466  	assert.Equal(t, newPath1, pathIPv4)
   467  
   468  	pType2, newPath2 := p.Apply(pathIPv6, nil)
   469  	assert.Equal(t, ROUTE_TYPE_REJECT, pType2)
   470  	assert.Equal(t, newPath2, pathIPv6)
   471  }
   472  
   473  func TestAsPathLengthConditionEvaluate(t *testing.T) {
   474  	// setup
   475  	// create path
   476  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
   477  	origin := bgp.NewPathAttributeOrigin(0)
   478  	aspathParam := []bgp.AsPathParamInterface{
   479  		bgp.NewAsPathParam(2, []uint16{65001, 65000, 65004, 65005}),
   480  		bgp.NewAsPathParam(1, []uint16{65001, 65000, 65004, 65005}),
   481  	}
   482  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   483  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
   484  	med := bgp.NewPathAttributeMultiExitDisc(0)
   485  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   486  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   487  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   488  	UpdatePathAttrs4ByteAs(updateMsg.Body.(*bgp.BGPUpdate))
   489  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   490  
   491  	// create match condition
   492  	asPathLength := config.AsPathLength{
   493  		Operator: "eq",
   494  		Value:    5,
   495  	}
   496  	c, _ := NewAsPathLengthCondition(asPathLength)
   497  
   498  	// test
   499  	assert.Equal(t, true, c.Evaluate(path, nil))
   500  
   501  	// create match condition
   502  	asPathLength = config.AsPathLength{
   503  		Operator: "ge",
   504  		Value:    3,
   505  	}
   506  	c, _ = NewAsPathLengthCondition(asPathLength)
   507  
   508  	// test
   509  	assert.Equal(t, true, c.Evaluate(path, nil))
   510  
   511  	// create match condition
   512  	asPathLength = config.AsPathLength{
   513  		Operator: "le",
   514  		Value:    3,
   515  	}
   516  	c, _ = NewAsPathLengthCondition(asPathLength)
   517  
   518  	// test
   519  	assert.Equal(t, false, c.Evaluate(path, nil))
   520  }
   521  
   522  func TestPolicyMatchAndAcceptNextHop(t *testing.T) {
   523  	// create path
   524  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
   525  	origin := bgp.NewPathAttributeOrigin(0)
   526  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
   527  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   528  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
   529  	med := bgp.NewPathAttributeMultiExitDisc(0)
   530  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   531  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   532  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   533  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   534  
   535  	// create policy
   536  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
   537  	ns := createNeighborSet("ns1", "10.0.0.1")
   538  	ds := config.DefinedSets{}
   539  	ds.PrefixSets = []config.PrefixSet{ps}
   540  	ds.NeighborSets = []config.NeighborSet{ns}
   541  	s := createStatement("statement1", "ps1", "ns1", true)
   542  	s.Conditions.BgpConditions.NextHopInList = []string{"10.0.0.1/32"}
   543  	pd := createPolicyDefinition("pd1", s)
   544  	pl := createRoutingPolicy(ds, pd)
   545  
   546  	r := NewRoutingPolicy()
   547  	err := r.reload(pl)
   548  	assert.Nil(t, err)
   549  	pType, newPath := r.policyMap["pd1"].Apply(path, nil)
   550  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
   551  	assert.Equal(t, newPath, path)
   552  }
   553  
   554  func TestPolicyMatchAndRejectNextHop(t *testing.T) {
   555  	// create path
   556  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
   557  	origin := bgp.NewPathAttributeOrigin(0)
   558  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
   559  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   560  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
   561  	med := bgp.NewPathAttributeMultiExitDisc(0)
   562  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   563  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   564  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   565  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   566  
   567  	// create policy
   568  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
   569  	ns := createNeighborSet("ns1", "10.0.0.1")
   570  	ds := config.DefinedSets{}
   571  	ds.PrefixSets = []config.PrefixSet{ps}
   572  	ds.NeighborSets = []config.NeighborSet{ns}
   573  	s := createStatement("statement1", "ps1", "ns1", true)
   574  	s.Conditions.BgpConditions.NextHopInList = []string{"10.0.0.12"}
   575  	pd := createPolicyDefinition("pd1", s)
   576  	pl := createRoutingPolicy(ds, pd)
   577  
   578  	r := NewRoutingPolicy()
   579  	err := r.reload(pl)
   580  	assert.Nil(t, err)
   581  	pType, newPath := r.policyMap["pd1"].Apply(path, nil)
   582  	assert.Equal(t, ROUTE_TYPE_NONE, pType)
   583  	assert.Equal(t, newPath, path)
   584  }
   585  
   586  func TestAsPathLengthConditionWithOtherCondition(t *testing.T) {
   587  	// setup
   588  	// create path
   589  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
   590  	origin := bgp.NewPathAttributeOrigin(0)
   591  	aspathParam := []bgp.AsPathParamInterface{
   592  		bgp.NewAsPathParam(2, []uint16{65001, 65000, 65004, 65004, 65005}),
   593  		bgp.NewAsPathParam(1, []uint16{65001, 65000, 65004, 65005}),
   594  	}
   595  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   596  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
   597  	med := bgp.NewPathAttributeMultiExitDisc(0)
   598  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   599  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   600  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   601  	UpdatePathAttrs4ByteAs(updateMsg.Body.(*bgp.BGPUpdate))
   602  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   603  
   604  	// create policy
   605  	ps := createPrefixSet("ps1", "10.10.1.0/16", "21..24")
   606  	ns := createNeighborSet("ns1", "10.0.0.1")
   607  
   608  	ds := config.DefinedSets{}
   609  	ds.PrefixSets = []config.PrefixSet{ps}
   610  	ds.NeighborSets = []config.NeighborSet{ns}
   611  
   612  	// create match condition
   613  	asPathLength := config.AsPathLength{
   614  		Operator: "le",
   615  		Value:    10,
   616  	}
   617  
   618  	s := createStatement("statement1", "ps1", "ns1", false)
   619  	s.Conditions.BgpConditions.AsPathLength = asPathLength
   620  	pd := createPolicyDefinition("pd1", s)
   621  	pl := createRoutingPolicy(ds, pd)
   622  
   623  	//test
   624  	r := NewRoutingPolicy()
   625  	err := r.reload(pl)
   626  	assert.Nil(t, err)
   627  	p := r.policyMap["pd1"]
   628  	pType, newPath := p.Apply(path, nil)
   629  	assert.Equal(t, ROUTE_TYPE_REJECT, pType)
   630  	assert.Equal(t, newPath, path)
   631  
   632  }
   633  
   634  func TestAs4PathLengthConditionEvaluate(t *testing.T) {
   635  	// setup
   636  	// create path
   637  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
   638  	origin := bgp.NewPathAttributeOrigin(0)
   639  	aspathParam := []bgp.AsPathParamInterface{
   640  		bgp.NewAs4PathParam(2, []uint32{
   641  			createAs4Value("65001.1"),
   642  			createAs4Value("65000.1"),
   643  			createAs4Value("65004.1"),
   644  			createAs4Value("65005.1"),
   645  		}),
   646  		bgp.NewAs4PathParam(1, []uint32{
   647  			createAs4Value("65001.1"),
   648  			createAs4Value("65000.1"),
   649  			createAs4Value("65004.1"),
   650  			createAs4Value("65005.1"),
   651  		}),
   652  	}
   653  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   654  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
   655  	med := bgp.NewPathAttributeMultiExitDisc(0)
   656  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   657  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   658  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   659  	UpdatePathAttrs4ByteAs(updateMsg.Body.(*bgp.BGPUpdate))
   660  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   661  
   662  	// create match condition
   663  	asPathLength := config.AsPathLength{
   664  		Operator: "eq",
   665  		Value:    5,
   666  	}
   667  	c, _ := NewAsPathLengthCondition(asPathLength)
   668  
   669  	// test
   670  	assert.Equal(t, true, c.Evaluate(path, nil))
   671  
   672  	// create match condition
   673  	asPathLength = config.AsPathLength{
   674  		Operator: "ge",
   675  		Value:    3,
   676  	}
   677  	c, _ = NewAsPathLengthCondition(asPathLength)
   678  
   679  	// test
   680  	assert.Equal(t, true, c.Evaluate(path, nil))
   681  
   682  	// create match condition
   683  	asPathLength = config.AsPathLength{
   684  		Operator: "le",
   685  		Value:    3,
   686  	}
   687  	c, _ = NewAsPathLengthCondition(asPathLength)
   688  
   689  	// test
   690  	assert.Equal(t, false, c.Evaluate(path, nil))
   691  }
   692  
   693  func addPolicy(r *RoutingPolicy, x *Policy) {
   694  	for _, s := range x.Statements {
   695  		for _, c := range s.Conditions {
   696  			r.validateCondition(c)
   697  		}
   698  	}
   699  }
   700  
   701  func TestAs4PathLengthConditionWithOtherCondition(t *testing.T) {
   702  	// setup
   703  	// create path
   704  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
   705  	origin := bgp.NewPathAttributeOrigin(0)
   706  	aspathParam := []bgp.AsPathParamInterface{
   707  		bgp.NewAs4PathParam(2, []uint32{
   708  			createAs4Value("65001.1"),
   709  			createAs4Value("65000.1"),
   710  			createAs4Value("65004.1"),
   711  			createAs4Value("65004.1"),
   712  			createAs4Value("65005.1"),
   713  		}),
   714  		bgp.NewAs4PathParam(1, []uint32{
   715  			createAs4Value("65001.1"),
   716  			createAs4Value("65000.1"),
   717  			createAs4Value("65004.1"),
   718  			createAs4Value("65005.1"),
   719  		}),
   720  	}
   721  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   722  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
   723  	med := bgp.NewPathAttributeMultiExitDisc(0)
   724  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   725  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   726  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   727  	UpdatePathAttrs4ByteAs(updateMsg.Body.(*bgp.BGPUpdate))
   728  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   729  
   730  	// create policy
   731  	ps := createPrefixSet("ps1", "10.10.1.0/16", "21..24")
   732  	ns := createNeighborSet("ns1", "10.0.0.1")
   733  
   734  	ds := config.DefinedSets{}
   735  	ds.PrefixSets = []config.PrefixSet{ps}
   736  	ds.NeighborSets = []config.NeighborSet{ns}
   737  
   738  	// create match condition
   739  	asPathLength := config.AsPathLength{
   740  		Operator: "le",
   741  		Value:    10,
   742  	}
   743  
   744  	s := createStatement("statement1", "ps1", "ns1", false)
   745  	s.Conditions.BgpConditions.AsPathLength = asPathLength
   746  	pd := createPolicyDefinition("pd1", s)
   747  	pl := createRoutingPolicy(ds, pd)
   748  
   749  	//test
   750  	r := NewRoutingPolicy()
   751  	r.reload(pl)
   752  	p, _ := NewPolicy(pl.PolicyDefinitions[0])
   753  	addPolicy(r, p)
   754  	pType, newPath := p.Apply(path, nil)
   755  	assert.Equal(t, ROUTE_TYPE_REJECT, pType)
   756  	assert.Equal(t, newPath, path)
   757  
   758  }
   759  
   760  func TestAsPathConditionEvaluate(t *testing.T) {
   761  
   762  	// setup
   763  	// create path
   764  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
   765  	origin := bgp.NewPathAttributeOrigin(0)
   766  	aspathParam1 := []bgp.AsPathParamInterface{
   767  		bgp.NewAsPathParam(2, []uint16{65001, 65000, 65010, 65004, 65005}),
   768  	}
   769  	aspath := bgp.NewPathAttributeAsPath(aspathParam1)
   770  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
   771  	med := bgp.NewPathAttributeMultiExitDisc(0)
   772  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   773  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   774  	updateMsg1 := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   775  	UpdatePathAttrs4ByteAs(updateMsg1.Body.(*bgp.BGPUpdate))
   776  	path1 := ProcessMessage(updateMsg1, peer, time.Now())[0]
   777  
   778  	aspathParam2 := []bgp.AsPathParamInterface{
   779  		bgp.NewAsPathParam(2, []uint16{65010}),
   780  	}
   781  	aspath2 := bgp.NewPathAttributeAsPath(aspathParam2)
   782  	pathAttributes = []bgp.PathAttributeInterface{origin, aspath2, nexthop, med}
   783  	updateMsg2 := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   784  	UpdatePathAttrs4ByteAs(updateMsg2.Body.(*bgp.BGPUpdate))
   785  	path2 := ProcessMessage(updateMsg2, peer, time.Now())[0]
   786  
   787  	// create match condition
   788  	asPathSet1 := config.AsPathSet{
   789  		AsPathSetName: "asset1",
   790  		AsPathList:    []string{"^65001"},
   791  	}
   792  
   793  	asPathSet2 := config.AsPathSet{
   794  		AsPathSetName: "asset2",
   795  		AsPathList:    []string{"65005$"},
   796  	}
   797  
   798  	asPathSet3 := config.AsPathSet{
   799  		AsPathSetName: "asset3",
   800  		AsPathList:    []string{"65004", "65005$"},
   801  	}
   802  
   803  	asPathSet4 := config.AsPathSet{
   804  		AsPathSetName: "asset4",
   805  		AsPathList:    []string{"65000$"},
   806  	}
   807  
   808  	asPathSet5 := config.AsPathSet{
   809  		AsPathSetName: "asset5",
   810  		AsPathList:    []string{"65010"},
   811  	}
   812  
   813  	asPathSet6 := config.AsPathSet{
   814  		AsPathSetName: "asset6",
   815  		AsPathList:    []string{"^65010$"},
   816  	}
   817  
   818  	m := make(map[string]DefinedSet)
   819  	for _, s := range []config.AsPathSet{asPathSet1, asPathSet2, asPathSet3,
   820  		asPathSet4, asPathSet5, asPathSet6} {
   821  		a, _ := NewAsPathSet(s)
   822  		m[s.AsPathSetName] = a
   823  	}
   824  
   825  	createAspathC := func(name string, option config.MatchSetOptionsType) *AsPathCondition {
   826  		matchSet := config.MatchAsPathSet{}
   827  		matchSet.AsPathSet = name
   828  		matchSet.MatchSetOptions = option
   829  		p, _ := NewAsPathCondition(matchSet)
   830  		if v, ok := m[name]; ok {
   831  			p.set = v.(*AsPathSet)
   832  		}
   833  		return p
   834  	}
   835  
   836  	p1 := createAspathC("asset1", config.MATCH_SET_OPTIONS_TYPE_ANY)
   837  	p2 := createAspathC("asset2", config.MATCH_SET_OPTIONS_TYPE_ANY)
   838  	p3 := createAspathC("asset3", config.MATCH_SET_OPTIONS_TYPE_ANY)
   839  	p4 := createAspathC("asset4", config.MATCH_SET_OPTIONS_TYPE_ANY)
   840  	p5 := createAspathC("asset5", config.MATCH_SET_OPTIONS_TYPE_ANY)
   841  	p6 := createAspathC("asset6", config.MATCH_SET_OPTIONS_TYPE_ANY)
   842  	p7 := createAspathC("asset3", config.MATCH_SET_OPTIONS_TYPE_ALL)
   843  	p8 := createAspathC("asset3", config.MATCH_SET_OPTIONS_TYPE_INVERT)
   844  
   845  	// test
   846  	assert.Equal(t, true, p1.Evaluate(path1, nil))
   847  	assert.Equal(t, true, p2.Evaluate(path1, nil))
   848  	assert.Equal(t, true, p3.Evaluate(path1, nil))
   849  	assert.Equal(t, false, p4.Evaluate(path1, nil))
   850  	assert.Equal(t, true, p5.Evaluate(path1, nil))
   851  	assert.Equal(t, false, p6.Evaluate(path1, nil))
   852  	assert.Equal(t, true, p6.Evaluate(path2, nil))
   853  	assert.Equal(t, true, p7.Evaluate(path1, nil))
   854  	assert.Equal(t, true, p8.Evaluate(path2, nil))
   855  }
   856  
   857  func TestMultipleAsPathConditionEvaluate(t *testing.T) {
   858  
   859  	// setup
   860  	// create path
   861  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
   862  	origin := bgp.NewPathAttributeOrigin(0)
   863  	aspathParam1 := []bgp.AsPathParamInterface{
   864  		bgp.NewAsPathParam(2, []uint16{65001, 65000, 54000, 65004, 65005}),
   865  	}
   866  	aspath := bgp.NewPathAttributeAsPath(aspathParam1)
   867  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
   868  	med := bgp.NewPathAttributeMultiExitDisc(0)
   869  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   870  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   871  	updateMsg1 := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   872  	UpdatePathAttrs4ByteAs(updateMsg1.Body.(*bgp.BGPUpdate))
   873  	path1 := ProcessMessage(updateMsg1, peer, time.Now())[0]
   874  
   875  	// create match condition
   876  	asPathSet1 := config.AsPathSet{
   877  		AsPathSetName: "asset1",
   878  		AsPathList:    []string{"^65001_65000"},
   879  	}
   880  
   881  	asPathSet2 := config.AsPathSet{
   882  		AsPathSetName: "asset2",
   883  		AsPathList:    []string{"65004_65005$"},
   884  	}
   885  
   886  	asPathSet3 := config.AsPathSet{
   887  		AsPathSetName: "asset3",
   888  		AsPathList:    []string{"65001_65000_54000"},
   889  	}
   890  
   891  	asPathSet4 := config.AsPathSet{
   892  		AsPathSetName: "asset4",
   893  		AsPathList:    []string{"54000_65004_65005"},
   894  	}
   895  
   896  	asPathSet5 := config.AsPathSet{
   897  		AsPathSetName: "asset5",
   898  		AsPathList:    []string{"^65001 65000 54000 65004 65005$"},
   899  	}
   900  
   901  	asPathSet6 := config.AsPathSet{
   902  		AsPathSetName: "asset6",
   903  		AsPathList:    []string{".*_[0-9]+_65005"},
   904  	}
   905  
   906  	asPathSet7 := config.AsPathSet{
   907  		AsPathSetName: "asset7",
   908  		AsPathList:    []string{".*_5[0-9]+_[0-9]+"},
   909  	}
   910  
   911  	asPathSet8 := config.AsPathSet{
   912  		AsPathSetName: "asset8",
   913  		AsPathList:    []string{"6[0-9]+_6[0-9]+_5[0-9]+"},
   914  	}
   915  
   916  	asPathSet9 := config.AsPathSet{
   917  		AsPathSetName: "asset9",
   918  		AsPathList:    []string{"6[0-9]+__6[0-9]+"},
   919  	}
   920  
   921  	m := make(map[string]DefinedSet)
   922  	for _, s := range []config.AsPathSet{asPathSet1, asPathSet2, asPathSet3,
   923  		asPathSet4, asPathSet5, asPathSet6, asPathSet7, asPathSet8, asPathSet9} {
   924  		a, _ := NewAsPathSet(s)
   925  		m[s.AsPathSetName] = a
   926  	}
   927  
   928  	createAspathC := func(name string, option config.MatchSetOptionsType) *AsPathCondition {
   929  		matchSet := config.MatchAsPathSet{}
   930  		matchSet.AsPathSet = name
   931  		matchSet.MatchSetOptions = option
   932  		p, _ := NewAsPathCondition(matchSet)
   933  		if v, ok := m[name]; ok {
   934  			p.set = v.(*AsPathSet)
   935  		}
   936  		return p
   937  	}
   938  
   939  	p1 := createAspathC("asset1", config.MATCH_SET_OPTIONS_TYPE_ANY)
   940  	p2 := createAspathC("asset2", config.MATCH_SET_OPTIONS_TYPE_ANY)
   941  	p3 := createAspathC("asset3", config.MATCH_SET_OPTIONS_TYPE_ANY)
   942  	p4 := createAspathC("asset4", config.MATCH_SET_OPTIONS_TYPE_ANY)
   943  	p5 := createAspathC("asset5", config.MATCH_SET_OPTIONS_TYPE_ANY)
   944  	p6 := createAspathC("asset6", config.MATCH_SET_OPTIONS_TYPE_ANY)
   945  	p7 := createAspathC("asset7", config.MATCH_SET_OPTIONS_TYPE_ANY)
   946  	p8 := createAspathC("asset8", config.MATCH_SET_OPTIONS_TYPE_ANY)
   947  	p9 := createAspathC("asset9", config.MATCH_SET_OPTIONS_TYPE_ANY)
   948  
   949  	// test
   950  	assert.Equal(t, true, p1.Evaluate(path1, nil))
   951  	assert.Equal(t, true, p2.Evaluate(path1, nil))
   952  	assert.Equal(t, true, p3.Evaluate(path1, nil))
   953  	assert.Equal(t, true, p4.Evaluate(path1, nil))
   954  	assert.Equal(t, true, p5.Evaluate(path1, nil))
   955  	assert.Equal(t, true, p6.Evaluate(path1, nil))
   956  	assert.Equal(t, true, p7.Evaluate(path1, nil))
   957  	assert.Equal(t, true, p8.Evaluate(path1, nil))
   958  	assert.Equal(t, false, p9.Evaluate(path1, nil))
   959  }
   960  
   961  func TestAsPathCondition(t *testing.T) {
   962  	type astest struct {
   963  		path   *Path
   964  		result bool
   965  	}
   966  
   967  	makeTest := func(asPathAttrType uint8, ases []uint32, result bool) astest {
   968  		aspathParam := []bgp.AsPathParamInterface{
   969  			bgp.NewAs4PathParam(asPathAttrType, ases),
   970  		}
   971  		pathAttributes := []bgp.PathAttributeInterface{bgp.NewPathAttributeAsPath(aspathParam)}
   972  		p := NewPath(nil, nil, false, pathAttributes, time.Time{}, false)
   973  		return astest{
   974  			path:   p,
   975  			result: result,
   976  		}
   977  	}
   978  
   979  	tests := make(map[string][]astest)
   980  
   981  	tests["^(100_)+(200_)+$"] = []astest{
   982  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{100, 200}, true),
   983  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{100, 100, 200}, true),
   984  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{100, 100, 200, 200}, true),
   985  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{100, 100, 200, 200, 300}, false),
   986  	}
   987  
   988  	aslen255 := func() []uint32 {
   989  		r := make([]uint32, 255)
   990  		for i := 0; i < 255; i++ {
   991  			r[i] = 1
   992  		}
   993  		return r
   994  	}()
   995  	tests["^([0-9]+_){0,255}$"] = []astest{
   996  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, aslen255, true),
   997  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, append(aslen255, 1), false),
   998  	}
   999  
  1000  	tests["(_7521)$"] = []astest{
  1001  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{7521}, true),
  1002  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{1000, 7521}, true),
  1003  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{7521, 1000}, false),
  1004  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{1000, 7521, 100}, false),
  1005  	}
  1006  
  1007  	tests["^65001( |_.*_)65535$"] = []astest{
  1008  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{65001, 65535}, true),
  1009  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{65001, 65001, 65535}, true),
  1010  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{65001, 65002, 65003, 65535}, true),
  1011  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{65001, 65534}, false),
  1012  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{65002, 65535}, false),
  1013  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{65002, 65001, 65535}, false),
  1014  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{65001, 65535, 65002}, false),
  1015  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{650019, 65535}, false),
  1016  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{65001, 165535}, false),
  1017  	}
  1018  
  1019  	for k, v := range tests {
  1020  		s, _ := NewAsPathSet(config.AsPathSet{
  1021  			AsPathSetName: k,
  1022  			AsPathList:    []string{k},
  1023  		})
  1024  		c, _ := NewAsPathCondition(config.MatchAsPathSet{
  1025  			AsPathSet:       k,
  1026  			MatchSetOptions: config.MATCH_SET_OPTIONS_TYPE_ANY,
  1027  		})
  1028  		c.set = s
  1029  		for _, a := range v {
  1030  			result := c.Evaluate(a.path, nil)
  1031  			if a.result != result {
  1032  				log.WithFields(log.Fields{
  1033  					"EXP":      k,
  1034  					"ASSTR":    a.path.GetAsString(),
  1035  					"Expected": a.result,
  1036  					"Result":   result,
  1037  				}).Fatal("failed")
  1038  			}
  1039  		}
  1040  	}
  1041  }
  1042  
  1043  func TestAsPathConditionWithOtherCondition(t *testing.T) {
  1044  
  1045  	// setup
  1046  	// create path
  1047  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1048  	origin := bgp.NewPathAttributeOrigin(0)
  1049  	aspathParam := []bgp.AsPathParamInterface{
  1050  		bgp.NewAsPathParam(1, []uint16{65001, 65000, 65004, 65005}),
  1051  		bgp.NewAsPathParam(2, []uint16{65001, 65000, 65004, 65004, 65005}),
  1052  	}
  1053  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  1054  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1055  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1056  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  1057  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1058  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1059  	UpdatePathAttrs4ByteAs(updateMsg.Body.(*bgp.BGPUpdate))
  1060  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  1061  
  1062  	// create policy
  1063  	asPathSet := config.AsPathSet{
  1064  		AsPathSetName: "asset1",
  1065  		AsPathList:    []string{"65005$"},
  1066  	}
  1067  
  1068  	ps := createPrefixSet("ps1", "10.10.1.0/16", "21..24")
  1069  	ns := createNeighborSet("ns1", "10.0.0.1")
  1070  
  1071  	ds := config.DefinedSets{}
  1072  	ds.PrefixSets = []config.PrefixSet{ps}
  1073  	ds.NeighborSets = []config.NeighborSet{ns}
  1074  	ds.BgpDefinedSets.AsPathSets = []config.AsPathSet{asPathSet}
  1075  
  1076  	s := createStatement("statement1", "ps1", "ns1", false)
  1077  	s.Conditions.BgpConditions.MatchAsPathSet.AsPathSet = "asset1"
  1078  
  1079  	pd := createPolicyDefinition("pd1", s)
  1080  	pl := createRoutingPolicy(ds, pd)
  1081  
  1082  	//test
  1083  	r := NewRoutingPolicy()
  1084  	err := r.reload(pl)
  1085  	assert.Nil(t, err)
  1086  	p := r.policyMap["pd1"]
  1087  	pType, newPath := p.Apply(path, nil)
  1088  	assert.Equal(t, ROUTE_TYPE_REJECT, pType)
  1089  	assert.Equal(t, newPath, path)
  1090  
  1091  }
  1092  
  1093  func TestAs4PathConditionEvaluate(t *testing.T) {
  1094  
  1095  	// setup
  1096  	// create path
  1097  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1098  	origin := bgp.NewPathAttributeOrigin(0)
  1099  	aspathParam1 := []bgp.AsPathParamInterface{
  1100  		bgp.NewAs4PathParam(2, []uint32{
  1101  			createAs4Value("65001.1"),
  1102  			createAs4Value("65000.1"),
  1103  			createAs4Value("65010.1"),
  1104  			createAs4Value("65004.1"),
  1105  			createAs4Value("65005.1"),
  1106  		})}
  1107  
  1108  	aspath := bgp.NewPathAttributeAsPath(aspathParam1)
  1109  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1110  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1111  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  1112  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1113  	updateMsg1 := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1114  	UpdatePathAttrs4ByteAs(updateMsg1.Body.(*bgp.BGPUpdate))
  1115  	path1 := ProcessMessage(updateMsg1, peer, time.Now())[0]
  1116  
  1117  	aspathParam2 := []bgp.AsPathParamInterface{
  1118  		bgp.NewAs4PathParam(2, []uint32{
  1119  			createAs4Value("65010.1"),
  1120  		}),
  1121  	}
  1122  	aspath2 := bgp.NewPathAttributeAsPath(aspathParam2)
  1123  	pathAttributes = []bgp.PathAttributeInterface{origin, aspath2, nexthop, med}
  1124  	updateMsg2 := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1125  	UpdatePathAttrs4ByteAs(updateMsg2.Body.(*bgp.BGPUpdate))
  1126  	path2 := ProcessMessage(updateMsg2, peer, time.Now())[0]
  1127  
  1128  	// create match condition
  1129  	asPathSet1 := config.AsPathSet{
  1130  		AsPathSetName: "asset1",
  1131  		AsPathList:    []string{fmt.Sprintf("^%d", createAs4Value("65001.1"))},
  1132  	}
  1133  
  1134  	asPathSet2 := config.AsPathSet{
  1135  		AsPathSetName: "asset2",
  1136  		AsPathList:    []string{fmt.Sprintf("%d$", createAs4Value("65005.1"))},
  1137  	}
  1138  
  1139  	asPathSet3 := config.AsPathSet{
  1140  		AsPathSetName: "asset3",
  1141  		AsPathList: []string{
  1142  			fmt.Sprintf("%d", createAs4Value("65004.1")),
  1143  			fmt.Sprintf("%d$", createAs4Value("65005.1")),
  1144  		},
  1145  	}
  1146  
  1147  	asPathSet4 := config.AsPathSet{
  1148  		AsPathSetName: "asset4",
  1149  		AsPathList: []string{
  1150  			fmt.Sprintf("%d$", createAs4Value("65000.1")),
  1151  		},
  1152  	}
  1153  
  1154  	asPathSet5 := config.AsPathSet{
  1155  		AsPathSetName: "asset5",
  1156  		AsPathList: []string{
  1157  			fmt.Sprintf("%d", createAs4Value("65010.1")),
  1158  		},
  1159  	}
  1160  
  1161  	asPathSet6 := config.AsPathSet{
  1162  		AsPathSetName: "asset6",
  1163  		AsPathList: []string{
  1164  			fmt.Sprintf("%d$", createAs4Value("65010.1")),
  1165  		},
  1166  	}
  1167  
  1168  	m := make(map[string]DefinedSet)
  1169  	for _, s := range []config.AsPathSet{asPathSet1, asPathSet2, asPathSet3,
  1170  		asPathSet4, asPathSet5, asPathSet6} {
  1171  		a, _ := NewAsPathSet(s)
  1172  		m[s.AsPathSetName] = a
  1173  	}
  1174  
  1175  	createAspathC := func(name string, option config.MatchSetOptionsType) *AsPathCondition {
  1176  		matchSet := config.MatchAsPathSet{}
  1177  		matchSet.AsPathSet = name
  1178  		matchSet.MatchSetOptions = option
  1179  		p, _ := NewAsPathCondition(matchSet)
  1180  		if v, ok := m[name]; ok {
  1181  			p.set = v.(*AsPathSet)
  1182  		}
  1183  		return p
  1184  	}
  1185  
  1186  	p1 := createAspathC("asset1", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1187  	p2 := createAspathC("asset2", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1188  	p3 := createAspathC("asset3", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1189  	p4 := createAspathC("asset4", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1190  	p5 := createAspathC("asset5", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1191  	p6 := createAspathC("asset6", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1192  
  1193  	p7 := createAspathC("asset3", config.MATCH_SET_OPTIONS_TYPE_ALL)
  1194  	p8 := createAspathC("asset3", config.MATCH_SET_OPTIONS_TYPE_INVERT)
  1195  
  1196  	// test
  1197  	assert.Equal(t, true, p1.Evaluate(path1, nil))
  1198  	assert.Equal(t, true, p2.Evaluate(path1, nil))
  1199  	assert.Equal(t, true, p3.Evaluate(path1, nil))
  1200  	assert.Equal(t, false, p4.Evaluate(path1, nil))
  1201  	assert.Equal(t, true, p5.Evaluate(path1, nil))
  1202  	assert.Equal(t, false, p6.Evaluate(path1, nil))
  1203  	assert.Equal(t, true, p6.Evaluate(path2, nil))
  1204  
  1205  	assert.Equal(t, true, p7.Evaluate(path1, nil))
  1206  	assert.Equal(t, true, p8.Evaluate(path2, nil))
  1207  }
  1208  
  1209  func TestMultipleAs4PathConditionEvaluate(t *testing.T) {
  1210  
  1211  	// setup
  1212  	// create path
  1213  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1214  	origin := bgp.NewPathAttributeOrigin(0)
  1215  	aspathParam1 := []bgp.AsPathParamInterface{
  1216  		bgp.NewAs4PathParam(2, []uint32{
  1217  			createAs4Value("65001.1"),
  1218  			createAs4Value("65000.1"),
  1219  			createAs4Value("54000.1"),
  1220  			createAs4Value("65004.1"),
  1221  			createAs4Value("65005.1"),
  1222  		}),
  1223  	}
  1224  
  1225  	aspath := bgp.NewPathAttributeAsPath(aspathParam1)
  1226  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1227  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1228  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  1229  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1230  	updateMsg1 := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1231  	UpdatePathAttrs4ByteAs(updateMsg1.Body.(*bgp.BGPUpdate))
  1232  	path1 := ProcessMessage(updateMsg1, peer, time.Now())[0]
  1233  
  1234  	// create match condition
  1235  	asPathSet1 := config.AsPathSet{
  1236  		AsPathSetName: "asset1",
  1237  		AsPathList: []string{
  1238  			fmt.Sprintf("^%d_%d", createAs4Value("65001.1"), createAs4Value("65000.1")),
  1239  		},
  1240  	}
  1241  
  1242  	asPathSet2 := config.AsPathSet{
  1243  		AsPathSetName: "asset2",
  1244  		AsPathList: []string{
  1245  			fmt.Sprintf("%d_%d$", createAs4Value("65004.1"), createAs4Value("65005.1")),
  1246  		},
  1247  	}
  1248  
  1249  	asPathSet3 := config.AsPathSet{
  1250  		AsPathSetName: "asset3",
  1251  		AsPathList: []string{
  1252  			fmt.Sprintf("%d_%d_%d", createAs4Value("65001.1"), createAs4Value("65000.1"), createAs4Value("54000.1")),
  1253  		},
  1254  	}
  1255  
  1256  	asPathSet4 := config.AsPathSet{
  1257  		AsPathSetName: "asset4",
  1258  		AsPathList: []string{
  1259  			fmt.Sprintf("%d_%d_%d", createAs4Value("54000.1"), createAs4Value("65004.1"), createAs4Value("65005.1")),
  1260  		},
  1261  	}
  1262  
  1263  	asPathSet5 := config.AsPathSet{
  1264  		AsPathSetName: "asset5",
  1265  		AsPathList: []string{
  1266  			fmt.Sprintf("^%d %d %d %d %d$", createAs4Value("65001.1"), createAs4Value("65000.1"), createAs4Value("54000.1"), createAs4Value("65004.1"), createAs4Value("65005.1")),
  1267  		},
  1268  	}
  1269  
  1270  	asPathSet6 := config.AsPathSet{
  1271  		AsPathSetName: "asset6",
  1272  		AsPathList: []string{
  1273  			fmt.Sprintf(".*_[0-9]+_%d", createAs4Value("65005.1")),
  1274  		},
  1275  	}
  1276  
  1277  	asPathSet7 := config.AsPathSet{
  1278  		AsPathSetName: "asset7",
  1279  		AsPathList:    []string{".*_3[0-9]+_[0-9]+"},
  1280  	}
  1281  
  1282  	asPathSet8 := config.AsPathSet{
  1283  		AsPathSetName: "asset8",
  1284  		AsPathList:    []string{"4[0-9]+_4[0-9]+_3[0-9]+"},
  1285  	}
  1286  
  1287  	asPathSet9 := config.AsPathSet{
  1288  		AsPathSetName: "asset9",
  1289  		AsPathList:    []string{"4[0-9]+__4[0-9]+"},
  1290  	}
  1291  
  1292  	m := make(map[string]DefinedSet)
  1293  	for _, s := range []config.AsPathSet{asPathSet1, asPathSet2, asPathSet3,
  1294  		asPathSet4, asPathSet5, asPathSet6, asPathSet7, asPathSet8, asPathSet9} {
  1295  		a, _ := NewAsPathSet(s)
  1296  		m[s.AsPathSetName] = a
  1297  	}
  1298  
  1299  	createAspathC := func(name string, option config.MatchSetOptionsType) *AsPathCondition {
  1300  		matchSet := config.MatchAsPathSet{}
  1301  		matchSet.AsPathSet = name
  1302  		matchSet.MatchSetOptions = option
  1303  		p, _ := NewAsPathCondition(matchSet)
  1304  		if v, ok := m[name]; ok {
  1305  			p.set = v.(*AsPathSet)
  1306  		}
  1307  		return p
  1308  	}
  1309  
  1310  	p1 := createAspathC("asset1", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1311  	p2 := createAspathC("asset2", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1312  	p3 := createAspathC("asset3", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1313  	p4 := createAspathC("asset4", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1314  	p5 := createAspathC("asset5", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1315  	p6 := createAspathC("asset6", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1316  	p7 := createAspathC("asset7", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1317  	p8 := createAspathC("asset8", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1318  	p9 := createAspathC("asset9", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1319  
  1320  	// test
  1321  	assert.Equal(t, true, p1.Evaluate(path1, nil))
  1322  	assert.Equal(t, true, p2.Evaluate(path1, nil))
  1323  	assert.Equal(t, true, p3.Evaluate(path1, nil))
  1324  	assert.Equal(t, true, p4.Evaluate(path1, nil))
  1325  	assert.Equal(t, true, p5.Evaluate(path1, nil))
  1326  	assert.Equal(t, true, p6.Evaluate(path1, nil))
  1327  	assert.Equal(t, true, p7.Evaluate(path1, nil))
  1328  	assert.Equal(t, true, p8.Evaluate(path1, nil))
  1329  	assert.Equal(t, false, p9.Evaluate(path1, nil))
  1330  }
  1331  
  1332  func TestAs4PathConditionWithOtherCondition(t *testing.T) {
  1333  
  1334  	// setup
  1335  	// create path
  1336  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1337  	origin := bgp.NewPathAttributeOrigin(0)
  1338  	aspathParam := []bgp.AsPathParamInterface{
  1339  		bgp.NewAs4PathParam(1, []uint32{
  1340  			createAs4Value("65001.1"),
  1341  			createAs4Value("65000.1"),
  1342  			createAs4Value("65004.1"),
  1343  			createAs4Value("65005.1"),
  1344  		}),
  1345  		bgp.NewAs4PathParam(2, []uint32{
  1346  			createAs4Value("65001.1"),
  1347  			createAs4Value("65000.1"),
  1348  			createAs4Value("65004.1"),
  1349  			createAs4Value("65004.1"),
  1350  			createAs4Value("65005.1"),
  1351  		}),
  1352  	}
  1353  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  1354  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1355  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1356  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  1357  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1358  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1359  	UpdatePathAttrs4ByteAs(updateMsg.Body.(*bgp.BGPUpdate))
  1360  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  1361  
  1362  	// create policy
  1363  	asPathSet := config.AsPathSet{
  1364  		AsPathSetName: "asset1",
  1365  		AsPathList:    []string{fmt.Sprintf("%d$", createAs4Value("65005.1"))},
  1366  	}
  1367  
  1368  	ps := createPrefixSet("ps1", "10.10.1.0/16", "21..24")
  1369  	ns := createNeighborSet("ns1", "10.0.0.1")
  1370  
  1371  	ds := config.DefinedSets{}
  1372  	ds.PrefixSets = []config.PrefixSet{ps}
  1373  	ds.NeighborSets = []config.NeighborSet{ns}
  1374  	ds.BgpDefinedSets.AsPathSets = []config.AsPathSet{asPathSet}
  1375  
  1376  	s := createStatement("statement1", "ps1", "ns1", false)
  1377  	s.Conditions.BgpConditions.MatchAsPathSet.AsPathSet = "asset1"
  1378  
  1379  	pd := createPolicyDefinition("pd1", s)
  1380  	pl := createRoutingPolicy(ds, pd)
  1381  
  1382  	//test
  1383  	r := NewRoutingPolicy()
  1384  	r.reload(pl)
  1385  	p, _ := NewPolicy(pl.PolicyDefinitions[0])
  1386  	addPolicy(r, p)
  1387  	pType, newPath := p.Apply(path, nil)
  1388  	assert.Equal(t, ROUTE_TYPE_REJECT, pType)
  1389  	assert.Equal(t, newPath, path)
  1390  
  1391  }
  1392  
  1393  func TestAs4PathConditionEvaluateMixedWith2byteAS(t *testing.T) {
  1394  
  1395  	// setup
  1396  	// create path
  1397  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1398  	origin := bgp.NewPathAttributeOrigin(0)
  1399  	aspathParam1 := []bgp.AsPathParamInterface{
  1400  		bgp.NewAs4PathParam(2, []uint32{
  1401  			createAs4Value("65001.1"),
  1402  			createAs4Value("65000.1"),
  1403  			createAs4Value("54000.1"),
  1404  			100,
  1405  			5000,
  1406  			createAs4Value("65004.1"),
  1407  			createAs4Value("65005.1"),
  1408  			4000,
  1409  		}),
  1410  	}
  1411  
  1412  	aspath := bgp.NewPathAttributeAsPath(aspathParam1)
  1413  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1414  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1415  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  1416  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1417  	updateMsg1 := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1418  	UpdatePathAttrs4ByteAs(updateMsg1.Body.(*bgp.BGPUpdate))
  1419  	path1 := ProcessMessage(updateMsg1, peer, time.Now())[0]
  1420  
  1421  	// create match condition
  1422  	asPathSet1 := config.AsPathSet{
  1423  		AsPathSetName: "asset1",
  1424  		AsPathList:    []string{fmt.Sprintf("^%d", createAs4Value("65001.1"))},
  1425  	}
  1426  
  1427  	asPathSet2 := config.AsPathSet{
  1428  		AsPathSetName: "asset2",
  1429  		AsPathList:    []string{"4000$"},
  1430  	}
  1431  
  1432  	asPathSet3 := config.AsPathSet{
  1433  		AsPathSetName: "asset3",
  1434  		AsPathList:    []string{fmt.Sprintf("%d", createAs4Value("65004.1")), "4000$"},
  1435  	}
  1436  
  1437  	asPathSet4 := config.AsPathSet{
  1438  		AsPathSetName: "asset4",
  1439  		AsPathList:    []string{fmt.Sprintf("%d_%d_%d", createAs4Value("54000.1"), 100, 5000)},
  1440  	}
  1441  
  1442  	asPathSet5 := config.AsPathSet{
  1443  		AsPathSetName: "asset5",
  1444  		AsPathList:    []string{".*_[0-9]+_100"},
  1445  	}
  1446  
  1447  	asPathSet6 := config.AsPathSet{
  1448  		AsPathSetName: "asset6",
  1449  		AsPathList:    []string{".*_3[0-9]+_[0]+"},
  1450  	}
  1451  
  1452  	asPathSet7 := config.AsPathSet{
  1453  		AsPathSetName: "asset7",
  1454  		AsPathList:    []string{".*_3[0-9]+_[1]+"},
  1455  	}
  1456  
  1457  	m := make(map[string]DefinedSet)
  1458  	for _, s := range []config.AsPathSet{asPathSet1, asPathSet2, asPathSet3,
  1459  		asPathSet4, asPathSet5, asPathSet6, asPathSet7} {
  1460  		a, _ := NewAsPathSet(s)
  1461  		m[s.AsPathSetName] = a
  1462  	}
  1463  
  1464  	createAspathC := func(name string, option config.MatchSetOptionsType) *AsPathCondition {
  1465  		matchSet := config.MatchAsPathSet{}
  1466  		matchSet.AsPathSet = name
  1467  		matchSet.MatchSetOptions = option
  1468  		p, _ := NewAsPathCondition(matchSet)
  1469  		if v, ok := m[name]; ok {
  1470  			p.set = v.(*AsPathSet)
  1471  		}
  1472  		return p
  1473  	}
  1474  
  1475  	p1 := createAspathC("asset1", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1476  	p2 := createAspathC("asset2", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1477  	p3 := createAspathC("asset3", config.MATCH_SET_OPTIONS_TYPE_ALL)
  1478  	p4 := createAspathC("asset4", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1479  	p5 := createAspathC("asset5", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1480  	p6 := createAspathC("asset6", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1481  	p7 := createAspathC("asset7", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1482  
  1483  	// test
  1484  	assert.Equal(t, true, p1.Evaluate(path1, nil))
  1485  	assert.Equal(t, true, p2.Evaluate(path1, nil))
  1486  	assert.Equal(t, true, p3.Evaluate(path1, nil))
  1487  	assert.Equal(t, true, p4.Evaluate(path1, nil))
  1488  	assert.Equal(t, true, p5.Evaluate(path1, nil))
  1489  	assert.Equal(t, false, p6.Evaluate(path1, nil))
  1490  	assert.Equal(t, true, p7.Evaluate(path1, nil))
  1491  
  1492  }
  1493  
  1494  func TestCommunityConditionEvaluate(t *testing.T) {
  1495  
  1496  	// setup
  1497  	// create path
  1498  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1499  	origin := bgp.NewPathAttributeOrigin(0)
  1500  	aspathParam1 := []bgp.AsPathParamInterface{
  1501  		bgp.NewAsPathParam(2, []uint16{65001, 65000, 65004, 65005}),
  1502  		bgp.NewAsPathParam(1, []uint16{65001, 65010, 65004, 65005}),
  1503  	}
  1504  	aspath := bgp.NewPathAttributeAsPath(aspathParam1)
  1505  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1506  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1507  	communities := bgp.NewPathAttributeCommunities([]uint32{
  1508  		stringToCommunityValue("65001:100"),
  1509  		stringToCommunityValue("65001:200"),
  1510  		stringToCommunityValue("65001:300"),
  1511  		stringToCommunityValue("65001:400"),
  1512  		0x00000000,
  1513  		0xFFFFFF01,
  1514  		0xFFFFFF02,
  1515  		0xFFFFFF03})
  1516  
  1517  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, communities}
  1518  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1519  	updateMsg1 := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1520  	UpdatePathAttrs4ByteAs(updateMsg1.Body.(*bgp.BGPUpdate))
  1521  	path1 := ProcessMessage(updateMsg1, peer, time.Now())[0]
  1522  
  1523  	communities2 := bgp.NewPathAttributeCommunities([]uint32{
  1524  		stringToCommunityValue("65001:100"),
  1525  		stringToCommunityValue("65001:200"),
  1526  		stringToCommunityValue("65001:300"),
  1527  		stringToCommunityValue("65001:400")})
  1528  
  1529  	pathAttributes2 := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, communities2}
  1530  	updateMsg2 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nlri)
  1531  	UpdatePathAttrs4ByteAs(updateMsg2.Body.(*bgp.BGPUpdate))
  1532  	path2 := ProcessMessage(updateMsg2, peer, time.Now())[0]
  1533  
  1534  	// create match condition
  1535  	comSet1 := config.CommunitySet{
  1536  		CommunitySetName: "comset1",
  1537  		CommunityList:    []string{"65001:10", "65001:50", "65001:100"},
  1538  	}
  1539  
  1540  	comSet2 := config.CommunitySet{
  1541  		CommunitySetName: "comset2",
  1542  		CommunityList:    []string{"65001:200"},
  1543  	}
  1544  
  1545  	comSet3 := config.CommunitySet{
  1546  		CommunitySetName: "comset3",
  1547  		CommunityList:    []string{"4259905936"},
  1548  	}
  1549  
  1550  	comSet4 := config.CommunitySet{
  1551  		CommunitySetName: "comset4",
  1552  		CommunityList:    []string{"^[0-9]*:300$"},
  1553  	}
  1554  
  1555  	comSet5 := config.CommunitySet{
  1556  		CommunitySetName: "comset5",
  1557  		CommunityList:    []string{"INTERNET"},
  1558  	}
  1559  
  1560  	comSet6 := config.CommunitySet{
  1561  		CommunitySetName: "comset6",
  1562  		CommunityList:    []string{"NO_EXPORT"},
  1563  	}
  1564  
  1565  	comSet7 := config.CommunitySet{
  1566  		CommunitySetName: "comset7",
  1567  		CommunityList:    []string{"NO_ADVERTISE"},
  1568  	}
  1569  
  1570  	comSet8 := config.CommunitySet{
  1571  		CommunitySetName: "comset8",
  1572  		CommunityList:    []string{"NO_EXPORT_SUBCONFED"},
  1573  	}
  1574  
  1575  	comSet9 := config.CommunitySet{
  1576  		CommunitySetName: "comset9",
  1577  		CommunityList: []string{
  1578  			"65001:\\d+",
  1579  			"\\d+:\\d00",
  1580  		},
  1581  	}
  1582  
  1583  	comSet10 := config.CommunitySet{
  1584  		CommunitySetName: "comset10",
  1585  		CommunityList: []string{
  1586  			"65001:1",
  1587  			"65001:2",
  1588  			"65001:3",
  1589  		},
  1590  	}
  1591  
  1592  	m := make(map[string]DefinedSet)
  1593  
  1594  	for _, c := range []config.CommunitySet{comSet1, comSet2, comSet3,
  1595  		comSet4, comSet5, comSet6, comSet7, comSet8, comSet9, comSet10} {
  1596  		s, _ := NewCommunitySet(c)
  1597  		m[c.CommunitySetName] = s
  1598  	}
  1599  
  1600  	createCommunityC := func(name string, option config.MatchSetOptionsType) *CommunityCondition {
  1601  		matchSet := config.MatchCommunitySet{}
  1602  		matchSet.CommunitySet = name
  1603  		matchSet.MatchSetOptions = option
  1604  		c, _ := NewCommunityCondition(matchSet)
  1605  		if v, ok := m[name]; ok {
  1606  			c.set = v.(*CommunitySet)
  1607  		}
  1608  		return c
  1609  	}
  1610  
  1611  	// ANY case
  1612  	p1 := createCommunityC("comset1", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1613  	p2 := createCommunityC("comset2", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1614  	p3 := createCommunityC("comset3", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1615  	p4 := createCommunityC("comset4", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1616  	p5 := createCommunityC("comset5", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1617  	p6 := createCommunityC("comset6", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1618  	p7 := createCommunityC("comset7", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1619  	p8 := createCommunityC("comset8", config.MATCH_SET_OPTIONS_TYPE_ANY)
  1620  
  1621  	// ALL case
  1622  	p9 := createCommunityC("comset9", config.MATCH_SET_OPTIONS_TYPE_ALL)
  1623  
  1624  	// INVERT case
  1625  	p10 := createCommunityC("comset10", config.MATCH_SET_OPTIONS_TYPE_INVERT)
  1626  
  1627  	// test
  1628  	assert.Equal(t, true, p1.Evaluate(path1, nil))
  1629  	assert.Equal(t, true, p2.Evaluate(path1, nil))
  1630  	assert.Equal(t, true, p3.Evaluate(path1, nil))
  1631  	assert.Equal(t, true, p4.Evaluate(path1, nil))
  1632  	assert.Equal(t, true, p5.Evaluate(path1, nil))
  1633  	assert.Equal(t, true, p6.Evaluate(path1, nil))
  1634  	assert.Equal(t, true, p7.Evaluate(path1, nil))
  1635  	assert.Equal(t, true, p8.Evaluate(path1, nil))
  1636  	assert.Equal(t, true, p9.Evaluate(path2, nil))
  1637  	assert.Equal(t, true, p10.Evaluate(path1, nil))
  1638  
  1639  }
  1640  
  1641  func TestCommunityConditionEvaluateWithOtherCondition(t *testing.T) {
  1642  
  1643  	// setup
  1644  	// create path
  1645  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1646  	origin := bgp.NewPathAttributeOrigin(0)
  1647  	aspathParam := []bgp.AsPathParamInterface{
  1648  		bgp.NewAsPathParam(1, []uint16{65001, 65000, 65004, 65005}),
  1649  		bgp.NewAsPathParam(2, []uint16{65001, 65000, 65004, 65004, 65005}),
  1650  	}
  1651  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  1652  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1653  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1654  	communities := bgp.NewPathAttributeCommunities([]uint32{
  1655  		stringToCommunityValue("65001:100"),
  1656  		stringToCommunityValue("65001:200"),
  1657  		stringToCommunityValue("65001:300"),
  1658  		stringToCommunityValue("65001:400"),
  1659  		0x00000000,
  1660  		0xFFFFFF01,
  1661  		0xFFFFFF02,
  1662  		0xFFFFFF03})
  1663  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, communities}
  1664  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1665  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1666  	UpdatePathAttrs4ByteAs(updateMsg.Body.(*bgp.BGPUpdate))
  1667  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  1668  
  1669  	// create policy
  1670  	asPathSet := config.AsPathSet{
  1671  		AsPathSetName: "asset1",
  1672  		AsPathList:    []string{"65005$"},
  1673  	}
  1674  
  1675  	comSet1 := config.CommunitySet{
  1676  		CommunitySetName: "comset1",
  1677  		CommunityList:    []string{"65001:100", "65001:200", "65001:300"},
  1678  	}
  1679  
  1680  	comSet2 := config.CommunitySet{
  1681  		CommunitySetName: "comset2",
  1682  		CommunityList:    []string{"65050:\\d+"},
  1683  	}
  1684  
  1685  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  1686  	ns := createNeighborSet("ns1", "10.0.0.1")
  1687  
  1688  	ds := config.DefinedSets{}
  1689  	ds.PrefixSets = []config.PrefixSet{ps}
  1690  	ds.NeighborSets = []config.NeighborSet{ns}
  1691  	ds.BgpDefinedSets.AsPathSets = []config.AsPathSet{asPathSet}
  1692  	ds.BgpDefinedSets.CommunitySets = []config.CommunitySet{comSet1, comSet2}
  1693  
  1694  	s1 := createStatement("statement1", "ps1", "ns1", false)
  1695  	s1.Conditions.BgpConditions.MatchAsPathSet.AsPathSet = "asset1"
  1696  	s1.Conditions.BgpConditions.MatchCommunitySet.CommunitySet = "comset1"
  1697  
  1698  	s2 := createStatement("statement2", "ps1", "ns1", false)
  1699  	s2.Conditions.BgpConditions.MatchAsPathSet.AsPathSet = "asset1"
  1700  	s2.Conditions.BgpConditions.MatchCommunitySet.CommunitySet = "comset2"
  1701  
  1702  	pd1 := createPolicyDefinition("pd1", s1)
  1703  	pd2 := createPolicyDefinition("pd2", s2)
  1704  	pl := createRoutingPolicy(ds, pd1, pd2)
  1705  
  1706  	//test
  1707  	r := NewRoutingPolicy()
  1708  	err := r.reload(pl)
  1709  	assert.Nil(t, err)
  1710  	p := r.policyMap["pd1"]
  1711  	pType, newPath := p.Apply(path, nil)
  1712  	assert.Equal(t, ROUTE_TYPE_REJECT, pType)
  1713  	assert.Equal(t, newPath, path)
  1714  
  1715  	p = r.policyMap["pd2"]
  1716  	pType, newPath = p.Apply(path, nil)
  1717  	assert.Equal(t, ROUTE_TYPE_NONE, pType)
  1718  	assert.Equal(t, newPath, path)
  1719  
  1720  }
  1721  
  1722  func TestPolicyMatchAndAddCommunities(t *testing.T) {
  1723  
  1724  	// create path
  1725  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1726  	origin := bgp.NewPathAttributeOrigin(0)
  1727  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  1728  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  1729  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1730  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1731  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  1732  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1733  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1734  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  1735  	// create policy
  1736  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  1737  	ns := createNeighborSet("ns1", "10.0.0.1")
  1738  
  1739  	ds := config.DefinedSets{}
  1740  	ds.PrefixSets = []config.PrefixSet{ps}
  1741  	ds.NeighborSets = []config.NeighborSet{ns}
  1742  
  1743  	community := "65000:100"
  1744  
  1745  	s := createStatement("statement1", "ps1", "ns1", true)
  1746  	s.Actions.BgpActions.SetCommunity = createSetCommunity("ADD", community)
  1747  
  1748  	pd := createPolicyDefinition("pd1", s)
  1749  	pl := createRoutingPolicy(ds, pd)
  1750  
  1751  	//test
  1752  	r := NewRoutingPolicy()
  1753  	err := r.reload(pl)
  1754  	assert.Nil(t, err)
  1755  	p := r.policyMap["pd1"]
  1756  
  1757  	pType, newPath := p.Apply(path, nil)
  1758  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  1759  	assert.NotEqual(t, nil, newPath)
  1760  	assert.Equal(t, []uint32{stringToCommunityValue(community)}, newPath.GetCommunities())
  1761  }
  1762  
  1763  func TestPolicyMatchAndReplaceCommunities(t *testing.T) {
  1764  
  1765  	// create path
  1766  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1767  	origin := bgp.NewPathAttributeOrigin(0)
  1768  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  1769  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  1770  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1771  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1772  	communities := bgp.NewPathAttributeCommunities([]uint32{
  1773  		stringToCommunityValue("65001:200"),
  1774  	})
  1775  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, communities}
  1776  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1777  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1778  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  1779  	// create policy
  1780  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  1781  	ns := createNeighborSet("ns1", "10.0.0.1")
  1782  
  1783  	ds := config.DefinedSets{}
  1784  	ds.PrefixSets = []config.PrefixSet{ps}
  1785  	ds.NeighborSets = []config.NeighborSet{ns}
  1786  
  1787  	community := "65000:100"
  1788  
  1789  	s := createStatement("statement1", "ps1", "ns1", true)
  1790  	s.Actions.BgpActions.SetCommunity = createSetCommunity("REPLACE", community)
  1791  
  1792  	pd := createPolicyDefinition("pd1", s)
  1793  	pl := createRoutingPolicy(ds, pd)
  1794  
  1795  	//test
  1796  	r := NewRoutingPolicy()
  1797  	err := r.reload(pl)
  1798  	assert.Nil(t, err)
  1799  	p := r.policyMap["pd1"]
  1800  
  1801  	pType, newPath := p.Apply(path, nil)
  1802  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  1803  	assert.NotEqual(t, nil, newPath)
  1804  	assert.Equal(t, []uint32{stringToCommunityValue(community)}, newPath.GetCommunities())
  1805  }
  1806  
  1807  func TestPolicyMatchAndRemoveCommunities(t *testing.T) {
  1808  
  1809  	// create path
  1810  	community1 := "65000:100"
  1811  	community2 := "65000:200"
  1812  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1813  	origin := bgp.NewPathAttributeOrigin(0)
  1814  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  1815  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  1816  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1817  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1818  	communities := bgp.NewPathAttributeCommunities([]uint32{
  1819  		stringToCommunityValue(community1),
  1820  		stringToCommunityValue(community2),
  1821  	})
  1822  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, communities}
  1823  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1824  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1825  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  1826  	// create policy
  1827  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  1828  	ns := createNeighborSet("ns1", "10.0.0.1")
  1829  
  1830  	ds := config.DefinedSets{}
  1831  	ds.PrefixSets = []config.PrefixSet{ps}
  1832  	ds.NeighborSets = []config.NeighborSet{ns}
  1833  
  1834  	s := createStatement("statement1", "ps1", "ns1", true)
  1835  	s.Actions.BgpActions.SetCommunity = createSetCommunity("REMOVE", community1)
  1836  
  1837  	pd := createPolicyDefinition("pd1", s)
  1838  	pl := createRoutingPolicy(ds, pd)
  1839  
  1840  	//test
  1841  	r := NewRoutingPolicy()
  1842  	err := r.reload(pl)
  1843  	assert.Nil(t, err)
  1844  	p := r.policyMap["pd1"]
  1845  	pType, newPath := p.Apply(path, nil)
  1846  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  1847  	assert.NotEqual(t, nil, newPath)
  1848  	assert.Equal(t, []uint32{stringToCommunityValue(community2)}, newPath.GetCommunities())
  1849  }
  1850  
  1851  func TestPolicyMatchAndRemoveCommunitiesRegexp(t *testing.T) {
  1852  
  1853  	// create path
  1854  	community1 := "65000:100"
  1855  	community2 := "65000:200"
  1856  	community3 := "65100:100"
  1857  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1858  	origin := bgp.NewPathAttributeOrigin(0)
  1859  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  1860  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  1861  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1862  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1863  	communities := bgp.NewPathAttributeCommunities([]uint32{
  1864  		stringToCommunityValue(community1),
  1865  		stringToCommunityValue(community2),
  1866  		stringToCommunityValue(community3),
  1867  	})
  1868  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, communities}
  1869  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1870  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1871  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  1872  	// create policy
  1873  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  1874  	ns := createNeighborSet("ns1", "10.0.0.1")
  1875  
  1876  	ds := config.DefinedSets{}
  1877  	ds.PrefixSets = []config.PrefixSet{ps}
  1878  	ds.NeighborSets = []config.NeighborSet{ns}
  1879  
  1880  	s := createStatement("statement1", "ps1", "ns1", true)
  1881  	s.Actions.BgpActions.SetCommunity = createSetCommunity("REMOVE", ".*:100")
  1882  
  1883  	pd := createPolicyDefinition("pd1", s)
  1884  	pl := createRoutingPolicy(ds, pd)
  1885  
  1886  	//test
  1887  	r := NewRoutingPolicy()
  1888  	err := r.reload(pl)
  1889  	assert.Nil(t, err)
  1890  	p := r.policyMap["pd1"]
  1891  	pType, newPath := p.Apply(path, nil)
  1892  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  1893  	assert.NotEqual(t, nil, newPath)
  1894  	assert.Equal(t, []uint32{stringToCommunityValue(community2)}, newPath.GetCommunities())
  1895  }
  1896  
  1897  func TestPolicyMatchAndRemoveCommunitiesRegexp2(t *testing.T) {
  1898  
  1899  	// create path
  1900  	community1 := "0:1"
  1901  	community2 := "10:1"
  1902  	community3 := "45686:2"
  1903  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1904  	origin := bgp.NewPathAttributeOrigin(0)
  1905  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  1906  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  1907  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1908  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1909  	communities := bgp.NewPathAttributeCommunities([]uint32{
  1910  		stringToCommunityValue(community1),
  1911  		stringToCommunityValue(community2),
  1912  		stringToCommunityValue(community3),
  1913  	})
  1914  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, communities}
  1915  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1916  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1917  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  1918  	// create policy
  1919  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  1920  	ns := createNeighborSet("ns1", "10.0.0.1")
  1921  
  1922  	ds := config.DefinedSets{}
  1923  	ds.PrefixSets = []config.PrefixSet{ps}
  1924  	ds.NeighborSets = []config.NeighborSet{ns}
  1925  
  1926  	s := createStatement("statement1", "ps1", "ns1", true)
  1927  	s.Actions.BgpActions.SetCommunity = createSetCommunity("REMOVE", "^(0|45686):[0-9]+")
  1928  
  1929  	pd := createPolicyDefinition("pd1", s)
  1930  	pl := createRoutingPolicy(ds, pd)
  1931  
  1932  	//test
  1933  	r := NewRoutingPolicy()
  1934  	err := r.reload(pl)
  1935  	assert.Nil(t, err)
  1936  	p := r.policyMap["pd1"]
  1937  	pType, newPath := p.Apply(path, nil)
  1938  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  1939  	assert.NotEqual(t, nil, newPath)
  1940  	assert.Equal(t, []uint32{stringToCommunityValue(community2)}, newPath.GetCommunities())
  1941  }
  1942  
  1943  func TestPolicyMatchAndClearCommunities(t *testing.T) {
  1944  
  1945  	// create path
  1946  	community1 := "65000:100"
  1947  	community2 := "65000:200"
  1948  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1949  	origin := bgp.NewPathAttributeOrigin(0)
  1950  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  1951  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  1952  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1953  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1954  	communities := bgp.NewPathAttributeCommunities([]uint32{
  1955  		stringToCommunityValue(community1),
  1956  		stringToCommunityValue(community2),
  1957  	})
  1958  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, communities}
  1959  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1960  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1961  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  1962  	// create policy
  1963  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  1964  	ns := createNeighborSet("ns1", "10.0.0.1")
  1965  
  1966  	ds := config.DefinedSets{}
  1967  	ds.PrefixSets = []config.PrefixSet{ps}
  1968  	ds.NeighborSets = []config.NeighborSet{ns}
  1969  
  1970  	s := createStatement("statement1", "ps1", "ns1", true)
  1971  	// action NULL is obsolate
  1972  	s.Actions.BgpActions.SetCommunity.Options = "REPLACE"
  1973  	s.Actions.BgpActions.SetCommunity.SetCommunityMethod.CommunitiesList = nil
  1974  
  1975  	pd := createPolicyDefinition("pd1", s)
  1976  	pl := createRoutingPolicy(ds, pd)
  1977  
  1978  	//test
  1979  	r := NewRoutingPolicy()
  1980  	err := r.reload(pl)
  1981  	assert.Nil(t, err)
  1982  	p := r.policyMap["pd1"]
  1983  
  1984  	pType, newPath := p.Apply(path, nil)
  1985  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  1986  	assert.NotEqual(t, nil, newPath)
  1987  	//assert.Equal(t, []uint32{}, newPath.GetCommunities())
  1988  }
  1989  
  1990  func TestExtCommunityConditionEvaluate(t *testing.T) {
  1991  
  1992  	// setup
  1993  	// create path
  1994  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1995  	origin := bgp.NewPathAttributeOrigin(0)
  1996  	aspathParam1 := []bgp.AsPathParamInterface{
  1997  		bgp.NewAsPathParam(2, []uint16{65001, 65000, 65004, 65005}),
  1998  		bgp.NewAsPathParam(1, []uint16{65001, 65010, 65004, 65005}),
  1999  	}
  2000  	aspath := bgp.NewPathAttributeAsPath(aspathParam1)
  2001  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2002  	med := bgp.NewPathAttributeMultiExitDisc(0)
  2003  	eComAsSpecific1 := &bgp.TwoOctetAsSpecificExtended{
  2004  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2005  		AS:           65001,
  2006  		LocalAdmin:   200,
  2007  		IsTransitive: true,
  2008  	}
  2009  	eComIpPrefix1 := &bgp.IPv4AddressSpecificExtended{
  2010  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2011  		IPv4:         net.ParseIP("10.0.0.1"),
  2012  		LocalAdmin:   300,
  2013  		IsTransitive: true,
  2014  	}
  2015  	eComAs4Specific1 := &bgp.FourOctetAsSpecificExtended{
  2016  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2017  		AS:           65030000,
  2018  		LocalAdmin:   200,
  2019  		IsTransitive: true,
  2020  	}
  2021  	eComAsSpecific2 := &bgp.TwoOctetAsSpecificExtended{
  2022  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2023  		AS:           65002,
  2024  		LocalAdmin:   200,
  2025  		IsTransitive: false,
  2026  	}
  2027  	eComIpPrefix2 := &bgp.IPv4AddressSpecificExtended{
  2028  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2029  		IPv4:         net.ParseIP("10.0.0.2"),
  2030  		LocalAdmin:   300,
  2031  		IsTransitive: false,
  2032  	}
  2033  	eComAs4Specific2 := &bgp.FourOctetAsSpecificExtended{
  2034  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2035  		AS:           65030001,
  2036  		LocalAdmin:   200,
  2037  		IsTransitive: false,
  2038  	}
  2039  	eComAsSpecific3 := &bgp.TwoOctetAsSpecificExtended{
  2040  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_ORIGIN),
  2041  		AS:           65010,
  2042  		LocalAdmin:   300,
  2043  		IsTransitive: true,
  2044  	}
  2045  	eComIpPrefix3 := &bgp.IPv4AddressSpecificExtended{
  2046  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_ORIGIN),
  2047  		IPv4:         net.ParseIP("10.0.10.10"),
  2048  		LocalAdmin:   400,
  2049  		IsTransitive: true,
  2050  	}
  2051  	eComAs4Specific3 := &bgp.FourOctetAsSpecificExtended{
  2052  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2053  		AS:           65030002,
  2054  		LocalAdmin:   500,
  2055  		IsTransitive: true,
  2056  	}
  2057  	ec := []bgp.ExtendedCommunityInterface{eComAsSpecific1, eComIpPrefix1, eComAs4Specific1, eComAsSpecific2,
  2058  		eComIpPrefix2, eComAs4Specific2, eComAsSpecific3, eComIpPrefix3, eComAs4Specific3}
  2059  	extCommunities := bgp.NewPathAttributeExtendedCommunities(ec)
  2060  
  2061  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, extCommunities}
  2062  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2063  	updateMsg1 := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2064  	UpdatePathAttrs4ByteAs(updateMsg1.Body.(*bgp.BGPUpdate))
  2065  	path1 := ProcessMessage(updateMsg1, peer, time.Now())[0]
  2066  
  2067  	convUintStr := func(as uint32) string {
  2068  		upper := strconv.FormatUint(uint64(as&0xFFFF0000>>16), 10)
  2069  		lower := strconv.FormatUint(uint64(as&0x0000FFFF), 10)
  2070  		str := fmt.Sprintf("%s.%s", upper, lower)
  2071  		return str
  2072  	}
  2073  
  2074  	// create match condition
  2075  	ecomSet1 := config.ExtCommunitySet{
  2076  		ExtCommunitySetName: "ecomSet1",
  2077  		ExtCommunityList:    []string{"RT:65001:200"},
  2078  	}
  2079  	ecomSet2 := config.ExtCommunitySet{
  2080  		ExtCommunitySetName: "ecomSet2",
  2081  		ExtCommunityList:    []string{"RT:10.0.0.1:300"},
  2082  	}
  2083  	ecomSet3 := config.ExtCommunitySet{
  2084  		ExtCommunitySetName: "ecomSet3",
  2085  		ExtCommunityList:    []string{fmt.Sprintf("RT:%s:200", convUintStr(65030000))},
  2086  	}
  2087  	ecomSet4 := config.ExtCommunitySet{
  2088  		ExtCommunitySetName: "ecomSet4",
  2089  		ExtCommunityList:    []string{"RT:65002:200"},
  2090  	}
  2091  	ecomSet5 := config.ExtCommunitySet{
  2092  		ExtCommunitySetName: "ecomSet5",
  2093  		ExtCommunityList:    []string{"RT:10.0.0.2:300"},
  2094  	}
  2095  	ecomSet6 := config.ExtCommunitySet{
  2096  		ExtCommunitySetName: "ecomSet6",
  2097  		ExtCommunityList:    []string{fmt.Sprintf("RT:%s:200", convUintStr(65030001))},
  2098  	}
  2099  	ecomSet7 := config.ExtCommunitySet{
  2100  		ExtCommunitySetName: "ecomSet7",
  2101  		ExtCommunityList:    []string{"SoO:65010:300"},
  2102  	}
  2103  	ecomSet8 := config.ExtCommunitySet{
  2104  		ExtCommunitySetName: "ecomSet8",
  2105  		ExtCommunityList:    []string{"SoO:10.0.10.10:[0-9]+"},
  2106  	}
  2107  	ecomSet9 := config.ExtCommunitySet{
  2108  		ExtCommunitySetName: "ecomSet9",
  2109  		ExtCommunityList:    []string{"RT:[0-9]+:[0-9]+"},
  2110  	}
  2111  	ecomSet10 := config.ExtCommunitySet{
  2112  		ExtCommunitySetName: "ecomSet10",
  2113  		ExtCommunityList:    []string{"RT:.+:\\d00", "SoO:.+:\\d00"},
  2114  	}
  2115  
  2116  	ecomSet11 := config.ExtCommunitySet{
  2117  		ExtCommunitySetName: "ecomSet11",
  2118  		ExtCommunityList:    []string{"RT:65001:2", "SoO:11.0.10.10:[0-9]+"},
  2119  	}
  2120  
  2121  	m := make(map[string]DefinedSet)
  2122  	for _, c := range []config.ExtCommunitySet{ecomSet1, ecomSet2, ecomSet3, ecomSet4, ecomSet5, ecomSet6, ecomSet7,
  2123  		ecomSet8, ecomSet9, ecomSet10, ecomSet11} {
  2124  		s, _ := NewExtCommunitySet(c)
  2125  		m[s.Name()] = s
  2126  	}
  2127  
  2128  	createExtCommunityC := func(name string, option config.MatchSetOptionsType) *ExtCommunityCondition {
  2129  		matchSet := config.MatchExtCommunitySet{}
  2130  		matchSet.ExtCommunitySet = name
  2131  		matchSet.MatchSetOptions = option
  2132  		c, _ := NewExtCommunityCondition(matchSet)
  2133  		if v, ok := m[name]; ok {
  2134  			c.set = v.(*ExtCommunitySet)
  2135  		}
  2136  
  2137  		return c
  2138  	}
  2139  
  2140  	p1 := createExtCommunityC("ecomSet1", config.MATCH_SET_OPTIONS_TYPE_ANY)
  2141  	p2 := createExtCommunityC("ecomSet2", config.MATCH_SET_OPTIONS_TYPE_ANY)
  2142  	p3 := createExtCommunityC("ecomSet3", config.MATCH_SET_OPTIONS_TYPE_ANY)
  2143  	p4 := createExtCommunityC("ecomSet4", config.MATCH_SET_OPTIONS_TYPE_ANY)
  2144  	p5 := createExtCommunityC("ecomSet5", config.MATCH_SET_OPTIONS_TYPE_ANY)
  2145  	p6 := createExtCommunityC("ecomSet6", config.MATCH_SET_OPTIONS_TYPE_ANY)
  2146  	p7 := createExtCommunityC("ecomSet7", config.MATCH_SET_OPTIONS_TYPE_ANY)
  2147  	p8 := createExtCommunityC("ecomSet8", config.MATCH_SET_OPTIONS_TYPE_ANY)
  2148  	p9 := createExtCommunityC("ecomSet9", config.MATCH_SET_OPTIONS_TYPE_ANY)
  2149  
  2150  	// ALL case
  2151  	p10 := createExtCommunityC("ecomSet10", config.MATCH_SET_OPTIONS_TYPE_ALL)
  2152  
  2153  	// INVERT case
  2154  	p11 := createExtCommunityC("ecomSet11", config.MATCH_SET_OPTIONS_TYPE_INVERT)
  2155  
  2156  	// test
  2157  	assert.Equal(t, true, p1.Evaluate(path1, nil))
  2158  	assert.Equal(t, true, p2.Evaluate(path1, nil))
  2159  	assert.Equal(t, true, p3.Evaluate(path1, nil))
  2160  	assert.Equal(t, false, p4.Evaluate(path1, nil))
  2161  	assert.Equal(t, false, p5.Evaluate(path1, nil))
  2162  	assert.Equal(t, false, p6.Evaluate(path1, nil))
  2163  	assert.Equal(t, true, p7.Evaluate(path1, nil))
  2164  	assert.Equal(t, true, p8.Evaluate(path1, nil))
  2165  	assert.Equal(t, true, p9.Evaluate(path1, nil))
  2166  	assert.Equal(t, true, p10.Evaluate(path1, nil))
  2167  	assert.Equal(t, true, p11.Evaluate(path1, nil))
  2168  
  2169  }
  2170  
  2171  func TestExtCommunityConditionEvaluateWithOtherCondition(t *testing.T) {
  2172  
  2173  	// setup
  2174  	// create path
  2175  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.2.1.1")}
  2176  	origin := bgp.NewPathAttributeOrigin(0)
  2177  	aspathParam := []bgp.AsPathParamInterface{
  2178  		bgp.NewAsPathParam(1, []uint16{65001, 65000, 65004, 65005}),
  2179  		bgp.NewAsPathParam(2, []uint16{65001, 65000, 65004, 65004, 65005}),
  2180  	}
  2181  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2182  	nexthop := bgp.NewPathAttributeNextHop("10.2.1.1")
  2183  	med := bgp.NewPathAttributeMultiExitDisc(0)
  2184  	eComAsSpecific1 := &bgp.TwoOctetAsSpecificExtended{
  2185  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2186  		AS:           65001,
  2187  		LocalAdmin:   200,
  2188  		IsTransitive: true,
  2189  	}
  2190  	eComIpPrefix1 := &bgp.IPv4AddressSpecificExtended{
  2191  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2192  		IPv4:         net.ParseIP("10.0.0.1"),
  2193  		LocalAdmin:   300,
  2194  		IsTransitive: true,
  2195  	}
  2196  	eComAs4Specific1 := &bgp.FourOctetAsSpecificExtended{
  2197  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2198  		AS:           65030000,
  2199  		LocalAdmin:   200,
  2200  		IsTransitive: true,
  2201  	}
  2202  	eComAsSpecific2 := &bgp.TwoOctetAsSpecificExtended{
  2203  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2204  		AS:           65002,
  2205  		LocalAdmin:   200,
  2206  		IsTransitive: false,
  2207  	}
  2208  	eComIpPrefix2 := &bgp.IPv4AddressSpecificExtended{
  2209  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2210  		IPv4:         net.ParseIP("10.0.0.2"),
  2211  		LocalAdmin:   300,
  2212  		IsTransitive: false,
  2213  	}
  2214  	eComAs4Specific2 := &bgp.FourOctetAsSpecificExtended{
  2215  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2216  		AS:           65030001,
  2217  		LocalAdmin:   200,
  2218  		IsTransitive: false,
  2219  	}
  2220  	eComAsSpecific3 := &bgp.TwoOctetAsSpecificExtended{
  2221  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_ORIGIN),
  2222  		AS:           65010,
  2223  		LocalAdmin:   300,
  2224  		IsTransitive: true,
  2225  	}
  2226  	eComIpPrefix3 := &bgp.IPv4AddressSpecificExtended{
  2227  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_ORIGIN),
  2228  		IPv4:         net.ParseIP("10.0.10.10"),
  2229  		LocalAdmin:   400,
  2230  		IsTransitive: true,
  2231  	}
  2232  	eComAs4Specific3 := &bgp.FourOctetAsSpecificExtended{
  2233  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2234  		AS:           65030002,
  2235  		LocalAdmin:   500,
  2236  		IsTransitive: true,
  2237  	}
  2238  	ec := []bgp.ExtendedCommunityInterface{eComAsSpecific1, eComIpPrefix1, eComAs4Specific1, eComAsSpecific2,
  2239  		eComIpPrefix2, eComAs4Specific2, eComAsSpecific3, eComIpPrefix3, eComAs4Specific3}
  2240  	extCommunities := bgp.NewPathAttributeExtendedCommunities(ec)
  2241  
  2242  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, extCommunities}
  2243  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2244  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2245  	UpdatePathAttrs4ByteAs(updateMsg.Body.(*bgp.BGPUpdate))
  2246  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2247  
  2248  	// create policy
  2249  	asPathSet := config.AsPathSet{
  2250  		AsPathSetName: "asset1",
  2251  		AsPathList:    []string{"65005$"},
  2252  	}
  2253  
  2254  	ecomSet1 := config.ExtCommunitySet{
  2255  		ExtCommunitySetName: "ecomSet1",
  2256  		ExtCommunityList:    []string{"RT:65001:201"},
  2257  	}
  2258  	ecomSet2 := config.ExtCommunitySet{
  2259  		ExtCommunitySetName: "ecomSet2",
  2260  		ExtCommunityList:    []string{"RT:[0-9]+:[0-9]+"},
  2261  	}
  2262  
  2263  	ps := createPrefixSet("ps1", "10.10.1.0/16", "21..24")
  2264  	ns := createNeighborSet("ns1", "10.2.1.1")
  2265  
  2266  	ds := config.DefinedSets{}
  2267  	ds.PrefixSets = []config.PrefixSet{ps}
  2268  	ds.NeighborSets = []config.NeighborSet{ns}
  2269  	ds.BgpDefinedSets.AsPathSets = []config.AsPathSet{asPathSet}
  2270  	ds.BgpDefinedSets.ExtCommunitySets = []config.ExtCommunitySet{ecomSet1, ecomSet2}
  2271  
  2272  	s1 := createStatement("statement1", "ps1", "ns1", false)
  2273  	s1.Conditions.BgpConditions.MatchAsPathSet.AsPathSet = "asset1"
  2274  	s1.Conditions.BgpConditions.MatchExtCommunitySet.ExtCommunitySet = "ecomSet1"
  2275  
  2276  	s2 := createStatement("statement2", "ps1", "ns1", false)
  2277  	s2.Conditions.BgpConditions.MatchAsPathSet.AsPathSet = "asset1"
  2278  	s2.Conditions.BgpConditions.MatchExtCommunitySet.ExtCommunitySet = "ecomSet2"
  2279  
  2280  	pd1 := createPolicyDefinition("pd1", s1)
  2281  	pd2 := createPolicyDefinition("pd2", s2)
  2282  	pl := createRoutingPolicy(ds, pd1, pd2)
  2283  	//test
  2284  	r := NewRoutingPolicy()
  2285  	err := r.reload(pl)
  2286  	assert.Nil(t, err)
  2287  	p := r.policyMap["pd1"]
  2288  	pType, newPath := p.Apply(path, nil)
  2289  	assert.Equal(t, ROUTE_TYPE_NONE, pType)
  2290  	assert.Equal(t, newPath, path)
  2291  
  2292  	p = r.policyMap["pd2"]
  2293  	pType, newPath = p.Apply(path, nil)
  2294  	assert.Equal(t, ROUTE_TYPE_REJECT, pType)
  2295  	assert.Equal(t, newPath, path)
  2296  
  2297  }
  2298  
  2299  func TestPolicyMatchAndReplaceMed(t *testing.T) {
  2300  
  2301  	// create path
  2302  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2303  	origin := bgp.NewPathAttributeOrigin(0)
  2304  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  2305  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2306  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2307  	med := bgp.NewPathAttributeMultiExitDisc(100)
  2308  
  2309  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  2310  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2311  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2312  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2313  	// create policy
  2314  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2315  	ns := createNeighborSet("ns1", "10.0.0.1")
  2316  
  2317  	ds := config.DefinedSets{}
  2318  	ds.PrefixSets = []config.PrefixSet{ps}
  2319  	ds.NeighborSets = []config.NeighborSet{ns}
  2320  
  2321  	m := "200"
  2322  	s := createStatement("statement1", "ps1", "ns1", true)
  2323  	s.Actions.BgpActions.SetMed = config.BgpSetMedType(m)
  2324  
  2325  	pd := createPolicyDefinition("pd1", s)
  2326  	pl := createRoutingPolicy(ds, pd)
  2327  
  2328  	//test
  2329  	r := NewRoutingPolicy()
  2330  	err := r.reload(pl)
  2331  	assert.Nil(t, err)
  2332  	p := r.policyMap["pd1"]
  2333  
  2334  	pType, newPath := p.Apply(path, nil)
  2335  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  2336  	assert.NotEqual(t, nil, newPath)
  2337  	v, err := newPath.GetMed()
  2338  	assert.Nil(t, err)
  2339  	newMed := fmt.Sprintf("%d", v)
  2340  	assert.Equal(t, m, newMed)
  2341  }
  2342  
  2343  func TestPolicyMatchAndAddingMed(t *testing.T) {
  2344  
  2345  	// create path
  2346  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2347  	origin := bgp.NewPathAttributeOrigin(0)
  2348  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  2349  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2350  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2351  	med := bgp.NewPathAttributeMultiExitDisc(100)
  2352  
  2353  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  2354  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2355  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2356  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2357  	// create policy
  2358  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2359  	ns := createNeighborSet("ns1", "10.0.0.1")
  2360  
  2361  	ds := config.DefinedSets{}
  2362  	ds.PrefixSets = []config.PrefixSet{ps}
  2363  	ds.NeighborSets = []config.NeighborSet{ns}
  2364  
  2365  	m := "+200"
  2366  	ma := "300"
  2367  	s := createStatement("statement1", "ps1", "ns1", true)
  2368  	s.Actions.BgpActions.SetMed = config.BgpSetMedType(m)
  2369  
  2370  	pd := createPolicyDefinition("pd1", s)
  2371  	pl := createRoutingPolicy(ds, pd)
  2372  	//test
  2373  	r := NewRoutingPolicy()
  2374  	err := r.reload(pl)
  2375  	assert.Nil(t, err)
  2376  	p := r.policyMap["pd1"]
  2377  	pType, newPath := p.Apply(path, nil)
  2378  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  2379  	assert.NotEqual(t, nil, newPath)
  2380  
  2381  	v, err := newPath.GetMed()
  2382  	assert.Nil(t, err)
  2383  	newMed := fmt.Sprintf("%d", v)
  2384  	assert.Equal(t, ma, newMed)
  2385  }
  2386  
  2387  func TestPolicyMatchAndAddingMedOverFlow(t *testing.T) {
  2388  
  2389  	// create path
  2390  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2391  	origin := bgp.NewPathAttributeOrigin(0)
  2392  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  2393  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2394  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2395  	med := bgp.NewPathAttributeMultiExitDisc(1)
  2396  
  2397  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  2398  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2399  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2400  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2401  	// create policy
  2402  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2403  	ns := createNeighborSet("ns1", "10.0.0.1")
  2404  
  2405  	ds := config.DefinedSets{}
  2406  	ds.PrefixSets = []config.PrefixSet{ps}
  2407  	ds.NeighborSets = []config.NeighborSet{ns}
  2408  
  2409  	m := fmt.Sprintf("+%d", uint32(math.MaxUint32))
  2410  	ma := "1"
  2411  
  2412  	s := createStatement("statement1", "ps1", "ns1", true)
  2413  	s.Actions.BgpActions.SetMed = config.BgpSetMedType(m)
  2414  
  2415  	pd := createPolicyDefinition("pd1", s)
  2416  	pl := createRoutingPolicy(ds, pd)
  2417  	//test
  2418  	r := NewRoutingPolicy()
  2419  	err := r.reload(pl)
  2420  	assert.Nil(t, err)
  2421  	p := r.policyMap["pd1"]
  2422  
  2423  	pType, newPath := p.Apply(path, nil)
  2424  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  2425  	assert.NotEqual(t, nil, newPath)
  2426  
  2427  	v, err := newPath.GetMed()
  2428  	assert.Nil(t, err)
  2429  	newMed := fmt.Sprintf("%d", v)
  2430  	assert.Equal(t, ma, newMed)
  2431  }
  2432  
  2433  func TestPolicyMatchAndSubtractMed(t *testing.T) {
  2434  
  2435  	// create path
  2436  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2437  	origin := bgp.NewPathAttributeOrigin(0)
  2438  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  2439  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2440  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2441  	med := bgp.NewPathAttributeMultiExitDisc(100)
  2442  
  2443  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  2444  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2445  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2446  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2447  	// create policy
  2448  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2449  	ns := createNeighborSet("ns1", "10.0.0.1")
  2450  
  2451  	ds := config.DefinedSets{}
  2452  	ds.PrefixSets = []config.PrefixSet{ps}
  2453  	ds.NeighborSets = []config.NeighborSet{ns}
  2454  
  2455  	m := "-50"
  2456  	ma := "50"
  2457  
  2458  	s := createStatement("statement1", "ps1", "ns1", true)
  2459  	s.Actions.BgpActions.SetMed = config.BgpSetMedType(m)
  2460  
  2461  	pd := createPolicyDefinition("pd1", s)
  2462  	pl := createRoutingPolicy(ds, pd)
  2463  	//test
  2464  	r := NewRoutingPolicy()
  2465  	err := r.reload(pl)
  2466  	assert.Nil(t, err)
  2467  	p := r.policyMap["pd1"]
  2468  
  2469  	pType, newPath := p.Apply(path, nil)
  2470  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  2471  	assert.NotEqual(t, nil, newPath)
  2472  
  2473  	v, err := newPath.GetMed()
  2474  	assert.Nil(t, err)
  2475  	newMed := fmt.Sprintf("%d", v)
  2476  	assert.Equal(t, ma, newMed)
  2477  }
  2478  
  2479  func TestPolicyMatchAndSubtractMedUnderFlow(t *testing.T) {
  2480  
  2481  	// create path
  2482  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2483  	origin := bgp.NewPathAttributeOrigin(0)
  2484  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  2485  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2486  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2487  	med := bgp.NewPathAttributeMultiExitDisc(100)
  2488  
  2489  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  2490  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2491  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2492  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2493  	// create policy
  2494  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2495  	ns := createNeighborSet("ns1", "10.0.0.1")
  2496  
  2497  	ds := config.DefinedSets{}
  2498  	ds.PrefixSets = []config.PrefixSet{ps}
  2499  	ds.NeighborSets = []config.NeighborSet{ns}
  2500  
  2501  	m := "-101"
  2502  	ma := "100"
  2503  
  2504  	s := createStatement("statement1", "ps1", "ns1", true)
  2505  	s.Actions.BgpActions.SetMed = config.BgpSetMedType(m)
  2506  
  2507  	pd := createPolicyDefinition("pd1", s)
  2508  	pl := createRoutingPolicy(ds, pd)
  2509  	//test
  2510  	r := NewRoutingPolicy()
  2511  	err := r.reload(pl)
  2512  	assert.Nil(t, err)
  2513  	p := r.policyMap["pd1"]
  2514  
  2515  	pType, newPath := p.Apply(path, nil)
  2516  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  2517  	assert.NotEqual(t, nil, newPath)
  2518  
  2519  	v, err := newPath.GetMed()
  2520  	assert.Nil(t, err)
  2521  	newMed := fmt.Sprintf("%d", v)
  2522  	assert.Equal(t, ma, newMed)
  2523  }
  2524  
  2525  func TestPolicyMatchWhenPathHaveNotMed(t *testing.T) {
  2526  
  2527  	// create path
  2528  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2529  	origin := bgp.NewPathAttributeOrigin(0)
  2530  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  2531  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2532  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2533  
  2534  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop}
  2535  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2536  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2537  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2538  	// create policy
  2539  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2540  	ns := createNeighborSet("ns1", "10.0.0.1")
  2541  
  2542  	ds := config.DefinedSets{}
  2543  	ds.PrefixSets = []config.PrefixSet{ps}
  2544  	ds.NeighborSets = []config.NeighborSet{ns}
  2545  
  2546  	m := "-50"
  2547  	s := createStatement("statement1", "ps1", "ns1", true)
  2548  	s.Actions.BgpActions.SetMed = config.BgpSetMedType(m)
  2549  
  2550  	pd := createPolicyDefinition("pd1", s)
  2551  	pl := createRoutingPolicy(ds, pd)
  2552  	//test
  2553  	r := NewRoutingPolicy()
  2554  	err := r.reload(pl)
  2555  	assert.Nil(t, err)
  2556  	p := r.policyMap["pd1"]
  2557  
  2558  	pType, newPath := p.Apply(path, nil)
  2559  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  2560  	assert.NotEqual(t, nil, newPath)
  2561  
  2562  	_, err = newPath.GetMed()
  2563  	assert.NotNil(t, err)
  2564  }
  2565  
  2566  func TestPolicyAsPathPrepend(t *testing.T) {
  2567  
  2568  	assert := assert.New(t)
  2569  
  2570  	// create path
  2571  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2572  	origin := bgp.NewPathAttributeOrigin(0)
  2573  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001, 65000})}
  2574  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2575  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2576  	med := bgp.NewPathAttributeMultiExitDisc(0)
  2577  
  2578  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  2579  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2580  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2581  
  2582  	body := updateMsg.Body.(*bgp.BGPUpdate)
  2583  	UpdatePathAttrs4ByteAs(body)
  2584  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2585  
  2586  	// create policy
  2587  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2588  	ns := createNeighborSet("ns1", "10.0.0.1")
  2589  
  2590  	ds := config.DefinedSets{}
  2591  	ds.PrefixSets = []config.PrefixSet{ps}
  2592  	ds.NeighborSets = []config.NeighborSet{ns}
  2593  
  2594  	s := createStatement("statement1", "ps1", "ns1", true)
  2595  	s.Actions.BgpActions.SetAsPathPrepend.As = "65002"
  2596  	s.Actions.BgpActions.SetAsPathPrepend.RepeatN = 10
  2597  
  2598  	pd := createPolicyDefinition("pd1", s)
  2599  	pl := createRoutingPolicy(ds, pd)
  2600  	//test
  2601  	r := NewRoutingPolicy()
  2602  	r.reload(pl)
  2603  	p := r.policyMap["pd1"]
  2604  
  2605  	pType, newPath := p.Apply(path, nil)
  2606  	assert.Equal(ROUTE_TYPE_ACCEPT, pType)
  2607  	assert.NotEqual(nil, newPath)
  2608  	assert.Equal([]uint32{65002, 65002, 65002, 65002, 65002, 65002, 65002, 65002, 65002, 65002, 65001, 65000}, newPath.GetAsSeqList())
  2609  }
  2610  
  2611  func TestPolicyAsPathPrependLastAs(t *testing.T) {
  2612  
  2613  	assert := assert.New(t)
  2614  	// create path
  2615  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2616  	origin := bgp.NewPathAttributeOrigin(0)
  2617  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65002, 65001, 65000})}
  2618  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2619  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2620  	med := bgp.NewPathAttributeMultiExitDisc(0)
  2621  
  2622  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  2623  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2624  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2625  
  2626  	body := updateMsg.Body.(*bgp.BGPUpdate)
  2627  	UpdatePathAttrs4ByteAs(body)
  2628  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2629  
  2630  	// create policy
  2631  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2632  	ns := createNeighborSet("ns1", "10.0.0.1")
  2633  
  2634  	ds := config.DefinedSets{}
  2635  	ds.PrefixSets = []config.PrefixSet{ps}
  2636  	ds.NeighborSets = []config.NeighborSet{ns}
  2637  
  2638  	s := createStatement("statement1", "ps1", "ns1", true)
  2639  	s.Actions.BgpActions.SetAsPathPrepend.As = "last-as"
  2640  	s.Actions.BgpActions.SetAsPathPrepend.RepeatN = 5
  2641  
  2642  	pd := createPolicyDefinition("pd1", s)
  2643  	pl := createRoutingPolicy(ds, pd)
  2644  	//test
  2645  	r := NewRoutingPolicy()
  2646  	r.reload(pl)
  2647  	p := r.policyMap["pd1"]
  2648  
  2649  	pType, newPath := p.Apply(path, nil)
  2650  	assert.Equal(ROUTE_TYPE_ACCEPT, pType)
  2651  	assert.NotEqual(nil, newPath)
  2652  	assert.Equal([]uint32{65002, 65002, 65002, 65002, 65002, 65002, 65001, 65000}, newPath.GetAsSeqList())
  2653  }
  2654  
  2655  func TestPolicyAs4PathPrepend(t *testing.T) {
  2656  
  2657  	assert := assert.New(t)
  2658  
  2659  	// create path
  2660  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2661  	origin := bgp.NewPathAttributeOrigin(0)
  2662  	aspathParam := []bgp.AsPathParamInterface{
  2663  		bgp.NewAs4PathParam(2, []uint32{
  2664  			createAs4Value("65001.1"),
  2665  			createAs4Value("65000.1"),
  2666  		}),
  2667  	}
  2668  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2669  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2670  	med := bgp.NewPathAttributeMultiExitDisc(0)
  2671  
  2672  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  2673  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2674  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2675  
  2676  	body := updateMsg.Body.(*bgp.BGPUpdate)
  2677  	UpdatePathAttrs4ByteAs(body)
  2678  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2679  
  2680  	// create policy
  2681  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2682  	ns := createNeighborSet("ns1", "10.0.0.1")
  2683  
  2684  	ds := config.DefinedSets{}
  2685  	ds.PrefixSets = []config.PrefixSet{ps}
  2686  	ds.NeighborSets = []config.NeighborSet{ns}
  2687  
  2688  	s := createStatement("statement1", "ps1", "ns1", true)
  2689  	s.Actions.BgpActions.SetAsPathPrepend.As = fmt.Sprintf("%d", createAs4Value("65002.1"))
  2690  	s.Actions.BgpActions.SetAsPathPrepend.RepeatN = 10
  2691  
  2692  	pd := createPolicyDefinition("pd1", s)
  2693  	pl := createRoutingPolicy(ds, pd)
  2694  	//test
  2695  	r := NewRoutingPolicy()
  2696  	r.reload(pl)
  2697  	p, err := NewPolicy(pl.PolicyDefinitions[0])
  2698  	assert.Nil(err)
  2699  	addPolicy(r, p)
  2700  
  2701  	pType, newPath := p.Apply(path, nil)
  2702  	assert.Equal(ROUTE_TYPE_ACCEPT, pType)
  2703  	assert.NotEqual(nil, newPath)
  2704  	asn := createAs4Value("65002.1")
  2705  	assert.Equal([]uint32{
  2706  		asn, asn, asn, asn, asn, asn, asn, asn, asn, asn,
  2707  		createAs4Value("65001.1"),
  2708  		createAs4Value("65000.1"),
  2709  	}, newPath.GetAsSeqList())
  2710  }
  2711  
  2712  func TestPolicyAs4PathPrependLastAs(t *testing.T) {
  2713  
  2714  	assert := assert.New(t)
  2715  	// create path
  2716  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2717  	origin := bgp.NewPathAttributeOrigin(0)
  2718  	aspathParam := []bgp.AsPathParamInterface{
  2719  		bgp.NewAs4PathParam(2, []uint32{
  2720  			createAs4Value("65002.1"),
  2721  			createAs4Value("65001.1"),
  2722  			createAs4Value("65000.1"),
  2723  		}),
  2724  	}
  2725  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2726  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2727  	med := bgp.NewPathAttributeMultiExitDisc(0)
  2728  
  2729  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  2730  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2731  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2732  
  2733  	body := updateMsg.Body.(*bgp.BGPUpdate)
  2734  	UpdatePathAttrs4ByteAs(body)
  2735  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2736  
  2737  	// create policy
  2738  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2739  	ns := createNeighborSet("ns1", "10.0.0.1")
  2740  
  2741  	ds := config.DefinedSets{}
  2742  	ds.PrefixSets = []config.PrefixSet{ps}
  2743  	ds.NeighborSets = []config.NeighborSet{ns}
  2744  
  2745  	s := createStatement("statement1", "ps1", "ns1", true)
  2746  	s.Actions.BgpActions.SetAsPathPrepend.As = "last-as"
  2747  	s.Actions.BgpActions.SetAsPathPrepend.RepeatN = 5
  2748  
  2749  	pd := createPolicyDefinition("pd1", s)
  2750  	pl := createRoutingPolicy(ds, pd)
  2751  	//test
  2752  	r := NewRoutingPolicy()
  2753  	r.reload(pl)
  2754  	p, _ := NewPolicy(pl.PolicyDefinitions[0])
  2755  	addPolicy(r, p)
  2756  
  2757  	pType, newPath := p.Apply(path, nil)
  2758  	assert.Equal(ROUTE_TYPE_ACCEPT, pType)
  2759  	assert.NotEqual(nil, newPath)
  2760  	asn := createAs4Value("65002.1")
  2761  	assert.Equal([]uint32{
  2762  		asn, asn, asn, asn, asn,
  2763  		createAs4Value("65002.1"),
  2764  		createAs4Value("65001.1"),
  2765  		createAs4Value("65000.1"),
  2766  	}, newPath.GetAsSeqList())
  2767  }
  2768  
  2769  func TestParseCommunityRegexp(t *testing.T) {
  2770  	exp, err := ParseCommunityRegexp("65000:1")
  2771  	assert.Equal(t, nil, err)
  2772  	assert.Equal(t, true, exp.MatchString("65000:1"))
  2773  	assert.Equal(t, false, exp.MatchString("65000:100"))
  2774  }
  2775  
  2776  func TestLocalPrefAction(t *testing.T) {
  2777  	action, err := NewLocalPrefAction(10)
  2778  	assert.Nil(t, err)
  2779  
  2780  	nlri := bgp.NewIPAddrPrefix(24, "10.0.0.0")
  2781  
  2782  	origin := bgp.NewPathAttributeOrigin(0)
  2783  	aspathParam := []bgp.AsPathParamInterface{
  2784  		bgp.NewAs4PathParam(2, []uint32{
  2785  			createAs4Value("65002.1"),
  2786  			createAs4Value("65001.1"),
  2787  			createAs4Value("65000.1"),
  2788  		}),
  2789  	}
  2790  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2791  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2792  	med := bgp.NewPathAttributeMultiExitDisc(0)
  2793  
  2794  	attrs := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  2795  
  2796  	path := NewPath(nil, nlri, false, attrs, time.Now(), false)
  2797  	p := action.Apply(path, nil)
  2798  	assert.NotNil(t, p)
  2799  
  2800  	attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_LOCAL_PREF)
  2801  	assert.NotNil(t, attr)
  2802  	lp := attr.(*bgp.PathAttributeLocalPref)
  2803  	assert.Equal(t, int(lp.Value), int(10))
  2804  }
  2805  
  2806  func createStatement(name, psname, nsname string, accept bool) config.Statement {
  2807  	c := config.Conditions{
  2808  		MatchPrefixSet: config.MatchPrefixSet{
  2809  			PrefixSet: psname,
  2810  		},
  2811  		MatchNeighborSet: config.MatchNeighborSet{
  2812  			NeighborSet: nsname,
  2813  		},
  2814  	}
  2815  	rd := config.ROUTE_DISPOSITION_REJECT_ROUTE
  2816  	if accept {
  2817  		rd = config.ROUTE_DISPOSITION_ACCEPT_ROUTE
  2818  	}
  2819  	a := config.Actions{
  2820  		RouteDisposition: rd,
  2821  	}
  2822  	s := config.Statement{
  2823  		Name:       name,
  2824  		Conditions: c,
  2825  		Actions:    a,
  2826  	}
  2827  	return s
  2828  }
  2829  
  2830  func createSetCommunity(operation string, community ...string) config.SetCommunity {
  2831  
  2832  	s := config.SetCommunity{
  2833  		SetCommunityMethod: config.SetCommunityMethod{
  2834  			CommunitiesList: community,
  2835  		},
  2836  		Options: operation,
  2837  	}
  2838  	return s
  2839  }
  2840  
  2841  func stringToCommunityValue(comStr string) uint32 {
  2842  	elem := strings.Split(comStr, ":")
  2843  	asn, _ := strconv.ParseUint(elem[0], 10, 16)
  2844  	val, _ := strconv.ParseUint(elem[1], 10, 16)
  2845  	return uint32(asn<<16 | val)
  2846  }
  2847  
  2848  func createPolicyDefinition(defName string, stmt ...config.Statement) config.PolicyDefinition {
  2849  	pd := config.PolicyDefinition{
  2850  		Name:       defName,
  2851  		Statements: []config.Statement(stmt),
  2852  	}
  2853  	return pd
  2854  }
  2855  
  2856  func createRoutingPolicy(ds config.DefinedSets, pd ...config.PolicyDefinition) config.RoutingPolicy {
  2857  	pl := config.RoutingPolicy{
  2858  		DefinedSets:       ds,
  2859  		PolicyDefinitions: []config.PolicyDefinition(pd),
  2860  	}
  2861  	return pl
  2862  }
  2863  
  2864  func createPrefixSet(name string, prefix string, maskLength string) config.PrefixSet {
  2865  	ps := config.PrefixSet{
  2866  		PrefixSetName: name,
  2867  		PrefixList: []config.Prefix{
  2868  			config.Prefix{
  2869  				IpPrefix:        prefix,
  2870  				MasklengthRange: maskLength,
  2871  			}},
  2872  	}
  2873  	return ps
  2874  }
  2875  
  2876  func createNeighborSet(name string, addr string) config.NeighborSet {
  2877  	ns := config.NeighborSet{
  2878  		NeighborSetName:  name,
  2879  		NeighborInfoList: []string{addr},
  2880  	}
  2881  	return ns
  2882  }
  2883  
  2884  func createAs4Value(s string) uint32 {
  2885  	v := strings.Split(s, ".")
  2886  	upper, _ := strconv.ParseUint(v[0], 10, 16)
  2887  	lower, _ := strconv.ParseUint(v[1], 10, 16)
  2888  	return uint32(upper<<16 | lower)
  2889  }
  2890  
  2891  func TestPrefixSetOperation(t *testing.T) {
  2892  	// tryp to create prefixset with multiple families
  2893  	p1 := config.Prefix{
  2894  		IpPrefix:        "0.0.0.0/0",
  2895  		MasklengthRange: "0..7",
  2896  	}
  2897  	p2 := config.Prefix{
  2898  		IpPrefix:        "0::/25",
  2899  		MasklengthRange: "25..128",
  2900  	}
  2901  	_, err := NewPrefixSet(config.PrefixSet{
  2902  		PrefixSetName: "ps1",
  2903  		PrefixList:    []config.Prefix{p1, p2},
  2904  	})
  2905  	assert.NotNil(t, err)
  2906  	m1, _ := NewPrefixSet(config.PrefixSet{
  2907  		PrefixSetName: "ps1",
  2908  		PrefixList:    []config.Prefix{p1},
  2909  	})
  2910  	m2, err := NewPrefixSet(config.PrefixSet{PrefixSetName: "ps2"})
  2911  	assert.Nil(t, err)
  2912  	err = m1.Append(m2)
  2913  	assert.Nil(t, err)
  2914  	err = m2.Append(m1)
  2915  	assert.Nil(t, err)
  2916  	assert.Equal(t, bgp.RF_IPv4_UC, m2.family)
  2917  	p3, _ := NewPrefix(config.Prefix{IpPrefix: "10.10.0.0/24", MasklengthRange: ""})
  2918  	p4, _ := NewPrefix(config.Prefix{IpPrefix: "0::/25", MasklengthRange: ""})
  2919  	_, err = NewPrefixSetFromApiStruct("ps3", []*Prefix{p3, p4})
  2920  	assert.NotNil(t, err)
  2921  }
  2922  
  2923  func TestPrefixSetMatch(t *testing.T) {
  2924  	p1 := config.Prefix{
  2925  		IpPrefix:        "0.0.0.0/0",
  2926  		MasklengthRange: "0..7",
  2927  	}
  2928  	p2 := config.Prefix{
  2929  		IpPrefix:        "0.0.0.0/0",
  2930  		MasklengthRange: "25..32",
  2931  	}
  2932  	ps, err := NewPrefixSet(config.PrefixSet{
  2933  		PrefixSetName: "ps1",
  2934  		PrefixList:    []config.Prefix{p1, p2},
  2935  	})
  2936  	assert.Nil(t, err)
  2937  	m := &PrefixCondition{
  2938  		set: ps,
  2939  	}
  2940  
  2941  	path := NewPath(nil, bgp.NewIPAddrPrefix(6, "0.0.0.0"), false, []bgp.PathAttributeInterface{}, time.Now(), false)
  2942  	assert.True(t, m.Evaluate(path, nil))
  2943  
  2944  	path = NewPath(nil, bgp.NewIPAddrPrefix(10, "0.0.0.0"), false, []bgp.PathAttributeInterface{}, time.Now(), false)
  2945  	assert.False(t, m.Evaluate(path, nil))
  2946  
  2947  	path = NewPath(nil, bgp.NewIPAddrPrefix(25, "0.0.0.0"), false, []bgp.PathAttributeInterface{}, time.Now(), false)
  2948  	assert.True(t, m.Evaluate(path, nil))
  2949  
  2950  	path = NewPath(nil, bgp.NewIPAddrPrefix(30, "0.0.0.0"), false, []bgp.PathAttributeInterface{}, time.Now(), false)
  2951  	assert.True(t, m.Evaluate(path, nil))
  2952  
  2953  	p3 := config.Prefix{
  2954  		IpPrefix:        "0.0.0.0/0",
  2955  		MasklengthRange: "9..10",
  2956  	}
  2957  	ps2, err := NewPrefixSet(config.PrefixSet{
  2958  		PrefixSetName: "ps2",
  2959  		PrefixList:    []config.Prefix{p3},
  2960  	})
  2961  	assert.Nil(t, err)
  2962  	err = ps.Append(ps2)
  2963  	assert.Nil(t, err)
  2964  
  2965  	path = NewPath(nil, bgp.NewIPAddrPrefix(10, "0.0.0.0"), false, []bgp.PathAttributeInterface{}, time.Now(), false)
  2966  	assert.True(t, m.Evaluate(path, nil))
  2967  
  2968  	ps3, err := NewPrefixSet(config.PrefixSet{
  2969  		PrefixSetName: "ps3",
  2970  		PrefixList:    []config.Prefix{p1},
  2971  	})
  2972  	assert.Nil(t, err)
  2973  	err = ps.Remove(ps3)
  2974  	assert.Nil(t, err)
  2975  
  2976  	path = NewPath(nil, bgp.NewIPAddrPrefix(6, "0.0.0.0"), false, []bgp.PathAttributeInterface{}, time.Now(), false)
  2977  	assert.False(t, m.Evaluate(path, nil))
  2978  }
  2979  
  2980  func TestPrefixSetMatchV4withV6Prefix(t *testing.T) {
  2981  	p1 := config.Prefix{
  2982  		IpPrefix:        "c000::/3",
  2983  		MasklengthRange: "3..128",
  2984  	}
  2985  	ps, err := NewPrefixSet(config.PrefixSet{
  2986  		PrefixSetName: "ps1",
  2987  		PrefixList:    []config.Prefix{p1},
  2988  	})
  2989  	assert.Nil(t, err)
  2990  	m := &PrefixCondition{
  2991  		set: ps,
  2992  	}
  2993  
  2994  	path := NewPath(nil, bgp.NewIPAddrPrefix(6, "192.0.0.0"), false, []bgp.PathAttributeInterface{}, time.Now(), false)
  2995  	assert.False(t, m.Evaluate(path, nil))
  2996  }
  2997  
  2998  func TestLargeCommunityMatchAction(t *testing.T) {
  2999  	coms := []*bgp.LargeCommunity{
  3000  		&bgp.LargeCommunity{ASN: 100, LocalData1: 100, LocalData2: 100},
  3001  		&bgp.LargeCommunity{ASN: 100, LocalData1: 200, LocalData2: 200},
  3002  	}
  3003  	p := NewPath(nil, nil, false, []bgp.PathAttributeInterface{bgp.NewPathAttributeLargeCommunities(coms)}, time.Time{}, false)
  3004  
  3005  	c := config.LargeCommunitySet{
  3006  		LargeCommunitySetName: "l0",
  3007  		LargeCommunityList: []string{
  3008  			"100:100:100",
  3009  			"100:300:100",
  3010  		},
  3011  	}
  3012  
  3013  	set, err := NewLargeCommunitySet(c)
  3014  	assert.Equal(t, err, nil)
  3015  
  3016  	m, err := NewLargeCommunityCondition(config.MatchLargeCommunitySet{
  3017  		LargeCommunitySet: "l0",
  3018  	})
  3019  	assert.Equal(t, err, nil)
  3020  	m.set = set
  3021  
  3022  	assert.Equal(t, m.Evaluate(p, nil), true)
  3023  
  3024  	a, err := NewLargeCommunityAction(config.SetLargeCommunity{
  3025  		SetLargeCommunityMethod: config.SetLargeCommunityMethod{
  3026  			CommunitiesList: []string{"100:100:100"},
  3027  		},
  3028  		Options: config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE,
  3029  	})
  3030  	assert.Equal(t, err, nil)
  3031  	p = a.Apply(p, nil)
  3032  
  3033  	assert.Equal(t, m.Evaluate(p, nil), false)
  3034  
  3035  	a, err = NewLargeCommunityAction(config.SetLargeCommunity{
  3036  		SetLargeCommunityMethod: config.SetLargeCommunityMethod{
  3037  			CommunitiesList: []string{
  3038  				"100:300:100",
  3039  				"200:100:100",
  3040  			},
  3041  		},
  3042  		Options: config.BGP_SET_COMMUNITY_OPTION_TYPE_ADD,
  3043  	})
  3044  	assert.Equal(t, err, nil)
  3045  	p = a.Apply(p, nil)
  3046  
  3047  	assert.Equal(t, m.Evaluate(p, nil), true)
  3048  
  3049  	a, err = NewLargeCommunityAction(config.SetLargeCommunity{
  3050  		SetLargeCommunityMethod: config.SetLargeCommunityMethod{
  3051  			CommunitiesList: []string{"^100:"},
  3052  		},
  3053  		Options: config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE,
  3054  	})
  3055  	assert.Equal(t, err, nil)
  3056  	p = a.Apply(p, nil)
  3057  
  3058  	assert.Equal(t, m.Evaluate(p, nil), false)
  3059  
  3060  	c = config.LargeCommunitySet{
  3061  		LargeCommunitySetName: "l1",
  3062  		LargeCommunityList: []string{
  3063  			"200:",
  3064  		},
  3065  	}
  3066  
  3067  	set, err = NewLargeCommunitySet(c)
  3068  	assert.Equal(t, err, nil)
  3069  
  3070  	m, err = NewLargeCommunityCondition(config.MatchLargeCommunitySet{
  3071  		LargeCommunitySet: "l1",
  3072  	})
  3073  	assert.Equal(t, err, nil)
  3074  	m.set = set
  3075  
  3076  	assert.Equal(t, m.Evaluate(p, nil), true)
  3077  }
  3078  
  3079  func TestAfiSafiInMatchPath(t *testing.T) {
  3080  	condition, err := NewAfiSafiInCondition([]config.AfiSafiType{config.AFI_SAFI_TYPE_L3VPN_IPV4_UNICAST, config.AFI_SAFI_TYPE_L3VPN_IPV6_UNICAST})
  3081  	require.NoError(t, err)
  3082  
  3083  	rtExtCom, err := bgp.ParseExtendedCommunity(bgp.EC_SUBTYPE_ROUTE_TARGET, "100:100")
  3084  	assert.NoError(t, err)
  3085  
  3086  	prefixVPNv4 := bgp.NewLabeledVPNIPAddrPrefix(0, "1.1.1.0/24", *bgp.NewMPLSLabelStack(), bgp.NewRouteDistinguisherTwoOctetAS(100, 100))
  3087  	prefixVPNv6 := bgp.NewLabeledVPNIPv6AddrPrefix(0, "2001:0db8:85a3:0000:0000:8a2e:0370:7334", *bgp.NewMPLSLabelStack(), bgp.NewRouteDistinguisherTwoOctetAS(200, 200))
  3088  	prefixRTC := bgp.NewRouteTargetMembershipNLRI(100, nil)
  3089  	prefixv4 := bgp.NewIPAddrPrefix(0, "1.1.1.0/24")
  3090  	prefixv6 := bgp.NewIPv6AddrPrefix(0, "2001:0db8:85a3:0000:0000:8a2e:0370:7334")
  3091  
  3092  	pathVPNv4 := NewPath(nil, prefixVPNv4, false, []bgp.PathAttributeInterface{bgp.NewPathAttributeExtendedCommunities([]bgp.ExtendedCommunityInterface{rtExtCom})}, time.Time{}, false)
  3093  	pathVPNv6 := NewPath(nil, prefixVPNv6, false, []bgp.PathAttributeInterface{bgp.NewPathAttributeExtendedCommunities([]bgp.ExtendedCommunityInterface{rtExtCom})}, time.Time{}, false)
  3094  	pathv4 := NewPath(nil, prefixv4, false, []bgp.PathAttributeInterface{}, time.Time{}, false)
  3095  	pathv6 := NewPath(nil, prefixv6, false, []bgp.PathAttributeInterface{}, time.Time{}, false)
  3096  	pathRTC := NewPath(nil, prefixRTC, false, []bgp.PathAttributeInterface{}, time.Time{}, false)
  3097  
  3098  	type Entry struct {
  3099  		path        *Path
  3100  		shouldMatch bool
  3101  	}
  3102  
  3103  	for _, entry := range []Entry{
  3104  		{pathVPNv4, true},
  3105  		{pathVPNv6, true},
  3106  		{pathv4, false},
  3107  		{pathv6, false},
  3108  		{pathRTC, false},
  3109  	} {
  3110  		assert.Equal(t, condition.Evaluate(entry.path, nil), entry.shouldMatch)
  3111  	}
  3112  }
  3113  
  3114  func TestMultipleStatementPolicy(t *testing.T) {
  3115  	r := NewRoutingPolicy()
  3116  	rp := config.RoutingPolicy{
  3117  		PolicyDefinitions: []config.PolicyDefinition{config.PolicyDefinition{
  3118  			Name: "p1",
  3119  			Statements: []config.Statement{
  3120  				config.Statement{
  3121  					Actions: config.Actions{
  3122  						BgpActions: config.BgpActions{
  3123  							SetMed: "+100",
  3124  						},
  3125  					},
  3126  				},
  3127  				config.Statement{
  3128  					Actions: config.Actions{
  3129  						BgpActions: config.BgpActions{
  3130  							SetLocalPref: 100,
  3131  						},
  3132  					},
  3133  				},
  3134  			},
  3135  		},
  3136  		},
  3137  	}
  3138  	err := r.reload(rp)
  3139  	assert.Nil(t, err)
  3140  
  3141  	nlri := bgp.NewIPAddrPrefix(24, "10.10.0.0")
  3142  
  3143  	origin := bgp.NewPathAttributeOrigin(0)
  3144  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  3145  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  3146  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  3147  	pattrs := []bgp.PathAttributeInterface{origin, aspath, nexthop}
  3148  
  3149  	path := NewPath(nil, nlri, false, pattrs, time.Now(), false)
  3150  
  3151  	pType, newPath := r.policyMap["p1"].Apply(path, nil)
  3152  	assert.Equal(t, ROUTE_TYPE_NONE, pType)
  3153  	med, _ := newPath.GetMed()
  3154  	assert.Equal(t, med, uint32(100))
  3155  	localPref, _ := newPath.GetLocalPref()
  3156  	assert.Equal(t, localPref, uint32(100))
  3157  }