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