Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later
2 : /*
3 : * Prefix related functions.
4 : * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
5 : */
6 :
7 : #include <zebra.h>
8 :
9 : #include "command.h"
10 : #include "prefix.h"
11 : #include "ipaddr.h"
12 : #include "vty.h"
13 : #include "sockunion.h"
14 : #include "memory.h"
15 : #include "log.h"
16 : #include "jhash.h"
17 : #include "lib_errors.h"
18 : #include "printfrr.h"
19 : #include "vxlan.h"
20 :
21 12 : DEFINE_MTYPE_STATIC(LIB, PREFIX, "Prefix");
22 12 : DEFINE_MTYPE_STATIC(LIB, PREFIX_FLOWSPEC, "Prefix Flowspec");
23 :
24 : /* Maskbit. */
25 : static const uint8_t maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
26 : 0xf8, 0xfc, 0xfe, 0xff};
27 :
28 : /* Number of bits in prefix type. */
29 : #ifndef PNBBY
30 : #define PNBBY 8
31 : #endif /* PNBBY */
32 :
33 : #define MASKBIT(offset) ((0xff << (PNBBY - (offset))) & 0xff)
34 :
35 0 : int is_zero_mac(const struct ethaddr *mac)
36 : {
37 0 : int i = 0;
38 :
39 0 : for (i = 0; i < ETH_ALEN; i++) {
40 0 : if (mac->octet[i])
41 : return 0;
42 : }
43 :
44 : return 1;
45 : }
46 :
47 0 : bool is_bcast_mac(const struct ethaddr *mac)
48 : {
49 0 : int i = 0;
50 :
51 0 : for (i = 0; i < ETH_ALEN; i++)
52 0 : if (mac->octet[i] != 0xFF)
53 : return false;
54 :
55 : return true;
56 : }
57 :
58 0 : bool is_mcast_mac(const struct ethaddr *mac)
59 : {
60 0 : if ((mac->octet[0] & 0x01) == 0x01)
61 0 : return true;
62 :
63 : return false;
64 : }
65 :
66 337 : unsigned int prefix_bit(const uint8_t *prefix, const uint16_t bit_index)
67 : {
68 337 : unsigned int offset = bit_index / 8;
69 337 : unsigned int shift = 7 - (bit_index % 8);
70 :
71 337 : return (prefix[offset] >> shift) & 1;
72 : }
73 :
74 0 : int str2family(const char *string)
75 : {
76 0 : if (!strcmp("ipv4", string))
77 : return AF_INET;
78 0 : else if (!strcmp("ipv6", string))
79 : return AF_INET6;
80 0 : else if (!strcmp("ethernet", string))
81 : return AF_ETHERNET;
82 0 : else if (!strcmp("evpn", string))
83 0 : return AF_EVPN;
84 : return -1;
85 : }
86 :
87 0 : const char *family2str(int family)
88 : {
89 0 : switch (family) {
90 : case AF_INET:
91 : return "IPv4";
92 0 : case AF_INET6:
93 0 : return "IPv6";
94 0 : case AF_ETHERNET:
95 0 : return "Ethernet";
96 0 : case AF_EVPN:
97 0 : return "Evpn";
98 : }
99 0 : return "?";
100 : }
101 :
102 : /* Address Family Identifier to Address Family converter. */
103 20 : int afi2family(afi_t afi)
104 : {
105 20 : if (afi == AFI_IP)
106 : return AF_INET;
107 4 : else if (afi == AFI_IP6)
108 : return AF_INET6;
109 0 : else if (afi == AFI_L2VPN)
110 0 : return AF_ETHERNET;
111 : /* NOTE: EVPN code should NOT use this interface. */
112 : return 0;
113 : }
114 :
115 394 : afi_t family2afi(int family)
116 : {
117 394 : if (family == AF_INET)
118 : return AFI_IP;
119 138 : else if (family == AF_INET6)
120 : return AFI_IP6;
121 0 : else if (family == AF_ETHERNET || family == AF_EVPN)
122 0 : return AFI_L2VPN;
123 : return 0;
124 : }
125 :
126 0 : const char *afi2str_lower(afi_t afi)
127 : {
128 0 : switch (afi) {
129 : case AFI_IP:
130 : return "ipv4";
131 0 : case AFI_IP6:
132 0 : return "ipv6";
133 0 : case AFI_L2VPN:
134 0 : return "l2vpn";
135 0 : case AFI_MAX:
136 : case AFI_UNSPEC:
137 0 : return "bad-value";
138 : }
139 :
140 0 : assert(!"Reached end of function we should never reach");
141 : }
142 :
143 27 : const char *afi2str(afi_t afi)
144 : {
145 27 : switch (afi) {
146 : case AFI_IP:
147 : return "IPv4";
148 0 : case AFI_IP6:
149 0 : return "IPv6";
150 0 : case AFI_L2VPN:
151 0 : return "l2vpn";
152 0 : case AFI_MAX:
153 : case AFI_UNSPEC:
154 0 : return "bad-value";
155 : }
156 :
157 0 : assert(!"Reached end of function we should never reach");
158 : }
159 :
160 27 : const char *safi2str(safi_t safi)
161 : {
162 27 : switch (safi) {
163 : case SAFI_UNICAST:
164 : return "unicast";
165 0 : case SAFI_MULTICAST:
166 0 : return "multicast";
167 0 : case SAFI_MPLS_VPN:
168 0 : return "vpn";
169 0 : case SAFI_ENCAP:
170 0 : return "encap";
171 0 : case SAFI_EVPN:
172 0 : return "evpn";
173 0 : case SAFI_LABELED_UNICAST:
174 0 : return "labeled-unicast";
175 0 : case SAFI_FLOWSPEC:
176 0 : return "flowspec";
177 0 : case SAFI_UNSPEC:
178 : case SAFI_MAX:
179 0 : return "unknown";
180 : }
181 :
182 0 : assert(!"Reached end of function we should never reach");
183 : }
184 :
185 : /* If n includes p prefix then return 1 else return 0. */
186 280 : int prefix_match(union prefixconstptr unet, union prefixconstptr upfx)
187 : {
188 280 : const struct prefix *n = unet.p;
189 280 : const struct prefix *p = upfx.p;
190 280 : int offset;
191 280 : int shift;
192 280 : const uint8_t *np, *pp;
193 :
194 : /* If n's prefix is longer than p's one return 0. */
195 280 : if (n->prefixlen > p->prefixlen)
196 : return 0;
197 :
198 280 : if (n->family == AF_FLOWSPEC) {
199 : /* prefixlen is unused. look at fs prefix len */
200 0 : if (n->u.prefix_flowspec.family !=
201 0 : p->u.prefix_flowspec.family)
202 : return 0;
203 :
204 0 : if (n->u.prefix_flowspec.prefixlen >
205 0 : p->u.prefix_flowspec.prefixlen)
206 : return 0;
207 :
208 : /* Set both prefix's head pointer. */
209 0 : np = (const uint8_t *)&n->u.prefix_flowspec.ptr;
210 0 : pp = (const uint8_t *)&p->u.prefix_flowspec.ptr;
211 :
212 0 : offset = n->u.prefix_flowspec.prefixlen;
213 :
214 0 : while (offset--)
215 0 : if (np[offset] != pp[offset])
216 : return 0;
217 : return 1;
218 : }
219 :
220 : /* Set both prefix's head pointer. */
221 280 : np = n->u.val;
222 280 : pp = p->u.val;
223 :
224 280 : offset = n->prefixlen / PNBBY;
225 280 : shift = n->prefixlen % PNBBY;
226 :
227 280 : if (shift)
228 64 : if (maskbit[shift] & (np[offset] ^ pp[offset]))
229 : return 0;
230 :
231 758 : while (offset--)
232 522 : if (np[offset] != pp[offset])
233 : return 0;
234 : return 1;
235 :
236 : }
237 :
238 : /*
239 : * n is a type5 evpn prefix. This function tries to see if there is an
240 : * ip-prefix within n which matches prefix p
241 : * If n includes p prefix then return 1 else return 0.
242 : */
243 0 : int evpn_type5_prefix_match(const struct prefix *n, const struct prefix *p)
244 : {
245 0 : int offset;
246 0 : int shift;
247 0 : int prefixlen;
248 0 : const uint8_t *np, *pp;
249 0 : struct prefix_evpn *evp;
250 :
251 0 : if (n->family != AF_EVPN)
252 : return 0;
253 :
254 0 : evp = (struct prefix_evpn *)n;
255 0 : pp = p->u.val;
256 :
257 0 : if ((evp->prefix.route_type != 5) ||
258 0 : (p->family == AF_INET6 && !is_evpn_prefix_ipaddr_v6(evp)) ||
259 0 : (p->family == AF_INET && !is_evpn_prefix_ipaddr_v4(evp)) ||
260 0 : (is_evpn_prefix_ipaddr_none(evp)))
261 : return 0;
262 :
263 0 : prefixlen = evp->prefix.prefix_addr.ip_prefix_length;
264 0 : np = evp->prefix.prefix_addr.ip.ip.addrbytes;
265 :
266 : /* If n's prefix is longer than p's one return 0. */
267 0 : if (prefixlen > p->prefixlen)
268 : return 0;
269 :
270 0 : offset = prefixlen / PNBBY;
271 0 : shift = prefixlen % PNBBY;
272 :
273 0 : if (shift)
274 0 : if (maskbit[shift] & (np[offset] ^ pp[offset]))
275 : return 0;
276 :
277 0 : while (offset--)
278 0 : if (np[offset] != pp[offset])
279 : return 0;
280 : return 1;
281 :
282 : }
283 :
284 : /* If n includes p then return 1 else return 0. Prefix mask is not considered */
285 0 : int prefix_match_network_statement(union prefixconstptr unet,
286 : union prefixconstptr upfx)
287 : {
288 0 : const struct prefix *n = unet.p;
289 0 : const struct prefix *p = upfx.p;
290 0 : int offset;
291 0 : int shift;
292 0 : const uint8_t *np, *pp;
293 :
294 : /* Set both prefix's head pointer. */
295 0 : np = n->u.val;
296 0 : pp = p->u.val;
297 :
298 0 : offset = n->prefixlen / PNBBY;
299 0 : shift = n->prefixlen % PNBBY;
300 :
301 0 : if (shift)
302 0 : if (maskbit[shift] & (np[offset] ^ pp[offset]))
303 : return 0;
304 :
305 0 : while (offset--)
306 0 : if (np[offset] != pp[offset])
307 : return 0;
308 : return 1;
309 : }
310 :
311 : #ifdef __clang_analyzer__
312 : #undef prefix_copy /* cf. prefix.h */
313 : #endif
314 :
315 1056 : void prefix_copy(union prefixptr udest, union prefixconstptr usrc)
316 : {
317 1056 : struct prefix *dest = udest.p;
318 1056 : const struct prefix *src = usrc.p;
319 :
320 1056 : dest->family = src->family;
321 1056 : dest->prefixlen = src->prefixlen;
322 :
323 1056 : if (src->family == AF_INET)
324 532 : dest->u.prefix4 = src->u.prefix4;
325 : else if (src->family == AF_INET6)
326 524 : dest->u.prefix6 = src->u.prefix6;
327 : else if (src->family == AF_ETHERNET) {
328 0 : memcpy(&dest->u.prefix_eth, &src->u.prefix_eth,
329 : sizeof(struct ethaddr));
330 : } else if (src->family == AF_EVPN) {
331 0 : memcpy(&dest->u.prefix_evpn, &src->u.prefix_evpn,
332 : sizeof(struct evpn_addr));
333 : } else if (src->family == AF_UNSPEC) {
334 0 : dest->u.lp.id = src->u.lp.id;
335 0 : dest->u.lp.adv_router = src->u.lp.adv_router;
336 : } else if (src->family == AF_FLOWSPEC) {
337 0 : void *temp;
338 0 : int len;
339 :
340 0 : len = src->u.prefix_flowspec.prefixlen;
341 0 : dest->u.prefix_flowspec.prefixlen =
342 : src->u.prefix_flowspec.prefixlen;
343 0 : dest->u.prefix_flowspec.family =
344 0 : src->u.prefix_flowspec.family;
345 0 : dest->family = src->family;
346 0 : temp = XCALLOC(MTYPE_PREFIX_FLOWSPEC, len);
347 0 : dest->u.prefix_flowspec.ptr = (uintptr_t)temp;
348 0 : memcpy((void *)dest->u.prefix_flowspec.ptr,
349 0 : (void *)src->u.prefix_flowspec.ptr, len);
350 : } else {
351 0 : flog_err(EC_LIB_DEVELOPMENT,
352 : "prefix_copy(): Unknown address family %d",
353 : src->family);
354 0 : assert(0);
355 : }
356 1056 : }
357 :
358 0 : bool evpn_addr_same(const struct evpn_addr *e1, const struct evpn_addr *e2)
359 : {
360 0 : if (e1->route_type != e2->route_type)
361 : return false;
362 0 : if (e1->route_type == BGP_EVPN_AD_ROUTE)
363 0 : return (!memcmp(&e1->ead_addr.esi.val,
364 0 : &e2->ead_addr.esi.val, ESI_BYTES) &&
365 0 : e1->ead_addr.eth_tag == e2->ead_addr.eth_tag &&
366 0 : !ipaddr_cmp(&e1->ead_addr.ip, &e2->ead_addr.ip));
367 : if (e1->route_type == BGP_EVPN_MAC_IP_ROUTE)
368 0 : return (e1->macip_addr.eth_tag == e2->macip_addr.eth_tag &&
369 0 : e1->macip_addr.ip_prefix_length
370 0 : == e2->macip_addr.ip_prefix_length &&
371 0 : !memcmp(&e1->macip_addr.mac,
372 0 : &e2->macip_addr.mac, ETH_ALEN) &&
373 0 : !ipaddr_cmp(&e1->macip_addr.ip, &e2->macip_addr.ip));
374 : if (e1->route_type == BGP_EVPN_IMET_ROUTE)
375 0 : return (e1->imet_addr.eth_tag == e2->imet_addr.eth_tag &&
376 0 : e1->imet_addr.ip_prefix_length
377 0 : == e2->imet_addr.ip_prefix_length &&
378 0 : !ipaddr_cmp(&e1->imet_addr.ip, &e2->imet_addr.ip));
379 : if (e1->route_type == BGP_EVPN_ES_ROUTE)
380 0 : return (!memcmp(&e1->es_addr.esi.val,
381 0 : &e2->es_addr.esi.val, ESI_BYTES) &&
382 0 : e1->es_addr.ip_prefix_length
383 0 : == e2->es_addr.ip_prefix_length &&
384 0 : !ipaddr_cmp(&e1->es_addr.ip, &e2->es_addr.ip));
385 : if (e1->route_type == BGP_EVPN_IP_PREFIX_ROUTE)
386 0 : return (e1->prefix_addr.eth_tag == e2->prefix_addr.eth_tag &&
387 0 : e1->prefix_addr.ip_prefix_length
388 0 : == e2->prefix_addr.ip_prefix_length &&
389 0 : !ipaddr_cmp(&e1->prefix_addr.ip, &e2->prefix_addr.ip));
390 : return true;
391 : }
392 :
393 : /*
394 : * Return 1 if the address/netmask contained in the prefix structure
395 : * is the same, and else return 0. For this routine, 'same' requires
396 : * that not only the prefix length and the network part be the same,
397 : * but also the host part. Thus, 10.0.0.1/8 and 10.0.0.2/8 are not
398 : * the same. Note that this routine has the same return value sense
399 : * as '==' (which is different from prefix_cmp).
400 : */
401 160 : int prefix_same(union prefixconstptr up1, union prefixconstptr up2)
402 : {
403 160 : const struct prefix *p1 = up1.p;
404 160 : const struct prefix *p2 = up2.p;
405 :
406 160 : if ((p1 && !p2) || (!p1 && p2))
407 : return 0;
408 :
409 160 : if (!p1 && !p2)
410 : return 1;
411 :
412 160 : if (p1->family == p2->family && p1->prefixlen == p2->prefixlen) {
413 132 : if (p1->family == AF_INET)
414 29 : if (IPV4_ADDR_SAME(&p1->u.prefix4, &p2->u.prefix4))
415 : return 1;
416 105 : if (p1->family == AF_INET6)
417 103 : if (IPV6_ADDR_SAME(&p1->u.prefix6.s6_addr,
418 : &p2->u.prefix6.s6_addr))
419 : return 1;
420 29 : if (p1->family == AF_ETHERNET)
421 0 : if (!memcmp(&p1->u.prefix_eth, &p2->u.prefix_eth,
422 : sizeof(struct ethaddr)))
423 : return 1;
424 29 : if (p1->family == AF_EVPN)
425 0 : if (evpn_addr_same(&p1->u.prefix_evpn, &p2->u.prefix_evpn))
426 : return 1;
427 29 : if (p1->family == AF_FLOWSPEC) {
428 0 : if (p1->u.prefix_flowspec.family !=
429 0 : p2->u.prefix_flowspec.family)
430 : return 0;
431 0 : if (p1->u.prefix_flowspec.prefixlen !=
432 0 : p2->u.prefix_flowspec.prefixlen)
433 : return 0;
434 0 : if (!memcmp(&p1->u.prefix_flowspec.ptr,
435 0 : &p2->u.prefix_flowspec.ptr,
436 : p2->u.prefix_flowspec.prefixlen))
437 : return 1;
438 : }
439 : }
440 : return 0;
441 : }
442 :
443 : /*
444 : * Return -1/0/1 comparing the prefixes in a way that gives a full/linear
445 : * order.
446 : *
447 : * Network prefixes are considered the same if the prefix lengths are equal
448 : * and the network parts are the same. Host bits (which are considered masked
449 : * by the prefix length) are not significant. Thus, 10.0.0.1/8 and
450 : * 10.0.0.2/8 are considered equivalent by this routine. Note that
451 : * this routine has the same return sense as strcmp (which is different
452 : * from prefix_same).
453 : */
454 259 : int prefix_cmp(union prefixconstptr up1, union prefixconstptr up2)
455 : {
456 259 : const struct prefix *p1 = up1.p;
457 259 : const struct prefix *p2 = up2.p;
458 259 : int offset;
459 259 : int shift;
460 259 : int i;
461 :
462 : /* Set both prefix's head pointer. */
463 259 : const uint8_t *pp1;
464 259 : const uint8_t *pp2;
465 :
466 259 : if (p1->family != p2->family)
467 0 : return numcmp(p1->family, p2->family);
468 259 : if (p1->family == AF_FLOWSPEC) {
469 0 : pp1 = (const uint8_t *)p1->u.prefix_flowspec.ptr;
470 0 : pp2 = (const uint8_t *)p2->u.prefix_flowspec.ptr;
471 :
472 0 : if (p1->u.prefix_flowspec.family !=
473 0 : p2->u.prefix_flowspec.family)
474 : return 1;
475 :
476 0 : if (p1->u.prefix_flowspec.prefixlen !=
477 0 : p2->u.prefix_flowspec.prefixlen)
478 0 : return numcmp(p1->u.prefix_flowspec.prefixlen,
479 : p2->u.prefix_flowspec.prefixlen);
480 :
481 0 : offset = p1->u.prefix_flowspec.prefixlen;
482 0 : while (offset--)
483 0 : if (pp1[offset] != pp2[offset])
484 0 : return numcmp(pp1[offset], pp2[offset]);
485 : return 0;
486 : }
487 259 : pp1 = p1->u.val;
488 259 : pp2 = p2->u.val;
489 :
490 259 : if (p1->prefixlen != p2->prefixlen)
491 0 : return numcmp(p1->prefixlen, p2->prefixlen);
492 259 : offset = p1->prefixlen / PNBBY;
493 259 : shift = p1->prefixlen % PNBBY;
494 :
495 259 : i = memcmp(pp1, pp2, offset);
496 259 : if (i)
497 : return i;
498 :
499 : /*
500 : * At this point offset was the same, if we have shift
501 : * that means we still have data to compare, if shift is
502 : * 0 then we are at the end of the data structure
503 : * and should just return, as that we will be accessing
504 : * memory beyond the end of the party zone
505 : */
506 240 : if (shift)
507 0 : return numcmp(pp1[offset] & maskbit[shift],
508 : pp2[offset] & maskbit[shift]);
509 :
510 : return 0;
511 : }
512 :
513 : /*
514 : * Count the number of common bits in 2 prefixes. The prefix length is
515 : * ignored for this function; the whole prefix is compared. If the prefix
516 : * address families don't match, return -1; otherwise the return value is
517 : * in range 0 ... maximum prefix length for the address family.
518 : */
519 0 : int prefix_common_bits(union prefixconstptr ua, union prefixconstptr ub)
520 : {
521 0 : const struct prefix *p1 = ua.p;
522 0 : const struct prefix *p2 = ub.p;
523 0 : int pos, bit;
524 0 : int length = 0;
525 0 : uint8_t xor ;
526 :
527 : /* Set both prefix's head pointer. */
528 0 : const uint8_t *pp1 = p1->u.val;
529 0 : const uint8_t *pp2 = p2->u.val;
530 :
531 0 : if (p1->family == AF_INET)
532 0 : length = IPV4_MAX_BYTELEN;
533 0 : if (p1->family == AF_INET6)
534 0 : length = IPV6_MAX_BYTELEN;
535 0 : if (p1->family == AF_ETHERNET)
536 0 : length = ETH_ALEN;
537 0 : if (p1->family == AF_EVPN)
538 0 : length = 8 * sizeof(struct evpn_addr);
539 :
540 0 : if (p1->family != p2->family || !length)
541 : return -1;
542 :
543 0 : for (pos = 0; pos < length; pos++)
544 0 : if (pp1[pos] != pp2[pos])
545 : break;
546 0 : if (pos == length)
547 0 : return pos * 8;
548 :
549 0 : xor = pp1[pos] ^ pp2[pos];
550 0 : for (bit = 0; bit < 8; bit++)
551 0 : if (xor&(1 << (7 - bit)))
552 : break;
553 :
554 0 : return pos * 8 + bit;
555 : }
556 :
557 : /* Return prefix family type string. */
558 0 : const char *prefix_family_str(union prefixconstptr pu)
559 : {
560 0 : const struct prefix *p = pu.p;
561 :
562 0 : if (p->family == AF_INET)
563 : return "inet";
564 0 : if (p->family == AF_INET6)
565 : return "inet6";
566 0 : if (p->family == AF_ETHERNET)
567 : return "ether";
568 0 : if (p->family == AF_EVPN)
569 0 : return "evpn";
570 : return "unspec";
571 : }
572 :
573 : /* Allocate new prefix_ipv4 structure. */
574 4 : struct prefix_ipv4 *prefix_ipv4_new(void)
575 : {
576 4 : struct prefix_ipv4 *p;
577 :
578 : /* Call prefix_new to allocate a full-size struct prefix to avoid
579 : problems
580 : where the struct prefix_ipv4 is cast to struct prefix and unallocated
581 : bytes were being referenced (e.g. in structure assignments). */
582 4 : p = (struct prefix_ipv4 *)prefix_new();
583 4 : p->family = AF_INET;
584 4 : return p;
585 : }
586 :
587 : /* Free prefix_ipv4 structure. */
588 0 : void prefix_ipv4_free(struct prefix_ipv4 **p)
589 : {
590 0 : prefix_free((struct prefix **)p);
591 0 : }
592 :
593 : /* If given string is valid return 1 else return 0 */
594 0 : int str2prefix_ipv4(const char *str, struct prefix_ipv4 *p)
595 : {
596 0 : int ret;
597 0 : int plen;
598 0 : char *pnt;
599 0 : char *cp;
600 :
601 : /* Find slash inside string. */
602 0 : pnt = strchr(str, '/');
603 :
604 : /* String doesn't contail slash. */
605 0 : if (pnt == NULL) {
606 : /* Convert string to prefix. */
607 0 : ret = inet_pton(AF_INET, str, &p->prefix);
608 0 : if (ret == 0)
609 : return 0;
610 :
611 : /* If address doesn't contain slash we assume it host address.
612 : */
613 0 : p->family = AF_INET;
614 0 : p->prefixlen = IPV4_MAX_BITLEN;
615 :
616 0 : return ret;
617 : } else {
618 0 : cp = XMALLOC(MTYPE_TMP, (pnt - str) + 1);
619 0 : memcpy(cp, str, pnt - str);
620 0 : *(cp + (pnt - str)) = '\0';
621 0 : ret = inet_pton(AF_INET, cp, &p->prefix);
622 0 : XFREE(MTYPE_TMP, cp);
623 0 : if (ret == 0)
624 : return 0;
625 :
626 : /* Get prefix length. */
627 0 : plen = (uint8_t)atoi(++pnt);
628 0 : if (plen > IPV4_MAX_BITLEN)
629 : return 0;
630 :
631 0 : p->family = AF_INET;
632 0 : p->prefixlen = plen;
633 : }
634 :
635 0 : return ret;
636 : }
637 :
638 : /* When string format is invalid return 0. */
639 0 : int str2prefix_eth(const char *str, struct prefix_eth *p)
640 : {
641 0 : int ret = 0;
642 0 : int plen = 48;
643 0 : char *pnt;
644 0 : char *cp = NULL;
645 0 : const char *str_addr = str;
646 0 : unsigned int a[6];
647 0 : int i;
648 0 : bool slash = false;
649 :
650 0 : if (!strcmp(str, "any")) {
651 0 : memset(p, 0, sizeof(*p));
652 0 : p->family = AF_ETHERNET;
653 0 : return 1;
654 : }
655 :
656 : /* Find slash inside string. */
657 0 : pnt = strchr(str, '/');
658 :
659 0 : if (pnt) {
660 : /* Get prefix length. */
661 0 : plen = (uint8_t)atoi(++pnt);
662 0 : if (plen > 48) {
663 0 : ret = 0;
664 0 : goto done;
665 : }
666 :
667 0 : cp = XMALLOC(MTYPE_TMP, (pnt - str) + 1);
668 0 : memcpy(cp, str, pnt - str);
669 0 : *(cp + (pnt - str)) = '\0';
670 :
671 0 : str_addr = cp;
672 0 : slash = true;
673 : }
674 :
675 : /* Convert string to prefix. */
676 0 : if (sscanf(str_addr, "%2x:%2x:%2x:%2x:%2x:%2x", a + 0, a + 1, a + 2,
677 : a + 3, a + 4, a + 5)
678 : != 6) {
679 0 : ret = 0;
680 0 : goto done;
681 : }
682 0 : for (i = 0; i < 6; ++i) {
683 0 : p->eth_addr.octet[i] = a[i] & 0xff;
684 : }
685 0 : p->prefixlen = plen;
686 0 : p->family = AF_ETHERNET;
687 :
688 : /*
689 : * special case to allow old configurations to work
690 : * Since all zero's is implicitly meant to allow
691 : * a comparison to zero, let's assume
692 : */
693 0 : if (!slash && is_zero_mac(&(p->eth_addr)))
694 0 : p->prefixlen = 0;
695 :
696 : ret = 1;
697 :
698 0 : done:
699 0 : XFREE(MTYPE_TMP, cp);
700 :
701 0 : return ret;
702 : }
703 :
704 : /* Convert masklen into IP address's netmask (network byte order). */
705 247 : void masklen2ip(const int masklen, struct in_addr *netmask)
706 : {
707 247 : assert(masklen >= 0 && masklen <= IPV4_MAX_BITLEN);
708 :
709 : /* left shift is only defined for less than the size of the type.
710 : * we unconditionally use long long in case the target platform
711 : * has defined behaviour for << 32 (or has a 64-bit left shift) */
712 :
713 247 : if (sizeof(unsigned long long) > 4)
714 247 : netmask->s_addr = htonl(0xffffffffULL << (32 - masklen));
715 : else
716 : netmask->s_addr =
717 : htonl(masklen ? 0xffffffffU << (32 - masklen) : 0);
718 247 : }
719 :
720 : /* Convert IP address's netmask into integer. We assume netmask is
721 : * sequential one. Argument netmask should be network byte order. */
722 0 : uint8_t ip_masklen(struct in_addr netmask)
723 : {
724 0 : uint32_t tmp = ~ntohl(netmask.s_addr);
725 :
726 : /*
727 : * clz: count leading zeroes. sadly, the behaviour of this builtin is
728 : * undefined for a 0 argument, even though most CPUs give 32
729 : */
730 0 : return tmp ? __builtin_clz(tmp) : 32;
731 : }
732 :
733 : /* Apply mask to IPv4 prefix (network byte order). */
734 247 : void apply_mask_ipv4(struct prefix_ipv4 *p)
735 : {
736 247 : struct in_addr mask;
737 247 : masklen2ip(p->prefixlen, &mask);
738 247 : p->prefix.s_addr &= mask.s_addr;
739 247 : }
740 :
741 : /* If prefix is 0.0.0.0/0 then return 1 else return 0. */
742 22 : int prefix_ipv4_any(const struct prefix_ipv4 *p)
743 : {
744 22 : return (p->prefix.s_addr == INADDR_ANY && p->prefixlen == 0);
745 : }
746 :
747 : /* Allocate a new ip version 6 route */
748 14 : struct prefix_ipv6 *prefix_ipv6_new(void)
749 : {
750 14 : struct prefix_ipv6 *p;
751 :
752 : /* Allocate a full-size struct prefix to avoid problems with structure
753 : size mismatches. */
754 14 : p = (struct prefix_ipv6 *)prefix_new();
755 14 : p->family = AF_INET6;
756 14 : return p;
757 : }
758 :
759 : /* Free prefix for IPv6. */
760 0 : void prefix_ipv6_free(struct prefix_ipv6 **p)
761 : {
762 0 : prefix_free((struct prefix **)p);
763 0 : }
764 :
765 : /* If given string is valid return 1 else return 0 */
766 0 : int str2prefix_ipv6(const char *str, struct prefix_ipv6 *p)
767 : {
768 0 : char *pnt;
769 0 : char *cp;
770 0 : int ret;
771 :
772 0 : pnt = strchr(str, '/');
773 :
774 : /* If string doesn't contain `/' treat it as host route. */
775 0 : if (pnt == NULL) {
776 0 : ret = inet_pton(AF_INET6, str, &p->prefix);
777 0 : if (ret == 0)
778 : return 0;
779 0 : p->prefixlen = IPV6_MAX_BITLEN;
780 : } else {
781 0 : int plen;
782 :
783 0 : cp = XMALLOC(MTYPE_TMP, (pnt - str) + 1);
784 0 : memcpy(cp, str, pnt - str);
785 0 : *(cp + (pnt - str)) = '\0';
786 0 : ret = inet_pton(AF_INET6, cp, &p->prefix);
787 0 : XFREE(MTYPE_TMP, cp);
788 0 : if (ret == 0)
789 : return 0;
790 0 : plen = (uint8_t)atoi(++pnt);
791 0 : if (plen > IPV6_MAX_BITLEN)
792 : return 0;
793 0 : p->prefixlen = plen;
794 : }
795 0 : p->family = AF_INET6;
796 :
797 0 : return ret;
798 : }
799 :
800 : /* Convert struct in6_addr netmask into integer.
801 : * FIXME return uint8_t as ip_maskleni() does. */
802 0 : int ip6_masklen(struct in6_addr netmask)
803 : {
804 0 : if (netmask.s6_addr32[0] != 0xffffffffU)
805 0 : return __builtin_clz(~ntohl(netmask.s6_addr32[0]));
806 0 : if (netmask.s6_addr32[1] != 0xffffffffU)
807 0 : return __builtin_clz(~ntohl(netmask.s6_addr32[1])) + 32;
808 0 : if (netmask.s6_addr32[2] != 0xffffffffU)
809 0 : return __builtin_clz(~ntohl(netmask.s6_addr32[2])) + 64;
810 0 : if (netmask.s6_addr32[3] != 0xffffffffU)
811 0 : return __builtin_clz(~ntohl(netmask.s6_addr32[3])) + 96;
812 : /* note __builtin_clz(0) is undefined */
813 : return 128;
814 : }
815 :
816 0 : void masklen2ip6(const int masklen, struct in6_addr *netmask)
817 : {
818 0 : assert(masklen >= 0 && masklen <= IPV6_MAX_BITLEN);
819 :
820 0 : if (masklen == 0) {
821 : /* note << 32 is undefined */
822 0 : memset(netmask, 0, sizeof(*netmask));
823 0 : } else if (masklen <= 32) {
824 0 : netmask->s6_addr32[0] = htonl(0xffffffffU << (32 - masklen));
825 0 : netmask->s6_addr32[1] = 0;
826 0 : netmask->s6_addr32[2] = 0;
827 0 : netmask->s6_addr32[3] = 0;
828 0 : } else if (masklen <= 64) {
829 0 : netmask->s6_addr32[0] = 0xffffffffU;
830 0 : netmask->s6_addr32[1] = htonl(0xffffffffU << (64 - masklen));
831 0 : netmask->s6_addr32[2] = 0;
832 0 : netmask->s6_addr32[3] = 0;
833 0 : } else if (masklen <= 96) {
834 0 : netmask->s6_addr32[0] = 0xffffffffU;
835 0 : netmask->s6_addr32[1] = 0xffffffffU;
836 0 : netmask->s6_addr32[2] = htonl(0xffffffffU << (96 - masklen));
837 0 : netmask->s6_addr32[3] = 0;
838 : } else {
839 0 : netmask->s6_addr32[0] = 0xffffffffU;
840 0 : netmask->s6_addr32[1] = 0xffffffffU;
841 0 : netmask->s6_addr32[2] = 0xffffffffU;
842 0 : netmask->s6_addr32[3] = htonl(0xffffffffU << (128 - masklen));
843 : }
844 0 : }
845 :
846 280 : void apply_mask_ipv6(struct prefix_ipv6 *p)
847 : {
848 280 : uint8_t *pnt;
849 280 : int index;
850 280 : int offset;
851 :
852 280 : index = p->prefixlen / 8;
853 :
854 280 : if (index < 16) {
855 234 : pnt = (uint8_t *)&p->prefix;
856 234 : offset = p->prefixlen % 8;
857 :
858 234 : pnt[index] &= maskbit[offset];
859 234 : index++;
860 :
861 1904 : while (index < 16)
862 1670 : pnt[index++] = 0;
863 : }
864 280 : }
865 :
866 478 : void apply_mask(union prefixptr pu)
867 : {
868 478 : struct prefix *p = pu.p;
869 :
870 478 : switch (p->family) {
871 236 : case AF_INET:
872 236 : apply_mask_ipv4(pu.p4);
873 236 : break;
874 242 : case AF_INET6:
875 242 : apply_mask_ipv6(pu.p6);
876 242 : break;
877 : default:
878 : break;
879 : }
880 478 : return;
881 : }
882 :
883 : /* Utility function of convert between struct prefix <=> union sockunion. */
884 30 : struct prefix *sockunion2hostprefix(const union sockunion *su,
885 : struct prefix *prefix)
886 : {
887 30 : if (su->sa.sa_family == AF_INET) {
888 0 : struct prefix_ipv4 *p;
889 :
890 0 : p = prefix ? (struct prefix_ipv4 *)prefix : prefix_ipv4_new();
891 0 : p->family = AF_INET;
892 0 : p->prefix = su->sin.sin_addr;
893 0 : p->prefixlen = IPV4_MAX_BITLEN;
894 0 : return (struct prefix *)p;
895 : }
896 30 : if (su->sa.sa_family == AF_INET6) {
897 30 : struct prefix_ipv6 *p;
898 :
899 30 : p = prefix ? (struct prefix_ipv6 *)prefix : prefix_ipv6_new();
900 30 : p->family = AF_INET6;
901 30 : p->prefixlen = IPV6_MAX_BITLEN;
902 30 : memcpy(&p->prefix, &su->sin6.sin6_addr,
903 : sizeof(struct in6_addr));
904 30 : return (struct prefix *)p;
905 : }
906 : return NULL;
907 : }
908 :
909 0 : void prefix2sockunion(const struct prefix *p, union sockunion *su)
910 : {
911 0 : memset(su, 0, sizeof(*su));
912 :
913 0 : su->sa.sa_family = p->family;
914 0 : if (p->family == AF_INET)
915 0 : su->sin.sin_addr = p->u.prefix4;
916 0 : if (p->family == AF_INET6)
917 0 : memcpy(&su->sin6.sin6_addr, &p->u.prefix6,
918 : sizeof(struct in6_addr));
919 0 : }
920 :
921 160 : int prefix_blen(union prefixconstptr pu)
922 : {
923 160 : const struct prefix *p = pu.p;
924 :
925 160 : switch (p->family) {
926 : case AF_INET:
927 : return IPV4_MAX_BYTELEN;
928 : case AF_INET6:
929 : return IPV6_MAX_BYTELEN;
930 : case AF_ETHERNET:
931 : return ETH_ALEN;
932 : }
933 : return 0;
934 : }
935 :
936 : /* Generic function for conversion string to struct prefix. */
937 0 : int str2prefix(const char *str, struct prefix *p)
938 : {
939 0 : int ret;
940 :
941 0 : if (!str || !p)
942 : return 0;
943 :
944 : /* First we try to convert string to struct prefix_ipv4. */
945 0 : ret = str2prefix_ipv4(str, (struct prefix_ipv4 *)p);
946 0 : if (ret)
947 : return ret;
948 :
949 : /* Next we try to convert string to struct prefix_ipv6. */
950 0 : ret = str2prefix_ipv6(str, (struct prefix_ipv6 *)p);
951 0 : if (ret)
952 : return ret;
953 :
954 : /* Next we try to convert string to struct prefix_eth. */
955 0 : ret = str2prefix_eth(str, (struct prefix_eth *)p);
956 0 : if (ret)
957 : return ret;
958 :
959 : return 0;
960 : }
961 :
962 0 : static const char *prefixevpn_ead2str(const struct prefix_evpn *p, char *str,
963 : int size)
964 : {
965 0 : uint8_t family;
966 0 : char buf[ESI_STR_LEN];
967 0 : char buf1[INET6_ADDRSTRLEN];
968 :
969 0 : family = IS_IPADDR_V4(&p->prefix.ead_addr.ip) ? AF_INET : AF_INET6;
970 0 : snprintf(str, size, "[%d]:[%u]:[%s]:[%d]:[%s]:[%u]",
971 0 : p->prefix.route_type, p->prefix.ead_addr.eth_tag,
972 : esi_to_str(&p->prefix.ead_addr.esi, buf, sizeof(buf)),
973 : (family == AF_INET) ? IPV4_MAX_BITLEN : IPV6_MAX_BITLEN,
974 0 : inet_ntop(family, &p->prefix.ead_addr.ip.ipaddr_v4, buf1,
975 : sizeof(buf1)),
976 0 : p->prefix.ead_addr.frag_id);
977 0 : return str;
978 : }
979 :
980 0 : static const char *prefixevpn_macip2str(const struct prefix_evpn *p, char *str,
981 : int size)
982 : {
983 0 : uint8_t family;
984 0 : char buf1[ETHER_ADDR_STRLEN];
985 0 : char buf2[PREFIX2STR_BUFFER];
986 :
987 0 : if (is_evpn_prefix_ipaddr_none(p))
988 0 : snprintf(str, size, "[%d]:[%d]:[%d]:[%s]", p->prefix.route_type,
989 0 : p->prefix.macip_addr.eth_tag, 8 * ETH_ALEN,
990 : prefix_mac2str(&p->prefix.macip_addr.mac, buf1,
991 : sizeof(buf1)));
992 : else {
993 0 : family = is_evpn_prefix_ipaddr_v4(p) ? AF_INET : AF_INET6;
994 0 : snprintf(str, size, "[%d]:[%d]:[%d]:[%s]:[%d]:[%s]",
995 0 : p->prefix.route_type, p->prefix.macip_addr.eth_tag,
996 : 8 * ETH_ALEN,
997 : prefix_mac2str(&p->prefix.macip_addr.mac, buf1,
998 : sizeof(buf1)),
999 : family == AF_INET ? IPV4_MAX_BITLEN : IPV6_MAX_BITLEN,
1000 0 : inet_ntop(family, &p->prefix.macip_addr.ip.ip.addr,
1001 : buf2, PREFIX2STR_BUFFER));
1002 : }
1003 0 : return str;
1004 : }
1005 :
1006 0 : static const char *prefixevpn_imet2str(const struct prefix_evpn *p, char *str,
1007 : int size)
1008 : {
1009 0 : uint8_t family;
1010 0 : char buf[INET6_ADDRSTRLEN];
1011 :
1012 0 : family = IS_IPADDR_V4(&p->prefix.imet_addr.ip) ? AF_INET : AF_INET6;
1013 0 : snprintf(str, size, "[%d]:[%d]:[%d]:[%s]", p->prefix.route_type,
1014 0 : p->prefix.imet_addr.eth_tag,
1015 : (family == AF_INET) ? IPV4_MAX_BITLEN : IPV6_MAX_BITLEN,
1016 0 : inet_ntop(family, &p->prefix.imet_addr.ip.ipaddr_v4, buf,
1017 : sizeof(buf)));
1018 :
1019 0 : return str;
1020 : }
1021 :
1022 0 : static const char *prefixevpn_es2str(const struct prefix_evpn *p, char *str,
1023 : int size)
1024 : {
1025 0 : uint8_t family;
1026 0 : char buf[ESI_STR_LEN];
1027 0 : char buf1[INET6_ADDRSTRLEN];
1028 :
1029 0 : family = IS_IPADDR_V4(&p->prefix.es_addr.ip) ? AF_INET : AF_INET6;
1030 0 : snprintf(str, size, "[%d]:[%s]:[%d]:[%s]", p->prefix.route_type,
1031 : esi_to_str(&p->prefix.es_addr.esi, buf, sizeof(buf)),
1032 : (family == AF_INET) ? IPV4_MAX_BITLEN : IPV6_MAX_BITLEN,
1033 0 : inet_ntop(family, &p->prefix.es_addr.ip.ipaddr_v4, buf1,
1034 : sizeof(buf1)));
1035 :
1036 0 : return str;
1037 : }
1038 :
1039 0 : static const char *prefixevpn_prefix2str(const struct prefix_evpn *p, char *str,
1040 : int size)
1041 : {
1042 0 : uint8_t family;
1043 0 : char buf[INET6_ADDRSTRLEN];
1044 :
1045 0 : family = IS_IPADDR_V4(&p->prefix.prefix_addr.ip) ? AF_INET : AF_INET6;
1046 0 : snprintf(str, size, "[%d]:[%d]:[%d]:[%s]", p->prefix.route_type,
1047 0 : p->prefix.prefix_addr.eth_tag,
1048 0 : p->prefix.prefix_addr.ip_prefix_length,
1049 0 : inet_ntop(family, &p->prefix.prefix_addr.ip.ipaddr_v4, buf,
1050 : sizeof(buf)));
1051 0 : return str;
1052 : }
1053 :
1054 0 : static const char *prefixevpn2str(const struct prefix_evpn *p, char *str,
1055 : int size)
1056 : {
1057 0 : switch (p->prefix.route_type) {
1058 0 : case BGP_EVPN_AD_ROUTE:
1059 0 : return prefixevpn_ead2str(p, str, size);
1060 0 : case BGP_EVPN_MAC_IP_ROUTE:
1061 0 : return prefixevpn_macip2str(p, str, size);
1062 0 : case BGP_EVPN_IMET_ROUTE:
1063 0 : return prefixevpn_imet2str(p, str, size);
1064 0 : case BGP_EVPN_ES_ROUTE:
1065 0 : return prefixevpn_es2str(p, str, size);
1066 0 : case BGP_EVPN_IP_PREFIX_ROUTE:
1067 0 : return prefixevpn_prefix2str(p, str, size);
1068 0 : default:
1069 0 : snprintf(str, size, "Unsupported EVPN prefix");
1070 0 : break;
1071 : }
1072 0 : return str;
1073 : }
1074 :
1075 385 : const char *prefix2str(union prefixconstptr pu, char *str, int size)
1076 : {
1077 385 : const struct prefix *p = pu.p;
1078 385 : char buf[PREFIX2STR_BUFFER];
1079 385 : int byte, tmp, a, b;
1080 385 : bool z = false;
1081 385 : size_t l;
1082 :
1083 385 : switch (p->family) {
1084 385 : case AF_INET:
1085 : case AF_INET6:
1086 385 : inet_ntop(p->family, &p->u.prefix, buf, sizeof(buf));
1087 385 : l = strlen(buf);
1088 385 : buf[l++] = '/';
1089 385 : byte = p->prefixlen;
1090 385 : tmp = p->prefixlen - 100;
1091 385 : if (tmp >= 0) {
1092 52 : buf[l++] = '1';
1093 52 : z = true;
1094 52 : byte = tmp;
1095 : }
1096 385 : b = byte % 10;
1097 385 : a = byte / 10;
1098 385 : if (a || z)
1099 385 : buf[l++] = '0' + a;
1100 385 : buf[l++] = '0' + b;
1101 385 : buf[l] = '\0';
1102 385 : strlcpy(str, buf, size);
1103 385 : break;
1104 :
1105 0 : case AF_ETHERNET:
1106 0 : snprintf(str, size, "%s/%d",
1107 : prefix_mac2str(&p->u.prefix_eth, buf, sizeof(buf)),
1108 0 : p->prefixlen);
1109 0 : break;
1110 :
1111 0 : case AF_EVPN:
1112 0 : prefixevpn2str((const struct prefix_evpn *)p, str, size);
1113 0 : break;
1114 :
1115 0 : case AF_FLOWSPEC:
1116 0 : strlcpy(str, "FS prefix", size);
1117 0 : break;
1118 :
1119 0 : default:
1120 0 : strlcpy(str, "UNK prefix", size);
1121 0 : break;
1122 : }
1123 :
1124 385 : return str;
1125 : }
1126 :
1127 0 : static ssize_t prefixhost2str(struct fbuf *fbuf, union prefixconstptr pu)
1128 : {
1129 0 : const struct prefix *p = pu.p;
1130 0 : char buf[PREFIX2STR_BUFFER];
1131 :
1132 0 : switch (p->family) {
1133 0 : case AF_INET:
1134 : case AF_INET6:
1135 0 : inet_ntop(p->family, &p->u.prefix, buf, sizeof(buf));
1136 0 : return bputs(fbuf, buf);
1137 :
1138 0 : case AF_ETHERNET:
1139 0 : prefix_mac2str(&p->u.prefix_eth, buf, sizeof(buf));
1140 0 : return bputs(fbuf, buf);
1141 :
1142 0 : default:
1143 0 : return bprintfrr(fbuf, "{prefix.af=%dPF}", p->family);
1144 : }
1145 : }
1146 :
1147 0 : void prefix_mcast_inet4_dump(const char *onfail, struct in_addr addr,
1148 : char *buf, int buf_size)
1149 : {
1150 0 : int save_errno = errno;
1151 :
1152 0 : if (addr.s_addr == INADDR_ANY)
1153 0 : strlcpy(buf, "*", buf_size);
1154 : else {
1155 0 : if (!inet_ntop(AF_INET, &addr, buf, buf_size)) {
1156 0 : if (onfail)
1157 0 : snprintf(buf, buf_size, "%s", onfail);
1158 : }
1159 : }
1160 :
1161 0 : errno = save_errno;
1162 0 : }
1163 :
1164 0 : const char *prefix_sg2str(const struct prefix_sg *sg, char *sg_str)
1165 : {
1166 0 : char src_str[INET_ADDRSTRLEN];
1167 0 : char grp_str[INET_ADDRSTRLEN];
1168 :
1169 0 : prefix_mcast_inet4_dump("<src?>", sg->src, src_str, sizeof(src_str));
1170 0 : prefix_mcast_inet4_dump("<grp?>", sg->grp, grp_str, sizeof(grp_str));
1171 0 : snprintf(sg_str, PREFIX_SG_STR_LEN, "(%s,%s)", src_str, grp_str);
1172 :
1173 0 : return sg_str;
1174 : }
1175 :
1176 40 : struct prefix *prefix_new(void)
1177 : {
1178 40 : struct prefix *p;
1179 :
1180 40 : p = XCALLOC(MTYPE_PREFIX, sizeof(*p));
1181 40 : return p;
1182 : }
1183 :
1184 0 : void prefix_free_lists(void *arg)
1185 : {
1186 0 : struct prefix *p = arg;
1187 :
1188 0 : prefix_free(&p);
1189 0 : }
1190 :
1191 : /* Free prefix structure. */
1192 80 : void prefix_free(struct prefix **p)
1193 : {
1194 80 : XFREE(MTYPE_PREFIX, *p);
1195 80 : }
1196 :
1197 : /* Utility function to convert ipv4 prefixes to Classful prefixes */
1198 0 : void apply_classful_mask_ipv4(struct prefix_ipv4 *p)
1199 : {
1200 :
1201 0 : uint32_t destination;
1202 :
1203 0 : destination = ntohl(p->prefix.s_addr);
1204 :
1205 0 : if (p->prefixlen == IPV4_MAX_BITLEN)
1206 : ;
1207 : /* do nothing for host routes */
1208 0 : else if (IN_CLASSC(destination)) {
1209 0 : p->prefixlen = 24;
1210 0 : apply_mask_ipv4(p);
1211 0 : } else if (IN_CLASSB(destination)) {
1212 0 : p->prefixlen = 16;
1213 0 : apply_mask_ipv4(p);
1214 : } else {
1215 0 : p->prefixlen = 8;
1216 0 : apply_mask_ipv4(p);
1217 : }
1218 0 : }
1219 :
1220 0 : in_addr_t ipv4_broadcast_addr(in_addr_t hostaddr, int masklen)
1221 : {
1222 0 : struct in_addr mask;
1223 :
1224 0 : masklen2ip(masklen, &mask);
1225 0 : return (masklen != IPV4_MAX_BITLEN - 1)
1226 : ?
1227 : /* normal case */
1228 0 : (hostaddr | ~mask.s_addr)
1229 0 : :
1230 : /* For prefix 31 return 255.255.255.255 (RFC3021) */
1231 : htonl(0xFFFFFFFF);
1232 : }
1233 :
1234 : /* Utility function to convert ipv4 netmask to prefixes
1235 : ex.) "1.1.0.0" "255.255.0.0" => "1.1.0.0/16"
1236 : ex.) "1.0.0.0" NULL => "1.0.0.0/8" */
1237 0 : int netmask_str2prefix_str(const char *net_str, const char *mask_str,
1238 : char *prefix_str, size_t prefix_str_len)
1239 : {
1240 0 : struct in_addr network;
1241 0 : struct in_addr mask;
1242 0 : uint8_t prefixlen;
1243 0 : uint32_t destination;
1244 0 : int ret;
1245 :
1246 0 : ret = inet_aton(net_str, &network);
1247 0 : if (!ret)
1248 : return 0;
1249 :
1250 0 : if (mask_str) {
1251 0 : ret = inet_aton(mask_str, &mask);
1252 0 : if (!ret)
1253 : return 0;
1254 :
1255 0 : prefixlen = ip_masklen(mask);
1256 : } else {
1257 0 : destination = ntohl(network.s_addr);
1258 :
1259 0 : if (network.s_addr == INADDR_ANY)
1260 : prefixlen = 0;
1261 0 : else if (IN_CLASSC(destination))
1262 : prefixlen = 24;
1263 0 : else if (IN_CLASSB(destination))
1264 : prefixlen = 16;
1265 0 : else if (IN_CLASSA(destination))
1266 : prefixlen = 8;
1267 : else
1268 : return 0;
1269 : }
1270 :
1271 0 : snprintf(prefix_str, prefix_str_len, "%s/%d", net_str, prefixlen);
1272 :
1273 0 : return 1;
1274 : }
1275 :
1276 : /* converts to internal representation of mac address
1277 : * returns 1 on success, 0 otherwise
1278 : * format accepted: AA:BB:CC:DD:EE:FF
1279 : * if mac parameter is null, then check only
1280 : */
1281 0 : int prefix_str2mac(const char *str, struct ethaddr *mac)
1282 : {
1283 0 : unsigned int a[6];
1284 0 : int i;
1285 :
1286 0 : if (!str)
1287 : return 0;
1288 :
1289 0 : if (sscanf(str, "%2x:%2x:%2x:%2x:%2x:%2x", a + 0, a + 1, a + 2, a + 3,
1290 : a + 4, a + 5)
1291 : != 6) {
1292 : /* error in incoming str length */
1293 : return 0;
1294 : }
1295 : /* valid mac address */
1296 0 : if (!mac)
1297 : return 1;
1298 0 : for (i = 0; i < 6; ++i)
1299 0 : mac->octet[i] = a[i] & 0xff;
1300 : return 1;
1301 : }
1302 :
1303 0 : char *prefix_mac2str(const struct ethaddr *mac, char *buf, int size)
1304 : {
1305 0 : char *ptr;
1306 :
1307 0 : if (!mac)
1308 : return NULL;
1309 0 : if (!buf)
1310 0 : ptr = XMALLOC(MTYPE_TMP, ETHER_ADDR_STRLEN * sizeof(char));
1311 : else {
1312 0 : assert(size >= ETHER_ADDR_STRLEN);
1313 : ptr = buf;
1314 : }
1315 0 : snprintf(ptr, (ETHER_ADDR_STRLEN), "%02x:%02x:%02x:%02x:%02x:%02x",
1316 0 : (uint8_t)mac->octet[0], (uint8_t)mac->octet[1],
1317 0 : (uint8_t)mac->octet[2], (uint8_t)mac->octet[3],
1318 0 : (uint8_t)mac->octet[4], (uint8_t)mac->octet[5]);
1319 0 : return ptr;
1320 : }
1321 :
1322 499 : unsigned prefix_hash_key(const void *pp)
1323 : {
1324 499 : struct prefix copy;
1325 :
1326 499 : if (((struct prefix *)pp)->family == AF_FLOWSPEC) {
1327 0 : uint32_t len;
1328 0 : void *temp;
1329 :
1330 : /* make sure *all* unused bits are zero,
1331 : * particularly including alignment /
1332 : * padding and unused prefix bytes.
1333 : */
1334 0 : memset(©, 0, sizeof(copy));
1335 0 : prefix_copy(©, (struct prefix *)pp);
1336 0 : len = jhash((void *)copy.u.prefix_flowspec.ptr,
1337 0 : copy.u.prefix_flowspec.prefixlen,
1338 : 0x55aa5a5a);
1339 0 : temp = (void *)copy.u.prefix_flowspec.ptr;
1340 0 : XFREE(MTYPE_PREFIX_FLOWSPEC, temp);
1341 0 : copy.u.prefix_flowspec.ptr = (uintptr_t)NULL;
1342 0 : return len;
1343 : }
1344 : /* make sure *all* unused bits are zero, particularly including
1345 : * alignment /
1346 : * padding and unused prefix bytes. */
1347 499 : memset(©, 0, sizeof(copy));
1348 499 : prefix_copy(©, (struct prefix *)pp);
1349 499 : return jhash(©,
1350 499 : offsetof(struct prefix, u.prefix) + PSIZE(copy.prefixlen),
1351 : 0x55aa5a5a);
1352 : }
1353 :
1354 : /* converts to internal representation of esi
1355 : * returns 1 on success, 0 otherwise
1356 : * format accepted: aa:aa:aa:aa:aa:aa:aa:aa:aa:aa
1357 : * if esi parameter is null, then check only
1358 : */
1359 0 : int str_to_esi(const char *str, esi_t *esi)
1360 : {
1361 0 : int i;
1362 0 : unsigned int a[ESI_BYTES];
1363 :
1364 0 : if (!str)
1365 : return 0;
1366 :
1367 0 : if (sscanf(str, "%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x",
1368 : a + 0, a + 1, a + 2, a + 3,
1369 : a + 4, a + 5, a + 6, a + 7,
1370 : a + 8, a + 9)
1371 : != ESI_BYTES) {
1372 : /* error in incoming str length */
1373 : return 0;
1374 : }
1375 :
1376 : /* valid ESI */
1377 0 : if (!esi)
1378 : return 1;
1379 0 : for (i = 0; i < ESI_BYTES; ++i)
1380 0 : esi->val[i] = a[i] & 0xff;
1381 : return 1;
1382 : }
1383 :
1384 0 : char *esi_to_str(const esi_t *esi, char *buf, int size)
1385 : {
1386 0 : char *ptr;
1387 :
1388 0 : if (!esi)
1389 : return NULL;
1390 0 : if (!buf)
1391 0 : ptr = XMALLOC(MTYPE_TMP, ESI_STR_LEN * sizeof(char));
1392 : else {
1393 0 : assert(size >= ESI_STR_LEN);
1394 : ptr = buf;
1395 : }
1396 :
1397 0 : snprintf(ptr, ESI_STR_LEN,
1398 : "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1399 0 : esi->val[0], esi->val[1], esi->val[2],
1400 0 : esi->val[3], esi->val[4], esi->val[5],
1401 0 : esi->val[6], esi->val[7], esi->val[8],
1402 0 : esi->val[9]);
1403 0 : return ptr;
1404 : }
1405 :
1406 0 : char *evpn_es_df_alg2str(uint8_t df_alg, char *buf, int buf_len)
1407 : {
1408 0 : switch (df_alg) {
1409 0 : case EVPN_MH_DF_ALG_SERVICE_CARVING:
1410 0 : snprintf(buf, buf_len, "service-carving");
1411 0 : break;
1412 :
1413 0 : case EVPN_MH_DF_ALG_HRW:
1414 0 : snprintf(buf, buf_len, "HRW");
1415 0 : break;
1416 :
1417 0 : case EVPN_MH_DF_ALG_PREF:
1418 0 : snprintf(buf, buf_len, "preference");
1419 0 : break;
1420 :
1421 0 : default:
1422 0 : snprintf(buf, buf_len, "unknown %u", df_alg);
1423 0 : break;
1424 : }
1425 :
1426 0 : return buf;
1427 : }
1428 :
1429 6 : bool ipv4_unicast_valid(const struct in_addr *addr)
1430 : {
1431 6 : in_addr_t ip = ntohl(addr->s_addr);
1432 :
1433 6 : if (IPV4_CLASS_D(ip))
1434 : return false;
1435 :
1436 6 : if (IPV4_NET0(ip) || IPV4_NET127(ip) || IPV4_CLASS_E(ip)) {
1437 2 : if (cmd_allow_reserved_ranges_get())
1438 : return true;
1439 : else
1440 : return false;
1441 : }
1442 :
1443 : return true;
1444 : }
1445 :
1446 0 : static int ipaddr2prefix(const struct ipaddr *ip, uint16_t prefixlen,
1447 : struct prefix *p)
1448 : {
1449 0 : switch (ip->ipa_type) {
1450 0 : case (IPADDR_V4):
1451 0 : p->family = AF_INET;
1452 0 : p->u.prefix4 = ip->ipaddr_v4;
1453 0 : p->prefixlen = prefixlen;
1454 0 : break;
1455 0 : case (IPADDR_V6):
1456 0 : p->family = AF_INET6;
1457 0 : p->u.prefix6 = ip->ipaddr_v6;
1458 0 : p->prefixlen = prefixlen;
1459 0 : break;
1460 0 : case (IPADDR_NONE):
1461 0 : p->family = AF_UNSPEC;
1462 0 : break;
1463 : }
1464 :
1465 0 : return 0;
1466 : }
1467 :
1468 : /*
1469 : * Convert type-2 and type-5 evpn route prefixes into the more
1470 : * general ipv4/ipv6 prefix types so we can match prefix lists
1471 : * and such.
1472 : */
1473 0 : int evpn_prefix2prefix(const struct prefix *evpn, struct prefix *to)
1474 : {
1475 0 : const struct evpn_addr *addr;
1476 :
1477 0 : if (evpn->family != AF_EVPN)
1478 : return -1;
1479 :
1480 0 : addr = &evpn->u.prefix_evpn;
1481 :
1482 0 : switch (addr->route_type) {
1483 0 : case BGP_EVPN_MAC_IP_ROUTE:
1484 0 : if (IS_IPADDR_V4(&addr->macip_addr.ip))
1485 0 : ipaddr2prefix(&addr->macip_addr.ip, IPV4_MAX_BITLEN,
1486 : to);
1487 0 : else if (IS_IPADDR_V6(&addr->macip_addr.ip))
1488 0 : ipaddr2prefix(&addr->macip_addr.ip, IPV6_MAX_BITLEN,
1489 : to);
1490 : else
1491 : return -1; /* mac only? */
1492 :
1493 : break;
1494 0 : case BGP_EVPN_IP_PREFIX_ROUTE:
1495 0 : ipaddr2prefix(&addr->prefix_addr.ip,
1496 0 : addr->prefix_addr.ip_prefix_length, to);
1497 0 : break;
1498 : default:
1499 : return -1;
1500 : }
1501 :
1502 : return 0;
1503 : }
1504 :
1505 4 : printfrr_ext_autoreg_p("EA", printfrr_ea);
1506 0 : static ssize_t printfrr_ea(struct fbuf *buf, struct printfrr_eargs *ea,
1507 : const void *ptr)
1508 : {
1509 0 : const struct ethaddr *mac = ptr;
1510 0 : char cbuf[ETHER_ADDR_STRLEN];
1511 :
1512 0 : if (!mac)
1513 0 : return bputs(buf, "(null)");
1514 :
1515 : /* need real length even if buffer is too short */
1516 0 : prefix_mac2str(mac, cbuf, sizeof(cbuf));
1517 0 : return bputs(buf, cbuf);
1518 : }
1519 :
1520 4 : printfrr_ext_autoreg_p("IA", printfrr_ia);
1521 0 : static ssize_t printfrr_ia(struct fbuf *buf, struct printfrr_eargs *ea,
1522 : const void *ptr)
1523 : {
1524 0 : const struct ipaddr *ipa = ptr;
1525 0 : char cbuf[INET6_ADDRSTRLEN];
1526 0 : bool use_star = false;
1527 :
1528 0 : if (ea->fmt[0] == 's') {
1529 0 : use_star = true;
1530 0 : ea->fmt++;
1531 : }
1532 :
1533 0 : if (!ipa || !ipa->ipa_type)
1534 0 : return bputs(buf, "(null)");
1535 :
1536 0 : if (use_star) {
1537 0 : struct in_addr zero4 = {};
1538 0 : struct in6_addr zero6 = {};
1539 :
1540 0 : switch (ipa->ipa_type) {
1541 0 : case IPADDR_V4:
1542 0 : if (!memcmp(&ipa->ip.addr, &zero4, sizeof(zero4)))
1543 0 : return bputch(buf, '*');
1544 : break;
1545 :
1546 0 : case IPADDR_V6:
1547 0 : if (!memcmp(&ipa->ip.addr, &zero6, sizeof(zero6)))
1548 0 : return bputch(buf, '*');
1549 : break;
1550 :
1551 : case IPADDR_NONE:
1552 : break;
1553 : }
1554 : }
1555 :
1556 0 : ipaddr2str(ipa, cbuf, sizeof(cbuf));
1557 0 : return bputs(buf, cbuf);
1558 : }
1559 :
1560 4 : printfrr_ext_autoreg_p("I4", printfrr_i4);
1561 36 : static ssize_t printfrr_i4(struct fbuf *buf, struct printfrr_eargs *ea,
1562 : const void *ptr)
1563 : {
1564 36 : char cbuf[INET_ADDRSTRLEN];
1565 36 : bool use_star = false;
1566 36 : struct in_addr zero = {};
1567 :
1568 36 : if (ea->fmt[0] == 's') {
1569 0 : use_star = true;
1570 0 : ea->fmt++;
1571 : }
1572 :
1573 36 : if (!ptr)
1574 0 : return bputs(buf, "(null)");
1575 :
1576 36 : if (use_star && !memcmp(ptr, &zero, sizeof(zero)))
1577 0 : return bputch(buf, '*');
1578 :
1579 36 : inet_ntop(AF_INET, ptr, cbuf, sizeof(cbuf));
1580 36 : return bputs(buf, cbuf);
1581 : }
1582 :
1583 4 : printfrr_ext_autoreg_p("I6", printfrr_i6);
1584 58 : static ssize_t printfrr_i6(struct fbuf *buf, struct printfrr_eargs *ea,
1585 : const void *ptr)
1586 : {
1587 58 : char cbuf[INET6_ADDRSTRLEN];
1588 58 : bool use_star = false;
1589 58 : struct in6_addr zero = {};
1590 :
1591 58 : if (ea->fmt[0] == 's') {
1592 0 : use_star = true;
1593 0 : ea->fmt++;
1594 : }
1595 :
1596 58 : if (!ptr)
1597 0 : return bputs(buf, "(null)");
1598 :
1599 58 : if (use_star && !memcmp(ptr, &zero, sizeof(zero)))
1600 0 : return bputch(buf, '*');
1601 :
1602 58 : inet_ntop(AF_INET6, ptr, cbuf, sizeof(cbuf));
1603 58 : return bputs(buf, cbuf);
1604 : }
1605 :
1606 4 : printfrr_ext_autoreg_p("FX", printfrr_pfx);
1607 120 : static ssize_t printfrr_pfx(struct fbuf *buf, struct printfrr_eargs *ea,
1608 : const void *ptr)
1609 : {
1610 120 : bool host_only = false;
1611 :
1612 120 : if (ea->fmt[0] == 'h') {
1613 0 : ea->fmt++;
1614 0 : host_only = true;
1615 : }
1616 :
1617 120 : if (!ptr)
1618 0 : return bputs(buf, "(null)");
1619 :
1620 120 : if (host_only)
1621 0 : return prefixhost2str(buf, (struct prefix *)ptr);
1622 : else {
1623 120 : char cbuf[PREFIX_STRLEN];
1624 :
1625 120 : prefix2str(ptr, cbuf, sizeof(cbuf));
1626 120 : return bputs(buf, cbuf);
1627 : }
1628 : }
1629 :
1630 4 : printfrr_ext_autoreg_p("PSG4", printfrr_psg);
1631 0 : static ssize_t printfrr_psg(struct fbuf *buf, struct printfrr_eargs *ea,
1632 : const void *ptr)
1633 : {
1634 0 : const struct prefix_sg *sg = ptr;
1635 0 : ssize_t ret = 0;
1636 :
1637 0 : if (!sg)
1638 0 : return bputs(buf, "(null)");
1639 :
1640 0 : if (sg->src.s_addr == INADDR_ANY)
1641 0 : ret += bputs(buf, "(*,");
1642 : else
1643 0 : ret += bprintfrr(buf, "(%pI4,", &sg->src);
1644 :
1645 0 : if (sg->grp.s_addr == INADDR_ANY)
1646 0 : ret += bputs(buf, "*)");
1647 : else
1648 0 : ret += bprintfrr(buf, "%pI4)", &sg->grp);
1649 :
1650 : return ret;
1651 : }
|