Coverage Report

Created: 2025-10-23 06:55

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