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