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