]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_attr.c
Merge pull request #8734 from imzyxwvu/paf-deactivate
[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(peer->curr, length,
1501 CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV));
1502
1503 /* In case of IBGP, length will be zero. */
1504 if (!attr->aspath) {
1505 flog_err(EC_BGP_ATTR_MAL_AS_PATH,
1506 "Malformed AS path from %s, length is %d", peer->host,
1507 length);
1508 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_MAL_AS_PATH,
1509 0);
1510 }
1511
1512 /* Set aspath attribute flag. */
1513 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AS_PATH);
1514
1515 return BGP_ATTR_PARSE_PROCEED;
1516 }
1517
1518 static bgp_attr_parse_ret_t bgp_attr_aspath_check(struct peer *const peer,
1519 struct attr *const attr)
1520 {
1521 /* These checks were part of bgp_attr_aspath, but with
1522 * as4 we should to check aspath things when
1523 * aspath synthesizing with as4_path has already taken place.
1524 * Otherwise we check ASPATH and use the synthesized thing, and that is
1525 * not right.
1526 * So do the checks later, i.e. here
1527 */
1528 struct aspath *aspath;
1529
1530 /* Confederation sanity check. */
1531 if ((peer->sort == BGP_PEER_CONFED
1532 && !aspath_left_confed_check(attr->aspath))
1533 || (peer->sort == BGP_PEER_EBGP
1534 && aspath_confed_check(attr->aspath))) {
1535 flog_err(EC_BGP_ATTR_MAL_AS_PATH, "Malformed AS path from %s",
1536 peer->host);
1537 return BGP_ATTR_PARSE_WITHDRAW;
1538 }
1539
1540 /* First AS check for EBGP. */
1541 if (CHECK_FLAG(peer->flags, PEER_FLAG_ENFORCE_FIRST_AS)) {
1542 if (peer->sort == BGP_PEER_EBGP
1543 && !aspath_firstas_check(attr->aspath, peer->as)) {
1544 flog_err(EC_BGP_ATTR_FIRST_AS,
1545 "%s incorrect first AS (must be %u)",
1546 peer->host, peer->as);
1547 return BGP_ATTR_PARSE_WITHDRAW;
1548 }
1549 }
1550
1551 /* Codification of AS 0 Processing */
1552 if (peer->sort == BGP_PEER_EBGP && aspath_check_as_zero(attr->aspath)) {
1553 flog_err(
1554 EC_BGP_ATTR_MAL_AS_PATH,
1555 "Malformed AS path, AS number is 0 in the path from %s",
1556 peer->host);
1557 return BGP_ATTR_PARSE_WITHDRAW;
1558 }
1559
1560 /* local-as prepend */
1561 if (peer->change_local_as
1562 && !CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND)) {
1563 aspath = aspath_dup(attr->aspath);
1564 aspath = aspath_add_seq(aspath, peer->change_local_as);
1565 aspath_unintern(&attr->aspath);
1566 attr->aspath = aspath_intern(aspath);
1567 }
1568
1569 return BGP_ATTR_PARSE_PROCEED;
1570 }
1571
1572 /* Parse AS4 path information. This function is another wrapper of
1573 aspath_parse. */
1574 static int bgp_attr_as4_path(struct bgp_attr_parser_args *args,
1575 struct aspath **as4_path)
1576 {
1577 struct peer *const peer = args->peer;
1578 struct attr *const attr = args->attr;
1579 const bgp_size_t length = args->length;
1580
1581 *as4_path = aspath_parse(peer->curr, length, 1);
1582
1583 /* In case of IBGP, length will be zero. */
1584 if (!*as4_path) {
1585 flog_err(EC_BGP_ATTR_MAL_AS_PATH,
1586 "Malformed AS4 path from %s, length is %d", peer->host,
1587 length);
1588 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_MAL_AS_PATH,
1589 0);
1590 }
1591
1592 /* Set aspath attribute flag. */
1593 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AS4_PATH);
1594
1595 return BGP_ATTR_PARSE_PROCEED;
1596 }
1597
1598 /*
1599 * Check that the nexthop attribute is valid.
1600 */
1601 bgp_attr_parse_ret_t
1602 bgp_attr_nexthop_valid(struct peer *peer, struct attr *attr)
1603 {
1604 in_addr_t nexthop_h;
1605
1606 nexthop_h = ntohl(attr->nexthop.s_addr);
1607 if ((IPV4_NET0(nexthop_h) || IPV4_NET127(nexthop_h)
1608 || IPV4_CLASS_DE(nexthop_h))
1609 && !BGP_DEBUG(allow_martians, ALLOW_MARTIANS)) {
1610 uint8_t data[7]; /* type(2) + length(1) + nhop(4) */
1611 char buf[INET_ADDRSTRLEN];
1612
1613 inet_ntop(AF_INET, &attr->nexthop.s_addr, buf,
1614 INET_ADDRSTRLEN);
1615 flog_err(EC_BGP_ATTR_MARTIAN_NH, "Martian nexthop %s",
1616 buf);
1617 data[0] = BGP_ATTR_FLAG_TRANS;
1618 data[1] = BGP_ATTR_NEXT_HOP;
1619 data[2] = BGP_ATTR_NHLEN_IPV4;
1620 memcpy(&data[3], &attr->nexthop.s_addr, BGP_ATTR_NHLEN_IPV4);
1621 bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR,
1622 BGP_NOTIFY_UPDATE_INVAL_NEXT_HOP,
1623 data, 7);
1624 return BGP_ATTR_PARSE_ERROR;
1625 }
1626
1627 return BGP_ATTR_PARSE_PROCEED;
1628 }
1629
1630 /* Nexthop attribute. */
1631 static bgp_attr_parse_ret_t bgp_attr_nexthop(struct bgp_attr_parser_args *args)
1632 {
1633 struct peer *const peer = args->peer;
1634 struct attr *const attr = args->attr;
1635 const bgp_size_t length = args->length;
1636
1637 /* Check nexthop attribute length. */
1638 if (length != 4) {
1639 flog_err(EC_BGP_ATTR_LEN,
1640 "Nexthop attribute length isn't four [%d]", length);
1641
1642 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1643 args->total);
1644 }
1645
1646 attr->nexthop.s_addr = stream_get_ipv4(peer->curr);
1647 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
1648
1649 return BGP_ATTR_PARSE_PROCEED;
1650 }
1651
1652 /* MED atrribute. */
1653 static bgp_attr_parse_ret_t bgp_attr_med(struct bgp_attr_parser_args *args)
1654 {
1655 struct peer *const peer = args->peer;
1656 struct attr *const attr = args->attr;
1657 const bgp_size_t length = args->length;
1658
1659 /* Length check. */
1660 if (length != 4) {
1661 flog_err(EC_BGP_ATTR_LEN,
1662 "MED attribute length isn't four [%d]", length);
1663
1664 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1665 args->total);
1666 }
1667
1668 attr->med = stream_getl(peer->curr);
1669
1670 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
1671
1672 return BGP_ATTR_PARSE_PROCEED;
1673 }
1674
1675 /* Local preference attribute. */
1676 static bgp_attr_parse_ret_t
1677 bgp_attr_local_pref(struct bgp_attr_parser_args *args)
1678 {
1679 struct peer *const peer = args->peer;
1680 struct attr *const attr = args->attr;
1681 const bgp_size_t length = args->length;
1682
1683 /* if received from an internal neighbor, it SHALL be considered
1684 * malformed if its length is not equal to 4. If malformed, the
1685 * UPDATE message SHALL be handled using the approach of "treat-as-
1686 * withdraw".
1687 */
1688 if (peer->sort == BGP_PEER_IBGP && length != 4) {
1689 flog_err(EC_BGP_ATTR_LEN,
1690 "LOCAL_PREF attribute length isn't 4 [%u]", length);
1691 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1692 args->total);
1693 }
1694
1695 /* If it is contained in an UPDATE message that is received from an
1696 external peer, then this attribute MUST be ignored by the
1697 receiving speaker. */
1698 if (peer->sort == BGP_PEER_EBGP) {
1699 STREAM_FORWARD_GETP(peer->curr, length);
1700 return BGP_ATTR_PARSE_PROCEED;
1701 }
1702
1703 STREAM_GETL(peer->curr, attr->local_pref);
1704
1705 /* Set the local-pref flag. */
1706 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1707
1708 return BGP_ATTR_PARSE_PROCEED;
1709
1710 stream_failure:
1711 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1712 args->total);
1713 }
1714
1715 /* Atomic aggregate. */
1716 static int bgp_attr_atomic(struct bgp_attr_parser_args *args)
1717 {
1718 struct attr *const attr = args->attr;
1719 const bgp_size_t length = args->length;
1720
1721 /* Length check. */
1722 if (length != 0) {
1723 flog_err(EC_BGP_ATTR_LEN,
1724 "ATOMIC_AGGREGATE attribute length isn't 0 [%u]",
1725 length);
1726 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1727 args->total);
1728 }
1729
1730 /* Set atomic aggregate flag. */
1731 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
1732
1733 return BGP_ATTR_PARSE_PROCEED;
1734 }
1735
1736 /* Aggregator attribute */
1737 static int bgp_attr_aggregator(struct bgp_attr_parser_args *args)
1738 {
1739 struct peer *const peer = args->peer;
1740 struct attr *const attr = args->attr;
1741 const bgp_size_t length = args->length;
1742 as_t aggregator_as;
1743
1744 int wantedlen = 6;
1745
1746 /* peer with AS4 will send 4 Byte AS, peer without will send 2 Byte */
1747 if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)
1748 && CHECK_FLAG(peer->cap, PEER_CAP_AS4_ADV))
1749 wantedlen = 8;
1750
1751 if (length != wantedlen) {
1752 flog_err(EC_BGP_ATTR_LEN,
1753 "AGGREGATOR attribute length isn't %u [%u]", wantedlen,
1754 length);
1755 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1756 args->total);
1757 }
1758
1759 if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV))
1760 aggregator_as = stream_getl(peer->curr);
1761 else
1762 aggregator_as = stream_getw(peer->curr);
1763
1764 attr->aggregator_as = aggregator_as;
1765 attr->aggregator_addr.s_addr = stream_get_ipv4(peer->curr);
1766
1767 /* Codification of AS 0 Processing */
1768 if (aggregator_as == BGP_AS_ZERO) {
1769 flog_err(EC_BGP_ATTR_LEN,
1770 "%s: AGGREGATOR AS number is 0 for aspath: %s",
1771 peer->host, aspath_print(attr->aspath));
1772
1773 if (bgp_debug_update(peer, NULL, NULL, 1)) {
1774 char attr_str[BUFSIZ] = {0};
1775
1776 bgp_dump_attr(attr, attr_str, sizeof(attr_str));
1777
1778 zlog_debug("%s: attributes: %s", __func__, attr_str);
1779 }
1780 } else {
1781 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR);
1782 }
1783
1784 return BGP_ATTR_PARSE_PROCEED;
1785 }
1786
1787 /* New Aggregator attribute */
1788 static bgp_attr_parse_ret_t
1789 bgp_attr_as4_aggregator(struct bgp_attr_parser_args *args,
1790 as_t *as4_aggregator_as,
1791 struct in_addr *as4_aggregator_addr)
1792 {
1793 struct peer *const peer = args->peer;
1794 struct attr *const attr = args->attr;
1795 const bgp_size_t length = args->length;
1796 as_t aggregator_as;
1797
1798 if (length != 8) {
1799 flog_err(EC_BGP_ATTR_LEN, "New Aggregator length is not 8 [%d]",
1800 length);
1801 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1802 0);
1803 }
1804
1805 aggregator_as = stream_getl(peer->curr);
1806
1807 *as4_aggregator_as = aggregator_as;
1808 as4_aggregator_addr->s_addr = stream_get_ipv4(peer->curr);
1809
1810 /* Codification of AS 0 Processing */
1811 if (aggregator_as == BGP_AS_ZERO) {
1812 flog_err(EC_BGP_ATTR_LEN,
1813 "%s: AS4_AGGREGATOR AS number is 0 for aspath: %s",
1814 peer->host, aspath_print(attr->aspath));
1815
1816 if (bgp_debug_update(peer, NULL, NULL, 1)) {
1817 char attr_str[BUFSIZ] = {0};
1818
1819 bgp_dump_attr(attr, attr_str, sizeof(attr_str));
1820
1821 zlog_debug("%s: attributes: %s", __func__, attr_str);
1822 }
1823 } else {
1824 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AS4_AGGREGATOR);
1825 }
1826
1827 return BGP_ATTR_PARSE_PROCEED;
1828 }
1829
1830 /* Munge Aggregator and New-Aggregator, AS_PATH and NEW_AS_PATH.
1831 */
1832 static bgp_attr_parse_ret_t
1833 bgp_attr_munge_as4_attrs(struct peer *const peer, struct attr *const attr,
1834 struct aspath *as4_path, as_t as4_aggregator,
1835 struct in_addr *as4_aggregator_addr)
1836 {
1837 int ignore_as4_path = 0;
1838 struct aspath *newpath;
1839
1840 if (!attr->aspath) {
1841 /* NULL aspath shouldn't be possible as bgp_attr_parse should
1842 * have
1843 * checked that all well-known, mandatory attributes were
1844 * present.
1845 *
1846 * Can only be a problem with peer itself - hard error
1847 */
1848 return BGP_ATTR_PARSE_ERROR;
1849 }
1850
1851 if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)) {
1852 /* peer can do AS4, so we ignore AS4_PATH and AS4_AGGREGATOR
1853 * if given.
1854 * It is worth a warning though, because the peer really
1855 * should not send them
1856 */
1857 if (BGP_DEBUG(as4, AS4)) {
1858 if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS4_PATH)))
1859 zlog_debug("[AS4] %s %s AS4_PATH", peer->host,
1860 "AS4 capable peer, yet it sent");
1861
1862 if (attr->flag
1863 & (ATTR_FLAG_BIT(BGP_ATTR_AS4_AGGREGATOR)))
1864 zlog_debug("[AS4] %s %s AS4_AGGREGATOR",
1865 peer->host,
1866 "AS4 capable peer, yet it sent");
1867 }
1868
1869 return BGP_ATTR_PARSE_PROCEED;
1870 }
1871
1872 /* We have a asn16 peer. First, look for AS4_AGGREGATOR
1873 * because that may override AS4_PATH
1874 */
1875 if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS4_AGGREGATOR))) {
1876 if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
1877 /* received both.
1878 * if the as_number in aggregator is not AS_TRANS,
1879 * then AS4_AGGREGATOR and AS4_PATH shall be ignored
1880 * and the Aggregator shall be taken as
1881 * info on the aggregating node, and the AS_PATH
1882 * shall be taken as the AS_PATH
1883 * otherwise
1884 * the Aggregator shall be ignored and the
1885 * AS4_AGGREGATOR shall be taken as the
1886 * Aggregating node and the AS_PATH is to be
1887 * constructed "as in all other cases"
1888 */
1889 if (attr->aggregator_as != BGP_AS_TRANS) {
1890 /* ignore */
1891 if (BGP_DEBUG(as4, AS4))
1892 zlog_debug(
1893 "[AS4] %s BGP not AS4 capable peer send AGGREGATOR != AS_TRANS and AS4_AGGREGATOR, so ignore AS4_AGGREGATOR and AS4_PATH",
1894 peer->host);
1895 ignore_as4_path = 1;
1896 } else {
1897 /* "New_aggregator shall be taken as aggregator"
1898 */
1899 attr->aggregator_as = as4_aggregator;
1900 attr->aggregator_addr.s_addr =
1901 as4_aggregator_addr->s_addr;
1902 }
1903 } else {
1904 /* We received a AS4_AGGREGATOR but no AGGREGATOR.
1905 * That is bogus - but reading the conditions
1906 * we have to handle AS4_AGGREGATOR as if it were
1907 * AGGREGATOR in that case
1908 */
1909 if (BGP_DEBUG(as4, AS4))
1910 zlog_debug(
1911 "[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",
1912 peer->host);
1913 attr->aggregator_as = as4_aggregator;
1914 /* sweep it under the carpet and simulate a "good"
1915 * AGGREGATOR */
1916 attr->flag |= (ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR));
1917 }
1918 }
1919
1920 /* need to reconcile NEW_AS_PATH and AS_PATH */
1921 if (!ignore_as4_path
1922 && (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS4_PATH)))) {
1923 newpath = aspath_reconcile_as4(attr->aspath, as4_path);
1924 if (!newpath)
1925 return BGP_ATTR_PARSE_ERROR;
1926
1927 aspath_unintern(&attr->aspath);
1928 attr->aspath = aspath_intern(newpath);
1929 }
1930 return BGP_ATTR_PARSE_PROCEED;
1931 }
1932
1933 /* Community attribute. */
1934 static bgp_attr_parse_ret_t
1935 bgp_attr_community(struct bgp_attr_parser_args *args)
1936 {
1937 struct peer *const peer = args->peer;
1938 struct attr *const attr = args->attr;
1939 const bgp_size_t length = args->length;
1940
1941 if (length == 0) {
1942 attr->community = NULL;
1943 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
1944 args->total);
1945 }
1946
1947 attr->community =
1948 community_parse((uint32_t *)stream_pnt(peer->curr), length);
1949
1950 /* XXX: fix community_parse to use stream API and remove this */
1951 stream_forward_getp(peer->curr, length);
1952
1953 /* The Community attribute SHALL be considered malformed if its
1954 * length is not a non-zero multiple of 4.
1955 */
1956 if (!attr->community)
1957 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
1958 args->total);
1959
1960 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
1961
1962 return BGP_ATTR_PARSE_PROCEED;
1963 }
1964
1965 /* Originator ID attribute. */
1966 static bgp_attr_parse_ret_t
1967 bgp_attr_originator_id(struct bgp_attr_parser_args *args)
1968 {
1969 struct peer *const peer = args->peer;
1970 struct attr *const attr = args->attr;
1971 const bgp_size_t length = args->length;
1972
1973 /* if received from an internal neighbor, it SHALL be considered
1974 * malformed if its length is not equal to 4. If malformed, the
1975 * UPDATE message SHALL be handled using the approach of "treat-as-
1976 * withdraw".
1977 */
1978 if (length != 4) {
1979 flog_err(EC_BGP_ATTR_LEN, "Bad originator ID length %d",
1980 length);
1981
1982 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1983 args->total);
1984 }
1985
1986 attr->originator_id.s_addr = stream_get_ipv4(peer->curr);
1987
1988 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID);
1989
1990 return BGP_ATTR_PARSE_PROCEED;
1991 }
1992
1993 /* Cluster list attribute. */
1994 static bgp_attr_parse_ret_t
1995 bgp_attr_cluster_list(struct bgp_attr_parser_args *args)
1996 {
1997 struct peer *const peer = args->peer;
1998 struct attr *const attr = args->attr;
1999 const bgp_size_t length = args->length;
2000
2001 /* if received from an internal neighbor, it SHALL be considered
2002 * malformed if its length is not a non-zero multiple of 4. If
2003 * malformed, the UPDATE message SHALL be handled using the approach
2004 * of "treat-as-withdraw".
2005 */
2006 if (length == 0 || length % 4) {
2007 flog_err(EC_BGP_ATTR_LEN, "Bad cluster list length %d", length);
2008
2009 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2010 args->total);
2011 }
2012
2013 bgp_attr_set_cluster(
2014 attr, cluster_parse((struct in_addr *)stream_pnt(peer->curr),
2015 length));
2016
2017 /* XXX: Fix cluster_parse to use stream API and then remove this */
2018 stream_forward_getp(peer->curr, length);
2019
2020 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST);
2021
2022 return BGP_ATTR_PARSE_PROCEED;
2023 }
2024
2025 /* Multiprotocol reachability information parse. */
2026 int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
2027 struct bgp_nlri *mp_update)
2028 {
2029 iana_afi_t pkt_afi;
2030 afi_t afi;
2031 iana_safi_t pkt_safi;
2032 safi_t safi;
2033 bgp_size_t nlri_len;
2034 size_t start;
2035 struct stream *s;
2036 struct peer *const peer = args->peer;
2037 struct attr *const attr = args->attr;
2038 const bgp_size_t length = args->length;
2039
2040 /* Set end of packet. */
2041 s = BGP_INPUT(peer);
2042 start = stream_get_getp(s);
2043
2044 /* safe to read statically sized header? */
2045 #define BGP_MP_REACH_MIN_SIZE 5
2046 #define LEN_LEFT (length - (stream_get_getp(s) - start))
2047 if ((length > STREAM_READABLE(s)) || (length < BGP_MP_REACH_MIN_SIZE)) {
2048 zlog_info("%s: %s sent invalid length, %lu, of MP_REACH_NLRI",
2049 __func__, peer->host, (unsigned long)length);
2050 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2051 }
2052
2053 /* Load AFI, SAFI. */
2054 pkt_afi = stream_getw(s);
2055 pkt_safi = stream_getc(s);
2056
2057 /* Convert AFI, SAFI to internal values, check. */
2058 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
2059 /* Log if AFI or SAFI is unrecognized. This is not an error
2060 * unless
2061 * the attribute is otherwise malformed.
2062 */
2063 if (bgp_debug_update(peer, NULL, NULL, 0))
2064 zlog_debug(
2065 "%s sent unrecognizable AFI, %s or, SAFI, %s, of MP_REACH_NLRI",
2066 peer->host, iana_afi2str(pkt_afi),
2067 iana_safi2str(pkt_safi));
2068 return BGP_ATTR_PARSE_ERROR;
2069 }
2070
2071 /* Get nexthop length. */
2072 attr->mp_nexthop_len = stream_getc(s);
2073
2074 if (LEN_LEFT < attr->mp_nexthop_len) {
2075 zlog_info(
2076 "%s: %s sent next-hop length, %u, in MP_REACH_NLRI which goes past the end of attribute",
2077 __func__, peer->host, attr->mp_nexthop_len);
2078 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2079 }
2080
2081 /* Nexthop length check. */
2082 switch (attr->mp_nexthop_len) {
2083 case 0:
2084 if (safi != SAFI_FLOWSPEC) {
2085 zlog_info("%s: %s sent wrong next-hop length, %d, in MP_REACH_NLRI",
2086 __func__, peer->host, attr->mp_nexthop_len);
2087 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2088 }
2089 break;
2090 case BGP_ATTR_NHLEN_VPNV4:
2091 stream_getl(s); /* RD high */
2092 stream_getl(s); /* RD low */
2093 /*
2094 * NOTE: intentional fall through
2095 * - for consistency in rx processing
2096 *
2097 * The following comment is to signal GCC this intention
2098 * and suppress the warning
2099 */
2100 /* FALLTHRU */
2101 case BGP_ATTR_NHLEN_IPV4:
2102 stream_get(&attr->mp_nexthop_global_in, s, IPV4_MAX_BYTELEN);
2103 /* Probably needed for RFC 2283 */
2104 if (attr->nexthop.s_addr == INADDR_ANY)
2105 memcpy(&attr->nexthop.s_addr,
2106 &attr->mp_nexthop_global_in, IPV4_MAX_BYTELEN);
2107 break;
2108 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
2109 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
2110 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_VPNV6_GLOBAL) {
2111 stream_getl(s); /* RD high */
2112 stream_getl(s); /* RD low */
2113 }
2114 stream_get(&attr->mp_nexthop_global, s, IPV6_MAX_BYTELEN);
2115 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2116 if (!peer->nexthop.ifp) {
2117 zlog_warn("%s sent a v6 global attribute but address is a V6 LL and there's no peer interface information. Hence, withdrawing",
2118 peer->host);
2119 return BGP_ATTR_PARSE_WITHDRAW;
2120 }
2121 attr->nh_ifindex = peer->nexthop.ifp->ifindex;
2122 }
2123 break;
2124 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
2125 case BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL:
2126 if (attr->mp_nexthop_len
2127 == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) {
2128 stream_getl(s); /* RD high */
2129 stream_getl(s); /* RD low */
2130 }
2131 stream_get(&attr->mp_nexthop_global, s, IPV6_MAX_BYTELEN);
2132 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2133 if (!peer->nexthop.ifp) {
2134 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",
2135 peer->host);
2136 return BGP_ATTR_PARSE_WITHDRAW;
2137 }
2138 attr->nh_ifindex = peer->nexthop.ifp->ifindex;
2139 }
2140 if (attr->mp_nexthop_len
2141 == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) {
2142 stream_getl(s); /* RD high */
2143 stream_getl(s); /* RD low */
2144 }
2145 stream_get(&attr->mp_nexthop_local, s, IPV6_MAX_BYTELEN);
2146 if (!IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local)) {
2147 if (bgp_debug_update(peer, NULL, NULL, 1))
2148 zlog_debug(
2149 "%s sent next-hops %pI6 and %pI6. Ignoring non-LL value",
2150 peer->host, &attr->mp_nexthop_global,
2151 &attr->mp_nexthop_local);
2152
2153 attr->mp_nexthop_len = IPV6_MAX_BYTELEN;
2154 }
2155 if (!peer->nexthop.ifp) {
2156 zlog_warn("%s sent a v6 LL next-hop and there's no peer interface information. Hence, withdrawing",
2157 peer->host);
2158 return BGP_ATTR_PARSE_WITHDRAW;
2159 }
2160 attr->nh_lla_ifindex = peer->nexthop.ifp->ifindex;
2161 break;
2162 default:
2163 zlog_info("%s: %s sent wrong next-hop length, %d, in MP_REACH_NLRI",
2164 __func__, peer->host, attr->mp_nexthop_len);
2165 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2166 }
2167
2168 if (!LEN_LEFT) {
2169 zlog_info("%s: %s sent SNPA which couldn't be read",
2170 __func__, peer->host);
2171 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2172 }
2173
2174 {
2175 uint8_t val;
2176 if ((val = stream_getc(s)))
2177 flog_warn(
2178 EC_BGP_DEFUNCT_SNPA_LEN,
2179 "%s sent non-zero value, %u, for defunct SNPA-length field",
2180 peer->host, val);
2181 }
2182
2183 /* must have nrli_len, what is left of the attribute */
2184 nlri_len = LEN_LEFT;
2185 if (nlri_len > STREAM_READABLE(s)) {
2186 zlog_info("%s: %s sent MP_REACH_NLRI which couldn't be read",
2187 __func__, peer->host);
2188 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2189 }
2190
2191 if (!nlri_len) {
2192 zlog_info("%s: %s sent a zero-length NLRI. Hence, treating as a EOR marker",
2193 __func__, peer->host);
2194
2195 mp_update->afi = afi;
2196 mp_update->safi = safi;
2197 return BGP_ATTR_PARSE_EOR;
2198 }
2199
2200 mp_update->afi = afi;
2201 mp_update->safi = safi;
2202 mp_update->nlri = stream_pnt(s);
2203 mp_update->length = nlri_len;
2204
2205 stream_forward_getp(s, nlri_len);
2206
2207 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI);
2208
2209 return BGP_ATTR_PARSE_PROCEED;
2210 #undef LEN_LEFT
2211 }
2212
2213 /* Multiprotocol unreachable parse */
2214 int bgp_mp_unreach_parse(struct bgp_attr_parser_args *args,
2215 struct bgp_nlri *mp_withdraw)
2216 {
2217 struct stream *s;
2218 iana_afi_t pkt_afi;
2219 afi_t afi;
2220 iana_safi_t pkt_safi;
2221 safi_t safi;
2222 uint16_t withdraw_len;
2223 struct peer *const peer = args->peer;
2224 struct attr *const attr = args->attr;
2225 const bgp_size_t length = args->length;
2226
2227 s = peer->curr;
2228
2229 #define BGP_MP_UNREACH_MIN_SIZE 3
2230 if ((length > STREAM_READABLE(s)) || (length < BGP_MP_UNREACH_MIN_SIZE))
2231 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2232
2233 pkt_afi = stream_getw(s);
2234 pkt_safi = stream_getc(s);
2235
2236 /* Convert AFI, SAFI to internal values, check. */
2237 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
2238 /* Log if AFI or SAFI is unrecognized. This is not an error
2239 * unless
2240 * the attribute is otherwise malformed.
2241 */
2242 if (bgp_debug_update(peer, NULL, NULL, 0))
2243 zlog_debug(
2244 "%s: MP_UNREACH received AFI %s or SAFI %s is unrecognized",
2245 peer->host, iana_afi2str(pkt_afi),
2246 iana_safi2str(pkt_safi));
2247 return BGP_ATTR_PARSE_ERROR;
2248 }
2249
2250 withdraw_len = length - BGP_MP_UNREACH_MIN_SIZE;
2251
2252 mp_withdraw->afi = afi;
2253 mp_withdraw->safi = safi;
2254 mp_withdraw->nlri = stream_pnt(s);
2255 mp_withdraw->length = withdraw_len;
2256
2257 stream_forward_getp(s, withdraw_len);
2258
2259 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI);
2260
2261 return BGP_ATTR_PARSE_PROCEED;
2262 }
2263
2264 /* Large Community attribute. */
2265 static bgp_attr_parse_ret_t
2266 bgp_attr_large_community(struct bgp_attr_parser_args *args)
2267 {
2268 struct peer *const peer = args->peer;
2269 struct attr *const attr = args->attr;
2270 const bgp_size_t length = args->length;
2271
2272 /*
2273 * Large community follows new attribute format.
2274 */
2275 if (length == 0) {
2276 attr->lcommunity = NULL;
2277 /* Empty extcomm doesn't seem to be invalid per se */
2278 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2279 args->total);
2280 }
2281
2282 attr->lcommunity = lcommunity_parse(stream_pnt(peer->curr), length);
2283 /* XXX: fix ecommunity_parse to use stream API */
2284 stream_forward_getp(peer->curr, length);
2285
2286 if (!attr->lcommunity)
2287 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2288 args->total);
2289
2290 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES);
2291
2292 return BGP_ATTR_PARSE_PROCEED;
2293 }
2294
2295 /* Extended Community attribute. */
2296 static bgp_attr_parse_ret_t
2297 bgp_attr_ext_communities(struct bgp_attr_parser_args *args)
2298 {
2299 struct peer *const peer = args->peer;
2300 struct attr *const attr = args->attr;
2301 const bgp_size_t length = args->length;
2302 uint8_t sticky = 0;
2303 bool proxy = false;
2304
2305 if (length == 0) {
2306 attr->ecommunity = NULL;
2307 /* Empty extcomm doesn't seem to be invalid per se */
2308 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2309 args->total);
2310 }
2311
2312 attr->ecommunity =
2313 ecommunity_parse(stream_pnt(peer->curr), length);
2314 /* XXX: fix ecommunity_parse to use stream API */
2315 stream_forward_getp(peer->curr, length);
2316
2317 /* The Extended Community attribute SHALL be considered malformed if
2318 * its length is not a non-zero multiple of 8.
2319 */
2320 if (!attr->ecommunity)
2321 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2322 args->total);
2323
2324 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
2325
2326 /* Extract DF election preference and mobility sequence number */
2327 attr->df_pref = bgp_attr_df_pref_from_ec(attr, &attr->df_alg);
2328
2329 /* Extract MAC mobility sequence number, if any. */
2330 attr->mm_seqnum = bgp_attr_mac_mobility_seqnum(attr, &sticky);
2331 attr->sticky = sticky;
2332
2333 /* Check if this is a Gateway MAC-IP advertisement */
2334 attr->default_gw = bgp_attr_default_gw(attr);
2335
2336 /* Handle scenario where router flag ecommunity is not
2337 * set but default gw ext community is present.
2338 * Use default gateway, set and propogate R-bit.
2339 */
2340 if (attr->default_gw)
2341 attr->router_flag = 1;
2342
2343 /* Check EVPN Neighbor advertisement flags, R-bit */
2344 bgp_attr_evpn_na_flag(attr, &attr->router_flag, &proxy);
2345 if (proxy)
2346 attr->es_flags |= ATTR_ES_PROXY_ADVERT;
2347
2348 /* Extract the Rmac, if any */
2349 if (bgp_attr_rmac(attr, &attr->rmac)) {
2350 if (bgp_debug_update(peer, NULL, NULL, 1)
2351 && bgp_mac_exist(&attr->rmac))
2352 zlog_debug("%s: router mac %pEA is self mac", __func__,
2353 &attr->rmac);
2354 }
2355
2356 /* Get the tunnel type from encap extended community */
2357 bgp_attr_extcom_tunnel_type(attr,
2358 (bgp_encap_types *)&attr->encap_tunneltype);
2359
2360 /* Extract link bandwidth, if any. */
2361 (void)ecommunity_linkbw_present(attr->ecommunity, &attr->link_bw);
2362
2363 return BGP_ATTR_PARSE_PROCEED;
2364 }
2365
2366 /* IPv6 Extended Community attribute. */
2367 static bgp_attr_parse_ret_t
2368 bgp_attr_ipv6_ext_communities(struct bgp_attr_parser_args *args)
2369 {
2370 struct peer *const peer = args->peer;
2371 struct attr *const attr = args->attr;
2372 const bgp_size_t length = args->length;
2373 struct ecommunity *ipv6_ecomm = NULL;
2374
2375 if (length == 0) {
2376 bgp_attr_set_ipv6_ecommunity(attr, ipv6_ecomm);
2377 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2378 args->total);
2379 }
2380
2381 ipv6_ecomm = ecommunity_parse_ipv6(stream_pnt(peer->curr), length);
2382 bgp_attr_set_ipv6_ecommunity(attr, ipv6_ecomm);
2383
2384 /* XXX: fix ecommunity_parse to use stream API */
2385 stream_forward_getp(peer->curr, length);
2386
2387 if (!ipv6_ecomm)
2388 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2389 args->total);
2390
2391 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_IPV6_EXT_COMMUNITIES);
2392
2393 return BGP_ATTR_PARSE_PROCEED;
2394 }
2395
2396 /* Parse Tunnel Encap attribute in an UPDATE */
2397 static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */
2398 bgp_size_t length, /* IN: attr's length field */
2399 struct attr *attr, /* IN: caller already allocated */
2400 uint8_t flag, /* IN: attr's flags field */
2401 uint8_t *startp)
2402 {
2403 bgp_size_t total;
2404 uint16_t tunneltype = 0;
2405
2406 total = length + (CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
2407
2408 if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS)
2409 || !CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL)) {
2410 zlog_info(
2411 "Tunnel Encap attribute flag isn't optional and transitive %d",
2412 flag);
2413 bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR,
2414 BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
2415 startp, total);
2416 return -1;
2417 }
2418
2419 if (BGP_ATTR_ENCAP == type) {
2420 /* read outer TLV type and length */
2421 uint16_t tlv_length;
2422
2423 if (length < 4) {
2424 zlog_info(
2425 "Tunnel Encap attribute not long enough to contain outer T,L");
2426 bgp_notify_send_with_data(
2427 peer, BGP_NOTIFY_UPDATE_ERR,
2428 BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, startp, total);
2429 return -1;
2430 }
2431 tunneltype = stream_getw(BGP_INPUT(peer));
2432 tlv_length = stream_getw(BGP_INPUT(peer));
2433 length -= 4;
2434
2435 if (tlv_length != length) {
2436 zlog_info("%s: tlv_length(%d) != length(%d)",
2437 __func__, tlv_length, length);
2438 }
2439 }
2440
2441 while (length >= 4) {
2442 uint16_t subtype = 0;
2443 uint16_t sublength = 0;
2444 struct bgp_attr_encap_subtlv *tlv;
2445
2446 if (BGP_ATTR_ENCAP == type) {
2447 subtype = stream_getc(BGP_INPUT(peer));
2448 sublength = stream_getc(BGP_INPUT(peer));
2449 length -= 2;
2450 #ifdef ENABLE_BGP_VNC
2451 } else {
2452 subtype = stream_getw(BGP_INPUT(peer));
2453 sublength = stream_getw(BGP_INPUT(peer));
2454 length -= 4;
2455 #endif
2456 }
2457
2458 if (sublength > length) {
2459 zlog_info(
2460 "Tunnel Encap attribute sub-tlv length %d exceeds remaining length %d",
2461 sublength, length);
2462 bgp_notify_send_with_data(
2463 peer, BGP_NOTIFY_UPDATE_ERR,
2464 BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, startp, total);
2465 return -1;
2466 }
2467
2468 /* alloc and copy sub-tlv */
2469 /* TBD make sure these are freed when attributes are released */
2470 tlv = XCALLOC(MTYPE_ENCAP_TLV,
2471 sizeof(struct bgp_attr_encap_subtlv) + sublength);
2472 tlv->type = subtype;
2473 tlv->length = sublength;
2474 stream_get(tlv->value, peer->curr, sublength);
2475 length -= sublength;
2476
2477 /* attach tlv to encap chain */
2478 if (BGP_ATTR_ENCAP == type) {
2479 struct bgp_attr_encap_subtlv *stlv_last;
2480 for (stlv_last = attr->encap_subtlvs;
2481 stlv_last && stlv_last->next;
2482 stlv_last = stlv_last->next)
2483 ;
2484 if (stlv_last) {
2485 stlv_last->next = tlv;
2486 } else {
2487 attr->encap_subtlvs = tlv;
2488 }
2489 #ifdef ENABLE_BGP_VNC
2490 } else {
2491 struct bgp_attr_encap_subtlv *stlv_last;
2492 struct bgp_attr_encap_subtlv *vnc_subtlvs =
2493 bgp_attr_get_vnc_subtlvs(attr);
2494
2495 for (stlv_last = vnc_subtlvs;
2496 stlv_last && stlv_last->next;
2497 stlv_last = stlv_last->next)
2498 ;
2499 if (stlv_last)
2500 stlv_last->next = tlv;
2501 else
2502 bgp_attr_set_vnc_subtlvs(attr, tlv);
2503 #endif
2504 }
2505 }
2506
2507 if (BGP_ATTR_ENCAP == type) {
2508 attr->encap_tunneltype = tunneltype;
2509 }
2510
2511 if (length) {
2512 /* spurious leftover data */
2513 zlog_info(
2514 "Tunnel Encap attribute length is bad: %d leftover octets",
2515 length);
2516 bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR,
2517 BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2518 startp, total);
2519 return -1;
2520 }
2521
2522 return 0;
2523 }
2524
2525 /*
2526 * Read an individual SID value returning how much data we have read
2527 * Returns 0 if there was an error that needs to be passed up the stack
2528 */
2529 static bgp_attr_parse_ret_t bgp_attr_psid_sub(uint8_t type, uint16_t length,
2530 struct bgp_attr_parser_args *args)
2531 {
2532 struct peer *const peer = args->peer;
2533 struct attr *const attr = args->attr;
2534 uint32_t label_index;
2535 struct in6_addr ipv6_sid;
2536 uint32_t srgb_base;
2537 uint32_t srgb_range;
2538 int srgb_count;
2539 uint8_t sid_type, sid_flags;
2540 uint16_t endpoint_behavior;
2541 char buf[BUFSIZ];
2542
2543 if (type == BGP_PREFIX_SID_LABEL_INDEX) {
2544 if (STREAM_READABLE(peer->curr) < length
2545 || length != BGP_PREFIX_SID_LABEL_INDEX_LENGTH) {
2546 flog_err(EC_BGP_ATTR_LEN,
2547 "Prefix SID label index length is %hu instead of %u",
2548 length, BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
2549 return bgp_attr_malformed(args,
2550 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2551 args->total);
2552 }
2553
2554 /* Ignore flags and reserved */
2555 stream_getc(peer->curr);
2556 stream_getw(peer->curr);
2557
2558 /* Fetch the label index and see if it is valid. */
2559 label_index = stream_getl(peer->curr);
2560 if (label_index == BGP_INVALID_LABEL_INDEX)
2561 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2562 args->total);
2563
2564 /* Store label index; subsequently, we'll check on
2565 * address-family */
2566 attr->label_index = label_index;
2567 }
2568
2569 /* Placeholder code for the IPv6 SID type */
2570 else if (type == BGP_PREFIX_SID_IPV6) {
2571 if (STREAM_READABLE(peer->curr) < length
2572 || length != BGP_PREFIX_SID_IPV6_LENGTH) {
2573 flog_err(EC_BGP_ATTR_LEN,
2574 "Prefix SID IPv6 length is %hu instead of %u",
2575 length, BGP_PREFIX_SID_IPV6_LENGTH);
2576 return bgp_attr_malformed(args,
2577 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2578 args->total);
2579 }
2580
2581 /* Ignore reserved */
2582 stream_getc(peer->curr);
2583 stream_getw(peer->curr);
2584
2585 stream_get(&ipv6_sid, peer->curr, 16);
2586 }
2587
2588 /* Placeholder code for the Originator SRGB type */
2589 else if (type == BGP_PREFIX_SID_ORIGINATOR_SRGB) {
2590 /*
2591 * ietf-idr-bgp-prefix-sid-05:
2592 * Length is the total length of the value portion of the
2593 * TLV: 2 + multiple of 6.
2594 *
2595 * peer->curr stream readp should be at the beginning of the 16
2596 * bit flag field at this point in the code.
2597 */
2598
2599 /*
2600 * Check that the TLV length field is sane: at least 2 bytes of
2601 * flag, and at least 1 SRGB (these are 6 bytes each)
2602 */
2603 if (length < (2 + BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH)) {
2604 flog_err(
2605 EC_BGP_ATTR_LEN,
2606 "Prefix SID Originator SRGB length field claims length of %hu bytes, but the minimum for this TLV type is %u",
2607 length,
2608 2 + BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH);
2609 return bgp_attr_malformed(
2610 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2611 args->total);
2612 }
2613
2614 /*
2615 * Check that we actually have at least as much data as
2616 * specified by the length field
2617 */
2618 if (STREAM_READABLE(peer->curr) < length) {
2619 flog_err(EC_BGP_ATTR_LEN,
2620 "Prefix SID Originator SRGB specifies length %hu, but only %zu bytes remain",
2621 length, STREAM_READABLE(peer->curr));
2622 return bgp_attr_malformed(
2623 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2624 args->total);
2625 }
2626
2627 /*
2628 * Check that the portion of the TLV containing the sequence of
2629 * SRGBs corresponds to a multiple of the SRGB size; to get
2630 * that length, we skip the 16 bit flags field
2631 */
2632 stream_getw(peer->curr);
2633 length -= 2;
2634 if (length % BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH) {
2635 flog_err(
2636 EC_BGP_ATTR_LEN,
2637 "Prefix SID Originator SRGB length field claims attribute SRGB sequence section is %hubytes, but it must be a multiple of %u",
2638 length, BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH);
2639 return bgp_attr_malformed(
2640 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2641 args->total);
2642 }
2643
2644 srgb_count = length / BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH;
2645
2646 for (int i = 0; i < srgb_count; i++) {
2647 stream_get(&srgb_base, peer->curr, 3);
2648 stream_get(&srgb_range, peer->curr, 3);
2649 }
2650 }
2651
2652 /* Placeholder code for the VPN-SID Service type */
2653 else if (type == BGP_PREFIX_SID_VPN_SID) {
2654 if (STREAM_READABLE(peer->curr) < length
2655 || length != BGP_PREFIX_SID_VPN_SID_LENGTH) {
2656 flog_err(EC_BGP_ATTR_LEN,
2657 "Prefix SID VPN SID length is %hu instead of %u",
2658 length, BGP_PREFIX_SID_VPN_SID_LENGTH);
2659 return bgp_attr_malformed(args,
2660 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2661 args->total);
2662 }
2663
2664 /* Parse VPN-SID Sub-TLV */
2665 stream_getc(peer->curr); /* reserved */
2666 sid_type = stream_getc(peer->curr); /* sid_type */
2667 sid_flags = stream_getc(peer->curr); /* sid_flags */
2668 stream_get(&ipv6_sid, peer->curr,
2669 sizeof(ipv6_sid)); /* sid_value */
2670
2671 /* Log VPN-SID Sub-TLV */
2672 if (BGP_DEBUG(vpn, VPN_LEAK_LABEL)) {
2673 inet_ntop(AF_INET6, &ipv6_sid, buf, sizeof(buf));
2674 zlog_debug(
2675 "%s: vpn-sid: sid %s, sid-type 0x%02x sid-flags 0x%02x",
2676 __func__, buf, sid_type, sid_flags);
2677 }
2678
2679 /* Configure from Info */
2680 if (attr->srv6_vpn) {
2681 flog_err(EC_BGP_ATTRIBUTE_REPEATED,
2682 "Prefix SID SRv6 VPN field repeated");
2683 return bgp_attr_malformed(
2684 args, BGP_NOTIFY_UPDATE_MAL_ATTR, args->total);
2685 }
2686 attr->srv6_vpn = XCALLOC(MTYPE_BGP_SRV6_VPN,
2687 sizeof(struct bgp_attr_srv6_vpn));
2688 attr->srv6_vpn->sid_flags = sid_flags;
2689 sid_copy(&attr->srv6_vpn->sid, &ipv6_sid);
2690 attr->srv6_vpn = srv6_vpn_intern(attr->srv6_vpn);
2691 }
2692
2693 /* Placeholder code for the SRv6 L3 Service type */
2694 else if (type == BGP_PREFIX_SID_SRV6_L3_SERVICE) {
2695 if (STREAM_READABLE(peer->curr) < length
2696 || length != BGP_PREFIX_SID_SRV6_L3_SERVICE_LENGTH) {
2697 flog_err(EC_BGP_ATTR_LEN,
2698 "Prefix SID SRv6 L3-Service length is %hu instead of %u",
2699 length, BGP_PREFIX_SID_SRV6_L3_SERVICE_LENGTH);
2700 return bgp_attr_malformed(args,
2701 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2702 args->total);
2703 }
2704
2705 /* Parse L3-SERVICE Sub-TLV */
2706 stream_getc(peer->curr); /* reserved */
2707 stream_get(&ipv6_sid, peer->curr,
2708 sizeof(ipv6_sid)); /* sid_value */
2709 sid_flags = stream_getc(peer->curr); /* sid_flags */
2710 endpoint_behavior = stream_getw(peer->curr); /* endpoint */
2711 stream_getc(peer->curr); /* reserved */
2712
2713 /* Log L3-SERVICE Sub-TLV */
2714 if (BGP_DEBUG(vpn, VPN_LEAK_LABEL)) {
2715 inet_ntop(AF_INET6, &ipv6_sid, buf, sizeof(buf));
2716 zlog_debug(
2717 "%s: srv6-l3-srv sid %s, sid-flags 0x%02x, end-behaviour 0x%04x",
2718 __func__, buf, sid_flags, endpoint_behavior);
2719 }
2720
2721 /* Configure from Info */
2722 if (attr->srv6_l3vpn) {
2723 flog_err(EC_BGP_ATTRIBUTE_REPEATED,
2724 "Prefix SID SRv6 L3VPN field repeated");
2725 return bgp_attr_malformed(
2726 args, BGP_NOTIFY_UPDATE_MAL_ATTR, args->total);
2727 }
2728 attr->srv6_l3vpn = XCALLOC(MTYPE_BGP_SRV6_L3VPN,
2729 sizeof(struct bgp_attr_srv6_l3vpn));
2730 attr->srv6_l3vpn->sid_flags = sid_flags;
2731 attr->srv6_l3vpn->endpoint_behavior = endpoint_behavior;
2732 sid_copy(&attr->srv6_l3vpn->sid, &ipv6_sid);
2733 attr->srv6_l3vpn = srv6_l3vpn_intern(attr->srv6_l3vpn);
2734 }
2735
2736 /* Placeholder code for Unsupported TLV */
2737 else {
2738
2739 if (STREAM_READABLE(peer->curr) < length) {
2740 flog_err(
2741 EC_BGP_ATTR_LEN,
2742 "Prefix SID SRv6 length is %hu - too long, only %zu remaining in this UPDATE",
2743 length, STREAM_READABLE(peer->curr));
2744 return bgp_attr_malformed(
2745 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2746 args->total);
2747 }
2748
2749 if (bgp_debug_update(peer, NULL, NULL, 1))
2750 zlog_debug(
2751 "%s attr Prefix-SID sub-type=%u is not supported, skipped",
2752 peer->host, type);
2753
2754 stream_forward_getp(peer->curr, length);
2755 }
2756
2757 return BGP_ATTR_PARSE_PROCEED;
2758 }
2759
2760 /* Prefix SID attribute
2761 * draft-ietf-idr-bgp-prefix-sid-05
2762 */
2763 bgp_attr_parse_ret_t bgp_attr_prefix_sid(struct bgp_attr_parser_args *args)
2764 {
2765 struct peer *const peer = args->peer;
2766 struct attr *const attr = args->attr;
2767 bgp_attr_parse_ret_t ret;
2768
2769 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
2770
2771 uint8_t type;
2772 uint16_t length;
2773 size_t headersz = sizeof(type) + sizeof(length);
2774 size_t psid_parsed_length = 0;
2775
2776 while (STREAM_READABLE(peer->curr) > 0
2777 && psid_parsed_length < args->length) {
2778
2779 if (STREAM_READABLE(peer->curr) < headersz) {
2780 flog_err(
2781 EC_BGP_ATTR_LEN,
2782 "Malformed Prefix SID attribute - insufficent data (need %zu for attribute header, have %zu remaining in UPDATE)",
2783 headersz, STREAM_READABLE(peer->curr));
2784 return bgp_attr_malformed(
2785 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2786 args->total);
2787 }
2788
2789 type = stream_getc(peer->curr);
2790 length = stream_getw(peer->curr);
2791
2792 if (STREAM_READABLE(peer->curr) < length) {
2793 flog_err(
2794 EC_BGP_ATTR_LEN,
2795 "Malformed Prefix SID attribute - insufficient data (need %hu for attribute body, have %zu remaining in UPDATE)",
2796 length, STREAM_READABLE(peer->curr));
2797 return bgp_attr_malformed(args,
2798 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2799 args->total);
2800 }
2801
2802 ret = bgp_attr_psid_sub(type, length, args);
2803
2804 if (ret != BGP_ATTR_PARSE_PROCEED)
2805 return ret;
2806
2807 psid_parsed_length += length + headersz;
2808
2809 if (psid_parsed_length > args->length) {
2810 flog_err(
2811 EC_BGP_ATTR_LEN,
2812 "Malformed Prefix SID attribute - TLV overflow by attribute (need %zu for TLV length, have %zu overflowed in UPDATE)",
2813 length + headersz, psid_parsed_length - (length + headersz));
2814 return bgp_attr_malformed(
2815 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2816 args->total);
2817 }
2818 }
2819
2820 return BGP_ATTR_PARSE_PROCEED;
2821 }
2822
2823 /* PMSI tunnel attribute (RFC 6514)
2824 * Basic validation checks done here.
2825 */
2826 static bgp_attr_parse_ret_t
2827 bgp_attr_pmsi_tunnel(struct bgp_attr_parser_args *args)
2828 {
2829 struct peer *const peer = args->peer;
2830 struct attr *const attr = args->attr;
2831 const bgp_size_t length = args->length;
2832 uint8_t tnl_type;
2833 int attr_parse_len = 2 + BGP_LABEL_BYTES;
2834
2835 /* Verify that the receiver is expecting "ingress replication" as we
2836 * can only support that.
2837 */
2838 if (length < attr_parse_len) {
2839 flog_err(EC_BGP_ATTR_LEN, "Bad PMSI tunnel attribute length %d",
2840 length);
2841 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2842 args->total);
2843 }
2844 stream_getc(peer->curr); /* Flags */
2845 tnl_type = stream_getc(peer->curr);
2846 if (tnl_type > PMSI_TNLTYPE_MAX) {
2847 flog_err(EC_BGP_ATTR_PMSI_TYPE,
2848 "Invalid PMSI tunnel attribute type %d", tnl_type);
2849 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2850 args->total);
2851 }
2852 if (tnl_type == PMSI_TNLTYPE_INGR_REPL) {
2853 if (length != 9) {
2854 flog_err(EC_BGP_ATTR_PMSI_LEN,
2855 "Bad PMSI tunnel attribute length %d for IR",
2856 length);
2857 return bgp_attr_malformed(
2858 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2859 args->total);
2860 }
2861 }
2862
2863 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL);
2864 bgp_attr_set_pmsi_tnl_type(attr, tnl_type);
2865 stream_get(&attr->label, peer->curr, BGP_LABEL_BYTES);
2866
2867 /* Forward read pointer of input stream. */
2868 stream_forward_getp(peer->curr, length - attr_parse_len);
2869
2870 return BGP_ATTR_PARSE_PROCEED;
2871 }
2872
2873 /* BGP unknown attribute treatment. */
2874 static bgp_attr_parse_ret_t bgp_attr_unknown(struct bgp_attr_parser_args *args)
2875 {
2876 bgp_size_t total = args->total;
2877 struct transit *transit;
2878 struct peer *const peer = args->peer;
2879 struct attr *const attr = args->attr;
2880 uint8_t *const startp = args->startp;
2881 const uint8_t type = args->type;
2882 const uint8_t flag = args->flags;
2883 const bgp_size_t length = args->length;
2884
2885 if (bgp_debug_update(peer, NULL, NULL, 1))
2886 zlog_debug(
2887 "%s Unknown attribute is received (type %d, length %d)",
2888 peer->host, type, length);
2889
2890 /* Forward read pointer of input stream. */
2891 stream_forward_getp(peer->curr, length);
2892
2893 /* If any of the mandatory well-known attributes are not recognized,
2894 then the Error Subcode is set to Unrecognized Well-known
2895 Attribute. The Data field contains the unrecognized attribute
2896 (type, length and value). */
2897 if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL)) {
2898 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_UNREC_ATTR,
2899 args->total);
2900 }
2901
2902 /* Unrecognized non-transitive optional attributes must be quietly
2903 ignored and not passed along to other BGP peers. */
2904 if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS))
2905 return BGP_ATTR_PARSE_PROCEED;
2906
2907 /* If a path with recognized transitive optional attribute is
2908 accepted and passed along to other BGP peers and the Partial bit
2909 in the Attribute Flags octet is set to 1 by some previous AS, it
2910 is not set back to 0 by the current AS. */
2911 SET_FLAG(*startp, BGP_ATTR_FLAG_PARTIAL);
2912
2913 /* Store transitive attribute to the end of attr->transit. */
2914 transit = bgp_attr_get_transit(attr);
2915 if (!transit)
2916 transit = XCALLOC(MTYPE_TRANSIT, sizeof(struct transit));
2917
2918 if (transit->val)
2919 transit->val = XREALLOC(MTYPE_TRANSIT_VAL, transit->val,
2920 transit->length + total);
2921 else
2922 transit->val = XMALLOC(MTYPE_TRANSIT_VAL, total);
2923
2924 memcpy(transit->val + transit->length, startp, total);
2925 transit->length += total;
2926 bgp_attr_set_transit(attr, transit);
2927
2928 return BGP_ATTR_PARSE_PROCEED;
2929 }
2930
2931 /* Well-known attribute check. */
2932 static int bgp_attr_check(struct peer *peer, struct attr *attr)
2933 {
2934 uint8_t type = 0;
2935
2936 /* BGP Graceful-Restart End-of-RIB for IPv4 unicast is signaled as an
2937 * empty UPDATE. */
2938 if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV) && !attr->flag)
2939 return BGP_ATTR_PARSE_PROCEED;
2940
2941 /* "An UPDATE message that contains the MP_UNREACH_NLRI is not required
2942 to carry any other path attributes.", though if MP_REACH_NLRI or NLRI
2943 are present, it should. Check for any other attribute being present
2944 instead.
2945 */
2946 if ((!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI)) &&
2947 CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI))))
2948 return BGP_ATTR_PARSE_PROCEED;
2949
2950 if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGIN)))
2951 type = BGP_ATTR_ORIGIN;
2952
2953 if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AS_PATH)))
2954 type = BGP_ATTR_AS_PATH;
2955
2956 /* RFC 2858 makes Next-Hop optional/ignored, if MP_REACH_NLRI is present
2957 * and
2958 * NLRI is empty. We can't easily check NLRI empty here though.
2959 */
2960 if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP))
2961 && !CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI)))
2962 type = BGP_ATTR_NEXT_HOP;
2963
2964 if (peer->sort == BGP_PEER_IBGP
2965 && !CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))
2966 type = BGP_ATTR_LOCAL_PREF;
2967
2968 /* If any of the well-known mandatory attributes are not present
2969 * in an UPDATE message, then "treat-as-withdraw" MUST be used.
2970 */
2971 if (type) {
2972 flog_warn(EC_BGP_MISSING_ATTRIBUTE,
2973 "%s Missing well-known attribute %s.", peer->host,
2974 lookup_msg(attr_str, type, NULL));
2975 return BGP_ATTR_PARSE_WITHDRAW;
2976 }
2977 return BGP_ATTR_PARSE_PROCEED;
2978 }
2979
2980 /* Read attribute of update packet. This function is called from
2981 bgp_update_receive() in bgp_packet.c. */
2982 bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr,
2983 bgp_size_t size, struct bgp_nlri *mp_update,
2984 struct bgp_nlri *mp_withdraw)
2985 {
2986 bgp_attr_parse_ret_t ret;
2987 uint8_t flag = 0;
2988 uint8_t type = 0;
2989 bgp_size_t length;
2990 uint8_t *startp, *endp;
2991 uint8_t *attr_endp;
2992 uint8_t seen[BGP_ATTR_BITMAP_SIZE];
2993 /* we need the as4_path only until we have synthesized the as_path with
2994 * it */
2995 /* same goes for as4_aggregator */
2996 struct aspath *as4_path = NULL;
2997 as_t as4_aggregator = 0;
2998 struct in_addr as4_aggregator_addr = {.s_addr = 0};
2999 struct transit *transit;
3000
3001 /* Initialize bitmap. */
3002 memset(seen, 0, BGP_ATTR_BITMAP_SIZE);
3003
3004 /* End pointer of BGP attribute. */
3005 endp = BGP_INPUT_PNT(peer) + size;
3006
3007 /* Get attributes to the end of attribute length. */
3008 while (BGP_INPUT_PNT(peer) < endp) {
3009 /* Check remaining length check.*/
3010 if (endp - BGP_INPUT_PNT(peer) < BGP_ATTR_MIN_LEN) {
3011 /* XXX warning: long int format, int arg (arg 5) */
3012 flog_warn(
3013 EC_BGP_ATTRIBUTE_TOO_SMALL,
3014 "%s: error BGP attribute length %lu is smaller than min len",
3015 peer->host,
3016 (unsigned long)(endp
3017 - stream_pnt(BGP_INPUT(peer))));
3018
3019 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3020 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
3021 ret = BGP_ATTR_PARSE_ERROR;
3022 goto done;
3023 }
3024
3025 /* Fetch attribute flag and type. */
3026 startp = BGP_INPUT_PNT(peer);
3027 /* "The lower-order four bits of the Attribute Flags octet are
3028 unused. They MUST be zero when sent and MUST be ignored when
3029 received." */
3030 flag = 0xF0 & stream_getc(BGP_INPUT(peer));
3031 type = stream_getc(BGP_INPUT(peer));
3032
3033 /* Check whether Extended-Length applies and is in bounds */
3034 if (CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN)
3035 && ((endp - startp) < (BGP_ATTR_MIN_LEN + 1))) {
3036 flog_warn(
3037 EC_BGP_EXT_ATTRIBUTE_TOO_SMALL,
3038 "%s: Extended length set, but just %lu bytes of attr header",
3039 peer->host,
3040 (unsigned long)(endp
3041 - stream_pnt(BGP_INPUT(peer))));
3042
3043 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3044 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
3045 ret = BGP_ATTR_PARSE_ERROR;
3046 goto done;
3047 }
3048
3049 /* Check extended attribue length bit. */
3050 if (CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN))
3051 length = stream_getw(BGP_INPUT(peer));
3052 else
3053 length = stream_getc(BGP_INPUT(peer));
3054
3055 /* If any attribute appears more than once in the UPDATE
3056 message, then the Error Subcode is set to Malformed Attribute
3057 List. */
3058
3059 if (CHECK_BITMAP(seen, type)) {
3060 flog_warn(
3061 EC_BGP_ATTRIBUTE_REPEATED,
3062 "%s: error BGP attribute type %d appears twice in a message",
3063 peer->host, type);
3064
3065 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3066 BGP_NOTIFY_UPDATE_MAL_ATTR);
3067 ret = BGP_ATTR_PARSE_ERROR;
3068 goto done;
3069 }
3070
3071 /* Set type to bitmap to check duplicate attribute. `type' is
3072 unsigned char so it never overflow bitmap range. */
3073
3074 SET_BITMAP(seen, type);
3075
3076 /* Overflow check. */
3077 attr_endp = BGP_INPUT_PNT(peer) + length;
3078
3079 if (attr_endp > endp) {
3080 flog_warn(
3081 EC_BGP_ATTRIBUTE_TOO_LARGE,
3082 "%s: BGP type %d length %d is too large, attribute total length is %d. attr_endp is %p. endp is %p",
3083 peer->host, type, length, size, attr_endp,
3084 endp);
3085 /*
3086 * RFC 4271 6.3
3087 * If any recognized attribute has an Attribute
3088 * Length that conflicts with the expected length
3089 * (based on the attribute type code), then the
3090 * Error Subcode MUST be set to Attribute Length
3091 * Error. The Data field MUST contain the erroneous
3092 * attribute (type, length, and value).
3093 * ----------
3094 * We do not currently have a good way to determine the
3095 * length of the attribute independent of the length
3096 * received in the message. Instead we send the
3097 * minimum between the amount of data we have and the
3098 * amount specified by the attribute length field.
3099 *
3100 * Instead of directly passing in the packet buffer and
3101 * offset we use the stream_get* functions to read into
3102 * a stack buffer, since they perform bounds checking
3103 * and we are working with untrusted data.
3104 */
3105 unsigned char ndata[peer->max_packet_size];
3106 memset(ndata, 0x00, sizeof(ndata));
3107 size_t lfl =
3108 CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN) ? 2 : 1;
3109 /* Rewind to end of flag field */
3110 stream_rewind_getp(BGP_INPUT(peer), (1 + lfl));
3111 /* Type */
3112 stream_get(&ndata[0], BGP_INPUT(peer), 1);
3113 /* Length */
3114 stream_get(&ndata[1], BGP_INPUT(peer), lfl);
3115 /* Value */
3116 size_t atl = attr_endp - startp;
3117 size_t ndl = MIN(atl, STREAM_READABLE(BGP_INPUT(peer)));
3118 stream_get(&ndata[lfl + 1], BGP_INPUT(peer), ndl);
3119
3120 bgp_notify_send_with_data(
3121 peer, BGP_NOTIFY_UPDATE_ERR,
3122 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, ndata,
3123 ndl + lfl + 1);
3124
3125 ret = BGP_ATTR_PARSE_ERROR;
3126 goto done;
3127 }
3128
3129 struct bgp_attr_parser_args attr_args = {
3130 .peer = peer,
3131 .length = length,
3132 .attr = attr,
3133 .type = type,
3134 .flags = flag,
3135 .startp = startp,
3136 .total = attr_endp - startp,
3137 };
3138
3139
3140 /* If any recognized attribute has Attribute Flags that conflict
3141 with the Attribute Type Code, then the Error Subcode is set
3142 to
3143 Attribute Flags Error. The Data field contains the erroneous
3144 attribute (type, length and value). */
3145 if (bgp_attr_flag_invalid(&attr_args)) {
3146 ret = bgp_attr_malformed(
3147 &attr_args, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
3148 attr_args.total);
3149 if (ret == BGP_ATTR_PARSE_PROCEED)
3150 continue;
3151 goto done;
3152 }
3153
3154 /* OK check attribute and store it's value. */
3155 switch (type) {
3156 case BGP_ATTR_ORIGIN:
3157 ret = bgp_attr_origin(&attr_args);
3158 break;
3159 case BGP_ATTR_AS_PATH:
3160 ret = bgp_attr_aspath(&attr_args);
3161 break;
3162 case BGP_ATTR_AS4_PATH:
3163 ret = bgp_attr_as4_path(&attr_args, &as4_path);
3164 break;
3165 case BGP_ATTR_NEXT_HOP:
3166 ret = bgp_attr_nexthop(&attr_args);
3167 break;
3168 case BGP_ATTR_MULTI_EXIT_DISC:
3169 ret = bgp_attr_med(&attr_args);
3170 break;
3171 case BGP_ATTR_LOCAL_PREF:
3172 ret = bgp_attr_local_pref(&attr_args);
3173 break;
3174 case BGP_ATTR_ATOMIC_AGGREGATE:
3175 ret = bgp_attr_atomic(&attr_args);
3176 break;
3177 case BGP_ATTR_AGGREGATOR:
3178 ret = bgp_attr_aggregator(&attr_args);
3179 break;
3180 case BGP_ATTR_AS4_AGGREGATOR:
3181 ret = bgp_attr_as4_aggregator(&attr_args,
3182 &as4_aggregator,
3183 &as4_aggregator_addr);
3184 break;
3185 case BGP_ATTR_COMMUNITIES:
3186 ret = bgp_attr_community(&attr_args);
3187 break;
3188 case BGP_ATTR_LARGE_COMMUNITIES:
3189 ret = bgp_attr_large_community(&attr_args);
3190 break;
3191 case BGP_ATTR_ORIGINATOR_ID:
3192 ret = bgp_attr_originator_id(&attr_args);
3193 break;
3194 case BGP_ATTR_CLUSTER_LIST:
3195 ret = bgp_attr_cluster_list(&attr_args);
3196 break;
3197 case BGP_ATTR_MP_REACH_NLRI:
3198 ret = bgp_mp_reach_parse(&attr_args, mp_update);
3199 break;
3200 case BGP_ATTR_MP_UNREACH_NLRI:
3201 ret = bgp_mp_unreach_parse(&attr_args, mp_withdraw);
3202 break;
3203 case BGP_ATTR_EXT_COMMUNITIES:
3204 ret = bgp_attr_ext_communities(&attr_args);
3205 break;
3206 #ifdef ENABLE_BGP_VNC_ATTR
3207 case BGP_ATTR_VNC:
3208 #endif
3209 case BGP_ATTR_ENCAP:
3210 ret = bgp_attr_encap(type, peer, length, attr, flag,
3211 startp);
3212 break;
3213 case BGP_ATTR_PREFIX_SID:
3214 ret = bgp_attr_prefix_sid(&attr_args);
3215 break;
3216 case BGP_ATTR_PMSI_TUNNEL:
3217 ret = bgp_attr_pmsi_tunnel(&attr_args);
3218 break;
3219 case BGP_ATTR_IPV6_EXT_COMMUNITIES:
3220 ret = bgp_attr_ipv6_ext_communities(&attr_args);
3221 break;
3222 default:
3223 ret = bgp_attr_unknown(&attr_args);
3224 break;
3225 }
3226
3227 if (ret == BGP_ATTR_PARSE_ERROR_NOTIFYPLS) {
3228 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3229 BGP_NOTIFY_UPDATE_MAL_ATTR);
3230 ret = BGP_ATTR_PARSE_ERROR;
3231 goto done;
3232 }
3233
3234 if (ret == BGP_ATTR_PARSE_EOR) {
3235 goto done;
3236 }
3237
3238 if (ret == BGP_ATTR_PARSE_ERROR) {
3239 flog_warn(EC_BGP_ATTRIBUTE_PARSE_ERROR,
3240 "%s: Attribute %s, parse error", peer->host,
3241 lookup_msg(attr_str, type, NULL));
3242 goto done;
3243 }
3244 if (ret == BGP_ATTR_PARSE_WITHDRAW) {
3245 flog_warn(
3246 EC_BGP_ATTRIBUTE_PARSE_WITHDRAW,
3247 "%s: Attribute %s, parse error - treating as withdrawal",
3248 peer->host, lookup_msg(attr_str, type, NULL));
3249 goto done;
3250 }
3251
3252 /* Check the fetched length. */
3253 if (BGP_INPUT_PNT(peer) != attr_endp) {
3254 flog_warn(EC_BGP_ATTRIBUTE_FETCH_ERROR,
3255 "%s: BGP attribute %s, fetch error",
3256 peer->host, lookup_msg(attr_str, type, NULL));
3257 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3258 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
3259 ret = BGP_ATTR_PARSE_ERROR;
3260 goto done;
3261 }
3262 }
3263
3264 /*
3265 * draft-ietf-idr-bgp-prefix-sid-27#section-3:
3266 * About Prefix-SID path attribute,
3267 * Label-Index TLV(type1) and The Originator SRGB TLV(type-3)
3268 * may only appear in a BGP Prefix-SID attribute attached to
3269 * IPv4/IPv6 Labeled Unicast prefixes ([RFC8277]).
3270 * It MUST be ignored when received for other BGP AFI/SAFI combinations.
3271 */
3272 if (!attr->mp_nexthop_len || mp_update->safi != SAFI_LABELED_UNICAST)
3273 attr->label_index = BGP_INVALID_LABEL_INDEX;
3274
3275 /* Check final read pointer is same as end pointer. */
3276 if (BGP_INPUT_PNT(peer) != endp) {
3277 flog_warn(EC_BGP_ATTRIBUTES_MISMATCH,
3278 "%s: BGP attribute %s, length mismatch", peer->host,
3279 lookup_msg(attr_str, type, NULL));
3280 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3281 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
3282
3283 ret = BGP_ATTR_PARSE_ERROR;
3284 goto done;
3285 }
3286
3287 /*
3288 * RFC4271: If the NEXT_HOP attribute field is syntactically incorrect,
3289 * then the Error Subcode MUST be set to Invalid NEXT_HOP Attribute.
3290 * This is implemented below and will result in a NOTIFICATION. If the
3291 * NEXT_HOP attribute is semantically incorrect, the error SHOULD be
3292 * logged, and the route SHOULD be ignored. In this case, a NOTIFICATION
3293 * message SHOULD NOT be sent. This is implemented elsewhere.
3294 *
3295 * RFC4760: An UPDATE message that carries no NLRI, other than the one
3296 * encoded in the MP_REACH_NLRI attribute, SHOULD NOT carry the NEXT_HOP
3297 * attribute. If such a message contains the NEXT_HOP attribute, the BGP
3298 * speaker that receives the message SHOULD ignore this attribute.
3299 */
3300 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP))
3301 && !CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI))) {
3302 if (bgp_attr_nexthop_valid(peer, attr) < 0) {
3303 ret = BGP_ATTR_PARSE_ERROR;
3304 goto done;
3305 }
3306 }
3307
3308 /* Check all mandatory well-known attributes are present */
3309 ret = bgp_attr_check(peer, attr);
3310 if (ret < 0)
3311 goto done;
3312
3313 /*
3314 * At this place we can see whether we got AS4_PATH and/or
3315 * AS4_AGGREGATOR from a 16Bit peer and act accordingly.
3316 * We can not do this before we've read all attributes because
3317 * the as4 handling does not say whether AS4_PATH has to be sent
3318 * after AS_PATH or not - and when AS4_AGGREGATOR will be send
3319 * in relationship to AGGREGATOR.
3320 * So, to be defensive, we are not relying on any order and read
3321 * all attributes first, including these 32bit ones, and now,
3322 * afterwards, we look what and if something is to be done for as4.
3323 *
3324 * It is possible to not have AS_PATH, e.g. GR EoR and sole
3325 * MP_UNREACH_NLRI.
3326 */
3327 /* actually... this doesn't ever return failure currently, but
3328 * better safe than sorry */
3329 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AS_PATH))
3330 && bgp_attr_munge_as4_attrs(peer, attr, as4_path, as4_aggregator,
3331 &as4_aggregator_addr)) {
3332 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3333 BGP_NOTIFY_UPDATE_MAL_ATTR);
3334 ret = BGP_ATTR_PARSE_ERROR;
3335 goto done;
3336 }
3337
3338 /*
3339 * Finally do the checks on the aspath we did not do yet
3340 * because we waited for a potentially synthesized aspath.
3341 */
3342 if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS_PATH))) {
3343 ret = bgp_attr_aspath_check(peer, attr);
3344 if (ret != BGP_ATTR_PARSE_PROCEED)
3345 goto done;
3346 }
3347
3348 ret = BGP_ATTR_PARSE_PROCEED;
3349 done:
3350
3351 /*
3352 * At this stage, we have done all fiddling with as4, and the
3353 * resulting info is in attr->aggregator resp. attr->aspath so
3354 * we can chuck as4_aggregator and as4_path alltogether in order
3355 * to save memory
3356 */
3357 if (as4_path) {
3358 /*
3359 * unintern - it is in the hash
3360 * The flag that we got this is still there, but that
3361 * does not do any trouble
3362 */
3363 aspath_unintern(&as4_path);
3364 }
3365
3366 transit = bgp_attr_get_transit(attr);
3367 if (ret != BGP_ATTR_PARSE_ERROR) {
3368 /* Finally intern unknown attribute. */
3369 if (transit)
3370 bgp_attr_set_transit(attr, transit_intern(transit));
3371 if (attr->encap_subtlvs)
3372 attr->encap_subtlvs = encap_intern(attr->encap_subtlvs,
3373 ENCAP_SUBTLV_TYPE);
3374 #ifdef ENABLE_BGP_VNC
3375 struct bgp_attr_encap_subtlv *vnc_subtlvs =
3376 bgp_attr_get_vnc_subtlvs(attr);
3377
3378 if (vnc_subtlvs)
3379 bgp_attr_set_vnc_subtlvs(
3380 attr,
3381 encap_intern(vnc_subtlvs, VNC_SUBTLV_TYPE));
3382 #endif
3383 } else {
3384 if (transit) {
3385 transit_free(transit);
3386 bgp_attr_set_transit(attr, NULL);
3387 }
3388
3389 bgp_attr_flush_encap(attr);
3390 };
3391
3392 /* Sanity checks */
3393 transit = bgp_attr_get_transit(attr);
3394 if (transit)
3395 assert(transit->refcnt > 0);
3396 if (attr->encap_subtlvs)
3397 assert(attr->encap_subtlvs->refcnt > 0);
3398 #ifdef ENABLE_BGP_VNC
3399 struct bgp_attr_encap_subtlv *vnc_subtlvs =
3400 bgp_attr_get_vnc_subtlvs(attr);
3401
3402 if (vnc_subtlvs)
3403 assert(vnc_subtlvs->refcnt > 0);
3404 #endif
3405
3406 return ret;
3407 }
3408
3409 /*
3410 * Extract the tunnel type from extended community
3411 */
3412 void bgp_attr_extcom_tunnel_type(struct attr *attr,
3413 bgp_encap_types *tunnel_type)
3414 {
3415 struct ecommunity *ecom;
3416 uint32_t i;
3417
3418 if (!attr)
3419 return;
3420
3421 ecom = attr->ecommunity;
3422 if (!ecom || !ecom->size)
3423 return;
3424
3425 for (i = 0; i < ecom->size; i++) {
3426 uint8_t *pnt;
3427 uint8_t type, sub_type;
3428
3429 pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
3430 type = pnt[0];
3431 sub_type = pnt[1];
3432 if (!(type == ECOMMUNITY_ENCODE_OPAQUE &&
3433 sub_type == ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP))
3434 continue;
3435 *tunnel_type = ((pnt[6] << 8) | pnt[7]);
3436 return;
3437 }
3438
3439 return;
3440 }
3441
3442 size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi,
3443 safi_t safi, struct bpacket_attr_vec_arr *vecarr,
3444 struct attr *attr)
3445 {
3446 size_t sizep;
3447 iana_afi_t pkt_afi;
3448 iana_safi_t pkt_safi;
3449 afi_t nh_afi;
3450
3451 /* Set extended bit always to encode the attribute length as 2 bytes */
3452 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_EXTLEN);
3453 stream_putc(s, BGP_ATTR_MP_REACH_NLRI);
3454 sizep = stream_get_endp(s);
3455 stream_putw(s, 0); /* Marker: Attribute length. */
3456
3457
3458 /* Convert AFI, SAFI to values for packet. */
3459 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
3460
3461 stream_putw(s, pkt_afi); /* AFI */
3462 stream_putc(s, pkt_safi); /* SAFI */
3463
3464 /* Nexthop AFI */
3465 if (afi == AFI_IP
3466 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST
3467 || safi == SAFI_MPLS_VPN || safi == SAFI_MULTICAST))
3468 nh_afi = peer_cap_enhe(peer, afi, safi) ? AFI_IP6 : AFI_IP;
3469 else if (safi == SAFI_FLOWSPEC)
3470 nh_afi = afi;
3471 else
3472 nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->mp_nexthop_len);
3473
3474 /* Nexthop */
3475 bpacket_attr_vec_arr_set_vec(vecarr, BGP_ATTR_VEC_NH, s, attr);
3476 switch (nh_afi) {
3477 case AFI_IP:
3478 switch (safi) {
3479 case SAFI_UNICAST:
3480 case SAFI_MULTICAST:
3481 case SAFI_LABELED_UNICAST:
3482 stream_putc(s, 4);
3483 stream_put_ipv4(s, attr->nexthop.s_addr);
3484 break;
3485 case SAFI_MPLS_VPN:
3486 stream_putc(s, 12);
3487 stream_putl(s, 0); /* RD = 0, per RFC */
3488 stream_putl(s, 0);
3489 stream_put(s, &attr->mp_nexthop_global_in, 4);
3490 break;
3491 case SAFI_ENCAP:
3492 case SAFI_EVPN:
3493 stream_putc(s, 4);
3494 stream_put(s, &attr->mp_nexthop_global_in, 4);
3495 break;
3496 case SAFI_FLOWSPEC:
3497 if (attr->mp_nexthop_len == 0)
3498 stream_putc(s, 0); /* no nexthop for flowspec */
3499 else {
3500 stream_putc(s, attr->mp_nexthop_len);
3501 stream_put_ipv4(s, attr->nexthop.s_addr);
3502 }
3503 default:
3504 break;
3505 }
3506 break;
3507 case AFI_IP6:
3508 switch (safi) {
3509 case SAFI_UNICAST:
3510 case SAFI_MULTICAST:
3511 case SAFI_LABELED_UNICAST:
3512 case SAFI_EVPN: {
3513 if (attr->mp_nexthop_len
3514 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
3515 stream_putc(s,
3516 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL);
3517 stream_put(s, &attr->mp_nexthop_global,
3518 IPV6_MAX_BYTELEN);
3519 stream_put(s, &attr->mp_nexthop_local,
3520 IPV6_MAX_BYTELEN);
3521 } else {
3522 stream_putc(s, IPV6_MAX_BYTELEN);
3523 stream_put(s, &attr->mp_nexthop_global,
3524 IPV6_MAX_BYTELEN);
3525 }
3526 } break;
3527 case SAFI_MPLS_VPN: {
3528 if (attr->mp_nexthop_len
3529 == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
3530 stream_putc(s, 24);
3531 stream_putl(s, 0); /* RD = 0, per RFC */
3532 stream_putl(s, 0);
3533 stream_put(s, &attr->mp_nexthop_global,
3534 IPV6_MAX_BYTELEN);
3535 } else if (attr->mp_nexthop_len
3536 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
3537 stream_putc(s, 48);
3538 stream_putl(s, 0); /* RD = 0, per RFC */
3539 stream_putl(s, 0);
3540 stream_put(s, &attr->mp_nexthop_global,
3541 IPV6_MAX_BYTELEN);
3542 stream_putl(s, 0); /* RD = 0, per RFC */
3543 stream_putl(s, 0);
3544 stream_put(s, &attr->mp_nexthop_local,
3545 IPV6_MAX_BYTELEN);
3546 }
3547 } break;
3548 case SAFI_ENCAP:
3549 stream_putc(s, IPV6_MAX_BYTELEN);
3550 stream_put(s, &attr->mp_nexthop_global,
3551 IPV6_MAX_BYTELEN);
3552 break;
3553 case SAFI_FLOWSPEC:
3554 stream_putc(s, 0); /* no nexthop for flowspec */
3555 default:
3556 break;
3557 }
3558 break;
3559 default:
3560 if (safi != SAFI_FLOWSPEC)
3561 flog_err(
3562 EC_BGP_ATTR_NH_SEND_LEN,
3563 "Bad nexthop when sending to %s, AFI %u SAFI %u nhlen %d",
3564 peer->host, afi, safi, attr->mp_nexthop_len);
3565 break;
3566 }
3567
3568 /* SNPA */
3569 stream_putc(s, 0);
3570 return sizep;
3571 }
3572
3573 void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
3574 const struct prefix *p,
3575 const struct prefix_rd *prd, mpls_label_t *label,
3576 uint32_t num_labels, int addpath_encode,
3577 uint32_t addpath_tx_id, struct attr *attr)
3578 {
3579 if (safi == SAFI_MPLS_VPN) {
3580 if (addpath_encode)
3581 stream_putl(s, addpath_tx_id);
3582 /* Label, RD, Prefix write. */
3583 stream_putc(s, p->prefixlen + 88);
3584 stream_put(s, label, BGP_LABEL_BYTES);
3585 stream_put(s, prd->val, 8);
3586 stream_put(s, &p->u.prefix, PSIZE(p->prefixlen));
3587 } else if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
3588 /* EVPN prefix - contents depend on type */
3589 bgp_evpn_encode_prefix(s, p, prd, label, num_labels, attr,
3590 addpath_encode, addpath_tx_id);
3591 } else if (safi == SAFI_LABELED_UNICAST) {
3592 /* Prefix write with label. */
3593 stream_put_labeled_prefix(s, p, label, addpath_encode,
3594 addpath_tx_id);
3595 } else if (safi == SAFI_FLOWSPEC) {
3596 stream_putc(s, p->u.prefix_flowspec.prefixlen);
3597 stream_put(s, (const void *)p->u.prefix_flowspec.ptr,
3598 p->u.prefix_flowspec.prefixlen);
3599 } else
3600 stream_put_prefix_addpath(s, p, addpath_encode, addpath_tx_id);
3601 }
3602
3603 size_t bgp_packet_mpattr_prefix_size(afi_t afi, safi_t safi,
3604 const struct prefix *p)
3605 {
3606 int size = PSIZE(p->prefixlen);
3607 if (safi == SAFI_MPLS_VPN)
3608 size += 88;
3609 else if (safi == SAFI_LABELED_UNICAST)
3610 size += BGP_LABEL_BYTES;
3611 else if (afi == AFI_L2VPN && safi == SAFI_EVPN)
3612 size += 232; // TODO: Maximum possible for type-2, type-3 and
3613 // type-5
3614 return size;
3615 }
3616
3617 /*
3618 * Encodes the tunnel encapsulation attribute,
3619 * and with ENABLE_BGP_VNC the VNC attribute which uses
3620 * almost the same TLV format
3621 */
3622 static void bgp_packet_mpattr_tea(struct bgp *bgp, struct peer *peer,
3623 struct stream *s, struct attr *attr,
3624 uint8_t attrtype)
3625 {
3626 unsigned int attrlenfield = 0;
3627 unsigned int attrhdrlen = 0;
3628 struct bgp_attr_encap_subtlv *subtlvs;
3629 struct bgp_attr_encap_subtlv *st;
3630 const char *attrname;
3631
3632 if (!attr || (attrtype == BGP_ATTR_ENCAP
3633 && (!attr->encap_tunneltype
3634 || attr->encap_tunneltype == BGP_ENCAP_TYPE_MPLS)))
3635 return;
3636
3637 switch (attrtype) {
3638 case BGP_ATTR_ENCAP:
3639 attrname = "Tunnel Encap";
3640 subtlvs = attr->encap_subtlvs;
3641 if (subtlvs == NULL) /* nothing to do */
3642 return;
3643 /*
3644 * The tunnel encap attr has an "outer" tlv.
3645 * T = tunneltype,
3646 * L = total length of subtlvs,
3647 * V = concatenated subtlvs.
3648 */
3649 attrlenfield = 2 + 2; /* T + L */
3650 attrhdrlen = 1 + 1; /* subTLV T + L */
3651 break;
3652
3653 #ifdef ENABLE_BGP_VNC_ATTR
3654 case BGP_ATTR_VNC:
3655 attrname = "VNC";
3656 subtlvs = bgp_attr_get_vnc_subtlvs(attr);
3657 if (subtlvs == NULL) /* nothing to do */
3658 return;
3659 attrlenfield = 0; /* no outer T + L */
3660 attrhdrlen = 2 + 2; /* subTLV T + L */
3661 break;
3662 #endif
3663
3664 default:
3665 assert(0);
3666 }
3667
3668 /* compute attr length */
3669 for (st = subtlvs; st; st = st->next) {
3670 attrlenfield += (attrhdrlen + st->length);
3671 }
3672
3673 if (attrlenfield > 0xffff) {
3674 zlog_info("%s attribute is too long (length=%d), can't send it",
3675 attrname, attrlenfield);
3676 return;
3677 }
3678
3679 if (attrlenfield > 0xff) {
3680 /* 2-octet length field */
3681 stream_putc(s,
3682 BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL
3683 | BGP_ATTR_FLAG_EXTLEN);
3684 stream_putc(s, attrtype);
3685 stream_putw(s, attrlenfield & 0xffff);
3686 } else {
3687 /* 1-octet length field */
3688 stream_putc(s, BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL);
3689 stream_putc(s, attrtype);
3690 stream_putc(s, attrlenfield & 0xff);
3691 }
3692
3693 if (attrtype == BGP_ATTR_ENCAP) {
3694 /* write outer T+L */
3695 stream_putw(s, attr->encap_tunneltype);
3696 stream_putw(s, attrlenfield - 4);
3697 }
3698
3699 /* write each sub-tlv */
3700 for (st = subtlvs; st; st = st->next) {
3701 if (attrtype == BGP_ATTR_ENCAP) {
3702 stream_putc(s, st->type);
3703 stream_putc(s, st->length);
3704 #ifdef ENABLE_BGP_VNC
3705 } else {
3706 stream_putw(s, st->type);
3707 stream_putw(s, st->length);
3708 #endif
3709 }
3710 stream_put(s, st->value, st->length);
3711 }
3712 }
3713
3714 void bgp_packet_mpattr_end(struct stream *s, size_t sizep)
3715 {
3716 /* Set MP attribute length. Don't count the (2) bytes used to encode
3717 the attr length */
3718 stream_putw_at(s, sizep, (stream_get_endp(s) - sizep) - 2);
3719 }
3720
3721 static bool bgp_append_local_as(struct peer *peer, afi_t afi, safi_t safi)
3722 {
3723 if (!BGP_AS_IS_PRIVATE(peer->local_as)
3724 || (BGP_AS_IS_PRIVATE(peer->local_as)
3725 && !CHECK_FLAG(peer->af_flags[afi][safi],
3726 PEER_FLAG_REMOVE_PRIVATE_AS)
3727 && !CHECK_FLAG(peer->af_flags[afi][safi],
3728 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
3729 && !CHECK_FLAG(peer->af_flags[afi][safi],
3730 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
3731 && !CHECK_FLAG(peer->af_flags[afi][safi],
3732 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)))
3733 return true;
3734 return false;
3735 }
3736
3737 /* Make attribute packet. */
3738 bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
3739 struct stream *s, struct attr *attr,
3740 struct bpacket_attr_vec_arr *vecarr,
3741 struct prefix *p, afi_t afi, safi_t safi,
3742 struct peer *from, struct prefix_rd *prd,
3743 mpls_label_t *label, uint32_t num_labels,
3744 int addpath_encode, uint32_t addpath_tx_id)
3745 {
3746 size_t cp;
3747 size_t aspath_sizep;
3748 struct aspath *aspath;
3749 int send_as4_path = 0;
3750 int send_as4_aggregator = 0;
3751 bool use32bit = CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV);
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 }