File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / bgpd / bgpd.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jul 21 23:54:38 2013 UTC (10 years, 11 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, HEAD
0.99.22

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

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