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