]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_attr.c
Merge pull request #12791 from taspelund/loc_rib_json_fix
[mirror_frr.git] / bgpd / bgp_attr.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* BGP attributes management routines.
3 * Copyright (C) 1996, 97, 98, 1999 Kunihiro Ishiguro
4 */
5
6 #include <zebra.h>
7
8 #include "linklist.h"
9 #include "prefix.h"
10 #include "memory.h"
11 #include "vector.h"
12 #include "stream.h"
13 #include "log.h"
14 #include "hash.h"
15 #include "jhash.h"
16 #include "queue.h"
17 #include "table.h"
18 #include "filter.h"
19 #include "command.h"
20 #include "srv6.h"
21 #include "frrstr.h"
22
23 #include "bgpd/bgpd.h"
24 #include "bgpd/bgp_attr.h"
25 #include "bgpd/bgp_route.h"
26 #include "bgpd/bgp_aspath.h"
27 #include "bgpd/bgp_community.h"
28 #include "bgpd/bgp_debug.h"
29 #include "bgpd/bgp_errors.h"
30 #include "bgpd/bgp_label.h"
31 #include "bgpd/bgp_packet.h"
32 #include "bgpd/bgp_ecommunity.h"
33 #include "bgpd/bgp_lcommunity.h"
34 #include "bgpd/bgp_updgrp.h"
35 #include "bgpd/bgp_encap_types.h"
36 #ifdef ENABLE_BGP_VNC
37 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
38 #include "bgp_encap_types.h"
39 #include "bgp_vnc_types.h"
40 #endif
41 #include "bgp_evpn.h"
42 #include "bgp_flowspec_private.h"
43 #include "bgp_mac.h"
44
45 /* Attribute strings for logging. */
46 static const struct message attr_str[] = {
47 {BGP_ATTR_ORIGIN, "ORIGIN"},
48 {BGP_ATTR_AS_PATH, "AS_PATH"},
49 {BGP_ATTR_NEXT_HOP, "NEXT_HOP"},
50 {BGP_ATTR_MULTI_EXIT_DISC, "MULTI_EXIT_DISC"},
51 {BGP_ATTR_LOCAL_PREF, "LOCAL_PREF"},
52 {BGP_ATTR_ATOMIC_AGGREGATE, "ATOMIC_AGGREGATE"},
53 {BGP_ATTR_AGGREGATOR, "AGGREGATOR"},
54 {BGP_ATTR_COMMUNITIES, "COMMUNITY"},
55 {BGP_ATTR_ORIGINATOR_ID, "ORIGINATOR_ID"},
56 {BGP_ATTR_CLUSTER_LIST, "CLUSTER_LIST"},
57 {BGP_ATTR_MP_REACH_NLRI, "MP_REACH_NLRI"},
58 {BGP_ATTR_MP_UNREACH_NLRI, "MP_UNREACH_NLRI"},
59 {BGP_ATTR_EXT_COMMUNITIES, "EXT_COMMUNITIES"},
60 {BGP_ATTR_AS4_PATH, "AS4_PATH"},
61 {BGP_ATTR_AS4_AGGREGATOR, "AS4_AGGREGATOR"},
62 {BGP_ATTR_PMSI_TUNNEL, "PMSI_TUNNEL_ATTRIBUTE"},
63 {BGP_ATTR_ENCAP, "ENCAP"},
64 {BGP_ATTR_OTC, "OTC"},
65 #ifdef ENABLE_BGP_VNC_ATTR
66 {BGP_ATTR_VNC, "VNC"},
67 #endif
68 {BGP_ATTR_LARGE_COMMUNITIES, "LARGE_COMMUNITY"},
69 {BGP_ATTR_PREFIX_SID, "PREFIX_SID"},
70 {BGP_ATTR_IPV6_EXT_COMMUNITIES, "IPV6_EXT_COMMUNITIES"},
71 {BGP_ATTR_AIGP, "AIGP"},
72 {0}};
73
74 static const struct message attr_flag_str[] = {
75 {BGP_ATTR_FLAG_OPTIONAL, "Optional"},
76 {BGP_ATTR_FLAG_TRANS, "Transitive"},
77 {BGP_ATTR_FLAG_PARTIAL, "Partial"},
78 /* bgp_attr_flags_diagnose() relies on this bit being last in
79 this list */
80 {BGP_ATTR_FLAG_EXTLEN, "Extended Length"},
81 {0}};
82
83 static struct hash *cluster_hash;
84
85 static void *cluster_hash_alloc(void *p)
86 {
87 const struct cluster_list *val = (const struct cluster_list *)p;
88 struct cluster_list *cluster;
89
90 cluster = XMALLOC(MTYPE_CLUSTER, sizeof(struct cluster_list));
91 cluster->length = val->length;
92
93 if (cluster->length) {
94 cluster->list = XMALLOC(MTYPE_CLUSTER_VAL, val->length);
95 memcpy(cluster->list, val->list, val->length);
96 } else
97 cluster->list = NULL;
98
99 cluster->refcnt = 0;
100
101 return cluster;
102 }
103
104 /* Cluster list related functions. */
105 static struct cluster_list *cluster_parse(struct in_addr *pnt, int length)
106 {
107 struct cluster_list tmp = {};
108 struct cluster_list *cluster;
109
110 tmp.length = length;
111 tmp.list = length == 0 ? NULL : pnt;
112
113 cluster = hash_get(cluster_hash, &tmp, cluster_hash_alloc);
114 cluster->refcnt++;
115 return cluster;
116 }
117
118 bool cluster_loop_check(struct cluster_list *cluster, struct in_addr originator)
119 {
120 int i;
121
122 for (i = 0; i < cluster->length / 4; i++)
123 if (cluster->list[i].s_addr == originator.s_addr)
124 return true;
125 return false;
126 }
127
128 static unsigned int cluster_hash_key_make(const void *p)
129 {
130 const struct cluster_list *cluster = p;
131
132 return jhash(cluster->list, cluster->length, 0);
133 }
134
135 static bool cluster_hash_cmp(const void *p1, const void *p2)
136 {
137 const struct cluster_list *cluster1 = p1;
138 const struct cluster_list *cluster2 = p2;
139
140 if (cluster1->list == cluster2->list)
141 return true;
142
143 if (!cluster1->list || !cluster2->list)
144 return false;
145
146 if (cluster1->length != cluster2->length)
147 return false;
148
149 return (memcmp(cluster1->list, cluster2->list, cluster1->length) == 0);
150 }
151
152 static void cluster_free(struct cluster_list *cluster)
153 {
154 XFREE(MTYPE_CLUSTER_VAL, cluster->list);
155 XFREE(MTYPE_CLUSTER, cluster);
156 }
157
158 static struct cluster_list *cluster_intern(struct cluster_list *cluster)
159 {
160 struct cluster_list *find;
161
162 find = hash_get(cluster_hash, cluster, cluster_hash_alloc);
163 find->refcnt++;
164
165 return find;
166 }
167
168 static void cluster_unintern(struct cluster_list **cluster)
169 {
170 if ((*cluster)->refcnt)
171 (*cluster)->refcnt--;
172
173 if ((*cluster)->refcnt == 0) {
174 void *p = hash_release(cluster_hash, *cluster);
175 assert(p == *cluster);
176 cluster_free(*cluster);
177 *cluster = NULL;
178 }
179 }
180
181 static void cluster_init(void)
182 {
183 cluster_hash = hash_create(cluster_hash_key_make, cluster_hash_cmp,
184 "BGP Cluster");
185 }
186
187 static void cluster_finish(void)
188 {
189 hash_clean(cluster_hash, (void (*)(void *))cluster_free);
190 hash_free(cluster_hash);
191 cluster_hash = NULL;
192 }
193
194 static struct hash *encap_hash = NULL;
195 #ifdef ENABLE_BGP_VNC
196 static struct hash *vnc_hash = NULL;
197 #endif
198 static struct hash *srv6_l3vpn_hash;
199 static struct hash *srv6_vpn_hash;
200
201 struct bgp_attr_encap_subtlv *encap_tlv_dup(struct bgp_attr_encap_subtlv *orig)
202 {
203 struct bgp_attr_encap_subtlv *new;
204 struct bgp_attr_encap_subtlv *tail;
205 struct bgp_attr_encap_subtlv *p;
206
207 for (p = orig, tail = new = NULL; p; p = p->next) {
208 int size = sizeof(struct bgp_attr_encap_subtlv) + p->length;
209 if (tail) {
210 tail->next = XCALLOC(MTYPE_ENCAP_TLV, size);
211 tail = tail->next;
212 } else {
213 tail = new = XCALLOC(MTYPE_ENCAP_TLV, size);
214 }
215 assert(tail);
216 memcpy(tail, p, size);
217 tail->next = NULL;
218 }
219
220 return new;
221 }
222
223 static void encap_free(struct bgp_attr_encap_subtlv *p)
224 {
225 struct bgp_attr_encap_subtlv *next;
226 while (p) {
227 next = p->next;
228 p->next = NULL;
229 XFREE(MTYPE_ENCAP_TLV, p);
230 p = next;
231 }
232 }
233
234 void bgp_attr_flush_encap(struct attr *attr)
235 {
236 if (!attr)
237 return;
238
239 if (attr->encap_subtlvs) {
240 encap_free(attr->encap_subtlvs);
241 attr->encap_subtlvs = NULL;
242 }
243 #ifdef ENABLE_BGP_VNC
244 struct bgp_attr_encap_subtlv *vnc_subtlvs =
245 bgp_attr_get_vnc_subtlvs(attr);
246
247 if (vnc_subtlvs) {
248 encap_free(vnc_subtlvs);
249 bgp_attr_set_vnc_subtlvs(attr, NULL);
250 }
251 #endif
252 }
253
254 /*
255 * Compare encap sub-tlv chains
256 *
257 * 1 = equivalent
258 * 0 = not equivalent
259 *
260 * This algorithm could be made faster if needed
261 */
262 static bool encap_same(const struct bgp_attr_encap_subtlv *h1,
263 const struct bgp_attr_encap_subtlv *h2)
264 {
265 const struct bgp_attr_encap_subtlv *p;
266 const struct bgp_attr_encap_subtlv *q;
267
268 if (h1 == h2)
269 return true;
270 if (h1 == NULL || h2 == NULL)
271 return false;
272
273 for (p = h1; p; p = p->next) {
274 for (q = h2; q; q = q->next) {
275 if ((p->type == q->type) && (p->length == q->length)
276 && !memcmp(p->value, q->value, p->length)) {
277
278 break;
279 }
280 }
281 if (!q)
282 return false;
283 }
284
285 for (p = h2; p; p = p->next) {
286 for (q = h1; q; q = q->next) {
287 if ((p->type == q->type) && (p->length == q->length)
288 && !memcmp(p->value, q->value, p->length)) {
289
290 break;
291 }
292 }
293 if (!q)
294 return false;
295 }
296
297 return true;
298 }
299
300 static void *encap_hash_alloc(void *p)
301 {
302 /* Encap structure is already allocated. */
303 return p;
304 }
305
306 typedef enum {
307 ENCAP_SUBTLV_TYPE,
308 #ifdef ENABLE_BGP_VNC
309 VNC_SUBTLV_TYPE
310 #endif
311 } encap_subtlv_type;
312
313 static struct bgp_attr_encap_subtlv *
314 encap_intern(struct bgp_attr_encap_subtlv *encap, encap_subtlv_type type)
315 {
316 struct bgp_attr_encap_subtlv *find;
317 struct hash *hash = encap_hash;
318 #ifdef ENABLE_BGP_VNC
319 if (type == VNC_SUBTLV_TYPE)
320 hash = vnc_hash;
321 #endif
322
323 find = hash_get(hash, encap, encap_hash_alloc);
324 if (find != encap)
325 encap_free(encap);
326 find->refcnt++;
327
328 return find;
329 }
330
331 static void encap_unintern(struct bgp_attr_encap_subtlv **encapp,
332 encap_subtlv_type type)
333 {
334 struct bgp_attr_encap_subtlv *encap = *encapp;
335 if (encap->refcnt)
336 encap->refcnt--;
337
338 if (encap->refcnt == 0) {
339 struct hash *hash = encap_hash;
340 #ifdef ENABLE_BGP_VNC
341 if (type == VNC_SUBTLV_TYPE)
342 hash = vnc_hash;
343 #endif
344 hash_release(hash, encap);
345 encap_free(encap);
346 *encapp = NULL;
347 }
348 }
349
350 static unsigned int encap_hash_key_make(const void *p)
351 {
352 const struct bgp_attr_encap_subtlv *encap = p;
353
354 return jhash(encap->value, encap->length, 0);
355 }
356
357 static bool encap_hash_cmp(const void *p1, const void *p2)
358 {
359 return encap_same((const struct bgp_attr_encap_subtlv *)p1,
360 (const struct bgp_attr_encap_subtlv *)p2);
361 }
362
363 static void encap_init(void)
364 {
365 encap_hash = hash_create(encap_hash_key_make, encap_hash_cmp,
366 "BGP Encap Hash");
367 #ifdef ENABLE_BGP_VNC
368 vnc_hash = hash_create(encap_hash_key_make, encap_hash_cmp,
369 "BGP VNC Hash");
370 #endif
371 }
372
373 static void encap_finish(void)
374 {
375 hash_clean(encap_hash, (void (*)(void *))encap_free);
376 hash_free(encap_hash);
377 encap_hash = NULL;
378 #ifdef ENABLE_BGP_VNC
379 hash_clean(vnc_hash, (void (*)(void *))encap_free);
380 hash_free(vnc_hash);
381 vnc_hash = NULL;
382 #endif
383 }
384
385 static bool overlay_index_same(const struct attr *a1, const struct attr *a2)
386 {
387 if (!a1 && a2)
388 return false;
389 if (!a2 && a1)
390 return false;
391 if (!a1 && !a2)
392 return true;
393
394 return bgp_route_evpn_same(bgp_attr_get_evpn_overlay(a1),
395 bgp_attr_get_evpn_overlay(a2));
396 }
397
398 /* Unknown transit attribute. */
399 static struct hash *transit_hash;
400
401 static void transit_free(struct transit *transit)
402 {
403 XFREE(MTYPE_TRANSIT_VAL, transit->val);
404 XFREE(MTYPE_TRANSIT, transit);
405 }
406
407 static void *transit_hash_alloc(void *p)
408 {
409 /* Transit structure is already allocated. */
410 return p;
411 }
412
413 static struct transit *transit_intern(struct transit *transit)
414 {
415 struct transit *find;
416
417 find = hash_get(transit_hash, transit, transit_hash_alloc);
418 if (find != transit)
419 transit_free(transit);
420 find->refcnt++;
421
422 return find;
423 }
424
425 static void transit_unintern(struct transit **transit)
426 {
427 if ((*transit)->refcnt)
428 (*transit)->refcnt--;
429
430 if ((*transit)->refcnt == 0) {
431 hash_release(transit_hash, *transit);
432 transit_free(*transit);
433 *transit = NULL;
434 }
435 }
436
437 static bool bgp_attr_aigp_get_tlv_metric(uint8_t *pnt, int length,
438 uint64_t *aigp)
439 {
440 uint8_t *data = pnt;
441 uint8_t tlv_type;
442 uint16_t tlv_length;
443
444 while (length) {
445 tlv_type = *data;
446 ptr_get_be16(data + 1, &tlv_length);
447 (void)data;
448
449 /* The value field of the AIGP TLV is always 8 octets
450 * long and its value is interpreted as an unsigned 64-bit
451 * integer.
452 */
453 if (tlv_type == BGP_AIGP_TLV_METRIC) {
454 (void)ptr_get_be64(data + 3, aigp);
455
456 /* If an AIGP attribute is received and its first AIGP
457 * TLV contains the maximum value 0xffffffffffffffff,
458 * the attribute SHOULD be considered to be malformed
459 * and SHOULD be discarded as specified in this section.
460 */
461 if (*aigp == BGP_AIGP_TLV_METRIC_MAX) {
462 zlog_err("Bad AIGP TLV (%s) length: %llu",
463 BGP_AIGP_TLV_METRIC_DESC,
464 BGP_AIGP_TLV_METRIC_MAX);
465 return false;
466 }
467
468 return true;
469 }
470
471 data += tlv_length;
472 length -= tlv_length;
473 }
474
475 return false;
476 }
477
478 static uint64_t bgp_aigp_metric_total(struct bgp_path_info *bpi)
479 {
480 uint64_t aigp = bgp_attr_get_aigp_metric(bpi->attr);
481
482 if (bpi->nexthop)
483 return aigp + bpi->nexthop->metric;
484 else
485 return aigp;
486 }
487
488 static void stream_put_bgp_aigp_tlv_metric(struct stream *s,
489 struct bgp_path_info *bpi)
490 {
491 stream_putc(s, BGP_AIGP_TLV_METRIC);
492 stream_putw(s, BGP_AIGP_TLV_METRIC_LEN);
493 stream_putq(s, bgp_aigp_metric_total(bpi));
494 }
495
496 static bool bgp_attr_aigp_valid(uint8_t *pnt, int length)
497 {
498 uint8_t *data = pnt;
499 uint8_t tlv_type;
500 uint16_t tlv_length;
501
502 if (length < 3) {
503 zlog_err("Bad AIGP attribute length (MUST be minimum 3): %u",
504 length);
505 return false;
506 }
507
508 while (length) {
509 tlv_type = *data;
510 ptr_get_be16(data + 1, &tlv_length);
511 (void)data;
512
513 if (length < tlv_length) {
514 zlog_err(
515 "Bad AIGP attribute length: %u, but TLV length: %u",
516 length, tlv_length);
517 return false;
518 }
519
520 if (tlv_length < 3) {
521 zlog_err("Bad AIGP TLV length (MUST be minimum 3): %u",
522 tlv_length);
523 return false;
524 }
525
526 /* AIGP TLV, Length: 11 */
527 if (tlv_type == BGP_AIGP_TLV_METRIC &&
528 tlv_length != BGP_AIGP_TLV_METRIC_LEN) {
529 zlog_err("Bad AIGP TLV (%s) length: %u",
530 BGP_AIGP_TLV_METRIC_DESC, tlv_length);
531 return false;
532 }
533
534 data += tlv_length;
535 length -= tlv_length;
536 }
537
538 return true;
539 }
540
541 static void *srv6_l3vpn_hash_alloc(void *p)
542 {
543 return p;
544 }
545
546 static void srv6_l3vpn_free(struct bgp_attr_srv6_l3vpn *l3vpn)
547 {
548 XFREE(MTYPE_BGP_SRV6_L3VPN, l3vpn);
549 }
550
551 static struct bgp_attr_srv6_l3vpn *
552 srv6_l3vpn_intern(struct bgp_attr_srv6_l3vpn *l3vpn)
553 {
554 struct bgp_attr_srv6_l3vpn *find;
555
556 find = hash_get(srv6_l3vpn_hash, l3vpn, srv6_l3vpn_hash_alloc);
557 if (find != l3vpn)
558 srv6_l3vpn_free(l3vpn);
559 find->refcnt++;
560 return find;
561 }
562
563 static void srv6_l3vpn_unintern(struct bgp_attr_srv6_l3vpn **l3vpnp)
564 {
565 struct bgp_attr_srv6_l3vpn *l3vpn = *l3vpnp;
566
567 if (l3vpn->refcnt)
568 l3vpn->refcnt--;
569
570 if (l3vpn->refcnt == 0) {
571 hash_release(srv6_l3vpn_hash, l3vpn);
572 srv6_l3vpn_free(l3vpn);
573 *l3vpnp = NULL;
574 }
575 }
576
577 static void *srv6_vpn_hash_alloc(void *p)
578 {
579 return p;
580 }
581
582 static void srv6_vpn_free(struct bgp_attr_srv6_vpn *vpn)
583 {
584 XFREE(MTYPE_BGP_SRV6_VPN, vpn);
585 }
586
587 static struct bgp_attr_srv6_vpn *srv6_vpn_intern(struct bgp_attr_srv6_vpn *vpn)
588 {
589 struct bgp_attr_srv6_vpn *find;
590
591 find = hash_get(srv6_vpn_hash, vpn, srv6_vpn_hash_alloc);
592 if (find != vpn)
593 srv6_vpn_free(vpn);
594 find->refcnt++;
595 return find;
596 }
597
598 static void srv6_vpn_unintern(struct bgp_attr_srv6_vpn **vpnp)
599 {
600 struct bgp_attr_srv6_vpn *vpn = *vpnp;
601
602 if (vpn->refcnt)
603 vpn->refcnt--;
604
605 if (vpn->refcnt == 0) {
606 hash_release(srv6_vpn_hash, vpn);
607 srv6_vpn_free(vpn);
608 *vpnp = NULL;
609 }
610 }
611
612 static uint32_t srv6_l3vpn_hash_key_make(const void *p)
613 {
614 const struct bgp_attr_srv6_l3vpn *l3vpn = p;
615 uint32_t key = 0;
616
617 key = jhash(&l3vpn->sid, 16, key);
618 key = jhash_1word(l3vpn->sid_flags, key);
619 key = jhash_1word(l3vpn->endpoint_behavior, key);
620 key = jhash_1word(l3vpn->loc_block_len, key);
621 key = jhash_1word(l3vpn->loc_node_len, key);
622 key = jhash_1word(l3vpn->func_len, key);
623 key = jhash_1word(l3vpn->arg_len, key);
624 key = jhash_1word(l3vpn->transposition_len, key);
625 key = jhash_1word(l3vpn->transposition_offset, key);
626 return key;
627 }
628
629 static bool srv6_l3vpn_hash_cmp(const void *p1, const void *p2)
630 {
631 const struct bgp_attr_srv6_l3vpn *l3vpn1 = p1;
632 const struct bgp_attr_srv6_l3vpn *l3vpn2 = p2;
633
634 return sid_same(&l3vpn1->sid, &l3vpn2->sid)
635 && l3vpn1->sid_flags == l3vpn2->sid_flags
636 && l3vpn1->endpoint_behavior == l3vpn2->endpoint_behavior
637 && l3vpn1->loc_block_len == l3vpn2->loc_block_len
638 && l3vpn1->loc_node_len == l3vpn2->loc_node_len
639 && l3vpn1->func_len == l3vpn2->func_len
640 && l3vpn1->arg_len == l3vpn2->arg_len
641 && l3vpn1->transposition_len == l3vpn2->transposition_len
642 && l3vpn1->transposition_offset == l3vpn2->transposition_offset;
643 }
644
645 static bool srv6_l3vpn_same(const struct bgp_attr_srv6_l3vpn *h1,
646 const struct bgp_attr_srv6_l3vpn *h2)
647 {
648 if (h1 == h2)
649 return true;
650 else if (h1 == NULL || h2 == NULL)
651 return false;
652 else
653 return srv6_l3vpn_hash_cmp((const void *)h1, (const void *)h2);
654 }
655
656 static unsigned int srv6_vpn_hash_key_make(const void *p)
657 {
658 const struct bgp_attr_srv6_vpn *vpn = p;
659 uint32_t key = 0;
660
661 key = jhash(&vpn->sid, 16, key);
662 key = jhash_1word(vpn->sid_flags, key);
663 return key;
664 }
665
666 static bool srv6_vpn_hash_cmp(const void *p1, const void *p2)
667 {
668 const struct bgp_attr_srv6_vpn *vpn1 = p1;
669 const struct bgp_attr_srv6_vpn *vpn2 = p2;
670
671 return sid_same(&vpn1->sid, &vpn2->sid)
672 && vpn1->sid_flags == vpn2->sid_flags;
673 }
674
675 static bool srv6_vpn_same(const struct bgp_attr_srv6_vpn *h1,
676 const struct bgp_attr_srv6_vpn *h2)
677 {
678 if (h1 == h2)
679 return true;
680 else if (h1 == NULL || h2 == NULL)
681 return false;
682 else
683 return srv6_vpn_hash_cmp((const void *)h1, (const void *)h2);
684 }
685
686 static void srv6_init(void)
687 {
688 srv6_l3vpn_hash =
689 hash_create(srv6_l3vpn_hash_key_make, srv6_l3vpn_hash_cmp,
690 "BGP Prefix-SID SRv6-L3VPN-Service-TLV");
691 srv6_vpn_hash = hash_create(srv6_vpn_hash_key_make, srv6_vpn_hash_cmp,
692 "BGP Prefix-SID SRv6-VPN-Service-TLV");
693 }
694
695 static void srv6_finish(void)
696 {
697 hash_clean(srv6_l3vpn_hash, (void (*)(void *))srv6_l3vpn_free);
698 hash_free(srv6_l3vpn_hash);
699 srv6_l3vpn_hash = NULL;
700 hash_clean(srv6_vpn_hash, (void (*)(void *))srv6_vpn_free);
701 hash_free(srv6_vpn_hash);
702 srv6_vpn_hash = NULL;
703 }
704
705 static unsigned int transit_hash_key_make(const void *p)
706 {
707 const struct transit *transit = p;
708
709 return jhash(transit->val, transit->length, 0);
710 }
711
712 static bool transit_hash_cmp(const void *p1, const void *p2)
713 {
714 const struct transit *transit1 = p1;
715 const struct transit *transit2 = p2;
716
717 return (transit1->length == transit2->length
718 && memcmp(transit1->val, transit2->val, transit1->length) == 0);
719 }
720
721 static void transit_init(void)
722 {
723 transit_hash = hash_create(transit_hash_key_make, transit_hash_cmp,
724 "BGP Transit Hash");
725 }
726
727 static void transit_finish(void)
728 {
729 hash_clean(transit_hash, (void (*)(void *))transit_free);
730 hash_free(transit_hash);
731 transit_hash = NULL;
732 }
733
734 /* Attribute hash routines. */
735 static struct hash *attrhash;
736
737 unsigned long int attr_count(void)
738 {
739 return attrhash->count;
740 }
741
742 unsigned long int attr_unknown_count(void)
743 {
744 return transit_hash->count;
745 }
746
747 unsigned int attrhash_key_make(const void *p)
748 {
749 const struct attr *attr = (struct attr *)p;
750 uint32_t key = 0;
751 #define MIX(val) key = jhash_1word(val, key)
752 #define MIX3(a, b, c) key = jhash_3words((a), (b), (c), key)
753
754 MIX3(attr->origin, attr->nexthop.s_addr, attr->med);
755 MIX3(attr->local_pref, attr->aggregator_as,
756 attr->aggregator_addr.s_addr);
757 MIX3(attr->weight, attr->mp_nexthop_global_in.s_addr,
758 attr->originator_id.s_addr);
759 MIX3(attr->tag, attr->label, attr->label_index);
760
761 if (attr->aspath)
762 MIX(aspath_key_make(attr->aspath));
763 if (bgp_attr_get_community(attr))
764 MIX(community_hash_make(bgp_attr_get_community(attr)));
765 if (bgp_attr_get_lcommunity(attr))
766 MIX(lcommunity_hash_make(bgp_attr_get_lcommunity(attr)));
767 if (bgp_attr_get_ecommunity(attr))
768 MIX(ecommunity_hash_make(bgp_attr_get_ecommunity(attr)));
769 if (bgp_attr_get_ipv6_ecommunity(attr))
770 MIX(ecommunity_hash_make(bgp_attr_get_ipv6_ecommunity(attr)));
771 if (bgp_attr_get_cluster(attr))
772 MIX(cluster_hash_key_make(bgp_attr_get_cluster(attr)));
773 if (bgp_attr_get_transit(attr))
774 MIX(transit_hash_key_make(bgp_attr_get_transit(attr)));
775 if (attr->encap_subtlvs)
776 MIX(encap_hash_key_make(attr->encap_subtlvs));
777 if (attr->srv6_l3vpn)
778 MIX(srv6_l3vpn_hash_key_make(attr->srv6_l3vpn));
779 if (attr->srv6_vpn)
780 MIX(srv6_vpn_hash_key_make(attr->srv6_vpn));
781 #ifdef ENABLE_BGP_VNC
782 struct bgp_attr_encap_subtlv *vnc_subtlvs =
783 bgp_attr_get_vnc_subtlvs(attr);
784 if (vnc_subtlvs)
785 MIX(encap_hash_key_make(vnc_subtlvs));
786 #endif
787 MIX(attr->mp_nexthop_len);
788 key = jhash(attr->mp_nexthop_global.s6_addr, IPV6_MAX_BYTELEN, key);
789 key = jhash(attr->mp_nexthop_local.s6_addr, IPV6_MAX_BYTELEN, key);
790 MIX3(attr->nh_ifindex, attr->nh_lla_ifindex, attr->distance);
791 MIX(attr->rmap_table_id);
792 MIX(attr->nh_type);
793 MIX(attr->bh_type);
794 MIX(attr->otc);
795 MIX(bgp_attr_get_aigp_metric(attr));
796
797 return key;
798 }
799
800 bool attrhash_cmp(const void *p1, const void *p2)
801 {
802 const struct attr *attr1 = p1;
803 const struct attr *attr2 = p2;
804
805 if (attr1->flag == attr2->flag && attr1->origin == attr2->origin
806 && attr1->nexthop.s_addr == attr2->nexthop.s_addr
807 && attr1->aspath == attr2->aspath
808 && bgp_attr_get_community(attr1)
809 == bgp_attr_get_community(attr2)
810 && attr1->med == attr2->med
811 && attr1->local_pref == attr2->local_pref
812 && attr1->rmap_change_flags == attr2->rmap_change_flags) {
813 if (attr1->aggregator_as == attr2->aggregator_as
814 && attr1->aggregator_addr.s_addr
815 == attr2->aggregator_addr.s_addr
816 && attr1->weight == attr2->weight
817 && attr1->tag == attr2->tag
818 && attr1->label_index == attr2->label_index
819 && attr1->mp_nexthop_len == attr2->mp_nexthop_len
820 && bgp_attr_get_ecommunity(attr1)
821 == bgp_attr_get_ecommunity(attr2)
822 && bgp_attr_get_ipv6_ecommunity(attr1)
823 == bgp_attr_get_ipv6_ecommunity(attr2)
824 && bgp_attr_get_lcommunity(attr1)
825 == bgp_attr_get_lcommunity(attr2)
826 && bgp_attr_get_cluster(attr1)
827 == bgp_attr_get_cluster(attr2)
828 && bgp_attr_get_transit(attr1)
829 == bgp_attr_get_transit(attr2)
830 && bgp_attr_get_aigp_metric(attr1)
831 == bgp_attr_get_aigp_metric(attr2)
832 && attr1->rmap_table_id == attr2->rmap_table_id
833 && (attr1->encap_tunneltype == attr2->encap_tunneltype)
834 && encap_same(attr1->encap_subtlvs, attr2->encap_subtlvs)
835 #ifdef ENABLE_BGP_VNC
836 && encap_same(bgp_attr_get_vnc_subtlvs(attr1),
837 bgp_attr_get_vnc_subtlvs(attr2))
838 #endif
839 && IPV6_ADDR_SAME(&attr1->mp_nexthop_global,
840 &attr2->mp_nexthop_global)
841 && IPV6_ADDR_SAME(&attr1->mp_nexthop_local,
842 &attr2->mp_nexthop_local)
843 && IPV4_ADDR_SAME(&attr1->mp_nexthop_global_in,
844 &attr2->mp_nexthop_global_in)
845 && IPV4_ADDR_SAME(&attr1->originator_id,
846 &attr2->originator_id)
847 && overlay_index_same(attr1, attr2)
848 && !memcmp(&attr1->esi, &attr2->esi, sizeof(esi_t))
849 && attr1->es_flags == attr2->es_flags
850 && attr1->mm_sync_seqnum == attr2->mm_sync_seqnum
851 && attr1->df_pref == attr2->df_pref
852 && attr1->df_alg == attr2->df_alg
853 && attr1->nh_ifindex == attr2->nh_ifindex
854 && attr1->nh_lla_ifindex == attr2->nh_lla_ifindex
855 && attr1->distance == attr2->distance
856 && srv6_l3vpn_same(attr1->srv6_l3vpn, attr2->srv6_l3vpn)
857 && srv6_vpn_same(attr1->srv6_vpn, attr2->srv6_vpn)
858 && attr1->srte_color == attr2->srte_color
859 && attr1->nh_type == attr2->nh_type
860 && attr1->bh_type == attr2->bh_type
861 && attr1->otc == attr2->otc)
862 return true;
863 }
864
865 return false;
866 }
867
868 static void attrhash_init(void)
869 {
870 attrhash =
871 hash_create(attrhash_key_make, attrhash_cmp, "BGP Attributes");
872 }
873
874 /*
875 * special for hash_clean below
876 */
877 static void attr_vfree(void *attr)
878 {
879 XFREE(MTYPE_ATTR, attr);
880 }
881
882 static void attrhash_finish(void)
883 {
884 hash_clean(attrhash, attr_vfree);
885 hash_free(attrhash);
886 attrhash = NULL;
887 }
888
889 static void attr_show_all_iterator(struct hash_bucket *bucket, struct vty *vty)
890 {
891 struct attr *attr = bucket->data;
892 struct in6_addr *sid = NULL;
893
894 if (attr->srv6_l3vpn)
895 sid = &attr->srv6_l3vpn->sid;
896 else if (attr->srv6_vpn)
897 sid = &attr->srv6_vpn->sid;
898
899 vty_out(vty, "attr[%ld] nexthop %pI4\n", attr->refcnt, &attr->nexthop);
900
901 vty_out(vty,
902 "\tflags: %" PRIu64
903 " distance: %u med: %u local_pref: %u origin: %u weight: %u label: %u sid: %pI6\n",
904 attr->flag, attr->distance, attr->med, attr->local_pref,
905 attr->origin, attr->weight, attr->label, sid);
906 }
907
908 void attr_show_all(struct vty *vty)
909 {
910 hash_iterate(attrhash, (void (*)(struct hash_bucket *,
911 void *))attr_show_all_iterator,
912 vty);
913 }
914
915 static void *bgp_attr_hash_alloc(void *p)
916 {
917 struct attr *val = (struct attr *)p;
918 struct attr *attr;
919
920 attr = XMALLOC(MTYPE_ATTR, sizeof(struct attr));
921 *attr = *val;
922 if (val->encap_subtlvs) {
923 val->encap_subtlvs = NULL;
924 }
925 #ifdef ENABLE_BGP_VNC
926 struct bgp_attr_encap_subtlv *vnc_subtlvs =
927 bgp_attr_get_vnc_subtlvs(val);
928
929 if (vnc_subtlvs)
930 bgp_attr_set_vnc_subtlvs(val, NULL);
931 #endif
932
933 attr->refcnt = 0;
934 return attr;
935 }
936
937 /* Internet argument attribute. */
938 struct attr *bgp_attr_intern(struct attr *attr)
939 {
940 struct attr *find;
941 struct ecommunity *ecomm = NULL;
942 struct ecommunity *ipv6_ecomm = NULL;
943 struct lcommunity *lcomm = NULL;
944 struct community *comm = NULL;
945
946 /* Intern referenced structure. */
947 if (attr->aspath) {
948 if (!attr->aspath->refcnt)
949 attr->aspath = aspath_intern(attr->aspath);
950 else
951 attr->aspath->refcnt++;
952 }
953
954 comm = bgp_attr_get_community(attr);
955 if (comm) {
956 if (!comm->refcnt)
957 bgp_attr_set_community(attr, community_intern(comm));
958 else
959 comm->refcnt++;
960 }
961
962 ecomm = bgp_attr_get_ecommunity(attr);
963 if (ecomm) {
964 if (!ecomm->refcnt)
965 bgp_attr_set_ecommunity(attr, ecommunity_intern(ecomm));
966 else
967 ecomm->refcnt++;
968 }
969
970 ipv6_ecomm = bgp_attr_get_ipv6_ecommunity(attr);
971 if (ipv6_ecomm) {
972 if (!ipv6_ecomm->refcnt)
973 bgp_attr_set_ipv6_ecommunity(
974 attr, ecommunity_intern(ipv6_ecomm));
975 else
976 ipv6_ecomm->refcnt++;
977 }
978
979 lcomm = bgp_attr_get_lcommunity(attr);
980 if (lcomm) {
981 if (!lcomm->refcnt)
982 bgp_attr_set_lcommunity(attr, lcommunity_intern(lcomm));
983 else
984 lcomm->refcnt++;
985 }
986
987 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
988
989 if (cluster) {
990 if (!cluster->refcnt)
991 bgp_attr_set_cluster(attr, cluster_intern(cluster));
992 else
993 cluster->refcnt++;
994 }
995
996 struct transit *transit = bgp_attr_get_transit(attr);
997
998 if (transit) {
999 if (!transit->refcnt)
1000 bgp_attr_set_transit(attr, transit_intern(transit));
1001 else
1002 transit->refcnt++;
1003 }
1004 if (attr->encap_subtlvs) {
1005 if (!attr->encap_subtlvs->refcnt)
1006 attr->encap_subtlvs = encap_intern(attr->encap_subtlvs,
1007 ENCAP_SUBTLV_TYPE);
1008 else
1009 attr->encap_subtlvs->refcnt++;
1010 }
1011 if (attr->srv6_l3vpn) {
1012 if (!attr->srv6_l3vpn->refcnt)
1013 attr->srv6_l3vpn = srv6_l3vpn_intern(attr->srv6_l3vpn);
1014 else
1015 attr->srv6_l3vpn->refcnt++;
1016 }
1017 if (attr->srv6_vpn) {
1018 if (!attr->srv6_vpn->refcnt)
1019 attr->srv6_vpn = srv6_vpn_intern(attr->srv6_vpn);
1020 else
1021 attr->srv6_vpn->refcnt++;
1022 }
1023 #ifdef ENABLE_BGP_VNC
1024 struct bgp_attr_encap_subtlv *vnc_subtlvs =
1025 bgp_attr_get_vnc_subtlvs(attr);
1026
1027 if (vnc_subtlvs) {
1028 if (!vnc_subtlvs->refcnt)
1029 bgp_attr_set_vnc_subtlvs(
1030 attr,
1031 encap_intern(vnc_subtlvs, VNC_SUBTLV_TYPE));
1032 else
1033 vnc_subtlvs->refcnt++;
1034 }
1035 #endif
1036
1037 /* At this point, attr only contains intern'd pointers. that means
1038 * if we find it in attrhash, it has all the same pointers and we
1039 * correctly updated the refcounts on these.
1040 * If we don't find it, we need to allocate a one because in all
1041 * cases this returns a new reference to a hashed attr, but the input
1042 * wasn't on hash. */
1043 find = (struct attr *)hash_get(attrhash, attr, bgp_attr_hash_alloc);
1044 find->refcnt++;
1045
1046 return find;
1047 }
1048
1049 /* Make network statement's attribute. */
1050 struct attr *bgp_attr_default_set(struct attr *attr, struct bgp *bgp,
1051 uint8_t origin)
1052 {
1053 memset(attr, 0, sizeof(struct attr));
1054
1055 attr->origin = origin;
1056 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_ORIGIN);
1057 attr->aspath = aspath_empty();
1058 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AS_PATH);
1059 attr->weight = BGP_ATTR_DEFAULT_WEIGHT;
1060 attr->tag = 0;
1061 attr->label_index = BGP_INVALID_LABEL_INDEX;
1062 attr->label = MPLS_INVALID_LABEL;
1063 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
1064 attr->mp_nexthop_len = IPV6_MAX_BYTELEN;
1065 attr->local_pref = bgp->default_local_pref;
1066
1067 return attr;
1068 }
1069
1070 /* Create the attributes for an aggregate */
1071 struct attr *bgp_attr_aggregate_intern(
1072 struct bgp *bgp, uint8_t origin, struct aspath *aspath,
1073 struct community *community, struct ecommunity *ecommunity,
1074 struct lcommunity *lcommunity, struct bgp_aggregate *aggregate,
1075 uint8_t atomic_aggregate, const struct prefix *p)
1076 {
1077 struct attr attr;
1078 struct attr *new;
1079 route_map_result_t ret;
1080
1081 memset(&attr, 0, sizeof(attr));
1082
1083 /* Origin attribute. */
1084 attr.origin = origin;
1085 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ORIGIN);
1086
1087 /* MED */
1088 attr.med = 0;
1089 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
1090
1091 /* AS path attribute. */
1092 if (aspath)
1093 attr.aspath = aspath_intern(aspath);
1094 else
1095 attr.aspath = aspath_empty();
1096 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_AS_PATH);
1097
1098 /* Next hop attribute. */
1099 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
1100
1101 if (community) {
1102 uint32_t gshut = COMMUNITY_GSHUT;
1103
1104 /* If we are not shutting down ourselves and we are
1105 * aggregating a route that contains the GSHUT community we
1106 * need to remove that community when creating the aggregate */
1107 if (!bgp_in_graceful_shutdown(bgp)
1108 && community_include(community, gshut)) {
1109 community_del_val(community, &gshut);
1110 }
1111
1112 bgp_attr_set_community(&attr, community);
1113 }
1114
1115 if (ecommunity)
1116 bgp_attr_set_ecommunity(&attr, ecommunity);
1117
1118 if (lcommunity)
1119 bgp_attr_set_lcommunity(&attr, lcommunity);
1120
1121 if (bgp_in_graceful_shutdown(bgp))
1122 bgp_attr_add_gshut_community(&attr);
1123
1124 attr.label_index = BGP_INVALID_LABEL_INDEX;
1125 attr.label = MPLS_INVALID_LABEL;
1126 attr.weight = BGP_ATTR_DEFAULT_WEIGHT;
1127 attr.mp_nexthop_len = IPV6_MAX_BYTELEN;
1128 if (!aggregate->as_set || atomic_aggregate)
1129 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
1130 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR);
1131 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
1132 attr.aggregator_as = bgp->confed_id;
1133 else
1134 attr.aggregator_as = bgp->as;
1135 attr.aggregator_addr = bgp->router_id;
1136
1137 /* Apply route-map */
1138 if (aggregate->rmap.name) {
1139 struct attr attr_tmp = attr;
1140 struct bgp_path_info rmap_path;
1141
1142 memset(&rmap_path, 0, sizeof(rmap_path));
1143 rmap_path.peer = bgp->peer_self;
1144 rmap_path.attr = &attr_tmp;
1145
1146 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
1147
1148 ret = route_map_apply(aggregate->rmap.map, p, &rmap_path);
1149
1150 bgp->peer_self->rmap_type = 0;
1151
1152 if (ret == RMAP_DENYMATCH) {
1153 /* Free uninterned attribute. */
1154 bgp_attr_flush(&attr_tmp);
1155
1156 /* Unintern original. */
1157 aspath_unintern(&attr.aspath);
1158 return NULL;
1159 }
1160
1161 if (bgp_in_graceful_shutdown(bgp))
1162 bgp_attr_add_gshut_community(&attr_tmp);
1163
1164 new = bgp_attr_intern(&attr_tmp);
1165 } else {
1166
1167 if (bgp_in_graceful_shutdown(bgp))
1168 bgp_attr_add_gshut_community(&attr);
1169
1170 new = bgp_attr_intern(&attr);
1171 }
1172
1173 /* Always release the 'intern()'ed AS Path. */
1174 aspath_unintern(&attr.aspath);
1175
1176 return new;
1177 }
1178
1179 /* Unintern just the sub-components of the attr, but not the attr */
1180 void bgp_attr_unintern_sub(struct attr *attr)
1181 {
1182 struct ecommunity *ecomm = NULL;
1183 struct ecommunity *ipv6_ecomm = NULL;
1184 struct cluster_list *cluster;
1185 struct lcommunity *lcomm = NULL;
1186 struct community *comm = NULL;
1187
1188 /* aspath refcount shoud be decrement. */
1189 aspath_unintern(&attr->aspath);
1190 UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AS_PATH));
1191
1192 comm = bgp_attr_get_community(attr);
1193 community_unintern(&comm);
1194 bgp_attr_set_community(attr, NULL);
1195
1196 ecomm = bgp_attr_get_ecommunity(attr);
1197 ecommunity_unintern(&ecomm);
1198 bgp_attr_set_ecommunity(attr, NULL);
1199
1200 ipv6_ecomm = bgp_attr_get_ipv6_ecommunity(attr);
1201 ecommunity_unintern(&ipv6_ecomm);
1202 bgp_attr_set_ipv6_ecommunity(attr, NULL);
1203
1204 lcomm = bgp_attr_get_lcommunity(attr);
1205 lcommunity_unintern(&lcomm);
1206 bgp_attr_set_lcommunity(attr, NULL);
1207
1208 cluster = bgp_attr_get_cluster(attr);
1209 if (cluster) {
1210 cluster_unintern(&cluster);
1211 bgp_attr_set_cluster(attr, cluster);
1212 }
1213 UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST));
1214
1215 struct transit *transit = bgp_attr_get_transit(attr);
1216
1217 if (transit) {
1218 transit_unintern(&transit);
1219 bgp_attr_set_transit(attr, transit);
1220 }
1221
1222 if (attr->encap_subtlvs)
1223 encap_unintern(&attr->encap_subtlvs, ENCAP_SUBTLV_TYPE);
1224
1225 #ifdef ENABLE_BGP_VNC
1226 struct bgp_attr_encap_subtlv *vnc_subtlvs =
1227 bgp_attr_get_vnc_subtlvs(attr);
1228
1229 if (vnc_subtlvs) {
1230 encap_unintern(&vnc_subtlvs, VNC_SUBTLV_TYPE);
1231 bgp_attr_set_vnc_subtlvs(attr, vnc_subtlvs);
1232 }
1233 #endif
1234
1235 if (attr->srv6_l3vpn)
1236 srv6_l3vpn_unintern(&attr->srv6_l3vpn);
1237
1238 if (attr->srv6_vpn)
1239 srv6_vpn_unintern(&attr->srv6_vpn);
1240 }
1241
1242 /* Free bgp attribute and aspath. */
1243 void bgp_attr_unintern(struct attr **pattr)
1244 {
1245 struct attr *attr = *pattr;
1246 struct attr *ret;
1247 struct attr tmp;
1248
1249 /* Decrement attribute reference. */
1250 attr->refcnt--;
1251
1252 tmp = *attr;
1253
1254 /* If reference becomes zero then free attribute object. */
1255 if (attr->refcnt == 0) {
1256 ret = hash_release(attrhash, attr);
1257 assert(ret != NULL);
1258 XFREE(MTYPE_ATTR, attr);
1259 *pattr = NULL;
1260 }
1261
1262 bgp_attr_unintern_sub(&tmp);
1263 }
1264
1265 void bgp_attr_flush(struct attr *attr)
1266 {
1267 struct ecommunity *ecomm;
1268 struct ecommunity *ipv6_ecomm;
1269 struct cluster_list *cluster;
1270 struct lcommunity *lcomm;
1271 struct community *comm;
1272
1273 if (attr->aspath && !attr->aspath->refcnt) {
1274 aspath_free(attr->aspath);
1275 attr->aspath = NULL;
1276 }
1277 comm = bgp_attr_get_community(attr);
1278 if (comm && !comm->refcnt)
1279 community_free(&comm);
1280 bgp_attr_set_community(attr, NULL);
1281
1282 ecomm = bgp_attr_get_ecommunity(attr);
1283 if (ecomm && !ecomm->refcnt)
1284 ecommunity_free(&ecomm);
1285 bgp_attr_set_ecommunity(attr, NULL);
1286
1287 ipv6_ecomm = bgp_attr_get_ipv6_ecommunity(attr);
1288 if (ipv6_ecomm && !ipv6_ecomm->refcnt)
1289 ecommunity_free(&ipv6_ecomm);
1290 bgp_attr_set_ipv6_ecommunity(attr, NULL);
1291
1292 lcomm = bgp_attr_get_lcommunity(attr);
1293 if (lcomm && !lcomm->refcnt)
1294 lcommunity_free(&lcomm);
1295 bgp_attr_set_lcommunity(attr, NULL);
1296
1297 cluster = bgp_attr_get_cluster(attr);
1298 if (cluster && !cluster->refcnt) {
1299 cluster_free(cluster);
1300 bgp_attr_set_cluster(attr, NULL);
1301 }
1302
1303 struct transit *transit = bgp_attr_get_transit(attr);
1304
1305 if (transit && !transit->refcnt) {
1306 transit_free(transit);
1307 bgp_attr_set_transit(attr, NULL);
1308 }
1309 if (attr->encap_subtlvs && !attr->encap_subtlvs->refcnt) {
1310 encap_free(attr->encap_subtlvs);
1311 attr->encap_subtlvs = NULL;
1312 }
1313 if (attr->srv6_l3vpn && !attr->srv6_l3vpn->refcnt) {
1314 srv6_l3vpn_free(attr->srv6_l3vpn);
1315 attr->srv6_l3vpn = NULL;
1316 }
1317 if (attr->srv6_vpn && !attr->srv6_vpn->refcnt) {
1318 srv6_vpn_free(attr->srv6_vpn);
1319 attr->srv6_vpn = NULL;
1320 }
1321 #ifdef ENABLE_BGP_VNC
1322 struct bgp_attr_encap_subtlv *vnc_subtlvs =
1323 bgp_attr_get_vnc_subtlvs(attr);
1324
1325 if (vnc_subtlvs && !vnc_subtlvs->refcnt) {
1326 encap_free(vnc_subtlvs);
1327 bgp_attr_set_vnc_subtlvs(attr, NULL);
1328 }
1329 #endif
1330 }
1331
1332 /* Implement draft-scudder-idr-optional-transitive behaviour and
1333 * avoid resetting sessions for malformed attributes which are
1334 * are partial/optional and hence where the error likely was not
1335 * introduced by the sending neighbour.
1336 */
1337 static enum bgp_attr_parse_ret
1338 bgp_attr_malformed(struct bgp_attr_parser_args *args, uint8_t subcode,
1339 bgp_size_t length)
1340 {
1341 struct peer *const peer = args->peer;
1342 struct attr *const attr = args->attr;
1343 const uint8_t flags = args->flags;
1344 /* startp and length must be special-cased, as whether or not to
1345 * send the attribute data with the NOTIFY depends on the error,
1346 * the caller therefore signals this with the seperate length argument
1347 */
1348 uint8_t *notify_datap = (length > 0 ? args->startp : NULL);
1349
1350 if (bgp_debug_update(peer, NULL, NULL, 1)) {
1351 char attr_str[BUFSIZ] = {0};
1352
1353 bgp_dump_attr(attr, attr_str, sizeof(attr_str));
1354
1355 zlog_debug("%s: attributes: %s", __func__, attr_str);
1356 }
1357
1358 /* Only relax error handling for eBGP peers */
1359 if (peer->sort != BGP_PEER_EBGP) {
1360 bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR, subcode,
1361 notify_datap, length);
1362 return BGP_ATTR_PARSE_ERROR;
1363 }
1364
1365 /* Adjust the stream getp to the end of the attribute, in case we can
1366 * still proceed but the caller hasn't read all the attribute.
1367 */
1368 stream_set_getp(BGP_INPUT(peer),
1369 (args->startp - STREAM_DATA(BGP_INPUT(peer)))
1370 + args->total);
1371
1372 switch (args->type) {
1373 /* where an attribute is relatively inconsequential, e.g. it does not
1374 * affect route selection, and can be safely ignored, then any such
1375 * attributes which are malformed should just be ignored and the route
1376 * processed as normal.
1377 */
1378 case BGP_ATTR_AS4_AGGREGATOR:
1379 case BGP_ATTR_AGGREGATOR:
1380 case BGP_ATTR_ATOMIC_AGGREGATE:
1381 return BGP_ATTR_PARSE_PROCEED;
1382
1383 /* Core attributes, particularly ones which may influence route
1384 * selection, should be treat-as-withdraw.
1385 */
1386 case BGP_ATTR_ORIGIN:
1387 case BGP_ATTR_AS_PATH:
1388 case BGP_ATTR_NEXT_HOP:
1389 case BGP_ATTR_MULTI_EXIT_DISC:
1390 case BGP_ATTR_LOCAL_PREF:
1391 case BGP_ATTR_COMMUNITIES:
1392 case BGP_ATTR_EXT_COMMUNITIES:
1393 case BGP_ATTR_IPV6_EXT_COMMUNITIES:
1394 case BGP_ATTR_LARGE_COMMUNITIES:
1395 case BGP_ATTR_ORIGINATOR_ID:
1396 case BGP_ATTR_CLUSTER_LIST:
1397 case BGP_ATTR_OTC:
1398 return BGP_ATTR_PARSE_WITHDRAW;
1399 case BGP_ATTR_MP_REACH_NLRI:
1400 case BGP_ATTR_MP_UNREACH_NLRI:
1401 bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR, subcode,
1402 notify_datap, length);
1403 return BGP_ATTR_PARSE_ERROR;
1404 }
1405
1406 /* Partial optional attributes that are malformed should not cause
1407 * the whole session to be reset. Instead treat it as a withdrawal
1408 * of the routes, if possible.
1409 */
1410 if (CHECK_FLAG(flags, BGP_ATTR_FLAG_TRANS)
1411 && CHECK_FLAG(flags, BGP_ATTR_FLAG_OPTIONAL)
1412 && CHECK_FLAG(flags, BGP_ATTR_FLAG_PARTIAL))
1413 return BGP_ATTR_PARSE_WITHDRAW;
1414
1415 /* default to reset */
1416 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
1417 }
1418
1419 /* Find out what is wrong with the path attribute flag bits and log the error.
1420 "Flag bits" here stand for Optional, Transitive and Partial, but not for
1421 Extended Length. Checking O/T/P bits at once implies, that the attribute
1422 being diagnosed is defined by RFC as either a "well-known" or an "optional,
1423 non-transitive" attribute. */
1424 static void
1425 bgp_attr_flags_diagnose(struct bgp_attr_parser_args *args,
1426 uint8_t desired_flags /* how RFC says it must be */
1427 )
1428 {
1429 uint8_t seen = 0, i;
1430 uint8_t real_flags = args->flags;
1431 const uint8_t attr_code = args->type;
1432
1433 desired_flags &= ~BGP_ATTR_FLAG_EXTLEN;
1434 real_flags &= ~BGP_ATTR_FLAG_EXTLEN;
1435 for (i = 0; i <= 2; i++) /* O,T,P, but not E */
1436 if (CHECK_FLAG(desired_flags, attr_flag_str[i].key)
1437 != CHECK_FLAG(real_flags, attr_flag_str[i].key)) {
1438 flog_err(EC_BGP_ATTR_FLAG,
1439 "%s attribute must%s be flagged as \"%s\"",
1440 lookup_msg(attr_str, attr_code, NULL),
1441 CHECK_FLAG(desired_flags, attr_flag_str[i].key)
1442 ? ""
1443 : " not",
1444 attr_flag_str[i].str);
1445 seen = 1;
1446 }
1447 if (!seen) {
1448 zlog_debug(
1449 "Strange, %s called for attr %s, but no problem found with flags (real flags 0x%x, desired 0x%x)",
1450 __func__, lookup_msg(attr_str, attr_code, NULL),
1451 real_flags, desired_flags);
1452 }
1453 }
1454
1455 /* Required flags for attributes. EXTLEN will be masked off when testing,
1456 * as will PARTIAL for optional+transitive attributes.
1457 */
1458 const uint8_t attr_flags_values[] = {
1459 [BGP_ATTR_ORIGIN] = BGP_ATTR_FLAG_TRANS,
1460 [BGP_ATTR_AS_PATH] = BGP_ATTR_FLAG_TRANS,
1461 [BGP_ATTR_NEXT_HOP] = BGP_ATTR_FLAG_TRANS,
1462 [BGP_ATTR_MULTI_EXIT_DISC] = BGP_ATTR_FLAG_OPTIONAL,
1463 [BGP_ATTR_LOCAL_PREF] = BGP_ATTR_FLAG_TRANS,
1464 [BGP_ATTR_ATOMIC_AGGREGATE] = BGP_ATTR_FLAG_TRANS,
1465 [BGP_ATTR_AGGREGATOR] = BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
1466 [BGP_ATTR_COMMUNITIES] = BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
1467 [BGP_ATTR_ORIGINATOR_ID] = BGP_ATTR_FLAG_OPTIONAL,
1468 [BGP_ATTR_CLUSTER_LIST] = BGP_ATTR_FLAG_OPTIONAL,
1469 [BGP_ATTR_MP_REACH_NLRI] = BGP_ATTR_FLAG_OPTIONAL,
1470 [BGP_ATTR_MP_UNREACH_NLRI] = BGP_ATTR_FLAG_OPTIONAL,
1471 [BGP_ATTR_EXT_COMMUNITIES] =
1472 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1473 [BGP_ATTR_AS4_PATH] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1474 [BGP_ATTR_AS4_AGGREGATOR] =
1475 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1476 [BGP_ATTR_PMSI_TUNNEL] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1477 [BGP_ATTR_LARGE_COMMUNITIES] =
1478 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1479 [BGP_ATTR_OTC] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1480 [BGP_ATTR_PREFIX_SID] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1481 [BGP_ATTR_IPV6_EXT_COMMUNITIES] =
1482 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1483 [BGP_ATTR_AIGP] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1484 };
1485 static const size_t attr_flags_values_max = array_size(attr_flags_values) - 1;
1486
1487 static bool bgp_attr_flag_invalid(struct bgp_attr_parser_args *args)
1488 {
1489 uint8_t mask = BGP_ATTR_FLAG_EXTLEN;
1490 const uint8_t flags = args->flags;
1491 const uint8_t attr_code = args->type;
1492
1493 /* there may be attributes we don't know about */
1494 if (attr_code > attr_flags_values_max)
1495 return false;
1496 if (attr_flags_values[attr_code] == 0)
1497 return false;
1498
1499 /* RFC4271, "For well-known attributes, the Transitive bit MUST be set
1500 * to
1501 * 1."
1502 */
1503 if (!CHECK_FLAG(BGP_ATTR_FLAG_OPTIONAL, flags)
1504 && !CHECK_FLAG(BGP_ATTR_FLAG_TRANS, flags)) {
1505 flog_err(
1506 EC_BGP_ATTR_FLAG,
1507 "%s well-known attributes must have transitive flag set (%x)",
1508 lookup_msg(attr_str, attr_code, NULL), flags);
1509 return true;
1510 }
1511
1512 /* "For well-known attributes and for optional non-transitive
1513 * attributes,
1514 * the Partial bit MUST be set to 0."
1515 */
1516 if (CHECK_FLAG(flags, BGP_ATTR_FLAG_PARTIAL)) {
1517 if (!CHECK_FLAG(flags, BGP_ATTR_FLAG_OPTIONAL)) {
1518 flog_err(EC_BGP_ATTR_FLAG,
1519 "%s well-known attribute must NOT have the partial flag set (%x)",
1520 lookup_msg(attr_str, attr_code, NULL), flags);
1521 return true;
1522 }
1523 if (CHECK_FLAG(flags, BGP_ATTR_FLAG_OPTIONAL)
1524 && !CHECK_FLAG(flags, BGP_ATTR_FLAG_TRANS)) {
1525 flog_err(EC_BGP_ATTR_FLAG,
1526 "%s optional + transitive attribute must NOT have the partial flag set (%x)",
1527 lookup_msg(attr_str, attr_code, NULL), flags);
1528 return true;
1529 }
1530 }
1531
1532 /* Optional transitive attributes may go through speakers that don't
1533 * reocgnise them and set the Partial bit.
1534 */
1535 if (CHECK_FLAG(flags, BGP_ATTR_FLAG_OPTIONAL)
1536 && CHECK_FLAG(flags, BGP_ATTR_FLAG_TRANS))
1537 SET_FLAG(mask, BGP_ATTR_FLAG_PARTIAL);
1538
1539 if ((flags & ~mask) == attr_flags_values[attr_code])
1540 return false;
1541
1542 bgp_attr_flags_diagnose(args, attr_flags_values[attr_code]);
1543 return true;
1544 }
1545
1546 /* Get origin attribute of the update message. */
1547 static enum bgp_attr_parse_ret
1548 bgp_attr_origin(struct bgp_attr_parser_args *args)
1549 {
1550 struct peer *const peer = args->peer;
1551 struct attr *const attr = args->attr;
1552 const bgp_size_t length = args->length;
1553
1554 /* If any recognized attribute has Attribute Length that conflicts
1555 with the expected length (based on the attribute type code), then
1556 the Error Subcode is set to Attribute Length Error. The Data
1557 field contains the erroneous attribute (type, length and
1558 value). */
1559 if (length != 1) {
1560 flog_err(EC_BGP_ATTR_LEN,
1561 "Origin attribute length is not one %d", length);
1562 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1563 args->total);
1564 }
1565
1566 /* Fetch origin attribute. */
1567 attr->origin = stream_getc(BGP_INPUT(peer));
1568
1569 /* If the ORIGIN attribute has an undefined value, then the Error
1570 Subcode is set to Invalid Origin Attribute. The Data field
1571 contains the unrecognized attribute (type, length and value). */
1572 if ((attr->origin != BGP_ORIGIN_IGP) && (attr->origin != BGP_ORIGIN_EGP)
1573 && (attr->origin != BGP_ORIGIN_INCOMPLETE)) {
1574 flog_err(EC_BGP_ATTR_ORIGIN,
1575 "Origin attribute value is invalid %d", attr->origin);
1576 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_INVAL_ORIGIN,
1577 args->total);
1578 }
1579
1580 /* Set oring attribute flag. */
1581 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_ORIGIN);
1582
1583 return 0;
1584 }
1585
1586 /* Parse AS path information. This function is wrapper of
1587 aspath_parse. */
1588 static int bgp_attr_aspath(struct bgp_attr_parser_args *args)
1589 {
1590 struct attr *const attr = args->attr;
1591 struct peer *const peer = args->peer;
1592 const bgp_size_t length = args->length;
1593
1594 /*
1595 * peer with AS4 => will get 4Byte ASnums
1596 * otherwise, will get 16 Bit
1597 */
1598 attr->aspath = aspath_parse(
1599 peer->curr, length,
1600 CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)
1601 && CHECK_FLAG(peer->cap, PEER_CAP_AS4_ADV));
1602
1603 /* In case of IBGP, length will be zero. */
1604 if (!attr->aspath) {
1605 flog_err(EC_BGP_ATTR_MAL_AS_PATH,
1606 "Malformed AS path from %s, length is %d", peer->host,
1607 length);
1608 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_MAL_AS_PATH,
1609 0);
1610 }
1611
1612 /* Conformant BGP speakers SHOULD NOT send BGP
1613 * UPDATE messages containing AS_SET or AS_CONFED_SET. Upon receipt of
1614 * such messages, conformant BGP speakers SHOULD use the "Treat-as-
1615 * withdraw" error handling behavior as per [RFC7606].
1616 */
1617 if (peer->bgp->reject_as_sets && aspath_check_as_sets(attr->aspath)) {
1618 flog_err(EC_BGP_ATTR_MAL_AS_PATH,
1619 "AS_SET and AS_CONFED_SET are deprecated from %pBP",
1620 peer);
1621 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_MAL_AS_PATH,
1622 0);
1623 }
1624
1625 /* Set aspath attribute flag. */
1626 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AS_PATH);
1627
1628 return BGP_ATTR_PARSE_PROCEED;
1629 }
1630
1631 static enum bgp_attr_parse_ret bgp_attr_aspath_check(struct peer *const peer,
1632 struct attr *const attr)
1633 {
1634 /* These checks were part of bgp_attr_aspath, but with
1635 * as4 we should to check aspath things when
1636 * aspath synthesizing with as4_path has already taken place.
1637 * Otherwise we check ASPATH and use the synthesized thing, and that is
1638 * not right.
1639 * So do the checks later, i.e. here
1640 */
1641 struct aspath *aspath;
1642
1643 /* Confederation sanity check. */
1644 if ((peer->sort == BGP_PEER_CONFED
1645 && !aspath_left_confed_check(attr->aspath))
1646 || (peer->sort == BGP_PEER_EBGP
1647 && aspath_confed_check(attr->aspath))) {
1648 flog_err(EC_BGP_ATTR_MAL_AS_PATH, "Malformed AS path from %s",
1649 peer->host);
1650 return BGP_ATTR_PARSE_WITHDRAW;
1651 }
1652
1653 /* First AS check for EBGP. */
1654 if (CHECK_FLAG(peer->flags, PEER_FLAG_ENFORCE_FIRST_AS)) {
1655 if (peer->sort == BGP_PEER_EBGP
1656 && !aspath_firstas_check(attr->aspath, peer->as)) {
1657 flog_err(EC_BGP_ATTR_FIRST_AS,
1658 "%s incorrect first AS (must be %u)",
1659 peer->host, peer->as);
1660 return BGP_ATTR_PARSE_WITHDRAW;
1661 }
1662 }
1663
1664 /* Codification of AS 0 Processing */
1665 if (peer->sort == BGP_PEER_EBGP && aspath_check_as_zero(attr->aspath)) {
1666 flog_err(
1667 EC_BGP_ATTR_MAL_AS_PATH,
1668 "Malformed AS path, AS number is 0 in the path from %s",
1669 peer->host);
1670 return BGP_ATTR_PARSE_WITHDRAW;
1671 }
1672
1673 /* local-as prepend */
1674 if (peer->change_local_as
1675 && !CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND)) {
1676 aspath = aspath_dup(attr->aspath);
1677 aspath = aspath_add_seq(aspath, peer->change_local_as);
1678 aspath_unintern(&attr->aspath);
1679 attr->aspath = aspath_intern(aspath);
1680 }
1681
1682 return BGP_ATTR_PARSE_PROCEED;
1683 }
1684
1685 /* Parse AS4 path information. This function is another wrapper of
1686 aspath_parse. */
1687 static int bgp_attr_as4_path(struct bgp_attr_parser_args *args,
1688 struct aspath **as4_path)
1689 {
1690 struct peer *const peer = args->peer;
1691 struct attr *const attr = args->attr;
1692 const bgp_size_t length = args->length;
1693
1694 *as4_path = aspath_parse(peer->curr, length, 1);
1695
1696 /* In case of IBGP, length will be zero. */
1697 if (!*as4_path) {
1698 flog_err(EC_BGP_ATTR_MAL_AS_PATH,
1699 "Malformed AS4 path from %s, length is %d", peer->host,
1700 length);
1701 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_MAL_AS_PATH,
1702 0);
1703 }
1704
1705 /* Conformant BGP speakers SHOULD NOT send BGP
1706 * UPDATE messages containing AS_SET or AS_CONFED_SET. Upon receipt of
1707 * such messages, conformant BGP speakers SHOULD use the "Treat-as-
1708 * withdraw" error handling behavior as per [RFC7606].
1709 */
1710 if (peer->bgp->reject_as_sets && aspath_check_as_sets(attr->aspath)) {
1711 flog_err(EC_BGP_ATTR_MAL_AS_PATH,
1712 "AS_SET and AS_CONFED_SET are deprecated from %pBP",
1713 peer);
1714 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_MAL_AS_PATH,
1715 0);
1716 }
1717
1718 /* Set aspath attribute flag. */
1719 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AS4_PATH);
1720
1721 return BGP_ATTR_PARSE_PROCEED;
1722 }
1723
1724 /*
1725 * Check that the nexthop attribute is valid.
1726 */
1727 enum bgp_attr_parse_ret bgp_attr_nexthop_valid(struct peer *peer,
1728 struct attr *attr)
1729 {
1730 struct bgp *bgp = peer->bgp;
1731
1732 if (ipv4_martian(&attr->nexthop) && !bgp->allow_martian) {
1733 uint8_t data[7]; /* type(2) + length(1) + nhop(4) */
1734
1735 flog_err(EC_BGP_ATTR_MARTIAN_NH, "Martian nexthop %pI4",
1736 &attr->nexthop);
1737 data[0] = BGP_ATTR_FLAG_TRANS;
1738 data[1] = BGP_ATTR_NEXT_HOP;
1739 data[2] = BGP_ATTR_NHLEN_IPV4;
1740 memcpy(&data[3], &attr->nexthop.s_addr, BGP_ATTR_NHLEN_IPV4);
1741 bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR,
1742 BGP_NOTIFY_UPDATE_INVAL_NEXT_HOP,
1743 data, 7);
1744 return BGP_ATTR_PARSE_ERROR;
1745 }
1746
1747 return BGP_ATTR_PARSE_PROCEED;
1748 }
1749
1750 /* Nexthop attribute. */
1751 static enum bgp_attr_parse_ret
1752 bgp_attr_nexthop(struct bgp_attr_parser_args *args)
1753 {
1754 struct peer *const peer = args->peer;
1755 struct attr *const attr = args->attr;
1756 const bgp_size_t length = args->length;
1757
1758 /* Check nexthop attribute length. */
1759 if (length != 4) {
1760 flog_err(EC_BGP_ATTR_LEN,
1761 "Nexthop attribute length isn't four [%d]", length);
1762
1763 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1764 args->total);
1765 }
1766
1767 attr->nexthop.s_addr = stream_get_ipv4(peer->curr);
1768 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
1769
1770 return BGP_ATTR_PARSE_PROCEED;
1771 }
1772
1773 /* MED atrribute. */
1774 static enum bgp_attr_parse_ret bgp_attr_med(struct bgp_attr_parser_args *args)
1775 {
1776 struct peer *const peer = args->peer;
1777 struct attr *const attr = args->attr;
1778 const bgp_size_t length = args->length;
1779
1780 /* Length check. */
1781 if (length != 4) {
1782 flog_err(EC_BGP_ATTR_LEN,
1783 "MED attribute length isn't four [%d]", length);
1784
1785 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1786 args->total);
1787 }
1788
1789 attr->med = stream_getl(peer->curr);
1790
1791 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
1792
1793 return BGP_ATTR_PARSE_PROCEED;
1794 }
1795
1796 /* Local preference attribute. */
1797 static enum bgp_attr_parse_ret
1798 bgp_attr_local_pref(struct bgp_attr_parser_args *args)
1799 {
1800 struct peer *const peer = args->peer;
1801 struct attr *const attr = args->attr;
1802 const bgp_size_t length = args->length;
1803
1804 /* if received from an internal neighbor, it SHALL be considered
1805 * malformed if its length is not equal to 4. If malformed, the
1806 * UPDATE message SHALL be handled using the approach of "treat-as-
1807 * withdraw".
1808 */
1809 if (peer->sort == BGP_PEER_IBGP && length != 4) {
1810 flog_err(EC_BGP_ATTR_LEN,
1811 "LOCAL_PREF attribute length isn't 4 [%u]", length);
1812 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1813 args->total);
1814 }
1815
1816 /* If it is contained in an UPDATE message that is received from an
1817 external peer, then this attribute MUST be ignored by the
1818 receiving speaker. */
1819 if (peer->sort == BGP_PEER_EBGP) {
1820 STREAM_FORWARD_GETP(peer->curr, length);
1821 return BGP_ATTR_PARSE_PROCEED;
1822 }
1823
1824 STREAM_GETL(peer->curr, attr->local_pref);
1825
1826 /* Set the local-pref flag. */
1827 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1828
1829 return BGP_ATTR_PARSE_PROCEED;
1830
1831 stream_failure:
1832 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1833 args->total);
1834 }
1835
1836 /* Atomic aggregate. */
1837 static int bgp_attr_atomic(struct bgp_attr_parser_args *args)
1838 {
1839 struct peer *const peer = args->peer;
1840 struct attr *const attr = args->attr;
1841 const bgp_size_t length = args->length;
1842
1843 /* Length check. */
1844 if (length != 0) {
1845 flog_err(EC_BGP_ATTR_LEN,
1846 "ATOMIC_AGGREGATE attribute length isn't 0 [%u]",
1847 length);
1848 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1849 args->total);
1850 }
1851
1852 if (peer->discard_attrs[args->type] || peer->withdraw_attrs[args->type])
1853 goto atomic_ignore;
1854
1855 /* Set atomic aggregate flag. */
1856 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
1857
1858 return BGP_ATTR_PARSE_PROCEED;
1859
1860 atomic_ignore:
1861 stream_forward_getp(peer->curr, length);
1862
1863 return bgp_attr_ignore(peer, args->type);
1864 }
1865
1866 /* Aggregator attribute */
1867 static int bgp_attr_aggregator(struct bgp_attr_parser_args *args)
1868 {
1869 struct peer *const peer = args->peer;
1870 struct attr *const attr = args->attr;
1871 const bgp_size_t length = args->length;
1872 as_t aggregator_as;
1873
1874 int wantedlen = 6;
1875
1876 /* peer with AS4 will send 4 Byte AS, peer without will send 2 Byte */
1877 if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)
1878 && CHECK_FLAG(peer->cap, PEER_CAP_AS4_ADV))
1879 wantedlen = 8;
1880
1881 if (length != wantedlen) {
1882 flog_err(EC_BGP_ATTR_LEN,
1883 "AGGREGATOR attribute length isn't %u [%u]", wantedlen,
1884 length);
1885 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1886 args->total);
1887 }
1888
1889 if (peer->discard_attrs[args->type] || peer->withdraw_attrs[args->type])
1890 goto aggregator_ignore;
1891
1892 if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV))
1893 aggregator_as = stream_getl(peer->curr);
1894 else
1895 aggregator_as = stream_getw(peer->curr);
1896
1897 attr->aggregator_as = aggregator_as;
1898 attr->aggregator_addr.s_addr = stream_get_ipv4(peer->curr);
1899
1900 /* Codification of AS 0 Processing */
1901 if (aggregator_as == BGP_AS_ZERO) {
1902 flog_err(EC_BGP_ATTR_LEN,
1903 "%s: AGGREGATOR AS number is 0 for aspath: %s",
1904 peer->host, aspath_print(attr->aspath));
1905
1906 if (bgp_debug_update(peer, NULL, NULL, 1)) {
1907 char attr_str[BUFSIZ] = {0};
1908
1909 bgp_dump_attr(attr, attr_str, sizeof(attr_str));
1910
1911 zlog_debug("%s: attributes: %s", __func__, attr_str);
1912 }
1913 } else {
1914 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR);
1915 }
1916
1917 return BGP_ATTR_PARSE_PROCEED;
1918
1919 aggregator_ignore:
1920 stream_forward_getp(peer->curr, length);
1921
1922 return bgp_attr_ignore(peer, args->type);
1923 }
1924
1925 /* New Aggregator attribute */
1926 static enum bgp_attr_parse_ret
1927 bgp_attr_as4_aggregator(struct bgp_attr_parser_args *args,
1928 as_t *as4_aggregator_as,
1929 struct in_addr *as4_aggregator_addr)
1930 {
1931 struct peer *const peer = args->peer;
1932 struct attr *const attr = args->attr;
1933 const bgp_size_t length = args->length;
1934 as_t aggregator_as;
1935
1936 if (length != 8) {
1937 flog_err(EC_BGP_ATTR_LEN, "New Aggregator length is not 8 [%d]",
1938 length);
1939 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1940 0);
1941 }
1942
1943 if (peer->discard_attrs[args->type] || peer->withdraw_attrs[args->type])
1944 goto as4_aggregator_ignore;
1945
1946 aggregator_as = stream_getl(peer->curr);
1947
1948 *as4_aggregator_as = aggregator_as;
1949 as4_aggregator_addr->s_addr = stream_get_ipv4(peer->curr);
1950
1951 /* Codification of AS 0 Processing */
1952 if (aggregator_as == BGP_AS_ZERO) {
1953 flog_err(EC_BGP_ATTR_LEN,
1954 "%s: AS4_AGGREGATOR AS number is 0 for aspath: %s",
1955 peer->host, aspath_print(attr->aspath));
1956
1957 if (bgp_debug_update(peer, NULL, NULL, 1)) {
1958 char attr_str[BUFSIZ] = {0};
1959
1960 bgp_dump_attr(attr, attr_str, sizeof(attr_str));
1961
1962 zlog_debug("%s: attributes: %s", __func__, attr_str);
1963 }
1964 } else {
1965 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AS4_AGGREGATOR);
1966 }
1967
1968 return BGP_ATTR_PARSE_PROCEED;
1969
1970 as4_aggregator_ignore:
1971 stream_forward_getp(peer->curr, length);
1972
1973 return bgp_attr_ignore(peer, args->type);
1974 }
1975
1976 /* Munge Aggregator and New-Aggregator, AS_PATH and NEW_AS_PATH.
1977 */
1978 static enum bgp_attr_parse_ret
1979 bgp_attr_munge_as4_attrs(struct peer *const peer, struct attr *const attr,
1980 struct aspath *as4_path, as_t as4_aggregator,
1981 struct in_addr *as4_aggregator_addr)
1982 {
1983 int ignore_as4_path = 0;
1984 struct aspath *newpath;
1985
1986 if (!attr->aspath) {
1987 /* NULL aspath shouldn't be possible as bgp_attr_parse should
1988 * have
1989 * checked that all well-known, mandatory attributes were
1990 * present.
1991 *
1992 * Can only be a problem with peer itself - hard error
1993 */
1994 return BGP_ATTR_PARSE_ERROR;
1995 }
1996
1997 if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)) {
1998 /* peer can do AS4, so we ignore AS4_PATH and AS4_AGGREGATOR
1999 * if given.
2000 * It is worth a warning though, because the peer really
2001 * should not send them
2002 */
2003 if (BGP_DEBUG(as4, AS4)) {
2004 if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS4_PATH)))
2005 zlog_debug("[AS4] %s %s AS4_PATH", peer->host,
2006 "AS4 capable peer, yet it sent");
2007
2008 if (attr->flag
2009 & (ATTR_FLAG_BIT(BGP_ATTR_AS4_AGGREGATOR)))
2010 zlog_debug("[AS4] %s %s AS4_AGGREGATOR",
2011 peer->host,
2012 "AS4 capable peer, yet it sent");
2013 }
2014
2015 return BGP_ATTR_PARSE_PROCEED;
2016 }
2017
2018 /* We have a asn16 peer. First, look for AS4_AGGREGATOR
2019 * because that may override AS4_PATH
2020 */
2021 if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS4_AGGREGATOR))) {
2022 if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
2023 /* received both.
2024 * if the as_number in aggregator is not AS_TRANS,
2025 * then AS4_AGGREGATOR and AS4_PATH shall be ignored
2026 * and the Aggregator shall be taken as
2027 * info on the aggregating node, and the AS_PATH
2028 * shall be taken as the AS_PATH
2029 * otherwise
2030 * the Aggregator shall be ignored and the
2031 * AS4_AGGREGATOR shall be taken as the
2032 * Aggregating node and the AS_PATH is to be
2033 * constructed "as in all other cases"
2034 */
2035 if (attr->aggregator_as != BGP_AS_TRANS) {
2036 /* ignore */
2037 if (BGP_DEBUG(as4, AS4))
2038 zlog_debug(
2039 "[AS4] %s BGP not AS4 capable peer send AGGREGATOR != AS_TRANS and AS4_AGGREGATOR, so ignore AS4_AGGREGATOR and AS4_PATH",
2040 peer->host);
2041 ignore_as4_path = 1;
2042 } else {
2043 /* "New_aggregator shall be taken as aggregator"
2044 */
2045 attr->aggregator_as = as4_aggregator;
2046 attr->aggregator_addr.s_addr =
2047 as4_aggregator_addr->s_addr;
2048 }
2049 } else {
2050 /* We received a AS4_AGGREGATOR but no AGGREGATOR.
2051 * That is bogus - but reading the conditions
2052 * we have to handle AS4_AGGREGATOR as if it were
2053 * AGGREGATOR in that case
2054 */
2055 if (BGP_DEBUG(as4, AS4))
2056 zlog_debug(
2057 "[AS4] %s BGP not AS4 capable peer send AS4_AGGREGATOR but no AGGREGATOR, will take it as if AGGREGATOR with AS_TRANS had been there",
2058 peer->host);
2059 attr->aggregator_as = as4_aggregator;
2060 /* sweep it under the carpet and simulate a "good"
2061 * AGGREGATOR */
2062 attr->flag |= (ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR));
2063 }
2064 }
2065
2066 /* need to reconcile NEW_AS_PATH and AS_PATH */
2067 if (!ignore_as4_path
2068 && (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS4_PATH)))) {
2069 newpath = aspath_reconcile_as4(attr->aspath, as4_path);
2070 if (!newpath)
2071 return BGP_ATTR_PARSE_ERROR;
2072
2073 aspath_unintern(&attr->aspath);
2074 attr->aspath = aspath_intern(newpath);
2075 }
2076 return BGP_ATTR_PARSE_PROCEED;
2077 }
2078
2079 /* Community attribute. */
2080 static enum bgp_attr_parse_ret
2081 bgp_attr_community(struct bgp_attr_parser_args *args)
2082 {
2083 struct peer *const peer = args->peer;
2084 struct attr *const attr = args->attr;
2085 const bgp_size_t length = args->length;
2086
2087 if (length == 0) {
2088 bgp_attr_set_community(attr, NULL);
2089 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2090 args->total);
2091 }
2092
2093 if (peer->discard_attrs[args->type] || peer->withdraw_attrs[args->type])
2094 goto community_ignore;
2095
2096 bgp_attr_set_community(
2097 attr,
2098 community_parse((uint32_t *)stream_pnt(peer->curr), length));
2099
2100 /* XXX: fix community_parse to use stream API and remove this */
2101 stream_forward_getp(peer->curr, length);
2102
2103 /* The Community attribute SHALL be considered malformed if its
2104 * length is not a non-zero multiple of 4.
2105 */
2106 if (!bgp_attr_get_community(attr))
2107 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2108 args->total);
2109
2110 return BGP_ATTR_PARSE_PROCEED;
2111
2112 community_ignore:
2113 stream_forward_getp(peer->curr, length);
2114
2115 return bgp_attr_ignore(peer, args->type);
2116 }
2117
2118 /* Originator ID attribute. */
2119 static enum bgp_attr_parse_ret
2120 bgp_attr_originator_id(struct bgp_attr_parser_args *args)
2121 {
2122 struct peer *const peer = args->peer;
2123 struct attr *const attr = args->attr;
2124 const bgp_size_t length = args->length;
2125
2126 /* if received from an internal neighbor, it SHALL be considered
2127 * malformed if its length is not equal to 4. If malformed, the
2128 * UPDATE message SHALL be handled using the approach of "treat-as-
2129 * withdraw".
2130 */
2131 if (length != 4) {
2132 flog_err(EC_BGP_ATTR_LEN, "Bad originator ID length %d",
2133 length);
2134
2135 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2136 args->total);
2137 }
2138
2139 if (peer->discard_attrs[args->type] || peer->withdraw_attrs[args->type])
2140 goto originator_id_ignore;
2141
2142 attr->originator_id.s_addr = stream_get_ipv4(peer->curr);
2143
2144 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID);
2145
2146 return BGP_ATTR_PARSE_PROCEED;
2147
2148 originator_id_ignore:
2149 stream_forward_getp(peer->curr, length);
2150
2151 return bgp_attr_ignore(peer, args->type);
2152 }
2153
2154 /* Cluster list attribute. */
2155 static enum bgp_attr_parse_ret
2156 bgp_attr_cluster_list(struct bgp_attr_parser_args *args)
2157 {
2158 struct peer *const peer = args->peer;
2159 struct attr *const attr = args->attr;
2160 const bgp_size_t length = args->length;
2161
2162 /* if received from an internal neighbor, it SHALL be considered
2163 * malformed if its length is not a non-zero multiple of 4. If
2164 * malformed, the UPDATE message SHALL be handled using the approach
2165 * of "treat-as-withdraw".
2166 */
2167 if (length == 0 || length % 4) {
2168 flog_err(EC_BGP_ATTR_LEN, "Bad cluster list length %d", length);
2169
2170 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2171 args->total);
2172 }
2173
2174 if (peer->discard_attrs[args->type] || peer->withdraw_attrs[args->type])
2175 goto cluster_list_ignore;
2176
2177 bgp_attr_set_cluster(
2178 attr, cluster_parse((struct in_addr *)stream_pnt(peer->curr),
2179 length));
2180
2181 /* XXX: Fix cluster_parse to use stream API and then remove this */
2182 stream_forward_getp(peer->curr, length);
2183
2184 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST);
2185
2186 return BGP_ATTR_PARSE_PROCEED;
2187
2188 cluster_list_ignore:
2189 stream_forward_getp(peer->curr, length);
2190
2191 return bgp_attr_ignore(peer, args->type);
2192 }
2193
2194 /* Multiprotocol reachability information parse. */
2195 int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
2196 struct bgp_nlri *mp_update)
2197 {
2198 iana_afi_t pkt_afi;
2199 afi_t afi;
2200 iana_safi_t pkt_safi;
2201 safi_t safi;
2202 bgp_size_t nlri_len;
2203 size_t start;
2204 struct stream *s;
2205 struct peer *const peer = args->peer;
2206 struct attr *const attr = args->attr;
2207 const bgp_size_t length = args->length;
2208
2209 /* Set end of packet. */
2210 s = BGP_INPUT(peer);
2211 start = stream_get_getp(s);
2212
2213 /* safe to read statically sized header? */
2214 #define BGP_MP_REACH_MIN_SIZE 5
2215 #define LEN_LEFT (length - (stream_get_getp(s) - start))
2216 if ((length > STREAM_READABLE(s)) || (length < BGP_MP_REACH_MIN_SIZE)) {
2217 zlog_info("%s: %s sent invalid length, %lu, of MP_REACH_NLRI",
2218 __func__, peer->host, (unsigned long)length);
2219 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2220 }
2221
2222 /* Load AFI, SAFI. */
2223 pkt_afi = stream_getw(s);
2224 pkt_safi = stream_getc(s);
2225
2226 /* Convert AFI, SAFI to internal values, check. */
2227 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
2228 /* Log if AFI or SAFI is unrecognized. This is not an error
2229 * unless
2230 * the attribute is otherwise malformed.
2231 */
2232 if (bgp_debug_update(peer, NULL, NULL, 0))
2233 zlog_debug(
2234 "%s sent unrecognizable AFI, %s or, SAFI, %s, of MP_REACH_NLRI",
2235 peer->host, iana_afi2str(pkt_afi),
2236 iana_safi2str(pkt_safi));
2237 return BGP_ATTR_PARSE_ERROR;
2238 }
2239
2240 /* Get nexthop length. */
2241 attr->mp_nexthop_len = stream_getc(s);
2242
2243 if (LEN_LEFT < attr->mp_nexthop_len) {
2244 zlog_info(
2245 "%s: %s sent next-hop length, %u, in MP_REACH_NLRI which goes past the end of attribute",
2246 __func__, peer->host, attr->mp_nexthop_len);
2247 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2248 }
2249
2250 /* Nexthop length check. */
2251 switch (attr->mp_nexthop_len) {
2252 case 0:
2253 if (safi != SAFI_FLOWSPEC) {
2254 zlog_info("%s: %s sent wrong next-hop length, %d, in MP_REACH_NLRI",
2255 __func__, peer->host, attr->mp_nexthop_len);
2256 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2257 }
2258 break;
2259 case BGP_ATTR_NHLEN_VPNV4:
2260 stream_getl(s); /* RD high */
2261 stream_getl(s); /* RD low */
2262 /*
2263 * NOTE: intentional fall through
2264 * - for consistency in rx processing
2265 *
2266 * The following comment is to signal GCC this intention
2267 * and suppress the warning
2268 */
2269 /* FALLTHRU */
2270 case BGP_ATTR_NHLEN_IPV4:
2271 stream_get(&attr->mp_nexthop_global_in, s, IPV4_MAX_BYTELEN);
2272 /* Probably needed for RFC 2283 */
2273 if (attr->nexthop.s_addr == INADDR_ANY)
2274 memcpy(&attr->nexthop.s_addr,
2275 &attr->mp_nexthop_global_in, IPV4_MAX_BYTELEN);
2276 break;
2277 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
2278 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
2279 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_VPNV6_GLOBAL) {
2280 stream_getl(s); /* RD high */
2281 stream_getl(s); /* RD low */
2282 }
2283 stream_get(&attr->mp_nexthop_global, s, IPV6_MAX_BYTELEN);
2284 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2285 if (!peer->nexthop.ifp) {
2286 zlog_warn("%s sent a v6 global attribute but address is a V6 LL and there's no peer interface information. Hence, withdrawing",
2287 peer->host);
2288 return BGP_ATTR_PARSE_WITHDRAW;
2289 }
2290 attr->nh_ifindex = peer->nexthop.ifp->ifindex;
2291 }
2292 break;
2293 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
2294 case BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL:
2295 if (attr->mp_nexthop_len
2296 == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) {
2297 stream_getl(s); /* RD high */
2298 stream_getl(s); /* RD low */
2299 }
2300 stream_get(&attr->mp_nexthop_global, s, IPV6_MAX_BYTELEN);
2301 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2302 if (!peer->nexthop.ifp) {
2303 zlog_warn("%s sent a v6 global and LL attribute but global address is a V6 LL and there's no peer interface information. Hence, withdrawing",
2304 peer->host);
2305 return BGP_ATTR_PARSE_WITHDRAW;
2306 }
2307 attr->nh_ifindex = peer->nexthop.ifp->ifindex;
2308 }
2309 if (attr->mp_nexthop_len
2310 == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) {
2311 stream_getl(s); /* RD high */
2312 stream_getl(s); /* RD low */
2313 }
2314 stream_get(&attr->mp_nexthop_local, s, IPV6_MAX_BYTELEN);
2315 if (!IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local)) {
2316 if (bgp_debug_update(peer, NULL, NULL, 1))
2317 zlog_debug(
2318 "%s sent next-hops %pI6 and %pI6. Ignoring non-LL value",
2319 peer->host, &attr->mp_nexthop_global,
2320 &attr->mp_nexthop_local);
2321
2322 attr->mp_nexthop_len = IPV6_MAX_BYTELEN;
2323 }
2324 if (!peer->nexthop.ifp) {
2325 zlog_warn("%s sent a v6 LL next-hop and there's no peer interface information. Hence, withdrawing",
2326 peer->host);
2327 return BGP_ATTR_PARSE_WITHDRAW;
2328 }
2329 attr->nh_lla_ifindex = peer->nexthop.ifp->ifindex;
2330 break;
2331 default:
2332 zlog_info("%s: %s sent wrong next-hop length, %d, in MP_REACH_NLRI",
2333 __func__, peer->host, attr->mp_nexthop_len);
2334 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2335 }
2336
2337 if (!LEN_LEFT) {
2338 zlog_info("%s: %s sent SNPA which couldn't be read",
2339 __func__, peer->host);
2340 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2341 }
2342
2343 {
2344 uint8_t val;
2345 if ((val = stream_getc(s)))
2346 flog_warn(
2347 EC_BGP_DEFUNCT_SNPA_LEN,
2348 "%s sent non-zero value, %u, for defunct SNPA-length field",
2349 peer->host, val);
2350 }
2351
2352 /* must have nrli_len, what is left of the attribute */
2353 nlri_len = LEN_LEFT;
2354 if (nlri_len > STREAM_READABLE(s)) {
2355 zlog_info("%s: %s sent MP_REACH_NLRI which couldn't be read",
2356 __func__, peer->host);
2357 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2358 }
2359
2360 if (!nlri_len) {
2361 zlog_info("%s: %s sent a zero-length NLRI. Hence, treating as a EOR marker",
2362 __func__, peer->host);
2363
2364 mp_update->afi = afi;
2365 mp_update->safi = safi;
2366 return BGP_ATTR_PARSE_EOR;
2367 }
2368
2369 mp_update->afi = afi;
2370 mp_update->safi = safi;
2371 mp_update->nlri = stream_pnt(s);
2372 mp_update->length = nlri_len;
2373
2374 stream_forward_getp(s, nlri_len);
2375
2376 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI);
2377
2378 return BGP_ATTR_PARSE_PROCEED;
2379 #undef LEN_LEFT
2380 }
2381
2382 /* Multiprotocol unreachable parse */
2383 int bgp_mp_unreach_parse(struct bgp_attr_parser_args *args,
2384 struct bgp_nlri *mp_withdraw)
2385 {
2386 struct stream *s;
2387 iana_afi_t pkt_afi;
2388 afi_t afi;
2389 iana_safi_t pkt_safi;
2390 safi_t safi;
2391 uint16_t withdraw_len;
2392 struct peer *const peer = args->peer;
2393 struct attr *const attr = args->attr;
2394 const bgp_size_t length = args->length;
2395
2396 s = peer->curr;
2397
2398 #define BGP_MP_UNREACH_MIN_SIZE 3
2399 if ((length > STREAM_READABLE(s)) || (length < BGP_MP_UNREACH_MIN_SIZE))
2400 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2401
2402 pkt_afi = stream_getw(s);
2403 pkt_safi = stream_getc(s);
2404
2405 /* Convert AFI, SAFI to internal values, check. */
2406 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
2407 /* Log if AFI or SAFI is unrecognized. This is not an error
2408 * unless
2409 * the attribute is otherwise malformed.
2410 */
2411 if (bgp_debug_update(peer, NULL, NULL, 0))
2412 zlog_debug(
2413 "%s: MP_UNREACH received AFI %s or SAFI %s is unrecognized",
2414 peer->host, iana_afi2str(pkt_afi),
2415 iana_safi2str(pkt_safi));
2416 return BGP_ATTR_PARSE_ERROR;
2417 }
2418
2419 withdraw_len = length - BGP_MP_UNREACH_MIN_SIZE;
2420
2421 mp_withdraw->afi = afi;
2422 mp_withdraw->safi = safi;
2423 mp_withdraw->nlri = stream_pnt(s);
2424 mp_withdraw->length = withdraw_len;
2425
2426 stream_forward_getp(s, withdraw_len);
2427
2428 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI);
2429
2430 return BGP_ATTR_PARSE_PROCEED;
2431 }
2432
2433 /* Large Community attribute. */
2434 static enum bgp_attr_parse_ret
2435 bgp_attr_large_community(struct bgp_attr_parser_args *args)
2436 {
2437 struct peer *const peer = args->peer;
2438 struct attr *const attr = args->attr;
2439 const bgp_size_t length = args->length;
2440
2441 /*
2442 * Large community follows new attribute format.
2443 */
2444 if (length == 0) {
2445 bgp_attr_set_lcommunity(attr, NULL);
2446 /* Empty extcomm doesn't seem to be invalid per se */
2447 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2448 args->total);
2449 }
2450
2451 if (peer->discard_attrs[args->type] || peer->withdraw_attrs[args->type])
2452 goto large_community_ignore;
2453
2454 bgp_attr_set_lcommunity(
2455 attr, lcommunity_parse(stream_pnt(peer->curr), length));
2456 /* XXX: fix ecommunity_parse to use stream API */
2457 stream_forward_getp(peer->curr, length);
2458
2459 if (!bgp_attr_get_lcommunity(attr))
2460 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2461 args->total);
2462
2463 return BGP_ATTR_PARSE_PROCEED;
2464
2465 large_community_ignore:
2466 stream_forward_getp(peer->curr, length);
2467
2468 return bgp_attr_ignore(peer, args->type);
2469 }
2470
2471 /* Extended Community attribute. */
2472 static enum bgp_attr_parse_ret
2473 bgp_attr_ext_communities(struct bgp_attr_parser_args *args)
2474 {
2475 struct peer *const peer = args->peer;
2476 struct attr *const attr = args->attr;
2477 const bgp_size_t length = args->length;
2478 uint8_t sticky = 0;
2479 bool proxy = false;
2480 struct ecommunity *ecomm;
2481
2482 if (length == 0) {
2483 bgp_attr_set_ecommunity(attr, NULL);
2484 /* Empty extcomm doesn't seem to be invalid per se */
2485 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2486 args->total);
2487 }
2488
2489 ecomm = ecommunity_parse(
2490 stream_pnt(peer->curr), length,
2491 CHECK_FLAG(peer->flags,
2492 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE));
2493 bgp_attr_set_ecommunity(attr, ecomm);
2494 /* XXX: fix ecommunity_parse to use stream API */
2495 stream_forward_getp(peer->curr, length);
2496
2497 /* The Extended Community attribute SHALL be considered malformed if
2498 * its length is not a non-zero multiple of 8.
2499 */
2500 if (!bgp_attr_get_ecommunity(attr))
2501 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2502 args->total);
2503
2504 /* Extract DF election preference and mobility sequence number */
2505 attr->df_pref = bgp_attr_df_pref_from_ec(attr, &attr->df_alg);
2506
2507 /* Extract MAC mobility sequence number, if any. */
2508 attr->mm_seqnum = bgp_attr_mac_mobility_seqnum(attr, &sticky);
2509 attr->sticky = sticky;
2510
2511 /* Check if this is a Gateway MAC-IP advertisement */
2512 attr->default_gw = bgp_attr_default_gw(attr);
2513
2514 /* Handle scenario where router flag ecommunity is not
2515 * set but default gw ext community is present.
2516 * Use default gateway, set and propogate R-bit.
2517 */
2518 if (attr->default_gw)
2519 attr->router_flag = 1;
2520
2521 /* Check EVPN Neighbor advertisement flags, R-bit */
2522 bgp_attr_evpn_na_flag(attr, &attr->router_flag, &proxy);
2523 if (proxy)
2524 attr->es_flags |= ATTR_ES_PROXY_ADVERT;
2525
2526 /* Extract the Rmac, if any */
2527 if (bgp_attr_rmac(attr, &attr->rmac)) {
2528 if (bgp_debug_update(peer, NULL, NULL, 1)
2529 && bgp_mac_exist(&attr->rmac))
2530 zlog_debug("%s: router mac %pEA is self mac", __func__,
2531 &attr->rmac);
2532 }
2533
2534 /* Get the tunnel type from encap extended community */
2535 bgp_attr_extcom_tunnel_type(attr,
2536 (bgp_encap_types *)&attr->encap_tunneltype);
2537
2538 /* Extract link bandwidth, if any. */
2539 (void)ecommunity_linkbw_present(bgp_attr_get_ecommunity(attr),
2540 &attr->link_bw);
2541
2542 return BGP_ATTR_PARSE_PROCEED;
2543 }
2544
2545 /* IPv6 Extended Community attribute. */
2546 static enum bgp_attr_parse_ret
2547 bgp_attr_ipv6_ext_communities(struct bgp_attr_parser_args *args)
2548 {
2549 struct peer *const peer = args->peer;
2550 struct attr *const attr = args->attr;
2551 const bgp_size_t length = args->length;
2552 struct ecommunity *ipv6_ecomm = NULL;
2553
2554 if (length == 0) {
2555 bgp_attr_set_ipv6_ecommunity(attr, ipv6_ecomm);
2556 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2557 args->total);
2558 }
2559
2560 if (peer->discard_attrs[args->type] || peer->withdraw_attrs[args->type])
2561 goto ipv6_ext_community_ignore;
2562
2563 ipv6_ecomm = ecommunity_parse_ipv6(
2564 stream_pnt(peer->curr), length,
2565 CHECK_FLAG(peer->flags,
2566 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE));
2567 bgp_attr_set_ipv6_ecommunity(attr, ipv6_ecomm);
2568
2569 /* XXX: fix ecommunity_parse to use stream API */
2570 stream_forward_getp(peer->curr, length);
2571
2572 if (!ipv6_ecomm)
2573 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2574 args->total);
2575
2576 return BGP_ATTR_PARSE_PROCEED;
2577
2578 ipv6_ext_community_ignore:
2579 stream_forward_getp(peer->curr, length);
2580
2581 return bgp_attr_ignore(peer, args->type);
2582 }
2583
2584 /* Parse Tunnel Encap attribute in an UPDATE */
2585 static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */
2586 bgp_size_t length, /* IN: attr's length field */
2587 struct attr *attr, /* IN: caller already allocated */
2588 uint8_t flag, /* IN: attr's flags field */
2589 uint8_t *startp)
2590 {
2591 bgp_size_t total;
2592 uint16_t tunneltype = 0;
2593
2594 total = length + (CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
2595
2596 if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS)
2597 || !CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL)) {
2598 zlog_info(
2599 "Tunnel Encap attribute flag isn't optional and transitive %d",
2600 flag);
2601 bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR,
2602 BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
2603 startp, total);
2604 return -1;
2605 }
2606
2607 if (BGP_ATTR_ENCAP == type) {
2608 /* read outer TLV type and length */
2609 uint16_t tlv_length;
2610
2611 if (length < 4) {
2612 zlog_info(
2613 "Tunnel Encap attribute not long enough to contain outer T,L");
2614 bgp_notify_send_with_data(
2615 peer, BGP_NOTIFY_UPDATE_ERR,
2616 BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, startp, total);
2617 return -1;
2618 }
2619 tunneltype = stream_getw(BGP_INPUT(peer));
2620 tlv_length = stream_getw(BGP_INPUT(peer));
2621 length -= 4;
2622
2623 if (tlv_length != length) {
2624 zlog_info("%s: tlv_length(%d) != length(%d)",
2625 __func__, tlv_length, length);
2626 }
2627 }
2628
2629 while (length >= 4) {
2630 uint16_t subtype = 0;
2631 uint16_t sublength = 0;
2632 struct bgp_attr_encap_subtlv *tlv;
2633
2634 if (BGP_ATTR_ENCAP == type) {
2635 subtype = stream_getc(BGP_INPUT(peer));
2636 sublength = stream_getc(BGP_INPUT(peer));
2637 length -= 2;
2638 #ifdef ENABLE_BGP_VNC
2639 } else {
2640 subtype = stream_getw(BGP_INPUT(peer));
2641 sublength = stream_getw(BGP_INPUT(peer));
2642 length -= 4;
2643 #endif
2644 }
2645
2646 if (sublength > length) {
2647 zlog_info(
2648 "Tunnel Encap attribute sub-tlv length %d exceeds remaining length %d",
2649 sublength, length);
2650 bgp_notify_send_with_data(
2651 peer, BGP_NOTIFY_UPDATE_ERR,
2652 BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, startp, total);
2653 return -1;
2654 }
2655
2656 /* alloc and copy sub-tlv */
2657 /* TBD make sure these are freed when attributes are released */
2658 tlv = XCALLOC(MTYPE_ENCAP_TLV,
2659 sizeof(struct bgp_attr_encap_subtlv) + sublength);
2660 tlv->type = subtype;
2661 tlv->length = sublength;
2662 stream_get(tlv->value, peer->curr, sublength);
2663 length -= sublength;
2664
2665 /* attach tlv to encap chain */
2666 if (BGP_ATTR_ENCAP == type) {
2667 struct bgp_attr_encap_subtlv *stlv_last;
2668 for (stlv_last = attr->encap_subtlvs;
2669 stlv_last && stlv_last->next;
2670 stlv_last = stlv_last->next)
2671 ;
2672 if (stlv_last) {
2673 stlv_last->next = tlv;
2674 } else {
2675 attr->encap_subtlvs = tlv;
2676 }
2677 #ifdef ENABLE_BGP_VNC
2678 } else {
2679 struct bgp_attr_encap_subtlv *stlv_last;
2680 struct bgp_attr_encap_subtlv *vnc_subtlvs =
2681 bgp_attr_get_vnc_subtlvs(attr);
2682
2683 for (stlv_last = vnc_subtlvs;
2684 stlv_last && stlv_last->next;
2685 stlv_last = stlv_last->next)
2686 ;
2687 if (stlv_last)
2688 stlv_last->next = tlv;
2689 else
2690 bgp_attr_set_vnc_subtlvs(attr, tlv);
2691 #endif
2692 }
2693 }
2694
2695 if (BGP_ATTR_ENCAP == type) {
2696 attr->encap_tunneltype = tunneltype;
2697 }
2698
2699 if (length) {
2700 /* spurious leftover data */
2701 zlog_info(
2702 "Tunnel Encap attribute length is bad: %d leftover octets",
2703 length);
2704 bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR,
2705 BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2706 startp, total);
2707 return -1;
2708 }
2709
2710 return 0;
2711 }
2712
2713
2714 /* SRv6 Service Data Sub-Sub-TLV attribute
2715 * draft-ietf-bess-srv6-services-07
2716 */
2717 static enum bgp_attr_parse_ret
2718 bgp_attr_srv6_service_data(struct bgp_attr_parser_args *args)
2719 {
2720 struct peer *const peer = args->peer;
2721 struct attr *const attr = args->attr;
2722 uint8_t type, loc_block_len, loc_node_len, func_len, arg_len,
2723 transposition_len, transposition_offset;
2724 uint16_t length;
2725 size_t headersz = sizeof(type) + sizeof(length);
2726
2727 if (STREAM_READABLE(peer->curr) < headersz) {
2728 flog_err(
2729 EC_BGP_ATTR_LEN,
2730 "Malformed SRv6 Service Data Sub-Sub-TLV attribute - insufficent data (need %zu for attribute header, have %zu remaining in UPDATE)",
2731 headersz, STREAM_READABLE(peer->curr));
2732 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2733 args->total);
2734 }
2735
2736 type = stream_getc(peer->curr);
2737 length = stream_getw(peer->curr);
2738
2739 if (STREAM_READABLE(peer->curr) < length) {
2740 flog_err(
2741 EC_BGP_ATTR_LEN,
2742 "Malformed SRv6 Service Data Sub-Sub-TLV attribute - insufficent data (need %hu for attribute data, have %zu remaining in UPDATE)",
2743 length, STREAM_READABLE(peer->curr));
2744 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2745 args->total);
2746 }
2747
2748 if (length < BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_STRUCTURE_LENGTH) {
2749 flog_err(
2750 EC_BGP_ATTR_LEN,
2751 "Malformed SRv6 Service Data Sub-Sub-TLV attribute - insufficient data (need %u, have %hu remaining in UPDATE)",
2752 BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_STRUCTURE_LENGTH,
2753 length);
2754 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2755 args->total);
2756 }
2757
2758 if (type == BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_STRUCTURE) {
2759 if (STREAM_READABLE(peer->curr) <
2760 BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_STRUCTURE_LENGTH) {
2761 flog_err(
2762 EC_BGP_ATTR_LEN,
2763 "Malformed SRv6 Service Data Sub-Sub-TLV attribute - insufficient data (need %u, have %zu remaining in UPDATE)",
2764 BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_STRUCTURE_LENGTH,
2765 STREAM_READABLE(peer->curr));
2766 return bgp_attr_malformed(
2767 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2768 args->total);
2769 }
2770
2771 loc_block_len = stream_getc(peer->curr);
2772 loc_node_len = stream_getc(peer->curr);
2773 func_len = stream_getc(peer->curr);
2774 arg_len = stream_getc(peer->curr);
2775 transposition_len = stream_getc(peer->curr);
2776 transposition_offset = stream_getc(peer->curr);
2777
2778 /* Log SRv6 Service Data Sub-Sub-TLV */
2779 if (BGP_DEBUG(vpn, VPN_LEAK_LABEL)) {
2780 zlog_debug(
2781 "%s: srv6-l3-srv-data loc-block-len=%u, loc-node-len=%u func-len=%u, arg-len=%u, transposition-len=%u, transposition-offset=%u",
2782 __func__, loc_block_len, loc_node_len, func_len,
2783 arg_len, transposition_len,
2784 transposition_offset);
2785 }
2786
2787 attr->srv6_l3vpn->loc_block_len = loc_block_len;
2788 attr->srv6_l3vpn->loc_node_len = loc_node_len;
2789 attr->srv6_l3vpn->func_len = func_len;
2790 attr->srv6_l3vpn->arg_len = arg_len;
2791 attr->srv6_l3vpn->transposition_len = transposition_len;
2792 attr->srv6_l3vpn->transposition_offset = transposition_offset;
2793 }
2794
2795 else {
2796 if (bgp_debug_update(peer, NULL, NULL, 1))
2797 zlog_debug(
2798 "%s attr SRv6 Service Data Sub-Sub-TLV sub-sub-type=%u is not supported, skipped",
2799 peer->host, type);
2800
2801 stream_forward_getp(peer->curr, length);
2802 }
2803
2804 return BGP_ATTR_PARSE_PROCEED;
2805 }
2806
2807 /* SRv6 Service Sub-TLV attribute
2808 * draft-ietf-bess-srv6-services-07
2809 */
2810 static enum bgp_attr_parse_ret
2811 bgp_attr_srv6_service(struct bgp_attr_parser_args *args)
2812 {
2813 struct peer *const peer = args->peer;
2814 struct attr *const attr = args->attr;
2815 struct in6_addr ipv6_sid;
2816 uint8_t type, sid_flags;
2817 uint16_t length, endpoint_behavior;
2818 size_t headersz = sizeof(type) + sizeof(length);
2819 enum bgp_attr_parse_ret err;
2820
2821 if (STREAM_READABLE(peer->curr) < headersz) {
2822 flog_err(
2823 EC_BGP_ATTR_LEN,
2824 "Malformed SRv6 Service Sub-TLV attribute - insufficent data (need %zu for attribute header, have %zu remaining in UPDATE)",
2825 headersz, STREAM_READABLE(peer->curr));
2826 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2827 args->total);
2828 }
2829
2830 type = stream_getc(peer->curr);
2831 length = stream_getw(peer->curr);
2832
2833 if (STREAM_READABLE(peer->curr) < length) {
2834 flog_err(
2835 EC_BGP_ATTR_LEN,
2836 "Malformed SRv6 Service Sub-TLV attribute - insufficent data (need %hu for attribute data, have %zu remaining in UPDATE)",
2837 length, STREAM_READABLE(peer->curr));
2838 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2839 args->total);
2840 }
2841
2842 if (type == BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_INFO) {
2843 if (STREAM_READABLE(peer->curr) <
2844 BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_INFO_LENGTH) {
2845 flog_err(
2846 EC_BGP_ATTR_LEN,
2847 "Malformed SRv6 Service Sub-TLV attribute - insufficent data (need %d for attribute data, have %zu remaining in UPDATE)",
2848 BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_INFO_LENGTH,
2849 STREAM_READABLE(peer->curr));
2850 return bgp_attr_malformed(
2851 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2852 args->total);
2853 }
2854 stream_getc(peer->curr);
2855 stream_get(&ipv6_sid, peer->curr, sizeof(ipv6_sid));
2856 sid_flags = stream_getc(peer->curr);
2857 endpoint_behavior = stream_getw(peer->curr);
2858 stream_getc(peer->curr);
2859
2860 /* Log SRv6 Service Sub-TLV */
2861 if (BGP_DEBUG(vpn, VPN_LEAK_LABEL))
2862 zlog_debug(
2863 "%s: srv6-l3-srv sid %pI6, sid-flags 0x%02x, end-behaviour 0x%04x",
2864 __func__, &ipv6_sid, sid_flags,
2865 endpoint_behavior);
2866
2867 /* Configure from Info */
2868 if (attr->srv6_l3vpn) {
2869 flog_err(EC_BGP_ATTRIBUTE_REPEATED,
2870 "Prefix SID SRv6 L3VPN field repeated");
2871 return bgp_attr_malformed(
2872 args, BGP_NOTIFY_UPDATE_MAL_ATTR, args->total);
2873 }
2874 attr->srv6_l3vpn = XCALLOC(MTYPE_BGP_SRV6_L3VPN,
2875 sizeof(struct bgp_attr_srv6_l3vpn));
2876 sid_copy(&attr->srv6_l3vpn->sid, &ipv6_sid);
2877 attr->srv6_l3vpn->sid_flags = sid_flags;
2878 attr->srv6_l3vpn->endpoint_behavior = endpoint_behavior;
2879 attr->srv6_l3vpn->loc_block_len = 0;
2880 attr->srv6_l3vpn->loc_node_len = 0;
2881 attr->srv6_l3vpn->func_len = 0;
2882 attr->srv6_l3vpn->arg_len = 0;
2883 attr->srv6_l3vpn->transposition_len = 0;
2884 attr->srv6_l3vpn->transposition_offset = 0;
2885
2886 // Sub-Sub-TLV found
2887 if (length > BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_INFO_LENGTH) {
2888 err = bgp_attr_srv6_service_data(args);
2889
2890 if (err != BGP_ATTR_PARSE_PROCEED)
2891 return err;
2892 }
2893
2894 attr->srv6_l3vpn = srv6_l3vpn_intern(attr->srv6_l3vpn);
2895 }
2896
2897 /* Placeholder code for unsupported type */
2898 else {
2899 if (bgp_debug_update(peer, NULL, NULL, 1))
2900 zlog_debug(
2901 "%s attr SRv6 Service Sub-TLV sub-type=%u is not supported, skipped",
2902 peer->host, type);
2903
2904 stream_forward_getp(peer->curr, length);
2905 }
2906
2907 return BGP_ATTR_PARSE_PROCEED;
2908 }
2909
2910 /*
2911 * Read an individual SID value returning how much data we have read
2912 * Returns 0 if there was an error that needs to be passed up the stack
2913 */
2914 static enum bgp_attr_parse_ret
2915 bgp_attr_psid_sub(uint8_t type, uint16_t length,
2916 struct bgp_attr_parser_args *args)
2917 {
2918 struct peer *const peer = args->peer;
2919 struct attr *const attr = args->attr;
2920 uint32_t label_index;
2921 struct in6_addr ipv6_sid;
2922 uint32_t srgb_base;
2923 uint32_t srgb_range;
2924 int srgb_count;
2925 uint8_t sid_type, sid_flags;
2926
2927 if (type == BGP_PREFIX_SID_LABEL_INDEX) {
2928 if (STREAM_READABLE(peer->curr) < length
2929 || length != BGP_PREFIX_SID_LABEL_INDEX_LENGTH) {
2930 flog_err(EC_BGP_ATTR_LEN,
2931 "Prefix SID label index length is %hu instead of %u",
2932 length, BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
2933 return bgp_attr_malformed(args,
2934 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2935 args->total);
2936 }
2937
2938 /* Ignore flags and reserved */
2939 stream_getc(peer->curr);
2940 stream_getw(peer->curr);
2941
2942 /* Fetch the label index and see if it is valid. */
2943 label_index = stream_getl(peer->curr);
2944 if (label_index == BGP_INVALID_LABEL_INDEX)
2945 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2946 args->total);
2947
2948 /* Store label index; subsequently, we'll check on
2949 * address-family */
2950 attr->label_index = label_index;
2951 }
2952
2953 /* Placeholder code for the IPv6 SID type */
2954 else if (type == BGP_PREFIX_SID_IPV6) {
2955 if (STREAM_READABLE(peer->curr) < length
2956 || length != BGP_PREFIX_SID_IPV6_LENGTH) {
2957 flog_err(EC_BGP_ATTR_LEN,
2958 "Prefix SID IPv6 length is %hu instead of %u",
2959 length, BGP_PREFIX_SID_IPV6_LENGTH);
2960 return bgp_attr_malformed(args,
2961 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2962 args->total);
2963 }
2964
2965 /* Ignore reserved */
2966 stream_getc(peer->curr);
2967 stream_getw(peer->curr);
2968
2969 stream_get(&ipv6_sid, peer->curr, 16);
2970 }
2971
2972 /* Placeholder code for the Originator SRGB type */
2973 else if (type == BGP_PREFIX_SID_ORIGINATOR_SRGB) {
2974 /*
2975 * ietf-idr-bgp-prefix-sid-05:
2976 * Length is the total length of the value portion of the
2977 * TLV: 2 + multiple of 6.
2978 *
2979 * peer->curr stream readp should be at the beginning of the 16
2980 * bit flag field at this point in the code.
2981 */
2982
2983 /*
2984 * Check that the TLV length field is sane: at least 2 bytes of
2985 * flag, and at least 1 SRGB (these are 6 bytes each)
2986 */
2987 if (length < (2 + BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH)) {
2988 flog_err(
2989 EC_BGP_ATTR_LEN,
2990 "Prefix SID Originator SRGB length field claims length of %hu bytes, but the minimum for this TLV type is %u",
2991 length,
2992 2 + BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH);
2993 return bgp_attr_malformed(
2994 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2995 args->total);
2996 }
2997
2998 /*
2999 * Check that we actually have at least as much data as
3000 * specified by the length field
3001 */
3002 if (STREAM_READABLE(peer->curr) < length) {
3003 flog_err(EC_BGP_ATTR_LEN,
3004 "Prefix SID Originator SRGB specifies length %hu, but only %zu bytes remain",
3005 length, STREAM_READABLE(peer->curr));
3006 return bgp_attr_malformed(
3007 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3008 args->total);
3009 }
3010
3011 /*
3012 * Check that the portion of the TLV containing the sequence of
3013 * SRGBs corresponds to a multiple of the SRGB size; to get
3014 * that length, we skip the 16 bit flags field
3015 */
3016 stream_getw(peer->curr);
3017 length -= 2;
3018 if (length % BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH) {
3019 flog_err(
3020 EC_BGP_ATTR_LEN,
3021 "Prefix SID Originator SRGB length field claims attribute SRGB sequence section is %hubytes, but it must be a multiple of %u",
3022 length, BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH);
3023 return bgp_attr_malformed(
3024 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3025 args->total);
3026 }
3027
3028 srgb_count = length / BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH;
3029
3030 for (int i = 0; i < srgb_count; i++) {
3031 stream_get(&srgb_base, peer->curr, 3);
3032 stream_get(&srgb_range, peer->curr, 3);
3033 }
3034 }
3035
3036 /* Placeholder code for the VPN-SID Service type */
3037 else if (type == BGP_PREFIX_SID_VPN_SID) {
3038 if (STREAM_READABLE(peer->curr) < length
3039 || length != BGP_PREFIX_SID_VPN_SID_LENGTH) {
3040 flog_err(EC_BGP_ATTR_LEN,
3041 "Prefix SID VPN SID length is %hu instead of %u",
3042 length, BGP_PREFIX_SID_VPN_SID_LENGTH);
3043 return bgp_attr_malformed(args,
3044 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3045 args->total);
3046 }
3047
3048 /* Parse VPN-SID Sub-TLV */
3049 stream_getc(peer->curr); /* reserved */
3050 sid_type = stream_getc(peer->curr); /* sid_type */
3051 sid_flags = stream_getc(peer->curr); /* sid_flags */
3052 stream_get(&ipv6_sid, peer->curr,
3053 sizeof(ipv6_sid)); /* sid_value */
3054
3055 /* Log VPN-SID Sub-TLV */
3056 if (BGP_DEBUG(vpn, VPN_LEAK_LABEL))
3057 zlog_debug(
3058 "%s: vpn-sid: sid %pI6, sid-type 0x%02x sid-flags 0x%02x",
3059 __func__, &ipv6_sid, sid_type, sid_flags);
3060
3061 /* Configure from Info */
3062 if (attr->srv6_vpn) {
3063 flog_err(EC_BGP_ATTRIBUTE_REPEATED,
3064 "Prefix SID SRv6 VPN field repeated");
3065 return bgp_attr_malformed(
3066 args, BGP_NOTIFY_UPDATE_MAL_ATTR, args->total);
3067 }
3068 attr->srv6_vpn = XCALLOC(MTYPE_BGP_SRV6_VPN,
3069 sizeof(struct bgp_attr_srv6_vpn));
3070 attr->srv6_vpn->sid_flags = sid_flags;
3071 sid_copy(&attr->srv6_vpn->sid, &ipv6_sid);
3072 attr->srv6_vpn = srv6_vpn_intern(attr->srv6_vpn);
3073 }
3074
3075 /* Placeholder code for the SRv6 L3 Service type */
3076 else if (type == BGP_PREFIX_SID_SRV6_L3_SERVICE) {
3077 if (STREAM_READABLE(peer->curr) < length) {
3078 flog_err(
3079 EC_BGP_ATTR_LEN,
3080 "Prefix SID SRv6 L3-Service length is %hu, but only %zu bytes remain",
3081 length, STREAM_READABLE(peer->curr));
3082 return bgp_attr_malformed(args,
3083 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3084 args->total);
3085 }
3086
3087 /* ignore reserved */
3088 stream_getc(peer->curr);
3089
3090 return bgp_attr_srv6_service(args);
3091 }
3092
3093 /* Placeholder code for Unsupported TLV */
3094 else {
3095
3096 if (STREAM_READABLE(peer->curr) < length) {
3097 flog_err(
3098 EC_BGP_ATTR_LEN,
3099 "Prefix SID SRv6 length is %hu - too long, only %zu remaining in this UPDATE",
3100 length, STREAM_READABLE(peer->curr));
3101 return bgp_attr_malformed(
3102 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3103 args->total);
3104 }
3105
3106 if (bgp_debug_update(peer, NULL, NULL, 1))
3107 zlog_debug(
3108 "%s attr Prefix-SID sub-type=%u is not supported, skipped",
3109 peer->host, type);
3110
3111 stream_forward_getp(peer->curr, length);
3112 }
3113
3114 return BGP_ATTR_PARSE_PROCEED;
3115 }
3116
3117 /* Prefix SID attribute
3118 * draft-ietf-idr-bgp-prefix-sid-05
3119 */
3120 enum bgp_attr_parse_ret bgp_attr_prefix_sid(struct bgp_attr_parser_args *args)
3121 {
3122 struct peer *const peer = args->peer;
3123 struct attr *const attr = args->attr;
3124 enum bgp_attr_parse_ret ret;
3125
3126 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
3127
3128 uint8_t type;
3129 uint16_t length;
3130 size_t headersz = sizeof(type) + sizeof(length);
3131 size_t psid_parsed_length = 0;
3132
3133 while (STREAM_READABLE(peer->curr) > 0
3134 && psid_parsed_length < args->length) {
3135
3136 if (STREAM_READABLE(peer->curr) < headersz) {
3137 flog_err(
3138 EC_BGP_ATTR_LEN,
3139 "Malformed Prefix SID attribute - insufficent data (need %zu for attribute header, have %zu remaining in UPDATE)",
3140 headersz, STREAM_READABLE(peer->curr));
3141 return bgp_attr_malformed(
3142 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3143 args->total);
3144 }
3145
3146 type = stream_getc(peer->curr);
3147 length = stream_getw(peer->curr);
3148
3149 if (STREAM_READABLE(peer->curr) < length) {
3150 flog_err(
3151 EC_BGP_ATTR_LEN,
3152 "Malformed Prefix SID attribute - insufficient data (need %hu for attribute body, have %zu remaining in UPDATE)",
3153 length, STREAM_READABLE(peer->curr));
3154 return bgp_attr_malformed(args,
3155 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3156 args->total);
3157 }
3158
3159 ret = bgp_attr_psid_sub(type, length, args);
3160
3161 if (ret != BGP_ATTR_PARSE_PROCEED)
3162 return ret;
3163
3164 psid_parsed_length += length + headersz;
3165
3166 if (psid_parsed_length > args->length) {
3167 flog_err(
3168 EC_BGP_ATTR_LEN,
3169 "Malformed Prefix SID attribute - TLV overflow by attribute (need %zu for TLV length, have %zu overflowed in UPDATE)",
3170 length + headersz, psid_parsed_length - (length + headersz));
3171 return bgp_attr_malformed(
3172 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3173 args->total);
3174 }
3175 }
3176
3177 return BGP_ATTR_PARSE_PROCEED;
3178 }
3179
3180 /* PMSI tunnel attribute (RFC 6514)
3181 * Basic validation checks done here.
3182 */
3183 static enum bgp_attr_parse_ret
3184 bgp_attr_pmsi_tunnel(struct bgp_attr_parser_args *args)
3185 {
3186 struct peer *const peer = args->peer;
3187 struct attr *const attr = args->attr;
3188 const bgp_size_t length = args->length;
3189 uint8_t tnl_type;
3190 int attr_parse_len = 2 + BGP_LABEL_BYTES;
3191
3192 /* Verify that the receiver is expecting "ingress replication" as we
3193 * can only support that.
3194 */
3195 if (length < attr_parse_len) {
3196 flog_err(EC_BGP_ATTR_LEN, "Bad PMSI tunnel attribute length %d",
3197 length);
3198 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3199 args->total);
3200 }
3201 stream_getc(peer->curr); /* Flags */
3202 tnl_type = stream_getc(peer->curr);
3203 if (tnl_type > PMSI_TNLTYPE_MAX) {
3204 flog_err(EC_BGP_ATTR_PMSI_TYPE,
3205 "Invalid PMSI tunnel attribute type %d", tnl_type);
3206 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
3207 args->total);
3208 }
3209 if (tnl_type == PMSI_TNLTYPE_INGR_REPL) {
3210 if (length != 9) {
3211 flog_err(EC_BGP_ATTR_PMSI_LEN,
3212 "Bad PMSI tunnel attribute length %d for IR",
3213 length);
3214 return bgp_attr_malformed(
3215 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3216 args->total);
3217 }
3218 }
3219
3220 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL);
3221 bgp_attr_set_pmsi_tnl_type(attr, tnl_type);
3222 stream_get(&attr->label, peer->curr, BGP_LABEL_BYTES);
3223
3224 /* Forward read pointer of input stream. */
3225 stream_forward_getp(peer->curr, length - attr_parse_len);
3226
3227 return BGP_ATTR_PARSE_PROCEED;
3228 }
3229
3230 /* AIGP attribute (rfc7311) */
3231 static enum bgp_attr_parse_ret bgp_attr_aigp(struct bgp_attr_parser_args *args)
3232 {
3233 struct peer *const peer = args->peer;
3234 struct attr *const attr = args->attr;
3235 const bgp_size_t length = args->length;
3236 uint8_t *s = stream_pnt(peer->curr);
3237 uint64_t aigp = 0;
3238
3239 /* If an AIGP attribute is received on a BGP session for which
3240 * AIGP_SESSION is disabled, the attribute MUST be treated exactly
3241 * as if it were an unrecognized non-transitive attribute.
3242 * That is, it "MUST be quietly ignored and not passed along to
3243 * other BGP peers".
3244 * For Internal BGP (IBGP) sessions, and for External BGP (EBGP)
3245 * sessions between members of the same BGP Confederation,
3246 * the default value of AIGP_SESSION SHOULD be "enabled".
3247 */
3248 if (peer->sort == BGP_PEER_EBGP &&
3249 !CHECK_FLAG(peer->flags, PEER_FLAG_AIGP)) {
3250 zlog_warn(
3251 "%pBP received AIGP attribute, but eBGP peer do not support it",
3252 peer);
3253 goto aigp_ignore;
3254 }
3255
3256 if (peer->discard_attrs[args->type] || peer->withdraw_attrs[args->type])
3257 goto aigp_ignore;
3258
3259 if (!bgp_attr_aigp_valid(s, length))
3260 goto aigp_ignore;
3261
3262 /* Extract AIGP Metric TLV */
3263 if (bgp_attr_aigp_get_tlv_metric(s, length, &aigp))
3264 bgp_attr_set_aigp_metric(attr, aigp);
3265
3266 aigp_ignore:
3267 stream_forward_getp(peer->curr, length);
3268
3269 return bgp_attr_ignore(peer, args->type);
3270 }
3271
3272 /* OTC attribute. */
3273 static enum bgp_attr_parse_ret bgp_attr_otc(struct bgp_attr_parser_args *args)
3274 {
3275 struct peer *const peer = args->peer;
3276 struct attr *const attr = args->attr;
3277 const bgp_size_t length = args->length;
3278
3279 /* Length check. */
3280 if (length != 4) {
3281 flog_err(EC_BGP_ATTR_LEN, "OTC attribute length isn't 4 [%u]",
3282 length);
3283 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3284 args->total);
3285 }
3286
3287 if (peer->discard_attrs[args->type] || peer->withdraw_attrs[args->type])
3288 goto otc_ignore;
3289
3290 attr->otc = stream_getl(peer->curr);
3291 if (!attr->otc) {
3292 flog_err(EC_BGP_ATTR_MAL_AS_PATH, "OTC attribute value is 0");
3293 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_MAL_AS_PATH,
3294 args->total);
3295 }
3296
3297 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
3298
3299 return BGP_ATTR_PARSE_PROCEED;
3300
3301 otc_ignore:
3302 stream_forward_getp(peer->curr, length);
3303
3304 return bgp_attr_ignore(peer, args->type);
3305 }
3306
3307 /* BGP unknown attribute treatment. */
3308 static enum bgp_attr_parse_ret
3309 bgp_attr_unknown(struct bgp_attr_parser_args *args)
3310 {
3311 bgp_size_t total = args->total;
3312 struct transit *transit;
3313 struct peer *const peer = args->peer;
3314 struct attr *const attr = args->attr;
3315 uint8_t *const startp = args->startp;
3316 const uint8_t type = args->type;
3317 const uint8_t flag = args->flags;
3318 const bgp_size_t length = args->length;
3319
3320 if (bgp_debug_update(peer, NULL, NULL, 1))
3321 zlog_debug(
3322 "%s Unknown attribute is received (type %d, length %d)",
3323 peer->host, type, length);
3324
3325 /* Forward read pointer of input stream. */
3326 stream_forward_getp(peer->curr, length);
3327
3328 if (peer->discard_attrs[type] || peer->withdraw_attrs[type])
3329 return bgp_attr_ignore(peer, type);
3330
3331 /* If any of the mandatory well-known attributes are not recognized,
3332 then the Error Subcode is set to Unrecognized Well-known
3333 Attribute. The Data field contains the unrecognized attribute
3334 (type, length and value). */
3335 if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL)) {
3336 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_UNREC_ATTR,
3337 args->total);
3338 }
3339
3340 /* Unrecognized non-transitive optional attributes must be quietly
3341 ignored and not passed along to other BGP peers. */
3342 if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS))
3343 return BGP_ATTR_PARSE_PROCEED;
3344
3345 /* If a path with recognized transitive optional attribute is
3346 accepted and passed along to other BGP peers and the Partial bit
3347 in the Attribute Flags octet is set to 1 by some previous AS, it
3348 is not set back to 0 by the current AS. */
3349 SET_FLAG(*startp, BGP_ATTR_FLAG_PARTIAL);
3350
3351 /* Store transitive attribute to the end of attr->transit. */
3352 transit = bgp_attr_get_transit(attr);
3353 if (!transit)
3354 transit = XCALLOC(MTYPE_TRANSIT, sizeof(struct transit));
3355
3356 transit->val = XREALLOC(MTYPE_TRANSIT_VAL, transit->val,
3357 transit->length + total);
3358
3359 memcpy(transit->val + transit->length, startp, total);
3360 transit->length += total;
3361 bgp_attr_set_transit(attr, transit);
3362
3363 return BGP_ATTR_PARSE_PROCEED;
3364 }
3365
3366 /* Well-known attribute check. */
3367 static int bgp_attr_check(struct peer *peer, struct attr *attr)
3368 {
3369 uint8_t type = 0;
3370
3371 /* BGP Graceful-Restart End-of-RIB for IPv4 unicast is signaled as an
3372 * empty UPDATE. */
3373 if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV) && !attr->flag)
3374 return BGP_ATTR_PARSE_PROCEED;
3375
3376 /* "An UPDATE message that contains the MP_UNREACH_NLRI is not required
3377 to carry any other path attributes.", though if MP_REACH_NLRI or NLRI
3378 are present, it should. Check for any other attribute being present
3379 instead.
3380 */
3381 if ((!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI)) &&
3382 CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI))))
3383 return BGP_ATTR_PARSE_PROCEED;
3384
3385 if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGIN)))
3386 type = BGP_ATTR_ORIGIN;
3387
3388 if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AS_PATH)))
3389 type = BGP_ATTR_AS_PATH;
3390
3391 /* RFC 2858 makes Next-Hop optional/ignored, if MP_REACH_NLRI is present
3392 * and
3393 * NLRI is empty. We can't easily check NLRI empty here though.
3394 */
3395 if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP))
3396 && !CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI)))
3397 type = BGP_ATTR_NEXT_HOP;
3398
3399 if (peer->sort == BGP_PEER_IBGP
3400 && !CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))
3401 type = BGP_ATTR_LOCAL_PREF;
3402
3403 /* If any of the well-known mandatory attributes are not present
3404 * in an UPDATE message, then "treat-as-withdraw" MUST be used.
3405 */
3406 if (type) {
3407 flog_warn(EC_BGP_MISSING_ATTRIBUTE,
3408 "%s Missing well-known attribute %s.", peer->host,
3409 lookup_msg(attr_str, type, NULL));
3410 return BGP_ATTR_PARSE_WITHDRAW;
3411 }
3412 return BGP_ATTR_PARSE_PROCEED;
3413 }
3414
3415 /* Read attribute of update packet. This function is called from
3416 bgp_update_receive() in bgp_packet.c. */
3417 enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr,
3418 bgp_size_t size,
3419 struct bgp_nlri *mp_update,
3420 struct bgp_nlri *mp_withdraw)
3421 {
3422 enum bgp_attr_parse_ret ret;
3423 uint8_t flag = 0;
3424 uint8_t type = 0;
3425 bgp_size_t length;
3426 uint8_t *startp, *endp;
3427 uint8_t *attr_endp;
3428 uint8_t seen[BGP_ATTR_BITMAP_SIZE];
3429 /* we need the as4_path only until we have synthesized the as_path with
3430 * it */
3431 /* same goes for as4_aggregator */
3432 struct aspath *as4_path = NULL;
3433 as_t as4_aggregator = 0;
3434 struct in_addr as4_aggregator_addr = {.s_addr = 0};
3435 struct transit *transit;
3436
3437 /* Initialize bitmap. */
3438 memset(seen, 0, BGP_ATTR_BITMAP_SIZE);
3439
3440 /* End pointer of BGP attribute. */
3441 endp = BGP_INPUT_PNT(peer) + size;
3442
3443 /* Get attributes to the end of attribute length. */
3444 while (BGP_INPUT_PNT(peer) < endp) {
3445 /* Check remaining length check.*/
3446 if (endp - BGP_INPUT_PNT(peer) < BGP_ATTR_MIN_LEN) {
3447 /* XXX warning: long int format, int arg (arg 5) */
3448 flog_warn(
3449 EC_BGP_ATTRIBUTE_TOO_SMALL,
3450 "%s: error BGP attribute length %lu is smaller than min len",
3451 peer->host,
3452 (unsigned long)(endp
3453 - stream_pnt(BGP_INPUT(peer))));
3454
3455 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3456 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
3457 ret = BGP_ATTR_PARSE_ERROR;
3458 goto done;
3459 }
3460
3461 /* Fetch attribute flag and type. */
3462 startp = BGP_INPUT_PNT(peer);
3463 /* "The lower-order four bits of the Attribute Flags octet are
3464 unused. They MUST be zero when sent and MUST be ignored when
3465 received." */
3466 flag = 0xF0 & stream_getc(BGP_INPUT(peer));
3467 type = stream_getc(BGP_INPUT(peer));
3468
3469 /* Check whether Extended-Length applies and is in bounds */
3470 if (CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN)
3471 && ((endp - startp) < (BGP_ATTR_MIN_LEN + 1))) {
3472 flog_warn(
3473 EC_BGP_EXT_ATTRIBUTE_TOO_SMALL,
3474 "%s: Extended length set, but just %lu bytes of attr header",
3475 peer->host,
3476 (unsigned long)(endp
3477 - stream_pnt(BGP_INPUT(peer))));
3478
3479 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3480 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
3481 ret = BGP_ATTR_PARSE_ERROR;
3482 goto done;
3483 }
3484
3485 /* Check extended attribue length bit. */
3486 if (CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN))
3487 length = stream_getw(BGP_INPUT(peer));
3488 else
3489 length = stream_getc(BGP_INPUT(peer));
3490
3491 /* If any attribute appears more than once in the UPDATE
3492 message, then the Error Subcode is set to Malformed Attribute
3493 List. */
3494
3495 if (CHECK_BITMAP(seen, type)) {
3496 flog_warn(
3497 EC_BGP_ATTRIBUTE_REPEATED,
3498 "%s: error BGP attribute type %d appears twice in a message",
3499 peer->host, type);
3500
3501 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3502 BGP_NOTIFY_UPDATE_MAL_ATTR);
3503 ret = BGP_ATTR_PARSE_ERROR;
3504 goto done;
3505 }
3506
3507 /* Set type to bitmap to check duplicate attribute. `type' is
3508 unsigned char so it never overflow bitmap range. */
3509
3510 SET_BITMAP(seen, type);
3511
3512 /* Overflow check. */
3513 attr_endp = BGP_INPUT_PNT(peer) + length;
3514
3515 if (attr_endp > endp) {
3516 flog_warn(
3517 EC_BGP_ATTRIBUTE_TOO_LARGE,
3518 "%s: BGP type %d length %d is too large, attribute total length is %d. attr_endp is %p. endp is %p",
3519 peer->host, type, length, size, attr_endp,
3520 endp);
3521 /*
3522 * RFC 4271 6.3
3523 * If any recognized attribute has an Attribute
3524 * Length that conflicts with the expected length
3525 * (based on the attribute type code), then the
3526 * Error Subcode MUST be set to Attribute Length
3527 * Error. The Data field MUST contain the erroneous
3528 * attribute (type, length, and value).
3529 * ----------
3530 * We do not currently have a good way to determine the
3531 * length of the attribute independent of the length
3532 * received in the message. Instead we send the
3533 * minimum between the amount of data we have and the
3534 * amount specified by the attribute length field.
3535 *
3536 * Instead of directly passing in the packet buffer and
3537 * offset we use the stream_get* functions to read into
3538 * a stack buffer, since they perform bounds checking
3539 * and we are working with untrusted data.
3540 */
3541 unsigned char ndata[peer->max_packet_size];
3542 memset(ndata, 0x00, sizeof(ndata));
3543 size_t lfl =
3544 CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN) ? 2 : 1;
3545 /* Rewind to end of flag field */
3546 stream_rewind_getp(BGP_INPUT(peer), (1 + lfl));
3547 /* Type */
3548 stream_get(&ndata[0], BGP_INPUT(peer), 1);
3549 /* Length */
3550 stream_get(&ndata[1], BGP_INPUT(peer), lfl);
3551 /* Value */
3552 size_t atl = attr_endp - startp;
3553 size_t ndl = MIN(atl, STREAM_READABLE(BGP_INPUT(peer)));
3554 stream_get(&ndata[lfl + 1], BGP_INPUT(peer), ndl);
3555
3556 bgp_notify_send_with_data(
3557 peer, BGP_NOTIFY_UPDATE_ERR,
3558 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, ndata,
3559 ndl + lfl + 1);
3560
3561 ret = BGP_ATTR_PARSE_ERROR;
3562 goto done;
3563 }
3564
3565 struct bgp_attr_parser_args attr_args = {
3566 .peer = peer,
3567 .length = length,
3568 .attr = attr,
3569 .type = type,
3570 .flags = flag,
3571 .startp = startp,
3572 .total = attr_endp - startp,
3573 };
3574
3575
3576 /* If any recognized attribute has Attribute Flags that conflict
3577 with the Attribute Type Code, then the Error Subcode is set
3578 to
3579 Attribute Flags Error. The Data field contains the erroneous
3580 attribute (type, length and value). */
3581 if (bgp_attr_flag_invalid(&attr_args)) {
3582 ret = bgp_attr_malformed(
3583 &attr_args, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
3584 attr_args.total);
3585 if (ret == BGP_ATTR_PARSE_PROCEED)
3586 continue;
3587 goto done;
3588 }
3589
3590 /* OK check attribute and store it's value. */
3591 switch (type) {
3592 case BGP_ATTR_ORIGIN:
3593 ret = bgp_attr_origin(&attr_args);
3594 break;
3595 case BGP_ATTR_AS_PATH:
3596 ret = bgp_attr_aspath(&attr_args);
3597 break;
3598 case BGP_ATTR_AS4_PATH:
3599 ret = bgp_attr_as4_path(&attr_args, &as4_path);
3600 break;
3601 case BGP_ATTR_NEXT_HOP:
3602 ret = bgp_attr_nexthop(&attr_args);
3603 break;
3604 case BGP_ATTR_MULTI_EXIT_DISC:
3605 ret = bgp_attr_med(&attr_args);
3606 break;
3607 case BGP_ATTR_LOCAL_PREF:
3608 ret = bgp_attr_local_pref(&attr_args);
3609 break;
3610 case BGP_ATTR_ATOMIC_AGGREGATE:
3611 ret = bgp_attr_atomic(&attr_args);
3612 break;
3613 case BGP_ATTR_AGGREGATOR:
3614 ret = bgp_attr_aggregator(&attr_args);
3615 break;
3616 case BGP_ATTR_AS4_AGGREGATOR:
3617 ret = bgp_attr_as4_aggregator(&attr_args,
3618 &as4_aggregator,
3619 &as4_aggregator_addr);
3620 break;
3621 case BGP_ATTR_COMMUNITIES:
3622 ret = bgp_attr_community(&attr_args);
3623 break;
3624 case BGP_ATTR_LARGE_COMMUNITIES:
3625 ret = bgp_attr_large_community(&attr_args);
3626 break;
3627 case BGP_ATTR_ORIGINATOR_ID:
3628 ret = bgp_attr_originator_id(&attr_args);
3629 break;
3630 case BGP_ATTR_CLUSTER_LIST:
3631 ret = bgp_attr_cluster_list(&attr_args);
3632 break;
3633 case BGP_ATTR_MP_REACH_NLRI:
3634 ret = bgp_mp_reach_parse(&attr_args, mp_update);
3635 break;
3636 case BGP_ATTR_MP_UNREACH_NLRI:
3637 ret = bgp_mp_unreach_parse(&attr_args, mp_withdraw);
3638 break;
3639 case BGP_ATTR_EXT_COMMUNITIES:
3640 ret = bgp_attr_ext_communities(&attr_args);
3641 break;
3642 #ifdef ENABLE_BGP_VNC_ATTR
3643 case BGP_ATTR_VNC:
3644 #endif
3645 case BGP_ATTR_ENCAP:
3646 ret = bgp_attr_encap(type, peer, length, attr, flag,
3647 startp);
3648 break;
3649 case BGP_ATTR_PREFIX_SID:
3650 ret = bgp_attr_prefix_sid(&attr_args);
3651 break;
3652 case BGP_ATTR_PMSI_TUNNEL:
3653 ret = bgp_attr_pmsi_tunnel(&attr_args);
3654 break;
3655 case BGP_ATTR_IPV6_EXT_COMMUNITIES:
3656 ret = bgp_attr_ipv6_ext_communities(&attr_args);
3657 break;
3658 case BGP_ATTR_OTC:
3659 ret = bgp_attr_otc(&attr_args);
3660 break;
3661 case BGP_ATTR_AIGP:
3662 ret = bgp_attr_aigp(&attr_args);
3663 break;
3664 default:
3665 ret = bgp_attr_unknown(&attr_args);
3666 break;
3667 }
3668
3669 if (ret == BGP_ATTR_PARSE_ERROR_NOTIFYPLS) {
3670 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3671 BGP_NOTIFY_UPDATE_MAL_ATTR);
3672 ret = BGP_ATTR_PARSE_ERROR;
3673 goto done;
3674 }
3675
3676 if (ret == BGP_ATTR_PARSE_EOR) {
3677 goto done;
3678 }
3679
3680 if (ret == BGP_ATTR_PARSE_ERROR) {
3681 flog_warn(EC_BGP_ATTRIBUTE_PARSE_ERROR,
3682 "%s: Attribute %s, parse error", peer->host,
3683 lookup_msg(attr_str, type, NULL));
3684 goto done;
3685 }
3686 if (ret == BGP_ATTR_PARSE_WITHDRAW) {
3687 flog_warn(
3688 EC_BGP_ATTRIBUTE_PARSE_WITHDRAW,
3689 "%s: Attribute %s, parse error - treating as withdrawal",
3690 peer->host, lookup_msg(attr_str, type, NULL));
3691 goto done;
3692 }
3693
3694 /* Check the fetched length. */
3695 if (BGP_INPUT_PNT(peer) != attr_endp) {
3696 flog_warn(EC_BGP_ATTRIBUTE_FETCH_ERROR,
3697 "%s: BGP attribute %s, fetch error",
3698 peer->host, lookup_msg(attr_str, type, NULL));
3699 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3700 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
3701 ret = BGP_ATTR_PARSE_ERROR;
3702 goto done;
3703 }
3704 }
3705
3706 /*
3707 * draft-ietf-idr-bgp-prefix-sid-27#section-3:
3708 * About Prefix-SID path attribute,
3709 * Label-Index TLV(type1) and The Originator SRGB TLV(type-3)
3710 * may only appear in a BGP Prefix-SID attribute attached to
3711 * IPv4/IPv6 Labeled Unicast prefixes ([RFC8277]).
3712 * It MUST be ignored when received for other BGP AFI/SAFI combinations.
3713 */
3714 if (!attr->mp_nexthop_len || mp_update->safi != SAFI_LABELED_UNICAST)
3715 attr->label_index = BGP_INVALID_LABEL_INDEX;
3716
3717 /* Check final read pointer is same as end pointer. */
3718 if (BGP_INPUT_PNT(peer) != endp) {
3719 flog_warn(EC_BGP_ATTRIBUTES_MISMATCH,
3720 "%s: BGP attribute %s, length mismatch", peer->host,
3721 lookup_msg(attr_str, type, NULL));
3722 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3723 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
3724
3725 ret = BGP_ATTR_PARSE_ERROR;
3726 goto done;
3727 }
3728
3729 /*
3730 * RFC4271: If the NEXT_HOP attribute field is syntactically incorrect,
3731 * then the Error Subcode MUST be set to Invalid NEXT_HOP Attribute.
3732 * This is implemented below and will result in a NOTIFICATION. If the
3733 * NEXT_HOP attribute is semantically incorrect, the error SHOULD be
3734 * logged, and the route SHOULD be ignored. In this case, a NOTIFICATION
3735 * message SHOULD NOT be sent. This is implemented elsewhere.
3736 *
3737 * RFC4760: An UPDATE message that carries no NLRI, other than the one
3738 * encoded in the MP_REACH_NLRI attribute, SHOULD NOT carry the NEXT_HOP
3739 * attribute. If such a message contains the NEXT_HOP attribute, the BGP
3740 * speaker that receives the message SHOULD ignore this attribute.
3741 */
3742 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP))
3743 && !CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI))) {
3744 if (bgp_attr_nexthop_valid(peer, attr) < 0) {
3745 ret = BGP_ATTR_PARSE_ERROR;
3746 goto done;
3747 }
3748 }
3749
3750 /* Check all mandatory well-known attributes are present */
3751 ret = bgp_attr_check(peer, attr);
3752 if (ret < 0)
3753 goto done;
3754
3755 /*
3756 * At this place we can see whether we got AS4_PATH and/or
3757 * AS4_AGGREGATOR from a 16Bit peer and act accordingly.
3758 * We can not do this before we've read all attributes because
3759 * the as4 handling does not say whether AS4_PATH has to be sent
3760 * after AS_PATH or not - and when AS4_AGGREGATOR will be send
3761 * in relationship to AGGREGATOR.
3762 * So, to be defensive, we are not relying on any order and read
3763 * all attributes first, including these 32bit ones, and now,
3764 * afterwards, we look what and if something is to be done for as4.
3765 *
3766 * It is possible to not have AS_PATH, e.g. GR EoR and sole
3767 * MP_UNREACH_NLRI.
3768 */
3769 /* actually... this doesn't ever return failure currently, but
3770 * better safe than sorry */
3771 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AS_PATH))
3772 && bgp_attr_munge_as4_attrs(peer, attr, as4_path, as4_aggregator,
3773 &as4_aggregator_addr)) {
3774 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3775 BGP_NOTIFY_UPDATE_MAL_ATTR);
3776 ret = BGP_ATTR_PARSE_ERROR;
3777 goto done;
3778 }
3779
3780 /*
3781 * Finally do the checks on the aspath we did not do yet
3782 * because we waited for a potentially synthesized aspath.
3783 */
3784 if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS_PATH))) {
3785 ret = bgp_attr_aspath_check(peer, attr);
3786 if (ret != BGP_ATTR_PARSE_PROCEED)
3787 goto done;
3788 }
3789
3790 ret = BGP_ATTR_PARSE_PROCEED;
3791 done:
3792
3793 /*
3794 * At this stage, we have done all fiddling with as4, and the
3795 * resulting info is in attr->aggregator resp. attr->aspath so
3796 * we can chuck as4_aggregator and as4_path alltogether in order
3797 * to save memory
3798 */
3799 /*
3800 * unintern - it is in the hash
3801 * The flag that we got this is still there, but that
3802 * does not do any trouble
3803 */
3804 aspath_unintern(&as4_path);
3805
3806 transit = bgp_attr_get_transit(attr);
3807 if (ret != BGP_ATTR_PARSE_ERROR) {
3808 /* Finally intern unknown attribute. */
3809 if (transit)
3810 bgp_attr_set_transit(attr, transit_intern(transit));
3811 if (attr->encap_subtlvs)
3812 attr->encap_subtlvs = encap_intern(attr->encap_subtlvs,
3813 ENCAP_SUBTLV_TYPE);
3814 #ifdef ENABLE_BGP_VNC
3815 struct bgp_attr_encap_subtlv *vnc_subtlvs =
3816 bgp_attr_get_vnc_subtlvs(attr);
3817
3818 if (vnc_subtlvs)
3819 bgp_attr_set_vnc_subtlvs(
3820 attr,
3821 encap_intern(vnc_subtlvs, VNC_SUBTLV_TYPE));
3822 #endif
3823 } else {
3824 if (transit) {
3825 transit_free(transit);
3826 bgp_attr_set_transit(attr, NULL);
3827 }
3828
3829 bgp_attr_flush_encap(attr);
3830 };
3831
3832 /* Sanity checks */
3833 transit = bgp_attr_get_transit(attr);
3834 if (transit)
3835 assert(transit->refcnt > 0);
3836 if (attr->encap_subtlvs)
3837 assert(attr->encap_subtlvs->refcnt > 0);
3838 #ifdef ENABLE_BGP_VNC
3839 struct bgp_attr_encap_subtlv *vnc_subtlvs =
3840 bgp_attr_get_vnc_subtlvs(attr);
3841
3842 if (vnc_subtlvs)
3843 assert(vnc_subtlvs->refcnt > 0);
3844 #endif
3845
3846 return ret;
3847 }
3848
3849 /*
3850 * Extract the tunnel type from extended community
3851 */
3852 void bgp_attr_extcom_tunnel_type(struct attr *attr,
3853 bgp_encap_types *tunnel_type)
3854 {
3855 struct ecommunity *ecom;
3856 uint32_t i;
3857
3858 if (!attr)
3859 return;
3860
3861 ecom = bgp_attr_get_ecommunity(attr);
3862 if (!ecom || !ecom->size)
3863 return;
3864
3865 for (i = 0; i < ecom->size; i++) {
3866 uint8_t *pnt;
3867 uint8_t type, sub_type;
3868
3869 pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
3870 type = pnt[0];
3871 sub_type = pnt[1];
3872 if (!(type == ECOMMUNITY_ENCODE_OPAQUE &&
3873 sub_type == ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP))
3874 continue;
3875 *tunnel_type = ((pnt[6] << 8) | pnt[7]);
3876 return;
3877 }
3878
3879 return;
3880 }
3881
3882 size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi,
3883 safi_t safi, struct bpacket_attr_vec_arr *vecarr,
3884 struct attr *attr)
3885 {
3886 size_t sizep;
3887 iana_afi_t pkt_afi = IANA_AFI_IPV4;
3888 iana_safi_t pkt_safi = IANA_SAFI_UNICAST;
3889 afi_t nh_afi;
3890
3891 /* Set extended bit always to encode the attribute length as 2 bytes */
3892 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_EXTLEN);
3893 stream_putc(s, BGP_ATTR_MP_REACH_NLRI);
3894 sizep = stream_get_endp(s);
3895 stream_putw(s, 0); /* Marker: Attribute length. */
3896
3897
3898 /* Convert AFI, SAFI to values for packet. */
3899 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
3900
3901 stream_putw(s, pkt_afi); /* AFI */
3902 stream_putc(s, pkt_safi); /* SAFI */
3903
3904 /* Nexthop AFI */
3905 if (afi == AFI_IP
3906 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST
3907 || safi == SAFI_MPLS_VPN || safi == SAFI_MULTICAST))
3908 nh_afi = peer_cap_enhe(peer, afi, safi) ? AFI_IP6 : AFI_IP;
3909 else if (safi == SAFI_FLOWSPEC)
3910 nh_afi = afi;
3911 else
3912 nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->mp_nexthop_len);
3913
3914 /* Nexthop */
3915 bpacket_attr_vec_arr_set_vec(vecarr, BGP_ATTR_VEC_NH, s, attr);
3916 switch (nh_afi) {
3917 case AFI_IP:
3918 switch (safi) {
3919 case SAFI_UNICAST:
3920 case SAFI_MULTICAST:
3921 case SAFI_LABELED_UNICAST:
3922 stream_putc(s, 4);
3923 stream_put_ipv4(s, attr->nexthop.s_addr);
3924 break;
3925 case SAFI_MPLS_VPN:
3926 stream_putc(s, 12);
3927 stream_putl(s, 0); /* RD = 0, per RFC */
3928 stream_putl(s, 0);
3929 stream_put(s, &attr->mp_nexthop_global_in, 4);
3930 break;
3931 case SAFI_ENCAP:
3932 case SAFI_EVPN:
3933 stream_putc(s, 4);
3934 stream_put(s, &attr->mp_nexthop_global_in, 4);
3935 break;
3936 case SAFI_FLOWSPEC:
3937 if (attr->mp_nexthop_len == 0)
3938 stream_putc(s, 0); /* no nexthop for flowspec */
3939 else {
3940 stream_putc(s, attr->mp_nexthop_len);
3941 stream_put_ipv4(s, attr->nexthop.s_addr);
3942 }
3943 break;
3944 case SAFI_UNSPEC:
3945 case SAFI_MAX:
3946 assert(!"SAFI's UNSPEC or MAX being specified are a DEV ESCAPE");
3947 break;
3948 }
3949 break;
3950 case AFI_IP6:
3951 switch (safi) {
3952 case SAFI_UNICAST:
3953 case SAFI_MULTICAST:
3954 case SAFI_LABELED_UNICAST:
3955 case SAFI_EVPN: {
3956 if (attr->mp_nexthop_len
3957 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
3958 stream_putc(s,
3959 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL);
3960 stream_put(s, &attr->mp_nexthop_global,
3961 IPV6_MAX_BYTELEN);
3962 stream_put(s, &attr->mp_nexthop_local,
3963 IPV6_MAX_BYTELEN);
3964 } else {
3965 stream_putc(s, IPV6_MAX_BYTELEN);
3966 stream_put(s, &attr->mp_nexthop_global,
3967 IPV6_MAX_BYTELEN);
3968 }
3969 } break;
3970 case SAFI_MPLS_VPN: {
3971 if (attr->mp_nexthop_len ==
3972 BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) {
3973 stream_putc(s, 48);
3974 stream_putl(s, 0); /* RD = 0, per RFC */
3975 stream_putl(s, 0);
3976 stream_put(s, &attr->mp_nexthop_global,
3977 IPV6_MAX_BYTELEN);
3978 stream_putl(s, 0); /* RD = 0, per RFC */
3979 stream_putl(s, 0);
3980 stream_put(s, &attr->mp_nexthop_local,
3981 IPV6_MAX_BYTELEN);
3982 } else {
3983 stream_putc(s, 24);
3984 stream_putl(s, 0); /* RD = 0, per RFC */
3985 stream_putl(s, 0);
3986 stream_put(s, &attr->mp_nexthop_global,
3987 IPV6_MAX_BYTELEN);
3988 }
3989 } break;
3990 case SAFI_ENCAP:
3991 stream_putc(s, IPV6_MAX_BYTELEN);
3992 stream_put(s, &attr->mp_nexthop_global,
3993 IPV6_MAX_BYTELEN);
3994 break;
3995 case SAFI_FLOWSPEC:
3996 stream_putc(s, 0); /* no nexthop for flowspec */
3997 break;
3998 case SAFI_UNSPEC:
3999 case SAFI_MAX:
4000 assert(!"SAFI's UNSPEC or MAX being specified are a DEV ESCAPE");
4001 break;
4002 }
4003 break;
4004 case AFI_L2VPN:
4005 if (safi != SAFI_FLOWSPEC)
4006 flog_err(
4007 EC_BGP_ATTR_NH_SEND_LEN,
4008 "Bad nexthop when sending to %s, AFI %u SAFI %u nhlen %d",
4009 peer->host, afi, safi, attr->mp_nexthop_len);
4010 break;
4011 case AFI_UNSPEC:
4012 case AFI_MAX:
4013 assert(!"DEV ESCAPE: AFI_UNSPEC or AFI_MAX should not be used here");
4014 break;
4015 }
4016
4017 /* SNPA */
4018 stream_putc(s, 0);
4019 return sizep;
4020 }
4021
4022 void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
4023 const struct prefix *p,
4024 const struct prefix_rd *prd, mpls_label_t *label,
4025 uint32_t num_labels, bool addpath_capable,
4026 uint32_t addpath_tx_id, struct attr *attr)
4027 {
4028 switch (safi) {
4029 case SAFI_UNSPEC:
4030 case SAFI_MAX:
4031 assert(!"Dev escape usage of SAFI_UNSPEC or MAX");
4032 break;
4033 case SAFI_MPLS_VPN:
4034 if (addpath_capable)
4035 stream_putl(s, addpath_tx_id);
4036 /* Label, RD, Prefix write. */
4037 stream_putc(s, p->prefixlen + 88);
4038 stream_put(s, label, BGP_LABEL_BYTES);
4039 stream_put(s, prd->val, 8);
4040 stream_put(s, &p->u.prefix, PSIZE(p->prefixlen));
4041 break;
4042 case SAFI_EVPN:
4043 if (afi == AFI_L2VPN)
4044 /* EVPN prefix - contents depend on type */
4045 bgp_evpn_encode_prefix(s, p, prd, label, num_labels,
4046 attr, addpath_capable,
4047 addpath_tx_id);
4048 else
4049 assert(!"Add encoding bits here for other AFI's");
4050 break;
4051 case SAFI_LABELED_UNICAST:
4052 /* Prefix write with label. */
4053 stream_put_labeled_prefix(s, p, label, addpath_capable,
4054 addpath_tx_id);
4055 break;
4056 case SAFI_FLOWSPEC:
4057 stream_putc(s, p->u.prefix_flowspec.prefixlen);
4058 stream_put(s, (const void *)p->u.prefix_flowspec.ptr,
4059 p->u.prefix_flowspec.prefixlen);
4060 break;
4061
4062 case SAFI_UNICAST:
4063 case SAFI_MULTICAST:
4064 stream_put_prefix_addpath(s, p, addpath_capable, addpath_tx_id);
4065 break;
4066 case SAFI_ENCAP:
4067 assert(!"Please add proper encoding of SAFI_ENCAP");
4068 break;
4069 }
4070 }
4071
4072 size_t bgp_packet_mpattr_prefix_size(afi_t afi, safi_t safi,
4073 const struct prefix *p)
4074 {
4075 int size = PSIZE(p->prefixlen);
4076
4077 switch (safi) {
4078 case SAFI_UNSPEC:
4079 case SAFI_MAX:
4080 assert(!"Attempting to figure size for a SAFI_UNSPEC/SAFI_MAX this is a DEV ESCAPE");
4081 break;
4082 case SAFI_UNICAST:
4083 case SAFI_MULTICAST:
4084 break;
4085 case SAFI_MPLS_VPN:
4086 size += 88;
4087 break;
4088 case SAFI_ENCAP:
4089 /* This has to be wrong, but I don't know what to put here */
4090 assert(!"Do we try to use this?");
4091 break;
4092 case SAFI_LABELED_UNICAST:
4093 size += BGP_LABEL_BYTES;
4094 break;
4095 case SAFI_EVPN:
4096 /*
4097 * TODO: Maximum possible for type-2, type-3 and type-5
4098 */
4099 if (afi == AFI_L2VPN)
4100 size += 232;
4101 else
4102 assert(!"Attempting to figure size for SAFI_EVPN and !AFI_L2VPN and FRR will not have the proper values");
4103 break;
4104 case SAFI_FLOWSPEC:
4105 size = ((struct prefix_fs *)p)->prefix.prefixlen;
4106 break;
4107 }
4108
4109 return size;
4110 }
4111
4112 /*
4113 * Encodes the tunnel encapsulation attribute,
4114 * and with ENABLE_BGP_VNC the VNC attribute which uses
4115 * almost the same TLV format
4116 */
4117 static void bgp_packet_mpattr_tea(struct bgp *bgp, struct peer *peer,
4118 struct stream *s, struct attr *attr,
4119 uint8_t attrtype)
4120 {
4121 unsigned int attrlenfield = 0;
4122 unsigned int attrhdrlen = 0;
4123 struct bgp_attr_encap_subtlv *subtlvs;
4124 struct bgp_attr_encap_subtlv *st;
4125 const char *attrname;
4126
4127 if (!attr || (attrtype == BGP_ATTR_ENCAP
4128 && (!attr->encap_tunneltype
4129 || attr->encap_tunneltype == BGP_ENCAP_TYPE_MPLS)))
4130 return;
4131
4132 switch (attrtype) {
4133 case BGP_ATTR_ENCAP:
4134 attrname = "Tunnel Encap";
4135 subtlvs = attr->encap_subtlvs;
4136 if (subtlvs == NULL) /* nothing to do */
4137 return;
4138 /*
4139 * The tunnel encap attr has an "outer" tlv.
4140 * T = tunneltype,
4141 * L = total length of subtlvs,
4142 * V = concatenated subtlvs.
4143 */
4144 attrlenfield = 2 + 2; /* T + L */
4145 attrhdrlen = 1 + 1; /* subTLV T + L */
4146 break;
4147
4148 #ifdef ENABLE_BGP_VNC_ATTR
4149 case BGP_ATTR_VNC:
4150 attrname = "VNC";
4151 subtlvs = bgp_attr_get_vnc_subtlvs(attr);
4152 if (subtlvs == NULL) /* nothing to do */
4153 return;
4154 attrlenfield = 0; /* no outer T + L */
4155 attrhdrlen = 2 + 2; /* subTLV T + L */
4156 break;
4157 #endif
4158
4159 default:
4160 assert(0);
4161 }
4162
4163 /* compute attr length */
4164 for (st = subtlvs; st; st = st->next) {
4165 attrlenfield += (attrhdrlen + st->length);
4166 }
4167
4168 if (attrlenfield > 0xffff) {
4169 zlog_info("%s attribute is too long (length=%d), can't send it",
4170 attrname, attrlenfield);
4171 return;
4172 }
4173
4174 if (attrlenfield > 0xff) {
4175 /* 2-octet length field */
4176 stream_putc(s,
4177 BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL
4178 | BGP_ATTR_FLAG_EXTLEN);
4179 stream_putc(s, attrtype);
4180 stream_putw(s, attrlenfield & 0xffff);
4181 } else {
4182 /* 1-octet length field */
4183 stream_putc(s, BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL);
4184 stream_putc(s, attrtype);
4185 stream_putc(s, attrlenfield & 0xff);
4186 }
4187
4188 if (attrtype == BGP_ATTR_ENCAP) {
4189 /* write outer T+L */
4190 stream_putw(s, attr->encap_tunneltype);
4191 stream_putw(s, attrlenfield - 4);
4192 }
4193
4194 /* write each sub-tlv */
4195 for (st = subtlvs; st; st = st->next) {
4196 if (attrtype == BGP_ATTR_ENCAP) {
4197 stream_putc(s, st->type);
4198 stream_putc(s, st->length);
4199 #ifdef ENABLE_BGP_VNC
4200 } else {
4201 stream_putw(s, st->type);
4202 stream_putw(s, st->length);
4203 #endif
4204 }
4205 stream_put(s, st->value, st->length);
4206 }
4207 }
4208
4209 void bgp_packet_mpattr_end(struct stream *s, size_t sizep)
4210 {
4211 /* Set MP attribute length. Don't count the (2) bytes used to encode
4212 the attr length */
4213 stream_putw_at(s, sizep, (stream_get_endp(s) - sizep) - 2);
4214 }
4215
4216 static bool bgp_append_local_as(struct peer *peer, afi_t afi, safi_t safi)
4217 {
4218 if (!BGP_AS_IS_PRIVATE(peer->local_as)
4219 || (BGP_AS_IS_PRIVATE(peer->local_as)
4220 && !CHECK_FLAG(peer->af_flags[afi][safi],
4221 PEER_FLAG_REMOVE_PRIVATE_AS)
4222 && !CHECK_FLAG(peer->af_flags[afi][safi],
4223 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
4224 && !CHECK_FLAG(peer->af_flags[afi][safi],
4225 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
4226 && !CHECK_FLAG(peer->af_flags[afi][safi],
4227 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)))
4228 return true;
4229 return false;
4230 }
4231
4232 /* Make attribute packet. */
4233 bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
4234 struct stream *s, struct attr *attr,
4235 struct bpacket_attr_vec_arr *vecarr,
4236 struct prefix *p, afi_t afi, safi_t safi,
4237 struct peer *from, struct prefix_rd *prd,
4238 mpls_label_t *label, uint32_t num_labels,
4239 bool addpath_capable, uint32_t addpath_tx_id,
4240 struct bgp_path_info *bpi)
4241 {
4242 size_t cp;
4243 size_t aspath_sizep;
4244 struct aspath *aspath;
4245 int send_as4_path = 0;
4246 int send_as4_aggregator = 0;
4247 bool use32bit = CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)
4248 && CHECK_FLAG(peer->cap, PEER_CAP_AS4_ADV);
4249
4250 if (!bgp)
4251 bgp = peer->bgp;
4252
4253 /* Remember current pointer. */
4254 cp = stream_get_endp(s);
4255
4256 if (p
4257 && !((afi == AFI_IP && safi == SAFI_UNICAST)
4258 && !peer_cap_enhe(peer, afi, safi))) {
4259 size_t mpattrlen_pos = 0;
4260
4261 mpattrlen_pos = bgp_packet_mpattr_start(s, peer, afi, safi,
4262 vecarr, attr);
4263 bgp_packet_mpattr_prefix(s, afi, safi, p, prd, label,
4264 num_labels, addpath_capable,
4265 addpath_tx_id, attr);
4266 bgp_packet_mpattr_end(s, mpattrlen_pos);
4267 }
4268
4269 /* Origin attribute. */
4270 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4271 stream_putc(s, BGP_ATTR_ORIGIN);
4272 stream_putc(s, 1);
4273 stream_putc(s, attr->origin);
4274
4275 /* AS path attribute. */
4276
4277 /* If remote-peer is EBGP */
4278 if (peer->sort == BGP_PEER_EBGP
4279 && (!CHECK_FLAG(peer->af_flags[afi][safi],
4280 PEER_FLAG_AS_PATH_UNCHANGED)
4281 || attr->aspath->segments == NULL)
4282 && (!CHECK_FLAG(peer->af_flags[afi][safi],
4283 PEER_FLAG_RSERVER_CLIENT))) {
4284 aspath = aspath_dup(attr->aspath);
4285
4286 /* Even though we may not be configured for confederations we
4287 * may have
4288 * RXed an AS_PATH with AS_CONFED_SEQUENCE or AS_CONFED_SET */
4289 aspath = aspath_delete_confed_seq(aspath);
4290
4291 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
4292 /* Stuff our path CONFED_ID on the front */
4293 aspath = aspath_add_seq(aspath, bgp->confed_id);
4294 } else {
4295 if (peer->change_local_as) {
4296 /* If replace-as is specified, we only use the
4297 change_local_as when
4298 advertising routes. */
4299 if (!CHECK_FLAG(peer->flags,
4300 PEER_FLAG_LOCAL_AS_REPLACE_AS))
4301 if (bgp_append_local_as(peer, afi,
4302 safi))
4303 aspath = aspath_add_seq(
4304 aspath, peer->local_as);
4305 aspath = aspath_add_seq(aspath,
4306 peer->change_local_as);
4307 } else {
4308 aspath = aspath_add_seq(aspath, peer->local_as);
4309 }
4310 }
4311 } else if (peer->sort == BGP_PEER_CONFED) {
4312 /* A confed member, so we need to do the AS_CONFED_SEQUENCE
4313 * thing */
4314 aspath = aspath_dup(attr->aspath);
4315 aspath = aspath_add_confed_seq(aspath, peer->local_as);
4316 } else
4317 aspath = attr->aspath;
4318
4319 /* If peer is not AS4 capable, then:
4320 * - send the created AS_PATH out as AS4_PATH (optional, transitive),
4321 * but ensure that no AS_CONFED_SEQUENCE and AS_CONFED_SET path
4322 * segment
4323 * types are in it (i.e. exclude them if they are there)
4324 * AND do this only if there is at least one asnum > 65535 in the
4325 * path!
4326 * - send an AS_PATH out, but put 16Bit ASnums in it, not 32bit, and
4327 * change
4328 * all ASnums > 65535 to BGP_AS_TRANS
4329 */
4330
4331 stream_putc(s, BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_EXTLEN);
4332 stream_putc(s, BGP_ATTR_AS_PATH);
4333 aspath_sizep = stream_get_endp(s);
4334 stream_putw(s, 0);
4335 stream_putw_at(s, aspath_sizep, aspath_put(s, aspath, use32bit));
4336
4337 /* OLD session may need NEW_AS_PATH sent, if there are 4-byte ASNs
4338 * in the path
4339 */
4340 if (!use32bit && aspath_has_as4(aspath))
4341 send_as4_path =
4342 1; /* we'll do this later, at the correct place */
4343
4344 /* Nexthop attribute. */
4345 if (afi == AFI_IP && safi == SAFI_UNICAST
4346 && !peer_cap_enhe(peer, afi, safi)) {
4347 afi_t nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->mp_nexthop_len);
4348
4349 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
4350 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4351 stream_putc(s, BGP_ATTR_NEXT_HOP);
4352 bpacket_attr_vec_arr_set_vec(vecarr, BGP_ATTR_VEC_NH, s,
4353 attr);
4354 stream_putc(s, 4);
4355 stream_put_ipv4(s, attr->nexthop.s_addr);
4356 } else if (peer_cap_enhe(from, afi, safi)
4357 || (nh_afi == AFI_IP6)) {
4358 /*
4359 * Likely this is the case when an IPv4 prefix was
4360 * received with Extended Next-hop capability in this
4361 * or another vrf and is now being advertised to
4362 * non-ENHE peers. Since peer_cap_enhe only checks
4363 * peers in this vrf, also check the nh_afi to catch
4364 * the case where the originator was in another vrf.
4365 * Setting the mandatory (ipv4) next-hop attribute here
4366 * to enable implicit next-hop self with correct A-F
4367 * (ipv4 address family).
4368 */
4369 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4370 stream_putc(s, BGP_ATTR_NEXT_HOP);
4371 bpacket_attr_vec_arr_set_vec(vecarr, BGP_ATTR_VEC_NH, s,
4372 NULL);
4373 stream_putc(s, 4);
4374 stream_put_ipv4(s, 0);
4375 }
4376 }
4377
4378 /* MED attribute. */
4379 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)
4380 || bgp->maxmed_active) {
4381 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
4382 stream_putc(s, BGP_ATTR_MULTI_EXIT_DISC);
4383 stream_putc(s, 4);
4384 stream_putl(s, (bgp->maxmed_active ? bgp->maxmed_value
4385 : attr->med));
4386 }
4387
4388 /* Local preference. */
4389 if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED) {
4390 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4391 stream_putc(s, BGP_ATTR_LOCAL_PREF);
4392 stream_putc(s, 4);
4393 stream_putl(s, attr->local_pref);
4394 }
4395
4396 /* Atomic aggregate. */
4397 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
4398 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4399 stream_putc(s, BGP_ATTR_ATOMIC_AGGREGATE);
4400 stream_putc(s, 0);
4401 }
4402
4403 /* Aggregator. */
4404 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR)) {
4405 /* Common to BGP_ATTR_AGGREGATOR, regardless of ASN size */
4406 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
4407 stream_putc(s, BGP_ATTR_AGGREGATOR);
4408
4409 if (use32bit) {
4410 /* AS4 capable peer */
4411 stream_putc(s, 8);
4412 stream_putl(s, attr->aggregator_as);
4413 } else {
4414 /* 2-byte AS peer */
4415 stream_putc(s, 6);
4416
4417 /* Is ASN representable in 2-bytes? Or must AS_TRANS be
4418 * used? */
4419 if (attr->aggregator_as > UINT16_MAX) {
4420 stream_putw(s, BGP_AS_TRANS);
4421
4422 /* we have to send AS4_AGGREGATOR, too.
4423 * we'll do that later in order to send
4424 * attributes in ascending
4425 * order.
4426 */
4427 send_as4_aggregator = 1;
4428 } else
4429 stream_putw(s, (uint16_t)attr->aggregator_as);
4430 }
4431 stream_put_ipv4(s, attr->aggregator_addr.s_addr);
4432 }
4433
4434 /* Community attribute. */
4435 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY)
4436 && (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))) {
4437 struct community *comm = NULL;
4438
4439 comm = bgp_attr_get_community(attr);
4440 if (comm->size * 4 > 255) {
4441 stream_putc(s,
4442 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
4443 | BGP_ATTR_FLAG_EXTLEN);
4444 stream_putc(s, BGP_ATTR_COMMUNITIES);
4445 stream_putw(s, comm->size * 4);
4446 } else {
4447 stream_putc(s,
4448 BGP_ATTR_FLAG_OPTIONAL
4449 | BGP_ATTR_FLAG_TRANS);
4450 stream_putc(s, BGP_ATTR_COMMUNITIES);
4451 stream_putc(s, comm->size * 4);
4452 }
4453 stream_put(s, comm->val, comm->size * 4);
4454 }
4455
4456 /*
4457 * Large Community attribute.
4458 */
4459 if (CHECK_FLAG(peer->af_flags[afi][safi],
4460 PEER_FLAG_SEND_LARGE_COMMUNITY)
4461 && (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))) {
4462 if (lcom_length(bgp_attr_get_lcommunity(attr)) > 255) {
4463 stream_putc(s,
4464 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
4465 | BGP_ATTR_FLAG_EXTLEN);
4466 stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
4467 stream_putw(s,
4468 lcom_length(bgp_attr_get_lcommunity(attr)));
4469 } else {
4470 stream_putc(s,
4471 BGP_ATTR_FLAG_OPTIONAL
4472 | BGP_ATTR_FLAG_TRANS);
4473 stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
4474 stream_putc(s,
4475 lcom_length(bgp_attr_get_lcommunity(attr)));
4476 }
4477 stream_put(s, bgp_attr_get_lcommunity(attr)->val,
4478 lcom_length(bgp_attr_get_lcommunity(attr)));
4479 }
4480
4481 /* Route Reflector. */
4482 if (peer->sort == BGP_PEER_IBGP && from
4483 && from->sort == BGP_PEER_IBGP) {
4484 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
4485
4486 /* Originator ID. */
4487 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
4488 stream_putc(s, BGP_ATTR_ORIGINATOR_ID);
4489 stream_putc(s, 4);
4490
4491 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
4492 stream_put_in_addr(s, &attr->originator_id);
4493 else
4494 stream_put_in_addr(s, &from->remote_id);
4495
4496 /* Cluster list. */
4497 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
4498 stream_putc(s, BGP_ATTR_CLUSTER_LIST);
4499
4500 if (cluster) {
4501 stream_putc(s, cluster->length + 4);
4502 /* If this peer configuration's parent BGP has
4503 * cluster_id. */
4504 if (bgp->config & BGP_CONFIG_CLUSTER_ID)
4505 stream_put_in_addr(s, &bgp->cluster_id);
4506 else
4507 stream_put_in_addr(s, &bgp->router_id);
4508 stream_put(s, cluster->list, cluster->length);
4509 } else {
4510 stream_putc(s, 4);
4511 /* If this peer configuration's parent BGP has
4512 * cluster_id. */
4513 if (bgp->config & BGP_CONFIG_CLUSTER_ID)
4514 stream_put_in_addr(s, &bgp->cluster_id);
4515 else
4516 stream_put_in_addr(s, &bgp->router_id);
4517 }
4518 }
4519
4520 /* Extended Communities attribute. */
4521 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY)
4522 && (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4523 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
4524 bool transparent = CHECK_FLAG(peer->af_flags[afi][safi],
4525 PEER_FLAG_RSERVER_CLIENT) &&
4526 from &&
4527 CHECK_FLAG(from->af_flags[afi][safi],
4528 PEER_FLAG_RSERVER_CLIENT);
4529
4530 if (peer->sort == BGP_PEER_IBGP ||
4531 peer->sort == BGP_PEER_CONFED || transparent) {
4532 if (ecomm->size * 8 > 255) {
4533 stream_putc(s,
4534 BGP_ATTR_FLAG_OPTIONAL
4535 | BGP_ATTR_FLAG_TRANS
4536 | BGP_ATTR_FLAG_EXTLEN);
4537 stream_putc(s, BGP_ATTR_EXT_COMMUNITIES);
4538 stream_putw(s, ecomm->size * 8);
4539 } else {
4540 stream_putc(s,
4541 BGP_ATTR_FLAG_OPTIONAL
4542 | BGP_ATTR_FLAG_TRANS);
4543 stream_putc(s, BGP_ATTR_EXT_COMMUNITIES);
4544 stream_putc(s, ecomm->size * 8);
4545 }
4546 stream_put(s, ecomm->val, ecomm->size * 8);
4547 } else {
4548 uint8_t *pnt;
4549 int tbit;
4550 int ecom_tr_size = 0;
4551 uint32_t i;
4552
4553 for (i = 0; i < ecomm->size; i++) {
4554 pnt = ecomm->val + (i * 8);
4555 tbit = *pnt;
4556
4557 if (CHECK_FLAG(tbit,
4558 ECOMMUNITY_FLAG_NON_TRANSITIVE))
4559 continue;
4560
4561 ecom_tr_size++;
4562 }
4563
4564 if (ecom_tr_size) {
4565 if (ecom_tr_size * 8 > 255) {
4566 stream_putc(
4567 s,
4568 BGP_ATTR_FLAG_OPTIONAL
4569 | BGP_ATTR_FLAG_TRANS
4570 | BGP_ATTR_FLAG_EXTLEN);
4571 stream_putc(s,
4572 BGP_ATTR_EXT_COMMUNITIES);
4573 stream_putw(s, ecom_tr_size * 8);
4574 } else {
4575 stream_putc(
4576 s,
4577 BGP_ATTR_FLAG_OPTIONAL
4578 | BGP_ATTR_FLAG_TRANS);
4579 stream_putc(s,
4580 BGP_ATTR_EXT_COMMUNITIES);
4581 stream_putc(s, ecom_tr_size * 8);
4582 }
4583
4584 for (i = 0; i < ecomm->size; i++) {
4585 pnt = ecomm->val + (i * 8);
4586 tbit = *pnt;
4587
4588 if (CHECK_FLAG(
4589 tbit,
4590 ECOMMUNITY_FLAG_NON_TRANSITIVE))
4591 continue;
4592
4593 stream_put(s, pnt, 8);
4594 }
4595 }
4596 }
4597 }
4598
4599 /* Label index attribute. */
4600 if (safi == SAFI_LABELED_UNICAST) {
4601 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) {
4602 uint32_t label_index;
4603
4604 label_index = attr->label_index;
4605
4606 if (label_index != BGP_INVALID_LABEL_INDEX) {
4607 stream_putc(s,
4608 BGP_ATTR_FLAG_OPTIONAL
4609 | BGP_ATTR_FLAG_TRANS);
4610 stream_putc(s, BGP_ATTR_PREFIX_SID);
4611 stream_putc(s, 10);
4612 stream_putc(s, BGP_PREFIX_SID_LABEL_INDEX);
4613 stream_putw(s,
4614 BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
4615 stream_putc(s, 0); // reserved
4616 stream_putw(s, 0); // flags
4617 stream_putl(s, label_index);
4618 }
4619 }
4620 }
4621
4622 /* SRv6 Service Information Attribute. */
4623 if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_MPLS_VPN) {
4624 if (attr->srv6_l3vpn) {
4625 uint8_t subtlv_len =
4626 BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_STRUCTURE_LENGTH
4627 + BGP_ATTR_MIN_LEN
4628 + BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_INFO_LENGTH;
4629 uint8_t tlv_len = subtlv_len + BGP_ATTR_MIN_LEN + 1;
4630 uint8_t attr_len = tlv_len + BGP_ATTR_MIN_LEN;
4631 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL
4632 | BGP_ATTR_FLAG_TRANS);
4633 stream_putc(s, BGP_ATTR_PREFIX_SID);
4634 stream_putc(s, attr_len);
4635 stream_putc(s, BGP_PREFIX_SID_SRV6_L3_SERVICE);
4636 stream_putw(s, tlv_len);
4637 stream_putc(s, 0); /* reserved */
4638 stream_putc(s, BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_INFO);
4639 stream_putw(s, subtlv_len);
4640 stream_putc(s, 0); /* reserved */
4641 stream_put(s, &attr->srv6_l3vpn->sid,
4642 sizeof(attr->srv6_l3vpn->sid)); /* sid */
4643 stream_putc(s, 0); /* sid_flags */
4644 stream_putw(s,
4645 attr->srv6_l3vpn
4646 ->endpoint_behavior); /* endpoint */
4647 stream_putc(s, 0); /* reserved */
4648 stream_putc(
4649 s,
4650 BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_STRUCTURE);
4651 stream_putw(
4652 s,
4653 BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_STRUCTURE_LENGTH);
4654 stream_putc(s, attr->srv6_l3vpn->loc_block_len);
4655 stream_putc(s, attr->srv6_l3vpn->loc_node_len);
4656 stream_putc(s, attr->srv6_l3vpn->func_len);
4657 stream_putc(s, attr->srv6_l3vpn->arg_len);
4658 stream_putc(s, attr->srv6_l3vpn->transposition_len);
4659 stream_putc(s, attr->srv6_l3vpn->transposition_offset);
4660 } else if (attr->srv6_vpn) {
4661 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL
4662 | BGP_ATTR_FLAG_TRANS);
4663 stream_putc(s, BGP_ATTR_PREFIX_SID);
4664 stream_putc(s, 22); /* tlv len */
4665 stream_putc(s, BGP_PREFIX_SID_VPN_SID);
4666 stream_putw(s, 0x13); /* tlv len */
4667 stream_putc(s, 0x00); /* reserved */
4668 stream_putc(s, 0x01); /* sid_type */
4669 stream_putc(s, 0x00); /* sif_flags */
4670 stream_put(s, &attr->srv6_vpn->sid,
4671 sizeof(attr->srv6_vpn->sid)); /* sid */
4672 }
4673 }
4674
4675 if (send_as4_path) {
4676 /* If the peer is NOT As4 capable, AND */
4677 /* there are ASnums > 65535 in path THEN
4678 * give out AS4_PATH */
4679
4680 /* Get rid of all AS_CONFED_SEQUENCE and AS_CONFED_SET
4681 * path segments!
4682 * Hm, I wonder... confederation things *should* only be at
4683 * the beginning of an aspath, right? Then we should use
4684 * aspath_delete_confed_seq for this, because it is already
4685 * there! (JK)
4686 * Folks, talk to me: what is reasonable here!?
4687 */
4688 aspath = aspath_delete_confed_seq(aspath);
4689
4690 stream_putc(s,
4691 BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL
4692 | BGP_ATTR_FLAG_EXTLEN);
4693 stream_putc(s, BGP_ATTR_AS4_PATH);
4694 aspath_sizep = stream_get_endp(s);
4695 stream_putw(s, 0);
4696 stream_putw_at(s, aspath_sizep, aspath_put(s, aspath, 1));
4697 }
4698
4699 if (aspath != attr->aspath)
4700 aspath_free(aspath);
4701
4702 if (send_as4_aggregator) {
4703 /* send AS4_AGGREGATOR, at this place */
4704 /* this section of code moved here in order to ensure the
4705 * correct
4706 * *ascending* order of attributes
4707 */
4708 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
4709 stream_putc(s, BGP_ATTR_AS4_AGGREGATOR);
4710 stream_putc(s, 8);
4711 stream_putl(s, attr->aggregator_as);
4712 stream_put_ipv4(s, attr->aggregator_addr.s_addr);
4713 }
4714
4715 if (((afi == AFI_IP || afi == AFI_IP6)
4716 && (safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN))
4717 || (afi == AFI_L2VPN && safi == SAFI_EVPN)) {
4718 /* Tunnel Encap attribute */
4719 bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_ENCAP);
4720
4721 #ifdef ENABLE_BGP_VNC_ATTR
4722 /* VNC attribute */
4723 bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_VNC);
4724 #endif
4725 }
4726
4727 /* PMSI Tunnel */
4728 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
4729 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
4730 stream_putc(s, BGP_ATTR_PMSI_TUNNEL);
4731 stream_putc(s, 9); // Length
4732 stream_putc(s, 0); // Flags
4733 stream_putc(s, bgp_attr_get_pmsi_tnl_type(attr));
4734 stream_put(s, &(attr->label),
4735 BGP_LABEL_BYTES); // MPLS Label / VXLAN VNI
4736 stream_put_ipv4(s, attr->nexthop.s_addr);
4737 // Unicast tunnel endpoint IP address
4738 }
4739
4740 /* OTC */
4741 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
4742 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
4743 stream_putc(s, BGP_ATTR_OTC);
4744 stream_putc(s, 4);
4745 stream_putl(s, attr->otc);
4746 }
4747
4748 /* AIGP */
4749 if (bpi && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP) &&
4750 (CHECK_FLAG(peer->flags, PEER_FLAG_AIGP) ||
4751 peer->sort != BGP_PEER_EBGP)) {
4752 /* At the moment only AIGP Metric TLV exists for AIGP
4753 * attribute. If more comes in, do not forget to update
4754 * attr_len variable to include new ones.
4755 */
4756 uint8_t attr_len = BGP_AIGP_TLV_METRIC_LEN;
4757
4758 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
4759 stream_putc(s, BGP_ATTR_AIGP);
4760 stream_putc(s, attr_len);
4761 stream_put_bgp_aigp_tlv_metric(s, bpi);
4762 }
4763
4764 /* Unknown transit attribute. */
4765 struct transit *transit = bgp_attr_get_transit(attr);
4766
4767 if (transit)
4768 stream_put(s, transit->val, transit->length);
4769
4770 /* Return total size of attribute. */
4771 return stream_get_endp(s) - cp;
4772 }
4773
4774 size_t bgp_packet_mpunreach_start(struct stream *s, afi_t afi, safi_t safi)
4775 {
4776 unsigned long attrlen_pnt;
4777 iana_afi_t pkt_afi = IANA_AFI_IPV4;
4778 iana_safi_t pkt_safi = IANA_SAFI_UNICAST;
4779
4780 /* Set extended bit always to encode the attribute length as 2 bytes */
4781 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_EXTLEN);
4782 stream_putc(s, BGP_ATTR_MP_UNREACH_NLRI);
4783
4784 attrlen_pnt = stream_get_endp(s);
4785 stream_putw(s, 0); /* Length of this attribute. */
4786
4787 /* Convert AFI, SAFI to values for packet. */
4788 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
4789
4790 stream_putw(s, pkt_afi);
4791 stream_putc(s, pkt_safi);
4792
4793 return attrlen_pnt;
4794 }
4795
4796 void bgp_packet_mpunreach_prefix(struct stream *s, const struct prefix *p,
4797 afi_t afi, safi_t safi,
4798 const struct prefix_rd *prd,
4799 mpls_label_t *label, uint32_t num_labels,
4800 bool addpath_capable, uint32_t addpath_tx_id,
4801 struct attr *attr)
4802 {
4803 uint8_t wlabel[4] = {0x80, 0x00, 0x00};
4804
4805 if (safi == SAFI_LABELED_UNICAST) {
4806 label = (mpls_label_t *)wlabel;
4807 num_labels = 1;
4808 }
4809
4810 bgp_packet_mpattr_prefix(s, afi, safi, p, prd, label, num_labels,
4811 addpath_capable, addpath_tx_id, attr);
4812 }
4813
4814 void bgp_packet_mpunreach_end(struct stream *s, size_t attrlen_pnt)
4815 {
4816 bgp_packet_mpattr_end(s, attrlen_pnt);
4817 }
4818
4819 /* Initialization of attribute. */
4820 void bgp_attr_init(void)
4821 {
4822 aspath_init();
4823 attrhash_init();
4824 community_init();
4825 ecommunity_init();
4826 lcommunity_init();
4827 cluster_init();
4828 transit_init();
4829 encap_init();
4830 srv6_init();
4831 }
4832
4833 void bgp_attr_finish(void)
4834 {
4835 aspath_finish();
4836 attrhash_finish();
4837 community_finish();
4838 ecommunity_finish();
4839 lcommunity_finish();
4840 cluster_finish();
4841 transit_finish();
4842 encap_finish();
4843 srv6_finish();
4844 }
4845
4846 /* Make attribute packet. */
4847 void bgp_dump_routes_attr(struct stream *s, struct bgp_path_info *bpi,
4848 const struct prefix *prefix)
4849 {
4850 unsigned long cp;
4851 unsigned long len;
4852 size_t aspath_lenp;
4853 struct aspath *aspath;
4854 bool addpath_capable = false;
4855 uint32_t addpath_tx_id = 0;
4856 struct attr *attr = bpi->attr;
4857
4858 /* Remember current pointer. */
4859 cp = stream_get_endp(s);
4860
4861 /* Place holder of length. */
4862 stream_putw(s, 0);
4863
4864 /* Origin attribute. */
4865 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4866 stream_putc(s, BGP_ATTR_ORIGIN);
4867 stream_putc(s, 1);
4868 stream_putc(s, attr->origin);
4869
4870 aspath = attr->aspath;
4871
4872 stream_putc(s, BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_EXTLEN);
4873 stream_putc(s, BGP_ATTR_AS_PATH);
4874 aspath_lenp = stream_get_endp(s);
4875 stream_putw(s, 0);
4876
4877 stream_putw_at(s, aspath_lenp, aspath_put(s, aspath, 1));
4878
4879 /* Nexthop attribute. */
4880 /* If it's an IPv6 prefix, don't dump the IPv4 nexthop to save space */
4881 if (prefix != NULL && prefix->family != AF_INET6) {
4882 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4883 stream_putc(s, BGP_ATTR_NEXT_HOP);
4884 stream_putc(s, 4);
4885 stream_put_ipv4(s, attr->nexthop.s_addr);
4886 }
4887
4888 /* MED attribute. */
4889 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
4890 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
4891 stream_putc(s, BGP_ATTR_MULTI_EXIT_DISC);
4892 stream_putc(s, 4);
4893 stream_putl(s, attr->med);
4894 }
4895
4896 /* Local preference. */
4897 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
4898 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4899 stream_putc(s, BGP_ATTR_LOCAL_PREF);
4900 stream_putc(s, 4);
4901 stream_putl(s, attr->local_pref);
4902 }
4903
4904 /* Atomic aggregate. */
4905 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
4906 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4907 stream_putc(s, BGP_ATTR_ATOMIC_AGGREGATE);
4908 stream_putc(s, 0);
4909 }
4910
4911 /* Aggregator. */
4912 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR)) {
4913 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
4914 stream_putc(s, BGP_ATTR_AGGREGATOR);
4915 stream_putc(s, 8);
4916 stream_putl(s, attr->aggregator_as);
4917 stream_put_ipv4(s, attr->aggregator_addr.s_addr);
4918 }
4919
4920 /* Community attribute. */
4921 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
4922 struct community *comm = NULL;
4923
4924 comm = bgp_attr_get_community(attr);
4925 if (comm->size * 4 > 255) {
4926 stream_putc(s,
4927 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
4928 | BGP_ATTR_FLAG_EXTLEN);
4929 stream_putc(s, BGP_ATTR_COMMUNITIES);
4930 stream_putw(s, comm->size * 4);
4931 } else {
4932 stream_putc(s,
4933 BGP_ATTR_FLAG_OPTIONAL
4934 | BGP_ATTR_FLAG_TRANS);
4935 stream_putc(s, BGP_ATTR_COMMUNITIES);
4936 stream_putc(s, comm->size * 4);
4937 }
4938 stream_put(s, comm->val, comm->size * 4);
4939 }
4940
4941 /* Large Community attribute. */
4942 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
4943 if (lcom_length(bgp_attr_get_lcommunity(attr)) > 255) {
4944 stream_putc(s,
4945 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
4946 | BGP_ATTR_FLAG_EXTLEN);
4947 stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
4948 stream_putw(s,
4949 lcom_length(bgp_attr_get_lcommunity(attr)));
4950 } else {
4951 stream_putc(s,
4952 BGP_ATTR_FLAG_OPTIONAL
4953 | BGP_ATTR_FLAG_TRANS);
4954 stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
4955 stream_putc(s,
4956 lcom_length(bgp_attr_get_lcommunity(attr)));
4957 }
4958
4959 stream_put(s, bgp_attr_get_lcommunity(attr)->val,
4960 lcom_length(bgp_attr_get_lcommunity(attr)));
4961 }
4962
4963 /* Add a MP_NLRI attribute to dump the IPv6 next hop */
4964 if (prefix != NULL && prefix->family == AF_INET6
4965 && (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL
4966 || attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)) {
4967 int sizep;
4968
4969 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
4970 stream_putc(s, BGP_ATTR_MP_REACH_NLRI);
4971 sizep = stream_get_endp(s);
4972
4973 /* MP header */
4974 stream_putc(s, 0); /* Marker: Attribute length. */
4975 stream_putw(s, AFI_IP6); /* AFI */
4976 stream_putc(s, SAFI_UNICAST); /* SAFI */
4977
4978 /* Next hop */
4979 stream_putc(s, attr->mp_nexthop_len);
4980 stream_put(s, &attr->mp_nexthop_global, IPV6_MAX_BYTELEN);
4981 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
4982 stream_put(s, &attr->mp_nexthop_local,
4983 IPV6_MAX_BYTELEN);
4984
4985 /* SNPA */
4986 stream_putc(s, 0);
4987
4988 /* Prefix */
4989 stream_put_prefix_addpath(s, prefix, addpath_capable,
4990 addpath_tx_id);
4991
4992 /* Set MP attribute length. */
4993 stream_putc_at(s, sizep, (stream_get_endp(s) - sizep) - 1);
4994 }
4995
4996 /* Prefix SID */
4997 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) {
4998 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
4999 stream_putc(s,
5000 BGP_ATTR_FLAG_OPTIONAL
5001 | BGP_ATTR_FLAG_TRANS);
5002 stream_putc(s, BGP_ATTR_PREFIX_SID);
5003 stream_putc(s, 10);
5004 stream_putc(s, BGP_PREFIX_SID_LABEL_INDEX);
5005 stream_putc(s, BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
5006 stream_putc(s, 0); // reserved
5007 stream_putw(s, 0); // flags
5008 stream_putl(s, attr->label_index);
5009 }
5010 }
5011
5012 /* OTC */
5013 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
5014 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
5015 stream_putc(s, BGP_ATTR_OTC);
5016 stream_putc(s, 4);
5017 stream_putl(s, attr->otc);
5018 }
5019
5020 /* AIGP */
5021 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP)) {
5022 /* At the moment only AIGP Metric TLV exists for AIGP
5023 * attribute. If more comes in, do not forget to update
5024 * attr_len variable to include new ones.
5025 */
5026 uint8_t attr_len = BGP_AIGP_TLV_METRIC_LEN;
5027
5028 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
5029 stream_putc(s, BGP_ATTR_AIGP);
5030 stream_putc(s, attr_len);
5031 stream_put_bgp_aigp_tlv_metric(s, bpi);
5032 }
5033
5034 /* Return total size of attribute. */
5035 len = stream_get_endp(s) - cp - 2;
5036 stream_putw_at(s, cp, len);
5037 }
5038
5039 void bgp_path_attribute_discard_vty(struct vty *vty, struct peer *peer,
5040 const char *discard_attrs, bool set)
5041 {
5042 int i, num_attributes;
5043 char **attributes;
5044 afi_t afi;
5045 safi_t safi;
5046
5047
5048 /* If `no` command specified without arbitrary attributes,
5049 * then flush all.
5050 */
5051 if (!discard_attrs) {
5052 for (i = 0; i < BGP_ATTR_MAX; i++)
5053 peer->discard_attrs[i] = false;
5054 goto discard_soft_clear;
5055 }
5056
5057 if (discard_attrs) {
5058 frrstr_split(discard_attrs, " ", &attributes, &num_attributes);
5059
5060 if (set)
5061 for (i = 0; i < BGP_ATTR_MAX; i++)
5062 peer->discard_attrs[i] = false;
5063
5064 for (i = 0; i < num_attributes; i++) {
5065 uint8_t attr_num = strtoul(attributes[i], NULL, 10);
5066
5067 XFREE(MTYPE_TMP, attributes[i]);
5068
5069 /* Some of the attributes, just can't be ignored. */
5070 if (attr_num == BGP_ATTR_ORIGIN ||
5071 attr_num == BGP_ATTR_AS_PATH ||
5072 attr_num == BGP_ATTR_NEXT_HOP ||
5073 attr_num == BGP_ATTR_MULTI_EXIT_DISC ||
5074 attr_num == BGP_ATTR_MP_REACH_NLRI ||
5075 attr_num == BGP_ATTR_MP_UNREACH_NLRI ||
5076 attr_num == BGP_ATTR_EXT_COMMUNITIES) {
5077 vty_out(vty,
5078 "%% Can't discard path-attribute %s, ignoring.\n",
5079 lookup_msg(attr_str, attr_num, NULL));
5080 continue;
5081 }
5082
5083 /* Ignore local-pref, originator-id, cluster-list only
5084 * for eBGP.
5085 */
5086 if (peer->sort != BGP_PEER_EBGP &&
5087 (attr_num == BGP_ATTR_LOCAL_PREF ||
5088 attr_num == BGP_ATTR_ORIGINATOR_ID ||
5089 attr_num == BGP_ATTR_CLUSTER_LIST)) {
5090 vty_out(vty,
5091 "%% Can discard path-attribute %s only for eBGP, ignoring.\n",
5092 lookup_msg(attr_str, attr_num, NULL));
5093 continue;
5094 }
5095
5096 peer->discard_attrs[attr_num] = set;
5097 }
5098 XFREE(MTYPE_TMP, attributes);
5099 discard_soft_clear:
5100 /* Configuring path attributes to be discarded will trigger
5101 * an inbound Route Refresh to ensure that the routing table
5102 * is up to date.
5103 */
5104 FOREACH_AFI_SAFI (afi, safi)
5105 peer_clear_soft(peer, afi, safi, BGP_CLEAR_SOFT_IN);
5106 }
5107 }
5108
5109 void bgp_path_attribute_withdraw_vty(struct vty *vty, struct peer *peer,
5110 const char *withdraw_attrs, bool set)
5111 {
5112 int i, num_attributes;
5113 char **attributes;
5114 afi_t afi;
5115 safi_t safi;
5116
5117 /* If `no` command specified without arbitrary attributes,
5118 * then flush all.
5119 */
5120 if (!withdraw_attrs) {
5121 for (i = 0; i < BGP_ATTR_MAX; i++)
5122 peer->withdraw_attrs[i] = false;
5123 goto withdraw_soft_clear;
5124 }
5125
5126 if (withdraw_attrs) {
5127 frrstr_split(withdraw_attrs, " ", &attributes, &num_attributes);
5128
5129 if (set)
5130 for (i = 0; i < BGP_ATTR_MAX; i++)
5131 peer->withdraw_attrs[i] = false;
5132
5133 for (i = 0; i < num_attributes; i++) {
5134 uint8_t attr_num = strtoul(attributes[i], NULL, 10);
5135
5136 XFREE(MTYPE_TMP, attributes[i]);
5137
5138 /* Some of the attributes, just can't be ignored. */
5139 if (attr_num == BGP_ATTR_ORIGIN ||
5140 attr_num == BGP_ATTR_AS_PATH ||
5141 attr_num == BGP_ATTR_NEXT_HOP ||
5142 attr_num == BGP_ATTR_MULTI_EXIT_DISC ||
5143 attr_num == BGP_ATTR_MP_REACH_NLRI ||
5144 attr_num == BGP_ATTR_MP_UNREACH_NLRI ||
5145 attr_num == BGP_ATTR_EXT_COMMUNITIES) {
5146 vty_out(vty,
5147 "%% Can't treat-as-withdraw path-attribute %s, ignoring.\n",
5148 lookup_msg(attr_str, attr_num, NULL));
5149 continue;
5150 }
5151
5152 /* Ignore local-pref, originator-id, cluster-list only
5153 * for eBGP.
5154 */
5155 if (peer->sort != BGP_PEER_EBGP &&
5156 (attr_num == BGP_ATTR_LOCAL_PREF ||
5157 attr_num == BGP_ATTR_ORIGINATOR_ID ||
5158 attr_num == BGP_ATTR_CLUSTER_LIST)) {
5159 vty_out(vty,
5160 "%% Can treat-as-withdraw path-attribute %s only for eBGP, ignoring.\n",
5161 lookup_msg(attr_str, attr_num, NULL));
5162 continue;
5163 }
5164
5165 peer->withdraw_attrs[attr_num] = set;
5166 }
5167 XFREE(MTYPE_TMP, attributes);
5168 withdraw_soft_clear:
5169 /* Configuring path attributes to be treated as withdraw will
5170 * trigger
5171 * an inbound Route Refresh to ensure that the routing table
5172 * is up to date.
5173 */
5174 FOREACH_AFI_SAFI (afi, safi)
5175 peer_clear_soft(peer, afi, safi, BGP_CLEAR_SOFT_IN);
5176 }
5177 }
5178
5179 enum bgp_attr_parse_ret bgp_attr_ignore(struct peer *peer, uint8_t type)
5180 {
5181 bool discard = peer->discard_attrs[type];
5182 bool withdraw = peer->withdraw_attrs[type];
5183
5184 if (bgp_debug_update(peer, NULL, NULL, 1) && (discard || withdraw))
5185 zlog_debug("%pBP: Ignoring attribute %s (%s)", peer,
5186 lookup_msg(attr_str, type, NULL),
5187 withdraw ? "treat-as-withdraw" : "discard");
5188
5189 return withdraw ? BGP_ATTR_PARSE_WITHDRAW : BGP_ATTR_PARSE_PROCEED;
5190 }