1/* BGP attributes management routines. 2 Copyright (C) 1996, 97, 98, 1999 Kunihiro Ishiguro 3 4This file is part of GNU Zebra. 5 6GNU Zebra is free software; you can redistribute it and/or modify it 7under the terms of the GNU General Public License as published by the 8Free Software Foundation; either version 2, or (at your option) any 9later version. 10 11GNU Zebra is distributed in the hope that it will be useful, but 12WITHOUT ANY WARRANTY; without even the implied warranty of 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14General Public License for more details. 15 16You should have received a copy of the GNU General Public License 17along with GNU Zebra; see the file COPYING. If not, write to the Free 18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 1902111-1307, USA. */ 20 21#include <zebra.h> 22 23#include "linklist.h" 24#include "prefix.h" 25#include "memory.h" 26#include "vector.h" 27#include "vty.h" 28#include "stream.h" 29#include "log.h" 30#include "hash.h" 31 32#include "bgpd/bgpd.h" 33#include "bgpd/bgp_attr.h" 34#include "bgpd/bgp_route.h" 35#include "bgpd/bgp_aspath.h" 36#include "bgpd/bgp_community.h" 37#include "bgpd/bgp_debug.h" 38#include "bgpd/bgp_packet.h" 39#include "bgpd/bgp_ecommunity.h" 40 41/* Attribute strings for logging. */ 42struct message attr_str [] = 43{ 44 { BGP_ATTR_ORIGIN, "ORIGIN" }, 45 { BGP_ATTR_AS_PATH, "AS_PATH" }, 46 { BGP_ATTR_NEXT_HOP, "NEXT_HOP" }, 47 { BGP_ATTR_MULTI_EXIT_DISC, "MULTI_EXIT_DISC" }, 48 { BGP_ATTR_LOCAL_PREF, "LOCAL_PREF" }, 49 { BGP_ATTR_ATOMIC_AGGREGATE, "ATOMIC_AGGREGATE" }, 50 { BGP_ATTR_AGGREGATOR, "AGGREGATOR" }, 51 { BGP_ATTR_COMMUNITIES, "COMMUNITY" }, 52 { BGP_ATTR_ORIGINATOR_ID, "ORIGINATOR_ID" }, 53 { BGP_ATTR_CLUSTER_LIST, "CLUSTERLIST" }, 54 { BGP_ATTR_DPA, "DPA" }, 55 { BGP_ATTR_ADVERTISER, "ADVERTISER"} , 56 { BGP_ATTR_RCID_PATH, "RCID_PATH" }, 57 { BGP_ATTR_MP_REACH_NLRI, "MP_REACH_NLRI" }, 58 { BGP_ATTR_MP_UNREACH_NLRI, "MP_UNREACH_NLRI" }, 59 { 0, NULL } 60}; 61 62struct hash *cluster_hash; 63 64void * 65cluster_hash_alloc (struct cluster_list *val) 66{ 67 struct cluster_list *cluster; 68 69 cluster = XMALLOC (MTYPE_CLUSTER, sizeof (struct cluster_list)); 70 cluster->length = val->length; 71 72 if (cluster->length) 73 { 74 cluster->list = XMALLOC (MTYPE_CLUSTER_VAL, val->length); 75 memcpy (cluster->list, val->list, val->length); 76 } 77 else 78 cluster->list = NULL; 79 80 cluster->refcnt = 0; 81 82 return cluster; 83} 84 85/* Cluster list related functions. */ 86struct cluster_list * 87cluster_parse (caddr_t pnt, int length) 88{ 89 struct cluster_list tmp; 90 struct cluster_list *cluster; 91 92 tmp.length = length; 93 tmp.list = (struct in_addr *) pnt; 94 95 cluster = hash_get (cluster_hash, &tmp, cluster_hash_alloc); 96 cluster->refcnt++; 97 return cluster; 98} 99 100int 101cluster_loop_check (struct cluster_list *cluster, struct in_addr originator) 102{ 103 int i; 104 105 for (i = 0; i < cluster->length / 4; i++) 106 if (cluster->list[i].s_addr == originator.s_addr) 107 return 1; 108 return 0; 109} 110 111unsigned int 112cluster_hash_key_make (struct cluster_list *cluster) 113{ 114 unsigned int key = 0; 115 int length; 116 caddr_t pnt; 117 118 length = cluster->length; 119 pnt = (caddr_t) cluster->list; 120 121 while (length) 122 key += pnt[--length]; 123 124 return key; 125} 126 127int 128cluster_hash_cmp (struct cluster_list *cluster1, struct cluster_list *cluster2) 129{ 130 if (cluster1->length == cluster2->length && 131 memcmp (cluster1->list, cluster2->list, cluster1->length) == 0) 132 return 1; 133 return 0; 134} 135 136void 137cluster_free (struct cluster_list *cluster) 138{ 139 if (cluster->list) 140 XFREE (MTYPE_CLUSTER_VAL, cluster->list); 141 XFREE (MTYPE_CLUSTER, cluster); 142} 143 144struct cluster_list * 145cluster_dup (struct cluster_list *cluster) 146{ 147 struct cluster_list *new; 148 149 new = XMALLOC (MTYPE_CLUSTER, sizeof (struct cluster_list)); 150 memset (new, 0, sizeof (struct cluster_list)); 151 new->length = cluster->length; 152 153 if (cluster->length) 154 { 155 new->list = XMALLOC (MTYPE_CLUSTER_VAL, cluster->length); 156 memcpy (new->list, cluster->list, cluster->length); 157 } 158 else 159 new->list = NULL; 160 161 return new; 162} 163 164struct cluster_list * 165cluster_intern (struct cluster_list *cluster) 166{ 167 struct cluster_list *find; 168 169 find = hash_get (cluster_hash, cluster, cluster_hash_alloc); 170 find->refcnt++; 171 172 return find; 173} 174 175void 176cluster_unintern (struct cluster_list *cluster) 177{ 178 struct cluster_list *ret; 179 180 if (cluster->refcnt) 181 cluster->refcnt--; 182 183 if (cluster->refcnt == 0) 184 { 185 ret = hash_release (cluster_hash, cluster); 186 cluster_free (cluster); 187 } 188} 189 190void 191cluster_init () 192{ 193 cluster_hash = hash_create (cluster_hash_key_make, cluster_hash_cmp); 194} 195 196/* Unknown transit attribute. */ 197struct hash *transit_hash; 198 199void 200transit_free (struct transit *transit) 201{ 202 if (transit->val) 203 XFREE (MTYPE_TRANSIT_VAL, transit->val); 204 XFREE (MTYPE_TRANSIT, transit); 205} 206 207void * 208transit_hash_alloc (struct transit *transit) 209{ 210 /* Transit structure is already allocated. */ 211 return transit; 212} 213 214struct transit * 215transit_intern (struct transit *transit) 216{ 217 struct transit *find; 218 219 find = hash_get (transit_hash, transit, transit_hash_alloc); 220 if (find != transit) 221 transit_free (transit); 222 find->refcnt++; 223 224 return find; 225} 226 227void 228transit_unintern (struct transit *transit) 229{ 230 struct transit *ret; 231 232 if (transit->refcnt) 233 transit->refcnt--; 234 235 if (transit->refcnt == 0) 236 { 237 ret = hash_release (transit_hash, transit); 238 transit_free (transit); 239 } 240} 241 242unsigned int 243transit_hash_key_make (struct transit *transit) 244{ 245 unsigned int key = 0; 246 int length; 247 caddr_t pnt; 248 249 length = transit->length; 250 pnt = (caddr_t) transit->val; 251 252 while (length) 253 key += pnt[--length]; 254 255 return key; 256} 257 258int 259transit_hash_cmp (struct transit *transit1, struct transit *transit2) 260{ 261 if (transit1->length == transit2->length && 262 memcmp (transit1->val, transit2->val, transit1->length) == 0) 263 return 1; 264 return 0; 265} 266 267void 268transit_init () 269{ 270 transit_hash = hash_create (transit_hash_key_make, transit_hash_cmp); 271} 272 273/* Attribute hash routines. */ 274 275struct hash *attrhash; 276 277unsigned int 278attrhash_key_make (struct attr *attr) 279{ 280 unsigned int key = 0; 281 282 key += attr->origin; 283 key += attr->nexthop.s_addr; 284 key += attr->med; 285 key += attr->local_pref; 286 key += attr->aggregator_as; 287 key += attr->aggregator_addr.s_addr; 288 key += attr->weight; 289 290 key += attr->mp_nexthop_global_in.s_addr; 291 if (attr->aspath) 292 key += aspath_key_make (attr->aspath); 293 if (attr->community) 294 key += community_hash_make (attr->community); 295 if (attr->ecommunity) 296 key += ecommunity_hash_make (attr->ecommunity); 297 if (attr->cluster) 298 key += cluster_hash_key_make (attr->cluster); 299 if (attr->transit) 300 key += transit_hash_key_make (attr->transit); 301 302#ifdef HAVE_IPV6 303 { 304 int i; 305 306 key += attr->mp_nexthop_len; 307 for (i = 0; i < 16; i++) 308 key += attr->mp_nexthop_global.s6_addr[i]; 309 for (i = 0; i < 16; i++) 310 key += attr->mp_nexthop_local.s6_addr[i]; 311 } 312#endif /* HAVE_IPV6 */ 313 314 return key; 315} 316 317int 318attrhash_cmp (struct attr *attr1, struct attr *attr2) 319{ 320 if (attr1->flag == attr2->flag 321 && attr1->origin == attr2->origin 322 && attr1->nexthop.s_addr == attr2->nexthop.s_addr 323 && attr1->med == attr2->med 324 && attr1->local_pref == attr2->local_pref 325 && attr1->aggregator_as == attr2->aggregator_as 326 && attr1->aggregator_addr.s_addr == attr2->aggregator_addr.s_addr 327 && attr1->weight == attr2->weight 328#ifdef HAVE_IPV6 329 && attr1->mp_nexthop_len == attr2->mp_nexthop_len 330 && IPV6_ADDR_SAME (&attr1->mp_nexthop_global, &attr2->mp_nexthop_global) 331 && IPV6_ADDR_SAME (&attr1->mp_nexthop_local, &attr2->mp_nexthop_local) 332#endif /* HAVE_IPV6 */ 333 && IPV4_ADDR_SAME (&attr1->mp_nexthop_global_in, &attr2->mp_nexthop_global_in) 334 && attr1->aspath == attr2->aspath 335 && attr1->community == attr2->community 336 && attr1->ecommunity == attr2->ecommunity 337 && attr1->cluster == attr2->cluster 338 && attr1->transit == attr2->transit) 339 return 1; 340 else 341 return 0; 342} 343 344void 345attrhash_init () 346{ 347 attrhash = hash_create (attrhash_key_make, attrhash_cmp); 348} 349 350void 351attr_show_all_iterator (struct hash_backet *backet, struct vty *vty) 352{ 353 struct attr *attr = backet->data; 354 355 vty_out (vty, "attr[%ld] nexthop %s%s", attr->refcnt, 356 inet_ntoa (attr->nexthop), VTY_NEWLINE); 357} 358 359void 360attr_show_all (struct vty *vty) 361{ 362 hash_iterate (attrhash, 363 (void (*)(struct hash_backet *, void *)) 364 attr_show_all_iterator, 365 vty); 366} 367 368void * 369bgp_attr_hash_alloc (struct attr *val) 370{ 371 struct attr *attr; 372 373 attr = XMALLOC (MTYPE_ATTR, sizeof (struct attr)); 374 *attr = *val; 375 attr->refcnt = 0; 376 return attr; 377} 378 379/* Internet argument attribute. */ 380struct attr * 381bgp_attr_intern (struct attr *attr) 382{ 383 struct attr *find; 384 385 /* Intern referenced strucutre. */ 386 if (attr->aspath) 387 { 388 if (! attr->aspath->refcnt) 389 attr->aspath = aspath_intern (attr->aspath); 390 else 391 attr->aspath->refcnt++; 392 } 393 if (attr->community) 394 { 395 if (! attr->community->refcnt) 396 attr->community = community_intern (attr->community); 397 else 398 attr->community->refcnt++; 399 } 400 if (attr->ecommunity) 401 { 402 if (! attr->ecommunity->refcnt) 403 attr->ecommunity = ecommunity_intern (attr->ecommunity); 404 else 405 attr->ecommunity->refcnt++; 406 } 407 if (attr->cluster) 408 { 409 if (! attr->cluster->refcnt) 410 attr->cluster = cluster_intern (attr->cluster); 411 else 412 attr->cluster->refcnt++; 413 } 414 if (attr->transit) 415 { 416 if (! attr->transit->refcnt) 417 attr->transit = transit_intern (attr->transit); 418 else 419 attr->transit->refcnt++; 420 } 421 422 find = (struct attr *) hash_get (attrhash, attr, bgp_attr_hash_alloc); 423 find->refcnt++; 424 425 return find; 426} 427 428/* Make network statement's attribute. */ 429struct attr * 430bgp_attr_default_set (struct attr *attr, u_char origin) 431{ 432 memset (attr, 0, sizeof (struct attr)); 433 434 attr->origin = origin; 435 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGIN); 436 attr->aspath = aspath_empty (); 437 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATH); 438 attr->weight = 32768; 439 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP); 440#ifdef HAVE_IPV6 441 attr->mp_nexthop_len = 16; 442#endif 443 return attr; 444} 445 446/* Make network statement's attribute. */ 447struct attr * 448bgp_attr_default_intern (u_char origin) 449{ 450 struct attr attr; 451 struct attr *new; 452 453 memset (&attr, 0, sizeof (struct attr)); 454 455 attr.origin = origin; 456 attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGIN); 457 attr.aspath = aspath_empty (); 458 attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATH); 459 attr.weight = 32768; 460 attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP); 461#ifdef HAVE_IPV6 462 attr.mp_nexthop_len = 16; 463#endif 464 465 new = bgp_attr_intern (&attr); 466 aspath_unintern (new->aspath); 467 return new; 468} 469 470struct attr * 471bgp_attr_aggregate_intern (struct bgp *bgp, u_char origin, 472 struct aspath *aspath, 473 struct community *community, int as_set) 474{ 475 struct attr attr; 476 struct attr *new; 477 478 memset (&attr, 0, sizeof (struct attr)); 479 480 /* Origin attribute. */ 481 attr.origin = origin; 482 attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGIN); 483 484 /* AS path attribute. */ 485 if (aspath) 486 attr.aspath = aspath_intern (aspath); 487 else 488 attr.aspath = aspath_empty (); 489 attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATH); 490 491 /* Next hop attribute. */ 492 attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP); 493 494 if (community) 495 { 496 attr.community = community; 497 attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES); 498 } 499 500 attr.weight = 32768; 501#ifdef HAVE_IPV6 502 attr.mp_nexthop_len = 16; 503#endif 504 if (! as_set) 505 attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE); 506 attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR); 507 if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION)) 508 attr.aggregator_as = bgp->confed_id; 509 else 510 attr.aggregator_as = bgp->as; 511 attr.aggregator_addr = bgp->router_id; 512 513 new = bgp_attr_intern (&attr); 514 aspath_unintern (new->aspath); 515 return new; 516} 517 518/* Free bgp attribute and aspath. */ 519void 520bgp_attr_unintern (struct attr *attr) 521{ 522 struct attr *ret; 523 struct aspath *aspath; 524 struct community *community; 525 struct ecommunity *ecommunity; 526 struct cluster_list *cluster; 527 struct transit *transit; 528 529 /* Decrement attribute reference. */ 530 attr->refcnt--; 531 aspath = attr->aspath; 532 community = attr->community; 533 ecommunity = attr->ecommunity; 534 cluster = attr->cluster; 535 transit = attr->transit; 536 537 /* If reference becomes zero then free attribute object. */ 538 if (attr->refcnt == 0) 539 { 540 ret = hash_release (attrhash, attr); 541 assert (ret != NULL); 542 XFREE (MTYPE_ATTR, attr); 543 } 544 545 /* aspath refcount shoud be decrement. */ 546 if (aspath) 547 aspath_unintern (aspath); 548 if (community) 549 community_unintern (community); 550 if (ecommunity) 551 ecommunity_unintern (ecommunity); 552 if (cluster) 553 cluster_unintern (cluster); 554 if (transit) 555 transit_unintern (transit); 556} 557 558void 559bgp_attr_flush (struct attr *attr) 560{ 561 if (attr->aspath && ! attr->aspath->refcnt) 562 aspath_free (attr->aspath); 563 if (attr->community && ! attr->community->refcnt) 564 community_free (attr->community); 565 if (attr->ecommunity && ! attr->ecommunity->refcnt) 566 ecommunity_free (attr->ecommunity); 567 if (attr->cluster && ! attr->cluster->refcnt) 568 cluster_free (attr->cluster); 569 if (attr->transit && ! attr->transit->refcnt) 570 transit_free (attr->transit); 571} 572 573/* Get origin attribute of the update message. */ 574int 575bgp_attr_origin (struct peer *peer, bgp_size_t length, 576 struct attr *attr, u_char flag, u_char *startp) 577{ 578 bgp_size_t total; 579 580 /* total is entire attribute length include Attribute Flags (1), 581 Attribute Type code (1) and Attribute length (1 or 2). */ 582 total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); 583 584 /* If any recognized attribute has Attribute Flags that conflict 585 with the Attribute Type Code, then the Error Subcode is set to 586 Attribute Flags Error. The Data field contains the erroneous 587 attribute (type, length and value). */ 588 if (flag != BGP_ATTR_FLAG_TRANS) 589 { 590 zlog (peer->log, LOG_ERR, 591 "Origin attribute flag isn't transitive %d", flag); 592 bgp_notify_send_with_data (peer, 593 BGP_NOTIFY_UPDATE_ERR, 594 BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, 595 startp, total); 596 return -1; 597 } 598 599 /* If any recognized attribute has Attribute Length that conflicts 600 with the expected length (based on the attribute type code), then 601 the Error Subcode is set to Attribute Length Error. The Data 602 field contains the erroneous attribute (type, length and 603 value). */ 604 if (length != 1) 605 { 606 zlog (peer->log, LOG_ERR, "Origin attribute length is not one %d", 607 length); 608 bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, 609 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, 610 startp, total); 611 return -1; 612 } 613 614 /* Fetch origin attribute. */ 615 attr->origin = stream_getc (BGP_INPUT (peer)); 616 617 /* If the ORIGIN attribute has an undefined value, then the Error 618 Subcode is set to Invalid Origin Attribute. The Data field 619 contains the unrecognized attribute (type, length and value). */ 620 if ((attr->origin != BGP_ORIGIN_IGP) 621 && (attr->origin != BGP_ORIGIN_EGP) 622 && (attr->origin != BGP_ORIGIN_INCOMPLETE)) 623 { 624 zlog (peer->log, LOG_ERR, "Origin attribute value is invalid %d", 625 attr->origin); 626 627 bgp_notify_send_with_data (peer, 628 BGP_NOTIFY_UPDATE_ERR, 629 BGP_NOTIFY_UPDATE_INVAL_ORIGIN, 630 startp, total); 631 return -1; 632 } 633 634 /* Set oring attribute flag. */ 635 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGIN); 636 637 return 0; 638} 639 640/* Parse AS path information. This function is wrapper of 641 aspath_parse. */ 642int 643bgp_attr_aspath (struct peer *peer, bgp_size_t length, 644 struct attr *attr, u_char flag, u_char *startp) 645{ 646 struct bgp *bgp; 647 struct aspath *aspath; 648 bgp_size_t total; 649 650 total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); 651 652 /* Flag check. */ 653 if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL) 654 || ! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) 655 { 656 zlog (peer->log, LOG_ERR, 657 "Origin attribute flag isn't transitive %d", flag); 658 bgp_notify_send_with_data (peer, 659 BGP_NOTIFY_UPDATE_ERR, 660 BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, 661 startp, total); 662 return -1; 663 } 664 665 /* In case of IBGP, length will be zero. */ 666 attr->aspath = aspath_parse (stream_pnt (peer->ibuf), length); 667 if (! attr->aspath) 668 { 669 zlog (peer->log, LOG_ERR, "Malformed AS path length is %d", length); 670 bgp_notify_send (peer, 671 BGP_NOTIFY_UPDATE_ERR, 672 BGP_NOTIFY_UPDATE_MAL_AS_PATH); 673 return -1; 674 } 675 676 bgp = peer->bgp; 677 678 /* First AS check for EBGP. */ 679 if (bgp != NULL && bgp_flag_check (bgp, BGP_FLAG_ENFORCE_FIRST_AS)) 680 { 681 if (peer_sort (peer) == BGP_PEER_EBGP 682 && ! aspath_firstas_check (attr->aspath, peer->as)) 683 { 684 zlog (peer->log, LOG_ERR, 685 "%s incorrect first AS (must be %d)", peer->host, peer->as); 686 bgp_notify_send (peer, 687 BGP_NOTIFY_UPDATE_ERR, 688 BGP_NOTIFY_UPDATE_MAL_AS_PATH); 689 return -1; 690 } 691 } 692 693 /* local-as prepend */ 694 if (peer->change_local_as && 695 ! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND)) 696 { 697 aspath = aspath_dup (attr->aspath); 698 aspath = aspath_add_seq (aspath, peer->change_local_as); 699 aspath_unintern (attr->aspath); 700 attr->aspath = aspath_intern (aspath); 701 } 702 703 /* Forward pointer. */ 704 stream_forward (peer->ibuf, length); 705 706 /* Set aspath attribute flag. */ 707 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATH); 708 709 return 0; 710} 711 712/* Nexthop attribute. */ 713int 714bgp_attr_nexthop (struct peer *peer, bgp_size_t length, 715 struct attr *attr, u_char flag, u_char *startp) 716{ 717 bgp_size_t total; 718 719 total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); 720 721 /* Flag check. */ 722 if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL) 723 || ! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) 724 { 725 zlog (peer->log, LOG_ERR, 726 "Origin attribute flag isn't transitive %d", flag); 727 bgp_notify_send_with_data (peer, 728 BGP_NOTIFY_UPDATE_ERR, 729 BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, 730 startp, total); 731 return -1; 732 } 733 734 /* Check nexthop attribute length. */ 735 if (length != 4) 736 { 737 zlog (peer->log, LOG_ERR, "Nexthop attribute length isn't four [%d]", 738 length); 739 740 bgp_notify_send_with_data (peer, 741 BGP_NOTIFY_UPDATE_ERR, 742 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, 743 startp, total); 744 return -1; 745 } 746 747 attr->nexthop.s_addr = stream_get_ipv4 (peer->ibuf); 748 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP); 749 750 return 0; 751} 752 753/* MED atrribute. */ 754int 755bgp_attr_med (struct peer *peer, bgp_size_t length, 756 struct attr *attr, u_char flag, u_char *startp) 757{ 758 bgp_size_t total; 759 760 total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); 761 762 /* Length check. */ 763 if (length != 4) 764 { 765 zlog (peer->log, LOG_ERR, 766 "MED attribute length isn't four [%d]", length); 767 768 bgp_notify_send_with_data (peer, 769 BGP_NOTIFY_UPDATE_ERR, 770 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR, 771 startp, total); 772 return -1; 773 } 774 775 attr->med = stream_getl (peer->ibuf); 776 777 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC); 778 779 return 0; 780} 781 782/* Local preference attribute. */ 783int 784bgp_attr_local_pref (struct peer *peer, bgp_size_t length, 785 struct attr *attr, u_char flag) 786{ 787 /* If it is contained in an UPDATE message that is received from an 788 external peer, then this attribute MUST be ignored by the 789 receiving speaker. */ 790 if (peer_sort (peer) == BGP_PEER_EBGP) 791 { 792 stream_forward (peer->ibuf, length); 793 return 0; 794 } 795 796 if (length == 4) 797 attr->local_pref = stream_getl (peer->ibuf); 798 else 799 attr->local_pref = 0; 800 801 /* Set atomic aggregate flag. */ 802 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF); 803 804 return 0; 805} 806 807/* Atomic aggregate. */ 808int 809bgp_attr_atomic (struct peer *peer, bgp_size_t length, 810 struct attr *attr, u_char flag) 811{ 812 if (length != 0) 813 { 814 zlog (peer->log, LOG_ERR, "Bad atomic aggregate length %d", length); 815 816 bgp_notify_send (peer, 817 BGP_NOTIFY_UPDATE_ERR, 818 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR); 819 return -1; 820 } 821 822 /* Set atomic aggregate flag. */ 823 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE); 824 825 return 0; 826} 827 828/* Aggregator attribute */ 829int 830bgp_attr_aggregator (struct peer *peer, bgp_size_t length, 831 struct attr *attr, u_char flag) 832{ 833 if (length != 6) 834 { 835 zlog (peer->log, LOG_ERR, "Aggregator length is not 6 [%d]", length); 836 837 bgp_notify_send (peer, 838 BGP_NOTIFY_UPDATE_ERR, 839 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR); 840 return -1; 841 } 842 attr->aggregator_as = stream_getw (peer->ibuf); 843 attr->aggregator_addr.s_addr = stream_get_ipv4 (peer->ibuf); 844 845 /* Set atomic aggregate flag. */ 846 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR); 847 848 return 0; 849} 850 851/* Community attribute. */ 852int 853bgp_attr_community (struct peer *peer, bgp_size_t length, 854 struct attr *attr, u_char flag) 855{ 856 if (length == 0) 857 attr->community = NULL; 858 else 859 { 860 attr->community = community_parse (stream_pnt (peer->ibuf), length); 861 stream_forward (peer->ibuf, length); 862 } 863 864 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES); 865 866 return 0; 867} 868 869/* Originator ID attribute. */ 870int 871bgp_attr_originator_id (struct peer *peer, bgp_size_t length, 872 struct attr *attr, u_char flag) 873{ 874 if (length != 4) 875 { 876 zlog (peer->log, LOG_ERR, "Bad originator ID length %d", length); 877 878 bgp_notify_send (peer, 879 BGP_NOTIFY_UPDATE_ERR, 880 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR); 881 return -1; 882 } 883 884 attr->originator_id.s_addr = stream_get_ipv4 (peer->ibuf); 885 886 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID); 887 888 return 0; 889} 890 891/* Cluster list attribute. */ 892int 893bgp_attr_cluster_list (struct peer *peer, bgp_size_t length, 894 struct attr *attr, u_char flag) 895{ 896 /* Check length. */ 897 if (length % 4) 898 { 899 zlog (peer->log, LOG_ERR, "Bad cluster list length %d", length); 900 901 bgp_notify_send (peer, 902 BGP_NOTIFY_UPDATE_ERR, 903 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR); 904 return -1; 905 } 906 907 attr->cluster = cluster_parse (stream_pnt (peer->ibuf), length); 908 909 stream_forward (peer->ibuf, length);; 910 911 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_CLUSTER_LIST); 912 913 return 0; 914} 915 916/* Multiprotocol reachability information parse. */ 917int 918bgp_mp_reach_parse (struct peer *peer, bgp_size_t length, struct attr *attr, 919 struct bgp_nlri *mp_update) 920{ 921 u_int16_t afi; 922 u_char safi; 923 u_char snpa_num; 924 u_char snpa_len; 925 u_char *lim; 926 bgp_size_t nlri_len; 927 int ret; 928 struct stream *s; 929 930 /* Set end of packet. */ 931 s = peer->ibuf; 932 lim = stream_pnt (s) + length; 933 934 /* Load AFI, SAFI. */ 935 afi = stream_getw (s); 936 safi = stream_getc (s); 937 938 /* Get nexthop length. */ 939 attr->mp_nexthop_len = stream_getc (s); 940 941 /* Nexthop length check. */ 942 switch (attr->mp_nexthop_len) 943 { 944 case 4: 945 stream_get (&attr->mp_nexthop_global_in, s, 4); 946 break; 947 case 12: 948 { 949 u_int32_t rd_high; 950 u_int32_t rd_low; 951 952 rd_high = stream_getl (s); 953 rd_low = stream_getl (s); 954 stream_get (&attr->mp_nexthop_global_in, s, 4); 955 } 956 break; 957#ifdef HAVE_IPV6 958 case 16: 959 stream_get (&attr->mp_nexthop_global, s, 16); 960 break; 961 case 32: 962 stream_get (&attr->mp_nexthop_global, s, 16); 963 stream_get (&attr->mp_nexthop_local, s, 16); 964 if (! IN6_IS_ADDR_LINKLOCAL (&attr->mp_nexthop_local)) 965 { 966 char buf1[INET6_ADDRSTRLEN]; 967 char buf2[INET6_ADDRSTRLEN]; 968 969 if (BGP_DEBUG (update, UPDATE_IN)) 970 zlog_warn ("%s got two nexthop %s %s but second one is not a link-local nexthop", peer->host, 971 inet_ntop (AF_INET6, &attr->mp_nexthop_global, 972 buf1, INET6_ADDRSTRLEN), 973 inet_ntop (AF_INET6, &attr->mp_nexthop_local, 974 buf2, INET6_ADDRSTRLEN)); 975 976 attr->mp_nexthop_len = 16; 977 } 978 break; 979#endif /* HAVE_IPV6 */ 980 default: 981 zlog_info ("Wrong multiprotocol next hop length: %d", 982 attr->mp_nexthop_len); 983 return -1; 984 break; 985 } 986 987 snpa_num = stream_getc (s); 988 989 while (snpa_num--) 990 { 991 snpa_len = stream_getc (s); 992 stream_forward (s, (snpa_len + 1) >> 1); 993 } 994 995 /* If peer is based on old draft-00. I read NLRI length from the 996 packet. */ 997 if (peer->version == BGP_VERSION_MP_4_DRAFT_00) 998 { 999 bgp_size_t nlri_total_len; 1000 nlri_total_len = stream_getw (s); 1001 } 1002 1003 nlri_len = lim - stream_pnt (s); 1004 1005 if (safi != BGP_SAFI_VPNV4) 1006 { 1007 ret = bgp_nlri_sanity_check (peer, afi, stream_pnt (s), nlri_len); 1008 if (ret < 0) 1009 return -1; 1010 } 1011 1012 mp_update->afi = afi; 1013 mp_update->safi = safi; 1014 mp_update->nlri = stream_pnt (s); 1015 mp_update->length = nlri_len; 1016 1017 stream_forward (s, nlri_len); 1018 1019 return 0; 1020} 1021 1022/* Multiprotocol unreachable parse */ 1023int 1024bgp_mp_unreach_parse (struct peer *peer, int length, 1025 struct bgp_nlri *mp_withdraw) 1026{ 1027 struct stream *s; 1028 u_int16_t afi; 1029 u_char safi; 1030 u_char *lim; 1031 u_int16_t withdraw_len; 1032 int ret; 1033 1034 s = peer->ibuf; 1035 lim = stream_pnt (s) + length; 1036 1037 afi = stream_getw (s); 1038 safi = stream_getc (s); 1039 1040 withdraw_len = lim - stream_pnt (s); 1041 1042 if (safi != BGP_SAFI_VPNV4) 1043 { 1044 ret = bgp_nlri_sanity_check (peer, afi, stream_pnt (s), withdraw_len); 1045 if (ret < 0) 1046 return -1; 1047 } 1048 1049 mp_withdraw->afi = afi; 1050 mp_withdraw->safi = safi; 1051 mp_withdraw->nlri = stream_pnt (s); 1052 mp_withdraw->length = withdraw_len; 1053 1054 stream_forward (s, withdraw_len); 1055 1056 return 0; 1057} 1058 1059/* Extended Community attribute. */ 1060int 1061bgp_attr_ext_communities (struct peer *peer, bgp_size_t length, 1062 struct attr *attr, u_char flag) 1063{ 1064 if (length == 0) 1065 attr->ecommunity = NULL; 1066 else 1067 { 1068 attr->ecommunity = ecommunity_parse (stream_pnt (peer->ibuf), length); 1069 stream_forward (peer->ibuf, length); 1070 } 1071 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES); 1072 1073 return 0; 1074} 1075 1076/* BGP unknown attribute treatment. */ 1077int 1078bgp_attr_unknown (struct peer *peer, struct attr *attr, u_char flag, 1079 u_char type, bgp_size_t length, u_char *startp) 1080{ 1081 bgp_size_t total; 1082 struct transit *transit; 1083 1084 if (BGP_DEBUG (events, EVENTS)) 1085 zlog (peer->log, LOG_INFO, 1086 "Unknown attribute type %d length %d is received", type, length); 1087 1088 /* Forward read pointer of input stream. */ 1089 stream_forward (peer->ibuf, length); 1090 1091 /* Adjest total length to include type and length. */ 1092 total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); 1093 1094 /* If any of the mandatory well-known attributes are not recognized, 1095 then the Error Subcode is set to Unrecognized Well-known 1096 Attribute. The Data field contains the unrecognized attribute 1097 (type, length and value). */ 1098 if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)) 1099 { 1100 /* Adjust startp to do not include flag value. */ 1101 bgp_notify_send_with_data (peer, 1102 BGP_NOTIFY_UPDATE_ERR, 1103 BGP_NOTIFY_UPDATE_UNREC_ATTR, 1104 startp, total); 1105 return -1; 1106 } 1107 1108 /* Unrecognized non-transitive optional attributes must be quietly 1109 ignored and not passed along to other BGP peers. */ 1110 if (! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) 1111 return 0; 1112 1113 /* If a path with recognized transitive optional attribute is 1114 accepted and passed along to other BGP peers and the Partial bit 1115 in the Attribute Flags octet is set to 1 by some previous AS, it 1116 is not set back to 0 by the current AS. */ 1117 SET_FLAG (*startp, BGP_ATTR_FLAG_PARTIAL); 1118 1119 /* Store transitive attribute to the end of attr->transit. */ 1120 if (! attr->transit) 1121 { 1122 attr->transit = XMALLOC (MTYPE_TRANSIT, sizeof (struct transit)); 1123 memset (attr->transit, 0, sizeof (struct transit)); 1124 } 1125 1126 transit = attr->transit; 1127 1128 if (transit->val) 1129 transit->val = XREALLOC (MTYPE_TRANSIT_VAL, transit->val, 1130 transit->length + total); 1131 else 1132 transit->val = XMALLOC (MTYPE_TRANSIT_VAL, total); 1133 1134 memcpy (transit->val + transit->length, startp, total); 1135 transit->length += total; 1136 1137 return 0; 1138} 1139 1140/* Read attribute of update packet. This function is called from 1141 bgp_update() in bgpd.c. */ 1142int 1143bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size, 1144 struct bgp_nlri *mp_update, struct bgp_nlri *mp_withdraw) 1145{ 1146 int ret; 1147 u_char flag; 1148 u_char type; 1149 bgp_size_t length; 1150 u_char *startp, *endp; 1151 u_char *attr_endp; 1152 u_char seen[BGP_ATTR_BITMAP_SIZE]; 1153 1154 /* Initialize bitmap. */ 1155 memset (seen, 0, BGP_ATTR_BITMAP_SIZE); 1156 1157 /* End pointer of BGP attribute. */ 1158 endp = BGP_INPUT_PNT (peer) + size; 1159 1160 /* Get attributes to the end of attribute length. */ 1161 while (BGP_INPUT_PNT (peer) < endp) 1162 { 1163 /* Check remaining length check.*/ 1164 if (endp - BGP_INPUT_PNT (peer) < BGP_ATTR_MIN_LEN) 1165 { 1166 zlog (peer->log, LOG_WARNING, 1167 "%s error BGP attribute length %d is smaller than min len", 1168 peer->host, endp - STREAM_PNT (BGP_INPUT (peer))); 1169 1170 bgp_notify_send (peer, 1171 BGP_NOTIFY_UPDATE_ERR, 1172 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR); 1173 return -1; 1174 } 1175 1176 /* Fetch attribute flag and type. */ 1177 startp = BGP_INPUT_PNT (peer); 1178 flag = stream_getc (BGP_INPUT (peer)); 1179 type = stream_getc (BGP_INPUT (peer)); 1180 1181 /* Check extended attribue length bit. */ 1182 if (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN)) 1183 length = stream_getw (BGP_INPUT (peer)); 1184 else 1185 length = stream_getc (BGP_INPUT (peer)); 1186 1187 /* If any attribute appears more than once in the UPDATE 1188 message, then the Error Subcode is set to Malformed Attribute 1189 List. */ 1190 1191 if (CHECK_BITMAP (seen, type)) 1192 { 1193 zlog (peer->log, LOG_WARNING, 1194 "%s error BGP attribute type %d appears twice in a message", 1195 peer->host, type); 1196 1197 bgp_notify_send (peer, 1198 BGP_NOTIFY_UPDATE_ERR, 1199 BGP_NOTIFY_UPDATE_MAL_ATTR); 1200 return -1; 1201 } 1202 1203 /* Set type to bitmap to check duplicate attribute. `type' is 1204 unsigned char so it never overflow bitmap range. */ 1205 1206 SET_BITMAP (seen, type); 1207 1208 /* Overflow check. */ 1209 attr_endp = BGP_INPUT_PNT (peer) + length; 1210 1211 if (attr_endp > endp) 1212 { 1213 zlog (peer->log, LOG_WARNING, 1214 "%s BGP type %d length %d is too large, attribute total length is %d. attr_endp is %p. endp is %p", peer->host, type, length, size, attr_endp, endp); 1215 bgp_notify_send (peer, 1216 BGP_NOTIFY_UPDATE_ERR, 1217 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR); 1218 return -1; 1219 } 1220 1221 /* OK check attribute and store it's value. */ 1222 switch (type) 1223 { 1224 case BGP_ATTR_ORIGIN: 1225 ret = bgp_attr_origin (peer, length, attr, flag, startp); 1226 break; 1227 case BGP_ATTR_AS_PATH: 1228 ret = bgp_attr_aspath (peer, length, attr, flag, startp); 1229 break; 1230 case BGP_ATTR_NEXT_HOP: 1231 ret = bgp_attr_nexthop (peer, length, attr, flag, startp); 1232 break; 1233 case BGP_ATTR_MULTI_EXIT_DISC: 1234 ret = bgp_attr_med (peer, length, attr, flag, startp); 1235 break; 1236 case BGP_ATTR_LOCAL_PREF: 1237 ret = bgp_attr_local_pref (peer, length, attr, flag); 1238 break; 1239 case BGP_ATTR_ATOMIC_AGGREGATE: 1240 ret = bgp_attr_atomic (peer, length, attr, flag); 1241 break; 1242 case BGP_ATTR_AGGREGATOR: 1243 ret = bgp_attr_aggregator (peer, length, attr, flag); 1244 break; 1245 case BGP_ATTR_COMMUNITIES: 1246 ret = bgp_attr_community (peer, length, attr, flag); 1247 break; 1248 case BGP_ATTR_ORIGINATOR_ID: 1249 ret = bgp_attr_originator_id (peer, length, attr, flag); 1250 break; 1251 case BGP_ATTR_CLUSTER_LIST: 1252 ret = bgp_attr_cluster_list (peer, length, attr, flag); 1253 break; 1254 case BGP_ATTR_MP_REACH_NLRI: 1255 ret = bgp_mp_reach_parse (peer, length, attr, mp_update); 1256 break; 1257 case BGP_ATTR_MP_UNREACH_NLRI: 1258 ret = bgp_mp_unreach_parse (peer, length, mp_withdraw); 1259 break; 1260 case BGP_ATTR_EXT_COMMUNITIES: 1261 ret = bgp_attr_ext_communities (peer, length, attr, flag); 1262 break; 1263 default: 1264 ret = bgp_attr_unknown (peer, attr, flag, type, length, startp); 1265 break; 1266 } 1267 1268 /* If error occured immediately return to the caller. */ 1269 if (ret < 0) 1270 return ret; 1271 1272 /* Check the fetched length. */ 1273 if (BGP_INPUT_PNT (peer) != attr_endp) 1274 { 1275 zlog (peer->log, LOG_WARNING, 1276 "%s BGP attribute fetch error", peer->host); 1277 bgp_notify_send (peer, 1278 BGP_NOTIFY_UPDATE_ERR, 1279 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR); 1280 return -1; 1281 } 1282 } 1283 1284 /* Check final read pointer is same as end pointer. */ 1285 if (BGP_INPUT_PNT (peer) != endp) 1286 { 1287 zlog (peer->log, LOG_WARNING, 1288 "%s BGP attribute length mismatch", peer->host); 1289 bgp_notify_send (peer, 1290 BGP_NOTIFY_UPDATE_ERR, 1291 BGP_NOTIFY_UPDATE_ATTR_LENG_ERR); 1292 return -1; 1293 } 1294 1295 /* Finally intern unknown attribute. */ 1296 if (attr->transit) 1297 attr->transit = transit_intern (attr->transit); 1298 1299 return 0; 1300} 1301 1302/* Well-known attribute check. */ 1303int 1304bgp_attr_check (struct peer *peer, struct attr *attr) 1305{ 1306 u_char type = 0; 1307 1308 if (! CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_ORIGIN))) 1309 type = BGP_ATTR_ORIGIN; 1310 1311 if (! CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AS_PATH))) 1312 type = BGP_ATTR_AS_PATH; 1313 1314 if (! CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP))) 1315 type = BGP_ATTR_NEXT_HOP; 1316 1317 if (peer_sort (peer) == BGP_PEER_IBGP 1318 && ! CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))) 1319 type = BGP_ATTR_LOCAL_PREF; 1320 1321 if (type) 1322 { 1323 zlog (peer->log, LOG_WARNING, 1324 "%s Missing well-known attribute %d.", 1325 peer->host, type); 1326 bgp_notify_send_with_data (peer, 1327 BGP_NOTIFY_UPDATE_ERR, 1328 BGP_NOTIFY_UPDATE_MISS_ATTR, 1329 &type, 1); 1330 return -1; 1331 } 1332 return 0; 1333} 1334 1335int stream_put_prefix (struct stream *, struct prefix *); 1336 1337/* Make attribute packet. */ 1338bgp_size_t 1339bgp_packet_attribute (struct bgp *bgp, struct peer *peer, 1340 struct stream *s, struct attr *attr, struct prefix *p, 1341 afi_t afi, safi_t safi, struct peer *from, 1342 struct prefix_rd *prd, u_char *tag) 1343{ 1344 unsigned long cp; 1345 struct aspath *aspath; 1346 1347 if (! bgp) 1348 bgp = bgp_get_default (); 1349 1350 /* Remember current pointer. */ 1351 cp = stream_get_putp (s); 1352 1353 /* Origin attribute. */ 1354 stream_putc (s, BGP_ATTR_FLAG_TRANS); 1355 stream_putc (s, BGP_ATTR_ORIGIN); 1356 stream_putc (s, 1); 1357 stream_putc (s, attr->origin); 1358 1359 /* AS path attribute. */ 1360 1361 /* If remote-peer is EBGP */ 1362 if (peer_sort (peer) == BGP_PEER_EBGP 1363 && (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED) 1364 || attr->aspath->length == 0) 1365 && ! (CHECK_FLAG (from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT) 1366 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))) 1367 { 1368 aspath = aspath_dup (attr->aspath); 1369 1370 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) 1371 { 1372 /* Strip the confed info, and then stuff our path CONFED_ID 1373 on the front */ 1374 aspath = aspath_delete_confed_seq (aspath); 1375 aspath = aspath_add_seq (aspath, bgp->confed_id); 1376 } 1377 else 1378 { 1379 aspath = aspath_add_seq (aspath, peer->local_as); 1380 if (peer->change_local_as) 1381 aspath = aspath_add_seq (aspath, peer->change_local_as); 1382 } 1383 } 1384 else if (peer_sort (peer) == BGP_PEER_CONFED) 1385 { 1386 /* A confed member, so we need to do the AS_CONFED_SEQUENCE thing */ 1387 aspath = aspath_dup (attr->aspath); 1388 aspath = aspath_add_confed_seq (aspath, peer->local_as); 1389 } 1390 else 1391 aspath = attr->aspath; 1392 1393 /* AS path attribute extended length bit check. */ 1394 if (aspath->length > 255) 1395 { 1396 stream_putc (s, BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN); 1397 stream_putc (s, BGP_ATTR_AS_PATH); 1398 stream_putw (s, aspath->length); 1399 } 1400 else 1401 { 1402 stream_putc (s, BGP_ATTR_FLAG_TRANS); 1403 stream_putc(s, BGP_ATTR_AS_PATH); 1404 stream_putc (s, aspath->length); 1405 } 1406 stream_put (s, aspath->data, aspath->length); 1407 1408 if (aspath != attr->aspath) 1409 aspath_free (aspath); 1410 1411 /* Nexthop attribute. */ 1412 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP) && afi == AFI_IP) 1413 { 1414 stream_putc (s, BGP_ATTR_FLAG_TRANS); 1415 stream_putc (s, BGP_ATTR_NEXT_HOP); 1416 stream_putc (s, 4); 1417 if (safi == SAFI_MPLS_VPN) 1418 { 1419 if (attr->nexthop.s_addr == 0) 1420 stream_put_ipv4 (s, peer->nexthop.v4.s_addr); 1421 else 1422 stream_put_ipv4 (s, attr->nexthop.s_addr); 1423 } 1424 else 1425 stream_put_ipv4 (s, attr->nexthop.s_addr); 1426 } 1427 1428 /* MED attribute. */ 1429 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)) 1430 { 1431 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL); 1432 stream_putc (s, BGP_ATTR_MULTI_EXIT_DISC); 1433 stream_putc (s, 4); 1434 stream_putl (s, attr->med); 1435 } 1436 1437 /* Local preference. */ 1438 if (peer_sort (peer) == BGP_PEER_IBGP || 1439 peer_sort (peer) == BGP_PEER_CONFED) 1440 { 1441 stream_putc (s, BGP_ATTR_FLAG_TRANS); 1442 stream_putc (s, BGP_ATTR_LOCAL_PREF); 1443 stream_putc (s, 4); 1444 stream_putl (s, attr->local_pref); 1445 } 1446 1447 /* Atomic aggregate. */ 1448 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE)) 1449 { 1450 stream_putc (s, BGP_ATTR_FLAG_TRANS); 1451 stream_putc (s, BGP_ATTR_ATOMIC_AGGREGATE); 1452 stream_putc (s, 0); 1453 } 1454 1455 /* Aggregator. */ 1456 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR)) 1457 { 1458 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS); 1459 stream_putc (s, BGP_ATTR_AGGREGATOR); 1460 stream_putc (s, 6); 1461 stream_putw (s, attr->aggregator_as); 1462 stream_put_ipv4 (s, attr->aggregator_addr.s_addr); 1463 } 1464 1465 /* Community attribute. */ 1466 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY) 1467 && (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES))) 1468 { 1469 if (attr->community->size * 4 > 255) 1470 { 1471 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN); 1472 stream_putc (s, BGP_ATTR_COMMUNITIES); 1473 stream_putw (s, attr->community->size * 4); 1474 } 1475 else 1476 { 1477 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS); 1478 stream_putc (s, BGP_ATTR_COMMUNITIES); 1479 stream_putc (s, attr->community->size * 4); 1480 } 1481 stream_put (s, attr->community->val, attr->community->size * 4); 1482 } 1483 1484 /* Route Reflector. */ 1485 if (peer_sort (peer) == BGP_PEER_IBGP 1486 && from 1487 && peer_sort (from) == BGP_PEER_IBGP) 1488 { 1489 /* Originator ID. */ 1490 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL); 1491 stream_putc (s, BGP_ATTR_ORIGINATOR_ID); 1492 stream_putc (s, 4); 1493 1494 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) 1495 stream_put_in_addr (s, &attr->originator_id); 1496 else 1497 { 1498 if (from) 1499 stream_put_in_addr (s, &from->remote_id); 1500 else 1501 stream_put_in_addr (s, &attr->originator_id); 1502 } 1503 1504 /* Cluster list. */ 1505 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL); 1506 stream_putc (s, BGP_ATTR_CLUSTER_LIST); 1507 1508 if (attr->cluster) 1509 { 1510 stream_putc (s, attr->cluster->length + 4); 1511 /* If this peer configuration's parent BGP has cluster_id. */ 1512 if (bgp->config & BGP_CONFIG_CLUSTER_ID) 1513 stream_put_in_addr (s, &bgp->cluster_id); 1514 else 1515 stream_put_in_addr (s, &bgp->router_id); 1516 stream_put (s, attr->cluster->list, attr->cluster->length); 1517 } 1518 else 1519 { 1520 stream_putc (s, 4); 1521 /* If this peer configuration's parent BGP has cluster_id. */ 1522 if (bgp->config & BGP_CONFIG_CLUSTER_ID) 1523 stream_put_in_addr (s, &bgp->cluster_id); 1524 else 1525 stream_put_in_addr (s, &bgp->router_id); 1526 } 1527 } 1528 1529#ifdef HAVE_IPV6 1530 /* If p is IPv6 address put it into attribute. */ 1531 if (p->family == AF_INET6) 1532 { 1533 unsigned long sizep; 1534 unsigned long draftp = 0; 1535 1536 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL); 1537 stream_putc (s, BGP_ATTR_MP_REACH_NLRI); 1538 sizep = stream_get_putp (s); 1539 stream_putc (s, 0); /* Length of this attribute. */ 1540 stream_putw (s, AFI_IP6); /* AFI */ 1541 stream_putc (s, safi); /* SAFI */ 1542 1543 stream_putc (s, attr->mp_nexthop_len); 1544 1545 if (attr->mp_nexthop_len == 16) 1546 stream_put (s, &attr->mp_nexthop_global, 16); 1547 else if (attr->mp_nexthop_len == 32) 1548 { 1549 stream_put (s, &attr->mp_nexthop_global, 16); 1550 stream_put (s, &attr->mp_nexthop_local, 16); 1551 } 1552 1553 /* SNPA */ 1554 stream_putc (s, 0); 1555 1556 /* In case of old draft BGP-4+. */ 1557 if (peer->version == BGP_VERSION_MP_4_DRAFT_00) 1558 { 1559 draftp = stream_get_putp (s); 1560 stream_putw (s, 0); 1561 } 1562 1563 /* Prefix write. */ 1564 stream_put_prefix (s, p); 1565 1566 /* Set MP attribute length. */ 1567 stream_putc_at (s, sizep, (stream_get_putp (s) - sizep) - 1); 1568 1569 /* In case of old draft BGP-4+. */ 1570 if (peer->version == BGP_VERSION_MP_4_DRAFT_00) 1571 stream_putw_at (s, draftp, (stream_get_putp (s) - draftp) - 2); 1572 } 1573#endif /* HAVE_IPV6 */ 1574 1575 if (p->family == AF_INET && safi == SAFI_MULTICAST) 1576 { 1577 unsigned long sizep; 1578 unsigned long draftp = 0; 1579 1580 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL); 1581 stream_putc (s, BGP_ATTR_MP_REACH_NLRI); 1582 sizep = stream_get_putp (s); 1583 stream_putc (s, 0); /* Length of this attribute. */ 1584 stream_putw (s, AFI_IP); /* AFI */ 1585 stream_putc (s, SAFI_MULTICAST); /* SAFI */ 1586 1587 stream_putc (s, 4); 1588 stream_put_ipv4 (s, attr->nexthop.s_addr); 1589 1590 /* SNPA */ 1591 stream_putc (s, 0); 1592 1593 /* In case of old draft BGP-4+. */ 1594 if (peer->version == BGP_VERSION_MP_4_DRAFT_00) 1595 { 1596 draftp = stream_get_putp (s); 1597 stream_putw (s, 0); 1598 } 1599 1600 /* Prefix write. */ 1601 stream_put_prefix (s, p); 1602 1603 /* Set MP attribute length. */ 1604 stream_putc_at (s, sizep, (stream_get_putp (s) - sizep) - 1); 1605 1606 /* In case of old draft BGP-4+. */ 1607 if (peer->version == BGP_VERSION_MP_4_DRAFT_00) 1608 stream_putw_at (s, draftp, (stream_get_putp (s) - draftp) - 2); 1609 } 1610 1611 if (p->family == AF_INET && safi == SAFI_MPLS_VPN) 1612 { 1613 unsigned long sizep; 1614 unsigned long draftp = 0; 1615 1616 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL); 1617 stream_putc (s, BGP_ATTR_MP_REACH_NLRI); 1618 sizep = stream_get_putp (s); 1619 stream_putc (s, 0); /* Length of this attribute. */ 1620 stream_putw (s, AFI_IP); /* AFI */ 1621 stream_putc (s, BGP_SAFI_VPNV4); /* SAFI */ 1622 1623 stream_putc (s, 12); 1624 stream_putl (s, 0); 1625 stream_putl (s, 0); 1626 stream_put (s, &attr->mp_nexthop_global_in, 4); 1627 1628 /* SNPA */ 1629 stream_putc (s, 0); 1630 1631 /* In case of old draft BGP-4+. */ 1632 if (peer->version == BGP_VERSION_MP_4_DRAFT_00) 1633 { 1634 draftp = stream_get_putp (s); 1635 stream_putw (s, 0); 1636 } 1637 1638 /* Tag, RD, Prefix write. */ 1639 stream_putc (s, p->prefixlen + 88); 1640 stream_put (s, tag, 3); 1641 stream_put (s, prd->val, 8); 1642 stream_put (s, &p->u.prefix, PSIZE (p->prefixlen)); 1643 1644 /* Set MP attribute length. */ 1645 stream_putc_at (s, sizep, (stream_get_putp (s) - sizep) - 1); 1646 1647 /* In case of old draft BGP-4+. */ 1648 if (peer->version == BGP_VERSION_MP_4_DRAFT_00) 1649 stream_putw_at (s, draftp, (stream_get_putp (s) - draftp) - 2); 1650 } 1651 1652 /* Extended Communities attribute. */ 1653 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY) 1654 && (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES))) 1655 { 1656 if (attr->ecommunity->size * 8 > 255) 1657 { 1658 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN); 1659 stream_putc (s, BGP_ATTR_EXT_COMMUNITIES); 1660 stream_putw (s, attr->ecommunity->size * 8); 1661 } 1662 else 1663 { 1664 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS); 1665 stream_putc (s, BGP_ATTR_EXT_COMMUNITIES); 1666 stream_putc (s, attr->ecommunity->size * 8); 1667 } 1668 stream_put (s, attr->ecommunity->val, attr->ecommunity->size * 8); 1669 } 1670 1671 /* Unknown transit attribute. */ 1672 if (attr->transit) 1673 stream_put (s, attr->transit->val, attr->transit->length); 1674 1675 /* Return total size of attribute. */ 1676 return stream_get_putp (s) - cp; 1677} 1678 1679bgp_size_t 1680bgp_packet_withdraw (struct peer *peer, struct stream *s, struct prefix *p, 1681 afi_t afi, safi_t safi, struct prefix_rd *prd, 1682 u_char *tag) 1683{ 1684 unsigned long cp; 1685 unsigned long attrlen_pnt; 1686 bgp_size_t size; 1687 1688 cp = stream_get_putp (s); 1689 1690 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL); 1691 stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI); 1692 1693 attrlen_pnt = stream_get_putp (s); 1694 stream_putc (s, 0); /* Length of this attribute. */ 1695 1696 stream_putw (s, family2afi (p->family)); 1697 1698 if (safi == SAFI_MPLS_VPN) 1699 { 1700 /* SAFI */ 1701 stream_putc (s, BGP_SAFI_VPNV4); 1702 1703 /* prefix. */ 1704 stream_putc (s, p->prefixlen + 88); 1705 stream_put (s, tag, 3); 1706 stream_put (s, prd->val, 8); 1707 stream_put (s, &p->u.prefix, PSIZE (p->prefixlen)); 1708 } 1709 else 1710 { 1711 /* SAFI */ 1712 stream_putc (s, safi); 1713 1714 /* prefix */ 1715 stream_put_prefix (s, p); 1716 } 1717 1718 /* Set MP attribute length. */ 1719 size = stream_get_putp (s) - attrlen_pnt - 1; 1720 stream_putc_at (s, attrlen_pnt, size); 1721 1722 return stream_get_putp (s) - cp; 1723} 1724 1725/* Initialization of attribute. */ 1726void 1727bgp_attr_init () 1728{ 1729 void attrhash_init (); 1730 1731 aspath_init (); 1732 attrhash_init (); 1733 community_init (); 1734 ecommunity_init (); 1735 cluster_init (); 1736 transit_init (); 1737} 1738 1739/* Make attribute packet. */ 1740void 1741bgp_dump_routes_attr (struct stream *s, struct attr *attr) 1742{ 1743 unsigned long cp; 1744 unsigned long len; 1745 struct aspath *aspath; 1746 1747 /* Remember current pointer. */ 1748 cp = stream_get_putp (s); 1749 1750 /* Place holder of length. */ 1751 stream_putw (s, 0); 1752 1753 /* Origin attribute. */ 1754 stream_putc (s, BGP_ATTR_FLAG_TRANS); 1755 stream_putc (s, BGP_ATTR_ORIGIN); 1756 stream_putc (s, 1); 1757 stream_putc (s, attr->origin); 1758 1759 aspath = attr->aspath; 1760 1761 if (aspath->length > 255) 1762 { 1763 stream_putc (s, BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN); 1764 stream_putc (s, BGP_ATTR_AS_PATH); 1765 stream_putw (s, aspath->length); 1766 } 1767 else 1768 { 1769 stream_putc (s, BGP_ATTR_FLAG_TRANS); 1770 stream_putc (s, BGP_ATTR_AS_PATH); 1771 stream_putc (s, aspath->length); 1772 } 1773 stream_put (s, aspath->data, aspath->length); 1774 1775 /* Nexthop attribute. */ 1776 stream_putc (s, BGP_ATTR_FLAG_TRANS); 1777 stream_putc (s, BGP_ATTR_NEXT_HOP); 1778 stream_putc (s, 4); 1779 stream_put_ipv4 (s, attr->nexthop.s_addr); 1780 1781 /* MED attribute. */ 1782 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)) 1783 { 1784 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL); 1785 stream_putc (s, BGP_ATTR_MULTI_EXIT_DISC); 1786 stream_putc (s, 4); 1787 stream_putl (s, attr->med); 1788 } 1789 1790 /* Local preference. */ 1791 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)) 1792 { 1793 stream_putc (s, BGP_ATTR_FLAG_TRANS); 1794 stream_putc (s, BGP_ATTR_LOCAL_PREF); 1795 stream_putc (s, 4); 1796 stream_putl (s, attr->local_pref); 1797 } 1798 1799 /* Atomic aggregate. */ 1800 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE)) 1801 { 1802 stream_putc (s, BGP_ATTR_FLAG_TRANS); 1803 stream_putc (s, BGP_ATTR_ATOMIC_AGGREGATE); 1804 stream_putc (s, 0); 1805 } 1806 1807 /* Aggregator. */ 1808 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR)) 1809 { 1810 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS); 1811 stream_putc (s, BGP_ATTR_AGGREGATOR); 1812 stream_putc (s, 6); 1813 stream_putw (s, attr->aggregator_as); 1814 stream_put_ipv4 (s, attr->aggregator_addr.s_addr); 1815 } 1816 1817 /* Community attribute. */ 1818 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES)) 1819 { 1820 if (attr->community->size * 4 > 255) 1821 { 1822 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN); 1823 stream_putc (s, BGP_ATTR_COMMUNITIES); 1824 stream_putw (s, attr->community->size * 4); 1825 } 1826 else 1827 { 1828 stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS); 1829 stream_putc (s, BGP_ATTR_COMMUNITIES); 1830 stream_putc (s, attr->community->size * 4); 1831 } 1832 stream_put (s, attr->community->val, attr->community->size * 4); 1833 } 1834 1835 /* Return total size of attribute. */ 1836 len = stream_get_putp (s) - cp - 2; 1837 stream_putw_at (s, cp, len); 1838} 1839