-
Notifications
You must be signed in to change notification settings - Fork 1
/
test_bgp_blackhole_community.py
147 lines (129 loc) Β· 4.56 KB
/
test_bgp_blackhole_community.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2023 Nathan Mangar for NetDEF, Inc.
"""
Confirm that a BGP route tagged with BLACKHOLE community is not re-advertised
downstream outside local AS.
"""
__topotests_replaces__ = {
"bgp_blackhole_community/": "acddc0ed3ce0833490b7ef38ed000d54388ebea4",
}
# NB: upstream test change in 4777c8376a118629e4916059a8b4f86aa519db6c is bogus
# (should be a separate test)
# pylint: disable=invalid-name, missing-class-docstring, missing-function-docstring, line-too-long, consider-using-f-string, wildcard-import, unused-wildcard-import, f-string-without-interpolation, too-few-public-methods, unused-argument, attribute-defined-outside-init
from topotato.v1 import *
not_blackhole_prefix = "172.16.255.255/32"
blackhole_prefix = "172.16.255.254/32"
@topology_fixture()
def topology(topo):
"""
[ r1 ]--[ r2 ]--[ r3 ]
|
[ r4 ]
"""
topo.router("r1").lo_ip4.append(not_blackhole_prefix)
topo.router("r1").lo_ip4.append(blackhole_prefix)
class Configs(FRRConfigs):
zebra = """
#% extends "boilerplate.conf"
## nothing needed
"""
bgpd = """
#% block main
#% set blackhole_prefix = "172.16.255.254/32"
#% set asns = { "r1": 65001, "r2": 65002, "r3": 65003, "r4": 65002 }
router bgp {{ asns[router.name] }}
timers bgp 3 9
no bgp ebgp-requires-policy
#% for iface in router.ifaces
neighbor {{ iface.other.ip4[0].ip }} remote-as {{ asns[iface.other.endpoint.name] }}
neighbor {{ iface.other.ip4[0].ip }} timers connect 1
#% endfor
#% if router.name == 'r1'
address-family ipv4 unicast
redistribute connected
neighbor {{ router.iface_to('r2').other.ip4[0].ip }} route-map r2 out
!
ip prefix-list blackhole-prefix seq 10 permit {{ blackhole_prefix }}
ip prefix-list blackhole-prefix seq 20 deny any
!
route-map r2 permit 10
match ip address prefix-list blackhole-prefix
set community blackhole no-export
route-map r2 permit 20
#% endif
#% endblock
"""
class BGPBlackholeCommunity(TestBase, AutoFixture, topo=topology, configs=Configs):
@topotatofunc
def bgp_converge(self, topo, r1, r2, r3, r4):
"""
Ensure convergence:
- check that blackhole prefix made it to r2
- check that non-blackhole prefix is on r3 and r4
"""
expected = {
"advertisedRoutes": {
blackhole_prefix: {},
not_blackhole_prefix: {},
},
}
yield from AssertVtysh.make(
r1,
"bgpd",
f"show ip bgp neighbor {r2.iface_to('r1').ip4[0].ip} advertised-routes json",
maxwait=7.0,
compare=expected,
)
expected = {"paths": [{"community": {"list": ["blackhole", "noExport"]}}]}
yield from AssertVtysh.make(
r2,
"bgpd",
f"show ip bgp {blackhole_prefix} json",
maxwait=7.0,
compare=expected,
)
expected = {"prefix": not_blackhole_prefix}
for other in r3, r4:
yield from AssertVtysh.make(
other,
"bgpd",
f"show ip bgp {not_blackhole_prefix} json",
maxwait=7.0,
compare=expected,
)
@topotatofunc
def bgp_no_advertise_ebgp(self, r2):
"""
The blackholed prefix should be absent from r2's eBGP session.
NB: bgp_converge() above has ensured that non_blackhole_prefix is
propagated correctly. This is necessary since otherwise the blackholed
prefix might be absent because routes haven't converged yet.
"""
expected = {
"advertisedRoutes": {
blackhole_prefix: None,
},
}
yield from AssertVtysh.make(
r2,
"bgpd",
f"show ip bgp neighbor {r2.iface_to('r3').other.ip4[0].ip} advertised-routes json",
compare=expected,
)
@topotatofunc
def bgp_yes_advertise_ibgp(self, r2):
"""
Blackhole communities should NOT affect iBGP advertisements, so check
that the route is still carried on the iBGP session.
"""
expected = {
"advertisedRoutes": {
blackhole_prefix: JSONCompareIgnoreContent(),
},
}
yield from AssertVtysh.make(
r2,
"bgpd",
f"show ip bgp neighbor {r2.iface_to('r4').other.ip4[0].ip} advertised-routes json",
compare=expected,
)