blob: abb85fd219bdbed1de58c657212d0cba44db9647 [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
Ulrich Weber664711c2011-12-21 02:24:11 +0400528 /* Metric value shoud be integer. */
529 if (! all_digit (arg))
530 return NULL;
531
532 errno = 0;
paul3b424972003-10-13 09:47:32 +0000533 tmpval = strtoul (arg, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +0400534 if (*endptr != '\0' || errno || tmpval > UINT32_MAX)
paul3b424972003-10-13 09:47:32 +0000535 return NULL;
paulfd79ac92004-10-13 05:06:08 +0000536
paul718e3742002-12-13 20:15:29 +0000537 med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +0000538
539 if (!med)
540 return med;
541
paul3b424972003-10-13 09:47:32 +0000542 *med = tmpval;
paul718e3742002-12-13 20:15:29 +0000543 return med;
544}
545
546/* Free route map's compiled `match metric' value. */
paul94f2b392005-06-28 12:44:16 +0000547static void
paul718e3742002-12-13 20:15:29 +0000548route_match_metric_free (void *rule)
549{
550 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
551}
552
553/* Route map commands for metric matching. */
554struct route_map_rule_cmd route_match_metric_cmd =
555{
556 "metric",
557 route_match_metric,
558 route_match_metric_compile,
559 route_match_metric_free
560};
561
562/* `match as-path ASPATH' */
563
564/* Match function for as-path match. I assume given object is */
paul94f2b392005-06-28 12:44:16 +0000565static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000566route_match_aspath (void *rule, struct prefix *prefix,
567 route_map_object_t type, void *object)
568{
569
570 struct as_list *as_list;
571 struct bgp_info *bgp_info;
572
573 if (type == RMAP_BGP)
574 {
575 as_list = as_list_lookup ((char *) rule);
576 if (as_list == NULL)
577 return RMAP_NOMATCH;
578
579 bgp_info = object;
580
581 /* Perform match. */
582 return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
583 }
584 return RMAP_NOMATCH;
585}
586
587/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000588static void *
paulfd79ac92004-10-13 05:06:08 +0000589route_match_aspath_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000590{
591 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
592}
593
594/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000595static void
paul718e3742002-12-13 20:15:29 +0000596route_match_aspath_free (void *rule)
597{
598 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
599}
600
601/* Route map commands for aspath matching. */
602struct route_map_rule_cmd route_match_aspath_cmd =
603{
604 "as-path",
605 route_match_aspath,
606 route_match_aspath_compile,
607 route_match_aspath_free
608};
paul718e3742002-12-13 20:15:29 +0000609
610/* `match community COMMUNIY' */
611struct rmap_community
612{
613 char *name;
614 int exact;
615};
616
617/* Match function for community match. */
paul94f2b392005-06-28 12:44:16 +0000618static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000619route_match_community (void *rule, struct prefix *prefix,
620 route_map_object_t type, void *object)
621{
622 struct community_list *list;
623 struct bgp_info *bgp_info;
624 struct rmap_community *rcom;
625
626 if (type == RMAP_BGP)
627 {
628 bgp_info = object;
629 rcom = rule;
630
hassofee6e4e2005-02-02 16:29:31 +0000631 list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +0000632 if (! list)
633 return RMAP_NOMATCH;
634
635 if (rcom->exact)
636 {
637 if (community_list_exact_match (bgp_info->attr->community, list))
638 return RMAP_MATCH;
639 }
640 else
641 {
642 if (community_list_match (bgp_info->attr->community, list))
643 return RMAP_MATCH;
644 }
645 }
646 return RMAP_NOMATCH;
647}
648
649/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000650static void *
paulfd79ac92004-10-13 05:06:08 +0000651route_match_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000652{
653 struct rmap_community *rcom;
654 int len;
655 char *p;
656
657 rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
658
659 p = strchr (arg, ' ');
660 if (p)
661 {
662 len = p - arg;
663 rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
664 memcpy (rcom->name, arg, len);
665 rcom->exact = 1;
666 }
667 else
668 {
669 rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
670 rcom->exact = 0;
671 }
672 return rcom;
673}
674
675/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000676static void
paul718e3742002-12-13 20:15:29 +0000677route_match_community_free (void *rule)
678{
679 struct rmap_community *rcom = rule;
680
681 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
682 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
683}
684
685/* Route map commands for community matching. */
686struct route_map_rule_cmd route_match_community_cmd =
687{
688 "community",
689 route_match_community,
690 route_match_community_compile,
691 route_match_community_free
692};
693
paul73ffb252003-04-19 15:49:49 +0000694/* Match function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000695static route_map_result_t
paul73ffb252003-04-19 15:49:49 +0000696route_match_ecommunity (void *rule, struct prefix *prefix,
697 route_map_object_t type, void *object)
698{
699 struct community_list *list;
700 struct bgp_info *bgp_info;
701
702 if (type == RMAP_BGP)
703 {
704 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +0000705
706 if (!bgp_info->attr->extra)
707 return RMAP_NOMATCH;
708
paul73ffb252003-04-19 15:49:49 +0000709 list = community_list_lookup (bgp_clist, (char *) rule,
hassofee6e4e2005-02-02 16:29:31 +0000710 EXTCOMMUNITY_LIST_MASTER);
paul73ffb252003-04-19 15:49:49 +0000711 if (! list)
712 return RMAP_NOMATCH;
713
Paul Jakmafb982c22007-05-04 20:15:47 +0000714 if (ecommunity_list_match (bgp_info->attr->extra->ecommunity, list))
paul73ffb252003-04-19 15:49:49 +0000715 return RMAP_MATCH;
716 }
717 return RMAP_NOMATCH;
718}
719
720/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000721static void *
paulfd79ac92004-10-13 05:06:08 +0000722route_match_ecommunity_compile (const char *arg)
paul73ffb252003-04-19 15:49:49 +0000723{
724 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
725}
726
727/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000728static void
paul73ffb252003-04-19 15:49:49 +0000729route_match_ecommunity_free (void *rule)
730{
731 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
732}
733
734/* Route map commands for community matching. */
735struct route_map_rule_cmd route_match_ecommunity_cmd =
736{
737 "extcommunity",
738 route_match_ecommunity,
739 route_match_ecommunity_compile,
740 route_match_ecommunity_free
741};
742
paul718e3742002-12-13 20:15:29 +0000743/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
744 and `address-family vpnv4'. */
745
746/* `match origin' */
paul94f2b392005-06-28 12:44:16 +0000747static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000748route_match_origin (void *rule, struct prefix *prefix,
749 route_map_object_t type, void *object)
750{
751 u_char *origin;
752 struct bgp_info *bgp_info;
753
754 if (type == RMAP_BGP)
755 {
756 origin = rule;
757 bgp_info = object;
758
759 if (bgp_info->attr->origin == *origin)
760 return RMAP_MATCH;
761 }
762
763 return RMAP_NOMATCH;
764}
765
paul94f2b392005-06-28 12:44:16 +0000766static void *
paulfd79ac92004-10-13 05:06:08 +0000767route_match_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000768{
769 u_char *origin;
770
771 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
772
773 if (strcmp (arg, "igp") == 0)
774 *origin = 0;
775 else if (strcmp (arg, "egp") == 0)
776 *origin = 1;
777 else
778 *origin = 2;
779
780 return origin;
781}
782
783/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000784static void
paul718e3742002-12-13 20:15:29 +0000785route_match_origin_free (void *rule)
786{
787 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
788}
789
790/* Route map commands for origin matching. */
791struct route_map_rule_cmd route_match_origin_cmd =
792{
793 "origin",
794 route_match_origin,
795 route_match_origin_compile,
796 route_match_origin_free
797};
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400798
799/* match probability { */
800
801static route_map_result_t
802route_match_probability (void *rule, struct prefix *prefix,
803 route_map_object_t type, void *object)
804{
805 long r;
806#if _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500
807 r = random();
808#else
809 r = (long) rand();
810#endif
811
812 switch (*(unsigned *) rule)
813 {
814 case 0: break;
815 case RAND_MAX: return RMAP_MATCH;
816 default:
817 if (r < *(unsigned *) rule)
818 {
819 return RMAP_MATCH;
820 }
821 }
822
823 return RMAP_NOMATCH;
824}
825
826static void *
827route_match_probability_compile (const char *arg)
828{
829 unsigned *lobule;
830 unsigned perc;
831
832#if _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500
833 srandom (time (NULL));
834#else
835 srand (time (NULL));
836#endif
837
838 perc = atoi (arg);
839 lobule = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (unsigned));
840
841 switch (perc)
842 {
843 case 0: *lobule = 0; break;
844 case 100: *lobule = RAND_MAX; break;
845 default: *lobule = RAND_MAX / 100 * perc;
846 }
847
848 return lobule;
849}
850
851static void
852route_match_probability_free (void *rule)
853{
854 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
855}
856
857struct route_map_rule_cmd route_match_probability_cmd =
858{
859 "probability",
860 route_match_probability,
861 route_match_probability_compile,
862 route_match_probability_free
863};
864
865/* } */
866
paul718e3742002-12-13 20:15:29 +0000867/* `set ip next-hop IP_ADDRESS' */
868
869/* Set nexthop to object. ojbect must be pointer to struct attr. */
paulac41b2a2003-08-12 05:32:27 +0000870struct rmap_ip_nexthop_set
871{
872 struct in_addr *address;
873 int peer_address;
874};
875
paul94f2b392005-06-28 12:44:16 +0000876static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000877route_set_ip_nexthop (void *rule, struct prefix *prefix,
878 route_map_object_t type, void *object)
879{
paulac41b2a2003-08-12 05:32:27 +0000880 struct rmap_ip_nexthop_set *rins = rule;
881 struct in_addr peer_address;
paul718e3742002-12-13 20:15:29 +0000882 struct bgp_info *bgp_info;
paulac41b2a2003-08-12 05:32:27 +0000883 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000884
885 if (type == RMAP_BGP)
886 {
paul718e3742002-12-13 20:15:29 +0000887 bgp_info = object;
paulac41b2a2003-08-12 05:32:27 +0000888 peer = bgp_info->peer;
889
890 if (rins->peer_address)
891 {
paulfee0f4c2004-09-13 05:12:46 +0000892 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
893 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
paulac41b2a2003-08-12 05:32:27 +0000894 && peer->su_remote
895 && sockunion_family (peer->su_remote) == AF_INET)
896 {
897 inet_aton (sockunion_su2str (peer->su_remote), &peer_address);
898 bgp_info->attr->nexthop = peer_address;
899 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
900 }
901 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
902 && peer->su_local
903 && sockunion_family (peer->su_local) == AF_INET)
904 {
905 inet_aton (sockunion_su2str (peer->su_local), &peer_address);
906 bgp_info->attr->nexthop = peer_address;
907 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
908 }
909 }
910 else
911 {
912 /* Set next hop value. */
913 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
914 bgp_info->attr->nexthop = *rins->address;
915 }
paul718e3742002-12-13 20:15:29 +0000916 }
917
918 return RMAP_OKAY;
919}
920
921/* Route map `ip nexthop' compile function. Given string is converted
922 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +0000923static void *
paulfd79ac92004-10-13 05:06:08 +0000924route_set_ip_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000925{
paulac41b2a2003-08-12 05:32:27 +0000926 struct rmap_ip_nexthop_set *rins;
927 struct in_addr *address = NULL;
928 int peer_address = 0;
paul718e3742002-12-13 20:15:29 +0000929 int ret;
paul718e3742002-12-13 20:15:29 +0000930
paulac41b2a2003-08-12 05:32:27 +0000931 if (strcmp (arg, "peer-address") == 0)
932 peer_address = 1;
933 else
paul718e3742002-12-13 20:15:29 +0000934 {
paulac41b2a2003-08-12 05:32:27 +0000935 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
936 ret = inet_aton (arg, address);
937
938 if (ret == 0)
939 {
940 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
941 return NULL;
942 }
paul718e3742002-12-13 20:15:29 +0000943 }
944
Stephen Hemminger393deb92008-08-18 14:13:29 -0700945 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
paulac41b2a2003-08-12 05:32:27 +0000946
947 rins->address = address;
948 rins->peer_address = peer_address;
949
950 return rins;
paul718e3742002-12-13 20:15:29 +0000951}
952
953/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +0000954static void
paul718e3742002-12-13 20:15:29 +0000955route_set_ip_nexthop_free (void *rule)
956{
paulac41b2a2003-08-12 05:32:27 +0000957 struct rmap_ip_nexthop_set *rins = rule;
958
959 if (rins->address)
960 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
961
962 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +0000963}
964
965/* Route map commands for ip nexthop set. */
966struct route_map_rule_cmd route_set_ip_nexthop_cmd =
967{
968 "ip next-hop",
969 route_set_ip_nexthop,
970 route_set_ip_nexthop_compile,
971 route_set_ip_nexthop_free
972};
973
974/* `set local-preference LOCAL_PREF' */
975
976/* Set local preference. */
paul94f2b392005-06-28 12:44:16 +0000977static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000978route_set_local_pref (void *rule, struct prefix *prefix,
979 route_map_object_t type, void *object)
980{
981 u_int32_t *local_pref;
982 struct bgp_info *bgp_info;
983
984 if (type == RMAP_BGP)
985 {
986 /* Fetch routemap's rule information. */
987 local_pref = rule;
988 bgp_info = object;
989
990 /* Set local preference value. */
991 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
992 bgp_info->attr->local_pref = *local_pref;
993 }
994
995 return RMAP_OKAY;
996}
997
998/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +0000999static void *
paulfd79ac92004-10-13 05:06:08 +00001000route_set_local_pref_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001001{
paulfd79ac92004-10-13 05:06:08 +00001002 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +00001003 u_int32_t *local_pref;
1004 char *endptr = NULL;
1005
1006 /* Local preference value shoud be integer. */
1007 if (! all_digit (arg))
1008 return NULL;
paulfd79ac92004-10-13 05:06:08 +00001009
Ulrich Weber664711c2011-12-21 02:24:11 +04001010 errno = 0;
paulfd79ac92004-10-13 05:06:08 +00001011 tmp = strtoul (arg, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +04001012 if (*endptr != '\0' || errno || tmp > UINT32_MAX)
paulfd79ac92004-10-13 05:06:08 +00001013 return NULL;
1014
1015 local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
1016
1017 if (!local_pref)
1018 return local_pref;
1019
1020 *local_pref = tmp;
1021
paul718e3742002-12-13 20:15:29 +00001022 return local_pref;
1023}
1024
1025/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +00001026static void
paul718e3742002-12-13 20:15:29 +00001027route_set_local_pref_free (void *rule)
1028{
1029 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1030}
1031
1032/* Set local preference rule structure. */
1033struct route_map_rule_cmd route_set_local_pref_cmd =
1034{
1035 "local-preference",
1036 route_set_local_pref,
1037 route_set_local_pref_compile,
1038 route_set_local_pref_free,
1039};
1040
1041/* `set weight WEIGHT' */
1042
1043/* Set weight. */
paul94f2b392005-06-28 12:44:16 +00001044static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001045route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
1046 void *object)
1047{
1048 u_int32_t *weight;
1049 struct bgp_info *bgp_info;
1050
1051 if (type == RMAP_BGP)
1052 {
1053 /* Fetch routemap's rule information. */
1054 weight = rule;
1055 bgp_info = object;
1056
1057 /* Set weight value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001058 if (*weight)
1059 (bgp_attr_extra_get (bgp_info->attr))->weight = *weight;
1060 else if (bgp_info->attr->extra)
1061 bgp_info->attr->extra->weight = 0;
paul718e3742002-12-13 20:15:29 +00001062 }
1063
1064 return RMAP_OKAY;
1065}
1066
1067/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +00001068static void *
paulfd79ac92004-10-13 05:06:08 +00001069route_set_weight_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001070{
paulfd79ac92004-10-13 05:06:08 +00001071 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +00001072 u_int32_t *weight;
1073 char *endptr = NULL;
1074
1075 /* Local preference value shoud be integer. */
1076 if (! all_digit (arg))
1077 return NULL;
1078
Ulrich Weber664711c2011-12-21 02:24:11 +04001079 errno = 0;
paulfd79ac92004-10-13 05:06:08 +00001080 tmp = strtoul (arg, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +04001081 if (*endptr != '\0' || errno || tmp > UINT32_MAX)
paulfd79ac92004-10-13 05:06:08 +00001082 return NULL;
1083
paul718e3742002-12-13 20:15:29 +00001084 weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +00001085
1086 if (weight == NULL)
1087 return weight;
1088
1089 *weight = tmp;
1090
paul718e3742002-12-13 20:15:29 +00001091 return weight;
1092}
1093
1094/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +00001095static void
paul718e3742002-12-13 20:15:29 +00001096route_set_weight_free (void *rule)
1097{
1098 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1099}
1100
1101/* Set local preference rule structure. */
1102struct route_map_rule_cmd route_set_weight_cmd =
1103{
1104 "weight",
1105 route_set_weight,
1106 route_set_weight_compile,
1107 route_set_weight_free,
1108};
1109
1110/* `set metric METRIC' */
1111
1112/* Set metric to attribute. */
paul94f2b392005-06-28 12:44:16 +00001113static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001114route_set_metric (void *rule, struct prefix *prefix,
1115 route_map_object_t type, void *object)
1116{
1117 char *metric;
1118 u_int32_t metric_val;
1119 struct bgp_info *bgp_info;
1120
1121 if (type == RMAP_BGP)
1122 {
1123 /* Fetch routemap's rule information. */
1124 metric = rule;
1125 bgp_info = object;
1126
1127 if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
1128 bgp_info->attr->med = 0;
1129 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
1130
1131 if (all_digit (metric))
1132 {
1133 metric_val = strtoul (metric, (char **)NULL, 10);
1134 bgp_info->attr->med = metric_val;
1135 }
1136 else
1137 {
1138 metric_val = strtoul (metric+1, (char **)NULL, 10);
1139
1140 if (strncmp (metric, "+", 1) == 0)
1141 {
paul3b424972003-10-13 09:47:32 +00001142 if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2)
1143 bgp_info->attr->med = BGP_MED_MAX - 1;
paul718e3742002-12-13 20:15:29 +00001144 else
paul537d8ea2003-08-27 06:45:32 +00001145 bgp_info->attr->med += metric_val;
paul718e3742002-12-13 20:15:29 +00001146 }
1147 else if (strncmp (metric, "-", 1) == 0)
1148 {
paul537d8ea2003-08-27 06:45:32 +00001149 if (bgp_info->attr->med <= metric_val)
1150 bgp_info->attr->med = 0;
paul718e3742002-12-13 20:15:29 +00001151 else
paul537d8ea2003-08-27 06:45:32 +00001152 bgp_info->attr->med -= metric_val;
paul718e3742002-12-13 20:15:29 +00001153 }
1154 }
1155 }
1156 return RMAP_OKAY;
1157}
1158
1159/* set metric compilation. */
paul94f2b392005-06-28 12:44:16 +00001160static void *
paulfd79ac92004-10-13 05:06:08 +00001161route_set_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001162{
1163 u_int32_t metric;
paul94f2b392005-06-28 12:44:16 +00001164 unsigned long larg;
paul718e3742002-12-13 20:15:29 +00001165 char *endptr = NULL;
1166
1167 if (all_digit (arg))
1168 {
1169 /* set metric value check*/
Ulrich Weber664711c2011-12-21 02:24:11 +04001170 errno = 0;
paul94f2b392005-06-28 12:44:16 +00001171 larg = strtoul (arg, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +04001172 if (*endptr != '\0' || errno || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001173 return NULL;
paul94f2b392005-06-28 12:44:16 +00001174 metric = larg;
paul718e3742002-12-13 20:15:29 +00001175 }
1176 else
1177 {
1178 /* set metric +/-value check */
1179 if ((strncmp (arg, "+", 1) != 0
1180 && strncmp (arg, "-", 1) != 0)
1181 || (! all_digit (arg+1)))
1182 return NULL;
1183
Ulrich Weber664711c2011-12-21 02:24:11 +04001184 errno = 0;
paul94f2b392005-06-28 12:44:16 +00001185 larg = strtoul (arg+1, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +04001186 if (*endptr != '\0' || errno || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001187 return NULL;
paul94f2b392005-06-28 12:44:16 +00001188 metric = larg;
paul718e3742002-12-13 20:15:29 +00001189 }
1190
1191 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1192}
1193
1194/* Free route map's compiled `set metric' value. */
paul94f2b392005-06-28 12:44:16 +00001195static void
paul718e3742002-12-13 20:15:29 +00001196route_set_metric_free (void *rule)
1197{
1198 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1199}
1200
1201/* Set metric rule structure. */
1202struct route_map_rule_cmd route_set_metric_cmd =
1203{
1204 "metric",
1205 route_set_metric,
1206 route_set_metric_compile,
1207 route_set_metric_free,
1208};
1209
1210/* `set as-path prepend ASPATH' */
1211
1212/* For AS path prepend mechanism. */
paul94f2b392005-06-28 12:44:16 +00001213static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001214route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1215{
1216 struct aspath *aspath;
1217 struct aspath *new;
1218 struct bgp_info *binfo;
1219
1220 if (type == RMAP_BGP)
1221 {
1222 aspath = rule;
1223 binfo = object;
1224
1225 if (binfo->attr->aspath->refcnt)
1226 new = aspath_dup (binfo->attr->aspath);
1227 else
1228 new = binfo->attr->aspath;
1229
1230 aspath_prepend (aspath, new);
1231 binfo->attr->aspath = new;
1232 }
1233
1234 return RMAP_OKAY;
1235}
1236
1237/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001238static void *
paulfd79ac92004-10-13 05:06:08 +00001239route_set_aspath_prepend_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001240{
1241 struct aspath *aspath;
1242
1243 aspath = aspath_str2aspath (arg);
1244 if (! aspath)
1245 return NULL;
1246 return aspath;
1247}
1248
1249/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001250static void
paul718e3742002-12-13 20:15:29 +00001251route_set_aspath_prepend_free (void *rule)
1252{
1253 struct aspath *aspath = rule;
1254 aspath_free (aspath);
1255}
1256
1257/* Set metric rule structure. */
1258struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1259{
1260 "as-path prepend",
1261 route_set_aspath_prepend,
1262 route_set_aspath_prepend_compile,
1263 route_set_aspath_prepend_free,
1264};
1265
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001266/* `set as-path exclude ASn' */
1267
1268/* For ASN exclude mechanism.
1269 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1270 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1271 */
1272static route_map_result_t
1273route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
1274{
1275 struct aspath * new_path, * exclude_path;
1276 struct bgp_info *binfo;
1277
1278 if (type == RMAP_BGP)
1279 {
1280 exclude_path = rule;
1281 binfo = object;
1282 if (binfo->attr->aspath->refcnt)
1283 new_path = aspath_dup (binfo->attr->aspath);
1284 else
1285 new_path = binfo->attr->aspath;
1286 binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
1287 }
1288 return RMAP_OKAY;
1289}
1290
1291/* FIXME: consider using route_set_aspath_prepend_compile() and
1292 * route_set_aspath_prepend_free(), which two below function are
1293 * exact clones of.
1294 */
1295
1296/* Compile function for as-path exclude. */
1297static void *
1298route_set_aspath_exclude_compile (const char *arg)
1299{
1300 struct aspath *aspath;
1301
1302 aspath = aspath_str2aspath (arg);
1303 if (! aspath)
1304 return NULL;
1305 return aspath;
1306}
1307
1308static void
1309route_set_aspath_exclude_free (void *rule)
1310{
1311 struct aspath *aspath = rule;
1312 aspath_free (aspath);
1313}
1314
1315/* Set ASn exlude rule structure. */
1316struct route_map_rule_cmd route_set_aspath_exclude_cmd =
1317{
1318 "as-path exclude",
1319 route_set_aspath_exclude,
1320 route_set_aspath_exclude_compile,
1321 route_set_aspath_exclude_free,
1322};
1323
paul718e3742002-12-13 20:15:29 +00001324/* `set community COMMUNITY' */
1325struct rmap_com_set
1326{
1327 struct community *com;
1328 int additive;
1329 int none;
1330};
1331
1332/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001333static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001334route_set_community (void *rule, struct prefix *prefix,
1335 route_map_object_t type, void *object)
1336{
1337 struct rmap_com_set *rcs;
1338 struct bgp_info *binfo;
1339 struct attr *attr;
1340 struct community *new = NULL;
1341 struct community *old;
1342 struct community *merge;
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001343
paul718e3742002-12-13 20:15:29 +00001344 if (type == RMAP_BGP)
1345 {
1346 rcs = rule;
1347 binfo = object;
1348 attr = binfo->attr;
1349 old = attr->community;
1350
1351 /* "none" case. */
1352 if (rcs->none)
1353 {
1354 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1355 attr->community = NULL;
1356 return RMAP_OKAY;
1357 }
1358
1359 /* "additive" case. */
1360 if (rcs->additive && old)
1361 {
1362 merge = community_merge (community_dup (old), rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001363
1364 /* HACK: if the old community is not intern'd,
1365 * we should free it here, or all reference to it may be lost.
1366 * Really need to cleanup attribute caching sometime.
1367 */
1368 if (old->refcnt == 0)
1369 community_free (old);
paul718e3742002-12-13 20:15:29 +00001370 new = community_uniq_sort (merge);
1371 community_free (merge);
1372 }
1373 else
1374 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001375
1376 /* will be interned by caller if required */
Paul Jakma4a2035f2011-04-01 15:58:27 +01001377 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001378
paul718e3742002-12-13 20:15:29 +00001379 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1380 }
1381
1382 return RMAP_OKAY;
1383}
1384
1385/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001386static void *
paulfd79ac92004-10-13 05:06:08 +00001387route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001388{
1389 struct rmap_com_set *rcs;
1390 struct community *com = NULL;
1391 char *sp;
1392 int additive = 0;
1393 int none = 0;
1394
1395 if (strcmp (arg, "none") == 0)
1396 none = 1;
1397 else
1398 {
1399 sp = strstr (arg, "additive");
1400
1401 if (sp && sp > arg)
1402 {
1403 /* "additive" keyworkd is included. */
1404 additive = 1;
1405 *(sp - 1) = '\0';
1406 }
1407
1408 com = community_str2com (arg);
1409
1410 if (additive)
1411 *(sp - 1) = ' ';
1412
1413 if (! com)
1414 return NULL;
1415 }
1416
Stephen Hemminger393deb92008-08-18 14:13:29 -07001417 rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
Paul Jakma4a2035f2011-04-01 15:58:27 +01001418 rcs->com = com;
paul718e3742002-12-13 20:15:29 +00001419 rcs->additive = additive;
1420 rcs->none = none;
1421
1422 return rcs;
1423}
1424
1425/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001426static void
paul718e3742002-12-13 20:15:29 +00001427route_set_community_free (void *rule)
1428{
1429 struct rmap_com_set *rcs = rule;
1430
1431 if (rcs->com)
1432 community_free (rcs->com);
1433 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1434}
1435
1436/* Set community rule structure. */
1437struct route_map_rule_cmd route_set_community_cmd =
1438{
1439 "community",
1440 route_set_community,
1441 route_set_community_compile,
1442 route_set_community_free,
1443};
1444
hassofee6e4e2005-02-02 16:29:31 +00001445/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001446
1447/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001448static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001449route_set_community_delete (void *rule, struct prefix *prefix,
1450 route_map_object_t type, void *object)
1451{
1452 struct community_list *list;
1453 struct community *merge;
1454 struct community *new;
1455 struct community *old;
1456 struct bgp_info *binfo;
1457
1458 if (type == RMAP_BGP)
1459 {
1460 if (! rule)
1461 return RMAP_OKAY;
1462
1463 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001464 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001465 old = binfo->attr->community;
1466
1467 if (list && old)
1468 {
1469 merge = community_list_match_delete (community_dup (old), list);
1470 new = community_uniq_sort (merge);
1471 community_free (merge);
1472
Michael Lambert604a9b42010-09-13 11:48:11 -04001473 /* HACK: if the old community is not intern'd,
1474 * we should free it here, or all reference to it may be lost.
1475 * Really need to cleanup attribute caching sometime.
1476 */
1477 if (old->refcnt == 0)
1478 community_free (old);
1479
paul718e3742002-12-13 20:15:29 +00001480 if (new->size == 0)
1481 {
1482 binfo->attr->community = NULL;
1483 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1484 community_free (new);
1485 }
1486 else
1487 {
Paul Jakma4a2035f2011-04-01 15:58:27 +01001488 binfo->attr->community = new;
paul718e3742002-12-13 20:15:29 +00001489 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1490 }
1491 }
1492 }
1493
1494 return RMAP_OKAY;
1495}
1496
1497/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001498static void *
paulfd79ac92004-10-13 05:06:08 +00001499route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001500{
1501 char *p;
1502 char *str;
1503 int len;
1504
1505 p = strchr (arg, ' ');
1506 if (p)
1507 {
1508 len = p - arg;
1509 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1510 memcpy (str, arg, len);
1511 }
1512 else
1513 str = NULL;
1514
1515 return str;
1516}
1517
1518/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001519static void
paul718e3742002-12-13 20:15:29 +00001520route_set_community_delete_free (void *rule)
1521{
1522 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1523}
1524
1525/* Set community rule structure. */
1526struct route_map_rule_cmd route_set_community_delete_cmd =
1527{
1528 "comm-list",
1529 route_set_community_delete,
1530 route_set_community_delete_compile,
1531 route_set_community_delete_free,
1532};
1533
1534/* `set extcommunity rt COMMUNITY' */
1535
1536/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001537static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001538route_set_ecommunity_rt (void *rule, struct prefix *prefix,
1539 route_map_object_t type, void *object)
1540{
1541 struct ecommunity *ecom;
1542 struct ecommunity *new_ecom;
1543 struct ecommunity *old_ecom;
1544 struct bgp_info *bgp_info;
1545
1546 if (type == RMAP_BGP)
1547 {
1548 ecom = rule;
1549 bgp_info = object;
1550
1551 if (! ecom)
1552 return RMAP_OKAY;
1553
1554 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001555 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001556
1557 if (old_ecom)
1558 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1559 else
1560 new_ecom = ecommunity_dup (ecom);
1561
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001562 bgp_info->attr->extra->ecommunity = ecommunity_intern (new_ecom);
paul718e3742002-12-13 20:15:29 +00001563
hasso70601e02005-05-27 03:26:57 +00001564 if (old_ecom)
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001565 ecommunity_unintern (&old_ecom);
hasso70601e02005-05-27 03:26:57 +00001566
paul718e3742002-12-13 20:15:29 +00001567 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1568 }
1569 return RMAP_OKAY;
1570}
1571
1572/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001573static void *
paulfd79ac92004-10-13 05:06:08 +00001574route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001575{
1576 struct ecommunity *ecom;
1577
1578 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1579 if (! ecom)
1580 return NULL;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001581 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001582}
1583
1584/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001585static void
paul718e3742002-12-13 20:15:29 +00001586route_set_ecommunity_rt_free (void *rule)
1587{
1588 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001589 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001590}
1591
1592/* Set community rule structure. */
1593struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1594{
1595 "extcommunity rt",
1596 route_set_ecommunity_rt,
1597 route_set_ecommunity_rt_compile,
1598 route_set_ecommunity_rt_free,
1599};
1600
1601/* `set extcommunity soo COMMUNITY' */
1602
1603/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001604static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001605route_set_ecommunity_soo (void *rule, struct prefix *prefix,
1606 route_map_object_t type, void *object)
1607{
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001608 struct ecommunity *ecom, *old_ecom, *new_ecom;
paul718e3742002-12-13 20:15:29 +00001609 struct bgp_info *bgp_info;
1610
1611 if (type == RMAP_BGP)
1612 {
1613 ecom = rule;
1614 bgp_info = object;
1615
1616 if (! ecom)
1617 return RMAP_OKAY;
1618
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001619 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
1620
1621 if (old_ecom)
1622 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1623 else
1624 new_ecom = ecommunity_dup (ecom);
1625
1626 bgp_info->attr->extra->ecommunity = ecommunity_intern (new_ecom);
1627
1628 if (old_ecom)
1629 ecommunity_unintern (&old_ecom);
1630
paul718e3742002-12-13 20:15:29 +00001631 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
paul718e3742002-12-13 20:15:29 +00001632 }
1633 return RMAP_OKAY;
1634}
1635
1636/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001637static void *
paulfd79ac92004-10-13 05:06:08 +00001638route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001639{
1640 struct ecommunity *ecom;
1641
1642 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1643 if (! ecom)
1644 return NULL;
1645
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001646 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001647}
1648
1649/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001650static void
paul718e3742002-12-13 20:15:29 +00001651route_set_ecommunity_soo_free (void *rule)
1652{
1653 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001654 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001655}
1656
1657/* Set community rule structure. */
1658struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1659{
1660 "extcommunity soo",
1661 route_set_ecommunity_soo,
1662 route_set_ecommunity_soo_compile,
1663 route_set_ecommunity_soo_free,
1664};
1665
1666/* `set origin ORIGIN' */
1667
1668/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001669static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001670route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1671{
1672 u_char *origin;
1673 struct bgp_info *bgp_info;
1674
1675 if (type == RMAP_BGP)
1676 {
1677 origin = rule;
1678 bgp_info = object;
1679
1680 bgp_info->attr->origin = *origin;
1681 }
1682
1683 return RMAP_OKAY;
1684}
1685
1686/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001687static void *
paulfd79ac92004-10-13 05:06:08 +00001688route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001689{
1690 u_char *origin;
1691
1692 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1693
1694 if (strcmp (arg, "igp") == 0)
1695 *origin = 0;
1696 else if (strcmp (arg, "egp") == 0)
1697 *origin = 1;
1698 else
1699 *origin = 2;
1700
1701 return origin;
1702}
1703
1704/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001705static void
paul718e3742002-12-13 20:15:29 +00001706route_set_origin_free (void *rule)
1707{
1708 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1709}
1710
1711/* Set metric rule structure. */
1712struct route_map_rule_cmd route_set_origin_cmd =
1713{
1714 "origin",
1715 route_set_origin,
1716 route_set_origin_compile,
1717 route_set_origin_free,
1718};
1719
1720/* `set atomic-aggregate' */
1721
1722/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001723static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001724route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1725 route_map_object_t type, void *object)
1726{
1727 struct bgp_info *bgp_info;
1728
1729 if (type == RMAP_BGP)
1730 {
1731 bgp_info = object;
1732 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1733 }
1734
1735 return RMAP_OKAY;
1736}
1737
1738/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001739static void *
paulfd79ac92004-10-13 05:06:08 +00001740route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001741{
1742 return (void *)1;
1743}
1744
1745/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001746static void
paul718e3742002-12-13 20:15:29 +00001747route_set_atomic_aggregate_free (void *rule)
1748{
1749 return;
1750}
1751
1752/* Set atomic aggregate rule structure. */
1753struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1754{
1755 "atomic-aggregate",
1756 route_set_atomic_aggregate,
1757 route_set_atomic_aggregate_compile,
1758 route_set_atomic_aggregate_free,
1759};
1760
1761/* `set aggregator as AS A.B.C.D' */
1762struct aggregator
1763{
1764 as_t as;
1765 struct in_addr address;
1766};
1767
paul94f2b392005-06-28 12:44:16 +00001768static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001769route_set_aggregator_as (void *rule, struct prefix *prefix,
1770 route_map_object_t type, void *object)
1771{
1772 struct bgp_info *bgp_info;
1773 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001774 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001775
1776 if (type == RMAP_BGP)
1777 {
1778 bgp_info = object;
1779 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001780 ae = bgp_attr_extra_get (bgp_info->attr);
1781
1782 ae->aggregator_as = aggregator->as;
1783 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001784 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1785 }
1786
1787 return RMAP_OKAY;
1788}
1789
paul94f2b392005-06-28 12:44:16 +00001790static void *
paulfd79ac92004-10-13 05:06:08 +00001791route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001792{
1793 struct aggregator *aggregator;
1794 char as[10];
1795 char address[20];
1796
Stephen Hemminger393deb92008-08-18 14:13:29 -07001797 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
paul718e3742002-12-13 20:15:29 +00001798 sscanf (arg, "%s %s", as, address);
1799
1800 aggregator->as = strtoul (as, NULL, 10);
1801 inet_aton (address, &aggregator->address);
1802
1803 return aggregator;
1804}
1805
paul94f2b392005-06-28 12:44:16 +00001806static void
paul718e3742002-12-13 20:15:29 +00001807route_set_aggregator_as_free (void *rule)
1808{
1809 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1810}
1811
1812struct route_map_rule_cmd route_set_aggregator_as_cmd =
1813{
1814 "aggregator as",
1815 route_set_aggregator_as,
1816 route_set_aggregator_as_compile,
1817 route_set_aggregator_as_free,
1818};
1819
1820#ifdef HAVE_IPV6
1821/* `match ipv6 address IP_ACCESS_LIST' */
1822
paul94f2b392005-06-28 12:44:16 +00001823static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001824route_match_ipv6_address (void *rule, struct prefix *prefix,
1825 route_map_object_t type, void *object)
1826{
1827 struct access_list *alist;
1828
1829 if (type == RMAP_BGP)
1830 {
1831 alist = access_list_lookup (AFI_IP6, (char *) rule);
1832 if (alist == NULL)
1833 return RMAP_NOMATCH;
1834
1835 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1836 RMAP_NOMATCH : RMAP_MATCH);
1837 }
1838 return RMAP_NOMATCH;
1839}
1840
paul94f2b392005-06-28 12:44:16 +00001841static void *
paulfd79ac92004-10-13 05:06:08 +00001842route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001843{
1844 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1845}
1846
paul94f2b392005-06-28 12:44:16 +00001847static void
paul718e3742002-12-13 20:15:29 +00001848route_match_ipv6_address_free (void *rule)
1849{
1850 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1851}
1852
1853/* Route map commands for ip address matching. */
1854struct route_map_rule_cmd route_match_ipv6_address_cmd =
1855{
1856 "ipv6 address",
1857 route_match_ipv6_address,
1858 route_match_ipv6_address_compile,
1859 route_match_ipv6_address_free
1860};
1861
1862/* `match ipv6 next-hop IP_ADDRESS' */
1863
paul94f2b392005-06-28 12:44:16 +00001864static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001865route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1866 route_map_object_t type, void *object)
1867{
1868 struct in6_addr *addr;
1869 struct bgp_info *bgp_info;
1870
1871 if (type == RMAP_BGP)
1872 {
1873 addr = rule;
1874 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001875
1876 if (!bgp_info->attr->extra)
1877 return RMAP_NOMATCH;
1878
1879 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, rule))
paul718e3742002-12-13 20:15:29 +00001880 return RMAP_MATCH;
1881
Paul Jakmafb982c22007-05-04 20:15:47 +00001882 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
1883 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, rule))
paul718e3742002-12-13 20:15:29 +00001884 return RMAP_MATCH;
1885
1886 return RMAP_NOMATCH;
1887 }
1888
1889 return RMAP_NOMATCH;
1890}
1891
paul94f2b392005-06-28 12:44:16 +00001892static void *
paulfd79ac92004-10-13 05:06:08 +00001893route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001894{
1895 struct in6_addr *address;
1896 int ret;
1897
1898 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1899
1900 ret = inet_pton (AF_INET6, arg, address);
1901 if (!ret)
1902 {
1903 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1904 return NULL;
1905 }
1906
1907 return address;
1908}
1909
paul94f2b392005-06-28 12:44:16 +00001910static void
paul718e3742002-12-13 20:15:29 +00001911route_match_ipv6_next_hop_free (void *rule)
1912{
1913 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1914}
1915
1916struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1917{
1918 "ipv6 next-hop",
1919 route_match_ipv6_next_hop,
1920 route_match_ipv6_next_hop_compile,
1921 route_match_ipv6_next_hop_free
1922};
1923
1924/* `match ipv6 address prefix-list PREFIX_LIST' */
1925
paul94f2b392005-06-28 12:44:16 +00001926static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001927route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1928 route_map_object_t type, void *object)
1929{
1930 struct prefix_list *plist;
1931
1932 if (type == RMAP_BGP)
1933 {
1934 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1935 if (plist == NULL)
1936 return RMAP_NOMATCH;
1937
1938 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1939 RMAP_NOMATCH : RMAP_MATCH);
1940 }
1941 return RMAP_NOMATCH;
1942}
1943
paul94f2b392005-06-28 12:44:16 +00001944static void *
paulfd79ac92004-10-13 05:06:08 +00001945route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001946{
1947 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1948}
1949
paul94f2b392005-06-28 12:44:16 +00001950static void
paul718e3742002-12-13 20:15:29 +00001951route_match_ipv6_address_prefix_list_free (void *rule)
1952{
1953 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1954}
1955
1956struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1957{
1958 "ipv6 address prefix-list",
1959 route_match_ipv6_address_prefix_list,
1960 route_match_ipv6_address_prefix_list_compile,
1961 route_match_ipv6_address_prefix_list_free
1962};
1963
1964/* `set ipv6 nexthop global IP_ADDRESS' */
1965
1966/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001967static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001968route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1969 route_map_object_t type, void *object)
1970{
1971 struct in6_addr *address;
1972 struct bgp_info *bgp_info;
1973
1974 if (type == RMAP_BGP)
1975 {
1976 /* Fetch routemap's rule information. */
1977 address = rule;
1978 bgp_info = object;
1979
1980 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001981 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00001982
1983 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001984 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1985 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00001986 }
1987
1988 return RMAP_OKAY;
1989}
1990
1991/* Route map `ip next-hop' compile function. Given string is converted
1992 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001993static void *
paulfd79ac92004-10-13 05:06:08 +00001994route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001995{
1996 int ret;
1997 struct in6_addr *address;
1998
1999 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2000
2001 ret = inet_pton (AF_INET6, arg, address);
2002
2003 if (ret == 0)
2004 {
2005 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2006 return NULL;
2007 }
2008
2009 return address;
2010}
2011
2012/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00002013static void
paul718e3742002-12-13 20:15:29 +00002014route_set_ipv6_nexthop_global_free (void *rule)
2015{
2016 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2017}
2018
2019/* Route map commands for ip nexthop set. */
2020struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
2021{
2022 "ipv6 next-hop global",
2023 route_set_ipv6_nexthop_global,
2024 route_set_ipv6_nexthop_global_compile,
2025 route_set_ipv6_nexthop_global_free
2026};
2027
2028/* `set ipv6 nexthop local IP_ADDRESS' */
2029
2030/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00002031static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002032route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
2033 route_map_object_t type, void *object)
2034{
2035 struct in6_addr *address;
2036 struct bgp_info *bgp_info;
2037
2038 if (type == RMAP_BGP)
2039 {
2040 /* Fetch routemap's rule information. */
2041 address = rule;
2042 bgp_info = object;
2043
2044 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002045 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00002046
2047 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002048 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2049 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00002050 }
2051
2052 return RMAP_OKAY;
2053}
2054
2055/* Route map `ip nexthop' compile function. Given string is converted
2056 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00002057static void *
paulfd79ac92004-10-13 05:06:08 +00002058route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002059{
2060 int ret;
2061 struct in6_addr *address;
2062
2063 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2064
2065 ret = inet_pton (AF_INET6, arg, address);
2066
2067 if (ret == 0)
2068 {
2069 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2070 return NULL;
2071 }
2072
2073 return address;
2074}
2075
2076/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00002077static void
paul718e3742002-12-13 20:15:29 +00002078route_set_ipv6_nexthop_local_free (void *rule)
2079{
2080 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2081}
2082
2083/* Route map commands for ip nexthop set. */
2084struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
2085{
2086 "ipv6 next-hop local",
2087 route_set_ipv6_nexthop_local,
2088 route_set_ipv6_nexthop_local_compile,
2089 route_set_ipv6_nexthop_local_free
2090};
2091#endif /* HAVE_IPV6 */
2092
2093/* `set vpnv4 nexthop A.B.C.D' */
2094
paul94f2b392005-06-28 12:44:16 +00002095static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002096route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2097 route_map_object_t type, void *object)
2098{
2099 struct in_addr *address;
2100 struct bgp_info *bgp_info;
2101
2102 if (type == RMAP_BGP)
2103 {
2104 /* Fetch routemap's rule information. */
2105 address = rule;
2106 bgp_info = object;
2107
2108 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002109 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
paul718e3742002-12-13 20:15:29 +00002110 }
2111
2112 return RMAP_OKAY;
2113}
2114
paul94f2b392005-06-28 12:44:16 +00002115static void *
paulfd79ac92004-10-13 05:06:08 +00002116route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002117{
2118 int ret;
2119 struct in_addr *address;
2120
2121 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2122
2123 ret = inet_aton (arg, address);
2124
2125 if (ret == 0)
2126 {
2127 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2128 return NULL;
2129 }
2130
2131 return address;
2132}
2133
paul94f2b392005-06-28 12:44:16 +00002134static void
paul718e3742002-12-13 20:15:29 +00002135route_set_vpnv4_nexthop_free (void *rule)
2136{
2137 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2138}
2139
2140/* Route map commands for ip nexthop set. */
2141struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2142{
2143 "vpnv4 next-hop",
2144 route_set_vpnv4_nexthop,
2145 route_set_vpnv4_nexthop_compile,
2146 route_set_vpnv4_nexthop_free
2147};
2148
2149/* `set originator-id' */
2150
2151/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002152static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002153route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2154{
2155 struct in_addr *address;
2156 struct bgp_info *bgp_info;
2157
2158 if (type == RMAP_BGP)
2159 {
2160 address = rule;
2161 bgp_info = object;
2162
2163 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002164 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002165 }
2166
2167 return RMAP_OKAY;
2168}
2169
2170/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002171static void *
paulfd79ac92004-10-13 05:06:08 +00002172route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002173{
2174 int ret;
2175 struct in_addr *address;
2176
2177 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2178
2179 ret = inet_aton (arg, address);
2180
2181 if (ret == 0)
2182 {
2183 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2184 return NULL;
2185 }
2186
2187 return address;
2188}
2189
2190/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002191static void
paul718e3742002-12-13 20:15:29 +00002192route_set_originator_id_free (void *rule)
2193{
2194 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2195}
2196
2197/* Set metric rule structure. */
2198struct route_map_rule_cmd route_set_originator_id_cmd =
2199{
2200 "originator-id",
2201 route_set_originator_id,
2202 route_set_originator_id_compile,
2203 route_set_originator_id_free,
2204};
2205
2206/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002207static int
paul718e3742002-12-13 20:15:29 +00002208bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002209 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002210{
2211 int ret;
2212
2213 ret = route_map_add_match (index, command, arg);
2214 if (ret)
2215 {
2216 switch (ret)
2217 {
2218 case RMAP_RULE_MISSING:
2219 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2220 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002221 case RMAP_COMPILE_ERROR:
2222 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2223 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002224 }
2225 }
2226 return CMD_SUCCESS;
2227}
2228
2229/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002230static int
paul718e3742002-12-13 20:15:29 +00002231bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002232 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002233{
2234 int ret;
2235
2236 ret = route_map_delete_match (index, command, arg);
2237 if (ret)
2238 {
2239 switch (ret)
2240 {
2241 case RMAP_RULE_MISSING:
2242 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2243 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002244 case RMAP_COMPILE_ERROR:
2245 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2246 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002247 }
2248 }
2249 return CMD_SUCCESS;
2250}
2251
2252/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002253static int
paul718e3742002-12-13 20:15:29 +00002254bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002255 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002256{
2257 int ret;
2258
2259 ret = route_map_add_set (index, command, arg);
2260 if (ret)
2261 {
2262 switch (ret)
2263 {
2264 case RMAP_RULE_MISSING:
2265 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2266 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002267 case RMAP_COMPILE_ERROR:
2268 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2269 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002270 }
2271 }
2272 return CMD_SUCCESS;
2273}
2274
2275/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002276static int
paul718e3742002-12-13 20:15:29 +00002277bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002278 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002279{
2280 int ret;
2281
2282 ret = route_map_delete_set (index, command, arg);
2283 if (ret)
2284 {
2285 switch (ret)
2286 {
2287 case RMAP_RULE_MISSING:
2288 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2289 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002290 case RMAP_COMPILE_ERROR:
2291 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2292 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002293 }
2294 }
2295 return CMD_SUCCESS;
2296}
2297
2298/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002299static void
paulfd79ac92004-10-13 05:06:08 +00002300bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002301{
2302 int i;
2303 afi_t afi;
2304 safi_t safi;
2305 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002306 struct listnode *node, *nnode;
2307 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002308 struct bgp *bgp;
2309 struct peer *peer;
2310 struct peer_group *group;
2311 struct bgp_filter *filter;
2312 struct bgp_node *bn;
2313 struct bgp_static *bgp_static;
2314
2315 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002316 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002317 {
paul1eb8ef22005-04-07 07:30:20 +00002318 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002319 {
2320 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2321 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2322 {
2323 filter = &peer->filter[afi][safi];
2324
paulfee0f4c2004-09-13 05:12:46 +00002325 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002326 {
2327 if (filter->map[direct].name)
2328 filter->map[direct].map =
2329 route_map_lookup_by_name (filter->map[direct].name);
2330 else
2331 filter->map[direct].map = NULL;
2332 }
2333
2334 if (filter->usmap.name)
2335 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2336 else
2337 filter->usmap.map = NULL;
2338 }
2339 }
paul1eb8ef22005-04-07 07:30:20 +00002340 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002341 {
2342 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2343 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2344 {
2345 filter = &group->conf->filter[afi][safi];
2346
paulfee0f4c2004-09-13 05:12:46 +00002347 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002348 {
2349 if (filter->map[direct].name)
2350 filter->map[direct].map =
2351 route_map_lookup_by_name (filter->map[direct].name);
2352 else
2353 filter->map[direct].map = NULL;
2354 }
2355
2356 if (filter->usmap.name)
2357 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2358 else
2359 filter->usmap.map = NULL;
2360 }
2361 }
2362 }
2363
2364 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002365 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002366 {
paul1eb8ef22005-04-07 07:30:20 +00002367 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002368 {
2369 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2370 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2371 {
2372 if (peer->default_rmap[afi][safi].name)
2373 peer->default_rmap[afi][safi].map =
2374 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2375 else
2376 peer->default_rmap[afi][safi].map = NULL;
2377 }
2378 }
2379 }
2380
2381 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002382 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002383 {
2384 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2385 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2386 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2387 bn = bgp_route_next (bn))
2388 if ((bgp_static = bn->info) != NULL)
2389 {
2390 if (bgp_static->rmap.name)
2391 bgp_static->rmap.map =
2392 route_map_lookup_by_name (bgp_static->rmap.name);
2393 else
2394 bgp_static->rmap.map = NULL;
2395 }
2396 }
2397
2398 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002399 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002400 {
2401 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2402 {
2403 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2404 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2405 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2406#ifdef HAVE_IPV6
2407 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2408 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2409 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2410#endif /* HAVE_IPV6 */
2411 }
2412 }
2413}
2414
paulfee0f4c2004-09-13 05:12:46 +00002415DEFUN (match_peer,
2416 match_peer_cmd,
2417 "match peer (A.B.C.D|X:X::X:X)",
2418 MATCH_STR
2419 "Match peer address\n"
2420 "IPv6 address of peer\n"
2421 "IP address of peer\n")
2422{
2423 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2424}
2425
2426DEFUN (match_peer_local,
2427 match_peer_local_cmd,
2428 "match peer local",
2429 MATCH_STR
2430 "Match peer address\n"
2431 "Static or Redistributed routes\n")
2432{
2433 return bgp_route_match_add (vty, vty->index, "peer", NULL);
2434}
2435
2436DEFUN (no_match_peer,
2437 no_match_peer_cmd,
2438 "no match peer",
2439 NO_STR
2440 MATCH_STR
2441 "Match peer address\n")
2442{
2443 if (argc == 0)
2444 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2445
2446 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2447}
2448
2449ALIAS (no_match_peer,
2450 no_match_peer_val_cmd,
2451 "no match peer (A.B.C.D|X:X::X:X)",
2452 NO_STR
2453 MATCH_STR
2454 "Match peer address\n"
2455 "IPv6 address of peer\n"
2456 "IP address of peer\n")
2457
2458ALIAS (no_match_peer,
2459 no_match_peer_local_cmd,
2460 "no match peer local",
2461 NO_STR
2462 MATCH_STR
2463 "Match peer address\n"
2464 "Static or Redistributed routes\n")
2465
paul718e3742002-12-13 20:15:29 +00002466DEFUN (match_ip_address,
2467 match_ip_address_cmd,
2468 "match ip address (<1-199>|<1300-2699>|WORD)",
2469 MATCH_STR
2470 IP_STR
2471 "Match address of route\n"
2472 "IP access-list number\n"
2473 "IP access-list number (expanded range)\n"
2474 "IP Access-list name\n")
2475{
2476 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2477}
2478
2479DEFUN (no_match_ip_address,
2480 no_match_ip_address_cmd,
2481 "no match ip address",
2482 NO_STR
2483 MATCH_STR
2484 IP_STR
2485 "Match address of route\n")
2486{
2487 if (argc == 0)
2488 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2489
2490 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2491}
2492
2493ALIAS (no_match_ip_address,
2494 no_match_ip_address_val_cmd,
2495 "no match ip address (<1-199>|<1300-2699>|WORD)",
2496 NO_STR
2497 MATCH_STR
2498 IP_STR
2499 "Match address of route\n"
2500 "IP access-list number\n"
2501 "IP access-list number (expanded range)\n"
2502 "IP Access-list name\n")
2503
2504DEFUN (match_ip_next_hop,
2505 match_ip_next_hop_cmd,
2506 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2507 MATCH_STR
2508 IP_STR
2509 "Match next-hop address of route\n"
2510 "IP access-list number\n"
2511 "IP access-list number (expanded range)\n"
2512 "IP Access-list name\n")
2513{
2514 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2515}
2516
2517DEFUN (no_match_ip_next_hop,
2518 no_match_ip_next_hop_cmd,
2519 "no match ip next-hop",
2520 NO_STR
2521 MATCH_STR
2522 IP_STR
2523 "Match next-hop address of route\n")
2524{
2525 if (argc == 0)
2526 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2527
2528 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2529}
2530
2531ALIAS (no_match_ip_next_hop,
2532 no_match_ip_next_hop_val_cmd,
2533 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2534 NO_STR
2535 MATCH_STR
2536 IP_STR
2537 "Match next-hop address of route\n"
2538 "IP access-list number\n"
2539 "IP access-list number (expanded range)\n"
2540 "IP Access-list name\n")
2541
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04002542/* match probability { */
2543
2544DEFUN (match_probability,
2545 match_probability_cmd,
2546 "match probability <0-100>",
2547 MATCH_STR
2548 "Match portion of routes defined by percentage value\n"
2549 "Percentage of routes\n")
2550{
2551 return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
2552}
2553
2554DEFUN (no_match_probability,
2555 no_match_probability_cmd,
2556 "no match probability",
2557 NO_STR
2558 MATCH_STR
2559 "Match portion of routes defined by percentage value\n")
2560{
2561 return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL);
2562}
2563
2564ALIAS (no_match_probability,
2565 no_match_probability_val_cmd,
2566 "no match probability <1-99>",
2567 NO_STR
2568 MATCH_STR
2569 "Match portion of routes defined by percentage value\n"
2570 "Percentage of routes\n")
2571
2572/* } */
2573
hassoc1643bb2005-02-02 16:43:17 +00002574DEFUN (match_ip_route_source,
2575 match_ip_route_source_cmd,
2576 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2577 MATCH_STR
2578 IP_STR
2579 "Match advertising source address of route\n"
2580 "IP access-list number\n"
2581 "IP access-list number (expanded range)\n"
2582 "IP standard access-list name\n")
2583{
2584 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2585}
2586
2587DEFUN (no_match_ip_route_source,
2588 no_match_ip_route_source_cmd,
2589 "no match ip route-source",
2590 NO_STR
2591 MATCH_STR
2592 IP_STR
2593 "Match advertising source address of route\n")
2594{
2595 if (argc == 0)
2596 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2597
2598 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2599}
2600
2601ALIAS (no_match_ip_route_source,
2602 no_match_ip_route_source_val_cmd,
2603 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2604 NO_STR
2605 MATCH_STR
2606 IP_STR
2607 "Match advertising source address of route\n"
2608 "IP access-list number\n"
2609 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002610 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002611
paul718e3742002-12-13 20:15:29 +00002612DEFUN (match_ip_address_prefix_list,
2613 match_ip_address_prefix_list_cmd,
2614 "match ip address prefix-list WORD",
2615 MATCH_STR
2616 IP_STR
2617 "Match address of route\n"
2618 "Match entries of prefix-lists\n"
2619 "IP prefix-list name\n")
2620{
2621 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2622}
2623
2624DEFUN (no_match_ip_address_prefix_list,
2625 no_match_ip_address_prefix_list_cmd,
2626 "no match ip address prefix-list",
2627 NO_STR
2628 MATCH_STR
2629 IP_STR
2630 "Match address of route\n"
2631 "Match entries of prefix-lists\n")
2632{
2633 if (argc == 0)
2634 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2635
2636 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2637}
2638
2639ALIAS (no_match_ip_address_prefix_list,
2640 no_match_ip_address_prefix_list_val_cmd,
2641 "no match ip address prefix-list WORD",
2642 NO_STR
2643 MATCH_STR
2644 IP_STR
2645 "Match address of route\n"
2646 "Match entries of prefix-lists\n"
2647 "IP prefix-list name\n")
2648
2649DEFUN (match_ip_next_hop_prefix_list,
2650 match_ip_next_hop_prefix_list_cmd,
2651 "match ip next-hop prefix-list WORD",
2652 MATCH_STR
2653 IP_STR
2654 "Match next-hop address of route\n"
2655 "Match entries of prefix-lists\n"
2656 "IP prefix-list name\n")
2657{
2658 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2659}
2660
2661DEFUN (no_match_ip_next_hop_prefix_list,
2662 no_match_ip_next_hop_prefix_list_cmd,
2663 "no match ip next-hop prefix-list",
2664 NO_STR
2665 MATCH_STR
2666 IP_STR
2667 "Match next-hop address of route\n"
2668 "Match entries of prefix-lists\n")
2669{
2670 if (argc == 0)
2671 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2672
2673 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2674}
2675
2676ALIAS (no_match_ip_next_hop_prefix_list,
2677 no_match_ip_next_hop_prefix_list_val_cmd,
2678 "no match ip next-hop prefix-list WORD",
2679 NO_STR
2680 MATCH_STR
2681 IP_STR
2682 "Match next-hop address of route\n"
2683 "Match entries of prefix-lists\n"
2684 "IP prefix-list name\n")
2685
hassoc1643bb2005-02-02 16:43:17 +00002686DEFUN (match_ip_route_source_prefix_list,
2687 match_ip_route_source_prefix_list_cmd,
2688 "match ip route-source prefix-list WORD",
2689 MATCH_STR
2690 IP_STR
2691 "Match advertising source address of route\n"
2692 "Match entries of prefix-lists\n"
2693 "IP prefix-list name\n")
2694{
2695 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2696}
2697
2698DEFUN (no_match_ip_route_source_prefix_list,
2699 no_match_ip_route_source_prefix_list_cmd,
2700 "no match ip route-source prefix-list",
2701 NO_STR
2702 MATCH_STR
2703 IP_STR
2704 "Match advertising source address of route\n"
2705 "Match entries of prefix-lists\n")
2706{
2707 if (argc == 0)
2708 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2709
2710 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2711}
2712
2713ALIAS (no_match_ip_route_source_prefix_list,
2714 no_match_ip_route_source_prefix_list_val_cmd,
2715 "no match ip route-source prefix-list WORD",
2716 NO_STR
2717 MATCH_STR
2718 IP_STR
2719 "Match advertising source address of route\n"
2720 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002721 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002722
paul718e3742002-12-13 20:15:29 +00002723DEFUN (match_metric,
2724 match_metric_cmd,
2725 "match metric <0-4294967295>",
2726 MATCH_STR
2727 "Match metric of route\n"
2728 "Metric value\n")
2729{
2730 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2731}
2732
2733DEFUN (no_match_metric,
2734 no_match_metric_cmd,
2735 "no match metric",
2736 NO_STR
2737 MATCH_STR
2738 "Match metric of route\n")
2739{
2740 if (argc == 0)
2741 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2742
2743 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2744}
2745
2746ALIAS (no_match_metric,
2747 no_match_metric_val_cmd,
2748 "no match metric <0-4294967295>",
2749 NO_STR
2750 MATCH_STR
2751 "Match metric of route\n"
2752 "Metric value\n")
2753
2754DEFUN (match_community,
2755 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002756 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002757 MATCH_STR
2758 "Match BGP community list\n"
2759 "Community-list number (standard)\n"
2760 "Community-list number (expanded)\n"
2761 "Community-list name\n")
2762{
2763 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2764}
2765
2766DEFUN (match_community_exact,
2767 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002768 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002769 MATCH_STR
2770 "Match BGP community list\n"
2771 "Community-list number (standard)\n"
2772 "Community-list number (expanded)\n"
2773 "Community-list name\n"
2774 "Do exact matching of communities\n")
2775{
2776 int ret;
2777 char *argstr;
2778
2779 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2780 strlen (argv[0]) + strlen ("exact-match") + 2);
2781
2782 sprintf (argstr, "%s exact-match", argv[0]);
2783
2784 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2785
2786 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2787
2788 return ret;
2789}
2790
2791DEFUN (no_match_community,
2792 no_match_community_cmd,
2793 "no match community",
2794 NO_STR
2795 MATCH_STR
2796 "Match BGP community list\n")
2797{
2798 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2799}
2800
2801ALIAS (no_match_community,
2802 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002803 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002804 NO_STR
2805 MATCH_STR
2806 "Match BGP community list\n"
2807 "Community-list number (standard)\n"
2808 "Community-list number (expanded)\n"
2809 "Community-list name\n")
2810
2811ALIAS (no_match_community,
2812 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002813 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002814 NO_STR
2815 MATCH_STR
2816 "Match BGP community list\n"
2817 "Community-list number (standard)\n"
2818 "Community-list number (expanded)\n"
2819 "Community-list name\n"
2820 "Do exact matching of communities\n")
2821
paul73ffb252003-04-19 15:49:49 +00002822DEFUN (match_ecommunity,
2823 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002824 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002825 MATCH_STR
2826 "Match BGP/VPN extended community list\n"
2827 "Extended community-list number (standard)\n"
2828 "Extended community-list number (expanded)\n"
2829 "Extended community-list name\n")
2830{
2831 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2832}
2833
2834DEFUN (no_match_ecommunity,
2835 no_match_ecommunity_cmd,
2836 "no match extcommunity",
2837 NO_STR
2838 MATCH_STR
2839 "Match BGP/VPN extended community list\n")
2840{
2841 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2842}
2843
2844ALIAS (no_match_ecommunity,
2845 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002846 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002847 NO_STR
2848 MATCH_STR
2849 "Match BGP/VPN extended community list\n"
2850 "Extended community-list number (standard)\n"
2851 "Extended community-list number (expanded)\n"
2852 "Extended community-list name\n")
2853
paul718e3742002-12-13 20:15:29 +00002854DEFUN (match_aspath,
2855 match_aspath_cmd,
2856 "match as-path WORD",
2857 MATCH_STR
2858 "Match BGP AS path list\n"
2859 "AS path access-list name\n")
2860{
2861 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2862}
2863
2864DEFUN (no_match_aspath,
2865 no_match_aspath_cmd,
2866 "no match as-path",
2867 NO_STR
2868 MATCH_STR
2869 "Match BGP AS path list\n")
2870{
2871 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2872}
2873
2874ALIAS (no_match_aspath,
2875 no_match_aspath_val_cmd,
2876 "no match as-path WORD",
2877 NO_STR
2878 MATCH_STR
2879 "Match BGP AS path list\n"
2880 "AS path access-list name\n")
2881
2882DEFUN (match_origin,
2883 match_origin_cmd,
2884 "match origin (egp|igp|incomplete)",
2885 MATCH_STR
2886 "BGP origin code\n"
2887 "remote EGP\n"
2888 "local IGP\n"
2889 "unknown heritage\n")
2890{
2891 if (strncmp (argv[0], "igp", 2) == 0)
2892 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2893 if (strncmp (argv[0], "egp", 1) == 0)
2894 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2895 if (strncmp (argv[0], "incomplete", 2) == 0)
2896 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2897
2898 return CMD_WARNING;
2899}
2900
2901DEFUN (no_match_origin,
2902 no_match_origin_cmd,
2903 "no match origin",
2904 NO_STR
2905 MATCH_STR
2906 "BGP origin code\n")
2907{
2908 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2909}
2910
2911ALIAS (no_match_origin,
2912 no_match_origin_val_cmd,
2913 "no match origin (egp|igp|incomplete)",
2914 NO_STR
2915 MATCH_STR
2916 "BGP origin code\n"
2917 "remote EGP\n"
2918 "local IGP\n"
2919 "unknown heritage\n")
2920
2921DEFUN (set_ip_nexthop,
2922 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002923 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002924 SET_STR
2925 IP_STR
2926 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002927 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002928{
2929 union sockunion su;
2930 int ret;
2931
2932 ret = str2sockunion (argv[0], &su);
2933 if (ret < 0)
2934 {
2935 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2936 return CMD_WARNING;
2937 }
2938
2939 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2940}
2941
paulaf5cd0a2003-11-02 07:24:40 +00002942DEFUN (set_ip_nexthop_peer,
2943 set_ip_nexthop_peer_cmd,
2944 "set ip next-hop peer-address",
2945 SET_STR
2946 IP_STR
2947 "Next hop address\n"
2948 "Use peer address (for BGP only)\n")
2949{
2950 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2951}
2952
paul94f2b392005-06-28 12:44:16 +00002953DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00002954 no_set_ip_nexthop_peer_cmd,
2955 "no set ip next-hop peer-address",
2956 NO_STR
2957 SET_STR
2958 IP_STR
2959 "Next hop address\n"
2960 "Use peer address (for BGP only)\n")
2961{
2962 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2963}
2964
2965
paul718e3742002-12-13 20:15:29 +00002966DEFUN (no_set_ip_nexthop,
2967 no_set_ip_nexthop_cmd,
2968 "no set ip next-hop",
2969 NO_STR
2970 SET_STR
paul718e3742002-12-13 20:15:29 +00002971 "Next hop address\n")
2972{
paulaf5cd0a2003-11-02 07:24:40 +00002973 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002974 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2975
2976 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2977}
2978
2979ALIAS (no_set_ip_nexthop,
2980 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002981 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002982 NO_STR
2983 SET_STR
2984 IP_STR
2985 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002986 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002987
2988DEFUN (set_metric,
2989 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002990 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002991 SET_STR
2992 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002993 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002994{
2995 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2996}
2997
paul73ffb252003-04-19 15:49:49 +00002998ALIAS (set_metric,
2999 set_metric_addsub_cmd,
3000 "set metric <+/-metric>",
3001 SET_STR
3002 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00003003 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00003004
paul718e3742002-12-13 20:15:29 +00003005DEFUN (no_set_metric,
3006 no_set_metric_cmd,
3007 "no set metric",
3008 NO_STR
3009 SET_STR
3010 "Metric value for destination routing protocol\n")
3011{
3012 if (argc == 0)
3013 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
3014
3015 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
3016}
3017
3018ALIAS (no_set_metric,
3019 no_set_metric_val_cmd,
3020 "no set metric <0-4294967295>",
3021 NO_STR
3022 SET_STR
3023 "Metric value for destination routing protocol\n"
3024 "Metric value\n")
3025
3026DEFUN (set_local_pref,
3027 set_local_pref_cmd,
3028 "set local-preference <0-4294967295>",
3029 SET_STR
3030 "BGP local preference path attribute\n"
3031 "Preference value\n")
3032{
3033 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
3034}
3035
3036DEFUN (no_set_local_pref,
3037 no_set_local_pref_cmd,
3038 "no set local-preference",
3039 NO_STR
3040 SET_STR
3041 "BGP local preference path attribute\n")
3042{
3043 if (argc == 0)
3044 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3045
3046 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
3047}
3048
3049ALIAS (no_set_local_pref,
3050 no_set_local_pref_val_cmd,
3051 "no set local-preference <0-4294967295>",
3052 NO_STR
3053 SET_STR
3054 "BGP local preference path attribute\n"
3055 "Preference value\n")
3056
3057DEFUN (set_weight,
3058 set_weight_cmd,
3059 "set weight <0-4294967295>",
3060 SET_STR
3061 "BGP weight for routing table\n"
3062 "Weight value\n")
3063{
3064 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3065}
3066
3067DEFUN (no_set_weight,
3068 no_set_weight_cmd,
3069 "no set weight",
3070 NO_STR
3071 SET_STR
3072 "BGP weight for routing table\n")
3073{
3074 if (argc == 0)
3075 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3076
3077 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3078}
3079
3080ALIAS (no_set_weight,
3081 no_set_weight_val_cmd,
3082 "no set weight <0-4294967295>",
3083 NO_STR
3084 SET_STR
3085 "BGP weight for routing table\n"
3086 "Weight value\n")
3087
3088DEFUN (set_aspath_prepend,
3089 set_aspath_prepend_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003090 "set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003091 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003092 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003093 "Prepend to the as-path\n"
3094 "AS number\n")
3095{
3096 int ret;
3097 char *str;
3098
3099 str = argv_concat (argv, argc, 0);
3100 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3101 XFREE (MTYPE_TMP, str);
3102
3103 return ret;
3104}
3105
3106DEFUN (no_set_aspath_prepend,
3107 no_set_aspath_prepend_cmd,
3108 "no set as-path prepend",
3109 NO_STR
3110 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003111 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003112 "Prepend to the as-path\n")
3113{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00003114 int ret;
3115 char *str;
3116
3117 if (argc == 0)
3118 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3119
3120 str = argv_concat (argv, argc, 0);
3121 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3122 XFREE (MTYPE_TMP, str);
3123 return ret;
paul718e3742002-12-13 20:15:29 +00003124}
3125
3126ALIAS (no_set_aspath_prepend,
3127 no_set_aspath_prepend_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003128 "no set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003129 NO_STR
3130 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003131 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003132 "Prepend to the as-path\n"
3133 "AS number\n")
3134
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003135DEFUN (set_aspath_exclude,
3136 set_aspath_exclude_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003137 "set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003138 SET_STR
3139 "Transform BGP AS-path attribute\n"
3140 "Exclude from the as-path\n"
3141 "AS number\n")
3142{
3143 int ret;
3144 char *str;
3145
3146 str = argv_concat (argv, argc, 0);
3147 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3148 XFREE (MTYPE_TMP, str);
3149 return ret;
3150}
3151
3152DEFUN (no_set_aspath_exclude,
3153 no_set_aspath_exclude_cmd,
3154 "no set as-path exclude",
3155 NO_STR
3156 SET_STR
3157 "Transform BGP AS_PATH attribute\n"
3158 "Exclude from the as-path\n")
3159{
3160 int ret;
3161 char *str;
3162
3163 if (argc == 0)
3164 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3165
3166 str = argv_concat (argv, argc, 0);
3167 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3168 XFREE (MTYPE_TMP, str);
3169 return ret;
3170}
3171
3172ALIAS (no_set_aspath_exclude,
3173 no_set_aspath_exclude_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003174 "no set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003175 NO_STR
3176 SET_STR
3177 "Transform BGP AS_PATH attribute\n"
3178 "Exclude from the as-path\n"
3179 "AS number\n")
3180
paul718e3742002-12-13 20:15:29 +00003181DEFUN (set_community,
3182 set_community_cmd,
3183 "set community .AA:NN",
3184 SET_STR
3185 "BGP community attribute\n"
3186 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3187{
3188 int i;
3189 int first = 0;
3190 int additive = 0;
3191 struct buffer *b;
3192 struct community *com = NULL;
3193 char *str;
3194 char *argstr;
3195 int ret;
3196
3197 b = buffer_new (1024);
3198
3199 for (i = 0; i < argc; i++)
3200 {
3201 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3202 {
3203 additive = 1;
3204 continue;
3205 }
3206
3207 if (first)
3208 buffer_putc (b, ' ');
3209 else
3210 first = 1;
3211
3212 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3213 {
3214 buffer_putstr (b, "internet");
3215 continue;
3216 }
3217 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3218 {
3219 buffer_putstr (b, "local-AS");
3220 continue;
3221 }
3222 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3223 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3224 {
3225 buffer_putstr (b, "no-advertise");
3226 continue;
3227 }
3228 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3229 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3230 {
3231 buffer_putstr (b, "no-export");
3232 continue;
3233 }
3234 buffer_putstr (b, argv[i]);
3235 }
3236 buffer_putc (b, '\0');
3237
3238 /* Fetch result string then compile it to communities attribute. */
3239 str = buffer_getstr (b);
3240 buffer_free (b);
3241
3242 if (str)
3243 {
3244 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003245 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003246 }
3247
3248 /* Can't compile user input into communities attribute. */
3249 if (! com)
3250 {
3251 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3252 return CMD_WARNING;
3253 }
3254
3255 /* Set communites attribute string. */
3256 str = community_str (com);
3257
3258 if (additive)
3259 {
3260 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3261 strcpy (argstr, str);
3262 strcpy (argstr + strlen (str), " additive");
3263 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3264 XFREE (MTYPE_TMP, argstr);
3265 }
3266 else
3267 ret = bgp_route_set_add (vty, vty->index, "community", str);
3268
3269 community_free (com);
3270
3271 return ret;
3272}
3273
3274DEFUN (set_community_none,
3275 set_community_none_cmd,
3276 "set community none",
3277 SET_STR
3278 "BGP community attribute\n"
3279 "No community attribute\n")
3280{
3281 return bgp_route_set_add (vty, vty->index, "community", "none");
3282}
3283
3284DEFUN (no_set_community,
3285 no_set_community_cmd,
3286 "no set community",
3287 NO_STR
3288 SET_STR
3289 "BGP community attribute\n")
3290{
3291 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3292}
3293
3294ALIAS (no_set_community,
3295 no_set_community_val_cmd,
3296 "no set community .AA:NN",
3297 NO_STR
3298 SET_STR
3299 "BGP community attribute\n"
3300 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3301
3302ALIAS (no_set_community,
3303 no_set_community_none_cmd,
3304 "no set community none",
3305 NO_STR
3306 SET_STR
3307 "BGP community attribute\n"
3308 "No community attribute\n")
3309
3310DEFUN (set_community_delete,
3311 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003312 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003313 SET_STR
3314 "set BGP community list (for deletion)\n"
3315 "Community-list number (standard)\n"
3316 "Communitly-list number (expanded)\n"
3317 "Community-list name\n"
3318 "Delete matching communities\n")
3319{
3320 char *str;
3321
3322 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3323 strcpy (str, argv[0]);
3324 strcpy (str + strlen (argv[0]), " delete");
3325
3326 bgp_route_set_add (vty, vty->index, "comm-list", str);
3327
3328 XFREE (MTYPE_TMP, str);
3329 return CMD_SUCCESS;
3330}
3331
3332DEFUN (no_set_community_delete,
3333 no_set_community_delete_cmd,
3334 "no set comm-list",
3335 NO_STR
3336 SET_STR
3337 "set BGP community list (for deletion)\n")
3338{
3339 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3340}
3341
3342ALIAS (no_set_community_delete,
3343 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003344 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003345 NO_STR
3346 SET_STR
3347 "set BGP community list (for deletion)\n"
3348 "Community-list number (standard)\n"
3349 "Communitly-list number (expanded)\n"
3350 "Community-list name\n"
3351 "Delete matching communities\n")
3352
3353DEFUN (set_ecommunity_rt,
3354 set_ecommunity_rt_cmd,
3355 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3356 SET_STR
3357 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003358 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003359 "VPN extended community\n")
3360{
3361 int ret;
3362 char *str;
3363
3364 str = argv_concat (argv, argc, 0);
3365 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3366 XFREE (MTYPE_TMP, str);
3367
3368 return ret;
3369}
3370
3371DEFUN (no_set_ecommunity_rt,
3372 no_set_ecommunity_rt_cmd,
3373 "no set extcommunity rt",
3374 NO_STR
3375 SET_STR
3376 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003377 "Route Target extended community\n")
paul718e3742002-12-13 20:15:29 +00003378{
3379 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3380}
3381
3382ALIAS (no_set_ecommunity_rt,
3383 no_set_ecommunity_rt_val_cmd,
3384 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3385 NO_STR
3386 SET_STR
3387 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003388 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003389 "VPN extended community\n")
3390
3391DEFUN (set_ecommunity_soo,
3392 set_ecommunity_soo_cmd,
3393 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3394 SET_STR
3395 "BGP extended community attribute\n"
3396 "Site-of-Origin extended community\n"
3397 "VPN extended community\n")
3398{
3399 int ret;
3400 char *str;
3401
3402 str = argv_concat (argv, argc, 0);
3403 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3404 XFREE (MTYPE_TMP, str);
3405 return ret;
3406}
3407
3408DEFUN (no_set_ecommunity_soo,
3409 no_set_ecommunity_soo_cmd,
3410 "no set extcommunity soo",
3411 NO_STR
3412 SET_STR
3413 "BGP extended community attribute\n"
3414 "Site-of-Origin extended community\n")
3415{
3416 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3417}
3418
3419ALIAS (no_set_ecommunity_soo,
3420 no_set_ecommunity_soo_val_cmd,
3421 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3422 NO_STR
3423 SET_STR
3424 "BGP extended community attribute\n"
3425 "Site-of-Origin extended community\n"
3426 "VPN extended community\n")
3427
3428DEFUN (set_origin,
3429 set_origin_cmd,
3430 "set origin (egp|igp|incomplete)",
3431 SET_STR
3432 "BGP origin code\n"
3433 "remote EGP\n"
3434 "local IGP\n"
3435 "unknown heritage\n")
3436{
3437 if (strncmp (argv[0], "igp", 2) == 0)
3438 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3439 if (strncmp (argv[0], "egp", 1) == 0)
3440 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3441 if (strncmp (argv[0], "incomplete", 2) == 0)
3442 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3443
3444 return CMD_WARNING;
3445}
3446
3447DEFUN (no_set_origin,
3448 no_set_origin_cmd,
3449 "no set origin",
3450 NO_STR
3451 SET_STR
3452 "BGP origin code\n")
3453{
3454 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3455}
3456
3457ALIAS (no_set_origin,
3458 no_set_origin_val_cmd,
3459 "no set origin (egp|igp|incomplete)",
3460 NO_STR
3461 SET_STR
3462 "BGP origin code\n"
3463 "remote EGP\n"
3464 "local IGP\n"
3465 "unknown heritage\n")
3466
3467DEFUN (set_atomic_aggregate,
3468 set_atomic_aggregate_cmd,
3469 "set atomic-aggregate",
3470 SET_STR
3471 "BGP atomic aggregate attribute\n" )
3472{
3473 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3474}
3475
3476DEFUN (no_set_atomic_aggregate,
3477 no_set_atomic_aggregate_cmd,
3478 "no set atomic-aggregate",
3479 NO_STR
3480 SET_STR
3481 "BGP atomic aggregate attribute\n" )
3482{
3483 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3484}
3485
3486DEFUN (set_aggregator_as,
3487 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003488 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003489 SET_STR
3490 "BGP aggregator attribute\n"
3491 "AS number of aggregator\n"
3492 "AS number\n"
3493 "IP address of aggregator\n")
3494{
3495 int ret;
3496 as_t as;
3497 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003498 char *argstr;
3499
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003500 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003501
paul718e3742002-12-13 20:15:29 +00003502 ret = inet_aton (argv[1], &address);
3503 if (ret == 0)
3504 {
3505 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3506 return CMD_WARNING;
3507 }
3508
3509 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3510 strlen (argv[0]) + strlen (argv[1]) + 2);
3511
3512 sprintf (argstr, "%s %s", argv[0], argv[1]);
3513
3514 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3515
3516 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3517
3518 return ret;
3519}
3520
3521DEFUN (no_set_aggregator_as,
3522 no_set_aggregator_as_cmd,
3523 "no set aggregator as",
3524 NO_STR
3525 SET_STR
3526 "BGP aggregator attribute\n"
3527 "AS number of aggregator\n")
3528{
3529 int ret;
3530 as_t as;
3531 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003532 char *argstr;
3533
3534 if (argv == 0)
3535 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3536
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003537 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003538
3539 ret = inet_aton (argv[1], &address);
3540 if (ret == 0)
3541 {
3542 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3543 return CMD_WARNING;
3544 }
3545
3546 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3547 strlen (argv[0]) + strlen (argv[1]) + 2);
3548
3549 sprintf (argstr, "%s %s", argv[0], argv[1]);
3550
3551 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3552
3553 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3554
3555 return ret;
3556}
3557
3558ALIAS (no_set_aggregator_as,
3559 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003560 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003561 NO_STR
3562 SET_STR
3563 "BGP aggregator attribute\n"
3564 "AS number of aggregator\n"
3565 "AS number\n"
3566 "IP address of aggregator\n")
3567
3568
3569#ifdef HAVE_IPV6
3570DEFUN (match_ipv6_address,
3571 match_ipv6_address_cmd,
3572 "match ipv6 address WORD",
3573 MATCH_STR
3574 IPV6_STR
3575 "Match IPv6 address of route\n"
3576 "IPv6 access-list name\n")
3577{
3578 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3579}
3580
3581DEFUN (no_match_ipv6_address,
3582 no_match_ipv6_address_cmd,
3583 "no match ipv6 address WORD",
3584 NO_STR
3585 MATCH_STR
3586 IPV6_STR
3587 "Match IPv6 address of route\n"
3588 "IPv6 access-list name\n")
3589{
3590 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3591}
3592
3593DEFUN (match_ipv6_next_hop,
3594 match_ipv6_next_hop_cmd,
3595 "match ipv6 next-hop X:X::X:X",
3596 MATCH_STR
3597 IPV6_STR
3598 "Match IPv6 next-hop address of route\n"
3599 "IPv6 address of next hop\n")
3600{
3601 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3602}
3603
3604DEFUN (no_match_ipv6_next_hop,
3605 no_match_ipv6_next_hop_cmd,
3606 "no match ipv6 next-hop X:X::X:X",
3607 NO_STR
3608 MATCH_STR
3609 IPV6_STR
3610 "Match IPv6 next-hop address of route\n"
3611 "IPv6 address of next hop\n")
3612{
3613 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3614}
3615
3616DEFUN (match_ipv6_address_prefix_list,
3617 match_ipv6_address_prefix_list_cmd,
3618 "match ipv6 address prefix-list WORD",
3619 MATCH_STR
3620 IPV6_STR
3621 "Match address of route\n"
3622 "Match entries of prefix-lists\n"
3623 "IP prefix-list name\n")
3624{
3625 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3626}
3627
3628DEFUN (no_match_ipv6_address_prefix_list,
3629 no_match_ipv6_address_prefix_list_cmd,
3630 "no match ipv6 address prefix-list WORD",
3631 NO_STR
3632 MATCH_STR
3633 IPV6_STR
3634 "Match address of route\n"
3635 "Match entries of prefix-lists\n"
3636 "IP prefix-list name\n")
3637{
3638 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3639}
3640
3641DEFUN (set_ipv6_nexthop_global,
3642 set_ipv6_nexthop_global_cmd,
3643 "set ipv6 next-hop global X:X::X:X",
3644 SET_STR
3645 IPV6_STR
3646 "IPv6 next-hop address\n"
3647 "IPv6 global address\n"
3648 "IPv6 address of next hop\n")
3649{
3650 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3651}
3652
3653DEFUN (no_set_ipv6_nexthop_global,
3654 no_set_ipv6_nexthop_global_cmd,
3655 "no set ipv6 next-hop global",
3656 NO_STR
3657 SET_STR
3658 IPV6_STR
3659 "IPv6 next-hop address\n"
3660 "IPv6 global address\n")
3661{
3662 if (argc == 0)
3663 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3664
3665 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3666}
3667
3668ALIAS (no_set_ipv6_nexthop_global,
3669 no_set_ipv6_nexthop_global_val_cmd,
3670 "no set ipv6 next-hop global X:X::X:X",
3671 NO_STR
3672 SET_STR
3673 IPV6_STR
3674 "IPv6 next-hop address\n"
3675 "IPv6 global address\n"
3676 "IPv6 address of next hop\n")
3677
3678DEFUN (set_ipv6_nexthop_local,
3679 set_ipv6_nexthop_local_cmd,
3680 "set ipv6 next-hop local X:X::X:X",
3681 SET_STR
3682 IPV6_STR
3683 "IPv6 next-hop address\n"
3684 "IPv6 local address\n"
3685 "IPv6 address of next hop\n")
3686{
3687 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3688}
3689
3690DEFUN (no_set_ipv6_nexthop_local,
3691 no_set_ipv6_nexthop_local_cmd,
3692 "no set ipv6 next-hop local",
3693 NO_STR
3694 SET_STR
3695 IPV6_STR
3696 "IPv6 next-hop address\n"
3697 "IPv6 local address\n")
3698{
3699 if (argc == 0)
3700 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3701
3702 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3703}
3704
3705ALIAS (no_set_ipv6_nexthop_local,
3706 no_set_ipv6_nexthop_local_val_cmd,
3707 "no set ipv6 next-hop local X:X::X:X",
3708 NO_STR
3709 SET_STR
3710 IPV6_STR
3711 "IPv6 next-hop address\n"
3712 "IPv6 local address\n"
3713 "IPv6 address of next hop\n")
3714#endif /* HAVE_IPV6 */
3715
3716DEFUN (set_vpnv4_nexthop,
3717 set_vpnv4_nexthop_cmd,
3718 "set vpnv4 next-hop A.B.C.D",
3719 SET_STR
3720 "VPNv4 information\n"
3721 "VPNv4 next-hop address\n"
3722 "IP address of next hop\n")
3723{
3724 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3725}
3726
3727DEFUN (no_set_vpnv4_nexthop,
3728 no_set_vpnv4_nexthop_cmd,
3729 "no set vpnv4 next-hop",
3730 NO_STR
3731 SET_STR
3732 "VPNv4 information\n"
3733 "VPNv4 next-hop address\n")
3734{
3735 if (argc == 0)
3736 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3737
3738 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3739}
3740
3741ALIAS (no_set_vpnv4_nexthop,
3742 no_set_vpnv4_nexthop_val_cmd,
3743 "no set vpnv4 next-hop A.B.C.D",
3744 NO_STR
3745 SET_STR
3746 "VPNv4 information\n"
3747 "VPNv4 next-hop address\n"
3748 "IP address of next hop\n")
3749
3750DEFUN (set_originator_id,
3751 set_originator_id_cmd,
3752 "set originator-id A.B.C.D",
3753 SET_STR
3754 "BGP originator ID attribute\n"
3755 "IP address of originator\n")
3756{
3757 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3758}
3759
3760DEFUN (no_set_originator_id,
3761 no_set_originator_id_cmd,
3762 "no set originator-id",
3763 NO_STR
3764 SET_STR
3765 "BGP originator ID attribute\n")
3766{
3767 if (argc == 0)
3768 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3769
3770 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3771}
3772
3773ALIAS (no_set_originator_id,
3774 no_set_originator_id_val_cmd,
3775 "no set originator-id A.B.C.D",
3776 NO_STR
3777 SET_STR
3778 "BGP originator ID attribute\n"
3779 "IP address of originator\n")
3780
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003781DEFUN_DEPRECATED (set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003782 set_pathlimit_ttl_cmd,
3783 "set pathlimit ttl <1-255>",
3784 SET_STR
3785 "BGP AS-Pathlimit attribute\n"
3786 "Set AS-Path Hop-count TTL\n")
3787{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003788 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003789}
3790
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003791DEFUN_DEPRECATED (no_set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003792 no_set_pathlimit_ttl_cmd,
3793 "no set pathlimit ttl",
3794 NO_STR
3795 SET_STR
3796 "BGP AS-Pathlimit attribute\n"
3797 "Set AS-Path Hop-count TTL\n")
3798{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003799 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003800}
3801
3802ALIAS (no_set_pathlimit_ttl,
3803 no_set_pathlimit_ttl_val_cmd,
3804 "no set pathlimit ttl <1-255>",
3805 NO_STR
3806 MATCH_STR
3807 "BGP AS-Pathlimit attribute\n"
3808 "Set AS-Path Hop-count TTL\n")
3809
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003810DEFUN_DEPRECATED (match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003811 match_pathlimit_as_cmd,
3812 "match pathlimit as <1-65535>",
3813 MATCH_STR
3814 "BGP AS-Pathlimit attribute\n"
3815 "Match Pathlimit AS number\n")
3816{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003817 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003818}
3819
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003820DEFUN_DEPRECATED (no_match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003821 no_match_pathlimit_as_cmd,
3822 "no match pathlimit as",
3823 NO_STR
3824 MATCH_STR
3825 "BGP AS-Pathlimit attribute\n"
3826 "Match Pathlimit AS number\n")
3827{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003828 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003829}
3830
3831ALIAS (no_match_pathlimit_as,
3832 no_match_pathlimit_as_val_cmd,
3833 "no match pathlimit as <1-65535>",
3834 NO_STR
3835 MATCH_STR
3836 "BGP AS-Pathlimit attribute\n"
3837 "Match Pathlimit ASN\n")
3838
paul718e3742002-12-13 20:15:29 +00003839
3840/* Initialization of route map. */
3841void
paul94f2b392005-06-28 12:44:16 +00003842bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003843{
3844 route_map_init ();
3845 route_map_init_vty ();
3846 route_map_add_hook (bgp_route_map_update);
3847 route_map_delete_hook (bgp_route_map_update);
3848
paulfee0f4c2004-09-13 05:12:46 +00003849 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003850 route_map_install_match (&route_match_ip_address_cmd);
3851 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003852 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003853 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3854 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003855 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003856 route_map_install_match (&route_match_aspath_cmd);
3857 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003858 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003859 route_map_install_match (&route_match_metric_cmd);
3860 route_map_install_match (&route_match_origin_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003861 route_map_install_match (&route_match_probability_cmd);
paul718e3742002-12-13 20:15:29 +00003862
3863 route_map_install_set (&route_set_ip_nexthop_cmd);
3864 route_map_install_set (&route_set_local_pref_cmd);
3865 route_map_install_set (&route_set_weight_cmd);
3866 route_map_install_set (&route_set_metric_cmd);
3867 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003868 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003869 route_map_install_set (&route_set_origin_cmd);
3870 route_map_install_set (&route_set_atomic_aggregate_cmd);
3871 route_map_install_set (&route_set_aggregator_as_cmd);
3872 route_map_install_set (&route_set_community_cmd);
3873 route_map_install_set (&route_set_community_delete_cmd);
3874 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3875 route_map_install_set (&route_set_originator_id_cmd);
3876 route_map_install_set (&route_set_ecommunity_rt_cmd);
3877 route_map_install_set (&route_set_ecommunity_soo_cmd);
3878
paulfee0f4c2004-09-13 05:12:46 +00003879 install_element (RMAP_NODE, &match_peer_cmd);
3880 install_element (RMAP_NODE, &match_peer_local_cmd);
3881 install_element (RMAP_NODE, &no_match_peer_cmd);
3882 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3883 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003884 install_element (RMAP_NODE, &match_ip_address_cmd);
3885 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3886 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3887 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3888 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3889 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003890 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3891 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3892 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003893 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3894 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3895 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3896 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3897 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3898 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003899 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3900 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3901 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003902
3903 install_element (RMAP_NODE, &match_aspath_cmd);
3904 install_element (RMAP_NODE, &no_match_aspath_cmd);
3905 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3906 install_element (RMAP_NODE, &match_metric_cmd);
3907 install_element (RMAP_NODE, &no_match_metric_cmd);
3908 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3909 install_element (RMAP_NODE, &match_community_cmd);
3910 install_element (RMAP_NODE, &match_community_exact_cmd);
3911 install_element (RMAP_NODE, &no_match_community_cmd);
3912 install_element (RMAP_NODE, &no_match_community_val_cmd);
3913 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003914 install_element (RMAP_NODE, &match_ecommunity_cmd);
3915 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3916 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003917 install_element (RMAP_NODE, &match_origin_cmd);
3918 install_element (RMAP_NODE, &no_match_origin_cmd);
3919 install_element (RMAP_NODE, &no_match_origin_val_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003920 install_element (RMAP_NODE, &match_probability_cmd);
3921 install_element (RMAP_NODE, &no_match_probability_cmd);
3922 install_element (RMAP_NODE, &no_match_probability_val_cmd);
paul718e3742002-12-13 20:15:29 +00003923
3924 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003925 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003926 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3927 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3928 install_element (RMAP_NODE, &set_local_pref_cmd);
3929 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3930 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3931 install_element (RMAP_NODE, &set_weight_cmd);
3932 install_element (RMAP_NODE, &no_set_weight_cmd);
3933 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3934 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003935 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003936 install_element (RMAP_NODE, &no_set_metric_cmd);
3937 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3938 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003939 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003940 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3941 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003942 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
3943 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00003944 install_element (RMAP_NODE, &set_origin_cmd);
3945 install_element (RMAP_NODE, &no_set_origin_cmd);
3946 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3947 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3948 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3949 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3950 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3951 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3952 install_element (RMAP_NODE, &set_community_cmd);
3953 install_element (RMAP_NODE, &set_community_none_cmd);
3954 install_element (RMAP_NODE, &no_set_community_cmd);
3955 install_element (RMAP_NODE, &no_set_community_val_cmd);
3956 install_element (RMAP_NODE, &no_set_community_none_cmd);
3957 install_element (RMAP_NODE, &set_community_delete_cmd);
3958 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3959 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3960 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3961 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3962 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3963 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3964 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3965 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3966 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3967 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3968 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3969 install_element (RMAP_NODE, &set_originator_id_cmd);
3970 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3971 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3972
3973#ifdef HAVE_IPV6
3974 route_map_install_match (&route_match_ipv6_address_cmd);
3975 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3976 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3977 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3978 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Paul Jakma41367172007-08-06 15:24:51 +00003979
paul718e3742002-12-13 20:15:29 +00003980 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3981 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3982 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3983 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3984 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3985 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3986 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3987 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3988 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3989 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3990 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3991 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3992#endif /* HAVE_IPV6 */
Paul Jakma41367172007-08-06 15:24:51 +00003993
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003994 /* AS-Pathlimit: functionality removed, commands kept for
3995 * compatibility.
3996 */
Paul Jakma41367172007-08-06 15:24:51 +00003997 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
3998 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
3999 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
4000 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
4001 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
4002 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00004003}