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