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