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