File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / bgpd / bgpd.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:26:12 2012 UTC (12 years, 4 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

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

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