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