blob: 2b05e89822b00941f1a9e39b4ebaf580dbb7995e [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* Route map function of bgpd.
2 Copyright (C) 1998, 1999 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "prefix.h"
24#include "filter.h"
25#include "routemap.h"
26#include "command.h"
27#include "linklist.h"
28#include "plist.h"
29#include "memory.h"
30#include "log.h"
Jeremy Jackson25f45882009-01-12 16:06:12 -050031#ifdef HAVE_LIBPCREPOSIX
32# include <pcreposix.h>
paul718e3742002-12-13 20:15:29 +000033#else
Jeremy Jackson25f45882009-01-12 16:06:12 -050034# ifdef HAVE_GNU_REGEX
35# include <regex.h>
36# else
37# include "regex-gnu.h"
38# endif /* HAVE_GNU_REGEX */
39#endif /* HAVE_LIBPCREPOSIX */
paul718e3742002-12-13 20:15:29 +000040#include "buffer.h"
41#include "sockunion.h"
42
43#include "bgpd/bgpd.h"
44#include "bgpd/bgp_table.h"
45#include "bgpd/bgp_attr.h"
46#include "bgpd/bgp_aspath.h"
47#include "bgpd/bgp_route.h"
48#include "bgpd/bgp_regex.h"
49#include "bgpd/bgp_community.h"
50#include "bgpd/bgp_clist.h"
51#include "bgpd/bgp_filter.h"
52#include "bgpd/bgp_mplsvpn.h"
53#include "bgpd/bgp_ecommunity.h"
Paul Jakma320da872008-07-02 13:40:33 +000054#include "bgpd/bgp_vty.h"
paul718e3742002-12-13 20:15:29 +000055
56/* Memo of route-map commands.
57
58o Cisco route-map
59
60 match as-path : Done
61 community : Done
62 interface : Not yet
63 ip address : Done
64 ip next-hop : Done
hassoc1643bb2005-02-02 16:43:17 +000065 ip route-source : Done
paul718e3742002-12-13 20:15:29 +000066 ip prefix-list : Done
67 ipv6 address : Done
68 ipv6 next-hop : Done
69 ipv6 route-source: (This will not be implemented by bgpd)
70 ipv6 prefix-list : Done
71 length : (This will not be implemented by bgpd)
72 metric : Done
73 route-type : (This will not be implemented by bgpd)
74 tag : (This will not be implemented by bgpd)
75
76 set as-path prepend : Done
77 as-path tag : Not yet
78 automatic-tag : (This will not be implemented by bgpd)
79 community : Done
80 comm-list : Not yet
81 dampning : Not yet
82 default : (This will not be implemented by bgpd)
83 interface : (This will not be implemented by bgpd)
84 ip default : (This will not be implemented by bgpd)
85 ip next-hop : Done
86 ip precedence : (This will not be implemented by bgpd)
87 ip tos : (This will not be implemented by bgpd)
88 level : (This will not be implemented by bgpd)
89 local-preference : Done
90 metric : Done
91 metric-type : Not yet
92 origin : Done
93 tag : (This will not be implemented by bgpd)
94 weight : Done
95
96o Local extention
97
98 set ipv6 next-hop global: Done
99 set ipv6 next-hop local : Done
Denis Ovsienko841f7a52008-04-10 11:47:45 +0000100 set as-path exclude : Done
paul718e3742002-12-13 20:15:29 +0000101
102*/
103
paulfee0f4c2004-09-13 05:12:46 +0000104 /* 'match peer (A.B.C.D|X:X::X:X)' */
105
106/* Compares the peer specified in the 'match peer' clause with the peer
107 received in bgp_info->peer. If it is the same, or if the peer structure
108 received is a peer_group containing it, returns RMAP_MATCH. */
paul94f2b392005-06-28 12:44:16 +0000109static route_map_result_t
paulfee0f4c2004-09-13 05:12:46 +0000110route_match_peer (void *rule, struct prefix *prefix, route_map_object_t type,
111 void *object)
112{
113 union sockunion *su;
114 union sockunion *su2;
115 struct peer_group *group;
116 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +0000117 struct listnode *node, *nnode;
paulfee0f4c2004-09-13 05:12:46 +0000118
119 if (type == RMAP_BGP)
120 {
121 su = rule;
122 peer = ((struct bgp_info *) object)->peer;
123
124 if ( ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT) &&
125 ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_EXPORT) )
126 return RMAP_NOMATCH;
127
128 /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
129 REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
130 su2 = sockunion_str2su ("0.0.0.0");
131 if ( sockunion_same (su, su2) )
132 {
paul22db9de2005-05-19 01:50:11 +0000133 int ret;
paulfee0f4c2004-09-13 05:12:46 +0000134 if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
135 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE) ||
136 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
paul22db9de2005-05-19 01:50:11 +0000137 ret = RMAP_MATCH;
paulfee0f4c2004-09-13 05:12:46 +0000138 else
paul22db9de2005-05-19 01:50:11 +0000139 ret = RMAP_NOMATCH;
140
141 sockunion_free (su2);
142 return ret;
paulfee0f4c2004-09-13 05:12:46 +0000143 }
paul22db9de2005-05-19 01:50:11 +0000144 sockunion_free (su2);
145
paulfee0f4c2004-09-13 05:12:46 +0000146 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
147 {
148 if (sockunion_same (su, &peer->su))
149 return RMAP_MATCH;
150
151 return RMAP_NOMATCH;
152 }
153 else
154 {
155 group = peer->group;
paul1eb8ef22005-04-07 07:30:20 +0000156 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
paulfee0f4c2004-09-13 05:12:46 +0000157 {
158 if (sockunion_same (su, &peer->su))
159 return RMAP_MATCH;
paulfee0f4c2004-09-13 05:12:46 +0000160 }
Paul Jakma30a22312008-08-15 14:05:22 +0100161 return RMAP_NOMATCH;
paulfee0f4c2004-09-13 05:12:46 +0000162 }
163 }
164 return RMAP_NOMATCH;
165}
166
paul94f2b392005-06-28 12:44:16 +0000167static void *
paulfd79ac92004-10-13 05:06:08 +0000168route_match_peer_compile (const char *arg)
paulfee0f4c2004-09-13 05:12:46 +0000169{
170 union sockunion *su;
171 int ret;
172
173 su = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union sockunion));
174
175 ret = str2sockunion ( (arg)? arg : "0.0.0.0", su);
176 if (ret < 0) {
177 XFREE (MTYPE_ROUTE_MAP_COMPILED, su);
178 return NULL;
179 }
180
181 return su;
182}
183
184/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000185static void
paulfee0f4c2004-09-13 05:12:46 +0000186route_match_peer_free (void *rule)
187{
188 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
189}
190
191/* Route map commands for ip address matching. */
192struct route_map_rule_cmd route_match_peer_cmd =
193{
194 "peer",
195 route_match_peer,
196 route_match_peer_compile,
197 route_match_peer_free
198};
199
paul718e3742002-12-13 20:15:29 +0000200/* `match ip address IP_ACCESS_LIST' */
201
202/* Match function should return 1 if match is success else return
203 zero. */
paul94f2b392005-06-28 12:44:16 +0000204static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000205route_match_ip_address (void *rule, struct prefix *prefix,
206 route_map_object_t type, void *object)
207{
208 struct access_list *alist;
209 /* struct prefix_ipv4 match; */
210
211 if (type == RMAP_BGP)
212 {
213 alist = access_list_lookup (AFI_IP, (char *) rule);
214 if (alist == NULL)
215 return RMAP_NOMATCH;
216
217 return (access_list_apply (alist, prefix) == FILTER_DENY ?
218 RMAP_NOMATCH : RMAP_MATCH);
219 }
220 return RMAP_NOMATCH;
221}
222
223/* Route map `ip address' match statement. `arg' should be
224 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000225static void *
paulfd79ac92004-10-13 05:06:08 +0000226route_match_ip_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000227{
228 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
229}
230
231/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000232static void
paul718e3742002-12-13 20:15:29 +0000233route_match_ip_address_free (void *rule)
234{
235 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
236}
237
238/* Route map commands for ip address matching. */
239struct route_map_rule_cmd route_match_ip_address_cmd =
240{
241 "ip address",
242 route_match_ip_address,
243 route_match_ip_address_compile,
244 route_match_ip_address_free
245};
246
247/* `match ip next-hop IP_ADDRESS' */
248
249/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000250static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000251route_match_ip_next_hop (void *rule, struct prefix *prefix,
252 route_map_object_t type, void *object)
253{
254 struct access_list *alist;
255 struct bgp_info *bgp_info;
256 struct prefix_ipv4 p;
257
258 if (type == RMAP_BGP)
259 {
260 bgp_info = object;
261 p.family = AF_INET;
262 p.prefix = bgp_info->attr->nexthop;
263 p.prefixlen = IPV4_MAX_BITLEN;
264
265 alist = access_list_lookup (AFI_IP, (char *) rule);
266 if (alist == NULL)
267 return RMAP_NOMATCH;
268
269 return (access_list_apply (alist, &p) == FILTER_DENY ?
270 RMAP_NOMATCH : RMAP_MATCH);
271 }
272 return RMAP_NOMATCH;
273}
274
275/* Route map `ip next-hop' match statement. `arg' is
276 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000277static void *
paulfd79ac92004-10-13 05:06:08 +0000278route_match_ip_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000279{
280 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
281}
282
283/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000284static void
paul718e3742002-12-13 20:15:29 +0000285route_match_ip_next_hop_free (void *rule)
286{
287 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
288}
289
290/* Route map commands for ip next-hop matching. */
291struct route_map_rule_cmd route_match_ip_next_hop_cmd =
292{
293 "ip next-hop",
294 route_match_ip_next_hop,
295 route_match_ip_next_hop_compile,
296 route_match_ip_next_hop_free
297};
298
hassoc1643bb2005-02-02 16:43:17 +0000299/* `match ip route-source ACCESS-LIST' */
300
301/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000302static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000303route_match_ip_route_source (void *rule, struct prefix *prefix,
304 route_map_object_t type, void *object)
305{
306 struct access_list *alist;
307 struct bgp_info *bgp_info;
308 struct peer *peer;
309 struct prefix_ipv4 p;
310
311 if (type == RMAP_BGP)
312 {
313 bgp_info = object;
314 peer = bgp_info->peer;
315
316 if (! peer || sockunion_family (&peer->su) != AF_INET)
317 return RMAP_NOMATCH;
318
319 p.family = AF_INET;
320 p.prefix = peer->su.sin.sin_addr;
321 p.prefixlen = IPV4_MAX_BITLEN;
322
323 alist = access_list_lookup (AFI_IP, (char *) rule);
324 if (alist == NULL)
325 return RMAP_NOMATCH;
326
327 return (access_list_apply (alist, &p) == FILTER_DENY ?
328 RMAP_NOMATCH : RMAP_MATCH);
329 }
330 return RMAP_NOMATCH;
331}
332
333/* Route map `ip route-source' match statement. `arg' is
334 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000335static void *
hassoc1643bb2005-02-02 16:43:17 +0000336route_match_ip_route_source_compile (const char *arg)
337{
338 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
339}
340
341/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000342static void
hassoc1643bb2005-02-02 16:43:17 +0000343route_match_ip_route_source_free (void *rule)
344{
345 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
346}
347
348/* Route map commands for ip route-source matching. */
349struct route_map_rule_cmd route_match_ip_route_source_cmd =
350{
351 "ip route-source",
352 route_match_ip_route_source,
353 route_match_ip_route_source_compile,
354 route_match_ip_route_source_free
355};
356
paul718e3742002-12-13 20:15:29 +0000357/* `match ip address prefix-list PREFIX_LIST' */
358
paul94f2b392005-06-28 12:44:16 +0000359static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000360route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
361 route_map_object_t type, void *object)
362{
363 struct prefix_list *plist;
364
365 if (type == RMAP_BGP)
366 {
367 plist = prefix_list_lookup (AFI_IP, (char *) rule);
368 if (plist == NULL)
369 return RMAP_NOMATCH;
370
371 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
372 RMAP_NOMATCH : RMAP_MATCH);
373 }
374 return RMAP_NOMATCH;
375}
376
paul94f2b392005-06-28 12:44:16 +0000377static void *
paulfd79ac92004-10-13 05:06:08 +0000378route_match_ip_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000379{
380 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
381}
382
paul94f2b392005-06-28 12:44:16 +0000383static void
paul718e3742002-12-13 20:15:29 +0000384route_match_ip_address_prefix_list_free (void *rule)
385{
386 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
387}
388
389struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
390{
391 "ip address prefix-list",
392 route_match_ip_address_prefix_list,
393 route_match_ip_address_prefix_list_compile,
394 route_match_ip_address_prefix_list_free
395};
396
397/* `match ip next-hop prefix-list PREFIX_LIST' */
398
paul94f2b392005-06-28 12:44:16 +0000399static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000400route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
401 route_map_object_t type, void *object)
402{
403 struct prefix_list *plist;
404 struct bgp_info *bgp_info;
405 struct prefix_ipv4 p;
406
407 if (type == RMAP_BGP)
408 {
409 bgp_info = object;
410 p.family = AF_INET;
411 p.prefix = bgp_info->attr->nexthop;
412 p.prefixlen = IPV4_MAX_BITLEN;
413
414 plist = prefix_list_lookup (AFI_IP, (char *) rule);
415 if (plist == NULL)
416 return RMAP_NOMATCH;
417
418 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
419 RMAP_NOMATCH : RMAP_MATCH);
420 }
421 return RMAP_NOMATCH;
422}
423
paul94f2b392005-06-28 12:44:16 +0000424static void *
paulfd79ac92004-10-13 05:06:08 +0000425route_match_ip_next_hop_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000426{
427 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
428}
429
paul94f2b392005-06-28 12:44:16 +0000430static void
paul718e3742002-12-13 20:15:29 +0000431route_match_ip_next_hop_prefix_list_free (void *rule)
432{
433 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
434}
435
436struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
437{
438 "ip next-hop prefix-list",
439 route_match_ip_next_hop_prefix_list,
440 route_match_ip_next_hop_prefix_list_compile,
441 route_match_ip_next_hop_prefix_list_free
442};
443
hassoc1643bb2005-02-02 16:43:17 +0000444/* `match ip route-source prefix-list PREFIX_LIST' */
445
paul94f2b392005-06-28 12:44:16 +0000446static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000447route_match_ip_route_source_prefix_list (void *rule, struct prefix *prefix,
448 route_map_object_t type, void *object)
449{
450 struct prefix_list *plist;
451 struct bgp_info *bgp_info;
452 struct peer *peer;
453 struct prefix_ipv4 p;
454
455 if (type == RMAP_BGP)
456 {
457 bgp_info = object;
458 peer = bgp_info->peer;
459
460 if (! peer || sockunion_family (&peer->su) != AF_INET)
461 return RMAP_NOMATCH;
462
463 p.family = AF_INET;
464 p.prefix = peer->su.sin.sin_addr;
465 p.prefixlen = IPV4_MAX_BITLEN;
466
467 plist = prefix_list_lookup (AFI_IP, (char *) rule);
468 if (plist == NULL)
469 return RMAP_NOMATCH;
470
471 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
472 RMAP_NOMATCH : RMAP_MATCH);
473 }
474 return RMAP_NOMATCH;
475}
476
paul94f2b392005-06-28 12:44:16 +0000477static void *
hassoc1643bb2005-02-02 16:43:17 +0000478route_match_ip_route_source_prefix_list_compile (const char *arg)
479{
480 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
481}
482
paul94f2b392005-06-28 12:44:16 +0000483static void
hassoc1643bb2005-02-02 16:43:17 +0000484route_match_ip_route_source_prefix_list_free (void *rule)
485{
486 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
487}
488
489struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd =
490{
491 "ip route-source prefix-list",
492 route_match_ip_route_source_prefix_list,
493 route_match_ip_route_source_prefix_list_compile,
494 route_match_ip_route_source_prefix_list_free
495};
496
paul718e3742002-12-13 20:15:29 +0000497/* `match metric METRIC' */
498
499/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000500static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000501route_match_metric (void *rule, struct prefix *prefix,
502 route_map_object_t type, void *object)
503{
504 u_int32_t *med;
505 struct bgp_info *bgp_info;
506
507 if (type == RMAP_BGP)
508 {
509 med = rule;
510 bgp_info = object;
511
512 if (bgp_info->attr->med == *med)
513 return RMAP_MATCH;
514 else
515 return RMAP_NOMATCH;
516 }
517 return RMAP_NOMATCH;
518}
519
520/* Route map `match metric' match statement. `arg' is MED value */
paul94f2b392005-06-28 12:44:16 +0000521static void *
paulfd79ac92004-10-13 05:06:08 +0000522route_match_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000523{
524 u_int32_t *med;
525 char *endptr = NULL;
paul3b424972003-10-13 09:47:32 +0000526 unsigned long tmpval;
paul718e3742002-12-13 20:15:29 +0000527
paul3b424972003-10-13 09:47:32 +0000528 tmpval = strtoul (arg, &endptr, 10);
paulfd79ac92004-10-13 05:06:08 +0000529 if (*endptr != '\0' || tmpval == ULONG_MAX || tmpval > UINT32_MAX)
paul3b424972003-10-13 09:47:32 +0000530 return NULL;
paulfd79ac92004-10-13 05:06:08 +0000531
paul718e3742002-12-13 20:15:29 +0000532 med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +0000533
534 if (!med)
535 return med;
536
paul3b424972003-10-13 09:47:32 +0000537 *med = tmpval;
paul718e3742002-12-13 20:15:29 +0000538 return med;
539}
540
541/* Free route map's compiled `match metric' value. */
paul94f2b392005-06-28 12:44:16 +0000542static void
paul718e3742002-12-13 20:15:29 +0000543route_match_metric_free (void *rule)
544{
545 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
546}
547
548/* Route map commands for metric matching. */
549struct route_map_rule_cmd route_match_metric_cmd =
550{
551 "metric",
552 route_match_metric,
553 route_match_metric_compile,
554 route_match_metric_free
555};
556
557/* `match as-path ASPATH' */
558
559/* Match function for as-path match. I assume given object is */
paul94f2b392005-06-28 12:44:16 +0000560static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000561route_match_aspath (void *rule, struct prefix *prefix,
562 route_map_object_t type, void *object)
563{
564
565 struct as_list *as_list;
566 struct bgp_info *bgp_info;
567
568 if (type == RMAP_BGP)
569 {
570 as_list = as_list_lookup ((char *) rule);
571 if (as_list == NULL)
572 return RMAP_NOMATCH;
573
574 bgp_info = object;
575
576 /* Perform match. */
577 return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
578 }
579 return RMAP_NOMATCH;
580}
581
582/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000583static void *
paulfd79ac92004-10-13 05:06:08 +0000584route_match_aspath_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000585{
586 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
587}
588
589/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000590static void
paul718e3742002-12-13 20:15:29 +0000591route_match_aspath_free (void *rule)
592{
593 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
594}
595
596/* Route map commands for aspath matching. */
597struct route_map_rule_cmd route_match_aspath_cmd =
598{
599 "as-path",
600 route_match_aspath,
601 route_match_aspath_compile,
602 route_match_aspath_free
603};
paul718e3742002-12-13 20:15:29 +0000604
605/* `match community COMMUNIY' */
606struct rmap_community
607{
608 char *name;
609 int exact;
610};
611
612/* Match function for community match. */
paul94f2b392005-06-28 12:44:16 +0000613static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000614route_match_community (void *rule, struct prefix *prefix,
615 route_map_object_t type, void *object)
616{
617 struct community_list *list;
618 struct bgp_info *bgp_info;
619 struct rmap_community *rcom;
620
621 if (type == RMAP_BGP)
622 {
623 bgp_info = object;
624 rcom = rule;
625
hassofee6e4e2005-02-02 16:29:31 +0000626 list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +0000627 if (! list)
628 return RMAP_NOMATCH;
629
630 if (rcom->exact)
631 {
632 if (community_list_exact_match (bgp_info->attr->community, list))
633 return RMAP_MATCH;
634 }
635 else
636 {
637 if (community_list_match (bgp_info->attr->community, list))
638 return RMAP_MATCH;
639 }
640 }
641 return RMAP_NOMATCH;
642}
643
644/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000645static void *
paulfd79ac92004-10-13 05:06:08 +0000646route_match_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000647{
648 struct rmap_community *rcom;
649 int len;
650 char *p;
651
652 rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
653
654 p = strchr (arg, ' ');
655 if (p)
656 {
657 len = p - arg;
658 rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
659 memcpy (rcom->name, arg, len);
660 rcom->exact = 1;
661 }
662 else
663 {
664 rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
665 rcom->exact = 0;
666 }
667 return rcom;
668}
669
670/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000671static void
paul718e3742002-12-13 20:15:29 +0000672route_match_community_free (void *rule)
673{
674 struct rmap_community *rcom = rule;
675
676 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
677 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
678}
679
680/* Route map commands for community matching. */
681struct route_map_rule_cmd route_match_community_cmd =
682{
683 "community",
684 route_match_community,
685 route_match_community_compile,
686 route_match_community_free
687};
688
paul73ffb252003-04-19 15:49:49 +0000689/* Match function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000690static route_map_result_t
paul73ffb252003-04-19 15:49:49 +0000691route_match_ecommunity (void *rule, struct prefix *prefix,
692 route_map_object_t type, void *object)
693{
694 struct community_list *list;
695 struct bgp_info *bgp_info;
696
697 if (type == RMAP_BGP)
698 {
699 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +0000700
701 if (!bgp_info->attr->extra)
702 return RMAP_NOMATCH;
703
paul73ffb252003-04-19 15:49:49 +0000704 list = community_list_lookup (bgp_clist, (char *) rule,
hassofee6e4e2005-02-02 16:29:31 +0000705 EXTCOMMUNITY_LIST_MASTER);
paul73ffb252003-04-19 15:49:49 +0000706 if (! list)
707 return RMAP_NOMATCH;
708
Paul Jakmafb982c22007-05-04 20:15:47 +0000709 if (ecommunity_list_match (bgp_info->attr->extra->ecommunity, list))
paul73ffb252003-04-19 15:49:49 +0000710 return RMAP_MATCH;
711 }
712 return RMAP_NOMATCH;
713}
714
715/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000716static void *
paulfd79ac92004-10-13 05:06:08 +0000717route_match_ecommunity_compile (const char *arg)
paul73ffb252003-04-19 15:49:49 +0000718{
719 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
720}
721
722/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000723static void
paul73ffb252003-04-19 15:49:49 +0000724route_match_ecommunity_free (void *rule)
725{
726 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
727}
728
729/* Route map commands for community matching. */
730struct route_map_rule_cmd route_match_ecommunity_cmd =
731{
732 "extcommunity",
733 route_match_ecommunity,
734 route_match_ecommunity_compile,
735 route_match_ecommunity_free
736};
737
paul718e3742002-12-13 20:15:29 +0000738/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
739 and `address-family vpnv4'. */
740
741/* `match origin' */
paul94f2b392005-06-28 12:44:16 +0000742static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000743route_match_origin (void *rule, struct prefix *prefix,
744 route_map_object_t type, void *object)
745{
746 u_char *origin;
747 struct bgp_info *bgp_info;
748
749 if (type == RMAP_BGP)
750 {
751 origin = rule;
752 bgp_info = object;
753
754 if (bgp_info->attr->origin == *origin)
755 return RMAP_MATCH;
756 }
757
758 return RMAP_NOMATCH;
759}
760
paul94f2b392005-06-28 12:44:16 +0000761static void *
paulfd79ac92004-10-13 05:06:08 +0000762route_match_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000763{
764 u_char *origin;
765
766 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
767
768 if (strcmp (arg, "igp") == 0)
769 *origin = 0;
770 else if (strcmp (arg, "egp") == 0)
771 *origin = 1;
772 else
773 *origin = 2;
774
775 return origin;
776}
777
778/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000779static void
paul718e3742002-12-13 20:15:29 +0000780route_match_origin_free (void *rule)
781{
782 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
783}
784
785/* Route map commands for origin matching. */
786struct route_map_rule_cmd route_match_origin_cmd =
787{
788 "origin",
789 route_match_origin,
790 route_match_origin_compile,
791 route_match_origin_free
792};
793/* `set ip next-hop IP_ADDRESS' */
794
795/* Set nexthop to object. ojbect must be pointer to struct attr. */
paulac41b2a2003-08-12 05:32:27 +0000796struct rmap_ip_nexthop_set
797{
798 struct in_addr *address;
799 int peer_address;
800};
801
paul94f2b392005-06-28 12:44:16 +0000802static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000803route_set_ip_nexthop (void *rule, struct prefix *prefix,
804 route_map_object_t type, void *object)
805{
paulac41b2a2003-08-12 05:32:27 +0000806 struct rmap_ip_nexthop_set *rins = rule;
807 struct in_addr peer_address;
paul718e3742002-12-13 20:15:29 +0000808 struct bgp_info *bgp_info;
paulac41b2a2003-08-12 05:32:27 +0000809 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000810
811 if (type == RMAP_BGP)
812 {
paul718e3742002-12-13 20:15:29 +0000813 bgp_info = object;
paulac41b2a2003-08-12 05:32:27 +0000814 peer = bgp_info->peer;
815
816 if (rins->peer_address)
817 {
paulfee0f4c2004-09-13 05:12:46 +0000818 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
819 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
paulac41b2a2003-08-12 05:32:27 +0000820 && peer->su_remote
821 && sockunion_family (peer->su_remote) == AF_INET)
822 {
823 inet_aton (sockunion_su2str (peer->su_remote), &peer_address);
824 bgp_info->attr->nexthop = peer_address;
825 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
826 }
827 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
828 && peer->su_local
829 && sockunion_family (peer->su_local) == AF_INET)
830 {
831 inet_aton (sockunion_su2str (peer->su_local), &peer_address);
832 bgp_info->attr->nexthop = peer_address;
833 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
834 }
835 }
836 else
837 {
838 /* Set next hop value. */
839 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
840 bgp_info->attr->nexthop = *rins->address;
841 }
paul718e3742002-12-13 20:15:29 +0000842 }
843
844 return RMAP_OKAY;
845}
846
847/* Route map `ip nexthop' compile function. Given string is converted
848 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +0000849static void *
paulfd79ac92004-10-13 05:06:08 +0000850route_set_ip_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000851{
paulac41b2a2003-08-12 05:32:27 +0000852 struct rmap_ip_nexthop_set *rins;
853 struct in_addr *address = NULL;
854 int peer_address = 0;
paul718e3742002-12-13 20:15:29 +0000855 int ret;
paul718e3742002-12-13 20:15:29 +0000856
paulac41b2a2003-08-12 05:32:27 +0000857 if (strcmp (arg, "peer-address") == 0)
858 peer_address = 1;
859 else
paul718e3742002-12-13 20:15:29 +0000860 {
paulac41b2a2003-08-12 05:32:27 +0000861 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
862 ret = inet_aton (arg, address);
863
864 if (ret == 0)
865 {
866 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
867 return NULL;
868 }
paul718e3742002-12-13 20:15:29 +0000869 }
870
Stephen Hemminger393deb92008-08-18 14:13:29 -0700871 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
paulac41b2a2003-08-12 05:32:27 +0000872
873 rins->address = address;
874 rins->peer_address = peer_address;
875
876 return rins;
paul718e3742002-12-13 20:15:29 +0000877}
878
879/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +0000880static void
paul718e3742002-12-13 20:15:29 +0000881route_set_ip_nexthop_free (void *rule)
882{
paulac41b2a2003-08-12 05:32:27 +0000883 struct rmap_ip_nexthop_set *rins = rule;
884
885 if (rins->address)
886 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
887
888 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +0000889}
890
891/* Route map commands for ip nexthop set. */
892struct route_map_rule_cmd route_set_ip_nexthop_cmd =
893{
894 "ip next-hop",
895 route_set_ip_nexthop,
896 route_set_ip_nexthop_compile,
897 route_set_ip_nexthop_free
898};
899
900/* `set local-preference LOCAL_PREF' */
901
902/* Set local preference. */
paul94f2b392005-06-28 12:44:16 +0000903static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000904route_set_local_pref (void *rule, struct prefix *prefix,
905 route_map_object_t type, void *object)
906{
907 u_int32_t *local_pref;
908 struct bgp_info *bgp_info;
909
910 if (type == RMAP_BGP)
911 {
912 /* Fetch routemap's rule information. */
913 local_pref = rule;
914 bgp_info = object;
915
916 /* Set local preference value. */
917 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
918 bgp_info->attr->local_pref = *local_pref;
919 }
920
921 return RMAP_OKAY;
922}
923
924/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +0000925static void *
paulfd79ac92004-10-13 05:06:08 +0000926route_set_local_pref_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000927{
paulfd79ac92004-10-13 05:06:08 +0000928 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +0000929 u_int32_t *local_pref;
930 char *endptr = NULL;
931
932 /* Local preference value shoud be integer. */
933 if (! all_digit (arg))
934 return NULL;
paulfd79ac92004-10-13 05:06:08 +0000935
936 tmp = strtoul (arg, &endptr, 10);
937 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
938 return NULL;
939
940 local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
941
942 if (!local_pref)
943 return local_pref;
944
945 *local_pref = tmp;
946
paul718e3742002-12-13 20:15:29 +0000947 return local_pref;
948}
949
950/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +0000951static void
paul718e3742002-12-13 20:15:29 +0000952route_set_local_pref_free (void *rule)
953{
954 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
955}
956
957/* Set local preference rule structure. */
958struct route_map_rule_cmd route_set_local_pref_cmd =
959{
960 "local-preference",
961 route_set_local_pref,
962 route_set_local_pref_compile,
963 route_set_local_pref_free,
964};
965
966/* `set weight WEIGHT' */
967
968/* Set weight. */
paul94f2b392005-06-28 12:44:16 +0000969static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000970route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
971 void *object)
972{
973 u_int32_t *weight;
974 struct bgp_info *bgp_info;
975
976 if (type == RMAP_BGP)
977 {
978 /* Fetch routemap's rule information. */
979 weight = rule;
980 bgp_info = object;
981
982 /* Set weight value. */
Paul Jakmafb982c22007-05-04 20:15:47 +0000983 if (*weight)
984 (bgp_attr_extra_get (bgp_info->attr))->weight = *weight;
985 else if (bgp_info->attr->extra)
986 bgp_info->attr->extra->weight = 0;
paul718e3742002-12-13 20:15:29 +0000987 }
988
989 return RMAP_OKAY;
990}
991
992/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +0000993static void *
paulfd79ac92004-10-13 05:06:08 +0000994route_set_weight_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000995{
paulfd79ac92004-10-13 05:06:08 +0000996 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +0000997 u_int32_t *weight;
998 char *endptr = NULL;
999
1000 /* Local preference value shoud be integer. */
1001 if (! all_digit (arg))
1002 return NULL;
1003
paulfd79ac92004-10-13 05:06:08 +00001004
1005 tmp = strtoul (arg, &endptr, 10);
1006 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
1007 return NULL;
1008
paul718e3742002-12-13 20:15:29 +00001009 weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +00001010
1011 if (weight == NULL)
1012 return weight;
1013
1014 *weight = tmp;
1015
paul718e3742002-12-13 20:15:29 +00001016 return weight;
1017}
1018
1019/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +00001020static void
paul718e3742002-12-13 20:15:29 +00001021route_set_weight_free (void *rule)
1022{
1023 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1024}
1025
1026/* Set local preference rule structure. */
1027struct route_map_rule_cmd route_set_weight_cmd =
1028{
1029 "weight",
1030 route_set_weight,
1031 route_set_weight_compile,
1032 route_set_weight_free,
1033};
1034
1035/* `set metric METRIC' */
1036
1037/* Set metric to attribute. */
paul94f2b392005-06-28 12:44:16 +00001038static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001039route_set_metric (void *rule, struct prefix *prefix,
1040 route_map_object_t type, void *object)
1041{
1042 char *metric;
1043 u_int32_t metric_val;
1044 struct bgp_info *bgp_info;
1045
1046 if (type == RMAP_BGP)
1047 {
1048 /* Fetch routemap's rule information. */
1049 metric = rule;
1050 bgp_info = object;
1051
1052 if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
1053 bgp_info->attr->med = 0;
1054 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
1055
1056 if (all_digit (metric))
1057 {
1058 metric_val = strtoul (metric, (char **)NULL, 10);
1059 bgp_info->attr->med = metric_val;
1060 }
1061 else
1062 {
1063 metric_val = strtoul (metric+1, (char **)NULL, 10);
1064
1065 if (strncmp (metric, "+", 1) == 0)
1066 {
paul3b424972003-10-13 09:47:32 +00001067 if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2)
1068 bgp_info->attr->med = BGP_MED_MAX - 1;
paul718e3742002-12-13 20:15:29 +00001069 else
paul537d8ea2003-08-27 06:45:32 +00001070 bgp_info->attr->med += metric_val;
paul718e3742002-12-13 20:15:29 +00001071 }
1072 else if (strncmp (metric, "-", 1) == 0)
1073 {
paul537d8ea2003-08-27 06:45:32 +00001074 if (bgp_info->attr->med <= metric_val)
1075 bgp_info->attr->med = 0;
paul718e3742002-12-13 20:15:29 +00001076 else
paul537d8ea2003-08-27 06:45:32 +00001077 bgp_info->attr->med -= metric_val;
paul718e3742002-12-13 20:15:29 +00001078 }
1079 }
1080 }
1081 return RMAP_OKAY;
1082}
1083
1084/* set metric compilation. */
paul94f2b392005-06-28 12:44:16 +00001085static void *
paulfd79ac92004-10-13 05:06:08 +00001086route_set_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001087{
1088 u_int32_t metric;
paul94f2b392005-06-28 12:44:16 +00001089 unsigned long larg;
paul718e3742002-12-13 20:15:29 +00001090 char *endptr = NULL;
1091
1092 if (all_digit (arg))
1093 {
1094 /* set metric value check*/
paul94f2b392005-06-28 12:44:16 +00001095 larg = strtoul (arg, &endptr, 10);
1096 if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001097 return NULL;
paul94f2b392005-06-28 12:44:16 +00001098 metric = larg;
paul718e3742002-12-13 20:15:29 +00001099 }
1100 else
1101 {
1102 /* set metric +/-value check */
1103 if ((strncmp (arg, "+", 1) != 0
1104 && strncmp (arg, "-", 1) != 0)
1105 || (! all_digit (arg+1)))
1106 return NULL;
1107
paul94f2b392005-06-28 12:44:16 +00001108 larg = strtoul (arg+1, &endptr, 10);
1109 if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001110 return NULL;
paul94f2b392005-06-28 12:44:16 +00001111 metric = larg;
paul718e3742002-12-13 20:15:29 +00001112 }
1113
1114 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1115}
1116
1117/* Free route map's compiled `set metric' value. */
paul94f2b392005-06-28 12:44:16 +00001118static void
paul718e3742002-12-13 20:15:29 +00001119route_set_metric_free (void *rule)
1120{
1121 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1122}
1123
1124/* Set metric rule structure. */
1125struct route_map_rule_cmd route_set_metric_cmd =
1126{
1127 "metric",
1128 route_set_metric,
1129 route_set_metric_compile,
1130 route_set_metric_free,
1131};
1132
1133/* `set as-path prepend ASPATH' */
1134
1135/* For AS path prepend mechanism. */
paul94f2b392005-06-28 12:44:16 +00001136static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001137route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1138{
1139 struct aspath *aspath;
1140 struct aspath *new;
1141 struct bgp_info *binfo;
1142
1143 if (type == RMAP_BGP)
1144 {
1145 aspath = rule;
1146 binfo = object;
1147
1148 if (binfo->attr->aspath->refcnt)
1149 new = aspath_dup (binfo->attr->aspath);
1150 else
1151 new = binfo->attr->aspath;
1152
1153 aspath_prepend (aspath, new);
1154 binfo->attr->aspath = new;
1155 }
1156
1157 return RMAP_OKAY;
1158}
1159
1160/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001161static void *
paulfd79ac92004-10-13 05:06:08 +00001162route_set_aspath_prepend_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001163{
1164 struct aspath *aspath;
1165
1166 aspath = aspath_str2aspath (arg);
1167 if (! aspath)
1168 return NULL;
1169 return aspath;
1170}
1171
1172/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001173static void
paul718e3742002-12-13 20:15:29 +00001174route_set_aspath_prepend_free (void *rule)
1175{
1176 struct aspath *aspath = rule;
1177 aspath_free (aspath);
1178}
1179
1180/* Set metric rule structure. */
1181struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1182{
1183 "as-path prepend",
1184 route_set_aspath_prepend,
1185 route_set_aspath_prepend_compile,
1186 route_set_aspath_prepend_free,
1187};
1188
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001189/* `set as-path exclude ASn' */
1190
1191/* For ASN exclude mechanism.
1192 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1193 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1194 */
1195static route_map_result_t
1196route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
1197{
1198 struct aspath * new_path, * exclude_path;
1199 struct bgp_info *binfo;
1200
1201 if (type == RMAP_BGP)
1202 {
1203 exclude_path = rule;
1204 binfo = object;
1205 if (binfo->attr->aspath->refcnt)
1206 new_path = aspath_dup (binfo->attr->aspath);
1207 else
1208 new_path = binfo->attr->aspath;
1209 binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
1210 }
1211 return RMAP_OKAY;
1212}
1213
1214/* FIXME: consider using route_set_aspath_prepend_compile() and
1215 * route_set_aspath_prepend_free(), which two below function are
1216 * exact clones of.
1217 */
1218
1219/* Compile function for as-path exclude. */
1220static void *
1221route_set_aspath_exclude_compile (const char *arg)
1222{
1223 struct aspath *aspath;
1224
1225 aspath = aspath_str2aspath (arg);
1226 if (! aspath)
1227 return NULL;
1228 return aspath;
1229}
1230
1231static void
1232route_set_aspath_exclude_free (void *rule)
1233{
1234 struct aspath *aspath = rule;
1235 aspath_free (aspath);
1236}
1237
1238/* Set ASn exlude rule structure. */
1239struct route_map_rule_cmd route_set_aspath_exclude_cmd =
1240{
1241 "as-path exclude",
1242 route_set_aspath_exclude,
1243 route_set_aspath_exclude_compile,
1244 route_set_aspath_exclude_free,
1245};
1246
paul718e3742002-12-13 20:15:29 +00001247/* `set community COMMUNITY' */
1248struct rmap_com_set
1249{
1250 struct community *com;
1251 int additive;
1252 int none;
1253};
1254
1255/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001256static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001257route_set_community (void *rule, struct prefix *prefix,
1258 route_map_object_t type, void *object)
1259{
1260 struct rmap_com_set *rcs;
1261 struct bgp_info *binfo;
1262 struct attr *attr;
1263 struct community *new = NULL;
1264 struct community *old;
1265 struct community *merge;
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001266
paul718e3742002-12-13 20:15:29 +00001267 if (type == RMAP_BGP)
1268 {
1269 rcs = rule;
1270 binfo = object;
1271 attr = binfo->attr;
1272 old = attr->community;
1273
1274 /* "none" case. */
1275 if (rcs->none)
1276 {
1277 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1278 attr->community = NULL;
1279 return RMAP_OKAY;
1280 }
1281
1282 /* "additive" case. */
1283 if (rcs->additive && old)
1284 {
1285 merge = community_merge (community_dup (old), rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001286
1287 /* HACK: if the old community is not intern'd,
1288 * we should free it here, or all reference to it may be lost.
1289 * Really need to cleanup attribute caching sometime.
1290 */
1291 if (old->refcnt == 0)
1292 community_free (old);
paul718e3742002-12-13 20:15:29 +00001293 new = community_uniq_sort (merge);
1294 community_free (merge);
1295 }
1296 else
1297 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001298
1299 /* will be interned by caller if required */
Michael Lambert2c9fd7e2010-07-24 12:44:07 -04001300 attr->community = community_intern (new);
hasso70601e02005-05-27 03:26:57 +00001301
paul718e3742002-12-13 20:15:29 +00001302 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1303 }
1304
1305 return RMAP_OKAY;
1306}
1307
1308/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001309static void *
paulfd79ac92004-10-13 05:06:08 +00001310route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001311{
1312 struct rmap_com_set *rcs;
1313 struct community *com = NULL;
Michael Lambert2c9fd7e2010-07-24 12:44:07 -04001314 struct community *comint;
paul718e3742002-12-13 20:15:29 +00001315 char *sp;
1316 int additive = 0;
1317 int none = 0;
1318
1319 if (strcmp (arg, "none") == 0)
1320 none = 1;
1321 else
1322 {
1323 sp = strstr (arg, "additive");
1324
1325 if (sp && sp > arg)
1326 {
1327 /* "additive" keyworkd is included. */
1328 additive = 1;
1329 *(sp - 1) = '\0';
1330 }
1331
1332 com = community_str2com (arg);
1333
1334 if (additive)
1335 *(sp - 1) = ' ';
1336
1337 if (! com)
1338 return NULL;
1339 }
1340
Michael Lambert2c9fd7e2010-07-24 12:44:07 -04001341 comint = community_intern (com);
Stephen Hemminger393deb92008-08-18 14:13:29 -07001342 rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
Michael Lambert2c9fd7e2010-07-24 12:44:07 -04001343 rcs->com = comint;
paul718e3742002-12-13 20:15:29 +00001344 rcs->additive = additive;
1345 rcs->none = none;
1346
1347 return rcs;
1348}
1349
1350/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001351static void
paul718e3742002-12-13 20:15:29 +00001352route_set_community_free (void *rule)
1353{
1354 struct rmap_com_set *rcs = rule;
1355
1356 if (rcs->com)
1357 community_free (rcs->com);
1358 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1359}
1360
1361/* Set community rule structure. */
1362struct route_map_rule_cmd route_set_community_cmd =
1363{
1364 "community",
1365 route_set_community,
1366 route_set_community_compile,
1367 route_set_community_free,
1368};
1369
hassofee6e4e2005-02-02 16:29:31 +00001370/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001371
1372/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001373static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001374route_set_community_delete (void *rule, struct prefix *prefix,
1375 route_map_object_t type, void *object)
1376{
1377 struct community_list *list;
1378 struct community *merge;
1379 struct community *new;
1380 struct community *old;
1381 struct bgp_info *binfo;
1382
1383 if (type == RMAP_BGP)
1384 {
1385 if (! rule)
1386 return RMAP_OKAY;
1387
1388 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001389 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001390 old = binfo->attr->community;
1391
1392 if (list && old)
1393 {
1394 merge = community_list_match_delete (community_dup (old), list);
1395 new = community_uniq_sort (merge);
1396 community_free (merge);
1397
1398 if (new->size == 0)
1399 {
1400 binfo->attr->community = NULL;
1401 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1402 community_free (new);
1403 }
1404 else
1405 {
Michael Lambert2c9fd7e2010-07-24 12:44:07 -04001406 binfo->attr->community = community_intern (new);
paul718e3742002-12-13 20:15:29 +00001407 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1408 }
1409 }
1410 }
1411
1412 return RMAP_OKAY;
1413}
1414
1415/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001416static void *
paulfd79ac92004-10-13 05:06:08 +00001417route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001418{
1419 char *p;
1420 char *str;
1421 int len;
1422
1423 p = strchr (arg, ' ');
1424 if (p)
1425 {
1426 len = p - arg;
1427 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1428 memcpy (str, arg, len);
1429 }
1430 else
1431 str = NULL;
1432
1433 return str;
1434}
1435
1436/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001437static void
paul718e3742002-12-13 20:15:29 +00001438route_set_community_delete_free (void *rule)
1439{
1440 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1441}
1442
1443/* Set community rule structure. */
1444struct route_map_rule_cmd route_set_community_delete_cmd =
1445{
1446 "comm-list",
1447 route_set_community_delete,
1448 route_set_community_delete_compile,
1449 route_set_community_delete_free,
1450};
1451
1452/* `set extcommunity rt COMMUNITY' */
1453
1454/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001455static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001456route_set_ecommunity_rt (void *rule, struct prefix *prefix,
1457 route_map_object_t type, void *object)
1458{
1459 struct ecommunity *ecom;
1460 struct ecommunity *new_ecom;
1461 struct ecommunity *old_ecom;
1462 struct bgp_info *bgp_info;
1463
1464 if (type == RMAP_BGP)
1465 {
1466 ecom = rule;
1467 bgp_info = object;
1468
1469 if (! ecom)
1470 return RMAP_OKAY;
1471
1472 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001473 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001474
1475 if (old_ecom)
1476 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1477 else
1478 new_ecom = ecommunity_dup (ecom);
1479
Paul Jakmafb982c22007-05-04 20:15:47 +00001480 bgp_info->attr->extra->ecommunity = new_ecom;
paul718e3742002-12-13 20:15:29 +00001481
hasso70601e02005-05-27 03:26:57 +00001482 if (old_ecom)
1483 ecommunity_free (old_ecom);
1484
paul718e3742002-12-13 20:15:29 +00001485 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1486 }
1487 return RMAP_OKAY;
1488}
1489
1490/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001491static void *
paulfd79ac92004-10-13 05:06:08 +00001492route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001493{
1494 struct ecommunity *ecom;
1495
1496 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1497 if (! ecom)
1498 return NULL;
1499 return ecom;
1500}
1501
1502/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001503static void
paul718e3742002-12-13 20:15:29 +00001504route_set_ecommunity_rt_free (void *rule)
1505{
1506 struct ecommunity *ecom = rule;
1507 ecommunity_free (ecom);
1508}
1509
1510/* Set community rule structure. */
1511struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1512{
1513 "extcommunity rt",
1514 route_set_ecommunity_rt,
1515 route_set_ecommunity_rt_compile,
1516 route_set_ecommunity_rt_free,
1517};
1518
1519/* `set extcommunity soo COMMUNITY' */
1520
1521/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001522static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001523route_set_ecommunity_soo (void *rule, struct prefix *prefix,
1524 route_map_object_t type, void *object)
1525{
1526 struct ecommunity *ecom;
1527 struct bgp_info *bgp_info;
1528
1529 if (type == RMAP_BGP)
1530 {
1531 ecom = rule;
1532 bgp_info = object;
1533
1534 if (! ecom)
1535 return RMAP_OKAY;
1536
1537 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
Paul Jakmafb982c22007-05-04 20:15:47 +00001538 (bgp_attr_extra_get (bgp_info->attr))->ecommunity = ecommunity_dup (ecom);
paul718e3742002-12-13 20:15:29 +00001539 }
1540 return RMAP_OKAY;
1541}
1542
1543/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001544static void *
paulfd79ac92004-10-13 05:06:08 +00001545route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001546{
1547 struct ecommunity *ecom;
1548
1549 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1550 if (! ecom)
1551 return NULL;
1552
1553 return ecom;
1554}
1555
1556/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001557static void
paul718e3742002-12-13 20:15:29 +00001558route_set_ecommunity_soo_free (void *rule)
1559{
1560 struct ecommunity *ecom = rule;
1561 ecommunity_free (ecom);
1562}
1563
1564/* Set community rule structure. */
1565struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1566{
1567 "extcommunity soo",
1568 route_set_ecommunity_soo,
1569 route_set_ecommunity_soo_compile,
1570 route_set_ecommunity_soo_free,
1571};
1572
1573/* `set origin ORIGIN' */
1574
1575/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001576static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001577route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1578{
1579 u_char *origin;
1580 struct bgp_info *bgp_info;
1581
1582 if (type == RMAP_BGP)
1583 {
1584 origin = rule;
1585 bgp_info = object;
1586
1587 bgp_info->attr->origin = *origin;
1588 }
1589
1590 return RMAP_OKAY;
1591}
1592
1593/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001594static void *
paulfd79ac92004-10-13 05:06:08 +00001595route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001596{
1597 u_char *origin;
1598
1599 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1600
1601 if (strcmp (arg, "igp") == 0)
1602 *origin = 0;
1603 else if (strcmp (arg, "egp") == 0)
1604 *origin = 1;
1605 else
1606 *origin = 2;
1607
1608 return origin;
1609}
1610
1611/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001612static void
paul718e3742002-12-13 20:15:29 +00001613route_set_origin_free (void *rule)
1614{
1615 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1616}
1617
1618/* Set metric rule structure. */
1619struct route_map_rule_cmd route_set_origin_cmd =
1620{
1621 "origin",
1622 route_set_origin,
1623 route_set_origin_compile,
1624 route_set_origin_free,
1625};
1626
1627/* `set atomic-aggregate' */
1628
1629/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001630static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001631route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1632 route_map_object_t type, void *object)
1633{
1634 struct bgp_info *bgp_info;
1635
1636 if (type == RMAP_BGP)
1637 {
1638 bgp_info = object;
1639 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1640 }
1641
1642 return RMAP_OKAY;
1643}
1644
1645/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001646static void *
paulfd79ac92004-10-13 05:06:08 +00001647route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001648{
1649 return (void *)1;
1650}
1651
1652/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001653static void
paul718e3742002-12-13 20:15:29 +00001654route_set_atomic_aggregate_free (void *rule)
1655{
1656 return;
1657}
1658
1659/* Set atomic aggregate rule structure. */
1660struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1661{
1662 "atomic-aggregate",
1663 route_set_atomic_aggregate,
1664 route_set_atomic_aggregate_compile,
1665 route_set_atomic_aggregate_free,
1666};
1667
1668/* `set aggregator as AS A.B.C.D' */
1669struct aggregator
1670{
1671 as_t as;
1672 struct in_addr address;
1673};
1674
paul94f2b392005-06-28 12:44:16 +00001675static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001676route_set_aggregator_as (void *rule, struct prefix *prefix,
1677 route_map_object_t type, void *object)
1678{
1679 struct bgp_info *bgp_info;
1680 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001681 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001682
1683 if (type == RMAP_BGP)
1684 {
1685 bgp_info = object;
1686 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001687 ae = bgp_attr_extra_get (bgp_info->attr);
1688
1689 ae->aggregator_as = aggregator->as;
1690 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001691 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1692 }
1693
1694 return RMAP_OKAY;
1695}
1696
paul94f2b392005-06-28 12:44:16 +00001697static void *
paulfd79ac92004-10-13 05:06:08 +00001698route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001699{
1700 struct aggregator *aggregator;
1701 char as[10];
1702 char address[20];
1703
Stephen Hemminger393deb92008-08-18 14:13:29 -07001704 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
paul718e3742002-12-13 20:15:29 +00001705 sscanf (arg, "%s %s", as, address);
1706
1707 aggregator->as = strtoul (as, NULL, 10);
1708 inet_aton (address, &aggregator->address);
1709
1710 return aggregator;
1711}
1712
paul94f2b392005-06-28 12:44:16 +00001713static void
paul718e3742002-12-13 20:15:29 +00001714route_set_aggregator_as_free (void *rule)
1715{
1716 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1717}
1718
1719struct route_map_rule_cmd route_set_aggregator_as_cmd =
1720{
1721 "aggregator as",
1722 route_set_aggregator_as,
1723 route_set_aggregator_as_compile,
1724 route_set_aggregator_as_free,
1725};
1726
1727#ifdef HAVE_IPV6
1728/* `match ipv6 address IP_ACCESS_LIST' */
1729
paul94f2b392005-06-28 12:44:16 +00001730static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001731route_match_ipv6_address (void *rule, struct prefix *prefix,
1732 route_map_object_t type, void *object)
1733{
1734 struct access_list *alist;
1735
1736 if (type == RMAP_BGP)
1737 {
1738 alist = access_list_lookup (AFI_IP6, (char *) rule);
1739 if (alist == NULL)
1740 return RMAP_NOMATCH;
1741
1742 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1743 RMAP_NOMATCH : RMAP_MATCH);
1744 }
1745 return RMAP_NOMATCH;
1746}
1747
paul94f2b392005-06-28 12:44:16 +00001748static void *
paulfd79ac92004-10-13 05:06:08 +00001749route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001750{
1751 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1752}
1753
paul94f2b392005-06-28 12:44:16 +00001754static void
paul718e3742002-12-13 20:15:29 +00001755route_match_ipv6_address_free (void *rule)
1756{
1757 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1758}
1759
1760/* Route map commands for ip address matching. */
1761struct route_map_rule_cmd route_match_ipv6_address_cmd =
1762{
1763 "ipv6 address",
1764 route_match_ipv6_address,
1765 route_match_ipv6_address_compile,
1766 route_match_ipv6_address_free
1767};
1768
1769/* `match ipv6 next-hop IP_ADDRESS' */
1770
paul94f2b392005-06-28 12:44:16 +00001771static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001772route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1773 route_map_object_t type, void *object)
1774{
1775 struct in6_addr *addr;
1776 struct bgp_info *bgp_info;
1777
1778 if (type == RMAP_BGP)
1779 {
1780 addr = rule;
1781 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001782
1783 if (!bgp_info->attr->extra)
1784 return RMAP_NOMATCH;
1785
1786 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, rule))
paul718e3742002-12-13 20:15:29 +00001787 return RMAP_MATCH;
1788
Paul Jakmafb982c22007-05-04 20:15:47 +00001789 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
1790 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, rule))
paul718e3742002-12-13 20:15:29 +00001791 return RMAP_MATCH;
1792
1793 return RMAP_NOMATCH;
1794 }
1795
1796 return RMAP_NOMATCH;
1797}
1798
paul94f2b392005-06-28 12:44:16 +00001799static void *
paulfd79ac92004-10-13 05:06:08 +00001800route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001801{
1802 struct in6_addr *address;
1803 int ret;
1804
1805 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1806
1807 ret = inet_pton (AF_INET6, arg, address);
1808 if (!ret)
1809 {
1810 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1811 return NULL;
1812 }
1813
1814 return address;
1815}
1816
paul94f2b392005-06-28 12:44:16 +00001817static void
paul718e3742002-12-13 20:15:29 +00001818route_match_ipv6_next_hop_free (void *rule)
1819{
1820 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1821}
1822
1823struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1824{
1825 "ipv6 next-hop",
1826 route_match_ipv6_next_hop,
1827 route_match_ipv6_next_hop_compile,
1828 route_match_ipv6_next_hop_free
1829};
1830
1831/* `match ipv6 address prefix-list PREFIX_LIST' */
1832
paul94f2b392005-06-28 12:44:16 +00001833static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001834route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1835 route_map_object_t type, void *object)
1836{
1837 struct prefix_list *plist;
1838
1839 if (type == RMAP_BGP)
1840 {
1841 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1842 if (plist == NULL)
1843 return RMAP_NOMATCH;
1844
1845 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1846 RMAP_NOMATCH : RMAP_MATCH);
1847 }
1848 return RMAP_NOMATCH;
1849}
1850
paul94f2b392005-06-28 12:44:16 +00001851static void *
paulfd79ac92004-10-13 05:06:08 +00001852route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001853{
1854 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1855}
1856
paul94f2b392005-06-28 12:44:16 +00001857static void
paul718e3742002-12-13 20:15:29 +00001858route_match_ipv6_address_prefix_list_free (void *rule)
1859{
1860 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1861}
1862
1863struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1864{
1865 "ipv6 address prefix-list",
1866 route_match_ipv6_address_prefix_list,
1867 route_match_ipv6_address_prefix_list_compile,
1868 route_match_ipv6_address_prefix_list_free
1869};
1870
1871/* `set ipv6 nexthop global IP_ADDRESS' */
1872
1873/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001874static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001875route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1876 route_map_object_t type, void *object)
1877{
1878 struct in6_addr *address;
1879 struct bgp_info *bgp_info;
1880
1881 if (type == RMAP_BGP)
1882 {
1883 /* Fetch routemap's rule information. */
1884 address = rule;
1885 bgp_info = object;
1886
1887 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001888 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00001889
1890 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001891 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1892 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00001893 }
1894
1895 return RMAP_OKAY;
1896}
1897
1898/* Route map `ip next-hop' compile function. Given string is converted
1899 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001900static void *
paulfd79ac92004-10-13 05:06:08 +00001901route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001902{
1903 int ret;
1904 struct in6_addr *address;
1905
1906 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1907
1908 ret = inet_pton (AF_INET6, arg, address);
1909
1910 if (ret == 0)
1911 {
1912 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1913 return NULL;
1914 }
1915
1916 return address;
1917}
1918
1919/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00001920static void
paul718e3742002-12-13 20:15:29 +00001921route_set_ipv6_nexthop_global_free (void *rule)
1922{
1923 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1924}
1925
1926/* Route map commands for ip nexthop set. */
1927struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
1928{
1929 "ipv6 next-hop global",
1930 route_set_ipv6_nexthop_global,
1931 route_set_ipv6_nexthop_global_compile,
1932 route_set_ipv6_nexthop_global_free
1933};
1934
1935/* `set ipv6 nexthop local IP_ADDRESS' */
1936
1937/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001938static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001939route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
1940 route_map_object_t type, void *object)
1941{
1942 struct in6_addr *address;
1943 struct bgp_info *bgp_info;
1944
1945 if (type == RMAP_BGP)
1946 {
1947 /* Fetch routemap's rule information. */
1948 address = rule;
1949 bgp_info = object;
1950
1951 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001952 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00001953
1954 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001955 if (bgp_info->attr->extra->mp_nexthop_len != 32)
1956 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00001957 }
1958
1959 return RMAP_OKAY;
1960}
1961
1962/* Route map `ip nexthop' compile function. Given string is converted
1963 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001964static void *
paulfd79ac92004-10-13 05:06:08 +00001965route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001966{
1967 int ret;
1968 struct in6_addr *address;
1969
1970 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1971
1972 ret = inet_pton (AF_INET6, arg, address);
1973
1974 if (ret == 0)
1975 {
1976 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1977 return NULL;
1978 }
1979
1980 return address;
1981}
1982
1983/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00001984static void
paul718e3742002-12-13 20:15:29 +00001985route_set_ipv6_nexthop_local_free (void *rule)
1986{
1987 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1988}
1989
1990/* Route map commands for ip nexthop set. */
1991struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
1992{
1993 "ipv6 next-hop local",
1994 route_set_ipv6_nexthop_local,
1995 route_set_ipv6_nexthop_local_compile,
1996 route_set_ipv6_nexthop_local_free
1997};
1998#endif /* HAVE_IPV6 */
1999
2000/* `set vpnv4 nexthop A.B.C.D' */
2001
paul94f2b392005-06-28 12:44:16 +00002002static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002003route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2004 route_map_object_t type, void *object)
2005{
2006 struct in_addr *address;
2007 struct bgp_info *bgp_info;
2008
2009 if (type == RMAP_BGP)
2010 {
2011 /* Fetch routemap's rule information. */
2012 address = rule;
2013 bgp_info = object;
2014
2015 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002016 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
paul718e3742002-12-13 20:15:29 +00002017 }
2018
2019 return RMAP_OKAY;
2020}
2021
paul94f2b392005-06-28 12:44:16 +00002022static void *
paulfd79ac92004-10-13 05:06:08 +00002023route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002024{
2025 int ret;
2026 struct in_addr *address;
2027
2028 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2029
2030 ret = inet_aton (arg, address);
2031
2032 if (ret == 0)
2033 {
2034 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2035 return NULL;
2036 }
2037
2038 return address;
2039}
2040
paul94f2b392005-06-28 12:44:16 +00002041static void
paul718e3742002-12-13 20:15:29 +00002042route_set_vpnv4_nexthop_free (void *rule)
2043{
2044 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2045}
2046
2047/* Route map commands for ip nexthop set. */
2048struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2049{
2050 "vpnv4 next-hop",
2051 route_set_vpnv4_nexthop,
2052 route_set_vpnv4_nexthop_compile,
2053 route_set_vpnv4_nexthop_free
2054};
2055
2056/* `set originator-id' */
2057
2058/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002059static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002060route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2061{
2062 struct in_addr *address;
2063 struct bgp_info *bgp_info;
2064
2065 if (type == RMAP_BGP)
2066 {
2067 address = rule;
2068 bgp_info = object;
2069
2070 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002071 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002072 }
2073
2074 return RMAP_OKAY;
2075}
2076
2077/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002078static void *
paulfd79ac92004-10-13 05:06:08 +00002079route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002080{
2081 int ret;
2082 struct in_addr *address;
2083
2084 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2085
2086 ret = inet_aton (arg, address);
2087
2088 if (ret == 0)
2089 {
2090 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2091 return NULL;
2092 }
2093
2094 return address;
2095}
2096
2097/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002098static void
paul718e3742002-12-13 20:15:29 +00002099route_set_originator_id_free (void *rule)
2100{
2101 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2102}
2103
2104/* Set metric rule structure. */
2105struct route_map_rule_cmd route_set_originator_id_cmd =
2106{
2107 "originator-id",
2108 route_set_originator_id,
2109 route_set_originator_id_compile,
2110 route_set_originator_id_free,
2111};
2112
2113/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002114static int
paul718e3742002-12-13 20:15:29 +00002115bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002116 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002117{
2118 int ret;
2119
2120 ret = route_map_add_match (index, command, arg);
2121 if (ret)
2122 {
2123 switch (ret)
2124 {
2125 case RMAP_RULE_MISSING:
2126 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2127 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002128 case RMAP_COMPILE_ERROR:
2129 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2130 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002131 }
2132 }
2133 return CMD_SUCCESS;
2134}
2135
2136/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002137static int
paul718e3742002-12-13 20:15:29 +00002138bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002139 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002140{
2141 int ret;
2142
2143 ret = route_map_delete_match (index, command, arg);
2144 if (ret)
2145 {
2146 switch (ret)
2147 {
2148 case RMAP_RULE_MISSING:
2149 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2150 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002151 case RMAP_COMPILE_ERROR:
2152 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2153 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002154 }
2155 }
2156 return CMD_SUCCESS;
2157}
2158
2159/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002160static int
paul718e3742002-12-13 20:15:29 +00002161bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002162 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002163{
2164 int ret;
2165
2166 ret = route_map_add_set (index, command, arg);
2167 if (ret)
2168 {
2169 switch (ret)
2170 {
2171 case RMAP_RULE_MISSING:
2172 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2173 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002174 case RMAP_COMPILE_ERROR:
2175 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2176 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002177 }
2178 }
2179 return CMD_SUCCESS;
2180}
2181
2182/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002183static int
paul718e3742002-12-13 20:15:29 +00002184bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002185 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002186{
2187 int ret;
2188
2189 ret = route_map_delete_set (index, command, arg);
2190 if (ret)
2191 {
2192 switch (ret)
2193 {
2194 case RMAP_RULE_MISSING:
2195 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2196 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002197 case RMAP_COMPILE_ERROR:
2198 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2199 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002200 }
2201 }
2202 return CMD_SUCCESS;
2203}
2204
2205/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002206static void
paulfd79ac92004-10-13 05:06:08 +00002207bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002208{
2209 int i;
2210 afi_t afi;
2211 safi_t safi;
2212 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002213 struct listnode *node, *nnode;
2214 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002215 struct bgp *bgp;
2216 struct peer *peer;
2217 struct peer_group *group;
2218 struct bgp_filter *filter;
2219 struct bgp_node *bn;
2220 struct bgp_static *bgp_static;
2221
2222 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002223 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002224 {
paul1eb8ef22005-04-07 07:30:20 +00002225 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002226 {
2227 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2228 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2229 {
2230 filter = &peer->filter[afi][safi];
2231
paulfee0f4c2004-09-13 05:12:46 +00002232 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002233 {
2234 if (filter->map[direct].name)
2235 filter->map[direct].map =
2236 route_map_lookup_by_name (filter->map[direct].name);
2237 else
2238 filter->map[direct].map = NULL;
2239 }
2240
2241 if (filter->usmap.name)
2242 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2243 else
2244 filter->usmap.map = NULL;
2245 }
2246 }
paul1eb8ef22005-04-07 07:30:20 +00002247 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002248 {
2249 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2250 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2251 {
2252 filter = &group->conf->filter[afi][safi];
2253
paulfee0f4c2004-09-13 05:12:46 +00002254 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002255 {
2256 if (filter->map[direct].name)
2257 filter->map[direct].map =
2258 route_map_lookup_by_name (filter->map[direct].name);
2259 else
2260 filter->map[direct].map = NULL;
2261 }
2262
2263 if (filter->usmap.name)
2264 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2265 else
2266 filter->usmap.map = NULL;
2267 }
2268 }
2269 }
2270
2271 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002272 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002273 {
paul1eb8ef22005-04-07 07:30:20 +00002274 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002275 {
2276 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2277 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2278 {
2279 if (peer->default_rmap[afi][safi].name)
2280 peer->default_rmap[afi][safi].map =
2281 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2282 else
2283 peer->default_rmap[afi][safi].map = NULL;
2284 }
2285 }
2286 }
2287
2288 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002289 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002290 {
2291 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2292 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2293 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2294 bn = bgp_route_next (bn))
2295 if ((bgp_static = bn->info) != NULL)
2296 {
2297 if (bgp_static->rmap.name)
2298 bgp_static->rmap.map =
2299 route_map_lookup_by_name (bgp_static->rmap.name);
2300 else
2301 bgp_static->rmap.map = NULL;
2302 }
2303 }
2304
2305 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002306 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002307 {
2308 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2309 {
2310 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2311 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2312 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2313#ifdef HAVE_IPV6
2314 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2315 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2316 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2317#endif /* HAVE_IPV6 */
2318 }
2319 }
2320}
2321
paulfee0f4c2004-09-13 05:12:46 +00002322DEFUN (match_peer,
2323 match_peer_cmd,
2324 "match peer (A.B.C.D|X:X::X:X)",
2325 MATCH_STR
2326 "Match peer address\n"
2327 "IPv6 address of peer\n"
2328 "IP address of peer\n")
2329{
2330 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2331}
2332
2333DEFUN (match_peer_local,
2334 match_peer_local_cmd,
2335 "match peer local",
2336 MATCH_STR
2337 "Match peer address\n"
2338 "Static or Redistributed routes\n")
2339{
2340 return bgp_route_match_add (vty, vty->index, "peer", NULL);
2341}
2342
2343DEFUN (no_match_peer,
2344 no_match_peer_cmd,
2345 "no match peer",
2346 NO_STR
2347 MATCH_STR
2348 "Match peer address\n")
2349{
2350 if (argc == 0)
2351 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2352
2353 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2354}
2355
2356ALIAS (no_match_peer,
2357 no_match_peer_val_cmd,
2358 "no match peer (A.B.C.D|X:X::X:X)",
2359 NO_STR
2360 MATCH_STR
2361 "Match peer address\n"
2362 "IPv6 address of peer\n"
2363 "IP address of peer\n")
2364
2365ALIAS (no_match_peer,
2366 no_match_peer_local_cmd,
2367 "no match peer local",
2368 NO_STR
2369 MATCH_STR
2370 "Match peer address\n"
2371 "Static or Redistributed routes\n")
2372
paul718e3742002-12-13 20:15:29 +00002373DEFUN (match_ip_address,
2374 match_ip_address_cmd,
2375 "match ip address (<1-199>|<1300-2699>|WORD)",
2376 MATCH_STR
2377 IP_STR
2378 "Match address of route\n"
2379 "IP access-list number\n"
2380 "IP access-list number (expanded range)\n"
2381 "IP Access-list name\n")
2382{
2383 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2384}
2385
2386DEFUN (no_match_ip_address,
2387 no_match_ip_address_cmd,
2388 "no match ip address",
2389 NO_STR
2390 MATCH_STR
2391 IP_STR
2392 "Match address of route\n")
2393{
2394 if (argc == 0)
2395 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2396
2397 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2398}
2399
2400ALIAS (no_match_ip_address,
2401 no_match_ip_address_val_cmd,
2402 "no match ip address (<1-199>|<1300-2699>|WORD)",
2403 NO_STR
2404 MATCH_STR
2405 IP_STR
2406 "Match address of route\n"
2407 "IP access-list number\n"
2408 "IP access-list number (expanded range)\n"
2409 "IP Access-list name\n")
2410
2411DEFUN (match_ip_next_hop,
2412 match_ip_next_hop_cmd,
2413 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2414 MATCH_STR
2415 IP_STR
2416 "Match next-hop address of route\n"
2417 "IP access-list number\n"
2418 "IP access-list number (expanded range)\n"
2419 "IP Access-list name\n")
2420{
2421 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2422}
2423
2424DEFUN (no_match_ip_next_hop,
2425 no_match_ip_next_hop_cmd,
2426 "no match ip next-hop",
2427 NO_STR
2428 MATCH_STR
2429 IP_STR
2430 "Match next-hop address of route\n")
2431{
2432 if (argc == 0)
2433 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2434
2435 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2436}
2437
2438ALIAS (no_match_ip_next_hop,
2439 no_match_ip_next_hop_val_cmd,
2440 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2441 NO_STR
2442 MATCH_STR
2443 IP_STR
2444 "Match next-hop address of route\n"
2445 "IP access-list number\n"
2446 "IP access-list number (expanded range)\n"
2447 "IP Access-list name\n")
2448
hassoc1643bb2005-02-02 16:43:17 +00002449DEFUN (match_ip_route_source,
2450 match_ip_route_source_cmd,
2451 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2452 MATCH_STR
2453 IP_STR
2454 "Match advertising source address of route\n"
2455 "IP access-list number\n"
2456 "IP access-list number (expanded range)\n"
2457 "IP standard access-list name\n")
2458{
2459 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2460}
2461
2462DEFUN (no_match_ip_route_source,
2463 no_match_ip_route_source_cmd,
2464 "no match ip route-source",
2465 NO_STR
2466 MATCH_STR
2467 IP_STR
2468 "Match advertising source address of route\n")
2469{
2470 if (argc == 0)
2471 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2472
2473 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2474}
2475
2476ALIAS (no_match_ip_route_source,
2477 no_match_ip_route_source_val_cmd,
2478 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2479 NO_STR
2480 MATCH_STR
2481 IP_STR
2482 "Match advertising source address of route\n"
2483 "IP access-list number\n"
2484 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002485 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002486
paul718e3742002-12-13 20:15:29 +00002487DEFUN (match_ip_address_prefix_list,
2488 match_ip_address_prefix_list_cmd,
2489 "match ip address prefix-list WORD",
2490 MATCH_STR
2491 IP_STR
2492 "Match address of route\n"
2493 "Match entries of prefix-lists\n"
2494 "IP prefix-list name\n")
2495{
2496 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2497}
2498
2499DEFUN (no_match_ip_address_prefix_list,
2500 no_match_ip_address_prefix_list_cmd,
2501 "no match ip address prefix-list",
2502 NO_STR
2503 MATCH_STR
2504 IP_STR
2505 "Match address of route\n"
2506 "Match entries of prefix-lists\n")
2507{
2508 if (argc == 0)
2509 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2510
2511 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2512}
2513
2514ALIAS (no_match_ip_address_prefix_list,
2515 no_match_ip_address_prefix_list_val_cmd,
2516 "no match ip address prefix-list WORD",
2517 NO_STR
2518 MATCH_STR
2519 IP_STR
2520 "Match address of route\n"
2521 "Match entries of prefix-lists\n"
2522 "IP prefix-list name\n")
2523
2524DEFUN (match_ip_next_hop_prefix_list,
2525 match_ip_next_hop_prefix_list_cmd,
2526 "match ip next-hop prefix-list WORD",
2527 MATCH_STR
2528 IP_STR
2529 "Match next-hop address of route\n"
2530 "Match entries of prefix-lists\n"
2531 "IP prefix-list name\n")
2532{
2533 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2534}
2535
2536DEFUN (no_match_ip_next_hop_prefix_list,
2537 no_match_ip_next_hop_prefix_list_cmd,
2538 "no match ip next-hop prefix-list",
2539 NO_STR
2540 MATCH_STR
2541 IP_STR
2542 "Match next-hop address of route\n"
2543 "Match entries of prefix-lists\n")
2544{
2545 if (argc == 0)
2546 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2547
2548 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2549}
2550
2551ALIAS (no_match_ip_next_hop_prefix_list,
2552 no_match_ip_next_hop_prefix_list_val_cmd,
2553 "no match ip next-hop prefix-list WORD",
2554 NO_STR
2555 MATCH_STR
2556 IP_STR
2557 "Match next-hop address of route\n"
2558 "Match entries of prefix-lists\n"
2559 "IP prefix-list name\n")
2560
hassoc1643bb2005-02-02 16:43:17 +00002561DEFUN (match_ip_route_source_prefix_list,
2562 match_ip_route_source_prefix_list_cmd,
2563 "match ip route-source prefix-list WORD",
2564 MATCH_STR
2565 IP_STR
2566 "Match advertising source address of route\n"
2567 "Match entries of prefix-lists\n"
2568 "IP prefix-list name\n")
2569{
2570 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2571}
2572
2573DEFUN (no_match_ip_route_source_prefix_list,
2574 no_match_ip_route_source_prefix_list_cmd,
2575 "no match ip route-source prefix-list",
2576 NO_STR
2577 MATCH_STR
2578 IP_STR
2579 "Match advertising source address of route\n"
2580 "Match entries of prefix-lists\n")
2581{
2582 if (argc == 0)
2583 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2584
2585 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2586}
2587
2588ALIAS (no_match_ip_route_source_prefix_list,
2589 no_match_ip_route_source_prefix_list_val_cmd,
2590 "no match ip route-source prefix-list WORD",
2591 NO_STR
2592 MATCH_STR
2593 IP_STR
2594 "Match advertising source address of route\n"
2595 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002596 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002597
paul718e3742002-12-13 20:15:29 +00002598DEFUN (match_metric,
2599 match_metric_cmd,
2600 "match metric <0-4294967295>",
2601 MATCH_STR
2602 "Match metric of route\n"
2603 "Metric value\n")
2604{
2605 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2606}
2607
2608DEFUN (no_match_metric,
2609 no_match_metric_cmd,
2610 "no match metric",
2611 NO_STR
2612 MATCH_STR
2613 "Match metric of route\n")
2614{
2615 if (argc == 0)
2616 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2617
2618 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2619}
2620
2621ALIAS (no_match_metric,
2622 no_match_metric_val_cmd,
2623 "no match metric <0-4294967295>",
2624 NO_STR
2625 MATCH_STR
2626 "Match metric of route\n"
2627 "Metric value\n")
2628
2629DEFUN (match_community,
2630 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002631 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002632 MATCH_STR
2633 "Match BGP community list\n"
2634 "Community-list number (standard)\n"
2635 "Community-list number (expanded)\n"
2636 "Community-list name\n")
2637{
2638 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2639}
2640
2641DEFUN (match_community_exact,
2642 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002643 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002644 MATCH_STR
2645 "Match BGP community list\n"
2646 "Community-list number (standard)\n"
2647 "Community-list number (expanded)\n"
2648 "Community-list name\n"
2649 "Do exact matching of communities\n")
2650{
2651 int ret;
2652 char *argstr;
2653
2654 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2655 strlen (argv[0]) + strlen ("exact-match") + 2);
2656
2657 sprintf (argstr, "%s exact-match", argv[0]);
2658
2659 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2660
2661 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2662
2663 return ret;
2664}
2665
2666DEFUN (no_match_community,
2667 no_match_community_cmd,
2668 "no match community",
2669 NO_STR
2670 MATCH_STR
2671 "Match BGP community list\n")
2672{
2673 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2674}
2675
2676ALIAS (no_match_community,
2677 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002678 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002679 NO_STR
2680 MATCH_STR
2681 "Match BGP community list\n"
2682 "Community-list number (standard)\n"
2683 "Community-list number (expanded)\n"
2684 "Community-list name\n")
2685
2686ALIAS (no_match_community,
2687 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002688 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002689 NO_STR
2690 MATCH_STR
2691 "Match BGP community list\n"
2692 "Community-list number (standard)\n"
2693 "Community-list number (expanded)\n"
2694 "Community-list name\n"
2695 "Do exact matching of communities\n")
2696
paul73ffb252003-04-19 15:49:49 +00002697DEFUN (match_ecommunity,
2698 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002699 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002700 MATCH_STR
2701 "Match BGP/VPN extended community list\n"
2702 "Extended community-list number (standard)\n"
2703 "Extended community-list number (expanded)\n"
2704 "Extended community-list name\n")
2705{
2706 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2707}
2708
2709DEFUN (no_match_ecommunity,
2710 no_match_ecommunity_cmd,
2711 "no match extcommunity",
2712 NO_STR
2713 MATCH_STR
2714 "Match BGP/VPN extended community list\n")
2715{
2716 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2717}
2718
2719ALIAS (no_match_ecommunity,
2720 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002721 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002722 NO_STR
2723 MATCH_STR
2724 "Match BGP/VPN extended community list\n"
2725 "Extended community-list number (standard)\n"
2726 "Extended community-list number (expanded)\n"
2727 "Extended community-list name\n")
2728
paul718e3742002-12-13 20:15:29 +00002729DEFUN (match_aspath,
2730 match_aspath_cmd,
2731 "match as-path WORD",
2732 MATCH_STR
2733 "Match BGP AS path list\n"
2734 "AS path access-list name\n")
2735{
2736 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2737}
2738
2739DEFUN (no_match_aspath,
2740 no_match_aspath_cmd,
2741 "no match as-path",
2742 NO_STR
2743 MATCH_STR
2744 "Match BGP AS path list\n")
2745{
2746 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2747}
2748
2749ALIAS (no_match_aspath,
2750 no_match_aspath_val_cmd,
2751 "no match as-path WORD",
2752 NO_STR
2753 MATCH_STR
2754 "Match BGP AS path list\n"
2755 "AS path access-list name\n")
2756
2757DEFUN (match_origin,
2758 match_origin_cmd,
2759 "match origin (egp|igp|incomplete)",
2760 MATCH_STR
2761 "BGP origin code\n"
2762 "remote EGP\n"
2763 "local IGP\n"
2764 "unknown heritage\n")
2765{
2766 if (strncmp (argv[0], "igp", 2) == 0)
2767 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2768 if (strncmp (argv[0], "egp", 1) == 0)
2769 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2770 if (strncmp (argv[0], "incomplete", 2) == 0)
2771 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2772
2773 return CMD_WARNING;
2774}
2775
2776DEFUN (no_match_origin,
2777 no_match_origin_cmd,
2778 "no match origin",
2779 NO_STR
2780 MATCH_STR
2781 "BGP origin code\n")
2782{
2783 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2784}
2785
2786ALIAS (no_match_origin,
2787 no_match_origin_val_cmd,
2788 "no match origin (egp|igp|incomplete)",
2789 NO_STR
2790 MATCH_STR
2791 "BGP origin code\n"
2792 "remote EGP\n"
2793 "local IGP\n"
2794 "unknown heritage\n")
2795
2796DEFUN (set_ip_nexthop,
2797 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002798 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002799 SET_STR
2800 IP_STR
2801 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002802 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002803{
2804 union sockunion su;
2805 int ret;
2806
2807 ret = str2sockunion (argv[0], &su);
2808 if (ret < 0)
2809 {
2810 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2811 return CMD_WARNING;
2812 }
2813
2814 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2815}
2816
paulaf5cd0a2003-11-02 07:24:40 +00002817DEFUN (set_ip_nexthop_peer,
2818 set_ip_nexthop_peer_cmd,
2819 "set ip next-hop peer-address",
2820 SET_STR
2821 IP_STR
2822 "Next hop address\n"
2823 "Use peer address (for BGP only)\n")
2824{
2825 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2826}
2827
paul94f2b392005-06-28 12:44:16 +00002828DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00002829 no_set_ip_nexthop_peer_cmd,
2830 "no set ip next-hop peer-address",
2831 NO_STR
2832 SET_STR
2833 IP_STR
2834 "Next hop address\n"
2835 "Use peer address (for BGP only)\n")
2836{
2837 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2838}
2839
2840
paul718e3742002-12-13 20:15:29 +00002841DEFUN (no_set_ip_nexthop,
2842 no_set_ip_nexthop_cmd,
2843 "no set ip next-hop",
2844 NO_STR
2845 SET_STR
paul718e3742002-12-13 20:15:29 +00002846 "Next hop address\n")
2847{
paulaf5cd0a2003-11-02 07:24:40 +00002848 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002849 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2850
2851 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2852}
2853
2854ALIAS (no_set_ip_nexthop,
2855 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002856 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002857 NO_STR
2858 SET_STR
2859 IP_STR
2860 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002861 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002862
2863DEFUN (set_metric,
2864 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002865 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002866 SET_STR
2867 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002868 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002869{
2870 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2871}
2872
paul73ffb252003-04-19 15:49:49 +00002873ALIAS (set_metric,
2874 set_metric_addsub_cmd,
2875 "set metric <+/-metric>",
2876 SET_STR
2877 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00002878 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00002879
paul718e3742002-12-13 20:15:29 +00002880DEFUN (no_set_metric,
2881 no_set_metric_cmd,
2882 "no set metric",
2883 NO_STR
2884 SET_STR
2885 "Metric value for destination routing protocol\n")
2886{
2887 if (argc == 0)
2888 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
2889
2890 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
2891}
2892
2893ALIAS (no_set_metric,
2894 no_set_metric_val_cmd,
2895 "no set metric <0-4294967295>",
2896 NO_STR
2897 SET_STR
2898 "Metric value for destination routing protocol\n"
2899 "Metric value\n")
2900
2901DEFUN (set_local_pref,
2902 set_local_pref_cmd,
2903 "set local-preference <0-4294967295>",
2904 SET_STR
2905 "BGP local preference path attribute\n"
2906 "Preference value\n")
2907{
2908 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
2909}
2910
2911DEFUN (no_set_local_pref,
2912 no_set_local_pref_cmd,
2913 "no set local-preference",
2914 NO_STR
2915 SET_STR
2916 "BGP local preference path attribute\n")
2917{
2918 if (argc == 0)
2919 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
2920
2921 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
2922}
2923
2924ALIAS (no_set_local_pref,
2925 no_set_local_pref_val_cmd,
2926 "no set local-preference <0-4294967295>",
2927 NO_STR
2928 SET_STR
2929 "BGP local preference path attribute\n"
2930 "Preference value\n")
2931
2932DEFUN (set_weight,
2933 set_weight_cmd,
2934 "set weight <0-4294967295>",
2935 SET_STR
2936 "BGP weight for routing table\n"
2937 "Weight value\n")
2938{
2939 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
2940}
2941
2942DEFUN (no_set_weight,
2943 no_set_weight_cmd,
2944 "no set weight",
2945 NO_STR
2946 SET_STR
2947 "BGP weight for routing table\n")
2948{
2949 if (argc == 0)
2950 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
2951
2952 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
2953}
2954
2955ALIAS (no_set_weight,
2956 no_set_weight_val_cmd,
2957 "no set weight <0-4294967295>",
2958 NO_STR
2959 SET_STR
2960 "BGP weight for routing table\n"
2961 "Weight value\n")
2962
2963DEFUN (set_aspath_prepend,
2964 set_aspath_prepend_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04002965 "set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00002966 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00002967 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00002968 "Prepend to the as-path\n"
2969 "AS number\n")
2970{
2971 int ret;
2972 char *str;
2973
2974 str = argv_concat (argv, argc, 0);
2975 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
2976 XFREE (MTYPE_TMP, str);
2977
2978 return ret;
2979}
2980
2981DEFUN (no_set_aspath_prepend,
2982 no_set_aspath_prepend_cmd,
2983 "no set as-path prepend",
2984 NO_STR
2985 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00002986 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00002987 "Prepend to the as-path\n")
2988{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00002989 int ret;
2990 char *str;
2991
2992 if (argc == 0)
2993 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
2994
2995 str = argv_concat (argv, argc, 0);
2996 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
2997 XFREE (MTYPE_TMP, str);
2998 return ret;
paul718e3742002-12-13 20:15:29 +00002999}
3000
3001ALIAS (no_set_aspath_prepend,
3002 no_set_aspath_prepend_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003003 "no set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003004 NO_STR
3005 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003006 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003007 "Prepend to the as-path\n"
3008 "AS number\n")
3009
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003010DEFUN (set_aspath_exclude,
3011 set_aspath_exclude_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003012 "set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003013 SET_STR
3014 "Transform BGP AS-path attribute\n"
3015 "Exclude from the as-path\n"
3016 "AS number\n")
3017{
3018 int ret;
3019 char *str;
3020
3021 str = argv_concat (argv, argc, 0);
3022 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3023 XFREE (MTYPE_TMP, str);
3024 return ret;
3025}
3026
3027DEFUN (no_set_aspath_exclude,
3028 no_set_aspath_exclude_cmd,
3029 "no set as-path exclude",
3030 NO_STR
3031 SET_STR
3032 "Transform BGP AS_PATH attribute\n"
3033 "Exclude from the as-path\n")
3034{
3035 int ret;
3036 char *str;
3037
3038 if (argc == 0)
3039 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3040
3041 str = argv_concat (argv, argc, 0);
3042 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3043 XFREE (MTYPE_TMP, str);
3044 return ret;
3045}
3046
3047ALIAS (no_set_aspath_exclude,
3048 no_set_aspath_exclude_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003049 "no set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003050 NO_STR
3051 SET_STR
3052 "Transform BGP AS_PATH attribute\n"
3053 "Exclude from the as-path\n"
3054 "AS number\n")
3055
paul718e3742002-12-13 20:15:29 +00003056DEFUN (set_community,
3057 set_community_cmd,
3058 "set community .AA:NN",
3059 SET_STR
3060 "BGP community attribute\n"
3061 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3062{
3063 int i;
3064 int first = 0;
3065 int additive = 0;
3066 struct buffer *b;
3067 struct community *com = NULL;
3068 char *str;
3069 char *argstr;
3070 int ret;
3071
3072 b = buffer_new (1024);
3073
3074 for (i = 0; i < argc; i++)
3075 {
3076 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3077 {
3078 additive = 1;
3079 continue;
3080 }
3081
3082 if (first)
3083 buffer_putc (b, ' ');
3084 else
3085 first = 1;
3086
3087 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3088 {
3089 buffer_putstr (b, "internet");
3090 continue;
3091 }
3092 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3093 {
3094 buffer_putstr (b, "local-AS");
3095 continue;
3096 }
3097 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3098 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3099 {
3100 buffer_putstr (b, "no-advertise");
3101 continue;
3102 }
3103 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3104 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3105 {
3106 buffer_putstr (b, "no-export");
3107 continue;
3108 }
3109 buffer_putstr (b, argv[i]);
3110 }
3111 buffer_putc (b, '\0');
3112
3113 /* Fetch result string then compile it to communities attribute. */
3114 str = buffer_getstr (b);
3115 buffer_free (b);
3116
3117 if (str)
3118 {
3119 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003120 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003121 }
3122
3123 /* Can't compile user input into communities attribute. */
3124 if (! com)
3125 {
3126 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3127 return CMD_WARNING;
3128 }
3129
3130 /* Set communites attribute string. */
3131 str = community_str (com);
3132
3133 if (additive)
3134 {
3135 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3136 strcpy (argstr, str);
3137 strcpy (argstr + strlen (str), " additive");
3138 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3139 XFREE (MTYPE_TMP, argstr);
3140 }
3141 else
3142 ret = bgp_route_set_add (vty, vty->index, "community", str);
3143
3144 community_free (com);
3145
3146 return ret;
3147}
3148
3149DEFUN (set_community_none,
3150 set_community_none_cmd,
3151 "set community none",
3152 SET_STR
3153 "BGP community attribute\n"
3154 "No community attribute\n")
3155{
3156 return bgp_route_set_add (vty, vty->index, "community", "none");
3157}
3158
3159DEFUN (no_set_community,
3160 no_set_community_cmd,
3161 "no set community",
3162 NO_STR
3163 SET_STR
3164 "BGP community attribute\n")
3165{
3166 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3167}
3168
3169ALIAS (no_set_community,
3170 no_set_community_val_cmd,
3171 "no set community .AA:NN",
3172 NO_STR
3173 SET_STR
3174 "BGP community attribute\n"
3175 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3176
3177ALIAS (no_set_community,
3178 no_set_community_none_cmd,
3179 "no set community none",
3180 NO_STR
3181 SET_STR
3182 "BGP community attribute\n"
3183 "No community attribute\n")
3184
3185DEFUN (set_community_delete,
3186 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003187 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003188 SET_STR
3189 "set BGP community list (for deletion)\n"
3190 "Community-list number (standard)\n"
3191 "Communitly-list number (expanded)\n"
3192 "Community-list name\n"
3193 "Delete matching communities\n")
3194{
3195 char *str;
3196
3197 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3198 strcpy (str, argv[0]);
3199 strcpy (str + strlen (argv[0]), " delete");
3200
3201 bgp_route_set_add (vty, vty->index, "comm-list", str);
3202
3203 XFREE (MTYPE_TMP, str);
3204 return CMD_SUCCESS;
3205}
3206
3207DEFUN (no_set_community_delete,
3208 no_set_community_delete_cmd,
3209 "no set comm-list",
3210 NO_STR
3211 SET_STR
3212 "set BGP community list (for deletion)\n")
3213{
3214 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3215}
3216
3217ALIAS (no_set_community_delete,
3218 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003219 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003220 NO_STR
3221 SET_STR
3222 "set BGP community list (for deletion)\n"
3223 "Community-list number (standard)\n"
3224 "Communitly-list number (expanded)\n"
3225 "Community-list name\n"
3226 "Delete matching communities\n")
3227
3228DEFUN (set_ecommunity_rt,
3229 set_ecommunity_rt_cmd,
3230 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3231 SET_STR
3232 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003233 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003234 "VPN extended community\n")
3235{
3236 int ret;
3237 char *str;
3238
3239 str = argv_concat (argv, argc, 0);
3240 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3241 XFREE (MTYPE_TMP, str);
3242
3243 return ret;
3244}
3245
3246DEFUN (no_set_ecommunity_rt,
3247 no_set_ecommunity_rt_cmd,
3248 "no set extcommunity rt",
3249 NO_STR
3250 SET_STR
3251 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003252 "Route Target extended community\n")
paul718e3742002-12-13 20:15:29 +00003253{
3254 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3255}
3256
3257ALIAS (no_set_ecommunity_rt,
3258 no_set_ecommunity_rt_val_cmd,
3259 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3260 NO_STR
3261 SET_STR
3262 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003263 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003264 "VPN extended community\n")
3265
3266DEFUN (set_ecommunity_soo,
3267 set_ecommunity_soo_cmd,
3268 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3269 SET_STR
3270 "BGP extended community attribute\n"
3271 "Site-of-Origin extended community\n"
3272 "VPN extended community\n")
3273{
3274 int ret;
3275 char *str;
3276
3277 str = argv_concat (argv, argc, 0);
3278 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3279 XFREE (MTYPE_TMP, str);
3280 return ret;
3281}
3282
3283DEFUN (no_set_ecommunity_soo,
3284 no_set_ecommunity_soo_cmd,
3285 "no set extcommunity soo",
3286 NO_STR
3287 SET_STR
3288 "BGP extended community attribute\n"
3289 "Site-of-Origin extended community\n")
3290{
3291 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3292}
3293
3294ALIAS (no_set_ecommunity_soo,
3295 no_set_ecommunity_soo_val_cmd,
3296 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3297 NO_STR
3298 SET_STR
3299 "BGP extended community attribute\n"
3300 "Site-of-Origin extended community\n"
3301 "VPN extended community\n")
3302
3303DEFUN (set_origin,
3304 set_origin_cmd,
3305 "set origin (egp|igp|incomplete)",
3306 SET_STR
3307 "BGP origin code\n"
3308 "remote EGP\n"
3309 "local IGP\n"
3310 "unknown heritage\n")
3311{
3312 if (strncmp (argv[0], "igp", 2) == 0)
3313 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3314 if (strncmp (argv[0], "egp", 1) == 0)
3315 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3316 if (strncmp (argv[0], "incomplete", 2) == 0)
3317 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3318
3319 return CMD_WARNING;
3320}
3321
3322DEFUN (no_set_origin,
3323 no_set_origin_cmd,
3324 "no set origin",
3325 NO_STR
3326 SET_STR
3327 "BGP origin code\n")
3328{
3329 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3330}
3331
3332ALIAS (no_set_origin,
3333 no_set_origin_val_cmd,
3334 "no set origin (egp|igp|incomplete)",
3335 NO_STR
3336 SET_STR
3337 "BGP origin code\n"
3338 "remote EGP\n"
3339 "local IGP\n"
3340 "unknown heritage\n")
3341
3342DEFUN (set_atomic_aggregate,
3343 set_atomic_aggregate_cmd,
3344 "set atomic-aggregate",
3345 SET_STR
3346 "BGP atomic aggregate attribute\n" )
3347{
3348 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3349}
3350
3351DEFUN (no_set_atomic_aggregate,
3352 no_set_atomic_aggregate_cmd,
3353 "no set atomic-aggregate",
3354 NO_STR
3355 SET_STR
3356 "BGP atomic aggregate attribute\n" )
3357{
3358 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3359}
3360
3361DEFUN (set_aggregator_as,
3362 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003363 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003364 SET_STR
3365 "BGP aggregator attribute\n"
3366 "AS number of aggregator\n"
3367 "AS number\n"
3368 "IP address of aggregator\n")
3369{
3370 int ret;
3371 as_t as;
3372 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003373 char *argstr;
3374
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003375 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003376
paul718e3742002-12-13 20:15:29 +00003377 ret = inet_aton (argv[1], &address);
3378 if (ret == 0)
3379 {
3380 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3381 return CMD_WARNING;
3382 }
3383
3384 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3385 strlen (argv[0]) + strlen (argv[1]) + 2);
3386
3387 sprintf (argstr, "%s %s", argv[0], argv[1]);
3388
3389 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3390
3391 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3392
3393 return ret;
3394}
3395
3396DEFUN (no_set_aggregator_as,
3397 no_set_aggregator_as_cmd,
3398 "no set aggregator as",
3399 NO_STR
3400 SET_STR
3401 "BGP aggregator attribute\n"
3402 "AS number of aggregator\n")
3403{
3404 int ret;
3405 as_t as;
3406 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003407 char *argstr;
3408
3409 if (argv == 0)
3410 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3411
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003412 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003413
3414 ret = inet_aton (argv[1], &address);
3415 if (ret == 0)
3416 {
3417 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3418 return CMD_WARNING;
3419 }
3420
3421 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3422 strlen (argv[0]) + strlen (argv[1]) + 2);
3423
3424 sprintf (argstr, "%s %s", argv[0], argv[1]);
3425
3426 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3427
3428 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3429
3430 return ret;
3431}
3432
3433ALIAS (no_set_aggregator_as,
3434 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003435 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003436 NO_STR
3437 SET_STR
3438 "BGP aggregator attribute\n"
3439 "AS number of aggregator\n"
3440 "AS number\n"
3441 "IP address of aggregator\n")
3442
3443
3444#ifdef HAVE_IPV6
3445DEFUN (match_ipv6_address,
3446 match_ipv6_address_cmd,
3447 "match ipv6 address WORD",
3448 MATCH_STR
3449 IPV6_STR
3450 "Match IPv6 address of route\n"
3451 "IPv6 access-list name\n")
3452{
3453 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3454}
3455
3456DEFUN (no_match_ipv6_address,
3457 no_match_ipv6_address_cmd,
3458 "no match ipv6 address WORD",
3459 NO_STR
3460 MATCH_STR
3461 IPV6_STR
3462 "Match IPv6 address of route\n"
3463 "IPv6 access-list name\n")
3464{
3465 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3466}
3467
3468DEFUN (match_ipv6_next_hop,
3469 match_ipv6_next_hop_cmd,
3470 "match ipv6 next-hop X:X::X:X",
3471 MATCH_STR
3472 IPV6_STR
3473 "Match IPv6 next-hop address of route\n"
3474 "IPv6 address of next hop\n")
3475{
3476 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3477}
3478
3479DEFUN (no_match_ipv6_next_hop,
3480 no_match_ipv6_next_hop_cmd,
3481 "no match ipv6 next-hop X:X::X:X",
3482 NO_STR
3483 MATCH_STR
3484 IPV6_STR
3485 "Match IPv6 next-hop address of route\n"
3486 "IPv6 address of next hop\n")
3487{
3488 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3489}
3490
3491DEFUN (match_ipv6_address_prefix_list,
3492 match_ipv6_address_prefix_list_cmd,
3493 "match ipv6 address prefix-list WORD",
3494 MATCH_STR
3495 IPV6_STR
3496 "Match address of route\n"
3497 "Match entries of prefix-lists\n"
3498 "IP prefix-list name\n")
3499{
3500 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3501}
3502
3503DEFUN (no_match_ipv6_address_prefix_list,
3504 no_match_ipv6_address_prefix_list_cmd,
3505 "no match ipv6 address prefix-list WORD",
3506 NO_STR
3507 MATCH_STR
3508 IPV6_STR
3509 "Match address of route\n"
3510 "Match entries of prefix-lists\n"
3511 "IP prefix-list name\n")
3512{
3513 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3514}
3515
3516DEFUN (set_ipv6_nexthop_global,
3517 set_ipv6_nexthop_global_cmd,
3518 "set ipv6 next-hop global X:X::X:X",
3519 SET_STR
3520 IPV6_STR
3521 "IPv6 next-hop address\n"
3522 "IPv6 global address\n"
3523 "IPv6 address of next hop\n")
3524{
3525 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3526}
3527
3528DEFUN (no_set_ipv6_nexthop_global,
3529 no_set_ipv6_nexthop_global_cmd,
3530 "no set ipv6 next-hop global",
3531 NO_STR
3532 SET_STR
3533 IPV6_STR
3534 "IPv6 next-hop address\n"
3535 "IPv6 global address\n")
3536{
3537 if (argc == 0)
3538 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3539
3540 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3541}
3542
3543ALIAS (no_set_ipv6_nexthop_global,
3544 no_set_ipv6_nexthop_global_val_cmd,
3545 "no set ipv6 next-hop global X:X::X:X",
3546 NO_STR
3547 SET_STR
3548 IPV6_STR
3549 "IPv6 next-hop address\n"
3550 "IPv6 global address\n"
3551 "IPv6 address of next hop\n")
3552
3553DEFUN (set_ipv6_nexthop_local,
3554 set_ipv6_nexthop_local_cmd,
3555 "set ipv6 next-hop local X:X::X:X",
3556 SET_STR
3557 IPV6_STR
3558 "IPv6 next-hop address\n"
3559 "IPv6 local address\n"
3560 "IPv6 address of next hop\n")
3561{
3562 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3563}
3564
3565DEFUN (no_set_ipv6_nexthop_local,
3566 no_set_ipv6_nexthop_local_cmd,
3567 "no set ipv6 next-hop local",
3568 NO_STR
3569 SET_STR
3570 IPV6_STR
3571 "IPv6 next-hop address\n"
3572 "IPv6 local address\n")
3573{
3574 if (argc == 0)
3575 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3576
3577 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3578}
3579
3580ALIAS (no_set_ipv6_nexthop_local,
3581 no_set_ipv6_nexthop_local_val_cmd,
3582 "no set ipv6 next-hop local X:X::X:X",
3583 NO_STR
3584 SET_STR
3585 IPV6_STR
3586 "IPv6 next-hop address\n"
3587 "IPv6 local address\n"
3588 "IPv6 address of next hop\n")
3589#endif /* HAVE_IPV6 */
3590
3591DEFUN (set_vpnv4_nexthop,
3592 set_vpnv4_nexthop_cmd,
3593 "set vpnv4 next-hop A.B.C.D",
3594 SET_STR
3595 "VPNv4 information\n"
3596 "VPNv4 next-hop address\n"
3597 "IP address of next hop\n")
3598{
3599 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3600}
3601
3602DEFUN (no_set_vpnv4_nexthop,
3603 no_set_vpnv4_nexthop_cmd,
3604 "no set vpnv4 next-hop",
3605 NO_STR
3606 SET_STR
3607 "VPNv4 information\n"
3608 "VPNv4 next-hop address\n")
3609{
3610 if (argc == 0)
3611 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3612
3613 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3614}
3615
3616ALIAS (no_set_vpnv4_nexthop,
3617 no_set_vpnv4_nexthop_val_cmd,
3618 "no set vpnv4 next-hop A.B.C.D",
3619 NO_STR
3620 SET_STR
3621 "VPNv4 information\n"
3622 "VPNv4 next-hop address\n"
3623 "IP address of next hop\n")
3624
3625DEFUN (set_originator_id,
3626 set_originator_id_cmd,
3627 "set originator-id A.B.C.D",
3628 SET_STR
3629 "BGP originator ID attribute\n"
3630 "IP address of originator\n")
3631{
3632 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3633}
3634
3635DEFUN (no_set_originator_id,
3636 no_set_originator_id_cmd,
3637 "no set originator-id",
3638 NO_STR
3639 SET_STR
3640 "BGP originator ID attribute\n")
3641{
3642 if (argc == 0)
3643 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3644
3645 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3646}
3647
3648ALIAS (no_set_originator_id,
3649 no_set_originator_id_val_cmd,
3650 "no set originator-id A.B.C.D",
3651 NO_STR
3652 SET_STR
3653 "BGP originator ID attribute\n"
3654 "IP address of originator\n")
3655
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003656DEFUN_DEPRECATED (set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003657 set_pathlimit_ttl_cmd,
3658 "set pathlimit ttl <1-255>",
3659 SET_STR
3660 "BGP AS-Pathlimit attribute\n"
3661 "Set AS-Path Hop-count TTL\n")
3662{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003663 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003664}
3665
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003666DEFUN_DEPRECATED (no_set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003667 no_set_pathlimit_ttl_cmd,
3668 "no set pathlimit ttl",
3669 NO_STR
3670 SET_STR
3671 "BGP AS-Pathlimit attribute\n"
3672 "Set AS-Path Hop-count TTL\n")
3673{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003674 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003675}
3676
3677ALIAS (no_set_pathlimit_ttl,
3678 no_set_pathlimit_ttl_val_cmd,
3679 "no set pathlimit ttl <1-255>",
3680 NO_STR
3681 MATCH_STR
3682 "BGP AS-Pathlimit attribute\n"
3683 "Set AS-Path Hop-count TTL\n")
3684
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003685DEFUN_DEPRECATED (match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003686 match_pathlimit_as_cmd,
3687 "match pathlimit as <1-65535>",
3688 MATCH_STR
3689 "BGP AS-Pathlimit attribute\n"
3690 "Match Pathlimit AS number\n")
3691{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003692 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003693}
3694
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003695DEFUN_DEPRECATED (no_match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003696 no_match_pathlimit_as_cmd,
3697 "no match pathlimit as",
3698 NO_STR
3699 MATCH_STR
3700 "BGP AS-Pathlimit attribute\n"
3701 "Match Pathlimit AS number\n")
3702{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003703 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003704}
3705
3706ALIAS (no_match_pathlimit_as,
3707 no_match_pathlimit_as_val_cmd,
3708 "no match pathlimit as <1-65535>",
3709 NO_STR
3710 MATCH_STR
3711 "BGP AS-Pathlimit attribute\n"
3712 "Match Pathlimit ASN\n")
3713
paul718e3742002-12-13 20:15:29 +00003714
3715/* Initialization of route map. */
3716void
paul94f2b392005-06-28 12:44:16 +00003717bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003718{
3719 route_map_init ();
3720 route_map_init_vty ();
3721 route_map_add_hook (bgp_route_map_update);
3722 route_map_delete_hook (bgp_route_map_update);
3723
paulfee0f4c2004-09-13 05:12:46 +00003724 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003725 route_map_install_match (&route_match_ip_address_cmd);
3726 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003727 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003728 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3729 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003730 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003731 route_map_install_match (&route_match_aspath_cmd);
3732 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003733 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003734 route_map_install_match (&route_match_metric_cmd);
3735 route_map_install_match (&route_match_origin_cmd);
3736
3737 route_map_install_set (&route_set_ip_nexthop_cmd);
3738 route_map_install_set (&route_set_local_pref_cmd);
3739 route_map_install_set (&route_set_weight_cmd);
3740 route_map_install_set (&route_set_metric_cmd);
3741 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003742 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003743 route_map_install_set (&route_set_origin_cmd);
3744 route_map_install_set (&route_set_atomic_aggregate_cmd);
3745 route_map_install_set (&route_set_aggregator_as_cmd);
3746 route_map_install_set (&route_set_community_cmd);
3747 route_map_install_set (&route_set_community_delete_cmd);
3748 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3749 route_map_install_set (&route_set_originator_id_cmd);
3750 route_map_install_set (&route_set_ecommunity_rt_cmd);
3751 route_map_install_set (&route_set_ecommunity_soo_cmd);
3752
paulfee0f4c2004-09-13 05:12:46 +00003753 install_element (RMAP_NODE, &match_peer_cmd);
3754 install_element (RMAP_NODE, &match_peer_local_cmd);
3755 install_element (RMAP_NODE, &no_match_peer_cmd);
3756 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3757 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003758 install_element (RMAP_NODE, &match_ip_address_cmd);
3759 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3760 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3761 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3762 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3763 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003764 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3765 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3766 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003767
3768 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3769 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3770 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3771 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3772 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3773 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003774 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3775 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3776 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003777
3778 install_element (RMAP_NODE, &match_aspath_cmd);
3779 install_element (RMAP_NODE, &no_match_aspath_cmd);
3780 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3781 install_element (RMAP_NODE, &match_metric_cmd);
3782 install_element (RMAP_NODE, &no_match_metric_cmd);
3783 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3784 install_element (RMAP_NODE, &match_community_cmd);
3785 install_element (RMAP_NODE, &match_community_exact_cmd);
3786 install_element (RMAP_NODE, &no_match_community_cmd);
3787 install_element (RMAP_NODE, &no_match_community_val_cmd);
3788 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003789 install_element (RMAP_NODE, &match_ecommunity_cmd);
3790 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3791 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003792 install_element (RMAP_NODE, &match_origin_cmd);
3793 install_element (RMAP_NODE, &no_match_origin_cmd);
3794 install_element (RMAP_NODE, &no_match_origin_val_cmd);
3795
3796 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003797 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003798 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3799 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3800 install_element (RMAP_NODE, &set_local_pref_cmd);
3801 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3802 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3803 install_element (RMAP_NODE, &set_weight_cmd);
3804 install_element (RMAP_NODE, &no_set_weight_cmd);
3805 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3806 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003807 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003808 install_element (RMAP_NODE, &no_set_metric_cmd);
3809 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3810 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003811 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003812 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3813 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003814 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
3815 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00003816 install_element (RMAP_NODE, &set_origin_cmd);
3817 install_element (RMAP_NODE, &no_set_origin_cmd);
3818 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3819 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3820 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3821 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3822 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3823 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3824 install_element (RMAP_NODE, &set_community_cmd);
3825 install_element (RMAP_NODE, &set_community_none_cmd);
3826 install_element (RMAP_NODE, &no_set_community_cmd);
3827 install_element (RMAP_NODE, &no_set_community_val_cmd);
3828 install_element (RMAP_NODE, &no_set_community_none_cmd);
3829 install_element (RMAP_NODE, &set_community_delete_cmd);
3830 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3831 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3832 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3833 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3834 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3835 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3836 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3837 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3838 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3839 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3840 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3841 install_element (RMAP_NODE, &set_originator_id_cmd);
3842 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3843 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3844
3845#ifdef HAVE_IPV6
3846 route_map_install_match (&route_match_ipv6_address_cmd);
3847 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3848 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3849 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3850 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Paul Jakma41367172007-08-06 15:24:51 +00003851
paul718e3742002-12-13 20:15:29 +00003852 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3853 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3854 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3855 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3856 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3857 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3858 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3859 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3860 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3861 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3862 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3863 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3864#endif /* HAVE_IPV6 */
Paul Jakma41367172007-08-06 15:24:51 +00003865
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003866 /* AS-Pathlimit: functionality removed, commands kept for
3867 * compatibility.
3868 */
Paul Jakma41367172007-08-06 15:24:51 +00003869 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
3870 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
3871 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
3872 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
3873 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
3874 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00003875}