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