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