blob: 5cfb5c8c744e7406d008854c7bd28a3e8a2f102f [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
paul73ffb252003-04-19 15:49:49 +0000521/* Match function for extcommunity match. */
522route_map_result_t
523route_match_ecommunity (void *rule, struct prefix *prefix,
524 route_map_object_t type, void *object)
525{
526 struct community_list *list;
527 struct bgp_info *bgp_info;
528
529 if (type == RMAP_BGP)
530 {
531 bgp_info = object;
532
533 list = community_list_lookup (bgp_clist, (char *) rule,
534 EXTCOMMUNITY_LIST_AUTO);
535 if (! list)
536 return RMAP_NOMATCH;
537
538 if (ecommunity_list_match (bgp_info->attr->ecommunity, list))
539 return RMAP_MATCH;
540 }
541 return RMAP_NOMATCH;
542}
543
544/* Compile function for extcommunity match. */
545void *
546route_match_ecommunity_compile (char *arg)
547{
548 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
549}
550
551/* Compile function for extcommunity match. */
552void
553route_match_ecommunity_free (void *rule)
554{
555 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
556}
557
558/* Route map commands for community matching. */
559struct route_map_rule_cmd route_match_ecommunity_cmd =
560{
561 "extcommunity",
562 route_match_ecommunity,
563 route_match_ecommunity_compile,
564 route_match_ecommunity_free
565};
566
paul718e3742002-12-13 20:15:29 +0000567/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
568 and `address-family vpnv4'. */
569
570/* `match origin' */
571route_map_result_t
572route_match_origin (void *rule, struct prefix *prefix,
573 route_map_object_t type, void *object)
574{
575 u_char *origin;
576 struct bgp_info *bgp_info;
577
578 if (type == RMAP_BGP)
579 {
580 origin = rule;
581 bgp_info = object;
582
583 if (bgp_info->attr->origin == *origin)
584 return RMAP_MATCH;
585 }
586
587 return RMAP_NOMATCH;
588}
589
590void *
591route_match_origin_compile (char *arg)
592{
593 u_char *origin;
594
595 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
596
597 if (strcmp (arg, "igp") == 0)
598 *origin = 0;
599 else if (strcmp (arg, "egp") == 0)
600 *origin = 1;
601 else
602 *origin = 2;
603
604 return origin;
605}
606
607/* Free route map's compiled `ip address' value. */
608void
609route_match_origin_free (void *rule)
610{
611 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
612}
613
614/* Route map commands for origin matching. */
615struct route_map_rule_cmd route_match_origin_cmd =
616{
617 "origin",
618 route_match_origin,
619 route_match_origin_compile,
620 route_match_origin_free
621};
622/* `set ip next-hop IP_ADDRESS' */
623
624/* Set nexthop to object. ojbect must be pointer to struct attr. */
625route_map_result_t
626route_set_ip_nexthop (void *rule, struct prefix *prefix,
627 route_map_object_t type, void *object)
628{
629 struct in_addr *address;
630 struct bgp_info *bgp_info;
631
632 if (type == RMAP_BGP)
633 {
634 /* Fetch routemap's rule information. */
635 address = rule;
636 bgp_info = object;
637
638 /* Set next hop value. */
639 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
640 bgp_info->attr->nexthop = *address;
641 }
642
643 return RMAP_OKAY;
644}
645
646/* Route map `ip nexthop' compile function. Given string is converted
647 to struct in_addr structure. */
648void *
649route_set_ip_nexthop_compile (char *arg)
650{
651 int ret;
652 struct in_addr *address;
653
654 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
655
656 ret = inet_aton (arg, address);
657
658 if (ret == 0)
659 {
660 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
661 return NULL;
662 }
663
664 return address;
665}
666
667/* Free route map's compiled `ip nexthop' value. */
668void
669route_set_ip_nexthop_free (void *rule)
670{
671 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
672}
673
674/* Route map commands for ip nexthop set. */
675struct route_map_rule_cmd route_set_ip_nexthop_cmd =
676{
677 "ip next-hop",
678 route_set_ip_nexthop,
679 route_set_ip_nexthop_compile,
680 route_set_ip_nexthop_free
681};
682
683/* `set local-preference LOCAL_PREF' */
684
685/* Set local preference. */
686route_map_result_t
687route_set_local_pref (void *rule, struct prefix *prefix,
688 route_map_object_t type, void *object)
689{
690 u_int32_t *local_pref;
691 struct bgp_info *bgp_info;
692
693 if (type == RMAP_BGP)
694 {
695 /* Fetch routemap's rule information. */
696 local_pref = rule;
697 bgp_info = object;
698
699 /* Set local preference value. */
700 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
701 bgp_info->attr->local_pref = *local_pref;
702 }
703
704 return RMAP_OKAY;
705}
706
707/* set local preference compilation. */
708void *
709route_set_local_pref_compile (char *arg)
710{
711 u_int32_t *local_pref;
712 char *endptr = NULL;
713
714 /* Local preference value shoud be integer. */
715 if (! all_digit (arg))
716 return NULL;
717
718 local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
719 *local_pref = strtoul (arg, &endptr, 10);
720 if (*endptr != '\0' || *local_pref == ULONG_MAX)
721 {
722 XFREE (MTYPE_ROUTE_MAP_COMPILED, local_pref);
723 return NULL;
724 }
725 return local_pref;
726}
727
728/* Free route map's local preference value. */
729void
730route_set_local_pref_free (void *rule)
731{
732 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
733}
734
735/* Set local preference rule structure. */
736struct route_map_rule_cmd route_set_local_pref_cmd =
737{
738 "local-preference",
739 route_set_local_pref,
740 route_set_local_pref_compile,
741 route_set_local_pref_free,
742};
743
744/* `set weight WEIGHT' */
745
746/* Set weight. */
747route_map_result_t
748route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
749 void *object)
750{
751 u_int32_t *weight;
752 struct bgp_info *bgp_info;
753
754 if (type == RMAP_BGP)
755 {
756 /* Fetch routemap's rule information. */
757 weight = rule;
758 bgp_info = object;
759
760 /* Set weight value. */
761 bgp_info->attr->weight = *weight;
762 }
763
764 return RMAP_OKAY;
765}
766
767/* set local preference compilation. */
768void *
769route_set_weight_compile (char *arg)
770{
771 u_int32_t *weight;
772 char *endptr = NULL;
773
774 /* Local preference value shoud be integer. */
775 if (! all_digit (arg))
776 return NULL;
777
778 weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
779 *weight = strtoul (arg, &endptr, 10);
780 if (*endptr != '\0' || *weight == ULONG_MAX)
781 {
782 XFREE (MTYPE_ROUTE_MAP_COMPILED, weight);
783 return NULL;
784 }
785 return weight;
786}
787
788/* Free route map's local preference value. */
789void
790route_set_weight_free (void *rule)
791{
792 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
793}
794
795/* Set local preference rule structure. */
796struct route_map_rule_cmd route_set_weight_cmd =
797{
798 "weight",
799 route_set_weight,
800 route_set_weight_compile,
801 route_set_weight_free,
802};
803
804/* `set metric METRIC' */
805
806/* Set metric to attribute. */
807route_map_result_t
808route_set_metric (void *rule, struct prefix *prefix,
809 route_map_object_t type, void *object)
810{
811 char *metric;
812 u_int32_t metric_val;
813 struct bgp_info *bgp_info;
814
815 if (type == RMAP_BGP)
816 {
817 /* Fetch routemap's rule information. */
818 metric = rule;
819 bgp_info = object;
820
821 if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
822 bgp_info->attr->med = 0;
823 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
824
825 if (all_digit (metric))
826 {
827 metric_val = strtoul (metric, (char **)NULL, 10);
828 bgp_info->attr->med = metric_val;
829 }
830 else
831 {
832 metric_val = strtoul (metric+1, (char **)NULL, 10);
833
834 if (strncmp (metric, "+", 1) == 0)
835 {
836 if (bgp_info->attr->med/2 + metric_val/2 > ULONG_MAX/2)
837 bgp_info->attr->med = ULONG_MAX-1;
838 else
839 bgp_info->attr->med += metric_val;
840 }
841 else if (strncmp (metric, "-", 1) == 0)
842 {
843 if (bgp_info->attr->med <= metric_val)
844 bgp_info->attr->med = 0;
845 else
846 bgp_info->attr->med -= metric_val;
847 }
848 }
849 }
850 return RMAP_OKAY;
851}
852
853/* set metric compilation. */
854void *
855route_set_metric_compile (char *arg)
856{
857 u_int32_t metric;
858 char *endptr = NULL;
859
860 if (all_digit (arg))
861 {
862 /* set metric value check*/
863 metric = strtoul (arg, &endptr, 10);
864 if (*endptr != '\0' || metric == ULONG_MAX)
865 return NULL;
866 }
867 else
868 {
869 /* set metric +/-value check */
870 if ((strncmp (arg, "+", 1) != 0
871 && strncmp (arg, "-", 1) != 0)
872 || (! all_digit (arg+1)))
873 return NULL;
874
875 metric = strtoul (arg+1, &endptr, 10);
876 if (*endptr != '\0' || metric == ULONG_MAX)
877 return NULL;
878 }
879
880 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
881}
882
883/* Free route map's compiled `set metric' value. */
884void
885route_set_metric_free (void *rule)
886{
887 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
888}
889
890/* Set metric rule structure. */
891struct route_map_rule_cmd route_set_metric_cmd =
892{
893 "metric",
894 route_set_metric,
895 route_set_metric_compile,
896 route_set_metric_free,
897};
898
899/* `set as-path prepend ASPATH' */
900
901/* For AS path prepend mechanism. */
902route_map_result_t
903route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
904{
905 struct aspath *aspath;
906 struct aspath *new;
907 struct bgp_info *binfo;
908
909 if (type == RMAP_BGP)
910 {
911 aspath = rule;
912 binfo = object;
913
914 if (binfo->attr->aspath->refcnt)
915 new = aspath_dup (binfo->attr->aspath);
916 else
917 new = binfo->attr->aspath;
918
919 aspath_prepend (aspath, new);
920 binfo->attr->aspath = new;
921 }
922
923 return RMAP_OKAY;
924}
925
926/* Compile function for as-path prepend. */
927void *
928route_set_aspath_prepend_compile (char *arg)
929{
930 struct aspath *aspath;
931
932 aspath = aspath_str2aspath (arg);
933 if (! aspath)
934 return NULL;
935 return aspath;
936}
937
938/* Compile function for as-path prepend. */
939void
940route_set_aspath_prepend_free (void *rule)
941{
942 struct aspath *aspath = rule;
943 aspath_free (aspath);
944}
945
946/* Set metric rule structure. */
947struct route_map_rule_cmd route_set_aspath_prepend_cmd =
948{
949 "as-path prepend",
950 route_set_aspath_prepend,
951 route_set_aspath_prepend_compile,
952 route_set_aspath_prepend_free,
953};
954
955/* `set community COMMUNITY' */
956struct rmap_com_set
957{
958 struct community *com;
959 int additive;
960 int none;
961};
962
963/* For community set mechanism. */
964route_map_result_t
965route_set_community (void *rule, struct prefix *prefix,
966 route_map_object_t type, void *object)
967{
968 struct rmap_com_set *rcs;
969 struct bgp_info *binfo;
970 struct attr *attr;
971 struct community *new = NULL;
972 struct community *old;
973 struct community *merge;
974
975 if (type == RMAP_BGP)
976 {
977 rcs = rule;
978 binfo = object;
979 attr = binfo->attr;
980 old = attr->community;
981
982 /* "none" case. */
983 if (rcs->none)
984 {
985 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
986 attr->community = NULL;
987 return RMAP_OKAY;
988 }
989
990 /* "additive" case. */
991 if (rcs->additive && old)
992 {
993 merge = community_merge (community_dup (old), rcs->com);
994 new = community_uniq_sort (merge);
995 community_free (merge);
996 }
997 else
998 new = community_dup (rcs->com);
999
1000 attr->community = new;
1001 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1002 }
1003
1004 return RMAP_OKAY;
1005}
1006
1007/* Compile function for set community. */
1008void *
1009route_set_community_compile (char *arg)
1010{
1011 struct rmap_com_set *rcs;
1012 struct community *com = NULL;
1013 char *sp;
1014 int additive = 0;
1015 int none = 0;
1016
1017 if (strcmp (arg, "none") == 0)
1018 none = 1;
1019 else
1020 {
1021 sp = strstr (arg, "additive");
1022
1023 if (sp && sp > arg)
1024 {
1025 /* "additive" keyworkd is included. */
1026 additive = 1;
1027 *(sp - 1) = '\0';
1028 }
1029
1030 com = community_str2com (arg);
1031
1032 if (additive)
1033 *(sp - 1) = ' ';
1034
1035 if (! com)
1036 return NULL;
1037 }
1038
1039 rcs = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
1040 memset (rcs, 0, sizeof (struct rmap_com_set));
1041
1042 rcs->com = com;
1043 rcs->additive = additive;
1044 rcs->none = none;
1045
1046 return rcs;
1047}
1048
1049/* Free function for set community. */
1050void
1051route_set_community_free (void *rule)
1052{
1053 struct rmap_com_set *rcs = rule;
1054
1055 if (rcs->com)
1056 community_free (rcs->com);
1057 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1058}
1059
1060/* Set community rule structure. */
1061struct route_map_rule_cmd route_set_community_cmd =
1062{
1063 "community",
1064 route_set_community,
1065 route_set_community_compile,
1066 route_set_community_free,
1067};
1068
1069/* `set comm-list (<1-99>|<100-199>|WORD) delete' */
1070
1071/* For community set mechanism. */
1072route_map_result_t
1073route_set_community_delete (void *rule, struct prefix *prefix,
1074 route_map_object_t type, void *object)
1075{
1076 struct community_list *list;
1077 struct community *merge;
1078 struct community *new;
1079 struct community *old;
1080 struct bgp_info *binfo;
1081
1082 if (type == RMAP_BGP)
1083 {
1084 if (! rule)
1085 return RMAP_OKAY;
1086
1087 binfo = object;
1088 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_AUTO);
1089 old = binfo->attr->community;
1090
1091 if (list && old)
1092 {
1093 merge = community_list_match_delete (community_dup (old), list);
1094 new = community_uniq_sort (merge);
1095 community_free (merge);
1096
1097 if (new->size == 0)
1098 {
1099 binfo->attr->community = NULL;
1100 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1101 community_free (new);
1102 }
1103 else
1104 {
1105 binfo->attr->community = new;
1106 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1107 }
1108 }
1109 }
1110
1111 return RMAP_OKAY;
1112}
1113
1114/* Compile function for set community. */
1115void *
1116route_set_community_delete_compile (char *arg)
1117{
1118 char *p;
1119 char *str;
1120 int len;
1121
1122 p = strchr (arg, ' ');
1123 if (p)
1124 {
1125 len = p - arg;
1126 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1127 memcpy (str, arg, len);
1128 }
1129 else
1130 str = NULL;
1131
1132 return str;
1133}
1134
1135/* Free function for set community. */
1136void
1137route_set_community_delete_free (void *rule)
1138{
1139 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1140}
1141
1142/* Set community rule structure. */
1143struct route_map_rule_cmd route_set_community_delete_cmd =
1144{
1145 "comm-list",
1146 route_set_community_delete,
1147 route_set_community_delete_compile,
1148 route_set_community_delete_free,
1149};
1150
1151/* `set extcommunity rt COMMUNITY' */
1152
1153/* For community set mechanism. */
1154route_map_result_t
1155route_set_ecommunity_rt (void *rule, struct prefix *prefix,
1156 route_map_object_t type, void *object)
1157{
1158 struct ecommunity *ecom;
1159 struct ecommunity *new_ecom;
1160 struct ecommunity *old_ecom;
1161 struct bgp_info *bgp_info;
1162
1163 if (type == RMAP_BGP)
1164 {
1165 ecom = rule;
1166 bgp_info = object;
1167
1168 if (! ecom)
1169 return RMAP_OKAY;
1170
1171 /* We assume additive for Extended Community. */
1172 old_ecom = bgp_info->attr->ecommunity;
1173
1174 if (old_ecom)
1175 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1176 else
1177 new_ecom = ecommunity_dup (ecom);
1178
1179 bgp_info->attr->ecommunity = new_ecom;
1180
1181 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1182 }
1183 return RMAP_OKAY;
1184}
1185
1186/* Compile function for set community. */
1187void *
1188route_set_ecommunity_rt_compile (char *arg)
1189{
1190 struct ecommunity *ecom;
1191
1192 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1193 if (! ecom)
1194 return NULL;
1195 return ecom;
1196}
1197
1198/* Free function for set community. */
1199void
1200route_set_ecommunity_rt_free (void *rule)
1201{
1202 struct ecommunity *ecom = rule;
1203 ecommunity_free (ecom);
1204}
1205
1206/* Set community rule structure. */
1207struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1208{
1209 "extcommunity rt",
1210 route_set_ecommunity_rt,
1211 route_set_ecommunity_rt_compile,
1212 route_set_ecommunity_rt_free,
1213};
1214
1215/* `set extcommunity soo COMMUNITY' */
1216
1217/* For community set mechanism. */
1218route_map_result_t
1219route_set_ecommunity_soo (void *rule, struct prefix *prefix,
1220 route_map_object_t type, void *object)
1221{
1222 struct ecommunity *ecom;
1223 struct bgp_info *bgp_info;
1224
1225 if (type == RMAP_BGP)
1226 {
1227 ecom = rule;
1228 bgp_info = object;
1229
1230 if (! ecom)
1231 return RMAP_OKAY;
1232
1233 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1234 bgp_info->attr->ecommunity = ecommunity_dup (ecom);
1235 }
1236 return RMAP_OKAY;
1237}
1238
1239/* Compile function for set community. */
1240void *
1241route_set_ecommunity_soo_compile (char *arg)
1242{
1243 struct ecommunity *ecom;
1244
1245 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1246 if (! ecom)
1247 return NULL;
1248
1249 return ecom;
1250}
1251
1252/* Free function for set community. */
1253void
1254route_set_ecommunity_soo_free (void *rule)
1255{
1256 struct ecommunity *ecom = rule;
1257 ecommunity_free (ecom);
1258}
1259
1260/* Set community rule structure. */
1261struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1262{
1263 "extcommunity soo",
1264 route_set_ecommunity_soo,
1265 route_set_ecommunity_soo_compile,
1266 route_set_ecommunity_soo_free,
1267};
1268
1269/* `set origin ORIGIN' */
1270
1271/* For origin set. */
1272route_map_result_t
1273route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1274{
1275 u_char *origin;
1276 struct bgp_info *bgp_info;
1277
1278 if (type == RMAP_BGP)
1279 {
1280 origin = rule;
1281 bgp_info = object;
1282
1283 bgp_info->attr->origin = *origin;
1284 }
1285
1286 return RMAP_OKAY;
1287}
1288
1289/* Compile function for origin set. */
1290void *
1291route_set_origin_compile (char *arg)
1292{
1293 u_char *origin;
1294
1295 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1296
1297 if (strcmp (arg, "igp") == 0)
1298 *origin = 0;
1299 else if (strcmp (arg, "egp") == 0)
1300 *origin = 1;
1301 else
1302 *origin = 2;
1303
1304 return origin;
1305}
1306
1307/* Compile function for origin set. */
1308void
1309route_set_origin_free (void *rule)
1310{
1311 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1312}
1313
1314/* Set metric rule structure. */
1315struct route_map_rule_cmd route_set_origin_cmd =
1316{
1317 "origin",
1318 route_set_origin,
1319 route_set_origin_compile,
1320 route_set_origin_free,
1321};
1322
1323/* `set atomic-aggregate' */
1324
1325/* For atomic aggregate set. */
1326route_map_result_t
1327route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1328 route_map_object_t type, void *object)
1329{
1330 struct bgp_info *bgp_info;
1331
1332 if (type == RMAP_BGP)
1333 {
1334 bgp_info = object;
1335 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1336 }
1337
1338 return RMAP_OKAY;
1339}
1340
1341/* Compile function for atomic aggregate. */
1342void *
1343route_set_atomic_aggregate_compile (char *arg)
1344{
1345 return (void *)1;
1346}
1347
1348/* Compile function for atomic aggregate. */
1349void
1350route_set_atomic_aggregate_free (void *rule)
1351{
1352 return;
1353}
1354
1355/* Set atomic aggregate rule structure. */
1356struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1357{
1358 "atomic-aggregate",
1359 route_set_atomic_aggregate,
1360 route_set_atomic_aggregate_compile,
1361 route_set_atomic_aggregate_free,
1362};
1363
1364/* `set aggregator as AS A.B.C.D' */
1365struct aggregator
1366{
1367 as_t as;
1368 struct in_addr address;
1369};
1370
1371route_map_result_t
1372route_set_aggregator_as (void *rule, struct prefix *prefix,
1373 route_map_object_t type, void *object)
1374{
1375 struct bgp_info *bgp_info;
1376 struct aggregator *aggregator;
1377
1378 if (type == RMAP_BGP)
1379 {
1380 bgp_info = object;
1381 aggregator = rule;
1382
1383 bgp_info->attr->aggregator_as = aggregator->as;
1384 bgp_info->attr->aggregator_addr = aggregator->address;
1385 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1386 }
1387
1388 return RMAP_OKAY;
1389}
1390
1391void *
1392route_set_aggregator_as_compile (char *arg)
1393{
1394 struct aggregator *aggregator;
1395 char as[10];
1396 char address[20];
1397
1398 aggregator = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
1399 memset (aggregator, 0, sizeof (struct aggregator));
1400
1401 sscanf (arg, "%s %s", as, address);
1402
1403 aggregator->as = strtoul (as, NULL, 10);
1404 inet_aton (address, &aggregator->address);
1405
1406 return aggregator;
1407}
1408
1409void
1410route_set_aggregator_as_free (void *rule)
1411{
1412 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1413}
1414
1415struct route_map_rule_cmd route_set_aggregator_as_cmd =
1416{
1417 "aggregator as",
1418 route_set_aggregator_as,
1419 route_set_aggregator_as_compile,
1420 route_set_aggregator_as_free,
1421};
1422
1423#ifdef HAVE_IPV6
1424/* `match ipv6 address IP_ACCESS_LIST' */
1425
1426route_map_result_t
1427route_match_ipv6_address (void *rule, struct prefix *prefix,
1428 route_map_object_t type, void *object)
1429{
1430 struct access_list *alist;
1431
1432 if (type == RMAP_BGP)
1433 {
1434 alist = access_list_lookup (AFI_IP6, (char *) rule);
1435 if (alist == NULL)
1436 return RMAP_NOMATCH;
1437
1438 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1439 RMAP_NOMATCH : RMAP_MATCH);
1440 }
1441 return RMAP_NOMATCH;
1442}
1443
1444void *
1445route_match_ipv6_address_compile (char *arg)
1446{
1447 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1448}
1449
1450void
1451route_match_ipv6_address_free (void *rule)
1452{
1453 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1454}
1455
1456/* Route map commands for ip address matching. */
1457struct route_map_rule_cmd route_match_ipv6_address_cmd =
1458{
1459 "ipv6 address",
1460 route_match_ipv6_address,
1461 route_match_ipv6_address_compile,
1462 route_match_ipv6_address_free
1463};
1464
1465/* `match ipv6 next-hop IP_ADDRESS' */
1466
1467route_map_result_t
1468route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1469 route_map_object_t type, void *object)
1470{
1471 struct in6_addr *addr;
1472 struct bgp_info *bgp_info;
1473
1474 if (type == RMAP_BGP)
1475 {
1476 addr = rule;
1477 bgp_info = object;
1478
1479 if (IPV6_ADDR_SAME (&bgp_info->attr->mp_nexthop_global, rule))
1480 return RMAP_MATCH;
1481
1482 if (bgp_info->attr->mp_nexthop_len == 32 &&
1483 IPV6_ADDR_SAME (&bgp_info->attr->mp_nexthop_local, rule))
1484 return RMAP_MATCH;
1485
1486 return RMAP_NOMATCH;
1487 }
1488
1489 return RMAP_NOMATCH;
1490}
1491
1492void *
1493route_match_ipv6_next_hop_compile (char *arg)
1494{
1495 struct in6_addr *address;
1496 int ret;
1497
1498 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1499
1500 ret = inet_pton (AF_INET6, arg, address);
1501 if (!ret)
1502 {
1503 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1504 return NULL;
1505 }
1506
1507 return address;
1508}
1509
1510void
1511route_match_ipv6_next_hop_free (void *rule)
1512{
1513 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1514}
1515
1516struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1517{
1518 "ipv6 next-hop",
1519 route_match_ipv6_next_hop,
1520 route_match_ipv6_next_hop_compile,
1521 route_match_ipv6_next_hop_free
1522};
1523
1524/* `match ipv6 address prefix-list PREFIX_LIST' */
1525
1526route_map_result_t
1527route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1528 route_map_object_t type, void *object)
1529{
1530 struct prefix_list *plist;
1531
1532 if (type == RMAP_BGP)
1533 {
1534 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1535 if (plist == NULL)
1536 return RMAP_NOMATCH;
1537
1538 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1539 RMAP_NOMATCH : RMAP_MATCH);
1540 }
1541 return RMAP_NOMATCH;
1542}
1543
1544void *
1545route_match_ipv6_address_prefix_list_compile (char *arg)
1546{
1547 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1548}
1549
1550void
1551route_match_ipv6_address_prefix_list_free (void *rule)
1552{
1553 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1554}
1555
1556struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1557{
1558 "ipv6 address prefix-list",
1559 route_match_ipv6_address_prefix_list,
1560 route_match_ipv6_address_prefix_list_compile,
1561 route_match_ipv6_address_prefix_list_free
1562};
1563
1564/* `set ipv6 nexthop global IP_ADDRESS' */
1565
1566/* Set nexthop to object. ojbect must be pointer to struct attr. */
1567route_map_result_t
1568route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1569 route_map_object_t type, void *object)
1570{
1571 struct in6_addr *address;
1572 struct bgp_info *bgp_info;
1573
1574 if (type == RMAP_BGP)
1575 {
1576 /* Fetch routemap's rule information. */
1577 address = rule;
1578 bgp_info = object;
1579
1580 /* Set next hop value. */
1581 bgp_info->attr->mp_nexthop_global = *address;
1582
1583 /* Set nexthop length. */
1584 if (bgp_info->attr->mp_nexthop_len == 0)
1585 bgp_info->attr->mp_nexthop_len = 16;
1586 }
1587
1588 return RMAP_OKAY;
1589}
1590
1591/* Route map `ip next-hop' compile function. Given string is converted
1592 to struct in_addr structure. */
1593void *
1594route_set_ipv6_nexthop_global_compile (char *arg)
1595{
1596 int ret;
1597 struct in6_addr *address;
1598
1599 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1600
1601 ret = inet_pton (AF_INET6, arg, address);
1602
1603 if (ret == 0)
1604 {
1605 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1606 return NULL;
1607 }
1608
1609 return address;
1610}
1611
1612/* Free route map's compiled `ip next-hop' value. */
1613void
1614route_set_ipv6_nexthop_global_free (void *rule)
1615{
1616 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1617}
1618
1619/* Route map commands for ip nexthop set. */
1620struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
1621{
1622 "ipv6 next-hop global",
1623 route_set_ipv6_nexthop_global,
1624 route_set_ipv6_nexthop_global_compile,
1625 route_set_ipv6_nexthop_global_free
1626};
1627
1628/* `set ipv6 nexthop local IP_ADDRESS' */
1629
1630/* Set nexthop to object. ojbect must be pointer to struct attr. */
1631route_map_result_t
1632route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
1633 route_map_object_t type, void *object)
1634{
1635 struct in6_addr *address;
1636 struct bgp_info *bgp_info;
1637
1638 if (type == RMAP_BGP)
1639 {
1640 /* Fetch routemap's rule information. */
1641 address = rule;
1642 bgp_info = object;
1643
1644 /* Set next hop value. */
1645 bgp_info->attr->mp_nexthop_local = *address;
1646
1647 /* Set nexthop length. */
1648 if (bgp_info->attr->mp_nexthop_len != 32)
1649 bgp_info->attr->mp_nexthop_len = 32;
1650 }
1651
1652 return RMAP_OKAY;
1653}
1654
1655/* Route map `ip nexthop' compile function. Given string is converted
1656 to struct in_addr structure. */
1657void *
1658route_set_ipv6_nexthop_local_compile (char *arg)
1659{
1660 int ret;
1661 struct in6_addr *address;
1662
1663 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1664
1665 ret = inet_pton (AF_INET6, arg, address);
1666
1667 if (ret == 0)
1668 {
1669 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1670 return NULL;
1671 }
1672
1673 return address;
1674}
1675
1676/* Free route map's compiled `ip nexthop' value. */
1677void
1678route_set_ipv6_nexthop_local_free (void *rule)
1679{
1680 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1681}
1682
1683/* Route map commands for ip nexthop set. */
1684struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
1685{
1686 "ipv6 next-hop local",
1687 route_set_ipv6_nexthop_local,
1688 route_set_ipv6_nexthop_local_compile,
1689 route_set_ipv6_nexthop_local_free
1690};
1691#endif /* HAVE_IPV6 */
1692
1693/* `set vpnv4 nexthop A.B.C.D' */
1694
1695route_map_result_t
1696route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
1697 route_map_object_t type, void *object)
1698{
1699 struct in_addr *address;
1700 struct bgp_info *bgp_info;
1701
1702 if (type == RMAP_BGP)
1703 {
1704 /* Fetch routemap's rule information. */
1705 address = rule;
1706 bgp_info = object;
1707
1708 /* Set next hop value. */
1709 bgp_info->attr->mp_nexthop_global_in = *address;
1710 }
1711
1712 return RMAP_OKAY;
1713}
1714
1715void *
1716route_set_vpnv4_nexthop_compile (char *arg)
1717{
1718 int ret;
1719 struct in_addr *address;
1720
1721 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
1722
1723 ret = inet_aton (arg, address);
1724
1725 if (ret == 0)
1726 {
1727 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1728 return NULL;
1729 }
1730
1731 return address;
1732}
1733
1734void
1735route_set_vpnv4_nexthop_free (void *rule)
1736{
1737 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1738}
1739
1740/* Route map commands for ip nexthop set. */
1741struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
1742{
1743 "vpnv4 next-hop",
1744 route_set_vpnv4_nexthop,
1745 route_set_vpnv4_nexthop_compile,
1746 route_set_vpnv4_nexthop_free
1747};
1748
1749/* `set originator-id' */
1750
1751/* For origin set. */
1752route_map_result_t
1753route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1754{
1755 struct in_addr *address;
1756 struct bgp_info *bgp_info;
1757
1758 if (type == RMAP_BGP)
1759 {
1760 address = rule;
1761 bgp_info = object;
1762
1763 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
1764 bgp_info->attr->originator_id = *address;
1765 }
1766
1767 return RMAP_OKAY;
1768}
1769
1770/* Compile function for originator-id set. */
1771void *
1772route_set_originator_id_compile (char *arg)
1773{
1774 int ret;
1775 struct in_addr *address;
1776
1777 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
1778
1779 ret = inet_aton (arg, address);
1780
1781 if (ret == 0)
1782 {
1783 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1784 return NULL;
1785 }
1786
1787 return address;
1788}
1789
1790/* Compile function for originator_id set. */
1791void
1792route_set_originator_id_free (void *rule)
1793{
1794 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1795}
1796
1797/* Set metric rule structure. */
1798struct route_map_rule_cmd route_set_originator_id_cmd =
1799{
1800 "originator-id",
1801 route_set_originator_id,
1802 route_set_originator_id_compile,
1803 route_set_originator_id_free,
1804};
1805
1806/* Add bgp route map rule. */
1807int
1808bgp_route_match_add (struct vty *vty, struct route_map_index *index,
1809 char *command, char *arg)
1810{
1811 int ret;
1812
1813 ret = route_map_add_match (index, command, arg);
1814 if (ret)
1815 {
1816 switch (ret)
1817 {
1818 case RMAP_RULE_MISSING:
1819 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
1820 return CMD_WARNING;
1821 break;
1822 case RMAP_COMPILE_ERROR:
1823 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
1824 return CMD_WARNING;
1825 break;
1826 }
1827 }
1828 return CMD_SUCCESS;
1829}
1830
1831/* Delete bgp route map rule. */
1832int
1833bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
1834 char *command, char *arg)
1835{
1836 int ret;
1837
1838 ret = route_map_delete_match (index, command, arg);
1839 if (ret)
1840 {
1841 switch (ret)
1842 {
1843 case RMAP_RULE_MISSING:
1844 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
1845 return CMD_WARNING;
1846 break;
1847 case RMAP_COMPILE_ERROR:
1848 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
1849 return CMD_WARNING;
1850 break;
1851 }
1852 }
1853 return CMD_SUCCESS;
1854}
1855
1856/* Add bgp route map rule. */
1857int
1858bgp_route_set_add (struct vty *vty, struct route_map_index *index,
1859 char *command, char *arg)
1860{
1861 int ret;
1862
1863 ret = route_map_add_set (index, command, arg);
1864 if (ret)
1865 {
1866 switch (ret)
1867 {
1868 case RMAP_RULE_MISSING:
1869 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
1870 return CMD_WARNING;
1871 break;
1872 case RMAP_COMPILE_ERROR:
1873 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
1874 return CMD_WARNING;
1875 break;
1876 }
1877 }
1878 return CMD_SUCCESS;
1879}
1880
1881/* Delete bgp route map rule. */
1882int
1883bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
1884 char *command, char *arg)
1885{
1886 int ret;
1887
1888 ret = route_map_delete_set (index, command, arg);
1889 if (ret)
1890 {
1891 switch (ret)
1892 {
1893 case RMAP_RULE_MISSING:
1894 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
1895 return CMD_WARNING;
1896 break;
1897 case RMAP_COMPILE_ERROR:
1898 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
1899 return CMD_WARNING;
1900 break;
1901 }
1902 }
1903 return CMD_SUCCESS;
1904}
1905
1906/* Hook function for updating route_map assignment. */
1907void
1908bgp_route_map_update ()
1909{
1910 int i;
1911 afi_t afi;
1912 safi_t safi;
1913 int direct;
1914 struct listnode *nn, *nm;
1915 struct bgp *bgp;
1916 struct peer *peer;
1917 struct peer_group *group;
1918 struct bgp_filter *filter;
1919 struct bgp_node *bn;
1920 struct bgp_static *bgp_static;
1921
1922 /* For neighbor route-map updates. */
1923 LIST_LOOP (bm->bgp, bgp, nn)
1924 {
1925 LIST_LOOP (bgp->peer, peer, nm)
1926 {
1927 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1928 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
1929 {
1930 filter = &peer->filter[afi][safi];
1931
1932 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
1933 {
1934 if (filter->map[direct].name)
1935 filter->map[direct].map =
1936 route_map_lookup_by_name (filter->map[direct].name);
1937 else
1938 filter->map[direct].map = NULL;
1939 }
1940
1941 if (filter->usmap.name)
1942 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
1943 else
1944 filter->usmap.map = NULL;
1945 }
1946 }
1947 LIST_LOOP (bgp->group, group, nm)
1948 {
1949 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1950 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
1951 {
1952 filter = &group->conf->filter[afi][safi];
1953
1954 for (direct = FILTER_IN; direct < FILTER_MAX; direct++)
1955 {
1956 if (filter->map[direct].name)
1957 filter->map[direct].map =
1958 route_map_lookup_by_name (filter->map[direct].name);
1959 else
1960 filter->map[direct].map = NULL;
1961 }
1962
1963 if (filter->usmap.name)
1964 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
1965 else
1966 filter->usmap.map = NULL;
1967 }
1968 }
1969 }
1970
1971 /* For default-originate route-map updates. */
1972 LIST_LOOP (bm->bgp, bgp, nn)
1973 {
1974 LIST_LOOP (bgp->peer, peer, nm)
1975 {
1976 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1977 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
1978 {
1979 if (peer->default_rmap[afi][safi].name)
1980 peer->default_rmap[afi][safi].map =
1981 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
1982 else
1983 peer->default_rmap[afi][safi].map = NULL;
1984 }
1985 }
1986 }
1987
1988 /* For network route-map updates. */
1989 LIST_LOOP (bm->bgp, bgp, nn)
1990 {
1991 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1992 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
1993 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
1994 bn = bgp_route_next (bn))
1995 if ((bgp_static = bn->info) != NULL)
1996 {
1997 if (bgp_static->rmap.name)
1998 bgp_static->rmap.map =
1999 route_map_lookup_by_name (bgp_static->rmap.name);
2000 else
2001 bgp_static->rmap.map = NULL;
2002 }
2003 }
2004
2005 /* For redistribute route-map updates. */
2006 LIST_LOOP (bm->bgp, bgp, nn)
2007 {
2008 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2009 {
2010 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2011 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2012 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2013#ifdef HAVE_IPV6
2014 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2015 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2016 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2017#endif /* HAVE_IPV6 */
2018 }
2019 }
2020}
2021
2022DEFUN (match_ip_address,
2023 match_ip_address_cmd,
2024 "match ip address (<1-199>|<1300-2699>|WORD)",
2025 MATCH_STR
2026 IP_STR
2027 "Match address of route\n"
2028 "IP access-list number\n"
2029 "IP access-list number (expanded range)\n"
2030 "IP Access-list name\n")
2031{
2032 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2033}
2034
2035DEFUN (no_match_ip_address,
2036 no_match_ip_address_cmd,
2037 "no match ip address",
2038 NO_STR
2039 MATCH_STR
2040 IP_STR
2041 "Match address of route\n")
2042{
2043 if (argc == 0)
2044 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2045
2046 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2047}
2048
2049ALIAS (no_match_ip_address,
2050 no_match_ip_address_val_cmd,
2051 "no match ip address (<1-199>|<1300-2699>|WORD)",
2052 NO_STR
2053 MATCH_STR
2054 IP_STR
2055 "Match address of route\n"
2056 "IP access-list number\n"
2057 "IP access-list number (expanded range)\n"
2058 "IP Access-list name\n")
2059
2060DEFUN (match_ip_next_hop,
2061 match_ip_next_hop_cmd,
2062 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2063 MATCH_STR
2064 IP_STR
2065 "Match next-hop address of route\n"
2066 "IP access-list number\n"
2067 "IP access-list number (expanded range)\n"
2068 "IP Access-list name\n")
2069{
2070 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2071}
2072
2073DEFUN (no_match_ip_next_hop,
2074 no_match_ip_next_hop_cmd,
2075 "no match ip next-hop",
2076 NO_STR
2077 MATCH_STR
2078 IP_STR
2079 "Match next-hop address of route\n")
2080{
2081 if (argc == 0)
2082 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2083
2084 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2085}
2086
2087ALIAS (no_match_ip_next_hop,
2088 no_match_ip_next_hop_val_cmd,
2089 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2090 NO_STR
2091 MATCH_STR
2092 IP_STR
2093 "Match next-hop address of route\n"
2094 "IP access-list number\n"
2095 "IP access-list number (expanded range)\n"
2096 "IP Access-list name\n")
2097
2098DEFUN (match_ip_address_prefix_list,
2099 match_ip_address_prefix_list_cmd,
2100 "match ip address prefix-list WORD",
2101 MATCH_STR
2102 IP_STR
2103 "Match address of route\n"
2104 "Match entries of prefix-lists\n"
2105 "IP prefix-list name\n")
2106{
2107 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2108}
2109
2110DEFUN (no_match_ip_address_prefix_list,
2111 no_match_ip_address_prefix_list_cmd,
2112 "no match ip address prefix-list",
2113 NO_STR
2114 MATCH_STR
2115 IP_STR
2116 "Match address of route\n"
2117 "Match entries of prefix-lists\n")
2118{
2119 if (argc == 0)
2120 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2121
2122 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2123}
2124
2125ALIAS (no_match_ip_address_prefix_list,
2126 no_match_ip_address_prefix_list_val_cmd,
2127 "no match ip address prefix-list WORD",
2128 NO_STR
2129 MATCH_STR
2130 IP_STR
2131 "Match address of route\n"
2132 "Match entries of prefix-lists\n"
2133 "IP prefix-list name\n")
2134
2135DEFUN (match_ip_next_hop_prefix_list,
2136 match_ip_next_hop_prefix_list_cmd,
2137 "match ip next-hop prefix-list WORD",
2138 MATCH_STR
2139 IP_STR
2140 "Match next-hop address of route\n"
2141 "Match entries of prefix-lists\n"
2142 "IP prefix-list name\n")
2143{
2144 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2145}
2146
2147DEFUN (no_match_ip_next_hop_prefix_list,
2148 no_match_ip_next_hop_prefix_list_cmd,
2149 "no match ip next-hop prefix-list",
2150 NO_STR
2151 MATCH_STR
2152 IP_STR
2153 "Match next-hop address of route\n"
2154 "Match entries of prefix-lists\n")
2155{
2156 if (argc == 0)
2157 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2158
2159 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2160}
2161
2162ALIAS (no_match_ip_next_hop_prefix_list,
2163 no_match_ip_next_hop_prefix_list_val_cmd,
2164 "no match ip next-hop prefix-list WORD",
2165 NO_STR
2166 MATCH_STR
2167 IP_STR
2168 "Match next-hop address of route\n"
2169 "Match entries of prefix-lists\n"
2170 "IP prefix-list name\n")
2171
2172DEFUN (match_metric,
2173 match_metric_cmd,
2174 "match metric <0-4294967295>",
2175 MATCH_STR
2176 "Match metric of route\n"
2177 "Metric value\n")
2178{
2179 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2180}
2181
2182DEFUN (no_match_metric,
2183 no_match_metric_cmd,
2184 "no match metric",
2185 NO_STR
2186 MATCH_STR
2187 "Match metric of route\n")
2188{
2189 if (argc == 0)
2190 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2191
2192 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2193}
2194
2195ALIAS (no_match_metric,
2196 no_match_metric_val_cmd,
2197 "no match metric <0-4294967295>",
2198 NO_STR
2199 MATCH_STR
2200 "Match metric of route\n"
2201 "Metric value\n")
2202
2203DEFUN (match_community,
2204 match_community_cmd,
2205 "match community (<1-99>|<100-199>|WORD)",
2206 MATCH_STR
2207 "Match BGP community list\n"
2208 "Community-list number (standard)\n"
2209 "Community-list number (expanded)\n"
2210 "Community-list name\n")
2211{
2212 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2213}
2214
2215DEFUN (match_community_exact,
2216 match_community_exact_cmd,
2217 "match community (<1-99>|<100-199>|WORD) exact-match",
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{
2225 int ret;
2226 char *argstr;
2227
2228 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2229 strlen (argv[0]) + strlen ("exact-match") + 2);
2230
2231 sprintf (argstr, "%s exact-match", argv[0]);
2232
2233 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2234
2235 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2236
2237 return ret;
2238}
2239
2240DEFUN (no_match_community,
2241 no_match_community_cmd,
2242 "no match community",
2243 NO_STR
2244 MATCH_STR
2245 "Match BGP community list\n")
2246{
2247 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2248}
2249
2250ALIAS (no_match_community,
2251 no_match_community_val_cmd,
2252 "no match community (<1-99>|<100-199>|WORD)",
2253 NO_STR
2254 MATCH_STR
2255 "Match BGP community list\n"
2256 "Community-list number (standard)\n"
2257 "Community-list number (expanded)\n"
2258 "Community-list name\n")
2259
2260ALIAS (no_match_community,
2261 no_match_community_exact_cmd,
2262 "no match community (<1-99>|<100-199>|WORD) exact-match",
2263 NO_STR
2264 MATCH_STR
2265 "Match BGP community list\n"
2266 "Community-list number (standard)\n"
2267 "Community-list number (expanded)\n"
2268 "Community-list name\n"
2269 "Do exact matching of communities\n")
2270
paul73ffb252003-04-19 15:49:49 +00002271DEFUN (match_ecommunity,
2272 match_ecommunity_cmd,
2273 "match extcommunity (<1-99>|<100-199>|WORD)",
2274 MATCH_STR
2275 "Match BGP/VPN extended community list\n"
2276 "Extended community-list number (standard)\n"
2277 "Extended community-list number (expanded)\n"
2278 "Extended community-list name\n")
2279{
2280 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2281}
2282
2283DEFUN (no_match_ecommunity,
2284 no_match_ecommunity_cmd,
2285 "no match extcommunity",
2286 NO_STR
2287 MATCH_STR
2288 "Match BGP/VPN extended community list\n")
2289{
2290 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2291}
2292
2293ALIAS (no_match_ecommunity,
2294 no_match_ecommunity_val_cmd,
2295 "no match extcommunity (<1-99>|<100-199>|WORD)",
2296 NO_STR
2297 MATCH_STR
2298 "Match BGP/VPN extended community list\n"
2299 "Extended community-list number (standard)\n"
2300 "Extended community-list number (expanded)\n"
2301 "Extended community-list name\n")
2302
paul718e3742002-12-13 20:15:29 +00002303DEFUN (match_aspath,
2304 match_aspath_cmd,
2305 "match as-path WORD",
2306 MATCH_STR
2307 "Match BGP AS path list\n"
2308 "AS path access-list name\n")
2309{
2310 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2311}
2312
2313DEFUN (no_match_aspath,
2314 no_match_aspath_cmd,
2315 "no match as-path",
2316 NO_STR
2317 MATCH_STR
2318 "Match BGP AS path list\n")
2319{
2320 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2321}
2322
2323ALIAS (no_match_aspath,
2324 no_match_aspath_val_cmd,
2325 "no match as-path WORD",
2326 NO_STR
2327 MATCH_STR
2328 "Match BGP AS path list\n"
2329 "AS path access-list name\n")
2330
2331DEFUN (match_origin,
2332 match_origin_cmd,
2333 "match origin (egp|igp|incomplete)",
2334 MATCH_STR
2335 "BGP origin code\n"
2336 "remote EGP\n"
2337 "local IGP\n"
2338 "unknown heritage\n")
2339{
2340 if (strncmp (argv[0], "igp", 2) == 0)
2341 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2342 if (strncmp (argv[0], "egp", 1) == 0)
2343 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2344 if (strncmp (argv[0], "incomplete", 2) == 0)
2345 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2346
2347 return CMD_WARNING;
2348}
2349
2350DEFUN (no_match_origin,
2351 no_match_origin_cmd,
2352 "no match origin",
2353 NO_STR
2354 MATCH_STR
2355 "BGP origin code\n")
2356{
2357 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2358}
2359
2360ALIAS (no_match_origin,
2361 no_match_origin_val_cmd,
2362 "no match origin (egp|igp|incomplete)",
2363 NO_STR
2364 MATCH_STR
2365 "BGP origin code\n"
2366 "remote EGP\n"
2367 "local IGP\n"
2368 "unknown heritage\n")
2369
2370DEFUN (set_ip_nexthop,
2371 set_ip_nexthop_cmd,
2372 "set ip next-hop A.B.C.D",
2373 SET_STR
2374 IP_STR
2375 "Next hop address\n"
2376 "IP address of next hop\n")
2377{
2378 union sockunion su;
2379 int ret;
2380
2381 ret = str2sockunion (argv[0], &su);
2382 if (ret < 0)
2383 {
2384 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2385 return CMD_WARNING;
2386 }
2387
2388 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2389}
2390
2391DEFUN (no_set_ip_nexthop,
2392 no_set_ip_nexthop_cmd,
2393 "no set ip next-hop",
2394 NO_STR
2395 SET_STR
2396 IP_STR
2397 "Next hop address\n")
2398{
2399 if (argc == 0)
2400 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2401
2402 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2403}
2404
2405ALIAS (no_set_ip_nexthop,
2406 no_set_ip_nexthop_val_cmd,
2407 "no set ip next-hop A.B.C.D",
2408 NO_STR
2409 SET_STR
2410 IP_STR
2411 "Next hop address\n"
2412 "IP address of next hop\n")
2413
2414DEFUN (set_metric,
2415 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002416 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002417 SET_STR
2418 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002419 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002420{
2421 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2422}
2423
paul73ffb252003-04-19 15:49:49 +00002424ALIAS (set_metric,
2425 set_metric_addsub_cmd,
2426 "set metric <+/-metric>",
2427 SET_STR
2428 "Metric value for destination routing protocol\n"
2429 "Add or subtract BGP metric\n")
2430
paul718e3742002-12-13 20:15:29 +00002431DEFUN (no_set_metric,
2432 no_set_metric_cmd,
2433 "no set metric",
2434 NO_STR
2435 SET_STR
2436 "Metric value for destination routing protocol\n")
2437{
2438 if (argc == 0)
2439 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
2440
2441 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
2442}
2443
2444ALIAS (no_set_metric,
2445 no_set_metric_val_cmd,
2446 "no set metric <0-4294967295>",
2447 NO_STR
2448 SET_STR
2449 "Metric value for destination routing protocol\n"
2450 "Metric value\n")
2451
2452DEFUN (set_local_pref,
2453 set_local_pref_cmd,
2454 "set local-preference <0-4294967295>",
2455 SET_STR
2456 "BGP local preference path attribute\n"
2457 "Preference value\n")
2458{
2459 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
2460}
2461
2462DEFUN (no_set_local_pref,
2463 no_set_local_pref_cmd,
2464 "no set local-preference",
2465 NO_STR
2466 SET_STR
2467 "BGP local preference path attribute\n")
2468{
2469 if (argc == 0)
2470 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
2471
2472 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
2473}
2474
2475ALIAS (no_set_local_pref,
2476 no_set_local_pref_val_cmd,
2477 "no set local-preference <0-4294967295>",
2478 NO_STR
2479 SET_STR
2480 "BGP local preference path attribute\n"
2481 "Preference value\n")
2482
2483DEFUN (set_weight,
2484 set_weight_cmd,
2485 "set weight <0-4294967295>",
2486 SET_STR
2487 "BGP weight for routing table\n"
2488 "Weight value\n")
2489{
2490 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
2491}
2492
2493DEFUN (no_set_weight,
2494 no_set_weight_cmd,
2495 "no set weight",
2496 NO_STR
2497 SET_STR
2498 "BGP weight for routing table\n")
2499{
2500 if (argc == 0)
2501 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
2502
2503 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
2504}
2505
2506ALIAS (no_set_weight,
2507 no_set_weight_val_cmd,
2508 "no set weight <0-4294967295>",
2509 NO_STR
2510 SET_STR
2511 "BGP weight for routing table\n"
2512 "Weight value\n")
2513
2514DEFUN (set_aspath_prepend,
2515 set_aspath_prepend_cmd,
2516 "set as-path prepend .<1-65535>",
2517 SET_STR
2518 "Prepend string for a BGP AS-path attribute\n"
2519 "Prepend to the as-path\n"
2520 "AS number\n")
2521{
2522 int ret;
2523 char *str;
2524
2525 str = argv_concat (argv, argc, 0);
2526 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
2527 XFREE (MTYPE_TMP, str);
2528
2529 return ret;
2530}
2531
2532DEFUN (no_set_aspath_prepend,
2533 no_set_aspath_prepend_cmd,
2534 "no set as-path prepend",
2535 NO_STR
2536 SET_STR
2537 "Prepend string for a BGP AS-path attribute\n"
2538 "Prepend to the as-path\n")
2539{
2540 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
2541}
2542
2543ALIAS (no_set_aspath_prepend,
2544 no_set_aspath_prepend_val_cmd,
2545 "no set as-path prepend .<1-65535>",
2546 NO_STR
2547 SET_STR
2548 "Prepend string for a BGP AS-path attribute\n"
2549 "Prepend to the as-path\n"
2550 "AS number\n")
2551
2552DEFUN (set_community,
2553 set_community_cmd,
2554 "set community .AA:NN",
2555 SET_STR
2556 "BGP community attribute\n"
2557 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
2558{
2559 int i;
2560 int first = 0;
2561 int additive = 0;
2562 struct buffer *b;
2563 struct community *com = NULL;
2564 char *str;
2565 char *argstr;
2566 int ret;
2567
2568 b = buffer_new (1024);
2569
2570 for (i = 0; i < argc; i++)
2571 {
2572 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
2573 {
2574 additive = 1;
2575 continue;
2576 }
2577
2578 if (first)
2579 buffer_putc (b, ' ');
2580 else
2581 first = 1;
2582
2583 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
2584 {
2585 buffer_putstr (b, "internet");
2586 continue;
2587 }
2588 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
2589 {
2590 buffer_putstr (b, "local-AS");
2591 continue;
2592 }
2593 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
2594 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
2595 {
2596 buffer_putstr (b, "no-advertise");
2597 continue;
2598 }
2599 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
2600 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
2601 {
2602 buffer_putstr (b, "no-export");
2603 continue;
2604 }
2605 buffer_putstr (b, argv[i]);
2606 }
2607 buffer_putc (b, '\0');
2608
2609 /* Fetch result string then compile it to communities attribute. */
2610 str = buffer_getstr (b);
2611 buffer_free (b);
2612
2613 if (str)
2614 {
2615 com = community_str2com (str);
2616 free (str);
2617 }
2618
2619 /* Can't compile user input into communities attribute. */
2620 if (! com)
2621 {
2622 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
2623 return CMD_WARNING;
2624 }
2625
2626 /* Set communites attribute string. */
2627 str = community_str (com);
2628
2629 if (additive)
2630 {
2631 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
2632 strcpy (argstr, str);
2633 strcpy (argstr + strlen (str), " additive");
2634 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
2635 XFREE (MTYPE_TMP, argstr);
2636 }
2637 else
2638 ret = bgp_route_set_add (vty, vty->index, "community", str);
2639
2640 community_free (com);
2641
2642 return ret;
2643}
2644
2645DEFUN (set_community_none,
2646 set_community_none_cmd,
2647 "set community none",
2648 SET_STR
2649 "BGP community attribute\n"
2650 "No community attribute\n")
2651{
2652 return bgp_route_set_add (vty, vty->index, "community", "none");
2653}
2654
2655DEFUN (no_set_community,
2656 no_set_community_cmd,
2657 "no set community",
2658 NO_STR
2659 SET_STR
2660 "BGP community attribute\n")
2661{
2662 return bgp_route_set_delete (vty, vty->index, "community", NULL);
2663}
2664
2665ALIAS (no_set_community,
2666 no_set_community_val_cmd,
2667 "no set community .AA:NN",
2668 NO_STR
2669 SET_STR
2670 "BGP community attribute\n"
2671 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
2672
2673ALIAS (no_set_community,
2674 no_set_community_none_cmd,
2675 "no set community none",
2676 NO_STR
2677 SET_STR
2678 "BGP community attribute\n"
2679 "No community attribute\n")
2680
2681DEFUN (set_community_delete,
2682 set_community_delete_cmd,
2683 "set comm-list (<1-99>|<100-199>|WORD) delete",
2684 SET_STR
2685 "set BGP community list (for deletion)\n"
2686 "Community-list number (standard)\n"
2687 "Communitly-list number (expanded)\n"
2688 "Community-list name\n"
2689 "Delete matching communities\n")
2690{
2691 char *str;
2692
2693 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
2694 strcpy (str, argv[0]);
2695 strcpy (str + strlen (argv[0]), " delete");
2696
2697 bgp_route_set_add (vty, vty->index, "comm-list", str);
2698
2699 XFREE (MTYPE_TMP, str);
2700 return CMD_SUCCESS;
2701}
2702
2703DEFUN (no_set_community_delete,
2704 no_set_community_delete_cmd,
2705 "no set comm-list",
2706 NO_STR
2707 SET_STR
2708 "set BGP community list (for deletion)\n")
2709{
2710 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
2711}
2712
2713ALIAS (no_set_community_delete,
2714 no_set_community_delete_val_cmd,
2715 "no set comm-list (<1-99>|<100-199>|WORD) delete",
2716 NO_STR
2717 SET_STR
2718 "set BGP community list (for deletion)\n"
2719 "Community-list number (standard)\n"
2720 "Communitly-list number (expanded)\n"
2721 "Community-list name\n"
2722 "Delete matching communities\n")
2723
2724DEFUN (set_ecommunity_rt,
2725 set_ecommunity_rt_cmd,
2726 "set extcommunity rt .ASN:nn_or_IP-address:nn",
2727 SET_STR
2728 "BGP extended community attribute\n"
2729 "Route Target extened communityt\n"
2730 "VPN extended community\n")
2731{
2732 int ret;
2733 char *str;
2734
2735 str = argv_concat (argv, argc, 0);
2736 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
2737 XFREE (MTYPE_TMP, str);
2738
2739 return ret;
2740}
2741
2742DEFUN (no_set_ecommunity_rt,
2743 no_set_ecommunity_rt_cmd,
2744 "no set extcommunity rt",
2745 NO_STR
2746 SET_STR
2747 "BGP extended community attribute\n"
2748 "Route Target extened communityt\n")
2749{
2750 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
2751}
2752
2753ALIAS (no_set_ecommunity_rt,
2754 no_set_ecommunity_rt_val_cmd,
2755 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
2756 NO_STR
2757 SET_STR
2758 "BGP extended community attribute\n"
2759 "Route Target extened communityt\n"
2760 "VPN extended community\n")
2761
2762DEFUN (set_ecommunity_soo,
2763 set_ecommunity_soo_cmd,
2764 "set extcommunity soo .ASN:nn_or_IP-address:nn",
2765 SET_STR
2766 "BGP extended community attribute\n"
2767 "Site-of-Origin extended community\n"
2768 "VPN extended community\n")
2769{
2770 int ret;
2771 char *str;
2772
2773 str = argv_concat (argv, argc, 0);
2774 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
2775 XFREE (MTYPE_TMP, str);
2776 return ret;
2777}
2778
2779DEFUN (no_set_ecommunity_soo,
2780 no_set_ecommunity_soo_cmd,
2781 "no set extcommunity soo",
2782 NO_STR
2783 SET_STR
2784 "BGP extended community attribute\n"
2785 "Site-of-Origin extended community\n")
2786{
2787 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
2788}
2789
2790ALIAS (no_set_ecommunity_soo,
2791 no_set_ecommunity_soo_val_cmd,
2792 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
2793 NO_STR
2794 SET_STR
2795 "BGP extended community attribute\n"
2796 "Site-of-Origin extended community\n"
2797 "VPN extended community\n")
2798
2799DEFUN (set_origin,
2800 set_origin_cmd,
2801 "set origin (egp|igp|incomplete)",
2802 SET_STR
2803 "BGP origin code\n"
2804 "remote EGP\n"
2805 "local IGP\n"
2806 "unknown heritage\n")
2807{
2808 if (strncmp (argv[0], "igp", 2) == 0)
2809 return bgp_route_set_add (vty, vty->index, "origin", "igp");
2810 if (strncmp (argv[0], "egp", 1) == 0)
2811 return bgp_route_set_add (vty, vty->index, "origin", "egp");
2812 if (strncmp (argv[0], "incomplete", 2) == 0)
2813 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
2814
2815 return CMD_WARNING;
2816}
2817
2818DEFUN (no_set_origin,
2819 no_set_origin_cmd,
2820 "no set origin",
2821 NO_STR
2822 SET_STR
2823 "BGP origin code\n")
2824{
2825 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
2826}
2827
2828ALIAS (no_set_origin,
2829 no_set_origin_val_cmd,
2830 "no set origin (egp|igp|incomplete)",
2831 NO_STR
2832 SET_STR
2833 "BGP origin code\n"
2834 "remote EGP\n"
2835 "local IGP\n"
2836 "unknown heritage\n")
2837
2838DEFUN (set_atomic_aggregate,
2839 set_atomic_aggregate_cmd,
2840 "set atomic-aggregate",
2841 SET_STR
2842 "BGP atomic aggregate attribute\n" )
2843{
2844 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
2845}
2846
2847DEFUN (no_set_atomic_aggregate,
2848 no_set_atomic_aggregate_cmd,
2849 "no set atomic-aggregate",
2850 NO_STR
2851 SET_STR
2852 "BGP atomic aggregate attribute\n" )
2853{
2854 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
2855}
2856
2857DEFUN (set_aggregator_as,
2858 set_aggregator_as_cmd,
2859 "set aggregator as <1-65535> A.B.C.D",
2860 SET_STR
2861 "BGP aggregator attribute\n"
2862 "AS number of aggregator\n"
2863 "AS number\n"
2864 "IP address of aggregator\n")
2865{
2866 int ret;
2867 as_t as;
2868 struct in_addr address;
2869 char *endptr = NULL;
2870 char *argstr;
2871
2872 as = strtoul (argv[0], &endptr, 10);
2873 if (as == 0 || as == ULONG_MAX || *endptr != '\0')
2874 {
2875 vty_out (vty, "AS path value malformed%s", VTY_NEWLINE);
2876 return CMD_WARNING;
2877 }
2878
2879 ret = inet_aton (argv[1], &address);
2880 if (ret == 0)
2881 {
2882 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
2883 return CMD_WARNING;
2884 }
2885
2886 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2887 strlen (argv[0]) + strlen (argv[1]) + 2);
2888
2889 sprintf (argstr, "%s %s", argv[0], argv[1]);
2890
2891 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
2892
2893 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2894
2895 return ret;
2896}
2897
2898DEFUN (no_set_aggregator_as,
2899 no_set_aggregator_as_cmd,
2900 "no set aggregator as",
2901 NO_STR
2902 SET_STR
2903 "BGP aggregator attribute\n"
2904 "AS number of aggregator\n")
2905{
2906 int ret;
2907 as_t as;
2908 struct in_addr address;
2909 char *endptr = NULL;
2910 char *argstr;
2911
2912 if (argv == 0)
2913 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
2914
2915 as = strtoul (argv[0], &endptr, 10);
2916 if (as == 0 || as == ULONG_MAX || *endptr != '\0')
2917 {
2918 vty_out (vty, "AS path value malformed%s", VTY_NEWLINE);
2919 return CMD_WARNING;
2920 }
2921
2922 ret = inet_aton (argv[1], &address);
2923 if (ret == 0)
2924 {
2925 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
2926 return CMD_WARNING;
2927 }
2928
2929 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2930 strlen (argv[0]) + strlen (argv[1]) + 2);
2931
2932 sprintf (argstr, "%s %s", argv[0], argv[1]);
2933
2934 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
2935
2936 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2937
2938 return ret;
2939}
2940
2941ALIAS (no_set_aggregator_as,
2942 no_set_aggregator_as_val_cmd,
2943 "no set aggregator as <1-65535> A.B.C.D",
2944 NO_STR
2945 SET_STR
2946 "BGP aggregator attribute\n"
2947 "AS number of aggregator\n"
2948 "AS number\n"
2949 "IP address of aggregator\n")
2950
2951
2952#ifdef HAVE_IPV6
2953DEFUN (match_ipv6_address,
2954 match_ipv6_address_cmd,
2955 "match ipv6 address WORD",
2956 MATCH_STR
2957 IPV6_STR
2958 "Match IPv6 address of route\n"
2959 "IPv6 access-list name\n")
2960{
2961 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
2962}
2963
2964DEFUN (no_match_ipv6_address,
2965 no_match_ipv6_address_cmd,
2966 "no match ipv6 address WORD",
2967 NO_STR
2968 MATCH_STR
2969 IPV6_STR
2970 "Match IPv6 address of route\n"
2971 "IPv6 access-list name\n")
2972{
2973 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
2974}
2975
2976DEFUN (match_ipv6_next_hop,
2977 match_ipv6_next_hop_cmd,
2978 "match ipv6 next-hop X:X::X:X",
2979 MATCH_STR
2980 IPV6_STR
2981 "Match IPv6 next-hop address of route\n"
2982 "IPv6 address of next hop\n")
2983{
2984 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
2985}
2986
2987DEFUN (no_match_ipv6_next_hop,
2988 no_match_ipv6_next_hop_cmd,
2989 "no match ipv6 next-hop X:X::X:X",
2990 NO_STR
2991 MATCH_STR
2992 IPV6_STR
2993 "Match IPv6 next-hop address of route\n"
2994 "IPv6 address of next hop\n")
2995{
2996 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
2997}
2998
2999DEFUN (match_ipv6_address_prefix_list,
3000 match_ipv6_address_prefix_list_cmd,
3001 "match ipv6 address prefix-list WORD",
3002 MATCH_STR
3003 IPV6_STR
3004 "Match address of route\n"
3005 "Match entries of prefix-lists\n"
3006 "IP prefix-list name\n")
3007{
3008 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3009}
3010
3011DEFUN (no_match_ipv6_address_prefix_list,
3012 no_match_ipv6_address_prefix_list_cmd,
3013 "no match ipv6 address prefix-list WORD",
3014 NO_STR
3015 MATCH_STR
3016 IPV6_STR
3017 "Match address of route\n"
3018 "Match entries of prefix-lists\n"
3019 "IP prefix-list name\n")
3020{
3021 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3022}
3023
3024DEFUN (set_ipv6_nexthop_global,
3025 set_ipv6_nexthop_global_cmd,
3026 "set ipv6 next-hop global X:X::X:X",
3027 SET_STR
3028 IPV6_STR
3029 "IPv6 next-hop address\n"
3030 "IPv6 global address\n"
3031 "IPv6 address of next hop\n")
3032{
3033 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3034}
3035
3036DEFUN (no_set_ipv6_nexthop_global,
3037 no_set_ipv6_nexthop_global_cmd,
3038 "no set ipv6 next-hop global",
3039 NO_STR
3040 SET_STR
3041 IPV6_STR
3042 "IPv6 next-hop address\n"
3043 "IPv6 global address\n")
3044{
3045 if (argc == 0)
3046 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3047
3048 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3049}
3050
3051ALIAS (no_set_ipv6_nexthop_global,
3052 no_set_ipv6_nexthop_global_val_cmd,
3053 "no set ipv6 next-hop global X:X::X:X",
3054 NO_STR
3055 SET_STR
3056 IPV6_STR
3057 "IPv6 next-hop address\n"
3058 "IPv6 global address\n"
3059 "IPv6 address of next hop\n")
3060
3061DEFUN (set_ipv6_nexthop_local,
3062 set_ipv6_nexthop_local_cmd,
3063 "set ipv6 next-hop local X:X::X:X",
3064 SET_STR
3065 IPV6_STR
3066 "IPv6 next-hop address\n"
3067 "IPv6 local address\n"
3068 "IPv6 address of next hop\n")
3069{
3070 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3071}
3072
3073DEFUN (no_set_ipv6_nexthop_local,
3074 no_set_ipv6_nexthop_local_cmd,
3075 "no set ipv6 next-hop local",
3076 NO_STR
3077 SET_STR
3078 IPV6_STR
3079 "IPv6 next-hop address\n"
3080 "IPv6 local address\n")
3081{
3082 if (argc == 0)
3083 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3084
3085 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3086}
3087
3088ALIAS (no_set_ipv6_nexthop_local,
3089 no_set_ipv6_nexthop_local_val_cmd,
3090 "no set ipv6 next-hop local X:X::X:X",
3091 NO_STR
3092 SET_STR
3093 IPV6_STR
3094 "IPv6 next-hop address\n"
3095 "IPv6 local address\n"
3096 "IPv6 address of next hop\n")
3097#endif /* HAVE_IPV6 */
3098
3099DEFUN (set_vpnv4_nexthop,
3100 set_vpnv4_nexthop_cmd,
3101 "set vpnv4 next-hop A.B.C.D",
3102 SET_STR
3103 "VPNv4 information\n"
3104 "VPNv4 next-hop address\n"
3105 "IP address of next hop\n")
3106{
3107 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3108}
3109
3110DEFUN (no_set_vpnv4_nexthop,
3111 no_set_vpnv4_nexthop_cmd,
3112 "no set vpnv4 next-hop",
3113 NO_STR
3114 SET_STR
3115 "VPNv4 information\n"
3116 "VPNv4 next-hop address\n")
3117{
3118 if (argc == 0)
3119 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3120
3121 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3122}
3123
3124ALIAS (no_set_vpnv4_nexthop,
3125 no_set_vpnv4_nexthop_val_cmd,
3126 "no set vpnv4 next-hop A.B.C.D",
3127 NO_STR
3128 SET_STR
3129 "VPNv4 information\n"
3130 "VPNv4 next-hop address\n"
3131 "IP address of next hop\n")
3132
3133DEFUN (set_originator_id,
3134 set_originator_id_cmd,
3135 "set originator-id A.B.C.D",
3136 SET_STR
3137 "BGP originator ID attribute\n"
3138 "IP address of originator\n")
3139{
3140 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3141}
3142
3143DEFUN (no_set_originator_id,
3144 no_set_originator_id_cmd,
3145 "no set originator-id",
3146 NO_STR
3147 SET_STR
3148 "BGP originator ID attribute\n")
3149{
3150 if (argc == 0)
3151 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3152
3153 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3154}
3155
3156ALIAS (no_set_originator_id,
3157 no_set_originator_id_val_cmd,
3158 "no set originator-id A.B.C.D",
3159 NO_STR
3160 SET_STR
3161 "BGP originator ID attribute\n"
3162 "IP address of originator\n")
3163
3164
3165/* Initialization of route map. */
3166void
3167bgp_route_map_init ()
3168{
3169 route_map_init ();
3170 route_map_init_vty ();
3171 route_map_add_hook (bgp_route_map_update);
3172 route_map_delete_hook (bgp_route_map_update);
3173
3174 route_map_install_match (&route_match_ip_address_cmd);
3175 route_map_install_match (&route_match_ip_next_hop_cmd);
3176 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3177 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
3178 route_map_install_match (&route_match_aspath_cmd);
3179 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003180 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003181 route_map_install_match (&route_match_metric_cmd);
3182 route_map_install_match (&route_match_origin_cmd);
3183
3184 route_map_install_set (&route_set_ip_nexthop_cmd);
3185 route_map_install_set (&route_set_local_pref_cmd);
3186 route_map_install_set (&route_set_weight_cmd);
3187 route_map_install_set (&route_set_metric_cmd);
3188 route_map_install_set (&route_set_aspath_prepend_cmd);
3189 route_map_install_set (&route_set_origin_cmd);
3190 route_map_install_set (&route_set_atomic_aggregate_cmd);
3191 route_map_install_set (&route_set_aggregator_as_cmd);
3192 route_map_install_set (&route_set_community_cmd);
3193 route_map_install_set (&route_set_community_delete_cmd);
3194 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3195 route_map_install_set (&route_set_originator_id_cmd);
3196 route_map_install_set (&route_set_ecommunity_rt_cmd);
3197 route_map_install_set (&route_set_ecommunity_soo_cmd);
3198
3199 install_element (RMAP_NODE, &match_ip_address_cmd);
3200 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3201 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3202 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3203 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3204 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
3205
3206 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3207 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3208 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3209 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3210 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3211 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
3212
3213 install_element (RMAP_NODE, &match_aspath_cmd);
3214 install_element (RMAP_NODE, &no_match_aspath_cmd);
3215 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3216 install_element (RMAP_NODE, &match_metric_cmd);
3217 install_element (RMAP_NODE, &no_match_metric_cmd);
3218 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3219 install_element (RMAP_NODE, &match_community_cmd);
3220 install_element (RMAP_NODE, &match_community_exact_cmd);
3221 install_element (RMAP_NODE, &no_match_community_cmd);
3222 install_element (RMAP_NODE, &no_match_community_val_cmd);
3223 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003224 install_element (RMAP_NODE, &match_ecommunity_cmd);
3225 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3226 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003227 install_element (RMAP_NODE, &match_origin_cmd);
3228 install_element (RMAP_NODE, &no_match_origin_cmd);
3229 install_element (RMAP_NODE, &no_match_origin_val_cmd);
3230
3231 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
3232 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3233 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3234 install_element (RMAP_NODE, &set_local_pref_cmd);
3235 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3236 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3237 install_element (RMAP_NODE, &set_weight_cmd);
3238 install_element (RMAP_NODE, &no_set_weight_cmd);
3239 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3240 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003241 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003242 install_element (RMAP_NODE, &no_set_metric_cmd);
3243 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3244 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
3245 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3246 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
3247 install_element (RMAP_NODE, &set_origin_cmd);
3248 install_element (RMAP_NODE, &no_set_origin_cmd);
3249 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3250 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3251 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3252 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3253 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3254 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3255 install_element (RMAP_NODE, &set_community_cmd);
3256 install_element (RMAP_NODE, &set_community_none_cmd);
3257 install_element (RMAP_NODE, &no_set_community_cmd);
3258 install_element (RMAP_NODE, &no_set_community_val_cmd);
3259 install_element (RMAP_NODE, &no_set_community_none_cmd);
3260 install_element (RMAP_NODE, &set_community_delete_cmd);
3261 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3262 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3263 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3264 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3265 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3266 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3267 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3268 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3269 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3270 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3271 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3272 install_element (RMAP_NODE, &set_originator_id_cmd);
3273 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3274 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3275
3276#ifdef HAVE_IPV6
3277 route_map_install_match (&route_match_ipv6_address_cmd);
3278 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3279 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3280 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3281 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
3282
3283 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3284 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3285 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3286 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3287 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3288 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3289 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3290 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3291 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3292 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3293 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3294 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3295#endif /* HAVE_IPV6 */
3296}