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