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