blob: 451458b5eb48abfdc34194c7db659c2bd8c0e97c [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 */
paul718e3742002-12-13 20:15:29 +00001300 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));
paul718e3742002-12-13 20:15:29 +00001341 rcs->com = com;
1342 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
1396 if (new->size == 0)
1397 {
1398 binfo->attr->community = NULL;
1399 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1400 community_free (new);
1401 }
1402 else
1403 {
1404 binfo->attr->community = new;
1405 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1406 }
1407 }
1408 }
1409
1410 return RMAP_OKAY;
1411}
1412
1413/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001414static void *
paulfd79ac92004-10-13 05:06:08 +00001415route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001416{
1417 char *p;
1418 char *str;
1419 int len;
1420
1421 p = strchr (arg, ' ');
1422 if (p)
1423 {
1424 len = p - arg;
1425 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1426 memcpy (str, arg, len);
1427 }
1428 else
1429 str = NULL;
1430
1431 return str;
1432}
1433
1434/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001435static void
paul718e3742002-12-13 20:15:29 +00001436route_set_community_delete_free (void *rule)
1437{
1438 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1439}
1440
1441/* Set community rule structure. */
1442struct route_map_rule_cmd route_set_community_delete_cmd =
1443{
1444 "comm-list",
1445 route_set_community_delete,
1446 route_set_community_delete_compile,
1447 route_set_community_delete_free,
1448};
1449
1450/* `set extcommunity rt COMMUNITY' */
1451
1452/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001453static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001454route_set_ecommunity_rt (void *rule, struct prefix *prefix,
1455 route_map_object_t type, void *object)
1456{
1457 struct ecommunity *ecom;
1458 struct ecommunity *new_ecom;
1459 struct ecommunity *old_ecom;
1460 struct bgp_info *bgp_info;
1461
1462 if (type == RMAP_BGP)
1463 {
1464 ecom = rule;
1465 bgp_info = object;
1466
1467 if (! ecom)
1468 return RMAP_OKAY;
1469
1470 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001471 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001472
1473 if (old_ecom)
1474 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1475 else
1476 new_ecom = ecommunity_dup (ecom);
1477
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001478 bgp_info->attr->extra->ecommunity = ecommunity_intern (new_ecom);
paul718e3742002-12-13 20:15:29 +00001479
hasso70601e02005-05-27 03:26:57 +00001480 if (old_ecom)
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001481 ecommunity_unintern (&old_ecom);
hasso70601e02005-05-27 03:26:57 +00001482
paul718e3742002-12-13 20:15:29 +00001483 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1484 }
1485 return RMAP_OKAY;
1486}
1487
1488/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001489static void *
paulfd79ac92004-10-13 05:06:08 +00001490route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001491{
1492 struct ecommunity *ecom;
1493
1494 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1495 if (! ecom)
1496 return NULL;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001497 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001498}
1499
1500/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001501static void
paul718e3742002-12-13 20:15:29 +00001502route_set_ecommunity_rt_free (void *rule)
1503{
1504 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001505 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001506}
1507
1508/* Set community rule structure. */
1509struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1510{
1511 "extcommunity rt",
1512 route_set_ecommunity_rt,
1513 route_set_ecommunity_rt_compile,
1514 route_set_ecommunity_rt_free,
1515};
1516
1517/* `set extcommunity soo COMMUNITY' */
1518
1519/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001520static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001521route_set_ecommunity_soo (void *rule, struct prefix *prefix,
1522 route_map_object_t type, void *object)
1523{
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001524 struct ecommunity *ecom, *old_ecom, *new_ecom;
paul718e3742002-12-13 20:15:29 +00001525 struct bgp_info *bgp_info;
1526
1527 if (type == RMAP_BGP)
1528 {
1529 ecom = rule;
1530 bgp_info = object;
1531
1532 if (! ecom)
1533 return RMAP_OKAY;
1534
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001535 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
1536
1537 if (old_ecom)
1538 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1539 else
1540 new_ecom = ecommunity_dup (ecom);
1541
1542 bgp_info->attr->extra->ecommunity = ecommunity_intern (new_ecom);
1543
1544 if (old_ecom)
1545 ecommunity_unintern (&old_ecom);
1546
paul718e3742002-12-13 20:15:29 +00001547 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
paul718e3742002-12-13 20:15:29 +00001548 }
1549 return RMAP_OKAY;
1550}
1551
1552/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001553static void *
paulfd79ac92004-10-13 05:06:08 +00001554route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001555{
1556 struct ecommunity *ecom;
1557
1558 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1559 if (! ecom)
1560 return NULL;
1561
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001562 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001563}
1564
1565/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001566static void
paul718e3742002-12-13 20:15:29 +00001567route_set_ecommunity_soo_free (void *rule)
1568{
1569 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001570 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001571}
1572
1573/* Set community rule structure. */
1574struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1575{
1576 "extcommunity soo",
1577 route_set_ecommunity_soo,
1578 route_set_ecommunity_soo_compile,
1579 route_set_ecommunity_soo_free,
1580};
1581
1582/* `set origin ORIGIN' */
1583
1584/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001585static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001586route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1587{
1588 u_char *origin;
1589 struct bgp_info *bgp_info;
1590
1591 if (type == RMAP_BGP)
1592 {
1593 origin = rule;
1594 bgp_info = object;
1595
1596 bgp_info->attr->origin = *origin;
1597 }
1598
1599 return RMAP_OKAY;
1600}
1601
1602/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001603static void *
paulfd79ac92004-10-13 05:06:08 +00001604route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001605{
1606 u_char *origin;
1607
1608 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1609
1610 if (strcmp (arg, "igp") == 0)
1611 *origin = 0;
1612 else if (strcmp (arg, "egp") == 0)
1613 *origin = 1;
1614 else
1615 *origin = 2;
1616
1617 return origin;
1618}
1619
1620/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001621static void
paul718e3742002-12-13 20:15:29 +00001622route_set_origin_free (void *rule)
1623{
1624 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1625}
1626
1627/* Set metric rule structure. */
1628struct route_map_rule_cmd route_set_origin_cmd =
1629{
1630 "origin",
1631 route_set_origin,
1632 route_set_origin_compile,
1633 route_set_origin_free,
1634};
1635
1636/* `set atomic-aggregate' */
1637
1638/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001639static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001640route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1641 route_map_object_t type, void *object)
1642{
1643 struct bgp_info *bgp_info;
1644
1645 if (type == RMAP_BGP)
1646 {
1647 bgp_info = object;
1648 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1649 }
1650
1651 return RMAP_OKAY;
1652}
1653
1654/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001655static void *
paulfd79ac92004-10-13 05:06:08 +00001656route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001657{
1658 return (void *)1;
1659}
1660
1661/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001662static void
paul718e3742002-12-13 20:15:29 +00001663route_set_atomic_aggregate_free (void *rule)
1664{
1665 return;
1666}
1667
1668/* Set atomic aggregate rule structure. */
1669struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1670{
1671 "atomic-aggregate",
1672 route_set_atomic_aggregate,
1673 route_set_atomic_aggregate_compile,
1674 route_set_atomic_aggregate_free,
1675};
1676
1677/* `set aggregator as AS A.B.C.D' */
1678struct aggregator
1679{
1680 as_t as;
1681 struct in_addr address;
1682};
1683
paul94f2b392005-06-28 12:44:16 +00001684static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001685route_set_aggregator_as (void *rule, struct prefix *prefix,
1686 route_map_object_t type, void *object)
1687{
1688 struct bgp_info *bgp_info;
1689 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001690 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001691
1692 if (type == RMAP_BGP)
1693 {
1694 bgp_info = object;
1695 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001696 ae = bgp_attr_extra_get (bgp_info->attr);
1697
1698 ae->aggregator_as = aggregator->as;
1699 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001700 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1701 }
1702
1703 return RMAP_OKAY;
1704}
1705
paul94f2b392005-06-28 12:44:16 +00001706static void *
paulfd79ac92004-10-13 05:06:08 +00001707route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001708{
1709 struct aggregator *aggregator;
1710 char as[10];
1711 char address[20];
1712
Stephen Hemminger393deb92008-08-18 14:13:29 -07001713 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
paul718e3742002-12-13 20:15:29 +00001714 sscanf (arg, "%s %s", as, address);
1715
1716 aggregator->as = strtoul (as, NULL, 10);
1717 inet_aton (address, &aggregator->address);
1718
1719 return aggregator;
1720}
1721
paul94f2b392005-06-28 12:44:16 +00001722static void
paul718e3742002-12-13 20:15:29 +00001723route_set_aggregator_as_free (void *rule)
1724{
1725 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1726}
1727
1728struct route_map_rule_cmd route_set_aggregator_as_cmd =
1729{
1730 "aggregator as",
1731 route_set_aggregator_as,
1732 route_set_aggregator_as_compile,
1733 route_set_aggregator_as_free,
1734};
1735
1736#ifdef HAVE_IPV6
1737/* `match ipv6 address IP_ACCESS_LIST' */
1738
paul94f2b392005-06-28 12:44:16 +00001739static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001740route_match_ipv6_address (void *rule, struct prefix *prefix,
1741 route_map_object_t type, void *object)
1742{
1743 struct access_list *alist;
1744
1745 if (type == RMAP_BGP)
1746 {
1747 alist = access_list_lookup (AFI_IP6, (char *) rule);
1748 if (alist == NULL)
1749 return RMAP_NOMATCH;
1750
1751 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1752 RMAP_NOMATCH : RMAP_MATCH);
1753 }
1754 return RMAP_NOMATCH;
1755}
1756
paul94f2b392005-06-28 12:44:16 +00001757static void *
paulfd79ac92004-10-13 05:06:08 +00001758route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001759{
1760 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1761}
1762
paul94f2b392005-06-28 12:44:16 +00001763static void
paul718e3742002-12-13 20:15:29 +00001764route_match_ipv6_address_free (void *rule)
1765{
1766 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1767}
1768
1769/* Route map commands for ip address matching. */
1770struct route_map_rule_cmd route_match_ipv6_address_cmd =
1771{
1772 "ipv6 address",
1773 route_match_ipv6_address,
1774 route_match_ipv6_address_compile,
1775 route_match_ipv6_address_free
1776};
1777
1778/* `match ipv6 next-hop IP_ADDRESS' */
1779
paul94f2b392005-06-28 12:44:16 +00001780static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001781route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1782 route_map_object_t type, void *object)
1783{
1784 struct in6_addr *addr;
1785 struct bgp_info *bgp_info;
1786
1787 if (type == RMAP_BGP)
1788 {
1789 addr = rule;
1790 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001791
1792 if (!bgp_info->attr->extra)
1793 return RMAP_NOMATCH;
1794
1795 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, rule))
paul718e3742002-12-13 20:15:29 +00001796 return RMAP_MATCH;
1797
Paul Jakmafb982c22007-05-04 20:15:47 +00001798 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
1799 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, rule))
paul718e3742002-12-13 20:15:29 +00001800 return RMAP_MATCH;
1801
1802 return RMAP_NOMATCH;
1803 }
1804
1805 return RMAP_NOMATCH;
1806}
1807
paul94f2b392005-06-28 12:44:16 +00001808static void *
paulfd79ac92004-10-13 05:06:08 +00001809route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001810{
1811 struct in6_addr *address;
1812 int ret;
1813
1814 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1815
1816 ret = inet_pton (AF_INET6, arg, address);
1817 if (!ret)
1818 {
1819 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1820 return NULL;
1821 }
1822
1823 return address;
1824}
1825
paul94f2b392005-06-28 12:44:16 +00001826static void
paul718e3742002-12-13 20:15:29 +00001827route_match_ipv6_next_hop_free (void *rule)
1828{
1829 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1830}
1831
1832struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1833{
1834 "ipv6 next-hop",
1835 route_match_ipv6_next_hop,
1836 route_match_ipv6_next_hop_compile,
1837 route_match_ipv6_next_hop_free
1838};
1839
1840/* `match ipv6 address prefix-list PREFIX_LIST' */
1841
paul94f2b392005-06-28 12:44:16 +00001842static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001843route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1844 route_map_object_t type, void *object)
1845{
1846 struct prefix_list *plist;
1847
1848 if (type == RMAP_BGP)
1849 {
1850 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1851 if (plist == NULL)
1852 return RMAP_NOMATCH;
1853
1854 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1855 RMAP_NOMATCH : RMAP_MATCH);
1856 }
1857 return RMAP_NOMATCH;
1858}
1859
paul94f2b392005-06-28 12:44:16 +00001860static void *
paulfd79ac92004-10-13 05:06:08 +00001861route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001862{
1863 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1864}
1865
paul94f2b392005-06-28 12:44:16 +00001866static void
paul718e3742002-12-13 20:15:29 +00001867route_match_ipv6_address_prefix_list_free (void *rule)
1868{
1869 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1870}
1871
1872struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1873{
1874 "ipv6 address prefix-list",
1875 route_match_ipv6_address_prefix_list,
1876 route_match_ipv6_address_prefix_list_compile,
1877 route_match_ipv6_address_prefix_list_free
1878};
1879
1880/* `set ipv6 nexthop global IP_ADDRESS' */
1881
1882/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001883static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001884route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1885 route_map_object_t type, void *object)
1886{
1887 struct in6_addr *address;
1888 struct bgp_info *bgp_info;
1889
1890 if (type == RMAP_BGP)
1891 {
1892 /* Fetch routemap's rule information. */
1893 address = rule;
1894 bgp_info = object;
1895
1896 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001897 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00001898
1899 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001900 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1901 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00001902 }
1903
1904 return RMAP_OKAY;
1905}
1906
1907/* Route map `ip next-hop' compile function. Given string is converted
1908 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001909static void *
paulfd79ac92004-10-13 05:06:08 +00001910route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001911{
1912 int ret;
1913 struct in6_addr *address;
1914
1915 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1916
1917 ret = inet_pton (AF_INET6, arg, address);
1918
1919 if (ret == 0)
1920 {
1921 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1922 return NULL;
1923 }
1924
1925 return address;
1926}
1927
1928/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00001929static void
paul718e3742002-12-13 20:15:29 +00001930route_set_ipv6_nexthop_global_free (void *rule)
1931{
1932 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1933}
1934
1935/* Route map commands for ip nexthop set. */
1936struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
1937{
1938 "ipv6 next-hop global",
1939 route_set_ipv6_nexthop_global,
1940 route_set_ipv6_nexthop_global_compile,
1941 route_set_ipv6_nexthop_global_free
1942};
1943
1944/* `set ipv6 nexthop local IP_ADDRESS' */
1945
1946/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001947static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001948route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
1949 route_map_object_t type, void *object)
1950{
1951 struct in6_addr *address;
1952 struct bgp_info *bgp_info;
1953
1954 if (type == RMAP_BGP)
1955 {
1956 /* Fetch routemap's rule information. */
1957 address = rule;
1958 bgp_info = object;
1959
1960 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001961 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00001962
1963 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001964 if (bgp_info->attr->extra->mp_nexthop_len != 32)
1965 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00001966 }
1967
1968 return RMAP_OKAY;
1969}
1970
1971/* Route map `ip nexthop' compile function. Given string is converted
1972 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001973static void *
paulfd79ac92004-10-13 05:06:08 +00001974route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001975{
1976 int ret;
1977 struct in6_addr *address;
1978
1979 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1980
1981 ret = inet_pton (AF_INET6, arg, address);
1982
1983 if (ret == 0)
1984 {
1985 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1986 return NULL;
1987 }
1988
1989 return address;
1990}
1991
1992/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00001993static void
paul718e3742002-12-13 20:15:29 +00001994route_set_ipv6_nexthop_local_free (void *rule)
1995{
1996 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1997}
1998
1999/* Route map commands for ip nexthop set. */
2000struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
2001{
2002 "ipv6 next-hop local",
2003 route_set_ipv6_nexthop_local,
2004 route_set_ipv6_nexthop_local_compile,
2005 route_set_ipv6_nexthop_local_free
2006};
2007#endif /* HAVE_IPV6 */
2008
2009/* `set vpnv4 nexthop A.B.C.D' */
2010
paul94f2b392005-06-28 12:44:16 +00002011static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002012route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2013 route_map_object_t type, void *object)
2014{
2015 struct in_addr *address;
2016 struct bgp_info *bgp_info;
2017
2018 if (type == RMAP_BGP)
2019 {
2020 /* Fetch routemap's rule information. */
2021 address = rule;
2022 bgp_info = object;
2023
2024 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002025 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
paul718e3742002-12-13 20:15:29 +00002026 }
2027
2028 return RMAP_OKAY;
2029}
2030
paul94f2b392005-06-28 12:44:16 +00002031static void *
paulfd79ac92004-10-13 05:06:08 +00002032route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002033{
2034 int ret;
2035 struct in_addr *address;
2036
2037 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2038
2039 ret = inet_aton (arg, address);
2040
2041 if (ret == 0)
2042 {
2043 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2044 return NULL;
2045 }
2046
2047 return address;
2048}
2049
paul94f2b392005-06-28 12:44:16 +00002050static void
paul718e3742002-12-13 20:15:29 +00002051route_set_vpnv4_nexthop_free (void *rule)
2052{
2053 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2054}
2055
2056/* Route map commands for ip nexthop set. */
2057struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2058{
2059 "vpnv4 next-hop",
2060 route_set_vpnv4_nexthop,
2061 route_set_vpnv4_nexthop_compile,
2062 route_set_vpnv4_nexthop_free
2063};
2064
2065/* `set originator-id' */
2066
2067/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002068static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002069route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2070{
2071 struct in_addr *address;
2072 struct bgp_info *bgp_info;
2073
2074 if (type == RMAP_BGP)
2075 {
2076 address = rule;
2077 bgp_info = object;
2078
2079 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002080 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002081 }
2082
2083 return RMAP_OKAY;
2084}
2085
2086/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002087static void *
paulfd79ac92004-10-13 05:06:08 +00002088route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002089{
2090 int ret;
2091 struct in_addr *address;
2092
2093 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2094
2095 ret = inet_aton (arg, address);
2096
2097 if (ret == 0)
2098 {
2099 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2100 return NULL;
2101 }
2102
2103 return address;
2104}
2105
2106/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002107static void
paul718e3742002-12-13 20:15:29 +00002108route_set_originator_id_free (void *rule)
2109{
2110 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2111}
2112
2113/* Set metric rule structure. */
2114struct route_map_rule_cmd route_set_originator_id_cmd =
2115{
2116 "originator-id",
2117 route_set_originator_id,
2118 route_set_originator_id_compile,
2119 route_set_originator_id_free,
2120};
2121
2122/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002123static int
paul718e3742002-12-13 20:15:29 +00002124bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002125 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002126{
2127 int ret;
2128
2129 ret = route_map_add_match (index, command, arg);
2130 if (ret)
2131 {
2132 switch (ret)
2133 {
2134 case RMAP_RULE_MISSING:
2135 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2136 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002137 case RMAP_COMPILE_ERROR:
2138 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2139 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002140 }
2141 }
2142 return CMD_SUCCESS;
2143}
2144
2145/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002146static int
paul718e3742002-12-13 20:15:29 +00002147bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002148 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002149{
2150 int ret;
2151
2152 ret = route_map_delete_match (index, command, arg);
2153 if (ret)
2154 {
2155 switch (ret)
2156 {
2157 case RMAP_RULE_MISSING:
2158 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2159 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002160 case RMAP_COMPILE_ERROR:
2161 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2162 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002163 }
2164 }
2165 return CMD_SUCCESS;
2166}
2167
2168/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002169static int
paul718e3742002-12-13 20:15:29 +00002170bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002171 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002172{
2173 int ret;
2174
2175 ret = route_map_add_set (index, command, arg);
2176 if (ret)
2177 {
2178 switch (ret)
2179 {
2180 case RMAP_RULE_MISSING:
2181 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2182 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002183 case RMAP_COMPILE_ERROR:
2184 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2185 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002186 }
2187 }
2188 return CMD_SUCCESS;
2189}
2190
2191/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002192static int
paul718e3742002-12-13 20:15:29 +00002193bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002194 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002195{
2196 int ret;
2197
2198 ret = route_map_delete_set (index, command, arg);
2199 if (ret)
2200 {
2201 switch (ret)
2202 {
2203 case RMAP_RULE_MISSING:
2204 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2205 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002206 case RMAP_COMPILE_ERROR:
2207 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2208 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002209 }
2210 }
2211 return CMD_SUCCESS;
2212}
2213
2214/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002215static void
paulfd79ac92004-10-13 05:06:08 +00002216bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002217{
2218 int i;
2219 afi_t afi;
2220 safi_t safi;
2221 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002222 struct listnode *node, *nnode;
2223 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002224 struct bgp *bgp;
2225 struct peer *peer;
2226 struct peer_group *group;
2227 struct bgp_filter *filter;
2228 struct bgp_node *bn;
2229 struct bgp_static *bgp_static;
2230
2231 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002232 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002233 {
paul1eb8ef22005-04-07 07:30:20 +00002234 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002235 {
2236 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2237 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2238 {
2239 filter = &peer->filter[afi][safi];
2240
paulfee0f4c2004-09-13 05:12:46 +00002241 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002242 {
2243 if (filter->map[direct].name)
2244 filter->map[direct].map =
2245 route_map_lookup_by_name (filter->map[direct].name);
2246 else
2247 filter->map[direct].map = NULL;
2248 }
2249
2250 if (filter->usmap.name)
2251 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2252 else
2253 filter->usmap.map = NULL;
2254 }
2255 }
paul1eb8ef22005-04-07 07:30:20 +00002256 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002257 {
2258 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2259 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2260 {
2261 filter = &group->conf->filter[afi][safi];
2262
paulfee0f4c2004-09-13 05:12:46 +00002263 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002264 {
2265 if (filter->map[direct].name)
2266 filter->map[direct].map =
2267 route_map_lookup_by_name (filter->map[direct].name);
2268 else
2269 filter->map[direct].map = NULL;
2270 }
2271
2272 if (filter->usmap.name)
2273 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2274 else
2275 filter->usmap.map = NULL;
2276 }
2277 }
2278 }
2279
2280 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002281 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002282 {
paul1eb8ef22005-04-07 07:30:20 +00002283 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002284 {
2285 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2286 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2287 {
2288 if (peer->default_rmap[afi][safi].name)
2289 peer->default_rmap[afi][safi].map =
2290 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2291 else
2292 peer->default_rmap[afi][safi].map = NULL;
2293 }
2294 }
2295 }
2296
2297 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002298 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002299 {
2300 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2301 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2302 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2303 bn = bgp_route_next (bn))
2304 if ((bgp_static = bn->info) != NULL)
2305 {
2306 if (bgp_static->rmap.name)
2307 bgp_static->rmap.map =
2308 route_map_lookup_by_name (bgp_static->rmap.name);
2309 else
2310 bgp_static->rmap.map = NULL;
2311 }
2312 }
2313
2314 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002315 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002316 {
2317 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2318 {
2319 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2320 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2321 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2322#ifdef HAVE_IPV6
2323 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2324 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2325 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2326#endif /* HAVE_IPV6 */
2327 }
2328 }
2329}
2330
paulfee0f4c2004-09-13 05:12:46 +00002331DEFUN (match_peer,
2332 match_peer_cmd,
2333 "match peer (A.B.C.D|X:X::X:X)",
2334 MATCH_STR
2335 "Match peer address\n"
2336 "IPv6 address of peer\n"
2337 "IP address of peer\n")
2338{
2339 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2340}
2341
2342DEFUN (match_peer_local,
2343 match_peer_local_cmd,
2344 "match peer local",
2345 MATCH_STR
2346 "Match peer address\n"
2347 "Static or Redistributed routes\n")
2348{
2349 return bgp_route_match_add (vty, vty->index, "peer", NULL);
2350}
2351
2352DEFUN (no_match_peer,
2353 no_match_peer_cmd,
2354 "no match peer",
2355 NO_STR
2356 MATCH_STR
2357 "Match peer address\n")
2358{
2359 if (argc == 0)
2360 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2361
2362 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2363}
2364
2365ALIAS (no_match_peer,
2366 no_match_peer_val_cmd,
2367 "no match peer (A.B.C.D|X:X::X:X)",
2368 NO_STR
2369 MATCH_STR
2370 "Match peer address\n"
2371 "IPv6 address of peer\n"
2372 "IP address of peer\n")
2373
2374ALIAS (no_match_peer,
2375 no_match_peer_local_cmd,
2376 "no match peer local",
2377 NO_STR
2378 MATCH_STR
2379 "Match peer address\n"
2380 "Static or Redistributed routes\n")
2381
paul718e3742002-12-13 20:15:29 +00002382DEFUN (match_ip_address,
2383 match_ip_address_cmd,
2384 "match ip address (<1-199>|<1300-2699>|WORD)",
2385 MATCH_STR
2386 IP_STR
2387 "Match address of route\n"
2388 "IP access-list number\n"
2389 "IP access-list number (expanded range)\n"
2390 "IP Access-list name\n")
2391{
2392 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2393}
2394
2395DEFUN (no_match_ip_address,
2396 no_match_ip_address_cmd,
2397 "no match ip address",
2398 NO_STR
2399 MATCH_STR
2400 IP_STR
2401 "Match address of route\n")
2402{
2403 if (argc == 0)
2404 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2405
2406 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2407}
2408
2409ALIAS (no_match_ip_address,
2410 no_match_ip_address_val_cmd,
2411 "no match ip address (<1-199>|<1300-2699>|WORD)",
2412 NO_STR
2413 MATCH_STR
2414 IP_STR
2415 "Match address of route\n"
2416 "IP access-list number\n"
2417 "IP access-list number (expanded range)\n"
2418 "IP Access-list name\n")
2419
2420DEFUN (match_ip_next_hop,
2421 match_ip_next_hop_cmd,
2422 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2423 MATCH_STR
2424 IP_STR
2425 "Match next-hop address of route\n"
2426 "IP access-list number\n"
2427 "IP access-list number (expanded range)\n"
2428 "IP Access-list name\n")
2429{
2430 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2431}
2432
2433DEFUN (no_match_ip_next_hop,
2434 no_match_ip_next_hop_cmd,
2435 "no match ip next-hop",
2436 NO_STR
2437 MATCH_STR
2438 IP_STR
2439 "Match next-hop address of route\n")
2440{
2441 if (argc == 0)
2442 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2443
2444 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2445}
2446
2447ALIAS (no_match_ip_next_hop,
2448 no_match_ip_next_hop_val_cmd,
2449 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2450 NO_STR
2451 MATCH_STR
2452 IP_STR
2453 "Match next-hop address of route\n"
2454 "IP access-list number\n"
2455 "IP access-list number (expanded range)\n"
2456 "IP Access-list name\n")
2457
hassoc1643bb2005-02-02 16:43:17 +00002458DEFUN (match_ip_route_source,
2459 match_ip_route_source_cmd,
2460 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2461 MATCH_STR
2462 IP_STR
2463 "Match advertising source address of route\n"
2464 "IP access-list number\n"
2465 "IP access-list number (expanded range)\n"
2466 "IP standard access-list name\n")
2467{
2468 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2469}
2470
2471DEFUN (no_match_ip_route_source,
2472 no_match_ip_route_source_cmd,
2473 "no match ip route-source",
2474 NO_STR
2475 MATCH_STR
2476 IP_STR
2477 "Match advertising source address of route\n")
2478{
2479 if (argc == 0)
2480 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2481
2482 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2483}
2484
2485ALIAS (no_match_ip_route_source,
2486 no_match_ip_route_source_val_cmd,
2487 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2488 NO_STR
2489 MATCH_STR
2490 IP_STR
2491 "Match advertising source address of route\n"
2492 "IP access-list number\n"
2493 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002494 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002495
paul718e3742002-12-13 20:15:29 +00002496DEFUN (match_ip_address_prefix_list,
2497 match_ip_address_prefix_list_cmd,
2498 "match ip address prefix-list WORD",
2499 MATCH_STR
2500 IP_STR
2501 "Match address of route\n"
2502 "Match entries of prefix-lists\n"
2503 "IP prefix-list name\n")
2504{
2505 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2506}
2507
2508DEFUN (no_match_ip_address_prefix_list,
2509 no_match_ip_address_prefix_list_cmd,
2510 "no match ip address prefix-list",
2511 NO_STR
2512 MATCH_STR
2513 IP_STR
2514 "Match address of route\n"
2515 "Match entries of prefix-lists\n")
2516{
2517 if (argc == 0)
2518 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2519
2520 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2521}
2522
2523ALIAS (no_match_ip_address_prefix_list,
2524 no_match_ip_address_prefix_list_val_cmd,
2525 "no match ip address prefix-list WORD",
2526 NO_STR
2527 MATCH_STR
2528 IP_STR
2529 "Match address of route\n"
2530 "Match entries of prefix-lists\n"
2531 "IP prefix-list name\n")
2532
2533DEFUN (match_ip_next_hop_prefix_list,
2534 match_ip_next_hop_prefix_list_cmd,
2535 "match ip next-hop prefix-list WORD",
2536 MATCH_STR
2537 IP_STR
2538 "Match next-hop address of route\n"
2539 "Match entries of prefix-lists\n"
2540 "IP prefix-list name\n")
2541{
2542 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2543}
2544
2545DEFUN (no_match_ip_next_hop_prefix_list,
2546 no_match_ip_next_hop_prefix_list_cmd,
2547 "no match ip next-hop prefix-list",
2548 NO_STR
2549 MATCH_STR
2550 IP_STR
2551 "Match next-hop address of route\n"
2552 "Match entries of prefix-lists\n")
2553{
2554 if (argc == 0)
2555 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2556
2557 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2558}
2559
2560ALIAS (no_match_ip_next_hop_prefix_list,
2561 no_match_ip_next_hop_prefix_list_val_cmd,
2562 "no match ip next-hop prefix-list WORD",
2563 NO_STR
2564 MATCH_STR
2565 IP_STR
2566 "Match next-hop address of route\n"
2567 "Match entries of prefix-lists\n"
2568 "IP prefix-list name\n")
2569
hassoc1643bb2005-02-02 16:43:17 +00002570DEFUN (match_ip_route_source_prefix_list,
2571 match_ip_route_source_prefix_list_cmd,
2572 "match ip route-source prefix-list WORD",
2573 MATCH_STR
2574 IP_STR
2575 "Match advertising source address of route\n"
2576 "Match entries of prefix-lists\n"
2577 "IP prefix-list name\n")
2578{
2579 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2580}
2581
2582DEFUN (no_match_ip_route_source_prefix_list,
2583 no_match_ip_route_source_prefix_list_cmd,
2584 "no match ip route-source prefix-list",
2585 NO_STR
2586 MATCH_STR
2587 IP_STR
2588 "Match advertising source address of route\n"
2589 "Match entries of prefix-lists\n")
2590{
2591 if (argc == 0)
2592 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2593
2594 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2595}
2596
2597ALIAS (no_match_ip_route_source_prefix_list,
2598 no_match_ip_route_source_prefix_list_val_cmd,
2599 "no match ip route-source prefix-list WORD",
2600 NO_STR
2601 MATCH_STR
2602 IP_STR
2603 "Match advertising source address of route\n"
2604 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002605 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002606
paul718e3742002-12-13 20:15:29 +00002607DEFUN (match_metric,
2608 match_metric_cmd,
2609 "match metric <0-4294967295>",
2610 MATCH_STR
2611 "Match metric of route\n"
2612 "Metric value\n")
2613{
2614 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2615}
2616
2617DEFUN (no_match_metric,
2618 no_match_metric_cmd,
2619 "no match metric",
2620 NO_STR
2621 MATCH_STR
2622 "Match metric of route\n")
2623{
2624 if (argc == 0)
2625 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2626
2627 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2628}
2629
2630ALIAS (no_match_metric,
2631 no_match_metric_val_cmd,
2632 "no match metric <0-4294967295>",
2633 NO_STR
2634 MATCH_STR
2635 "Match metric of route\n"
2636 "Metric value\n")
2637
2638DEFUN (match_community,
2639 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002640 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002641 MATCH_STR
2642 "Match BGP community list\n"
2643 "Community-list number (standard)\n"
2644 "Community-list number (expanded)\n"
2645 "Community-list name\n")
2646{
2647 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2648}
2649
2650DEFUN (match_community_exact,
2651 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002652 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002653 MATCH_STR
2654 "Match BGP community list\n"
2655 "Community-list number (standard)\n"
2656 "Community-list number (expanded)\n"
2657 "Community-list name\n"
2658 "Do exact matching of communities\n")
2659{
2660 int ret;
2661 char *argstr;
2662
2663 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2664 strlen (argv[0]) + strlen ("exact-match") + 2);
2665
2666 sprintf (argstr, "%s exact-match", argv[0]);
2667
2668 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2669
2670 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2671
2672 return ret;
2673}
2674
2675DEFUN (no_match_community,
2676 no_match_community_cmd,
2677 "no match community",
2678 NO_STR
2679 MATCH_STR
2680 "Match BGP community list\n")
2681{
2682 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2683}
2684
2685ALIAS (no_match_community,
2686 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002687 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002688 NO_STR
2689 MATCH_STR
2690 "Match BGP community list\n"
2691 "Community-list number (standard)\n"
2692 "Community-list number (expanded)\n"
2693 "Community-list name\n")
2694
2695ALIAS (no_match_community,
2696 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002697 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002698 NO_STR
2699 MATCH_STR
2700 "Match BGP community list\n"
2701 "Community-list number (standard)\n"
2702 "Community-list number (expanded)\n"
2703 "Community-list name\n"
2704 "Do exact matching of communities\n")
2705
paul73ffb252003-04-19 15:49:49 +00002706DEFUN (match_ecommunity,
2707 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002708 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002709 MATCH_STR
2710 "Match BGP/VPN extended community list\n"
2711 "Extended community-list number (standard)\n"
2712 "Extended community-list number (expanded)\n"
2713 "Extended community-list name\n")
2714{
2715 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2716}
2717
2718DEFUN (no_match_ecommunity,
2719 no_match_ecommunity_cmd,
2720 "no match extcommunity",
2721 NO_STR
2722 MATCH_STR
2723 "Match BGP/VPN extended community list\n")
2724{
2725 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2726}
2727
2728ALIAS (no_match_ecommunity,
2729 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002730 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002731 NO_STR
2732 MATCH_STR
2733 "Match BGP/VPN extended community list\n"
2734 "Extended community-list number (standard)\n"
2735 "Extended community-list number (expanded)\n"
2736 "Extended community-list name\n")
2737
paul718e3742002-12-13 20:15:29 +00002738DEFUN (match_aspath,
2739 match_aspath_cmd,
2740 "match as-path WORD",
2741 MATCH_STR
2742 "Match BGP AS path list\n"
2743 "AS path access-list name\n")
2744{
2745 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2746}
2747
2748DEFUN (no_match_aspath,
2749 no_match_aspath_cmd,
2750 "no match as-path",
2751 NO_STR
2752 MATCH_STR
2753 "Match BGP AS path list\n")
2754{
2755 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2756}
2757
2758ALIAS (no_match_aspath,
2759 no_match_aspath_val_cmd,
2760 "no match as-path WORD",
2761 NO_STR
2762 MATCH_STR
2763 "Match BGP AS path list\n"
2764 "AS path access-list name\n")
2765
2766DEFUN (match_origin,
2767 match_origin_cmd,
2768 "match origin (egp|igp|incomplete)",
2769 MATCH_STR
2770 "BGP origin code\n"
2771 "remote EGP\n"
2772 "local IGP\n"
2773 "unknown heritage\n")
2774{
2775 if (strncmp (argv[0], "igp", 2) == 0)
2776 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2777 if (strncmp (argv[0], "egp", 1) == 0)
2778 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2779 if (strncmp (argv[0], "incomplete", 2) == 0)
2780 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2781
2782 return CMD_WARNING;
2783}
2784
2785DEFUN (no_match_origin,
2786 no_match_origin_cmd,
2787 "no match origin",
2788 NO_STR
2789 MATCH_STR
2790 "BGP origin code\n")
2791{
2792 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2793}
2794
2795ALIAS (no_match_origin,
2796 no_match_origin_val_cmd,
2797 "no match origin (egp|igp|incomplete)",
2798 NO_STR
2799 MATCH_STR
2800 "BGP origin code\n"
2801 "remote EGP\n"
2802 "local IGP\n"
2803 "unknown heritage\n")
2804
2805DEFUN (set_ip_nexthop,
2806 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002807 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002808 SET_STR
2809 IP_STR
2810 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002811 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002812{
2813 union sockunion su;
2814 int ret;
2815
2816 ret = str2sockunion (argv[0], &su);
2817 if (ret < 0)
2818 {
2819 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2820 return CMD_WARNING;
2821 }
2822
2823 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2824}
2825
paulaf5cd0a2003-11-02 07:24:40 +00002826DEFUN (set_ip_nexthop_peer,
2827 set_ip_nexthop_peer_cmd,
2828 "set ip next-hop peer-address",
2829 SET_STR
2830 IP_STR
2831 "Next hop address\n"
2832 "Use peer address (for BGP only)\n")
2833{
2834 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2835}
2836
paul94f2b392005-06-28 12:44:16 +00002837DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00002838 no_set_ip_nexthop_peer_cmd,
2839 "no set ip next-hop peer-address",
2840 NO_STR
2841 SET_STR
2842 IP_STR
2843 "Next hop address\n"
2844 "Use peer address (for BGP only)\n")
2845{
2846 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2847}
2848
2849
paul718e3742002-12-13 20:15:29 +00002850DEFUN (no_set_ip_nexthop,
2851 no_set_ip_nexthop_cmd,
2852 "no set ip next-hop",
2853 NO_STR
2854 SET_STR
paul718e3742002-12-13 20:15:29 +00002855 "Next hop address\n")
2856{
paulaf5cd0a2003-11-02 07:24:40 +00002857 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002858 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2859
2860 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2861}
2862
2863ALIAS (no_set_ip_nexthop,
2864 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002865 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002866 NO_STR
2867 SET_STR
2868 IP_STR
2869 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002870 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002871
2872DEFUN (set_metric,
2873 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002874 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002875 SET_STR
2876 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002877 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002878{
2879 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2880}
2881
paul73ffb252003-04-19 15:49:49 +00002882ALIAS (set_metric,
2883 set_metric_addsub_cmd,
2884 "set metric <+/-metric>",
2885 SET_STR
2886 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00002887 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00002888
paul718e3742002-12-13 20:15:29 +00002889DEFUN (no_set_metric,
2890 no_set_metric_cmd,
2891 "no set metric",
2892 NO_STR
2893 SET_STR
2894 "Metric value for destination routing protocol\n")
2895{
2896 if (argc == 0)
2897 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
2898
2899 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
2900}
2901
2902ALIAS (no_set_metric,
2903 no_set_metric_val_cmd,
2904 "no set metric <0-4294967295>",
2905 NO_STR
2906 SET_STR
2907 "Metric value for destination routing protocol\n"
2908 "Metric value\n")
2909
2910DEFUN (set_local_pref,
2911 set_local_pref_cmd,
2912 "set local-preference <0-4294967295>",
2913 SET_STR
2914 "BGP local preference path attribute\n"
2915 "Preference value\n")
2916{
2917 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
2918}
2919
2920DEFUN (no_set_local_pref,
2921 no_set_local_pref_cmd,
2922 "no set local-preference",
2923 NO_STR
2924 SET_STR
2925 "BGP local preference path attribute\n")
2926{
2927 if (argc == 0)
2928 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
2929
2930 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
2931}
2932
2933ALIAS (no_set_local_pref,
2934 no_set_local_pref_val_cmd,
2935 "no set local-preference <0-4294967295>",
2936 NO_STR
2937 SET_STR
2938 "BGP local preference path attribute\n"
2939 "Preference value\n")
2940
2941DEFUN (set_weight,
2942 set_weight_cmd,
2943 "set weight <0-4294967295>",
2944 SET_STR
2945 "BGP weight for routing table\n"
2946 "Weight value\n")
2947{
2948 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
2949}
2950
2951DEFUN (no_set_weight,
2952 no_set_weight_cmd,
2953 "no set weight",
2954 NO_STR
2955 SET_STR
2956 "BGP weight for routing table\n")
2957{
2958 if (argc == 0)
2959 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
2960
2961 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
2962}
2963
2964ALIAS (no_set_weight,
2965 no_set_weight_val_cmd,
2966 "no set weight <0-4294967295>",
2967 NO_STR
2968 SET_STR
2969 "BGP weight for routing table\n"
2970 "Weight value\n")
2971
2972DEFUN (set_aspath_prepend,
2973 set_aspath_prepend_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04002974 "set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00002975 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00002976 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00002977 "Prepend to the as-path\n"
2978 "AS number\n")
2979{
2980 int ret;
2981 char *str;
2982
2983 str = argv_concat (argv, argc, 0);
2984 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
2985 XFREE (MTYPE_TMP, str);
2986
2987 return ret;
2988}
2989
2990DEFUN (no_set_aspath_prepend,
2991 no_set_aspath_prepend_cmd,
2992 "no set as-path prepend",
2993 NO_STR
2994 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00002995 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00002996 "Prepend to the as-path\n")
2997{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00002998 int ret;
2999 char *str;
3000
3001 if (argc == 0)
3002 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3003
3004 str = argv_concat (argv, argc, 0);
3005 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3006 XFREE (MTYPE_TMP, str);
3007 return ret;
paul718e3742002-12-13 20:15:29 +00003008}
3009
3010ALIAS (no_set_aspath_prepend,
3011 no_set_aspath_prepend_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003012 "no set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003013 NO_STR
3014 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003015 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003016 "Prepend to the as-path\n"
3017 "AS number\n")
3018
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003019DEFUN (set_aspath_exclude,
3020 set_aspath_exclude_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003021 "set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003022 SET_STR
3023 "Transform BGP AS-path attribute\n"
3024 "Exclude from the as-path\n"
3025 "AS number\n")
3026{
3027 int ret;
3028 char *str;
3029
3030 str = argv_concat (argv, argc, 0);
3031 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3032 XFREE (MTYPE_TMP, str);
3033 return ret;
3034}
3035
3036DEFUN (no_set_aspath_exclude,
3037 no_set_aspath_exclude_cmd,
3038 "no set as-path exclude",
3039 NO_STR
3040 SET_STR
3041 "Transform BGP AS_PATH attribute\n"
3042 "Exclude from the as-path\n")
3043{
3044 int ret;
3045 char *str;
3046
3047 if (argc == 0)
3048 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3049
3050 str = argv_concat (argv, argc, 0);
3051 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3052 XFREE (MTYPE_TMP, str);
3053 return ret;
3054}
3055
3056ALIAS (no_set_aspath_exclude,
3057 no_set_aspath_exclude_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003058 "no set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003059 NO_STR
3060 SET_STR
3061 "Transform BGP AS_PATH attribute\n"
3062 "Exclude from the as-path\n"
3063 "AS number\n")
3064
paul718e3742002-12-13 20:15:29 +00003065DEFUN (set_community,
3066 set_community_cmd,
3067 "set community .AA:NN",
3068 SET_STR
3069 "BGP community attribute\n"
3070 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3071{
3072 int i;
3073 int first = 0;
3074 int additive = 0;
3075 struct buffer *b;
3076 struct community *com = NULL;
3077 char *str;
3078 char *argstr;
3079 int ret;
3080
3081 b = buffer_new (1024);
3082
3083 for (i = 0; i < argc; i++)
3084 {
3085 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3086 {
3087 additive = 1;
3088 continue;
3089 }
3090
3091 if (first)
3092 buffer_putc (b, ' ');
3093 else
3094 first = 1;
3095
3096 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3097 {
3098 buffer_putstr (b, "internet");
3099 continue;
3100 }
3101 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3102 {
3103 buffer_putstr (b, "local-AS");
3104 continue;
3105 }
3106 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3107 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3108 {
3109 buffer_putstr (b, "no-advertise");
3110 continue;
3111 }
3112 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3113 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3114 {
3115 buffer_putstr (b, "no-export");
3116 continue;
3117 }
3118 buffer_putstr (b, argv[i]);
3119 }
3120 buffer_putc (b, '\0');
3121
3122 /* Fetch result string then compile it to communities attribute. */
3123 str = buffer_getstr (b);
3124 buffer_free (b);
3125
3126 if (str)
3127 {
3128 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003129 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003130 }
3131
3132 /* Can't compile user input into communities attribute. */
3133 if (! com)
3134 {
3135 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3136 return CMD_WARNING;
3137 }
3138
3139 /* Set communites attribute string. */
3140 str = community_str (com);
3141
3142 if (additive)
3143 {
3144 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3145 strcpy (argstr, str);
3146 strcpy (argstr + strlen (str), " additive");
3147 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3148 XFREE (MTYPE_TMP, argstr);
3149 }
3150 else
3151 ret = bgp_route_set_add (vty, vty->index, "community", str);
3152
3153 community_free (com);
3154
3155 return ret;
3156}
3157
3158DEFUN (set_community_none,
3159 set_community_none_cmd,
3160 "set community none",
3161 SET_STR
3162 "BGP community attribute\n"
3163 "No community attribute\n")
3164{
3165 return bgp_route_set_add (vty, vty->index, "community", "none");
3166}
3167
3168DEFUN (no_set_community,
3169 no_set_community_cmd,
3170 "no set community",
3171 NO_STR
3172 SET_STR
3173 "BGP community attribute\n")
3174{
3175 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3176}
3177
3178ALIAS (no_set_community,
3179 no_set_community_val_cmd,
3180 "no set community .AA:NN",
3181 NO_STR
3182 SET_STR
3183 "BGP community attribute\n"
3184 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3185
3186ALIAS (no_set_community,
3187 no_set_community_none_cmd,
3188 "no set community none",
3189 NO_STR
3190 SET_STR
3191 "BGP community attribute\n"
3192 "No community attribute\n")
3193
3194DEFUN (set_community_delete,
3195 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003196 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003197 SET_STR
3198 "set BGP community list (for deletion)\n"
3199 "Community-list number (standard)\n"
3200 "Communitly-list number (expanded)\n"
3201 "Community-list name\n"
3202 "Delete matching communities\n")
3203{
3204 char *str;
3205
3206 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3207 strcpy (str, argv[0]);
3208 strcpy (str + strlen (argv[0]), " delete");
3209
3210 bgp_route_set_add (vty, vty->index, "comm-list", str);
3211
3212 XFREE (MTYPE_TMP, str);
3213 return CMD_SUCCESS;
3214}
3215
3216DEFUN (no_set_community_delete,
3217 no_set_community_delete_cmd,
3218 "no set comm-list",
3219 NO_STR
3220 SET_STR
3221 "set BGP community list (for deletion)\n")
3222{
3223 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3224}
3225
3226ALIAS (no_set_community_delete,
3227 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003228 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003229 NO_STR
3230 SET_STR
3231 "set BGP community list (for deletion)\n"
3232 "Community-list number (standard)\n"
3233 "Communitly-list number (expanded)\n"
3234 "Community-list name\n"
3235 "Delete matching communities\n")
3236
3237DEFUN (set_ecommunity_rt,
3238 set_ecommunity_rt_cmd,
3239 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3240 SET_STR
3241 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003242 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003243 "VPN extended community\n")
3244{
3245 int ret;
3246 char *str;
3247
3248 str = argv_concat (argv, argc, 0);
3249 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3250 XFREE (MTYPE_TMP, str);
3251
3252 return ret;
3253}
3254
3255DEFUN (no_set_ecommunity_rt,
3256 no_set_ecommunity_rt_cmd,
3257 "no set extcommunity rt",
3258 NO_STR
3259 SET_STR
3260 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003261 "Route Target extended community\n")
paul718e3742002-12-13 20:15:29 +00003262{
3263 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3264}
3265
3266ALIAS (no_set_ecommunity_rt,
3267 no_set_ecommunity_rt_val_cmd,
3268 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3269 NO_STR
3270 SET_STR
3271 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003272 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003273 "VPN extended community\n")
3274
3275DEFUN (set_ecommunity_soo,
3276 set_ecommunity_soo_cmd,
3277 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3278 SET_STR
3279 "BGP extended community attribute\n"
3280 "Site-of-Origin extended community\n"
3281 "VPN extended community\n")
3282{
3283 int ret;
3284 char *str;
3285
3286 str = argv_concat (argv, argc, 0);
3287 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3288 XFREE (MTYPE_TMP, str);
3289 return ret;
3290}
3291
3292DEFUN (no_set_ecommunity_soo,
3293 no_set_ecommunity_soo_cmd,
3294 "no set extcommunity soo",
3295 NO_STR
3296 SET_STR
3297 "BGP extended community attribute\n"
3298 "Site-of-Origin extended community\n")
3299{
3300 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3301}
3302
3303ALIAS (no_set_ecommunity_soo,
3304 no_set_ecommunity_soo_val_cmd,
3305 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3306 NO_STR
3307 SET_STR
3308 "BGP extended community attribute\n"
3309 "Site-of-Origin extended community\n"
3310 "VPN extended community\n")
3311
3312DEFUN (set_origin,
3313 set_origin_cmd,
3314 "set origin (egp|igp|incomplete)",
3315 SET_STR
3316 "BGP origin code\n"
3317 "remote EGP\n"
3318 "local IGP\n"
3319 "unknown heritage\n")
3320{
3321 if (strncmp (argv[0], "igp", 2) == 0)
3322 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3323 if (strncmp (argv[0], "egp", 1) == 0)
3324 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3325 if (strncmp (argv[0], "incomplete", 2) == 0)
3326 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3327
3328 return CMD_WARNING;
3329}
3330
3331DEFUN (no_set_origin,
3332 no_set_origin_cmd,
3333 "no set origin",
3334 NO_STR
3335 SET_STR
3336 "BGP origin code\n")
3337{
3338 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3339}
3340
3341ALIAS (no_set_origin,
3342 no_set_origin_val_cmd,
3343 "no set origin (egp|igp|incomplete)",
3344 NO_STR
3345 SET_STR
3346 "BGP origin code\n"
3347 "remote EGP\n"
3348 "local IGP\n"
3349 "unknown heritage\n")
3350
3351DEFUN (set_atomic_aggregate,
3352 set_atomic_aggregate_cmd,
3353 "set atomic-aggregate",
3354 SET_STR
3355 "BGP atomic aggregate attribute\n" )
3356{
3357 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3358}
3359
3360DEFUN (no_set_atomic_aggregate,
3361 no_set_atomic_aggregate_cmd,
3362 "no set atomic-aggregate",
3363 NO_STR
3364 SET_STR
3365 "BGP atomic aggregate attribute\n" )
3366{
3367 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3368}
3369
3370DEFUN (set_aggregator_as,
3371 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003372 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003373 SET_STR
3374 "BGP aggregator attribute\n"
3375 "AS number of aggregator\n"
3376 "AS number\n"
3377 "IP address of aggregator\n")
3378{
3379 int ret;
3380 as_t as;
3381 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003382 char *argstr;
3383
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003384 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003385
paul718e3742002-12-13 20:15:29 +00003386 ret = inet_aton (argv[1], &address);
3387 if (ret == 0)
3388 {
3389 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3390 return CMD_WARNING;
3391 }
3392
3393 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3394 strlen (argv[0]) + strlen (argv[1]) + 2);
3395
3396 sprintf (argstr, "%s %s", argv[0], argv[1]);
3397
3398 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3399
3400 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3401
3402 return ret;
3403}
3404
3405DEFUN (no_set_aggregator_as,
3406 no_set_aggregator_as_cmd,
3407 "no set aggregator as",
3408 NO_STR
3409 SET_STR
3410 "BGP aggregator attribute\n"
3411 "AS number of aggregator\n")
3412{
3413 int ret;
3414 as_t as;
3415 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003416 char *argstr;
3417
3418 if (argv == 0)
3419 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3420
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003421 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003422
3423 ret = inet_aton (argv[1], &address);
3424 if (ret == 0)
3425 {
3426 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3427 return CMD_WARNING;
3428 }
3429
3430 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3431 strlen (argv[0]) + strlen (argv[1]) + 2);
3432
3433 sprintf (argstr, "%s %s", argv[0], argv[1]);
3434
3435 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3436
3437 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3438
3439 return ret;
3440}
3441
3442ALIAS (no_set_aggregator_as,
3443 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003444 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003445 NO_STR
3446 SET_STR
3447 "BGP aggregator attribute\n"
3448 "AS number of aggregator\n"
3449 "AS number\n"
3450 "IP address of aggregator\n")
3451
3452
3453#ifdef HAVE_IPV6
3454DEFUN (match_ipv6_address,
3455 match_ipv6_address_cmd,
3456 "match ipv6 address WORD",
3457 MATCH_STR
3458 IPV6_STR
3459 "Match IPv6 address of route\n"
3460 "IPv6 access-list name\n")
3461{
3462 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3463}
3464
3465DEFUN (no_match_ipv6_address,
3466 no_match_ipv6_address_cmd,
3467 "no match ipv6 address WORD",
3468 NO_STR
3469 MATCH_STR
3470 IPV6_STR
3471 "Match IPv6 address of route\n"
3472 "IPv6 access-list name\n")
3473{
3474 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3475}
3476
3477DEFUN (match_ipv6_next_hop,
3478 match_ipv6_next_hop_cmd,
3479 "match ipv6 next-hop X:X::X:X",
3480 MATCH_STR
3481 IPV6_STR
3482 "Match IPv6 next-hop address of route\n"
3483 "IPv6 address of next hop\n")
3484{
3485 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3486}
3487
3488DEFUN (no_match_ipv6_next_hop,
3489 no_match_ipv6_next_hop_cmd,
3490 "no match ipv6 next-hop X:X::X:X",
3491 NO_STR
3492 MATCH_STR
3493 IPV6_STR
3494 "Match IPv6 next-hop address of route\n"
3495 "IPv6 address of next hop\n")
3496{
3497 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3498}
3499
3500DEFUN (match_ipv6_address_prefix_list,
3501 match_ipv6_address_prefix_list_cmd,
3502 "match ipv6 address prefix-list WORD",
3503 MATCH_STR
3504 IPV6_STR
3505 "Match address of route\n"
3506 "Match entries of prefix-lists\n"
3507 "IP prefix-list name\n")
3508{
3509 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3510}
3511
3512DEFUN (no_match_ipv6_address_prefix_list,
3513 no_match_ipv6_address_prefix_list_cmd,
3514 "no match ipv6 address prefix-list WORD",
3515 NO_STR
3516 MATCH_STR
3517 IPV6_STR
3518 "Match address of route\n"
3519 "Match entries of prefix-lists\n"
3520 "IP prefix-list name\n")
3521{
3522 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3523}
3524
3525DEFUN (set_ipv6_nexthop_global,
3526 set_ipv6_nexthop_global_cmd,
3527 "set ipv6 next-hop global X:X::X:X",
3528 SET_STR
3529 IPV6_STR
3530 "IPv6 next-hop address\n"
3531 "IPv6 global address\n"
3532 "IPv6 address of next hop\n")
3533{
3534 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3535}
3536
3537DEFUN (no_set_ipv6_nexthop_global,
3538 no_set_ipv6_nexthop_global_cmd,
3539 "no set ipv6 next-hop global",
3540 NO_STR
3541 SET_STR
3542 IPV6_STR
3543 "IPv6 next-hop address\n"
3544 "IPv6 global address\n")
3545{
3546 if (argc == 0)
3547 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3548
3549 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3550}
3551
3552ALIAS (no_set_ipv6_nexthop_global,
3553 no_set_ipv6_nexthop_global_val_cmd,
3554 "no set ipv6 next-hop global X:X::X:X",
3555 NO_STR
3556 SET_STR
3557 IPV6_STR
3558 "IPv6 next-hop address\n"
3559 "IPv6 global address\n"
3560 "IPv6 address of next hop\n")
3561
3562DEFUN (set_ipv6_nexthop_local,
3563 set_ipv6_nexthop_local_cmd,
3564 "set ipv6 next-hop local X:X::X:X",
3565 SET_STR
3566 IPV6_STR
3567 "IPv6 next-hop address\n"
3568 "IPv6 local address\n"
3569 "IPv6 address of next hop\n")
3570{
3571 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3572}
3573
3574DEFUN (no_set_ipv6_nexthop_local,
3575 no_set_ipv6_nexthop_local_cmd,
3576 "no set ipv6 next-hop local",
3577 NO_STR
3578 SET_STR
3579 IPV6_STR
3580 "IPv6 next-hop address\n"
3581 "IPv6 local address\n")
3582{
3583 if (argc == 0)
3584 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3585
3586 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3587}
3588
3589ALIAS (no_set_ipv6_nexthop_local,
3590 no_set_ipv6_nexthop_local_val_cmd,
3591 "no set ipv6 next-hop local X:X::X:X",
3592 NO_STR
3593 SET_STR
3594 IPV6_STR
3595 "IPv6 next-hop address\n"
3596 "IPv6 local address\n"
3597 "IPv6 address of next hop\n")
3598#endif /* HAVE_IPV6 */
3599
3600DEFUN (set_vpnv4_nexthop,
3601 set_vpnv4_nexthop_cmd,
3602 "set vpnv4 next-hop A.B.C.D",
3603 SET_STR
3604 "VPNv4 information\n"
3605 "VPNv4 next-hop address\n"
3606 "IP address of next hop\n")
3607{
3608 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3609}
3610
3611DEFUN (no_set_vpnv4_nexthop,
3612 no_set_vpnv4_nexthop_cmd,
3613 "no set vpnv4 next-hop",
3614 NO_STR
3615 SET_STR
3616 "VPNv4 information\n"
3617 "VPNv4 next-hop address\n")
3618{
3619 if (argc == 0)
3620 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3621
3622 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3623}
3624
3625ALIAS (no_set_vpnv4_nexthop,
3626 no_set_vpnv4_nexthop_val_cmd,
3627 "no set vpnv4 next-hop A.B.C.D",
3628 NO_STR
3629 SET_STR
3630 "VPNv4 information\n"
3631 "VPNv4 next-hop address\n"
3632 "IP address of next hop\n")
3633
3634DEFUN (set_originator_id,
3635 set_originator_id_cmd,
3636 "set originator-id A.B.C.D",
3637 SET_STR
3638 "BGP originator ID attribute\n"
3639 "IP address of originator\n")
3640{
3641 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3642}
3643
3644DEFUN (no_set_originator_id,
3645 no_set_originator_id_cmd,
3646 "no set originator-id",
3647 NO_STR
3648 SET_STR
3649 "BGP originator ID attribute\n")
3650{
3651 if (argc == 0)
3652 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3653
3654 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3655}
3656
3657ALIAS (no_set_originator_id,
3658 no_set_originator_id_val_cmd,
3659 "no set originator-id A.B.C.D",
3660 NO_STR
3661 SET_STR
3662 "BGP originator ID attribute\n"
3663 "IP address of originator\n")
3664
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003665DEFUN_DEPRECATED (set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003666 set_pathlimit_ttl_cmd,
3667 "set pathlimit ttl <1-255>",
3668 SET_STR
3669 "BGP AS-Pathlimit attribute\n"
3670 "Set AS-Path Hop-count TTL\n")
3671{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003672 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003673}
3674
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003675DEFUN_DEPRECATED (no_set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003676 no_set_pathlimit_ttl_cmd,
3677 "no set pathlimit ttl",
3678 NO_STR
3679 SET_STR
3680 "BGP AS-Pathlimit attribute\n"
3681 "Set AS-Path Hop-count TTL\n")
3682{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003683 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003684}
3685
3686ALIAS (no_set_pathlimit_ttl,
3687 no_set_pathlimit_ttl_val_cmd,
3688 "no set pathlimit ttl <1-255>",
3689 NO_STR
3690 MATCH_STR
3691 "BGP AS-Pathlimit attribute\n"
3692 "Set AS-Path Hop-count TTL\n")
3693
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003694DEFUN_DEPRECATED (match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003695 match_pathlimit_as_cmd,
3696 "match pathlimit as <1-65535>",
3697 MATCH_STR
3698 "BGP AS-Pathlimit attribute\n"
3699 "Match Pathlimit AS number\n")
3700{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003701 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003702}
3703
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003704DEFUN_DEPRECATED (no_match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003705 no_match_pathlimit_as_cmd,
3706 "no match pathlimit as",
3707 NO_STR
3708 MATCH_STR
3709 "BGP AS-Pathlimit attribute\n"
3710 "Match Pathlimit AS number\n")
3711{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003712 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003713}
3714
3715ALIAS (no_match_pathlimit_as,
3716 no_match_pathlimit_as_val_cmd,
3717 "no match pathlimit as <1-65535>",
3718 NO_STR
3719 MATCH_STR
3720 "BGP AS-Pathlimit attribute\n"
3721 "Match Pathlimit ASN\n")
3722
paul718e3742002-12-13 20:15:29 +00003723
3724/* Initialization of route map. */
3725void
paul94f2b392005-06-28 12:44:16 +00003726bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003727{
3728 route_map_init ();
3729 route_map_init_vty ();
3730 route_map_add_hook (bgp_route_map_update);
3731 route_map_delete_hook (bgp_route_map_update);
3732
paulfee0f4c2004-09-13 05:12:46 +00003733 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003734 route_map_install_match (&route_match_ip_address_cmd);
3735 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003736 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003737 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3738 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003739 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003740 route_map_install_match (&route_match_aspath_cmd);
3741 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003742 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003743 route_map_install_match (&route_match_metric_cmd);
3744 route_map_install_match (&route_match_origin_cmd);
3745
3746 route_map_install_set (&route_set_ip_nexthop_cmd);
3747 route_map_install_set (&route_set_local_pref_cmd);
3748 route_map_install_set (&route_set_weight_cmd);
3749 route_map_install_set (&route_set_metric_cmd);
3750 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003751 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003752 route_map_install_set (&route_set_origin_cmd);
3753 route_map_install_set (&route_set_atomic_aggregate_cmd);
3754 route_map_install_set (&route_set_aggregator_as_cmd);
3755 route_map_install_set (&route_set_community_cmd);
3756 route_map_install_set (&route_set_community_delete_cmd);
3757 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3758 route_map_install_set (&route_set_originator_id_cmd);
3759 route_map_install_set (&route_set_ecommunity_rt_cmd);
3760 route_map_install_set (&route_set_ecommunity_soo_cmd);
3761
paulfee0f4c2004-09-13 05:12:46 +00003762 install_element (RMAP_NODE, &match_peer_cmd);
3763 install_element (RMAP_NODE, &match_peer_local_cmd);
3764 install_element (RMAP_NODE, &no_match_peer_cmd);
3765 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3766 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003767 install_element (RMAP_NODE, &match_ip_address_cmd);
3768 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3769 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3770 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3771 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3772 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003773 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3774 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3775 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003776
3777 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3778 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3779 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3780 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3781 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3782 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003783 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3784 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3785 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003786
3787 install_element (RMAP_NODE, &match_aspath_cmd);
3788 install_element (RMAP_NODE, &no_match_aspath_cmd);
3789 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3790 install_element (RMAP_NODE, &match_metric_cmd);
3791 install_element (RMAP_NODE, &no_match_metric_cmd);
3792 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3793 install_element (RMAP_NODE, &match_community_cmd);
3794 install_element (RMAP_NODE, &match_community_exact_cmd);
3795 install_element (RMAP_NODE, &no_match_community_cmd);
3796 install_element (RMAP_NODE, &no_match_community_val_cmd);
3797 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003798 install_element (RMAP_NODE, &match_ecommunity_cmd);
3799 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3800 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003801 install_element (RMAP_NODE, &match_origin_cmd);
3802 install_element (RMAP_NODE, &no_match_origin_cmd);
3803 install_element (RMAP_NODE, &no_match_origin_val_cmd);
3804
3805 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003806 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003807 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3808 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3809 install_element (RMAP_NODE, &set_local_pref_cmd);
3810 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3811 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3812 install_element (RMAP_NODE, &set_weight_cmd);
3813 install_element (RMAP_NODE, &no_set_weight_cmd);
3814 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3815 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003816 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003817 install_element (RMAP_NODE, &no_set_metric_cmd);
3818 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3819 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003820 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003821 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3822 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003823 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
3824 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00003825 install_element (RMAP_NODE, &set_origin_cmd);
3826 install_element (RMAP_NODE, &no_set_origin_cmd);
3827 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3828 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3829 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3830 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3831 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3832 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3833 install_element (RMAP_NODE, &set_community_cmd);
3834 install_element (RMAP_NODE, &set_community_none_cmd);
3835 install_element (RMAP_NODE, &no_set_community_cmd);
3836 install_element (RMAP_NODE, &no_set_community_val_cmd);
3837 install_element (RMAP_NODE, &no_set_community_none_cmd);
3838 install_element (RMAP_NODE, &set_community_delete_cmd);
3839 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3840 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3841 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3842 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3843 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3844 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3845 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3846 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3847 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3848 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3849 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3850 install_element (RMAP_NODE, &set_originator_id_cmd);
3851 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3852 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3853
3854#ifdef HAVE_IPV6
3855 route_map_install_match (&route_match_ipv6_address_cmd);
3856 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3857 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3858 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3859 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Paul Jakma41367172007-08-06 15:24:51 +00003860
paul718e3742002-12-13 20:15:29 +00003861 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3862 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3863 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3864 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3865 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3866 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3867 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3868 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3869 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3870 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3871 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3872 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3873#endif /* HAVE_IPV6 */
Paul Jakma41367172007-08-06 15:24:51 +00003874
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003875 /* AS-Pathlimit: functionality removed, commands kept for
3876 * compatibility.
3877 */
Paul Jakma41367172007-08-06 15:24:51 +00003878 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
3879 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
3880 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
3881 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
3882 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
3883 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00003884}