LCOV - code coverage report
Current view: top level - bgpd - bgp_route.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 51 4775 1.1 %
Date: 2015-11-19 Functions: 6 300 2.0 %

          Line data    Source code
       1             : /* BGP routing information
       2             :    Copyright (C) 1996, 97, 98, 99 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 "linklist.h"
      25             : #include "memory.h"
      26             : #include "command.h"
      27             : #include "stream.h"
      28             : #include "filter.h"
      29             : #include "str.h"
      30             : #include "log.h"
      31             : #include "routemap.h"
      32             : #include "buffer.h"
      33             : #include "sockunion.h"
      34             : #include "plist.h"
      35             : #include "thread.h"
      36             : #include "workqueue.h"
      37             : 
      38             : #include "bgpd/bgpd.h"
      39             : #include "bgpd/bgp_table.h"
      40             : #include "bgpd/bgp_route.h"
      41             : #include "bgpd/bgp_attr.h"
      42             : #include "bgpd/bgp_debug.h"
      43             : #include "bgpd/bgp_aspath.h"
      44             : #include "bgpd/bgp_regex.h"
      45             : #include "bgpd/bgp_community.h"
      46             : #include "bgpd/bgp_ecommunity.h"
      47             : #include "bgpd/bgp_clist.h"
      48             : #include "bgpd/bgp_packet.h"
      49             : #include "bgpd/bgp_filter.h"
      50             : #include "bgpd/bgp_fsm.h"
      51             : #include "bgpd/bgp_mplsvpn.h"
      52             : #include "bgpd/bgp_nexthop.h"
      53             : #include "bgpd/bgp_damp.h"
      54             : #include "bgpd/bgp_advertise.h"
      55             : #include "bgpd/bgp_zebra.h"
      56             : #include "bgpd/bgp_vty.h"
      57             : #include "bgpd/bgp_mpath.h"
      58             : 
      59             : /* Extern from bgp_dump.c */
      60             : extern const char *bgp_origin_str[];
      61             : extern const char *bgp_origin_long_str[];
      62             : 
      63             : static struct bgp_node *
      64           0 : bgp_afi_node_get (struct bgp_table *table, afi_t afi, safi_t safi, struct prefix *p,
      65             :                   struct prefix_rd *prd)
      66             : {
      67             :   struct bgp_node *rn;
      68           0 :   struct bgp_node *prn = NULL;
      69             :   
      70           0 :   assert (table);
      71           0 :   if (!table)
      72           0 :     return NULL;
      73             :   
      74           0 :   if (safi == SAFI_MPLS_VPN)
      75             :     {
      76           0 :       prn = bgp_node_get (table, (struct prefix *) prd);
      77             : 
      78           0 :       if (prn->info == NULL)
      79           0 :         prn->info = bgp_table_init (afi, safi);
      80             :       else
      81           0 :         bgp_unlock_node (prn);
      82           0 :       table = prn->info;
      83             :     }
      84             : 
      85           0 :   rn = bgp_node_get (table, p);
      86             : 
      87           0 :   if (safi == SAFI_MPLS_VPN)
      88           0 :     rn->prn = prn;
      89             : 
      90           0 :   return rn;
      91             : }
      92             : 
      93             : /* Allocate bgp_info_extra */
      94             : static struct bgp_info_extra *
      95           0 : bgp_info_extra_new (void)
      96             : {
      97             :   struct bgp_info_extra *new;
      98           0 :   new = XCALLOC (MTYPE_BGP_ROUTE_EXTRA, sizeof (struct bgp_info_extra));
      99           0 :   return new;
     100             : }
     101             : 
     102             : static void
     103           0 : bgp_info_extra_free (struct bgp_info_extra **extra)
     104             : {
     105           0 :   if (extra && *extra)
     106             :     {
     107           0 :       if ((*extra)->damp_info)
     108           0 :         bgp_damp_info_free ((*extra)->damp_info, 0);
     109             :       
     110           0 :       (*extra)->damp_info = NULL;
     111             :       
     112           0 :       XFREE (MTYPE_BGP_ROUTE_EXTRA, *extra);
     113             :       
     114           0 :       *extra = NULL;
     115             :     }
     116           0 : }
     117             : 
     118             : /* Get bgp_info extra information for the given bgp_info, lazy allocated
     119             :  * if required.
     120             :  */
     121             : struct bgp_info_extra *
     122           0 : bgp_info_extra_get (struct bgp_info *ri)
     123             : {
     124           0 :   if (!ri->extra)
     125           0 :     ri->extra = bgp_info_extra_new();
     126           0 :   return ri->extra;
     127             : }
     128             : 
     129             : /* Allocate new bgp info structure. */
     130             : static struct bgp_info *
     131           0 : bgp_info_new (void)
     132             : {
     133           0 :   return XCALLOC (MTYPE_BGP_ROUTE, sizeof (struct bgp_info));
     134             : }
     135             : 
     136             : /* Free bgp route information. */
     137             : static void
     138           0 : bgp_info_free (struct bgp_info *binfo)
     139             : {
     140           0 :   if (binfo->attr)
     141           0 :     bgp_attr_unintern (&binfo->attr);
     142             :   
     143           0 :   bgp_info_extra_free (&binfo->extra);
     144           0 :   bgp_info_mpath_free (&binfo->mpath);
     145             : 
     146           0 :   peer_unlock (binfo->peer); /* bgp_info peer reference */
     147             : 
     148           0 :   XFREE (MTYPE_BGP_ROUTE, binfo);
     149           0 : }
     150             : 
     151             : struct bgp_info *
     152           5 : bgp_info_lock (struct bgp_info *binfo)
     153             : {
     154           5 :   binfo->lock++;
     155           5 :   return binfo;
     156             : }
     157             : 
     158             : struct bgp_info *
     159           0 : bgp_info_unlock (struct bgp_info *binfo)
     160             : {
     161           0 :   assert (binfo && binfo->lock > 0);
     162           0 :   binfo->lock--;
     163             :   
     164           0 :   if (binfo->lock == 0)
     165             :     {
     166             : #if 0
     167             :       zlog_debug ("%s: unlocked and freeing", __func__);
     168             :       zlog_backtrace (LOG_DEBUG);
     169             : #endif
     170           0 :       bgp_info_free (binfo);
     171           0 :       return NULL;
     172             :     }
     173             : 
     174             : #if 0
     175             :   if (binfo->lock == 1)
     176             :     {
     177             :       zlog_debug ("%s: unlocked to 1", __func__);
     178             :       zlog_backtrace (LOG_DEBUG);
     179             :     }
     180             : #endif
     181             :   
     182           0 :   return binfo;
     183             : }
     184             : 
     185             : void
     186           5 : bgp_info_add (struct bgp_node *rn, struct bgp_info *ri)
     187             : {
     188             :   struct bgp_info *top;
     189             : 
     190           5 :   top = rn->info;
     191             :   
     192           5 :   ri->next = rn->info;
     193           5 :   ri->prev = NULL;
     194           5 :   if (top)
     195           4 :     top->prev = ri;
     196           5 :   rn->info = ri;
     197             :   
     198           5 :   bgp_info_lock (ri);
     199           5 :   bgp_lock_node (rn);
     200           5 :   peer_lock (ri->peer); /* bgp_info peer reference */
     201           5 : }
     202             : 
     203             : /* Do the actual removal of info from RIB, for use by bgp_process 
     204             :    completion callback *only* */
     205             : static void
     206           0 : bgp_info_reap (struct bgp_node *rn, struct bgp_info *ri)
     207             : {
     208           0 :   if (ri->next)
     209           0 :     ri->next->prev = ri->prev;
     210           0 :   if (ri->prev)
     211           0 :     ri->prev->next = ri->next;
     212             :   else
     213           0 :     rn->info = ri->next;
     214             :   
     215           0 :   bgp_info_mpath_dequeue (ri);
     216           0 :   bgp_info_unlock (ri);
     217           0 :   bgp_unlock_node (rn);
     218           0 : }
     219             : 
     220             : void
     221           0 : bgp_info_delete (struct bgp_node *rn, struct bgp_info *ri)
     222             : {
     223           0 :   bgp_info_set_flag (rn, ri, BGP_INFO_REMOVED);
     224             :   /* set of previous already took care of pcount */
     225           0 :   UNSET_FLAG (ri->flags, BGP_INFO_VALID);
     226           0 : }
     227             : 
     228             : /* undo the effects of a previous call to bgp_info_delete; typically
     229             :    called when a route is deleted and then quickly re-added before the
     230             :    deletion has been processed */
     231             : static void
     232           0 : bgp_info_restore (struct bgp_node *rn, struct bgp_info *ri)
     233             : {
     234           0 :   bgp_info_unset_flag (rn, ri, BGP_INFO_REMOVED);
     235             :   /* unset of previous already took care of pcount */
     236           0 :   SET_FLAG (ri->flags, BGP_INFO_VALID);
     237           0 : }
     238             : 
     239             : /* Adjust pcount as required */   
     240             : static void
     241           0 : bgp_pcount_adjust (struct bgp_node *rn, struct bgp_info *ri)
     242             : {
     243             :   struct bgp_table *table;
     244             : 
     245           0 :   assert (rn && bgp_node_table (rn));
     246           0 :   assert (ri && ri->peer && ri->peer->bgp);
     247             : 
     248           0 :   table = bgp_node_table (rn);
     249             : 
     250             :   /* Ignore 'pcount' for RS-client tables */
     251           0 :   if (table->type != BGP_TABLE_MAIN
     252           0 :       || ri->peer == ri->peer->bgp->peer_self)
     253           0 :     return;
     254             :     
     255           0 :   if (BGP_INFO_HOLDDOWN (ri)
     256           0 :       && CHECK_FLAG (ri->flags, BGP_INFO_COUNTED))
     257             :     {
     258             :           
     259           0 :       UNSET_FLAG (ri->flags, BGP_INFO_COUNTED);
     260             :       
     261             :       /* slight hack, but more robust against errors. */
     262           0 :       if (ri->peer->pcount[table->afi][table->safi])
     263           0 :         ri->peer->pcount[table->afi][table->safi]--;
     264             :       else
     265             :         {
     266           0 :           zlog_warn ("%s: Asked to decrement 0 prefix count for peer %s",
     267           0 :                      __func__, ri->peer->host);
     268           0 :           zlog_backtrace (LOG_WARNING);
     269           0 :           zlog_warn ("%s: Please report to Quagga bugzilla", __func__);
     270             :         }      
     271             :     }
     272           0 :   else if (!BGP_INFO_HOLDDOWN (ri) 
     273           0 :            && !CHECK_FLAG (ri->flags, BGP_INFO_COUNTED))
     274             :     {
     275           0 :       SET_FLAG (ri->flags, BGP_INFO_COUNTED);
     276           0 :       ri->peer->pcount[table->afi][table->safi]++;
     277             :     }
     278             : }
     279             : 
     280             : 
     281             : /* Set/unset bgp_info flags, adjusting any other state as needed.
     282             :  * This is here primarily to keep prefix-count in check.
     283             :  */
     284             : void
     285           0 : bgp_info_set_flag (struct bgp_node *rn, struct bgp_info *ri, u_int32_t flag)
     286             : {
     287           0 :   SET_FLAG (ri->flags, flag);
     288             :   
     289             :   /* early bath if we know it's not a flag that changes useability state */
     290           0 :   if (!CHECK_FLAG (flag, BGP_INFO_VALID|BGP_INFO_UNUSEABLE))
     291           0 :     return;
     292             :   
     293           0 :   bgp_pcount_adjust (rn, ri);
     294             : }
     295             : 
     296             : void
     297           0 : bgp_info_unset_flag (struct bgp_node *rn, struct bgp_info *ri, u_int32_t flag)
     298             : {
     299           0 :   UNSET_FLAG (ri->flags, flag);
     300             :   
     301             :   /* early bath if we know it's not a flag that changes useability state */
     302           0 :   if (!CHECK_FLAG (flag, BGP_INFO_VALID|BGP_INFO_UNUSEABLE))
     303           0 :     return;
     304             :   
     305           0 :   bgp_pcount_adjust (rn, ri);
     306             : }
     307             : 
     308             : /* Get MED value.  If MED value is missing and "bgp bestpath
     309             :    missing-as-worst" is specified, treat it as the worst value. */
     310             : static u_int32_t
     311           0 : bgp_med_value (struct attr *attr, struct bgp *bgp)
     312             : {
     313           0 :   if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
     314           0 :     return attr->med;
     315             :   else
     316             :     {
     317           0 :       if (bgp_flag_check (bgp, BGP_FLAG_MED_MISSING_AS_WORST))
     318           0 :         return BGP_MED_MAX;
     319             :       else
     320           0 :         return 0;
     321             :     }
     322             : }
     323             : 
     324             : /* Compare two bgp route entity.  br is preferable then return 1. */
     325             : static int
     326           0 : bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist,
     327             :               int *paths_eq)
     328             : {
     329             :   struct attr *newattr, *existattr;
     330             :   struct attr_extra *newattre, *existattre;
     331             :   bgp_peer_sort_t new_sort;
     332             :   bgp_peer_sort_t exist_sort;
     333             :   u_int32_t new_pref;
     334             :   u_int32_t exist_pref;
     335             :   u_int32_t new_med;
     336             :   u_int32_t exist_med;
     337             :   u_int32_t new_weight;
     338             :   u_int32_t exist_weight;
     339             :   uint32_t newm, existm;
     340             :   struct in_addr new_id;
     341             :   struct in_addr exist_id;
     342             :   int new_cluster;
     343             :   int exist_cluster;
     344             :   int internal_as_route;
     345             :   int confed_as_route;
     346             :   int ret;
     347             : 
     348           0 :   *paths_eq = 0;
     349             : 
     350             :   /* 0. Null check. */
     351           0 :   if (new == NULL)
     352           0 :     return 0;
     353           0 :   if (exist == NULL)
     354           0 :     return 1;
     355             : 
     356           0 :   newattr = new->attr;
     357           0 :   existattr = exist->attr;
     358           0 :   newattre = newattr->extra;
     359           0 :   existattre = existattr->extra;
     360             : 
     361             :   /* 1. Weight check. */
     362           0 :   new_weight = exist_weight = 0;
     363             : 
     364           0 :   if (newattre)
     365           0 :     new_weight = newattre->weight;
     366           0 :   if (existattre)
     367           0 :     exist_weight = existattre->weight;
     368             : 
     369           0 :   if (new_weight > exist_weight)
     370           0 :     return 1;
     371           0 :   if (new_weight < exist_weight)
     372           0 :     return 0;
     373             : 
     374             :   /* 2. Local preference check. */
     375           0 :   new_pref = exist_pref = bgp->default_local_pref;
     376             : 
     377           0 :   if (newattr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
     378           0 :     new_pref = newattr->local_pref;
     379           0 :   if (existattr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
     380           0 :     exist_pref = existattr->local_pref;
     381             : 
     382           0 :   if (new_pref > exist_pref)
     383           0 :     return 1;
     384           0 :   if (new_pref < exist_pref)
     385           0 :     return 0;
     386             : 
     387             :   /* 3. Local route check. We prefer:
     388             :    *  - BGP_ROUTE_STATIC
     389             :    *  - BGP_ROUTE_AGGREGATE
     390             :    *  - BGP_ROUTE_REDISTRIBUTE
     391             :    */
     392           0 :   if (! (new->sub_type == BGP_ROUTE_NORMAL))
     393           0 :      return 1;
     394           0 :   if (! (exist->sub_type == BGP_ROUTE_NORMAL))
     395           0 :      return 0;
     396             : 
     397             :   /* 4. AS path length check. */
     398           0 :   if (! bgp_flag_check (bgp, BGP_FLAG_ASPATH_IGNORE))
     399             :     {
     400           0 :       int exist_hops = aspath_count_hops (existattr->aspath);
     401           0 :       int exist_confeds = aspath_count_confeds (existattr->aspath);
     402             :       
     403           0 :       if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_CONFED))
     404             :         {
     405             :           int aspath_hops;
     406             :           
     407           0 :           aspath_hops = aspath_count_hops (newattr->aspath);
     408           0 :           aspath_hops += aspath_count_confeds (newattr->aspath);
     409             :           
     410           0 :           if ( aspath_hops < (exist_hops + exist_confeds))
     411           0 :             return 1;
     412           0 :           if ( aspath_hops > (exist_hops + exist_confeds))
     413           0 :             return 0;
     414             :         }
     415             :       else
     416             :         {
     417           0 :           int newhops = aspath_count_hops (newattr->aspath);
     418             :           
     419           0 :           if (newhops < exist_hops)
     420           0 :             return 1;
     421           0 :           if (newhops > exist_hops)
     422           0 :             return 0;
     423             :         }
     424             :     }
     425             : 
     426             :   /* 5. Origin check. */
     427           0 :   if (newattr->origin < existattr->origin)
     428           0 :     return 1;
     429           0 :   if (newattr->origin > existattr->origin)
     430           0 :     return 0;
     431             : 
     432             :   /* 6. MED check. */
     433           0 :   internal_as_route = (aspath_count_hops (newattr->aspath) == 0
     434           0 :                       && aspath_count_hops (existattr->aspath) == 0);
     435           0 :   confed_as_route = (aspath_count_confeds (newattr->aspath) > 0
     436           0 :                     && aspath_count_confeds (existattr->aspath) > 0
     437           0 :                     && aspath_count_hops (newattr->aspath) == 0
     438           0 :                     && aspath_count_hops (existattr->aspath) == 0);
     439             :   
     440           0 :   if (bgp_flag_check (bgp, BGP_FLAG_ALWAYS_COMPARE_MED)
     441           0 :       || (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED)
     442           0 :          && confed_as_route)
     443           0 :       || aspath_cmp_left (newattr->aspath, existattr->aspath)
     444           0 :       || aspath_cmp_left_confed (newattr->aspath, existattr->aspath)
     445           0 :       || internal_as_route)
     446             :     {
     447           0 :       new_med = bgp_med_value (new->attr, bgp);
     448           0 :       exist_med = bgp_med_value (exist->attr, bgp);
     449             : 
     450           0 :       if (new_med < exist_med)
     451           0 :         return 1;
     452           0 :       if (new_med > exist_med)
     453           0 :         return 0;
     454             :     }
     455             : 
     456             :   /* 7. Peer type check. */
     457           0 :   new_sort = new->peer->sort;
     458           0 :   exist_sort = exist->peer->sort;
     459             : 
     460           0 :   if (new_sort == BGP_PEER_EBGP
     461           0 :       && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED))
     462           0 :     return 1;
     463           0 :   if (exist_sort == BGP_PEER_EBGP
     464           0 :       && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED))
     465           0 :     return 0;
     466             : 
     467             :   /* 8. IGP metric check. */
     468           0 :   newm = existm = 0;
     469             : 
     470           0 :   if (new->extra)
     471           0 :     newm = new->extra->igpmetric;
     472           0 :   if (exist->extra)
     473           0 :     existm = exist->extra->igpmetric;
     474             : 
     475           0 :   if (newm < existm)
     476           0 :     ret = 1;
     477           0 :   if (newm > existm)
     478           0 :     ret = 0;
     479             : 
     480             :   /* 9. Maximum path check. */
     481           0 :   if (newm == existm)
     482             :     {
     483           0 :       if (new->peer->sort == BGP_PEER_IBGP)
     484             :         {
     485           0 :           if (aspath_cmp (new->attr->aspath, exist->attr->aspath))
     486           0 :             *paths_eq = 1;
     487             :         }
     488           0 :       else if (new->peer->as == exist->peer->as)
     489           0 :         *paths_eq = 1;
     490             :     }
     491             :   else
     492             :     {
     493             :       /*
     494             :        * TODO: If unequal cost ibgp multipath is enabled we can
     495             :        * mark the paths as equal here instead of returning
     496             :        */
     497           0 :       return ret;
     498             :     }
     499             : 
     500             :   /* 10. If both paths are external, prefer the path that was received
     501             :      first (the oldest one).  This step minimizes route-flap, since a
     502             :      newer path won't displace an older one, even if it was the
     503             :      preferred route based on the additional decision criteria below.  */
     504           0 :   if (! bgp_flag_check (bgp, BGP_FLAG_COMPARE_ROUTER_ID)
     505           0 :       && new_sort == BGP_PEER_EBGP
     506           0 :       && exist_sort == BGP_PEER_EBGP)
     507             :     {
     508           0 :       if (CHECK_FLAG (new->flags, BGP_INFO_SELECTED))
     509           0 :         return 1;
     510           0 :       if (CHECK_FLAG (exist->flags, BGP_INFO_SELECTED))
     511           0 :         return 0;
     512             :     }
     513             : 
     514             :   /* 11. Rourter-ID comparision. */
     515           0 :   if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
     516           0 :     new_id.s_addr = newattre->originator_id.s_addr;
     517             :   else
     518           0 :     new_id.s_addr = new->peer->remote_id.s_addr;
     519           0 :   if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
     520           0 :     exist_id.s_addr = existattre->originator_id.s_addr;
     521             :   else
     522           0 :     exist_id.s_addr = exist->peer->remote_id.s_addr;
     523             : 
     524           0 :   if (ntohl (new_id.s_addr) < ntohl (exist_id.s_addr))
     525           0 :     return 1;
     526           0 :   if (ntohl (new_id.s_addr) > ntohl (exist_id.s_addr))
     527           0 :     return 0;
     528             : 
     529             :   /* 12. Cluster length comparision. */
     530           0 :   new_cluster = exist_cluster = 0;
     531             : 
     532           0 :   if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))
     533           0 :     new_cluster = newattre->cluster->length;
     534           0 :   if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))
     535           0 :     exist_cluster = existattre->cluster->length;
     536             : 
     537           0 :   if (new_cluster < exist_cluster)
     538           0 :     return 1;
     539           0 :   if (new_cluster > exist_cluster)
     540           0 :     return 0;
     541             : 
     542             :   /* 13. Neighbor address comparision. */
     543           0 :   ret = sockunion_cmp (new->peer->su_remote, exist->peer->su_remote);
     544             : 
     545           0 :   if (ret == 1)
     546           0 :     return 0;
     547           0 :   if (ret == -1)
     548           0 :     return 1;
     549             : 
     550           0 :   return 1;
     551             : }
     552             : 
     553             : static enum filter_type
     554           0 : bgp_input_filter (struct peer *peer, struct prefix *p, struct attr *attr,
     555             :                   afi_t afi, safi_t safi)
     556             : {
     557             :   struct bgp_filter *filter;
     558             : 
     559           0 :   filter = &peer->filter[afi][safi];
     560             : 
     561             : #define FILTER_EXIST_WARN(F,f,filter) \
     562             :   if (BGP_DEBUG (update, UPDATE_IN) \
     563             :       && !(F ## _IN (filter))) \
     564             :     plog_warn (peer->log, "%s: Could not find configured input %s-list %s!", \
     565             :                peer->host, #f, F ## _IN_NAME(filter));
     566             :   
     567           0 :   if (DISTRIBUTE_IN_NAME (filter)) {
     568           0 :     FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
     569             :       
     570           0 :     if (access_list_apply (DISTRIBUTE_IN (filter), p) == FILTER_DENY)
     571           0 :       return FILTER_DENY;
     572             :   }
     573             : 
     574           0 :   if (PREFIX_LIST_IN_NAME (filter)) {
     575           0 :     FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
     576             :     
     577           0 :     if (prefix_list_apply (PREFIX_LIST_IN (filter), p) == PREFIX_DENY)
     578           0 :       return FILTER_DENY;
     579             :   }
     580             :   
     581           0 :   if (FILTER_LIST_IN_NAME (filter)) {
     582           0 :     FILTER_EXIST_WARN(FILTER_LIST, as, filter);
     583             :     
     584           0 :     if (as_list_apply (FILTER_LIST_IN (filter), attr->aspath)== AS_FILTER_DENY)
     585           0 :       return FILTER_DENY;
     586             :   }
     587             :   
     588           0 :   return FILTER_PERMIT;
     589             : #undef FILTER_EXIST_WARN
     590             : }
     591             : 
     592             : static enum filter_type
     593           0 : bgp_output_filter (struct peer *peer, struct prefix *p, struct attr *attr,
     594             :                    afi_t afi, safi_t safi)
     595             : {
     596             :   struct bgp_filter *filter;
     597             : 
     598           0 :   filter = &peer->filter[afi][safi];
     599             : 
     600             : #define FILTER_EXIST_WARN(F,f,filter) \
     601             :   if (BGP_DEBUG (update, UPDATE_OUT) \
     602             :       && !(F ## _OUT (filter))) \
     603             :     plog_warn (peer->log, "%s: Could not find configured output %s-list %s!", \
     604             :                peer->host, #f, F ## _OUT_NAME(filter));
     605             : 
     606           0 :   if (DISTRIBUTE_OUT_NAME (filter)) {
     607           0 :     FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
     608             :     
     609           0 :     if (access_list_apply (DISTRIBUTE_OUT (filter), p) == FILTER_DENY)
     610           0 :       return FILTER_DENY;
     611             :   }
     612             : 
     613           0 :   if (PREFIX_LIST_OUT_NAME (filter)) {
     614           0 :     FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
     615             :     
     616           0 :     if (prefix_list_apply (PREFIX_LIST_OUT (filter), p) == PREFIX_DENY)
     617           0 :       return FILTER_DENY;
     618             :   }
     619             : 
     620           0 :   if (FILTER_LIST_OUT_NAME (filter)) {
     621           0 :     FILTER_EXIST_WARN(FILTER_LIST, as, filter);
     622             :     
     623           0 :     if (as_list_apply (FILTER_LIST_OUT (filter), attr->aspath) == AS_FILTER_DENY)
     624           0 :       return FILTER_DENY;
     625             :   }
     626             : 
     627           0 :   return FILTER_PERMIT;
     628             : #undef FILTER_EXIST_WARN
     629             : }
     630             : 
     631             : /* If community attribute includes no_export then return 1. */
     632             : static int
     633           0 : bgp_community_filter (struct peer *peer, struct attr *attr)
     634             : {
     635           0 :   if (attr->community)
     636             :     {
     637             :       /* NO_ADVERTISE check. */
     638           0 :       if (community_include (attr->community, COMMUNITY_NO_ADVERTISE))
     639           0 :         return 1;
     640             : 
     641             :       /* NO_EXPORT check. */
     642           0 :       if (peer->sort == BGP_PEER_EBGP &&
     643           0 :           community_include (attr->community, COMMUNITY_NO_EXPORT))
     644           0 :         return 1;
     645             : 
     646             :       /* NO_EXPORT_SUBCONFED check. */
     647           0 :       if (peer->sort == BGP_PEER_EBGP
     648           0 :           || peer->sort == BGP_PEER_CONFED)
     649           0 :         if (community_include (attr->community, COMMUNITY_NO_EXPORT_SUBCONFED))
     650           0 :           return 1;
     651             :     }
     652           0 :   return 0;
     653             : }
     654             : 
     655             : /* Route reflection loop check.  */
     656             : static int
     657           0 : bgp_cluster_filter (struct peer *peer, struct attr *attr)
     658             : {
     659             :   struct in_addr cluster_id;
     660             : 
     661           0 :   if (attr->extra && attr->extra->cluster)
     662             :     {
     663           0 :       if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
     664           0 :         cluster_id = peer->bgp->cluster_id;
     665             :       else
     666           0 :         cluster_id = peer->bgp->router_id;
     667             :       
     668           0 :       if (cluster_loop_check (attr->extra->cluster, cluster_id))
     669           0 :         return 1;
     670             :     }
     671           0 :   return 0;
     672             : }
     673             : 
     674             : static int
     675           0 : bgp_input_modifier (struct peer *peer, struct prefix *p, struct attr *attr,
     676             :                     afi_t afi, safi_t safi)
     677             : {
     678             :   struct bgp_filter *filter;
     679             :   struct bgp_info info;
     680             :   route_map_result_t ret;
     681             : 
     682           0 :   filter = &peer->filter[afi][safi];
     683             : 
     684             :   /* Apply default weight value. */
     685           0 :   if (peer->weight)
     686           0 :     (bgp_attr_extra_get (attr))->weight = peer->weight;
     687             : 
     688             :   /* Route map apply. */
     689           0 :   if (ROUTE_MAP_IN_NAME (filter))
     690             :     {
     691             :       /* Duplicate current value to new strucutre for modification. */
     692           0 :       info.peer = peer;
     693           0 :       info.attr = attr;
     694             : 
     695           0 :       SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN); 
     696             : 
     697             :       /* Apply BGP route map to the attribute. */
     698           0 :       ret = route_map_apply (ROUTE_MAP_IN (filter), p, RMAP_BGP, &info);
     699             : 
     700           0 :       peer->rmap_type = 0;
     701             : 
     702           0 :       if (ret == RMAP_DENYMATCH)
     703             :         {
     704             :           /* Free newly generated AS path and community by route-map. */
     705           0 :           bgp_attr_flush (attr);
     706           0 :           return RMAP_DENY;
     707             :         }
     708             :     }
     709           0 :   return RMAP_PERMIT;
     710             : }
     711             : 
     712             : static int
     713           0 : bgp_export_modifier (struct peer *rsclient, struct peer *peer,
     714             :         struct prefix *p, struct attr *attr, afi_t afi, safi_t safi)
     715             : {
     716             :   struct bgp_filter *filter;
     717             :   struct bgp_info info;
     718             :   route_map_result_t ret;
     719             : 
     720           0 :   filter = &peer->filter[afi][safi];
     721             : 
     722             :   /* Route map apply. */
     723           0 :   if (ROUTE_MAP_EXPORT_NAME (filter))
     724             :     {
     725             :       /* Duplicate current value to new strucutre for modification. */
     726           0 :       info.peer = rsclient;
     727           0 :       info.attr = attr;
     728             : 
     729           0 :       SET_FLAG (rsclient->rmap_type, PEER_RMAP_TYPE_EXPORT);
     730             : 
     731             :       /* Apply BGP route map to the attribute. */
     732           0 :       ret = route_map_apply (ROUTE_MAP_EXPORT (filter), p, RMAP_BGP, &info);
     733             : 
     734           0 :       rsclient->rmap_type = 0;
     735             : 
     736           0 :       if (ret == RMAP_DENYMATCH)
     737             :         {
     738             :           /* Free newly generated AS path and community by route-map. */
     739           0 :           bgp_attr_flush (attr);
     740           0 :           return RMAP_DENY;
     741             :         }
     742             :     }
     743           0 :   return RMAP_PERMIT;
     744             : }
     745             : 
     746             : static int
     747           0 : bgp_import_modifier (struct peer *rsclient, struct peer *peer,
     748             :         struct prefix *p, struct attr *attr, afi_t afi, safi_t safi)
     749             : {
     750             :   struct bgp_filter *filter;
     751             :   struct bgp_info info;
     752             :   route_map_result_t ret;
     753             : 
     754           0 :   filter = &rsclient->filter[afi][safi];
     755             : 
     756             :   /* Apply default weight value. */
     757           0 :   if (peer->weight)
     758           0 :     (bgp_attr_extra_get (attr))->weight = peer->weight;
     759             : 
     760             :   /* Route map apply. */
     761           0 :   if (ROUTE_MAP_IMPORT_NAME (filter))
     762             :     {
     763             :       /* Duplicate current value to new strucutre for modification. */
     764           0 :       info.peer = peer;
     765           0 :       info.attr = attr;
     766             : 
     767           0 :       SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT);
     768             : 
     769             :       /* Apply BGP route map to the attribute. */
     770           0 :       ret = route_map_apply (ROUTE_MAP_IMPORT (filter), p, RMAP_BGP, &info);
     771             : 
     772           0 :       peer->rmap_type = 0;
     773             : 
     774           0 :       if (ret == RMAP_DENYMATCH)
     775             :         {
     776             :           /* Free newly generated AS path and community by route-map. */
     777           0 :           bgp_attr_flush (attr);
     778           0 :           return RMAP_DENY;
     779             :         }
     780             :     }
     781           0 :   return RMAP_PERMIT;
     782             : }
     783             : 
     784             : static int
     785           0 : bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
     786             :                     struct attr *attr, afi_t afi, safi_t safi)
     787             : {
     788             :   int ret;
     789             :   char buf[SU_ADDRSTRLEN];
     790             :   struct bgp_filter *filter;
     791             :   struct peer *from;
     792             :   struct bgp *bgp;
     793             :   int transparent;
     794             :   int reflect;
     795             :   struct attr *riattr;
     796             : 
     797           0 :   from = ri->peer;
     798           0 :   filter = &peer->filter[afi][safi];
     799           0 :   bgp = peer->bgp;
     800           0 :   riattr = bgp_info_mpath_count (ri) ? bgp_info_mpath_attr (ri) : ri->attr;
     801             :   
     802             :   if (DISABLE_BGP_ANNOUNCE)
     803             :     return 0;
     804             : 
     805             :   /* Do not send announces to RS-clients from the 'normal' bgp_table. */
     806           0 :   if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
     807           0 :     return 0;
     808             : 
     809             :   /* Do not send back route to sender. */
     810           0 :   if (from == peer)
     811           0 :     return 0;
     812             : 
     813             :   /* If peer's id and route's nexthop are same. draft-ietf-idr-bgp4-23 5.1.3 */
     814           0 :   if (p->family == AF_INET
     815           0 :       && IPV4_ADDR_SAME(&peer->remote_id, &riattr->nexthop))
     816           0 :     return 0;
     817             : #ifdef HAVE_IPV6
     818           0 :   if (p->family == AF_INET6
     819           0 :      && IPV6_ADDR_SAME(&peer->remote_id, &riattr->nexthop))
     820           0 :     return 0;
     821             : #endif
     822             : 
     823             :   /* Aggregate-address suppress check. */
     824           0 :   if (ri->extra && ri->extra->suppress)
     825           0 :     if (! UNSUPPRESS_MAP_NAME (filter))
     826           0 :       return 0;
     827             : 
     828             :   /* Default route check.  */
     829           0 :   if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE))
     830             :     {
     831           0 :       if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
     832           0 :         return 0;
     833             : #ifdef HAVE_IPV6
     834           0 :       else if (p->family == AF_INET6 && p->prefixlen == 0)
     835           0 :         return 0;
     836             : #endif /* HAVE_IPV6 */
     837             :     }
     838             : 
     839             :   /* Transparency check. */
     840           0 :   if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
     841           0 :       && CHECK_FLAG (from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
     842           0 :     transparent = 1;
     843             :   else
     844           0 :     transparent = 0;
     845             : 
     846             :   /* If community is not disabled check the no-export and local. */
     847           0 :   if (! transparent && bgp_community_filter (peer, riattr))
     848           0 :     return 0;
     849             : 
     850             :   /* If the attribute has originator-id and it is same as remote
     851             :      peer's id. */
     852           0 :   if (riattr->flag & ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID))
     853             :     {
     854           0 :       if (IPV4_ADDR_SAME (&peer->remote_id, &riattr->extra->originator_id))
     855             :         {
     856           0 :           if (BGP_DEBUG (filter, FILTER))  
     857           0 :             zlog (peer->log, LOG_DEBUG,
     858             :                   "%s [Update:SEND] %s/%d originator-id is same as remote router-id",
     859             :                   peer->host,
     860           0 :                   inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
     861           0 :                   p->prefixlen);
     862           0 :           return 0;
     863             :         }
     864             :     }
     865             :  
     866             :   /* ORF prefix-list filter check */
     867           0 :   if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
     868           0 :       && (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
     869           0 :           || CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
     870           0 :     if (peer->orf_plist[afi][safi])
     871             :       {
     872           0 :         if (prefix_list_apply (peer->orf_plist[afi][safi], p) == PREFIX_DENY)
     873           0 :           return 0;
     874             :       }
     875             : 
     876             :   /* Output filter check. */
     877           0 :   if (bgp_output_filter (peer, p, riattr, afi, safi) == FILTER_DENY)
     878             :     {
     879           0 :       if (BGP_DEBUG (filter, FILTER))
     880           0 :         zlog (peer->log, LOG_DEBUG,
     881             :               "%s [Update:SEND] %s/%d is filtered",
     882             :               peer->host,
     883           0 :               inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
     884           0 :               p->prefixlen);
     885           0 :       return 0;
     886             :     }
     887             : 
     888             : #ifdef BGP_SEND_ASPATH_CHECK
     889             :   /* AS path loop check. */
     890             :   if (aspath_loop_check (riattr->aspath, peer->as))
     891             :     {
     892             :       if (BGP_DEBUG (filter, FILTER))  
     893             :         zlog (peer->log, LOG_DEBUG, 
     894             :               "%s [Update:SEND] suppress announcement to peer AS %u is AS path.",
     895             :               peer->host, peer->as);
     896             :       return 0;
     897             :     }
     898             : #endif /* BGP_SEND_ASPATH_CHECK */
     899             : 
     900             :   /* If we're a CONFED we need to loop check the CONFED ID too */
     901           0 :   if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
     902             :     {
     903           0 :       if (aspath_loop_check(riattr->aspath, bgp->confed_id))
     904             :         {
     905           0 :           if (BGP_DEBUG (filter, FILTER))  
     906           0 :             zlog (peer->log, LOG_DEBUG, 
     907             :                   "%s [Update:SEND] suppress announcement to peer AS %u is AS path.",
     908             :                   peer->host,
     909             :                   bgp->confed_id);
     910           0 :           return 0;
     911             :         }      
     912             :     }
     913             : 
     914             :   /* Route-Reflect check. */
     915           0 :   if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
     916           0 :     reflect = 1;
     917             :   else
     918           0 :     reflect = 0;
     919             : 
     920             :   /* IBGP reflection check. */
     921           0 :   if (reflect)
     922             :     {
     923             :       /* A route from a Client peer. */
     924           0 :       if (CHECK_FLAG (from->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
     925             :         {
     926             :           /* Reflect to all the Non-Client peers and also to the
     927             :              Client peers other than the originator.  Originator check
     928             :              is already done.  So there is noting to do. */
     929             :           /* no bgp client-to-client reflection check. */
     930           0 :           if (bgp_flag_check (bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT))
     931           0 :             if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
     932           0 :               return 0;
     933             :         }
     934             :       else
     935             :         {
     936             :           /* A route from a Non-client peer. Reflect to all other
     937             :              clients. */
     938           0 :           if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
     939           0 :             return 0;
     940             :         }
     941             :     }
     942             :   
     943             :   /* For modify attribute, copy it to temporary structure. */
     944           0 :   bgp_attr_dup (attr, riattr);
     945             :   
     946             :   /* If local-preference is not set. */
     947           0 :   if ((peer->sort == BGP_PEER_IBGP
     948           0 :        || peer->sort == BGP_PEER_CONFED)
     949           0 :       && (! (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))))
     950             :     {
     951           0 :       attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
     952           0 :       attr->local_pref = bgp->default_local_pref;
     953             :     }
     954             : 
     955             :   /* Remove MED if its an EBGP peer - will get overwritten by route-maps */
     956           0 :   if (peer->sort == BGP_PEER_EBGP
     957           0 :       && attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
     958             :     {
     959           0 :       if (ri->peer != bgp->peer_self && ! transparent
     960           0 :           && ! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED))
     961           0 :         attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC));
     962             :     }
     963             : 
     964             :   /* next-hop-set */
     965           0 :   if (transparent || reflect
     966           0 :       || (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
     967           0 :           && ((p->family == AF_INET && attr->nexthop.s_addr)
     968             : #ifdef HAVE_IPV6
     969           0 :               || (p->family == AF_INET6 && 
     970           0 :                   ! IN6_IS_ADDR_UNSPECIFIED(&attr->extra->mp_nexthop_global))
     971             : #endif /* HAVE_IPV6 */
     972             :               )))
     973             :     {
     974             :       /* NEXT-HOP Unchanged. */
     975             :     }
     976           0 :   else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_SELF)
     977           0 :            || (p->family == AF_INET && attr->nexthop.s_addr == 0)
     978             : #ifdef HAVE_IPV6
     979           0 :            || (p->family == AF_INET6 && 
     980           0 :                IN6_IS_ADDR_UNSPECIFIED(&attr->extra->mp_nexthop_global))
     981             : #endif /* HAVE_IPV6 */
     982           0 :            || (peer->sort == BGP_PEER_EBGP
     983           0 :                && bgp_multiaccess_check_v4 (attr->nexthop, peer->host) == 0))
     984             :     {
     985             :       /* Set IPv4 nexthop. */
     986           0 :       if (p->family == AF_INET)
     987             :         {
     988           0 :           if (safi == SAFI_MPLS_VPN)
     989           0 :             memcpy (&attr->extra->mp_nexthop_global_in, &peer->nexthop.v4,
     990             :                     IPV4_MAX_BYTELEN);
     991             :           else
     992           0 :             memcpy (&attr->nexthop, &peer->nexthop.v4, IPV4_MAX_BYTELEN);
     993             :         }
     994             : #ifdef HAVE_IPV6
     995             :       /* Set IPv6 nexthop. */
     996           0 :       if (p->family == AF_INET6)
     997             :         {
     998             :           /* IPv6 global nexthop must be included. */
     999           0 :           memcpy (&attr->extra->mp_nexthop_global, &peer->nexthop.v6_global, 
    1000             :                   IPV6_MAX_BYTELEN);
    1001           0 :           attr->extra->mp_nexthop_len = 16;
    1002             :         }
    1003             : #endif /* HAVE_IPV6 */
    1004             :     }
    1005             : 
    1006             : #ifdef HAVE_IPV6
    1007           0 :   if (p->family == AF_INET6)
    1008             :     {
    1009             :       /* Left nexthop_local unchanged if so configured. */ 
    1010           0 :       if ( CHECK_FLAG (peer->af_flags[afi][safi], 
    1011             :            PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED) )
    1012             :         {
    1013           0 :           if ( IN6_IS_ADDR_LINKLOCAL (&attr->extra->mp_nexthop_local) )
    1014           0 :             attr->extra->mp_nexthop_len=32;
    1015             :           else
    1016           0 :             attr->extra->mp_nexthop_len=16;
    1017             :         }
    1018             : 
    1019             :       /* Default nexthop_local treatment for non-RS-Clients */
    1020             :       else 
    1021             :         {
    1022             :       /* Link-local address should not be transit to different peer. */
    1023           0 :       attr->extra->mp_nexthop_len = 16;
    1024             : 
    1025             :       /* Set link-local address for shared network peer. */
    1026           0 :       if (peer->shared_network 
    1027           0 :           && ! IN6_IS_ADDR_UNSPECIFIED (&peer->nexthop.v6_local))
    1028             :         {
    1029           0 :           memcpy (&attr->extra->mp_nexthop_local, &peer->nexthop.v6_local, 
    1030             :                   IPV6_MAX_BYTELEN);
    1031           0 :           attr->extra->mp_nexthop_len = 32;
    1032             :         }
    1033             : 
    1034             :       /* If bgpd act as BGP-4+ route-reflector, do not send link-local
    1035             :          address.*/
    1036           0 :       if (reflect)
    1037           0 :         attr->extra->mp_nexthop_len = 16;
    1038             : 
    1039             :       /* If BGP-4+ link-local nexthop is not link-local nexthop. */
    1040           0 :       if (! IN6_IS_ADDR_LINKLOCAL (&peer->nexthop.v6_local))
    1041           0 :         attr->extra->mp_nexthop_len = 16;
    1042             :     }
    1043             : 
    1044             :     }
    1045             : #endif /* HAVE_IPV6 */
    1046             : 
    1047             :   /* If this is EBGP peer and remove-private-AS is set.  */
    1048           0 :   if (peer->sort == BGP_PEER_EBGP
    1049           0 :       && peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
    1050           0 :       && aspath_private_as_check (attr->aspath))
    1051           0 :     attr->aspath = aspath_empty_get ();
    1052             : 
    1053             :   /* Route map & unsuppress-map apply. */
    1054           0 :   if (ROUTE_MAP_OUT_NAME (filter)
    1055           0 :       || (ri->extra && ri->extra->suppress) )
    1056             :     {
    1057             :       struct bgp_info info;
    1058             :       struct attr dummy_attr;
    1059             :       struct attr_extra dummy_extra;
    1060             : 
    1061           0 :       dummy_attr.extra = &dummy_extra;
    1062             : 
    1063           0 :       info.peer = peer;
    1064           0 :       info.attr = attr;
    1065             : 
    1066             :       /* The route reflector is not allowed to modify the attributes
    1067             :          of the reflected IBGP routes. */
    1068           0 :       if (from->sort == BGP_PEER_IBGP
    1069           0 :           && peer->sort == BGP_PEER_IBGP)
    1070             :         {
    1071           0 :           bgp_attr_dup (&dummy_attr, attr);
    1072           0 :           info.attr = &dummy_attr;
    1073             :         }
    1074             : 
    1075           0 :       SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT); 
    1076             : 
    1077           0 :       if (ri->extra && ri->extra->suppress)
    1078           0 :         ret = route_map_apply (UNSUPPRESS_MAP (filter), p, RMAP_BGP, &info);
    1079             :       else
    1080           0 :         ret = route_map_apply (ROUTE_MAP_OUT (filter), p, RMAP_BGP, &info);
    1081             : 
    1082           0 :       peer->rmap_type = 0;
    1083             : 
    1084           0 :       if (ret == RMAP_DENYMATCH)
    1085             :         {
    1086           0 :           bgp_attr_flush (attr);
    1087           0 :           return 0;
    1088             :         }
    1089             :     }
    1090           0 :   return 1;
    1091             : }
    1092             : 
    1093             : static int
    1094           0 : bgp_announce_check_rsclient (struct bgp_info *ri, struct peer *rsclient,
    1095             :         struct prefix *p, struct attr *attr, afi_t afi, safi_t safi)
    1096             : {
    1097             :   int ret;
    1098             :   char buf[SU_ADDRSTRLEN];
    1099             :   struct bgp_filter *filter;
    1100             :   struct bgp_info info;
    1101             :   struct peer *from;
    1102             :   struct attr *riattr;
    1103             : 
    1104           0 :   from = ri->peer;
    1105           0 :   filter = &rsclient->filter[afi][safi];
    1106           0 :   riattr = bgp_info_mpath_count (ri) ? bgp_info_mpath_attr (ri) : ri->attr;
    1107             : 
    1108             :   if (DISABLE_BGP_ANNOUNCE)
    1109             :     return 0;
    1110             : 
    1111             :   /* Do not send back route to sender. */
    1112           0 :   if (from == rsclient)
    1113           0 :     return 0;
    1114             : 
    1115             :   /* Aggregate-address suppress check. */
    1116           0 :   if (ri->extra && ri->extra->suppress)
    1117           0 :     if (! UNSUPPRESS_MAP_NAME (filter))
    1118           0 :       return 0;
    1119             : 
    1120             :   /* Default route check.  */
    1121           0 :   if (CHECK_FLAG (rsclient->af_sflags[afi][safi],
    1122             :           PEER_STATUS_DEFAULT_ORIGINATE))
    1123             :     {
    1124           0 :       if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
    1125           0 :         return 0;
    1126             : #ifdef HAVE_IPV6
    1127           0 :       else if (p->family == AF_INET6 && p->prefixlen == 0)
    1128           0 :         return 0;
    1129             : #endif /* HAVE_IPV6 */
    1130             :     }
    1131             : 
    1132             :   /* If the attribute has originator-id and it is same as remote
    1133             :      peer's id. */
    1134           0 :   if (riattr->flag & ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID))
    1135             :     {
    1136           0 :       if (IPV4_ADDR_SAME (&rsclient->remote_id, 
    1137             :                           &riattr->extra->originator_id))
    1138             :         {
    1139           0 :          if (BGP_DEBUG (filter, FILTER))
    1140           0 :            zlog (rsclient->log, LOG_DEBUG,
    1141             :                  "%s [Update:SEND] %s/%d originator-id is same as remote router-id",
    1142             :                  rsclient->host,
    1143           0 :                  inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
    1144           0 :                  p->prefixlen);
    1145           0 :          return 0;
    1146             :        }
    1147             :     }
    1148             : 
    1149             :   /* ORF prefix-list filter check */
    1150           0 :   if (CHECK_FLAG (rsclient->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
    1151           0 :       && (CHECK_FLAG (rsclient->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
    1152           0 :          || CHECK_FLAG (rsclient->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
    1153           0 :     if (rsclient->orf_plist[afi][safi])
    1154             :       {
    1155           0 :        if (prefix_list_apply (rsclient->orf_plist[afi][safi], p) == PREFIX_DENY)
    1156           0 :           return 0;
    1157             :       }
    1158             : 
    1159             :   /* Output filter check. */
    1160           0 :   if (bgp_output_filter (rsclient, p, riattr, afi, safi) == FILTER_DENY)
    1161             :     {
    1162           0 :       if (BGP_DEBUG (filter, FILTER))
    1163           0 :        zlog (rsclient->log, LOG_DEBUG,
    1164             :              "%s [Update:SEND] %s/%d is filtered",
    1165             :              rsclient->host,
    1166           0 :              inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
    1167           0 :              p->prefixlen);
    1168           0 :       return 0;
    1169             :     }
    1170             : 
    1171             : #ifdef BGP_SEND_ASPATH_CHECK
    1172             :   /* AS path loop check. */
    1173             :   if (aspath_loop_check (riattr->aspath, rsclient->as))
    1174             :     {
    1175             :       if (BGP_DEBUG (filter, FILTER))
    1176             :         zlog (rsclient->log, LOG_DEBUG,
    1177             :              "%s [Update:SEND] suppress announcement to peer AS %u is AS path.",
    1178             :              rsclient->host, rsclient->as);
    1179             :       return 0;
    1180             :     }
    1181             : #endif /* BGP_SEND_ASPATH_CHECK */
    1182             : 
    1183             :   /* For modify attribute, copy it to temporary structure. */
    1184           0 :   bgp_attr_dup (attr, riattr);
    1185             : 
    1186             :   /* next-hop-set */
    1187           0 :   if ((p->family == AF_INET && attr->nexthop.s_addr == 0)
    1188             : #ifdef HAVE_IPV6
    1189           0 :           || (p->family == AF_INET6 &&
    1190           0 :               IN6_IS_ADDR_UNSPECIFIED(&attr->extra->mp_nexthop_global))
    1191             : #endif /* HAVE_IPV6 */
    1192             :      )
    1193             :   {
    1194             :     /* Set IPv4 nexthop. */
    1195           0 :     if (p->family == AF_INET)
    1196             :       {
    1197           0 :         if (safi == SAFI_MPLS_VPN)
    1198           0 :           memcpy (&attr->extra->mp_nexthop_global_in, &rsclient->nexthop.v4,
    1199             :                   IPV4_MAX_BYTELEN);
    1200             :         else
    1201           0 :           memcpy (&attr->nexthop, &rsclient->nexthop.v4, IPV4_MAX_BYTELEN);
    1202             :       }
    1203             : #ifdef HAVE_IPV6
    1204             :     /* Set IPv6 nexthop. */
    1205           0 :     if (p->family == AF_INET6)
    1206             :       {
    1207             :         /* IPv6 global nexthop must be included. */
    1208           0 :         memcpy (&attr->extra->mp_nexthop_global, &rsclient->nexthop.v6_global,
    1209             :                 IPV6_MAX_BYTELEN);
    1210           0 :         attr->extra->mp_nexthop_len = 16;
    1211             :       }
    1212             : #endif /* HAVE_IPV6 */
    1213             :   }
    1214             : 
    1215             : #ifdef HAVE_IPV6
    1216           0 :   if (p->family == AF_INET6)
    1217             :     {
    1218           0 :       struct attr_extra *attre = attr->extra;
    1219             : 
    1220             :       /* Left nexthop_local unchanged if so configured. */
    1221           0 :       if ( CHECK_FLAG (rsclient->af_flags[afi][safi], 
    1222             :            PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED) )
    1223             :         {
    1224           0 :           if ( IN6_IS_ADDR_LINKLOCAL (&attre->mp_nexthop_local) )
    1225           0 :             attre->mp_nexthop_len=32;
    1226             :           else
    1227           0 :             attre->mp_nexthop_len=16;
    1228             :         }
    1229             :         
    1230             :       /* Default nexthop_local treatment for RS-Clients */
    1231             :       else 
    1232             :         { 
    1233             :           /* Announcer and RS-Client are both in the same network */      
    1234           0 :           if (rsclient->shared_network && from->shared_network &&
    1235           0 :               (rsclient->ifindex == from->ifindex))
    1236             :             {
    1237           0 :               if ( IN6_IS_ADDR_LINKLOCAL (&attre->mp_nexthop_local) )
    1238           0 :                 attre->mp_nexthop_len=32;
    1239             :               else
    1240           0 :                 attre->mp_nexthop_len=16;
    1241             :             }
    1242             : 
    1243             :           /* Set link-local address for shared network peer. */
    1244           0 :           else if (rsclient->shared_network
    1245           0 :               && IN6_IS_ADDR_LINKLOCAL (&rsclient->nexthop.v6_local))
    1246             :             {
    1247           0 :               memcpy (&attre->mp_nexthop_local, &rsclient->nexthop.v6_local,
    1248             :                       IPV6_MAX_BYTELEN);
    1249           0 :               attre->mp_nexthop_len = 32;
    1250             :             }
    1251             : 
    1252             :           else
    1253           0 :             attre->mp_nexthop_len = 16;
    1254             :         }
    1255             : 
    1256             :     }
    1257             : #endif /* HAVE_IPV6 */
    1258             : 
    1259             : 
    1260             :   /* If this is EBGP peer and remove-private-AS is set.  */
    1261           0 :   if (rsclient->sort == BGP_PEER_EBGP
    1262           0 :       && peer_af_flag_check (rsclient, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
    1263           0 :       && aspath_private_as_check (attr->aspath))
    1264           0 :     attr->aspath = aspath_empty_get ();
    1265             : 
    1266             :   /* Route map & unsuppress-map apply. */
    1267           0 :   if (ROUTE_MAP_OUT_NAME (filter) || (ri->extra && ri->extra->suppress) )
    1268             :     {
    1269           0 :       info.peer = rsclient;
    1270           0 :       info.attr = attr;
    1271             : 
    1272           0 :       SET_FLAG (rsclient->rmap_type, PEER_RMAP_TYPE_OUT);
    1273             : 
    1274           0 :       if (ri->extra && ri->extra->suppress)
    1275           0 :         ret = route_map_apply (UNSUPPRESS_MAP (filter), p, RMAP_BGP, &info);
    1276             :       else
    1277           0 :         ret = route_map_apply (ROUTE_MAP_OUT (filter), p, RMAP_BGP, &info);
    1278             : 
    1279           0 :       rsclient->rmap_type = 0;
    1280             : 
    1281           0 :       if (ret == RMAP_DENYMATCH)
    1282             :        {
    1283           0 :          bgp_attr_flush (attr);
    1284           0 :          return 0;
    1285             :        }
    1286             :     }
    1287             : 
    1288           0 :   return 1;
    1289             : }
    1290             : 
    1291             : struct bgp_info_pair
    1292             : {
    1293             :   struct bgp_info *old;
    1294             :   struct bgp_info *new;
    1295             : };
    1296             : 
    1297             : static void
    1298           0 : bgp_best_selection (struct bgp *bgp, struct bgp_node *rn,
    1299             :                     struct bgp_maxpaths_cfg *mpath_cfg,
    1300             :                     struct bgp_info_pair *result)
    1301             : {
    1302             :   struct bgp_info *new_select;
    1303             :   struct bgp_info *old_select;
    1304             :   struct bgp_info *ri;
    1305             :   struct bgp_info *ri1;
    1306             :   struct bgp_info *ri2;
    1307           0 :   struct bgp_info *nextri = NULL;
    1308             :   int paths_eq, do_mpath;
    1309             :   struct list mp_list;
    1310             : 
    1311           0 :   bgp_mp_list_init (&mp_list);
    1312           0 :   do_mpath = (mpath_cfg->maxpaths_ebgp != BGP_DEFAULT_MAXPATHS ||
    1313           0 :               mpath_cfg->maxpaths_ibgp != BGP_DEFAULT_MAXPATHS);
    1314             : 
    1315             :   /* bgp deterministic-med */
    1316           0 :   new_select = NULL;
    1317           0 :   if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED))
    1318           0 :     for (ri1 = rn->info; ri1; ri1 = ri1->next)
    1319             :       {
    1320           0 :         if (CHECK_FLAG (ri1->flags, BGP_INFO_DMED_CHECK))
    1321           0 :           continue;
    1322           0 :         if (BGP_INFO_HOLDDOWN (ri1))
    1323           0 :           continue;
    1324             : 
    1325           0 :         new_select = ri1;
    1326           0 :         if (do_mpath)
    1327           0 :           bgp_mp_list_add (&mp_list, ri1);
    1328           0 :         old_select = CHECK_FLAG (ri1->flags, BGP_INFO_SELECTED) ? ri1 : NULL;
    1329           0 :         if (ri1->next)
    1330           0 :           for (ri2 = ri1->next; ri2; ri2 = ri2->next)
    1331             :             {
    1332           0 :               if (CHECK_FLAG (ri2->flags, BGP_INFO_DMED_CHECK))
    1333           0 :                 continue;
    1334           0 :               if (BGP_INFO_HOLDDOWN (ri2))
    1335           0 :                 continue;
    1336             : 
    1337           0 :               if (aspath_cmp_left (ri1->attr->aspath, ri2->attr->aspath)
    1338           0 :                   || aspath_cmp_left_confed (ri1->attr->aspath,
    1339           0 :                                              ri2->attr->aspath))
    1340             :                 {
    1341           0 :                   if (CHECK_FLAG (ri2->flags, BGP_INFO_SELECTED))
    1342           0 :                     old_select = ri2;
    1343           0 :                   if (bgp_info_cmp (bgp, ri2, new_select, &paths_eq))
    1344             :                     {
    1345           0 :                       bgp_info_unset_flag (rn, new_select, BGP_INFO_DMED_SELECTED);
    1346           0 :                       new_select = ri2;
    1347           0 :                       if (do_mpath && !paths_eq)
    1348             :                         {
    1349           0 :                           bgp_mp_list_clear (&mp_list);
    1350           0 :                           bgp_mp_list_add (&mp_list, ri2);
    1351             :                         }
    1352             :                     }
    1353             : 
    1354           0 :                   if (do_mpath && paths_eq)
    1355           0 :                     bgp_mp_list_add (&mp_list, ri2);
    1356             : 
    1357           0 :                   bgp_info_set_flag (rn, ri2, BGP_INFO_DMED_CHECK);
    1358             :                 }
    1359             :             }
    1360           0 :         bgp_info_set_flag (rn, new_select, BGP_INFO_DMED_CHECK);
    1361           0 :         bgp_info_set_flag (rn, new_select, BGP_INFO_DMED_SELECTED);
    1362             : 
    1363           0 :         bgp_info_mpath_update (rn, new_select, old_select, &mp_list, mpath_cfg);
    1364           0 :         bgp_mp_list_clear (&mp_list);
    1365             :       }
    1366             : 
    1367             :   /* Check old selected route and new selected route. */
    1368           0 :   old_select = NULL;
    1369           0 :   new_select = NULL;
    1370           0 :   for (ri = rn->info; (ri != NULL) && (nextri = ri->next, 1); ri = nextri)
    1371             :     {
    1372           0 :       if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))
    1373           0 :         old_select = ri;
    1374             : 
    1375           0 :       if (BGP_INFO_HOLDDOWN (ri))
    1376             :         {
    1377             :           /* reap REMOVED routes, if needs be 
    1378             :            * selected route must stay for a while longer though
    1379             :            */
    1380           0 :           if (CHECK_FLAG (ri->flags, BGP_INFO_REMOVED)
    1381           0 :               && (ri != old_select))
    1382           0 :               bgp_info_reap (rn, ri);
    1383             :           
    1384           0 :           continue;
    1385             :         }
    1386             : 
    1387           0 :       if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED)
    1388           0 :           && (! CHECK_FLAG (ri->flags, BGP_INFO_DMED_SELECTED)))
    1389             :         {
    1390           0 :           bgp_info_unset_flag (rn, ri, BGP_INFO_DMED_CHECK);
    1391           0 :           continue;
    1392             :         }
    1393           0 :       bgp_info_unset_flag (rn, ri, BGP_INFO_DMED_CHECK);
    1394           0 :       bgp_info_unset_flag (rn, ri, BGP_INFO_DMED_SELECTED);
    1395             : 
    1396           0 :       if (bgp_info_cmp (bgp, ri, new_select, &paths_eq))
    1397             :         {
    1398           0 :           if (do_mpath && bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED))
    1399           0 :             bgp_mp_dmed_deselect (new_select);
    1400             : 
    1401           0 :           new_select = ri;
    1402             : 
    1403           0 :           if (do_mpath && !paths_eq)
    1404             :             {
    1405           0 :               bgp_mp_list_clear (&mp_list);
    1406           0 :               bgp_mp_list_add (&mp_list, ri);
    1407             :             }
    1408             :         }
    1409           0 :       else if (do_mpath && bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED))
    1410           0 :         bgp_mp_dmed_deselect (ri);
    1411             : 
    1412           0 :       if (do_mpath && paths_eq)
    1413           0 :         bgp_mp_list_add (&mp_list, ri);
    1414             :     }
    1415             :     
    1416             : 
    1417           0 :   if (!bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED))
    1418           0 :     bgp_info_mpath_update (rn, new_select, old_select, &mp_list, mpath_cfg);
    1419             : 
    1420           0 :   bgp_info_mpath_aggregate_update (new_select, old_select);
    1421           0 :   bgp_mp_list_clear (&mp_list);
    1422             : 
    1423           0 :   result->old = old_select;
    1424           0 :   result->new = new_select;
    1425             : 
    1426           0 :   return;
    1427             : }
    1428             : 
    1429             : static int
    1430           0 : bgp_process_announce_selected (struct peer *peer, struct bgp_info *selected,
    1431             :                                struct bgp_node *rn, afi_t afi, safi_t safi)
    1432             : {
    1433             :   struct prefix *p;
    1434             :   struct attr attr;
    1435             :   struct attr_extra extra;
    1436             : 
    1437           0 :   p = &rn->p;
    1438             : 
    1439             :   /* Announce route to Established peer. */
    1440           0 :   if (peer->status != Established)
    1441           0 :     return 0;
    1442             : 
    1443             :   /* Address family configuration check. */
    1444           0 :   if (! peer->afc_nego[afi][safi])
    1445           0 :     return 0;
    1446             : 
    1447             :   /* First update is deferred until ORF or ROUTE-REFRESH is received */
    1448           0 :   if (CHECK_FLAG (peer->af_sflags[afi][safi],
    1449             :       PEER_STATUS_ORF_WAIT_REFRESH))
    1450           0 :     return 0;
    1451             : 
    1452             :   /* It's initialized in bgp_announce_[check|check_rsclient]() */
    1453           0 :   attr.extra = &extra;
    1454             : 
    1455           0 :   switch (bgp_node_table (rn)->type)
    1456             :     {
    1457             :       case BGP_TABLE_MAIN:
    1458             :       /* Announcement to peer->conf.  If the route is filtered,
    1459             :          withdraw it. */
    1460           0 :         if (selected && bgp_announce_check (selected, peer, p, &attr, afi, safi))
    1461           0 :           bgp_adj_out_set (rn, peer, p, &attr, afi, safi, selected);
    1462             :         else
    1463           0 :           bgp_adj_out_unset (rn, peer, p, afi, safi);
    1464           0 :         break;
    1465             :       case BGP_TABLE_RSCLIENT:
    1466             :         /* Announcement to peer->conf.  If the route is filtered, 
    1467             :            withdraw it. */
    1468           0 :         if (selected && 
    1469           0 :             bgp_announce_check_rsclient (selected, peer, p, &attr, afi, safi))
    1470           0 :           bgp_adj_out_set (rn, peer, p, &attr, afi, safi, selected);
    1471             :         else
    1472           0 :           bgp_adj_out_unset (rn, peer, p, afi, safi);
    1473           0 :         break;
    1474             :     }
    1475             : 
    1476           0 :   return 0;
    1477             : }
    1478             : 
    1479             : struct bgp_process_queue 
    1480             : {
    1481             :   struct bgp *bgp;
    1482             :   struct bgp_node *rn;
    1483             :   afi_t afi;
    1484             :   safi_t safi;
    1485             : };
    1486             : 
    1487             : static wq_item_status
    1488           0 : bgp_process_rsclient (struct work_queue *wq, void *data)
    1489             : {
    1490           0 :   struct bgp_process_queue *pq = data;
    1491           0 :   struct bgp *bgp = pq->bgp;
    1492           0 :   struct bgp_node *rn = pq->rn;
    1493           0 :   afi_t afi = pq->afi;
    1494           0 :   safi_t safi = pq->safi;
    1495             :   struct bgp_info *new_select;
    1496             :   struct bgp_info *old_select;
    1497             :   struct bgp_info_pair old_and_new;
    1498             :   struct listnode *node, *nnode;
    1499           0 :   struct peer *rsclient = bgp_node_table (rn)->owner;
    1500             :   
    1501             :   /* Best path selection. */
    1502           0 :   bgp_best_selection (bgp, rn, &bgp->maxpaths[afi][safi], &old_and_new);
    1503           0 :   new_select = old_and_new.new;
    1504           0 :   old_select = old_and_new.old;
    1505             : 
    1506           0 :   if (CHECK_FLAG (rsclient->sflags, PEER_STATUS_GROUP))
    1507             :     {
    1508           0 :       if (rsclient->group)
    1509           0 :         for (ALL_LIST_ELEMENTS (rsclient->group->peer, node, nnode, rsclient))
    1510             :           {
    1511             :             /* Nothing to do. */
    1512           0 :             if (old_select && old_select == new_select)
    1513           0 :               if (!CHECK_FLAG (old_select->flags, BGP_INFO_ATTR_CHANGED))
    1514           0 :                 continue;
    1515             : 
    1516           0 :             if (old_select)
    1517           0 :               bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED);
    1518           0 :             if (new_select)
    1519             :               {
    1520           0 :                 bgp_info_set_flag (rn, new_select, BGP_INFO_SELECTED);
    1521           0 :                 bgp_info_unset_flag (rn, new_select, BGP_INFO_ATTR_CHANGED);
    1522           0 :                 UNSET_FLAG (new_select->flags, BGP_INFO_MULTIPATH_CHG);
    1523             :              }
    1524             : 
    1525           0 :             bgp_process_announce_selected (rsclient, new_select, rn,
    1526             :                                            afi, safi);
    1527             :           }
    1528             :     }
    1529             :   else
    1530             :     {
    1531           0 :       if (old_select)
    1532           0 :         bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED);
    1533           0 :       if (new_select)
    1534             :         {
    1535           0 :           bgp_info_set_flag (rn, new_select, BGP_INFO_SELECTED);
    1536           0 :           bgp_info_unset_flag (rn, new_select, BGP_INFO_ATTR_CHANGED);
    1537           0 :           UNSET_FLAG (new_select->flags, BGP_INFO_MULTIPATH_CHG);
    1538             :         }
    1539           0 :       bgp_process_announce_selected (rsclient, new_select, rn, afi, safi);
    1540             :     }
    1541             : 
    1542           0 :   if (old_select && CHECK_FLAG (old_select->flags, BGP_INFO_REMOVED))
    1543           0 :     bgp_info_reap (rn, old_select);
    1544             :   
    1545           0 :   UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
    1546           0 :   return WQ_SUCCESS;
    1547             : }
    1548             : 
    1549             : static wq_item_status
    1550           0 : bgp_process_main (struct work_queue *wq, void *data)
    1551             : {
    1552           0 :   struct bgp_process_queue *pq = data;
    1553           0 :   struct bgp *bgp = pq->bgp;
    1554           0 :   struct bgp_node *rn = pq->rn;
    1555           0 :   afi_t afi = pq->afi;
    1556           0 :   safi_t safi = pq->safi;
    1557           0 :   struct prefix *p = &rn->p;
    1558             :   struct bgp_info *new_select;
    1559             :   struct bgp_info *old_select;
    1560             :   struct bgp_info_pair old_and_new;
    1561             :   struct listnode *node, *nnode;
    1562             :   struct peer *peer;
    1563             :   
    1564             :   /* Best path selection. */
    1565           0 :   bgp_best_selection (bgp, rn, &bgp->maxpaths[afi][safi], &old_and_new);
    1566           0 :   old_select = old_and_new.old;
    1567           0 :   new_select = old_and_new.new;
    1568             : 
    1569             :   /* Nothing to do. */
    1570           0 :   if (old_select && old_select == new_select)
    1571             :     {
    1572           0 :       if (! CHECK_FLAG (old_select->flags, BGP_INFO_ATTR_CHANGED))
    1573             :         {
    1574           0 :           if (CHECK_FLAG (old_select->flags, BGP_INFO_IGP_CHANGED) ||
    1575           0 :               CHECK_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG))
    1576           0 :             bgp_zebra_announce (p, old_select, bgp, safi);
    1577             :           
    1578           0 :           UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG);
    1579           0 :           UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
    1580           0 :           return WQ_SUCCESS;
    1581             :         }
    1582             :     }
    1583             : 
    1584           0 :   if (old_select)
    1585           0 :     bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED);
    1586           0 :   if (new_select)
    1587             :     {
    1588           0 :       bgp_info_set_flag (rn, new_select, BGP_INFO_SELECTED);
    1589           0 :       bgp_info_unset_flag (rn, new_select, BGP_INFO_ATTR_CHANGED);
    1590           0 :       UNSET_FLAG (new_select->flags, BGP_INFO_MULTIPATH_CHG);
    1591             :     }
    1592             : 
    1593             : 
    1594             :   /* Check each BGP peer. */
    1595           0 :   for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
    1596             :     {
    1597           0 :       bgp_process_announce_selected (peer, new_select, rn, afi, safi);
    1598             :     }
    1599             : 
    1600             :   /* FIB update. */
    1601           0 :   if ((safi == SAFI_UNICAST || safi == SAFI_MULTICAST) && (! bgp->name &&
    1602           0 :       ! bgp_option_check (BGP_OPT_NO_FIB)))
    1603             :     {
    1604           0 :       if (new_select 
    1605           0 :           && new_select->type == ZEBRA_ROUTE_BGP 
    1606           0 :           && new_select->sub_type == BGP_ROUTE_NORMAL)
    1607           0 :         bgp_zebra_announce (p, new_select, bgp, safi);
    1608             :       else
    1609             :         {
    1610             :           /* Withdraw the route from the kernel. */
    1611           0 :           if (old_select 
    1612           0 :               && old_select->type == ZEBRA_ROUTE_BGP
    1613           0 :               && old_select->sub_type == BGP_ROUTE_NORMAL)
    1614           0 :             bgp_zebra_withdraw (p, old_select, safi);
    1615             :         }
    1616             :     }
    1617             :     
    1618             :   /* Reap old select bgp_info, it it has been removed */
    1619           0 :   if (old_select && CHECK_FLAG (old_select->flags, BGP_INFO_REMOVED))
    1620           0 :     bgp_info_reap (rn, old_select);
    1621             :   
    1622           0 :   UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
    1623           0 :   return WQ_SUCCESS;
    1624             : }
    1625             : 
    1626             : static void
    1627           0 : bgp_processq_del (struct work_queue *wq, void *data)
    1628             : {
    1629           0 :   struct bgp_process_queue *pq = data;
    1630           0 :   struct bgp_table *table = bgp_node_table (pq->rn);
    1631             :   
    1632           0 :   bgp_unlock (pq->bgp);
    1633           0 :   bgp_unlock_node (pq->rn);
    1634           0 :   bgp_table_unlock (table);
    1635           0 :   XFREE (MTYPE_BGP_PROCESS_QUEUE, pq);
    1636           0 : }
    1637             : 
    1638             : static void
    1639           0 : bgp_process_queue_init (void)
    1640             : {
    1641           0 :   bm->process_main_queue
    1642           0 :     = work_queue_new (bm->master, "process_main_queue");
    1643           0 :   bm->process_rsclient_queue
    1644           0 :     = work_queue_new (bm->master, "process_rsclient_queue");
    1645             :   
    1646           0 :   if ( !(bm->process_main_queue && bm->process_rsclient_queue) )
    1647             :     {
    1648           0 :       zlog_err ("%s: Failed to allocate work queue", __func__);
    1649           0 :       exit (1);
    1650             :     }
    1651             :   
    1652           0 :   bm->process_main_queue->spec.workfunc = &bgp_process_main;
    1653           0 :   bm->process_main_queue->spec.del_item_data = &bgp_processq_del;
    1654           0 :   bm->process_main_queue->spec.max_retries = 0;
    1655           0 :   bm->process_main_queue->spec.hold = 50;
    1656             :   
    1657           0 :   memcpy (bm->process_rsclient_queue, bm->process_main_queue,
    1658             :           sizeof (struct work_queue *));
    1659           0 :   bm->process_rsclient_queue->spec.workfunc = &bgp_process_rsclient;
    1660           0 : }
    1661             : 
    1662             : void
    1663           0 : bgp_process (struct bgp *bgp, struct bgp_node *rn, afi_t afi, safi_t safi)
    1664             : {
    1665             :   struct bgp_process_queue *pqnode;
    1666             :   
    1667             :   /* already scheduled for processing? */
    1668           0 :   if (CHECK_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED))
    1669           0 :     return;
    1670             :   
    1671           0 :   if ( (bm->process_main_queue == NULL) ||
    1672           0 :        (bm->process_rsclient_queue == NULL) )
    1673           0 :     bgp_process_queue_init ();
    1674             :   
    1675           0 :   pqnode = XCALLOC (MTYPE_BGP_PROCESS_QUEUE, 
    1676             :                     sizeof (struct bgp_process_queue));
    1677           0 :   if (!pqnode)
    1678           0 :     return;
    1679             : 
    1680             :   /* all unlocked in bgp_processq_del */
    1681           0 :   bgp_table_lock (bgp_node_table (rn));
    1682           0 :   pqnode->rn = bgp_lock_node (rn);
    1683           0 :   pqnode->bgp = bgp;
    1684           0 :   bgp_lock (bgp);
    1685           0 :   pqnode->afi = afi;
    1686           0 :   pqnode->safi = safi;
    1687             :   
    1688           0 :   switch (bgp_node_table (rn)->type)
    1689             :     {
    1690             :       case BGP_TABLE_MAIN:
    1691           0 :         work_queue_add (bm->process_main_queue, pqnode);
    1692           0 :         break;
    1693             :       case BGP_TABLE_RSCLIENT:
    1694           0 :         work_queue_add (bm->process_rsclient_queue, pqnode);
    1695           0 :         break;
    1696             :     }
    1697             :   
    1698           0 :   SET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
    1699           0 :   return;
    1700             : }
    1701             : 
    1702             : static int
    1703           0 : bgp_maximum_prefix_restart_timer (struct thread *thread)
    1704             : {
    1705             :   struct peer *peer;
    1706             : 
    1707           0 :   peer = THREAD_ARG (thread);
    1708           0 :   peer->t_pmax_restart = NULL;
    1709             : 
    1710           0 :   if (BGP_DEBUG (events, EVENTS))
    1711           0 :     zlog_debug ("%s Maximum-prefix restart timer expired, restore peering",
    1712             :                 peer->host);
    1713             : 
    1714           0 :   peer_clear (peer);
    1715             : 
    1716           0 :   return 0;
    1717             : }
    1718             : 
    1719             : int
    1720           0 : bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi, 
    1721             :                              safi_t safi, int always)
    1722             : {
    1723           0 :   if (!CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
    1724           0 :     return 0;
    1725             : 
    1726           0 :   if (peer->pcount[afi][safi] > peer->pmax[afi][safi])
    1727             :     {
    1728           0 :       if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT)
    1729           0 :          && ! always)
    1730           0 :        return 0;
    1731             : 
    1732           0 :       zlog (peer->log, LOG_INFO,
    1733             :             "%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
    1734             :             "limit %ld", afi_safi_print (afi, safi), peer->host,
    1735             :             peer->pcount[afi][safi], peer->pmax[afi][safi]);
    1736           0 :       SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
    1737             : 
    1738           0 :       if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
    1739           0 :        return 0;
    1740             : 
    1741             :       {
    1742             :        u_int8_t ndata[7];
    1743             : 
    1744           0 :        if (safi == SAFI_MPLS_VPN)
    1745           0 :          safi = SAFI_MPLS_LABELED_VPN;
    1746             :          
    1747           0 :        ndata[0] = (afi >>  8);
    1748           0 :        ndata[1] = afi;
    1749           0 :        ndata[2] = safi;
    1750           0 :        ndata[3] = (peer->pmax[afi][safi] >> 24);
    1751           0 :        ndata[4] = (peer->pmax[afi][safi] >> 16);
    1752           0 :        ndata[5] = (peer->pmax[afi][safi] >> 8);
    1753           0 :        ndata[6] = (peer->pmax[afi][safi]);
    1754             : 
    1755           0 :        SET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
    1756           0 :        bgp_notify_send_with_data (peer, BGP_NOTIFY_CEASE,
    1757             :                                   BGP_NOTIFY_CEASE_MAX_PREFIX, ndata, 7);
    1758             :       }
    1759             : 
    1760             :       /* restart timer start */
    1761           0 :       if (peer->pmax_restart[afi][safi])
    1762             :         {
    1763           0 :           peer->v_pmax_restart = peer->pmax_restart[afi][safi] * 60;
    1764             : 
    1765           0 :           if (BGP_DEBUG (events, EVENTS))
    1766           0 :             zlog_debug ("%s Maximum-prefix restart timer started for %d secs",
    1767             :                         peer->host, peer->v_pmax_restart);
    1768             : 
    1769           0 :           BGP_TIMER_ON (peer->t_pmax_restart, bgp_maximum_prefix_restart_timer,
    1770             :                         peer->v_pmax_restart);
    1771             :         }
    1772             : 
    1773           0 :       return 1;
    1774             :     }
    1775             :   else
    1776           0 :     UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
    1777             : 
    1778           0 :   if (peer->pcount[afi][safi] > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100))
    1779             :     {
    1780           0 :       if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_THRESHOLD)
    1781           0 :          && ! always)
    1782           0 :        return 0;
    1783             : 
    1784           0 :       zlog (peer->log, LOG_INFO,
    1785             :             "%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
    1786             :             afi_safi_print (afi, safi), peer->host, peer->pcount[afi][safi],
    1787             :             peer->pmax[afi][safi]);
    1788           0 :       SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_THRESHOLD);
    1789             :     }
    1790             :   else
    1791           0 :     UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_THRESHOLD);
    1792           0 :   return 0;
    1793             : }
    1794             : 
    1795             : /* Unconditionally remove the route from the RIB, without taking
    1796             :  * damping into consideration (eg, because the session went down)
    1797             :  */
    1798             : static void
    1799           0 : bgp_rib_remove (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
    1800             :                 afi_t afi, safi_t safi)
    1801             : {
    1802           0 :   bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi);
    1803             :   
    1804           0 :   if (!CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
    1805           0 :     bgp_info_delete (rn, ri); /* keep historical info */
    1806             :     
    1807           0 :   bgp_process (peer->bgp, rn, afi, safi);
    1808           0 : }
    1809             : 
    1810             : static void
    1811           0 : bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
    1812             :                   afi_t afi, safi_t safi)
    1813             : {
    1814           0 :   int status = BGP_DAMP_NONE;
    1815             : 
    1816             :   /* apply dampening, if result is suppressed, we'll be retaining 
    1817             :    * the bgp_info in the RIB for historical reference.
    1818             :    */
    1819           0 :   if (CHECK_FLAG (peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
    1820           0 :       && peer->sort == BGP_PEER_EBGP)
    1821           0 :     if ( (status = bgp_damp_withdraw (ri, rn, afi, safi, 0)) 
    1822             :          == BGP_DAMP_SUPPRESSED)
    1823             :       {
    1824           0 :         bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi);
    1825           0 :         return;
    1826             :       }
    1827             :     
    1828           0 :   bgp_rib_remove (rn, ri, peer, afi, safi);
    1829             : }
    1830             : 
    1831             : static void
    1832           0 : bgp_update_rsclient (struct peer *rsclient, afi_t afi, safi_t safi,
    1833             :       struct attr *attr, struct peer *peer, struct prefix *p, int type,
    1834             :       int sub_type, struct prefix_rd *prd, u_char *tag)
    1835             : {
    1836             :   struct bgp_node *rn;
    1837             :   struct bgp *bgp;
    1838             :   struct attr new_attr;
    1839             :   struct attr_extra new_extra;
    1840             :   struct attr *attr_new;
    1841             :   struct attr *attr_new2;
    1842             :   struct bgp_info *ri;
    1843             :   struct bgp_info *new;
    1844             :   const char *reason;
    1845             :   char buf[SU_ADDRSTRLEN];
    1846             : 
    1847             :   /* Do not insert announces from a rsclient into its own 'bgp_table'. */
    1848           0 :   if (peer == rsclient)
    1849           0 :     return;
    1850             : 
    1851           0 :   bgp = peer->bgp;
    1852           0 :   rn = bgp_afi_node_get (rsclient->rib[afi][safi], afi, safi, p, prd);
    1853             : 
    1854             :   /* Check previously received route. */
    1855           0 :   for (ri = rn->info; ri; ri = ri->next)
    1856           0 :     if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type)
    1857           0 :       break;
    1858             : 
    1859             :   /* AS path loop check. */
    1860           0 :   if (aspath_loop_check (attr->aspath, rsclient->as) > peer->allowas_in[afi][safi])
    1861             :     {
    1862           0 :       reason = "as-path contains our own AS;";
    1863           0 :       goto filtered;
    1864             :     }
    1865             : 
    1866             :   /* Route reflector originator ID check.  */
    1867           0 :   if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID)
    1868           0 :       && IPV4_ADDR_SAME (&rsclient->remote_id, &attr->extra->originator_id))
    1869             :     {
    1870           0 :       reason = "originator is us;";
    1871           0 :       goto filtered;
    1872             :     }
    1873             :   
    1874           0 :   new_attr.extra = &new_extra;
    1875           0 :   bgp_attr_dup (&new_attr, attr);
    1876             : 
    1877             :   /* Apply export policy. */
    1878           0 :   if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT) &&
    1879           0 :         bgp_export_modifier (rsclient, peer, p, &new_attr, afi, safi) == RMAP_DENY)
    1880             :     {
    1881           0 :       reason = "export-policy;";
    1882           0 :       goto filtered;
    1883             :     }
    1884             : 
    1885           0 :   attr_new2 = bgp_attr_intern (&new_attr);
    1886             :   
    1887             :   /* Apply import policy. */
    1888           0 :   if (bgp_import_modifier (rsclient, peer, p, &new_attr, afi, safi) == RMAP_DENY)
    1889             :     {
    1890           0 :       bgp_attr_unintern (&attr_new2);
    1891             : 
    1892           0 :       reason = "import-policy;";
    1893           0 :       goto filtered;
    1894             :     }
    1895             : 
    1896           0 :   attr_new = bgp_attr_intern (&new_attr);
    1897           0 :   bgp_attr_unintern (&attr_new2);
    1898             : 
    1899             :   /* IPv4 unicast next hop check.  */
    1900           0 :   if ((afi == AFI_IP) && ((safi == SAFI_UNICAST) || safi == SAFI_MULTICAST))
    1901             :     {
    1902             :      /* Next hop must not be 0.0.0.0 nor Class D/E address. */
    1903           0 :       if (new_attr.nexthop.s_addr == 0
    1904           0 :          || IPV4_CLASS_DE (ntohl (new_attr.nexthop.s_addr)))
    1905             :        {
    1906           0 :          bgp_attr_unintern (&attr_new);
    1907             : 
    1908           0 :          reason = "martian next-hop;";
    1909           0 :          goto filtered;
    1910             :        }
    1911             :     }
    1912             : 
    1913             :   /* If the update is implicit withdraw. */
    1914           0 :   if (ri)
    1915             :     {
    1916           0 :       ri->uptime = bgp_clock ();
    1917             : 
    1918             :       /* Same attribute comes in. */
    1919           0 :       if (!CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)
    1920           0 :           && attrhash_cmp (ri->attr, attr_new))
    1921             :         {
    1922             : 
    1923           0 :           bgp_info_unset_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
    1924             : 
    1925           0 :           if (BGP_DEBUG (update, UPDATE_IN))
    1926           0 :             zlog (peer->log, LOG_DEBUG,
    1927             :                     "%s rcvd %s/%d for RS-client %s...duplicate ignored",
    1928             :                     peer->host,
    1929           0 :                     inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
    1930           0 :                     p->prefixlen, rsclient->host);
    1931             : 
    1932           0 :           bgp_unlock_node (rn);
    1933           0 :           bgp_attr_unintern (&attr_new);
    1934             : 
    1935           0 :           return;
    1936             :         }
    1937             : 
    1938             :       /* Withdraw/Announce before we fully processed the withdraw */
    1939           0 :       if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
    1940           0 :         bgp_info_restore (rn, ri);
    1941             :       
    1942             :       /* Received Logging. */
    1943           0 :       if (BGP_DEBUG (update, UPDATE_IN))
    1944           0 :         zlog (peer->log, LOG_DEBUG, "%s rcvd %s/%d for RS-client %s",
    1945             :                 peer->host,
    1946           0 :                 inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
    1947           0 :                 p->prefixlen, rsclient->host);
    1948             : 
    1949             :       /* The attribute is changed. */
    1950           0 :       bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
    1951             : 
    1952             :       /* Update to new attribute.  */
    1953           0 :       bgp_attr_unintern (&ri->attr);
    1954           0 :       ri->attr = attr_new;
    1955             : 
    1956             :       /* Update MPLS tag.  */
    1957           0 :       if (safi == SAFI_MPLS_VPN)
    1958           0 :         memcpy ((bgp_info_extra_get (ri))->tag, tag, 3);
    1959             : 
    1960           0 :       bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
    1961             : 
    1962             :       /* Process change. */
    1963           0 :       bgp_process (bgp, rn, afi, safi);
    1964           0 :       bgp_unlock_node (rn);
    1965             : 
    1966           0 :       return;
    1967             :     }
    1968             : 
    1969             :   /* Received Logging. */
    1970           0 :   if (BGP_DEBUG (update, UPDATE_IN))
    1971             :     {
    1972           0 :       zlog (peer->log, LOG_DEBUG, "%s rcvd %s/%d for RS-client %s",
    1973             :               peer->host,
    1974           0 :               inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
    1975           0 :               p->prefixlen, rsclient->host);
    1976             :     }
    1977             : 
    1978             :   /* Make new BGP info. */
    1979           0 :   new = bgp_info_new ();
    1980           0 :   new->type = type;
    1981           0 :   new->sub_type = sub_type;
    1982           0 :   new->peer = peer;
    1983           0 :   new->attr = attr_new;
    1984           0 :   new->uptime = bgp_clock ();
    1985             : 
    1986             :   /* Update MPLS tag. */
    1987           0 :   if (safi == SAFI_MPLS_VPN)
    1988           0 :     memcpy ((bgp_info_extra_get (new))->tag, tag, 3);
    1989             : 
    1990           0 :   bgp_info_set_flag (rn, new, BGP_INFO_VALID);
    1991             : 
    1992             :   /* Register new BGP information. */
    1993           0 :   bgp_info_add (rn, new);
    1994             :   
    1995             :   /* route_node_get lock */
    1996           0 :   bgp_unlock_node (rn);
    1997             :   
    1998             :   /* Process change. */
    1999           0 :   bgp_process (bgp, rn, afi, safi);
    2000             : 
    2001           0 :   return;
    2002             : 
    2003             :  filtered: 
    2004             : 
    2005             :   /* This BGP update is filtered.  Log the reason then update BGP entry.  */
    2006           0 :   if (BGP_DEBUG (update, UPDATE_IN))
    2007           0 :         zlog (peer->log, LOG_DEBUG,
    2008             :         "%s rcvd UPDATE about %s/%d -- DENIED for RS-client %s due to: %s",
    2009             :         peer->host,
    2010           0 :         inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
    2011           0 :         p->prefixlen, rsclient->host, reason);
    2012             : 
    2013           0 :   if (ri)
    2014           0 :     bgp_rib_remove (rn, ri, peer, afi, safi);
    2015             : 
    2016           0 :   bgp_unlock_node (rn);
    2017             : 
    2018           0 :   return;
    2019             : }
    2020             : 
    2021             : static void
    2022           0 : bgp_withdraw_rsclient (struct peer *rsclient, afi_t afi, safi_t safi,
    2023             :       struct peer *peer, struct prefix *p, int type, int sub_type,
    2024             :       struct prefix_rd *prd, u_char *tag)
    2025             : {
    2026             :   struct bgp_node *rn;
    2027             :   struct bgp_info *ri;
    2028             :   char buf[SU_ADDRSTRLEN];
    2029             : 
    2030           0 :   if (rsclient == peer)
    2031           0 :     return;
    2032             : 
    2033           0 :   rn = bgp_afi_node_get (rsclient->rib[afi][safi], afi, safi, p, prd);
    2034             : 
    2035             :   /* Lookup withdrawn route. */
    2036           0 :   for (ri = rn->info; ri; ri = ri->next)
    2037           0 :     if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type)
    2038           0 :       break;
    2039             : 
    2040             :   /* Withdraw specified route from routing table. */
    2041           0 :   if (ri && ! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
    2042           0 :     bgp_rib_withdraw (rn, ri, peer, afi, safi);
    2043           0 :   else if (BGP_DEBUG (update, UPDATE_IN))
    2044           0 :     zlog (peer->log, LOG_DEBUG,
    2045             :           "%s Can't find the route %s/%d", peer->host,
    2046           0 :           inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
    2047           0 :           p->prefixlen);
    2048             : 
    2049             :   /* Unlock bgp_node_get() lock. */
    2050           0 :   bgp_unlock_node (rn);
    2051             : }
    2052             : 
    2053             : static int
    2054           0 : bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
    2055             :             afi_t afi, safi_t safi, int type, int sub_type,
    2056             :             struct prefix_rd *prd, u_char *tag, int soft_reconfig)
    2057             : {
    2058             :   int ret;
    2059           0 :   int aspath_loop_count = 0;
    2060             :   struct bgp_node *rn;
    2061             :   struct bgp *bgp;
    2062             :   struct attr new_attr;
    2063             :   struct attr_extra new_extra;
    2064             :   struct attr *attr_new;
    2065             :   struct bgp_info *ri;
    2066             :   struct bgp_info *new;
    2067             :   const char *reason;
    2068             :   char buf[SU_ADDRSTRLEN];
    2069             : 
    2070           0 :   bgp = peer->bgp;
    2071           0 :   rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
    2072             :   
    2073             :   /* When peer's soft reconfiguration enabled.  Record input packet in
    2074             :      Adj-RIBs-In.  */
    2075           0 :   if (! soft_reconfig && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
    2076           0 :       && peer != bgp->peer_self)
    2077           0 :     bgp_adj_in_set (rn, peer, attr);
    2078             : 
    2079             :   /* Check previously received route. */
    2080           0 :   for (ri = rn->info; ri; ri = ri->next)
    2081           0 :     if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type)
    2082           0 :       break;
    2083             : 
    2084             :   /* AS path local-as loop check. */
    2085           0 :   if (peer->change_local_as)
    2086             :     {
    2087           0 :       if (! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND))
    2088           0 :         aspath_loop_count = 1;
    2089             : 
    2090           0 :       if (aspath_loop_check (attr->aspath, peer->change_local_as) > aspath_loop_count) 
    2091             :         {
    2092           0 :           reason = "as-path contains our own AS;";
    2093           0 :           goto filtered;
    2094             :         }
    2095             :     }
    2096             : 
    2097             :   /* AS path loop check. */
    2098           0 :   if (aspath_loop_check (attr->aspath, bgp->as) > peer->allowas_in[afi][safi]
    2099           0 :       || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
    2100           0 :           && aspath_loop_check(attr->aspath, bgp->confed_id)
    2101           0 :           > peer->allowas_in[afi][safi]))
    2102             :     {
    2103           0 :       reason = "as-path contains our own AS;";
    2104           0 :       goto filtered;
    2105             :     }
    2106             : 
    2107             :   /* Route reflector originator ID check.  */
    2108           0 :   if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID)
    2109           0 :       && IPV4_ADDR_SAME (&bgp->router_id, &attr->extra->originator_id))
    2110             :     {
    2111           0 :       reason = "originator is us;";
    2112           0 :       goto filtered;
    2113             :     }
    2114             : 
    2115             :   /* Route reflector cluster ID check.  */
    2116           0 :   if (bgp_cluster_filter (peer, attr))
    2117             :     {
    2118           0 :       reason = "reflected from the same cluster;";
    2119           0 :       goto  filtered;
    2120             :     }
    2121             : 
    2122             :   /* Apply incoming filter.  */
    2123           0 :   if (bgp_input_filter (peer, p, attr, afi, safi) == FILTER_DENY)
    2124             :     {
    2125           0 :       reason = "filter;";
    2126           0 :       goto filtered;
    2127             :     }
    2128             : 
    2129           0 :   new_attr.extra = &new_extra;
    2130           0 :   bgp_attr_dup (&new_attr, attr);
    2131             : 
    2132             :   /* Apply incoming route-map. */
    2133           0 :   if (bgp_input_modifier (peer, p, &new_attr, afi, safi) == RMAP_DENY)
    2134             :     {
    2135           0 :       reason = "route-map;";
    2136           0 :       goto filtered;
    2137             :     }
    2138             : 
    2139             :   /* IPv4 unicast next hop check.  */
    2140           0 :   if (afi == AFI_IP && safi == SAFI_UNICAST)
    2141             :     {
    2142             :       /* If the peer is EBGP and nexthop is not on connected route,
    2143             :          discard it.  */
    2144           0 :       if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1
    2145           0 :           && ! bgp_nexthop_onlink (afi, &new_attr)
    2146           0 :           && ! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
    2147             :         {
    2148           0 :           reason = "non-connected next-hop;";
    2149           0 :           goto filtered;
    2150             :         }
    2151             : 
    2152             :       /* Next hop must not be 0.0.0.0 nor Class D/E address. Next hop
    2153             :          must not be my own address.  */
    2154           0 :       if (new_attr.nexthop.s_addr == 0
    2155           0 :           || IPV4_CLASS_DE (ntohl (new_attr.nexthop.s_addr))
    2156           0 :           || bgp_nexthop_self (&new_attr))
    2157             :         {
    2158           0 :           reason = "martian next-hop;";
    2159           0 :           goto filtered;
    2160             :         }
    2161             :     }
    2162             : 
    2163           0 :   attr_new = bgp_attr_intern (&new_attr);
    2164             : 
    2165             :   /* If the update is implicit withdraw. */
    2166           0 :   if (ri)
    2167             :     {
    2168           0 :       ri->uptime = bgp_clock ();
    2169             : 
    2170             :       /* Same attribute comes in. */
    2171           0 :       if (!CHECK_FLAG (ri->flags, BGP_INFO_REMOVED) 
    2172           0 :           && attrhash_cmp (ri->attr, attr_new))
    2173             :         {
    2174           0 :           bgp_info_unset_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
    2175             : 
    2176           0 :           if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
    2177           0 :               && peer->sort == BGP_PEER_EBGP
    2178           0 :               && CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
    2179             :             {
    2180           0 :               if (BGP_DEBUG (update, UPDATE_IN))  
    2181           0 :                   zlog (peer->log, LOG_DEBUG, "%s rcvd %s/%d",
    2182             :                   peer->host,
    2183           0 :                   inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
    2184           0 :                   p->prefixlen);
    2185             : 
    2186           0 :               if (bgp_damp_update (ri, rn, afi, safi) != BGP_DAMP_SUPPRESSED)
    2187             :                 {
    2188           0 :                   bgp_aggregate_increment (bgp, p, ri, afi, safi);
    2189           0 :                   bgp_process (bgp, rn, afi, safi);
    2190             :                 }
    2191             :             }
    2192             :           else /* Duplicate - odd */
    2193             :             {
    2194           0 :               if (BGP_DEBUG (update, UPDATE_IN))  
    2195           0 :                 zlog (peer->log, LOG_DEBUG,
    2196             :                 "%s rcvd %s/%d...duplicate ignored",
    2197             :                 peer->host,
    2198           0 :                 inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
    2199           0 :                 p->prefixlen);
    2200             : 
    2201             :               /* graceful restart STALE flag unset. */
    2202           0 :               if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
    2203             :                 {
    2204           0 :                   bgp_info_unset_flag (rn, ri, BGP_INFO_STALE);
    2205           0 :                   bgp_process (bgp, rn, afi, safi);
    2206             :                 }
    2207             :             }
    2208             : 
    2209           0 :           bgp_unlock_node (rn);
    2210           0 :           bgp_attr_unintern (&attr_new);
    2211             : 
    2212           0 :           return 0;
    2213             :         }
    2214             : 
    2215             :       /* Withdraw/Announce before we fully processed the withdraw */
    2216           0 :       if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
    2217             :         {
    2218           0 :           if (BGP_DEBUG (update, UPDATE_IN))
    2219           0 :             zlog (peer->log, LOG_DEBUG, "%s rcvd %s/%d, flapped quicker than processing",
    2220             :             peer->host,
    2221           0 :             inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
    2222           0 :             p->prefixlen);
    2223           0 :           bgp_info_restore (rn, ri);
    2224             :         }
    2225             : 
    2226             :       /* Received Logging. */
    2227           0 :       if (BGP_DEBUG (update, UPDATE_IN))  
    2228           0 :         zlog (peer->log, LOG_DEBUG, "%s rcvd %s/%d",
    2229             :               peer->host,
    2230           0 :               inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
    2231           0 :               p->prefixlen);
    2232             : 
    2233             :       /* graceful restart STALE flag unset. */
    2234           0 :       if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
    2235           0 :         bgp_info_unset_flag (rn, ri, BGP_INFO_STALE);
    2236             : 
    2237             :       /* The attribute is changed. */
    2238           0 :       bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
    2239             :       
    2240             :       /* implicit withdraw, decrement aggregate and pcount here.
    2241             :        * only if update is accepted, they'll increment below.
    2242             :        */
    2243           0 :       bgp_aggregate_decrement (bgp, p, ri, afi, safi);
    2244             :       
    2245             :       /* Update bgp route dampening information.  */
    2246           0 :       if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
    2247           0 :           && peer->sort == BGP_PEER_EBGP)
    2248             :         {
    2249             :           /* This is implicit withdraw so we should update dampening
    2250             :              information.  */
    2251           0 :           if (! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
    2252           0 :             bgp_damp_withdraw (ri, rn, afi, safi, 1);  
    2253             :         }
    2254             :         
    2255             :       /* Update to new attribute.  */
    2256           0 :       bgp_attr_unintern (&ri->attr);
    2257           0 :       ri->attr = attr_new;
    2258             : 
    2259             :       /* Update MPLS tag.  */
    2260           0 :       if (safi == SAFI_MPLS_VPN)
    2261           0 :         memcpy ((bgp_info_extra_get (ri))->tag, tag, 3);
    2262             : 
    2263             :       /* Update bgp route dampening information.  */
    2264           0 :       if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
    2265           0 :           && peer->sort == BGP_PEER_EBGP)
    2266             :         {
    2267             :           /* Now we do normal update dampening.  */
    2268           0 :           ret = bgp_damp_update (ri, rn, afi, safi);
    2269           0 :           if (ret == BGP_DAMP_SUPPRESSED)
    2270             :             {
    2271           0 :               bgp_unlock_node (rn);
    2272           0 :               return 0;
    2273             :             }
    2274             :         }
    2275             : 
    2276             :       /* Nexthop reachability check. */
    2277           0 :       if ((afi == AFI_IP || afi == AFI_IP6)
    2278           0 :           && safi == SAFI_UNICAST 
    2279           0 :           && (peer->sort == BGP_PEER_IBGP
    2280           0 :               || peer->sort == BGP_PEER_CONFED
    2281           0 :               || (peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
    2282           0 :               || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)))
    2283             :         {
    2284           0 :           if (bgp_nexthop_lookup (afi, peer, ri, NULL, NULL))
    2285           0 :             bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
    2286             :           else
    2287           0 :             bgp_info_unset_flag (rn, ri, BGP_INFO_VALID);
    2288             :         }
    2289             :       else
    2290           0 :         bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
    2291             : 
    2292             :       /* Process change. */
    2293           0 :       bgp_aggregate_increment (bgp, p, ri, afi, safi);
    2294             : 
    2295           0 :       bgp_process (bgp, rn, afi, safi);
    2296           0 :       bgp_unlock_node (rn);
    2297             : 
    2298           0 :       return 0;
    2299             :     }
    2300             : 
    2301             :   /* Received Logging. */
    2302           0 :   if (BGP_DEBUG (update, UPDATE_IN))  
    2303             :     {
    2304           0 :       zlog (peer->log, LOG_DEBUG, "%s rcvd %s/%d",
    2305             :             peer->host,
    2306           0 :             inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
    2307           0 :             p->prefixlen);
    2308             :     }
    2309             : 
    2310             :   /* Make new BGP info. */
    2311           0 :   new = bgp_info_new ();
    2312           0 :   new->type = type;
    2313           0 :   new->sub_type = sub_type;
    2314           0 :   new->peer = peer;
    2315           0 :   new->attr = attr_new;
    2316           0 :   new->uptime = bgp_clock ();
    2317             : 
    2318             :   /* Update MPLS tag. */
    2319           0 :   if (safi == SAFI_MPLS_VPN)
    2320           0 :     memcpy ((bgp_info_extra_get (new))->tag, tag, 3);
    2321             : 
    2322             :   /* Nexthop reachability check. */
    2323           0 :   if ((afi == AFI_IP || afi == AFI_IP6)
    2324           0 :       && safi == SAFI_UNICAST
    2325           0 :       && (peer->sort == BGP_PEER_IBGP
    2326           0 :           || peer->sort == BGP_PEER_CONFED
    2327           0 :           || (peer->sort == BGP_PEER_EBGP && peer->ttl != 1)
    2328           0 :           || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)))
    2329             :     {
    2330           0 :       if (bgp_nexthop_lookup (afi, peer, new, NULL, NULL))
    2331           0 :         bgp_info_set_flag (rn, new, BGP_INFO_VALID);
    2332             :       else
    2333           0 :         bgp_info_unset_flag (rn, new, BGP_INFO_VALID);
    2334             :     }
    2335             :   else
    2336           0 :     bgp_info_set_flag (rn, new, BGP_INFO_VALID);
    2337             : 
    2338             :   /* Increment prefix */
    2339           0 :   bgp_aggregate_increment (bgp, p, new, afi, safi);
    2340             :   
    2341             :   /* Register new BGP information. */
    2342           0 :   bgp_info_add (rn, new);
    2343             :   
    2344             :   /* route_node_get lock */
    2345           0 :   bgp_unlock_node (rn);
    2346             : 
    2347             :   /* If maximum prefix count is configured and current prefix
    2348             :      count exeed it. */
    2349           0 :   if (bgp_maximum_prefix_overflow (peer, afi, safi, 0))
    2350           0 :     return -1;
    2351             : 
    2352             :   /* Process change. */
    2353           0 :   bgp_process (bgp, rn, afi, safi);
    2354             : 
    2355           0 :   return 0;
    2356             : 
    2357             :   /* This BGP update is filtered.  Log the reason then update BGP
    2358             :      entry.  */
    2359             :  filtered:
    2360           0 :   if (BGP_DEBUG (update, UPDATE_IN))
    2361           0 :     zlog (peer->log, LOG_DEBUG,
    2362             :           "%s rcvd UPDATE about %s/%d -- DENIED due to: %s",
    2363             :           peer->host,
    2364           0 :           inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
    2365           0 :           p->prefixlen, reason);
    2366             : 
    2367           0 :   if (ri)
    2368           0 :     bgp_rib_remove (rn, ri, peer, afi, safi);
    2369             : 
    2370           0 :   bgp_unlock_node (rn);
    2371             : 
    2372           0 :   return 0;
    2373             : }
    2374             : 
    2375             : int
    2376           0 : bgp_update (struct peer *peer, struct prefix *p, struct attr *attr,
    2377             :             afi_t afi, safi_t safi, int type, int sub_type,
    2378             :             struct prefix_rd *prd, u_char *tag, int soft_reconfig)
    2379             : {
    2380             :   struct peer *rsclient;
    2381             :   struct listnode *node, *nnode;
    2382             :   struct bgp *bgp;
    2383             :   int ret;
    2384             : 
    2385           0 :   ret = bgp_update_main (peer, p, attr, afi, safi, type, sub_type, prd, tag,
    2386             :           soft_reconfig);
    2387             : 
    2388           0 :   bgp = peer->bgp;
    2389             : 
    2390             :   /* Process the update for each RS-client. */
    2391           0 :   for (ALL_LIST_ELEMENTS (bgp->rsclient, node, nnode, rsclient))
    2392             :     {
    2393           0 :       if (CHECK_FLAG (rsclient->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
    2394           0 :         bgp_update_rsclient (rsclient, afi, safi, attr, peer, p, type,
    2395             :                 sub_type, prd, tag);
    2396             :     }
    2397             : 
    2398           0 :   return ret;
    2399             : }
    2400             : 
    2401             : int
    2402           0 : bgp_withdraw (struct peer *peer, struct prefix *p, struct attr *attr, 
    2403             :              afi_t afi, safi_t safi, int type, int sub_type, 
    2404             :              struct prefix_rd *prd, u_char *tag)
    2405             : {
    2406             :   struct bgp *bgp;
    2407             :   char buf[SU_ADDRSTRLEN];
    2408             :   struct bgp_node *rn;
    2409             :   struct bgp_info *ri;
    2410             :   struct peer *rsclient;
    2411             :   struct listnode *node, *nnode;
    2412             : 
    2413           0 :   bgp = peer->bgp;
    2414             : 
    2415             :   /* Process the withdraw for each RS-client. */
    2416           0 :   for (ALL_LIST_ELEMENTS (bgp->rsclient, node, nnode, rsclient))
    2417             :     {
    2418           0 :       if (CHECK_FLAG (rsclient->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
    2419           0 :         bgp_withdraw_rsclient (rsclient, afi, safi, peer, p, type, sub_type, prd, tag);
    2420             :     }
    2421             : 
    2422             :   /* Logging. */
    2423           0 :   if (BGP_DEBUG (update, UPDATE_IN))  
    2424           0 :     zlog (peer->log, LOG_DEBUG, "%s rcvd UPDATE about %s/%d -- withdrawn",
    2425             :           peer->host,
    2426           0 :           inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
    2427           0 :           p->prefixlen);
    2428             : 
    2429             :   /* Lookup node. */
    2430           0 :   rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
    2431             : 
    2432             :   /* If peer is soft reconfiguration enabled.  Record input packet for
    2433             :      further calculation. */
    2434           0 :   if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
    2435           0 :       && peer != bgp->peer_self)
    2436           0 :     bgp_adj_in_unset (rn, peer);
    2437             : 
    2438             :   /* Lookup withdrawn route. */
    2439           0 :   for (ri = rn->info; ri; ri = ri->next)
    2440           0 :     if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type)
    2441           0 :       break;
    2442             : 
    2443             :   /* Withdraw specified route from routing table. */
    2444           0 :   if (ri && ! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
    2445           0 :     bgp_rib_withdraw (rn, ri, peer, afi, safi);
    2446           0 :   else if (BGP_DEBUG (update, UPDATE_IN))
    2447           0 :     zlog (peer->log, LOG_DEBUG, 
    2448             :           "%s Can't find the route %s/%d", peer->host,
    2449           0 :           inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
    2450           0 :           p->prefixlen);
    2451             : 
    2452             :   /* Unlock bgp_node_get() lock. */
    2453           0 :   bgp_unlock_node (rn);
    2454             : 
    2455           0 :   return 0;
    2456             : }
    2457             : 
    2458             : void
    2459           0 : bgp_default_originate (struct peer *peer, afi_t afi, safi_t safi, int withdraw)
    2460             : {
    2461             :   struct bgp *bgp;
    2462             :   struct attr attr;
    2463             :   struct aspath *aspath;
    2464             :   struct prefix p;
    2465             :   struct peer *from;
    2466             :   struct bgp_node *rn;
    2467             :   struct bgp_info *ri;
    2468           0 :   int ret = RMAP_DENYMATCH;
    2469             :   
    2470           0 :   if (!(afi == AFI_IP || afi == AFI_IP6))
    2471           0 :     return;
    2472             :   
    2473           0 :   bgp = peer->bgp;
    2474           0 :   from = bgp->peer_self;
    2475             :   
    2476           0 :   bgp_attr_default_set (&attr, BGP_ORIGIN_IGP);
    2477           0 :   aspath = attr.aspath;
    2478           0 :   attr.local_pref = bgp->default_local_pref;
    2479           0 :   memcpy (&attr.nexthop, &peer->nexthop.v4, IPV4_MAX_BYTELEN);
    2480             : 
    2481           0 :   if (afi == AFI_IP)
    2482           0 :     str2prefix ("0.0.0.0/0", &p);
    2483             : #ifdef HAVE_IPV6
    2484           0 :   else if (afi == AFI_IP6)
    2485             :     {
    2486           0 :       struct attr_extra *ae = attr.extra;
    2487             : 
    2488           0 :       str2prefix ("::/0", &p);
    2489             : 
    2490             :       /* IPv6 global nexthop must be included. */
    2491           0 :       memcpy (&ae->mp_nexthop_global, &peer->nexthop.v6_global, 
    2492             :               IPV6_MAX_BYTELEN);
    2493           0 :               ae->mp_nexthop_len = 16;
    2494             :  
    2495             :       /* If the peer is on shared nextwork and we have link-local
    2496             :          nexthop set it. */
    2497           0 :       if (peer->shared_network 
    2498           0 :           && !IN6_IS_ADDR_UNSPECIFIED (&peer->nexthop.v6_local))
    2499             :         {
    2500           0 :           memcpy (&ae->mp_nexthop_local, &peer->nexthop.v6_local, 
    2501             :                   IPV6_MAX_BYTELEN);
    2502           0 :           ae->mp_nexthop_len = 32;
    2503             :         }
    2504             :     }
    2505             : #endif /* HAVE_IPV6 */
    2506             : 
    2507           0 :   if (peer->default_rmap[afi][safi].name)
    2508             :     {
    2509           0 :       SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_DEFAULT);
    2510           0 :       for (rn = bgp_table_top(bgp->rib[afi][safi]); rn; rn = bgp_route_next(rn))
    2511             :         {
    2512           0 :           for (ri = rn->info; ri; ri = ri->next)
    2513             :             {
    2514             :               struct attr dummy_attr;
    2515             :               struct attr_extra dummy_extra;
    2516             :               struct bgp_info info;
    2517             : 
    2518             :               /* Provide dummy so the route-map can't modify the attributes */
    2519           0 :               dummy_attr.extra = &dummy_extra;
    2520           0 :               bgp_attr_dup(&dummy_attr, ri->attr);
    2521           0 :               info.peer = ri->peer;
    2522           0 :               info.attr = &dummy_attr;
    2523             : 
    2524           0 :               ret = route_map_apply(peer->default_rmap[afi][safi].map, &rn->p,
    2525             :                                     RMAP_BGP, &info);
    2526             : 
    2527             :               /* The route map might have set attributes. If we don't flush them
    2528             :                * here, they will be leaked. */
    2529           0 :               bgp_attr_flush(&dummy_attr);
    2530           0 :               if (ret != RMAP_DENYMATCH)
    2531           0 :                 break;
    2532             :             }
    2533           0 :           if (ret != RMAP_DENYMATCH)
    2534           0 :             break;
    2535             :         }
    2536           0 :       bgp->peer_self->rmap_type = 0;
    2537             : 
    2538           0 :       if (ret == RMAP_DENYMATCH)
    2539           0 :         withdraw = 1;
    2540             :     }
    2541             : 
    2542           0 :   if (withdraw)
    2543             :     {
    2544           0 :       if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE))
    2545           0 :         bgp_default_withdraw_send (peer, afi, safi);
    2546           0 :       UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE);
    2547             :     }
    2548             :   else
    2549             :     {
    2550           0 :       if (! CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE))
    2551             :         {
    2552           0 :           SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE);
    2553           0 :           bgp_default_update_send (peer, &attr, afi, safi, from);
    2554             :         }
    2555             :     }
    2556             :   
    2557           0 :   bgp_attr_extra_free (&attr);
    2558           0 :   aspath_unintern (&aspath);
    2559             : }
    2560             : 
    2561             : static void
    2562           4 : bgp_announce_table (struct peer *peer, afi_t afi, safi_t safi,
    2563             :                    struct bgp_table *table, int rsclient)
    2564             : {
    2565             :   struct bgp_node *rn;
    2566             :   struct bgp_info *ri;
    2567             :   struct attr attr;
    2568             :   struct attr_extra extra;
    2569             : 
    2570           4 :   if (! table)
    2571           4 :     table = (rsclient) ? peer->rib[afi][safi] : peer->bgp->rib[afi][safi];
    2572             : 
    2573           4 :   if (safi != SAFI_MPLS_VPN
    2574           4 :       && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE))
    2575           0 :     bgp_default_originate (peer, afi, safi, 0);
    2576             : 
    2577             :   /* It's initialized in bgp_announce_[check|check_rsclient]() */
    2578           4 :   attr.extra = &extra;
    2579             : 
    2580           4 :   for (rn = bgp_table_top (table); rn; rn = bgp_route_next(rn))
    2581           0 :     for (ri = rn->info; ri; ri = ri->next)
    2582           0 :       if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED) && ri->peer != peer)
    2583             :         {
    2584           0 :          if ( (rsclient) ?
    2585           0 :               (bgp_announce_check_rsclient (ri, peer, &rn->p, &attr, afi, safi))
    2586           0 :               : (bgp_announce_check (ri, peer, &rn->p, &attr, afi, safi)))
    2587           0 :             bgp_adj_out_set (rn, peer, &rn->p, &attr, afi, safi, ri);
    2588             :           else
    2589           0 :             bgp_adj_out_unset (rn, peer, &rn->p, afi, safi);
    2590             :         }
    2591           4 : }
    2592             : 
    2593             : void
    2594           4 : bgp_announce_route (struct peer *peer, afi_t afi, safi_t safi)
    2595             : {
    2596             :   struct bgp_node *rn;
    2597             :   struct bgp_table *table;
    2598             : 
    2599           4 :   if (peer->status != Established)
    2600           0 :     return;
    2601             : 
    2602           4 :   if (! peer->afc_nego[afi][safi])
    2603           0 :     return;
    2604             : 
    2605             :   /* First update is deferred until ORF or ROUTE-REFRESH is received */
    2606           4 :   if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))
    2607           0 :     return;
    2608             : 
    2609           4 :   if (safi != SAFI_MPLS_VPN)
    2610           4 :     bgp_announce_table (peer, afi, safi, NULL, 0);
    2611             :   else
    2612           0 :     for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn;
    2613           0 :          rn = bgp_route_next(rn))
    2614           0 :       if ((table = (rn->info)) != NULL)
    2615           0 :        bgp_announce_table (peer, afi, safi, table, 0);
    2616             : 
    2617           4 :   if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
    2618           0 :     bgp_announce_table (peer, afi, safi, NULL, 1);
    2619             : }
    2620             : 
    2621             : void
    2622           0 : bgp_announce_route_all (struct peer *peer)
    2623             : {
    2624             :   afi_t afi;
    2625             :   safi_t safi;
    2626             :   
    2627           0 :   for (afi = AFI_IP; afi < AFI_MAX; afi++)
    2628           0 :     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
    2629           0 :       bgp_announce_route (peer, afi, safi);
    2630           0 : }
    2631             : 
    2632             : static void
    2633           0 : bgp_soft_reconfig_table_rsclient (struct peer *rsclient, afi_t afi,
    2634             :         safi_t safi, struct bgp_table *table, struct prefix_rd *prd)
    2635             : {
    2636             :   struct bgp_node *rn;
    2637             :   struct bgp_adj_in *ain;
    2638             : 
    2639           0 :   if (! table)
    2640           0 :     table = rsclient->bgp->rib[afi][safi];
    2641             : 
    2642           0 :   for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
    2643           0 :     for (ain = rn->adj_in; ain; ain = ain->next)
    2644             :       {
    2645           0 :         struct bgp_info *ri = rn->info;
    2646           0 :         u_char *tag = (ri && ri->extra) ? ri->extra->tag : NULL;
    2647             : 
    2648           0 :         bgp_update_rsclient (rsclient, afi, safi, ain->attr, ain->peer,
    2649             :                 &rn->p, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, prd, tag);
    2650             :       }
    2651           0 : }
    2652             : 
    2653             : void
    2654           0 : bgp_soft_reconfig_rsclient (struct peer *rsclient, afi_t afi, safi_t safi)
    2655             : {
    2656             :   struct bgp_table *table;
    2657             :   struct bgp_node *rn;
    2658             :   
    2659           0 :   if (safi != SAFI_MPLS_VPN)
    2660           0 :     bgp_soft_reconfig_table_rsclient (rsclient, afi, safi, NULL, NULL);
    2661             : 
    2662             :   else
    2663           0 :     for (rn = bgp_table_top (rsclient->bgp->rib[afi][safi]); rn;
    2664           0 :             rn = bgp_route_next (rn))
    2665           0 :       if ((table = rn->info) != NULL)
    2666             :         {
    2667             :           struct prefix_rd prd;
    2668           0 :           prd.family = AF_UNSPEC;
    2669           0 :           prd.prefixlen = 64;
    2670           0 :           memcpy(&prd.val, rn->p.u.val, 8);
    2671             : 
    2672           0 :           bgp_soft_reconfig_table_rsclient (rsclient, afi, safi, table, &prd);
    2673             :         }
    2674           0 : }
    2675             : 
    2676             : static void
    2677           0 : bgp_soft_reconfig_table (struct peer *peer, afi_t afi, safi_t safi,
    2678             :                          struct bgp_table *table, struct prefix_rd *prd)
    2679             : {
    2680             :   int ret;
    2681             :   struct bgp_node *rn;
    2682             :   struct bgp_adj_in *ain;
    2683             : 
    2684           0 :   if (! table)
    2685           0 :     table = peer->bgp->rib[afi][safi];
    2686             : 
    2687           0 :   for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
    2688           0 :     for (ain = rn->adj_in; ain; ain = ain->next)
    2689             :       {
    2690           0 :         if (ain->peer == peer)
    2691             :           {
    2692           0 :             struct bgp_info *ri = rn->info;
    2693           0 :             u_char *tag = (ri && ri->extra) ? ri->extra->tag : NULL;
    2694             : 
    2695           0 :             ret = bgp_update (peer, &rn->p, ain->attr, afi, safi,
    2696             :                               ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
    2697             :                               prd, tag, 1);
    2698             : 
    2699           0 :             if (ret < 0)
    2700             :               {
    2701           0 :                 bgp_unlock_node (rn);
    2702           0 :                 return;
    2703             :               }
    2704           0 :             continue;
    2705             :           }
    2706             :       }
    2707             : }
    2708             : 
    2709             : void
    2710           0 : bgp_soft_reconfig_in (struct peer *peer, afi_t afi, safi_t safi)
    2711             : {
    2712             :   struct bgp_node *rn;
    2713             :   struct bgp_table *table;
    2714             : 
    2715           0 :   if (peer->status != Established)
    2716           0 :     return;
    2717             : 
    2718           0 :   if (safi != SAFI_MPLS_VPN)
    2719           0 :     bgp_soft_reconfig_table (peer, afi, safi, NULL, NULL);
    2720             :   else
    2721           0 :     for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn;
    2722           0 :          rn = bgp_route_next (rn))
    2723           0 :       if ((table = rn->info) != NULL)
    2724             :         {
    2725             :           struct prefix_rd prd;
    2726           0 :           prd.family = AF_UNSPEC;
    2727           0 :           prd.prefixlen = 64;
    2728           0 :           memcpy(&prd.val, rn->p.u.val, 8);
    2729             : 
    2730           0 :           bgp_soft_reconfig_table (peer, afi, safi, table, &prd);
    2731             :         }
    2732             : }
    2733             : 
    2734             : 
    2735             : struct bgp_clear_node_queue
    2736             : {
    2737             :   struct bgp_node *rn;
    2738             :   enum bgp_clear_route_type purpose;
    2739             : };
    2740             : 
    2741             : static wq_item_status
    2742           0 : bgp_clear_route_node (struct work_queue *wq, void *data)
    2743             : {
    2744           0 :   struct bgp_clear_node_queue *cnq = data;
    2745           0 :   struct bgp_node *rn = cnq->rn;
    2746           0 :   struct peer *peer = wq->spec.data;
    2747             :   struct bgp_info *ri;
    2748           0 :   afi_t afi = bgp_node_table (rn)->afi;
    2749           0 :   safi_t safi = bgp_node_table (rn)->safi;
    2750             :   
    2751           0 :   assert (rn && peer);
    2752             :   
    2753           0 :   for (ri = rn->info; ri; ri = ri->next)
    2754           0 :     if (ri->peer == peer || cnq->purpose == BGP_CLEAR_ROUTE_MY_RSCLIENT)
    2755             :       {
    2756             :         /* graceful restart STALE flag set. */
    2757           0 :         if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT)
    2758           0 :             && peer->nsf[afi][safi]
    2759           0 :             && ! CHECK_FLAG (ri->flags, BGP_INFO_STALE)
    2760           0 :             && ! CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE))
    2761           0 :           bgp_info_set_flag (rn, ri, BGP_INFO_STALE);
    2762             :         else
    2763           0 :           bgp_rib_remove (rn, ri, peer, afi, safi);
    2764           0 :         break;
    2765             :       }
    2766           0 :   return WQ_SUCCESS;
    2767             : }
    2768             : 
    2769             : static void
    2770           0 : bgp_clear_node_queue_del (struct work_queue *wq, void *data)
    2771             : {
    2772           0 :   struct bgp_clear_node_queue *cnq = data;
    2773           0 :   struct bgp_node *rn = cnq->rn;
    2774           0 :   struct bgp_table *table = bgp_node_table (rn);
    2775             :   
    2776           0 :   bgp_unlock_node (rn); 
    2777           0 :   bgp_table_unlock (table);
    2778           0 :   XFREE (MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
    2779           0 : }
    2780             : 
    2781             : static void
    2782           0 : bgp_clear_node_complete (struct work_queue *wq)
    2783             : {
    2784           0 :   struct peer *peer = wq->spec.data;
    2785             :   
    2786             :   /* Tickle FSM to start moving again */
    2787           0 :   BGP_EVENT_ADD (peer, Clearing_Completed);
    2788             : 
    2789           0 :   peer_unlock (peer); /* bgp_clear_route */
    2790           0 : }
    2791             : 
    2792             : static void
    2793           0 : bgp_clear_node_queue_init (struct peer *peer)
    2794             : {
    2795             :   char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
    2796             :   
    2797           0 :   snprintf (wname, sizeof(wname), "clear %s", peer->host);
    2798             : #undef CLEAR_QUEUE_NAME_LEN
    2799             : 
    2800           0 :   if ( (peer->clear_node_queue = work_queue_new (bm->master, wname)) == NULL)
    2801             :     {
    2802           0 :       zlog_err ("%s: Failed to allocate work queue", __func__);
    2803           0 :       exit (1);
    2804             :     }
    2805           0 :   peer->clear_node_queue->spec.hold = 10;
    2806           0 :   peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
    2807           0 :   peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
    2808           0 :   peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
    2809           0 :   peer->clear_node_queue->spec.max_retries = 0;
    2810             :   
    2811             :   /* we only 'lock' this peer reference when the queue is actually active */
    2812           0 :   peer->clear_node_queue->spec.data = peer;
    2813           0 : }
    2814             : 
    2815             : static void
    2816           0 : bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,
    2817             :                        struct bgp_table *table, struct peer *rsclient,
    2818             :                        enum bgp_clear_route_type purpose)
    2819             : {
    2820             :   struct bgp_node *rn;
    2821             :   
    2822             :   
    2823           0 :   if (! table)
    2824           0 :     table = (rsclient) ? rsclient->rib[afi][safi] : peer->bgp->rib[afi][safi];
    2825             :   
    2826             :   /* If still no table => afi/safi isn't configured at all or smth. */
    2827           0 :   if (! table)
    2828           0 :     return;
    2829             :   
    2830           0 :   for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
    2831             :     {
    2832             :       struct bgp_info *ri;
    2833             :       struct bgp_adj_in *ain;
    2834             :       struct bgp_adj_out *aout;
    2835             : 
    2836             :       /* XXX:TODO: This is suboptimal, every non-empty route_node is
    2837             :        * queued for every clearing peer, regardless of whether it is
    2838             :        * relevant to the peer at hand.
    2839             :        *
    2840             :        * Overview: There are 3 different indices which need to be
    2841             :        * scrubbed, potentially, when a peer is removed:
    2842             :        *
    2843             :        * 1 peer's routes visible via the RIB (ie accepted routes)
    2844             :        * 2 peer's routes visible by the (optional) peer's adj-in index
    2845             :        * 3 other routes visible by the peer's adj-out index
    2846             :        *
    2847             :        * 3 there is no hurry in scrubbing, once the struct peer is
    2848             :        * removed from bgp->peer, we could just GC such deleted peer's
    2849             :        * adj-outs at our leisure.
    2850             :        *
    2851             :        * 1 and 2 must be 'scrubbed' in some way, at least made
    2852             :        * invisible via RIB index before peer session is allowed to be
    2853             :        * brought back up. So one needs to know when such a 'search' is
    2854             :        * complete.
    2855             :        *
    2856             :        * Ideally:
    2857             :        *
    2858             :        * - there'd be a single global queue or a single RIB walker
    2859             :        * - rather than tracking which route_nodes still need to be
    2860             :        *   examined on a peer basis, we'd track which peers still
    2861             :        *   aren't cleared
    2862             :        *
    2863             :        * Given that our per-peer prefix-counts now should be reliable,
    2864             :        * this may actually be achievable. It doesn't seem to be a huge
    2865             :        * problem at this time,
    2866             :        */
    2867           0 :       for (ain = rn->adj_in; ain; ain = ain->next)
    2868           0 :         if (ain->peer == peer || purpose == BGP_CLEAR_ROUTE_MY_RSCLIENT)
    2869             :           {
    2870           0 :             bgp_adj_in_remove (rn, ain);
    2871           0 :             bgp_unlock_node (rn);
    2872           0 :             break;
    2873             :           }
    2874           0 :       for (aout = rn->adj_out; aout; aout = aout->next)
    2875           0 :         if (aout->peer == peer || purpose == BGP_CLEAR_ROUTE_MY_RSCLIENT)
    2876             :           {
    2877           0 :             bgp_adj_out_remove (rn, aout, peer, afi, safi);
    2878           0 :             bgp_unlock_node (rn);
    2879           0 :             break;
    2880             :           }
    2881             : 
    2882           0 :       for (ri = rn->info; ri; ri = ri->next)
    2883           0 :         if (ri->peer == peer || purpose == BGP_CLEAR_ROUTE_MY_RSCLIENT)
    2884             :           {
    2885             :             struct bgp_clear_node_queue *cnq;
    2886             : 
    2887             :             /* both unlocked in bgp_clear_node_queue_del */
    2888           0 :             bgp_table_lock (bgp_node_table (rn));
    2889           0 :             bgp_lock_node (rn);
    2890           0 :             cnq = XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE,
    2891             :                            sizeof (struct bgp_clear_node_queue));
    2892           0 :             cnq->rn = rn;
    2893           0 :             cnq->purpose = purpose;
    2894           0 :             work_queue_add (peer->clear_node_queue, cnq);
    2895           0 :             break;
    2896             :           }
    2897             :     }
    2898           0 :   return;
    2899             : }
    2900             : 
    2901             : void
    2902           0 : bgp_clear_route (struct peer *peer, afi_t afi, safi_t safi,
    2903             :                  enum bgp_clear_route_type purpose)
    2904             : {
    2905             :   struct bgp_node *rn;
    2906             :   struct bgp_table *table;
    2907             :   struct peer *rsclient;
    2908             :   struct listnode *node, *nnode;
    2909             : 
    2910           0 :   if (peer->clear_node_queue == NULL)
    2911           0 :     bgp_clear_node_queue_init (peer);
    2912             :   
    2913             :   /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
    2914             :    * Idle until it receives a Clearing_Completed event. This protects
    2915             :    * against peers which flap faster than we can we clear, which could
    2916             :    * lead to:
    2917             :    *
    2918             :    * a) race with routes from the new session being installed before
    2919             :    *    clear_route_node visits the node (to delete the route of that
    2920             :    *    peer)
    2921             :    * b) resource exhaustion, clear_route_node likely leads to an entry
    2922             :    *    on the process_main queue. Fast-flapping could cause that queue
    2923             :    *    to grow and grow.
    2924             :    */
    2925           0 :   if (!peer->clear_node_queue->thread)
    2926           0 :     peer_lock (peer); /* bgp_clear_node_complete */
    2927             : 
    2928           0 :   switch (purpose)
    2929             :     {
    2930             :     case BGP_CLEAR_ROUTE_NORMAL:
    2931           0 :       if (safi != SAFI_MPLS_VPN)
    2932           0 :         bgp_clear_route_table (peer, afi, safi, NULL, NULL, purpose);
    2933             :       else
    2934           0 :         for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn;
    2935           0 :              rn = bgp_route_next (rn))
    2936           0 :           if ((table = rn->info) != NULL)
    2937           0 :             bgp_clear_route_table (peer, afi, safi, table, NULL, purpose);
    2938             : 
    2939           0 :       for (ALL_LIST_ELEMENTS (peer->bgp->rsclient, node, nnode, rsclient))
    2940           0 :         if (CHECK_FLAG(rsclient->af_flags[afi][safi],
    2941             :                        PEER_FLAG_RSERVER_CLIENT))
    2942           0 :           bgp_clear_route_table (peer, afi, safi, NULL, rsclient, purpose);
    2943           0 :       break;
    2944             : 
    2945             :     case BGP_CLEAR_ROUTE_MY_RSCLIENT:
    2946           0 :       bgp_clear_route_table (peer, afi, safi, NULL, peer, purpose);
    2947           0 :       break;
    2948             : 
    2949             :     default:
    2950           0 :       assert (0);
    2951             :       break;
    2952             :     }
    2953             :   
    2954             :   /* If no routes were cleared, nothing was added to workqueue, the
    2955             :    * completion function won't be run by workqueue code - call it here. 
    2956             :    * XXX: Actually, this assumption doesn't hold, see
    2957             :    * bgp_clear_route_table(), we queue all non-empty nodes.
    2958             :    *
    2959             :    * Additionally, there is a presumption in FSM that clearing is only
    2960             :    * really needed if peer state is Established - peers in
    2961             :    * pre-Established states shouldn't have any route-update state
    2962             :    * associated with them (in or out).
    2963             :    *
    2964             :    * We still can get here in pre-Established though, through
    2965             :    * peer_delete -> bgp_fsm_change_status, so this is a useful sanity
    2966             :    * check to ensure the assumption above holds.
    2967             :    *
    2968             :    * At some future point, this check could be move to the top of the
    2969             :    * function, and do a quick early-return when state is
    2970             :    * pre-Established, avoiding above list and table scans. Once we're
    2971             :    * sure it is safe..
    2972             :    */
    2973           0 :   if (!peer->clear_node_queue->thread)
    2974           0 :     bgp_clear_node_complete (peer->clear_node_queue);
    2975           0 : }
    2976             :   
    2977             : void
    2978           0 : bgp_clear_route_all (struct peer *peer)
    2979             : {
    2980             :   afi_t afi;
    2981             :   safi_t safi;
    2982             : 
    2983           0 :   for (afi = AFI_IP; afi < AFI_MAX; afi++)
    2984           0 :     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
    2985           0 :       bgp_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
    2986           0 : }
    2987             : 
    2988             : void
    2989           0 : bgp_clear_adj_in (struct peer *peer, afi_t afi, safi_t safi)
    2990             : {
    2991             :   struct bgp_table *table;
    2992             :   struct bgp_node *rn;
    2993             :   struct bgp_adj_in *ain;
    2994             : 
    2995           0 :   table = peer->bgp->rib[afi][safi];
    2996             : 
    2997           0 :   for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
    2998           0 :     for (ain = rn->adj_in; ain ; ain = ain->next)
    2999           0 :       if (ain->peer == peer)
    3000             :         {
    3001           0 :           bgp_adj_in_remove (rn, ain);
    3002           0 :           bgp_unlock_node (rn);
    3003           0 :           break;
    3004             :         }
    3005           0 : }
    3006             : 
    3007             : void
    3008           0 : bgp_clear_stale_route (struct peer *peer, afi_t afi, safi_t safi)
    3009             : {
    3010             :   struct bgp_node *rn;
    3011             :   struct bgp_info *ri;
    3012             :   struct bgp_table *table;
    3013             : 
    3014           0 :   table = peer->bgp->rib[afi][safi];
    3015             : 
    3016           0 :   for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
    3017             :     {
    3018           0 :       for (ri = rn->info; ri; ri = ri->next)
    3019           0 :         if (ri->peer == peer)
    3020             :           {
    3021           0 :             if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
    3022           0 :               bgp_rib_remove (rn, ri, peer, afi, safi);
    3023           0 :             break;
    3024             :           }
    3025             :     }
    3026           0 : }
    3027             : 
    3028             : /* Delete all kernel routes. */
    3029             : void
    3030           0 : bgp_cleanup_routes (void)
    3031             : {
    3032             :   struct bgp *bgp;
    3033             :   struct listnode *node, *nnode;
    3034             :   struct bgp_node *rn;
    3035             :   struct bgp_table *table;
    3036             :   struct bgp_info *ri;
    3037             : 
    3038           0 :   for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
    3039             :     {
    3040           0 :       table = bgp->rib[AFI_IP][SAFI_UNICAST];
    3041             : 
    3042           0 :       for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
    3043           0 :         for (ri = rn->info; ri; ri = ri->next)
    3044           0 :           if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)
    3045           0 :               && ri->type == ZEBRA_ROUTE_BGP 
    3046           0 :               && ri->sub_type == BGP_ROUTE_NORMAL)
    3047           0 :             bgp_zebra_withdraw (&rn->p, ri,SAFI_UNICAST);
    3048             : 
    3049           0 :       table = bgp->rib[AFI_IP6][SAFI_UNICAST];
    3050             : 
    3051           0 :       for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
    3052           0 :         for (ri = rn->info; ri; ri = ri->next)
    3053           0 :           if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)
    3054           0 :               && ri->type == ZEBRA_ROUTE_BGP 
    3055           0 :               && ri->sub_type == BGP_ROUTE_NORMAL)
    3056           0 :             bgp_zebra_withdraw (&rn->p, ri,SAFI_UNICAST);
    3057             :     }
    3058           0 : }
    3059             : 
    3060             : void
    3061           0 : bgp_reset (void)
    3062             : {
    3063           0 :   vty_reset ();
    3064           0 :   bgp_zclient_reset ();
    3065           0 :   access_list_reset ();
    3066           0 :   prefix_list_reset ();
    3067           0 : }
    3068             : 
    3069             : /* Parse NLRI stream.  Withdraw NLRI is recognized by NULL attr
    3070             :    value. */
    3071             : int
    3072           0 : bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
    3073             : {
    3074             :   u_char *pnt;
    3075             :   u_char *lim;
    3076             :   struct prefix p;
    3077             :   int psize;
    3078             :   int ret;
    3079             : 
    3080             :   /* Check peer status. */
    3081           0 :   if (peer->status != Established)
    3082           0 :     return 0;
    3083             :   
    3084           0 :   pnt = packet->nlri;
    3085           0 :   lim = pnt + packet->length;
    3086             : 
    3087           0 :   for (; pnt < lim; pnt += psize)
    3088             :     {
    3089             :       /* Clear prefix structure. */
    3090           0 :       memset (&p, 0, sizeof (struct prefix));
    3091             : 
    3092             :       /* Fetch prefix length. */
    3093           0 :       p.prefixlen = *pnt++;
    3094           0 :       p.family = afi2family (packet->afi);
    3095             :       
    3096             :       /* Already checked in nlri_sanity_check().  We do double check
    3097             :          here. */
    3098           0 :       if ((packet->afi == AFI_IP && p.prefixlen > 32)
    3099           0 :           || (packet->afi == AFI_IP6 && p.prefixlen > 128))
    3100           0 :         return -1;
    3101             : 
    3102             :       /* Packet size overflow check. */
    3103           0 :       psize = PSIZE (p.prefixlen);
    3104             : 
    3105             :       /* When packet overflow occur return immediately. */
    3106           0 :       if (pnt + psize > lim)
    3107           0 :         return -1;
    3108             : 
    3109             :       /* Fetch prefix from NLRI packet. */
    3110           0 :       memcpy (&p.u.prefix, pnt, psize);
    3111             : 
    3112             :       /* Check address. */
    3113           0 :       if (packet->afi == AFI_IP && packet->safi == SAFI_UNICAST)
    3114             :         {
    3115           0 :           if (IN_CLASSD (ntohl (p.u.prefix4.s_addr)))
    3116             :             {
    3117             :              /* 
    3118             :               * From draft-ietf-idr-bgp4-22, Section 6.3: 
    3119             :               * If a BGP router receives an UPDATE message with a
    3120             :               * semantically incorrect NLRI field, in which a prefix is
    3121             :               * semantically incorrect (eg. an unexpected multicast IP
    3122             :               * address), it should ignore the prefix.
    3123             :               */
    3124           0 :               zlog (peer->log, LOG_ERR, 
    3125             :                     "IPv4 unicast NLRI is multicast address %s",
    3126             :                     inet_ntoa (p.u.prefix4));
    3127             : 
    3128           0 :               return -1;
    3129             :             }
    3130             :         }
    3131             : 
    3132             : #ifdef HAVE_IPV6
    3133             :       /* Check address. */
    3134           0 :       if (packet->afi == AFI_IP6 && packet->safi == SAFI_UNICAST)
    3135             :         {
    3136           0 :           if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
    3137             :             {
    3138             :               char buf[BUFSIZ];
    3139             : 
    3140           0 :               zlog (peer->log, LOG_WARNING, 
    3141             :                     "IPv6 link-local NLRI received %s ignore this NLRI",
    3142             :                     inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ));
    3143             : 
    3144           0 :               continue;
    3145             :             }
    3146             :         }
    3147             : #endif /* HAVE_IPV6 */
    3148             : 
    3149             :       /* Normal process. */
    3150           0 :       if (attr)
    3151           0 :         ret = bgp_update (peer, &p, attr, packet->afi, packet->safi, 
    3152             :                           ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL, 0);
    3153             :       else
    3154           0 :         ret = bgp_withdraw (peer, &p, attr, packet->afi, packet->safi, 
    3155             :                             ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL);
    3156             : 
    3157             :       /* Address family configuration mismatch or maximum-prefix count
    3158             :          overflow. */
    3159           0 :       if (ret < 0)
    3160           0 :         return -1;
    3161             :     }
    3162             : 
    3163             :   /* Packet length consistency check. */
    3164           0 :   if (pnt != lim)
    3165           0 :     return -1;
    3166             : 
    3167           0 :   return 0;
    3168             : }
    3169             : 
    3170             : /* NLRI encode syntax check routine. */
    3171             : int
    3172          15 : bgp_nlri_sanity_check (struct peer *peer, int afi, u_char *pnt,
    3173             :                        bgp_size_t length)
    3174             : {
    3175             :   u_char *end;
    3176             :   u_char prefixlen;
    3177             :   int psize;
    3178             : 
    3179          15 :   end = pnt + length;
    3180             : 
    3181             :   /* RFC1771 6.3 The NLRI field in the UPDATE message is checked for
    3182             :      syntactic validity.  If the field is syntactically incorrect,
    3183             :      then the Error Subcode is set to Invalid Network Field. */
    3184             : 
    3185          54 :   while (pnt < end)
    3186             :     {
    3187          30 :       prefixlen = *pnt++;
    3188             :       
    3189             :       /* Prefix length check. */
    3190          30 :       if ((afi == AFI_IP && prefixlen > 32)
    3191          30 :           || (afi == AFI_IP6 && prefixlen > 128))
    3192             :         {
    3193           2 :           plog_err (peer->log, 
    3194             :                     "%s [Error] Update packet error (wrong prefix length %d)",
    3195             :                     peer->host, prefixlen);
    3196           2 :           bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, 
    3197             :                            BGP_NOTIFY_UPDATE_INVAL_NETWORK);
    3198           2 :           return -1;
    3199             :         }
    3200             : 
    3201             :       /* Packet size overflow check. */
    3202          28 :       psize = PSIZE (prefixlen);
    3203             : 
    3204          28 :       if (pnt + psize > end)
    3205             :         {
    3206           4 :           plog_err (peer->log, 
    3207             :                     "%s [Error] Update packet error"
    3208             :                     " (prefix data overflow prefix size is %d)",
    3209             :                     peer->host, psize);
    3210           4 :           bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, 
    3211             :                            BGP_NOTIFY_UPDATE_INVAL_NETWORK);
    3212           4 :           return -1;
    3213             :         }
    3214             : 
    3215          24 :       pnt += psize;
    3216             :     }
    3217             : 
    3218             :   /* Packet length consistency check. */
    3219           9 :   if (pnt != end)
    3220             :     {
    3221           0 :       plog_err (peer->log,
    3222             :                 "%s [Error] Update packet error"
    3223             :                 " (prefix length mismatch with total length)",
    3224             :                 peer->host);
    3225           0 :       bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, 
    3226             :                        BGP_NOTIFY_UPDATE_INVAL_NETWORK);
    3227           0 :       return -1;
    3228             :     }
    3229           9 :   return 0;
    3230             : }
    3231             : 
    3232             : static struct bgp_static *
    3233           0 : bgp_static_new (void)
    3234             : {
    3235           0 :   return XCALLOC (MTYPE_BGP_STATIC, sizeof (struct bgp_static));
    3236             : }
    3237             : 
    3238             : static void
    3239           0 : bgp_static_free (struct bgp_static *bgp_static)
    3240             : {
    3241           0 :   if (bgp_static->rmap.name)
    3242           0 :     free (bgp_static->rmap.name);
    3243           0 :   XFREE (MTYPE_BGP_STATIC, bgp_static);
    3244           0 : }
    3245             : 
    3246             : static void
    3247           0 : bgp_static_withdraw_rsclient (struct bgp *bgp, struct peer *rsclient,
    3248             :         struct prefix *p, afi_t afi, safi_t safi)
    3249             : {
    3250             :   struct bgp_node *rn;
    3251             :   struct bgp_info *ri;
    3252             : 
    3253           0 :   rn = bgp_afi_node_get (rsclient->rib[afi][safi], afi, safi, p, NULL);
    3254             : 
    3255             :   /* Check selected route and self inserted route. */
    3256           0 :   for (ri = rn->info; ri; ri = ri->next)
    3257           0 :     if (ri->peer == bgp->peer_self
    3258           0 :        && ri->type == ZEBRA_ROUTE_BGP
    3259           0 :        && ri->sub_type == BGP_ROUTE_STATIC)
    3260           0 :       break;
    3261             : 
    3262             :   /* Withdraw static BGP route from routing table. */
    3263           0 :   if (ri)
    3264             :     {
    3265           0 :       bgp_info_delete (rn, ri);
    3266           0 :       bgp_process (bgp, rn, afi, safi);
    3267             :     }
    3268             : 
    3269             :   /* Unlock bgp_node_lookup. */
    3270           0 :   bgp_unlock_node (rn);
    3271           0 : }
    3272             : 
    3273             : static void
    3274           0 : bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p,
    3275             :                             struct bgp_static *bgp_static,
    3276             :                             afi_t afi, safi_t safi)
    3277             : {
    3278             :   struct bgp_node *rn;
    3279             :   struct bgp_info *ri;
    3280             :   struct bgp_info *new;
    3281             :   struct bgp_info info;
    3282             :   struct attr *attr_new;
    3283             :   struct attr attr;
    3284             :   struct attr new_attr;
    3285             :   struct attr_extra new_extra;
    3286             :   struct bgp *bgp;
    3287             :   int ret;
    3288             :   char buf[SU_ADDRSTRLEN];
    3289             : 
    3290           0 :   bgp = rsclient->bgp;
    3291             : 
    3292           0 :   assert (bgp_static);
    3293           0 :   if (!bgp_static)
    3294           0 :     return;
    3295             : 
    3296           0 :   rn = bgp_afi_node_get (rsclient->rib[afi][safi], afi, safi, p, NULL);
    3297             : 
    3298           0 :   bgp_attr_default_set (&attr, BGP_ORIGIN_IGP);
    3299             : 
    3300           0 :   attr.nexthop = bgp_static->igpnexthop;
    3301           0 :   attr.med = bgp_static->igpmetric;
    3302           0 :   attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
    3303             :   
    3304           0 :   if (bgp_static->atomic)
    3305           0 :     attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
    3306             :   
    3307             :   /* Apply network route-map for export to this rsclient. */
    3308           0 :   if (bgp_static->rmap.name)
    3309             :     {
    3310           0 :       struct attr attr_tmp = attr;
    3311           0 :       info.peer = rsclient;
    3312           0 :       info.attr = &attr_tmp;
    3313             :       
    3314           0 :       SET_FLAG (rsclient->rmap_type, PEER_RMAP_TYPE_EXPORT);
    3315           0 :       SET_FLAG (rsclient->rmap_type, PEER_RMAP_TYPE_NETWORK);
    3316             : 
    3317           0 :       ret = route_map_apply (bgp_static->rmap.map, p, RMAP_BGP, &info);
    3318             : 
    3319           0 :       rsclient->rmap_type = 0;
    3320             : 
    3321           0 :       if (ret == RMAP_DENYMATCH)
    3322             :         {
    3323             :           /* Free uninterned attribute. */
    3324           0 :           bgp_attr_flush (&attr_tmp);
    3325             : 
    3326             :           /* Unintern original. */
    3327           0 :           aspath_unintern (&attr.aspath);
    3328           0 :           bgp_static_withdraw_rsclient (bgp, rsclient, p, afi, safi);
    3329           0 :           bgp_attr_extra_free (&attr);
    3330             :           
    3331           0 :           return;
    3332             :         }
    3333           0 :       attr_new = bgp_attr_intern (&attr_tmp);
    3334             :     }
    3335             :   else
    3336           0 :     attr_new = bgp_attr_intern (&attr);
    3337             : 
    3338           0 :   new_attr.extra = &new_extra;
    3339           0 :   bgp_attr_dup(&new_attr, attr_new);
    3340             :   
    3341           0 :   SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
    3342             : 
    3343           0 :   if (bgp_import_modifier (rsclient, bgp->peer_self, p, &new_attr, afi, safi) 
    3344             :         == RMAP_DENY)
    3345             :     {
    3346             :       /* This BGP update is filtered.  Log the reason then update BGP entry.  */
    3347           0 :       if (BGP_DEBUG (update, UPDATE_IN))
    3348           0 :               zlog (rsclient->log, LOG_DEBUG,
    3349             :               "Static UPDATE about %s/%d -- DENIED for RS-client %s due to: import-policy",
    3350           0 :               inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
    3351           0 :               p->prefixlen, rsclient->host);
    3352             : 
    3353           0 :       bgp->peer_self->rmap_type = 0;
    3354             : 
    3355           0 :       bgp_attr_unintern (&attr_new);
    3356           0 :       aspath_unintern (&attr.aspath);
    3357           0 :       bgp_attr_extra_free (&attr);
    3358             : 
    3359           0 :       bgp_static_withdraw_rsclient (bgp, rsclient, p, afi, safi);
    3360             :       
    3361           0 :       return;
    3362             :     }
    3363             : 
    3364           0 :   bgp->peer_self->rmap_type = 0;
    3365             : 
    3366           0 :   bgp_attr_unintern (&attr_new);
    3367           0 :   attr_new = bgp_attr_intern (&new_attr);
    3368             : 
    3369           0 :   for (ri = rn->info; ri; ri = ri->next)
    3370           0 :     if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
    3371           0 :             && ri->sub_type == BGP_ROUTE_STATIC)
    3372           0 :       break;
    3373             : 
    3374           0 :   if (ri)
    3375             :        {
    3376           0 :       if (attrhash_cmp (ri->attr, attr_new) &&
    3377           0 :           !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
    3378             :         {
    3379           0 :           bgp_unlock_node (rn);
    3380           0 :           bgp_attr_unintern (&attr_new);
    3381           0 :           aspath_unintern (&attr.aspath);
    3382           0 :           bgp_attr_extra_free (&attr);
    3383           0 :           return;
    3384             :        }
    3385             :       else
    3386             :         {
    3387             :           /* The attribute is changed. */
    3388           0 :           bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
    3389             : 
    3390             :           /* Rewrite BGP route information. */
    3391           0 :           if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
    3392           0 :             bgp_info_restore(rn, ri);
    3393           0 :           bgp_attr_unintern (&ri->attr);
    3394           0 :           ri->attr = attr_new;
    3395           0 :           ri->uptime = bgp_clock ();
    3396             : 
    3397             :           /* Process change. */
    3398           0 :           bgp_process (bgp, rn, afi, safi);
    3399           0 :           bgp_unlock_node (rn);
    3400           0 :           aspath_unintern (&attr.aspath);
    3401           0 :           bgp_attr_extra_free (&attr);
    3402           0 :           return;
    3403             :         }
    3404             :     }
    3405             :   
    3406             :   /* Make new BGP info. */
    3407           0 :   new = bgp_info_new ();
    3408           0 :   new->type = ZEBRA_ROUTE_BGP;
    3409           0 :   new->sub_type = BGP_ROUTE_STATIC;
    3410           0 :   new->peer = bgp->peer_self;
    3411           0 :   SET_FLAG (new->flags, BGP_INFO_VALID);
    3412           0 :   new->attr = attr_new;
    3413           0 :   new->uptime = bgp_clock ();
    3414             : 
    3415             :   /* Register new BGP information. */
    3416           0 :   bgp_info_add (rn, new);
    3417             :   
    3418             :   /* route_node_get lock */
    3419           0 :   bgp_unlock_node (rn);
    3420             :   
    3421             :   /* Process change. */
    3422           0 :   bgp_process (bgp, rn, afi, safi);
    3423             : 
    3424             :   /* Unintern original. */
    3425           0 :   aspath_unintern (&attr.aspath);
    3426           0 :   bgp_attr_extra_free (&attr);
    3427             : }
    3428             : 
    3429             : static void
    3430           0 : bgp_static_update_main (struct bgp *bgp, struct prefix *p,
    3431             :                    struct bgp_static *bgp_static, afi_t afi, safi_t safi)
    3432             : {
    3433             :   struct bgp_node *rn;
    3434             :   struct bgp_info *ri;
    3435             :   struct bgp_info *new;
    3436             :   struct bgp_info info;
    3437             :   struct attr attr;
    3438             :   struct attr *attr_new;
    3439             :   int ret;
    3440             : 
    3441           0 :   assert (bgp_static);
    3442           0 :   if (!bgp_static)
    3443           0 :     return;
    3444             : 
    3445           0 :   rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, NULL);
    3446             : 
    3447           0 :   bgp_attr_default_set (&attr, BGP_ORIGIN_IGP);
    3448             :   
    3449           0 :   attr.nexthop = bgp_static->igpnexthop;
    3450           0 :   attr.med = bgp_static->igpmetric;
    3451           0 :   attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
    3452             : 
    3453           0 :   if (bgp_static->atomic)
    3454           0 :     attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
    3455             : 
    3456             :   /* Apply route-map. */
    3457           0 :   if (bgp_static->rmap.name)
    3458             :     {
    3459           0 :       struct attr attr_tmp = attr;
    3460           0 :       info.peer = bgp->peer_self;
    3461           0 :       info.attr = &attr_tmp;
    3462             : 
    3463           0 :       SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
    3464             : 
    3465           0 :       ret = route_map_apply (bgp_static->rmap.map, p, RMAP_BGP, &info);
    3466             : 
    3467           0 :       bgp->peer_self->rmap_type = 0;
    3468             : 
    3469           0 :       if (ret == RMAP_DENYMATCH)
    3470             :         {    
    3471             :           /* Free uninterned attribute. */
    3472           0 :           bgp_attr_flush (&attr_tmp);
    3473             : 
    3474             :           /* Unintern original. */
    3475           0 :           aspath_unintern (&attr.aspath);
    3476           0 :           bgp_attr_extra_free (&attr);
    3477           0 :           bgp_static_withdraw (bgp, p, afi, safi);
    3478           0 :           return;
    3479             :         }
    3480           0 :       attr_new = bgp_attr_intern (&attr_tmp);
    3481             :     }
    3482             :   else
    3483           0 :     attr_new = bgp_attr_intern (&attr);
    3484             : 
    3485           0 :   for (ri = rn->info; ri; ri = ri->next)
    3486           0 :     if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
    3487           0 :         && ri->sub_type == BGP_ROUTE_STATIC)
    3488           0 :       break;
    3489             : 
    3490           0 :   if (ri)
    3491             :     {
    3492           0 :       if (attrhash_cmp (ri->attr, attr_new) &&
    3493           0 :           !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
    3494             :         {
    3495           0 :           bgp_unlock_node (rn);
    3496           0 :           bgp_attr_unintern (&attr_new);
    3497           0 :           aspath_unintern (&attr.aspath);
    3498           0 :           bgp_attr_extra_free (&attr);
    3499           0 :           return;
    3500             :         }
    3501             :       else
    3502             :         {
    3503             :           /* The attribute is changed. */
    3504           0 :           bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
    3505             : 
    3506             :           /* Rewrite BGP route information. */
    3507           0 :           if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
    3508           0 :             bgp_info_restore(rn, ri);
    3509             :           else
    3510           0 :             bgp_aggregate_decrement (bgp, p, ri, afi, safi);
    3511           0 :           bgp_attr_unintern (&ri->attr);
    3512           0 :           ri->attr = attr_new;
    3513           0 :           ri->uptime = bgp_clock ();
    3514             : 
    3515             :           /* Process change. */
    3516           0 :           bgp_aggregate_increment (bgp, p, ri, afi, safi);
    3517           0 :           bgp_process (bgp, rn, afi, safi);
    3518           0 :           bgp_unlock_node (rn);
    3519           0 :           aspath_unintern (&attr.aspath);
    3520           0 :           bgp_attr_extra_free (&attr);
    3521           0 :           return;
    3522             :         }
    3523             :     }
    3524             : 
    3525             :   /* Make new BGP info. */
    3526           0 :   new = bgp_info_new ();
    3527           0 :   new->type = ZEBRA_ROUTE_BGP;
    3528           0 :   new->sub_type = BGP_ROUTE_STATIC;
    3529           0 :   new->peer = bgp->peer_self;
    3530           0 :   SET_FLAG (new->flags, BGP_INFO_VALID);
    3531           0 :   new->attr = attr_new;
    3532           0 :   new->uptime = bgp_clock ();
    3533             : 
    3534             :   /* Aggregate address increment. */
    3535           0 :   bgp_aggregate_increment (bgp, p, new, afi, safi);
    3536             :   
    3537             :   /* Register new BGP information. */
    3538           0 :   bgp_info_add (rn, new);
    3539             :   
    3540             :   /* route_node_get lock */
    3541           0 :   bgp_unlock_node (rn);
    3542             :   
    3543             :   /* Process change. */
    3544           0 :   bgp_process (bgp, rn, afi, safi);
    3545             : 
    3546             :   /* Unintern original. */
    3547           0 :   aspath_unintern (&attr.aspath);
    3548           0 :   bgp_attr_extra_free (&attr);
    3549             : }
    3550             : 
    3551             : void
    3552           0 : bgp_static_update (struct bgp *bgp, struct prefix *p,
    3553             :                   struct bgp_static *bgp_static, afi_t afi, safi_t safi)
    3554             : {
    3555             :   struct peer *rsclient;
    3556             :   struct listnode *node, *nnode;
    3557             : 
    3558           0 :   bgp_static_update_main (bgp, p, bgp_static, afi, safi);
    3559             : 
    3560           0 :   for (ALL_LIST_ELEMENTS (bgp->rsclient, node, nnode, rsclient))
    3561             :     {
    3562           0 :       if (CHECK_FLAG (rsclient->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
    3563           0 :         bgp_static_update_rsclient (rsclient, p, bgp_static, afi, safi);
    3564             :     }
    3565           0 : }
    3566             : 
    3567             : static void
    3568           0 : bgp_static_update_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi,
    3569             :                          safi_t safi, struct prefix_rd *prd, u_char *tag)
    3570             : {
    3571             :   struct bgp_node *rn;
    3572             :   struct bgp_info *new;
    3573             :   
    3574           0 :   rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
    3575             : 
    3576             :   /* Make new BGP info. */
    3577           0 :   new = bgp_info_new ();
    3578           0 :   new->type = ZEBRA_ROUTE_BGP;
    3579           0 :   new->sub_type = BGP_ROUTE_STATIC;
    3580           0 :   new->peer = bgp->peer_self;
    3581           0 :   new->attr = bgp_attr_default_intern (BGP_ORIGIN_IGP);
    3582           0 :   SET_FLAG (new->flags, BGP_INFO_VALID);
    3583           0 :   new->uptime = bgp_clock ();
    3584           0 :   new->extra = bgp_info_extra_new();
    3585           0 :   memcpy (new->extra->tag, tag, 3);
    3586             : 
    3587             :   /* Aggregate address increment. */
    3588           0 :   bgp_aggregate_increment (bgp, p, new, afi, safi);
    3589             :   
    3590             :   /* Register new BGP information. */
    3591           0 :   bgp_info_add (rn, new);
    3592             : 
    3593             :   /* route_node_get lock */
    3594           0 :   bgp_unlock_node (rn);
    3595             :   
    3596             :   /* Process change. */
    3597           0 :   bgp_process (bgp, rn, afi, safi);
    3598           0 : }
    3599             : 
    3600             : void
    3601           0 : bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi,
    3602             :                      safi_t safi)
    3603             : {
    3604             :   struct bgp_node *rn;
    3605             :   struct bgp_info *ri;
    3606             : 
    3607           0 :   rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, NULL);
    3608             : 
    3609             :   /* Check selected route and self inserted route. */
    3610           0 :   for (ri = rn->info; ri; ri = ri->next)
    3611           0 :     if (ri->peer == bgp->peer_self 
    3612           0 :         && ri->type == ZEBRA_ROUTE_BGP
    3613           0 :         && ri->sub_type == BGP_ROUTE_STATIC)
    3614           0 :       break;
    3615             : 
    3616             :   /* Withdraw static BGP route from routing table. */
    3617           0 :   if (ri)
    3618             :     {
    3619           0 :       bgp_aggregate_decrement (bgp, p, ri, afi, safi);
    3620           0 :       bgp_info_delete (rn, ri);
    3621           0 :       bgp_process (bgp, rn, afi, safi);
    3622             :     }
    3623             : 
    3624             :   /* Unlock bgp_node_lookup. */
    3625           0 :   bgp_unlock_node (rn);
    3626           0 : }
    3627             : 
    3628             : void
    3629           0 : bgp_check_local_routes_rsclient (struct peer *rsclient, afi_t afi, safi_t safi)
    3630             : {
    3631             :   struct bgp_static *bgp_static;
    3632             :   struct bgp *bgp;
    3633             :   struct bgp_node *rn;
    3634             :   struct prefix *p;
    3635             : 
    3636           0 :   bgp = rsclient->bgp;
    3637             : 
    3638           0 :   for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn))
    3639           0 :     if ((bgp_static = rn->info) != NULL)
    3640             :       {
    3641           0 :         p = &rn->p;
    3642             : 
    3643           0 :         bgp_static_update_rsclient (rsclient, p, bgp_static,
    3644             :                 afi, safi);
    3645             :       }
    3646           0 : }
    3647             : 
    3648             : static void
    3649           0 : bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi,
    3650             :                            safi_t safi, struct prefix_rd *prd, u_char *tag)
    3651             : {
    3652             :   struct bgp_node *rn;
    3653             :   struct bgp_info *ri;
    3654             : 
    3655           0 :   rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
    3656             : 
    3657             :   /* Check selected route and self inserted route. */
    3658           0 :   for (ri = rn->info; ri; ri = ri->next)
    3659           0 :     if (ri->peer == bgp->peer_self 
    3660           0 :         && ri->type == ZEBRA_ROUTE_BGP
    3661           0 :         && ri->sub_type == BGP_ROUTE_STATIC)
    3662           0 :       break;
    3663             : 
    3664             :   /* Withdraw static BGP route from routing table. */
    3665           0 :   if (ri)
    3666             :     {
    3667           0 :       bgp_aggregate_decrement (bgp, p, ri, afi, safi);
    3668           0 :       bgp_info_delete (rn, ri);
    3669           0 :       bgp_process (bgp, rn, afi, safi);
    3670             :     }
    3671             : 
    3672             :   /* Unlock bgp_node_lookup. */
    3673           0 :   bgp_unlock_node (rn);
    3674           0 : }
    3675             : 
    3676             : /* Configure static BGP network.  When user don't run zebra, static
    3677             :    route should be installed as valid.  */
    3678             : static int
    3679           0 : bgp_static_set (struct vty *vty, struct bgp *bgp, const char *ip_str, 
    3680             :                 afi_t afi, safi_t safi, const char *rmap, int backdoor)
    3681             : {
    3682             :   int ret;
    3683             :   struct prefix p;
    3684             :   struct bgp_static *bgp_static;
    3685             :   struct bgp_node *rn;
    3686           0 :   u_char need_update = 0;
    3687             : 
    3688             :   /* Convert IP prefix string to struct prefix. */
    3689           0 :   ret = str2prefix (ip_str, &p);
    3690           0 :   if (! ret)
    3691             :     {
    3692           0 :       vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
    3693           0 :       return CMD_WARNING;
    3694             :     }
    3695             : #ifdef HAVE_IPV6
    3696           0 :   if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
    3697             :     {
    3698           0 :       vty_out (vty, "%% Malformed prefix (link-local address)%s",
    3699           0 :                VTY_NEWLINE);
    3700           0 :       return CMD_WARNING;
    3701             :     }
    3702             : #endif /* HAVE_IPV6 */
    3703             : 
    3704           0 :   apply_mask (&p);
    3705             : 
    3706             :   /* Set BGP static route configuration. */
    3707           0 :   rn = bgp_node_get (bgp->route[afi][safi], &p);
    3708             : 
    3709           0 :   if (rn->info)
    3710             :     {
    3711             :       /* Configuration change. */
    3712           0 :       bgp_static = rn->info;
    3713             : 
    3714             :       /* Check previous routes are installed into BGP.  */
    3715           0 :       if (bgp_static->valid && bgp_static->backdoor != backdoor)
    3716           0 :         need_update = 1;
    3717             :       
    3718           0 :       bgp_static->backdoor = backdoor;
    3719             :       
    3720           0 :       if (rmap)
    3721             :         {
    3722           0 :           if (bgp_static->rmap.name)
    3723           0 :             free (bgp_static->rmap.name);
    3724           0 :           bgp_static->rmap.name = strdup (rmap);
    3725           0 :           bgp_static->rmap.map = route_map_lookup_by_name (rmap);
    3726             :         }
    3727             :       else
    3728             :         {
    3729           0 :           if (bgp_static->rmap.name)
    3730           0 :             free (bgp_static->rmap.name);
    3731           0 :           bgp_static->rmap.name = NULL;
    3732           0 :           bgp_static->rmap.map = NULL;
    3733           0 :           bgp_static->valid = 0;
    3734             :         }
    3735           0 :       bgp_unlock_node (rn);
    3736             :     }
    3737             :   else
    3738             :     {
    3739             :       /* New configuration. */
    3740           0 :       bgp_static = bgp_static_new ();
    3741           0 :       bgp_static->backdoor = backdoor;
    3742           0 :       bgp_static->valid = 0;
    3743           0 :       bgp_static->igpmetric = 0;
    3744           0 :       bgp_static->igpnexthop.s_addr = 0;
    3745             :       
    3746           0 :       if (rmap)
    3747             :         {
    3748           0 :           if (bgp_static->rmap.name)
    3749           0 :             free (bgp_static->rmap.name);
    3750           0 :           bgp_static->rmap.name = strdup (rmap);
    3751           0 :           bgp_static->rmap.map = route_map_lookup_by_name (rmap);
    3752             :         }
    3753           0 :       rn->info = bgp_static;
    3754             :     }
    3755             : 
    3756             :   /* If BGP scan is not enabled, we should install this route here.  */
    3757           0 :   if (! bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
    3758             :     {
    3759           0 :       bgp_static->valid = 1;
    3760             : 
    3761           0 :       if (need_update)
    3762           0 :         bgp_static_withdraw (bgp, &p, afi, safi);
    3763             : 
    3764           0 :       if (! bgp_static->backdoor)
    3765           0 :         bgp_static_update (bgp, &p, bgp_static, afi, safi);
    3766             :     }
    3767             : 
    3768           0 :   return CMD_SUCCESS;
    3769             : }
    3770             : 
    3771             : /* Configure static BGP network. */
    3772             : static int
    3773           0 : bgp_static_unset (struct vty *vty, struct bgp *bgp, const char *ip_str,
    3774             :                   afi_t afi, safi_t safi)
    3775             : {
    3776             :   int ret;
    3777             :   struct prefix p;
    3778             :   struct bgp_static *bgp_static;
    3779             :   struct bgp_node *rn;
    3780             : 
    3781             :   /* Convert IP prefix string to struct prefix. */
    3782           0 :   ret = str2prefix (ip_str, &p);
    3783           0 :   if (! ret)
    3784             :     {
    3785           0 :       vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
    3786           0 :       return CMD_WARNING;
    3787             :     }
    3788             : #ifdef HAVE_IPV6
    3789           0 :   if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
    3790             :     {
    3791           0 :       vty_out (vty, "%% Malformed prefix (link-local address)%s",
    3792           0 :                VTY_NEWLINE);
    3793           0 :       return CMD_WARNING;
    3794             :     }
    3795             : #endif /* HAVE_IPV6 */
    3796             : 
    3797           0 :   apply_mask (&p);
    3798             : 
    3799           0 :   rn = bgp_node_lookup (bgp->route[afi][safi], &p);
    3800           0 :   if (! rn)
    3801             :     {
    3802           0 :       vty_out (vty, "%% Can't find specified static route configuration.%s",
    3803           0 :                VTY_NEWLINE);
    3804           0 :       return CMD_WARNING;
    3805             :     }
    3806             : 
    3807           0 :   bgp_static = rn->info;
    3808             :   
    3809             :   /* Update BGP RIB. */
    3810           0 :   if (! bgp_static->backdoor)
    3811           0 :     bgp_static_withdraw (bgp, &p, afi, safi);
    3812             : 
    3813             :   /* Clear configuration. */
    3814           0 :   bgp_static_free (bgp_static);
    3815           0 :   rn->info = NULL;
    3816           0 :   bgp_unlock_node (rn);
    3817           0 :   bgp_unlock_node (rn);
    3818             : 
    3819           0 :   return CMD_SUCCESS;
    3820             : }
    3821             : 
    3822             : /* Called from bgp_delete().  Delete all static routes from the BGP
    3823             :    instance. */
    3824             : void
    3825           1 : bgp_static_delete (struct bgp *bgp)
    3826             : {
    3827             :   afi_t afi;
    3828             :   safi_t safi;
    3829             :   struct bgp_node *rn;
    3830             :   struct bgp_node *rm;
    3831             :   struct bgp_table *table;
    3832             :   struct bgp_static *bgp_static;
    3833             : 
    3834           3 :   for (afi = AFI_IP; afi < AFI_MAX; afi++)
    3835          10 :     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
    3836           8 :       for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn))
    3837           0 :         if (rn->info != NULL)
    3838             :           {      
    3839           0 :             if (safi == SAFI_MPLS_VPN)
    3840             :               {
    3841           0 :                 table = rn->info;
    3842             : 
    3843           0 :                 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
    3844             :                   {
    3845           0 :                     bgp_static = rn->info;
    3846           0 :                     bgp_static_withdraw_vpnv4 (bgp, &rm->p,
    3847             :                                                AFI_IP, SAFI_MPLS_VPN,
    3848           0 :                                                (struct prefix_rd *)&rn->p,
    3849           0 :                                                bgp_static->tag);
    3850           0 :                     bgp_static_free (bgp_static);
    3851           0 :                     rn->info = NULL;
    3852           0 :                     bgp_unlock_node (rn);
    3853             :                   }
    3854             :               }
    3855             :             else
    3856             :               {
    3857           0 :                 bgp_static = rn->info;
    3858           0 :                 bgp_static_withdraw (bgp, &rn->p, afi, safi);
    3859           0 :                 bgp_static_free (bgp_static);
    3860           0 :                 rn->info = NULL;
    3861           0 :                 bgp_unlock_node (rn);
    3862             :               }
    3863             :           }
    3864           1 : }
    3865             : 
    3866             : int
    3867           0 : bgp_static_set_vpnv4 (struct vty *vty, const char *ip_str, const char *rd_str,
    3868             :                       const char *tag_str)
    3869             : {
    3870             :   int ret;
    3871             :   struct prefix p;
    3872             :   struct prefix_rd prd;
    3873             :   struct bgp *bgp;
    3874             :   struct bgp_node *prn;
    3875             :   struct bgp_node *rn;
    3876             :   struct bgp_table *table;
    3877             :   struct bgp_static *bgp_static;
    3878             :   u_char tag[3];
    3879             : 
    3880           0 :   bgp = vty->index;
    3881             : 
    3882           0 :   ret = str2prefix (ip_str, &p);
    3883           0 :   if (! ret)
    3884             :     {
    3885           0 :       vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
    3886           0 :       return CMD_WARNING;
    3887             :     }
    3888           0 :   apply_mask (&p);
    3889             : 
    3890           0 :   ret = str2prefix_rd (rd_str, &prd);
    3891           0 :   if (! ret)
    3892             :     {
    3893           0 :       vty_out (vty, "%% Malformed rd%s", VTY_NEWLINE);
    3894           0 :       return CMD_WARNING;
    3895             :     }
    3896             : 
    3897           0 :   ret = str2tag (tag_str, tag);
    3898           0 :   if (! ret)
    3899             :     {
    3900           0 :       vty_out (vty, "%% Malformed tag%s", VTY_NEWLINE);
    3901           0 :       return CMD_WARNING;
    3902             :     }
    3903             : 
    3904           0 :   prn = bgp_node_get (bgp->route[AFI_IP][SAFI_MPLS_VPN],
    3905             :                         (struct prefix *)&prd);
    3906           0 :   if (prn->info == NULL)
    3907           0 :     prn->info = bgp_table_init (AFI_IP, SAFI_MPLS_VPN);
    3908             :   else
    3909           0 :     bgp_unlock_node (prn);
    3910           0 :   table = prn->info;
    3911             : 
    3912           0 :   rn = bgp_node_get (table, &p);
    3913             : 
    3914           0 :   if (rn->info)
    3915             :     {
    3916           0 :       vty_out (vty, "%% Same network configuration exists%s", VTY_NEWLINE);
    3917           0 :       bgp_unlock_node (rn);
    3918             :     }
    3919             :   else
    3920             :     {
    3921             :       /* New configuration. */
    3922           0 :       bgp_static = bgp_static_new ();
    3923           0 :       bgp_static->valid = 1;
    3924           0 :       memcpy (bgp_static->tag, tag, 3);
    3925           0 :       rn->info = bgp_static;
    3926             : 
    3927           0 :       bgp_static_update_vpnv4 (bgp, &p, AFI_IP, SAFI_MPLS_VPN, &prd, tag);
    3928             :     }
    3929             : 
    3930           0 :   return CMD_SUCCESS;
    3931             : }
    3932             : 
    3933             : /* Configure static BGP network. */
    3934             : int
    3935           0 : bgp_static_unset_vpnv4 (struct vty *vty, const char *ip_str, 
    3936             :                         const char *rd_str, const char *tag_str)
    3937             : {
    3938             :   int ret;
    3939             :   struct bgp *bgp;
    3940             :   struct prefix p;
    3941             :   struct prefix_rd prd;
    3942             :   struct bgp_node *prn;
    3943             :   struct bgp_node *rn;
    3944             :   struct bgp_table *table;
    3945             :   struct bgp_static *bgp_static;
    3946             :   u_char tag[3];
    3947             : 
    3948           0 :   bgp = vty->index;
    3949             : 
    3950             :   /* Convert IP prefix string to struct prefix. */
    3951           0 :   ret = str2prefix (ip_str, &p);
    3952           0 :   if (! ret)
    3953             :     {
    3954           0 :       vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
    3955           0 :       return CMD_WARNING;
    3956             :     }
    3957           0 :   apply_mask (&p);
    3958             : 
    3959           0 :   ret = str2prefix_rd (rd_str, &prd);
    3960           0 :   if (! ret)
    3961             :     {
    3962           0 :       vty_out (vty, "%% Malformed rd%s", VTY_NEWLINE);
    3963           0 :       return CMD_WARNING;
    3964             :     }
    3965             : 
    3966           0 :   ret = str2tag (tag_str, tag);
    3967           0 :   if (! ret)
    3968             :     {
    3969           0 :       vty_out (vty, "%% Malformed tag%s", VTY_NEWLINE);
    3970           0 :       return CMD_WARNING;
    3971             :     }
    3972             : 
    3973           0 :   prn = bgp_node_get (bgp->route[AFI_IP][SAFI_MPLS_VPN],
    3974             :                         (struct prefix *)&prd);
    3975           0 :   if (prn->info == NULL)
    3976           0 :     prn->info = bgp_table_init (AFI_IP, SAFI_MPLS_VPN);
    3977             :   else
    3978           0 :     bgp_unlock_node (prn);
    3979           0 :   table = prn->info;
    3980             : 
    3981           0 :   rn = bgp_node_lookup (table, &p);
    3982             : 
    3983           0 :   if (rn)
    3984             :     {
    3985           0 :       bgp_static_withdraw_vpnv4 (bgp, &p, AFI_IP, SAFI_MPLS_VPN, &prd, tag);
    3986             : 
    3987           0 :       bgp_static = rn->info;
    3988           0 :       bgp_static_free (bgp_static);
    3989           0 :       rn->info = NULL;
    3990           0 :       bgp_unlock_node (rn);
    3991           0 :       bgp_unlock_node (rn);
    3992             :     }
    3993             :   else
    3994           0 :     vty_out (vty, "%% Can't find the route%s", VTY_NEWLINE);
    3995             : 
    3996           0 :   return CMD_SUCCESS;
    3997             : }
    3998             : 
    3999           0 : DEFUN (bgp_network,
    4000             :        bgp_network_cmd,
    4001             :        "network A.B.C.D/M",
    4002             :        "Specify a network to announce via BGP\n"
    4003             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
    4004             : {
    4005           0 :   return bgp_static_set (vty, vty->index, argv[0],
    4006           0 :                          AFI_IP, bgp_node_safi (vty), NULL, 0);
    4007             : }
    4008             : 
    4009           0 : DEFUN (bgp_network_route_map,
    4010             :        bgp_network_route_map_cmd,
    4011             :        "network A.B.C.D/M route-map WORD",
    4012             :        "Specify a network to announce via BGP\n"
    4013             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
    4014             :        "Route-map to modify the attributes\n"
    4015             :        "Name of the route map\n")
    4016             : {
    4017           0 :   return bgp_static_set (vty, vty->index, argv[0],
    4018           0 :                          AFI_IP, bgp_node_safi (vty), argv[1], 0);
    4019             : }
    4020             : 
    4021           0 : DEFUN (bgp_network_backdoor,
    4022             :        bgp_network_backdoor_cmd,
    4023             :        "network A.B.C.D/M backdoor",
    4024             :        "Specify a network to announce via BGP\n"
    4025             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
    4026             :        "Specify a BGP backdoor route\n")
    4027             : {
    4028           0 :   return bgp_static_set (vty, vty->index, argv[0], AFI_IP, SAFI_UNICAST,
    4029             :                          NULL, 1);
    4030             : }
    4031             : 
    4032           0 : DEFUN (bgp_network_mask,
    4033             :        bgp_network_mask_cmd,
    4034             :        "network A.B.C.D mask A.B.C.D",
    4035             :        "Specify a network to announce via BGP\n"
    4036             :        "Network number\n"
    4037             :        "Network mask\n"
    4038             :        "Network mask\n")
    4039             : {
    4040             :   int ret;
    4041             :   char prefix_str[BUFSIZ];
    4042             :   
    4043           0 :   ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
    4044           0 :   if (! ret)
    4045             :     {
    4046           0 :       vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
    4047           0 :       return CMD_WARNING;
    4048             :     }
    4049             : 
    4050           0 :   return bgp_static_set (vty, vty->index, prefix_str,
    4051           0 :                          AFI_IP, bgp_node_safi (vty), NULL, 0);
    4052             : }
    4053             : 
    4054           0 : DEFUN (bgp_network_mask_route_map,
    4055             :        bgp_network_mask_route_map_cmd,
    4056             :        "network A.B.C.D mask A.B.C.D route-map WORD",
    4057             :        "Specify a network to announce via BGP\n"
    4058             :        "Network number\n"
    4059             :        "Network mask\n"
    4060             :        "Network mask\n"
    4061             :        "Route-map to modify the attributes\n"
    4062             :        "Name of the route map\n")
    4063             : {
    4064             :   int ret;
    4065             :   char prefix_str[BUFSIZ];
    4066             :   
    4067           0 :   ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
    4068           0 :   if (! ret)
    4069             :     {
    4070           0 :       vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
    4071           0 :       return CMD_WARNING;
    4072             :     }
    4073             : 
    4074           0 :   return bgp_static_set (vty, vty->index, prefix_str,
    4075           0 :                          AFI_IP, bgp_node_safi (vty), argv[2], 0);
    4076             : }
    4077             : 
    4078           0 : DEFUN (bgp_network_mask_backdoor,
    4079             :        bgp_network_mask_backdoor_cmd,
    4080             :        "network A.B.C.D mask A.B.C.D backdoor",
    4081             :        "Specify a network to announce via BGP\n"
    4082             :        "Network number\n"
    4083             :        "Network mask\n"
    4084             :        "Network mask\n"
    4085             :        "Specify a BGP backdoor route\n")
    4086             : {
    4087             :   int ret;
    4088             :   char prefix_str[BUFSIZ];
    4089             :   
    4090           0 :   ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
    4091           0 :   if (! ret)
    4092             :     {
    4093           0 :       vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
    4094           0 :       return CMD_WARNING;
    4095             :     }
    4096             : 
    4097           0 :   return bgp_static_set (vty, vty->index, prefix_str, AFI_IP, SAFI_UNICAST,
    4098             :                          NULL, 1);
    4099             : }
    4100             : 
    4101           0 : DEFUN (bgp_network_mask_natural,
    4102             :        bgp_network_mask_natural_cmd,
    4103             :        "network A.B.C.D",
    4104             :        "Specify a network to announce via BGP\n"
    4105             :        "Network number\n")
    4106             : {
    4107             :   int ret;
    4108             :   char prefix_str[BUFSIZ];
    4109             : 
    4110           0 :   ret = netmask_str2prefix_str (argv[0], NULL, prefix_str);
    4111           0 :   if (! ret)
    4112             :     {
    4113           0 :       vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
    4114           0 :       return CMD_WARNING;
    4115             :     }
    4116             : 
    4117           0 :   return bgp_static_set (vty, vty->index, prefix_str,
    4118           0 :                          AFI_IP, bgp_node_safi (vty), NULL, 0);
    4119             : }
    4120             : 
    4121           0 : DEFUN (bgp_network_mask_natural_route_map,
    4122             :        bgp_network_mask_natural_route_map_cmd,
    4123             :        "network A.B.C.D route-map WORD",
    4124             :        "Specify a network to announce via BGP\n"
    4125             :        "Network number\n"
    4126             :        "Route-map to modify the attributes\n"
    4127             :        "Name of the route map\n")
    4128             : {
    4129             :   int ret;
    4130             :   char prefix_str[BUFSIZ];
    4131             : 
    4132           0 :   ret = netmask_str2prefix_str (argv[0], NULL, prefix_str);
    4133           0 :   if (! ret)
    4134             :     {
    4135           0 :       vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
    4136           0 :       return CMD_WARNING;
    4137             :     }
    4138             : 
    4139           0 :   return bgp_static_set (vty, vty->index, prefix_str,
    4140           0 :                          AFI_IP, bgp_node_safi (vty), argv[1], 0);
    4141             : }
    4142             : 
    4143           0 : DEFUN (bgp_network_mask_natural_backdoor,
    4144             :        bgp_network_mask_natural_backdoor_cmd,
    4145             :        "network A.B.C.D backdoor",
    4146             :        "Specify a network to announce via BGP\n"
    4147             :        "Network number\n"
    4148             :        "Specify a BGP backdoor route\n")
    4149             : {
    4150             :   int ret;
    4151             :   char prefix_str[BUFSIZ];
    4152             : 
    4153           0 :   ret = netmask_str2prefix_str (argv[0], NULL, prefix_str);
    4154           0 :   if (! ret)
    4155             :     {
    4156           0 :       vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
    4157           0 :       return CMD_WARNING;
    4158             :     }
    4159             : 
    4160           0 :   return bgp_static_set (vty, vty->index, prefix_str, AFI_IP, SAFI_UNICAST,
    4161             :                          NULL, 1);
    4162             : }
    4163             : 
    4164           0 : DEFUN (no_bgp_network,
    4165             :        no_bgp_network_cmd,
    4166             :        "no network A.B.C.D/M",
    4167             :        NO_STR
    4168             :        "Specify a network to announce via BGP\n"
    4169             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
    4170             : {
    4171           0 :   return bgp_static_unset (vty, vty->index, argv[0], AFI_IP, 
    4172           0 :                            bgp_node_safi (vty));
    4173             : }
    4174             : 
    4175             : ALIAS (no_bgp_network,
    4176             :        no_bgp_network_route_map_cmd,
    4177             :        "no network A.B.C.D/M route-map WORD",
    4178             :        NO_STR
    4179             :        "Specify a network to announce via BGP\n"
    4180             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
    4181             :        "Route-map to modify the attributes\n"
    4182             :        "Name of the route map\n")
    4183             : 
    4184             : ALIAS (no_bgp_network,
    4185             :        no_bgp_network_backdoor_cmd,
    4186             :        "no network A.B.C.D/M backdoor",
    4187             :        NO_STR
    4188             :        "Specify a network to announce via BGP\n"
    4189             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
    4190             :        "Specify a BGP backdoor route\n")
    4191             : 
    4192           0 : DEFUN (no_bgp_network_mask,
    4193             :        no_bgp_network_mask_cmd,
    4194             :        "no network A.B.C.D mask A.B.C.D",
    4195             :        NO_STR
    4196             :        "Specify a network to announce via BGP\n"
    4197             :        "Network number\n"
    4198             :        "Network mask\n"
    4199             :        "Network mask\n")
    4200             : {
    4201             :   int ret;
    4202             :   char prefix_str[BUFSIZ];
    4203             : 
    4204           0 :   ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
    4205           0 :   if (! ret)
    4206             :     {
    4207           0 :       vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
    4208           0 :       return CMD_WARNING;
    4209             :     }
    4210             : 
    4211           0 :   return bgp_static_unset (vty, vty->index, prefix_str, AFI_IP, 
    4212           0 :                            bgp_node_safi (vty));
    4213             : }
    4214             : 
    4215             : ALIAS (no_bgp_network_mask,
    4216             :        no_bgp_network_mask_route_map_cmd,
    4217             :        "no network A.B.C.D mask A.B.C.D route-map WORD",
    4218             :        NO_STR
    4219             :        "Specify a network to announce via BGP\n"
    4220             :        "Network number\n"
    4221             :        "Network mask\n"
    4222             :        "Network mask\n"
    4223             :        "Route-map to modify the attributes\n"
    4224             :        "Name of the route map\n")
    4225             : 
    4226             : ALIAS (no_bgp_network_mask,
    4227             :        no_bgp_network_mask_backdoor_cmd,
    4228             :        "no network A.B.C.D mask A.B.C.D backdoor",
    4229             :        NO_STR
    4230             :        "Specify a network to announce via BGP\n"
    4231             :        "Network number\n"
    4232             :        "Network mask\n"
    4233             :        "Network mask\n"
    4234             :        "Specify a BGP backdoor route\n")
    4235             : 
    4236           0 : DEFUN (no_bgp_network_mask_natural,
    4237             :        no_bgp_network_mask_natural_cmd,
    4238             :        "no network A.B.C.D",
    4239             :        NO_STR
    4240             :        "Specify a network to announce via BGP\n"
    4241             :        "Network number\n")
    4242             : {
    4243             :   int ret;
    4244             :   char prefix_str[BUFSIZ];
    4245             : 
    4246           0 :   ret = netmask_str2prefix_str (argv[0], NULL, prefix_str);
    4247           0 :   if (! ret)
    4248             :     {
    4249           0 :       vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
    4250           0 :       return CMD_WARNING;
    4251             :     }
    4252             : 
    4253           0 :   return bgp_static_unset (vty, vty->index, prefix_str, AFI_IP, 
    4254           0 :                            bgp_node_safi (vty));
    4255             : }
    4256             : 
    4257             : ALIAS (no_bgp_network_mask_natural,
    4258             :        no_bgp_network_mask_natural_route_map_cmd,
    4259             :        "no network A.B.C.D route-map WORD",
    4260             :        NO_STR
    4261             :        "Specify a network to announce via BGP\n"
    4262             :        "Network number\n"
    4263             :        "Route-map to modify the attributes\n"
    4264             :        "Name of the route map\n")
    4265             : 
    4266             : ALIAS (no_bgp_network_mask_natural,
    4267             :        no_bgp_network_mask_natural_backdoor_cmd,
    4268             :        "no network A.B.C.D backdoor",
    4269             :        NO_STR
    4270             :        "Specify a network to announce via BGP\n"
    4271             :        "Network number\n"
    4272             :        "Specify a BGP backdoor route\n")
    4273             : 
    4274             : #ifdef HAVE_IPV6
    4275           0 : DEFUN (ipv6_bgp_network,
    4276             :        ipv6_bgp_network_cmd,
    4277             :        "network X:X::X:X/M",
    4278             :        "Specify a network to announce via BGP\n"
    4279             :        "IPv6 prefix <network>/<length>\n")
    4280             : {
    4281           0 :   return bgp_static_set (vty, vty->index, argv[0], AFI_IP6, bgp_node_safi(vty),
    4282             :                          NULL, 0);
    4283             : }
    4284             : 
    4285           0 : DEFUN (ipv6_bgp_network_route_map,
    4286             :        ipv6_bgp_network_route_map_cmd,
    4287             :        "network X:X::X:X/M route-map WORD",
    4288             :        "Specify a network to announce via BGP\n"
    4289             :        "IPv6 prefix <network>/<length>\n"
    4290             :        "Route-map to modify the attributes\n"
    4291             :        "Name of the route map\n")
    4292             : {
    4293           0 :   return bgp_static_set (vty, vty->index, argv[0], AFI_IP6,
    4294           0 :                          bgp_node_safi (vty), argv[1], 0);
    4295             : }
    4296             : 
    4297           0 : DEFUN (no_ipv6_bgp_network,
    4298             :        no_ipv6_bgp_network_cmd,
    4299             :        "no network X:X::X:X/M",
    4300             :        NO_STR
    4301             :        "Specify a network to announce via BGP\n"
    4302             :        "IPv6 prefix <network>/<length>\n")
    4303             : {
    4304           0 :   return bgp_static_unset (vty, vty->index, argv[0], AFI_IP6, bgp_node_safi(vty));
    4305             : }
    4306             : 
    4307             : ALIAS (no_ipv6_bgp_network,
    4308             :        no_ipv6_bgp_network_route_map_cmd,
    4309             :        "no network X:X::X:X/M route-map WORD",
    4310             :        NO_STR
    4311             :        "Specify a network to announce via BGP\n"
    4312             :        "IPv6 prefix <network>/<length>\n"
    4313             :        "Route-map to modify the attributes\n"
    4314             :        "Name of the route map\n")
    4315             : 
    4316             : ALIAS (ipv6_bgp_network,
    4317             :        old_ipv6_bgp_network_cmd,
    4318             :        "ipv6 bgp network X:X::X:X/M",
    4319             :        IPV6_STR
    4320             :        BGP_STR
    4321             :        "Specify a network to announce via BGP\n"
    4322             :        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
    4323             : 
    4324             : ALIAS (no_ipv6_bgp_network,
    4325             :        old_no_ipv6_bgp_network_cmd,
    4326             :        "no ipv6 bgp network X:X::X:X/M",
    4327             :        NO_STR
    4328             :        IPV6_STR
    4329             :        BGP_STR
    4330             :        "Specify a network to announce via BGP\n"
    4331             :        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
    4332             : #endif /* HAVE_IPV6 */
    4333             : 
    4334             : /* stubs for removed AS-Pathlimit commands, kept for config compatibility */
    4335             : ALIAS_DEPRECATED (bgp_network,
    4336             :        bgp_network_ttl_cmd,
    4337             :        "network A.B.C.D/M pathlimit <0-255>",
    4338             :        "Specify a network to announce via BGP\n"
    4339             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
    4340             :        "AS-Path hopcount limit attribute\n"
    4341             :        "AS-Pathlimit TTL, in number of AS-Path hops\n")
    4342             : ALIAS_DEPRECATED (bgp_network_backdoor,
    4343             :        bgp_network_backdoor_ttl_cmd,
    4344             :        "network A.B.C.D/M backdoor pathlimit <0-255>",
    4345             :        "Specify a network to announce via BGP\n"
    4346             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
    4347             :        "Specify a BGP backdoor route\n"
    4348             :        "AS-Path hopcount limit attribute\n"
    4349             :        "AS-Pathlimit TTL, in number of AS-Path hops\n")
    4350             : ALIAS_DEPRECATED (bgp_network_mask,
    4351             :        bgp_network_mask_ttl_cmd,
    4352             :        "network A.B.C.D mask A.B.C.D pathlimit <0-255>",
    4353             :        "Specify a network to announce via BGP\n"
    4354             :        "Network number\n"
    4355             :        "Network mask\n"
    4356             :        "Network mask\n"
    4357             :        "AS-Path hopcount limit attribute\n"
    4358             :        "AS-Pathlimit TTL, in number of AS-Path hops\n")
    4359             : ALIAS_DEPRECATED (bgp_network_mask_backdoor,
    4360             :        bgp_network_mask_backdoor_ttl_cmd,
    4361             :        "network A.B.C.D mask A.B.C.D backdoor pathlimit <0-255>",
    4362             :        "Specify a network to announce via BGP\n"
    4363             :        "Network number\n"
    4364             :        "Network mask\n"
    4365             :        "Network mask\n"
    4366             :        "Specify a BGP backdoor route\n"
    4367             :        "AS-Path hopcount limit attribute\n"
    4368             :        "AS-Pathlimit TTL, in number of AS-Path hops\n")
    4369             : ALIAS_DEPRECATED (bgp_network_mask_natural,
    4370             :        bgp_network_mask_natural_ttl_cmd,
    4371             :        "network A.B.C.D pathlimit <0-255>",
    4372             :        "Specify a network to announce via BGP\n"
    4373             :        "Network number\n"
    4374             :        "AS-Path hopcount limit attribute\n"
    4375             :        "AS-Pathlimit TTL, in number of AS-Path hops\n")
    4376             : ALIAS_DEPRECATED (bgp_network_mask_natural_backdoor,
    4377             :        bgp_network_mask_natural_backdoor_ttl_cmd,
    4378             :        "network A.B.C.D backdoor pathlimit <1-255>",
    4379             :        "Specify a network to announce via BGP\n"
    4380             :        "Network number\n"
    4381             :        "Specify a BGP backdoor route\n"
    4382             :        "AS-Path hopcount limit attribute\n"
    4383             :        "AS-Pathlimit TTL, in number of AS-Path hops\n")
    4384             : ALIAS_DEPRECATED (no_bgp_network,
    4385             :        no_bgp_network_ttl_cmd,
    4386             :        "no network A.B.C.D/M pathlimit <0-255>",
    4387             :        NO_STR
    4388             :        "Specify a network to announce via BGP\n"
    4389             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
    4390             :        "AS-Path hopcount limit attribute\n"
    4391             :        "AS-Pathlimit TTL, in number of AS-Path hops\n")
    4392             : ALIAS_DEPRECATED (no_bgp_network,
    4393             :        no_bgp_network_backdoor_ttl_cmd,
    4394             :        "no network A.B.C.D/M backdoor pathlimit <0-255>",
    4395             :        NO_STR
    4396             :        "Specify a network to announce via BGP\n"
    4397             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
    4398             :        "Specify a BGP backdoor route\n"
    4399             :        "AS-Path hopcount limit attribute\n"
    4400             :        "AS-Pathlimit TTL, in number of AS-Path hops\n")
    4401             : ALIAS_DEPRECATED (no_bgp_network,
    4402             :        no_bgp_network_mask_ttl_cmd,
    4403             :        "no network A.B.C.D mask A.B.C.D pathlimit <0-255>",
    4404             :        NO_STR
    4405             :        "Specify a network to announce via BGP\n"
    4406             :        "Network number\n"
    4407             :        "Network mask\n"
    4408             :        "Network mask\n"
    4409             :        "AS-Path hopcount limit attribute\n"
    4410             :        "AS-Pathlimit TTL, in number of AS-Path hops\n")
    4411             : ALIAS_DEPRECATED (no_bgp_network_mask,
    4412             :        no_bgp_network_mask_backdoor_ttl_cmd,
    4413             :        "no network A.B.C.D mask A.B.C.D  backdoor pathlimit <0-255>",
    4414             :        NO_STR
    4415             :        "Specify a network to announce via BGP\n"
    4416             :        "Network number\n"
    4417             :        "Network mask\n"
    4418             :        "Network mask\n"
    4419             :        "Specify a BGP backdoor route\n"
    4420             :        "AS-Path hopcount limit attribute\n"
    4421             :        "AS-Pathlimit TTL, in number of AS-Path hops\n")
    4422             : ALIAS_DEPRECATED (no_bgp_network_mask_natural,
    4423             :        no_bgp_network_mask_natural_ttl_cmd,
    4424             :        "no network A.B.C.D pathlimit <0-255>",
    4425             :        NO_STR
    4426             :        "Specify a network to announce via BGP\n"
    4427             :        "Network number\n"
    4428             :        "AS-Path hopcount limit attribute\n"
    4429             :        "AS-Pathlimit TTL, in number of AS-Path hops\n")
    4430             : ALIAS_DEPRECATED (no_bgp_network_mask_natural,
    4431             :        no_bgp_network_mask_natural_backdoor_ttl_cmd,
    4432             :        "no network A.B.C.D backdoor pathlimit <0-255>",
    4433             :        NO_STR
    4434             :        "Specify a network to announce via BGP\n"
    4435             :        "Network number\n"
    4436             :        "Specify a BGP backdoor route\n"
    4437             :        "AS-Path hopcount limit attribute\n"
    4438             :        "AS-Pathlimit TTL, in number of AS-Path hops\n")
    4439             : #ifdef HAVE_IPV6
    4440             : ALIAS_DEPRECATED (ipv6_bgp_network,
    4441             :        ipv6_bgp_network_ttl_cmd,
    4442             :        "network X:X::X:X/M pathlimit <0-255>",
    4443             :        "Specify a network to announce via BGP\n"
    4444             :        "IPv6 prefix <network>/<length>\n"
    4445             :        "AS-Path hopcount limit attribute\n"
    4446             :        "AS-Pathlimit TTL, in number of AS-Path hops\n")
    4447             : ALIAS_DEPRECATED (no_ipv6_bgp_network,
    4448             :        no_ipv6_bgp_network_ttl_cmd,
    4449             :        "no network X:X::X:X/M pathlimit <0-255>",
    4450             :        NO_STR
    4451             :        "Specify a network to announce via BGP\n"
    4452             :        "IPv6 prefix <network>/<length>\n"
    4453             :        "AS-Path hopcount limit attribute\n"
    4454             :        "AS-Pathlimit TTL, in number of AS-Path hops\n")
    4455             : #endif /* HAVE_IPV6 */
    4456             : 
    4457             : /* Aggreagete address:
    4458             : 
    4459             :   advertise-map  Set condition to advertise attribute
    4460             :   as-set         Generate AS set path information
    4461             :   attribute-map  Set attributes of aggregate
    4462             :   route-map      Set parameters of aggregate
    4463             :   summary-only   Filter more specific routes from updates
    4464             :   suppress-map   Conditionally filter more specific routes from updates
    4465             :   <cr>
    4466             :  */
    4467             : struct bgp_aggregate
    4468             : {
    4469             :   /* Summary-only flag. */
    4470             :   u_char summary_only;
    4471             : 
    4472             :   /* AS set generation. */
    4473             :   u_char as_set;
    4474             : 
    4475             :   /* Route-map for aggregated route. */
    4476             :   struct route_map *map;
    4477             : 
    4478             :   /* Suppress-count. */
    4479             :   unsigned long count;
    4480             : 
    4481             :   /* SAFI configuration. */
    4482             :   safi_t safi;
    4483             : };
    4484             : 
    4485             : static struct bgp_aggregate *
    4486           0 : bgp_aggregate_new (void)
    4487             : {
    4488           0 :   return XCALLOC (MTYPE_BGP_AGGREGATE, sizeof (struct bgp_aggregate));
    4489             : }
    4490             : 
    4491             : static void
    4492           0 : bgp_aggregate_free (struct bgp_aggregate *aggregate)
    4493             : {
    4494           0 :   XFREE (MTYPE_BGP_AGGREGATE, aggregate);
    4495           0 : }     
    4496             : 
    4497             : static void
    4498           0 : bgp_aggregate_route (struct bgp *bgp, struct prefix *p, struct bgp_info *rinew,
    4499             :                      afi_t afi, safi_t safi, struct bgp_info *del, 
    4500             :                      struct bgp_aggregate *aggregate)
    4501             : {
    4502             :   struct bgp_table *table;
    4503             :   struct bgp_node *top;
    4504             :   struct bgp_node *rn;
    4505             :   u_char origin;
    4506           0 :   struct aspath *aspath = NULL;
    4507           0 :   struct aspath *asmerge = NULL;
    4508           0 :   struct community *community = NULL;
    4509           0 :   struct community *commerge = NULL;
    4510             :   struct in_addr nexthop;
    4511           0 :   u_int32_t med = 0;
    4512             :   struct bgp_info *ri;
    4513             :   struct bgp_info *new;
    4514           0 :   int first = 1;
    4515           0 :   unsigned long match = 0;
    4516             : 
    4517             :   /* Record adding route's nexthop and med. */
    4518           0 :   if (rinew)
    4519             :     {
    4520           0 :       nexthop = rinew->attr->nexthop;
    4521           0 :       med = rinew->attr->med;
    4522             :     }
    4523             : 
    4524             :   /* ORIGIN attribute: If at least one route among routes that are
    4525             :      aggregated has ORIGIN with the value INCOMPLETE, then the
    4526             :      aggregated route must have the ORIGIN attribute with the value
    4527             :      INCOMPLETE. Otherwise, if at least one route among routes that
    4528             :      are aggregated has ORIGIN with the value EGP, then the aggregated
    4529             :      route must have the origin attribute with the value EGP. In all
    4530             :      other case the value of the ORIGIN attribute of the aggregated
    4531             :      route is INTERNAL. */
    4532           0 :   origin = BGP_ORIGIN_IGP;
    4533             : 
    4534           0 :   table = bgp->rib[afi][safi];
    4535             : 
    4536           0 :   top = bgp_node_get (table, p);
    4537           0 :   for (rn = bgp_node_get (table, p); rn; rn = bgp_route_next_until (rn, top))
    4538           0 :     if (rn->p.prefixlen > p->prefixlen)
    4539             :       {
    4540           0 :         match = 0;
    4541             : 
    4542           0 :         for (ri = rn->info; ri; ri = ri->next)
    4543             :           {
    4544           0 :             if (BGP_INFO_HOLDDOWN (ri))
    4545           0 :               continue;
    4546             : 
    4547           0 :             if (del && ri == del)
    4548           0 :               continue;
    4549             : 
    4550           0 :             if (! rinew && first)
    4551             :               {
    4552           0 :                 nexthop = ri->attr->nexthop;
    4553           0 :                 med = ri->attr->med;
    4554           0 :                 first = 0;
    4555             :               }
    4556             : 
    4557             : #ifdef AGGREGATE_NEXTHOP_CHECK
    4558             :             if (! IPV4_ADDR_SAME (&ri->attr->nexthop, &nexthop)
    4559             :                 || ri->attr->med != med)
    4560             :               {
    4561             :                 if (aspath)
    4562             :                   aspath_free (aspath);
    4563             :                 if (community)
    4564             :                   community_free (community);
    4565             :                 bgp_unlock_node (rn);
    4566             :                 bgp_unlock_node (top);
    4567             :                 return;
    4568             :               }
    4569             : #endif /* AGGREGATE_NEXTHOP_CHECK */
    4570             : 
    4571           0 :             if (ri->sub_type != BGP_ROUTE_AGGREGATE)
    4572             :               {
    4573           0 :                 if (aggregate->summary_only)
    4574             :                   {
    4575           0 :                     (bgp_info_extra_get (ri))->suppress++;
    4576           0 :                     bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
    4577           0 :                     match++;
    4578             :                   }
    4579             : 
    4580           0 :                 aggregate->count++;
    4581             : 
    4582           0 :                 if (aggregate->as_set)
    4583             :                   {
    4584           0 :                     if (origin < ri->attr->origin)
    4585           0 :                       origin = ri->attr->origin;
    4586             : 
    4587           0 :                     if (aspath)
    4588             :                       {
    4589           0 :                         asmerge = aspath_aggregate (aspath, ri->attr->aspath);
    4590           0 :                         aspath_free (aspath);
    4591           0 :                         aspath = asmerge;
    4592             :                       }
    4593             :                     else
    4594           0 :                       aspath = aspath_dup (ri->attr->aspath);
    4595             : 
    4596           0 :                     if (ri->attr->community)
    4597             :                       {
    4598           0 :                         if (community)
    4599             :                           {
    4600           0 :                             commerge = community_merge (community,
    4601           0 :                                                         ri->attr->community);
    4602           0 :                             community = community_uniq_sort (commerge);
    4603           0 :                             community_free (commerge);
    4604             :                           }
    4605             :                         else
    4606           0 :                           community = community_dup (ri->attr->community);
    4607             :                       }
    4608             :                   }
    4609             :               }
    4610             :           }
    4611           0 :         if (match)
    4612           0 :           bgp_process (bgp, rn, afi, safi);
    4613             :       }
    4614           0 :   bgp_unlock_node (top);
    4615             : 
    4616           0 :   if (rinew)
    4617             :     {
    4618           0 :       aggregate->count++;
    4619             :       
    4620           0 :       if (aggregate->summary_only)
    4621           0 :         (bgp_info_extra_get (rinew))->suppress++;
    4622             : 
    4623           0 :       if (aggregate->as_set)
    4624             :         {
    4625           0 :           if (origin < rinew->attr->origin)
    4626           0 :             origin = rinew->attr->origin;
    4627             : 
    4628           0 :           if (aspath)
    4629             :             {
    4630           0 :               asmerge = aspath_aggregate (aspath, rinew->attr->aspath);
    4631           0 :               aspath_free (aspath);
    4632           0 :               aspath = asmerge;
    4633             :             }
    4634             :           else
    4635           0 :             aspath = aspath_dup (rinew->attr->aspath);
    4636             : 
    4637           0 :           if (rinew->attr->community)
    4638             :             {
    4639           0 :               if (community)
    4640             :                 {
    4641           0 :                   commerge = community_merge (community,
    4642           0 :                                               rinew->attr->community);
    4643           0 :                   community = community_uniq_sort (commerge);
    4644           0 :                   community_free (commerge);
    4645             :                 }
    4646             :               else
    4647           0 :                 community = community_dup (rinew->attr->community);
    4648             :             }
    4649             :         }
    4650             :     }
    4651             : 
    4652           0 :   if (aggregate->count > 0)
    4653             :     {
    4654           0 :       rn = bgp_node_get (table, p);
    4655           0 :       new = bgp_info_new ();
    4656           0 :       new->type = ZEBRA_ROUTE_BGP;
    4657           0 :       new->sub_type = BGP_ROUTE_AGGREGATE;
    4658           0 :       new->peer = bgp->peer_self;
    4659           0 :       SET_FLAG (new->flags, BGP_INFO_VALID);
    4660           0 :       new->attr = bgp_attr_aggregate_intern (bgp, origin, aspath, community, aggregate->as_set);
    4661           0 :       new->uptime = bgp_clock ();
    4662             : 
    4663           0 :       bgp_info_add (rn, new);
    4664           0 :       bgp_unlock_node (rn);
    4665           0 :       bgp_process (bgp, rn, afi, safi);
    4666             :     }
    4667             :   else
    4668             :     {
    4669           0 :       if (aspath)
    4670           0 :         aspath_free (aspath);
    4671           0 :       if (community)
    4672           0 :         community_free (community);
    4673             :     }
    4674           0 : }
    4675             : 
    4676             : void bgp_aggregate_delete (struct bgp *, struct prefix *, afi_t, safi_t,
    4677             :                            struct bgp_aggregate *);
    4678             : 
    4679             : void
    4680           0 : bgp_aggregate_increment (struct bgp *bgp, struct prefix *p,
    4681             :                          struct bgp_info *ri, afi_t afi, safi_t safi)
    4682             : {
    4683             :   struct bgp_node *child;
    4684             :   struct bgp_node *rn;
    4685             :   struct bgp_aggregate *aggregate;
    4686             :   struct bgp_table *table;
    4687             : 
    4688             :   /* MPLS-VPN aggregation is not yet supported. */
    4689           0 :   if (safi == SAFI_MPLS_VPN)
    4690           0 :     return;
    4691             : 
    4692           0 :   table = bgp->aggregate[afi][safi];
    4693             : 
    4694             :   /* No aggregates configured. */
    4695           0 :   if (bgp_table_top_nolock (table) == NULL)
    4696           0 :     return;
    4697             : 
    4698           0 :   if (p->prefixlen == 0)
    4699           0 :     return;
    4700             : 
    4701           0 :   if (BGP_INFO_HOLDDOWN (ri))
    4702           0 :     return;
    4703             : 
    4704           0 :   child = bgp_node_get (table, p);
    4705             : 
    4706             :   /* Aggregate address configuration check. */
    4707           0 :   for (rn = child; rn; rn = bgp_node_parent_nolock (rn))
    4708           0 :     if ((aggregate = rn->info) != NULL && rn->p.prefixlen < p->prefixlen)
    4709             :       {
    4710           0 :         bgp_aggregate_delete (bgp, &rn->p, afi, safi, aggregate);
    4711           0 :         bgp_aggregate_route (bgp, &rn->p, ri, afi, safi, NULL, aggregate);
    4712             :       }
    4713           0 :   bgp_unlock_node (child);
    4714             : }
    4715             : 
    4716             : void
    4717           0 : bgp_aggregate_decrement (struct bgp *bgp, struct prefix *p, 
    4718             :                          struct bgp_info *del, afi_t afi, safi_t safi)
    4719             : {
    4720             :   struct bgp_node *child;
    4721             :   struct bgp_node *rn;
    4722             :   struct bgp_aggregate *aggregate;
    4723             :   struct bgp_table *table;
    4724             : 
    4725             :   /* MPLS-VPN aggregation is not yet supported. */
    4726           0 :   if (safi == SAFI_MPLS_VPN)
    4727           0 :     return;
    4728             : 
    4729           0 :   table = bgp->aggregate[afi][safi];
    4730             : 
    4731             :   /* No aggregates configured. */
    4732           0 :   if (bgp_table_top_nolock (table) == NULL)
    4733           0 :     return;
    4734             : 
    4735           0 :   if (p->prefixlen == 0)
    4736           0 :     return;
    4737             : 
    4738           0 :   child = bgp_node_get (table, p);
    4739             : 
    4740             :   /* Aggregate address configuration check. */
    4741           0 :   for (rn = child; rn; rn = bgp_node_parent_nolock (rn))
    4742           0 :     if ((aggregate = rn->info) != NULL && rn->p.prefixlen < p->prefixlen)
    4743             :       {
    4744           0 :         bgp_aggregate_delete (bgp, &rn->p, afi, safi, aggregate);
    4745           0 :         bgp_aggregate_route (bgp, &rn->p, NULL, afi, safi, del, aggregate);
    4746             :       }
    4747           0 :   bgp_unlock_node (child);
    4748             : }
    4749             : 
    4750             : static void
    4751           0 : bgp_aggregate_add (struct bgp *bgp, struct prefix *p, afi_t afi, safi_t safi,
    4752             :                    struct bgp_aggregate *aggregate)
    4753             : {
    4754             :   struct bgp_table *table;
    4755             :   struct bgp_node *top;
    4756             :   struct bgp_node *rn;
    4757             :   struct bgp_info *new;
    4758             :   struct bgp_info *ri;
    4759             :   unsigned long match;
    4760           0 :   u_char origin = BGP_ORIGIN_IGP;
    4761           0 :   struct aspath *aspath = NULL;
    4762           0 :   struct aspath *asmerge = NULL;
    4763           0 :   struct community *community = NULL;
    4764           0 :   struct community *commerge = NULL;
    4765             : 
    4766           0 :   table = bgp->rib[afi][safi];
    4767             : 
    4768             :   /* Sanity check. */
    4769           0 :   if (afi == AFI_IP && p->prefixlen == IPV4_MAX_BITLEN)
    4770           0 :     return;
    4771           0 :   if (afi == AFI_IP6 && p->prefixlen == IPV6_MAX_BITLEN)
    4772           0 :     return;
    4773             :     
    4774             :   /* If routes exists below this node, generate aggregate routes. */
    4775           0 :   top = bgp_node_get (table, p);
    4776           0 :   for (rn = bgp_node_get (table, p); rn; rn = bgp_route_next_until (rn, top))
    4777           0 :     if (rn->p.prefixlen > p->prefixlen)
    4778             :       {
    4779           0 :         match = 0;
    4780             : 
    4781           0 :         for (ri = rn->info; ri; ri = ri->next)
    4782             :           {
    4783           0 :             if (BGP_INFO_HOLDDOWN (ri))
    4784           0 :               continue;
    4785             : 
    4786           0 :             if (ri->sub_type != BGP_ROUTE_AGGREGATE)
    4787             :               {
    4788             :                 /* summary-only aggregate route suppress aggregated
    4789             :                    route announcement.  */
    4790           0 :                 if (aggregate->summary_only)
    4791             :                   {
    4792           0 :                     (bgp_info_extra_get (ri))->suppress++;
    4793           0 :                     bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
    4794           0 :                     match++;
    4795             :                   }
    4796             :                 /* as-set aggregate route generate origin, as path,
    4797             :                    community aggregation.  */
    4798           0 :                 if (aggregate->as_set)
    4799             :                   {
    4800           0 :                     if (origin < ri->attr->origin)
    4801           0 :                       origin = ri->attr->origin;
    4802             : 
    4803           0 :                     if (aspath)
    4804             :                       {
    4805           0 :                         asmerge = aspath_aggregate (aspath, ri->attr->aspath);
    4806           0 :                         aspath_free (aspath);
    4807           0 :                         aspath = asmerge;
    4808             :                       }
    4809             :                     else
    4810           0 :                       aspath = aspath_dup (ri->attr->aspath);
    4811             : 
    4812           0 :                     if (ri->attr->community)
    4813             :                       {
    4814           0 :                         if (community)
    4815             :                           {
    4816           0 :                             commerge = community_merge (community,
    4817           0 :                                                         ri->attr->community);
    4818           0 :                             community = community_uniq_sort (commerge);
    4819           0 :                             community_free (commerge);
    4820             :                           }
    4821             :                         else
    4822           0 :                           community = community_dup (ri->attr->community);
    4823             :                       }
    4824             :                   }
    4825           0 :                 aggregate->count++;
    4826             :               }
    4827             :           }
    4828             :         
    4829             :         /* If this node is suppressed, process the change. */
    4830           0 :         if (match)
    4831           0 :           bgp_process (bgp, rn, afi, safi);
    4832             :       }
    4833           0 :   bgp_unlock_node (top);
    4834             : 
    4835             :   /* Add aggregate route to BGP table. */
    4836           0 :   if (aggregate->count)
    4837             :     {
    4838           0 :       rn = bgp_node_get (table, p);
    4839             : 
    4840           0 :       new = bgp_info_new ();
    4841           0 :       new->type = ZEBRA_ROUTE_BGP;
    4842           0 :       new->sub_type = BGP_ROUTE_AGGREGATE;
    4843           0 :       new->peer = bgp->peer_self;
    4844           0 :       SET_FLAG (new->flags, BGP_INFO_VALID);
    4845           0 :       new->attr = bgp_attr_aggregate_intern (bgp, origin, aspath, community, aggregate->as_set);
    4846           0 :       new->uptime = bgp_clock ();
    4847             : 
    4848           0 :       bgp_info_add (rn, new);
    4849           0 :       bgp_unlock_node (rn);
    4850             :       
    4851             :       /* Process change. */
    4852           0 :       bgp_process (bgp, rn, afi, safi);
    4853             :     }
    4854             : }
    4855             : 
    4856             : void
    4857           0 : bgp_aggregate_delete (struct bgp *bgp, struct prefix *p, afi_t afi, 
    4858             :                       safi_t safi, struct bgp_aggregate *aggregate)
    4859             : {
    4860             :   struct bgp_table *table;
    4861             :   struct bgp_node *top;
    4862             :   struct bgp_node *rn;
    4863             :   struct bgp_info *ri;
    4864             :   unsigned long match;
    4865             : 
    4866           0 :   table = bgp->rib[afi][safi];
    4867             : 
    4868           0 :   if (afi == AFI_IP && p->prefixlen == IPV4_MAX_BITLEN)
    4869           0 :     return;
    4870           0 :   if (afi == AFI_IP6 && p->prefixlen == IPV6_MAX_BITLEN)
    4871           0 :     return;
    4872             : 
    4873             :   /* If routes exists below this node, generate aggregate routes. */
    4874           0 :   top = bgp_node_get (table, p);
    4875           0 :   for (rn = bgp_node_get (table, p); rn; rn = bgp_route_next_until (rn, top))
    4876           0 :     if (rn->p.prefixlen > p->prefixlen)
    4877             :       {
    4878           0 :         match = 0;
    4879             : 
    4880           0 :         for (ri = rn->info; ri; ri = ri->next)
    4881             :           {
    4882           0 :             if (BGP_INFO_HOLDDOWN (ri))
    4883           0 :               continue;
    4884             : 
    4885           0 :             if (ri->sub_type != BGP_ROUTE_AGGREGATE)
    4886             :               {
    4887           0 :                 if (aggregate->summary_only && ri->extra)
    4888             :                   {
    4889           0 :                     ri->extra->suppress--;
    4890             : 
    4891           0 :                     if (ri->extra->suppress == 0)
    4892             :                       {
    4893           0 :                         bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
    4894           0 :                         match++;
    4895             :                       }
    4896             :                   }
    4897           0 :                 aggregate->count--;
    4898             :               }
    4899             :           }
    4900             : 
    4901             :         /* If this node was suppressed, process the change. */
    4902           0 :         if (match)
    4903           0 :           bgp_process (bgp, rn, afi, safi);
    4904             :       }
    4905           0 :   bgp_unlock_node (top);
    4906             : 
    4907             :   /* Delete aggregate route from BGP table. */
    4908           0 :   rn = bgp_node_get (table, p);
    4909             : 
    4910           0 :   for (ri = rn->info; ri; ri = ri->next)
    4911           0 :     if (ri->peer == bgp->peer_self 
    4912           0 :         && ri->type == ZEBRA_ROUTE_BGP
    4913           0 :         && ri->sub_type == BGP_ROUTE_AGGREGATE)
    4914           0 :       break;
    4915             : 
    4916             :   /* Withdraw static BGP route from routing table. */
    4917           0 :   if (ri)
    4918             :     {
    4919           0 :       bgp_info_delete (rn, ri);
    4920           0 :       bgp_process (bgp, rn, afi, safi);
    4921             :     }
    4922             : 
    4923             :   /* Unlock bgp_node_lookup. */
    4924           0 :   bgp_unlock_node (rn);
    4925             : }
    4926             : 
    4927             : /* Aggregate route attribute. */
    4928             : #define AGGREGATE_SUMMARY_ONLY 1
    4929             : #define AGGREGATE_AS_SET       1
    4930             : 
    4931             : static int
    4932           0 : bgp_aggregate_unset (struct vty *vty, const char *prefix_str,
    4933             :                      afi_t afi, safi_t safi)
    4934             : {
    4935             :   int ret;
    4936             :   struct prefix p;
    4937             :   struct bgp_node *rn;
    4938             :   struct bgp *bgp;
    4939             :   struct bgp_aggregate *aggregate;
    4940             : 
    4941             :   /* Convert string to prefix structure. */
    4942           0 :   ret = str2prefix (prefix_str, &p);
    4943           0 :   if (!ret)
    4944             :     {
    4945           0 :       vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
    4946           0 :       return CMD_WARNING;
    4947             :     }
    4948           0 :   apply_mask (&p);
    4949             : 
    4950             :   /* Get BGP structure. */
    4951           0 :   bgp = vty->index;
    4952             : 
    4953             :   /* Old configuration check. */
    4954           0 :   rn = bgp_node_lookup (bgp->aggregate[afi][safi], &p);
    4955           0 :   if (! rn)
    4956             :     {
    4957           0 :       vty_out (vty, "%% There is no aggregate-address configuration.%s",
    4958           0 :                VTY_NEWLINE);
    4959           0 :       return CMD_WARNING;
    4960             :     }
    4961             : 
    4962           0 :   aggregate = rn->info;
    4963           0 :   if (aggregate->safi & SAFI_UNICAST)
    4964           0 :     bgp_aggregate_delete (bgp, &p, afi, SAFI_UNICAST, aggregate);
    4965           0 :   if (aggregate->safi & SAFI_MULTICAST)
    4966           0 :     bgp_aggregate_delete (bgp, &p, afi, SAFI_MULTICAST, aggregate);
    4967             : 
    4968             :   /* Unlock aggregate address configuration. */
    4969           0 :   rn->info = NULL;
    4970           0 :   bgp_aggregate_free (aggregate);
    4971           0 :   bgp_unlock_node (rn);
    4972           0 :   bgp_unlock_node (rn);
    4973             : 
    4974           0 :   return CMD_SUCCESS;
    4975             : }
    4976             : 
    4977             : static int
    4978           0 : bgp_aggregate_set (struct vty *vty, const char *prefix_str,
    4979             :                    afi_t afi, safi_t safi,
    4980             :                    u_char summary_only, u_char as_set)
    4981             : {
    4982             :   int ret;
    4983             :   struct prefix p;
    4984             :   struct bgp_node *rn;
    4985             :   struct bgp *bgp;
    4986             :   struct bgp_aggregate *aggregate;
    4987             : 
    4988             :   /* Convert string to prefix structure. */
    4989           0 :   ret = str2prefix (prefix_str, &p);
    4990           0 :   if (!ret)
    4991             :     {
    4992           0 :       vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
    4993           0 :       return CMD_WARNING;
    4994             :     }
    4995           0 :   apply_mask (&p);
    4996             : 
    4997             :   /* Get BGP structure. */
    4998           0 :   bgp = vty->index;
    4999             : 
    5000             :   /* Old configuration check. */
    5001           0 :   rn = bgp_node_get (bgp->aggregate[afi][safi], &p);
    5002             : 
    5003           0 :   if (rn->info)
    5004             :     {
    5005           0 :       vty_out (vty, "There is already same aggregate network.%s", VTY_NEWLINE);
    5006             :       /* try to remove the old entry */
    5007           0 :       ret = bgp_aggregate_unset (vty, prefix_str, afi, safi);
    5008           0 :       if (ret)
    5009             :         {
    5010           0 :           vty_out (vty, "Error deleting aggregate.%s", VTY_NEWLINE);
    5011           0 :           bgp_unlock_node (rn);
    5012           0 :           return CMD_WARNING;
    5013             :         }
    5014             :     }
    5015             : 
    5016             :   /* Make aggregate address structure. */
    5017           0 :   aggregate = bgp_aggregate_new ();
    5018           0 :   aggregate->summary_only = summary_only;
    5019           0 :   aggregate->as_set = as_set;
    5020           0 :   aggregate->safi = safi;
    5021           0 :   rn->info = aggregate;
    5022             : 
    5023             :   /* Aggregate address insert into BGP routing table. */
    5024           0 :   if (safi & SAFI_UNICAST)
    5025           0 :     bgp_aggregate_add (bgp, &p, afi, SAFI_UNICAST, aggregate);
    5026           0 :   if (safi & SAFI_MULTICAST)
    5027           0 :     bgp_aggregate_add (bgp, &p, afi, SAFI_MULTICAST, aggregate);
    5028             : 
    5029           0 :   return CMD_SUCCESS;
    5030             : }
    5031             : 
    5032           0 : DEFUN (aggregate_address,
    5033             :        aggregate_address_cmd,
    5034             :        "aggregate-address A.B.C.D/M",
    5035             :        "Configure BGP aggregate entries\n"
    5036             :        "Aggregate prefix\n")
    5037             : {
    5038           0 :   return bgp_aggregate_set (vty, argv[0], AFI_IP, bgp_node_safi (vty), 0, 0);
    5039             : }
    5040             : 
    5041           0 : DEFUN (aggregate_address_mask,
    5042             :        aggregate_address_mask_cmd,
    5043             :        "aggregate-address A.B.C.D A.B.C.D",
    5044             :        "Configure BGP aggregate entries\n"
    5045             :        "Aggregate address\n"
    5046             :        "Aggregate mask\n")
    5047             : {
    5048             :   int ret;
    5049             :   char prefix_str[BUFSIZ];
    5050             : 
    5051           0 :   ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
    5052             : 
    5053           0 :   if (! ret)
    5054             :     {
    5055           0 :       vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
    5056           0 :       return CMD_WARNING;
    5057             :     }
    5058             : 
    5059           0 :   return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty),
    5060             :                             0, 0);
    5061             : }
    5062             : 
    5063           0 : DEFUN (aggregate_address_summary_only,
    5064             :        aggregate_address_summary_only_cmd,
    5065             :        "aggregate-address A.B.C.D/M summary-only",
    5066             :        "Configure BGP aggregate entries\n"
    5067             :        "Aggregate prefix\n"
    5068             :        "Filter more specific routes from updates\n")
    5069             : {
    5070           0 :   return bgp_aggregate_set (vty, argv[0], AFI_IP, bgp_node_safi (vty),
    5071             :                             AGGREGATE_SUMMARY_ONLY, 0);
    5072             : }
    5073             : 
    5074           0 : DEFUN (aggregate_address_mask_summary_only,
    5075             :        aggregate_address_mask_summary_only_cmd,
    5076             :        "aggregate-address A.B.C.D A.B.C.D summary-only",
    5077             :        "Configure BGP aggregate entries\n"
    5078             :        "Aggregate address\n"
    5079             :        "Aggregate mask\n"
    5080             :        "Filter more specific routes from updates\n")
    5081             : {
    5082             :   int ret;
    5083             :   char prefix_str[BUFSIZ];
    5084             : 
    5085           0 :   ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
    5086             : 
    5087           0 :   if (! ret)
    5088             :     {
    5089           0 :       vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
    5090           0 :       return CMD_WARNING;
    5091             :     }
    5092             : 
    5093           0 :   return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty),
    5094             :                             AGGREGATE_SUMMARY_ONLY, 0);
    5095             : }
    5096             : 
    5097           0 : DEFUN (aggregate_address_as_set,
    5098             :        aggregate_address_as_set_cmd,
    5099             :        "aggregate-address A.B.C.D/M as-set",
    5100             :        "Configure BGP aggregate entries\n"
    5101             :        "Aggregate prefix\n"
    5102             :        "Generate AS set path information\n")
    5103             : {
    5104           0 :   return bgp_aggregate_set (vty, argv[0], AFI_IP, bgp_node_safi (vty),
    5105             :                             0, AGGREGATE_AS_SET);
    5106             : }
    5107             : 
    5108           0 : DEFUN (aggregate_address_mask_as_set,
    5109             :        aggregate_address_mask_as_set_cmd,
    5110             :        "aggregate-address A.B.C.D A.B.C.D as-set",
    5111             :        "Configure BGP aggregate entries\n"
    5112             :        "Aggregate address\n"
    5113             :        "Aggregate mask\n"
    5114             :        "Generate AS set path information\n")
    5115             : {
    5116             :   int ret;
    5117             :   char prefix_str[BUFSIZ];
    5118             : 
    5119           0 :   ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
    5120             : 
    5121           0 :   if (! ret)
    5122             :     {
    5123           0 :       vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
    5124           0 :       return CMD_WARNING;
    5125             :     }
    5126             : 
    5127           0 :   return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty),
    5128             :                             0, AGGREGATE_AS_SET);
    5129             : }
    5130             : 
    5131             : 
    5132           0 : DEFUN (aggregate_address_as_set_summary,
    5133             :        aggregate_address_as_set_summary_cmd,
    5134             :        "aggregate-address A.B.C.D/M as-set summary-only",
    5135             :        "Configure BGP aggregate entries\n"
    5136             :        "Aggregate prefix\n"
    5137             :        "Generate AS set path information\n"
    5138             :        "Filter more specific routes from updates\n")
    5139             : {
    5140           0 :   return bgp_aggregate_set (vty, argv[0], AFI_IP, bgp_node_safi (vty),
    5141             :                             AGGREGATE_SUMMARY_ONLY, AGGREGATE_AS_SET);
    5142             : }
    5143             : 
    5144             : ALIAS (aggregate_address_as_set_summary,
    5145             :        aggregate_address_summary_as_set_cmd,
    5146             :        "aggregate-address A.B.C.D/M summary-only as-set",
    5147             :        "Configure BGP aggregate entries\n"
    5148             :        "Aggregate prefix\n"
    5149             :        "Filter more specific routes from updates\n"
    5150             :        "Generate AS set path information\n")
    5151             : 
    5152           0 : DEFUN (aggregate_address_mask_as_set_summary,
    5153             :        aggregate_address_mask_as_set_summary_cmd,
    5154             :        "aggregate-address A.B.C.D A.B.C.D as-set summary-only",
    5155             :        "Configure BGP aggregate entries\n"
    5156             :        "Aggregate address\n"
    5157             :        "Aggregate mask\n"
    5158             :        "Generate AS set path information\n"
    5159             :        "Filter more specific routes from updates\n")
    5160             : {
    5161             :   int ret;
    5162             :   char prefix_str[BUFSIZ];
    5163             : 
    5164           0 :   ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
    5165             : 
    5166           0 :   if (! ret)
    5167             :     {
    5168           0 :       vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
    5169           0 :       return CMD_WARNING;
    5170             :     }
    5171             : 
    5172           0 :   return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty),
    5173             :                             AGGREGATE_SUMMARY_ONLY, AGGREGATE_AS_SET);
    5174             : }
    5175             : 
    5176             : ALIAS (aggregate_address_mask_as_set_summary,
    5177             :        aggregate_address_mask_summary_as_set_cmd,
    5178             :        "aggregate-address A.B.C.D A.B.C.D summary-only as-set",
    5179             :        "Configure BGP aggregate entries\n"
    5180             :        "Aggregate address\n"
    5181             :        "Aggregate mask\n"
    5182             :        "Filter more specific routes from updates\n"
    5183             :        "Generate AS set path information\n")
    5184             : 
    5185           0 : DEFUN (no_aggregate_address,
    5186             :        no_aggregate_address_cmd,
    5187             :        "no aggregate-address A.B.C.D/M",
    5188             :        NO_STR
    5189             :        "Configure BGP aggregate entries\n"
    5190             :        "Aggregate prefix\n")
    5191             : {
    5192           0 :   return bgp_aggregate_unset (vty, argv[0], AFI_IP, bgp_node_safi (vty));
    5193             : }
    5194             : 
    5195             : ALIAS (no_aggregate_address,
    5196             :        no_aggregate_address_summary_only_cmd,
    5197             :        "no aggregate-address A.B.C.D/M summary-only",
    5198             :        NO_STR
    5199             :        "Configure BGP aggregate entries\n"
    5200             :        "Aggregate prefix\n"
    5201             :        "Filter more specific routes from updates\n")
    5202             : 
    5203             : ALIAS (no_aggregate_address,
    5204             :        no_aggregate_address_as_set_cmd,
    5205             :        "no aggregate-address A.B.C.D/M as-set",
    5206             :        NO_STR
    5207             :        "Configure BGP aggregate entries\n"
    5208             :        "Aggregate prefix\n"
    5209             :        "Generate AS set path information\n")
    5210             : 
    5211             : ALIAS (no_aggregate_address,
    5212             :        no_aggregate_address_as_set_summary_cmd,
    5213             :        "no aggregate-address A.B.C.D/M as-set summary-only",
    5214             :        NO_STR
    5215             :        "Configure BGP aggregate entries\n"
    5216             :        "Aggregate prefix\n"
    5217             :        "Generate AS set path information\n"
    5218             :        "Filter more specific routes from updates\n")
    5219             : 
    5220             : ALIAS (no_aggregate_address,
    5221             :        no_aggregate_address_summary_as_set_cmd,
    5222             :        "no aggregate-address A.B.C.D/M summary-only as-set",
    5223             :        NO_STR
    5224             :        "Configure BGP aggregate entries\n"
    5225             :        "Aggregate prefix\n"
    5226             :        "Filter more specific routes from updates\n"
    5227             :        "Generate AS set path information\n")
    5228             : 
    5229           0 : DEFUN (no_aggregate_address_mask,
    5230             :        no_aggregate_address_mask_cmd,
    5231             :        "no aggregate-address A.B.C.D A.B.C.D",
    5232             :        NO_STR
    5233             :        "Configure BGP aggregate entries\n"
    5234             :        "Aggregate address\n"
    5235             :        "Aggregate mask\n")
    5236             : {
    5237             :   int ret;
    5238             :   char prefix_str[BUFSIZ];
    5239             : 
    5240           0 :   ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
    5241             : 
    5242           0 :   if (! ret)
    5243             :     {
    5244           0 :       vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
    5245           0 :       return CMD_WARNING;
    5246             :     }
    5247             : 
    5248           0 :   return bgp_aggregate_unset (vty, prefix_str, AFI_IP, bgp_node_safi (vty));
    5249             : }
    5250             : 
    5251             : ALIAS (no_aggregate_address_mask,
    5252             :        no_aggregate_address_mask_summary_only_cmd,
    5253             :        "no aggregate-address A.B.C.D A.B.C.D summary-only",
    5254             :        NO_STR
    5255             :        "Configure BGP aggregate entries\n"
    5256             :        "Aggregate address\n"
    5257             :        "Aggregate mask\n"
    5258             :        "Filter more specific routes from updates\n")
    5259             : 
    5260             : ALIAS (no_aggregate_address_mask,
    5261             :        no_aggregate_address_mask_as_set_cmd,
    5262             :        "no aggregate-address A.B.C.D A.B.C.D as-set",
    5263             :        NO_STR
    5264             :        "Configure BGP aggregate entries\n"
    5265             :        "Aggregate address\n"
    5266             :        "Aggregate mask\n"
    5267             :        "Generate AS set path information\n")
    5268             : 
    5269             : ALIAS (no_aggregate_address_mask,
    5270             :        no_aggregate_address_mask_as_set_summary_cmd,
    5271             :        "no aggregate-address A.B.C.D A.B.C.D as-set summary-only",
    5272             :        NO_STR
    5273             :        "Configure BGP aggregate entries\n"
    5274             :        "Aggregate address\n"
    5275             :        "Aggregate mask\n"
    5276             :        "Generate AS set path information\n"
    5277             :        "Filter more specific routes from updates\n")
    5278             : 
    5279             : ALIAS (no_aggregate_address_mask,
    5280             :        no_aggregate_address_mask_summary_as_set_cmd,
    5281             :        "no aggregate-address A.B.C.D A.B.C.D summary-only as-set",
    5282             :        NO_STR
    5283             :        "Configure BGP aggregate entries\n"
    5284             :        "Aggregate address\n"
    5285             :        "Aggregate mask\n"
    5286             :        "Filter more specific routes from updates\n"
    5287             :        "Generate AS set path information\n")
    5288             : 
    5289             : #ifdef HAVE_IPV6
    5290           0 : DEFUN (ipv6_aggregate_address,
    5291             :        ipv6_aggregate_address_cmd,
    5292             :        "aggregate-address X:X::X:X/M",
    5293             :        "Configure BGP aggregate entries\n"
    5294             :        "Aggregate prefix\n")
    5295             : {
    5296           0 :   return bgp_aggregate_set (vty, argv[0], AFI_IP6, SAFI_UNICAST, 0, 0);
    5297             : }
    5298             : 
    5299           0 : DEFUN (ipv6_aggregate_address_summary_only,
    5300             :        ipv6_aggregate_address_summary_only_cmd,
    5301             :        "aggregate-address X:X::X:X/M summary-only",
    5302             :        "Configure BGP aggregate entries\n"
    5303             :        "Aggregate prefix\n"
    5304             :        "Filter more specific routes from updates\n")
    5305             : {
    5306           0 :   return bgp_aggregate_set (vty, argv[0], AFI_IP6, SAFI_UNICAST, 
    5307             :                             AGGREGATE_SUMMARY_ONLY, 0);
    5308             : }
    5309             : 
    5310           0 : DEFUN (no_ipv6_aggregate_address,
    5311             :        no_ipv6_aggregate_address_cmd,
    5312             :        "no aggregate-address X:X::X:X/M",
    5313             :        NO_STR
    5314             :        "Configure BGP aggregate entries\n"
    5315             :        "Aggregate prefix\n")
    5316             : {
    5317           0 :   return bgp_aggregate_unset (vty, argv[0], AFI_IP6, SAFI_UNICAST);
    5318             : }
    5319             : 
    5320           0 : DEFUN (no_ipv6_aggregate_address_summary_only,
    5321             :        no_ipv6_aggregate_address_summary_only_cmd,
    5322             :        "no aggregate-address X:X::X:X/M summary-only",
    5323             :        NO_STR
    5324             :        "Configure BGP aggregate entries\n"
    5325             :        "Aggregate prefix\n"
    5326             :        "Filter more specific routes from updates\n")
    5327             : {
    5328           0 :   return bgp_aggregate_unset (vty, argv[0], AFI_IP6, SAFI_UNICAST);
    5329             : }
    5330             : 
    5331             : ALIAS (ipv6_aggregate_address,
    5332             :        old_ipv6_aggregate_address_cmd,
    5333             :        "ipv6 bgp aggregate-address X:X::X:X/M",
    5334             :        IPV6_STR
    5335             :        BGP_STR
    5336             :        "Configure BGP aggregate entries\n"
    5337             :        "Aggregate prefix\n")
    5338             : 
    5339             : ALIAS (ipv6_aggregate_address_summary_only,
    5340             :        old_ipv6_aggregate_address_summary_only_cmd,
    5341             :        "ipv6 bgp aggregate-address X:X::X:X/M summary-only",
    5342             :        IPV6_STR
    5343             :        BGP_STR
    5344             :        "Configure BGP aggregate entries\n"
    5345             :        "Aggregate prefix\n"
    5346             :        "Filter more specific routes from updates\n")
    5347             : 
    5348             : ALIAS (no_ipv6_aggregate_address,
    5349             :        old_no_ipv6_aggregate_address_cmd,
    5350             :        "no ipv6 bgp aggregate-address X:X::X:X/M",
    5351             :        NO_STR
    5352             :        IPV6_STR
    5353             :        BGP_STR
    5354             :        "Configure BGP aggregate entries\n"
    5355             :        "Aggregate prefix\n")
    5356             : 
    5357             : ALIAS (no_ipv6_aggregate_address_summary_only,
    5358             :        old_no_ipv6_aggregate_address_summary_only_cmd,
    5359             :        "no ipv6 bgp aggregate-address X:X::X:X/M summary-only",
    5360             :        NO_STR
    5361             :        IPV6_STR
    5362             :        BGP_STR
    5363             :        "Configure BGP aggregate entries\n"
    5364             :        "Aggregate prefix\n"
    5365             :        "Filter more specific routes from updates\n")
    5366             : #endif /* HAVE_IPV6 */
    5367             : 
    5368             : /* Redistribute route treatment. */
    5369             : void
    5370           0 : bgp_redistribute_add (struct prefix *p, const struct in_addr *nexthop,
    5371             :                       const struct in6_addr *nexthop6,
    5372             :                       u_int32_t metric, u_char type)
    5373             : {
    5374             :   struct bgp *bgp;
    5375             :   struct listnode *node, *nnode;
    5376             :   struct bgp_info *new;
    5377             :   struct bgp_info *bi;
    5378             :   struct bgp_info info;
    5379             :   struct bgp_node *bn;
    5380             :   struct attr attr;
    5381             :   struct attr *new_attr;
    5382             :   afi_t afi;
    5383             :   int ret;
    5384             : 
    5385             :   /* Make default attribute. */
    5386           0 :   bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE);
    5387           0 :   if (nexthop)
    5388           0 :     attr.nexthop = *nexthop;
    5389             : 
    5390             : #ifdef HAVE_IPV6
    5391           0 :   if (nexthop6)
    5392             :     {
    5393           0 :       struct attr_extra *extra = bgp_attr_extra_get(&attr);
    5394           0 :       extra->mp_nexthop_global = *nexthop6;
    5395           0 :       extra->mp_nexthop_len = 16;
    5396             :     }
    5397             : #endif
    5398             : 
    5399           0 :   attr.med = metric;
    5400           0 :   attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
    5401             : 
    5402           0 :   for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
    5403             :     {
    5404           0 :       afi = family2afi (p->family);
    5405             : 
    5406           0 :       if (bgp->redist[afi][type])
    5407             :         {
    5408             :           struct attr attr_new;
    5409             :           struct attr_extra extra_new;
    5410             : 
    5411             :           /* Copy attribute for modification. */
    5412           0 :           attr_new.extra = &extra_new;
    5413           0 :           bgp_attr_dup (&attr_new, &attr);
    5414             : 
    5415           0 :           if (bgp->redist_metric_flag[afi][type])
    5416           0 :             attr_new.med = bgp->redist_metric[afi][type];
    5417             : 
    5418             :           /* Apply route-map. */
    5419           0 :           if (bgp->rmap[afi][type].map)
    5420             :             {
    5421           0 :               info.peer = bgp->peer_self;
    5422           0 :               info.attr = &attr_new;
    5423             : 
    5424           0 :               SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE);
    5425             : 
    5426           0 :               ret = route_map_apply (bgp->rmap[afi][type].map, p, RMAP_BGP,
    5427             :                                      &info);
    5428             : 
    5429           0 :               bgp->peer_self->rmap_type = 0;
    5430             : 
    5431           0 :               if (ret == RMAP_DENYMATCH)
    5432             :                 {
    5433             :                   /* Free uninterned attribute. */
    5434           0 :                   bgp_attr_flush (&attr_new);
    5435             : 
    5436             :                   /* Unintern original. */
    5437           0 :                   aspath_unintern (&attr.aspath);
    5438           0 :                   bgp_attr_extra_free (&attr);
    5439           0 :                   bgp_redistribute_delete (p, type);
    5440           0 :                   return;
    5441             :                 }
    5442             :             }
    5443             : 
    5444           0 :           bn = bgp_afi_node_get (bgp->rib[afi][SAFI_UNICAST], 
    5445             :                                  afi, SAFI_UNICAST, p, NULL);
    5446             :           
    5447           0 :           new_attr = bgp_attr_intern (&attr_new);
    5448             : 
    5449           0 :           for (bi = bn->info; bi; bi = bi->next)
    5450           0 :             if (bi->peer == bgp->peer_self
    5451           0 :                 && bi->sub_type == BGP_ROUTE_REDISTRIBUTE)
    5452           0 :               break;
    5453             :  
    5454           0 :           if (bi)
    5455             :             {
    5456           0 :               if (attrhash_cmp (bi->attr, new_attr) &&
    5457           0 :                   !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
    5458             :                 {
    5459           0 :                   bgp_attr_unintern (&new_attr);
    5460           0 :                   aspath_unintern (&attr.aspath);
    5461           0 :                   bgp_attr_extra_free (&attr);
    5462           0 :                   bgp_unlock_node (bn);
    5463           0 :                   return;
    5464             :                 }
    5465             :               else
    5466             :                 {
    5467             :                   /* The attribute is changed. */
    5468           0 :                   bgp_info_set_flag (bn, bi, BGP_INFO_ATTR_CHANGED);
    5469             :  
    5470             :                   /* Rewrite BGP route information. */
    5471           0 :                   if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
    5472           0 :                     bgp_info_restore(bn, bi);
    5473             :                   else
    5474           0 :                     bgp_aggregate_decrement (bgp, p, bi, afi, SAFI_UNICAST);
    5475           0 :                   bgp_attr_unintern (&bi->attr);
    5476           0 :                   bi->attr = new_attr;
    5477           0 :                   bi->uptime = bgp_clock ();
    5478             :  
    5479             :                   /* Process change. */
    5480           0 :                   bgp_aggregate_increment (bgp, p, bi, afi, SAFI_UNICAST);
    5481           0 :                   bgp_process (bgp, bn, afi, SAFI_UNICAST);
    5482           0 :                   bgp_unlock_node (bn);
    5483           0 :                   aspath_unintern (&attr.aspath);
    5484           0 :                   bgp_attr_extra_free (&attr);
    5485           0 :                   return;
    5486             :                 } 
    5487             :             }
    5488             : 
    5489           0 :           new = bgp_info_new ();
    5490           0 :           new->type = type;
    5491           0 :           new->sub_type = BGP_ROUTE_REDISTRIBUTE;
    5492           0 :           new->peer = bgp->peer_self;
    5493           0 :           SET_FLAG (new->flags, BGP_INFO_VALID);
    5494           0 :           new->attr = new_attr;
    5495           0 :           new->uptime = bgp_clock ();
    5496             : 
    5497           0 :           bgp_aggregate_increment (bgp, p, new, afi, SAFI_UNICAST);
    5498           0 :           bgp_info_add (bn, new);
    5499           0 :           bgp_unlock_node (bn);
    5500           0 :           bgp_process (bgp, bn, afi, SAFI_UNICAST);
    5501             :         }
    5502             :     }
    5503             : 
    5504             :   /* Unintern original. */
    5505           0 :   aspath_unintern (&attr.aspath);
    5506           0 :   bgp_attr_extra_free (&attr);
    5507             : }
    5508             : 
    5509             : void
    5510           0 : bgp_redistribute_delete (struct prefix *p, u_char type)
    5511             : {
    5512             :   struct bgp *bgp;
    5513             :   struct listnode *node, *nnode;
    5514             :   afi_t afi;
    5515             :   struct bgp_node *rn;
    5516             :   struct bgp_info *ri;
    5517             : 
    5518           0 :   for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
    5519             :     {
    5520           0 :       afi = family2afi (p->family);
    5521             : 
    5522           0 :       if (bgp->redist[afi][type])
    5523             :         {
    5524           0 :          rn = bgp_afi_node_get (bgp->rib[afi][SAFI_UNICAST], afi, SAFI_UNICAST, p, NULL);
    5525             : 
    5526           0 :           for (ri = rn->info; ri; ri = ri->next)
    5527           0 :             if (ri->peer == bgp->peer_self
    5528           0 :                 && ri->type == type)
    5529           0 :               break;
    5530             : 
    5531           0 :           if (ri)
    5532             :             {
    5533           0 :               bgp_aggregate_decrement (bgp, p, ri, afi, SAFI_UNICAST);
    5534           0 :               bgp_info_delete (rn, ri);
    5535           0 :               bgp_process (bgp, rn, afi, SAFI_UNICAST);
    5536             :             }
    5537           0 :           bgp_unlock_node (rn);
    5538             :         }
    5539             :     }
    5540           0 : }
    5541             : 
    5542             : /* Withdraw specified route type's route. */
    5543             : void
    5544           0 : bgp_redistribute_withdraw (struct bgp *bgp, afi_t afi, int type)
    5545             : {
    5546             :   struct bgp_node *rn;
    5547             :   struct bgp_info *ri;
    5548             :   struct bgp_table *table;
    5549             : 
    5550           0 :   table = bgp->rib[afi][SAFI_UNICAST];
    5551             : 
    5552           0 :   for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
    5553             :     {
    5554           0 :       for (ri = rn->info; ri; ri = ri->next)
    5555           0 :         if (ri->peer == bgp->peer_self
    5556           0 :             && ri->type == type)
    5557           0 :           break;
    5558             : 
    5559           0 :       if (ri)
    5560             :         {
    5561           0 :           bgp_aggregate_decrement (bgp, &rn->p, ri, afi, SAFI_UNICAST);
    5562           0 :           bgp_info_delete (rn, ri);
    5563           0 :           bgp_process (bgp, rn, afi, SAFI_UNICAST);
    5564             :         }
    5565             :     }
    5566           0 : }
    5567             : 
    5568             : /* Static function to display route. */
    5569             : static void
    5570           0 : route_vty_out_route (struct prefix *p, struct vty *vty)
    5571             : {
    5572             :   int len;
    5573             :   u_int32_t destination; 
    5574             :   char buf[BUFSIZ];
    5575             : 
    5576           0 :   if (p->family == AF_INET)
    5577             :     {
    5578           0 :       len = vty_out (vty, "%s", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ));
    5579           0 :       destination = ntohl (p->u.prefix4.s_addr);
    5580             : 
    5581           0 :       if ((IN_CLASSC (destination) && p->prefixlen == 24)
    5582           0 :           || (IN_CLASSB (destination) && p->prefixlen == 16)
    5583           0 :           || (IN_CLASSA (destination) && p->prefixlen == 8)
    5584           0 :           || p->u.prefix4.s_addr == 0)
    5585             :         {
    5586             :           /* When mask is natural, mask is not displayed. */
    5587             :         }
    5588             :       else
    5589           0 :         len += vty_out (vty, "/%d", p->prefixlen);
    5590             :     }
    5591             :   else
    5592           0 :     len = vty_out (vty, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
    5593           0 :                    p->prefixlen);
    5594             : 
    5595           0 :   len = 17 - len;
    5596           0 :   if (len < 1)
    5597           0 :     vty_out (vty, "%s%*s", VTY_NEWLINE, 20, " ");
    5598             :   else
    5599           0 :     vty_out (vty, "%*s", len, " ");
    5600           0 : }
    5601             : 
    5602             : enum bgp_display_type
    5603             : {
    5604             :   normal_list,
    5605             : };
    5606             : 
    5607             : /* Print the short form route status for a bgp_info */
    5608             : static void
    5609           0 : route_vty_short_status_out (struct vty *vty, struct bgp_info *binfo)
    5610             : {
    5611             :  /* Route status display. */
    5612           0 :   if (CHECK_FLAG (binfo->flags, BGP_INFO_REMOVED))
    5613           0 :     vty_out (vty, "R");
    5614           0 :   else if (CHECK_FLAG (binfo->flags, BGP_INFO_STALE))
    5615           0 :     vty_out (vty, "S");
    5616           0 :   else if (binfo->extra && binfo->extra->suppress)
    5617           0 :     vty_out (vty, "s");
    5618           0 :   else if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
    5619           0 :     vty_out (vty, "*");
    5620             :   else
    5621           0 :     vty_out (vty, " ");
    5622             : 
    5623             :   /* Selected */
    5624           0 :   if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
    5625           0 :     vty_out (vty, "h");
    5626           0 :   else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
    5627           0 :     vty_out (vty, "d");
    5628           0 :   else if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
    5629           0 :     vty_out (vty, ">");
    5630             :   else
    5631           0 :     vty_out (vty, " ");
    5632             : 
    5633             :   /* Internal route. */
    5634           0 :     if ((binfo->peer->as) && (binfo->peer->as == binfo->peer->local_as))
    5635           0 :       vty_out (vty, "i");
    5636             :     else
    5637           0 :       vty_out (vty, " "); 
    5638           0 : }
    5639             : 
    5640             : /* called from terminal list command */
    5641             : void
    5642           0 : route_vty_out (struct vty *vty, struct prefix *p,
    5643             :                struct bgp_info *binfo, int display, safi_t safi)
    5644             : {
    5645             :   struct attr *attr;
    5646             :   
    5647             :   /* short status lead text */ 
    5648           0 :   route_vty_short_status_out (vty, binfo);
    5649             :   
    5650             :   /* print prefix and mask */
    5651           0 :   if (! display)
    5652           0 :     route_vty_out_route (p, vty);
    5653             :   else
    5654           0 :     vty_out (vty, "%*s", 17, " ");
    5655             : 
    5656             :   /* Print attribute */
    5657           0 :   attr = binfo->attr;
    5658           0 :   if (attr) 
    5659             :     {
    5660           0 :       if (p->family == AF_INET)
    5661             :         {
    5662           0 :           if (safi == SAFI_MPLS_VPN)
    5663           0 :             vty_out (vty, "%-16s",
    5664           0 :                      inet_ntoa (attr->extra->mp_nexthop_global_in));
    5665             :           else
    5666           0 :             vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
    5667             :         }
    5668             : #ifdef HAVE_IPV6      
    5669           0 :       else if (p->family == AF_INET6)
    5670             :         {
    5671             :           int len;
    5672             :           char buf[BUFSIZ];
    5673             : 
    5674           0 :           len = vty_out (vty, "%s", 
    5675           0 :                          inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
    5676             :                          buf, BUFSIZ));
    5677           0 :           len = 16 - len;
    5678           0 :           if (len < 1)
    5679           0 :             vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " ");
    5680             :           else
    5681           0 :             vty_out (vty, "%*s", len, " ");
    5682             :         }
    5683             : #endif /* HAVE_IPV6 */
    5684             : 
    5685           0 :       if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
    5686           0 :         vty_out (vty, "%10u", attr->med);
    5687             :       else
    5688           0 :         vty_out (vty, "          ");
    5689             : 
    5690           0 :       if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
    5691           0 :         vty_out (vty, "%7u", attr->local_pref);
    5692             :       else
    5693           0 :         vty_out (vty, "       ");
    5694             : 
    5695           0 :       vty_out (vty, "%7u ", (attr->extra ? attr->extra->weight : 0));
    5696             :     
    5697             :       /* Print aspath */
    5698           0 :       if (attr->aspath)
    5699           0 :         aspath_print_vty (vty, "%s", attr->aspath, " ");
    5700             : 
    5701             :       /* Print origin */
    5702           0 :       vty_out (vty, "%s", bgp_origin_str[attr->origin]);
    5703             :     }
    5704           0 :   vty_out (vty, "%s", VTY_NEWLINE);
    5705           0 : }  
    5706             : 
    5707             : /* called from terminal list command */
    5708             : void
    5709           0 : route_vty_out_tmp (struct vty *vty, struct prefix *p,
    5710             :                    struct attr *attr, safi_t safi)
    5711             : {
    5712             :   /* Route status display. */
    5713           0 :   vty_out (vty, "*");
    5714           0 :   vty_out (vty, ">");
    5715           0 :   vty_out (vty, " ");
    5716             : 
    5717             :   /* print prefix and mask */
    5718           0 :   route_vty_out_route (p, vty);
    5719             : 
    5720             :   /* Print attribute */
    5721           0 :   if (attr) 
    5722             :     {
    5723           0 :       if (p->family == AF_INET)
    5724             :         {
    5725           0 :           if (safi == SAFI_MPLS_VPN)
    5726           0 :             vty_out (vty, "%-16s",
    5727           0 :                      inet_ntoa (attr->extra->mp_nexthop_global_in));
    5728             :           else
    5729           0 :             vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
    5730             :         }
    5731             : #ifdef HAVE_IPV6
    5732           0 :       else if (p->family == AF_INET6)
    5733             :         {
    5734             :           int len;
    5735             :           char buf[BUFSIZ];
    5736             :           
    5737           0 :           assert (attr->extra);
    5738             : 
    5739           0 :           len = vty_out (vty, "%s",
    5740           0 :                          inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
    5741             :                          buf, BUFSIZ));
    5742           0 :           len = 16 - len;
    5743           0 :           if (len < 1)
    5744           0 :             vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " ");
    5745             :           else
    5746           0 :             vty_out (vty, "%*s", len, " ");
    5747             :         }
    5748             : #endif /* HAVE_IPV6 */
    5749             : 
    5750           0 :       if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
    5751           0 :         vty_out (vty, "%10u", attr->med);
    5752             :       else
    5753           0 :         vty_out (vty, "          ");
    5754             : 
    5755           0 :       if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
    5756           0 :         vty_out (vty, "%7u", attr->local_pref);
    5757             :       else
    5758           0 :         vty_out (vty, "       ");
    5759             :       
    5760           0 :       vty_out (vty, "%7u ", (attr->extra ? attr->extra->weight : 0));
    5761             :       
    5762             :       /* Print aspath */
    5763           0 :       if (attr->aspath)
    5764           0 :         aspath_print_vty (vty, "%s", attr->aspath, " ");
    5765             : 
    5766             :       /* Print origin */
    5767           0 :       vty_out (vty, "%s", bgp_origin_str[attr->origin]);
    5768             :     }
    5769             : 
    5770           0 :   vty_out (vty, "%s", VTY_NEWLINE);
    5771           0 : }  
    5772             : 
    5773             : void
    5774           0 : route_vty_out_tag (struct vty *vty, struct prefix *p,
    5775             :                    struct bgp_info *binfo, int display, safi_t safi)
    5776             : {
    5777             :   struct attr *attr;
    5778           0 :   u_int32_t label = 0;
    5779             :   
    5780           0 :   if (!binfo->extra)
    5781           0 :     return;
    5782             :   
    5783             :   /* short status lead text */ 
    5784           0 :   route_vty_short_status_out (vty, binfo);
    5785             :     
    5786             :   /* print prefix and mask */
    5787           0 :   if (! display)
    5788           0 :     route_vty_out_route (p, vty);
    5789             :   else
    5790           0 :     vty_out (vty, "%*s", 17, " ");
    5791             : 
    5792             :   /* Print attribute */
    5793           0 :   attr = binfo->attr;
    5794           0 :   if (attr) 
    5795             :     {
    5796           0 :       if (p->family == AF_INET)
    5797             :         {
    5798           0 :           if (safi == SAFI_MPLS_VPN)
    5799           0 :             vty_out (vty, "%-16s",
    5800           0 :                      inet_ntoa (attr->extra->mp_nexthop_global_in));
    5801             :           else
    5802           0 :             vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
    5803             :         }
    5804             : #ifdef HAVE_IPV6      
    5805           0 :       else if (p->family == AF_INET6)
    5806             :         {
    5807           0 :           assert (attr->extra);
    5808             :           char buf[BUFSIZ];
    5809             :           char buf1[BUFSIZ];
    5810           0 :           if (attr->extra->mp_nexthop_len == 16)
    5811           0 :             vty_out (vty, "%s", 
    5812           0 :                      inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
    5813             :                      buf, BUFSIZ));
    5814           0 :           else if (attr->extra->mp_nexthop_len == 32)
    5815           0 :             vty_out (vty, "%s(%s)",
    5816           0 :                      inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
    5817             :                                 buf, BUFSIZ),
    5818           0 :                      inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
    5819             :                                 buf1, BUFSIZ));
    5820             :           
    5821             :         }
    5822             : #endif /* HAVE_IPV6 */
    5823             :     }
    5824             : 
    5825           0 :   label = decode_label (binfo->extra->tag);
    5826             : 
    5827           0 :   vty_out (vty, "notag/%d", label);
    5828             : 
    5829           0 :   vty_out (vty, "%s", VTY_NEWLINE);
    5830             : }  
    5831             : 
    5832             : /* dampening route */
    5833             : static void
    5834           0 : damp_route_vty_out (struct vty *vty, struct prefix *p,
    5835             :                     struct bgp_info *binfo, int display, safi_t safi)
    5836             : {
    5837             :   struct attr *attr;
    5838             :   int len;
    5839             :   char timebuf[BGP_UPTIME_LEN];
    5840             : 
    5841             :   /* short status lead text */ 
    5842           0 :   route_vty_short_status_out (vty, binfo);
    5843             :   
    5844             :   /* print prefix and mask */
    5845           0 :   if (! display)
    5846           0 :     route_vty_out_route (p, vty);
    5847             :   else
    5848           0 :     vty_out (vty, "%*s", 17, " ");
    5849             : 
    5850           0 :   len = vty_out (vty, "%s", binfo->peer->host);
    5851           0 :   len = 17 - len;
    5852           0 :   if (len < 1)
    5853           0 :     vty_out (vty, "%s%*s", VTY_NEWLINE, 34, " ");
    5854             :   else
    5855           0 :     vty_out (vty, "%*s", len, " ");
    5856             : 
    5857           0 :   vty_out (vty, "%s ", bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN));
    5858             : 
    5859             :   /* Print attribute */
    5860           0 :   attr = binfo->attr;
    5861           0 :   if (attr)
    5862             :     {
    5863             :       /* Print aspath */
    5864           0 :       if (attr->aspath)
    5865           0 :         aspath_print_vty (vty, "%s", attr->aspath, " ");
    5866             : 
    5867             :       /* Print origin */
    5868           0 :       vty_out (vty, "%s", bgp_origin_str[attr->origin]);
    5869             :     }
    5870           0 :   vty_out (vty, "%s", VTY_NEWLINE);
    5871           0 : }
    5872             : 
    5873             : /* flap route */
    5874             : static void
    5875           0 : flap_route_vty_out (struct vty *vty, struct prefix *p,
    5876             :                     struct bgp_info *binfo, int display, safi_t safi)
    5877             : {
    5878             :   struct attr *attr;
    5879             :   struct bgp_damp_info *bdi;
    5880             :   char timebuf[BGP_UPTIME_LEN];
    5881             :   int len;
    5882             :   
    5883           0 :   if (!binfo->extra)
    5884           0 :     return;
    5885             :   
    5886           0 :   bdi = binfo->extra->damp_info;
    5887             : 
    5888             :   /* short status lead text */
    5889           0 :   route_vty_short_status_out (vty, binfo);
    5890             :   
    5891             :   /* print prefix and mask */
    5892           0 :   if (! display)
    5893           0 :     route_vty_out_route (p, vty);
    5894             :   else
    5895           0 :     vty_out (vty, "%*s", 17, " ");
    5896             : 
    5897           0 :   len = vty_out (vty, "%s", binfo->peer->host);
    5898           0 :   len = 16 - len;
    5899           0 :   if (len < 1)
    5900           0 :     vty_out (vty, "%s%*s", VTY_NEWLINE, 33, " ");
    5901             :   else
    5902           0 :     vty_out (vty, "%*s", len, " ");
    5903             : 
    5904           0 :   len = vty_out (vty, "%d", bdi->flap);
    5905           0 :   len = 5 - len;
    5906           0 :   if (len < 1)
    5907           0 :     vty_out (vty, " ");
    5908             :   else
    5909           0 :     vty_out (vty, "%*s ", len, " ");
    5910             :     
    5911           0 :   vty_out (vty, "%s ", peer_uptime (bdi->start_time,
    5912             :            timebuf, BGP_UPTIME_LEN));
    5913             : 
    5914           0 :   if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED)
    5915           0 :       && ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
    5916           0 :     vty_out (vty, "%s ", bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN));
    5917             :   else
    5918           0 :     vty_out (vty, "%*s ", 8, " ");
    5919             : 
    5920             :   /* Print attribute */
    5921           0 :   attr = binfo->attr;
    5922           0 :   if (attr)
    5923             :     {
    5924             :       /* Print aspath */
    5925           0 :       if (attr->aspath)
    5926           0 :         aspath_print_vty (vty, "%s", attr->aspath, " ");
    5927             : 
    5928             :       /* Print origin */
    5929           0 :       vty_out (vty, "%s", bgp_origin_str[attr->origin]);
    5930             :     }
    5931           0 :   vty_out (vty, "%s", VTY_NEWLINE);
    5932             : }
    5933             : 
    5934             : static void
    5935           0 : route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p, 
    5936             :                       struct bgp_info *binfo, afi_t afi, safi_t safi)
    5937             : {
    5938             :   char buf[INET6_ADDRSTRLEN];
    5939             :   char buf1[BUFSIZ];
    5940             :   struct attr *attr;
    5941             :   int sockunion_vty_out (struct vty *, union sockunion *);
    5942             : #ifdef HAVE_CLOCK_MONOTONIC
    5943             :   time_t tbuf;
    5944             : #endif
    5945             :         
    5946           0 :   attr = binfo->attr;
    5947             : 
    5948           0 :   if (attr)
    5949             :     {
    5950             :       /* Line1 display AS-path, Aggregator */
    5951           0 :       if (attr->aspath)
    5952             :         {
    5953           0 :           vty_out (vty, "  ");
    5954           0 :           if (aspath_count_hops (attr->aspath) == 0)
    5955           0 :             vty_out (vty, "Local");
    5956             :           else
    5957           0 :             aspath_print_vty (vty, "%s", attr->aspath, "");
    5958             :         }
    5959             : 
    5960           0 :       if (CHECK_FLAG (binfo->flags, BGP_INFO_REMOVED))
    5961           0 :         vty_out (vty, ", (removed)");
    5962           0 :       if (CHECK_FLAG (binfo->flags, BGP_INFO_STALE))
    5963           0 :         vty_out (vty, ", (stale)");
    5964           0 :       if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR)))
    5965           0 :         vty_out (vty, ", (aggregated by %u %s)", 
    5966           0 :                  attr->extra->aggregator_as,
    5967           0 :                  inet_ntoa (attr->extra->aggregator_addr));
    5968           0 :       if (CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
    5969           0 :         vty_out (vty, ", (Received from a RR-client)");
    5970           0 :       if (CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
    5971           0 :         vty_out (vty, ", (Received from a RS-client)");
    5972           0 :       if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
    5973           0 :         vty_out (vty, ", (history entry)");
    5974           0 :       else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
    5975           0 :         vty_out (vty, ", (suppressed due to dampening)");
    5976           0 :       vty_out (vty, "%s", VTY_NEWLINE);
    5977             :           
    5978             :       /* Line2 display Next-hop, Neighbor, Router-id */
    5979           0 :       if (p->family == AF_INET)
    5980             :         {
    5981           0 :           vty_out (vty, "    %s", safi == SAFI_MPLS_VPN ?
    5982           0 :                    inet_ntoa (attr->extra->mp_nexthop_global_in) :
    5983             :                    inet_ntoa (attr->nexthop));
    5984             :         }
    5985             : #ifdef HAVE_IPV6
    5986             :       else
    5987             :         {
    5988           0 :           assert (attr->extra);
    5989           0 :           vty_out (vty, "    %s",
    5990           0 :                    inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
    5991             :                               buf, INET6_ADDRSTRLEN));
    5992             :         }
    5993             : #endif /* HAVE_IPV6 */
    5994             : 
    5995           0 :       if (binfo->peer == bgp->peer_self)
    5996             :         {
    5997           0 :           vty_out (vty, " from %s ", 
    5998           0 :                    p->family == AF_INET ? "0.0.0.0" : "::");
    5999           0 :           vty_out (vty, "(%s)", inet_ntoa(bgp->router_id));
    6000             :         }
    6001             :       else
    6002             :         {
    6003           0 :           if (! CHECK_FLAG (binfo->flags, BGP_INFO_VALID))
    6004           0 :             vty_out (vty, " (inaccessible)"); 
    6005           0 :           else if (binfo->extra && binfo->extra->igpmetric)
    6006           0 :             vty_out (vty, " (metric %u)", binfo->extra->igpmetric);
    6007           0 :           vty_out (vty, " from %s", sockunion2str (&binfo->peer->su, buf, SU_ADDRSTRLEN));
    6008           0 :           if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
    6009           0 :             vty_out (vty, " (%s)", inet_ntoa (attr->extra->originator_id));
    6010             :           else
    6011           0 :             vty_out (vty, " (%s)", inet_ntop (AF_INET, &binfo->peer->remote_id, buf1, BUFSIZ));
    6012             :         }
    6013           0 :       vty_out (vty, "%s", VTY_NEWLINE);
    6014             : 
    6015             : #ifdef HAVE_IPV6
    6016             :       /* display nexthop local */
    6017           0 :       if (attr->extra && attr->extra->mp_nexthop_len == 32)
    6018             :         {
    6019           0 :           vty_out (vty, "    (%s)%s",
    6020           0 :                    inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
    6021             :                               buf, INET6_ADDRSTRLEN),
    6022           0 :                    VTY_NEWLINE);
    6023             :         }
    6024             : #endif /* HAVE_IPV6 */
    6025             : 
    6026             :       /* Line 3 display Origin, Med, Locpref, Weight, valid, Int/Ext/Local, Atomic, best */
    6027           0 :       vty_out (vty, "      Origin %s", bgp_origin_long_str[attr->origin]);
    6028             :           
    6029           0 :       if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
    6030           0 :         vty_out (vty, ", metric %u", attr->med);
    6031             :           
    6032           0 :       if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
    6033           0 :         vty_out (vty, ", localpref %u", attr->local_pref);
    6034             :       else
    6035           0 :         vty_out (vty, ", localpref %u", bgp->default_local_pref);
    6036             : 
    6037           0 :       if (attr->extra && attr->extra->weight != 0)
    6038           0 :         vty_out (vty, ", weight %u", attr->extra->weight);
    6039             :         
    6040           0 :       if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
    6041           0 :         vty_out (vty, ", valid");
    6042             : 
    6043           0 :       if (binfo->peer != bgp->peer_self)
    6044             :         {
    6045           0 :           if (binfo->peer->as == binfo->peer->local_as)
    6046           0 :             vty_out (vty, ", internal");
    6047             :           else 
    6048           0 :             vty_out (vty, ", %s", 
    6049           0 :                      (bgp_confederation_peers_check(bgp, binfo->peer->as) ? "confed-external" : "external"));
    6050             :         }
    6051           0 :       else if (binfo->sub_type == BGP_ROUTE_AGGREGATE)
    6052           0 :         vty_out (vty, ", aggregated, local");
    6053           0 :       else if (binfo->type != ZEBRA_ROUTE_BGP)
    6054           0 :         vty_out (vty, ", sourced");
    6055             :       else
    6056           0 :         vty_out (vty, ", sourced, local");
    6057             : 
    6058           0 :       if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
    6059           0 :         vty_out (vty, ", atomic-aggregate");
    6060             :           
    6061           0 :       if (CHECK_FLAG (binfo->flags, BGP_INFO_MULTIPATH) ||
    6062           0 :           (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED) &&
    6063           0 :            bgp_info_mpath_count (binfo)))
    6064           0 :         vty_out (vty, ", multipath");
    6065             : 
    6066           0 :       if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
    6067           0 :         vty_out (vty, ", best");
    6068             : 
    6069           0 :       vty_out (vty, "%s", VTY_NEWLINE);
    6070             :           
    6071             :       /* Line 4 display Community */
    6072           0 :       if (attr->community)
    6073           0 :         vty_out (vty, "      Community: %s%s", attr->community->str,
    6074           0 :                  VTY_NEWLINE);
    6075             :           
    6076             :       /* Line 5 display Extended-community */
    6077           0 :       if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
    6078           0 :         vty_out (vty, "      Extended Community: %s%s", 
    6079           0 :                  attr->extra->ecommunity->str, VTY_NEWLINE);
    6080             :           
    6081             :       /* Line 6 display Originator, Cluster-id */
    6082           0 :       if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) ||
    6083           0 :           (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)))
    6084             :         {
    6085           0 :           assert (attr->extra);
    6086           0 :           if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
    6087           0 :             vty_out (vty, "      Originator: %s", 
    6088           0 :                      inet_ntoa (attr->extra->originator_id));
    6089             : 
    6090           0 :           if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))
    6091             :             {
    6092             :               int i;
    6093           0 :               vty_out (vty, ", Cluster list: ");
    6094           0 :               for (i = 0; i < attr->extra->cluster->length / 4; i++)
    6095           0 :                 vty_out (vty, "%s ", 
    6096           0 :                          inet_ntoa (attr->extra->cluster->list[i]));
    6097             :             }
    6098           0 :           vty_out (vty, "%s", VTY_NEWLINE);
    6099             :         }
    6100             :       
    6101           0 :       if (binfo->extra && binfo->extra->damp_info)
    6102           0 :         bgp_damp_info_vty (vty, binfo);
    6103             : 
    6104             :       /* Line 7 display Uptime */
    6105             : #ifdef HAVE_CLOCK_MONOTONIC
    6106           0 :       tbuf = time(NULL) - (bgp_clock() - binfo->uptime);
    6107           0 :       vty_out (vty, "      Last update: %s", ctime(&tbuf));
    6108             : #else
    6109             :       vty_out (vty, "      Last update: %s", ctime(&binfo->uptime));
    6110             : #endif /* HAVE_CLOCK_MONOTONIC */
    6111             :     }
    6112           0 :   vty_out (vty, "%s", VTY_NEWLINE);
    6113           0 : }  
    6114             : 
    6115             : #define BGP_SHOW_SCODE_HEADER "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,%s              r RIB-failure, S Stale, R Removed%s"
    6116             : #define BGP_SHOW_OCODE_HEADER "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s"
    6117             : #define BGP_SHOW_HEADER "   Network          Next Hop            Metric LocPrf Weight Path%s"
    6118             : #define BGP_SHOW_DAMP_HEADER "   Network          From             Reuse    Path%s"
    6119             : #define BGP_SHOW_FLAP_HEADER "   Network          From            Flaps Duration Reuse    Path%s"
    6120             : 
    6121             : enum bgp_show_type
    6122             : {
    6123             :   bgp_show_type_normal,
    6124             :   bgp_show_type_regexp,
    6125             :   bgp_show_type_prefix_list,
    6126             :   bgp_show_type_filter_list,
    6127             :   bgp_show_type_route_map,
    6128             :   bgp_show_type_neighbor,
    6129             :   bgp_show_type_cidr_only,
    6130             :   bgp_show_type_prefix_longer,
    6131             :   bgp_show_type_community_all,
    6132             :   bgp_show_type_community,
    6133             :   bgp_show_type_community_exact,
    6134             :   bgp_show_type_community_list,
    6135             :   bgp_show_type_community_list_exact,
    6136             :   bgp_show_type_flap_statistics,
    6137             :   bgp_show_type_flap_address,
    6138             :   bgp_show_type_flap_prefix,
    6139             :   bgp_show_type_flap_cidr_only,
    6140             :   bgp_show_type_flap_regexp,
    6141             :   bgp_show_type_flap_filter_list,
    6142             :   bgp_show_type_flap_prefix_list,
    6143             :   bgp_show_type_flap_prefix_longer,
    6144             :   bgp_show_type_flap_route_map,
    6145             :   bgp_show_type_flap_neighbor,
    6146             :   bgp_show_type_dampend_paths,
    6147             :   bgp_show_type_damp_neighbor
    6148             : };
    6149             : 
    6150             : static int
    6151           0 : bgp_show_table (struct vty *vty, struct bgp_table *table, struct in_addr *router_id,
    6152             :           enum bgp_show_type type, void *output_arg)
    6153             : {
    6154             :   struct bgp_info *ri;
    6155             :   struct bgp_node *rn;
    6156           0 :   int header = 1;
    6157             :   int display;
    6158             :   unsigned long output_count;
    6159             : 
    6160             :   /* This is first entry point, so reset total line. */
    6161           0 :   output_count = 0;
    6162             : 
    6163             :   /* Start processing of routes. */
    6164           0 :   for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn)) 
    6165           0 :     if (rn->info != NULL)
    6166             :       {
    6167           0 :         display = 0;
    6168             : 
    6169           0 :         for (ri = rn->info; ri; ri = ri->next)
    6170             :           {
    6171           0 :             if (type == bgp_show_type_flap_statistics
    6172           0 :                 || type == bgp_show_type_flap_address
    6173           0 :                 || type == bgp_show_type_flap_prefix
    6174           0 :                 || type == bgp_show_type_flap_cidr_only
    6175           0 :                 || type == bgp_show_type_flap_regexp
    6176           0 :                 || type == bgp_show_type_flap_filter_list
    6177           0 :                 || type == bgp_show_type_flap_prefix_list
    6178           0 :                 || type == bgp_show_type_flap_prefix_longer
    6179           0 :                 || type == bgp_show_type_flap_route_map
    6180           0 :                 || type == bgp_show_type_flap_neighbor
    6181           0 :                 || type == bgp_show_type_dampend_paths
    6182           0 :                 || type == bgp_show_type_damp_neighbor)
    6183             :               {
    6184           0 :                 if (!(ri->extra && ri->extra->damp_info))
    6185           0 :                   continue;
    6186             :               }
    6187           0 :             if (type == bgp_show_type_regexp
    6188           0 :                 || type == bgp_show_type_flap_regexp)
    6189             :               {
    6190           0 :                 regex_t *regex = output_arg;
    6191             :                     
    6192           0 :                 if (bgp_regexec (regex, ri->attr->aspath) == REG_NOMATCH)
    6193           0 :                   continue;
    6194             :               }
    6195           0 :             if (type == bgp_show_type_prefix_list
    6196           0 :                 || type == bgp_show_type_flap_prefix_list)
    6197             :               {
    6198           0 :                 struct prefix_list *plist = output_arg;
    6199             :                     
    6200           0 :                 if (prefix_list_apply (plist, &rn->p) != PREFIX_PERMIT)
    6201           0 :                   continue;
    6202             :               }
    6203           0 :             if (type == bgp_show_type_filter_list
    6204           0 :                 || type == bgp_show_type_flap_filter_list)
    6205             :               {
    6206           0 :                 struct as_list *as_list = output_arg;
    6207             : 
    6208           0 :                 if (as_list_apply (as_list, ri->attr->aspath) != AS_FILTER_PERMIT)
    6209           0 :                   continue;
    6210             :               }
    6211           0 :             if (type == bgp_show_type_route_map
    6212           0 :                 || type == bgp_show_type_flap_route_map)
    6213             :               {
    6214           0 :                 struct route_map *rmap = output_arg;
    6215             :                 struct bgp_info binfo;
    6216             :                 struct attr dummy_attr;
    6217             :                 struct attr_extra dummy_extra;
    6218             :                 int ret;
    6219             : 
    6220           0 :                 dummy_attr.extra = &dummy_extra;
    6221           0 :                 bgp_attr_dup (&dummy_attr, ri->attr);
    6222             : 
    6223           0 :                 binfo.peer = ri->peer;
    6224           0 :                 binfo.attr = &dummy_attr;
    6225             : 
    6226           0 :                 ret = route_map_apply (rmap, &rn->p, RMAP_BGP, &binfo);
    6227           0 :                 if (ret == RMAP_DENYMATCH)
    6228           0 :                   continue;
    6229             :               }
    6230           0 :             if (type == bgp_show_type_neighbor
    6231           0 :                 || type == bgp_show_type_flap_neighbor
    6232           0 :                 || type == bgp_show_type_damp_neighbor)
    6233             :               {
    6234           0 :                 union sockunion *su = output_arg;
    6235             : 
    6236           0 :                 if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
    6237           0 :                   continue;
    6238             :               }
    6239           0 :             if (type == bgp_show_type_cidr_only
    6240           0 :                 || type == bgp_show_type_flap_cidr_only)
    6241             :               {
    6242             :                 u_int32_t destination;
    6243             : 
    6244           0 :                 destination = ntohl (rn->p.u.prefix4.s_addr);
    6245           0 :                 if (IN_CLASSC (destination) && rn->p.prefixlen == 24)
    6246           0 :                   continue;
    6247           0 :                 if (IN_CLASSB (destination) && rn->p.prefixlen == 16)
    6248           0 :                   continue;
    6249           0 :                 if (IN_CLASSA (destination) && rn->p.prefixlen == 8)
    6250           0 :                   continue;
    6251             :               }
    6252           0 :             if (type == bgp_show_type_prefix_longer
    6253           0 :                 || type == bgp_show_type_flap_prefix_longer)
    6254             :               {
    6255           0 :                 struct prefix *p = output_arg;
    6256             : 
    6257           0 :                 if (! prefix_match (p, &rn->p))
    6258           0 :                   continue;
    6259             :               }
    6260           0 :             if (type == bgp_show_type_community_all)
    6261             :               {
    6262           0 :                 if (! ri->attr->community)
    6263           0 :                   continue;
    6264             :               }
    6265           0 :             if (type == bgp_show_type_community)
    6266             :               {
    6267           0 :                 struct community *com = output_arg;
    6268             : 
    6269           0 :                 if (! ri->attr->community ||
    6270           0 :                     ! community_match (ri->attr->community, com))
    6271           0 :                   continue;
    6272             :               }
    6273           0 :             if (type == bgp_show_type_community_exact)
    6274             :               {
    6275           0 :                 struct community *com = output_arg;
    6276             : 
    6277           0 :                 if (! ri->attr->community ||
    6278           0 :                     ! community_cmp (ri->attr->community, com))
    6279           0 :                   continue;
    6280             :               }
    6281           0 :             if (type == bgp_show_type_community_list)
    6282             :               {
    6283           0 :                 struct community_list *list = output_arg;
    6284             : 
    6285           0 :                 if (! community_list_match (ri->attr->community, list))
    6286           0 :                   continue;
    6287             :               }
    6288           0 :             if (type == bgp_show_type_community_list_exact)
    6289             :               {
    6290           0 :                 struct community_list *list = output_arg;
    6291             : 
    6292           0 :                 if (! community_list_exact_match (ri->attr->community, list))
    6293           0 :                   continue;
    6294             :               }
    6295           0 :             if (type == bgp_show_type_flap_address
    6296           0 :                 || type == bgp_show_type_flap_prefix)
    6297             :               {
    6298           0 :                 struct prefix *p = output_arg;
    6299             : 
    6300           0 :                 if (! prefix_match (&rn->p, p))
    6301           0 :                   continue;
    6302             : 
    6303           0 :                 if (type == bgp_show_type_flap_prefix)
    6304           0 :                   if (p->prefixlen != rn->p.prefixlen)
    6305           0 :                     continue;
    6306             :               }
    6307           0 :             if (type == bgp_show_type_dampend_paths
    6308           0 :                 || type == bgp_show_type_damp_neighbor)
    6309             :               {
    6310           0 :                 if (! CHECK_FLAG (ri->flags, BGP_INFO_DAMPED)
    6311           0 :                     || CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
    6312           0 :                   continue;
    6313             :               }
    6314             : 
    6315           0 :             if (header)
    6316             :               {
    6317           0 :                 vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (*router_id), VTY_NEWLINE);
    6318           0 :                 vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
    6319           0 :                 vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
    6320           0 :                 if (type == bgp_show_type_dampend_paths
    6321           0 :                     || type == bgp_show_type_damp_neighbor)
    6322           0 :                   vty_out (vty, BGP_SHOW_DAMP_HEADER, VTY_NEWLINE);
    6323           0 :                 else if (type == bgp_show_type_flap_statistics
    6324           0 :                          || type == bgp_show_type_flap_address
    6325           0 :                          || type == bgp_show_type_flap_prefix
    6326           0 :                          || type == bgp_show_type_flap_cidr_only
    6327           0 :                          || type == bgp_show_type_flap_regexp
    6328           0 :                          || type == bgp_show_type_flap_filter_list
    6329           0 :                          || type == bgp_show_type_flap_prefix_list
    6330           0 :                          || type == bgp_show_type_flap_prefix_longer
    6331           0 :                          || type == bgp_show_type_flap_route_map
    6332           0 :                          || type == bgp_show_type_flap_neighbor)
    6333           0 :                   vty_out (vty, BGP_SHOW_FLAP_HEADER, VTY_NEWLINE);
    6334             :                 else
    6335           0 :                   vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE);
    6336           0 :                 header = 0;
    6337             :               }
    6338             : 
    6339           0 :             if (type == bgp_show_type_dampend_paths
    6340           0 :                 || type == bgp_show_type_damp_neighbor)
    6341           0 :               damp_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST);
    6342           0 :             else if (type == bgp_show_type_flap_statistics
    6343           0 :                      || type == bgp_show_type_flap_address
    6344           0 :                      || type == bgp_show_type_flap_prefix
    6345           0 :                      || type == bgp_show_type_flap_cidr_only
    6346           0 :                      || type == bgp_show_type_flap_regexp
    6347           0 :                      || type == bgp_show_type_flap_filter_list
    6348           0 :                      || type == bgp_show_type_flap_prefix_list
    6349           0 :                      || type == bgp_show_type_flap_prefix_longer
    6350           0 :                      || type == bgp_show_type_flap_route_map
    6351           0 :                      || type == bgp_show_type_flap_neighbor)
    6352           0 :               flap_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST);
    6353             :             else
    6354           0 :               route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST);
    6355           0 :             display++;
    6356             :           }
    6357           0 :         if (display)
    6358           0 :           output_count++;
    6359             :       }
    6360             : 
    6361             :   /* No route is displayed */
    6362           0 :   if (output_count == 0)
    6363             :     {
    6364           0 :       if (type == bgp_show_type_normal)
    6365           0 :         vty_out (vty, "No BGP network exists%s", VTY_NEWLINE);
    6366             :     }
    6367             :   else
    6368           0 :     vty_out (vty, "%sTotal number of prefixes %ld%s",
    6369           0 :              VTY_NEWLINE, output_count, VTY_NEWLINE);
    6370             : 
    6371           0 :   return CMD_SUCCESS;
    6372             : }
    6373             : 
    6374             : static int
    6375           0 : bgp_show (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
    6376             :          enum bgp_show_type type, void *output_arg)
    6377             : {
    6378             :   struct bgp_table *table;
    6379             : 
    6380           0 :   if (bgp == NULL) {
    6381           0 :     bgp = bgp_get_default ();
    6382             :   }
    6383             : 
    6384           0 :   if (bgp == NULL)
    6385             :     {
    6386           0 :       vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
    6387           0 :       return CMD_WARNING;
    6388             :     }
    6389             : 
    6390             : 
    6391           0 :   table = bgp->rib[afi][safi];
    6392             : 
    6393           0 :   return bgp_show_table (vty, table, &bgp->router_id, type, output_arg);
    6394             : }
    6395             : 
    6396             : /* Header of detailed BGP route information */
    6397             : static void
    6398           0 : route_vty_out_detail_header (struct vty *vty, struct bgp *bgp,
    6399             :                              struct bgp_node *rn,
    6400             :                              struct prefix_rd *prd, afi_t afi, safi_t safi)
    6401             : {
    6402             :   struct bgp_info *ri;
    6403             :   struct prefix *p;
    6404             :   struct peer *peer;
    6405             :   struct listnode *node, *nnode;
    6406             :   char buf1[INET6_ADDRSTRLEN];
    6407             :   char buf2[INET6_ADDRSTRLEN];
    6408           0 :   int count = 0;
    6409           0 :   int best = 0;
    6410           0 :   int suppress = 0;
    6411           0 :   int no_export = 0;
    6412           0 :   int no_advertise = 0;
    6413           0 :   int local_as = 0;
    6414           0 :   int first = 0;
    6415             : 
    6416           0 :   p = &rn->p;
    6417           0 :   vty_out (vty, "BGP routing table entry for %s%s%s/%d%s",
    6418             :            (safi == SAFI_MPLS_VPN ?
    6419             :            prefix_rd2str (prd, buf1, RD_ADDRSTRLEN) : ""),
    6420             :            safi == SAFI_MPLS_VPN ? ":" : "",
    6421           0 :            inet_ntop (p->family, &p->u.prefix, buf2, INET6_ADDRSTRLEN),
    6422           0 :            p->prefixlen, VTY_NEWLINE);
    6423             : 
    6424           0 :   for (ri = rn->info; ri; ri = ri->next)
    6425             :     {
    6426           0 :       count++;
    6427           0 :       if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))
    6428             :         {
    6429           0 :           best = count;
    6430           0 :           if (ri->extra && ri->extra->suppress)
    6431           0 :             suppress = 1;
    6432           0 :           if (ri->attr->community != NULL)
    6433             :             {
    6434           0 :               if (community_include (ri->attr->community, COMMUNITY_NO_ADVERTISE))
    6435           0 :                 no_advertise = 1;
    6436           0 :               if (community_include (ri->attr->community, COMMUNITY_NO_EXPORT))
    6437           0 :                 no_export = 1;
    6438           0 :               if (community_include (ri->attr->community, COMMUNITY_LOCAL_AS))
    6439           0 :                 local_as = 1;
    6440             :             }
    6441             :         }
    6442             :     }
    6443             : 
    6444           0 :   vty_out (vty, "Paths: (%d available", count);
    6445           0 :   if (best)
    6446             :     {
    6447           0 :       vty_out (vty, ", best #%d", best);
    6448           0 :       if (safi == SAFI_UNICAST)
    6449           0 :         vty_out (vty, ", table Default-IP-Routing-Table");
    6450             :     }
    6451             :   else
    6452           0 :     vty_out (vty, ", no best path");
    6453           0 :   if (no_advertise)
    6454           0 :     vty_out (vty, ", not advertised to any peer");
    6455           0 :   else if (no_export)
    6456           0 :     vty_out (vty, ", not advertised to EBGP peer");
    6457           0 :   else if (local_as)
    6458           0 :     vty_out (vty, ", not advertised outside local AS");
    6459           0 :   if (suppress)
    6460           0 :     vty_out (vty, ", Advertisements suppressed by an aggregate.");
    6461           0 :   vty_out (vty, ")%s", VTY_NEWLINE);
    6462             : 
    6463             :   /* advertised peer */
    6464           0 :   for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
    6465             :     {
    6466           0 :       if (bgp_adj_out_lookup (peer, p, afi, safi, rn))
    6467             :         {
    6468           0 :           if (! first)
    6469           0 :             vty_out (vty, "  Advertised to non peer-group peers:%s ", VTY_NEWLINE);
    6470           0 :           vty_out (vty, " %s", sockunion2str (&peer->su, buf1, SU_ADDRSTRLEN));
    6471           0 :           first = 1;
    6472             :         }
    6473             :     }
    6474           0 :   if (! first)
    6475           0 :     vty_out (vty, "  Not advertised to any peer");
    6476           0 :   vty_out (vty, "%s", VTY_NEWLINE);
    6477           0 : }
    6478             : 
    6479             : /* Display specified route of BGP table. */
    6480             : static int
    6481           0 : bgp_show_route_in_table (struct vty *vty, struct bgp *bgp, 
    6482             :                          struct bgp_table *rib, const char *ip_str,
    6483             :                          afi_t afi, safi_t safi, struct prefix_rd *prd,
    6484             :                          int prefix_check)
    6485             : {
    6486             :   int ret;
    6487             :   int header;
    6488           0 :   int display = 0;
    6489             :   struct prefix match;
    6490             :   struct bgp_node *rn;
    6491             :   struct bgp_node *rm;
    6492             :   struct bgp_info *ri;
    6493             :   struct bgp_table *table;
    6494             : 
    6495             :   /* Check IP address argument. */
    6496           0 :   ret = str2prefix (ip_str, &match);
    6497           0 :   if (! ret)
    6498             :     {
    6499           0 :       vty_out (vty, "address is malformed%s", VTY_NEWLINE);
    6500           0 :       return CMD_WARNING;
    6501             :     }
    6502             : 
    6503           0 :   match.family = afi2family (afi);
    6504             : 
    6505           0 :   if (safi == SAFI_MPLS_VPN)
    6506             :     {
    6507           0 :       for (rn = bgp_table_top (rib); rn; rn = bgp_route_next (rn))
    6508             :         {
    6509           0 :           if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
    6510           0 :             continue;
    6511             : 
    6512           0 :           if ((table = rn->info) != NULL)
    6513             :             {
    6514           0 :               header = 1;
    6515             : 
    6516           0 :               if ((rm = bgp_node_match (table, &match)) != NULL)
    6517             :                 {
    6518           0 :                   if (prefix_check && rm->p.prefixlen != match.prefixlen)
    6519             :                     {
    6520           0 :                       bgp_unlock_node (rm);
    6521           0 :                       continue;
    6522             :                     }
    6523             : 
    6524           0 :                   for (ri = rm->info; ri; ri = ri->next)
    6525             :                     {
    6526           0 :                       if (header)
    6527             :                         {
    6528           0 :                           route_vty_out_detail_header (vty, bgp, rm, (struct prefix_rd *)&rn->p,
    6529             :                                                        AFI_IP, SAFI_MPLS_VPN);
    6530             : 
    6531           0 :                           header = 0;
    6532             :                         }
    6533           0 :                       display++;
    6534           0 :                       route_vty_out_detail (vty, bgp, &rm->p, ri, AFI_IP, SAFI_MPLS_VPN);
    6535             :                     }
    6536             : 
    6537           0 :                   bgp_unlock_node (rm);
    6538             :                 }
    6539             :             }
    6540             :         }
    6541             :     }
    6542             :   else
    6543             :     {
    6544           0 :       header = 1;
    6545             : 
    6546           0 :       if ((rn = bgp_node_match (rib, &match)) != NULL)
    6547             :         {
    6548           0 :           if (! prefix_check || rn->p.prefixlen == match.prefixlen)
    6549             :             {
    6550           0 :               for (ri = rn->info; ri; ri = ri->next)
    6551             :                 {
    6552           0 :                   if (header)
    6553             :                     {
    6554           0 :                       route_vty_out_detail_header (vty, bgp, rn, NULL, afi, safi);
    6555           0 :                       header = 0;
    6556             :                     }
    6557           0 :                   display++;
    6558           0 :                   route_vty_out_detail (vty, bgp, &rn->p, ri, afi, safi);
    6559             :                 }
    6560             :             }
    6561             : 
    6562           0 :           bgp_unlock_node (rn);
    6563             :         }
    6564             :     }
    6565             : 
    6566           0 :   if (! display)
    6567             :     {
    6568           0 :       vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
    6569           0 :       return CMD_WARNING;
    6570             :     }
    6571             : 
    6572           0 :   return CMD_SUCCESS;
    6573             : }
    6574             : 
    6575             : /* Display specified route of Main RIB */
    6576             : static int
    6577           0 : bgp_show_route (struct vty *vty, const char *view_name, const char *ip_str,
    6578             :                 afi_t afi, safi_t safi, struct prefix_rd *prd,
    6579             :                 int prefix_check)
    6580             : {
    6581             :   struct bgp *bgp;
    6582             : 
    6583             :   /* BGP structure lookup. */
    6584           0 :   if (view_name)
    6585             :     {
    6586           0 :       bgp = bgp_lookup_by_name (view_name);
    6587           0 :       if (bgp == NULL)
    6588             :         {
    6589           0 :           vty_out (vty, "Can't find BGP view %s%s", view_name, VTY_NEWLINE);
    6590           0 :           return CMD_WARNING;
    6591             :         }
    6592             :     }
    6593             :   else
    6594             :     {
    6595           0 :       bgp = bgp_get_default ();
    6596           0 :       if (bgp == NULL)
    6597             :         {
    6598           0 :           vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
    6599           0 :           return CMD_WARNING;
    6600             :         }
    6601             :     }
    6602             :  
    6603           0 :   return bgp_show_route_in_table (vty, bgp, bgp->rib[afi][safi], ip_str, 
    6604             :                                    afi, safi, prd, prefix_check);
    6605             : }
    6606             : 
    6607             : /* BGP route print out function. */
    6608           0 : DEFUN (show_ip_bgp,
    6609             :        show_ip_bgp_cmd,
    6610             :        "show ip bgp",
    6611             :        SHOW_STR
    6612             :        IP_STR
    6613             :        BGP_STR)
    6614             : {
    6615           0 :   return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST, bgp_show_type_normal, NULL);
    6616             : }
    6617             : 
    6618           0 : DEFUN (show_ip_bgp_ipv4,
    6619             :        show_ip_bgp_ipv4_cmd,
    6620             :        "show ip bgp ipv4 (unicast|multicast)",
    6621             :        SHOW_STR
    6622             :        IP_STR
    6623             :        BGP_STR
    6624             :        "Address family\n"
    6625             :        "Address Family modifier\n"
    6626             :        "Address Family modifier\n")
    6627             : {
    6628           0 :   if (strncmp (argv[0], "m", 1) == 0)
    6629           0 :     return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST, bgp_show_type_normal,
    6630             :                      NULL);
    6631             :  
    6632           0 :   return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST, bgp_show_type_normal, NULL);
    6633             : }
    6634             : 
    6635             : ALIAS (show_ip_bgp_ipv4,
    6636             :        show_bgp_ipv4_safi_cmd,
    6637             :        "show bgp ipv4 (unicast|multicast)",
    6638             :        SHOW_STR
    6639             :        BGP_STR
    6640             :        "Address family\n"
    6641             :        "Address Family modifier\n"
    6642             :        "Address Family modifier\n")
    6643             : 
    6644           0 : DEFUN (show_ip_bgp_route,
    6645             :        show_ip_bgp_route_cmd,
    6646             :        "show ip bgp A.B.C.D",
    6647             :        SHOW_STR
    6648             :        IP_STR
    6649             :        BGP_STR
    6650             :        "Network in the BGP routing table to display\n")
    6651             : {
    6652           0 :   return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL, 0);
    6653             : }
    6654             : 
    6655           0 : DEFUN (show_ip_bgp_ipv4_route,
    6656             :        show_ip_bgp_ipv4_route_cmd,
    6657             :        "show ip bgp ipv4 (unicast|multicast) A.B.C.D",
    6658             :        SHOW_STR
    6659             :        IP_STR
    6660             :        BGP_STR
    6661             :        "Address family\n"
    6662             :        "Address Family modifier\n"
    6663             :        "Address Family modifier\n"
    6664             :        "Network in the BGP routing table to display\n")
    6665             : {
    6666           0 :   if (strncmp (argv[0], "m", 1) == 0)
    6667           0 :     return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MULTICAST, NULL, 0);
    6668             : 
    6669           0 :   return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 0);
    6670             : }
    6671             : 
    6672             : ALIAS (show_ip_bgp_ipv4_route,
    6673             :        show_bgp_ipv4_safi_route_cmd,
    6674             :        "show bgp ipv4 (unicast|multicast) A.B.C.D",
    6675             :        SHOW_STR
    6676             :        BGP_STR
    6677             :        "Address family\n"
    6678             :        "Address Family modifier\n"
    6679             :        "Address Family modifier\n"
    6680             :        "Network in the BGP routing table to display\n")
    6681             : 
    6682           0 : DEFUN (show_ip_bgp_vpnv4_all_route,
    6683             :        show_ip_bgp_vpnv4_all_route_cmd,
    6684             :        "show ip bgp vpnv4 all A.B.C.D",
    6685             :        SHOW_STR
    6686             :        IP_STR
    6687             :        BGP_STR
    6688             :        "Display VPNv4 NLRI specific information\n"
    6689             :        "Display information about all VPNv4 NLRIs\n"
    6690             :        "Network in the BGP routing table to display\n")
    6691             : {
    6692           0 :   return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_MPLS_VPN, NULL, 0);
    6693             : }
    6694             : 
    6695           0 : DEFUN (show_ip_bgp_vpnv4_rd_route,
    6696             :        show_ip_bgp_vpnv4_rd_route_cmd,
    6697             :        "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn A.B.C.D",
    6698             :        SHOW_STR
    6699             :        IP_STR
    6700             :        BGP_STR
    6701             :        "Display VPNv4 NLRI specific information\n"
    6702             :        "Display information for a route distinguisher\n"
    6703             :        "VPN Route Distinguisher\n"
    6704             :        "Network in the BGP routing table to display\n")
    6705             : {
    6706             :   int ret;
    6707             :   struct prefix_rd prd;
    6708             : 
    6709           0 :   ret = str2prefix_rd (argv[0], &prd);
    6710           0 :   if (! ret)
    6711             :     {
    6712           0 :       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
    6713           0 :       return CMD_WARNING;
    6714             :     }
    6715           0 :   return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MPLS_VPN, &prd, 0);
    6716             : }
    6717             : 
    6718           0 : DEFUN (show_ip_bgp_prefix,
    6719             :        show_ip_bgp_prefix_cmd,
    6720             :        "show ip bgp A.B.C.D/M",
    6721             :        SHOW_STR
    6722             :        IP_STR
    6723             :        BGP_STR
    6724             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
    6725             : {
    6726           0 :   return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL, 1);
    6727             : }
    6728             : 
    6729           0 : DEFUN (show_ip_bgp_ipv4_prefix,
    6730             :        show_ip_bgp_ipv4_prefix_cmd,
    6731             :        "show ip bgp ipv4 (unicast|multicast) A.B.C.D/M",
    6732             :        SHOW_STR
    6733             :        IP_STR
    6734             :        BGP_STR
    6735             :        "Address family\n"
    6736             :        "Address Family modifier\n"
    6737             :        "Address Family modifier\n"
    6738             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
    6739             : {
    6740           0 :   if (strncmp (argv[0], "m", 1) == 0)
    6741           0 :     return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MULTICAST, NULL, 1);
    6742             : 
    6743           0 :   return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 1);
    6744             : }
    6745             : 
    6746             : ALIAS (show_ip_bgp_ipv4_prefix,
    6747             :        show_bgp_ipv4_safi_prefix_cmd,
    6748             :        "show bgp ipv4 (unicast|multicast) A.B.C.D/M",
    6749             :        SHOW_STR
    6750             :        BGP_STR
    6751             :        "Address family\n"
    6752             :        "Address Family modifier\n"
    6753             :        "Address Family modifier\n"
    6754             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
    6755             : 
    6756           0 : DEFUN (show_ip_bgp_vpnv4_all_prefix,
    6757             :        show_ip_bgp_vpnv4_all_prefix_cmd,
    6758             :        "show ip bgp vpnv4 all A.B.C.D/M",
    6759             :        SHOW_STR
    6760             :        IP_STR
    6761             :        BGP_STR
    6762             :        "Display VPNv4 NLRI specific information\n"
    6763             :        "Display information about all VPNv4 NLRIs\n"
    6764             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
    6765             : {
    6766           0 :   return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_MPLS_VPN, NULL, 1);
    6767             : }
    6768             : 
    6769           0 : DEFUN (show_ip_bgp_vpnv4_rd_prefix,
    6770             :        show_ip_bgp_vpnv4_rd_prefix_cmd,
    6771             :        "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn A.B.C.D/M",
    6772             :        SHOW_STR
    6773             :        IP_STR
    6774             :        BGP_STR
    6775             :        "Display VPNv4 NLRI specific information\n"
    6776             :        "Display information for a route distinguisher\n"
    6777             :        "VPN Route Distinguisher\n"
    6778             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
    6779             : {
    6780             :   int ret;
    6781             :   struct prefix_rd prd;
    6782             : 
    6783           0 :   ret = str2prefix_rd (argv[0], &prd);
    6784           0 :   if (! ret)
    6785             :     {
    6786           0 :       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
    6787           0 :       return CMD_WARNING;
    6788             :     }
    6789           0 :   return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MPLS_VPN, &prd, 1);
    6790             : }
    6791             : 
    6792           0 : DEFUN (show_ip_bgp_view,
    6793             :        show_ip_bgp_view_cmd,
    6794             :        "show ip bgp view WORD",
    6795             :        SHOW_STR
    6796             :        IP_STR
    6797             :        BGP_STR
    6798             :        "BGP view\n"
    6799             :        "View name\n")
    6800             : {
    6801             :   struct bgp *bgp;
    6802             : 
    6803             :   /* BGP structure lookup. */
    6804           0 :   bgp = bgp_lookup_by_name (argv[0]);
    6805           0 :   if (bgp == NULL)
    6806             :         {
    6807           0 :           vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE);
    6808           0 :           return CMD_WARNING;
    6809             :         }
    6810             : 
    6811           0 :   return bgp_show (vty, bgp, AFI_IP, SAFI_UNICAST, bgp_show_type_normal, NULL);
    6812             : }
    6813             : 
    6814           0 : DEFUN (show_ip_bgp_view_route,
    6815             :        show_ip_bgp_view_route_cmd,
    6816             :        "show ip bgp view WORD A.B.C.D",
    6817             :        SHOW_STR
    6818             :        IP_STR
    6819             :        BGP_STR
    6820             :        "BGP view\n"
    6821             :        "View name\n"
    6822             :        "Network in the BGP routing table to display\n")
    6823             : {
    6824           0 :   return bgp_show_route (vty, argv[0], argv[1], AFI_IP, SAFI_UNICAST, NULL, 0);
    6825             : }
    6826             : 
    6827           0 : DEFUN (show_ip_bgp_view_prefix,
    6828             :        show_ip_bgp_view_prefix_cmd,
    6829             :        "show ip bgp view WORD A.B.C.D/M",
    6830             :        SHOW_STR
    6831             :        IP_STR
    6832             :        BGP_STR
    6833             :        "BGP view\n"
    6834             :        "View name\n"
    6835             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
    6836             : {
    6837           0 :   return bgp_show_route (vty, argv[0], argv[1], AFI_IP, SAFI_UNICAST, NULL, 1);
    6838             : }
    6839             : 
    6840             : #ifdef HAVE_IPV6
    6841           0 : DEFUN (show_bgp,
    6842             :        show_bgp_cmd,
    6843             :        "show bgp",
    6844             :        SHOW_STR
    6845             :        BGP_STR)
    6846             : {
    6847           0 :   return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST, bgp_show_type_normal,
    6848             :                    NULL);
    6849             : }
    6850             : 
    6851             : ALIAS (show_bgp,
    6852             :        show_bgp_ipv6_cmd,
    6853             :        "show bgp ipv6",
    6854             :        SHOW_STR
    6855             :        BGP_STR
    6856             :        "Address family\n")
    6857             : 
    6858           0 : DEFUN (show_bgp_ipv6_safi,
    6859             :        show_bgp_ipv6_safi_cmd,
    6860             :        "show bgp ipv6 (unicast|multicast)",
    6861             :        SHOW_STR
    6862             :        BGP_STR
    6863             :        "Address family\n"
    6864             :        "Address Family modifier\n"
    6865             :        "Address Family modifier\n")
    6866             : {
    6867           0 :   if (strncmp (argv[0], "m", 1) == 0)
    6868           0 :     return bgp_show (vty, NULL, AFI_IP6, SAFI_MULTICAST, bgp_show_type_normal,
    6869             :                      NULL);
    6870             : 
    6871           0 :   return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST, bgp_show_type_normal, NULL);
    6872             : }
    6873             : 
    6874             : /* old command */
    6875           0 : DEFUN (show_ipv6_bgp,
    6876             :        show_ipv6_bgp_cmd,
    6877             :        "show ipv6 bgp",
    6878             :        SHOW_STR
    6879             :        IP_STR
    6880             :        BGP_STR)
    6881             : {
    6882           0 :   return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST, bgp_show_type_normal,
    6883             :                    NULL);
    6884             : }
    6885             : 
    6886           0 : DEFUN (show_bgp_route,
    6887             :        show_bgp_route_cmd,
    6888             :        "show bgp X:X::X:X",
    6889             :        SHOW_STR
    6890             :        BGP_STR
    6891             :        "Network in the BGP routing table to display\n")
    6892             : {
    6893           0 :   return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 0);
    6894             : }
    6895             : 
    6896             : ALIAS (show_bgp_route,
    6897             :        show_bgp_ipv6_route_cmd,
    6898             :        "show bgp ipv6 X:X::X:X",
    6899             :        SHOW_STR
    6900             :        BGP_STR
    6901             :        "Address family\n"
    6902             :        "Network in the BGP routing table to display\n")
    6903             : 
    6904           0 : DEFUN (show_bgp_ipv6_safi_route,
    6905             :        show_bgp_ipv6_safi_route_cmd,
    6906             :        "show bgp ipv6 (unicast|multicast) X:X::X:X",
    6907             :        SHOW_STR
    6908             :        BGP_STR
    6909             :        "Address family\n"
    6910             :        "Address Family modifier\n"
    6911             :        "Address Family modifier\n"
    6912             :        "Network in the BGP routing table to display\n")
    6913             : {
    6914           0 :   if (strncmp (argv[0], "m", 1) == 0)
    6915           0 :     return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_MULTICAST, NULL, 0);
    6916             : 
    6917           0 :   return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_UNICAST, NULL, 0);
    6918             : }
    6919             : 
    6920             : /* old command */
    6921           0 : DEFUN (show_ipv6_bgp_route,
    6922             :        show_ipv6_bgp_route_cmd,
    6923             :        "show ipv6 bgp X:X::X:X",
    6924             :        SHOW_STR
    6925             :        IP_STR
    6926             :        BGP_STR
    6927             :        "Network in the BGP routing table to display\n")
    6928             : {
    6929           0 :   return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 0);
    6930             : }
    6931             : 
    6932           0 : DEFUN (show_bgp_prefix,
    6933             :        show_bgp_prefix_cmd,
    6934             :        "show bgp X:X::X:X/M",
    6935             :        SHOW_STR
    6936             :        BGP_STR
    6937             :        "IPv6 prefix <network>/<length>\n")
    6938             : {
    6939           0 :   return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 1);
    6940             : }
    6941             : 
    6942             : ALIAS (show_bgp_prefix,
    6943             :        show_bgp_ipv6_prefix_cmd,
    6944             :        "show bgp ipv6 X:X::X:X/M",
    6945             :        SHOW_STR
    6946             :        BGP_STR
    6947             :        "Address family\n"
    6948             :        "IPv6 prefix <network>/<length>\n")
    6949             : 
    6950           0 : DEFUN (show_bgp_ipv6_safi_prefix,
    6951             :        show_bgp_ipv6_safi_prefix_cmd,
    6952             :        "show bgp ipv6 (unicast|multicast) X:X::X:X/M",
    6953             :        SHOW_STR
    6954             :        BGP_STR
    6955             :        "Address family\n"
    6956             :        "Address Family modifier\n"
    6957             :        "Address Family modifier\n"
    6958             :        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
    6959             : {
    6960           0 :   if (strncmp (argv[0], "m", 1) == 0)
    6961           0 :     return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_MULTICAST, NULL, 1);
    6962             : 
    6963           0 :   return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_UNICAST, NULL, 1);
    6964             : }
    6965             : 
    6966             : /* old command */
    6967           0 : DEFUN (show_ipv6_bgp_prefix,
    6968             :        show_ipv6_bgp_prefix_cmd,
    6969             :        "show ipv6 bgp X:X::X:X/M",
    6970             :        SHOW_STR
    6971             :        IP_STR
    6972             :        BGP_STR
    6973             :        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
    6974             : {
    6975           0 :   return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 1);
    6976             : }
    6977             : 
    6978           0 : DEFUN (show_bgp_view,
    6979             :        show_bgp_view_cmd,
    6980             :        "show bgp view WORD",
    6981             :        SHOW_STR
    6982             :        BGP_STR
    6983             :        "BGP view\n"
    6984             :        "View name\n")
    6985             : {
    6986             :   struct bgp *bgp;
    6987             : 
    6988             :   /* BGP structure lookup. */
    6989           0 :   bgp = bgp_lookup_by_name (argv[0]);
    6990           0 :   if (bgp == NULL)
    6991             :         {
    6992           0 :           vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE);
    6993           0 :           return CMD_WARNING;
    6994             :         }
    6995             :   
    6996           0 :   return bgp_show (vty, bgp, AFI_IP6, SAFI_UNICAST, bgp_show_type_normal, NULL);
    6997             : }
    6998             : 
    6999             : ALIAS (show_bgp_view,
    7000             :        show_bgp_view_ipv6_cmd,
    7001             :        "show bgp view WORD ipv6",
    7002             :        SHOW_STR
    7003             :        BGP_STR             
    7004             :        "BGP view\n"
    7005             :        "View name\n"
    7006             :        "Address family\n")
    7007             :   
    7008           0 : DEFUN (show_bgp_view_route,
    7009             :        show_bgp_view_route_cmd,
    7010             :        "show bgp view WORD X:X::X:X",
    7011             :        SHOW_STR
    7012             :        BGP_STR
    7013             :        "BGP view\n"
    7014             :        "View name\n"
    7015             :        "Network in the BGP routing table to display\n")
    7016             : {
    7017           0 :   return bgp_show_route (vty, argv[0], argv[1], AFI_IP6, SAFI_UNICAST, NULL, 0);
    7018             : }
    7019             : 
    7020             : ALIAS (show_bgp_view_route,
    7021             :        show_bgp_view_ipv6_route_cmd,
    7022             :        "show bgp view WORD ipv6 X:X::X:X",
    7023             :        SHOW_STR
    7024             :        BGP_STR
    7025             :        "BGP view\n"
    7026             :        "View name\n"
    7027             :        "Address family\n"
    7028             :        "Network in the BGP routing table to display\n")
    7029             : 
    7030           0 : DEFUN (show_bgp_view_prefix,
    7031             :        show_bgp_view_prefix_cmd,
    7032             :        "show bgp view WORD X:X::X:X/M",
    7033             :        SHOW_STR
    7034             :        BGP_STR
    7035             :        "BGP view\n"
    7036             :        "View name\n"       
    7037             :        "IPv6 prefix <network>/<length>\n")
    7038             : {
    7039           0 :   return bgp_show_route (vty, argv[0], argv[1], AFI_IP6, SAFI_UNICAST, NULL, 1); 
    7040             : }
    7041             : 
    7042             : ALIAS (show_bgp_view_prefix,
    7043             :        show_bgp_view_ipv6_prefix_cmd,
    7044             :        "show bgp view WORD ipv6 X:X::X:X/M",
    7045             :        SHOW_STR
    7046             :        BGP_STR
    7047             :        "BGP view\n"
    7048             :        "View name\n"
    7049             :        "Address family\n"
    7050             :        "IPv6 prefix <network>/<length>\n")  
    7051             : 
    7052             : /* old command */
    7053           0 : DEFUN (show_ipv6_mbgp,
    7054             :        show_ipv6_mbgp_cmd,
    7055             :        "show ipv6 mbgp",
    7056             :        SHOW_STR
    7057             :        IP_STR
    7058             :        MBGP_STR)
    7059             : {
    7060           0 :   return bgp_show (vty, NULL, AFI_IP6, SAFI_MULTICAST, bgp_show_type_normal,
    7061             :                    NULL);
    7062             : }
    7063             : 
    7064             : /* old command */
    7065           0 : DEFUN (show_ipv6_mbgp_route,
    7066             :        show_ipv6_mbgp_route_cmd,
    7067             :        "show ipv6 mbgp X:X::X:X",
    7068             :        SHOW_STR
    7069             :        IP_STR
    7070             :        MBGP_STR
    7071             :        "Network in the MBGP routing table to display\n")
    7072             : {
    7073           0 :   return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_MULTICAST, NULL, 0);
    7074             : }
    7075             : 
    7076             : /* old command */
    7077           0 : DEFUN (show_ipv6_mbgp_prefix,
    7078             :        show_ipv6_mbgp_prefix_cmd,
    7079             :        "show ipv6 mbgp X:X::X:X/M",
    7080             :        SHOW_STR
    7081             :        IP_STR
    7082             :        MBGP_STR
    7083             :        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n")
    7084             : {
    7085           0 :   return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_MULTICAST, NULL, 1);
    7086             : }
    7087             : #endif
    7088             : 
    7089             : 
    7090             : static int
    7091           0 : bgp_show_regexp (struct vty *vty, int argc, const char **argv, afi_t afi,
    7092             :                  safi_t safi, enum bgp_show_type type)
    7093             : {
    7094             :   int i;
    7095             :   struct buffer *b;
    7096             :   char *regstr;
    7097             :   int first;
    7098             :   regex_t *regex;
    7099             :   int rc;
    7100             :   
    7101           0 :   first = 0;
    7102           0 :   b = buffer_new (1024);
    7103           0 :   for (i = 0; i < argc; i++)
    7104             :     {
    7105           0 :       if (first)
    7106           0 :         buffer_putc (b, ' ');
    7107             :       else
    7108             :         {
    7109           0 :           if ((strcmp (argv[i], "unicast") == 0) || (strcmp (argv[i], "multicast") == 0))
    7110           0 :             continue;
    7111           0 :           first = 1;
    7112             :         }
    7113             : 
    7114           0 :       buffer_putstr (b, argv[i]);
    7115             :     }
    7116           0 :   buffer_putc (b, '\0');
    7117             : 
    7118           0 :   regstr = buffer_getstr (b);
    7119           0 :   buffer_free (b);
    7120             : 
    7121           0 :   regex = bgp_regcomp (regstr);
    7122           0 :   XFREE(MTYPE_TMP, regstr);
    7123           0 :   if (! regex)
    7124             :     {
    7125           0 :       vty_out (vty, "Can't compile regexp %s%s", argv[0],
    7126           0 :                VTY_NEWLINE);
    7127           0 :       return CMD_WARNING;
    7128             :     }
    7129             : 
    7130           0 :   rc = bgp_show (vty, NULL, afi, safi, type, regex);
    7131           0 :   bgp_regex_free (regex);
    7132           0 :   return rc;
    7133             : }
    7134             : 
    7135           0 : DEFUN (show_ip_bgp_regexp, 
    7136             :        show_ip_bgp_regexp_cmd,
    7137             :        "show ip bgp regexp .LINE",
    7138             :        SHOW_STR
    7139             :        IP_STR
    7140             :        BGP_STR
    7141             :        "Display routes matching the AS path regular expression\n"
    7142             :        "A regular-expression to match the BGP AS paths\n")
    7143             : {
    7144           0 :   return bgp_show_regexp (vty, argc, argv, AFI_IP, SAFI_UNICAST,
    7145             :                           bgp_show_type_regexp);
    7146             : }
    7147             : 
    7148           0 : DEFUN (show_ip_bgp_flap_regexp, 
    7149             :        show_ip_bgp_flap_regexp_cmd,
    7150             :        "show ip bgp flap-statistics regexp .LINE",
    7151             :        SHOW_STR
    7152             :        IP_STR
    7153             :        BGP_STR
    7154             :        "Display flap statistics of routes\n"
    7155             :        "Display routes matching the AS path regular expression\n"
    7156             :        "A regular-expression to match the BGP AS paths\n")
    7157             : {
    7158           0 :   return bgp_show_regexp (vty, argc, argv, AFI_IP, SAFI_UNICAST,
    7159             :                           bgp_show_type_flap_regexp);
    7160             : }
    7161             : 
    7162           0 : DEFUN (show_ip_bgp_ipv4_regexp, 
    7163             :        show_ip_bgp_ipv4_regexp_cmd,
    7164             :        "show ip bgp ipv4 (unicast|multicast) regexp .LINE",
    7165             :        SHOW_STR
    7166             :        IP_STR
    7167             :        BGP_STR
    7168             :        "Address family\n"
    7169             :        "Address Family modifier\n"
    7170             :        "Address Family modifier\n"
    7171             :        "Display routes matching the AS path regular expression\n"
    7172             :        "A regular-expression to match the BGP AS paths\n")
    7173             : {
    7174           0 :   if (strncmp (argv[0], "m", 1) == 0)
    7175           0 :     return bgp_show_regexp (vty, argc, argv, AFI_IP, SAFI_MULTICAST,
    7176             :                             bgp_show_type_regexp);
    7177             : 
    7178           0 :   return bgp_show_regexp (vty, argc, argv, AFI_IP, SAFI_UNICAST,
    7179             :                           bgp_show_type_regexp);
    7180             : }
    7181             : 
    7182             : #ifdef HAVE_IPV6
    7183           0 : DEFUN (show_bgp_regexp, 
    7184             :        show_bgp_regexp_cmd,
    7185             :        "show bgp regexp .LINE",
    7186             :        SHOW_STR
    7187             :        BGP_STR
    7188             :        "Display routes matching the AS path regular expression\n"
    7189             :        "A regular-expression to match the BGP AS paths\n")
    7190             : {
    7191           0 :   return bgp_show_regexp (vty, argc, argv, AFI_IP6, SAFI_UNICAST,
    7192             :                           bgp_show_type_regexp);
    7193             : }
    7194             : 
    7195             : ALIAS (show_bgp_regexp, 
    7196             :        show_bgp_ipv6_regexp_cmd,
    7197             :        "show bgp ipv6 regexp .LINE",
    7198             :        SHOW_STR
    7199             :        BGP_STR
    7200             :        "Address family\n"
    7201             :        "Display routes matching the AS path regular expression\n"
    7202             :        "A regular-expression to match the BGP AS paths\n")
    7203             : 
    7204             : /* old command */
    7205           0 : DEFUN (show_ipv6_bgp_regexp, 
    7206             :        show_ipv6_bgp_regexp_cmd,
    7207             :        "show ipv6 bgp regexp .LINE",
    7208             :        SHOW_STR
    7209             :        IP_STR
    7210             :        BGP_STR
    7211             :        "Display routes matching the AS path regular expression\n"
    7212             :        "A regular-expression to match the BGP AS paths\n")
    7213             : {
    7214           0 :   return bgp_show_regexp (vty, argc, argv, AFI_IP6, SAFI_UNICAST,
    7215             :                           bgp_show_type_regexp);
    7216             : }
    7217             : 
    7218             : /* old command */
    7219           0 : DEFUN (show_ipv6_mbgp_regexp, 
    7220             :        show_ipv6_mbgp_regexp_cmd,
    7221             :        "show ipv6 mbgp regexp .LINE",
    7222             :        SHOW_STR
    7223             :        IP_STR
    7224             :        BGP_STR
    7225             :        "Display routes matching the AS path regular expression\n"
    7226             :        "A regular-expression to match the MBGP AS paths\n")
    7227             : {
    7228           0 :   return bgp_show_regexp (vty, argc, argv, AFI_IP6, SAFI_MULTICAST,
    7229             :                           bgp_show_type_regexp);
    7230             : }
    7231             : #endif /* HAVE_IPV6 */
    7232             : 
    7233             : static int
    7234           0 : bgp_show_prefix_list (struct vty *vty, const char *prefix_list_str, afi_t afi,
    7235             :                       safi_t safi, enum bgp_show_type type)
    7236             : {
    7237             :   struct prefix_list *plist;
    7238             : 
    7239           0 :   plist = prefix_list_lookup (afi, prefix_list_str);
    7240           0 :   if (plist == NULL)
    7241             :     {
    7242           0 :       vty_out (vty, "%% %s is not a valid prefix-list name%s",
    7243           0 :                prefix_list_str, VTY_NEWLINE);       
    7244           0 :       return CMD_WARNING;
    7245             :     }
    7246             : 
    7247           0 :   return bgp_show (vty, NULL, afi, safi, type, plist);
    7248             : }
    7249             : 
    7250           0 : DEFUN (show_ip_bgp_prefix_list, 
    7251             :        show_ip_bgp_prefix_list_cmd,
    7252             :        "show ip bgp prefix-list WORD",
    7253             :        SHOW_STR
    7254             :        IP_STR
    7255             :        BGP_STR
    7256             :        "Display routes conforming to the prefix-list\n"
    7257             :        "IP prefix-list name\n")
    7258             : {
    7259           0 :   return bgp_show_prefix_list (vty, argv[0], AFI_IP, SAFI_UNICAST,
    7260             :                                bgp_show_type_prefix_list);
    7261             : }
    7262             : 
    7263           0 : DEFUN (show_ip_bgp_flap_prefix_list, 
    7264             :        show_ip_bgp_flap_prefix_list_cmd,
    7265             :        "show ip bgp flap-statistics prefix-list WORD",
    7266             :        SHOW_STR
    7267             :        IP_STR
    7268             :        BGP_STR
    7269             :        "Display flap statistics of routes\n"
    7270             :        "Display routes conforming to the prefix-list\n"
    7271             :        "IP prefix-list name\n")
    7272             : {
    7273           0 :   return bgp_show_prefix_list (vty, argv[0], AFI_IP, SAFI_UNICAST,
    7274             :                                bgp_show_type_flap_prefix_list);
    7275             : }
    7276             : 
    7277           0 : DEFUN (show_ip_bgp_ipv4_prefix_list, 
    7278             :        show_ip_bgp_ipv4_prefix_list_cmd,
    7279             :        "show ip bgp ipv4 (unicast|multicast) prefix-list WORD",
    7280             :        SHOW_STR
    7281             :        IP_STR
    7282             :        BGP_STR
    7283             :        "Address family\n"
    7284             :        "Address Family modifier\n"
    7285             :        "Address Family modifier\n"
    7286             :        "Display routes conforming to the prefix-list\n"
    7287             :        "IP prefix-list name\n")
    7288             : {
    7289           0 :   if (strncmp (argv[0], "m", 1) == 0)
    7290           0 :     return bgp_show_prefix_list (vty, argv[1], AFI_IP, SAFI_MULTICAST,
    7291             :                                  bgp_show_type_prefix_list);
    7292             : 
    7293           0 :   return bgp_show_prefix_list (vty, argv[1], AFI_IP, SAFI_UNICAST,
    7294             :                                bgp_show_type_prefix_list);
    7295             : }
    7296             : 
    7297             : #ifdef HAVE_IPV6
    7298           0 : DEFUN (show_bgp_prefix_list, 
    7299             :        show_bgp_prefix_list_cmd,
    7300             :        "show bgp prefix-list WORD",
    7301             :        SHOW_STR
    7302             :        BGP_STR
    7303             :        "Display routes conforming to the prefix-list\n"
    7304             :        "IPv6 prefix-list name\n")
    7305             : {
    7306           0 :   return bgp_show_prefix_list (vty, argv[0], AFI_IP6, SAFI_UNICAST,
    7307             :                                bgp_show_type_prefix_list);
    7308             : }
    7309             : 
    7310             : ALIAS (show_bgp_prefix_list, 
    7311             :        show_bgp_ipv6_prefix_list_cmd,
    7312             :        "show bgp ipv6 prefix-list WORD",
    7313             :        SHOW_STR
    7314             :        BGP_STR
    7315             :        "Address family\n"
    7316             :        "Display routes conforming to the prefix-list\n"
    7317             :        "IPv6 prefix-list name\n")
    7318             : 
    7319             : /* old command */
    7320           0 : DEFUN (show_ipv6_bgp_prefix_list, 
    7321             :        show_ipv6_bgp_prefix_list_cmd,
    7322             :        "show ipv6 bgp prefix-list WORD",
    7323             :        SHOW_STR
    7324             :        IPV6_STR
    7325             :        BGP_STR
    7326             :        "Display routes matching the prefix-list\n"
    7327             :        "IPv6 prefix-list name\n")
    7328             : {
    7329           0 :   return bgp_show_prefix_list (vty, argv[0], AFI_IP6, SAFI_UNICAST,
    7330             :                                bgp_show_type_prefix_list);
    7331             : }
    7332             : 
    7333             : /* old command */
    7334           0 : DEFUN (show_ipv6_mbgp_prefix_list, 
    7335             :        show_ipv6_mbgp_prefix_list_cmd,
    7336             :        "show ipv6 mbgp prefix-list WORD",
    7337             :        SHOW_STR
    7338             :        IPV6_STR
    7339             :        MBGP_STR
    7340             :        "Display routes matching the prefix-list\n"
    7341             :        "IPv6 prefix-list name\n")
    7342             : {
    7343           0 :   return bgp_show_prefix_list (vty, argv[0], AFI_IP6, SAFI_MULTICAST,
    7344             :                                bgp_show_type_prefix_list);
    7345             : }
    7346             : #endif /* HAVE_IPV6 */
    7347             : 
    7348             : static int
    7349           0 : bgp_show_filter_list (struct vty *vty, const char *filter, afi_t afi,
    7350             :                       safi_t safi, enum bgp_show_type type)
    7351             : {
    7352             :   struct as_list *as_list;
    7353             : 
    7354           0 :   as_list = as_list_lookup (filter);
    7355           0 :   if (as_list == NULL)
    7356             :     {
    7357           0 :       vty_out (vty, "%% %s is not a valid AS-path access-list name%s", filter, VTY_NEWLINE);      
    7358           0 :       return CMD_WARNING;
    7359             :     }
    7360             : 
    7361           0 :   return bgp_show (vty, NULL, afi, safi, type, as_list);
    7362             : }
    7363             : 
    7364           0 : DEFUN (show_ip_bgp_filter_list, 
    7365             :        show_ip_bgp_filter_list_cmd,
    7366             :        "show ip bgp filter-list WORD",
    7367             :        SHOW_STR
    7368             :        IP_STR
    7369             :        BGP_STR
    7370             :        "Display routes conforming to the filter-list\n"
    7371             :        "Regular expression access list name\n")
    7372             : {
    7373           0 :   return bgp_show_filter_list (vty, argv[0], AFI_IP, SAFI_UNICAST,
    7374             :                                bgp_show_type_filter_list);
    7375             : }
    7376             : 
    7377           0 : DEFUN (show_ip_bgp_flap_filter_list, 
    7378             :        show_ip_bgp_flap_filter_list_cmd,
    7379             :        "show ip bgp flap-statistics filter-list WORD",
    7380             :        SHOW_STR
    7381             :        IP_STR
    7382             :        BGP_STR
    7383             :        "Display flap statistics of routes\n"
    7384             :        "Display routes conforming to the filter-list\n"
    7385             :        "Regular expression access list name\n")
    7386             : {
    7387           0 :   return bgp_show_filter_list (vty, argv[0], AFI_IP, SAFI_UNICAST,
    7388             :                                bgp_show_type_flap_filter_list);
    7389             : }
    7390             : 
    7391           0 : DEFUN (show_ip_bgp_ipv4_filter_list, 
    7392             :        show_ip_bgp_ipv4_filter_list_cmd,
    7393             :        "show ip bgp ipv4 (unicast|multicast) filter-list WORD",
    7394             :        SHOW_STR
    7395             :        IP_STR
    7396             :        BGP_STR
    7397             :        "Address family\n"
    7398             :        "Address Family modifier\n"
    7399             :        "Address Family modifier\n"
    7400             :        "Display routes conforming to the filter-list\n"
    7401             :        "Regular expression access list name\n")
    7402             : {
    7403           0 :   if (strncmp (argv[0], "m", 1) == 0)
    7404           0 :     return bgp_show_filter_list (vty, argv[1], AFI_IP, SAFI_MULTICAST,
    7405             :                                  bgp_show_type_filter_list);
    7406             :   
    7407           0 :   return bgp_show_filter_list (vty, argv[1], AFI_IP, SAFI_UNICAST,
    7408             :                                bgp_show_type_filter_list);
    7409             : }
    7410             : 
    7411             : #ifdef HAVE_IPV6
    7412           0 : DEFUN (show_bgp_filter_list, 
    7413             :        show_bgp_filter_list_cmd,
    7414             :        "show bgp filter-list WORD",
    7415             :        SHOW_STR
    7416             :        BGP_STR
    7417             :        "Display routes conforming to the filter-list\n"
    7418             :        "Regular expression access list name\n")
    7419             : {
    7420           0 :   return bgp_show_filter_list (vty, argv[0], AFI_IP6, SAFI_UNICAST,
    7421             :                                bgp_show_type_filter_list);
    7422             : }
    7423             : 
    7424             : ALIAS (show_bgp_filter_list, 
    7425             :        show_bgp_ipv6_filter_list_cmd,
    7426             :        "show bgp ipv6 filter-list WORD",
    7427             :        SHOW_STR
    7428             :        BGP_STR
    7429             :        "Address family\n"
    7430             :        "Display routes conforming to the filter-list\n"
    7431             :        "Regular expression access list name\n")
    7432             : 
    7433             : /* old command */
    7434           0 : DEFUN (show_ipv6_bgp_filter_list, 
    7435             :        show_ipv6_bgp_filter_list_cmd,
    7436             :        "show ipv6 bgp filter-list WORD",
    7437             :        SHOW_STR
    7438             :        IPV6_STR
    7439             :        BGP_STR
    7440             :        "Display routes conforming to the filter-list\n"
    7441             :        "Regular expression access list name\n")
    7442             : {
    7443           0 :   return bgp_show_filter_list (vty, argv[0], AFI_IP6, SAFI_UNICAST,
    7444             :                                bgp_show_type_filter_list);
    7445             : }
    7446             : 
    7447             : /* old command */
    7448           0 : DEFUN (show_ipv6_mbgp_filter_list, 
    7449             :        show_ipv6_mbgp_filter_list_cmd,
    7450             :        "show ipv6 mbgp filter-list WORD",
    7451             :        SHOW_STR
    7452             :        IPV6_STR
    7453             :        MBGP_STR
    7454             :        "Display routes conforming to the filter-list\n"
    7455             :        "Regular expression access list name\n")
    7456             : {
    7457           0 :   return bgp_show_filter_list (vty, argv[0], AFI_IP6, SAFI_MULTICAST,
    7458             :                                bgp_show_type_filter_list);
    7459             : }
    7460             : #endif /* HAVE_IPV6 */
    7461             : 
    7462             : static int
    7463           0 : bgp_show_route_map (struct vty *vty, const char *rmap_str, afi_t afi,
    7464             :                     safi_t safi, enum bgp_show_type type)
    7465             : {
    7466             :   struct route_map *rmap;
    7467             : 
    7468           0 :   rmap = route_map_lookup_by_name (rmap_str);
    7469           0 :   if (! rmap)
    7470             :     {
    7471           0 :       vty_out (vty, "%% %s is not a valid route-map name%s",
    7472           0 :                rmap_str, VTY_NEWLINE);      
    7473           0 :       return CMD_WARNING;
    7474             :     }
    7475             : 
    7476           0 :   return bgp_show (vty, NULL, afi, safi, type, rmap);
    7477             : }
    7478             : 
    7479           0 : DEFUN (show_ip_bgp_route_map, 
    7480             :        show_ip_bgp_route_map_cmd,
    7481             :        "show ip bgp route-map WORD",
    7482             :        SHOW_STR
    7483             :        IP_STR
    7484             :        BGP_STR
    7485             :        "Display routes matching the route-map\n"
    7486             :        "A route-map to match on\n")
    7487             : {
    7488           0 :   return bgp_show_route_map (vty, argv[0], AFI_IP, SAFI_UNICAST,
    7489             :                              bgp_show_type_route_map);
    7490             : }
    7491             : 
    7492           0 : DEFUN (show_ip_bgp_flap_route_map, 
    7493             :        show_ip_bgp_flap_route_map_cmd,
    7494             :        "show ip bgp flap-statistics route-map WORD",
    7495             :        SHOW_STR
    7496             :        IP_STR
    7497             :        BGP_STR
    7498             :        "Display flap statistics of routes\n"
    7499             :        "Display routes matching the route-map\n"
    7500             :        "A route-map to match on\n")
    7501             : {
    7502           0 :   return bgp_show_route_map (vty, argv[0], AFI_IP, SAFI_UNICAST,
    7503             :                              bgp_show_type_flap_route_map);
    7504             : }
    7505             : 
    7506           0 : DEFUN (show_ip_bgp_ipv4_route_map, 
    7507             :        show_ip_bgp_ipv4_route_map_cmd,
    7508             :        "show ip bgp ipv4 (unicast|multicast) route-map WORD",
    7509             :        SHOW_STR
    7510             :        IP_STR
    7511             :        BGP_STR
    7512             :        "Address family\n"
    7513             :        "Address Family modifier\n"
    7514             :        "Address Family modifier\n"
    7515             :        "Display routes matching the route-map\n"
    7516             :        "A route-map to match on\n")
    7517             : {
    7518           0 :   if (strncmp (argv[0], "m", 1) == 0)
    7519           0 :     return bgp_show_route_map (vty, argv[1], AFI_IP, SAFI_MULTICAST,
    7520             :                                bgp_show_type_route_map);
    7521             : 
    7522           0 :   return bgp_show_route_map (vty, argv[1], AFI_IP, SAFI_UNICAST,
    7523             :                              bgp_show_type_route_map);
    7524             : }
    7525             : 
    7526           0 : DEFUN (show_bgp_route_map, 
    7527             :        show_bgp_route_map_cmd,
    7528             :        "show bgp route-map WORD",
    7529             :        SHOW_STR
    7530             :        BGP_STR
    7531             :        "Display routes matching the route-map\n"
    7532             :        "A route-map to match on\n")
    7533             : {
    7534           0 :   return bgp_show_route_map (vty, argv[0], AFI_IP6, SAFI_UNICAST,
    7535             :                              bgp_show_type_route_map);
    7536             : }
    7537             : 
    7538             : ALIAS (show_bgp_route_map, 
    7539             :        show_bgp_ipv6_route_map_cmd,
    7540             :        "show bgp ipv6 route-map WORD",
    7541             :        SHOW_STR
    7542             :        BGP_STR
    7543             :        "Address family\n"
    7544             :        "Display routes matching the route-map\n"
    7545             :        "A route-map to match on\n")
    7546             : 
    7547           0 : DEFUN (show_ip_bgp_cidr_only,
    7548             :        show_ip_bgp_cidr_only_cmd,
    7549             :        "show ip bgp cidr-only",
    7550             :        SHOW_STR
    7551             :        IP_STR
    7552             :        BGP_STR
    7553             :        "Display only routes with non-natural netmasks\n")
    7554             : {
    7555           0 :     return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
    7556             :                      bgp_show_type_cidr_only, NULL);
    7557             : }
    7558             : 
    7559           0 : DEFUN (show_ip_bgp_flap_cidr_only,
    7560             :        show_ip_bgp_flap_cidr_only_cmd,
    7561             :        "show ip bgp flap-statistics cidr-only",
    7562             :        SHOW_STR
    7563             :        IP_STR
    7564             :        BGP_STR
    7565             :        "Display flap statistics of routes\n"
    7566             :        "Display only routes with non-natural netmasks\n")
    7567             : {
    7568           0 :   return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
    7569             :                    bgp_show_type_flap_cidr_only, NULL);
    7570             : }
    7571             : 
    7572           0 : DEFUN (show_ip_bgp_ipv4_cidr_only,
    7573             :        show_ip_bgp_ipv4_cidr_only_cmd,
    7574             :        "show ip bgp ipv4 (unicast|multicast) cidr-only",
    7575             :        SHOW_STR
    7576             :        IP_STR
    7577             :        BGP_STR
    7578             :        "Address family\n"
    7579             :        "Address Family modifier\n"
    7580             :        "Address Family modifier\n"
    7581             :        "Display only routes with non-natural netmasks\n")
    7582             : {
    7583           0 :   if (strncmp (argv[0], "m", 1) == 0)
    7584           0 :     return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST,
    7585             :                      bgp_show_type_cidr_only, NULL);
    7586             : 
    7587           0 :   return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
    7588             :                      bgp_show_type_cidr_only, NULL);
    7589             : }
    7590             : 
    7591           0 : DEFUN (show_ip_bgp_community_all,
    7592             :        show_ip_bgp_community_all_cmd,
    7593             :        "show ip bgp community",
    7594             :        SHOW_STR
    7595             :        IP_STR
    7596             :        BGP_STR
    7597             :        "Display routes matching the communities\n")
    7598             : {
    7599           0 :   return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
    7600             :                      bgp_show_type_community_all, NULL);
    7601             : }
    7602             : 
    7603           0 : DEFUN (show_ip_bgp_ipv4_community_all,
    7604             :        show_ip_bgp_ipv4_community_all_cmd,
    7605             :        "show ip bgp ipv4 (unicast|multicast) community",
    7606             :        SHOW_STR
    7607             :        IP_STR
    7608             :        BGP_STR
    7609             :        "Address family\n"
    7610             :        "Address Family modifier\n"
    7611             :        "Address Family modifier\n"
    7612             :        "Display routes matching the communities\n")
    7613             : {
    7614           0 :   if (strncmp (argv[0], "m", 1) == 0)
    7615           0 :     return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST,
    7616             :                      bgp_show_type_community_all, NULL);
    7617             :  
    7618           0 :   return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
    7619             :                    bgp_show_type_community_all, NULL);
    7620             : }
    7621             : 
    7622             : #ifdef HAVE_IPV6
    7623           0 : DEFUN (show_bgp_community_all,
    7624             :        show_bgp_community_all_cmd,
    7625             :        "show bgp community",
    7626             :        SHOW_STR
    7627             :        BGP_STR
    7628             :        "Display routes matching the communities\n")
    7629             : {
    7630           0 :   return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST,
    7631             :                    bgp_show_type_community_all, NULL);
    7632             : }
    7633             : 
    7634             : ALIAS (show_bgp_community_all,
    7635             :        show_bgp_ipv6_community_all_cmd,
    7636             :        "show bgp ipv6 community",
    7637             :        SHOW_STR
    7638             :        BGP_STR
    7639             :        "Address family\n"
    7640             :        "Display routes matching the communities\n")
    7641             : 
    7642             : /* old command */
    7643           0 : DEFUN (show_ipv6_bgp_community_all,
    7644             :        show_ipv6_bgp_community_all_cmd,
    7645             :        "show ipv6 bgp community",
    7646             :        SHOW_STR
    7647             :        IPV6_STR
    7648             :        BGP_STR
    7649             :        "Display routes matching the communities\n")
    7650             : {
    7651           0 :   return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST,
    7652             :                    bgp_show_type_community_all, NULL);
    7653             : }
    7654             : 
    7655             : /* old command */
    7656           0 : DEFUN (show_ipv6_mbgp_community_all,
    7657             :        show_ipv6_mbgp_community_all_cmd,
    7658             :        "show ipv6 mbgp community",
    7659             :        SHOW_STR
    7660             :        IPV6_STR
    7661             :        MBGP_STR
    7662             :        "Display routes matching the communities\n")
    7663             : {
    7664           0 :   return bgp_show (vty, NULL, AFI_IP6, SAFI_MULTICAST,
    7665             :                    bgp_show_type_community_all, NULL);
    7666             : }
    7667             : #endif /* HAVE_IPV6 */
    7668             : 
    7669             : static int
    7670           0 : bgp_show_community (struct vty *vty, const char *view_name, int argc,
    7671             :                     const char **argv, int exact, afi_t afi, safi_t safi)
    7672             : {
    7673             :   struct community *com;
    7674             :   struct buffer *b;
    7675             :   struct bgp *bgp;
    7676             :   int i;
    7677             :   char *str;
    7678           0 :   int first = 0;
    7679             : 
    7680             :   /* BGP structure lookup */
    7681           0 :   if (view_name)
    7682             :     {
    7683           0 :       bgp = bgp_lookup_by_name (view_name);
    7684           0 :       if (bgp == NULL)
    7685             :         {
    7686           0 :           vty_out (vty, "Can't find BGP view %s%s", view_name, VTY_NEWLINE);
    7687           0 :           return CMD_WARNING;
    7688             :         }
    7689             :     }
    7690             :   else
    7691             :     {
    7692           0 :       bgp = bgp_get_default ();
    7693           0 :       if (bgp == NULL)
    7694             :         {
    7695           0 :           vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
    7696           0 :           return CMD_WARNING;
    7697             :         }
    7698             :     }
    7699             : 
    7700           0 :   b = buffer_new (1024);
    7701           0 :   for (i = 0; i < argc; i++)
    7702             :     {
    7703           0 :       if (first)
    7704           0 :         buffer_putc (b, ' ');
    7705             :       else
    7706             :         {
    7707           0 :           if ((strcmp (argv[i], "unicast") == 0) || (strcmp (argv[i], "multicast") == 0))
    7708           0 :             continue;
    7709           0 :           first = 1;
    7710             :         }
    7711             :       
    7712           0 :       buffer_putstr (b, argv[i]);
    7713             :     }
    7714           0 :   buffer_putc (b, '\0');
    7715             : 
    7716           0 :   str = buffer_getstr (b);
    7717           0 :   buffer_free (b);
    7718             : 
    7719           0 :   com = community_str2com (str);
    7720           0 :   XFREE (MTYPE_TMP, str);
    7721           0 :   if (! com)
    7722             :     {
    7723           0 :       vty_out (vty, "%% Community malformed: %s", VTY_NEWLINE);
    7724           0 :       return CMD_WARNING;
    7725             :     }
    7726             : 
    7727           0 :   return bgp_show (vty, bgp, afi, safi,
    7728             :                    (exact ? bgp_show_type_community_exact :
    7729             :                             bgp_show_type_community), com);
    7730             : }
    7731             : 
    7732           0 : DEFUN (show_ip_bgp_community,
    7733             :        show_ip_bgp_community_cmd,
    7734             :        "show ip bgp community (AA:NN|local-AS|no-advertise|no-export)",
    7735             :        SHOW_STR
    7736             :        IP_STR
    7737             :        BGP_STR
    7738             :        "Display routes matching the communities\n"
    7739             :        "community number\n"
    7740             :        "Do not send outside local AS (well-known community)\n"
    7741             :        "Do not advertise to any peer (well-known community)\n"
    7742             :        "Do not export to next AS (well-known community)\n")
    7743             : {
    7744           0 :   return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP, SAFI_UNICAST);
    7745             : }
    7746             : 
    7747             : ALIAS (show_ip_bgp_community,
    7748             :        show_ip_bgp_community2_cmd,
    7749             :        "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    7750             :        SHOW_STR
    7751             :        IP_STR
    7752             :        BGP_STR
    7753             :        "Display routes matching the communities\n"
    7754             :        "community number\n"
    7755             :        "Do not send outside local AS (well-known community)\n"
    7756             :        "Do not advertise to any peer (well-known community)\n"
    7757             :        "Do not export to next AS (well-known community)\n"
    7758             :        "community number\n"
    7759             :        "Do not send outside local AS (well-known community)\n"
    7760             :        "Do not advertise to any peer (well-known community)\n"
    7761             :        "Do not export to next AS (well-known community)\n")
    7762             :         
    7763             : ALIAS (show_ip_bgp_community,
    7764             :        show_ip_bgp_community3_cmd,
    7765             :        "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    7766             :        SHOW_STR
    7767             :        IP_STR
    7768             :        BGP_STR
    7769             :        "Display routes matching the communities\n"
    7770             :        "community number\n"
    7771             :        "Do not send outside local AS (well-known community)\n"
    7772             :        "Do not advertise to any peer (well-known community)\n"
    7773             :        "Do not export to next AS (well-known community)\n"
    7774             :        "community number\n"
    7775             :        "Do not send outside local AS (well-known community)\n"
    7776             :        "Do not advertise to any peer (well-known community)\n"
    7777             :        "Do not export to next AS (well-known community)\n"
    7778             :        "community number\n"
    7779             :        "Do not send outside local AS (well-known community)\n"
    7780             :        "Do not advertise to any peer (well-known community)\n"
    7781             :        "Do not export to next AS (well-known community)\n")
    7782             :         
    7783             : ALIAS (show_ip_bgp_community,
    7784             :        show_ip_bgp_community4_cmd,
    7785             :        "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    7786             :        SHOW_STR
    7787             :        IP_STR
    7788             :        BGP_STR
    7789             :        "Display routes matching the communities\n"
    7790             :        "community number\n"
    7791             :        "Do not send outside local AS (well-known community)\n"
    7792             :        "Do not advertise to any peer (well-known community)\n"
    7793             :        "Do not export to next AS (well-known community)\n"
    7794             :        "community number\n"
    7795             :        "Do not send outside local AS (well-known community)\n"
    7796             :        "Do not advertise to any peer (well-known community)\n"
    7797             :        "Do not export to next AS (well-known community)\n"
    7798             :        "community number\n"
    7799             :        "Do not send outside local AS (well-known community)\n"
    7800             :        "Do not advertise to any peer (well-known community)\n"
    7801             :        "Do not export to next AS (well-known community)\n"
    7802             :        "community number\n"
    7803             :        "Do not send outside local AS (well-known community)\n"
    7804             :        "Do not advertise to any peer (well-known community)\n"
    7805             :        "Do not export to next AS (well-known community)\n")
    7806             : 
    7807           0 : DEFUN (show_ip_bgp_ipv4_community,
    7808             :        show_ip_bgp_ipv4_community_cmd,
    7809             :        "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export)",
    7810             :        SHOW_STR
    7811             :        IP_STR
    7812             :        BGP_STR
    7813             :        "Address family\n"
    7814             :        "Address Family modifier\n"
    7815             :        "Address Family modifier\n"
    7816             :        "Display routes matching the communities\n"
    7817             :        "community number\n"
    7818             :        "Do not send outside local AS (well-known community)\n"
    7819             :        "Do not advertise to any peer (well-known community)\n"
    7820             :        "Do not export to next AS (well-known community)\n")
    7821             : {
    7822           0 :   if (strncmp (argv[0], "m", 1) == 0)
    7823           0 :     return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP, SAFI_MULTICAST);
    7824             :  
    7825           0 :   return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP, SAFI_UNICAST);
    7826             : }
    7827             : 
    7828             : ALIAS (show_ip_bgp_ipv4_community,
    7829             :        show_ip_bgp_ipv4_community2_cmd,
    7830             :        "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    7831             :        SHOW_STR
    7832             :        IP_STR
    7833             :        BGP_STR
    7834             :        "Address family\n"
    7835             :        "Address Family modifier\n"
    7836             :        "Address Family modifier\n"
    7837             :        "Display routes matching the communities\n"
    7838             :        "community number\n"
    7839             :        "Do not send outside local AS (well-known community)\n"
    7840             :        "Do not advertise to any peer (well-known community)\n"
    7841             :        "Do not export to next AS (well-known community)\n"
    7842             :        "community number\n"
    7843             :        "Do not send outside local AS (well-known community)\n"
    7844             :        "Do not advertise to any peer (well-known community)\n"
    7845             :        "Do not export to next AS (well-known community)\n")
    7846             :         
    7847             : ALIAS (show_ip_bgp_ipv4_community,
    7848             :        show_ip_bgp_ipv4_community3_cmd,
    7849             :        "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    7850             :        SHOW_STR
    7851             :        IP_STR
    7852             :        BGP_STR
    7853             :        "Address family\n"
    7854             :        "Address Family modifier\n"
    7855             :        "Address Family modifier\n"
    7856             :        "Display routes matching the communities\n"
    7857             :        "community number\n"
    7858             :        "Do not send outside local AS (well-known community)\n"
    7859             :        "Do not advertise to any peer (well-known community)\n"
    7860             :        "Do not export to next AS (well-known community)\n"
    7861             :        "community number\n"
    7862             :        "Do not send outside local AS (well-known community)\n"
    7863             :        "Do not advertise to any peer (well-known community)\n"
    7864             :        "Do not export to next AS (well-known community)\n"
    7865             :        "community number\n"
    7866             :        "Do not send outside local AS (well-known community)\n"
    7867             :        "Do not advertise to any peer (well-known community)\n"
    7868             :        "Do not export to next AS (well-known community)\n")
    7869             :         
    7870             : ALIAS (show_ip_bgp_ipv4_community,
    7871             :        show_ip_bgp_ipv4_community4_cmd,
    7872             :        "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    7873             :        SHOW_STR
    7874             :        IP_STR
    7875             :        BGP_STR
    7876             :        "Address family\n"
    7877             :        "Address Family modifier\n"
    7878             :        "Address Family modifier\n"
    7879             :        "Display routes matching the communities\n"
    7880             :        "community number\n"
    7881             :        "Do not send outside local AS (well-known community)\n"
    7882             :        "Do not advertise to any peer (well-known community)\n"
    7883             :        "Do not export to next AS (well-known community)\n"
    7884             :        "community number\n"
    7885             :        "Do not send outside local AS (well-known community)\n"
    7886             :        "Do not advertise to any peer (well-known community)\n"
    7887             :        "Do not export to next AS (well-known community)\n"
    7888             :        "community number\n"
    7889             :        "Do not send outside local AS (well-known community)\n"
    7890             :        "Do not advertise to any peer (well-known community)\n"
    7891             :        "Do not export to next AS (well-known community)\n"
    7892             :        "community number\n"
    7893             :        "Do not send outside local AS (well-known community)\n"
    7894             :        "Do not advertise to any peer (well-known community)\n"
    7895             :        "Do not export to next AS (well-known community)\n")
    7896             : 
    7897           0 : DEFUN (show_bgp_view_afi_safi_community_all,
    7898             :        show_bgp_view_afi_safi_community_all_cmd,
    7899             : #ifdef HAVE_IPV6
    7900             :        "show bgp view WORD (ipv4|ipv6) (unicast|multicast) community",
    7901             : #else
    7902             :        "show bgp view WORD ipv4 (unicast|multicast) community",
    7903             : #endif
    7904             :        SHOW_STR
    7905             :        BGP_STR
    7906             :        "BGP view\n"
    7907             :        "View name\n"
    7908             :        "Address family\n"
    7909             : #ifdef HAVE_IPV6
    7910             :        "Address family\n"
    7911             : #endif
    7912             :        "Address Family modifier\n"
    7913             :        "Address Family modifier\n"
    7914             :        "Display routes matching the communities\n")
    7915             : {
    7916             :   int afi;
    7917             :   int safi;
    7918             :   struct bgp *bgp;
    7919             : 
    7920             :   /* BGP structure lookup. */
    7921           0 :   bgp = bgp_lookup_by_name (argv[0]);
    7922           0 :   if (bgp == NULL)
    7923             :     {
    7924           0 :       vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE);
    7925           0 :       return CMD_WARNING;
    7926             :     }
    7927             : 
    7928             : #ifdef HAVE_IPV6
    7929           0 :   afi = (strncmp (argv[1], "ipv6", 4) == 0) ? AFI_IP6 : AFI_IP;
    7930           0 :   safi = (strncmp (argv[2], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
    7931             : #else
    7932             :   afi = AFI_IP;
    7933             :   safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
    7934             : #endif
    7935           0 :   return bgp_show (vty, bgp, afi, safi, bgp_show_type_community_all, NULL);
    7936             : }
    7937             : 
    7938           0 : DEFUN (show_bgp_view_afi_safi_community,
    7939             :        show_bgp_view_afi_safi_community_cmd,
    7940             : #ifdef HAVE_IPV6
    7941             :        "show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export)",
    7942             : #else
    7943             :        "show bgp view WORD ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export)",
    7944             : #endif
    7945             :        SHOW_STR
    7946             :        BGP_STR
    7947             :        "BGP view\n"
    7948             :        "View name\n"
    7949             :        "Address family\n"
    7950             : #ifdef HAVE_IPV6
    7951             :        "Address family\n"
    7952             : #endif
    7953             :        "Address family modifier\n"
    7954             :        "Address family modifier\n"
    7955             :        "Display routes matching the communities\n"
    7956             :        "community number\n"
    7957             :        "Do not send outside local AS (well-known community)\n"
    7958             :        "Do not advertise to any peer (well-known community)\n"
    7959             :        "Do not export to next AS (well-known community)\n")
    7960             : {
    7961             :   int afi;
    7962             :   int safi;
    7963             : 
    7964             : #ifdef HAVE_IPV6
    7965           0 :   afi = (strncmp (argv[1], "ipv6", 4) == 0) ? AFI_IP6 : AFI_IP;
    7966           0 :   safi = (strncmp (argv[2], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
    7967           0 :   return bgp_show_community (vty, argv[0], argc-3, &argv[3], 0, afi, safi);
    7968             : #else
    7969             :   afi = AFI_IP;
    7970             :   safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
    7971             :   return bgp_show_community (vty, argv[0], argc-2, &argv[2], 0, afi, safi);
    7972             : #endif
    7973             : }
    7974             : 
    7975             : ALIAS (show_bgp_view_afi_safi_community,
    7976             :        show_bgp_view_afi_safi_community2_cmd,
    7977             : #ifdef HAVE_IPV6
    7978             :        "show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    7979             : #else
    7980             :        "show bgp view WORD ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    7981             : #endif
    7982             :        SHOW_STR
    7983             :        BGP_STR
    7984             :        "BGP view\n"
    7985             :        "View name\n"
    7986             :        "Address family\n"
    7987             : #ifdef HAVE_IPV6
    7988             :        "Address family\n"
    7989             : #endif
    7990             :        "Address family modifier\n"
    7991             :        "Address family modifier\n"
    7992             :        "Display routes matching the communities\n"
    7993             :        "community number\n"
    7994             :        "Do not send outside local AS (well-known community)\n"
    7995             :        "Do not advertise to any peer (well-known community)\n"
    7996             :        "Do not export to next AS (well-known community)\n"
    7997             :        "community number\n"
    7998             :        "Do not send outside local AS (well-known community)\n"
    7999             :        "Do not advertise to any peer (well-known community)\n"
    8000             :        "Do not export to next AS (well-known community)\n")
    8001             : 
    8002             : ALIAS (show_bgp_view_afi_safi_community,
    8003             :        show_bgp_view_afi_safi_community3_cmd,
    8004             : #ifdef HAVE_IPV6
    8005             :        "show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    8006             : #else
    8007             :        "show bgp view WORD ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    8008             : #endif
    8009             :        SHOW_STR
    8010             :        BGP_STR
    8011             :        "BGP view\n"
    8012             :        "View name\n"
    8013             :        "Address family\n"
    8014             : #ifdef HAVE_IPV6
    8015             :        "Address family\n"
    8016             : #endif
    8017             :        "Address family modifier\n"
    8018             :        "Address family modifier\n"
    8019             :        "Display routes matching the communities\n"
    8020             :        "community number\n"
    8021             :        "Do not send outside local AS (well-known community)\n"
    8022             :        "Do not advertise to any peer (well-known community)\n"
    8023             :        "Do not export to next AS (well-known community)\n"
    8024             :        "community number\n"
    8025             :        "Do not send outside local AS (well-known community)\n"
    8026             :        "Do not advertise to any peer (well-known community)\n"
    8027             :        "Do not export to next AS (well-known community)\n"
    8028             :        "community number\n"
    8029             :        "Do not send outside local AS (well-known community)\n"
    8030             :        "Do not advertise to any peer (well-known community)\n"
    8031             :        "Do not export to next AS (well-known community)\n")
    8032             : 
    8033             : ALIAS (show_bgp_view_afi_safi_community,
    8034             :        show_bgp_view_afi_safi_community4_cmd,
    8035             : #ifdef HAVE_IPV6
    8036             :        "show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    8037             : #else
    8038             :        "show bgp view WORD ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    8039             : #endif
    8040             :        SHOW_STR
    8041             :        BGP_STR
    8042             :        "BGP view\n"
    8043             :        "View name\n"
    8044             :        "Address family\n"
    8045             : #ifdef HAVE_IPV6
    8046             :        "Address family\n"
    8047             : #endif
    8048             :        "Address family modifier\n"
    8049             :        "Address family modifier\n"
    8050             :        "Display routes matching the communities\n"
    8051             :        "community number\n"
    8052             :        "Do not send outside local AS (well-known community)\n"
    8053             :        "Do not advertise to any peer (well-known community)\n"
    8054             :        "Do not export to next AS (well-known community)\n"
    8055             :        "community number\n"
    8056             :        "Do not send outside local AS (well-known community)\n"
    8057             :        "Do not advertise to any peer (well-known community)\n"
    8058             :        "Do not export to next AS (well-known community)\n"
    8059             :        "community number\n"
    8060             :        "Do not send outside local AS (well-known community)\n"
    8061             :        "Do not advertise to any peer (well-known community)\n"
    8062             :        "Do not export to next AS (well-known community)\n"
    8063             :        "community number\n"
    8064             :        "Do not send outside local AS (well-known community)\n"
    8065             :        "Do not advertise to any peer (well-known community)\n"
    8066             :        "Do not export to next AS (well-known community)\n")
    8067             : 
    8068           0 : DEFUN (show_ip_bgp_community_exact,
    8069             :        show_ip_bgp_community_exact_cmd,
    8070             :        "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8071             :        SHOW_STR
    8072             :        IP_STR
    8073             :        BGP_STR
    8074             :        "Display routes matching the communities\n"
    8075             :        "community number\n"
    8076             :        "Do not send outside local AS (well-known community)\n"
    8077             :        "Do not advertise to any peer (well-known community)\n"
    8078             :        "Do not export to next AS (well-known community)\n"
    8079             :        "Exact match of the communities")
    8080             : {
    8081           0 :   return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP, SAFI_UNICAST);
    8082             : }
    8083             : 
    8084             : ALIAS (show_ip_bgp_community_exact,
    8085             :        show_ip_bgp_community2_exact_cmd,
    8086             :        "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8087             :        SHOW_STR
    8088             :        IP_STR
    8089             :        BGP_STR
    8090             :        "Display routes matching the communities\n"
    8091             :        "community number\n"
    8092             :        "Do not send outside local AS (well-known community)\n"
    8093             :        "Do not advertise to any peer (well-known community)\n"
    8094             :        "Do not export to next AS (well-known community)\n"
    8095             :        "community number\n"
    8096             :        "Do not send outside local AS (well-known community)\n"
    8097             :        "Do not advertise to any peer (well-known community)\n"
    8098             :        "Do not export to next AS (well-known community)\n"
    8099             :        "Exact match of the communities")
    8100             : 
    8101             : ALIAS (show_ip_bgp_community_exact,
    8102             :        show_ip_bgp_community3_exact_cmd,
    8103             :        "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8104             :        SHOW_STR
    8105             :        IP_STR
    8106             :        BGP_STR
    8107             :        "Display routes matching the communities\n"
    8108             :        "community number\n"
    8109             :        "Do not send outside local AS (well-known community)\n"
    8110             :        "Do not advertise to any peer (well-known community)\n"
    8111             :        "Do not export to next AS (well-known community)\n"
    8112             :        "community number\n"
    8113             :        "Do not send outside local AS (well-known community)\n"
    8114             :        "Do not advertise to any peer (well-known community)\n"
    8115             :        "Do not export to next AS (well-known community)\n"
    8116             :        "community number\n"
    8117             :        "Do not send outside local AS (well-known community)\n"
    8118             :        "Do not advertise to any peer (well-known community)\n"
    8119             :        "Do not export to next AS (well-known community)\n"
    8120             :        "Exact match of the communities")
    8121             : 
    8122             : ALIAS (show_ip_bgp_community_exact,
    8123             :        show_ip_bgp_community4_exact_cmd,
    8124             :        "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8125             :        SHOW_STR
    8126             :        IP_STR
    8127             :        BGP_STR
    8128             :        "Display routes matching the communities\n"
    8129             :        "community number\n"
    8130             :        "Do not send outside local AS (well-known community)\n"
    8131             :        "Do not advertise to any peer (well-known community)\n"
    8132             :        "Do not export to next AS (well-known community)\n"
    8133             :        "community number\n"
    8134             :        "Do not send outside local AS (well-known community)\n"
    8135             :        "Do not advertise to any peer (well-known community)\n"
    8136             :        "Do not export to next AS (well-known community)\n"
    8137             :        "community number\n"
    8138             :        "Do not send outside local AS (well-known community)\n"
    8139             :        "Do not advertise to any peer (well-known community)\n"
    8140             :        "Do not export to next AS (well-known community)\n"
    8141             :        "community number\n"
    8142             :        "Do not send outside local AS (well-known community)\n"
    8143             :        "Do not advertise to any peer (well-known community)\n"
    8144             :        "Do not export to next AS (well-known community)\n"
    8145             :        "Exact match of the communities")
    8146             : 
    8147           0 : DEFUN (show_ip_bgp_ipv4_community_exact,
    8148             :        show_ip_bgp_ipv4_community_exact_cmd,
    8149             :        "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8150             :        SHOW_STR
    8151             :        IP_STR
    8152             :        BGP_STR
    8153             :        "Address family\n"
    8154             :        "Address Family modifier\n"
    8155             :        "Address Family modifier\n"
    8156             :        "Display routes matching the communities\n"
    8157             :        "community number\n"
    8158             :        "Do not send outside local AS (well-known community)\n"
    8159             :        "Do not advertise to any peer (well-known community)\n"
    8160             :        "Do not export to next AS (well-known community)\n"
    8161             :        "Exact match of the communities")
    8162             : {
    8163           0 :   if (strncmp (argv[0], "m", 1) == 0)
    8164           0 :     return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP, SAFI_MULTICAST);
    8165             :  
    8166           0 :   return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP, SAFI_UNICAST);
    8167             : }
    8168             : 
    8169             : ALIAS (show_ip_bgp_ipv4_community_exact,
    8170             :        show_ip_bgp_ipv4_community2_exact_cmd,
    8171             :        "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8172             :        SHOW_STR
    8173             :        IP_STR
    8174             :        BGP_STR
    8175             :        "Address family\n"
    8176             :        "Address Family modifier\n"
    8177             :        "Address Family modifier\n"
    8178             :        "Display routes matching the communities\n"
    8179             :        "community number\n"
    8180             :        "Do not send outside local AS (well-known community)\n"
    8181             :        "Do not advertise to any peer (well-known community)\n"
    8182             :        "Do not export to next AS (well-known community)\n"
    8183             :        "community number\n"
    8184             :        "Do not send outside local AS (well-known community)\n"
    8185             :        "Do not advertise to any peer (well-known community)\n"
    8186             :        "Do not export to next AS (well-known community)\n"
    8187             :        "Exact match of the communities")
    8188             : 
    8189             : ALIAS (show_ip_bgp_ipv4_community_exact,
    8190             :        show_ip_bgp_ipv4_community3_exact_cmd,
    8191             :        "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8192             :        SHOW_STR
    8193             :        IP_STR
    8194             :        BGP_STR
    8195             :        "Address family\n"
    8196             :        "Address Family modifier\n"
    8197             :        "Address Family modifier\n"
    8198             :        "Display routes matching the communities\n"
    8199             :        "community number\n"
    8200             :        "Do not send outside local AS (well-known community)\n"
    8201             :        "Do not advertise to any peer (well-known community)\n"
    8202             :        "Do not export to next AS (well-known community)\n"
    8203             :        "community number\n"
    8204             :        "Do not send outside local AS (well-known community)\n"
    8205             :        "Do not advertise to any peer (well-known community)\n"
    8206             :        "Do not export to next AS (well-known community)\n"
    8207             :        "community number\n"
    8208             :        "Do not send outside local AS (well-known community)\n"
    8209             :        "Do not advertise to any peer (well-known community)\n"
    8210             :        "Do not export to next AS (well-known community)\n"
    8211             :        "Exact match of the communities")
    8212             :        
    8213             : ALIAS (show_ip_bgp_ipv4_community_exact,
    8214             :        show_ip_bgp_ipv4_community4_exact_cmd,
    8215             :        "show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8216             :        SHOW_STR
    8217             :        IP_STR
    8218             :        BGP_STR
    8219             :        "Address family\n"
    8220             :        "Address Family modifier\n"
    8221             :        "Address Family modifier\n"
    8222             :        "Display routes matching the communities\n"
    8223             :        "community number\n"
    8224             :        "Do not send outside local AS (well-known community)\n"
    8225             :        "Do not advertise to any peer (well-known community)\n"
    8226             :        "Do not export to next AS (well-known community)\n"
    8227             :        "community number\n"
    8228             :        "Do not send outside local AS (well-known community)\n"
    8229             :        "Do not advertise to any peer (well-known community)\n"
    8230             :        "Do not export to next AS (well-known community)\n"
    8231             :        "community number\n"
    8232             :        "Do not send outside local AS (well-known community)\n"
    8233             :        "Do not advertise to any peer (well-known community)\n"
    8234             :        "Do not export to next AS (well-known community)\n"
    8235             :        "community number\n"
    8236             :        "Do not send outside local AS (well-known community)\n"
    8237             :        "Do not advertise to any peer (well-known community)\n"
    8238             :        "Do not export to next AS (well-known community)\n"
    8239             :        "Exact match of the communities")
    8240             : 
    8241             : #ifdef HAVE_IPV6
    8242           0 : DEFUN (show_bgp_community,
    8243             :        show_bgp_community_cmd,
    8244             :        "show bgp community (AA:NN|local-AS|no-advertise|no-export)",
    8245             :        SHOW_STR
    8246             :        BGP_STR
    8247             :        "Display routes matching the communities\n"
    8248             :        "community number\n"
    8249             :        "Do not send outside local AS (well-known community)\n"
    8250             :        "Do not advertise to any peer (well-known community)\n"
    8251             :        "Do not export to next AS (well-known community)\n")
    8252             : {
    8253           0 :   return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP6, SAFI_UNICAST);
    8254             : }
    8255             : 
    8256             : ALIAS (show_bgp_community,
    8257             :        show_bgp_ipv6_community_cmd,
    8258             :        "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export)",
    8259             :        SHOW_STR
    8260             :        BGP_STR
    8261             :        "Address family\n"
    8262             :        "Display routes matching the communities\n"
    8263             :        "community number\n"
    8264             :        "Do not send outside local AS (well-known community)\n"
    8265             :        "Do not advertise to any peer (well-known community)\n"
    8266             :        "Do not export to next AS (well-known community)\n")
    8267             : 
    8268             : ALIAS (show_bgp_community,
    8269             :        show_bgp_community2_cmd,
    8270             :        "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    8271             :        SHOW_STR
    8272             :        BGP_STR
    8273             :        "Display routes matching the communities\n"
    8274             :        "community number\n"
    8275             :        "Do not send outside local AS (well-known community)\n"
    8276             :        "Do not advertise to any peer (well-known community)\n"
    8277             :        "Do not export to next AS (well-known community)\n"
    8278             :        "community number\n"
    8279             :        "Do not send outside local AS (well-known community)\n"
    8280             :        "Do not advertise to any peer (well-known community)\n"
    8281             :        "Do not export to next AS (well-known community)\n")
    8282             : 
    8283             : ALIAS (show_bgp_community,
    8284             :        show_bgp_ipv6_community2_cmd,
    8285             :        "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    8286             :        SHOW_STR
    8287             :        BGP_STR
    8288             :        "Address family\n"
    8289             :        "Display routes matching the communities\n"
    8290             :        "community number\n"
    8291             :        "Do not send outside local AS (well-known community)\n"
    8292             :        "Do not advertise to any peer (well-known community)\n"
    8293             :        "Do not export to next AS (well-known community)\n"
    8294             :        "community number\n"
    8295             :        "Do not send outside local AS (well-known community)\n"
    8296             :        "Do not advertise to any peer (well-known community)\n"
    8297             :        "Do not export to next AS (well-known community)\n")
    8298             :         
    8299             : ALIAS (show_bgp_community,
    8300             :        show_bgp_community3_cmd,
    8301             :        "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    8302             :        SHOW_STR
    8303             :        BGP_STR
    8304             :        "Display routes matching the communities\n"
    8305             :        "community number\n"
    8306             :        "Do not send outside local AS (well-known community)\n"
    8307             :        "Do not advertise to any peer (well-known community)\n"
    8308             :        "Do not export to next AS (well-known community)\n"
    8309             :        "community number\n"
    8310             :        "Do not send outside local AS (well-known community)\n"
    8311             :        "Do not advertise to any peer (well-known community)\n"
    8312             :        "Do not export to next AS (well-known community)\n"
    8313             :        "community number\n"
    8314             :        "Do not send outside local AS (well-known community)\n"
    8315             :        "Do not advertise to any peer (well-known community)\n"
    8316             :        "Do not export to next AS (well-known community)\n")
    8317             : 
    8318             : ALIAS (show_bgp_community,
    8319             :        show_bgp_ipv6_community3_cmd,
    8320             :        "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    8321             :        SHOW_STR
    8322             :        BGP_STR
    8323             :        "Address family\n"
    8324             :        "Display routes matching the communities\n"
    8325             :        "community number\n"
    8326             :        "Do not send outside local AS (well-known community)\n"
    8327             :        "Do not advertise to any peer (well-known community)\n"
    8328             :        "Do not export to next AS (well-known community)\n"
    8329             :        "community number\n"
    8330             :        "Do not send outside local AS (well-known community)\n"
    8331             :        "Do not advertise to any peer (well-known community)\n"
    8332             :        "Do not export to next AS (well-known community)\n"
    8333             :        "community number\n"
    8334             :        "Do not send outside local AS (well-known community)\n"
    8335             :        "Do not advertise to any peer (well-known community)\n"
    8336             :        "Do not export to next AS (well-known community)\n")
    8337             : 
    8338             : ALIAS (show_bgp_community,
    8339             :        show_bgp_community4_cmd,
    8340             :        "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    8341             :        SHOW_STR
    8342             :        BGP_STR
    8343             :        "Display routes matching the communities\n"
    8344             :        "community number\n"
    8345             :        "Do not send outside local AS (well-known community)\n"
    8346             :        "Do not advertise to any peer (well-known community)\n"
    8347             :        "Do not export to next AS (well-known community)\n"
    8348             :        "community number\n"
    8349             :        "Do not send outside local AS (well-known community)\n"
    8350             :        "Do not advertise to any peer (well-known community)\n"
    8351             :        "Do not export to next AS (well-known community)\n"
    8352             :        "community number\n"
    8353             :        "Do not send outside local AS (well-known community)\n"
    8354             :        "Do not advertise to any peer (well-known community)\n"
    8355             :        "Do not export to next AS (well-known community)\n"
    8356             :        "community number\n"
    8357             :        "Do not send outside local AS (well-known community)\n"
    8358             :        "Do not advertise to any peer (well-known community)\n"
    8359             :        "Do not export to next AS (well-known community)\n")
    8360             : 
    8361             : ALIAS (show_bgp_community,
    8362             :        show_bgp_ipv6_community4_cmd,
    8363             :        "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    8364             :        SHOW_STR
    8365             :        BGP_STR
    8366             :        "Address family\n"
    8367             :        "Display routes matching the communities\n"
    8368             :        "community number\n"
    8369             :        "Do not send outside local AS (well-known community)\n"
    8370             :        "Do not advertise to any peer (well-known community)\n"
    8371             :        "Do not export to next AS (well-known community)\n"
    8372             :        "community number\n"
    8373             :        "Do not send outside local AS (well-known community)\n"
    8374             :        "Do not advertise to any peer (well-known community)\n"
    8375             :        "Do not export to next AS (well-known community)\n"
    8376             :        "community number\n"
    8377             :        "Do not send outside local AS (well-known community)\n"
    8378             :        "Do not advertise to any peer (well-known community)\n"
    8379             :        "Do not export to next AS (well-known community)\n"
    8380             :        "community number\n"
    8381             :        "Do not send outside local AS (well-known community)\n"
    8382             :        "Do not advertise to any peer (well-known community)\n"
    8383             :        "Do not export to next AS (well-known community)\n")
    8384             : 
    8385             : /* old command */
    8386           0 : DEFUN (show_ipv6_bgp_community,
    8387             :        show_ipv6_bgp_community_cmd,
    8388             :        "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export)",
    8389             :        SHOW_STR
    8390             :        IPV6_STR
    8391             :        BGP_STR
    8392             :        "Display routes matching the communities\n"
    8393             :        "community number\n"
    8394             :        "Do not send outside local AS (well-known community)\n"
    8395             :        "Do not advertise to any peer (well-known community)\n"
    8396             :        "Do not export to next AS (well-known community)\n")
    8397             : {
    8398           0 :   return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP6, SAFI_UNICAST);
    8399             : }
    8400             : 
    8401             : /* old command */
    8402             : ALIAS (show_ipv6_bgp_community,
    8403             :        show_ipv6_bgp_community2_cmd,
    8404             :        "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    8405             :        SHOW_STR
    8406             :        IPV6_STR
    8407             :        BGP_STR
    8408             :        "Display routes matching the communities\n"
    8409             :        "community number\n"
    8410             :        "Do not send outside local AS (well-known community)\n"
    8411             :        "Do not advertise to any peer (well-known community)\n"
    8412             :        "Do not export to next AS (well-known community)\n"
    8413             :        "community number\n"
    8414             :        "Do not send outside local AS (well-known community)\n"
    8415             :        "Do not advertise to any peer (well-known community)\n"
    8416             :        "Do not export to next AS (well-known community)\n")
    8417             : 
    8418             : /* old command */
    8419             : ALIAS (show_ipv6_bgp_community,
    8420             :        show_ipv6_bgp_community3_cmd,
    8421             :        "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    8422             :        SHOW_STR
    8423             :        IPV6_STR
    8424             :        BGP_STR
    8425             :        "Display routes matching the communities\n"
    8426             :        "community number\n"
    8427             :        "Do not send outside local AS (well-known community)\n"
    8428             :        "Do not advertise to any peer (well-known community)\n"
    8429             :        "Do not export to next AS (well-known community)\n"
    8430             :        "community number\n"
    8431             :        "Do not send outside local AS (well-known community)\n"
    8432             :        "Do not advertise to any peer (well-known community)\n"
    8433             :        "Do not export to next AS (well-known community)\n"
    8434             :        "community number\n"
    8435             :        "Do not send outside local AS (well-known community)\n"
    8436             :        "Do not advertise to any peer (well-known community)\n"
    8437             :        "Do not export to next AS (well-known community)\n")
    8438             : 
    8439             : /* old command */
    8440             : ALIAS (show_ipv6_bgp_community,
    8441             :        show_ipv6_bgp_community4_cmd,
    8442             :        "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    8443             :        SHOW_STR
    8444             :        IPV6_STR
    8445             :        BGP_STR
    8446             :        "Display routes matching the communities\n"
    8447             :        "community number\n"
    8448             :        "Do not send outside local AS (well-known community)\n"
    8449             :        "Do not advertise to any peer (well-known community)\n"
    8450             :        "Do not export to next AS (well-known community)\n"
    8451             :        "community number\n"
    8452             :        "Do not send outside local AS (well-known community)\n"
    8453             :        "Do not advertise to any peer (well-known community)\n"
    8454             :        "Do not export to next AS (well-known community)\n"
    8455             :        "community number\n"
    8456             :        "Do not send outside local AS (well-known community)\n"
    8457             :        "Do not advertise to any peer (well-known community)\n"
    8458             :        "Do not export to next AS (well-known community)\n"
    8459             :        "community number\n"
    8460             :        "Do not send outside local AS (well-known community)\n"
    8461             :        "Do not advertise to any peer (well-known community)\n"
    8462             :        "Do not export to next AS (well-known community)\n")
    8463             : 
    8464           0 : DEFUN (show_bgp_community_exact,
    8465             :        show_bgp_community_exact_cmd,
    8466             :        "show bgp community (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8467             :        SHOW_STR
    8468             :        BGP_STR
    8469             :        "Display routes matching the communities\n"
    8470             :        "community number\n"
    8471             :        "Do not send outside local AS (well-known community)\n"
    8472             :        "Do not advertise to any peer (well-known community)\n"
    8473             :        "Do not export to next AS (well-known community)\n"
    8474             :        "Exact match of the communities")
    8475             : {
    8476           0 :   return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP6, SAFI_UNICAST);
    8477             : }
    8478             : 
    8479             : ALIAS (show_bgp_community_exact,
    8480             :        show_bgp_ipv6_community_exact_cmd,
    8481             :        "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8482             :        SHOW_STR
    8483             :        BGP_STR
    8484             :        "Address family\n"
    8485             :        "Display routes matching the communities\n"
    8486             :        "community number\n"
    8487             :        "Do not send outside local AS (well-known community)\n"
    8488             :        "Do not advertise to any peer (well-known community)\n"
    8489             :        "Do not export to next AS (well-known community)\n"
    8490             :        "Exact match of the communities")
    8491             : 
    8492             : ALIAS (show_bgp_community_exact,
    8493             :        show_bgp_community2_exact_cmd,
    8494             :        "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8495             :        SHOW_STR
    8496             :        BGP_STR
    8497             :        "Display routes matching the communities\n"
    8498             :        "community number\n"
    8499             :        "Do not send outside local AS (well-known community)\n"
    8500             :        "Do not advertise to any peer (well-known community)\n"
    8501             :        "Do not export to next AS (well-known community)\n"
    8502             :        "community number\n"
    8503             :        "Do not send outside local AS (well-known community)\n"
    8504             :        "Do not advertise to any peer (well-known community)\n"
    8505             :        "Do not export to next AS (well-known community)\n"
    8506             :        "Exact match of the communities")
    8507             : 
    8508             : ALIAS (show_bgp_community_exact,
    8509             :        show_bgp_ipv6_community2_exact_cmd,
    8510             :        "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8511             :        SHOW_STR
    8512             :        BGP_STR
    8513             :        "Address family\n"
    8514             :        "Display routes matching the communities\n"
    8515             :        "community number\n"
    8516             :        "Do not send outside local AS (well-known community)\n"
    8517             :        "Do not advertise to any peer (well-known community)\n"
    8518             :        "Do not export to next AS (well-known community)\n"
    8519             :        "community number\n"
    8520             :        "Do not send outside local AS (well-known community)\n"
    8521             :        "Do not advertise to any peer (well-known community)\n"
    8522             :        "Do not export to next AS (well-known community)\n"
    8523             :        "Exact match of the communities")
    8524             : 
    8525             : ALIAS (show_bgp_community_exact,
    8526             :        show_bgp_community3_exact_cmd,
    8527             :        "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8528             :        SHOW_STR
    8529             :        BGP_STR
    8530             :        "Display routes matching the communities\n"
    8531             :        "community number\n"
    8532             :        "Do not send outside local AS (well-known community)\n"
    8533             :        "Do not advertise to any peer (well-known community)\n"
    8534             :        "Do not export to next AS (well-known community)\n"
    8535             :        "community number\n"
    8536             :        "Do not send outside local AS (well-known community)\n"
    8537             :        "Do not advertise to any peer (well-known community)\n"
    8538             :        "Do not export to next AS (well-known community)\n"
    8539             :        "community number\n"
    8540             :        "Do not send outside local AS (well-known community)\n"
    8541             :        "Do not advertise to any peer (well-known community)\n"
    8542             :        "Do not export to next AS (well-known community)\n"
    8543             :        "Exact match of the communities")
    8544             : 
    8545             : ALIAS (show_bgp_community_exact,
    8546             :        show_bgp_ipv6_community3_exact_cmd,
    8547             :        "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8548             :        SHOW_STR
    8549             :        BGP_STR
    8550             :        "Address family\n"
    8551             :        "Display routes matching the communities\n"
    8552             :        "community number\n"
    8553             :        "Do not send outside local AS (well-known community)\n"
    8554             :        "Do not advertise to any peer (well-known community)\n"
    8555             :        "Do not export to next AS (well-known community)\n"
    8556             :        "community number\n"
    8557             :        "Do not send outside local AS (well-known community)\n"
    8558             :        "Do not advertise to any peer (well-known community)\n"
    8559             :        "Do not export to next AS (well-known community)\n"
    8560             :        "community number\n"
    8561             :        "Do not send outside local AS (well-known community)\n"
    8562             :        "Do not advertise to any peer (well-known community)\n"
    8563             :        "Do not export to next AS (well-known community)\n"
    8564             :        "Exact match of the communities")
    8565             : 
    8566             : ALIAS (show_bgp_community_exact,
    8567             :        show_bgp_community4_exact_cmd,
    8568             :        "show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8569             :        SHOW_STR
    8570             :        BGP_STR
    8571             :        "Display routes matching the communities\n"
    8572             :        "community number\n"
    8573             :        "Do not send outside local AS (well-known community)\n"
    8574             :        "Do not advertise to any peer (well-known community)\n"
    8575             :        "Do not export to next AS (well-known community)\n"
    8576             :        "community number\n"
    8577             :        "Do not send outside local AS (well-known community)\n"
    8578             :        "Do not advertise to any peer (well-known community)\n"
    8579             :        "Do not export to next AS (well-known community)\n"
    8580             :        "community number\n"
    8581             :        "Do not send outside local AS (well-known community)\n"
    8582             :        "Do not advertise to any peer (well-known community)\n"
    8583             :        "Do not export to next AS (well-known community)\n"
    8584             :        "community number\n"
    8585             :        "Do not send outside local AS (well-known community)\n"
    8586             :        "Do not advertise to any peer (well-known community)\n"
    8587             :        "Do not export to next AS (well-known community)\n"
    8588             :        "Exact match of the communities")
    8589             :  
    8590             : ALIAS (show_bgp_community_exact,
    8591             :        show_bgp_ipv6_community4_exact_cmd,
    8592             :        "show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8593             :        SHOW_STR
    8594             :        BGP_STR
    8595             :        "Address family\n"
    8596             :        "Display routes matching the communities\n"
    8597             :        "community number\n"
    8598             :        "Do not send outside local AS (well-known community)\n"
    8599             :        "Do not advertise to any peer (well-known community)\n"
    8600             :        "Do not export to next AS (well-known community)\n"
    8601             :        "community number\n"
    8602             :        "Do not send outside local AS (well-known community)\n"
    8603             :        "Do not advertise to any peer (well-known community)\n"
    8604             :        "Do not export to next AS (well-known community)\n"
    8605             :        "community number\n"
    8606             :        "Do not send outside local AS (well-known community)\n"
    8607             :        "Do not advertise to any peer (well-known community)\n"
    8608             :        "Do not export to next AS (well-known community)\n"
    8609             :        "community number\n"
    8610             :        "Do not send outside local AS (well-known community)\n"
    8611             :        "Do not advertise to any peer (well-known community)\n"
    8612             :        "Do not export to next AS (well-known community)\n"
    8613             :        "Exact match of the communities")
    8614             : 
    8615             : /* old command */
    8616           0 : DEFUN (show_ipv6_bgp_community_exact,
    8617             :        show_ipv6_bgp_community_exact_cmd,
    8618             :        "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8619             :        SHOW_STR
    8620             :        IPV6_STR
    8621             :        BGP_STR
    8622             :        "Display routes matching the communities\n"
    8623             :        "community number\n"
    8624             :        "Do not send outside local AS (well-known community)\n"
    8625             :        "Do not advertise to any peer (well-known community)\n"
    8626             :        "Do not export to next AS (well-known community)\n"
    8627             :        "Exact match of the communities")
    8628             : {
    8629           0 :   return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP6, SAFI_UNICAST);
    8630             : }
    8631             : 
    8632             : /* old command */
    8633             : ALIAS (show_ipv6_bgp_community_exact,
    8634             :        show_ipv6_bgp_community2_exact_cmd,
    8635             :        "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8636             :        SHOW_STR
    8637             :        IPV6_STR
    8638             :        BGP_STR
    8639             :        "Display routes matching the communities\n"
    8640             :        "community number\n"
    8641             :        "Do not send outside local AS (well-known community)\n"
    8642             :        "Do not advertise to any peer (well-known community)\n"
    8643             :        "Do not export to next AS (well-known community)\n"
    8644             :        "community number\n"
    8645             :        "Do not send outside local AS (well-known community)\n"
    8646             :        "Do not advertise to any peer (well-known community)\n"
    8647             :        "Do not export to next AS (well-known community)\n"
    8648             :        "Exact match of the communities")
    8649             : 
    8650             : /* old command */
    8651             : ALIAS (show_ipv6_bgp_community_exact,
    8652             :        show_ipv6_bgp_community3_exact_cmd,
    8653             :        "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8654             :        SHOW_STR
    8655             :        IPV6_STR
    8656             :        BGP_STR
    8657             :        "Display routes matching the communities\n"
    8658             :        "community number\n"
    8659             :        "Do not send outside local AS (well-known community)\n"
    8660             :        "Do not advertise to any peer (well-known community)\n"
    8661             :        "Do not export to next AS (well-known community)\n"
    8662             :        "community number\n"
    8663             :        "Do not send outside local AS (well-known community)\n"
    8664             :        "Do not advertise to any peer (well-known community)\n"
    8665             :        "Do not export to next AS (well-known community)\n"
    8666             :        "community number\n"
    8667             :        "Do not send outside local AS (well-known community)\n"
    8668             :        "Do not advertise to any peer (well-known community)\n"
    8669             :        "Do not export to next AS (well-known community)\n"
    8670             :        "Exact match of the communities")
    8671             : 
    8672             : /* old command */
    8673             : ALIAS (show_ipv6_bgp_community_exact,
    8674             :        show_ipv6_bgp_community4_exact_cmd,
    8675             :        "show ipv6 bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8676             :        SHOW_STR
    8677             :        IPV6_STR
    8678             :        BGP_STR
    8679             :        "Display routes matching the communities\n"
    8680             :        "community number\n"
    8681             :        "Do not send outside local AS (well-known community)\n"
    8682             :        "Do not advertise to any peer (well-known community)\n"
    8683             :        "Do not export to next AS (well-known community)\n"
    8684             :        "community number\n"
    8685             :        "Do not send outside local AS (well-known community)\n"
    8686             :        "Do not advertise to any peer (well-known community)\n"
    8687             :        "Do not export to next AS (well-known community)\n"
    8688             :        "community number\n"
    8689             :        "Do not send outside local AS (well-known community)\n"
    8690             :        "Do not advertise to any peer (well-known community)\n"
    8691             :        "Do not export to next AS (well-known community)\n"
    8692             :        "community number\n"
    8693             :        "Do not send outside local AS (well-known community)\n"
    8694             :        "Do not advertise to any peer (well-known community)\n"
    8695             :        "Do not export to next AS (well-known community)\n"
    8696             :        "Exact match of the communities")
    8697             :  
    8698             : /* old command */
    8699           0 : DEFUN (show_ipv6_mbgp_community,
    8700             :        show_ipv6_mbgp_community_cmd,
    8701             :        "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export)",
    8702             :        SHOW_STR
    8703             :        IPV6_STR
    8704             :        MBGP_STR
    8705             :        "Display routes matching the communities\n"
    8706             :        "community number\n"
    8707             :        "Do not send outside local AS (well-known community)\n"
    8708             :        "Do not advertise to any peer (well-known community)\n"
    8709             :        "Do not export to next AS (well-known community)\n")
    8710             : {
    8711           0 :   return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP6, SAFI_MULTICAST);
    8712             : }
    8713             : 
    8714             : /* old command */
    8715             : ALIAS (show_ipv6_mbgp_community,
    8716             :        show_ipv6_mbgp_community2_cmd,
    8717             :        "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    8718             :        SHOW_STR
    8719             :        IPV6_STR
    8720             :        MBGP_STR
    8721             :        "Display routes matching the communities\n"
    8722             :        "community number\n"
    8723             :        "Do not send outside local AS (well-known community)\n"
    8724             :        "Do not advertise to any peer (well-known community)\n"
    8725             :        "Do not export to next AS (well-known community)\n"
    8726             :        "community number\n"
    8727             :        "Do not send outside local AS (well-known community)\n"
    8728             :        "Do not advertise to any peer (well-known community)\n"
    8729             :        "Do not export to next AS (well-known community)\n")
    8730             : 
    8731             : /* old command */
    8732             : ALIAS (show_ipv6_mbgp_community,
    8733             :        show_ipv6_mbgp_community3_cmd,
    8734             :        "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    8735             :        SHOW_STR
    8736             :        IPV6_STR
    8737             :        MBGP_STR
    8738             :        "Display routes matching the communities\n"
    8739             :        "community number\n"
    8740             :        "Do not send outside local AS (well-known community)\n"
    8741             :        "Do not advertise to any peer (well-known community)\n"
    8742             :        "Do not export to next AS (well-known community)\n"
    8743             :        "community number\n"
    8744             :        "Do not send outside local AS (well-known community)\n"
    8745             :        "Do not advertise to any peer (well-known community)\n"
    8746             :        "Do not export to next AS (well-known community)\n"
    8747             :        "community number\n"
    8748             :        "Do not send outside local AS (well-known community)\n"
    8749             :        "Do not advertise to any peer (well-known community)\n"
    8750             :        "Do not export to next AS (well-known community)\n")
    8751             : 
    8752             : /* old command */
    8753             : ALIAS (show_ipv6_mbgp_community,
    8754             :        show_ipv6_mbgp_community4_cmd,
    8755             :        "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
    8756             :        SHOW_STR
    8757             :        IPV6_STR
    8758             :        MBGP_STR
    8759             :        "Display routes matching the communities\n"
    8760             :        "community number\n"
    8761             :        "Do not send outside local AS (well-known community)\n"
    8762             :        "Do not advertise to any peer (well-known community)\n"
    8763             :        "Do not export to next AS (well-known community)\n"
    8764             :        "community number\n"
    8765             :        "Do not send outside local AS (well-known community)\n"
    8766             :        "Do not advertise to any peer (well-known community)\n"
    8767             :        "Do not export to next AS (well-known community)\n"
    8768             :        "community number\n"
    8769             :        "Do not send outside local AS (well-known community)\n"
    8770             :        "Do not advertise to any peer (well-known community)\n"
    8771             :        "Do not export to next AS (well-known community)\n"
    8772             :        "community number\n"
    8773             :        "Do not send outside local AS (well-known community)\n"
    8774             :        "Do not advertise to any peer (well-known community)\n"
    8775             :        "Do not export to next AS (well-known community)\n")
    8776             : 
    8777             : /* old command */
    8778           0 : DEFUN (show_ipv6_mbgp_community_exact,
    8779             :        show_ipv6_mbgp_community_exact_cmd,
    8780             :        "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8781             :        SHOW_STR
    8782             :        IPV6_STR
    8783             :        MBGP_STR
    8784             :        "Display routes matching the communities\n"
    8785             :        "community number\n"
    8786             :        "Do not send outside local AS (well-known community)\n"
    8787             :        "Do not advertise to any peer (well-known community)\n"
    8788             :        "Do not export to next AS (well-known community)\n"
    8789             :        "Exact match of the communities")
    8790             : {
    8791           0 :   return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP6, SAFI_MULTICAST);
    8792             : }
    8793             : 
    8794             : /* old command */
    8795             : ALIAS (show_ipv6_mbgp_community_exact,
    8796             :        show_ipv6_mbgp_community2_exact_cmd,
    8797             :        "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8798             :        SHOW_STR
    8799             :        IPV6_STR
    8800             :        MBGP_STR
    8801             :        "Display routes matching the communities\n"
    8802             :        "community number\n"
    8803             :        "Do not send outside local AS (well-known community)\n"
    8804             :        "Do not advertise to any peer (well-known community)\n"
    8805             :        "Do not export to next AS (well-known community)\n"
    8806             :        "community number\n"
    8807             :        "Do not send outside local AS (well-known community)\n"
    8808             :        "Do not advertise to any peer (well-known community)\n"
    8809             :        "Do not export to next AS (well-known community)\n"
    8810             :        "Exact match of the communities")
    8811             : 
    8812             : /* old command */
    8813             : ALIAS (show_ipv6_mbgp_community_exact,
    8814             :        show_ipv6_mbgp_community3_exact_cmd,
    8815             :        "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8816             :        SHOW_STR
    8817             :        IPV6_STR
    8818             :        MBGP_STR
    8819             :        "Display routes matching the communities\n"
    8820             :        "community number\n"
    8821             :        "Do not send outside local AS (well-known community)\n"
    8822             :        "Do not advertise to any peer (well-known community)\n"
    8823             :        "Do not export to next AS (well-known community)\n"
    8824             :        "community number\n"
    8825             :        "Do not send outside local AS (well-known community)\n"
    8826             :        "Do not advertise to any peer (well-known community)\n"
    8827             :        "Do not export to next AS (well-known community)\n"
    8828             :        "community number\n"
    8829             :        "Do not send outside local AS (well-known community)\n"
    8830             :        "Do not advertise to any peer (well-known community)\n"
    8831             :        "Do not export to next AS (well-known community)\n"
    8832             :        "Exact match of the communities")
    8833             : 
    8834             : /* old command */
    8835             : ALIAS (show_ipv6_mbgp_community_exact,
    8836             :        show_ipv6_mbgp_community4_exact_cmd,
    8837             :        "show ipv6 mbgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
    8838             :        SHOW_STR
    8839             :        IPV6_STR
    8840             :        MBGP_STR
    8841             :        "Display routes matching the communities\n"
    8842             :        "community number\n"
    8843             :        "Do not send outside local AS (well-known community)\n"
    8844             :        "Do not advertise to any peer (well-known community)\n"
    8845             :        "Do not export to next AS (well-known community)\n"
    8846             :        "community number\n"
    8847             :        "Do not send outside local AS (well-known community)\n"
    8848             :        "Do not advertise to any peer (well-known community)\n"
    8849             :        "Do not export to next AS (well-known community)\n"
    8850             :        "community number\n"
    8851             :        "Do not send outside local AS (well-known community)\n"
    8852             :        "Do not advertise to any peer (well-known community)\n"
    8853             :        "Do not export to next AS (well-known community)\n"
    8854             :        "community number\n"
    8855             :        "Do not send outside local AS (well-known community)\n"
    8856             :        "Do not advertise to any peer (well-known community)\n"
    8857             :        "Do not export to next AS (well-known community)\n"
    8858             :        "Exact match of the communities")
    8859             : #endif /* HAVE_IPV6 */
    8860             : 
    8861             : static int
    8862           0 : bgp_show_community_list (struct vty *vty, const char *com, int exact,
    8863             :                          afi_t afi, safi_t safi)
    8864             : {
    8865             :   struct community_list *list;
    8866             : 
    8867           0 :   list = community_list_lookup (bgp_clist, com, COMMUNITY_LIST_MASTER);
    8868           0 :   if (list == NULL)
    8869             :     {
    8870           0 :       vty_out (vty, "%% %s is not a valid community-list name%s", com,
    8871           0 :                VTY_NEWLINE);
    8872           0 :       return CMD_WARNING;
    8873             :     }
    8874             : 
    8875           0 :   return bgp_show (vty, NULL, afi, safi,
    8876             :                    (exact ? bgp_show_type_community_list_exact :
    8877             :                             bgp_show_type_community_list), list);
    8878             : }
    8879             : 
    8880           0 : DEFUN (show_ip_bgp_community_list,
    8881             :        show_ip_bgp_community_list_cmd,
    8882             :        "show ip bgp community-list (<1-500>|WORD)",
    8883             :        SHOW_STR
    8884             :        IP_STR
    8885             :        BGP_STR
    8886             :        "Display routes matching the community-list\n"
    8887             :        "community-list number\n"
    8888             :        "community-list name\n")
    8889             : {
    8890           0 :   return bgp_show_community_list (vty, argv[0], 0, AFI_IP, SAFI_UNICAST);
    8891             : }
    8892             : 
    8893           0 : DEFUN (show_ip_bgp_ipv4_community_list,
    8894             :        show_ip_bgp_ipv4_community_list_cmd,
    8895             :        "show ip bgp ipv4 (unicast|multicast) community-list (<1-500>|WORD)",
    8896             :        SHOW_STR
    8897             :        IP_STR
    8898             :        BGP_STR
    8899             :        "Address family\n"
    8900             :        "Address Family modifier\n"
    8901             :        "Address Family modifier\n"
    8902             :        "Display routes matching the community-list\n"
    8903             :        "community-list number\n"
    8904             :        "community-list name\n")
    8905             : {
    8906           0 :   if (strncmp (argv[0], "m", 1) == 0)
    8907           0 :     return bgp_show_community_list (vty, argv[1], 0, AFI_IP, SAFI_MULTICAST);
    8908             :   
    8909           0 :   return bgp_show_community_list (vty, argv[1], 0, AFI_IP, SAFI_UNICAST);
    8910             : }
    8911             : 
    8912           0 : DEFUN (show_ip_bgp_community_list_exact,
    8913             :        show_ip_bgp_community_list_exact_cmd,
    8914             :        "show ip bgp community-list (<1-500>|WORD) exact-match",
    8915             :        SHOW_STR
    8916             :        IP_STR
    8917             :        BGP_STR
    8918             :        "Display routes matching the community-list\n"
    8919             :        "community-list number\n"
    8920             :        "community-list name\n"
    8921             :        "Exact match of the communities\n")
    8922             : {
    8923           0 :   return bgp_show_community_list (vty, argv[0], 1, AFI_IP, SAFI_UNICAST);
    8924             : }
    8925             : 
    8926           0 : DEFUN (show_ip_bgp_ipv4_community_list_exact,
    8927             :        show_ip_bgp_ipv4_community_list_exact_cmd,
    8928             :        "show ip bgp ipv4 (unicast|multicast) community-list (<1-500>|WORD) exact-match",
    8929             :        SHOW_STR
    8930             :        IP_STR
    8931             :        BGP_STR
    8932             :        "Address family\n"
    8933             :        "Address Family modifier\n"
    8934             :        "Address Family modifier\n"
    8935             :        "Display routes matching the community-list\n"
    8936             :        "community-list number\n"
    8937             :        "community-list name\n"
    8938             :        "Exact match of the communities\n")
    8939             : {
    8940           0 :   if (strncmp (argv[0], "m", 1) == 0)
    8941           0 :     return bgp_show_community_list (vty, argv[1], 1, AFI_IP, SAFI_MULTICAST);
    8942             :  
    8943           0 :   return bgp_show_community_list (vty, argv[1], 1, AFI_IP, SAFI_UNICAST);
    8944             : }
    8945             : 
    8946             : #ifdef HAVE_IPV6
    8947           0 : DEFUN (show_bgp_community_list,
    8948             :        show_bgp_community_list_cmd,
    8949             :        "show bgp community-list (<1-500>|WORD)",
    8950             :        SHOW_STR
    8951             :        BGP_STR
    8952             :        "Display routes matching the community-list\n"
    8953             :        "community-list number\n"
    8954             :        "community-list name\n")
    8955             : {
    8956           0 :   return bgp_show_community_list (vty, argv[0], 0, AFI_IP6, SAFI_UNICAST);
    8957             : }
    8958             : 
    8959             : ALIAS (show_bgp_community_list,
    8960             :        show_bgp_ipv6_community_list_cmd,
    8961             :        "show bgp ipv6 community-list (<1-500>|WORD)",
    8962             :        SHOW_STR
    8963             :        BGP_STR
    8964             :        "Address family\n"
    8965             :        "Display routes matching the community-list\n"
    8966             :        "community-list number\n"
    8967             :        "community-list name\n")
    8968             : 
    8969             : /* old command */
    8970           0 : DEFUN (show_ipv6_bgp_community_list,
    8971             :        show_ipv6_bgp_community_list_cmd,
    8972             :        "show ipv6 bgp community-list WORD",
    8973             :        SHOW_STR
    8974             :        IPV6_STR
    8975             :        BGP_STR
    8976             :        "Display routes matching the community-list\n"
    8977             :        "community-list name\n")
    8978             : {
    8979           0 :   return bgp_show_community_list (vty, argv[0], 0, AFI_IP6, SAFI_UNICAST);
    8980             : }
    8981             : 
    8982             : /* old command */
    8983           0 : DEFUN (show_ipv6_mbgp_community_list,
    8984             :        show_ipv6_mbgp_community_list_cmd,
    8985             :        "show ipv6 mbgp community-list WORD",
    8986             :        SHOW_STR
    8987             :        IPV6_STR
    8988             :        MBGP_STR
    8989             :        "Display routes matching the community-list\n"
    8990             :        "community-list name\n")
    8991             : {
    8992           0 :   return bgp_show_community_list (vty, argv[0], 0, AFI_IP6, SAFI_MULTICAST);
    8993             : }
    8994             : 
    8995           0 : DEFUN (show_bgp_community_list_exact,
    8996             :        show_bgp_community_list_exact_cmd,
    8997             :        "show bgp community-list (<1-500>|WORD) exact-match",
    8998             :        SHOW_STR
    8999             :        BGP_STR
    9000             :        "Display routes matching the community-list\n"
    9001             :        "community-list number\n"
    9002             :        "community-list name\n"
    9003             :        "Exact match of the communities\n")
    9004             : {
    9005           0 :   return bgp_show_community_list (vty, argv[0], 1, AFI_IP6, SAFI_UNICAST);
    9006             : }
    9007             : 
    9008             : ALIAS (show_bgp_community_list_exact,
    9009             :        show_bgp_ipv6_community_list_exact_cmd,
    9010             :        "show bgp ipv6 community-list (<1-500>|WORD) exact-match",
    9011             :        SHOW_STR
    9012             :        BGP_STR
    9013             :        "Address family\n"
    9014             :        "Display routes matching the community-list\n"
    9015             :        "community-list number\n"
    9016             :        "community-list name\n"
    9017             :        "Exact match of the communities\n")
    9018             : 
    9019             : /* old command */
    9020           0 : DEFUN (show_ipv6_bgp_community_list_exact,
    9021             :        show_ipv6_bgp_community_list_exact_cmd,
    9022             :        "show ipv6 bgp community-list WORD exact-match",
    9023             :        SHOW_STR
    9024             :        IPV6_STR
    9025             :        BGP_STR
    9026             :        "Display routes matching the community-list\n"
    9027             :        "community-list name\n"
    9028             :        "Exact match of the communities\n")
    9029             : {
    9030           0 :   return bgp_show_community_list (vty, argv[0], 1, AFI_IP6, SAFI_UNICAST);
    9031             : }
    9032             : 
    9033             : /* old command */
    9034           0 : DEFUN (show_ipv6_mbgp_community_list_exact,
    9035             :        show_ipv6_mbgp_community_list_exact_cmd,
    9036             :        "show ipv6 mbgp community-list WORD exact-match",
    9037             :        SHOW_STR
    9038             :        IPV6_STR
    9039             :        MBGP_STR
    9040             :        "Display routes matching the community-list\n"
    9041             :        "community-list name\n"
    9042             :        "Exact match of the communities\n")
    9043             : {
    9044           0 :   return bgp_show_community_list (vty, argv[0], 1, AFI_IP6, SAFI_MULTICAST);
    9045             : }
    9046             : #endif /* HAVE_IPV6 */
    9047             : 
    9048             : static int
    9049           0 : bgp_show_prefix_longer (struct vty *vty, const char *prefix, afi_t afi,
    9050             :                         safi_t safi, enum bgp_show_type type)
    9051             : {
    9052             :   int ret;
    9053             :   struct prefix *p;
    9054             : 
    9055           0 :   p = prefix_new();
    9056             : 
    9057           0 :   ret = str2prefix (prefix, p);
    9058           0 :   if (! ret)
    9059             :     {
    9060           0 :       vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
    9061           0 :       return CMD_WARNING;
    9062             :     }
    9063             : 
    9064           0 :   ret = bgp_show (vty, NULL, afi, safi, type, p);
    9065           0 :   prefix_free(p);
    9066           0 :   return ret;
    9067             : }
    9068             : 
    9069           0 : DEFUN (show_ip_bgp_prefix_longer,
    9070             :        show_ip_bgp_prefix_longer_cmd,
    9071             :        "show ip bgp A.B.C.D/M longer-prefixes",
    9072             :        SHOW_STR
    9073             :        IP_STR
    9074             :        BGP_STR
    9075             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
    9076             :        "Display route and more specific routes\n")
    9077             : {
    9078           0 :   return bgp_show_prefix_longer (vty, argv[0], AFI_IP, SAFI_UNICAST,
    9079             :                                  bgp_show_type_prefix_longer);
    9080             : }
    9081             : 
    9082           0 : DEFUN (show_ip_bgp_flap_prefix_longer,
    9083             :        show_ip_bgp_flap_prefix_longer_cmd,
    9084             :        "show ip bgp flap-statistics A.B.C.D/M longer-prefixes",
    9085             :        SHOW_STR
    9086             :        IP_STR
    9087             :        BGP_STR
    9088             :        "Display flap statistics of routes\n"
    9089             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
    9090             :        "Display route and more specific routes\n")
    9091             : {
    9092           0 :   return bgp_show_prefix_longer (vty, argv[0], AFI_IP, SAFI_UNICAST,
    9093             :                                  bgp_show_type_flap_prefix_longer);
    9094             : }
    9095             : 
    9096           0 : DEFUN (show_ip_bgp_ipv4_prefix_longer,
    9097             :        show_ip_bgp_ipv4_prefix_longer_cmd,
    9098             :        "show ip bgp ipv4 (unicast|multicast) A.B.C.D/M longer-prefixes",
    9099             :        SHOW_STR
    9100             :        IP_STR
    9101             :        BGP_STR
    9102             :        "Address family\n"
    9103             :        "Address Family modifier\n"
    9104             :        "Address Family modifier\n"
    9105             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
    9106             :        "Display route and more specific routes\n")
    9107             : {
    9108           0 :   if (strncmp (argv[0], "m", 1) == 0)
    9109           0 :     return bgp_show_prefix_longer (vty, argv[1], AFI_IP, SAFI_MULTICAST,
    9110             :                                    bgp_show_type_prefix_longer);
    9111             : 
    9112           0 :   return bgp_show_prefix_longer (vty, argv[1], AFI_IP, SAFI_UNICAST,
    9113             :                                  bgp_show_type_prefix_longer);
    9114             : }
    9115             : 
    9116           0 : DEFUN (show_ip_bgp_flap_address,
    9117             :        show_ip_bgp_flap_address_cmd,
    9118             :        "show ip bgp flap-statistics A.B.C.D",
    9119             :        SHOW_STR
    9120             :        IP_STR
    9121             :        BGP_STR
    9122             :        "Display flap statistics of routes\n"
    9123             :        "Network in the BGP routing table to display\n")
    9124             : {
    9125           0 :   return bgp_show_prefix_longer (vty, argv[0], AFI_IP, SAFI_UNICAST,
    9126             :                                  bgp_show_type_flap_address);
    9127             : }
    9128             : 
    9129           0 : DEFUN (show_ip_bgp_flap_prefix,
    9130             :        show_ip_bgp_flap_prefix_cmd,
    9131             :        "show ip bgp flap-statistics A.B.C.D/M",
    9132             :        SHOW_STR
    9133             :        IP_STR
    9134             :        BGP_STR
    9135             :        "Display flap statistics of routes\n"
    9136             :        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
    9137             : {
    9138           0 :   return bgp_show_prefix_longer (vty, argv[0], AFI_IP, SAFI_UNICAST,
    9139             :                                  bgp_show_type_flap_prefix);
    9140             : }
    9141             : #ifdef HAVE_IPV6
    9142           0 : DEFUN (show_bgp_prefix_longer,
    9143             :        show_bgp_prefix_longer_cmd,
    9144             :        "show bgp X:X::X:X/M longer-prefixes",
    9145             :        SHOW_STR
    9146             :        BGP_STR
    9147             :        "IPv6 prefix <network>/<length>\n"
    9148             :        "Display route and more specific routes\n")
    9149             : {
    9150           0 :   return bgp_show_prefix_longer (vty, argv[0], AFI_IP6, SAFI_UNICAST,
    9151             :                                  bgp_show_type_prefix_longer);
    9152             : }
    9153             : 
    9154             : ALIAS (show_bgp_prefix_longer,
    9155             :        show_bgp_ipv6_prefix_longer_cmd,
    9156             :        "show bgp ipv6 X:X::X:X/M longer-prefixes",
    9157             :        SHOW_STR
    9158             :        BGP_STR
    9159             :        "Address family\n"
    9160             :        "IPv6 prefix <network>/<length>\n"
    9161             :        "Display route and more specific routes\n")
    9162             : 
    9163             : /* old command */
    9164           0 : DEFUN (show_ipv6_bgp_prefix_longer,
    9165             :        show_ipv6_bgp_prefix_longer_cmd,
    9166             :        "show ipv6 bgp X:X::X:X/M longer-prefixes",
    9167             :        SHOW_STR
    9168             :        IPV6_STR
    9169             :        BGP_STR
    9170             :        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
    9171             :        "Display route and more specific routes\n")
    9172             : {
    9173           0 :   return bgp_show_prefix_longer (vty, argv[0], AFI_IP6, SAFI_UNICAST,
    9174             :                                  bgp_show_type_prefix_longer);
    9175             : }
    9176             : 
    9177             : /* old command */
    9178           0 : DEFUN (show_ipv6_mbgp_prefix_longer,
    9179             :        show_ipv6_mbgp_prefix_longer_cmd,
    9180             :        "show ipv6 mbgp X:X::X:X/M longer-prefixes",
    9181             :        SHOW_STR
    9182             :        IPV6_STR
    9183             :        MBGP_STR
    9184             :        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n"
    9185             :        "Display route and more specific routes\n")
    9186             : {
    9187           0 :   return bgp_show_prefix_longer (vty, argv[0], AFI_IP6, SAFI_MULTICAST,
    9188             :                                  bgp_show_type_prefix_longer);
    9189             : }
    9190             : #endif /* HAVE_IPV6 */
    9191             : 
    9192             : static struct peer *
    9193           0 : peer_lookup_in_view (struct vty *vty, const char *view_name, 
    9194             :                      const char *ip_str)
    9195             : {
    9196             :   int ret;
    9197             :   struct bgp *bgp;
    9198             :   struct peer *peer;
    9199             :   union sockunion su;
    9200             : 
    9201             :   /* BGP structure lookup. */
    9202           0 :   if (view_name)
    9203             :     {
    9204           0 :       bgp = bgp_lookup_by_name (view_name);
    9205           0 :       if (! bgp)
    9206             :         {
    9207           0 :           vty_out (vty, "Can't find BGP view %s%s", view_name, VTY_NEWLINE);
    9208           0 :           return NULL;
    9209             :         }      
    9210             :     }
    9211             :   else
    9212             :     {
    9213           0 :       bgp = bgp_get_default ();
    9214           0 :       if (! bgp)
    9215             :         {
    9216           0 :           vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
    9217           0 :           return NULL;
    9218             :         }
    9219             :     }
    9220             : 
    9221             :   /* Get peer sockunion. */  
    9222           0 :   ret = str2sockunion (ip_str, &su);
    9223           0 :   if (ret < 0)
    9224             :     {
    9225           0 :       vty_out (vty, "Malformed address: %s%s", ip_str, VTY_NEWLINE);
    9226           0 :       return NULL;
    9227             :     }
    9228             : 
    9229             :   /* Peer structure lookup. */
    9230           0 :   peer = peer_lookup (bgp, &su);
    9231           0 :   if (! peer)
    9232             :     {
    9233           0 :       vty_out (vty, "No such neighbor%s", VTY_NEWLINE);
    9234           0 :       return NULL;
    9235             :     }
    9236             :   
    9237           0 :   return peer;
    9238             : }
    9239             : 
    9240             : enum bgp_stats
    9241             : {
    9242             :   BGP_STATS_MAXBITLEN = 0,
    9243             :   BGP_STATS_RIB,
    9244             :   BGP_STATS_PREFIXES,
    9245             :   BGP_STATS_TOTPLEN,
    9246             :   BGP_STATS_UNAGGREGATEABLE,
    9247             :   BGP_STATS_MAX_AGGREGATEABLE,
    9248             :   BGP_STATS_AGGREGATES,
    9249             :   BGP_STATS_SPACE,
    9250             :   BGP_STATS_ASPATH_COUNT,
    9251             :   BGP_STATS_ASPATH_MAXHOPS,
    9252             :   BGP_STATS_ASPATH_TOTHOPS,
    9253             :   BGP_STATS_ASPATH_MAXSIZE,
    9254             :   BGP_STATS_ASPATH_TOTSIZE,
    9255             :   BGP_STATS_ASN_HIGHEST,
    9256             :   BGP_STATS_MAX,
    9257             : };
    9258             : 
    9259             : static const char *table_stats_strs[] =
    9260             : {
    9261             :   [BGP_STATS_PREFIXES]            = "Total Prefixes",
    9262             :   [BGP_STATS_TOTPLEN]             = "Average prefix length",
    9263             :   [BGP_STATS_RIB]                 = "Total Advertisements",
    9264             :   [BGP_STATS_UNAGGREGATEABLE]     = "Unaggregateable prefixes",
    9265             :   [BGP_STATS_MAX_AGGREGATEABLE]   = "Maximum aggregateable prefixes",
    9266             :   [BGP_STATS_AGGREGATES]          = "BGP Aggregate advertisements",
    9267             :   [BGP_STATS_SPACE]               = "Address space advertised",
    9268             :   [BGP_STATS_ASPATH_COUNT]        = "Advertisements with paths",
    9269             :   [BGP_STATS_ASPATH_MAXHOPS]      = "Longest AS-Path (hops)",
    9270             :   [BGP_STATS_ASPATH_MAXSIZE]      = "Largest AS-Path (bytes)",
    9271             :   [BGP_STATS_ASPATH_TOTHOPS]      = "Average AS-Path length (hops)",
    9272             :   [BGP_STATS_ASPATH_TOTSIZE]      = "Average AS-Path size (bytes)",
    9273             :   [BGP_STATS_ASN_HIGHEST]         = "Highest public ASN",
    9274             :   [BGP_STATS_MAX] = NULL,
    9275             : };
    9276             : 
    9277             : struct bgp_table_stats
    9278             : {
    9279             :   struct bgp_table *table;
    9280             :   unsigned long long counts[BGP_STATS_MAX];
    9281             : };
    9282             : 
    9283             : #if 0
    9284             : #define TALLY_SIGFIG 100000
    9285             : static unsigned long
    9286             : ravg_tally (unsigned long count, unsigned long oldavg, unsigned long newval)
    9287             : {
    9288             :   unsigned long newtot = (count-1) * oldavg + (newval * TALLY_SIGFIG);
    9289             :   unsigned long res = (newtot * TALLY_SIGFIG) / count;
    9290             :   unsigned long ret = newtot / count;
    9291             :   
    9292             :   if ((res % TALLY_SIGFIG) > (TALLY_SIGFIG/2))
    9293             :     return ret + 1;
    9294             :   else
    9295             :     return ret;
    9296             : }
    9297             : #endif
    9298             : 
    9299             : static int
    9300           0 : bgp_table_stats_walker (struct thread *t)
    9301             : {
    9302             :   struct bgp_node *rn;
    9303             :   struct bgp_node *top;
    9304           0 :   struct bgp_table_stats *ts = THREAD_ARG (t);
    9305           0 :   unsigned int space = 0;
    9306             :   
    9307           0 :   if (!(top = bgp_table_top (ts->table)))
    9308           0 :     return 0;
    9309             : 
    9310           0 :   switch (top->p.family)
    9311             :     {
    9312             :       case AF_INET:
    9313           0 :         space = IPV4_MAX_BITLEN;
    9314           0 :         break;
    9315             :       case AF_INET6:
    9316           0 :         space = IPV6_MAX_BITLEN;
    9317           0 :         break;
    9318             :     }
    9319             :     
    9320           0 :   ts->counts[BGP_STATS_MAXBITLEN] = space;
    9321             : 
    9322           0 :   for (rn = top; rn; rn = bgp_route_next (rn))
    9323             :     {
    9324             :       struct bgp_info *ri;
    9325           0 :       struct bgp_node *prn = bgp_node_parent_nolock (rn);
    9326           0 :       unsigned int rinum = 0;
    9327             :       
    9328           0 :       if (rn == top)
    9329           0 :         continue;
    9330             :       
    9331           0 :       if (!rn->info)
    9332           0 :         continue;
    9333             :       
    9334           0 :       ts->counts[BGP_STATS_PREFIXES]++;
    9335           0 :       ts->counts[BGP_STATS_TOTPLEN] += rn->p.prefixlen;
    9336             : 
    9337             : #if 0
    9338             :       ts->counts[BGP_STATS_AVGPLEN]
    9339             :         = ravg_tally (ts->counts[BGP_STATS_PREFIXES],
    9340             :                       ts->counts[BGP_STATS_AVGPLEN],
    9341             :                       rn->p.prefixlen);
    9342             : #endif
    9343             :       
    9344             :       /* check if the prefix is included by any other announcements */
    9345           0 :       while (prn && !prn->info)
    9346           0 :         prn = bgp_node_parent_nolock (prn);
    9347             :       
    9348           0 :       if (prn == NULL || prn == top)
    9349             :         {
    9350           0 :           ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
    9351             :           /* announced address space */
    9352           0 :           if (space)
    9353           0 :             ts->counts[BGP_STATS_SPACE] += 1 << (space - rn->p.prefixlen);
    9354             :         }
    9355           0 :       else if (prn->info)
    9356           0 :         ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
    9357             :       
    9358           0 :       for (ri = rn->info; ri; ri = ri->next)
    9359             :         {
    9360           0 :           rinum++;
    9361           0 :           ts->counts[BGP_STATS_RIB]++;
    9362             :           
    9363           0 :           if (ri->attr &&
    9364           0 :               (CHECK_FLAG (ri->attr->flag,
    9365             :                            ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE))))
    9366           0 :             ts->counts[BGP_STATS_AGGREGATES]++;
    9367             :           
    9368             :           /* as-path stats */
    9369           0 :           if (ri->attr && ri->attr->aspath)
    9370             :             {
    9371           0 :               unsigned int hops = aspath_count_hops (ri->attr->aspath);
    9372           0 :               unsigned int size = aspath_size (ri->attr->aspath);
    9373           0 :               as_t highest = aspath_highest (ri->attr->aspath);
    9374             :               
    9375           0 :               ts->counts[BGP_STATS_ASPATH_COUNT]++;
    9376             :               
    9377           0 :               if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
    9378           0 :                 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
    9379             :               
    9380           0 :               if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
    9381           0 :                 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
    9382             :               
    9383           0 :               ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
    9384           0 :               ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
    9385             : #if 0
    9386             :               ts->counts[BGP_STATS_ASPATH_AVGHOPS] 
    9387             :                 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
    9388             :                               ts->counts[BGP_STATS_ASPATH_AVGHOPS],
    9389             :                               hops);
    9390             :               ts->counts[BGP_STATS_ASPATH_AVGSIZE]
    9391             :                 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
    9392             :                               ts->counts[BGP_STATS_ASPATH_AVGSIZE],
    9393             :                               size);
    9394             : #endif
    9395           0 :               if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
    9396           0 :                 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
    9397             :             }
    9398             :         }
    9399             :     }
    9400           0 :   return 0;
    9401             : }
    9402             : 
    9403             : static int
    9404           0 : bgp_table_stats (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi)
    9405             : {
    9406             :   struct bgp_table_stats ts;
    9407             :   unsigned int i;
    9408             :   
    9409           0 :   if (!bgp->rib[afi][safi])
    9410             :     {
    9411           0 :       vty_out (vty, "%% No RIB exist for the AFI/SAFI%s", VTY_NEWLINE);
    9412           0 :       return CMD_WARNING;
    9413             :     }
    9414             :   
    9415           0 :   memset (&ts, 0, sizeof (ts));
    9416           0 :   ts.table = bgp->rib[afi][safi];
    9417           0 :   thread_execute (bm->master, bgp_table_stats_walker, &ts, 0);
    9418             : 
    9419           0 :   vty_out (vty, "BGP %s RIB statistics%s%s",
    9420           0 :            afi_safi_print (afi, safi), VTY_NEWLINE, VTY_NEWLINE);
    9421             :   
    9422           0 :   for (i = 0; i < BGP_STATS_MAX; i++)
    9423             :     {
    9424           0 :       if (!table_stats_strs[i])
    9425           0 :         continue;
    9426             :       
    9427           0 :       switch (i)
    9428             :         {
    9429             : #if 0
    9430             :           case BGP_STATS_ASPATH_AVGHOPS:
    9431             :           case BGP_STATS_ASPATH_AVGSIZE:
    9432             :           case BGP_STATS_AVGPLEN:
    9433             :             vty_out (vty, "%-30s: ", table_stats_strs[i]);
    9434             :             vty_out (vty, "%12.2f",
    9435             :                      (float)ts.counts[i] / (float)TALLY_SIGFIG);
    9436             :             break;
    9437             : #endif
    9438             :           case BGP_STATS_ASPATH_TOTHOPS:
    9439             :           case BGP_STATS_ASPATH_TOTSIZE:
    9440           0 :             vty_out (vty, "%-30s: ", table_stats_strs[i]);
    9441           0 :             vty_out (vty, "%12.2f",
    9442           0 :                      ts.counts[i] ?
    9443           0 :                      (float)ts.counts[i] / 
    9444           0 :                       (float)ts.counts[BGP_STATS_ASPATH_COUNT]
    9445             :                      : 0);
    9446           0 :             break;
    9447             :           case BGP_STATS_TOTPLEN:
    9448           0 :             vty_out (vty, "%-30s: ", table_stats_strs[i]);
    9449           0 :             vty_out (vty, "%12.2f",
    9450           0 :                      ts.counts[i] ?
    9451           0 :                      (float)ts.counts[i] / 
    9452           0 :                       (float)ts.counts[BGP_STATS_PREFIXES]
    9453             :                      : 0);
    9454           0 :             break;
    9455             :           case BGP_STATS_SPACE:
    9456           0 :             vty_out (vty, "%-30s: ", table_stats_strs[i]);
    9457           0 :             vty_out (vty, "%12llu%s", ts.counts[i], VTY_NEWLINE);
    9458           0 :             if (ts.counts[BGP_STATS_MAXBITLEN] < 9)
    9459           0 :               break;
    9460           0 :             vty_out (vty, "%30s: ", "%% announced ");
    9461           0 :             vty_out (vty, "%12.2f%s", 
    9462           0 :                      100 * (float)ts.counts[BGP_STATS_SPACE] / 
    9463           0 :                        (float)((uint64_t)1UL << ts.counts[BGP_STATS_MAXBITLEN]),
    9464           0 :                        VTY_NEWLINE);
    9465           0 :             vty_out (vty, "%30s: ", "/8 equivalent ");
    9466           0 :             vty_out (vty, "%12.2f%s", 
    9467           0 :                      (float)ts.counts[BGP_STATS_SPACE] / 
    9468           0 :                        (float)(1UL << (ts.counts[BGP_STATS_MAXBITLEN] - 8)),
    9469           0 :                      VTY_NEWLINE);
    9470           0 :             if (ts.counts[BGP_STATS_MAXBITLEN] < 25)
    9471           0 :               break;
    9472           0 :             vty_out (vty, "%30s: ", "/24 equivalent ");
    9473           0 :             vty_out (vty, "%12.2f", 
    9474           0 :                      (float)ts.counts[BGP_STATS_SPACE] / 
    9475           0 :                        (float)(1UL << (ts.counts[BGP_STATS_MAXBITLEN] - 24)));
    9476           0 :             break;
    9477             :           default:
    9478           0 :             vty_out (vty, "%-30s: ", table_stats_strs[i]);
    9479           0 :             vty_out (vty, "%12llu", ts.counts[i]);
    9480             :         }
    9481             :         
    9482           0 :       vty_out (vty, "%s", VTY_NEWLINE);
    9483             :     }
    9484           0 :   return CMD_SUCCESS;
    9485             : }
    9486             : 
    9487             : static int
    9488           0 : bgp_table_stats_vty (struct vty *vty, const char *name,
    9489             :                      const char *afi_str, const char *safi_str)
    9490             : {
    9491             :   struct bgp *bgp;
    9492             :   afi_t afi;
    9493             :   safi_t safi;
    9494             :   
    9495           0 :  if (name)
    9496           0 :     bgp = bgp_lookup_by_name (name);
    9497             :   else
    9498           0 :     bgp = bgp_get_default ();
    9499             : 
    9500           0 :   if (!bgp)
    9501             :     {
    9502           0 :       vty_out (vty, "%% No such BGP instance exist%s", VTY_NEWLINE);
    9503           0 :       return CMD_WARNING;
    9504             :     }
    9505           0 :   if (strncmp (afi_str, "ipv", 3) == 0)
    9506             :     {
    9507           0 :       if (strncmp (afi_str, "ipv4", 4) == 0)
    9508           0 :         afi = AFI_IP;
    9509           0 :       else if (strncmp (afi_str, "ipv6", 4) == 0)
    9510           0 :         afi = AFI_IP6;
    9511             :       else
    9512             :         {
    9513           0 :           vty_out (vty, "%% Invalid address family %s%s",
    9514           0 :                    afi_str, VTY_NEWLINE);
    9515           0 :           return CMD_WARNING;
    9516             :         }
    9517           0 :       if (strncmp (safi_str, "m", 1) == 0)
    9518           0 :         safi = SAFI_MULTICAST;
    9519           0 :       else if (strncmp (safi_str, "u", 1) == 0)
    9520           0 :         safi = SAFI_UNICAST;
    9521           0 :       else if (strncmp (safi_str, "vpnv4", 5) == 0 || strncmp (safi_str, "vpnv6", 5) == 0)
    9522           0 :         safi = SAFI_MPLS_LABELED_VPN;
    9523             :       else
    9524             :         {
    9525           0 :           vty_out (vty, "%% Invalid subsequent address family %s%s",
    9526           0 :                    safi_str, VTY_NEWLINE);
    9527           0 :           return CMD_WARNING;
    9528             :         }
    9529             :     }
    9530             :   else
    9531             :     {
    9532           0 :       vty_out (vty, "%% Invalid address family %s%s",
    9533           0 :                afi_str, VTY_NEWLINE);
    9534           0 :       return CMD_WARNING;
    9535             :     }
    9536             : 
    9537           0 :   return bgp_table_stats (vty, bgp, afi, safi);
    9538             : }
    9539             : 
    9540           0 : DEFUN (show_bgp_statistics,
    9541             :        show_bgp_statistics_cmd,
    9542             :        "show bgp (ipv4|ipv6) (unicast|multicast) statistics",
    9543             :        SHOW_STR
    9544             :        BGP_STR
    9545             :        "Address family\n"
    9546             :        "Address family\n"
    9547             :        "Address Family modifier\n"
    9548             :        "Address Family modifier\n"
    9549             :        "BGP RIB advertisement statistics\n")
    9550             : {
    9551           0 :   return bgp_table_stats_vty (vty, NULL, argv[0], argv[1]);
    9552             : }
    9553             : 
    9554             : ALIAS (show_bgp_statistics,
    9555             :        show_bgp_statistics_vpnv4_cmd,
    9556             :        "show bgp (ipv4) (vpnv4) statistics",
    9557             :        SHOW_STR
    9558             :        BGP_STR
    9559             :        "Address family\n"
    9560             :        "Address Family modifier\n"
    9561             :        "BGP RIB advertisement statistics\n")
    9562             : 
    9563           0 : DEFUN (show_bgp_statistics_view,
    9564             :        show_bgp_statistics_view_cmd,
    9565             :        "show bgp view WORD (ipv4|ipv6) (unicast|multicast) statistics",
    9566             :        SHOW_STR
    9567             :        BGP_STR
    9568             :        "BGP view\n"
    9569             :        "Address family\n"
    9570             :        "Address family\n"
    9571             :        "Address Family modifier\n"
    9572             :        "Address Family modifier\n"
    9573             :        "BGP RIB advertisement statistics\n")
    9574             : {
    9575           0 :   return bgp_table_stats_vty (vty, NULL, argv[0], argv[1]);
    9576             : }
    9577             : 
    9578             : ALIAS (show_bgp_statistics_view,
    9579             :        show_bgp_statistics_view_vpnv4_cmd,
    9580             :        "show bgp view WORD (ipv4) (vpnv4) statistics",
    9581             :        SHOW_STR
    9582             :        BGP_STR
    9583             :        "BGP view\n"
    9584             :        "Address family\n"
    9585             :        "Address Family modifier\n"
    9586             :        "BGP RIB advertisement statistics\n")
    9587             : 
    9588             : enum bgp_pcounts
    9589             : {
    9590             :   PCOUNT_ADJ_IN = 0,
    9591             :   PCOUNT_DAMPED,
    9592             :   PCOUNT_REMOVED,
    9593             :   PCOUNT_HISTORY,
    9594             :   PCOUNT_STALE,
    9595             :   PCOUNT_VALID,
    9596             :   PCOUNT_ALL,
    9597             :   PCOUNT_COUNTED,
    9598             :   PCOUNT_PFCNT, /* the figure we display to users */
    9599             :   PCOUNT_MAX,
    9600             : };
    9601             : 
    9602             : static const char *pcount_strs[] =
    9603             : {
    9604             :   [PCOUNT_ADJ_IN]  = "Adj-in",
    9605             :   [PCOUNT_DAMPED]  = "Damped",
    9606             :   [PCOUNT_REMOVED] = "Removed",
    9607             :   [PCOUNT_HISTORY] = "History",
    9608             :   [PCOUNT_STALE]   = "Stale",
    9609             :   [PCOUNT_VALID]   = "Valid",
    9610             :   [PCOUNT_ALL]     = "All RIB",
    9611             :   [PCOUNT_COUNTED] = "PfxCt counted",
    9612             :   [PCOUNT_PFCNT]   = "Useable",
    9613             :   [PCOUNT_MAX]     = NULL,
    9614             : };
    9615             : 
    9616             : struct peer_pcounts
    9617             : {
    9618             :   unsigned int count[PCOUNT_MAX];
    9619             :   const struct peer *peer;
    9620             :   const struct bgp_table *table;
    9621             : };
    9622             : 
    9623             : static int
    9624           0 : bgp_peer_count_walker (struct thread *t)
    9625             : {
    9626             :   struct bgp_node *rn;
    9627           0 :   struct peer_pcounts *pc = THREAD_ARG (t);
    9628           0 :   const struct peer *peer = pc->peer;
    9629             :   
    9630           0 :   for (rn = bgp_table_top (pc->table); rn; rn = bgp_route_next (rn))
    9631             :     {
    9632             :       struct bgp_adj_in *ain;
    9633             :       struct bgp_info *ri;
    9634             :       
    9635           0 :       for (ain = rn->adj_in; ain; ain = ain->next)
    9636           0 :         if (ain->peer == peer)
    9637           0 :           pc->count[PCOUNT_ADJ_IN]++;
    9638             : 
    9639           0 :       for (ri = rn->info; ri; ri = ri->next)
    9640             :         {
    9641             :           char buf[SU_ADDRSTRLEN];
    9642             :           
    9643           0 :           if (ri->peer != peer)
    9644           0 :             continue;
    9645             :           
    9646           0 :           pc->count[PCOUNT_ALL]++;
    9647             :           
    9648           0 :           if (CHECK_FLAG (ri->flags, BGP_INFO_DAMPED))
    9649           0 :             pc->count[PCOUNT_DAMPED]++;
    9650           0 :           if (CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
    9651           0 :             pc->count[PCOUNT_HISTORY]++;
    9652           0 :           if (CHECK_FLAG (ri->flags, BGP_INFO_REMOVED))
    9653           0 :             pc->count[PCOUNT_REMOVED]++;
    9654           0 :           if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
    9655           0 :             pc->count[PCOUNT_STALE]++;
    9656           0 :           if (CHECK_FLAG (ri->flags, BGP_INFO_VALID))
    9657           0 :             pc->count[PCOUNT_VALID]++;
    9658           0 :           if (!CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE))
    9659           0 :             pc->count[PCOUNT_PFCNT]++;
    9660             :           
    9661           0 :           if (CHECK_FLAG (ri->flags, BGP_INFO_COUNTED))
    9662             :             {
    9663           0 :               pc->count[PCOUNT_COUNTED]++;
    9664           0 :               if (CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE))
    9665           0 :                 plog_warn (peer->log,
    9666             :                            "%s [pcount] %s/%d is counted but flags 0x%x",
    9667             :                            peer->host,
    9668           0 :                            inet_ntop(rn->p.family, &rn->p.u.prefix,
    9669             :                                      buf, SU_ADDRSTRLEN),
    9670           0 :                            rn->p.prefixlen,
    9671           0 :                            ri->flags);
    9672             :             }
    9673             :           else
    9674             :             {
    9675           0 :               if (!CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE))
    9676           0 :                 plog_warn (peer->log,
    9677             :                            "%s [pcount] %s/%d not counted but flags 0x%x",
    9678             :                            peer->host,
    9679           0 :                            inet_ntop(rn->p.family, &rn->p.u.prefix,
    9680             :                                      buf, SU_ADDRSTRLEN),
    9681           0 :                            rn->p.prefixlen,
    9682           0 :                            ri->flags);
    9683             :             }
    9684             :         }
    9685             :     }
    9686           0 :   return 0;
    9687             : }
    9688             : 
    9689             : static int
    9690           0 : bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi)
    9691             : {
    9692           0 :   struct peer_pcounts pcounts = { .peer = peer };
    9693             :   unsigned int i;
    9694             :   
    9695           0 :   if (!peer || !peer->bgp || !peer->afc[afi][safi]
    9696           0 :       || !peer->bgp->rib[afi][safi])
    9697             :     {
    9698           0 :       vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
    9699           0 :       return CMD_WARNING;
    9700             :     }
    9701             :   
    9702           0 :   memset (&pcounts, 0, sizeof(pcounts));
    9703           0 :   pcounts.peer = peer;
    9704           0 :   pcounts.table = peer->bgp->rib[afi][safi];
    9705             :   
    9706             :   /* in-place call via thread subsystem so as to record execution time
    9707             :    * stats for the thread-walk (i.e. ensure this can't be blamed on
    9708             :    * on just vty_read()).
    9709             :    */
    9710           0 :   thread_execute (bm->master, bgp_peer_count_walker, &pcounts, 0);
    9711             :   
    9712           0 :   vty_out (vty, "Prefix counts for %s, %s%s", 
    9713           0 :            peer->host, afi_safi_print (afi, safi), VTY_NEWLINE);
    9714           0 :   vty_out (vty, "PfxCt: %ld%s", peer->pcount[afi][safi], VTY_NEWLINE);
    9715           0 :   vty_out (vty, "%sCounts from RIB table walk:%s%s", 
    9716           0 :            VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
    9717             : 
    9718           0 :   for (i = 0; i < PCOUNT_MAX; i++)
    9719           0 :       vty_out (vty, "%20s: %-10d%s",
    9720           0 :                pcount_strs[i], pcounts.count[i], VTY_NEWLINE);
    9721             : 
    9722           0 :   if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi])
    9723             :     {
    9724           0 :       vty_out (vty, "%s [pcount] PfxCt drift!%s",
    9725           0 :                peer->host, VTY_NEWLINE);
    9726           0 :       vty_out (vty, "Please report this bug, with the above command output%s",
    9727           0 :               VTY_NEWLINE);
    9728             :     }
    9729             :                
    9730           0 :   return CMD_SUCCESS;
    9731             : }
    9732             : 
    9733           0 : DEFUN (show_ip_bgp_neighbor_prefix_counts,
    9734             :        show_ip_bgp_neighbor_prefix_counts_cmd,
    9735             :        "show ip bgp neighbors (A.B.C.D|X:X::X:X) prefix-counts",
    9736             :        SHOW_STR
    9737             :        IP_STR
    9738             :        BGP_STR
    9739             :        "Detailed information on TCP and BGP neighbor connections\n"
    9740             :        "Neighbor to display information about\n"
    9741             :        "Neighbor to display information about\n"
    9742             :        "Display detailed prefix count information\n")
    9743             : {
    9744             :   struct peer *peer;
    9745             : 
    9746           0 :   peer = peer_lookup_in_view (vty, NULL, argv[0]);  
    9747           0 :   if (! peer) 
    9748           0 :     return CMD_WARNING;
    9749             :  
    9750           0 :   return bgp_peer_counts (vty, peer, AFI_IP, SAFI_UNICAST);
    9751             : }
    9752             : 
    9753           0 : DEFUN (show_bgp_ipv6_neighbor_prefix_counts,
    9754             :        show_bgp_ipv6_neighbor_prefix_counts_cmd,
    9755             :        "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) prefix-counts",
    9756             :        SHOW_STR
    9757             :        BGP_STR
    9758             :        "Address family\n"
    9759             :        "Detailed information on TCP and BGP neighbor connections\n"
    9760             :        "Neighbor to display information about\n"
    9761             :        "Neighbor to display information about\n"
    9762             :        "Display detailed prefix count information\n")
    9763             : {
    9764             :   struct peer *peer;
    9765             : 
    9766           0 :   peer = peer_lookup_in_view (vty, NULL, argv[0]);  
    9767           0 :   if (! peer) 
    9768           0 :     return CMD_WARNING;
    9769             :  
    9770           0 :   return bgp_peer_counts (vty, peer, AFI_IP6, SAFI_UNICAST);
    9771             : }
    9772             : 
    9773           0 : DEFUN (show_ip_bgp_ipv4_neighbor_prefix_counts,
    9774             :        show_ip_bgp_ipv4_neighbor_prefix_counts_cmd,
    9775             :        "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) prefix-counts",
    9776             :        SHOW_STR
    9777             :        IP_STR
    9778             :        BGP_STR
    9779             :        "Address family\n"
    9780             :        "Address Family modifier\n"
    9781             :        "Address Family modifier\n"
    9782             :        "Detailed information on TCP and BGP neighbor connections\n"
    9783             :        "Neighbor to display information about\n"
    9784             :        "Neighbor to display information about\n"
    9785             :        "Display detailed prefix count information\n")
    9786             : {
    9787             :   struct peer *peer;
    9788             : 
    9789           0 :   peer = peer_lookup_in_view (vty, NULL, argv[1]);
    9790           0 :   if (! peer)
    9791           0 :     return CMD_WARNING;
    9792             : 
    9793           0 :   if (strncmp (argv[0], "m", 1) == 0)
    9794           0 :     return bgp_peer_counts (vty, peer, AFI_IP, SAFI_MULTICAST);
    9795             : 
    9796           0 :   return bgp_peer_counts (vty, peer, AFI_IP, SAFI_UNICAST);
    9797             : }
    9798             : 
    9799           0 : DEFUN (show_ip_bgp_vpnv4_neighbor_prefix_counts,
    9800             :        show_ip_bgp_vpnv4_neighbor_prefix_counts_cmd,
    9801             :        "show ip bgp vpnv4 all neighbors (A.B.C.D|X:X::X:X) prefix-counts",
    9802             :        SHOW_STR
    9803             :        IP_STR
    9804             :        BGP_STR
    9805             :        "Address family\n"
    9806             :        "Address Family modifier\n"
    9807             :        "Address Family modifier\n"
    9808             :        "Detailed information on TCP and BGP neighbor connections\n"
    9809             :        "Neighbor to display information about\n"
    9810             :        "Neighbor to display information about\n"
    9811             :        "Display detailed prefix count information\n")
    9812             : {
    9813             :   struct peer *peer;
    9814             : 
    9815           0 :   peer = peer_lookup_in_view (vty, NULL, argv[0]);
    9816           0 :   if (! peer)
    9817           0 :     return CMD_WARNING;
    9818             :   
    9819           0 :   return bgp_peer_counts (vty, peer, AFI_IP, SAFI_MPLS_VPN);
    9820             : }
    9821             : 
    9822             : 
    9823             : static void
    9824           0 : show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
    9825             :                 int in)
    9826             : {
    9827             :   struct bgp_table *table;
    9828             :   struct bgp_adj_in *ain;
    9829             :   struct bgp_adj_out *adj;
    9830             :   unsigned long output_count;
    9831             :   struct bgp_node *rn;
    9832           0 :   int header1 = 1;
    9833             :   struct bgp *bgp;
    9834           0 :   int header2 = 1;
    9835             : 
    9836           0 :   bgp = peer->bgp;
    9837             : 
    9838           0 :   if (! bgp)
    9839           0 :     return;
    9840             : 
    9841           0 :   table = bgp->rib[afi][safi];
    9842             : 
    9843           0 :   output_count = 0;
    9844             :         
    9845           0 :   if (! in && CHECK_FLAG (peer->af_sflags[afi][safi],
    9846             :                           PEER_STATUS_DEFAULT_ORIGINATE))
    9847             :     {
    9848           0 :       vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
    9849           0 :       vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
    9850           0 :       vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
    9851             : 
    9852           0 :       vty_out (vty, "Originating default network 0.0.0.0%s%s",
    9853           0 :                VTY_NEWLINE, VTY_NEWLINE);
    9854           0 :       header1 = 0;
    9855             :     }
    9856             : 
    9857           0 :   for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
    9858           0 :     if (in)
    9859             :       {
    9860           0 :         for (ain = rn->adj_in; ain; ain = ain->next)
    9861           0 :           if (ain->peer == peer)
    9862             :             {
    9863           0 :               if (header1)
    9864             :                 {
    9865           0 :                   vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
    9866           0 :                   vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
    9867           0 :                   vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
    9868           0 :                   header1 = 0;
    9869             :                 }
    9870           0 :               if (header2)
    9871             :                 {
    9872           0 :                   vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE);
    9873           0 :                   header2 = 0;
    9874             :                 }
    9875           0 :               if (ain->attr)
    9876             :                 { 
    9877           0 :                   route_vty_out_tmp (vty, &rn->p, ain->attr, safi);
    9878           0 :                   output_count++;
    9879             :                 }
    9880             :             }
    9881             :       }
    9882             :     else
    9883             :       {
    9884           0 :         for (adj = rn->adj_out; adj; adj = adj->next)
    9885           0 :           if (adj->peer == peer)
    9886             :             {
    9887           0 :               if (header1)
    9888             :                 {
    9889           0 :                   vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
    9890           0 :                   vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
    9891           0 :                   vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
    9892           0 :                   header1 = 0;
    9893             :                 }
    9894           0 :               if (header2)
    9895             :                 {
    9896           0 :                   vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE);
    9897           0 :                   header2 = 0;
    9898             :                 }
    9899           0 :               if (adj->attr)
    9900             :                 {       
    9901           0 :                   route_vty_out_tmp (vty, &rn->p, adj->attr, safi);
    9902           0 :                   output_count++;
    9903             :                 }
    9904             :             }
    9905             :       }
    9906             :   
    9907           0 :   if (output_count != 0)
    9908           0 :     vty_out (vty, "%sTotal number of prefixes %ld%s",
    9909           0 :              VTY_NEWLINE, output_count, VTY_NEWLINE);
    9910             : }
    9911             : 
    9912             : static int
    9913           0 : peer_adj_routes (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, int in)
    9914             : {    
    9915           0 :   if (! peer || ! peer->afc[afi][safi])
    9916             :     {
    9917           0 :       vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
    9918           0 :       return CMD_WARNING;
    9919             :     }
    9920             : 
    9921           0 :   if (in && ! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
    9922             :     {
    9923           0 :       vty_out (vty, "%% Inbound soft reconfiguration not enabled%s",
    9924           0 :                VTY_NEWLINE);
    9925           0 :       return CMD_WARNING;
    9926             :     }
    9927             : 
    9928           0 :   show_adj_route (vty, peer, afi, safi, in);
    9929             : 
    9930           0 :   return CMD_SUCCESS;
    9931             : }
    9932             : 
    9933           0 : DEFUN (show_ip_bgp_view_neighbor_advertised_route,
    9934             :        show_ip_bgp_view_neighbor_advertised_route_cmd,
    9935             :        "show ip bgp view WORD neighbors (A.B.C.D|X:X::X:X) advertised-routes",
    9936             :        SHOW_STR
    9937             :        IP_STR
    9938             :        BGP_STR
    9939             :        "BGP view\n"
    9940             :        "View name\n"
    9941             :        "Detailed information on TCP and BGP neighbor connections\n"
    9942             :        "Neighbor to display information about\n"
    9943             :        "Neighbor to display information about\n"
    9944             :        "Display the routes advertised to a BGP neighbor\n")
    9945             : {
    9946             :   struct peer *peer;
    9947             : 
    9948           0 :   if (argc == 2)
    9949           0 :     peer = peer_lookup_in_view (vty, argv[0], argv[1]);
    9950             :   else
    9951           0 :     peer = peer_lookup_in_view (vty, NULL, argv[0]);
    9952             : 
    9953           0 :   if (! peer) 
    9954           0 :     return CMD_WARNING;
    9955             :  
    9956           0 :   return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 0);
    9957             : }
    9958             : 
    9959             : ALIAS (show_ip_bgp_view_neighbor_advertised_route,
    9960             :        show_ip_bgp_neighbor_advertised_route_cmd,
    9961             :        "show ip bgp neighbors (A.B.C.D|X:X::X:X) advertised-routes",
    9962             :        SHOW_STR
    9963             :        IP_STR
    9964             :        BGP_STR
    9965             :        "Detailed information on TCP and BGP neighbor connections\n"
    9966             :        "Neighbor to display information about\n"
    9967             :        "Neighbor to display information about\n"
    9968             :        "Display the routes advertised to a BGP neighbor\n")
    9969             : 
    9970           0 : DEFUN (show_ip_bgp_ipv4_neighbor_advertised_route,
    9971             :        show_ip_bgp_ipv4_neighbor_advertised_route_cmd,
    9972             :        "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) advertised-routes",
    9973             :        SHOW_STR
    9974             :        IP_STR
    9975             :        BGP_STR
    9976             :        "Address family\n"
    9977             :        "Address Family modifier\n"
    9978             :        "Address Family modifier\n"
    9979             :        "Detailed information on TCP and BGP neighbor connections\n"
    9980             :        "Neighbor to display information about\n"
    9981             :        "Neighbor to display information about\n"
    9982             :        "Display the routes advertised to a BGP neighbor\n")
    9983             : {
    9984             :   struct peer *peer;
    9985             : 
    9986           0 :   peer = peer_lookup_in_view (vty, NULL, argv[1]);
    9987           0 :   if (! peer)
    9988           0 :     return CMD_WARNING;
    9989             : 
    9990           0 :   if (strncmp (argv[0], "m", 1) == 0)
    9991           0 :     return peer_adj_routes (vty, peer, AFI_IP, SAFI_MULTICAST, 0);
    9992             : 
    9993           0 :   return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 0);
    9994             : }
    9995             : 
    9996             : #ifdef HAVE_IPV6
    9997           0 : DEFUN (show_bgp_view_neighbor_advertised_route,
    9998             :        show_bgp_view_neighbor_advertised_route_cmd,
    9999             :        "show bgp view WORD neighbors (A.B.C.D|X:X::X:X) advertised-routes",
   10000             :        SHOW_STR
   10001             :        BGP_STR
   10002             :        "BGP view\n"
   10003             :        "View name\n"
   10004             :        "Detailed information on TCP and BGP neighbor connections\n"
   10005             :        "Neighbor to display information about\n"
   10006             :        "Neighbor to display information about\n"
   10007             :        "Display the routes advertised to a BGP neighbor\n")
   10008             : {
   10009             :   struct peer *peer;
   10010             : 
   10011           0 :   if (argc == 2)
   10012           0 :     peer = peer_lookup_in_view (vty, argv[0], argv[1]);
   10013             :   else
   10014           0 :     peer = peer_lookup_in_view (vty, NULL, argv[0]);
   10015             : 
   10016           0 :   if (! peer)
   10017           0 :     return CMD_WARNING;    
   10018             : 
   10019           0 :   return peer_adj_routes (vty, peer, AFI_IP6, SAFI_UNICAST, 0);
   10020             : }
   10021             : 
   10022             : ALIAS (show_bgp_view_neighbor_advertised_route,
   10023             :        show_bgp_view_ipv6_neighbor_advertised_route_cmd,
   10024             :        "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X) advertised-routes",
   10025             :        SHOW_STR
   10026             :        BGP_STR
   10027             :        "BGP view\n"
   10028             :        "View name\n"
   10029             :        "Address family\n"
   10030             :        "Detailed information on TCP and BGP neighbor connections\n"
   10031             :        "Neighbor to display information about\n"
   10032             :        "Neighbor to display information about\n"
   10033             :        "Display the routes advertised to a BGP neighbor\n")
   10034             : 
   10035           0 : DEFUN (show_bgp_view_neighbor_received_routes,
   10036             :        show_bgp_view_neighbor_received_routes_cmd,
   10037             :        "show bgp view WORD neighbors (A.B.C.D|X:X::X:X) received-routes",
   10038             :        SHOW_STR
   10039             :        BGP_STR
   10040             :        "BGP view\n"
   10041             :        "View name\n"
   10042             :        "Detailed information on TCP and BGP neighbor connections\n"
   10043             :        "Neighbor to display information about\n"
   10044             :        "Neighbor to display information about\n"
   10045             :        "Display the received routes from neighbor\n")
   10046             : {
   10047             :   struct peer *peer;
   10048             : 
   10049           0 :   if (argc == 2)
   10050           0 :     peer = peer_lookup_in_view (vty, argv[0], argv[1]);
   10051             :   else
   10052           0 :     peer = peer_lookup_in_view (vty, NULL, argv[0]);
   10053             : 
   10054           0 :   if (! peer)
   10055           0 :     return CMD_WARNING;
   10056             : 
   10057           0 :   return peer_adj_routes (vty, peer, AFI_IP6, SAFI_UNICAST, 1);
   10058             : }
   10059             : 
   10060             : ALIAS (show_bgp_view_neighbor_received_routes,
   10061             :        show_bgp_view_ipv6_neighbor_received_routes_cmd,
   10062             :        "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X) received-routes",
   10063             :        SHOW_STR
   10064             :        BGP_STR
   10065             :        "BGP view\n"
   10066             :        "View name\n"
   10067             :        "Address family\n"
   10068             :        "Detailed information on TCP and BGP neighbor connections\n"
   10069             :        "Neighbor to display information about\n"
   10070             :        "Neighbor to display information about\n"
   10071             :        "Display the received routes from neighbor\n")
   10072             : 
   10073             : ALIAS (show_bgp_view_neighbor_advertised_route,
   10074             :        show_bgp_neighbor_advertised_route_cmd,
   10075             :        "show bgp neighbors (A.B.C.D|X:X::X:X) advertised-routes",
   10076             :        SHOW_STR
   10077             :        BGP_STR
   10078             :        "Detailed information on TCP and BGP neighbor connections\n"
   10079             :        "Neighbor to display information about\n"
   10080             :        "Neighbor to display information about\n"
   10081             :        "Display the routes advertised to a BGP neighbor\n")
   10082             :        
   10083             : ALIAS (show_bgp_view_neighbor_advertised_route,
   10084             :        show_bgp_ipv6_neighbor_advertised_route_cmd,
   10085             :        "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) advertised-routes",
   10086             :        SHOW_STR
   10087             :        BGP_STR
   10088             :        "Address family\n"
   10089             :        "Detailed information on TCP and BGP neighbor connections\n"
   10090             :        "Neighbor to display information about\n"
   10091             :        "Neighbor to display information about\n"
   10092             :        "Display the routes advertised to a BGP neighbor\n")
   10093             : 
   10094             : /* old command */
   10095             : ALIAS (show_bgp_view_neighbor_advertised_route,
   10096             :        ipv6_bgp_neighbor_advertised_route_cmd,
   10097             :        "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X) advertised-routes",
   10098             :        SHOW_STR
   10099             :        IPV6_STR
   10100             :        BGP_STR
   10101             :        "Detailed information on TCP and BGP neighbor connections\n"
   10102             :        "Neighbor to display information about\n"
   10103             :        "Neighbor to display information about\n"
   10104             :        "Display the routes advertised to a BGP neighbor\n")
   10105             :   
   10106             : /* old command */
   10107           0 : DEFUN (ipv6_mbgp_neighbor_advertised_route,
   10108             :        ipv6_mbgp_neighbor_advertised_route_cmd,
   10109             :        "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X) advertised-routes",
   10110             :        SHOW_STR
   10111             :        IPV6_STR
   10112             :        MBGP_STR
   10113             :        "Detailed information on TCP and BGP neighbor connections\n"
   10114             :        "Neighbor to display information about\n"
   10115             :        "Neighbor to display information about\n"
   10116             :        "Display the routes advertised to a BGP neighbor\n")
   10117             : {
   10118             :   struct peer *peer;
   10119             : 
   10120           0 :   peer = peer_lookup_in_view (vty, NULL, argv[0]);
   10121           0 :   if (! peer)
   10122           0 :     return CMD_WARNING;  
   10123             : 
   10124           0 :   return peer_adj_routes (vty, peer, AFI_IP6, SAFI_MULTICAST, 0);
   10125             : }
   10126             : #endif /* HAVE_IPV6 */
   10127             : 
   10128           0 : DEFUN (show_ip_bgp_view_neighbor_received_routes,
   10129             :        show_ip_bgp_view_neighbor_received_routes_cmd,
   10130             :        "show ip bgp view WORD neighbors (A.B.C.D|X:X::X:X) received-routes",
   10131             :        SHOW_STR
   10132             :        IP_STR
   10133             :        BGP_STR
   10134             :        "BGP view\n"
   10135             :        "View name\n"
   10136             :        "Detailed information on TCP and BGP neighbor connections\n"
   10137             :        "Neighbor to display information about\n"
   10138             :        "Neighbor to display information about\n"
   10139             :        "Display the received routes from neighbor\n")
   10140             : {
   10141             :   struct peer *peer;
   10142             : 
   10143           0 :   if (argc == 2)
   10144           0 :     peer = peer_lookup_in_view (vty, argv[0], argv[1]);
   10145             :   else
   10146           0 :     peer = peer_lookup_in_view (vty, NULL, argv[0]);
   10147             : 
   10148           0 :   if (! peer)
   10149           0 :     return CMD_WARNING;
   10150             : 
   10151           0 :   return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 1);
   10152             : }
   10153             : 
   10154             : ALIAS (show_ip_bgp_view_neighbor_received_routes,
   10155             :        show_ip_bgp_neighbor_received_routes_cmd,
   10156             :        "show ip bgp neighbors (A.B.C.D|X:X::X:X) received-routes",
   10157             :        SHOW_STR
   10158             :        IP_STR
   10159             :        BGP_STR
   10160             :        "Detailed information on TCP and BGP neighbor connections\n"
   10161             :        "Neighbor to display information about\n"
   10162             :        "Neighbor to display information about\n"
   10163             :        "Display the received routes from neighbor\n")
   10164             : 
   10165           0 : DEFUN (show_ip_bgp_ipv4_neighbor_received_routes,
   10166             :        show_ip_bgp_ipv4_neighbor_received_routes_cmd,
   10167             :        "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) received-routes",
   10168             :        SHOW_STR
   10169             :        IP_STR
   10170             :        BGP_STR
   10171             :        "Address family\n"
   10172             :        "Address Family modifier\n"
   10173             :        "Address Family modifier\n"
   10174             :        "Detailed information on TCP and BGP neighbor connections\n"
   10175             :        "Neighbor to display information about\n"
   10176             :        "Neighbor to display information about\n"
   10177             :        "Display the received routes from neighbor\n")
   10178             : {
   10179             :   struct peer *peer;
   10180             : 
   10181           0 :   peer = peer_lookup_in_view (vty, NULL, argv[1]);
   10182           0 :   if (! peer)
   10183           0 :     return CMD_WARNING;
   10184             :   
   10185           0 :   if (strncmp (argv[0], "m", 1) == 0)
   10186           0 :     return peer_adj_routes (vty, peer, AFI_IP, SAFI_MULTICAST, 1);
   10187             : 
   10188           0 :   return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 1);
   10189             : }
   10190             : 
   10191           0 : DEFUN (show_bgp_view_afi_safi_neighbor_adv_recd_routes,
   10192             :        show_bgp_view_afi_safi_neighbor_adv_recd_routes_cmd,
   10193             : #ifdef HAVE_IPV6
   10194             :        "show bgp view WORD (ipv4|ipv6) (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) (advertised-routes|received-routes)",
   10195             : #else
   10196             :        "show bgp view WORD ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) (advertised-routes|received-routes)",
   10197             : #endif
   10198             :        SHOW_STR
   10199             :        BGP_STR
   10200             :        "BGP view\n"
   10201             :        "View name\n"
   10202             :        "Address family\n"
   10203             : #ifdef HAVE_IPV6
   10204             :        "Address family\n"
   10205             : #endif
   10206             :        "Address family modifier\n"
   10207             :        "Address family modifier\n"
   10208             :        "Detailed information on TCP and BGP neighbor connections\n"
   10209             :        "Neighbor to display information about\n"
   10210             :        "Neighbor to display information about\n"
   10211             :        "Display the advertised routes to neighbor\n"
   10212             :        "Display the received routes from neighbor\n")
   10213             : {
   10214             :   int afi;
   10215             :   int safi;
   10216             :   int in;
   10217             :   struct peer *peer;
   10218             : 
   10219             : #ifdef HAVE_IPV6
   10220           0 :     peer = peer_lookup_in_view (vty, argv[0], argv[3]);
   10221             : #else
   10222             :     peer = peer_lookup_in_view (vty, argv[0], argv[2]);
   10223             : #endif
   10224             : 
   10225           0 :   if (! peer)
   10226           0 :     return CMD_WARNING;
   10227             : 
   10228             : #ifdef HAVE_IPV6
   10229           0 :   afi = (strncmp (argv[1], "ipv6", 4) == 0) ? AFI_IP6 : AFI_IP;
   10230           0 :   safi = (strncmp (argv[2], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
   10231           0 :   in = (strncmp (argv[4], "r", 1) == 0) ? 1 : 0;
   10232             : #else
   10233             :   afi = AFI_IP;
   10234             :   safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
   10235             :   in = (strncmp (argv[3], "r", 1) == 0) ? 1 : 0;
   10236             : #endif
   10237             : 
   10238           0 :   return peer_adj_routes (vty, peer, afi, safi, in);
   10239             : }
   10240             : 
   10241           0 : DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
   10242             :        show_ip_bgp_neighbor_received_prefix_filter_cmd,
   10243             :        "show ip bgp neighbors (A.B.C.D|X:X::X:X) received prefix-filter",
   10244             :        SHOW_STR
   10245             :        IP_STR
   10246             :        BGP_STR
   10247             :        "Detailed information on TCP and BGP neighbor connections\n"
   10248             :        "Neighbor to display information about\n"
   10249             :        "Neighbor to display information about\n"
   10250             :        "Display information received from a BGP neighbor\n"
   10251             :        "Display the prefixlist filter\n")
   10252             : {
   10253             :   char name[BUFSIZ];
   10254             :   union sockunion su;
   10255             :   struct peer *peer;
   10256             :   int count, ret;
   10257             : 
   10258           0 :   ret = str2sockunion (argv[0], &su);
   10259           0 :   if (ret < 0)
   10260             :     {
   10261           0 :       vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
   10262           0 :       return CMD_WARNING;
   10263             :     }
   10264             : 
   10265           0 :   peer = peer_lookup (NULL, &su);
   10266           0 :   if (! peer)
   10267           0 :     return CMD_WARNING;
   10268             : 
   10269           0 :   sprintf (name, "%s.%d.%d", peer->host, AFI_IP, SAFI_UNICAST);
   10270           0 :   count =  prefix_bgp_show_prefix_list (NULL, AFI_IP, name);
   10271           0 :   if (count)
   10272             :     {
   10273           0 :       vty_out (vty, "Address family: IPv4 Unicast%s", VTY_NEWLINE);
   10274           0 :       prefix_bgp_show_prefix_list (vty, AFI_IP, name);
   10275             :     }
   10276             : 
   10277           0 :   return CMD_SUCCESS;
   10278             : }
   10279             : 
   10280           0 : DEFUN (show_ip_bgp_ipv4_neighbor_received_prefix_filter,
   10281             :        show_ip_bgp_ipv4_neighbor_received_prefix_filter_cmd,
   10282             :        "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) received prefix-filter",
   10283             :        SHOW_STR
   10284             :        IP_STR
   10285             :        BGP_STR
   10286             :        "Address family\n"
   10287             :        "Address Family modifier\n"
   10288             :        "Address Family modifier\n"
   10289             :        "Detailed information on TCP and BGP neighbor connections\n"
   10290             :        "Neighbor to display information about\n"
   10291             :        "Neighbor to display information about\n"
   10292             :        "Display information received from a BGP neighbor\n"
   10293             :        "Display the prefixlist filter\n")
   10294             : {
   10295             :   char name[BUFSIZ];
   10296             :   union sockunion su;
   10297             :   struct peer *peer;
   10298             :   int count, ret;
   10299             : 
   10300           0 :   ret = str2sockunion (argv[1], &su);
   10301           0 :   if (ret < 0)
   10302             :     {
   10303           0 :       vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE);
   10304           0 :       return CMD_WARNING;
   10305             :     }
   10306             : 
   10307           0 :   peer = peer_lookup (NULL, &su);
   10308           0 :   if (! peer)
   10309           0 :     return CMD_WARNING;
   10310             : 
   10311           0 :   if (strncmp (argv[0], "m", 1) == 0)
   10312             :     {
   10313           0 :       sprintf (name, "%s.%d.%d", peer->host, AFI_IP, SAFI_MULTICAST);
   10314           0 :       count =  prefix_bgp_show_prefix_list (NULL, AFI_IP, name);
   10315           0 :       if (count)
   10316             :         {
   10317           0 :           vty_out (vty, "Address family: IPv4 Multicast%s", VTY_NEWLINE);
   10318           0 :           prefix_bgp_show_prefix_list (vty, AFI_IP, name);
   10319             :         }
   10320             :     }
   10321             :   else 
   10322             :     {
   10323           0 :       sprintf (name, "%s.%d.%d", peer->host, AFI_IP, SAFI_UNICAST);
   10324           0 :       count =  prefix_bgp_show_prefix_list (NULL, AFI_IP, name);
   10325           0 :       if (count)
   10326             :         {
   10327           0 :           vty_out (vty, "Address family: IPv4 Unicast%s", VTY_NEWLINE);
   10328           0 :           prefix_bgp_show_prefix_list (vty, AFI_IP, name);
   10329             :         }
   10330             :     }
   10331             : 
   10332           0 :   return CMD_SUCCESS;
   10333             : }
   10334             : 
   10335             : 
   10336             : #ifdef HAVE_IPV6
   10337             : ALIAS (show_bgp_view_neighbor_received_routes,
   10338             :        show_bgp_neighbor_received_routes_cmd,
   10339             :        "show bgp neighbors (A.B.C.D|X:X::X:X) received-routes",
   10340             :        SHOW_STR
   10341             :        BGP_STR
   10342             :        "Detailed information on TCP and BGP neighbor connections\n"
   10343             :        "Neighbor to display information about\n"
   10344             :        "Neighbor to display information about\n"
   10345             :        "Display the received routes from neighbor\n")
   10346             : 
   10347             : ALIAS (show_bgp_view_neighbor_received_routes,
   10348             :        show_bgp_ipv6_neighbor_received_routes_cmd,
   10349             :        "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) received-routes",
   10350             :        SHOW_STR
   10351             :        BGP_STR
   10352             :        "Address family\n"
   10353             :        "Detailed information on TCP and BGP neighbor connections\n"
   10354             :        "Neighbor to display information about\n"
   10355             :        "Neighbor to display information about\n"
   10356             :        "Display the received routes from neighbor\n")
   10357             : 
   10358           0 : DEFUN (show_bgp_neighbor_received_prefix_filter,
   10359             :        show_bgp_neighbor_received_prefix_filter_cmd,
   10360             :        "show bgp neighbors (A.B.C.D|X:X::X:X) received prefix-filter",
   10361             :        SHOW_STR
   10362             :        BGP_STR
   10363             :        "Detailed information on TCP and BGP neighbor connections\n"
   10364             :        "Neighbor to display information about\n"
   10365             :        "Neighbor to display information about\n"
   10366             :        "Display information received from a BGP neighbor\n"
   10367             :        "Display the prefixlist filter\n")
   10368             : {
   10369             :   char name[BUFSIZ];
   10370             :   union sockunion su;
   10371             :   struct peer *peer;
   10372             :   int count, ret;
   10373             : 
   10374           0 :   ret = str2sockunion (argv[0], &su);
   10375           0 :   if (ret < 0)
   10376             :     {
   10377           0 :       vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
   10378           0 :       return CMD_WARNING;
   10379             :     }
   10380             : 
   10381           0 :   peer = peer_lookup (NULL, &su);
   10382           0 :   if (! peer)
   10383           0 :     return CMD_WARNING;
   10384             : 
   10385           0 :   sprintf (name, "%s.%d.%d", peer->host, AFI_IP6, SAFI_UNICAST);
   10386           0 :   count =  prefix_bgp_show_prefix_list (NULL, AFI_IP6, name);
   10387           0 :   if (count)
   10388             :     {
   10389           0 :       vty_out (vty, "Address family: IPv6 Unicast%s", VTY_NEWLINE);
   10390           0 :       prefix_bgp_show_prefix_list (vty, AFI_IP6, name);
   10391             :     }
   10392             : 
   10393           0 :   return CMD_SUCCESS;
   10394             : }
   10395             : 
   10396             : ALIAS (show_bgp_neighbor_received_prefix_filter,
   10397             :        show_bgp_ipv6_neighbor_received_prefix_filter_cmd,
   10398             :        "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) received prefix-filter",
   10399             :        SHOW_STR
   10400             :        BGP_STR
   10401             :        "Address family\n"
   10402             :        "Detailed information on TCP and BGP neighbor connections\n"
   10403             :        "Neighbor to display information about\n"
   10404             :        "Neighbor to display information about\n"
   10405             :        "Display information received from a BGP neighbor\n"
   10406             :        "Display the prefixlist filter\n")
   10407             : 
   10408             : /* old command */
   10409             : ALIAS (show_bgp_view_neighbor_received_routes,
   10410             :        ipv6_bgp_neighbor_received_routes_cmd,
   10411             :        "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X) received-routes",
   10412             :        SHOW_STR
   10413             :        IPV6_STR
   10414             :        BGP_STR
   10415             :        "Detailed information on TCP and BGP neighbor connections\n"
   10416             :        "Neighbor to display information about\n"
   10417             :        "Neighbor to display information about\n"
   10418             :        "Display the received routes from neighbor\n")
   10419             : 
   10420             : /* old command */
   10421           0 : DEFUN (ipv6_mbgp_neighbor_received_routes,
   10422             :        ipv6_mbgp_neighbor_received_routes_cmd,
   10423             :        "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X) received-routes",
   10424             :        SHOW_STR
   10425             :        IPV6_STR
   10426             :        MBGP_STR
   10427             :        "Detailed information on TCP and BGP neighbor connections\n"
   10428             :        "Neighbor to display information about\n"
   10429             :        "Neighbor to display information about\n"
   10430             :        "Display the received routes from neighbor\n")
   10431             : {
   10432             :   struct peer *peer;
   10433             : 
   10434           0 :   peer = peer_lookup_in_view (vty, NULL, argv[0]);
   10435           0 :   if (! peer)
   10436           0 :     return CMD_WARNING;
   10437             : 
   10438           0 :   return peer_adj_routes (vty, peer, AFI_IP6, SAFI_MULTICAST, 1);
   10439             : }
   10440             : 
   10441           0 : DEFUN (show_bgp_view_neighbor_received_prefix_filter,
   10442             :        show_bgp_view_neighbor_received_prefix_filter_cmd,
   10443             :        "show bgp view WORD neighbors (A.B.C.D|X:X::X:X) received prefix-filter",
   10444             :        SHOW_STR
   10445             :        BGP_STR
   10446             :        "BGP view\n"
   10447             :        "View name\n"
   10448             :        "Detailed information on TCP and BGP neighbor connections\n"
   10449             :        "Neighbor to display information about\n"
   10450             :        "Neighbor to display information about\n"
   10451             :        "Display information received from a BGP neighbor\n"
   10452             :        "Display the prefixlist filter\n")
   10453             : {
   10454             :   char name[BUFSIZ];
   10455             :   union sockunion su;
   10456             :   struct peer *peer;
   10457             :   struct bgp *bgp;
   10458             :   int count, ret;
   10459             : 
   10460             :   /* BGP structure lookup. */
   10461           0 :   bgp = bgp_lookup_by_name (argv[0]);
   10462           0 :   if (bgp == NULL)
   10463             :   {  
   10464           0 :           vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE);
   10465           0 :           return CMD_WARNING;
   10466             :         }
   10467             :   
   10468           0 :   ret = str2sockunion (argv[1], &su);
   10469           0 :   if (ret < 0)
   10470             :     {
   10471           0 :       vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE);
   10472           0 :       return CMD_WARNING;
   10473             :     }
   10474             : 
   10475           0 :   peer = peer_lookup (bgp, &su);
   10476           0 :   if (! peer)
   10477           0 :     return CMD_WARNING;
   10478             : 
   10479           0 :   sprintf (name, "%s.%d.%d", peer->host, AFI_IP6, SAFI_UNICAST);
   10480           0 :   count =  prefix_bgp_show_prefix_list (NULL, AFI_IP6, name);
   10481           0 :   if (count)
   10482             :     {
   10483           0 :       vty_out (vty, "Address family: IPv6 Unicast%s", VTY_NEWLINE);
   10484           0 :       prefix_bgp_show_prefix_list (vty, AFI_IP6, name);
   10485             :     }
   10486             : 
   10487           0 :   return CMD_SUCCESS;
   10488             : }
   10489             : 
   10490             : ALIAS (show_bgp_view_neighbor_received_prefix_filter,
   10491             :        show_bgp_view_ipv6_neighbor_received_prefix_filter_cmd,
   10492             :        "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X) received prefix-filter",
   10493             :        SHOW_STR
   10494             :        BGP_STR
   10495             :        "BGP view\n"
   10496             :        "View name\n"
   10497             :        "Address family\n"
   10498             :        "Detailed information on TCP and BGP neighbor connections\n"
   10499             :        "Neighbor to display information about\n"
   10500             :        "Neighbor to display information about\n"
   10501             :        "Display information received from a BGP neighbor\n"
   10502             :        "Display the prefixlist filter\n")
   10503             : #endif /* HAVE_IPV6 */
   10504             : 
   10505             : static int
   10506           0 : bgp_show_neighbor_route (struct vty *vty, struct peer *peer, afi_t afi,
   10507             :                          safi_t safi, enum bgp_show_type type)
   10508             : {
   10509           0 :   if (! peer || ! peer->afc[afi][safi])
   10510             :     {
   10511           0 :       vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
   10512           0 :       return CMD_WARNING;
   10513             :     }
   10514             :  
   10515           0 :   return bgp_show (vty, peer->bgp, afi, safi, type, &peer->su);
   10516             : }
   10517             : 
   10518           0 : DEFUN (show_ip_bgp_neighbor_routes,
   10519             :        show_ip_bgp_neighbor_routes_cmd,
   10520             :        "show ip bgp neighbors (A.B.C.D|X:X::X:X) routes",
   10521             :        SHOW_STR
   10522             :        IP_STR
   10523             :        BGP_STR
   10524             :        "Detailed information on TCP and BGP neighbor connections\n"
   10525             :        "Neighbor to display information about\n"
   10526             :        "Neighbor to display information about\n"
   10527             :        "Display routes learned from neighbor\n")
   10528             : {
   10529             :   struct peer *peer;
   10530             : 
   10531           0 :   peer = peer_lookup_in_view (vty, NULL, argv[0]);
   10532           0 :   if (! peer)
   10533           0 :     return CMD_WARNING;
   10534             :     
   10535           0 :   return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_UNICAST,
   10536             :                                   bgp_show_type_neighbor);
   10537             : }
   10538             : 
   10539           0 : DEFUN (show_ip_bgp_neighbor_flap,
   10540             :        show_ip_bgp_neighbor_flap_cmd,
   10541             :        "show ip bgp neighbors (A.B.C.D|X:X::X:X) flap-statistics",
   10542             :        SHOW_STR
   10543             :        IP_STR
   10544             :        BGP_STR
   10545             :        "Detailed information on TCP and BGP neighbor connections\n"
   10546             :        "Neighbor to display information about\n"
   10547             :        "Neighbor to display information about\n"
   10548             :        "Display flap statistics of the routes learned from neighbor\n")
   10549             : {
   10550             :   struct peer *peer;
   10551             : 
   10552           0 :   peer = peer_lookup_in_view (vty, NULL, argv[0]);
   10553           0 :   if (! peer)
   10554           0 :     return CMD_WARNING;
   10555             :     
   10556           0 :   return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_UNICAST,
   10557             :                                   bgp_show_type_flap_neighbor);
   10558             : }
   10559             : 
   10560           0 : DEFUN (show_ip_bgp_neighbor_damp,
   10561             :        show_ip_bgp_neighbor_damp_cmd,
   10562             :        "show ip bgp neighbors (A.B.C.D|X:X::X:X) dampened-routes",
   10563             :        SHOW_STR
   10564             :        IP_STR
   10565             :        BGP_STR
   10566             :        "Detailed information on TCP and BGP neighbor connections\n"
   10567             :        "Neighbor to display information about\n"
   10568             :        "Neighbor to display information about\n"
   10569             :        "Display the dampened routes received from neighbor\n")
   10570             : {
   10571             :   struct peer *peer;
   10572             : 
   10573           0 :   peer = peer_lookup_in_view (vty, NULL, argv[0]);
   10574           0 :   if (! peer)
   10575           0 :     return CMD_WARNING;
   10576             :     
   10577           0 :   return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_UNICAST,
   10578             :                                   bgp_show_type_damp_neighbor);
   10579             : }
   10580             : 
   10581           0 : DEFUN (show_ip_bgp_ipv4_neighbor_routes,
   10582             :        show_ip_bgp_ipv4_neighbor_routes_cmd,
   10583             :        "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) routes",
   10584             :        SHOW_STR
   10585             :        IP_STR
   10586             :        BGP_STR
   10587             :        "Address family\n"
   10588             :        "Address Family modifier\n"
   10589             :        "Address Family modifier\n"
   10590             :        "Detailed information on TCP and BGP neighbor connections\n"
   10591             :        "Neighbor to display information about\n"
   10592             :        "Neighbor to display information about\n"
   10593             :        "Display routes learned from neighbor\n")
   10594             : {
   10595             :   struct peer *peer;
   10596             : 
   10597           0 :   peer = peer_lookup_in_view (vty, NULL, argv[1]);
   10598           0 :   if (! peer)
   10599           0 :     return CMD_WARNING;
   10600             :  
   10601           0 :   if (strncmp (argv[0], "m", 1) == 0)
   10602           0 :     return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_MULTICAST,
   10603             :                                     bgp_show_type_neighbor);
   10604             : 
   10605           0 :   return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_UNICAST,
   10606             :                                   bgp_show_type_neighbor);
   10607             : }
   10608             : 
   10609           0 : DEFUN (show_ip_bgp_view_rsclient,
   10610             :        show_ip_bgp_view_rsclient_cmd,
   10611             :        "show ip bgp view WORD rsclient (A.B.C.D|X:X::X:X)",
   10612             :        SHOW_STR
   10613             :        IP_STR
   10614             :        BGP_STR
   10615             :        "BGP view\n"
   10616             :        "View name\n"
   10617             :        "Information about Route Server Client\n"
   10618             :        NEIGHBOR_ADDR_STR)
   10619             : {
   10620             :   struct bgp_table *table;
   10621             :   struct peer *peer;
   10622             : 
   10623           0 :   if (argc == 2)
   10624           0 :     peer = peer_lookup_in_view (vty, argv[0], argv[1]);
   10625             :   else
   10626           0 :     peer = peer_lookup_in_view (vty, NULL, argv[0]);
   10627             : 
   10628           0 :   if (! peer)
   10629           0 :     return CMD_WARNING;
   10630             : 
   10631           0 :   if (! peer->afc[AFI_IP][SAFI_UNICAST])
   10632             :     {
   10633           0 :       vty_out (vty, "%% Activate the neighbor for the address family first%s",
   10634           0 :             VTY_NEWLINE);
   10635           0 :       return CMD_WARNING;
   10636             :     }
   10637             : 
   10638           0 :   if ( ! CHECK_FLAG (peer->af_flags[AFI_IP][SAFI_UNICAST],
   10639             :               PEER_FLAG_RSERVER_CLIENT))
   10640             :     {
   10641           0 :       vty_out (vty, "%% Neighbor is not a Route-Server client%s",
   10642           0 :             VTY_NEWLINE);
   10643           0 :       return CMD_WARNING;
   10644             :     }
   10645             : 
   10646           0 :   table = peer->rib[AFI_IP][SAFI_UNICAST];
   10647             : 
   10648           0 :   return bgp_show_table (vty, table, &peer->remote_id, bgp_show_type_normal, NULL);
   10649             : }
   10650             : 
   10651             : ALIAS (show_ip_bgp_view_rsclient,
   10652             :        show_ip_bgp_rsclient_cmd,
   10653             :        "show ip bgp rsclient (A.B.C.D|X:X::X:X)",
   10654             :        SHOW_STR
   10655             :        IP_STR
   10656             :        BGP_STR
   10657             :        "Information about Route Server Client\n"
   10658             :        NEIGHBOR_ADDR_STR)
   10659             : 
   10660           0 : DEFUN (show_bgp_view_ipv4_safi_rsclient,
   10661             :        show_bgp_view_ipv4_safi_rsclient_cmd,
   10662             :        "show bgp view WORD ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X)",
   10663             :        SHOW_STR
   10664             :        BGP_STR
   10665             :        "BGP view\n"
   10666             :        "View name\n"
   10667             :        "Address family\n"
   10668             :        "Address Family modifier\n"
   10669             :        "Address Family modifier\n"
   10670             :        "Information about Route Server Client\n"
   10671             :        NEIGHBOR_ADDR_STR)
   10672             : {
   10673             :   struct bgp_table *table;
   10674             :   struct peer *peer;
   10675             :   safi_t safi;
   10676             : 
   10677           0 :   if (argc == 3) {
   10678           0 :     peer = peer_lookup_in_view (vty, argv[0], argv[2]);
   10679           0 :     safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
   10680             :   } else {
   10681           0 :     peer = peer_lookup_in_view (vty, NULL, argv[1]);
   10682           0 :     safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST;
   10683             :   }
   10684             : 
   10685           0 :   if (! peer)
   10686           0 :     return CMD_WARNING;
   10687             : 
   10688           0 :   if (! peer->afc[AFI_IP][safi])
   10689             :     {
   10690           0 :       vty_out (vty, "%% Activate the neighbor for the address family first%s",
   10691           0 :             VTY_NEWLINE);
   10692           0 :       return CMD_WARNING;
   10693             :     }
   10694             : 
   10695           0 :   if ( ! CHECK_FLAG (peer->af_flags[AFI_IP][safi],
   10696             :               PEER_FLAG_RSERVER_CLIENT))
   10697             :     {
   10698           0 :       vty_out (vty, "%% Neighbor is not a Route-Server client%s",
   10699           0 :             VTY_NEWLINE);
   10700           0 :       return CMD_WARNING;
   10701             :     }
   10702             : 
   10703           0 :   table = peer->rib[AFI_IP][safi];
   10704             : 
   10705           0 :   return bgp_show_table (vty, table, &peer->remote_id, bgp_show_type_normal, NULL);
   10706             : }
   10707             : 
   10708             : ALIAS (show_bgp_view_ipv4_safi_rsclient,
   10709             :        show_bgp_ipv4_safi_rsclient_cmd,
   10710             :        "show bgp ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X)",
   10711             :        SHOW_STR
   10712             :        BGP_STR
   10713             :        "Address family\n"
   10714             :        "Address Family modifier\n"
   10715             :        "Address Family modifier\n"
   10716             :        "Information about Route Server Client\n"
   10717             :        NEIGHBOR_ADDR_STR)
   10718             : 
   10719           0 : DEFUN (show_ip_bgp_view_rsclient_route,
   10720             :        show_ip_bgp_view_rsclient_route_cmd,
   10721             :        "show ip bgp view WORD rsclient (A.B.C.D|X:X::X:X) A.B.C.D",
   10722             :        SHOW_STR
   10723             :        IP_STR
   10724             :        BGP_STR
   10725             :        "BGP view\n"
   10726             :        "View name\n"
   10727             :        "Information about Route Server Client\n"
   10728             :        NEIGHBOR_ADDR_STR
   10729             :        "Network in the BGP routing table to display\n")
   10730             : {
   10731             :   struct bgp *bgp;
   10732             :   struct peer *peer;
   10733             : 
   10734             :   /* BGP structure lookup. */
   10735           0 :   if (argc == 3)
   10736             :     {
   10737           0 :       bgp = bgp_lookup_by_name (argv[0]);
   10738           0 :       if (bgp == NULL)
   10739             :         {
   10740           0 :           vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE);
   10741           0 :           return CMD_WARNING;
   10742             :         }
   10743             :     }
   10744             :   else
   10745             :     {
   10746           0 :       bgp = bgp_get_default ();
   10747           0 :       if (bgp == NULL)
   10748             :         {
   10749           0 :           vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
   10750           0 :           return CMD_WARNING;
   10751             :         }
   10752             :     }
   10753             : 
   10754           0 :   if (argc == 3)
   10755           0 :     peer = peer_lookup_in_view (vty, argv[0], argv[1]);
   10756             :   else
   10757           0 :     peer = peer_lookup_in_view (vty, NULL, argv[0]);
   10758             : 
   10759           0 :   if (! peer)
   10760           0 :     return CMD_WARNING;
   10761             : 
   10762           0 :   if (! peer->afc[AFI_IP][SAFI_UNICAST])
   10763             :     {
   10764           0 :       vty_out (vty, "%% Activate the neighbor for the address family first%s",
   10765           0 :             VTY_NEWLINE);
   10766           0 :       return CMD_WARNING;
   10767             : }
   10768             : 
   10769           0 :   if ( ! CHECK_FLAG (peer->af_flags[AFI_IP][SAFI_UNICAST],
   10770             :               PEER_FLAG_RSERVER_CLIENT))
   10771             :     {
   10772           0 :       vty_out (vty, "%% Neighbor is not a Route-Server client%s",
   10773           0 :             VTY_NEWLINE);
   10774           0 :       return CMD_WARNING;
   10775             :     }
   10776             :  
   10777           0 :   return bgp_show_route_in_table (vty, bgp, peer->rib[AFI_IP][SAFI_UNICAST], 
   10778             :                                   (argc == 3) ? argv[2] : argv[1],
   10779             :                                   AFI_IP, SAFI_UNICAST, NULL, 0);
   10780             : }
   10781             : 
   10782             : ALIAS (show_ip_bgp_view_rsclient_route,
   10783             :        show_ip_bgp_rsclient_route_cmd,
   10784             :        "show ip bgp rsclient (A.B.C.D|X:X::X:X) A.B.C.D",
   10785             :        SHOW_STR
   10786             :        IP_STR
   10787             :        BGP_STR
   10788             :        "Information about Route Server Client\n"
   10789             :        NEIGHBOR_ADDR_STR
   10790             :        "Network in the BGP routing table to display\n")
   10791             : 
   10792           0 : DEFUN (show_bgp_view_ipv4_safi_rsclient_route,
   10793             :        show_bgp_view_ipv4_safi_rsclient_route_cmd,
   10794             :        "show bgp view WORD ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) A.B.C.D",
   10795             :        SHOW_STR
   10796             :        BGP_STR
   10797             :        "BGP view\n"
   10798             :        "View name\n"
   10799             :        "Address family\n"
   10800             :        "Address Family modifier\n"
   10801             :        "Address Family modifier\n"
   10802             :        "Information about Route Server Client\n"
   10803             :        NEIGHBOR_ADDR_STR
   10804             :        "Network in the BGP routing table to display\n")
   10805             : {
   10806             :   struct bgp *bgp;
   10807             :   struct peer *peer;
   10808             :   safi_t safi;
   10809             : 
   10810             :   /* BGP structure lookup. */
   10811           0 :   if (argc == 4)
   10812             :     {
   10813           0 :       bgp = bgp_lookup_by_name (argv[0]);
   10814           0 :       if (bgp == NULL)
   10815             :         {
   10816           0 :           vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE);
   10817           0 :           return CMD_WARNING;
   10818             :         }
   10819             :     }
   10820             :   else
   10821             :     {
   10822           0 :       bgp = bgp_get_default ();
   10823           0 :       if (bgp == NULL)
   10824             :         {
   10825           0 :           vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
   10826 </