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