File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / bgpd / bgpd.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Oct 9 09:22:28 2012 UTC (11 years, 9 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_21, HEAD
quagga

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

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