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