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