]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_attr.c
bgpd: inet_ntop() adjustments
[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 loc_block_len = stream_getc(peer->curr);
2706 loc_node_len = stream_getc(peer->curr);
2707 func_len = stream_getc(peer->curr);
2708 arg_len = stream_getc(peer->curr);
2709 transposition_len = stream_getc(peer->curr);
2710 transposition_offset = stream_getc(peer->curr);
2711
2712 /* Log SRv6 Service Data Sub-Sub-TLV */
2713 if (BGP_DEBUG(vpn, VPN_LEAK_LABEL)) {
2714 zlog_debug(
2715 "%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",
2716 __func__, loc_block_len, loc_node_len, func_len,
2717 arg_len, transposition_len,
2718 transposition_offset);
2719 }
2720
2721 attr->srv6_l3vpn->loc_block_len = loc_block_len;
2722 attr->srv6_l3vpn->loc_node_len = loc_node_len;
2723 attr->srv6_l3vpn->func_len = func_len;
2724 attr->srv6_l3vpn->arg_len = arg_len;
2725 attr->srv6_l3vpn->transposition_len = transposition_len;
2726 attr->srv6_l3vpn->transposition_offset = transposition_offset;
2727 }
2728
2729 else {
2730 if (bgp_debug_update(peer, NULL, NULL, 1))
2731 zlog_debug(
2732 "%s attr SRv6 Service Data Sub-Sub-TLV sub-sub-type=%u is not supported, skipped",
2733 peer->host, type);
2734
2735 stream_forward_getp(peer->curr, length);
2736 }
2737
2738 return BGP_ATTR_PARSE_PROCEED;
2739 }
2740
2741 /* SRv6 Service Sub-TLV attribute
2742 * draft-ietf-bess-srv6-services-07
2743 */
2744 static enum bgp_attr_parse_ret
2745 bgp_attr_srv6_service(struct bgp_attr_parser_args *args)
2746 {
2747 struct peer *const peer = args->peer;
2748 struct attr *const attr = args->attr;
2749 struct in6_addr ipv6_sid;
2750 uint8_t type, sid_flags;
2751 uint16_t length, endpoint_behavior;
2752 size_t headersz = sizeof(type) + sizeof(length);
2753 enum bgp_attr_parse_ret err;
2754
2755 if (STREAM_READABLE(peer->curr) < headersz) {
2756 flog_err(
2757 EC_BGP_ATTR_LEN,
2758 "Malformed SRv6 Service Sub-TLV attribute - insufficent data (need %zu for attribute header, have %zu remaining in UPDATE)",
2759 headersz, STREAM_READABLE(peer->curr));
2760 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2761 args->total);
2762 }
2763
2764 type = stream_getc(peer->curr);
2765 length = stream_getw(peer->curr);
2766
2767 if (STREAM_READABLE(peer->curr) < length) {
2768 flog_err(
2769 EC_BGP_ATTR_LEN,
2770 "Malformed SRv6 Service Sub-TLV attribute - insufficent data (need %hu for attribute data, have %zu remaining in UPDATE)",
2771 length, STREAM_READABLE(peer->curr));
2772 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2773 args->total);
2774 }
2775
2776 if (type == BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_INFO) {
2777 stream_getc(peer->curr);
2778 stream_get(&ipv6_sid, peer->curr, sizeof(ipv6_sid));
2779 sid_flags = stream_getc(peer->curr);
2780 endpoint_behavior = stream_getw(peer->curr);
2781 stream_getc(peer->curr);
2782
2783 /* Log SRv6 Service Sub-TLV */
2784 if (BGP_DEBUG(vpn, VPN_LEAK_LABEL))
2785 zlog_debug(
2786 "%s: srv6-l3-srv sid %pI6, sid-flags 0x%02x, end-behaviour 0x%04x",
2787 __func__, &ipv6_sid, sid_flags,
2788 endpoint_behavior);
2789
2790 /* Configure from Info */
2791 if (attr->srv6_l3vpn) {
2792 flog_err(EC_BGP_ATTRIBUTE_REPEATED,
2793 "Prefix SID SRv6 L3VPN field repeated");
2794 return bgp_attr_malformed(
2795 args, BGP_NOTIFY_UPDATE_MAL_ATTR, args->total);
2796 }
2797 attr->srv6_l3vpn = XCALLOC(MTYPE_BGP_SRV6_L3VPN,
2798 sizeof(struct bgp_attr_srv6_l3vpn));
2799 sid_copy(&attr->srv6_l3vpn->sid, &ipv6_sid);
2800 attr->srv6_l3vpn->sid_flags = sid_flags;
2801 attr->srv6_l3vpn->endpoint_behavior = endpoint_behavior;
2802 attr->srv6_l3vpn->loc_block_len = 0;
2803 attr->srv6_l3vpn->loc_node_len = 0;
2804 attr->srv6_l3vpn->func_len = 0;
2805 attr->srv6_l3vpn->arg_len = 0;
2806 attr->srv6_l3vpn->transposition_len = 0;
2807 attr->srv6_l3vpn->transposition_offset = 0;
2808
2809 // Sub-Sub-TLV found
2810 if (length > BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_INFO_LENGTH) {
2811 err = bgp_attr_srv6_service_data(args);
2812
2813 if (err != BGP_ATTR_PARSE_PROCEED)
2814 return err;
2815 }
2816
2817 attr->srv6_l3vpn = srv6_l3vpn_intern(attr->srv6_l3vpn);
2818 }
2819
2820 /* Placeholder code for unsupported type */
2821 else {
2822 if (bgp_debug_update(peer, NULL, NULL, 1))
2823 zlog_debug(
2824 "%s attr SRv6 Service Sub-TLV sub-type=%u is not supported, skipped",
2825 peer->host, type);
2826
2827 stream_forward_getp(peer->curr, length);
2828 }
2829
2830 return BGP_ATTR_PARSE_PROCEED;
2831 }
2832
2833 /*
2834 * Read an individual SID value returning how much data we have read
2835 * Returns 0 if there was an error that needs to be passed up the stack
2836 */
2837 static enum bgp_attr_parse_ret
2838 bgp_attr_psid_sub(uint8_t type, uint16_t length,
2839 struct bgp_attr_parser_args *args)
2840 {
2841 struct peer *const peer = args->peer;
2842 struct attr *const attr = args->attr;
2843 uint32_t label_index;
2844 struct in6_addr ipv6_sid;
2845 uint32_t srgb_base;
2846 uint32_t srgb_range;
2847 int srgb_count;
2848 uint8_t sid_type, sid_flags;
2849
2850 if (type == BGP_PREFIX_SID_LABEL_INDEX) {
2851 if (STREAM_READABLE(peer->curr) < length
2852 || length != BGP_PREFIX_SID_LABEL_INDEX_LENGTH) {
2853 flog_err(EC_BGP_ATTR_LEN,
2854 "Prefix SID label index length is %hu instead of %u",
2855 length, BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
2856 return bgp_attr_malformed(args,
2857 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2858 args->total);
2859 }
2860
2861 /* Ignore flags and reserved */
2862 stream_getc(peer->curr);
2863 stream_getw(peer->curr);
2864
2865 /* Fetch the label index and see if it is valid. */
2866 label_index = stream_getl(peer->curr);
2867 if (label_index == BGP_INVALID_LABEL_INDEX)
2868 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2869 args->total);
2870
2871 /* Store label index; subsequently, we'll check on
2872 * address-family */
2873 attr->label_index = label_index;
2874 }
2875
2876 /* Placeholder code for the IPv6 SID type */
2877 else if (type == BGP_PREFIX_SID_IPV6) {
2878 if (STREAM_READABLE(peer->curr) < length
2879 || length != BGP_PREFIX_SID_IPV6_LENGTH) {
2880 flog_err(EC_BGP_ATTR_LEN,
2881 "Prefix SID IPv6 length is %hu instead of %u",
2882 length, BGP_PREFIX_SID_IPV6_LENGTH);
2883 return bgp_attr_malformed(args,
2884 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2885 args->total);
2886 }
2887
2888 /* Ignore reserved */
2889 stream_getc(peer->curr);
2890 stream_getw(peer->curr);
2891
2892 stream_get(&ipv6_sid, peer->curr, 16);
2893 }
2894
2895 /* Placeholder code for the Originator SRGB type */
2896 else if (type == BGP_PREFIX_SID_ORIGINATOR_SRGB) {
2897 /*
2898 * ietf-idr-bgp-prefix-sid-05:
2899 * Length is the total length of the value portion of the
2900 * TLV: 2 + multiple of 6.
2901 *
2902 * peer->curr stream readp should be at the beginning of the 16
2903 * bit flag field at this point in the code.
2904 */
2905
2906 /*
2907 * Check that the TLV length field is sane: at least 2 bytes of
2908 * flag, and at least 1 SRGB (these are 6 bytes each)
2909 */
2910 if (length < (2 + BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH)) {
2911 flog_err(
2912 EC_BGP_ATTR_LEN,
2913 "Prefix SID Originator SRGB length field claims length of %hu bytes, but the minimum for this TLV type is %u",
2914 length,
2915 2 + BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH);
2916 return bgp_attr_malformed(
2917 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2918 args->total);
2919 }
2920
2921 /*
2922 * Check that we actually have at least as much data as
2923 * specified by the length field
2924 */
2925 if (STREAM_READABLE(peer->curr) < length) {
2926 flog_err(EC_BGP_ATTR_LEN,
2927 "Prefix SID Originator SRGB specifies length %hu, but only %zu bytes remain",
2928 length, STREAM_READABLE(peer->curr));
2929 return bgp_attr_malformed(
2930 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2931 args->total);
2932 }
2933
2934 /*
2935 * Check that the portion of the TLV containing the sequence of
2936 * SRGBs corresponds to a multiple of the SRGB size; to get
2937 * that length, we skip the 16 bit flags field
2938 */
2939 stream_getw(peer->curr);
2940 length -= 2;
2941 if (length % BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH) {
2942 flog_err(
2943 EC_BGP_ATTR_LEN,
2944 "Prefix SID Originator SRGB length field claims attribute SRGB sequence section is %hubytes, but it must be a multiple of %u",
2945 length, BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH);
2946 return bgp_attr_malformed(
2947 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2948 args->total);
2949 }
2950
2951 srgb_count = length / BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH;
2952
2953 for (int i = 0; i < srgb_count; i++) {
2954 stream_get(&srgb_base, peer->curr, 3);
2955 stream_get(&srgb_range, peer->curr, 3);
2956 }
2957 }
2958
2959 /* Placeholder code for the VPN-SID Service type */
2960 else if (type == BGP_PREFIX_SID_VPN_SID) {
2961 if (STREAM_READABLE(peer->curr) < length
2962 || length != BGP_PREFIX_SID_VPN_SID_LENGTH) {
2963 flog_err(EC_BGP_ATTR_LEN,
2964 "Prefix SID VPN SID length is %hu instead of %u",
2965 length, BGP_PREFIX_SID_VPN_SID_LENGTH);
2966 return bgp_attr_malformed(args,
2967 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2968 args->total);
2969 }
2970
2971 /* Parse VPN-SID Sub-TLV */
2972 stream_getc(peer->curr); /* reserved */
2973 sid_type = stream_getc(peer->curr); /* sid_type */
2974 sid_flags = stream_getc(peer->curr); /* sid_flags */
2975 stream_get(&ipv6_sid, peer->curr,
2976 sizeof(ipv6_sid)); /* sid_value */
2977
2978 /* Log VPN-SID Sub-TLV */
2979 if (BGP_DEBUG(vpn, VPN_LEAK_LABEL))
2980 zlog_debug(
2981 "%s: vpn-sid: sid %pI6, sid-type 0x%02x sid-flags 0x%02x",
2982 __func__, &ipv6_sid, sid_type, sid_flags);
2983
2984 /* Configure from Info */
2985 if (attr->srv6_vpn) {
2986 flog_err(EC_BGP_ATTRIBUTE_REPEATED,
2987 "Prefix SID SRv6 VPN field repeated");
2988 return bgp_attr_malformed(
2989 args, BGP_NOTIFY_UPDATE_MAL_ATTR, args->total);
2990 }
2991 attr->srv6_vpn = XCALLOC(MTYPE_BGP_SRV6_VPN,
2992 sizeof(struct bgp_attr_srv6_vpn));
2993 attr->srv6_vpn->sid_flags = sid_flags;
2994 sid_copy(&attr->srv6_vpn->sid, &ipv6_sid);
2995 attr->srv6_vpn = srv6_vpn_intern(attr->srv6_vpn);
2996 }
2997
2998 /* Placeholder code for the SRv6 L3 Service type */
2999 else if (type == BGP_PREFIX_SID_SRV6_L3_SERVICE) {
3000 if (STREAM_READABLE(peer->curr) < length) {
3001 flog_err(
3002 EC_BGP_ATTR_LEN,
3003 "Prefix SID SRv6 L3-Service length is %hu, but only %zu bytes remain",
3004 length, STREAM_READABLE(peer->curr));
3005 return bgp_attr_malformed(args,
3006 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3007 args->total);
3008 }
3009
3010 /* ignore reserved */
3011 stream_getc(peer->curr);
3012
3013 return bgp_attr_srv6_service(args);
3014 }
3015
3016 /* Placeholder code for Unsupported TLV */
3017 else {
3018
3019 if (STREAM_READABLE(peer->curr) < length) {
3020 flog_err(
3021 EC_BGP_ATTR_LEN,
3022 "Prefix SID SRv6 length is %hu - too long, only %zu remaining in this UPDATE",
3023 length, STREAM_READABLE(peer->curr));
3024 return bgp_attr_malformed(
3025 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3026 args->total);
3027 }
3028
3029 if (bgp_debug_update(peer, NULL, NULL, 1))
3030 zlog_debug(
3031 "%s attr Prefix-SID sub-type=%u is not supported, skipped",
3032 peer->host, type);
3033
3034 stream_forward_getp(peer->curr, length);
3035 }
3036
3037 return BGP_ATTR_PARSE_PROCEED;
3038 }
3039
3040 /* Prefix SID attribute
3041 * draft-ietf-idr-bgp-prefix-sid-05
3042 */
3043 enum bgp_attr_parse_ret bgp_attr_prefix_sid(struct bgp_attr_parser_args *args)
3044 {
3045 struct peer *const peer = args->peer;
3046 struct attr *const attr = args->attr;
3047 enum bgp_attr_parse_ret ret;
3048
3049 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
3050
3051 uint8_t type;
3052 uint16_t length;
3053 size_t headersz = sizeof(type) + sizeof(length);
3054 size_t psid_parsed_length = 0;
3055
3056 while (STREAM_READABLE(peer->curr) > 0
3057 && psid_parsed_length < args->length) {
3058
3059 if (STREAM_READABLE(peer->curr) < headersz) {
3060 flog_err(
3061 EC_BGP_ATTR_LEN,
3062 "Malformed Prefix SID attribute - insufficent data (need %zu for attribute header, have %zu remaining in UPDATE)",
3063 headersz, STREAM_READABLE(peer->curr));
3064 return bgp_attr_malformed(
3065 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3066 args->total);
3067 }
3068
3069 type = stream_getc(peer->curr);
3070 length = stream_getw(peer->curr);
3071
3072 if (STREAM_READABLE(peer->curr) < length) {
3073 flog_err(
3074 EC_BGP_ATTR_LEN,
3075 "Malformed Prefix SID attribute - insufficient data (need %hu for attribute body, have %zu remaining in UPDATE)",
3076 length, STREAM_READABLE(peer->curr));
3077 return bgp_attr_malformed(args,
3078 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3079 args->total);
3080 }
3081
3082 ret = bgp_attr_psid_sub(type, length, args);
3083
3084 if (ret != BGP_ATTR_PARSE_PROCEED)
3085 return ret;
3086
3087 psid_parsed_length += length + headersz;
3088
3089 if (psid_parsed_length > args->length) {
3090 flog_err(
3091 EC_BGP_ATTR_LEN,
3092 "Malformed Prefix SID attribute - TLV overflow by attribute (need %zu for TLV length, have %zu overflowed in UPDATE)",
3093 length + headersz, psid_parsed_length - (length + headersz));
3094 return bgp_attr_malformed(
3095 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3096 args->total);
3097 }
3098 }
3099
3100 return BGP_ATTR_PARSE_PROCEED;
3101 }
3102
3103 /* PMSI tunnel attribute (RFC 6514)
3104 * Basic validation checks done here.
3105 */
3106 static enum bgp_attr_parse_ret
3107 bgp_attr_pmsi_tunnel(struct bgp_attr_parser_args *args)
3108 {
3109 struct peer *const peer = args->peer;
3110 struct attr *const attr = args->attr;
3111 const bgp_size_t length = args->length;
3112 uint8_t tnl_type;
3113 int attr_parse_len = 2 + BGP_LABEL_BYTES;
3114
3115 /* Verify that the receiver is expecting "ingress replication" as we
3116 * can only support that.
3117 */
3118 if (length < attr_parse_len) {
3119 flog_err(EC_BGP_ATTR_LEN, "Bad PMSI tunnel attribute length %d",
3120 length);
3121 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3122 args->total);
3123 }
3124 stream_getc(peer->curr); /* Flags */
3125 tnl_type = stream_getc(peer->curr);
3126 if (tnl_type > PMSI_TNLTYPE_MAX) {
3127 flog_err(EC_BGP_ATTR_PMSI_TYPE,
3128 "Invalid PMSI tunnel attribute type %d", tnl_type);
3129 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
3130 args->total);
3131 }
3132 if (tnl_type == PMSI_TNLTYPE_INGR_REPL) {
3133 if (length != 9) {
3134 flog_err(EC_BGP_ATTR_PMSI_LEN,
3135 "Bad PMSI tunnel attribute length %d for IR",
3136 length);
3137 return bgp_attr_malformed(
3138 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3139 args->total);
3140 }
3141 }
3142
3143 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL);
3144 bgp_attr_set_pmsi_tnl_type(attr, tnl_type);
3145 stream_get(&attr->label, peer->curr, BGP_LABEL_BYTES);
3146
3147 /* Forward read pointer of input stream. */
3148 stream_forward_getp(peer->curr, length - attr_parse_len);
3149
3150 return BGP_ATTR_PARSE_PROCEED;
3151 }
3152
3153 /* AIGP attribute (rfc7311) */
3154 static enum bgp_attr_parse_ret bgp_attr_aigp(struct bgp_attr_parser_args *args)
3155 {
3156 struct peer *const peer = args->peer;
3157 struct attr *const attr = args->attr;
3158 const bgp_size_t length = args->length;
3159 uint8_t *s = stream_pnt(peer->curr);
3160 uint64_t aigp = 0;
3161
3162 /* If an AIGP attribute is received on a BGP session for which
3163 * AIGP_SESSION is disabled, the attribute MUST be treated exactly
3164 * as if it were an unrecognized non-transitive attribute.
3165 * That is, it "MUST be quietly ignored and not passed along to
3166 * other BGP peers".
3167 * For Internal BGP (IBGP) sessions, and for External BGP (EBGP)
3168 * sessions between members of the same BGP Confederation,
3169 * the default value of AIGP_SESSION SHOULD be "enabled".
3170 */
3171 if (peer->sort == BGP_PEER_EBGP &&
3172 !CHECK_FLAG(peer->flags, PEER_FLAG_AIGP)) {
3173 zlog_warn(
3174 "%pBP received AIGP attribute, but eBGP peer do not support it",
3175 peer);
3176 goto aigp_ignore;
3177 }
3178
3179 if (!bgp_attr_aigp_valid(s, length))
3180 goto aigp_ignore;
3181
3182 /* Extract AIGP Metric TLV */
3183 if (bgp_attr_aigp_get_tlv_metric(s, length, &aigp))
3184 bgp_attr_set_aigp_metric(attr, aigp);
3185
3186 aigp_ignore:
3187 stream_forward_getp(peer->curr, length);
3188
3189 return BGP_ATTR_PARSE_PROCEED;
3190 }
3191
3192 /* OTC attribute. */
3193 static enum bgp_attr_parse_ret bgp_attr_otc(struct bgp_attr_parser_args *args)
3194 {
3195 struct peer *const peer = args->peer;
3196 struct attr *const attr = args->attr;
3197 const bgp_size_t length = args->length;
3198
3199 /* Length check. */
3200 if (length != 4) {
3201 flog_err(EC_BGP_ATTR_LEN, "OTC attribute length isn't 4 [%u]",
3202 length);
3203 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3204 args->total);
3205 }
3206
3207 attr->otc = stream_getl(peer->curr);
3208 if (!attr->otc) {
3209 flog_err(EC_BGP_ATTR_MAL_AS_PATH, "OTC attribute value is 0");
3210 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_MAL_AS_PATH,
3211 args->total);
3212 }
3213
3214 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
3215
3216 return BGP_ATTR_PARSE_PROCEED;
3217 }
3218
3219 /* BGP unknown attribute treatment. */
3220 static enum bgp_attr_parse_ret
3221 bgp_attr_unknown(struct bgp_attr_parser_args *args)
3222 {
3223 bgp_size_t total = args->total;
3224 struct transit *transit;
3225 struct peer *const peer = args->peer;
3226 struct attr *const attr = args->attr;
3227 uint8_t *const startp = args->startp;
3228 const uint8_t type = args->type;
3229 const uint8_t flag = args->flags;
3230 const bgp_size_t length = args->length;
3231
3232 if (bgp_debug_update(peer, NULL, NULL, 1))
3233 zlog_debug(
3234 "%s Unknown attribute is received (type %d, length %d)",
3235 peer->host, type, length);
3236
3237 /* Forward read pointer of input stream. */
3238 stream_forward_getp(peer->curr, length);
3239
3240 /* If any of the mandatory well-known attributes are not recognized,
3241 then the Error Subcode is set to Unrecognized Well-known
3242 Attribute. The Data field contains the unrecognized attribute
3243 (type, length and value). */
3244 if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL)) {
3245 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_UNREC_ATTR,
3246 args->total);
3247 }
3248
3249 /* Unrecognized non-transitive optional attributes must be quietly
3250 ignored and not passed along to other BGP peers. */
3251 if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS))
3252 return BGP_ATTR_PARSE_PROCEED;
3253
3254 /* If a path with recognized transitive optional attribute is
3255 accepted and passed along to other BGP peers and the Partial bit
3256 in the Attribute Flags octet is set to 1 by some previous AS, it
3257 is not set back to 0 by the current AS. */
3258 SET_FLAG(*startp, BGP_ATTR_FLAG_PARTIAL);
3259
3260 /* Store transitive attribute to the end of attr->transit. */
3261 transit = bgp_attr_get_transit(attr);
3262 if (!transit)
3263 transit = XCALLOC(MTYPE_TRANSIT, sizeof(struct transit));
3264
3265 transit->val = XREALLOC(MTYPE_TRANSIT_VAL, transit->val,
3266 transit->length + total);
3267
3268 memcpy(transit->val + transit->length, startp, total);
3269 transit->length += total;
3270 bgp_attr_set_transit(attr, transit);
3271
3272 return BGP_ATTR_PARSE_PROCEED;
3273 }
3274
3275 /* Well-known attribute check. */
3276 static int bgp_attr_check(struct peer *peer, struct attr *attr)
3277 {
3278 uint8_t type = 0;
3279
3280 /* BGP Graceful-Restart End-of-RIB for IPv4 unicast is signaled as an
3281 * empty UPDATE. */
3282 if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV) && !attr->flag)
3283 return BGP_ATTR_PARSE_PROCEED;
3284
3285 /* "An UPDATE message that contains the MP_UNREACH_NLRI is not required
3286 to carry any other path attributes.", though if MP_REACH_NLRI or NLRI
3287 are present, it should. Check for any other attribute being present
3288 instead.
3289 */
3290 if ((!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI)) &&
3291 CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI))))
3292 return BGP_ATTR_PARSE_PROCEED;
3293
3294 if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGIN)))
3295 type = BGP_ATTR_ORIGIN;
3296
3297 if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AS_PATH)))
3298 type = BGP_ATTR_AS_PATH;
3299
3300 /* RFC 2858 makes Next-Hop optional/ignored, if MP_REACH_NLRI is present
3301 * and
3302 * NLRI is empty. We can't easily check NLRI empty here though.
3303 */
3304 if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP))
3305 && !CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI)))
3306 type = BGP_ATTR_NEXT_HOP;
3307
3308 if (peer->sort == BGP_PEER_IBGP
3309 && !CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))
3310 type = BGP_ATTR_LOCAL_PREF;
3311
3312 /* If any of the well-known mandatory attributes are not present
3313 * in an UPDATE message, then "treat-as-withdraw" MUST be used.
3314 */
3315 if (type) {
3316 flog_warn(EC_BGP_MISSING_ATTRIBUTE,
3317 "%s Missing well-known attribute %s.", peer->host,
3318 lookup_msg(attr_str, type, NULL));
3319 return BGP_ATTR_PARSE_WITHDRAW;
3320 }
3321 return BGP_ATTR_PARSE_PROCEED;
3322 }
3323
3324 /* Read attribute of update packet. This function is called from
3325 bgp_update_receive() in bgp_packet.c. */
3326 enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr,
3327 bgp_size_t size,
3328 struct bgp_nlri *mp_update,
3329 struct bgp_nlri *mp_withdraw)
3330 {
3331 enum bgp_attr_parse_ret ret;
3332 uint8_t flag = 0;
3333 uint8_t type = 0;
3334 bgp_size_t length;
3335 uint8_t *startp, *endp;
3336 uint8_t *attr_endp;
3337 uint8_t seen[BGP_ATTR_BITMAP_SIZE];
3338 /* we need the as4_path only until we have synthesized the as_path with
3339 * it */
3340 /* same goes for as4_aggregator */
3341 struct aspath *as4_path = NULL;
3342 as_t as4_aggregator = 0;
3343 struct in_addr as4_aggregator_addr = {.s_addr = 0};
3344 struct transit *transit;
3345
3346 /* Initialize bitmap. */
3347 memset(seen, 0, BGP_ATTR_BITMAP_SIZE);
3348
3349 /* End pointer of BGP attribute. */
3350 endp = BGP_INPUT_PNT(peer) + size;
3351
3352 /* Get attributes to the end of attribute length. */
3353 while (BGP_INPUT_PNT(peer) < endp) {
3354 /* Check remaining length check.*/
3355 if (endp - BGP_INPUT_PNT(peer) < BGP_ATTR_MIN_LEN) {
3356 /* XXX warning: long int format, int arg (arg 5) */
3357 flog_warn(
3358 EC_BGP_ATTRIBUTE_TOO_SMALL,
3359 "%s: error BGP attribute length %lu is smaller than min len",
3360 peer->host,
3361 (unsigned long)(endp
3362 - stream_pnt(BGP_INPUT(peer))));
3363
3364 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3365 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
3366 ret = BGP_ATTR_PARSE_ERROR;
3367 goto done;
3368 }
3369
3370 /* Fetch attribute flag and type. */
3371 startp = BGP_INPUT_PNT(peer);
3372 /* "The lower-order four bits of the Attribute Flags octet are
3373 unused. They MUST be zero when sent and MUST be ignored when
3374 received." */
3375 flag = 0xF0 & stream_getc(BGP_INPUT(peer));
3376 type = stream_getc(BGP_INPUT(peer));
3377
3378 /* Check whether Extended-Length applies and is in bounds */
3379 if (CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN)
3380 && ((endp - startp) < (BGP_ATTR_MIN_LEN + 1))) {
3381 flog_warn(
3382 EC_BGP_EXT_ATTRIBUTE_TOO_SMALL,
3383 "%s: Extended length set, but just %lu bytes of attr header",
3384 peer->host,
3385 (unsigned long)(endp
3386 - stream_pnt(BGP_INPUT(peer))));
3387
3388 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3389 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
3390 ret = BGP_ATTR_PARSE_ERROR;
3391 goto done;
3392 }
3393
3394 /* Check extended attribue length bit. */
3395 if (CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN))
3396 length = stream_getw(BGP_INPUT(peer));
3397 else
3398 length = stream_getc(BGP_INPUT(peer));
3399
3400 /* If any attribute appears more than once in the UPDATE
3401 message, then the Error Subcode is set to Malformed Attribute
3402 List. */
3403
3404 if (CHECK_BITMAP(seen, type)) {
3405 flog_warn(
3406 EC_BGP_ATTRIBUTE_REPEATED,
3407 "%s: error BGP attribute type %d appears twice in a message",
3408 peer->host, type);
3409
3410 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3411 BGP_NOTIFY_UPDATE_MAL_ATTR);
3412 ret = BGP_ATTR_PARSE_ERROR;
3413 goto done;
3414 }
3415
3416 /* Set type to bitmap to check duplicate attribute. `type' is
3417 unsigned char so it never overflow bitmap range. */
3418
3419 SET_BITMAP(seen, type);
3420
3421 /* Overflow check. */
3422 attr_endp = BGP_INPUT_PNT(peer) + length;
3423
3424 if (attr_endp > endp) {
3425 flog_warn(
3426 EC_BGP_ATTRIBUTE_TOO_LARGE,
3427 "%s: BGP type %d length %d is too large, attribute total length is %d. attr_endp is %p. endp is %p",
3428 peer->host, type, length, size, attr_endp,
3429 endp);
3430 /*
3431 * RFC 4271 6.3
3432 * If any recognized attribute has an Attribute
3433 * Length that conflicts with the expected length
3434 * (based on the attribute type code), then the
3435 * Error Subcode MUST be set to Attribute Length
3436 * Error. The Data field MUST contain the erroneous
3437 * attribute (type, length, and value).
3438 * ----------
3439 * We do not currently have a good way to determine the
3440 * length of the attribute independent of the length
3441 * received in the message. Instead we send the
3442 * minimum between the amount of data we have and the
3443 * amount specified by the attribute length field.
3444 *
3445 * Instead of directly passing in the packet buffer and
3446 * offset we use the stream_get* functions to read into
3447 * a stack buffer, since they perform bounds checking
3448 * and we are working with untrusted data.
3449 */
3450 unsigned char ndata[peer->max_packet_size];
3451 memset(ndata, 0x00, sizeof(ndata));
3452 size_t lfl =
3453 CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN) ? 2 : 1;
3454 /* Rewind to end of flag field */
3455 stream_rewind_getp(BGP_INPUT(peer), (1 + lfl));
3456 /* Type */
3457 stream_get(&ndata[0], BGP_INPUT(peer), 1);
3458 /* Length */
3459 stream_get(&ndata[1], BGP_INPUT(peer), lfl);
3460 /* Value */
3461 size_t atl = attr_endp - startp;
3462 size_t ndl = MIN(atl, STREAM_READABLE(BGP_INPUT(peer)));
3463 stream_get(&ndata[lfl + 1], BGP_INPUT(peer), ndl);
3464
3465 bgp_notify_send_with_data(
3466 peer, BGP_NOTIFY_UPDATE_ERR,
3467 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, ndata,
3468 ndl + lfl + 1);
3469
3470 ret = BGP_ATTR_PARSE_ERROR;
3471 goto done;
3472 }
3473
3474 struct bgp_attr_parser_args attr_args = {
3475 .peer = peer,
3476 .length = length,
3477 .attr = attr,
3478 .type = type,
3479 .flags = flag,
3480 .startp = startp,
3481 .total = attr_endp - startp,
3482 };
3483
3484
3485 /* If any recognized attribute has Attribute Flags that conflict
3486 with the Attribute Type Code, then the Error Subcode is set
3487 to
3488 Attribute Flags Error. The Data field contains the erroneous
3489 attribute (type, length and value). */
3490 if (bgp_attr_flag_invalid(&attr_args)) {
3491 ret = bgp_attr_malformed(
3492 &attr_args, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
3493 attr_args.total);
3494 if (ret == BGP_ATTR_PARSE_PROCEED)
3495 continue;
3496 goto done;
3497 }
3498
3499 /* OK check attribute and store it's value. */
3500 switch (type) {
3501 case BGP_ATTR_ORIGIN:
3502 ret = bgp_attr_origin(&attr_args);
3503 break;
3504 case BGP_ATTR_AS_PATH:
3505 ret = bgp_attr_aspath(&attr_args);
3506 break;
3507 case BGP_ATTR_AS4_PATH:
3508 ret = bgp_attr_as4_path(&attr_args, &as4_path);
3509 break;
3510 case BGP_ATTR_NEXT_HOP:
3511 ret = bgp_attr_nexthop(&attr_args);
3512 break;
3513 case BGP_ATTR_MULTI_EXIT_DISC:
3514 ret = bgp_attr_med(&attr_args);
3515 break;
3516 case BGP_ATTR_LOCAL_PREF:
3517 ret = bgp_attr_local_pref(&attr_args);
3518 break;
3519 case BGP_ATTR_ATOMIC_AGGREGATE:
3520 ret = bgp_attr_atomic(&attr_args);
3521 break;
3522 case BGP_ATTR_AGGREGATOR:
3523 ret = bgp_attr_aggregator(&attr_args);
3524 break;
3525 case BGP_ATTR_AS4_AGGREGATOR:
3526 ret = bgp_attr_as4_aggregator(&attr_args,
3527 &as4_aggregator,
3528 &as4_aggregator_addr);
3529 break;
3530 case BGP_ATTR_COMMUNITIES:
3531 ret = bgp_attr_community(&attr_args);
3532 break;
3533 case BGP_ATTR_LARGE_COMMUNITIES:
3534 ret = bgp_attr_large_community(&attr_args);
3535 break;
3536 case BGP_ATTR_ORIGINATOR_ID:
3537 ret = bgp_attr_originator_id(&attr_args);
3538 break;
3539 case BGP_ATTR_CLUSTER_LIST:
3540 ret = bgp_attr_cluster_list(&attr_args);
3541 break;
3542 case BGP_ATTR_MP_REACH_NLRI:
3543 ret = bgp_mp_reach_parse(&attr_args, mp_update);
3544 break;
3545 case BGP_ATTR_MP_UNREACH_NLRI:
3546 ret = bgp_mp_unreach_parse(&attr_args, mp_withdraw);
3547 break;
3548 case BGP_ATTR_EXT_COMMUNITIES:
3549 ret = bgp_attr_ext_communities(&attr_args);
3550 break;
3551 #ifdef ENABLE_BGP_VNC_ATTR
3552 case BGP_ATTR_VNC:
3553 #endif
3554 case BGP_ATTR_ENCAP:
3555 ret = bgp_attr_encap(type, peer, length, attr, flag,
3556 startp);
3557 break;
3558 case BGP_ATTR_PREFIX_SID:
3559 ret = bgp_attr_prefix_sid(&attr_args);
3560 break;
3561 case BGP_ATTR_PMSI_TUNNEL:
3562 ret = bgp_attr_pmsi_tunnel(&attr_args);
3563 break;
3564 case BGP_ATTR_IPV6_EXT_COMMUNITIES:
3565 ret = bgp_attr_ipv6_ext_communities(&attr_args);
3566 break;
3567 case BGP_ATTR_OTC:
3568 ret = bgp_attr_otc(&attr_args);
3569 break;
3570 case BGP_ATTR_AIGP:
3571 ret = bgp_attr_aigp(&attr_args);
3572 break;
3573 default:
3574 ret = bgp_attr_unknown(&attr_args);
3575 break;
3576 }
3577
3578 if (ret == BGP_ATTR_PARSE_ERROR_NOTIFYPLS) {
3579 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3580 BGP_NOTIFY_UPDATE_MAL_ATTR);
3581 ret = BGP_ATTR_PARSE_ERROR;
3582 goto done;
3583 }
3584
3585 if (ret == BGP_ATTR_PARSE_EOR) {
3586 goto done;
3587 }
3588
3589 if (ret == BGP_ATTR_PARSE_ERROR) {
3590 flog_warn(EC_BGP_ATTRIBUTE_PARSE_ERROR,
3591 "%s: Attribute %s, parse error", peer->host,
3592 lookup_msg(attr_str, type, NULL));
3593 goto done;
3594 }
3595 if (ret == BGP_ATTR_PARSE_WITHDRAW) {
3596 flog_warn(
3597 EC_BGP_ATTRIBUTE_PARSE_WITHDRAW,
3598 "%s: Attribute %s, parse error - treating as withdrawal",
3599 peer->host, lookup_msg(attr_str, type, NULL));
3600 goto done;
3601 }
3602
3603 /* Check the fetched length. */
3604 if (BGP_INPUT_PNT(peer) != attr_endp) {
3605 flog_warn(EC_BGP_ATTRIBUTE_FETCH_ERROR,
3606 "%s: BGP attribute %s, fetch error",
3607 peer->host, lookup_msg(attr_str, type, NULL));
3608 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3609 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
3610 ret = BGP_ATTR_PARSE_ERROR;
3611 goto done;
3612 }
3613 }
3614
3615 /*
3616 * draft-ietf-idr-bgp-prefix-sid-27#section-3:
3617 * About Prefix-SID path attribute,
3618 * Label-Index TLV(type1) and The Originator SRGB TLV(type-3)
3619 * may only appear in a BGP Prefix-SID attribute attached to
3620 * IPv4/IPv6 Labeled Unicast prefixes ([RFC8277]).
3621 * It MUST be ignored when received for other BGP AFI/SAFI combinations.
3622 */
3623 if (!attr->mp_nexthop_len || mp_update->safi != SAFI_LABELED_UNICAST)
3624 attr->label_index = BGP_INVALID_LABEL_INDEX;
3625
3626 /* Check final read pointer is same as end pointer. */
3627 if (BGP_INPUT_PNT(peer) != endp) {
3628 flog_warn(EC_BGP_ATTRIBUTES_MISMATCH,
3629 "%s: BGP attribute %s, length mismatch", peer->host,
3630 lookup_msg(attr_str, type, NULL));
3631 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3632 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
3633
3634 ret = BGP_ATTR_PARSE_ERROR;
3635 goto done;
3636 }
3637
3638 /*
3639 * RFC4271: If the NEXT_HOP attribute field is syntactically incorrect,
3640 * then the Error Subcode MUST be set to Invalid NEXT_HOP Attribute.
3641 * This is implemented below and will result in a NOTIFICATION. If the
3642 * NEXT_HOP attribute is semantically incorrect, the error SHOULD be
3643 * logged, and the route SHOULD be ignored. In this case, a NOTIFICATION
3644 * message SHOULD NOT be sent. This is implemented elsewhere.
3645 *
3646 * RFC4760: An UPDATE message that carries no NLRI, other than the one
3647 * encoded in the MP_REACH_NLRI attribute, SHOULD NOT carry the NEXT_HOP
3648 * attribute. If such a message contains the NEXT_HOP attribute, the BGP
3649 * speaker that receives the message SHOULD ignore this attribute.
3650 */
3651 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP))
3652 && !CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI))) {
3653 if (bgp_attr_nexthop_valid(peer, attr) < 0) {
3654 ret = BGP_ATTR_PARSE_ERROR;
3655 goto done;
3656 }
3657 }
3658
3659 /* Check all mandatory well-known attributes are present */
3660 ret = bgp_attr_check(peer, attr);
3661 if (ret < 0)
3662 goto done;
3663
3664 /*
3665 * At this place we can see whether we got AS4_PATH and/or
3666 * AS4_AGGREGATOR from a 16Bit peer and act accordingly.
3667 * We can not do this before we've read all attributes because
3668 * the as4 handling does not say whether AS4_PATH has to be sent
3669 * after AS_PATH or not - and when AS4_AGGREGATOR will be send
3670 * in relationship to AGGREGATOR.
3671 * So, to be defensive, we are not relying on any order and read
3672 * all attributes first, including these 32bit ones, and now,
3673 * afterwards, we look what and if something is to be done for as4.
3674 *
3675 * It is possible to not have AS_PATH, e.g. GR EoR and sole
3676 * MP_UNREACH_NLRI.
3677 */
3678 /* actually... this doesn't ever return failure currently, but
3679 * better safe than sorry */
3680 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AS_PATH))
3681 && bgp_attr_munge_as4_attrs(peer, attr, as4_path, as4_aggregator,
3682 &as4_aggregator_addr)) {
3683 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3684 BGP_NOTIFY_UPDATE_MAL_ATTR);
3685 ret = BGP_ATTR_PARSE_ERROR;
3686 goto done;
3687 }
3688
3689 /*
3690 * Finally do the checks on the aspath we did not do yet
3691 * because we waited for a potentially synthesized aspath.
3692 */
3693 if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS_PATH))) {
3694 ret = bgp_attr_aspath_check(peer, attr);
3695 if (ret != BGP_ATTR_PARSE_PROCEED)
3696 goto done;
3697 }
3698
3699 ret = BGP_ATTR_PARSE_PROCEED;
3700 done:
3701
3702 /*
3703 * At this stage, we have done all fiddling with as4, and the
3704 * resulting info is in attr->aggregator resp. attr->aspath so
3705 * we can chuck as4_aggregator and as4_path alltogether in order
3706 * to save memory
3707 */
3708 /*
3709 * unintern - it is in the hash
3710 * The flag that we got this is still there, but that
3711 * does not do any trouble
3712 */
3713 aspath_unintern(&as4_path);
3714
3715 transit = bgp_attr_get_transit(attr);
3716 if (ret != BGP_ATTR_PARSE_ERROR) {
3717 /* Finally intern unknown attribute. */
3718 if (transit)
3719 bgp_attr_set_transit(attr, transit_intern(transit));
3720 if (attr->encap_subtlvs)
3721 attr->encap_subtlvs = encap_intern(attr->encap_subtlvs,
3722 ENCAP_SUBTLV_TYPE);
3723 #ifdef ENABLE_BGP_VNC
3724 struct bgp_attr_encap_subtlv *vnc_subtlvs =
3725 bgp_attr_get_vnc_subtlvs(attr);
3726
3727 if (vnc_subtlvs)
3728 bgp_attr_set_vnc_subtlvs(
3729 attr,
3730 encap_intern(vnc_subtlvs, VNC_SUBTLV_TYPE));
3731 #endif
3732 } else {
3733 if (transit) {
3734 transit_free(transit);
3735 bgp_attr_set_transit(attr, NULL);
3736 }
3737
3738 bgp_attr_flush_encap(attr);
3739 };
3740
3741 /* Sanity checks */
3742 transit = bgp_attr_get_transit(attr);
3743 if (transit)
3744 assert(transit->refcnt > 0);
3745 if (attr->encap_subtlvs)
3746 assert(attr->encap_subtlvs->refcnt > 0);
3747 #ifdef ENABLE_BGP_VNC
3748 struct bgp_attr_encap_subtlv *vnc_subtlvs =
3749 bgp_attr_get_vnc_subtlvs(attr);
3750
3751 if (vnc_subtlvs)
3752 assert(vnc_subtlvs->refcnt > 0);
3753 #endif
3754
3755 return ret;
3756 }
3757
3758 /*
3759 * Extract the tunnel type from extended community
3760 */
3761 void bgp_attr_extcom_tunnel_type(struct attr *attr,
3762 bgp_encap_types *tunnel_type)
3763 {
3764 struct ecommunity *ecom;
3765 uint32_t i;
3766
3767 if (!attr)
3768 return;
3769
3770 ecom = bgp_attr_get_ecommunity(attr);
3771 if (!ecom || !ecom->size)
3772 return;
3773
3774 for (i = 0; i < ecom->size; i++) {
3775 uint8_t *pnt;
3776 uint8_t type, sub_type;
3777
3778 pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
3779 type = pnt[0];
3780 sub_type = pnt[1];
3781 if (!(type == ECOMMUNITY_ENCODE_OPAQUE &&
3782 sub_type == ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP))
3783 continue;
3784 *tunnel_type = ((pnt[6] << 8) | pnt[7]);
3785 return;
3786 }
3787
3788 return;
3789 }
3790
3791 size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi,
3792 safi_t safi, struct bpacket_attr_vec_arr *vecarr,
3793 struct attr *attr)
3794 {
3795 size_t sizep;
3796 iana_afi_t pkt_afi = IANA_AFI_IPV4;
3797 iana_safi_t pkt_safi = IANA_SAFI_UNICAST;
3798 afi_t nh_afi;
3799
3800 /* Set extended bit always to encode the attribute length as 2 bytes */
3801 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_EXTLEN);
3802 stream_putc(s, BGP_ATTR_MP_REACH_NLRI);
3803 sizep = stream_get_endp(s);
3804 stream_putw(s, 0); /* Marker: Attribute length. */
3805
3806
3807 /* Convert AFI, SAFI to values for packet. */
3808 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
3809
3810 stream_putw(s, pkt_afi); /* AFI */
3811 stream_putc(s, pkt_safi); /* SAFI */
3812
3813 /* Nexthop AFI */
3814 if (afi == AFI_IP
3815 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST
3816 || safi == SAFI_MPLS_VPN || safi == SAFI_MULTICAST))
3817 nh_afi = peer_cap_enhe(peer, afi, safi) ? AFI_IP6 : AFI_IP;
3818 else if (safi == SAFI_FLOWSPEC)
3819 nh_afi = afi;
3820 else
3821 nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->mp_nexthop_len);
3822
3823 /* Nexthop */
3824 bpacket_attr_vec_arr_set_vec(vecarr, BGP_ATTR_VEC_NH, s, attr);
3825 switch (nh_afi) {
3826 case AFI_IP:
3827 switch (safi) {
3828 case SAFI_UNICAST:
3829 case SAFI_MULTICAST:
3830 case SAFI_LABELED_UNICAST:
3831 stream_putc(s, 4);
3832 stream_put_ipv4(s, attr->nexthop.s_addr);
3833 break;
3834 case SAFI_MPLS_VPN:
3835 stream_putc(s, 12);
3836 stream_putl(s, 0); /* RD = 0, per RFC */
3837 stream_putl(s, 0);
3838 stream_put(s, &attr->mp_nexthop_global_in, 4);
3839 break;
3840 case SAFI_ENCAP:
3841 case SAFI_EVPN:
3842 stream_putc(s, 4);
3843 stream_put(s, &attr->mp_nexthop_global_in, 4);
3844 break;
3845 case SAFI_FLOWSPEC:
3846 if (attr->mp_nexthop_len == 0)
3847 stream_putc(s, 0); /* no nexthop for flowspec */
3848 else {
3849 stream_putc(s, attr->mp_nexthop_len);
3850 stream_put_ipv4(s, attr->nexthop.s_addr);
3851 }
3852 default:
3853 break;
3854 }
3855 break;
3856 case AFI_IP6:
3857 switch (safi) {
3858 case SAFI_UNICAST:
3859 case SAFI_MULTICAST:
3860 case SAFI_LABELED_UNICAST:
3861 case SAFI_EVPN: {
3862 if (attr->mp_nexthop_len
3863 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
3864 stream_putc(s,
3865 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL);
3866 stream_put(s, &attr->mp_nexthop_global,
3867 IPV6_MAX_BYTELEN);
3868 stream_put(s, &attr->mp_nexthop_local,
3869 IPV6_MAX_BYTELEN);
3870 } else {
3871 stream_putc(s, IPV6_MAX_BYTELEN);
3872 stream_put(s, &attr->mp_nexthop_global,
3873 IPV6_MAX_BYTELEN);
3874 }
3875 } break;
3876 case SAFI_MPLS_VPN: {
3877 if (attr->mp_nexthop_len
3878 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
3879 stream_putc(s, 48);
3880 stream_putl(s, 0); /* RD = 0, per RFC */
3881 stream_putl(s, 0);
3882 stream_put(s, &attr->mp_nexthop_global,
3883 IPV6_MAX_BYTELEN);
3884 stream_putl(s, 0); /* RD = 0, per RFC */
3885 stream_putl(s, 0);
3886 stream_put(s, &attr->mp_nexthop_local,
3887 IPV6_MAX_BYTELEN);
3888 } else {
3889 stream_putc(s, 24);
3890 stream_putl(s, 0); /* RD = 0, per RFC */
3891 stream_putl(s, 0);
3892 stream_put(s, &attr->mp_nexthop_global,
3893 IPV6_MAX_BYTELEN);
3894 }
3895 } break;
3896 case SAFI_ENCAP:
3897 stream_putc(s, IPV6_MAX_BYTELEN);
3898 stream_put(s, &attr->mp_nexthop_global,
3899 IPV6_MAX_BYTELEN);
3900 break;
3901 case SAFI_FLOWSPEC:
3902 stream_putc(s, 0); /* no nexthop for flowspec */
3903 default:
3904 break;
3905 }
3906 break;
3907 default:
3908 if (safi != SAFI_FLOWSPEC)
3909 flog_err(
3910 EC_BGP_ATTR_NH_SEND_LEN,
3911 "Bad nexthop when sending to %s, AFI %u SAFI %u nhlen %d",
3912 peer->host, afi, safi, attr->mp_nexthop_len);
3913 break;
3914 }
3915
3916 /* SNPA */
3917 stream_putc(s, 0);
3918 return sizep;
3919 }
3920
3921 void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
3922 const struct prefix *p,
3923 const struct prefix_rd *prd, mpls_label_t *label,
3924 uint32_t num_labels, bool addpath_capable,
3925 uint32_t addpath_tx_id, struct attr *attr)
3926 {
3927 if (safi == SAFI_MPLS_VPN) {
3928 if (addpath_capable)
3929 stream_putl(s, addpath_tx_id);
3930 /* Label, RD, Prefix write. */
3931 stream_putc(s, p->prefixlen + 88);
3932 stream_put(s, label, BGP_LABEL_BYTES);
3933 stream_put(s, prd->val, 8);
3934 stream_put(s, &p->u.prefix, PSIZE(p->prefixlen));
3935 } else if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
3936 /* EVPN prefix - contents depend on type */
3937 bgp_evpn_encode_prefix(s, p, prd, label, num_labels, attr,
3938 addpath_capable, addpath_tx_id);
3939 } else if (safi == SAFI_LABELED_UNICAST) {
3940 /* Prefix write with label. */
3941 stream_put_labeled_prefix(s, p, label, addpath_capable,
3942 addpath_tx_id);
3943 } else if (safi == SAFI_FLOWSPEC) {
3944 stream_putc(s, p->u.prefix_flowspec.prefixlen);
3945 stream_put(s, (const void *)p->u.prefix_flowspec.ptr,
3946 p->u.prefix_flowspec.prefixlen);
3947 } else
3948 stream_put_prefix_addpath(s, p, addpath_capable, addpath_tx_id);
3949 }
3950
3951 size_t bgp_packet_mpattr_prefix_size(afi_t afi, safi_t safi,
3952 const struct prefix *p)
3953 {
3954 int size = PSIZE(p->prefixlen);
3955 if (safi == SAFI_MPLS_VPN)
3956 size += 88;
3957 else if (safi == SAFI_LABELED_UNICAST)
3958 size += BGP_LABEL_BYTES;
3959 else if (afi == AFI_L2VPN && safi == SAFI_EVPN)
3960 size += 232; // TODO: Maximum possible for type-2, type-3 and
3961 // type-5
3962 return size;
3963 }
3964
3965 /*
3966 * Encodes the tunnel encapsulation attribute,
3967 * and with ENABLE_BGP_VNC the VNC attribute which uses
3968 * almost the same TLV format
3969 */
3970 static void bgp_packet_mpattr_tea(struct bgp *bgp, struct peer *peer,
3971 struct stream *s, struct attr *attr,
3972 uint8_t attrtype)
3973 {
3974 unsigned int attrlenfield = 0;
3975 unsigned int attrhdrlen = 0;
3976 struct bgp_attr_encap_subtlv *subtlvs;
3977 struct bgp_attr_encap_subtlv *st;
3978 const char *attrname;
3979
3980 if (!attr || (attrtype == BGP_ATTR_ENCAP
3981 && (!attr->encap_tunneltype
3982 || attr->encap_tunneltype == BGP_ENCAP_TYPE_MPLS)))
3983 return;
3984
3985 switch (attrtype) {
3986 case BGP_ATTR_ENCAP:
3987 attrname = "Tunnel Encap";
3988 subtlvs = attr->encap_subtlvs;
3989 if (subtlvs == NULL) /* nothing to do */
3990 return;
3991 /*
3992 * The tunnel encap attr has an "outer" tlv.
3993 * T = tunneltype,
3994 * L = total length of subtlvs,
3995 * V = concatenated subtlvs.
3996 */
3997 attrlenfield = 2 + 2; /* T + L */
3998 attrhdrlen = 1 + 1; /* subTLV T + L */
3999 break;
4000
4001 #ifdef ENABLE_BGP_VNC_ATTR
4002 case BGP_ATTR_VNC:
4003 attrname = "VNC";
4004 subtlvs = bgp_attr_get_vnc_subtlvs(attr);
4005 if (subtlvs == NULL) /* nothing to do */
4006 return;
4007 attrlenfield = 0; /* no outer T + L */
4008 attrhdrlen = 2 + 2; /* subTLV T + L */
4009 break;
4010 #endif
4011
4012 default:
4013 assert(0);
4014 }
4015
4016 /* compute attr length */
4017 for (st = subtlvs; st; st = st->next) {
4018 attrlenfield += (attrhdrlen + st->length);
4019 }
4020
4021 if (attrlenfield > 0xffff) {
4022 zlog_info("%s attribute is too long (length=%d), can't send it",
4023 attrname, attrlenfield);
4024 return;
4025 }
4026
4027 if (attrlenfield > 0xff) {
4028 /* 2-octet length field */
4029 stream_putc(s,
4030 BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL
4031 | BGP_ATTR_FLAG_EXTLEN);
4032 stream_putc(s, attrtype);
4033 stream_putw(s, attrlenfield & 0xffff);
4034 } else {
4035 /* 1-octet length field */
4036 stream_putc(s, BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL);
4037 stream_putc(s, attrtype);
4038 stream_putc(s, attrlenfield & 0xff);
4039 }
4040
4041 if (attrtype == BGP_ATTR_ENCAP) {
4042 /* write outer T+L */
4043 stream_putw(s, attr->encap_tunneltype);
4044 stream_putw(s, attrlenfield - 4);
4045 }
4046
4047 /* write each sub-tlv */
4048 for (st = subtlvs; st; st = st->next) {
4049 if (attrtype == BGP_ATTR_ENCAP) {
4050 stream_putc(s, st->type);
4051 stream_putc(s, st->length);
4052 #ifdef ENABLE_BGP_VNC
4053 } else {
4054 stream_putw(s, st->type);
4055 stream_putw(s, st->length);
4056 #endif
4057 }
4058 stream_put(s, st->value, st->length);
4059 }
4060 }
4061
4062 void bgp_packet_mpattr_end(struct stream *s, size_t sizep)
4063 {
4064 /* Set MP attribute length. Don't count the (2) bytes used to encode
4065 the attr length */
4066 stream_putw_at(s, sizep, (stream_get_endp(s) - sizep) - 2);
4067 }
4068
4069 static bool bgp_append_local_as(struct peer *peer, afi_t afi, safi_t safi)
4070 {
4071 if (!BGP_AS_IS_PRIVATE(peer->local_as)
4072 || (BGP_AS_IS_PRIVATE(peer->local_as)
4073 && !CHECK_FLAG(peer->af_flags[afi][safi],
4074 PEER_FLAG_REMOVE_PRIVATE_AS)
4075 && !CHECK_FLAG(peer->af_flags[afi][safi],
4076 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
4077 && !CHECK_FLAG(peer->af_flags[afi][safi],
4078 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
4079 && !CHECK_FLAG(peer->af_flags[afi][safi],
4080 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)))
4081 return true;
4082 return false;
4083 }
4084
4085 /* Make attribute packet. */
4086 bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
4087 struct stream *s, struct attr *attr,
4088 struct bpacket_attr_vec_arr *vecarr,
4089 struct prefix *p, afi_t afi, safi_t safi,
4090 struct peer *from, struct prefix_rd *prd,
4091 mpls_label_t *label, uint32_t num_labels,
4092 bool addpath_capable, uint32_t addpath_tx_id,
4093 struct bgp_path_info *bpi)
4094 {
4095 size_t cp;
4096 size_t aspath_sizep;
4097 struct aspath *aspath;
4098 int send_as4_path = 0;
4099 int send_as4_aggregator = 0;
4100 bool use32bit = CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)
4101 && CHECK_FLAG(peer->cap, PEER_CAP_AS4_ADV);
4102
4103 if (!bgp)
4104 bgp = peer->bgp;
4105
4106 /* Remember current pointer. */
4107 cp = stream_get_endp(s);
4108
4109 if (p
4110 && !((afi == AFI_IP && safi == SAFI_UNICAST)
4111 && !peer_cap_enhe(peer, afi, safi))) {
4112 size_t mpattrlen_pos = 0;
4113
4114 mpattrlen_pos = bgp_packet_mpattr_start(s, peer, afi, safi,
4115 vecarr, attr);
4116 bgp_packet_mpattr_prefix(s, afi, safi, p, prd, label,
4117 num_labels, addpath_capable,
4118 addpath_tx_id, attr);
4119 bgp_packet_mpattr_end(s, mpattrlen_pos);
4120 }
4121
4122 /* Origin attribute. */
4123 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4124 stream_putc(s, BGP_ATTR_ORIGIN);
4125 stream_putc(s, 1);
4126 stream_putc(s, attr->origin);
4127
4128 /* AS path attribute. */
4129
4130 /* If remote-peer is EBGP */
4131 if (peer->sort == BGP_PEER_EBGP
4132 && (!CHECK_FLAG(peer->af_flags[afi][safi],
4133 PEER_FLAG_AS_PATH_UNCHANGED)
4134 || attr->aspath->segments == NULL)
4135 && (!CHECK_FLAG(peer->af_flags[afi][safi],
4136 PEER_FLAG_RSERVER_CLIENT))) {
4137 aspath = aspath_dup(attr->aspath);
4138
4139 /* Even though we may not be configured for confederations we
4140 * may have
4141 * RXed an AS_PATH with AS_CONFED_SEQUENCE or AS_CONFED_SET */
4142 aspath = aspath_delete_confed_seq(aspath);
4143
4144 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
4145 /* Stuff our path CONFED_ID on the front */
4146 aspath = aspath_add_seq(aspath, bgp->confed_id);
4147 } else {
4148 if (peer->change_local_as) {
4149 /* If replace-as is specified, we only use the
4150 change_local_as when
4151 advertising routes. */
4152 if (!CHECK_FLAG(peer->flags,
4153 PEER_FLAG_LOCAL_AS_REPLACE_AS))
4154 if (bgp_append_local_as(peer, afi,
4155 safi))
4156 aspath = aspath_add_seq(
4157 aspath, peer->local_as);
4158 aspath = aspath_add_seq(aspath,
4159 peer->change_local_as);
4160 } else {
4161 aspath = aspath_add_seq(aspath, peer->local_as);
4162 }
4163 }
4164 } else if (peer->sort == BGP_PEER_CONFED) {
4165 /* A confed member, so we need to do the AS_CONFED_SEQUENCE
4166 * thing */
4167 aspath = aspath_dup(attr->aspath);
4168 aspath = aspath_add_confed_seq(aspath, peer->local_as);
4169 } else
4170 aspath = attr->aspath;
4171
4172 /* If peer is not AS4 capable, then:
4173 * - send the created AS_PATH out as AS4_PATH (optional, transitive),
4174 * but ensure that no AS_CONFED_SEQUENCE and AS_CONFED_SET path
4175 * segment
4176 * types are in it (i.e. exclude them if they are there)
4177 * AND do this only if there is at least one asnum > 65535 in the
4178 * path!
4179 * - send an AS_PATH out, but put 16Bit ASnums in it, not 32bit, and
4180 * change
4181 * all ASnums > 65535 to BGP_AS_TRANS
4182 */
4183
4184 stream_putc(s, BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_EXTLEN);
4185 stream_putc(s, BGP_ATTR_AS_PATH);
4186 aspath_sizep = stream_get_endp(s);
4187 stream_putw(s, 0);
4188 stream_putw_at(s, aspath_sizep, aspath_put(s, aspath, use32bit));
4189
4190 /* OLD session may need NEW_AS_PATH sent, if there are 4-byte ASNs
4191 * in the path
4192 */
4193 if (!use32bit && aspath_has_as4(aspath))
4194 send_as4_path =
4195 1; /* we'll do this later, at the correct place */
4196
4197 /* Nexthop attribute. */
4198 if (afi == AFI_IP && safi == SAFI_UNICAST
4199 && !peer_cap_enhe(peer, afi, safi)) {
4200 afi_t nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->mp_nexthop_len);
4201
4202 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
4203 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4204 stream_putc(s, BGP_ATTR_NEXT_HOP);
4205 bpacket_attr_vec_arr_set_vec(vecarr, BGP_ATTR_VEC_NH, s,
4206 attr);
4207 stream_putc(s, 4);
4208 stream_put_ipv4(s, attr->nexthop.s_addr);
4209 } else if (peer_cap_enhe(from, afi, safi)
4210 || (nh_afi == AFI_IP6)) {
4211 /*
4212 * Likely this is the case when an IPv4 prefix was
4213 * received with Extended Next-hop capability in this
4214 * or another vrf and is now being advertised to
4215 * non-ENHE peers. Since peer_cap_enhe only checks
4216 * peers in this vrf, also check the nh_afi to catch
4217 * the case where the originator was in another vrf.
4218 * Setting the mandatory (ipv4) next-hop attribute here
4219 * to enable implicit next-hop self with correct A-F
4220 * (ipv4 address family).
4221 */
4222 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4223 stream_putc(s, BGP_ATTR_NEXT_HOP);
4224 bpacket_attr_vec_arr_set_vec(vecarr, BGP_ATTR_VEC_NH, s,
4225 NULL);
4226 stream_putc(s, 4);
4227 stream_put_ipv4(s, 0);
4228 }
4229 }
4230
4231 /* MED attribute. */
4232 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)
4233 || bgp->maxmed_active) {
4234 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
4235 stream_putc(s, BGP_ATTR_MULTI_EXIT_DISC);
4236 stream_putc(s, 4);
4237 stream_putl(s, (bgp->maxmed_active ? bgp->maxmed_value
4238 : attr->med));
4239 }
4240
4241 /* Local preference. */
4242 if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED) {
4243 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4244 stream_putc(s, BGP_ATTR_LOCAL_PREF);
4245 stream_putc(s, 4);
4246 stream_putl(s, attr->local_pref);
4247 }
4248
4249 /* Atomic aggregate. */
4250 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
4251 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4252 stream_putc(s, BGP_ATTR_ATOMIC_AGGREGATE);
4253 stream_putc(s, 0);
4254 }
4255
4256 /* Aggregator. */
4257 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR)) {
4258 /* Common to BGP_ATTR_AGGREGATOR, regardless of ASN size */
4259 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
4260 stream_putc(s, BGP_ATTR_AGGREGATOR);
4261
4262 if (use32bit) {
4263 /* AS4 capable peer */
4264 stream_putc(s, 8);
4265 stream_putl(s, attr->aggregator_as);
4266 } else {
4267 /* 2-byte AS peer */
4268 stream_putc(s, 6);
4269
4270 /* Is ASN representable in 2-bytes? Or must AS_TRANS be
4271 * used? */
4272 if (attr->aggregator_as > UINT16_MAX) {
4273 stream_putw(s, BGP_AS_TRANS);
4274
4275 /* we have to send AS4_AGGREGATOR, too.
4276 * we'll do that later in order to send
4277 * attributes in ascending
4278 * order.
4279 */
4280 send_as4_aggregator = 1;
4281 } else
4282 stream_putw(s, (uint16_t)attr->aggregator_as);
4283 }
4284 stream_put_ipv4(s, attr->aggregator_addr.s_addr);
4285 }
4286
4287 /* Community attribute. */
4288 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY)
4289 && (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))) {
4290 struct community *comm = NULL;
4291
4292 comm = bgp_attr_get_community(attr);
4293 if (comm->size * 4 > 255) {
4294 stream_putc(s,
4295 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
4296 | BGP_ATTR_FLAG_EXTLEN);
4297 stream_putc(s, BGP_ATTR_COMMUNITIES);
4298 stream_putw(s, comm->size * 4);
4299 } else {
4300 stream_putc(s,
4301 BGP_ATTR_FLAG_OPTIONAL
4302 | BGP_ATTR_FLAG_TRANS);
4303 stream_putc(s, BGP_ATTR_COMMUNITIES);
4304 stream_putc(s, comm->size * 4);
4305 }
4306 stream_put(s, comm->val, comm->size * 4);
4307 }
4308
4309 /*
4310 * Large Community attribute.
4311 */
4312 if (CHECK_FLAG(peer->af_flags[afi][safi],
4313 PEER_FLAG_SEND_LARGE_COMMUNITY)
4314 && (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))) {
4315 if (lcom_length(bgp_attr_get_lcommunity(attr)) > 255) {
4316 stream_putc(s,
4317 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
4318 | BGP_ATTR_FLAG_EXTLEN);
4319 stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
4320 stream_putw(s,
4321 lcom_length(bgp_attr_get_lcommunity(attr)));
4322 } else {
4323 stream_putc(s,
4324 BGP_ATTR_FLAG_OPTIONAL
4325 | BGP_ATTR_FLAG_TRANS);
4326 stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
4327 stream_putc(s,
4328 lcom_length(bgp_attr_get_lcommunity(attr)));
4329 }
4330 stream_put(s, bgp_attr_get_lcommunity(attr)->val,
4331 lcom_length(bgp_attr_get_lcommunity(attr)));
4332 }
4333
4334 /* Route Reflector. */
4335 if (peer->sort == BGP_PEER_IBGP && from
4336 && from->sort == BGP_PEER_IBGP) {
4337 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
4338
4339 /* Originator ID. */
4340 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
4341 stream_putc(s, BGP_ATTR_ORIGINATOR_ID);
4342 stream_putc(s, 4);
4343
4344 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
4345 stream_put_in_addr(s, &attr->originator_id);
4346 else
4347 stream_put_in_addr(s, &from->remote_id);
4348
4349 /* Cluster list. */
4350 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
4351 stream_putc(s, BGP_ATTR_CLUSTER_LIST);
4352
4353 if (cluster) {
4354 stream_putc(s, cluster->length + 4);
4355 /* If this peer configuration's parent BGP has
4356 * cluster_id. */
4357 if (bgp->config & BGP_CONFIG_CLUSTER_ID)
4358 stream_put_in_addr(s, &bgp->cluster_id);
4359 else
4360 stream_put_in_addr(s, &bgp->router_id);
4361 stream_put(s, cluster->list, cluster->length);
4362 } else {
4363 stream_putc(s, 4);
4364 /* If this peer configuration's parent BGP has
4365 * cluster_id. */
4366 if (bgp->config & BGP_CONFIG_CLUSTER_ID)
4367 stream_put_in_addr(s, &bgp->cluster_id);
4368 else
4369 stream_put_in_addr(s, &bgp->router_id);
4370 }
4371 }
4372
4373 /* Extended Communities attribute. */
4374 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY)
4375 && (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4376 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
4377 bool transparent = CHECK_FLAG(peer->af_flags[afi][safi],
4378 PEER_FLAG_RSERVER_CLIENT) &&
4379 from &&
4380 CHECK_FLAG(from->af_flags[afi][safi],
4381 PEER_FLAG_RSERVER_CLIENT);
4382
4383 if (peer->sort == BGP_PEER_IBGP ||
4384 peer->sort == BGP_PEER_CONFED || transparent) {
4385 if (ecomm->size * 8 > 255) {
4386 stream_putc(s,
4387 BGP_ATTR_FLAG_OPTIONAL
4388 | BGP_ATTR_FLAG_TRANS
4389 | BGP_ATTR_FLAG_EXTLEN);
4390 stream_putc(s, BGP_ATTR_EXT_COMMUNITIES);
4391 stream_putw(s, ecomm->size * 8);
4392 } else {
4393 stream_putc(s,
4394 BGP_ATTR_FLAG_OPTIONAL
4395 | BGP_ATTR_FLAG_TRANS);
4396 stream_putc(s, BGP_ATTR_EXT_COMMUNITIES);
4397 stream_putc(s, ecomm->size * 8);
4398 }
4399 stream_put(s, ecomm->val, ecomm->size * 8);
4400 } else {
4401 uint8_t *pnt;
4402 int tbit;
4403 int ecom_tr_size = 0;
4404 uint32_t i;
4405
4406 for (i = 0; i < ecomm->size; i++) {
4407 pnt = ecomm->val + (i * 8);
4408 tbit = *pnt;
4409
4410 if (CHECK_FLAG(tbit,
4411 ECOMMUNITY_FLAG_NON_TRANSITIVE))
4412 continue;
4413
4414 ecom_tr_size++;
4415 }
4416
4417 if (ecom_tr_size) {
4418 if (ecom_tr_size * 8 > 255) {
4419 stream_putc(
4420 s,
4421 BGP_ATTR_FLAG_OPTIONAL
4422 | BGP_ATTR_FLAG_TRANS
4423 | BGP_ATTR_FLAG_EXTLEN);
4424 stream_putc(s,
4425 BGP_ATTR_EXT_COMMUNITIES);
4426 stream_putw(s, ecom_tr_size * 8);
4427 } else {
4428 stream_putc(
4429 s,
4430 BGP_ATTR_FLAG_OPTIONAL
4431 | BGP_ATTR_FLAG_TRANS);
4432 stream_putc(s,
4433 BGP_ATTR_EXT_COMMUNITIES);
4434 stream_putc(s, ecom_tr_size * 8);
4435 }
4436
4437 for (i = 0; i < ecomm->size; i++) {
4438 pnt = ecomm->val + (i * 8);
4439 tbit = *pnt;
4440
4441 if (CHECK_FLAG(
4442 tbit,
4443 ECOMMUNITY_FLAG_NON_TRANSITIVE))
4444 continue;
4445
4446 stream_put(s, pnt, 8);
4447 }
4448 }
4449 }
4450 }
4451
4452 /* Label index attribute. */
4453 if (safi == SAFI_LABELED_UNICAST) {
4454 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) {
4455 uint32_t label_index;
4456
4457 label_index = attr->label_index;
4458
4459 if (label_index != BGP_INVALID_LABEL_INDEX) {
4460 stream_putc(s,
4461 BGP_ATTR_FLAG_OPTIONAL
4462 | BGP_ATTR_FLAG_TRANS);
4463 stream_putc(s, BGP_ATTR_PREFIX_SID);
4464 stream_putc(s, 10);
4465 stream_putc(s, BGP_PREFIX_SID_LABEL_INDEX);
4466 stream_putw(s,
4467 BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
4468 stream_putc(s, 0); // reserved
4469 stream_putw(s, 0); // flags
4470 stream_putl(s, label_index);
4471 }
4472 }
4473 }
4474
4475 /* SRv6 Service Information Attribute. */
4476 if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_MPLS_VPN) {
4477 if (attr->srv6_l3vpn) {
4478 uint8_t subtlv_len =
4479 BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_STRUCTURE_LENGTH
4480 + BGP_ATTR_MIN_LEN
4481 + BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_INFO_LENGTH;
4482 uint8_t tlv_len = subtlv_len + BGP_ATTR_MIN_LEN + 1;
4483 uint8_t attr_len = tlv_len + BGP_ATTR_MIN_LEN;
4484 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL
4485 | BGP_ATTR_FLAG_TRANS);
4486 stream_putc(s, BGP_ATTR_PREFIX_SID);
4487 stream_putc(s, attr_len);
4488 stream_putc(s, BGP_PREFIX_SID_SRV6_L3_SERVICE);
4489 stream_putw(s, tlv_len);
4490 stream_putc(s, 0); /* reserved */
4491 stream_putc(s, BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_INFO);
4492 stream_putw(s, subtlv_len);
4493 stream_putc(s, 0); /* reserved */
4494 stream_put(s, &attr->srv6_l3vpn->sid,
4495 sizeof(attr->srv6_l3vpn->sid)); /* sid */
4496 stream_putc(s, 0); /* sid_flags */
4497 stream_putw(s,
4498 attr->srv6_l3vpn
4499 ->endpoint_behavior); /* endpoint */
4500 stream_putc(s, 0); /* reserved */
4501 stream_putc(
4502 s,
4503 BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_STRUCTURE);
4504 stream_putw(
4505 s,
4506 BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_STRUCTURE_LENGTH);
4507 stream_putc(s, attr->srv6_l3vpn->loc_block_len);
4508 stream_putc(s, attr->srv6_l3vpn->loc_node_len);
4509 stream_putc(s, attr->srv6_l3vpn->func_len);
4510 stream_putc(s, attr->srv6_l3vpn->arg_len);
4511 stream_putc(s, attr->srv6_l3vpn->transposition_len);
4512 stream_putc(s, attr->srv6_l3vpn->transposition_offset);
4513 } else if (attr->srv6_vpn) {
4514 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL
4515 | BGP_ATTR_FLAG_TRANS);
4516 stream_putc(s, BGP_ATTR_PREFIX_SID);
4517 stream_putc(s, 22); /* tlv len */
4518 stream_putc(s, BGP_PREFIX_SID_VPN_SID);
4519 stream_putw(s, 0x13); /* tlv len */
4520 stream_putc(s, 0x00); /* reserved */
4521 stream_putc(s, 0x01); /* sid_type */
4522 stream_putc(s, 0x00); /* sif_flags */
4523 stream_put(s, &attr->srv6_vpn->sid,
4524 sizeof(attr->srv6_vpn->sid)); /* sid */
4525 }
4526 }
4527
4528 if (send_as4_path) {
4529 /* If the peer is NOT As4 capable, AND */
4530 /* there are ASnums > 65535 in path THEN
4531 * give out AS4_PATH */
4532
4533 /* Get rid of all AS_CONFED_SEQUENCE and AS_CONFED_SET
4534 * path segments!
4535 * Hm, I wonder... confederation things *should* only be at
4536 * the beginning of an aspath, right? Then we should use
4537 * aspath_delete_confed_seq for this, because it is already
4538 * there! (JK)
4539 * Folks, talk to me: what is reasonable here!?
4540 */
4541 aspath = aspath_delete_confed_seq(aspath);
4542
4543 stream_putc(s,
4544 BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL
4545 | BGP_ATTR_FLAG_EXTLEN);
4546 stream_putc(s, BGP_ATTR_AS4_PATH);
4547 aspath_sizep = stream_get_endp(s);
4548 stream_putw(s, 0);
4549 stream_putw_at(s, aspath_sizep, aspath_put(s, aspath, 1));
4550 }
4551
4552 if (aspath != attr->aspath)
4553 aspath_free(aspath);
4554
4555 if (send_as4_aggregator) {
4556 /* send AS4_AGGREGATOR, at this place */
4557 /* this section of code moved here in order to ensure the
4558 * correct
4559 * *ascending* order of attributes
4560 */
4561 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
4562 stream_putc(s, BGP_ATTR_AS4_AGGREGATOR);
4563 stream_putc(s, 8);
4564 stream_putl(s, attr->aggregator_as);
4565 stream_put_ipv4(s, attr->aggregator_addr.s_addr);
4566 }
4567
4568 if (((afi == AFI_IP || afi == AFI_IP6)
4569 && (safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN))
4570 || (afi == AFI_L2VPN && safi == SAFI_EVPN)) {
4571 /* Tunnel Encap attribute */
4572 bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_ENCAP);
4573
4574 #ifdef ENABLE_BGP_VNC_ATTR
4575 /* VNC attribute */
4576 bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_VNC);
4577 #endif
4578 }
4579
4580 /* PMSI Tunnel */
4581 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
4582 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
4583 stream_putc(s, BGP_ATTR_PMSI_TUNNEL);
4584 stream_putc(s, 9); // Length
4585 stream_putc(s, 0); // Flags
4586 stream_putc(s, bgp_attr_get_pmsi_tnl_type(attr));
4587 stream_put(s, &(attr->label),
4588 BGP_LABEL_BYTES); // MPLS Label / VXLAN VNI
4589 stream_put_ipv4(s, attr->nexthop.s_addr);
4590 // Unicast tunnel endpoint IP address
4591 }
4592
4593 /* OTC */
4594 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
4595 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
4596 stream_putc(s, BGP_ATTR_OTC);
4597 stream_putc(s, 4);
4598 stream_putl(s, attr->otc);
4599 }
4600
4601 /* AIGP */
4602 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP) &&
4603 (CHECK_FLAG(peer->flags, PEER_FLAG_AIGP) ||
4604 peer->sort != BGP_PEER_EBGP)) {
4605 /* At the moment only AIGP Metric TLV exists for AIGP
4606 * attribute. If more comes in, do not forget to update
4607 * attr_len variable to include new ones.
4608 */
4609 uint8_t attr_len = BGP_AIGP_TLV_METRIC_LEN;
4610
4611 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
4612 stream_putc(s, BGP_ATTR_AIGP);
4613 stream_putc(s, attr_len);
4614 stream_put_bgp_aigp_tlv_metric(s, bpi);
4615 }
4616
4617 /* Unknown transit attribute. */
4618 struct transit *transit = bgp_attr_get_transit(attr);
4619
4620 if (transit)
4621 stream_put(s, transit->val, transit->length);
4622
4623 /* Return total size of attribute. */
4624 return stream_get_endp(s) - cp;
4625 }
4626
4627 size_t bgp_packet_mpunreach_start(struct stream *s, afi_t afi, safi_t safi)
4628 {
4629 unsigned long attrlen_pnt;
4630 iana_afi_t pkt_afi = IANA_AFI_IPV4;
4631 iana_safi_t pkt_safi = IANA_SAFI_UNICAST;
4632
4633 /* Set extended bit always to encode the attribute length as 2 bytes */
4634 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_EXTLEN);
4635 stream_putc(s, BGP_ATTR_MP_UNREACH_NLRI);
4636
4637 attrlen_pnt = stream_get_endp(s);
4638 stream_putw(s, 0); /* Length of this attribute. */
4639
4640 /* Convert AFI, SAFI to values for packet. */
4641 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
4642
4643 stream_putw(s, pkt_afi);
4644 stream_putc(s, pkt_safi);
4645
4646 return attrlen_pnt;
4647 }
4648
4649 void bgp_packet_mpunreach_prefix(struct stream *s, const struct prefix *p,
4650 afi_t afi, safi_t safi,
4651 const struct prefix_rd *prd,
4652 mpls_label_t *label, uint32_t num_labels,
4653 bool addpath_capable, uint32_t addpath_tx_id,
4654 struct attr *attr)
4655 {
4656 uint8_t wlabel[4] = {0x80, 0x00, 0x00};
4657
4658 if (safi == SAFI_LABELED_UNICAST) {
4659 label = (mpls_label_t *)wlabel;
4660 num_labels = 1;
4661 }
4662
4663 bgp_packet_mpattr_prefix(s, afi, safi, p, prd, label, num_labels,
4664 addpath_capable, addpath_tx_id, attr);
4665 }
4666
4667 void bgp_packet_mpunreach_end(struct stream *s, size_t attrlen_pnt)
4668 {
4669 bgp_packet_mpattr_end(s, attrlen_pnt);
4670 }
4671
4672 /* Initialization of attribute. */
4673 void bgp_attr_init(void)
4674 {
4675 aspath_init();
4676 attrhash_init();
4677 community_init();
4678 ecommunity_init();
4679 lcommunity_init();
4680 cluster_init();
4681 transit_init();
4682 encap_init();
4683 srv6_init();
4684 }
4685
4686 void bgp_attr_finish(void)
4687 {
4688 aspath_finish();
4689 attrhash_finish();
4690 community_finish();
4691 ecommunity_finish();
4692 lcommunity_finish();
4693 cluster_finish();
4694 transit_finish();
4695 encap_finish();
4696 srv6_finish();
4697 }
4698
4699 /* Make attribute packet. */
4700 void bgp_dump_routes_attr(struct stream *s, struct bgp_path_info *bpi,
4701 const struct prefix *prefix)
4702 {
4703 unsigned long cp;
4704 unsigned long len;
4705 size_t aspath_lenp;
4706 struct aspath *aspath;
4707 bool addpath_capable = false;
4708 uint32_t addpath_tx_id = 0;
4709 struct attr *attr = bpi->attr;
4710
4711 /* Remember current pointer. */
4712 cp = stream_get_endp(s);
4713
4714 /* Place holder of length. */
4715 stream_putw(s, 0);
4716
4717 /* Origin attribute. */
4718 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4719 stream_putc(s, BGP_ATTR_ORIGIN);
4720 stream_putc(s, 1);
4721 stream_putc(s, attr->origin);
4722
4723 aspath = attr->aspath;
4724
4725 stream_putc(s, BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_EXTLEN);
4726 stream_putc(s, BGP_ATTR_AS_PATH);
4727 aspath_lenp = stream_get_endp(s);
4728 stream_putw(s, 0);
4729
4730 stream_putw_at(s, aspath_lenp, aspath_put(s, aspath, 1));
4731
4732 /* Nexthop attribute. */
4733 /* If it's an IPv6 prefix, don't dump the IPv4 nexthop to save space */
4734 if (prefix != NULL && prefix->family != AF_INET6) {
4735 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4736 stream_putc(s, BGP_ATTR_NEXT_HOP);
4737 stream_putc(s, 4);
4738 stream_put_ipv4(s, attr->nexthop.s_addr);
4739 }
4740
4741 /* MED attribute. */
4742 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
4743 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
4744 stream_putc(s, BGP_ATTR_MULTI_EXIT_DISC);
4745 stream_putc(s, 4);
4746 stream_putl(s, attr->med);
4747 }
4748
4749 /* Local preference. */
4750 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
4751 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4752 stream_putc(s, BGP_ATTR_LOCAL_PREF);
4753 stream_putc(s, 4);
4754 stream_putl(s, attr->local_pref);
4755 }
4756
4757 /* Atomic aggregate. */
4758 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
4759 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4760 stream_putc(s, BGP_ATTR_ATOMIC_AGGREGATE);
4761 stream_putc(s, 0);
4762 }
4763
4764 /* Aggregator. */
4765 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR)) {
4766 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
4767 stream_putc(s, BGP_ATTR_AGGREGATOR);
4768 stream_putc(s, 8);
4769 stream_putl(s, attr->aggregator_as);
4770 stream_put_ipv4(s, attr->aggregator_addr.s_addr);
4771 }
4772
4773 /* Community attribute. */
4774 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
4775 struct community *comm = NULL;
4776
4777 comm = bgp_attr_get_community(attr);
4778 if (comm->size * 4 > 255) {
4779 stream_putc(s,
4780 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
4781 | BGP_ATTR_FLAG_EXTLEN);
4782 stream_putc(s, BGP_ATTR_COMMUNITIES);
4783 stream_putw(s, comm->size * 4);
4784 } else {
4785 stream_putc(s,
4786 BGP_ATTR_FLAG_OPTIONAL
4787 | BGP_ATTR_FLAG_TRANS);
4788 stream_putc(s, BGP_ATTR_COMMUNITIES);
4789 stream_putc(s, comm->size * 4);
4790 }
4791 stream_put(s, comm->val, comm->size * 4);
4792 }
4793
4794 /* Large Community attribute. */
4795 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
4796 if (lcom_length(bgp_attr_get_lcommunity(attr)) > 255) {
4797 stream_putc(s,
4798 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
4799 | BGP_ATTR_FLAG_EXTLEN);
4800 stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
4801 stream_putw(s,
4802 lcom_length(bgp_attr_get_lcommunity(attr)));
4803 } else {
4804 stream_putc(s,
4805 BGP_ATTR_FLAG_OPTIONAL
4806 | BGP_ATTR_FLAG_TRANS);
4807 stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
4808 stream_putc(s,
4809 lcom_length(bgp_attr_get_lcommunity(attr)));
4810 }
4811
4812 stream_put(s, bgp_attr_get_lcommunity(attr)->val,
4813 lcom_length(bgp_attr_get_lcommunity(attr)));
4814 }
4815
4816 /* Add a MP_NLRI attribute to dump the IPv6 next hop */
4817 if (prefix != NULL && prefix->family == AF_INET6
4818 && (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL
4819 || attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)) {
4820 int sizep;
4821
4822 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
4823 stream_putc(s, BGP_ATTR_MP_REACH_NLRI);
4824 sizep = stream_get_endp(s);
4825
4826 /* MP header */
4827 stream_putc(s, 0); /* Marker: Attribute length. */
4828 stream_putw(s, AFI_IP6); /* AFI */
4829 stream_putc(s, SAFI_UNICAST); /* SAFI */
4830
4831 /* Next hop */
4832 stream_putc(s, attr->mp_nexthop_len);
4833 stream_put(s, &attr->mp_nexthop_global, IPV6_MAX_BYTELEN);
4834 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
4835 stream_put(s, &attr->mp_nexthop_local,
4836 IPV6_MAX_BYTELEN);
4837
4838 /* SNPA */
4839 stream_putc(s, 0);
4840
4841 /* Prefix */
4842 stream_put_prefix_addpath(s, prefix, addpath_capable,
4843 addpath_tx_id);
4844
4845 /* Set MP attribute length. */
4846 stream_putc_at(s, sizep, (stream_get_endp(s) - sizep) - 1);
4847 }
4848
4849 /* Prefix SID */
4850 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) {
4851 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
4852 stream_putc(s,
4853 BGP_ATTR_FLAG_OPTIONAL
4854 | BGP_ATTR_FLAG_TRANS);
4855 stream_putc(s, BGP_ATTR_PREFIX_SID);
4856 stream_putc(s, 10);
4857 stream_putc(s, BGP_PREFIX_SID_LABEL_INDEX);
4858 stream_putc(s, BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
4859 stream_putc(s, 0); // reserved
4860 stream_putw(s, 0); // flags
4861 stream_putl(s, attr->label_index);
4862 }
4863 }
4864
4865 /* OTC */
4866 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
4867 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
4868 stream_putc(s, BGP_ATTR_OTC);
4869 stream_putc(s, 4);
4870 stream_putl(s, attr->otc);
4871 }
4872
4873 /* AIGP */
4874 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP)) {
4875 /* At the moment only AIGP Metric TLV exists for AIGP
4876 * attribute. If more comes in, do not forget to update
4877 * attr_len variable to include new ones.
4878 */
4879 uint8_t attr_len = BGP_AIGP_TLV_METRIC_LEN;
4880
4881 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
4882 stream_putc(s, BGP_ATTR_AIGP);
4883 stream_putc(s, attr_len);
4884 stream_put_bgp_aigp_tlv_metric(s, bpi);
4885 }
4886
4887 /* Return total size of attribute. */
4888 len = stream_get_endp(s) - cp - 2;
4889 stream_putw_at(s, cp, len);
4890 }