xref: /openbsd-src/usr.sbin/rpki-client/output-bird.c (revision 8c922ca8d8be49867b6aea24c6506c1e0cfbee1c)
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