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

网络

开发平台:

Unix_Linux

  1. /*
  2.  * Route map function of ospfd.
  3.  * Copyright (C) 2000 IP Infusion Inc.
  4.  *
  5.  * Written by Toshiaki Takada.
  6.  *
  7.  * This file is part of GNU Zebra.
  8.  *
  9.  * GNU Zebra is free software; you can redistribute it and/or modify it
  10.  * under the terms of the GNU General Public License as published by the
  11.  * Free Software Foundation; either version 2, or (at your option) any
  12.  * later version.
  13.  *
  14.  * GNU Zebra is distributed in the hope that it will be useful, but
  15.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17.  * General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
  21.  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  22.  * 02111-1307, USA.
  23.  */
  24. #include <zebra.h>
  25. #include "memory.h"
  26. #include "prefix.h"
  27. #include "table.h"
  28. #include "routemap.h"
  29. #include "command.h"
  30. #include "log.h"
  31. #include "plist.h"
  32. #include "ospfd/ospfd.h"
  33. #include "ospfd/ospf_asbr.h"
  34. #include "ospfd/ospf_interface.h"
  35. #include "ospfd/ospf_lsa.h"
  36. #include "ospfd/ospf_route.h"
  37. #include "ospfd/ospf_zebra.h"
  38. /* Hook function for updating route_map assignment. */
  39. void
  40. ospf_route_map_update (char *name)
  41. {
  42.   struct ospf *ospf;
  43.   int type;
  44.   /* If OSPF instatnce does not exist, return right now. */
  45.   ospf = ospf_lookup ();
  46.   if (ospf == NULL)
  47.     return;
  48.   /* Update route-map */
  49.   for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
  50.     {
  51.       if (ROUTEMAP_NAME (ospf, type)
  52.   && strcmp (ROUTEMAP_NAME (ospf, type), name) == 0)
  53. {
  54.   /* Keep old route-map. */
  55.   struct route_map *old = ROUTEMAP (ospf, type);
  56.   /* Update route-map. */
  57.   ROUTEMAP (ospf, type) =
  58.     route_map_lookup_by_name (ROUTEMAP_NAME (ospf, type));
  59.   /* No update for this distribute type. */
  60.   if (old == NULL && ROUTEMAP (ospf, type) == NULL)
  61.     continue;
  62.   ospf_distribute_list_update (ospf, type);
  63. }
  64.     }
  65. }
  66. void
  67. ospf_route_map_event (route_map_event_t event, char *name)
  68. {
  69.   struct ospf *ospf;
  70.   int type;
  71.   /* If OSPF instatnce does not exist, return right now. */
  72.   ospf = ospf_lookup ();
  73.   if (ospf == NULL)
  74.     return;
  75.   /* Update route-map. */
  76.   for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
  77.     {
  78.       if (ROUTEMAP_NAME (ospf, type) &&  ROUTEMAP (ospf, type)
  79.   && !strcmp (ROUTEMAP_NAME (ospf, type), name))
  80.         {
  81.           ospf_distribute_list_update (ospf, type);
  82.         }
  83.     }
  84. }
  85. /* Delete rip route map rule. */
  86. int
  87. ospf_route_match_delete (struct vty *vty, struct route_map_index *index,
  88.  char *command, char *arg)
  89. {
  90.   int ret;
  91.   ret = route_map_delete_match (index, command, arg);
  92.   if (ret)
  93.     {
  94.       switch (ret)
  95.         {
  96.         case RMAP_RULE_MISSING:
  97.           vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
  98.           return CMD_WARNING;
  99.           break;
  100.         case RMAP_COMPILE_ERROR:
  101.           vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
  102.           return CMD_WARNING;
  103.           break;
  104.         }
  105.     }
  106.   return CMD_SUCCESS;
  107. }
  108. int
  109. ospf_route_match_add (struct vty *vty, struct route_map_index *index,
  110.       char *command, char *arg)
  111. {                                                                              
  112.   int ret;
  113.   ret = route_map_add_match (index, command, arg);
  114.   if (ret)
  115.     {
  116.       switch (ret)
  117.         {
  118.         case RMAP_RULE_MISSING:
  119.           vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
  120.           return CMD_WARNING;
  121.           break;
  122.         case RMAP_COMPILE_ERROR:
  123.           vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
  124.           return CMD_WARNING;
  125.           break;
  126.         }
  127.     }
  128.   return CMD_SUCCESS;
  129. }
  130. int
  131. ospf_route_set_add (struct vty *vty, struct route_map_index *index,
  132.     char *command, char *arg)
  133. {
  134.   int ret;
  135.   ret = route_map_add_set (index, command, arg);
  136.   if (ret)
  137.     {
  138.       switch (ret)
  139.         {
  140.         case RMAP_RULE_MISSING:
  141.           vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
  142.           return CMD_WARNING;
  143.           break;
  144.         case RMAP_COMPILE_ERROR:
  145.           vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
  146.           return CMD_WARNING;
  147.           break;
  148.         }
  149.     }
  150.   return CMD_SUCCESS;
  151. }
  152. /* Delete rip route map rule. */
  153. int
  154. ospf_route_set_delete (struct vty *vty, struct route_map_index *index,
  155.        char *command, char *arg)
  156. {                                              
  157.   int ret;
  158.   ret = route_map_delete_set (index, command, arg);
  159.   if (ret)
  160.     {
  161.       switch (ret)
  162.         {
  163.         case RMAP_RULE_MISSING:
  164.           vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
  165.           return CMD_WARNING;
  166.           break;
  167.         case RMAP_COMPILE_ERROR:
  168.           vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
  169.           return CMD_WARNING;
  170.           break;
  171.         }
  172.     }
  173.   return CMD_SUCCESS;
  174. }
  175. /* `match ip netxthop ' */
  176. /* Match function return 1 if match is success else return zero. */
  177. route_map_result_t
  178. route_match_ip_nexthop (void *rule, struct prefix *prefix,
  179. route_map_object_t type, void *object)
  180. {
  181.   struct access_list *alist;
  182.   struct external_info *ei = object;
  183.   struct prefix_ipv4 p;
  184.   if (type == RMAP_OSPF)
  185.     {
  186.       p.family = AF_INET;
  187.       p.prefix = ei->nexthop;
  188.       p.prefixlen = IPV4_MAX_BITLEN;
  189.       alist = access_list_lookup (AFI_IP, (char *) rule);
  190.       if (alist == NULL)
  191.         return RMAP_NOMATCH;
  192.       return (access_list_apply (alist, &p) == FILTER_DENY ?
  193.               RMAP_NOMATCH : RMAP_MATCH);
  194.     }
  195.   return RMAP_NOMATCH;
  196. }
  197. /* Route map `ip next-hop' match statement. `arg' should be
  198.    access-list name. */
  199. void *
  200. route_match_ip_nexthop_compile (char *arg)
  201. {
  202.   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  203. }
  204. /* Free route map's compiled `ip address' value. */
  205. void
  206. route_match_ip_nexthop_free (void *rule)
  207. {
  208.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  209. }
  210. /* Route map commands for metric matching. */
  211. struct route_map_rule_cmd route_match_ip_nexthop_cmd =
  212. {
  213.   "ip next-hop",
  214.   route_match_ip_nexthop,
  215.   route_match_ip_nexthop_compile,
  216.   route_match_ip_nexthop_free
  217. };
  218. /* `match ip next-hop prefix-list PREFIX_LIST' */
  219. route_map_result_t
  220. route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
  221.                                     route_map_object_t type, void *object)
  222. {
  223.   struct prefix_list *plist;
  224.   struct external_info *ei = object;
  225.   struct prefix_ipv4 p;
  226.   if (type == RMAP_OSPF)
  227.     {
  228.       p.family = AF_INET;
  229.       p.prefix = ei->nexthop;
  230.       p.prefixlen = IPV4_MAX_BITLEN;
  231.       plist = prefix_list_lookup (AFI_IP, (char *) rule);
  232.       if (plist == NULL)
  233.         return RMAP_NOMATCH;
  234.       return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
  235.               RMAP_NOMATCH : RMAP_MATCH);
  236.     }
  237.   return RMAP_NOMATCH;
  238. }
  239. void *
  240. route_match_ip_next_hop_prefix_list_compile (char *arg)
  241. {
  242.   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  243. }
  244. void
  245. route_match_ip_next_hop_prefix_list_free (void *rule)
  246. {
  247.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  248. }
  249. struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
  250. {
  251.   "ip next-hop prefix-list",
  252.   route_match_ip_next_hop_prefix_list,
  253.   route_match_ip_next_hop_prefix_list_compile,
  254.   route_match_ip_next_hop_prefix_list_free
  255. };
  256. /* `match ip address IP_ACCESS_LIST' */
  257. /* Match function should return 1 if match is success else return
  258.    zero. */
  259. route_map_result_t
  260. route_match_ip_address (void *rule, struct prefix *prefix,
  261.                         route_map_object_t type, void *object)
  262. {
  263.   struct access_list *alist;
  264.   /* struct prefix_ipv4 match; */
  265.   if (type == RMAP_OSPF)
  266.     {
  267.       alist = access_list_lookup (AFI_IP, (char *) rule);
  268.       if (alist == NULL)
  269.         return RMAP_NOMATCH;
  270.       return (access_list_apply (alist, prefix) == FILTER_DENY ?
  271.               RMAP_NOMATCH : RMAP_MATCH);
  272.     }
  273.   return RMAP_NOMATCH;
  274. }
  275. /* Route map `ip address' match statement.  `arg' should be
  276.    access-list name. */
  277. void *
  278. route_match_ip_address_compile (char *arg)
  279. {
  280.   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  281. }
  282. /* Free route map's compiled `ip address' value. */
  283. void
  284. route_match_ip_address_free (void *rule)
  285. {
  286.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  287. }
  288. /* Route map commands for ip address matching. */
  289. struct route_map_rule_cmd route_match_ip_address_cmd =
  290. {
  291.   "ip address",
  292.   route_match_ip_address,
  293.   route_match_ip_address_compile,
  294.   route_match_ip_address_free
  295. };
  296. /* `match ip address prefix-list PREFIX_LIST' */
  297. route_map_result_t
  298. route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
  299.                                     route_map_object_t type, void *object)
  300. {
  301.   struct prefix_list *plist;
  302.   if (type == RMAP_OSPF)
  303.     {
  304.       plist = prefix_list_lookup (AFI_IP, (char *) rule);
  305.       if (plist == NULL)
  306.         return RMAP_NOMATCH;
  307.       return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
  308.               RMAP_NOMATCH : RMAP_MATCH);
  309.     }
  310.   return RMAP_NOMATCH;
  311. }
  312. void *
  313. route_match_ip_address_prefix_list_compile (char *arg)
  314. {
  315.   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  316. }
  317. void
  318. route_match_ip_address_prefix_list_free (void *rule)
  319. {
  320.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  321. }
  322. struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
  323. {
  324.   "ip address prefix-list",
  325.   route_match_ip_address_prefix_list,
  326.   route_match_ip_address_prefix_list_compile,
  327.   route_match_ip_address_prefix_list_free
  328. };
  329. /* `match interface IFNAME' */
  330. /* Match function should return 1 if match is success else return
  331.    zero. */
  332. route_map_result_t
  333. route_match_interface (void *rule, struct prefix *prefix,
  334.        route_map_object_t type, void *object)
  335. {
  336.   struct interface *ifp;
  337.   struct external_info *ei;
  338.   if (type == RMAP_OSPF)
  339.     {
  340.       ei = object;
  341.       ifp = if_lookup_by_name ((char *)rule);
  342.       if (ifp == NULL || ifp->ifindex != ei->ifindex)
  343. return RMAP_NOMATCH;
  344.       return RMAP_MATCH;
  345.     }
  346.   return RMAP_NOMATCH;
  347. }
  348. /* Route map `interface' match statement.  `arg' should be
  349.    interface name. */
  350. void *
  351. route_match_interface_compile (char *arg)
  352. {
  353.   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  354. }
  355. /* Free route map's compiled `interface' value. */
  356. void
  357. route_match_interface_free (void *rule)
  358. {
  359.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  360. }
  361. /* Route map commands for ip address matching. */
  362. struct route_map_rule_cmd route_match_interface_cmd =
  363. {
  364.   "interface",
  365.   route_match_interface,
  366.   route_match_interface_compile,
  367.   route_match_interface_free
  368. };
  369. /* `set metric METRIC' */
  370. /* Set metric to attribute. */
  371. route_map_result_t
  372. route_set_metric (void *rule, struct prefix *prefix,
  373.                   route_map_object_t type, void *object)
  374. {
  375.   u_int32_t *metric;
  376.   struct external_info *ei;
  377.   if (type == RMAP_OSPF)
  378.     {
  379.       /* Fetch routemap's rule information. */
  380.       metric = rule;
  381.       ei = object;
  382.       /* Set metric out value. */
  383.       ei->route_map_set.metric = *metric;
  384.     }
  385.   return RMAP_OKAY;
  386. }
  387. /* set metric compilation. */
  388. void *
  389. route_set_metric_compile (char *arg)
  390. {
  391.   u_int32_t *metric;
  392.   metric = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
  393.   *metric = atoi (arg);
  394.   if (*metric >= 0)
  395.     return metric;
  396.   XFREE (MTYPE_ROUTE_MAP_COMPILED, metric);
  397.   return NULL;
  398. }
  399. /* Free route map's compiled `set metric' value. */
  400. void
  401. route_set_metric_free (void *rule)
  402. {
  403.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  404. }
  405. /* Set metric rule structure. */
  406. struct route_map_rule_cmd route_set_metric_cmd =
  407. {
  408.   "metric",
  409.   route_set_metric,
  410.   route_set_metric_compile,
  411.   route_set_metric_free,
  412. };
  413. /* `set metric-type TYPE' */
  414. /* Set metric-type to attribute. */
  415. route_map_result_t
  416. route_set_metric_type (void *rule, struct prefix *prefix,
  417.        route_map_object_t type, void *object)
  418. {
  419.   u_int32_t *metric_type;
  420.   struct external_info *ei;
  421.   if (type == RMAP_OSPF)
  422.     {
  423.       /* Fetch routemap's rule information. */
  424.       metric_type = rule;
  425.       ei = object;
  426.       /* Set metric out value. */
  427.       ei->route_map_set.metric_type = *metric_type;
  428.     }
  429.   return RMAP_OKAY;
  430. }
  431. /* set metric-type compilation. */
  432. void *
  433. route_set_metric_type_compile (char *arg)
  434. {
  435.   u_int32_t *metric_type;
  436.   metric_type = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
  437.   if (strcmp (arg, "type-1") == 0)
  438.     *metric_type = EXTERNAL_METRIC_TYPE_1;
  439.   else if (strcmp (arg, "type-2") == 0)
  440.     *metric_type = EXTERNAL_METRIC_TYPE_2;
  441.   if (*metric_type == EXTERNAL_METRIC_TYPE_1 ||
  442.       *metric_type == EXTERNAL_METRIC_TYPE_2)
  443.     return metric_type;
  444.   XFREE (MTYPE_ROUTE_MAP_COMPILED, metric_type);
  445.   return NULL;
  446. }
  447. /* Free route map's compiled `set metric-type' value. */
  448. void
  449. route_set_metric_type_free (void *rule)
  450. {
  451.   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  452. }
  453. /* Set metric rule structure. */
  454. struct route_map_rule_cmd route_set_metric_type_cmd =
  455. {
  456.   "metric-type",
  457.   route_set_metric_type,
  458.   route_set_metric_type_compile,
  459.   route_set_metric_type_free,
  460. };
  461. DEFUN (match_ip_nexthop,
  462.        match_ip_nexthop_cmd,
  463.        "match ip next-hop (<1-199>|<1300-2699>|WORD)",
  464.        MATCH_STR
  465.        IP_STR
  466.        "Match next-hop address of routen"
  467.        "IP access-list numbern"
  468.        "IP access-list number (expanded range)n"
  469.        "IP access-list namen")
  470. {
  471.   return ospf_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
  472. }
  473. DEFUN (no_match_ip_nexthop,
  474.        no_match_ip_nexthop_cmd,
  475.        "no match ip next-hop",
  476.        NO_STR
  477.        MATCH_STR
  478.        IP_STR
  479.        "Match next-hop address of routen")
  480. {
  481.   if (argc == 0)
  482.     return ospf_route_match_delete (vty, vty->index, "ip next-hop", NULL);
  483.   return ospf_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
  484. }
  485. ALIAS (no_match_ip_nexthop,
  486.        no_match_ip_nexthop_val_cmd,
  487.        "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
  488.        NO_STR
  489.        MATCH_STR
  490.        IP_STR
  491.        "Match next-hop address of routen"
  492.        "IP access-list numbern"
  493.        "IP access-list number (expanded range)n"
  494.        "IP access-list namen");
  495. DEFUN (match_ip_next_hop_prefix_list,
  496.        match_ip_next_hop_prefix_list_cmd,
  497.        "match ip next-hop prefix-list WORD",
  498.        MATCH_STR
  499.        IP_STR
  500.        "Match next-hop address of routen"
  501.        "Match entries of prefix-listsn"
  502.        "IP prefix-list namen")
  503. {
  504.   return ospf_route_match_add (vty, vty->index, "ip next-hop prefix-list",
  505.        argv[0]);
  506. }
  507. DEFUN (no_match_ip_next_hop_prefix_list,
  508.        no_match_ip_next_hop_prefix_list_cmd,
  509.        "no match ip next-hop prefix-list",
  510.        NO_STR
  511.        MATCH_STR
  512.        IP_STR
  513.        "Match next-hop address of routen"
  514.        "Match entries of prefix-listsn")
  515. {
  516.   if (argc == 0)
  517.     return ospf_route_match_delete (vty, vty->index, "ip next-hop prefix-list",
  518.     NULL);
  519.   return ospf_route_match_delete (vty, vty->index, "ip next-hop prefix-list",
  520.   argv[0]);
  521. }
  522. ALIAS (no_match_ip_next_hop_prefix_list,
  523.        no_match_ip_next_hop_prefix_list_val_cmd,
  524.        "no match ip next-hop prefix-list WORD",
  525.        NO_STR
  526.        MATCH_STR
  527.        IP_STR
  528.        "Match next-hop address of routen"
  529.        "Match entries of prefix-listsn"
  530.        "IP prefix-list namen");
  531. DEFUN (match_ip_address,
  532.        match_ip_address_cmd,
  533.        "match ip address (<1-199>|<1300-2699>|WORD)",
  534.        MATCH_STR
  535.        IP_STR
  536.        "Match address of routen"
  537.        "IP access-list numbern"
  538.        "IP access-list number (expanded range)n"
  539.        "IP access-list namen")
  540. {
  541.   return ospf_route_match_add (vty, vty->index, "ip address", argv[0]);
  542. }
  543. DEFUN (no_match_ip_address,
  544.        no_match_ip_address_cmd,
  545.        "no match ip address",
  546.        NO_STR
  547.        MATCH_STR
  548.        IP_STR
  549.        "Match address of routen")
  550. {
  551.   if (argc == 0)
  552.     return ospf_route_match_delete (vty, vty->index, "ip address", NULL);
  553.   return ospf_route_match_delete (vty, vty->index, "ip address", argv[0]);
  554. }
  555. ALIAS (no_match_ip_address,
  556.        no_match_ip_address_val_cmd,
  557.        "no match ip address (<1-199>|<1300-2699>|WORD)",
  558.        NO_STR
  559.        MATCH_STR
  560.        IP_STR
  561.        "Match address of routen"
  562.        "IP access-list numbern"
  563.        "IP access-list number (expanded range)n"
  564.        "IP access-list namen");
  565. DEFUN (match_ip_address_prefix_list,
  566.        match_ip_address_prefix_list_cmd,
  567.        "match ip address prefix-list WORD",
  568.        MATCH_STR
  569.        IP_STR
  570.        "Match address of routen"
  571.        "Match entries of prefix-listsn"
  572.        "IP prefix-list namen")
  573. {
  574.   return ospf_route_match_add (vty, vty->index, "ip address prefix-list",
  575.        argv[0]);
  576. }
  577. DEFUN (no_match_ip_address_prefix_list,
  578.        no_match_ip_address_prefix_list_cmd,
  579.        "no match ip address prefix-list",
  580.        NO_STR
  581.        MATCH_STR
  582.        IP_STR
  583.        "Match address of routen"
  584.        "Match entries of prefix-listsn")
  585. {
  586.   if (argc == 0)
  587.     return ospf_route_match_delete (vty, vty->index, "ip address prefix-list",
  588.     NULL);
  589.   return ospf_route_match_delete (vty, vty->index, "ip address prefix-list",
  590.   argv[0]);
  591. }
  592. ALIAS (no_match_ip_address_prefix_list,
  593.        no_match_ip_address_prefix_list_val_cmd,
  594.        "no match ip address prefix-list WORD",
  595.        NO_STR
  596.        MATCH_STR
  597.        IP_STR
  598.        "Match address of routen"
  599.        "Match entries of prefix-listsn"
  600.        "IP prefix-list namen");
  601. DEFUN (match_interface,
  602.        match_interface_cmd,
  603.        "match interface WORD",
  604.        MATCH_STR
  605.        "Match first hop interface of routen"
  606.        "Interface namen")
  607. {
  608.   return ospf_route_match_add (vty, vty->index, "interface", argv[0]);
  609. }
  610. DEFUN (no_match_interface,
  611.        no_match_interface_cmd,
  612.        "no match interface",
  613.        NO_STR
  614.        MATCH_STR
  615.        "Match first hop interface of routen")
  616. {
  617.   if (argc == 0)
  618.     return ospf_route_match_delete (vty, vty->index, "interface", NULL);
  619.   return ospf_route_match_delete (vty, vty->index, "interface", argv[0]);
  620. }
  621. ALIAS (no_match_interface,
  622.        no_match_interface_val_cmd,
  623.        "no match interface WORD",
  624.        NO_STR
  625.        MATCH_STR
  626.        "Match first hop interface of routen"
  627.        "Interface namen");
  628. DEFUN (set_metric,
  629.        set_metric_cmd,
  630.        "set metric <0-4294967295>",
  631.        SET_STR
  632.        "Metric value for destination routing protocoln"
  633.        "Metric valuen")
  634. {
  635.   return ospf_route_set_add (vty, vty->index, "metric", argv[0]);
  636. }
  637. DEFUN (no_set_metric,
  638.        no_set_metric_cmd,
  639.        "no set metric",
  640.        NO_STR
  641.        SET_STR
  642.        "Metric value for destination routing protocoln")
  643. {
  644.   if (argc == 0)
  645.     return ospf_route_set_delete (vty, vty->index, "metric", NULL);
  646.   return ospf_route_set_delete (vty, vty->index, "metric", argv[0]);
  647. }
  648. ALIAS (no_set_metric,
  649.        no_set_metric_val_cmd,
  650.        "no set metric <0-4294967295>",
  651.        NO_STR
  652.        SET_STR
  653.        "Metric value for destination routing protocoln"
  654.        "Metric valuen");
  655. DEFUN (set_metric_type,
  656.        set_metric_type_cmd,
  657.        "set metric-type (type-1|type-2)",
  658.        SET_STR
  659.        "Type of metric for destination routing protocoln"
  660.        "OSPF external type 1 metricn"
  661.        "OSPF external type 2 metricn")
  662. {
  663.   if (strcmp (argv[0], "1") == 0)
  664.     return ospf_route_set_add (vty, vty->index, "metric-type", "type-1");
  665.   if (strcmp (argv[0], "2") == 0)
  666.     return ospf_route_set_add (vty, vty->index, "metric-type", "type-2");
  667.   return ospf_route_set_add (vty, vty->index, "metric-type", argv[0]);
  668. }
  669. DEFUN (no_set_metric_type,
  670.        no_set_metric_type_cmd,
  671.        "no set metric-type",
  672.        NO_STR
  673.        SET_STR
  674.        "Type of metric for destination routing protocoln")
  675. {
  676.   if (argc == 0)
  677.     return ospf_route_set_delete (vty, vty->index, "metric-type", NULL);
  678.   return ospf_route_set_delete (vty, vty->index, "metric-type", argv[0]);
  679. }
  680. ALIAS (no_set_metric_type,
  681.        no_set_metric_type_val_cmd,
  682.        "no set metric-type (type-1|type-2)",
  683.        NO_STR
  684.        SET_STR
  685.        "Type of metric for destination routing protocoln"
  686.        "OSPF external type 1 metricn"
  687.        "OSPF external type 2 metricn");
  688. /* Route-map init */
  689. void
  690. ospf_route_map_init (void)
  691. {
  692.   route_map_init ();
  693.   route_map_init_vty ();
  694.   route_map_add_hook (ospf_route_map_update);
  695.   route_map_delete_hook (ospf_route_map_update);
  696.   route_map_event_hook (ospf_route_map_event);
  697.   
  698.   route_map_install_match (&route_match_ip_nexthop_cmd);
  699.   route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
  700.   route_map_install_match (&route_match_ip_address_cmd);
  701.   route_map_install_match (&route_match_ip_address_prefix_list_cmd);
  702.   route_map_install_match (&route_match_interface_cmd);
  703.   route_map_install_set (&route_set_metric_cmd);
  704.   route_map_install_set (&route_set_metric_type_cmd);
  705.   install_element (RMAP_NODE, &match_ip_nexthop_cmd);
  706.   install_element (RMAP_NODE, &no_match_ip_nexthop_cmd);
  707.   install_element (RMAP_NODE, &no_match_ip_nexthop_val_cmd);
  708.   install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
  709.   install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
  710.   install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
  711.   install_element (RMAP_NODE, &match_ip_address_cmd);
  712.   install_element (RMAP_NODE, &no_match_ip_address_cmd);
  713.   install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
  714.   install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
  715.   install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
  716.   install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
  717.   install_element (RMAP_NODE, &match_interface_cmd);
  718.   install_element (RMAP_NODE, &no_match_interface_cmd);
  719.   install_element (RMAP_NODE, &no_match_interface_val_cmd);
  720.   install_element (RMAP_NODE, &set_metric_cmd);
  721.   install_element (RMAP_NODE, &no_set_metric_cmd);
  722.   install_element (RMAP_NODE, &no_set_metric_val_cmd);
  723.   install_element (RMAP_NODE, &set_metric_type_cmd);
  724.   install_element (RMAP_NODE, &no_set_metric_type_cmd);
  725.   install_element (RMAP_NODE, &no_set_metric_type_val_cmd);
  726. }