]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_attr.c
Merge pull request #10256 from anlancs/cleanup-zebra_evpn_mac_add
[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 /* Always release the 'intern()'ed AS Path. */
1077 aspath_unintern(&attr.aspath);
1078
1079 return new;
1080 }
1081
1082 /* Unintern just the sub-components of the attr, but not the attr */
1083 void bgp_attr_unintern_sub(struct attr *attr)
1084 {
1085 struct ecommunity *ecomm;
1086 struct cluster_list *cluster;
1087
1088 /* aspath refcount shoud be decrement. */
1089 if (attr->aspath)
1090 aspath_unintern(&attr->aspath);
1091 UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AS_PATH));
1092
1093 if (attr->community)
1094 community_unintern(&attr->community);
1095 UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES));
1096
1097 ecommunity_unintern(&attr->ecommunity);
1098 UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES));
1099
1100 ecomm = bgp_attr_get_ipv6_ecommunity(attr);
1101 ecommunity_unintern(&ecomm);
1102 UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_IPV6_EXT_COMMUNITIES));
1103 bgp_attr_set_ipv6_ecommunity(attr, NULL);
1104
1105 if (attr->lcommunity)
1106 lcommunity_unintern(&attr->lcommunity);
1107 UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES));
1108
1109 cluster = bgp_attr_get_cluster(attr);
1110 if (cluster) {
1111 cluster_unintern(&cluster);
1112 bgp_attr_set_cluster(attr, cluster);
1113 }
1114 UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST));
1115
1116 struct transit *transit = bgp_attr_get_transit(attr);
1117
1118 if (transit) {
1119 transit_unintern(&transit);
1120 bgp_attr_set_transit(attr, transit);
1121 }
1122
1123 if (attr->encap_subtlvs)
1124 encap_unintern(&attr->encap_subtlvs, ENCAP_SUBTLV_TYPE);
1125
1126 #ifdef ENABLE_BGP_VNC
1127 struct bgp_attr_encap_subtlv *vnc_subtlvs =
1128 bgp_attr_get_vnc_subtlvs(attr);
1129
1130 if (vnc_subtlvs) {
1131 encap_unintern(&vnc_subtlvs, VNC_SUBTLV_TYPE);
1132 bgp_attr_set_vnc_subtlvs(attr, vnc_subtlvs);
1133 }
1134 #endif
1135
1136 if (attr->srv6_l3vpn)
1137 srv6_l3vpn_unintern(&attr->srv6_l3vpn);
1138
1139 if (attr->srv6_vpn)
1140 srv6_vpn_unintern(&attr->srv6_vpn);
1141 }
1142
1143 /*
1144 * We have some show commands that let you experimentally
1145 * apply a route-map. When we apply the route-map
1146 * we are reseting values but not saving them for
1147 * posterity via intern'ing( because route-maps don't
1148 * do that) but at this point in time we need
1149 * to compare the new attr to the old and if the
1150 * routemap has changed it we need to, as Snoop Dog says,
1151 * Drop it like it's hot
1152 */
1153 void bgp_attr_undup(struct attr *new, struct attr *old)
1154 {
1155 if (new->aspath != old->aspath)
1156 aspath_free(new->aspath);
1157
1158 if (new->community != old->community)
1159 community_free(&new->community);
1160
1161 if (new->ecommunity != old->ecommunity)
1162 ecommunity_free(&new->ecommunity);
1163
1164 if (new->lcommunity != old->lcommunity)
1165 lcommunity_free(&new->lcommunity);
1166
1167 if (new->srv6_l3vpn != old->srv6_l3vpn) {
1168 srv6_l3vpn_free(new->srv6_l3vpn);
1169 new->srv6_l3vpn = NULL;
1170 }
1171
1172 if (new->srv6_vpn != old->srv6_vpn) {
1173 srv6_vpn_free(new->srv6_vpn);
1174 new->srv6_vpn = NULL;
1175 }
1176 }
1177
1178 /* Free bgp attribute and aspath. */
1179 void bgp_attr_unintern(struct attr **pattr)
1180 {
1181 struct attr *attr = *pattr;
1182 struct attr *ret;
1183 struct attr tmp;
1184
1185 /* Decrement attribute reference. */
1186 attr->refcnt--;
1187
1188 tmp = *attr;
1189
1190 /* If reference becomes zero then free attribute object. */
1191 if (attr->refcnt == 0) {
1192 ret = hash_release(attrhash, attr);
1193 assert(ret != NULL);
1194 XFREE(MTYPE_ATTR, attr);
1195 *pattr = NULL;
1196 }
1197
1198 bgp_attr_unintern_sub(&tmp);
1199 }
1200
1201 void bgp_attr_flush(struct attr *attr)
1202 {
1203 struct ecommunity *ecomm;
1204 struct cluster_list *cluster;
1205
1206 if (attr->aspath && !attr->aspath->refcnt) {
1207 aspath_free(attr->aspath);
1208 attr->aspath = NULL;
1209 }
1210 if (attr->community && !attr->community->refcnt)
1211 community_free(&attr->community);
1212 if (attr->ecommunity && !attr->ecommunity->refcnt)
1213 ecommunity_free(&attr->ecommunity);
1214 ecomm = bgp_attr_get_ipv6_ecommunity(attr);
1215 if (ecomm && !ecomm->refcnt)
1216 ecommunity_free(&ecomm);
1217 bgp_attr_set_ipv6_ecommunity(attr, NULL);
1218 if (attr->lcommunity && !attr->lcommunity->refcnt)
1219 lcommunity_free(&attr->lcommunity);
1220
1221 cluster = bgp_attr_get_cluster(attr);
1222 if (cluster && !cluster->refcnt) {
1223 cluster_free(cluster);
1224 bgp_attr_set_cluster(attr, NULL);
1225 }
1226
1227 struct transit *transit = bgp_attr_get_transit(attr);
1228
1229 if (transit && !transit->refcnt) {
1230 transit_free(transit);
1231 bgp_attr_set_transit(attr, NULL);
1232 }
1233 if (attr->encap_subtlvs && !attr->encap_subtlvs->refcnt) {
1234 encap_free(attr->encap_subtlvs);
1235 attr->encap_subtlvs = NULL;
1236 }
1237 if (attr->srv6_l3vpn && !attr->srv6_l3vpn->refcnt) {
1238 srv6_l3vpn_free(attr->srv6_l3vpn);
1239 attr->srv6_l3vpn = NULL;
1240 }
1241 if (attr->srv6_vpn && !attr->srv6_vpn->refcnt) {
1242 srv6_vpn_free(attr->srv6_vpn);
1243 attr->srv6_vpn = NULL;
1244 }
1245 #ifdef ENABLE_BGP_VNC
1246 struct bgp_attr_encap_subtlv *vnc_subtlvs =
1247 bgp_attr_get_vnc_subtlvs(attr);
1248
1249 if (vnc_subtlvs && !vnc_subtlvs->refcnt) {
1250 encap_free(vnc_subtlvs);
1251 bgp_attr_set_vnc_subtlvs(attr, NULL);
1252 }
1253 #endif
1254 }
1255
1256 /* Implement draft-scudder-idr-optional-transitive behaviour and
1257 * avoid resetting sessions for malformed attributes which are
1258 * are partial/optional and hence where the error likely was not
1259 * introduced by the sending neighbour.
1260 */
1261 static bgp_attr_parse_ret_t
1262 bgp_attr_malformed(struct bgp_attr_parser_args *args, uint8_t subcode,
1263 bgp_size_t length)
1264 {
1265 struct peer *const peer = args->peer;
1266 struct attr *const attr = args->attr;
1267 const uint8_t flags = args->flags;
1268 /* startp and length must be special-cased, as whether or not to
1269 * send the attribute data with the NOTIFY depends on the error,
1270 * the caller therefore signals this with the seperate length argument
1271 */
1272 uint8_t *notify_datap = (length > 0 ? args->startp : NULL);
1273
1274 if (bgp_debug_update(peer, NULL, NULL, 1)) {
1275 char attr_str[BUFSIZ] = {0};
1276
1277 bgp_dump_attr(attr, attr_str, sizeof(attr_str));
1278
1279 zlog_debug("%s: attributes: %s", __func__, attr_str);
1280 }
1281
1282 /* Only relax error handling for eBGP peers */
1283 if (peer->sort != BGP_PEER_EBGP) {
1284 bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR, subcode,
1285 notify_datap, length);
1286 return BGP_ATTR_PARSE_ERROR;
1287 }
1288
1289 /* Adjust the stream getp to the end of the attribute, in case we can
1290 * still proceed but the caller hasn't read all the attribute.
1291 */
1292 stream_set_getp(BGP_INPUT(peer),
1293 (args->startp - STREAM_DATA(BGP_INPUT(peer)))
1294 + args->total);
1295
1296 switch (args->type) {
1297 /* where an attribute is relatively inconsequential, e.g. it does not
1298 * affect route selection, and can be safely ignored, then any such
1299 * attributes which are malformed should just be ignored and the route
1300 * processed as normal.
1301 */
1302 case BGP_ATTR_AS4_AGGREGATOR:
1303 case BGP_ATTR_AGGREGATOR:
1304 case BGP_ATTR_ATOMIC_AGGREGATE:
1305 return BGP_ATTR_PARSE_PROCEED;
1306
1307 /* Core attributes, particularly ones which may influence route
1308 * selection, should be treat-as-withdraw.
1309 */
1310 case BGP_ATTR_ORIGIN:
1311 case BGP_ATTR_AS_PATH:
1312 case BGP_ATTR_NEXT_HOP:
1313 case BGP_ATTR_MULTI_EXIT_DISC:
1314 case BGP_ATTR_LOCAL_PREF:
1315 case BGP_ATTR_COMMUNITIES:
1316 case BGP_ATTR_EXT_COMMUNITIES:
1317 case BGP_ATTR_IPV6_EXT_COMMUNITIES:
1318 case BGP_ATTR_LARGE_COMMUNITIES:
1319 case BGP_ATTR_ORIGINATOR_ID:
1320 case BGP_ATTR_CLUSTER_LIST:
1321 return BGP_ATTR_PARSE_WITHDRAW;
1322 case BGP_ATTR_MP_REACH_NLRI:
1323 case BGP_ATTR_MP_UNREACH_NLRI:
1324 bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR, subcode,
1325 notify_datap, length);
1326 return BGP_ATTR_PARSE_ERROR;
1327 }
1328
1329 /* Partial optional attributes that are malformed should not cause
1330 * the whole session to be reset. Instead treat it as a withdrawal
1331 * of the routes, if possible.
1332 */
1333 if (CHECK_FLAG(flags, BGP_ATTR_FLAG_TRANS)
1334 && CHECK_FLAG(flags, BGP_ATTR_FLAG_OPTIONAL)
1335 && CHECK_FLAG(flags, BGP_ATTR_FLAG_PARTIAL))
1336 return BGP_ATTR_PARSE_WITHDRAW;
1337
1338 /* default to reset */
1339 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
1340 }
1341
1342 /* Find out what is wrong with the path attribute flag bits and log the error.
1343 "Flag bits" here stand for Optional, Transitive and Partial, but not for
1344 Extended Length. Checking O/T/P bits at once implies, that the attribute
1345 being diagnosed is defined by RFC as either a "well-known" or an "optional,
1346 non-transitive" attribute. */
1347 static void
1348 bgp_attr_flags_diagnose(struct bgp_attr_parser_args *args,
1349 uint8_t desired_flags /* how RFC says it must be */
1350 )
1351 {
1352 uint8_t seen = 0, i;
1353 uint8_t real_flags = args->flags;
1354 const uint8_t attr_code = args->type;
1355
1356 desired_flags &= ~BGP_ATTR_FLAG_EXTLEN;
1357 real_flags &= ~BGP_ATTR_FLAG_EXTLEN;
1358 for (i = 0; i <= 2; i++) /* O,T,P, but not E */
1359 if (CHECK_FLAG(desired_flags, attr_flag_str[i].key)
1360 != CHECK_FLAG(real_flags, attr_flag_str[i].key)) {
1361 flog_err(EC_BGP_ATTR_FLAG,
1362 "%s attribute must%s be flagged as \"%s\"",
1363 lookup_msg(attr_str, attr_code, NULL),
1364 CHECK_FLAG(desired_flags, attr_flag_str[i].key)
1365 ? ""
1366 : " not",
1367 attr_flag_str[i].str);
1368 seen = 1;
1369 }
1370 if (!seen) {
1371 zlog_debug(
1372 "Strange, %s called for attr %s, but no problem found with flags (real flags 0x%x, desired 0x%x)",
1373 __func__, lookup_msg(attr_str, attr_code, NULL),
1374 real_flags, desired_flags);
1375 }
1376 }
1377
1378 /* Required flags for attributes. EXTLEN will be masked off when testing,
1379 * as will PARTIAL for optional+transitive attributes.
1380 */
1381 const uint8_t attr_flags_values[] = {
1382 [BGP_ATTR_ORIGIN] = BGP_ATTR_FLAG_TRANS,
1383 [BGP_ATTR_AS_PATH] = BGP_ATTR_FLAG_TRANS,
1384 [BGP_ATTR_NEXT_HOP] = BGP_ATTR_FLAG_TRANS,
1385 [BGP_ATTR_MULTI_EXIT_DISC] = BGP_ATTR_FLAG_OPTIONAL,
1386 [BGP_ATTR_LOCAL_PREF] = BGP_ATTR_FLAG_TRANS,
1387 [BGP_ATTR_ATOMIC_AGGREGATE] = BGP_ATTR_FLAG_TRANS,
1388 [BGP_ATTR_AGGREGATOR] = BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
1389 [BGP_ATTR_COMMUNITIES] = BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL,
1390 [BGP_ATTR_ORIGINATOR_ID] = BGP_ATTR_FLAG_OPTIONAL,
1391 [BGP_ATTR_CLUSTER_LIST] = BGP_ATTR_FLAG_OPTIONAL,
1392 [BGP_ATTR_MP_REACH_NLRI] = BGP_ATTR_FLAG_OPTIONAL,
1393 [BGP_ATTR_MP_UNREACH_NLRI] = BGP_ATTR_FLAG_OPTIONAL,
1394 [BGP_ATTR_EXT_COMMUNITIES] =
1395 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1396 [BGP_ATTR_AS4_PATH] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1397 [BGP_ATTR_AS4_AGGREGATOR] =
1398 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1399 [BGP_ATTR_PMSI_TUNNEL] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1400 [BGP_ATTR_LARGE_COMMUNITIES] =
1401 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1402 [BGP_ATTR_PREFIX_SID] = BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1403 [BGP_ATTR_IPV6_EXT_COMMUNITIES] =
1404 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS,
1405 };
1406 static const size_t attr_flags_values_max = array_size(attr_flags_values) - 1;
1407
1408 static bool bgp_attr_flag_invalid(struct bgp_attr_parser_args *args)
1409 {
1410 uint8_t mask = BGP_ATTR_FLAG_EXTLEN;
1411 const uint8_t flags = args->flags;
1412 const uint8_t attr_code = args->type;
1413
1414 /* there may be attributes we don't know about */
1415 if (attr_code > attr_flags_values_max)
1416 return false;
1417 if (attr_flags_values[attr_code] == 0)
1418 return false;
1419
1420 /* RFC4271, "For well-known attributes, the Transitive bit MUST be set
1421 * to
1422 * 1."
1423 */
1424 if (!CHECK_FLAG(BGP_ATTR_FLAG_OPTIONAL, flags)
1425 && !CHECK_FLAG(BGP_ATTR_FLAG_TRANS, flags)) {
1426 flog_err(
1427 EC_BGP_ATTR_FLAG,
1428 "%s well-known attributes must have transitive flag set (%x)",
1429 lookup_msg(attr_str, attr_code, NULL), flags);
1430 return true;
1431 }
1432
1433 /* "For well-known attributes and for optional non-transitive
1434 * attributes,
1435 * the Partial bit MUST be set to 0."
1436 */
1437 if (CHECK_FLAG(flags, BGP_ATTR_FLAG_PARTIAL)) {
1438 if (!CHECK_FLAG(flags, BGP_ATTR_FLAG_OPTIONAL)) {
1439 flog_err(EC_BGP_ATTR_FLAG,
1440 "%s well-known attribute must NOT have the partial flag set (%x)",
1441 lookup_msg(attr_str, attr_code, NULL), flags);
1442 return true;
1443 }
1444 if (CHECK_FLAG(flags, BGP_ATTR_FLAG_OPTIONAL)
1445 && !CHECK_FLAG(flags, BGP_ATTR_FLAG_TRANS)) {
1446 flog_err(EC_BGP_ATTR_FLAG,
1447 "%s optional + transitive attribute must NOT have the partial flag set (%x)",
1448 lookup_msg(attr_str, attr_code, NULL), flags);
1449 return true;
1450 }
1451 }
1452
1453 /* Optional transitive attributes may go through speakers that don't
1454 * reocgnise them and set the Partial bit.
1455 */
1456 if (CHECK_FLAG(flags, BGP_ATTR_FLAG_OPTIONAL)
1457 && CHECK_FLAG(flags, BGP_ATTR_FLAG_TRANS))
1458 SET_FLAG(mask, BGP_ATTR_FLAG_PARTIAL);
1459
1460 if ((flags & ~mask) == attr_flags_values[attr_code])
1461 return false;
1462
1463 bgp_attr_flags_diagnose(args, attr_flags_values[attr_code]);
1464 return true;
1465 }
1466
1467 /* Get origin attribute of the update message. */
1468 static bgp_attr_parse_ret_t bgp_attr_origin(struct bgp_attr_parser_args *args)
1469 {
1470 struct peer *const peer = args->peer;
1471 struct attr *const attr = args->attr;
1472 const bgp_size_t length = args->length;
1473
1474 /* If any recognized attribute has Attribute Length that conflicts
1475 with the expected length (based on the attribute type code), then
1476 the Error Subcode is set to Attribute Length Error. The Data
1477 field contains the erroneous attribute (type, length and
1478 value). */
1479 if (length != 1) {
1480 flog_err(EC_BGP_ATTR_LEN,
1481 "Origin attribute length is not one %d", length);
1482 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1483 args->total);
1484 }
1485
1486 /* Fetch origin attribute. */
1487 attr->origin = stream_getc(BGP_INPUT(peer));
1488
1489 /* If the ORIGIN attribute has an undefined value, then the Error
1490 Subcode is set to Invalid Origin Attribute. The Data field
1491 contains the unrecognized attribute (type, length and value). */
1492 if ((attr->origin != BGP_ORIGIN_IGP) && (attr->origin != BGP_ORIGIN_EGP)
1493 && (attr->origin != BGP_ORIGIN_INCOMPLETE)) {
1494 flog_err(EC_BGP_ATTR_ORIGIN,
1495 "Origin attribute value is invalid %d", attr->origin);
1496 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_INVAL_ORIGIN,
1497 args->total);
1498 }
1499
1500 /* Set oring attribute flag. */
1501 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_ORIGIN);
1502
1503 return 0;
1504 }
1505
1506 /* Parse AS path information. This function is wrapper of
1507 aspath_parse. */
1508 static int bgp_attr_aspath(struct bgp_attr_parser_args *args)
1509 {
1510 struct attr *const attr = args->attr;
1511 struct peer *const peer = args->peer;
1512 const bgp_size_t length = args->length;
1513
1514 /*
1515 * peer with AS4 => will get 4Byte ASnums
1516 * otherwise, will get 16 Bit
1517 */
1518 attr->aspath = aspath_parse(
1519 peer->curr, length,
1520 CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)
1521 && CHECK_FLAG(peer->cap, PEER_CAP_AS4_ADV));
1522
1523 /* In case of IBGP, length will be zero. */
1524 if (!attr->aspath) {
1525 flog_err(EC_BGP_ATTR_MAL_AS_PATH,
1526 "Malformed AS path from %s, length is %d", peer->host,
1527 length);
1528 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_MAL_AS_PATH,
1529 0);
1530 }
1531
1532 /* Set aspath attribute flag. */
1533 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AS_PATH);
1534
1535 return BGP_ATTR_PARSE_PROCEED;
1536 }
1537
1538 static bgp_attr_parse_ret_t bgp_attr_aspath_check(struct peer *const peer,
1539 struct attr *const attr)
1540 {
1541 /* These checks were part of bgp_attr_aspath, but with
1542 * as4 we should to check aspath things when
1543 * aspath synthesizing with as4_path has already taken place.
1544 * Otherwise we check ASPATH and use the synthesized thing, and that is
1545 * not right.
1546 * So do the checks later, i.e. here
1547 */
1548 struct aspath *aspath;
1549
1550 /* Confederation sanity check. */
1551 if ((peer->sort == BGP_PEER_CONFED
1552 && !aspath_left_confed_check(attr->aspath))
1553 || (peer->sort == BGP_PEER_EBGP
1554 && aspath_confed_check(attr->aspath))) {
1555 flog_err(EC_BGP_ATTR_MAL_AS_PATH, "Malformed AS path from %s",
1556 peer->host);
1557 return BGP_ATTR_PARSE_WITHDRAW;
1558 }
1559
1560 /* First AS check for EBGP. */
1561 if (CHECK_FLAG(peer->flags, PEER_FLAG_ENFORCE_FIRST_AS)) {
1562 if (peer->sort == BGP_PEER_EBGP
1563 && !aspath_firstas_check(attr->aspath, peer->as)) {
1564 flog_err(EC_BGP_ATTR_FIRST_AS,
1565 "%s incorrect first AS (must be %u)",
1566 peer->host, peer->as);
1567 return BGP_ATTR_PARSE_WITHDRAW;
1568 }
1569 }
1570
1571 /* Codification of AS 0 Processing */
1572 if (peer->sort == BGP_PEER_EBGP && aspath_check_as_zero(attr->aspath)) {
1573 flog_err(
1574 EC_BGP_ATTR_MAL_AS_PATH,
1575 "Malformed AS path, AS number is 0 in the path from %s",
1576 peer->host);
1577 return BGP_ATTR_PARSE_WITHDRAW;
1578 }
1579
1580 /* local-as prepend */
1581 if (peer->change_local_as
1582 && !CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND)) {
1583 aspath = aspath_dup(attr->aspath);
1584 aspath = aspath_add_seq(aspath, peer->change_local_as);
1585 aspath_unintern(&attr->aspath);
1586 attr->aspath = aspath_intern(aspath);
1587 }
1588
1589 return BGP_ATTR_PARSE_PROCEED;
1590 }
1591
1592 /* Parse AS4 path information. This function is another wrapper of
1593 aspath_parse. */
1594 static int bgp_attr_as4_path(struct bgp_attr_parser_args *args,
1595 struct aspath **as4_path)
1596 {
1597 struct peer *const peer = args->peer;
1598 struct attr *const attr = args->attr;
1599 const bgp_size_t length = args->length;
1600
1601 *as4_path = aspath_parse(peer->curr, length, 1);
1602
1603 /* In case of IBGP, length will be zero. */
1604 if (!*as4_path) {
1605 flog_err(EC_BGP_ATTR_MAL_AS_PATH,
1606 "Malformed AS4 path from %s, length is %d", peer->host,
1607 length);
1608 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_MAL_AS_PATH,
1609 0);
1610 }
1611
1612 /* Set aspath attribute flag. */
1613 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AS4_PATH);
1614
1615 return BGP_ATTR_PARSE_PROCEED;
1616 }
1617
1618 /*
1619 * Check that the nexthop attribute is valid.
1620 */
1621 bgp_attr_parse_ret_t
1622 bgp_attr_nexthop_valid(struct peer *peer, struct attr *attr)
1623 {
1624 in_addr_t nexthop_h;
1625
1626 nexthop_h = ntohl(attr->nexthop.s_addr);
1627 if ((IPV4_NET0(nexthop_h) || IPV4_NET127(nexthop_h)
1628 || IPV4_CLASS_DE(nexthop_h))
1629 && !BGP_DEBUG(allow_martians, ALLOW_MARTIANS)) {
1630 uint8_t data[7]; /* type(2) + length(1) + nhop(4) */
1631 char buf[INET_ADDRSTRLEN];
1632
1633 inet_ntop(AF_INET, &attr->nexthop.s_addr, buf,
1634 INET_ADDRSTRLEN);
1635 flog_err(EC_BGP_ATTR_MARTIAN_NH, "Martian nexthop %s",
1636 buf);
1637 data[0] = BGP_ATTR_FLAG_TRANS;
1638 data[1] = BGP_ATTR_NEXT_HOP;
1639 data[2] = BGP_ATTR_NHLEN_IPV4;
1640 memcpy(&data[3], &attr->nexthop.s_addr, BGP_ATTR_NHLEN_IPV4);
1641 bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR,
1642 BGP_NOTIFY_UPDATE_INVAL_NEXT_HOP,
1643 data, 7);
1644 return BGP_ATTR_PARSE_ERROR;
1645 }
1646
1647 return BGP_ATTR_PARSE_PROCEED;
1648 }
1649
1650 /* Nexthop attribute. */
1651 static bgp_attr_parse_ret_t bgp_attr_nexthop(struct bgp_attr_parser_args *args)
1652 {
1653 struct peer *const peer = args->peer;
1654 struct attr *const attr = args->attr;
1655 const bgp_size_t length = args->length;
1656
1657 /* Check nexthop attribute length. */
1658 if (length != 4) {
1659 flog_err(EC_BGP_ATTR_LEN,
1660 "Nexthop attribute length isn't four [%d]", length);
1661
1662 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1663 args->total);
1664 }
1665
1666 attr->nexthop.s_addr = stream_get_ipv4(peer->curr);
1667 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
1668
1669 return BGP_ATTR_PARSE_PROCEED;
1670 }
1671
1672 /* MED atrribute. */
1673 static bgp_attr_parse_ret_t bgp_attr_med(struct bgp_attr_parser_args *args)
1674 {
1675 struct peer *const peer = args->peer;
1676 struct attr *const attr = args->attr;
1677 const bgp_size_t length = args->length;
1678
1679 /* Length check. */
1680 if (length != 4) {
1681 flog_err(EC_BGP_ATTR_LEN,
1682 "MED attribute length isn't four [%d]", length);
1683
1684 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1685 args->total);
1686 }
1687
1688 attr->med = stream_getl(peer->curr);
1689
1690 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
1691
1692 return BGP_ATTR_PARSE_PROCEED;
1693 }
1694
1695 /* Local preference attribute. */
1696 static bgp_attr_parse_ret_t
1697 bgp_attr_local_pref(struct bgp_attr_parser_args *args)
1698 {
1699 struct peer *const peer = args->peer;
1700 struct attr *const attr = args->attr;
1701 const bgp_size_t length = args->length;
1702
1703 /* if received from an internal neighbor, it SHALL be considered
1704 * malformed if its length is not equal to 4. If malformed, the
1705 * UPDATE message SHALL be handled using the approach of "treat-as-
1706 * withdraw".
1707 */
1708 if (peer->sort == BGP_PEER_IBGP && length != 4) {
1709 flog_err(EC_BGP_ATTR_LEN,
1710 "LOCAL_PREF attribute length isn't 4 [%u]", length);
1711 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1712 args->total);
1713 }
1714
1715 /* If it is contained in an UPDATE message that is received from an
1716 external peer, then this attribute MUST be ignored by the
1717 receiving speaker. */
1718 if (peer->sort == BGP_PEER_EBGP) {
1719 STREAM_FORWARD_GETP(peer->curr, length);
1720 return BGP_ATTR_PARSE_PROCEED;
1721 }
1722
1723 STREAM_GETL(peer->curr, attr->local_pref);
1724
1725 /* Set the local-pref flag. */
1726 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1727
1728 return BGP_ATTR_PARSE_PROCEED;
1729
1730 stream_failure:
1731 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1732 args->total);
1733 }
1734
1735 /* Atomic aggregate. */
1736 static int bgp_attr_atomic(struct bgp_attr_parser_args *args)
1737 {
1738 struct attr *const attr = args->attr;
1739 const bgp_size_t length = args->length;
1740
1741 /* Length check. */
1742 if (length != 0) {
1743 flog_err(EC_BGP_ATTR_LEN,
1744 "ATOMIC_AGGREGATE attribute length isn't 0 [%u]",
1745 length);
1746 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1747 args->total);
1748 }
1749
1750 /* Set atomic aggregate flag. */
1751 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
1752
1753 return BGP_ATTR_PARSE_PROCEED;
1754 }
1755
1756 /* Aggregator attribute */
1757 static int bgp_attr_aggregator(struct bgp_attr_parser_args *args)
1758 {
1759 struct peer *const peer = args->peer;
1760 struct attr *const attr = args->attr;
1761 const bgp_size_t length = args->length;
1762 as_t aggregator_as;
1763
1764 int wantedlen = 6;
1765
1766 /* peer with AS4 will send 4 Byte AS, peer without will send 2 Byte */
1767 if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)
1768 && CHECK_FLAG(peer->cap, PEER_CAP_AS4_ADV))
1769 wantedlen = 8;
1770
1771 if (length != wantedlen) {
1772 flog_err(EC_BGP_ATTR_LEN,
1773 "AGGREGATOR attribute length isn't %u [%u]", wantedlen,
1774 length);
1775 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1776 args->total);
1777 }
1778
1779 if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV))
1780 aggregator_as = stream_getl(peer->curr);
1781 else
1782 aggregator_as = stream_getw(peer->curr);
1783
1784 attr->aggregator_as = aggregator_as;
1785 attr->aggregator_addr.s_addr = stream_get_ipv4(peer->curr);
1786
1787 /* Codification of AS 0 Processing */
1788 if (aggregator_as == BGP_AS_ZERO) {
1789 flog_err(EC_BGP_ATTR_LEN,
1790 "%s: AGGREGATOR AS number is 0 for aspath: %s",
1791 peer->host, aspath_print(attr->aspath));
1792
1793 if (bgp_debug_update(peer, NULL, NULL, 1)) {
1794 char attr_str[BUFSIZ] = {0};
1795
1796 bgp_dump_attr(attr, attr_str, sizeof(attr_str));
1797
1798 zlog_debug("%s: attributes: %s", __func__, attr_str);
1799 }
1800 } else {
1801 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR);
1802 }
1803
1804 return BGP_ATTR_PARSE_PROCEED;
1805 }
1806
1807 /* New Aggregator attribute */
1808 static bgp_attr_parse_ret_t
1809 bgp_attr_as4_aggregator(struct bgp_attr_parser_args *args,
1810 as_t *as4_aggregator_as,
1811 struct in_addr *as4_aggregator_addr)
1812 {
1813 struct peer *const peer = args->peer;
1814 struct attr *const attr = args->attr;
1815 const bgp_size_t length = args->length;
1816 as_t aggregator_as;
1817
1818 if (length != 8) {
1819 flog_err(EC_BGP_ATTR_LEN, "New Aggregator length is not 8 [%d]",
1820 length);
1821 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
1822 0);
1823 }
1824
1825 aggregator_as = stream_getl(peer->curr);
1826
1827 *as4_aggregator_as = aggregator_as;
1828 as4_aggregator_addr->s_addr = stream_get_ipv4(peer->curr);
1829
1830 /* Codification of AS 0 Processing */
1831 if (aggregator_as == BGP_AS_ZERO) {
1832 flog_err(EC_BGP_ATTR_LEN,
1833 "%s: AS4_AGGREGATOR AS number is 0 for aspath: %s",
1834 peer->host, aspath_print(attr->aspath));
1835
1836 if (bgp_debug_update(peer, NULL, NULL, 1)) {
1837 char attr_str[BUFSIZ] = {0};
1838
1839 bgp_dump_attr(attr, attr_str, sizeof(attr_str));
1840
1841 zlog_debug("%s: attributes: %s", __func__, attr_str);
1842 }
1843 } else {
1844 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AS4_AGGREGATOR);
1845 }
1846
1847 return BGP_ATTR_PARSE_PROCEED;
1848 }
1849
1850 /* Munge Aggregator and New-Aggregator, AS_PATH and NEW_AS_PATH.
1851 */
1852 static bgp_attr_parse_ret_t
1853 bgp_attr_munge_as4_attrs(struct peer *const peer, struct attr *const attr,
1854 struct aspath *as4_path, as_t as4_aggregator,
1855 struct in_addr *as4_aggregator_addr)
1856 {
1857 int ignore_as4_path = 0;
1858 struct aspath *newpath;
1859
1860 if (!attr->aspath) {
1861 /* NULL aspath shouldn't be possible as bgp_attr_parse should
1862 * have
1863 * checked that all well-known, mandatory attributes were
1864 * present.
1865 *
1866 * Can only be a problem with peer itself - hard error
1867 */
1868 return BGP_ATTR_PARSE_ERROR;
1869 }
1870
1871 if (CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)) {
1872 /* peer can do AS4, so we ignore AS4_PATH and AS4_AGGREGATOR
1873 * if given.
1874 * It is worth a warning though, because the peer really
1875 * should not send them
1876 */
1877 if (BGP_DEBUG(as4, AS4)) {
1878 if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS4_PATH)))
1879 zlog_debug("[AS4] %s %s AS4_PATH", peer->host,
1880 "AS4 capable peer, yet it sent");
1881
1882 if (attr->flag
1883 & (ATTR_FLAG_BIT(BGP_ATTR_AS4_AGGREGATOR)))
1884 zlog_debug("[AS4] %s %s AS4_AGGREGATOR",
1885 peer->host,
1886 "AS4 capable peer, yet it sent");
1887 }
1888
1889 return BGP_ATTR_PARSE_PROCEED;
1890 }
1891
1892 /* We have a asn16 peer. First, look for AS4_AGGREGATOR
1893 * because that may override AS4_PATH
1894 */
1895 if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS4_AGGREGATOR))) {
1896 if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
1897 /* received both.
1898 * if the as_number in aggregator is not AS_TRANS,
1899 * then AS4_AGGREGATOR and AS4_PATH shall be ignored
1900 * and the Aggregator shall be taken as
1901 * info on the aggregating node, and the AS_PATH
1902 * shall be taken as the AS_PATH
1903 * otherwise
1904 * the Aggregator shall be ignored and the
1905 * AS4_AGGREGATOR shall be taken as the
1906 * Aggregating node and the AS_PATH is to be
1907 * constructed "as in all other cases"
1908 */
1909 if (attr->aggregator_as != BGP_AS_TRANS) {
1910 /* ignore */
1911 if (BGP_DEBUG(as4, AS4))
1912 zlog_debug(
1913 "[AS4] %s BGP not AS4 capable peer send AGGREGATOR != AS_TRANS and AS4_AGGREGATOR, so ignore AS4_AGGREGATOR and AS4_PATH",
1914 peer->host);
1915 ignore_as4_path = 1;
1916 } else {
1917 /* "New_aggregator shall be taken as aggregator"
1918 */
1919 attr->aggregator_as = as4_aggregator;
1920 attr->aggregator_addr.s_addr =
1921 as4_aggregator_addr->s_addr;
1922 }
1923 } else {
1924 /* We received a AS4_AGGREGATOR but no AGGREGATOR.
1925 * That is bogus - but reading the conditions
1926 * we have to handle AS4_AGGREGATOR as if it were
1927 * AGGREGATOR in that case
1928 */
1929 if (BGP_DEBUG(as4, AS4))
1930 zlog_debug(
1931 "[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",
1932 peer->host);
1933 attr->aggregator_as = as4_aggregator;
1934 /* sweep it under the carpet and simulate a "good"
1935 * AGGREGATOR */
1936 attr->flag |= (ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR));
1937 }
1938 }
1939
1940 /* need to reconcile NEW_AS_PATH and AS_PATH */
1941 if (!ignore_as4_path
1942 && (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS4_PATH)))) {
1943 newpath = aspath_reconcile_as4(attr->aspath, as4_path);
1944 if (!newpath)
1945 return BGP_ATTR_PARSE_ERROR;
1946
1947 aspath_unintern(&attr->aspath);
1948 attr->aspath = aspath_intern(newpath);
1949 }
1950 return BGP_ATTR_PARSE_PROCEED;
1951 }
1952
1953 /* Community attribute. */
1954 static bgp_attr_parse_ret_t
1955 bgp_attr_community(struct bgp_attr_parser_args *args)
1956 {
1957 struct peer *const peer = args->peer;
1958 struct attr *const attr = args->attr;
1959 const bgp_size_t length = args->length;
1960
1961 if (length == 0) {
1962 attr->community = NULL;
1963 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
1964 args->total);
1965 }
1966
1967 attr->community =
1968 community_parse((uint32_t *)stream_pnt(peer->curr), length);
1969
1970 /* XXX: fix community_parse to use stream API and remove this */
1971 stream_forward_getp(peer->curr, length);
1972
1973 /* The Community attribute SHALL be considered malformed if its
1974 * length is not a non-zero multiple of 4.
1975 */
1976 if (!attr->community)
1977 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
1978 args->total);
1979
1980 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
1981
1982 return BGP_ATTR_PARSE_PROCEED;
1983 }
1984
1985 /* Originator ID attribute. */
1986 static bgp_attr_parse_ret_t
1987 bgp_attr_originator_id(struct bgp_attr_parser_args *args)
1988 {
1989 struct peer *const peer = args->peer;
1990 struct attr *const attr = args->attr;
1991 const bgp_size_t length = args->length;
1992
1993 /* if received from an internal neighbor, it SHALL be considered
1994 * malformed if its length is not equal to 4. If malformed, the
1995 * UPDATE message SHALL be handled using the approach of "treat-as-
1996 * withdraw".
1997 */
1998 if (length != 4) {
1999 flog_err(EC_BGP_ATTR_LEN, "Bad originator ID length %d",
2000 length);
2001
2002 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2003 args->total);
2004 }
2005
2006 attr->originator_id.s_addr = stream_get_ipv4(peer->curr);
2007
2008 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID);
2009
2010 return BGP_ATTR_PARSE_PROCEED;
2011 }
2012
2013 /* Cluster list attribute. */
2014 static bgp_attr_parse_ret_t
2015 bgp_attr_cluster_list(struct bgp_attr_parser_args *args)
2016 {
2017 struct peer *const peer = args->peer;
2018 struct attr *const attr = args->attr;
2019 const bgp_size_t length = args->length;
2020
2021 /* if received from an internal neighbor, it SHALL be considered
2022 * malformed if its length is not a non-zero multiple of 4. If
2023 * malformed, the UPDATE message SHALL be handled using the approach
2024 * of "treat-as-withdraw".
2025 */
2026 if (length == 0 || length % 4) {
2027 flog_err(EC_BGP_ATTR_LEN, "Bad cluster list length %d", length);
2028
2029 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2030 args->total);
2031 }
2032
2033 bgp_attr_set_cluster(
2034 attr, cluster_parse((struct in_addr *)stream_pnt(peer->curr),
2035 length));
2036
2037 /* XXX: Fix cluster_parse to use stream API and then remove this */
2038 stream_forward_getp(peer->curr, length);
2039
2040 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST);
2041
2042 return BGP_ATTR_PARSE_PROCEED;
2043 }
2044
2045 /* Multiprotocol reachability information parse. */
2046 int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
2047 struct bgp_nlri *mp_update)
2048 {
2049 iana_afi_t pkt_afi;
2050 afi_t afi;
2051 iana_safi_t pkt_safi;
2052 safi_t safi;
2053 bgp_size_t nlri_len;
2054 size_t start;
2055 struct stream *s;
2056 struct peer *const peer = args->peer;
2057 struct attr *const attr = args->attr;
2058 const bgp_size_t length = args->length;
2059
2060 /* Set end of packet. */
2061 s = BGP_INPUT(peer);
2062 start = stream_get_getp(s);
2063
2064 /* safe to read statically sized header? */
2065 #define BGP_MP_REACH_MIN_SIZE 5
2066 #define LEN_LEFT (length - (stream_get_getp(s) - start))
2067 if ((length > STREAM_READABLE(s)) || (length < BGP_MP_REACH_MIN_SIZE)) {
2068 zlog_info("%s: %s sent invalid length, %lu, of MP_REACH_NLRI",
2069 __func__, peer->host, (unsigned long)length);
2070 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2071 }
2072
2073 /* Load AFI, SAFI. */
2074 pkt_afi = stream_getw(s);
2075 pkt_safi = stream_getc(s);
2076
2077 /* Convert AFI, SAFI to internal values, check. */
2078 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
2079 /* Log if AFI or SAFI is unrecognized. This is not an error
2080 * unless
2081 * the attribute is otherwise malformed.
2082 */
2083 if (bgp_debug_update(peer, NULL, NULL, 0))
2084 zlog_debug(
2085 "%s sent unrecognizable AFI, %s or, SAFI, %s, of MP_REACH_NLRI",
2086 peer->host, iana_afi2str(pkt_afi),
2087 iana_safi2str(pkt_safi));
2088 return BGP_ATTR_PARSE_ERROR;
2089 }
2090
2091 /* Get nexthop length. */
2092 attr->mp_nexthop_len = stream_getc(s);
2093
2094 if (LEN_LEFT < attr->mp_nexthop_len) {
2095 zlog_info(
2096 "%s: %s sent next-hop length, %u, in MP_REACH_NLRI which goes past the end of attribute",
2097 __func__, peer->host, attr->mp_nexthop_len);
2098 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2099 }
2100
2101 /* Nexthop length check. */
2102 switch (attr->mp_nexthop_len) {
2103 case 0:
2104 if (safi != SAFI_FLOWSPEC) {
2105 zlog_info("%s: %s sent wrong next-hop length, %d, in MP_REACH_NLRI",
2106 __func__, peer->host, attr->mp_nexthop_len);
2107 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2108 }
2109 break;
2110 case BGP_ATTR_NHLEN_VPNV4:
2111 stream_getl(s); /* RD high */
2112 stream_getl(s); /* RD low */
2113 /*
2114 * NOTE: intentional fall through
2115 * - for consistency in rx processing
2116 *
2117 * The following comment is to signal GCC this intention
2118 * and suppress the warning
2119 */
2120 /* FALLTHRU */
2121 case BGP_ATTR_NHLEN_IPV4:
2122 stream_get(&attr->mp_nexthop_global_in, s, IPV4_MAX_BYTELEN);
2123 /* Probably needed for RFC 2283 */
2124 if (attr->nexthop.s_addr == INADDR_ANY)
2125 memcpy(&attr->nexthop.s_addr,
2126 &attr->mp_nexthop_global_in, IPV4_MAX_BYTELEN);
2127 break;
2128 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
2129 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
2130 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_VPNV6_GLOBAL) {
2131 stream_getl(s); /* RD high */
2132 stream_getl(s); /* RD low */
2133 }
2134 stream_get(&attr->mp_nexthop_global, s, IPV6_MAX_BYTELEN);
2135 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2136 if (!peer->nexthop.ifp) {
2137 zlog_warn("%s sent a v6 global attribute but address is a V6 LL and there's no peer interface information. Hence, withdrawing",
2138 peer->host);
2139 return BGP_ATTR_PARSE_WITHDRAW;
2140 }
2141 attr->nh_ifindex = peer->nexthop.ifp->ifindex;
2142 }
2143 break;
2144 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
2145 case BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL:
2146 if (attr->mp_nexthop_len
2147 == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) {
2148 stream_getl(s); /* RD high */
2149 stream_getl(s); /* RD low */
2150 }
2151 stream_get(&attr->mp_nexthop_global, s, IPV6_MAX_BYTELEN);
2152 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2153 if (!peer->nexthop.ifp) {
2154 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",
2155 peer->host);
2156 return BGP_ATTR_PARSE_WITHDRAW;
2157 }
2158 attr->nh_ifindex = peer->nexthop.ifp->ifindex;
2159 }
2160 if (attr->mp_nexthop_len
2161 == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) {
2162 stream_getl(s); /* RD high */
2163 stream_getl(s); /* RD low */
2164 }
2165 stream_get(&attr->mp_nexthop_local, s, IPV6_MAX_BYTELEN);
2166 if (!IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local)) {
2167 if (bgp_debug_update(peer, NULL, NULL, 1))
2168 zlog_debug(
2169 "%s sent next-hops %pI6 and %pI6. Ignoring non-LL value",
2170 peer->host, &attr->mp_nexthop_global,
2171 &attr->mp_nexthop_local);
2172
2173 attr->mp_nexthop_len = IPV6_MAX_BYTELEN;
2174 }
2175 if (!peer->nexthop.ifp) {
2176 zlog_warn("%s sent a v6 LL next-hop and there's no peer interface information. Hence, withdrawing",
2177 peer->host);
2178 return BGP_ATTR_PARSE_WITHDRAW;
2179 }
2180 attr->nh_lla_ifindex = peer->nexthop.ifp->ifindex;
2181 break;
2182 default:
2183 zlog_info("%s: %s sent wrong next-hop length, %d, in MP_REACH_NLRI",
2184 __func__, peer->host, attr->mp_nexthop_len);
2185 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2186 }
2187
2188 if (!LEN_LEFT) {
2189 zlog_info("%s: %s sent SNPA which couldn't be read",
2190 __func__, peer->host);
2191 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2192 }
2193
2194 {
2195 uint8_t val;
2196 if ((val = stream_getc(s)))
2197 flog_warn(
2198 EC_BGP_DEFUNCT_SNPA_LEN,
2199 "%s sent non-zero value, %u, for defunct SNPA-length field",
2200 peer->host, val);
2201 }
2202
2203 /* must have nrli_len, what is left of the attribute */
2204 nlri_len = LEN_LEFT;
2205 if (nlri_len > STREAM_READABLE(s)) {
2206 zlog_info("%s: %s sent MP_REACH_NLRI which couldn't be read",
2207 __func__, peer->host);
2208 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2209 }
2210
2211 if (!nlri_len) {
2212 zlog_info("%s: %s sent a zero-length NLRI. Hence, treating as a EOR marker",
2213 __func__, peer->host);
2214
2215 mp_update->afi = afi;
2216 mp_update->safi = safi;
2217 return BGP_ATTR_PARSE_EOR;
2218 }
2219
2220 mp_update->afi = afi;
2221 mp_update->safi = safi;
2222 mp_update->nlri = stream_pnt(s);
2223 mp_update->length = nlri_len;
2224
2225 stream_forward_getp(s, nlri_len);
2226
2227 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI);
2228
2229 return BGP_ATTR_PARSE_PROCEED;
2230 #undef LEN_LEFT
2231 }
2232
2233 /* Multiprotocol unreachable parse */
2234 int bgp_mp_unreach_parse(struct bgp_attr_parser_args *args,
2235 struct bgp_nlri *mp_withdraw)
2236 {
2237 struct stream *s;
2238 iana_afi_t pkt_afi;
2239 afi_t afi;
2240 iana_safi_t pkt_safi;
2241 safi_t safi;
2242 uint16_t withdraw_len;
2243 struct peer *const peer = args->peer;
2244 struct attr *const attr = args->attr;
2245 const bgp_size_t length = args->length;
2246
2247 s = peer->curr;
2248
2249 #define BGP_MP_UNREACH_MIN_SIZE 3
2250 if ((length > STREAM_READABLE(s)) || (length < BGP_MP_UNREACH_MIN_SIZE))
2251 return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
2252
2253 pkt_afi = stream_getw(s);
2254 pkt_safi = stream_getc(s);
2255
2256 /* Convert AFI, SAFI to internal values, check. */
2257 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
2258 /* Log if AFI or SAFI is unrecognized. This is not an error
2259 * unless
2260 * the attribute is otherwise malformed.
2261 */
2262 if (bgp_debug_update(peer, NULL, NULL, 0))
2263 zlog_debug(
2264 "%s: MP_UNREACH received AFI %s or SAFI %s is unrecognized",
2265 peer->host, iana_afi2str(pkt_afi),
2266 iana_safi2str(pkt_safi));
2267 return BGP_ATTR_PARSE_ERROR;
2268 }
2269
2270 withdraw_len = length - BGP_MP_UNREACH_MIN_SIZE;
2271
2272 mp_withdraw->afi = afi;
2273 mp_withdraw->safi = safi;
2274 mp_withdraw->nlri = stream_pnt(s);
2275 mp_withdraw->length = withdraw_len;
2276
2277 stream_forward_getp(s, withdraw_len);
2278
2279 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI);
2280
2281 return BGP_ATTR_PARSE_PROCEED;
2282 }
2283
2284 /* Large Community attribute. */
2285 static bgp_attr_parse_ret_t
2286 bgp_attr_large_community(struct bgp_attr_parser_args *args)
2287 {
2288 struct peer *const peer = args->peer;
2289 struct attr *const attr = args->attr;
2290 const bgp_size_t length = args->length;
2291
2292 /*
2293 * Large community follows new attribute format.
2294 */
2295 if (length == 0) {
2296 attr->lcommunity = NULL;
2297 /* Empty extcomm doesn't seem to be invalid per se */
2298 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2299 args->total);
2300 }
2301
2302 attr->lcommunity = lcommunity_parse(stream_pnt(peer->curr), length);
2303 /* XXX: fix ecommunity_parse to use stream API */
2304 stream_forward_getp(peer->curr, length);
2305
2306 if (!attr->lcommunity)
2307 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2308 args->total);
2309
2310 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES);
2311
2312 return BGP_ATTR_PARSE_PROCEED;
2313 }
2314
2315 /* Extended Community attribute. */
2316 static bgp_attr_parse_ret_t
2317 bgp_attr_ext_communities(struct bgp_attr_parser_args *args)
2318 {
2319 struct peer *const peer = args->peer;
2320 struct attr *const attr = args->attr;
2321 const bgp_size_t length = args->length;
2322 uint8_t sticky = 0;
2323 bool proxy = false;
2324
2325 if (length == 0) {
2326 attr->ecommunity = NULL;
2327 /* Empty extcomm doesn't seem to be invalid per se */
2328 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2329 args->total);
2330 }
2331
2332 attr->ecommunity = ecommunity_parse(
2333 stream_pnt(peer->curr), length,
2334 CHECK_FLAG(peer->flags,
2335 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE));
2336 /* XXX: fix ecommunity_parse to use stream API */
2337 stream_forward_getp(peer->curr, length);
2338
2339 /* The Extended Community attribute SHALL be considered malformed if
2340 * its length is not a non-zero multiple of 8.
2341 */
2342 if (!attr->ecommunity)
2343 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2344 args->total);
2345
2346 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
2347
2348 /* Extract DF election preference and mobility sequence number */
2349 attr->df_pref = bgp_attr_df_pref_from_ec(attr, &attr->df_alg);
2350
2351 /* Extract MAC mobility sequence number, if any. */
2352 attr->mm_seqnum = bgp_attr_mac_mobility_seqnum(attr, &sticky);
2353 attr->sticky = sticky;
2354
2355 /* Check if this is a Gateway MAC-IP advertisement */
2356 attr->default_gw = bgp_attr_default_gw(attr);
2357
2358 /* Handle scenario where router flag ecommunity is not
2359 * set but default gw ext community is present.
2360 * Use default gateway, set and propogate R-bit.
2361 */
2362 if (attr->default_gw)
2363 attr->router_flag = 1;
2364
2365 /* Check EVPN Neighbor advertisement flags, R-bit */
2366 bgp_attr_evpn_na_flag(attr, &attr->router_flag, &proxy);
2367 if (proxy)
2368 attr->es_flags |= ATTR_ES_PROXY_ADVERT;
2369
2370 /* Extract the Rmac, if any */
2371 if (bgp_attr_rmac(attr, &attr->rmac)) {
2372 if (bgp_debug_update(peer, NULL, NULL, 1)
2373 && bgp_mac_exist(&attr->rmac))
2374 zlog_debug("%s: router mac %pEA is self mac", __func__,
2375 &attr->rmac);
2376 }
2377
2378 /* Get the tunnel type from encap extended community */
2379 bgp_attr_extcom_tunnel_type(attr,
2380 (bgp_encap_types *)&attr->encap_tunneltype);
2381
2382 /* Extract link bandwidth, if any. */
2383 (void)ecommunity_linkbw_present(attr->ecommunity, &attr->link_bw);
2384
2385 return BGP_ATTR_PARSE_PROCEED;
2386 }
2387
2388 /* IPv6 Extended Community attribute. */
2389 static bgp_attr_parse_ret_t
2390 bgp_attr_ipv6_ext_communities(struct bgp_attr_parser_args *args)
2391 {
2392 struct peer *const peer = args->peer;
2393 struct attr *const attr = args->attr;
2394 const bgp_size_t length = args->length;
2395 struct ecommunity *ipv6_ecomm = NULL;
2396
2397 if (length == 0) {
2398 bgp_attr_set_ipv6_ecommunity(attr, ipv6_ecomm);
2399 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2400 args->total);
2401 }
2402
2403 ipv6_ecomm = ecommunity_parse_ipv6(
2404 stream_pnt(peer->curr), length,
2405 CHECK_FLAG(peer->flags,
2406 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE));
2407 bgp_attr_set_ipv6_ecommunity(attr, ipv6_ecomm);
2408
2409 /* XXX: fix ecommunity_parse to use stream API */
2410 stream_forward_getp(peer->curr, length);
2411
2412 if (!ipv6_ecomm)
2413 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2414 args->total);
2415
2416 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_IPV6_EXT_COMMUNITIES);
2417
2418 return BGP_ATTR_PARSE_PROCEED;
2419 }
2420
2421 /* Parse Tunnel Encap attribute in an UPDATE */
2422 static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */
2423 bgp_size_t length, /* IN: attr's length field */
2424 struct attr *attr, /* IN: caller already allocated */
2425 uint8_t flag, /* IN: attr's flags field */
2426 uint8_t *startp)
2427 {
2428 bgp_size_t total;
2429 uint16_t tunneltype = 0;
2430
2431 total = length + (CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
2432
2433 if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS)
2434 || !CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL)) {
2435 zlog_info(
2436 "Tunnel Encap attribute flag isn't optional and transitive %d",
2437 flag);
2438 bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR,
2439 BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
2440 startp, total);
2441 return -1;
2442 }
2443
2444 if (BGP_ATTR_ENCAP == type) {
2445 /* read outer TLV type and length */
2446 uint16_t tlv_length;
2447
2448 if (length < 4) {
2449 zlog_info(
2450 "Tunnel Encap attribute not long enough to contain outer T,L");
2451 bgp_notify_send_with_data(
2452 peer, BGP_NOTIFY_UPDATE_ERR,
2453 BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, startp, total);
2454 return -1;
2455 }
2456 tunneltype = stream_getw(BGP_INPUT(peer));
2457 tlv_length = stream_getw(BGP_INPUT(peer));
2458 length -= 4;
2459
2460 if (tlv_length != length) {
2461 zlog_info("%s: tlv_length(%d) != length(%d)",
2462 __func__, tlv_length, length);
2463 }
2464 }
2465
2466 while (length >= 4) {
2467 uint16_t subtype = 0;
2468 uint16_t sublength = 0;
2469 struct bgp_attr_encap_subtlv *tlv;
2470
2471 if (BGP_ATTR_ENCAP == type) {
2472 subtype = stream_getc(BGP_INPUT(peer));
2473 sublength = stream_getc(BGP_INPUT(peer));
2474 length -= 2;
2475 #ifdef ENABLE_BGP_VNC
2476 } else {
2477 subtype = stream_getw(BGP_INPUT(peer));
2478 sublength = stream_getw(BGP_INPUT(peer));
2479 length -= 4;
2480 #endif
2481 }
2482
2483 if (sublength > length) {
2484 zlog_info(
2485 "Tunnel Encap attribute sub-tlv length %d exceeds remaining length %d",
2486 sublength, length);
2487 bgp_notify_send_with_data(
2488 peer, BGP_NOTIFY_UPDATE_ERR,
2489 BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, startp, total);
2490 return -1;
2491 }
2492
2493 /* alloc and copy sub-tlv */
2494 /* TBD make sure these are freed when attributes are released */
2495 tlv = XCALLOC(MTYPE_ENCAP_TLV,
2496 sizeof(struct bgp_attr_encap_subtlv) + sublength);
2497 tlv->type = subtype;
2498 tlv->length = sublength;
2499 stream_get(tlv->value, peer->curr, sublength);
2500 length -= sublength;
2501
2502 /* attach tlv to encap chain */
2503 if (BGP_ATTR_ENCAP == type) {
2504 struct bgp_attr_encap_subtlv *stlv_last;
2505 for (stlv_last = attr->encap_subtlvs;
2506 stlv_last && stlv_last->next;
2507 stlv_last = stlv_last->next)
2508 ;
2509 if (stlv_last) {
2510 stlv_last->next = tlv;
2511 } else {
2512 attr->encap_subtlvs = tlv;
2513 }
2514 #ifdef ENABLE_BGP_VNC
2515 } else {
2516 struct bgp_attr_encap_subtlv *stlv_last;
2517 struct bgp_attr_encap_subtlv *vnc_subtlvs =
2518 bgp_attr_get_vnc_subtlvs(attr);
2519
2520 for (stlv_last = vnc_subtlvs;
2521 stlv_last && stlv_last->next;
2522 stlv_last = stlv_last->next)
2523 ;
2524 if (stlv_last)
2525 stlv_last->next = tlv;
2526 else
2527 bgp_attr_set_vnc_subtlvs(attr, tlv);
2528 #endif
2529 }
2530 }
2531
2532 if (BGP_ATTR_ENCAP == type) {
2533 attr->encap_tunneltype = tunneltype;
2534 }
2535
2536 if (length) {
2537 /* spurious leftover data */
2538 zlog_info(
2539 "Tunnel Encap attribute length is bad: %d leftover octets",
2540 length);
2541 bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR,
2542 BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2543 startp, total);
2544 return -1;
2545 }
2546
2547 return 0;
2548 }
2549
2550
2551 /* SRv6 Service Data Sub-Sub-TLV attribute
2552 * draft-ietf-bess-srv6-services-07
2553 */
2554 static bgp_attr_parse_ret_t
2555 bgp_attr_srv6_service_data(struct bgp_attr_parser_args *args)
2556 {
2557 struct peer *const peer = args->peer;
2558 struct attr *const attr = args->attr;
2559 uint8_t type, loc_block_len, loc_node_len, func_len, arg_len,
2560 transposition_len, transposition_offset;
2561 uint16_t length;
2562 size_t headersz = sizeof(type) + sizeof(length);
2563
2564 if (STREAM_READABLE(peer->curr) < headersz) {
2565 flog_err(
2566 EC_BGP_ATTR_LEN,
2567 "Malformed SRv6 Service Data Sub-Sub-TLV attribute - insufficent data (need %zu for attribute header, have %zu remaining in UPDATE)",
2568 headersz, STREAM_READABLE(peer->curr));
2569 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2570 args->total);
2571 }
2572
2573 type = stream_getc(peer->curr);
2574 length = stream_getw(peer->curr);
2575
2576 if (STREAM_READABLE(peer->curr) < length) {
2577 flog_err(
2578 EC_BGP_ATTR_LEN,
2579 "Malformed SRv6 Service Data Sub-Sub-TLV attribute - insufficent data (need %hu for attribute data, have %zu remaining in UPDATE)",
2580 length, STREAM_READABLE(peer->curr));
2581 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2582 args->total);
2583 }
2584
2585 if (type == BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_STRUCTURE) {
2586 loc_block_len = stream_getc(peer->curr);
2587 loc_node_len = stream_getc(peer->curr);
2588 func_len = stream_getc(peer->curr);
2589 arg_len = stream_getc(peer->curr);
2590 transposition_len = stream_getc(peer->curr);
2591 transposition_offset = stream_getc(peer->curr);
2592
2593 /* Log SRv6 Service Data Sub-Sub-TLV */
2594 if (BGP_DEBUG(vpn, VPN_LEAK_LABEL)) {
2595 zlog_debug(
2596 "%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",
2597 __func__, loc_block_len, loc_node_len, func_len,
2598 arg_len, transposition_len,
2599 transposition_offset);
2600 }
2601
2602 attr->srv6_l3vpn->loc_block_len = loc_block_len;
2603 attr->srv6_l3vpn->loc_node_len = loc_node_len;
2604 attr->srv6_l3vpn->func_len = func_len;
2605 attr->srv6_l3vpn->arg_len = arg_len;
2606 attr->srv6_l3vpn->transposition_len = transposition_len;
2607 attr->srv6_l3vpn->transposition_offset = transposition_offset;
2608 }
2609
2610 else {
2611 if (bgp_debug_update(peer, NULL, NULL, 1))
2612 zlog_debug(
2613 "%s attr SRv6 Service Data Sub-Sub-TLV sub-sub-type=%u is not supported, skipped",
2614 peer->host, type);
2615
2616 stream_forward_getp(peer->curr, length);
2617 }
2618
2619 return BGP_ATTR_PARSE_PROCEED;
2620 }
2621
2622 /* SRv6 Service Sub-TLV attribute
2623 * draft-ietf-bess-srv6-services-07
2624 */
2625 static bgp_attr_parse_ret_t
2626 bgp_attr_srv6_service(struct bgp_attr_parser_args *args)
2627 {
2628 struct peer *const peer = args->peer;
2629 struct attr *const attr = args->attr;
2630 struct in6_addr ipv6_sid;
2631 uint8_t type, sid_flags;
2632 uint16_t length, endpoint_behavior;
2633 size_t headersz = sizeof(type) + sizeof(length);
2634 bgp_attr_parse_ret_t err;
2635 char buf[BUFSIZ];
2636
2637 if (STREAM_READABLE(peer->curr) < headersz) {
2638 flog_err(
2639 EC_BGP_ATTR_LEN,
2640 "Malformed SRv6 Service Sub-TLV attribute - insufficent data (need %zu for attribute header, have %zu remaining in UPDATE)",
2641 headersz, STREAM_READABLE(peer->curr));
2642 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2643 args->total);
2644 }
2645
2646 type = stream_getc(peer->curr);
2647 length = stream_getw(peer->curr);
2648
2649 if (STREAM_READABLE(peer->curr) < length) {
2650 flog_err(
2651 EC_BGP_ATTR_LEN,
2652 "Malformed SRv6 Service Sub-TLV attribute - insufficent data (need %hu for attribute data, have %zu remaining in UPDATE)",
2653 length, STREAM_READABLE(peer->curr));
2654 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2655 args->total);
2656 }
2657
2658 if (type == BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_INFO) {
2659 stream_getc(peer->curr);
2660 stream_get(&ipv6_sid, peer->curr, sizeof(ipv6_sid));
2661 sid_flags = stream_getc(peer->curr);
2662 endpoint_behavior = stream_getw(peer->curr);
2663 stream_getc(peer->curr);
2664
2665 /* Log SRv6 Service Sub-TLV */
2666 if (BGP_DEBUG(vpn, VPN_LEAK_LABEL)) {
2667 inet_ntop(AF_INET6, &ipv6_sid, buf, sizeof(buf));
2668 zlog_debug(
2669 "%s: srv6-l3-srv sid %s, sid-flags 0x%02x, end-behaviour 0x%04x",
2670 __func__, buf, sid_flags, endpoint_behavior);
2671 }
2672
2673 /* Configure from Info */
2674 if (attr->srv6_l3vpn) {
2675 flog_err(EC_BGP_ATTRIBUTE_REPEATED,
2676 "Prefix SID SRv6 L3VPN field repeated");
2677 return bgp_attr_malformed(
2678 args, BGP_NOTIFY_UPDATE_MAL_ATTR, args->total);
2679 }
2680 attr->srv6_l3vpn = XCALLOC(MTYPE_BGP_SRV6_L3VPN,
2681 sizeof(struct bgp_attr_srv6_l3vpn));
2682 sid_copy(&attr->srv6_l3vpn->sid, &ipv6_sid);
2683 attr->srv6_l3vpn->sid_flags = sid_flags;
2684 attr->srv6_l3vpn->endpoint_behavior = endpoint_behavior;
2685 attr->srv6_l3vpn->loc_block_len = 0;
2686 attr->srv6_l3vpn->loc_node_len = 0;
2687 attr->srv6_l3vpn->func_len = 0;
2688 attr->srv6_l3vpn->arg_len = 0;
2689 attr->srv6_l3vpn->transposition_len = 0;
2690 attr->srv6_l3vpn->transposition_offset = 0;
2691
2692 // Sub-Sub-TLV found
2693 if (length > BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_INFO_LENGTH) {
2694 err = bgp_attr_srv6_service_data(args);
2695
2696 if (err != BGP_ATTR_PARSE_PROCEED)
2697 return err;
2698 }
2699
2700 attr->srv6_l3vpn = srv6_l3vpn_intern(attr->srv6_l3vpn);
2701 }
2702
2703 /* Placeholder code for unsupported type */
2704 else {
2705 if (bgp_debug_update(peer, NULL, NULL, 1))
2706 zlog_debug(
2707 "%s attr SRv6 Service Sub-TLV sub-type=%u is not supported, skipped",
2708 peer->host, type);
2709
2710 stream_forward_getp(peer->curr, length);
2711 }
2712
2713 return BGP_ATTR_PARSE_PROCEED;
2714 }
2715
2716 /*
2717 * Read an individual SID value returning how much data we have read
2718 * Returns 0 if there was an error that needs to be passed up the stack
2719 */
2720 static bgp_attr_parse_ret_t bgp_attr_psid_sub(uint8_t type, uint16_t length,
2721 struct bgp_attr_parser_args *args)
2722 {
2723 struct peer *const peer = args->peer;
2724 struct attr *const attr = args->attr;
2725 uint32_t label_index;
2726 struct in6_addr ipv6_sid;
2727 uint32_t srgb_base;
2728 uint32_t srgb_range;
2729 int srgb_count;
2730 uint8_t sid_type, sid_flags;
2731 char buf[BUFSIZ];
2732
2733 if (type == BGP_PREFIX_SID_LABEL_INDEX) {
2734 if (STREAM_READABLE(peer->curr) < length
2735 || length != BGP_PREFIX_SID_LABEL_INDEX_LENGTH) {
2736 flog_err(EC_BGP_ATTR_LEN,
2737 "Prefix SID label index length is %hu instead of %u",
2738 length, BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
2739 return bgp_attr_malformed(args,
2740 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2741 args->total);
2742 }
2743
2744 /* Ignore flags and reserved */
2745 stream_getc(peer->curr);
2746 stream_getw(peer->curr);
2747
2748 /* Fetch the label index and see if it is valid. */
2749 label_index = stream_getl(peer->curr);
2750 if (label_index == BGP_INVALID_LABEL_INDEX)
2751 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
2752 args->total);
2753
2754 /* Store label index; subsequently, we'll check on
2755 * address-family */
2756 attr->label_index = label_index;
2757 }
2758
2759 /* Placeholder code for the IPv6 SID type */
2760 else if (type == BGP_PREFIX_SID_IPV6) {
2761 if (STREAM_READABLE(peer->curr) < length
2762 || length != BGP_PREFIX_SID_IPV6_LENGTH) {
2763 flog_err(EC_BGP_ATTR_LEN,
2764 "Prefix SID IPv6 length is %hu instead of %u",
2765 length, BGP_PREFIX_SID_IPV6_LENGTH);
2766 return bgp_attr_malformed(args,
2767 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2768 args->total);
2769 }
2770
2771 /* Ignore reserved */
2772 stream_getc(peer->curr);
2773 stream_getw(peer->curr);
2774
2775 stream_get(&ipv6_sid, peer->curr, 16);
2776 }
2777
2778 /* Placeholder code for the Originator SRGB type */
2779 else if (type == BGP_PREFIX_SID_ORIGINATOR_SRGB) {
2780 /*
2781 * ietf-idr-bgp-prefix-sid-05:
2782 * Length is the total length of the value portion of the
2783 * TLV: 2 + multiple of 6.
2784 *
2785 * peer->curr stream readp should be at the beginning of the 16
2786 * bit flag field at this point in the code.
2787 */
2788
2789 /*
2790 * Check that the TLV length field is sane: at least 2 bytes of
2791 * flag, and at least 1 SRGB (these are 6 bytes each)
2792 */
2793 if (length < (2 + BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH)) {
2794 flog_err(
2795 EC_BGP_ATTR_LEN,
2796 "Prefix SID Originator SRGB length field claims length of %hu bytes, but the minimum for this TLV type is %u",
2797 length,
2798 2 + BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH);
2799 return bgp_attr_malformed(
2800 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2801 args->total);
2802 }
2803
2804 /*
2805 * Check that we actually have at least as much data as
2806 * specified by the length field
2807 */
2808 if (STREAM_READABLE(peer->curr) < length) {
2809 flog_err(EC_BGP_ATTR_LEN,
2810 "Prefix SID Originator SRGB specifies length %hu, but only %zu bytes remain",
2811 length, STREAM_READABLE(peer->curr));
2812 return bgp_attr_malformed(
2813 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2814 args->total);
2815 }
2816
2817 /*
2818 * Check that the portion of the TLV containing the sequence of
2819 * SRGBs corresponds to a multiple of the SRGB size; to get
2820 * that length, we skip the 16 bit flags field
2821 */
2822 stream_getw(peer->curr);
2823 length -= 2;
2824 if (length % BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH) {
2825 flog_err(
2826 EC_BGP_ATTR_LEN,
2827 "Prefix SID Originator SRGB length field claims attribute SRGB sequence section is %hubytes, but it must be a multiple of %u",
2828 length, BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH);
2829 return bgp_attr_malformed(
2830 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2831 args->total);
2832 }
2833
2834 srgb_count = length / BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH;
2835
2836 for (int i = 0; i < srgb_count; i++) {
2837 stream_get(&srgb_base, peer->curr, 3);
2838 stream_get(&srgb_range, peer->curr, 3);
2839 }
2840 }
2841
2842 /* Placeholder code for the VPN-SID Service type */
2843 else if (type == BGP_PREFIX_SID_VPN_SID) {
2844 if (STREAM_READABLE(peer->curr) < length
2845 || length != BGP_PREFIX_SID_VPN_SID_LENGTH) {
2846 flog_err(EC_BGP_ATTR_LEN,
2847 "Prefix SID VPN SID length is %hu instead of %u",
2848 length, BGP_PREFIX_SID_VPN_SID_LENGTH);
2849 return bgp_attr_malformed(args,
2850 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2851 args->total);
2852 }
2853
2854 /* Parse VPN-SID Sub-TLV */
2855 stream_getc(peer->curr); /* reserved */
2856 sid_type = stream_getc(peer->curr); /* sid_type */
2857 sid_flags = stream_getc(peer->curr); /* sid_flags */
2858 stream_get(&ipv6_sid, peer->curr,
2859 sizeof(ipv6_sid)); /* sid_value */
2860
2861 /* Log VPN-SID Sub-TLV */
2862 if (BGP_DEBUG(vpn, VPN_LEAK_LABEL)) {
2863 inet_ntop(AF_INET6, &ipv6_sid, buf, sizeof(buf));
2864 zlog_debug(
2865 "%s: vpn-sid: sid %s, sid-type 0x%02x sid-flags 0x%02x",
2866 __func__, buf, sid_type, sid_flags);
2867 }
2868
2869 /* Configure from Info */
2870 if (attr->srv6_vpn) {
2871 flog_err(EC_BGP_ATTRIBUTE_REPEATED,
2872 "Prefix SID SRv6 VPN field repeated");
2873 return bgp_attr_malformed(
2874 args, BGP_NOTIFY_UPDATE_MAL_ATTR, args->total);
2875 }
2876 attr->srv6_vpn = XCALLOC(MTYPE_BGP_SRV6_VPN,
2877 sizeof(struct bgp_attr_srv6_vpn));
2878 attr->srv6_vpn->sid_flags = sid_flags;
2879 sid_copy(&attr->srv6_vpn->sid, &ipv6_sid);
2880 attr->srv6_vpn = srv6_vpn_intern(attr->srv6_vpn);
2881 }
2882
2883 /* Placeholder code for the SRv6 L3 Service type */
2884 else if (type == BGP_PREFIX_SID_SRV6_L3_SERVICE) {
2885 if (STREAM_READABLE(peer->curr) < length) {
2886 flog_err(
2887 EC_BGP_ATTR_LEN,
2888 "Prefix SID SRv6 L3-Service length is %hu, but only %zu bytes remain",
2889 length, STREAM_READABLE(peer->curr));
2890 return bgp_attr_malformed(args,
2891 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2892 args->total);
2893 }
2894
2895 /* ignore reserved */
2896 stream_getc(peer->curr);
2897
2898 return bgp_attr_srv6_service(args);
2899 }
2900
2901 /* Placeholder code for Unsupported TLV */
2902 else {
2903
2904 if (STREAM_READABLE(peer->curr) < length) {
2905 flog_err(
2906 EC_BGP_ATTR_LEN,
2907 "Prefix SID SRv6 length is %hu - too long, only %zu remaining in this UPDATE",
2908 length, STREAM_READABLE(peer->curr));
2909 return bgp_attr_malformed(
2910 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2911 args->total);
2912 }
2913
2914 if (bgp_debug_update(peer, NULL, NULL, 1))
2915 zlog_debug(
2916 "%s attr Prefix-SID sub-type=%u is not supported, skipped",
2917 peer->host, type);
2918
2919 stream_forward_getp(peer->curr, length);
2920 }
2921
2922 return BGP_ATTR_PARSE_PROCEED;
2923 }
2924
2925 /* Prefix SID attribute
2926 * draft-ietf-idr-bgp-prefix-sid-05
2927 */
2928 bgp_attr_parse_ret_t bgp_attr_prefix_sid(struct bgp_attr_parser_args *args)
2929 {
2930 struct peer *const peer = args->peer;
2931 struct attr *const attr = args->attr;
2932 bgp_attr_parse_ret_t ret;
2933
2934 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
2935
2936 uint8_t type;
2937 uint16_t length;
2938 size_t headersz = sizeof(type) + sizeof(length);
2939 size_t psid_parsed_length = 0;
2940
2941 while (STREAM_READABLE(peer->curr) > 0
2942 && psid_parsed_length < args->length) {
2943
2944 if (STREAM_READABLE(peer->curr) < headersz) {
2945 flog_err(
2946 EC_BGP_ATTR_LEN,
2947 "Malformed Prefix SID attribute - insufficent data (need %zu for attribute header, have %zu remaining in UPDATE)",
2948 headersz, STREAM_READABLE(peer->curr));
2949 return bgp_attr_malformed(
2950 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2951 args->total);
2952 }
2953
2954 type = stream_getc(peer->curr);
2955 length = stream_getw(peer->curr);
2956
2957 if (STREAM_READABLE(peer->curr) < length) {
2958 flog_err(
2959 EC_BGP_ATTR_LEN,
2960 "Malformed Prefix SID attribute - insufficient data (need %hu for attribute body, have %zu remaining in UPDATE)",
2961 length, STREAM_READABLE(peer->curr));
2962 return bgp_attr_malformed(args,
2963 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2964 args->total);
2965 }
2966
2967 ret = bgp_attr_psid_sub(type, length, args);
2968
2969 if (ret != BGP_ATTR_PARSE_PROCEED)
2970 return ret;
2971
2972 psid_parsed_length += length + headersz;
2973
2974 if (psid_parsed_length > args->length) {
2975 flog_err(
2976 EC_BGP_ATTR_LEN,
2977 "Malformed Prefix SID attribute - TLV overflow by attribute (need %zu for TLV length, have %zu overflowed in UPDATE)",
2978 length + headersz, psid_parsed_length - (length + headersz));
2979 return bgp_attr_malformed(
2980 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
2981 args->total);
2982 }
2983 }
2984
2985 return BGP_ATTR_PARSE_PROCEED;
2986 }
2987
2988 /* PMSI tunnel attribute (RFC 6514)
2989 * Basic validation checks done here.
2990 */
2991 static bgp_attr_parse_ret_t
2992 bgp_attr_pmsi_tunnel(struct bgp_attr_parser_args *args)
2993 {
2994 struct peer *const peer = args->peer;
2995 struct attr *const attr = args->attr;
2996 const bgp_size_t length = args->length;
2997 uint8_t tnl_type;
2998 int attr_parse_len = 2 + BGP_LABEL_BYTES;
2999
3000 /* Verify that the receiver is expecting "ingress replication" as we
3001 * can only support that.
3002 */
3003 if (length < attr_parse_len) {
3004 flog_err(EC_BGP_ATTR_LEN, "Bad PMSI tunnel attribute length %d",
3005 length);
3006 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3007 args->total);
3008 }
3009 stream_getc(peer->curr); /* Flags */
3010 tnl_type = stream_getc(peer->curr);
3011 if (tnl_type > PMSI_TNLTYPE_MAX) {
3012 flog_err(EC_BGP_ATTR_PMSI_TYPE,
3013 "Invalid PMSI tunnel attribute type %d", tnl_type);
3014 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
3015 args->total);
3016 }
3017 if (tnl_type == PMSI_TNLTYPE_INGR_REPL) {
3018 if (length != 9) {
3019 flog_err(EC_BGP_ATTR_PMSI_LEN,
3020 "Bad PMSI tunnel attribute length %d for IR",
3021 length);
3022 return bgp_attr_malformed(
3023 args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
3024 args->total);
3025 }
3026 }
3027
3028 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL);
3029 bgp_attr_set_pmsi_tnl_type(attr, tnl_type);
3030 stream_get(&attr->label, peer->curr, BGP_LABEL_BYTES);
3031
3032 /* Forward read pointer of input stream. */
3033 stream_forward_getp(peer->curr, length - attr_parse_len);
3034
3035 return BGP_ATTR_PARSE_PROCEED;
3036 }
3037
3038 /* BGP unknown attribute treatment. */
3039 static bgp_attr_parse_ret_t bgp_attr_unknown(struct bgp_attr_parser_args *args)
3040 {
3041 bgp_size_t total = args->total;
3042 struct transit *transit;
3043 struct peer *const peer = args->peer;
3044 struct attr *const attr = args->attr;
3045 uint8_t *const startp = args->startp;
3046 const uint8_t type = args->type;
3047 const uint8_t flag = args->flags;
3048 const bgp_size_t length = args->length;
3049
3050 if (bgp_debug_update(peer, NULL, NULL, 1))
3051 zlog_debug(
3052 "%s Unknown attribute is received (type %d, length %d)",
3053 peer->host, type, length);
3054
3055 /* Forward read pointer of input stream. */
3056 stream_forward_getp(peer->curr, length);
3057
3058 /* If any of the mandatory well-known attributes are not recognized,
3059 then the Error Subcode is set to Unrecognized Well-known
3060 Attribute. The Data field contains the unrecognized attribute
3061 (type, length and value). */
3062 if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL)) {
3063 return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_UNREC_ATTR,
3064 args->total);
3065 }
3066
3067 /* Unrecognized non-transitive optional attributes must be quietly
3068 ignored and not passed along to other BGP peers. */
3069 if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS))
3070 return BGP_ATTR_PARSE_PROCEED;
3071
3072 /* If a path with recognized transitive optional attribute is
3073 accepted and passed along to other BGP peers and the Partial bit
3074 in the Attribute Flags octet is set to 1 by some previous AS, it
3075 is not set back to 0 by the current AS. */
3076 SET_FLAG(*startp, BGP_ATTR_FLAG_PARTIAL);
3077
3078 /* Store transitive attribute to the end of attr->transit. */
3079 transit = bgp_attr_get_transit(attr);
3080 if (!transit)
3081 transit = XCALLOC(MTYPE_TRANSIT, sizeof(struct transit));
3082
3083 transit->val = XREALLOC(MTYPE_TRANSIT_VAL, transit->val,
3084 transit->length + total);
3085
3086 memcpy(transit->val + transit->length, startp, total);
3087 transit->length += total;
3088 bgp_attr_set_transit(attr, transit);
3089
3090 return BGP_ATTR_PARSE_PROCEED;
3091 }
3092
3093 /* Well-known attribute check. */
3094 static int bgp_attr_check(struct peer *peer, struct attr *attr)
3095 {
3096 uint8_t type = 0;
3097
3098 /* BGP Graceful-Restart End-of-RIB for IPv4 unicast is signaled as an
3099 * empty UPDATE. */
3100 if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV) && !attr->flag)
3101 return BGP_ATTR_PARSE_PROCEED;
3102
3103 /* "An UPDATE message that contains the MP_UNREACH_NLRI is not required
3104 to carry any other path attributes.", though if MP_REACH_NLRI or NLRI
3105 are present, it should. Check for any other attribute being present
3106 instead.
3107 */
3108 if ((!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI)) &&
3109 CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI))))
3110 return BGP_ATTR_PARSE_PROCEED;
3111
3112 if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGIN)))
3113 type = BGP_ATTR_ORIGIN;
3114
3115 if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AS_PATH)))
3116 type = BGP_ATTR_AS_PATH;
3117
3118 /* RFC 2858 makes Next-Hop optional/ignored, if MP_REACH_NLRI is present
3119 * and
3120 * NLRI is empty. We can't easily check NLRI empty here though.
3121 */
3122 if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP))
3123 && !CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI)))
3124 type = BGP_ATTR_NEXT_HOP;
3125
3126 if (peer->sort == BGP_PEER_IBGP
3127 && !CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))
3128 type = BGP_ATTR_LOCAL_PREF;
3129
3130 /* If any of the well-known mandatory attributes are not present
3131 * in an UPDATE message, then "treat-as-withdraw" MUST be used.
3132 */
3133 if (type) {
3134 flog_warn(EC_BGP_MISSING_ATTRIBUTE,
3135 "%s Missing well-known attribute %s.", peer->host,
3136 lookup_msg(attr_str, type, NULL));
3137 return BGP_ATTR_PARSE_WITHDRAW;
3138 }
3139 return BGP_ATTR_PARSE_PROCEED;
3140 }
3141
3142 /* Read attribute of update packet. This function is called from
3143 bgp_update_receive() in bgp_packet.c. */
3144 bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr,
3145 bgp_size_t size, struct bgp_nlri *mp_update,
3146 struct bgp_nlri *mp_withdraw)
3147 {
3148 bgp_attr_parse_ret_t ret;
3149 uint8_t flag = 0;
3150 uint8_t type = 0;
3151 bgp_size_t length;
3152 uint8_t *startp, *endp;
3153 uint8_t *attr_endp;
3154 uint8_t seen[BGP_ATTR_BITMAP_SIZE];
3155 /* we need the as4_path only until we have synthesized the as_path with
3156 * it */
3157 /* same goes for as4_aggregator */
3158 struct aspath *as4_path = NULL;
3159 as_t as4_aggregator = 0;
3160 struct in_addr as4_aggregator_addr = {.s_addr = 0};
3161 struct transit *transit;
3162
3163 /* Initialize bitmap. */
3164 memset(seen, 0, BGP_ATTR_BITMAP_SIZE);
3165
3166 /* End pointer of BGP attribute. */
3167 endp = BGP_INPUT_PNT(peer) + size;
3168
3169 /* Get attributes to the end of attribute length. */
3170 while (BGP_INPUT_PNT(peer) < endp) {
3171 /* Check remaining length check.*/
3172 if (endp - BGP_INPUT_PNT(peer) < BGP_ATTR_MIN_LEN) {
3173 /* XXX warning: long int format, int arg (arg 5) */
3174 flog_warn(
3175 EC_BGP_ATTRIBUTE_TOO_SMALL,
3176 "%s: error BGP attribute length %lu is smaller than min len",
3177 peer->host,
3178 (unsigned long)(endp
3179 - stream_pnt(BGP_INPUT(peer))));
3180
3181 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3182 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
3183 ret = BGP_ATTR_PARSE_ERROR;
3184 goto done;
3185 }
3186
3187 /* Fetch attribute flag and type. */
3188 startp = BGP_INPUT_PNT(peer);
3189 /* "The lower-order four bits of the Attribute Flags octet are
3190 unused. They MUST be zero when sent and MUST be ignored when
3191 received." */
3192 flag = 0xF0 & stream_getc(BGP_INPUT(peer));
3193 type = stream_getc(BGP_INPUT(peer));
3194
3195 /* Check whether Extended-Length applies and is in bounds */
3196 if (CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN)
3197 && ((endp - startp) < (BGP_ATTR_MIN_LEN + 1))) {
3198 flog_warn(
3199 EC_BGP_EXT_ATTRIBUTE_TOO_SMALL,
3200 "%s: Extended length set, but just %lu bytes of attr header",
3201 peer->host,
3202 (unsigned long)(endp
3203 - stream_pnt(BGP_INPUT(peer))));
3204
3205 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3206 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
3207 ret = BGP_ATTR_PARSE_ERROR;
3208 goto done;
3209 }
3210
3211 /* Check extended attribue length bit. */
3212 if (CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN))
3213 length = stream_getw(BGP_INPUT(peer));
3214 else
3215 length = stream_getc(BGP_INPUT(peer));
3216
3217 /* If any attribute appears more than once in the UPDATE
3218 message, then the Error Subcode is set to Malformed Attribute
3219 List. */
3220
3221 if (CHECK_BITMAP(seen, type)) {
3222 flog_warn(
3223 EC_BGP_ATTRIBUTE_REPEATED,
3224 "%s: error BGP attribute type %d appears twice in a message",
3225 peer->host, type);
3226
3227 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3228 BGP_NOTIFY_UPDATE_MAL_ATTR);
3229 ret = BGP_ATTR_PARSE_ERROR;
3230 goto done;
3231 }
3232
3233 /* Set type to bitmap to check duplicate attribute. `type' is
3234 unsigned char so it never overflow bitmap range. */
3235
3236 SET_BITMAP(seen, type);
3237
3238 /* Overflow check. */
3239 attr_endp = BGP_INPUT_PNT(peer) + length;
3240
3241 if (attr_endp > endp) {
3242 flog_warn(
3243 EC_BGP_ATTRIBUTE_TOO_LARGE,
3244 "%s: BGP type %d length %d is too large, attribute total length is %d. attr_endp is %p. endp is %p",
3245 peer->host, type, length, size, attr_endp,
3246 endp);
3247 /*
3248 * RFC 4271 6.3
3249 * If any recognized attribute has an Attribute
3250 * Length that conflicts with the expected length
3251 * (based on the attribute type code), then the
3252 * Error Subcode MUST be set to Attribute Length
3253 * Error. The Data field MUST contain the erroneous
3254 * attribute (type, length, and value).
3255 * ----------
3256 * We do not currently have a good way to determine the
3257 * length of the attribute independent of the length
3258 * received in the message. Instead we send the
3259 * minimum between the amount of data we have and the
3260 * amount specified by the attribute length field.
3261 *
3262 * Instead of directly passing in the packet buffer and
3263 * offset we use the stream_get* functions to read into
3264 * a stack buffer, since they perform bounds checking
3265 * and we are working with untrusted data.
3266 */
3267 unsigned char ndata[peer->max_packet_size];
3268 memset(ndata, 0x00, sizeof(ndata));
3269 size_t lfl =
3270 CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN) ? 2 : 1;
3271 /* Rewind to end of flag field */
3272 stream_rewind_getp(BGP_INPUT(peer), (1 + lfl));
3273 /* Type */
3274 stream_get(&ndata[0], BGP_INPUT(peer), 1);
3275 /* Length */
3276 stream_get(&ndata[1], BGP_INPUT(peer), lfl);
3277 /* Value */
3278 size_t atl = attr_endp - startp;
3279 size_t ndl = MIN(atl, STREAM_READABLE(BGP_INPUT(peer)));
3280 stream_get(&ndata[lfl + 1], BGP_INPUT(peer), ndl);
3281
3282 bgp_notify_send_with_data(
3283 peer, BGP_NOTIFY_UPDATE_ERR,
3284 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, ndata,
3285 ndl + lfl + 1);
3286
3287 ret = BGP_ATTR_PARSE_ERROR;
3288 goto done;
3289 }
3290
3291 struct bgp_attr_parser_args attr_args = {
3292 .peer = peer,
3293 .length = length,
3294 .attr = attr,
3295 .type = type,
3296 .flags = flag,
3297 .startp = startp,
3298 .total = attr_endp - startp,
3299 };
3300
3301
3302 /* If any recognized attribute has Attribute Flags that conflict
3303 with the Attribute Type Code, then the Error Subcode is set
3304 to
3305 Attribute Flags Error. The Data field contains the erroneous
3306 attribute (type, length and value). */
3307 if (bgp_attr_flag_invalid(&attr_args)) {
3308 ret = bgp_attr_malformed(
3309 &attr_args, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
3310 attr_args.total);
3311 if (ret == BGP_ATTR_PARSE_PROCEED)
3312 continue;
3313 goto done;
3314 }
3315
3316 /* OK check attribute and store it's value. */
3317 switch (type) {
3318 case BGP_ATTR_ORIGIN:
3319 ret = bgp_attr_origin(&attr_args);
3320 break;
3321 case BGP_ATTR_AS_PATH:
3322 ret = bgp_attr_aspath(&attr_args);
3323 break;
3324 case BGP_ATTR_AS4_PATH:
3325 ret = bgp_attr_as4_path(&attr_args, &as4_path);
3326 break;
3327 case BGP_ATTR_NEXT_HOP:
3328 ret = bgp_attr_nexthop(&attr_args);
3329 break;
3330 case BGP_ATTR_MULTI_EXIT_DISC:
3331 ret = bgp_attr_med(&attr_args);
3332 break;
3333 case BGP_ATTR_LOCAL_PREF:
3334 ret = bgp_attr_local_pref(&attr_args);
3335 break;
3336 case BGP_ATTR_ATOMIC_AGGREGATE:
3337 ret = bgp_attr_atomic(&attr_args);
3338 break;
3339 case BGP_ATTR_AGGREGATOR:
3340 ret = bgp_attr_aggregator(&attr_args);
3341 break;
3342 case BGP_ATTR_AS4_AGGREGATOR:
3343 ret = bgp_attr_as4_aggregator(&attr_args,
3344 &as4_aggregator,
3345 &as4_aggregator_addr);
3346 break;
3347 case BGP_ATTR_COMMUNITIES:
3348 ret = bgp_attr_community(&attr_args);
3349 break;
3350 case BGP_ATTR_LARGE_COMMUNITIES:
3351 ret = bgp_attr_large_community(&attr_args);
3352 break;
3353 case BGP_ATTR_ORIGINATOR_ID:
3354 ret = bgp_attr_originator_id(&attr_args);
3355 break;
3356 case BGP_ATTR_CLUSTER_LIST:
3357 ret = bgp_attr_cluster_list(&attr_args);
3358 break;
3359 case BGP_ATTR_MP_REACH_NLRI:
3360 ret = bgp_mp_reach_parse(&attr_args, mp_update);
3361 break;
3362 case BGP_ATTR_MP_UNREACH_NLRI:
3363 ret = bgp_mp_unreach_parse(&attr_args, mp_withdraw);
3364 break;
3365 case BGP_ATTR_EXT_COMMUNITIES:
3366 ret = bgp_attr_ext_communities(&attr_args);
3367 break;
3368 #ifdef ENABLE_BGP_VNC_ATTR
3369 case BGP_ATTR_VNC:
3370 #endif
3371 case BGP_ATTR_ENCAP:
3372 ret = bgp_attr_encap(type, peer, length, attr, flag,
3373 startp);
3374 break;
3375 case BGP_ATTR_PREFIX_SID:
3376 ret = bgp_attr_prefix_sid(&attr_args);
3377 break;
3378 case BGP_ATTR_PMSI_TUNNEL:
3379 ret = bgp_attr_pmsi_tunnel(&attr_args);
3380 break;
3381 case BGP_ATTR_IPV6_EXT_COMMUNITIES:
3382 ret = bgp_attr_ipv6_ext_communities(&attr_args);
3383 break;
3384 default:
3385 ret = bgp_attr_unknown(&attr_args);
3386 break;
3387 }
3388
3389 if (ret == BGP_ATTR_PARSE_ERROR_NOTIFYPLS) {
3390 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3391 BGP_NOTIFY_UPDATE_MAL_ATTR);
3392 ret = BGP_ATTR_PARSE_ERROR;
3393 goto done;
3394 }
3395
3396 if (ret == BGP_ATTR_PARSE_EOR) {
3397 goto done;
3398 }
3399
3400 if (ret == BGP_ATTR_PARSE_ERROR) {
3401 flog_warn(EC_BGP_ATTRIBUTE_PARSE_ERROR,
3402 "%s: Attribute %s, parse error", peer->host,
3403 lookup_msg(attr_str, type, NULL));
3404 goto done;
3405 }
3406 if (ret == BGP_ATTR_PARSE_WITHDRAW) {
3407 flog_warn(
3408 EC_BGP_ATTRIBUTE_PARSE_WITHDRAW,
3409 "%s: Attribute %s, parse error - treating as withdrawal",
3410 peer->host, lookup_msg(attr_str, type, NULL));
3411 goto done;
3412 }
3413
3414 /* Check the fetched length. */
3415 if (BGP_INPUT_PNT(peer) != attr_endp) {
3416 flog_warn(EC_BGP_ATTRIBUTE_FETCH_ERROR,
3417 "%s: BGP attribute %s, fetch error",
3418 peer->host, lookup_msg(attr_str, type, NULL));
3419 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3420 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
3421 ret = BGP_ATTR_PARSE_ERROR;
3422 goto done;
3423 }
3424 }
3425
3426 /*
3427 * draft-ietf-idr-bgp-prefix-sid-27#section-3:
3428 * About Prefix-SID path attribute,
3429 * Label-Index TLV(type1) and The Originator SRGB TLV(type-3)
3430 * may only appear in a BGP Prefix-SID attribute attached to
3431 * IPv4/IPv6 Labeled Unicast prefixes ([RFC8277]).
3432 * It MUST be ignored when received for other BGP AFI/SAFI combinations.
3433 */
3434 if (!attr->mp_nexthop_len || mp_update->safi != SAFI_LABELED_UNICAST)
3435 attr->label_index = BGP_INVALID_LABEL_INDEX;
3436
3437 /* Check final read pointer is same as end pointer. */
3438 if (BGP_INPUT_PNT(peer) != endp) {
3439 flog_warn(EC_BGP_ATTRIBUTES_MISMATCH,
3440 "%s: BGP attribute %s, length mismatch", peer->host,
3441 lookup_msg(attr_str, type, NULL));
3442 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3443 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
3444
3445 ret = BGP_ATTR_PARSE_ERROR;
3446 goto done;
3447 }
3448
3449 /*
3450 * RFC4271: If the NEXT_HOP attribute field is syntactically incorrect,
3451 * then the Error Subcode MUST be set to Invalid NEXT_HOP Attribute.
3452 * This is implemented below and will result in a NOTIFICATION. If the
3453 * NEXT_HOP attribute is semantically incorrect, the error SHOULD be
3454 * logged, and the route SHOULD be ignored. In this case, a NOTIFICATION
3455 * message SHOULD NOT be sent. This is implemented elsewhere.
3456 *
3457 * RFC4760: An UPDATE message that carries no NLRI, other than the one
3458 * encoded in the MP_REACH_NLRI attribute, SHOULD NOT carry the NEXT_HOP
3459 * attribute. If such a message contains the NEXT_HOP attribute, the BGP
3460 * speaker that receives the message SHOULD ignore this attribute.
3461 */
3462 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP))
3463 && !CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI))) {
3464 if (bgp_attr_nexthop_valid(peer, attr) < 0) {
3465 ret = BGP_ATTR_PARSE_ERROR;
3466 goto done;
3467 }
3468 }
3469
3470 /* Check all mandatory well-known attributes are present */
3471 ret = bgp_attr_check(peer, attr);
3472 if (ret < 0)
3473 goto done;
3474
3475 /*
3476 * At this place we can see whether we got AS4_PATH and/or
3477 * AS4_AGGREGATOR from a 16Bit peer and act accordingly.
3478 * We can not do this before we've read all attributes because
3479 * the as4 handling does not say whether AS4_PATH has to be sent
3480 * after AS_PATH or not - and when AS4_AGGREGATOR will be send
3481 * in relationship to AGGREGATOR.
3482 * So, to be defensive, we are not relying on any order and read
3483 * all attributes first, including these 32bit ones, and now,
3484 * afterwards, we look what and if something is to be done for as4.
3485 *
3486 * It is possible to not have AS_PATH, e.g. GR EoR and sole
3487 * MP_UNREACH_NLRI.
3488 */
3489 /* actually... this doesn't ever return failure currently, but
3490 * better safe than sorry */
3491 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AS_PATH))
3492 && bgp_attr_munge_as4_attrs(peer, attr, as4_path, as4_aggregator,
3493 &as4_aggregator_addr)) {
3494 bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
3495 BGP_NOTIFY_UPDATE_MAL_ATTR);
3496 ret = BGP_ATTR_PARSE_ERROR;
3497 goto done;
3498 }
3499
3500 /*
3501 * Finally do the checks on the aspath we did not do yet
3502 * because we waited for a potentially synthesized aspath.
3503 */
3504 if (attr->flag & (ATTR_FLAG_BIT(BGP_ATTR_AS_PATH))) {
3505 ret = bgp_attr_aspath_check(peer, attr);
3506 if (ret != BGP_ATTR_PARSE_PROCEED)
3507 goto done;
3508 }
3509
3510 ret = BGP_ATTR_PARSE_PROCEED;
3511 done:
3512
3513 /*
3514 * At this stage, we have done all fiddling with as4, and the
3515 * resulting info is in attr->aggregator resp. attr->aspath so
3516 * we can chuck as4_aggregator and as4_path alltogether in order
3517 * to save memory
3518 */
3519 if (as4_path) {
3520 /*
3521 * unintern - it is in the hash
3522 * The flag that we got this is still there, but that
3523 * does not do any trouble
3524 */
3525 aspath_unintern(&as4_path);
3526 }
3527
3528 transit = bgp_attr_get_transit(attr);
3529 if (ret != BGP_ATTR_PARSE_ERROR) {
3530 /* Finally intern unknown attribute. */
3531 if (transit)
3532 bgp_attr_set_transit(attr, transit_intern(transit));
3533 if (attr->encap_subtlvs)
3534 attr->encap_subtlvs = encap_intern(attr->encap_subtlvs,
3535 ENCAP_SUBTLV_TYPE);
3536 #ifdef ENABLE_BGP_VNC
3537 struct bgp_attr_encap_subtlv *vnc_subtlvs =
3538 bgp_attr_get_vnc_subtlvs(attr);
3539
3540 if (vnc_subtlvs)
3541 bgp_attr_set_vnc_subtlvs(
3542 attr,
3543 encap_intern(vnc_subtlvs, VNC_SUBTLV_TYPE));
3544 #endif
3545 } else {
3546 if (transit) {
3547 transit_free(transit);
3548 bgp_attr_set_transit(attr, NULL);
3549 }
3550
3551 bgp_attr_flush_encap(attr);
3552 };
3553
3554 /* Sanity checks */
3555 transit = bgp_attr_get_transit(attr);
3556 if (transit)
3557 assert(transit->refcnt > 0);
3558 if (attr->encap_subtlvs)
3559 assert(attr->encap_subtlvs->refcnt > 0);
3560 #ifdef ENABLE_BGP_VNC
3561 struct bgp_attr_encap_subtlv *vnc_subtlvs =
3562 bgp_attr_get_vnc_subtlvs(attr);
3563
3564 if (vnc_subtlvs)
3565 assert(vnc_subtlvs->refcnt > 0);
3566 #endif
3567
3568 return ret;
3569 }
3570
3571 /*
3572 * Extract the tunnel type from extended community
3573 */
3574 void bgp_attr_extcom_tunnel_type(struct attr *attr,
3575 bgp_encap_types *tunnel_type)
3576 {
3577 struct ecommunity *ecom;
3578 uint32_t i;
3579
3580 if (!attr)
3581 return;
3582
3583 ecom = attr->ecommunity;
3584 if (!ecom || !ecom->size)
3585 return;
3586
3587 for (i = 0; i < ecom->size; i++) {
3588 uint8_t *pnt;
3589 uint8_t type, sub_type;
3590
3591 pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
3592 type = pnt[0];
3593 sub_type = pnt[1];
3594 if (!(type == ECOMMUNITY_ENCODE_OPAQUE &&
3595 sub_type == ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP))
3596 continue;
3597 *tunnel_type = ((pnt[6] << 8) | pnt[7]);
3598 return;
3599 }
3600
3601 return;
3602 }
3603
3604 size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi,
3605 safi_t safi, struct bpacket_attr_vec_arr *vecarr,
3606 struct attr *attr)
3607 {
3608 size_t sizep;
3609 iana_afi_t pkt_afi;
3610 iana_safi_t pkt_safi;
3611 afi_t nh_afi;
3612
3613 /* Set extended bit always to encode the attribute length as 2 bytes */
3614 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_EXTLEN);
3615 stream_putc(s, BGP_ATTR_MP_REACH_NLRI);
3616 sizep = stream_get_endp(s);
3617 stream_putw(s, 0); /* Marker: Attribute length. */
3618
3619
3620 /* Convert AFI, SAFI to values for packet. */
3621 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
3622
3623 stream_putw(s, pkt_afi); /* AFI */
3624 stream_putc(s, pkt_safi); /* SAFI */
3625
3626 /* Nexthop AFI */
3627 if (afi == AFI_IP
3628 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST
3629 || safi == SAFI_MPLS_VPN || safi == SAFI_MULTICAST))
3630 nh_afi = peer_cap_enhe(peer, afi, safi) ? AFI_IP6 : AFI_IP;
3631 else if (safi == SAFI_FLOWSPEC)
3632 nh_afi = afi;
3633 else
3634 nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->mp_nexthop_len);
3635
3636 /* Nexthop */
3637 bpacket_attr_vec_arr_set_vec(vecarr, BGP_ATTR_VEC_NH, s, attr);
3638 switch (nh_afi) {
3639 case AFI_IP:
3640 switch (safi) {
3641 case SAFI_UNICAST:
3642 case SAFI_MULTICAST:
3643 case SAFI_LABELED_UNICAST:
3644 stream_putc(s, 4);
3645 stream_put_ipv4(s, attr->nexthop.s_addr);
3646 break;
3647 case SAFI_MPLS_VPN:
3648 stream_putc(s, 12);
3649 stream_putl(s, 0); /* RD = 0, per RFC */
3650 stream_putl(s, 0);
3651 stream_put(s, &attr->mp_nexthop_global_in, 4);
3652 break;
3653 case SAFI_ENCAP:
3654 case SAFI_EVPN:
3655 stream_putc(s, 4);
3656 stream_put(s, &attr->mp_nexthop_global_in, 4);
3657 break;
3658 case SAFI_FLOWSPEC:
3659 if (attr->mp_nexthop_len == 0)
3660 stream_putc(s, 0); /* no nexthop for flowspec */
3661 else {
3662 stream_putc(s, attr->mp_nexthop_len);
3663 stream_put_ipv4(s, attr->nexthop.s_addr);
3664 }
3665 default:
3666 break;
3667 }
3668 break;
3669 case AFI_IP6:
3670 switch (safi) {
3671 case SAFI_UNICAST:
3672 case SAFI_MULTICAST:
3673 case SAFI_LABELED_UNICAST:
3674 case SAFI_EVPN: {
3675 if (attr->mp_nexthop_len
3676 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
3677 stream_putc(s,
3678 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL);
3679 stream_put(s, &attr->mp_nexthop_global,
3680 IPV6_MAX_BYTELEN);
3681 stream_put(s, &attr->mp_nexthop_local,
3682 IPV6_MAX_BYTELEN);
3683 } else {
3684 stream_putc(s, IPV6_MAX_BYTELEN);
3685 stream_put(s, &attr->mp_nexthop_global,
3686 IPV6_MAX_BYTELEN);
3687 }
3688 } break;
3689 case SAFI_MPLS_VPN: {
3690 if (attr->mp_nexthop_len
3691 == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
3692 stream_putc(s, 24);
3693 stream_putl(s, 0); /* RD = 0, per RFC */
3694 stream_putl(s, 0);
3695 stream_put(s, &attr->mp_nexthop_global,
3696 IPV6_MAX_BYTELEN);
3697 } else if (attr->mp_nexthop_len
3698 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
3699 stream_putc(s, 48);
3700 stream_putl(s, 0); /* RD = 0, per RFC */
3701 stream_putl(s, 0);
3702 stream_put(s, &attr->mp_nexthop_global,
3703 IPV6_MAX_BYTELEN);
3704 stream_putl(s, 0); /* RD = 0, per RFC */
3705 stream_putl(s, 0);
3706 stream_put(s, &attr->mp_nexthop_local,
3707 IPV6_MAX_BYTELEN);
3708 }
3709 } break;
3710 case SAFI_ENCAP:
3711 stream_putc(s, IPV6_MAX_BYTELEN);
3712 stream_put(s, &attr->mp_nexthop_global,
3713 IPV6_MAX_BYTELEN);
3714 break;
3715 case SAFI_FLOWSPEC:
3716 stream_putc(s, 0); /* no nexthop for flowspec */
3717 default:
3718 break;
3719 }
3720 break;
3721 default:
3722 if (safi != SAFI_FLOWSPEC)
3723 flog_err(
3724 EC_BGP_ATTR_NH_SEND_LEN,
3725 "Bad nexthop when sending to %s, AFI %u SAFI %u nhlen %d",
3726 peer->host, afi, safi, attr->mp_nexthop_len);
3727 break;
3728 }
3729
3730 /* SNPA */
3731 stream_putc(s, 0);
3732 return sizep;
3733 }
3734
3735 void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
3736 const struct prefix *p,
3737 const struct prefix_rd *prd, mpls_label_t *label,
3738 uint32_t num_labels, int addpath_encode,
3739 uint32_t addpath_tx_id, struct attr *attr)
3740 {
3741 if (safi == SAFI_MPLS_VPN) {
3742 if (addpath_encode)
3743 stream_putl(s, addpath_tx_id);
3744 /* Label, RD, Prefix write. */
3745 stream_putc(s, p->prefixlen + 88);
3746 stream_put(s, label, BGP_LABEL_BYTES);
3747 stream_put(s, prd->val, 8);
3748 stream_put(s, &p->u.prefix, PSIZE(p->prefixlen));
3749 } else if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
3750 /* EVPN prefix - contents depend on type */
3751 bgp_evpn_encode_prefix(s, p, prd, label, num_labels, attr,
3752 addpath_encode, addpath_tx_id);
3753 } else if (safi == SAFI_LABELED_UNICAST) {
3754 /* Prefix write with label. */
3755 stream_put_labeled_prefix(s, p, label, addpath_encode,
3756 addpath_tx_id);
3757 } else if (safi == SAFI_FLOWSPEC) {
3758 stream_putc(s, p->u.prefix_flowspec.prefixlen);
3759 stream_put(s, (const void *)p->u.prefix_flowspec.ptr,
3760 p->u.prefix_flowspec.prefixlen);
3761 } else
3762 stream_put_prefix_addpath(s, p, addpath_encode, addpath_tx_id);
3763 }
3764
3765 size_t bgp_packet_mpattr_prefix_size(afi_t afi, safi_t safi,
3766 const struct prefix *p)
3767 {
3768 int size = PSIZE(p->prefixlen);
3769 if (safi == SAFI_MPLS_VPN)
3770 size += 88;
3771 else if (safi == SAFI_LABELED_UNICAST)
3772 size += BGP_LABEL_BYTES;
3773 else if (afi == AFI_L2VPN && safi == SAFI_EVPN)
3774 size += 232; // TODO: Maximum possible for type-2, type-3 and
3775 // type-5
3776 return size;
3777 }
3778
3779 /*
3780 * Encodes the tunnel encapsulation attribute,
3781 * and with ENABLE_BGP_VNC the VNC attribute which uses
3782 * almost the same TLV format
3783 */
3784 static void bgp_packet_mpattr_tea(struct bgp *bgp, struct peer *peer,
3785 struct stream *s, struct attr *attr,
3786 uint8_t attrtype)
3787 {
3788 unsigned int attrlenfield = 0;
3789 unsigned int attrhdrlen = 0;
3790 struct bgp_attr_encap_subtlv *subtlvs;
3791 struct bgp_attr_encap_subtlv *st;
3792 const char *attrname;
3793
3794 if (!attr || (attrtype == BGP_ATTR_ENCAP
3795 && (!attr->encap_tunneltype
3796 || attr->encap_tunneltype == BGP_ENCAP_TYPE_MPLS)))
3797 return;
3798
3799 switch (attrtype) {
3800 case BGP_ATTR_ENCAP:
3801 attrname = "Tunnel Encap";
3802 subtlvs = attr->encap_subtlvs;
3803 if (subtlvs == NULL) /* nothing to do */
3804 return;
3805 /*
3806 * The tunnel encap attr has an "outer" tlv.
3807 * T = tunneltype,
3808 * L = total length of subtlvs,
3809 * V = concatenated subtlvs.
3810 */
3811 attrlenfield = 2 + 2; /* T + L */
3812 attrhdrlen = 1 + 1; /* subTLV T + L */
3813 break;
3814
3815 #ifdef ENABLE_BGP_VNC_ATTR
3816 case BGP_ATTR_VNC:
3817 attrname = "VNC";
3818 subtlvs = bgp_attr_get_vnc_subtlvs(attr);
3819 if (subtlvs == NULL) /* nothing to do */
3820 return;
3821 attrlenfield = 0; /* no outer T + L */
3822 attrhdrlen = 2 + 2; /* subTLV T + L */
3823 break;
3824 #endif
3825
3826 default:
3827 assert(0);
3828 }
3829
3830 /* compute attr length */
3831 for (st = subtlvs; st; st = st->next) {
3832 attrlenfield += (attrhdrlen + st->length);
3833 }
3834
3835 if (attrlenfield > 0xffff) {
3836 zlog_info("%s attribute is too long (length=%d), can't send it",
3837 attrname, attrlenfield);
3838 return;
3839 }
3840
3841 if (attrlenfield > 0xff) {
3842 /* 2-octet length field */
3843 stream_putc(s,
3844 BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL
3845 | BGP_ATTR_FLAG_EXTLEN);
3846 stream_putc(s, attrtype);
3847 stream_putw(s, attrlenfield & 0xffff);
3848 } else {
3849 /* 1-octet length field */
3850 stream_putc(s, BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL);
3851 stream_putc(s, attrtype);
3852 stream_putc(s, attrlenfield & 0xff);
3853 }
3854
3855 if (attrtype == BGP_ATTR_ENCAP) {
3856 /* write outer T+L */
3857 stream_putw(s, attr->encap_tunneltype);
3858 stream_putw(s, attrlenfield - 4);
3859 }
3860
3861 /* write each sub-tlv */
3862 for (st = subtlvs; st; st = st->next) {
3863 if (attrtype == BGP_ATTR_ENCAP) {
3864 stream_putc(s, st->type);
3865 stream_putc(s, st->length);
3866 #ifdef ENABLE_BGP_VNC
3867 } else {
3868 stream_putw(s, st->type);
3869 stream_putw(s, st->length);
3870 #endif
3871 }
3872 stream_put(s, st->value, st->length);
3873 }
3874 }
3875
3876 void bgp_packet_mpattr_end(struct stream *s, size_t sizep)
3877 {
3878 /* Set MP attribute length. Don't count the (2) bytes used to encode
3879 the attr length */
3880 stream_putw_at(s, sizep, (stream_get_endp(s) - sizep) - 2);
3881 }
3882
3883 static bool bgp_append_local_as(struct peer *peer, afi_t afi, safi_t safi)
3884 {
3885 if (!BGP_AS_IS_PRIVATE(peer->local_as)
3886 || (BGP_AS_IS_PRIVATE(peer->local_as)
3887 && !CHECK_FLAG(peer->af_flags[afi][safi],
3888 PEER_FLAG_REMOVE_PRIVATE_AS)
3889 && !CHECK_FLAG(peer->af_flags[afi][safi],
3890 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
3891 && !CHECK_FLAG(peer->af_flags[afi][safi],
3892 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
3893 && !CHECK_FLAG(peer->af_flags[afi][safi],
3894 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)))
3895 return true;
3896 return false;
3897 }
3898
3899 /* Make attribute packet. */
3900 bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
3901 struct stream *s, struct attr *attr,
3902 struct bpacket_attr_vec_arr *vecarr,
3903 struct prefix *p, afi_t afi, safi_t safi,
3904 struct peer *from, struct prefix_rd *prd,
3905 mpls_label_t *label, uint32_t num_labels,
3906 int addpath_encode, uint32_t addpath_tx_id)
3907 {
3908 size_t cp;
3909 size_t aspath_sizep;
3910 struct aspath *aspath;
3911 int send_as4_path = 0;
3912 int send_as4_aggregator = 0;
3913 bool use32bit = CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)
3914 && CHECK_FLAG(peer->cap, PEER_CAP_AS4_ADV);
3915
3916 if (!bgp)
3917 bgp = peer->bgp;
3918
3919 /* Remember current pointer. */
3920 cp = stream_get_endp(s);
3921
3922 if (p
3923 && !((afi == AFI_IP && safi == SAFI_UNICAST)
3924 && !peer_cap_enhe(peer, afi, safi))) {
3925 size_t mpattrlen_pos = 0;
3926
3927 mpattrlen_pos = bgp_packet_mpattr_start(s, peer, afi, safi,
3928 vecarr, attr);
3929 bgp_packet_mpattr_prefix(s, afi, safi, p, prd, label,
3930 num_labels, addpath_encode,
3931 addpath_tx_id, attr);
3932 bgp_packet_mpattr_end(s, mpattrlen_pos);
3933 }
3934
3935 /* Origin attribute. */
3936 stream_putc(s, BGP_ATTR_FLAG_TRANS);
3937 stream_putc(s, BGP_ATTR_ORIGIN);
3938 stream_putc(s, 1);
3939 stream_putc(s, attr->origin);
3940
3941 /* AS path attribute. */
3942
3943 /* If remote-peer is EBGP */
3944 if (peer->sort == BGP_PEER_EBGP
3945 && (!CHECK_FLAG(peer->af_flags[afi][safi],
3946 PEER_FLAG_AS_PATH_UNCHANGED)
3947 || attr->aspath->segments == NULL)
3948 && (!CHECK_FLAG(peer->af_flags[afi][safi],
3949 PEER_FLAG_RSERVER_CLIENT))) {
3950 aspath = aspath_dup(attr->aspath);
3951
3952 /* Even though we may not be configured for confederations we
3953 * may have
3954 * RXed an AS_PATH with AS_CONFED_SEQUENCE or AS_CONFED_SET */
3955 aspath = aspath_delete_confed_seq(aspath);
3956
3957 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
3958 /* Stuff our path CONFED_ID on the front */
3959 aspath = aspath_add_seq(aspath, bgp->confed_id);
3960 } else {
3961 if (peer->change_local_as) {
3962 /* If replace-as is specified, we only use the
3963 change_local_as when
3964 advertising routes. */
3965 if (!CHECK_FLAG(peer->flags,
3966 PEER_FLAG_LOCAL_AS_REPLACE_AS))
3967 if (bgp_append_local_as(peer, afi,
3968 safi))
3969 aspath = aspath_add_seq(
3970 aspath, peer->local_as);
3971 aspath = aspath_add_seq(aspath,
3972 peer->change_local_as);
3973 } else {
3974 aspath = aspath_add_seq(aspath, peer->local_as);
3975 }
3976 }
3977 } else if (peer->sort == BGP_PEER_CONFED) {
3978 /* A confed member, so we need to do the AS_CONFED_SEQUENCE
3979 * thing */
3980 aspath = aspath_dup(attr->aspath);
3981 aspath = aspath_add_confed_seq(aspath, peer->local_as);
3982 } else
3983 aspath = attr->aspath;
3984
3985 /* If peer is not AS4 capable, then:
3986 * - send the created AS_PATH out as AS4_PATH (optional, transitive),
3987 * but ensure that no AS_CONFED_SEQUENCE and AS_CONFED_SET path
3988 * segment
3989 * types are in it (i.e. exclude them if they are there)
3990 * AND do this only if there is at least one asnum > 65535 in the
3991 * path!
3992 * - send an AS_PATH out, but put 16Bit ASnums in it, not 32bit, and
3993 * change
3994 * all ASnums > 65535 to BGP_AS_TRANS
3995 */
3996
3997 stream_putc(s, BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_EXTLEN);
3998 stream_putc(s, BGP_ATTR_AS_PATH);
3999 aspath_sizep = stream_get_endp(s);
4000 stream_putw(s, 0);
4001 stream_putw_at(s, aspath_sizep, aspath_put(s, aspath, use32bit));
4002
4003 /* OLD session may need NEW_AS_PATH sent, if there are 4-byte ASNs
4004 * in the path
4005 */
4006 if (!use32bit && aspath_has_as4(aspath))
4007 send_as4_path =
4008 1; /* we'll do this later, at the correct place */
4009
4010 /* Nexthop attribute. */
4011 if (afi == AFI_IP && safi == SAFI_UNICAST
4012 && !peer_cap_enhe(peer, afi, safi)) {
4013 afi_t nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->mp_nexthop_len);
4014
4015 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
4016 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4017 stream_putc(s, BGP_ATTR_NEXT_HOP);
4018 bpacket_attr_vec_arr_set_vec(vecarr, BGP_ATTR_VEC_NH, s,
4019 attr);
4020 stream_putc(s, 4);
4021 stream_put_ipv4(s, attr->nexthop.s_addr);
4022 } else if (peer_cap_enhe(from, afi, safi)
4023 || (nh_afi == AFI_IP6)) {
4024 /*
4025 * Likely this is the case when an IPv4 prefix was
4026 * received with Extended Next-hop capability in this
4027 * or another vrf and is now being advertised to
4028 * non-ENHE peers. Since peer_cap_enhe only checks
4029 * peers in this vrf, also check the nh_afi to catch
4030 * the case where the originator was in another vrf.
4031 * Setting the mandatory (ipv4) next-hop attribute here
4032 * to enable implicit next-hop self with correct A-F
4033 * (ipv4 address family).
4034 */
4035 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4036 stream_putc(s, BGP_ATTR_NEXT_HOP);
4037 bpacket_attr_vec_arr_set_vec(vecarr, BGP_ATTR_VEC_NH, s,
4038 NULL);
4039 stream_putc(s, 4);
4040 stream_put_ipv4(s, 0);
4041 }
4042 }
4043
4044 /* MED attribute. */
4045 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)
4046 || bgp->maxmed_active) {
4047 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
4048 stream_putc(s, BGP_ATTR_MULTI_EXIT_DISC);
4049 stream_putc(s, 4);
4050 stream_putl(s, (bgp->maxmed_active ? bgp->maxmed_value
4051 : attr->med));
4052 }
4053
4054 /* Local preference. */
4055 if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED) {
4056 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4057 stream_putc(s, BGP_ATTR_LOCAL_PREF);
4058 stream_putc(s, 4);
4059 stream_putl(s, attr->local_pref);
4060 }
4061
4062 /* Atomic aggregate. */
4063 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
4064 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4065 stream_putc(s, BGP_ATTR_ATOMIC_AGGREGATE);
4066 stream_putc(s, 0);
4067 }
4068
4069 /* Aggregator. */
4070 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR)) {
4071 /* Common to BGP_ATTR_AGGREGATOR, regardless of ASN size */
4072 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
4073 stream_putc(s, BGP_ATTR_AGGREGATOR);
4074
4075 if (use32bit) {
4076 /* AS4 capable peer */
4077 stream_putc(s, 8);
4078 stream_putl(s, attr->aggregator_as);
4079 } else {
4080 /* 2-byte AS peer */
4081 stream_putc(s, 6);
4082
4083 /* Is ASN representable in 2-bytes? Or must AS_TRANS be
4084 * used? */
4085 if (attr->aggregator_as > UINT16_MAX) {
4086 stream_putw(s, BGP_AS_TRANS);
4087
4088 /* we have to send AS4_AGGREGATOR, too.
4089 * we'll do that later in order to send
4090 * attributes in ascending
4091 * order.
4092 */
4093 send_as4_aggregator = 1;
4094 } else
4095 stream_putw(s, (uint16_t)attr->aggregator_as);
4096 }
4097 stream_put_ipv4(s, attr->aggregator_addr.s_addr);
4098 }
4099
4100 /* Community attribute. */
4101 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY)
4102 && (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))) {
4103 if (attr->community->size * 4 > 255) {
4104 stream_putc(s,
4105 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
4106 | BGP_ATTR_FLAG_EXTLEN);
4107 stream_putc(s, BGP_ATTR_COMMUNITIES);
4108 stream_putw(s, attr->community->size * 4);
4109 } else {
4110 stream_putc(s,
4111 BGP_ATTR_FLAG_OPTIONAL
4112 | BGP_ATTR_FLAG_TRANS);
4113 stream_putc(s, BGP_ATTR_COMMUNITIES);
4114 stream_putc(s, attr->community->size * 4);
4115 }
4116 stream_put(s, attr->community->val, attr->community->size * 4);
4117 }
4118
4119 /*
4120 * Large Community attribute.
4121 */
4122 if (CHECK_FLAG(peer->af_flags[afi][safi],
4123 PEER_FLAG_SEND_LARGE_COMMUNITY)
4124 && (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))) {
4125 if (lcom_length(attr->lcommunity) > 255) {
4126 stream_putc(s,
4127 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
4128 | BGP_ATTR_FLAG_EXTLEN);
4129 stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
4130 stream_putw(s, lcom_length(attr->lcommunity));
4131 } else {
4132 stream_putc(s,
4133 BGP_ATTR_FLAG_OPTIONAL
4134 | BGP_ATTR_FLAG_TRANS);
4135 stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
4136 stream_putc(s, lcom_length(attr->lcommunity));
4137 }
4138 stream_put(s, attr->lcommunity->val,
4139 lcom_length(attr->lcommunity));
4140 }
4141
4142 /* Route Reflector. */
4143 if (peer->sort == BGP_PEER_IBGP && from
4144 && from->sort == BGP_PEER_IBGP) {
4145 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
4146
4147 /* Originator ID. */
4148 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
4149 stream_putc(s, BGP_ATTR_ORIGINATOR_ID);
4150 stream_putc(s, 4);
4151
4152 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
4153 stream_put_in_addr(s, &attr->originator_id);
4154 else
4155 stream_put_in_addr(s, &from->remote_id);
4156
4157 /* Cluster list. */
4158 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
4159 stream_putc(s, BGP_ATTR_CLUSTER_LIST);
4160
4161 if (cluster) {
4162 stream_putc(s, cluster->length + 4);
4163 /* If this peer configuration's parent BGP has
4164 * cluster_id. */
4165 if (bgp->config & BGP_CONFIG_CLUSTER_ID)
4166 stream_put_in_addr(s, &bgp->cluster_id);
4167 else
4168 stream_put_in_addr(s, &bgp->router_id);
4169 stream_put(s, cluster->list, cluster->length);
4170 } else {
4171 stream_putc(s, 4);
4172 /* If this peer configuration's parent BGP has
4173 * cluster_id. */
4174 if (bgp->config & BGP_CONFIG_CLUSTER_ID)
4175 stream_put_in_addr(s, &bgp->cluster_id);
4176 else
4177 stream_put_in_addr(s, &bgp->router_id);
4178 }
4179 }
4180
4181 /* Extended Communities attribute. */
4182 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY)
4183 && (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4184 if (peer->sort == BGP_PEER_IBGP
4185 || peer->sort == BGP_PEER_CONFED) {
4186 if (attr->ecommunity->size * 8 > 255) {
4187 stream_putc(s,
4188 BGP_ATTR_FLAG_OPTIONAL
4189 | BGP_ATTR_FLAG_TRANS
4190 | BGP_ATTR_FLAG_EXTLEN);
4191 stream_putc(s, BGP_ATTR_EXT_COMMUNITIES);
4192 stream_putw(s, attr->ecommunity->size * 8);
4193 } else {
4194 stream_putc(s,
4195 BGP_ATTR_FLAG_OPTIONAL
4196 | BGP_ATTR_FLAG_TRANS);
4197 stream_putc(s, BGP_ATTR_EXT_COMMUNITIES);
4198 stream_putc(s, attr->ecommunity->size * 8);
4199 }
4200 stream_put(s, attr->ecommunity->val,
4201 attr->ecommunity->size * 8);
4202 } else {
4203 uint8_t *pnt;
4204 int tbit;
4205 int ecom_tr_size = 0;
4206 uint32_t i;
4207
4208 for (i = 0; i < attr->ecommunity->size; i++) {
4209 pnt = attr->ecommunity->val + (i * 8);
4210 tbit = *pnt;
4211
4212 if (CHECK_FLAG(tbit,
4213 ECOMMUNITY_FLAG_NON_TRANSITIVE))
4214 continue;
4215
4216 ecom_tr_size++;
4217 }
4218
4219 if (ecom_tr_size) {
4220 if (ecom_tr_size * 8 > 255) {
4221 stream_putc(
4222 s,
4223 BGP_ATTR_FLAG_OPTIONAL
4224 | BGP_ATTR_FLAG_TRANS
4225 | BGP_ATTR_FLAG_EXTLEN);
4226 stream_putc(s,
4227 BGP_ATTR_EXT_COMMUNITIES);
4228 stream_putw(s, ecom_tr_size * 8);
4229 } else {
4230 stream_putc(
4231 s,
4232 BGP_ATTR_FLAG_OPTIONAL
4233 | BGP_ATTR_FLAG_TRANS);
4234 stream_putc(s,
4235 BGP_ATTR_EXT_COMMUNITIES);
4236 stream_putc(s, ecom_tr_size * 8);
4237 }
4238
4239 for (i = 0; i < attr->ecommunity->size; i++) {
4240 pnt = attr->ecommunity->val + (i * 8);
4241 tbit = *pnt;
4242
4243 if (CHECK_FLAG(
4244 tbit,
4245 ECOMMUNITY_FLAG_NON_TRANSITIVE))
4246 continue;
4247
4248 stream_put(s, pnt, 8);
4249 }
4250 }
4251 }
4252 }
4253
4254 /* Label index attribute. */
4255 if (safi == SAFI_LABELED_UNICAST) {
4256 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) {
4257 uint32_t label_index;
4258
4259 label_index = attr->label_index;
4260
4261 if (label_index != BGP_INVALID_LABEL_INDEX) {
4262 stream_putc(s,
4263 BGP_ATTR_FLAG_OPTIONAL
4264 | BGP_ATTR_FLAG_TRANS);
4265 stream_putc(s, BGP_ATTR_PREFIX_SID);
4266 stream_putc(s, 10);
4267 stream_putc(s, BGP_PREFIX_SID_LABEL_INDEX);
4268 stream_putw(s,
4269 BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
4270 stream_putc(s, 0); // reserved
4271 stream_putw(s, 0); // flags
4272 stream_putl(s, label_index);
4273 }
4274 }
4275 }
4276
4277 /* SRv6 Service Information Attribute. */
4278 if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_MPLS_VPN) {
4279 if (attr->srv6_l3vpn) {
4280 uint8_t subtlv_len =
4281 BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_STRUCTURE_LENGTH
4282 + BGP_ATTR_MIN_LEN
4283 + BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_INFO_LENGTH;
4284 uint8_t tlv_len = subtlv_len + BGP_ATTR_MIN_LEN + 1;
4285 uint8_t attr_len = tlv_len + BGP_ATTR_MIN_LEN;
4286 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL
4287 | BGP_ATTR_FLAG_TRANS);
4288 stream_putc(s, BGP_ATTR_PREFIX_SID);
4289 stream_putc(s, attr_len);
4290 stream_putc(s, BGP_PREFIX_SID_SRV6_L3_SERVICE);
4291 stream_putw(s, tlv_len);
4292 stream_putc(s, 0); /* reserved */
4293 stream_putc(s, BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_INFO);
4294 stream_putw(s, subtlv_len);
4295 stream_putc(s, 0); /* reserved */
4296 stream_put(s, &attr->srv6_l3vpn->sid,
4297 sizeof(attr->srv6_l3vpn->sid)); /* sid */
4298 stream_putc(s, 0); /* sid_flags */
4299 stream_putw(s, 0xffff); /* endpoint */
4300 stream_putc(s, 0); /* reserved */
4301 stream_putc(
4302 s,
4303 BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_STRUCTURE);
4304 stream_putw(
4305 s,
4306 BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_STRUCTURE_LENGTH);
4307 stream_putc(s, attr->srv6_l3vpn->loc_block_len);
4308 stream_putc(s, attr->srv6_l3vpn->loc_node_len);
4309 stream_putc(s, attr->srv6_l3vpn->func_len);
4310 stream_putc(s, attr->srv6_l3vpn->arg_len);
4311 stream_putc(s, attr->srv6_l3vpn->transposition_len);
4312 stream_putc(s, attr->srv6_l3vpn->transposition_offset);
4313 } else if (attr->srv6_vpn) {
4314 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL
4315 | BGP_ATTR_FLAG_TRANS);
4316 stream_putc(s, BGP_ATTR_PREFIX_SID);
4317 stream_putc(s, 22); /* tlv len */
4318 stream_putc(s, BGP_PREFIX_SID_VPN_SID);
4319 stream_putw(s, 0x13); /* tlv len */
4320 stream_putc(s, 0x00); /* reserved */
4321 stream_putc(s, 0x01); /* sid_type */
4322 stream_putc(s, 0x00); /* sif_flags */
4323 stream_put(s, &attr->srv6_vpn->sid,
4324 sizeof(attr->srv6_vpn->sid)); /* sid */
4325 }
4326 }
4327
4328 if (send_as4_path) {
4329 /* If the peer is NOT As4 capable, AND */
4330 /* there are ASnums > 65535 in path THEN
4331 * give out AS4_PATH */
4332
4333 /* Get rid of all AS_CONFED_SEQUENCE and AS_CONFED_SET
4334 * path segments!
4335 * Hm, I wonder... confederation things *should* only be at
4336 * the beginning of an aspath, right? Then we should use
4337 * aspath_delete_confed_seq for this, because it is already
4338 * there! (JK)
4339 * Folks, talk to me: what is reasonable here!?
4340 */
4341 aspath = aspath_delete_confed_seq(aspath);
4342
4343 stream_putc(s,
4344 BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_OPTIONAL
4345 | BGP_ATTR_FLAG_EXTLEN);
4346 stream_putc(s, BGP_ATTR_AS4_PATH);
4347 aspath_sizep = stream_get_endp(s);
4348 stream_putw(s, 0);
4349 stream_putw_at(s, aspath_sizep, aspath_put(s, aspath, 1));
4350 }
4351
4352 if (aspath != attr->aspath)
4353 aspath_free(aspath);
4354
4355 if (send_as4_aggregator) {
4356 /* send AS4_AGGREGATOR, at this place */
4357 /* this section of code moved here in order to ensure the
4358 * correct
4359 * *ascending* order of attributes
4360 */
4361 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
4362 stream_putc(s, BGP_ATTR_AS4_AGGREGATOR);
4363 stream_putc(s, 8);
4364 stream_putl(s, attr->aggregator_as);
4365 stream_put_ipv4(s, attr->aggregator_addr.s_addr);
4366 }
4367
4368 if (((afi == AFI_IP || afi == AFI_IP6)
4369 && (safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN))
4370 || (afi == AFI_L2VPN && safi == SAFI_EVPN)) {
4371 /* Tunnel Encap attribute */
4372 bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_ENCAP);
4373
4374 #ifdef ENABLE_BGP_VNC_ATTR
4375 /* VNC attribute */
4376 bgp_packet_mpattr_tea(bgp, peer, s, attr, BGP_ATTR_VNC);
4377 #endif
4378 }
4379
4380 /* PMSI Tunnel */
4381 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
4382 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
4383 stream_putc(s, BGP_ATTR_PMSI_TUNNEL);
4384 stream_putc(s, 9); // Length
4385 stream_putc(s, 0); // Flags
4386 stream_putc(s, bgp_attr_get_pmsi_tnl_type(attr));
4387 stream_put(s, &(attr->label),
4388 BGP_LABEL_BYTES); // MPLS Label / VXLAN VNI
4389 stream_put_ipv4(s, attr->nexthop.s_addr);
4390 // Unicast tunnel endpoint IP address
4391 }
4392
4393 /* Unknown transit attribute. */
4394 struct transit *transit = bgp_attr_get_transit(attr);
4395
4396 if (transit)
4397 stream_put(s, transit->val, transit->length);
4398
4399 /* Return total size of attribute. */
4400 return stream_get_endp(s) - cp;
4401 }
4402
4403 size_t bgp_packet_mpunreach_start(struct stream *s, afi_t afi, safi_t safi)
4404 {
4405 unsigned long attrlen_pnt;
4406 iana_afi_t pkt_afi;
4407 iana_safi_t pkt_safi;
4408
4409 /* Set extended bit always to encode the attribute length as 2 bytes */
4410 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_EXTLEN);
4411 stream_putc(s, BGP_ATTR_MP_UNREACH_NLRI);
4412
4413 attrlen_pnt = stream_get_endp(s);
4414 stream_putw(s, 0); /* Length of this attribute. */
4415
4416 /* Convert AFI, SAFI to values for packet. */
4417 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
4418
4419 stream_putw(s, pkt_afi);
4420 stream_putc(s, pkt_safi);
4421
4422 return attrlen_pnt;
4423 }
4424
4425 void bgp_packet_mpunreach_prefix(struct stream *s, const struct prefix *p,
4426 afi_t afi, safi_t safi,
4427 const struct prefix_rd *prd,
4428 mpls_label_t *label, uint32_t num_labels,
4429 int addpath_encode, uint32_t addpath_tx_id,
4430 struct attr *attr)
4431 {
4432 uint8_t wlabel[3] = {0x80, 0x00, 0x00};
4433
4434 if (safi == SAFI_LABELED_UNICAST) {
4435 label = (mpls_label_t *)wlabel;
4436 num_labels = 1;
4437 }
4438
4439 bgp_packet_mpattr_prefix(s, afi, safi, p, prd, label, num_labels,
4440 addpath_encode, addpath_tx_id, attr);
4441 }
4442
4443 void bgp_packet_mpunreach_end(struct stream *s, size_t attrlen_pnt)
4444 {
4445 bgp_packet_mpattr_end(s, attrlen_pnt);
4446 }
4447
4448 /* Initialization of attribute. */
4449 void bgp_attr_init(void)
4450 {
4451 aspath_init();
4452 attrhash_init();
4453 community_init();
4454 ecommunity_init();
4455 lcommunity_init();
4456 cluster_init();
4457 transit_init();
4458 encap_init();
4459 srv6_init();
4460 }
4461
4462 void bgp_attr_finish(void)
4463 {
4464 aspath_finish();
4465 attrhash_finish();
4466 community_finish();
4467 ecommunity_finish();
4468 lcommunity_finish();
4469 cluster_finish();
4470 transit_finish();
4471 encap_finish();
4472 srv6_finish();
4473 }
4474
4475 /* Make attribute packet. */
4476 void bgp_dump_routes_attr(struct stream *s, struct attr *attr,
4477 const struct prefix *prefix)
4478 {
4479 unsigned long cp;
4480 unsigned long len;
4481 size_t aspath_lenp;
4482 struct aspath *aspath;
4483 int addpath_encode = 0;
4484 uint32_t addpath_tx_id = 0;
4485
4486 /* Remember current pointer. */
4487 cp = stream_get_endp(s);
4488
4489 /* Place holder of length. */
4490 stream_putw(s, 0);
4491
4492 /* Origin attribute. */
4493 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4494 stream_putc(s, BGP_ATTR_ORIGIN);
4495 stream_putc(s, 1);
4496 stream_putc(s, attr->origin);
4497
4498 aspath = attr->aspath;
4499
4500 stream_putc(s, BGP_ATTR_FLAG_TRANS | BGP_ATTR_FLAG_EXTLEN);
4501 stream_putc(s, BGP_ATTR_AS_PATH);
4502 aspath_lenp = stream_get_endp(s);
4503 stream_putw(s, 0);
4504
4505 stream_putw_at(s, aspath_lenp, aspath_put(s, aspath, 1));
4506
4507 /* Nexthop attribute. */
4508 /* If it's an IPv6 prefix, don't dump the IPv4 nexthop to save space */
4509 if (prefix != NULL && prefix->family != AF_INET6) {
4510 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4511 stream_putc(s, BGP_ATTR_NEXT_HOP);
4512 stream_putc(s, 4);
4513 stream_put_ipv4(s, attr->nexthop.s_addr);
4514 }
4515
4516 /* MED attribute. */
4517 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
4518 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
4519 stream_putc(s, BGP_ATTR_MULTI_EXIT_DISC);
4520 stream_putc(s, 4);
4521 stream_putl(s, attr->med);
4522 }
4523
4524 /* Local preference. */
4525 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
4526 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4527 stream_putc(s, BGP_ATTR_LOCAL_PREF);
4528 stream_putc(s, 4);
4529 stream_putl(s, attr->local_pref);
4530 }
4531
4532 /* Atomic aggregate. */
4533 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
4534 stream_putc(s, BGP_ATTR_FLAG_TRANS);
4535 stream_putc(s, BGP_ATTR_ATOMIC_AGGREGATE);
4536 stream_putc(s, 0);
4537 }
4538
4539 /* Aggregator. */
4540 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR)) {
4541 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
4542 stream_putc(s, BGP_ATTR_AGGREGATOR);
4543 stream_putc(s, 8);
4544 stream_putl(s, attr->aggregator_as);
4545 stream_put_ipv4(s, attr->aggregator_addr.s_addr);
4546 }
4547
4548 /* Community attribute. */
4549 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
4550 if (attr->community->size * 4 > 255) {
4551 stream_putc(s,
4552 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
4553 | BGP_ATTR_FLAG_EXTLEN);
4554 stream_putc(s, BGP_ATTR_COMMUNITIES);
4555 stream_putw(s, attr->community->size * 4);
4556 } else {
4557 stream_putc(s,
4558 BGP_ATTR_FLAG_OPTIONAL
4559 | BGP_ATTR_FLAG_TRANS);
4560 stream_putc(s, BGP_ATTR_COMMUNITIES);
4561 stream_putc(s, attr->community->size * 4);
4562 }
4563 stream_put(s, attr->community->val, attr->community->size * 4);
4564 }
4565
4566 /* Large Community attribute. */
4567 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
4568 if (lcom_length(attr->lcommunity) > 255) {
4569 stream_putc(s,
4570 BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
4571 | BGP_ATTR_FLAG_EXTLEN);
4572 stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
4573 stream_putw(s, lcom_length(attr->lcommunity));
4574 } else {
4575 stream_putc(s,
4576 BGP_ATTR_FLAG_OPTIONAL
4577 | BGP_ATTR_FLAG_TRANS);
4578 stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
4579 stream_putc(s, lcom_length(attr->lcommunity));
4580 }
4581
4582 stream_put(s, attr->lcommunity->val,
4583 lcom_length(attr->lcommunity));
4584 }
4585
4586 /* Add a MP_NLRI attribute to dump the IPv6 next hop */
4587 if (prefix != NULL && prefix->family == AF_INET6
4588 && (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL
4589 || attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)) {
4590 int sizep;
4591
4592 stream_putc(s, BGP_ATTR_FLAG_OPTIONAL);
4593 stream_putc(s, BGP_ATTR_MP_REACH_NLRI);
4594 sizep = stream_get_endp(s);
4595
4596 /* MP header */
4597 stream_putc(s, 0); /* Marker: Attribute length. */
4598 stream_putw(s, AFI_IP6); /* AFI */
4599 stream_putc(s, SAFI_UNICAST); /* SAFI */
4600
4601 /* Next hop */
4602 stream_putc(s, attr->mp_nexthop_len);
4603 stream_put(s, &attr->mp_nexthop_global, IPV6_MAX_BYTELEN);
4604 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
4605 stream_put(s, &attr->mp_nexthop_local,
4606 IPV6_MAX_BYTELEN);
4607
4608 /* SNPA */
4609 stream_putc(s, 0);
4610
4611 /* Prefix */
4612 stream_put_prefix_addpath(s, prefix, addpath_encode,
4613 addpath_tx_id);
4614
4615 /* Set MP attribute length. */
4616 stream_putc_at(s, sizep, (stream_get_endp(s) - sizep) - 1);
4617 }
4618
4619 /* Prefix SID */
4620 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID)) {
4621 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
4622 stream_putc(s,
4623 BGP_ATTR_FLAG_OPTIONAL
4624 | BGP_ATTR_FLAG_TRANS);
4625 stream_putc(s, BGP_ATTR_PREFIX_SID);
4626 stream_putc(s, 10);
4627 stream_putc(s, BGP_PREFIX_SID_LABEL_INDEX);
4628 stream_putc(s, BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
4629 stream_putc(s, 0); // reserved
4630 stream_putw(s, 0); // flags
4631 stream_putl(s, attr->label_index);
4632 }
4633 }
4634
4635 /* Return total size of attribute. */
4636 len = stream_get_endp(s) - cp - 2;
4637 stream_putw_at(s, cp, len);
4638 }