File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / bgpd / bgpd.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:10 2016 UTC (7 years, 7 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

    1: /* BGP-4, BGP-4+ daemon program
    2:    Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
    3: 
    4: This file is part of GNU Zebra.
    5: 
    6: GNU Zebra is free software; you can redistribute it and/or modify it
    7: under the terms of the GNU General Public License as published by the
    8: Free Software Foundation; either version 2, or (at your option) any
    9: later version.
   10: 
   11: GNU Zebra is distributed in the hope that it will be useful, but
   12: WITHOUT ANY WARRANTY; without even the implied warranty of
   13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14: General Public License for more details.
   15: 
   16: You should have received a copy of the GNU General Public License
   17: along with GNU Zebra; see the file COPYING.  If not, write to the Free
   18: Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   19: 02111-1307, USA.  */
   20: 
   21: #include <zebra.h>
   22: 
   23: #include "prefix.h"
   24: #include "thread.h"
   25: #include "buffer.h"
   26: #include "stream.h"
   27: #include "command.h"
   28: #include "sockunion.h"
   29: #include "sockopt.h"
   30: #include "network.h"
   31: #include "memory.h"
   32: #include "filter.h"
   33: #include "routemap.h"
   34: #include "str.h"
   35: #include "log.h"
   36: #include "plist.h"
   37: #include "linklist.h"
   38: #include "workqueue.h"
   39: #include "table.h"
   40: 
   41: #include "bgpd/bgpd.h"
   42: #include "bgpd/bgp_table.h"
   43: #include "bgpd/bgp_aspath.h"
   44: #include "bgpd/bgp_route.h"
   45: #include "bgpd/bgp_dump.h"
   46: #include "bgpd/bgp_debug.h"
   47: #include "bgpd/bgp_community.h"
   48: #include "bgpd/bgp_attr.h"
   49: #include "bgpd/bgp_regex.h"
   50: #include "bgpd/bgp_clist.h"
   51: #include "bgpd/bgp_fsm.h"
   52: #include "bgpd/bgp_packet.h"
   53: #include "bgpd/bgp_zebra.h"
   54: #include "bgpd/bgp_open.h"
   55: #include "bgpd/bgp_filter.h"
   56: #include "bgpd/bgp_nexthop.h"
   57: #include "bgpd/bgp_damp.h"
   58: #include "bgpd/bgp_mplsvpn.h"
   59: #include "bgpd/bgp_encap.h"
   60: #include "bgpd/bgp_advertise.h"
   61: #include "bgpd/bgp_network.h"
   62: #include "bgpd/bgp_vty.h"
   63: #include "bgpd/bgp_mpath.h"
   64: #ifdef HAVE_SNMP
   65: #include "bgpd/bgp_snmp.h"
   66: #endif /* HAVE_SNMP */
   67: 
   68: /* BGP process wide configuration.  */
   69: static struct bgp_master bgp_master;
   70: 
   71: extern struct in_addr router_id_zebra;
   72: 
   73: /* BGP process wide configuration pointer to export.  */
   74: struct bgp_master *bm;
   75: 
   76: /* BGP community-list.  */
   77: struct community_list_handler *bgp_clist;
   78: 
   79: /* BGP global flag manipulation.  */
   80: int
   81: bgp_option_set (int flag)
   82: {
   83:   switch (flag)
   84:     {
   85:     case BGP_OPT_NO_FIB:
   86:     case BGP_OPT_MULTIPLE_INSTANCE:
   87:     case BGP_OPT_CONFIG_CISCO:
   88:     case BGP_OPT_NO_LISTEN:
   89:       SET_FLAG (bm->options, flag);
   90:       break;
   91:     default:
   92:       return BGP_ERR_INVALID_FLAG;
   93:     }
   94:   return 0;
   95: }
   96: 
   97: int
   98: bgp_option_unset (int flag)
   99: {
  100:   switch (flag)
  101:     {
  102:     case BGP_OPT_MULTIPLE_INSTANCE:
  103:       if (listcount (bm->bgp) > 1)
  104: 	return BGP_ERR_MULTIPLE_INSTANCE_USED;
  105:       /* Fall through.  */
  106:     case BGP_OPT_NO_FIB:
  107:     case BGP_OPT_CONFIG_CISCO:
  108:       UNSET_FLAG (bm->options, flag);
  109:       break;
  110:     default:
  111:       return BGP_ERR_INVALID_FLAG;
  112:     }
  113:   return 0;
  114: }
  115: 
  116: int
  117: bgp_option_check (int flag)
  118: {
  119:   return CHECK_FLAG (bm->options, flag);
  120: }
  121: 
  122: /* BGP flag manipulation.  */
  123: int
  124: bgp_flag_set (struct bgp *bgp, int flag)
  125: {
  126:   SET_FLAG (bgp->flags, flag);
  127:   return 0;
  128: }
  129: 
  130: int
  131: bgp_flag_unset (struct bgp *bgp, int flag)
  132: {
  133:   UNSET_FLAG (bgp->flags, flag);
  134:   return 0;
  135: }
  136: 
  137: int
  138: bgp_flag_check (struct bgp *bgp, int flag)
  139: {
  140:   return CHECK_FLAG (bgp->flags, flag);
  141: }
  142: 
  143: /* Internal function to set BGP structure configureation flag.  */
  144: static void
  145: bgp_config_set (struct bgp *bgp, int config)
  146: {
  147:   SET_FLAG (bgp->config, config);
  148: }
  149: 
  150: static void
  151: bgp_config_unset (struct bgp *bgp, int config)
  152: {
  153:   UNSET_FLAG (bgp->config, config);
  154: }
  155: 
  156: static int
  157: bgp_config_check (struct bgp *bgp, int config)
  158: {
  159:   return CHECK_FLAG (bgp->config, config);
  160: }
  161: 
  162: /* Set BGP router identifier. */
  163: int
  164: bgp_router_id_set (struct bgp *bgp, struct in_addr *id)
  165: {
  166:   struct peer *peer;
  167:   struct listnode *node, *nnode;
  168: 
  169:   if (bgp_config_check (bgp, BGP_CONFIG_ROUTER_ID)
  170:       && IPV4_ADDR_SAME (&bgp->router_id, id))
  171:     return 0;
  172: 
  173:   IPV4_ADDR_COPY (&bgp->router_id, id);
  174:   bgp_config_set (bgp, BGP_CONFIG_ROUTER_ID);
  175: 
  176:   /* Set all peer's local identifier with this value. */
  177:   for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
  178:     {
  179:       IPV4_ADDR_COPY (&peer->local_id, id);
  180: 
  181:       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
  182:        {
  183:          peer->last_reset = PEER_DOWN_RID_CHANGE;
  184:          bgp_notify_send (peer, BGP_NOTIFY_CEASE,
  185:                           BGP_NOTIFY_CEASE_CONFIG_CHANGE);
  186:        }
  187:     }
  188:   return 0;
  189: }
  190: 
  191: /* BGP's cluster-id control. */
  192: int
  193: bgp_cluster_id_set (struct bgp *bgp, struct in_addr *cluster_id)
  194: {
  195:   struct peer *peer;
  196:   struct listnode *node, *nnode;
  197: 
  198:   if (bgp_config_check (bgp, BGP_CONFIG_CLUSTER_ID)
  199:       && IPV4_ADDR_SAME (&bgp->cluster_id, cluster_id))
  200:     return 0;
  201: 
  202:   IPV4_ADDR_COPY (&bgp->cluster_id, cluster_id);
  203:   bgp_config_set (bgp, BGP_CONFIG_CLUSTER_ID);
  204: 
  205:   /* Clear all IBGP peer. */
  206:   for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
  207:     {
  208:       if (peer->sort != BGP_PEER_IBGP)
  209: 	continue;
  210: 
  211:       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
  212:        {
  213:          peer->last_reset = PEER_DOWN_CLID_CHANGE;
  214:          bgp_notify_send (peer, BGP_NOTIFY_CEASE,
  215:                           BGP_NOTIFY_CEASE_CONFIG_CHANGE);
  216:        }
  217:     }
  218:   return 0;
  219: }
  220: 
  221: int
  222: bgp_cluster_id_unset (struct bgp *bgp)
  223: {
  224:   struct peer *peer;
  225:   struct listnode *node, *nnode;
  226: 
  227:   if (! bgp_config_check (bgp, BGP_CONFIG_CLUSTER_ID))
  228:     return 0;
  229: 
  230:   bgp->cluster_id.s_addr = 0;
  231:   bgp_config_unset (bgp, BGP_CONFIG_CLUSTER_ID);
  232: 
  233:   /* Clear all IBGP peer. */
  234:   for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
  235:     {
  236:       if (peer->sort != BGP_PEER_IBGP)
  237: 	continue;
  238: 
  239:       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
  240:        {
  241:          peer->last_reset = PEER_DOWN_CLID_CHANGE;
  242:          bgp_notify_send (peer, BGP_NOTIFY_CEASE,
  243:                           BGP_NOTIFY_CEASE_CONFIG_CHANGE);
  244:        }
  245:     }
  246:   return 0;
  247: }
  248: 
  249: /* time_t value that is monotonicly increasing
  250:  * and uneffected by adjustments to system clock
  251:  */
  252: time_t bgp_clock (void)
  253: {
  254:   struct timeval tv;
  255: 
  256:   quagga_gettime(QUAGGA_CLK_MONOTONIC, &tv);
  257:   return tv.tv_sec;
  258: }
  259: 
  260: /* BGP timer configuration.  */
  261: int
  262: bgp_timers_set (struct bgp *bgp, u_int32_t keepalive, u_int32_t holdtime)
  263: {
  264:   bgp->default_keepalive = (keepalive < holdtime / 3 
  265: 			    ? keepalive : holdtime / 3);
  266:   bgp->default_holdtime = holdtime;
  267: 
  268:   return 0;
  269: }
  270: 
  271: int
  272: bgp_timers_unset (struct bgp *bgp)
  273: {
  274:   bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
  275:   bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
  276: 
  277:   return 0;
  278: }
  279: 
  280: /* BGP confederation configuration.  */
  281: int
  282: bgp_confederation_id_set (struct bgp *bgp, as_t as)
  283: {
  284:   struct peer *peer;
  285:   struct listnode *node, *nnode;
  286:   int already_confed;
  287: 
  288:   if (as == 0)
  289:     return BGP_ERR_INVALID_AS;
  290: 
  291:   /* Remember - were we doing confederation before? */
  292:   already_confed = bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION);
  293:   bgp->confed_id = as;
  294:   bgp_config_set (bgp, BGP_CONFIG_CONFEDERATION);
  295: 
  296:   /* If we were doing confederation already, this is just an external
  297:      AS change.  Just Reset EBGP sessions, not CONFED sessions.  If we
  298:      were not doing confederation before, reset all EBGP sessions.  */
  299:   for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
  300:     {
  301:       /* We're looking for peers who's AS is not local or part of our
  302: 	 confederation.  */
  303:       if (already_confed)
  304: 	{
  305: 	  if (peer_sort (peer) == BGP_PEER_EBGP)
  306: 	    {
  307: 	      peer->local_as = as;
  308: 	      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
  309:                {
  310:                  peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
  311:                  bgp_notify_send (peer, BGP_NOTIFY_CEASE,
  312:                               BGP_NOTIFY_CEASE_CONFIG_CHANGE);
  313:                }
  314: 
  315: 	      else
  316: 		BGP_EVENT_ADD (peer, BGP_Stop);
  317: 	    }
  318: 	}
  319:       else
  320: 	{
  321: 	  /* Not doign confederation before, so reset every non-local
  322: 	     session */
  323: 	  if (peer_sort (peer) != BGP_PEER_IBGP)
  324: 	    {
  325: 	      /* Reset the local_as to be our EBGP one */
  326: 	      if (peer_sort (peer) == BGP_PEER_EBGP)
  327: 		peer->local_as = as;
  328: 	      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
  329:                {
  330:                  peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
  331:                  bgp_notify_send (peer, BGP_NOTIFY_CEASE,
  332:                               BGP_NOTIFY_CEASE_CONFIG_CHANGE);
  333:                }
  334: 	      else
  335: 		BGP_EVENT_ADD (peer, BGP_Stop);
  336: 	    }
  337: 	}
  338:     }
  339:   return 0;
  340: }
  341: 
  342: int
  343: bgp_confederation_id_unset (struct bgp *bgp)
  344: {
  345:   struct peer *peer;
  346:   struct listnode *node, *nnode;
  347: 
  348:   bgp->confed_id = 0;
  349:   bgp_config_unset (bgp, BGP_CONFIG_CONFEDERATION);
  350:       
  351:   for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
  352:     {
  353:       /* We're looking for peers who's AS is not local */
  354:       if (peer_sort (peer) != BGP_PEER_IBGP)
  355: 	{
  356: 	  peer->local_as = bgp->as;
  357: 	  if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
  358:            {
  359:              peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
  360:              bgp_notify_send (peer, BGP_NOTIFY_CEASE,
  361:                               BGP_NOTIFY_CEASE_CONFIG_CHANGE);
  362:            }
  363: 
  364: 	  else
  365: 	    BGP_EVENT_ADD (peer, BGP_Stop);
  366: 	}
  367:     }
  368:   return 0;
  369: }
  370: 
  371: /* Is an AS part of the confed or not? */
  372: int
  373: bgp_confederation_peers_check (struct bgp *bgp, as_t as)
  374: {
  375:   int i;
  376: 
  377:   if (! bgp)
  378:     return 0;
  379: 
  380:   for (i = 0; i < bgp->confed_peers_cnt; i++)
  381:     if (bgp->confed_peers[i] == as)
  382:       return 1;
  383:   
  384:   return 0;
  385: }
  386: 
  387: /* Add an AS to the confederation set.  */
  388: int
  389: bgp_confederation_peers_add (struct bgp *bgp, as_t as)
  390: {
  391:   struct peer *peer;
  392:   struct listnode *node, *nnode;
  393: 
  394:   if (! bgp)
  395:     return BGP_ERR_INVALID_BGP;
  396: 
  397:   if (bgp->as == as)
  398:     return BGP_ERR_INVALID_AS;
  399: 
  400:   if (bgp_confederation_peers_check (bgp, as))
  401:     return -1;
  402: 
  403:   if (bgp->confed_peers)
  404:     bgp->confed_peers = XREALLOC (MTYPE_BGP_CONFED_LIST, 
  405: 				  bgp->confed_peers,
  406: 				  (bgp->confed_peers_cnt + 1) * sizeof (as_t));
  407:   else
  408:     bgp->confed_peers = XMALLOC (MTYPE_BGP_CONFED_LIST, 
  409: 				 (bgp->confed_peers_cnt + 1) * sizeof (as_t));
  410: 
  411:   bgp->confed_peers[bgp->confed_peers_cnt] = as;
  412:   bgp->confed_peers_cnt++;
  413: 
  414:   if (bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION))
  415:     {
  416:       for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
  417: 	{
  418: 	  if (peer->as == as)
  419: 	    {
  420: 	      peer->local_as = bgp->as;
  421: 	      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
  422:                {
  423:                  peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE;
  424:                  bgp_notify_send (peer, BGP_NOTIFY_CEASE,
  425:                                   BGP_NOTIFY_CEASE_CONFIG_CHANGE);
  426:                }
  427: 	      else
  428: 	        BGP_EVENT_ADD (peer, BGP_Stop);
  429: 	    }
  430: 	}
  431:     }
  432:   return 0;
  433: }
  434: 
  435: /* Delete an AS from the confederation set.  */
  436: int
  437: bgp_confederation_peers_remove (struct bgp *bgp, as_t as)
  438: {
  439:   int i;
  440:   int j;
  441:   struct peer *peer;
  442:   struct listnode *node, *nnode;
  443: 
  444:   if (! bgp)
  445:     return -1;
  446: 
  447:   if (! bgp_confederation_peers_check (bgp, as))
  448:     return -1;
  449: 
  450:   for (i = 0; i < bgp->confed_peers_cnt; i++)
  451:     if (bgp->confed_peers[i] == as)
  452:       for(j = i + 1; j < bgp->confed_peers_cnt; j++)
  453: 	bgp->confed_peers[j - 1] = bgp->confed_peers[j];
  454: 
  455:   bgp->confed_peers_cnt--;
  456: 
  457:   if (bgp->confed_peers_cnt == 0)
  458:     {
  459:       if (bgp->confed_peers)
  460: 	XFREE (MTYPE_BGP_CONFED_LIST, bgp->confed_peers);
  461:       bgp->confed_peers = NULL;
  462:     }
  463:   else
  464:     bgp->confed_peers = XREALLOC (MTYPE_BGP_CONFED_LIST,
  465: 				  bgp->confed_peers,
  466: 				  bgp->confed_peers_cnt * sizeof (as_t));
  467: 
  468:   /* Now reset any peer who's remote AS has just been removed from the
  469:      CONFED */
  470:   if (bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION))
  471:     {
  472:       for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
  473: 	{
  474: 	  if (peer->as == as)
  475: 	    {
  476: 	      peer->local_as = bgp->confed_id;
  477: 	      if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
  478:                {
  479:                  peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE;
  480:                  bgp_notify_send (peer, BGP_NOTIFY_CEASE,
  481:                                   BGP_NOTIFY_CEASE_CONFIG_CHANGE);
  482:                }
  483: 	      else
  484: 		BGP_EVENT_ADD (peer, BGP_Stop);
  485: 	    }
  486: 	}
  487:     }
  488: 
  489:   return 0;
  490: }
  491: 
  492: /* Local preference configuration.  */
  493: int
  494: bgp_default_local_preference_set (struct bgp *bgp, u_int32_t local_pref)
  495: {
  496:   if (! bgp)
  497:     return -1;
  498: 
  499:   bgp->default_local_pref = local_pref;
  500: 
  501:   return 0;
  502: }
  503: 
  504: int
  505: bgp_default_local_preference_unset (struct bgp *bgp)
  506: {
  507:   if (! bgp)
  508:     return -1;
  509: 
  510:   bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
  511: 
  512:   return 0;
  513: }
  514: 
  515: /* If peer is RSERVER_CLIENT in at least one address family and is not member
  516:     of a peer_group for that family, return 1.
  517:     Used to check wether the peer is included in list bgp->rsclient. */
  518: int
  519: peer_rsclient_active (struct peer *peer)
  520: {
  521:   int i;
  522:   int j;
  523: 
  524:   for (i=AFI_IP; i < AFI_MAX; i++)
  525:     for (j=SAFI_UNICAST; j < SAFI_MAX; j++)
  526:       if (CHECK_FLAG(peer->af_flags[i][j], PEER_FLAG_RSERVER_CLIENT)
  527:             && ! peer->af_group[i][j])
  528:         return 1;
  529:   return 0;
  530: }
  531: 
  532: /* Peer comparison function for sorting.  */
  533: static int
  534: peer_cmp (struct peer *p1, struct peer *p2)
  535: {
  536:   return sockunion_cmp (&p1->su, &p2->su);
  537: }
  538: 
  539: int
  540: peer_af_flag_check (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
  541: {
  542:   return CHECK_FLAG (peer->af_flags[afi][safi], flag);
  543: }
  544: 
  545: /* Reset all address family specific configuration.  */
  546: static void
  547: peer_af_flag_reset (struct peer *peer, afi_t afi, safi_t safi)
  548: {
  549:   int i;
  550:   struct bgp_filter *filter;
  551:   char orf_name[BUFSIZ];
  552: 
  553:   filter = &peer->filter[afi][safi];
  554: 
  555:   /* Clear neighbor filter and route-map */
  556:   for (i = FILTER_IN; i < FILTER_MAX; i++)
  557:     {
  558:       if (filter->dlist[i].name)
  559: 	{
  560: 	  free (filter->dlist[i].name);
  561: 	  filter->dlist[i].name = NULL;
  562: 	}
  563:       if (filter->plist[i].name)
  564: 	{
  565: 	  free (filter->plist[i].name);
  566: 	  filter->plist[i].name = NULL; 
  567: 	}
  568:       if (filter->aslist[i].name)
  569: 	{
  570: 	  free (filter->aslist[i].name);
  571: 	  filter->aslist[i].name = NULL;
  572: 	}
  573:    }
  574:  for (i = RMAP_IN; i < RMAP_MAX; i++)
  575:        {
  576:       if (filter->map[i].name)
  577: 	{
  578: 	  free (filter->map[i].name);
  579: 	  filter->map[i].name = NULL;
  580: 	}
  581:     }
  582: 
  583:   /* Clear unsuppress map.  */
  584:   if (filter->usmap.name)
  585:     free (filter->usmap.name);
  586:   filter->usmap.name = NULL;
  587:   filter->usmap.map = NULL;
  588: 
  589:   /* Clear neighbor's all address family flags.  */
  590:   peer->af_flags[afi][safi] = 0;
  591: 
  592:   /* Clear neighbor's all address family sflags. */
  593:   peer->af_sflags[afi][safi] = 0;
  594: 
  595:   /* Clear neighbor's all address family capabilities. */
  596:   peer->af_cap[afi][safi] = 0;
  597: 
  598:   /* Clear ORF info */
  599:   peer->orf_plist[afi][safi] = NULL;
  600:   sprintf (orf_name, "%s.%d.%d", peer->host, afi, safi);
  601:   prefix_bgp_orf_remove_all (afi, orf_name);
  602: 
  603:   /* Set default neighbor send-community.  */
  604:   if (! bgp_option_check (BGP_OPT_CONFIG_CISCO))
  605:     {
  606:       SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY);
  607:       SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY);
  608:     }
  609: 
  610:   /* Clear neighbor default_originate_rmap */
  611:   if (peer->default_rmap[afi][safi].name)
  612:     free (peer->default_rmap[afi][safi].name);
  613:   peer->default_rmap[afi][safi].name = NULL;
  614:   peer->default_rmap[afi][safi].map = NULL;
  615: 
  616:   /* Clear neighbor maximum-prefix */
  617:   peer->pmax[afi][safi] = 0;
  618:   peer->pmax_threshold[afi][safi] = MAXIMUM_PREFIX_THRESHOLD_DEFAULT;
  619: }
  620: 
  621: /* peer global config reset */
  622: static void
  623: peer_global_config_reset (struct peer *peer)
  624: {
  625:   peer->weight = 0;
  626:   peer->change_local_as = 0;
  627:   peer->ttl = (peer_sort (peer) == BGP_PEER_IBGP ? 255 : 1);
  628:   if (peer->update_source)
  629:     {
  630:       sockunion_free (peer->update_source);
  631:       peer->update_source = NULL;
  632:     }
  633:   if (peer->update_if)
  634:     {
  635:       XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
  636:       peer->update_if = NULL;
  637:     }
  638: 
  639:   if (peer_sort (peer) == BGP_PEER_IBGP)
  640:     peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
  641:   else
  642:     peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
  643: 
  644:   peer->flags = 0;
  645:   peer->config = 0;
  646:   peer->holdtime = 0;
  647:   peer->keepalive = 0;
  648:   peer->connect = 0;
  649:   peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
  650: }
  651: 
  652: /* Check peer's AS number and determines if this peer is IBGP or EBGP */
  653: static bgp_peer_sort_t
  654: peer_calc_sort (struct peer *peer)
  655: {
  656:   struct bgp *bgp;
  657: 
  658:   bgp = peer->bgp;
  659: 
  660:   /* Peer-group */
  661:   if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
  662:     {
  663:       if (peer->as)
  664: 	return (bgp->as == peer->as ? BGP_PEER_IBGP : BGP_PEER_EBGP);
  665:       else
  666: 	{
  667: 	  struct peer *peer1;
  668: 	  peer1 = listnode_head (peer->group->peer);
  669: 	  if (peer1)
  670: 	    return (peer1->local_as == peer1->as 
  671: 		    ? BGP_PEER_IBGP : BGP_PEER_EBGP);
  672: 	} 
  673:       return BGP_PEER_INTERNAL;
  674:     }
  675: 
  676:   /* Normal peer */
  677:   if (bgp && CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION))
  678:     {
  679:       if (peer->local_as == 0)
  680: 	return BGP_PEER_INTERNAL;
  681: 
  682:       if (peer->local_as == peer->as)
  683: 	{
  684: 	  if (peer->local_as == bgp->confed_id)
  685: 	    return BGP_PEER_EBGP;
  686: 	  else
  687: 	    return BGP_PEER_IBGP;
  688: 	}
  689: 
  690:       if (bgp_confederation_peers_check (bgp, peer->as))
  691: 	return BGP_PEER_CONFED;
  692: 
  693:       return BGP_PEER_EBGP;
  694:     }
  695:   else
  696:     {
  697:       return (peer->local_as == 0
  698: 	      ? BGP_PEER_INTERNAL : peer->local_as == peer->as
  699: 	      ? BGP_PEER_IBGP : BGP_PEER_EBGP);
  700:     }
  701: }
  702: 
  703: /* Calculate and cache the peer "sort" */
  704: bgp_peer_sort_t
  705: peer_sort (struct peer *peer)
  706: {
  707:   peer->sort = peer_calc_sort (peer);
  708:   return peer->sort;
  709: }
  710: 
  711: static void
  712: peer_free (struct peer *peer)
  713: {
  714:   assert (peer->status == Deleted);
  715: 
  716:   bgp_unlock(peer->bgp);
  717: 
  718:   /* this /ought/ to have been done already through bgp_stop earlier,
  719:    * but just to be sure.. 
  720:    */
  721:   bgp_timer_set (peer);
  722:   BGP_READ_OFF (peer->t_read);
  723:   BGP_WRITE_OFF (peer->t_write);
  724:   BGP_EVENT_FLUSH (peer);
  725:   
  726:   if (peer->desc)
  727:     {
  728:       XFREE (MTYPE_PEER_DESC, peer->desc);
  729:       peer->desc = NULL;
  730:     }
  731:   
  732:   /* Free allocated host character. */
  733:   if (peer->host)
  734:     {
  735:       XFREE (MTYPE_BGP_PEER_HOST, peer->host);
  736:       peer->host = NULL;
  737:     }
  738: 
  739:   /* Update source configuration.  */
  740:   if (peer->update_source)
  741:     {
  742:       sockunion_free (peer->update_source);
  743:       peer->update_source = NULL;
  744:     }
  745:   
  746:   if (peer->update_if)
  747:     {
  748:       XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
  749:       peer->update_if = NULL;
  750:     }
  751:     
  752:   if (peer->clear_node_queue)
  753:     {
  754:       work_queue_free(peer->clear_node_queue);
  755:       peer->clear_node_queue = NULL;
  756:     }
  757:   
  758:   if (peer->notify.data)
  759:     XFREE(MTYPE_TMP, peer->notify.data);
  760:   
  761:   bgp_sync_delete (peer);
  762:   memset (peer, 0, sizeof (struct peer));
  763:   
  764:   XFREE (MTYPE_BGP_PEER, peer);
  765: }
  766:                                                 
  767: /* increase reference count on a struct peer */
  768: struct peer *
  769: peer_lock_with_caller (const char *name, struct peer *peer)
  770: {
  771:   assert (peer && (peer->lock >= 0));
  772: 
  773: #if 0
  774:   zlog_debug("%s peer_lock %p %d", name, peer, peer->lock);
  775: #endif
  776: 
  777:   peer->lock++;
  778:   
  779:   return peer;
  780: }
  781: 
  782: /* decrease reference count on a struct peer
  783:  * struct peer is freed and NULL returned if last reference
  784:  */
  785: struct peer *
  786: peer_unlock_with_caller (const char *name, struct peer *peer)
  787: {
  788:   assert (peer && (peer->lock > 0));
  789: 
  790: #if 0
  791:   zlog_debug("%s peer_unlock %p %d", name, peer, peer->lock);
  792: #endif
  793: 
  794:   peer->lock--;
  795:   
  796:   if (peer->lock == 0)
  797:     {
  798:       peer_free (peer);
  799:       return NULL;
  800:     }
  801: 
  802:   return peer;
  803: }
  804:   
  805: /* Allocate new peer object, implicitely locked.  */
  806: static struct peer *
  807: peer_new (struct bgp *bgp)
  808: {
  809:   afi_t afi;
  810:   safi_t safi;
  811:   struct peer *peer;
  812:   struct servent *sp;
  813:   
  814:   /* bgp argument is absolutely required */
  815:   assert (bgp);
  816:   if (!bgp)
  817:     return NULL;
  818:   
  819:   /* Allocate new peer. */
  820:   peer = XCALLOC (MTYPE_BGP_PEER, sizeof (struct peer));
  821: 
  822:   /* Set default value. */
  823:   peer->fd = -1;
  824:   peer->v_start = BGP_INIT_START_TIMER;
  825:   peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
  826:   peer->status = Idle;
  827:   peer->ostatus = Idle;
  828:   peer->weight = 0;
  829:   peer->password = NULL;
  830:   peer->bgp = bgp;
  831:   peer = peer_lock (peer); /* initial reference */
  832:   bgp_lock (bgp);
  833: 
  834:   /* Set default flags.  */
  835:   for (afi = AFI_IP; afi < AFI_MAX; afi++)
  836:     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
  837:       {
  838: 	if (! bgp_option_check (BGP_OPT_CONFIG_CISCO))
  839: 	  {
  840: 	    SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY);
  841: 	    SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY);
  842: 	  }
  843: 	peer->orf_plist[afi][safi] = NULL;
  844:       }
  845:   SET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);
  846: 
  847:   /* Create buffers.  */
  848:   peer->ibuf = stream_new (BGP_MAX_PACKET_SIZE);
  849:   peer->obuf = stream_fifo_new ();
  850:   peer->work = stream_new (BGP_MAX_PACKET_SIZE);
  851:   peer->scratch = stream_new (BGP_MAX_PACKET_SIZE);
  852: 
  853:   bgp_sync_init (peer);
  854: 
  855:   /* Get service port number.  */
  856:   sp = getservbyname ("bgp", "tcp");
  857:   peer->port = (sp == NULL) ? BGP_PORT_DEFAULT : ntohs (sp->s_port);
  858: 
  859:   return peer;
  860: }
  861: 
  862: /* Create new BGP peer.  */
  863: static struct peer *
  864: peer_create (union sockunion *su, struct bgp *bgp, as_t local_as,
  865: 	     as_t remote_as, afi_t afi, safi_t safi)
  866: {
  867:   int active;
  868:   struct peer *peer;
  869:   char buf[SU_ADDRSTRLEN];
  870: 
  871:   peer = peer_new (bgp);
  872:   peer->su = *su;
  873:   peer->local_as = local_as;
  874:   peer->as = remote_as;
  875:   peer->local_id = bgp->router_id;
  876:   peer->v_holdtime = bgp->default_holdtime;
  877:   peer->v_keepalive = bgp->default_keepalive;
  878:   if (peer_sort (peer) == BGP_PEER_IBGP)
  879:     peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
  880:   else
  881:     peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
  882:     
  883:   peer = peer_lock (peer); /* bgp peer list reference */
  884:   listnode_add_sort (bgp->peer, peer);
  885: 
  886:   active = peer_active (peer);
  887: 
  888:   if (afi && safi)
  889:     peer->afc[afi][safi] = 1;
  890: 
  891:   /* Last read and reset time set */
  892:   peer->readtime = peer->resettime = bgp_clock ();
  893: 
  894:   /* Default TTL set. */
  895:   peer->ttl = (peer->sort == BGP_PEER_IBGP) ? 255 : 1;
  896: 
  897:   /* Make peer's address string. */
  898:   sockunion2str (su, buf, SU_ADDRSTRLEN);
  899:   peer->host = XSTRDUP (MTYPE_BGP_PEER_HOST, buf);
  900: 
  901:   /* Set up peer's events and timers. */
  902:   if (! active && peer_active (peer))
  903:     bgp_timer_set (peer);
  904: 
  905:   return peer;
  906: }
  907: 
  908: /* Make accept BGP peer.  Called from bgp_accept (). */
  909: struct peer *
  910: peer_create_accept (struct bgp *bgp)
  911: {
  912:   struct peer *peer;
  913: 
  914:   peer = peer_new (bgp);
  915:   
  916:   peer = peer_lock (peer); /* bgp peer list reference */
  917:   listnode_add_sort (bgp->peer, peer);
  918: 
  919:   return peer;
  920: }
  921: 
  922: /* Change peer's AS number.  */
  923: static void
  924: peer_as_change (struct peer *peer, as_t as)
  925: {
  926:   bgp_peer_sort_t type;
  927:   struct peer *conf;
  928: 
  929:   /* Stop peer. */
  930:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
  931:     {
  932:       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
  933:        {
  934:          peer->last_reset = PEER_DOWN_REMOTE_AS_CHANGE;
  935:          bgp_notify_send (peer, BGP_NOTIFY_CEASE,
  936:                           BGP_NOTIFY_CEASE_CONFIG_CHANGE);
  937:        }
  938:       else
  939: 	BGP_EVENT_ADD (peer, BGP_Stop);
  940:     }
  941:   type = peer_sort (peer);
  942:   peer->as = as;
  943: 
  944:   if (bgp_config_check (peer->bgp, BGP_CONFIG_CONFEDERATION)
  945:       && ! bgp_confederation_peers_check (peer->bgp, as)
  946:       && peer->bgp->as != as)
  947:     peer->local_as = peer->bgp->confed_id;
  948:   else
  949:     peer->local_as = peer->bgp->as;
  950: 
  951:   /* Advertisement-interval reset */
  952:   conf = NULL;
  953:   if (peer->group)
  954:     conf = peer->group->conf;
  955: 
  956:   if (conf && CHECK_FLAG (conf->config, PEER_CONFIG_ROUTEADV))
  957:       peer->v_routeadv = conf->routeadv;
  958:   else
  959:     if (peer_sort (peer) == BGP_PEER_IBGP)
  960:       peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
  961:     else
  962:       peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
  963: 
  964:   /* TTL reset */
  965:   if (peer_sort (peer) == BGP_PEER_IBGP)
  966:     peer->ttl = 255;
  967:   else if (type == BGP_PEER_IBGP)
  968:     peer->ttl = 1;
  969: 
  970:   /* reflector-client reset */
  971:   if (peer_sort (peer) != BGP_PEER_IBGP)
  972:     {
  973:       UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_UNICAST],
  974: 		  PEER_FLAG_REFLECTOR_CLIENT);
  975:       UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_MULTICAST],
  976: 		  PEER_FLAG_REFLECTOR_CLIENT);
  977:       UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_MPLS_VPN],
  978: 		  PEER_FLAG_REFLECTOR_CLIENT);
  979:       UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_ENCAP],
  980: 		  PEER_FLAG_REFLECTOR_CLIENT);
  981:       UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_UNICAST],
  982: 		  PEER_FLAG_REFLECTOR_CLIENT);
  983:       UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_MULTICAST],
  984: 		  PEER_FLAG_REFLECTOR_CLIENT);
  985:       UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_MPLS_VPN],
  986: 		  PEER_FLAG_REFLECTOR_CLIENT);
  987:       UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_ENCAP],
  988: 		  PEER_FLAG_REFLECTOR_CLIENT);
  989:     }
  990: 
  991:   /* local-as reset */
  992:   if (peer_sort (peer) != BGP_PEER_EBGP)
  993:     {
  994:       peer->change_local_as = 0;
  995:       UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
  996:       UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
  997:     }
  998: }
  999: 
 1000: /* If peer does not exist, create new one.  If peer already exists,
 1001:    set AS number to the peer.  */
 1002: int
 1003: peer_remote_as (struct bgp *bgp, union sockunion *su, as_t *as,
 1004: 		afi_t afi, safi_t safi)
 1005: {
 1006:   struct peer *peer;
 1007:   as_t local_as;
 1008: 
 1009:   peer = peer_lookup (bgp, su);
 1010: 
 1011:   if (peer)
 1012:     {
 1013:       /* When this peer is a member of peer-group.  */
 1014:       if (peer->group)
 1015: 	{
 1016: 	  if (peer->group->conf->as)
 1017: 	    {
 1018: 	      /* Return peer group's AS number.  */
 1019: 	      *as = peer->group->conf->as;
 1020: 	      return BGP_ERR_PEER_GROUP_MEMBER;
 1021: 	    }
 1022: 	  if (peer_sort (peer->group->conf) == BGP_PEER_IBGP)
 1023: 	    {
 1024: 	      if (bgp->as != *as)
 1025: 		{
 1026: 		  *as = peer->as;
 1027: 		  return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
 1028: 		}
 1029: 	    }
 1030: 	  else
 1031: 	    {
 1032: 	      if (bgp->as == *as)
 1033: 		{
 1034: 		  *as = peer->as;
 1035: 		  return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
 1036: 		}
 1037: 	    }
 1038: 	}
 1039: 
 1040:       /* Existing peer's AS number change. */
 1041:       if (peer->as != *as)
 1042: 	peer_as_change (peer, *as);
 1043:     }
 1044:   else
 1045:     {
 1046: 
 1047:       /* If the peer is not part of our confederation, and its not an
 1048: 	 iBGP peer then spoof the source AS */
 1049:       if (bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION)
 1050: 	  && ! bgp_confederation_peers_check (bgp, *as) 
 1051: 	  && bgp->as != *as)
 1052: 	local_as = bgp->confed_id;
 1053:       else
 1054: 	local_as = bgp->as;
 1055:       
 1056:       /* If this is IPv4 unicast configuration and "no bgp default
 1057:          ipv4-unicast" is specified. */
 1058: 
 1059:       if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4)
 1060: 	  && afi == AFI_IP && safi == SAFI_UNICAST)
 1061: 	peer_create (su, bgp, local_as, *as, 0, 0); 
 1062:       else
 1063: 	peer_create (su, bgp, local_as, *as, afi, safi); 
 1064:     }
 1065: 
 1066:   return 0;
 1067: }
 1068: 
 1069: /* Activate the peer or peer group for specified AFI and SAFI.  */
 1070: int
 1071: peer_activate (struct peer *peer, afi_t afi, safi_t safi)
 1072: {
 1073:   int active;
 1074: 
 1075:   if (peer->afc[afi][safi])
 1076:     return 0;
 1077: 
 1078:   /* Activate the address family configuration. */
 1079:   if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 1080:     peer->afc[afi][safi] = 1;
 1081:   else
 1082:     {
 1083:       active = peer_active (peer);
 1084: 
 1085:       peer->afc[afi][safi] = 1;
 1086: 
 1087:       if (! active && peer_active (peer))
 1088: 	bgp_timer_set (peer);
 1089:       else
 1090: 	{
 1091: 	  if (peer->status == Established)
 1092: 	    {
 1093: 	      if (CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV))
 1094: 		{
 1095: 		  peer->afc_adv[afi][safi] = 1;
 1096: 		  bgp_capability_send (peer, afi, safi,
 1097: 				       CAPABILITY_CODE_MP,
 1098: 				       CAPABILITY_ACTION_SET);
 1099: 		  if (peer->afc_recv[afi][safi])
 1100: 		    {
 1101: 		      peer->afc_nego[afi][safi] = 1;
 1102: 		      bgp_announce_route (peer, afi, safi);
 1103: 		    }
 1104: 		}
 1105: 	      else
 1106:                {
 1107:                  peer->last_reset = PEER_DOWN_AF_ACTIVATE;
 1108:                  bgp_notify_send (peer, BGP_NOTIFY_CEASE,
 1109:                                   BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 1110:                }
 1111: 	    }
 1112: 	}
 1113:     }
 1114:   return 0;
 1115: }
 1116: 
 1117: int
 1118: peer_deactivate (struct peer *peer, afi_t afi, safi_t safi)
 1119: {
 1120:   struct peer_group *group;
 1121:   struct peer *peer1;
 1122:   struct listnode *node, *nnode;
 1123: 
 1124:   if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 1125:     {
 1126:       group = peer->group;
 1127: 
 1128:       for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
 1129: 	{
 1130: 	  if (peer1->af_group[afi][safi])
 1131: 	    return BGP_ERR_PEER_GROUP_MEMBER_EXISTS;
 1132: 	}
 1133:     }
 1134:   else
 1135:     {
 1136:       if (peer->af_group[afi][safi])
 1137: 	return BGP_ERR_PEER_BELONGS_TO_GROUP;
 1138:     }
 1139: 
 1140:   if (! peer->afc[afi][safi])
 1141:     return 0;
 1142: 
 1143:   /* De-activate the address family configuration. */
 1144:   peer->afc[afi][safi] = 0;
 1145:   peer_af_flag_reset (peer, afi, safi);
 1146: 
 1147:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 1148:     {  
 1149:       if (peer->status == Established)
 1150: 	{
 1151: 	  if (CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV))
 1152: 	    {
 1153: 	      peer->afc_adv[afi][safi] = 0;
 1154: 	      peer->afc_nego[afi][safi] = 0;
 1155: 
 1156: 	      if (peer_active_nego (peer))
 1157: 		{
 1158: 		  bgp_capability_send (peer, afi, safi,
 1159: 				       CAPABILITY_CODE_MP,
 1160: 				       CAPABILITY_ACTION_UNSET);
 1161: 		  bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
 1162: 		  peer->pcount[afi][safi] = 0;
 1163: 		}
 1164: 	      else
 1165:                {
 1166:                  peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
 1167:                  bgp_notify_send (peer, BGP_NOTIFY_CEASE,
 1168:                                   BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 1169:                }
 1170: 	    }
 1171: 	  else
 1172:            {
 1173:              peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
 1174:              bgp_notify_send (peer, BGP_NOTIFY_CEASE,
 1175:                               BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 1176:            }
 1177: 	}
 1178:     }
 1179:   return 0;
 1180: }
 1181: 
 1182: static void
 1183: peer_nsf_stop (struct peer *peer)
 1184: {
 1185:   afi_t afi;
 1186:   safi_t safi;
 1187: 
 1188:   UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT);
 1189:   UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE);
 1190: 
 1191:   for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
 1192:     for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++)
 1193:       peer->nsf[afi][safi] = 0;
 1194: 
 1195:   if (peer->t_gr_restart)
 1196:     {
 1197:       BGP_TIMER_OFF (peer->t_gr_restart);
 1198:       if (BGP_DEBUG (events, EVENTS))
 1199: 	zlog_debug ("%s graceful restart timer stopped", peer->host);
 1200:     }
 1201:   if (peer->t_gr_stale)
 1202:     {
 1203:       BGP_TIMER_OFF (peer->t_gr_stale);
 1204:       if (BGP_DEBUG (events, EVENTS))
 1205: 	zlog_debug ("%s graceful restart stalepath timer stopped", peer->host);
 1206:     }
 1207:   bgp_clear_route_all (peer);
 1208: }
 1209: 
 1210: /* Delete peer from confguration.
 1211:  *
 1212:  * The peer is moved to a dead-end "Deleted" neighbour-state, to allow
 1213:  * it to "cool off" and refcounts to hit 0, at which state it is freed.
 1214:  *
 1215:  * This function /should/ take care to be idempotent, to guard against
 1216:  * it being called multiple times through stray events that come in
 1217:  * that happen to result in this function being called again.  That
 1218:  * said, getting here for a "Deleted" peer is a bug in the neighbour
 1219:  * FSM.
 1220:  */
 1221: int
 1222: peer_delete (struct peer *peer)
 1223: {
 1224:   int i;
 1225:   afi_t afi;
 1226:   safi_t safi;
 1227:   struct bgp *bgp;
 1228:   struct bgp_filter *filter;
 1229:   struct listnode *pn;
 1230: 
 1231:   assert (peer->status != Deleted);
 1232:   
 1233:   bgp = peer->bgp;
 1234: 
 1235:   if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
 1236:     peer_nsf_stop (peer);
 1237: 
 1238:   /* If this peer belongs to peer group, clear up the
 1239:      relationship.  */
 1240:   if (peer->group)
 1241:     {
 1242:       if ((pn = listnode_lookup (peer->group->peer, peer)))
 1243:         {
 1244:           peer = peer_unlock (peer); /* group->peer list reference */
 1245:           list_delete_node (peer->group->peer, pn);
 1246:         }
 1247:       peer->group = NULL;
 1248:     }
 1249:   
 1250:   /* Withdraw all information from routing table.  We can not use
 1251:    * BGP_EVENT_ADD (peer, BGP_Stop) at here.  Because the event is
 1252:    * executed after peer structure is deleted.
 1253:    */
 1254:   peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
 1255:   bgp_stop (peer);
 1256:   bgp_fsm_change_status (peer, Deleted);
 1257: 
 1258:   /* Password configuration */
 1259:   if (peer->password)
 1260:     {
 1261:       XFREE (MTYPE_PEER_PASSWORD, peer->password);
 1262:       peer->password = NULL;
 1263: 
 1264:       if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 1265: 	bgp_md5_set (peer);
 1266:     }
 1267:   
 1268:   bgp_timer_set (peer); /* stops all timers for Deleted */
 1269:   
 1270:   /* Delete from all peer list. */
 1271:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
 1272:       && (pn = listnode_lookup (bgp->peer, peer)))
 1273:     {
 1274:       peer_unlock (peer); /* bgp peer list reference */
 1275:       list_delete_node (bgp->peer, pn);
 1276:     }
 1277:       
 1278:   if (peer_rsclient_active (peer)
 1279:       && (pn = listnode_lookup (bgp->rsclient, peer)))
 1280:     {
 1281:       peer_unlock (peer); /* rsclient list reference */
 1282:       list_delete_node (bgp->rsclient, pn);
 1283: 
 1284:       /* Clear our own rsclient ribs. */
 1285:       for (afi = AFI_IP; afi < AFI_MAX; afi++)
 1286:         for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
 1287:           if (CHECK_FLAG(peer->af_flags[afi][safi],
 1288:                          PEER_FLAG_RSERVER_CLIENT))
 1289:             bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_MY_RSCLIENT);
 1290:     }
 1291: 
 1292:   /* Free RIB for any family in which peer is RSERVER_CLIENT, and is not
 1293:       member of a peer_group. */
 1294:   for (afi = AFI_IP; afi < AFI_MAX; afi++)
 1295:     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
 1296:       if (peer->rib[afi][safi] && ! peer->af_group[afi][safi])
 1297:         bgp_table_finish (&peer->rib[afi][safi]);
 1298: 
 1299:   /* Buffers.  */
 1300:   if (peer->ibuf)
 1301:     {
 1302:       stream_free (peer->ibuf);
 1303:       peer->ibuf = NULL;
 1304:     }
 1305: 
 1306:   if (peer->obuf)
 1307:     {
 1308:       stream_fifo_free (peer->obuf);
 1309:       peer->obuf = NULL;
 1310:     }
 1311: 
 1312:   if (peer->work)
 1313:     {
 1314:       stream_free (peer->work);
 1315:       peer->work = NULL;
 1316:     }
 1317: 
 1318:   if (peer->scratch)
 1319:     {
 1320:       stream_free(peer->scratch);
 1321:       peer->scratch = NULL;
 1322:     }
 1323: 
 1324:   /* Local and remote addresses. */
 1325:   if (peer->su_local)
 1326:     {
 1327:       sockunion_free (peer->su_local);
 1328:       peer->su_local = NULL;
 1329:     }
 1330: 
 1331:   if (peer->su_remote)
 1332:     {
 1333:       sockunion_free (peer->su_remote);
 1334:       peer->su_remote = NULL;
 1335:     }
 1336:   
 1337:   /* Free filter related memory.  */
 1338:   for (afi = AFI_IP; afi < AFI_MAX; afi++)
 1339:     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
 1340:       {
 1341: 	filter = &peer->filter[afi][safi];
 1342: 
 1343: 	for (i = FILTER_IN; i < FILTER_MAX; i++)
 1344: 	  {
 1345: 	    if (filter->dlist[i].name)
 1346:               {
 1347:                 free(filter->dlist[i].name);
 1348:                 filter->dlist[i].name = NULL;
 1349:               }
 1350: 
 1351: 	    if (filter->plist[i].name)
 1352:               {
 1353:                 free(filter->plist[i].name);
 1354:                 filter->plist[i].name = NULL;
 1355:               }
 1356: 
 1357: 	    if (filter->aslist[i].name)
 1358:               {
 1359:                 free(filter->aslist[i].name);
 1360:                 filter->aslist[i].name = NULL;
 1361:               }
 1362:           }
 1363: 
 1364:         for (i = RMAP_IN; i < RMAP_MAX; i++)
 1365:           {
 1366: 	    if (filter->map[i].name)
 1367:               {
 1368: 	        free (filter->map[i].name);
 1369:                 filter->map[i].name = NULL;
 1370:               }
 1371: 	  }
 1372: 
 1373: 	if (filter->usmap.name)
 1374:           {
 1375: 	    free (filter->usmap.name);
 1376:             filter->usmap.name = NULL;
 1377:           }
 1378: 
 1379: 	if (peer->default_rmap[afi][safi].name)
 1380:           {
 1381: 	    free (peer->default_rmap[afi][safi].name);
 1382:             peer->default_rmap[afi][safi].name = NULL;
 1383:           }
 1384:       }
 1385:   
 1386:   if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETING))
 1387:     bgp_peer_clear_node_queue_drain_immediate(peer);
 1388: 
 1389:   peer_unlock (peer); /* initial reference */
 1390: 
 1391:   return 0;
 1392: }
 1393: 
 1394: static int
 1395: peer_group_cmp (struct peer_group *g1, struct peer_group *g2)
 1396: {
 1397:   return strcmp (g1->name, g2->name);
 1398: }
 1399: 
 1400: /* If peer is configured at least one address family return 1. */
 1401: static int
 1402: peer_group_active (struct peer *peer)
 1403: {
 1404:   if (peer->af_group[AFI_IP][SAFI_UNICAST]
 1405:       || peer->af_group[AFI_IP][SAFI_MULTICAST]
 1406:       || peer->af_group[AFI_IP][SAFI_MPLS_VPN]
 1407:       || peer->af_group[AFI_IP][SAFI_ENCAP]
 1408:       || peer->af_group[AFI_IP6][SAFI_UNICAST]
 1409:       || peer->af_group[AFI_IP6][SAFI_MULTICAST]
 1410:       || peer->af_group[AFI_IP6][SAFI_MPLS_VPN]
 1411:       || peer->af_group[AFI_IP6][SAFI_ENCAP])
 1412:     return 1;
 1413:   return 0;
 1414: }
 1415: 
 1416: /* Peer group cofiguration. */
 1417: static struct peer_group *
 1418: peer_group_new (void)
 1419: {
 1420:   return (struct peer_group *) XCALLOC (MTYPE_PEER_GROUP,
 1421: 					sizeof (struct peer_group));
 1422: }
 1423: 
 1424: static void
 1425: peer_group_free (struct peer_group *group)
 1426: {
 1427:   XFREE (MTYPE_PEER_GROUP, group);
 1428: }
 1429: 
 1430: struct peer_group *
 1431: peer_group_lookup (struct bgp *bgp, const char *name)
 1432: {
 1433:   struct peer_group *group;
 1434:   struct listnode *node, *nnode;
 1435: 
 1436:   for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
 1437:     {
 1438:       if (strcmp (group->name, name) == 0)
 1439: 	return group;
 1440:     }
 1441:   return NULL;
 1442: }
 1443: 
 1444: struct peer_group *
 1445: peer_group_get (struct bgp *bgp, const char *name)
 1446: {
 1447:   struct peer_group *group;
 1448: 
 1449:   group = peer_group_lookup (bgp, name);
 1450:   if (group)
 1451:     return group;
 1452: 
 1453:   group = peer_group_new ();
 1454:   group->bgp = bgp;
 1455:   group->name = strdup (name);
 1456:   group->peer = list_new ();
 1457:   group->conf = peer_new (bgp);
 1458:   if (! bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4))
 1459:     group->conf->afc[AFI_IP][SAFI_UNICAST] = 1;
 1460:   group->conf->host = XSTRDUP (MTYPE_BGP_PEER_HOST, name);
 1461:   group->conf->group = group;
 1462:   group->conf->as = 0; 
 1463:   group->conf->ttl = 1;
 1464:   group->conf->gtsm_hops = 0;
 1465:   group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
 1466:   UNSET_FLAG (group->conf->config, PEER_CONFIG_TIMER);
 1467:   UNSET_FLAG (group->conf->config, PEER_CONFIG_CONNECT);
 1468:   group->conf->keepalive = 0;
 1469:   group->conf->holdtime = 0;
 1470:   group->conf->connect = 0;
 1471:   SET_FLAG (group->conf->sflags, PEER_STATUS_GROUP);
 1472:   listnode_add_sort (bgp->group, group);
 1473: 
 1474:   return 0;
 1475: }
 1476: 
 1477: static void 
 1478: peer_group2peer_config_copy (struct peer_group *group, struct peer *peer,
 1479: 			     afi_t afi, safi_t safi)
 1480: {
 1481:   int in = FILTER_IN;
 1482:   int out = FILTER_OUT;
 1483:   struct peer *conf;
 1484:   struct bgp_filter *pfilter;
 1485:   struct bgp_filter *gfilter;
 1486: 
 1487:   conf = group->conf;
 1488:   pfilter = &peer->filter[afi][safi];
 1489:   gfilter = &conf->filter[afi][safi];
 1490: 
 1491:   /* remote-as */
 1492:   if (conf->as)
 1493:     peer->as = conf->as;
 1494: 
 1495:   /* remote-as */
 1496:   if (conf->change_local_as)
 1497:     peer->change_local_as = conf->change_local_as;
 1498: 
 1499:   /* TTL */
 1500:   peer->ttl = conf->ttl;
 1501: 
 1502:   /* GTSM hops */
 1503:   peer->gtsm_hops = conf->gtsm_hops;
 1504: 
 1505:   /* Weight */
 1506:   peer->weight = conf->weight;
 1507: 
 1508:   /* peer flags apply */
 1509:   peer->flags = conf->flags;
 1510:   /* peer af_flags apply */
 1511:   peer->af_flags[afi][safi] = conf->af_flags[afi][safi];
 1512:   /* peer config apply */
 1513:   peer->config = conf->config;
 1514: 
 1515:   /* peer timers apply */
 1516:   peer->holdtime = conf->holdtime;
 1517:   peer->keepalive = conf->keepalive;
 1518:   peer->connect = conf->connect;
 1519:   if (CHECK_FLAG (conf->config, PEER_CONFIG_CONNECT))
 1520:     peer->v_connect = conf->connect;
 1521:   else
 1522:     peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
 1523: 
 1524:   /* advertisement-interval reset */
 1525:   if (CHECK_FLAG (conf->config, PEER_CONFIG_ROUTEADV))
 1526:       peer->v_routeadv = conf->routeadv;
 1527:   else
 1528:       if (peer_sort (peer) == BGP_PEER_IBGP)
 1529:         peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
 1530:       else
 1531:         peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
 1532: 
 1533:   /* password apply */
 1534:   if (conf->password && !peer->password)
 1535:     peer->password =  XSTRDUP (MTYPE_PEER_PASSWORD, conf->password);
 1536: 
 1537:   bgp_md5_set (peer);
 1538: 
 1539:   /* maximum-prefix */
 1540:   peer->pmax[afi][safi] = conf->pmax[afi][safi];
 1541:   peer->pmax_threshold[afi][safi] = conf->pmax_threshold[afi][safi];
 1542:   peer->pmax_restart[afi][safi] = conf->pmax_restart[afi][safi];
 1543: 
 1544:   /* allowas-in */
 1545:   peer->allowas_in[afi][safi] = conf->allowas_in[afi][safi];
 1546: 
 1547:   /* route-server-client */
 1548:   if (CHECK_FLAG(conf->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
 1549:     {
 1550:       /* Make peer's RIB point to group's RIB. */
 1551:       peer->rib[afi][safi] = group->conf->rib[afi][safi];
 1552: 
 1553:       /* Import policy. */
 1554:       if (pfilter->map[RMAP_IMPORT].name)
 1555:         free (pfilter->map[RMAP_IMPORT].name);
 1556:       if (gfilter->map[RMAP_IMPORT].name)
 1557:         {
 1558:           pfilter->map[RMAP_IMPORT].name = strdup (gfilter->map[RMAP_IMPORT].name);
 1559:           pfilter->map[RMAP_IMPORT].map = gfilter->map[RMAP_IMPORT].map;
 1560:         }
 1561:       else
 1562:         {
 1563:           pfilter->map[RMAP_IMPORT].name = NULL;
 1564:           pfilter->map[RMAP_IMPORT].map = NULL;
 1565:         }
 1566: 
 1567:       /* Export policy. */
 1568:       if (gfilter->map[RMAP_EXPORT].name && ! pfilter->map[RMAP_EXPORT].name)
 1569:         {
 1570:           pfilter->map[RMAP_EXPORT].name = strdup (gfilter->map[RMAP_EXPORT].name);
 1571:           pfilter->map[RMAP_EXPORT].map = gfilter->map[RMAP_EXPORT].map;
 1572:         }
 1573:     }
 1574: 
 1575:   /* default-originate route-map */
 1576:   if (conf->default_rmap[afi][safi].name)
 1577:     {
 1578:       if (peer->default_rmap[afi][safi].name)
 1579: 	free (peer->default_rmap[afi][safi].name);
 1580:       peer->default_rmap[afi][safi].name = strdup (conf->default_rmap[afi][safi].name);
 1581:       peer->default_rmap[afi][safi].map = conf->default_rmap[afi][safi].map;
 1582:     }
 1583: 
 1584:   /* update-source apply */
 1585:   if (conf->update_source)
 1586:     {
 1587:       if (peer->update_source)
 1588: 	sockunion_free (peer->update_source);
 1589:       if (peer->update_if)
 1590: 	{
 1591: 	  XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
 1592: 	  peer->update_if = NULL;
 1593: 	}
 1594:       peer->update_source = sockunion_dup (conf->update_source);
 1595:     }
 1596:   else if (conf->update_if)
 1597:     {
 1598:       if (peer->update_if)
 1599: 	XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
 1600:       if (peer->update_source)
 1601: 	{
 1602: 	  sockunion_free (peer->update_source);
 1603: 	  peer->update_source = NULL;
 1604: 	}
 1605:       peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, conf->update_if);
 1606:     }
 1607: 
 1608:   /* inbound filter apply */
 1609:   if (gfilter->dlist[in].name && ! pfilter->dlist[in].name)
 1610:     {
 1611:       if (pfilter->dlist[in].name)
 1612: 	free (pfilter->dlist[in].name);
 1613:       pfilter->dlist[in].name = strdup (gfilter->dlist[in].name);
 1614:       pfilter->dlist[in].alist = gfilter->dlist[in].alist;
 1615:     }
 1616:   if (gfilter->plist[in].name && ! pfilter->plist[in].name)
 1617:     {
 1618:       if (pfilter->plist[in].name)
 1619: 	free (pfilter->plist[in].name);
 1620:       pfilter->plist[in].name = strdup (gfilter->plist[in].name);
 1621:       pfilter->plist[in].plist = gfilter->plist[in].plist;
 1622:     }
 1623:   if (gfilter->aslist[in].name && ! pfilter->aslist[in].name)
 1624:     {
 1625:       if (pfilter->aslist[in].name)
 1626: 	free (pfilter->aslist[in].name);
 1627:       pfilter->aslist[in].name = strdup (gfilter->aslist[in].name);
 1628:       pfilter->aslist[in].aslist = gfilter->aslist[in].aslist;
 1629:     }
 1630:   if (gfilter->map[RMAP_IN].name && ! pfilter->map[RMAP_IN].name)
 1631:     {
 1632:       if (pfilter->map[RMAP_IN].name)
 1633:         free (pfilter->map[RMAP_IN].name);
 1634:       pfilter->map[RMAP_IN].name = strdup (gfilter->map[RMAP_IN].name);
 1635:       pfilter->map[RMAP_IN].map = gfilter->map[RMAP_IN].map;
 1636:     }
 1637: 
 1638:   /* outbound filter apply */
 1639:   if (gfilter->dlist[out].name)
 1640:     {
 1641:       if (pfilter->dlist[out].name)
 1642: 	free (pfilter->dlist[out].name);
 1643:       pfilter->dlist[out].name = strdup (gfilter->dlist[out].name);
 1644:       pfilter->dlist[out].alist = gfilter->dlist[out].alist;
 1645:     }
 1646:   else
 1647:     {
 1648:       if (pfilter->dlist[out].name)
 1649: 	free (pfilter->dlist[out].name);
 1650:       pfilter->dlist[out].name = NULL;
 1651:       pfilter->dlist[out].alist = NULL;
 1652:     }
 1653:   if (gfilter->plist[out].name)
 1654:     {
 1655:       if (pfilter->plist[out].name)
 1656: 	free (pfilter->plist[out].name);
 1657:       pfilter->plist[out].name = strdup (gfilter->plist[out].name);
 1658:       pfilter->plist[out].plist = gfilter->plist[out].plist;
 1659:     }
 1660:   else
 1661:     {
 1662:       if (pfilter->plist[out].name)
 1663: 	free (pfilter->plist[out].name);
 1664:       pfilter->plist[out].name = NULL;
 1665:       pfilter->plist[out].plist = NULL;
 1666:     }
 1667:   if (gfilter->aslist[out].name)
 1668:     {
 1669:       if (pfilter->aslist[out].name)
 1670: 	free (pfilter->aslist[out].name);
 1671:       pfilter->aslist[out].name = strdup (gfilter->aslist[out].name);
 1672:       pfilter->aslist[out].aslist = gfilter->aslist[out].aslist;
 1673:     }
 1674:   else
 1675:     {
 1676:       if (pfilter->aslist[out].name)
 1677: 	free (pfilter->aslist[out].name);
 1678:       pfilter->aslist[out].name = NULL;
 1679:       pfilter->aslist[out].aslist = NULL;
 1680:     }
 1681:   if (gfilter->map[RMAP_OUT].name)
 1682:     {
 1683:       if (pfilter->map[RMAP_OUT].name)
 1684:         free (pfilter->map[RMAP_OUT].name);
 1685:       pfilter->map[RMAP_OUT].name = strdup (gfilter->map[RMAP_OUT].name);
 1686:       pfilter->map[RMAP_OUT].map = gfilter->map[RMAP_OUT].map;
 1687:     }
 1688:   else
 1689:     {
 1690:       if (pfilter->map[RMAP_OUT].name)
 1691:         free (pfilter->map[RMAP_OUT].name);
 1692:       pfilter->map[RMAP_OUT].name = NULL;
 1693:       pfilter->map[RMAP_OUT].map = NULL;
 1694:     }
 1695: 
 1696:  /* RS-client's import/export route-maps. */
 1697:   if (gfilter->map[RMAP_IMPORT].name)
 1698:     {
 1699:       if (pfilter->map[RMAP_IMPORT].name)
 1700:         free (pfilter->map[RMAP_IMPORT].name);
 1701:       pfilter->map[RMAP_IMPORT].name = strdup (gfilter->map[RMAP_IMPORT].name);
 1702:       pfilter->map[RMAP_IMPORT].map = gfilter->map[RMAP_IMPORT].map;
 1703:     }
 1704:   else
 1705:     {
 1706:       if (pfilter->map[RMAP_IMPORT].name)
 1707:         free (pfilter->map[RMAP_IMPORT].name);
 1708:       pfilter->map[RMAP_IMPORT].name = NULL;
 1709:       pfilter->map[RMAP_IMPORT].map = NULL;
 1710:     }
 1711:   if (gfilter->map[RMAP_EXPORT].name && ! pfilter->map[RMAP_EXPORT].name)
 1712:     {
 1713:       if (pfilter->map[RMAP_EXPORT].name)
 1714:         free (pfilter->map[RMAP_EXPORT].name);
 1715:       pfilter->map[RMAP_EXPORT].name = strdup (gfilter->map[RMAP_EXPORT].name);
 1716:       pfilter->map[RMAP_EXPORT].map = gfilter->map[RMAP_EXPORT].map;
 1717:     }
 1718: 
 1719:   if (gfilter->usmap.name)
 1720:     {
 1721:       if (pfilter->usmap.name)
 1722: 	free (pfilter->usmap.name);
 1723:       pfilter->usmap.name = strdup (gfilter->usmap.name);
 1724:       pfilter->usmap.map = gfilter->usmap.map;
 1725:     }
 1726:   else
 1727:     {
 1728:       if (pfilter->usmap.name)
 1729: 	free (pfilter->usmap.name);
 1730:       pfilter->usmap.name = NULL;
 1731:       pfilter->usmap.map = NULL;
 1732:     }
 1733: } 
 1734: 
 1735: /* Peer group's remote AS configuration.  */
 1736: int
 1737: peer_group_remote_as (struct bgp *bgp, const char *group_name, as_t *as)
 1738: {
 1739:   struct peer_group *group;
 1740:   struct peer *peer;
 1741:   struct listnode *node, *nnode;
 1742: 
 1743:   group = peer_group_lookup (bgp, group_name);
 1744:   if (! group)
 1745:     return -1;
 1746: 
 1747:   if (group->conf->as == *as)
 1748:     return 0;
 1749: 
 1750:   /* When we setup peer-group AS number all peer group member's AS
 1751:      number must be updated to same number.  */
 1752:   peer_as_change (group->conf, *as);
 1753: 
 1754:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 1755:     {
 1756:       if (peer->as != *as)
 1757: 	peer_as_change (peer, *as);
 1758:     }
 1759: 
 1760:   return 0;
 1761: }
 1762: 
 1763: int
 1764: peer_group_delete (struct peer_group *group)
 1765: {
 1766:   struct bgp *bgp;
 1767:   struct peer *peer;
 1768:   struct listnode *node, *nnode;
 1769: 
 1770:   bgp = group->bgp;
 1771: 
 1772:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 1773:     {
 1774:       peer_delete (peer);
 1775:     }
 1776:   list_delete (group->peer);
 1777: 
 1778:   free (group->name);
 1779:   group->name = NULL;
 1780: 
 1781:   group->conf->group = NULL;
 1782:   peer_delete (group->conf);
 1783: 
 1784:   /* Delete from all peer_group list. */
 1785:   listnode_delete (bgp->group, group);
 1786: 
 1787:   peer_group_free (group);
 1788: 
 1789:   return 0;
 1790: }
 1791: 
 1792: int
 1793: peer_group_remote_as_delete (struct peer_group *group)
 1794: {
 1795:   struct peer *peer;
 1796:   struct listnode *node, *nnode;
 1797: 
 1798:   if (! group->conf->as)
 1799:     return 0;
 1800: 
 1801:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 1802:     {
 1803:       peer_delete (peer);
 1804:     }
 1805:   list_delete_all_node (group->peer);
 1806: 
 1807:   group->conf->as = 0;
 1808: 
 1809:   return 0;
 1810: }
 1811: 
 1812: /* Bind specified peer to peer group.  */
 1813: int
 1814: peer_group_bind (struct bgp *bgp, union sockunion *su,
 1815: 		 struct peer_group *group, afi_t afi, safi_t safi, as_t *as)
 1816: {
 1817:   struct peer *peer;
 1818:   int first_member = 0;
 1819: 
 1820:   /* Check peer group's address family.  */
 1821:   if (! group->conf->afc[afi][safi])
 1822:     return BGP_ERR_PEER_GROUP_AF_UNCONFIGURED;
 1823: 
 1824:   /* Lookup the peer.  */
 1825:   peer = peer_lookup (bgp, su);
 1826: 
 1827:   /* Create a new peer. */
 1828:   if (! peer)
 1829:     {
 1830:       if (! group->conf->as)
 1831: 	return BGP_ERR_PEER_GROUP_NO_REMOTE_AS;
 1832: 
 1833:       peer = peer_create (su, bgp, bgp->as, group->conf->as, afi, safi);
 1834:       peer->group = group;
 1835:       peer->af_group[afi][safi] = 1;
 1836: 
 1837:       peer = peer_lock (peer); /* group->peer list reference */
 1838:       listnode_add (group->peer, peer);
 1839:       peer_group2peer_config_copy (group, peer, afi, safi);
 1840: 
 1841:       return 0;
 1842:     }
 1843: 
 1844:   /* When the peer already belongs to peer group, check the consistency.  */
 1845:   if (peer->af_group[afi][safi])
 1846:     {
 1847:       if (strcmp (peer->group->name, group->name) != 0)
 1848: 	return BGP_ERR_PEER_GROUP_CANT_CHANGE;
 1849: 
 1850:       return 0;
 1851:     }
 1852: 
 1853:   /* Check current peer group configuration.  */
 1854:   if (peer_group_active (peer)
 1855:       && strcmp (peer->group->name, group->name) != 0)
 1856:     return BGP_ERR_PEER_GROUP_MISMATCH;
 1857: 
 1858:   if (! group->conf->as)
 1859:     {
 1860:       if (peer_sort (group->conf) != BGP_PEER_INTERNAL
 1861: 	  && peer_sort (group->conf) != peer_sort (peer))
 1862: 	{
 1863: 	  if (as)
 1864: 	    *as = peer->as;
 1865: 	  return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT;
 1866: 	}
 1867: 
 1868:       if (peer_sort (group->conf) == BGP_PEER_INTERNAL)
 1869: 	first_member = 1;
 1870:     }
 1871: 
 1872:   peer->af_group[afi][safi] = 1;
 1873:   peer->afc[afi][safi] = 1;
 1874:   if (! peer->group)
 1875:     {
 1876:       peer->group = group;
 1877:       
 1878:       peer = peer_lock (peer); /* group->peer list reference */
 1879:       listnode_add (group->peer, peer);
 1880:     }
 1881:   else
 1882:     assert (group && peer->group == group);
 1883: 
 1884:   if (first_member)
 1885:     {
 1886:       /* Advertisement-interval reset */
 1887:       if (! CHECK_FLAG (group->conf->config, PEER_CONFIG_ROUTEADV))
 1888: 	{
 1889: 	  if (peer_sort (group->conf) == BGP_PEER_IBGP)
 1890: 	    group->conf->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
 1891: 	  else
 1892: 	    group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
 1893: 	}
 1894: 
 1895:       /* ebgp-multihop reset */
 1896:       if (peer_sort (group->conf) == BGP_PEER_IBGP)
 1897: 	group->conf->ttl = 255;
 1898: 
 1899:       /* local-as reset */
 1900:       if (peer_sort (group->conf) != BGP_PEER_EBGP)
 1901: 	{
 1902: 	  group->conf->change_local_as = 0;
 1903: 	  UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
 1904: 	  UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
 1905: 	}
 1906:     }
 1907: 
 1908:   if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
 1909:     {
 1910:       struct listnode *pn;
 1911:       
 1912:       /* If it's not configured as RSERVER_CLIENT in any other address
 1913:           family, without being member of a peer_group, remove it from
 1914:           list bgp->rsclient.*/
 1915:       if (! peer_rsclient_active (peer)
 1916:           && (pn = listnode_lookup (bgp->rsclient, peer)))
 1917:         {
 1918:           peer_unlock (peer); /* peer rsclient reference */
 1919:           list_delete_node (bgp->rsclient, pn);
 1920: 
 1921:           /* Clear our own rsclient rib for this afi/safi. */
 1922:           bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_MY_RSCLIENT);
 1923:         }
 1924: 
 1925:       bgp_table_finish (&peer->rib[afi][safi]);
 1926: 
 1927:       /* Import policy. */
 1928:       if (peer->filter[afi][safi].map[RMAP_IMPORT].name)
 1929:         {
 1930:           free (peer->filter[afi][safi].map[RMAP_IMPORT].name);
 1931:           peer->filter[afi][safi].map[RMAP_IMPORT].name = NULL;
 1932:           peer->filter[afi][safi].map[RMAP_IMPORT].map = NULL;
 1933:         }
 1934: 
 1935:       /* Export policy. */
 1936:       if (! CHECK_FLAG(group->conf->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
 1937:               && peer->filter[afi][safi].map[RMAP_EXPORT].name)
 1938:         {
 1939:           free (peer->filter[afi][safi].map[RMAP_EXPORT].name);
 1940:           peer->filter[afi][safi].map[RMAP_EXPORT].name = NULL;
 1941:           peer->filter[afi][safi].map[RMAP_EXPORT].map = NULL;
 1942:         }
 1943:     }
 1944: 
 1945:   peer_group2peer_config_copy (group, peer, afi, safi);
 1946: 
 1947:   if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
 1948:     {
 1949:       peer->last_reset = PEER_DOWN_RMAP_BIND;
 1950:       bgp_notify_send (peer, BGP_NOTIFY_CEASE,
 1951:                       BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 1952:     }
 1953:   else
 1954:     BGP_EVENT_ADD (peer, BGP_Stop);
 1955: 
 1956:   return 0;
 1957: }
 1958: 
 1959: int
 1960: peer_group_unbind (struct bgp *bgp, struct peer *peer,
 1961: 		   struct peer_group *group, afi_t afi, safi_t safi)
 1962: {
 1963:   if (! peer->af_group[afi][safi])
 1964:       return 0;
 1965: 
 1966:   if (group != peer->group)
 1967:     return BGP_ERR_PEER_GROUP_MISMATCH;
 1968: 
 1969:   peer->af_group[afi][safi] = 0;
 1970:   peer->afc[afi][safi] = 0;
 1971:   peer_af_flag_reset (peer, afi, safi);
 1972: 
 1973:   if (peer->rib[afi][safi])
 1974:     peer->rib[afi][safi] = NULL;
 1975: 
 1976:   if (! peer_group_active (peer))
 1977:     {
 1978:       assert (listnode_lookup (group->peer, peer));
 1979:       peer_unlock (peer); /* peer group list reference */
 1980:       listnode_delete (group->peer, peer);
 1981:       peer->group = NULL;
 1982:       if (group->conf->as)
 1983: 	{
 1984: 	  peer_delete (peer);
 1985: 	  return 0;
 1986: 	}
 1987:       peer_global_config_reset (peer);
 1988:     }
 1989: 
 1990:   if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
 1991:     {
 1992:       peer->last_reset = PEER_DOWN_RMAP_UNBIND;
 1993:       bgp_notify_send (peer, BGP_NOTIFY_CEASE,
 1994:                       BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 1995:     }
 1996:   else
 1997:     BGP_EVENT_ADD (peer, BGP_Stop);
 1998: 
 1999:   return 0;
 2000: }
 2001: 
 2002: 
 2003: static int
 2004: bgp_startup_timer_expire (struct thread *thread)
 2005: {
 2006:   struct bgp *bgp;
 2007: 
 2008:   bgp = THREAD_ARG (thread);
 2009:   bgp->t_startup = NULL;
 2010: 
 2011:   return 0;
 2012: }
 2013: 
 2014: /* BGP instance creation by `router bgp' commands. */
 2015: static struct bgp *
 2016: bgp_create (as_t *as, const char *name)
 2017: {
 2018:   struct bgp *bgp;
 2019:   afi_t afi;
 2020:   safi_t safi;
 2021: 
 2022:   if ( (bgp = XCALLOC (MTYPE_BGP, sizeof (struct bgp))) == NULL)
 2023:     return NULL;
 2024:   
 2025:   bgp_lock (bgp);
 2026:   bgp->peer_self = peer_new (bgp);
 2027:   bgp->peer_self->host = XSTRDUP (MTYPE_BGP_PEER_HOST, "Static announcement");
 2028: 
 2029:   bgp->peer = list_new ();
 2030:   bgp->peer->cmp = (int (*)(void *, void *)) peer_cmp;
 2031: 
 2032:   bgp->group = list_new ();
 2033:   bgp->group->cmp = (int (*)(void *, void *)) peer_group_cmp;
 2034: 
 2035:   bgp->rsclient = list_new ();
 2036:   bgp->rsclient->cmp = (int (*)(void*, void*)) peer_cmp;
 2037: 
 2038:   for (afi = AFI_IP; afi < AFI_MAX; afi++)
 2039:     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
 2040:       {
 2041: 	bgp->route[afi][safi] = bgp_table_init (afi, safi);
 2042: 	bgp->aggregate[afi][safi] = bgp_table_init (afi, safi);
 2043: 	bgp->rib[afi][safi] = bgp_table_init (afi, safi);
 2044: 	bgp->maxpaths[afi][safi].maxpaths_ebgp = BGP_DEFAULT_MAXPATHS;
 2045: 	bgp->maxpaths[afi][safi].maxpaths_ibgp = BGP_DEFAULT_MAXPATHS;
 2046:       }
 2047: 
 2048:   bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
 2049:   bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
 2050:   bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
 2051:   bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
 2052:   bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME;
 2053:   bgp_flag_set (bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
 2054: 
 2055:   bgp->as = *as;
 2056: 
 2057:   if (name)
 2058:     bgp->name = strdup (name);
 2059: 
 2060:   THREAD_TIMER_ON (bm->master, bgp->t_startup, bgp_startup_timer_expire,
 2061:                    bgp, bgp->restart_time);
 2062: 
 2063:   return bgp;
 2064: }
 2065: 
 2066: /* Return first entry of BGP. */
 2067: struct bgp *
 2068: bgp_get_default (void)
 2069: {
 2070:   if (bm && bm->bgp && bm->bgp->head)
 2071:     return (listgetdata (listhead (bm->bgp)));
 2072:   return NULL;
 2073: }
 2074: 
 2075: /* Lookup BGP entry. */
 2076: struct bgp *
 2077: bgp_lookup (as_t as, const char *name)
 2078: {
 2079:   struct bgp *bgp;
 2080:   struct listnode *node, *nnode;
 2081: 
 2082:   for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
 2083:     if (bgp->as == as
 2084: 	&& ((bgp->name == NULL && name == NULL) 
 2085: 	    || (bgp->name && name && strcmp (bgp->name, name) == 0)))
 2086:       return bgp;
 2087:   return NULL;
 2088: }
 2089: 
 2090: /* Lookup BGP structure by view name. */
 2091: struct bgp *
 2092: bgp_lookup_by_name (const char *name)
 2093: {
 2094:   struct bgp *bgp;
 2095:   struct listnode *node, *nnode;
 2096: 
 2097:   for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
 2098:     if ((bgp->name == NULL && name == NULL)
 2099: 	|| (bgp->name && name && strcmp (bgp->name, name) == 0))
 2100:       return bgp;
 2101:   return NULL;
 2102: }
 2103: 
 2104: /* Called from VTY commands. */
 2105: int
 2106: bgp_get (struct bgp **bgp_val, as_t *as, const char *name)
 2107: {
 2108:   struct bgp *bgp;
 2109: 
 2110:   /* Multiple instance check. */
 2111:   if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
 2112:     {
 2113:       if (name)
 2114: 	bgp = bgp_lookup_by_name (name);
 2115:       else
 2116: 	bgp = bgp_get_default ();
 2117: 
 2118:       /* Already exists. */
 2119:       if (bgp)
 2120: 	{
 2121:           if (bgp->as != *as)
 2122: 	    {
 2123: 	      *as = bgp->as;
 2124: 	      return BGP_ERR_INSTANCE_MISMATCH;
 2125: 	    }
 2126: 	  *bgp_val = bgp;
 2127: 	  return 0;
 2128: 	}
 2129:     }
 2130:   else
 2131:     {
 2132:       /* BGP instance name can not be specified for single instance.  */
 2133:       if (name)
 2134: 	return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET;
 2135: 
 2136:       /* Get default BGP structure if exists. */
 2137:       bgp = bgp_get_default ();
 2138: 
 2139:       if (bgp)
 2140: 	{
 2141: 	  if (bgp->as != *as)
 2142: 	    {
 2143: 	      *as = bgp->as;
 2144: 	      return BGP_ERR_AS_MISMATCH;
 2145: 	    }
 2146: 	  *bgp_val = bgp;
 2147: 	  return 0;
 2148: 	}
 2149:     }
 2150: 
 2151:   bgp = bgp_create (as, name);
 2152:   bgp_router_id_set(bgp, &router_id_zebra);
 2153:   *bgp_val = bgp;
 2154: 
 2155:   /* Create BGP server socket, if first instance.  */
 2156:   if (list_isempty(bm->bgp)
 2157:       && !bgp_option_check (BGP_OPT_NO_LISTEN))
 2158:     {
 2159:       if (bgp_socket (bm->port, bm->address) < 0)
 2160: 	return BGP_ERR_INVALID_VALUE;
 2161:     }
 2162: 
 2163:   listnode_add (bm->bgp, bgp);
 2164: 
 2165:   return 0;
 2166: }
 2167: 
 2168: /* Delete BGP instance. */
 2169: int
 2170: bgp_delete (struct bgp *bgp)
 2171: {
 2172:   struct peer *peer;
 2173:   struct peer_group *group;
 2174:   struct listnode *node, *pnode;
 2175:   struct listnode *next, *pnext;
 2176:   afi_t afi;
 2177:   int i;
 2178: 
 2179:   SET_FLAG(bgp->flags, BGP_FLAG_DELETING);
 2180: 
 2181:   THREAD_OFF (bgp->t_startup);
 2182: 
 2183:   /* Delete static route. */
 2184:   bgp_static_delete (bgp);
 2185: 
 2186:   /* Unset redistribution. */
 2187:   for (afi = AFI_IP; afi < AFI_MAX; afi++)
 2188:     for (i = 0; i < ZEBRA_ROUTE_MAX; i++) 
 2189:       if (i != ZEBRA_ROUTE_BGP)
 2190: 	bgp_redistribute_unset (bgp, afi, i);
 2191: 
 2192:   for (ALL_LIST_ELEMENTS (bgp->peer, node, next, peer))
 2193:     {
 2194:       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
 2195: 	{
 2196: 	  /* Send notify to remote peer. */
 2197: 	  bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
 2198: 	}
 2199: 
 2200:       peer_delete (peer);
 2201:     }
 2202: 
 2203:   for (ALL_LIST_ELEMENTS (bgp->group, node, next, group))
 2204:     {
 2205:       for (ALL_LIST_ELEMENTS (group->peer, pnode, pnext, peer))
 2206: 	{
 2207: 	  if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
 2208: 	    {
 2209: 	      /* Send notify to remote peer. */
 2210: 	      bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
 2211: 	    }
 2212: 	}
 2213:       peer_group_delete (group);
 2214:     }
 2215: 
 2216:   assert (listcount (bgp->rsclient) == 0);
 2217: 
 2218:   if (bgp->peer_self) {
 2219:     peer_delete(bgp->peer_self);
 2220:     bgp->peer_self = NULL;
 2221:   }
 2222: 
 2223:   /*
 2224:    * Free pending deleted routes. Unfortunately, it also has to process
 2225:    * all the pending activity for other instances of struct bgp.
 2226:    *
 2227:    * This call was added to achieve clean memory allocation at exit,
 2228:    * for the sake of valgrind.
 2229:    */
 2230:   bgp_process_queues_drain_immediate();
 2231: 
 2232:   /* Remove visibility via the master list - there may however still be
 2233:    * routes to be processed still referencing the struct bgp.
 2234:    */
 2235:   listnode_delete (bm->bgp, bgp);
 2236:   if (list_isempty(bm->bgp))
 2237:     bgp_close ();
 2238: 
 2239:   bgp_unlock(bgp);  /* initial reference */
 2240:   
 2241:   return 0;
 2242: }
 2243: 
 2244: static void bgp_free (struct bgp *);
 2245: 
 2246: void
 2247: bgp_lock (struct bgp *bgp)
 2248: {
 2249:   ++bgp->lock;
 2250: }
 2251: 
 2252: void
 2253: bgp_unlock(struct bgp *bgp)
 2254: {
 2255:   assert(bgp->lock > 0);
 2256:   if (--bgp->lock == 0)
 2257:     bgp_free (bgp);
 2258: }
 2259: 
 2260: static void
 2261: bgp_free (struct bgp *bgp)
 2262: {
 2263:   afi_t afi;
 2264:   safi_t safi;
 2265: 
 2266:   list_delete (bgp->group);
 2267:   list_delete (bgp->peer);
 2268:   list_delete (bgp->rsclient);
 2269: 
 2270:   if (bgp->name)
 2271:     free (bgp->name);
 2272:   
 2273:   for (afi = AFI_IP; afi < AFI_MAX; afi++)
 2274:     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
 2275:       {
 2276: 	if (bgp->route[afi][safi])
 2277:           bgp_table_finish (&bgp->route[afi][safi]);
 2278: 	if (bgp->aggregate[afi][safi])
 2279:           bgp_table_finish (&bgp->aggregate[afi][safi]) ;
 2280: 	if (bgp->rib[afi][safi])
 2281:           bgp_table_finish (&bgp->rib[afi][safi]);
 2282:       }
 2283:   XFREE (MTYPE_BGP, bgp);
 2284: }
 2285: 
 2286: struct peer *
 2287: peer_lookup (struct bgp *bgp, union sockunion *su)
 2288: {
 2289:   struct peer *peer;
 2290:   struct listnode *node, *nnode;
 2291: 
 2292:   if (bgp != NULL)
 2293:     {
 2294:       for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
 2295:         if (sockunion_same (&peer->su, su)
 2296:             && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
 2297:           return peer;
 2298:     }
 2299:   else if (bm->bgp != NULL)
 2300:     {
 2301:       struct listnode *bgpnode, *nbgpnode;
 2302:   
 2303:       for (ALL_LIST_ELEMENTS (bm->bgp, bgpnode, nbgpnode, bgp))
 2304:         for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
 2305:           if (sockunion_same (&peer->su, su)
 2306:               && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
 2307:             return peer;
 2308:     }
 2309:   return NULL;
 2310: }
 2311: 
 2312: struct peer *
 2313: peer_lookup_with_open (union sockunion *su, as_t remote_as,
 2314: 		       struct in_addr *remote_id, int *as)
 2315: {
 2316:   struct peer *peer;
 2317:   struct listnode *node;
 2318:   struct listnode *bgpnode;
 2319:   struct bgp *bgp;
 2320: 
 2321:   if (! bm->bgp)
 2322:     return NULL;
 2323: 
 2324:   for (ALL_LIST_ELEMENTS_RO (bm->bgp, bgpnode, bgp))
 2325:     {
 2326:       for (ALL_LIST_ELEMENTS_RO (bgp->peer, node, peer))
 2327:         {
 2328:           if (sockunion_same (&peer->su, su)
 2329:               && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
 2330:             {
 2331:               if (peer->as == remote_as
 2332:                   && peer->remote_id.s_addr == remote_id->s_addr)
 2333:                 return peer;
 2334:               if (peer->as == remote_as)
 2335:                 *as = 1;
 2336:             }
 2337:         }
 2338: 
 2339:       for (ALL_LIST_ELEMENTS_RO (bgp->peer, node, peer))
 2340:         {
 2341:           if (sockunion_same (&peer->su, su)
 2342:               &&  ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
 2343:             {
 2344:               if (peer->as == remote_as
 2345:                   && peer->remote_id.s_addr == 0)
 2346:                 return peer;
 2347:               if (peer->as == remote_as)
 2348:                 *as = 1;
 2349:             }
 2350:         }
 2351:     }
 2352:   return NULL;
 2353: }
 2354: 
 2355: /* If peer is configured at least one address family return 1. */
 2356: int
 2357: peer_active (struct peer *peer)
 2358: {
 2359:   if (peer->afc[AFI_IP][SAFI_UNICAST]
 2360:       || peer->afc[AFI_IP][SAFI_MULTICAST]
 2361:       || peer->afc[AFI_IP][SAFI_MPLS_VPN]
 2362:       || peer->afc[AFI_IP][SAFI_ENCAP]
 2363:       || peer->afc[AFI_IP6][SAFI_UNICAST]
 2364:       || peer->afc[AFI_IP6][SAFI_MULTICAST]
 2365:       || peer->afc[AFI_IP6][SAFI_MPLS_VPN]
 2366:       || peer->afc[AFI_IP6][SAFI_ENCAP])
 2367:     return 1;
 2368:   return 0;
 2369: }
 2370: 
 2371: /* If peer is negotiated at least one address family return 1. */
 2372: int
 2373: peer_active_nego (struct peer *peer)
 2374: {
 2375:   if (peer->afc_nego[AFI_IP][SAFI_UNICAST]
 2376:       || peer->afc_nego[AFI_IP][SAFI_MULTICAST]
 2377:       || peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
 2378:       || peer->afc_nego[AFI_IP][SAFI_ENCAP]
 2379:       || peer->afc_nego[AFI_IP6][SAFI_UNICAST]
 2380:       || peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
 2381:       || peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
 2382:       || peer->afc_nego[AFI_IP6][SAFI_ENCAP])
 2383:     return 1;
 2384:   return 0;
 2385: }
 2386: 
 2387: /* peer_flag_change_type. */
 2388: enum peer_change_type
 2389: {
 2390:   peer_change_none,
 2391:   peer_change_reset,
 2392:   peer_change_reset_in,
 2393:   peer_change_reset_out,
 2394: };
 2395: 
 2396: static void
 2397: peer_change_action (struct peer *peer, afi_t afi, safi_t safi,
 2398: 		    enum peer_change_type type)
 2399: {
 2400:   if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 2401:     return;
 2402: 
 2403:   if (peer->status != Established)
 2404:     return;
 2405: 
 2406:   if (type == peer_change_reset)
 2407:     bgp_notify_send (peer, BGP_NOTIFY_CEASE,
 2408: 		     BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 2409:   else if (type == peer_change_reset_in)
 2410:     {
 2411:       if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV)
 2412: 	  || CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
 2413: 	bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
 2414:       else
 2415: 	bgp_notify_send (peer, BGP_NOTIFY_CEASE,
 2416: 			 BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 2417:     }
 2418:   else if (type == peer_change_reset_out)
 2419:     bgp_announce_route (peer, afi, safi);
 2420: }
 2421: 
 2422: struct peer_flag_action
 2423: {
 2424:   /* Peer's flag.  */
 2425:   u_int32_t flag;
 2426: 
 2427:   /* This flag can be set for peer-group member.  */
 2428:   u_char not_for_member;
 2429: 
 2430:   /* Action when the flag is changed.  */
 2431:   enum peer_change_type type;
 2432: 
 2433:   /* Peer down cause */
 2434:   u_char peer_down;
 2435: };
 2436: 
 2437: static const struct peer_flag_action peer_flag_action_list[] =
 2438:   {
 2439:     { PEER_FLAG_PASSIVE,                  0, peer_change_reset },
 2440:     { PEER_FLAG_SHUTDOWN,                 0, peer_change_reset },
 2441:     { PEER_FLAG_DONT_CAPABILITY,          0, peer_change_none },
 2442:     { PEER_FLAG_OVERRIDE_CAPABILITY,      0, peer_change_none },
 2443:     { PEER_FLAG_STRICT_CAP_MATCH,         0, peer_change_none },
 2444:     { PEER_FLAG_DYNAMIC_CAPABILITY,       0, peer_change_reset },
 2445:     { PEER_FLAG_DISABLE_CONNECTED_CHECK,  0, peer_change_reset },
 2446:     { 0, 0, 0 }
 2447:   };
 2448: 
 2449: static const struct peer_flag_action peer_af_flag_action_list[] =
 2450:   {
 2451:     { PEER_FLAG_NEXTHOP_SELF,             1, peer_change_reset_out },
 2452:     { PEER_FLAG_SEND_COMMUNITY,           1, peer_change_reset_out },
 2453:     { PEER_FLAG_SEND_EXT_COMMUNITY,       1, peer_change_reset_out },
 2454:     { PEER_FLAG_SOFT_RECONFIG,            0, peer_change_reset_in },
 2455:     { PEER_FLAG_REFLECTOR_CLIENT,         1, peer_change_reset },
 2456:     { PEER_FLAG_RSERVER_CLIENT,           1, peer_change_reset },
 2457:     { PEER_FLAG_AS_PATH_UNCHANGED,        1, peer_change_reset_out },
 2458:     { PEER_FLAG_NEXTHOP_UNCHANGED,        1, peer_change_reset_out },
 2459:     { PEER_FLAG_MED_UNCHANGED,            1, peer_change_reset_out },
 2460:     { PEER_FLAG_REMOVE_PRIVATE_AS,        1, peer_change_reset_out },
 2461:     { PEER_FLAG_ALLOWAS_IN,               0, peer_change_reset_in },
 2462:     { PEER_FLAG_ORF_PREFIX_SM,            1, peer_change_reset },
 2463:     { PEER_FLAG_ORF_PREFIX_RM,            1, peer_change_reset },
 2464:     { PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED,  0, peer_change_reset_out },
 2465:     { PEER_FLAG_NEXTHOP_SELF_ALL,         1, peer_change_reset_out },
 2466:     { 0, 0, 0 }
 2467:   };
 2468: 
 2469: /* Proper action set. */
 2470: static int
 2471: peer_flag_action_set (const struct peer_flag_action *action_list, int size,
 2472: 		      struct peer_flag_action *action, u_int32_t flag)
 2473: {
 2474:   int i;
 2475:   int found = 0;
 2476:   int reset_in = 0;
 2477:   int reset_out = 0;
 2478:   const struct peer_flag_action *match = NULL;
 2479: 
 2480:   /* Check peer's frag action.  */
 2481:   for (i = 0; i < size; i++)
 2482:     {
 2483:       match = &action_list[i];
 2484: 
 2485:       if (match->flag == 0)
 2486: 	break;
 2487: 
 2488:       if (match->flag & flag)
 2489: 	{
 2490: 	  found = 1;
 2491: 
 2492: 	  if (match->type == peer_change_reset_in)
 2493: 	    reset_in = 1;
 2494: 	  if (match->type == peer_change_reset_out)
 2495: 	    reset_out = 1;
 2496: 	  if (match->type == peer_change_reset)
 2497: 	    {
 2498: 	      reset_in = 1;
 2499: 	      reset_out = 1;
 2500: 	    }
 2501: 	  if (match->not_for_member)
 2502: 	    action->not_for_member = 1;
 2503: 	}
 2504:     }
 2505: 
 2506:   /* Set peer clear type.  */
 2507:   if (reset_in && reset_out)
 2508:     action->type = peer_change_reset;
 2509:   else if (reset_in)
 2510:     action->type = peer_change_reset_in;
 2511:   else if (reset_out)
 2512:     action->type = peer_change_reset_out;
 2513:   else
 2514:     action->type = peer_change_none;
 2515: 
 2516:   return found;
 2517: }
 2518: 
 2519: static void
 2520: peer_flag_modify_action (struct peer *peer, u_int32_t flag)
 2521: {
 2522:   if (flag == PEER_FLAG_SHUTDOWN)
 2523:     {
 2524:       if (CHECK_FLAG (peer->flags, flag))
 2525: 	{
 2526: 	  if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
 2527: 	    peer_nsf_stop (peer);
 2528: 
 2529: 	  UNSET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
 2530: 	  if (peer->t_pmax_restart)
 2531: 	    {
 2532: 	      BGP_TIMER_OFF (peer->t_pmax_restart);
 2533:               if (BGP_DEBUG (events, EVENTS))
 2534: 		zlog_debug ("%s Maximum-prefix restart timer canceled",
 2535: 			    peer->host);
 2536: 	    }
 2537: 
 2538:       if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
 2539: 	peer_nsf_stop (peer);
 2540: 
 2541: 	  if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
 2542: 	    bgp_notify_send (peer, BGP_NOTIFY_CEASE,
 2543: 			     BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
 2544: 	  else
 2545: 	    BGP_EVENT_ADD (peer, BGP_Stop);
 2546: 	}
 2547:       else
 2548: 	{
 2549: 	  peer->v_start = BGP_INIT_START_TIMER;
 2550: 	  BGP_EVENT_ADD (peer, BGP_Stop);
 2551: 	}
 2552:     }
 2553:   else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
 2554:     {
 2555:       if (flag == PEER_FLAG_DYNAMIC_CAPABILITY)
 2556: 	peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
 2557:       else if (flag == PEER_FLAG_PASSIVE)
 2558: 	peer->last_reset = PEER_DOWN_PASSIVE_CHANGE;
 2559:       else if (flag == PEER_FLAG_DISABLE_CONNECTED_CHECK)
 2560: 	peer->last_reset = PEER_DOWN_MULTIHOP_CHANGE;
 2561: 
 2562:       bgp_notify_send (peer, BGP_NOTIFY_CEASE,
 2563: 		       BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 2564:     }
 2565:   else
 2566:     BGP_EVENT_ADD (peer, BGP_Stop);
 2567: }
 2568: 
 2569: /* Change specified peer flag. */
 2570: static int
 2571: peer_flag_modify (struct peer *peer, u_int32_t flag, int set)
 2572: {
 2573:   int found;
 2574:   int size;
 2575:   struct peer_group *group;
 2576:   struct listnode *node, *nnode;
 2577:   struct peer_flag_action action;
 2578: 
 2579:   memset (&action, 0, sizeof (struct peer_flag_action));
 2580:   size = sizeof peer_flag_action_list / sizeof (struct peer_flag_action);
 2581: 
 2582:   found = peer_flag_action_set (peer_flag_action_list, size, &action, flag);
 2583: 
 2584:   /* No flag action is found.  */
 2585:   if (! found)
 2586:     return BGP_ERR_INVALID_FLAG;    
 2587: 
 2588:   /* Not for peer-group member.  */
 2589:   if (action.not_for_member && peer_group_active (peer))
 2590:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 2591: 
 2592:   /* When unset the peer-group member's flag we have to check
 2593:      peer-group configuration.  */
 2594:   if (! set && peer_group_active (peer))
 2595:     if (CHECK_FLAG (peer->group->conf->flags, flag))
 2596:       {
 2597: 	if (flag == PEER_FLAG_SHUTDOWN)
 2598: 	  return BGP_ERR_PEER_GROUP_SHUTDOWN;
 2599: 	else
 2600: 	  return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
 2601:       }
 2602: 
 2603:   /* Flag conflict check.  */
 2604:   if (set
 2605:       && CHECK_FLAG (peer->flags | flag, PEER_FLAG_STRICT_CAP_MATCH)
 2606:       && CHECK_FLAG (peer->flags | flag, PEER_FLAG_OVERRIDE_CAPABILITY))
 2607:     return BGP_ERR_PEER_FLAG_CONFLICT;
 2608: 
 2609:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 2610:     {
 2611:       if (set && CHECK_FLAG (peer->flags, flag) == flag)
 2612: 	return 0;
 2613:       if (! set && ! CHECK_FLAG (peer->flags, flag))
 2614: 	return 0;
 2615:     }
 2616: 
 2617:   if (set)
 2618:     SET_FLAG (peer->flags, flag);
 2619:   else
 2620:     UNSET_FLAG (peer->flags, flag);
 2621:  
 2622:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 2623:     {
 2624:       if (action.type == peer_change_reset)
 2625: 	peer_flag_modify_action (peer, flag);
 2626: 
 2627:       return 0;
 2628:     }
 2629: 
 2630:   /* peer-group member updates. */
 2631:   group = peer->group;
 2632: 
 2633:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 2634:     {
 2635:       if (set && CHECK_FLAG (peer->flags, flag) == flag)
 2636: 	continue;
 2637: 
 2638:       if (! set && ! CHECK_FLAG (peer->flags, flag))
 2639: 	continue;
 2640: 
 2641:       if (set)
 2642: 	SET_FLAG (peer->flags, flag);
 2643:       else
 2644: 	UNSET_FLAG (peer->flags, flag);
 2645: 
 2646:       if (action.type == peer_change_reset)
 2647: 	peer_flag_modify_action (peer, flag);
 2648:     }
 2649:   return 0;
 2650: }
 2651: 
 2652: int
 2653: peer_flag_set (struct peer *peer, u_int32_t flag)
 2654: {
 2655:   return peer_flag_modify (peer, flag, 1);
 2656: }
 2657: 
 2658: int
 2659: peer_flag_unset (struct peer *peer, u_int32_t flag)
 2660: {
 2661:   return peer_flag_modify (peer, flag, 0);
 2662: }
 2663: 
 2664: static int
 2665: peer_is_group_member (struct peer *peer, afi_t afi, safi_t safi)
 2666: {
 2667:   if (peer->af_group[afi][safi])
 2668:     return 1;
 2669:   return 0;
 2670: }
 2671: 
 2672: static int
 2673: peer_af_flag_modify (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag,
 2674: 		     int set)
 2675: {
 2676:   int found;
 2677:   int size;
 2678:   struct listnode *node, *nnode;
 2679:   struct peer_group *group;
 2680:   struct peer_flag_action action;
 2681: 
 2682:   memset (&action, 0, sizeof (struct peer_flag_action));
 2683:   size = sizeof peer_af_flag_action_list / sizeof (struct peer_flag_action);
 2684:   
 2685:   found = peer_flag_action_set (peer_af_flag_action_list, size, &action, flag);
 2686:   
 2687:   /* No flag action is found.  */
 2688:   if (! found)
 2689:     return BGP_ERR_INVALID_FLAG;    
 2690: 
 2691:   /* Adress family must be activated.  */
 2692:   if (! peer->afc[afi][safi])
 2693:     return BGP_ERR_PEER_INACTIVE;
 2694: 
 2695:   /* Not for peer-group member.  */
 2696:   if (action.not_for_member && peer_is_group_member (peer, afi, safi))
 2697:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 2698: 
 2699:  /* Spcecial check for reflector client.  */
 2700:   if (flag & PEER_FLAG_REFLECTOR_CLIENT
 2701:       && peer_sort (peer) != BGP_PEER_IBGP)
 2702:     return BGP_ERR_NOT_INTERNAL_PEER;
 2703: 
 2704:   /* Spcecial check for remove-private-AS.  */
 2705:   if (flag & PEER_FLAG_REMOVE_PRIVATE_AS
 2706:       && peer_sort (peer) == BGP_PEER_IBGP)
 2707:     return BGP_ERR_REMOVE_PRIVATE_AS;
 2708: 
 2709:   /* When unset the peer-group member's flag we have to check
 2710:      peer-group configuration.  */
 2711:   if (! set && peer->af_group[afi][safi])
 2712:     if (CHECK_FLAG (peer->group->conf->af_flags[afi][safi], flag))
 2713:       return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
 2714: 
 2715:   /* When current flag configuration is same as requested one.  */
 2716:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 2717:     {
 2718:       if (set && CHECK_FLAG (peer->af_flags[afi][safi], flag) == flag)
 2719: 	return 0;
 2720:       if (! set && ! CHECK_FLAG (peer->af_flags[afi][safi], flag))
 2721: 	return 0;
 2722:     }
 2723: 
 2724:   if (set)
 2725:     SET_FLAG (peer->af_flags[afi][safi], flag);
 2726:   else
 2727:     UNSET_FLAG (peer->af_flags[afi][safi], flag);
 2728: 
 2729:   /* Execute action when peer is established.  */
 2730:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
 2731:       && peer->status == Established)
 2732:     {
 2733:       if (! set && flag == PEER_FLAG_SOFT_RECONFIG)
 2734: 	bgp_clear_adj_in (peer, afi, safi);
 2735:       else
 2736:        {
 2737:          if (flag == PEER_FLAG_REFLECTOR_CLIENT)
 2738:            peer->last_reset = PEER_DOWN_RR_CLIENT_CHANGE;
 2739:          else if (flag == PEER_FLAG_RSERVER_CLIENT)
 2740:            peer->last_reset = PEER_DOWN_RS_CLIENT_CHANGE;
 2741:          else if (flag == PEER_FLAG_ORF_PREFIX_SM)
 2742:            peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
 2743:          else if (flag == PEER_FLAG_ORF_PREFIX_RM)
 2744:            peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
 2745: 
 2746:          peer_change_action (peer, afi, safi, action.type);
 2747:        }
 2748: 
 2749:     }
 2750: 
 2751:   /* Peer group member updates.  */
 2752:   if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 2753:     {
 2754:       group = peer->group;
 2755:       
 2756:       for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 2757: 	{
 2758: 	  if (! peer->af_group[afi][safi])
 2759: 	    continue;
 2760: 
 2761: 	  if (set && CHECK_FLAG (peer->af_flags[afi][safi], flag) == flag)
 2762: 	    continue;
 2763: 
 2764: 	  if (! set && ! CHECK_FLAG (peer->af_flags[afi][safi], flag))
 2765: 	    continue;
 2766: 
 2767: 	  if (set)
 2768: 	    SET_FLAG (peer->af_flags[afi][safi], flag);
 2769: 	  else
 2770: 	    UNSET_FLAG (peer->af_flags[afi][safi], flag);
 2771: 
 2772: 	  if (peer->status == Established)
 2773: 	    {
 2774: 	      if (! set && flag == PEER_FLAG_SOFT_RECONFIG)
 2775: 		bgp_clear_adj_in (peer, afi, safi);
 2776: 	      else
 2777:                {
 2778:                  if (flag == PEER_FLAG_REFLECTOR_CLIENT)
 2779:                    peer->last_reset = PEER_DOWN_RR_CLIENT_CHANGE;
 2780:                  else if (flag == PEER_FLAG_RSERVER_CLIENT)
 2781:                    peer->last_reset = PEER_DOWN_RS_CLIENT_CHANGE;
 2782:                  else if (flag == PEER_FLAG_ORF_PREFIX_SM)
 2783:                    peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
 2784:                  else if (flag == PEER_FLAG_ORF_PREFIX_RM)
 2785:                    peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
 2786: 
 2787:                  peer_change_action (peer, afi, safi, action.type);
 2788:                }
 2789: 	    }
 2790: 	}
 2791:     }
 2792:   return 0;
 2793: }
 2794: 
 2795: int
 2796: peer_af_flag_set (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
 2797: {
 2798:   return peer_af_flag_modify (peer, afi, safi, flag, 1);
 2799: }
 2800: 
 2801: int
 2802: peer_af_flag_unset (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
 2803: {
 2804:   return peer_af_flag_modify (peer, afi, safi, flag, 0);
 2805: }
 2806: 
 2807: /* EBGP multihop configuration. */
 2808: int
 2809: peer_ebgp_multihop_set (struct peer *peer, int ttl)
 2810: {
 2811:   struct peer_group *group;
 2812:   struct listnode *node, *nnode;
 2813:   struct peer *peer1;
 2814: 
 2815:   if (peer->sort == BGP_PEER_IBGP)
 2816:     return 0;
 2817: 
 2818:   /* see comment in peer_ttl_security_hops_set() */
 2819:   if (ttl != MAXTTL)
 2820:     {
 2821:       if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 2822:         {
 2823:           group = peer->group;
 2824:           if (group->conf->gtsm_hops != 0)
 2825:             return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
 2826: 
 2827:           for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
 2828:             {
 2829:               if (peer1->sort == BGP_PEER_IBGP)
 2830:                 continue;
 2831: 
 2832:               if (peer1->gtsm_hops != 0)
 2833:                 return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
 2834:             }
 2835:         }
 2836:       else
 2837:         {
 2838:           if (peer->gtsm_hops != 0)
 2839:             return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
 2840:         }
 2841:     }
 2842: 
 2843:   peer->ttl = ttl;
 2844: 
 2845:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 2846:     {
 2847:       if (peer->fd >= 0 && peer->sort != BGP_PEER_IBGP)
 2848: 	sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
 2849:     }
 2850:   else
 2851:     {
 2852:       group = peer->group;
 2853:       for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 2854: 	{
 2855: 	  if (peer->sort == BGP_PEER_IBGP)
 2856: 	    continue;
 2857: 
 2858: 	  peer->ttl = group->conf->ttl;
 2859: 
 2860: 	  if (peer->fd >= 0)
 2861: 	    sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
 2862: 	}
 2863:     }
 2864:   return 0;
 2865: }
 2866: 
 2867: int
 2868: peer_ebgp_multihop_unset (struct peer *peer)
 2869: {
 2870:   struct peer_group *group;
 2871:   struct listnode *node, *nnode;
 2872: 
 2873:   if (peer->sort == BGP_PEER_IBGP)
 2874:     return 0;
 2875: 
 2876:   if (peer->gtsm_hops != 0 && peer->ttl != MAXTTL)
 2877:       return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
 2878: 
 2879:   if (peer_group_active (peer))
 2880:     peer->ttl = peer->group->conf->ttl;
 2881:   else
 2882:     peer->ttl = 1;
 2883: 
 2884:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 2885:     {
 2886:       if (peer->fd >= 0 && peer->sort != BGP_PEER_IBGP)
 2887: 	sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
 2888:     }
 2889:   else
 2890:     {
 2891:       group = peer->group;
 2892:       for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 2893: 	{
 2894: 	  if (peer->sort == BGP_PEER_IBGP)
 2895: 	    continue;
 2896: 
 2897: 	  peer->ttl = 1;
 2898: 	  
 2899: 	  if (peer->fd >= 0)
 2900: 	    sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
 2901: 	}
 2902:     }
 2903:   return 0;
 2904: }
 2905: 
 2906: /* Neighbor description. */
 2907: int
 2908: peer_description_set (struct peer *peer, char *desc)
 2909: {
 2910:   if (peer->desc)
 2911:     XFREE (MTYPE_PEER_DESC, peer->desc);
 2912: 
 2913:   peer->desc = XSTRDUP (MTYPE_PEER_DESC, desc);
 2914: 
 2915:   return 0;
 2916: }
 2917: 
 2918: int
 2919: peer_description_unset (struct peer *peer)
 2920: {
 2921:   if (peer->desc)
 2922:     XFREE (MTYPE_PEER_DESC, peer->desc);
 2923: 
 2924:   peer->desc = NULL;
 2925: 
 2926:   return 0;
 2927: }
 2928: 
 2929: /* Neighbor update-source. */
 2930: int
 2931: peer_update_source_if_set (struct peer *peer, const char *ifname)
 2932: {
 2933:   struct peer_group *group;
 2934:   struct listnode *node, *nnode;
 2935: 
 2936:   if (peer->update_if)
 2937:     {
 2938:       if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
 2939: 	  && strcmp (peer->update_if, ifname) == 0)
 2940: 	return 0;
 2941: 
 2942:       XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
 2943:       peer->update_if = NULL;
 2944:     }
 2945: 
 2946:   if (peer->update_source)
 2947:     {
 2948:       sockunion_free (peer->update_source);
 2949:       peer->update_source = NULL;
 2950:     }
 2951: 
 2952:   peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, ifname);
 2953: 
 2954:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 2955:     {
 2956:       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
 2957:        {
 2958:          peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
 2959:          bgp_notify_send (peer, BGP_NOTIFY_CEASE,
 2960:                           BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 2961:        }
 2962:       else
 2963: 	BGP_EVENT_ADD (peer, BGP_Stop);
 2964:       return 0;
 2965:     }
 2966: 
 2967:   /* peer-group member updates. */
 2968:   group = peer->group;
 2969:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 2970:     {
 2971:       if (peer->update_if)
 2972: 	{
 2973: 	  if (strcmp (peer->update_if, ifname) == 0)
 2974: 	    continue;
 2975: 
 2976: 	  XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
 2977: 	  peer->update_if = NULL;
 2978: 	}
 2979: 
 2980:       if (peer->update_source)
 2981: 	{
 2982: 	  sockunion_free (peer->update_source);
 2983: 	  peer->update_source = NULL;
 2984: 	}
 2985: 
 2986:       peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, ifname);
 2987: 
 2988:       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
 2989:        {
 2990:          peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
 2991:          bgp_notify_send (peer, BGP_NOTIFY_CEASE,
 2992:                           BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 2993:        }
 2994:       else
 2995: 	BGP_EVENT_ADD (peer, BGP_Stop);
 2996:     }
 2997:   return 0;
 2998: }
 2999: 
 3000: int
 3001: peer_update_source_addr_set (struct peer *peer, union sockunion *su)
 3002: {
 3003:   struct peer_group *group;
 3004:   struct listnode *node, *nnode;
 3005: 
 3006:   if (peer->update_source)
 3007:     {
 3008:       if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
 3009: 	  && sockunion_cmp (peer->update_source, su) == 0)
 3010: 	return 0;
 3011:       sockunion_free (peer->update_source);
 3012:       peer->update_source = NULL;
 3013:     }
 3014: 
 3015:   if (peer->update_if)
 3016:     {
 3017:       XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
 3018:       peer->update_if = NULL;
 3019:     }
 3020: 
 3021:   peer->update_source = sockunion_dup (su);
 3022: 
 3023:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3024:     {
 3025:       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
 3026:        {
 3027:          peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
 3028:          bgp_notify_send (peer, BGP_NOTIFY_CEASE,
 3029:                           BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 3030:        }
 3031:       else
 3032: 	BGP_EVENT_ADD (peer, BGP_Stop);
 3033:       return 0;
 3034:     }
 3035: 
 3036:   /* peer-group member updates. */
 3037:   group = peer->group;
 3038:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 3039:     {
 3040:       if (peer->update_source)
 3041: 	{
 3042: 	  if (sockunion_cmp (peer->update_source, su) == 0)
 3043: 	    continue;
 3044: 	  sockunion_free (peer->update_source);
 3045: 	  peer->update_source = NULL;
 3046: 	}
 3047: 
 3048:       if (peer->update_if)
 3049: 	{
 3050: 	  XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
 3051: 	  peer->update_if = NULL;
 3052: 	}
 3053: 
 3054:       peer->update_source = sockunion_dup (su);
 3055: 
 3056:       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
 3057:        {
 3058:          peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
 3059:          bgp_notify_send (peer, BGP_NOTIFY_CEASE,
 3060:                           BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 3061:        }
 3062:       else
 3063: 	BGP_EVENT_ADD (peer, BGP_Stop);
 3064:     }
 3065:   return 0;
 3066: }
 3067: 
 3068: int
 3069: peer_update_source_unset (struct peer *peer)
 3070: {
 3071:   union sockunion *su;
 3072:   struct peer_group *group;
 3073:   struct listnode *node, *nnode;
 3074: 
 3075:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
 3076:       && ! peer->update_source
 3077:       && ! peer->update_if)
 3078:     return 0;
 3079: 
 3080:   if (peer->update_source)
 3081:     {
 3082:       sockunion_free (peer->update_source);
 3083:       peer->update_source = NULL;
 3084:     }
 3085:   if (peer->update_if)
 3086:     {
 3087:       XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
 3088:       peer->update_if = NULL;
 3089:     }
 3090: 
 3091:   if (peer_group_active (peer))
 3092:     {
 3093:       group = peer->group;
 3094: 
 3095:       if (group->conf->update_source)
 3096: 	{
 3097: 	  su = sockunion_dup (group->conf->update_source);
 3098: 	  peer->update_source = su;
 3099: 	}
 3100:       else if (group->conf->update_if)
 3101: 	peer->update_if = 
 3102: 	  XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, group->conf->update_if);
 3103:     }
 3104: 
 3105:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3106:     {
 3107:       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
 3108:        {
 3109:          peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
 3110:          bgp_notify_send (peer, BGP_NOTIFY_CEASE,
 3111:                           BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 3112:        }
 3113:       else
 3114: 	BGP_EVENT_ADD (peer, BGP_Stop);
 3115:       return 0;
 3116:     }
 3117: 
 3118:   /* peer-group member updates. */
 3119:   group = peer->group;
 3120:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 3121:     {
 3122:       if (! peer->update_source && ! peer->update_if)
 3123: 	continue;
 3124: 
 3125:       if (peer->update_source)
 3126: 	{
 3127: 	  sockunion_free (peer->update_source);
 3128: 	  peer->update_source = NULL;
 3129: 	}
 3130: 
 3131:       if (peer->update_if)
 3132: 	{
 3133: 	  XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
 3134: 	  peer->update_if = NULL;
 3135: 	}
 3136: 
 3137:       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
 3138:        {
 3139:          peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
 3140:          bgp_notify_send (peer, BGP_NOTIFY_CEASE,
 3141:                           BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 3142:        }
 3143:       else
 3144: 	BGP_EVENT_ADD (peer, BGP_Stop);
 3145:     }
 3146:   return 0;
 3147: }
 3148: 
 3149: int
 3150: peer_default_originate_set (struct peer *peer, afi_t afi, safi_t safi,
 3151: 			    const char *rmap)
 3152: {
 3153:   struct peer_group *group;
 3154:   struct listnode *node, *nnode;
 3155: 
 3156:   /* Adress family must be activated.  */
 3157:   if (! peer->afc[afi][safi])
 3158:     return BGP_ERR_PEER_INACTIVE;
 3159: 
 3160:   /* Default originate can't be used for peer group memeber.  */
 3161:   if (peer_is_group_member (peer, afi, safi))
 3162:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 3163: 
 3164:   if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE)
 3165:       || (rmap && ! peer->default_rmap[afi][safi].name)
 3166:       || (rmap && strcmp (rmap, peer->default_rmap[afi][safi].name) != 0))
 3167:     { 
 3168:       SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
 3169: 
 3170:       if (rmap)
 3171: 	{
 3172: 	  if (peer->default_rmap[afi][safi].name)
 3173: 	    free (peer->default_rmap[afi][safi].name);
 3174: 	  peer->default_rmap[afi][safi].name = strdup (rmap);
 3175: 	  peer->default_rmap[afi][safi].map = route_map_lookup_by_name (rmap);
 3176: 	}
 3177:     }
 3178: 
 3179:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3180:     {
 3181:       if (peer->status == Established && peer->afc_nego[afi][safi])
 3182: 	bgp_default_originate (peer, afi, safi, 0);
 3183:       return 0;
 3184:     }
 3185: 
 3186:   /* peer-group member updates. */
 3187:   group = peer->group;
 3188:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 3189:     {
 3190:       SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
 3191: 
 3192:       if (rmap)
 3193: 	{
 3194: 	  if (peer->default_rmap[afi][safi].name)
 3195: 	    free (peer->default_rmap[afi][safi].name);
 3196: 	  peer->default_rmap[afi][safi].name = strdup (rmap);
 3197: 	  peer->default_rmap[afi][safi].map = route_map_lookup_by_name (rmap);
 3198: 	}
 3199: 
 3200:       if (peer->status == Established && peer->afc_nego[afi][safi])
 3201: 	bgp_default_originate (peer, afi, safi, 0);
 3202:     }
 3203:   return 0;
 3204: }
 3205: 
 3206: int
 3207: peer_default_originate_unset (struct peer *peer, afi_t afi, safi_t safi)
 3208: {
 3209:   struct peer_group *group;
 3210:   struct listnode *node, *nnode;
 3211: 
 3212:   /* Adress family must be activated.  */
 3213:   if (! peer->afc[afi][safi])
 3214:     return BGP_ERR_PEER_INACTIVE;
 3215: 
 3216:   /* Default originate can't be used for peer group memeber.  */
 3217:   if (peer_is_group_member (peer, afi, safi))
 3218:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 3219: 
 3220:   if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE))
 3221:     { 
 3222:       UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
 3223: 
 3224:       if (peer->default_rmap[afi][safi].name)
 3225: 	free (peer->default_rmap[afi][safi].name);
 3226:       peer->default_rmap[afi][safi].name = NULL;
 3227:       peer->default_rmap[afi][safi].map = NULL;
 3228:     }
 3229: 
 3230:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3231:     {
 3232:       if (peer->status == Established && peer->afc_nego[afi][safi])
 3233: 	bgp_default_originate (peer, afi, safi, 1);
 3234:       return 0;
 3235:     }
 3236: 
 3237:   /* peer-group member updates. */
 3238:   group = peer->group;
 3239:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 3240:     {
 3241:       UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
 3242: 
 3243:       if (peer->default_rmap[afi][safi].name)
 3244: 	free (peer->default_rmap[afi][safi].name);
 3245:       peer->default_rmap[afi][safi].name = NULL;
 3246:       peer->default_rmap[afi][safi].map = NULL;
 3247: 
 3248:       if (peer->status == Established && peer->afc_nego[afi][safi])
 3249: 	bgp_default_originate (peer, afi, safi, 1);
 3250:     }
 3251:   return 0;
 3252: }
 3253: 
 3254: int
 3255: peer_port_set (struct peer *peer, u_int16_t port)
 3256: {
 3257:   peer->port = port;
 3258:   return 0;
 3259: }
 3260: 
 3261: int
 3262: peer_port_unset (struct peer *peer)
 3263: {
 3264:   peer->port = BGP_PORT_DEFAULT;
 3265:   return 0;
 3266: }
 3267: 
 3268: /* neighbor weight. */
 3269: int
 3270: peer_weight_set (struct peer *peer, u_int16_t weight)
 3271: {
 3272:   struct peer_group *group;
 3273:   struct listnode *node, *nnode;
 3274: 
 3275:   SET_FLAG (peer->config, PEER_CONFIG_WEIGHT);
 3276:   peer->weight = weight;
 3277: 
 3278:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3279:     return 0;
 3280: 
 3281:   /* peer-group member updates. */
 3282:   group = peer->group;
 3283:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 3284:     {
 3285:       peer->weight = group->conf->weight;
 3286:     }
 3287:   return 0;
 3288: }
 3289: 
 3290: int
 3291: peer_weight_unset (struct peer *peer)
 3292: {
 3293:   struct peer_group *group;
 3294:   struct listnode *node, *nnode;
 3295: 
 3296:   /* Set default weight. */
 3297:   if (peer_group_active (peer))
 3298:     peer->weight = peer->group->conf->weight;
 3299:   else
 3300:     peer->weight = 0;
 3301: 
 3302:   UNSET_FLAG (peer->config, PEER_CONFIG_WEIGHT);
 3303: 
 3304:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3305:     return 0;
 3306: 
 3307:   /* peer-group member updates. */
 3308:   group = peer->group;
 3309:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 3310:     {
 3311:       peer->weight = 0;
 3312:     }
 3313:   return 0;
 3314: }
 3315: 
 3316: int
 3317: peer_timers_set (struct peer *peer, u_int32_t keepalive, u_int32_t holdtime)
 3318: {
 3319:   struct peer_group *group;
 3320:   struct listnode *node, *nnode;
 3321: 
 3322:   /* Not for peer group memeber.  */
 3323:   if (peer_group_active (peer))
 3324:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 3325: 
 3326:   /* keepalive value check.  */
 3327:   if (keepalive > 65535)
 3328:     return BGP_ERR_INVALID_VALUE;
 3329: 
 3330:   /* Holdtime value check.  */
 3331:   if (holdtime > 65535)
 3332:     return BGP_ERR_INVALID_VALUE;
 3333: 
 3334:   /* Holdtime value must be either 0 or greater than 3.  */
 3335:   if (holdtime < 3 && holdtime != 0)
 3336:     return BGP_ERR_INVALID_VALUE;
 3337: 
 3338:   /* Set value to the configuration. */
 3339:   SET_FLAG (peer->config, PEER_CONFIG_TIMER);
 3340:   peer->holdtime = holdtime;
 3341:   peer->keepalive = (keepalive < holdtime / 3 ? keepalive : holdtime / 3);
 3342: 
 3343:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3344:     return 0;
 3345: 
 3346:   /* peer-group member updates. */
 3347:   group = peer->group;
 3348:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 3349:     {
 3350:       SET_FLAG (peer->config, PEER_CONFIG_TIMER);
 3351:       peer->holdtime = group->conf->holdtime;
 3352:       peer->keepalive = group->conf->keepalive;
 3353:     }
 3354:   return 0;
 3355: }
 3356: 
 3357: int
 3358: peer_timers_unset (struct peer *peer)
 3359: {
 3360:   struct peer_group *group;
 3361:   struct listnode *node, *nnode;
 3362: 
 3363:   if (peer_group_active (peer))
 3364:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 3365: 
 3366:   /* Clear configuration. */
 3367:   UNSET_FLAG (peer->config, PEER_CONFIG_TIMER);
 3368:   peer->keepalive = 0;
 3369:   peer->holdtime = 0;
 3370: 
 3371:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3372:     return 0;
 3373: 
 3374:   /* peer-group member updates. */
 3375:   group = peer->group;
 3376:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 3377:     {
 3378:       UNSET_FLAG (peer->config, PEER_CONFIG_TIMER);
 3379:       peer->holdtime = 0;
 3380:       peer->keepalive = 0;
 3381:     }
 3382: 
 3383:   return 0;
 3384: }
 3385: 
 3386: int
 3387: peer_timers_connect_set (struct peer *peer, u_int32_t connect)
 3388: {
 3389:   struct peer_group *group;
 3390:   struct listnode *node, *nnode;
 3391: 
 3392:   if (peer_group_active (peer))
 3393:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 3394: 
 3395:   if (connect > 65535)
 3396:     return BGP_ERR_INVALID_VALUE;
 3397: 
 3398:   /* Set value to the configuration. */
 3399:   SET_FLAG (peer->config, PEER_CONFIG_CONNECT);
 3400:   peer->connect = connect;
 3401: 
 3402:   /* Set value to timer setting. */
 3403:   peer->v_connect = connect;
 3404: 
 3405:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3406:     return 0;
 3407: 
 3408:   /* peer-group member updates. */
 3409:   group = peer->group;
 3410:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 3411:     {
 3412:       SET_FLAG (peer->config, PEER_CONFIG_CONNECT);
 3413:       peer->connect = connect;
 3414:       peer->v_connect = connect;
 3415:     }
 3416:   return 0;
 3417: }
 3418: 
 3419: int
 3420: peer_timers_connect_unset (struct peer *peer)
 3421: {
 3422:   struct peer_group *group;
 3423:   struct listnode *node, *nnode;
 3424: 
 3425:   if (peer_group_active (peer))
 3426:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 3427: 
 3428:   /* Clear configuration. */
 3429:   UNSET_FLAG (peer->config, PEER_CONFIG_CONNECT);
 3430:   peer->connect = 0;
 3431: 
 3432:   /* Set timer setting to default value. */
 3433:   peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
 3434: 
 3435:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3436:     return 0;
 3437: 
 3438:   /* peer-group member updates. */
 3439:   group = peer->group;
 3440:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 3441:     {
 3442:       UNSET_FLAG (peer->config, PEER_CONFIG_CONNECT);
 3443:       peer->connect = 0;
 3444:       peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
 3445:     }
 3446:    return 0;
 3447: }
 3448: 
 3449: int
 3450: peer_advertise_interval_set (struct peer *peer, u_int32_t routeadv)
 3451: {
 3452:   struct peer_group *group;
 3453:   struct listnode *node, *nnode;
 3454: 
 3455:   if (peer_group_active (peer))
 3456:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 3457: 
 3458:   if (routeadv > 600)
 3459:     return BGP_ERR_INVALID_VALUE;
 3460: 
 3461:   SET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
 3462:   peer->routeadv = routeadv;
 3463:   peer->v_routeadv = routeadv;
 3464: 
 3465:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3466:     return 0;
 3467: 
 3468:   /* peer-group member updates. */
 3469:   group = peer->group;
 3470:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 3471:     {
 3472:       SET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
 3473:       peer->routeadv = routeadv;
 3474:       peer->v_routeadv = routeadv;
 3475:     }
 3476: 
 3477:   return 0;
 3478: }
 3479: 
 3480: int
 3481: peer_advertise_interval_unset (struct peer *peer)
 3482: {
 3483:   struct peer_group *group;
 3484:   struct listnode *node, *nnode;
 3485: 
 3486:   if (peer_group_active (peer))
 3487:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 3488: 
 3489:   UNSET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
 3490:   peer->routeadv = 0;
 3491: 
 3492:   if (peer->sort == BGP_PEER_IBGP)
 3493:     peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
 3494:   else
 3495:     peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
 3496: 
 3497:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3498:     return 0;
 3499: 
 3500:   /* peer-group member updates. */
 3501:   group = peer->group;
 3502:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 3503:     {
 3504:       UNSET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
 3505:       peer->routeadv = 0;
 3506: 
 3507:       if (peer->sort == BGP_PEER_IBGP)
 3508:         peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
 3509:       else
 3510:         peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
 3511:     }
 3512:   
 3513:   return 0;
 3514: }
 3515: 
 3516: /* neighbor interface */
 3517: int
 3518: peer_interface_set (struct peer *peer, const char *str)
 3519: {
 3520:   if (peer->ifname)
 3521:     free (peer->ifname);
 3522:   peer->ifname = strdup (str);
 3523: 
 3524:   return 0;
 3525: }
 3526: 
 3527: int
 3528: peer_interface_unset (struct peer *peer)
 3529: {
 3530:   if (peer->ifname)
 3531:     free (peer->ifname);
 3532:   peer->ifname = NULL;
 3533: 
 3534:   return 0;
 3535: }
 3536: 
 3537: /* Allow-as in.  */
 3538: int
 3539: peer_allowas_in_set (struct peer *peer, afi_t afi, safi_t safi, int allow_num)
 3540: {
 3541:   struct peer_group *group;
 3542:   struct listnode *node, *nnode;
 3543: 
 3544:   if (allow_num < 1 || allow_num > 10)
 3545:     return BGP_ERR_INVALID_VALUE;
 3546: 
 3547:   if (peer->allowas_in[afi][safi] != allow_num)
 3548:     {
 3549:       peer->allowas_in[afi][safi] = allow_num;
 3550:       SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN);
 3551:       peer_change_action (peer, afi, safi, peer_change_reset_in);
 3552:     }
 3553: 
 3554:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3555:     return 0;
 3556: 
 3557:   group = peer->group;
 3558:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 3559:     {
 3560:       if (peer->allowas_in[afi][safi] != allow_num)
 3561: 	{
 3562: 	  peer->allowas_in[afi][safi] = allow_num;
 3563: 	  SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN);
 3564: 	  peer_change_action (peer, afi, safi, peer_change_reset_in);
 3565: 	}
 3566: 	  
 3567:     }
 3568:   return 0;
 3569: }
 3570: 
 3571: int
 3572: peer_allowas_in_unset (struct peer *peer, afi_t afi, safi_t safi)
 3573: {
 3574:   struct peer_group *group;
 3575:   struct listnode *node, *nnode;
 3576: 
 3577:   if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
 3578:     {
 3579:       peer->allowas_in[afi][safi] = 0;
 3580:       peer_af_flag_unset (peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
 3581:     }
 3582: 
 3583:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3584:     return 0;
 3585: 
 3586:   group = peer->group;
 3587:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 3588:     {
 3589:       if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
 3590: 	{
 3591: 	  peer->allowas_in[afi][safi] = 0;
 3592: 	  peer_af_flag_unset (peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
 3593: 	}
 3594:     }
 3595:   return 0;
 3596: }
 3597: 
 3598: int
 3599: peer_local_as_set (struct peer *peer, as_t as, int no_prepend, int replace_as)
 3600: {
 3601:   struct bgp *bgp = peer->bgp;
 3602:   struct peer_group *group;
 3603:   struct listnode *node, *nnode;
 3604: 
 3605:   if (peer_sort (peer) != BGP_PEER_EBGP
 3606:       && peer_sort (peer) != BGP_PEER_INTERNAL)
 3607:     return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP;
 3608: 
 3609:   if (bgp->as == as)
 3610:     return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS;
 3611: 
 3612:   if (peer_group_active (peer))
 3613:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 3614: 
 3615:   if (peer->as == as)
 3616:     return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS_REMOTE_AS;
 3617: 
 3618:   if (peer->change_local_as == as &&
 3619:       ((CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) && no_prepend)
 3620:        || (! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) && ! no_prepend)) &&
 3621:       ((CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) && replace_as)
 3622:        || (! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) && ! replace_as)))
 3623:     return 0;
 3624: 
 3625:   peer->change_local_as = as;
 3626:   if (no_prepend)
 3627:     SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
 3628:   else
 3629:     UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
 3630: 
 3631:   if (replace_as)
 3632:     SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
 3633:   else
 3634:     UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
 3635: 
 3636:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3637:     {
 3638:       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
 3639:        {
 3640:          peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
 3641:          bgp_notify_send (peer, BGP_NOTIFY_CEASE,
 3642:                           BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 3643:        }
 3644:       else
 3645:         BGP_EVENT_ADD (peer, BGP_Stop);
 3646: 
 3647:       return 0;
 3648:     }
 3649: 
 3650:   group = peer->group;
 3651:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 3652:     {
 3653:       peer->change_local_as = as;
 3654:       if (no_prepend)
 3655: 	SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
 3656:       else
 3657: 	UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
 3658: 
 3659:       if (replace_as)
 3660:         SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
 3661:       else
 3662:         UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
 3663: 
 3664:       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
 3665:        {
 3666:          peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
 3667:          bgp_notify_send (peer, BGP_NOTIFY_CEASE,
 3668:                           BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 3669:        }
 3670:       else
 3671:         BGP_EVENT_ADD (peer, BGP_Stop);
 3672:     }
 3673: 
 3674:   return 0;
 3675: }
 3676: 
 3677: int
 3678: peer_local_as_unset (struct peer *peer)
 3679: {
 3680:   struct peer_group *group;
 3681:   struct listnode *node, *nnode;
 3682: 
 3683:   if (peer_group_active (peer))
 3684:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 3685: 
 3686:   if (! peer->change_local_as)
 3687:     return 0;
 3688: 
 3689:   peer->change_local_as = 0;
 3690:   UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
 3691:   UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
 3692: 
 3693:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3694:     {
 3695:       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
 3696:        {
 3697:          peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
 3698:          bgp_notify_send (peer, BGP_NOTIFY_CEASE,
 3699:                           BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 3700:        }
 3701:       else
 3702:         BGP_EVENT_ADD (peer, BGP_Stop);
 3703: 
 3704:       return 0;
 3705:     }
 3706: 
 3707:   group = peer->group;
 3708:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 3709:     {
 3710:       peer->change_local_as = 0;
 3711:       UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
 3712:       UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS);
 3713: 
 3714:       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
 3715:        {
 3716:          peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
 3717:          bgp_notify_send (peer, BGP_NOTIFY_CEASE,
 3718:                           BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 3719:        }
 3720:       else
 3721:         BGP_EVENT_ADD (peer, BGP_Stop);
 3722:     }
 3723:   return 0;
 3724: }
 3725: 
 3726: /* Set password for authenticating with the peer. */
 3727: int
 3728: peer_password_set (struct peer *peer, const char *password)
 3729: {
 3730:   struct listnode *nn, *nnode;
 3731:   int len = password ? strlen(password) : 0;
 3732:   int ret = BGP_SUCCESS;
 3733: 
 3734:   if ((len < PEER_PASSWORD_MINLEN) || (len > PEER_PASSWORD_MAXLEN))
 3735:     return BGP_ERR_INVALID_VALUE;
 3736: 
 3737:   if (peer->password && strcmp (peer->password, password) == 0
 3738:       && ! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3739:     return 0;
 3740: 
 3741:   if (peer->password)
 3742:     XFREE (MTYPE_PEER_PASSWORD, peer->password);
 3743:   
 3744:   peer->password = XSTRDUP (MTYPE_PEER_PASSWORD, password);
 3745: 
 3746:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3747:     {
 3748:       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
 3749:         bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 3750:       else
 3751:         BGP_EVENT_ADD (peer, BGP_Stop);
 3752:         
 3753:       return (bgp_md5_set (peer) >= 0) ? BGP_SUCCESS : BGP_ERR_TCPSIG_FAILED;
 3754:     }
 3755: 
 3756:   for (ALL_LIST_ELEMENTS (peer->group->peer, nn, nnode, peer))
 3757:     {
 3758:       if (peer->password && strcmp (peer->password, password) == 0)
 3759: 	continue;
 3760:       
 3761:       if (peer->password)
 3762:         XFREE (MTYPE_PEER_PASSWORD, peer->password);
 3763:       
 3764:       peer->password = XSTRDUP(MTYPE_PEER_PASSWORD, password);
 3765: 
 3766:       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
 3767:         bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 3768:       else
 3769:         BGP_EVENT_ADD (peer, BGP_Stop);
 3770:       
 3771:       if (bgp_md5_set (peer) < 0)
 3772:         ret = BGP_ERR_TCPSIG_FAILED;
 3773:     }
 3774: 
 3775:   return ret;
 3776: }
 3777: 
 3778: int
 3779: peer_password_unset (struct peer *peer)
 3780: {
 3781:   struct listnode *nn, *nnode;
 3782: 
 3783:   if (!peer->password
 3784:       && !CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3785:     return 0;
 3786: 
 3787:   if (!CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3788:     {
 3789:       if (peer_group_active (peer)
 3790: 	  && peer->group->conf->password
 3791: 	  && strcmp (peer->group->conf->password, peer->password) == 0)
 3792: 	return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
 3793: 
 3794:       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
 3795:         bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 3796:       else
 3797:         BGP_EVENT_ADD (peer, BGP_Stop);
 3798: 
 3799:       if (peer->password)
 3800:         XFREE (MTYPE_PEER_PASSWORD, peer->password);
 3801:       
 3802:       peer->password = NULL;
 3803:       
 3804:       bgp_md5_set (peer);
 3805: 
 3806:       return 0;
 3807:     }
 3808: 
 3809:   XFREE (MTYPE_PEER_PASSWORD, peer->password);
 3810:   peer->password = NULL;
 3811: 
 3812:   for (ALL_LIST_ELEMENTS (peer->group->peer, nn, nnode, peer))
 3813:     {
 3814:       if (!peer->password)
 3815: 	continue;
 3816: 
 3817:       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
 3818:         bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
 3819:       else
 3820:         BGP_EVENT_ADD (peer, BGP_Stop);
 3821:       
 3822:       XFREE (MTYPE_PEER_PASSWORD, peer->password);
 3823:       peer->password = NULL;
 3824: 
 3825:       bgp_md5_set (peer);
 3826:     }
 3827: 
 3828:   return 0;
 3829: }
 3830: 
 3831: /* Set distribute list to the peer. */
 3832: int
 3833: peer_distribute_set (struct peer *peer, afi_t afi, safi_t safi, int direct, 
 3834: 		     const char *name)
 3835: {
 3836:   struct bgp_filter *filter;
 3837:   struct peer_group *group;
 3838:   struct listnode *node, *nnode;
 3839: 
 3840:   if (! peer->afc[afi][safi])
 3841:     return BGP_ERR_PEER_INACTIVE;
 3842: 
 3843:   if (direct != FILTER_IN && direct != FILTER_OUT)
 3844:     return BGP_ERR_INVALID_VALUE;
 3845: 
 3846:   if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
 3847:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 3848: 
 3849:   filter = &peer->filter[afi][safi];
 3850: 
 3851:   if (filter->plist[direct].name)
 3852:     return BGP_ERR_PEER_FILTER_CONFLICT;
 3853: 
 3854:   if (filter->dlist[direct].name)
 3855:     free (filter->dlist[direct].name);
 3856:   filter->dlist[direct].name = strdup (name);
 3857:   filter->dlist[direct].alist = access_list_lookup (afi, name);
 3858: 
 3859:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3860:     return 0;
 3861: 
 3862:   group = peer->group;
 3863:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 3864:     {
 3865:       filter = &peer->filter[afi][safi];
 3866: 
 3867:       if (! peer->af_group[afi][safi])
 3868: 	continue;
 3869: 
 3870:       if (filter->dlist[direct].name)
 3871: 	free (filter->dlist[direct].name);
 3872:       filter->dlist[direct].name = strdup (name);
 3873:       filter->dlist[direct].alist = access_list_lookup (afi, name);
 3874:     }
 3875: 
 3876:   return 0;
 3877: }
 3878: 
 3879: int
 3880: peer_distribute_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
 3881: {
 3882:   struct bgp_filter *filter;
 3883:   struct bgp_filter *gfilter;
 3884:   struct peer_group *group;
 3885:   struct listnode *node, *nnode;
 3886: 
 3887:   if (! peer->afc[afi][safi])
 3888:     return BGP_ERR_PEER_INACTIVE;
 3889: 
 3890:   if (direct != FILTER_IN && direct != FILTER_OUT)
 3891:     return BGP_ERR_INVALID_VALUE;
 3892: 
 3893:   if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
 3894:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 3895: 
 3896:   filter = &peer->filter[afi][safi];
 3897: 
 3898:   /* apply peer-group filter */
 3899:   if (peer->af_group[afi][safi])
 3900:     {
 3901:       gfilter = &peer->group->conf->filter[afi][safi];
 3902: 
 3903:       if (gfilter->dlist[direct].name)
 3904: 	{
 3905: 	  if (filter->dlist[direct].name)
 3906: 	    free (filter->dlist[direct].name);
 3907: 	  filter->dlist[direct].name = strdup (gfilter->dlist[direct].name);
 3908: 	  filter->dlist[direct].alist = gfilter->dlist[direct].alist;
 3909: 	  return 0;
 3910: 	}
 3911:     }
 3912: 
 3913:   if (filter->dlist[direct].name)
 3914:     free (filter->dlist[direct].name);
 3915:   filter->dlist[direct].name = NULL;
 3916:   filter->dlist[direct].alist = NULL;
 3917: 
 3918:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 3919:     return 0;
 3920: 
 3921:     group = peer->group;
 3922:     for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 3923:       {
 3924: 	filter = &peer->filter[afi][safi];
 3925: 
 3926: 	if (! peer->af_group[afi][safi])
 3927: 	  continue;
 3928: 
 3929: 	if (filter->dlist[direct].name)
 3930: 	  free (filter->dlist[direct].name);
 3931: 	filter->dlist[direct].name = NULL;
 3932: 	filter->dlist[direct].alist = NULL;
 3933:       }
 3934: 
 3935:   return 0;
 3936: }
 3937: 
 3938: /* Update distribute list. */
 3939: static void
 3940: peer_distribute_update (struct access_list *access)
 3941: {
 3942:   afi_t afi;
 3943:   safi_t safi;
 3944:   int direct;
 3945:   struct listnode *mnode, *mnnode;
 3946:   struct listnode *node, *nnode;
 3947:   struct bgp *bgp;
 3948:   struct peer *peer;
 3949:   struct peer_group *group;
 3950:   struct bgp_filter *filter;
 3951: 
 3952:   for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
 3953:     {
 3954:       for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
 3955: 	{
 3956: 	  for (afi = AFI_IP; afi < AFI_MAX; afi++)
 3957: 	    for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
 3958: 	      {
 3959: 		filter = &peer->filter[afi][safi];
 3960: 
 3961: 		for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
 3962: 		  {
 3963: 		    if (filter->dlist[direct].name)
 3964: 		      filter->dlist[direct].alist = 
 3965: 			access_list_lookup (afi, filter->dlist[direct].name);
 3966: 		    else
 3967: 		      filter->dlist[direct].alist = NULL;
 3968: 		  }
 3969: 	      }
 3970: 	}
 3971:       for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
 3972: 	{
 3973: 	  for (afi = AFI_IP; afi < AFI_MAX; afi++)
 3974: 	    for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
 3975: 	      {
 3976: 		filter = &group->conf->filter[afi][safi];
 3977: 
 3978: 		for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
 3979: 		  {
 3980: 		    if (filter->dlist[direct].name)
 3981: 		      filter->dlist[direct].alist = 
 3982: 			access_list_lookup (afi, filter->dlist[direct].name);
 3983: 		    else
 3984: 		      filter->dlist[direct].alist = NULL;
 3985: 		  }
 3986: 	      }
 3987: 	}
 3988:     }
 3989: }
 3990: 
 3991: /* Set prefix list to the peer. */
 3992: int
 3993: peer_prefix_list_set (struct peer *peer, afi_t afi, safi_t safi, int direct, 
 3994: 		      const char *name)
 3995: {
 3996:   struct bgp_filter *filter;
 3997:   struct peer_group *group;
 3998:   struct listnode *node, *nnode;
 3999: 
 4000:   if (! peer->afc[afi][safi])
 4001:     return BGP_ERR_PEER_INACTIVE;
 4002: 
 4003:   if (direct != FILTER_IN && direct != FILTER_OUT)
 4004:     return BGP_ERR_INVALID_VALUE;
 4005: 
 4006:   if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
 4007:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 4008: 
 4009:   filter = &peer->filter[afi][safi];
 4010: 
 4011:   if (filter->dlist[direct].name)
 4012:     return BGP_ERR_PEER_FILTER_CONFLICT;
 4013: 
 4014:   if (filter->plist[direct].name)
 4015:     free (filter->plist[direct].name);
 4016:   filter->plist[direct].name = strdup (name);
 4017:   filter->plist[direct].plist = prefix_list_lookup (afi, name);
 4018: 
 4019:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 4020:     return 0;
 4021: 
 4022:   group = peer->group;
 4023:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 4024:     {
 4025:       filter = &peer->filter[afi][safi];
 4026: 
 4027:       if (! peer->af_group[afi][safi])
 4028: 	continue;
 4029: 
 4030:       if (filter->plist[direct].name)
 4031: 	free (filter->plist[direct].name);
 4032:       filter->plist[direct].name = strdup (name);
 4033:       filter->plist[direct].plist = prefix_list_lookup (afi, name);
 4034:     }
 4035:   return 0;
 4036: }
 4037: 
 4038: int
 4039: peer_prefix_list_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
 4040: {
 4041:   struct bgp_filter *filter;
 4042:   struct bgp_filter *gfilter;
 4043:   struct peer_group *group;
 4044:   struct listnode *node, *nnode;
 4045: 
 4046:   if (! peer->afc[afi][safi])
 4047:     return BGP_ERR_PEER_INACTIVE;
 4048: 
 4049:   if (direct != FILTER_IN && direct != FILTER_OUT)
 4050:     return BGP_ERR_INVALID_VALUE;
 4051: 
 4052:   if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
 4053:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 4054: 
 4055:   filter = &peer->filter[afi][safi];
 4056: 
 4057:   /* apply peer-group filter */
 4058:   if (peer->af_group[afi][safi])
 4059:     {
 4060:       gfilter = &peer->group->conf->filter[afi][safi];
 4061: 
 4062:       if (gfilter->plist[direct].name)
 4063: 	{
 4064: 	  if (filter->plist[direct].name)
 4065: 	    free (filter->plist[direct].name);
 4066: 	  filter->plist[direct].name = strdup (gfilter->plist[direct].name);
 4067: 	  filter->plist[direct].plist = gfilter->plist[direct].plist;
 4068: 	  return 0;
 4069: 	}
 4070:     }
 4071: 
 4072:   if (filter->plist[direct].name)
 4073:     free (filter->plist[direct].name);
 4074:   filter->plist[direct].name = NULL;
 4075:   filter->plist[direct].plist = NULL;
 4076: 
 4077:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 4078:     return 0;
 4079: 
 4080:   group = peer->group;
 4081:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 4082:     {
 4083:       filter = &peer->filter[afi][safi];
 4084: 
 4085:       if (! peer->af_group[afi][safi])
 4086: 	continue;
 4087: 
 4088:       if (filter->plist[direct].name)
 4089: 	free (filter->plist[direct].name);
 4090:       filter->plist[direct].name = NULL;
 4091:       filter->plist[direct].plist = NULL;
 4092:     }
 4093: 
 4094:   return 0;
 4095: }
 4096: 
 4097: /* Update prefix-list list. */
 4098: static void
 4099: peer_prefix_list_update (struct prefix_list *plist)
 4100: {
 4101:   struct listnode *mnode, *mnnode;
 4102:   struct listnode *node, *nnode;
 4103:   struct bgp *bgp;
 4104:   struct peer *peer;
 4105:   struct peer_group *group;
 4106:   struct bgp_filter *filter;
 4107:   afi_t afi;
 4108:   safi_t safi;
 4109:   int direct;
 4110: 
 4111:   for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
 4112:     {
 4113:       for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
 4114: 	{
 4115: 	  for (afi = AFI_IP; afi < AFI_MAX; afi++)
 4116: 	    for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
 4117: 	      {
 4118: 		filter = &peer->filter[afi][safi];
 4119: 
 4120: 		for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
 4121: 		  {
 4122: 		    if (filter->plist[direct].name)
 4123: 		      filter->plist[direct].plist = 
 4124: 			prefix_list_lookup (afi, filter->plist[direct].name);
 4125: 		    else
 4126: 		      filter->plist[direct].plist = NULL;
 4127: 		  }
 4128: 	      }
 4129: 	}
 4130:       for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
 4131: 	{
 4132: 	  for (afi = AFI_IP; afi < AFI_MAX; afi++)
 4133: 	    for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
 4134: 	      {
 4135: 		filter = &group->conf->filter[afi][safi];
 4136: 
 4137: 		for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
 4138: 		  {
 4139: 		    if (filter->plist[direct].name)
 4140: 		      filter->plist[direct].plist = 
 4141: 			prefix_list_lookup (afi, filter->plist[direct].name);
 4142: 		    else
 4143: 		      filter->plist[direct].plist = NULL;
 4144: 		  }
 4145: 	      }
 4146: 	}
 4147:     }
 4148: }
 4149: 
 4150: int
 4151: peer_aslist_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
 4152: 		 const char *name)
 4153: {
 4154:   struct bgp_filter *filter;
 4155:   struct peer_group *group;
 4156:   struct listnode *node, *nnode;
 4157: 
 4158:   if (! peer->afc[afi][safi])
 4159:     return BGP_ERR_PEER_INACTIVE;
 4160: 
 4161:   if (direct != FILTER_IN && direct != FILTER_OUT)
 4162:     return BGP_ERR_INVALID_VALUE;
 4163: 
 4164:   if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
 4165:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 4166: 
 4167:   filter = &peer->filter[afi][safi];
 4168: 
 4169:   if (filter->aslist[direct].name)
 4170:     free (filter->aslist[direct].name);
 4171:   filter->aslist[direct].name = strdup (name);
 4172:   filter->aslist[direct].aslist = as_list_lookup (name);
 4173: 
 4174:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 4175:     return 0;
 4176: 
 4177:   group = peer->group;
 4178:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 4179:     {
 4180:       filter = &peer->filter[afi][safi];
 4181: 
 4182:       if (! peer->af_group[afi][safi])
 4183: 	continue;
 4184: 
 4185:       if (filter->aslist[direct].name)
 4186: 	free (filter->aslist[direct].name);
 4187:       filter->aslist[direct].name = strdup (name);
 4188:       filter->aslist[direct].aslist = as_list_lookup (name);
 4189:     }
 4190:   return 0;
 4191: }
 4192: 
 4193: int
 4194: peer_aslist_unset (struct peer *peer,afi_t afi, safi_t safi, int direct)
 4195: {
 4196:   struct bgp_filter *filter;
 4197:   struct bgp_filter *gfilter;
 4198:   struct peer_group *group;
 4199:   struct listnode *node, *nnode;
 4200: 
 4201:   if (! peer->afc[afi][safi])
 4202:     return BGP_ERR_PEER_INACTIVE;
 4203: 
 4204:   if (direct != FILTER_IN && direct != FILTER_OUT)
 4205:     return BGP_ERR_INVALID_VALUE;
 4206: 
 4207:   if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
 4208:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 4209: 
 4210:   filter = &peer->filter[afi][safi];
 4211: 
 4212:   /* apply peer-group filter */
 4213:   if (peer->af_group[afi][safi])
 4214:     {
 4215:       gfilter = &peer->group->conf->filter[afi][safi];
 4216: 
 4217:       if (gfilter->aslist[direct].name)
 4218: 	{
 4219: 	  if (filter->aslist[direct].name)
 4220: 	    free (filter->aslist[direct].name);
 4221: 	  filter->aslist[direct].name = strdup (gfilter->aslist[direct].name);
 4222: 	  filter->aslist[direct].aslist = gfilter->aslist[direct].aslist;
 4223: 	  return 0;
 4224: 	}
 4225:     }
 4226: 
 4227:   if (filter->aslist[direct].name)
 4228:     free (filter->aslist[direct].name);
 4229:   filter->aslist[direct].name = NULL;
 4230:   filter->aslist[direct].aslist = NULL;
 4231: 
 4232:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 4233:     return 0;
 4234: 
 4235:   group = peer->group;
 4236:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 4237:     {
 4238:       filter = &peer->filter[afi][safi];
 4239: 
 4240:       if (! peer->af_group[afi][safi])
 4241: 	continue;
 4242: 
 4243:       if (filter->aslist[direct].name)
 4244: 	free (filter->aslist[direct].name);
 4245:       filter->aslist[direct].name = NULL;
 4246:       filter->aslist[direct].aslist = NULL;
 4247:     }
 4248: 
 4249:   return 0;
 4250: }
 4251: 
 4252: static void
 4253: peer_aslist_update (void)
 4254: {
 4255:   afi_t afi;
 4256:   safi_t safi;
 4257:   int direct;
 4258:   struct listnode *mnode, *mnnode;
 4259:   struct listnode *node, *nnode;
 4260:   struct bgp *bgp;
 4261:   struct peer *peer;
 4262:   struct peer_group *group;
 4263:   struct bgp_filter *filter;
 4264: 
 4265:   for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
 4266:     {
 4267:       for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
 4268: 	{
 4269: 	  for (afi = AFI_IP; afi < AFI_MAX; afi++)
 4270: 	    for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
 4271: 	      {
 4272: 		filter = &peer->filter[afi][safi];
 4273: 
 4274: 		for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
 4275: 		  {
 4276: 		    if (filter->aslist[direct].name)
 4277: 		      filter->aslist[direct].aslist = 
 4278: 			as_list_lookup (filter->aslist[direct].name);
 4279: 		    else
 4280: 		      filter->aslist[direct].aslist = NULL;
 4281: 		  }
 4282: 	      }
 4283: 	}
 4284:       for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
 4285: 	{
 4286: 	  for (afi = AFI_IP; afi < AFI_MAX; afi++)
 4287: 	    for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
 4288: 	      {
 4289: 		filter = &group->conf->filter[afi][safi];
 4290: 
 4291: 		for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
 4292: 		  {
 4293: 		    if (filter->aslist[direct].name)
 4294: 		      filter->aslist[direct].aslist = 
 4295: 			as_list_lookup (filter->aslist[direct].name);
 4296: 		    else
 4297: 		      filter->aslist[direct].aslist = NULL;
 4298: 		  }
 4299: 	      }
 4300: 	}
 4301:     }
 4302: }
 4303: 
 4304: /* Set route-map to the peer. */
 4305: int
 4306: peer_route_map_set (struct peer *peer, afi_t afi, safi_t safi, int direct, 
 4307: 		    const char *name)
 4308: {
 4309:   struct bgp_filter *filter;
 4310:   struct peer_group *group;
 4311:   struct listnode *node, *nnode;
 4312: 
 4313:   if (! peer->afc[afi][safi])
 4314:     return BGP_ERR_PEER_INACTIVE;
 4315: 
 4316:   if (direct != RMAP_IN && direct != RMAP_OUT &&
 4317:       direct != RMAP_IMPORT && direct != RMAP_EXPORT)
 4318:     return BGP_ERR_INVALID_VALUE;
 4319: 
 4320:   if ( (direct == RMAP_OUT || direct == RMAP_IMPORT)
 4321:       && peer_is_group_member (peer, afi, safi))
 4322:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 4323: 
 4324:   filter = &peer->filter[afi][safi];
 4325: 
 4326:   if (filter->map[direct].name)
 4327:     free (filter->map[direct].name);
 4328:   
 4329:   filter->map[direct].name = strdup (name);
 4330:   filter->map[direct].map = route_map_lookup_by_name (name);
 4331: 
 4332:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 4333:     return 0;
 4334: 
 4335:   group = peer->group;
 4336:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 4337:     {
 4338:       filter = &peer->filter[afi][safi];
 4339: 
 4340:       if (! peer->af_group[afi][safi])
 4341: 	continue;
 4342: 
 4343:       if (filter->map[direct].name)
 4344: 	free (filter->map[direct].name);
 4345:       filter->map[direct].name = strdup (name);
 4346:       filter->map[direct].map = route_map_lookup_by_name (name);
 4347:     }
 4348:   return 0;
 4349: }
 4350: 
 4351: /* Unset route-map from the peer. */
 4352: int
 4353: peer_route_map_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
 4354: {
 4355:   struct bgp_filter *filter;
 4356:   struct bgp_filter *gfilter;
 4357:   struct peer_group *group;
 4358:   struct listnode *node, *nnode;
 4359: 
 4360:   if (! peer->afc[afi][safi])
 4361:     return BGP_ERR_PEER_INACTIVE;
 4362: 
 4363:   if (direct != RMAP_IN && direct != RMAP_OUT &&
 4364:       direct != RMAP_IMPORT && direct != RMAP_EXPORT)
 4365:     return BGP_ERR_INVALID_VALUE;
 4366: 
 4367:   if ( (direct == RMAP_OUT || direct == RMAP_IMPORT)
 4368:       && peer_is_group_member (peer, afi, safi))
 4369:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 4370: 
 4371:   filter = &peer->filter[afi][safi];
 4372: 
 4373:   /* apply peer-group filter */
 4374:   if (peer->af_group[afi][safi])
 4375:     {
 4376:       gfilter = &peer->group->conf->filter[afi][safi];
 4377: 
 4378:       if (gfilter->map[direct].name)
 4379: 	{
 4380: 	  if (filter->map[direct].name)
 4381: 	    free (filter->map[direct].name);
 4382: 	  filter->map[direct].name = strdup (gfilter->map[direct].name);
 4383: 	  filter->map[direct].map = gfilter->map[direct].map;
 4384: 	  return 0;
 4385: 	}
 4386:     }
 4387: 
 4388:   if (filter->map[direct].name)
 4389:     free (filter->map[direct].name);
 4390:   filter->map[direct].name = NULL;
 4391:   filter->map[direct].map = NULL;
 4392: 
 4393:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 4394:     return 0;
 4395: 
 4396:   group = peer->group;
 4397:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 4398:     {
 4399:       filter = &peer->filter[afi][safi];
 4400: 
 4401:       if (! peer->af_group[afi][safi])
 4402: 	continue;
 4403: 
 4404:       if (filter->map[direct].name)
 4405: 	free (filter->map[direct].name);
 4406:       filter->map[direct].name = NULL;
 4407:       filter->map[direct].map = NULL;
 4408:     }
 4409:   return 0;
 4410: }
 4411: 
 4412: /* Set unsuppress-map to the peer. */
 4413: int
 4414: peer_unsuppress_map_set (struct peer *peer, afi_t afi, safi_t safi, 
 4415:                          const char *name)
 4416: {
 4417:   struct bgp_filter *filter;
 4418:   struct peer_group *group;
 4419:   struct listnode *node, *nnode;
 4420: 
 4421:   if (! peer->afc[afi][safi])
 4422:     return BGP_ERR_PEER_INACTIVE;
 4423: 
 4424:   if (peer_is_group_member (peer, afi, safi))
 4425:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 4426:       
 4427:   filter = &peer->filter[afi][safi];
 4428: 
 4429:   if (filter->usmap.name)
 4430:     free (filter->usmap.name);
 4431:   
 4432:   filter->usmap.name = strdup (name);
 4433:   filter->usmap.map = route_map_lookup_by_name (name);
 4434: 
 4435:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 4436:     return 0;
 4437: 
 4438:   group = peer->group;
 4439:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 4440:     {
 4441:       filter = &peer->filter[afi][safi];
 4442: 
 4443:       if (! peer->af_group[afi][safi])
 4444: 	continue;
 4445: 
 4446:       if (filter->usmap.name)
 4447: 	free (filter->usmap.name);
 4448:       filter->usmap.name = strdup (name);
 4449:       filter->usmap.map = route_map_lookup_by_name (name);
 4450:     }
 4451:   return 0;
 4452: }
 4453: 
 4454: /* Unset route-map from the peer. */
 4455: int
 4456: peer_unsuppress_map_unset (struct peer *peer, afi_t afi, safi_t safi)
 4457: {
 4458:   struct bgp_filter *filter;
 4459:   struct peer_group *group;
 4460:   struct listnode *node, *nnode;
 4461: 
 4462:   if (! peer->afc[afi][safi])
 4463:     return BGP_ERR_PEER_INACTIVE;
 4464:   
 4465:   if (peer_is_group_member (peer, afi, safi))
 4466:     return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
 4467: 
 4468:   filter = &peer->filter[afi][safi];
 4469: 
 4470:   if (filter->usmap.name)
 4471:     free (filter->usmap.name);
 4472:   filter->usmap.name = NULL;
 4473:   filter->usmap.map = NULL;
 4474: 
 4475:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 4476:     return 0;
 4477: 
 4478:   group = peer->group;
 4479:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 4480:     {
 4481:       filter = &peer->filter[afi][safi];
 4482: 
 4483:       if (! peer->af_group[afi][safi])
 4484: 	continue;
 4485: 
 4486:       if (filter->usmap.name)
 4487: 	free (filter->usmap.name);
 4488:       filter->usmap.name = NULL;
 4489:       filter->usmap.map = NULL;
 4490:     }
 4491:   return 0;
 4492: }
 4493: 
 4494: int
 4495: peer_maximum_prefix_set (struct peer *peer, afi_t afi, safi_t safi,
 4496: 			 u_int32_t max, u_char threshold,
 4497: 			 int warning, u_int16_t restart)
 4498: {
 4499:   struct peer_group *group;
 4500:   struct listnode *node, *nnode;
 4501: 
 4502:   if (! peer->afc[afi][safi])
 4503:     return BGP_ERR_PEER_INACTIVE;
 4504: 
 4505:   SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
 4506:   peer->pmax[afi][safi] = max;
 4507:   peer->pmax_threshold[afi][safi] = threshold;
 4508:   peer->pmax_restart[afi][safi] = restart;
 4509:   if (warning)
 4510:     SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
 4511:   else
 4512:     UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
 4513: 
 4514:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 4515:     return 0;
 4516: 
 4517:   group = peer->group;
 4518:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 4519:     {
 4520:       if (! peer->af_group[afi][safi])
 4521: 	continue;
 4522: 
 4523:       SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
 4524:       peer->pmax[afi][safi] = max;
 4525:       peer->pmax_threshold[afi][safi] = threshold;
 4526:       peer->pmax_restart[afi][safi] = restart;
 4527:       if (warning)
 4528: 	SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
 4529:       else
 4530: 	UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
 4531:     }
 4532:   return 0;
 4533: }
 4534: 
 4535: int
 4536: peer_maximum_prefix_unset (struct peer *peer, afi_t afi, safi_t safi)
 4537: {
 4538:   struct peer_group *group;
 4539:   struct listnode *node, *nnode;
 4540: 
 4541:   if (! peer->afc[afi][safi])
 4542:     return BGP_ERR_PEER_INACTIVE;
 4543: 
 4544:   /* apply peer-group config */
 4545:   if (peer->af_group[afi][safi])
 4546:     {
 4547:       if (CHECK_FLAG (peer->group->conf->af_flags[afi][safi],
 4548: 	  PEER_FLAG_MAX_PREFIX))
 4549: 	SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
 4550:       else
 4551: 	UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
 4552: 
 4553:       if (CHECK_FLAG (peer->group->conf->af_flags[afi][safi],
 4554: 	  PEER_FLAG_MAX_PREFIX_WARNING))
 4555: 	SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
 4556:       else
 4557: 	UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
 4558: 
 4559:       peer->pmax[afi][safi] = peer->group->conf->pmax[afi][safi];
 4560:       peer->pmax_threshold[afi][safi] = peer->group->conf->pmax_threshold[afi][safi];
 4561:       peer->pmax_restart[afi][safi] = peer->group->conf->pmax_restart[afi][safi];
 4562:       return 0;
 4563:     }
 4564: 
 4565:   UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
 4566:   UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
 4567:   peer->pmax[afi][safi] = 0;
 4568:   peer->pmax_threshold[afi][safi] = 0;
 4569:   peer->pmax_restart[afi][safi] = 0;
 4570: 
 4571:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 4572:     return 0;
 4573: 
 4574:   group = peer->group;
 4575:   for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 4576:     {
 4577:       if (! peer->af_group[afi][safi])
 4578: 	continue;
 4579: 
 4580:       UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
 4581:       UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
 4582:       peer->pmax[afi][safi] = 0;
 4583:       peer->pmax_threshold[afi][safi] = 0;
 4584:       peer->pmax_restart[afi][safi] = 0;
 4585:     }
 4586:   return 0;
 4587: }
 4588: 
 4589: static int is_ebgp_multihop_configured (struct peer *peer)
 4590: {
 4591:   struct peer_group *group;
 4592:   struct listnode *node, *nnode;
 4593:   struct peer *peer1;
 4594: 
 4595:   if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 4596:     {
 4597:       group = peer->group;
 4598:       if ((peer_sort(peer) != BGP_PEER_IBGP) &&
 4599: 	  (group->conf->ttl != 1))
 4600: 	return 1;
 4601: 
 4602:       for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
 4603: 	{
 4604: 	  if ((peer_sort (peer1) != BGP_PEER_IBGP) &&
 4605: 	      (peer1->ttl != 1))
 4606: 	    return 1;
 4607: 	}
 4608:     }
 4609:   else
 4610:     {
 4611:       if ((peer_sort(peer) != BGP_PEER_IBGP) &&
 4612: 	  (peer->ttl != 1))
 4613: 	return 1;
 4614:     }
 4615:   return 0;
 4616: }
 4617: 
 4618: /* Set # of hops between us and BGP peer. */
 4619: int
 4620: peer_ttl_security_hops_set (struct peer *peer, int gtsm_hops)
 4621: {
 4622:   struct peer_group *group;
 4623:   struct listnode *node, *nnode;
 4624:   int ret;
 4625: 
 4626:   zlog_debug ("peer_ttl_security_hops_set: set gtsm_hops to %d for %s", gtsm_hops, peer->host);
 4627: 
 4628:   /* We cannot configure ttl-security hops when ebgp-multihop is already
 4629:      set.  For non peer-groups, the check is simple.  For peer-groups, it's
 4630:      slightly messy, because we need to check both the peer-group structure
 4631:      and all peer-group members for any trace of ebgp-multihop configuration
 4632:      before actually applying the ttl-security rules.  Cisco really made a
 4633:      mess of this configuration parameter, and OpenBGPD got it right.
 4634:   */
 4635:   
 4636:   if (peer->gtsm_hops == 0)
 4637:     {
 4638:       if (is_ebgp_multihop_configured (peer))
 4639: 	return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK;
 4640: 
 4641:       /* specify MAXTTL on outgoing packets */
 4642:       /* Routine handles iBGP peers correctly */
 4643:       ret = peer_ebgp_multihop_set (peer, MAXTTL);
 4644:       if (ret != 0)
 4645: 	return ret;
 4646:     }
 4647:   
 4648:   peer->gtsm_hops = gtsm_hops;
 4649: 
 4650:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 4651:     {
 4652:       if (peer->fd >= 0)
 4653: 	sockopt_minttl (peer->su.sa.sa_family, peer->fd, MAXTTL + 1 - gtsm_hops);
 4654:     }
 4655:   else
 4656:     {
 4657:       group = peer->group;
 4658:       for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 4659: 	{
 4660: 	  peer->gtsm_hops = group->conf->gtsm_hops;
 4661: 
 4662: 	  /* Change setting of existing peer
 4663: 	   *   established then change value (may break connectivity)
 4664: 	   *   not established yet (teardown session and restart)
 4665: 	   *   no session then do nothing (will get handled by next connection)
 4666: 	   */
 4667: 	  if (peer->status == Established)
 4668: 	    {
 4669: 	      if (peer->fd >= 0 && peer->gtsm_hops != 0)
 4670: 		sockopt_minttl (peer->su.sa.sa_family, peer->fd,
 4671: 				MAXTTL + 1 - peer->gtsm_hops);
 4672: 	    }
 4673: 	  else if (peer->status < Established)
 4674: 	    {
 4675: 	      if (BGP_DEBUG (events, EVENTS))
 4676: 		zlog_debug ("%s Min-ttl changed", peer->host);
 4677: 	      BGP_EVENT_ADD (peer, BGP_Stop);
 4678: 	    }
 4679: 	}
 4680:     }
 4681: 
 4682:   return 0;
 4683: }
 4684: 
 4685: int
 4686: peer_ttl_security_hops_unset (struct peer *peer)
 4687: {
 4688:   struct peer_group *group;
 4689:   struct listnode *node, *nnode;
 4690:   struct peer *opeer;
 4691: 
 4692:   zlog_debug ("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s", peer->host);
 4693: 
 4694:   /* if a peer-group member, then reset to peer-group default rather than 0 */
 4695:   if (peer_group_active (peer))
 4696:     peer->gtsm_hops = peer->group->conf->gtsm_hops;
 4697:   else
 4698:     peer->gtsm_hops = 0;
 4699: 
 4700:   opeer = peer;
 4701:   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 4702:     {
 4703:       if (peer->fd >= 0)
 4704: 	sockopt_minttl (peer->su.sa.sa_family, peer->fd, 0);
 4705:     }
 4706:   else
 4707:     {
 4708:       group = peer->group;
 4709:       for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
 4710: 	{
 4711: 	  peer->gtsm_hops = 0;
 4712: 	  
 4713: 	  if (peer->fd >= 0)
 4714: 	    sockopt_minttl (peer->su.sa.sa_family, peer->fd, 0);
 4715: 	}
 4716:     }
 4717: 
 4718:   return peer_ebgp_multihop_unset (opeer);
 4719: }
 4720: 
 4721: int
 4722: peer_clear (struct peer *peer)
 4723: {
 4724:   if (! CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
 4725:     {
 4726:       if (CHECK_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
 4727: 	{
 4728: 	  UNSET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
 4729: 	  if (peer->t_pmax_restart)
 4730: 	    {
 4731: 	      BGP_TIMER_OFF (peer->t_pmax_restart);
 4732: 	      if (BGP_DEBUG (events, EVENTS))
 4733: 		zlog_debug ("%s Maximum-prefix restart timer canceled",
 4734: 			    peer->host);
 4735: 	    }
 4736: 	  BGP_EVENT_ADD (peer, BGP_Start);
 4737: 	  return 0;
 4738: 	}
 4739: 
 4740:       peer->v_start = BGP_INIT_START_TIMER;
 4741:       if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
 4742: 	bgp_notify_send (peer, BGP_NOTIFY_CEASE,
 4743: 			 BGP_NOTIFY_CEASE_ADMIN_RESET);
 4744:       else
 4745:         BGP_EVENT_ADD (peer, BGP_Stop);
 4746:     }
 4747:   return 0;
 4748: }
 4749: 
 4750: int
 4751: peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi,
 4752: 		 enum bgp_clear_type stype)
 4753: {
 4754:   if (peer->status != Established)
 4755:     return 0;
 4756: 
 4757:   if (! peer->afc[afi][safi])
 4758:     return BGP_ERR_AF_UNCONFIGURED;
 4759: 
 4760:   peer->rtt = sockopt_tcp_rtt (peer->fd);
 4761: 
 4762:   if (stype == BGP_CLEAR_SOFT_RSCLIENT)
 4763:     {
 4764:       if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
 4765:         return 0;
 4766:       bgp_check_local_routes_rsclient (peer, afi, safi);
 4767:       bgp_soft_reconfig_rsclient (peer, afi, safi);
 4768:     }
 4769: 
 4770:   if (stype == BGP_CLEAR_SOFT_OUT || stype == BGP_CLEAR_SOFT_BOTH)
 4771:     bgp_announce_route (peer, afi, safi);
 4772: 
 4773:   if (stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX)
 4774:     {
 4775:       if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV)
 4776: 	  && (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV)
 4777: 	      || CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV)))
 4778: 	{
 4779: 	  struct bgp_filter *filter = &peer->filter[afi][safi];
 4780: 	  u_char prefix_type;
 4781: 
 4782: 	  if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV))
 4783: 	    prefix_type = ORF_TYPE_PREFIX;
 4784: 	  else
 4785: 	    prefix_type = ORF_TYPE_PREFIX_OLD;
 4786: 
 4787: 	  if (filter->plist[FILTER_IN].plist)
 4788: 	    {
 4789: 	      if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND))
 4790: 		bgp_route_refresh_send (peer, afi, safi,
 4791: 					prefix_type, REFRESH_DEFER, 1);
 4792: 	      bgp_route_refresh_send (peer, afi, safi, prefix_type,
 4793: 				      REFRESH_IMMEDIATE, 0);
 4794: 	    }
 4795: 	  else
 4796: 	    {
 4797: 	      if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND))
 4798: 		bgp_route_refresh_send (peer, afi, safi,
 4799: 					prefix_type, REFRESH_IMMEDIATE, 1);
 4800: 	      else
 4801: 		bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
 4802: 	    }
 4803: 	  return 0;
 4804: 	}
 4805:     }
 4806: 
 4807:   if (stype == BGP_CLEAR_SOFT_IN || stype == BGP_CLEAR_SOFT_BOTH
 4808:       || stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX)
 4809:     {
 4810:       /* If neighbor has soft reconfiguration inbound flag.
 4811: 	 Use Adj-RIB-In database. */
 4812:       if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
 4813: 	bgp_soft_reconfig_in (peer, afi, safi);
 4814:       else
 4815: 	{
 4816: 	  /* If neighbor has route refresh capability, send route refresh
 4817: 	     message to the peer. */
 4818: 	  if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV)
 4819: 	      || CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
 4820: 	    bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
 4821: 	  else
 4822: 	    return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED;
 4823: 	}
 4824:     }
 4825:   return 0;
 4826: }
 4827: 
 4828: /* Display peer uptime.*/
 4829: /* XXX: why does this function return char * when it takes buffer? */
 4830: char *
 4831: peer_uptime (time_t uptime2, char *buf, size_t len)
 4832: {
 4833:   time_t uptime1;
 4834:   struct tm *tm;
 4835: 
 4836:   /* Check buffer length. */
 4837:   if (len < BGP_UPTIME_LEN)
 4838:     {
 4839:       zlog_warn ("peer_uptime (): buffer shortage %lu", (u_long)len);
 4840:       /* XXX: should return status instead of buf... */
 4841:       snprintf (buf, len, "<error> "); 
 4842:       return buf;
 4843:     }
 4844: 
 4845:   /* If there is no connection has been done before print `never'. */
 4846:   if (uptime2 == 0)
 4847:     {
 4848:       snprintf (buf, len, "never   ");
 4849:       return buf;
 4850:     }
 4851: 
 4852:   /* Get current time. */
 4853:   uptime1 = bgp_clock ();
 4854:   uptime1 -= uptime2;
 4855:   tm = gmtime (&uptime1);
 4856:   
 4857:   /* Making formatted timer strings. */
 4858: #define ONE_DAY_SECOND 60*60*24
 4859: #define ONE_WEEK_SECOND ONE_DAY_SECOND*7
 4860: #define ONE_YEAR_SECOND ONE_DAY_SECOND*365
 4861: 
 4862:   if (uptime1 < ONE_DAY_SECOND)
 4863:     snprintf (buf, len, "%02d:%02d:%02d", 
 4864: 	      tm->tm_hour, tm->tm_min, tm->tm_sec);
 4865:   else if (uptime1 < ONE_WEEK_SECOND)
 4866:     snprintf (buf, len, "%dd%02dh%02dm", 
 4867: 	      tm->tm_yday, tm->tm_hour, tm->tm_min);
 4868:   else if (uptime1 < ONE_YEAR_SECOND)
 4869:     snprintf (buf, len, "%02dw%dd%02dh", 
 4870: 	      tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
 4871:   else
 4872:     snprintf (buf, len, "%02dy%02dw%dd", 
 4873: 	      tm->tm_year - 70, tm->tm_yday/7, 
 4874: 	      tm->tm_yday - ((tm->tm_yday/7) * 7));
 4875:   return buf;
 4876: }
 4877: 
 4878: static void
 4879: bgp_config_write_filter (struct vty *vty, struct peer *peer,
 4880: 			 afi_t afi, safi_t safi)
 4881: {
 4882:   struct bgp_filter *filter;
 4883:   struct bgp_filter *gfilter = NULL;
 4884:   char *addr;
 4885:   int in = FILTER_IN;
 4886:   int out = FILTER_OUT;
 4887: 
 4888:   addr = peer->host;
 4889:   filter = &peer->filter[afi][safi];
 4890:   if (peer->af_group[afi][safi])
 4891:     gfilter = &peer->group->conf->filter[afi][safi];
 4892: 
 4893:   /* distribute-list. */
 4894:   if (filter->dlist[in].name)
 4895:     if (! gfilter || ! gfilter->dlist[in].name
 4896: 	|| strcmp (filter->dlist[in].name, gfilter->dlist[in].name) != 0)
 4897:     vty_out (vty, " neighbor %s distribute-list %s in%s", addr, 
 4898: 	     filter->dlist[in].name, VTY_NEWLINE);
 4899:   if (filter->dlist[out].name && ! gfilter)
 4900:     vty_out (vty, " neighbor %s distribute-list %s out%s", addr, 
 4901: 	     filter->dlist[out].name, VTY_NEWLINE);
 4902: 
 4903:   /* prefix-list. */
 4904:   if (filter->plist[in].name)
 4905:     if (! gfilter || ! gfilter->plist[in].name
 4906: 	|| strcmp (filter->plist[in].name, gfilter->plist[in].name) != 0)
 4907:     vty_out (vty, " neighbor %s prefix-list %s in%s", addr, 
 4908: 	     filter->plist[in].name, VTY_NEWLINE);
 4909:   if (filter->plist[out].name && ! gfilter)
 4910:     vty_out (vty, " neighbor %s prefix-list %s out%s", addr, 
 4911: 	     filter->plist[out].name, VTY_NEWLINE);
 4912: 
 4913:   /* route-map. */
 4914:   if (filter->map[RMAP_IN].name)
 4915:     if (! gfilter || ! gfilter->map[RMAP_IN].name
 4916:        || strcmp (filter->map[RMAP_IN].name, gfilter->map[RMAP_IN].name) != 0)
 4917:       vty_out (vty, " neighbor %s route-map %s in%s", addr, 
 4918:               filter->map[RMAP_IN].name, VTY_NEWLINE);
 4919:   if (filter->map[RMAP_OUT].name && ! gfilter)
 4920:     vty_out (vty, " neighbor %s route-map %s out%s", addr, 
 4921:             filter->map[RMAP_OUT].name, VTY_NEWLINE);
 4922:   if (filter->map[RMAP_IMPORT].name && ! gfilter)
 4923:     vty_out (vty, " neighbor %s route-map %s import%s", addr,
 4924:         filter->map[RMAP_IMPORT].name, VTY_NEWLINE);
 4925:   if (filter->map[RMAP_EXPORT].name)
 4926:     if (! gfilter || ! gfilter->map[RMAP_EXPORT].name
 4927:     || strcmp (filter->map[RMAP_EXPORT].name,
 4928:                     gfilter->map[RMAP_EXPORT].name) != 0)
 4929:     vty_out (vty, " neighbor %s route-map %s export%s", addr,
 4930:         filter->map[RMAP_EXPORT].name, VTY_NEWLINE);
 4931: 
 4932:   /* unsuppress-map */
 4933:   if (filter->usmap.name && ! gfilter)
 4934:     vty_out (vty, " neighbor %s unsuppress-map %s%s", addr,
 4935: 	     filter->usmap.name, VTY_NEWLINE);
 4936: 
 4937:   /* filter-list. */
 4938:   if (filter->aslist[in].name)
 4939:     if (! gfilter || ! gfilter->aslist[in].name
 4940: 	|| strcmp (filter->aslist[in].name, gfilter->aslist[in].name) != 0)
 4941:       vty_out (vty, " neighbor %s filter-list %s in%s", addr, 
 4942: 	       filter->aslist[in].name, VTY_NEWLINE);
 4943:   if (filter->aslist[out].name && ! gfilter)
 4944:     vty_out (vty, " neighbor %s filter-list %s out%s", addr, 
 4945: 	     filter->aslist[out].name, VTY_NEWLINE);
 4946: }
 4947: 
 4948: /* BGP peer configuration display function. */
 4949: static void
 4950: bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
 4951: 		       struct peer *peer, afi_t afi, safi_t safi)
 4952: {
 4953:   struct peer *g_peer = NULL;
 4954:   char buf[SU_ADDRSTRLEN];
 4955:   char *addr;
 4956: 
 4957:   addr = peer->host;
 4958:   if (peer_group_active (peer))
 4959:     g_peer = peer->group->conf;
 4960: 
 4961:   /************************************
 4962:    ****** Global to the neighbor ******
 4963:    ************************************/
 4964:   if (afi == AFI_IP && safi == SAFI_UNICAST)
 4965:     {
 4966:       /* remote-as. */
 4967:       if (! peer_group_active (peer))
 4968: 	{
 4969: 	  if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
 4970: 	    vty_out (vty, " neighbor %s peer-group%s", addr,
 4971: 		     VTY_NEWLINE);
 4972: 	  if (peer->as)
 4973: 	    vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
 4974: 		     VTY_NEWLINE);
 4975: 	}
 4976:       else
 4977: 	{
 4978: 	  if (! g_peer->as)
 4979: 	    vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
 4980: 		     VTY_NEWLINE);
 4981: 	  if (peer->af_group[AFI_IP][SAFI_UNICAST])
 4982: 	    vty_out (vty, " neighbor %s peer-group %s%s", addr,
 4983: 		     peer->group->name, VTY_NEWLINE);
 4984: 	}
 4985: 
 4986:       /* local-as. */
 4987:       if (peer->change_local_as)
 4988: 	if (! peer_group_active (peer))
 4989: 	  vty_out (vty, " neighbor %s local-as %u%s%s%s", addr,
 4990: 		   peer->change_local_as,
 4991: 		   CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) ?
 4992: 		   " no-prepend" : "",
 4993: 		   CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) ?
 4994: 		   " replace-as" : "", VTY_NEWLINE);
 4995: 
 4996:       /* Description. */
 4997:       if (peer->desc)
 4998: 	vty_out (vty, " neighbor %s description %s%s", addr, peer->desc,
 4999: 		 VTY_NEWLINE);
 5000: 
 5001:       /* Shutdown. */
 5002:       if (CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
 5003:         if (! peer_group_active (peer) ||
 5004: 	    ! CHECK_FLAG (g_peer->flags, PEER_FLAG_SHUTDOWN))
 5005: 	  vty_out (vty, " neighbor %s shutdown%s", addr, VTY_NEWLINE);
 5006: 
 5007:       /* Password. */
 5008:       if (peer->password)
 5009: 	if (!peer_group_active (peer)
 5010: 	    || ! g_peer->password
 5011: 	    || strcmp (peer->password, g_peer->password) != 0)
 5012: 	  vty_out (vty, " neighbor %s password %s%s", addr, peer->password,
 5013: 		   VTY_NEWLINE);
 5014: 
 5015:       /* BGP port. */
 5016:       if (peer->port != BGP_PORT_DEFAULT)
 5017: 	vty_out (vty, " neighbor %s port %d%s", addr, peer->port,
 5018: 		 VTY_NEWLINE);
 5019: 
 5020:       /* Local interface name. */
 5021:       if (peer->ifname)
 5022: 	vty_out (vty, " neighbor %s interface %s%s", addr, peer->ifname,
 5023: 		 VTY_NEWLINE);
 5024:   
 5025:       /* Passive. */
 5026:       if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE))
 5027:         if (! peer_group_active (peer) ||
 5028: 	    ! CHECK_FLAG (g_peer->flags, PEER_FLAG_PASSIVE))
 5029: 	  vty_out (vty, " neighbor %s passive%s", addr, VTY_NEWLINE);
 5030: 
 5031:       /* EBGP multihop.  */
 5032:       if (peer->sort != BGP_PEER_IBGP && peer->ttl != 1 &&
 5033:                    !(peer->gtsm_hops != 0 && peer->ttl == MAXTTL))
 5034:         if (! peer_group_active (peer) ||
 5035: 	    g_peer->ttl != peer->ttl)
 5036: 	  vty_out (vty, " neighbor %s ebgp-multihop %d%s", addr, peer->ttl,
 5037: 		   VTY_NEWLINE);
 5038: 
 5039:      /* ttl-security hops */
 5040:       if (peer->gtsm_hops != 0)
 5041:         if (! peer_group_active (peer) || g_peer->gtsm_hops != peer->gtsm_hops)
 5042:           vty_out (vty, " neighbor %s ttl-security hops %d%s", addr,
 5043:                    peer->gtsm_hops, VTY_NEWLINE);
 5044: 
 5045:       /* disable-connected-check.  */
 5046:       if (CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
 5047: 	if (! peer_group_active (peer) ||
 5048: 	    ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
 5049: 	  vty_out (vty, " neighbor %s disable-connected-check%s", addr, VTY_NEWLINE);
 5050: 
 5051:       /* Update-source. */
 5052:       if (peer->update_if)
 5053: 	if (! peer_group_active (peer) || ! g_peer->update_if
 5054: 	    || strcmp (g_peer->update_if, peer->update_if) != 0)
 5055: 	  vty_out (vty, " neighbor %s update-source %s%s", addr,
 5056: 		   peer->update_if, VTY_NEWLINE);
 5057:       if (peer->update_source)
 5058: 	if (! peer_group_active (peer) || ! g_peer->update_source
 5059: 	    || sockunion_cmp (g_peer->update_source,
 5060: 			      peer->update_source) != 0)
 5061: 	  vty_out (vty, " neighbor %s update-source %s%s", addr,
 5062: 		   sockunion2str (peer->update_source, buf, SU_ADDRSTRLEN),
 5063: 		   VTY_NEWLINE);
 5064: 
 5065:       /* advertisement-interval */
 5066:       if (CHECK_FLAG (peer->config, PEER_CONFIG_ROUTEADV) &&
 5067:           ! peer_group_active (peer))
 5068: 	vty_out (vty, " neighbor %s advertisement-interval %d%s",
 5069: 		 addr, peer->v_routeadv, VTY_NEWLINE); 
 5070: 
 5071:       /* timers. */
 5072:       if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER)
 5073: 	  && ! peer_group_active (peer))
 5074: 	  vty_out (vty, " neighbor %s timers %d %d%s", addr, 
 5075: 	  peer->keepalive, peer->holdtime, VTY_NEWLINE);
 5076: 
 5077:       if (CHECK_FLAG (peer->config, PEER_CONFIG_CONNECT) &&
 5078:           ! peer_group_active (peer))
 5079: 	  vty_out (vty, " neighbor %s timers connect %d%s", addr, 
 5080: 	  peer->connect, VTY_NEWLINE);
 5081: 
 5082:       /* Default weight. */
 5083:       if (CHECK_FLAG (peer->config, PEER_CONFIG_WEIGHT))
 5084:         if (! peer_group_active (peer) ||
 5085: 	    g_peer->weight != peer->weight)
 5086: 	  vty_out (vty, " neighbor %s weight %d%s", addr, peer->weight,
 5087: 		   VTY_NEWLINE);
 5088: 
 5089:       /* Dynamic capability.  */
 5090:       if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
 5091:         if (! peer_group_active (peer) ||
 5092: 	    ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
 5093: 	vty_out (vty, " neighbor %s capability dynamic%s", addr,
 5094: 	     VTY_NEWLINE);
 5095: 
 5096:       /* dont capability negotiation. */
 5097:       if (CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
 5098:         if (! peer_group_active (peer) ||
 5099: 	    ! CHECK_FLAG (g_peer->flags, PEER_FLAG_DONT_CAPABILITY))
 5100: 	vty_out (vty, " neighbor %s dont-capability-negotiate%s", addr,
 5101: 		 VTY_NEWLINE);
 5102: 
 5103:       /* override capability negotiation. */
 5104:       if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
 5105:         if (! peer_group_active (peer) ||
 5106: 	    ! CHECK_FLAG (g_peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
 5107: 	vty_out (vty, " neighbor %s override-capability%s", addr,
 5108: 		 VTY_NEWLINE);
 5109: 
 5110:       /* strict capability negotiation. */
 5111:       if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
 5112:         if (! peer_group_active (peer) ||
 5113: 	    ! CHECK_FLAG (g_peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
 5114: 	vty_out (vty, " neighbor %s strict-capability-match%s", addr,
 5115: 	     VTY_NEWLINE);
 5116: 
 5117:       if (! peer->af_group[AFI_IP][SAFI_UNICAST])
 5118: 	{
 5119: 	  if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4))
 5120: 	    {
 5121: 	      if (peer->afc[AFI_IP][SAFI_UNICAST])
 5122: 		vty_out (vty, " neighbor %s activate%s", addr, VTY_NEWLINE);
 5123: 	    }
 5124:           else
 5125: 	    {
 5126: 	      if (! peer->afc[AFI_IP][SAFI_UNICAST])
 5127: 		vty_out (vty, " no neighbor %s activate%s", addr, VTY_NEWLINE);
 5128: 	    }
 5129: 	}
 5130:     }
 5131: 
 5132: 
 5133:   /************************************
 5134:    ****** Per AF to the neighbor ******
 5135:    ************************************/
 5136: 
 5137:   if (! (afi == AFI_IP && safi == SAFI_UNICAST))
 5138:     {
 5139:       if (peer->af_group[afi][safi])
 5140: 	vty_out (vty, " neighbor %s peer-group %s%s", addr,
 5141: 		 peer->group->name, VTY_NEWLINE);
 5142:       else
 5143: 	vty_out (vty, " neighbor %s activate%s", addr, VTY_NEWLINE);
 5144:     }
 5145: 
 5146:   /* ORF capability.  */
 5147:   if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
 5148:       || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
 5149:     if (! peer->af_group[afi][safi])
 5150:     {
 5151:       vty_out (vty, " neighbor %s capability orf prefix-list", addr);
 5152: 
 5153:       if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
 5154: 	  && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
 5155: 	vty_out (vty, " both");
 5156:       else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM))
 5157: 	vty_out (vty, " send");
 5158:       else
 5159: 	vty_out (vty, " receive");
 5160:       vty_out (vty, "%s", VTY_NEWLINE);
 5161:     }
 5162: 
 5163:   /* Route reflector client. */
 5164:   if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REFLECTOR_CLIENT)
 5165:       && ! peer->af_group[afi][safi])
 5166:     vty_out (vty, " neighbor %s route-reflector-client%s", addr, 
 5167: 	     VTY_NEWLINE);
 5168: 
 5169:   /* Nexthop self. */
 5170:   if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_SELF)
 5171:       && ! peer->af_group[afi][safi])
 5172:     vty_out (vty, " neighbor %s next-hop-self%s%s", addr,
 5173: 	     peer_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_SELF_ALL) ?
 5174: 	     " all" : "", VTY_NEWLINE);
 5175: 
 5176:   /* Remove private AS. */
 5177:   if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
 5178:       && ! peer->af_group[afi][safi])
 5179:     vty_out (vty, " neighbor %s remove-private-AS%s",
 5180: 	     addr, VTY_NEWLINE);
 5181: 
 5182:   /* send-community print. */
 5183:   if (! peer->af_group[afi][safi])
 5184:     {
 5185:       if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
 5186: 	{
 5187: 	  if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY)
 5188: 	      && peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
 5189: 	    vty_out (vty, " neighbor %s send-community both%s", addr, VTY_NEWLINE);
 5190: 	  else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))	
 5191: 	    vty_out (vty, " neighbor %s send-community extended%s",
 5192: 		     addr, VTY_NEWLINE);
 5193: 	  else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY))
 5194: 	    vty_out (vty, " neighbor %s send-community%s", addr, VTY_NEWLINE);
 5195: 	}
 5196:       else
 5197: 	{
 5198: 	  if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY)
 5199: 	      && ! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
 5200: 	    vty_out (vty, " no neighbor %s send-community both%s",
 5201: 		     addr, VTY_NEWLINE);
 5202: 	  else if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
 5203: 	    vty_out (vty, " no neighbor %s send-community extended%s",
 5204: 		     addr, VTY_NEWLINE);
 5205: 	  else if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY))
 5206: 	    vty_out (vty, " no neighbor %s send-community%s",
 5207: 		     addr, VTY_NEWLINE);
 5208: 	}
 5209:     }
 5210: 
 5211:   /* Default information */
 5212:   if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_DEFAULT_ORIGINATE)
 5213:       && ! peer->af_group[afi][safi])
 5214:     {
 5215:       vty_out (vty, " neighbor %s default-originate", addr);
 5216:       if (peer->default_rmap[afi][safi].name)
 5217: 	vty_out (vty, " route-map %s", peer->default_rmap[afi][safi].name);
 5218:       vty_out (vty, "%s", VTY_NEWLINE);
 5219:     }
 5220: 
 5221:   /* Soft reconfiguration inbound. */
 5222:   if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
 5223:     if (! peer->af_group[afi][safi] ||
 5224: 	! CHECK_FLAG (g_peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
 5225:     vty_out (vty, " neighbor %s soft-reconfiguration inbound%s", addr,
 5226: 	     VTY_NEWLINE);
 5227: 
 5228:   /* maximum-prefix. */
 5229:   if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
 5230:     if (! peer->af_group[afi][safi]
 5231: 	|| g_peer->pmax[afi][safi] != peer->pmax[afi][safi]
 5232:         || g_peer->pmax_threshold[afi][safi] != peer->pmax_threshold[afi][safi]
 5233: 	|| CHECK_FLAG (g_peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING)
 5234: 	   != CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
 5235:       {
 5236: 	vty_out (vty, " neighbor %s maximum-prefix %ld", addr, peer->pmax[afi][safi]);
 5237: 	if (peer->pmax_threshold[afi][safi] != MAXIMUM_PREFIX_THRESHOLD_DEFAULT)
 5238: 	  vty_out (vty, " %d", peer->pmax_threshold[afi][safi]);
 5239: 	if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
 5240: 	  vty_out (vty, " warning-only");
 5241: 	if (peer->pmax_restart[afi][safi])
 5242: 	  vty_out (vty, " restart %d", peer->pmax_restart[afi][safi]);
 5243: 	vty_out (vty, "%s", VTY_NEWLINE);
 5244:       }
 5245: 
 5246:   /* Route server client. */
 5247:   if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
 5248:       && ! peer->af_group[afi][safi])
 5249:     vty_out (vty, " neighbor %s route-server-client%s", addr, VTY_NEWLINE);
 5250: 
 5251:   /* Nexthop-local unchanged. */
 5252:   if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
 5253:       && ! peer->af_group[afi][safi])
 5254:     vty_out (vty, " neighbor %s nexthop-local unchanged%s", addr, VTY_NEWLINE);
 5255: 
 5256:   /* Allow AS in.  */
 5257:   if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_ALLOWAS_IN))
 5258:     if (! peer_group_active (peer)
 5259: 	|| ! peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_ALLOWAS_IN)
 5260: 	|| peer->allowas_in[afi][safi] != g_peer->allowas_in[afi][safi])
 5261:       {
 5262: 	if (peer->allowas_in[afi][safi] == 3)
 5263: 	  vty_out (vty, " neighbor %s allowas-in%s", addr, VTY_NEWLINE);
 5264: 	else
 5265: 	  vty_out (vty, " neighbor %s allowas-in %d%s", addr,
 5266: 		   peer->allowas_in[afi][safi], VTY_NEWLINE);
 5267:       }
 5268: 
 5269:   /* Filter. */
 5270:   bgp_config_write_filter (vty, peer, afi, safi);
 5271: 
 5272:   /* atribute-unchanged. */
 5273:   if ((CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
 5274:       || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
 5275:       || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED))
 5276:       && ! peer->af_group[afi][safi])
 5277:     {
 5278:       if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
 5279:           && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
 5280:           && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED))
 5281: 	vty_out (vty, " neighbor %s attribute-unchanged%s", addr, VTY_NEWLINE);
 5282:       else
 5283: 	vty_out (vty, " neighbor %s attribute-unchanged%s%s%s%s", addr, 
 5284: 	     (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)) ?
 5285: 	     " as-path" : "",
 5286: 	     (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)) ?
 5287: 	     " next-hop" : "",
 5288: 	     (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED)) ?
 5289: 	     " med" : "", VTY_NEWLINE);
 5290:     }
 5291: }
 5292: 
 5293: /* Display "address-family" configuration header. */
 5294: void
 5295: bgp_config_write_family_header (struct vty *vty, afi_t afi, safi_t safi,
 5296: 				int *write)
 5297: {
 5298:   if (*write)
 5299:     return;
 5300: 
 5301:   if (afi == AFI_IP && safi == SAFI_UNICAST)
 5302:     return;
 5303: 
 5304:   vty_out (vty, "!%s address-family ", VTY_NEWLINE);
 5305: 
 5306:   if (afi == AFI_IP)
 5307:     {
 5308:       if (safi == SAFI_MULTICAST)
 5309: 	vty_out (vty, "ipv4 multicast");
 5310:       else if (safi == SAFI_MPLS_VPN)
 5311: 	vty_out (vty, "vpnv4");
 5312:       else if (safi == SAFI_ENCAP)
 5313: 	vty_out (vty, "encap");
 5314:     }
 5315:   else if (afi == AFI_IP6)
 5316:     {
 5317:       if (safi == SAFI_MPLS_VPN)
 5318:         vty_out (vty, "vpnv6");
 5319:       else if (safi == SAFI_ENCAP)
 5320:         vty_out (vty, "encapv6");
 5321:       else
 5322:         {
 5323:           vty_out (vty, "ipv6");
 5324:           if (safi == SAFI_MULTICAST)
 5325:             vty_out (vty, " multicast");
 5326:         }
 5327:     }
 5328: 
 5329:   vty_out (vty, "%s", VTY_NEWLINE);
 5330: 
 5331:   *write = 1;
 5332: }
 5333: 
 5334: /* Address family based peer configuration display.  */
 5335: static int
 5336: bgp_config_write_family (struct vty *vty, struct bgp *bgp, afi_t afi,
 5337: 			 safi_t safi)
 5338: {
 5339:   int write = 0;
 5340:   struct peer *peer;
 5341:   struct peer_group *group;
 5342:   struct listnode *node, *nnode;
 5343: 
 5344:   bgp_config_write_network (vty, bgp, afi, safi, &write);
 5345: 
 5346:   bgp_config_write_redistribute (vty, bgp, afi, safi, &write);
 5347: 
 5348:   for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
 5349:     {
 5350:       if (group->conf->afc[afi][safi])
 5351: 	{
 5352: 	  bgp_config_write_family_header (vty, afi, safi, &write);
 5353: 	  bgp_config_write_peer (vty, bgp, group->conf, afi, safi);
 5354: 	}
 5355:     }
 5356:   for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
 5357:     {
 5358:       if (peer->afc[afi][safi])
 5359: 	{
 5360: 	  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
 5361: 	    {
 5362: 	      bgp_config_write_family_header (vty, afi, safi, &write);
 5363: 	      bgp_config_write_peer (vty, bgp, peer, afi, safi);
 5364: 	    }
 5365: 	}
 5366:     }
 5367: 
 5368:   bgp_config_write_maxpaths (vty, bgp, afi, safi, &write);
 5369: 
 5370:   if (write)
 5371:     vty_out (vty, " exit-address-family%s", VTY_NEWLINE);
 5372: 
 5373:   return write;
 5374: }
 5375: 
 5376: int
 5377: bgp_config_write (struct vty *vty)
 5378: {
 5379:   int write = 0;
 5380:   struct bgp *bgp;
 5381:   struct peer_group *group;
 5382:   struct peer *peer;
 5383:   struct listnode *node, *nnode;
 5384:   struct listnode *mnode, *mnnode;
 5385: 
 5386:   /* BGP Multiple instance. */
 5387:   if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
 5388:     {    
 5389:       vty_out (vty, "bgp multiple-instance%s", VTY_NEWLINE);
 5390:       write++;
 5391:     }
 5392: 
 5393:   /* BGP Config type. */
 5394:   if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
 5395:     {    
 5396:       vty_out (vty, "bgp config-type cisco%s", VTY_NEWLINE);
 5397:       write++;
 5398:     }
 5399: 
 5400:   /* BGP configuration. */
 5401:   for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
 5402:     {
 5403:       if (write)
 5404: 	vty_out (vty, "!%s", VTY_NEWLINE);
 5405: 
 5406:       /* Router bgp ASN */
 5407:       vty_out (vty, "router bgp %u", bgp->as);
 5408: 
 5409:       if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
 5410: 	{
 5411: 	  if (bgp->name)
 5412: 	    vty_out (vty, " view %s", bgp->name);
 5413: 	}
 5414:       vty_out (vty, "%s", VTY_NEWLINE);
 5415: 
 5416:       /* No Synchronization */
 5417:       if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
 5418: 	vty_out (vty, " no synchronization%s", VTY_NEWLINE);
 5419: 
 5420:       /* BGP fast-external-failover. */
 5421:       if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))
 5422: 	vty_out (vty, " no bgp fast-external-failover%s", VTY_NEWLINE); 
 5423: 
 5424:       /* BGP router ID. */
 5425:       if (CHECK_FLAG (bgp->config, BGP_CONFIG_ROUTER_ID))
 5426: 	vty_out (vty, " bgp router-id %s%s", inet_ntoa (bgp->router_id), 
 5427: 		 VTY_NEWLINE);
 5428: 
 5429:       /* BGP log-neighbor-changes. */
 5430:       if (!bgp_flag_check (bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
 5431: 	vty_out (vty, " no bgp log-neighbor-changes%s", VTY_NEWLINE);
 5432: 
 5433:       /* BGP configuration. */
 5434:       if (bgp_flag_check (bgp, BGP_FLAG_ALWAYS_COMPARE_MED))
 5435: 	vty_out (vty, " bgp always-compare-med%s", VTY_NEWLINE);
 5436: 
 5437:       /* BGP default ipv4-unicast. */
 5438:       if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4))
 5439: 	vty_out (vty, " no bgp default ipv4-unicast%s", VTY_NEWLINE);
 5440: 
 5441:       /* BGP default local-preference. */
 5442:       if (bgp->default_local_pref != BGP_DEFAULT_LOCAL_PREF)
 5443: 	vty_out (vty, " bgp default local-preference %d%s",
 5444: 		 bgp->default_local_pref, VTY_NEWLINE);
 5445: 
 5446:       /* BGP client-to-client reflection. */
 5447:       if (bgp_flag_check (bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT))
 5448: 	vty_out (vty, " no bgp client-to-client reflection%s", VTY_NEWLINE);
 5449:       
 5450:       /* BGP cluster ID. */
 5451:       if (CHECK_FLAG (bgp->config, BGP_CONFIG_CLUSTER_ID))
 5452: 	vty_out (vty, " bgp cluster-id %s%s", inet_ntoa (bgp->cluster_id),
 5453: 		 VTY_NEWLINE);
 5454: 
 5455:       /* Confederation identifier*/
 5456:       if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION))
 5457:        vty_out (vty, " bgp confederation identifier %i%s", bgp->confed_id,
 5458:                 VTY_NEWLINE);
 5459: 
 5460:       /* Confederation peer */
 5461:       if (bgp->confed_peers_cnt > 0)
 5462: 	{
 5463: 	  int i;
 5464: 
 5465: 	  vty_out (vty, " bgp confederation peers");
 5466: 
 5467:          for (i = 0; i < bgp->confed_peers_cnt; i++)
 5468:            vty_out(vty, " %u", bgp->confed_peers[i]);
 5469: 
 5470:           vty_out (vty, "%s", VTY_NEWLINE);
 5471: 	}
 5472: 
 5473:       /* BGP enforce-first-as. */
 5474:       if (bgp_flag_check (bgp, BGP_FLAG_ENFORCE_FIRST_AS))
 5475: 	vty_out (vty, " bgp enforce-first-as%s", VTY_NEWLINE);
 5476: 
 5477:       /* BGP deterministic-med. */
 5478:       if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED))
 5479: 	vty_out (vty, " bgp deterministic-med%s", VTY_NEWLINE);
 5480: 
 5481:       /* BGP graceful-restart. */
 5482:       if (bgp->stalepath_time != BGP_DEFAULT_STALEPATH_TIME)
 5483: 	vty_out (vty, " bgp graceful-restart stalepath-time %d%s",
 5484: 		 bgp->stalepath_time, VTY_NEWLINE);
 5485:       if (bgp_flag_check (bgp, BGP_FLAG_GRACEFUL_RESTART))
 5486:        vty_out (vty, " bgp graceful-restart%s", VTY_NEWLINE);
 5487: 
 5488:       /* BGP bestpath method. */
 5489:       if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_IGNORE))
 5490: 	vty_out (vty, " bgp bestpath as-path ignore%s", VTY_NEWLINE);
 5491:       if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_CONFED))
 5492: 	vty_out (vty, " bgp bestpath as-path confed%s", VTY_NEWLINE);
 5493:       if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
 5494: 	vty_out (vty, " bgp bestpath as-path multipath-relax%s", VTY_NEWLINE);
 5495:       }
 5496:       if (bgp_flag_check (bgp, BGP_FLAG_COMPARE_ROUTER_ID))
 5497: 	vty_out (vty, " bgp bestpath compare-routerid%s", VTY_NEWLINE);
 5498:       if (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED)
 5499: 	  || bgp_flag_check (bgp, BGP_FLAG_MED_MISSING_AS_WORST))
 5500: 	{
 5501: 	  vty_out (vty, " bgp bestpath med");
 5502: 	  if (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED))
 5503: 	    vty_out (vty, " confed");
 5504: 	  if (bgp_flag_check (bgp, BGP_FLAG_MED_MISSING_AS_WORST))
 5505: 	    vty_out (vty, " missing-as-worst");
 5506: 	  vty_out (vty, "%s", VTY_NEWLINE);
 5507: 	}
 5508: 
 5509:       /* BGP network import check. */
 5510:       if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
 5511: 	vty_out (vty, " bgp network import-check%s", VTY_NEWLINE);
 5512: 
 5513:       /* BGP scan interval. */
 5514:       bgp_config_write_scan_time (vty);
 5515: 
 5516:       /* BGP flag dampening. */
 5517:       if (CHECK_FLAG (bgp->af_flags[AFI_IP][SAFI_UNICAST],
 5518: 	  BGP_CONFIG_DAMPENING))
 5519: 	bgp_config_write_damp (vty);
 5520: 
 5521:       /* BGP static route configuration. */
 5522:       bgp_config_write_network (vty, bgp, AFI_IP, SAFI_UNICAST, &write);
 5523: 
 5524:       /* BGP redistribute configuration. */
 5525:       bgp_config_write_redistribute (vty, bgp, AFI_IP, SAFI_UNICAST, &write);
 5526: 
 5527:       /* BGP timers configuration. */
 5528:       if (bgp->default_keepalive != BGP_DEFAULT_KEEPALIVE
 5529: 	  && bgp->default_holdtime != BGP_DEFAULT_HOLDTIME)
 5530: 	vty_out (vty, " timers bgp %d %d%s", bgp->default_keepalive, 
 5531: 		 bgp->default_holdtime, VTY_NEWLINE);
 5532: 
 5533:       /* peer-group */
 5534:       for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
 5535: 	{
 5536: 	  bgp_config_write_peer (vty, bgp, group->conf, AFI_IP, SAFI_UNICAST);
 5537: 	}
 5538: 
 5539:       /* Normal neighbor configuration. */
 5540:       for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
 5541: 	{
 5542: 	  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
 5543: 	    bgp_config_write_peer (vty, bgp, peer, AFI_IP, SAFI_UNICAST);
 5544: 	}
 5545: 
 5546:       /* maximum-paths */
 5547:       bgp_config_write_maxpaths (vty, bgp, AFI_IP, SAFI_UNICAST, &write);
 5548: 
 5549:       /* Distance configuration. */
 5550:       bgp_config_write_distance (vty, bgp);
 5551:       
 5552:       /* No auto-summary */
 5553:       if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
 5554: 	vty_out (vty, " no auto-summary%s", VTY_NEWLINE);
 5555: 
 5556:       /* IPv4 multicast configuration.  */
 5557:       write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_MULTICAST);
 5558: 
 5559:       /* IPv4 VPN configuration.  */
 5560:       write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_MPLS_VPN);
 5561: 
 5562:       /* ENCAPv4 configuration.  */
 5563:       write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_ENCAP);
 5564: 
 5565:       /* IPv6 unicast configuration.  */
 5566:       write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_UNICAST);
 5567: 
 5568:       /* IPv6 multicast configuration.  */
 5569:       write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_MULTICAST);
 5570: 
 5571:       /* IPv6 VPN configuration.  */
 5572:       write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_MPLS_VPN);
 5573: 
 5574:       /* ENCAPv6 configuration.  */
 5575:       write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_ENCAP);
 5576: 
 5577:       vty_out (vty, " exit%s", VTY_NEWLINE);
 5578: 
 5579:       write++;
 5580:     }
 5581:   return write;
 5582: }
 5583: 
 5584: void
 5585: bgp_master_init (void)
 5586: {
 5587:   memset (&bgp_master, 0, sizeof (struct bgp_master));
 5588: 
 5589:   bm = &bgp_master;
 5590:   bm->bgp = list_new ();
 5591:   bm->listen_sockets = list_new ();
 5592:   bm->port = BGP_PORT_DEFAULT;
 5593:   bm->master = thread_master_create ();
 5594:   bm->start_time = bgp_clock ();
 5595: }
 5596: 
 5597: 
 5598: void
 5599: bgp_init (void)
 5600: {
 5601:   /* BGP VTY commands installation.  */
 5602:   bgp_vty_init ();
 5603: 
 5604:   /* Init zebra. */
 5605:   bgp_zebra_init (bm->master);
 5606: 
 5607:   /* BGP inits. */
 5608:   bgp_attr_init ();
 5609:   bgp_debug_init ();
 5610:   bgp_dump_init ();
 5611:   bgp_route_init ();
 5612:   bgp_route_map_init ();
 5613:   bgp_address_init ();
 5614:   bgp_scan_init ();
 5615:   bgp_mplsvpn_init ();
 5616:   bgp_encap_init ();
 5617: 
 5618:   /* Access list initialize. */
 5619:   access_list_init ();
 5620:   access_list_add_hook (peer_distribute_update);
 5621:   access_list_delete_hook (peer_distribute_update);
 5622: 
 5623:   /* Filter list initialize. */
 5624:   bgp_filter_init ();
 5625:   as_list_add_hook (peer_aslist_update);
 5626:   as_list_delete_hook (peer_aslist_update);
 5627: 
 5628:   /* Prefix list initialize.*/
 5629:   prefix_list_init ();
 5630:   prefix_list_add_hook (peer_prefix_list_update);
 5631:   prefix_list_delete_hook (peer_prefix_list_update);
 5632: 
 5633:   /* Community list initialize. */
 5634:   bgp_clist = community_list_init ();
 5635: 
 5636: #ifdef HAVE_SNMP
 5637:   bgp_snmp_init ();
 5638: #endif /* HAVE_SNMP */
 5639: }
 5640: 
 5641: void
 5642: bgp_terminate (void)
 5643: {
 5644:   struct bgp *bgp;
 5645:   struct peer *peer;
 5646:   struct listnode *node, *nnode;
 5647:   struct listnode *mnode, *mnnode;
 5648: 
 5649:   for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
 5650:     for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
 5651:       if (peer->status == Established)
 5652:           bgp_notify_send (peer, BGP_NOTIFY_CEASE,
 5653:                            BGP_NOTIFY_CEASE_PEER_UNCONFIG);
 5654:   
 5655:   bgp_cleanup_routes ();
 5656:   
 5657:   if (bm->process_main_queue)
 5658:     {
 5659:       work_queue_free (bm->process_main_queue);
 5660:       bm->process_main_queue = NULL;
 5661:     }
 5662:   if (bm->process_rsclient_queue)
 5663:     {
 5664:       work_queue_free (bm->process_rsclient_queue);
 5665:       bm->process_rsclient_queue = NULL;
 5666:     }
 5667: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>