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