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