1/* BGP-4, BGP-4+ daemon program 2 Copyright (C) 1996, 97, 98, 99, 2000 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 "prefix.h" 24#include "thread.h" 25#include "buffer.h" 26#include "stream.h" 27#include "command.h" 28#include "sockunion.h" 29#include "network.h" 30#include "memory.h" 31#include "filter.h" 32#include "routemap.h" 33#include "str.h" 34#include "log.h" 35#include "plist.h" 36#include "linklist.h" 37 38#include "bgpd/bgpd.h" 39#include "bgpd/bgp_table.h" 40#include "bgpd/bgp_aspath.h" 41#include "bgpd/bgp_route.h" 42#include "bgpd/bgp_dump.h" 43#include "bgpd/bgp_debug.h" 44#include "bgpd/bgp_community.h" 45#include "bgpd/bgp_attr.h" 46#include "bgpd/bgp_regex.h" 47#include "bgpd/bgp_clist.h" 48#include "bgpd/bgp_fsm.h" 49#include "bgpd/bgp_packet.h" 50#include "bgpd/bgp_zebra.h" 51#include "bgpd/bgp_open.h" 52#include "bgpd/bgp_filter.h" 53#include "bgpd/bgp_nexthop.h" 54#include "bgpd/bgp_damp.h" 55#include "bgpd/bgp_mplsvpn.h" 56#include "bgpd/bgp_advertise.h" 57#include "bgpd/bgp_network.h" 58#include "bgpd/bgp_vty.h" 59#ifdef HAVE_SNMP 60#include "bgpd/bgp_snmp.h" 61#endif /* HAVE_SNMP */ 62 63/* BGP process wide configuration. */ 64static struct bgp_master bgp_master; 65 66/* BGP process wide configuration pointer to export. */ 67struct bgp_master *bm; 68 69/* BGP community-list. */ 70struct community_list_handler *bgp_clist; 71 72/* BGP global flag manipulation. */ 73int 74bgp_option_set (int flag) 75{ 76 switch (flag) 77 { 78 case BGP_OPT_NO_FIB: 79 case BGP_OPT_MULTIPLE_INSTANCE: 80 case BGP_OPT_CONFIG_CISCO: 81 SET_FLAG (bm->options, flag); 82 break; 83 default: 84 return BGP_ERR_INVALID_FLAG; 85 break; 86 } 87 return 0; 88} 89 90int 91bgp_option_unset (int flag) 92{ 93 switch (flag) 94 { 95 case BGP_OPT_MULTIPLE_INSTANCE: 96 if (listcount (bm->bgp) > 1) 97 return BGP_ERR_MULTIPLE_INSTANCE_USED; 98 /* Fall through. */ 99 case BGP_OPT_NO_FIB: 100 case BGP_OPT_CONFIG_CISCO: 101 UNSET_FLAG (bm->options, flag); 102 break; 103 default: 104 return BGP_ERR_INVALID_FLAG; 105 break; 106 } 107 return 0; 108} 109 110int 111bgp_option_check (int flag) 112{ 113 return CHECK_FLAG (bm->options, flag); 114} 115 116/* BGP flag manipulation. */ 117int 118bgp_flag_set (struct bgp *bgp, int flag) 119{ 120 SET_FLAG (bgp->flags, flag); 121 return 0; 122} 123 124int 125bgp_flag_unset (struct bgp *bgp, int flag) 126{ 127 UNSET_FLAG (bgp->flags, flag); 128 return 0; 129} 130 131int 132bgp_flag_check (struct bgp *bgp, int flag) 133{ 134 return CHECK_FLAG (bgp->flags, flag); 135} 136 137/* Internal function to set BGP structure configureation flag. */ 138static void 139bgp_config_set (struct bgp *bgp, int config) 140{ 141 SET_FLAG (bgp->config, config); 142} 143 144static void 145bgp_config_unset (struct bgp *bgp, int config) 146{ 147 UNSET_FLAG (bgp->config, config); 148} 149 150static int 151bgp_config_check (struct bgp *bgp, int config) 152{ 153 return CHECK_FLAG (bgp->config, config); 154} 155 156/* Set BGP router identifier. */ 157int 158bgp_router_id_set (struct bgp *bgp, struct in_addr *id) 159{ 160 struct peer *peer; 161 struct listnode *nn; 162 163 if (bgp_config_check (bgp, BGP_CONFIG_ROUTER_ID) 164 && IPV4_ADDR_SAME (&bgp->router_id, id)) 165 return 0; 166 167 IPV4_ADDR_COPY (&bgp->router_id, id); 168 bgp_config_set (bgp, BGP_CONFIG_ROUTER_ID); 169 170 /* Set all peer's local identifier with this value. */ 171 LIST_LOOP (bgp->peer, peer, nn) 172 { 173 IPV4_ADDR_COPY (&peer->local_id, id); 174 175 if (peer->status == Established) 176 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 177 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 178 } 179 return 0; 180} 181 182/* Unset BGP router identifier. */ 183int 184bgp_router_id_unset (struct bgp *bgp) 185{ 186 struct peer *peer; 187 struct listnode *nn; 188 189 if (! bgp_config_check (bgp, BGP_CONFIG_ROUTER_ID)) 190 return 0; 191 192 bgp->router_id.s_addr = 0; 193 bgp_config_unset (bgp, BGP_CONFIG_ROUTER_ID); 194 195 /* Clear peer router id configuration. */ 196 LIST_LOOP (bgp->peer, peer, nn) 197 { 198 peer->local_id.s_addr = 0; 199 } 200 201 /* Set router-id from interface's address. */ 202 bgp_if_update_all (); 203 204 /* Reset all BGP sessions to use new router-id. */ 205 LIST_LOOP (bgp->peer, peer, nn) 206 { 207 if (peer->status == Established) 208 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 209 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 210 } 211 212 return 0; 213} 214 215/* BGP's cluster-id control. */ 216int 217bgp_cluster_id_set (struct bgp *bgp, struct in_addr *cluster_id) 218{ 219 struct peer *peer; 220 struct listnode *nn; 221 222 if (bgp_config_check (bgp, BGP_CONFIG_CLUSTER_ID) 223 && IPV4_ADDR_SAME (&bgp->cluster_id, cluster_id)) 224 return 0; 225 226 IPV4_ADDR_COPY (&bgp->cluster_id, cluster_id); 227 bgp_config_set (bgp, BGP_CONFIG_CLUSTER_ID); 228 229 /* Clear all IBGP peer. */ 230 LIST_LOOP (bgp->peer, peer, nn) 231 { 232 if (peer_sort (peer) != BGP_PEER_IBGP) 233 continue; 234 235 if (peer->status == Established) 236 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 237 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 238 } 239 return 0; 240} 241 242int 243bgp_cluster_id_unset (struct bgp *bgp) 244{ 245 struct peer *peer; 246 struct listnode *nn; 247 248 if (! bgp_config_check (bgp, BGP_CONFIG_CLUSTER_ID)) 249 return 0; 250 251 bgp->cluster_id.s_addr = 0; 252 bgp_config_unset (bgp, BGP_CONFIG_CLUSTER_ID); 253 254 /* Clear all IBGP peer. */ 255 LIST_LOOP (bgp->peer, peer, nn) 256 { 257 if (peer_sort (peer) != BGP_PEER_IBGP) 258 continue; 259 260 if (peer->status == Established) 261 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 262 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 263 } 264 return 0; 265} 266 267/* BGP timer configuration. */ 268int 269bgp_timers_set (struct bgp *bgp, u_int32_t keepalive, u_int32_t holdtime) 270{ 271 bgp->default_keepalive = (keepalive < holdtime / 3 272 ? keepalive : holdtime / 3); 273 bgp->default_holdtime = holdtime; 274 275 return 0; 276} 277 278int 279bgp_timers_unset (struct bgp *bgp) 280{ 281 bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE; 282 bgp->default_holdtime = BGP_DEFAULT_HOLDTIME; 283 284 return 0; 285} 286 287/* BGP confederation configuration. */ 288int 289bgp_confederation_id_set (struct bgp *bgp, as_t as) 290{ 291 struct peer *peer; 292 struct listnode *nn; 293 int already_confed; 294 295 if (as == 0) 296 return BGP_ERR_INVALID_AS; 297 298 /* Remember - were we doing confederation before? */ 299 already_confed = bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION); 300 bgp->confed_id = as; 301 bgp_config_set (bgp, BGP_CONFIG_CONFEDERATION); 302 303 /* If we were doing confederation already, this is just an external 304 AS change. Just Reset EBGP sessions, not CONFED sessions. If we 305 were not doing confederation before, reset all EBGP sessions. */ 306 LIST_LOOP (bgp->peer, peer, nn) 307 { 308 /* We're looking for peers who's AS is not local or part of our 309 confederation. */ 310 if (already_confed) 311 { 312 if (peer_sort (peer) == BGP_PEER_EBGP) 313 { 314 peer->local_as = as; 315 if (peer->status == Established) 316 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 317 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 318 else 319 BGP_EVENT_ADD (peer, BGP_Stop); 320 } 321 } 322 else 323 { 324 /* Not doign confederation before, so reset every non-local 325 session */ 326 if (peer_sort (peer) != BGP_PEER_IBGP) 327 { 328 /* Reset the local_as to be our EBGP one */ 329 if (peer_sort (peer) == BGP_PEER_EBGP) 330 peer->local_as = as; 331 if (peer->status == Established) 332 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 333 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 334 else 335 BGP_EVENT_ADD (peer, BGP_Stop); 336 } 337 } 338 } 339 return 0; 340} 341 342int 343bgp_confederation_id_unset (struct bgp *bgp) 344{ 345 struct peer *peer; 346 struct listnode *nn; 347 348 bgp->confed_id = 0; 349 bgp_config_unset (bgp, BGP_CONFIG_CONFEDERATION); 350 351 LIST_LOOP (bgp->peer, peer, nn) 352 { 353 /* We're looking for peers who's AS is not local */ 354 if (peer_sort (peer) != BGP_PEER_IBGP) 355 { 356 peer->local_as = bgp->as; 357 if (peer->status == Established) 358 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 359 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 360 else 361 BGP_EVENT_ADD (peer, BGP_Stop); 362 } 363 } 364 return 0; 365} 366 367/* Is an AS part of the confed or not? */ 368int 369bgp_confederation_peers_check (struct bgp *bgp, as_t as) 370{ 371 int i; 372 373 if (! bgp) 374 return 0; 375 376 for (i = 0; i < bgp->confed_peers_cnt; i++) 377 if (bgp->confed_peers[i] == as) 378 return 1; 379 380 return 0; 381} 382 383/* Add an AS to the confederation set. */ 384int 385bgp_confederation_peers_add (struct bgp *bgp, as_t as) 386{ 387 struct peer *peer; 388 struct listnode *nn; 389 390 if (! bgp) 391 return BGP_ERR_INVALID_BGP; 392 393 if (bgp->as == as) 394 return BGP_ERR_INVALID_AS; 395 396 if (bgp_confederation_peers_check (bgp, as)) 397 return -1; 398 399 if (bgp->confed_peers) 400 bgp->confed_peers = XREALLOC (MTYPE_BGP_CONFED_LIST, 401 bgp->confed_peers, 402 (bgp->confed_peers_cnt + 1) * sizeof (as_t)); 403 else 404 bgp->confed_peers = XMALLOC (MTYPE_BGP_CONFED_LIST, 405 (bgp->confed_peers_cnt + 1) * sizeof (as_t)); 406 407 bgp->confed_peers[bgp->confed_peers_cnt] = as; 408 bgp->confed_peers_cnt++; 409 410 if (bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION)) 411 { 412 LIST_LOOP (bgp->peer, peer, nn) 413 { 414 if (peer->as == as) 415 { 416 peer->local_as = bgp->as; 417 if (peer->status == Established) 418 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 419 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 420 else 421 BGP_EVENT_ADD (peer, BGP_Stop); 422 } 423 } 424 } 425 return 0; 426} 427 428/* Delete an AS from the confederation set. */ 429int 430bgp_confederation_peers_remove (struct bgp *bgp, as_t as) 431{ 432 int i; 433 int j; 434 struct peer *peer; 435 struct listnode *nn; 436 437 if (! bgp) 438 return -1; 439 440 if (! bgp_confederation_peers_check (bgp, as)) 441 return -1; 442 443 for (i = 0; i < bgp->confed_peers_cnt; i++) 444 if (bgp->confed_peers[i] == as) 445 for(j = i + 1; j < bgp->confed_peers_cnt; j++) 446 bgp->confed_peers[j - 1] = bgp->confed_peers[j]; 447 448 bgp->confed_peers_cnt--; 449 450 if (bgp->confed_peers_cnt == 0) 451 { 452 if (bgp->confed_peers) 453 XFREE (MTYPE_BGP_CONFED_LIST, bgp->confed_peers); 454 bgp->confed_peers = NULL; 455 } 456 else 457 bgp->confed_peers = XREALLOC (MTYPE_BGP_CONFED_LIST, 458 bgp->confed_peers, 459 bgp->confed_peers_cnt * sizeof (as_t)); 460 461 /* Now reset any peer who's remote AS has just been removed from the 462 CONFED */ 463 if (bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION)) 464 { 465 LIST_LOOP (bgp->peer, peer, nn) 466 { 467 if (peer->as == as) 468 { 469 peer->local_as = bgp->confed_id; 470 if (peer->status == Established) 471 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 472 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 473 else 474 BGP_EVENT_ADD (peer, BGP_Stop); 475 } 476 } 477 } 478 479 return 0; 480} 481 482/* Local preference configuration. */ 483int 484bgp_default_local_preference_set (struct bgp *bgp, u_int32_t local_pref) 485{ 486 if (! bgp) 487 return -1; 488 489 bgp_config_set (bgp, BGP_CONFIG_DEFAULT_LOCAL_PREF); 490 bgp->default_local_pref = local_pref; 491 492 return 0; 493} 494 495int 496bgp_default_local_preference_unset (struct bgp *bgp) 497{ 498 if (! bgp) 499 return -1; 500 501 bgp_config_unset (bgp, BGP_CONFIG_DEFAULT_LOCAL_PREF); 502 bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF; 503 504 return 0; 505} 506 507/* Peer comparison function for sorting. */ 508static int 509peer_cmp (struct peer *p1, struct peer *p2) 510{ 511 return sockunion_cmp (&p1->su, &p2->su); 512} 513 514int 515peer_af_flag_check (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag) 516{ 517 return CHECK_FLAG (peer->af_flags[afi][safi], flag); 518} 519 520/* Reset all address family specific configuration. */ 521static void 522peer_af_flag_reset (struct peer *peer, afi_t afi, safi_t safi) 523{ 524 int i; 525 struct bgp_filter *filter; 526 char orf_name[BUFSIZ]; 527 528 filter = &peer->filter[afi][safi]; 529 530 /* Clear neighbor filter and route-map */ 531 for (i = FILTER_IN; i < FILTER_MAX; i++) 532 { 533 if (filter->dlist[i].name) 534 { 535 free (filter->dlist[i].name); 536 filter->dlist[i].name = NULL; 537 } 538 if (filter->plist[i].name) 539 { 540 free (filter->plist[i].name); 541 filter->plist[i].name = NULL; 542 } 543 if (filter->aslist[i].name) 544 { 545 free (filter->aslist[i].name); 546 filter->aslist[i].name = NULL; 547 } 548 if (filter->map[i].name) 549 { 550 free (filter->map[i].name); 551 filter->map[i].name = NULL; 552 } 553 } 554 555 /* Clear unsuppress map. */ 556 if (filter->usmap.name) 557 free (filter->usmap.name); 558 filter->usmap.name = NULL; 559 filter->usmap.map = NULL; 560 561 /* Clear neighbor's all address family flags. */ 562 peer->af_flags[afi][safi] = 0; 563 564 /* Clear neighbor's all address family sflags. */ 565 peer->af_sflags[afi][safi] = 0; 566 567 /* Clear neighbor's all address family capabilities. */ 568 peer->af_cap[afi][safi] = 0; 569 570 /* Clear ORF info */ 571 peer->orf_plist[afi][safi] = NULL; 572 sprintf (orf_name, "%s.%d.%d", peer->host, afi, safi); 573 prefix_bgp_orf_remove_all (orf_name); 574 575 /* Set default neighbor send-community. */ 576 if (! bgp_option_check (BGP_OPT_CONFIG_CISCO)) 577 { 578 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY); 579 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY); 580 } 581 582 /* Clear neighbor default_originate_rmap */ 583 if (peer->default_rmap[afi][safi].name) 584 free (peer->default_rmap[afi][safi].name); 585 peer->default_rmap[afi][safi].name = NULL; 586 peer->default_rmap[afi][safi].map = NULL; 587 588 /* Clear neighbor maximum-prefix */ 589 peer->pmax[afi][safi] = 0; 590 peer->pmax_warning[afi][safi] = 0; 591} 592 593/* peer global config reset */ 594void 595peer_global_config_reset (struct peer *peer) 596{ 597 peer->weight = 0; 598 peer->change_local_as = 0; 599 peer->ttl = (peer_sort (peer) == BGP_PEER_IBGP ? 255 : 1); 600 if (peer->update_source) 601 { 602 sockunion_free (peer->update_source); 603 peer->update_source = NULL; 604 } 605 if (peer->update_if) 606 { 607 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if); 608 peer->update_if = NULL; 609 } 610 611 if (peer_sort (peer) == BGP_PEER_IBGP) 612 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV; 613 else 614 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV; 615 616 peer->flags = 0; 617 peer->config = 0; 618 peer->holdtime = 0; 619 peer->keepalive = 0; 620 peer->connect = 0; 621 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY; 622} 623 624/* Check peer's AS number and determin is this peer IBGP or EBGP */ 625int 626peer_sort (struct peer *peer) 627{ 628 struct bgp *bgp; 629 630 bgp = peer->bgp; 631 632 /* Peer-group */ 633 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 634 { 635 if (peer->as) 636 return (bgp->as == peer->as ? BGP_PEER_IBGP : BGP_PEER_EBGP); 637 else 638 { 639 struct peer *peer1; 640 peer1 = listnode_head (peer->group->peer); 641 if (peer1) 642 return (peer1->local_as == peer1->as 643 ? BGP_PEER_IBGP : BGP_PEER_EBGP); 644 } 645 return BGP_PEER_INTERNAL; 646 } 647 648 /* Normal peer */ 649 if (bgp && CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION)) 650 { 651 if (peer->local_as == 0) 652 return BGP_PEER_INTERNAL; 653 654 if (peer->local_as == peer->as) 655 { 656 if (peer->local_as == bgp->confed_id) 657 return BGP_PEER_EBGP; 658 else 659 return BGP_PEER_IBGP; 660 } 661 662 if (bgp_confederation_peers_check (bgp, peer->as)) 663 return BGP_PEER_CONFED; 664 665 return BGP_PEER_EBGP; 666 } 667 else 668 { 669 return (peer->local_as == 0 670 ? BGP_PEER_INTERNAL : peer->local_as == peer->as 671 ? BGP_PEER_IBGP : BGP_PEER_EBGP); 672 } 673} 674 675/* Allocate new peer object. */ 676static struct peer * 677peer_new () 678{ 679 afi_t afi; 680 safi_t safi; 681 struct peer *peer; 682 struct servent *sp; 683 684 /* Allocate new peer. */ 685 peer = XMALLOC (MTYPE_BGP_PEER, sizeof (struct peer)); 686 memset (peer, 0, sizeof (struct peer)); 687 688 /* Set default value. */ 689 peer->fd = -1; 690 peer->v_start = BGP_INIT_START_TIMER; 691 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY; 692 peer->v_asorig = BGP_DEFAULT_ASORIGINATE; 693 peer->status = Idle; 694 peer->ostatus = Idle; 695 peer->version = BGP_VERSION_4; 696 peer->weight = 0; 697 698 /* Set default flags. */ 699 for (afi = AFI_IP; afi < AFI_MAX; afi++) 700 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) 701 { 702 if (! bgp_option_check (BGP_OPT_CONFIG_CISCO)) 703 { 704 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY); 705 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY); 706 } 707 peer->orf_plist[afi][safi] = NULL; 708 } 709 SET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN); 710 711 /* Create buffers. */ 712 peer->ibuf = stream_new (BGP_MAX_PACKET_SIZE); 713 peer->obuf = stream_fifo_new (); 714 peer->work = stream_new (BGP_MAX_PACKET_SIZE); 715 716 bgp_sync_init (peer); 717 718 /* Get service port number. */ 719 sp = getservbyname ("bgp", "tcp"); 720 peer->port = (sp == NULL) ? BGP_PORT_DEFAULT : ntohs (sp->s_port); 721 722 return peer; 723} 724 725/* Create new BGP peer. */ 726struct peer * 727peer_create (union sockunion *su, struct bgp *bgp, as_t local_as, 728 as_t remote_as, afi_t afi, safi_t safi) 729{ 730 int active; 731 struct peer *peer; 732 char buf[SU_ADDRSTRLEN]; 733 734 peer = peer_new (); 735 peer->bgp = bgp; 736 peer->su = *su; 737 peer->local_as = local_as; 738 peer->as = remote_as; 739 peer->local_id = bgp->router_id; 740 peer->v_holdtime = bgp->default_holdtime; 741 peer->v_keepalive = bgp->default_keepalive; 742 if (peer_sort (peer) == BGP_PEER_IBGP) 743 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV; 744 else 745 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV; 746 listnode_add_sort (bgp->peer, peer); 747 748 active = peer_active (peer); 749 750 if (afi && safi) 751 peer->afc[afi][safi] = 1; 752 753 /* Last read time set */ 754 peer->readtime = time (NULL); 755 756 /* Default TTL set. */ 757 peer->ttl = (peer_sort (peer) == BGP_PEER_IBGP ? 255 : 1); 758 759 /* Make peer's address string. */ 760 sockunion2str (su, buf, SU_ADDRSTRLEN); 761 peer->host = strdup (buf); 762 763 /* Set up peer's events and timers. */ 764 if (! active && peer_active (peer)) 765 bgp_timer_set (peer); 766 767 return peer; 768} 769 770/* Make accept BGP peer. Called from bgp_accept (). */ 771struct peer * 772peer_create_accept (struct bgp *bgp) 773{ 774 struct peer *peer; 775 776 peer = peer_new (); 777 peer->bgp = bgp; 778 listnode_add_sort (bgp->peer, peer); 779 780 return peer; 781} 782 783/* Change peer's AS number. */ 784void 785peer_as_change (struct peer *peer, as_t as) 786{ 787 int type; 788 789 /* Stop peer. */ 790 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 791 { 792 if (peer->status == Established) 793 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 794 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 795 else 796 BGP_EVENT_ADD (peer, BGP_Stop); 797 } 798 type = peer_sort (peer); 799 peer->as = as; 800 801 /* Advertisement-interval reset */ 802 if (peer_sort (peer) == BGP_PEER_IBGP) 803 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV; 804 else 805 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV; 806 807 /* TTL reset */ 808 if (peer_sort (peer) == BGP_PEER_IBGP) 809 peer->ttl = 255; 810 else if (type == BGP_PEER_IBGP) 811 peer->ttl = 1; 812 813 /* reflector-client reset */ 814 if (peer_sort (peer) != BGP_PEER_IBGP) 815 { 816 UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_UNICAST], 817 PEER_FLAG_REFLECTOR_CLIENT); 818 UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_MULTICAST], 819 PEER_FLAG_REFLECTOR_CLIENT); 820 UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_MPLS_VPN], 821 PEER_FLAG_REFLECTOR_CLIENT); 822 UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_UNICAST], 823 PEER_FLAG_REFLECTOR_CLIENT); 824 UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_MULTICAST], 825 PEER_FLAG_REFLECTOR_CLIENT); 826 } 827 828 /* local-as reset */ 829 if (peer_sort (peer) != BGP_PEER_EBGP) 830 { 831 peer->change_local_as = 0; 832 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND); 833 } 834} 835 836/* If peer does not exist, create new one. If peer already exists, 837 set AS number to the peer. */ 838int 839peer_remote_as (struct bgp *bgp, union sockunion *su, as_t *as, 840 afi_t afi, safi_t safi) 841{ 842 struct peer *peer; 843 as_t local_as; 844 845 peer = peer_lookup (bgp, su); 846 847 if (peer) 848 { 849 /* When this peer is a member of peer-group. */ 850 if (peer->group) 851 { 852 if (peer->group->conf->as) 853 { 854 /* Return peer group's AS number. */ 855 *as = peer->group->conf->as; 856 return BGP_ERR_PEER_GROUP_MEMBER; 857 } 858 if (peer_sort (peer->group->conf) == BGP_PEER_IBGP) 859 { 860 if (bgp->as != *as) 861 { 862 *as = peer->as; 863 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT; 864 } 865 } 866 else 867 { 868 if (bgp->as == *as) 869 { 870 *as = peer->as; 871 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT; 872 } 873 } 874 } 875 876 /* Existing peer's AS number change. */ 877 if (peer->as != *as) 878 peer_as_change (peer, *as); 879 } 880 else 881 { 882 883 /* If the peer is not part of our confederation, and its not an 884 iBGP peer then spoof the source AS */ 885 if (bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION) 886 && ! bgp_confederation_peers_check (bgp, *as) 887 && bgp->as != *as) 888 local_as = bgp->confed_id; 889 else 890 local_as = bgp->as; 891 892 /* If this is IPv4 unicast configuration and "no bgp default 893 ipv4-unicast" is specified. */ 894 895 if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4) 896 && afi == AFI_IP && safi == SAFI_UNICAST) 897 peer = peer_create (su, bgp, local_as, *as, 0, 0); 898 else 899 peer = peer_create (su, bgp, local_as, *as, afi, safi); 900 } 901 902 return 0; 903} 904 905/* Activate the peer or peer group for specified AFI and SAFI. */ 906int 907peer_activate (struct peer *peer, afi_t afi, safi_t safi) 908{ 909 int active; 910 911 if (peer->afc[afi][safi]) 912 return 0; 913 914 /* Activate the address family configuration. */ 915 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 916 peer->afc[afi][safi] = 1; 917 else 918 { 919 active = peer_active (peer); 920 921 peer->afc[afi][safi] = 1; 922 923 if (! active && peer_active (peer)) 924 bgp_timer_set (peer); 925 else 926 { 927 if (peer->status == Established) 928 { 929 if (CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV)) 930 { 931 peer->afc_adv[afi][safi] = 1; 932 bgp_capability_send (peer, afi, safi, 933 CAPABILITY_CODE_MP, 934 CAPABILITY_ACTION_SET); 935 if (peer->afc_recv[afi][safi]) 936 { 937 peer->afc_nego[afi][safi] = 1; 938 bgp_announce_route (peer, afi, safi); 939 } 940 } 941 else 942 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 943 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 944 } 945 } 946 } 947 return 0; 948} 949 950int 951peer_deactivate (struct peer *peer, afi_t afi, safi_t safi) 952{ 953 struct peer_group *group; 954 struct peer *peer1; 955 struct listnode *nn; 956 957 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 958 { 959 group = peer->group; 960 961 LIST_LOOP (group->peer, peer1, nn) 962 { 963 if (peer1->af_group[afi][safi]) 964 return BGP_ERR_PEER_GROUP_MEMBER_EXISTS; 965 } 966 } 967 else 968 { 969 if (peer->af_group[afi][safi]) 970 return BGP_ERR_PEER_BELONGS_TO_GROUP; 971 } 972 973 if (! peer->afc[afi][safi]) 974 return 0; 975 976 /* De-activate the address family configuration. */ 977 peer->afc[afi][safi] = 0; 978 peer_af_flag_reset (peer, afi, safi); 979 980 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 981 { 982 if (peer->status == Established) 983 { 984 if (CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV)) 985 { 986 peer->afc_adv[afi][safi] = 0; 987 peer->afc_nego[afi][safi] = 0; 988 989 if (peer_active_nego (peer)) 990 { 991 bgp_capability_send (peer, afi, safi, 992 CAPABILITY_CODE_MP, 993 CAPABILITY_ACTION_UNSET); 994 bgp_clear_route (peer, afi, safi); 995 peer->pcount[afi][safi] = 0; 996 } 997 else 998 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 999 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 1000 } 1001 else 1002 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 1003 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 1004 } 1005 } 1006 return 0; 1007} 1008 1009/* Delete peer from confguration. */ 1010int 1011peer_delete (struct peer *peer) 1012{ 1013 int i; 1014 afi_t afi; 1015 safi_t safi; 1016 struct bgp *bgp; 1017 struct bgp_filter *filter; 1018 1019 bgp = peer->bgp; 1020 1021 /* If this peer belongs to peer group. Clearn up the 1022 relationship. */ 1023 if (peer->group) 1024 { 1025 listnode_delete (peer->group->peer, peer); 1026 peer->group = NULL; 1027 } 1028 1029 /* Withdraw all information from routing table. We can not use 1030 BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is 1031 executed after peer structure is deleted. */ 1032 bgp_stop (peer); 1033 bgp_fsm_change_status (peer, Idle); 1034 1035 /* Stop all timers. */ 1036 BGP_TIMER_OFF (peer->t_start); 1037 BGP_TIMER_OFF (peer->t_connect); 1038 BGP_TIMER_OFF (peer->t_holdtime); 1039 BGP_TIMER_OFF (peer->t_keepalive); 1040 BGP_TIMER_OFF (peer->t_asorig); 1041 BGP_TIMER_OFF (peer->t_routeadv); 1042 1043 /* Delete from all peer list. */ 1044 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 1045 listnode_delete (bgp->peer, peer); 1046 1047 /* Buffer. */ 1048 if (peer->ibuf) 1049 stream_free (peer->ibuf); 1050 1051 if (peer->obuf) 1052 stream_fifo_free (peer->obuf); 1053 1054 if (peer->work) 1055 stream_free (peer->work); 1056 1057 /* Free allocated host character. */ 1058 if (peer->host) 1059 free (peer->host); 1060 1061 /* Local and remote addresses. */ 1062 if (peer->su_local) 1063 XFREE (MTYPE_TMP, peer->su_local); 1064 if (peer->su_remote) 1065 XFREE (MTYPE_TMP, peer->su_remote); 1066 1067 /* Peer description string. */ 1068 if (peer->desc) 1069 XFREE (MTYPE_TMP, peer->desc); 1070 1071 bgp_sync_delete (peer); 1072 1073 /* Free filter related memory. */ 1074 for (afi = AFI_IP; afi < AFI_MAX; afi++) 1075 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) 1076 { 1077 filter = &peer->filter[afi][safi]; 1078 1079 for (i = FILTER_IN; i < FILTER_MAX; i++) 1080 { 1081 if (filter->dlist[i].name) 1082 free (filter->dlist[i].name); 1083 if (filter->plist[i].name) 1084 free (filter->plist[i].name); 1085 if (filter->aslist[i].name) 1086 free (filter->aslist[i].name); 1087 if (filter->map[i].name) 1088 free (filter->map[i].name); 1089 } 1090 1091 if (filter->usmap.name) 1092 free (filter->usmap.name); 1093 1094 if (peer->default_rmap[afi][safi].name) 1095 free (peer->default_rmap[afi][safi].name); 1096 } 1097 1098 /* Update source configuration. */ 1099 if (peer->update_source) 1100 { 1101 sockunion_free (peer->update_source); 1102 peer->update_source = NULL; 1103 } 1104 if (peer->update_if) 1105 { 1106 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if); 1107 peer->update_if = NULL; 1108 } 1109 1110 /* Free peer structure. */ 1111 XFREE (MTYPE_BGP_PEER, peer); 1112 1113 return 0; 1114} 1115 1116int 1117peer_group_cmp (struct peer_group *g1, struct peer_group *g2) 1118{ 1119 return strcmp (g1->name, g2->name); 1120} 1121 1122/* If peer is configured at least one address family return 1. */ 1123int 1124peer_group_active (struct peer *peer) 1125{ 1126 if (peer->af_group[AFI_IP][SAFI_UNICAST] 1127 || peer->af_group[AFI_IP][SAFI_MULTICAST] 1128 || peer->af_group[AFI_IP][SAFI_MPLS_VPN] 1129 || peer->af_group[AFI_IP6][SAFI_UNICAST] 1130 || peer->af_group[AFI_IP6][SAFI_MULTICAST]) 1131 return 1; 1132 return 0; 1133} 1134 1135/* Peer group cofiguration. */ 1136static struct peer_group * 1137peer_group_new () 1138{ 1139 return (struct peer_group *) XCALLOC (MTYPE_PEER_GROUP, 1140 sizeof (struct peer_group)); 1141} 1142 1143void 1144peer_group_free (struct peer_group *group) 1145{ 1146 XFREE (MTYPE_PEER_GROUP, group); 1147} 1148 1149struct peer_group * 1150peer_group_lookup (struct bgp *bgp, char *name) 1151{ 1152 struct peer_group *group; 1153 struct listnode *nn; 1154 1155 LIST_LOOP (bgp->group, group, nn) 1156 { 1157 if (strcmp (group->name, name) == 0) 1158 return group; 1159 } 1160 return NULL; 1161} 1162 1163struct peer_group * 1164peer_group_get (struct bgp *bgp, char *name) 1165{ 1166 struct peer_group *group; 1167 1168 group = peer_group_lookup (bgp, name); 1169 if (group) 1170 return group; 1171 1172 group = peer_group_new (); 1173 group->bgp = bgp; 1174 group->name = strdup (name); 1175 group->peer = list_new (); 1176 group->conf = peer_new (); 1177 if (! bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4)) 1178 group->conf->afc[AFI_IP][SAFI_UNICAST] = 1; 1179 group->conf->host = strdup (name); 1180 group->conf->bgp = bgp; 1181 group->conf->group = group; 1182 group->conf->as = 0; 1183 group->conf->ttl = 1; 1184 group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV; 1185 UNSET_FLAG (group->conf->config, PEER_CONFIG_TIMER); 1186 UNSET_FLAG (group->conf->config, PEER_CONFIG_CONNECT); 1187 group->conf->keepalive = 0; 1188 group->conf->holdtime = 0; 1189 group->conf->connect = 0; 1190 SET_FLAG (group->conf->sflags, PEER_STATUS_GROUP); 1191 listnode_add_sort (bgp->group, group); 1192 1193 return 0; 1194} 1195 1196void 1197peer_group2peer_config_copy (struct peer_group *group, struct peer *peer, 1198 afi_t afi, safi_t safi) 1199{ 1200 int in = FILTER_IN; 1201 int out = FILTER_OUT; 1202 struct peer *conf; 1203 struct bgp_filter *pfilter; 1204 struct bgp_filter *gfilter; 1205 1206 conf = group->conf; 1207 pfilter = &peer->filter[afi][safi]; 1208 gfilter = &conf->filter[afi][safi]; 1209 1210 /* remote-as */ 1211 if (conf->as) 1212 peer->as = conf->as; 1213 1214 /* remote-as */ 1215 if (conf->change_local_as) 1216 peer->change_local_as = conf->change_local_as; 1217 1218 /* TTL */ 1219 peer->ttl = conf->ttl; 1220 1221 /* Weight */ 1222 peer->weight = conf->weight; 1223 1224 /* peer flags apply */ 1225 peer->flags = conf->flags; 1226 /* peer af_flags apply */ 1227 peer->af_flags[afi][safi] = conf->af_flags[afi][safi]; 1228 /* peer config apply */ 1229 peer->config = conf->config; 1230 1231 /* peer timers apply */ 1232 peer->holdtime = conf->holdtime; 1233 peer->keepalive = conf->keepalive; 1234 peer->connect = conf->connect; 1235 if (CHECK_FLAG (conf->config, PEER_CONFIG_CONNECT)) 1236 peer->v_connect = conf->connect; 1237 else 1238 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY; 1239 1240 /* advertisement-interval reset */ 1241 if (peer_sort (peer) == BGP_PEER_IBGP) 1242 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV; 1243 else 1244 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV; 1245 1246 /* allowas-in */ 1247 peer->allowas_in[afi][safi] = conf->allowas_in[afi][safi]; 1248 1249 /* update-source apply */ 1250 if (conf->update_source) 1251 { 1252 if (peer->update_source) 1253 sockunion_free (peer->update_source); 1254 if (peer->update_if) 1255 { 1256 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if); 1257 peer->update_if = NULL; 1258 } 1259 peer->update_source = sockunion_dup (conf->update_source); 1260 } 1261 else if (conf->update_if) 1262 { 1263 if (peer->update_if) 1264 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if); 1265 if (peer->update_source) 1266 { 1267 sockunion_free (peer->update_source); 1268 peer->update_source = NULL; 1269 } 1270 peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, conf->update_if); 1271 } 1272 1273 /* inbound filter apply */ 1274 if (gfilter->dlist[in].name && ! pfilter->dlist[in].name) 1275 { 1276 if (pfilter->dlist[in].name) 1277 free (pfilter->dlist[in].name); 1278 pfilter->dlist[in].name = strdup (gfilter->dlist[in].name); 1279 pfilter->dlist[in].alist = gfilter->dlist[in].alist; 1280 } 1281 if (gfilter->plist[in].name && ! pfilter->plist[in].name) 1282 { 1283 if (pfilter->plist[in].name) 1284 free (pfilter->plist[in].name); 1285 pfilter->plist[in].name = strdup (gfilter->plist[in].name); 1286 pfilter->plist[in].plist = gfilter->plist[in].plist; 1287 } 1288 if (gfilter->aslist[in].name && ! pfilter->aslist[in].name) 1289 { 1290 if (pfilter->aslist[in].name) 1291 free (pfilter->aslist[in].name); 1292 pfilter->aslist[in].name = strdup (gfilter->aslist[in].name); 1293 pfilter->aslist[in].aslist = gfilter->aslist[in].aslist; 1294 } 1295 if (gfilter->map[in].name && ! pfilter->map[in].name) 1296 { 1297 if (pfilter->map[in].name) 1298 free (pfilter->map[in].name); 1299 pfilter->map[in].name = strdup (gfilter->map[in].name); 1300 pfilter->map[in].map = gfilter->map[in].map; 1301 } 1302 1303 /* outbound filter apply */ 1304 if (gfilter->dlist[out].name) 1305 { 1306 if (pfilter->dlist[out].name) 1307 free (pfilter->dlist[out].name); 1308 pfilter->dlist[out].name = strdup (gfilter->dlist[out].name); 1309 pfilter->dlist[out].alist = gfilter->dlist[out].alist; 1310 } 1311 else 1312 { 1313 if (pfilter->dlist[out].name) 1314 free (pfilter->dlist[out].name); 1315 pfilter->dlist[out].name = NULL; 1316 pfilter->dlist[out].alist = NULL; 1317 } 1318 if (gfilter->plist[out].name) 1319 { 1320 if (pfilter->plist[out].name) 1321 free (pfilter->plist[out].name); 1322 pfilter->plist[out].name = strdup (gfilter->plist[out].name); 1323 pfilter->plist[out].plist = gfilter->plist[out].plist; 1324 } 1325 else 1326 { 1327 if (pfilter->plist[out].name) 1328 free (pfilter->plist[out].name); 1329 pfilter->plist[out].name = NULL; 1330 pfilter->plist[out].plist = NULL; 1331 } 1332 if (gfilter->aslist[out].name) 1333 { 1334 if (pfilter->aslist[out].name) 1335 free (pfilter->aslist[out].name); 1336 pfilter->aslist[out].name = strdup (gfilter->aslist[out].name); 1337 pfilter->aslist[out].aslist = gfilter->aslist[out].aslist; 1338 } 1339 else 1340 { 1341 if (pfilter->aslist[out].name) 1342 free (pfilter->aslist[out].name); 1343 pfilter->aslist[out].name = NULL; 1344 pfilter->aslist[out].aslist = NULL; 1345 } 1346 if (gfilter->map[out].name) 1347 { 1348 if (pfilter->map[out].name) 1349 free (pfilter->map[out].name); 1350 pfilter->map[out].name = strdup (gfilter->map[out].name); 1351 pfilter->map[out].map = gfilter->map[out].map; 1352 } 1353 else 1354 { 1355 if (pfilter->map[out].name) 1356 free (pfilter->map[out].name); 1357 pfilter->map[out].name = NULL; 1358 pfilter->map[out].map = NULL; 1359 } 1360 1361 if (gfilter->usmap.name) 1362 { 1363 if (pfilter->usmap.name) 1364 free (pfilter->usmap.name); 1365 pfilter->usmap.name = strdup (gfilter->usmap.name); 1366 pfilter->usmap.map = gfilter->usmap.map; 1367 } 1368 else 1369 { 1370 if (pfilter->usmap.name) 1371 free (pfilter->usmap.name); 1372 pfilter->usmap.name = NULL; 1373 pfilter->usmap.map = NULL; 1374 } 1375} 1376 1377/* Peer group's remote AS configuration. */ 1378int 1379peer_group_remote_as (struct bgp *bgp, char *group_name, as_t *as) 1380{ 1381 struct peer_group *group; 1382 struct peer *peer; 1383 struct listnode *nn; 1384 1385 group = peer_group_lookup (bgp, group_name); 1386 if (! group) 1387 return -1; 1388 1389 if (group->conf->as == *as) 1390 return 0; 1391 1392 /* When we setup peer-group AS number all peer group member's AS 1393 number must be updated to same number. */ 1394 peer_as_change (group->conf, *as); 1395 1396 LIST_LOOP (group->peer, peer, nn) 1397 { 1398 if (peer->as != *as) 1399 peer_as_change (peer, *as); 1400 } 1401 1402 return 0; 1403} 1404 1405int 1406peer_group_delete (struct peer_group *group) 1407{ 1408 struct bgp *bgp; 1409 struct peer *peer; 1410 struct listnode *nn; 1411 1412 bgp = group->bgp; 1413 1414 LIST_LOOP (group->peer, peer, nn) 1415 { 1416 peer->group = NULL; 1417 peer_delete (peer); 1418 } 1419 list_delete (group->peer); 1420 1421 free (group->name); 1422 group->name = NULL; 1423 1424 group->conf->group = NULL; 1425 peer_delete (group->conf); 1426 1427 /* Delete from all peer_group list. */ 1428 listnode_delete (bgp->group, group); 1429 1430 peer_group_free (group); 1431 1432 return 0; 1433} 1434 1435int 1436peer_group_remote_as_delete (struct peer_group *group) 1437{ 1438 struct peer *peer; 1439 struct listnode *nn; 1440 1441 if (! group->conf->as) 1442 return 0; 1443 1444 LIST_LOOP (group->peer, peer, nn) 1445 { 1446 peer->group = NULL; 1447 peer_delete (peer); 1448 } 1449 list_delete_all_node (group->peer); 1450 1451 group->conf->as = 0; 1452 1453 return 0; 1454} 1455 1456/* Bind specified peer to peer group. */ 1457int 1458peer_group_bind (struct bgp *bgp, union sockunion *su, 1459 struct peer_group *group, afi_t afi, safi_t safi, as_t *as) 1460{ 1461 struct peer *peer; 1462 int first_member = 0; 1463 1464 /* Check peer group's address family. */ 1465 if (! group->conf->afc[afi][safi]) 1466 return BGP_ERR_PEER_GROUP_AF_UNCONFIGURED; 1467 1468 /* Lookup the peer. */ 1469 peer = peer_lookup (bgp, su); 1470 1471 /* Create a new peer. */ 1472 if (! peer) 1473 { 1474 if (! group->conf->as) 1475 return BGP_ERR_PEER_GROUP_NO_REMOTE_AS; 1476 1477 peer = peer_create (su, bgp, bgp->as, group->conf->as, afi, safi); 1478 peer->group = group; 1479 peer->af_group[afi][safi] = 1; 1480 listnode_add (group->peer, peer); 1481 peer_group2peer_config_copy (group, peer, afi, safi); 1482 1483 return 0; 1484 } 1485 1486 /* When the peer already belongs to peer group, check the consistency. */ 1487 if (peer->af_group[afi][safi]) 1488 { 1489 if (strcmp (peer->group->name, group->name) != 0) 1490 return BGP_ERR_PEER_GROUP_CANT_CHANGE; 1491 1492 return 0; 1493 } 1494 1495 /* Check current peer group configuration. */ 1496 if (peer_group_active (peer) 1497 && strcmp (peer->group->name, group->name) != 0) 1498 return BGP_ERR_PEER_GROUP_MISMATCH; 1499 1500 if (! group->conf->as) 1501 { 1502 if (peer_sort (group->conf) != BGP_PEER_INTERNAL 1503 && peer_sort (group->conf) != peer_sort (peer)) 1504 { 1505 if (as) 1506 *as = peer->as; 1507 return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT; 1508 } 1509 1510 if (peer_sort (group->conf) == BGP_PEER_INTERNAL) 1511 first_member = 1; 1512 } 1513 1514 peer->af_group[afi][safi] = 1; 1515 peer->afc[afi][safi] = 1; 1516 if (! peer->group) 1517 { 1518 peer->group = group; 1519 listnode_add (group->peer, peer); 1520 } 1521 1522 if (first_member) 1523 { 1524 /* Advertisement-interval reset */ 1525 if (peer_sort (group->conf) == BGP_PEER_IBGP) 1526 group->conf->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV; 1527 else 1528 group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV; 1529 1530 /* ebgp-multihop reset */ 1531 if (peer_sort (group->conf) == BGP_PEER_IBGP) 1532 group->conf->ttl = 255; 1533 1534 /* local-as reset */ 1535 if (peer_sort (group->conf) != BGP_PEER_EBGP) 1536 { 1537 group->conf->change_local_as = 0; 1538 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND); 1539 } 1540 } 1541 peer_group2peer_config_copy (group, peer, afi, safi); 1542 1543 if (peer->status == Established) 1544 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 1545 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 1546 else 1547 BGP_EVENT_ADD (peer, BGP_Stop); 1548 1549 return 0; 1550} 1551 1552int 1553peer_group_unbind (struct bgp *bgp, struct peer *peer, 1554 struct peer_group *group, afi_t afi, safi_t safi) 1555{ 1556 if (! peer->af_group[afi][safi]) 1557 return 0; 1558 1559 if (group != peer->group) 1560 return BGP_ERR_PEER_GROUP_MISMATCH; 1561 1562 peer->af_group[afi][safi] = 0; 1563 peer->afc[afi][safi] = 0; 1564 peer_af_flag_reset (peer, afi, safi); 1565 1566 if (! peer_group_active (peer)) 1567 { 1568 listnode_delete (group->peer, peer); 1569 peer->group = NULL; 1570 if (group->conf->as) 1571 { 1572 peer_delete (peer); 1573 return 0; 1574 } 1575 peer_global_config_reset (peer); 1576 } 1577 1578 if (peer->status == Established) 1579 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 1580 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 1581 else 1582 BGP_EVENT_ADD (peer, BGP_Stop); 1583 1584 return 0; 1585} 1586 1587/* BGP instance creation by `router bgp' commands. */ 1588struct bgp * 1589bgp_create (as_t *as, char *name) 1590{ 1591 struct bgp *bgp; 1592 afi_t afi; 1593 safi_t safi; 1594 1595 bgp = XCALLOC (MTYPE_BGP, sizeof (struct bgp)); 1596 1597 bgp->peer_self = peer_new (); 1598 bgp->peer_self->host = "Static announcement"; 1599 1600 bgp->peer = list_new (); 1601 bgp->peer->cmp = (int (*)(void *, void *)) peer_cmp; 1602 1603 bgp->group = list_new (); 1604 bgp->group->cmp = (int (*)(void *, void *)) peer_group_cmp; 1605 1606 for (afi = AFI_IP; afi < AFI_MAX; afi++) 1607 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) 1608 { 1609 bgp->route[afi][safi] = bgp_table_init (); 1610 bgp->aggregate[afi][safi] = bgp_table_init (); 1611 bgp->rib[afi][safi] = bgp_table_init (); 1612 } 1613 1614 bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF; 1615 bgp->default_holdtime = BGP_DEFAULT_HOLDTIME; 1616 bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE; 1617 1618 bgp->as = *as; 1619 1620 if (name) 1621 bgp->name = strdup (name); 1622 1623 return bgp; 1624} 1625 1626/* Return first entry of BGP. */ 1627struct bgp * 1628bgp_get_default () 1629{ 1630 if (bm->bgp->head) 1631 return bm->bgp->head->data; 1632 return NULL; 1633} 1634 1635/* Lookup BGP entry. */ 1636struct bgp * 1637bgp_lookup (as_t as, char *name) 1638{ 1639 struct bgp *bgp; 1640 struct listnode *nn; 1641 1642 LIST_LOOP (bm->bgp, bgp, nn) 1643 if (bgp->as == as 1644 && ((bgp->name == NULL && name == NULL) 1645 || (bgp->name && name && strcmp (bgp->name, name) == 0))) 1646 return bgp; 1647 return NULL; 1648} 1649 1650/* Lookup BGP structure by view name. */ 1651struct bgp * 1652bgp_lookup_by_name (char *name) 1653{ 1654 struct bgp *bgp; 1655 struct listnode *nn; 1656 1657 LIST_LOOP (bm->bgp, bgp, nn) 1658 if ((bgp->name == NULL && name == NULL) 1659 || (bgp->name && name && strcmp (bgp->name, name) == 0)) 1660 return bgp; 1661 return NULL; 1662} 1663 1664/* Called from VTY commands. */ 1665int 1666bgp_get (struct bgp **bgp_val, as_t *as, char *name) 1667{ 1668 struct bgp *bgp; 1669 1670 /* Multiple instance check. */ 1671 if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE)) 1672 { 1673 if (name) 1674 bgp = bgp_lookup_by_name (name); 1675 else 1676 bgp = bgp_get_default (); 1677 1678 /* Already exists. */ 1679 if (bgp) 1680 { 1681 if (bgp->as != *as) 1682 { 1683 *as = bgp->as; 1684 return BGP_ERR_INSTANCE_MISMATCH; 1685 } 1686 *bgp_val = bgp; 1687 return 0; 1688 } 1689 } 1690 else 1691 { 1692 /* BGP instance name can not be specified for single instance. */ 1693 if (name) 1694 return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET; 1695 1696 /* Get default BGP structure if exists. */ 1697 bgp = bgp_get_default (); 1698 1699 if (bgp) 1700 { 1701 if (bgp->as != *as) 1702 { 1703 *as = bgp->as; 1704 return BGP_ERR_AS_MISMATCH; 1705 } 1706 *bgp_val = bgp; 1707 return 0; 1708 } 1709 } 1710 1711 bgp = bgp_create (as, name); 1712 listnode_add (bm->bgp, bgp); 1713 bgp_if_update_all (); 1714 *bgp_val = bgp; 1715 1716 return 0; 1717} 1718 1719/* Delete BGP instance. */ 1720int 1721bgp_delete (struct bgp *bgp) 1722{ 1723 struct peer *peer; 1724 struct listnode *nn; 1725 struct listnode *next; 1726 afi_t afi; 1727 safi_t safi; 1728 int i; 1729 1730 /* Delete static route. */ 1731 bgp_static_delete (bgp); 1732 1733 /* Unset redistribution. */ 1734 for (afi = AFI_IP; afi < AFI_MAX; afi++) 1735 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) 1736 if (i != ZEBRA_ROUTE_BGP) 1737 bgp_redistribute_unset (bgp, afi, i); 1738 1739 bgp->group->del = (void (*)(void *)) peer_group_delete; 1740 list_delete (bgp->group); 1741 1742 for (nn = bgp->peer->head; nn; nn = next) 1743 { 1744 peer = nn->data; 1745 next = nn->next; 1746 peer_delete (peer); 1747 } 1748 1749 listnode_delete (bm->bgp, bgp); 1750 1751 if (bgp->name) 1752 free (bgp->name); 1753 1754 for (afi = AFI_IP; afi < AFI_MAX; afi++) 1755 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) 1756 { 1757 if (bgp->route[afi][safi]) 1758 XFREE (MTYPE_ROUTE_TABLE, bgp->route[afi][safi]); 1759 if (bgp->aggregate[afi][safi]) 1760 XFREE (MTYPE_ROUTE_TABLE,bgp->aggregate[afi][safi]) ; 1761 if (bgp->rib[afi][safi]) 1762 XFREE (MTYPE_ROUTE_TABLE,bgp->rib[afi][safi]); 1763 } 1764 XFREE (MTYPE_BGP, bgp); 1765 1766 return 0; 1767} 1768 1769struct peer * 1770peer_lookup (struct bgp *bgp, union sockunion *su) 1771{ 1772 struct peer *peer; 1773 struct listnode *nn; 1774 1775 if (! bgp) 1776 bgp = bgp_get_default (); 1777 1778 if (! bgp) 1779 return NULL; 1780 1781 LIST_LOOP (bgp->peer, peer, nn) 1782 { 1783 if (sockunion_same (&peer->su, su) 1784 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER)) 1785 return peer; 1786 } 1787 return NULL; 1788} 1789 1790struct peer * 1791peer_lookup_with_open (union sockunion *su, as_t remote_as, 1792 struct in_addr *remote_id, int *as) 1793{ 1794 struct peer *peer; 1795 struct listnode *nn; 1796 struct bgp *bgp; 1797 1798 bgp = bgp_get_default (); 1799 if (! bgp) 1800 return NULL; 1801 1802 LIST_LOOP (bgp->peer, peer, nn) 1803 { 1804 if (sockunion_same (&peer->su, su) 1805 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER)) 1806 { 1807 if (peer->as == remote_as 1808 && peer->remote_id.s_addr == remote_id->s_addr) 1809 return peer; 1810 if (peer->as == remote_as) 1811 *as = 1; 1812 } 1813 } 1814 LIST_LOOP (bgp->peer, peer, nn) 1815 { 1816 if (sockunion_same (&peer->su, su) 1817 && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER)) 1818 { 1819 if (peer->as == remote_as 1820 && peer->remote_id.s_addr == 0) 1821 return peer; 1822 if (peer->as == remote_as) 1823 *as = 1; 1824 } 1825 } 1826 return NULL; 1827} 1828 1829/* If peer is configured at least one address family return 1. */ 1830int 1831peer_active (struct peer *peer) 1832{ 1833 if (peer->afc[AFI_IP][SAFI_UNICAST] 1834 || peer->afc[AFI_IP][SAFI_MULTICAST] 1835 || peer->afc[AFI_IP][SAFI_MPLS_VPN] 1836 || peer->afc[AFI_IP6][SAFI_UNICAST] 1837 || peer->afc[AFI_IP6][SAFI_MULTICAST]) 1838 return 1; 1839 return 0; 1840} 1841 1842/* If peer is negotiated at least one address family return 1. */ 1843int 1844peer_active_nego (struct peer *peer) 1845{ 1846 if (peer->afc_nego[AFI_IP][SAFI_UNICAST] 1847 || peer->afc_nego[AFI_IP][SAFI_MULTICAST] 1848 || peer->afc_nego[AFI_IP][SAFI_MPLS_VPN] 1849 || peer->afc_nego[AFI_IP6][SAFI_UNICAST] 1850 || peer->afc_nego[AFI_IP6][SAFI_MULTICAST]) 1851 return 1; 1852 return 0; 1853} 1854 1855/* peer_flag_change_type. */ 1856enum peer_change_type 1857{ 1858 peer_change_none, 1859 peer_change_reset, 1860 peer_change_reset_in, 1861 peer_change_reset_out, 1862}; 1863 1864void 1865peer_change_action (struct peer *peer, afi_t afi, safi_t safi, 1866 enum peer_change_type type) 1867{ 1868 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 1869 return; 1870 1871 if (type == peer_change_reset) 1872 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 1873 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 1874 else if (type == peer_change_reset_in) 1875 { 1876 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV) 1877 || CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV)) 1878 bgp_route_refresh_send (peer, afi, safi, 0, 0, 0); 1879 else 1880 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 1881 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 1882 } 1883 else if (type == peer_change_reset_out) 1884 bgp_announce_route (peer, afi, safi); 1885} 1886 1887struct peer_flag_action 1888{ 1889 /* Peer's flag. */ 1890 u_int32_t flag; 1891 1892 /* This flag can be set for peer-group member. */ 1893 u_char not_for_member; 1894 1895 /* Action when the flag is changed. */ 1896 enum peer_change_type type; 1897}; 1898 1899struct peer_flag_action peer_flag_action_list[] = 1900 { 1901 { PEER_FLAG_PASSIVE, 0, peer_change_reset }, 1902 { PEER_FLAG_SHUTDOWN, 0, peer_change_reset }, 1903 { PEER_FLAG_DONT_CAPABILITY, 0, peer_change_none }, 1904 { PEER_FLAG_OVERRIDE_CAPABILITY, 0, peer_change_none }, 1905 { PEER_FLAG_STRICT_CAP_MATCH, 0, peer_change_none }, 1906 { PEER_FLAG_NO_ROUTE_REFRESH_CAP, 0, peer_change_reset }, 1907 { PEER_FLAG_DYNAMIC_CAPABILITY, 0, peer_change_reset }, 1908 { PEER_FLAG_ENFORCE_MULTIHOP, 0, peer_change_reset }, 1909 { 0, 0, 0 } 1910 }; 1911 1912struct peer_flag_action peer_af_flag_action_list[] = 1913 { 1914 { PEER_FLAG_NEXTHOP_SELF, 1, peer_change_reset_out }, 1915 { PEER_FLAG_SEND_COMMUNITY, 1, peer_change_reset_out }, 1916 { PEER_FLAG_SEND_EXT_COMMUNITY, 1, peer_change_reset_out }, 1917 { PEER_FLAG_SOFT_RECONFIG, 0, peer_change_reset_in }, 1918 { PEER_FLAG_REFLECTOR_CLIENT, 1, peer_change_reset }, 1919 { PEER_FLAG_RSERVER_CLIENT, 1, peer_change_reset }, 1920 { PEER_FLAG_AS_PATH_UNCHANGED, 1, peer_change_reset_out }, 1921 { PEER_FLAG_NEXTHOP_UNCHANGED, 1, peer_change_reset_out }, 1922 { PEER_FLAG_MED_UNCHANGED, 1, peer_change_reset_out }, 1923 { PEER_FLAG_REMOVE_PRIVATE_AS, 1, peer_change_reset_out }, 1924 { PEER_FLAG_ALLOWAS_IN, 0, peer_change_reset_in }, 1925 { PEER_FLAG_ORF_PREFIX_SM, 1, peer_change_reset }, 1926 { PEER_FLAG_ORF_PREFIX_RM, 1, peer_change_reset }, 1927 { 0, 0, 0 } 1928 }; 1929 1930/* Proper action set. */ 1931int 1932peer_flag_action_set (struct peer_flag_action *action_list, int size, 1933 struct peer_flag_action *action, u_int32_t flag) 1934{ 1935 int i; 1936 int found = 0; 1937 int reset_in = 0; 1938 int reset_out = 0; 1939 struct peer_flag_action *match = NULL; 1940 1941 /* Check peer's frag action. */ 1942 for (i = 0; i < size; i++) 1943 { 1944 match = &action_list[i]; 1945 1946 if (match->flag == 0) 1947 break; 1948 1949 if (match->flag & flag) 1950 { 1951 found = 1; 1952 1953 if (match->type == peer_change_reset_in) 1954 reset_in = 1; 1955 if (match->type == peer_change_reset_out) 1956 reset_out = 1; 1957 if (match->type == peer_change_reset) 1958 { 1959 reset_in = 1; 1960 reset_out = 1; 1961 } 1962 if (match->not_for_member) 1963 action->not_for_member = 1; 1964 } 1965 } 1966 1967 /* Set peer clear type. */ 1968 if (reset_in && reset_out) 1969 action->type = peer_change_reset; 1970 else if (reset_in) 1971 action->type = peer_change_reset_in; 1972 else if (reset_out) 1973 action->type = peer_change_reset_out; 1974 else 1975 action->type = peer_change_none; 1976 1977 return found; 1978} 1979 1980void 1981peer_flag_modify_action (struct peer *peer, u_int32_t flag) 1982{ 1983 if (flag == PEER_FLAG_SHUTDOWN) 1984 { 1985 if (CHECK_FLAG (peer->flags, flag)) 1986 { 1987 if (peer->status == Established) 1988 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 1989 BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN); 1990 else 1991 BGP_EVENT_ADD (peer, BGP_Stop); 1992 } 1993 else 1994 { 1995 peer->v_start = BGP_INIT_START_TIMER; 1996 BGP_EVENT_ADD (peer, BGP_Stop); 1997 } 1998 } 1999 else if (peer->status == Established) 2000 { 2001 if (flag == PEER_FLAG_NO_ROUTE_REFRESH_CAP 2002 && CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV)) 2003 { 2004 if (CHECK_FLAG (peer->flags, flag)) 2005 UNSET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV); 2006 else 2007 SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV); 2008 2009 bgp_capability_send (peer, AFI_IP, SAFI_UNICAST, 2010 CAPABILITY_CODE_REFRESH, 2011 CHECK_FLAG (peer->flags, flag) ? 2012 CAPABILITY_ACTION_UNSET : CAPABILITY_ACTION_SET); 2013 } 2014 else 2015 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 2016 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 2017 } 2018 else 2019 BGP_EVENT_ADD (peer, BGP_Stop); 2020} 2021 2022/* Change specified peer flag. */ 2023int 2024peer_flag_modify (struct peer *peer, u_int32_t flag, int set) 2025{ 2026 int found; 2027 int size; 2028 struct peer_group *group; 2029 struct listnode *nn; 2030 struct peer_flag_action action; 2031 2032 memset (&action, 0, sizeof (struct peer_flag_action)); 2033 size = sizeof peer_flag_action_list / sizeof (struct peer_flag_action); 2034 2035 found = peer_flag_action_set (peer_flag_action_list, size, &action, flag); 2036 2037 /* No flag action is found. */ 2038 if (! found) 2039 return BGP_ERR_INVALID_FLAG; 2040 2041 /* Not for peer-group member. */ 2042 if (action.not_for_member && peer_group_active (peer)) 2043 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 2044 2045 /* When unset the peer-group member's flag we have to check 2046 peer-group configuration. */ 2047 if (! set && peer_group_active (peer)) 2048 if (CHECK_FLAG (peer->group->conf->flags, flag)) 2049 { 2050 if (flag == PEER_FLAG_SHUTDOWN) 2051 return BGP_ERR_PEER_GROUP_SHUTDOWN; 2052 else 2053 return BGP_ERR_PEER_GROUP_HAS_THE_FLAG; 2054 } 2055 2056 /* Flag conflict check. */ 2057 if (set 2058 && CHECK_FLAG (peer->flags | flag, PEER_FLAG_STRICT_CAP_MATCH) 2059 && CHECK_FLAG (peer->flags | flag, PEER_FLAG_OVERRIDE_CAPABILITY)) 2060 return BGP_ERR_PEER_FLAG_CONFLICT; 2061 2062 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 2063 { 2064 if (set && CHECK_FLAG (peer->flags, flag) == flag) 2065 return 0; 2066 if (! set && ! CHECK_FLAG (peer->flags, flag)) 2067 return 0; 2068 } 2069 2070 if (set) 2071 SET_FLAG (peer->flags, flag); 2072 else 2073 UNSET_FLAG (peer->flags, flag); 2074 2075 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 2076 { 2077 if (action.type == peer_change_reset) 2078 peer_flag_modify_action (peer, flag); 2079 2080 return 0; 2081 } 2082 2083 /* peer-group member updates. */ 2084 group = peer->group; 2085 2086 LIST_LOOP (group->peer, peer, nn) 2087 { 2088 if (set && CHECK_FLAG (peer->flags, flag) == flag) 2089 continue; 2090 2091 if (! set && ! CHECK_FLAG (peer->flags, flag)) 2092 continue; 2093 2094 if (set) 2095 SET_FLAG (peer->flags, flag); 2096 else 2097 UNSET_FLAG (peer->flags, flag); 2098 2099 if (action.type == peer_change_reset) 2100 peer_flag_modify_action (peer, flag); 2101 } 2102 return 0; 2103} 2104 2105int 2106peer_flag_set (struct peer *peer, u_int32_t flag) 2107{ 2108 return peer_flag_modify (peer, flag, 1); 2109} 2110 2111int 2112peer_flag_unset (struct peer *peer, u_int32_t flag) 2113{ 2114 return peer_flag_modify (peer, flag, 0); 2115} 2116 2117int 2118peer_is_group_member (struct peer *peer, afi_t afi, safi_t safi) 2119{ 2120 if (peer->af_group[afi][safi]) 2121 return 1; 2122 return 0; 2123} 2124 2125int 2126peer_af_flag_modify (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag, 2127 int set) 2128{ 2129 int found; 2130 int size; 2131 struct listnode *nn; 2132 struct peer_group *group; 2133 struct peer_flag_action action; 2134 2135 memset (&action, 0, sizeof (struct peer_flag_action)); 2136 size = sizeof peer_af_flag_action_list / sizeof (struct peer_flag_action); 2137 2138 found = peer_flag_action_set (peer_af_flag_action_list, size, &action, flag); 2139 2140 /* No flag action is found. */ 2141 if (! found) 2142 return BGP_ERR_INVALID_FLAG; 2143 2144 /* Adress family must be activated. */ 2145 if (! peer->afc[afi][safi]) 2146 return BGP_ERR_PEER_INACTIVE; 2147 2148 /* Not for peer-group member. */ 2149 if (action.not_for_member && peer_is_group_member (peer, afi, safi)) 2150 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 2151 2152 /* Spcecial check for reflector client. */ 2153 if (flag & PEER_FLAG_REFLECTOR_CLIENT 2154 && peer_sort (peer) != BGP_PEER_IBGP) 2155 return BGP_ERR_NOT_INTERNAL_PEER; 2156 2157 /* Spcecial check for remove-private-AS. */ 2158 if (flag & PEER_FLAG_REMOVE_PRIVATE_AS 2159 && peer_sort (peer) == BGP_PEER_IBGP) 2160 return BGP_ERR_REMOVE_PRIVATE_AS; 2161 2162 /* When unset the peer-group member's flag we have to check 2163 peer-group configuration. */ 2164 if (! set && peer->af_group[afi][safi]) 2165 if (CHECK_FLAG (peer->group->conf->af_flags[afi][safi], flag)) 2166 return BGP_ERR_PEER_GROUP_HAS_THE_FLAG; 2167 2168 /* When current flag configuration is same as requested one. */ 2169 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 2170 { 2171 if (set && CHECK_FLAG (peer->af_flags[afi][safi], flag) == flag) 2172 return 0; 2173 if (! set && ! CHECK_FLAG (peer->af_flags[afi][safi], flag)) 2174 return 0; 2175 } 2176 2177 if (set) 2178 SET_FLAG (peer->af_flags[afi][safi], flag); 2179 else 2180 UNSET_FLAG (peer->af_flags[afi][safi], flag); 2181 2182 /* Execute action when peer is established. */ 2183 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP) 2184 && peer->status == Established) 2185 { 2186 if (! set && flag == PEER_FLAG_SOFT_RECONFIG) 2187 bgp_clear_adj_in (peer, afi, safi); 2188 else 2189 peer_change_action (peer, afi, safi, action.type); 2190 } 2191 2192 /* Peer group member updates. */ 2193 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 2194 { 2195 group = peer->group; 2196 2197 LIST_LOOP (group->peer, peer, nn) 2198 { 2199 if (! peer->af_group[afi][safi]) 2200 continue; 2201 2202 if (set && CHECK_FLAG (peer->af_flags[afi][safi], flag) == flag) 2203 continue; 2204 2205 if (! set && ! CHECK_FLAG (peer->af_flags[afi][safi], flag)) 2206 continue; 2207 2208 if (set) 2209 SET_FLAG (peer->af_flags[afi][safi], flag); 2210 else 2211 UNSET_FLAG (peer->af_flags[afi][safi], flag); 2212 2213 if (peer->status == Established) 2214 { 2215 if (! set && flag == PEER_FLAG_SOFT_RECONFIG) 2216 bgp_clear_adj_in (peer, afi, safi); 2217 else 2218 peer_change_action (peer, afi, safi, action.type); 2219 } 2220 } 2221 } 2222 return 0; 2223} 2224 2225int 2226peer_af_flag_set (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag) 2227{ 2228 return peer_af_flag_modify (peer, afi, safi, flag, 1); 2229} 2230 2231int 2232peer_af_flag_unset (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag) 2233{ 2234 return peer_af_flag_modify (peer, afi, safi, flag, 0); 2235} 2236 2237/* EBGP multihop configuration. */ 2238int 2239peer_ebgp_multihop_set (struct peer *peer, int ttl) 2240{ 2241 struct peer_group *group; 2242 struct listnode *nn; 2243 2244 if (peer_sort (peer) == BGP_PEER_IBGP) 2245 return 0; 2246 2247 peer->ttl = ttl; 2248 2249 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 2250 { 2251 if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP) 2252 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl); 2253 } 2254 else 2255 { 2256 group = peer->group; 2257 LIST_LOOP (group->peer, peer, nn) 2258 { 2259 if (peer_sort (peer) == BGP_PEER_IBGP) 2260 continue; 2261 2262 peer->ttl = group->conf->ttl; 2263 2264 if (peer->fd >= 0) 2265 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl); 2266 } 2267 } 2268 return 0; 2269} 2270 2271int 2272peer_ebgp_multihop_unset (struct peer *peer) 2273{ 2274 struct peer_group *group; 2275 struct listnode *nn; 2276 2277 if (peer_sort (peer) == BGP_PEER_IBGP) 2278 return 0; 2279 2280 if (peer_group_active (peer)) 2281 peer->ttl = peer->group->conf->ttl; 2282 else 2283 peer->ttl = 1; 2284 2285 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 2286 { 2287 if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP) 2288 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl); 2289 } 2290 else 2291 { 2292 group = peer->group; 2293 LIST_LOOP (group->peer, peer, nn) 2294 { 2295 if (peer_sort (peer) == BGP_PEER_IBGP) 2296 continue; 2297 2298 peer->ttl = 1; 2299 2300 if (peer->fd >= 0) 2301 sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl); 2302 } 2303 } 2304 return 0; 2305} 2306 2307/* Neighbor description. */ 2308int 2309peer_description_set (struct peer *peer, char *desc) 2310{ 2311 if (peer->desc) 2312 XFREE (MTYPE_PEER_DESC, peer->desc); 2313 2314 peer->desc = XSTRDUP (MTYPE_PEER_DESC, desc); 2315 2316 return 0; 2317} 2318 2319int 2320peer_description_unset (struct peer *peer) 2321{ 2322 if (peer->desc) 2323 XFREE (MTYPE_PEER_DESC, peer->desc); 2324 2325 peer->desc = NULL; 2326 2327 return 0; 2328} 2329 2330/* Neighbor update-source. */ 2331int 2332peer_update_source_if_set (struct peer *peer, char *ifname) 2333{ 2334 struct peer_group *group; 2335 struct listnode *nn; 2336 2337 if (peer->update_if) 2338 { 2339 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP) 2340 && strcmp (peer->update_if, ifname) == 0) 2341 return 0; 2342 2343 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if); 2344 peer->update_if = NULL; 2345 } 2346 2347 if (peer->update_source) 2348 { 2349 sockunion_free (peer->update_source); 2350 peer->update_source = NULL; 2351 } 2352 2353 peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, ifname); 2354 2355 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 2356 { 2357 if (peer->status == Established) 2358 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 2359 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 2360 else 2361 BGP_EVENT_ADD (peer, BGP_Stop); 2362 return 0; 2363 } 2364 2365 /* peer-group member updates. */ 2366 group = peer->group; 2367 LIST_LOOP (group->peer, peer, nn) 2368 { 2369 if (peer->update_if) 2370 { 2371 if (strcmp (peer->update_if, ifname) == 0) 2372 continue; 2373 2374 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if); 2375 peer->update_if = NULL; 2376 } 2377 2378 if (peer->update_source) 2379 { 2380 sockunion_free (peer->update_source); 2381 peer->update_source = NULL; 2382 } 2383 2384 peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, ifname); 2385 2386 if (peer->status == Established) 2387 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 2388 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 2389 else 2390 BGP_EVENT_ADD (peer, BGP_Stop); 2391 } 2392 return 0; 2393} 2394 2395int 2396peer_update_source_addr_set (struct peer *peer, union sockunion *su) 2397{ 2398 struct peer_group *group; 2399 struct listnode *nn; 2400 2401 if (peer->update_source) 2402 { 2403 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP) 2404 && sockunion_cmp (peer->update_source, su) == 0) 2405 return 0; 2406 sockunion_free (peer->update_source); 2407 peer->update_source = NULL; 2408 } 2409 2410 if (peer->update_if) 2411 { 2412 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if); 2413 peer->update_if = NULL; 2414 } 2415 2416 peer->update_source = sockunion_dup (su); 2417 2418 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 2419 { 2420 if (peer->status == Established) 2421 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 2422 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 2423 else 2424 BGP_EVENT_ADD (peer, BGP_Stop); 2425 return 0; 2426 } 2427 2428 /* peer-group member updates. */ 2429 group = peer->group; 2430 LIST_LOOP (group->peer, peer, nn) 2431 { 2432 if (peer->update_source) 2433 { 2434 if (sockunion_cmp (peer->update_source, su) == 0) 2435 continue; 2436 sockunion_free (peer->update_source); 2437 peer->update_source = NULL; 2438 } 2439 2440 if (peer->update_if) 2441 { 2442 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if); 2443 peer->update_if = NULL; 2444 } 2445 2446 peer->update_source = sockunion_dup (su); 2447 2448 if (peer->status == Established) 2449 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 2450 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 2451 else 2452 BGP_EVENT_ADD (peer, BGP_Stop); 2453 } 2454 return 0; 2455} 2456 2457int 2458peer_update_source_unset (struct peer *peer) 2459{ 2460 union sockunion *su; 2461 struct peer_group *group; 2462 struct listnode *nn; 2463 2464 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP) 2465 && ! peer->update_source 2466 && ! peer->update_if) 2467 return 0; 2468 2469 if (peer->update_source) 2470 { 2471 sockunion_free (peer->update_source); 2472 peer->update_source = NULL; 2473 } 2474 if (peer->update_if) 2475 { 2476 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if); 2477 peer->update_if = NULL; 2478 } 2479 2480 if (peer_group_active (peer)) 2481 { 2482 group = peer->group; 2483 2484 if (group->conf->update_source) 2485 { 2486 su = sockunion_dup (group->conf->update_source); 2487 peer->update_source = su; 2488 } 2489 else if (group->conf->update_if) 2490 peer->update_if = 2491 XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, group->conf->update_if); 2492 } 2493 2494 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 2495 { 2496 if (peer->status == Established) 2497 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 2498 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 2499 else 2500 BGP_EVENT_ADD (peer, BGP_Stop); 2501 return 0; 2502 } 2503 2504 /* peer-group member updates. */ 2505 group = peer->group; 2506 LIST_LOOP (group->peer, peer, nn) 2507 { 2508 if (! peer->update_source && ! peer->update_if) 2509 continue; 2510 2511 if (peer->update_source) 2512 { 2513 sockunion_free (peer->update_source); 2514 peer->update_source = NULL; 2515 } 2516 2517 if (peer->update_if) 2518 { 2519 XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if); 2520 peer->update_if = NULL; 2521 } 2522 2523 if (peer->status == Established) 2524 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 2525 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 2526 else 2527 BGP_EVENT_ADD (peer, BGP_Stop); 2528 } 2529 return 0; 2530} 2531 2532int 2533peer_default_originate_set (struct peer *peer, afi_t afi, safi_t safi, 2534 char *rmap) 2535{ 2536 /* Adress family must be activated. */ 2537 if (! peer->afc[afi][safi]) 2538 return BGP_ERR_PEER_INACTIVE; 2539 2540 /* Default originate can't be used for peer group memeber. */ 2541 if (peer_is_group_member (peer, afi, safi)) 2542 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 2543 2544 if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE) 2545 || (rmap && ! peer->default_rmap[afi][safi].name) 2546 || (rmap && strcmp (rmap, peer->default_rmap[afi][safi].name) != 0)) 2547 { 2548 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE); 2549 2550 if (rmap) 2551 { 2552 if (peer->default_rmap[afi][safi].name) 2553 free (peer->default_rmap[afi][safi].name); 2554 peer->default_rmap[afi][safi].name = strdup (rmap); 2555 peer->default_rmap[afi][safi].map = route_map_lookup_by_name (rmap); 2556 } 2557 2558 if (peer->status == Established && peer->afc_nego[afi][safi]) 2559 bgp_default_originate (peer, afi, safi, 0); 2560 } 2561 return 0; 2562} 2563 2564int 2565peer_default_originate_unset (struct peer *peer, afi_t afi, safi_t safi) 2566{ 2567 /* Adress family must be activated. */ 2568 if (! peer->afc[afi][safi]) 2569 return BGP_ERR_PEER_INACTIVE; 2570 2571 /* Default originate can't be used for peer group memeber. */ 2572 if (peer_is_group_member (peer, afi, safi)) 2573 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 2574 2575 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE)) 2576 { 2577 UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE); 2578 2579 if (peer->default_rmap[afi][safi].name) 2580 free (peer->default_rmap[afi][safi].name); 2581 peer->default_rmap[afi][safi].name = NULL; 2582 peer->default_rmap[afi][safi].map = NULL; 2583 2584 if (peer->status == Established && peer->afc_nego[afi][safi]) 2585 bgp_default_originate (peer, afi, safi, 1); 2586 } 2587 return 0; 2588} 2589 2590int 2591peer_port_set (struct peer *peer, u_int16_t port) 2592{ 2593 peer->port = port; 2594 return 0; 2595} 2596 2597int 2598peer_port_unset (struct peer *peer) 2599{ 2600 peer->port = BGP_PORT_DEFAULT; 2601 return 0; 2602} 2603 2604/* neighbor weight. */ 2605int 2606peer_weight_set (struct peer *peer, u_int16_t weight) 2607{ 2608 struct peer_group *group; 2609 struct listnode *nn; 2610 2611 SET_FLAG (peer->config, PEER_CONFIG_WEIGHT); 2612 peer->weight = weight; 2613 2614 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 2615 return 0; 2616 2617 /* peer-group member updates. */ 2618 group = peer->group; 2619 LIST_LOOP (group->peer, peer, nn) 2620 { 2621 peer->weight = group->conf->weight; 2622 } 2623 return 0; 2624} 2625 2626int 2627peer_weight_unset (struct peer *peer) 2628{ 2629 struct peer_group *group; 2630 struct listnode *nn; 2631 2632 /* Set default weight. */ 2633 if (peer_group_active (peer)) 2634 peer->weight = peer->group->conf->weight; 2635 else 2636 peer->weight = 0; 2637 2638 UNSET_FLAG (peer->config, PEER_CONFIG_WEIGHT); 2639 2640 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 2641 return 0; 2642 2643 /* peer-group member updates. */ 2644 group = peer->group; 2645 LIST_LOOP (group->peer, peer, nn) 2646 { 2647 peer->weight = 0; 2648 } 2649 return 0; 2650} 2651 2652int 2653peer_timers_set (struct peer *peer, u_int32_t keepalive, u_int32_t holdtime) 2654{ 2655 struct peer_group *group; 2656 struct listnode *nn; 2657 2658 /* Not for peer group memeber. */ 2659 if (peer_group_active (peer)) 2660 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 2661 2662 /* keepalive value check. */ 2663 if (keepalive > 65535) 2664 return BGP_ERR_INVALID_VALUE; 2665 2666 /* Holdtime value check. */ 2667 if (holdtime > 65535) 2668 return BGP_ERR_INVALID_VALUE; 2669 2670 /* Holdtime value must be either 0 or greater than 3. */ 2671 if (holdtime < 3 && holdtime != 0) 2672 return BGP_ERR_INVALID_VALUE; 2673 2674 /* Set value to the configuration. */ 2675 SET_FLAG (peer->config, PEER_CONFIG_TIMER); 2676 peer->holdtime = holdtime; 2677 peer->keepalive = (keepalive < holdtime / 3 ? keepalive : holdtime / 3); 2678 2679 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 2680 return 0; 2681 2682 /* peer-group member updates. */ 2683 group = peer->group; 2684 LIST_LOOP (group->peer, peer, nn) 2685 { 2686 SET_FLAG (peer->config, PEER_CONFIG_TIMER); 2687 peer->holdtime = group->conf->holdtime; 2688 peer->keepalive = group->conf->keepalive; 2689 } 2690 return 0; 2691} 2692 2693int 2694peer_timers_unset (struct peer *peer) 2695{ 2696 struct peer_group *group; 2697 struct listnode *nn; 2698 2699 if (peer_group_active (peer)) 2700 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 2701 2702 /* Clear configuration. */ 2703 UNSET_FLAG (peer->config, PEER_CONFIG_TIMER); 2704 peer->keepalive = 0; 2705 peer->holdtime = 0; 2706 2707 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 2708 return 0; 2709 2710 /* peer-group member updates. */ 2711 group = peer->group; 2712 LIST_LOOP (group->peer, peer, nn) 2713 { 2714 UNSET_FLAG (peer->config, PEER_CONFIG_TIMER); 2715 peer->holdtime = 0; 2716 peer->keepalive = 0; 2717 } 2718 2719 return 0; 2720} 2721 2722int 2723peer_timers_connect_set (struct peer *peer, u_int32_t connect) 2724{ 2725 if (peer_group_active (peer)) 2726 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 2727 2728 if (connect > 65535) 2729 return BGP_ERR_INVALID_VALUE; 2730 2731 /* Set value to the configuration. */ 2732 SET_FLAG (peer->config, PEER_CONFIG_CONNECT); 2733 peer->connect = connect; 2734 2735 /* Set value to timer setting. */ 2736 peer->v_connect = connect; 2737 2738 return 0; 2739} 2740 2741int 2742peer_timers_connect_unset (struct peer *peer) 2743{ 2744 if (peer_group_active (peer)) 2745 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 2746 2747 /* Clear configuration. */ 2748 UNSET_FLAG (peer->config, PEER_CONFIG_CONNECT); 2749 peer->connect = 0; 2750 2751 /* Set timer setting to default value. */ 2752 peer->v_connect = BGP_DEFAULT_CONNECT_RETRY; 2753 2754 return 0; 2755} 2756 2757int 2758peer_advertise_interval_set (struct peer *peer, u_int32_t routeadv) 2759{ 2760 if (peer_group_active (peer)) 2761 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 2762 2763 if (routeadv > 600) 2764 return BGP_ERR_INVALID_VALUE; 2765 2766 SET_FLAG (peer->config, PEER_CONFIG_ROUTEADV); 2767 peer->routeadv = routeadv; 2768 peer->v_routeadv = routeadv; 2769 2770 return 0; 2771} 2772 2773int 2774peer_advertise_interval_unset (struct peer *peer) 2775{ 2776 if (peer_group_active (peer)) 2777 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 2778 2779 UNSET_FLAG (peer->config, PEER_CONFIG_ROUTEADV); 2780 peer->routeadv = 0; 2781 2782 if (peer_sort (peer) == BGP_PEER_IBGP) 2783 peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV; 2784 else 2785 peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV; 2786 2787 return 0; 2788} 2789 2790int 2791peer_version_set (struct peer *peer, int version) 2792{ 2793 if (version != BGP_VERSION_4 && version != BGP_VERSION_MP_4_DRAFT_00) 2794 return BGP_ERR_INVALID_VALUE; 2795 2796 peer->version = version; 2797 2798 return 0; 2799} 2800 2801int 2802peer_version_unset (struct peer *peer) 2803{ 2804 peer->version = BGP_VERSION_4; 2805 return 0; 2806} 2807 2808/* neighbor interface */ 2809int 2810peer_interface_set (struct peer *peer, char *str) 2811{ 2812 if (peer->ifname) 2813 free (peer->ifname); 2814 peer->ifname = strdup (str); 2815 2816 return 0; 2817} 2818 2819int 2820peer_interface_unset (struct peer *peer) 2821{ 2822 if (peer->ifname) 2823 free (peer->ifname); 2824 peer->ifname = NULL; 2825 2826 return 0; 2827} 2828 2829/* Allow-as in. */ 2830int 2831peer_allowas_in_set (struct peer *peer, afi_t afi, safi_t safi, int allow_num) 2832{ 2833 struct peer_group *group; 2834 struct listnode *nn; 2835 2836 if (allow_num < 1 || allow_num > 10) 2837 return BGP_ERR_INVALID_VALUE; 2838 2839 if (peer->allowas_in[afi][safi] != allow_num) 2840 { 2841 peer->allowas_in[afi][safi] = allow_num; 2842 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN); 2843 peer_change_action (peer, afi, safi, peer_change_reset_in); 2844 } 2845 2846 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 2847 return 0; 2848 2849 group = peer->group; 2850 LIST_LOOP (group->peer, peer, nn) 2851 { 2852 if (peer->allowas_in[afi][safi] != allow_num) 2853 { 2854 peer->allowas_in[afi][safi] = allow_num; 2855 SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN); 2856 peer_change_action (peer, afi, safi, peer_change_reset_in); 2857 } 2858 2859 } 2860 return 0; 2861} 2862 2863int 2864peer_allowas_in_unset (struct peer *peer, afi_t afi, safi_t safi) 2865{ 2866 struct peer_group *group; 2867 struct listnode *nn; 2868 2869 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN)) 2870 { 2871 peer->allowas_in[afi][safi] = 0; 2872 peer_af_flag_unset (peer, afi, safi, PEER_FLAG_ALLOWAS_IN); 2873 } 2874 2875 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 2876 return 0; 2877 2878 group = peer->group; 2879 LIST_LOOP (group->peer, peer, nn) 2880 { 2881 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN)) 2882 { 2883 peer->allowas_in[afi][safi] = 0; 2884 peer_af_flag_unset (peer, afi, safi, PEER_FLAG_ALLOWAS_IN); 2885 } 2886 } 2887 return 0; 2888} 2889 2890int 2891peer_local_as_set (struct peer *peer, as_t as, int no_prepend) 2892{ 2893 struct bgp *bgp = peer->bgp; 2894 struct peer_group *group; 2895 struct listnode *nn; 2896 2897 if (peer_sort (peer) != BGP_PEER_EBGP 2898 && peer_sort (peer) != BGP_PEER_INTERNAL) 2899 return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP; 2900 2901 if (bgp->as == as) 2902 return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS; 2903 2904 if (peer_group_active (peer)) 2905 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 2906 2907 if (peer->change_local_as == as && 2908 ((CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) && no_prepend) 2909 || (! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) && ! no_prepend))) 2910 return 0; 2911 2912 peer->change_local_as = as; 2913 if (no_prepend) 2914 SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND); 2915 else 2916 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND); 2917 2918 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 2919 { 2920 if (peer->status == Established) 2921 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 2922 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 2923 else 2924 BGP_EVENT_ADD (peer, BGP_Stop); 2925 2926 return 0; 2927 } 2928 2929 group = peer->group; 2930 LIST_LOOP (group->peer, peer, nn) 2931 { 2932 peer->change_local_as = as; 2933 if (no_prepend) 2934 SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND); 2935 else 2936 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND); 2937 2938 if (peer->status == Established) 2939 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 2940 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 2941 else 2942 BGP_EVENT_ADD (peer, BGP_Stop); 2943 } 2944 2945 return 0; 2946} 2947 2948int 2949peer_local_as_unset (struct peer *peer) 2950{ 2951 struct peer_group *group; 2952 struct listnode *nn; 2953 2954 if (peer_group_active (peer)) 2955 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 2956 2957 if (! peer->change_local_as) 2958 return 0; 2959 2960 peer->change_local_as = 0; 2961 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND); 2962 2963 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 2964 { 2965 if (peer->status == Established) 2966 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 2967 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 2968 else 2969 BGP_EVENT_ADD (peer, BGP_Stop); 2970 2971 return 0; 2972 } 2973 2974 group = peer->group; 2975 LIST_LOOP (group->peer, peer, nn) 2976 { 2977 peer->change_local_as = 0; 2978 UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND); 2979 2980 if (peer->status == Established) 2981 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 2982 BGP_NOTIFY_CEASE_CONFIG_CHANGE); 2983 else 2984 BGP_EVENT_ADD (peer, BGP_Stop); 2985 } 2986 return 0; 2987} 2988 2989/* Set distribute list to the peer. */ 2990int 2991peer_distribute_set (struct peer *peer, afi_t afi, safi_t safi, int direct, 2992 char *name) 2993{ 2994 struct bgp_filter *filter; 2995 struct peer_group *group; 2996 struct listnode *nn; 2997 2998 if (! peer->afc[afi][safi]) 2999 return BGP_ERR_PEER_INACTIVE; 3000 3001 if (direct != FILTER_IN && direct != FILTER_OUT) 3002 return BGP_ERR_INVALID_VALUE; 3003 3004 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi)) 3005 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 3006 3007 filter = &peer->filter[afi][safi]; 3008 3009 if (filter->plist[direct].name) 3010 return BGP_ERR_PEER_FILTER_CONFLICT; 3011 3012 if (filter->dlist[direct].name) 3013 free (filter->dlist[direct].name); 3014 filter->dlist[direct].name = strdup (name); 3015 filter->dlist[direct].alist = access_list_lookup (afi, name); 3016 3017 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 3018 return 0; 3019 3020 group = peer->group; 3021 LIST_LOOP (group->peer, peer, nn) 3022 { 3023 filter = &peer->filter[afi][safi]; 3024 3025 if (! peer->af_group[afi][safi]) 3026 continue; 3027 3028 if (filter->dlist[direct].name) 3029 free (filter->dlist[direct].name); 3030 filter->dlist[direct].name = strdup (name); 3031 filter->dlist[direct].alist = access_list_lookup (afi, name); 3032 } 3033 3034 return 0; 3035} 3036 3037int 3038peer_distribute_unset (struct peer *peer, afi_t afi, safi_t safi, int direct) 3039{ 3040 struct bgp_filter *filter; 3041 struct bgp_filter *gfilter; 3042 struct peer_group *group; 3043 struct listnode *nn; 3044 3045 if (! peer->afc[afi][safi]) 3046 return BGP_ERR_PEER_INACTIVE; 3047 3048 if (direct != FILTER_IN && direct != FILTER_OUT) 3049 return BGP_ERR_INVALID_VALUE; 3050 3051 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi)) 3052 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 3053 3054 filter = &peer->filter[afi][safi]; 3055 3056 /* apply peer-group filter */ 3057 if (peer->af_group[afi][safi]) 3058 { 3059 gfilter = &peer->group->conf->filter[afi][safi]; 3060 3061 if (gfilter->dlist[direct].name) 3062 { 3063 if (filter->dlist[direct].name) 3064 free (filter->dlist[direct].name); 3065 filter->dlist[direct].name = strdup (gfilter->dlist[direct].name); 3066 filter->dlist[direct].alist = gfilter->dlist[direct].alist; 3067 return 0; 3068 } 3069 } 3070 3071 if (filter->dlist[direct].name) 3072 free (filter->dlist[direct].name); 3073 filter->dlist[direct].name = NULL; 3074 filter->dlist[direct].alist = NULL; 3075 3076 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 3077 return 0; 3078 3079 group = peer->group; 3080 LIST_LOOP (group->peer, peer, nn) 3081 { 3082 filter = &peer->filter[afi][safi]; 3083 3084 if (! peer->af_group[afi][safi]) 3085 continue; 3086 3087 if (filter->dlist[direct].name) 3088 free (filter->dlist[direct].name); 3089 filter->dlist[direct].name = NULL; 3090 filter->dlist[direct].alist = NULL; 3091 } 3092 3093 return 0; 3094} 3095 3096/* Update distribute list. */ 3097void 3098peer_distribute_update (struct access_list *access) 3099{ 3100 afi_t afi; 3101 safi_t safi; 3102 int direct; 3103 struct listnode *nn, *nm; 3104 struct bgp *bgp; 3105 struct peer *peer; 3106 struct peer_group *group; 3107 struct bgp_filter *filter; 3108 3109 LIST_LOOP (bm->bgp, bgp, nn) 3110 { 3111 LIST_LOOP (bgp->peer, peer, nm) 3112 { 3113 for (afi = AFI_IP; afi < AFI_MAX; afi++) 3114 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) 3115 { 3116 filter = &peer->filter[afi][safi]; 3117 3118 for (direct = FILTER_IN; direct < FILTER_MAX; direct++) 3119 { 3120 if (filter->dlist[direct].name) 3121 filter->dlist[direct].alist = 3122 access_list_lookup (afi, filter->dlist[direct].name); 3123 else 3124 filter->dlist[direct].alist = NULL; 3125 } 3126 } 3127 } 3128 LIST_LOOP (bgp->group, group, nm) 3129 { 3130 for (afi = AFI_IP; afi < AFI_MAX; afi++) 3131 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) 3132 { 3133 filter = &group->conf->filter[afi][safi]; 3134 3135 for (direct = FILTER_IN; direct < FILTER_MAX; direct++) 3136 { 3137 if (filter->dlist[direct].name) 3138 filter->dlist[direct].alist = 3139 access_list_lookup (afi, filter->dlist[direct].name); 3140 else 3141 filter->dlist[direct].alist = NULL; 3142 } 3143 } 3144 } 3145 } 3146} 3147 3148/* Set prefix list to the peer. */ 3149int 3150peer_prefix_list_set (struct peer *peer, afi_t afi, safi_t safi, int direct, 3151 char *name) 3152{ 3153 struct bgp_filter *filter; 3154 struct peer_group *group; 3155 struct listnode *nn; 3156 3157 if (! peer->afc[afi][safi]) 3158 return BGP_ERR_PEER_INACTIVE; 3159 3160 if (direct != FILTER_IN && direct != FILTER_OUT) 3161 return BGP_ERR_INVALID_VALUE; 3162 3163 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi)) 3164 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 3165 3166 filter = &peer->filter[afi][safi]; 3167 3168 if (filter->dlist[direct].name) 3169 return BGP_ERR_PEER_FILTER_CONFLICT; 3170 3171 if (filter->plist[direct].name) 3172 free (filter->plist[direct].name); 3173 filter->plist[direct].name = strdup (name); 3174 filter->plist[direct].plist = prefix_list_lookup (afi, name); 3175 3176 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 3177 return 0; 3178 3179 group = peer->group; 3180 LIST_LOOP (group->peer, peer, nn) 3181 { 3182 filter = &peer->filter[afi][safi]; 3183 3184 if (! peer->af_group[afi][safi]) 3185 continue; 3186 3187 if (filter->plist[direct].name) 3188 free (filter->plist[direct].name); 3189 filter->plist[direct].name = strdup (name); 3190 filter->plist[direct].plist = prefix_list_lookup (afi, name); 3191 } 3192 return 0; 3193} 3194 3195int 3196peer_prefix_list_unset (struct peer *peer, afi_t afi, safi_t safi, int direct) 3197{ 3198 struct bgp_filter *filter; 3199 struct bgp_filter *gfilter; 3200 struct peer_group *group; 3201 struct listnode *nn; 3202 3203 if (! peer->afc[afi][safi]) 3204 return BGP_ERR_PEER_INACTIVE; 3205 3206 if (direct != FILTER_IN && direct != FILTER_OUT) 3207 return BGP_ERR_INVALID_VALUE; 3208 3209 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi)) 3210 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 3211 3212 filter = &peer->filter[afi][safi]; 3213 3214 /* apply peer-group filter */ 3215 if (peer->af_group[afi][safi]) 3216 { 3217 gfilter = &peer->group->conf->filter[afi][safi]; 3218 3219 if (gfilter->plist[direct].name) 3220 { 3221 if (filter->plist[direct].name) 3222 free (filter->plist[direct].name); 3223 filter->plist[direct].name = strdup (gfilter->plist[direct].name); 3224 filter->plist[direct].plist = gfilter->plist[direct].plist; 3225 return 0; 3226 } 3227 } 3228 3229 if (filter->plist[direct].name) 3230 free (filter->plist[direct].name); 3231 filter->plist[direct].name = NULL; 3232 filter->plist[direct].plist = NULL; 3233 3234 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 3235 return 0; 3236 3237 group = peer->group; 3238 LIST_LOOP (group->peer, peer, nn) 3239 { 3240 filter = &peer->filter[afi][safi]; 3241 3242 if (! peer->af_group[afi][safi]) 3243 continue; 3244 3245 if (filter->plist[direct].name) 3246 free (filter->plist[direct].name); 3247 filter->plist[direct].name = NULL; 3248 filter->plist[direct].plist = NULL; 3249 } 3250 3251 return 0; 3252} 3253 3254/* Update prefix-list list. */ 3255void 3256peer_prefix_list_update (struct prefix_list *plist) 3257{ 3258 struct listnode *nn, *nm; 3259 struct bgp *bgp; 3260 struct peer *peer; 3261 struct peer_group *group; 3262 struct bgp_filter *filter; 3263 afi_t afi; 3264 safi_t safi; 3265 int direct; 3266 3267 LIST_LOOP (bm->bgp, bgp, nn) 3268 { 3269 LIST_LOOP (bgp->peer, peer, nm) 3270 { 3271 for (afi = AFI_IP; afi < AFI_MAX; afi++) 3272 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) 3273 { 3274 filter = &peer->filter[afi][safi]; 3275 3276 for (direct = FILTER_IN; direct < FILTER_MAX; direct++) 3277 { 3278 if (filter->plist[direct].name) 3279 filter->plist[direct].plist = 3280 prefix_list_lookup (afi, filter->plist[direct].name); 3281 else 3282 filter->plist[direct].plist = NULL; 3283 } 3284 } 3285 } 3286 LIST_LOOP (bgp->group, group, nm) 3287 { 3288 for (afi = AFI_IP; afi < AFI_MAX; afi++) 3289 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) 3290 { 3291 filter = &group->conf->filter[afi][safi]; 3292 3293 for (direct = FILTER_IN; direct < FILTER_MAX; direct++) 3294 { 3295 if (filter->plist[direct].name) 3296 filter->plist[direct].plist = 3297 prefix_list_lookup (afi, filter->plist[direct].name); 3298 else 3299 filter->plist[direct].plist = NULL; 3300 } 3301 } 3302 } 3303 } 3304} 3305 3306int 3307peer_aslist_set (struct peer *peer, afi_t afi, safi_t safi, int direct, 3308 char *name) 3309{ 3310 struct bgp_filter *filter; 3311 struct peer_group *group; 3312 struct listnode *nn; 3313 3314 if (! peer->afc[afi][safi]) 3315 return BGP_ERR_PEER_INACTIVE; 3316 3317 if (direct != FILTER_IN && direct != FILTER_OUT) 3318 return BGP_ERR_INVALID_VALUE; 3319 3320 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi)) 3321 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 3322 3323 filter = &peer->filter[afi][safi]; 3324 3325 if (filter->aslist[direct].name) 3326 free (filter->aslist[direct].name); 3327 filter->aslist[direct].name = strdup (name); 3328 filter->aslist[direct].aslist = as_list_lookup (name); 3329 3330 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 3331 return 0; 3332 3333 group = peer->group; 3334 LIST_LOOP (group->peer, peer, nn) 3335 { 3336 filter = &peer->filter[afi][safi]; 3337 3338 if (! peer->af_group[afi][safi]) 3339 continue; 3340 3341 if (filter->aslist[direct].name) 3342 free (filter->aslist[direct].name); 3343 filter->aslist[direct].name = strdup (name); 3344 filter->aslist[direct].aslist = as_list_lookup (name); 3345 } 3346 return 0; 3347} 3348 3349int 3350peer_aslist_unset (struct peer *peer,afi_t afi, safi_t safi, int direct) 3351{ 3352 struct bgp_filter *filter; 3353 struct bgp_filter *gfilter; 3354 struct peer_group *group; 3355 struct listnode *nn; 3356 3357 if (! peer->afc[afi][safi]) 3358 return BGP_ERR_PEER_INACTIVE; 3359 3360 if (direct != FILTER_IN && direct != FILTER_OUT) 3361 return BGP_ERR_INVALID_VALUE; 3362 3363 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi)) 3364 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 3365 3366 filter = &peer->filter[afi][safi]; 3367 3368 /* apply peer-group filter */ 3369 if (peer->af_group[afi][safi]) 3370 { 3371 gfilter = &peer->group->conf->filter[afi][safi]; 3372 3373 if (gfilter->aslist[direct].name) 3374 { 3375 if (filter->aslist[direct].name) 3376 free (filter->aslist[direct].name); 3377 filter->aslist[direct].name = strdup (gfilter->aslist[direct].name); 3378 filter->aslist[direct].aslist = gfilter->aslist[direct].aslist; 3379 return 0; 3380 } 3381 } 3382 3383 if (filter->aslist[direct].name) 3384 free (filter->aslist[direct].name); 3385 filter->aslist[direct].name = NULL; 3386 filter->aslist[direct].aslist = NULL; 3387 3388 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 3389 return 0; 3390 3391 group = peer->group; 3392 LIST_LOOP (group->peer, peer, nn) 3393 { 3394 filter = &peer->filter[afi][safi]; 3395 3396 if (! peer->af_group[afi][safi]) 3397 continue; 3398 3399 if (filter->aslist[direct].name) 3400 free (filter->aslist[direct].name); 3401 filter->aslist[direct].name = NULL; 3402 filter->aslist[direct].aslist = NULL; 3403 } 3404 3405 return 0; 3406} 3407 3408void 3409peer_aslist_update () 3410{ 3411 afi_t afi; 3412 safi_t safi; 3413 int direct; 3414 struct listnode *nn, *nm; 3415 struct bgp *bgp; 3416 struct peer *peer; 3417 struct peer_group *group; 3418 struct bgp_filter *filter; 3419 3420 LIST_LOOP (bm->bgp, bgp, nn) 3421 { 3422 LIST_LOOP (bgp->peer, peer, nm) 3423 { 3424 for (afi = AFI_IP; afi < AFI_MAX; afi++) 3425 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) 3426 { 3427 filter = &peer->filter[afi][safi]; 3428 3429 for (direct = FILTER_IN; direct < FILTER_MAX; direct++) 3430 { 3431 if (filter->aslist[direct].name) 3432 filter->aslist[direct].aslist = 3433 as_list_lookup (filter->aslist[direct].name); 3434 else 3435 filter->aslist[direct].aslist = NULL; 3436 } 3437 } 3438 } 3439 LIST_LOOP (bgp->group, group, nm) 3440 { 3441 for (afi = AFI_IP; afi < AFI_MAX; afi++) 3442 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) 3443 { 3444 filter = &group->conf->filter[afi][safi]; 3445 3446 for (direct = FILTER_IN; direct < FILTER_MAX; direct++) 3447 { 3448 if (filter->aslist[direct].name) 3449 filter->aslist[direct].aslist = 3450 as_list_lookup (filter->aslist[direct].name); 3451 else 3452 filter->aslist[direct].aslist = NULL; 3453 } 3454 } 3455 } 3456 } 3457} 3458 3459/* Set route-map to the peer. */ 3460int 3461peer_route_map_set (struct peer *peer, afi_t afi, safi_t safi, int direct, 3462 char *name) 3463{ 3464 struct bgp_filter *filter; 3465 struct peer_group *group; 3466 struct listnode *nn; 3467 3468 if (! peer->afc[afi][safi]) 3469 return BGP_ERR_PEER_INACTIVE; 3470 3471 if (direct != FILTER_IN && direct != FILTER_OUT) 3472 return BGP_ERR_INVALID_VALUE; 3473 3474 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi)) 3475 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 3476 3477 filter = &peer->filter[afi][safi]; 3478 3479 if (filter->map[direct].name) 3480 free (filter->map[direct].name); 3481 3482 filter->map[direct].name = strdup (name); 3483 filter->map[direct].map = route_map_lookup_by_name (name); 3484 3485 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 3486 return 0; 3487 3488 group = peer->group; 3489 LIST_LOOP (group->peer, peer, nn) 3490 { 3491 filter = &peer->filter[afi][safi]; 3492 3493 if (! peer->af_group[afi][safi]) 3494 continue; 3495 3496 if (filter->map[direct].name) 3497 free (filter->map[direct].name); 3498 filter->map[direct].name = strdup (name); 3499 filter->map[direct].map = route_map_lookup_by_name (name); 3500 } 3501 return 0; 3502} 3503 3504/* Unset route-map from the peer. */ 3505int 3506peer_route_map_unset (struct peer *peer, afi_t afi, safi_t safi, int direct) 3507{ 3508 struct bgp_filter *filter; 3509 struct bgp_filter *gfilter; 3510 struct peer_group *group; 3511 struct listnode *nn; 3512 3513 if (! peer->afc[afi][safi]) 3514 return BGP_ERR_PEER_INACTIVE; 3515 3516 if (direct != FILTER_IN && direct != FILTER_OUT) 3517 return BGP_ERR_INVALID_VALUE; 3518 3519 if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi)) 3520 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 3521 3522 filter = &peer->filter[afi][safi]; 3523 3524 /* apply peer-group filter */ 3525 if (peer->af_group[afi][safi]) 3526 { 3527 gfilter = &peer->group->conf->filter[afi][safi]; 3528 3529 if (gfilter->map[direct].name) 3530 { 3531 if (filter->map[direct].name) 3532 free (filter->map[direct].name); 3533 filter->map[direct].name = strdup (gfilter->map[direct].name); 3534 filter->map[direct].map = gfilter->map[direct].map; 3535 return 0; 3536 } 3537 } 3538 3539 if (filter->map[direct].name) 3540 free (filter->map[direct].name); 3541 filter->map[direct].name = NULL; 3542 filter->map[direct].map = NULL; 3543 3544 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 3545 return 0; 3546 3547 group = peer->group; 3548 LIST_LOOP (group->peer, peer, nn) 3549 { 3550 filter = &peer->filter[afi][safi]; 3551 3552 if (! peer->af_group[afi][safi]) 3553 continue; 3554 3555 if (filter->map[direct].name) 3556 free (filter->map[direct].name); 3557 filter->map[direct].name = NULL; 3558 filter->map[direct].map = NULL; 3559 } 3560 return 0; 3561} 3562 3563/* Set unsuppress-map to the peer. */ 3564int 3565peer_unsuppress_map_set (struct peer *peer, afi_t afi, safi_t safi, char *name) 3566{ 3567 struct bgp_filter *filter; 3568 struct peer_group *group; 3569 struct listnode *nn; 3570 3571 if (! peer->afc[afi][safi]) 3572 return BGP_ERR_PEER_INACTIVE; 3573 3574 if (peer_is_group_member (peer, afi, safi)) 3575 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 3576 3577 filter = &peer->filter[afi][safi]; 3578 3579 if (filter->usmap.name) 3580 free (filter->usmap.name); 3581 3582 filter->usmap.name = strdup (name); 3583 filter->usmap.map = route_map_lookup_by_name (name); 3584 3585 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 3586 return 0; 3587 3588 group = peer->group; 3589 LIST_LOOP (group->peer, peer, nn) 3590 { 3591 filter = &peer->filter[afi][safi]; 3592 3593 if (! peer->af_group[afi][safi]) 3594 continue; 3595 3596 if (filter->usmap.name) 3597 free (filter->usmap.name); 3598 filter->usmap.name = strdup (name); 3599 filter->usmap.map = route_map_lookup_by_name (name); 3600 } 3601 return 0; 3602} 3603 3604/* Unset route-map from the peer. */ 3605int 3606peer_unsuppress_map_unset (struct peer *peer, afi_t afi, safi_t safi) 3607{ 3608 struct bgp_filter *filter; 3609 struct peer_group *group; 3610 struct listnode *nn; 3611 3612 if (! peer->afc[afi][safi]) 3613 return BGP_ERR_PEER_INACTIVE; 3614 3615 if (peer_is_group_member (peer, afi, safi)) 3616 return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; 3617 3618 filter = &peer->filter[afi][safi]; 3619 3620 if (filter->usmap.name) 3621 free (filter->usmap.name); 3622 filter->usmap.name = NULL; 3623 filter->usmap.map = NULL; 3624 3625 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 3626 return 0; 3627 3628 group = peer->group; 3629 LIST_LOOP (group->peer, peer, nn) 3630 { 3631 filter = &peer->filter[afi][safi]; 3632 3633 if (! peer->af_group[afi][safi]) 3634 continue; 3635 3636 if (filter->usmap.name) 3637 free (filter->usmap.name); 3638 filter->usmap.name = NULL; 3639 filter->usmap.map = NULL; 3640 } 3641 return 0; 3642} 3643 3644int 3645peer_maximum_prefix_set (struct peer *peer, afi_t afi, safi_t safi, 3646 u_int32_t max, int warning) 3647{ 3648 if (! peer->afc[afi][safi]) 3649 return BGP_ERR_PEER_INACTIVE; 3650 3651 peer->pmax[afi][safi] = max; 3652 peer->pmax_warning[afi][safi] = (warning ? 1 : 0); 3653 3654 return 0; 3655} 3656 3657int 3658peer_maximum_prefix_unset (struct peer *peer, afi_t afi, safi_t safi) 3659{ 3660 if (! peer->afc[afi][safi]) 3661 return BGP_ERR_PEER_INACTIVE; 3662 3663 peer->pmax[afi][safi] = 0; 3664 peer->pmax_warning[afi][safi] = 0; 3665 3666 return 0; 3667} 3668 3669int 3670peer_clear (struct peer *peer) 3671{ 3672 if (! CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN)) 3673 { 3674 UNSET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW); 3675 peer->v_start = BGP_INIT_START_TIMER; 3676 if (peer->status == Established) 3677 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 3678 BGP_NOTIFY_CEASE_ADMIN_RESET); 3679 else 3680 BGP_EVENT_ADD (peer, BGP_Stop); 3681 } 3682 return 0; 3683} 3684 3685int 3686peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi, 3687 enum bgp_clear_type stype) 3688{ 3689 if (peer->status != Established) 3690 return 0; 3691 3692 if (! peer->afc[afi][safi]) 3693 return BGP_ERR_AF_UNCONFIGURED; 3694 3695 if (stype == BGP_CLEAR_SOFT_OUT || stype == BGP_CLEAR_SOFT_BOTH) 3696 bgp_announce_route (peer, afi, safi); 3697 3698 if (stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX) 3699 { 3700 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV) 3701 && (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV) 3702 || CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV))) 3703 { 3704 struct bgp_filter *filter = &peer->filter[afi][safi]; 3705 u_char prefix_type; 3706 3707 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV)) 3708 prefix_type = ORF_TYPE_PREFIX; 3709 else 3710 prefix_type = ORF_TYPE_PREFIX_OLD; 3711 3712 if (filter->plist[FILTER_IN].plist) 3713 { 3714 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND)) 3715 bgp_route_refresh_send (peer, afi, safi, 3716 prefix_type, REFRESH_DEFER, 1); 3717 bgp_route_refresh_send (peer, afi, safi, prefix_type, 3718 REFRESH_IMMEDIATE, 0); 3719 } 3720 else 3721 { 3722 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND)) 3723 bgp_route_refresh_send (peer, afi, safi, 3724 prefix_type, REFRESH_IMMEDIATE, 1); 3725 else 3726 bgp_route_refresh_send (peer, afi, safi, 0, 0, 0); 3727 } 3728 return 0; 3729 } 3730 } 3731 3732 if (stype == BGP_CLEAR_SOFT_IN || stype == BGP_CLEAR_SOFT_BOTH 3733 || stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX) 3734 { 3735 /* If neighbor has soft reconfiguration inbound flag. 3736 Use Adj-RIB-In database. */ 3737 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)) 3738 bgp_soft_reconfig_in (peer, afi, safi); 3739 else 3740 { 3741 /* If neighbor has route refresh capability, send route refresh 3742 message to the peer. */ 3743 if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV) 3744 || CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV)) 3745 bgp_route_refresh_send (peer, afi, safi, 0, 0, 0); 3746 else 3747 return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED; 3748 } 3749 } 3750 return 0; 3751} 3752 3753/* Display peer uptime. */ 3754char * 3755peer_uptime (time_t uptime2, char *buf, size_t len) 3756{ 3757 time_t uptime1; 3758 struct tm *tm; 3759 3760 /* Check buffer length. */ 3761 if (len < BGP_UPTIME_LEN) 3762 { 3763 zlog_warn ("peer_uptime (): buffer shortage %d", len); 3764 return ""; 3765 } 3766 3767 /* If there is no connection has been done before print `never'. */ 3768 if (uptime2 == 0) 3769 { 3770 snprintf (buf, len, "never "); 3771 return buf; 3772 } 3773 3774 /* Get current time. */ 3775 uptime1 = time (NULL); 3776 uptime1 -= uptime2; 3777 tm = gmtime (&uptime1); 3778 3779 /* Making formatted timer strings. */ 3780#define ONE_DAY_SECOND 60*60*24 3781#define ONE_WEEK_SECOND 60*60*24*7 3782 3783 if (uptime1 < ONE_DAY_SECOND) 3784 snprintf (buf, len, "%02d:%02d:%02d", 3785 tm->tm_hour, tm->tm_min, tm->tm_sec); 3786 else if (uptime1 < ONE_WEEK_SECOND) 3787 snprintf (buf, len, "%dd%02dh%02dm", 3788 tm->tm_yday, tm->tm_hour, tm->tm_min); 3789 else 3790 snprintf (buf, len, "%02dw%dd%02dh", 3791 tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); 3792 return buf; 3793} 3794 3795void 3796bgp_config_write_filter (struct vty *vty, struct peer *peer, 3797 afi_t afi, safi_t safi) 3798{ 3799 struct bgp_filter *filter; 3800 struct bgp_filter *gfilter = NULL; 3801 char *addr; 3802 int in = FILTER_IN; 3803 int out = FILTER_OUT; 3804 3805 addr = peer->host; 3806 filter = &peer->filter[afi][safi]; 3807 if (peer->af_group[afi][safi]) 3808 gfilter = &peer->group->conf->filter[afi][safi]; 3809 3810 /* distribute-list. */ 3811 if (filter->dlist[in].name) 3812 if (! gfilter || ! gfilter->dlist[in].name 3813 || strcmp (filter->dlist[in].name, gfilter->dlist[in].name) != 0) 3814 vty_out (vty, " neighbor %s distribute-list %s in%s", addr, 3815 filter->dlist[in].name, VTY_NEWLINE); 3816 if (filter->dlist[out].name && ! gfilter) 3817 vty_out (vty, " neighbor %s distribute-list %s out%s", addr, 3818 filter->dlist[out].name, VTY_NEWLINE); 3819 3820 /* prefix-list. */ 3821 if (filter->plist[in].name) 3822 if (! gfilter || ! gfilter->plist[in].name 3823 || strcmp (filter->plist[in].name, gfilter->plist[in].name) != 0) 3824 vty_out (vty, " neighbor %s prefix-list %s in%s", addr, 3825 filter->plist[in].name, VTY_NEWLINE); 3826 if (filter->plist[out].name && ! gfilter) 3827 vty_out (vty, " neighbor %s prefix-list %s out%s", addr, 3828 filter->plist[out].name, VTY_NEWLINE); 3829 3830 /* route-map. */ 3831 if (filter->map[in].name) 3832 if (! gfilter || ! gfilter->map[in].name 3833 || strcmp (filter->map[in].name, gfilter->map[in].name) != 0) 3834 vty_out (vty, " neighbor %s route-map %s in%s", addr, 3835 filter->map[in].name, VTY_NEWLINE); 3836 if (filter->map[out].name && ! gfilter) 3837 vty_out (vty, " neighbor %s route-map %s out%s", addr, 3838 filter->map[out].name, VTY_NEWLINE); 3839 3840 /* unsuppress-map */ 3841 if (filter->usmap.name && ! gfilter) 3842 vty_out (vty, " neighbor %s unsuppress-map %s%s", addr, 3843 filter->usmap.name, VTY_NEWLINE); 3844 3845 /* filter-list. */ 3846 if (filter->aslist[in].name) 3847 if (! gfilter || ! gfilter->aslist[in].name 3848 || strcmp (filter->aslist[in].name, gfilter->aslist[in].name) != 0) 3849 vty_out (vty, " neighbor %s filter-list %s in%s", addr, 3850 filter->aslist[in].name, VTY_NEWLINE); 3851 if (filter->aslist[out].name && ! gfilter) 3852 vty_out (vty, " neighbor %s filter-list %s out%s", addr, 3853 filter->aslist[out].name, VTY_NEWLINE); 3854} 3855 3856/* BGP peer configuration display function. */ 3857void 3858bgp_config_write_peer (struct vty *vty, struct bgp *bgp, 3859 struct peer *peer, afi_t afi, safi_t safi) 3860{ 3861 struct bgp_filter *filter; 3862 struct peer *g_peer = NULL; 3863 char buf[SU_ADDRSTRLEN]; 3864 char *addr; 3865 3866 filter = &peer->filter[afi][safi]; 3867 addr = peer->host; 3868 if (peer_group_active (peer)) 3869 g_peer = peer->group->conf; 3870 3871 /************************************ 3872 ****** Global to the neighbor ****** 3873 ************************************/ 3874 if (afi == AFI_IP && safi == SAFI_UNICAST) 3875 { 3876 /* remote-as. */ 3877 if (! peer_group_active (peer)) 3878 { 3879 if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) 3880 vty_out (vty, " neighbor %s peer-group%s", addr, 3881 VTY_NEWLINE); 3882 if (peer->as) 3883 vty_out (vty, " neighbor %s remote-as %d%s", addr, peer->as, 3884 VTY_NEWLINE); 3885 } 3886 else 3887 { 3888 if (! g_peer->as) 3889 vty_out (vty, " neighbor %s remote-as %d%s", addr, peer->as, 3890 VTY_NEWLINE); 3891 if (peer->af_group[AFI_IP][SAFI_UNICAST]) 3892 vty_out (vty, " neighbor %s peer-group %s%s", addr, 3893 peer->group->name, VTY_NEWLINE); 3894 } 3895 3896 /* local-as. */ 3897 if (peer->change_local_as) 3898 if (! peer_group_active (peer)) 3899 vty_out (vty, " neighbor %s local-as %d%s%s", addr, 3900 peer->change_local_as, 3901 CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) ? 3902 " no-prepend" : "", VTY_NEWLINE); 3903 3904 /* Description. */ 3905 if (peer->desc) 3906 vty_out (vty, " neighbor %s description %s%s", addr, peer->desc, 3907 VTY_NEWLINE); 3908 3909 /* Shutdown. */ 3910 if (CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN)) 3911 if (! peer_group_active (peer) || 3912 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_SHUTDOWN)) 3913 vty_out (vty, " neighbor %s shutdown%s", addr, VTY_NEWLINE); 3914 3915 /* BGP port. */ 3916 if (peer->port != BGP_PORT_DEFAULT) 3917 vty_out (vty, " neighbor %s port %d%s", addr, peer->port, 3918 VTY_NEWLINE); 3919 3920 /* Local interface name. */ 3921 if (peer->ifname) 3922 vty_out (vty, " neighbor %s interface %s%s", addr, peer->ifname, 3923 VTY_NEWLINE); 3924 3925 /* Passive. */ 3926 if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE)) 3927 if (! peer_group_active (peer) || 3928 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_PASSIVE)) 3929 vty_out (vty, " neighbor %s passive%s", addr, VTY_NEWLINE); 3930 3931 /* EBGP multihop. */ 3932 if (peer_sort (peer) != BGP_PEER_IBGP && peer->ttl != 1) 3933 if (! peer_group_active (peer) || 3934 g_peer->ttl != peer->ttl) 3935 vty_out (vty, " neighbor %s ebgp-multihop %d%s", addr, peer->ttl, 3936 VTY_NEWLINE); 3937 3938 /* Enforce multihop. */ 3939 if (CHECK_FLAG (peer->flags, PEER_FLAG_ENFORCE_MULTIHOP)) 3940 if (! peer_group_active (peer) || 3941 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_ENFORCE_MULTIHOP)) 3942 vty_out (vty, " neighbor %s enforce-multihop%s", addr, VTY_NEWLINE); 3943 3944 /* Update-source. */ 3945 if (peer->update_if) 3946 if (! peer_group_active (peer) || ! g_peer->update_if 3947 || strcmp (g_peer->update_if, peer->update_if) != 0) 3948 vty_out (vty, " neighbor %s update-source %s%s", addr, 3949 peer->update_if, VTY_NEWLINE); 3950 if (peer->update_source) 3951 if (! peer_group_active (peer) || ! g_peer->update_source 3952 || sockunion_cmp (g_peer->update_source, 3953 peer->update_source) != 0) 3954 vty_out (vty, " neighbor %s update-source %s%s", addr, 3955 sockunion2str (peer->update_source, buf, SU_ADDRSTRLEN), 3956 VTY_NEWLINE); 3957 3958 /* BGP version print. */ 3959 if (peer->version == BGP_VERSION_MP_4_DRAFT_00) 3960 vty_out (vty, " neighbor %s version %s%s", 3961 addr,"4-", VTY_NEWLINE); 3962 3963 /* advertisement-interval */ 3964 if (CHECK_FLAG (peer->config, PEER_CONFIG_ROUTEADV)) 3965 vty_out (vty, " neighbor %s advertisement-interval %d%s", 3966 addr, peer->v_routeadv, VTY_NEWLINE); 3967 3968 /* timers. */ 3969 if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER) 3970 && ! peer_group_active (peer)) 3971 vty_out (vty, " neighbor %s timers %d %d%s", addr, 3972 peer->keepalive, peer->holdtime, VTY_NEWLINE); 3973 3974 if (CHECK_FLAG (peer->config, PEER_CONFIG_CONNECT)) 3975 vty_out (vty, " neighbor %s timers connect %d%s", addr, 3976 peer->connect, VTY_NEWLINE); 3977 3978 /* Default weight. */ 3979 if (CHECK_FLAG (peer->config, PEER_CONFIG_WEIGHT)) 3980 if (! peer_group_active (peer) || 3981 g_peer->weight != peer->weight) 3982 vty_out (vty, " neighbor %s weight %d%s", addr, peer->weight, 3983 VTY_NEWLINE); 3984 3985 /* Route refresh. */ 3986 if (CHECK_FLAG (peer->flags, PEER_FLAG_NO_ROUTE_REFRESH_CAP)) 3987 if (! peer_group_active (peer) || 3988 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_NO_ROUTE_REFRESH_CAP)) 3989 vty_out (vty, " no neighbor %s capability route-refresh%s", addr, 3990 VTY_NEWLINE); 3991 3992 /* Dynamic capability. */ 3993 if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY)) 3994 if (! peer_group_active (peer) || 3995 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY)) 3996 vty_out (vty, " neighbor %s capability dynamic%s", addr, 3997 VTY_NEWLINE); 3998 3999 /* dont capability negotiation. */ 4000 if (CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY)) 4001 if (! peer_group_active (peer) || 4002 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DONT_CAPABILITY)) 4003 vty_out (vty, " neighbor %s dont-capability-negotiate%s", addr, 4004 VTY_NEWLINE); 4005 4006 /* override capability negotiation. */ 4007 if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY)) 4008 if (! peer_group_active (peer) || 4009 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY)) 4010 vty_out (vty, " neighbor %s override-capability%s", addr, 4011 VTY_NEWLINE); 4012 4013 /* strict capability negotiation. */ 4014 if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH)) 4015 if (! peer_group_active (peer) || 4016 ! CHECK_FLAG (g_peer->flags, PEER_FLAG_STRICT_CAP_MATCH)) 4017 vty_out (vty, " neighbor %s strict-capability-match%s", addr, 4018 VTY_NEWLINE); 4019 4020 if (! peer_group_active (peer)) 4021 { 4022 if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4)) 4023 { 4024 if (peer->afc[AFI_IP][SAFI_UNICAST]) 4025 vty_out (vty, " neighbor %s activate%s", addr, VTY_NEWLINE); 4026 } 4027 else 4028 { 4029 if (! peer->afc[AFI_IP][SAFI_UNICAST]) 4030 vty_out (vty, " no neighbor %s activate%s", addr, VTY_NEWLINE); 4031 } 4032 } 4033 } 4034 4035 4036 /************************************ 4037 ****** Per AF to the neighbor ****** 4038 ************************************/ 4039 4040 if (! (afi == AFI_IP && safi == SAFI_UNICAST)) 4041 { 4042 if (peer->af_group[afi][safi]) 4043 vty_out (vty, " neighbor %s peer-group %s%s", addr, 4044 peer->group->name, VTY_NEWLINE); 4045 else 4046 vty_out (vty, " neighbor %s activate%s", addr, VTY_NEWLINE); 4047 } 4048 4049 /* ORF capability. */ 4050 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM) 4051 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM)) 4052 if (! peer->af_group[afi][safi]) 4053 { 4054 vty_out (vty, " neighbor %s capability orf prefix-list", addr); 4055 4056 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM) 4057 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM)) 4058 vty_out (vty, " both"); 4059 else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)) 4060 vty_out (vty, " send"); 4061 else 4062 vty_out (vty, " receive"); 4063 vty_out (vty, "%s", VTY_NEWLINE); 4064 } 4065 4066 /* Route reflector client. */ 4067 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REFLECTOR_CLIENT) 4068 && ! peer->af_group[afi][safi]) 4069 vty_out (vty, " neighbor %s route-reflector-client%s", addr, 4070 VTY_NEWLINE); 4071 4072 /* Nexthop self. */ 4073 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_SELF) 4074 && ! peer->af_group[afi][safi]) 4075 vty_out (vty, " neighbor %s next-hop-self%s", addr, VTY_NEWLINE); 4076 4077 /* Remove private AS. */ 4078 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS) 4079 && ! peer->af_group[afi][safi]) 4080 vty_out (vty, " neighbor %s remove-private-AS%s", 4081 addr, VTY_NEWLINE); 4082 4083 /* send-community print. */ 4084 if (! peer->af_group[afi][safi]) 4085 { 4086 if (bgp_option_check (BGP_OPT_CONFIG_CISCO)) 4087 { 4088 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY) 4089 && peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY)) 4090 vty_out (vty, " neighbor %s send-community both%s", addr, VTY_NEWLINE); 4091 else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY)) 4092 vty_out (vty, " neighbor %s send-community extended%s", 4093 addr, VTY_NEWLINE); 4094 else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY)) 4095 vty_out (vty, " neighbor %s send-community%s", addr, VTY_NEWLINE); 4096 } 4097 else 4098 { 4099 if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY) 4100 && ! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY)) 4101 vty_out (vty, " no neighbor %s send-community both%s", 4102 addr, VTY_NEWLINE); 4103 else if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY)) 4104 vty_out (vty, " no neighbor %s send-community extended%s", 4105 addr, VTY_NEWLINE); 4106 else if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY)) 4107 vty_out (vty, " no neighbor %s send-community%s", 4108 addr, VTY_NEWLINE); 4109 } 4110 } 4111 4112 /* Default information */ 4113 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE)) 4114 { 4115 vty_out (vty, " neighbor %s default-originate", addr); 4116 if (peer->default_rmap[afi][safi].name) 4117 vty_out (vty, " route-map %s", peer->default_rmap[afi][safi].name); 4118 vty_out (vty, "%s", VTY_NEWLINE); 4119 } 4120 4121 /* Soft reconfiguration inbound. */ 4122 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)) 4123 if (! peer->af_group[afi][safi] || 4124 ! CHECK_FLAG (g_peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)) 4125 vty_out (vty, " neighbor %s soft-reconfiguration inbound%s", addr, 4126 VTY_NEWLINE); 4127 4128 /* maximum-prefix. */ 4129 if (peer->pmax[afi][safi]) 4130 vty_out (vty, " neighbor %s maximum-prefix %ld%s%s", 4131 addr, peer->pmax[afi][safi], 4132 peer->pmax_warning[afi][safi] ? " warning-only" : "", 4133 VTY_NEWLINE); 4134 4135 /* Route server client. */ 4136 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT) 4137 && ! peer->af_group[afi][safi]) 4138 vty_out (vty, " neighbor %s route-server-client%s", addr, VTY_NEWLINE); 4139 4140 /* Allow AS in. */ 4141 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_ALLOWAS_IN)) 4142 if (! peer_group_active (peer) 4143 || ! peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_ALLOWAS_IN) 4144 || peer->allowas_in[afi][safi] != g_peer->allowas_in[afi][safi]) 4145 { 4146 if (peer->allowas_in[afi][safi] == 3) 4147 vty_out (vty, " neighbor %s allowas-in%s", addr, VTY_NEWLINE); 4148 else 4149 vty_out (vty, " neighbor %s allowas-in %d%s", addr, 4150 peer->allowas_in[afi][safi], VTY_NEWLINE); 4151 } 4152 4153 /* Filter. */ 4154 bgp_config_write_filter (vty, peer, afi, safi); 4155 4156 /* atribute-unchanged. */ 4157 if ((CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED) 4158 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED) 4159 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED)) 4160 && ! peer->af_group[afi][safi]) 4161 { 4162 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED) 4163 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED) 4164 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED)) 4165 vty_out (vty, " neighbor %s attribute-unchanged%s", addr, VTY_NEWLINE); 4166 else 4167 vty_out (vty, " neighbor %s attribute-unchanged%s%s%s%s", addr, 4168 (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)) ? 4169 " as-path" : "", 4170 (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)) ? 4171 " next-hop" : "", 4172 (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED)) ? 4173 " med" : "", VTY_NEWLINE); 4174 } 4175} 4176 4177/* Display "address-family" configuration header. */ 4178void 4179bgp_config_write_family_header (struct vty *vty, afi_t afi, safi_t safi, 4180 int *write) 4181{ 4182 if (*write) 4183 return; 4184 4185 if (afi == AFI_IP && safi == SAFI_UNICAST) 4186 return; 4187 4188 vty_out (vty, "!%s address-family ", VTY_NEWLINE); 4189 4190 if (afi == AFI_IP) 4191 { 4192 if (safi == SAFI_MULTICAST) 4193 vty_out (vty, "ipv4 multicast"); 4194 else if (safi == SAFI_MPLS_VPN) 4195 vty_out (vty, "vpnv4 unicast"); 4196 } 4197 else if (afi == AFI_IP6) 4198 vty_out (vty, "ipv6"); 4199 4200 vty_out (vty, "%s", VTY_NEWLINE); 4201 4202 *write = 1; 4203} 4204 4205/* Address family based peer configuration display. */ 4206int 4207bgp_config_write_family (struct vty *vty, struct bgp *bgp, afi_t afi, 4208 safi_t safi) 4209{ 4210 int write = 0; 4211 struct peer *peer; 4212 struct peer_group *group; 4213 struct listnode *nn; 4214 4215 bgp_config_write_network (vty, bgp, afi, safi, &write); 4216 4217 bgp_config_write_redistribute (vty, bgp, afi, safi, &write); 4218 4219 LIST_LOOP (bgp->group, group, nn) 4220 { 4221 if (group->conf->afc[afi][safi]) 4222 { 4223 bgp_config_write_family_header (vty, afi, safi, &write); 4224 bgp_config_write_peer (vty, bgp, group->conf, afi, safi); 4225 } 4226 } 4227 LIST_LOOP (bgp->peer, peer, nn) 4228 { 4229 if (peer->afc[afi][safi]) 4230 { 4231 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER)) 4232 { 4233 bgp_config_write_family_header (vty, afi, safi, &write); 4234 bgp_config_write_peer (vty, bgp, peer, afi, safi); 4235 } 4236 } 4237 } 4238 if (write) 4239 vty_out (vty, " exit-address-family%s", VTY_NEWLINE); 4240 4241 return write; 4242} 4243 4244int 4245bgp_config_write (struct vty *vty) 4246{ 4247 int write = 0; 4248 struct bgp *bgp; 4249 struct peer_group *group; 4250 struct peer *peer; 4251 struct listnode *nn, *nm, *no; 4252 4253 /* BGP Multiple instance. */ 4254 if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE)) 4255 { 4256 vty_out (vty, "bgp multiple-instance%s", VTY_NEWLINE); 4257 write++; 4258 } 4259 4260 /* BGP Config type. */ 4261 if (bgp_option_check (BGP_OPT_CONFIG_CISCO)) 4262 { 4263 vty_out (vty, "bgp config-type cisco%s", VTY_NEWLINE); 4264 write++; 4265 } 4266 4267 /* BGP configuration. */ 4268 LIST_LOOP (bm->bgp, bgp, nn) 4269 { 4270 if (write) 4271 vty_out (vty, "!%s", VTY_NEWLINE); 4272 4273 /* Router bgp ASN */ 4274 vty_out (vty, "router bgp %d", bgp->as); 4275 4276 if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE)) 4277 { 4278 if (bgp->name) 4279 vty_out (vty, " view %s", bgp->name); 4280 } 4281 vty_out (vty, "%s", VTY_NEWLINE); 4282 4283 /* No Synchronization */ 4284 if (bgp_option_check (BGP_OPT_CONFIG_CISCO)) 4285 vty_out (vty, " no synchronization%s", VTY_NEWLINE); 4286 4287 /* BGP fast-external-failover. */ 4288 if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) 4289 vty_out (vty, " no bgp fast-external-failover%s", VTY_NEWLINE); 4290 4291 /* BGP router ID. */ 4292 if (CHECK_FLAG (bgp->config, BGP_CONFIG_ROUTER_ID)) 4293 vty_out (vty, " bgp router-id %s%s", inet_ntoa (bgp->router_id), 4294 VTY_NEWLINE); 4295 4296 /* BGP configuration. */ 4297 if (bgp_flag_check (bgp, BGP_FLAG_ALWAYS_COMPARE_MED)) 4298 vty_out (vty, " bgp always-compare-med%s", VTY_NEWLINE); 4299 4300 /* BGP default ipv4-unicast. */ 4301 if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4)) 4302 vty_out (vty, " no bgp default ipv4-unicast%s", VTY_NEWLINE); 4303 4304 /* BGP default local-preference. */ 4305 if (bgp->default_local_pref != BGP_DEFAULT_LOCAL_PREF) 4306 vty_out (vty, " bgp default local-preference %d%s", 4307 bgp->default_local_pref, VTY_NEWLINE); 4308 4309 /* BGP client-to-client reflection. */ 4310 if (bgp_flag_check (bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT)) 4311 vty_out (vty, " no bgp client-to-client reflection%s", VTY_NEWLINE); 4312 4313 /* BGP cluster ID. */ 4314 if (CHECK_FLAG (bgp->config, BGP_CONFIG_CLUSTER_ID)) 4315 vty_out (vty, " bgp cluster-id %s%s", inet_ntoa (bgp->cluster_id), 4316 VTY_NEWLINE); 4317 4318 /* Confederation Information */ 4319 if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION)) 4320 { 4321 vty_out (vty, " bgp confederation identifier %i%s", bgp->confed_id, 4322 VTY_NEWLINE); 4323 if (bgp->confed_peers_cnt > 0) 4324 { 4325 int i; 4326 4327 vty_out (vty, " bgp confederation peers"); 4328 4329 for (i = 0; i < bgp->confed_peers_cnt; i++) 4330 { 4331 vty_out(vty, " "); 4332 vty_out(vty, "%d", bgp->confed_peers[i]); 4333 } 4334 4335 vty_out (vty, "%s", VTY_NEWLINE); 4336 } 4337 } 4338 4339 /* BGP enforce-first-as. */ 4340 if (bgp_flag_check (bgp, BGP_FLAG_ENFORCE_FIRST_AS)) 4341 vty_out (vty, " bgp enforce-first-as%s", VTY_NEWLINE); 4342 4343 /* BGP deterministic-med. */ 4344 if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED)) 4345 vty_out (vty, " bgp deterministic-med%s", VTY_NEWLINE); 4346 4347 /* BGP bestpath method. */ 4348 if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_IGNORE)) 4349 vty_out (vty, " bgp bestpath as-path ignore%s", VTY_NEWLINE); 4350 if (bgp_flag_check (bgp, BGP_FLAG_COMPARE_ROUTER_ID)) 4351 vty_out (vty, " bgp bestpath compare-routerid%s", VTY_NEWLINE); 4352 if (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED) 4353 || bgp_flag_check (bgp, BGP_FLAG_MED_MISSING_AS_WORST)) 4354 { 4355 vty_out (vty, " bgp bestpath med"); 4356 if (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED)) 4357 vty_out (vty, " confed"); 4358 if (bgp_flag_check (bgp, BGP_FLAG_MED_MISSING_AS_WORST)) 4359 vty_out (vty, " missing-as-worst"); 4360 vty_out (vty, "%s", VTY_NEWLINE); 4361 } 4362 4363 /* BGP network import check. */ 4364 if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK)) 4365 vty_out (vty, " bgp network import-check%s", VTY_NEWLINE); 4366 4367 /* BGP scan interval. */ 4368 bgp_config_write_scan_time (vty); 4369 4370 /* BGP flag dampening. */ 4371 if (CHECK_FLAG (bgp->af_flags[AFI_IP][SAFI_UNICAST], 4372 BGP_CONFIG_DAMPENING)) 4373 bgp_config_write_damp (vty); 4374 4375 /* BGP static route configuration. */ 4376 bgp_config_write_network (vty, bgp, AFI_IP, SAFI_UNICAST, &write); 4377 4378 /* BGP redistribute configuration. */ 4379 bgp_config_write_redistribute (vty, bgp, AFI_IP, SAFI_UNICAST, &write); 4380 4381 /* BGP timers configuration. */ 4382 if (bgp->default_keepalive != BGP_DEFAULT_KEEPALIVE 4383 && bgp->default_holdtime != BGP_DEFAULT_HOLDTIME) 4384 vty_out (vty, " timers bgp %d %d%s", bgp->default_keepalive, 4385 bgp->default_holdtime, VTY_NEWLINE); 4386 4387 /* peer-group */ 4388 LIST_LOOP (bgp->group, group, nm) 4389 { 4390 bgp_config_write_peer (vty, bgp, group->conf, AFI_IP, SAFI_UNICAST); 4391 } 4392 4393 /* Normal neighbor configuration. */ 4394 LIST_LOOP (bgp->peer, peer, no) 4395 { 4396 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER)) 4397 bgp_config_write_peer (vty, bgp, peer, AFI_IP, SAFI_UNICAST); 4398 } 4399 4400 /* Distance configuration. */ 4401 bgp_config_write_distance (vty, bgp); 4402 4403 /* No auto-summary */ 4404 if (bgp_option_check (BGP_OPT_CONFIG_CISCO)) 4405 vty_out (vty, " no auto-summary%s", VTY_NEWLINE); 4406 4407 /* IPv4 multicast configuration. */ 4408 write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_MULTICAST); 4409 4410 /* IPv4 VPN configuration. */ 4411 write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_MPLS_VPN); 4412 4413 /* IPv6 unicast configuration. */ 4414 write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_UNICAST); 4415 4416 write++; 4417 } 4418 return write; 4419} 4420 4421void 4422bgp_master_init () 4423{ 4424 memset (&bgp_master, 0, sizeof (struct bgp_master)); 4425 4426 bm = &bgp_master; 4427 bm->bgp = list_new (); 4428 bm->port = BGP_PORT_DEFAULT; 4429 bm->master = thread_master_create (); 4430 bm->start_time = time (NULL); 4431} 4432 4433void 4434bgp_init () 4435{ 4436 void bgp_zebra_init (); 4437 void bgp_route_map_init (); 4438 void bgp_filter_init (); 4439 4440 /* BGP VTY commands installation. */ 4441 bgp_vty_init (); 4442 4443 /* Create BGP server socket. */ 4444 bgp_socket (NULL, bm->port); 4445 4446 /* Init zebra. */ 4447 bgp_zebra_init (); 4448 4449 /* BGP inits. */ 4450 bgp_attr_init (); 4451 bgp_debug_init (); 4452 bgp_dump_init (); 4453 bgp_route_init (); 4454 bgp_route_map_init (); 4455 bgp_scan_init (); 4456 bgp_mplsvpn_init (); 4457 4458 /* Access list initialize. */ 4459 access_list_init (); 4460 access_list_add_hook (peer_distribute_update); 4461 access_list_delete_hook (peer_distribute_update); 4462 4463 /* Filter list initialize. */ 4464 bgp_filter_init (); 4465 as_list_add_hook (peer_aslist_update); 4466 as_list_delete_hook (peer_aslist_update); 4467 4468 /* Prefix list initialize.*/ 4469 prefix_list_init (); 4470 prefix_list_add_hook (peer_prefix_list_update); 4471 prefix_list_delete_hook (peer_prefix_list_update); 4472 4473 /* Community list initialize. */ 4474 bgp_clist = community_list_init (); 4475 4476#ifdef HAVE_SNMP 4477 bgp_snmp_init (); 4478#endif /* HAVE_SNMP */ 4479} 4480