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