blob: 05bc304bdef168d7af606c66943a093cdde0b9e5 [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};
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400793
794/* match probability { */
795
796static route_map_result_t
797route_match_probability (void *rule, struct prefix *prefix,
798 route_map_object_t type, void *object)
799{
800 long r;
801#if _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500
802 r = random();
803#else
804 r = (long) rand();
805#endif
806
807 switch (*(unsigned *) rule)
808 {
809 case 0: break;
810 case RAND_MAX: return RMAP_MATCH;
811 default:
812 if (r < *(unsigned *) rule)
813 {
814 return RMAP_MATCH;
815 }
816 }
817
818 return RMAP_NOMATCH;
819}
820
821static void *
822route_match_probability_compile (const char *arg)
823{
824 unsigned *lobule;
825 unsigned perc;
826
827#if _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500
828 srandom (time (NULL));
829#else
830 srand (time (NULL));
831#endif
832
833 perc = atoi (arg);
834 lobule = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (unsigned));
835
836 switch (perc)
837 {
838 case 0: *lobule = 0; break;
839 case 100: *lobule = RAND_MAX; break;
840 default: *lobule = RAND_MAX / 100 * perc;
841 }
842
843 return lobule;
844}
845
846static void
847route_match_probability_free (void *rule)
848{
849 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
850}
851
852struct route_map_rule_cmd route_match_probability_cmd =
853{
854 "probability",
855 route_match_probability,
856 route_match_probability_compile,
857 route_match_probability_free
858};
859
860/* } */
861
paul718e3742002-12-13 20:15:29 +0000862/* `set ip next-hop IP_ADDRESS' */
863
864/* Set nexthop to object. ojbect must be pointer to struct attr. */
paulac41b2a2003-08-12 05:32:27 +0000865struct rmap_ip_nexthop_set
866{
867 struct in_addr *address;
868 int peer_address;
869};
870
paul94f2b392005-06-28 12:44:16 +0000871static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000872route_set_ip_nexthop (void *rule, struct prefix *prefix,
873 route_map_object_t type, void *object)
874{
paulac41b2a2003-08-12 05:32:27 +0000875 struct rmap_ip_nexthop_set *rins = rule;
876 struct in_addr peer_address;
paul718e3742002-12-13 20:15:29 +0000877 struct bgp_info *bgp_info;
paulac41b2a2003-08-12 05:32:27 +0000878 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000879
880 if (type == RMAP_BGP)
881 {
paul718e3742002-12-13 20:15:29 +0000882 bgp_info = object;
paulac41b2a2003-08-12 05:32:27 +0000883 peer = bgp_info->peer;
884
885 if (rins->peer_address)
886 {
paulfee0f4c2004-09-13 05:12:46 +0000887 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
888 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
paulac41b2a2003-08-12 05:32:27 +0000889 && peer->su_remote
890 && sockunion_family (peer->su_remote) == AF_INET)
891 {
892 inet_aton (sockunion_su2str (peer->su_remote), &peer_address);
893 bgp_info->attr->nexthop = peer_address;
894 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
895 }
896 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
897 && peer->su_local
898 && sockunion_family (peer->su_local) == AF_INET)
899 {
900 inet_aton (sockunion_su2str (peer->su_local), &peer_address);
901 bgp_info->attr->nexthop = peer_address;
902 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
903 }
904 }
905 else
906 {
907 /* Set next hop value. */
908 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
909 bgp_info->attr->nexthop = *rins->address;
910 }
paul718e3742002-12-13 20:15:29 +0000911 }
912
913 return RMAP_OKAY;
914}
915
916/* Route map `ip nexthop' compile function. Given string is converted
917 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +0000918static void *
paulfd79ac92004-10-13 05:06:08 +0000919route_set_ip_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000920{
paulac41b2a2003-08-12 05:32:27 +0000921 struct rmap_ip_nexthop_set *rins;
922 struct in_addr *address = NULL;
923 int peer_address = 0;
paul718e3742002-12-13 20:15:29 +0000924 int ret;
paul718e3742002-12-13 20:15:29 +0000925
paulac41b2a2003-08-12 05:32:27 +0000926 if (strcmp (arg, "peer-address") == 0)
927 peer_address = 1;
928 else
paul718e3742002-12-13 20:15:29 +0000929 {
paulac41b2a2003-08-12 05:32:27 +0000930 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
931 ret = inet_aton (arg, address);
932
933 if (ret == 0)
934 {
935 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
936 return NULL;
937 }
paul718e3742002-12-13 20:15:29 +0000938 }
939
Stephen Hemminger393deb92008-08-18 14:13:29 -0700940 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
paulac41b2a2003-08-12 05:32:27 +0000941
942 rins->address = address;
943 rins->peer_address = peer_address;
944
945 return rins;
paul718e3742002-12-13 20:15:29 +0000946}
947
948/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +0000949static void
paul718e3742002-12-13 20:15:29 +0000950route_set_ip_nexthop_free (void *rule)
951{
paulac41b2a2003-08-12 05:32:27 +0000952 struct rmap_ip_nexthop_set *rins = rule;
953
954 if (rins->address)
955 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
956
957 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +0000958}
959
960/* Route map commands for ip nexthop set. */
961struct route_map_rule_cmd route_set_ip_nexthop_cmd =
962{
963 "ip next-hop",
964 route_set_ip_nexthop,
965 route_set_ip_nexthop_compile,
966 route_set_ip_nexthop_free
967};
968
969/* `set local-preference LOCAL_PREF' */
970
971/* Set local preference. */
paul94f2b392005-06-28 12:44:16 +0000972static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000973route_set_local_pref (void *rule, struct prefix *prefix,
974 route_map_object_t type, void *object)
975{
976 u_int32_t *local_pref;
977 struct bgp_info *bgp_info;
978
979 if (type == RMAP_BGP)
980 {
981 /* Fetch routemap's rule information. */
982 local_pref = rule;
983 bgp_info = object;
984
985 /* Set local preference value. */
986 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
987 bgp_info->attr->local_pref = *local_pref;
988 }
989
990 return RMAP_OKAY;
991}
992
993/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +0000994static void *
paulfd79ac92004-10-13 05:06:08 +0000995route_set_local_pref_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000996{
paulfd79ac92004-10-13 05:06:08 +0000997 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +0000998 u_int32_t *local_pref;
999 char *endptr = NULL;
1000
1001 /* Local preference value shoud be integer. */
1002 if (! all_digit (arg))
1003 return NULL;
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
1009 local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
1010
1011 if (!local_pref)
1012 return local_pref;
1013
1014 *local_pref = tmp;
1015
paul718e3742002-12-13 20:15:29 +00001016 return local_pref;
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_local_pref_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_local_pref_cmd =
1028{
1029 "local-preference",
1030 route_set_local_pref,
1031 route_set_local_pref_compile,
1032 route_set_local_pref_free,
1033};
1034
1035/* `set weight WEIGHT' */
1036
1037/* Set weight. */
paul94f2b392005-06-28 12:44:16 +00001038static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001039route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
1040 void *object)
1041{
1042 u_int32_t *weight;
1043 struct bgp_info *bgp_info;
1044
1045 if (type == RMAP_BGP)
1046 {
1047 /* Fetch routemap's rule information. */
1048 weight = rule;
1049 bgp_info = object;
1050
1051 /* Set weight value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001052 if (*weight)
1053 (bgp_attr_extra_get (bgp_info->attr))->weight = *weight;
1054 else if (bgp_info->attr->extra)
1055 bgp_info->attr->extra->weight = 0;
paul718e3742002-12-13 20:15:29 +00001056 }
1057
1058 return RMAP_OKAY;
1059}
1060
1061/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +00001062static void *
paulfd79ac92004-10-13 05:06:08 +00001063route_set_weight_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001064{
paulfd79ac92004-10-13 05:06:08 +00001065 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +00001066 u_int32_t *weight;
1067 char *endptr = NULL;
1068
1069 /* Local preference value shoud be integer. */
1070 if (! all_digit (arg))
1071 return NULL;
1072
paulfd79ac92004-10-13 05:06:08 +00001073
1074 tmp = strtoul (arg, &endptr, 10);
1075 if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX)
1076 return NULL;
1077
paul718e3742002-12-13 20:15:29 +00001078 weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +00001079
1080 if (weight == NULL)
1081 return weight;
1082
1083 *weight = tmp;
1084
paul718e3742002-12-13 20:15:29 +00001085 return weight;
1086}
1087
1088/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +00001089static void
paul718e3742002-12-13 20:15:29 +00001090route_set_weight_free (void *rule)
1091{
1092 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1093}
1094
1095/* Set local preference rule structure. */
1096struct route_map_rule_cmd route_set_weight_cmd =
1097{
1098 "weight",
1099 route_set_weight,
1100 route_set_weight_compile,
1101 route_set_weight_free,
1102};
1103
1104/* `set metric METRIC' */
1105
1106/* Set metric to attribute. */
paul94f2b392005-06-28 12:44:16 +00001107static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001108route_set_metric (void *rule, struct prefix *prefix,
1109 route_map_object_t type, void *object)
1110{
1111 char *metric;
1112 u_int32_t metric_val;
1113 struct bgp_info *bgp_info;
1114
1115 if (type == RMAP_BGP)
1116 {
1117 /* Fetch routemap's rule information. */
1118 metric = rule;
1119 bgp_info = object;
1120
1121 if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
1122 bgp_info->attr->med = 0;
1123 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
1124
1125 if (all_digit (metric))
1126 {
1127 metric_val = strtoul (metric, (char **)NULL, 10);
1128 bgp_info->attr->med = metric_val;
1129 }
1130 else
1131 {
1132 metric_val = strtoul (metric+1, (char **)NULL, 10);
1133
1134 if (strncmp (metric, "+", 1) == 0)
1135 {
paul3b424972003-10-13 09:47:32 +00001136 if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2)
1137 bgp_info->attr->med = BGP_MED_MAX - 1;
paul718e3742002-12-13 20:15:29 +00001138 else
paul537d8ea2003-08-27 06:45:32 +00001139 bgp_info->attr->med += metric_val;
paul718e3742002-12-13 20:15:29 +00001140 }
1141 else if (strncmp (metric, "-", 1) == 0)
1142 {
paul537d8ea2003-08-27 06:45:32 +00001143 if (bgp_info->attr->med <= metric_val)
1144 bgp_info->attr->med = 0;
paul718e3742002-12-13 20:15:29 +00001145 else
paul537d8ea2003-08-27 06:45:32 +00001146 bgp_info->attr->med -= metric_val;
paul718e3742002-12-13 20:15:29 +00001147 }
1148 }
1149 }
1150 return RMAP_OKAY;
1151}
1152
1153/* set metric compilation. */
paul94f2b392005-06-28 12:44:16 +00001154static void *
paulfd79ac92004-10-13 05:06:08 +00001155route_set_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001156{
1157 u_int32_t metric;
paul94f2b392005-06-28 12:44:16 +00001158 unsigned long larg;
paul718e3742002-12-13 20:15:29 +00001159 char *endptr = NULL;
1160
1161 if (all_digit (arg))
1162 {
1163 /* set metric value check*/
paul94f2b392005-06-28 12:44:16 +00001164 larg = strtoul (arg, &endptr, 10);
1165 if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001166 return NULL;
paul94f2b392005-06-28 12:44:16 +00001167 metric = larg;
paul718e3742002-12-13 20:15:29 +00001168 }
1169 else
1170 {
1171 /* set metric +/-value check */
1172 if ((strncmp (arg, "+", 1) != 0
1173 && strncmp (arg, "-", 1) != 0)
1174 || (! all_digit (arg+1)))
1175 return NULL;
1176
paul94f2b392005-06-28 12:44:16 +00001177 larg = strtoul (arg+1, &endptr, 10);
1178 if (*endptr != '\0' || larg == ULONG_MAX || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001179 return NULL;
paul94f2b392005-06-28 12:44:16 +00001180 metric = larg;
paul718e3742002-12-13 20:15:29 +00001181 }
1182
1183 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1184}
1185
1186/* Free route map's compiled `set metric' value. */
paul94f2b392005-06-28 12:44:16 +00001187static void
paul718e3742002-12-13 20:15:29 +00001188route_set_metric_free (void *rule)
1189{
1190 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1191}
1192
1193/* Set metric rule structure. */
1194struct route_map_rule_cmd route_set_metric_cmd =
1195{
1196 "metric",
1197 route_set_metric,
1198 route_set_metric_compile,
1199 route_set_metric_free,
1200};
1201
1202/* `set as-path prepend ASPATH' */
1203
1204/* For AS path prepend mechanism. */
paul94f2b392005-06-28 12:44:16 +00001205static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001206route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1207{
1208 struct aspath *aspath;
1209 struct aspath *new;
1210 struct bgp_info *binfo;
1211
1212 if (type == RMAP_BGP)
1213 {
1214 aspath = rule;
1215 binfo = object;
1216
1217 if (binfo->attr->aspath->refcnt)
1218 new = aspath_dup (binfo->attr->aspath);
1219 else
1220 new = binfo->attr->aspath;
1221
1222 aspath_prepend (aspath, new);
1223 binfo->attr->aspath = new;
1224 }
1225
1226 return RMAP_OKAY;
1227}
1228
1229/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001230static void *
paulfd79ac92004-10-13 05:06:08 +00001231route_set_aspath_prepend_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001232{
1233 struct aspath *aspath;
1234
1235 aspath = aspath_str2aspath (arg);
1236 if (! aspath)
1237 return NULL;
1238 return aspath;
1239}
1240
1241/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001242static void
paul718e3742002-12-13 20:15:29 +00001243route_set_aspath_prepend_free (void *rule)
1244{
1245 struct aspath *aspath = rule;
1246 aspath_free (aspath);
1247}
1248
1249/* Set metric rule structure. */
1250struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1251{
1252 "as-path prepend",
1253 route_set_aspath_prepend,
1254 route_set_aspath_prepend_compile,
1255 route_set_aspath_prepend_free,
1256};
1257
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001258/* `set as-path exclude ASn' */
1259
1260/* For ASN exclude mechanism.
1261 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1262 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1263 */
1264static route_map_result_t
1265route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
1266{
1267 struct aspath * new_path, * exclude_path;
1268 struct bgp_info *binfo;
1269
1270 if (type == RMAP_BGP)
1271 {
1272 exclude_path = rule;
1273 binfo = object;
1274 if (binfo->attr->aspath->refcnt)
1275 new_path = aspath_dup (binfo->attr->aspath);
1276 else
1277 new_path = binfo->attr->aspath;
1278 binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
1279 }
1280 return RMAP_OKAY;
1281}
1282
1283/* FIXME: consider using route_set_aspath_prepend_compile() and
1284 * route_set_aspath_prepend_free(), which two below function are
1285 * exact clones of.
1286 */
1287
1288/* Compile function for as-path exclude. */
1289static void *
1290route_set_aspath_exclude_compile (const char *arg)
1291{
1292 struct aspath *aspath;
1293
1294 aspath = aspath_str2aspath (arg);
1295 if (! aspath)
1296 return NULL;
1297 return aspath;
1298}
1299
1300static void
1301route_set_aspath_exclude_free (void *rule)
1302{
1303 struct aspath *aspath = rule;
1304 aspath_free (aspath);
1305}
1306
1307/* Set ASn exlude rule structure. */
1308struct route_map_rule_cmd route_set_aspath_exclude_cmd =
1309{
1310 "as-path exclude",
1311 route_set_aspath_exclude,
1312 route_set_aspath_exclude_compile,
1313 route_set_aspath_exclude_free,
1314};
1315
paul718e3742002-12-13 20:15:29 +00001316/* `set community COMMUNITY' */
1317struct rmap_com_set
1318{
1319 struct community *com;
1320 int additive;
1321 int none;
1322};
1323
1324/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001325static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001326route_set_community (void *rule, struct prefix *prefix,
1327 route_map_object_t type, void *object)
1328{
1329 struct rmap_com_set *rcs;
1330 struct bgp_info *binfo;
1331 struct attr *attr;
1332 struct community *new = NULL;
1333 struct community *old;
1334 struct community *merge;
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001335
paul718e3742002-12-13 20:15:29 +00001336 if (type == RMAP_BGP)
1337 {
1338 rcs = rule;
1339 binfo = object;
1340 attr = binfo->attr;
1341 old = attr->community;
1342
1343 /* "none" case. */
1344 if (rcs->none)
1345 {
1346 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1347 attr->community = NULL;
1348 return RMAP_OKAY;
1349 }
1350
1351 /* "additive" case. */
1352 if (rcs->additive && old)
1353 {
1354 merge = community_merge (community_dup (old), rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001355
1356 /* HACK: if the old community is not intern'd,
1357 * we should free it here, or all reference to it may be lost.
1358 * Really need to cleanup attribute caching sometime.
1359 */
1360 if (old->refcnt == 0)
1361 community_free (old);
paul718e3742002-12-13 20:15:29 +00001362 new = community_uniq_sort (merge);
1363 community_free (merge);
1364 }
1365 else
1366 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001367
1368 /* will be interned by caller if required */
Paul Jakma4a2035f2011-04-01 15:58:27 +01001369 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001370
paul718e3742002-12-13 20:15:29 +00001371 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1372 }
1373
1374 return RMAP_OKAY;
1375}
1376
1377/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001378static void *
paulfd79ac92004-10-13 05:06:08 +00001379route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001380{
1381 struct rmap_com_set *rcs;
1382 struct community *com = NULL;
1383 char *sp;
1384 int additive = 0;
1385 int none = 0;
1386
1387 if (strcmp (arg, "none") == 0)
1388 none = 1;
1389 else
1390 {
1391 sp = strstr (arg, "additive");
1392
1393 if (sp && sp > arg)
1394 {
1395 /* "additive" keyworkd is included. */
1396 additive = 1;
1397 *(sp - 1) = '\0';
1398 }
1399
1400 com = community_str2com (arg);
1401
1402 if (additive)
1403 *(sp - 1) = ' ';
1404
1405 if (! com)
1406 return NULL;
1407 }
1408
Stephen Hemminger393deb92008-08-18 14:13:29 -07001409 rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
Paul Jakma4a2035f2011-04-01 15:58:27 +01001410 rcs->com = com;
paul718e3742002-12-13 20:15:29 +00001411 rcs->additive = additive;
1412 rcs->none = none;
1413
1414 return rcs;
1415}
1416
1417/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001418static void
paul718e3742002-12-13 20:15:29 +00001419route_set_community_free (void *rule)
1420{
1421 struct rmap_com_set *rcs = rule;
1422
1423 if (rcs->com)
1424 community_free (rcs->com);
1425 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1426}
1427
1428/* Set community rule structure. */
1429struct route_map_rule_cmd route_set_community_cmd =
1430{
1431 "community",
1432 route_set_community,
1433 route_set_community_compile,
1434 route_set_community_free,
1435};
1436
hassofee6e4e2005-02-02 16:29:31 +00001437/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001438
1439/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001440static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001441route_set_community_delete (void *rule, struct prefix *prefix,
1442 route_map_object_t type, void *object)
1443{
1444 struct community_list *list;
1445 struct community *merge;
1446 struct community *new;
1447 struct community *old;
1448 struct bgp_info *binfo;
1449
1450 if (type == RMAP_BGP)
1451 {
1452 if (! rule)
1453 return RMAP_OKAY;
1454
1455 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001456 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001457 old = binfo->attr->community;
1458
1459 if (list && old)
1460 {
1461 merge = community_list_match_delete (community_dup (old), list);
1462 new = community_uniq_sort (merge);
1463 community_free (merge);
1464
Michael Lambert604a9b42010-09-13 11:48:11 -04001465 /* HACK: if the old community is not intern'd,
1466 * we should free it here, or all reference to it may be lost.
1467 * Really need to cleanup attribute caching sometime.
1468 */
1469 if (old->refcnt == 0)
1470 community_free (old);
1471
paul718e3742002-12-13 20:15:29 +00001472 if (new->size == 0)
1473 {
1474 binfo->attr->community = NULL;
1475 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1476 community_free (new);
1477 }
1478 else
1479 {
Paul Jakma4a2035f2011-04-01 15:58:27 +01001480 binfo->attr->community = new;
paul718e3742002-12-13 20:15:29 +00001481 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1482 }
1483 }
1484 }
1485
1486 return RMAP_OKAY;
1487}
1488
1489/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001490static void *
paulfd79ac92004-10-13 05:06:08 +00001491route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001492{
1493 char *p;
1494 char *str;
1495 int len;
1496
1497 p = strchr (arg, ' ');
1498 if (p)
1499 {
1500 len = p - arg;
1501 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1502 memcpy (str, arg, len);
1503 }
1504 else
1505 str = NULL;
1506
1507 return str;
1508}
1509
1510/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001511static void
paul718e3742002-12-13 20:15:29 +00001512route_set_community_delete_free (void *rule)
1513{
1514 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1515}
1516
1517/* Set community rule structure. */
1518struct route_map_rule_cmd route_set_community_delete_cmd =
1519{
1520 "comm-list",
1521 route_set_community_delete,
1522 route_set_community_delete_compile,
1523 route_set_community_delete_free,
1524};
1525
1526/* `set extcommunity rt COMMUNITY' */
1527
1528/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001529static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001530route_set_ecommunity_rt (void *rule, struct prefix *prefix,
1531 route_map_object_t type, void *object)
1532{
1533 struct ecommunity *ecom;
1534 struct ecommunity *new_ecom;
1535 struct ecommunity *old_ecom;
1536 struct bgp_info *bgp_info;
1537
1538 if (type == RMAP_BGP)
1539 {
1540 ecom = rule;
1541 bgp_info = object;
1542
1543 if (! ecom)
1544 return RMAP_OKAY;
1545
1546 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001547 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001548
1549 if (old_ecom)
1550 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1551 else
1552 new_ecom = ecommunity_dup (ecom);
1553
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001554 bgp_info->attr->extra->ecommunity = ecommunity_intern (new_ecom);
paul718e3742002-12-13 20:15:29 +00001555
hasso70601e02005-05-27 03:26:57 +00001556 if (old_ecom)
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001557 ecommunity_unintern (&old_ecom);
hasso70601e02005-05-27 03:26:57 +00001558
paul718e3742002-12-13 20:15:29 +00001559 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1560 }
1561 return RMAP_OKAY;
1562}
1563
1564/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001565static void *
paulfd79ac92004-10-13 05:06:08 +00001566route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001567{
1568 struct ecommunity *ecom;
1569
1570 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1571 if (! ecom)
1572 return NULL;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001573 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001574}
1575
1576/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001577static void
paul718e3742002-12-13 20:15:29 +00001578route_set_ecommunity_rt_free (void *rule)
1579{
1580 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001581 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001582}
1583
1584/* Set community rule structure. */
1585struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1586{
1587 "extcommunity rt",
1588 route_set_ecommunity_rt,
1589 route_set_ecommunity_rt_compile,
1590 route_set_ecommunity_rt_free,
1591};
1592
1593/* `set extcommunity soo COMMUNITY' */
1594
1595/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001596static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001597route_set_ecommunity_soo (void *rule, struct prefix *prefix,
1598 route_map_object_t type, void *object)
1599{
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001600 struct ecommunity *ecom, *old_ecom, *new_ecom;
paul718e3742002-12-13 20:15:29 +00001601 struct bgp_info *bgp_info;
1602
1603 if (type == RMAP_BGP)
1604 {
1605 ecom = rule;
1606 bgp_info = object;
1607
1608 if (! ecom)
1609 return RMAP_OKAY;
1610
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001611 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
1612
1613 if (old_ecom)
1614 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1615 else
1616 new_ecom = ecommunity_dup (ecom);
1617
1618 bgp_info->attr->extra->ecommunity = ecommunity_intern (new_ecom);
1619
1620 if (old_ecom)
1621 ecommunity_unintern (&old_ecom);
1622
paul718e3742002-12-13 20:15:29 +00001623 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
paul718e3742002-12-13 20:15:29 +00001624 }
1625 return RMAP_OKAY;
1626}
1627
1628/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001629static void *
paulfd79ac92004-10-13 05:06:08 +00001630route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001631{
1632 struct ecommunity *ecom;
1633
1634 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1635 if (! ecom)
1636 return NULL;
1637
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001638 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001639}
1640
1641/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001642static void
paul718e3742002-12-13 20:15:29 +00001643route_set_ecommunity_soo_free (void *rule)
1644{
1645 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001646 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001647}
1648
1649/* Set community rule structure. */
1650struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1651{
1652 "extcommunity soo",
1653 route_set_ecommunity_soo,
1654 route_set_ecommunity_soo_compile,
1655 route_set_ecommunity_soo_free,
1656};
1657
1658/* `set origin ORIGIN' */
1659
1660/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001661static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001662route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1663{
1664 u_char *origin;
1665 struct bgp_info *bgp_info;
1666
1667 if (type == RMAP_BGP)
1668 {
1669 origin = rule;
1670 bgp_info = object;
1671
1672 bgp_info->attr->origin = *origin;
1673 }
1674
1675 return RMAP_OKAY;
1676}
1677
1678/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001679static void *
paulfd79ac92004-10-13 05:06:08 +00001680route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001681{
1682 u_char *origin;
1683
1684 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1685
1686 if (strcmp (arg, "igp") == 0)
1687 *origin = 0;
1688 else if (strcmp (arg, "egp") == 0)
1689 *origin = 1;
1690 else
1691 *origin = 2;
1692
1693 return origin;
1694}
1695
1696/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001697static void
paul718e3742002-12-13 20:15:29 +00001698route_set_origin_free (void *rule)
1699{
1700 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1701}
1702
1703/* Set metric rule structure. */
1704struct route_map_rule_cmd route_set_origin_cmd =
1705{
1706 "origin",
1707 route_set_origin,
1708 route_set_origin_compile,
1709 route_set_origin_free,
1710};
1711
1712/* `set atomic-aggregate' */
1713
1714/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001715static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001716route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1717 route_map_object_t type, void *object)
1718{
1719 struct bgp_info *bgp_info;
1720
1721 if (type == RMAP_BGP)
1722 {
1723 bgp_info = object;
1724 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1725 }
1726
1727 return RMAP_OKAY;
1728}
1729
1730/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001731static void *
paulfd79ac92004-10-13 05:06:08 +00001732route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001733{
1734 return (void *)1;
1735}
1736
1737/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001738static void
paul718e3742002-12-13 20:15:29 +00001739route_set_atomic_aggregate_free (void *rule)
1740{
1741 return;
1742}
1743
1744/* Set atomic aggregate rule structure. */
1745struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1746{
1747 "atomic-aggregate",
1748 route_set_atomic_aggregate,
1749 route_set_atomic_aggregate_compile,
1750 route_set_atomic_aggregate_free,
1751};
1752
1753/* `set aggregator as AS A.B.C.D' */
1754struct aggregator
1755{
1756 as_t as;
1757 struct in_addr address;
1758};
1759
paul94f2b392005-06-28 12:44:16 +00001760static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001761route_set_aggregator_as (void *rule, struct prefix *prefix,
1762 route_map_object_t type, void *object)
1763{
1764 struct bgp_info *bgp_info;
1765 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001766 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001767
1768 if (type == RMAP_BGP)
1769 {
1770 bgp_info = object;
1771 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001772 ae = bgp_attr_extra_get (bgp_info->attr);
1773
1774 ae->aggregator_as = aggregator->as;
1775 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001776 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1777 }
1778
1779 return RMAP_OKAY;
1780}
1781
paul94f2b392005-06-28 12:44:16 +00001782static void *
paulfd79ac92004-10-13 05:06:08 +00001783route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001784{
1785 struct aggregator *aggregator;
1786 char as[10];
1787 char address[20];
1788
Stephen Hemminger393deb92008-08-18 14:13:29 -07001789 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
paul718e3742002-12-13 20:15:29 +00001790 sscanf (arg, "%s %s", as, address);
1791
1792 aggregator->as = strtoul (as, NULL, 10);
1793 inet_aton (address, &aggregator->address);
1794
1795 return aggregator;
1796}
1797
paul94f2b392005-06-28 12:44:16 +00001798static void
paul718e3742002-12-13 20:15:29 +00001799route_set_aggregator_as_free (void *rule)
1800{
1801 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1802}
1803
1804struct route_map_rule_cmd route_set_aggregator_as_cmd =
1805{
1806 "aggregator as",
1807 route_set_aggregator_as,
1808 route_set_aggregator_as_compile,
1809 route_set_aggregator_as_free,
1810};
1811
1812#ifdef HAVE_IPV6
1813/* `match ipv6 address IP_ACCESS_LIST' */
1814
paul94f2b392005-06-28 12:44:16 +00001815static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001816route_match_ipv6_address (void *rule, struct prefix *prefix,
1817 route_map_object_t type, void *object)
1818{
1819 struct access_list *alist;
1820
1821 if (type == RMAP_BGP)
1822 {
1823 alist = access_list_lookup (AFI_IP6, (char *) rule);
1824 if (alist == NULL)
1825 return RMAP_NOMATCH;
1826
1827 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1828 RMAP_NOMATCH : RMAP_MATCH);
1829 }
1830 return RMAP_NOMATCH;
1831}
1832
paul94f2b392005-06-28 12:44:16 +00001833static void *
paulfd79ac92004-10-13 05:06:08 +00001834route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001835{
1836 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1837}
1838
paul94f2b392005-06-28 12:44:16 +00001839static void
paul718e3742002-12-13 20:15:29 +00001840route_match_ipv6_address_free (void *rule)
1841{
1842 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1843}
1844
1845/* Route map commands for ip address matching. */
1846struct route_map_rule_cmd route_match_ipv6_address_cmd =
1847{
1848 "ipv6 address",
1849 route_match_ipv6_address,
1850 route_match_ipv6_address_compile,
1851 route_match_ipv6_address_free
1852};
1853
1854/* `match ipv6 next-hop IP_ADDRESS' */
1855
paul94f2b392005-06-28 12:44:16 +00001856static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001857route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1858 route_map_object_t type, void *object)
1859{
1860 struct in6_addr *addr;
1861 struct bgp_info *bgp_info;
1862
1863 if (type == RMAP_BGP)
1864 {
1865 addr = rule;
1866 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001867
1868 if (!bgp_info->attr->extra)
1869 return RMAP_NOMATCH;
1870
1871 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, rule))
paul718e3742002-12-13 20:15:29 +00001872 return RMAP_MATCH;
1873
Paul Jakmafb982c22007-05-04 20:15:47 +00001874 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
1875 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, rule))
paul718e3742002-12-13 20:15:29 +00001876 return RMAP_MATCH;
1877
1878 return RMAP_NOMATCH;
1879 }
1880
1881 return RMAP_NOMATCH;
1882}
1883
paul94f2b392005-06-28 12:44:16 +00001884static void *
paulfd79ac92004-10-13 05:06:08 +00001885route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001886{
1887 struct in6_addr *address;
1888 int ret;
1889
1890 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1891
1892 ret = inet_pton (AF_INET6, arg, address);
1893 if (!ret)
1894 {
1895 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1896 return NULL;
1897 }
1898
1899 return address;
1900}
1901
paul94f2b392005-06-28 12:44:16 +00001902static void
paul718e3742002-12-13 20:15:29 +00001903route_match_ipv6_next_hop_free (void *rule)
1904{
1905 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1906}
1907
1908struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1909{
1910 "ipv6 next-hop",
1911 route_match_ipv6_next_hop,
1912 route_match_ipv6_next_hop_compile,
1913 route_match_ipv6_next_hop_free
1914};
1915
1916/* `match ipv6 address prefix-list PREFIX_LIST' */
1917
paul94f2b392005-06-28 12:44:16 +00001918static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001919route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1920 route_map_object_t type, void *object)
1921{
1922 struct prefix_list *plist;
1923
1924 if (type == RMAP_BGP)
1925 {
1926 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1927 if (plist == NULL)
1928 return RMAP_NOMATCH;
1929
1930 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1931 RMAP_NOMATCH : RMAP_MATCH);
1932 }
1933 return RMAP_NOMATCH;
1934}
1935
paul94f2b392005-06-28 12:44:16 +00001936static void *
paulfd79ac92004-10-13 05:06:08 +00001937route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001938{
1939 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1940}
1941
paul94f2b392005-06-28 12:44:16 +00001942static void
paul718e3742002-12-13 20:15:29 +00001943route_match_ipv6_address_prefix_list_free (void *rule)
1944{
1945 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1946}
1947
1948struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1949{
1950 "ipv6 address prefix-list",
1951 route_match_ipv6_address_prefix_list,
1952 route_match_ipv6_address_prefix_list_compile,
1953 route_match_ipv6_address_prefix_list_free
1954};
1955
1956/* `set ipv6 nexthop global IP_ADDRESS' */
1957
1958/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001959static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001960route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1961 route_map_object_t type, void *object)
1962{
1963 struct in6_addr *address;
1964 struct bgp_info *bgp_info;
1965
1966 if (type == RMAP_BGP)
1967 {
1968 /* Fetch routemap's rule information. */
1969 address = rule;
1970 bgp_info = object;
1971
1972 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001973 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00001974
1975 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001976 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1977 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00001978 }
1979
1980 return RMAP_OKAY;
1981}
1982
1983/* Route map `ip next-hop' compile function. Given string is converted
1984 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001985static void *
paulfd79ac92004-10-13 05:06:08 +00001986route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001987{
1988 int ret;
1989 struct in6_addr *address;
1990
1991 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1992
1993 ret = inet_pton (AF_INET6, arg, address);
1994
1995 if (ret == 0)
1996 {
1997 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1998 return NULL;
1999 }
2000
2001 return address;
2002}
2003
2004/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00002005static void
paul718e3742002-12-13 20:15:29 +00002006route_set_ipv6_nexthop_global_free (void *rule)
2007{
2008 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2009}
2010
2011/* Route map commands for ip nexthop set. */
2012struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
2013{
2014 "ipv6 next-hop global",
2015 route_set_ipv6_nexthop_global,
2016 route_set_ipv6_nexthop_global_compile,
2017 route_set_ipv6_nexthop_global_free
2018};
2019
2020/* `set ipv6 nexthop local IP_ADDRESS' */
2021
2022/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00002023static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002024route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
2025 route_map_object_t type, void *object)
2026{
2027 struct in6_addr *address;
2028 struct bgp_info *bgp_info;
2029
2030 if (type == RMAP_BGP)
2031 {
2032 /* Fetch routemap's rule information. */
2033 address = rule;
2034 bgp_info = object;
2035
2036 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002037 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00002038
2039 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002040 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2041 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00002042 }
2043
2044 return RMAP_OKAY;
2045}
2046
2047/* Route map `ip nexthop' compile function. Given string is converted
2048 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00002049static void *
paulfd79ac92004-10-13 05:06:08 +00002050route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002051{
2052 int ret;
2053 struct in6_addr *address;
2054
2055 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2056
2057 ret = inet_pton (AF_INET6, arg, address);
2058
2059 if (ret == 0)
2060 {
2061 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2062 return NULL;
2063 }
2064
2065 return address;
2066}
2067
2068/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00002069static void
paul718e3742002-12-13 20:15:29 +00002070route_set_ipv6_nexthop_local_free (void *rule)
2071{
2072 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2073}
2074
2075/* Route map commands for ip nexthop set. */
2076struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
2077{
2078 "ipv6 next-hop local",
2079 route_set_ipv6_nexthop_local,
2080 route_set_ipv6_nexthop_local_compile,
2081 route_set_ipv6_nexthop_local_free
2082};
2083#endif /* HAVE_IPV6 */
2084
2085/* `set vpnv4 nexthop A.B.C.D' */
2086
paul94f2b392005-06-28 12:44:16 +00002087static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002088route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2089 route_map_object_t type, void *object)
2090{
2091 struct in_addr *address;
2092 struct bgp_info *bgp_info;
2093
2094 if (type == RMAP_BGP)
2095 {
2096 /* Fetch routemap's rule information. */
2097 address = rule;
2098 bgp_info = object;
2099
2100 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002101 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
paul718e3742002-12-13 20:15:29 +00002102 }
2103
2104 return RMAP_OKAY;
2105}
2106
paul94f2b392005-06-28 12:44:16 +00002107static void *
paulfd79ac92004-10-13 05:06:08 +00002108route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002109{
2110 int ret;
2111 struct in_addr *address;
2112
2113 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2114
2115 ret = inet_aton (arg, address);
2116
2117 if (ret == 0)
2118 {
2119 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2120 return NULL;
2121 }
2122
2123 return address;
2124}
2125
paul94f2b392005-06-28 12:44:16 +00002126static void
paul718e3742002-12-13 20:15:29 +00002127route_set_vpnv4_nexthop_free (void *rule)
2128{
2129 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2130}
2131
2132/* Route map commands for ip nexthop set. */
2133struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2134{
2135 "vpnv4 next-hop",
2136 route_set_vpnv4_nexthop,
2137 route_set_vpnv4_nexthop_compile,
2138 route_set_vpnv4_nexthop_free
2139};
2140
2141/* `set originator-id' */
2142
2143/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002144static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002145route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2146{
2147 struct in_addr *address;
2148 struct bgp_info *bgp_info;
2149
2150 if (type == RMAP_BGP)
2151 {
2152 address = rule;
2153 bgp_info = object;
2154
2155 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002156 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002157 }
2158
2159 return RMAP_OKAY;
2160}
2161
2162/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002163static void *
paulfd79ac92004-10-13 05:06:08 +00002164route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002165{
2166 int ret;
2167 struct in_addr *address;
2168
2169 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2170
2171 ret = inet_aton (arg, address);
2172
2173 if (ret == 0)
2174 {
2175 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2176 return NULL;
2177 }
2178
2179 return address;
2180}
2181
2182/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002183static void
paul718e3742002-12-13 20:15:29 +00002184route_set_originator_id_free (void *rule)
2185{
2186 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2187}
2188
2189/* Set metric rule structure. */
2190struct route_map_rule_cmd route_set_originator_id_cmd =
2191{
2192 "originator-id",
2193 route_set_originator_id,
2194 route_set_originator_id_compile,
2195 route_set_originator_id_free,
2196};
2197
2198/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002199static int
paul718e3742002-12-13 20:15:29 +00002200bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002201 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002202{
2203 int ret;
2204
2205 ret = route_map_add_match (index, command, arg);
2206 if (ret)
2207 {
2208 switch (ret)
2209 {
2210 case RMAP_RULE_MISSING:
2211 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2212 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002213 case RMAP_COMPILE_ERROR:
2214 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2215 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002216 }
2217 }
2218 return CMD_SUCCESS;
2219}
2220
2221/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002222static int
paul718e3742002-12-13 20:15:29 +00002223bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002224 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002225{
2226 int ret;
2227
2228 ret = route_map_delete_match (index, command, arg);
2229 if (ret)
2230 {
2231 switch (ret)
2232 {
2233 case RMAP_RULE_MISSING:
2234 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2235 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002236 case RMAP_COMPILE_ERROR:
2237 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2238 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002239 }
2240 }
2241 return CMD_SUCCESS;
2242}
2243
2244/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002245static int
paul718e3742002-12-13 20:15:29 +00002246bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002247 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002248{
2249 int ret;
2250
2251 ret = route_map_add_set (index, command, arg);
2252 if (ret)
2253 {
2254 switch (ret)
2255 {
2256 case RMAP_RULE_MISSING:
2257 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2258 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002259 case RMAP_COMPILE_ERROR:
2260 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2261 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002262 }
2263 }
2264 return CMD_SUCCESS;
2265}
2266
2267/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002268static int
paul718e3742002-12-13 20:15:29 +00002269bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002270 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002271{
2272 int ret;
2273
2274 ret = route_map_delete_set (index, command, arg);
2275 if (ret)
2276 {
2277 switch (ret)
2278 {
2279 case RMAP_RULE_MISSING:
2280 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2281 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002282 case RMAP_COMPILE_ERROR:
2283 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2284 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002285 }
2286 }
2287 return CMD_SUCCESS;
2288}
2289
2290/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002291static void
paulfd79ac92004-10-13 05:06:08 +00002292bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002293{
2294 int i;
2295 afi_t afi;
2296 safi_t safi;
2297 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002298 struct listnode *node, *nnode;
2299 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002300 struct bgp *bgp;
2301 struct peer *peer;
2302 struct peer_group *group;
2303 struct bgp_filter *filter;
2304 struct bgp_node *bn;
2305 struct bgp_static *bgp_static;
2306
2307 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002308 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002309 {
paul1eb8ef22005-04-07 07:30:20 +00002310 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002311 {
2312 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2313 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2314 {
2315 filter = &peer->filter[afi][safi];
2316
paulfee0f4c2004-09-13 05:12:46 +00002317 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002318 {
2319 if (filter->map[direct].name)
2320 filter->map[direct].map =
2321 route_map_lookup_by_name (filter->map[direct].name);
2322 else
2323 filter->map[direct].map = NULL;
2324 }
2325
2326 if (filter->usmap.name)
2327 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2328 else
2329 filter->usmap.map = NULL;
2330 }
2331 }
paul1eb8ef22005-04-07 07:30:20 +00002332 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002333 {
2334 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2335 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2336 {
2337 filter = &group->conf->filter[afi][safi];
2338
paulfee0f4c2004-09-13 05:12:46 +00002339 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002340 {
2341 if (filter->map[direct].name)
2342 filter->map[direct].map =
2343 route_map_lookup_by_name (filter->map[direct].name);
2344 else
2345 filter->map[direct].map = NULL;
2346 }
2347
2348 if (filter->usmap.name)
2349 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2350 else
2351 filter->usmap.map = NULL;
2352 }
2353 }
2354 }
2355
2356 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002357 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002358 {
paul1eb8ef22005-04-07 07:30:20 +00002359 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002360 {
2361 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2362 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2363 {
2364 if (peer->default_rmap[afi][safi].name)
2365 peer->default_rmap[afi][safi].map =
2366 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2367 else
2368 peer->default_rmap[afi][safi].map = NULL;
2369 }
2370 }
2371 }
2372
2373 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002374 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002375 {
2376 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2377 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2378 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2379 bn = bgp_route_next (bn))
2380 if ((bgp_static = bn->info) != NULL)
2381 {
2382 if (bgp_static->rmap.name)
2383 bgp_static->rmap.map =
2384 route_map_lookup_by_name (bgp_static->rmap.name);
2385 else
2386 bgp_static->rmap.map = NULL;
2387 }
2388 }
2389
2390 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002391 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002392 {
2393 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2394 {
2395 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2396 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2397 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2398#ifdef HAVE_IPV6
2399 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2400 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2401 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2402#endif /* HAVE_IPV6 */
2403 }
2404 }
2405}
2406
paulfee0f4c2004-09-13 05:12:46 +00002407DEFUN (match_peer,
2408 match_peer_cmd,
2409 "match peer (A.B.C.D|X:X::X:X)",
2410 MATCH_STR
2411 "Match peer address\n"
2412 "IPv6 address of peer\n"
2413 "IP address of peer\n")
2414{
2415 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2416}
2417
2418DEFUN (match_peer_local,
2419 match_peer_local_cmd,
2420 "match peer local",
2421 MATCH_STR
2422 "Match peer address\n"
2423 "Static or Redistributed routes\n")
2424{
2425 return bgp_route_match_add (vty, vty->index, "peer", NULL);
2426}
2427
2428DEFUN (no_match_peer,
2429 no_match_peer_cmd,
2430 "no match peer",
2431 NO_STR
2432 MATCH_STR
2433 "Match peer address\n")
2434{
2435 if (argc == 0)
2436 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2437
2438 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2439}
2440
2441ALIAS (no_match_peer,
2442 no_match_peer_val_cmd,
2443 "no match peer (A.B.C.D|X:X::X:X)",
2444 NO_STR
2445 MATCH_STR
2446 "Match peer address\n"
2447 "IPv6 address of peer\n"
2448 "IP address of peer\n")
2449
2450ALIAS (no_match_peer,
2451 no_match_peer_local_cmd,
2452 "no match peer local",
2453 NO_STR
2454 MATCH_STR
2455 "Match peer address\n"
2456 "Static or Redistributed routes\n")
2457
paul718e3742002-12-13 20:15:29 +00002458DEFUN (match_ip_address,
2459 match_ip_address_cmd,
2460 "match ip address (<1-199>|<1300-2699>|WORD)",
2461 MATCH_STR
2462 IP_STR
2463 "Match address of route\n"
2464 "IP access-list number\n"
2465 "IP access-list number (expanded range)\n"
2466 "IP Access-list name\n")
2467{
2468 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2469}
2470
2471DEFUN (no_match_ip_address,
2472 no_match_ip_address_cmd,
2473 "no match ip address",
2474 NO_STR
2475 MATCH_STR
2476 IP_STR
2477 "Match address of route\n")
2478{
2479 if (argc == 0)
2480 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2481
2482 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2483}
2484
2485ALIAS (no_match_ip_address,
2486 no_match_ip_address_val_cmd,
2487 "no match ip address (<1-199>|<1300-2699>|WORD)",
2488 NO_STR
2489 MATCH_STR
2490 IP_STR
2491 "Match address of route\n"
2492 "IP access-list number\n"
2493 "IP access-list number (expanded range)\n"
2494 "IP Access-list name\n")
2495
2496DEFUN (match_ip_next_hop,
2497 match_ip_next_hop_cmd,
2498 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2499 MATCH_STR
2500 IP_STR
2501 "Match next-hop address of route\n"
2502 "IP access-list number\n"
2503 "IP access-list number (expanded range)\n"
2504 "IP Access-list name\n")
2505{
2506 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2507}
2508
2509DEFUN (no_match_ip_next_hop,
2510 no_match_ip_next_hop_cmd,
2511 "no match ip next-hop",
2512 NO_STR
2513 MATCH_STR
2514 IP_STR
2515 "Match next-hop address of route\n")
2516{
2517 if (argc == 0)
2518 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2519
2520 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2521}
2522
2523ALIAS (no_match_ip_next_hop,
2524 no_match_ip_next_hop_val_cmd,
2525 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2526 NO_STR
2527 MATCH_STR
2528 IP_STR
2529 "Match next-hop address of route\n"
2530 "IP access-list number\n"
2531 "IP access-list number (expanded range)\n"
2532 "IP Access-list name\n")
2533
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04002534/* match probability { */
2535
2536DEFUN (match_probability,
2537 match_probability_cmd,
2538 "match probability <0-100>",
2539 MATCH_STR
2540 "Match portion of routes defined by percentage value\n"
2541 "Percentage of routes\n")
2542{
2543 return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
2544}
2545
2546DEFUN (no_match_probability,
2547 no_match_probability_cmd,
2548 "no match probability",
2549 NO_STR
2550 MATCH_STR
2551 "Match portion of routes defined by percentage value\n")
2552{
2553 return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL);
2554}
2555
2556ALIAS (no_match_probability,
2557 no_match_probability_val_cmd,
2558 "no match probability <1-99>",
2559 NO_STR
2560 MATCH_STR
2561 "Match portion of routes defined by percentage value\n"
2562 "Percentage of routes\n")
2563
2564/* } */
2565
hassoc1643bb2005-02-02 16:43:17 +00002566DEFUN (match_ip_route_source,
2567 match_ip_route_source_cmd,
2568 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2569 MATCH_STR
2570 IP_STR
2571 "Match advertising source address of route\n"
2572 "IP access-list number\n"
2573 "IP access-list number (expanded range)\n"
2574 "IP standard access-list name\n")
2575{
2576 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2577}
2578
2579DEFUN (no_match_ip_route_source,
2580 no_match_ip_route_source_cmd,
2581 "no match ip route-source",
2582 NO_STR
2583 MATCH_STR
2584 IP_STR
2585 "Match advertising source address of route\n")
2586{
2587 if (argc == 0)
2588 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2589
2590 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2591}
2592
2593ALIAS (no_match_ip_route_source,
2594 no_match_ip_route_source_val_cmd,
2595 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2596 NO_STR
2597 MATCH_STR
2598 IP_STR
2599 "Match advertising source address of route\n"
2600 "IP access-list number\n"
2601 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002602 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002603
paul718e3742002-12-13 20:15:29 +00002604DEFUN (match_ip_address_prefix_list,
2605 match_ip_address_prefix_list_cmd,
2606 "match ip address prefix-list WORD",
2607 MATCH_STR
2608 IP_STR
2609 "Match address of route\n"
2610 "Match entries of prefix-lists\n"
2611 "IP prefix-list name\n")
2612{
2613 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2614}
2615
2616DEFUN (no_match_ip_address_prefix_list,
2617 no_match_ip_address_prefix_list_cmd,
2618 "no match ip address prefix-list",
2619 NO_STR
2620 MATCH_STR
2621 IP_STR
2622 "Match address of route\n"
2623 "Match entries of prefix-lists\n")
2624{
2625 if (argc == 0)
2626 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2627
2628 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2629}
2630
2631ALIAS (no_match_ip_address_prefix_list,
2632 no_match_ip_address_prefix_list_val_cmd,
2633 "no match ip address prefix-list WORD",
2634 NO_STR
2635 MATCH_STR
2636 IP_STR
2637 "Match address of route\n"
2638 "Match entries of prefix-lists\n"
2639 "IP prefix-list name\n")
2640
2641DEFUN (match_ip_next_hop_prefix_list,
2642 match_ip_next_hop_prefix_list_cmd,
2643 "match ip next-hop prefix-list WORD",
2644 MATCH_STR
2645 IP_STR
2646 "Match next-hop address of route\n"
2647 "Match entries of prefix-lists\n"
2648 "IP prefix-list name\n")
2649{
2650 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2651}
2652
2653DEFUN (no_match_ip_next_hop_prefix_list,
2654 no_match_ip_next_hop_prefix_list_cmd,
2655 "no match ip next-hop prefix-list",
2656 NO_STR
2657 MATCH_STR
2658 IP_STR
2659 "Match next-hop address of route\n"
2660 "Match entries of prefix-lists\n")
2661{
2662 if (argc == 0)
2663 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2664
2665 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2666}
2667
2668ALIAS (no_match_ip_next_hop_prefix_list,
2669 no_match_ip_next_hop_prefix_list_val_cmd,
2670 "no match ip next-hop prefix-list WORD",
2671 NO_STR
2672 MATCH_STR
2673 IP_STR
2674 "Match next-hop address of route\n"
2675 "Match entries of prefix-lists\n"
2676 "IP prefix-list name\n")
2677
hassoc1643bb2005-02-02 16:43:17 +00002678DEFUN (match_ip_route_source_prefix_list,
2679 match_ip_route_source_prefix_list_cmd,
2680 "match ip route-source prefix-list WORD",
2681 MATCH_STR
2682 IP_STR
2683 "Match advertising source address of route\n"
2684 "Match entries of prefix-lists\n"
2685 "IP prefix-list name\n")
2686{
2687 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2688}
2689
2690DEFUN (no_match_ip_route_source_prefix_list,
2691 no_match_ip_route_source_prefix_list_cmd,
2692 "no match ip route-source prefix-list",
2693 NO_STR
2694 MATCH_STR
2695 IP_STR
2696 "Match advertising source address of route\n"
2697 "Match entries of prefix-lists\n")
2698{
2699 if (argc == 0)
2700 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2701
2702 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2703}
2704
2705ALIAS (no_match_ip_route_source_prefix_list,
2706 no_match_ip_route_source_prefix_list_val_cmd,
2707 "no match ip route-source prefix-list WORD",
2708 NO_STR
2709 MATCH_STR
2710 IP_STR
2711 "Match advertising source address of route\n"
2712 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002713 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002714
paul718e3742002-12-13 20:15:29 +00002715DEFUN (match_metric,
2716 match_metric_cmd,
2717 "match metric <0-4294967295>",
2718 MATCH_STR
2719 "Match metric of route\n"
2720 "Metric value\n")
2721{
2722 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2723}
2724
2725DEFUN (no_match_metric,
2726 no_match_metric_cmd,
2727 "no match metric",
2728 NO_STR
2729 MATCH_STR
2730 "Match metric of route\n")
2731{
2732 if (argc == 0)
2733 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2734
2735 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2736}
2737
2738ALIAS (no_match_metric,
2739 no_match_metric_val_cmd,
2740 "no match metric <0-4294967295>",
2741 NO_STR
2742 MATCH_STR
2743 "Match metric of route\n"
2744 "Metric value\n")
2745
2746DEFUN (match_community,
2747 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002748 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002749 MATCH_STR
2750 "Match BGP community list\n"
2751 "Community-list number (standard)\n"
2752 "Community-list number (expanded)\n"
2753 "Community-list name\n")
2754{
2755 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2756}
2757
2758DEFUN (match_community_exact,
2759 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002760 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002761 MATCH_STR
2762 "Match BGP community list\n"
2763 "Community-list number (standard)\n"
2764 "Community-list number (expanded)\n"
2765 "Community-list name\n"
2766 "Do exact matching of communities\n")
2767{
2768 int ret;
2769 char *argstr;
2770
2771 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2772 strlen (argv[0]) + strlen ("exact-match") + 2);
2773
2774 sprintf (argstr, "%s exact-match", argv[0]);
2775
2776 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2777
2778 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2779
2780 return ret;
2781}
2782
2783DEFUN (no_match_community,
2784 no_match_community_cmd,
2785 "no match community",
2786 NO_STR
2787 MATCH_STR
2788 "Match BGP community list\n")
2789{
2790 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2791}
2792
2793ALIAS (no_match_community,
2794 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002795 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002796 NO_STR
2797 MATCH_STR
2798 "Match BGP community list\n"
2799 "Community-list number (standard)\n"
2800 "Community-list number (expanded)\n"
2801 "Community-list name\n")
2802
2803ALIAS (no_match_community,
2804 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002805 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002806 NO_STR
2807 MATCH_STR
2808 "Match BGP community list\n"
2809 "Community-list number (standard)\n"
2810 "Community-list number (expanded)\n"
2811 "Community-list name\n"
2812 "Do exact matching of communities\n")
2813
paul73ffb252003-04-19 15:49:49 +00002814DEFUN (match_ecommunity,
2815 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002816 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002817 MATCH_STR
2818 "Match BGP/VPN extended community list\n"
2819 "Extended community-list number (standard)\n"
2820 "Extended community-list number (expanded)\n"
2821 "Extended community-list name\n")
2822{
2823 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2824}
2825
2826DEFUN (no_match_ecommunity,
2827 no_match_ecommunity_cmd,
2828 "no match extcommunity",
2829 NO_STR
2830 MATCH_STR
2831 "Match BGP/VPN extended community list\n")
2832{
2833 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2834}
2835
2836ALIAS (no_match_ecommunity,
2837 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002838 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002839 NO_STR
2840 MATCH_STR
2841 "Match BGP/VPN extended community list\n"
2842 "Extended community-list number (standard)\n"
2843 "Extended community-list number (expanded)\n"
2844 "Extended community-list name\n")
2845
paul718e3742002-12-13 20:15:29 +00002846DEFUN (match_aspath,
2847 match_aspath_cmd,
2848 "match as-path WORD",
2849 MATCH_STR
2850 "Match BGP AS path list\n"
2851 "AS path access-list name\n")
2852{
2853 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2854}
2855
2856DEFUN (no_match_aspath,
2857 no_match_aspath_cmd,
2858 "no match as-path",
2859 NO_STR
2860 MATCH_STR
2861 "Match BGP AS path list\n")
2862{
2863 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2864}
2865
2866ALIAS (no_match_aspath,
2867 no_match_aspath_val_cmd,
2868 "no match as-path WORD",
2869 NO_STR
2870 MATCH_STR
2871 "Match BGP AS path list\n"
2872 "AS path access-list name\n")
2873
2874DEFUN (match_origin,
2875 match_origin_cmd,
2876 "match origin (egp|igp|incomplete)",
2877 MATCH_STR
2878 "BGP origin code\n"
2879 "remote EGP\n"
2880 "local IGP\n"
2881 "unknown heritage\n")
2882{
2883 if (strncmp (argv[0], "igp", 2) == 0)
2884 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2885 if (strncmp (argv[0], "egp", 1) == 0)
2886 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2887 if (strncmp (argv[0], "incomplete", 2) == 0)
2888 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2889
2890 return CMD_WARNING;
2891}
2892
2893DEFUN (no_match_origin,
2894 no_match_origin_cmd,
2895 "no match origin",
2896 NO_STR
2897 MATCH_STR
2898 "BGP origin code\n")
2899{
2900 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2901}
2902
2903ALIAS (no_match_origin,
2904 no_match_origin_val_cmd,
2905 "no match origin (egp|igp|incomplete)",
2906 NO_STR
2907 MATCH_STR
2908 "BGP origin code\n"
2909 "remote EGP\n"
2910 "local IGP\n"
2911 "unknown heritage\n")
2912
2913DEFUN (set_ip_nexthop,
2914 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002915 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002916 SET_STR
2917 IP_STR
2918 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002919 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002920{
2921 union sockunion su;
2922 int ret;
2923
2924 ret = str2sockunion (argv[0], &su);
2925 if (ret < 0)
2926 {
2927 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2928 return CMD_WARNING;
2929 }
2930
2931 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2932}
2933
paulaf5cd0a2003-11-02 07:24:40 +00002934DEFUN (set_ip_nexthop_peer,
2935 set_ip_nexthop_peer_cmd,
2936 "set ip next-hop peer-address",
2937 SET_STR
2938 IP_STR
2939 "Next hop address\n"
2940 "Use peer address (for BGP only)\n")
2941{
2942 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2943}
2944
paul94f2b392005-06-28 12:44:16 +00002945DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00002946 no_set_ip_nexthop_peer_cmd,
2947 "no set ip next-hop peer-address",
2948 NO_STR
2949 SET_STR
2950 IP_STR
2951 "Next hop address\n"
2952 "Use peer address (for BGP only)\n")
2953{
2954 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2955}
2956
2957
paul718e3742002-12-13 20:15:29 +00002958DEFUN (no_set_ip_nexthop,
2959 no_set_ip_nexthop_cmd,
2960 "no set ip next-hop",
2961 NO_STR
2962 SET_STR
paul718e3742002-12-13 20:15:29 +00002963 "Next hop address\n")
2964{
paulaf5cd0a2003-11-02 07:24:40 +00002965 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002966 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2967
2968 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2969}
2970
2971ALIAS (no_set_ip_nexthop,
2972 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002973 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002974 NO_STR
2975 SET_STR
2976 IP_STR
2977 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002978 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002979
2980DEFUN (set_metric,
2981 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002982 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002983 SET_STR
2984 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002985 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002986{
2987 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2988}
2989
paul73ffb252003-04-19 15:49:49 +00002990ALIAS (set_metric,
2991 set_metric_addsub_cmd,
2992 "set metric <+/-metric>",
2993 SET_STR
2994 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00002995 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00002996
paul718e3742002-12-13 20:15:29 +00002997DEFUN (no_set_metric,
2998 no_set_metric_cmd,
2999 "no set metric",
3000 NO_STR
3001 SET_STR
3002 "Metric value for destination routing protocol\n")
3003{
3004 if (argc == 0)
3005 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
3006
3007 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
3008}
3009
3010ALIAS (no_set_metric,
3011 no_set_metric_val_cmd,
3012 "no set metric <0-4294967295>",
3013 NO_STR
3014 SET_STR
3015 "Metric value for destination routing protocol\n"
3016 "Metric value\n")
3017
3018DEFUN (set_local_pref,
3019 set_local_pref_cmd,
3020 "set local-preference <0-4294967295>",
3021 SET_STR
3022 "BGP local preference path attribute\n"
3023 "Preference value\n")
3024{
3025 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
3026}
3027
3028DEFUN (no_set_local_pref,
3029 no_set_local_pref_cmd,
3030 "no set local-preference",
3031 NO_STR
3032 SET_STR
3033 "BGP local preference path attribute\n")
3034{
3035 if (argc == 0)
3036 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3037
3038 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
3039}
3040
3041ALIAS (no_set_local_pref,
3042 no_set_local_pref_val_cmd,
3043 "no set local-preference <0-4294967295>",
3044 NO_STR
3045 SET_STR
3046 "BGP local preference path attribute\n"
3047 "Preference value\n")
3048
3049DEFUN (set_weight,
3050 set_weight_cmd,
3051 "set weight <0-4294967295>",
3052 SET_STR
3053 "BGP weight for routing table\n"
3054 "Weight value\n")
3055{
3056 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3057}
3058
3059DEFUN (no_set_weight,
3060 no_set_weight_cmd,
3061 "no set weight",
3062 NO_STR
3063 SET_STR
3064 "BGP weight for routing table\n")
3065{
3066 if (argc == 0)
3067 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3068
3069 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3070}
3071
3072ALIAS (no_set_weight,
3073 no_set_weight_val_cmd,
3074 "no set weight <0-4294967295>",
3075 NO_STR
3076 SET_STR
3077 "BGP weight for routing table\n"
3078 "Weight value\n")
3079
3080DEFUN (set_aspath_prepend,
3081 set_aspath_prepend_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003082 "set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003083 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003084 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003085 "Prepend to the as-path\n"
3086 "AS number\n")
3087{
3088 int ret;
3089 char *str;
3090
3091 str = argv_concat (argv, argc, 0);
3092 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3093 XFREE (MTYPE_TMP, str);
3094
3095 return ret;
3096}
3097
3098DEFUN (no_set_aspath_prepend,
3099 no_set_aspath_prepend_cmd,
3100 "no set as-path prepend",
3101 NO_STR
3102 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003103 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003104 "Prepend to the as-path\n")
3105{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00003106 int ret;
3107 char *str;
3108
3109 if (argc == 0)
3110 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3111
3112 str = argv_concat (argv, argc, 0);
3113 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3114 XFREE (MTYPE_TMP, str);
3115 return ret;
paul718e3742002-12-13 20:15:29 +00003116}
3117
3118ALIAS (no_set_aspath_prepend,
3119 no_set_aspath_prepend_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003120 "no set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003121 NO_STR
3122 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003123 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003124 "Prepend to the as-path\n"
3125 "AS number\n")
3126
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003127DEFUN (set_aspath_exclude,
3128 set_aspath_exclude_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003129 "set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003130 SET_STR
3131 "Transform BGP AS-path attribute\n"
3132 "Exclude from the as-path\n"
3133 "AS number\n")
3134{
3135 int ret;
3136 char *str;
3137
3138 str = argv_concat (argv, argc, 0);
3139 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3140 XFREE (MTYPE_TMP, str);
3141 return ret;
3142}
3143
3144DEFUN (no_set_aspath_exclude,
3145 no_set_aspath_exclude_cmd,
3146 "no set as-path exclude",
3147 NO_STR
3148 SET_STR
3149 "Transform BGP AS_PATH attribute\n"
3150 "Exclude from the as-path\n")
3151{
3152 int ret;
3153 char *str;
3154
3155 if (argc == 0)
3156 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3157
3158 str = argv_concat (argv, argc, 0);
3159 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3160 XFREE (MTYPE_TMP, str);
3161 return ret;
3162}
3163
3164ALIAS (no_set_aspath_exclude,
3165 no_set_aspath_exclude_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003166 "no set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003167 NO_STR
3168 SET_STR
3169 "Transform BGP AS_PATH attribute\n"
3170 "Exclude from the as-path\n"
3171 "AS number\n")
3172
paul718e3742002-12-13 20:15:29 +00003173DEFUN (set_community,
3174 set_community_cmd,
3175 "set community .AA:NN",
3176 SET_STR
3177 "BGP community attribute\n"
3178 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3179{
3180 int i;
3181 int first = 0;
3182 int additive = 0;
3183 struct buffer *b;
3184 struct community *com = NULL;
3185 char *str;
3186 char *argstr;
3187 int ret;
3188
3189 b = buffer_new (1024);
3190
3191 for (i = 0; i < argc; i++)
3192 {
3193 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3194 {
3195 additive = 1;
3196 continue;
3197 }
3198
3199 if (first)
3200 buffer_putc (b, ' ');
3201 else
3202 first = 1;
3203
3204 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3205 {
3206 buffer_putstr (b, "internet");
3207 continue;
3208 }
3209 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3210 {
3211 buffer_putstr (b, "local-AS");
3212 continue;
3213 }
3214 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3215 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3216 {
3217 buffer_putstr (b, "no-advertise");
3218 continue;
3219 }
3220 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3221 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3222 {
3223 buffer_putstr (b, "no-export");
3224 continue;
3225 }
3226 buffer_putstr (b, argv[i]);
3227 }
3228 buffer_putc (b, '\0');
3229
3230 /* Fetch result string then compile it to communities attribute. */
3231 str = buffer_getstr (b);
3232 buffer_free (b);
3233
3234 if (str)
3235 {
3236 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003237 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003238 }
3239
3240 /* Can't compile user input into communities attribute. */
3241 if (! com)
3242 {
3243 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3244 return CMD_WARNING;
3245 }
3246
3247 /* Set communites attribute string. */
3248 str = community_str (com);
3249
3250 if (additive)
3251 {
3252 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3253 strcpy (argstr, str);
3254 strcpy (argstr + strlen (str), " additive");
3255 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3256 XFREE (MTYPE_TMP, argstr);
3257 }
3258 else
3259 ret = bgp_route_set_add (vty, vty->index, "community", str);
3260
3261 community_free (com);
3262
3263 return ret;
3264}
3265
3266DEFUN (set_community_none,
3267 set_community_none_cmd,
3268 "set community none",
3269 SET_STR
3270 "BGP community attribute\n"
3271 "No community attribute\n")
3272{
3273 return bgp_route_set_add (vty, vty->index, "community", "none");
3274}
3275
3276DEFUN (no_set_community,
3277 no_set_community_cmd,
3278 "no set community",
3279 NO_STR
3280 SET_STR
3281 "BGP community attribute\n")
3282{
3283 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3284}
3285
3286ALIAS (no_set_community,
3287 no_set_community_val_cmd,
3288 "no set community .AA:NN",
3289 NO_STR
3290 SET_STR
3291 "BGP community attribute\n"
3292 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3293
3294ALIAS (no_set_community,
3295 no_set_community_none_cmd,
3296 "no set community none",
3297 NO_STR
3298 SET_STR
3299 "BGP community attribute\n"
3300 "No community attribute\n")
3301
3302DEFUN (set_community_delete,
3303 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003304 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003305 SET_STR
3306 "set BGP community list (for deletion)\n"
3307 "Community-list number (standard)\n"
3308 "Communitly-list number (expanded)\n"
3309 "Community-list name\n"
3310 "Delete matching communities\n")
3311{
3312 char *str;
3313
3314 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3315 strcpy (str, argv[0]);
3316 strcpy (str + strlen (argv[0]), " delete");
3317
3318 bgp_route_set_add (vty, vty->index, "comm-list", str);
3319
3320 XFREE (MTYPE_TMP, str);
3321 return CMD_SUCCESS;
3322}
3323
3324DEFUN (no_set_community_delete,
3325 no_set_community_delete_cmd,
3326 "no set comm-list",
3327 NO_STR
3328 SET_STR
3329 "set BGP community list (for deletion)\n")
3330{
3331 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3332}
3333
3334ALIAS (no_set_community_delete,
3335 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003336 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003337 NO_STR
3338 SET_STR
3339 "set BGP community list (for deletion)\n"
3340 "Community-list number (standard)\n"
3341 "Communitly-list number (expanded)\n"
3342 "Community-list name\n"
3343 "Delete matching communities\n")
3344
3345DEFUN (set_ecommunity_rt,
3346 set_ecommunity_rt_cmd,
3347 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3348 SET_STR
3349 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003350 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003351 "VPN extended community\n")
3352{
3353 int ret;
3354 char *str;
3355
3356 str = argv_concat (argv, argc, 0);
3357 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3358 XFREE (MTYPE_TMP, str);
3359
3360 return ret;
3361}
3362
3363DEFUN (no_set_ecommunity_rt,
3364 no_set_ecommunity_rt_cmd,
3365 "no set extcommunity rt",
3366 NO_STR
3367 SET_STR
3368 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003369 "Route Target extended community\n")
paul718e3742002-12-13 20:15:29 +00003370{
3371 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3372}
3373
3374ALIAS (no_set_ecommunity_rt,
3375 no_set_ecommunity_rt_val_cmd,
3376 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3377 NO_STR
3378 SET_STR
3379 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003380 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003381 "VPN extended community\n")
3382
3383DEFUN (set_ecommunity_soo,
3384 set_ecommunity_soo_cmd,
3385 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3386 SET_STR
3387 "BGP extended community attribute\n"
3388 "Site-of-Origin extended community\n"
3389 "VPN extended community\n")
3390{
3391 int ret;
3392 char *str;
3393
3394 str = argv_concat (argv, argc, 0);
3395 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3396 XFREE (MTYPE_TMP, str);
3397 return ret;
3398}
3399
3400DEFUN (no_set_ecommunity_soo,
3401 no_set_ecommunity_soo_cmd,
3402 "no set extcommunity soo",
3403 NO_STR
3404 SET_STR
3405 "BGP extended community attribute\n"
3406 "Site-of-Origin extended community\n")
3407{
3408 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3409}
3410
3411ALIAS (no_set_ecommunity_soo,
3412 no_set_ecommunity_soo_val_cmd,
3413 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3414 NO_STR
3415 SET_STR
3416 "BGP extended community attribute\n"
3417 "Site-of-Origin extended community\n"
3418 "VPN extended community\n")
3419
3420DEFUN (set_origin,
3421 set_origin_cmd,
3422 "set origin (egp|igp|incomplete)",
3423 SET_STR
3424 "BGP origin code\n"
3425 "remote EGP\n"
3426 "local IGP\n"
3427 "unknown heritage\n")
3428{
3429 if (strncmp (argv[0], "igp", 2) == 0)
3430 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3431 if (strncmp (argv[0], "egp", 1) == 0)
3432 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3433 if (strncmp (argv[0], "incomplete", 2) == 0)
3434 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3435
3436 return CMD_WARNING;
3437}
3438
3439DEFUN (no_set_origin,
3440 no_set_origin_cmd,
3441 "no set origin",
3442 NO_STR
3443 SET_STR
3444 "BGP origin code\n")
3445{
3446 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3447}
3448
3449ALIAS (no_set_origin,
3450 no_set_origin_val_cmd,
3451 "no set origin (egp|igp|incomplete)",
3452 NO_STR
3453 SET_STR
3454 "BGP origin code\n"
3455 "remote EGP\n"
3456 "local IGP\n"
3457 "unknown heritage\n")
3458
3459DEFUN (set_atomic_aggregate,
3460 set_atomic_aggregate_cmd,
3461 "set atomic-aggregate",
3462 SET_STR
3463 "BGP atomic aggregate attribute\n" )
3464{
3465 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3466}
3467
3468DEFUN (no_set_atomic_aggregate,
3469 no_set_atomic_aggregate_cmd,
3470 "no set atomic-aggregate",
3471 NO_STR
3472 SET_STR
3473 "BGP atomic aggregate attribute\n" )
3474{
3475 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3476}
3477
3478DEFUN (set_aggregator_as,
3479 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003480 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003481 SET_STR
3482 "BGP aggregator attribute\n"
3483 "AS number of aggregator\n"
3484 "AS number\n"
3485 "IP address of aggregator\n")
3486{
3487 int ret;
3488 as_t as;
3489 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003490 char *argstr;
3491
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003492 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003493
paul718e3742002-12-13 20:15:29 +00003494 ret = inet_aton (argv[1], &address);
3495 if (ret == 0)
3496 {
3497 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3498 return CMD_WARNING;
3499 }
3500
3501 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3502 strlen (argv[0]) + strlen (argv[1]) + 2);
3503
3504 sprintf (argstr, "%s %s", argv[0], argv[1]);
3505
3506 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3507
3508 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3509
3510 return ret;
3511}
3512
3513DEFUN (no_set_aggregator_as,
3514 no_set_aggregator_as_cmd,
3515 "no set aggregator as",
3516 NO_STR
3517 SET_STR
3518 "BGP aggregator attribute\n"
3519 "AS number of aggregator\n")
3520{
3521 int ret;
3522 as_t as;
3523 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003524 char *argstr;
3525
3526 if (argv == 0)
3527 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3528
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003529 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003530
3531 ret = inet_aton (argv[1], &address);
3532 if (ret == 0)
3533 {
3534 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3535 return CMD_WARNING;
3536 }
3537
3538 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3539 strlen (argv[0]) + strlen (argv[1]) + 2);
3540
3541 sprintf (argstr, "%s %s", argv[0], argv[1]);
3542
3543 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3544
3545 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3546
3547 return ret;
3548}
3549
3550ALIAS (no_set_aggregator_as,
3551 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003552 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003553 NO_STR
3554 SET_STR
3555 "BGP aggregator attribute\n"
3556 "AS number of aggregator\n"
3557 "AS number\n"
3558 "IP address of aggregator\n")
3559
3560
3561#ifdef HAVE_IPV6
3562DEFUN (match_ipv6_address,
3563 match_ipv6_address_cmd,
3564 "match ipv6 address WORD",
3565 MATCH_STR
3566 IPV6_STR
3567 "Match IPv6 address of route\n"
3568 "IPv6 access-list name\n")
3569{
3570 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3571}
3572
3573DEFUN (no_match_ipv6_address,
3574 no_match_ipv6_address_cmd,
3575 "no match ipv6 address WORD",
3576 NO_STR
3577 MATCH_STR
3578 IPV6_STR
3579 "Match IPv6 address of route\n"
3580 "IPv6 access-list name\n")
3581{
3582 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3583}
3584
3585DEFUN (match_ipv6_next_hop,
3586 match_ipv6_next_hop_cmd,
3587 "match ipv6 next-hop X:X::X:X",
3588 MATCH_STR
3589 IPV6_STR
3590 "Match IPv6 next-hop address of route\n"
3591 "IPv6 address of next hop\n")
3592{
3593 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3594}
3595
3596DEFUN (no_match_ipv6_next_hop,
3597 no_match_ipv6_next_hop_cmd,
3598 "no match ipv6 next-hop X:X::X:X",
3599 NO_STR
3600 MATCH_STR
3601 IPV6_STR
3602 "Match IPv6 next-hop address of route\n"
3603 "IPv6 address of next hop\n")
3604{
3605 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3606}
3607
3608DEFUN (match_ipv6_address_prefix_list,
3609 match_ipv6_address_prefix_list_cmd,
3610 "match ipv6 address prefix-list WORD",
3611 MATCH_STR
3612 IPV6_STR
3613 "Match address of route\n"
3614 "Match entries of prefix-lists\n"
3615 "IP prefix-list name\n")
3616{
3617 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3618}
3619
3620DEFUN (no_match_ipv6_address_prefix_list,
3621 no_match_ipv6_address_prefix_list_cmd,
3622 "no match ipv6 address prefix-list WORD",
3623 NO_STR
3624 MATCH_STR
3625 IPV6_STR
3626 "Match address of route\n"
3627 "Match entries of prefix-lists\n"
3628 "IP prefix-list name\n")
3629{
3630 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3631}
3632
3633DEFUN (set_ipv6_nexthop_global,
3634 set_ipv6_nexthop_global_cmd,
3635 "set ipv6 next-hop global X:X::X:X",
3636 SET_STR
3637 IPV6_STR
3638 "IPv6 next-hop address\n"
3639 "IPv6 global address\n"
3640 "IPv6 address of next hop\n")
3641{
3642 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3643}
3644
3645DEFUN (no_set_ipv6_nexthop_global,
3646 no_set_ipv6_nexthop_global_cmd,
3647 "no set ipv6 next-hop global",
3648 NO_STR
3649 SET_STR
3650 IPV6_STR
3651 "IPv6 next-hop address\n"
3652 "IPv6 global address\n")
3653{
3654 if (argc == 0)
3655 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3656
3657 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3658}
3659
3660ALIAS (no_set_ipv6_nexthop_global,
3661 no_set_ipv6_nexthop_global_val_cmd,
3662 "no set ipv6 next-hop global X:X::X:X",
3663 NO_STR
3664 SET_STR
3665 IPV6_STR
3666 "IPv6 next-hop address\n"
3667 "IPv6 global address\n"
3668 "IPv6 address of next hop\n")
3669
3670DEFUN (set_ipv6_nexthop_local,
3671 set_ipv6_nexthop_local_cmd,
3672 "set ipv6 next-hop local X:X::X:X",
3673 SET_STR
3674 IPV6_STR
3675 "IPv6 next-hop address\n"
3676 "IPv6 local address\n"
3677 "IPv6 address of next hop\n")
3678{
3679 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3680}
3681
3682DEFUN (no_set_ipv6_nexthop_local,
3683 no_set_ipv6_nexthop_local_cmd,
3684 "no set ipv6 next-hop local",
3685 NO_STR
3686 SET_STR
3687 IPV6_STR
3688 "IPv6 next-hop address\n"
3689 "IPv6 local address\n")
3690{
3691 if (argc == 0)
3692 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3693
3694 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3695}
3696
3697ALIAS (no_set_ipv6_nexthop_local,
3698 no_set_ipv6_nexthop_local_val_cmd,
3699 "no set ipv6 next-hop local X:X::X:X",
3700 NO_STR
3701 SET_STR
3702 IPV6_STR
3703 "IPv6 next-hop address\n"
3704 "IPv6 local address\n"
3705 "IPv6 address of next hop\n")
3706#endif /* HAVE_IPV6 */
3707
3708DEFUN (set_vpnv4_nexthop,
3709 set_vpnv4_nexthop_cmd,
3710 "set vpnv4 next-hop A.B.C.D",
3711 SET_STR
3712 "VPNv4 information\n"
3713 "VPNv4 next-hop address\n"
3714 "IP address of next hop\n")
3715{
3716 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3717}
3718
3719DEFUN (no_set_vpnv4_nexthop,
3720 no_set_vpnv4_nexthop_cmd,
3721 "no set vpnv4 next-hop",
3722 NO_STR
3723 SET_STR
3724 "VPNv4 information\n"
3725 "VPNv4 next-hop address\n")
3726{
3727 if (argc == 0)
3728 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3729
3730 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3731}
3732
3733ALIAS (no_set_vpnv4_nexthop,
3734 no_set_vpnv4_nexthop_val_cmd,
3735 "no set vpnv4 next-hop A.B.C.D",
3736 NO_STR
3737 SET_STR
3738 "VPNv4 information\n"
3739 "VPNv4 next-hop address\n"
3740 "IP address of next hop\n")
3741
3742DEFUN (set_originator_id,
3743 set_originator_id_cmd,
3744 "set originator-id A.B.C.D",
3745 SET_STR
3746 "BGP originator ID attribute\n"
3747 "IP address of originator\n")
3748{
3749 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3750}
3751
3752DEFUN (no_set_originator_id,
3753 no_set_originator_id_cmd,
3754 "no set originator-id",
3755 NO_STR
3756 SET_STR
3757 "BGP originator ID attribute\n")
3758{
3759 if (argc == 0)
3760 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3761
3762 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3763}
3764
3765ALIAS (no_set_originator_id,
3766 no_set_originator_id_val_cmd,
3767 "no set originator-id A.B.C.D",
3768 NO_STR
3769 SET_STR
3770 "BGP originator ID attribute\n"
3771 "IP address of originator\n")
3772
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003773DEFUN_DEPRECATED (set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003774 set_pathlimit_ttl_cmd,
3775 "set pathlimit ttl <1-255>",
3776 SET_STR
3777 "BGP AS-Pathlimit attribute\n"
3778 "Set AS-Path Hop-count TTL\n")
3779{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003780 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003781}
3782
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003783DEFUN_DEPRECATED (no_set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003784 no_set_pathlimit_ttl_cmd,
3785 "no set pathlimit ttl",
3786 NO_STR
3787 SET_STR
3788 "BGP AS-Pathlimit attribute\n"
3789 "Set AS-Path Hop-count TTL\n")
3790{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003791 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003792}
3793
3794ALIAS (no_set_pathlimit_ttl,
3795 no_set_pathlimit_ttl_val_cmd,
3796 "no set pathlimit ttl <1-255>",
3797 NO_STR
3798 MATCH_STR
3799 "BGP AS-Pathlimit attribute\n"
3800 "Set AS-Path Hop-count TTL\n")
3801
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003802DEFUN_DEPRECATED (match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003803 match_pathlimit_as_cmd,
3804 "match pathlimit as <1-65535>",
3805 MATCH_STR
3806 "BGP AS-Pathlimit attribute\n"
3807 "Match Pathlimit AS number\n")
3808{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003809 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003810}
3811
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003812DEFUN_DEPRECATED (no_match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003813 no_match_pathlimit_as_cmd,
3814 "no match pathlimit as",
3815 NO_STR
3816 MATCH_STR
3817 "BGP AS-Pathlimit attribute\n"
3818 "Match Pathlimit AS number\n")
3819{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003820 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003821}
3822
3823ALIAS (no_match_pathlimit_as,
3824 no_match_pathlimit_as_val_cmd,
3825 "no match pathlimit as <1-65535>",
3826 NO_STR
3827 MATCH_STR
3828 "BGP AS-Pathlimit attribute\n"
3829 "Match Pathlimit ASN\n")
3830
paul718e3742002-12-13 20:15:29 +00003831
3832/* Initialization of route map. */
3833void
paul94f2b392005-06-28 12:44:16 +00003834bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003835{
3836 route_map_init ();
3837 route_map_init_vty ();
3838 route_map_add_hook (bgp_route_map_update);
3839 route_map_delete_hook (bgp_route_map_update);
3840
paulfee0f4c2004-09-13 05:12:46 +00003841 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003842 route_map_install_match (&route_match_ip_address_cmd);
3843 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003844 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003845 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3846 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003847 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003848 route_map_install_match (&route_match_aspath_cmd);
3849 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003850 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003851 route_map_install_match (&route_match_metric_cmd);
3852 route_map_install_match (&route_match_origin_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003853 route_map_install_match (&route_match_probability_cmd);
paul718e3742002-12-13 20:15:29 +00003854
3855 route_map_install_set (&route_set_ip_nexthop_cmd);
3856 route_map_install_set (&route_set_local_pref_cmd);
3857 route_map_install_set (&route_set_weight_cmd);
3858 route_map_install_set (&route_set_metric_cmd);
3859 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003860 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003861 route_map_install_set (&route_set_origin_cmd);
3862 route_map_install_set (&route_set_atomic_aggregate_cmd);
3863 route_map_install_set (&route_set_aggregator_as_cmd);
3864 route_map_install_set (&route_set_community_cmd);
3865 route_map_install_set (&route_set_community_delete_cmd);
3866 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3867 route_map_install_set (&route_set_originator_id_cmd);
3868 route_map_install_set (&route_set_ecommunity_rt_cmd);
3869 route_map_install_set (&route_set_ecommunity_soo_cmd);
3870
paulfee0f4c2004-09-13 05:12:46 +00003871 install_element (RMAP_NODE, &match_peer_cmd);
3872 install_element (RMAP_NODE, &match_peer_local_cmd);
3873 install_element (RMAP_NODE, &no_match_peer_cmd);
3874 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3875 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003876 install_element (RMAP_NODE, &match_ip_address_cmd);
3877 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3878 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3879 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3880 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3881 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003882 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3883 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3884 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003885 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3886 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3887 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3888 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3889 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3890 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003891 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3892 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3893 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003894
3895 install_element (RMAP_NODE, &match_aspath_cmd);
3896 install_element (RMAP_NODE, &no_match_aspath_cmd);
3897 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3898 install_element (RMAP_NODE, &match_metric_cmd);
3899 install_element (RMAP_NODE, &no_match_metric_cmd);
3900 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3901 install_element (RMAP_NODE, &match_community_cmd);
3902 install_element (RMAP_NODE, &match_community_exact_cmd);
3903 install_element (RMAP_NODE, &no_match_community_cmd);
3904 install_element (RMAP_NODE, &no_match_community_val_cmd);
3905 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003906 install_element (RMAP_NODE, &match_ecommunity_cmd);
3907 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3908 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003909 install_element (RMAP_NODE, &match_origin_cmd);
3910 install_element (RMAP_NODE, &no_match_origin_cmd);
3911 install_element (RMAP_NODE, &no_match_origin_val_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003912 install_element (RMAP_NODE, &match_probability_cmd);
3913 install_element (RMAP_NODE, &no_match_probability_cmd);
3914 install_element (RMAP_NODE, &no_match_probability_val_cmd);
paul718e3742002-12-13 20:15:29 +00003915
3916 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003917 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003918 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3919 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3920 install_element (RMAP_NODE, &set_local_pref_cmd);
3921 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3922 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3923 install_element (RMAP_NODE, &set_weight_cmd);
3924 install_element (RMAP_NODE, &no_set_weight_cmd);
3925 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3926 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003927 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003928 install_element (RMAP_NODE, &no_set_metric_cmd);
3929 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3930 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003931 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003932 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3933 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003934 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
3935 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00003936 install_element (RMAP_NODE, &set_origin_cmd);
3937 install_element (RMAP_NODE, &no_set_origin_cmd);
3938 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3939 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3940 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3941 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3942 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3943 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3944 install_element (RMAP_NODE, &set_community_cmd);
3945 install_element (RMAP_NODE, &set_community_none_cmd);
3946 install_element (RMAP_NODE, &no_set_community_cmd);
3947 install_element (RMAP_NODE, &no_set_community_val_cmd);
3948 install_element (RMAP_NODE, &no_set_community_none_cmd);
3949 install_element (RMAP_NODE, &set_community_delete_cmd);
3950 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3951 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3952 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3953 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3954 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3955 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3956 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3957 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3958 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3959 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3960 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3961 install_element (RMAP_NODE, &set_originator_id_cmd);
3962 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3963 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3964
3965#ifdef HAVE_IPV6
3966 route_map_install_match (&route_match_ipv6_address_cmd);
3967 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3968 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3969 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3970 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Paul Jakma41367172007-08-06 15:24:51 +00003971
paul718e3742002-12-13 20:15:29 +00003972 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3973 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3974 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3975 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3976 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3977 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3978 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3979 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3980 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3981 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3982 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3983 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3984#endif /* HAVE_IPV6 */
Paul Jakma41367172007-08-06 15:24:51 +00003985
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003986 /* AS-Pathlimit: functionality removed, commands kept for
3987 * compatibility.
3988 */
Paul Jakma41367172007-08-06 15:24:51 +00003989 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
3990 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
3991 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
3992 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
3993 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
3994 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00003995}