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