blob: 255b25aedfbc827602e5b6429da9a0d2fee5a6f2 [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"
Jeremy Jackson25f45882009-01-12 16:06:12 -050031#ifdef HAVE_LIBPCREPOSIX
32# include <pcreposix.h>
paul718e3742002-12-13 20:15:29 +000033#else
Jeremy Jackson25f45882009-01-12 16:06:12 -050034# ifdef HAVE_GNU_REGEX
35# include <regex.h>
36# else
37# include "regex-gnu.h"
38# endif /* HAVE_GNU_REGEX */
39#endif /* HAVE_LIBPCREPOSIX */
paul718e3742002-12-13 20:15:29 +000040#include "buffer.h"
41#include "sockunion.h"
42
43#include "bgpd/bgpd.h"
44#include "bgpd/bgp_table.h"
45#include "bgpd/bgp_attr.h"
46#include "bgpd/bgp_aspath.h"
47#include "bgpd/bgp_route.h"
48#include "bgpd/bgp_regex.h"
49#include "bgpd/bgp_community.h"
50#include "bgpd/bgp_clist.h"
51#include "bgpd/bgp_filter.h"
52#include "bgpd/bgp_mplsvpn.h"
53#include "bgpd/bgp_ecommunity.h"
Paul Jakma320da872008-07-02 13:40:33 +000054#include "bgpd/bgp_vty.h"
paul718e3742002-12-13 20:15:29 +000055
56/* Memo of route-map commands.
57
58o Cisco route-map
59
60 match as-path : Done
61 community : Done
62 interface : Not yet
63 ip address : Done
64 ip next-hop : Done
hassoc1643bb2005-02-02 16:43:17 +000065 ip route-source : Done
paul718e3742002-12-13 20:15:29 +000066 ip prefix-list : Done
67 ipv6 address : Done
68 ipv6 next-hop : Done
69 ipv6 route-source: (This will not be implemented by bgpd)
70 ipv6 prefix-list : Done
71 length : (This will not be implemented by bgpd)
72 metric : Done
73 route-type : (This will not be implemented by bgpd)
74 tag : (This will not be implemented by bgpd)
75
76 set as-path prepend : Done
77 as-path tag : Not yet
78 automatic-tag : (This will not be implemented by bgpd)
79 community : Done
80 comm-list : Not yet
81 dampning : Not yet
82 default : (This will not be implemented by bgpd)
83 interface : (This will not be implemented by bgpd)
84 ip default : (This will not be implemented by bgpd)
85 ip next-hop : Done
86 ip precedence : (This will not be implemented by bgpd)
87 ip tos : (This will not be implemented by bgpd)
88 level : (This will not be implemented by bgpd)
89 local-preference : Done
90 metric : Done
91 metric-type : Not yet
92 origin : Done
93 tag : (This will not be implemented by bgpd)
94 weight : Done
95
96o Local extention
97
98 set ipv6 next-hop global: Done
99 set ipv6 next-hop local : Done
Denis Ovsienko841f7a52008-04-10 11:47:45 +0000100 set as-path exclude : Done
paul718e3742002-12-13 20:15:29 +0000101
102*/
103
paulfee0f4c2004-09-13 05:12:46 +0000104 /* 'match peer (A.B.C.D|X:X::X:X)' */
105
106/* Compares the peer specified in the 'match peer' clause with the peer
107 received in bgp_info->peer. If it is the same, or if the peer structure
108 received is a peer_group containing it, returns RMAP_MATCH. */
paul94f2b392005-06-28 12:44:16 +0000109static route_map_result_t
paulfee0f4c2004-09-13 05:12:46 +0000110route_match_peer (void *rule, struct prefix *prefix, route_map_object_t type,
111 void *object)
112{
113 union sockunion *su;
114 union sockunion *su2;
115 struct peer_group *group;
116 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +0000117 struct listnode *node, *nnode;
paulfee0f4c2004-09-13 05:12:46 +0000118
119 if (type == RMAP_BGP)
120 {
121 su = rule;
122 peer = ((struct bgp_info *) object)->peer;
123
124 if ( ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT) &&
125 ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_EXPORT) )
126 return RMAP_NOMATCH;
127
128 /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
129 REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
130 su2 = sockunion_str2su ("0.0.0.0");
131 if ( sockunion_same (su, su2) )
132 {
paul22db9de2005-05-19 01:50:11 +0000133 int ret;
paulfee0f4c2004-09-13 05:12:46 +0000134 if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
135 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE) ||
136 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
paul22db9de2005-05-19 01:50:11 +0000137 ret = RMAP_MATCH;
paulfee0f4c2004-09-13 05:12:46 +0000138 else
paul22db9de2005-05-19 01:50:11 +0000139 ret = RMAP_NOMATCH;
140
141 sockunion_free (su2);
142 return ret;
paulfee0f4c2004-09-13 05:12:46 +0000143 }
paul22db9de2005-05-19 01:50:11 +0000144 sockunion_free (su2);
145
paulfee0f4c2004-09-13 05:12:46 +0000146 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
147 {
148 if (sockunion_same (su, &peer->su))
149 return RMAP_MATCH;
150
151 return RMAP_NOMATCH;
152 }
153 else
154 {
155 group = peer->group;
paul1eb8ef22005-04-07 07:30:20 +0000156 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
paulfee0f4c2004-09-13 05:12:46 +0000157 {
158 if (sockunion_same (su, &peer->su))
159 return RMAP_MATCH;
paulfee0f4c2004-09-13 05:12:46 +0000160 }
Paul Jakma30a22312008-08-15 14:05:22 +0100161 return RMAP_NOMATCH;
paulfee0f4c2004-09-13 05:12:46 +0000162 }
163 }
164 return RMAP_NOMATCH;
165}
166
paul94f2b392005-06-28 12:44:16 +0000167static void *
paulfd79ac92004-10-13 05:06:08 +0000168route_match_peer_compile (const char *arg)
paulfee0f4c2004-09-13 05:12:46 +0000169{
170 union sockunion *su;
171 int ret;
172
173 su = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union sockunion));
174
175 ret = str2sockunion ( (arg)? arg : "0.0.0.0", su);
176 if (ret < 0) {
177 XFREE (MTYPE_ROUTE_MAP_COMPILED, su);
178 return NULL;
179 }
180
181 return su;
182}
183
184/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000185static void
paulfee0f4c2004-09-13 05:12:46 +0000186route_match_peer_free (void *rule)
187{
188 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
189}
190
191/* Route map commands for ip address matching. */
192struct route_map_rule_cmd route_match_peer_cmd =
193{
194 "peer",
195 route_match_peer,
196 route_match_peer_compile,
197 route_match_peer_free
198};
199
paul718e3742002-12-13 20:15:29 +0000200/* `match ip address IP_ACCESS_LIST' */
201
202/* Match function should return 1 if match is success else return
203 zero. */
paul94f2b392005-06-28 12:44:16 +0000204static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000205route_match_ip_address (void *rule, struct prefix *prefix,
206 route_map_object_t type, void *object)
207{
208 struct access_list *alist;
209 /* struct prefix_ipv4 match; */
210
211 if (type == RMAP_BGP)
212 {
213 alist = access_list_lookup (AFI_IP, (char *) rule);
214 if (alist == NULL)
215 return RMAP_NOMATCH;
216
217 return (access_list_apply (alist, prefix) == FILTER_DENY ?
218 RMAP_NOMATCH : RMAP_MATCH);
219 }
220 return RMAP_NOMATCH;
221}
222
223/* Route map `ip address' match statement. `arg' should be
224 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000225static void *
paulfd79ac92004-10-13 05:06:08 +0000226route_match_ip_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000227{
228 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
229}
230
231/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000232static void
paul718e3742002-12-13 20:15:29 +0000233route_match_ip_address_free (void *rule)
234{
235 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
236}
237
238/* Route map commands for ip address matching. */
239struct route_map_rule_cmd route_match_ip_address_cmd =
240{
241 "ip address",
242 route_match_ip_address,
243 route_match_ip_address_compile,
244 route_match_ip_address_free
245};
246
247/* `match ip next-hop IP_ADDRESS' */
248
249/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000250static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000251route_match_ip_next_hop (void *rule, struct prefix *prefix,
252 route_map_object_t type, void *object)
253{
254 struct access_list *alist;
255 struct bgp_info *bgp_info;
256 struct prefix_ipv4 p;
257
258 if (type == RMAP_BGP)
259 {
260 bgp_info = object;
261 p.family = AF_INET;
262 p.prefix = bgp_info->attr->nexthop;
263 p.prefixlen = IPV4_MAX_BITLEN;
264
265 alist = access_list_lookup (AFI_IP, (char *) rule);
266 if (alist == NULL)
267 return RMAP_NOMATCH;
268
269 return (access_list_apply (alist, &p) == FILTER_DENY ?
270 RMAP_NOMATCH : RMAP_MATCH);
271 }
272 return RMAP_NOMATCH;
273}
274
275/* Route map `ip next-hop' match statement. `arg' is
276 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000277static void *
paulfd79ac92004-10-13 05:06:08 +0000278route_match_ip_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000279{
280 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
281}
282
283/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000284static void
paul718e3742002-12-13 20:15:29 +0000285route_match_ip_next_hop_free (void *rule)
286{
287 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
288}
289
290/* Route map commands for ip next-hop matching. */
291struct route_map_rule_cmd route_match_ip_next_hop_cmd =
292{
293 "ip next-hop",
294 route_match_ip_next_hop,
295 route_match_ip_next_hop_compile,
296 route_match_ip_next_hop_free
297};
298
hassoc1643bb2005-02-02 16:43:17 +0000299/* `match ip route-source ACCESS-LIST' */
300
301/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000302static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000303route_match_ip_route_source (void *rule, struct prefix *prefix,
304 route_map_object_t type, void *object)
305{
306 struct access_list *alist;
307 struct bgp_info *bgp_info;
308 struct peer *peer;
309 struct prefix_ipv4 p;
310
311 if (type == RMAP_BGP)
312 {
313 bgp_info = object;
314 peer = bgp_info->peer;
315
316 if (! peer || sockunion_family (&peer->su) != AF_INET)
317 return RMAP_NOMATCH;
318
319 p.family = AF_INET;
320 p.prefix = peer->su.sin.sin_addr;
321 p.prefixlen = IPV4_MAX_BITLEN;
322
323 alist = access_list_lookup (AFI_IP, (char *) rule);
324 if (alist == NULL)
325 return RMAP_NOMATCH;
326
327 return (access_list_apply (alist, &p) == FILTER_DENY ?
328 RMAP_NOMATCH : RMAP_MATCH);
329 }
330 return RMAP_NOMATCH;
331}
332
333/* Route map `ip route-source' match statement. `arg' is
334 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000335static void *
hassoc1643bb2005-02-02 16:43:17 +0000336route_match_ip_route_source_compile (const char *arg)
337{
338 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
339}
340
341/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000342static void
hassoc1643bb2005-02-02 16:43:17 +0000343route_match_ip_route_source_free (void *rule)
344{
345 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
346}
347
348/* Route map commands for ip route-source matching. */
349struct route_map_rule_cmd route_match_ip_route_source_cmd =
350{
351 "ip route-source",
352 route_match_ip_route_source,
353 route_match_ip_route_source_compile,
354 route_match_ip_route_source_free
355};
356
paul718e3742002-12-13 20:15:29 +0000357/* `match ip address prefix-list PREFIX_LIST' */
358
paul94f2b392005-06-28 12:44:16 +0000359static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000360route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
361 route_map_object_t type, void *object)
362{
363 struct prefix_list *plist;
364
365 if (type == RMAP_BGP)
366 {
367 plist = prefix_list_lookup (AFI_IP, (char *) rule);
368 if (plist == NULL)
369 return RMAP_NOMATCH;
370
371 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
372 RMAP_NOMATCH : RMAP_MATCH);
373 }
374 return RMAP_NOMATCH;
375}
376
paul94f2b392005-06-28 12:44:16 +0000377static void *
paulfd79ac92004-10-13 05:06:08 +0000378route_match_ip_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000379{
380 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
381}
382
paul94f2b392005-06-28 12:44:16 +0000383static void
paul718e3742002-12-13 20:15:29 +0000384route_match_ip_address_prefix_list_free (void *rule)
385{
386 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
387}
388
389struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
390{
391 "ip address prefix-list",
392 route_match_ip_address_prefix_list,
393 route_match_ip_address_prefix_list_compile,
394 route_match_ip_address_prefix_list_free
395};
396
397/* `match ip next-hop prefix-list PREFIX_LIST' */
398
paul94f2b392005-06-28 12:44:16 +0000399static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000400route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
401 route_map_object_t type, void *object)
402{
403 struct prefix_list *plist;
404 struct bgp_info *bgp_info;
405 struct prefix_ipv4 p;
406
407 if (type == RMAP_BGP)
408 {
409 bgp_info = object;
410 p.family = AF_INET;
411 p.prefix = bgp_info->attr->nexthop;
412 p.prefixlen = IPV4_MAX_BITLEN;
413
414 plist = prefix_list_lookup (AFI_IP, (char *) rule);
415 if (plist == NULL)
416 return RMAP_NOMATCH;
417
418 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
419 RMAP_NOMATCH : RMAP_MATCH);
420 }
421 return RMAP_NOMATCH;
422}
423
paul94f2b392005-06-28 12:44:16 +0000424static void *
paulfd79ac92004-10-13 05:06:08 +0000425route_match_ip_next_hop_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000426{
427 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
428}
429
paul94f2b392005-06-28 12:44:16 +0000430static void
paul718e3742002-12-13 20:15:29 +0000431route_match_ip_next_hop_prefix_list_free (void *rule)
432{
433 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
434}
435
436struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
437{
438 "ip next-hop prefix-list",
439 route_match_ip_next_hop_prefix_list,
440 route_match_ip_next_hop_prefix_list_compile,
441 route_match_ip_next_hop_prefix_list_free
442};
443
hassoc1643bb2005-02-02 16:43:17 +0000444/* `match ip route-source prefix-list PREFIX_LIST' */
445
paul94f2b392005-06-28 12:44:16 +0000446static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000447route_match_ip_route_source_prefix_list (void *rule, struct prefix *prefix,
448 route_map_object_t type, void *object)
449{
450 struct prefix_list *plist;
451 struct bgp_info *bgp_info;
452 struct peer *peer;
453 struct prefix_ipv4 p;
454
455 if (type == RMAP_BGP)
456 {
457 bgp_info = object;
458 peer = bgp_info->peer;
459
460 if (! peer || sockunion_family (&peer->su) != AF_INET)
461 return RMAP_NOMATCH;
462
463 p.family = AF_INET;
464 p.prefix = peer->su.sin.sin_addr;
465 p.prefixlen = IPV4_MAX_BITLEN;
466
467 plist = prefix_list_lookup (AFI_IP, (char *) rule);
468 if (plist == NULL)
469 return RMAP_NOMATCH;
470
471 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
472 RMAP_NOMATCH : RMAP_MATCH);
473 }
474 return RMAP_NOMATCH;
475}
476
paul94f2b392005-06-28 12:44:16 +0000477static void *
hassoc1643bb2005-02-02 16:43:17 +0000478route_match_ip_route_source_prefix_list_compile (const char *arg)
479{
480 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
481}
482
paul94f2b392005-06-28 12:44:16 +0000483static void
hassoc1643bb2005-02-02 16:43:17 +0000484route_match_ip_route_source_prefix_list_free (void *rule)
485{
486 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
487}
488
489struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd =
490{
491 "ip route-source prefix-list",
492 route_match_ip_route_source_prefix_list,
493 route_match_ip_route_source_prefix_list_compile,
494 route_match_ip_route_source_prefix_list_free
495};
496
paul718e3742002-12-13 20:15:29 +0000497/* `match metric METRIC' */
498
499/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000500static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000501route_match_metric (void *rule, struct prefix *prefix,
502 route_map_object_t type, void *object)
503{
504 u_int32_t *med;
505 struct bgp_info *bgp_info;
506
507 if (type == RMAP_BGP)
508 {
509 med = rule;
510 bgp_info = object;
511
512 if (bgp_info->attr->med == *med)
513 return RMAP_MATCH;
514 else
515 return RMAP_NOMATCH;
516 }
517 return RMAP_NOMATCH;
518}
519
520/* Route map `match metric' match statement. `arg' is MED value */
paul94f2b392005-06-28 12:44:16 +0000521static void *
paulfd79ac92004-10-13 05:06:08 +0000522route_match_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000523{
524 u_int32_t *med;
525 char *endptr = NULL;
paul3b424972003-10-13 09:47:32 +0000526 unsigned long tmpval;
paul718e3742002-12-13 20:15:29 +0000527
paul3b424972003-10-13 09:47:32 +0000528 tmpval = strtoul (arg, &endptr, 10);
paulfd79ac92004-10-13 05:06:08 +0000529 if (*endptr != '\0' || tmpval == ULONG_MAX || tmpval > UINT32_MAX)
paul3b424972003-10-13 09:47:32 +0000530 return NULL;
paulfd79ac92004-10-13 05:06:08 +0000531
paul718e3742002-12-13 20:15:29 +0000532 med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +0000533
534 if (!med)
535 return med;
536
paul3b424972003-10-13 09:47:32 +0000537 *med = tmpval;
paul718e3742002-12-13 20:15:29 +0000538 return med;
539}
540
541/* Free route map's compiled `match metric' value. */
paul94f2b392005-06-28 12:44:16 +0000542static void
paul718e3742002-12-13 20:15:29 +0000543route_match_metric_free (void *rule)
544{
545 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
546}
547
548/* Route map commands for metric matching. */
549struct route_map_rule_cmd route_match_metric_cmd =
550{
551 "metric",
552 route_match_metric,
553 route_match_metric_compile,
554 route_match_metric_free
555};
556
557/* `match as-path ASPATH' */
558
559/* Match function for as-path match. I assume given object is */
paul94f2b392005-06-28 12:44:16 +0000560static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000561route_match_aspath (void *rule, struct prefix *prefix,
562 route_map_object_t type, void *object)
563{
564
565 struct as_list *as_list;
566 struct bgp_info *bgp_info;
567
568 if (type == RMAP_BGP)
569 {
570 as_list = as_list_lookup ((char *) rule);
571 if (as_list == NULL)
572 return RMAP_NOMATCH;
573
574 bgp_info = object;
575
576 /* Perform match. */
577 return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
578 }
579 return RMAP_NOMATCH;
580}
581
582/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000583static void *
paulfd79ac92004-10-13 05:06:08 +0000584route_match_aspath_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000585{
586 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
587}
588
589/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000590static void
paul718e3742002-12-13 20:15:29 +0000591route_match_aspath_free (void *rule)
592{
593 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
594}
595
596/* Route map commands for aspath matching. */
597struct route_map_rule_cmd route_match_aspath_cmd =
598{
599 "as-path",
600 route_match_aspath,
601 route_match_aspath_compile,
602 route_match_aspath_free
603};
paul718e3742002-12-13 20:15:29 +0000604
605/* `match community COMMUNIY' */
606struct rmap_community
607{
608 char *name;
609 int exact;
610};
611
612/* Match function for community match. */
paul94f2b392005-06-28 12:44:16 +0000613static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000614route_match_community (void *rule, struct prefix *prefix,
615 route_map_object_t type, void *object)
616{
617 struct community_list *list;
618 struct bgp_info *bgp_info;
619 struct rmap_community *rcom;
620
621 if (type == RMAP_BGP)
622 {
623 bgp_info = object;
624 rcom = rule;
625
hassofee6e4e2005-02-02 16:29:31 +0000626 list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +0000627 if (! list)
628 return RMAP_NOMATCH;
629
630 if (rcom->exact)
631 {
632 if (community_list_exact_match (bgp_info->attr->community, list))
633 return RMAP_MATCH;
634 }
635 else
636 {
637 if (community_list_match (bgp_info->attr->community, list))
638 return RMAP_MATCH;
639 }
640 }
641 return RMAP_NOMATCH;
642}
643
644/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000645static void *
paulfd79ac92004-10-13 05:06:08 +0000646route_match_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000647{
648 struct rmap_community *rcom;
649 int len;
650 char *p;
651
652 rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
653
654 p = strchr (arg, ' ');
655 if (p)
656 {
657 len = p - arg;
658 rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
659 memcpy (rcom->name, arg, len);
660 rcom->exact = 1;
661 }
662 else
663 {
664 rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
665 rcom->exact = 0;
666 }
667 return rcom;
668}
669
670/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000671static void
paul718e3742002-12-13 20:15:29 +0000672route_match_community_free (void *rule)
673{
674 struct rmap_community *rcom = rule;
675
676 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
677 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
678}
679
680/* Route map commands for community matching. */
681struct route_map_rule_cmd route_match_community_cmd =
682{
683 "community",
684 route_match_community,
685 route_match_community_compile,
686 route_match_community_free
687};
688
paul73ffb252003-04-19 15:49:49 +0000689/* Match function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000690static route_map_result_t
paul73ffb252003-04-19 15:49:49 +0000691route_match_ecommunity (void *rule, struct prefix *prefix,
692 route_map_object_t type, void *object)
693{
694 struct community_list *list;
695 struct bgp_info *bgp_info;
696
697 if (type == RMAP_BGP)
698 {
699 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +0000700
701 if (!bgp_info->attr->extra)
702 return RMAP_NOMATCH;
703
paul73ffb252003-04-19 15:49:49 +0000704 list = community_list_lookup (bgp_clist, (char *) rule,
hassofee6e4e2005-02-02 16:29:31 +0000705 EXTCOMMUNITY_LIST_MASTER);
paul73ffb252003-04-19 15:49:49 +0000706 if (! list)
707 return RMAP_NOMATCH;
708
Paul Jakmafb982c22007-05-04 20:15:47 +0000709 if (ecommunity_list_match (bgp_info->attr->extra->ecommunity, list))
paul73ffb252003-04-19 15:49:49 +0000710 return RMAP_MATCH;
711 }
712 return RMAP_NOMATCH;
713}
714
715/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000716static void *
paulfd79ac92004-10-13 05:06:08 +0000717route_match_ecommunity_compile (const char *arg)
paul73ffb252003-04-19 15:49:49 +0000718{
719 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
720}
721
722/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000723static void
paul73ffb252003-04-19 15:49:49 +0000724route_match_ecommunity_free (void *rule)
725{
726 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
727}
728
729/* Route map commands for community matching. */
730struct route_map_rule_cmd route_match_ecommunity_cmd =
731{
732 "extcommunity",
733 route_match_ecommunity,
734 route_match_ecommunity_compile,
735 route_match_ecommunity_free
736};
737
paul718e3742002-12-13 20:15:29 +0000738/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
739 and `address-family vpnv4'. */
740
741/* `match origin' */
paul94f2b392005-06-28 12:44:16 +0000742static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000743route_match_origin (void *rule, struct prefix *prefix,
744 route_map_object_t type, void *object)
745{
746 u_char *origin;
747 struct bgp_info *bgp_info;
748
749 if (type == RMAP_BGP)
750 {
751 origin = rule;
752 bgp_info = object;
753
754 if (bgp_info->attr->origin == *origin)
755 return RMAP_MATCH;
756 }
757
758 return RMAP_NOMATCH;
759}
760
paul94f2b392005-06-28 12:44:16 +0000761static void *
paulfd79ac92004-10-13 05:06:08 +0000762route_match_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000763{
764 u_char *origin;
765
766 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
767
768 if (strcmp (arg, "igp") == 0)
769 *origin = 0;
770 else if (strcmp (arg, "egp") == 0)
771 *origin = 1;
772 else
773 *origin = 2;
774
775 return origin;
776}
777
778/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000779static void
paul718e3742002-12-13 20:15:29 +0000780route_match_origin_free (void *rule)
781{
782 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
783}
784
785/* Route map commands for origin matching. */
786struct route_map_rule_cmd route_match_origin_cmd =
787{
788 "origin",
789 route_match_origin,
790 route_match_origin_compile,
791 route_match_origin_free
792};
793/* `set ip next-hop IP_ADDRESS' */
794
795/* Set nexthop to object. ojbect must be pointer to struct attr. */
paulac41b2a2003-08-12 05:32:27 +0000796struct rmap_ip_nexthop_set
797{
798 struct in_addr *address;
799 int peer_address;
800};
801
paul94f2b392005-06-28 12:44:16 +0000802static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000803route_set_ip_nexthop (void *rule, struct prefix *prefix,
804 route_map_object_t type, void *object)
805{
paulac41b2a2003-08-12 05:32:27 +0000806 struct rmap_ip_nexthop_set *rins = rule;
807 struct in_addr peer_address;
paul718e3742002-12-13 20:15:29 +0000808 struct bgp_info *bgp_info;
paulac41b2a2003-08-12 05:32:27 +0000809 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000810
811 if (type == RMAP_BGP)
812 {
paul718e3742002-12-13 20:15:29 +0000813 bgp_info = object;
paulac41b2a2003-08-12 05:32:27 +0000814 peer = bgp_info->peer;
815
816 if (rins->peer_address)
817 {
paulfee0f4c2004-09-13 05:12:46 +0000818 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
819 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
paulac41b2a2003-08-12 05:32:27 +0000820 && peer->su_remote
821 && sockunion_family (peer->su_remote) == AF_INET)
822 {
823 inet_aton (sockunion_su2str (peer->su_remote), &peer_address);
824 bgp_info->attr->nexthop = peer_address;
825 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
826 }
827 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
828 && peer->su_local
829 && sockunion_family (peer->su_local) == AF_INET)
830 {
831 inet_aton (sockunion_su2str (peer->su_local), &peer_address);
832 bgp_info->attr->nexthop = peer_address;
833 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
834 }
835 }
836 else
837 {
838 /* Set next hop value. */
839 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
840 bgp_info->attr->nexthop = *rins->address;
841 }
paul718e3742002-12-13 20:15:29 +0000842 }
843
844 return RMAP_OKAY;
845}
846
847/* Route map `ip nexthop' compile function. Given string is converted
848 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +0000849static void *
paulfd79ac92004-10-13 05:06:08 +0000850route_set_ip_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000851{
paulac41b2a2003-08-12 05:32:27 +0000852 struct rmap_ip_nexthop_set *rins;
853 struct in_addr *address = NULL;
854 int peer_address = 0;
paul718e3742002-12-13 20:15:29 +0000855 int ret;
paul718e3742002-12-13 20:15:29 +0000856
paulac41b2a2003-08-12 05:32:27 +0000857 if (strcmp (arg, "peer-address") == 0)
858 peer_address = 1;
859 else
paul718e3742002-12-13 20:15:29 +0000860 {
paulac41b2a2003-08-12 05:32:27 +0000861 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
862 ret = inet_aton (arg, address);
863
864 if (ret == 0)
865 {
866 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
867 return NULL;
868 }
paul718e3742002-12-13 20:15:29 +0000869 }
870
Stephen Hemminger393deb92008-08-18 14:13:29 -0700871 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
paulac41b2a2003-08-12 05:32:27 +0000872
873 rins->address = address;
874 rins->peer_address = peer_address;
875
876 return rins;
paul718e3742002-12-13 20:15:29 +0000877}
878
879/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +0000880static void
paul718e3742002-12-13 20:15:29 +0000881route_set_ip_nexthop_free (void *rule)
882{
paulac41b2a2003-08-12 05:32:27 +0000883 struct rmap_ip_nexthop_set *rins = rule;
884
885 if (rins->address)
886 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
887
888 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +0000889}
890
891/* Route map commands for ip nexthop set. */
892struct route_map_rule_cmd route_set_ip_nexthop_cmd =
893{
894 "ip next-hop",
895 route_set_ip_nexthop,
896 route_set_ip_nexthop_compile,
897 route_set_ip_nexthop_free
898};
899
900/* `set local-preference LOCAL_PREF' */
901
902/* Set local preference. */
paul94f2b392005-06-28 12:44:16 +0000903static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000904route_set_local_pref (void *rule, struct prefix *prefix,
905 route_map_object_t type, void *object)
906{
907 u_int32_t *local_pref;
908 struct bgp_info *bgp_info;
909
910 if (type == RMAP_BGP)
911 {
912 /* Fetch routemap's rule information. */
913 local_pref = rule;
914 bgp_info = object;
915
916 /* Set local preference value. */
917 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
918 bgp_info->attr->local_pref = *local_pref;
919 }
920
921 return RMAP_OKAY;
922}
923
924/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +0000925static void *
paulfd79ac92004-10-13 05:06:08 +0000926route_set_local_pref_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000927{
paulfd79ac92004-10-13 05:06:08 +0000928 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +0000929 u_int32_t *local_pref;
930 char *endptr = NULL;
931
932 /* Local preference value shoud be integer. */
933 if (! all_digit (arg))
934 return NULL;
paulfd79ac92004-10-13 05:06:08 +0000935
936 tmp = strtoul (arg, &endptr, 10);
937 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
938 return NULL;
939
940 local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
941
942 if (!local_pref)
943 return local_pref;
944
945 *local_pref = tmp;
946
paul718e3742002-12-13 20:15:29 +0000947 return local_pref;
948}
949
950/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +0000951static void
paul718e3742002-12-13 20:15:29 +0000952route_set_local_pref_free (void *rule)
953{
954 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
955}
956
957/* Set local preference rule structure. */
958struct route_map_rule_cmd route_set_local_pref_cmd =
959{
960 "local-preference",
961 route_set_local_pref,
962 route_set_local_pref_compile,
963 route_set_local_pref_free,
964};
965
966/* `set weight WEIGHT' */
967
968/* Set weight. */
paul94f2b392005-06-28 12:44:16 +0000969static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000970route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
971 void *object)
972{
973 u_int32_t *weight;
974 struct bgp_info *bgp_info;
975
976 if (type == RMAP_BGP)
977 {
978 /* Fetch routemap's rule information. */
979 weight = rule;
980 bgp_info = object;
981
982 /* Set weight value. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000983 if (*weight)
984 (bgp_attr_extra_get (bgp_info->attr))->weight = *weight;
985 else if (bgp_info->attr->extra)
986 bgp_info->attr->extra->weight = 0;
paul718e3742002-12-13 20:15:29 +0000987 }
988
989 return RMAP_OKAY;
990}
991
992/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +0000993static void *
paulfd79ac92004-10-13 05:06:08 +0000994route_set_weight_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000995{
paulfd79ac92004-10-13 05:06:08 +0000996 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +0000997 u_int32_t *weight;
998 char *endptr = NULL;
999
1000 /* Local preference value shoud be integer. */
1001 if (! all_digit (arg))
1002 return NULL;
1003
paulfd79ac92004-10-13 05:06:08 +00001004
1005 tmp = strtoul (arg, &endptr, 10);
1006 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
1007 return NULL;
1008
paul718e3742002-12-13 20:15:29 +00001009 weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +00001010
1011 if (weight == NULL)
1012 return weight;
1013
1014 *weight = tmp;
1015
paul718e3742002-12-13 20:15:29 +00001016 return weight;
1017}
1018
1019/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +00001020static void
paul718e3742002-12-13 20:15:29 +00001021route_set_weight_free (void *rule)
1022{
1023 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1024}
1025
1026/* Set local preference rule structure. */
1027struct route_map_rule_cmd route_set_weight_cmd =
1028{
1029 "weight",
1030 route_set_weight,
1031 route_set_weight_compile,
1032 route_set_weight_free,
1033};
1034
1035/* `set metric METRIC' */
1036
1037/* Set metric to attribute. */
paul94f2b392005-06-28 12:44:16 +00001038static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001039route_set_metric (void *rule, struct prefix *prefix,
1040 route_map_object_t type, void *object)
1041{
1042 char *metric;
1043 u_int32_t metric_val;
1044 struct bgp_info *bgp_info;
1045
1046 if (type == RMAP_BGP)
1047 {
1048 /* Fetch routemap's rule information. */
1049 metric = rule;
1050 bgp_info = object;
1051
1052 if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
1053 bgp_info->attr->med = 0;
1054 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
1055
1056 if (all_digit (metric))
1057 {
1058 metric_val = strtoul (metric, (char **)NULL, 10);
1059 bgp_info->attr->med = metric_val;
1060 }
1061 else
1062 {
1063 metric_val = strtoul (metric+1, (char **)NULL, 10);
1064
1065 if (strncmp (metric, "+", 1) == 0)
1066 {
paul3b424972003-10-13 09:47:32 +00001067 if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2)
1068 bgp_info->attr->med = BGP_MED_MAX - 1;
paul718e3742002-12-13 20:15:29 +00001069 else
paul537d8ea2003-08-27 06:45:32 +00001070 bgp_info->attr->med += metric_val;
paul718e3742002-12-13 20:15:29 +00001071 }
1072 else if (strncmp (metric, "-", 1) == 0)
1073 {
paul537d8ea2003-08-27 06:45:32 +00001074 if (bgp_info->attr->med <= metric_val)
1075 bgp_info->attr->med = 0;
paul718e3742002-12-13 20:15:29 +00001076 else
paul537d8ea2003-08-27 06:45:32 +00001077 bgp_info->attr->med -= metric_val;
paul718e3742002-12-13 20:15:29 +00001078 }
1079 }
1080 }
1081 return RMAP_OKAY;
1082}
1083
1084/* set metric compilation. */
paul94f2b392005-06-28 12:44:16 +00001085static void *
paulfd79ac92004-10-13 05:06:08 +00001086route_set_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001087{
1088 u_int32_t metric;
paul94f2b392005-06-28 12:44:16 +00001089 unsigned long larg;
paul718e3742002-12-13 20:15:29 +00001090 char *endptr = NULL;
1091
1092 if (all_digit (arg))
1093 {
1094 /* set metric value check*/
paul94f2b392005-06-28 12:44:16 +00001095 larg = strtoul (arg, &endptr, 10);
1096 if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001097 return NULL;
paul94f2b392005-06-28 12:44:16 +00001098 metric = larg;
paul718e3742002-12-13 20:15:29 +00001099 }
1100 else
1101 {
1102 /* set metric +/-value check */
1103 if ((strncmp (arg, "+", 1) != 0
1104 && strncmp (arg, "-", 1) != 0)
1105 || (! all_digit (arg+1)))
1106 return NULL;
1107
paul94f2b392005-06-28 12:44:16 +00001108 larg = strtoul (arg+1, &endptr, 10);
1109 if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001110 return NULL;
paul94f2b392005-06-28 12:44:16 +00001111 metric = larg;
paul718e3742002-12-13 20:15:29 +00001112 }
1113
1114 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1115}
1116
1117/* Free route map's compiled `set metric' value. */
paul94f2b392005-06-28 12:44:16 +00001118static void
paul718e3742002-12-13 20:15:29 +00001119route_set_metric_free (void *rule)
1120{
1121 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1122}
1123
1124/* Set metric rule structure. */
1125struct route_map_rule_cmd route_set_metric_cmd =
1126{
1127 "metric",
1128 route_set_metric,
1129 route_set_metric_compile,
1130 route_set_metric_free,
1131};
1132
1133/* `set as-path prepend ASPATH' */
1134
1135/* For AS path prepend mechanism. */
paul94f2b392005-06-28 12:44:16 +00001136static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001137route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1138{
1139 struct aspath *aspath;
1140 struct aspath *new;
1141 struct bgp_info *binfo;
1142
1143 if (type == RMAP_BGP)
1144 {
1145 aspath = rule;
1146 binfo = object;
1147
1148 if (binfo->attr->aspath->refcnt)
1149 new = aspath_dup (binfo->attr->aspath);
1150 else
1151 new = binfo->attr->aspath;
1152
1153 aspath_prepend (aspath, new);
1154 binfo->attr->aspath = new;
1155 }
1156
1157 return RMAP_OKAY;
1158}
1159
1160/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001161static void *
paulfd79ac92004-10-13 05:06:08 +00001162route_set_aspath_prepend_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001163{
1164 struct aspath *aspath;
1165
1166 aspath = aspath_str2aspath (arg);
1167 if (! aspath)
1168 return NULL;
1169 return aspath;
1170}
1171
1172/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001173static void
paul718e3742002-12-13 20:15:29 +00001174route_set_aspath_prepend_free (void *rule)
1175{
1176 struct aspath *aspath = rule;
1177 aspath_free (aspath);
1178}
1179
1180/* Set metric rule structure. */
1181struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1182{
1183 "as-path prepend",
1184 route_set_aspath_prepend,
1185 route_set_aspath_prepend_compile,
1186 route_set_aspath_prepend_free,
1187};
1188
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001189/* `set as-path exclude ASn' */
1190
1191/* For ASN exclude mechanism.
1192 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1193 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1194 */
1195static route_map_result_t
1196route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
1197{
1198 struct aspath * new_path, * exclude_path;
1199 struct bgp_info *binfo;
1200
1201 if (type == RMAP_BGP)
1202 {
1203 exclude_path = rule;
1204 binfo = object;
1205 if (binfo->attr->aspath->refcnt)
1206 new_path = aspath_dup (binfo->attr->aspath);
1207 else
1208 new_path = binfo->attr->aspath;
1209 binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
1210 }
1211 return RMAP_OKAY;
1212}
1213
1214/* FIXME: consider using route_set_aspath_prepend_compile() and
1215 * route_set_aspath_prepend_free(), which two below function are
1216 * exact clones of.
1217 */
1218
1219/* Compile function for as-path exclude. */
1220static void *
1221route_set_aspath_exclude_compile (const char *arg)
1222{
1223 struct aspath *aspath;
1224
1225 aspath = aspath_str2aspath (arg);
1226 if (! aspath)
1227 return NULL;
1228 return aspath;
1229}
1230
1231static void
1232route_set_aspath_exclude_free (void *rule)
1233{
1234 struct aspath *aspath = rule;
1235 aspath_free (aspath);
1236}
1237
1238/* Set ASn exlude rule structure. */
1239struct route_map_rule_cmd route_set_aspath_exclude_cmd =
1240{
1241 "as-path exclude",
1242 route_set_aspath_exclude,
1243 route_set_aspath_exclude_compile,
1244 route_set_aspath_exclude_free,
1245};
1246
paul718e3742002-12-13 20:15:29 +00001247/* `set community COMMUNITY' */
1248struct rmap_com_set
1249{
1250 struct community *com;
1251 int additive;
1252 int none;
1253};
1254
1255/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001256static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001257route_set_community (void *rule, struct prefix *prefix,
1258 route_map_object_t type, void *object)
1259{
1260 struct rmap_com_set *rcs;
1261 struct bgp_info *binfo;
1262 struct attr *attr;
1263 struct community *new = NULL;
1264 struct community *old;
1265 struct community *merge;
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001266
paul718e3742002-12-13 20:15:29 +00001267 if (type == RMAP_BGP)
1268 {
1269 rcs = rule;
1270 binfo = object;
1271 attr = binfo->attr;
1272 old = attr->community;
1273
1274 /* "none" case. */
1275 if (rcs->none)
1276 {
1277 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1278 attr->community = NULL;
1279 return RMAP_OKAY;
1280 }
1281
1282 /* "additive" case. */
1283 if (rcs->additive && old)
1284 {
1285 merge = community_merge (community_dup (old), rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001286
1287 /* HACK: if the old community is not intern'd,
1288 * we should free it here, or all reference to it may be lost.
1289 * Really need to cleanup attribute caching sometime.
1290 */
1291 if (old->refcnt == 0)
1292 community_free (old);
paul718e3742002-12-13 20:15:29 +00001293 new = community_uniq_sort (merge);
1294 community_free (merge);
1295 }
1296 else
1297 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001298
1299 /* will be interned by caller if required */
Paul Jakma4a2035f2011-04-01 15:58:27 +01001300 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001301
paul718e3742002-12-13 20:15:29 +00001302 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1303 }
1304
1305 return RMAP_OKAY;
1306}
1307
1308/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001309static void *
paulfd79ac92004-10-13 05:06:08 +00001310route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001311{
1312 struct rmap_com_set *rcs;
1313 struct community *com = NULL;
1314 char *sp;
1315 int additive = 0;
1316 int none = 0;
1317
1318 if (strcmp (arg, "none") == 0)
1319 none = 1;
1320 else
1321 {
1322 sp = strstr (arg, "additive");
1323
1324 if (sp && sp > arg)
1325 {
1326 /* "additive" keyworkd is included. */
1327 additive = 1;
1328 *(sp - 1) = '\0';
1329 }
1330
1331 com = community_str2com (arg);
1332
1333 if (additive)
1334 *(sp - 1) = ' ';
1335
1336 if (! com)
1337 return NULL;
1338 }
1339
Stephen Hemminger393deb92008-08-18 14:13:29 -07001340 rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
Paul Jakma4a2035f2011-04-01 15:58:27 +01001341 rcs->com = com;
paul718e3742002-12-13 20:15:29 +00001342 rcs->additive = additive;
1343 rcs->none = none;
1344
1345 return rcs;
1346}
1347
1348/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001349static void
paul718e3742002-12-13 20:15:29 +00001350route_set_community_free (void *rule)
1351{
1352 struct rmap_com_set *rcs = rule;
1353
1354 if (rcs->com)
1355 community_free (rcs->com);
1356 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1357}
1358
1359/* Set community rule structure. */
1360struct route_map_rule_cmd route_set_community_cmd =
1361{
1362 "community",
1363 route_set_community,
1364 route_set_community_compile,
1365 route_set_community_free,
1366};
1367
hassofee6e4e2005-02-02 16:29:31 +00001368/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001369
1370/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001371static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001372route_set_community_delete (void *rule, struct prefix *prefix,
1373 route_map_object_t type, void *object)
1374{
1375 struct community_list *list;
1376 struct community *merge;
1377 struct community *new;
1378 struct community *old;
1379 struct bgp_info *binfo;
1380
1381 if (type == RMAP_BGP)
1382 {
1383 if (! rule)
1384 return RMAP_OKAY;
1385
1386 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001387 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001388 old = binfo->attr->community;
1389
1390 if (list && old)
1391 {
1392 merge = community_list_match_delete (community_dup (old), list);
1393 new = community_uniq_sort (merge);
1394 community_free (merge);
1395
Michael Lambert604a9b42010-09-13 11:48:11 -04001396 /* HACK: if the old community is not intern'd,
1397 * we should free it here, or all reference to it may be lost.
1398 * Really need to cleanup attribute caching sometime.
1399 */
1400 if (old->refcnt == 0)
1401 community_free (old);
1402
paul718e3742002-12-13 20:15:29 +00001403 if (new->size == 0)
1404 {
1405 binfo->attr->community = NULL;
1406 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1407 community_free (new);
1408 }
1409 else
1410 {
Paul Jakma4a2035f2011-04-01 15:58:27 +01001411 binfo->attr->community = new;
paul718e3742002-12-13 20:15:29 +00001412 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1413 }
1414 }
1415 }
1416
1417 return RMAP_OKAY;
1418}
1419
1420/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001421static void *
paulfd79ac92004-10-13 05:06:08 +00001422route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001423{
1424 char *p;
1425 char *str;
1426 int len;
1427
1428 p = strchr (arg, ' ');
1429 if (p)
1430 {
1431 len = p - arg;
1432 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1433 memcpy (str, arg, len);
1434 }
1435 else
1436 str = NULL;
1437
1438 return str;
1439}
1440
1441/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001442static void
paul718e3742002-12-13 20:15:29 +00001443route_set_community_delete_free (void *rule)
1444{
1445 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1446}
1447
1448/* Set community rule structure. */
1449struct route_map_rule_cmd route_set_community_delete_cmd =
1450{
1451 "comm-list",
1452 route_set_community_delete,
1453 route_set_community_delete_compile,
1454 route_set_community_delete_free,
1455};
1456
1457/* `set extcommunity rt 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_rt (void *rule, struct prefix *prefix,
1462 route_map_object_t type, void *object)
1463{
1464 struct ecommunity *ecom;
1465 struct ecommunity *new_ecom;
1466 struct ecommunity *old_ecom;
1467 struct bgp_info *bgp_info;
1468
1469 if (type == RMAP_BGP)
1470 {
1471 ecom = rule;
1472 bgp_info = object;
1473
1474 if (! ecom)
1475 return RMAP_OKAY;
1476
1477 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001478 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001479
1480 if (old_ecom)
1481 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1482 else
1483 new_ecom = ecommunity_dup (ecom);
1484
Paul Jakmafb982c22007-05-04 20:15:47 +00001485 bgp_info->attr->extra->ecommunity = new_ecom;
paul718e3742002-12-13 20:15:29 +00001486
hasso70601e02005-05-27 03:26:57 +00001487 if (old_ecom)
1488 ecommunity_free (old_ecom);
1489
paul718e3742002-12-13 20:15:29 +00001490 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1491 }
1492 return RMAP_OKAY;
1493}
1494
1495/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001496static void *
paulfd79ac92004-10-13 05:06:08 +00001497route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001498{
1499 struct ecommunity *ecom;
1500
1501 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1502 if (! ecom)
1503 return NULL;
1504 return ecom;
1505}
1506
1507/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001508static void
paul718e3742002-12-13 20:15:29 +00001509route_set_ecommunity_rt_free (void *rule)
1510{
1511 struct ecommunity *ecom = rule;
1512 ecommunity_free (ecom);
1513}
1514
1515/* Set community rule structure. */
1516struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1517{
1518 "extcommunity rt",
1519 route_set_ecommunity_rt,
1520 route_set_ecommunity_rt_compile,
1521 route_set_ecommunity_rt_free,
1522};
1523
1524/* `set extcommunity soo COMMUNITY' */
1525
1526/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001527static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001528route_set_ecommunity_soo (void *rule, struct prefix *prefix,
1529 route_map_object_t type, void *object)
1530{
1531 struct ecommunity *ecom;
1532 struct bgp_info *bgp_info;
1533
1534 if (type == RMAP_BGP)
1535 {
1536 ecom = rule;
1537 bgp_info = object;
1538
1539 if (! ecom)
1540 return RMAP_OKAY;
1541
1542 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
Paul Jakmafb982c22007-05-04 20:15:47 +00001543 (bgp_attr_extra_get (bgp_info->attr))->ecommunity = ecommunity_dup (ecom);
paul718e3742002-12-13 20:15:29 +00001544 }
1545 return RMAP_OKAY;
1546}
1547
1548/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001549static void *
paulfd79ac92004-10-13 05:06:08 +00001550route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001551{
1552 struct ecommunity *ecom;
1553
1554 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1555 if (! ecom)
1556 return NULL;
1557
1558 return ecom;
1559}
1560
1561/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001562static void
paul718e3742002-12-13 20:15:29 +00001563route_set_ecommunity_soo_free (void *rule)
1564{
1565 struct ecommunity *ecom = rule;
1566 ecommunity_free (ecom);
1567}
1568
1569/* Set community rule structure. */
1570struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1571{
1572 "extcommunity soo",
1573 route_set_ecommunity_soo,
1574 route_set_ecommunity_soo_compile,
1575 route_set_ecommunity_soo_free,
1576};
1577
1578/* `set origin ORIGIN' */
1579
1580/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001581static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001582route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1583{
1584 u_char *origin;
1585 struct bgp_info *bgp_info;
1586
1587 if (type == RMAP_BGP)
1588 {
1589 origin = rule;
1590 bgp_info = object;
1591
1592 bgp_info->attr->origin = *origin;
1593 }
1594
1595 return RMAP_OKAY;
1596}
1597
1598/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001599static void *
paulfd79ac92004-10-13 05:06:08 +00001600route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001601{
1602 u_char *origin;
1603
1604 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1605
1606 if (strcmp (arg, "igp") == 0)
1607 *origin = 0;
1608 else if (strcmp (arg, "egp") == 0)
1609 *origin = 1;
1610 else
1611 *origin = 2;
1612
1613 return origin;
1614}
1615
1616/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001617static void
paul718e3742002-12-13 20:15:29 +00001618route_set_origin_free (void *rule)
1619{
1620 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1621}
1622
1623/* Set metric rule structure. */
1624struct route_map_rule_cmd route_set_origin_cmd =
1625{
1626 "origin",
1627 route_set_origin,
1628 route_set_origin_compile,
1629 route_set_origin_free,
1630};
1631
1632/* `set atomic-aggregate' */
1633
1634/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001635static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001636route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1637 route_map_object_t type, void *object)
1638{
1639 struct bgp_info *bgp_info;
1640
1641 if (type == RMAP_BGP)
1642 {
1643 bgp_info = object;
1644 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1645 }
1646
1647 return RMAP_OKAY;
1648}
1649
1650/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001651static void *
paulfd79ac92004-10-13 05:06:08 +00001652route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001653{
1654 return (void *)1;
1655}
1656
1657/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001658static void
paul718e3742002-12-13 20:15:29 +00001659route_set_atomic_aggregate_free (void *rule)
1660{
1661 return;
1662}
1663
1664/* Set atomic aggregate rule structure. */
1665struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1666{
1667 "atomic-aggregate",
1668 route_set_atomic_aggregate,
1669 route_set_atomic_aggregate_compile,
1670 route_set_atomic_aggregate_free,
1671};
1672
1673/* `set aggregator as AS A.B.C.D' */
1674struct aggregator
1675{
1676 as_t as;
1677 struct in_addr address;
1678};
1679
paul94f2b392005-06-28 12:44:16 +00001680static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001681route_set_aggregator_as (void *rule, struct prefix *prefix,
1682 route_map_object_t type, void *object)
1683{
1684 struct bgp_info *bgp_info;
1685 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001686 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001687
1688 if (type == RMAP_BGP)
1689 {
1690 bgp_info = object;
1691 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001692 ae = bgp_attr_extra_get (bgp_info->attr);
1693
1694 ae->aggregator_as = aggregator->as;
1695 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001696 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1697 }
1698
1699 return RMAP_OKAY;
1700}
1701
paul94f2b392005-06-28 12:44:16 +00001702static void *
paulfd79ac92004-10-13 05:06:08 +00001703route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001704{
1705 struct aggregator *aggregator;
1706 char as[10];
1707 char address[20];
1708
Stephen Hemminger393deb92008-08-18 14:13:29 -07001709 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
paul718e3742002-12-13 20:15:29 +00001710 sscanf (arg, "%s %s", as, address);
1711
1712 aggregator->as = strtoul (as, NULL, 10);
1713 inet_aton (address, &aggregator->address);
1714
1715 return aggregator;
1716}
1717
paul94f2b392005-06-28 12:44:16 +00001718static void
paul718e3742002-12-13 20:15:29 +00001719route_set_aggregator_as_free (void *rule)
1720{
1721 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1722}
1723
1724struct route_map_rule_cmd route_set_aggregator_as_cmd =
1725{
1726 "aggregator as",
1727 route_set_aggregator_as,
1728 route_set_aggregator_as_compile,
1729 route_set_aggregator_as_free,
1730};
1731
1732#ifdef HAVE_IPV6
1733/* `match ipv6 address IP_ACCESS_LIST' */
1734
paul94f2b392005-06-28 12:44:16 +00001735static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001736route_match_ipv6_address (void *rule, struct prefix *prefix,
1737 route_map_object_t type, void *object)
1738{
1739 struct access_list *alist;
1740
1741 if (type == RMAP_BGP)
1742 {
1743 alist = access_list_lookup (AFI_IP6, (char *) rule);
1744 if (alist == NULL)
1745 return RMAP_NOMATCH;
1746
1747 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1748 RMAP_NOMATCH : RMAP_MATCH);
1749 }
1750 return RMAP_NOMATCH;
1751}
1752
paul94f2b392005-06-28 12:44:16 +00001753static void *
paulfd79ac92004-10-13 05:06:08 +00001754route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001755{
1756 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1757}
1758
paul94f2b392005-06-28 12:44:16 +00001759static void
paul718e3742002-12-13 20:15:29 +00001760route_match_ipv6_address_free (void *rule)
1761{
1762 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1763}
1764
1765/* Route map commands for ip address matching. */
1766struct route_map_rule_cmd route_match_ipv6_address_cmd =
1767{
1768 "ipv6 address",
1769 route_match_ipv6_address,
1770 route_match_ipv6_address_compile,
1771 route_match_ipv6_address_free
1772};
1773
1774/* `match ipv6 next-hop IP_ADDRESS' */
1775
paul94f2b392005-06-28 12:44:16 +00001776static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001777route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1778 route_map_object_t type, void *object)
1779{
1780 struct in6_addr *addr;
1781 struct bgp_info *bgp_info;
1782
1783 if (type == RMAP_BGP)
1784 {
1785 addr = rule;
1786 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001787
1788 if (!bgp_info->attr->extra)
1789 return RMAP_NOMATCH;
1790
1791 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, rule))
paul718e3742002-12-13 20:15:29 +00001792 return RMAP_MATCH;
1793
Paul Jakmafb982c22007-05-04 20:15:47 +00001794 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
1795 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, rule))
paul718e3742002-12-13 20:15:29 +00001796 return RMAP_MATCH;
1797
1798 return RMAP_NOMATCH;
1799 }
1800
1801 return RMAP_NOMATCH;
1802}
1803
paul94f2b392005-06-28 12:44:16 +00001804static void *
paulfd79ac92004-10-13 05:06:08 +00001805route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001806{
1807 struct in6_addr *address;
1808 int ret;
1809
1810 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1811
1812 ret = inet_pton (AF_INET6, arg, address);
1813 if (!ret)
1814 {
1815 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1816 return NULL;
1817 }
1818
1819 return address;
1820}
1821
paul94f2b392005-06-28 12:44:16 +00001822static void
paul718e3742002-12-13 20:15:29 +00001823route_match_ipv6_next_hop_free (void *rule)
1824{
1825 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1826}
1827
1828struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1829{
1830 "ipv6 next-hop",
1831 route_match_ipv6_next_hop,
1832 route_match_ipv6_next_hop_compile,
1833 route_match_ipv6_next_hop_free
1834};
1835
1836/* `match ipv6 address prefix-list PREFIX_LIST' */
1837
paul94f2b392005-06-28 12:44:16 +00001838static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001839route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1840 route_map_object_t type, void *object)
1841{
1842 struct prefix_list *plist;
1843
1844 if (type == RMAP_BGP)
1845 {
1846 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1847 if (plist == NULL)
1848 return RMAP_NOMATCH;
1849
1850 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1851 RMAP_NOMATCH : RMAP_MATCH);
1852 }
1853 return RMAP_NOMATCH;
1854}
1855
paul94f2b392005-06-28 12:44:16 +00001856static void *
paulfd79ac92004-10-13 05:06:08 +00001857route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001858{
1859 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1860}
1861
paul94f2b392005-06-28 12:44:16 +00001862static void
paul718e3742002-12-13 20:15:29 +00001863route_match_ipv6_address_prefix_list_free (void *rule)
1864{
1865 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1866}
1867
1868struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1869{
1870 "ipv6 address prefix-list",
1871 route_match_ipv6_address_prefix_list,
1872 route_match_ipv6_address_prefix_list_compile,
1873 route_match_ipv6_address_prefix_list_free
1874};
1875
1876/* `set ipv6 nexthop global IP_ADDRESS' */
1877
1878/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001879static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001880route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1881 route_map_object_t type, void *object)
1882{
1883 struct in6_addr *address;
1884 struct bgp_info *bgp_info;
1885
1886 if (type == RMAP_BGP)
1887 {
1888 /* Fetch routemap's rule information. */
1889 address = rule;
1890 bgp_info = object;
1891
1892 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001893 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00001894
1895 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001896 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1897 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00001898 }
1899
1900 return RMAP_OKAY;
1901}
1902
1903/* Route map `ip next-hop' compile function. Given string is converted
1904 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001905static void *
paulfd79ac92004-10-13 05:06:08 +00001906route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001907{
1908 int ret;
1909 struct in6_addr *address;
1910
1911 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1912
1913 ret = inet_pton (AF_INET6, arg, address);
1914
1915 if (ret == 0)
1916 {
1917 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1918 return NULL;
1919 }
1920
1921 return address;
1922}
1923
1924/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00001925static void
paul718e3742002-12-13 20:15:29 +00001926route_set_ipv6_nexthop_global_free (void *rule)
1927{
1928 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1929}
1930
1931/* Route map commands for ip nexthop set. */
1932struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
1933{
1934 "ipv6 next-hop global",
1935 route_set_ipv6_nexthop_global,
1936 route_set_ipv6_nexthop_global_compile,
1937 route_set_ipv6_nexthop_global_free
1938};
1939
1940/* `set ipv6 nexthop local IP_ADDRESS' */
1941
1942/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001943static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001944route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
1945 route_map_object_t type, void *object)
1946{
1947 struct in6_addr *address;
1948 struct bgp_info *bgp_info;
1949
1950 if (type == RMAP_BGP)
1951 {
1952 /* Fetch routemap's rule information. */
1953 address = rule;
1954 bgp_info = object;
1955
1956 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001957 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00001958
1959 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001960 if (bgp_info->attr->extra->mp_nexthop_len != 32)
1961 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00001962 }
1963
1964 return RMAP_OKAY;
1965}
1966
1967/* Route map `ip nexthop' compile function. Given string is converted
1968 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001969static void *
paulfd79ac92004-10-13 05:06:08 +00001970route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001971{
1972 int ret;
1973 struct in6_addr *address;
1974
1975 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1976
1977 ret = inet_pton (AF_INET6, arg, address);
1978
1979 if (ret == 0)
1980 {
1981 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1982 return NULL;
1983 }
1984
1985 return address;
1986}
1987
1988/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00001989static void
paul718e3742002-12-13 20:15:29 +00001990route_set_ipv6_nexthop_local_free (void *rule)
1991{
1992 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1993}
1994
1995/* Route map commands for ip nexthop set. */
1996struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
1997{
1998 "ipv6 next-hop local",
1999 route_set_ipv6_nexthop_local,
2000 route_set_ipv6_nexthop_local_compile,
2001 route_set_ipv6_nexthop_local_free
2002};
2003#endif /* HAVE_IPV6 */
2004
2005/* `set vpnv4 nexthop A.B.C.D' */
2006
paul94f2b392005-06-28 12:44:16 +00002007static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002008route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2009 route_map_object_t type, void *object)
2010{
2011 struct in_addr *address;
2012 struct bgp_info *bgp_info;
2013
2014 if (type == RMAP_BGP)
2015 {
2016 /* Fetch routemap's rule information. */
2017 address = rule;
2018 bgp_info = object;
2019
2020 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002021 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
paul718e3742002-12-13 20:15:29 +00002022 }
2023
2024 return RMAP_OKAY;
2025}
2026
paul94f2b392005-06-28 12:44:16 +00002027static void *
paulfd79ac92004-10-13 05:06:08 +00002028route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002029{
2030 int ret;
2031 struct in_addr *address;
2032
2033 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2034
2035 ret = inet_aton (arg, address);
2036
2037 if (ret == 0)
2038 {
2039 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2040 return NULL;
2041 }
2042
2043 return address;
2044}
2045
paul94f2b392005-06-28 12:44:16 +00002046static void
paul718e3742002-12-13 20:15:29 +00002047route_set_vpnv4_nexthop_free (void *rule)
2048{
2049 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2050}
2051
2052/* Route map commands for ip nexthop set. */
2053struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2054{
2055 "vpnv4 next-hop",
2056 route_set_vpnv4_nexthop,
2057 route_set_vpnv4_nexthop_compile,
2058 route_set_vpnv4_nexthop_free
2059};
2060
2061/* `set originator-id' */
2062
2063/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002064static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002065route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2066{
2067 struct in_addr *address;
2068 struct bgp_info *bgp_info;
2069
2070 if (type == RMAP_BGP)
2071 {
2072 address = rule;
2073 bgp_info = object;
2074
2075 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002076 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002077 }
2078
2079 return RMAP_OKAY;
2080}
2081
2082/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002083static void *
paulfd79ac92004-10-13 05:06:08 +00002084route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002085{
2086 int ret;
2087 struct in_addr *address;
2088
2089 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2090
2091 ret = inet_aton (arg, address);
2092
2093 if (ret == 0)
2094 {
2095 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2096 return NULL;
2097 }
2098
2099 return address;
2100}
2101
2102/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002103static void
paul718e3742002-12-13 20:15:29 +00002104route_set_originator_id_free (void *rule)
2105{
2106 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2107}
2108
2109/* Set metric rule structure. */
2110struct route_map_rule_cmd route_set_originator_id_cmd =
2111{
2112 "originator-id",
2113 route_set_originator_id,
2114 route_set_originator_id_compile,
2115 route_set_originator_id_free,
2116};
2117
2118/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002119static int
paul718e3742002-12-13 20:15:29 +00002120bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002121 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002122{
2123 int ret;
2124
2125 ret = route_map_add_match (index, command, arg);
2126 if (ret)
2127 {
2128 switch (ret)
2129 {
2130 case RMAP_RULE_MISSING:
2131 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2132 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002133 case RMAP_COMPILE_ERROR:
2134 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2135 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002136 }
2137 }
2138 return CMD_SUCCESS;
2139}
2140
2141/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002142static int
paul718e3742002-12-13 20:15:29 +00002143bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002144 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002145{
2146 int ret;
2147
2148 ret = route_map_delete_match (index, command, arg);
2149 if (ret)
2150 {
2151 switch (ret)
2152 {
2153 case RMAP_RULE_MISSING:
2154 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2155 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002156 case RMAP_COMPILE_ERROR:
2157 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2158 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002159 }
2160 }
2161 return CMD_SUCCESS;
2162}
2163
2164/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002165static int
paul718e3742002-12-13 20:15:29 +00002166bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002167 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002168{
2169 int ret;
2170
2171 ret = route_map_add_set (index, command, arg);
2172 if (ret)
2173 {
2174 switch (ret)
2175 {
2176 case RMAP_RULE_MISSING:
2177 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2178 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002179 case RMAP_COMPILE_ERROR:
2180 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2181 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002182 }
2183 }
2184 return CMD_SUCCESS;
2185}
2186
2187/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002188static int
paul718e3742002-12-13 20:15:29 +00002189bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002190 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002191{
2192 int ret;
2193
2194 ret = route_map_delete_set (index, command, arg);
2195 if (ret)
2196 {
2197 switch (ret)
2198 {
2199 case RMAP_RULE_MISSING:
2200 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2201 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002202 case RMAP_COMPILE_ERROR:
2203 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2204 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002205 }
2206 }
2207 return CMD_SUCCESS;
2208}
2209
2210/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002211static void
paulfd79ac92004-10-13 05:06:08 +00002212bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002213{
2214 int i;
2215 afi_t afi;
2216 safi_t safi;
2217 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002218 struct listnode *node, *nnode;
2219 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002220 struct bgp *bgp;
2221 struct peer *peer;
2222 struct peer_group *group;
2223 struct bgp_filter *filter;
2224 struct bgp_node *bn;
2225 struct bgp_static *bgp_static;
2226
2227 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002228 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002229 {
paul1eb8ef22005-04-07 07:30:20 +00002230 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002231 {
2232 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2233 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2234 {
2235 filter = &peer->filter[afi][safi];
2236
paulfee0f4c2004-09-13 05:12:46 +00002237 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002238 {
2239 if (filter->map[direct].name)
2240 filter->map[direct].map =
2241 route_map_lookup_by_name (filter->map[direct].name);
2242 else
2243 filter->map[direct].map = NULL;
2244 }
2245
2246 if (filter->usmap.name)
2247 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2248 else
2249 filter->usmap.map = NULL;
2250 }
2251 }
paul1eb8ef22005-04-07 07:30:20 +00002252 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002253 {
2254 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2255 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2256 {
2257 filter = &group->conf->filter[afi][safi];
2258
paulfee0f4c2004-09-13 05:12:46 +00002259 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002260 {
2261 if (filter->map[direct].name)
2262 filter->map[direct].map =
2263 route_map_lookup_by_name (filter->map[direct].name);
2264 else
2265 filter->map[direct].map = NULL;
2266 }
2267
2268 if (filter->usmap.name)
2269 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2270 else
2271 filter->usmap.map = NULL;
2272 }
2273 }
2274 }
2275
2276 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002277 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002278 {
paul1eb8ef22005-04-07 07:30:20 +00002279 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002280 {
2281 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2282 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2283 {
2284 if (peer->default_rmap[afi][safi].name)
2285 peer->default_rmap[afi][safi].map =
2286 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2287 else
2288 peer->default_rmap[afi][safi].map = NULL;
2289 }
2290 }
2291 }
2292
2293 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002294 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002295 {
2296 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2297 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2298 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2299 bn = bgp_route_next (bn))
2300 if ((bgp_static = bn->info) != NULL)
2301 {
2302 if (bgp_static->rmap.name)
2303 bgp_static->rmap.map =
2304 route_map_lookup_by_name (bgp_static->rmap.name);
2305 else
2306 bgp_static->rmap.map = NULL;
2307 }
2308 }
2309
2310 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002311 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002312 {
2313 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2314 {
2315 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2316 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2317 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2318#ifdef HAVE_IPV6
2319 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2320 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2321 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2322#endif /* HAVE_IPV6 */
2323 }
2324 }
2325}
2326
paulfee0f4c2004-09-13 05:12:46 +00002327DEFUN (match_peer,
2328 match_peer_cmd,
2329 "match peer (A.B.C.D|X:X::X:X)",
2330 MATCH_STR
2331 "Match peer address\n"
2332 "IPv6 address of peer\n"
2333 "IP address of peer\n")
2334{
2335 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2336}
2337
2338DEFUN (match_peer_local,
2339 match_peer_local_cmd,
2340 "match peer local",
2341 MATCH_STR
2342 "Match peer address\n"
2343 "Static or Redistributed routes\n")
2344{
2345 return bgp_route_match_add (vty, vty->index, "peer", NULL);
2346}
2347
2348DEFUN (no_match_peer,
2349 no_match_peer_cmd,
2350 "no match peer",
2351 NO_STR
2352 MATCH_STR
2353 "Match peer address\n")
2354{
2355 if (argc == 0)
2356 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2357
2358 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2359}
2360
2361ALIAS (no_match_peer,
2362 no_match_peer_val_cmd,
2363 "no match peer (A.B.C.D|X:X::X:X)",
2364 NO_STR
2365 MATCH_STR
2366 "Match peer address\n"
2367 "IPv6 address of peer\n"
2368 "IP address of peer\n")
2369
2370ALIAS (no_match_peer,
2371 no_match_peer_local_cmd,
2372 "no match peer local",
2373 NO_STR
2374 MATCH_STR
2375 "Match peer address\n"
2376 "Static or Redistributed routes\n")
2377
paul718e3742002-12-13 20:15:29 +00002378DEFUN (match_ip_address,
2379 match_ip_address_cmd,
2380 "match ip address (<1-199>|<1300-2699>|WORD)",
2381 MATCH_STR
2382 IP_STR
2383 "Match address of route\n"
2384 "IP access-list number\n"
2385 "IP access-list number (expanded range)\n"
2386 "IP Access-list name\n")
2387{
2388 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2389}
2390
2391DEFUN (no_match_ip_address,
2392 no_match_ip_address_cmd,
2393 "no match ip address",
2394 NO_STR
2395 MATCH_STR
2396 IP_STR
2397 "Match address of route\n")
2398{
2399 if (argc == 0)
2400 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2401
2402 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2403}
2404
2405ALIAS (no_match_ip_address,
2406 no_match_ip_address_val_cmd,
2407 "no match ip address (<1-199>|<1300-2699>|WORD)",
2408 NO_STR
2409 MATCH_STR
2410 IP_STR
2411 "Match address of route\n"
2412 "IP access-list number\n"
2413 "IP access-list number (expanded range)\n"
2414 "IP Access-list name\n")
2415
2416DEFUN (match_ip_next_hop,
2417 match_ip_next_hop_cmd,
2418 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2419 MATCH_STR
2420 IP_STR
2421 "Match next-hop address of route\n"
2422 "IP access-list number\n"
2423 "IP access-list number (expanded range)\n"
2424 "IP Access-list name\n")
2425{
2426 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2427}
2428
2429DEFUN (no_match_ip_next_hop,
2430 no_match_ip_next_hop_cmd,
2431 "no match ip next-hop",
2432 NO_STR
2433 MATCH_STR
2434 IP_STR
2435 "Match next-hop address of route\n")
2436{
2437 if (argc == 0)
2438 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2439
2440 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2441}
2442
2443ALIAS (no_match_ip_next_hop,
2444 no_match_ip_next_hop_val_cmd,
2445 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2446 NO_STR
2447 MATCH_STR
2448 IP_STR
2449 "Match next-hop address of route\n"
2450 "IP access-list number\n"
2451 "IP access-list number (expanded range)\n"
2452 "IP Access-list name\n")
2453
hassoc1643bb2005-02-02 16:43:17 +00002454DEFUN (match_ip_route_source,
2455 match_ip_route_source_cmd,
2456 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2457 MATCH_STR
2458 IP_STR
2459 "Match advertising source address of route\n"
2460 "IP access-list number\n"
2461 "IP access-list number (expanded range)\n"
2462 "IP standard access-list name\n")
2463{
2464 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2465}
2466
2467DEFUN (no_match_ip_route_source,
2468 no_match_ip_route_source_cmd,
2469 "no match ip route-source",
2470 NO_STR
2471 MATCH_STR
2472 IP_STR
2473 "Match advertising source address of route\n")
2474{
2475 if (argc == 0)
2476 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2477
2478 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2479}
2480
2481ALIAS (no_match_ip_route_source,
2482 no_match_ip_route_source_val_cmd,
2483 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2484 NO_STR
2485 MATCH_STR
2486 IP_STR
2487 "Match advertising source address of route\n"
2488 "IP access-list number\n"
2489 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002490 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002491
paul718e3742002-12-13 20:15:29 +00002492DEFUN (match_ip_address_prefix_list,
2493 match_ip_address_prefix_list_cmd,
2494 "match ip address prefix-list WORD",
2495 MATCH_STR
2496 IP_STR
2497 "Match address of route\n"
2498 "Match entries of prefix-lists\n"
2499 "IP prefix-list name\n")
2500{
2501 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2502}
2503
2504DEFUN (no_match_ip_address_prefix_list,
2505 no_match_ip_address_prefix_list_cmd,
2506 "no match ip address prefix-list",
2507 NO_STR
2508 MATCH_STR
2509 IP_STR
2510 "Match address of route\n"
2511 "Match entries of prefix-lists\n")
2512{
2513 if (argc == 0)
2514 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2515
2516 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2517}
2518
2519ALIAS (no_match_ip_address_prefix_list,
2520 no_match_ip_address_prefix_list_val_cmd,
2521 "no match ip address prefix-list WORD",
2522 NO_STR
2523 MATCH_STR
2524 IP_STR
2525 "Match address of route\n"
2526 "Match entries of prefix-lists\n"
2527 "IP prefix-list name\n")
2528
2529DEFUN (match_ip_next_hop_prefix_list,
2530 match_ip_next_hop_prefix_list_cmd,
2531 "match ip next-hop prefix-list WORD",
2532 MATCH_STR
2533 IP_STR
2534 "Match next-hop address of route\n"
2535 "Match entries of prefix-lists\n"
2536 "IP prefix-list name\n")
2537{
2538 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2539}
2540
2541DEFUN (no_match_ip_next_hop_prefix_list,
2542 no_match_ip_next_hop_prefix_list_cmd,
2543 "no match ip next-hop prefix-list",
2544 NO_STR
2545 MATCH_STR
2546 IP_STR
2547 "Match next-hop address of route\n"
2548 "Match entries of prefix-lists\n")
2549{
2550 if (argc == 0)
2551 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2552
2553 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2554}
2555
2556ALIAS (no_match_ip_next_hop_prefix_list,
2557 no_match_ip_next_hop_prefix_list_val_cmd,
2558 "no match ip next-hop prefix-list WORD",
2559 NO_STR
2560 MATCH_STR
2561 IP_STR
2562 "Match next-hop address of route\n"
2563 "Match entries of prefix-lists\n"
2564 "IP prefix-list name\n")
2565
hassoc1643bb2005-02-02 16:43:17 +00002566DEFUN (match_ip_route_source_prefix_list,
2567 match_ip_route_source_prefix_list_cmd,
2568 "match ip route-source prefix-list WORD",
2569 MATCH_STR
2570 IP_STR
2571 "Match advertising source address of route\n"
2572 "Match entries of prefix-lists\n"
2573 "IP prefix-list name\n")
2574{
2575 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2576}
2577
2578DEFUN (no_match_ip_route_source_prefix_list,
2579 no_match_ip_route_source_prefix_list_cmd,
2580 "no match ip route-source prefix-list",
2581 NO_STR
2582 MATCH_STR
2583 IP_STR
2584 "Match advertising source address of route\n"
2585 "Match entries of prefix-lists\n")
2586{
2587 if (argc == 0)
2588 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2589
2590 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2591}
2592
2593ALIAS (no_match_ip_route_source_prefix_list,
2594 no_match_ip_route_source_prefix_list_val_cmd,
2595 "no match ip route-source prefix-list WORD",
2596 NO_STR
2597 MATCH_STR
2598 IP_STR
2599 "Match advertising source address of route\n"
2600 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002601 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002602
paul718e3742002-12-13 20:15:29 +00002603DEFUN (match_metric,
2604 match_metric_cmd,
2605 "match metric <0-4294967295>",
2606 MATCH_STR
2607 "Match metric of route\n"
2608 "Metric value\n")
2609{
2610 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2611}
2612
2613DEFUN (no_match_metric,
2614 no_match_metric_cmd,
2615 "no match metric",
2616 NO_STR
2617 MATCH_STR
2618 "Match metric of route\n")
2619{
2620 if (argc == 0)
2621 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2622
2623 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2624}
2625
2626ALIAS (no_match_metric,
2627 no_match_metric_val_cmd,
2628 "no match metric <0-4294967295>",
2629 NO_STR
2630 MATCH_STR
2631 "Match metric of route\n"
2632 "Metric value\n")
2633
2634DEFUN (match_community,
2635 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002636 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002637 MATCH_STR
2638 "Match BGP community list\n"
2639 "Community-list number (standard)\n"
2640 "Community-list number (expanded)\n"
2641 "Community-list name\n")
2642{
2643 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2644}
2645
2646DEFUN (match_community_exact,
2647 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002648 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002649 MATCH_STR
2650 "Match BGP community list\n"
2651 "Community-list number (standard)\n"
2652 "Community-list number (expanded)\n"
2653 "Community-list name\n"
2654 "Do exact matching of communities\n")
2655{
2656 int ret;
2657 char *argstr;
2658
2659 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2660 strlen (argv[0]) + strlen ("exact-match") + 2);
2661
2662 sprintf (argstr, "%s exact-match", argv[0]);
2663
2664 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2665
2666 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2667
2668 return ret;
2669}
2670
2671DEFUN (no_match_community,
2672 no_match_community_cmd,
2673 "no match community",
2674 NO_STR
2675 MATCH_STR
2676 "Match BGP community list\n")
2677{
2678 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2679}
2680
2681ALIAS (no_match_community,
2682 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002683 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002684 NO_STR
2685 MATCH_STR
2686 "Match BGP community list\n"
2687 "Community-list number (standard)\n"
2688 "Community-list number (expanded)\n"
2689 "Community-list name\n")
2690
2691ALIAS (no_match_community,
2692 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002693 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002694 NO_STR
2695 MATCH_STR
2696 "Match BGP community list\n"
2697 "Community-list number (standard)\n"
2698 "Community-list number (expanded)\n"
2699 "Community-list name\n"
2700 "Do exact matching of communities\n")
2701
paul73ffb252003-04-19 15:49:49 +00002702DEFUN (match_ecommunity,
2703 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002704 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002705 MATCH_STR
2706 "Match BGP/VPN extended community list\n"
2707 "Extended community-list number (standard)\n"
2708 "Extended community-list number (expanded)\n"
2709 "Extended community-list name\n")
2710{
2711 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2712}
2713
2714DEFUN (no_match_ecommunity,
2715 no_match_ecommunity_cmd,
2716 "no match extcommunity",
2717 NO_STR
2718 MATCH_STR
2719 "Match BGP/VPN extended community list\n")
2720{
2721 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2722}
2723
2724ALIAS (no_match_ecommunity,
2725 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002726 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002727 NO_STR
2728 MATCH_STR
2729 "Match BGP/VPN extended community list\n"
2730 "Extended community-list number (standard)\n"
2731 "Extended community-list number (expanded)\n"
2732 "Extended community-list name\n")
2733
paul718e3742002-12-13 20:15:29 +00002734DEFUN (match_aspath,
2735 match_aspath_cmd,
2736 "match as-path WORD",
2737 MATCH_STR
2738 "Match BGP AS path list\n"
2739 "AS path access-list name\n")
2740{
2741 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2742}
2743
2744DEFUN (no_match_aspath,
2745 no_match_aspath_cmd,
2746 "no match as-path",
2747 NO_STR
2748 MATCH_STR
2749 "Match BGP AS path list\n")
2750{
2751 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2752}
2753
2754ALIAS (no_match_aspath,
2755 no_match_aspath_val_cmd,
2756 "no match as-path WORD",
2757 NO_STR
2758 MATCH_STR
2759 "Match BGP AS path list\n"
2760 "AS path access-list name\n")
2761
2762DEFUN (match_origin,
2763 match_origin_cmd,
2764 "match origin (egp|igp|incomplete)",
2765 MATCH_STR
2766 "BGP origin code\n"
2767 "remote EGP\n"
2768 "local IGP\n"
2769 "unknown heritage\n")
2770{
2771 if (strncmp (argv[0], "igp", 2) == 0)
2772 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2773 if (strncmp (argv[0], "egp", 1) == 0)
2774 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2775 if (strncmp (argv[0], "incomplete", 2) == 0)
2776 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2777
2778 return CMD_WARNING;
2779}
2780
2781DEFUN (no_match_origin,
2782 no_match_origin_cmd,
2783 "no match origin",
2784 NO_STR
2785 MATCH_STR
2786 "BGP origin code\n")
2787{
2788 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2789}
2790
2791ALIAS (no_match_origin,
2792 no_match_origin_val_cmd,
2793 "no match origin (egp|igp|incomplete)",
2794 NO_STR
2795 MATCH_STR
2796 "BGP origin code\n"
2797 "remote EGP\n"
2798 "local IGP\n"
2799 "unknown heritage\n")
2800
2801DEFUN (set_ip_nexthop,
2802 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002803 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002804 SET_STR
2805 IP_STR
2806 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002807 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002808{
2809 union sockunion su;
2810 int ret;
2811
2812 ret = str2sockunion (argv[0], &su);
2813 if (ret < 0)
2814 {
2815 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2816 return CMD_WARNING;
2817 }
2818
2819 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2820}
2821
paulaf5cd0a2003-11-02 07:24:40 +00002822DEFUN (set_ip_nexthop_peer,
2823 set_ip_nexthop_peer_cmd,
2824 "set ip next-hop peer-address",
2825 SET_STR
2826 IP_STR
2827 "Next hop address\n"
2828 "Use peer address (for BGP only)\n")
2829{
2830 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2831}
2832
paul94f2b392005-06-28 12:44:16 +00002833DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00002834 no_set_ip_nexthop_peer_cmd,
2835 "no set ip next-hop peer-address",
2836 NO_STR
2837 SET_STR
2838 IP_STR
2839 "Next hop address\n"
2840 "Use peer address (for BGP only)\n")
2841{
2842 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2843}
2844
2845
paul718e3742002-12-13 20:15:29 +00002846DEFUN (no_set_ip_nexthop,
2847 no_set_ip_nexthop_cmd,
2848 "no set ip next-hop",
2849 NO_STR
2850 SET_STR
paul718e3742002-12-13 20:15:29 +00002851 "Next hop address\n")
2852{
paulaf5cd0a2003-11-02 07:24:40 +00002853 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002854 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2855
2856 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2857}
2858
2859ALIAS (no_set_ip_nexthop,
2860 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002861 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002862 NO_STR
2863 SET_STR
2864 IP_STR
2865 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002866 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002867
2868DEFUN (set_metric,
2869 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002870 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002871 SET_STR
2872 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002873 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002874{
2875 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2876}
2877
paul73ffb252003-04-19 15:49:49 +00002878ALIAS (set_metric,
2879 set_metric_addsub_cmd,
2880 "set metric <+/-metric>",
2881 SET_STR
2882 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00002883 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00002884
paul718e3742002-12-13 20:15:29 +00002885DEFUN (no_set_metric,
2886 no_set_metric_cmd,
2887 "no set metric",
2888 NO_STR
2889 SET_STR
2890 "Metric value for destination routing protocol\n")
2891{
2892 if (argc == 0)
2893 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
2894
2895 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
2896}
2897
2898ALIAS (no_set_metric,
2899 no_set_metric_val_cmd,
2900 "no set metric <0-4294967295>",
2901 NO_STR
2902 SET_STR
2903 "Metric value for destination routing protocol\n"
2904 "Metric value\n")
2905
2906DEFUN (set_local_pref,
2907 set_local_pref_cmd,
2908 "set local-preference <0-4294967295>",
2909 SET_STR
2910 "BGP local preference path attribute\n"
2911 "Preference value\n")
2912{
2913 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
2914}
2915
2916DEFUN (no_set_local_pref,
2917 no_set_local_pref_cmd,
2918 "no set local-preference",
2919 NO_STR
2920 SET_STR
2921 "BGP local preference path attribute\n")
2922{
2923 if (argc == 0)
2924 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
2925
2926 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
2927}
2928
2929ALIAS (no_set_local_pref,
2930 no_set_local_pref_val_cmd,
2931 "no set local-preference <0-4294967295>",
2932 NO_STR
2933 SET_STR
2934 "BGP local preference path attribute\n"
2935 "Preference value\n")
2936
2937DEFUN (set_weight,
2938 set_weight_cmd,
2939 "set weight <0-4294967295>",
2940 SET_STR
2941 "BGP weight for routing table\n"
2942 "Weight value\n")
2943{
2944 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
2945}
2946
2947DEFUN (no_set_weight,
2948 no_set_weight_cmd,
2949 "no set weight",
2950 NO_STR
2951 SET_STR
2952 "BGP weight for routing table\n")
2953{
2954 if (argc == 0)
2955 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
2956
2957 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
2958}
2959
2960ALIAS (no_set_weight,
2961 no_set_weight_val_cmd,
2962 "no set weight <0-4294967295>",
2963 NO_STR
2964 SET_STR
2965 "BGP weight for routing table\n"
2966 "Weight value\n")
2967
2968DEFUN (set_aspath_prepend,
2969 set_aspath_prepend_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04002970 "set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00002971 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00002972 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00002973 "Prepend to the as-path\n"
2974 "AS number\n")
2975{
2976 int ret;
2977 char *str;
2978
2979 str = argv_concat (argv, argc, 0);
2980 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
2981 XFREE (MTYPE_TMP, str);
2982
2983 return ret;
2984}
2985
2986DEFUN (no_set_aspath_prepend,
2987 no_set_aspath_prepend_cmd,
2988 "no set as-path prepend",
2989 NO_STR
2990 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00002991 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00002992 "Prepend to the as-path\n")
2993{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00002994 int ret;
2995 char *str;
2996
2997 if (argc == 0)
2998 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
2999
3000 str = argv_concat (argv, argc, 0);
3001 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3002 XFREE (MTYPE_TMP, str);
3003 return ret;
paul718e3742002-12-13 20:15:29 +00003004}
3005
3006ALIAS (no_set_aspath_prepend,
3007 no_set_aspath_prepend_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003008 "no set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003009 NO_STR
3010 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003011 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003012 "Prepend to the as-path\n"
3013 "AS number\n")
3014
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003015DEFUN (set_aspath_exclude,
3016 set_aspath_exclude_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003017 "set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003018 SET_STR
3019 "Transform BGP AS-path attribute\n"
3020 "Exclude from the as-path\n"
3021 "AS number\n")
3022{
3023 int ret;
3024 char *str;
3025
3026 str = argv_concat (argv, argc, 0);
3027 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3028 XFREE (MTYPE_TMP, str);
3029 return ret;
3030}
3031
3032DEFUN (no_set_aspath_exclude,
3033 no_set_aspath_exclude_cmd,
3034 "no set as-path exclude",
3035 NO_STR
3036 SET_STR
3037 "Transform BGP AS_PATH attribute\n"
3038 "Exclude from the as-path\n")
3039{
3040 int ret;
3041 char *str;
3042
3043 if (argc == 0)
3044 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3045
3046 str = argv_concat (argv, argc, 0);
3047 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3048 XFREE (MTYPE_TMP, str);
3049 return ret;
3050}
3051
3052ALIAS (no_set_aspath_exclude,
3053 no_set_aspath_exclude_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003054 "no set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003055 NO_STR
3056 SET_STR
3057 "Transform BGP AS_PATH attribute\n"
3058 "Exclude from the as-path\n"
3059 "AS number\n")
3060
paul718e3742002-12-13 20:15:29 +00003061DEFUN (set_community,
3062 set_community_cmd,
3063 "set community .AA:NN",
3064 SET_STR
3065 "BGP community attribute\n"
3066 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3067{
3068 int i;
3069 int first = 0;
3070 int additive = 0;
3071 struct buffer *b;
3072 struct community *com = NULL;
3073 char *str;
3074 char *argstr;
3075 int ret;
3076
3077 b = buffer_new (1024);
3078
3079 for (i = 0; i < argc; i++)
3080 {
3081 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3082 {
3083 additive = 1;
3084 continue;
3085 }
3086
3087 if (first)
3088 buffer_putc (b, ' ');
3089 else
3090 first = 1;
3091
3092 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3093 {
3094 buffer_putstr (b, "internet");
3095 continue;
3096 }
3097 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3098 {
3099 buffer_putstr (b, "local-AS");
3100 continue;
3101 }
3102 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3103 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3104 {
3105 buffer_putstr (b, "no-advertise");
3106 continue;
3107 }
3108 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3109 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3110 {
3111 buffer_putstr (b, "no-export");
3112 continue;
3113 }
3114 buffer_putstr (b, argv[i]);
3115 }
3116 buffer_putc (b, '\0');
3117
3118 /* Fetch result string then compile it to communities attribute. */
3119 str = buffer_getstr (b);
3120 buffer_free (b);
3121
3122 if (str)
3123 {
3124 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003125 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003126 }
3127
3128 /* Can't compile user input into communities attribute. */
3129 if (! com)
3130 {
3131 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3132 return CMD_WARNING;
3133 }
3134
3135 /* Set communites attribute string. */
3136 str = community_str (com);
3137
3138 if (additive)
3139 {
3140 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3141 strcpy (argstr, str);
3142 strcpy (argstr + strlen (str), " additive");
3143 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3144 XFREE (MTYPE_TMP, argstr);
3145 }
3146 else
3147 ret = bgp_route_set_add (vty, vty->index, "community", str);
3148
3149 community_free (com);
3150
3151 return ret;
3152}
3153
3154DEFUN (set_community_none,
3155 set_community_none_cmd,
3156 "set community none",
3157 SET_STR
3158 "BGP community attribute\n"
3159 "No community attribute\n")
3160{
3161 return bgp_route_set_add (vty, vty->index, "community", "none");
3162}
3163
3164DEFUN (no_set_community,
3165 no_set_community_cmd,
3166 "no set community",
3167 NO_STR
3168 SET_STR
3169 "BGP community attribute\n")
3170{
3171 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3172}
3173
3174ALIAS (no_set_community,
3175 no_set_community_val_cmd,
3176 "no set community .AA:NN",
3177 NO_STR
3178 SET_STR
3179 "BGP community attribute\n"
3180 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3181
3182ALIAS (no_set_community,
3183 no_set_community_none_cmd,
3184 "no set community none",
3185 NO_STR
3186 SET_STR
3187 "BGP community attribute\n"
3188 "No community attribute\n")
3189
3190DEFUN (set_community_delete,
3191 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003192 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003193 SET_STR
3194 "set BGP community list (for deletion)\n"
3195 "Community-list number (standard)\n"
3196 "Communitly-list number (expanded)\n"
3197 "Community-list name\n"
3198 "Delete matching communities\n")
3199{
3200 char *str;
3201
3202 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3203 strcpy (str, argv[0]);
3204 strcpy (str + strlen (argv[0]), " delete");
3205
3206 bgp_route_set_add (vty, vty->index, "comm-list", str);
3207
3208 XFREE (MTYPE_TMP, str);
3209 return CMD_SUCCESS;
3210}
3211
3212DEFUN (no_set_community_delete,
3213 no_set_community_delete_cmd,
3214 "no set comm-list",
3215 NO_STR
3216 SET_STR
3217 "set BGP community list (for deletion)\n")
3218{
3219 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3220}
3221
3222ALIAS (no_set_community_delete,
3223 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003224 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003225 NO_STR
3226 SET_STR
3227 "set BGP community list (for deletion)\n"
3228 "Community-list number (standard)\n"
3229 "Communitly-list number (expanded)\n"
3230 "Community-list name\n"
3231 "Delete matching communities\n")
3232
3233DEFUN (set_ecommunity_rt,
3234 set_ecommunity_rt_cmd,
3235 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3236 SET_STR
3237 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003238 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003239 "VPN extended community\n")
3240{
3241 int ret;
3242 char *str;
3243
3244 str = argv_concat (argv, argc, 0);
3245 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3246 XFREE (MTYPE_TMP, str);
3247
3248 return ret;
3249}
3250
3251DEFUN (no_set_ecommunity_rt,
3252 no_set_ecommunity_rt_cmd,
3253 "no set extcommunity rt",
3254 NO_STR
3255 SET_STR
3256 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003257 "Route Target extended community\n")
paul718e3742002-12-13 20:15:29 +00003258{
3259 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3260}
3261
3262ALIAS (no_set_ecommunity_rt,
3263 no_set_ecommunity_rt_val_cmd,
3264 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3265 NO_STR
3266 SET_STR
3267 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003268 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003269 "VPN extended community\n")
3270
3271DEFUN (set_ecommunity_soo,
3272 set_ecommunity_soo_cmd,
3273 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3274 SET_STR
3275 "BGP extended community attribute\n"
3276 "Site-of-Origin extended community\n"
3277 "VPN extended community\n")
3278{
3279 int ret;
3280 char *str;
3281
3282 str = argv_concat (argv, argc, 0);
3283 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3284 XFREE (MTYPE_TMP, str);
3285 return ret;
3286}
3287
3288DEFUN (no_set_ecommunity_soo,
3289 no_set_ecommunity_soo_cmd,
3290 "no set extcommunity soo",
3291 NO_STR
3292 SET_STR
3293 "BGP extended community attribute\n"
3294 "Site-of-Origin extended community\n")
3295{
3296 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3297}
3298
3299ALIAS (no_set_ecommunity_soo,
3300 no_set_ecommunity_soo_val_cmd,
3301 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3302 NO_STR
3303 SET_STR
3304 "BGP extended community attribute\n"
3305 "Site-of-Origin extended community\n"
3306 "VPN extended community\n")
3307
3308DEFUN (set_origin,
3309 set_origin_cmd,
3310 "set origin (egp|igp|incomplete)",
3311 SET_STR
3312 "BGP origin code\n"
3313 "remote EGP\n"
3314 "local IGP\n"
3315 "unknown heritage\n")
3316{
3317 if (strncmp (argv[0], "igp", 2) == 0)
3318 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3319 if (strncmp (argv[0], "egp", 1) == 0)
3320 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3321 if (strncmp (argv[0], "incomplete", 2) == 0)
3322 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3323
3324 return CMD_WARNING;
3325}
3326
3327DEFUN (no_set_origin,
3328 no_set_origin_cmd,
3329 "no set origin",
3330 NO_STR
3331 SET_STR
3332 "BGP origin code\n")
3333{
3334 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3335}
3336
3337ALIAS (no_set_origin,
3338 no_set_origin_val_cmd,
3339 "no set origin (egp|igp|incomplete)",
3340 NO_STR
3341 SET_STR
3342 "BGP origin code\n"
3343 "remote EGP\n"
3344 "local IGP\n"
3345 "unknown heritage\n")
3346
3347DEFUN (set_atomic_aggregate,
3348 set_atomic_aggregate_cmd,
3349 "set atomic-aggregate",
3350 SET_STR
3351 "BGP atomic aggregate attribute\n" )
3352{
3353 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3354}
3355
3356DEFUN (no_set_atomic_aggregate,
3357 no_set_atomic_aggregate_cmd,
3358 "no set atomic-aggregate",
3359 NO_STR
3360 SET_STR
3361 "BGP atomic aggregate attribute\n" )
3362{
3363 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3364}
3365
3366DEFUN (set_aggregator_as,
3367 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003368 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003369 SET_STR
3370 "BGP aggregator attribute\n"
3371 "AS number of aggregator\n"
3372 "AS number\n"
3373 "IP address of aggregator\n")
3374{
3375 int ret;
3376 as_t as;
3377 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003378 char *argstr;
3379
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003380 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003381
paul718e3742002-12-13 20:15:29 +00003382 ret = inet_aton (argv[1], &address);
3383 if (ret == 0)
3384 {
3385 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3386 return CMD_WARNING;
3387 }
3388
3389 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3390 strlen (argv[0]) + strlen (argv[1]) + 2);
3391
3392 sprintf (argstr, "%s %s", argv[0], argv[1]);
3393
3394 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3395
3396 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3397
3398 return ret;
3399}
3400
3401DEFUN (no_set_aggregator_as,
3402 no_set_aggregator_as_cmd,
3403 "no set aggregator as",
3404 NO_STR
3405 SET_STR
3406 "BGP aggregator attribute\n"
3407 "AS number of aggregator\n")
3408{
3409 int ret;
3410 as_t as;
3411 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003412 char *argstr;
3413
3414 if (argv == 0)
3415 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3416
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003417 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003418
3419 ret = inet_aton (argv[1], &address);
3420 if (ret == 0)
3421 {
3422 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3423 return CMD_WARNING;
3424 }
3425
3426 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3427 strlen (argv[0]) + strlen (argv[1]) + 2);
3428
3429 sprintf (argstr, "%s %s", argv[0], argv[1]);
3430
3431 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3432
3433 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3434
3435 return ret;
3436}
3437
3438ALIAS (no_set_aggregator_as,
3439 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003440 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003441 NO_STR
3442 SET_STR
3443 "BGP aggregator attribute\n"
3444 "AS number of aggregator\n"
3445 "AS number\n"
3446 "IP address of aggregator\n")
3447
3448
3449#ifdef HAVE_IPV6
3450DEFUN (match_ipv6_address,
3451 match_ipv6_address_cmd,
3452 "match ipv6 address WORD",
3453 MATCH_STR
3454 IPV6_STR
3455 "Match IPv6 address of route\n"
3456 "IPv6 access-list name\n")
3457{
3458 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3459}
3460
3461DEFUN (no_match_ipv6_address,
3462 no_match_ipv6_address_cmd,
3463 "no match ipv6 address WORD",
3464 NO_STR
3465 MATCH_STR
3466 IPV6_STR
3467 "Match IPv6 address of route\n"
3468 "IPv6 access-list name\n")
3469{
3470 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3471}
3472
3473DEFUN (match_ipv6_next_hop,
3474 match_ipv6_next_hop_cmd,
3475 "match ipv6 next-hop X:X::X:X",
3476 MATCH_STR
3477 IPV6_STR
3478 "Match IPv6 next-hop address of route\n"
3479 "IPv6 address of next hop\n")
3480{
3481 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3482}
3483
3484DEFUN (no_match_ipv6_next_hop,
3485 no_match_ipv6_next_hop_cmd,
3486 "no match ipv6 next-hop X:X::X:X",
3487 NO_STR
3488 MATCH_STR
3489 IPV6_STR
3490 "Match IPv6 next-hop address of route\n"
3491 "IPv6 address of next hop\n")
3492{
3493 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3494}
3495
3496DEFUN (match_ipv6_address_prefix_list,
3497 match_ipv6_address_prefix_list_cmd,
3498 "match ipv6 address prefix-list WORD",
3499 MATCH_STR
3500 IPV6_STR
3501 "Match address of route\n"
3502 "Match entries of prefix-lists\n"
3503 "IP prefix-list name\n")
3504{
3505 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3506}
3507
3508DEFUN (no_match_ipv6_address_prefix_list,
3509 no_match_ipv6_address_prefix_list_cmd,
3510 "no match ipv6 address prefix-list WORD",
3511 NO_STR
3512 MATCH_STR
3513 IPV6_STR
3514 "Match address of route\n"
3515 "Match entries of prefix-lists\n"
3516 "IP prefix-list name\n")
3517{
3518 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3519}
3520
3521DEFUN (set_ipv6_nexthop_global,
3522 set_ipv6_nexthop_global_cmd,
3523 "set ipv6 next-hop global X:X::X:X",
3524 SET_STR
3525 IPV6_STR
3526 "IPv6 next-hop address\n"
3527 "IPv6 global address\n"
3528 "IPv6 address of next hop\n")
3529{
3530 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3531}
3532
3533DEFUN (no_set_ipv6_nexthop_global,
3534 no_set_ipv6_nexthop_global_cmd,
3535 "no set ipv6 next-hop global",
3536 NO_STR
3537 SET_STR
3538 IPV6_STR
3539 "IPv6 next-hop address\n"
3540 "IPv6 global address\n")
3541{
3542 if (argc == 0)
3543 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3544
3545 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3546}
3547
3548ALIAS (no_set_ipv6_nexthop_global,
3549 no_set_ipv6_nexthop_global_val_cmd,
3550 "no set ipv6 next-hop global X:X::X:X",
3551 NO_STR
3552 SET_STR
3553 IPV6_STR
3554 "IPv6 next-hop address\n"
3555 "IPv6 global address\n"
3556 "IPv6 address of next hop\n")
3557
3558DEFUN (set_ipv6_nexthop_local,
3559 set_ipv6_nexthop_local_cmd,
3560 "set ipv6 next-hop local X:X::X:X",
3561 SET_STR
3562 IPV6_STR
3563 "IPv6 next-hop address\n"
3564 "IPv6 local address\n"
3565 "IPv6 address of next hop\n")
3566{
3567 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3568}
3569
3570DEFUN (no_set_ipv6_nexthop_local,
3571 no_set_ipv6_nexthop_local_cmd,
3572 "no set ipv6 next-hop local",
3573 NO_STR
3574 SET_STR
3575 IPV6_STR
3576 "IPv6 next-hop address\n"
3577 "IPv6 local address\n")
3578{
3579 if (argc == 0)
3580 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3581
3582 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3583}
3584
3585ALIAS (no_set_ipv6_nexthop_local,
3586 no_set_ipv6_nexthop_local_val_cmd,
3587 "no set ipv6 next-hop local X:X::X:X",
3588 NO_STR
3589 SET_STR
3590 IPV6_STR
3591 "IPv6 next-hop address\n"
3592 "IPv6 local address\n"
3593 "IPv6 address of next hop\n")
3594#endif /* HAVE_IPV6 */
3595
3596DEFUN (set_vpnv4_nexthop,
3597 set_vpnv4_nexthop_cmd,
3598 "set vpnv4 next-hop A.B.C.D",
3599 SET_STR
3600 "VPNv4 information\n"
3601 "VPNv4 next-hop address\n"
3602 "IP address of next hop\n")
3603{
3604 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3605}
3606
3607DEFUN (no_set_vpnv4_nexthop,
3608 no_set_vpnv4_nexthop_cmd,
3609 "no set vpnv4 next-hop",
3610 NO_STR
3611 SET_STR
3612 "VPNv4 information\n"
3613 "VPNv4 next-hop address\n")
3614{
3615 if (argc == 0)
3616 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3617
3618 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3619}
3620
3621ALIAS (no_set_vpnv4_nexthop,
3622 no_set_vpnv4_nexthop_val_cmd,
3623 "no set vpnv4 next-hop A.B.C.D",
3624 NO_STR
3625 SET_STR
3626 "VPNv4 information\n"
3627 "VPNv4 next-hop address\n"
3628 "IP address of next hop\n")
3629
3630DEFUN (set_originator_id,
3631 set_originator_id_cmd,
3632 "set originator-id A.B.C.D",
3633 SET_STR
3634 "BGP originator ID attribute\n"
3635 "IP address of originator\n")
3636{
3637 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3638}
3639
3640DEFUN (no_set_originator_id,
3641 no_set_originator_id_cmd,
3642 "no set originator-id",
3643 NO_STR
3644 SET_STR
3645 "BGP originator ID attribute\n")
3646{
3647 if (argc == 0)
3648 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3649
3650 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3651}
3652
3653ALIAS (no_set_originator_id,
3654 no_set_originator_id_val_cmd,
3655 "no set originator-id A.B.C.D",
3656 NO_STR
3657 SET_STR
3658 "BGP originator ID attribute\n"
3659 "IP address of originator\n")
3660
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003661DEFUN_DEPRECATED (set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003662 set_pathlimit_ttl_cmd,
3663 "set pathlimit ttl <1-255>",
3664 SET_STR
3665 "BGP AS-Pathlimit attribute\n"
3666 "Set AS-Path Hop-count TTL\n")
3667{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003668 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003669}
3670
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003671DEFUN_DEPRECATED (no_set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003672 no_set_pathlimit_ttl_cmd,
3673 "no set pathlimit ttl",
3674 NO_STR
3675 SET_STR
3676 "BGP AS-Pathlimit attribute\n"
3677 "Set AS-Path Hop-count TTL\n")
3678{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003679 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003680}
3681
3682ALIAS (no_set_pathlimit_ttl,
3683 no_set_pathlimit_ttl_val_cmd,
3684 "no set pathlimit ttl <1-255>",
3685 NO_STR
3686 MATCH_STR
3687 "BGP AS-Pathlimit attribute\n"
3688 "Set AS-Path Hop-count TTL\n")
3689
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003690DEFUN_DEPRECATED (match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003691 match_pathlimit_as_cmd,
3692 "match pathlimit as <1-65535>",
3693 MATCH_STR
3694 "BGP AS-Pathlimit attribute\n"
3695 "Match Pathlimit AS number\n")
3696{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003697 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003698}
3699
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003700DEFUN_DEPRECATED (no_match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003701 no_match_pathlimit_as_cmd,
3702 "no match pathlimit as",
3703 NO_STR
3704 MATCH_STR
3705 "BGP AS-Pathlimit attribute\n"
3706 "Match Pathlimit AS number\n")
3707{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003708 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003709}
3710
3711ALIAS (no_match_pathlimit_as,
3712 no_match_pathlimit_as_val_cmd,
3713 "no match pathlimit as <1-65535>",
3714 NO_STR
3715 MATCH_STR
3716 "BGP AS-Pathlimit attribute\n"
3717 "Match Pathlimit ASN\n")
3718
paul718e3742002-12-13 20:15:29 +00003719
3720/* Initialization of route map. */
3721void
paul94f2b392005-06-28 12:44:16 +00003722bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003723{
3724 route_map_init ();
3725 route_map_init_vty ();
3726 route_map_add_hook (bgp_route_map_update);
3727 route_map_delete_hook (bgp_route_map_update);
3728
paulfee0f4c2004-09-13 05:12:46 +00003729 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003730 route_map_install_match (&route_match_ip_address_cmd);
3731 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003732 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003733 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3734 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003735 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003736 route_map_install_match (&route_match_aspath_cmd);
3737 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003738 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003739 route_map_install_match (&route_match_metric_cmd);
3740 route_map_install_match (&route_match_origin_cmd);
3741
3742 route_map_install_set (&route_set_ip_nexthop_cmd);
3743 route_map_install_set (&route_set_local_pref_cmd);
3744 route_map_install_set (&route_set_weight_cmd);
3745 route_map_install_set (&route_set_metric_cmd);
3746 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003747 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003748 route_map_install_set (&route_set_origin_cmd);
3749 route_map_install_set (&route_set_atomic_aggregate_cmd);
3750 route_map_install_set (&route_set_aggregator_as_cmd);
3751 route_map_install_set (&route_set_community_cmd);
3752 route_map_install_set (&route_set_community_delete_cmd);
3753 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3754 route_map_install_set (&route_set_originator_id_cmd);
3755 route_map_install_set (&route_set_ecommunity_rt_cmd);
3756 route_map_install_set (&route_set_ecommunity_soo_cmd);
3757
paulfee0f4c2004-09-13 05:12:46 +00003758 install_element (RMAP_NODE, &match_peer_cmd);
3759 install_element (RMAP_NODE, &match_peer_local_cmd);
3760 install_element (RMAP_NODE, &no_match_peer_cmd);
3761 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3762 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003763 install_element (RMAP_NODE, &match_ip_address_cmd);
3764 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3765 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3766 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3767 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3768 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003769 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3770 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3771 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003772
3773 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3774 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3775 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3776 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3777 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3778 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003779 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3780 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3781 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003782
3783 install_element (RMAP_NODE, &match_aspath_cmd);
3784 install_element (RMAP_NODE, &no_match_aspath_cmd);
3785 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3786 install_element (RMAP_NODE, &match_metric_cmd);
3787 install_element (RMAP_NODE, &no_match_metric_cmd);
3788 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3789 install_element (RMAP_NODE, &match_community_cmd);
3790 install_element (RMAP_NODE, &match_community_exact_cmd);
3791 install_element (RMAP_NODE, &no_match_community_cmd);
3792 install_element (RMAP_NODE, &no_match_community_val_cmd);
3793 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003794 install_element (RMAP_NODE, &match_ecommunity_cmd);
3795 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3796 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003797 install_element (RMAP_NODE, &match_origin_cmd);
3798 install_element (RMAP_NODE, &no_match_origin_cmd);
3799 install_element (RMAP_NODE, &no_match_origin_val_cmd);
3800
3801 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003802 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003803 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3804 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3805 install_element (RMAP_NODE, &set_local_pref_cmd);
3806 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3807 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3808 install_element (RMAP_NODE, &set_weight_cmd);
3809 install_element (RMAP_NODE, &no_set_weight_cmd);
3810 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3811 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003812 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003813 install_element (RMAP_NODE, &no_set_metric_cmd);
3814 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3815 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003816 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003817 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3818 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003819 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
3820 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00003821 install_element (RMAP_NODE, &set_origin_cmd);
3822 install_element (RMAP_NODE, &no_set_origin_cmd);
3823 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3824 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3825 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3826 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3827 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3828 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3829 install_element (RMAP_NODE, &set_community_cmd);
3830 install_element (RMAP_NODE, &set_community_none_cmd);
3831 install_element (RMAP_NODE, &no_set_community_cmd);
3832 install_element (RMAP_NODE, &no_set_community_val_cmd);
3833 install_element (RMAP_NODE, &no_set_community_none_cmd);
3834 install_element (RMAP_NODE, &set_community_delete_cmd);
3835 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3836 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3837 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3838 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3839 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3840 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3841 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3842 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3843 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3844 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3845 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3846 install_element (RMAP_NODE, &set_originator_id_cmd);
3847 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3848 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3849
3850#ifdef HAVE_IPV6
3851 route_map_install_match (&route_match_ipv6_address_cmd);
3852 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3853 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3854 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3855 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Paul Jakma41367172007-08-06 15:24:51 +00003856
paul718e3742002-12-13 20:15:29 +00003857 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3858 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3859 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3860 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3861 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3862 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3863 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3864 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3865 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3866 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3867 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3868 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3869#endif /* HAVE_IPV6 */
Paul Jakma41367172007-08-06 15:24:51 +00003870
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003871 /* AS-Pathlimit: functionality removed, commands kept for
3872 * compatibility.
3873 */
Paul Jakma41367172007-08-06 15:24:51 +00003874 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
3875 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
3876 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
3877 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
3878 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
3879 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00003880}