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