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

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

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