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

网络

开发平台:

Unix_Linux

  1. /* Route map function of bgpd.
  2.    Copyright (C) 1998, 1999 Kunihiro Ishiguro
  3. This file is part of GNU Zebra.
  4. GNU Zebra is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by the
  6. Free Software Foundation; either version 2, or (at your option) any
  7. later version.
  8. GNU Zebra is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Zebra; see the file COPYING.  If not, write to the Free
  14. Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  15. 02111-1307, USA.  */
  16. #include <zebra.h>
  17. #include "prefix.h"
  18. #include "filter.h"
  19. #include "routemap.h"
  20. #include "command.h"
  21. #include "linklist.h"
  22. #include "plist.h"
  23. #include "memory.h"
  24. #include "log.h"
  25. #ifdef HAVE_GNU_REGEX
  26. #include <regex.h>
  27. #else
  28. #include "regex-gnu.h"
  29. #endif /* HAVE_GNU_REGEX */
  30. #include "buffer.h"
  31. #include "sockunion.h"
  32. #include "bgpd/bgpd.h"
  33. #include "bgpd/bgp_table.h"
  34. #include "bgpd/bgp_attr.h"
  35. #include "bgpd/bgp_aspath.h"
  36. #include "bgpd/bgp_route.h"
  37. #include "bgpd/bgp_regex.h"
  38. #include "bgpd/bgp_community.h"
  39. #include "bgpd/bgp_clist.h"
  40. #include "bgpd/bgp_filter.h"
  41. #include "bgpd/bgp_mplsvpn.h"
  42. #include "bgpd/bgp_ecommunity.h"
  43. /* Memo of route-map commands.
  44. o Cisco route-map
  45.  match as-path          :  Done
  46.        community        :  Done
  47.        interface        :  Not yet
  48.        ip address       :  Done
  49.        ip next-hop      :  Done
  50.        ip route-source  :  (This will not be implemented by bgpd)
  51.        ip prefix-list   :  Done
  52.        ipv6 address     :  Done
  53.        ipv6 next-hop    :  Done
  54.        ipv6 route-source:  (This will not be implemented by bgpd)
  55.        ipv6 prefix-list :  Done
  56.        length           :  (This will not be implemented by bgpd)
  57.        metric           :  Done
  58.        route-type       :  (This will not be implemented by bgpd)
  59.        tag              :  (This will not be implemented by bgpd)
  60.  set  as-path prepend   :  Done
  61.       as-path tag       :  Not yet
  62.       automatic-tag     :  (This will not be implemented by bgpd)
  63.       community         :  Done
  64.       comm-list         :  Not yet
  65.       dampning          :  Not yet
  66.       default           :  (This will not be implemented by bgpd)
  67.       interface         :  (This will not be implemented by bgpd)
  68.       ip default        :  (This will not be implemented by bgpd)
  69.       ip next-hop       :  Done
  70.       ip precedence     :  (This will not be implemented by bgpd)
  71.       ip tos            :  (This will not be implemented by bgpd)
  72.       level             :  (This will not be implemented by bgpd)
  73.       local-preference  :  Done
  74.       metric            :  Done
  75.       metric-type       :  Not yet
  76.       origin            :  Done
  77.       tag               :  (This will not be implemented by bgpd)
  78.       weight            :  Done
  79. o Local extention
  80.   set ipv6 next-hop global: Done
  81.   set ipv6 next-hop local : Done
  82. */ 
  83. /* `match ip address IP_ACCESS_LIST' */
  84. /* Match function should return 1 if match is success else return
  85.    zero. */
  86. route_map_result_t
  87. route_match_ip_address (void *rule, struct prefix *prefix, 
  88. route_map_object_t type, void *object)
  89. {
  90.   struct access_list *alist;
  91.   /* struct prefix_ipv4 match; */
  92.   if (type == RMAP_BGP)
  93.     {
  94.       alist = access_list_lookup (AFI_IP, (char *) rule);
  95.       if (alist == NULL)
  96. return RMAP_NOMATCH;
  97.     
  98.       return (access_list_apply (alist, prefix) == FILTER_DENY ?
  99.       RMAP_NOMATCH : RMAP_MATCH);
  100.     }
  101.   return RMAP_NOMATCH;
  102. }
  103. /* Route map `ip address' match statement.  `arg' should be
  104.    access-list name. */
  105. void *
  106. route_match_ip_address_compile (char *arg)
  107. {
  108.   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  109. }
  110. /* Free route map's compiled `ip address' value. */
  111. void
  112. route_match_ip_address_free (void *rule)
  113. {
  114.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  115. }
  116. /* Route map commands for ip address matching. */
  117. struct route_map_rule_cmd route_match_ip_address_cmd =
  118. {
  119.   "ip address",
  120.   route_match_ip_address,
  121.   route_match_ip_address_compile,
  122.   route_match_ip_address_free
  123. };
  124. /* `match ip next-hop IP_ADDRESS' */
  125. /* Match function return 1 if match is success else return zero. */
  126. route_map_result_t
  127. route_match_ip_next_hop (void *rule, struct prefix *prefix, 
  128.  route_map_object_t type, void *object)
  129. {
  130.   struct access_list *alist;
  131.   struct bgp_info *bgp_info;
  132.   struct prefix_ipv4 p;
  133.   if (type == RMAP_BGP)
  134.     {
  135.       bgp_info = object;
  136.       p.family = AF_INET;
  137.       p.prefix = bgp_info->attr->nexthop;
  138.       p.prefixlen = IPV4_MAX_BITLEN;
  139.       alist = access_list_lookup (AFI_IP, (char *) rule);
  140.       if (alist == NULL)
  141. return RMAP_NOMATCH;
  142.       return (access_list_apply (alist, &p) == FILTER_DENY ?
  143.               RMAP_NOMATCH : RMAP_MATCH);
  144.     }
  145.   return RMAP_NOMATCH;
  146. }
  147. /* Route map `ip next-hop' match statement. `arg' is
  148.    access-list name. */
  149. void *
  150. route_match_ip_next_hop_compile (char *arg)
  151. {
  152.   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  153. }
  154. /* Free route map's compiled `ip address' value. */
  155. void
  156. route_match_ip_next_hop_free (void *rule)
  157. {
  158.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  159. }
  160. /* Route map commands for ip next-hop matching. */
  161. struct route_map_rule_cmd route_match_ip_next_hop_cmd =
  162. {
  163.   "ip next-hop",
  164.   route_match_ip_next_hop,
  165.   route_match_ip_next_hop_compile,
  166.   route_match_ip_next_hop_free
  167. };
  168. /* `match ip route-source ACCESS-LIST' */
  169. /* Match function return 1 if match is success else return zero. */
  170. route_map_result_t
  171. route_match_ip_route_source (void *rule, struct prefix *prefix, 
  172.      route_map_object_t type, void *object)
  173. {
  174.   struct access_list *alist;
  175.   struct bgp_info *bgp_info;
  176.   struct peer *peer;
  177.   struct prefix_ipv4 p;
  178.   if (type == RMAP_BGP)
  179.     {
  180.       bgp_info = object;
  181.       peer = bgp_info->peer;
  182.       if (! peer || sockunion_family (&peer->su) != AF_INET)
  183. return RMAP_NOMATCH;
  184.       p.family = AF_INET;
  185.       p.prefix = peer->su.sin.sin_addr;
  186.       p.prefixlen = IPV4_MAX_BITLEN;
  187.       alist = access_list_lookup (AFI_IP, (char *) rule);
  188.       if (alist == NULL)
  189. return RMAP_NOMATCH;
  190.       return (access_list_apply (alist, &p) == FILTER_DENY ?
  191.               RMAP_NOMATCH : RMAP_MATCH);
  192.     }
  193.   return RMAP_NOMATCH;
  194. }
  195. /* Route map `ip route-source' match statement. `arg' is
  196.    access-list name. */
  197. void *
  198. route_match_ip_route_source_compile (char *arg)
  199. {
  200.   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  201. }
  202. /* Free route map's compiled `ip address' value. */
  203. void
  204. route_match_ip_route_source_free (void *rule)
  205. {
  206.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  207. }
  208. /* Route map commands for ip route-source matching. */
  209. struct route_map_rule_cmd route_match_ip_route_source_cmd =
  210. {
  211.   "ip route-source",
  212.   route_match_ip_route_source,
  213.   route_match_ip_route_source_compile,
  214.   route_match_ip_route_source_free
  215. };
  216. /* `match ip address prefix-list PREFIX_LIST' */
  217. route_map_result_t
  218. route_match_ip_address_prefix_list (void *rule, struct prefix *prefix, 
  219.     route_map_object_t type, void *object)
  220. {
  221.   struct prefix_list *plist;
  222.   if (type == RMAP_BGP)
  223.     {
  224.       plist = prefix_list_lookup (AFI_IP, (char *) rule);
  225.       if (plist == NULL)
  226. return RMAP_NOMATCH;
  227.     
  228.       return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
  229.       RMAP_NOMATCH : RMAP_MATCH);
  230.     }
  231.   return RMAP_NOMATCH;
  232. }
  233. void *
  234. route_match_ip_address_prefix_list_compile (char *arg)
  235. {
  236.   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  237. }
  238. void
  239. route_match_ip_address_prefix_list_free (void *rule)
  240. {
  241.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  242. }
  243. struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
  244. {
  245.   "ip address prefix-list",
  246.   route_match_ip_address_prefix_list,
  247.   route_match_ip_address_prefix_list_compile,
  248.   route_match_ip_address_prefix_list_free
  249. };
  250. /* `match ip next-hop prefix-list PREFIX_LIST' */
  251. route_map_result_t
  252. route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
  253.                                     route_map_object_t type, void *object)
  254. {
  255.   struct prefix_list *plist;
  256.   struct bgp_info *bgp_info;
  257.   struct prefix_ipv4 p;
  258.   if (type == RMAP_BGP)
  259.     {
  260.       bgp_info = object;
  261.       p.family = AF_INET;
  262.       p.prefix = bgp_info->attr->nexthop;
  263.       p.prefixlen = IPV4_MAX_BITLEN;
  264.       plist = prefix_list_lookup (AFI_IP, (char *) rule);
  265.       if (plist == NULL)
  266.         return RMAP_NOMATCH;
  267.       return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
  268.               RMAP_NOMATCH : RMAP_MATCH);
  269.     }
  270.   return RMAP_NOMATCH;
  271. }
  272. void *
  273. route_match_ip_next_hop_prefix_list_compile (char *arg)
  274. {
  275.   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  276. }
  277. void
  278. route_match_ip_next_hop_prefix_list_free (void *rule)
  279. {
  280.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  281. }
  282. struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
  283. {
  284.   "ip next-hop prefix-list",
  285.   route_match_ip_next_hop_prefix_list,
  286.   route_match_ip_next_hop_prefix_list_compile,
  287.   route_match_ip_next_hop_prefix_list_free
  288. };
  289. /* `match ip route-source prefix-list PREFIX_LIST' */
  290. route_map_result_t
  291. route_match_ip_route_source_prefix_list (void *rule, struct prefix *prefix,
  292.  route_map_object_t type, void *object)
  293. {
  294.   struct prefix_list *plist;
  295.   struct bgp_info *bgp_info;
  296.   struct peer *peer;
  297.   struct prefix_ipv4 p;
  298.   if (type == RMAP_BGP)
  299.     {
  300.       bgp_info = object;
  301.       peer = bgp_info->peer;
  302.       if (! peer || sockunion_family (&peer->su) != AF_INET)
  303. return RMAP_NOMATCH;
  304.       p.family = AF_INET;
  305.       p.prefix = peer->su.sin.sin_addr;
  306.       p.prefixlen = IPV4_MAX_BITLEN;
  307.       plist = prefix_list_lookup (AFI_IP, (char *) rule);
  308.       if (plist == NULL)
  309.         return RMAP_NOMATCH;
  310.       return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
  311.               RMAP_NOMATCH : RMAP_MATCH);
  312.     }
  313.   return RMAP_NOMATCH;
  314. }
  315. void *
  316. route_match_ip_route_source_prefix_list_compile (char *arg)
  317. {
  318.   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  319. }
  320. void
  321. route_match_ip_route_source_prefix_list_free (void *rule)
  322. {
  323.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  324. }
  325. struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd =
  326. {
  327.   "ip route-source prefix-list",
  328.   route_match_ip_route_source_prefix_list,
  329.   route_match_ip_route_source_prefix_list_compile,
  330.   route_match_ip_route_source_prefix_list_free
  331. };
  332. /* `match metric METRIC' */
  333. /* Match function return 1 if match is success else return zero. */
  334. route_map_result_t
  335. route_match_metric (void *rule, struct prefix *prefix, 
  336.     route_map_object_t type, void *object)
  337. {
  338.   u_int32_t *med;
  339.   struct bgp_info *bgp_info;
  340.   if (type == RMAP_BGP)
  341.     {
  342.       med = rule;
  343.       bgp_info = object;
  344.     
  345.       if (bgp_info->attr->med == *med)
  346. return RMAP_MATCH;
  347.       else
  348. return RMAP_NOMATCH;
  349.     }
  350.   return RMAP_NOMATCH;
  351. }
  352. /* Route map `match metric' match statement. `arg' is MED value */
  353. void *
  354. route_match_metric_compile (char *arg)
  355. {
  356.   u_int32_t *med;
  357.   char *endptr = NULL;
  358.   med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
  359.   *med = strtoul (arg, &endptr, 10);
  360.   if (*endptr != '' || *med == ULONG_MAX)
  361.     {
  362.       XFREE (MTYPE_ROUTE_MAP_COMPILED, med);
  363.       return NULL;
  364.     }
  365.   return med;
  366. }
  367. /* Free route map's compiled `match metric' value. */
  368. void
  369. route_match_metric_free (void *rule)
  370. {
  371.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  372. }
  373. /* Route map commands for metric matching. */
  374. struct route_map_rule_cmd route_match_metric_cmd =
  375. {
  376.   "metric",
  377.   route_match_metric,
  378.   route_match_metric_compile,
  379.   route_match_metric_free
  380. };
  381. /* `match as-path ASPATH' */
  382. /* Match function for as-path match.  I assume given object is */
  383. route_map_result_t
  384. route_match_aspath (void *rule, struct prefix *prefix, 
  385.     route_map_object_t type, void *object)
  386. {
  387.   
  388.   struct as_list *as_list;
  389.   struct bgp_info *bgp_info;
  390.   if (type == RMAP_BGP)
  391.     {
  392.       as_list = as_list_lookup ((char *) rule);
  393.       if (as_list == NULL)
  394. return RMAP_NOMATCH;
  395.     
  396.       bgp_info = object;
  397.     
  398.       /* Perform match. */
  399.       return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
  400.     }
  401.   return RMAP_NOMATCH;
  402. }
  403. /* Compile function for as-path match. */
  404. void *
  405. route_match_aspath_compile (char *arg)
  406. {
  407.   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  408. }
  409. /* Compile function for as-path match. */
  410. void
  411. route_match_aspath_free (void *rule)
  412. {
  413.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  414. }
  415. /* Route map commands for aspath matching. */
  416. struct route_map_rule_cmd route_match_aspath_cmd = 
  417. {
  418.   "as-path",
  419.   route_match_aspath,
  420.   route_match_aspath_compile,
  421.   route_match_aspath_free
  422. };
  423. #if ROUTE_MATCH_ASPATH_OLD
  424. /* `match as-path ASPATH' */
  425. /* Match function for as-path match.  I assume given object is */
  426. int
  427. route_match_aspath (void *rule, struct prefix *prefix, void *object)
  428. {
  429.   regex_t *regex;
  430.   struct bgp_info *bgp_info;
  431.   regex = rule;
  432.   bgp_info = object;
  433.   
  434.   /* Perform match. */
  435.   return bgp_regexec (regex, bgp_info->attr->aspath);
  436. }
  437. /* Compile function for as-path match. */
  438. void *
  439. route_match_aspath_compile (char *arg)
  440. {
  441.   regex_t *regex;
  442.   regex = bgp_regcomp (arg);
  443.   if (! regex)
  444.     return NULL;
  445.   return regex;
  446. }
  447. /* Compile function for as-path match. */
  448. void
  449. route_match_aspath_free (void *rule)
  450. {
  451.   regex_t *regex = rule;
  452.   bgp_regex_free (regex);
  453. }
  454. /* Route map commands for aspath matching. */
  455. struct route_map_rule_cmd route_match_aspath_cmd = 
  456. {
  457.   "as-path",
  458.   route_match_aspath,
  459.   route_match_aspath_compile,
  460.   route_match_aspath_free
  461. };
  462. #endif /* ROUTE_MATCH_ASPATH_OLD */
  463. /* `match community COMMUNIY' */
  464. struct rmap_community
  465. {
  466.   char *name;
  467.   int exact;
  468. };
  469. /* Match function for community match. */
  470. route_map_result_t
  471. route_match_community (void *rule, struct prefix *prefix, 
  472.        route_map_object_t type, void *object)
  473. {
  474.   struct community_list *list;
  475.   struct bgp_info *bgp_info;
  476.   struct rmap_community *rcom;
  477.   if (type == RMAP_BGP) 
  478.     {
  479.       bgp_info = object;
  480.       rcom = rule;
  481.       list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
  482.       if (! list)
  483. return RMAP_NOMATCH;
  484.       if (rcom->exact)
  485. {
  486.   if (community_list_exact_match (bgp_info->attr->community, list))
  487.     return RMAP_MATCH;
  488. }
  489.       else
  490. {
  491.   if (community_list_match (bgp_info->attr->community, list))
  492.     return RMAP_MATCH;
  493. }
  494.     }
  495.   return RMAP_NOMATCH;
  496. }
  497. /* Compile function for community match. */
  498. void *
  499. route_match_community_compile (char *arg)
  500. {
  501.   struct rmap_community *rcom;
  502.   int len;
  503.   char *p;
  504.   rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
  505.   p = strchr (arg, ' ');
  506.   if (p)
  507.     {
  508.       len = p - arg;
  509.       rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
  510.       memcpy (rcom->name, arg, len);
  511.       rcom->exact = 1;
  512.     }
  513.   else
  514.     {
  515.       rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  516.       rcom->exact = 0;
  517.     }
  518.   return rcom;
  519. }
  520. /* Compile function for community match. */
  521. void
  522. route_match_community_free (void *rule)
  523. {
  524.   struct rmap_community *rcom = rule;
  525.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name); 
  526.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
  527. }
  528. /* Route map commands for community matching. */
  529. struct route_map_rule_cmd route_match_community_cmd = 
  530. {
  531.   "community",
  532.   route_match_community,
  533.   route_match_community_compile,
  534.   route_match_community_free
  535. };
  536. /* Match function for extcommunity match. */
  537. route_map_result_t
  538. route_match_ecommunity (void *rule, struct prefix *prefix, 
  539. route_map_object_t type, void *object)
  540. {
  541.   struct community_list *list;
  542.   struct bgp_info *bgp_info;
  543.   if (type == RMAP_BGP) 
  544.     {
  545.       bgp_info = object;
  546.       list = community_list_lookup (bgp_clist, (char *) rule,
  547.     EXTCOMMUNITY_LIST_MASTER);
  548.       if (! list)
  549. return RMAP_NOMATCH;
  550.       if (ecommunity_list_match (bgp_info->attr->ecommunity, list))
  551. return RMAP_MATCH;
  552.     }
  553.   return RMAP_NOMATCH;
  554. }
  555. /* Compile function for extcommunity match. */
  556. void *
  557. route_match_ecommunity_compile (char *arg)
  558. {
  559.   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  560. }
  561. /* Compile function for extcommunity match. */
  562. void
  563. route_match_ecommunity_free (void *rule)
  564. {
  565.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  566. }
  567. /* Route map commands for community matching. */
  568. struct route_map_rule_cmd route_match_ecommunity_cmd = 
  569. {
  570.   "extcommunity",
  571.   route_match_ecommunity,
  572.   route_match_ecommunity_compile,
  573.   route_match_ecommunity_free
  574. };
  575. /* `match nlri` and `set nlri` are replaced by `address-family ipv4`
  576.    and `address-family vpnv4'.  */
  577. /* `match origin' */
  578. route_map_result_t
  579. route_match_origin (void *rule, struct prefix *prefix, 
  580.     route_map_object_t type, void *object)
  581. {
  582.   u_char *origin;
  583.   struct bgp_info *bgp_info;
  584.   if (type == RMAP_BGP)
  585.     {
  586.       origin = rule;
  587.       bgp_info = object;
  588.     
  589.       if (bgp_info->attr->origin == *origin)
  590. return RMAP_MATCH;
  591.     }
  592.   return RMAP_NOMATCH;
  593. }
  594. void *
  595. route_match_origin_compile (char *arg)
  596. {
  597.   u_char *origin;
  598.   origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
  599.   if (strcmp (arg, "igp") == 0)
  600.     *origin = 0;
  601.   else if (strcmp (arg, "egp") == 0)
  602.     *origin = 1;
  603.   else
  604.     *origin = 2;
  605.   return origin;
  606. }
  607. /* Free route map's compiled `ip address' value. */
  608. void
  609. route_match_origin_free (void *rule)
  610. {
  611.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  612. }
  613. /* Route map commands for origin matching. */
  614. struct route_map_rule_cmd route_match_origin_cmd =
  615. {
  616.   "origin",
  617.   route_match_origin,
  618.   route_match_origin_compile,
  619.   route_match_origin_free
  620. };
  621. /* `set ip next-hop IP_ADDRESS' */
  622. /* Set nexthop to object.  ojbect must be pointer to struct attr. */
  623. struct rmap_ip_nexthop_set
  624. {
  625.   struct in_addr *address;
  626.   int peer_address;
  627. };
  628. route_map_result_t
  629. route_set_ip_nexthop (void *rule, struct prefix *prefix,
  630.       route_map_object_t type, void *object)
  631. {
  632.   struct rmap_ip_nexthop_set *rins = rule;
  633.   struct in_addr peer_address;
  634.   struct bgp_info *bgp_info;
  635.   struct peer *peer;
  636.   if (type == RMAP_BGP)
  637.     {
  638.       bgp_info = object;
  639.       peer = bgp_info->peer;
  640.       if (rins->peer_address)
  641. {
  642.   if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) 
  643.       && peer->su_remote 
  644.       && sockunion_family (peer->su_remote) == AF_INET)
  645.     {
  646.               inet_aton (sockunion_su2str (peer->su_remote), &peer_address);
  647.               bgp_info->attr->nexthop = peer_address;
  648.       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
  649.     }
  650.   else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
  651.    && peer->su_local
  652.    && sockunion_family (peer->su_local) == AF_INET)
  653.     {
  654.               inet_aton (sockunion_su2str (peer->su_local), &peer_address);
  655.               bgp_info->attr->nexthop = peer_address;
  656.       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
  657.     }
  658. }
  659.       else
  660. {
  661.   /* Set next hop value. */ 
  662.   bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
  663.   bgp_info->attr->nexthop = *rins->address;
  664. }
  665.     }
  666.   return RMAP_OKAY;
  667. }
  668. /* Route map `ip nexthop' compile function.  Given string is converted
  669.    to struct in_addr structure. */
  670. void *
  671. route_set_ip_nexthop_compile (char *arg)
  672. {
  673.   struct rmap_ip_nexthop_set *rins;
  674.   struct in_addr *address = NULL;
  675.   int peer_address = 0;
  676.   int ret;
  677.   if (strcmp (arg, "peer-address") == 0)
  678.     peer_address = 1;
  679.   else
  680.     {
  681.       address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
  682.       ret = inet_aton (arg, address);
  683.       if (ret == 0)
  684. {
  685.   XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
  686.   return NULL;
  687. }
  688.     }
  689.   rins = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
  690.   memset (rins, 0, sizeof (struct rmap_ip_nexthop_set));
  691.   rins->address = address;
  692.   rins->peer_address = peer_address;
  693.   return rins;
  694. }
  695. /* Free route map's compiled `ip nexthop' value. */
  696. void
  697. route_set_ip_nexthop_free (void *rule)
  698. {
  699.   struct rmap_ip_nexthop_set *rins = rule;
  700.   if (rins->address)
  701.     XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
  702.     
  703.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
  704. }
  705. /* Route map commands for ip nexthop set. */
  706. struct route_map_rule_cmd route_set_ip_nexthop_cmd =
  707. {
  708.   "ip next-hop",
  709.   route_set_ip_nexthop,
  710.   route_set_ip_nexthop_compile,
  711.   route_set_ip_nexthop_free
  712. };
  713. /* `set local-preference LOCAL_PREF' */
  714. /* Set local preference. */
  715. route_map_result_t
  716. route_set_local_pref (void *rule, struct prefix *prefix,
  717.       route_map_object_t type, void *object)
  718. {
  719.   u_int32_t *local_pref;
  720.   struct bgp_info *bgp_info;
  721.   if (type == RMAP_BGP)
  722.     {
  723.       /* Fetch routemap's rule information. */
  724.       local_pref = rule;
  725.       bgp_info = object;
  726.     
  727.       /* Set local preference value. */ 
  728.       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
  729.       bgp_info->attr->local_pref = *local_pref;
  730.     }
  731.   return RMAP_OKAY;
  732. }
  733. /* set local preference compilation. */
  734. void *
  735. route_set_local_pref_compile (char *arg)
  736. {
  737.   u_int32_t *local_pref;
  738.   char *endptr = NULL;
  739.   /* Local preference value shoud be integer. */
  740.   if (! all_digit (arg))
  741.     return NULL;
  742.   local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
  743.   *local_pref = strtoul (arg, &endptr, 10);
  744.   if (*endptr != '' || *local_pref == ULONG_MAX)
  745.     {
  746.       XFREE (MTYPE_ROUTE_MAP_COMPILED, local_pref);
  747.       return NULL;
  748.     }
  749.   return local_pref;
  750. }
  751. /* Free route map's local preference value. */
  752. void
  753. route_set_local_pref_free (void *rule)
  754. {
  755.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  756. }
  757. /* Set local preference rule structure. */
  758. struct route_map_rule_cmd route_set_local_pref_cmd = 
  759. {
  760.   "local-preference",
  761.   route_set_local_pref,
  762.   route_set_local_pref_compile,
  763.   route_set_local_pref_free,
  764. };
  765. /* `set weight WEIGHT' */
  766. /* Set weight. */
  767. route_map_result_t
  768. route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
  769.   void *object)
  770. {
  771.   u_int16_t *weight;
  772.   struct bgp_info *bgp_info;
  773.   if (type == RMAP_BGP)
  774.     {
  775.       /* Fetch routemap's rule information. */
  776.       weight = rule;
  777.       bgp_info = object;
  778.     
  779.       /* Set weight value. */ 
  780.       bgp_info->attr->weight = *weight;
  781.     }
  782.   return RMAP_OKAY;
  783. }
  784. /* set local preference compilation. */
  785. void *
  786. route_set_weight_compile (char *arg)
  787. {
  788.   u_int16_t *weight;
  789.   char *endptr = NULL;
  790.   /* Local preference value shoud be integer. */
  791.   if (! all_digit (arg))
  792.     return NULL;
  793.   weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int16_t));
  794.   *weight = strtoul (arg, &endptr, 10);
  795.   if (*endptr != '' || *weight == ULONG_MAX)
  796.     {
  797.       XFREE (MTYPE_ROUTE_MAP_COMPILED, weight);
  798.       return NULL;
  799.     }
  800.   return weight;
  801. }
  802. /* Free route map's local preference value. */
  803. void
  804. route_set_weight_free (void *rule)
  805. {
  806.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  807. }
  808. /* Set local preference rule structure. */
  809. struct route_map_rule_cmd route_set_weight_cmd = 
  810. {
  811.   "weight",
  812.   route_set_weight,
  813.   route_set_weight_compile,
  814.   route_set_weight_free,
  815. };
  816. /* `set metric METRIC' */
  817. /* Set metric to attribute. */
  818. route_map_result_t
  819. route_set_metric (void *rule, struct prefix *prefix, 
  820.   route_map_object_t type, void *object)
  821. {
  822.   char *metric;
  823.   u_int32_t metric_val;
  824.   struct bgp_info *bgp_info;
  825.   if (type == RMAP_BGP)
  826.     {
  827.       /* Fetch routemap's rule information. */
  828.       metric = rule;
  829.       bgp_info = object;
  830.       if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
  831. bgp_info->attr->med = 0;
  832.       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
  833.       if (all_digit (metric))
  834. {
  835.   metric_val = strtoul (metric, (char **)NULL, 10);
  836.   bgp_info->attr->med = metric_val;
  837. }
  838.       else
  839. {
  840.   metric_val = strtoul (metric+1, (char **)NULL, 10);
  841.   if (strncmp (metric, "+", 1) == 0)
  842.     {
  843.       if (bgp_info->attr->med/2 + metric_val/2 > ULONG_MAX/2)
  844. bgp_info->attr->med = ULONG_MAX-1;
  845.       else
  846. bgp_info->attr->med += metric_val;
  847.     }
  848.   else if (strncmp (metric, "-", 1) == 0)
  849.     {
  850.       if (bgp_info->attr->med <= metric_val) 
  851. bgp_info->attr->med = 0;
  852.       else
  853. bgp_info->attr->med -= metric_val;
  854.     }
  855. }
  856.     }
  857.   return RMAP_OKAY;
  858. }
  859. /* set metric compilation. */
  860. void *
  861. route_set_metric_compile (char *arg)
  862. {
  863.   u_int32_t metric;
  864.   char *endptr = NULL;
  865.   if (all_digit (arg))
  866.     {
  867.       /* set metric value check*/
  868.       metric = strtoul (arg, &endptr, 10);
  869.       if (*endptr != '' || metric == ULONG_MAX)
  870.         return NULL;
  871.     }
  872.   else
  873.     {
  874.       /* set metric +/-value check */
  875.       if ((strncmp (arg, "+", 1) != 0
  876.    && strncmp (arg, "-", 1) != 0)
  877.    || (! all_digit (arg+1)))
  878. return NULL;
  879.       metric = strtoul (arg+1, &endptr, 10);
  880.       if (*endptr != '' || metric == ULONG_MAX)
  881. return NULL;
  882.     }
  883.   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  884. }
  885. /* Free route map's compiled `set metric' value. */
  886. void
  887. route_set_metric_free (void *rule)
  888. {
  889.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  890. }
  891. /* Set metric rule structure. */
  892. struct route_map_rule_cmd route_set_metric_cmd = 
  893. {
  894.   "metric",
  895.   route_set_metric,
  896.   route_set_metric_compile,
  897.   route_set_metric_free,
  898. };
  899. /* `set as-path prepend ASPATH' */
  900. /* For AS path prepend mechanism. */
  901. route_map_result_t
  902. route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
  903. {
  904.   struct aspath *aspath;
  905.   struct aspath *new;
  906.   struct bgp_info *binfo;
  907.   if (type == RMAP_BGP)
  908.     {
  909.       aspath = rule;
  910.       binfo = object;
  911.     
  912.       if (binfo->attr->aspath->refcnt)
  913. new = aspath_dup (binfo->attr->aspath);
  914.       else
  915. new = binfo->attr->aspath;
  916.       aspath_prepend (aspath, new);
  917.       binfo->attr->aspath = new;
  918.     }
  919.   return RMAP_OKAY;
  920. }
  921. /* Compile function for as-path prepend. */
  922. void *
  923. route_set_aspath_prepend_compile (char *arg)
  924. {
  925.   struct aspath *aspath;
  926.   aspath = aspath_str2aspath (arg);
  927.   if (! aspath)
  928.     return NULL;
  929.   return aspath;
  930. }
  931. /* Compile function for as-path prepend. */
  932. void
  933. route_set_aspath_prepend_free (void *rule)
  934. {
  935.   struct aspath *aspath = rule;
  936.   aspath_free (aspath);
  937. }
  938. /* Set metric rule structure. */
  939. struct route_map_rule_cmd route_set_aspath_prepend_cmd = 
  940. {
  941.   "as-path prepend",
  942.   route_set_aspath_prepend,
  943.   route_set_aspath_prepend_compile,
  944.   route_set_aspath_prepend_free,
  945. };
  946. /* `set community COMMUNITY' */
  947. struct rmap_com_set
  948. {
  949.   struct community *com;
  950.   int additive;
  951.   int none;
  952. };
  953. /* For community set mechanism. */
  954. route_map_result_t
  955. route_set_community (void *rule, struct prefix *prefix,
  956.      route_map_object_t type, void *object)
  957. {
  958.   struct rmap_com_set *rcs;
  959.   struct bgp_info *binfo;
  960.   struct attr *attr;
  961.   struct community *new = NULL;
  962.   struct community *old;
  963.   struct community *merge;
  964.   if (type == RMAP_BGP)
  965.     {
  966.       rcs = rule;
  967.       binfo = object;
  968.       attr = binfo->attr;
  969.       old = attr->community;
  970.       /* "none" case.  */
  971.       if (rcs->none)
  972. {
  973.   attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
  974.   attr->community = NULL;
  975.   return RMAP_OKAY;
  976. }
  977.       /* "additive" case.  */
  978.       if (rcs->additive && old)
  979. {
  980.   merge = community_merge (community_dup (old), rcs->com);
  981.   new = community_uniq_sort (merge);
  982.   community_free (merge);
  983. }
  984.       else
  985. new = community_dup (rcs->com);
  986.       attr->community = new;
  987.       attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
  988.     }
  989.   return RMAP_OKAY;
  990. }
  991. /* Compile function for set community. */
  992. void *
  993. route_set_community_compile (char *arg)
  994. {
  995.   struct rmap_com_set *rcs;
  996.   struct community *com = NULL;
  997.   char *sp;
  998.   int additive = 0;
  999.   int none = 0;
  1000.   
  1001.   if (strcmp (arg, "none") == 0)
  1002.     none = 1;
  1003.   else
  1004.     {
  1005.       sp = strstr (arg, "additive");
  1006.       if (sp && sp > arg)
  1007.    {
  1008.   /* "additive" keyworkd is included.  */
  1009.   additive = 1;
  1010.   *(sp - 1) = '';
  1011. }
  1012.       com = community_str2com (arg);
  1013.       if (additive)
  1014. *(sp - 1) = ' ';
  1015.       if (! com)
  1016. return NULL;
  1017.     }
  1018.   
  1019.   rcs = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
  1020.   memset (rcs, 0, sizeof (struct rmap_com_set));
  1021.   
  1022.   rcs->com = com;
  1023.   rcs->additive = additive;
  1024.   rcs->none = none;
  1025.   
  1026.   return rcs;
  1027. }
  1028. /* Free function for set community. */
  1029. void
  1030. route_set_community_free (void *rule)
  1031. {
  1032.   struct rmap_com_set *rcs = rule;
  1033.   if (rcs->com)
  1034.     community_free (rcs->com);
  1035.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
  1036. }
  1037. /* Set community rule structure. */
  1038. struct route_map_rule_cmd route_set_community_cmd = 
  1039. {
  1040.   "community",
  1041.   route_set_community,
  1042.   route_set_community_compile,
  1043.   route_set_community_free,
  1044. };
  1045. /* `set comm-list (<1-99>|<100-500>|WORD) delete' */
  1046. /* For community set mechanism. */
  1047. route_map_result_t
  1048. route_set_community_delete (void *rule, struct prefix *prefix,
  1049.     route_map_object_t type, void *object)
  1050. {
  1051.   struct community_list *list;
  1052.   struct community *merge;
  1053.   struct community *new;
  1054.   struct community *old;
  1055.   struct bgp_info *binfo;
  1056.   if (type == RMAP_BGP)
  1057.     {
  1058.       if (! rule)
  1059. return RMAP_OKAY;
  1060.       binfo = object;
  1061.       list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
  1062.       old = binfo->attr->community;
  1063.       if (list && old)
  1064. {
  1065.   merge = community_list_match_delete (old, list);
  1066.   new = community_uniq_sort (merge);
  1067.   community_free (merge);
  1068.   if (new->size == 0)
  1069.     {
  1070.       binfo->attr->community = NULL;
  1071.       binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
  1072.       community_free (new);
  1073.     }
  1074.   else
  1075.     {
  1076.       binfo->attr->community = new;
  1077.       binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
  1078.     }
  1079. }
  1080.     }
  1081.   return RMAP_OKAY;
  1082. }
  1083. /* Compile function for set community. */
  1084. void *
  1085. route_set_community_delete_compile (char *arg)
  1086. {
  1087.   char *p;
  1088.   char *str;
  1089.   int len;
  1090.   p = strchr (arg, ' ');
  1091.   if (p)
  1092.     {
  1093.       len = p - arg;
  1094.       str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
  1095.       memcpy (str, arg, len);
  1096.     }
  1097.   else
  1098.     str = NULL;
  1099.   return str;
  1100. }
  1101. /* Free function for set community. */
  1102. void
  1103. route_set_community_delete_free (void *rule)
  1104. {
  1105.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  1106. }
  1107. /* Set community rule structure. */
  1108. struct route_map_rule_cmd route_set_community_delete_cmd =
  1109. {
  1110.   "comm-list",
  1111.   route_set_community_delete,
  1112.   route_set_community_delete_compile,
  1113.   route_set_community_delete_free,
  1114. };
  1115. /* `set extcommunity rt COMMUNITY' */
  1116. /* For community set mechanism. */
  1117. route_map_result_t
  1118. route_set_ecommunity_rt (void *rule, struct prefix *prefix, 
  1119.  route_map_object_t type, void *object)
  1120. {
  1121.   struct ecommunity *ecom;
  1122.   struct ecommunity *new_ecom;
  1123.   struct ecommunity *old_ecom;
  1124.   struct bgp_info *bgp_info;
  1125.   if (type == RMAP_BGP)
  1126.     {
  1127.       ecom = rule;
  1128.       bgp_info = object;
  1129.     
  1130.       if (! ecom)
  1131. return RMAP_OKAY;
  1132.     
  1133.       /* We assume additive for Extended Community. */
  1134.       old_ecom = bgp_info->attr->ecommunity;
  1135.       if (old_ecom)
  1136. new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
  1137.       else
  1138. new_ecom = ecommunity_dup (ecom);
  1139.       bgp_info->attr->ecommunity = new_ecom;
  1140.       if (old_ecom)
  1141. ecommunity_free (old_ecom);
  1142.       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
  1143.     }
  1144.   return RMAP_OKAY;
  1145. }
  1146. /* Compile function for set community. */
  1147. void *
  1148. route_set_ecommunity_rt_compile (char *arg)
  1149. {
  1150.   struct ecommunity *ecom;
  1151.   ecom = ecommunity_str2com (arg, ECOMMUNITY_TYPE_ROUTE_TARGET, 0);
  1152.   if (! ecom)
  1153.     return NULL;
  1154.   return ecom;
  1155. }
  1156. /* Free function for set community. */
  1157. void
  1158. route_set_ecommunity_rt_free (void *rule)
  1159. {
  1160.   struct ecommunity *ecom = rule;
  1161.   ecommunity_free (ecom);
  1162. }
  1163. /* Set community rule structure. */
  1164. struct route_map_rule_cmd route_set_ecommunity_rt_cmd = 
  1165. {
  1166.   "extcommunity rt",
  1167.   route_set_ecommunity_rt,
  1168.   route_set_ecommunity_rt_compile,
  1169.   route_set_ecommunity_rt_free,
  1170. };
  1171. /* `set extcommunity soo COMMUNITY' */
  1172. /* For community set mechanism. */
  1173. route_map_result_t
  1174. route_set_ecommunity_soo (void *rule, struct prefix *prefix, 
  1175.  route_map_object_t type, void *object)
  1176. {
  1177.   struct ecommunity *ecom;
  1178.   struct ecommunity *new_ecom;
  1179.   struct ecommunity *old_ecom;
  1180.   struct bgp_info *bgp_info;
  1181.   if (type == RMAP_BGP)
  1182.     {
  1183.       ecom = rule;
  1184.       bgp_info = object;
  1185.     
  1186.       if (! ecom)
  1187. return RMAP_OKAY;
  1188.       /* We assume additive for Extended Community. */
  1189.       old_ecom = bgp_info->attr->ecommunity;
  1190.       if (old_ecom)
  1191.         new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
  1192.       else
  1193.         new_ecom = ecommunity_dup (ecom);
  1194.       bgp_info->attr->ecommunity = new_ecom;
  1195.       if (old_ecom)
  1196. ecommunity_free (old_ecom);
  1197.       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
  1198.     }
  1199.   return RMAP_OKAY;
  1200. }
  1201. /* Compile function for set community. */
  1202. void *
  1203. route_set_ecommunity_soo_compile (char *arg)
  1204. {
  1205.   struct ecommunity *ecom;
  1206.   ecom = ecommunity_str2com (arg, ECOMMUNITY_TYPE_SITE_ORIGIN, 0);
  1207.   if (! ecom)
  1208.     return NULL;
  1209.   
  1210.   return ecom;
  1211. }
  1212. /* Free function for set community. */
  1213. void
  1214. route_set_ecommunity_soo_free (void *rule)
  1215. {
  1216.   struct ecommunity *ecom = rule;
  1217.   ecommunity_free (ecom);
  1218. }
  1219. /* Set community rule structure. */
  1220. struct route_map_rule_cmd route_set_ecommunity_soo_cmd = 
  1221. {
  1222.   "extcommunity soo",
  1223.   route_set_ecommunity_soo,
  1224.   route_set_ecommunity_soo_compile,
  1225.   route_set_ecommunity_soo_free,
  1226. };
  1227. /* `set extcommunity cost igp COMMUNITY' */
  1228. /* For community set mechanism. */
  1229. route_map_result_t
  1230. route_set_ecommunity_cost_igp (void *rule, struct prefix *prefix, 
  1231.        route_map_object_t type, void *object)
  1232. {
  1233.   struct ecommunity *ecom;
  1234.   struct ecommunity *new_ecom;
  1235.   struct ecommunity *old_ecom;
  1236.   struct bgp_info *bgp_info;
  1237.   if (type == RMAP_BGP)
  1238.     {
  1239.       ecom = rule;
  1240.       bgp_info = object;
  1241.     
  1242.       if (! ecom)
  1243. return RMAP_OKAY;
  1244.     
  1245.       /* We assume additive for Extended Community. */
  1246.       old_ecom = bgp_info->attr->ecommunity;
  1247.       if (old_ecom)
  1248. new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
  1249.       else
  1250. new_ecom = ecommunity_dup (ecom);
  1251.       bgp_info->attr->ecommunity = new_ecom;
  1252.       if (old_ecom)
  1253. ecommunity_free (old_ecom);
  1254.       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
  1255.     }
  1256.   return RMAP_OKAY;
  1257. }
  1258. /* Compile function for set community. */
  1259. void *
  1260. route_set_ecommunity_cost_igp_compile (char *arg)
  1261. {
  1262.   struct ecommunity *ecom;
  1263.   ecom = ecommunity_cost_str2com (arg, ECOMMUNITY_COST_POI_IGP);
  1264.   if (! ecom)
  1265.     return NULL;
  1266.   return ecom;
  1267. }
  1268. /* Free function for set community. */
  1269. void
  1270. route_set_ecommunity_cost_igp_free (void *rule)
  1271. {
  1272.   struct ecommunity *ecom = rule;
  1273.   ecommunity_free (ecom);
  1274. }
  1275. /* Set community rule structure. */
  1276. struct route_map_rule_cmd route_set_ecommunity_cost_igp_cmd = 
  1277. {
  1278.   "extcommunity cost igp",
  1279.   route_set_ecommunity_cost_igp,
  1280.   route_set_ecommunity_cost_igp_compile,
  1281.   route_set_ecommunity_cost_igp_free,
  1282. };
  1283. /* `set origin ORIGIN' */
  1284. /* For origin set. */
  1285. route_map_result_t
  1286. route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
  1287. {
  1288.   u_char *origin;
  1289.   struct bgp_info *bgp_info;
  1290.   if (type == RMAP_BGP)
  1291.     {
  1292.       origin = rule;
  1293.       bgp_info = object;
  1294.     
  1295.       bgp_info->attr->origin = *origin;
  1296.     }
  1297.   return RMAP_OKAY;
  1298. }
  1299. /* Compile function for origin set. */
  1300. void *
  1301. route_set_origin_compile (char *arg)
  1302. {
  1303.   u_char *origin;
  1304.   origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
  1305.   if (strcmp (arg, "igp") == 0)
  1306.     *origin = 0;
  1307.   else if (strcmp (arg, "egp") == 0)
  1308.     *origin = 1;
  1309.   else
  1310.     *origin = 2;
  1311.   return origin;
  1312. }
  1313. /* Compile function for origin set. */
  1314. void
  1315. route_set_origin_free (void *rule)
  1316. {
  1317.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  1318. }
  1319. /* Set metric rule structure. */
  1320. struct route_map_rule_cmd route_set_origin_cmd = 
  1321. {
  1322.   "origin",
  1323.   route_set_origin,
  1324.   route_set_origin_compile,
  1325.   route_set_origin_free,
  1326. };
  1327. /* `set atomic-aggregate' */
  1328. /* For atomic aggregate set. */
  1329. route_map_result_t
  1330. route_set_atomic_aggregate (void *rule, struct prefix *prefix,
  1331.     route_map_object_t type, void *object)
  1332. {
  1333.   struct bgp_info *bgp_info;
  1334.   if (type == RMAP_BGP)
  1335.     {
  1336.       bgp_info = object;
  1337.       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
  1338.     }
  1339.   return RMAP_OKAY;
  1340. }
  1341. /* Compile function for atomic aggregate. */
  1342. void *
  1343. route_set_atomic_aggregate_compile (char *arg)
  1344. {
  1345.   return (void *)1;
  1346. }
  1347. /* Compile function for atomic aggregate. */
  1348. void
  1349. route_set_atomic_aggregate_free (void *rule)
  1350. {
  1351.   return;
  1352. }
  1353. /* Set atomic aggregate rule structure. */
  1354. struct route_map_rule_cmd route_set_atomic_aggregate_cmd = 
  1355. {
  1356.   "atomic-aggregate",
  1357.   route_set_atomic_aggregate,
  1358.   route_set_atomic_aggregate_compile,
  1359.   route_set_atomic_aggregate_free,
  1360. };
  1361. /* `set aggregator as AS A.B.C.D' */
  1362. struct aggregator
  1363. {
  1364.   as_t as;
  1365.   struct in_addr address;
  1366. };
  1367. route_map_result_t
  1368. route_set_aggregator_as (void *rule, struct prefix *prefix, 
  1369.  route_map_object_t type, void *object)
  1370. {
  1371.   struct bgp_info *bgp_info;
  1372.   struct aggregator *aggregator;
  1373.   if (type == RMAP_BGP)
  1374.     {
  1375.       bgp_info = object;
  1376.       aggregator = rule;
  1377.     
  1378.       bgp_info->attr->aggregator_as = aggregator->as;
  1379.       bgp_info->attr->aggregator_addr = aggregator->address;
  1380.       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
  1381.     }
  1382.   return RMAP_OKAY;
  1383. }
  1384. void *
  1385. route_set_aggregator_as_compile (char *arg)
  1386. {
  1387.   struct aggregator *aggregator;
  1388.   char as[10];
  1389.   char address[20];
  1390.   aggregator = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
  1391.   memset (aggregator, 0, sizeof (struct aggregator));
  1392.   sscanf (arg, "%s %s", as, address);
  1393.   aggregator->as = strtoul (as, NULL, 10);
  1394.   inet_aton (address, &aggregator->address);
  1395.   return aggregator;
  1396. }
  1397. void
  1398. route_set_aggregator_as_free (void *rule)
  1399. {
  1400.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  1401. }
  1402. struct route_map_rule_cmd route_set_aggregator_as_cmd = 
  1403. {
  1404.   "aggregator as",
  1405.   route_set_aggregator_as,
  1406.   route_set_aggregator_as_compile,
  1407.   route_set_aggregator_as_free,
  1408. };
  1409. #ifdef HAVE_IPV6
  1410. /* `match ipv6 address IP_ACCESS_LIST' */
  1411. route_map_result_t
  1412. route_match_ipv6_address (void *rule, struct prefix *prefix, 
  1413.   route_map_object_t type, void *object)
  1414. {
  1415.   struct access_list *alist;
  1416.   if (type == RMAP_BGP)
  1417.     {
  1418.       alist = access_list_lookup (AFI_IP6, (char *) rule);
  1419.       if (alist == NULL)
  1420. return RMAP_NOMATCH;
  1421.     
  1422.       return (access_list_apply (alist, prefix) == FILTER_DENY ?
  1423.       RMAP_NOMATCH : RMAP_MATCH);
  1424.     }
  1425.   return RMAP_NOMATCH;
  1426. }
  1427. void *
  1428. route_match_ipv6_address_compile (char *arg)
  1429. {
  1430.   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  1431. }
  1432. void
  1433. route_match_ipv6_address_free (void *rule)
  1434. {
  1435.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  1436. }
  1437. /* Route map commands for ip address matching. */
  1438. struct route_map_rule_cmd route_match_ipv6_address_cmd =
  1439. {
  1440.   "ipv6 address",
  1441.   route_match_ipv6_address,
  1442.   route_match_ipv6_address_compile,
  1443.   route_match_ipv6_address_free
  1444. };
  1445. /* `match ipv6 next-hop IP_ADDRESS' */
  1446. route_map_result_t
  1447. route_match_ipv6_next_hop (void *rule, struct prefix *prefix, 
  1448.    route_map_object_t type, void *object)
  1449. {
  1450.   struct in6_addr *addr;
  1451.   struct bgp_info *bgp_info;
  1452.   if (type == RMAP_BGP)
  1453.     {
  1454.       addr = rule;
  1455.       bgp_info = object;
  1456.     
  1457.       if (IPV6_ADDR_SAME (&bgp_info->attr->mp_nexthop_global, rule))
  1458. return RMAP_MATCH;
  1459.       if (bgp_info->attr->mp_nexthop_len == 32 &&
  1460.   IPV6_ADDR_SAME (&bgp_info->attr->mp_nexthop_local, rule))
  1461. return RMAP_MATCH;
  1462.       return RMAP_NOMATCH;
  1463.     }
  1464.   return RMAP_NOMATCH;
  1465. }
  1466. void *
  1467. route_match_ipv6_next_hop_compile (char *arg)
  1468. {
  1469.   struct in6_addr *address;
  1470.   int ret;
  1471.   address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
  1472.   ret = inet_pton (AF_INET6, arg, address);
  1473.   if (!ret)
  1474.     {
  1475.       XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
  1476.       return NULL;
  1477.     }
  1478.   return address;
  1479. }
  1480. void
  1481. route_match_ipv6_next_hop_free (void *rule)
  1482. {
  1483.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  1484. }
  1485. struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
  1486. {
  1487.   "ipv6 next-hop",
  1488.   route_match_ipv6_next_hop,
  1489.   route_match_ipv6_next_hop_compile,
  1490.   route_match_ipv6_next_hop_free
  1491. };
  1492. /* `match ipv6 address prefix-list PREFIX_LIST' */
  1493. route_map_result_t
  1494. route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix, 
  1495.       route_map_object_t type, void *object)
  1496. {
  1497.   struct prefix_list *plist;
  1498.   if (type == RMAP_BGP)
  1499.     {
  1500.       plist = prefix_list_lookup (AFI_IP6, (char *) rule);
  1501.       if (plist == NULL)
  1502. return RMAP_NOMATCH;
  1503.     
  1504.       return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
  1505.       RMAP_NOMATCH : RMAP_MATCH);
  1506.     }
  1507.   return RMAP_NOMATCH;
  1508. }
  1509. void *
  1510. route_match_ipv6_address_prefix_list_compile (char *arg)
  1511. {
  1512.   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  1513. }
  1514. void
  1515. route_match_ipv6_address_prefix_list_free (void *rule)
  1516. {
  1517.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  1518. }
  1519. struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
  1520. {
  1521.   "ipv6 address prefix-list",
  1522.   route_match_ipv6_address_prefix_list,
  1523.   route_match_ipv6_address_prefix_list_compile,
  1524.   route_match_ipv6_address_prefix_list_free
  1525. };
  1526. /* `set ipv6 nexthop global IP_ADDRESS' */
  1527. /* Set nexthop to object.  ojbect must be pointer to struct attr. */
  1528. route_map_result_t
  1529. route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix, 
  1530.        route_map_object_t type, void *object)
  1531. {
  1532.   struct in6_addr *address;
  1533.   struct bgp_info *bgp_info;
  1534.   if (type == RMAP_BGP)
  1535.     {
  1536.       /* Fetch routemap's rule information. */
  1537.       address = rule;
  1538.       bgp_info = object;
  1539.     
  1540.       /* Set next hop value. */ 
  1541.       bgp_info->attr->mp_nexthop_global = *address;
  1542.     
  1543.       /* Set nexthop length. */
  1544.       if (bgp_info->attr->mp_nexthop_len == 0)
  1545. bgp_info->attr->mp_nexthop_len = 16;
  1546.     }
  1547.   return RMAP_OKAY;
  1548. }
  1549. /* Route map `ip next-hop' compile function.  Given string is converted
  1550.    to struct in_addr structure. */
  1551. void *
  1552. route_set_ipv6_nexthop_global_compile (char *arg)
  1553. {
  1554.   int ret;
  1555.   struct in6_addr *address;
  1556.   address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
  1557.   ret = inet_pton (AF_INET6, arg, address);
  1558.   if (ret == 0)
  1559.     {
  1560.       XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
  1561.       return NULL;
  1562.     }
  1563.   return address;
  1564. }
  1565. /* Free route map's compiled `ip next-hop' value. */
  1566. void
  1567. route_set_ipv6_nexthop_global_free (void *rule)
  1568. {
  1569.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  1570. }
  1571. /* Route map commands for ip nexthop set. */
  1572. struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
  1573. {
  1574.   "ipv6 next-hop global",
  1575.   route_set_ipv6_nexthop_global,
  1576.   route_set_ipv6_nexthop_global_compile,
  1577.   route_set_ipv6_nexthop_global_free
  1578. };
  1579. /* `set ipv6 nexthop local IP_ADDRESS' */
  1580. /* Set nexthop to object.  ojbect must be pointer to struct attr. */
  1581. route_map_result_t
  1582. route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix, 
  1583.       route_map_object_t type, void *object)
  1584. {
  1585.   struct in6_addr *address;
  1586.   struct bgp_info *bgp_info;
  1587.   if (type == RMAP_BGP)
  1588.     {
  1589.       /* Fetch routemap's rule information. */
  1590.       address = rule;
  1591.       bgp_info = object;
  1592.     
  1593.       /* Set next hop value. */ 
  1594.       bgp_info->attr->mp_nexthop_local = *address;
  1595.     
  1596.       /* Set nexthop length. */
  1597.       if (bgp_info->attr->mp_nexthop_len != 32)
  1598. bgp_info->attr->mp_nexthop_len = 32;
  1599.     }
  1600.   return RMAP_OKAY;
  1601. }
  1602. /* Route map `ip nexthop' compile function.  Given string is converted
  1603.    to struct in_addr structure. */
  1604. void *
  1605. route_set_ipv6_nexthop_local_compile (char *arg)
  1606. {
  1607.   int ret;
  1608.   struct in6_addr *address;
  1609.   address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
  1610.   ret = inet_pton (AF_INET6, arg, address);
  1611.   if (ret == 0)
  1612.     {
  1613.       XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
  1614.       return NULL;
  1615.     }
  1616.   return address;
  1617. }
  1618. /* Free route map's compiled `ip nexthop' value. */
  1619. void
  1620. route_set_ipv6_nexthop_local_free (void *rule)
  1621. {
  1622.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  1623. }
  1624. /* Route map commands for ip nexthop set. */
  1625. struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
  1626. {
  1627.   "ipv6 next-hop local",
  1628.   route_set_ipv6_nexthop_local,
  1629.   route_set_ipv6_nexthop_local_compile,
  1630.   route_set_ipv6_nexthop_local_free
  1631. };
  1632. #endif /* HAVE_IPV6 */
  1633. /* `set vpnv4 nexthop A.B.C.D' */
  1634. route_map_result_t
  1635. route_set_vpnv4_nexthop (void *rule, struct prefix *prefix, 
  1636.  route_map_object_t type, void *object)
  1637. {
  1638.   struct in_addr *address;
  1639.   struct bgp_info *bgp_info;
  1640.   if (type == RMAP_BGP)
  1641.     {
  1642.       /* Fetch routemap's rule information. */
  1643.       address = rule;
  1644.       bgp_info = object;
  1645.     
  1646.       /* Set next hop value. */ 
  1647.       bgp_info->attr->mp_nexthop_global_in = *address;
  1648.     }
  1649.   return RMAP_OKAY;
  1650. }
  1651. void *
  1652. route_set_vpnv4_nexthop_compile (char *arg)
  1653. {
  1654.   int ret;
  1655.   struct in_addr *address;
  1656.   address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
  1657.   ret = inet_aton (arg, address);
  1658.   if (ret == 0)
  1659.     {
  1660.       XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
  1661.       return NULL;
  1662.     }
  1663.   return address;
  1664. }
  1665. void
  1666. route_set_vpnv4_nexthop_free (void *rule)
  1667. {
  1668.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  1669. }
  1670. /* Route map commands for ip nexthop set. */
  1671. struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
  1672. {
  1673.   "vpnv4 next-hop",
  1674.   route_set_vpnv4_nexthop,
  1675.   route_set_vpnv4_nexthop_compile,
  1676.   route_set_vpnv4_nexthop_free
  1677. };
  1678. /* `set originator-id' */
  1679. /* For origin set. */
  1680. route_map_result_t
  1681. route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
  1682. {
  1683.   struct in_addr *address;
  1684.   struct bgp_info *bgp_info;
  1685.   if (type == RMAP_BGP) 
  1686.     {
  1687.       address = rule;
  1688.       bgp_info = object;
  1689.     
  1690.       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
  1691.       bgp_info->attr->originator_id = *address;
  1692.     }
  1693.   return RMAP_OKAY;
  1694. }
  1695. /* Compile function for originator-id set. */
  1696. void *
  1697. route_set_originator_id_compile (char *arg)
  1698. {
  1699.   int ret;
  1700.   struct in_addr *address;
  1701.   address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
  1702.   ret = inet_aton (arg, address);
  1703.   if (ret == 0)
  1704.     {
  1705.       XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
  1706.       return NULL;
  1707.     }
  1708.   return address;
  1709. }
  1710. /* Compile function for originator_id set. */
  1711. void
  1712. route_set_originator_id_free (void *rule)
  1713. {
  1714.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  1715. }
  1716. /* Set metric rule structure. */
  1717. struct route_map_rule_cmd route_set_originator_id_cmd = 
  1718. {
  1719.   "originator-id",
  1720.   route_set_originator_id,
  1721.   route_set_originator_id_compile,
  1722.   route_set_originator_id_free,
  1723. };
  1724. /* Add bgp route map rule. */
  1725. int
  1726. bgp_route_match_add (struct vty *vty, struct route_map_index *index,
  1727.     char *command, char *arg)
  1728. {
  1729.   int ret;
  1730.   ret = route_map_add_match (index, command, arg);
  1731.   if (ret)
  1732.     {
  1733.       switch (ret)
  1734. {
  1735. case RMAP_RULE_MISSING:
  1736.   vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
  1737.   return CMD_WARNING;
  1738.   break;
  1739. case RMAP_COMPILE_ERROR:
  1740.   vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
  1741.   return CMD_WARNING;
  1742.   break;
  1743. }
  1744.     }
  1745.   return CMD_SUCCESS;
  1746. }
  1747. /* Delete bgp route map rule. */
  1748. int
  1749. bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
  1750. char *command, char *arg)
  1751. {
  1752.   int ret;
  1753.   ret = route_map_delete_match (index, command, arg);
  1754.   if (ret)
  1755.     {
  1756.       switch (ret)
  1757. {
  1758. case RMAP_RULE_MISSING:
  1759.   vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
  1760.   return CMD_WARNING;
  1761.   break;
  1762. case RMAP_COMPILE_ERROR:
  1763.   vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
  1764.   return CMD_WARNING;
  1765.   break;
  1766. }
  1767.     }
  1768.   return CMD_SUCCESS;
  1769. }
  1770. /* Add bgp route map rule. */
  1771. int
  1772. bgp_route_set_add (struct vty *vty, struct route_map_index *index,
  1773.    char *command, char *arg)
  1774. {
  1775.   int ret;
  1776.   ret = route_map_add_set (index, command, arg);
  1777.   if (ret)
  1778.     {
  1779.       switch (ret)
  1780. {
  1781. case RMAP_RULE_MISSING:
  1782.   vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
  1783.   return CMD_WARNING;
  1784.   break;
  1785. case RMAP_COMPILE_ERROR:
  1786.   vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
  1787.   return CMD_WARNING;
  1788.   break;
  1789. }
  1790.     }
  1791.   return CMD_SUCCESS;
  1792. }
  1793. /* Delete bgp route map rule. */
  1794. int
  1795. bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
  1796.       char *command, char *arg)
  1797. {
  1798.   int ret;
  1799.   ret = route_map_delete_set (index, command, arg);
  1800.   if (ret)
  1801.     {
  1802.       switch (ret)
  1803. {
  1804. case RMAP_RULE_MISSING:
  1805.   vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
  1806.   return CMD_WARNING;
  1807.   break;
  1808. case RMAP_COMPILE_ERROR:
  1809.   vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
  1810.   return CMD_WARNING;
  1811.   break;
  1812. }
  1813.     }
  1814.   return CMD_SUCCESS;
  1815. }
  1816. /* Hook function for updating route_map assignment. */
  1817. void
  1818. bgp_route_map_update ()
  1819. {
  1820.   int i;
  1821.   afi_t afi;
  1822.   safi_t safi;
  1823.   int direct;
  1824.   struct listnode *nn, *nm;
  1825.   struct bgp *bgp;
  1826.   struct peer *peer;
  1827.   struct peer_group *group;
  1828.   struct bgp_filter *filter;
  1829.   struct bgp_node *bn;
  1830.   struct bgp_static *bgp_static;
  1831.   /* For neighbor route-map updates. */
  1832.   LIST_LOOP (bm->bgp, bgp, nn)
  1833.     {
  1834.       LIST_LOOP (bgp->peer, peer, nm)
  1835. {
  1836.   for (afi = AFI_IP; afi < AFI_MAX; afi++)
  1837.     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
  1838.       {
  1839. filter = &peer->filter[afi][safi];
  1840.   
  1841. for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
  1842.   {
  1843.     if (filter->map[direct].name)
  1844.       filter->map[direct].map = 
  1845. route_map_lookup_by_name (filter->map[direct].name);
  1846.     else
  1847.       filter->map[direct].map = NULL;
  1848.   }
  1849. if (filter->usmap.name)
  1850.   filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
  1851. else
  1852.   filter->usmap.map = NULL;
  1853.       }
  1854. }
  1855.       LIST_LOOP (bgp->group, group, nm)
  1856. {
  1857.   for (afi = AFI_IP; afi < AFI_MAX; afi++)
  1858.     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
  1859.       {
  1860. filter = &group->conf->filter[afi][safi];
  1861.   
  1862. for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
  1863.   {
  1864.     if (filter->map[direct].name)
  1865.       filter->map[direct].map = 
  1866. route_map_lookup_by_name (filter->map[direct].name);
  1867.     else
  1868.       filter->map[direct].map = NULL;
  1869.   }
  1870. if (filter->usmap.name)
  1871.   filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
  1872. else
  1873.   filter->usmap.map = NULL;
  1874.       }
  1875. }
  1876.     }
  1877.   /* For default-originate route-map updates. */
  1878.   LIST_LOOP (bm->bgp, bgp, nn)
  1879.     {
  1880.       LIST_LOOP (bgp->peer, peer, nm)
  1881. {
  1882.   for (afi = AFI_IP; afi < AFI_MAX; afi++)
  1883.     for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
  1884.       {
  1885. if (peer->default_rmap[afi][safi].name)
  1886.   peer->default_rmap[afi][safi].map =
  1887.     route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
  1888. else
  1889.   peer->default_rmap[afi][safi].map = NULL;
  1890.       }
  1891. }
  1892.     }
  1893.   /* For network route-map updates. */
  1894.   LIST_LOOP (bm->bgp, bgp, nn)
  1895.     {
  1896.       for (afi = AFI_IP; afi < AFI_MAX; afi++)
  1897. for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
  1898.   for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
  1899.        bn = bgp_route_next (bn))
  1900.     if ((bgp_static = bn->info) != NULL)
  1901.       {
  1902. if (bgp_static->rmap.name)
  1903.   bgp_static->rmap.map =
  1904.  route_map_lookup_by_name (bgp_static->rmap.name);
  1905. else
  1906.   bgp_static->rmap.map = NULL;
  1907.       }
  1908.     }
  1909.   /* For redistribute route-map updates. */
  1910.   LIST_LOOP (bm->bgp, bgp, nn)
  1911.     {
  1912.       for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
  1913. {
  1914.   if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
  1915.     bgp->rmap[ZEBRA_FAMILY_IPV4][i].map = 
  1916.       route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
  1917. #ifdef HAVE_IPV6
  1918.   if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
  1919.     bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
  1920.       route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
  1921. #endif /* HAVE_IPV6 */
  1922. }
  1923.     }
  1924. }
  1925. DEFUN (match_ip_address, 
  1926.        match_ip_address_cmd,
  1927.        "match ip address (<1-199>|<1300-2699>|WORD)",
  1928.        MATCH_STR
  1929.        IP_STR
  1930.        "Match address of routen"
  1931.        "IP access-list numbern"
  1932.        "IP access-list number (expanded range)n"
  1933.        "IP Access-list namen")
  1934. {
  1935.   return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
  1936. }
  1937. DEFUN (no_match_ip_address, 
  1938.        no_match_ip_address_cmd,
  1939.        "no match ip address",
  1940.        NO_STR
  1941.        MATCH_STR
  1942.        IP_STR
  1943.        "Match address of routen")
  1944. {
  1945.   if (argc == 0)
  1946.     return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
  1947.   return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
  1948. }
  1949. ALIAS (no_match_ip_address, 
  1950.        no_match_ip_address_val_cmd,
  1951.        "no match ip address (<1-199>|<1300-2699>|WORD)",
  1952.        NO_STR
  1953.        MATCH_STR
  1954.        IP_STR
  1955.        "Match address of routen"
  1956.        "IP access-list numbern"
  1957.        "IP access-list number (expanded range)n"
  1958.        "IP Access-list namen");
  1959. DEFUN (match_ip_next_hop, 
  1960.        match_ip_next_hop_cmd,
  1961.        "match ip next-hop (<1-199>|<1300-2699>|WORD)",
  1962.        MATCH_STR
  1963.        IP_STR
  1964.        "Match next-hop address of routen"
  1965.        "IP access-list numbern"
  1966.        "IP access-list number (expanded range)n"
  1967.        "IP Access-list namen")
  1968. {
  1969.   return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
  1970. }
  1971. DEFUN (no_match_ip_next_hop,
  1972.        no_match_ip_next_hop_cmd,
  1973.        "no match ip next-hop",
  1974.        NO_STR
  1975.        MATCH_STR
  1976.        IP_STR
  1977.        "Match next-hop address of routen")
  1978. {
  1979.   if (argc == 0)
  1980.     return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
  1981.   return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
  1982. }
  1983. ALIAS (no_match_ip_next_hop,
  1984.        no_match_ip_next_hop_val_cmd,
  1985.        "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
  1986.        NO_STR
  1987.        MATCH_STR
  1988.        IP_STR
  1989.        "Match next-hop address of routen"
  1990.        "IP access-list numbern"
  1991.        "IP access-list number (expanded range)n"
  1992.        "IP Access-list namen");
  1993. DEFUN (match_ip_route_source, 
  1994.        match_ip_route_source_cmd,
  1995.        "match ip route-source (<1-199>|<1300-2699>|WORD)",
  1996.        MATCH_STR
  1997.        IP_STR
  1998.        "Match advertising source address of routen"
  1999.        "IP access-list numbern"
  2000.        "IP access-list number (expanded range)n"
  2001.        "IP standard access-list namen")
  2002. {
  2003.   return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
  2004. }
  2005. DEFUN (no_match_ip_route_source,
  2006.        no_match_ip_route_source_cmd,
  2007.        "no match ip route-source",
  2008.        NO_STR
  2009.        MATCH_STR
  2010.        IP_STR
  2011.        "Match advertising source address of routen")
  2012. {
  2013.   if (argc == 0)
  2014.     return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
  2015.   return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
  2016. }
  2017. ALIAS (no_match_ip_route_source,
  2018.        no_match_ip_route_source_val_cmd,
  2019.        "no match ip route-source (<1-199>|<1300-2699>|WORD)",
  2020.        NO_STR
  2021.        MATCH_STR
  2022.        IP_STR
  2023.        "Match advertising source address of routen"
  2024.        "IP access-list numbern"
  2025.        "IP access-list number (expanded range)n"
  2026.        "IP standard access-list namen");
  2027. DEFUN (match_ip_address_prefix_list, 
  2028.        match_ip_address_prefix_list_cmd,
  2029.        "match ip address prefix-list WORD",
  2030.        MATCH_STR
  2031.        IP_STR
  2032.        "Match address of routen"
  2033.        "Match entries of prefix-listsn"
  2034.        "IP prefix-list namen")
  2035. {
  2036.   return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
  2037. }
  2038. DEFUN (no_match_ip_address_prefix_list,
  2039.        no_match_ip_address_prefix_list_cmd,
  2040.        "no match ip address prefix-list",
  2041.        NO_STR
  2042.        MATCH_STR
  2043.        IP_STR
  2044.        "Match address of routen"
  2045.        "Match entries of prefix-listsn")
  2046. {
  2047.   if (argc == 0)
  2048.     return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
  2049.   return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
  2050. }
  2051. ALIAS (no_match_ip_address_prefix_list,
  2052.        no_match_ip_address_prefix_list_val_cmd,
  2053.        "no match ip address prefix-list WORD",
  2054.        NO_STR
  2055.        MATCH_STR
  2056.        IP_STR
  2057.        "Match address of routen"
  2058.        "Match entries of prefix-listsn"
  2059.        "IP prefix-list namen");
  2060. DEFUN (match_ip_next_hop_prefix_list, 
  2061.        match_ip_next_hop_prefix_list_cmd,
  2062.        "match ip next-hop prefix-list WORD",
  2063.        MATCH_STR
  2064.        IP_STR
  2065.        "Match next-hop address of routen"
  2066.        "Match entries of prefix-listsn"
  2067.        "IP prefix-list namen")
  2068. {
  2069.   return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
  2070. }
  2071. DEFUN (no_match_ip_next_hop_prefix_list,
  2072.        no_match_ip_next_hop_prefix_list_cmd,
  2073.        "no match ip next-hop prefix-list",
  2074.        NO_STR
  2075.        MATCH_STR
  2076.        IP_STR
  2077.        "Match next-hop address of routen"
  2078.        "Match entries of prefix-listsn")
  2079. {
  2080.   if (argc == 0)
  2081.     return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
  2082.   return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
  2083. }
  2084. ALIAS (no_match_ip_next_hop_prefix_list,
  2085.        no_match_ip_next_hop_prefix_list_val_cmd,
  2086.        "no match ip next-hop prefix-list WORD",
  2087.        NO_STR
  2088.        MATCH_STR
  2089.        IP_STR
  2090.        "Match next-hop address of routen"
  2091.        "Match entries of prefix-listsn"
  2092.        "IP prefix-list namen");
  2093. DEFUN (match_ip_route_source_prefix_list, 
  2094.        match_ip_route_source_prefix_list_cmd,
  2095.        "match ip route-source prefix-list WORD",
  2096.        MATCH_STR
  2097.        IP_STR
  2098.        "Match advertising source address of routen"
  2099.        "Match entries of prefix-listsn"
  2100.        "IP prefix-list namen")
  2101. {
  2102.   return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
  2103. }
  2104. DEFUN (no_match_ip_route_source_prefix_list,
  2105.        no_match_ip_route_source_prefix_list_cmd,
  2106.        "no match ip route-source prefix-list",
  2107.        NO_STR
  2108.        MATCH_STR
  2109.        IP_STR
  2110.        "Match advertising source address of routen"
  2111.        "Match entries of prefix-listsn")
  2112. {
  2113.   if (argc == 0)
  2114.     return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
  2115.   return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
  2116. }
  2117. ALIAS (no_match_ip_route_source_prefix_list,
  2118.        no_match_ip_route_source_prefix_list_val_cmd,
  2119.        "no match ip route-source prefix-list WORD",
  2120.        NO_STR
  2121.        MATCH_STR
  2122.        IP_STR
  2123.        "Match advertising source address of routen"
  2124.        "Match entries of prefix-listsn"
  2125.        "IP prefix-list namen");
  2126. DEFUN (match_metric, 
  2127.        match_metric_cmd,
  2128.        "match metric <0-4294967295>",
  2129.        MATCH_STR
  2130.        "Match metric of routen"
  2131.        "Metric valuen")
  2132. {
  2133.   return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
  2134. }
  2135. DEFUN (no_match_metric,
  2136.        no_match_metric_cmd,
  2137.        "no match metric",
  2138.        NO_STR
  2139.        MATCH_STR
  2140.        "Match metric of routen")
  2141. {
  2142.   if (argc == 0)
  2143.     return bgp_route_match_delete (vty, vty->index, "metric", NULL);
  2144.   return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
  2145. }
  2146. ALIAS (no_match_metric,
  2147.        no_match_metric_val_cmd,
  2148.        "no match metric <0-4294967295>",
  2149.        NO_STR
  2150.        MATCH_STR
  2151.        "Match metric of routen"
  2152.        "Metric valuen");
  2153. DEFUN (match_community, 
  2154.        match_community_cmd,
  2155.        "match community (<1-99>|<100-500>|WORD)",
  2156.        MATCH_STR
  2157.        "Match BGP community listn"
  2158.        "Community-list number (standard)n"
  2159.        "Community-list number (expanded)n"
  2160.        "Community-list namen")
  2161. {
  2162.   return bgp_route_match_add (vty, vty->index, "community", argv[0]);
  2163. }
  2164. DEFUN (match_community_exact, 
  2165.        match_community_exact_cmd,
  2166.        "match community (<1-99>|<100-500>|WORD) exact-match",
  2167.        MATCH_STR
  2168.        "Match BGP community listn"
  2169.        "Community-list number (standard)n"
  2170.        "Community-list number (expanded)n"
  2171.        "Community-list namen"
  2172.        "Do exact matching of communitiesn")
  2173. {
  2174.   int ret;
  2175.   char *argstr;
  2176.   argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
  2177.     strlen (argv[0]) + strlen ("exact-match") + 2);
  2178.   sprintf (argstr, "%s exact-match", argv[0]);
  2179.   ret = bgp_route_match_add (vty, vty->index, "community", argstr);
  2180.   XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
  2181.   return ret;
  2182. }
  2183. DEFUN (no_match_community,
  2184.        no_match_community_cmd,
  2185.        "no match community",
  2186.        NO_STR
  2187.        MATCH_STR
  2188.        "Match BGP community listn")
  2189. {
  2190.   return bgp_route_match_delete (vty, vty->index, "community", NULL);
  2191. }
  2192. ALIAS (no_match_community,
  2193.        no_match_community_val_cmd,
  2194.        "no match community (<1-99>|<100-500>|WORD)",
  2195.        NO_STR
  2196.        MATCH_STR
  2197.        "Match BGP community listn"
  2198.        "Community-list number (standard)n"
  2199.        "Community-list number (expanded)n"
  2200.        "Community-list namen");
  2201. ALIAS (no_match_community,
  2202.        no_match_community_exact_cmd,
  2203.        "no match community (<1-99>|<100-500>|WORD) exact-match",
  2204.        NO_STR
  2205.        MATCH_STR
  2206.        "Match BGP community listn"
  2207.        "Community-list number (standard)n"
  2208.        "Community-list number (expanded)n"
  2209.        "Community-list namen"
  2210.        "Do exact matching of communitiesn");
  2211. DEFUN (match_ecommunity, 
  2212.        match_ecommunity_cmd,
  2213.        "match extcommunity (<1-99>|<100-500>|WORD)",
  2214.        MATCH_STR
  2215.        "Match BGP/VPN extended community listn"
  2216.        "Extended community-list number (standard)n"
  2217.        "Extended community-list number (expanded)n"
  2218.        "Extended community-list namen")
  2219. {
  2220.   return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
  2221. }
  2222. DEFUN (no_match_ecommunity,
  2223.        no_match_ecommunity_cmd,
  2224.        "no match extcommunity",
  2225.        NO_STR
  2226.        MATCH_STR
  2227.        "Match BGP/VPN extended community listn")
  2228. {
  2229.   return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
  2230. }
  2231. ALIAS (no_match_ecommunity,
  2232.        no_match_ecommunity_val_cmd,
  2233.        "no match extcommunity (<1-99>|<100-500>|WORD)",
  2234.        NO_STR
  2235.        MATCH_STR
  2236.        "Match BGP/VPN extended community listn"
  2237.        "Extended community-list number (standard)n"
  2238.        "Extended community-list number (expanded)n"
  2239.        "Extended community-list namen");
  2240. DEFUN (match_aspath,
  2241.        match_aspath_cmd,
  2242.        "match as-path WORD",
  2243.        MATCH_STR
  2244.        "Match BGP AS path listn"
  2245.        "AS path access-list namen")
  2246. {
  2247.   return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
  2248. }
  2249. DEFUN (no_match_aspath,
  2250.        no_match_aspath_cmd,
  2251.        "no match as-path",
  2252.        NO_STR
  2253.        MATCH_STR
  2254.        "Match BGP AS path listn")
  2255. {
  2256.   return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
  2257. }
  2258. ALIAS (no_match_aspath,
  2259.        no_match_aspath_val_cmd,
  2260.        "no match as-path WORD",
  2261.        NO_STR
  2262.        MATCH_STR
  2263.        "Match BGP AS path listn"
  2264.        "AS path access-list namen");
  2265. DEFUN (match_origin,
  2266.        match_origin_cmd,
  2267.        "match origin (egp|igp|incomplete)",
  2268.        MATCH_STR
  2269.        "BGP origin coden"
  2270.        "remote EGPn"
  2271.        "local IGPn"
  2272.        "unknown heritagen")
  2273. {
  2274.   if (strncmp (argv[0], "igp", 2) == 0)
  2275.     return bgp_route_match_add (vty, vty->index, "origin", "igp");
  2276.   if (strncmp (argv[0], "egp", 1) == 0)
  2277.     return bgp_route_match_add (vty, vty->index, "origin", "egp");
  2278.   if (strncmp (argv[0], "incomplete", 2) == 0)
  2279.     return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
  2280.   return CMD_WARNING;
  2281. }
  2282. DEFUN (no_match_origin,
  2283.        no_match_origin_cmd,
  2284.        "no match origin",
  2285.        NO_STR
  2286.        MATCH_STR
  2287.        "BGP origin coden")
  2288. {
  2289.   return bgp_route_match_delete (vty, vty->index, "origin", NULL);
  2290. }
  2291. ALIAS (no_match_origin,
  2292.        no_match_origin_val_cmd,
  2293.        "no match origin (egp|igp|incomplete)",
  2294.        NO_STR
  2295.        MATCH_STR
  2296.        "BGP origin coden"
  2297.        "remote EGPn"
  2298.        "local IGPn"
  2299.        "unknown heritagen");
  2300. DEFUN (set_ip_nexthop,
  2301.        set_ip_nexthop_cmd,
  2302.        "set ip next-hop A.B.C.D",
  2303.        SET_STR
  2304.        IP_STR
  2305.        "Next hop addressn"
  2306.        "IP address of next hopn")
  2307. {
  2308.   union sockunion su;
  2309.   int ret;
  2310.   ret = str2sockunion (argv[0], &su);
  2311.   if (ret < 0)
  2312.     {
  2313.       vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
  2314.       return CMD_WARNING;
  2315.     }
  2316.  
  2317.   return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
  2318. }
  2319. DEFUN (set_ip_nexthop_bgp,
  2320.        set_ip_nexthop_bgp_cmd,
  2321.        "set ip next-hop peer-address",
  2322.        SET_STR
  2323.        IP_STR
  2324.        "Next hop addressn"
  2325.        "Use peer address (for BGP only)n")
  2326. {
  2327.   return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
  2328. }
  2329. DEFUN (no_set_ip_nexthop,
  2330.        no_set_ip_nexthop_cmd,
  2331.        "no set ip next-hop",
  2332.        NO_STR
  2333.        SET_STR
  2334.        IP_STR
  2335.        "Next hop addressn")
  2336. {
  2337.   return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
  2338. }
  2339. ALIAS (no_set_ip_nexthop,
  2340.        no_set_ip_nexthop_val_cmd,
  2341.        "no set ip next-hop A.B.C.D",
  2342.        NO_STR
  2343.        SET_STR
  2344.        IP_STR
  2345.        "Next hop addressn"
  2346.        "IP address of next hopn");
  2347. ALIAS (no_set_ip_nexthop,
  2348.        no_set_ip_nexthop_val_bgp_cmd,
  2349.        "no set ip next-hop peer-address",
  2350.        NO_STR
  2351.        SET_STR
  2352.        IP_STR
  2353.        "Next hop addressn"
  2354.        "Use peer address (for BGP only)n");
  2355. DEFUN (set_metric,
  2356.        set_metric_cmd,
  2357.        "set metric <0-4294967295>",
  2358.        SET_STR
  2359.        "Metric value for destination routing protocoln"
  2360.        "Metric valuen")
  2361. {
  2362.   return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
  2363. }
  2364. ALIAS (set_metric,
  2365.        set_metric_addsub_cmd,
  2366.        "set metric <+/-metric>",
  2367.        SET_STR
  2368.        "Metric value for destination routing protocoln"
  2369.        "Add or subtract BGP metricn");
  2370. DEFUN (no_set_metric,
  2371.        no_set_metric_cmd,
  2372.        "no set metric",
  2373.        NO_STR
  2374.        SET_STR
  2375.        "Metric value for destination routing protocoln")
  2376. {
  2377.   if (argc == 0)
  2378.     return bgp_route_set_delete (vty, vty->index, "metric", NULL);
  2379.   return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
  2380. }
  2381. ALIAS (no_set_metric,
  2382.        no_set_metric_val_cmd,
  2383.        "no set metric <0-4294967295>",
  2384.        NO_STR
  2385.        SET_STR
  2386.        "Metric value for destination routing protocoln"
  2387.        "Metric valuen");
  2388. DEFUN (set_local_pref,
  2389.        set_local_pref_cmd,
  2390.        "set local-preference <0-4294967295>",
  2391.        SET_STR
  2392.        "BGP local preference path attributen"
  2393.        "Preference valuen")
  2394. {
  2395.   return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
  2396. }
  2397. DEFUN (no_set_local_pref,
  2398.        no_set_local_pref_cmd,
  2399.        "no set local-preference",
  2400.        NO_STR
  2401.        SET_STR
  2402.        "BGP local preference path attributen")
  2403. {
  2404.   if (argc == 0)
  2405.     return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
  2406.   return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
  2407. }
  2408. ALIAS (no_set_local_pref,
  2409.        no_set_local_pref_val_cmd,
  2410.        "no set local-preference <0-4294967295>",
  2411.        NO_STR
  2412.        SET_STR
  2413.        "BGP local preference path attributen"
  2414.        "Preference valuen");
  2415. DEFUN (set_weight,
  2416.        set_weight_cmd,
  2417.        "set weight <0-65535>",
  2418.        SET_STR
  2419.        "BGP weight for routing tablen"
  2420.        "Weight valuen")
  2421. {
  2422.   return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
  2423. }
  2424. DEFUN (no_set_weight,
  2425.        no_set_weight_cmd,
  2426.        "no set weight",
  2427.        NO_STR
  2428.        SET_STR
  2429.        "BGP weight for routing tablen")
  2430. {
  2431.   if (argc == 0)
  2432.     return bgp_route_set_delete (vty, vty->index, "weight", NULL);
  2433.   
  2434.   return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
  2435. }
  2436. ALIAS (no_set_weight,
  2437.        no_set_weight_val_cmd,
  2438.        "no set weight <0-65535>",
  2439.        NO_STR
  2440.        SET_STR
  2441.        "BGP weight for routing tablen"
  2442.        "Weight valuen");
  2443. DEFUN (set_aspath_prepend,
  2444.        set_aspath_prepend_cmd,
  2445.        "set as-path prepend .<1-65535>",
  2446.        SET_STR
  2447.        "Prepend string for a BGP AS-path attributen"
  2448.        "Prepend to the as-pathn"
  2449.        "AS numbern")
  2450. {
  2451.   int ret;
  2452.   char *str;
  2453.   str = argv_concat (argv, argc, 0);
  2454.   ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
  2455.   XFREE (MTYPE_TMP, str);
  2456.   return ret;
  2457. }
  2458. DEFUN (no_set_aspath_prepend,
  2459.        no_set_aspath_prepend_cmd,
  2460.        "no set as-path prepend",
  2461.        NO_STR
  2462.        SET_STR
  2463.        "Prepend string for a BGP AS-path attributen"
  2464.        "Prepend to the as-pathn")
  2465. {
  2466.   return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
  2467. }
  2468. ALIAS (no_set_aspath_prepend,
  2469.        no_set_aspath_prepend_val_cmd,
  2470.        "no set as-path prepend .<1-65535>",
  2471.        NO_STR
  2472.        SET_STR
  2473.        "Prepend string for a BGP AS-path attributen"
  2474.        "Prepend to the as-pathn"
  2475.        "AS numbern");
  2476. DEFUN (set_community,
  2477.        set_community_cmd,
  2478.        "set community .AA:NN",
  2479.        SET_STR
  2480.        "BGP community attributen"
  2481.        "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additiven")
  2482. {
  2483.   int i;
  2484.   int first = 0;
  2485.   int additive = 0;
  2486.   struct buffer *b;
  2487.   struct community *com = NULL;
  2488.   char *str;
  2489.   char *argstr;
  2490.   int ret;
  2491.   b = buffer_new (1024);
  2492.   for (i = 0; i < argc; i++)
  2493.     {
  2494.       if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
  2495.   {
  2496.     additive = 1;
  2497.     continue;
  2498.   }
  2499.       if (first)
  2500. buffer_putc (b, ' ');
  2501.       else
  2502. first = 1;
  2503.       if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
  2504.   {
  2505.   buffer_putstr (b, "internet");
  2506.     continue;
  2507.   }
  2508.       if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
  2509.   {
  2510.   buffer_putstr (b, "local-AS");
  2511.     continue;
  2512.   }
  2513.       if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
  2514.   && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
  2515.   {
  2516.   buffer_putstr (b, "no-advertise");
  2517.     continue;
  2518.   }
  2519.       if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
  2520.   && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
  2521.   {
  2522.   buffer_putstr (b, "no-export");
  2523.     continue;
  2524.   }
  2525.       buffer_putstr (b, argv[i]);
  2526.     }
  2527.   buffer_putc (b, '');
  2528.   /* Fetch result string then compile it to communities attribute.  */
  2529.   str = buffer_getstr (b);
  2530.   buffer_free (b);
  2531.   if (str)
  2532.     {
  2533.       com = community_str2com (str);
  2534.       free (str);
  2535.     }
  2536.   /* Can't compile user input into communities attribute.  */
  2537.   if (! com)
  2538.     {
  2539.       vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
  2540.       return CMD_WARNING;
  2541.     }
  2542.   /* Set communites attribute string.  */
  2543.   str = community_str (com);
  2544.   if (additive)
  2545.     {
  2546.       argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
  2547.       strcpy (argstr, str);
  2548.       strcpy (argstr + strlen (str), " additive");
  2549.       ret =  bgp_route_set_add (vty, vty->index, "community", argstr);
  2550.       XFREE (MTYPE_TMP, argstr);
  2551.     }
  2552.   else
  2553.     ret =  bgp_route_set_add (vty, vty->index, "community", str);
  2554.   community_free (com);
  2555.   return ret;
  2556. }
  2557. DEFUN (set_community_none,
  2558.        set_community_none_cmd,
  2559.        "set community none",
  2560.        SET_STR
  2561.        "BGP community attributen"
  2562.        "No community attributen")
  2563. {
  2564.   return bgp_route_set_add (vty, vty->index, "community", "none");
  2565. }
  2566. DEFUN (no_set_community,
  2567.        no_set_community_cmd,
  2568.        "no set community",
  2569.        NO_STR
  2570.        SET_STR
  2571.        "BGP community attributen")
  2572. {
  2573.   return bgp_route_set_delete (vty, vty->index, "community", NULL);
  2574. }
  2575. ALIAS (no_set_community,
  2576.        no_set_community_val_cmd,
  2577.        "no set community .AA:NN",
  2578.        NO_STR
  2579.        SET_STR
  2580.        "BGP community attributen"
  2581.        "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additiven");
  2582. ALIAS (no_set_community,
  2583.        no_set_community_none_cmd,
  2584.        "no set community none",
  2585.        NO_STR
  2586.        SET_STR
  2587.        "BGP community attributen"
  2588.        "No community attributen");
  2589. DEFUN (set_community_delete,
  2590.        set_community_delete_cmd,
  2591.        "set comm-list (<1-99>|<100-500>|WORD) delete",
  2592.        SET_STR
  2593.        "set BGP community list (for deletion)n"
  2594.        "Community-list number (standard)n"
  2595.        "Communitly-list number (expanded)n"
  2596.        "Community-list namen"
  2597.        "Delete matching communitiesn")
  2598. {
  2599.   char *str;
  2600.   str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
  2601.   strcpy (str, argv[0]);
  2602.   strcpy (str + strlen (argv[0]), " delete");
  2603.   bgp_route_set_add (vty, vty->index, "comm-list", str);
  2604.   XFREE (MTYPE_TMP, str);
  2605.   return CMD_SUCCESS;
  2606. }
  2607. DEFUN (no_set_community_delete,
  2608.        no_set_community_delete_cmd,
  2609.        "no set comm-list",
  2610.        NO_STR
  2611.        SET_STR
  2612.        "set BGP community list (for deletion)n")
  2613. {
  2614.   return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
  2615. }
  2616. ALIAS (no_set_community_delete,
  2617.        no_set_community_delete_val_cmd,
  2618.        "no set comm-list (<1-99>|<100-500>|WORD) delete",
  2619.        NO_STR
  2620.        SET_STR
  2621.        "set BGP community list (for deletion)n"
  2622.        "Community-list number (standard)n"
  2623.        "Communitly-list number (expanded)n"
  2624.        "Community-list namen"
  2625.        "Delete matching communitiesn");
  2626. DEFUN (set_ecommunity_rt,
  2627.        set_ecommunity_rt_cmd,
  2628.        "set extcommunity rt .ASN:nn_or_IP-address:nn",
  2629.        SET_STR
  2630.        "BGP extended community attributen"
  2631.        "Route Target extened communitytn"
  2632.        "VPN extended communityn")
  2633. {
  2634.   struct ecommunity *ecom;
  2635.   int ret;
  2636.   char *str;
  2637.   str = argv_concat (argv, argc, 0);
  2638.   ecom = ecommunity_str2com (str, ECOMMUNITY_TYPE_ROUTE_TARGET, 0);
  2639.   XFREE (MTYPE_TMP, str);
  2640.   if (! ecom)
  2641.     {
  2642.       vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
  2643.       return CMD_WARNING;
  2644.     }
  2645.   ecom->str = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_RMAP);
  2646.   ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", ecom->str);
  2647.   ecommunity_free (ecom);
  2648.   return ret;
  2649. }
  2650. DEFUN (no_set_ecommunity_rt,
  2651.        no_set_ecommunity_rt_cmd,
  2652.        "no set extcommunity rt",
  2653.        NO_STR
  2654.        SET_STR
  2655.        "BGP extended community attributen"
  2656.        "Route Target extened communitytn")
  2657. {
  2658.   return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
  2659. }
  2660. ALIAS (no_set_ecommunity_rt,
  2661.        no_set_ecommunity_rt_val_cmd,
  2662.        "no set extcommunity rt .ASN:nn_or_IP-address:nn",
  2663.        NO_STR
  2664.        SET_STR
  2665.        "BGP extended community attributen"
  2666.        "Route Target extened communitytn"
  2667.        "VPN extended communityn");
  2668. DEFUN (set_ecommunity_soo,
  2669.        set_ecommunity_soo_cmd,
  2670.        "set extcommunity soo .ASN:nn_or_IP-address:nn",
  2671.        SET_STR
  2672.        "BGP extended community attributen"
  2673.        "Site-of-Origin extended communityn"
  2674.        "VPN extended communityn")
  2675. {
  2676.   struct ecommunity *ecom;
  2677.   int ret;
  2678.   char *str;
  2679.   str = argv_concat (argv, argc, 0);
  2680.   ecom = ecommunity_str2com (str, ECOMMUNITY_TYPE_SITE_ORIGIN, 0);
  2681.   XFREE (MTYPE_TMP, str);
  2682.   if (! ecom)
  2683.     {
  2684.       vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
  2685.       return CMD_WARNING;
  2686.     }
  2687.   ecom->str = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_RMAP);
  2688.   ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", ecom->str);
  2689.   ecommunity_free (ecom);
  2690.   return ret;
  2691. }
  2692. DEFUN (no_set_ecommunity_soo,
  2693.        no_set_ecommunity_soo_cmd,
  2694.        "no set extcommunity soo",
  2695.        NO_STR
  2696.        SET_STR
  2697.        "BGP extended community attributen"
  2698.        "Site-of-Origin extended communityn")
  2699. {
  2700.   return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
  2701. }
  2702. ALIAS (no_set_ecommunity_soo,
  2703.        no_set_ecommunity_soo_val_cmd,
  2704.        "no set extcommunity soo .ASN:nn_or_IP-address:nn",
  2705.        NO_STR
  2706.        SET_STR
  2707.        "BGP extended community attributen"
  2708.        "Site-of-Origin extended communityn"
  2709.        "VPN extended communityn");
  2710. DEFUN (set_ecommunity_cost_igp,
  2711.        set_ecommunity_cost_igp_cmd,
  2712.        "set extcommunity cost igp <0-255> <0-4294967295>",
  2713.        SET_STR
  2714.        "BGP extended community attributen"
  2715.        "Cost extended communityn"
  2716.        "Compare following IGP cost comparisonn"
  2717.        "Community IDn"
  2718.        "Cost Valuen"
  2719.        "VPN extended communityn")
  2720. {
  2721.   int ret;
  2722.   char *str;
  2723.   str = argv_concat (argv, argc, 0);
  2724.   ret = bgp_route_set_add (vty, vty->index, "extcommunity cost igp", str);
  2725.   XFREE (MTYPE_TMP, str);
  2726.   return ret;
  2727. }
  2728. DEFUN (no_set_ecommunity_cost_igp,
  2729.        no_set_ecommunity_cost_igp_cmd,
  2730.        "no set extcommunity cost igp",
  2731.        NO_STR
  2732.        SET_STR
  2733.        "BGP extended community attributen"
  2734.        "Cost extended communityn"
  2735.        "Compare following IGP cost comparisonn")
  2736. {
  2737.   return bgp_route_set_delete (vty, vty->index, "extcommunity cost igp", NULL);
  2738. }
  2739. ALIAS (no_set_ecommunity_cost_igp,
  2740.        no_set_ecommunity_cost_igp_val_cmd,
  2741.        "no set extcommunity cost igp <0-255> <0-4294967295>",
  2742.        NO_STR
  2743.        SET_STR
  2744.        "BGP extended community attributen"
  2745.        "Cost extended communityn"
  2746.        "Compare following IGP cost comparisonn"
  2747.        "Community IDn"
  2748.        "Cost Valuen"
  2749.        "VPN extended communityn")
  2750. DEFUN (set_origin,
  2751.        set_origin_cmd,
  2752.        "set origin (egp|igp|incomplete)",
  2753.        SET_STR
  2754.        "BGP origin coden"
  2755.        "remote EGPn"
  2756.        "local IGPn"
  2757.        "unknown heritagen")
  2758. {
  2759.   if (strncmp (argv[0], "igp", 2) == 0)
  2760.     return bgp_route_set_add (vty, vty->index, "origin", "igp");
  2761.   if (strncmp (argv[0], "egp", 1) == 0)
  2762.     return bgp_route_set_add (vty, vty->index, "origin", "egp");
  2763.   if (strncmp (argv[0], "incomplete", 2) == 0)
  2764.     return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
  2765.   return CMD_WARNING;
  2766. }
  2767. DEFUN (no_set_origin,
  2768.        no_set_origin_cmd,
  2769.        "no set origin",
  2770.        NO_STR
  2771.        SET_STR
  2772.        "BGP origin coden")
  2773. {
  2774.   return bgp_route_set_delete (vty, vty->index, "origin", NULL);
  2775. }
  2776. ALIAS (no_set_origin,
  2777.        no_set_origin_val_cmd,
  2778.        "no set origin (egp|igp|incomplete)",
  2779.        NO_STR
  2780.        SET_STR
  2781.        "BGP origin coden"
  2782.        "remote EGPn"
  2783.        "local IGPn"
  2784.        "unknown heritagen");
  2785. DEFUN (set_atomic_aggregate,
  2786.        set_atomic_aggregate_cmd,
  2787.        "set atomic-aggregate",
  2788.        SET_STR
  2789.        "BGP atomic aggregate attributen" )
  2790. {
  2791.   return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
  2792. }
  2793. DEFUN (no_set_atomic_aggregate,
  2794.        no_set_atomic_aggregate_cmd,
  2795.        "no set atomic-aggregate",
  2796.        NO_STR
  2797.        SET_STR
  2798.        "BGP atomic aggregate attributen" )
  2799. {
  2800.   return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
  2801. }
  2802. DEFUN (set_aggregator_as,
  2803.        set_aggregator_as_cmd,
  2804.        "set aggregator as <1-65535> A.B.C.D",
  2805.        SET_STR
  2806.        "BGP aggregator attributen"
  2807.        "AS number of aggregatorn"
  2808.        "AS numbern"
  2809.        "IP address of aggregatorn")
  2810. {
  2811.   int ret;
  2812.   as_t as;
  2813.   struct in_addr address;
  2814.   char *endptr = NULL;
  2815.   char *argstr;
  2816.   as = strtoul (argv[0], &endptr, 10);
  2817.   if (as == 0 || as == ULONG_MAX || *endptr != '')
  2818.     {
  2819.       vty_out (vty, "AS path value malformed%s", VTY_NEWLINE);
  2820.       return CMD_WARNING;
  2821.     }
  2822.   ret = inet_aton (argv[1], &address);
  2823.   if (ret == 0)
  2824.     {
  2825.       vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
  2826.       return CMD_WARNING;
  2827.     }
  2828.   argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
  2829.     strlen (argv[0]) + strlen (argv[1]) + 2);
  2830.   sprintf (argstr, "%s %s", argv[0], argv[1]);
  2831.   ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
  2832.   XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
  2833.   return ret;
  2834. }
  2835. DEFUN (no_set_aggregator_as,
  2836.        no_set_aggregator_as_cmd,
  2837.        "no set aggregator as",
  2838.        NO_STR
  2839.        SET_STR
  2840.        "BGP aggregator attributen"
  2841.        "AS number of aggregatorn")
  2842. {
  2843.   int ret;
  2844.   as_t as;
  2845.   struct in_addr address;
  2846.   char *endptr = NULL;
  2847.   char *argstr;
  2848.   if (argv == 0)
  2849.     return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
  2850.   
  2851.   as = strtoul (argv[0], &endptr, 10);
  2852.   if (as == 0 || as == ULONG_MAX || *endptr != '')
  2853.     {
  2854.       vty_out (vty, "AS path value malformed%s", VTY_NEWLINE);
  2855.       return CMD_WARNING;
  2856.     }
  2857.   ret = inet_aton (argv[1], &address);
  2858.   if (ret == 0)
  2859.     {
  2860.       vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
  2861.       return CMD_WARNING;
  2862.     }
  2863.   argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
  2864.     strlen (argv[0]) + strlen (argv[1]) + 2);
  2865.   sprintf (argstr, "%s %s", argv[0], argv[1]);
  2866.   ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
  2867.   XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
  2868.   return ret;
  2869. }
  2870. ALIAS (no_set_aggregator_as,
  2871.        no_set_aggregator_as_val_cmd,
  2872.        "no set aggregator as <1-65535> A.B.C.D",
  2873.        NO_STR
  2874.        SET_STR
  2875.        "BGP aggregator attributen"
  2876.        "AS number of aggregatorn"
  2877.        "AS numbern"
  2878.        "IP address of aggregatorn");
  2879. #ifdef HAVE_IPV6
  2880. DEFUN (match_ipv6_address, 
  2881.        match_ipv6_address_cmd,
  2882.        "match ipv6 address WORD",
  2883.        MATCH_STR
  2884.        IPV6_STR
  2885.        "Match IPv6 address of routen"
  2886.        "IPv6 access-list namen")
  2887. {
  2888.   return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
  2889. }
  2890. DEFUN (no_match_ipv6_address, 
  2891.        no_match_ipv6_address_cmd,
  2892.        "no match ipv6 address WORD",
  2893.        NO_STR
  2894.        MATCH_STR
  2895.        IPV6_STR
  2896.        "Match IPv6 address of routen"
  2897.        "IPv6 access-list namen")
  2898. {
  2899.   return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
  2900. }
  2901. DEFUN (match_ipv6_next_hop, 
  2902.        match_ipv6_next_hop_cmd,
  2903.        "match ipv6 next-hop X:X::X:X",
  2904.        MATCH_STR
  2905.        IPV6_STR
  2906.        "Match IPv6 next-hop address of routen"
  2907.        "IPv6 address of next hopn")
  2908. {
  2909.   return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
  2910. }
  2911. DEFUN (no_match_ipv6_next_hop,
  2912.        no_match_ipv6_next_hop_cmd,
  2913.        "no match ipv6 next-hop X:X::X:X",
  2914.        NO_STR
  2915.        MATCH_STR
  2916.        IPV6_STR
  2917.        "Match IPv6 next-hop address of routen"
  2918.        "IPv6 address of next hopn")
  2919. {
  2920.   return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
  2921. }
  2922. DEFUN (match_ipv6_address_prefix_list, 
  2923.        match_ipv6_address_prefix_list_cmd,
  2924.        "match ipv6 address prefix-list WORD",
  2925.        MATCH_STR
  2926.        IPV6_STR
  2927.        "Match address of routen"
  2928.        "Match entries of prefix-listsn"
  2929.        "IP prefix-list namen")
  2930. {
  2931.   return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
  2932. }
  2933. DEFUN (no_match_ipv6_address_prefix_list,
  2934.        no_match_ipv6_address_prefix_list_cmd,
  2935.        "no match ipv6 address prefix-list WORD",
  2936.        NO_STR
  2937.        MATCH_STR
  2938.        IPV6_STR
  2939.        "Match address of routen"
  2940.        "Match entries of prefix-listsn"
  2941.        "IP prefix-list namen")
  2942. {
  2943.   return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
  2944. }
  2945. DEFUN (set_ipv6_nexthop_global,
  2946.        set_ipv6_nexthop_global_cmd,
  2947.        "set ipv6 next-hop global X:X::X:X",
  2948.        SET_STR
  2949.        IPV6_STR
  2950.        "IPv6 next-hop addressn"
  2951.        "IPv6 global addressn"
  2952.        "IPv6 address of next hopn")
  2953. {
  2954.   return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
  2955. }
  2956. DEFUN (no_set_ipv6_nexthop_global,
  2957.        no_set_ipv6_nexthop_global_cmd,
  2958.        "no set ipv6 next-hop global",
  2959.        NO_STR
  2960.        SET_STR
  2961.        IPV6_STR
  2962.        "IPv6 next-hop addressn"
  2963.        "IPv6 global addressn")
  2964. {
  2965.   if (argc == 0)
  2966.     return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
  2967.   return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
  2968. }
  2969. ALIAS (no_set_ipv6_nexthop_global,
  2970.        no_set_ipv6_nexthop_global_val_cmd,
  2971.        "no set ipv6 next-hop global X:X::X:X",
  2972.        NO_STR
  2973.        SET_STR
  2974.        IPV6_STR
  2975.        "IPv6 next-hop addressn"
  2976.        "IPv6 global addressn"
  2977.        "IPv6 address of next hopn");
  2978. DEFUN (set_ipv6_nexthop_local,
  2979.        set_ipv6_nexthop_local_cmd,
  2980.        "set ipv6 next-hop local X:X::X:X",
  2981.        SET_STR
  2982.        IPV6_STR
  2983.        "IPv6 next-hop addressn"
  2984.        "IPv6 local addressn"
  2985.        "IPv6 address of next hopn")
  2986. {
  2987.   return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
  2988. }
  2989. DEFUN (no_set_ipv6_nexthop_local,
  2990.        no_set_ipv6_nexthop_local_cmd,
  2991.        "no set ipv6 next-hop local",
  2992.        NO_STR
  2993.        SET_STR
  2994.        IPV6_STR
  2995.        "IPv6 next-hop addressn"
  2996.        "IPv6 local addressn")
  2997. {
  2998.   if (argc == 0)
  2999.     return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
  3000.   
  3001.   return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
  3002. }
  3003. ALIAS (no_set_ipv6_nexthop_local,
  3004.        no_set_ipv6_nexthop_local_val_cmd,
  3005.        "no set ipv6 next-hop local X:X::X:X",
  3006.        NO_STR
  3007.        SET_STR
  3008.        IPV6_STR
  3009.        "IPv6 next-hop addressn"
  3010.        "IPv6 local addressn"
  3011.        "IPv6 address of next hopn");
  3012. #endif /* HAVE_IPV6 */
  3013. DEFUN (set_vpnv4_nexthop,
  3014.        set_vpnv4_nexthop_cmd,
  3015.        "set vpnv4 next-hop A.B.C.D",
  3016.        SET_STR
  3017.        "VPNv4 informationn"
  3018.        "VPNv4 next-hop addressn"
  3019.        "IP address of next hopn")
  3020. {
  3021.   return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
  3022. }
  3023. DEFUN (no_set_vpnv4_nexthop,
  3024.        no_set_vpnv4_nexthop_cmd,
  3025.        "no set vpnv4 next-hop",
  3026.        NO_STR
  3027.        SET_STR
  3028.        "VPNv4 informationn"
  3029.        "VPNv4 next-hop addressn")
  3030. {
  3031.   if (argc == 0)
  3032.     return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
  3033.   return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
  3034. }
  3035. ALIAS (no_set_vpnv4_nexthop,
  3036.        no_set_vpnv4_nexthop_val_cmd,
  3037.        "no set vpnv4 next-hop A.B.C.D",
  3038.        NO_STR
  3039.        SET_STR
  3040.        "VPNv4 informationn"
  3041.        "VPNv4 next-hop addressn"
  3042.        "IP address of next hopn");
  3043. DEFUN (set_originator_id,
  3044.        set_originator_id_cmd,
  3045.        "set originator-id A.B.C.D",
  3046.        SET_STR
  3047.        "BGP originator ID attributen"
  3048.        "IP address of originatorn")
  3049. {
  3050.   return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
  3051. }
  3052. DEFUN (no_set_originator_id,
  3053.        no_set_originator_id_cmd,
  3054.        "no set originator-id",
  3055.        NO_STR
  3056.        SET_STR
  3057.        "BGP originator ID attributen")
  3058. {
  3059.   if (argc == 0)
  3060.     return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
  3061.   
  3062.   return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
  3063. }
  3064. ALIAS (no_set_originator_id,
  3065.        no_set_originator_id_val_cmd,
  3066.        "no set originator-id A.B.C.D",
  3067.        NO_STR
  3068.        SET_STR
  3069.        "BGP originator ID attributen"
  3070.        "IP address of originatorn");
  3071. /* Initialization of route map. */
  3072. void
  3073. bgp_route_map_init ()
  3074. {
  3075.   route_map_init ();
  3076.   route_map_init_vty ();
  3077.   route_map_add_hook (bgp_route_map_update);
  3078.   route_map_delete_hook (bgp_route_map_update);
  3079.   route_map_install_match (&route_match_ip_address_cmd);
  3080.   route_map_install_match (&route_match_ip_next_hop_cmd);
  3081.   route_map_install_match (&route_match_ip_route_source_cmd);
  3082.   route_map_install_match (&route_match_ip_address_prefix_list_cmd);
  3083.   route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
  3084.   route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
  3085.   route_map_install_match (&route_match_aspath_cmd);
  3086.   route_map_install_match (&route_match_community_cmd);
  3087.   route_map_install_match (&route_match_ecommunity_cmd);
  3088.   route_map_install_match (&route_match_metric_cmd);
  3089.   route_map_install_match (&route_match_origin_cmd);
  3090.   route_map_install_set (&route_set_ip_nexthop_cmd);
  3091.   route_map_install_set (&route_set_local_pref_cmd);
  3092.   route_map_install_set (&route_set_weight_cmd);
  3093.   route_map_install_set (&route_set_metric_cmd);
  3094.   route_map_install_set (&route_set_aspath_prepend_cmd);
  3095.   route_map_install_set (&route_set_origin_cmd);
  3096.   route_map_install_set (&route_set_atomic_aggregate_cmd);
  3097.   route_map_install_set (&route_set_aggregator_as_cmd);
  3098.   route_map_install_set (&route_set_community_cmd);
  3099.   route_map_install_set (&route_set_community_delete_cmd);
  3100.   route_map_install_set (&route_set_vpnv4_nexthop_cmd);
  3101.   route_map_install_set (&route_set_originator_id_cmd);
  3102.   route_map_install_set (&route_set_ecommunity_rt_cmd);
  3103.   route_map_install_set (&route_set_ecommunity_soo_cmd);
  3104.   route_map_install_set (&route_set_ecommunity_cost_igp_cmd);
  3105.   install_element (RMAP_NODE, &match_ip_address_cmd);
  3106.   install_element (RMAP_NODE, &no_match_ip_address_cmd);
  3107.   install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
  3108.   install_element (RMAP_NODE, &match_ip_next_hop_cmd);
  3109.   install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
  3110.   install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
  3111.   install_element (RMAP_NODE, &match_ip_route_source_cmd);
  3112.   install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
  3113.   install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
  3114.   install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
  3115.   install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
  3116.   install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
  3117.   install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
  3118.   install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
  3119.   install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
  3120.   install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
  3121.   install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
  3122.   install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
  3123.   install_element (RMAP_NODE, &match_aspath_cmd);
  3124.   install_element (RMAP_NODE, &no_match_aspath_cmd);
  3125.   install_element (RMAP_NODE, &no_match_aspath_val_cmd);
  3126.   install_element (RMAP_NODE, &match_metric_cmd);
  3127.   install_element (RMAP_NODE, &no_match_metric_cmd);
  3128.   install_element (RMAP_NODE, &no_match_metric_val_cmd);
  3129.   install_element (RMAP_NODE, &match_community_cmd);
  3130.   install_element (RMAP_NODE, &match_community_exact_cmd);
  3131.   install_element (RMAP_NODE, &no_match_community_cmd);
  3132.   install_element (RMAP_NODE, &no_match_community_val_cmd);
  3133.   install_element (RMAP_NODE, &no_match_community_exact_cmd);
  3134.   install_element (RMAP_NODE, &match_ecommunity_cmd);
  3135.   install_element (RMAP_NODE, &no_match_ecommunity_cmd);
  3136.   install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
  3137.   install_element (RMAP_NODE, &match_origin_cmd);
  3138.   install_element (RMAP_NODE, &no_match_origin_cmd);
  3139.   install_element (RMAP_NODE, &no_match_origin_val_cmd);
  3140.   install_element (RMAP_NODE, &set_ip_nexthop_cmd);
  3141.   install_element (RMAP_NODE, &set_ip_nexthop_bgp_cmd);
  3142.   install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
  3143.   install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
  3144.   install_element (RMAP_NODE, &no_set_ip_nexthop_val_bgp_cmd);
  3145.   install_element (RMAP_NODE, &set_local_pref_cmd);
  3146.   install_element (RMAP_NODE, &no_set_local_pref_cmd);
  3147.   install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
  3148.   install_element (RMAP_NODE, &set_weight_cmd);
  3149.   install_element (RMAP_NODE, &no_set_weight_cmd);
  3150.   install_element (RMAP_NODE, &no_set_weight_val_cmd);
  3151.   install_element (RMAP_NODE, &set_metric_cmd);
  3152.   install_element (RMAP_NODE, &set_metric_addsub_cmd);
  3153.   install_element (RMAP_NODE, &no_set_metric_cmd);
  3154.   install_element (RMAP_NODE, &no_set_metric_val_cmd);
  3155.   install_element (RMAP_NODE, &set_aspath_prepend_cmd);
  3156.   install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
  3157.   install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
  3158.   install_element (RMAP_NODE, &set_origin_cmd);
  3159.   install_element (RMAP_NODE, &no_set_origin_cmd);
  3160.   install_element (RMAP_NODE, &no_set_origin_val_cmd);
  3161.   install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
  3162.   install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
  3163.   install_element (RMAP_NODE, &set_aggregator_as_cmd);
  3164.   install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
  3165.   install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
  3166.   install_element (RMAP_NODE, &set_community_cmd);
  3167.   install_element (RMAP_NODE, &set_community_none_cmd);
  3168.   install_element (RMAP_NODE, &no_set_community_cmd);
  3169.   install_element (RMAP_NODE, &no_set_community_val_cmd);
  3170.   install_element (RMAP_NODE, &no_set_community_none_cmd);
  3171.   install_element (RMAP_NODE, &set_community_delete_cmd);
  3172.   install_element (RMAP_NODE, &no_set_community_delete_cmd);
  3173.   install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
  3174.   install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
  3175.   install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
  3176.   install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
  3177.   install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
  3178.   install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
  3179.   install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
  3180.   install_element (RMAP_NODE, &set_ecommunity_cost_igp_cmd);
  3181.   install_element (RMAP_NODE, &no_set_ecommunity_cost_igp_cmd);
  3182.   install_element (RMAP_NODE, &no_set_ecommunity_cost_igp_val_cmd);
  3183.   install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
  3184.   install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
  3185.   install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
  3186.   install_element (RMAP_NODE, &set_originator_id_cmd);
  3187.   install_element (RMAP_NODE, &no_set_originator_id_cmd);
  3188.   install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
  3189. #ifdef HAVE_IPV6
  3190.   route_map_install_match (&route_match_ipv6_address_cmd);
  3191.   route_map_install_match (&route_match_ipv6_next_hop_cmd);
  3192.   route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
  3193.   route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
  3194.   route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
  3195.   install_element (RMAP_NODE, &match_ipv6_address_cmd);
  3196.   install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
  3197.   install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
  3198.   install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
  3199.   install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
  3200.   install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
  3201.   install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
  3202.   install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
  3203.   install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
  3204.   install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
  3205.   install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
  3206.   install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
  3207. #endif /* HAVE_IPV6 */
  3208. }