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

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/>. 

18 

19"""BGP protocol specific functions class.""" 

20 

21from ....globals import BirdConfigGlobals 

22from ...functions import BirdFunction, BirdFunctionArg, BirdVariable, SectionFunctions 

23from ..base_protocol_functions import ProtocolFunctionsBase 

24 

25__all__ = ["BGPFunctions"] 

26 

27 

28class BGPFunctions(ProtocolFunctionsBase): # pylint: disable=too-many-public-methods 

29 """BGP protocol specific functions class.""" 

30 

31 def __init__(self, birdconfig_globals: BirdConfigGlobals, functions: SectionFunctions) -> None: 

32 """Initialize the object.""" 

33 super().__init__(birdconfig_globals, functions) 

34 

35 self._section = "BGP Functions" 

36 

37 @BirdFunction("bgp_accept_bgp") 

38 def accept_bgp(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

39 """BIRD bgp_accept_bgp function.""" 

40 

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 }}""" 

54 

55 @BirdFunction("bgp_accept_customer_blackhole") 

56 def accept_customer_blackhole(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

57 """BIRD bgp_accept_customer_blackhole function.""" 

58 

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 }}""" 

72 

73 @BirdFunction("bgp_accept_own_blackhole") 

74 def accept_own_blackhole(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

75 """BIRD bgp_accept_own_blackhole function.""" 

76 

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 }}""" 

90 

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.""" 

94 

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 }}""" 

108 

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.""" 

112 

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 }}""" 

126 

127 @BirdFunction("bgp_accept_originated") 

128 def accept_originated(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

129 """BIRD bgp_accept_originated function.""" 

130 

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 }}""" 

139 

140 @BirdFunction("bgp_accept_originated_default") 

141 def accept_originated_default(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

142 """BIRD bgp_accept_originated_default function.""" 

143 

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 }}""" 

152 

153 @BirdFunction("bgp_is_connected") 

154 def is_connected(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

155 """BIRD bgp_is_connected function.""" 

156 

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 }""" 

163 

164 @BirdFunction("bgp_is_originated") 

165 def is_originated(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

166 """BIRD bgp_is_originated function.""" 

167 

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 }""" 

174 

175 @BirdFunction("bgp_is_bgp_customer") 

176 def is_bgp_customer(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

177 """BIRD bgp_is_bgp_customer function.""" 

178 

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 }""" 

185 

186 @BirdFunction("bgp_is_bgp_own") 

187 def is_bgp_own(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

188 """BIRD bgp_is_bgp_own function.""" 

189 

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 }}""" 

196 

197 @BirdFunction("bgp_is_bgp_peer") 

198 def is_bgp_peer(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

199 """BIRD bgp_is_bgp_peer function.""" 

200 

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 }""" 

207 

208 @BirdFunction("bgp_is_bgp_peering") 

209 def is_bgp_peering(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

210 """BIRD bgp_is_bgp_peering function.""" 

211 

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 }}""" 

218 

219 @BirdFunction("bgp_is_bgp_routeserver") 

220 def is_bgp_routeserver(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

221 """BIRD bgp_is_bgp_routeserver function.""" 

222 

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 }""" 

229 

230 @BirdFunction("bgp_is_bgp_transit") 

231 def is_bgp_transit(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

232 """BIRD bgp_is_bgp_transit function.""" 

233 

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 }""" 

240 

241 @BirdFunction("bgp_is_blackhole") 

242 def is_blackhole(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

243 """BIRD bgp_is_blackhole function.""" 

244 

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 }""" 

251 

252 @BirdFunction("bgp_import_kernel") 

253 def import_kernel(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

254 """BIRD bgp_import_kernel function.""" 

255 

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 }}""" 

265 

266 @BirdFunction("bgp_import_kernel_blackhole") 

267 def import_kernel_blackhole(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

268 """BIRD bgp_import_kernel_blackhole function.""" 

269 

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 }}""" 

281 

282 @BirdFunction("bgp_import_kernel_default") 

283 def import_kernel_default(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

284 """BIRD bgp_import_kernel_default function.""" 

285 

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 }}""" 

295 

296 @BirdFunction("bgp_import_own") 

297 def import_own(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

298 """BIRD bgp_import_own function.""" 

299 

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 }}""" 

317 

318 @BirdFunction("bgp_import_static") 

319 def import_static(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

320 """BIRD bgp_import_static function.""" 

321 

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 }}""" 

331 

332 @BirdFunction("bgp_import_static_blackhole") 

333 def import_static_blackhole(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

334 """BIRD bgp_import_static_blackhole function.""" 

335 

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 }}""" 

347 

348 @BirdFunction("bgp_import_static_default") 

349 def import_static_default(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

350 """BIRD bgp_import_static_default function.""" 

351 

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 }}""" 

361 

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.""" 

365 

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 }}""" 

408 

409 @BirdFunction("bgp_peer_accept") 

410 def peer_accept(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

411 """BIRD bgp_peer_accept function.""" 

412 

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 }}""" 

420 

421 @BirdFunction("bgp_peer_accept_blackhole") 

422 def peer_accept_blackhole(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

423 """BIRD bgp_peer_accept_blackhole function.""" 

424 

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 }}""" 

436 

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.""" 

440 

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 }}""" 

451 

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.""" 

455 

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 }}""" 

526 

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.""" 

530 

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 }}""" 

602 

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.""" 

606 

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 }}""" 

615 

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.""" 

619 

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 }}""" 

629 

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.""" 

633 

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 }}""" 

643 

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.""" 

647 

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 }}""" 

657 

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.""" 

661 

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 }}""" 

671 

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.""" 

675 

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 }}""" 

685 

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.""" 

689 

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 }}""" 

699 

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.""" 

703 

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 }}""" 

712 

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.""" 

716 

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 }}""" 

725 

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.""" 

729 

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 }}""" 

746 

747 @BirdFunction("bgp_import_filter_blackhole") 

748 def import_filter_blackhole(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

749 """BIRD bgp_import_filter_blackhole function.""" 

750 

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 }}""" 

760 

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.""" 

764 

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 }}""" 

801 

802 @BirdFunction("bgp_import_filter_bogons") 

803 def import_filter_bogons(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

804 """BIRD bgp_import_filter_bogons function.""" 

805 

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 }}""" 

814 

815 @BirdFunction("bgp_import_filter_rpki") 

816 def import_filter_rpki(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

817 """BIRD bgp_import_filter_rpki function.""" 

818 

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 }}""" 

852 

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.""" 

856 

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 }}""" 

887 

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.""" 

891 

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 }}""" 

902 

903 @BirdFunction("bgp_import_filter_default") 

904 def import_filter_default(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

905 """BIRD bgp_import_filter_default function.""" 

906 

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 }}""" 

916 

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.""" 

920 

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 }}""" 

931 

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.""" 

935 

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 }}""" 

946 

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.""" 

950 

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 }}""" 

959 

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.""" 

963 

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 }}""" 

973 

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.""" 

977 

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 }}""" 

986 

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.""" 

990 

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 }}""" 

999 

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.""" 

1003 

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 }}""" 

1012 

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.""" 

1016 

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 }}""" 

1026 

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.""" 

1030 

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 }}""" 

1041 

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.""" 

1045 

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 }}""" 

1056 

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.""" 

1060 

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 }}""" 

1097 

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.""" 

1101 

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 }}""" 

1115 

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.""" 

1119 

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 }}""" 

1133 

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.""" 

1137 

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 }}""" 

1151 

1152 @BirdFunction("bgp_export_filter_prefixes") 

1153 def export_filter_prefixes(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

1154 """BIRD bgp_export_filter_prefixes function.""" 

1155 

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 }}""" 

1168 

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.""" 

1172 

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 }}""" 

1189 

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.""" 

1193 

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 }}""" 

1210 

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.""" 

1214 

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 }}""" 

1222 

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.""" 

1226 

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 }}""" 

1237 

1238 @BirdFunction("bgp_peer_graceful_shutdown") 

1239 def peer_graceful_shutdown(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

1240 """BIRD bgp_peer_graceful_shutdown function.""" 

1241 

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 }}""" 

1249 

1250 @BirdFunction("bgp_peer_import_customer") 

1251 def peer_import_customer(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

1252 """BIRD bgp_peer_import_customer function.""" 

1253 

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 }}""" 

1265 

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.""" 

1269 

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 }}""" 

1278 

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.""" 

1282 

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 }}""" 

1291 

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.""" 

1295 

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 }}""" 

1304 

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.""" 

1309 

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 }}""" 

1330 

1331 @BirdFunction("bgp_peer_import_peer") 

1332 def peer_import_peer(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

1333 """BIRD bgp_peer_import_peer function.""" 

1334 

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 }}""" 

1346 

1347 @BirdFunction("bgp_peer_import_routeserver") 

1348 def peer_import_routeserver(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

1349 """BIRD bgp_peer_import_routeserver function.""" 

1350 

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 }}""" 

1362 

1363 @BirdFunction("bgp_peer_import_transit") 

1364 def peer_import_transit(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

1365 """BIRD bgp_peer_import_transit function.""" 

1366 

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 }}""" 

1378 

1379 # 

1380 # Communities 

1381 # 

1382 

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.""" 

1386 

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 }}""" 

1395 

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.""" 

1399 

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 }}""" 

1412 

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.""" 

1416 

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 }}""" 

1429 

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.""" 

1433 

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 }}""" 

1446 

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.""" 

1450 

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 }}""" 

1460 

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.""" 

1464 

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 }}""" 

1477 

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.""" 

1481 

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 }}""" 

1494 

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.""" 

1498 

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 }}""" 

1511 

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.""" 

1515 

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 }}""" 

1528 

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.""" 

1532 

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 }}""" 

1545 

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.""" 

1549 

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 }}""" 

1563 

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.""" 

1567 

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 }}""" 

1580 

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.""" 

1584 

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 }}""" 

1597 

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.""" 

1601 

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 }}""" 

1615 

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.""" 

1619 

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 }}""" 

1632 

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.""" 

1636 

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 }}""" 

1646 

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.""" 

1650 

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 }}""" 

1664 

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.""" 

1668 

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 }}""" 

1681 

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.""" 

1685 

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 }}""" 

1695 

1696 # 

1697 # Large Communities 

1698 # 

1699 

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.""" 

1703 

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 }}""" 

1712 

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.""" 

1716 

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 }}""" 

1729 

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.""" 

1733 

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 }}""" 

1746 

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.""" 

1750 

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 }}""" 

1763 

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.""" 

1767 

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 }}""" 

1777 

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.""" 

1781 

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 }}""" 

1794 

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.""" 

1798 

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 }}""" 

1811 

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.""" 

1815 

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 }}""" 

1828 

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.""" 

1832 

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 }}""" 

1845 

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.""" 

1849 

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 }}""" 

1862 

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.""" 

1866 

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 }}""" 

1880 

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.""" 

1884 

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 }}""" 

1897 

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.""" 

1901 

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 }}""" 

1914 

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.""" 

1918 

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 }}""" 

1932 

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.""" 

1936 

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 }}""" 

1949 

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.""" 

1953 

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 }}""" 

1963 

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.""" 

1967 

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 }}""" 

1981 

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.""" 

1985 

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 }}""" 

1998 

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.""" 

2002 

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 }}""" 

2012 

2013 @BirdFunction("bgp_peer_prepend") 

2014 def peer_prepend(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

2015 """BIRD bgp_peer_prepend function.""" 

2016 

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 }""" 

2031 

2032 @BirdFunction("bgp_peer_prepend_default") 

2033 def peer_prepend_default(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

2034 """BIRD bgp_peer_prepend_default function.""" 

2035 

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 }}""" 

2044 

2045 @BirdFunction("bgp_peer_prepend_connected") 

2046 def peer_prepend_connected(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

2047 """BIRD bgp_peer_prepend_connected function.""" 

2048 

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 }}""" 

2058 

2059 @BirdFunction("bgp_peer_prepend_kernel") 

2060 def peer_prepend_kernel(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

2061 """BIRD bgp_peer_prepend_kernel function.""" 

2062 

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 }}""" 

2075 

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.""" 

2079 

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 }}""" 

2092 

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.""" 

2096 

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 }}""" 

2109 

2110 @BirdFunction("bgp_peer_prepend_originated") 

2111 def peer_prepend_originated(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

2112 """BIRD bgp_peer_prepend_originated function.""" 

2113 

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 }}""" 

2125 

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.""" 

2129 

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 }}""" 

2141 

2142 @BirdFunction("bgp_peer_prepend_static") 

2143 def peer_prepend_static(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

2144 """BIRD bgp_peer_prepend_static function.""" 

2145 

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 }}""" 

2158 

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.""" 

2162 

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 }}""" 

2175 

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.""" 

2179 

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 }}""" 

2192 

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.""" 

2196 

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 }}""" 

2209 

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.""" 

2213 

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 }}""" 

2226 

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.""" 

2230 

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 }}""" 

2243 

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.""" 

2247 

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 }}""" 

2260 

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.""" 

2264 

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 }}""" 

2277 

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.""" 

2281 

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 }}""" 

2290 

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.""" 

2294 

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 }}""" 

2307 

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.""" 

2311 

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 }}""" 

2324 

2325 @BirdFunction("bgp_peer_prepend_lc") 

2326 def peer_prepend_lc(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

2327 """BIRD bgp_peer_prepend_lc function.""" 

2328 

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 }}""" 

2361 

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.""" 

2365 

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 }}""" 

2402 

2403 @BirdFunction("bgp_peer_quarantine") 

2404 def peer_quarantine(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

2405 """BIRD bgp_peer_quarantine function.""" 

2406 

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 }}""" 

2414 

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.""" 

2418 

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 }}""" 

2435 

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.""" 

2439 

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 }}""" 

2456 

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.""" 

2460 

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 }}""" 

2477 

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.""" 

2481 

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 }}""" 

2498 

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.""" 

2502 

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 }}""" 

2519 

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.""" 

2523 

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 }}""" 

2556 

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.""" 

2560 

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 }}""" 

2577 

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.""" 

2581 

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 }}""" 

2598 

2599 @BirdFunction("bgp_peer_redistribute_connected") 

2600 def peer_redistribute_connected(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

2601 """BIRD bgp_peer_redistribute_connected function.""" 

2602 

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 }}""" 

2619 

2620 @BirdFunction("bgp_peer_redistribute_kernel") 

2621 def peer_redistribute_kernel(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

2622 """BIRD bgp_peer_redistribute_kernel function.""" 

2623 

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 }}""" 

2639 

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.""" 

2643 

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 }}""" 

2659 

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.""" 

2663 

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 }}""" 

2680 

2681 @BirdFunction("bgp_peer_redistribute_originated") 

2682 def peer_redistribute_originated(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

2683 """BIRD bgp_peer_redistribute_originated function.""" 

2684 

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 }}""" 

2701 

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.""" 

2705 

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 }}""" 

2721 

2722 @BirdFunction("bgp_peer_redistribute_static") 

2723 def peer_redistribute_static(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

2724 """BIRD bgp_peer_redistribute_static function.""" 

2725 

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 }}""" 

2741 

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.""" 

2745 

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 }}""" 

2761 

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.""" 

2765 

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 }}""" 

2782 

2783 @BirdFunction("bgp_peer_reject_blackholes") 

2784 def peer_reject_blackholes(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

2785 """BIRD bgp_peer_reject_blackholes function.""" 

2786 

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 }}""" 

2796 

2797 @BirdFunction("bgp_peer_reject_bogons") 

2798 def peer_reject_bogons(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

2799 """BIRD bgp_peer_reject_bogons function.""" 

2800 

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 }}""" 

2809 

2810 @BirdFunction("bgp_peer_reject_filtered") 

2811 def peer_reject_filtered(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

2812 """BIRD bgp_peer_reject_filtered function.""" 

2813 

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 }}""" 

2822 

2823 @BirdFunction("bgp_peer_reject_noadvertise") 

2824 def peer_reject_noadvertise(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

2825 """BIRD bgp_peer_reject_noadvertise function.""" 

2826 

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 }}""" 

2837 

2838 @BirdFunction("bgp_peer_reject_noexport") 

2839 def peer_reject_noexport(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

2840 """BIRD bgp_peer_reject_noexport function.""" 

2841 

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 }}""" 

2851 

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.""" 

2855 

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 }}""" 

2866 

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.""" 

2870 

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 }}""" 

2881 

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.""" 

2885 

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 }}""" 

2896 

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.""" 

2900 

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 }}""" 

2911 

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.""" 

2915 

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 }}""" 

2926 

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.""" 

2930 

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 }}""" 

2966 

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.""" 

2970 

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 }}""" 

3006 

3007 @BirdFunction("bgp_peer_replace_aspath") 

3008 def peer_replace_aspath(self, *args: BirdFunctionArg) -> str: # noqa: ARG002 

3009 """BIRD bgp_peer_replace_aspath function.""" 

3010 

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 }}""" 

3029 

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.""" 

3033 

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 }}""" 

3043 

3044 @property 

3045 def functions(self) -> SectionFunctions: 

3046 """Return the functions section.""" 

3047 return self._functions