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