Annotation of embedaddon/quagga/bgpd/bgpd.c, revision 1.1.1.1

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

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