]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_attr.c
Merge pull request #5619 from qlyoung/fix-zebra-netlink-undefined-bitshift
[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 ||
2909 safi == SAFI_LABELED_UNICAST ||
2910 safi == SAFI_MULTICAST))
2911 nh_afi = peer_cap_enhe(peer, afi, safi) ? AFI_IP6 : AFI_IP;
2912 else
2913 nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->mp_nexthop_len);
2914
2915 /* Nexthop */
2916 bpacket_attr_vec_arr_set_vec(vecarr, BGP_ATTR_VEC_NH, s, attr);
2917 switch (nh_afi) {
2918 case AFI_IP:
2919 switch (safi) {
2920 case SAFI_UNICAST:
2921 case SAFI_MULTICAST:
2922 case SAFI_LABELED_UNICAST:
2923 stream_putc(s, 4);
2924 stream_put_ipv4(s, attr->nexthop.s_addr);
2925 break;
2926 case SAFI_MPLS_VPN:
2927 stream_putc(s, 12);
2928 stream_putl(s, 0); /* RD = 0, per RFC */
2929 stream_putl(s, 0);
2930 stream_put(s, &attr->mp_nexthop_global_in, 4);
2931 break;
2932 case SAFI_ENCAP:
2933 case SAFI_EVPN:
2934 stream_putc(s, 4);
2935 stream_put(s, &attr->mp_nexthop_global_in, 4);
2936 break;
2937 case SAFI_FLOWSPEC:
2938 stream_putc(s, 0); /* no nexthop for flowspec */
2939 default:
2940 break;
2941 }
2942 break;
2943 case AFI_IP6:
2944 switch (safi) {
2945 case SAFI_UNICAST:
2946 case SAFI_MULTICAST:
2947 case SAFI_LABELED_UNICAST:
2948 case SAFI_EVPN: {
2949 if (attr->mp_nexthop_len
2950 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
2951 stream_putc(s,
2952 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL);
2953 stream_put(s, &attr->mp_nexthop_global,
2954 IPV6_MAX_BYTELEN);
2955 stream_put(s, &attr->mp_nexthop_local,
2956 IPV6_MAX_BYTELEN);
2957 } else {
2958 stream_putc(s, IPV6_MAX_BYTELEN);
2959 stream_put(s, &attr->mp_nexthop_global,
2960 IPV6_MAX_BYTELEN);
2961 }
2962 } break;
2963 case SAFI_MPLS_VPN: {
2964 if (attr->mp_nexthop_len
2965 == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
2966 stream_putc(s, 24);
2967 stream_putl(s, 0); /* RD = 0, per RFC */
2968 stream_putl(s, 0);
2969 stream_put(s, &attr->mp_nexthop_global,
2970 IPV6_MAX_BYTELEN);
2971 } else if (attr->mp_nexthop_len
2972 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
2973 stream_putc(s, 48);
2974 stream_putl(s, 0); /* RD = 0, per RFC */
2975 stream_putl(s, 0);
2976 stream_put(s, &attr->mp_nexthop_global,
2977 IPV6_MAX_BYTELEN);
2978 stream_putl(s, 0); /* RD = 0, per RFC */
2979 stream_putl(s, 0);
2980 stream_put(s, &attr->mp_nexthop_local,
2981 IPV6_MAX_BYTELEN);
2982 }
2983 } break;
2984 case SAFI_ENCAP:
2985 stream_putc(s, IPV6_MAX_BYTELEN);
2986 stream_put(s, &attr->mp_nexthop_global,
2987 IPV6_MAX_BYTELEN);
2988 break;
2989 case SAFI_FLOWSPEC:
2990 stream_putc(s, 0); /* no nexthop for flowspec */
2991 default:
2992 break;
2993 }
2994 break;
2995 default:
2996 if (safi != SAFI_FLOWSPEC)
2997 flog_err(
2998 EC_BGP_ATTR_NH_SEND_LEN,
2999 "Bad nexthop when sending to %s, AFI %u SAFI %u nhlen %d",
3000 peer->host, afi, safi, attr->mp_nexthop_len);
3001 break;
3002 }
3003
3004 /* SNPA */
3005 stream_putc(s, 0);
3006 return sizep;
3007 }
3008
3009 void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
3010 struct prefix *p, struct prefix_rd *prd,
3011 mpls_label_t *label, uint32_t num_labels,
3012 int addpath_encode, uint32_t addpath_tx_id,
3013 struct attr *attr)
3014 {
3015 if (safi == SAFI_MPLS_VPN) {
3016 if (addpath_encode)
3017 stream_putl(s, addpath_tx_id);
3018 /* Label, RD, Prefix write. */
3019 stream_putc(s, p->prefixlen + 88);
3020 stream_put(s, label, BGP_LABEL_BYTES);
3021 stream_put(s, prd->val, 8);
3022 stream_put(s, &p->u.prefix, PSIZE(p->prefixlen));
3023 } else if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
3024 /* EVPN prefix - contents depend on type */
3025 bgp_evpn_encode_prefix(s, p, prd, label, num_labels, attr,
3026 addpath_encode, addpath_tx_id);
3027 } else if (safi == SAFI_LABELED_UNICAST) {
3028 /* Prefix write with label. */
3029 stream_put_labeled_prefix(s, p, label, addpath_encode,
3030 addpath_tx_id);
3031 } else if (safi == SAFI_FLOWSPEC) {
3032 if (PSIZE (p->prefixlen)+2 < FLOWSPEC_NLRI_SIZELIMIT)
3033 stream_putc(s, PSIZE (p->prefixlen)+2);
3034 else
3035 stream_putw(s, (PSIZE (p->prefixlen)+2)|(0xf<<12));
3036 stream_putc(s, 2);/* Filter type */
3037 stream_putc(s, p->prefixlen);/* Prefix length */
3038 stream_put(s, &p->u.prefix, PSIZE (p->prefixlen));
3039 } else
3040 stream_put_prefix_addpath(s, p, addpath_encode, addpath_tx_id);
3041 }
3042
3043 size_t bgp_packet_mpattr_prefix_size(afi_t afi, safi_t safi, struct prefix *p)
3044 {
3045 int size = PSIZE(p->prefixlen);
3046 if (safi == SAFI_MPLS_VPN)
3047 size += 88;
3048 else if (safi == SAFI_LABELED_UNICAST)
3049 size += BGP_LABEL_BYTES;
3050 else if (afi == AFI_L2VPN && safi == SAFI_EVPN)
3051 size += 232; // TODO: Maximum possible for type-2, type-3 and
3052 // type-5
3053 return size;
3054 }
3055
3056 /*
3057 * Encodes the tunnel encapsulation attribute,
3058 * and with ENABLE_BGP_VNC the VNC attribute which uses
3059 * almost the same TLV format
3060 */
3061 static void bgp_packet_mpattr_tea(struct bgp *bgp, struct peer *peer,
3062 struct stream *s, struct attr *attr,
3063 uint8_t attrtype)
3064 {
3065 unsigned int attrlenfield = 0;
3066 unsigned int attrhdrlen = 0;
3067 struct bgp_attr_encap_subtlv *subtlvs;
3068 struct bgp_attr_encap_subtlv *st;
3069 const char *attrname;
3070
3071 if (!attr || (attrtype == BGP_ATTR_ENCAP
3072 && (!attr->encap_tunneltype
3073 || attr->encap_tunneltype == BGP_ENCAP_TYPE_MPLS)))
3074 return;
3075
3076 switch (attrtype) {
3077 case BGP_ATTR_ENCAP:
3078 attrname = "Tunnel Encap";
3079 subtlvs = attr->encap_subtlvs;
3080 if (subtlvs == NULL) /* nothing to do */
3081 return;
3082 /*
3083 * The tunnel encap attr has an "outer" tlv.
3084 * T = tunneltype,
3085 * L = total length of subtlvs,
3086 * V = concatenated subtlvs.
3087 */
3088 attrlenfield = 2 + 2; /* T + L */
3089 attrhdrlen = 1 + 1; /* subTLV T + L */
3090 break;
3091
3092 #if ENABLE_BGP_VNC_ATTR
3093 case BGP_ATTR_VNC:
3094 attrname = "VNC";
3095 subtlvs = attr->vnc_subtlvs;
3096 if (subtlvs == NULL) /* nothing to do */
3097 return;
3098 attrlenfield = 0; /* no outer T + L */
3099 attrhdrlen = 2 + 2; /* subTLV T + L */
3100 break;
3101 #endif
3102
3103 default:
3104 assert(0);
3105 }
3106
3107 /* compute attr length */
3108 for (st = subtlvs; st; st = st->next) {
3109 attrlenfield += (attrhdrlen + st->length);
3110 }
3111
3112 if (attrlenfield > 0xffff) {
3113 zlog_info("%s attribute is too long (length=%d), can't send it",
3114 attrname, attrlenfield);
3115 return;
3116 }
3117
3118 if (attrlenfield > 0xff) {
3119 /* 2-octet length field */
3120 stream_putc(s,
3121 BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL
3122 | BGP_ATTR_FLAG_EXTLEN);
3123 stream_putc(s, attrtype);
3124 stream_putw(s, attrlenfield & 0xffff);
3125 } else {
3126 /* 1-octet length field */
3127 stream_putc(s, BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL);
3128 stream_putc(s, attrtype);
3129 stream_putc(s, attrlenfield & 0xff);
3130 }
3131
3132 if (attrtype == BGP_ATTR_ENCAP) {
3133 /* write outer T+L */
3134 stream_putw(s, attr->encap_tunneltype);
3135 stream_putw(s, attrlenfield - 4);
3136 }
3137
3138 /* write each sub-tlv */
3139 for (st = subtlvs; st; st = st->next) {
3140 if (attrtype == BGP_ATTR_ENCAP) {
3141 stream_putc(s, st->type);
3142 stream_putc(s, st->length);
3143 #if ENABLE_BGP_VNC
3144 } else {
3145 stream_putw(s, st->type);
3146 stream_putw(s, st->length);
3147 #endif
3148 }
3149 stream_put(s, st->value, st->length);
3150 }
3151 }
3152
3153 void bgp_packet_mpattr_end(struct stream *s, size_t sizep)
3154 {
3155 /* Set MP attribute length. Don't count the (2) bytes used to encode
3156 the attr length */
3157 stream_putw_at(s, sizep, (stream_get_endp(s) - sizep) - 2);
3158 }
3159
3160 static int bgp_append_local_as(struct peer *peer, afi_t afi, safi_t safi)
3161 {
3162 if (!BGP_AS_IS_PRIVATE(peer->local_as)
3163 || (BGP_AS_IS_PRIVATE(peer->local_as)
3164 && !CHECK_FLAG(peer->af_flags[afi][safi],
3165 PEER_FLAG_REMOVE_PRIVATE_AS)
3166 && !CHECK_FLAG(peer->af_flags[afi][safi],
3167 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
3168 && !CHECK_FLAG(peer->af_flags[afi][safi],
3169 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
3170 && !CHECK_FLAG(peer->af_flags[afi][safi],
3171 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)))
3172 return 1;
3173 return 0;
3174 }
3175
3176 /* Make attribute packet. */
3177 bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
3178 struct stream *s, struct attr *attr,
3179 struct bpacket_attr_vec_arr *vecarr,
3180 struct prefix *p, afi_t afi, safi_t safi,
3181 struct peer *from, struct prefix_rd *prd,
3182 mpls_label_t *label, uint32_t num_labels,
3183 int addpath_encode, uint32_t addpath_tx_id)
3184 {
3185 size_t cp;
3186 size_t aspath_sizep;
3187 struct aspath *aspath;
3188 int send_as4_path = 0;
3189 int send_as4_aggregator = 0;
3190 int use32bit = (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)) ? 1 : 0;
3191
3192 if (!bgp)
3193 bgp = peer->bgp;
3194
3195 /* Remember current pointer. */
3196 cp = stream_get_endp(s);
3197
3198 if (p
3199 && !((afi == AFI_IP && safi == SAFI_UNICAST)
3200 && !peer_cap_enhe(peer, afi, safi))) {
3201 size_t mpattrlen_pos = 0;
3202
3203 mpattrlen_pos = bgp_packet_mpattr_start(s, peer, afi, safi,
3204 vecarr, attr);
3205 bgp_packet_mpattr_prefix(s, afi, safi, p, prd, label,
3206 num_labels, addpath_encode,
3207 addpath_tx_id, attr);
3208 bgp_packet_mpattr_end(s, mpattrlen_pos);
3209 }
3210
3211 /* Origin attribute. */
3212 stream_putc(s, BGP_ATTR_FLAG_TRANS);
3213 stream_putc(s, BGP_ATTR_ORIGIN);
3214 stream_putc(s, 1);
3215 stream_putc(s, attr->origin);
3216
3217 /* AS path attribute. */
3218
3219 /* If remote-peer is EBGP */
3220 if (peer->sort == BGP_PEER_EBGP
3221 && (!CHECK_FLAG(peer->af_flags[afi][safi],
3222 PEER_FLAG_AS_PATH_UNCHANGED)
3223 || attr->aspath->segments == NULL)
3224 && (!CHECK_FLAG(peer->af_flags[afi][safi],
3225 PEER_FLAG_RSERVER_CLIENT))) {
3226 aspath = aspath_dup(attr->aspath);
3227
3228 /* Even though we may not be configured for confederations we
3229 * may have
3230 * RXed an AS_PATH with AS_CONFED_SEQUENCE or AS_CONFED_SET */
3231 aspath = aspath_delete_confed_seq(aspath);
3232
3233 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
3234 /* Stuff our path CONFED_ID on the front */
3235 aspath = aspath_add_seq(aspath, bgp->confed_id);
3236 } else {
3237 if (peer->change_local_as) {
3238 /* If replace-as is specified, we only use the
3239 change_local_as when
3240 advertising routes. */
3241 if (!CHECK_FLAG(peer->flags,
3242 PEER_FLAG_LOCAL_AS_REPLACE_AS))
3243 if (bgp_append_local_as(peer, afi,
3244 safi))
3245 aspath = aspath_add_seq(
3246 aspath, peer->local_as);
3247 aspath = aspath_add_seq(aspath,
3248 peer->change_local_as);
3249 } else {
3250 aspath = aspath_add_seq(aspath, peer->local_as);
3251 }
3252 }
3253 } else if (peer->sort == BGP_PEER_CONFED) {
3254 /* A confed member, so we need to do the AS_CONFED_SEQUENCE
3255 * thing */
3256 aspath = aspath_dup(attr->aspath);
3257 aspath = aspath_add_confed_seq(aspath, peer->local_as);
3258 } else
3259 aspath = attr->aspath;
3260
3261 /* If peer is not AS4 capable, then:
3262 * - send the created AS_PATH out as AS4_PATH (optional, transitive),
3263 * but ensure that no AS_CONFED_SEQUENCE and AS_CONFED_SET path
3264 * segment
3265 * types are in it (i.e. exclude them if they are there)
3266 * AND do this only if there is at least one asnum > 65535 in the
3267 * path!
3268 * - send an AS_PATH out, but put 16Bit ASnums in it, not 32bit, and
3269 * change
3270 * all ASnums > 65535 to BGP_AS_TRANS
3271 */
3272
3273 stream_putc(s, BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_EXTLEN);
3274 stream_putc(s, BGP_ATTR_AS_PATH);
3275 aspath_sizep = stream_get_endp(s);
3276 stream_putw(s, 0);
3277 stream_putw_at(s, aspath_sizep, aspath_put(s, aspath, use32bit));
3278
3279 /* OLD session may need NEW_AS_PATH sent, if there are 4-byte ASNs
3280 * in the path
3281 */
3282 if (!use32bit && aspath_has_as4(aspath))
3283 send_as4_path =
3284 1; /* we'll do this later, at the correct place */
3285
3286 /* Nexthop attribute. */
3287 if (afi == AFI_IP && safi == SAFI_UNICAST
3288 && !peer_cap_enhe(peer, afi, safi)) {
3289 afi_t nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->mp_nexthop_len);
3290
3291 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3292 stream_putc(s, BGP_ATTR_FLAG_TRANS);
3293 stream_putc(s, BGP_ATTR_NEXT_HOP);
3294 bpacket_attr_vec_arr_set_vec(vecarr, BGP_ATTR_VEC_NH, s,
3295 attr);
3296 stream_putc(s, 4);
3297 stream_put_ipv4(s, attr->nexthop.s_addr);
3298 } else if (peer_cap_enhe(from, afi, safi)
3299 || (nh_afi == AFI_IP6)) {
3300 /*
3301 * Likely this is the case when an IPv4 prefix was
3302 * received with Extended Next-hop capability in this
3303 * or another vrf and is now being advertised to
3304 * non-ENHE peers. Since peer_cap_enhe only checks
3305 * peers in this vrf, also check the nh_afi to catch
3306 * the case where the originator was in another vrf.
3307 * Setting the mandatory (ipv4) next-hop attribute here
3308 * to enable implicit next-hop self with correct A-F
3309 * (ipv4 address family).
3310 */
3311 stream_putc(s, BGP_ATTR_FLAG_TRANS);
3312 stream_putc(s, BGP_ATTR_NEXT_HOP);
3313 bpacket_attr_vec_arr_set_vec(vecarr, BGP_ATTR_VEC_NH, s,
3314 NULL);
3315 stream_putc(s, 4);
3316 stream_put_ipv4(s, 0);
3317 }
3318 }
3319
3320 /* MED attribute. */
3321 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)
3322 || bgp->maxmed_active) {
3323 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
3324 stream_putc(s, BGP_ATTR_MULTI_EXIT_DISC);
3325 stream_putc(s, 4);
3326 stream_putl(s, (bgp->maxmed_active ? bgp->maxmed_value
3327 : attr->med));
3328 }
3329
3330 /* Local preference. */
3331 if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED) {
3332 stream_putc(s, BGP_ATTR_FLAG_TRANS);
3333 stream_putc(s, BGP_ATTR_LOCAL_PREF);
3334 stream_putc(s, 4);
3335 stream_putl(s, attr->local_pref);
3336 }
3337
3338 /* Atomic aggregate. */
3339 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
3340 stream_putc(s, BGP_ATTR_FLAG_TRANS);
3341 stream_putc(s, BGP_ATTR_ATOMIC_AGGREGATE);
3342 stream_putc(s, 0);
3343 }
3344
3345 /* Aggregator. */
3346 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR)) {
3347 /* Common to BGP_ATTR_AGGREGATOR, regardless of ASN size */
3348 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
3349 stream_putc(s, BGP_ATTR_AGGREGATOR);
3350
3351 if (use32bit) {
3352 /* AS4 capable peer */
3353 stream_putc(s, 8);
3354 stream_putl(s, attr->aggregator_as);
3355 } else {
3356 /* 2-byte AS peer */
3357 stream_putc(s, 6);
3358
3359 /* Is ASN representable in 2-bytes? Or must AS_TRANS be
3360 * used? */
3361 if (attr->aggregator_as > 65535) {
3362 stream_putw(s, BGP_AS_TRANS);
3363
3364 /* we have to send AS4_AGGREGATOR, too.
3365 * we'll do that later in order to send
3366 * attributes in ascending
3367 * order.
3368 */
3369 send_as4_aggregator = 1;
3370 } else
3371 stream_putw(s, (uint16_t)attr->aggregator_as);
3372 }
3373 stream_put_ipv4(s, attr->aggregator_addr.s_addr);
3374 }
3375
3376 /* Community attribute. */
3377 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY)
3378 && (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))) {
3379 if (attr->community->size * 4 > 255) {
3380 stream_putc(s,
3381 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
3382 | BGP_ATTR_FLAG_EXTLEN);
3383 stream_putc(s, BGP_ATTR_COMMUNITIES);
3384 stream_putw(s, attr->community->size * 4);
3385 } else {
3386 stream_putc(s,
3387 BGP_ATTR_FLAG_OPTIONAL
3388 | BGP_ATTR_FLAG_TRANS);
3389 stream_putc(s, BGP_ATTR_COMMUNITIES);
3390 stream_putc(s, attr->community->size * 4);
3391 }
3392 stream_put(s, attr->community->val, attr->community->size * 4);
3393 }
3394
3395 /*
3396 * Large Community attribute.
3397 */
3398 if (CHECK_FLAG(peer->af_flags[afi][safi],
3399 PEER_FLAG_SEND_LARGE_COMMUNITY)
3400 && (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))) {
3401 if (lcom_length(attr->lcommunity) > 255) {
3402 stream_putc(s,
3403 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
3404 | BGP_ATTR_FLAG_EXTLEN);
3405 stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
3406 stream_putw(s, lcom_length(attr->lcommunity));
3407 } else {
3408 stream_putc(s,
3409 BGP_ATTR_FLAG_OPTIONAL
3410 | BGP_ATTR_FLAG_TRANS);
3411 stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
3412 stream_putc(s, lcom_length(attr->lcommunity));
3413 }
3414 stream_put(s, attr->lcommunity->val,
3415 lcom_length(attr->lcommunity));
3416 }
3417
3418 /* Route Reflector. */
3419 if (peer->sort == BGP_PEER_IBGP && from
3420 && from->sort == BGP_PEER_IBGP) {
3421 /* Originator ID. */
3422 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
3423 stream_putc(s, BGP_ATTR_ORIGINATOR_ID);
3424 stream_putc(s, 4);
3425
3426 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
3427 stream_put_in_addr(s, &attr->originator_id);
3428 else
3429 stream_put_in_addr(s, &from->remote_id);
3430
3431 /* Cluster list. */
3432 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
3433 stream_putc(s, BGP_ATTR_CLUSTER_LIST);
3434
3435 if (attr->cluster) {
3436 stream_putc(s, attr->cluster->length + 4);
3437 /* If this peer configuration's parent BGP has
3438 * cluster_id. */
3439 if (bgp->config & BGP_CONFIG_CLUSTER_ID)
3440 stream_put_in_addr(s, &bgp->cluster_id);
3441 else
3442 stream_put_in_addr(s, &bgp->router_id);
3443 stream_put(s, attr->cluster->list,
3444 attr->cluster->length);
3445 } else {
3446 stream_putc(s, 4);
3447 /* If this peer configuration's parent BGP has
3448 * cluster_id. */
3449 if (bgp->config & BGP_CONFIG_CLUSTER_ID)
3450 stream_put_in_addr(s, &bgp->cluster_id);
3451 else
3452 stream_put_in_addr(s, &bgp->router_id);
3453 }
3454 }
3455
3456 /* Extended Communities attribute. */
3457 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY)
3458 && (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
3459 if (peer->sort == BGP_PEER_IBGP
3460 || peer->sort == BGP_PEER_CONFED) {
3461 if (attr->ecommunity->size * 8 > 255) {
3462 stream_putc(s,
3463 BGP_ATTR_FLAG_OPTIONAL
3464 | BGP_ATTR_FLAG_TRANS
3465 | BGP_ATTR_FLAG_EXTLEN);
3466 stream_putc(s, BGP_ATTR_EXT_COMMUNITIES);
3467 stream_putw(s, attr->ecommunity->size * 8);
3468 } else {
3469 stream_putc(s,
3470 BGP_ATTR_FLAG_OPTIONAL
3471 | BGP_ATTR_FLAG_TRANS);
3472 stream_putc(s, BGP_ATTR_EXT_COMMUNITIES);
3473 stream_putc(s, attr->ecommunity->size * 8);
3474 }
3475 stream_put(s, attr->ecommunity->val,
3476 attr->ecommunity->size * 8);
3477 } else {
3478 uint8_t *pnt;
3479 int tbit;
3480 int ecom_tr_size = 0;
3481 int i;
3482
3483 for (i = 0; i < attr->ecommunity->size; i++) {
3484 pnt = attr->ecommunity->val + (i * 8);
3485 tbit = *pnt;
3486
3487 if (CHECK_FLAG(tbit,
3488 ECOMMUNITY_FLAG_NON_TRANSITIVE))
3489 continue;
3490
3491 ecom_tr_size++;
3492 }
3493
3494 if (ecom_tr_size) {
3495 if (ecom_tr_size * 8 > 255) {
3496 stream_putc(
3497 s,
3498 BGP_ATTR_FLAG_OPTIONAL
3499 | BGP_ATTR_FLAG_TRANS
3500 | BGP_ATTR_FLAG_EXTLEN);
3501 stream_putc(s,
3502 BGP_ATTR_EXT_COMMUNITIES);
3503 stream_putw(s, ecom_tr_size * 8);
3504 } else {
3505 stream_putc(
3506 s,
3507 BGP_ATTR_FLAG_OPTIONAL
3508 | BGP_ATTR_FLAG_TRANS);
3509 stream_putc(s,
3510 BGP_ATTR_EXT_COMMUNITIES);
3511 stream_putc(s, ecom_tr_size * 8);
3512 }
3513
3514 for (i = 0; i < attr->ecommunity->size; i++) {
3515 pnt = attr->ecommunity->val + (i * 8);
3516 tbit = *pnt;
3517
3518 if (CHECK_FLAG(
3519 tbit,
3520 ECOMMUNITY_FLAG_NON_TRANSITIVE))
3521 continue;
3522
3523 stream_put(s, pnt, 8);
3524 }
3525 }
3526 }
3527 }
3528
3529 /* Label index attribute. */
3530 if (safi == SAFI_LABELED_UNICAST) {
3531 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) {
3532 uint32_t label_index;
3533
3534 label_index = attr->label_index;
3535
3536 if (label_index != BGP_INVALID_LABEL_INDEX) {
3537 stream_putc(s,
3538 BGP_ATTR_FLAG_OPTIONAL
3539 | BGP_ATTR_FLAG_TRANS);
3540 stream_putc(s, BGP_ATTR_PREFIX_SID);
3541 stream_putc(s, 10);
3542 stream_putc(s, BGP_PREFIX_SID_LABEL_INDEX);
3543 stream_putw(s,
3544 BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
3545 stream_putc(s, 0); // reserved
3546 stream_putw(s, 0); // flags
3547 stream_putl(s, label_index);
3548 }
3549 }
3550 }
3551
3552 if (send_as4_path) {
3553 /* If the peer is NOT As4 capable, AND */
3554 /* there are ASnums > 65535 in path THEN
3555 * give out AS4_PATH */
3556
3557 /* Get rid of all AS_CONFED_SEQUENCE and AS_CONFED_SET
3558 * path segments!
3559 * Hm, I wonder... confederation things *should* only be at
3560 * the beginning of an aspath, right? Then we should use
3561 * aspath_delete_confed_seq for this, because it is already
3562 * there! (JK)
3563 * Folks, talk to me: what is reasonable here!?
3564 */
3565 aspath = aspath_delete_confed_seq(aspath);
3566
3567 stream_putc(s,
3568 BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL
3569 | BGP_ATTR_FLAG_EXTLEN);
3570 stream_putc(s, BGP_ATTR_AS4_PATH);
3571 aspath_sizep = stream_get_endp(s);
3572 stream_putw(s, 0);
3573 stream_putw_at(s, aspath_sizep, aspath_put(s, aspath, 1));
3574 }
3575
3576 if (aspath != attr->aspath)
3577 aspath_free(aspath);
3578
3579 if (send_as4_aggregator) {
3580 /* send AS4_AGGREGATOR, at this place */
3581 /* this section of code moved here in order to ensure the
3582 * correct
3583 * *ascending* order of attributes
3584 */
3585 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
3586 stream_putc(s, BGP_ATTR_AS4_AGGREGATOR);
3587 stream_putc(s, 8);
3588 stream_putl(s, attr->aggregator_as);
3589 stream_put_ipv4(s, attr->aggregator_addr.s_addr);
3590 }
3591
3592 if (((afi == AFI_IP || afi == AFI_IP6)
3593 && (safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN))
3594 || (afi == AFI_L2VPN && safi == SAFI_EVPN)) {
3595 /* Tunnel Encap attribute */
3596 bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_ENCAP);
3597
3598 #if ENABLE_BGP_VNC_ATTR
3599 /* VNC attribute */
3600 bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_VNC);
3601 #endif
3602 }
3603
3604 /* PMSI Tunnel */
3605 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
3606 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
3607 stream_putc(s, BGP_ATTR_PMSI_TUNNEL);
3608 stream_putc(s, 9); // Length
3609 stream_putc(s, 0); // Flags
3610 stream_putc(s, attr->pmsi_tnl_type);
3611 stream_put(s, &(attr->label),
3612 BGP_LABEL_BYTES); // MPLS Label / VXLAN VNI
3613 stream_put_ipv4(s, attr->nexthop.s_addr);
3614 // Unicast tunnel endpoint IP address
3615 }
3616
3617 /* Unknown transit attribute. */
3618 if (attr->transit)
3619 stream_put(s, attr->transit->val, attr->transit->length);
3620
3621 /* Return total size of attribute. */
3622 return stream_get_endp(s) - cp;
3623 }
3624
3625 size_t bgp_packet_mpunreach_start(struct stream *s, afi_t afi, safi_t safi)
3626 {
3627 unsigned long attrlen_pnt;
3628 iana_afi_t pkt_afi;
3629 iana_safi_t pkt_safi;
3630
3631 /* Set extended bit always to encode the attribute length as 2 bytes */
3632 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_EXTLEN);
3633 stream_putc(s, BGP_ATTR_MP_UNREACH_NLRI);
3634
3635 attrlen_pnt = stream_get_endp(s);
3636 stream_putw(s, 0); /* Length of this attribute. */
3637
3638 /* Convert AFI, SAFI to values for packet. */
3639 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
3640
3641 stream_putw(s, pkt_afi);
3642 stream_putc(s, pkt_safi);
3643
3644 return attrlen_pnt;
3645 }
3646
3647 void bgp_packet_mpunreach_prefix(struct stream *s, struct prefix *p, afi_t afi,
3648 safi_t safi, struct prefix_rd *prd,
3649 mpls_label_t *label, uint32_t num_labels,
3650 int addpath_encode, uint32_t addpath_tx_id,
3651 struct attr *attr)
3652 {
3653 uint8_t wlabel[3] = {0x80, 0x00, 0x00};
3654
3655 if (safi == SAFI_LABELED_UNICAST) {
3656 label = (mpls_label_t *)wlabel;
3657 num_labels = 1;
3658 }
3659
3660 bgp_packet_mpattr_prefix(s, afi, safi, p, prd, label, num_labels,
3661 addpath_encode, addpath_tx_id, attr);
3662 }
3663
3664 void bgp_packet_mpunreach_end(struct stream *s, size_t attrlen_pnt)
3665 {
3666 bgp_packet_mpattr_end(s, attrlen_pnt);
3667 }
3668
3669 /* Initialization of attribute. */
3670 void bgp_attr_init(void)
3671 {
3672 aspath_init();
3673 attrhash_init();
3674 community_init();
3675 ecommunity_init();
3676 lcommunity_init();
3677 cluster_init();
3678 transit_init();
3679 encap_init();
3680 }
3681
3682 void bgp_attr_finish(void)
3683 {
3684 aspath_finish();
3685 attrhash_finish();
3686 community_finish();
3687 ecommunity_finish();
3688 lcommunity_finish();
3689 cluster_finish();
3690 transit_finish();
3691 encap_finish();
3692 }
3693
3694 /* Make attribute packet. */
3695 void bgp_dump_routes_attr(struct stream *s, struct attr *attr,
3696 struct prefix *prefix)
3697 {
3698 unsigned long cp;
3699 unsigned long len;
3700 size_t aspath_lenp;
3701 struct aspath *aspath;
3702 int addpath_encode = 0;
3703 uint32_t addpath_tx_id = 0;
3704
3705 /* Remember current pointer. */
3706 cp = stream_get_endp(s);
3707
3708 /* Place holder of length. */
3709 stream_putw(s, 0);
3710
3711 /* Origin attribute. */
3712 stream_putc(s, BGP_ATTR_FLAG_TRANS);
3713 stream_putc(s, BGP_ATTR_ORIGIN);
3714 stream_putc(s, 1);
3715 stream_putc(s, attr->origin);
3716
3717 aspath = attr->aspath;
3718
3719 stream_putc(s, BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_EXTLEN);
3720 stream_putc(s, BGP_ATTR_AS_PATH);
3721 aspath_lenp = stream_get_endp(s);
3722 stream_putw(s, 0);
3723
3724 stream_putw_at(s, aspath_lenp, aspath_put(s, aspath, 1));
3725
3726 /* Nexthop attribute. */
3727 /* If it's an IPv6 prefix, don't dump the IPv4 nexthop to save space */
3728 if (prefix != NULL && prefix->family != AF_INET6) {
3729 stream_putc(s, BGP_ATTR_FLAG_TRANS);
3730 stream_putc(s, BGP_ATTR_NEXT_HOP);
3731 stream_putc(s, 4);
3732 stream_put_ipv4(s, attr->nexthop.s_addr);
3733 }
3734
3735 /* MED attribute. */
3736 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
3737 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
3738 stream_putc(s, BGP_ATTR_MULTI_EXIT_DISC);
3739 stream_putc(s, 4);
3740 stream_putl(s, attr->med);
3741 }
3742
3743 /* Local preference. */
3744 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
3745 stream_putc(s, BGP_ATTR_FLAG_TRANS);
3746 stream_putc(s, BGP_ATTR_LOCAL_PREF);
3747 stream_putc(s, 4);
3748 stream_putl(s, attr->local_pref);
3749 }
3750
3751 /* Atomic aggregate. */
3752 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
3753 stream_putc(s, BGP_ATTR_FLAG_TRANS);
3754 stream_putc(s, BGP_ATTR_ATOMIC_AGGREGATE);
3755 stream_putc(s, 0);
3756 }
3757
3758 /* Aggregator. */
3759 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR)) {
3760 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
3761 stream_putc(s, BGP_ATTR_AGGREGATOR);
3762 stream_putc(s, 8);
3763 stream_putl(s, attr->aggregator_as);
3764 stream_put_ipv4(s, attr->aggregator_addr.s_addr);
3765 }
3766
3767 /* Community attribute. */
3768 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
3769 if (attr->community->size * 4 > 255) {
3770 stream_putc(s,
3771 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
3772 | BGP_ATTR_FLAG_EXTLEN);
3773 stream_putc(s, BGP_ATTR_COMMUNITIES);
3774 stream_putw(s, attr->community->size * 4);
3775 } else {
3776 stream_putc(s,
3777 BGP_ATTR_FLAG_OPTIONAL
3778 | BGP_ATTR_FLAG_TRANS);
3779 stream_putc(s, BGP_ATTR_COMMUNITIES);
3780 stream_putc(s, attr->community->size * 4);
3781 }
3782 stream_put(s, attr->community->val, attr->community->size * 4);
3783 }
3784
3785 /* Large Community attribute. */
3786 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
3787 if (lcom_length(attr->lcommunity) > 255) {
3788 stream_putc(s,
3789 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
3790 | BGP_ATTR_FLAG_EXTLEN);
3791 stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
3792 stream_putw(s, lcom_length(attr->lcommunity));
3793 } else {
3794 stream_putc(s,
3795 BGP_ATTR_FLAG_OPTIONAL
3796 | BGP_ATTR_FLAG_TRANS);
3797 stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
3798 stream_putc(s, lcom_length(attr->lcommunity));
3799 }
3800
3801 stream_put(s, attr->lcommunity->val,
3802 lcom_length(attr->lcommunity));
3803 }
3804
3805 /* Add a MP_NLRI attribute to dump the IPv6 next hop */
3806 if (prefix != NULL && prefix->family == AF_INET6
3807 && (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL
3808 || attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)) {
3809 int sizep;
3810
3811 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
3812 stream_putc(s, BGP_ATTR_MP_REACH_NLRI);
3813 sizep = stream_get_endp(s);
3814
3815 /* MP header */
3816 stream_putc(s, 0); /* Marker: Attribute length. */
3817 stream_putw(s, AFI_IP6); /* AFI */
3818 stream_putc(s, SAFI_UNICAST); /* SAFI */
3819
3820 /* Next hop */
3821 stream_putc(s, attr->mp_nexthop_len);
3822 stream_put(s, &attr->mp_nexthop_global, IPV6_MAX_BYTELEN);
3823 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
3824 stream_put(s, &attr->mp_nexthop_local,
3825 IPV6_MAX_BYTELEN);
3826
3827 /* SNPA */
3828 stream_putc(s, 0);
3829
3830 /* Prefix */
3831 stream_put_prefix_addpath(s, prefix, addpath_encode,
3832 addpath_tx_id);
3833
3834 /* Set MP attribute length. */
3835 stream_putc_at(s, sizep, (stream_get_endp(s) - sizep) - 1);
3836 }
3837
3838 /* Prefix SID */
3839 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) {
3840 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
3841 stream_putc(s,
3842 BGP_ATTR_FLAG_OPTIONAL
3843 | BGP_ATTR_FLAG_TRANS);
3844 stream_putc(s, BGP_ATTR_PREFIX_SID);
3845 stream_putc(s, 10);
3846 stream_putc(s, BGP_PREFIX_SID_LABEL_INDEX);
3847 stream_putc(s, BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
3848 stream_putc(s, 0); // reserved
3849 stream_putw(s, 0); // flags
3850 stream_putl(s, attr->label_index);
3851 }
3852 }
3853
3854 /* Return total size of attribute. */
3855 len = stream_get_endp(s) - cp - 2;
3856 stream_putw_at(s, cp, len);
3857 }