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