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
output_bird(FILE * out,struct vrp_tree * vrps,struct brk_tree * brks,struct vap_tree * vaps,struct vsp_tree * vsps,struct stats * st)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