Coverage for birdplan/bird_config/sections/protocols/bgp/bgp_functions.py: 99%
505 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-23 03:27 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-23 03:27 +0000
1#
2# SPDX-License-Identifier: GPL-3.0-or-later
3#
4# Copyright (c) 2019-2024, AllWorldIT
5#
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
19"""BGP protocol specific functions class."""
21# pylint: disable=too-many-lines
23from typing import Any
25from ....globals import BirdConfigGlobals
26from ...functions import BirdFunction, BirdVariable, SectionFunctions
27from ..base_protocol_functions import ProtocolFunctionsBase
29__all__ = ["BGPFunctions"]
32class BGPFunctions(ProtocolFunctionsBase): # pylint: disable=too-many-public-methods
33 """BGP protocol specific functions class."""
35 def __init__(self, birdconfig_globals: BirdConfigGlobals, functions: SectionFunctions):
36 """Initialize the object."""
37 super().__init__(birdconfig_globals, functions)
39 self._section = "BGP Functions"
41 @BirdFunction("bgp_accept_bgp")
42 def accept_bgp(self, *args: Any) -> str: # pylint: disable=unused-argument
43 """BIRD bgp_accept_bgp function."""
45 return f"""\
46 # Accept bgp routes
47 function bgp_accept_bgp(string filter_name) -> bool {{
48 if (
49 !{self.functions.is_bgp()} ||
50 {self.is_blackhole()} ||
51 {self.is_originated()} ||
52 {self.functions.is_default()}
53 ) then return false;
54 if DEBUG then print filter_name,
55 " [bgp_accept_bgp] Accepting BGP route ", {self.functions.route_info()};
56 accept;
57 }}"""
59 @BirdFunction("bgp_accept_customer_blackhole")
60 def accept_customer_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
61 """BIRD bgp_accept_customer_blackhole function."""
63 return f"""\
64 # Accept customer blackhole routes
65 function bgp_accept_customer_blackhole(string filter_name) -> bool {{
66 if (
67 !{self.functions.is_bgp()} ||
68 !{self.is_blackhole()} ||
69 !{self.is_bgp_customer()} ||
70 {self.functions.is_default()}
71 ) then return false;
72 if DEBUG then print filter_name,
73 " [bgp_accept_customer_blackhole] Accepting BGP customer blackhole route ", {self.functions.route_info()};
74 accept;
75 }}"""
77 @BirdFunction("bgp_accept_own_blackhole")
78 def accept_own_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
79 """BIRD bgp_accept_own_blackhole function."""
81 return f"""\
82 # Accept own blackhole routes
83 function bgp_accept_own_blackhole(string filter_name) -> bool {{
84 if (
85 !{self.functions.is_bgp()} ||
86 !{self.is_blackhole()} ||
87 !{self.is_bgp_own()} ||
88 {self.functions.is_default()}
89 ) then return false;
90 if DEBUG then print filter_name,
91 " [bgp_accept_own_blackhole] Accepting BGP own blackhole route ", {self.functions.route_info()};
92 accept;
93 }}"""
95 @BirdFunction("bgp_accept_bgp_own_default")
96 def accept_bgp_own_default(self, *args: Any) -> str: # pylint: disable=unused-argument
97 """BIRD bgp_accept_bgp_own_default function."""
99 return f"""\
100 # Accept BGP default routes
101 function bgp_accept_bgp_own_default(string filter_name) -> bool {{
102 if (
103 !{self.functions.is_bgp()} ||
104 !{self.is_bgp_own()} ||
105 !{self.functions.is_default()} ||
106 {self.is_blackhole()}
107 ) then return false;
108 if DEBUG then print filter_name,
109 " [bgp_accept_bgp_own_default] Accepting BGP own default route ", {self.functions.route_info()};
110 accept;
111 }}"""
113 @BirdFunction("bgp_accept_bgp_transit_default")
114 def accept_bgp_transit_default(self, *args: Any) -> str: # pylint: disable=unused-argument
115 """BIRD bgp_accept_bgp_transit_default function."""
117 return f"""\
118 # Accept BGP default routes
119 function bgp_accept_bgp_transit_default(string filter_name) -> bool {{
120 if (
121 !{self.functions.is_bgp()} ||
122 !{self.is_bgp_transit()} ||
123 !{self.functions.is_default()} ||
124 {self.is_blackhole()}
125 ) then return false;
126 if DEBUG then print filter_name,
127 " [bgp_accept_bgp_transit_default] Accepting BGP transit default route ", {self.functions.route_info()};
128 accept;
129 }}"""
131 @BirdFunction("bgp_accept_originated")
132 def accept_originated(self, *args: Any) -> str: # pylint: disable=unused-argument
133 """BIRD bgp_accept_originated function."""
135 return f"""\
136 # Accept originated routes
137 function bgp_accept_originated(string filter_name) -> bool {{
138 if (!{self.is_originated()} || {self.is_blackhole()} || {self.functions.is_default()}) then return false;
139 if DEBUG then print filter_name,
140 " [bgp_accept_originated] Accepting originated route ", {self.functions.route_info()};
141 accept;
142 }}"""
144 @BirdFunction("bgp_accept_originated_default")
145 def accept_originated_default(self, *args: Any) -> str: # pylint: disable=unused-argument
146 """BIRD bgp_accept_originated_default function."""
148 return f"""\
149 # Accept originated default routes
150 function bgp_accept_originated_default(string filter_name) -> bool {{
151 if (!{self.is_originated()} || {self.is_blackhole()} || !{self.functions.is_default()}) then return false;
152 if DEBUG then print filter_name,
153 " [bgp_accept_originated_default] Accepting originated default route ", {self.functions.route_info()};
154 accept;
155 }}"""
157 @BirdFunction("bgp_is_connected")
158 def is_connected(self, *args: Any) -> str: # pylint: disable=unused-argument
159 """BIRD bgp_is_connected function."""
161 return """\
162 # Check if this is an connected route
163 function bgp_is_connected(string filter_name) -> bool {
164 if (proto = "direct4_bgp" || proto = "direct6_bgp") then return true;
165 return false;
166 }"""
168 @BirdFunction("bgp_is_originated")
169 def is_originated(self, *args: Any) -> str: # pylint: disable=unused-argument
170 """BIRD bgp_is_originated function."""
172 return """\
173 # Check if this is an originated route
174 function bgp_is_originated(string filter_name) -> bool {
175 if (proto = "bgp_originate4" || proto = "bgp_originate6") then return true;
176 return false;
177 }"""
179 @BirdFunction("bgp_is_bgp_customer")
180 def is_bgp_customer(self, *args: Any) -> str: # pylint: disable=unused-argument
181 """BIRD bgp_is_bgp_customer function."""
183 return """\
184 # Check if this is a route that originated from a customer
185 function bgp_is_bgp_customer(string filter_name) -> bool {
186 if (BGP_LC_RELATION_CUSTOMER ~ bgp_large_community) then return true;
187 return false;
188 }"""
190 @BirdFunction("bgp_is_bgp_own")
191 def is_bgp_own(self, *args: Any) -> str: # pylint: disable=unused-argument
192 """BIRD bgp_is_bgp_own function."""
194 return f"""\
195 # Check if this is a route that originated within our federation
196 function bgp_is_bgp_own(string filter_name) -> bool {{
197 if ({self.functions.is_bgp()} && BGP_LC_RELATION_OWN ~ bgp_large_community) then return true;
198 return false;
199 }}"""
201 @BirdFunction("bgp_is_bgp_peer")
202 def is_bgp_peer(self, *args: Any) -> str: # pylint: disable=unused-argument
203 """BIRD bgp_is_bgp_peer function."""
205 return """\
206 # Check if this is a route that originated from a peer
207 function bgp_is_bgp_peer(string filter_name) -> bool {
208 if (BGP_LC_RELATION_PEER ~ bgp_large_community) then return true;
209 return false;
210 }"""
212 @BirdFunction("bgp_is_bgp_peering")
213 def is_bgp_peering(self, *args: Any) -> str: # pylint: disable=unused-argument
214 """BIRD bgp_is_bgp_peering function."""
216 return f"""\
217 # Check if this is a route that originated from a peer or routeserver
218 function bgp_is_bgp_peering(string filter_name) -> bool {{
219 if ({self.is_bgp_peer()} || {self.is_bgp_routeserver()}) then return true;
220 return false;
221 }}"""
223 @BirdFunction("bgp_is_bgp_routeserver")
224 def is_bgp_routeserver(self, *args: Any) -> str: # pylint: disable=unused-argument
225 """BIRD bgp_is_bgp_routeserver function."""
227 return """\
228 # Check if this is a route that originated from a routeserver
229 function bgp_is_bgp_routeserver(string filter_name) -> bool {
230 if (BGP_LC_RELATION_ROUTESERVER ~ bgp_large_community) then return true;
231 return false;
232 }"""
234 @BirdFunction("bgp_is_bgp_transit")
235 def is_bgp_transit(self, *args: Any) -> str: # pylint: disable=unused-argument
236 """BIRD bgp_is_bgp_transit function."""
238 return """\
239 # Check if this is a route that originated from a transit peer
240 function bgp_is_bgp_transit(string filter_name) -> bool {
241 if (BGP_LC_RELATION_TRANSIT ~ bgp_large_community) then return true;
242 return false;
243 }"""
245 @BirdFunction("bgp_is_blackhole")
246 def is_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
247 """BIRD bgp_is_blackhole function."""
249 return """\
250 # Check if this is a blackhole route
251 function bgp_is_blackhole(string filter_name) -> bool {
252 if (BGP_COMMUNITY_BLACKHOLE ~ bgp_community) then return true;
253 return false;
254 }"""
256 @BirdFunction("bgp_import_kernel")
257 def import_kernel(self, *args: Any) -> str: # pylint: disable=unused-argument
258 """BIRD bgp_import_kernel function."""
260 return f"""\
261 # Import kernel routes
262 function bgp_import_kernel(string filter_name) -> bool {{
263 if (!{self.functions.is_kernel()} || dest = RTD_BLACKHOLE || {self.functions.is_default()}) then return false;
264 if DEBUG then print filter_name,
265 " [bgp_import_kernel] Importing kernel route ", {self.functions.route_info()};
266 {self.import_own(5)};
267 accept;
268 }}"""
270 @BirdFunction("bgp_import_kernel_blackhole")
271 def import_kernel_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
272 """BIRD bgp_import_kernel_blackhole function."""
274 return f"""\
275 # Import kernel blackhole routes
276 function bgp_import_kernel_blackhole(string filter_name) -> bool {{
277 if (!{self.functions.is_kernel()} || dest != RTD_BLACKHOLE || {self.functions.is_default()}) then return false;
278 if DEBUG then print filter_name,
279 " [bgp_import_kernel_blackhole] Importing kernel blackhole route ", {self.functions.route_info()};
280 {self.import_own(5)};
281 bgp_community.add(BGP_COMMUNITY_BLACKHOLE);
282 bgp_community.add(BGP_COMMUNITY_NOEXPORT);
283 accept;
284 }}"""
286 @BirdFunction("bgp_import_kernel_default")
287 def import_kernel_default(self, *args: Any) -> str: # pylint: disable=unused-argument
288 """BIRD bgp_import_kernel_default function."""
290 return f"""\
291 # Import kernel default routes
292 function bgp_import_kernel_default(string filter_name) -> bool {{
293 if (!{self.functions.is_kernel()} || dest = RTD_BLACKHOLE || !{self.functions.is_default()}) then return false;
294 if DEBUG then print filter_name,
295 " [bgp_import_kernel_default] Importing kernel default route ", {self.functions.route_info()};
296 {self.import_own(5)};
297 accept;
298 }}"""
300 @BirdFunction("bgp_import_own")
301 def import_own(self, *args: Any) -> str: # pylint: disable=unused-argument
302 """BIRD bgp_import_own function."""
304 return f"""\
305 # Import own routes
306 function bgp_import_own(string filter_name; int local_pref_cost) {{
307 if DEBUG then print filter_name,
308 " [bgp_import_own] Adding BGP_LC_RELATION_OWN to ", {self.functions.route_info()}, " with local pref ",
309 BGP_PREF_OWN - local_pref_cost;
310 # Tag route as a our own (originated and static) route
311 bgp_large_community.add(BGP_LC_RELATION_OWN);
312 # Add our internal blackhole action to originated routes
313 if ({self.is_originated()} && dest = RTD_BLACKHOLE) then {{
314 if DEBUG then print filter_name,
315 " [bgp_import_own] Adding BGP_LC_ACTION_BLACKHOLE_ORIGINATE to ", {self.functions.route_info()};
316 bgp_large_community.add(BGP_LC_ACTION_BLACKHOLE_ORIGINATE);
317 }}
318 # Set local preference
319 bgp_local_pref = BGP_PREF_OWN - local_pref_cost;
320 }}"""
322 @BirdFunction("bgp_import_static")
323 def import_static(self, *args: Any) -> str: # pylint: disable=unused-argument
324 """BIRD bgp_import_static function."""
326 return f"""\
327 # Import static routes
328 function bgp_import_static(string filter_name) -> bool {{
329 if (!{self.functions.is_static()} || dest = RTD_BLACKHOLE || {self.functions.is_default()}) then return false;
330 if DEBUG then print filter_name,
331 " [bgp_import_static] Importing static route ", {self.functions.route_info()};
332 {self.import_own(10)};
333 accept;
334 }}"""
336 @BirdFunction("bgp_import_static_blackhole")
337 def import_static_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
338 """BIRD bgp_import_static_blackhole function."""
340 return f"""\
341 # Import static blackhole routes
342 function bgp_import_static_blackhole(string filter_name) -> bool {{
343 if (!{self.functions.is_static()} || dest != RTD_BLACKHOLE || {self.functions.is_default()}) then return false;
344 if DEBUG then print filter_name,
345 " [bgp_import_static_blackhole] Importing static blackhole route ", {self.functions.route_info()};
346 {self.import_own(10)};
347 bgp_community.add(BGP_COMMUNITY_BLACKHOLE);
348 bgp_community.add(BGP_COMMUNITY_NOEXPORT);
349 accept;
350 }}"""
352 @BirdFunction("bgp_import_static_default")
353 def import_static_default(self, *args: Any) -> str: # pylint: disable=unused-argument
354 """BIRD bgp_import_static_default function."""
356 return f"""\
357 # Import static default routes
358 function bgp_import_static_default(string filter_name) -> bool {{
359 if (!{self.functions.is_static()} || dest = RTD_BLACKHOLE || !{self.functions.is_default()}) then return false;
360 if DEBUG then print filter_name,
361 " [bgp_import_static_default] Importing static default route ", {self.functions.route_info()};
362 {self.import_own(10)};
363 accept;
364 }}"""
366 @BirdFunction("bgp_peer_reject_non_targetted_blackhole")
367 def peer_reject_non_targetted_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
368 """BIRD bgp_peer_reject_non_targetted_blackhole function."""
370 return f"""\
371 # Check if we're allowing blackholes tagged with the blackhole large community
372 function bgp_peer_reject_non_targetted_blackhole(
373 string filter_name;
374 bool capable;
375 bool allow_kernel_blackhole;
376 bool allow_static_blackhole;
377 int peer_asn;
378 int type_asn
379 ) -> bool {{
380 # If this is not a route with a blackhole community, then just return false
381 if !{self.is_blackhole()} then return false;
382 # If this is a blackhole community, check if we're going to allow it
383 if (
384 # ASN based ACL
385 ((BGP_ASN, 666, peer_asn) ~ bgp_large_community || (BGP_ASN, 666, type_asn) ~ bgp_large_community) ||
386 # Kernel blackholes
387 (allow_kernel_blackhole && {self.functions.is_kernel()}) ||
388 # Static blackholes
389 (allow_static_blackhole && {self.functions.is_static()})
390 ) then {{
391 # Check if the peer is blackhole community capable
392 if (!capable) then {{
393 if DEBUG then print filter_name,
394 " [bgp_peer_reject_non_targetted_blackhole] Rejecting blackhole ", {self.functions.route_info()},
395 " due to peer not being blackhole community capable";
396 reject;
397 }}
398 # Check if we have a NOEXPORT community set, if we do strip it off")
399 if (BGP_COMMUNITY_NOEXPORT ~ bgp_community) then {{
400 if DEBUG then print filter_name,
401 " [bgp_peer_reject_non_targetted_blackhole] Removing community BGP_COMMUNITY_NOEXPORT from ",
402 {self.functions.route_info()}, " due to match on BGP blackhole advertise large community function";
403 bgp_community.delete(BGP_COMMUNITY_NOEXPORT);
404 }}
405 return true;
406 }}
407 if DEBUG then print filter_name,
408 " [bgp_peer_reject_non_targetted_blackhole] Rejecting blackhole ", {self.functions.route_info()},
409 " due to no match on BGP blackhole advertise large community function";
410 reject;
411 }}"""
413 @BirdFunction("bgp_peer_accept")
414 def peer_accept(self, *args: Any) -> str: # pylint: disable=unused-argument
415 """BIRD bgp_peer_accept function."""
417 return f"""\
418 # Accept BGP route into the main BGP table
419 function bgp_peer_accept(string filter_name) {{
420 if DEBUG then print filter_name,
421 " [bgp_peer_accept] Exporting ", {self.functions.route_info()}, " to main BGP table";
422 accept;
423 }}"""
425 @BirdFunction("bgp_peer_accept_blackhole")
426 def peer_accept_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
427 """BIRD bgp_peer_accept_blackhole function."""
429 return f"""\
430 # Accept BGP blackhole
431 function bgp_peer_accept_blackhole(string filter_name) -> bool {{
432 if !{self.is_blackhole()} then return false;
433 if DEBUG then print filter_name,
434 " [bgp_peer_accept_blackhole] Enabling blackhole for ", {self.functions.route_info()};
435 # Set destination as blackhole
436 dest = RTD_BLACKHOLE;
437 # Make sure we have our NOEXPORT community set
438 if (BGP_COMMUNITY_NOEXPORT !~ bgp_community) then bgp_community.add(BGP_COMMUNITY_NOEXPORT);
439 }}"""
441 @BirdFunction("bgp_peer_accept_blackhole_originated")
442 def peer_accept_blackhole_originated(self, *args: Any) -> str: # pylint: disable=unused-argument
443 """BIRD bgp_peer_accept_blackhole_originated function."""
445 return f"""\
446 # Origination blackhole action
447 function bgp_peer_accept_blackhole_originated(string filter_name) -> bool {{
448 if (BGP_LC_ACTION_BLACKHOLE_ORIGINATE !~ bgp_large_community) then return false;
449 if DEBUG then print filter_name,
450 " [bgp_peer_accept_blackhole_originated] Enabling origination blackhole for ",
451 {self.functions.route_info()};
452 # Set destination as blackhole
453 dest = RTD_BLACKHOLE;
454 }}"""
456 @BirdFunction("bgp_peer_communities_strip_all")
457 def peer_communities_strip_all(self, *args: Any) -> str: # pylint: disable=unused-argument
458 """BIRD bgp_peer_communities_strip_all function."""
460 return f"""\
461 # Strip all communities we could interpret internally
462 function bgp_peer_communities_strip_all(string filter_name)
463 bool stripped_community;
464 bool stripped_community_private;
465 bool stripped_lc;
466 bool stripped_lc_private;
467 {{
468 stripped_community = false;
469 stripped_community_private = false;
470 stripped_lc = false;
471 stripped_lc_private = false;
472 # Sanitize communities
473 if (bgp_community ~ BGP_COMMUNITY_STRIP_ALL) then {{
474 if DEBUG then print filter_name,
475 " [bgp_peer_communities_strip_all] Sanitizing communities for ", {self.functions.route_info()};
476 bgp_community.delete(BGP_COMMUNITY_STRIP_ALL);
477 stripped_community = true;
478 }}
479 # Sanitize large communities
480 if (bgp_large_community ~ BGP_LC_STRIP_ALL) then {{
481 if DEBUG then print filter_name,
482 " [bgp_peer_communities_strip_all] Sanitizing large communities for ", {self.functions.route_info()};
483 bgp_large_community.delete(BGP_LC_STRIP_ALL);
484 stripped_lc = true;
485 }}
486 # Sanitize private communities
487 if (bgp_community ~ BGP_COMMUNITY_STRIP_PRIVATE) then {{
488 if DEBUG then print filter_name,
489 " [bgp_peer_communities_strip_all] Sanitizing private communities for ",
490 {self.functions.route_info()};
491 bgp_community.delete(BGP_COMMUNITY_STRIP_PRIVATE);
492 stripped_community_private = true;
493 }}
494 # Sanitize private large communities
495 if (bgp_large_community ~ BGP_LC_STRIP_PRIVATE) then {{
496 if DEBUG then print filter_name,
497 " [bgp_peer_communities_strip_all] Sanitizing private large communities for ",
498 {self.functions.route_info()};
499 bgp_large_community.delete(BGP_LC_STRIP_PRIVATE);
500 stripped_lc_private = true;
501 }}
502 #
503 # Output debug info and do the actual stripping
504 #
505 if (stripped_community) then {{
506 if DEBUG then print filter_name,
507 " [bgp_peer_communities_strip_all] Adding BGP_LC_INFORMATION_STRIPPED_COMMUNITY to ",
508 {self.functions.route_info()};
509 bgp_large_community.add(BGP_LC_INFORMATION_STRIPPED_COMMUNITY);
510 }}
511 if (stripped_community_private) then {{
512 if DEBUG then print filter_name,
513 " [bgp_peer_communities_strip_all] Adding BGP_LC_INFORMATION_STRIPPED_COMMUNITY_PRIVATE to ",
514 {self.functions.route_info()};
515 bgp_large_community.add(BGP_LC_INFORMATION_STRIPPED_COMMUNITY_PRIVATE);
516 }}
517 if (stripped_lc) then {{
518 if DEBUG then print filter_name,
519 " [bgp_peer_communities_strip_all] Adding BGP_LC_INFORMATION_STRIPPED_LC to ",
520 {self.functions.route_info()};
521 bgp_large_community.add(BGP_LC_INFORMATION_STRIPPED_LC);
522 }}
523 if (stripped_lc_private) then {{
524 if DEBUG then print filter_name,
525 " [bgp_peer_communities_strip_all] Adding BGP_LC_INFORMATION_STRIPPED_LC_PRIVATE to ",
526 {self.functions.route_info()};
527 bgp_large_community.add(BGP_LC_INFORMATION_STRIPPED_LC_PRIVATE);
528 }}
529 }}"""
531 @BirdFunction("bgp_peer_communities_strip_internal")
532 def peer_communities_strip_internal(self, *args: Any) -> str: # pylint: disable=unused-argument
533 """BIRD bgp_peer_communities_strip_internal function."""
535 return f"""\
536 # Strip internal communities
537 function bgp_peer_communities_strip_internal(string filter_name)
538 bool stripped_community;
539 bool stripped_community_private;
540 bool stripped_lc;
541 bool stripped_lc_private;
542 {{
543 stripped_community = false;
544 stripped_community_private = false;
545 stripped_lc = false;
546 stripped_lc_private = false;
547 # Remove stripped communities
548 if (bgp_community ~ BGP_COMMUNITY_STRIP) then {{
549 if DEBUG then print filter_name,
550 " [bgp_peer_communities_strip_internal] Removing stripped communities from ", {self.functions.route_info()};
551 bgp_community.delete(BGP_COMMUNITY_STRIP);
552 stripped_community = true;
553 }}
554 # Remove stripped large communities
555 if (bgp_large_community ~ BGP_LC_STRIP) then {{
556 if DEBUG then print filter_name,
557 " [bgp_peer_communities_strip_internal] Removing stripped large communities from ",
558 {self.functions.route_info()};
559 bgp_large_community.delete(BGP_LC_STRIP);
560 stripped_lc = true;
561 }}
562 # Remove stripped private communities
563 if (bgp_community ~ BGP_COMMUNITY_STRIP_PRIVATE) then {{
564 if DEBUG then print filter_name,
565 " [bgp_peer_communities_strip_internal] Removing stripped private communities from ",
566 {self.functions.route_info()};
567 bgp_community.delete(BGP_COMMUNITY_STRIP_PRIVATE);
568 stripped_community_private = true;
569 }}
570 # Remove stripped private large communities
571 if (bgp_large_community ~ BGP_LC_STRIP_PRIVATE) then {{
572 if DEBUG then print filter_name,
573 " [bgp_peer_communities_strip_internal] Removing stripped private large communities from ",
574 {self.functions.route_info()};
575 bgp_large_community.delete(BGP_LC_STRIP_PRIVATE);
576 stripped_lc_private = true;
577 }}
578 #
579 # Output debug info and do the actual stripping
580 #
581 if (stripped_community) then {{
582 if DEBUG then print filter_name,
583 " [bgp_peer_communities_strip_internal] Adding BGP_LC_INFORMATION_STRIPPED_COMMUNITY to ",
584 {self.functions.route_info()};
585 bgp_large_community.add(BGP_LC_INFORMATION_STRIPPED_COMMUNITY);
586 }}
587 if (stripped_lc) then {{
588 if DEBUG then print filter_name,
589 " [bgp_peer_communities_strip_internal] Adding BGP_LC_INFORMATION_STRIPPED_COMMUNITY to ",
590 {self.functions.route_info()};
591 bgp_large_community.add(BGP_LC_INFORMATION_STRIPPED_LC);
592 }}
593 if (stripped_community_private) then {{
594 if DEBUG then print filter_name,
595 " [bgp_peer_communities_strip_internal] Adding BGP_LC_INFORMATION_STRIPPED_COMMUNITY_PRIVATE to ",
596 {self.functions.route_info()};
597 bgp_large_community.add(BGP_LC_INFORMATION_STRIPPED_COMMUNITY_PRIVATE);
598 }}
599 if (stripped_lc_private) then {{
600 if DEBUG then print filter_name,
601 " [bgp_peer_communities_strip_internal] Adding BGP_LC_INFORMATION_STRIPPED_LC_PRIVATE to ",
602 {self.functions.route_info()};
603 bgp_large_community.add(BGP_LC_INFORMATION_STRIPPED_LC_PRIVATE);
604 }}
605 }}"""
607 @BirdFunction("bgp_import_filter_asn_bogons")
608 def import_filter_asn_bogons(self, *args: Any) -> str: # pylint: disable=unused-argument
609 """BIRD bgp_import_filter_asn_bogons function."""
611 return f"""\
612 # Import filter bogon ASNs
613 function bgp_import_filter_asn_bogons(string filter_name) -> bool {{
614 if (bgp_path !~ BOGON_ASNS) then return false;
615 if DEBUG then print filter_name,
616 " [bgp_import_filter_asn_bogons] Adding BGP_LC_FILTERED_BOGON_ASN to ", {self.functions.route_info()};
617 bgp_large_community.add(BGP_LC_FILTERED_BOGON_ASN);
618 }}"""
620 @BirdFunction("bgp_import_filter_asn_invalid")
621 def import_filter_asn_invalid(self, *args: Any) -> str: # pylint: disable=unused-argument
622 """BIRD bgp_import_filter_asn_invalid function."""
624 return f"""\
625 # Import filter peer ASN != route first ASN
626 function bgp_import_filter_asn_invalid(string filter_name; int peer_asn) -> bool {{
627 if (bgp_path.first = peer_asn) then return false;
628 if DEBUG then print filter_name,
629 " [bgp_import_filter_asn_invalid] Adding BGP_LC_FILTERED_FIRST_AS_NOT_PEER_AS to ",
630 {self.functions.route_info()};
631 bgp_large_community.add(BGP_LC_FILTERED_FIRST_AS_NOT_PEER_AS);
632 }}"""
634 @BirdFunction("bgp_import_filter_aspath_allow")
635 def import_filter_aspath_allow(self, *args: Any) -> str: # pylint: disable=unused-argument
636 """BIRD bgp_import_filter_aspath_allow function."""
638 return f"""\
639 function bgp_import_filter_aspath_allow(string filter_name; int set asn_list) -> bool {{
640 if (bgp_path = filter(bgp_path, asn_list)) then return false;
641 if (bgp_large_community ~ [BGP_LC_FILTERED_ORIGIN_AS, BGP_LC_FILTERED_PEER_AS]) then return false;
642 if DEBUG then print filter_name,
643 " [bgp_import_filter_aspath_allow] Adding BGP_LC_FILTERED_ASPATH_NOT_ALLOWED to ",
644 {self.functions.route_info()};
645 bgp_large_community.add(BGP_LC_FILTERED_ASPATH_NOT_ALLOWED);
646 }}"""
648 @BirdFunction("bgp_import_filter_aspath_deny")
649 def import_filter_aspath_deny(self, *args: Any) -> str: # pylint: disable=unused-argument
650 """BIRD bgp_import_filter_aspath_deny function."""
652 return f"""\
653 function bgp_import_filter_aspath_deny(string filter_name; int set asn_list) -> bool {{
654 if (bgp_path !~ asn_list) then return false;
655 if (bgp_large_community ~ [BGP_LC_FILTERED_ORIGIN_AS, BGP_LC_FILTERED_PEER_AS]) then return false;
656 if DEBUG then print filter_name,
657 " [bgp_import_filter_aspath_deny] Adding BGP_LC_FILTERED_ASPATH_NOT_ALLOWED to ",
658 {self.functions.route_info()};
659 bgp_large_community.add(BGP_LC_FILTERED_ASPATH_NOT_ALLOWED);
660 }}"""
662 @BirdFunction("bgp_import_filter_deny_aspath")
663 def import_filter_deny_aspath(self, *args: Any) -> str: # pylint: disable=unused-argument
664 """BIRD bgp_import_filter_deny_aspath function."""
666 return f"""\
667 function bgp_import_filter_deny_aspath(string filter_name; int set asn_list) -> bool {{
668 if (bgp_path !~ asn_list) then return false;
669 if (bgp_large_community ~ [BGP_LC_FILTERED_ORIGIN_AS, BGP_LC_FILTERED_PEER_AS]) then return false;
670 if DEBUG then print filter_name,
671 " [bgp_import_filter_deny_aspath] Adding BGP_LC_FILTERED_DENY_ASPATH to ",
672 {self.functions.route_info()};
673 bgp_large_community.add(BGP_LC_FILTERED_DENY_ASPATH);
674 }}"""
676 @BirdFunction("bgp_import_filter_asn_private")
677 def import_filter_asn_private(self, *args: Any) -> str: # pylint: disable=unused-argument
678 """BIRD bgp_import_filter_asn_private function."""
680 return f"""\
681 # Import filter private ASN's
682 function bgp_import_filter_asn_private(string filter_name; int set allowed_asns) -> bool {{
683 if (bgp_path = filter(bgp_path, allowed_asns)) then return false;
684 if DEBUG then print filter_name,
685 " [bgp_import_filter_asn_private] Adding BGP_LC_FILTERED_ASPATH_NOT_ALLOWED to ",
686 {self.functions.route_info()};
687 bgp_large_community.add(BGP_LC_FILTERED_ASPATH_NOT_ALLOWED);
688 }}"""
690 @BirdFunction("bgp_import_filter_asn_transit")
691 def import_filter_asn_transit(self, *args: Any) -> str: # pylint: disable=unused-argument
692 """BIRD bgp_import_filter_asn_transit function."""
694 return f"""\
695 # Import filter transit free ASNs
696 function bgp_import_filter_asn_transit(string filter_name) -> bool {{
697 if (bgp_path !~ BGP_ASNS_TRANSIT) then return false;
698 if DEBUG then print filter_name,
699 " [bgp_import_filter_asn_transit] Adding BGP_LC_FILTERED_TRANSIT_FREE_ASN to ",
700 {self.functions.route_info()};
701 bgp_large_community.add(BGP_LC_FILTERED_TRANSIT_FREE_ASN);
702 }}"""
704 @BirdFunction("bgp_import_filter_asns_allow")
705 def import_filter_asns_allow(self, *args: Any) -> str: # pylint: disable=unused-argument
706 """BIRD bgp_import_filter_asns_allow function."""
708 return f"""\
709 # Import filter peer ASNs (ALLOW list)
710 function bgp_import_filter_asns_allow(string filter_name; int set asns) -> bool {{
711 if (bgp_path.first ~ asns) then return false;
712 if DEBUG then print filter_name,
713 " [bgp_import_filter_asns_allow] Adding BGP_LC_FILTERED_PEER_AS to ", {self.functions.route_info()};
714 bgp_large_community.add(BGP_LC_FILTERED_PEER_AS);
715 }}"""
717 @BirdFunction("bgp_import_filter_asns_deny")
718 def import_filter_asns_deny(self, *args: Any) -> str: # pylint: disable=unused-argument
719 """BIRD bgp_import_filter_asns_deny function."""
721 return f"""\
722 # Import filter peer ASNs (DENY list)
723 function bgp_import_filter_asns_deny(string filter_name; int set asns) -> bool {{
724 if (bgp_path.first !~ asns) then return false;
725 if DEBUG then print filter_name,
726 " [bgp_import_filter_asns_deny] Adding BGP_LC_FILTERED_PEER_AS to ", {self.functions.route_info()};
727 bgp_large_community.add(BGP_LC_FILTERED_PEER_AS);
728 }}"""
730 @BirdFunction("bgp_import_filter_aspath_length")
731 def import_filter_aspath_length(self, *args: Any) -> str: # pylint: disable=unused-argument
732 """BIRD bgp_import_filter_aspath_length function."""
734 return f"""\
735 # Import filter AS-PATH length
736 function bgp_import_filter_aspath_length(string filter_name; int aspath_maxlen; int aspath_minlen) {{
737 if (bgp_path.len > aspath_maxlen) then {{
738 if DEBUG then print filter_name,
739 " [bgp_import_filter_aspath_length] AS-PATH length >", aspath_maxlen,
740 ", adding BGP_LC_FILTERED_ASPATH_TOO_LONG to ", {self.functions.route_info()};
741 bgp_large_community.add(BGP_LC_FILTERED_ASPATH_TOO_LONG);
742 }}
743 if (bgp_path.len < aspath_minlen) then {{
744 if DEBUG then print filter_name,
745 " [bgp_import_filter_aspath_length] AS-PATH length <", aspath_minlen,
746 ", adding BGP_LC_FILTERED_ASPATH_TOO_SHORT to ", {self.functions.route_info()};
747 bgp_large_community.add(BGP_LC_FILTERED_ASPATH_TOO_SHORT);
748 }}
749 }}"""
751 @BirdFunction("bgp_import_filter_blackhole")
752 def import_filter_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
753 """BIRD bgp_import_filter_blackhole function."""
755 return f"""\
756 # Import filter blackhole routes
757 function bgp_import_filter_blackhole(string filter_name) -> bool {{
758 if !{self.is_blackhole()} then return false;
759 if DEBUG then print filter_name,
760 " [bgp_import_filter_blackhole] Adding BGP_LC_FILTERED_BLACKHOLE_NOT_ALLOWED to ",
761 {self.functions.route_info()};
762 bgp_large_community.add(BGP_LC_FILTERED_BLACKHOLE_NOT_ALLOWED);
763 }}"""
765 @BirdFunction("bgp_import_filter_blackhole_size")
766 def import_filter_blackhole_size(self, *args: Any) -> str: # pylint: disable=unused-argument
767 """BIRD bgp_import_filter_blackhole_size function."""
769 return f"""\
770 # Import filter blackhole size
771 function bgp_import_filter_blackhole_size(
772 string filter_name;
773 int ipv4_maxlen; int ipv4_minlen;
774 int ipv6_maxlen; int ipv6_minlen
775 ) -> bool
776 int prefix_maxlen;
777 int prefix_minlen;
778 {{
779 # Work out what prefix lenghts we're going to use
780 if (net.type = NET_IP4) then {{
781 prefix_maxlen = ipv4_maxlen;
782 prefix_minlen = ipv4_minlen;
783 }}
784 if (net.type = NET_IP6) then {{
785 prefix_maxlen = ipv6_maxlen;
786 prefix_minlen = ipv6_minlen;
787 }}
788 # If this is not a blackhole then just return
789 if !{self.is_blackhole()} then return false;
790 # Check prefix is not longer than what we allow
791 if {self.functions.prefix_is_longer(BirdVariable("prefix_maxlen"))} then {{
792 if DEBUG then print filter_name,
793 " [bgp_filter_prefix_size] Blackhole length >", prefix_maxlen,
794 ", adding BGP_FILTERED_BLACKHOLE_LEN_TOO_LONG to ", {self.functions.route_info()};
795 bgp_large_community.add(BGP_LC_FILTERED_BLACKHOLE_LEN_TOO_LONG);
796 }}
797 # Check prefix is not shorter than what we allow
798 if {self.functions.prefix_is_shorter(BirdVariable("prefix_minlen"))} then {{
799 if DEBUG then print filter_name,
800 " [bgp_filter_prefix_size] Blackhole length <", prefix_minlen,
801 ", adding BGP_FILTERED_BLACKHOLE_LEN_TOO_SHORT to ", {self.functions.route_info()};
802 bgp_large_community.add(BGP_LC_FILTERED_BLACKHOLE_LEN_TOO_SHORT);
803 }}
804 }}"""
806 @BirdFunction("bgp_import_filter_bogons")
807 def import_filter_bogons(self, *args: Any) -> str: # pylint: disable=unused-argument
808 """BIRD bgp_import_filter_bogons function."""
810 return f"""\
811 # Import filter bogons
812 function bgp_import_filter_bogons(string filter_name) -> bool {{
813 if !{self.functions.is_bogon()} then return false;
814 if DEBUG then print filter_name,
815 " [bgp_import_filter_bogons] Adding BGP_FILTERED_BOGON to ", {self.functions.route_info()};
816 bgp_large_community.add(BGP_LC_FILTERED_BOGON);
817 }}"""
819 @BirdFunction("bgp_import_filter_community_lengths")
820 def import_filter_community_lengths(self, *args: Any) -> str: # pylint: disable=unused-argument
821 """BIRD bgp_import_filter_community_lengths function."""
823 return f"""\
824 # Import filter too many communities
825 function bgp_import_filter_community_lengths(
826 string filter_name;
827 int community_maxlen;
828 int ext_maxlen;
829 int large_maxlen
830 ) {{
831 if (bgp_community.len > community_maxlen) then {{
832 if DEBUG then print filter_name,
833 " [bgp_import_filter_community_lengths] Community list length >", community_maxlen,
834 ", adding BGP_LC_FILTERED_TOO_MANY_COMMUNITIES to ", {self.functions.route_info()},
835 " counted ", bgp_community.len;
836 bgp_large_community.add(BGP_LC_FILTERED_TOO_MANY_COMMUNITIES);
837 }}
838 if (bgp_ext_community.len > ext_maxlen) then {{
839 if DEBUG then print filter_name,
840 " [bgp_import_filter_community_lengths] Extended community list length >", ext_maxlen,
841 ", adding BGP_LC_FILTERED_TOO_MANY_EXTENDED_COMMUNITIES to ", {self.functions.route_info()},
842 " counted ", bgp_ext_community.len;
843 bgp_large_community.add(BGP_LC_FILTERED_TOO_MANY_EXTENDED_COMMUNITIES);
844 }}
845 if (bgp_large_community.len > large_maxlen) then {{
846 if DEBUG then print filter_name,
847 " [bgp_import_filter_community_lengths] Large community list length >", large_maxlen,
848 ", adding BGP_LC_FILTERED_TOO_MANY_LARGE_COMMUNITIES to ", {self.functions.route_info()},
849 " counted ", bgp_large_community.len;
850 bgp_large_community.add(BGP_LC_FILTERED_TOO_MANY_LARGE_COMMUNITIES);
851 }}
852 }}"""
854 @BirdFunction("bgp_import_filter_customer_blackhole")
855 def import_filter_customer_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
856 """BIRD bgp_import_filter_customer_blackhole function."""
858 return f"""\
859 # Import filter customer blackhole routes
860 function bgp_import_filter_customer_blackhole(string filter_name) -> bool {{
861 if (!{self.is_blackhole()} || !{self.is_bgp_customer()}) then return false;
862 if DEBUG then print filter_name,
863 " [bgp_import_filter_customer_blackhole] Adding BGP_LC_FILTERED_BLACKHOLE_NOT_ALLOWED to ",
864 {self.functions.route_info()};
865 bgp_large_community.add(BGP_LC_FILTERED_BLACKHOLE_NOT_ALLOWED);
866 accept;
867 }}"""
869 @BirdFunction("bgp_import_filter_default")
870 def import_filter_default(self, *args: Any) -> str: # pylint: disable=unused-argument
871 """BIRD bgp_import_filter_default function."""
873 return f"""\
874 # Import filter default routes
875 function bgp_import_filter_default(string filter_name) -> bool {{
876 if !{self.functions.is_default()} then return false;
877 if DEBUG then print filter_name,
878 " [bgp_import_filter_default] Adding BGP_LC_FILTERED_DEFAULT_NOT_ALLOWED to ", {self.functions.route_info()};
879 bgp_large_community.add(BGP_LC_FILTERED_DEFAULT_NOT_ALLOWED);
880 accept;
881 }}"""
883 @BirdFunction("bgp_import_filter_invalid_blackhole")
884 def import_filter_invalid_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
885 """BIRD bgp_import_filter_invalid_blackhole function."""
887 return f"""\
888 # Import filter invalid blackhole routes
889 function bgp_import_filter_invalid_blackhole(string filter_name) -> bool {{
890 if (!{self.is_blackhole()} || {self.is_bgp_customer()} || {self.is_bgp_own()}) then return false;
891 if DEBUG then print filter_name,
892 " [bgp_import_filter_invalid_blackhole] Adding BGP_LC_FILTERED_BLACKHOLE_NOT_ALLOWED to ",
893 {self.functions.route_info()};
894 bgp_large_community.add(BGP_LC_FILTERED_BLACKHOLE_NOT_ALLOWED);
895 accept;
896 }}"""
898 @BirdFunction("bgp_import_filter_invalid_default")
899 def import_filter_invalid_default(self, *args: Any) -> str: # pylint: disable=unused-argument
900 """BIRD bgp_import_filter_invalid_default function."""
902 return f"""\
903 # Import filter invalid default routes
904 function bgp_import_filter_invalid_default(string filter_name) -> bool {{
905 if (!{self.functions.is_default()} || {self.is_bgp_own()} || {self.is_bgp_transit()}) then return false;
906 if DEBUG then print filter_name,
907 " [bgp_import_filter_invalid_default] Adding BGP_LC_FILTERED_DEFAULT_NOT_ALLOWED to ",
908 {self.functions.route_info()};
909 bgp_large_community.add(BGP_LC_FILTERED_DEFAULT_NOT_ALLOWED);
910 accept;
911 }}"""
913 @BirdFunction("bgp_import_filter_lc_no_relation")
914 def import_filter_lc_no_relation(self, *args: Any) -> str: # pylint: disable=unused-argument
915 """BIRD bgp_import_filter_lc_no_relation function."""
917 return f"""\
918 # Import filter prefixes without a large community relation set
919 function bgp_import_filter_lc_no_relation(string filter_name) -> bool {{
920 if (bgp_large_community ~ BGP_LC_RELATION) then return false;
921 if DEBUG then print filter_name,
922 " [bgp_import_filter_lc_no_relation] Adding BGP_LC_FILTERED_NO_RELATION_LC to ", {self.functions.route_info()};
923 bgp_large_community.add(BGP_LC_FILTERED_NO_RELATION_LC);
924 }}"""
926 @BirdFunction("bgp_import_filter_nexthop_not_peerip")
927 def import_filter_nexthop_not_peerip(self, *args: Any) -> str: # pylint: disable=unused-argument
928 """BIRD bgp_import_filter_nexthop_not_peerip function."""
930 return f"""\
931 # Import filter peer != next_hop
932 function bgp_import_filter_nexthop_not_peerip(string filter_name) -> bool {{
933 if (from = bgp_next_hop) then return false;
934 if DEBUG then print filter_name,
935 " [bgp_import_filter_nexthop_not_peerip] Adding BGP_LC_FILTERED_NEXT_HOP_NOT_PEER_IP to ",
936 {self.functions.route_info()};
937 bgp_large_community.add(BGP_LC_FILTERED_NEXT_HOP_NOT_PEER_IP);
938 }}"""
940 @BirdFunction("bgp_import_filter_origin_asns_allow")
941 def import_filter_origin_asns_allow(self, *args: Any) -> str: # pylint: disable=unused-argument
942 """BIRD bgp_import_filter_origin_asns_allow function."""
944 return f"""\
945 # Import filter origin ASNs (ALLOW list)
946 function bgp_import_filter_origin_asns_allow(string filter_name; int set asns) -> bool {{
947 if (bgp_path.last_nonaggregated ~ asns) then return false;
948 if DEBUG then print filter_name,
949 " [bgp_import_filter_origin_asns_allow] Adding BGP_LC_FILTERED_ORIGIN_AS to ", {self.functions.route_info()};
950 bgp_large_community.add(BGP_LC_FILTERED_ORIGIN_AS);
951 }}"""
953 @BirdFunction("bgp_export_filter_origin_asns")
954 def export_filter_origin_asns(self, *args: Any) -> str: # pylint: disable=unused-argument
955 """BIRD bgp_export_filter_origin_asns function."""
957 return f"""\
958 # Export filter origin ASNs
959 function bgp_export_filter_origin_asns(string filter_name; int set asns) -> bool {{
960 if (bgp_path.last_nonaggregated !~ asns) then return false;
961 if DEBUG then print filter_name,
962 " [bgp_export_filter_origin_asns] Dropping origin ASN filtered route ", {self.functions.route_info()};
963 return true;
964 }}"""
966 @BirdFunction("bgp_import_filter_origin_asns_deny")
967 def import_filter_origin_asns_deny(self, *args: Any) -> str: # pylint: disable=unused-argument
968 """BIRD bgp_import_filter_origin_asns_deny function."""
970 return f"""\
971 # Import filter origin ASNs (DENY list)
972 function bgp_import_filter_origin_asns_deny(string filter_name; int set asns) -> bool {{
973 if (bgp_path.last_nonaggregated !~ asns) then return false;
974 if DEBUG then print filter_name,
975 " [bgp_import_filter_origin_asns_deny] Adding BGP_LC_FILTERED_ORIGIN_AS to ", {self.functions.route_info()};
976 bgp_large_community.add(BGP_LC_FILTERED_ORIGIN_AS);
977 }}"""
979 @BirdFunction("bgp_import_filter_deny_origin_asns")
980 def import_filter_deny_origin_asns(self, *args: Any) -> str: # pylint: disable=unused-argument
981 """BIRD bgp_import_filter_deny_origin_asns function."""
983 return f"""\
984 # Import filter origin ASNs (import_filter_deny)
985 function bgp_import_filter_deny_origin_asns(string filter_name; int set asns) -> bool {{
986 if (bgp_path.last_nonaggregated !~ asns) then return false;
987 if DEBUG then print filter_name,
988 " [bgp_import_filter_deny_origin_asns] Adding BGP_LC_FILTERED_DENY_ORIGIN_AS to ",
989 {self.functions.route_info()};
990 bgp_large_community.add(BGP_LC_FILTERED_DENY_ORIGIN_AS);
991 }}"""
993 @BirdFunction("bgp_import_filter_own_blackhole")
994 def import_filter_own_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
995 """BIRD bgp_import_filter_own_blackhole function."""
997 return f"""\
998 # Import filter own blackhole routes
999 function bgp_import_filter_own_blackhole(string filter_name) -> bool {{
1000 if (!{self.is_blackhole()} || !{self.is_bgp_own()}) then return false;
1001 if DEBUG then print filter_name,
1002 " [bgp_import_filter_own_blackhole] Adding BGP_LC_FILTERED_BLACKHOLE_NOT_ALLOWED to ",
1003 {self.functions.route_info()};
1004 bgp_large_community.add(BGP_LC_FILTERED_BLACKHOLE_NOT_ALLOWED);
1005 accept;
1006 }}"""
1008 @BirdFunction("bgp_import_filter_own_default")
1009 def import_filter_own_default(self, *args: Any) -> str: # pylint: disable=unused-argument
1010 """BIRD bgp_import_filter_own_default function."""
1012 return f"""\
1013 # Import filter own default routes
1014 function bgp_import_filter_own_default(string filter_name) -> bool {{
1015 if (!{self.functions.is_default()} || !{self.is_bgp_own()}) then return false;
1016 if DEBUG then print filter_name,
1017 " [bgp_import_filter_own_default] Adding BGP_LC_FILTERED_DEFAULT_NOT_ALLOWED to ",
1018 {self.functions.route_info()};
1019 bgp_large_community.add(BGP_LC_FILTERED_DEFAULT_NOT_ALLOWED);
1020 accept;
1021 }}"""
1023 @BirdFunction("bgp_import_filter_prefix_size")
1024 def import_filter_prefix_size(self, *args: Any) -> str: # pylint: disable=unused-argument
1025 """BIRD bgp_import_filter_prefix_size function."""
1027 return f"""\
1028 # Import filter prefix size
1029 function bgp_import_filter_prefix_size(
1030 string filter_name;
1031 int ipv4_maxlen; int ipv4_minlen;
1032 int ipv6_maxlen; int ipv6_minlen
1033 ) -> bool
1034 int prefix_maxlen;
1035 int prefix_minlen;
1036 {{
1037 # Work out what prefix lenghts we're going to use
1038 if (net.type = NET_IP4) then {{
1039 prefix_maxlen = ipv4_maxlen;
1040 prefix_minlen = ipv4_minlen;
1041 }}
1042 if (net.type = NET_IP6) then {{
1043 prefix_maxlen = ipv6_maxlen;
1044 prefix_minlen = ipv6_minlen;
1045 }}
1046 # If this is a blackhole prefix then just return, it will be caught later
1047 if {self.is_blackhole()} then return false;
1048 # Check prefix length is within the range we allow
1049 if {self.functions.prefix_is_longer(BirdVariable("prefix_maxlen"))} then {{
1050 if DEBUG then print filter_name,
1051 " [bgp_import_filter_prefix_size] Prefix length >", prefix_maxlen,
1052 ", adding BGP_FILTERED_PREFIX_LEN_TOO_LONG to ", {self.functions.route_info()};
1053 bgp_large_community.add(BGP_LC_FILTERED_PREFIX_LEN_TOO_LONG);
1054 }}
1055 # Check prefix length is within the range we allow
1056 if {self.functions.prefix_is_shorter(BirdVariable("prefix_minlen"))} then {{
1057 if DEBUG then print filter_name,
1058 " [bgp_import_filter_prefix_size] Prefix length <", prefix_minlen,
1059 ", adding BGP_FILTERED_PREFIX_LEN_TOO_SHORT to ", {self.functions.route_info()};
1060 bgp_large_community.add(BGP_LC_FILTERED_PREFIX_LEN_TOO_SHORT);
1061 }}
1062 }}"""
1064 @BirdFunction("bgp_import_filter_prefixes_allow")
1065 def import_filter_prefixes_allow(self, *args: Any) -> str: # pylint: disable=unused-argument
1066 """BIRD bgp_import_filter_prefixes_allow function."""
1068 return f"""\
1069 # Import filter prefixes (ALLOW)
1070 function bgp_import_filter_prefixes_allow(
1071 string filter_name;
1072 prefix set prefix_list4; prefix set prefix_list6
1073 ) -> bool {{
1074 if {self.is_blackhole()} then return false;
1075 if (net.type = NET_IP4 && net ~ prefix_list4) then return false;
1076 if (net.type = NET_IP6 && net ~ prefix_list6) then return false;
1077 if DEBUG then print filter_name,
1078 " [bgp_import_filter_prefixes_allow] Adding BGP_LC_FILTERED_PREFIX_FILTERED to ", {self.functions.route_info()};
1079 bgp_large_community.add(BGP_LC_FILTERED_PREFIX_FILTERED);
1080 }}"""
1082 @BirdFunction("bgp_import_filter_prefixes_deny")
1083 def import_filter_prefixes_deny(self, *args: Any) -> str: # pylint: disable=unused-argument
1084 """BIRD bgp_import_filter_prefixes_deny function."""
1086 return f"""\
1087 # Import filter prefixes (DENY)
1088 function bgp_import_filter_prefixes_deny(
1089 string filter_name;
1090 prefix set prefix_list4; prefix set prefix_list6
1091 ) -> bool {{
1092 if {self.is_blackhole()} then return false;
1093 if (net.type = NET_IP4 && net !~ prefix_list4) then return false;
1094 if (net.type = NET_IP6 && net !~ prefix_list6) then return false;
1095 if DEBUG then print filter_name,
1096 " [bgp_import_filter_prefixes_deny] Adding BGP_LC_FILTERED_PREFIX_FILTERED to ", {self.functions.route_info()};
1097 bgp_large_community.add(BGP_LC_FILTERED_PREFIX_FILTERED);
1098 }}"""
1100 @BirdFunction("bgp_import_filter_deny_prefixes")
1101 def import_filter_deny_prefixes(self, *args: Any) -> str: # pylint: disable=unused-argument
1102 """BIRD bgp_import_filter_deny_prefixes function."""
1104 return f"""\
1105 # Import filter prefixes (DENY)
1106 function bgp_import_filter_deny_prefixes(
1107 string filter_name;
1108 prefix set prefix_list4; prefix set prefix_list6
1109 ) -> bool {{
1110 if {self.is_blackhole()} then return false;
1111 if (net.type = NET_IP4 && net !~ prefix_list4) then return false;
1112 if (net.type = NET_IP6 && net !~ prefix_list6) then return false;
1113 if DEBUG then print filter_name,
1114 " [bgp_import_filter_deny_prefixes] Adding BGP_LC_FILTERED_DENY_PREFIX to ", {self.functions.route_info()};
1115 bgp_large_community.add(BGP_LC_FILTERED_DENY_PREFIX);
1116 }}"""
1118 @BirdFunction("bgp_export_filter_prefixes")
1119 def export_filter_prefixes(self, *args: Any) -> str: # pylint: disable=unused-argument
1120 """BIRD bgp_export_filter_prefixes function."""
1122 return f"""\
1123 # Export filter prefixes
1124 function bgp_export_filter_prefixes(
1125 string filter_name;
1126 prefix set prefix_list4; prefix set prefix_list6
1127 ) -> bool {{
1128 if (net.type = NET_IP4 && net !~ prefix_list4) then return false;
1129 if (net.type = NET_IP6 && net !~ prefix_list6) then return false;
1130 if DEBUG then print filter_name,
1131 " [bgp_export_filter_prefixes] Dropping filtered route ", {self.functions.route_info()};
1132 return true;
1133 }}"""
1135 @BirdFunction("bgp_import_filter_prefixes_blackhole_allow")
1136 def import_filter_prefixes_blackhole_allow(self, *args: Any) -> str: # pylint: disable=unused-argument
1137 """BIRD bgp_import_filter_prefixes_blackhole_allow function."""
1139 return f"""\
1140 # Import filter prefixes blackholes (ALLOW)
1141 function bgp_import_filter_prefixes_blackhole_allow(
1142 string filter_name;
1143 prefix set prefix_list4; prefix set prefix_list6
1144 ) -> bool {{
1145 if !{self.is_blackhole()} then return false;
1146 if (net.type = NET_IP4 && net ~ prefix_list4) then return false;
1147 if (net.type = NET_IP6 && net ~ prefix_list6) then return false;
1148 if DEBUG then print filter_name,
1149 " [bgp_import_filter_prefixes_blackhole_allow] Adding BGP_LC_FILTERED_PREFIX_FILTERED, ",
1150 "BGP_LC_FILTERED_BLACKHOLE_NOT_ALLOWED to ",
1151 {self.functions.route_info()};
1152 bgp_large_community.add(BGP_LC_FILTERED_PREFIX_FILTERED);
1153 bgp_large_community.add(BGP_LC_FILTERED_BLACKHOLE_NOT_ALLOWED);
1154 }}"""
1156 @BirdFunction("bgp_import_filter_prefixes_blackhole_deny")
1157 def import_filter_prefixes_blackhole_deny(self, *args: Any) -> str: # pylint: disable=unused-argument
1158 """BIRD bgp_import_filter_prefixes_blackhole_deny function."""
1160 return f"""\
1161 # Import filter blackholes (DENY)
1162 function bgp_import_filter_prefixes_blackhole_deny(
1163 string filter_name;
1164 prefix set prefix_list4; prefix set prefix_list6
1165 ) -> bool {{
1166 if !{self.is_blackhole()} then return false;
1167 if (net.type = NET_IP4 && net !~ prefix_list4) then return false;
1168 if (net.type = NET_IP6 && net !~ prefix_list6) then return false;
1169 if DEBUG then print filter_name,
1170 " [bgp_import_filter_prefixes_blackhole_deny] Adding BGP_LC_FILTERED_PREFIX_FILTERED, ",
1171 "BGP_LC_FILTERED_BLACKHOLE_NOT_ALLOWED to ",
1172 {self.functions.route_info()};
1173 bgp_large_community.add(BGP_LC_FILTERED_PREFIX_FILTERED);
1174 bgp_large_community.add(BGP_LC_FILTERED_BLACKHOLE_NOT_ALLOWED);
1175 }}"""
1177 @BirdFunction("bgp_import_filter_routecollector_all")
1178 def import_filter_routecollector_all(self, *args: Any) -> str: # pylint: disable=unused-argument
1179 """BIRD bgp_import_filter_routecollector_all function."""
1181 return f"""\
1182 # Import filter all incoming routecollector routes
1183 function bgp_import_filter_routecollector_all(string filter_name) {{
1184 if DEBUG then print filter_name,
1185 " [bgp_peer_import_routecollector] Adding BGP_FILTERED_ROUTECOLLECTOR to ", {self.functions.route_info()};
1186 bgp_large_community.add(BGP_LC_FILTERED_ROUTECOLLECTOR);
1187 }}"""
1189 @BirdFunction("bgp_import_filter_transit_default")
1190 def import_filter_transit_default(self, *args: Any) -> str: # pylint: disable=unused-argument
1191 """BIRD bgp_import_filter_transit_default function."""
1193 return f"""\
1194 # Import filter default route
1195 function bgp_import_filter_transit_default(string filter_name) -> bool {{
1196 if (!{self.functions.is_default()} || !{self.is_bgp_transit()}) then return false;
1197 if DEBUG then print filter_name,
1198 " [bgp_import_filter_transit_default] Adding BGP_LC_FILTERED_DEFAULT_NOT_ALLOWED to ",
1199 {self.functions.route_info()};
1200 bgp_large_community.add(BGP_LC_FILTERED_DEFAULT_NOT_ALLOWED);
1201 accept;
1202 }}"""
1204 @BirdFunction("bgp_peer_graceful_shutdown")
1205 def peer_graceful_shutdown(self, *args: Any) -> str: # pylint: disable=unused-argument
1206 """BIRD bgp_peer_graceful_shutdown function."""
1208 return f"""\
1209 # Enable graceful shutdown
1210 function bgp_peer_graceful_shutdown(string filter_name) {{
1211 if DEBUG then print filter_name,
1212 " [peer_graceful_shutdown] Adding GRACEFUL_SHUTDOWN community to ", {self.functions.route_info()};
1213 bgp_community.add(BGP_COMMUNITY_GRACEFUL_SHUTDOWN);
1214 }}"""
1216 @BirdFunction("bgp_peer_import_customer")
1217 def peer_import_customer(self, *args: Any) -> str: # pylint: disable=unused-argument
1218 """BIRD bgp_peer_import_customer function."""
1220 return f"""\
1221 # Import customer routes
1222 function bgp_peer_import_customer(string filter_name; int peer_asn; int local_pref_cost) {{
1223 if DEBUG then print filter_name,
1224 " [bgp_peer_import_customer] Adding BGP_LC_RELATION_CUSTOMER to ", {self.functions.route_info()},
1225 " with local pref ", BGP_PREF_CUSTOMER - local_pref_cost;
1226 # Tag route as a customer route
1227 bgp_large_community.add(BGP_LC_RELATION_CUSTOMER);
1228 # Set local preference
1229 bgp_local_pref = BGP_PREF_CUSTOMER - local_pref_cost;
1230 }}"""
1232 @BirdFunction("bgp_peer_import_graceful_shutdown")
1233 def peer_import_graceful_shutdown(self, *args: Any) -> str: # pylint: disable=unused-argument
1234 """BIRD bgp_peer_import_graceful_shutdown function."""
1236 return f"""\
1237 # Import a graceful shutdown prefix
1238 function bgp_peer_import_graceful_shutdown(string filter_name) -> bool {{
1239 if (BGP_COMMUNITY_GRACEFUL_SHUTDOWN !~ bgp_community) then return false;
1240 if DEBUG then print filter_name,
1241 " [bgp_peer_import_graceful_shutdown] Setting LOCAL_PREF to 0 for ", {self.functions.route_info()};
1242 bgp_local_pref = 0;
1243 }}"""
1245 @BirdFunction("bgp_peer_import_location_iso3166")
1246 def peer_import_location_iso3166(self, *args: Any) -> str: # pylint: disable=unused-argument
1247 """BIRD bgp_peer_import_location_iso3166 function."""
1249 return f"""\
1250 # Location-based prefix importing (ISO-3166 country codes)
1251 function bgp_peer_import_location_iso3166(string filter_name; int location) {{
1252 if DEBUG then print filter_name,
1253 " [bgp_peer_import_location_iso3166] Adding BGP_LC_FUNCTION_LOCATION_ISO3166 with ", location, " to ",
1254 {self.functions.route_info()};
1255 bgp_large_community.add((BGP_ASN, BGP_LC_FUNCTION_LOCATION_ISO3166, location));
1256 }}"""
1258 @BirdFunction("bgp_peer_import_location_unm49")
1259 def peer_import_location_unm49(self, *args: Any) -> str: # pylint: disable=unused-argument
1260 """BIRD bgp_peer_import_location_unm49 function."""
1262 return f"""\
1263 # Location-based prefix importing (UN.M49 country codes)
1264 function bgp_peer_import_location_unm49(string filter_name; int location) {{
1265 if DEBUG then print filter_name,
1266 " [bgp_peer_import_location_unm49] Adding BGP_LC_FUNCTION_LOCATION_UNM49 with ", location, " to ",
1267 {self.functions.route_info()};
1268 bgp_large_community.add((BGP_ASN, BGP_LC_FUNCTION_LOCATION_UNM49, location));
1269 }}"""
1271 # Local pref manipulation
1272 @BirdFunction("bgp_peer_import_localpref")
1273 def peer_import_localpref(self, *args: Any) -> str: # pylint: disable=unused-argument
1274 """BIRD bgp_peer_import_localpref function."""
1276 return f"""\
1277 # BGP import local_pref manipulation
1278 function bgp_peer_import_localpref(string filter_name) {{
1279 # If we are reducing local_pref by three
1280 if (BGP_LC_LOCALPREF_MINUS_THREE ~ bgp_large_community) then {{
1281 if DEBUG then print filter_name,
1282 " [bgp_peer_import_localpref] Matched BGP_LC_LOCALPREF_MINUS_THREE for ", {self.functions.route_info()};
1283 bgp_local_pref = bgp_local_pref - 3;
1284 # If we are reducing local_pref by two
1285 }} else if (BGP_LC_LOCALPREF_MINUS_TWO ~ bgp_large_community) then {{
1286 if DEBUG then print filter_name,
1287 " [bgp_peer_import_localpref] Matched BGP_LC_LOCALPREF_MINUS_TWO for ", {self.functions.route_info()};
1288 bgp_local_pref = bgp_local_pref - 2;
1289 # If we are reducing local_pref by one
1290 }} else if (BGP_LC_LOCALPREF_MINUS_ONE ~ bgp_large_community) then {{
1291 if DEBUG then print filter_name,
1292 " [bgp_peer_import_localpref] Matched BGP_LC_LOCALPREF_MINUS_ONE for ", {self.functions.route_info()};
1293 bgp_local_pref = bgp_local_pref - 1;
1294 }}
1295 }}"""
1297 @BirdFunction("bgp_peer_import_peer")
1298 def peer_import_peer(self, *args: Any) -> str: # pylint: disable=unused-argument
1299 """BIRD bgp_peer_import_peer function."""
1301 return f"""\
1302 # Import peer routes
1303 function bgp_peer_import_peer(string filter_name; int peer_asn; int local_pref_cost) {{
1304 if DEBUG then print filter_name,
1305 " [bgp_peer_import_peer] Adding BGP_LC_RELATION_PEER to ", {self.functions.route_info()}, " with local pref ",
1306 BGP_PREF_PEER - local_pref_cost;
1307 # Tag route as a peer route
1308 bgp_large_community.add(BGP_LC_RELATION_PEER);
1309 # Set local preference
1310 bgp_local_pref = BGP_PREF_PEER - local_pref_cost;
1311 }}"""
1313 @BirdFunction("bgp_peer_import_routeserver")
1314 def peer_import_routeserver(self, *args: Any) -> str: # pylint: disable=unused-argument
1315 """BIRD bgp_peer_import_routeserver function."""
1317 return f"""\
1318 # Import routeserver routes
1319 function bgp_peer_import_routeserver(string filter_name; int peer_asn; int local_pref_cost) {{
1320 if DEBUG then print filter_name,
1321 " [bgp_peer_import_routeserver] Adding BGP_LC_RELATION_ROUTESERVER to ", {self.functions.route_info()},
1322 " with local pref ", BGP_PREF_ROUTESERVER - local_pref_cost;
1323 # Tag route as a routeserver route
1324 bgp_large_community.add(BGP_LC_RELATION_ROUTESERVER);
1325 # Set local preference
1326 bgp_local_pref = BGP_PREF_ROUTESERVER - local_pref_cost;
1327 }}"""
1329 @BirdFunction("bgp_peer_import_transit")
1330 def peer_import_transit(self, *args: Any) -> str: # pylint: disable=unused-argument
1331 """BIRD bgp_peer_import_transit function."""
1333 return f"""\
1334 # Import transit routes
1335 function bgp_peer_import_transit(string filter_name; int peer_asn; int local_pref_cost) {{
1336 if DEBUG then print filter_name,
1337 " [bgp_peer_import_transit] Adding BGP_LC_RELATION_TRANSIT to ", {self.functions.route_info()},
1338 " with local pref ", BGP_PREF_TRANSIT - local_pref_cost;
1339 # Tag route as a transit route
1340 bgp_large_community.add(BGP_LC_RELATION_TRANSIT);
1341 # Set local preference
1342 bgp_local_pref = BGP_PREF_TRANSIT - local_pref_cost;
1343 }}"""
1345 #
1346 # Communities
1347 #
1349 @BirdFunction("bgp_peer_community_add_connected")
1350 def peer_community_add_connected(self, *args: Any) -> str: # pylint: disable=unused-argument
1351 """BIRD bgp_peer_community_add_connected function."""
1353 return f"""\
1354 function bgp_peer_community_add_connected(string filter_name; pair community) -> bool {{
1355 if !{self.is_connected()} then return false;
1356 if DEBUG then print filter_name,
1357 " [bgp_peer_community_add_connected] Adding community ", community, " for type CONNECTED to ",
1358 {self.functions.route_info()};
1359 bgp_community.add(community);
1360 }}"""
1362 @BirdFunction("bgp_peer_community_add_kernel")
1363 def peer_community_add_kernel(self, *args: Any) -> str: # pylint: disable=unused-argument
1364 """BIRD bgp_peer_community_add_kernel function."""
1366 return f"""\
1367 function bgp_peer_community_add_kernel(string filter_name; pair community) -> bool {{
1368 if (
1369 !{self.functions.is_kernel()} ||
1370 {self.functions.is_default()} ||
1371 {self.is_blackhole()}
1372 ) then return false;
1373 if DEBUG then print filter_name,
1374 " [bgp_peer_community_add_kernel] Adding community ", community, " for type KERNEL to ",
1375 {self.functions.route_info()};
1376 bgp_community.add(community);
1377 }}"""
1379 @BirdFunction("bgp_peer_community_add_kernel_blackhole")
1380 def peer_community_add_kernel_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
1381 """BIRD bgp_peer_community_add_kernel_blackhole function."""
1383 return f"""\
1384 function bgp_peer_community_add_kernel_blackhole(string filter_name; pair community) -> bool {{
1385 if (
1386 !{self.functions.is_kernel()} ||
1387 {self.functions.is_default()} ||
1388 !{self.is_blackhole()}
1389 ) then return false;
1390 if DEBUG then print filter_name,
1391 " [bgp_peer_community_add_kernel_blackhole] Adding community ", community,
1392 " for type KERNEL BLACKHOLE to ", {self.functions.route_info()};
1393 bgp_community.add(community);
1394 }}"""
1396 @BirdFunction("bgp_peer_community_add_kernel_default")
1397 def peer_community_add_kernel_default(self, *args: Any) -> str: # pylint: disable=unused-argument
1398 """BIRD bgp_peer_community_add_kernel_default function."""
1400 return f"""\
1401 function bgp_peer_community_add_kernel_default(string filter_name; pair community) -> bool {{
1402 if (
1403 !{self.functions.is_kernel()} ||
1404 !{self.functions.is_default()} ||
1405 {self.is_blackhole()}
1406 ) then return false;
1407 if DEBUG then print filter_name,
1408 " [bgp_peer_community_add_kernel_default] Adding community ", community,
1409 " for type KERNEL DEFAULT to ", {self.functions.route_info()};
1410 bgp_community.add(community);
1411 }}"""
1413 @BirdFunction("bgp_peer_community_add_originated")
1414 def peer_community_add_originated(self, *args: Any) -> str: # pylint: disable=unused-argument
1415 """BIRD bgp_peer_community_add_originated function."""
1417 return f"""\
1418 # BGP originated route community adding
1419 function bgp_peer_community_add_originated(string filter_name; pair community) -> bool {{
1420 if (!{self.is_originated()} || {self.functions.is_default()}) then return false;
1421 if DEBUG then print filter_name,
1422 " [bgp_peer_community_add_originate] Adding community ", community,
1423 " for type ORIGINATED to ", {self.functions.route_info()};
1424 bgp_community.add(community);
1425 }}"""
1427 @BirdFunction("bgp_peer_community_add_originated_blackhole")
1428 def peer_community_add_originated_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
1429 """BIRD bgp_peer_community_add_originated_blackhole function."""
1431 return f"""\
1432 function bgp_peer_community_add_originated_blackhole(string filter_name; pair community) -> bool {{
1433 if (
1434 !{self.is_originated()} ||
1435 {self.functions.is_default()} ||
1436 !{self.is_blackhole()}
1437 ) then return false;
1438 if DEBUG then print filter_name,
1439 " [bgp_peer_community_add_originated_blackhole] Adding community ", community,
1440 " for type ORIGINATED BLACKHOLE to ", {self.functions.route_info()};
1441 bgp_community.add(community);
1442 }}"""
1444 @BirdFunction("bgp_peer_community_add_originated_default")
1445 def peer_community_add_originated_default(self, *args: Any) -> str: # pylint: disable=unused-argument
1446 """BIRD bgp_peer_community_add_originated_default function."""
1448 return f"""\
1449 function bgp_peer_community_add_originated_default(string filter_name; pair community) -> bool {{
1450 if (
1451 !{self.is_originated()} ||
1452 !{self.functions.is_default()} ||
1453 {self.is_blackhole()}
1454 ) then return false;
1455 if DEBUG then print filter_name,
1456 " [bgp_peer_community_add_originated_default] Adding community ", community,
1457 " for type ORIGINATED DEFAULT to ", {self.functions.route_info()};
1458 bgp_community.add(community);
1459 }}"""
1461 @BirdFunction("bgp_peer_community_add_static")
1462 def peer_community_add_static(self, *args: Any) -> str: # pylint: disable=unused-argument
1463 """BIRD bgp_peer_community_add_static function."""
1465 return f"""\
1466 function bgp_peer_community_add_static(string filter_name; pair community) -> bool {{
1467 if (
1468 !{self.functions.is_static()} ||
1469 {self.functions.is_default()} ||
1470 {self.is_blackhole()}
1471 ) then return false;
1472 if DEBUG then print filter_name,
1473 " [bgp_peer_community_add_static] Adding community ", community, " for type STATIC to ",
1474 {self.functions.route_info()};
1475 bgp_community.add(community);
1476 }}"""
1478 @BirdFunction("bgp_peer_community_add_static_blackhole")
1479 def peer_community_add_static_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
1480 """BIRD bgp_peer_community_add_static_blackhole function."""
1482 return f"""\
1483 function bgp_peer_community_add_static_blackhole(string filter_name; pair community) -> bool {{
1484 if (
1485 !{self.functions.is_static()} ||
1486 {self.functions.is_default()} ||
1487 !{self.is_blackhole()}
1488 ) then return false;
1489 if DEBUG then print filter_name,
1490 " [bgp_peer_community_add_static_blackhole] Adding community ", community,
1491 " for type STATIC BLACKHOLE to ", {self.functions.route_info()};
1492 bgp_community.add(community);
1493 }}"""
1495 @BirdFunction("bgp_peer_community_add_static_default")
1496 def peer_community_add_static_default(self, *args: Any) -> str: # pylint: disable=unused-argument
1497 """BIRD bgp_peer_community_add_static_default function."""
1499 return f"""\
1500 function bgp_peer_community_add_static_default(string filter_name; pair community) -> bool {{
1501 if (
1502 !{self.functions.is_static()} ||
1503 !{self.functions.is_default()} ||
1504 {self.is_blackhole()}
1505 ) then return false;
1506 if DEBUG then print filter_name,
1507 " [bgp_peer_community_add_static_default] Adding community ", community,
1508 " for type STATIC DEFAULT to ", {self.functions.route_info()};
1509 bgp_community.add(community);
1510 }}"""
1512 @BirdFunction("bgp_peer_community_add_bgp_own")
1513 def peer_community_add_bgp_own(self, *args: Any) -> str: # pylint: disable=unused-argument
1514 """BIRD bgp_peer_community_add_bgp_own function."""
1516 return f"""\
1517 # BGP own route community adding
1518 function bgp_peer_community_add_bgp_own(string filter_name; pair community) -> bool {{
1519 if (
1520 !{self.is_bgp_own()} ||
1521 {self.functions.is_default()} ||
1522 {self.is_blackhole()}
1523 ) then return false;
1524 if DEBUG then print filter_name,
1525 " [bgp_peer_community_add_bgp_own] Adding community ", community, " for type BGP_OWN to ",
1526 {self.functions.route_info()};
1527 bgp_community.add(community);
1528 }}"""
1530 @BirdFunction("bgp_peer_community_add_bgp_own_blackhole")
1531 def peer_community_add_bgp_own_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
1532 """BIRD bgp_peer_community_add_bgp_own_blackhole function."""
1534 return f"""\
1535 function bgp_peer_community_add_bgp_own_blackhole(string filter_name; pair community) -> bool {{
1536 if (
1537 !{self.is_bgp_own()} ||
1538 {self.functions.is_default()} ||
1539 !{self.is_blackhole()}
1540 ) then return false;
1541 if DEBUG then print filter_name,
1542 " [bgp_peer_community_add_bgp_own_blackhole] Adding community ", community,
1543 " for type BGP_OWN BLACKHOLE to ", {self.functions.route_info()};
1544 bgp_community.add(community);
1545 }}"""
1547 @BirdFunction("bgp_peer_community_add_bgp_own_default")
1548 def peer_community_add_bgp_own_default(self, *args: Any) -> str: # pylint: disable=unused-argument
1549 """BIRD bgp_peer_community_add_bgp_own_default function."""
1551 return f"""\
1552 function bgp_peer_community_add_bgp_own_default(string filter_name; pair community) -> bool {{
1553 if (
1554 !{self.is_bgp_own()} ||
1555 !{self.functions.is_default()} ||
1556 {self.is_blackhole()}
1557 ) then return false;
1558 if DEBUG then print filter_name,
1559 " [bgp_peer_community_add_bgp_own_default] Adding community ", community,
1560 " for type BGP_OWN DEFAULT to ", {self.functions.route_info()};
1561 bgp_community.add(community);
1562 }}"""
1564 @BirdFunction("bgp_peer_community_add_bgp_customer")
1565 def peer_community_add_bgp_customer(self, *args: Any) -> str: # pylint: disable=unused-argument
1566 """BIRD bgp_peer_community_add_bgp_customer function."""
1568 return f"""\
1569 # BGP customer route community adding
1570 function bgp_peer_community_add_bgp_customer(string filter_name; pair community) -> bool {{
1571 if (
1572 !{self.is_bgp_customer()} ||
1573 {self.functions.is_default()} ||
1574 {self.is_blackhole()}
1575 ) then return false;
1576 if DEBUG then print filter_name,
1577 " [bgp_peer_community_add_bgp_customer] Adding community ", community, " for type BGP_CUSTOMER to ",
1578 {self.functions.route_info()};
1579 bgp_community.add(community);
1580 }}"""
1582 @BirdFunction("bgp_peer_community_add_bgp_customer_blackhole")
1583 def peer_community_add_bgp_customer_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
1584 """BIRD bgp_peer_community_add_bgp_customer_blackhole function."""
1586 return f"""\
1587 function bgp_peer_community_add_bgp_customer_blackhole(string filter_name; pair community) -> bool {{
1588 if (
1589 !{self.is_bgp_customer()} ||
1590 {self.functions.is_default()} ||
1591 !{self.is_blackhole()}
1592 ) then return false;
1593 if DEBUG then print filter_name,
1594 " [bgp_peer_community_add_bgp_customer_blackhole] Adding community ", community,
1595 " for type BGP_CUSTOMER BLACKHOLE to ", {self.functions.route_info()};
1596 bgp_community.add(community);
1597 }}"""
1599 @BirdFunction("bgp_peer_community_add_bgp_peering")
1600 def peer_community_add_bgp_peering(self, *args: Any) -> str: # pylint: disable=unused-argument
1601 """BIRD bgp_peer_community_add_bgp_peering function."""
1603 return f"""\
1604 # BGP peering route community adding
1605 function bgp_peer_community_add_bgp_peering(string filter_name; pair community) -> bool {{
1606 if (!{self.is_bgp_peer()} && !{self.is_bgp_routeserver()}) then return false;
1607 if DEBUG then print filter_name,
1608 " [bgp_peer_community_add_bgp_peer] Adding community ", community, " for type BGP_PEER to ",
1609 {self.functions.route_info()};
1610 bgp_community.add(community);
1611 }}"""
1613 @BirdFunction("bgp_peer_community_add_bgp_transit")
1614 def peer_community_add_bgp_transit(self, *args: Any) -> str: # pylint: disable=unused-argument
1615 """BIRD bgp_peer_community_add_bgp_transit function."""
1617 return f"""\
1618 # BGP transit route community adding
1619 function bgp_peer_community_add_bgp_transit(string filter_name; pair community) -> bool {{
1620 if (
1621 !{self.is_bgp_transit()} ||
1622 {self.functions.is_default()} ||
1623 {self.is_blackhole()}
1624 ) then return false;
1625 if DEBUG then print filter_name,
1626 " [bgp_peer_community_add_bgp_transit] Adding community ", community, " for type BGP_TRANSIT to ",
1627 {self.functions.route_info()};
1628 bgp_community.add(community);
1629 }}"""
1631 @BirdFunction("bgp_peer_community_add_bgp_transit_default")
1632 def peer_community_add_bgp_transit_default(self, *args: Any) -> str: # pylint: disable=unused-argument
1633 """BIRD bgp_peer_community_add_bgp_transit_default function."""
1635 return f"""\
1636 function bgp_peer_community_add_bgp_transit_default(string filter_name; pair community) -> bool {{
1637 if (
1638 !{self.is_bgp_transit()} ||
1639 !{self.functions.is_default()} ||
1640 {self.is_blackhole()}
1641 ) then return false;
1642 if DEBUG then print filter_name,
1643 " [bgp_peer_community_add_bgp_transit_default] Adding community ", community,
1644 " for type BGP_TRANSIT DEFAULT to ", {self.functions.route_info()};
1645 bgp_community.add(community);
1646 }}"""
1648 @BirdFunction("bgp_peer_community_add_blackhole")
1649 def peer_community_add_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
1650 """BIRD bgp_peer_community_add_blackhole function."""
1652 return f"""\
1653 # Add a community to a blackhole route (the check for a blackhole route needs to be done before calling this
1654 # function)
1655 function bgp_peer_community_add_blackhole(string filter_name; pair community) {{
1656 if DEBUG then print filter_name,
1657 " [bgp_peer_community_add_blackhole] Adding community ", community, " for type BLACKHOLE to ",
1658 {self.functions.route_info()};
1659 bgp_community.add(community);
1660 }}"""
1662 #
1663 # Large Communities
1664 #
1666 @BirdFunction("bgp_peer_lc_add_connected")
1667 def peer_lc_add_connected(self, *args: Any) -> str: # pylint: disable=unused-argument
1668 """BIRD bgp_peer_lc_add_connected function."""
1670 return f"""\
1671 function bgp_peer_lc_add_connected(string filter_name; lc large_community) -> bool {{
1672 if !{self.is_connected()} then return false;
1673 if DEBUG then print filter_name,
1674 " [bgp_peer_lc_add_connected] Adding large community ", large_community, " for type CONNECTED to ",
1675 {self.functions.route_info()};
1676 bgp_large_community.add(large_community);
1677 }}"""
1679 @BirdFunction("bgp_peer_lc_add_kernel")
1680 def peer_lc_add_kernel(self, *args: Any) -> str: # pylint: disable=unused-argument
1681 """BIRD bgp_peer_lc_add_kernel function."""
1683 return f"""\
1684 function bgp_peer_lc_add_kernel(string filter_name; lc large_community) -> bool {{
1685 if (
1686 !{self.functions.is_kernel()} ||
1687 {self.functions.is_default()} ||
1688 {self.is_blackhole()}
1689 ) then return false;
1690 if DEBUG then print filter_name,
1691 " [bgp_peer_lc_add_kernel] Adding large community ", large_community, " for type KERNEL to ",
1692 {self.functions.route_info()};
1693 bgp_large_community.add(large_community);
1694 }}"""
1696 @BirdFunction("bgp_peer_lc_add_kernel_blackhole")
1697 def peer_lc_add_kernel_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
1698 """BIRD bgp_peer_lc_add_kernel_blackhole function."""
1700 return f"""\
1701 function bgp_peer_lc_add_kernel_blackhole(string filter_name; lc large_community) -> bool {{
1702 if (
1703 !{self.functions.is_kernel()} ||
1704 {self.functions.is_default()} ||
1705 !{self.is_blackhole()}
1706 ) then return false;
1707 if DEBUG then print filter_name,
1708 " [bgp_peer_lc_add_kernel_blackhole] Adding large community ", large_community,
1709 " for type KERNEL BLACKHOLE to ", {self.functions.route_info()};
1710 bgp_large_community.add(large_community);
1711 }}"""
1713 @BirdFunction("bgp_peer_lc_add_kernel_default")
1714 def peer_lc_add_kernel_default(self, *args: Any) -> str: # pylint: disable=unused-argument
1715 """BIRD bgp_peer_lc_add_kernel_default function."""
1717 return f"""\
1718 function bgp_peer_lc_add_kernel_default(string filter_name; lc large_community) -> bool {{
1719 if (
1720 !{self.functions.is_kernel()} ||
1721 !{self.functions.is_default()} ||
1722 {self.is_blackhole()}
1723 ) then return false;
1724 if DEBUG then print filter_name,
1725 " [bgp_peer_lc_add_kernel_default] Adding large community ", large_community,
1726 " for type KERNEL DEFAULT to ", {self.functions.route_info()};
1727 bgp_large_community.add(large_community);
1728 }}"""
1730 @BirdFunction("bgp_peer_lc_add_originated")
1731 def peer_lc_add_originated(self, *args: Any) -> str: # pylint: disable=unused-argument
1732 """BIRD bgp_peer_lc_add_originated function."""
1734 return f"""\
1735 # BGP originated route large community adding
1736 function bgp_peer_lc_add_originated(string filter_name; lc large_community) -> bool {{
1737 if (!{self.is_originated()} || {self.functions.is_default()}) then return false;
1738 if DEBUG then print filter_name,
1739 " [bgp_peer_lc_add_originate] Adding large community ", large_community,
1740 " for type ORIGINATED to ", {self.functions.route_info()};
1741 bgp_large_community.add(large_community);
1742 }}"""
1744 @BirdFunction("bgp_peer_lc_add_originated_blackhole")
1745 def peer_lc_add_originated_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
1746 """BIRD bgp_peer_lc_add_originated_blackhole function."""
1748 return f"""\
1749 function bgp_peer_lc_add_originated_blackhole(string filter_name; lc large_community) -> bool {{
1750 if (
1751 !{self.is_originated()} ||
1752 {self.functions.is_default()} ||
1753 !{self.is_blackhole()}
1754 ) then return false;
1755 if DEBUG then print filter_name,
1756 " [bgp_peer_lc_add_originated_blackhole] Adding large community ", large_community,
1757 " for type ORIGINATED BLACKHOLE to ", {self.functions.route_info()};
1758 bgp_large_community.add(large_community);
1759 }}"""
1761 @BirdFunction("bgp_peer_lc_add_originated_default")
1762 def peer_lc_add_originated_default(self, *args: Any) -> str: # pylint: disable=unused-argument
1763 """BIRD bgp_peer_lc_add_originated_default function."""
1765 return f"""\
1766 function bgp_peer_lc_add_originated_default(string filter_name; lc large_community) -> bool {{
1767 if (
1768 !{self.is_originated()} ||
1769 !{self.functions.is_default()} ||
1770 {self.is_blackhole()}
1771 ) then return false;
1772 if DEBUG then print filter_name,
1773 " [bgp_peer_lc_add_originated_default] Adding large community ", large_community,
1774 " for type ORIGINATED DEFAULT to ", {self.functions.route_info()};
1775 bgp_large_community.add(large_community);
1776 }}"""
1778 @BirdFunction("bgp_peer_lc_add_static")
1779 def peer_lc_add_static(self, *args: Any) -> str: # pylint: disable=unused-argument
1780 """BIRD bgp_peer_lc_add_static function."""
1782 return f"""\
1783 function bgp_peer_lc_add_static(string filter_name; lc large_community) -> bool {{
1784 if (
1785 !{self.functions.is_static()} ||
1786 {self.functions.is_default()} ||
1787 {self.is_blackhole()}
1788 ) then return false;
1789 if DEBUG then print filter_name,
1790 " [bgp_peer_lc_add_static] Adding large community ", large_community, " for type STATIC to ",
1791 {self.functions.route_info()};
1792 bgp_large_community.add(large_community);
1793 }}"""
1795 @BirdFunction("bgp_peer_lc_add_static_blackhole")
1796 def peer_lc_add_static_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
1797 """BIRD bgp_peer_lc_add_static_blackhole function."""
1799 return f"""\
1800 function bgp_peer_lc_add_static_blackhole(string filter_name; lc large_community) -> bool {{
1801 if (
1802 !{self.functions.is_static()} ||
1803 {self.functions.is_default()} ||
1804 !{self.is_blackhole()}
1805 ) then return false;
1806 if DEBUG then print filter_name,
1807 " [bgp_peer_lc_add_static_blackhole] Adding large community ", large_community,
1808 " for type STATIC BLACKHOLE to ", {self.functions.route_info()};
1809 bgp_large_community.add(large_community);
1810 }}"""
1812 @BirdFunction("bgp_peer_lc_add_static_default")
1813 def peer_lc_add_static_default(self, *args: Any) -> str: # pylint: disable=unused-argument
1814 """BIRD bgp_peer_lc_add_static_default function."""
1816 return f"""\
1817 function bgp_peer_lc_add_static_default(string filter_name; lc large_community) -> bool {{
1818 if (
1819 !{self.functions.is_static()} ||
1820 !{self.functions.is_default()} ||
1821 {self.is_blackhole()}
1822 ) then return false;
1823 if DEBUG then print filter_name,
1824 " [bgp_peer_lc_add_static_default] Adding large community ", large_community,
1825 " for type STATIC DEFAULT to ", {self.functions.route_info()};
1826 bgp_large_community.add(large_community);
1827 }}"""
1829 @BirdFunction("bgp_peer_lc_add_bgp_own")
1830 def peer_lc_add_bgp_own(self, *args: Any) -> str: # pylint: disable=unused-argument
1831 """BIRD bgp_peer_lc_add_bgp_own function."""
1833 return f"""\
1834 # BGP own route large community adding
1835 function bgp_peer_lc_add_bgp_own(string filter_name; lc large_community) -> bool {{
1836 if (
1837 !{self.is_bgp_own()} ||
1838 {self.functions.is_default()} ||
1839 {self.is_blackhole()}
1840 ) then return false;
1841 if DEBUG then print filter_name,
1842 " [bgp_peer_lc_add_bgp_own] Adding large community ", large_community, " for type BGP_OWN to ",
1843 {self.functions.route_info()};
1844 bgp_large_community.add(large_community);
1845 }}"""
1847 @BirdFunction("bgp_peer_lc_add_bgp_own_blackhole")
1848 def peer_lc_add_bgp_own_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
1849 """BIRD bgp_peer_lc_add_bgp_own_blackhole function."""
1851 return f"""\
1852 function bgp_peer_lc_add_bgp_own_blackhole(string filter_name; lc large_community) -> bool {{
1853 if (
1854 !{self.is_bgp_own()} ||
1855 {self.functions.is_default()} ||
1856 !{self.is_blackhole()}
1857 ) then return false;
1858 if DEBUG then print filter_name,
1859 " [bgp_peer_lc_add_bgp_own_blackhole] Adding large community ", large_community,
1860 " for type BGP_OWN BLACKHOLE to ", {self.functions.route_info()};
1861 bgp_large_community.add(large_community);
1862 }}"""
1864 @BirdFunction("bgp_peer_lc_add_bgp_own_default")
1865 def peer_lc_add_bgp_own_default(self, *args: Any) -> str: # pylint: disable=unused-argument
1866 """BIRD bgp_peer_lc_add_bgp_own_default function."""
1868 return f"""\
1869 function bgp_peer_lc_add_bgp_own_default(string filter_name; lc large_community) -> bool {{
1870 if (
1871 !{self.is_bgp_own()} ||
1872 !{self.functions.is_default()} ||
1873 {self.is_blackhole()}
1874 ) then return false;
1875 if DEBUG then print filter_name,
1876 " [bgp_peer_lc_add_bgp_own_default] Adding large community ", large_community,
1877 " for type BGP_OWN DEFAULT to ", {self.functions.route_info()};
1878 bgp_large_community.add(large_community);
1879 }}"""
1881 @BirdFunction("bgp_peer_lc_add_bgp_customer")
1882 def peer_lc_add_bgp_customer(self, *args: Any) -> str: # pylint: disable=unused-argument
1883 """BIRD bgp_peer_lc_add_bgp_customer function."""
1885 return f"""\
1886 # BGP customer route large community adding
1887 function bgp_peer_lc_add_bgp_customer(string filter_name; lc large_community) -> bool {{
1888 if (
1889 !{self.is_bgp_customer()} ||
1890 {self.functions.is_default()} ||
1891 {self.is_blackhole()}
1892 ) then return false;
1893 if DEBUG then print filter_name,
1894 " [bgp_peer_lc_add_bgp_customer] Adding large community ", large_community, " for type BGP_CUSTOMER to ",
1895 {self.functions.route_info()};
1896 bgp_large_community.add(large_community);
1897 }}"""
1899 @BirdFunction("bgp_peer_lc_add_bgp_customer_blackhole")
1900 def peer_lc_add_bgp_customer_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
1901 """BIRD bgp_peer_lc_add_bgp_customer_blackhole function."""
1903 return f"""\
1904 function bgp_peer_lc_add_bgp_customer_blackhole(string filter_name; lc large_community) -> bool {{
1905 if (
1906 !{self.is_bgp_customer()} ||
1907 {self.functions.is_default()} ||
1908 !{self.is_blackhole()}
1909 ) then return false;
1910 if DEBUG then print filter_name,
1911 " [bgp_peer_lc_add_bgp_customer_blackhole] Adding large community ", large_community,
1912 " for type BGP_CUSTOMER BLACKHOLE to ", {self.functions.route_info()};
1913 bgp_large_community.add(large_community);
1914 }}"""
1916 @BirdFunction("bgp_peer_lc_add_bgp_peering")
1917 def peer_lc_add_bgp_peering(self, *args: Any) -> str: # pylint: disable=unused-argument
1918 """BIRD bgp_peer_lc_add_bgp_peering function."""
1920 return f"""\
1921 # BGP peering route large community adding
1922 function bgp_peer_lc_add_bgp_peering(string filter_name; lc large_community) -> bool {{
1923 if (!{self.is_bgp_peer()} && !{self.is_bgp_routeserver()}) then return false;
1924 if DEBUG then print filter_name,
1925 " [bgp_peer_lc_add_bgp_peer] Adding large community ", large_community, " for type BGP_PEER to ",
1926 {self.functions.route_info()};
1927 bgp_large_community.add(large_community);
1928 }}"""
1930 @BirdFunction("bgp_peer_lc_add_bgp_transit")
1931 def peer_lc_add_bgp_transit(self, *args: Any) -> str: # pylint: disable=unused-argument
1932 """BIRD bgp_peer_lc_add_bgp_transit function."""
1934 return f"""\
1935 # BGP transit route large community adding
1936 function bgp_peer_lc_add_bgp_transit(string filter_name; lc large_community) -> bool {{
1937 if (
1938 !{self.is_bgp_transit()} ||
1939 {self.functions.is_default()} ||
1940 {self.is_blackhole()}
1941 ) then return false;
1942 if DEBUG then print filter_name,
1943 " [bgp_peer_lc_add_bgp_transit] Adding large community ", large_community, " for type BGP_TRANSIT to ",
1944 {self.functions.route_info()};
1945 bgp_large_community.add(large_community);
1946 }}"""
1948 @BirdFunction("bgp_peer_lc_add_bgp_transit_default")
1949 def peer_lc_add_bgp_transit_default(self, *args: Any) -> str: # pylint: disable=unused-argument
1950 """BIRD bgp_peer_lc_add_bgp_transit_default function."""
1952 return f"""\
1953 function bgp_peer_lc_add_bgp_transit_default(string filter_name; lc large_community) -> bool {{
1954 if (
1955 !{self.is_bgp_transit()} ||
1956 !{self.functions.is_default()} ||
1957 {self.is_blackhole()}
1958 ) then return false;
1959 if DEBUG then print filter_name,
1960 " [bgp_peer_lc_add_bgp_transit_default] Adding large community ", large_community,
1961 " for type BGP_TRANSIT DEFAULT to ", {self.functions.route_info()};
1962 bgp_large_community.add(large_community);
1963 }}"""
1965 @BirdFunction("bgp_peer_lc_add_blackhole")
1966 def peer_lc_add_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
1967 """BIRD bgp_peer_lc_add_blackhole function."""
1969 return f"""\
1970 # Add a large community to a blackhole route (the check for a blackhole route needs to be done before calling this
1971 # function)
1972 function bgp_peer_lc_add_blackhole(string filter_name; lc large_community) {{
1973 if DEBUG then print filter_name,
1974 " [bgp_peer_lc_add_blackhole] Adding large community ", large_community, " for type BLACKHOLE to ",
1975 {self.functions.route_info()};
1976 bgp_large_community.add(large_community);
1977 }}"""
1979 @BirdFunction("bgp_peer_peer_prepend")
1980 def peer_prepend(self, *args: Any) -> str: # pylint: disable=unused-argument
1981 """BIRD bgp_peer_peer_prepend function."""
1983 return """\
1984 # BGP prepending
1985 function bgp_peer_peer_prepend(string filter_name; int peer_asn; int prepend_count) {
1986 if (prepend_count > 0) then bgp_path.prepend(peer_asn);
1987 if (prepend_count > 1) then bgp_path.prepend(peer_asn);
1988 if (prepend_count > 2) then bgp_path.prepend(peer_asn);
1989 if (prepend_count > 3) then bgp_path.prepend(peer_asn);
1990 if (prepend_count > 4) then bgp_path.prepend(peer_asn);
1991 if (prepend_count > 5) then bgp_path.prepend(peer_asn);
1992 if (prepend_count > 6) then bgp_path.prepend(peer_asn);
1993 if (prepend_count > 7) then bgp_path.prepend(peer_asn);
1994 if (prepend_count > 8) then bgp_path.prepend(peer_asn);
1995 if (prepend_count > 9) then bgp_path.prepend(peer_asn);
1996 }"""
1998 @BirdFunction("bgp_peer_peer_prepend_default")
1999 def peer_prepend_default(self, *args: Any) -> str: # pylint: disable=unused-argument
2000 """BIRD bgp_peer_peer_prepend_default function."""
2002 return f"""\
2003 function bgp_peer_prepend_default(string filter_name; int peer_asn; int prepend_count) -> bool {{
2004 if !{self.functions.is_default()} then return false;
2005 if DEBUG then print filter_name,
2006 " [bgp_peer_prepend_default] Prepending AS-PATH for type DEFAULT ", prepend_count, "x to ",
2007 {self.functions.route_info()};
2008 {self.peer_prepend(BirdVariable("peer_asn"), BirdVariable("prepend_count"))};
2009 }}"""
2011 @BirdFunction("bgp_peer_prepend_connected")
2012 def peer_prepend_connected(self, *args: Any) -> str: # pylint: disable=unused-argument
2013 """BIRD bgp_peer_prepend_connected function."""
2015 return f"""\
2016 # BGP connected route prepending
2017 function bgp_peer_prepend_connected(string filter_name; int peer_asn; int prepend_count) -> bool {{
2018 if !{self.is_connected()} then return false;
2019 if DEBUG then print filter_name,
2020 " [bgp_peer_prepend_connected] Prepending AS-PATH for type CONNECTED ", prepend_count, "x to "
2021 , {self.functions.route_info()};
2022 {self.peer_prepend(BirdVariable("peer_asn"), BirdVariable("prepend_count"))};
2023 }}"""
2025 @BirdFunction("bgp_peer_prepend_kernel")
2026 def peer_prepend_kernel(self, *args: Any) -> str: # pylint: disable=unused-argument
2027 """BIRD bgp_peer_prepend_kernel function."""
2029 return f"""\
2030 function bgp_peer_prepend_kernel(string filter_name; int peer_asn; int prepend_count) -> bool {{
2031 if (
2032 !{self.functions.is_kernel()} ||
2033 {self.functions.is_default()} ||
2034 {self.is_blackhole()}
2035 ) then return false;
2036 if DEBUG then print filter_name,
2037 " [bgp_peer_prepend_kernel] Prepending AS-PATH for type KERNEL ", prepend_count, "x to ",
2038 {self.functions.route_info()};
2039 {self.peer_prepend(BirdVariable("peer_asn"), BirdVariable("prepend_count"))};
2040 }}"""
2042 @BirdFunction("bgp_peer_prepend_kernel_blackhole")
2043 def peer_prepend_kernel_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
2044 """BIRD bgp_peer_prepend_kernel_blackhole function."""
2046 return f"""\
2047 function bgp_peer_prepend_kernel_blackhole(string filter_name; int peer_asn; int prepend_count) -> bool {{
2048 if (
2049 !{self.functions.is_kernel()} ||
2050 {self.functions.is_default()} ||
2051 !{self.is_blackhole()}
2052 ) then return false;
2053 if DEBUG then print filter_name,
2054 " [bgp_peer_prepend_kernel_blackhole] Prepending AS-PATH for type KERNEL BLACKHOLE ",
2055 prepend_count, "x to ", {self.functions.route_info()};
2056 {self.peer_prepend(BirdVariable("peer_asn"), BirdVariable("prepend_count"))};
2057 }}"""
2059 @BirdFunction("bgp_peer_prepend_kernel_default")
2060 def peer_prepend_kernel_default(self, *args: Any) -> str: # pylint: disable=unused-argument
2061 """BIRD bgp_peer_prepend_kernel_default function."""
2063 return f"""\
2064 function bgp_peer_prepend_kernel_default(string filter_name; int peer_asn; int prepend_count) -> bool {{
2065 if (
2066 !{self.functions.is_kernel()} ||
2067 !{self.functions.is_default()} ||
2068 {self.is_blackhole()}
2069 ) then return false;
2070 if DEBUG then print filter_name,
2071 " [bgp_peer_prepend_kernel_default] Prepending AS-PATH for type KERNEL DEFAULT ",
2072 prepend_count, "x to ", {self.functions.route_info()};
2073 {self.peer_prepend(BirdVariable("peer_asn"), BirdVariable("prepend_count"))};
2074 }}"""
2076 @BirdFunction("bgp_peer_prepend_originated")
2077 def peer_prepend_originated(self, *args: Any) -> str: # pylint: disable=unused-argument
2078 """BIRD bgp_peer_prepend_originated function."""
2080 return f"""\
2081 function bgp_peer_prepend_originated(string filter_name; int peer_asn; int prepend_count) -> bool {{
2082 if (
2083 !{self.is_originated()} ||
2084 {self.functions.is_default()}
2085 ) then return false;
2086 if DEBUG then print filter_name,
2087 " [bgp_peer_prepend_originated] Prepending AS-PATH for type ORIGINATED ", prepend_count, "x to ",
2088 {self.functions.route_info()};
2089 {self.peer_prepend(BirdVariable("peer_asn"), BirdVariable("prepend_count"))};
2090 }}"""
2092 @BirdFunction("bgp_peer_prepend_originated_default")
2093 def peer_prepend_originated_default(self, *args: Any) -> str: # pylint: disable=unused-argument
2094 """BIRD bgp_peer_prepend_originated_default function."""
2096 return f"""\
2097 function bgp_peer_prepend_originated_default(string filter_name; int peer_asn; int prepend_count) -> bool {{
2098 if (
2099 !{self.is_originated()} ||
2100 !{self.functions.is_default()}
2101 ) then return false;
2102 if DEBUG then print filter_name,
2103 " [bgp_peer_prepend_originated_default] Prepending AS-PATH for type ORIGINATED DEFAULT ", prepend_count,
2104 "x to ", {self.functions.route_info()};
2105 {self.peer_prepend(BirdVariable("peer_asn"), BirdVariable("prepend_count"))};
2106 }}"""
2108 @BirdFunction("bgp_peer_prepend_static")
2109 def peer_prepend_static(self, *args: Any) -> str: # pylint: disable=unused-argument
2110 """BIRD bgp_peer_prepend_static function."""
2112 return f"""\
2113 function bgp_peer_prepend_static(string filter_name; int peer_asn; int prepend_count) -> bool {{
2114 if (
2115 !{self.functions.is_static()} ||
2116 {self.functions.is_default()} ||
2117 {self.is_blackhole()}
2118 ) then return false;
2119 if DEBUG then print filter_name,
2120 " [bgp_peer_prepend_static] Prepending AS-PATH for type STATIC ", prepend_count, "x to ",
2121 {self.functions.route_info()};
2122 {self.peer_prepend(BirdVariable("peer_asn"), BirdVariable("prepend_count"))};
2123 }}"""
2125 @BirdFunction("bgp_peer_prepend_static_blackhole")
2126 def peer_prepend_static_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
2127 """BIRD bgp_peer_prepend_static_blackhole function."""
2129 return f"""\
2130 function bgp_peer_prepend_static_blackhole(string filter_name; int peer_asn; int prepend_count) -> bool {{
2131 if (
2132 !{self.functions.is_static()} ||
2133 {self.functions.is_default()} ||
2134 !{self.is_blackhole()}
2135 ) then return false;
2136 if DEBUG then print filter_name,
2137 " [bgp_peer_prepend_static_blackhole] Prepending AS-PATH for type STATIC BLACKHOLE ",
2138 prepend_count, "x to ", {self.functions.route_info()};
2139 {self.peer_prepend(BirdVariable("peer_asn"), BirdVariable("prepend_count"))};
2140 }}"""
2142 @BirdFunction("bgp_peer_prepend_static_default")
2143 def peer_prepend_static_default(self, *args: Any) -> str: # pylint: disable=unused-argument
2144 """BIRD bgp_peer_prepend_static_default function."""
2146 return f"""\
2147 function bgp_peer_prepend_static_default(string filter_name; int peer_asn; int prepend_count) -> bool {{
2148 if (
2149 !{self.functions.is_static()} ||
2150 !{self.functions.is_default()} ||
2151 {self.is_blackhole()}
2152 ) then return false;
2153 if DEBUG then print filter_name,
2154 " [bgp_peer_prepend_static_default] Prepending AS-PATH for type STATIC DEFAULT ",
2155 prepend_count, "x to ", {self.functions.route_info()};
2156 {self.peer_prepend(BirdVariable("peer_asn"), BirdVariable("prepend_count"))};
2157 }}"""
2159 @BirdFunction("bgp_peer_prepend_bgp_own")
2160 def peer_prepend_bgp_own(self, *args: Any) -> str: # pylint: disable=unused-argument
2161 """BIRD bgp_peer_prepend_bgp_own function."""
2163 return f"""\
2164 function bgp_peer_prepend_bgp_own(string filter_name; int peer_asn; int prepend_count) -> bool {{
2165 if (
2166 !{self.is_bgp_own()} ||
2167 {self.functions.is_default()} ||
2168 {self.is_blackhole()}
2169 ) then return false;
2170 if DEBUG then print filter_name,
2171 " [bgp_peer_prepend_bgp_own] Prepending AS-PATH for type BGP_OWN ", prepend_count, "x to ",
2172 {self.functions.route_info()};
2173 {self.peer_prepend(BirdVariable("peer_asn"), BirdVariable("prepend_count"))};
2174 }}"""
2176 @BirdFunction("bgp_peer_prepend_bgp_own_blackhole")
2177 def peer_prepend_bgp_own_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
2178 """BIRD bgp_peer_prepend_bgp_own_blackhole function."""
2180 return f"""\
2181 function bgp_peer_prepend_bgp_own_blackhole(string filter_name; int peer_asn; int prepend_count) -> bool {{
2182 if (
2183 !{self.is_bgp_own()} ||
2184 {self.functions.is_default()} ||
2185 !{self.is_blackhole()}
2186 ) then return false;
2187 if DEBUG then print filter_name,
2188 " [bgp_peer_prepend_bgp_own_blackhole] Prepending AS-PATH for type BGP_OWN BLACKHOLE ", prepend_count,
2189 "x to ", {self.functions.route_info()};
2190 {self.peer_prepend(BirdVariable("peer_asn"), BirdVariable("prepend_count"))};
2191 }}"""
2193 @BirdFunction("bgp_peer_prepend_bgp_own_default")
2194 def peer_prepend_bgp_own_default(self, *args: Any) -> str: # pylint: disable=unused-argument
2195 """BIRD bgp_peer_prepend_bgp_own_default function."""
2197 return f"""\
2198 function bgp_peer_prepend_bgp_own_default(string filter_name; int peer_asn; int prepend_count) -> bool {{
2199 if (
2200 !{self.is_bgp_own()} ||
2201 !{self.functions.is_default()} ||
2202 {self.is_blackhole()}
2203 ) then return false;
2204 if DEBUG then print filter_name,
2205 " [bgp_peer_prepend_bgp_own_default] Prepending AS-PATH for type BGP_OWN DEFAULT ", prepend_count,
2206 "x to ", {self.functions.route_info()};
2207 {self.peer_prepend(BirdVariable("peer_asn"), BirdVariable("prepend_count"))};
2208 }}"""
2210 @BirdFunction("bgp_peer_prepend_bgp_customer")
2211 def peer_prepend_bgp_customer(self, *args: Any) -> str: # pylint: disable=unused-argument
2212 """BIRD bgp_peer_prepend_bgp_customer function."""
2214 return f"""\
2215 function bgp_peer_prepend_bgp_customer(string filter_name; int peer_asn; int prepend_count) -> bool {{
2216 if (
2217 !{self.is_bgp_customer()} ||
2218 {self.functions.is_default()} ||
2219 {self.is_blackhole()}
2220 ) then return false;
2221 if DEBUG then print filter_name,
2222 " [bgp_peer_prepend_bgp_customer] Prepending AS-PATH for type BGP_CUSTOMER ", prepend_count, "x to ",
2223 {self.functions.route_info()};
2224 {self.peer_prepend(BirdVariable("peer_asn"), BirdVariable("prepend_count"))};
2225 }}"""
2227 @BirdFunction("bgp_peer_prepend_bgp_customer_blackhole")
2228 def peer_prepend_bgp_customer_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
2229 """BIRD bgp_peer_prepend_bgp_customer_blackhole function."""
2231 return f"""\
2232 function bgp_peer_prepend_bgp_customer_blackhole(string filter_name; int peer_asn; int prepend_count) -> bool {{
2233 if (
2234 !{self.is_bgp_customer()} ||
2235 {self.functions.is_default()} ||
2236 !{self.is_blackhole()}
2237 ) then return false;
2238 if DEBUG then print filter_name,
2239 " [bgp_peer_prepend_bgp_customer_blackhole] Prepending AS-PATH for type BGP_CUSTOMER BLACKHOLE ", prepend_count,
2240 "x to ", {self.functions.route_info()};
2241 {self.peer_prepend(BirdVariable("peer_asn"), BirdVariable("prepend_count"))};
2242 }}"""
2244 @BirdFunction("bgp_peer_prepend_bgp_peering")
2245 def peer_prepend_bgp_peering(self, *args: Any) -> str: # pylint: disable=unused-argument
2246 """BIRD bgp_peer_prepend_bgp_peering function."""
2248 return f"""\
2249 function bgp_peer_prepend_bgp_peering(string filter_name; int peer_asn; int prepend_count) -> bool {{
2250 if (!{self.is_bgp_peer()} && !{self.is_bgp_routeserver()}) then return false;
2251 if DEBUG then print filter_name,
2252 " [bgp_peer_prepend_bgp_peer] Prepending AS-PATH for type BGP_PEER ", prepend_count, "x to ",
2253 {self.functions.route_info()};
2254 {self.peer_prepend(BirdVariable("peer_asn"), BirdVariable("prepend_count"))};
2255 }}"""
2257 @BirdFunction("bgp_peer_prepend_bgp_transit")
2258 def peer_prepend_bgp_transit(self, *args: Any) -> str: # pylint: disable=unused-argument
2259 """BIRD bgp_peer_prepend_bgp_transit function."""
2261 return f"""\
2262 function bgp_peer_prepend_bgp_transit(string filter_name; int peer_asn; int prepend_count) -> bool {{
2263 if (
2264 !{self.is_bgp_transit()} ||
2265 {self.functions.is_default()} ||
2266 {self.is_blackhole()}
2267 ) then return false;
2268 if DEBUG then print filter_name,
2269 " [bgp_peer_prepend_bgp_transit] Prepending AS-PATH for type BGP_TRANSIT ", prepend_count, "x to ",
2270 {self.functions.route_info()};
2271 {self.peer_prepend(BirdVariable("peer_asn"), BirdVariable("prepend_count"))};
2272 }}"""
2274 @BirdFunction("bgp_peer_prepend_bgp_transit_default")
2275 def peer_prepend_bgp_transit_default(self, *args: Any) -> str: # pylint: disable=unused-argument
2276 """BIRD bgp_peer_prepend_bgp_transit_default function."""
2278 return f"""\
2279 function bgp_peer_prepend_bgp_transit_default(string filter_name; int peer_asn; int prepend_count) -> bool {{
2280 if (
2281 !{self.is_bgp_transit()} ||
2282 !{self.functions.is_default()} ||
2283 {self.is_blackhole()}
2284 ) then return false;
2285 if DEBUG then print filter_name,
2286 " [bgp_peer_prepend_bgp_transit_default] Prepending AS-PATH for type BGP_TRANSIT DEFAULT ", prepend_count,
2287 "x to ", {self.functions.route_info()};
2288 {self.peer_prepend(BirdVariable("peer_asn"), BirdVariable("prepend_count"))};
2289 }}"""
2291 @BirdFunction("bgp_peer_prepend_lc")
2292 def peer_prepend_lc(self, *args: Any) -> str: # pylint: disable=unused-argument
2293 """BIRD bgp_peer_prepend_lc function."""
2295 return f"""\
2296 # BGP large community based prepending
2297 function bgp_peer_prepend_lc(string filter_name; int peer_asn)
2298 int prepend_asn;
2299 {{
2300 # Make sure we use the right ASN when prepending, and not 0 if bgp_path is empty
2301 if (bgp_path.len = 0) then {{
2302 prepend_asn = BGP_ASN;
2303 }} else {{
2304 prepend_asn = bgp_path.first;
2305 }}
2306 # If we are prepending three times
2307 if ((BGP_ASN, BGP_LC_FUNCTION_PREPEND_THREE, peer_asn) ~ bgp_large_community) then {{
2308 if DEBUG then print filter_name,
2309 " [bgp_peer_prepend_lc] Matched BGP_LC_FUNCTION_PREPEND_THREE for ", {self.functions.route_info()};
2310 {self.peer_prepend(BirdVariable("prepend_asn"), 3)};
2311 # If we are prepending two times
2312 }} else if ((BGP_ASN, BGP_LC_FUNCTION_PREPEND_TWO, peer_asn) ~ bgp_large_community) then {{
2313 if DEBUG then print filter_name,
2314 " [bgp_peer_prepend_lc] Matched BGP_LC_FUNCTION_PREPEND_TWO for ", {self.functions.route_info()};
2315 {self.peer_prepend(BirdVariable("prepend_asn"), 2)};
2316 # If we are prepending one time
2317 }} else if ((BGP_ASN, BGP_LC_FUNCTION_PREPEND_ONE, peer_asn) ~ bgp_large_community) then {{
2318 if DEBUG then print filter_name,
2319 " [bgp_peer_prepend_lc] Matched BGP_LC_FUNCTION_PREPEND_ONE for ", {self.functions.route_info()};
2320 {self.peer_prepend(BirdVariable("prepend_asn"), 1)};
2321 }} else if ((BGP_ASN, BGP_LC_FUNCTION_PREPEND_ONE_2, peer_asn) ~ bgp_large_community) then {{
2322 if DEBUG then print filter_name,
2323 " [bgp_peer_prepend_lc] Matched BGP_LC_FUNCTION_PREPEND_ONE_2 for ", {self.functions.route_info()};
2324 {self.peer_prepend(BirdVariable("prepend_asn"), 1)};
2325 }}
2326 }}"""
2328 @BirdFunction("bgp_peer_prepend_lc_location")
2329 def peer_prepend_lc_location(self, *args: Any) -> str: # pylint: disable=unused-argument
2330 """BIRD bgp_peer_prepend_location function."""
2332 return f"""\
2333 # BGP large community location based prepending
2334 function bgp_peer_prepend_lc_location(string filter_name; int location)
2335 int prepend_asn;
2336 {{
2337 # Make sure we use the right ASN when prepending, and not 0 if bgp_path is empty
2338 if (bgp_path.len = 0) then {{
2339 prepend_asn = BGP_ASN;
2340 }} else {{
2341 prepend_asn = bgp_path.first;
2342 }}
2343 # If we are prepending three times
2344 if ((BGP_ASN, BGP_LC_FUNCTION_PREPEND_LOCATION_THREE, location) ~ bgp_large_community) then {{
2345 if DEBUG then print filter_name,
2346 " [bgp_peer_prepend_lc_location] Matched BGP_LC_FUNCTION_PREPEND_LOCATION_THREE for ",
2347 {self.functions.route_info()};
2348 {self.peer_prepend(BirdVariable("prepend_asn"), 3)};
2349 # If we are prepending two times
2350 }} else if ((BGP_ASN, BGP_LC_FUNCTION_PREPEND_LOCATION_TWO, location) ~ bgp_large_community) then {{
2351 if DEBUG then print filter_name,
2352 " [bgp_peer_prepend_lc_location] Matched BGP_LC_FUNCTION_PREPEND_LOCATION_TWO for ",
2353 {self.functions.route_info()};
2354 {self.peer_prepend(BirdVariable("prepend_asn"), 2)};
2355 # If we are prepending one time
2356 }} else if ((BGP_ASN, BGP_LC_FUNCTION_PREPEND_LOCATION_ONE, location) ~ bgp_large_community) then {{
2357 if DEBUG then print filter_name,
2358 " [bgp_peer_prepend_lc_location] Matched BGP_LC_FUNCTION_PREPEND_LOCATION_ONE for ",
2359 {self.functions.route_info()};
2360 {self.peer_prepend(BirdVariable("prepend_asn"), 1)};
2361 }} else if ((BGP_ASN, BGP_LC_FUNCTION_PREPEND_LOCATION_ONE_2, location) ~ bgp_large_community) then {{
2362 if DEBUG then print filter_name,
2363 " [bgp_peer_prepend_lc_location] Matched BGP_LC_FUNCTION_PREPEND_LOCATION_ONE_2 for ",
2364 {self.functions.route_info()};
2365 {self.peer_prepend(BirdVariable("prepend_asn"), 1)};
2366 }}
2367 }}"""
2369 @BirdFunction("bgp_peer_quarantine")
2370 def peer_quarantine(self, *args: Any) -> str: # pylint: disable=unused-argument
2371 """BIRD bgp_peer_quarantine function."""
2373 return f"""\
2374 # Quarantine peer
2375 function bgp_peer_quarantine(string filter_name) {{
2376 if DEBUG then print filter_name,
2377 " [bgp_peer_quarantine] Adding BGP_LC_FILTERED_QUARANTINED to ", {self.functions.route_info()};
2378 bgp_large_community.add(BGP_LC_FILTERED_QUARANTINED);
2379 }}"""
2381 @BirdFunction("bgp_peer_redistribute_bgp_customer")
2382 def peer_redistribute_bgp_customer(self, *args: Any) -> str: # pylint: disable=unused-argument
2383 """BIRD bgp_peer_redistribute_bgp_customer function."""
2385 return f"""\
2386 # Check for redistribution of customer routes for BGP
2387 function bgp_peer_redistribute_bgp_customer(string filter_name; bool redistribute) -> bool {{
2388 # Check for redistribute customer routes
2389 if (!{self.is_bgp_customer()} || {self.is_blackhole()} || {self.functions.is_default()}) then return false;
2390 if (redistribute) then {{
2391 if DEBUG then print filter_name,
2392 " [bgp_peer_redistribute_bgp_customer] Accepting ", {self.functions.route_info()},
2393 " due to BGP_LC_RELATION_CUSTOMER route match (redistribute customer)";
2394 return true;
2395 }}
2396 if DEBUG then print filter_name,
2397 " [bgp_peer_redistribute_bgp_customer] Rejecting ", {self.functions.route_info()},
2398 " due to BGP_LC_RELATION_CUSTOMER route match (no redistribute customer)";
2399 reject;
2400 }}"""
2402 @BirdFunction("bgp_peer_redistribute_bgp_customer_blackhole")
2403 def peer_redistribute_bgp_customer_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
2404 """BIRD bgp_peer_redistribute_bgp_customer_blackhole function."""
2406 return f"""\
2407 # Check for redistribution of customer blackhole routes for BGP
2408 function bgp_peer_redistribute_bgp_customer_blackhole(string filter_name; bool redistribute) -> bool {{
2409 # Check for redistribute customer blackhole routes
2410 if (!{self.is_bgp_customer()} || !{self.is_blackhole()} || {self.functions.is_default()}) then return false;
2411 if (redistribute) then {{
2412 if DEBUG then print filter_name,
2413 " [bgp_peer_redistribute_bgp_customer_blackhole] Accepting ", {self.functions.route_info()},
2414 " due to BGP_LC_RELATION_CUSTOMER and blackhole route match (redistribute customer blackhole)";
2415 return true;
2416 }}
2417 if DEBUG then print filter_name,
2418 " [bgp_peer_redistribute_bgp_customer_blackhole] Rejecting ", {self.functions.route_info()},
2419 " due to BGP_LC_RELATION_CUSTOMER and blackhole route match (no redistribute customer blackhole)";
2420 reject;
2421 }}"""
2423 @BirdFunction("bgp_peer_redistribute_bgp_own")
2424 def peer_redistribute_bgp_own(self, *args: Any) -> str: # pylint: disable=unused-argument
2425 """BIRD bgp_peer_redistribute_bgp_own function."""
2427 return f"""\
2428 # Check for redistribution of our own routes for BGP
2429 function bgp_peer_redistribute_bgp_own(string filter_name; bool redistribute) -> bool {{
2430 # Check for redistribute own routes
2431 if (!{self.is_bgp_own()} || {self.is_blackhole()} || {self.functions.is_default()}) then return false;
2432 if (redistribute) then {{
2433 if DEBUG then print filter_name,
2434 " [bgp_peer_redistribute_bgp_own] Accepting ", {self.functions.route_info()},
2435 " due to BGP_LC_RELATION_OWN route match (redistribute own)";
2436 return true;
2437 }}
2438 if DEBUG then print filter_name,
2439 " [bgp_peer_redistribute_bgp_own] Rejecting ", {self.functions.route_info()},
2440 " due to BGP_LC_RELATION_OWN route match (no redistribute own)";
2441 reject;
2442 }}"""
2444 @BirdFunction("bgp_peer_redistribute_bgp_own_blackhole")
2445 def peer_redistribute_bgp_own_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
2446 """BIRD bgp_peer_redistribute_bgp_own_blackhole function."""
2448 return f"""\
2449 # Check for redistribution of our own blackhoole routes for BGP
2450 function bgp_peer_redistribute_bgp_own_blackhole(string filter_name; bool redistribute) -> bool {{
2451 # Check for redistribute own blackhole routes
2452 if (!{self.is_bgp_own()} || !{self.is_blackhole()} || {self.functions.is_default()}) then return false;
2453 if (redistribute) then {{
2454 if DEBUG then print filter_name,
2455 " [bgp_peer_redistribute_bgp_own_blackhole] Accepting ", {self.functions.route_info()},
2456 " due to BGP_LC_RELATION_OWN and blackhole route match (redistribute own blackhole)";
2457 return true;
2458 }}
2459 if DEBUG then print filter_name,
2460 " [bgp_peer_redistribute_bgp_own_blackhole] Rejecting ", {self.functions.route_info()},
2461 " due to BGP_LC_RELATION_OWN and blackhole route match (no redistribute own blackhole)";
2462 reject;
2463 }}"""
2465 @BirdFunction("bgp_peer_redistribute_bgp_own_default")
2466 def peer_redistribute_bgp_own_default(self, *args: Any) -> str: # pylint: disable=unused-argument
2467 """BIRD bgp_peer_redistribute_bgp_own_default function."""
2469 return f"""\
2470 # Check for redistribution of our own default routes for BGP
2471 function bgp_peer_redistribute_bgp_own_default(string filter_name; bool redistribute) -> bool {{
2472 # Check for redistribute own default routes
2473 if (!{self.is_bgp_own()} || {self.is_blackhole()} || !{self.functions.is_default()}) then return false;
2474 if (redistribute) then {{
2475 if DEBUG then print filter_name,
2476 " [bgp_peer_redistribute_bgp_own_default] Accepting ", {self.functions.route_info()},
2477 " due to BGP_LC_RELATION_OWN and default route match (redistribute own default)";
2478 return true;
2479 }}
2480 if DEBUG then print filter_name,
2481 " [bgp_peer_redistribute_bgp_own_default] Rejecting ", {self.functions.route_info()},
2482 " due to BGP_LC_RELATION_OWN and default route match (no redistribute own default)";
2483 reject;
2484 }}"""
2486 @BirdFunction("bgp_peer_redistribute_bgp_peering")
2487 def peer_redistribute_bgp_peering(self, *args: Any) -> str: # pylint: disable=unused-argument
2488 """BIRD bgp_peer_redistribute_bgp_peering function."""
2490 return f"""\
2491 # Check for redistribution of peering routes for BGP
2492 function bgp_peer_redistribute_bgp_peering(string filter_name; bool redistribute) -> bool {{
2493 if (!{self.is_bgp_peering()} || {self.is_blackhole()} || {self.functions.is_default()}) then return false;
2494 # Check for redistribute peering routes
2495 if {self.is_bgp_peer()} then {{
2496 if (redistribute) then {{
2497 if DEBUG then print filter_name,
2498 " [bgp_peer_redistribute_bgp_peering] Accepting ", {self.functions.route_info()},
2499 " due to BGP_LC_RELATION_PEER route match (redistribute peering)";
2500 return true;
2501 }}
2502 if DEBUG then print filter_name,
2503 " [bgp_peer_redistribute_bgp_peering] Rejecting ", {self.functions.route_info()},
2504 " due to BGP_LC_RELATION_PEER route match (no redistribute peering)";
2505 reject;
2506 }}
2507 # Check for redistribute routeserver routes
2508 if {self.is_bgp_routeserver()} then {{
2509 if (redistribute) then {{
2510 if DEBUG then print filter_name,
2511 " [bgp_peer_redistribute_bgp_peering] Accepting ", {self.functions.route_info()},
2512 " due to BGP_LC_RELATION_ROUTESERVER route match (redistribute peering)";
2513 return true;
2514 }}
2515 if DEBUG then print filter_name,
2516 " [bgp_peer_redistribute_bgp_peering] Rejecting ", {self.functions.route_info()},
2517 " due to BGP_LC_RELATION_ROUTESERVER route match (no redistribute peering)";
2518 reject;
2519 }}
2520 return false;
2521 }}"""
2523 @BirdFunction("bgp_peer_redistribute_bgp_transit")
2524 def peer_redistribute_bgp_transit(self, *args: Any) -> str: # pylint: disable=unused-argument
2525 """BIRD bgp_peer_redistribute_bgp_transit function."""
2527 return f"""\
2528 # Check for redistribution of transit routes for BGP
2529 function bgp_peer_redistribute_bgp_transit(string filter_name; bool redistribute) -> bool {{
2530 # Check for redistribute transit routes
2531 if (!{self.is_bgp_transit()} || {self.is_blackhole()} || {self.functions.is_default()}) then return false;
2532 if (redistribute) then {{
2533 if DEBUG then print filter_name,
2534 " [bgp_peer_redistribute_bgp_transit] Accepting ", {self.functions.route_info()},
2535 " due to BGP_LC_RELATION_TRANSIT route match (redistribute transit)";
2536 return true;
2537 }}
2538 if DEBUG then print filter_name,
2539 " [bgp_peer_redistribute_bgp_transit] Rejecting ", {self.functions.route_info()},
2540 " due to BGP_LC_RELATION_TRANSIT route match (no redistribute transit)";
2541 reject;
2542 }}"""
2544 @BirdFunction("bgp_peer_redistribute_bgp_transit_default")
2545 def peer_redistribute_bgp_transit_default(self, *args: Any) -> str: # pylint: disable=unused-argument
2546 """BIRD bgp_peer_redistribute_bgp_transit_default function."""
2548 return f"""\
2549 # Check for redistribution of transit routes for BGP
2550 function bgp_peer_redistribute_bgp_transit_default(string filter_name; bool redistribute) -> bool {{
2551 # Check for redistribute transit routes
2552 if (!{self.is_bgp_transit()} || {self.is_blackhole()} || !{self.functions.is_default()}) then return false;
2553 if (redistribute) then {{
2554 if DEBUG then print filter_name,
2555 " [bgp_peer_redistribute_bgp_transit_default] Accepting ", {self.functions.route_info()},
2556 " due to BGP_LC_RELATION_TRANSIT and default route match (redistribute transit default)";
2557 return true;
2558 }}
2559 if DEBUG then print filter_name,
2560 " [bgp_peer_redistribute_bgp_transit_default] Rejecting ", {self.functions.route_info()},
2561 " due to BGP_LC_RELATION_TRANSIT and default route match (no redistribute transit default)";
2562 reject;
2563 }}"""
2565 @BirdFunction("bgp_peer_redistribute_connected")
2566 def peer_redistribute_connected(self, *args: Any) -> str: # pylint: disable=unused-argument
2567 """BIRD bgp_peer_redistribute_connected function."""
2569 return f"""\
2570 # Check for redistribution of connected routes for BGP
2571 function bgp_peer_redistribute_connected(string filter_name; bool redistribute) -> bool {{
2572 # Check for connected routes
2573 if !{self.is_connected()} then return false;
2574 if (redistribute) then {{
2575 if DEBUG then print filter_name,
2576 " [bgp_peer_redistribute_connected] Accepting ", {self.functions.route_info()},
2577 " due to direct route match (redistribute connected)";
2578 return true;
2579 }}
2580 if DEBUG then print filter_name,
2581 " [bgp_peer_redistribute_connected] Rejecting ", {self.functions.route_info()},
2582 " due to direct route match (no redistribute connected)";
2583 reject;
2584 }}"""
2586 @BirdFunction("bgp_peer_redistribute_kernel")
2587 def peer_redistribute_kernel(self, *args: Any) -> str: # pylint: disable=unused-argument
2588 """BIRD bgp_peer_redistribute_kernel function."""
2590 return f"""\
2591 # Check for redistribution of kernel routes for BGP
2592 function bgp_peer_redistribute_kernel(string filter_name; bool redistribute) -> bool {{
2593 if (!{self.functions.is_kernel()} || {self.is_blackhole()} || {self.functions.is_default()}) then return false;
2594 if (redistribute) then {{
2595 if DEBUG then print filter_name,
2596 " [bgp_peer_redistribute_kernel] Accepting ", {self.functions.route_info()},
2597 " due to kernel route match (redistribute kernel)";
2598 return true;
2599 }}
2600 if DEBUG then print filter_name,
2601 " [bgp_peer_redistribute_kernel] Rejecting ", {self.functions.route_info()},
2602 " due to kernel route match (no redistribute kernel)";
2603 reject;
2604 }}"""
2606 @BirdFunction("bgp_peer_redistribute_kernel_blackhole")
2607 def peer_redistribute_kernel_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
2608 """BIRD bgp_peer_redistribute_kernel_blackhole function."""
2610 return f"""\
2611 # Check for redistribution of kernel blackhole routes for BGP
2612 function bgp_peer_redistribute_kernel_blackhole(string filter_name; bool redistribute) -> bool {{
2613 if (!{self.functions.is_kernel()} || !{self.is_blackhole()} || {self.functions.is_default()}) then return false;
2614 if (redistribute) then {{
2615 if DEBUG then print filter_name,
2616 " [bgp_peer_redistribute_kernel_blackhole] Accepting ", {self.functions.route_info()},
2617 " due to kernel blackhole route match (redistribute kernel)";
2618 return true;
2619 }}
2620 if DEBUG then print filter_name,
2621 " [bgp_peer_redistribute_kernel_blackhole] Rejecting ", {self.functions.route_info()},
2622 " due to kernel blackhole route match (no redistribute kernel)";
2623 reject;
2624 }}"""
2626 @BirdFunction("bgp_peer_redistribute_kernel_default")
2627 def peer_redistribute_kernel_default(self, *args: Any) -> str: # pylint: disable=unused-argument
2628 """BIRD bgp_peer_redistribute_kernel_default function."""
2630 return f"""\
2631 # Check for redistribution of kernel default routes for BGP
2632 function bgp_peer_redistribute_kernel_default(string filter_name; bool redistribute) -> bool {{
2633 if (!{self.functions.is_kernel()} || {self.is_blackhole()} || !{self.functions.is_default()}) then
2634 return false;
2635 if (redistribute) then {{
2636 if DEBUG then print filter_name,
2637 " [bgp_peer_redistribute_kernel_default] Accepting ", {self.functions.route_info()},
2638 " due to kernel default route match (redistribute kernel default) and accepted";
2639 return true;
2640 }}
2641 if DEBUG then print filter_name,
2642 " [bgp_peer_redistribute_kernel_default] Rejecting ", {self.functions.route_info()},
2643 " due to kernel default route match";
2644 reject;
2645 }}"""
2647 @BirdFunction("bgp_peer_redistribute_originated")
2648 def peer_redistribute_originated(self, *args: Any) -> str: # pylint: disable=unused-argument
2649 """BIRD bgp_peer_redistribute_originated function."""
2651 return f"""\
2652 # Check for redistribution of originated routes for BGP
2653 function bgp_peer_redistribute_originated(string filter_name; bool redistribute) -> bool {{
2654 if (!{self.is_originated()} || {self.is_blackhole()} || {self.functions.is_default()}) then
2655 return false;
2656 if (redistribute) then {{
2657 if DEBUG then print filter_name,
2658 " [bgp_peer_redistribute_originated] Accepting ", {self.functions.route_info()},
2659 " due to originated route match (redistribute originated)";
2660 return true;
2661 }}
2662 if DEBUG then print filter_name,
2663 " [bgp_peer_redistribute_originated] Rejecting ", {self.functions.route_info()},
2664 " due to originated route match (no redistribute originated)";
2665 reject;
2666 }}"""
2668 @BirdFunction("bgp_peer_redistribute_originated_default")
2669 def peer_redistribute_originated_default(self, *args: Any) -> str: # pylint: disable=unused-argument
2670 """BIRD bgp_peer_redistribute_originated_default function."""
2672 return f"""\
2673 # Check for redistribution of originated default routes for BGP
2674 function bgp_peer_redistribute_originated_default(string filter_name; bool redistribute) -> bool {{
2675 if (!{self.is_originated()} || {self.is_blackhole()} || !{self.functions.is_default()}) then return false;
2676 if (redistribute) then {{
2677 if DEBUG then print filter_name,
2678 " [bgp_peer_redistribute_originated_default] Accepting ", {self.functions.route_info()},
2679 " due to originated default route match (redistribute originated default) and accepted";
2680 return true;
2681 }}
2682 if DEBUG then print filter_name,
2683 " [bgp_peer_redistribute_originated_default] Rejecting ", {self.functions.route_info()},
2684 " due to originated default route match";
2685 reject;
2686 }}"""
2688 @BirdFunction("bgp_peer_redistribute_static")
2689 def peer_redistribute_static(self, *args: Any) -> str: # pylint: disable=unused-argument
2690 """BIRD bgp_peer_redistribute_static function."""
2692 return f"""\
2693 # Check for redistribution of static routes for BGP
2694 function bgp_peer_redistribute_static(string filter_name; bool redistribute) -> bool {{
2695 if (!{self.functions.is_static()} || {self.is_blackhole()} || {self.functions.is_default()}) then return false;
2696 if (redistribute) then {{
2697 if DEBUG then print filter_name,
2698 " [bgp_peer_redistribute_static] Accepting ", {self.functions.route_info()},
2699 " due to static route match (redistribute static)";
2700 return true;
2701 }}
2702 if DEBUG then print filter_name,
2703 " [bgp_peer_redistribute_static] Rejecting ", {self.functions.route_info()},
2704 " due to static route match (no redistribute static)";
2705 reject;
2706 }}"""
2708 @BirdFunction("bgp_peer_redistribute_static_blackhole")
2709 def peer_redistribute_static_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
2710 """BIRD bgp_peer_redistribute_static_blackhole function."""
2712 return f"""\
2713 # Check for redistribution of static blackhole routes for BGP
2714 function bgp_peer_redistribute_static_blackhole(string filter_name; bool redistribute) -> bool {{
2715 if (!{self.functions.is_static()} || !{self.is_blackhole()} || {self.functions.is_default()}) then return false;
2716 if (redistribute) then {{
2717 if DEBUG then print filter_name,
2718 " [bgp_peer_redistribute_static_blackhole] Accepting ", {self.functions.route_info()},
2719 " due to static blackhole route match (redistribute static)";
2720 return true;
2721 }}
2722 if DEBUG then print filter_name,
2723 " [bgp_peer_redistribute_static_blackhole] Rejecting ", {self.functions.route_info()},
2724 " due to static blackhole route match (no redistribute static)";
2725 reject;
2726 }}"""
2728 @BirdFunction("bgp_peer_redistribute_static_default")
2729 def peer_redistribute_static_default(self, *args: Any) -> str: # pylint: disable=unused-argument
2730 """BIRD bgp_peer_redistribute_static_default function."""
2732 return f"""\
2733 # Check for redistribution of static default routes for BGP
2734 function bgp_peer_redistribute_static_default(string filter_name; bool redistribute) -> bool {{
2735 if (!{self.functions.is_static()} || {self.is_blackhole()} || !{self.functions.is_default()}) then
2736 return false;
2737 if (redistribute) then {{
2738 if DEBUG then print filter_name,
2739 " [bgp_peer_redistribute_static_default] Accepting ", {self.functions.route_info()},
2740 " due to static default route match (redistribute static default) and accepted";
2741 return true;
2742 }}
2743 if DEBUG then print filter_name,
2744 " [bgp_peer_redistribute_static_default] Rejecting ", {self.functions.route_info()},
2745 " due to static default route match";
2746 reject;
2747 }}"""
2749 @BirdFunction("bgp_peer_reject_blackholes")
2750 def peer_reject_blackholes(self, *args: Any) -> str: # pylint: disable=unused-argument
2751 """BIRD bgp_peer_reject_blackholes function."""
2753 return f"""\
2754 # Reject blackhole routes
2755 function bgp_peer_reject_blackholes(string filter_name) -> bool {{
2756 if !{self.is_blackhole()} then return false;
2757 if DEBUG then print filter_name,
2758 " [bgp_peer_reject_blackholes] Rejecting blackhole ", {self.functions.route_info()},
2759 " due to match on BGP_COMMUNITY_BLACKHOLE";
2760 reject;
2761 }}"""
2763 @BirdFunction("bgp_peer_reject_bogons")
2764 def peer_reject_bogons(self, *args: Any) -> str: # pylint: disable=unused-argument
2765 """BIRD bgp_peer_reject_bogons function."""
2767 return f"""\
2768 # Reject bogon routes
2769 function bgp_peer_reject_bogons(string filter_name) -> bool {{
2770 if !{self.functions.is_bogon()} then return false;
2771 if DEBUG then print filter_name,
2772 " [bgp_peer_reject_bogons] Rejecting bogon ", {self.functions.route_info()};
2773 reject;
2774 }}"""
2776 @BirdFunction("bgp_peer_reject_filtered")
2777 def peer_reject_filtered(self, *args: Any) -> str: # pylint: disable=unused-argument
2778 """BIRD bgp_peer_reject_filtered function."""
2780 return f"""\
2781 # Reject filtered routes to main BGP table
2782 function bgp_peer_reject_filtered(string filter_name) -> bool {{
2783 if (bgp_large_community !~ [(BGP_ASN, BGP_LC_FUNCTION_FILTERED, *)]) then return false;
2784 if DEBUG then print filter_name,
2785 " [bgp_peer_reject_filtered] Filtered ", {self.functions.route_info()}, " to main BGP table";
2786 reject;
2787 }}"""
2789 @BirdFunction("bgp_peer_reject_noadvertise")
2790 def peer_reject_noadvertise(self, *args: Any) -> str: # pylint: disable=unused-argument
2791 """BIRD bgp_peer_reject_noadvertise function."""
2793 return f"""\
2794 # Reject NO_ADVERTISE routes
2795 function bgp_peer_reject_noadvertise(string filter_name) -> bool {{
2796 # Check for NO_ADVERTISE community
2797 if (BGP_COMMUNITY_NOADVERTISE !~ bgp_community) then return false;
2798 if DEBUG then print filter_name,
2799 " [bgp_peer_reject_noadvertise] Rejecting ", {self.functions.route_info()},
2800 " due to match on BGP_COMMUNITY_NOADVERTISE";
2801 reject;
2802 }}"""
2804 @BirdFunction("bgp_peer_reject_noexport")
2805 def peer_reject_noexport(self, *args: Any) -> str: # pylint: disable=unused-argument
2806 """BIRD bgp_peer_reject_noexport function."""
2808 return f"""\
2809 # Reject NOEXPORT routes
2810 function bgp_peer_reject_noexport(string filter_name) -> bool {{
2811 if (BGP_COMMUNITY_NOEXPORT !~ bgp_community) then return false;
2812 if DEBUG then print filter_name,
2813 " [bgp_peer_reject_noexport] Rejecting ", {self.functions.route_info()},
2814 " due to match on BGP_COMMUNITY_NOEXPORT";
2815 reject;
2816 }}"""
2818 @BirdFunction("bgp_peer_reject_noexport_asn")
2819 def peer_reject_noexport_asn(self, *args: Any) -> str: # pylint: disable=unused-argument
2820 """BIRD bgp_peer_reject_noexport_asn function."""
2822 return f"""\
2823 # Reject NOEXPORT ASN routes
2824 function bgp_peer_reject_noexport_asn(string filter_name; int peer_asn) -> bool {{
2825 # Check for NOEXPORT large community
2826 if ((BGP_ASN, BGP_LC_FUNCTION_NOEXPORT, peer_asn) !~ bgp_large_community) then return false;
2827 if DEBUG then print filter_name,
2828 " [bgp_peer_reject_noexport_asn] Rejecting ", {self.functions.route_info()},
2829 " due to match on BGP_LC_FUNCTION_NOEXPORT for AS", peer_asn;
2830 reject;
2831 }}"""
2833 @BirdFunction("bgp_peer_reject_noexport_customer")
2834 def peer_reject_noexport_customer(self, *args: Any) -> str: # pylint: disable=unused-argument
2835 """BIRD bgp_peer_reject_noexport_customer function."""
2837 return f"""\
2838 # Reject EXPORT_NOCUSTOMER routes
2839 function bgp_peer_reject_noexport_customer(string filter_name) -> bool {{
2840 # Check for large community to prevent export to customers
2841 if (BGP_LC_EXPORT_NOCUSTOMER !~ bgp_large_community) then return false;
2842 if DEBUG then print filter_name,
2843 " [bgp_peer_reject_noexport_customer] Rejecting ", {self.functions.route_info()},
2844 " due to match on BGP_LC_EXPORT_NOCUSTOMER";
2845 reject;
2846 }}"""
2848 @BirdFunction("bgp_peer_reject_noexport_peer")
2849 def peer_reject_noexport_peer(self, *args: Any) -> str: # pylint: disable=unused-argument
2850 """BIRD bgp_peer_reject_noexport_peer function."""
2852 return f"""\
2853 # Reject EXPORT_NOPEER routes
2854 function bgp_peer_reject_noexport_peer(string filter_name) -> bool {{
2855 # Check for large community to prevent export to peers
2856 if (BGP_LC_EXPORT_NOPEER !~ bgp_large_community) then return false;
2857 if DEBUG then print filter_name,
2858 " [bgp_peer_reject_noexport_peer] Rejecting ", {self.functions.route_info()},
2859 " due to match on BGP_LC_EXPORT_NOPEER";
2860 reject;
2861 }}"""
2863 @BirdFunction("bgp_peer_reject_noexport_transit")
2864 def peer_reject_noexport_transit(self, *args: Any) -> str: # pylint: disable=unused-argument
2865 """BIRD bgp_peer_reject_noexport_transit function."""
2867 return f"""\
2868 # Reject EXPORT_NOTRANSIT routes
2869 function bgp_peer_reject_noexport_transit(string filter_name) -> bool {{
2870 # Check for large community to prevent export to transit
2871 if (BGP_LC_EXPORT_NOTRANSIT !~ bgp_large_community) then return false;
2872 if DEBUG then print filter_name,
2873 " [bgp_peer_reject_noexport_transit] Rejecting ", {self.functions.route_info()},
2874 " due to match on BGP_LC_EXPORT_NOTRANSIT";
2875 reject;
2876 }}"""
2878 @BirdFunction("bgp_peer_reject_noexport_location")
2879 def peer_reject_noexport_location(self, *args: Any) -> str: # pylint: disable=unused-argument
2880 """BIRD bgp_peer_reject_noexport_location function."""
2882 return f"""\
2883 # Reject NOEXPORT_LOCATION routes
2884 function bgp_peer_reject_noexport_location(string filter_name; int location) -> bool {{
2885 # Check for large community to prevent export to a location
2886 if ((BGP_ASN, BGP_LC_FUNCTION_NOEXPORT_LOCATION, location) !~ bgp_large_community) then return false;
2887 if DEBUG then print filter_name,
2888 " [bgp_peer_reject_noexport_location] Rejecting ", {self.functions.route_info()},
2889 " due to match on BGP_LC_FUNCTION_NOEXPORT_LOCATION with location ", location;
2890 reject;
2891 }}"""
2893 @BirdFunction("bgp_peer_reject_non_exportable")
2894 def peer_reject_non_exportable(self, *args: Any) -> str: # pylint: disable=unused-argument
2895 """BIRD bgp_peer_reject_non_exportable function."""
2897 return f"""\
2898 # Can we export this route to the peer_asn?
2899 function bgp_peer_reject_non_exportable(
2900 string filter_name;
2901 int ipv4_maxlen; int ipv4_minlen;
2902 int ipv6_maxlen; int ipv6_minlen
2903 ) -> bool
2904 int prefix_maxlen;
2905 int prefix_minlen;
2906 {{
2907 # Work out what prefix lenghts we're going to use
2908 if (net.type = NET_IP4) then {{
2909 prefix_maxlen = ipv4_maxlen;
2910 prefix_minlen = ipv4_minlen;
2911 }}
2912 if (net.type = NET_IP6) then {{
2913 prefix_maxlen = ipv6_maxlen;
2914 prefix_minlen = ipv6_minlen;
2915 }}
2916 # Validate route before export
2917 if {self.functions.prefix_is_longer(BirdVariable("prefix_maxlen"))} then {{
2918 if DEBUG then print filter_name,
2919 " [bgp_peer_reject_non_exportable] Not exporting due to prefix length >", prefix_maxlen," for ",
2920 {self.functions.route_info()};
2921 reject;
2922 }}
2923 if {self.functions.prefix_is_shorter(BirdVariable("prefix_minlen"))} then {{
2924 if DEBUG then print filter_name,
2925 " [bgp_peer_reject_non_exportable] Not exporting due to prefix length <", prefix_minlen, " for ",
2926 {self.functions.route_info()};
2927 reject;
2928 }}
2929 # If all above tests are ok, then we can
2930 return true;
2931 }}"""
2933 @BirdFunction("bgp_peer_reject_non_exportable_blackhole")
2934 def peer_reject_non_exportable_blackhole(self, *args: Any) -> str: # pylint: disable=unused-argument
2935 """BIRD bgp_peer_reject_non_exportable_blackhole function."""
2937 return f"""\
2938 # Can we export this route to the peer_asn?
2939 function bgp_peer_reject_non_exportable_blackhole(
2940 string filter_name;
2941 int ipv4_maxlen; int ipv4_minlen;
2942 int ipv6_maxlen; int ipv6_minlen
2943 ) -> bool
2944 int prefix_maxlen;
2945 int prefix_minlen;
2946 {{
2947 # Work out what prefix lenghts we're going to use
2948 if (net.type = NET_IP4) then {{
2949 prefix_maxlen = ipv4_maxlen;
2950 prefix_minlen = ipv4_minlen;
2951 }}
2952 if (net.type = NET_IP6) then {{
2953 prefix_maxlen = ipv6_maxlen;
2954 prefix_minlen = ipv6_minlen;
2955 }}
2956 # Validate route before export
2957 if {self.functions.prefix_is_longer(BirdVariable("prefix_maxlen"))} then {{
2958 if DEBUG then print filter_name,
2959 " [bgp_peer_reject_non_exportable_blackhole] Not exporting due to prefix length >", prefix_maxlen," for ",
2960 net;
2961 reject;
2962 }}
2963 if {self.functions.prefix_is_shorter(BirdVariable("prefix_minlen"))} then {{
2964 if DEBUG then print filter_name,
2965 " [bgp_peer_reject_non_exportable_blackhole] Not exporting due to prefix length <", prefix_minlen, " for ",
2966 net;
2967 reject;
2968 }}
2969 # If all above tests are ok, then we can
2970 return true;
2971 }}"""
2973 @BirdFunction("bgp_peer_replace_aspath")
2974 def peer_replace_aspath(self, *args: Any) -> str: # pylint: disable=unused-argument
2975 """BIRD bgp_peer_replace_aspath function."""
2977 return f"""\
2978 # Check if we need to replace the AS-PATH
2979 function bgp_peer_replace_aspath(string filter_name) -> bool
2980 int path_len;
2981 {{
2982 # Check for replace AS-PATH large community action
2983 if (BGP_LC_ACTION_REPLACE_ASPATH !~ bgp_large_community) then return false;
2984 # Grab current path length
2985 path_len = bgp_path.len;
2986 if DEBUG then print filter_name,
2987 " [bgp_peer_replace_aspath] Replacing AS-PATH [", bgp_path, "] for ", {self.functions.route_info()},
2988 " with ", path_len, "x ", BGP_ASN;
2989 # Empty the path, as we cannot assign a sequence
2990 bgp_path.empty;
2991 # Prepend our own ASN the number of times there was an ASN in the path
2992 path_len = path_len - 1;
2993 {self.peer_prepend(BirdVariable("BGP_ASN"), BirdVariable("path_len"))};
2994 }}"""
2996 @BirdFunction("bgp_peer_remove_lc_private")
2997 def peer_remove_lc_private(self, *args: Any) -> str: # pylint: disable=unused-argument
2998 """BIRD bgp_peer_remove_lc_private function."""
3000 return f"""\
3001 # Remove private large communities
3002 function bgp_peer_remove_lc_private(string filter_name) -> bool {{
3003 # Remove private large communities
3004 if (bgp_large_community !~ BGP_LC_STRIP_PRIVATE) then return false;
3005 if DEBUG then print filter_name,
3006 " [bgp_peer_remove_lc_private] Removing private large communities from ", {self.functions.route_info()};
3007 bgp_large_community.delete(BGP_LC_STRIP_PRIVATE);
3008 }}"""
3010 @property
3011 def functions(self) -> SectionFunctions:
3012 """Return the functions section."""
3013 return self._functions