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