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