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