@@ -32,6 +32,55 @@ ip route vrf MGMT 0.0.0.0/0 {{ vm_mgmt_gw }}
3232ip route vrf MGMT 0.0.0.0/0 {{ mgmt_gw }}
3333{% endif %}
3434!
35+ route-map DEFAULT_ROUTES permit
36+ !
37+ {# #}
38+ {# NOTE: Using large enough values (e.g., podset_number = 200, #}
39+ {# us to overflow the 192.168.0.0/16 private address space here. #}
40+ {# This should be fine for internal use, but may pose an issue if used otherwise #}
41+ {# #}
42+ {% for podset in range (0, props .podset_number ) %}
43+ {% for tor in range (0, props .tor_number ) %}
44+ {% for subnet in range (0, props .tor_subnet_number ) %}
45+ {# Skip tor 0 podset 0 #}
46+ {% if podset != 0 or tor != 0 %}
47+ {% set suffix = ( (podset * props .tor_number * props .max_tor_subnet_number * props .tor_subnet_size ) +
48+ (tor * props .max_tor_subnet_number * props .tor_subnet_size ) +
49+ (subnet * props .tor_subnet_size ) ) %}
50+ {% set octet 2 = (168 + (suffix // (256 ** 2))) %}
51+ {% set octet 1 = (192 + (octet 2 // 256)) %}
52+ {% set octet 2 = (octet 2 % 256) %}
53+ {% set octet 3 = ((suffix // 256) % 256) %}
54+ {% set octet 4 = (suffix % 256) %}
55+ {% set prefixlen_v 4 = (32 - ((props .tor_subnet_size | log (2))) | int ) %}
56+ ip route {{ octet1 }}.{{ octet2 }}.{{ octet3 }}.{{ octet4 }}/{{ prefixlen_v4 }} {{ props.nhipv4 }}
57+ ipv6 route {{ '20%02x' % octet1 }}:{{ '%02X%02X' % (octet2, octet3) }}:0:{{ '%02X' % octet4 }}::/64 {{ props.nhipv6 }}
58+ {% endif %}
59+ {% endfor %}
60+ {% endfor %}
61+ {% endfor %}
62+ !
63+ {% for podset in range (0, props .podset_number ) %}
64+ {% for tor in range (0, props .tor_number ) %}
65+ {# Skip tor 0 podset 0 #}
66+ {% if podset != 0 or tor != 0 %}
67+ {% set suffix = ( (podset * props .tor_number * props .max_tor_subnet_number * props .tor_subnet_size ) +
68+ (tor * props .max_tor_subnet_number * props .tor_subnet_size ) ) %}
69+ {% set octet 2 = (168 + (suffix // (256 ** 2))) %}
70+ {% set octet 1 = (192 + (octet 2 // 256)) %}
71+ {% set octet 2 = (octet 2 % 256) %}
72+ {% set octet 3 = ((suffix // 256) % 256) %}
73+ {% set octet 4 = (suffix % 256) %}
74+ {% set prefixlen_v 4 = (32 - (((props .max_tor_subnet_number * props .tor_subnet_size ) | log (2)) | int ) ) %}
75+ {% set prefixlen_v 6 = (64 - (((props .max_tor_subnet_number * props .tor_subnet_size ) | log (2)) | int ) ) %}
76+ ip prefix-list test_ipv4_{{ podset}}_{{ tor }} seq 10 permit {{ octet1 }}.{{ octet2 }}.{{ octet3 }}.{{ octet4 }}/{{ prefixlen_v4 }} ge {{ prefixlen_v4 }}
77+ ipv6 prefix-list test_ipv6_{{ podset}}_{{ tor }}
78+ seq 10 permit {{ '20%02x' % octet1 }}:{{ '%02X%02X' % (octet2, octet3) }}:0:{{ '%02X' % octet4 }}::/{{ prefixlen_v6 }} ge {{ prefixlen_v6 }}
79+ exit
80+ {% endif %}
81+ {% endfor %}
82+ {% endfor %}
83+ !
3584interface Management 1
3685 description TO LAB MGMT SWITCH
3786 vrf forwarding MGMT
@@ -77,27 +126,46 @@ interface {{ bp_ifname }}
77126{% endif %}
78127 no shutdown
79128!
129+ {% for podset in range (0, props .podset_number ) %}
130+ {% if range (0, 1000)|random () >= props .failure_rate %}
131+ {% for tor in range (0, props .tor_number ) %}
132+ {% set leafasn = props .leaf_asn_start + podset %}
133+ {% set torasn = props .tor_asn_start + tor %}
134+ route-map PREPENDAS permit {{ 2 * (podset * props.tor_number + tor + 1) }}
135+ match ip address prefix-list test_ipv4_{{ podset }}_{{ tor }}
136+ {% if podset == 0 %}
137+ set as-path prepend {{ torasn }}
138+ {% else %}
139+ set as-path prepend {{ props.spine_asn }} {{ leafasn }} {{ torasn }}
140+ {% endif %}
141+ !
142+ route-map PREPENDAS permit {{ 2 * (podset * props.tor_number + tor + 1) + 1 }}
143+ match ipv6 address prefix-list test_ipv6_{{ podset }}_{{ tor }}
144+ {% if podset == 0 %}
145+ set as-path prepend {{ torasn }}
146+ {% else %}
147+ set as-path prepend {{ props.spine_asn }} {{ leafasn }} {{ torasn }}
148+ {% endif %}
149+ !
150+ {% endfor %}
151+ {% endif %}
152+ {% endfor %}
153+ !
80154router bgp {{ host['bgp'] ['asn'] }}
81155 router-id {{ host['interfaces'] ['Loopback0'] ['ipv4'] | ipaddr('address') }}
82156 !
83157{% for asn , remote_ips in host ['bgp' ]['peers' ].items () %}
84158{% for remote_ip in remote_ips %}
85159 neighbor {{ remote_ip }} remote-as {{ asn }}
86160 neighbor {{ remote_ip }} description {{ asn }}
161+ neighbor {{ remote_ip }} default-originate route-map DEFAULT_ROUTES
87162{% if remote_ip | ipv 6 %}
88163 address-family ipv6
89164 neighbor {{ remote_ip }} activate
90165 exit
91166{% endif %}
92167{% endfor %}
93168{% endfor %}
94- neighbor {{ props.nhipv4 }} remote-as {{ host['bgp'] ['asn'] }}
95- neighbor {{ props.nhipv4 }} description exabgp_v4
96- neighbor {{ props.nhipv6 }} remote-as {{ host['bgp'] ['asn'] }}
97- neighbor {{ props.nhipv6 }} description exabgp_v6
98- address-family ipv6
99- neighbor {{ props.nhipv6 }} activate
100- exit
101169 !
102170{% for name , iface in host ['interfaces' ].items () if name .startswith ('Loopback' ) %}
103171{% if iface ['ipv4' ] is defined %}
@@ -107,10 +175,12 @@ router bgp {{ host['bgp']['asn'] }}
107175 network {{ iface['ipv6'] }}
108176{% endif %}
109177{% endfor %}
178+ redistribute static route-map PREPENDAS
110179!
111180management api http-commands
112181 no protocol https
113182 protocol http
114183 no shutdown
115184!
116185end
186+ s
0 commit comments