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