bgp_route.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:275k
源码类别:

网络

开发平台:

Unix_Linux

  1.     SET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED);
  2.     match++;
  3.   }
  4. /* as-set aggregate route generate origin, as path,
  5.    community aggregation.  */
  6. if (aggregate->as_set)
  7.   {
  8.     if (origin < ri->attr->origin)
  9.       origin = ri->attr->origin;
  10.     if (aspath)
  11.       {
  12. asmerge = aspath_aggregate (aspath, ri->attr->aspath);
  13. aspath_free (aspath);
  14. aspath = asmerge;
  15.       }
  16.     else
  17.       aspath = aspath_dup (ri->attr->aspath);
  18.     if (ri->attr->community)
  19.       {
  20. if (community)
  21.   {
  22.     commerge = community_merge (community,
  23. ri->attr->community);
  24.     community = community_uniq_sort (commerge);
  25.     community_free (commerge);
  26.   }
  27. else
  28.   community = community_dup (ri->attr->community);
  29.       }
  30.   }
  31. aggregate->count++;
  32.       }
  33.   }
  34. /* If this node is suppressed, process the change. */
  35. if (match)
  36.   bgp_process (bgp, rn, afi, safi);
  37.       }
  38.   bgp_unlock_node (top);
  39.   /* Add aggregate route to BGP table. */
  40.   if (aggregate->count)
  41.     {
  42.       rn = bgp_node_get (table, p);
  43.       new = bgp_info_new ();
  44.       new->type = ZEBRA_ROUTE_BGP;
  45.       new->sub_type = BGP_ROUTE_AGGREGATE;
  46.       new->peer = bgp->peer_self;
  47.       SET_FLAG (new->flags, BGP_INFO_VALID);
  48.       new->attr = bgp_attr_aggregate_intern (bgp, origin, aspath, community, aggregate->as_set);
  49.       new->uptime = time (NULL);
  50.       bgp_info_add (rn, new);
  51.       /* Process change. */
  52.       bgp_process (bgp, rn, afi, safi);
  53.     }
  54. }
  55. void
  56. bgp_aggregate_delete (struct bgp *bgp, struct prefix *p, afi_t afi, 
  57.       safi_t safi, struct bgp_aggregate *aggregate)
  58. {
  59.   struct bgp_table *table;
  60.   struct bgp_node *top;
  61.   struct bgp_node *rn;
  62.   struct bgp_info *ri;
  63.   unsigned long match;
  64.   table = bgp->rib[afi][safi];
  65.   if (afi == AFI_IP && p->prefixlen == IPV4_MAX_BITLEN)
  66.     return;
  67.   if (afi == AFI_IP6 && p->prefixlen == IPV6_MAX_BITLEN)
  68.     return;
  69.   /* If routes exists below this node, generate aggregate routes. */
  70.   top = bgp_node_get (table, p);
  71.   for (rn = bgp_node_get (table, p); rn; rn = bgp_route_next_until (rn, top))
  72.     if (rn->p.prefixlen > p->prefixlen)
  73.       {
  74. match = 0;
  75. for (ri = rn->info; ri; ri = ri->next)
  76.   {
  77.     if (BGP_INFO_HOLDDOWN (ri))
  78.       continue;
  79.     if (ri->sub_type != BGP_ROUTE_AGGREGATE)
  80.       {
  81. if (aggregate->summary_only)
  82.   {
  83.     ri->suppress--;
  84.     if (ri->suppress == 0)
  85.       {
  86. SET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED);
  87. match++;
  88.       }
  89.   }
  90. aggregate->count--;
  91.       }
  92.   }
  93. /* If this node is suppressed, process the change. */
  94. if (match)
  95.   bgp_process (bgp, rn, afi, safi);
  96.       }
  97.   bgp_unlock_node (top);
  98.   /* Delete aggregate route from BGP table. */
  99.   rn = bgp_node_get (table, p);
  100.   for (ri = rn->info; ri; ri = ri->next)
  101.     if (ri->peer == bgp->peer_self 
  102. && ri->type == ZEBRA_ROUTE_BGP
  103. && ri->sub_type == BGP_ROUTE_AGGREGATE)
  104.       break;
  105.   /* Withdraw static BGP route from routing table. */
  106.   if (ri)
  107.     {
  108.       UNSET_FLAG (ri->flags, BGP_INFO_VALID);
  109.       bgp_process (bgp, rn, afi, safi);
  110.       bgp_info_delete (rn, ri);
  111.       bgp_info_free (ri);
  112.       bgp_unlock_node (rn);
  113.     }
  114.   /* Unlock bgp_node_lookup. */
  115.   bgp_unlock_node (rn);
  116. }
  117. /* Aggregate route attribute. */
  118. #define AGGREGATE_SUMMARY_ONLY 1
  119. #define AGGREGATE_AS_SET       1
  120. int
  121. bgp_aggregate_set (struct vty *vty, char *prefix_str, afi_t afi, safi_t safi,
  122.    u_char summary_only, u_char as_set)
  123. {
  124.   int ret;
  125.   struct prefix p;
  126.   struct bgp_node *rn;
  127.   struct bgp *bgp;
  128.   struct bgp_aggregate *aggregate;
  129.   /* Convert string to prefix structure. */
  130.   ret = str2prefix (prefix_str, &p);
  131.   if (!ret)
  132.     {
  133.       vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
  134.       return CMD_WARNING;
  135.     }
  136.   apply_mask (&p);
  137.   /* Get BGP structure. */
  138.   bgp = vty->index;
  139.   /* Old configuration check. */
  140.   rn = bgp_node_get (bgp->aggregate[afi][safi], &p);
  141.   if (rn->info)
  142.     {
  143.       vty_out (vty, "There is already same aggregate network.%s", VTY_NEWLINE);
  144.       bgp_unlock_node (rn);
  145.       return CMD_WARNING;
  146.     }
  147.   /* Make aggregate address structure. */
  148.   aggregate = bgp_aggregate_new ();
  149.   aggregate->summary_only = summary_only;
  150.   aggregate->as_set = as_set;
  151.   aggregate->safi = safi;
  152.   rn->info = aggregate;
  153.   /* Aggregate address insert into BGP routing table. */
  154.   if (safi & SAFI_UNICAST)
  155.     bgp_aggregate_add (bgp, &p, afi, SAFI_UNICAST, aggregate);
  156.   if (safi & SAFI_MULTICAST)
  157.     bgp_aggregate_add (bgp, &p, afi, SAFI_MULTICAST, aggregate);
  158.   return CMD_SUCCESS;
  159. }
  160. int
  161. bgp_aggregate_unset (struct vty *vty, char *prefix_str, afi_t afi, safi_t safi)
  162. {
  163.   int ret;
  164.   struct prefix p;
  165.   struct bgp_node *rn;
  166.   struct bgp *bgp;
  167.   struct bgp_aggregate *aggregate;
  168.   /* Convert string to prefix structure. */
  169.   ret = str2prefix (prefix_str, &p);
  170.   if (!ret)
  171.     {
  172.       vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
  173.       return CMD_WARNING;
  174.     }
  175.   apply_mask (&p);
  176.   /* Get BGP structure. */
  177.   bgp = vty->index;
  178.   /* Old configuration check. */
  179.   rn = bgp_node_lookup (bgp->aggregate[afi][safi], &p);
  180.   if (! rn)
  181.     {
  182.       vty_out (vty, "%% There is no aggregate-address configuration.%s",
  183.        VTY_NEWLINE);
  184.       return CMD_WARNING;
  185.     }
  186.   aggregate = rn->info;
  187.   if (aggregate->safi & SAFI_UNICAST)
  188.     bgp_aggregate_delete (bgp, &p, afi, SAFI_UNICAST, aggregate);
  189.   if (aggregate->safi & SAFI_MULTICAST)
  190.     bgp_aggregate_delete (bgp, &p, afi, SAFI_MULTICAST, aggregate);
  191.   /* Unlock aggregate address configuration. */
  192.   rn->info = NULL;
  193.   bgp_aggregate_free (aggregate);
  194.   bgp_unlock_node (rn);
  195.   bgp_unlock_node (rn);
  196.   return CMD_SUCCESS;
  197. }
  198. DEFUN (aggregate_address,
  199.        aggregate_address_cmd,
  200.        "aggregate-address A.B.C.D/M",
  201.        "Configure BGP aggregate entriesn"
  202.        "Aggregate prefixn")
  203. {
  204.   return bgp_aggregate_set (vty, argv[0], AFI_IP, bgp_node_safi (vty), 0, 0);
  205. }
  206. DEFUN (aggregate_address_mask,
  207.        aggregate_address_mask_cmd,
  208.        "aggregate-address A.B.C.D A.B.C.D",
  209.        "Configure BGP aggregate entriesn"
  210.        "Aggregate addressn"
  211.        "Aggregate maskn")
  212. {
  213.   int ret;
  214.   char prefix_str[BUFSIZ];
  215.   ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
  216.   if (! ret)
  217.     {
  218.       vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
  219.       return CMD_WARNING;
  220.     }
  221.   return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty),
  222.     0, 0);
  223. }
  224. DEFUN (aggregate_address_summary_only,
  225.        aggregate_address_summary_only_cmd,
  226.        "aggregate-address A.B.C.D/M summary-only",
  227.        "Configure BGP aggregate entriesn"
  228.        "Aggregate prefixn"
  229.        "Filter more specific routes from updatesn")
  230. {
  231.   return bgp_aggregate_set (vty, argv[0], AFI_IP, bgp_node_safi (vty),
  232.     AGGREGATE_SUMMARY_ONLY, 0);
  233. }
  234. DEFUN (aggregate_address_mask_summary_only,
  235.        aggregate_address_mask_summary_only_cmd,
  236.        "aggregate-address A.B.C.D A.B.C.D summary-only",
  237.        "Configure BGP aggregate entriesn"
  238.        "Aggregate addressn"
  239.        "Aggregate maskn"
  240.        "Filter more specific routes from updatesn")
  241. {
  242.   int ret;
  243.   char prefix_str[BUFSIZ];
  244.   ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
  245.   if (! ret)
  246.     {
  247.       vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
  248.       return CMD_WARNING;
  249.     }
  250.   return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty),
  251.     AGGREGATE_SUMMARY_ONLY, 0);
  252. }
  253. DEFUN (aggregate_address_as_set,
  254.        aggregate_address_as_set_cmd,
  255.        "aggregate-address A.B.C.D/M as-set",
  256.        "Configure BGP aggregate entriesn"
  257.        "Aggregate prefixn"
  258.        "Generate AS set path informationn")
  259. {
  260.   return bgp_aggregate_set (vty, argv[0], AFI_IP, bgp_node_safi (vty),
  261.     0, AGGREGATE_AS_SET);
  262. }
  263. DEFUN (aggregate_address_mask_as_set,
  264.        aggregate_address_mask_as_set_cmd,
  265.        "aggregate-address A.B.C.D A.B.C.D as-set",
  266.        "Configure BGP aggregate entriesn"
  267.        "Aggregate addressn"
  268.        "Aggregate maskn"
  269.        "Generate AS set path informationn")
  270. {
  271.   int ret;
  272.   char prefix_str[BUFSIZ];
  273.   ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
  274.   if (! ret)
  275.     {
  276.       vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
  277.       return CMD_WARNING;
  278.     }
  279.   return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty),
  280.     0, AGGREGATE_AS_SET);
  281. }
  282. DEFUN (aggregate_address_as_set_summary,
  283.        aggregate_address_as_set_summary_cmd,
  284.        "aggregate-address A.B.C.D/M as-set summary-only",
  285.        "Configure BGP aggregate entriesn"
  286.        "Aggregate prefixn"
  287.        "Generate AS set path informationn"
  288.        "Filter more specific routes from updatesn")
  289. {
  290.   return bgp_aggregate_set (vty, argv[0], AFI_IP, bgp_node_safi (vty),
  291.     AGGREGATE_SUMMARY_ONLY, AGGREGATE_AS_SET);
  292. }
  293. ALIAS (aggregate_address_as_set_summary,
  294.        aggregate_address_summary_as_set_cmd,
  295.        "aggregate-address A.B.C.D/M summary-only as-set",
  296.        "Configure BGP aggregate entriesn"
  297.        "Aggregate prefixn"
  298.        "Filter more specific routes from updatesn"
  299.        "Generate AS set path informationn");
  300. DEFUN (aggregate_address_mask_as_set_summary,
  301.        aggregate_address_mask_as_set_summary_cmd,
  302.        "aggregate-address A.B.C.D A.B.C.D as-set summary-only",
  303.        "Configure BGP aggregate entriesn"
  304.        "Aggregate addressn"
  305.        "Aggregate maskn"
  306.        "Generate AS set path informationn"
  307.        "Filter more specific routes from updatesn")
  308. {
  309.   int ret;
  310.   char prefix_str[BUFSIZ];
  311.   ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
  312.   if (! ret)
  313.     {
  314.       vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
  315.       return CMD_WARNING;
  316.     }
  317.   return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty),
  318.     AGGREGATE_SUMMARY_ONLY, AGGREGATE_AS_SET);
  319. }
  320. ALIAS (aggregate_address_mask_as_set_summary,
  321.        aggregate_address_mask_summary_as_set_cmd,
  322.        "aggregate-address A.B.C.D A.B.C.D summary-only as-set",
  323.        "Configure BGP aggregate entriesn"
  324.        "Aggregate addressn"
  325.        "Aggregate maskn"
  326.        "Filter more specific routes from updatesn"
  327.        "Generate AS set path informationn");
  328. DEFUN (no_aggregate_address,
  329.        no_aggregate_address_cmd,
  330.        "no aggregate-address A.B.C.D/M",
  331.        NO_STR
  332.        "Configure BGP aggregate entriesn"
  333.        "Aggregate prefixn")
  334. {
  335.   return bgp_aggregate_unset (vty, argv[0], AFI_IP, bgp_node_safi (vty));
  336. }
  337. ALIAS (no_aggregate_address,
  338.        no_aggregate_address_summary_only_cmd,
  339.        "no aggregate-address A.B.C.D/M summary-only",
  340.        NO_STR
  341.        "Configure BGP aggregate entriesn"
  342.        "Aggregate prefixn"
  343.        "Filter more specific routes from updatesn");
  344. ALIAS (no_aggregate_address,
  345.        no_aggregate_address_as_set_cmd,
  346.        "no aggregate-address A.B.C.D/M as-set",
  347.        NO_STR
  348.        "Configure BGP aggregate entriesn"
  349.        "Aggregate prefixn"
  350.        "Generate AS set path informationn");
  351. ALIAS (no_aggregate_address,
  352.        no_aggregate_address_as_set_summary_cmd,
  353.        "no aggregate-address A.B.C.D/M as-set summary-only",
  354.        NO_STR
  355.        "Configure BGP aggregate entriesn"
  356.        "Aggregate prefixn"
  357.        "Generate AS set path informationn"
  358.        "Filter more specific routes from updatesn");
  359. ALIAS (no_aggregate_address,
  360.        no_aggregate_address_summary_as_set_cmd,
  361.        "no aggregate-address A.B.C.D/M summary-only as-set",
  362.        NO_STR
  363.        "Configure BGP aggregate entriesn"
  364.        "Aggregate prefixn"
  365.        "Filter more specific routes from updatesn"
  366.        "Generate AS set path informationn");
  367. DEFUN (no_aggregate_address_mask,
  368.        no_aggregate_address_mask_cmd,
  369.        "no aggregate-address A.B.C.D A.B.C.D",
  370.        NO_STR
  371.        "Configure BGP aggregate entriesn"
  372.        "Aggregate addressn"
  373.        "Aggregate maskn")
  374. {
  375.   int ret;
  376.   char prefix_str[BUFSIZ];
  377.   ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
  378.   if (! ret)
  379.     {
  380.       vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
  381.       return CMD_WARNING;
  382.     }
  383.   return bgp_aggregate_unset (vty, prefix_str, AFI_IP, bgp_node_safi (vty));
  384. }
  385. ALIAS (no_aggregate_address_mask,
  386.        no_aggregate_address_mask_summary_only_cmd,
  387.        "no aggregate-address A.B.C.D A.B.C.D summary-only",
  388.        NO_STR
  389.        "Configure BGP aggregate entriesn"
  390.        "Aggregate addressn"
  391.        "Aggregate maskn"
  392.        "Filter more specific routes from updatesn");
  393. ALIAS (no_aggregate_address_mask,
  394.        no_aggregate_address_mask_as_set_cmd,
  395.        "no aggregate-address A.B.C.D A.B.C.D as-set",
  396.        NO_STR
  397.        "Configure BGP aggregate entriesn"
  398.        "Aggregate addressn"
  399.        "Aggregate maskn"
  400.        "Generate AS set path informationn");
  401. ALIAS (no_aggregate_address_mask,
  402.        no_aggregate_address_mask_as_set_summary_cmd,
  403.        "no aggregate-address A.B.C.D A.B.C.D as-set summary-only",
  404.        NO_STR
  405.        "Configure BGP aggregate entriesn"
  406.        "Aggregate addressn"
  407.        "Aggregate maskn"
  408.        "Generate AS set path informationn"
  409.        "Filter more specific routes from updatesn");
  410. ALIAS (no_aggregate_address_mask,
  411.        no_aggregate_address_mask_summary_as_set_cmd,
  412.        "no aggregate-address A.B.C.D A.B.C.D summary-only as-set",
  413.        NO_STR
  414.        "Configure BGP aggregate entriesn"
  415.        "Aggregate addressn"
  416.        "Aggregate maskn"
  417.        "Filter more specific routes from updatesn"
  418.        "Generate AS set path informationn");
  419. #ifdef HAVE_IPV6
  420. DEFUN (ipv6_aggregate_address,
  421.        ipv6_aggregate_address_cmd,
  422.        "aggregate-address X:X::X:X/M",
  423.        "Configure BGP aggregate entriesn"
  424.        "Aggregate prefixn")
  425. {
  426.   return bgp_aggregate_set (vty, argv[0], AFI_IP6, SAFI_UNICAST, 0, 0);
  427. }
  428. DEFUN (ipv6_aggregate_address_summary_only,
  429.        ipv6_aggregate_address_summary_only_cmd,
  430.        "aggregate-address X:X::X:X/M summary-only",
  431.        "Configure BGP aggregate entriesn"
  432.        "Aggregate prefixn"
  433.        "Filter more specific routes from updatesn")
  434. {
  435.   return bgp_aggregate_set (vty, argv[0], AFI_IP6, SAFI_UNICAST, 
  436.     AGGREGATE_SUMMARY_ONLY, 0);
  437. }
  438. DEFUN (no_ipv6_aggregate_address,
  439.        no_ipv6_aggregate_address_cmd,
  440.        "no aggregate-address X:X::X:X/M",
  441.        NO_STR
  442.        "Configure BGP aggregate entriesn"
  443.        "Aggregate prefixn")
  444. {
  445.   return bgp_aggregate_unset (vty, argv[0], AFI_IP6, SAFI_UNICAST);
  446. }
  447. DEFUN (no_ipv6_aggregate_address_summary_only,
  448.        no_ipv6_aggregate_address_summary_only_cmd,
  449.        "no aggregate-address X:X::X:X/M summary-only",
  450.        NO_STR
  451.        "Configure BGP aggregate entriesn"
  452.        "Aggregate prefixn"
  453.        "Filter more specific routes from updatesn")
  454. {
  455.   return bgp_aggregate_unset (vty, argv[0], AFI_IP6, SAFI_UNICAST);
  456. }
  457. ALIAS (ipv6_aggregate_address,
  458.        old_ipv6_aggregate_address_cmd,
  459.        "ipv6 bgp aggregate-address X:X::X:X/M",
  460.        IPV6_STR
  461.        BGP_STR
  462.        "Configure BGP aggregate entriesn"
  463.        "Aggregate prefixn");
  464. ALIAS (ipv6_aggregate_address_summary_only,
  465.        old_ipv6_aggregate_address_summary_only_cmd,
  466.        "ipv6 bgp aggregate-address X:X::X:X/M summary-only",
  467.        IPV6_STR
  468.        BGP_STR
  469.        "Configure BGP aggregate entriesn"
  470.        "Aggregate prefixn"
  471.        "Filter more specific routes from updatesn");
  472. ALIAS (no_ipv6_aggregate_address,
  473.        old_no_ipv6_aggregate_address_cmd,
  474.        "no ipv6 bgp aggregate-address X:X::X:X/M",
  475.        NO_STR
  476.        IPV6_STR
  477.        BGP_STR
  478.        "Configure BGP aggregate entriesn"
  479.        "Aggregate prefixn");
  480. ALIAS (no_ipv6_aggregate_address_summary_only,
  481.        old_no_ipv6_aggregate_address_summary_only_cmd,
  482.        "no ipv6 bgp aggregate-address X:X::X:X/M summary-only",
  483.        NO_STR
  484.        IPV6_STR
  485.        BGP_STR
  486.        "Configure BGP aggregate entriesn"
  487.        "Aggregate prefixn"
  488.        "Filter more specific routes from updatesn");
  489. #endif /* HAVE_IPV6 */
  490. /* Redistribute route treatment. */
  491. void
  492. bgp_redistribute_add (struct prefix *p, struct in_addr *nexthop,
  493.       u_int32_t metric, u_char type)
  494. {
  495.   struct bgp *bgp;
  496.   struct listnode *nn;
  497.   struct bgp_info *new;
  498.   struct bgp_info *bi;
  499.   struct bgp_info info;
  500.   struct bgp_node *bn;
  501.   struct attr attr;
  502.   struct attr attr_new;
  503.   struct attr *new_attr;
  504.   afi_t afi;
  505.   int ret;
  506.   /* Make default attribute. */
  507.   bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE);
  508.   if (nexthop)
  509.     attr.nexthop = *nexthop;
  510.   attr.med = metric;
  511.   attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
  512.   LIST_LOOP (bm->bgp, bgp, nn)
  513.     {
  514.       afi = family2afi (p->family);
  515.       if (bgp->redist[afi][type])
  516. {
  517.   /* Copy attribute for modification. */
  518.   attr_new = attr;
  519.   if (bgp->redist_metric_flag[afi][type])
  520.     attr_new.med = bgp->redist_metric[afi][type];
  521.   /* Apply route-map. */
  522.   if (bgp->rmap[afi][type].map)
  523.     {
  524.       info.peer = bgp->peer_self;
  525.       info.attr = &attr_new;
  526.       ret = route_map_apply (bgp->rmap[afi][type].map, p, RMAP_BGP,
  527.      &info);
  528.       if (ret == RMAP_DENYMATCH)
  529. {
  530.   /* Free uninterned attribute. */
  531.   bgp_attr_flush (&attr_new);
  532.   /* Unintern original. */
  533.   aspath_unintern (attr.aspath);
  534.   bgp_redistribute_delete (p, type);
  535.   return;
  536. }
  537.     }
  538.   bn = bgp_afi_node_get (bgp, afi, SAFI_UNICAST, p, NULL);
  539.   new_attr = bgp_attr_intern (&attr_new);
  540.  
  541.     for (bi = bn->info; bi; bi = bi->next)
  542.       if (bi->peer == bgp->peer_self
  543.   && bi->sub_type == BGP_ROUTE_REDISTRIBUTE)
  544.         break;
  545.  
  546.     if (bi)
  547.       {
  548.         if (attrhash_cmp (bi->attr, new_attr))
  549.   {
  550.     bgp_attr_unintern (new_attr);
  551.     aspath_unintern (attr.aspath);
  552.     bgp_unlock_node (bn);
  553.     return;
  554.   }
  555.         else
  556.   {
  557.     /* The attribute is changed. */
  558.     SET_FLAG (bi->flags, BGP_INFO_ATTR_CHANGED);
  559.  
  560.     /* Rewrite BGP route information. */
  561.     bgp_aggregate_decrement (bgp, p, bi, afi, SAFI_UNICAST);
  562.     bgp_attr_unintern (bi->attr);
  563.     bi->attr = new_attr;
  564.     bi->uptime = time (NULL);
  565.  
  566.     /* Process change. */
  567.     bgp_aggregate_increment (bgp, p, bi, afi, SAFI_UNICAST);
  568.     bgp_process (bgp, bn, afi, SAFI_UNICAST);
  569.     bgp_unlock_node (bn);
  570.     aspath_unintern (attr.aspath);
  571.     return;
  572.   } 
  573.       }
  574.   new = bgp_info_new ();
  575.   new->type = type;
  576.   new->sub_type = BGP_ROUTE_REDISTRIBUTE;
  577.   new->peer = bgp->peer_self;
  578.   SET_FLAG (new->flags, BGP_INFO_VALID);
  579.   new->attr = new_attr;
  580.   new->uptime = time (NULL);
  581.   bgp_aggregate_increment (bgp, p, new, afi, SAFI_UNICAST);
  582.   bgp_info_add (bn, new);
  583.   bgp_process (bgp, bn, afi, SAFI_UNICAST);
  584. }
  585.     }
  586.   /* Unintern original. */
  587.   aspath_unintern (attr.aspath);
  588. }
  589. void
  590. bgp_redistribute_delete (struct prefix *p, u_char type)
  591. {
  592.   struct bgp *bgp;
  593.   struct listnode *nn;
  594.   afi_t afi;
  595.   struct bgp_node *rn;
  596.   struct bgp_info *ri;
  597.   LIST_LOOP (bm->bgp, bgp, nn)
  598.     {
  599.       afi = family2afi (p->family);
  600.       if (bgp->redist[afi][type])
  601. {
  602.   rn = bgp_afi_node_get (bgp, afi, SAFI_UNICAST, p, NULL);
  603.   for (ri = rn->info; ri; ri = ri->next)
  604.     if (ri->peer == bgp->peer_self
  605. && ri->type == type)
  606.       break;
  607.   if (ri)
  608.     {
  609.       bgp_aggregate_decrement (bgp, p, ri, afi, SAFI_UNICAST);
  610.       UNSET_FLAG (ri->flags, BGP_INFO_VALID);
  611.       bgp_process (bgp, rn, afi, SAFI_UNICAST);
  612.       bgp_info_delete (rn, ri);
  613.       bgp_info_free (ri);
  614.       bgp_unlock_node (rn);
  615.     }
  616.   bgp_unlock_node (rn);
  617. }
  618.     }
  619. }
  620. /* Withdraw specified route type's route. */
  621. void
  622. bgp_redistribute_withdraw (struct bgp *bgp, afi_t afi, int type)
  623. {
  624.   struct bgp_node *rn;
  625.   struct bgp_info *ri;
  626.   struct bgp_table *table;
  627.   table = bgp->rib[afi][SAFI_UNICAST];
  628.   for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
  629.     {
  630.       for (ri = rn->info; ri; ri = ri->next)
  631. if (ri->peer == bgp->peer_self
  632.     && ri->type == type)
  633.   break;
  634.       if (ri)
  635. {
  636.   bgp_aggregate_decrement (bgp, &rn->p, ri, afi, SAFI_UNICAST);
  637.   UNSET_FLAG (ri->flags, BGP_INFO_VALID);
  638.   bgp_process (bgp, rn, afi, SAFI_UNICAST);
  639.   bgp_info_delete (rn, ri);
  640.   bgp_info_free (ri);
  641.   bgp_unlock_node (rn);
  642. }
  643.     }
  644. }
  645. /* Static function to display route. */
  646. static int
  647. route_vty_out_route (struct prefix *p, struct vty *vty)
  648. {
  649.   int len;
  650.   u_int32_t destination; 
  651.   char buf[BUFSIZ];
  652.   if (p->family == AF_INET)
  653.     {
  654.       len = vty_out (vty, "%s", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ));
  655.       destination = ntohl (p->u.prefix4.s_addr);
  656.       if ((IN_CLASSC (destination) && p->prefixlen == 24)
  657.   || (IN_CLASSB (destination) && p->prefixlen == 16)
  658.   || (IN_CLASSA (destination) && p->prefixlen == 8)
  659.   || p->u.prefix4.s_addr == 0)
  660. {
  661.   /* When mask is natural, mask is not displayed. */
  662. }
  663.       else
  664. len += vty_out (vty, "/%d", p->prefixlen);
  665.     }
  666.   else
  667.     len = vty_out (vty, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
  668.    p->prefixlen);
  669.   len = 17 - len;
  670.   if (len < 1)
  671.     vty_out (vty, "%s%*s", VTY_NEWLINE, 20, " ");
  672.   else
  673.     vty_out (vty, "%*s", len, " ");
  674.   /* return 1 if it added extra newline */
  675.   if (len < 1)
  676.     return 1;
  677.   else
  678.     return 0;
  679. }
  680. /* Calculate line number of output data. */
  681. int
  682. vty_calc_line (struct vty *vty, unsigned long length)
  683. {
  684.   return vty->width ? (((vty->obuf->length - length) / vty->width) + 1) : 1;
  685. }
  686. enum bgp_display_type
  687. {
  688.   normal_list,
  689. };
  690. /* called from terminal list command */
  691. int
  692. route_vty_out (struct vty *vty, struct prefix *p,
  693.        struct bgp_info *binfo, int display, safi_t safi)
  694. {
  695.   struct attr *attr;
  696.   unsigned long length = 0;
  697.   int extra_line = 0;
  698.   length = vty->obuf->length;
  699.   /* Route status display. */
  700.   if (CHECK_FLAG (binfo->flags, BGP_INFO_STALE))
  701.     vty_out (vty, "S");
  702.   else if (binfo->suppress)
  703.     vty_out (vty, "s");
  704.   else if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
  705.     vty_out (vty, "*");
  706.   else
  707.     vty_out (vty, " ");
  708.   /* Selected */
  709.   if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
  710.     vty_out (vty, "h");
  711.   else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
  712.     vty_out (vty, "d");
  713.   else if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
  714.     vty_out (vty, ">");
  715.   else
  716.     vty_out (vty, " ");
  717.   /* Internal route. */
  718.     if ((binfo->peer->as) && (binfo->peer->as == binfo->peer->local_as))
  719.       vty_out (vty, "i");
  720.     else
  721.       vty_out (vty, " ");
  722.   
  723.   /* print prefix and mask */
  724.   if (! display)
  725.     extra_line += route_vty_out_route (p, vty);
  726.   else
  727.     vty_out (vty, "%*s", 17, " ");
  728.   /* Print attribute */
  729.   attr = binfo->attr;
  730.   if (attr) 
  731.     {
  732.       if (p->family == AF_INET)
  733. {
  734.   if (safi == SAFI_MPLS_VPN)
  735.     vty_out (vty, "%-16s", inet_ntoa (attr->mp_nexthop_global_in));
  736.   else
  737.     vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
  738. }
  739. #ifdef HAVE_IPV6      
  740.       else if (p->family == AF_INET6)
  741. {
  742.   int len;
  743.   char buf[BUFSIZ];
  744.   len = vty_out (vty, "%s", 
  745.  inet_ntop (AF_INET6, &attr->mp_nexthop_global, buf, BUFSIZ));
  746.   len = 16 - len;
  747.   if (len < 1)
  748.             {
  749.       vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " ");
  750.               extra_line++; /* Adjust More mode for newline above */
  751.             }
  752.   else
  753.     vty_out (vty, "%*s", len, " ");
  754. }
  755. #endif /* HAVE_IPV6 */
  756.       if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
  757. vty_out (vty, "%10u", attr->med);
  758.       else
  759. vty_out (vty, "          ");
  760.       if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
  761. vty_out (vty, "%7u", attr->local_pref);
  762.       else
  763. vty_out (vty, "       ");
  764.       vty_out (vty, "%7d ",attr->weight);
  765.     
  766.     /* Print aspath */
  767.     if (attr->aspath)
  768.       aspath_print_vty (vty, attr->aspath);
  769.     /* Print origin */
  770.     if (strlen (attr->aspath->str) == 0)
  771.       vty_out (vty, "%s", bgp_origin_str[attr->origin]);
  772.     else
  773.       vty_out (vty, " %s", bgp_origin_str[attr->origin]);
  774.   }
  775.   vty_out (vty, "%s", VTY_NEWLINE);
  776.   return vty_calc_line (vty, length) + extra_line;
  777. }  
  778. /* called from terminal list command */
  779. void
  780. route_vty_out_tmp (struct vty *vty, struct prefix *p,
  781.    struct attr *attr, safi_t safi)
  782. {
  783.   /* Route status display. */
  784.   vty_out (vty, "*");
  785.   vty_out (vty, ">");
  786.   vty_out (vty, " ");
  787.   /* print prefix and mask */
  788.   route_vty_out_route (p, vty);
  789.   /* Print attribute */
  790.   if (attr) 
  791.     {
  792.       if (p->family == AF_INET)
  793. {
  794.   if (safi == SAFI_MPLS_VPN)
  795.     vty_out (vty, "%-16s", inet_ntoa (attr->mp_nexthop_global_in));
  796.   else
  797.     vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
  798. }
  799. #ifdef HAVE_IPV6
  800.       else if (p->family == AF_INET6)
  801.         {
  802.           int len;
  803.           char buf[BUFSIZ];
  804.           len = vty_out (vty, "%s",
  805.                          inet_ntop (AF_INET6, &attr->mp_nexthop_global, buf, BUFSIZ));
  806.           len = 16 - len;
  807.           if (len < 1)
  808.             vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " ");
  809.           else
  810.             vty_out (vty, "%*s", len, " ");
  811.         }
  812. #endif /* HAVE_IPV6 */
  813.       if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
  814. vty_out (vty, "%10u", attr->med);
  815.       else
  816. vty_out (vty, "          ");
  817.       if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
  818. vty_out (vty, "%7u", attr->local_pref);
  819.       else
  820. vty_out (vty, "       ");
  821.       vty_out (vty, "%7d ",attr->weight);
  822.     
  823.     /* Print aspath */
  824.     if (attr->aspath)
  825.       aspath_print_vty (vty, attr->aspath);
  826.     /* Print origin */
  827.     if (strlen (attr->aspath->str) == 0)
  828.       vty_out (vty, "%s", bgp_origin_str[attr->origin]);
  829.     else
  830.       vty_out (vty, " %s", bgp_origin_str[attr->origin]);
  831.   }
  832.   vty_out (vty, "%s", VTY_NEWLINE);
  833. }  
  834. int
  835. route_vty_out_tag (struct vty *vty, struct prefix *p,
  836.    struct bgp_info *binfo, int display, safi_t safi)
  837. {
  838.   struct attr *attr;
  839.   unsigned long length = 0;
  840.   u_int32_t label = 0;
  841.   int extra_line = 0;
  842.   length = vty->obuf->length;
  843.   /* Route status display. */
  844.   if (binfo->suppress)
  845.     vty_out (vty, "s");
  846.   else if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
  847.     vty_out (vty, "*");
  848.   else
  849.     vty_out (vty, " ");
  850.   /* Selected */
  851.   if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
  852.     vty_out (vty, "h");
  853.   else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
  854.     vty_out (vty, "d");
  855.   else if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
  856.     vty_out (vty, ">");
  857.   else
  858.     vty_out (vty, " ");
  859.   /* Internal route. */
  860.     if ((binfo->peer->as) && (binfo->peer->as == binfo->peer->local_as))
  861.       vty_out (vty, "i");
  862.     else
  863.       vty_out (vty, " ");
  864.   /* print prefix and mask */
  865.   if (! display)
  866.     extra_line += route_vty_out_route (p, vty);
  867.   else
  868.     vty_out (vty, "%*s", 17, " ");
  869.   /* Print attribute */
  870.   attr = binfo->attr;
  871.   if (attr) 
  872.     {
  873.       if (p->family == AF_INET)
  874. {
  875.   if (safi == SAFI_MPLS_VPN)
  876.     vty_out (vty, "%-16s", inet_ntoa (attr->mp_nexthop_global_in));
  877.   else
  878.     vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
  879. }
  880. #ifdef HAVE_IPV6      
  881.       else if (p->family == AF_INET6)
  882. {
  883.   char buf[BUFSIZ];
  884.   char buf1[BUFSIZ];
  885.   if (attr->mp_nexthop_len == 16)
  886.     vty_out (vty, "%s", 
  887.      inet_ntop (AF_INET6, &attr->mp_nexthop_global, buf, BUFSIZ));
  888.   else if (attr->mp_nexthop_len == 32)
  889.     vty_out (vty, "%s(%s)",
  890.      inet_ntop (AF_INET6, &attr->mp_nexthop_global, buf, BUFSIZ),
  891.      inet_ntop (AF_INET6, &attr->mp_nexthop_local, buf1, BUFSIZ));
  892.   
  893. }
  894. #endif /* HAVE_IPV6 */
  895.     }
  896.   label = decode_label (binfo->tag);
  897.   vty_out (vty, "notag/%d", label);
  898.   vty_out (vty, "%s", VTY_NEWLINE);
  899.   return vty_calc_line (vty, length) + extra_line;
  900. }  
  901. /* dampening route */
  902. int
  903. damp_route_vty_out (struct vty *vty, struct prefix *p,
  904.     struct bgp_info *binfo, int display, safi_t safi)
  905. {
  906.   struct attr *attr;
  907.   unsigned long length = 0;
  908.   int len;
  909.   int extra_line = 0;
  910.   length = vty->obuf->length;
  911.   /* Route status display. */
  912.   if (binfo->suppress)
  913.     vty_out (vty, "s");
  914.   else if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
  915.     vty_out (vty, "*");
  916.   else
  917.     vty_out (vty, " ");
  918.   /* Selected */
  919.   if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
  920.     vty_out (vty, "h");
  921.   else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
  922.     vty_out (vty, "d");
  923.   else if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
  924.     vty_out (vty, ">");
  925.   else
  926.     vty_out (vty, " ");
  927.   vty_out (vty, " ");
  928.   /* print prefix and mask */
  929.   if (! display)
  930.     extra_line += route_vty_out_route (p, vty);
  931.   else
  932.     vty_out (vty, "%*s", 17, " ");
  933.   len = vty_out (vty, "%s", binfo->peer->host);
  934.   len = 17 - len;
  935.   if (len < 1)
  936.     {
  937.       vty_out (vty, "%s%*s", VTY_NEWLINE, 34, " ");
  938.       extra_line++;
  939.     }
  940.   else
  941.     vty_out (vty, "%*s", len, " ");
  942.   vty_out (vty, "%s ", bgp_damp_reuse_time_vty (vty, binfo));
  943.   /* Print attribute */
  944.   attr = binfo->attr;
  945.   if (attr)
  946.     {
  947.       /* Print aspath */
  948.       if (attr->aspath)
  949. aspath_print_vty (vty, attr->aspath);
  950.       /* Print origin */
  951.       if (strlen (attr->aspath->str) == 0)
  952. vty_out (vty, "%s", bgp_origin_str[attr->origin]);
  953.       else
  954. vty_out (vty, " %s", bgp_origin_str[attr->origin]);
  955.     }
  956.   vty_out (vty, "%s", VTY_NEWLINE);
  957.   return vty_calc_line (vty, length) + extra_line;
  958. }
  959. #define BGP_UPTIME_LEN 25
  960. /* flap route */
  961. int
  962. flap_route_vty_out (struct vty *vty, struct prefix *p,
  963.     struct bgp_info *binfo, int display, safi_t safi)
  964. {
  965.   struct attr *attr;
  966.   struct bgp_damp_info *bdi;
  967.   unsigned long length = 0;
  968.   char timebuf[BGP_UPTIME_LEN];
  969.   int len;
  970.   int extra_line = 0;
  971.   length = vty->obuf->length;
  972.   bdi = binfo->damp_info;
  973.   /* Route status display. */
  974.   if (binfo->suppress)
  975.     vty_out (vty, "s");
  976.   else if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
  977.     vty_out (vty, "*");
  978.   else
  979.     vty_out (vty, " ");
  980.   /* Selected */
  981.   if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
  982.     vty_out (vty, "h");
  983.   else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
  984.     vty_out (vty, "d");
  985.   else if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
  986.     vty_out (vty, ">");
  987.   else
  988.     vty_out (vty, " ");
  989.   vty_out (vty, " ");
  990.   /* print prefix and mask */
  991.   if (! display)
  992.     extra_line += route_vty_out_route (p, vty);
  993.   else
  994.     vty_out (vty, "%*s", 17, " ");
  995.   len = vty_out (vty, "%s", binfo->peer->host);
  996.   len = 16 - len;
  997.   if (len < 1)
  998.     {
  999.       vty_out (vty, "%s%*s", VTY_NEWLINE, 33, " ");
  1000.       extra_line++;
  1001.     }
  1002.   else
  1003.     vty_out (vty, "%*s", len, " ");
  1004.   len = vty_out (vty, "%d", bdi->flap);
  1005.   len = 5 - len;
  1006.   if (len < 1)
  1007.     vty_out (vty, " ");
  1008.   else
  1009.     vty_out (vty, "%*s ", len, " ");
  1010.     
  1011.   vty_out (vty, "%s ", peer_uptime (bdi->start_time,
  1012.    timebuf, BGP_UPTIME_LEN));
  1013.   if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED)
  1014.       && ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
  1015.     vty_out (vty, "%s ", bgp_damp_reuse_time_vty (vty, binfo));
  1016.   else
  1017.     vty_out (vty, "%*s ", 8, " ");
  1018.   /* Print attribute */
  1019.   attr = binfo->attr;
  1020.   if (attr)
  1021.     {
  1022.       /* Print aspath */
  1023.       if (attr->aspath)
  1024. aspath_print_vty (vty, attr->aspath);
  1025.       /* Print origin */
  1026.       if (strlen (attr->aspath->str) == 0)
  1027. vty_out (vty, "%s", bgp_origin_str[attr->origin]);
  1028.       else
  1029. vty_out (vty, " %s", bgp_origin_str[attr->origin]);
  1030.     }
  1031.   vty_out (vty, "%s", VTY_NEWLINE);
  1032.   return vty_calc_line (vty, length) + extra_line;
  1033. }
  1034. void
  1035. route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p, 
  1036.       struct bgp_info *binfo, afi_t afi, safi_t safi)
  1037. {
  1038.   char buf[INET6_ADDRSTRLEN];
  1039.   char buf1[BUFSIZ];
  1040.   struct attr *attr;
  1041.   int sockunion_vty_out (struct vty *, union sockunion *);
  1042.   attr = binfo->attr;
  1043.   if (attr)
  1044.     {
  1045.       /* Line1 display AS-path, Aggregator */
  1046.       if (attr->aspath)
  1047. {
  1048.   vty_out (vty, "  ");
  1049.   if (attr->aspath->length == 0)
  1050.     vty_out (vty, "Local");
  1051.   else
  1052.     aspath_print_vty (vty, attr->aspath);
  1053. }
  1054.       if (CHECK_FLAG (binfo->flags, BGP_INFO_STALE))
  1055. vty_out (vty, ", (stale)");
  1056.       if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR)))
  1057. vty_out (vty, ", (aggregated by %d %s)", attr->aggregator_as,
  1058.  inet_ntoa (attr->aggregator_addr));
  1059.       if (CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
  1060. vty_out (vty, ", (Received from a RR-client)");
  1061.       if (CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
  1062. vty_out (vty, ", (Received from a RS-client)");
  1063.       if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
  1064. vty_out (vty, ", (history entry)");
  1065.       else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
  1066. vty_out (vty, ", (suppressed due to dampening)");
  1067.       vty_out (vty, "%s", VTY_NEWLINE);
  1068.   
  1069.       /* Line2 display Next-hop, Neighbor, Router-id */
  1070.       if (p->family == AF_INET)
  1071. {
  1072.   vty_out (vty, "    %s", safi == SAFI_MPLS_VPN ?
  1073.    inet_ntoa (attr->mp_nexthop_global_in) :
  1074.    inet_ntoa (attr->nexthop));
  1075. }
  1076. #ifdef HAVE_IPV6
  1077.       else
  1078. {
  1079.   vty_out (vty, "    %s",
  1080.    inet_ntop (AF_INET6, &attr->mp_nexthop_global,
  1081.       buf, INET6_ADDRSTRLEN));
  1082. }
  1083. #endif /* HAVE_IPV6 */
  1084.       if (binfo->peer == bgp->peer_self)
  1085. {
  1086.   vty_out (vty, " from %s ", 
  1087.    p->family == AF_INET ? "0.0.0.0" : "::");
  1088.   vty_out (vty, "(%s)", inet_ntoa(bgp->router_id));
  1089. }
  1090.       else
  1091. {
  1092.   if (! CHECK_FLAG (binfo->flags, BGP_INFO_VALID))
  1093.     vty_out (vty, " (inaccessible)"); 
  1094.   else if (binfo->igpmetric)
  1095.     vty_out (vty, " (metric %d)", binfo->igpmetric);
  1096.   vty_out (vty, " from %s", sockunion2str (&binfo->peer->su, buf, SU_ADDRSTRLEN));
  1097.   if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
  1098.     vty_out (vty, " (%s)", inet_ntoa (attr->originator_id));
  1099.   else
  1100.     vty_out (vty, " (%s)", inet_ntop (AF_INET, &binfo->peer->remote_id, buf1, BUFSIZ));
  1101. }
  1102.       vty_out (vty, "%s", VTY_NEWLINE);
  1103. #ifdef HAVE_IPV6
  1104.       /* display nexthop local */
  1105.       if (attr->mp_nexthop_len == 32)
  1106. {
  1107.   vty_out (vty, "    (%s)%s",
  1108.    inet_ntop (AF_INET6, &attr->mp_nexthop_local,
  1109.       buf, INET6_ADDRSTRLEN),
  1110.    VTY_NEWLINE);
  1111. }
  1112. #endif /* HAVE_IPV6 */
  1113.       /* Line 3 display Origin, Med, Locpref, Weight, valid, Int/Ext/Local, Atomic, best */
  1114.       vty_out (vty, "      Origin %s", bgp_origin_long_str[attr->origin]);
  1115.   
  1116.       if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
  1117. vty_out (vty, ", metric %u", attr->med);
  1118.   
  1119.       if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
  1120. vty_out (vty, ", localpref %u", attr->local_pref);
  1121.       else
  1122. vty_out (vty, ", localpref %u", bgp->default_local_pref);
  1123.       if (attr->weight != 0)
  1124. vty_out (vty, ", weight %d", attr->weight);
  1125.       if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
  1126. vty_out (vty, ", valid");
  1127.       if (binfo->peer != bgp->peer_self)
  1128. {
  1129.   if (binfo->peer->as == binfo->peer->local_as)
  1130.     vty_out (vty, ", internal");
  1131.   else 
  1132.     vty_out (vty, ", %s", 
  1133.      (bgp_confederation_peers_check(bgp, binfo->peer->as) ? "confed-external" : "external"));
  1134. }
  1135.       else if (binfo->sub_type == BGP_ROUTE_AGGREGATE)
  1136. vty_out (vty, ", aggregated, local");
  1137.       else if (binfo->type != ZEBRA_ROUTE_BGP)
  1138. vty_out (vty, ", sourced");
  1139.       else
  1140. vty_out (vty, ", sourced, local");
  1141.       if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
  1142. vty_out (vty, ", atomic-aggregate");
  1143.   
  1144.       if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
  1145. vty_out (vty, ", best");
  1146.       vty_out (vty, "%s", VTY_NEWLINE);
  1147.   
  1148.       /* Line 4 display Community */
  1149.       if (attr->community)
  1150. vty_out (vty, "      Community: %s%s", attr->community->str,
  1151.  VTY_NEWLINE);
  1152.   
  1153.       /* Line 5 display Extended-community */
  1154.       if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
  1155. vty_out (vty, "      Extended Community: %s%s", attr->ecommunity->str,
  1156.  VTY_NEWLINE);
  1157.   
  1158.       /* Line 6 display Originator, Cluster-id */
  1159.       if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) ||
  1160.   (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)))
  1161. {
  1162.   if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
  1163.     vty_out (vty, "      Originator: %s", inet_ntoa (attr->originator_id));
  1164.   if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))
  1165.     {
  1166.       int i;
  1167.       vty_out (vty, ", Cluster list: ");
  1168.       for (i = 0; i < attr->cluster->length / 4; i++)
  1169. vty_out (vty, "%s ", inet_ntoa (attr->cluster->list[i]));
  1170.     }
  1171.   vty_out (vty, "%s", VTY_NEWLINE);
  1172. }
  1173.       if (binfo->damp_info)
  1174. bgp_damp_info_vty (vty, binfo);
  1175.       /* Line 7 display Uptime */
  1176.       vty_out (vty, "      Last update: %s", ctime (&binfo->uptime));
  1177.     }
  1178.   vty_out (vty, "%s", VTY_NEWLINE);
  1179. }  
  1180. #define BGP_SHOW_SCODE_HEADER "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,%s              r RIB-failure, S Stale%s"
  1181. #define BGP_SHOW_OCODE_HEADER "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s"
  1182. #define BGP_SHOW_HEADER "   Network          Next Hop            Metric LocPrf Weight Path%s"
  1183. #define BGP_SHOW_DAMP_HEADER "   Network          From             Reuse    Path%s"
  1184. #define BGP_SHOW_FLAP_HEADER "   Network          From            Flaps Duration Reuse    Path%s"
  1185. enum bgp_show_type
  1186. {
  1187.   bgp_show_type_normal,
  1188.   bgp_show_type_regexp,
  1189.   bgp_show_type_prefix_list,
  1190.   bgp_show_type_filter_list,
  1191.   bgp_show_type_route_map,
  1192.   bgp_show_type_neighbor,
  1193.   bgp_show_type_cidr_only,
  1194.   bgp_show_type_prefix_longer,
  1195.   bgp_show_type_community_all,
  1196.   bgp_show_type_community,
  1197.   bgp_show_type_community_exact,
  1198.   bgp_show_type_community_list,
  1199.   bgp_show_type_community_list_exact,
  1200.   bgp_show_type_flap_statistics,
  1201.   bgp_show_type_flap_address,
  1202.   bgp_show_type_flap_prefix,
  1203.   bgp_show_type_flap_cidr_only,
  1204.   bgp_show_type_flap_regexp,
  1205.   bgp_show_type_flap_filter_list,
  1206.   bgp_show_type_flap_prefix_list,
  1207.   bgp_show_type_flap_prefix_longer,
  1208.   bgp_show_type_flap_route_map,
  1209.   bgp_show_type_flap_neighbor,
  1210.   bgp_show_type_dampend_paths,
  1211.   bgp_show_type_damp_neighbor
  1212. };
  1213. int
  1214. bgp_show_callback (struct vty *vty, int unlock)
  1215. {
  1216.   struct bgp_node *rn;
  1217.   struct bgp_info *ri;
  1218.   int count;
  1219.   int limit;
  1220.   int display;
  1221.   rn = vty->output_rn;
  1222.   count = 0;
  1223.   limit = ((vty->lines == 0) ? 10 :
  1224.            (vty->lines > 0 ? vty->lines : vty->height - 2));
  1225.   if (vty->status == VTY_MORELINE)
  1226.     limit = 1;
  1227.   else
  1228.     limit = limit > 0 ? limit : 2;
  1229.   /* Quit of display. */
  1230.   if (unlock && rn)
  1231.     {
  1232.       bgp_unlock_node (rn);
  1233.       if (vty->output_clean)
  1234. (*vty->output_clean) (vty);
  1235.       vty->output_rn = NULL;
  1236.       vty->output_func = NULL;
  1237.       vty->output_clean = NULL;
  1238.       vty->output_arg = NULL;
  1239.       return 0;
  1240.     }
  1241.   for (; rn; rn = bgp_route_next (rn)) 
  1242.     if (rn->info != NULL)
  1243.       {
  1244. display = 0;
  1245. for (ri = rn->info; ri; ri = ri->next)
  1246.   {
  1247.     if (vty->output_type == bgp_show_type_flap_statistics
  1248. || vty->output_type == bgp_show_type_flap_address
  1249. || vty->output_type == bgp_show_type_flap_prefix
  1250. || vty->output_type == bgp_show_type_flap_cidr_only
  1251. || vty->output_type == bgp_show_type_flap_regexp
  1252. || vty->output_type == bgp_show_type_flap_filter_list
  1253. || vty->output_type == bgp_show_type_flap_prefix_list
  1254. || vty->output_type == bgp_show_type_flap_prefix_longer
  1255. || vty->output_type == bgp_show_type_flap_route_map
  1256. || vty->output_type == bgp_show_type_flap_neighbor
  1257. || vty->output_type == bgp_show_type_dampend_paths
  1258. || vty->output_type == bgp_show_type_damp_neighbor)
  1259.       {
  1260. if (! ri->damp_info)
  1261.   continue;
  1262.       }
  1263.     if (vty->output_type == bgp_show_type_regexp
  1264. || vty->output_type == bgp_show_type_flap_regexp)
  1265.       {
  1266. regex_t *regex = vty->output_arg;
  1267. if (bgp_regexec (regex, ri->attr->aspath) == REG_NOMATCH)
  1268.   continue;
  1269.       }
  1270.     if (vty->output_type == bgp_show_type_prefix_list
  1271. || vty->output_type == bgp_show_type_flap_prefix_list)
  1272.       {
  1273. struct prefix_list *plist = vty->output_arg;
  1274. if (prefix_list_apply (plist, &rn->p) != PREFIX_PERMIT)
  1275.   continue;
  1276.       }
  1277.     if (vty->output_type == bgp_show_type_filter_list
  1278. || vty->output_type == bgp_show_type_flap_filter_list)
  1279.       {
  1280. struct as_list *as_list = vty->output_arg;
  1281. if (as_list_apply (as_list, ri->attr->aspath) != AS_FILTER_PERMIT)
  1282.   continue;
  1283.       }
  1284.     if (vty->output_type == bgp_show_type_route_map
  1285. || vty->output_type == bgp_show_type_flap_route_map)
  1286.       {
  1287. struct route_map *rmap = vty->output_arg;
  1288. struct bgp_info binfo;
  1289. struct attr dummy_attr; 
  1290. int ret;
  1291. dummy_attr = *ri->attr;
  1292. binfo.peer = ri->peer;
  1293. binfo.attr = &dummy_attr;
  1294. ret = route_map_apply (rmap, &rn->p, RMAP_BGP, &binfo);
  1295. if (ret == RMAP_DENYMATCH)
  1296.   continue;
  1297.       }
  1298.     if (vty->output_type == bgp_show_type_neighbor
  1299. || vty->output_type == bgp_show_type_flap_neighbor
  1300. || vty->output_type == bgp_show_type_damp_neighbor)
  1301.       {
  1302. union sockunion *su = vty->output_arg;
  1303. if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
  1304.   continue;
  1305.       }
  1306.     if (vty->output_type == bgp_show_type_cidr_only
  1307. || vty->output_type == bgp_show_type_flap_cidr_only)
  1308.       {
  1309. u_int32_t destination;
  1310. destination = ntohl (rn->p.u.prefix4.s_addr);
  1311. if (IN_CLASSC (destination) && rn->p.prefixlen == 24)
  1312.   continue;
  1313. if (IN_CLASSB (destination) && rn->p.prefixlen == 16)
  1314.   continue;
  1315. if (IN_CLASSA (destination) && rn->p.prefixlen == 8)
  1316.   continue;
  1317.       }
  1318.     if (vty->output_type == bgp_show_type_prefix_longer
  1319. || vty->output_type == bgp_show_type_flap_prefix_longer)
  1320.       {
  1321. struct prefix *p = vty->output_arg;
  1322. if (! prefix_match (p, &rn->p))
  1323.   continue;
  1324.       }
  1325.     if (vty->output_type == bgp_show_type_community_all)
  1326.       {
  1327. if (! ri->attr->community)
  1328.   continue;
  1329.       }
  1330.     if (vty->output_type == bgp_show_type_community)
  1331.       {
  1332. struct community *com = vty->output_arg;
  1333. if (! ri->attr->community ||
  1334.     ! community_match (ri->attr->community, com))
  1335.   continue;
  1336.       }
  1337.     if (vty->output_type == bgp_show_type_community_exact)
  1338.       {
  1339. struct community *com = vty->output_arg;
  1340. if (! ri->attr->community ||
  1341.     ! community_cmp (ri->attr->community, com))
  1342.   continue;
  1343.       }
  1344.     if (vty->output_type == bgp_show_type_community_list)
  1345.       {
  1346. struct community_list *list = vty->output_arg;
  1347. if (! community_list_match (ri->attr->community, list))
  1348.   continue;
  1349.       }
  1350.     if (vty->output_type == bgp_show_type_community_list_exact)
  1351.       {
  1352. struct community_list *list = vty->output_arg;
  1353. if (! community_list_exact_match (ri->attr->community, list))
  1354.   continue;
  1355.       }
  1356.     if (vty->output_type == bgp_show_type_flap_address
  1357. || vty->output_type == bgp_show_type_flap_prefix)
  1358.       {
  1359. struct prefix *p = vty->output_arg;
  1360. if (! prefix_match (&rn->p, p))
  1361.   continue;
  1362. if (vty->output_type == bgp_show_type_flap_prefix)
  1363.   if (p->prefixlen != rn->p.prefixlen)
  1364.     continue;
  1365.       }
  1366.     if (vty->output_type == bgp_show_type_dampend_paths
  1367. || vty->output_type == bgp_show_type_damp_neighbor)
  1368.       {
  1369. if (! CHECK_FLAG (ri->flags, BGP_INFO_DAMPED)
  1370.     || CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
  1371.   continue;
  1372.       }
  1373.     if (vty->output_type == bgp_show_type_dampend_paths
  1374. || vty->output_type == bgp_show_type_damp_neighbor)
  1375.       count += damp_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST);
  1376.     else if (vty->output_type == bgp_show_type_flap_statistics
  1377.      || vty->output_type == bgp_show_type_flap_address
  1378.      || vty->output_type == bgp_show_type_flap_prefix
  1379.      || vty->output_type == bgp_show_type_flap_cidr_only
  1380.      || vty->output_type == bgp_show_type_flap_regexp
  1381.      || vty->output_type == bgp_show_type_flap_filter_list
  1382.      || vty->output_type == bgp_show_type_flap_prefix_list
  1383.      || vty->output_type == bgp_show_type_flap_prefix_longer
  1384.      || vty->output_type == bgp_show_type_flap_route_map
  1385.      || vty->output_type == bgp_show_type_flap_neighbor)
  1386.       count += flap_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST);
  1387.     else
  1388.       count += route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST);
  1389.     display++;
  1390.   }
  1391. if (display)
  1392.   vty->output_count++;
  1393. /* Remember current pointer then suspend output. */
  1394. if (count >= limit)
  1395.   {
  1396.     vty->status = VTY_CONTINUE;
  1397.     vty->output_rn = bgp_route_next (rn);;
  1398.     vty->output_func = bgp_show_callback;
  1399.     return 0;
  1400.   }
  1401.       }
  1402.   /* Total line display. */
  1403.   if (vty->output_count)
  1404.     vty_out (vty, "%sTotal number of prefixes %ld%s",
  1405.      VTY_NEWLINE, vty->output_count, VTY_NEWLINE);
  1406.   if (vty->output_clean)
  1407.     (*vty->output_clean) (vty);
  1408.   vty->status = VTY_CONTINUE;
  1409.   vty->output_rn = NULL;
  1410.   vty->output_func = NULL;
  1411.   vty->output_clean = NULL;
  1412.   vty->output_arg = NULL;
  1413.   return 0;
  1414. }
  1415. int
  1416. bgp_show (struct vty *vty, char *view_name, afi_t afi, safi_t safi,
  1417.   enum bgp_show_type type)
  1418. {
  1419.   struct bgp *bgp;
  1420.   struct bgp_info *ri;
  1421.   struct bgp_node *rn;
  1422.   struct bgp_table *table;
  1423.   int header = 1;
  1424.   int count;
  1425.   int limit;
  1426.   int display;
  1427.   limit = ((vty->lines == 0) 
  1428.    ? 10 : (vty->lines > 0 
  1429.    ? vty->lines : vty->height - 2));
  1430.   limit = limit > 0 ? limit : 2;
  1431.   /* BGP structure lookup. */
  1432.   if (view_name)
  1433.     {
  1434.       bgp = bgp_lookup_by_name (view_name);
  1435.       if (bgp == NULL)
  1436. {
  1437.   vty_out (vty, "Can't find BGP view %s%s", view_name, VTY_NEWLINE);
  1438.   return CMD_WARNING;
  1439. }
  1440.     }
  1441.   else
  1442.     {
  1443.       bgp = bgp_get_default ();
  1444.       if (bgp == NULL)
  1445. {
  1446.   vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
  1447.   return CMD_WARNING;
  1448. }
  1449.     }
  1450.   count = 0;
  1451.   /* This is first entry point, so reset total line. */
  1452.   vty->output_count = 0;
  1453.   vty->output_type = type;
  1454.   table = bgp->rib[afi][safi];
  1455.   /* Start processing of routes. */
  1456.   for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn)) 
  1457.     if (rn->info != NULL)
  1458.       {
  1459. display = 0;
  1460. for (ri = rn->info; ri; ri = ri->next)
  1461.   {
  1462.     if (vty->output_type == bgp_show_type_flap_statistics
  1463. || type == bgp_show_type_flap_address
  1464. || type == bgp_show_type_flap_prefix
  1465. || type == bgp_show_type_flap_cidr_only
  1466. || type == bgp_show_type_flap_regexp
  1467. || type == bgp_show_type_flap_filter_list
  1468. || type == bgp_show_type_flap_prefix_list
  1469. || type == bgp_show_type_flap_prefix_longer
  1470. || type == bgp_show_type_flap_route_map
  1471. || type == bgp_show_type_flap_neighbor
  1472. || type == bgp_show_type_dampend_paths
  1473. || type == bgp_show_type_damp_neighbor)
  1474.       {
  1475. if (! ri->damp_info)
  1476.   continue;
  1477.       }
  1478.     if (type == bgp_show_type_regexp
  1479. || type == bgp_show_type_flap_regexp)
  1480.       {
  1481. regex_t *regex = vty->output_arg;
  1482.     
  1483. if (bgp_regexec (regex, ri->attr->aspath) == REG_NOMATCH)
  1484.   continue;
  1485.       }
  1486.     if (type == bgp_show_type_prefix_list
  1487. || type == bgp_show_type_flap_prefix_list)
  1488.       {
  1489. struct prefix_list *plist = vty->output_arg;
  1490.     
  1491. if (prefix_list_apply (plist, &rn->p) != PREFIX_PERMIT)
  1492.   continue;
  1493.       }
  1494.     if (type == bgp_show_type_filter_list
  1495. || type == bgp_show_type_flap_filter_list)
  1496.       {
  1497. struct as_list *as_list = vty->output_arg;
  1498. if (as_list_apply (as_list, ri->attr->aspath) != AS_FILTER_PERMIT)
  1499.   continue;
  1500.       }
  1501.     if (type == bgp_show_type_route_map
  1502. || type == bgp_show_type_flap_route_map)
  1503.       {
  1504. struct route_map *rmap = vty->output_arg;
  1505. struct bgp_info binfo;
  1506. struct attr dummy_attr; 
  1507. int ret;
  1508. dummy_attr = *ri->attr;
  1509. binfo.peer = ri->peer;
  1510. binfo.attr = &dummy_attr;
  1511. ret = route_map_apply (rmap, &rn->p, RMAP_BGP, &binfo);
  1512. if (ret == RMAP_DENYMATCH)
  1513.   continue;
  1514.       }
  1515.     if (type == bgp_show_type_neighbor
  1516. || type == bgp_show_type_flap_neighbor
  1517. || type == bgp_show_type_damp_neighbor)
  1518.       {
  1519. union sockunion *su = vty->output_arg;
  1520. if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
  1521.   continue;
  1522.       }
  1523.     if (type == bgp_show_type_cidr_only
  1524. || type == bgp_show_type_flap_cidr_only)
  1525.       {
  1526. u_int32_t destination;
  1527. destination = ntohl (rn->p.u.prefix4.s_addr);
  1528. if (IN_CLASSC (destination) && rn->p.prefixlen == 24)
  1529.   continue;
  1530. if (IN_CLASSB (destination) && rn->p.prefixlen == 16)
  1531.   continue;
  1532. if (IN_CLASSA (destination) && rn->p.prefixlen == 8)
  1533.   continue;
  1534.       }
  1535.     if (type == bgp_show_type_prefix_longer
  1536. || type == bgp_show_type_flap_prefix_longer)
  1537.       {
  1538. struct prefix *p = vty->output_arg;
  1539. if (! prefix_match (p, &rn->p))
  1540.   continue;
  1541.       }
  1542.     if (type == bgp_show_type_community_all)
  1543.       {
  1544. if (! ri->attr->community)
  1545.   continue;
  1546.       }
  1547.     if (type == bgp_show_type_community)
  1548.       {
  1549. struct community *com = vty->output_arg;
  1550. if (! ri->attr->community ||
  1551.     ! community_match (ri->attr->community, com))
  1552.   continue;
  1553.       }
  1554.     if (type == bgp_show_type_community_exact)
  1555.       {
  1556. struct community *com = vty->output_arg;
  1557. if (! ri->attr->community ||
  1558.     ! community_cmp (ri->attr->community, com))
  1559.   continue;
  1560.       }
  1561.     if (type == bgp_show_type_community_list)
  1562.       {
  1563. struct community_list *list = vty->output_arg;
  1564. if (! community_list_match (ri->attr->community, list))
  1565.   continue;
  1566.       }
  1567.     if (type == bgp_show_type_community_list_exact)
  1568.       {
  1569. struct community_list *list = vty->output_arg;
  1570. if (! community_list_exact_match (ri->attr->community, list))
  1571.   continue;
  1572.       }
  1573.     if (type == bgp_show_type_flap_address
  1574. || type == bgp_show_type_flap_prefix)
  1575.       {
  1576. struct prefix *p = vty->output_arg;
  1577. if (! prefix_match (&rn->p, p))
  1578.   continue;
  1579. if (type == bgp_show_type_flap_prefix)
  1580.   if (p->prefixlen != rn->p.prefixlen)
  1581.     continue;
  1582.       }
  1583.     if (type == bgp_show_type_dampend_paths
  1584. || type == bgp_show_type_damp_neighbor)
  1585.       {
  1586. if (! CHECK_FLAG (ri->flags, BGP_INFO_DAMPED)
  1587.     || CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
  1588.   continue;
  1589.       }
  1590.     if (header)
  1591.       {
  1592. vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
  1593. vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
  1594. vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
  1595. if (type == bgp_show_type_dampend_paths
  1596.     || type == bgp_show_type_damp_neighbor)
  1597.   vty_out (vty, BGP_SHOW_DAMP_HEADER, VTY_NEWLINE);
  1598. else if (type == bgp_show_type_flap_statistics
  1599.  || type == bgp_show_type_flap_address
  1600.  || type == bgp_show_type_flap_prefix
  1601.  || type == bgp_show_type_flap_cidr_only
  1602.  || type == bgp_show_type_flap_regexp
  1603.  || type == bgp_show_type_flap_filter_list
  1604.  || type == bgp_show_type_flap_prefix_list
  1605.  || type == bgp_show_type_flap_prefix_longer
  1606.  || type == bgp_show_type_flap_route_map
  1607.  || type == bgp_show_type_flap_neighbor)
  1608.   vty_out (vty, BGP_SHOW_FLAP_HEADER, VTY_NEWLINE);
  1609. else
  1610.   vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE);
  1611. count += 5;
  1612. header = 0;
  1613.       }
  1614.     if (type == bgp_show_type_dampend_paths
  1615. || type == bgp_show_type_damp_neighbor)
  1616.       count += damp_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST);
  1617.     else if (type == bgp_show_type_flap_statistics
  1618.      || type == bgp_show_type_flap_address
  1619.      || type == bgp_show_type_flap_prefix
  1620.      || type == bgp_show_type_flap_cidr_only
  1621.      || type == bgp_show_type_flap_regexp
  1622.      || type == bgp_show_type_flap_filter_list
  1623.      || type == bgp_show_type_flap_prefix_list
  1624.      || type == bgp_show_type_flap_prefix_longer
  1625.      || type == bgp_show_type_flap_route_map
  1626.      || type == bgp_show_type_flap_neighbor)
  1627.       count += flap_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST);
  1628.     else
  1629.       count += route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST);
  1630.     display++;
  1631.   }
  1632. if (display)
  1633.   vty->output_count++;
  1634. /* Remember current pointer then suspend output. */
  1635. if (count >= limit  && vty->type != VTY_SHELL_SERV)
  1636.   {
  1637.     vty->status = VTY_START;
  1638.     vty->output_rn = bgp_route_next (rn);
  1639.     vty->output_func = bgp_show_callback;
  1640.     vty->output_type = type;
  1641.     return CMD_SUCCESS;
  1642.   }
  1643.       }
  1644.   /* No route is displayed */
  1645.   if (vty->output_count == 0)
  1646.     {
  1647.       if (type == bgp_show_type_normal)
  1648. vty_out (vty, "No BGP network exists%s", VTY_NEWLINE);
  1649.     }
  1650.   else
  1651.     vty_out (vty, "%sTotal number of prefixes %ld%s",
  1652.      VTY_NEWLINE, vty->output_count, VTY_NEWLINE);
  1653.   /* Clean up allocated resources. */
  1654.   if (vty->output_clean)
  1655.     (*vty->output_clean) (vty);
  1656.   vty->status = VTY_START;
  1657.   vty->output_rn = NULL;
  1658.   vty->output_func = NULL;
  1659.   vty->output_clean = NULL;
  1660.   vty->output_arg = NULL;
  1661.   return CMD_SUCCESS;
  1662. }
  1663. /* Header of detailed BGP route information */
  1664. void
  1665. route_vty_out_detail_header (struct vty *vty, struct bgp *bgp,
  1666.      struct bgp_node *rn,
  1667.                              struct prefix_rd *prd, afi_t afi, safi_t safi)
  1668. {
  1669.   struct bgp_info *ri;
  1670.   struct prefix *p;
  1671.   struct peer *peer;
  1672.   struct listnode *nn;
  1673.   char buf1[INET6_ADDRSTRLEN];
  1674.   char buf2[INET6_ADDRSTRLEN];
  1675.   int count = 0;
  1676.   int best = 0;
  1677.   int suppress = 0;
  1678.   int no_export = 0;
  1679.   int no_advertise = 0;
  1680.   int local_as = 0;
  1681.   int first = 0;
  1682.   p = &rn->p;
  1683.   vty_out (vty, "BGP routing table entry for %s%s%s/%d%s",
  1684.    (safi == SAFI_MPLS_VPN ?
  1685.    prefix_rd2str (prd, buf1, RD_ADDRSTRLEN) : ""),
  1686.    safi == SAFI_MPLS_VPN ? ":" : "",
  1687.    inet_ntop (p->family, &p->u.prefix, buf2, INET6_ADDRSTRLEN),
  1688.    p->prefixlen, VTY_NEWLINE);
  1689.   for (ri = rn->info; ri; ri = ri->next)
  1690.     {
  1691.       count++;
  1692.       if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))
  1693. {
  1694.   best = count;
  1695.   if (ri->suppress)
  1696.     suppress = 1;
  1697.   if (ri->attr->community != NULL)
  1698.     {
  1699.       if (community_include (ri->attr->community, COMMUNITY_NO_ADVERTISE))
  1700. no_advertise = 1;
  1701.       if (community_include (ri->attr->community, COMMUNITY_NO_EXPORT))
  1702. no_export = 1;
  1703.       if (community_include (ri->attr->community, COMMUNITY_LOCAL_AS))
  1704. local_as = 1;
  1705.     }
  1706. }
  1707.     }
  1708.   vty_out (vty, "Paths: (%d available", count);
  1709.   if (best)
  1710.     {
  1711.       vty_out (vty, ", best #%d", best);
  1712.       if (safi == SAFI_UNICAST)
  1713. vty_out (vty, ", table Default-IP-Routing-Table");
  1714.     }
  1715.   else
  1716.     vty_out (vty, ", no best path");
  1717.   if (no_advertise)
  1718.     vty_out (vty, ", not advertised to any peer");
  1719.   else if (no_export)
  1720.     vty_out (vty, ", not advertised to EBGP peer");
  1721.   else if (local_as)
  1722.     vty_out (vty, ", not advertised outside local AS");
  1723.   if (suppress)
  1724.     vty_out (vty, ", Advertisements suppressed by an aggregate.");
  1725.   vty_out (vty, ")%s", VTY_NEWLINE);
  1726.   /* advertised peer */
  1727.   LIST_LOOP (bgp->peer, peer, nn)
  1728.     {
  1729.       if (bgp_adj_out_lookup (peer, p, afi, safi, rn))
  1730. {
  1731.   if (! first)
  1732.     vty_out (vty, "  Advertised to non peer-group peers:%s ", VTY_NEWLINE);
  1733.   vty_out (vty, " %s", sockunion2str (&peer->su, buf1, SU_ADDRSTRLEN));
  1734.   first = 1;
  1735. }
  1736.     }
  1737.   if (! first)
  1738.     vty_out (vty, "  Not advertised to any peer");
  1739.   vty_out (vty, "%s", VTY_NEWLINE);
  1740. }
  1741. /* Display specified route of BGP table. */
  1742. int
  1743. bgp_show_route (struct vty *vty, char *view_name, char *ip_str,
  1744. afi_t afi, safi_t safi, struct prefix_rd *prd,
  1745. int prefix_check)
  1746. {
  1747.   int ret;
  1748.   int header;
  1749.   int display = 0;
  1750.   struct prefix match;
  1751.   struct bgp_node *rn;
  1752.   struct bgp_node *rm;
  1753.   struct bgp_info *ri;
  1754.   struct bgp *bgp;
  1755.   struct bgp_table *table;
  1756.   /* BGP structure lookup. */
  1757.   if (view_name)
  1758.     {
  1759.       bgp = bgp_lookup_by_name (view_name);
  1760.       if (bgp == NULL)
  1761. {
  1762.   vty_out (vty, "Can't find BGP view %s%s", view_name, VTY_NEWLINE);
  1763.   return CMD_WARNING;
  1764. }
  1765.     }
  1766.   else
  1767.     {
  1768.       bgp = bgp_get_default ();
  1769.       if (bgp == NULL)
  1770. {
  1771.   vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
  1772.   return CMD_WARNING;
  1773. }
  1774.     }
  1775.   /* Check IP address argument. */
  1776.   ret = str2prefix (ip_str, &match);
  1777.   if (! ret)
  1778.     {
  1779.       vty_out (vty, "address is malformed%s", VTY_NEWLINE);
  1780.       return CMD_WARNING;
  1781.     }
  1782.   match.family = afi2family (afi);
  1783.   if (safi == SAFI_MPLS_VPN)
  1784.     {
  1785.       for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
  1786.         {
  1787.           if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
  1788.             continue;
  1789.           if ((table = rn->info) != NULL)
  1790.             {
  1791.               header = 1;
  1792.               if ((rm = bgp_node_match (table, &match)) != NULL)
  1793.                 {
  1794.                   if (prefix_check && rm->p.prefixlen != match.prefixlen)
  1795.                     continue;
  1796.                   for (ri = rm->info; ri; ri = ri->next)
  1797.                     {
  1798.                       if (header)
  1799.                         {
  1800.                           route_vty_out_detail_header (vty, bgp, rm, (struct prefix_rd *)&rn->p,
  1801.                                                        AFI_IP, SAFI_MPLS_VPN);
  1802.                           header = 0;
  1803.                         }
  1804.                       display++;
  1805.                       route_vty_out_detail (vty, bgp, &rm->p, ri, AFI_IP, SAFI_MPLS_VPN);
  1806.                     }
  1807.                 }
  1808.             }
  1809.         }
  1810.     }
  1811.   else
  1812.     {
  1813.       header = 1;
  1814.       if ((rn = bgp_node_match (bgp->rib[afi][safi], &match)) != NULL)
  1815.         {
  1816.           if (! prefix_check || rn->p.prefixlen == match.prefixlen)
  1817.             {
  1818.               for (ri = rn->info; ri; ri = ri->next)
  1819.                 {
  1820.                   if (header)
  1821.                     {
  1822.                       route_vty_out_detail_header (vty, bgp, rn, NULL, afi, safi);
  1823.                       header = 0;
  1824.                     }
  1825.                   display++;
  1826.                   route_vty_out_detail (vty, bgp, &rn->p, ri, afi, safi);
  1827.                 }
  1828.             }
  1829.         }
  1830.     }
  1831.   if (! display)
  1832.     {
  1833.       vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
  1834.       return CMD_WARNING;
  1835.     }
  1836.   return CMD_SUCCESS;
  1837. }
  1838. /* BGP route print out function. */
  1839. DEFUN (show_ip_bgp,
  1840.        show_ip_bgp_cmd,
  1841.        "show ip bgp",
  1842.        SHOW_STR
  1843.        IP_STR
  1844.        BGP_STR)
  1845. {
  1846.   return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST, bgp_show_type_normal);
  1847. }
  1848. DEFUN (show_ip_bgp_ipv4,
  1849.        show_ip_bgp_ipv4_cmd,
  1850.        "show ip bgp ipv4 (unicast|multicast)",
  1851.        SHOW_STR
  1852.        IP_STR
  1853.        BGP_STR
  1854.        "Address familyn"
  1855.        "Address Family modifiern"
  1856.        "Address Family modifiern")
  1857. {
  1858.   if (strncmp (argv[0], "m", 1) == 0)
  1859.     return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST, bgp_show_type_normal);
  1860.  
  1861.   return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST, bgp_show_type_normal);
  1862. }
  1863. DEFUN (show_ip_bgp_route,
  1864.        show_ip_bgp_route_cmd,
  1865.        "show ip bgp A.B.C.D",
  1866.        SHOW_STR
  1867.        IP_STR
  1868.        BGP_STR
  1869.        "Network in the BGP routing table to displayn")
  1870. {
  1871.   return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL, 0);
  1872. }
  1873. DEFUN (show_ip_bgp_ipv4_route,
  1874.        show_ip_bgp_ipv4_route_cmd,
  1875.        "show ip bgp ipv4 (unicast|multicast) A.B.C.D",
  1876.        SHOW_STR
  1877.        IP_STR
  1878.        BGP_STR
  1879.        "Address familyn"
  1880.        "Address Family modifiern"
  1881.        "Address Family modifiern"
  1882.        "Network in the BGP routing table to displayn")
  1883. {
  1884.   if (strncmp (argv[0], "m", 1) == 0)
  1885.     return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MULTICAST, NULL, 0);
  1886.   return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 0);
  1887. }
  1888. DEFUN (show_ip_bgp_vpnv4_all_route,
  1889.        show_ip_bgp_vpnv4_all_route_cmd,
  1890.        "show ip bgp vpnv4 all A.B.C.D",
  1891.        SHOW_STR
  1892.        IP_STR
  1893.        BGP_STR
  1894.        "Display VPNv4 NLRI specific informationn"
  1895.        "Display information about all VPNv4 NLRIsn"
  1896.        "Network in the BGP routing table to displayn")
  1897. {
  1898.   return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_MPLS_VPN, NULL, 0);
  1899. }
  1900. DEFUN (show_ip_bgp_vpnv4_rd_route,
  1901.        show_ip_bgp_vpnv4_rd_route_cmd,
  1902.        "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn A.B.C.D",
  1903.        SHOW_STR
  1904.        IP_STR
  1905.        BGP_STR
  1906.        "Display VPNv4 NLRI specific informationn"
  1907.        "Display information for a route distinguishern"
  1908.        "VPN Route Distinguishern"
  1909.        "Network in the BGP routing table to displayn")
  1910. {
  1911.   int ret;
  1912.   struct prefix_rd prd;
  1913.   ret = str2prefix_rd (argv[0], &prd);
  1914.   if (! ret)
  1915.     {
  1916.       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
  1917.       return CMD_WARNING;
  1918.     }
  1919.   return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MPLS_VPN, &prd, 0);
  1920. }
  1921. DEFUN (show_ip_bgp_prefix,
  1922.        show_ip_bgp_prefix_cmd,
  1923.        "show ip bgp A.B.C.D/M",
  1924.        SHOW_STR
  1925.        IP_STR
  1926.        BGP_STR
  1927.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n")
  1928. {
  1929.   return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL, 1);
  1930. }
  1931. DEFUN (show_ip_bgp_ipv4_prefix,
  1932.        show_ip_bgp_ipv4_prefix_cmd,
  1933.        "show ip bgp ipv4 (unicast|multicast) A.B.C.D/M",
  1934.        SHOW_STR
  1935.        IP_STR
  1936.        BGP_STR
  1937.        "Address familyn"
  1938.        "Address Family modifiern"
  1939.        "Address Family modifiern"
  1940.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n")
  1941. {
  1942.   if (strncmp (argv[0], "m", 1) == 0)
  1943.     return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MULTICAST, NULL, 1);
  1944.   return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 1);
  1945. }
  1946. DEFUN (show_ip_bgp_vpnv4_all_prefix,
  1947.        show_ip_bgp_vpnv4_all_prefix_cmd,
  1948.        "show ip bgp vpnv4 all A.B.C.D/M",
  1949.        SHOW_STR
  1950.        IP_STR
  1951.        BGP_STR
  1952.        "Display VPNv4 NLRI specific informationn"
  1953.        "Display information about all VPNv4 NLRIsn"
  1954.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n")
  1955. {
  1956.   return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_MPLS_VPN, NULL, 1);
  1957. }
  1958. DEFUN (show_ip_bgp_vpnv4_rd_prefix,
  1959.        show_ip_bgp_vpnv4_rd_prefix_cmd,
  1960.        "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn A.B.C.D/M",
  1961.        SHOW_STR
  1962.        IP_STR
  1963.        BGP_STR
  1964.        "Display VPNv4 NLRI specific informationn"
  1965.        "Display information for a route distinguishern"
  1966.        "VPN Route Distinguishern"
  1967.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n")
  1968. {
  1969.   int ret;
  1970.   struct prefix_rd prd;
  1971.   ret = str2prefix_rd (argv[0], &prd);
  1972.   if (! ret)
  1973.     {
  1974.       vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
  1975.       return CMD_WARNING;
  1976.     }
  1977.   return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MPLS_VPN, &prd, 1);
  1978. }
  1979. DEFUN (show_ip_bgp_view,
  1980.        show_ip_bgp_view_cmd,
  1981.        "show ip bgp view WORD",
  1982.        SHOW_STR
  1983.        IP_STR
  1984.        BGP_STR
  1985.        "BGP viewn"
  1986.        "BGP view namen")
  1987. {
  1988.   return bgp_show (vty, argv[0], AFI_IP, SAFI_UNICAST, bgp_show_type_normal);
  1989. }
  1990. DEFUN (show_ip_bgp_view_route,
  1991.        show_ip_bgp_view_route_cmd,
  1992.        "show ip bgp view WORD A.B.C.D",
  1993.        SHOW_STR
  1994.        IP_STR
  1995.        BGP_STR
  1996.        "BGP viewn"
  1997.        "BGP view namen"
  1998.        "Network in the BGP routing table to displayn")
  1999. {
  2000.   return bgp_show_route (vty, argv[0], argv[1], AFI_IP, SAFI_UNICAST, NULL, 0);
  2001. }
  2002. DEFUN (show_ip_bgp_view_prefix,
  2003.        show_ip_bgp_view_prefix_cmd,
  2004.        "show ip bgp view WORD A.B.C.D/M",
  2005.        SHOW_STR
  2006.        IP_STR
  2007.        BGP_STR
  2008.        "BGP viewn"
  2009.        "BGP view namen"
  2010.        "IP prefix <network>/<length>, e.g., 35.0.0.0/8n")
  2011. {
  2012.   return bgp_show_route (vty, argv[0], argv[1], AFI_IP, SAFI_UNICAST, NULL, 1);
  2013. }
  2014. #ifdef HAVE_IPV6
  2015. DEFUN (show_bgp,
  2016.        show_bgp_cmd,
  2017.        "show bgp",
  2018.        SHOW_STR
  2019.        BGP_STR)
  2020. {
  2021.   return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST, bgp_show_type_normal);
  2022. }
  2023. ALIAS (show_bgp,
  2024.        show_bgp_ipv6_cmd,
  2025.        "show bgp ipv6",
  2026.        SHOW_STR
  2027.        BGP_STR
  2028.        "Address familyn");
  2029. /* old command */
  2030. DEFUN (show_ipv6_bgp,
  2031.        show_ipv6_bgp_cmd,
  2032.        "show ipv6 bgp",
  2033.        SHOW_STR
  2034.        IP_STR
  2035.        BGP_STR)
  2036. {
  2037.   return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST, bgp_show_type_normal);
  2038. }
  2039. DEFUN (show_bgp_route,
  2040.        show_bgp_route_cmd,
  2041.        "show bgp X:X::X:X",
  2042.        SHOW_STR
  2043.        BGP_STR
  2044.        "Network in the BGP routing table to displayn")
  2045. {
  2046.   return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 0);
  2047. }
  2048. ALIAS (show_bgp_route,
  2049.        show_bgp_ipv6_route_cmd,
  2050.        "show bgp ipv6 X:X::X:X",
  2051.        SHOW_STR
  2052.        BGP_STR
  2053.        "Address familyn"
  2054.        "Network in the BGP routing table to displayn");
  2055. /* old command */
  2056. DEFUN (show_ipv6_bgp_route,
  2057.        show_ipv6_bgp_route_cmd,
  2058.        "show ipv6 bgp X:X::X:X",
  2059.        SHOW_STR
  2060.        IP_STR
  2061.        BGP_STR
  2062.        "Network in the BGP routing table to displayn")
  2063. {
  2064.   return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 0);
  2065. }
  2066. DEFUN (show_bgp_prefix,
  2067.        show_bgp_prefix_cmd,
  2068.        "show bgp X:X::X:X/M",
  2069.        SHOW_STR
  2070.        BGP_STR
  2071.        "IPv6 prefix <network>/<length>n")
  2072. {
  2073.   return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 1);
  2074. }
  2075. ALIAS (show_bgp_prefix,
  2076.        show_bgp_ipv6_prefix_cmd,
  2077.        "show bgp ipv6 X:X::X:X/M",
  2078.        SHOW_STR
  2079.        BGP_STR
  2080.        "Address familyn"
  2081.        "IPv6 prefix <network>/<length>n");
  2082. /* old command */
  2083. DEFUN (show_ipv6_bgp_prefix,
  2084.        show_ipv6_bgp_prefix_cmd,
  2085.        "show ipv6 bgp X:X::X:X/M",
  2086.        SHOW_STR
  2087.        IP_STR
  2088.        BGP_STR
  2089.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n")
  2090. {
  2091.   return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 1);
  2092. }
  2093. /* old command */
  2094. DEFUN (show_ipv6_mbgp,
  2095.        show_ipv6_mbgp_cmd,
  2096.        "show ipv6 mbgp",
  2097.        SHOW_STR
  2098.        IP_STR
  2099.        MBGP_STR)
  2100. {
  2101.   return bgp_show (vty, NULL, AFI_IP6, SAFI_MULTICAST, bgp_show_type_normal);
  2102. }
  2103. /* old command */
  2104. DEFUN (show_ipv6_mbgp_route,
  2105.        show_ipv6_mbgp_route_cmd,
  2106.        "show ipv6 mbgp X:X::X:X",
  2107.        SHOW_STR
  2108.        IP_STR
  2109.        MBGP_STR
  2110.        "Network in the MBGP routing table to displayn")
  2111. {
  2112.   return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_MULTICAST, NULL, 0);
  2113. }
  2114. /* old command */
  2115. DEFUN (show_ipv6_mbgp_prefix,
  2116.        show_ipv6_mbgp_prefix_cmd,
  2117.        "show ipv6 mbgp X:X::X:X/M",
  2118.        SHOW_STR
  2119.        IP_STR
  2120.        MBGP_STR
  2121.        "IPv6 prefix <network>/<length>, e.g., 3ffe::/16n")
  2122. {
  2123.   return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_MULTICAST, NULL, 1);
  2124. }
  2125. #endif
  2126. void
  2127. bgp_show_regexp_clean (struct vty *vty)
  2128. {
  2129.   bgp_regex_free (vty->output_arg);
  2130. }
  2131. int
  2132. bgp_show_regexp (struct vty *vty, int argc, char **argv, afi_t afi,
  2133.  safi_t safi, enum bgp_show_type type)
  2134. {
  2135.   int i;
  2136.   struct buffer *b;
  2137.   char *regstr;
  2138.   int first;
  2139.   regex_t *regex;
  2140.   
  2141.   first = 0;
  2142.   b = buffer_new (1024);
  2143.   for (i = 0; i < argc; i++)
  2144.     {
  2145.       if (first)
  2146. buffer_putc (b, ' ');
  2147.       else
  2148. {
  2149.   if ((strcmp (argv[i], "unicast") == 0) || (strcmp (argv[i], "multicast") == 0))
  2150.     continue;
  2151.   first = 1;
  2152. }
  2153.       buffer_putstr (b, argv[i]);
  2154.     }
  2155.   buffer_putc (b, '');
  2156.   regstr = buffer_getstr (b);
  2157.   buffer_free (b);
  2158.   regex = bgp_regcomp (regstr);
  2159.   if (! regex)
  2160.     {
  2161.       vty_out (vty, "Can't compile regexp %s%s", argv[0],
  2162.        VTY_NEWLINE);
  2163.       return CMD_WARNING;
  2164.     }
  2165.   vty->output_arg = regex;
  2166.   vty->output_clean = bgp_show_regexp_clean;
  2167.   return bgp_show (vty, NULL, afi, safi, type);
  2168. }
  2169. DEFUN (show_ip_bgp_regexp, 
  2170.        show_ip_bgp_regexp_cmd,
  2171.        "show ip bgp regexp .LINE",
  2172.        SHOW_STR
  2173.        IP_STR
  2174.        BGP_STR
  2175.        "Display routes matching the AS path regular expressionn"
  2176.        "A regular-expression to match the BGP AS pathsn")
  2177. {
  2178.   return bgp_show_regexp (vty, argc, argv, AFI_IP, SAFI_UNICAST,
  2179.   bgp_show_type_regexp);
  2180. }
  2181. DEFUN (show_ip_bgp_flap_regexp, 
  2182.        show_ip_bgp_flap_regexp_cmd,
  2183.        "show ip bgp flap-statistics regexp .LINE",
  2184.        SHOW_STR
  2185.        IP_STR
  2186.        BGP_STR
  2187.        "Display flap statistics of routesn"
  2188.        "Display routes matching the AS path regular expressionn"
  2189.        "A regular-expression to match the BGP AS pathsn")
  2190. {
  2191.   return bgp_show_regexp (vty, argc, argv, AFI_IP, SAFI_UNICAST,
  2192.   bgp_show_type_flap_regexp);
  2193. }
  2194. DEFUN (show_ip_bgp_ipv4_regexp, 
  2195.        show_ip_bgp_ipv4_regexp_cmd,
  2196.        "show ip bgp ipv4 (unicast|multicast) regexp .LINE",
  2197.        SHOW_STR
  2198.        IP_STR
  2199.        BGP_STR
  2200.        "Address familyn"
  2201.        "Address Family modifiern"
  2202.        "Address Family modifiern"
  2203.        "Display routes matching the AS path regular expressionn"
  2204.        "A regular-expression to match the BGP AS pathsn")
  2205. {
  2206.   if (strncmp (argv[0], "m", 1) == 0)
  2207.     return bgp_show_regexp (vty, argc, argv, AFI_IP, SAFI_MULTICAST,
  2208.     bgp_show_type_regexp);
  2209.   return bgp_show_regexp (vty, argc, argv, AFI_IP, SAFI_UNICAST,
  2210.   bgp_show_type_regexp);
  2211. }
  2212. #ifdef HAVE_IPV6
  2213. DEFUN (show_bgp_regexp, 
  2214.        show_bgp_regexp_cmd,
  2215.        "show bgp regexp .LINE",
  2216.        SHOW_STR
  2217.        BGP_STR
  2218.        "Display routes matching the AS path regular expressionn"
  2219.        "A regular-expression to match the BGP AS pathsn")
  2220. {
  2221.   return bgp_show_regexp (vty, argc, argv, AFI_IP6, SAFI_UNICAST,
  2222.   bgp_show_type_regexp);
  2223. }
  2224. ALIAS (show_bgp_regexp, 
  2225.        show_bgp_ipv6_regexp_cmd,
  2226.        "show bgp ipv6 regexp .LINE",
  2227.        SHOW_STR
  2228.        BGP_STR
  2229.        "Address familyn"
  2230.        "Display routes matching the AS path regular expressionn"
  2231.        "A regular-expression to match the BGP AS pathsn");
  2232. /* old command */
  2233. DEFUN (show_ipv6_bgp_regexp, 
  2234.        show_ipv6_bgp_regexp_cmd,
  2235.        "show ipv6 bgp regexp .LINE",
  2236.        SHOW_STR
  2237.        IP_STR
  2238.        BGP_STR
  2239.        "Display routes matching the AS path regular expressionn"
  2240.        "A regular-expression to match the BGP AS pathsn")
  2241. {
  2242.   return bgp_show_regexp (vty, argc, argv, AFI_IP6, SAFI_UNICAST,
  2243.   bgp_show_type_regexp);
  2244. }
  2245. /* old command */
  2246. DEFUN (show_ipv6_mbgp_regexp, 
  2247.        show_ipv6_mbgp_regexp_cmd,
  2248.        "show ipv6 mbgp regexp .LINE",
  2249.        SHOW_STR
  2250.        IP_STR
  2251.        BGP_STR
  2252.        "Display routes matching the AS path regular expressionn"
  2253.        "A regular-expression to match the MBGP AS pathsn")
  2254. {
  2255.   return bgp_show_regexp (vty, argc, argv, AFI_IP6, SAFI_MULTICAST,
  2256.   bgp_show_type_regexp);
  2257. }
  2258. #endif /* HAVE_IPV6 */
  2259. int
  2260. bgp_show_prefix_list (struct vty *vty, char *prefix_list_str, afi_t afi,
  2261.       safi_t safi, enum bgp_show_type type)
  2262. {
  2263.   struct prefix_list *plist;
  2264.   plist = prefix_list_lookup (afi, prefix_list_str);
  2265.   if (plist == NULL)
  2266.     {
  2267.       vty_out (vty, "%% %s is not a valid prefix-list name%s",
  2268.                prefix_list_str, VTY_NEWLINE);     
  2269.       return CMD_WARNING;
  2270.     }
  2271.   vty->output_arg = plist;
  2272.   return bgp_show (vty, NULL, afi, safi, type);
  2273. }
  2274. DEFUN (show_ip_bgp_prefix_list, 
  2275.        show_ip_bgp_prefix_list_cmd,
  2276.        "show ip bgp prefix-list WORD",
  2277.        SHOW_STR
  2278.        IP_STR
  2279.        BGP_STR
  2280.        "Display routes conforming to the prefix-listn"
  2281.        "IP prefix-list namen")
  2282. {
  2283.   return bgp_show_prefix_list (vty, argv[0], AFI_IP, SAFI_UNICAST,
  2284.        bgp_show_type_prefix_list);
  2285. }
  2286. DEFUN (show_ip_bgp_flap_prefix_list, 
  2287.        show_ip_bgp_flap_prefix_list_cmd,
  2288.        "show ip bgp flap-statistics prefix-list WORD",
  2289.        SHOW_STR
  2290.        IP_STR
  2291.        BGP_STR
  2292.        "Display flap statistics of routesn"
  2293.        "Display routes conforming to the prefix-listn"
  2294.        "IP prefix-list namen")
  2295. {
  2296.   return bgp_show_prefix_list (vty, argv[0], AFI_IP, SAFI_UNICAST,
  2297.        bgp_show_type_flap_prefix_list);
  2298. }
  2299. DEFUN (show_ip_bgp_ipv4_prefix_list, 
  2300.        show_ip_bgp_ipv4_prefix_list_cmd,
  2301.        "show ip bgp ipv4 (unicast|multicast) prefix-list WORD",
  2302.        SHOW_STR
  2303.        IP_STR
  2304.        BGP_STR
  2305.        "Address familyn"
  2306.        "Address Family modifiern"
  2307.        "Address Family modifiern"
  2308.        "Display routes conforming to the prefix-listn"
  2309.        "IP prefix-list namen")
  2310. {
  2311.   if (strncmp (argv[0], "m", 1) == 0)
  2312.     return bgp_show_prefix_list (vty, argv[1], AFI_IP, SAFI_MULTICAST,
  2313.          bgp_show_type_prefix_list);
  2314.   return bgp_show_prefix_list (vty, argv[1], AFI_IP, SAFI_UNICAST,
  2315.        bgp_show_type_prefix_list);
  2316. }
  2317. #ifdef HAVE_IPV6
  2318. DEFUN (show_bgp_prefix_list, 
  2319.        show_bgp_prefix_list_cmd,
  2320.        "show bgp prefix-list WORD",
  2321.        SHOW_STR
  2322.        BGP_STR
  2323.        "Display routes conforming to the prefix-listn"
  2324.        "IPv6 prefix-list namen")
  2325. {
  2326.   return bgp_show_prefix_list (vty, argv[0], AFI_IP6, SAFI_UNICAST,
  2327.        bgp_show_type_prefix_list);
  2328. }
  2329. ALIAS (show_bgp_prefix_list, 
  2330.        show_bgp_ipv6_prefix_list_cmd,
  2331.        "show bgp ipv6 prefix-list WORD",
  2332.        SHOW_STR
  2333.        BGP_STR
  2334.        "Address familyn"
  2335.        "Display routes conforming to the prefix-listn"
  2336.        "IPv6 prefix-list namen");
  2337. /* old command */
  2338. DEFUN (show_ipv6_bgp_prefix_list, 
  2339.        show_ipv6_bgp_prefix_list_cmd,
  2340.        "show ipv6 bgp prefix-list WORD",
  2341.        SHOW_STR
  2342.        IPV6_STR
  2343.        BGP_STR
  2344.        "Display routes matching the prefix-listn"
  2345.        "IPv6 prefix-list namen")
  2346. {
  2347.   return bgp_show_prefix_list (vty, argv[0], AFI_IP6, SAFI_UNICAST,
  2348.        bgp_show_type_prefix_list);
  2349. }
  2350. /* old command */
  2351. DEFUN (show_ipv6_mbgp_prefix_list, 
  2352.        show_ipv6_mbgp_prefix_list_cmd,
  2353.        "show ipv6 mbgp prefix-list WORD",
  2354.        SHOW_STR
  2355.        IPV6_STR
  2356.        MBGP_STR
  2357.        "Display routes matching the prefix-listn"
  2358.        "IPv6 prefix-list namen")
  2359. {
  2360.   return bgp_show_prefix_list (vty, argv[0], AFI_IP6, SAFI_MULTICAST,
  2361.        bgp_show_type_prefix_list);
  2362. }
  2363. #endif /* HAVE_IPV6 */
  2364. int
  2365. bgp_show_filter_list (struct vty *vty, char *filter, afi_t afi,
  2366.       safi_t safi, enum bgp_show_type type)
  2367. {
  2368.   struct as_list *as_list;
  2369.   as_list = as_list_lookup (filter);
  2370.   if (as_list == NULL)
  2371.     {
  2372.       vty_out (vty, "%% %s is not a valid AS-path access-list name%s", filter, VTY_NEWLINE);     
  2373.       return CMD_WARNING;
  2374.     }
  2375.   vty->output_arg = as_list;
  2376.   return bgp_show (vty, NULL, afi, safi, type);
  2377. }
  2378. DEFUN (show_ip_bgp_filter_list, 
  2379.        show_ip_bgp_filter_list_cmd,
  2380.        "show ip bgp filter-list WORD",
  2381.        SHOW_STR
  2382.        IP_STR
  2383.        BGP_STR
  2384.        "Display routes conforming to the filter-listn"
  2385.        "Regular expression access list namen")
  2386. {
  2387.   return bgp_show_filter_list (vty, argv[0], AFI_IP, SAFI_UNICAST,
  2388.        bgp_show_type_filter_list);
  2389. }
  2390. DEFUN (show_ip_bgp_flap_filter_list, 
  2391.        show_ip_bgp_flap_filter_list_cmd,
  2392.        "show ip bgp flap-statistics filter-list WORD",
  2393.        SHOW_STR
  2394.        IP_STR
  2395.        BGP_STR
  2396.        "Display flap statistics of routesn"
  2397.        "Display routes conforming to the filter-listn"
  2398.        "Regular expression access list namen")
  2399. {
  2400.   return bgp_show_filter_list (vty, argv[0], AFI_IP, SAFI_UNICAST,
  2401.        bgp_show_type_flap_filter_list);
  2402. }
  2403. DEFUN (show_ip_bgp_ipv4_filter_list, 
  2404.        show_ip_bgp_ipv4_filter_list_cmd,
  2405.        "show ip bgp ipv4 (unicast|multicast) filter-list WORD",
  2406.        SHOW_STR
  2407.        IP_STR
  2408.        BGP_STR
  2409.        "Address familyn"
  2410.        "Address Family modifiern"
  2411.        "Address Family modifiern"
  2412.        "Display routes conforming to the filter-listn"
  2413.        "Regular expression access list namen")
  2414. {
  2415.   if (strncmp (argv[0], "m", 1) == 0)
  2416.     return bgp_show_filter_list (vty, argv[1], AFI_IP, SAFI_MULTICAST,
  2417.          bgp_show_type_filter_list);
  2418.   
  2419.   return bgp_show_filter_list (vty, argv[1], AFI_IP, SAFI_UNICAST,
  2420.        bgp_show_type_filter_list);
  2421. }
  2422. #ifdef HAVE_IPV6
  2423. DEFUN (show_bgp_filter_list, 
  2424.        show_bgp_filter_list_cmd,
  2425.        "show bgp filter-list WORD",
  2426.        SHOW_STR
  2427.        BGP_STR
  2428.        "Display routes conforming to the filter-listn"
  2429.        "Regular expression access list namen")
  2430. {
  2431.   return bgp_show_filter_list (vty, argv[0], AFI_IP6, SAFI_UNICAST,
  2432.        bgp_show_type_filter_list);
  2433. }
  2434. ALIAS (show_bgp_filter_list, 
  2435.        show_bgp_ipv6_filter_list_cmd,
  2436.        "show bgp ipv6 filter-list WORD",
  2437.        SHOW_STR
  2438.        BGP_STR
  2439.        "Address familyn"
  2440.        "Display routes conforming to the filter-listn"
  2441.        "Regular expression access list namen");
  2442. /* old command */
  2443. DEFUN (show_ipv6_bgp_filter_list, 
  2444.        show_ipv6_bgp_filter_list_cmd,
  2445.        "show ipv6 bgp filter-list WORD",
  2446.        SHOW_STR
  2447.        IPV6_STR
  2448.        BGP_STR
  2449.        "Display routes conforming to the filter-listn"
  2450.        "Regular expression access list namen")
  2451. {
  2452.   return bgp_show_filter_list (vty, argv[0], AFI_IP6, SAFI_UNICAST,
  2453.        bgp_show_type_filter_list);
  2454. }
  2455. /* old command */
  2456. DEFUN (show_ipv6_mbgp_filter_list, 
  2457.        show_ipv6_mbgp_filter_list_cmd,
  2458.        "show ipv6 mbgp filter-list WORD",
  2459.        SHOW_STR
  2460.        IPV6_STR
  2461.        MBGP_STR
  2462.        "Display routes conforming to the filter-listn"
  2463.        "Regular expression access list namen")
  2464. {
  2465.   return bgp_show_filter_list (vty, argv[0], AFI_IP6, SAFI_MULTICAST,
  2466.        bgp_show_type_filter_list);
  2467. }
  2468. #endif /* HAVE_IPV6 */
  2469. int
  2470. bgp_show_route_map (struct vty *vty, char *rmap_str, afi_t afi,
  2471.     safi_t safi, enum bgp_show_type type)
  2472. {
  2473.   struct route_map *rmap;
  2474.   rmap = route_map_lookup_by_name (rmap_str);
  2475.   if (! rmap)
  2476.     {
  2477.       vty_out (vty, "%% %s is not a valid route-map name%s",
  2478.        rmap_str, VTY_NEWLINE);     
  2479.       return CMD_WARNING;
  2480.     }
  2481.   vty->output_arg = rmap;
  2482.   return bgp_show (vty, NULL, afi, safi, type);
  2483. }
  2484. DEFUN (show_ip_bgp_route_map, 
  2485.        show_ip_bgp_route_map_cmd,
  2486.        "show ip bgp route-map WORD",
  2487.        SHOW_STR
  2488.        IP_STR
  2489.        BGP_STR
  2490.        "Display routes matching the route-mapn"
  2491.        "A route-map to match onn")
  2492. {
  2493.   return bgp_show_route_map (vty, argv[0], AFI_IP, SAFI_UNICAST,
  2494.      bgp_show_type_route_map);
  2495. }
  2496. DEFUN (show_ip_bgp_flap_route_map, 
  2497.        show_ip_bgp_flap_route_map_cmd,
  2498.        "show ip bgp flap-statistics route-map WORD",
  2499.        SHOW_STR
  2500.        IP_STR
  2501.        BGP_STR
  2502.        "Display flap statistics of routesn"
  2503.        "Display routes matching the route-mapn"
  2504.        "A route-map to match onn")
  2505. {
  2506.   return bgp_show_route_map (vty, argv[0], AFI_IP, SAFI_UNICAST,
  2507.      bgp_show_type_flap_route_map);
  2508. }
  2509. DEFUN (show_ip_bgp_ipv4_route_map, 
  2510.        show_ip_bgp_ipv4_route_map_cmd,
  2511.        "show ip bgp ipv4 (unicast|multicast) route-map WORD",
  2512.        SHOW_STR
  2513.        IP_STR
  2514.        BGP_STR
  2515.        "Address familyn"
  2516.        "Address Family modifiern"
  2517.        "Address Family modifiern"
  2518.        "Display routes matching the route-mapn"
  2519.        "A route-map to match onn")
  2520. {
  2521.   if (strncmp (argv[0], "m", 1) == 0)
  2522.     return bgp_show_route_map (vty, argv[1], AFI_IP, SAFI_MULTICAST,
  2523.        bgp_show_type_route_map);
  2524.   return bgp_show_route_map (vty, argv[1], AFI_IP, SAFI_UNICAST,
  2525.      bgp_show_type_route_map);
  2526. }
  2527. DEFUN (show_bgp_route_map, 
  2528.        show_bgp_route_map_cmd,
  2529.        "show bgp route-map WORD",
  2530.        SHOW_STR
  2531.        BGP_STR
  2532.        "Display routes matching the route-mapn"
  2533.        "A route-map to match onn")
  2534. {
  2535.   return bgp_show_route_map (vty, argv[0], AFI_IP6, SAFI_UNICAST,
  2536.      bgp_show_type_route_map);
  2537. }
  2538. ALIAS (show_bgp_route_map, 
  2539.        show_bgp_ipv6_route_map_cmd,
  2540.        "show bgp ipv6 route-map WORD",
  2541.        SHOW_STR
  2542.        BGP_STR
  2543.        "Address familyn"
  2544.        "Display routes matching the route-mapn"
  2545.        "A route-map to match onn");
  2546. DEFUN (show_ip_bgp_cidr_only,
  2547.        show_ip_bgp_cidr_only_cmd,
  2548.        "show ip bgp cidr-only",
  2549.        SHOW_STR
  2550.        IP_STR
  2551.        BGP_STR
  2552.        "Display only routes with non-natural netmasksn")
  2553. {
  2554.     return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
  2555.      bgp_show_type_cidr_only);
  2556. }
  2557. DEFUN (show_ip_bgp_flap_cidr_only,
  2558.        show_ip_bgp_flap_cidr_only_cmd,
  2559.        "show ip bgp flap-statistics cidr-only",
  2560.        SHOW_STR
  2561.        IP_STR
  2562.        BGP_STR
  2563.        "Display flap statistics of routesn"
  2564.        "Display only routes with non-natural netmasksn")
  2565. {
  2566.   return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
  2567.    bgp_show_type_flap_cidr_only);
  2568. }
  2569. DEFUN (show_ip_bgp_ipv4_cidr_only,
  2570.        show_ip_bgp_ipv4_cidr_only_cmd,
  2571.        "show ip bgp ipv4 (unicast|multicast) cidr-only",
  2572.        SHOW_STR
  2573.        IP_STR
  2574.        BGP_STR
  2575.        "Address familyn"
  2576.        "Address Family modifiern"
  2577.        "Address Family modifiern"
  2578.        "Display only routes with non-natural netmasksn")
  2579. {
  2580.   if (strncmp (argv[0], "m", 1) == 0)
  2581.     return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST,
  2582.      bgp_show_type_cidr_only);
  2583.   return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
  2584.      bgp_show_type_cidr_only);
  2585. }
  2586. DEFUN (show_ip_bgp_community_all,
  2587.        show_ip_bgp_community_all_cmd,
  2588.        "show ip bgp community",
  2589.        SHOW_STR
  2590.        IP_STR
  2591.        BGP_STR
  2592.        "Display routes matching the communitiesn")
  2593. {
  2594.   return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
  2595.      bgp_show_type_community_all);
  2596. }
  2597. DEFUN (show_ip_bgp_ipv4_community_all,
  2598.        show_ip_bgp_ipv4_community_all_cmd,
  2599.        "show ip bgp ipv4 (unicast|multicast) community",
  2600.        SHOW_STR
  2601.        IP_STR
  2602.        BGP_STR
  2603.        "Address familyn"
  2604.        "Address Family modifiern"
  2605.        "Address Family modifiern"
  2606.        "Display routes matching the communitiesn")
  2607. {
  2608.   if (strncmp (argv[0], "m", 1) == 0)
  2609.     return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST,
  2610.      bgp_show_type_community_all);
  2611.  
  2612.   return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
  2613.    bgp_show_type_community_all);
  2614. }
  2615. #ifdef HAVE_IPV6
  2616. DEFUN (show_bgp_community_all,
  2617.        show_bgp_community_all_cmd,
  2618.        "show bgp community",
  2619.        SHOW_STR
  2620.        BGP_STR
  2621.        "Display routes matching the communitiesn")
  2622. {
  2623.   return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST,
  2624.    bgp_show_type_community_all);
  2625. }
  2626. ALIAS (show_bgp_community_all,
  2627.        show_bgp_ipv6_community_all_cmd,
  2628.        "show bgp ipv6 community",
  2629.        SHOW_STR
  2630.        BGP_STR
  2631.        "Address familyn"
  2632.        "Display routes matching the communitiesn");
  2633. /* old command */
  2634. DEFUN (show_ipv6_bgp_community_all,
  2635.        show_ipv6_bgp_community_all_cmd,
  2636.        "show ipv6 bgp community",
  2637.        SHOW_STR
  2638.        IPV6_STR
  2639.        BGP_STR
  2640.        "Display routes matching the communitiesn")
  2641. {
  2642.   return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST,
  2643.    bgp_show_type_community_all);
  2644. }
  2645. /* old command */
  2646. DEFUN (show_ipv6_mbgp_community_all,
  2647.        show_ipv6_mbgp_community_all_cmd,
  2648.        "show ipv6 mbgp community",
  2649.        SHOW_STR
  2650.        IPV6_STR
  2651.        MBGP_STR
  2652.        "Display routes matching the communitiesn")
  2653. {
  2654.   return bgp_show (vty, NULL, AFI_IP6, SAFI_MULTICAST,
  2655.    bgp_show_type_community_all);
  2656. }
  2657. #endif /* HAVE_IPV6 */
  2658. int
  2659. bgp_show_community (struct vty *vty, int argc, char **argv, int exact,
  2660.                           u_int16_t afi, u_char safi)
  2661. {
  2662.   struct community *com;
  2663.   struct buffer *b;
  2664.   int i;
  2665.   char *str;
  2666.   int first = 0;
  2667.   b = buffer_new (1024);
  2668.   for (i = 0; i < argc; i++)
  2669.     {
  2670.       if (first)
  2671.         buffer_putc (b, ' ');
  2672.       else
  2673. {
  2674.   if ((strcmp (argv[i], "unicast") == 0) || (strcmp (argv[i], "multicast") == 0))
  2675.     continue;
  2676.   first = 1;
  2677. }
  2678.       
  2679.       buffer_putstr (b, argv[i]);
  2680.     }
  2681.   buffer_putc (b, '');
  2682.   str = buffer_getstr (b);
  2683.   buffer_free (b);
  2684.   com = community_str2com (str);
  2685.   free (str);
  2686.   if (! com)
  2687.     {
  2688.       vty_out (vty, "%% Community malformed: %s", VTY_NEWLINE);
  2689.       return CMD_WARNING;
  2690.     }
  2691.   vty->output_arg = com;
  2692.   if (exact)
  2693.     return bgp_show (vty, NULL, afi, safi, bgp_show_type_community_exact);
  2694.   return bgp_show (vty, NULL, afi, safi, bgp_show_type_community);
  2695. }
  2696. DEFUN (show_ip_bgp_community,
  2697.        show_ip_bgp_community_cmd,
  2698.        "show ip bgp community (AA:NN|local-AS|no-advertise|no-export)",
  2699.        SHOW_STR
  2700.        IP_STR
  2701.        BGP_STR
  2702.        "Display routes matching the communitiesn"
  2703.        "community numbern"
  2704.        "Do not send outside local AS (well-known community)n"
  2705.        "Do not advertise to any peer (well-known community)n"
  2706.        "Do not export to next AS (well-known community)n")
  2707. {
  2708.   return bgp_show_community (vty, argc, argv, 0, AFI_IP, SAFI_UNICAST);
  2709. }
  2710. ALIAS (show_ip_bgp_community,
  2711.        show_ip_bgp_community2_cmd,
  2712.        "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
  2713.        SHOW_STR
  2714.        IP_STR
  2715.        BGP_STR
  2716.        "Display routes matching the communitiesn"
  2717.        "community numbern"
  2718.        "Do not send outside local AS (well-known community)n"
  2719.        "Do not advertise to any peer (well-known community)n"
  2720.        "Do not export to next AS (well-known community)n"
  2721.        "community numbern"
  2722.        "Do not send outside local AS (well-known community)n"