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