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