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