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