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