]> git.ipfire.org Git - thirdparty/bird.git/blob - lib/net.c
Filter: Fix function comparison
[thirdparty/bird.git] / lib / net.c
1
2 #include "nest/bird.h"
3 #include "lib/ip.h"
4 #include "lib/net.h"
5 #include "lib/flowspec.h"
6
7
8 const char * const net_label[] = {
9 [NET_IP4] = "ipv4",
10 [NET_IP6] = "ipv6",
11 [NET_VPN4] = "vpn4",
12 [NET_VPN6] = "vpn6",
13 [NET_ROA4] = "roa4",
14 [NET_ROA6] = "roa6",
15 [NET_FLOW4] = "flow4",
16 [NET_FLOW6] = "flow6",
17 [NET_IP6_SADR]= "ipv6-sadr",
18 [NET_MPLS] = "mpls",
19 };
20
21 const u16 net_addr_length[] = {
22 [NET_IP4] = sizeof(net_addr_ip4),
23 [NET_IP6] = sizeof(net_addr_ip6),
24 [NET_VPN4] = sizeof(net_addr_vpn4),
25 [NET_VPN6] = sizeof(net_addr_vpn6),
26 [NET_ROA4] = sizeof(net_addr_roa4),
27 [NET_ROA6] = sizeof(net_addr_roa6),
28 [NET_FLOW4] = 0,
29 [NET_FLOW6] = 0,
30 [NET_IP6_SADR]= sizeof(net_addr_ip6_sadr),
31 [NET_MPLS] = sizeof(net_addr_mpls),
32 };
33
34 const u8 net_max_prefix_length[] = {
35 [NET_IP4] = IP4_MAX_PREFIX_LENGTH,
36 [NET_IP6] = IP6_MAX_PREFIX_LENGTH,
37 [NET_VPN4] = IP4_MAX_PREFIX_LENGTH,
38 [NET_VPN6] = IP6_MAX_PREFIX_LENGTH,
39 [NET_ROA4] = IP4_MAX_PREFIX_LENGTH,
40 [NET_ROA6] = IP6_MAX_PREFIX_LENGTH,
41 [NET_FLOW4] = IP4_MAX_PREFIX_LENGTH,
42 [NET_FLOW6] = IP6_MAX_PREFIX_LENGTH,
43 [NET_IP6_SADR]= IP6_MAX_PREFIX_LENGTH,
44 [NET_MPLS] = 0,
45 };
46
47 const u16 net_max_text_length[] = {
48 [NET_IP4] = 18, /* "255.255.255.255/32" */
49 [NET_IP6] = 43, /* "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128" */
50 [NET_VPN4] = 40, /* "4294967296:4294967296 255.255.255.255/32" */
51 [NET_VPN6] = 65, /* "4294967296:4294967296 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128" */
52 [NET_ROA4] = 34, /* "255.255.255.255/32-32 AS4294967295" */
53 [NET_ROA6] = 60, /* "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128-128 AS4294967295" */
54 [NET_FLOW4] = 0, /* "flow4 { ... }" */
55 [NET_FLOW6] = 0, /* "flow6 { ... }" */
56 [NET_IP6_SADR]= 92, /* "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128 from ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128" */
57 [NET_MPLS] = 7, /* "1048575" */
58 };
59
60
61 int
62 rd_format(const u64 rd, char *buf, int buflen)
63 {
64 switch (rd >> 48)
65 {
66 case 0: return bsnprintf(buf, buflen, "%u:%u", (u32) (rd >> 32), (u32) rd);
67 case 1: return bsnprintf(buf, buflen, "%I4:%u", ip4_from_u32(rd >> 16), (u32) (rd & 0xffff));
68 case 2: if (((u32) (rd >> 16)) >> 16)
69 return bsnprintf(buf, buflen, "%u:%u", (u32) (rd >> 16), (u32) (rd & 0xffff));
70 else
71 return bsnprintf(buf, buflen, "2:%u:%u", (u32) (rd >> 16), (u32) (rd & 0xffff));
72 default: return bsnprintf(buf, buflen, "X:%08x:%08x", (u32) (rd >> 32), (u32) rd);
73 }
74 }
75
76 int
77 net_format(const net_addr *N, char *buf, int buflen)
78 {
79 net_addr_union *n = (void *) N;
80 buf[0] = 0;
81
82 switch (n->n.type)
83 {
84 case NET_IP4:
85 return bsnprintf(buf, buflen, "%I4/%d", n->ip4.prefix, n->ip4.pxlen);
86 case NET_IP6:
87 return bsnprintf(buf, buflen, "%I6/%d", n->ip6.prefix, n->ip6.pxlen);
88 case NET_VPN4:
89 {
90 int c = rd_format(n->vpn4.rd, buf, buflen);
91 ADVANCE(buf, buflen, c);
92 return bsnprintf(buf, buflen, " %I4/%d", n->vpn4.prefix, n->vpn4.pxlen);
93 }
94 case NET_VPN6:
95 {
96 /* XXX: RD format is specified for VPN4; not found any for VPN6, reusing the same as for VPN4 */
97 int c = rd_format(n->vpn6.rd, buf, buflen);
98 ADVANCE(buf, buflen, c);
99 return bsnprintf(buf, buflen, " %I6/%d", n->vpn6.prefix, n->vpn6.pxlen);
100 }
101 case NET_ROA4:
102 return bsnprintf(buf, buflen, "%I4/%u-%u AS%u", n->roa4.prefix, n->roa4.pxlen, n->roa4.max_pxlen, n->roa4.asn);
103 case NET_ROA6:
104 return bsnprintf(buf, buflen, "%I6/%u-%u AS%u", n->roa6.prefix, n->roa6.pxlen, n->roa6.max_pxlen, n->roa6.asn);
105 case NET_FLOW4:
106 return flow4_net_format(buf, buflen, &n->flow4);
107 case NET_FLOW6:
108 return flow6_net_format(buf, buflen, &n->flow6);
109 case NET_IP6_SADR:
110 return bsnprintf(buf, buflen, "%I6/%d from %I6/%d", n->ip6_sadr.dst_prefix, n->ip6_sadr.dst_pxlen, n->ip6_sadr.src_prefix, n->ip6_sadr.src_pxlen);
111 case NET_MPLS:
112 return bsnprintf(buf, buflen, "%u", n->mpls.label);
113 }
114
115 bug("unknown network type");
116 }
117
118 ip_addr
119 net_pxmask(const net_addr *a)
120 {
121 switch (a->type)
122 {
123 case NET_IP4:
124 case NET_VPN4:
125 case NET_ROA4:
126 case NET_FLOW4:
127 return ipa_from_ip4(ip4_mkmask(net4_pxlen(a)));
128
129 case NET_IP6:
130 case NET_VPN6:
131 case NET_ROA6:
132 case NET_FLOW6:
133 case NET_IP6_SADR:
134 return ipa_from_ip6(ip6_mkmask(net6_pxlen(a)));
135
136 case NET_MPLS:
137 default:
138 return IPA_NONE;
139 }
140 }
141
142 int
143 net_compare(const net_addr *a, const net_addr *b)
144 {
145 if (a->type != b->type)
146 return uint_cmp(a->type, b->type);
147
148 switch (a->type)
149 {
150 case NET_IP4:
151 return net_compare_ip4((const net_addr_ip4 *) a, (const net_addr_ip4 *) b);
152 case NET_IP6:
153 return net_compare_ip6((const net_addr_ip6 *) a, (const net_addr_ip6 *) b);
154 case NET_VPN4:
155 return net_compare_vpn4((const net_addr_vpn4 *) a, (const net_addr_vpn4 *) b);
156 case NET_VPN6:
157 return net_compare_vpn6((const net_addr_vpn6 *) a, (const net_addr_vpn6 *) b);
158 case NET_ROA4:
159 return net_compare_roa4((const net_addr_roa4 *) a, (const net_addr_roa4 *) b);
160 case NET_ROA6:
161 return net_compare_roa6((const net_addr_roa6 *) a, (const net_addr_roa6 *) b);
162 case NET_FLOW4:
163 return net_compare_flow4((const net_addr_flow4 *) a, (const net_addr_flow4 *) b);
164 case NET_FLOW6:
165 return net_compare_flow6((const net_addr_flow6 *) a, (const net_addr_flow6 *) b);
166 case NET_IP6_SADR:
167 return net_compare_ip6_sadr((const net_addr_ip6_sadr *) a, (const net_addr_ip6_sadr *) b);
168 case NET_MPLS:
169 return net_compare_mpls((const net_addr_mpls *) a, (const net_addr_mpls *) b);
170 }
171 return 0;
172 }
173
174 #define NET_HASH(a,t) net_hash_##t((const net_addr_##t *) a)
175
176 u32
177 net_hash(const net_addr *n)
178 {
179 switch (n->type)
180 {
181 case NET_IP4: return NET_HASH(n, ip4);
182 case NET_IP6: return NET_HASH(n, ip6);
183 case NET_VPN4: return NET_HASH(n, vpn4);
184 case NET_VPN6: return NET_HASH(n, vpn6);
185 case NET_ROA4: return NET_HASH(n, roa4);
186 case NET_ROA6: return NET_HASH(n, roa6);
187 case NET_FLOW4: return NET_HASH(n, flow4);
188 case NET_FLOW6: return NET_HASH(n, flow6);
189 case NET_IP6_SADR: return NET_HASH(n, ip6_sadr);
190 case NET_MPLS: return NET_HASH(n, mpls);
191 default: bug("invalid type");
192 }
193 }
194
195
196 #define NET_VALIDATE(a,t) net_validate_##t((const net_addr_##t *) a)
197
198 int
199 net_validate(const net_addr *n)
200 {
201 switch (n->type)
202 {
203 case NET_IP4: return NET_VALIDATE(n, ip4);
204 case NET_IP6: return NET_VALIDATE(n, ip6);
205 case NET_VPN4: return NET_VALIDATE(n, vpn4);
206 case NET_VPN6: return NET_VALIDATE(n, vpn6);
207 case NET_ROA4: return NET_VALIDATE(n, roa4);
208 case NET_ROA6: return NET_VALIDATE(n, roa6);
209 case NET_FLOW4: return NET_VALIDATE(n, flow4);
210 case NET_FLOW6: return NET_VALIDATE(n, flow6);
211 case NET_IP6_SADR: return NET_VALIDATE(n, ip6_sadr);
212 case NET_MPLS: return NET_VALIDATE(n, mpls);
213 default: return 0;
214 }
215 }
216
217 void
218 net_normalize(net_addr *N)
219 {
220 net_addr_union *n = (void *) N;
221
222 switch (n->n.type)
223 {
224 case NET_IP4:
225 case NET_VPN4:
226 case NET_ROA4:
227 case NET_FLOW4:
228 return net_normalize_ip4(&n->ip4);
229
230 case NET_IP6:
231 case NET_VPN6:
232 case NET_ROA6:
233 case NET_FLOW6:
234 return net_normalize_ip6(&n->ip6);
235
236 case NET_IP6_SADR:
237 return net_normalize_ip6_sadr(&n->ip6_sadr);
238
239 case NET_MPLS:
240 return;
241 }
242 }
243
244 int
245 net_classify(const net_addr *N)
246 {
247 net_addr_union *n = (void *) N;
248
249 switch (n->n.type)
250 {
251 case NET_IP4:
252 case NET_VPN4:
253 case NET_ROA4:
254 case NET_FLOW4:
255 return ip4_zero(n->ip4.prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip4_classify(n->ip4.prefix);
256
257 case NET_IP6:
258 case NET_VPN6:
259 case NET_ROA6:
260 case NET_FLOW6:
261 return ip6_zero(n->ip6.prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip6_classify(&n->ip6.prefix);
262
263 case NET_IP6_SADR:
264 return ip6_zero(n->ip6_sadr.dst_prefix) ? (IADDR_HOST | SCOPE_UNIVERSE) : ip6_classify(&n->ip6_sadr.dst_prefix);
265
266 case NET_MPLS:
267 return IADDR_HOST | SCOPE_UNIVERSE;
268 }
269
270 return IADDR_INVALID;
271 }
272
273 int
274 ipa_in_netX(const ip_addr a, const net_addr *n)
275 {
276 switch (n->type)
277 {
278 case NET_IP4:
279 case NET_VPN4:
280 case NET_ROA4:
281 case NET_FLOW4:
282 if (!ipa_is_ip4(a)) return 0;
283 return ip4_zero(ip4_and(ip4_xor(ipa_to_ip4(a), net4_prefix(n)),
284 ip4_mkmask(net4_pxlen(n))));
285
286 case NET_IP6:
287 case NET_VPN6:
288 case NET_ROA6:
289 case NET_FLOW6:
290 if (ipa_is_ip4(a)) return 0;
291 return ip6_zero(ip6_and(ip6_xor(ipa_to_ip6(a), net6_prefix(n)),
292 ip6_mkmask(net6_pxlen(n))));
293
294 case NET_IP6_SADR:
295 if (ipa_is_ip4(a)) return 0;
296 return ip6_zero(ip6_and(ip6_xor(ipa_to_ip6(a), net6_prefix(n)),
297 ip6_mkmask(net6_pxlen(n))));
298
299 case NET_MPLS:
300 default:
301 return 0;
302 }
303 }
304
305 int
306 net_in_netX(const net_addr *a, const net_addr *n)
307 {
308 if (a->type != n->type)
309 return 0;
310
311 return (net_pxlen(n) <= net_pxlen(a)) && ipa_in_netX(net_prefix(a), n);
312 }
313
314 #define CHECK_NET(T,S) \
315 ({ if (sizeof(T) != S) die("sizeof %s is %d/%d", #T, (int) sizeof(T), S); })
316
317 void
318 net_init(void)
319 {
320 CHECK_NET(net_addr, 24);
321 CHECK_NET(net_addr_ip4, 8);
322 CHECK_NET(net_addr_ip6, 20);
323 CHECK_NET(net_addr_vpn4, 16);
324 CHECK_NET(net_addr_vpn6, 32);
325 CHECK_NET(net_addr_roa4, 16);
326 CHECK_NET(net_addr_roa6, 28);
327 CHECK_NET(net_addr_flow4, 8);
328 CHECK_NET(net_addr_flow6, 20);
329 CHECK_NET(net_addr_ip6_sadr, 40);
330 CHECK_NET(net_addr_mpls, 8);
331 }