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