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