bgpd.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:124k
源码类别:

网络

开发平台:

Unix_Linux

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