1 /* $OpenBSD: output-bird.c,v 1.22 2025/01/03 10:32:21 job Exp $ */ 2 /* 3 * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org> 4 * Copyright (c) 2020 Robert Scheck <robert@fedoraproject.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <stdlib.h> 20 21 #include "extern.h" 22 23 int 24 output_bird(FILE *out, struct vrp_tree *vrps, struct brk_tree *brks, 25 struct vap_tree *vaps, struct vsp_tree *vsps, struct stats *st) 26 { 27 struct vrp *v; 28 struct vap *vap; 29 time_t now = get_current_time(); 30 size_t i; 31 32 if (fprintf(out, "# For BIRD %s\n#\n", excludeaspa ? "2" : "2.16+") < 0) 33 return -1; 34 35 if (outputheader(out, st) < 0) 36 return -1; 37 38 if (fprintf(out, "\ndefine force_roa_table_update = %lld;\n\n" 39 "roa4 table ROAS4;\nroa6 table ROAS6;\n", (long long)now) < 0) 40 return -1; 41 42 if (!excludeaspa) { 43 if (fprintf(out, "aspa table ASPAS;\n") < 0) 44 return -1; 45 } 46 47 if (fprintf(out, "\nprotocol static {\n" 48 "\troa4 { table ROAS4; };\n\n") < 0) 49 return -1; 50 51 RB_FOREACH(v, vrp_tree, vrps) { 52 char buf[64]; 53 54 if (v->afi == AFI_IPV4) { 55 ip_addr_print(&v->addr, v->afi, buf, sizeof(buf)); 56 if (fprintf(out, "\troute %s max %u as %u;\n", buf, 57 v->maxlength, v->asid) < 0) 58 return -1; 59 } 60 } 61 62 if (fprintf(out, "}\n\nprotocol static {\n" 63 "\troa6 { table ROAS6; };\n\n") < 0) 64 return -1; 65 66 RB_FOREACH(v, vrp_tree, vrps) { 67 char buf[64]; 68 69 if (v->afi == AFI_IPV6) { 70 ip_addr_print(&v->addr, v->afi, buf, sizeof(buf)); 71 if (fprintf(out, "\troute %s max %u as %u;\n", buf, 72 v->maxlength, v->asid) < 0) 73 return -1; 74 } 75 } 76 77 if (fprintf(out, "}") < 0) 78 return -1; 79 80 if (excludeaspa) 81 return 0; 82 83 if (fprintf(out, "\n\nprotocol static {\n\taspa { table ASPAS; " 84 "};\n\n") < 0) 85 return -1; 86 87 RB_FOREACH(vap, vap_tree, vaps) { 88 if (vap->overflowed) 89 continue; 90 if (fprintf(out, "\troute aspa %d providers ", 91 vap->custasid) < 0) 92 return -1; 93 for (i = 0; i < vap->num_providers; i++) { 94 if (fprintf(out, "%u", vap->providers[i]) < 0) 95 return -1; 96 if (i + 1 < vap->num_providers) 97 if (fprintf(out, ", ") < 0) 98 return -1; 99 } 100 if (fprintf(out, ";\n") < 0) 101 return -1; 102 } 103 104 if (fprintf(out, "}\n") < 0) 105 return -1; 106 107 return 0; 108 } 109