blob: 6a44c479615859ac93f0f07583a074f675566dec [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
hassoc1643bb2005-02-02 16:43:17 +000060 ip route-source : Done
paul718e3742002-12-13 20:15:29 +000061 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. */
paul94f2b392005-06-28 12:44:16 +0000103static route_map_result_t
paulfee0f4c2004-09-13 05:12:46 +0000104route_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;
paul1eb8ef22005-04-07 07:30:20 +0000111 struct listnode *node, *nnode;
paulfee0f4c2004-09-13 05:12:46 +0000112
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 {
paul22db9de2005-05-19 01:50:11 +0000127 int ret;
paulfee0f4c2004-09-13 05:12:46 +0000128 if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
129 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE) ||
130 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
paul22db9de2005-05-19 01:50:11 +0000131 ret = RMAP_MATCH;
paulfee0f4c2004-09-13 05:12:46 +0000132 else
paul22db9de2005-05-19 01:50:11 +0000133 ret = RMAP_NOMATCH;
134
135 sockunion_free (su2);
136 return ret;
paulfee0f4c2004-09-13 05:12:46 +0000137 }
paul22db9de2005-05-19 01:50:11 +0000138 sockunion_free (su2);
139
paulfee0f4c2004-09-13 05:12:46 +0000140 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;
paul1eb8ef22005-04-07 07:30:20 +0000150 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
paulfee0f4c2004-09-13 05:12:46 +0000151 {
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
paul94f2b392005-06-28 12:44:16 +0000162static void *
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. */
paul94f2b392005-06-28 12:44:16 +0000180static void
paulfee0f4c2004-09-13 05:12:46 +0000181route_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. */
paul94f2b392005-06-28 12:44:16 +0000199static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000200route_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. */
paul94f2b392005-06-28 12:44:16 +0000220static void *
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. */
paul94f2b392005-06-28 12:44:16 +0000227static void
paul718e3742002-12-13 20:15:29 +0000228route_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. */
paul94f2b392005-06-28 12:44:16 +0000245static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000246route_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. */
paul94f2b392005-06-28 12:44:16 +0000272static void *
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. */
paul94f2b392005-06-28 12:44:16 +0000279static void
paul718e3742002-12-13 20:15:29 +0000280route_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
hassoc1643bb2005-02-02 16:43:17 +0000294/* `match ip route-source ACCESS-LIST' */
295
296/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000297static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000298route_match_ip_route_source (void *rule, struct prefix *prefix,
299 route_map_object_t type, void *object)
300{
301 struct access_list *alist;
302 struct bgp_info *bgp_info;
303 struct peer *peer;
304 struct prefix_ipv4 p;
305
306 if (type == RMAP_BGP)
307 {
308 bgp_info = object;
309 peer = bgp_info->peer;
310
311 if (! peer || sockunion_family (&peer->su) != AF_INET)
312 return RMAP_NOMATCH;
313
314 p.family = AF_INET;
315 p.prefix = peer->su.sin.sin_addr;
316 p.prefixlen = IPV4_MAX_BITLEN;
317
318 alist = access_list_lookup (AFI_IP, (char *) rule);
319 if (alist == NULL)
320 return RMAP_NOMATCH;
321
322 return (access_list_apply (alist, &p) == FILTER_DENY ?
323 RMAP_NOMATCH : RMAP_MATCH);
324 }
325 return RMAP_NOMATCH;
326}
327
328/* Route map `ip route-source' match statement. `arg' is
329 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000330static void *
hassoc1643bb2005-02-02 16:43:17 +0000331route_match_ip_route_source_compile (const char *arg)
332{
333 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
334}
335
336/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000337static void
hassoc1643bb2005-02-02 16:43:17 +0000338route_match_ip_route_source_free (void *rule)
339{
340 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
341}
342
343/* Route map commands for ip route-source matching. */
344struct route_map_rule_cmd route_match_ip_route_source_cmd =
345{
346 "ip route-source",
347 route_match_ip_route_source,
348 route_match_ip_route_source_compile,
349 route_match_ip_route_source_free
350};
351
paul718e3742002-12-13 20:15:29 +0000352/* `match ip address prefix-list PREFIX_LIST' */
353
paul94f2b392005-06-28 12:44:16 +0000354static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000355route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
356 route_map_object_t type, void *object)
357{
358 struct prefix_list *plist;
359
360 if (type == RMAP_BGP)
361 {
362 plist = prefix_list_lookup (AFI_IP, (char *) rule);
363 if (plist == NULL)
364 return RMAP_NOMATCH;
365
366 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
367 RMAP_NOMATCH : RMAP_MATCH);
368 }
369 return RMAP_NOMATCH;
370}
371
paul94f2b392005-06-28 12:44:16 +0000372static void *
paulfd79ac92004-10-13 05:06:08 +0000373route_match_ip_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000374{
375 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
376}
377
paul94f2b392005-06-28 12:44:16 +0000378static void
paul718e3742002-12-13 20:15:29 +0000379route_match_ip_address_prefix_list_free (void *rule)
380{
381 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
382}
383
384struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
385{
386 "ip address prefix-list",
387 route_match_ip_address_prefix_list,
388 route_match_ip_address_prefix_list_compile,
389 route_match_ip_address_prefix_list_free
390};
391
392/* `match ip next-hop prefix-list PREFIX_LIST' */
393
paul94f2b392005-06-28 12:44:16 +0000394static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000395route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
396 route_map_object_t type, void *object)
397{
398 struct prefix_list *plist;
399 struct bgp_info *bgp_info;
400 struct prefix_ipv4 p;
401
402 if (type == RMAP_BGP)
403 {
404 bgp_info = object;
405 p.family = AF_INET;
406 p.prefix = bgp_info->attr->nexthop;
407 p.prefixlen = IPV4_MAX_BITLEN;
408
409 plist = prefix_list_lookup (AFI_IP, (char *) rule);
410 if (plist == NULL)
411 return RMAP_NOMATCH;
412
413 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
414 RMAP_NOMATCH : RMAP_MATCH);
415 }
416 return RMAP_NOMATCH;
417}
418
paul94f2b392005-06-28 12:44:16 +0000419static void *
paulfd79ac92004-10-13 05:06:08 +0000420route_match_ip_next_hop_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000421{
422 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
423}
424
paul94f2b392005-06-28 12:44:16 +0000425static void
paul718e3742002-12-13 20:15:29 +0000426route_match_ip_next_hop_prefix_list_free (void *rule)
427{
428 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
429}
430
431struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
432{
433 "ip next-hop prefix-list",
434 route_match_ip_next_hop_prefix_list,
435 route_match_ip_next_hop_prefix_list_compile,
436 route_match_ip_next_hop_prefix_list_free
437};
438
hassoc1643bb2005-02-02 16:43:17 +0000439/* `match ip route-source prefix-list PREFIX_LIST' */
440
paul94f2b392005-06-28 12:44:16 +0000441static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000442route_match_ip_route_source_prefix_list (void *rule, struct prefix *prefix,
443 route_map_object_t type, void *object)
444{
445 struct prefix_list *plist;
446 struct bgp_info *bgp_info;
447 struct peer *peer;
448 struct prefix_ipv4 p;
449
450 if (type == RMAP_BGP)
451 {
452 bgp_info = object;
453 peer = bgp_info->peer;
454
455 if (! peer || sockunion_family (&peer->su) != AF_INET)
456 return RMAP_NOMATCH;
457
458 p.family = AF_INET;
459 p.prefix = peer->su.sin.sin_addr;
460 p.prefixlen = IPV4_MAX_BITLEN;
461
462 plist = prefix_list_lookup (AFI_IP, (char *) rule);
463 if (plist == NULL)
464 return RMAP_NOMATCH;
465
466 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
467 RMAP_NOMATCH : RMAP_MATCH);
468 }
469 return RMAP_NOMATCH;
470}
471
paul94f2b392005-06-28 12:44:16 +0000472static void *
hassoc1643bb2005-02-02 16:43:17 +0000473route_match_ip_route_source_prefix_list_compile (const char *arg)
474{
475 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
476}
477
paul94f2b392005-06-28 12:44:16 +0000478static void
hassoc1643bb2005-02-02 16:43:17 +0000479route_match_ip_route_source_prefix_list_free (void *rule)
480{
481 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
482}
483
484struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd =
485{
486 "ip route-source prefix-list",
487 route_match_ip_route_source_prefix_list,
488 route_match_ip_route_source_prefix_list_compile,
489 route_match_ip_route_source_prefix_list_free
490};
491
paul718e3742002-12-13 20:15:29 +0000492/* `match metric METRIC' */
493
494/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000495static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000496route_match_metric (void *rule, struct prefix *prefix,
497 route_map_object_t type, void *object)
498{
499 u_int32_t *med;
500 struct bgp_info *bgp_info;
501
502 if (type == RMAP_BGP)
503 {
504 med = rule;
505 bgp_info = object;
506
507 if (bgp_info->attr->med == *med)
508 return RMAP_MATCH;
509 else
510 return RMAP_NOMATCH;
511 }
512 return RMAP_NOMATCH;
513}
514
515/* Route map `match metric' match statement. `arg' is MED value */
paul94f2b392005-06-28 12:44:16 +0000516static void *
paulfd79ac92004-10-13 05:06:08 +0000517route_match_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000518{
519 u_int32_t *med;
520 char *endptr = NULL;
paul3b424972003-10-13 09:47:32 +0000521 unsigned long tmpval;
paul718e3742002-12-13 20:15:29 +0000522
paul3b424972003-10-13 09:47:32 +0000523 tmpval = strtoul (arg, &endptr, 10);
paulfd79ac92004-10-13 05:06:08 +0000524 if (*endptr != '\0' || tmpval == ULONG_MAX || tmpval > UINT32_MAX)
paul3b424972003-10-13 09:47:32 +0000525 return NULL;
paulfd79ac92004-10-13 05:06:08 +0000526
paul718e3742002-12-13 20:15:29 +0000527 med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +0000528
529 if (!med)
530 return med;
531
paul3b424972003-10-13 09:47:32 +0000532 *med = tmpval;
paul718e3742002-12-13 20:15:29 +0000533 return med;
534}
535
536/* Free route map's compiled `match metric' value. */
paul94f2b392005-06-28 12:44:16 +0000537static void
paul718e3742002-12-13 20:15:29 +0000538route_match_metric_free (void *rule)
539{
540 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
541}
542
543/* Route map commands for metric matching. */
544struct route_map_rule_cmd route_match_metric_cmd =
545{
546 "metric",
547 route_match_metric,
548 route_match_metric_compile,
549 route_match_metric_free
550};
551
552/* `match as-path ASPATH' */
553
554/* Match function for as-path match. I assume given object is */
paul94f2b392005-06-28 12:44:16 +0000555static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000556route_match_aspath (void *rule, struct prefix *prefix,
557 route_map_object_t type, void *object)
558{
559
560 struct as_list *as_list;
561 struct bgp_info *bgp_info;
562
563 if (type == RMAP_BGP)
564 {
565 as_list = as_list_lookup ((char *) rule);
566 if (as_list == NULL)
567 return RMAP_NOMATCH;
568
569 bgp_info = object;
570
571 /* Perform match. */
572 return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
573 }
574 return RMAP_NOMATCH;
575}
576
577/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000578static void *
paulfd79ac92004-10-13 05:06:08 +0000579route_match_aspath_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000580{
581 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
582}
583
584/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000585static void
paul718e3742002-12-13 20:15:29 +0000586route_match_aspath_free (void *rule)
587{
588 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
589}
590
591/* Route map commands for aspath matching. */
592struct route_map_rule_cmd route_match_aspath_cmd =
593{
594 "as-path",
595 route_match_aspath,
596 route_match_aspath_compile,
597 route_match_aspath_free
598};
paul718e3742002-12-13 20:15:29 +0000599
600/* `match community COMMUNIY' */
601struct rmap_community
602{
603 char *name;
604 int exact;
605};
606
607/* Match function for community match. */
paul94f2b392005-06-28 12:44:16 +0000608static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000609route_match_community (void *rule, struct prefix *prefix,
610 route_map_object_t type, void *object)
611{
612 struct community_list *list;
613 struct bgp_info *bgp_info;
614 struct rmap_community *rcom;
615
616 if (type == RMAP_BGP)
617 {
618 bgp_info = object;
619 rcom = rule;
620
hassofee6e4e2005-02-02 16:29:31 +0000621 list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +0000622 if (! list)
623 return RMAP_NOMATCH;
624
625 if (rcom->exact)
626 {
627 if (community_list_exact_match (bgp_info->attr->community, list))
628 return RMAP_MATCH;
629 }
630 else
631 {
632 if (community_list_match (bgp_info->attr->community, list))
633 return RMAP_MATCH;
634 }
635 }
636 return RMAP_NOMATCH;
637}
638
639/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000640static void *
paulfd79ac92004-10-13 05:06:08 +0000641route_match_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000642{
643 struct rmap_community *rcom;
644 int len;
645 char *p;
646
647 rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
648
649 p = strchr (arg, ' ');
650 if (p)
651 {
652 len = p - arg;
653 rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
654 memcpy (rcom->name, arg, len);
655 rcom->exact = 1;
656 }
657 else
658 {
659 rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
660 rcom->exact = 0;
661 }
662 return rcom;
663}
664
665/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000666static void
paul718e3742002-12-13 20:15:29 +0000667route_match_community_free (void *rule)
668{
669 struct rmap_community *rcom = rule;
670
671 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
672 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
673}
674
675/* Route map commands for community matching. */
676struct route_map_rule_cmd route_match_community_cmd =
677{
678 "community",
679 route_match_community,
680 route_match_community_compile,
681 route_match_community_free
682};
683
paul73ffb252003-04-19 15:49:49 +0000684/* Match function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000685static route_map_result_t
paul73ffb252003-04-19 15:49:49 +0000686route_match_ecommunity (void *rule, struct prefix *prefix,
687 route_map_object_t type, void *object)
688{
689 struct community_list *list;
690 struct bgp_info *bgp_info;
691
692 if (type == RMAP_BGP)
693 {
694 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +0000695
696 if (!bgp_info->attr->extra)
697 return RMAP_NOMATCH;
698
paul73ffb252003-04-19 15:49:49 +0000699 list = community_list_lookup (bgp_clist, (char *) rule,
hassofee6e4e2005-02-02 16:29:31 +0000700 EXTCOMMUNITY_LIST_MASTER);
paul73ffb252003-04-19 15:49:49 +0000701 if (! list)
702 return RMAP_NOMATCH;
703
Paul Jakmafb982c22007-05-04 20:15:47 +0000704 if (ecommunity_list_match (bgp_info->attr->extra->ecommunity, list))
paul73ffb252003-04-19 15:49:49 +0000705 return RMAP_MATCH;
706 }
707 return RMAP_NOMATCH;
708}
709
710/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000711static void *
paulfd79ac92004-10-13 05:06:08 +0000712route_match_ecommunity_compile (const char *arg)
paul73ffb252003-04-19 15:49:49 +0000713{
714 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
715}
716
717/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000718static void
paul73ffb252003-04-19 15:49:49 +0000719route_match_ecommunity_free (void *rule)
720{
721 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
722}
723
724/* Route map commands for community matching. */
725struct route_map_rule_cmd route_match_ecommunity_cmd =
726{
727 "extcommunity",
728 route_match_ecommunity,
729 route_match_ecommunity_compile,
730 route_match_ecommunity_free
731};
732
paul718e3742002-12-13 20:15:29 +0000733/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
734 and `address-family vpnv4'. */
735
736/* `match origin' */
paul94f2b392005-06-28 12:44:16 +0000737static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000738route_match_origin (void *rule, struct prefix *prefix,
739 route_map_object_t type, void *object)
740{
741 u_char *origin;
742 struct bgp_info *bgp_info;
743
744 if (type == RMAP_BGP)
745 {
746 origin = rule;
747 bgp_info = object;
748
749 if (bgp_info->attr->origin == *origin)
750 return RMAP_MATCH;
751 }
752
753 return RMAP_NOMATCH;
754}
755
paul94f2b392005-06-28 12:44:16 +0000756static void *
paulfd79ac92004-10-13 05:06:08 +0000757route_match_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000758{
759 u_char *origin;
760
761 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
762
763 if (strcmp (arg, "igp") == 0)
764 *origin = 0;
765 else if (strcmp (arg, "egp") == 0)
766 *origin = 1;
767 else
768 *origin = 2;
769
770 return origin;
771}
772
773/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000774static void
paul718e3742002-12-13 20:15:29 +0000775route_match_origin_free (void *rule)
776{
777 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
778}
779
780/* Route map commands for origin matching. */
781struct route_map_rule_cmd route_match_origin_cmd =
782{
783 "origin",
784 route_match_origin,
785 route_match_origin_compile,
786 route_match_origin_free
787};
788/* `set ip next-hop IP_ADDRESS' */
789
790/* Set nexthop to object. ojbect must be pointer to struct attr. */
paulac41b2a2003-08-12 05:32:27 +0000791struct rmap_ip_nexthop_set
792{
793 struct in_addr *address;
794 int peer_address;
795};
796
paul94f2b392005-06-28 12:44:16 +0000797static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000798route_set_ip_nexthop (void *rule, struct prefix *prefix,
799 route_map_object_t type, void *object)
800{
paulac41b2a2003-08-12 05:32:27 +0000801 struct rmap_ip_nexthop_set *rins = rule;
802 struct in_addr peer_address;
paul718e3742002-12-13 20:15:29 +0000803 struct bgp_info *bgp_info;
paulac41b2a2003-08-12 05:32:27 +0000804 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000805
806 if (type == RMAP_BGP)
807 {
paul718e3742002-12-13 20:15:29 +0000808 bgp_info = object;
paulac41b2a2003-08-12 05:32:27 +0000809 peer = bgp_info->peer;
810
811 if (rins->peer_address)
812 {
paulfee0f4c2004-09-13 05:12:46 +0000813 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
814 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
paulac41b2a2003-08-12 05:32:27 +0000815 && peer->su_remote
816 && sockunion_family (peer->su_remote) == AF_INET)
817 {
818 inet_aton (sockunion_su2str (peer->su_remote), &peer_address);
819 bgp_info->attr->nexthop = peer_address;
820 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
821 }
822 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
823 && peer->su_local
824 && sockunion_family (peer->su_local) == AF_INET)
825 {
826 inet_aton (sockunion_su2str (peer->su_local), &peer_address);
827 bgp_info->attr->nexthop = peer_address;
828 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
829 }
830 }
831 else
832 {
833 /* Set next hop value. */
834 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
835 bgp_info->attr->nexthop = *rins->address;
836 }
paul718e3742002-12-13 20:15:29 +0000837 }
838
839 return RMAP_OKAY;
840}
841
842/* Route map `ip nexthop' compile function. Given string is converted
843 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +0000844static void *
paulfd79ac92004-10-13 05:06:08 +0000845route_set_ip_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000846{
paulac41b2a2003-08-12 05:32:27 +0000847 struct rmap_ip_nexthop_set *rins;
848 struct in_addr *address = NULL;
849 int peer_address = 0;
paul718e3742002-12-13 20:15:29 +0000850 int ret;
paul718e3742002-12-13 20:15:29 +0000851
paulac41b2a2003-08-12 05:32:27 +0000852 if (strcmp (arg, "peer-address") == 0)
853 peer_address = 1;
854 else
paul718e3742002-12-13 20:15:29 +0000855 {
paulac41b2a2003-08-12 05:32:27 +0000856 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
857 ret = inet_aton (arg, address);
858
859 if (ret == 0)
860 {
861 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
862 return NULL;
863 }
paul718e3742002-12-13 20:15:29 +0000864 }
865
paulac41b2a2003-08-12 05:32:27 +0000866 rins = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
867 memset (rins, 0, sizeof (struct rmap_ip_nexthop_set));
868
869 rins->address = address;
870 rins->peer_address = peer_address;
871
872 return rins;
paul718e3742002-12-13 20:15:29 +0000873}
874
875/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +0000876static void
paul718e3742002-12-13 20:15:29 +0000877route_set_ip_nexthop_free (void *rule)
878{
paulac41b2a2003-08-12 05:32:27 +0000879 struct rmap_ip_nexthop_set *rins = rule;
880
881 if (rins->address)
882 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
883
884 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +0000885}
886
887/* Route map commands for ip nexthop set. */
888struct route_map_rule_cmd route_set_ip_nexthop_cmd =
889{
890 "ip next-hop",
891 route_set_ip_nexthop,
892 route_set_ip_nexthop_compile,
893 route_set_ip_nexthop_free
894};
895
896/* `set local-preference LOCAL_PREF' */
897
898/* Set local preference. */
paul94f2b392005-06-28 12:44:16 +0000899static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000900route_set_local_pref (void *rule, struct prefix *prefix,
901 route_map_object_t type, void *object)
902{
903 u_int32_t *local_pref;
904 struct bgp_info *bgp_info;
905
906 if (type == RMAP_BGP)
907 {
908 /* Fetch routemap's rule information. */
909 local_pref = rule;
910 bgp_info = object;
911
912 /* Set local preference value. */
913 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
914 bgp_info->attr->local_pref = *local_pref;
915 }
916
917 return RMAP_OKAY;
918}
919
920/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +0000921static void *
paulfd79ac92004-10-13 05:06:08 +0000922route_set_local_pref_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 *local_pref;
926 char *endptr = NULL;
927
928 /* Local preference value shoud be integer. */
929 if (! all_digit (arg))
930 return NULL;
paulfd79ac92004-10-13 05:06:08 +0000931
932 tmp = strtoul (arg, &endptr, 10);
933 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
934 return NULL;
935
936 local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
937
938 if (!local_pref)
939 return local_pref;
940
941 *local_pref = tmp;
942
paul718e3742002-12-13 20:15:29 +0000943 return local_pref;
944}
945
946/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +0000947static void
paul718e3742002-12-13 20:15:29 +0000948route_set_local_pref_free (void *rule)
949{
950 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
951}
952
953/* Set local preference rule structure. */
954struct route_map_rule_cmd route_set_local_pref_cmd =
955{
956 "local-preference",
957 route_set_local_pref,
958 route_set_local_pref_compile,
959 route_set_local_pref_free,
960};
961
962/* `set weight WEIGHT' */
963
964/* Set weight. */
paul94f2b392005-06-28 12:44:16 +0000965static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000966route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
967 void *object)
968{
969 u_int32_t *weight;
970 struct bgp_info *bgp_info;
971
972 if (type == RMAP_BGP)
973 {
974 /* Fetch routemap's rule information. */
975 weight = rule;
976 bgp_info = object;
977
978 /* Set weight value. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000979 if (*weight)
980 (bgp_attr_extra_get (bgp_info->attr))->weight = *weight;
981 else if (bgp_info->attr->extra)
982 bgp_info->attr->extra->weight = 0;
paul718e3742002-12-13 20:15:29 +0000983 }
984
985 return RMAP_OKAY;
986}
987
988/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +0000989static void *
paulfd79ac92004-10-13 05:06:08 +0000990route_set_weight_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000991{
paulfd79ac92004-10-13 05:06:08 +0000992 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +0000993 u_int32_t *weight;
994 char *endptr = NULL;
995
996 /* Local preference value shoud be integer. */
997 if (! all_digit (arg))
998 return NULL;
999
paulfd79ac92004-10-13 05:06:08 +00001000
1001 tmp = strtoul (arg, &endptr, 10);
1002 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
1003 return NULL;
1004
paul718e3742002-12-13 20:15:29 +00001005 weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +00001006
1007 if (weight == NULL)
1008 return weight;
1009
1010 *weight = tmp;
1011
paul718e3742002-12-13 20:15:29 +00001012 return weight;
1013}
1014
1015/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +00001016static void
paul718e3742002-12-13 20:15:29 +00001017route_set_weight_free (void *rule)
1018{
1019 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1020}
1021
1022/* Set local preference rule structure. */
1023struct route_map_rule_cmd route_set_weight_cmd =
1024{
1025 "weight",
1026 route_set_weight,
1027 route_set_weight_compile,
1028 route_set_weight_free,
1029};
1030
1031/* `set metric METRIC' */
1032
1033/* Set metric to attribute. */
paul94f2b392005-06-28 12:44:16 +00001034static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001035route_set_metric (void *rule, struct prefix *prefix,
1036 route_map_object_t type, void *object)
1037{
1038 char *metric;
1039 u_int32_t metric_val;
1040 struct bgp_info *bgp_info;
1041
1042 if (type == RMAP_BGP)
1043 {
1044 /* Fetch routemap's rule information. */
1045 metric = rule;
1046 bgp_info = object;
1047
1048 if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
1049 bgp_info->attr->med = 0;
1050 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
1051
1052 if (all_digit (metric))
1053 {
1054 metric_val = strtoul (metric, (char **)NULL, 10);
1055 bgp_info->attr->med = metric_val;
1056 }
1057 else
1058 {
1059 metric_val = strtoul (metric+1, (char **)NULL, 10);
1060
1061 if (strncmp (metric, "+", 1) == 0)
1062 {
paul3b424972003-10-13 09:47:32 +00001063 if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2)
1064 bgp_info->attr->med = BGP_MED_MAX - 1;
paul718e3742002-12-13 20:15:29 +00001065 else
paul537d8ea2003-08-27 06:45:32 +00001066 bgp_info->attr->med += metric_val;
paul718e3742002-12-13 20:15:29 +00001067 }
1068 else if (strncmp (metric, "-", 1) == 0)
1069 {
paul537d8ea2003-08-27 06:45:32 +00001070 if (bgp_info->attr->med <= metric_val)
1071 bgp_info->attr->med = 0;
paul718e3742002-12-13 20:15:29 +00001072 else
paul537d8ea2003-08-27 06:45:32 +00001073 bgp_info->attr->med -= metric_val;
paul718e3742002-12-13 20:15:29 +00001074 }
1075 }
1076 }
1077 return RMAP_OKAY;
1078}
1079
1080/* set metric compilation. */
paul94f2b392005-06-28 12:44:16 +00001081static void *
paulfd79ac92004-10-13 05:06:08 +00001082route_set_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001083{
1084 u_int32_t metric;
paul94f2b392005-06-28 12:44:16 +00001085 unsigned long larg;
paul718e3742002-12-13 20:15:29 +00001086 char *endptr = NULL;
1087
1088 if (all_digit (arg))
1089 {
1090 /* set metric value check*/
paul94f2b392005-06-28 12:44:16 +00001091 larg = strtoul (arg, &endptr, 10);
1092 if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001093 return NULL;
paul94f2b392005-06-28 12:44:16 +00001094 metric = larg;
paul718e3742002-12-13 20:15:29 +00001095 }
1096 else
1097 {
1098 /* set metric +/-value check */
1099 if ((strncmp (arg, "+", 1) != 0
1100 && strncmp (arg, "-", 1) != 0)
1101 || (! all_digit (arg+1)))
1102 return NULL;
1103
paul94f2b392005-06-28 12:44:16 +00001104 larg = strtoul (arg+1, &endptr, 10);
1105 if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001106 return NULL;
paul94f2b392005-06-28 12:44:16 +00001107 metric = larg;
paul718e3742002-12-13 20:15:29 +00001108 }
1109
1110 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1111}
1112
1113/* Free route map's compiled `set metric' value. */
paul94f2b392005-06-28 12:44:16 +00001114static void
paul718e3742002-12-13 20:15:29 +00001115route_set_metric_free (void *rule)
1116{
1117 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1118}
1119
1120/* Set metric rule structure. */
1121struct route_map_rule_cmd route_set_metric_cmd =
1122{
1123 "metric",
1124 route_set_metric,
1125 route_set_metric_compile,
1126 route_set_metric_free,
1127};
1128
1129/* `set as-path prepend ASPATH' */
1130
1131/* For AS path prepend mechanism. */
paul94f2b392005-06-28 12:44:16 +00001132static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001133route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1134{
1135 struct aspath *aspath;
1136 struct aspath *new;
1137 struct bgp_info *binfo;
1138
1139 if (type == RMAP_BGP)
1140 {
1141 aspath = rule;
1142 binfo = object;
1143
1144 if (binfo->attr->aspath->refcnt)
1145 new = aspath_dup (binfo->attr->aspath);
1146 else
1147 new = binfo->attr->aspath;
1148
1149 aspath_prepend (aspath, new);
1150 binfo->attr->aspath = new;
1151 }
1152
1153 return RMAP_OKAY;
1154}
1155
1156/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001157static void *
paulfd79ac92004-10-13 05:06:08 +00001158route_set_aspath_prepend_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001159{
1160 struct aspath *aspath;
1161
1162 aspath = aspath_str2aspath (arg);
1163 if (! aspath)
1164 return NULL;
1165 return aspath;
1166}
1167
1168/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001169static void
paul718e3742002-12-13 20:15:29 +00001170route_set_aspath_prepend_free (void *rule)
1171{
1172 struct aspath *aspath = rule;
1173 aspath_free (aspath);
1174}
1175
1176/* Set metric rule structure. */
1177struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1178{
1179 "as-path prepend",
1180 route_set_aspath_prepend,
1181 route_set_aspath_prepend_compile,
1182 route_set_aspath_prepend_free,
1183};
1184
1185/* `set community COMMUNITY' */
1186struct rmap_com_set
1187{
1188 struct community *com;
1189 int additive;
1190 int none;
1191};
1192
1193/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001194static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001195route_set_community (void *rule, struct prefix *prefix,
1196 route_map_object_t type, void *object)
1197{
1198 struct rmap_com_set *rcs;
1199 struct bgp_info *binfo;
1200 struct attr *attr;
1201 struct community *new = NULL;
1202 struct community *old;
1203 struct community *merge;
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001204
paul718e3742002-12-13 20:15:29 +00001205 if (type == RMAP_BGP)
1206 {
1207 rcs = rule;
1208 binfo = object;
1209 attr = binfo->attr;
1210 old = attr->community;
1211
1212 /* "none" case. */
1213 if (rcs->none)
1214 {
1215 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1216 attr->community = NULL;
1217 return RMAP_OKAY;
1218 }
1219
1220 /* "additive" case. */
1221 if (rcs->additive && old)
1222 {
1223 merge = community_merge (community_dup (old), rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001224
1225 /* HACK: if the old community is not intern'd,
1226 * we should free it here, or all reference to it may be lost.
1227 * Really need to cleanup attribute caching sometime.
1228 */
1229 if (old->refcnt == 0)
1230 community_free (old);
paul718e3742002-12-13 20:15:29 +00001231 new = community_uniq_sort (merge);
1232 community_free (merge);
1233 }
1234 else
1235 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001236
1237 /* will be interned by caller if required */
paul718e3742002-12-13 20:15:29 +00001238 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001239
paul718e3742002-12-13 20:15:29 +00001240 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1241 }
1242
1243 return RMAP_OKAY;
1244}
1245
1246/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001247static void *
paulfd79ac92004-10-13 05:06:08 +00001248route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001249{
1250 struct rmap_com_set *rcs;
1251 struct community *com = NULL;
1252 char *sp;
1253 int additive = 0;
1254 int none = 0;
1255
1256 if (strcmp (arg, "none") == 0)
1257 none = 1;
1258 else
1259 {
1260 sp = strstr (arg, "additive");
1261
1262 if (sp && sp > arg)
1263 {
1264 /* "additive" keyworkd is included. */
1265 additive = 1;
1266 *(sp - 1) = '\0';
1267 }
1268
1269 com = community_str2com (arg);
1270
1271 if (additive)
1272 *(sp - 1) = ' ';
1273
1274 if (! com)
1275 return NULL;
1276 }
1277
1278 rcs = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
1279 memset (rcs, 0, sizeof (struct rmap_com_set));
1280
1281 rcs->com = com;
1282 rcs->additive = additive;
1283 rcs->none = none;
1284
1285 return rcs;
1286}
1287
1288/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001289static void
paul718e3742002-12-13 20:15:29 +00001290route_set_community_free (void *rule)
1291{
1292 struct rmap_com_set *rcs = rule;
1293
1294 if (rcs->com)
1295 community_free (rcs->com);
1296 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1297}
1298
1299/* Set community rule structure. */
1300struct route_map_rule_cmd route_set_community_cmd =
1301{
1302 "community",
1303 route_set_community,
1304 route_set_community_compile,
1305 route_set_community_free,
1306};
1307
hassofee6e4e2005-02-02 16:29:31 +00001308/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001309
1310/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001311static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001312route_set_community_delete (void *rule, struct prefix *prefix,
1313 route_map_object_t type, void *object)
1314{
1315 struct community_list *list;
1316 struct community *merge;
1317 struct community *new;
1318 struct community *old;
1319 struct bgp_info *binfo;
1320
1321 if (type == RMAP_BGP)
1322 {
1323 if (! rule)
1324 return RMAP_OKAY;
1325
1326 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001327 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001328 old = binfo->attr->community;
1329
1330 if (list && old)
1331 {
1332 merge = community_list_match_delete (community_dup (old), list);
1333 new = community_uniq_sort (merge);
1334 community_free (merge);
1335
1336 if (new->size == 0)
1337 {
1338 binfo->attr->community = NULL;
1339 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1340 community_free (new);
1341 }
1342 else
1343 {
1344 binfo->attr->community = new;
1345 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1346 }
1347 }
1348 }
1349
1350 return RMAP_OKAY;
1351}
1352
1353/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001354static void *
paulfd79ac92004-10-13 05:06:08 +00001355route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001356{
1357 char *p;
1358 char *str;
1359 int len;
1360
1361 p = strchr (arg, ' ');
1362 if (p)
1363 {
1364 len = p - arg;
1365 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1366 memcpy (str, arg, len);
1367 }
1368 else
1369 str = NULL;
1370
1371 return str;
1372}
1373
1374/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001375static void
paul718e3742002-12-13 20:15:29 +00001376route_set_community_delete_free (void *rule)
1377{
1378 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1379}
1380
1381/* Set community rule structure. */
1382struct route_map_rule_cmd route_set_community_delete_cmd =
1383{
1384 "comm-list",
1385 route_set_community_delete,
1386 route_set_community_delete_compile,
1387 route_set_community_delete_free,
1388};
1389
1390/* `set extcommunity rt COMMUNITY' */
1391
1392/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001393static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001394route_set_ecommunity_rt (void *rule, struct prefix *prefix,
1395 route_map_object_t type, void *object)
1396{
1397 struct ecommunity *ecom;
1398 struct ecommunity *new_ecom;
1399 struct ecommunity *old_ecom;
1400 struct bgp_info *bgp_info;
1401
1402 if (type == RMAP_BGP)
1403 {
1404 ecom = rule;
1405 bgp_info = object;
1406
1407 if (! ecom)
1408 return RMAP_OKAY;
1409
1410 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001411 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001412
1413 if (old_ecom)
1414 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1415 else
1416 new_ecom = ecommunity_dup (ecom);
1417
Paul Jakmafb982c22007-05-04 20:15:47 +00001418 bgp_info->attr->extra->ecommunity = new_ecom;
paul718e3742002-12-13 20:15:29 +00001419
hasso70601e02005-05-27 03:26:57 +00001420 if (old_ecom)
1421 ecommunity_free (old_ecom);
1422
paul718e3742002-12-13 20:15:29 +00001423 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1424 }
1425 return RMAP_OKAY;
1426}
1427
1428/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001429static void *
paulfd79ac92004-10-13 05:06:08 +00001430route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001431{
1432 struct ecommunity *ecom;
1433
1434 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1435 if (! ecom)
1436 return NULL;
1437 return ecom;
1438}
1439
1440/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001441static void
paul718e3742002-12-13 20:15:29 +00001442route_set_ecommunity_rt_free (void *rule)
1443{
1444 struct ecommunity *ecom = rule;
1445 ecommunity_free (ecom);
1446}
1447
1448/* Set community rule structure. */
1449struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1450{
1451 "extcommunity rt",
1452 route_set_ecommunity_rt,
1453 route_set_ecommunity_rt_compile,
1454 route_set_ecommunity_rt_free,
1455};
1456
1457/* `set extcommunity soo COMMUNITY' */
1458
1459/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001460static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001461route_set_ecommunity_soo (void *rule, struct prefix *prefix,
1462 route_map_object_t type, void *object)
1463{
1464 struct ecommunity *ecom;
1465 struct bgp_info *bgp_info;
1466
1467 if (type == RMAP_BGP)
1468 {
1469 ecom = rule;
1470 bgp_info = object;
1471
1472 if (! ecom)
1473 return RMAP_OKAY;
1474
1475 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
Paul Jakmafb982c22007-05-04 20:15:47 +00001476 (bgp_attr_extra_get (bgp_info->attr))->ecommunity = ecommunity_dup (ecom);
paul718e3742002-12-13 20:15:29 +00001477 }
1478 return RMAP_OKAY;
1479}
1480
1481/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001482static void *
paulfd79ac92004-10-13 05:06:08 +00001483route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001484{
1485 struct ecommunity *ecom;
1486
1487 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1488 if (! ecom)
1489 return NULL;
1490
1491 return ecom;
1492}
1493
1494/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001495static void
paul718e3742002-12-13 20:15:29 +00001496route_set_ecommunity_soo_free (void *rule)
1497{
1498 struct ecommunity *ecom = rule;
1499 ecommunity_free (ecom);
1500}
1501
1502/* Set community rule structure. */
1503struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1504{
1505 "extcommunity soo",
1506 route_set_ecommunity_soo,
1507 route_set_ecommunity_soo_compile,
1508 route_set_ecommunity_soo_free,
1509};
1510
1511/* `set origin ORIGIN' */
1512
1513/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001514static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001515route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1516{
1517 u_char *origin;
1518 struct bgp_info *bgp_info;
1519
1520 if (type == RMAP_BGP)
1521 {
1522 origin = rule;
1523 bgp_info = object;
1524
1525 bgp_info->attr->origin = *origin;
1526 }
1527
1528 return RMAP_OKAY;
1529}
1530
1531/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001532static void *
paulfd79ac92004-10-13 05:06:08 +00001533route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001534{
1535 u_char *origin;
1536
1537 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1538
1539 if (strcmp (arg, "igp") == 0)
1540 *origin = 0;
1541 else if (strcmp (arg, "egp") == 0)
1542 *origin = 1;
1543 else
1544 *origin = 2;
1545
1546 return origin;
1547}
1548
1549/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001550static void
paul718e3742002-12-13 20:15:29 +00001551route_set_origin_free (void *rule)
1552{
1553 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1554}
1555
1556/* Set metric rule structure. */
1557struct route_map_rule_cmd route_set_origin_cmd =
1558{
1559 "origin",
1560 route_set_origin,
1561 route_set_origin_compile,
1562 route_set_origin_free,
1563};
1564
1565/* `set atomic-aggregate' */
1566
1567/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001568static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001569route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1570 route_map_object_t type, void *object)
1571{
1572 struct bgp_info *bgp_info;
1573
1574 if (type == RMAP_BGP)
1575 {
1576 bgp_info = object;
1577 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1578 }
1579
1580 return RMAP_OKAY;
1581}
1582
1583/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001584static void *
paulfd79ac92004-10-13 05:06:08 +00001585route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001586{
1587 return (void *)1;
1588}
1589
1590/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001591static void
paul718e3742002-12-13 20:15:29 +00001592route_set_atomic_aggregate_free (void *rule)
1593{
1594 return;
1595}
1596
1597/* Set atomic aggregate rule structure. */
1598struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1599{
1600 "atomic-aggregate",
1601 route_set_atomic_aggregate,
1602 route_set_atomic_aggregate_compile,
1603 route_set_atomic_aggregate_free,
1604};
1605
1606/* `set aggregator as AS A.B.C.D' */
1607struct aggregator
1608{
1609 as_t as;
1610 struct in_addr address;
1611};
1612
paul94f2b392005-06-28 12:44:16 +00001613static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001614route_set_aggregator_as (void *rule, struct prefix *prefix,
1615 route_map_object_t type, void *object)
1616{
1617 struct bgp_info *bgp_info;
1618 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001619 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001620
1621 if (type == RMAP_BGP)
1622 {
1623 bgp_info = object;
1624 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001625 ae = bgp_attr_extra_get (bgp_info->attr);
1626
1627 ae->aggregator_as = aggregator->as;
1628 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001629 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1630 }
1631
1632 return RMAP_OKAY;
1633}
1634
paul94f2b392005-06-28 12:44:16 +00001635static void *
paulfd79ac92004-10-13 05:06:08 +00001636route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001637{
1638 struct aggregator *aggregator;
1639 char as[10];
1640 char address[20];
1641
1642 aggregator = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
1643 memset (aggregator, 0, sizeof (struct aggregator));
1644
1645 sscanf (arg, "%s %s", as, address);
1646
1647 aggregator->as = strtoul (as, NULL, 10);
1648 inet_aton (address, &aggregator->address);
1649
1650 return aggregator;
1651}
1652
paul94f2b392005-06-28 12:44:16 +00001653static void
paul718e3742002-12-13 20:15:29 +00001654route_set_aggregator_as_free (void *rule)
1655{
1656 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1657}
1658
1659struct route_map_rule_cmd route_set_aggregator_as_cmd =
1660{
1661 "aggregator as",
1662 route_set_aggregator_as,
1663 route_set_aggregator_as_compile,
1664 route_set_aggregator_as_free,
1665};
1666
1667#ifdef HAVE_IPV6
1668/* `match ipv6 address IP_ACCESS_LIST' */
1669
paul94f2b392005-06-28 12:44:16 +00001670static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001671route_match_ipv6_address (void *rule, struct prefix *prefix,
1672 route_map_object_t type, void *object)
1673{
1674 struct access_list *alist;
1675
1676 if (type == RMAP_BGP)
1677 {
1678 alist = access_list_lookup (AFI_IP6, (char *) rule);
1679 if (alist == NULL)
1680 return RMAP_NOMATCH;
1681
1682 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1683 RMAP_NOMATCH : RMAP_MATCH);
1684 }
1685 return RMAP_NOMATCH;
1686}
1687
paul94f2b392005-06-28 12:44:16 +00001688static void *
paulfd79ac92004-10-13 05:06:08 +00001689route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001690{
1691 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1692}
1693
paul94f2b392005-06-28 12:44:16 +00001694static void
paul718e3742002-12-13 20:15:29 +00001695route_match_ipv6_address_free (void *rule)
1696{
1697 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1698}
1699
1700/* Route map commands for ip address matching. */
1701struct route_map_rule_cmd route_match_ipv6_address_cmd =
1702{
1703 "ipv6 address",
1704 route_match_ipv6_address,
1705 route_match_ipv6_address_compile,
1706 route_match_ipv6_address_free
1707};
1708
1709/* `match ipv6 next-hop IP_ADDRESS' */
1710
paul94f2b392005-06-28 12:44:16 +00001711static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001712route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1713 route_map_object_t type, void *object)
1714{
1715 struct in6_addr *addr;
1716 struct bgp_info *bgp_info;
1717
1718 if (type == RMAP_BGP)
1719 {
1720 addr = rule;
1721 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001722
1723 if (!bgp_info->attr->extra)
1724 return RMAP_NOMATCH;
1725
1726 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, rule))
paul718e3742002-12-13 20:15:29 +00001727 return RMAP_MATCH;
1728
Paul Jakmafb982c22007-05-04 20:15:47 +00001729 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
1730 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, rule))
paul718e3742002-12-13 20:15:29 +00001731 return RMAP_MATCH;
1732
1733 return RMAP_NOMATCH;
1734 }
1735
1736 return RMAP_NOMATCH;
1737}
1738
paul94f2b392005-06-28 12:44:16 +00001739static void *
paulfd79ac92004-10-13 05:06:08 +00001740route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001741{
1742 struct in6_addr *address;
1743 int ret;
1744
1745 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1746
1747 ret = inet_pton (AF_INET6, arg, address);
1748 if (!ret)
1749 {
1750 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1751 return NULL;
1752 }
1753
1754 return address;
1755}
1756
paul94f2b392005-06-28 12:44:16 +00001757static void
paul718e3742002-12-13 20:15:29 +00001758route_match_ipv6_next_hop_free (void *rule)
1759{
1760 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1761}
1762
1763struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1764{
1765 "ipv6 next-hop",
1766 route_match_ipv6_next_hop,
1767 route_match_ipv6_next_hop_compile,
1768 route_match_ipv6_next_hop_free
1769};
1770
1771/* `match ipv6 address prefix-list PREFIX_LIST' */
1772
paul94f2b392005-06-28 12:44:16 +00001773static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001774route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1775 route_map_object_t type, void *object)
1776{
1777 struct prefix_list *plist;
1778
1779 if (type == RMAP_BGP)
1780 {
1781 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1782 if (plist == NULL)
1783 return RMAP_NOMATCH;
1784
1785 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1786 RMAP_NOMATCH : RMAP_MATCH);
1787 }
1788 return RMAP_NOMATCH;
1789}
1790
paul94f2b392005-06-28 12:44:16 +00001791static void *
paulfd79ac92004-10-13 05:06:08 +00001792route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001793{
1794 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1795}
1796
paul94f2b392005-06-28 12:44:16 +00001797static void
paul718e3742002-12-13 20:15:29 +00001798route_match_ipv6_address_prefix_list_free (void *rule)
1799{
1800 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1801}
1802
1803struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1804{
1805 "ipv6 address prefix-list",
1806 route_match_ipv6_address_prefix_list,
1807 route_match_ipv6_address_prefix_list_compile,
1808 route_match_ipv6_address_prefix_list_free
1809};
1810
1811/* `set ipv6 nexthop global IP_ADDRESS' */
1812
1813/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001814static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001815route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1816 route_map_object_t type, void *object)
1817{
1818 struct in6_addr *address;
1819 struct bgp_info *bgp_info;
1820
1821 if (type == RMAP_BGP)
1822 {
1823 /* Fetch routemap's rule information. */
1824 address = rule;
1825 bgp_info = object;
1826
1827 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001828 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00001829
1830 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001831 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1832 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00001833 }
1834
1835 return RMAP_OKAY;
1836}
1837
1838/* Route map `ip next-hop' compile function. Given string is converted
1839 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001840static void *
paulfd79ac92004-10-13 05:06:08 +00001841route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001842{
1843 int ret;
1844 struct in6_addr *address;
1845
1846 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1847
1848 ret = inet_pton (AF_INET6, arg, address);
1849
1850 if (ret == 0)
1851 {
1852 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1853 return NULL;
1854 }
1855
1856 return address;
1857}
1858
1859/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00001860static void
paul718e3742002-12-13 20:15:29 +00001861route_set_ipv6_nexthop_global_free (void *rule)
1862{
1863 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1864}
1865
1866/* Route map commands for ip nexthop set. */
1867struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
1868{
1869 "ipv6 next-hop global",
1870 route_set_ipv6_nexthop_global,
1871 route_set_ipv6_nexthop_global_compile,
1872 route_set_ipv6_nexthop_global_free
1873};
1874
1875/* `set ipv6 nexthop local IP_ADDRESS' */
1876
1877/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001878static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001879route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
1880 route_map_object_t type, void *object)
1881{
1882 struct in6_addr *address;
1883 struct bgp_info *bgp_info;
1884
1885 if (type == RMAP_BGP)
1886 {
1887 /* Fetch routemap's rule information. */
1888 address = rule;
1889 bgp_info = object;
1890
1891 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001892 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00001893
1894 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001895 if (bgp_info->attr->extra->mp_nexthop_len != 32)
1896 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00001897 }
1898
1899 return RMAP_OKAY;
1900}
1901
1902/* Route map `ip nexthop' compile function. Given string is converted
1903 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001904static void *
paulfd79ac92004-10-13 05:06:08 +00001905route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001906{
1907 int ret;
1908 struct in6_addr *address;
1909
1910 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1911
1912 ret = inet_pton (AF_INET6, arg, address);
1913
1914 if (ret == 0)
1915 {
1916 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1917 return NULL;
1918 }
1919
1920 return address;
1921}
1922
1923/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00001924static void
paul718e3742002-12-13 20:15:29 +00001925route_set_ipv6_nexthop_local_free (void *rule)
1926{
1927 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1928}
1929
1930/* Route map commands for ip nexthop set. */
1931struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
1932{
1933 "ipv6 next-hop local",
1934 route_set_ipv6_nexthop_local,
1935 route_set_ipv6_nexthop_local_compile,
1936 route_set_ipv6_nexthop_local_free
1937};
1938#endif /* HAVE_IPV6 */
1939
1940/* `set vpnv4 nexthop A.B.C.D' */
1941
paul94f2b392005-06-28 12:44:16 +00001942static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001943route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
1944 route_map_object_t type, void *object)
1945{
1946 struct in_addr *address;
1947 struct bgp_info *bgp_info;
1948
1949 if (type == RMAP_BGP)
1950 {
1951 /* Fetch routemap's rule information. */
1952 address = rule;
1953 bgp_info = object;
1954
1955 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001956 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
paul718e3742002-12-13 20:15:29 +00001957 }
1958
1959 return RMAP_OKAY;
1960}
1961
paul94f2b392005-06-28 12:44:16 +00001962static void *
paulfd79ac92004-10-13 05:06:08 +00001963route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001964{
1965 int ret;
1966 struct in_addr *address;
1967
1968 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
1969
1970 ret = inet_aton (arg, address);
1971
1972 if (ret == 0)
1973 {
1974 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1975 return NULL;
1976 }
1977
1978 return address;
1979}
1980
paul94f2b392005-06-28 12:44:16 +00001981static void
paul718e3742002-12-13 20:15:29 +00001982route_set_vpnv4_nexthop_free (void *rule)
1983{
1984 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1985}
1986
1987/* Route map commands for ip nexthop set. */
1988struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
1989{
1990 "vpnv4 next-hop",
1991 route_set_vpnv4_nexthop,
1992 route_set_vpnv4_nexthop_compile,
1993 route_set_vpnv4_nexthop_free
1994};
1995
1996/* `set originator-id' */
1997
1998/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001999static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002000route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2001{
2002 struct in_addr *address;
2003 struct bgp_info *bgp_info;
2004
2005 if (type == RMAP_BGP)
2006 {
2007 address = rule;
2008 bgp_info = object;
2009
2010 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002011 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002012 }
2013
2014 return RMAP_OKAY;
2015}
2016
2017/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002018static void *
paulfd79ac92004-10-13 05:06:08 +00002019route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002020{
2021 int ret;
2022 struct in_addr *address;
2023
2024 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2025
2026 ret = inet_aton (arg, address);
2027
2028 if (ret == 0)
2029 {
2030 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2031 return NULL;
2032 }
2033
2034 return address;
2035}
2036
2037/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002038static void
paul718e3742002-12-13 20:15:29 +00002039route_set_originator_id_free (void *rule)
2040{
2041 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2042}
2043
2044/* Set metric rule structure. */
2045struct route_map_rule_cmd route_set_originator_id_cmd =
2046{
2047 "originator-id",
2048 route_set_originator_id,
2049 route_set_originator_id_compile,
2050 route_set_originator_id_free,
2051};
2052
2053/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002054static int
paul718e3742002-12-13 20:15:29 +00002055bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002056 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002057{
2058 int ret;
2059
2060 ret = route_map_add_match (index, command, arg);
2061 if (ret)
2062 {
2063 switch (ret)
2064 {
2065 case RMAP_RULE_MISSING:
2066 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2067 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002068 case RMAP_COMPILE_ERROR:
2069 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2070 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002071 }
2072 }
2073 return CMD_SUCCESS;
2074}
2075
2076/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002077static int
paul718e3742002-12-13 20:15:29 +00002078bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002079 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002080{
2081 int ret;
2082
2083 ret = route_map_delete_match (index, command, arg);
2084 if (ret)
2085 {
2086 switch (ret)
2087 {
2088 case RMAP_RULE_MISSING:
2089 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2090 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002091 case RMAP_COMPILE_ERROR:
2092 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2093 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002094 }
2095 }
2096 return CMD_SUCCESS;
2097}
2098
2099/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002100static int
paul718e3742002-12-13 20:15:29 +00002101bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002102 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002103{
2104 int ret;
2105
2106 ret = route_map_add_set (index, command, arg);
2107 if (ret)
2108 {
2109 switch (ret)
2110 {
2111 case RMAP_RULE_MISSING:
2112 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2113 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002114 case RMAP_COMPILE_ERROR:
2115 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2116 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002117 }
2118 }
2119 return CMD_SUCCESS;
2120}
2121
2122/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002123static int
paul718e3742002-12-13 20:15:29 +00002124bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002125 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002126{
2127 int ret;
2128
2129 ret = route_map_delete_set (index, command, arg);
2130 if (ret)
2131 {
2132 switch (ret)
2133 {
2134 case RMAP_RULE_MISSING:
2135 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2136 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002137 case RMAP_COMPILE_ERROR:
2138 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2139 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002140 }
2141 }
2142 return CMD_SUCCESS;
2143}
2144
2145/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002146static void
paulfd79ac92004-10-13 05:06:08 +00002147bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002148{
2149 int i;
2150 afi_t afi;
2151 safi_t safi;
2152 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002153 struct listnode *node, *nnode;
2154 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002155 struct bgp *bgp;
2156 struct peer *peer;
2157 struct peer_group *group;
2158 struct bgp_filter *filter;
2159 struct bgp_node *bn;
2160 struct bgp_static *bgp_static;
2161
2162 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002163 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002164 {
paul1eb8ef22005-04-07 07:30:20 +00002165 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002166 {
2167 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2168 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2169 {
2170 filter = &peer->filter[afi][safi];
2171
paulfee0f4c2004-09-13 05:12:46 +00002172 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002173 {
2174 if (filter->map[direct].name)
2175 filter->map[direct].map =
2176 route_map_lookup_by_name (filter->map[direct].name);
2177 else
2178 filter->map[direct].map = NULL;
2179 }
2180
2181 if (filter->usmap.name)
2182 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2183 else
2184 filter->usmap.map = NULL;
2185 }
2186 }
paul1eb8ef22005-04-07 07:30:20 +00002187 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002188 {
2189 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2190 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2191 {
2192 filter = &group->conf->filter[afi][safi];
2193
paulfee0f4c2004-09-13 05:12:46 +00002194 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002195 {
2196 if (filter->map[direct].name)
2197 filter->map[direct].map =
2198 route_map_lookup_by_name (filter->map[direct].name);
2199 else
2200 filter->map[direct].map = NULL;
2201 }
2202
2203 if (filter->usmap.name)
2204 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2205 else
2206 filter->usmap.map = NULL;
2207 }
2208 }
2209 }
2210
2211 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002212 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002213 {
paul1eb8ef22005-04-07 07:30:20 +00002214 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002215 {
2216 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2217 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2218 {
2219 if (peer->default_rmap[afi][safi].name)
2220 peer->default_rmap[afi][safi].map =
2221 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2222 else
2223 peer->default_rmap[afi][safi].map = NULL;
2224 }
2225 }
2226 }
2227
2228 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002229 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002230 {
2231 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2232 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2233 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2234 bn = bgp_route_next (bn))
2235 if ((bgp_static = bn->info) != NULL)
2236 {
2237 if (bgp_static->rmap.name)
2238 bgp_static->rmap.map =
2239 route_map_lookup_by_name (bgp_static->rmap.name);
2240 else
2241 bgp_static->rmap.map = NULL;
2242 }
2243 }
2244
2245 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002246 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002247 {
2248 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2249 {
2250 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2251 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2252 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2253#ifdef HAVE_IPV6
2254 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2255 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2256 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2257#endif /* HAVE_IPV6 */
2258 }
2259 }
2260}
2261
paulfee0f4c2004-09-13 05:12:46 +00002262DEFUN (match_peer,
2263 match_peer_cmd,
2264 "match peer (A.B.C.D|X:X::X:X)",
2265 MATCH_STR
2266 "Match peer address\n"
2267 "IPv6 address of peer\n"
2268 "IP address of peer\n")
2269{
2270 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2271}
2272
2273DEFUN (match_peer_local,
2274 match_peer_local_cmd,
2275 "match peer local",
2276 MATCH_STR
2277 "Match peer address\n"
2278 "Static or Redistributed routes\n")
2279{
2280 return bgp_route_match_add (vty, vty->index, "peer", NULL);
2281}
2282
2283DEFUN (no_match_peer,
2284 no_match_peer_cmd,
2285 "no match peer",
2286 NO_STR
2287 MATCH_STR
2288 "Match peer address\n")
2289{
2290 if (argc == 0)
2291 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2292
2293 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2294}
2295
2296ALIAS (no_match_peer,
2297 no_match_peer_val_cmd,
2298 "no match peer (A.B.C.D|X:X::X:X)",
2299 NO_STR
2300 MATCH_STR
2301 "Match peer address\n"
2302 "IPv6 address of peer\n"
2303 "IP address of peer\n")
2304
2305ALIAS (no_match_peer,
2306 no_match_peer_local_cmd,
2307 "no match peer local",
2308 NO_STR
2309 MATCH_STR
2310 "Match peer address\n"
2311 "Static or Redistributed routes\n")
2312
paul718e3742002-12-13 20:15:29 +00002313DEFUN (match_ip_address,
2314 match_ip_address_cmd,
2315 "match ip address (<1-199>|<1300-2699>|WORD)",
2316 MATCH_STR
2317 IP_STR
2318 "Match address of route\n"
2319 "IP access-list number\n"
2320 "IP access-list number (expanded range)\n"
2321 "IP Access-list name\n")
2322{
2323 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2324}
2325
2326DEFUN (no_match_ip_address,
2327 no_match_ip_address_cmd,
2328 "no match ip address",
2329 NO_STR
2330 MATCH_STR
2331 IP_STR
2332 "Match address of route\n")
2333{
2334 if (argc == 0)
2335 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2336
2337 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2338}
2339
2340ALIAS (no_match_ip_address,
2341 no_match_ip_address_val_cmd,
2342 "no match ip address (<1-199>|<1300-2699>|WORD)",
2343 NO_STR
2344 MATCH_STR
2345 IP_STR
2346 "Match address of route\n"
2347 "IP access-list number\n"
2348 "IP access-list number (expanded range)\n"
2349 "IP Access-list name\n")
2350
2351DEFUN (match_ip_next_hop,
2352 match_ip_next_hop_cmd,
2353 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2354 MATCH_STR
2355 IP_STR
2356 "Match next-hop address of route\n"
2357 "IP access-list number\n"
2358 "IP access-list number (expanded range)\n"
2359 "IP Access-list name\n")
2360{
2361 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2362}
2363
2364DEFUN (no_match_ip_next_hop,
2365 no_match_ip_next_hop_cmd,
2366 "no match ip next-hop",
2367 NO_STR
2368 MATCH_STR
2369 IP_STR
2370 "Match next-hop address of route\n")
2371{
2372 if (argc == 0)
2373 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2374
2375 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2376}
2377
2378ALIAS (no_match_ip_next_hop,
2379 no_match_ip_next_hop_val_cmd,
2380 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2381 NO_STR
2382 MATCH_STR
2383 IP_STR
2384 "Match next-hop address of route\n"
2385 "IP access-list number\n"
2386 "IP access-list number (expanded range)\n"
2387 "IP Access-list name\n")
2388
hassoc1643bb2005-02-02 16:43:17 +00002389DEFUN (match_ip_route_source,
2390 match_ip_route_source_cmd,
2391 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2392 MATCH_STR
2393 IP_STR
2394 "Match advertising source address of route\n"
2395 "IP access-list number\n"
2396 "IP access-list number (expanded range)\n"
2397 "IP standard access-list name\n")
2398{
2399 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2400}
2401
2402DEFUN (no_match_ip_route_source,
2403 no_match_ip_route_source_cmd,
2404 "no match ip route-source",
2405 NO_STR
2406 MATCH_STR
2407 IP_STR
2408 "Match advertising source address of route\n")
2409{
2410 if (argc == 0)
2411 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2412
2413 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2414}
2415
2416ALIAS (no_match_ip_route_source,
2417 no_match_ip_route_source_val_cmd,
2418 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2419 NO_STR
2420 MATCH_STR
2421 IP_STR
2422 "Match advertising source address of route\n"
2423 "IP access-list number\n"
2424 "IP access-list number (expanded range)\n"
2425 "IP standard access-list name\n");
2426
paul718e3742002-12-13 20:15:29 +00002427DEFUN (match_ip_address_prefix_list,
2428 match_ip_address_prefix_list_cmd,
2429 "match ip address prefix-list WORD",
2430 MATCH_STR
2431 IP_STR
2432 "Match address of route\n"
2433 "Match entries of prefix-lists\n"
2434 "IP prefix-list name\n")
2435{
2436 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2437}
2438
2439DEFUN (no_match_ip_address_prefix_list,
2440 no_match_ip_address_prefix_list_cmd,
2441 "no match ip address prefix-list",
2442 NO_STR
2443 MATCH_STR
2444 IP_STR
2445 "Match address of route\n"
2446 "Match entries of prefix-lists\n")
2447{
2448 if (argc == 0)
2449 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2450
2451 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2452}
2453
2454ALIAS (no_match_ip_address_prefix_list,
2455 no_match_ip_address_prefix_list_val_cmd,
2456 "no match ip address prefix-list WORD",
2457 NO_STR
2458 MATCH_STR
2459 IP_STR
2460 "Match address of route\n"
2461 "Match entries of prefix-lists\n"
2462 "IP prefix-list name\n")
2463
2464DEFUN (match_ip_next_hop_prefix_list,
2465 match_ip_next_hop_prefix_list_cmd,
2466 "match ip next-hop prefix-list WORD",
2467 MATCH_STR
2468 IP_STR
2469 "Match next-hop address of route\n"
2470 "Match entries of prefix-lists\n"
2471 "IP prefix-list name\n")
2472{
2473 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2474}
2475
2476DEFUN (no_match_ip_next_hop_prefix_list,
2477 no_match_ip_next_hop_prefix_list_cmd,
2478 "no match ip next-hop prefix-list",
2479 NO_STR
2480 MATCH_STR
2481 IP_STR
2482 "Match next-hop address of route\n"
2483 "Match entries of prefix-lists\n")
2484{
2485 if (argc == 0)
2486 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2487
2488 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2489}
2490
2491ALIAS (no_match_ip_next_hop_prefix_list,
2492 no_match_ip_next_hop_prefix_list_val_cmd,
2493 "no match ip next-hop prefix-list WORD",
2494 NO_STR
2495 MATCH_STR
2496 IP_STR
2497 "Match next-hop address of route\n"
2498 "Match entries of prefix-lists\n"
2499 "IP prefix-list name\n")
2500
hassoc1643bb2005-02-02 16:43:17 +00002501DEFUN (match_ip_route_source_prefix_list,
2502 match_ip_route_source_prefix_list_cmd,
2503 "match ip route-source prefix-list WORD",
2504 MATCH_STR
2505 IP_STR
2506 "Match advertising source address of route\n"
2507 "Match entries of prefix-lists\n"
2508 "IP prefix-list name\n")
2509{
2510 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2511}
2512
2513DEFUN (no_match_ip_route_source_prefix_list,
2514 no_match_ip_route_source_prefix_list_cmd,
2515 "no match ip route-source prefix-list",
2516 NO_STR
2517 MATCH_STR
2518 IP_STR
2519 "Match advertising source address of route\n"
2520 "Match entries of prefix-lists\n")
2521{
2522 if (argc == 0)
2523 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2524
2525 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2526}
2527
2528ALIAS (no_match_ip_route_source_prefix_list,
2529 no_match_ip_route_source_prefix_list_val_cmd,
2530 "no match ip route-source prefix-list WORD",
2531 NO_STR
2532 MATCH_STR
2533 IP_STR
2534 "Match advertising source address of route\n"
2535 "Match entries of prefix-lists\n"
2536 "IP prefix-list name\n");
2537
paul718e3742002-12-13 20:15:29 +00002538DEFUN (match_metric,
2539 match_metric_cmd,
2540 "match metric <0-4294967295>",
2541 MATCH_STR
2542 "Match metric of route\n"
2543 "Metric value\n")
2544{
2545 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2546}
2547
2548DEFUN (no_match_metric,
2549 no_match_metric_cmd,
2550 "no match metric",
2551 NO_STR
2552 MATCH_STR
2553 "Match metric of route\n")
2554{
2555 if (argc == 0)
2556 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2557
2558 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2559}
2560
2561ALIAS (no_match_metric,
2562 no_match_metric_val_cmd,
2563 "no match metric <0-4294967295>",
2564 NO_STR
2565 MATCH_STR
2566 "Match metric of route\n"
2567 "Metric value\n")
2568
2569DEFUN (match_community,
2570 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002571 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002572 MATCH_STR
2573 "Match BGP community list\n"
2574 "Community-list number (standard)\n"
2575 "Community-list number (expanded)\n"
2576 "Community-list name\n")
2577{
2578 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2579}
2580
2581DEFUN (match_community_exact,
2582 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002583 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002584 MATCH_STR
2585 "Match BGP community list\n"
2586 "Community-list number (standard)\n"
2587 "Community-list number (expanded)\n"
2588 "Community-list name\n"
2589 "Do exact matching of communities\n")
2590{
2591 int ret;
2592 char *argstr;
2593
2594 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2595 strlen (argv[0]) + strlen ("exact-match") + 2);
2596
2597 sprintf (argstr, "%s exact-match", argv[0]);
2598
2599 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2600
2601 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2602
2603 return ret;
2604}
2605
2606DEFUN (no_match_community,
2607 no_match_community_cmd,
2608 "no match community",
2609 NO_STR
2610 MATCH_STR
2611 "Match BGP community list\n")
2612{
2613 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2614}
2615
2616ALIAS (no_match_community,
2617 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002618 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002619 NO_STR
2620 MATCH_STR
2621 "Match BGP community list\n"
2622 "Community-list number (standard)\n"
2623 "Community-list number (expanded)\n"
2624 "Community-list name\n")
2625
2626ALIAS (no_match_community,
2627 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002628 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002629 NO_STR
2630 MATCH_STR
2631 "Match BGP community list\n"
2632 "Community-list number (standard)\n"
2633 "Community-list number (expanded)\n"
2634 "Community-list name\n"
2635 "Do exact matching of communities\n")
2636
paul73ffb252003-04-19 15:49:49 +00002637DEFUN (match_ecommunity,
2638 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002639 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002640 MATCH_STR
2641 "Match BGP/VPN extended community list\n"
2642 "Extended community-list number (standard)\n"
2643 "Extended community-list number (expanded)\n"
2644 "Extended community-list name\n")
2645{
2646 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2647}
2648
2649DEFUN (no_match_ecommunity,
2650 no_match_ecommunity_cmd,
2651 "no match extcommunity",
2652 NO_STR
2653 MATCH_STR
2654 "Match BGP/VPN extended community list\n")
2655{
2656 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2657}
2658
2659ALIAS (no_match_ecommunity,
2660 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002661 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002662 NO_STR
2663 MATCH_STR
2664 "Match BGP/VPN extended community list\n"
2665 "Extended community-list number (standard)\n"
2666 "Extended community-list number (expanded)\n"
2667 "Extended community-list name\n")
2668
paul718e3742002-12-13 20:15:29 +00002669DEFUN (match_aspath,
2670 match_aspath_cmd,
2671 "match as-path WORD",
2672 MATCH_STR
2673 "Match BGP AS path list\n"
2674 "AS path access-list name\n")
2675{
2676 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2677}
2678
2679DEFUN (no_match_aspath,
2680 no_match_aspath_cmd,
2681 "no match as-path",
2682 NO_STR
2683 MATCH_STR
2684 "Match BGP AS path list\n")
2685{
2686 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2687}
2688
2689ALIAS (no_match_aspath,
2690 no_match_aspath_val_cmd,
2691 "no match as-path WORD",
2692 NO_STR
2693 MATCH_STR
2694 "Match BGP AS path list\n"
2695 "AS path access-list name\n")
2696
2697DEFUN (match_origin,
2698 match_origin_cmd,
2699 "match origin (egp|igp|incomplete)",
2700 MATCH_STR
2701 "BGP origin code\n"
2702 "remote EGP\n"
2703 "local IGP\n"
2704 "unknown heritage\n")
2705{
2706 if (strncmp (argv[0], "igp", 2) == 0)
2707 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2708 if (strncmp (argv[0], "egp", 1) == 0)
2709 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2710 if (strncmp (argv[0], "incomplete", 2) == 0)
2711 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2712
2713 return CMD_WARNING;
2714}
2715
2716DEFUN (no_match_origin,
2717 no_match_origin_cmd,
2718 "no match origin",
2719 NO_STR
2720 MATCH_STR
2721 "BGP origin code\n")
2722{
2723 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2724}
2725
2726ALIAS (no_match_origin,
2727 no_match_origin_val_cmd,
2728 "no match origin (egp|igp|incomplete)",
2729 NO_STR
2730 MATCH_STR
2731 "BGP origin code\n"
2732 "remote EGP\n"
2733 "local IGP\n"
2734 "unknown heritage\n")
2735
2736DEFUN (set_ip_nexthop,
2737 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002738 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002739 SET_STR
2740 IP_STR
2741 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002742 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002743{
2744 union sockunion su;
2745 int ret;
2746
2747 ret = str2sockunion (argv[0], &su);
2748 if (ret < 0)
2749 {
2750 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2751 return CMD_WARNING;
2752 }
2753
2754 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2755}
2756
paulaf5cd0a2003-11-02 07:24:40 +00002757DEFUN (set_ip_nexthop_peer,
2758 set_ip_nexthop_peer_cmd,
2759 "set ip next-hop peer-address",
2760 SET_STR
2761 IP_STR
2762 "Next hop address\n"
2763 "Use peer address (for BGP only)\n")
2764{
2765 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2766}
2767
paul94f2b392005-06-28 12:44:16 +00002768DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00002769 no_set_ip_nexthop_peer_cmd,
2770 "no set ip next-hop peer-address",
2771 NO_STR
2772 SET_STR
2773 IP_STR
2774 "Next hop address\n"
2775 "Use peer address (for BGP only)\n")
2776{
2777 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2778}
2779
2780
paul718e3742002-12-13 20:15:29 +00002781DEFUN (no_set_ip_nexthop,
2782 no_set_ip_nexthop_cmd,
2783 "no set ip next-hop",
2784 NO_STR
2785 SET_STR
paul718e3742002-12-13 20:15:29 +00002786 "Next hop address\n")
2787{
paulaf5cd0a2003-11-02 07:24:40 +00002788 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002789 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2790
2791 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2792}
2793
2794ALIAS (no_set_ip_nexthop,
2795 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002796 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002797 NO_STR
2798 SET_STR
2799 IP_STR
2800 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002801 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002802
2803DEFUN (set_metric,
2804 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002805 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002806 SET_STR
2807 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002808 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002809{
2810 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2811}
2812
paul73ffb252003-04-19 15:49:49 +00002813ALIAS (set_metric,
2814 set_metric_addsub_cmd,
2815 "set metric <+/-metric>",
2816 SET_STR
2817 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00002818 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00002819
paul718e3742002-12-13 20:15:29 +00002820DEFUN (no_set_metric,
2821 no_set_metric_cmd,
2822 "no set metric",
2823 NO_STR
2824 SET_STR
2825 "Metric value for destination routing protocol\n")
2826{
2827 if (argc == 0)
2828 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
2829
2830 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
2831}
2832
2833ALIAS (no_set_metric,
2834 no_set_metric_val_cmd,
2835 "no set metric <0-4294967295>",
2836 NO_STR
2837 SET_STR
2838 "Metric value for destination routing protocol\n"
2839 "Metric value\n")
2840
2841DEFUN (set_local_pref,
2842 set_local_pref_cmd,
2843 "set local-preference <0-4294967295>",
2844 SET_STR
2845 "BGP local preference path attribute\n"
2846 "Preference value\n")
2847{
2848 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
2849}
2850
2851DEFUN (no_set_local_pref,
2852 no_set_local_pref_cmd,
2853 "no set local-preference",
2854 NO_STR
2855 SET_STR
2856 "BGP local preference path attribute\n")
2857{
2858 if (argc == 0)
2859 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
2860
2861 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
2862}
2863
2864ALIAS (no_set_local_pref,
2865 no_set_local_pref_val_cmd,
2866 "no set local-preference <0-4294967295>",
2867 NO_STR
2868 SET_STR
2869 "BGP local preference path attribute\n"
2870 "Preference value\n")
2871
2872DEFUN (set_weight,
2873 set_weight_cmd,
2874 "set weight <0-4294967295>",
2875 SET_STR
2876 "BGP weight for routing table\n"
2877 "Weight value\n")
2878{
2879 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
2880}
2881
2882DEFUN (no_set_weight,
2883 no_set_weight_cmd,
2884 "no set weight",
2885 NO_STR
2886 SET_STR
2887 "BGP weight for routing table\n")
2888{
2889 if (argc == 0)
2890 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
2891
2892 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
2893}
2894
2895ALIAS (no_set_weight,
2896 no_set_weight_val_cmd,
2897 "no set weight <0-4294967295>",
2898 NO_STR
2899 SET_STR
2900 "BGP weight for routing table\n"
2901 "Weight value\n")
2902
2903DEFUN (set_aspath_prepend,
2904 set_aspath_prepend_cmd,
2905 "set as-path prepend .<1-65535>",
2906 SET_STR
2907 "Prepend string for a BGP AS-path attribute\n"
2908 "Prepend to the as-path\n"
2909 "AS number\n")
2910{
2911 int ret;
2912 char *str;
2913
2914 str = argv_concat (argv, argc, 0);
2915 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
2916 XFREE (MTYPE_TMP, str);
2917
2918 return ret;
2919}
2920
2921DEFUN (no_set_aspath_prepend,
2922 no_set_aspath_prepend_cmd,
2923 "no set as-path prepend",
2924 NO_STR
2925 SET_STR
2926 "Prepend string for a BGP AS-path attribute\n"
2927 "Prepend to the as-path\n")
2928{
2929 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
2930}
2931
2932ALIAS (no_set_aspath_prepend,
2933 no_set_aspath_prepend_val_cmd,
2934 "no set as-path prepend .<1-65535>",
2935 NO_STR
2936 SET_STR
2937 "Prepend string for a BGP AS-path attribute\n"
2938 "Prepend to the as-path\n"
2939 "AS number\n")
2940
2941DEFUN (set_community,
2942 set_community_cmd,
2943 "set community .AA:NN",
2944 SET_STR
2945 "BGP community attribute\n"
2946 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
2947{
2948 int i;
2949 int first = 0;
2950 int additive = 0;
2951 struct buffer *b;
2952 struct community *com = NULL;
2953 char *str;
2954 char *argstr;
2955 int ret;
2956
2957 b = buffer_new (1024);
2958
2959 for (i = 0; i < argc; i++)
2960 {
2961 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
2962 {
2963 additive = 1;
2964 continue;
2965 }
2966
2967 if (first)
2968 buffer_putc (b, ' ');
2969 else
2970 first = 1;
2971
2972 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
2973 {
2974 buffer_putstr (b, "internet");
2975 continue;
2976 }
2977 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
2978 {
2979 buffer_putstr (b, "local-AS");
2980 continue;
2981 }
2982 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
2983 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
2984 {
2985 buffer_putstr (b, "no-advertise");
2986 continue;
2987 }
2988 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
2989 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
2990 {
2991 buffer_putstr (b, "no-export");
2992 continue;
2993 }
2994 buffer_putstr (b, argv[i]);
2995 }
2996 buffer_putc (b, '\0');
2997
2998 /* Fetch result string then compile it to communities attribute. */
2999 str = buffer_getstr (b);
3000 buffer_free (b);
3001
3002 if (str)
3003 {
3004 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003005 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003006 }
3007
3008 /* Can't compile user input into communities attribute. */
3009 if (! com)
3010 {
3011 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3012 return CMD_WARNING;
3013 }
3014
3015 /* Set communites attribute string. */
3016 str = community_str (com);
3017
3018 if (additive)
3019 {
3020 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3021 strcpy (argstr, str);
3022 strcpy (argstr + strlen (str), " additive");
3023 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3024 XFREE (MTYPE_TMP, argstr);
3025 }
3026 else
3027 ret = bgp_route_set_add (vty, vty->index, "community", str);
3028
3029 community_free (com);
3030
3031 return ret;
3032}
3033
3034DEFUN (set_community_none,
3035 set_community_none_cmd,
3036 "set community none",
3037 SET_STR
3038 "BGP community attribute\n"
3039 "No community attribute\n")
3040{
3041 return bgp_route_set_add (vty, vty->index, "community", "none");
3042}
3043
3044DEFUN (no_set_community,
3045 no_set_community_cmd,
3046 "no set community",
3047 NO_STR
3048 SET_STR
3049 "BGP community attribute\n")
3050{
3051 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3052}
3053
3054ALIAS (no_set_community,
3055 no_set_community_val_cmd,
3056 "no set community .AA:NN",
3057 NO_STR
3058 SET_STR
3059 "BGP community attribute\n"
3060 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3061
3062ALIAS (no_set_community,
3063 no_set_community_none_cmd,
3064 "no set community none",
3065 NO_STR
3066 SET_STR
3067 "BGP community attribute\n"
3068 "No community attribute\n")
3069
3070DEFUN (set_community_delete,
3071 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003072 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003073 SET_STR
3074 "set BGP community list (for deletion)\n"
3075 "Community-list number (standard)\n"
3076 "Communitly-list number (expanded)\n"
3077 "Community-list name\n"
3078 "Delete matching communities\n")
3079{
3080 char *str;
3081
3082 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3083 strcpy (str, argv[0]);
3084 strcpy (str + strlen (argv[0]), " delete");
3085
3086 bgp_route_set_add (vty, vty->index, "comm-list", str);
3087
3088 XFREE (MTYPE_TMP, str);
3089 return CMD_SUCCESS;
3090}
3091
3092DEFUN (no_set_community_delete,
3093 no_set_community_delete_cmd,
3094 "no set comm-list",
3095 NO_STR
3096 SET_STR
3097 "set BGP community list (for deletion)\n")
3098{
3099 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3100}
3101
3102ALIAS (no_set_community_delete,
3103 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003104 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003105 NO_STR
3106 SET_STR
3107 "set BGP community list (for deletion)\n"
3108 "Community-list number (standard)\n"
3109 "Communitly-list number (expanded)\n"
3110 "Community-list name\n"
3111 "Delete matching communities\n")
3112
3113DEFUN (set_ecommunity_rt,
3114 set_ecommunity_rt_cmd,
3115 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3116 SET_STR
3117 "BGP extended community attribute\n"
3118 "Route Target extened communityt\n"
3119 "VPN extended community\n")
3120{
3121 int ret;
3122 char *str;
3123
3124 str = argv_concat (argv, argc, 0);
3125 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3126 XFREE (MTYPE_TMP, str);
3127
3128 return ret;
3129}
3130
3131DEFUN (no_set_ecommunity_rt,
3132 no_set_ecommunity_rt_cmd,
3133 "no set extcommunity rt",
3134 NO_STR
3135 SET_STR
3136 "BGP extended community attribute\n"
3137 "Route Target extened communityt\n")
3138{
3139 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3140}
3141
3142ALIAS (no_set_ecommunity_rt,
3143 no_set_ecommunity_rt_val_cmd,
3144 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3145 NO_STR
3146 SET_STR
3147 "BGP extended community attribute\n"
3148 "Route Target extened communityt\n"
3149 "VPN extended community\n")
3150
3151DEFUN (set_ecommunity_soo,
3152 set_ecommunity_soo_cmd,
3153 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3154 SET_STR
3155 "BGP extended community attribute\n"
3156 "Site-of-Origin extended community\n"
3157 "VPN extended community\n")
3158{
3159 int ret;
3160 char *str;
3161
3162 str = argv_concat (argv, argc, 0);
3163 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3164 XFREE (MTYPE_TMP, str);
3165 return ret;
3166}
3167
3168DEFUN (no_set_ecommunity_soo,
3169 no_set_ecommunity_soo_cmd,
3170 "no set extcommunity soo",
3171 NO_STR
3172 SET_STR
3173 "BGP extended community attribute\n"
3174 "Site-of-Origin extended community\n")
3175{
3176 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3177}
3178
3179ALIAS (no_set_ecommunity_soo,
3180 no_set_ecommunity_soo_val_cmd,
3181 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3182 NO_STR
3183 SET_STR
3184 "BGP extended community attribute\n"
3185 "Site-of-Origin extended community\n"
3186 "VPN extended community\n")
3187
3188DEFUN (set_origin,
3189 set_origin_cmd,
3190 "set origin (egp|igp|incomplete)",
3191 SET_STR
3192 "BGP origin code\n"
3193 "remote EGP\n"
3194 "local IGP\n"
3195 "unknown heritage\n")
3196{
3197 if (strncmp (argv[0], "igp", 2) == 0)
3198 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3199 if (strncmp (argv[0], "egp", 1) == 0)
3200 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3201 if (strncmp (argv[0], "incomplete", 2) == 0)
3202 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3203
3204 return CMD_WARNING;
3205}
3206
3207DEFUN (no_set_origin,
3208 no_set_origin_cmd,
3209 "no set origin",
3210 NO_STR
3211 SET_STR
3212 "BGP origin code\n")
3213{
3214 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3215}
3216
3217ALIAS (no_set_origin,
3218 no_set_origin_val_cmd,
3219 "no set origin (egp|igp|incomplete)",
3220 NO_STR
3221 SET_STR
3222 "BGP origin code\n"
3223 "remote EGP\n"
3224 "local IGP\n"
3225 "unknown heritage\n")
3226
3227DEFUN (set_atomic_aggregate,
3228 set_atomic_aggregate_cmd,
3229 "set atomic-aggregate",
3230 SET_STR
3231 "BGP atomic aggregate attribute\n" )
3232{
3233 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3234}
3235
3236DEFUN (no_set_atomic_aggregate,
3237 no_set_atomic_aggregate_cmd,
3238 "no set atomic-aggregate",
3239 NO_STR
3240 SET_STR
3241 "BGP atomic aggregate attribute\n" )
3242{
3243 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3244}
3245
3246DEFUN (set_aggregator_as,
3247 set_aggregator_as_cmd,
3248 "set aggregator as <1-65535> A.B.C.D",
3249 SET_STR
3250 "BGP aggregator attribute\n"
3251 "AS number of aggregator\n"
3252 "AS number\n"
3253 "IP address of aggregator\n")
3254{
3255 int ret;
3256 as_t as;
3257 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003258 char *argstr;
3259
paula94feb32005-05-23 13:17:29 +00003260 VTY_GET_INTEGER_RANGE ("AS Path", as, argv[0], 1, BGP_AS_MAX);
paulfd79ac92004-10-13 05:06:08 +00003261
paul718e3742002-12-13 20:15:29 +00003262 ret = inet_aton (argv[1], &address);
3263 if (ret == 0)
3264 {
3265 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3266 return CMD_WARNING;
3267 }
3268
3269 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3270 strlen (argv[0]) + strlen (argv[1]) + 2);
3271
3272 sprintf (argstr, "%s %s", argv[0], argv[1]);
3273
3274 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3275
3276 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3277
3278 return ret;
3279}
3280
3281DEFUN (no_set_aggregator_as,
3282 no_set_aggregator_as_cmd,
3283 "no set aggregator as",
3284 NO_STR
3285 SET_STR
3286 "BGP aggregator attribute\n"
3287 "AS number of aggregator\n")
3288{
3289 int ret;
3290 as_t as;
3291 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003292 char *argstr;
3293
3294 if (argv == 0)
3295 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3296
paula94feb32005-05-23 13:17:29 +00003297 VTY_GET_INTEGER_RANGE ("AS Path", as, argv[0], 1, BGP_AS_MAX);
paul718e3742002-12-13 20:15:29 +00003298
3299 ret = inet_aton (argv[1], &address);
3300 if (ret == 0)
3301 {
3302 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3303 return CMD_WARNING;
3304 }
3305
3306 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3307 strlen (argv[0]) + strlen (argv[1]) + 2);
3308
3309 sprintf (argstr, "%s %s", argv[0], argv[1]);
3310
3311 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3312
3313 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3314
3315 return ret;
3316}
3317
3318ALIAS (no_set_aggregator_as,
3319 no_set_aggregator_as_val_cmd,
3320 "no set aggregator as <1-65535> A.B.C.D",
3321 NO_STR
3322 SET_STR
3323 "BGP aggregator attribute\n"
3324 "AS number of aggregator\n"
3325 "AS number\n"
3326 "IP address of aggregator\n")
3327
3328
3329#ifdef HAVE_IPV6
3330DEFUN (match_ipv6_address,
3331 match_ipv6_address_cmd,
3332 "match ipv6 address WORD",
3333 MATCH_STR
3334 IPV6_STR
3335 "Match IPv6 address of route\n"
3336 "IPv6 access-list name\n")
3337{
3338 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3339}
3340
3341DEFUN (no_match_ipv6_address,
3342 no_match_ipv6_address_cmd,
3343 "no match ipv6 address WORD",
3344 NO_STR
3345 MATCH_STR
3346 IPV6_STR
3347 "Match IPv6 address of route\n"
3348 "IPv6 access-list name\n")
3349{
3350 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3351}
3352
3353DEFUN (match_ipv6_next_hop,
3354 match_ipv6_next_hop_cmd,
3355 "match ipv6 next-hop X:X::X:X",
3356 MATCH_STR
3357 IPV6_STR
3358 "Match IPv6 next-hop address of route\n"
3359 "IPv6 address of next hop\n")
3360{
3361 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3362}
3363
3364DEFUN (no_match_ipv6_next_hop,
3365 no_match_ipv6_next_hop_cmd,
3366 "no match ipv6 next-hop X:X::X:X",
3367 NO_STR
3368 MATCH_STR
3369 IPV6_STR
3370 "Match IPv6 next-hop address of route\n"
3371 "IPv6 address of next hop\n")
3372{
3373 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3374}
3375
3376DEFUN (match_ipv6_address_prefix_list,
3377 match_ipv6_address_prefix_list_cmd,
3378 "match ipv6 address prefix-list WORD",
3379 MATCH_STR
3380 IPV6_STR
3381 "Match address of route\n"
3382 "Match entries of prefix-lists\n"
3383 "IP prefix-list name\n")
3384{
3385 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3386}
3387
3388DEFUN (no_match_ipv6_address_prefix_list,
3389 no_match_ipv6_address_prefix_list_cmd,
3390 "no match ipv6 address prefix-list WORD",
3391 NO_STR
3392 MATCH_STR
3393 IPV6_STR
3394 "Match address of route\n"
3395 "Match entries of prefix-lists\n"
3396 "IP prefix-list name\n")
3397{
3398 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3399}
3400
3401DEFUN (set_ipv6_nexthop_global,
3402 set_ipv6_nexthop_global_cmd,
3403 "set ipv6 next-hop global X:X::X:X",
3404 SET_STR
3405 IPV6_STR
3406 "IPv6 next-hop address\n"
3407 "IPv6 global address\n"
3408 "IPv6 address of next hop\n")
3409{
3410 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3411}
3412
3413DEFUN (no_set_ipv6_nexthop_global,
3414 no_set_ipv6_nexthop_global_cmd,
3415 "no set ipv6 next-hop global",
3416 NO_STR
3417 SET_STR
3418 IPV6_STR
3419 "IPv6 next-hop address\n"
3420 "IPv6 global address\n")
3421{
3422 if (argc == 0)
3423 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3424
3425 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3426}
3427
3428ALIAS (no_set_ipv6_nexthop_global,
3429 no_set_ipv6_nexthop_global_val_cmd,
3430 "no set ipv6 next-hop global X:X::X:X",
3431 NO_STR
3432 SET_STR
3433 IPV6_STR
3434 "IPv6 next-hop address\n"
3435 "IPv6 global address\n"
3436 "IPv6 address of next hop\n")
3437
3438DEFUN (set_ipv6_nexthop_local,
3439 set_ipv6_nexthop_local_cmd,
3440 "set ipv6 next-hop local X:X::X:X",
3441 SET_STR
3442 IPV6_STR
3443 "IPv6 next-hop address\n"
3444 "IPv6 local address\n"
3445 "IPv6 address of next hop\n")
3446{
3447 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3448}
3449
3450DEFUN (no_set_ipv6_nexthop_local,
3451 no_set_ipv6_nexthop_local_cmd,
3452 "no set ipv6 next-hop local",
3453 NO_STR
3454 SET_STR
3455 IPV6_STR
3456 "IPv6 next-hop address\n"
3457 "IPv6 local address\n")
3458{
3459 if (argc == 0)
3460 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3461
3462 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3463}
3464
3465ALIAS (no_set_ipv6_nexthop_local,
3466 no_set_ipv6_nexthop_local_val_cmd,
3467 "no set ipv6 next-hop local X:X::X:X",
3468 NO_STR
3469 SET_STR
3470 IPV6_STR
3471 "IPv6 next-hop address\n"
3472 "IPv6 local address\n"
3473 "IPv6 address of next hop\n")
3474#endif /* HAVE_IPV6 */
3475
3476DEFUN (set_vpnv4_nexthop,
3477 set_vpnv4_nexthop_cmd,
3478 "set vpnv4 next-hop A.B.C.D",
3479 SET_STR
3480 "VPNv4 information\n"
3481 "VPNv4 next-hop address\n"
3482 "IP address of next hop\n")
3483{
3484 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3485}
3486
3487DEFUN (no_set_vpnv4_nexthop,
3488 no_set_vpnv4_nexthop_cmd,
3489 "no set vpnv4 next-hop",
3490 NO_STR
3491 SET_STR
3492 "VPNv4 information\n"
3493 "VPNv4 next-hop address\n")
3494{
3495 if (argc == 0)
3496 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3497
3498 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3499}
3500
3501ALIAS (no_set_vpnv4_nexthop,
3502 no_set_vpnv4_nexthop_val_cmd,
3503 "no set vpnv4 next-hop A.B.C.D",
3504 NO_STR
3505 SET_STR
3506 "VPNv4 information\n"
3507 "VPNv4 next-hop address\n"
3508 "IP address of next hop\n")
3509
3510DEFUN (set_originator_id,
3511 set_originator_id_cmd,
3512 "set originator-id A.B.C.D",
3513 SET_STR
3514 "BGP originator ID attribute\n"
3515 "IP address of originator\n")
3516{
3517 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3518}
3519
3520DEFUN (no_set_originator_id,
3521 no_set_originator_id_cmd,
3522 "no set originator-id",
3523 NO_STR
3524 SET_STR
3525 "BGP originator ID attribute\n")
3526{
3527 if (argc == 0)
3528 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3529
3530 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3531}
3532
3533ALIAS (no_set_originator_id,
3534 no_set_originator_id_val_cmd,
3535 "no set originator-id A.B.C.D",
3536 NO_STR
3537 SET_STR
3538 "BGP originator ID attribute\n"
3539 "IP address of originator\n")
3540
3541
3542/* Initialization of route map. */
3543void
paul94f2b392005-06-28 12:44:16 +00003544bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003545{
3546 route_map_init ();
3547 route_map_init_vty ();
3548 route_map_add_hook (bgp_route_map_update);
3549 route_map_delete_hook (bgp_route_map_update);
3550
paulfee0f4c2004-09-13 05:12:46 +00003551 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003552 route_map_install_match (&route_match_ip_address_cmd);
3553 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003554 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003555 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3556 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003557 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003558 route_map_install_match (&route_match_aspath_cmd);
3559 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003560 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003561 route_map_install_match (&route_match_metric_cmd);
3562 route_map_install_match (&route_match_origin_cmd);
3563
3564 route_map_install_set (&route_set_ip_nexthop_cmd);
3565 route_map_install_set (&route_set_local_pref_cmd);
3566 route_map_install_set (&route_set_weight_cmd);
3567 route_map_install_set (&route_set_metric_cmd);
3568 route_map_install_set (&route_set_aspath_prepend_cmd);
3569 route_map_install_set (&route_set_origin_cmd);
3570 route_map_install_set (&route_set_atomic_aggregate_cmd);
3571 route_map_install_set (&route_set_aggregator_as_cmd);
3572 route_map_install_set (&route_set_community_cmd);
3573 route_map_install_set (&route_set_community_delete_cmd);
3574 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3575 route_map_install_set (&route_set_originator_id_cmd);
3576 route_map_install_set (&route_set_ecommunity_rt_cmd);
3577 route_map_install_set (&route_set_ecommunity_soo_cmd);
3578
paulfee0f4c2004-09-13 05:12:46 +00003579 install_element (RMAP_NODE, &match_peer_cmd);
3580 install_element (RMAP_NODE, &match_peer_local_cmd);
3581 install_element (RMAP_NODE, &no_match_peer_cmd);
3582 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3583 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003584 install_element (RMAP_NODE, &match_ip_address_cmd);
3585 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3586 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3587 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3588 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3589 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003590 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3591 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3592 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003593
3594 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3595 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3596 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3597 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3598 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3599 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003600 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3601 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3602 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003603
3604 install_element (RMAP_NODE, &match_aspath_cmd);
3605 install_element (RMAP_NODE, &no_match_aspath_cmd);
3606 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3607 install_element (RMAP_NODE, &match_metric_cmd);
3608 install_element (RMAP_NODE, &no_match_metric_cmd);
3609 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3610 install_element (RMAP_NODE, &match_community_cmd);
3611 install_element (RMAP_NODE, &match_community_exact_cmd);
3612 install_element (RMAP_NODE, &no_match_community_cmd);
3613 install_element (RMAP_NODE, &no_match_community_val_cmd);
3614 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003615 install_element (RMAP_NODE, &match_ecommunity_cmd);
3616 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3617 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003618 install_element (RMAP_NODE, &match_origin_cmd);
3619 install_element (RMAP_NODE, &no_match_origin_cmd);
3620 install_element (RMAP_NODE, &no_match_origin_val_cmd);
3621
3622 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003623 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003624 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3625 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3626 install_element (RMAP_NODE, &set_local_pref_cmd);
3627 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3628 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3629 install_element (RMAP_NODE, &set_weight_cmd);
3630 install_element (RMAP_NODE, &no_set_weight_cmd);
3631 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3632 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003633 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003634 install_element (RMAP_NODE, &no_set_metric_cmd);
3635 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3636 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
3637 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3638 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
3639 install_element (RMAP_NODE, &set_origin_cmd);
3640 install_element (RMAP_NODE, &no_set_origin_cmd);
3641 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3642 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3643 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3644 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3645 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3646 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3647 install_element (RMAP_NODE, &set_community_cmd);
3648 install_element (RMAP_NODE, &set_community_none_cmd);
3649 install_element (RMAP_NODE, &no_set_community_cmd);
3650 install_element (RMAP_NODE, &no_set_community_val_cmd);
3651 install_element (RMAP_NODE, &no_set_community_none_cmd);
3652 install_element (RMAP_NODE, &set_community_delete_cmd);
3653 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3654 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3655 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3656 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3657 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3658 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3659 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3660 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3661 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3662 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3663 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3664 install_element (RMAP_NODE, &set_originator_id_cmd);
3665 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3666 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3667
3668#ifdef HAVE_IPV6
3669 route_map_install_match (&route_match_ipv6_address_cmd);
3670 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3671 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3672 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3673 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
3674
3675 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3676 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3677 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3678 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3679 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3680 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3681 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3682 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3683 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3684 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3685 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3686 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3687#endif /* HAVE_IPV6 */
3688}