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