blob: e2ad5e0fc8a2c87411c02e47d8649f7b32ea2493 [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
paulfee0f4c2004-09-13 05:12:46 +000098 /* 'match peer (A.B.C.D|X:X::X:X)' */
99
100/* Compares the peer specified in the 'match peer' clause with the peer
101 received in bgp_info->peer. If it is the same, or if the peer structure
102 received is a peer_group containing it, returns RMAP_MATCH. */
103route_map_result_t
104route_match_peer (void *rule, struct prefix *prefix, route_map_object_t type,
105 void *object)
106{
107 union sockunion *su;
108 union sockunion *su2;
109 struct peer_group *group;
110 struct peer *peer;
111 struct listnode *nn;
112
113 if (type == RMAP_BGP)
114 {
115 su = rule;
116 peer = ((struct bgp_info *) object)->peer;
117
118 if ( ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT) &&
119 ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_EXPORT) )
120 return RMAP_NOMATCH;
121
122 /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
123 REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
124 su2 = sockunion_str2su ("0.0.0.0");
125 if ( sockunion_same (su, su2) )
126 {
127 if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
128 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE) ||
129 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
130 {
131 XFREE (MTYPE_SOCKUNION, su2);
132
133 return RMAP_MATCH;
134 }
135 else
136 return RMAP_NOMATCH;
137 }
138 XFREE (MTYPE_SOCKUNION, su2);
139
140 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
141 {
142 if (sockunion_same (su, &peer->su))
143 return RMAP_MATCH;
144
145 return RMAP_NOMATCH;
146 }
147 else
148 {
149 group = peer->group;
150 LIST_LOOP (group->peer, peer, nn)
151 {
152 if (sockunion_same (su, &peer->su))
153 return RMAP_MATCH;
154
155 return RMAP_NOMATCH;
156 }
157 }
158 }
159 return RMAP_NOMATCH;
160}
161
162void *
paulfd79ac92004-10-13 05:06:08 +0000163route_match_peer_compile (const char *arg)
paulfee0f4c2004-09-13 05:12:46 +0000164{
165 union sockunion *su;
166 int ret;
167
168 su = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union sockunion));
169
170 ret = str2sockunion ( (arg)? arg : "0.0.0.0", su);
171 if (ret < 0) {
172 XFREE (MTYPE_ROUTE_MAP_COMPILED, su);
173 return NULL;
174 }
175
176 return su;
177}
178
179/* Free route map's compiled `ip address' value. */
180void
181route_match_peer_free (void *rule)
182{
183 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
184}
185
186/* Route map commands for ip address matching. */
187struct route_map_rule_cmd route_match_peer_cmd =
188{
189 "peer",
190 route_match_peer,
191 route_match_peer_compile,
192 route_match_peer_free
193};
194
paul718e3742002-12-13 20:15:29 +0000195/* `match ip address IP_ACCESS_LIST' */
196
197/* Match function should return 1 if match is success else return
198 zero. */
199route_map_result_t
200route_match_ip_address (void *rule, struct prefix *prefix,
201 route_map_object_t type, void *object)
202{
203 struct access_list *alist;
204 /* struct prefix_ipv4 match; */
205
206 if (type == RMAP_BGP)
207 {
208 alist = access_list_lookup (AFI_IP, (char *) rule);
209 if (alist == NULL)
210 return RMAP_NOMATCH;
211
212 return (access_list_apply (alist, prefix) == FILTER_DENY ?
213 RMAP_NOMATCH : RMAP_MATCH);
214 }
215 return RMAP_NOMATCH;
216}
217
218/* Route map `ip address' match statement. `arg' should be
219 access-list name. */
220void *
paulfd79ac92004-10-13 05:06:08 +0000221route_match_ip_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000222{
223 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
224}
225
226/* Free route map's compiled `ip address' value. */
227void
228route_match_ip_address_free (void *rule)
229{
230 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
231}
232
233/* Route map commands for ip address matching. */
234struct route_map_rule_cmd route_match_ip_address_cmd =
235{
236 "ip address",
237 route_match_ip_address,
238 route_match_ip_address_compile,
239 route_match_ip_address_free
240};
241
242/* `match ip next-hop IP_ADDRESS' */
243
244/* Match function return 1 if match is success else return zero. */
245route_map_result_t
246route_match_ip_next_hop (void *rule, struct prefix *prefix,
247 route_map_object_t type, void *object)
248{
249 struct access_list *alist;
250 struct bgp_info *bgp_info;
251 struct prefix_ipv4 p;
252
253 if (type == RMAP_BGP)
254 {
255 bgp_info = object;
256 p.family = AF_INET;
257 p.prefix = bgp_info->attr->nexthop;
258 p.prefixlen = IPV4_MAX_BITLEN;
259
260 alist = access_list_lookup (AFI_IP, (char *) rule);
261 if (alist == NULL)
262 return RMAP_NOMATCH;
263
264 return (access_list_apply (alist, &p) == FILTER_DENY ?
265 RMAP_NOMATCH : RMAP_MATCH);
266 }
267 return RMAP_NOMATCH;
268}
269
270/* Route map `ip next-hop' match statement. `arg' is
271 access-list name. */
272void *
paulfd79ac92004-10-13 05:06:08 +0000273route_match_ip_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000274{
275 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
276}
277
278/* Free route map's compiled `ip address' value. */
279void
280route_match_ip_next_hop_free (void *rule)
281{
282 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
283}
284
285/* Route map commands for ip next-hop matching. */
286struct route_map_rule_cmd route_match_ip_next_hop_cmd =
287{
288 "ip next-hop",
289 route_match_ip_next_hop,
290 route_match_ip_next_hop_compile,
291 route_match_ip_next_hop_free
292};
293
294/* `match ip address prefix-list PREFIX_LIST' */
295
296route_map_result_t
297route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
298 route_map_object_t type, void *object)
299{
300 struct prefix_list *plist;
301
302 if (type == RMAP_BGP)
303 {
304 plist = prefix_list_lookup (AFI_IP, (char *) rule);
305 if (plist == NULL)
306 return RMAP_NOMATCH;
307
308 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
309 RMAP_NOMATCH : RMAP_MATCH);
310 }
311 return RMAP_NOMATCH;
312}
313
314void *
paulfd79ac92004-10-13 05:06:08 +0000315route_match_ip_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000316{
317 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
318}
319
320void
321route_match_ip_address_prefix_list_free (void *rule)
322{
323 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
324}
325
326struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
327{
328 "ip address prefix-list",
329 route_match_ip_address_prefix_list,
330 route_match_ip_address_prefix_list_compile,
331 route_match_ip_address_prefix_list_free
332};
333
334/* `match ip next-hop prefix-list PREFIX_LIST' */
335
336route_map_result_t
337route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
338 route_map_object_t type, void *object)
339{
340 struct prefix_list *plist;
341 struct bgp_info *bgp_info;
342 struct prefix_ipv4 p;
343
344 if (type == RMAP_BGP)
345 {
346 bgp_info = object;
347 p.family = AF_INET;
348 p.prefix = bgp_info->attr->nexthop;
349 p.prefixlen = IPV4_MAX_BITLEN;
350
351 plist = prefix_list_lookup (AFI_IP, (char *) rule);
352 if (plist == NULL)
353 return RMAP_NOMATCH;
354
355 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
356 RMAP_NOMATCH : RMAP_MATCH);
357 }
358 return RMAP_NOMATCH;
359}
360
361void *
paulfd79ac92004-10-13 05:06:08 +0000362route_match_ip_next_hop_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000363{
364 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
365}
366
367void
368route_match_ip_next_hop_prefix_list_free (void *rule)
369{
370 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
371}
372
373struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
374{
375 "ip next-hop prefix-list",
376 route_match_ip_next_hop_prefix_list,
377 route_match_ip_next_hop_prefix_list_compile,
378 route_match_ip_next_hop_prefix_list_free
379};
380
381/* `match metric METRIC' */
382
383/* Match function return 1 if match is success else return zero. */
384route_map_result_t
385route_match_metric (void *rule, struct prefix *prefix,
386 route_map_object_t type, void *object)
387{
388 u_int32_t *med;
389 struct bgp_info *bgp_info;
390
391 if (type == RMAP_BGP)
392 {
393 med = rule;
394 bgp_info = object;
395
396 if (bgp_info->attr->med == *med)
397 return RMAP_MATCH;
398 else
399 return RMAP_NOMATCH;
400 }
401 return RMAP_NOMATCH;
402}
403
404/* Route map `match metric' match statement. `arg' is MED value */
405void *
paulfd79ac92004-10-13 05:06:08 +0000406route_match_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000407{
408 u_int32_t *med;
409 char *endptr = NULL;
paul3b424972003-10-13 09:47:32 +0000410 unsigned long tmpval;
paul718e3742002-12-13 20:15:29 +0000411
paul3b424972003-10-13 09:47:32 +0000412 tmpval = strtoul (arg, &endptr, 10);
paulfd79ac92004-10-13 05:06:08 +0000413 if (*endptr != '\0' || tmpval == ULONG_MAX || tmpval > UINT32_MAX)
paul3b424972003-10-13 09:47:32 +0000414 return NULL;
paulfd79ac92004-10-13 05:06:08 +0000415
paul718e3742002-12-13 20:15:29 +0000416 med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +0000417
418 if (!med)
419 return med;
420
paul3b424972003-10-13 09:47:32 +0000421 *med = tmpval;
paul718e3742002-12-13 20:15:29 +0000422 return med;
423}
424
425/* Free route map's compiled `match metric' value. */
426void
427route_match_metric_free (void *rule)
428{
429 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
430}
431
432/* Route map commands for metric matching. */
433struct route_map_rule_cmd route_match_metric_cmd =
434{
435 "metric",
436 route_match_metric,
437 route_match_metric_compile,
438 route_match_metric_free
439};
440
441/* `match as-path ASPATH' */
442
443/* Match function for as-path match. I assume given object is */
444route_map_result_t
445route_match_aspath (void *rule, struct prefix *prefix,
446 route_map_object_t type, void *object)
447{
448
449 struct as_list *as_list;
450 struct bgp_info *bgp_info;
451
452 if (type == RMAP_BGP)
453 {
454 as_list = as_list_lookup ((char *) rule);
455 if (as_list == NULL)
456 return RMAP_NOMATCH;
457
458 bgp_info = object;
459
460 /* Perform match. */
461 return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
462 }
463 return RMAP_NOMATCH;
464}
465
466/* Compile function for as-path match. */
467void *
paulfd79ac92004-10-13 05:06:08 +0000468route_match_aspath_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000469{
470 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
471}
472
473/* Compile function for as-path match. */
474void
475route_match_aspath_free (void *rule)
476{
477 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
478}
479
480/* Route map commands for aspath matching. */
481struct route_map_rule_cmd route_match_aspath_cmd =
482{
483 "as-path",
484 route_match_aspath,
485 route_match_aspath_compile,
486 route_match_aspath_free
487};
488
489#if ROUTE_MATCH_ASPATH_OLD
490/* `match as-path ASPATH' */
491
492/* Match function for as-path match. I assume given object is */
493int
494route_match_aspath (void *rule, struct prefix *prefix, void *object)
495{
496 regex_t *regex;
497 struct bgp_info *bgp_info;
498
499 regex = rule;
500 bgp_info = object;
501
502 /* Perform match. */
503 return bgp_regexec (regex, bgp_info->attr->aspath);
504}
505
506/* Compile function for as-path match. */
507void *
paulfd79ac92004-10-13 05:06:08 +0000508route_match_aspath_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000509{
510 regex_t *regex;
511
512 regex = bgp_regcomp (arg);
513 if (! regex)
514 return NULL;
515
516 return regex;
517}
518
519/* Compile function for as-path match. */
520void
521route_match_aspath_free (void *rule)
522{
523 regex_t *regex = rule;
524
525 bgp_regex_free (regex);
526}
527
528/* Route map commands for aspath matching. */
529struct route_map_rule_cmd route_match_aspath_cmd =
530{
531 "as-path",
532 route_match_aspath,
533 route_match_aspath_compile,
534 route_match_aspath_free
535};
536#endif /* ROUTE_MATCH_ASPATH_OLD */
537
538/* `match community COMMUNIY' */
539struct rmap_community
540{
541 char *name;
542 int exact;
543};
544
545/* Match function for community match. */
546route_map_result_t
547route_match_community (void *rule, struct prefix *prefix,
548 route_map_object_t type, void *object)
549{
550 struct community_list *list;
551 struct bgp_info *bgp_info;
552 struct rmap_community *rcom;
553
554 if (type == RMAP_BGP)
555 {
556 bgp_info = object;
557 rcom = rule;
558
559 list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_AUTO);
560 if (! list)
561 return RMAP_NOMATCH;
562
563 if (rcom->exact)
564 {
565 if (community_list_exact_match (bgp_info->attr->community, list))
566 return RMAP_MATCH;
567 }
568 else
569 {
570 if (community_list_match (bgp_info->attr->community, list))
571 return RMAP_MATCH;
572 }
573 }
574 return RMAP_NOMATCH;
575}
576
577/* Compile function for community match. */
578void *
paulfd79ac92004-10-13 05:06:08 +0000579route_match_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000580{
581 struct rmap_community *rcom;
582 int len;
583 char *p;
584
585 rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
586
587 p = strchr (arg, ' ');
588 if (p)
589 {
590 len = p - arg;
591 rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
592 memcpy (rcom->name, arg, len);
593 rcom->exact = 1;
594 }
595 else
596 {
597 rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
598 rcom->exact = 0;
599 }
600 return rcom;
601}
602
603/* Compile function for community match. */
604void
605route_match_community_free (void *rule)
606{
607 struct rmap_community *rcom = rule;
608
609 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
610 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
611}
612
613/* Route map commands for community matching. */
614struct route_map_rule_cmd route_match_community_cmd =
615{
616 "community",
617 route_match_community,
618 route_match_community_compile,
619 route_match_community_free
620};
621
paul73ffb252003-04-19 15:49:49 +0000622/* Match function for extcommunity match. */
623route_map_result_t
624route_match_ecommunity (void *rule, struct prefix *prefix,
625 route_map_object_t type, void *object)
626{
627 struct community_list *list;
628 struct bgp_info *bgp_info;
629
630 if (type == RMAP_BGP)
631 {
632 bgp_info = object;
633
634 list = community_list_lookup (bgp_clist, (char *) rule,
635 EXTCOMMUNITY_LIST_AUTO);
636 if (! list)
637 return RMAP_NOMATCH;
638
639 if (ecommunity_list_match (bgp_info->attr->ecommunity, list))
640 return RMAP_MATCH;
641 }
642 return RMAP_NOMATCH;
643}
644
645/* Compile function for extcommunity match. */
646void *
paulfd79ac92004-10-13 05:06:08 +0000647route_match_ecommunity_compile (const char *arg)
paul73ffb252003-04-19 15:49:49 +0000648{
649 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
650}
651
652/* Compile function for extcommunity match. */
653void
654route_match_ecommunity_free (void *rule)
655{
656 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
657}
658
659/* Route map commands for community matching. */
660struct route_map_rule_cmd route_match_ecommunity_cmd =
661{
662 "extcommunity",
663 route_match_ecommunity,
664 route_match_ecommunity_compile,
665 route_match_ecommunity_free
666};
667
paul718e3742002-12-13 20:15:29 +0000668/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
669 and `address-family vpnv4'. */
670
671/* `match origin' */
672route_map_result_t
673route_match_origin (void *rule, struct prefix *prefix,
674 route_map_object_t type, void *object)
675{
676 u_char *origin;
677 struct bgp_info *bgp_info;
678
679 if (type == RMAP_BGP)
680 {
681 origin = rule;
682 bgp_info = object;
683
684 if (bgp_info->attr->origin == *origin)
685 return RMAP_MATCH;
686 }
687
688 return RMAP_NOMATCH;
689}
690
691void *
paulfd79ac92004-10-13 05:06:08 +0000692route_match_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000693{
694 u_char *origin;
695
696 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
697
698 if (strcmp (arg, "igp") == 0)
699 *origin = 0;
700 else if (strcmp (arg, "egp") == 0)
701 *origin = 1;
702 else
703 *origin = 2;
704
705 return origin;
706}
707
708/* Free route map's compiled `ip address' value. */
709void
710route_match_origin_free (void *rule)
711{
712 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
713}
714
715/* Route map commands for origin matching. */
716struct route_map_rule_cmd route_match_origin_cmd =
717{
718 "origin",
719 route_match_origin,
720 route_match_origin_compile,
721 route_match_origin_free
722};
723/* `set ip next-hop IP_ADDRESS' */
724
725/* Set nexthop to object. ojbect must be pointer to struct attr. */
paulac41b2a2003-08-12 05:32:27 +0000726struct rmap_ip_nexthop_set
727{
728 struct in_addr *address;
729 int peer_address;
730};
731
paul718e3742002-12-13 20:15:29 +0000732route_map_result_t
733route_set_ip_nexthop (void *rule, struct prefix *prefix,
734 route_map_object_t type, void *object)
735{
paulac41b2a2003-08-12 05:32:27 +0000736 struct rmap_ip_nexthop_set *rins = rule;
737 struct in_addr peer_address;
paul718e3742002-12-13 20:15:29 +0000738 struct bgp_info *bgp_info;
paulac41b2a2003-08-12 05:32:27 +0000739 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000740
741 if (type == RMAP_BGP)
742 {
paul718e3742002-12-13 20:15:29 +0000743 bgp_info = object;
paulac41b2a2003-08-12 05:32:27 +0000744 peer = bgp_info->peer;
745
746 if (rins->peer_address)
747 {
paulfee0f4c2004-09-13 05:12:46 +0000748 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
749 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
paulac41b2a2003-08-12 05:32:27 +0000750 && peer->su_remote
751 && sockunion_family (peer->su_remote) == AF_INET)
752 {
753 inet_aton (sockunion_su2str (peer->su_remote), &peer_address);
754 bgp_info->attr->nexthop = peer_address;
755 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
756 }
757 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
758 && peer->su_local
759 && sockunion_family (peer->su_local) == AF_INET)
760 {
761 inet_aton (sockunion_su2str (peer->su_local), &peer_address);
762 bgp_info->attr->nexthop = peer_address;
763 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
764 }
765 }
766 else
767 {
768 /* Set next hop value. */
769 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
770 bgp_info->attr->nexthop = *rins->address;
771 }
paul718e3742002-12-13 20:15:29 +0000772 }
773
774 return RMAP_OKAY;
775}
776
777/* Route map `ip nexthop' compile function. Given string is converted
778 to struct in_addr structure. */
779void *
paulfd79ac92004-10-13 05:06:08 +0000780route_set_ip_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000781{
paulac41b2a2003-08-12 05:32:27 +0000782 struct rmap_ip_nexthop_set *rins;
783 struct in_addr *address = NULL;
784 int peer_address = 0;
paul718e3742002-12-13 20:15:29 +0000785 int ret;
paul718e3742002-12-13 20:15:29 +0000786
paulac41b2a2003-08-12 05:32:27 +0000787 if (strcmp (arg, "peer-address") == 0)
788 peer_address = 1;
789 else
paul718e3742002-12-13 20:15:29 +0000790 {
paulac41b2a2003-08-12 05:32:27 +0000791 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
792 ret = inet_aton (arg, address);
793
794 if (ret == 0)
795 {
796 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
797 return NULL;
798 }
paul718e3742002-12-13 20:15:29 +0000799 }
800
paulac41b2a2003-08-12 05:32:27 +0000801 rins = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
802 memset (rins, 0, sizeof (struct rmap_ip_nexthop_set));
803
804 rins->address = address;
805 rins->peer_address = peer_address;
806
807 return rins;
paul718e3742002-12-13 20:15:29 +0000808}
809
810/* Free route map's compiled `ip nexthop' value. */
811void
812route_set_ip_nexthop_free (void *rule)
813{
paulac41b2a2003-08-12 05:32:27 +0000814 struct rmap_ip_nexthop_set *rins = rule;
815
816 if (rins->address)
817 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
818
819 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +0000820}
821
822/* Route map commands for ip nexthop set. */
823struct route_map_rule_cmd route_set_ip_nexthop_cmd =
824{
825 "ip next-hop",
826 route_set_ip_nexthop,
827 route_set_ip_nexthop_compile,
828 route_set_ip_nexthop_free
829};
830
831/* `set local-preference LOCAL_PREF' */
832
833/* Set local preference. */
834route_map_result_t
835route_set_local_pref (void *rule, struct prefix *prefix,
836 route_map_object_t type, void *object)
837{
838 u_int32_t *local_pref;
839 struct bgp_info *bgp_info;
840
841 if (type == RMAP_BGP)
842 {
843 /* Fetch routemap's rule information. */
844 local_pref = rule;
845 bgp_info = object;
846
847 /* Set local preference value. */
848 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
849 bgp_info->attr->local_pref = *local_pref;
850 }
851
852 return RMAP_OKAY;
853}
854
855/* set local preference compilation. */
856void *
paulfd79ac92004-10-13 05:06:08 +0000857route_set_local_pref_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000858{
paulfd79ac92004-10-13 05:06:08 +0000859 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +0000860 u_int32_t *local_pref;
861 char *endptr = NULL;
862
863 /* Local preference value shoud be integer. */
864 if (! all_digit (arg))
865 return NULL;
paulfd79ac92004-10-13 05:06:08 +0000866
867 tmp = strtoul (arg, &endptr, 10);
868 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
869 return NULL;
870
871 local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
872
873 if (!local_pref)
874 return local_pref;
875
876 *local_pref = tmp;
877
paul718e3742002-12-13 20:15:29 +0000878 return local_pref;
879}
880
881/* Free route map's local preference value. */
882void
883route_set_local_pref_free (void *rule)
884{
885 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
886}
887
888/* Set local preference rule structure. */
889struct route_map_rule_cmd route_set_local_pref_cmd =
890{
891 "local-preference",
892 route_set_local_pref,
893 route_set_local_pref_compile,
894 route_set_local_pref_free,
895};
896
897/* `set weight WEIGHT' */
898
899/* Set weight. */
900route_map_result_t
901route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
902 void *object)
903{
904 u_int32_t *weight;
905 struct bgp_info *bgp_info;
906
907 if (type == RMAP_BGP)
908 {
909 /* Fetch routemap's rule information. */
910 weight = rule;
911 bgp_info = object;
912
913 /* Set weight value. */
914 bgp_info->attr->weight = *weight;
915 }
916
917 return RMAP_OKAY;
918}
919
920/* set local preference compilation. */
921void *
paulfd79ac92004-10-13 05:06:08 +0000922route_set_weight_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000923{
paulfd79ac92004-10-13 05:06:08 +0000924 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +0000925 u_int32_t *weight;
926 char *endptr = NULL;
927
928 /* Local preference value shoud be integer. */
929 if (! all_digit (arg))
930 return NULL;
931
paulfd79ac92004-10-13 05:06:08 +0000932
933 tmp = strtoul (arg, &endptr, 10);
934 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
935 return NULL;
936
paul718e3742002-12-13 20:15:29 +0000937 weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +0000938
939 if (weight == NULL)
940 return weight;
941
942 *weight = tmp;
943
paul718e3742002-12-13 20:15:29 +0000944 return weight;
945}
946
947/* Free route map's local preference value. */
948void
949route_set_weight_free (void *rule)
950{
951 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
952}
953
954/* Set local preference rule structure. */
955struct route_map_rule_cmd route_set_weight_cmd =
956{
957 "weight",
958 route_set_weight,
959 route_set_weight_compile,
960 route_set_weight_free,
961};
962
963/* `set metric METRIC' */
964
965/* Set metric to attribute. */
966route_map_result_t
967route_set_metric (void *rule, struct prefix *prefix,
968 route_map_object_t type, void *object)
969{
970 char *metric;
971 u_int32_t metric_val;
972 struct bgp_info *bgp_info;
973
974 if (type == RMAP_BGP)
975 {
976 /* Fetch routemap's rule information. */
977 metric = rule;
978 bgp_info = object;
979
980 if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
981 bgp_info->attr->med = 0;
982 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
983
984 if (all_digit (metric))
985 {
986 metric_val = strtoul (metric, (char **)NULL, 10);
987 bgp_info->attr->med = metric_val;
988 }
989 else
990 {
991 metric_val = strtoul (metric+1, (char **)NULL, 10);
992
993 if (strncmp (metric, "+", 1) == 0)
994 {
paul3b424972003-10-13 09:47:32 +0000995 if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2)
996 bgp_info->attr->med = BGP_MED_MAX - 1;
paul718e3742002-12-13 20:15:29 +0000997 else
paul537d8ea2003-08-27 06:45:32 +0000998 bgp_info->attr->med += metric_val;
paul718e3742002-12-13 20:15:29 +0000999 }
1000 else if (strncmp (metric, "-", 1) == 0)
1001 {
paul537d8ea2003-08-27 06:45:32 +00001002 if (bgp_info->attr->med <= metric_val)
1003 bgp_info->attr->med = 0;
paul718e3742002-12-13 20:15:29 +00001004 else
paul537d8ea2003-08-27 06:45:32 +00001005 bgp_info->attr->med -= metric_val;
paul718e3742002-12-13 20:15:29 +00001006 }
1007 }
1008 }
1009 return RMAP_OKAY;
1010}
1011
1012/* set metric compilation. */
1013void *
paulfd79ac92004-10-13 05:06:08 +00001014route_set_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001015{
1016 u_int32_t metric;
1017 char *endptr = NULL;
1018
1019 if (all_digit (arg))
1020 {
1021 /* set metric value check*/
1022 metric = strtoul (arg, &endptr, 10);
1023 if (*endptr != '\0' || metric == ULONG_MAX)
1024 return NULL;
1025 }
1026 else
1027 {
1028 /* set metric +/-value check */
1029 if ((strncmp (arg, "+", 1) != 0
1030 && strncmp (arg, "-", 1) != 0)
1031 || (! all_digit (arg+1)))
1032 return NULL;
1033
1034 metric = strtoul (arg+1, &endptr, 10);
1035 if (*endptr != '\0' || metric == ULONG_MAX)
1036 return NULL;
1037 }
1038
1039 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1040}
1041
1042/* Free route map's compiled `set metric' value. */
1043void
1044route_set_metric_free (void *rule)
1045{
1046 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1047}
1048
1049/* Set metric rule structure. */
1050struct route_map_rule_cmd route_set_metric_cmd =
1051{
1052 "metric",
1053 route_set_metric,
1054 route_set_metric_compile,
1055 route_set_metric_free,
1056};
1057
1058/* `set as-path prepend ASPATH' */
1059
1060/* For AS path prepend mechanism. */
1061route_map_result_t
1062route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1063{
1064 struct aspath *aspath;
1065 struct aspath *new;
1066 struct bgp_info *binfo;
1067
1068 if (type == RMAP_BGP)
1069 {
1070 aspath = rule;
1071 binfo = object;
1072
1073 if (binfo->attr->aspath->refcnt)
1074 new = aspath_dup (binfo->attr->aspath);
1075 else
1076 new = binfo->attr->aspath;
1077
1078 aspath_prepend (aspath, new);
1079 binfo->attr->aspath = new;
1080 }
1081
1082 return RMAP_OKAY;
1083}
1084
1085/* Compile function for as-path prepend. */
1086void *
paulfd79ac92004-10-13 05:06:08 +00001087route_set_aspath_prepend_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001088{
1089 struct aspath *aspath;
1090
1091 aspath = aspath_str2aspath (arg);
1092 if (! aspath)
1093 return NULL;
1094 return aspath;
1095}
1096
1097/* Compile function for as-path prepend. */
1098void
1099route_set_aspath_prepend_free (void *rule)
1100{
1101 struct aspath *aspath = rule;
1102 aspath_free (aspath);
1103}
1104
1105/* Set metric rule structure. */
1106struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1107{
1108 "as-path prepend",
1109 route_set_aspath_prepend,
1110 route_set_aspath_prepend_compile,
1111 route_set_aspath_prepend_free,
1112};
1113
1114/* `set community COMMUNITY' */
1115struct rmap_com_set
1116{
1117 struct community *com;
1118 int additive;
1119 int none;
1120};
1121
1122/* For community set mechanism. */
1123route_map_result_t
1124route_set_community (void *rule, struct prefix *prefix,
1125 route_map_object_t type, void *object)
1126{
1127 struct rmap_com_set *rcs;
1128 struct bgp_info *binfo;
1129 struct attr *attr;
1130 struct community *new = NULL;
1131 struct community *old;
1132 struct community *merge;
1133
1134 if (type == RMAP_BGP)
1135 {
1136 rcs = rule;
1137 binfo = object;
1138 attr = binfo->attr;
1139 old = attr->community;
1140
1141 /* "none" case. */
1142 if (rcs->none)
1143 {
1144 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1145 attr->community = NULL;
1146 return RMAP_OKAY;
1147 }
1148
1149 /* "additive" case. */
1150 if (rcs->additive && old)
1151 {
1152 merge = community_merge (community_dup (old), rcs->com);
1153 new = community_uniq_sort (merge);
1154 community_free (merge);
1155 }
1156 else
1157 new = community_dup (rcs->com);
1158
1159 attr->community = new;
1160 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1161 }
1162
1163 return RMAP_OKAY;
1164}
1165
1166/* Compile function for set community. */
1167void *
paulfd79ac92004-10-13 05:06:08 +00001168route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001169{
1170 struct rmap_com_set *rcs;
1171 struct community *com = NULL;
1172 char *sp;
1173 int additive = 0;
1174 int none = 0;
1175
1176 if (strcmp (arg, "none") == 0)
1177 none = 1;
1178 else
1179 {
1180 sp = strstr (arg, "additive");
1181
1182 if (sp && sp > arg)
1183 {
1184 /* "additive" keyworkd is included. */
1185 additive = 1;
1186 *(sp - 1) = '\0';
1187 }
1188
1189 com = community_str2com (arg);
1190
1191 if (additive)
1192 *(sp - 1) = ' ';
1193
1194 if (! com)
1195 return NULL;
1196 }
1197
1198 rcs = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
1199 memset (rcs, 0, sizeof (struct rmap_com_set));
1200
1201 rcs->com = com;
1202 rcs->additive = additive;
1203 rcs->none = none;
1204
1205 return rcs;
1206}
1207
1208/* Free function for set community. */
1209void
1210route_set_community_free (void *rule)
1211{
1212 struct rmap_com_set *rcs = rule;
1213
1214 if (rcs->com)
1215 community_free (rcs->com);
1216 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1217}
1218
1219/* Set community rule structure. */
1220struct route_map_rule_cmd route_set_community_cmd =
1221{
1222 "community",
1223 route_set_community,
1224 route_set_community_compile,
1225 route_set_community_free,
1226};
1227
1228/* `set comm-list (<1-99>|<100-199>|WORD) delete' */
1229
1230/* For community set mechanism. */
1231route_map_result_t
1232route_set_community_delete (void *rule, struct prefix *prefix,
1233 route_map_object_t type, void *object)
1234{
1235 struct community_list *list;
1236 struct community *merge;
1237 struct community *new;
1238 struct community *old;
1239 struct bgp_info *binfo;
1240
1241 if (type == RMAP_BGP)
1242 {
1243 if (! rule)
1244 return RMAP_OKAY;
1245
1246 binfo = object;
1247 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_AUTO);
1248 old = binfo->attr->community;
1249
1250 if (list && old)
1251 {
1252 merge = community_list_match_delete (community_dup (old), list);
1253 new = community_uniq_sort (merge);
1254 community_free (merge);
1255
1256 if (new->size == 0)
1257 {
1258 binfo->attr->community = NULL;
1259 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1260 community_free (new);
1261 }
1262 else
1263 {
1264 binfo->attr->community = new;
1265 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1266 }
1267 }
1268 }
1269
1270 return RMAP_OKAY;
1271}
1272
1273/* Compile function for set community. */
1274void *
paulfd79ac92004-10-13 05:06:08 +00001275route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001276{
1277 char *p;
1278 char *str;
1279 int len;
1280
1281 p = strchr (arg, ' ');
1282 if (p)
1283 {
1284 len = p - arg;
1285 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1286 memcpy (str, arg, len);
1287 }
1288 else
1289 str = NULL;
1290
1291 return str;
1292}
1293
1294/* Free function for set community. */
1295void
1296route_set_community_delete_free (void *rule)
1297{
1298 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1299}
1300
1301/* Set community rule structure. */
1302struct route_map_rule_cmd route_set_community_delete_cmd =
1303{
1304 "comm-list",
1305 route_set_community_delete,
1306 route_set_community_delete_compile,
1307 route_set_community_delete_free,
1308};
1309
1310/* `set extcommunity rt COMMUNITY' */
1311
1312/* For community set mechanism. */
1313route_map_result_t
1314route_set_ecommunity_rt (void *rule, struct prefix *prefix,
1315 route_map_object_t type, void *object)
1316{
1317 struct ecommunity *ecom;
1318 struct ecommunity *new_ecom;
1319 struct ecommunity *old_ecom;
1320 struct bgp_info *bgp_info;
1321
1322 if (type == RMAP_BGP)
1323 {
1324 ecom = rule;
1325 bgp_info = object;
1326
1327 if (! ecom)
1328 return RMAP_OKAY;
1329
1330 /* We assume additive for Extended Community. */
1331 old_ecom = bgp_info->attr->ecommunity;
1332
1333 if (old_ecom)
1334 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1335 else
1336 new_ecom = ecommunity_dup (ecom);
1337
1338 bgp_info->attr->ecommunity = new_ecom;
1339
1340 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1341 }
1342 return RMAP_OKAY;
1343}
1344
1345/* Compile function for set community. */
1346void *
paulfd79ac92004-10-13 05:06:08 +00001347route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001348{
1349 struct ecommunity *ecom;
1350
1351 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1352 if (! ecom)
1353 return NULL;
1354 return ecom;
1355}
1356
1357/* Free function for set community. */
1358void
1359route_set_ecommunity_rt_free (void *rule)
1360{
1361 struct ecommunity *ecom = rule;
1362 ecommunity_free (ecom);
1363}
1364
1365/* Set community rule structure. */
1366struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1367{
1368 "extcommunity rt",
1369 route_set_ecommunity_rt,
1370 route_set_ecommunity_rt_compile,
1371 route_set_ecommunity_rt_free,
1372};
1373
1374/* `set extcommunity soo COMMUNITY' */
1375
1376/* For community set mechanism. */
1377route_map_result_t
1378route_set_ecommunity_soo (void *rule, struct prefix *prefix,
1379 route_map_object_t type, void *object)
1380{
1381 struct ecommunity *ecom;
1382 struct bgp_info *bgp_info;
1383
1384 if (type == RMAP_BGP)
1385 {
1386 ecom = rule;
1387 bgp_info = object;
1388
1389 if (! ecom)
1390 return RMAP_OKAY;
1391
1392 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1393 bgp_info->attr->ecommunity = ecommunity_dup (ecom);
1394 }
1395 return RMAP_OKAY;
1396}
1397
1398/* Compile function for set community. */
1399void *
paulfd79ac92004-10-13 05:06:08 +00001400route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001401{
1402 struct ecommunity *ecom;
1403
1404 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1405 if (! ecom)
1406 return NULL;
1407
1408 return ecom;
1409}
1410
1411/* Free function for set community. */
1412void
1413route_set_ecommunity_soo_free (void *rule)
1414{
1415 struct ecommunity *ecom = rule;
1416 ecommunity_free (ecom);
1417}
1418
1419/* Set community rule structure. */
1420struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1421{
1422 "extcommunity soo",
1423 route_set_ecommunity_soo,
1424 route_set_ecommunity_soo_compile,
1425 route_set_ecommunity_soo_free,
1426};
1427
1428/* `set origin ORIGIN' */
1429
1430/* For origin set. */
1431route_map_result_t
1432route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1433{
1434 u_char *origin;
1435 struct bgp_info *bgp_info;
1436
1437 if (type == RMAP_BGP)
1438 {
1439 origin = rule;
1440 bgp_info = object;
1441
1442 bgp_info->attr->origin = *origin;
1443 }
1444
1445 return RMAP_OKAY;
1446}
1447
1448/* Compile function for origin set. */
1449void *
paulfd79ac92004-10-13 05:06:08 +00001450route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001451{
1452 u_char *origin;
1453
1454 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1455
1456 if (strcmp (arg, "igp") == 0)
1457 *origin = 0;
1458 else if (strcmp (arg, "egp") == 0)
1459 *origin = 1;
1460 else
1461 *origin = 2;
1462
1463 return origin;
1464}
1465
1466/* Compile function for origin set. */
1467void
1468route_set_origin_free (void *rule)
1469{
1470 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1471}
1472
1473/* Set metric rule structure. */
1474struct route_map_rule_cmd route_set_origin_cmd =
1475{
1476 "origin",
1477 route_set_origin,
1478 route_set_origin_compile,
1479 route_set_origin_free,
1480};
1481
1482/* `set atomic-aggregate' */
1483
1484/* For atomic aggregate set. */
1485route_map_result_t
1486route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1487 route_map_object_t type, void *object)
1488{
1489 struct bgp_info *bgp_info;
1490
1491 if (type == RMAP_BGP)
1492 {
1493 bgp_info = object;
1494 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1495 }
1496
1497 return RMAP_OKAY;
1498}
1499
1500/* Compile function for atomic aggregate. */
1501void *
paulfd79ac92004-10-13 05:06:08 +00001502route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001503{
1504 return (void *)1;
1505}
1506
1507/* Compile function for atomic aggregate. */
1508void
1509route_set_atomic_aggregate_free (void *rule)
1510{
1511 return;
1512}
1513
1514/* Set atomic aggregate rule structure. */
1515struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1516{
1517 "atomic-aggregate",
1518 route_set_atomic_aggregate,
1519 route_set_atomic_aggregate_compile,
1520 route_set_atomic_aggregate_free,
1521};
1522
1523/* `set aggregator as AS A.B.C.D' */
1524struct aggregator
1525{
1526 as_t as;
1527 struct in_addr address;
1528};
1529
1530route_map_result_t
1531route_set_aggregator_as (void *rule, struct prefix *prefix,
1532 route_map_object_t type, void *object)
1533{
1534 struct bgp_info *bgp_info;
1535 struct aggregator *aggregator;
1536
1537 if (type == RMAP_BGP)
1538 {
1539 bgp_info = object;
1540 aggregator = rule;
1541
1542 bgp_info->attr->aggregator_as = aggregator->as;
1543 bgp_info->attr->aggregator_addr = aggregator->address;
1544 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1545 }
1546
1547 return RMAP_OKAY;
1548}
1549
1550void *
paulfd79ac92004-10-13 05:06:08 +00001551route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001552{
1553 struct aggregator *aggregator;
1554 char as[10];
1555 char address[20];
1556
1557 aggregator = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
1558 memset (aggregator, 0, sizeof (struct aggregator));
1559
1560 sscanf (arg, "%s %s", as, address);
1561
1562 aggregator->as = strtoul (as, NULL, 10);
1563 inet_aton (address, &aggregator->address);
1564
1565 return aggregator;
1566}
1567
1568void
1569route_set_aggregator_as_free (void *rule)
1570{
1571 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1572}
1573
1574struct route_map_rule_cmd route_set_aggregator_as_cmd =
1575{
1576 "aggregator as",
1577 route_set_aggregator_as,
1578 route_set_aggregator_as_compile,
1579 route_set_aggregator_as_free,
1580};
1581
1582#ifdef HAVE_IPV6
1583/* `match ipv6 address IP_ACCESS_LIST' */
1584
1585route_map_result_t
1586route_match_ipv6_address (void *rule, struct prefix *prefix,
1587 route_map_object_t type, void *object)
1588{
1589 struct access_list *alist;
1590
1591 if (type == RMAP_BGP)
1592 {
1593 alist = access_list_lookup (AFI_IP6, (char *) rule);
1594 if (alist == NULL)
1595 return RMAP_NOMATCH;
1596
1597 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1598 RMAP_NOMATCH : RMAP_MATCH);
1599 }
1600 return RMAP_NOMATCH;
1601}
1602
1603void *
paulfd79ac92004-10-13 05:06:08 +00001604route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001605{
1606 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1607}
1608
1609void
1610route_match_ipv6_address_free (void *rule)
1611{
1612 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1613}
1614
1615/* Route map commands for ip address matching. */
1616struct route_map_rule_cmd route_match_ipv6_address_cmd =
1617{
1618 "ipv6 address",
1619 route_match_ipv6_address,
1620 route_match_ipv6_address_compile,
1621 route_match_ipv6_address_free
1622};
1623
1624/* `match ipv6 next-hop IP_ADDRESS' */
1625
1626route_map_result_t
1627route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1628 route_map_object_t type, void *object)
1629{
1630 struct in6_addr *addr;
1631 struct bgp_info *bgp_info;
1632
1633 if (type == RMAP_BGP)
1634 {
1635 addr = rule;
1636 bgp_info = object;
1637
1638 if (IPV6_ADDR_SAME (&bgp_info->attr->mp_nexthop_global, rule))
1639 return RMAP_MATCH;
1640
1641 if (bgp_info->attr->mp_nexthop_len == 32 &&
1642 IPV6_ADDR_SAME (&bgp_info->attr->mp_nexthop_local, rule))
1643 return RMAP_MATCH;
1644
1645 return RMAP_NOMATCH;
1646 }
1647
1648 return RMAP_NOMATCH;
1649}
1650
1651void *
paulfd79ac92004-10-13 05:06:08 +00001652route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001653{
1654 struct in6_addr *address;
1655 int ret;
1656
1657 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1658
1659 ret = inet_pton (AF_INET6, arg, address);
1660 if (!ret)
1661 {
1662 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1663 return NULL;
1664 }
1665
1666 return address;
1667}
1668
1669void
1670route_match_ipv6_next_hop_free (void *rule)
1671{
1672 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1673}
1674
1675struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1676{
1677 "ipv6 next-hop",
1678 route_match_ipv6_next_hop,
1679 route_match_ipv6_next_hop_compile,
1680 route_match_ipv6_next_hop_free
1681};
1682
1683/* `match ipv6 address prefix-list PREFIX_LIST' */
1684
1685route_map_result_t
1686route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1687 route_map_object_t type, void *object)
1688{
1689 struct prefix_list *plist;
1690
1691 if (type == RMAP_BGP)
1692 {
1693 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1694 if (plist == NULL)
1695 return RMAP_NOMATCH;
1696
1697 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1698 RMAP_NOMATCH : RMAP_MATCH);
1699 }
1700 return RMAP_NOMATCH;
1701}
1702
1703void *
paulfd79ac92004-10-13 05:06:08 +00001704route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001705{
1706 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1707}
1708
1709void
1710route_match_ipv6_address_prefix_list_free (void *rule)
1711{
1712 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1713}
1714
1715struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1716{
1717 "ipv6 address prefix-list",
1718 route_match_ipv6_address_prefix_list,
1719 route_match_ipv6_address_prefix_list_compile,
1720 route_match_ipv6_address_prefix_list_free
1721};
1722
1723/* `set ipv6 nexthop global IP_ADDRESS' */
1724
1725/* Set nexthop to object. ojbect must be pointer to struct attr. */
1726route_map_result_t
1727route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1728 route_map_object_t type, void *object)
1729{
1730 struct in6_addr *address;
1731 struct bgp_info *bgp_info;
1732
1733 if (type == RMAP_BGP)
1734 {
1735 /* Fetch routemap's rule information. */
1736 address = rule;
1737 bgp_info = object;
1738
1739 /* Set next hop value. */
1740 bgp_info->attr->mp_nexthop_global = *address;
1741
1742 /* Set nexthop length. */
1743 if (bgp_info->attr->mp_nexthop_len == 0)
1744 bgp_info->attr->mp_nexthop_len = 16;
1745 }
1746
1747 return RMAP_OKAY;
1748}
1749
1750/* Route map `ip next-hop' compile function. Given string is converted
1751 to struct in_addr structure. */
1752void *
paulfd79ac92004-10-13 05:06:08 +00001753route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001754{
1755 int ret;
1756 struct in6_addr *address;
1757
1758 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1759
1760 ret = inet_pton (AF_INET6, arg, address);
1761
1762 if (ret == 0)
1763 {
1764 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1765 return NULL;
1766 }
1767
1768 return address;
1769}
1770
1771/* Free route map's compiled `ip next-hop' value. */
1772void
1773route_set_ipv6_nexthop_global_free (void *rule)
1774{
1775 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1776}
1777
1778/* Route map commands for ip nexthop set. */
1779struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
1780{
1781 "ipv6 next-hop global",
1782 route_set_ipv6_nexthop_global,
1783 route_set_ipv6_nexthop_global_compile,
1784 route_set_ipv6_nexthop_global_free
1785};
1786
1787/* `set ipv6 nexthop local IP_ADDRESS' */
1788
1789/* Set nexthop to object. ojbect must be pointer to struct attr. */
1790route_map_result_t
1791route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
1792 route_map_object_t type, void *object)
1793{
1794 struct in6_addr *address;
1795 struct bgp_info *bgp_info;
1796
1797 if (type == RMAP_BGP)
1798 {
1799 /* Fetch routemap's rule information. */
1800 address = rule;
1801 bgp_info = object;
1802
1803 /* Set next hop value. */
1804 bgp_info->attr->mp_nexthop_local = *address;
1805
1806 /* Set nexthop length. */
1807 if (bgp_info->attr->mp_nexthop_len != 32)
1808 bgp_info->attr->mp_nexthop_len = 32;
1809 }
1810
1811 return RMAP_OKAY;
1812}
1813
1814/* Route map `ip nexthop' compile function. Given string is converted
1815 to struct in_addr structure. */
1816void *
paulfd79ac92004-10-13 05:06:08 +00001817route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001818{
1819 int ret;
1820 struct in6_addr *address;
1821
1822 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1823
1824 ret = inet_pton (AF_INET6, arg, address);
1825
1826 if (ret == 0)
1827 {
1828 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1829 return NULL;
1830 }
1831
1832 return address;
1833}
1834
1835/* Free route map's compiled `ip nexthop' value. */
1836void
1837route_set_ipv6_nexthop_local_free (void *rule)
1838{
1839 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1840}
1841
1842/* Route map commands for ip nexthop set. */
1843struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
1844{
1845 "ipv6 next-hop local",
1846 route_set_ipv6_nexthop_local,
1847 route_set_ipv6_nexthop_local_compile,
1848 route_set_ipv6_nexthop_local_free
1849};
1850#endif /* HAVE_IPV6 */
1851
1852/* `set vpnv4 nexthop A.B.C.D' */
1853
1854route_map_result_t
1855route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
1856 route_map_object_t type, void *object)
1857{
1858 struct in_addr *address;
1859 struct bgp_info *bgp_info;
1860
1861 if (type == RMAP_BGP)
1862 {
1863 /* Fetch routemap's rule information. */
1864 address = rule;
1865 bgp_info = object;
1866
1867 /* Set next hop value. */
1868 bgp_info->attr->mp_nexthop_global_in = *address;
1869 }
1870
1871 return RMAP_OKAY;
1872}
1873
1874void *
paulfd79ac92004-10-13 05:06:08 +00001875route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001876{
1877 int ret;
1878 struct in_addr *address;
1879
1880 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
1881
1882 ret = inet_aton (arg, address);
1883
1884 if (ret == 0)
1885 {
1886 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1887 return NULL;
1888 }
1889
1890 return address;
1891}
1892
1893void
1894route_set_vpnv4_nexthop_free (void *rule)
1895{
1896 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1897}
1898
1899/* Route map commands for ip nexthop set. */
1900struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
1901{
1902 "vpnv4 next-hop",
1903 route_set_vpnv4_nexthop,
1904 route_set_vpnv4_nexthop_compile,
1905 route_set_vpnv4_nexthop_free
1906};
1907
1908/* `set originator-id' */
1909
1910/* For origin set. */
1911route_map_result_t
1912route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1913{
1914 struct in_addr *address;
1915 struct bgp_info *bgp_info;
1916
1917 if (type == RMAP_BGP)
1918 {
1919 address = rule;
1920 bgp_info = object;
1921
1922 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
1923 bgp_info->attr->originator_id = *address;
1924 }
1925
1926 return RMAP_OKAY;
1927}
1928
1929/* Compile function for originator-id set. */
1930void *
paulfd79ac92004-10-13 05:06:08 +00001931route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001932{
1933 int ret;
1934 struct in_addr *address;
1935
1936 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
1937
1938 ret = inet_aton (arg, address);
1939
1940 if (ret == 0)
1941 {
1942 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1943 return NULL;
1944 }
1945
1946 return address;
1947}
1948
1949/* Compile function for originator_id set. */
1950void
1951route_set_originator_id_free (void *rule)
1952{
1953 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1954}
1955
1956/* Set metric rule structure. */
1957struct route_map_rule_cmd route_set_originator_id_cmd =
1958{
1959 "originator-id",
1960 route_set_originator_id,
1961 route_set_originator_id_compile,
1962 route_set_originator_id_free,
1963};
1964
1965/* Add bgp route map rule. */
1966int
1967bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00001968 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00001969{
1970 int ret;
1971
1972 ret = route_map_add_match (index, command, arg);
1973 if (ret)
1974 {
1975 switch (ret)
1976 {
1977 case RMAP_RULE_MISSING:
1978 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
1979 return CMD_WARNING;
1980 break;
1981 case RMAP_COMPILE_ERROR:
1982 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
1983 return CMD_WARNING;
1984 break;
1985 }
1986 }
1987 return CMD_SUCCESS;
1988}
1989
1990/* Delete bgp route map rule. */
1991int
1992bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00001993 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00001994{
1995 int ret;
1996
1997 ret = route_map_delete_match (index, command, arg);
1998 if (ret)
1999 {
2000 switch (ret)
2001 {
2002 case RMAP_RULE_MISSING:
2003 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2004 return CMD_WARNING;
2005 break;
2006 case RMAP_COMPILE_ERROR:
2007 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2008 return CMD_WARNING;
2009 break;
2010 }
2011 }
2012 return CMD_SUCCESS;
2013}
2014
2015/* Add bgp route map rule. */
2016int
2017bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002018 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002019{
2020 int ret;
2021
2022 ret = route_map_add_set (index, command, arg);
2023 if (ret)
2024 {
2025 switch (ret)
2026 {
2027 case RMAP_RULE_MISSING:
2028 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2029 return CMD_WARNING;
2030 break;
2031 case RMAP_COMPILE_ERROR:
2032 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2033 return CMD_WARNING;
2034 break;
2035 }
2036 }
2037 return CMD_SUCCESS;
2038}
2039
2040/* Delete bgp route map rule. */
2041int
2042bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002043 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002044{
2045 int ret;
2046
2047 ret = route_map_delete_set (index, command, arg);
2048 if (ret)
2049 {
2050 switch (ret)
2051 {
2052 case RMAP_RULE_MISSING:
2053 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2054 return CMD_WARNING;
2055 break;
2056 case RMAP_COMPILE_ERROR:
2057 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2058 return CMD_WARNING;
2059 break;
2060 }
2061 }
2062 return CMD_SUCCESS;
2063}
2064
2065/* Hook function for updating route_map assignment. */
2066void
paulfd79ac92004-10-13 05:06:08 +00002067bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002068{
2069 int i;
2070 afi_t afi;
2071 safi_t safi;
2072 int direct;
2073 struct listnode *nn, *nm;
2074 struct bgp *bgp;
2075 struct peer *peer;
2076 struct peer_group *group;
2077 struct bgp_filter *filter;
2078 struct bgp_node *bn;
2079 struct bgp_static *bgp_static;
2080
2081 /* For neighbor route-map updates. */
2082 LIST_LOOP (bm->bgp, bgp, nn)
2083 {
2084 LIST_LOOP (bgp->peer, peer, nm)
2085 {
2086 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2087 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2088 {
2089 filter = &peer->filter[afi][safi];
2090
paulfee0f4c2004-09-13 05:12:46 +00002091 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002092 {
2093 if (filter->map[direct].name)
2094 filter->map[direct].map =
2095 route_map_lookup_by_name (filter->map[direct].name);
2096 else
2097 filter->map[direct].map = NULL;
2098 }
2099
2100 if (filter->usmap.name)
2101 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2102 else
2103 filter->usmap.map = NULL;
2104 }
2105 }
2106 LIST_LOOP (bgp->group, group, nm)
2107 {
2108 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2109 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2110 {
2111 filter = &group->conf->filter[afi][safi];
2112
paulfee0f4c2004-09-13 05:12:46 +00002113 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002114 {
2115 if (filter->map[direct].name)
2116 filter->map[direct].map =
2117 route_map_lookup_by_name (filter->map[direct].name);
2118 else
2119 filter->map[direct].map = NULL;
2120 }
2121
2122 if (filter->usmap.name)
2123 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2124 else
2125 filter->usmap.map = NULL;
2126 }
2127 }
2128 }
2129
2130 /* For default-originate route-map updates. */
2131 LIST_LOOP (bm->bgp, bgp, nn)
2132 {
2133 LIST_LOOP (bgp->peer, peer, nm)
2134 {
2135 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2136 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2137 {
2138 if (peer->default_rmap[afi][safi].name)
2139 peer->default_rmap[afi][safi].map =
2140 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2141 else
2142 peer->default_rmap[afi][safi].map = NULL;
2143 }
2144 }
2145 }
2146
2147 /* For network route-map updates. */
2148 LIST_LOOP (bm->bgp, bgp, nn)
2149 {
2150 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2151 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2152 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2153 bn = bgp_route_next (bn))
2154 if ((bgp_static = bn->info) != NULL)
2155 {
2156 if (bgp_static->rmap.name)
2157 bgp_static->rmap.map =
2158 route_map_lookup_by_name (bgp_static->rmap.name);
2159 else
2160 bgp_static->rmap.map = NULL;
2161 }
2162 }
2163
2164 /* For redistribute route-map updates. */
2165 LIST_LOOP (bm->bgp, bgp, nn)
2166 {
2167 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2168 {
2169 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2170 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2171 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2172#ifdef HAVE_IPV6
2173 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2174 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2175 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2176#endif /* HAVE_IPV6 */
2177 }
2178 }
2179}
2180
paulfee0f4c2004-09-13 05:12:46 +00002181DEFUN (match_peer,
2182 match_peer_cmd,
2183 "match peer (A.B.C.D|X:X::X:X)",
2184 MATCH_STR
2185 "Match peer address\n"
2186 "IPv6 address of peer\n"
2187 "IP address of peer\n")
2188{
2189 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2190}
2191
2192DEFUN (match_peer_local,
2193 match_peer_local_cmd,
2194 "match peer local",
2195 MATCH_STR
2196 "Match peer address\n"
2197 "Static or Redistributed routes\n")
2198{
2199 return bgp_route_match_add (vty, vty->index, "peer", NULL);
2200}
2201
2202DEFUN (no_match_peer,
2203 no_match_peer_cmd,
2204 "no match peer",
2205 NO_STR
2206 MATCH_STR
2207 "Match peer address\n")
2208{
2209 if (argc == 0)
2210 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2211
2212 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2213}
2214
2215ALIAS (no_match_peer,
2216 no_match_peer_val_cmd,
2217 "no match peer (A.B.C.D|X:X::X:X)",
2218 NO_STR
2219 MATCH_STR
2220 "Match peer address\n"
2221 "IPv6 address of peer\n"
2222 "IP address of peer\n")
2223
2224ALIAS (no_match_peer,
2225 no_match_peer_local_cmd,
2226 "no match peer local",
2227 NO_STR
2228 MATCH_STR
2229 "Match peer address\n"
2230 "Static or Redistributed routes\n")
2231
paul718e3742002-12-13 20:15:29 +00002232DEFUN (match_ip_address,
2233 match_ip_address_cmd,
2234 "match ip address (<1-199>|<1300-2699>|WORD)",
2235 MATCH_STR
2236 IP_STR
2237 "Match address of route\n"
2238 "IP access-list number\n"
2239 "IP access-list number (expanded range)\n"
2240 "IP Access-list name\n")
2241{
2242 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2243}
2244
2245DEFUN (no_match_ip_address,
2246 no_match_ip_address_cmd,
2247 "no match ip address",
2248 NO_STR
2249 MATCH_STR
2250 IP_STR
2251 "Match address of route\n")
2252{
2253 if (argc == 0)
2254 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2255
2256 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2257}
2258
2259ALIAS (no_match_ip_address,
2260 no_match_ip_address_val_cmd,
2261 "no match ip address (<1-199>|<1300-2699>|WORD)",
2262 NO_STR
2263 MATCH_STR
2264 IP_STR
2265 "Match address of route\n"
2266 "IP access-list number\n"
2267 "IP access-list number (expanded range)\n"
2268 "IP Access-list name\n")
2269
2270DEFUN (match_ip_next_hop,
2271 match_ip_next_hop_cmd,
2272 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2273 MATCH_STR
2274 IP_STR
2275 "Match next-hop address of route\n"
2276 "IP access-list number\n"
2277 "IP access-list number (expanded range)\n"
2278 "IP Access-list name\n")
2279{
2280 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2281}
2282
2283DEFUN (no_match_ip_next_hop,
2284 no_match_ip_next_hop_cmd,
2285 "no match ip next-hop",
2286 NO_STR
2287 MATCH_STR
2288 IP_STR
2289 "Match next-hop address of route\n")
2290{
2291 if (argc == 0)
2292 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2293
2294 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2295}
2296
2297ALIAS (no_match_ip_next_hop,
2298 no_match_ip_next_hop_val_cmd,
2299 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2300 NO_STR
2301 MATCH_STR
2302 IP_STR
2303 "Match next-hop address of route\n"
2304 "IP access-list number\n"
2305 "IP access-list number (expanded range)\n"
2306 "IP Access-list name\n")
2307
2308DEFUN (match_ip_address_prefix_list,
2309 match_ip_address_prefix_list_cmd,
2310 "match ip address prefix-list WORD",
2311 MATCH_STR
2312 IP_STR
2313 "Match address of route\n"
2314 "Match entries of prefix-lists\n"
2315 "IP prefix-list name\n")
2316{
2317 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2318}
2319
2320DEFUN (no_match_ip_address_prefix_list,
2321 no_match_ip_address_prefix_list_cmd,
2322 "no match ip address prefix-list",
2323 NO_STR
2324 MATCH_STR
2325 IP_STR
2326 "Match address of route\n"
2327 "Match entries of prefix-lists\n")
2328{
2329 if (argc == 0)
2330 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2331
2332 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2333}
2334
2335ALIAS (no_match_ip_address_prefix_list,
2336 no_match_ip_address_prefix_list_val_cmd,
2337 "no match ip address prefix-list WORD",
2338 NO_STR
2339 MATCH_STR
2340 IP_STR
2341 "Match address of route\n"
2342 "Match entries of prefix-lists\n"
2343 "IP prefix-list name\n")
2344
2345DEFUN (match_ip_next_hop_prefix_list,
2346 match_ip_next_hop_prefix_list_cmd,
2347 "match ip next-hop prefix-list WORD",
2348 MATCH_STR
2349 IP_STR
2350 "Match next-hop address of route\n"
2351 "Match entries of prefix-lists\n"
2352 "IP prefix-list name\n")
2353{
2354 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2355}
2356
2357DEFUN (no_match_ip_next_hop_prefix_list,
2358 no_match_ip_next_hop_prefix_list_cmd,
2359 "no match ip next-hop prefix-list",
2360 NO_STR
2361 MATCH_STR
2362 IP_STR
2363 "Match next-hop address of route\n"
2364 "Match entries of prefix-lists\n")
2365{
2366 if (argc == 0)
2367 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2368
2369 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2370}
2371
2372ALIAS (no_match_ip_next_hop_prefix_list,
2373 no_match_ip_next_hop_prefix_list_val_cmd,
2374 "no match ip next-hop prefix-list WORD",
2375 NO_STR
2376 MATCH_STR
2377 IP_STR
2378 "Match next-hop address of route\n"
2379 "Match entries of prefix-lists\n"
2380 "IP prefix-list name\n")
2381
2382DEFUN (match_metric,
2383 match_metric_cmd,
2384 "match metric <0-4294967295>",
2385 MATCH_STR
2386 "Match metric of route\n"
2387 "Metric value\n")
2388{
2389 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2390}
2391
2392DEFUN (no_match_metric,
2393 no_match_metric_cmd,
2394 "no match metric",
2395 NO_STR
2396 MATCH_STR
2397 "Match metric of route\n")
2398{
2399 if (argc == 0)
2400 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2401
2402 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2403}
2404
2405ALIAS (no_match_metric,
2406 no_match_metric_val_cmd,
2407 "no match metric <0-4294967295>",
2408 NO_STR
2409 MATCH_STR
2410 "Match metric of route\n"
2411 "Metric value\n")
2412
2413DEFUN (match_community,
2414 match_community_cmd,
2415 "match community (<1-99>|<100-199>|WORD)",
2416 MATCH_STR
2417 "Match BGP community list\n"
2418 "Community-list number (standard)\n"
2419 "Community-list number (expanded)\n"
2420 "Community-list name\n")
2421{
2422 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2423}
2424
2425DEFUN (match_community_exact,
2426 match_community_exact_cmd,
2427 "match community (<1-99>|<100-199>|WORD) exact-match",
2428 MATCH_STR
2429 "Match BGP community list\n"
2430 "Community-list number (standard)\n"
2431 "Community-list number (expanded)\n"
2432 "Community-list name\n"
2433 "Do exact matching of communities\n")
2434{
2435 int ret;
2436 char *argstr;
2437
2438 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2439 strlen (argv[0]) + strlen ("exact-match") + 2);
2440
2441 sprintf (argstr, "%s exact-match", argv[0]);
2442
2443 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2444
2445 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2446
2447 return ret;
2448}
2449
2450DEFUN (no_match_community,
2451 no_match_community_cmd,
2452 "no match community",
2453 NO_STR
2454 MATCH_STR
2455 "Match BGP community list\n")
2456{
2457 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2458}
2459
2460ALIAS (no_match_community,
2461 no_match_community_val_cmd,
2462 "no match community (<1-99>|<100-199>|WORD)",
2463 NO_STR
2464 MATCH_STR
2465 "Match BGP community list\n"
2466 "Community-list number (standard)\n"
2467 "Community-list number (expanded)\n"
2468 "Community-list name\n")
2469
2470ALIAS (no_match_community,
2471 no_match_community_exact_cmd,
2472 "no match community (<1-99>|<100-199>|WORD) exact-match",
2473 NO_STR
2474 MATCH_STR
2475 "Match BGP community list\n"
2476 "Community-list number (standard)\n"
2477 "Community-list number (expanded)\n"
2478 "Community-list name\n"
2479 "Do exact matching of communities\n")
2480
paul73ffb252003-04-19 15:49:49 +00002481DEFUN (match_ecommunity,
2482 match_ecommunity_cmd,
2483 "match extcommunity (<1-99>|<100-199>|WORD)",
2484 MATCH_STR
2485 "Match BGP/VPN extended community list\n"
2486 "Extended community-list number (standard)\n"
2487 "Extended community-list number (expanded)\n"
2488 "Extended community-list name\n")
2489{
2490 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2491}
2492
2493DEFUN (no_match_ecommunity,
2494 no_match_ecommunity_cmd,
2495 "no match extcommunity",
2496 NO_STR
2497 MATCH_STR
2498 "Match BGP/VPN extended community list\n")
2499{
2500 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2501}
2502
2503ALIAS (no_match_ecommunity,
2504 no_match_ecommunity_val_cmd,
2505 "no match extcommunity (<1-99>|<100-199>|WORD)",
2506 NO_STR
2507 MATCH_STR
2508 "Match BGP/VPN extended community list\n"
2509 "Extended community-list number (standard)\n"
2510 "Extended community-list number (expanded)\n"
2511 "Extended community-list name\n")
2512
paul718e3742002-12-13 20:15:29 +00002513DEFUN (match_aspath,
2514 match_aspath_cmd,
2515 "match as-path WORD",
2516 MATCH_STR
2517 "Match BGP AS path list\n"
2518 "AS path access-list name\n")
2519{
2520 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2521}
2522
2523DEFUN (no_match_aspath,
2524 no_match_aspath_cmd,
2525 "no match as-path",
2526 NO_STR
2527 MATCH_STR
2528 "Match BGP AS path list\n")
2529{
2530 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2531}
2532
2533ALIAS (no_match_aspath,
2534 no_match_aspath_val_cmd,
2535 "no match as-path WORD",
2536 NO_STR
2537 MATCH_STR
2538 "Match BGP AS path list\n"
2539 "AS path access-list name\n")
2540
2541DEFUN (match_origin,
2542 match_origin_cmd,
2543 "match origin (egp|igp|incomplete)",
2544 MATCH_STR
2545 "BGP origin code\n"
2546 "remote EGP\n"
2547 "local IGP\n"
2548 "unknown heritage\n")
2549{
2550 if (strncmp (argv[0], "igp", 2) == 0)
2551 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2552 if (strncmp (argv[0], "egp", 1) == 0)
2553 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2554 if (strncmp (argv[0], "incomplete", 2) == 0)
2555 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2556
2557 return CMD_WARNING;
2558}
2559
2560DEFUN (no_match_origin,
2561 no_match_origin_cmd,
2562 "no match origin",
2563 NO_STR
2564 MATCH_STR
2565 "BGP origin code\n")
2566{
2567 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2568}
2569
2570ALIAS (no_match_origin,
2571 no_match_origin_val_cmd,
2572 "no match origin (egp|igp|incomplete)",
2573 NO_STR
2574 MATCH_STR
2575 "BGP origin code\n"
2576 "remote EGP\n"
2577 "local IGP\n"
2578 "unknown heritage\n")
2579
2580DEFUN (set_ip_nexthop,
2581 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002582 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002583 SET_STR
2584 IP_STR
2585 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002586 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002587{
2588 union sockunion su;
2589 int ret;
2590
2591 ret = str2sockunion (argv[0], &su);
2592 if (ret < 0)
2593 {
2594 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2595 return CMD_WARNING;
2596 }
2597
2598 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2599}
2600
paulaf5cd0a2003-11-02 07:24:40 +00002601DEFUN (set_ip_nexthop_peer,
2602 set_ip_nexthop_peer_cmd,
2603 "set ip next-hop peer-address",
2604 SET_STR
2605 IP_STR
2606 "Next hop address\n"
2607 "Use peer address (for BGP only)\n")
2608{
2609 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2610}
2611
2612DEFUN (no_set_ip_nexthop_peer,
2613 no_set_ip_nexthop_peer_cmd,
2614 "no set ip next-hop peer-address",
2615 NO_STR
2616 SET_STR
2617 IP_STR
2618 "Next hop address\n"
2619 "Use peer address (for BGP only)\n")
2620{
2621 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2622}
2623
2624
paul718e3742002-12-13 20:15:29 +00002625DEFUN (no_set_ip_nexthop,
2626 no_set_ip_nexthop_cmd,
2627 "no set ip next-hop",
2628 NO_STR
2629 SET_STR
paul718e3742002-12-13 20:15:29 +00002630 "Next hop address\n")
2631{
paulaf5cd0a2003-11-02 07:24:40 +00002632 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002633 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2634
2635 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2636}
2637
2638ALIAS (no_set_ip_nexthop,
2639 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002640 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002641 NO_STR
2642 SET_STR
2643 IP_STR
2644 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002645 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002646
2647DEFUN (set_metric,
2648 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002649 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002650 SET_STR
2651 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002652 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002653{
2654 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2655}
2656
paul73ffb252003-04-19 15:49:49 +00002657ALIAS (set_metric,
2658 set_metric_addsub_cmd,
2659 "set metric <+/-metric>",
2660 SET_STR
2661 "Metric value for destination routing protocol\n"
2662 "Add or subtract BGP metric\n")
2663
paul718e3742002-12-13 20:15:29 +00002664DEFUN (no_set_metric,
2665 no_set_metric_cmd,
2666 "no set metric",
2667 NO_STR
2668 SET_STR
2669 "Metric value for destination routing protocol\n")
2670{
2671 if (argc == 0)
2672 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
2673
2674 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
2675}
2676
2677ALIAS (no_set_metric,
2678 no_set_metric_val_cmd,
2679 "no set metric <0-4294967295>",
2680 NO_STR
2681 SET_STR
2682 "Metric value for destination routing protocol\n"
2683 "Metric value\n")
2684
2685DEFUN (set_local_pref,
2686 set_local_pref_cmd,
2687 "set local-preference <0-4294967295>",
2688 SET_STR
2689 "BGP local preference path attribute\n"
2690 "Preference value\n")
2691{
2692 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
2693}
2694
2695DEFUN (no_set_local_pref,
2696 no_set_local_pref_cmd,
2697 "no set local-preference",
2698 NO_STR
2699 SET_STR
2700 "BGP local preference path attribute\n")
2701{
2702 if (argc == 0)
2703 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
2704
2705 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
2706}
2707
2708ALIAS (no_set_local_pref,
2709 no_set_local_pref_val_cmd,
2710 "no set local-preference <0-4294967295>",
2711 NO_STR
2712 SET_STR
2713 "BGP local preference path attribute\n"
2714 "Preference value\n")
2715
2716DEFUN (set_weight,
2717 set_weight_cmd,
2718 "set weight <0-4294967295>",
2719 SET_STR
2720 "BGP weight for routing table\n"
2721 "Weight value\n")
2722{
2723 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
2724}
2725
2726DEFUN (no_set_weight,
2727 no_set_weight_cmd,
2728 "no set weight",
2729 NO_STR
2730 SET_STR
2731 "BGP weight for routing table\n")
2732{
2733 if (argc == 0)
2734 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
2735
2736 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
2737}
2738
2739ALIAS (no_set_weight,
2740 no_set_weight_val_cmd,
2741 "no set weight <0-4294967295>",
2742 NO_STR
2743 SET_STR
2744 "BGP weight for routing table\n"
2745 "Weight value\n")
2746
2747DEFUN (set_aspath_prepend,
2748 set_aspath_prepend_cmd,
2749 "set as-path prepend .<1-65535>",
2750 SET_STR
2751 "Prepend string for a BGP AS-path attribute\n"
2752 "Prepend to the as-path\n"
2753 "AS number\n")
2754{
2755 int ret;
2756 char *str;
2757
2758 str = argv_concat (argv, argc, 0);
2759 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
2760 XFREE (MTYPE_TMP, str);
2761
2762 return ret;
2763}
2764
2765DEFUN (no_set_aspath_prepend,
2766 no_set_aspath_prepend_cmd,
2767 "no set as-path prepend",
2768 NO_STR
2769 SET_STR
2770 "Prepend string for a BGP AS-path attribute\n"
2771 "Prepend to the as-path\n")
2772{
2773 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
2774}
2775
2776ALIAS (no_set_aspath_prepend,
2777 no_set_aspath_prepend_val_cmd,
2778 "no set as-path prepend .<1-65535>",
2779 NO_STR
2780 SET_STR
2781 "Prepend string for a BGP AS-path attribute\n"
2782 "Prepend to the as-path\n"
2783 "AS number\n")
2784
2785DEFUN (set_community,
2786 set_community_cmd,
2787 "set community .AA:NN",
2788 SET_STR
2789 "BGP community attribute\n"
2790 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
2791{
2792 int i;
2793 int first = 0;
2794 int additive = 0;
2795 struct buffer *b;
2796 struct community *com = NULL;
2797 char *str;
2798 char *argstr;
2799 int ret;
2800
2801 b = buffer_new (1024);
2802
2803 for (i = 0; i < argc; i++)
2804 {
2805 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
2806 {
2807 additive = 1;
2808 continue;
2809 }
2810
2811 if (first)
2812 buffer_putc (b, ' ');
2813 else
2814 first = 1;
2815
2816 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
2817 {
2818 buffer_putstr (b, "internet");
2819 continue;
2820 }
2821 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
2822 {
2823 buffer_putstr (b, "local-AS");
2824 continue;
2825 }
2826 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
2827 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
2828 {
2829 buffer_putstr (b, "no-advertise");
2830 continue;
2831 }
2832 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
2833 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
2834 {
2835 buffer_putstr (b, "no-export");
2836 continue;
2837 }
2838 buffer_putstr (b, argv[i]);
2839 }
2840 buffer_putc (b, '\0');
2841
2842 /* Fetch result string then compile it to communities attribute. */
2843 str = buffer_getstr (b);
2844 buffer_free (b);
2845
2846 if (str)
2847 {
2848 com = community_str2com (str);
2849 free (str);
2850 }
2851
2852 /* Can't compile user input into communities attribute. */
2853 if (! com)
2854 {
2855 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
2856 return CMD_WARNING;
2857 }
2858
2859 /* Set communites attribute string. */
2860 str = community_str (com);
2861
2862 if (additive)
2863 {
2864 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
2865 strcpy (argstr, str);
2866 strcpy (argstr + strlen (str), " additive");
2867 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
2868 XFREE (MTYPE_TMP, argstr);
2869 }
2870 else
2871 ret = bgp_route_set_add (vty, vty->index, "community", str);
2872
2873 community_free (com);
2874
2875 return ret;
2876}
2877
2878DEFUN (set_community_none,
2879 set_community_none_cmd,
2880 "set community none",
2881 SET_STR
2882 "BGP community attribute\n"
2883 "No community attribute\n")
2884{
2885 return bgp_route_set_add (vty, vty->index, "community", "none");
2886}
2887
2888DEFUN (no_set_community,
2889 no_set_community_cmd,
2890 "no set community",
2891 NO_STR
2892 SET_STR
2893 "BGP community attribute\n")
2894{
2895 return bgp_route_set_delete (vty, vty->index, "community", NULL);
2896}
2897
2898ALIAS (no_set_community,
2899 no_set_community_val_cmd,
2900 "no set community .AA:NN",
2901 NO_STR
2902 SET_STR
2903 "BGP community attribute\n"
2904 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
2905
2906ALIAS (no_set_community,
2907 no_set_community_none_cmd,
2908 "no set community none",
2909 NO_STR
2910 SET_STR
2911 "BGP community attribute\n"
2912 "No community attribute\n")
2913
2914DEFUN (set_community_delete,
2915 set_community_delete_cmd,
2916 "set comm-list (<1-99>|<100-199>|WORD) delete",
2917 SET_STR
2918 "set BGP community list (for deletion)\n"
2919 "Community-list number (standard)\n"
2920 "Communitly-list number (expanded)\n"
2921 "Community-list name\n"
2922 "Delete matching communities\n")
2923{
2924 char *str;
2925
2926 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
2927 strcpy (str, argv[0]);
2928 strcpy (str + strlen (argv[0]), " delete");
2929
2930 bgp_route_set_add (vty, vty->index, "comm-list", str);
2931
2932 XFREE (MTYPE_TMP, str);
2933 return CMD_SUCCESS;
2934}
2935
2936DEFUN (no_set_community_delete,
2937 no_set_community_delete_cmd,
2938 "no set comm-list",
2939 NO_STR
2940 SET_STR
2941 "set BGP community list (for deletion)\n")
2942{
2943 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
2944}
2945
2946ALIAS (no_set_community_delete,
2947 no_set_community_delete_val_cmd,
2948 "no set comm-list (<1-99>|<100-199>|WORD) delete",
2949 NO_STR
2950 SET_STR
2951 "set BGP community list (for deletion)\n"
2952 "Community-list number (standard)\n"
2953 "Communitly-list number (expanded)\n"
2954 "Community-list name\n"
2955 "Delete matching communities\n")
2956
2957DEFUN (set_ecommunity_rt,
2958 set_ecommunity_rt_cmd,
2959 "set extcommunity rt .ASN:nn_or_IP-address:nn",
2960 SET_STR
2961 "BGP extended community attribute\n"
2962 "Route Target extened communityt\n"
2963 "VPN extended community\n")
2964{
2965 int ret;
2966 char *str;
2967
2968 str = argv_concat (argv, argc, 0);
2969 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
2970 XFREE (MTYPE_TMP, str);
2971
2972 return ret;
2973}
2974
2975DEFUN (no_set_ecommunity_rt,
2976 no_set_ecommunity_rt_cmd,
2977 "no set extcommunity rt",
2978 NO_STR
2979 SET_STR
2980 "BGP extended community attribute\n"
2981 "Route Target extened communityt\n")
2982{
2983 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
2984}
2985
2986ALIAS (no_set_ecommunity_rt,
2987 no_set_ecommunity_rt_val_cmd,
2988 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
2989 NO_STR
2990 SET_STR
2991 "BGP extended community attribute\n"
2992 "Route Target extened communityt\n"
2993 "VPN extended community\n")
2994
2995DEFUN (set_ecommunity_soo,
2996 set_ecommunity_soo_cmd,
2997 "set extcommunity soo .ASN:nn_or_IP-address:nn",
2998 SET_STR
2999 "BGP extended community attribute\n"
3000 "Site-of-Origin extended community\n"
3001 "VPN extended community\n")
3002{
3003 int ret;
3004 char *str;
3005
3006 str = argv_concat (argv, argc, 0);
3007 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3008 XFREE (MTYPE_TMP, str);
3009 return ret;
3010}
3011
3012DEFUN (no_set_ecommunity_soo,
3013 no_set_ecommunity_soo_cmd,
3014 "no set extcommunity soo",
3015 NO_STR
3016 SET_STR
3017 "BGP extended community attribute\n"
3018 "Site-of-Origin extended community\n")
3019{
3020 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3021}
3022
3023ALIAS (no_set_ecommunity_soo,
3024 no_set_ecommunity_soo_val_cmd,
3025 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3026 NO_STR
3027 SET_STR
3028 "BGP extended community attribute\n"
3029 "Site-of-Origin extended community\n"
3030 "VPN extended community\n")
3031
3032DEFUN (set_origin,
3033 set_origin_cmd,
3034 "set origin (egp|igp|incomplete)",
3035 SET_STR
3036 "BGP origin code\n"
3037 "remote EGP\n"
3038 "local IGP\n"
3039 "unknown heritage\n")
3040{
3041 if (strncmp (argv[0], "igp", 2) == 0)
3042 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3043 if (strncmp (argv[0], "egp", 1) == 0)
3044 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3045 if (strncmp (argv[0], "incomplete", 2) == 0)
3046 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3047
3048 return CMD_WARNING;
3049}
3050
3051DEFUN (no_set_origin,
3052 no_set_origin_cmd,
3053 "no set origin",
3054 NO_STR
3055 SET_STR
3056 "BGP origin code\n")
3057{
3058 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3059}
3060
3061ALIAS (no_set_origin,
3062 no_set_origin_val_cmd,
3063 "no set origin (egp|igp|incomplete)",
3064 NO_STR
3065 SET_STR
3066 "BGP origin code\n"
3067 "remote EGP\n"
3068 "local IGP\n"
3069 "unknown heritage\n")
3070
3071DEFUN (set_atomic_aggregate,
3072 set_atomic_aggregate_cmd,
3073 "set atomic-aggregate",
3074 SET_STR
3075 "BGP atomic aggregate attribute\n" )
3076{
3077 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3078}
3079
3080DEFUN (no_set_atomic_aggregate,
3081 no_set_atomic_aggregate_cmd,
3082 "no set atomic-aggregate",
3083 NO_STR
3084 SET_STR
3085 "BGP atomic aggregate attribute\n" )
3086{
3087 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3088}
3089
3090DEFUN (set_aggregator_as,
3091 set_aggregator_as_cmd,
3092 "set aggregator as <1-65535> A.B.C.D",
3093 SET_STR
3094 "BGP aggregator attribute\n"
3095 "AS number of aggregator\n"
3096 "AS number\n"
3097 "IP address of aggregator\n")
3098{
3099 int ret;
3100 as_t as;
3101 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003102 char *argstr;
3103
paulfd79ac92004-10-13 05:06:08 +00003104 VTY_GET_INTEGER_RANGE ("AS Path", as, argv[0], 1, BGP_AS_MAX)
3105
paul718e3742002-12-13 20:15:29 +00003106 ret = inet_aton (argv[1], &address);
3107 if (ret == 0)
3108 {
3109 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3110 return CMD_WARNING;
3111 }
3112
3113 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3114 strlen (argv[0]) + strlen (argv[1]) + 2);
3115
3116 sprintf (argstr, "%s %s", argv[0], argv[1]);
3117
3118 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3119
3120 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3121
3122 return ret;
3123}
3124
3125DEFUN (no_set_aggregator_as,
3126 no_set_aggregator_as_cmd,
3127 "no set aggregator as",
3128 NO_STR
3129 SET_STR
3130 "BGP aggregator attribute\n"
3131 "AS number of aggregator\n")
3132{
3133 int ret;
3134 as_t as;
3135 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003136 char *argstr;
3137
3138 if (argv == 0)
3139 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3140
paulfd79ac92004-10-13 05:06:08 +00003141 VTY_GET_INTEGER_RANGE ("AS Path", as, argv[0], 1, BGP_AS_MAX)
paul718e3742002-12-13 20:15:29 +00003142
3143 ret = inet_aton (argv[1], &address);
3144 if (ret == 0)
3145 {
3146 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3147 return CMD_WARNING;
3148 }
3149
3150 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3151 strlen (argv[0]) + strlen (argv[1]) + 2);
3152
3153 sprintf (argstr, "%s %s", argv[0], argv[1]);
3154
3155 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3156
3157 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3158
3159 return ret;
3160}
3161
3162ALIAS (no_set_aggregator_as,
3163 no_set_aggregator_as_val_cmd,
3164 "no set aggregator as <1-65535> A.B.C.D",
3165 NO_STR
3166 SET_STR
3167 "BGP aggregator attribute\n"
3168 "AS number of aggregator\n"
3169 "AS number\n"
3170 "IP address of aggregator\n")
3171
3172
3173#ifdef HAVE_IPV6
3174DEFUN (match_ipv6_address,
3175 match_ipv6_address_cmd,
3176 "match ipv6 address WORD",
3177 MATCH_STR
3178 IPV6_STR
3179 "Match IPv6 address of route\n"
3180 "IPv6 access-list name\n")
3181{
3182 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3183}
3184
3185DEFUN (no_match_ipv6_address,
3186 no_match_ipv6_address_cmd,
3187 "no match ipv6 address WORD",
3188 NO_STR
3189 MATCH_STR
3190 IPV6_STR
3191 "Match IPv6 address of route\n"
3192 "IPv6 access-list name\n")
3193{
3194 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3195}
3196
3197DEFUN (match_ipv6_next_hop,
3198 match_ipv6_next_hop_cmd,
3199 "match ipv6 next-hop X:X::X:X",
3200 MATCH_STR
3201 IPV6_STR
3202 "Match IPv6 next-hop address of route\n"
3203 "IPv6 address of next hop\n")
3204{
3205 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3206}
3207
3208DEFUN (no_match_ipv6_next_hop,
3209 no_match_ipv6_next_hop_cmd,
3210 "no match ipv6 next-hop X:X::X:X",
3211 NO_STR
3212 MATCH_STR
3213 IPV6_STR
3214 "Match IPv6 next-hop address of route\n"
3215 "IPv6 address of next hop\n")
3216{
3217 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3218}
3219
3220DEFUN (match_ipv6_address_prefix_list,
3221 match_ipv6_address_prefix_list_cmd,
3222 "match ipv6 address prefix-list WORD",
3223 MATCH_STR
3224 IPV6_STR
3225 "Match address of route\n"
3226 "Match entries of prefix-lists\n"
3227 "IP prefix-list name\n")
3228{
3229 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3230}
3231
3232DEFUN (no_match_ipv6_address_prefix_list,
3233 no_match_ipv6_address_prefix_list_cmd,
3234 "no match ipv6 address prefix-list WORD",
3235 NO_STR
3236 MATCH_STR
3237 IPV6_STR
3238 "Match address of route\n"
3239 "Match entries of prefix-lists\n"
3240 "IP prefix-list name\n")
3241{
3242 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3243}
3244
3245DEFUN (set_ipv6_nexthop_global,
3246 set_ipv6_nexthop_global_cmd,
3247 "set ipv6 next-hop global X:X::X:X",
3248 SET_STR
3249 IPV6_STR
3250 "IPv6 next-hop address\n"
3251 "IPv6 global address\n"
3252 "IPv6 address of next hop\n")
3253{
3254 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3255}
3256
3257DEFUN (no_set_ipv6_nexthop_global,
3258 no_set_ipv6_nexthop_global_cmd,
3259 "no set ipv6 next-hop global",
3260 NO_STR
3261 SET_STR
3262 IPV6_STR
3263 "IPv6 next-hop address\n"
3264 "IPv6 global address\n")
3265{
3266 if (argc == 0)
3267 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3268
3269 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3270}
3271
3272ALIAS (no_set_ipv6_nexthop_global,
3273 no_set_ipv6_nexthop_global_val_cmd,
3274 "no set ipv6 next-hop global X:X::X:X",
3275 NO_STR
3276 SET_STR
3277 IPV6_STR
3278 "IPv6 next-hop address\n"
3279 "IPv6 global address\n"
3280 "IPv6 address of next hop\n")
3281
3282DEFUN (set_ipv6_nexthop_local,
3283 set_ipv6_nexthop_local_cmd,
3284 "set ipv6 next-hop local X:X::X:X",
3285 SET_STR
3286 IPV6_STR
3287 "IPv6 next-hop address\n"
3288 "IPv6 local address\n"
3289 "IPv6 address of next hop\n")
3290{
3291 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3292}
3293
3294DEFUN (no_set_ipv6_nexthop_local,
3295 no_set_ipv6_nexthop_local_cmd,
3296 "no set ipv6 next-hop local",
3297 NO_STR
3298 SET_STR
3299 IPV6_STR
3300 "IPv6 next-hop address\n"
3301 "IPv6 local address\n")
3302{
3303 if (argc == 0)
3304 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3305
3306 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3307}
3308
3309ALIAS (no_set_ipv6_nexthop_local,
3310 no_set_ipv6_nexthop_local_val_cmd,
3311 "no set ipv6 next-hop local X:X::X:X",
3312 NO_STR
3313 SET_STR
3314 IPV6_STR
3315 "IPv6 next-hop address\n"
3316 "IPv6 local address\n"
3317 "IPv6 address of next hop\n")
3318#endif /* HAVE_IPV6 */
3319
3320DEFUN (set_vpnv4_nexthop,
3321 set_vpnv4_nexthop_cmd,
3322 "set vpnv4 next-hop A.B.C.D",
3323 SET_STR
3324 "VPNv4 information\n"
3325 "VPNv4 next-hop address\n"
3326 "IP address of next hop\n")
3327{
3328 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3329}
3330
3331DEFUN (no_set_vpnv4_nexthop,
3332 no_set_vpnv4_nexthop_cmd,
3333 "no set vpnv4 next-hop",
3334 NO_STR
3335 SET_STR
3336 "VPNv4 information\n"
3337 "VPNv4 next-hop address\n")
3338{
3339 if (argc == 0)
3340 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3341
3342 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3343}
3344
3345ALIAS (no_set_vpnv4_nexthop,
3346 no_set_vpnv4_nexthop_val_cmd,
3347 "no set vpnv4 next-hop A.B.C.D",
3348 NO_STR
3349 SET_STR
3350 "VPNv4 information\n"
3351 "VPNv4 next-hop address\n"
3352 "IP address of next hop\n")
3353
3354DEFUN (set_originator_id,
3355 set_originator_id_cmd,
3356 "set originator-id A.B.C.D",
3357 SET_STR
3358 "BGP originator ID attribute\n"
3359 "IP address of originator\n")
3360{
3361 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3362}
3363
3364DEFUN (no_set_originator_id,
3365 no_set_originator_id_cmd,
3366 "no set originator-id",
3367 NO_STR
3368 SET_STR
3369 "BGP originator ID attribute\n")
3370{
3371 if (argc == 0)
3372 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3373
3374 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3375}
3376
3377ALIAS (no_set_originator_id,
3378 no_set_originator_id_val_cmd,
3379 "no set originator-id A.B.C.D",
3380 NO_STR
3381 SET_STR
3382 "BGP originator ID attribute\n"
3383 "IP address of originator\n")
3384
3385
3386/* Initialization of route map. */
3387void
3388bgp_route_map_init ()
3389{
3390 route_map_init ();
3391 route_map_init_vty ();
3392 route_map_add_hook (bgp_route_map_update);
3393 route_map_delete_hook (bgp_route_map_update);
3394
paulfee0f4c2004-09-13 05:12:46 +00003395 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003396 route_map_install_match (&route_match_ip_address_cmd);
3397 route_map_install_match (&route_match_ip_next_hop_cmd);
3398 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3399 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
3400 route_map_install_match (&route_match_aspath_cmd);
3401 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003402 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003403 route_map_install_match (&route_match_metric_cmd);
3404 route_map_install_match (&route_match_origin_cmd);
3405
3406 route_map_install_set (&route_set_ip_nexthop_cmd);
3407 route_map_install_set (&route_set_local_pref_cmd);
3408 route_map_install_set (&route_set_weight_cmd);
3409 route_map_install_set (&route_set_metric_cmd);
3410 route_map_install_set (&route_set_aspath_prepend_cmd);
3411 route_map_install_set (&route_set_origin_cmd);
3412 route_map_install_set (&route_set_atomic_aggregate_cmd);
3413 route_map_install_set (&route_set_aggregator_as_cmd);
3414 route_map_install_set (&route_set_community_cmd);
3415 route_map_install_set (&route_set_community_delete_cmd);
3416 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3417 route_map_install_set (&route_set_originator_id_cmd);
3418 route_map_install_set (&route_set_ecommunity_rt_cmd);
3419 route_map_install_set (&route_set_ecommunity_soo_cmd);
3420
paulfee0f4c2004-09-13 05:12:46 +00003421 install_element (RMAP_NODE, &match_peer_cmd);
3422 install_element (RMAP_NODE, &match_peer_local_cmd);
3423 install_element (RMAP_NODE, &no_match_peer_cmd);
3424 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3425 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003426 install_element (RMAP_NODE, &match_ip_address_cmd);
3427 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3428 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3429 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3430 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3431 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
3432
3433 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3434 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3435 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3436 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3437 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3438 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
3439
3440 install_element (RMAP_NODE, &match_aspath_cmd);
3441 install_element (RMAP_NODE, &no_match_aspath_cmd);
3442 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3443 install_element (RMAP_NODE, &match_metric_cmd);
3444 install_element (RMAP_NODE, &no_match_metric_cmd);
3445 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3446 install_element (RMAP_NODE, &match_community_cmd);
3447 install_element (RMAP_NODE, &match_community_exact_cmd);
3448 install_element (RMAP_NODE, &no_match_community_cmd);
3449 install_element (RMAP_NODE, &no_match_community_val_cmd);
3450 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003451 install_element (RMAP_NODE, &match_ecommunity_cmd);
3452 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3453 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003454 install_element (RMAP_NODE, &match_origin_cmd);
3455 install_element (RMAP_NODE, &no_match_origin_cmd);
3456 install_element (RMAP_NODE, &no_match_origin_val_cmd);
3457
3458 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003459 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003460 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3461 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3462 install_element (RMAP_NODE, &set_local_pref_cmd);
3463 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3464 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3465 install_element (RMAP_NODE, &set_weight_cmd);
3466 install_element (RMAP_NODE, &no_set_weight_cmd);
3467 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3468 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003469 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003470 install_element (RMAP_NODE, &no_set_metric_cmd);
3471 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3472 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
3473 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3474 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
3475 install_element (RMAP_NODE, &set_origin_cmd);
3476 install_element (RMAP_NODE, &no_set_origin_cmd);
3477 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3478 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3479 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3480 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3481 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3482 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3483 install_element (RMAP_NODE, &set_community_cmd);
3484 install_element (RMAP_NODE, &set_community_none_cmd);
3485 install_element (RMAP_NODE, &no_set_community_cmd);
3486 install_element (RMAP_NODE, &no_set_community_val_cmd);
3487 install_element (RMAP_NODE, &no_set_community_none_cmd);
3488 install_element (RMAP_NODE, &set_community_delete_cmd);
3489 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3490 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3491 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3492 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3493 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3494 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3495 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3496 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3497 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3498 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3499 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3500 install_element (RMAP_NODE, &set_originator_id_cmd);
3501 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3502 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3503
3504#ifdef HAVE_IPV6
3505 route_map_install_match (&route_match_ipv6_address_cmd);
3506 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3507 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3508 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3509 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
3510
3511 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3512 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3513 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3514 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3515 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3516 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3517 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3518 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3519 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3520 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3521 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3522 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3523#endif /* HAVE_IPV6 */
3524}