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