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