github.com/osrg/gobgp/v3@v3.30.0/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/google/go-cmp/cmp"
    28  	"github.com/osrg/gobgp/v3/pkg/config/oc"
    29  	"github.com/osrg/gobgp/v3/pkg/packet/bgp"
    30  
    31  	"github.com/stretchr/testify/assert"
    32  	"github.com/stretchr/testify/require"
    33  )
    34  
    35  func TestGetStatement(t *testing.T) {
    36  	r := NewRoutingPolicy(logger)
    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(logger)
    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(oc.Prefix{IpPrefix: "10.10.0.0/24", MasklengthRange: ""})
    66  	match1 := pl1.Match(path)
    67  	assert.Equal(t, true, match1)
    68  	pl2, _ := NewPrefix(oc.Prefix{IpPrefix: "10.10.0.0/23", MasklengthRange: ""})
    69  	match2 := pl2.Match(path)
    70  	assert.Equal(t, false, match2)
    71  	pl3, _ := NewPrefix(oc.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(oc.Prefix{IpPrefix: "10.11.0.0/16", MasklengthRange: "21..24"})
    90  	match1 := pl1.Match(path)
    91  	assert.Equal(t, false, match1)
    92  	pl2, _ := NewPrefix(oc.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(oc.Prefix{IpPrefix: "10.10.64.0/24", MasklengthRange: "21..24"})
   111  	match1 := pl1.Match(path)
   112  	assert.Equal(t, false, match1)
   113  	pl2, _ := NewPrefix(oc.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(oc.Prefix{IpPrefix: "10.10.0.0/16", MasklengthRange: "21..23"})
   132  	match1 := pl1.Match(path)
   133  	assert.Equal(t, false, match1)
   134  	pl2, _ := NewPrefix(oc.Prefix{IpPrefix: "10.10.0.0/16", MasklengthRange: "25..26"})
   135  	match2 := pl2.Match(path)
   136  	assert.Equal(t, false, match2)
   137  	pl3, _ := NewPrefix(oc.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(oc.Prefix{IpPrefix: "2001:123:123::/48", MasklengthRange: ""})
   156  	match1 := pl1.Match(path)
   157  	assert.Equal(t, false, match1)
   158  	pl2, _ := NewPrefix(oc.Prefix{IpPrefix: "2001:123:123:1::/64", MasklengthRange: ""})
   159  	match2 := pl2.Match(path)
   160  	assert.Equal(t, true, match2)
   161  	pl3, _ := NewPrefix(oc.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(oc.Prefix{IpPrefix: "2001:123:128::/48", MasklengthRange: "64..80"})
   180  	match1 := pl1.Match(path)
   181  	assert.Equal(t, false, match1)
   182  	pl2, _ := NewPrefix(oc.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(oc.Prefix{IpPrefix: "2001:123:123:64::/64", MasklengthRange: "64..80"})
   201  	match1 := pl1.Match(path)
   202  	assert.Equal(t, false, match1)
   203  	pl2, _ := NewPrefix(oc.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(oc.Prefix{IpPrefix: "2001:123:123::/48", MasklengthRange: "62..63"})
   222  	match1 := pl1.Match(path)
   223  	assert.Equal(t, false, match1)
   224  	pl2, _ := NewPrefix(oc.Prefix{IpPrefix: "2001:123:123::/48", MasklengthRange: "65..66"})
   225  	match2 := pl2.Match(path)
   226  	assert.Equal(t, false, match2)
   227  	pl3, _ := NewPrefix(oc.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 := oc.DefinedSets{}
   249  	ds.PrefixSets = []oc.PrefixSet{ps}
   250  	ds.NeighborSets = []oc.NeighborSet{ns}
   251  	s := createStatement("statement1", "ps1", "ns1", false)
   252  	pd := createPolicyDefinition("pd1", s)
   253  	pl := createRoutingPolicy(ds, pd)
   254  
   255  	r := NewRoutingPolicy(logger)
   256  	err := r.reload(pl)
   257  	assert.Nil(t, err)
   258  	pType, newPath := r.policyMap["pd1"].Apply(logger, 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 := oc.DefinedSets{}
   279  	ds.PrefixSets = []oc.PrefixSet{ps}
   280  	ds.NeighborSets = []oc.NeighborSet{ns}
   281  
   282  	s := createStatement("statement1", "ps1", "ns1", false)
   283  	pd := createPolicyDefinition("pd1", s)
   284  	pl := createRoutingPolicy(ds, pd)
   285  
   286  	r := NewRoutingPolicy(logger)
   287  	err := r.reload(pl)
   288  	assert.Nil(t, err)
   289  	pType, newPath := r.policyMap["pd1"].Apply(logger, 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 := oc.DefinedSets{}
   310  	ds.PrefixSets = []oc.PrefixSet{ps}
   311  	ds.NeighborSets = []oc.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(logger)
   319  	err := r.reload(pl)
   320  	assert.Nil(t, err)
   321  	pType, newPath := r.policyMap["pd1"].Apply(logger, 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 := oc.DefinedSets{}
   353  	ds.PrefixSets = []oc.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(logger)
   361  	err := r.reload(pl)
   362  	assert.Nil(t, err)
   363  	p := r.policyMap["pd1"]
   364  	pType, newPath := p.Apply(logger, path1, nil)
   365  	assert.Equal(t, ROUTE_TYPE_REJECT, pType)
   366  	assert.Equal(t, newPath, path1)
   367  
   368  	pType2, newPath2 := p.Apply(logger, 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 := oc.DefinedSets{}
   400  	ds.NeighborSets = []oc.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(logger)
   408  	err := r.reload(pl)
   409  	assert.Nil(t, err)
   410  	pType, newPath := r.policyMap["pd1"].Apply(logger, path1, nil)
   411  	assert.Equal(t, ROUTE_TYPE_REJECT, pType)
   412  	assert.Equal(t, newPath, path1)
   413  
   414  	pType2, newPath2 := r.policyMap["pd1"].Apply(logger, 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 := oc.DefinedSets{}
   450  	ds.PrefixSets = []oc.PrefixSet{psIPv4, psIPv6}
   451  	ds.NeighborSets = []oc.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(logger)
   461  	err := r.reload(pl)
   462  	assert.Nil(t, err)
   463  	p := r.policyMap["pd1"]
   464  	pType1, newPath1 := p.Apply(logger, pathIPv4, nil)
   465  	assert.Equal(t, ROUTE_TYPE_REJECT, pType1)
   466  	assert.Equal(t, newPath1, pathIPv4)
   467  
   468  	pType2, newPath2 := p.Apply(logger, 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(logger, updateMsg.Body.(*bgp.BGPUpdate))
   489  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   490  
   491  	// create match condition
   492  	asPathLength := oc.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 = oc.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 = oc.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 TestOriginConditionEvaluate(t *testing.T) {
   523  	// setup
   524  	// create path
   525  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
   526  	origin := bgp.NewPathAttributeOrigin(uint8(oc.BGP_ORIGIN_ATTR_TYPE_IGP.ToInt()))
   527  	aspathParam := []bgp.AsPathParamInterface{
   528  		bgp.NewAsPathParam(2, []uint16{65001, 65000, 65004, 65005}),
   529  		bgp.NewAsPathParam(1, []uint16{65001, 65000, 65004, 65005}),
   530  	}
   531  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   532  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
   533  	med := bgp.NewPathAttributeMultiExitDisc(0)
   534  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   535  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   536  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   537  	UpdatePathAttrs4ByteAs(logger, updateMsg.Body.(*bgp.BGPUpdate))
   538  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   539  
   540  	// create match condition
   541  	c, err := NewOriginCondition(oc.BGP_ORIGIN_ATTR_TYPE_IGP)
   542  	if err != nil {
   543  		t.Fatal(err)
   544  	}
   545  
   546  	// test
   547  	assert.Equal(t, true, c.Evaluate(path, nil))
   548  
   549  	// create match condition
   550  	c, err = NewOriginCondition(oc.BGP_ORIGIN_ATTR_TYPE_EGP)
   551  	if err != nil {
   552  		t.Fatal(err)
   553  	}
   554  
   555  	// test
   556  	assert.Equal(t, false, c.Evaluate(path, nil))
   557  
   558  	// Change the route origin.
   559  	action, err := NewOriginAction(oc.BGP_ORIGIN_ATTR_TYPE_INCOMPLETE)
   560  	assert.Nil(t, err)
   561  
   562  	path, _ = action.Apply(path, nil)
   563  	assert.NotNil(t, path)
   564  
   565  	// create match condition
   566  	c, err = NewOriginCondition(oc.BGP_ORIGIN_ATTR_TYPE_IGP)
   567  	if err != nil {
   568  		t.Fatal(err)
   569  	}
   570  
   571  	// test
   572  	assert.Equal(t, false, c.Evaluate(path, nil))
   573  
   574  	// create match condition
   575  	c, err = NewOriginCondition(oc.BGP_ORIGIN_ATTR_TYPE_EGP)
   576  	if err != nil {
   577  		t.Fatal(err)
   578  	}
   579  
   580  	// test
   581  	assert.Equal(t, false, c.Evaluate(path, nil))
   582  
   583  	// create match condition
   584  	c, err = NewOriginCondition(oc.BGP_ORIGIN_ATTR_TYPE_INCOMPLETE)
   585  	if err != nil {
   586  		t.Fatal(err)
   587  	}
   588  
   589  	// test
   590  	assert.Equal(t, true, c.Evaluate(path, nil))
   591  
   592  }
   593  
   594  func TestPolicyMatchAndAcceptNextHop(t *testing.T) {
   595  	// create path
   596  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
   597  	origin := bgp.NewPathAttributeOrigin(0)
   598  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
   599  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   600  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
   601  	med := bgp.NewPathAttributeMultiExitDisc(0)
   602  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   603  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   604  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   605  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   606  
   607  	// create policy
   608  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
   609  	ns := createNeighborSet("ns1", "10.0.0.1")
   610  	ds := oc.DefinedSets{}
   611  	ds.PrefixSets = []oc.PrefixSet{ps}
   612  	ds.NeighborSets = []oc.NeighborSet{ns}
   613  	s := createStatement("statement1", "ps1", "ns1", true)
   614  	s.Conditions.BgpConditions.NextHopInList = []string{"10.0.0.1/32"}
   615  	pd := createPolicyDefinition("pd1", s)
   616  	pl := createRoutingPolicy(ds, pd)
   617  
   618  	r := NewRoutingPolicy(logger)
   619  	err := r.reload(pl)
   620  	assert.Nil(t, err)
   621  	pType, newPath := r.policyMap["pd1"].Apply(logger, path, nil)
   622  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
   623  	assert.Equal(t, newPath, path)
   624  }
   625  
   626  func TestPolicyMatchAndRejectNextHop(t *testing.T) {
   627  	// create path
   628  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
   629  	origin := bgp.NewPathAttributeOrigin(0)
   630  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
   631  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   632  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
   633  	med := bgp.NewPathAttributeMultiExitDisc(0)
   634  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   635  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   636  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   637  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   638  
   639  	// create policy
   640  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
   641  	ns := createNeighborSet("ns1", "10.0.0.1")
   642  	ds := oc.DefinedSets{}
   643  	ds.PrefixSets = []oc.PrefixSet{ps}
   644  	ds.NeighborSets = []oc.NeighborSet{ns}
   645  	s := createStatement("statement1", "ps1", "ns1", true)
   646  	s.Conditions.BgpConditions.NextHopInList = []string{"10.0.0.12"}
   647  	pd := createPolicyDefinition("pd1", s)
   648  	pl := createRoutingPolicy(ds, pd)
   649  
   650  	r := NewRoutingPolicy(logger)
   651  	err := r.reload(pl)
   652  	assert.Nil(t, err)
   653  	pType, newPath := r.policyMap["pd1"].Apply(logger, path, nil)
   654  	assert.Equal(t, ROUTE_TYPE_NONE, pType)
   655  	assert.Equal(t, newPath, path)
   656  }
   657  
   658  func TestSetNextHop(t *testing.T) {
   659  	// create path
   660  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.2"), LocalAddress: net.ParseIP("20.0.0.1")}
   661  	origin := bgp.NewPathAttributeOrigin(0)
   662  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
   663  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   664  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.5")
   665  	med := bgp.NewPathAttributeMultiExitDisc(0)
   666  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   667  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   668  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   669  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   670  
   671  	// create policy
   672  	ps := createPrefixSet("ps", "10.10.0.0/16", "21..24")
   673  	ns := createNeighborSet("ns", "10.0.0.2")
   674  	ds := oc.DefinedSets{}
   675  	ds.PrefixSets = []oc.PrefixSet{ps}
   676  	ds.NeighborSets = []oc.NeighborSet{ns}
   677  
   678  	t.Run("custom", func(t *testing.T) {
   679  		s1 := createStatement("statement1", "ps", "ns", true)
   680  		s1.Actions.BgpActions.SetNextHop = oc.BgpNextHopType("10.2.2.2")
   681  		s1.Actions.RouteDisposition = oc.ROUTE_DISPOSITION_NONE
   682  		s2 := createStatement("statement2", "ps", "ns", true)
   683  		s2.Conditions.BgpConditions.NextHopInList = []string{"10.2.2.2"}
   684  		pd := createPolicyDefinition("pd1", s1, s2)
   685  		pl := createRoutingPolicy(ds, pd)
   686  
   687  		r := NewRoutingPolicy(logger)
   688  		err := r.reload(pl)
   689  		assert.Nil(t, err)
   690  		pType, newPath := r.policyMap["pd1"].Apply(logger, path, &PolicyOptions{Info: peer})
   691  		assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
   692  		path.SetNexthop(net.ParseIP("10.2.2.2"))
   693  		if diff := cmp.Diff(newPath, path); diff != "" {
   694  			t.Errorf("(-want, +got):\n%s", diff)
   695  		}
   696  	})
   697  
   698  	t.Run("self", func(t *testing.T) {
   699  		s1 := createStatement("statement1", "ps", "ns", true)
   700  		s1.Actions.BgpActions.SetNextHop = oc.BgpNextHopType("self")
   701  		s1.Actions.RouteDisposition = oc.ROUTE_DISPOSITION_NONE
   702  		s2 := createStatement("statement2", "ps", "ns", true)
   703  		s2.Conditions.BgpConditions.NextHopInList = []string{"20.0.0.1"}
   704  		pd := createPolicyDefinition("pd1", s1, s2)
   705  		pl := createRoutingPolicy(ds, pd)
   706  
   707  		r := NewRoutingPolicy(logger)
   708  		err := r.reload(pl)
   709  		assert.Nil(t, err)
   710  		pType, newPath := r.policyMap["pd1"].Apply(logger, path, &PolicyOptions{Info: peer})
   711  		assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
   712  		path.SetNexthop(net.ParseIP("20.0.0.1"))
   713  		if diff := cmp.Diff(newPath, path); diff != "" {
   714  			t.Errorf("(-want, +got):\n%s", diff)
   715  		}
   716  	})
   717  
   718  	t.Run("peer-address", func(t *testing.T) {
   719  		s1 := createStatement("statement1", "ps", "ns", true)
   720  		s1.Actions.BgpActions.SetNextHop = oc.BgpNextHopType("peer-address")
   721  		s1.Actions.RouteDisposition = oc.ROUTE_DISPOSITION_NONE
   722  		s2 := createStatement("statement2", "ps", "ns", true)
   723  		s2.Conditions.BgpConditions.NextHopInList = []string{"10.0.0.2"}
   724  		pd := createPolicyDefinition("pd1", s1, s2)
   725  		pl := createRoutingPolicy(ds, pd)
   726  
   727  		r := NewRoutingPolicy(logger)
   728  		err := r.reload(pl)
   729  		assert.Nil(t, err)
   730  		pType, newPath := r.policyMap["pd1"].Apply(logger, path, &PolicyOptions{Info: peer})
   731  		assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
   732  		path.SetNexthop(net.ParseIP("10.0.0.2"))
   733  		if diff := cmp.Diff(newPath, path); diff != "" {
   734  			t.Errorf("(-want, +got):\n%s", diff)
   735  		}
   736  	})
   737  }
   738  
   739  func TestAsPathLengthConditionWithOtherCondition(t *testing.T) {
   740  	// setup
   741  	// create path
   742  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
   743  	origin := bgp.NewPathAttributeOrigin(0)
   744  	aspathParam := []bgp.AsPathParamInterface{
   745  		bgp.NewAsPathParam(2, []uint16{65001, 65000, 65004, 65004, 65005}),
   746  		bgp.NewAsPathParam(1, []uint16{65001, 65000, 65004, 65005}),
   747  	}
   748  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   749  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
   750  	med := bgp.NewPathAttributeMultiExitDisc(0)
   751  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   752  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   753  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   754  	UpdatePathAttrs4ByteAs(logger, updateMsg.Body.(*bgp.BGPUpdate))
   755  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   756  
   757  	// create policy
   758  	ps := createPrefixSet("ps1", "10.10.1.0/16", "21..24")
   759  	ns := createNeighborSet("ns1", "10.0.0.1")
   760  
   761  	ds := oc.DefinedSets{}
   762  	ds.PrefixSets = []oc.PrefixSet{ps}
   763  	ds.NeighborSets = []oc.NeighborSet{ns}
   764  
   765  	// create match condition
   766  	asPathLength := oc.AsPathLength{
   767  		Operator: "le",
   768  		Value:    10,
   769  	}
   770  
   771  	s := createStatement("statement1", "ps1", "ns1", false)
   772  	s.Conditions.BgpConditions.AsPathLength = asPathLength
   773  	pd := createPolicyDefinition("pd1", s)
   774  	pl := createRoutingPolicy(ds, pd)
   775  
   776  	//test
   777  	r := NewRoutingPolicy(logger)
   778  	err := r.reload(pl)
   779  	assert.Nil(t, err)
   780  	p := r.policyMap["pd1"]
   781  	pType, newPath := p.Apply(logger, path, nil)
   782  	assert.Equal(t, ROUTE_TYPE_REJECT, pType)
   783  	assert.Equal(t, newPath, path)
   784  
   785  }
   786  
   787  func TestAs4PathLengthConditionEvaluate(t *testing.T) {
   788  	// setup
   789  	// create path
   790  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
   791  	origin := bgp.NewPathAttributeOrigin(0)
   792  	aspathParam := []bgp.AsPathParamInterface{
   793  		bgp.NewAs4PathParam(2, []uint32{
   794  			createAs4Value("65001.1"),
   795  			createAs4Value("65000.1"),
   796  			createAs4Value("65004.1"),
   797  			createAs4Value("65005.1"),
   798  		}),
   799  		bgp.NewAs4PathParam(1, []uint32{
   800  			createAs4Value("65001.1"),
   801  			createAs4Value("65000.1"),
   802  			createAs4Value("65004.1"),
   803  			createAs4Value("65005.1"),
   804  		}),
   805  	}
   806  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   807  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
   808  	med := bgp.NewPathAttributeMultiExitDisc(0)
   809  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   810  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   811  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   812  	UpdatePathAttrs4ByteAs(logger, updateMsg.Body.(*bgp.BGPUpdate))
   813  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   814  
   815  	// create match condition
   816  	asPathLength := oc.AsPathLength{
   817  		Operator: "eq",
   818  		Value:    5,
   819  	}
   820  	c, _ := NewAsPathLengthCondition(asPathLength)
   821  
   822  	// test
   823  	assert.Equal(t, true, c.Evaluate(path, nil))
   824  
   825  	// create match condition
   826  	asPathLength = oc.AsPathLength{
   827  		Operator: "ge",
   828  		Value:    3,
   829  	}
   830  	c, _ = NewAsPathLengthCondition(asPathLength)
   831  
   832  	// test
   833  	assert.Equal(t, true, c.Evaluate(path, nil))
   834  
   835  	// create match condition
   836  	asPathLength = oc.AsPathLength{
   837  		Operator: "le",
   838  		Value:    3,
   839  	}
   840  	c, _ = NewAsPathLengthCondition(asPathLength)
   841  
   842  	// test
   843  	assert.Equal(t, false, c.Evaluate(path, nil))
   844  }
   845  
   846  func addPolicy(r *RoutingPolicy, x *Policy) {
   847  	for _, s := range x.Statements {
   848  		for _, c := range s.Conditions {
   849  			r.validateCondition(c)
   850  		}
   851  	}
   852  }
   853  
   854  func TestAs4PathLengthConditionWithOtherCondition(t *testing.T) {
   855  	// setup
   856  	// create path
   857  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
   858  	origin := bgp.NewPathAttributeOrigin(0)
   859  	aspathParam := []bgp.AsPathParamInterface{
   860  		bgp.NewAs4PathParam(2, []uint32{
   861  			createAs4Value("65001.1"),
   862  			createAs4Value("65000.1"),
   863  			createAs4Value("65004.1"),
   864  			createAs4Value("65004.1"),
   865  			createAs4Value("65005.1"),
   866  		}),
   867  		bgp.NewAs4PathParam(1, []uint32{
   868  			createAs4Value("65001.1"),
   869  			createAs4Value("65000.1"),
   870  			createAs4Value("65004.1"),
   871  			createAs4Value("65005.1"),
   872  		}),
   873  	}
   874  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
   875  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
   876  	med := bgp.NewPathAttributeMultiExitDisc(0)
   877  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   878  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   879  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   880  	UpdatePathAttrs4ByteAs(logger, updateMsg.Body.(*bgp.BGPUpdate))
   881  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
   882  
   883  	// create policy
   884  	ps := createPrefixSet("ps1", "10.10.1.0/16", "21..24")
   885  	ns := createNeighborSet("ns1", "10.0.0.1")
   886  
   887  	ds := oc.DefinedSets{}
   888  	ds.PrefixSets = []oc.PrefixSet{ps}
   889  	ds.NeighborSets = []oc.NeighborSet{ns}
   890  
   891  	// create match condition
   892  	asPathLength := oc.AsPathLength{
   893  		Operator: "le",
   894  		Value:    10,
   895  	}
   896  
   897  	s := createStatement("statement1", "ps1", "ns1", false)
   898  	s.Conditions.BgpConditions.AsPathLength = asPathLength
   899  	pd := createPolicyDefinition("pd1", s)
   900  	pl := createRoutingPolicy(ds, pd)
   901  
   902  	//test
   903  	r := NewRoutingPolicy(logger)
   904  	r.reload(pl)
   905  	p, _ := NewPolicy(pl.PolicyDefinitions[0])
   906  	addPolicy(r, p)
   907  	pType, newPath := p.Apply(logger, path, nil)
   908  	assert.Equal(t, ROUTE_TYPE_REJECT, pType)
   909  	assert.Equal(t, newPath, path)
   910  
   911  }
   912  
   913  func TestAsPathConditionEvaluate(t *testing.T) {
   914  
   915  	// setup
   916  	// create path
   917  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
   918  	origin := bgp.NewPathAttributeOrigin(0)
   919  	aspathParam1 := []bgp.AsPathParamInterface{
   920  		bgp.NewAsPathParam(2, []uint16{65001, 65000, 65010, 65004, 65005}),
   921  	}
   922  	aspath := bgp.NewPathAttributeAsPath(aspathParam1)
   923  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
   924  	med := bgp.NewPathAttributeMultiExitDisc(0)
   925  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
   926  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
   927  	updateMsg1 := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   928  	UpdatePathAttrs4ByteAs(logger, updateMsg1.Body.(*bgp.BGPUpdate))
   929  	path1 := ProcessMessage(updateMsg1, peer, time.Now())[0]
   930  
   931  	aspathParam2 := []bgp.AsPathParamInterface{
   932  		bgp.NewAsPathParam(2, []uint16{65010}),
   933  	}
   934  	aspath2 := bgp.NewPathAttributeAsPath(aspathParam2)
   935  	pathAttributes = []bgp.PathAttributeInterface{origin, aspath2, nexthop, med}
   936  	updateMsg2 := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
   937  	UpdatePathAttrs4ByteAs(logger, updateMsg2.Body.(*bgp.BGPUpdate))
   938  	path2 := ProcessMessage(updateMsg2, peer, time.Now())[0]
   939  
   940  	// create match condition
   941  	asPathSet1 := oc.AsPathSet{
   942  		AsPathSetName: "asset1",
   943  		AsPathList:    []string{"^65001"},
   944  	}
   945  
   946  	asPathSet2 := oc.AsPathSet{
   947  		AsPathSetName: "asset2",
   948  		AsPathList:    []string{"65005$"},
   949  	}
   950  
   951  	asPathSet3 := oc.AsPathSet{
   952  		AsPathSetName: "asset3",
   953  		AsPathList:    []string{"65004", "65005$"},
   954  	}
   955  
   956  	asPathSet4 := oc.AsPathSet{
   957  		AsPathSetName: "asset4",
   958  		AsPathList:    []string{"65000$"},
   959  	}
   960  
   961  	asPathSet5 := oc.AsPathSet{
   962  		AsPathSetName: "asset5",
   963  		AsPathList:    []string{"65010"},
   964  	}
   965  
   966  	asPathSet6 := oc.AsPathSet{
   967  		AsPathSetName: "asset6",
   968  		AsPathList:    []string{"^65010$"},
   969  	}
   970  
   971  	m := make(map[string]DefinedSet)
   972  	for _, s := range []oc.AsPathSet{asPathSet1, asPathSet2, asPathSet3,
   973  		asPathSet4, asPathSet5, asPathSet6} {
   974  		a, _ := NewAsPathSet(s)
   975  		m[s.AsPathSetName] = a
   976  	}
   977  
   978  	createAspathC := func(name string, option oc.MatchSetOptionsType) *AsPathCondition {
   979  		matchSet := oc.MatchAsPathSet{}
   980  		matchSet.AsPathSet = name
   981  		matchSet.MatchSetOptions = option
   982  		p, _ := NewAsPathCondition(matchSet)
   983  		if v, ok := m[name]; ok {
   984  			p.set = v.(*AsPathSet)
   985  		}
   986  		return p
   987  	}
   988  
   989  	p1 := createAspathC("asset1", oc.MATCH_SET_OPTIONS_TYPE_ANY)
   990  	p2 := createAspathC("asset2", oc.MATCH_SET_OPTIONS_TYPE_ANY)
   991  	p3 := createAspathC("asset3", oc.MATCH_SET_OPTIONS_TYPE_ANY)
   992  	p4 := createAspathC("asset4", oc.MATCH_SET_OPTIONS_TYPE_ANY)
   993  	p5 := createAspathC("asset5", oc.MATCH_SET_OPTIONS_TYPE_ANY)
   994  	p6 := createAspathC("asset6", oc.MATCH_SET_OPTIONS_TYPE_ANY)
   995  	p7 := createAspathC("asset3", oc.MATCH_SET_OPTIONS_TYPE_ALL)
   996  	p8 := createAspathC("asset3", oc.MATCH_SET_OPTIONS_TYPE_INVERT)
   997  
   998  	// test
   999  	assert.Equal(t, true, p1.Evaluate(path1, nil))
  1000  	assert.Equal(t, true, p2.Evaluate(path1, nil))
  1001  	assert.Equal(t, true, p3.Evaluate(path1, nil))
  1002  	assert.Equal(t, false, p4.Evaluate(path1, nil))
  1003  	assert.Equal(t, true, p5.Evaluate(path1, nil))
  1004  	assert.Equal(t, false, p6.Evaluate(path1, nil))
  1005  	assert.Equal(t, true, p6.Evaluate(path2, nil))
  1006  	assert.Equal(t, true, p7.Evaluate(path1, nil))
  1007  	assert.Equal(t, true, p8.Evaluate(path2, nil))
  1008  }
  1009  
  1010  func TestMultipleAsPathConditionEvaluate(t *testing.T) {
  1011  
  1012  	// setup
  1013  	// create path
  1014  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1015  	origin := bgp.NewPathAttributeOrigin(0)
  1016  	aspathParam1 := []bgp.AsPathParamInterface{
  1017  		bgp.NewAsPathParam(2, []uint16{65001, 65000, 54000, 65004, 65005}),
  1018  	}
  1019  	aspath := bgp.NewPathAttributeAsPath(aspathParam1)
  1020  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1021  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1022  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  1023  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1024  	updateMsg1 := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1025  	UpdatePathAttrs4ByteAs(logger, updateMsg1.Body.(*bgp.BGPUpdate))
  1026  	path1 := ProcessMessage(updateMsg1, peer, time.Now())[0]
  1027  
  1028  	// create match condition
  1029  	asPathSet1 := oc.AsPathSet{
  1030  		AsPathSetName: "asset1",
  1031  		AsPathList:    []string{"^65001_65000"},
  1032  	}
  1033  
  1034  	asPathSet2 := oc.AsPathSet{
  1035  		AsPathSetName: "asset2",
  1036  		AsPathList:    []string{"65004_65005$"},
  1037  	}
  1038  
  1039  	asPathSet3 := oc.AsPathSet{
  1040  		AsPathSetName: "asset3",
  1041  		AsPathList:    []string{"65001_65000_54000"},
  1042  	}
  1043  
  1044  	asPathSet4 := oc.AsPathSet{
  1045  		AsPathSetName: "asset4",
  1046  		AsPathList:    []string{"54000_65004_65005"},
  1047  	}
  1048  
  1049  	asPathSet5 := oc.AsPathSet{
  1050  		AsPathSetName: "asset5",
  1051  		AsPathList:    []string{"^65001 65000 54000 65004 65005$"},
  1052  	}
  1053  
  1054  	asPathSet6 := oc.AsPathSet{
  1055  		AsPathSetName: "asset6",
  1056  		AsPathList:    []string{".*_[0-9]+_65005"},
  1057  	}
  1058  
  1059  	asPathSet7 := oc.AsPathSet{
  1060  		AsPathSetName: "asset7",
  1061  		AsPathList:    []string{".*_5[0-9]+_[0-9]+"},
  1062  	}
  1063  
  1064  	asPathSet8 := oc.AsPathSet{
  1065  		AsPathSetName: "asset8",
  1066  		AsPathList:    []string{"6[0-9]+_6[0-9]+_5[0-9]+"},
  1067  	}
  1068  
  1069  	asPathSet9 := oc.AsPathSet{
  1070  		AsPathSetName: "asset9",
  1071  		AsPathList:    []string{"6[0-9]+__6[0-9]+"},
  1072  	}
  1073  
  1074  	m := make(map[string]DefinedSet)
  1075  	for _, s := range []oc.AsPathSet{asPathSet1, asPathSet2, asPathSet3,
  1076  		asPathSet4, asPathSet5, asPathSet6, asPathSet7, asPathSet8, asPathSet9} {
  1077  		a, _ := NewAsPathSet(s)
  1078  		m[s.AsPathSetName] = a
  1079  	}
  1080  
  1081  	createAspathC := func(name string, option oc.MatchSetOptionsType) *AsPathCondition {
  1082  		matchSet := oc.MatchAsPathSet{}
  1083  		matchSet.AsPathSet = name
  1084  		matchSet.MatchSetOptions = option
  1085  		p, _ := NewAsPathCondition(matchSet)
  1086  		if v, ok := m[name]; ok {
  1087  			p.set = v.(*AsPathSet)
  1088  		}
  1089  		return p
  1090  	}
  1091  
  1092  	p1 := createAspathC("asset1", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1093  	p2 := createAspathC("asset2", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1094  	p3 := createAspathC("asset3", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1095  	p4 := createAspathC("asset4", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1096  	p5 := createAspathC("asset5", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1097  	p6 := createAspathC("asset6", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1098  	p7 := createAspathC("asset7", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1099  	p8 := createAspathC("asset8", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1100  	p9 := createAspathC("asset9", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1101  
  1102  	// test
  1103  	assert.Equal(t, true, p1.Evaluate(path1, nil))
  1104  	assert.Equal(t, true, p2.Evaluate(path1, nil))
  1105  	assert.Equal(t, true, p3.Evaluate(path1, nil))
  1106  	assert.Equal(t, true, p4.Evaluate(path1, nil))
  1107  	assert.Equal(t, true, p5.Evaluate(path1, nil))
  1108  	assert.Equal(t, true, p6.Evaluate(path1, nil))
  1109  	assert.Equal(t, true, p7.Evaluate(path1, nil))
  1110  	assert.Equal(t, true, p8.Evaluate(path1, nil))
  1111  	assert.Equal(t, false, p9.Evaluate(path1, nil))
  1112  }
  1113  
  1114  func TestAsPathCondition(t *testing.T) {
  1115  	type astest struct {
  1116  		path   *Path
  1117  		result bool
  1118  	}
  1119  
  1120  	makeTest := func(asPathAttrType uint8, ases []uint32, result bool) astest {
  1121  		aspathParam := []bgp.AsPathParamInterface{
  1122  			bgp.NewAs4PathParam(asPathAttrType, ases),
  1123  		}
  1124  		pathAttributes := []bgp.PathAttributeInterface{bgp.NewPathAttributeAsPath(aspathParam)}
  1125  		p := NewPath(nil, nil, false, pathAttributes, time.Time{}, false)
  1126  		return astest{
  1127  			path:   p,
  1128  			result: result,
  1129  		}
  1130  	}
  1131  
  1132  	tests := make(map[string][]astest)
  1133  
  1134  	tests["^(100_)+(200_)+$"] = []astest{
  1135  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{100, 200}, true),
  1136  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{100, 100, 200}, true),
  1137  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{100, 100, 200, 200}, true),
  1138  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{100, 100, 200, 200, 300}, false),
  1139  	}
  1140  
  1141  	aslen255 := func() []uint32 {
  1142  		r := make([]uint32, 255)
  1143  		for i := 0; i < 255; i++ {
  1144  			r[i] = 1
  1145  		}
  1146  		return r
  1147  	}()
  1148  	tests["^([0-9]+_){0,255}$"] = []astest{
  1149  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, aslen255, true),
  1150  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, append(aslen255, 1), false),
  1151  	}
  1152  
  1153  	tests["(_7521)$"] = []astest{
  1154  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{7521}, true),
  1155  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{1000, 7521}, true),
  1156  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{7521, 1000}, false),
  1157  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{1000, 7521, 100}, false),
  1158  	}
  1159  
  1160  	tests["^65001( |_.*_)65535$"] = []astest{
  1161  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{65001, 65535}, true),
  1162  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{65001, 65001, 65535}, true),
  1163  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{65001, 65002, 65003, 65535}, true),
  1164  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{65001, 65534}, false),
  1165  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{65002, 65535}, false),
  1166  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{65002, 65001, 65535}, false),
  1167  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{65001, 65535, 65002}, false),
  1168  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{650019, 65535}, false),
  1169  		makeTest(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{65001, 165535}, false),
  1170  	}
  1171  
  1172  	for k, v := range tests {
  1173  		s, _ := NewAsPathSet(oc.AsPathSet{
  1174  			AsPathSetName: k,
  1175  			AsPathList:    []string{k},
  1176  		})
  1177  		c, _ := NewAsPathCondition(oc.MatchAsPathSet{
  1178  			AsPathSet:       k,
  1179  			MatchSetOptions: oc.MATCH_SET_OPTIONS_TYPE_ANY,
  1180  		})
  1181  		c.set = s
  1182  		for _, a := range v {
  1183  			result := c.Evaluate(a.path, nil)
  1184  			if a.result != result {
  1185  				t.Logf("failed: EXP: %v, ASSTR: %v, Expected: %v, Result: %v",
  1186  					k,
  1187  					a.path.GetAsString(),
  1188  					a.result,
  1189  					result)
  1190  			}
  1191  		}
  1192  	}
  1193  }
  1194  
  1195  func TestAsPathConditionWithOtherCondition(t *testing.T) {
  1196  
  1197  	// setup
  1198  	// create path
  1199  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1200  	origin := bgp.NewPathAttributeOrigin(0)
  1201  	aspathParam := []bgp.AsPathParamInterface{
  1202  		bgp.NewAsPathParam(1, []uint16{65001, 65000, 65004, 65005}),
  1203  		bgp.NewAsPathParam(2, []uint16{65001, 65000, 65004, 65004, 65005}),
  1204  	}
  1205  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  1206  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1207  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1208  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  1209  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1210  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1211  	UpdatePathAttrs4ByteAs(logger, updateMsg.Body.(*bgp.BGPUpdate))
  1212  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  1213  
  1214  	// create policy
  1215  	asPathSet := oc.AsPathSet{
  1216  		AsPathSetName: "asset1",
  1217  		AsPathList:    []string{"65005$"},
  1218  	}
  1219  
  1220  	ps := createPrefixSet("ps1", "10.10.1.0/16", "21..24")
  1221  	ns := createNeighborSet("ns1", "10.0.0.1")
  1222  
  1223  	ds := oc.DefinedSets{}
  1224  	ds.PrefixSets = []oc.PrefixSet{ps}
  1225  	ds.NeighborSets = []oc.NeighborSet{ns}
  1226  	ds.BgpDefinedSets.AsPathSets = []oc.AsPathSet{asPathSet}
  1227  
  1228  	s := createStatement("statement1", "ps1", "ns1", false)
  1229  	s.Conditions.BgpConditions.MatchAsPathSet.AsPathSet = "asset1"
  1230  
  1231  	pd := createPolicyDefinition("pd1", s)
  1232  	pl := createRoutingPolicy(ds, pd)
  1233  
  1234  	//test
  1235  	r := NewRoutingPolicy(logger)
  1236  	err := r.reload(pl)
  1237  	assert.Nil(t, err)
  1238  	p := r.policyMap["pd1"]
  1239  	pType, newPath := p.Apply(logger, path, nil)
  1240  	assert.Equal(t, ROUTE_TYPE_REJECT, pType)
  1241  	assert.Equal(t, newPath, path)
  1242  
  1243  }
  1244  
  1245  func TestAs4PathConditionEvaluate(t *testing.T) {
  1246  
  1247  	// setup
  1248  	// create path
  1249  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1250  	origin := bgp.NewPathAttributeOrigin(0)
  1251  	aspathParam1 := []bgp.AsPathParamInterface{
  1252  		bgp.NewAs4PathParam(2, []uint32{
  1253  			createAs4Value("65001.1"),
  1254  			createAs4Value("65000.1"),
  1255  			createAs4Value("65010.1"),
  1256  			createAs4Value("65004.1"),
  1257  			createAs4Value("65005.1"),
  1258  		})}
  1259  
  1260  	aspath := bgp.NewPathAttributeAsPath(aspathParam1)
  1261  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1262  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1263  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  1264  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1265  	updateMsg1 := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1266  	UpdatePathAttrs4ByteAs(logger, updateMsg1.Body.(*bgp.BGPUpdate))
  1267  	path1 := ProcessMessage(updateMsg1, peer, time.Now())[0]
  1268  
  1269  	aspathParam2 := []bgp.AsPathParamInterface{
  1270  		bgp.NewAs4PathParam(2, []uint32{
  1271  			createAs4Value("65010.1"),
  1272  		}),
  1273  	}
  1274  	aspath2 := bgp.NewPathAttributeAsPath(aspathParam2)
  1275  	pathAttributes = []bgp.PathAttributeInterface{origin, aspath2, nexthop, med}
  1276  	updateMsg2 := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1277  	UpdatePathAttrs4ByteAs(logger, updateMsg2.Body.(*bgp.BGPUpdate))
  1278  	path2 := ProcessMessage(updateMsg2, peer, time.Now())[0]
  1279  
  1280  	// create match condition
  1281  	asPathSet1 := oc.AsPathSet{
  1282  		AsPathSetName: "asset1",
  1283  		AsPathList:    []string{fmt.Sprintf("^%d", createAs4Value("65001.1"))},
  1284  	}
  1285  
  1286  	asPathSet2 := oc.AsPathSet{
  1287  		AsPathSetName: "asset2",
  1288  		AsPathList:    []string{fmt.Sprintf("%d$", createAs4Value("65005.1"))},
  1289  	}
  1290  
  1291  	asPathSet3 := oc.AsPathSet{
  1292  		AsPathSetName: "asset3",
  1293  		AsPathList: []string{
  1294  			fmt.Sprintf("%d", createAs4Value("65004.1")),
  1295  			fmt.Sprintf("%d$", createAs4Value("65005.1")),
  1296  		},
  1297  	}
  1298  
  1299  	asPathSet4 := oc.AsPathSet{
  1300  		AsPathSetName: "asset4",
  1301  		AsPathList: []string{
  1302  			fmt.Sprintf("%d$", createAs4Value("65000.1")),
  1303  		},
  1304  	}
  1305  
  1306  	asPathSet5 := oc.AsPathSet{
  1307  		AsPathSetName: "asset5",
  1308  		AsPathList: []string{
  1309  			fmt.Sprintf("%d", createAs4Value("65010.1")),
  1310  		},
  1311  	}
  1312  
  1313  	asPathSet6 := oc.AsPathSet{
  1314  		AsPathSetName: "asset6",
  1315  		AsPathList: []string{
  1316  			fmt.Sprintf("%d$", createAs4Value("65010.1")),
  1317  		},
  1318  	}
  1319  
  1320  	m := make(map[string]DefinedSet)
  1321  	for _, s := range []oc.AsPathSet{asPathSet1, asPathSet2, asPathSet3,
  1322  		asPathSet4, asPathSet5, asPathSet6} {
  1323  		a, _ := NewAsPathSet(s)
  1324  		m[s.AsPathSetName] = a
  1325  	}
  1326  
  1327  	createAspathC := func(name string, option oc.MatchSetOptionsType) *AsPathCondition {
  1328  		matchSet := oc.MatchAsPathSet{}
  1329  		matchSet.AsPathSet = name
  1330  		matchSet.MatchSetOptions = option
  1331  		p, _ := NewAsPathCondition(matchSet)
  1332  		if v, ok := m[name]; ok {
  1333  			p.set = v.(*AsPathSet)
  1334  		}
  1335  		return p
  1336  	}
  1337  
  1338  	p1 := createAspathC("asset1", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1339  	p2 := createAspathC("asset2", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1340  	p3 := createAspathC("asset3", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1341  	p4 := createAspathC("asset4", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1342  	p5 := createAspathC("asset5", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1343  	p6 := createAspathC("asset6", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1344  
  1345  	p7 := createAspathC("asset3", oc.MATCH_SET_OPTIONS_TYPE_ALL)
  1346  	p8 := createAspathC("asset3", oc.MATCH_SET_OPTIONS_TYPE_INVERT)
  1347  
  1348  	// test
  1349  	assert.Equal(t, true, p1.Evaluate(path1, nil))
  1350  	assert.Equal(t, true, p2.Evaluate(path1, nil))
  1351  	assert.Equal(t, true, p3.Evaluate(path1, nil))
  1352  	assert.Equal(t, false, p4.Evaluate(path1, nil))
  1353  	assert.Equal(t, true, p5.Evaluate(path1, nil))
  1354  	assert.Equal(t, false, p6.Evaluate(path1, nil))
  1355  	assert.Equal(t, true, p6.Evaluate(path2, nil))
  1356  
  1357  	assert.Equal(t, true, p7.Evaluate(path1, nil))
  1358  	assert.Equal(t, true, p8.Evaluate(path2, nil))
  1359  }
  1360  
  1361  func TestMultipleAs4PathConditionEvaluate(t *testing.T) {
  1362  
  1363  	// setup
  1364  	// create path
  1365  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1366  	origin := bgp.NewPathAttributeOrigin(0)
  1367  	aspathParam1 := []bgp.AsPathParamInterface{
  1368  		bgp.NewAs4PathParam(2, []uint32{
  1369  			createAs4Value("65001.1"),
  1370  			createAs4Value("65000.1"),
  1371  			createAs4Value("54000.1"),
  1372  			createAs4Value("65004.1"),
  1373  			createAs4Value("65005.1"),
  1374  		}),
  1375  	}
  1376  
  1377  	aspath := bgp.NewPathAttributeAsPath(aspathParam1)
  1378  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1379  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1380  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  1381  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1382  	updateMsg1 := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1383  	UpdatePathAttrs4ByteAs(logger, updateMsg1.Body.(*bgp.BGPUpdate))
  1384  	path1 := ProcessMessage(updateMsg1, peer, time.Now())[0]
  1385  
  1386  	// create match condition
  1387  	asPathSet1 := oc.AsPathSet{
  1388  		AsPathSetName: "asset1",
  1389  		AsPathList: []string{
  1390  			fmt.Sprintf("^%d_%d", createAs4Value("65001.1"), createAs4Value("65000.1")),
  1391  		},
  1392  	}
  1393  
  1394  	asPathSet2 := oc.AsPathSet{
  1395  		AsPathSetName: "asset2",
  1396  		AsPathList: []string{
  1397  			fmt.Sprintf("%d_%d$", createAs4Value("65004.1"), createAs4Value("65005.1")),
  1398  		},
  1399  	}
  1400  
  1401  	asPathSet3 := oc.AsPathSet{
  1402  		AsPathSetName: "asset3",
  1403  		AsPathList: []string{
  1404  			fmt.Sprintf("%d_%d_%d", createAs4Value("65001.1"), createAs4Value("65000.1"), createAs4Value("54000.1")),
  1405  		},
  1406  	}
  1407  
  1408  	asPathSet4 := oc.AsPathSet{
  1409  		AsPathSetName: "asset4",
  1410  		AsPathList: []string{
  1411  			fmt.Sprintf("%d_%d_%d", createAs4Value("54000.1"), createAs4Value("65004.1"), createAs4Value("65005.1")),
  1412  		},
  1413  	}
  1414  
  1415  	asPathSet5 := oc.AsPathSet{
  1416  		AsPathSetName: "asset5",
  1417  		AsPathList: []string{
  1418  			fmt.Sprintf("^%d %d %d %d %d$", createAs4Value("65001.1"), createAs4Value("65000.1"), createAs4Value("54000.1"), createAs4Value("65004.1"), createAs4Value("65005.1")),
  1419  		},
  1420  	}
  1421  
  1422  	asPathSet6 := oc.AsPathSet{
  1423  		AsPathSetName: "asset6",
  1424  		AsPathList: []string{
  1425  			fmt.Sprintf(".*_[0-9]+_%d", createAs4Value("65005.1")),
  1426  		},
  1427  	}
  1428  
  1429  	asPathSet7 := oc.AsPathSet{
  1430  		AsPathSetName: "asset7",
  1431  		AsPathList:    []string{".*_3[0-9]+_[0-9]+"},
  1432  	}
  1433  
  1434  	asPathSet8 := oc.AsPathSet{
  1435  		AsPathSetName: "asset8",
  1436  		AsPathList:    []string{"4[0-9]+_4[0-9]+_3[0-9]+"},
  1437  	}
  1438  
  1439  	asPathSet9 := oc.AsPathSet{
  1440  		AsPathSetName: "asset9",
  1441  		AsPathList:    []string{"4[0-9]+__4[0-9]+"},
  1442  	}
  1443  
  1444  	m := make(map[string]DefinedSet)
  1445  	for _, s := range []oc.AsPathSet{asPathSet1, asPathSet2, asPathSet3,
  1446  		asPathSet4, asPathSet5, asPathSet6, asPathSet7, asPathSet8, asPathSet9} {
  1447  		a, _ := NewAsPathSet(s)
  1448  		m[s.AsPathSetName] = a
  1449  	}
  1450  
  1451  	createAspathC := func(name string, option oc.MatchSetOptionsType) *AsPathCondition {
  1452  		matchSet := oc.MatchAsPathSet{}
  1453  		matchSet.AsPathSet = name
  1454  		matchSet.MatchSetOptions = option
  1455  		p, _ := NewAsPathCondition(matchSet)
  1456  		if v, ok := m[name]; ok {
  1457  			p.set = v.(*AsPathSet)
  1458  		}
  1459  		return p
  1460  	}
  1461  
  1462  	p1 := createAspathC("asset1", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1463  	p2 := createAspathC("asset2", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1464  	p3 := createAspathC("asset3", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1465  	p4 := createAspathC("asset4", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1466  	p5 := createAspathC("asset5", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1467  	p6 := createAspathC("asset6", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1468  	p7 := createAspathC("asset7", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1469  	p8 := createAspathC("asset8", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1470  	p9 := createAspathC("asset9", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1471  
  1472  	// test
  1473  	assert.Equal(t, true, p1.Evaluate(path1, nil))
  1474  	assert.Equal(t, true, p2.Evaluate(path1, nil))
  1475  	assert.Equal(t, true, p3.Evaluate(path1, nil))
  1476  	assert.Equal(t, true, p4.Evaluate(path1, nil))
  1477  	assert.Equal(t, true, p5.Evaluate(path1, nil))
  1478  	assert.Equal(t, true, p6.Evaluate(path1, nil))
  1479  	assert.Equal(t, true, p7.Evaluate(path1, nil))
  1480  	assert.Equal(t, true, p8.Evaluate(path1, nil))
  1481  	assert.Equal(t, false, p9.Evaluate(path1, nil))
  1482  }
  1483  
  1484  func TestAs4PathConditionWithOtherCondition(t *testing.T) {
  1485  
  1486  	// setup
  1487  	// create path
  1488  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1489  	origin := bgp.NewPathAttributeOrigin(0)
  1490  	aspathParam := []bgp.AsPathParamInterface{
  1491  		bgp.NewAs4PathParam(1, []uint32{
  1492  			createAs4Value("65001.1"),
  1493  			createAs4Value("65000.1"),
  1494  			createAs4Value("65004.1"),
  1495  			createAs4Value("65005.1"),
  1496  		}),
  1497  		bgp.NewAs4PathParam(2, []uint32{
  1498  			createAs4Value("65001.1"),
  1499  			createAs4Value("65000.1"),
  1500  			createAs4Value("65004.1"),
  1501  			createAs4Value("65004.1"),
  1502  			createAs4Value("65005.1"),
  1503  		}),
  1504  	}
  1505  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  1506  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1507  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1508  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  1509  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1510  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1511  	UpdatePathAttrs4ByteAs(logger, updateMsg.Body.(*bgp.BGPUpdate))
  1512  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  1513  
  1514  	// create policy
  1515  	asPathSet := oc.AsPathSet{
  1516  		AsPathSetName: "asset1",
  1517  		AsPathList:    []string{fmt.Sprintf("%d$", createAs4Value("65005.1"))},
  1518  	}
  1519  
  1520  	ps := createPrefixSet("ps1", "10.10.1.0/16", "21..24")
  1521  	ns := createNeighborSet("ns1", "10.0.0.1")
  1522  
  1523  	ds := oc.DefinedSets{}
  1524  	ds.PrefixSets = []oc.PrefixSet{ps}
  1525  	ds.NeighborSets = []oc.NeighborSet{ns}
  1526  	ds.BgpDefinedSets.AsPathSets = []oc.AsPathSet{asPathSet}
  1527  
  1528  	s := createStatement("statement1", "ps1", "ns1", false)
  1529  	s.Conditions.BgpConditions.MatchAsPathSet.AsPathSet = "asset1"
  1530  
  1531  	pd := createPolicyDefinition("pd1", s)
  1532  	pl := createRoutingPolicy(ds, pd)
  1533  
  1534  	//test
  1535  	r := NewRoutingPolicy(logger)
  1536  	r.reload(pl)
  1537  	p, _ := NewPolicy(pl.PolicyDefinitions[0])
  1538  	addPolicy(r, p)
  1539  	pType, newPath := p.Apply(logger, path, nil)
  1540  	assert.Equal(t, ROUTE_TYPE_REJECT, pType)
  1541  	assert.Equal(t, newPath, path)
  1542  
  1543  }
  1544  
  1545  func TestAs4PathConditionEvaluateMixedWith2byteAS(t *testing.T) {
  1546  
  1547  	// setup
  1548  	// create path
  1549  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1550  	origin := bgp.NewPathAttributeOrigin(0)
  1551  	aspathParam1 := []bgp.AsPathParamInterface{
  1552  		bgp.NewAs4PathParam(2, []uint32{
  1553  			createAs4Value("65001.1"),
  1554  			createAs4Value("65000.1"),
  1555  			createAs4Value("54000.1"),
  1556  			100,
  1557  			5000,
  1558  			createAs4Value("65004.1"),
  1559  			createAs4Value("65005.1"),
  1560  			4000,
  1561  		}),
  1562  	}
  1563  
  1564  	aspath := bgp.NewPathAttributeAsPath(aspathParam1)
  1565  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1566  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1567  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  1568  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1569  	updateMsg1 := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1570  	UpdatePathAttrs4ByteAs(logger, updateMsg1.Body.(*bgp.BGPUpdate))
  1571  	path1 := ProcessMessage(updateMsg1, peer, time.Now())[0]
  1572  
  1573  	// create match condition
  1574  	asPathSet1 := oc.AsPathSet{
  1575  		AsPathSetName: "asset1",
  1576  		AsPathList:    []string{fmt.Sprintf("^%d", createAs4Value("65001.1"))},
  1577  	}
  1578  
  1579  	asPathSet2 := oc.AsPathSet{
  1580  		AsPathSetName: "asset2",
  1581  		AsPathList:    []string{"4000$"},
  1582  	}
  1583  
  1584  	asPathSet3 := oc.AsPathSet{
  1585  		AsPathSetName: "asset3",
  1586  		AsPathList:    []string{fmt.Sprintf("%d", createAs4Value("65004.1")), "4000$"},
  1587  	}
  1588  
  1589  	asPathSet4 := oc.AsPathSet{
  1590  		AsPathSetName: "asset4",
  1591  		AsPathList:    []string{fmt.Sprintf("%d_%d_%d", createAs4Value("54000.1"), 100, 5000)},
  1592  	}
  1593  
  1594  	asPathSet5 := oc.AsPathSet{
  1595  		AsPathSetName: "asset5",
  1596  		AsPathList:    []string{".*_[0-9]+_100"},
  1597  	}
  1598  
  1599  	asPathSet6 := oc.AsPathSet{
  1600  		AsPathSetName: "asset6",
  1601  		AsPathList:    []string{".*_3[0-9]+_[0]+"},
  1602  	}
  1603  
  1604  	asPathSet7 := oc.AsPathSet{
  1605  		AsPathSetName: "asset7",
  1606  		AsPathList:    []string{".*_3[0-9]+_[1]+"},
  1607  	}
  1608  
  1609  	m := make(map[string]DefinedSet)
  1610  	for _, s := range []oc.AsPathSet{asPathSet1, asPathSet2, asPathSet3,
  1611  		asPathSet4, asPathSet5, asPathSet6, asPathSet7} {
  1612  		a, _ := NewAsPathSet(s)
  1613  		m[s.AsPathSetName] = a
  1614  	}
  1615  
  1616  	createAspathC := func(name string, option oc.MatchSetOptionsType) *AsPathCondition {
  1617  		matchSet := oc.MatchAsPathSet{}
  1618  		matchSet.AsPathSet = name
  1619  		matchSet.MatchSetOptions = option
  1620  		p, _ := NewAsPathCondition(matchSet)
  1621  		if v, ok := m[name]; ok {
  1622  			p.set = v.(*AsPathSet)
  1623  		}
  1624  		return p
  1625  	}
  1626  
  1627  	p1 := createAspathC("asset1", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1628  	p2 := createAspathC("asset2", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1629  	p3 := createAspathC("asset3", oc.MATCH_SET_OPTIONS_TYPE_ALL)
  1630  	p4 := createAspathC("asset4", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1631  	p5 := createAspathC("asset5", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1632  	p6 := createAspathC("asset6", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1633  	p7 := createAspathC("asset7", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1634  
  1635  	// test
  1636  	assert.Equal(t, true, p1.Evaluate(path1, nil))
  1637  	assert.Equal(t, true, p2.Evaluate(path1, nil))
  1638  	assert.Equal(t, true, p3.Evaluate(path1, nil))
  1639  	assert.Equal(t, true, p4.Evaluate(path1, nil))
  1640  	assert.Equal(t, true, p5.Evaluate(path1, nil))
  1641  	assert.Equal(t, false, p6.Evaluate(path1, nil))
  1642  	assert.Equal(t, true, p7.Evaluate(path1, nil))
  1643  
  1644  }
  1645  
  1646  func TestCommunityConditionEvaluate(t *testing.T) {
  1647  
  1648  	// setup
  1649  	// create path
  1650  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1651  	origin := bgp.NewPathAttributeOrigin(0)
  1652  	aspathParam1 := []bgp.AsPathParamInterface{
  1653  		bgp.NewAsPathParam(2, []uint16{65001, 65000, 65004, 65005}),
  1654  		bgp.NewAsPathParam(1, []uint16{65001, 65010, 65004, 65005}),
  1655  	}
  1656  	aspath := bgp.NewPathAttributeAsPath(aspathParam1)
  1657  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1658  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1659  	communities := bgp.NewPathAttributeCommunities([]uint32{
  1660  		stringToCommunityValue("65001:100"),
  1661  		stringToCommunityValue("65001:200"),
  1662  		stringToCommunityValue("65001:300"),
  1663  		stringToCommunityValue("65001:400"),
  1664  		0x00000000,
  1665  		0xFFFFFF01,
  1666  		0xFFFFFF02,
  1667  		0xFFFFFF03})
  1668  
  1669  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, communities}
  1670  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1671  	updateMsg1 := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1672  	UpdatePathAttrs4ByteAs(logger, updateMsg1.Body.(*bgp.BGPUpdate))
  1673  	path1 := ProcessMessage(updateMsg1, peer, time.Now())[0]
  1674  
  1675  	communities2 := bgp.NewPathAttributeCommunities([]uint32{
  1676  		stringToCommunityValue("65001:100"),
  1677  		stringToCommunityValue("65001:200"),
  1678  		stringToCommunityValue("65001:300"),
  1679  		stringToCommunityValue("65001:400")})
  1680  
  1681  	pathAttributes2 := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, communities2}
  1682  	updateMsg2 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nlri)
  1683  	UpdatePathAttrs4ByteAs(logger, updateMsg2.Body.(*bgp.BGPUpdate))
  1684  	path2 := ProcessMessage(updateMsg2, peer, time.Now())[0]
  1685  
  1686  	// create match condition
  1687  	comSet1 := oc.CommunitySet{
  1688  		CommunitySetName: "comset1",
  1689  		CommunityList:    []string{"65001:10", "65001:50", "65001:100"},
  1690  	}
  1691  
  1692  	comSet2 := oc.CommunitySet{
  1693  		CommunitySetName: "comset2",
  1694  		CommunityList:    []string{"65001:200"},
  1695  	}
  1696  
  1697  	comSet3 := oc.CommunitySet{
  1698  		CommunitySetName: "comset3",
  1699  		CommunityList:    []string{"4259905936"},
  1700  	}
  1701  
  1702  	comSet4 := oc.CommunitySet{
  1703  		CommunitySetName: "comset4",
  1704  		CommunityList:    []string{"^[0-9]*:300$"},
  1705  	}
  1706  
  1707  	comSet5 := oc.CommunitySet{
  1708  		CommunitySetName: "comset5",
  1709  		CommunityList:    []string{"INTERNET"},
  1710  	}
  1711  
  1712  	comSet6 := oc.CommunitySet{
  1713  		CommunitySetName: "comset6",
  1714  		CommunityList:    []string{"NO_EXPORT"},
  1715  	}
  1716  
  1717  	comSet7 := oc.CommunitySet{
  1718  		CommunitySetName: "comset7",
  1719  		CommunityList:    []string{"NO_ADVERTISE"},
  1720  	}
  1721  
  1722  	comSet8 := oc.CommunitySet{
  1723  		CommunitySetName: "comset8",
  1724  		CommunityList:    []string{"NO_EXPORT_SUBCONFED"},
  1725  	}
  1726  
  1727  	comSet9 := oc.CommunitySet{
  1728  		CommunitySetName: "comset9",
  1729  		CommunityList: []string{
  1730  			"65001:\\d+",
  1731  			"\\d+:\\d00",
  1732  		},
  1733  	}
  1734  
  1735  	comSet10 := oc.CommunitySet{
  1736  		CommunitySetName: "comset10",
  1737  		CommunityList: []string{
  1738  			"65001:1",
  1739  			"65001:2",
  1740  			"65001:3",
  1741  		},
  1742  	}
  1743  
  1744  	m := make(map[string]DefinedSet)
  1745  
  1746  	for _, c := range []oc.CommunitySet{comSet1, comSet2, comSet3,
  1747  		comSet4, comSet5, comSet6, comSet7, comSet8, comSet9, comSet10} {
  1748  		s, _ := NewCommunitySet(c)
  1749  		m[c.CommunitySetName] = s
  1750  	}
  1751  
  1752  	createCommunityC := func(name string, option oc.MatchSetOptionsType) *CommunityCondition {
  1753  		matchSet := oc.MatchCommunitySet{}
  1754  		matchSet.CommunitySet = name
  1755  		matchSet.MatchSetOptions = option
  1756  		c, _ := NewCommunityCondition(matchSet)
  1757  		if v, ok := m[name]; ok {
  1758  			c.set = v.(*CommunitySet)
  1759  		}
  1760  		return c
  1761  	}
  1762  
  1763  	// ANY case
  1764  	p1 := createCommunityC("comset1", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1765  	p2 := createCommunityC("comset2", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1766  	p3 := createCommunityC("comset3", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1767  	p4 := createCommunityC("comset4", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1768  	p5 := createCommunityC("comset5", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1769  	p6 := createCommunityC("comset6", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1770  	p7 := createCommunityC("comset7", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1771  	p8 := createCommunityC("comset8", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  1772  
  1773  	// ALL case
  1774  	p9 := createCommunityC("comset9", oc.MATCH_SET_OPTIONS_TYPE_ALL)
  1775  
  1776  	// INVERT case
  1777  	p10 := createCommunityC("comset10", oc.MATCH_SET_OPTIONS_TYPE_INVERT)
  1778  
  1779  	// test
  1780  	assert.Equal(t, true, p1.Evaluate(path1, nil))
  1781  	assert.Equal(t, true, p2.Evaluate(path1, nil))
  1782  	assert.Equal(t, true, p3.Evaluate(path1, nil))
  1783  	assert.Equal(t, true, p4.Evaluate(path1, nil))
  1784  	assert.Equal(t, true, p5.Evaluate(path1, nil))
  1785  	assert.Equal(t, true, p6.Evaluate(path1, nil))
  1786  	assert.Equal(t, true, p7.Evaluate(path1, nil))
  1787  	assert.Equal(t, true, p8.Evaluate(path1, nil))
  1788  	assert.Equal(t, true, p9.Evaluate(path2, nil))
  1789  	assert.Equal(t, true, p10.Evaluate(path1, nil))
  1790  
  1791  }
  1792  
  1793  func TestCommunityCountConditionEvaluate(t *testing.T) {
  1794  	// common setup
  1795  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1796  	origin := bgp.NewPathAttributeOrigin(0)
  1797  	aspathParam := []bgp.AsPathParamInterface{
  1798  		bgp.NewAsPathParam(2, []uint16{65001, 65000, 65004, 65005}),
  1799  		bgp.NewAsPathParam(1, []uint16{65001, 65010, 65004, 65005}),
  1800  	}
  1801  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  1802  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1803  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1804  
  1805  	tests := []struct {
  1806  		desc             string
  1807  		inPath           *Path
  1808  		inCommunityCount uint32
  1809  	}{{
  1810  		desc: "no-communities",
  1811  		inPath: func() *Path {
  1812  			pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  1813  			nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1814  			updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1815  			UpdatePathAttrs4ByteAs(logger, updateMsg.Body.(*bgp.BGPUpdate))
  1816  			return ProcessMessage(updateMsg, peer, time.Now())[0]
  1817  		}(),
  1818  		inCommunityCount: 0,
  1819  	}, {
  1820  		desc: "no-communities-one-ext-community",
  1821  		inPath: func() *Path {
  1822  			eComAsSpecific := &bgp.TwoOctetAsSpecificExtended{
  1823  				SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  1824  				AS:           65001,
  1825  				LocalAdmin:   200,
  1826  				IsTransitive: true,
  1827  			}
  1828  			ec := []bgp.ExtendedCommunityInterface{eComAsSpecific}
  1829  			extCommunities := bgp.NewPathAttributeExtendedCommunities(ec)
  1830  			pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, extCommunities}
  1831  			nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1832  			updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1833  			UpdatePathAttrs4ByteAs(logger, updateMsg.Body.(*bgp.BGPUpdate))
  1834  			return ProcessMessage(updateMsg, peer, time.Now())[0]
  1835  		}(),
  1836  		inCommunityCount: 0,
  1837  	}, {
  1838  		desc: "one-community",
  1839  		inPath: func() *Path {
  1840  			communities := bgp.NewPathAttributeCommunities([]uint32{stringToCommunityValue("65001:111")})
  1841  			pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, communities}
  1842  			nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1843  			updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1844  			UpdatePathAttrs4ByteAs(logger, updateMsg.Body.(*bgp.BGPUpdate))
  1845  			return ProcessMessage(updateMsg, peer, time.Now())[0]
  1846  		}(),
  1847  		inCommunityCount: 1,
  1848  	}, {
  1849  		desc: "one-community-one-ext-community-one-large-community",
  1850  		inPath: func() *Path {
  1851  			communities := bgp.NewPathAttributeCommunities([]uint32{stringToCommunityValue("65001:111")})
  1852  			eComAsSpecific := &bgp.TwoOctetAsSpecificExtended{
  1853  				SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  1854  				AS:           65001,
  1855  				LocalAdmin:   200,
  1856  				IsTransitive: true,
  1857  			}
  1858  			ec := []bgp.ExtendedCommunityInterface{eComAsSpecific}
  1859  			extCommunities := bgp.NewPathAttributeExtendedCommunities(ec)
  1860  			largeCommunities := bgp.NewPathAttributeLargeCommunities([]*bgp.LargeCommunity{
  1861  				{ASN: 100, LocalData1: 100, LocalData2: 100},
  1862  				{ASN: 100, LocalData1: 200, LocalData2: 200},
  1863  			})
  1864  			pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, communities, extCommunities, largeCommunities}
  1865  			nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1866  			updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1867  			UpdatePathAttrs4ByteAs(logger, updateMsg.Body.(*bgp.BGPUpdate))
  1868  			return ProcessMessage(updateMsg, peer, time.Now())[0]
  1869  		}(),
  1870  		inCommunityCount: 1,
  1871  	}, {
  1872  		desc: "two-communities-one-ext-community",
  1873  		inPath: func() *Path {
  1874  			communities := bgp.NewPathAttributeCommunities([]uint32{
  1875  				stringToCommunityValue("65001:111"),
  1876  				stringToCommunityValue("65001:222"),
  1877  			})
  1878  			eComAsSpecific := &bgp.TwoOctetAsSpecificExtended{
  1879  				SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  1880  				AS:           65001,
  1881  				LocalAdmin:   200,
  1882  				IsTransitive: true,
  1883  			}
  1884  			ec := []bgp.ExtendedCommunityInterface{eComAsSpecific}
  1885  			extCommunities := bgp.NewPathAttributeExtendedCommunities(ec)
  1886  			pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, communities, extCommunities}
  1887  			nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1888  			updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1889  			UpdatePathAttrs4ByteAs(logger, updateMsg.Body.(*bgp.BGPUpdate))
  1890  			return ProcessMessage(updateMsg, peer, time.Now())[0]
  1891  		}(),
  1892  		inCommunityCount: 2,
  1893  	}, {
  1894  		desc: "ten-communities",
  1895  		inPath: func() *Path {
  1896  			communities := bgp.NewPathAttributeCommunities([]uint32{
  1897  				stringToCommunityValue("65001:111"),
  1898  				stringToCommunityValue("65001:222"),
  1899  				stringToCommunityValue("65001:333"),
  1900  				stringToCommunityValue("65001:444"),
  1901  				stringToCommunityValue("65001:555"),
  1902  				0x00000000,
  1903  				0xFFFFFF01,
  1904  				0xFFFFFF02,
  1905  				0xFFFFFF03,
  1906  				0xFFFFFF04,
  1907  			})
  1908  			eComAsSpecific := &bgp.TwoOctetAsSpecificExtended{
  1909  				SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  1910  				AS:           65001,
  1911  				LocalAdmin:   200,
  1912  				IsTransitive: true,
  1913  			}
  1914  			ec := []bgp.ExtendedCommunityInterface{eComAsSpecific}
  1915  			extCommunities := bgp.NewPathAttributeExtendedCommunities(ec)
  1916  			largeCommunities := bgp.NewPathAttributeLargeCommunities([]*bgp.LargeCommunity{
  1917  				{ASN: 100, LocalData1: 100, LocalData2: 100},
  1918  				{ASN: 100, LocalData1: 200, LocalData2: 200},
  1919  			})
  1920  			pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, communities, extCommunities, largeCommunities}
  1921  			nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  1922  			updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  1923  			UpdatePathAttrs4ByteAs(logger, updateMsg.Body.(*bgp.BGPUpdate))
  1924  			return ProcessMessage(updateMsg, peer, time.Now())[0]
  1925  		}(),
  1926  		inCommunityCount: 10,
  1927  	}}
  1928  	for _, tt := range tests {
  1929  		t.Run(tt.desc, func(t *testing.T) {
  1930  			tests := []struct {
  1931  				desc              string
  1932  				inComparisonCount uint32
  1933  			}{{
  1934  				desc:              "zero",
  1935  				inComparisonCount: 0,
  1936  			}, {
  1937  				desc:              "two",
  1938  				inComparisonCount: 2,
  1939  			}}
  1940  			for _, ttt := range tests {
  1941  				t.Run(ttt.desc, func(t *testing.T) {
  1942  					tests := []struct {
  1943  						desc        string
  1944  						inCondition oc.CommunityCount
  1945  						inWant      bool
  1946  					}{{
  1947  						desc: "equal",
  1948  						inCondition: oc.CommunityCount{
  1949  							Operator: oc.ATTRIBUTE_COMPARISON_ATTRIBUTE_EQ,
  1950  							Value:    tt.inCommunityCount,
  1951  						},
  1952  						inWant: tt.inCommunityCount == ttt.inComparisonCount,
  1953  					}, {
  1954  						desc: "greater-or-equal",
  1955  						inCondition: oc.CommunityCount{
  1956  							Operator: oc.ATTRIBUTE_COMPARISON_ATTRIBUTE_GE,
  1957  							Value:    tt.inCommunityCount,
  1958  						},
  1959  						inWant: tt.inCommunityCount >= ttt.inComparisonCount,
  1960  					}, {
  1961  						desc: "less-or-equal",
  1962  						inCondition: oc.CommunityCount{
  1963  							Operator: oc.ATTRIBUTE_COMPARISON_ATTRIBUTE_LE,
  1964  							Value:    tt.inCommunityCount,
  1965  						},
  1966  						inWant: tt.inCommunityCount <= ttt.inComparisonCount,
  1967  					}}
  1968  					for _, tttt := range tests {
  1969  						t.Run(fmt.Sprintf("%s-%v", tttt.desc, tttt.inWant), func(t *testing.T) {
  1970  							p, err := NewCommunityCountCondition(tttt.inCondition)
  1971  							if err != nil {
  1972  								t.Fatalf("error while creating CommunityCountCondition: %v", err)
  1973  							}
  1974  							want := true
  1975  							if got := p.Evaluate(tt.inPath, nil); got != want {
  1976  								t.Errorf("Evaluate CommunityCount (%v %v %v): got: %v, want: %v", tt.inCommunityCount, tttt.inCondition.Operator, tttt.inCondition.Value, want, got)
  1977  							}
  1978  						})
  1979  					}
  1980  				})
  1981  			}
  1982  		})
  1983  	}
  1984  }
  1985  
  1986  func TestCommunityConditionEvaluateWithOtherCondition(t *testing.T) {
  1987  
  1988  	// setup
  1989  	// create path
  1990  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  1991  	origin := bgp.NewPathAttributeOrigin(0)
  1992  	aspathParam := []bgp.AsPathParamInterface{
  1993  		bgp.NewAsPathParam(1, []uint16{65001, 65000, 65004, 65005}),
  1994  		bgp.NewAsPathParam(2, []uint16{65001, 65000, 65004, 65004, 65005}),
  1995  	}
  1996  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  1997  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  1998  	med := bgp.NewPathAttributeMultiExitDisc(0)
  1999  	communities := bgp.NewPathAttributeCommunities([]uint32{
  2000  		stringToCommunityValue("65001:100"),
  2001  		stringToCommunityValue("65001:200"),
  2002  		stringToCommunityValue("65001:300"),
  2003  		stringToCommunityValue("65001:400"),
  2004  		0x00000000,
  2005  		0xFFFFFF01,
  2006  		0xFFFFFF02,
  2007  		0xFFFFFF03})
  2008  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, communities}
  2009  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2010  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2011  	UpdatePathAttrs4ByteAs(logger, updateMsg.Body.(*bgp.BGPUpdate))
  2012  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2013  
  2014  	// create policy
  2015  	asPathSet := oc.AsPathSet{
  2016  		AsPathSetName: "asset1",
  2017  		AsPathList:    []string{"65005$"},
  2018  	}
  2019  
  2020  	comSet1 := oc.CommunitySet{
  2021  		CommunitySetName: "comset1",
  2022  		CommunityList:    []string{"65001:100", "65001:200", "65001:300"},
  2023  	}
  2024  
  2025  	comSet2 := oc.CommunitySet{
  2026  		CommunitySetName: "comset2",
  2027  		CommunityList:    []string{"65050:\\d+"},
  2028  	}
  2029  
  2030  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2031  	ns := createNeighborSet("ns1", "10.0.0.1")
  2032  
  2033  	ds := oc.DefinedSets{}
  2034  	ds.PrefixSets = []oc.PrefixSet{ps}
  2035  	ds.NeighborSets = []oc.NeighborSet{ns}
  2036  	ds.BgpDefinedSets.AsPathSets = []oc.AsPathSet{asPathSet}
  2037  	ds.BgpDefinedSets.CommunitySets = []oc.CommunitySet{comSet1, comSet2}
  2038  
  2039  	s1 := createStatement("statement1", "ps1", "ns1", false)
  2040  	s1.Conditions.BgpConditions.MatchAsPathSet.AsPathSet = "asset1"
  2041  	s1.Conditions.BgpConditions.MatchCommunitySet.CommunitySet = "comset1"
  2042  	s1.Conditions.BgpConditions.CommunityCount.Operator = oc.ATTRIBUTE_COMPARISON_EQ
  2043  	s1.Conditions.BgpConditions.CommunityCount.Value = 8
  2044  
  2045  	s2 := createStatement("statement2", "ps1", "ns1", false)
  2046  	s2.Conditions.BgpConditions.MatchAsPathSet.AsPathSet = "asset1"
  2047  	s2.Conditions.BgpConditions.MatchCommunitySet.CommunitySet = "comset1"
  2048  	s2.Conditions.BgpConditions.CommunityCount.Operator = oc.ATTRIBUTE_COMPARISON_ATTRIBUTE_GE
  2049  	s2.Conditions.BgpConditions.CommunityCount.Value = 9
  2050  
  2051  	s3 := createStatement("statement3", "ps1", "ns1", false)
  2052  	s3.Conditions.BgpConditions.MatchAsPathSet.AsPathSet = "asset1"
  2053  	s3.Conditions.BgpConditions.MatchCommunitySet.CommunitySet = "comset2"
  2054  
  2055  	pd1 := createPolicyDefinition("pd1", s1)
  2056  	pd2 := createPolicyDefinition("pd2", s2)
  2057  	pd3 := createPolicyDefinition("pd3", s3)
  2058  	pl := createRoutingPolicy(ds, pd1, pd2, pd3)
  2059  
  2060  	//test
  2061  	r := NewRoutingPolicy(logger)
  2062  	err := r.reload(pl)
  2063  	assert.Nil(t, err)
  2064  	p := r.policyMap["pd1"]
  2065  	pType, newPath := p.Apply(logger, path, nil)
  2066  	assert.Equal(t, ROUTE_TYPE_REJECT, pType)
  2067  	assert.Equal(t, newPath, path)
  2068  
  2069  	p = r.policyMap["pd2"]
  2070  	pType, newPath = p.Apply(logger, path, nil)
  2071  	assert.Equal(t, ROUTE_TYPE_NONE, pType)
  2072  	assert.Equal(t, newPath, path)
  2073  
  2074  	p = r.policyMap["pd3"]
  2075  	pType, newPath = p.Apply(logger, path, nil)
  2076  	assert.Equal(t, ROUTE_TYPE_NONE, pType)
  2077  	assert.Equal(t, newPath, path)
  2078  
  2079  }
  2080  
  2081  func TestPolicyMatchAndAddCommunities(t *testing.T) {
  2082  
  2083  	// create path
  2084  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2085  	origin := bgp.NewPathAttributeOrigin(0)
  2086  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  2087  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2088  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2089  	med := bgp.NewPathAttributeMultiExitDisc(0)
  2090  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  2091  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2092  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2093  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2094  	// create policy
  2095  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2096  	ns := createNeighborSet("ns1", "10.0.0.1")
  2097  
  2098  	ds := oc.DefinedSets{}
  2099  	ds.PrefixSets = []oc.PrefixSet{ps}
  2100  	ds.NeighborSets = []oc.NeighborSet{ns}
  2101  
  2102  	community := "65000:100"
  2103  
  2104  	s := createStatement("statement1", "ps1", "ns1", true)
  2105  	s.Actions.BgpActions.SetCommunity = createSetCommunity("ADD", community)
  2106  
  2107  	pd := createPolicyDefinition("pd1", s)
  2108  	pl := createRoutingPolicy(ds, pd)
  2109  
  2110  	//test
  2111  	r := NewRoutingPolicy(logger)
  2112  	err := r.reload(pl)
  2113  	assert.Nil(t, err)
  2114  	p := r.policyMap["pd1"]
  2115  
  2116  	pType, newPath := p.Apply(logger, path, nil)
  2117  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  2118  	assert.NotEqual(t, nil, newPath)
  2119  	assert.Equal(t, []uint32{stringToCommunityValue(community)}, newPath.GetCommunities())
  2120  }
  2121  
  2122  func TestPolicyMatchAndReplaceCommunities(t *testing.T) {
  2123  
  2124  	// create path
  2125  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2126  	origin := bgp.NewPathAttributeOrigin(0)
  2127  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  2128  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2129  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2130  	med := bgp.NewPathAttributeMultiExitDisc(0)
  2131  	communities := bgp.NewPathAttributeCommunities([]uint32{
  2132  		stringToCommunityValue("65001:200"),
  2133  	})
  2134  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, communities}
  2135  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2136  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2137  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2138  	// create policy
  2139  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2140  	ns := createNeighborSet("ns1", "10.0.0.1")
  2141  
  2142  	ds := oc.DefinedSets{}
  2143  	ds.PrefixSets = []oc.PrefixSet{ps}
  2144  	ds.NeighborSets = []oc.NeighborSet{ns}
  2145  
  2146  	community := "65000:100"
  2147  
  2148  	s := createStatement("statement1", "ps1", "ns1", true)
  2149  	s.Actions.BgpActions.SetCommunity = createSetCommunity("REPLACE", community)
  2150  
  2151  	pd := createPolicyDefinition("pd1", s)
  2152  	pl := createRoutingPolicy(ds, pd)
  2153  
  2154  	//test
  2155  	r := NewRoutingPolicy(logger)
  2156  	err := r.reload(pl)
  2157  	assert.Nil(t, err)
  2158  	p := r.policyMap["pd1"]
  2159  
  2160  	pType, newPath := p.Apply(logger, path, nil)
  2161  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  2162  	assert.NotEqual(t, nil, newPath)
  2163  	assert.Equal(t, []uint32{stringToCommunityValue(community)}, newPath.GetCommunities())
  2164  }
  2165  
  2166  func TestPolicyMatchAndRemoveCommunities(t *testing.T) {
  2167  
  2168  	// create path
  2169  	community1 := "65000:100"
  2170  	community2 := "65000:200"
  2171  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2172  	origin := bgp.NewPathAttributeOrigin(0)
  2173  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  2174  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2175  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2176  	med := bgp.NewPathAttributeMultiExitDisc(0)
  2177  	communities := bgp.NewPathAttributeCommunities([]uint32{
  2178  		stringToCommunityValue(community1),
  2179  		stringToCommunityValue(community2),
  2180  	})
  2181  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, communities}
  2182  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2183  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2184  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2185  	// create policy
  2186  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2187  	ns := createNeighborSet("ns1", "10.0.0.1")
  2188  
  2189  	ds := oc.DefinedSets{}
  2190  	ds.PrefixSets = []oc.PrefixSet{ps}
  2191  	ds.NeighborSets = []oc.NeighborSet{ns}
  2192  
  2193  	s := createStatement("statement1", "ps1", "ns1", true)
  2194  	s.Actions.BgpActions.SetCommunity = createSetCommunity("REMOVE", community1)
  2195  
  2196  	pd := createPolicyDefinition("pd1", s)
  2197  	pl := createRoutingPolicy(ds, pd)
  2198  
  2199  	//test
  2200  	r := NewRoutingPolicy(logger)
  2201  	err := r.reload(pl)
  2202  	assert.Nil(t, err)
  2203  	p := r.policyMap["pd1"]
  2204  	pType, newPath := p.Apply(logger, path, nil)
  2205  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  2206  	assert.NotEqual(t, nil, newPath)
  2207  	assert.Equal(t, []uint32{stringToCommunityValue(community2)}, newPath.GetCommunities())
  2208  }
  2209  
  2210  func TestPolicyMatchAndRemoveCommunitiesRegexp(t *testing.T) {
  2211  
  2212  	// create path
  2213  	community1 := "65000:100"
  2214  	community2 := "65000:200"
  2215  	community3 := "65100:100"
  2216  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2217  	origin := bgp.NewPathAttributeOrigin(0)
  2218  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  2219  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2220  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2221  	med := bgp.NewPathAttributeMultiExitDisc(0)
  2222  	communities := bgp.NewPathAttributeCommunities([]uint32{
  2223  		stringToCommunityValue(community1),
  2224  		stringToCommunityValue(community2),
  2225  		stringToCommunityValue(community3),
  2226  	})
  2227  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, communities}
  2228  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2229  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2230  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2231  	// create policy
  2232  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2233  	ns := createNeighborSet("ns1", "10.0.0.1")
  2234  
  2235  	ds := oc.DefinedSets{}
  2236  	ds.PrefixSets = []oc.PrefixSet{ps}
  2237  	ds.NeighborSets = []oc.NeighborSet{ns}
  2238  
  2239  	s := createStatement("statement1", "ps1", "ns1", true)
  2240  	s.Actions.BgpActions.SetCommunity = createSetCommunity("REMOVE", ".*:100")
  2241  
  2242  	pd := createPolicyDefinition("pd1", s)
  2243  	pl := createRoutingPolicy(ds, pd)
  2244  
  2245  	//test
  2246  	r := NewRoutingPolicy(logger)
  2247  	err := r.reload(pl)
  2248  	assert.Nil(t, err)
  2249  	p := r.policyMap["pd1"]
  2250  	pType, newPath := p.Apply(logger, path, nil)
  2251  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  2252  	assert.NotEqual(t, nil, newPath)
  2253  	assert.Equal(t, []uint32{stringToCommunityValue(community2)}, newPath.GetCommunities())
  2254  }
  2255  
  2256  func TestPolicyMatchAndRemoveCommunitiesRegexp2(t *testing.T) {
  2257  
  2258  	// create path
  2259  	community1 := "0:1"
  2260  	community2 := "10:1"
  2261  	community3 := "45686:2"
  2262  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2263  	origin := bgp.NewPathAttributeOrigin(0)
  2264  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  2265  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2266  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2267  	med := bgp.NewPathAttributeMultiExitDisc(0)
  2268  	communities := bgp.NewPathAttributeCommunities([]uint32{
  2269  		stringToCommunityValue(community1),
  2270  		stringToCommunityValue(community2),
  2271  		stringToCommunityValue(community3),
  2272  	})
  2273  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, communities}
  2274  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2275  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2276  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2277  	// create policy
  2278  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2279  	ns := createNeighborSet("ns1", "10.0.0.1")
  2280  
  2281  	ds := oc.DefinedSets{}
  2282  	ds.PrefixSets = []oc.PrefixSet{ps}
  2283  	ds.NeighborSets = []oc.NeighborSet{ns}
  2284  
  2285  	s := createStatement("statement1", "ps1", "ns1", true)
  2286  	s.Actions.BgpActions.SetCommunity = createSetCommunity("REMOVE", "^(0|45686):[0-9]+")
  2287  
  2288  	pd := createPolicyDefinition("pd1", s)
  2289  	pl := createRoutingPolicy(ds, pd)
  2290  
  2291  	//test
  2292  	r := NewRoutingPolicy(logger)
  2293  	err := r.reload(pl)
  2294  	assert.Nil(t, err)
  2295  	p := r.policyMap["pd1"]
  2296  	pType, newPath := p.Apply(logger, path, nil)
  2297  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  2298  	assert.NotEqual(t, nil, newPath)
  2299  	assert.Equal(t, []uint32{stringToCommunityValue(community2)}, newPath.GetCommunities())
  2300  }
  2301  
  2302  func TestPolicyMatchAndClearCommunities(t *testing.T) {
  2303  
  2304  	// create path
  2305  	community1 := "65000:100"
  2306  	community2 := "65000:200"
  2307  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2308  	origin := bgp.NewPathAttributeOrigin(0)
  2309  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  2310  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2311  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2312  	med := bgp.NewPathAttributeMultiExitDisc(0)
  2313  	communities := bgp.NewPathAttributeCommunities([]uint32{
  2314  		stringToCommunityValue(community1),
  2315  		stringToCommunityValue(community2),
  2316  	})
  2317  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, communities}
  2318  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2319  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2320  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2321  	// create policy
  2322  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2323  	ns := createNeighborSet("ns1", "10.0.0.1")
  2324  
  2325  	ds := oc.DefinedSets{}
  2326  	ds.PrefixSets = []oc.PrefixSet{ps}
  2327  	ds.NeighborSets = []oc.NeighborSet{ns}
  2328  
  2329  	s := createStatement("statement1", "ps1", "ns1", true)
  2330  	// action NULL is obsolate
  2331  	s.Actions.BgpActions.SetCommunity.Options = "REPLACE"
  2332  	s.Actions.BgpActions.SetCommunity.SetCommunityMethod.CommunitiesList = nil
  2333  
  2334  	pd := createPolicyDefinition("pd1", s)
  2335  	pl := createRoutingPolicy(ds, pd)
  2336  
  2337  	//test
  2338  	r := NewRoutingPolicy(logger)
  2339  	err := r.reload(pl)
  2340  	assert.Nil(t, err)
  2341  	p := r.policyMap["pd1"]
  2342  
  2343  	pType, newPath := p.Apply(logger, path, nil)
  2344  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  2345  	assert.NotEqual(t, nil, newPath)
  2346  	//assert.Equal(t, []uint32{}, newPath.GetCommunities())
  2347  }
  2348  
  2349  func TestExtCommunityConditionEvaluate(t *testing.T) {
  2350  
  2351  	// setup
  2352  	// create path
  2353  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2354  	origin := bgp.NewPathAttributeOrigin(0)
  2355  	aspathParam1 := []bgp.AsPathParamInterface{
  2356  		bgp.NewAsPathParam(2, []uint16{65001, 65000, 65004, 65005}),
  2357  		bgp.NewAsPathParam(1, []uint16{65001, 65010, 65004, 65005}),
  2358  	}
  2359  	aspath := bgp.NewPathAttributeAsPath(aspathParam1)
  2360  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2361  	med := bgp.NewPathAttributeMultiExitDisc(0)
  2362  	eComAsSpecific1 := &bgp.TwoOctetAsSpecificExtended{
  2363  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2364  		AS:           65001,
  2365  		LocalAdmin:   200,
  2366  		IsTransitive: true,
  2367  	}
  2368  	eComIpPrefix1 := &bgp.IPv4AddressSpecificExtended{
  2369  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2370  		IPv4:         net.ParseIP("10.0.0.1"),
  2371  		LocalAdmin:   300,
  2372  		IsTransitive: true,
  2373  	}
  2374  	eComAs4Specific1 := &bgp.FourOctetAsSpecificExtended{
  2375  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2376  		AS:           65030000,
  2377  		LocalAdmin:   200,
  2378  		IsTransitive: true,
  2379  	}
  2380  	eComAsSpecific2 := &bgp.TwoOctetAsSpecificExtended{
  2381  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2382  		AS:           65002,
  2383  		LocalAdmin:   200,
  2384  		IsTransitive: false,
  2385  	}
  2386  	eComIpPrefix2 := &bgp.IPv4AddressSpecificExtended{
  2387  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2388  		IPv4:         net.ParseIP("10.0.0.2"),
  2389  		LocalAdmin:   300,
  2390  		IsTransitive: false,
  2391  	}
  2392  	eComAs4Specific2 := &bgp.FourOctetAsSpecificExtended{
  2393  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2394  		AS:           65030001,
  2395  		LocalAdmin:   200,
  2396  		IsTransitive: false,
  2397  	}
  2398  	eComAsSpecific3 := &bgp.TwoOctetAsSpecificExtended{
  2399  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_ORIGIN),
  2400  		AS:           65010,
  2401  		LocalAdmin:   300,
  2402  		IsTransitive: true,
  2403  	}
  2404  	eComIpPrefix3 := &bgp.IPv4AddressSpecificExtended{
  2405  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_ORIGIN),
  2406  		IPv4:         net.ParseIP("10.0.10.10"),
  2407  		LocalAdmin:   400,
  2408  		IsTransitive: true,
  2409  	}
  2410  	eComAs4Specific3 := &bgp.FourOctetAsSpecificExtended{
  2411  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2412  		AS:           65030002,
  2413  		LocalAdmin:   500,
  2414  		IsTransitive: true,
  2415  	}
  2416  	ec := []bgp.ExtendedCommunityInterface{eComAsSpecific1, eComIpPrefix1, eComAs4Specific1, eComAsSpecific2,
  2417  		eComIpPrefix2, eComAs4Specific2, eComAsSpecific3, eComIpPrefix3, eComAs4Specific3}
  2418  	extCommunities := bgp.NewPathAttributeExtendedCommunities(ec)
  2419  
  2420  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, extCommunities}
  2421  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2422  	updateMsg1 := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2423  	UpdatePathAttrs4ByteAs(logger, updateMsg1.Body.(*bgp.BGPUpdate))
  2424  	path1 := ProcessMessage(updateMsg1, peer, time.Now())[0]
  2425  
  2426  	convUintStr := func(as uint32) string {
  2427  		upper := strconv.FormatUint(uint64(as&0xFFFF0000>>16), 10)
  2428  		lower := strconv.FormatUint(uint64(as&0x0000FFFF), 10)
  2429  		str := fmt.Sprintf("%s.%s", upper, lower)
  2430  		return str
  2431  	}
  2432  
  2433  	// create match condition
  2434  	ecomSet1 := oc.ExtCommunitySet{
  2435  		ExtCommunitySetName: "ecomSet1",
  2436  		ExtCommunityList:    []string{"RT:65001:200"},
  2437  	}
  2438  	ecomSet2 := oc.ExtCommunitySet{
  2439  		ExtCommunitySetName: "ecomSet2",
  2440  		ExtCommunityList:    []string{"RT:10.0.0.1:300"},
  2441  	}
  2442  	ecomSet3 := oc.ExtCommunitySet{
  2443  		ExtCommunitySetName: "ecomSet3",
  2444  		ExtCommunityList:    []string{fmt.Sprintf("RT:%s:200", convUintStr(65030000))},
  2445  	}
  2446  	ecomSet4 := oc.ExtCommunitySet{
  2447  		ExtCommunitySetName: "ecomSet4",
  2448  		ExtCommunityList:    []string{"RT:65002:200"},
  2449  	}
  2450  	ecomSet5 := oc.ExtCommunitySet{
  2451  		ExtCommunitySetName: "ecomSet5",
  2452  		ExtCommunityList:    []string{"RT:10.0.0.2:300"},
  2453  	}
  2454  	ecomSet6 := oc.ExtCommunitySet{
  2455  		ExtCommunitySetName: "ecomSet6",
  2456  		ExtCommunityList:    []string{fmt.Sprintf("RT:%s:200", convUintStr(65030001))},
  2457  	}
  2458  	ecomSet7 := oc.ExtCommunitySet{
  2459  		ExtCommunitySetName: "ecomSet7",
  2460  		ExtCommunityList:    []string{"SoO:65010:300"},
  2461  	}
  2462  	ecomSet8 := oc.ExtCommunitySet{
  2463  		ExtCommunitySetName: "ecomSet8",
  2464  		ExtCommunityList:    []string{"SoO:10.0.10.10:[0-9]+"},
  2465  	}
  2466  	ecomSet9 := oc.ExtCommunitySet{
  2467  		ExtCommunitySetName: "ecomSet9",
  2468  		ExtCommunityList:    []string{"RT:[0-9]+:[0-9]+"},
  2469  	}
  2470  	ecomSet10 := oc.ExtCommunitySet{
  2471  		ExtCommunitySetName: "ecomSet10",
  2472  		ExtCommunityList:    []string{"RT:.+:\\d00", "SoO:.+:\\d00"},
  2473  	}
  2474  	ecomSet11 := oc.ExtCommunitySet{
  2475  		ExtCommunitySetName: "ecomSet11",
  2476  		ExtCommunityList:    []string{"RT:65001:2", "SoO:11.0.10.10:[0-9]+"},
  2477  	}
  2478  	ecomSet12 := oc.ExtCommunitySet{
  2479  		ExtCommunitySetName: "ecomSet12",
  2480  		ExtCommunityList:    []string{"LB:65001:125000"},
  2481  	}
  2482  
  2483  	m := make(map[string]DefinedSet)
  2484  	for _, c := range []oc.ExtCommunitySet{ecomSet1, ecomSet2, ecomSet3, ecomSet4, ecomSet5, ecomSet6, ecomSet7,
  2485  		ecomSet8, ecomSet9, ecomSet10, ecomSet11, ecomSet12} {
  2486  		s, _ := NewExtCommunitySet(c)
  2487  		m[s.Name()] = s
  2488  	}
  2489  
  2490  	createExtCommunityC := func(name string, option oc.MatchSetOptionsType) *ExtCommunityCondition {
  2491  		matchSet := oc.MatchExtCommunitySet{}
  2492  		matchSet.ExtCommunitySet = name
  2493  		matchSet.MatchSetOptions = option
  2494  		c, _ := NewExtCommunityCondition(matchSet)
  2495  		if v, ok := m[name]; ok {
  2496  			c.set = v.(*ExtCommunitySet)
  2497  		}
  2498  
  2499  		return c
  2500  	}
  2501  
  2502  	p1 := createExtCommunityC("ecomSet1", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  2503  	p2 := createExtCommunityC("ecomSet2", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  2504  	p3 := createExtCommunityC("ecomSet3", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  2505  	p4 := createExtCommunityC("ecomSet4", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  2506  	p5 := createExtCommunityC("ecomSet5", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  2507  	p6 := createExtCommunityC("ecomSet6", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  2508  	p7 := createExtCommunityC("ecomSet7", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  2509  	p8 := createExtCommunityC("ecomSet8", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  2510  	p9 := createExtCommunityC("ecomSet9", oc.MATCH_SET_OPTIONS_TYPE_ANY)
  2511  
  2512  	// ALL case
  2513  	p10 := createExtCommunityC("ecomSet10", oc.MATCH_SET_OPTIONS_TYPE_ALL)
  2514  
  2515  	// INVERT case
  2516  	p11 := createExtCommunityC("ecomSet11", oc.MATCH_SET_OPTIONS_TYPE_INVERT)
  2517  
  2518  	// test
  2519  	assert.Equal(t, true, p1.Evaluate(path1, nil))
  2520  	assert.Equal(t, true, p2.Evaluate(path1, nil))
  2521  	assert.Equal(t, true, p3.Evaluate(path1, nil))
  2522  	assert.Equal(t, false, p4.Evaluate(path1, nil))
  2523  	assert.Equal(t, false, p5.Evaluate(path1, nil))
  2524  	assert.Equal(t, false, p6.Evaluate(path1, nil))
  2525  	assert.Equal(t, true, p7.Evaluate(path1, nil))
  2526  	assert.Equal(t, true, p8.Evaluate(path1, nil))
  2527  	assert.Equal(t, true, p9.Evaluate(path1, nil))
  2528  	assert.Equal(t, true, p10.Evaluate(path1, nil))
  2529  	assert.Equal(t, true, p11.Evaluate(path1, nil))
  2530  
  2531  }
  2532  
  2533  func TestExtCommunityConditionEvaluateWithOtherCondition(t *testing.T) {
  2534  
  2535  	// setup
  2536  	// create path
  2537  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.2.1.1")}
  2538  	origin := bgp.NewPathAttributeOrigin(0)
  2539  	aspathParam := []bgp.AsPathParamInterface{
  2540  		bgp.NewAsPathParam(1, []uint16{65001, 65000, 65004, 65005}),
  2541  		bgp.NewAsPathParam(2, []uint16{65001, 65000, 65004, 65004, 65005}),
  2542  	}
  2543  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2544  	nexthop := bgp.NewPathAttributeNextHop("10.2.1.1")
  2545  	med := bgp.NewPathAttributeMultiExitDisc(0)
  2546  	eComAsSpecific1 := &bgp.TwoOctetAsSpecificExtended{
  2547  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2548  		AS:           65001,
  2549  		LocalAdmin:   200,
  2550  		IsTransitive: true,
  2551  	}
  2552  	eComIpPrefix1 := &bgp.IPv4AddressSpecificExtended{
  2553  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2554  		IPv4:         net.ParseIP("10.0.0.1"),
  2555  		LocalAdmin:   300,
  2556  		IsTransitive: true,
  2557  	}
  2558  	eComAs4Specific1 := &bgp.FourOctetAsSpecificExtended{
  2559  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2560  		AS:           65030000,
  2561  		LocalAdmin:   200,
  2562  		IsTransitive: true,
  2563  	}
  2564  	eComAsSpecific2 := &bgp.TwoOctetAsSpecificExtended{
  2565  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2566  		AS:           65002,
  2567  		LocalAdmin:   200,
  2568  		IsTransitive: false,
  2569  	}
  2570  	eComIpPrefix2 := &bgp.IPv4AddressSpecificExtended{
  2571  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2572  		IPv4:         net.ParseIP("10.0.0.2"),
  2573  		LocalAdmin:   300,
  2574  		IsTransitive: false,
  2575  	}
  2576  	eComAs4Specific2 := &bgp.FourOctetAsSpecificExtended{
  2577  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2578  		AS:           65030001,
  2579  		LocalAdmin:   200,
  2580  		IsTransitive: false,
  2581  	}
  2582  	eComAsSpecific3 := &bgp.TwoOctetAsSpecificExtended{
  2583  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_ORIGIN),
  2584  		AS:           65010,
  2585  		LocalAdmin:   300,
  2586  		IsTransitive: true,
  2587  	}
  2588  	eComIpPrefix3 := &bgp.IPv4AddressSpecificExtended{
  2589  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_ORIGIN),
  2590  		IPv4:         net.ParseIP("10.0.10.10"),
  2591  		LocalAdmin:   400,
  2592  		IsTransitive: true,
  2593  	}
  2594  	eComAs4Specific3 := &bgp.FourOctetAsSpecificExtended{
  2595  		SubType:      bgp.ExtendedCommunityAttrSubType(bgp.EC_SUBTYPE_ROUTE_TARGET),
  2596  		AS:           65030002,
  2597  		LocalAdmin:   500,
  2598  		IsTransitive: true,
  2599  	}
  2600  	ec := []bgp.ExtendedCommunityInterface{eComAsSpecific1, eComIpPrefix1, eComAs4Specific1, eComAsSpecific2,
  2601  		eComIpPrefix2, eComAs4Specific2, eComAsSpecific3, eComIpPrefix3, eComAs4Specific3}
  2602  	extCommunities := bgp.NewPathAttributeExtendedCommunities(ec)
  2603  
  2604  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, extCommunities}
  2605  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2606  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2607  	UpdatePathAttrs4ByteAs(logger, updateMsg.Body.(*bgp.BGPUpdate))
  2608  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2609  
  2610  	// create policy
  2611  	asPathSet := oc.AsPathSet{
  2612  		AsPathSetName: "asset1",
  2613  		AsPathList:    []string{"65005$"},
  2614  	}
  2615  
  2616  	ecomSet1 := oc.ExtCommunitySet{
  2617  		ExtCommunitySetName: "ecomSet1",
  2618  		ExtCommunityList:    []string{"RT:65001:201"},
  2619  	}
  2620  	ecomSet2 := oc.ExtCommunitySet{
  2621  		ExtCommunitySetName: "ecomSet2",
  2622  		ExtCommunityList:    []string{"RT:[0-9]+:[0-9]+"},
  2623  	}
  2624  
  2625  	ps := createPrefixSet("ps1", "10.10.1.0/16", "21..24")
  2626  	ns := createNeighborSet("ns1", "10.2.1.1")
  2627  
  2628  	ds := oc.DefinedSets{}
  2629  	ds.PrefixSets = []oc.PrefixSet{ps}
  2630  	ds.NeighborSets = []oc.NeighborSet{ns}
  2631  	ds.BgpDefinedSets.AsPathSets = []oc.AsPathSet{asPathSet}
  2632  	ds.BgpDefinedSets.ExtCommunitySets = []oc.ExtCommunitySet{ecomSet1, ecomSet2}
  2633  
  2634  	s1 := createStatement("statement1", "ps1", "ns1", false)
  2635  	s1.Conditions.BgpConditions.MatchAsPathSet.AsPathSet = "asset1"
  2636  	s1.Conditions.BgpConditions.MatchExtCommunitySet.ExtCommunitySet = "ecomSet1"
  2637  
  2638  	s2 := createStatement("statement2", "ps1", "ns1", false)
  2639  	s2.Conditions.BgpConditions.MatchAsPathSet.AsPathSet = "asset1"
  2640  	s2.Conditions.BgpConditions.MatchExtCommunitySet.ExtCommunitySet = "ecomSet2"
  2641  
  2642  	pd1 := createPolicyDefinition("pd1", s1)
  2643  	pd2 := createPolicyDefinition("pd2", s2)
  2644  	pl := createRoutingPolicy(ds, pd1, pd2)
  2645  	//test
  2646  	r := NewRoutingPolicy(logger)
  2647  	err := r.reload(pl)
  2648  	assert.Nil(t, err)
  2649  	p := r.policyMap["pd1"]
  2650  	pType, newPath := p.Apply(logger, path, nil)
  2651  	assert.Equal(t, ROUTE_TYPE_NONE, pType)
  2652  	assert.Equal(t, newPath, path)
  2653  
  2654  	p = r.policyMap["pd2"]
  2655  	pType, newPath = p.Apply(logger, path, nil)
  2656  	assert.Equal(t, ROUTE_TYPE_REJECT, pType)
  2657  	assert.Equal(t, newPath, path)
  2658  
  2659  }
  2660  
  2661  func TestPolicyMatchAndReplaceMed(t *testing.T) {
  2662  
  2663  	// create path
  2664  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2665  	origin := bgp.NewPathAttributeOrigin(0)
  2666  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  2667  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2668  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2669  	med := bgp.NewPathAttributeMultiExitDisc(100)
  2670  
  2671  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  2672  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2673  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2674  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2675  	// create policy
  2676  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2677  	ns := createNeighborSet("ns1", "10.0.0.1")
  2678  
  2679  	ds := oc.DefinedSets{}
  2680  	ds.PrefixSets = []oc.PrefixSet{ps}
  2681  	ds.NeighborSets = []oc.NeighborSet{ns}
  2682  
  2683  	m := "200"
  2684  	s := createStatement("statement1", "ps1", "ns1", true)
  2685  	s.Actions.BgpActions.SetMed = oc.BgpSetMedType(m)
  2686  
  2687  	pd := createPolicyDefinition("pd1", s)
  2688  	pl := createRoutingPolicy(ds, pd)
  2689  
  2690  	//test
  2691  	r := NewRoutingPolicy(logger)
  2692  	err := r.reload(pl)
  2693  	assert.Nil(t, err)
  2694  	p := r.policyMap["pd1"]
  2695  
  2696  	pType, newPath := p.Apply(logger, path, nil)
  2697  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  2698  	assert.NotEqual(t, nil, newPath)
  2699  	v, err := newPath.GetMed()
  2700  	assert.Nil(t, err)
  2701  	newMed := fmt.Sprintf("%d", v)
  2702  	assert.Equal(t, m, newMed)
  2703  }
  2704  
  2705  func TestPolicyMatchAndAddingMed(t *testing.T) {
  2706  
  2707  	// create path
  2708  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2709  	origin := bgp.NewPathAttributeOrigin(0)
  2710  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  2711  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2712  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2713  	med := bgp.NewPathAttributeMultiExitDisc(100)
  2714  
  2715  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  2716  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2717  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2718  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2719  	// create policy
  2720  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2721  	ns := createNeighborSet("ns1", "10.0.0.1")
  2722  
  2723  	ds := oc.DefinedSets{}
  2724  	ds.PrefixSets = []oc.PrefixSet{ps}
  2725  	ds.NeighborSets = []oc.NeighborSet{ns}
  2726  
  2727  	m := "+200"
  2728  	ma := "300"
  2729  	s := createStatement("statement1", "ps1", "ns1", true)
  2730  	s.Actions.BgpActions.SetMed = oc.BgpSetMedType(m)
  2731  
  2732  	pd := createPolicyDefinition("pd1", s)
  2733  	pl := createRoutingPolicy(ds, pd)
  2734  	//test
  2735  	r := NewRoutingPolicy(logger)
  2736  	err := r.reload(pl)
  2737  	assert.Nil(t, err)
  2738  	p := r.policyMap["pd1"]
  2739  	pType, newPath := p.Apply(logger, path, nil)
  2740  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  2741  	assert.NotEqual(t, nil, newPath)
  2742  
  2743  	v, err := newPath.GetMed()
  2744  	assert.Nil(t, err)
  2745  	newMed := fmt.Sprintf("%d", v)
  2746  	assert.Equal(t, ma, newMed)
  2747  }
  2748  
  2749  func TestPolicyMatchAndAddingMedOverFlow(t *testing.T) {
  2750  
  2751  	// create path
  2752  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2753  	origin := bgp.NewPathAttributeOrigin(0)
  2754  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  2755  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2756  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2757  	med := bgp.NewPathAttributeMultiExitDisc(1)
  2758  
  2759  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  2760  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2761  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2762  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2763  	// create policy
  2764  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2765  	ns := createNeighborSet("ns1", "10.0.0.1")
  2766  
  2767  	ds := oc.DefinedSets{}
  2768  	ds.PrefixSets = []oc.PrefixSet{ps}
  2769  	ds.NeighborSets = []oc.NeighborSet{ns}
  2770  
  2771  	m := fmt.Sprintf("+%d", uint32(math.MaxUint32))
  2772  	ma := "1"
  2773  
  2774  	s := createStatement("statement1", "ps1", "ns1", true)
  2775  	s.Actions.BgpActions.SetMed = oc.BgpSetMedType(m)
  2776  
  2777  	pd := createPolicyDefinition("pd1", s)
  2778  	pl := createRoutingPolicy(ds, pd)
  2779  	//test
  2780  	r := NewRoutingPolicy(logger)
  2781  	err := r.reload(pl)
  2782  	assert.Nil(t, err)
  2783  	p := r.policyMap["pd1"]
  2784  
  2785  	pType, newPath := p.Apply(logger, path, nil)
  2786  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  2787  	assert.NotEqual(t, nil, newPath)
  2788  
  2789  	v, err := newPath.GetMed()
  2790  	assert.Nil(t, err)
  2791  	newMed := fmt.Sprintf("%d", v)
  2792  	assert.Equal(t, ma, newMed)
  2793  }
  2794  
  2795  func TestPolicyMatchAndSubtractMed(t *testing.T) {
  2796  
  2797  	// create path
  2798  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2799  	origin := bgp.NewPathAttributeOrigin(0)
  2800  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  2801  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2802  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2803  	med := bgp.NewPathAttributeMultiExitDisc(100)
  2804  
  2805  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  2806  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2807  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2808  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2809  	// create policy
  2810  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2811  	ns := createNeighborSet("ns1", "10.0.0.1")
  2812  
  2813  	ds := oc.DefinedSets{}
  2814  	ds.PrefixSets = []oc.PrefixSet{ps}
  2815  	ds.NeighborSets = []oc.NeighborSet{ns}
  2816  
  2817  	m := "-50"
  2818  	ma := "50"
  2819  
  2820  	s := createStatement("statement1", "ps1", "ns1", true)
  2821  	s.Actions.BgpActions.SetMed = oc.BgpSetMedType(m)
  2822  
  2823  	pd := createPolicyDefinition("pd1", s)
  2824  	pl := createRoutingPolicy(ds, pd)
  2825  	//test
  2826  	r := NewRoutingPolicy(logger)
  2827  	err := r.reload(pl)
  2828  	assert.Nil(t, err)
  2829  	p := r.policyMap["pd1"]
  2830  
  2831  	pType, newPath := p.Apply(logger, path, nil)
  2832  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  2833  	assert.NotEqual(t, nil, newPath)
  2834  
  2835  	v, err := newPath.GetMed()
  2836  	assert.Nil(t, err)
  2837  	newMed := fmt.Sprintf("%d", v)
  2838  	assert.Equal(t, ma, newMed)
  2839  }
  2840  
  2841  func TestPolicyMatchAndSubtractMedUnderFlow(t *testing.T) {
  2842  
  2843  	// create path
  2844  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2845  	origin := bgp.NewPathAttributeOrigin(0)
  2846  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  2847  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2848  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2849  	med := bgp.NewPathAttributeMultiExitDisc(100)
  2850  
  2851  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  2852  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2853  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2854  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2855  	// create policy
  2856  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2857  	ns := createNeighborSet("ns1", "10.0.0.1")
  2858  
  2859  	ds := oc.DefinedSets{}
  2860  	ds.PrefixSets = []oc.PrefixSet{ps}
  2861  	ds.NeighborSets = []oc.NeighborSet{ns}
  2862  
  2863  	m := "-101"
  2864  	ma := "100"
  2865  
  2866  	s := createStatement("statement1", "ps1", "ns1", true)
  2867  	s.Actions.BgpActions.SetMed = oc.BgpSetMedType(m)
  2868  
  2869  	pd := createPolicyDefinition("pd1", s)
  2870  	pl := createRoutingPolicy(ds, pd)
  2871  	//test
  2872  	r := NewRoutingPolicy(logger)
  2873  	err := r.reload(pl)
  2874  	assert.Nil(t, err)
  2875  	p := r.policyMap["pd1"]
  2876  
  2877  	pType, newPath := p.Apply(logger, path, nil)
  2878  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  2879  	assert.NotEqual(t, nil, newPath)
  2880  
  2881  	v, err := newPath.GetMed()
  2882  	assert.Nil(t, err)
  2883  	newMed := fmt.Sprintf("%d", v)
  2884  	assert.Equal(t, ma, newMed)
  2885  }
  2886  
  2887  func TestPolicyMatchWhenPathHaveNotMed(t *testing.T) {
  2888  
  2889  	// create path
  2890  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2891  	origin := bgp.NewPathAttributeOrigin(0)
  2892  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  2893  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2894  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2895  
  2896  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop}
  2897  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2898  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2899  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2900  	// create policy
  2901  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2902  	ns := createNeighborSet("ns1", "10.0.0.1")
  2903  
  2904  	ds := oc.DefinedSets{}
  2905  	ds.PrefixSets = []oc.PrefixSet{ps}
  2906  	ds.NeighborSets = []oc.NeighborSet{ns}
  2907  
  2908  	m := "-50"
  2909  	s := createStatement("statement1", "ps1", "ns1", true)
  2910  	s.Actions.BgpActions.SetMed = oc.BgpSetMedType(m)
  2911  
  2912  	pd := createPolicyDefinition("pd1", s)
  2913  	pl := createRoutingPolicy(ds, pd)
  2914  	//test
  2915  	r := NewRoutingPolicy(logger)
  2916  	err := r.reload(pl)
  2917  	assert.Nil(t, err)
  2918  	p := r.policyMap["pd1"]
  2919  
  2920  	pType, newPath := p.Apply(logger, path, nil)
  2921  	assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
  2922  	assert.NotEqual(t, nil, newPath)
  2923  
  2924  	_, err = newPath.GetMed()
  2925  	assert.NotNil(t, err)
  2926  }
  2927  
  2928  func TestPolicyAsPathPrepend(t *testing.T) {
  2929  
  2930  	assert := assert.New(t)
  2931  
  2932  	// create path
  2933  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2934  	origin := bgp.NewPathAttributeOrigin(0)
  2935  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001, 65000})}
  2936  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2937  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2938  	med := bgp.NewPathAttributeMultiExitDisc(0)
  2939  
  2940  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  2941  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2942  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2943  
  2944  	body := updateMsg.Body.(*bgp.BGPUpdate)
  2945  	UpdatePathAttrs4ByteAs(logger, body)
  2946  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2947  
  2948  	// create policy
  2949  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2950  	ns := createNeighborSet("ns1", "10.0.0.1")
  2951  
  2952  	ds := oc.DefinedSets{}
  2953  	ds.PrefixSets = []oc.PrefixSet{ps}
  2954  	ds.NeighborSets = []oc.NeighborSet{ns}
  2955  
  2956  	s := createStatement("statement1", "ps1", "ns1", true)
  2957  	s.Actions.BgpActions.SetAsPathPrepend.As = "65002"
  2958  	s.Actions.BgpActions.SetAsPathPrepend.RepeatN = 10
  2959  
  2960  	pd := createPolicyDefinition("pd1", s)
  2961  	pl := createRoutingPolicy(ds, pd)
  2962  	//test
  2963  	r := NewRoutingPolicy(logger)
  2964  	r.reload(pl)
  2965  	p := r.policyMap["pd1"]
  2966  
  2967  	pType, newPath := p.Apply(logger, path, nil)
  2968  	assert.Equal(ROUTE_TYPE_ACCEPT, pType)
  2969  	assert.NotEqual(nil, newPath)
  2970  	assert.Equal([]uint32{65002, 65002, 65002, 65002, 65002, 65002, 65002, 65002, 65002, 65002, 65001, 65000}, newPath.GetAsSeqList())
  2971  }
  2972  
  2973  func TestPolicyAsPathPrependLastAs(t *testing.T) {
  2974  
  2975  	assert := assert.New(t)
  2976  	// create path
  2977  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  2978  	origin := bgp.NewPathAttributeOrigin(0)
  2979  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65002, 65001, 65000})}
  2980  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2981  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  2982  	med := bgp.NewPathAttributeMultiExitDisc(0)
  2983  
  2984  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  2985  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  2986  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2987  
  2988  	body := updateMsg.Body.(*bgp.BGPUpdate)
  2989  	UpdatePathAttrs4ByteAs(logger, body)
  2990  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  2991  
  2992  	// create policy
  2993  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  2994  	ns := createNeighborSet("ns1", "10.0.0.1")
  2995  
  2996  	ds := oc.DefinedSets{}
  2997  	ds.PrefixSets = []oc.PrefixSet{ps}
  2998  	ds.NeighborSets = []oc.NeighborSet{ns}
  2999  
  3000  	s := createStatement("statement1", "ps1", "ns1", true)
  3001  	s.Actions.BgpActions.SetAsPathPrepend.As = "last-as"
  3002  	s.Actions.BgpActions.SetAsPathPrepend.RepeatN = 5
  3003  
  3004  	pd := createPolicyDefinition("pd1", s)
  3005  	pl := createRoutingPolicy(ds, pd)
  3006  	//test
  3007  	r := NewRoutingPolicy(logger)
  3008  	r.reload(pl)
  3009  	p := r.policyMap["pd1"]
  3010  
  3011  	pType, newPath := p.Apply(logger, path, nil)
  3012  	assert.Equal(ROUTE_TYPE_ACCEPT, pType)
  3013  	assert.NotEqual(nil, newPath)
  3014  	assert.Equal([]uint32{65002, 65002, 65002, 65002, 65002, 65002, 65001, 65000}, newPath.GetAsSeqList())
  3015  }
  3016  
  3017  func TestPolicyAs4PathPrepend(t *testing.T) {
  3018  
  3019  	assert := assert.New(t)
  3020  
  3021  	// create path
  3022  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  3023  	origin := bgp.NewPathAttributeOrigin(0)
  3024  	aspathParam := []bgp.AsPathParamInterface{
  3025  		bgp.NewAs4PathParam(2, []uint32{
  3026  			createAs4Value("65001.1"),
  3027  			createAs4Value("65000.1"),
  3028  		}),
  3029  	}
  3030  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  3031  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  3032  	med := bgp.NewPathAttributeMultiExitDisc(0)
  3033  
  3034  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  3035  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  3036  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  3037  
  3038  	body := updateMsg.Body.(*bgp.BGPUpdate)
  3039  	UpdatePathAttrs4ByteAs(logger, body)
  3040  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  3041  
  3042  	// create policy
  3043  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  3044  	ns := createNeighborSet("ns1", "10.0.0.1")
  3045  
  3046  	ds := oc.DefinedSets{}
  3047  	ds.PrefixSets = []oc.PrefixSet{ps}
  3048  	ds.NeighborSets = []oc.NeighborSet{ns}
  3049  
  3050  	s := createStatement("statement1", "ps1", "ns1", true)
  3051  	s.Actions.BgpActions.SetAsPathPrepend.As = fmt.Sprintf("%d", createAs4Value("65002.1"))
  3052  	s.Actions.BgpActions.SetAsPathPrepend.RepeatN = 10
  3053  
  3054  	pd := createPolicyDefinition("pd1", s)
  3055  	pl := createRoutingPolicy(ds, pd)
  3056  	//test
  3057  	r := NewRoutingPolicy(logger)
  3058  	r.reload(pl)
  3059  	p, err := NewPolicy(pl.PolicyDefinitions[0])
  3060  	assert.Nil(err)
  3061  	addPolicy(r, p)
  3062  
  3063  	pType, newPath := p.Apply(logger, path, nil)
  3064  	assert.Equal(ROUTE_TYPE_ACCEPT, pType)
  3065  	assert.NotEqual(nil, newPath)
  3066  	asn := createAs4Value("65002.1")
  3067  	assert.Equal([]uint32{
  3068  		asn, asn, asn, asn, asn, asn, asn, asn, asn, asn,
  3069  		createAs4Value("65001.1"),
  3070  		createAs4Value("65000.1"),
  3071  	}, newPath.GetAsSeqList())
  3072  }
  3073  
  3074  func TestPolicyAs4PathPrependLastAs(t *testing.T) {
  3075  
  3076  	assert := assert.New(t)
  3077  	// create path
  3078  	peer := &PeerInfo{AS: 65001, Address: net.ParseIP("10.0.0.1")}
  3079  	origin := bgp.NewPathAttributeOrigin(0)
  3080  	aspathParam := []bgp.AsPathParamInterface{
  3081  		bgp.NewAs4PathParam(2, []uint32{
  3082  			createAs4Value("65002.1"),
  3083  			createAs4Value("65001.1"),
  3084  			createAs4Value("65000.1"),
  3085  		}),
  3086  	}
  3087  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  3088  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  3089  	med := bgp.NewPathAttributeMultiExitDisc(0)
  3090  
  3091  	pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  3092  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")}
  3093  	updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  3094  
  3095  	body := updateMsg.Body.(*bgp.BGPUpdate)
  3096  	UpdatePathAttrs4ByteAs(logger, body)
  3097  	path := ProcessMessage(updateMsg, peer, time.Now())[0]
  3098  
  3099  	// create policy
  3100  	ps := createPrefixSet("ps1", "10.10.0.0/16", "21..24")
  3101  	ns := createNeighborSet("ns1", "10.0.0.1")
  3102  
  3103  	ds := oc.DefinedSets{}
  3104  	ds.PrefixSets = []oc.PrefixSet{ps}
  3105  	ds.NeighborSets = []oc.NeighborSet{ns}
  3106  
  3107  	s := createStatement("statement1", "ps1", "ns1", true)
  3108  	s.Actions.BgpActions.SetAsPathPrepend.As = "last-as"
  3109  	s.Actions.BgpActions.SetAsPathPrepend.RepeatN = 5
  3110  
  3111  	pd := createPolicyDefinition("pd1", s)
  3112  	pl := createRoutingPolicy(ds, pd)
  3113  	//test
  3114  	r := NewRoutingPolicy(logger)
  3115  	r.reload(pl)
  3116  	p, _ := NewPolicy(pl.PolicyDefinitions[0])
  3117  	addPolicy(r, p)
  3118  
  3119  	pType, newPath := p.Apply(logger, path, nil)
  3120  	assert.Equal(ROUTE_TYPE_ACCEPT, pType)
  3121  	assert.NotEqual(nil, newPath)
  3122  	asn := createAs4Value("65002.1")
  3123  	assert.Equal([]uint32{
  3124  		asn, asn, asn, asn, asn,
  3125  		createAs4Value("65002.1"),
  3126  		createAs4Value("65001.1"),
  3127  		createAs4Value("65000.1"),
  3128  	}, newPath.GetAsSeqList())
  3129  }
  3130  
  3131  func TestParseCommunityRegexp(t *testing.T) {
  3132  	exp, err := ParseCommunityRegexp("65000:1")
  3133  	assert.Equal(t, nil, err)
  3134  	assert.Equal(t, true, exp.MatchString("65000:1"))
  3135  	assert.Equal(t, false, exp.MatchString("65000:100"))
  3136  
  3137  	// test if the parseCommunityRegexp function behaves as expected
  3138  
  3139  	l1 := "6830:24370$"
  3140  	r1, _ := ParseCommunityRegexp("6830:24370$")
  3141  
  3142  	l2 := "^6830:24370$"
  3143  	r2, _ := ParseCommunityRegexp("^6830:24370$")
  3144  
  3145  	l3 := "^65001:100$"
  3146  	r3, _ := ParseCommunityRegexp("65001:100")
  3147  
  3148  	l4 := "^65001:400$"
  3149  	r4, _ := ParseCommunityRegexp("4259905936")
  3150  
  3151  	l5 := "^[0-9]*:300$"
  3152  	r5, _ := ParseCommunityRegexp("^[0-9]*:300$")
  3153  
  3154  	l6 := "^" + strconv.Itoa(int(bgp.COMMUNITY_INTERNET)) + ":" + strconv.Itoa(int(bgp.COMMUNITY_INTERNET)) + "$"
  3155  	r6, _ := ParseCommunityRegexp("INTERNET")
  3156  
  3157  	fmt.Printf("%v %v", l2, r2)
  3158  
  3159  	assert.Equal(t, l1, r1.String())
  3160  	assert.Equal(t, l2, r2.String())
  3161  	assert.Equal(t, l3, r3.String())
  3162  	assert.Equal(t, l4, r4.String())
  3163  	assert.Equal(t, l5, r5.String())
  3164  	assert.Equal(t, l6, r6.String())
  3165  }
  3166  
  3167  func TestLocalPrefAction(t *testing.T) {
  3168  	action, err := NewLocalPrefAction(10)
  3169  	assert.Nil(t, err)
  3170  
  3171  	nlri := bgp.NewIPAddrPrefix(24, "10.0.0.0")
  3172  
  3173  	origin := bgp.NewPathAttributeOrigin(0)
  3174  	aspathParam := []bgp.AsPathParamInterface{
  3175  		bgp.NewAs4PathParam(2, []uint32{
  3176  			createAs4Value("65002.1"),
  3177  			createAs4Value("65001.1"),
  3178  			createAs4Value("65000.1"),
  3179  		}),
  3180  	}
  3181  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  3182  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  3183  	med := bgp.NewPathAttributeMultiExitDisc(0)
  3184  
  3185  	attrs := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  3186  
  3187  	path := NewPath(nil, nlri, false, attrs, time.Now(), false)
  3188  	p, _ := action.Apply(path, nil)
  3189  	assert.NotNil(t, p)
  3190  
  3191  	attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_LOCAL_PREF)
  3192  	assert.NotNil(t, attr)
  3193  	lp := attr.(*bgp.PathAttributeLocalPref)
  3194  	assert.Equal(t, int(lp.Value), int(10))
  3195  }
  3196  
  3197  func TestOriginAction(t *testing.T) {
  3198  	action, err := NewOriginAction(oc.BGP_ORIGIN_ATTR_TYPE_EGP)
  3199  	assert.Nil(t, err)
  3200  
  3201  	nlri := bgp.NewIPAddrPrefix(24, "10.0.0.0")
  3202  
  3203  	origin := bgp.NewPathAttributeOrigin(0)
  3204  	aspathParam := []bgp.AsPathParamInterface{
  3205  		bgp.NewAs4PathParam(2, []uint32{
  3206  			createAs4Value("65002.1"),
  3207  			createAs4Value("65001.1"),
  3208  			createAs4Value("65000.1"),
  3209  		}),
  3210  	}
  3211  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  3212  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  3213  	med := bgp.NewPathAttributeMultiExitDisc(0)
  3214  
  3215  	attrs := []bgp.PathAttributeInterface{origin, aspath, nexthop, med}
  3216  
  3217  	path := NewPath(nil, nlri, false, attrs, time.Now(), false)
  3218  	p, _ := action.Apply(path, nil)
  3219  	assert.NotNil(t, p)
  3220  
  3221  	attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
  3222  	assert.NotNil(t, attr)
  3223  	lp := attr.(*bgp.PathAttributeOrigin)
  3224  	assert.Equal(t, int(lp.Value), oc.BGP_ORIGIN_ATTR_TYPE_EGP.ToInt())
  3225  
  3226  	action, err = NewOriginAction(oc.BGP_ORIGIN_ATTR_TYPE_INCOMPLETE)
  3227  	assert.Nil(t, err)
  3228  
  3229  	p, _ = action.Apply(p, nil)
  3230  	assert.NotNil(t, p)
  3231  
  3232  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
  3233  	assert.NotNil(t, attr)
  3234  	lp = attr.(*bgp.PathAttributeOrigin)
  3235  	assert.Equal(t, int(lp.Value), oc.BGP_ORIGIN_ATTR_TYPE_INCOMPLETE.ToInt())
  3236  
  3237  	action, err = NewOriginAction(oc.BGP_ORIGIN_ATTR_TYPE_IGP)
  3238  	assert.Nil(t, err)
  3239  
  3240  	p, _ = action.Apply(p, nil)
  3241  	assert.NotNil(t, p)
  3242  
  3243  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
  3244  	assert.NotNil(t, attr)
  3245  	lp = attr.(*bgp.PathAttributeOrigin)
  3246  	assert.Equal(t, int(lp.Value), oc.BGP_ORIGIN_ATTR_TYPE_IGP.ToInt())
  3247  }
  3248  
  3249  func createStatement(name, psname, nsname string, accept bool) oc.Statement {
  3250  	c := oc.Conditions{
  3251  		MatchPrefixSet: oc.MatchPrefixSet{
  3252  			PrefixSet: psname,
  3253  		},
  3254  		MatchNeighborSet: oc.MatchNeighborSet{
  3255  			NeighborSet: nsname,
  3256  		},
  3257  	}
  3258  	rd := oc.ROUTE_DISPOSITION_REJECT_ROUTE
  3259  	if accept {
  3260  		rd = oc.ROUTE_DISPOSITION_ACCEPT_ROUTE
  3261  	}
  3262  	a := oc.Actions{
  3263  		RouteDisposition: rd,
  3264  	}
  3265  	s := oc.Statement{
  3266  		Name:       name,
  3267  		Conditions: c,
  3268  		Actions:    a,
  3269  	}
  3270  	return s
  3271  }
  3272  
  3273  func createSetCommunity(operation string, community ...string) oc.SetCommunity {
  3274  
  3275  	s := oc.SetCommunity{
  3276  		SetCommunityMethod: oc.SetCommunityMethod{
  3277  			CommunitiesList: community,
  3278  		},
  3279  		Options: operation,
  3280  	}
  3281  	return s
  3282  }
  3283  
  3284  func stringToCommunityValue(comStr string) uint32 {
  3285  	elem := strings.Split(comStr, ":")
  3286  	asn, _ := strconv.ParseUint(elem[0], 10, 16)
  3287  	val, _ := strconv.ParseUint(elem[1], 10, 16)
  3288  	return uint32(asn<<16 | val)
  3289  }
  3290  
  3291  func createPolicyDefinition(defName string, stmt ...oc.Statement) oc.PolicyDefinition {
  3292  	pd := oc.PolicyDefinition{
  3293  		Name:       defName,
  3294  		Statements: []oc.Statement(stmt),
  3295  	}
  3296  	return pd
  3297  }
  3298  
  3299  func createRoutingPolicy(ds oc.DefinedSets, pd ...oc.PolicyDefinition) oc.RoutingPolicy {
  3300  	pl := oc.RoutingPolicy{
  3301  		DefinedSets:       ds,
  3302  		PolicyDefinitions: []oc.PolicyDefinition(pd),
  3303  	}
  3304  	return pl
  3305  }
  3306  
  3307  func createPrefixSet(name string, prefix string, maskLength string) oc.PrefixSet {
  3308  	ps := oc.PrefixSet{
  3309  		PrefixSetName: name,
  3310  		PrefixList: []oc.Prefix{
  3311  			{
  3312  				IpPrefix:        prefix,
  3313  				MasklengthRange: maskLength,
  3314  			}},
  3315  	}
  3316  	return ps
  3317  }
  3318  
  3319  func createNeighborSet(name string, addr string) oc.NeighborSet {
  3320  	ns := oc.NeighborSet{
  3321  		NeighborSetName:  name,
  3322  		NeighborInfoList: []string{addr},
  3323  	}
  3324  	return ns
  3325  }
  3326  
  3327  func createAs4Value(s string) uint32 {
  3328  	v := strings.Split(s, ".")
  3329  	upper, _ := strconv.ParseUint(v[0], 10, 16)
  3330  	lower, _ := strconv.ParseUint(v[1], 10, 16)
  3331  	return uint32(upper<<16 | lower)
  3332  }
  3333  
  3334  func TestPrefixSetOperation(t *testing.T) {
  3335  	// tryp to create prefixset with multiple families
  3336  	p1 := oc.Prefix{
  3337  		IpPrefix:        "0.0.0.0/0",
  3338  		MasklengthRange: "0..7",
  3339  	}
  3340  	p2 := oc.Prefix{
  3341  		IpPrefix:        "0::/25",
  3342  		MasklengthRange: "25..128",
  3343  	}
  3344  	_, err := NewPrefixSet(oc.PrefixSet{
  3345  		PrefixSetName: "ps1",
  3346  		PrefixList:    []oc.Prefix{p1, p2},
  3347  	})
  3348  	assert.NotNil(t, err)
  3349  	m1, _ := NewPrefixSet(oc.PrefixSet{
  3350  		PrefixSetName: "ps1",
  3351  		PrefixList:    []oc.Prefix{p1},
  3352  	})
  3353  	m2, err := NewPrefixSet(oc.PrefixSet{PrefixSetName: "ps2"})
  3354  	assert.Nil(t, err)
  3355  	err = m1.Append(m2)
  3356  	assert.Nil(t, err)
  3357  	err = m2.Append(m1)
  3358  	assert.Nil(t, err)
  3359  	assert.Equal(t, bgp.RF_IPv4_UC, m2.family)
  3360  	p3, _ := NewPrefix(oc.Prefix{IpPrefix: "10.10.0.0/24", MasklengthRange: ""})
  3361  	p4, _ := NewPrefix(oc.Prefix{IpPrefix: "0::/25", MasklengthRange: ""})
  3362  	_, err = NewPrefixSetFromApiStruct("ps3", []*Prefix{p3, p4})
  3363  	assert.NotNil(t, err)
  3364  }
  3365  
  3366  func TestPrefixSetMatch(t *testing.T) {
  3367  	p1 := oc.Prefix{
  3368  		IpPrefix:        "0.0.0.0/0",
  3369  		MasklengthRange: "0..7",
  3370  	}
  3371  	p2 := oc.Prefix{
  3372  		IpPrefix:        "0.0.0.0/0",
  3373  		MasklengthRange: "25..32",
  3374  	}
  3375  	ps, err := NewPrefixSet(oc.PrefixSet{
  3376  		PrefixSetName: "ps1",
  3377  		PrefixList:    []oc.Prefix{p1, p2},
  3378  	})
  3379  	assert.Nil(t, err)
  3380  	m := &PrefixCondition{
  3381  		set: ps,
  3382  	}
  3383  
  3384  	path := NewPath(nil, bgp.NewIPAddrPrefix(6, "0.0.0.0"), false, []bgp.PathAttributeInterface{}, time.Now(), false)
  3385  	assert.True(t, m.Evaluate(path, nil))
  3386  
  3387  	path = NewPath(nil, bgp.NewIPAddrPrefix(10, "0.0.0.0"), false, []bgp.PathAttributeInterface{}, time.Now(), false)
  3388  	assert.False(t, m.Evaluate(path, nil))
  3389  
  3390  	path = NewPath(nil, bgp.NewIPAddrPrefix(25, "0.0.0.0"), false, []bgp.PathAttributeInterface{}, time.Now(), false)
  3391  	assert.True(t, m.Evaluate(path, nil))
  3392  
  3393  	path = NewPath(nil, bgp.NewIPAddrPrefix(30, "0.0.0.0"), false, []bgp.PathAttributeInterface{}, time.Now(), false)
  3394  	assert.True(t, m.Evaluate(path, nil))
  3395  
  3396  	p3 := oc.Prefix{
  3397  		IpPrefix:        "0.0.0.0/0",
  3398  		MasklengthRange: "9..10",
  3399  	}
  3400  	ps2, err := NewPrefixSet(oc.PrefixSet{
  3401  		PrefixSetName: "ps2",
  3402  		PrefixList:    []oc.Prefix{p3},
  3403  	})
  3404  	assert.Nil(t, err)
  3405  	err = ps.Append(ps2)
  3406  	assert.Nil(t, err)
  3407  
  3408  	path = NewPath(nil, bgp.NewIPAddrPrefix(10, "0.0.0.0"), false, []bgp.PathAttributeInterface{}, time.Now(), false)
  3409  	assert.True(t, m.Evaluate(path, nil))
  3410  
  3411  	ps3, err := NewPrefixSet(oc.PrefixSet{
  3412  		PrefixSetName: "ps3",
  3413  		PrefixList:    []oc.Prefix{p1},
  3414  	})
  3415  	assert.Nil(t, err)
  3416  	err = ps.Remove(ps3)
  3417  	assert.Nil(t, err)
  3418  
  3419  	path = NewPath(nil, bgp.NewIPAddrPrefix(6, "0.0.0.0"), false, []bgp.PathAttributeInterface{}, time.Now(), false)
  3420  	assert.False(t, m.Evaluate(path, nil))
  3421  }
  3422  
  3423  func TestPrefixSetMatchV4withV6Prefix(t *testing.T) {
  3424  	p1 := oc.Prefix{
  3425  		IpPrefix:        "c000::/3",
  3426  		MasklengthRange: "3..128",
  3427  	}
  3428  	ps, err := NewPrefixSet(oc.PrefixSet{
  3429  		PrefixSetName: "ps1",
  3430  		PrefixList:    []oc.Prefix{p1},
  3431  	})
  3432  	assert.Nil(t, err)
  3433  	m := &PrefixCondition{
  3434  		set: ps,
  3435  	}
  3436  
  3437  	path := NewPath(nil, bgp.NewIPAddrPrefix(6, "192.0.0.0"), false, []bgp.PathAttributeInterface{}, time.Now(), false)
  3438  	assert.False(t, m.Evaluate(path, nil))
  3439  }
  3440  
  3441  func TestPrefixSetMatchV6LabeledwithV6Prefix(t *testing.T) {
  3442  	p1 := oc.Prefix{
  3443  		IpPrefix:        "2806:106e:19::/48",
  3444  		MasklengthRange: "48..48",
  3445  	}
  3446  	ps, err := NewPrefixSet(oc.PrefixSet{
  3447  		PrefixSetName: "ps1",
  3448  		PrefixList:    []oc.Prefix{p1},
  3449  	})
  3450  	assert.Nil(t, err)
  3451  	m := &PrefixCondition{
  3452  		set: ps,
  3453  	}
  3454  
  3455  	labels := bgp.NewMPLSLabelStack(100, 200)
  3456  	n1 := bgp.NewLabeledIPv6AddrPrefix(48, "2806:106e:19::", *labels)
  3457  	path := NewPath(nil, n1, false, []bgp.PathAttributeInterface{}, time.Now(), false)
  3458  	assert.True(t, m.Evaluate(path, nil))
  3459  
  3460  	labels = bgp.NewMPLSLabelStack(100, 200)
  3461  	n2 := bgp.NewLabeledIPv6AddrPrefix(48, "1806:106e:19::", *labels)
  3462  	path = NewPath(nil, n2, false, []bgp.PathAttributeInterface{}, time.Now(), false)
  3463  	assert.False(t, m.Evaluate(path, nil))
  3464  }
  3465  
  3466  func TestPrefixSetMatchVPNV4Prefix(t *testing.T) {
  3467  	p1 := oc.Prefix{
  3468  		IpPrefix:        "10.10.10.0/24",
  3469  		MasklengthRange: "24..32",
  3470  	}
  3471  	ps, err := NewPrefixSet(oc.PrefixSet{
  3472  		PrefixSetName: "ps1",
  3473  		PrefixList:    []oc.Prefix{p1},
  3474  	})
  3475  	assert.Nil(t, err)
  3476  	m := &PrefixCondition{
  3477  		set: ps,
  3478  	}
  3479  
  3480  	labels := bgp.NewMPLSLabelStack(100, 200)
  3481  	rd, _ := bgp.ParseRouteDistinguisher("100:100")
  3482  
  3483  	n1 := bgp.NewLabeledVPNIPAddrPrefix(32, "10.10.10.10", *labels, rd)
  3484  	path := NewPath(nil, n1, false, []bgp.PathAttributeInterface{}, time.Now(), false)
  3485  	assert.True(t, m.Evaluate(path, nil))
  3486  
  3487  	n2 := bgp.NewLabeledVPNIPAddrPrefix(32, "10.20.20.20", *labels, rd)
  3488  	path = NewPath(nil, n2, false, []bgp.PathAttributeInterface{}, time.Now(), false)
  3489  	assert.False(t, m.Evaluate(path, nil))
  3490  
  3491  	n3 := bgp.NewLabeledVPNIPAddrPrefix(16, "10.10.0.0", *labels, rd)
  3492  	path = NewPath(nil, n3, false, []bgp.PathAttributeInterface{}, time.Now(), false)
  3493  	assert.False(t, m.Evaluate(path, nil))
  3494  }
  3495  
  3496  func TestPrefixSetMatchVPNV6Prefix(t *testing.T) {
  3497  	p1 := oc.Prefix{
  3498  		IpPrefix:        "2001:123:123:1::/64",
  3499  		MasklengthRange: "64..128",
  3500  	}
  3501  	ps, err := NewPrefixSet(oc.PrefixSet{
  3502  		PrefixSetName: "ps1",
  3503  		PrefixList:    []oc.Prefix{p1},
  3504  	})
  3505  	assert.Nil(t, err)
  3506  	m := &PrefixCondition{
  3507  		set: ps,
  3508  	}
  3509  
  3510  	labels := bgp.NewMPLSLabelStack(100, 200)
  3511  	rd, _ := bgp.ParseRouteDistinguisher("100:100")
  3512  
  3513  	n1 := bgp.NewLabeledVPNIPv6AddrPrefix(128, "2001:123:123:1::", *labels, rd)
  3514  	path := NewPath(nil, n1, false, []bgp.PathAttributeInterface{}, time.Now(), false)
  3515  	assert.True(t, m.Evaluate(path, nil))
  3516  
  3517  	n2 := bgp.NewLabeledVPNIPv6AddrPrefix(128, "2001:124:123:1::", *labels, rd)
  3518  	path = NewPath(nil, n2, false, []bgp.PathAttributeInterface{}, time.Now(), false)
  3519  	assert.False(t, m.Evaluate(path, nil))
  3520  
  3521  	n3 := bgp.NewLabeledVPNIPv6AddrPrefix(48, "2001:124:123::", *labels, rd)
  3522  	path = NewPath(nil, n3, false, []bgp.PathAttributeInterface{}, time.Now(), false)
  3523  	assert.False(t, m.Evaluate(path, nil))
  3524  }
  3525  
  3526  func TestLargeCommunityMatchAction(t *testing.T) {
  3527  	coms := []*bgp.LargeCommunity{
  3528  		{ASN: 100, LocalData1: 100, LocalData2: 100},
  3529  		{ASN: 100, LocalData1: 200, LocalData2: 200},
  3530  	}
  3531  	p := NewPath(nil, nil, false, []bgp.PathAttributeInterface{bgp.NewPathAttributeLargeCommunities(coms)}, time.Time{}, false)
  3532  
  3533  	c := oc.LargeCommunitySet{
  3534  		LargeCommunitySetName: "l0",
  3535  		LargeCommunityList: []string{
  3536  			"100:100:100",
  3537  			"100:300:100",
  3538  		},
  3539  	}
  3540  
  3541  	set, err := NewLargeCommunitySet(c)
  3542  	assert.Equal(t, err, nil)
  3543  
  3544  	m, err := NewLargeCommunityCondition(oc.MatchLargeCommunitySet{
  3545  		LargeCommunitySet: "l0",
  3546  	})
  3547  	assert.Equal(t, err, nil)
  3548  	m.set = set
  3549  
  3550  	assert.Equal(t, m.Evaluate(p, nil), true)
  3551  
  3552  	a, err := NewLargeCommunityAction(oc.SetLargeCommunity{
  3553  		SetLargeCommunityMethod: oc.SetLargeCommunityMethod{
  3554  			CommunitiesList: []string{"100:100:100"},
  3555  		},
  3556  		Options: oc.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE,
  3557  	})
  3558  	assert.Equal(t, err, nil)
  3559  	p, _ = a.Apply(p, nil)
  3560  
  3561  	assert.Equal(t, m.Evaluate(p, nil), false)
  3562  
  3563  	a, err = NewLargeCommunityAction(oc.SetLargeCommunity{
  3564  		SetLargeCommunityMethod: oc.SetLargeCommunityMethod{
  3565  			CommunitiesList: []string{
  3566  				"100:300:100",
  3567  				"200:100:100",
  3568  			},
  3569  		},
  3570  		Options: oc.BGP_SET_COMMUNITY_OPTION_TYPE_ADD,
  3571  	})
  3572  	assert.Equal(t, err, nil)
  3573  	p, _ = a.Apply(p, nil)
  3574  
  3575  	assert.Equal(t, m.Evaluate(p, nil), true)
  3576  
  3577  	a, err = NewLargeCommunityAction(oc.SetLargeCommunity{
  3578  		SetLargeCommunityMethod: oc.SetLargeCommunityMethod{
  3579  			CommunitiesList: []string{"^100:"},
  3580  		},
  3581  		Options: oc.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE,
  3582  	})
  3583  	assert.Equal(t, err, nil)
  3584  	p, _ = a.Apply(p, nil)
  3585  
  3586  	assert.Equal(t, m.Evaluate(p, nil), false)
  3587  
  3588  	c = oc.LargeCommunitySet{
  3589  		LargeCommunitySetName: "l1",
  3590  		LargeCommunityList: []string{
  3591  			"200:",
  3592  		},
  3593  	}
  3594  
  3595  	set, err = NewLargeCommunitySet(c)
  3596  	assert.Equal(t, err, nil)
  3597  
  3598  	m, err = NewLargeCommunityCondition(oc.MatchLargeCommunitySet{
  3599  		LargeCommunitySet: "l1",
  3600  	})
  3601  	assert.Equal(t, err, nil)
  3602  	m.set = set
  3603  
  3604  	assert.Equal(t, m.Evaluate(p, nil), true)
  3605  }
  3606  
  3607  func TestLargeCommunitiesMatchClearAction(t *testing.T) {
  3608  	coms := []*bgp.LargeCommunity{
  3609  		{ASN: 100, LocalData1: 100, LocalData2: 100},
  3610  		{ASN: 100, LocalData1: 200, LocalData2: 200},
  3611  	}
  3612  	p := NewPath(nil, nil, false, []bgp.PathAttributeInterface{bgp.NewPathAttributeLargeCommunities(coms)}, time.Time{}, false)
  3613  
  3614  	a, err := NewLargeCommunityAction(oc.SetLargeCommunity{
  3615  		SetLargeCommunityMethod: oc.SetLargeCommunityMethod{
  3616  			CommunitiesList: []string{
  3617  				"100:100:100",
  3618  				"100:200:200",
  3619  			},
  3620  		},
  3621  		Options: oc.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE,
  3622  	})
  3623  
  3624  	assert.Equal(t, err, nil)
  3625  	p, _ = a.Apply(p, nil)
  3626  
  3627  	var lc []*bgp.LargeCommunity
  3628  	assert.Equal(t, lc, p.GetLargeCommunities())
  3629  }
  3630  
  3631  func TestAfiSafiInMatchPath(t *testing.T) {
  3632  	condition, err := NewAfiSafiInCondition([]oc.AfiSafiType{oc.AFI_SAFI_TYPE_L3VPN_IPV4_UNICAST, oc.AFI_SAFI_TYPE_L3VPN_IPV6_UNICAST})
  3633  	require.NoError(t, err)
  3634  
  3635  	rtExtCom, err := bgp.ParseExtendedCommunity(bgp.EC_SUBTYPE_ROUTE_TARGET, "100:100")
  3636  	assert.NoError(t, err)
  3637  
  3638  	prefixVPNv4 := bgp.NewLabeledVPNIPAddrPrefix(0, "1.1.1.0/24", *bgp.NewMPLSLabelStack(), bgp.NewRouteDistinguisherTwoOctetAS(100, 100))
  3639  	prefixVPNv6 := bgp.NewLabeledVPNIPv6AddrPrefix(0, "2001:0db8:85a3:0000:0000:8a2e:0370:7334", *bgp.NewMPLSLabelStack(), bgp.NewRouteDistinguisherTwoOctetAS(200, 200))
  3640  	prefixRTC := bgp.NewRouteTargetMembershipNLRI(100, nil)
  3641  	prefixv4 := bgp.NewIPAddrPrefix(0, "1.1.1.0/24")
  3642  	prefixv6 := bgp.NewIPv6AddrPrefix(0, "2001:0db8:85a3:0000:0000:8a2e:0370:7334")
  3643  
  3644  	pathVPNv4 := NewPath(nil, prefixVPNv4, false, []bgp.PathAttributeInterface{bgp.NewPathAttributeExtendedCommunities([]bgp.ExtendedCommunityInterface{rtExtCom})}, time.Time{}, false)
  3645  	pathVPNv6 := NewPath(nil, prefixVPNv6, false, []bgp.PathAttributeInterface{bgp.NewPathAttributeExtendedCommunities([]bgp.ExtendedCommunityInterface{rtExtCom})}, time.Time{}, false)
  3646  	pathv4 := NewPath(nil, prefixv4, false, []bgp.PathAttributeInterface{}, time.Time{}, false)
  3647  	pathv6 := NewPath(nil, prefixv6, false, []bgp.PathAttributeInterface{}, time.Time{}, false)
  3648  	pathRTC := NewPath(nil, prefixRTC, false, []bgp.PathAttributeInterface{}, time.Time{}, false)
  3649  
  3650  	type Entry struct {
  3651  		path        *Path
  3652  		shouldMatch bool
  3653  	}
  3654  
  3655  	for _, entry := range []Entry{
  3656  		{pathVPNv4, true},
  3657  		{pathVPNv6, true},
  3658  		{pathv4, false},
  3659  		{pathv6, false},
  3660  		{pathRTC, false},
  3661  	} {
  3662  		assert.Equal(t, condition.Evaluate(entry.path, nil), entry.shouldMatch)
  3663  	}
  3664  }
  3665  
  3666  func TestMultipleStatementPolicy(t *testing.T) {
  3667  	r := NewRoutingPolicy(logger)
  3668  	rp := oc.RoutingPolicy{
  3669  		PolicyDefinitions: []oc.PolicyDefinition{{
  3670  			Name: "p1",
  3671  			Statements: []oc.Statement{
  3672  				{
  3673  					Actions: oc.Actions{
  3674  						BgpActions: oc.BgpActions{
  3675  							SetMed: "+100",
  3676  						},
  3677  					},
  3678  				},
  3679  				{
  3680  					Actions: oc.Actions{
  3681  						BgpActions: oc.BgpActions{
  3682  							SetLocalPref: 100,
  3683  						},
  3684  					},
  3685  				},
  3686  			},
  3687  		},
  3688  		},
  3689  	}
  3690  	err := r.reload(rp)
  3691  	assert.Nil(t, err)
  3692  
  3693  	nlri := bgp.NewIPAddrPrefix(24, "10.10.0.0")
  3694  
  3695  	origin := bgp.NewPathAttributeOrigin(0)
  3696  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65001})}
  3697  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  3698  	nexthop := bgp.NewPathAttributeNextHop("10.0.0.1")
  3699  	pattrs := []bgp.PathAttributeInterface{origin, aspath, nexthop}
  3700  
  3701  	path := NewPath(nil, nlri, false, pattrs, time.Now(), false)
  3702  
  3703  	pType, newPath := r.policyMap["p1"].Apply(logger, path, nil)
  3704  	assert.Equal(t, ROUTE_TYPE_NONE, pType)
  3705  	med, _ := newPath.GetMed()
  3706  	assert.Equal(t, med, uint32(100))
  3707  	localPref, _ := newPath.GetLocalPref()
  3708  	assert.Equal(t, localPref, uint32(100))
  3709  }
  3710  
  3711  func TestNewSingleAsPathMatch(t *testing.T) {
  3712  	r := NewSingleAsPathMatch("^65100_")
  3713  	assert.Equal(t, r.mode, LEFT_MOST)
  3714  	r = NewSingleAsPathMatch("_65100$")
  3715  	assert.Equal(t, r.mode, ORIGIN)
  3716  	r = NewSingleAsPathMatch("_65100_")
  3717  	assert.Equal(t, r.mode, INCLUDE)
  3718  	r = NewSingleAsPathMatch("^65100$")
  3719  	assert.Equal(t, r.mode, ONLY)
  3720  }