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