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 }