blob: fa645ac41139a8c8ec2ad461b4c10ca2ff2d5c34 [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
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +0200175 ret = str2sockunion (strcmp(arg, "local") ? arg : "0.0.0.0", su);
paulfee0f4c2004-09-13 05:12:46 +0000176 if (ret < 0) {
177 XFREE (MTYPE_ROUTE_MAP_COMPILED, su);
178 return NULL;
179 }
180
181 return su;
182}
183
184/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000185static void
paulfee0f4c2004-09-13 05:12:46 +0000186route_match_peer_free (void *rule)
187{
188 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
189}
190
191/* Route map commands for ip address matching. */
192struct route_map_rule_cmd route_match_peer_cmd =
193{
194 "peer",
195 route_match_peer,
196 route_match_peer_compile,
197 route_match_peer_free
198};
199
paul718e3742002-12-13 20:15:29 +0000200/* `match ip address IP_ACCESS_LIST' */
201
202/* Match function should return 1 if match is success else return
203 zero. */
paul94f2b392005-06-28 12:44:16 +0000204static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000205route_match_ip_address (void *rule, struct prefix *prefix,
206 route_map_object_t type, void *object)
207{
208 struct access_list *alist;
209 /* struct prefix_ipv4 match; */
210
211 if (type == RMAP_BGP)
212 {
213 alist = access_list_lookup (AFI_IP, (char *) rule);
214 if (alist == NULL)
215 return RMAP_NOMATCH;
216
217 return (access_list_apply (alist, prefix) == FILTER_DENY ?
218 RMAP_NOMATCH : RMAP_MATCH);
219 }
220 return RMAP_NOMATCH;
221}
222
223/* Route map `ip address' match statement. `arg' should be
224 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000225static void *
paulfd79ac92004-10-13 05:06:08 +0000226route_match_ip_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000227{
228 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
229}
230
231/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000232static void
paul718e3742002-12-13 20:15:29 +0000233route_match_ip_address_free (void *rule)
234{
235 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
236}
237
238/* Route map commands for ip address matching. */
239struct route_map_rule_cmd route_match_ip_address_cmd =
240{
241 "ip address",
242 route_match_ip_address,
243 route_match_ip_address_compile,
244 route_match_ip_address_free
245};
246
247/* `match ip next-hop IP_ADDRESS' */
248
249/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000250static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000251route_match_ip_next_hop (void *rule, struct prefix *prefix,
252 route_map_object_t type, void *object)
253{
254 struct access_list *alist;
255 struct bgp_info *bgp_info;
256 struct prefix_ipv4 p;
257
258 if (type == RMAP_BGP)
259 {
260 bgp_info = object;
261 p.family = AF_INET;
262 p.prefix = bgp_info->attr->nexthop;
263 p.prefixlen = IPV4_MAX_BITLEN;
264
265 alist = access_list_lookup (AFI_IP, (char *) rule);
266 if (alist == NULL)
267 return RMAP_NOMATCH;
268
269 return (access_list_apply (alist, &p) == FILTER_DENY ?
270 RMAP_NOMATCH : RMAP_MATCH);
271 }
272 return RMAP_NOMATCH;
273}
274
275/* Route map `ip next-hop' match statement. `arg' is
276 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000277static void *
paulfd79ac92004-10-13 05:06:08 +0000278route_match_ip_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000279{
280 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
281}
282
283/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000284static void
paul718e3742002-12-13 20:15:29 +0000285route_match_ip_next_hop_free (void *rule)
286{
287 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
288}
289
290/* Route map commands for ip next-hop matching. */
291struct route_map_rule_cmd route_match_ip_next_hop_cmd =
292{
293 "ip next-hop",
294 route_match_ip_next_hop,
295 route_match_ip_next_hop_compile,
296 route_match_ip_next_hop_free
297};
298
hassoc1643bb2005-02-02 16:43:17 +0000299/* `match ip route-source ACCESS-LIST' */
300
301/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000302static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000303route_match_ip_route_source (void *rule, struct prefix *prefix,
304 route_map_object_t type, void *object)
305{
306 struct access_list *alist;
307 struct bgp_info *bgp_info;
308 struct peer *peer;
309 struct prefix_ipv4 p;
310
311 if (type == RMAP_BGP)
312 {
313 bgp_info = object;
314 peer = bgp_info->peer;
315
316 if (! peer || sockunion_family (&peer->su) != AF_INET)
317 return RMAP_NOMATCH;
318
319 p.family = AF_INET;
320 p.prefix = peer->su.sin.sin_addr;
321 p.prefixlen = IPV4_MAX_BITLEN;
322
323 alist = access_list_lookup (AFI_IP, (char *) rule);
324 if (alist == NULL)
325 return RMAP_NOMATCH;
326
327 return (access_list_apply (alist, &p) == FILTER_DENY ?
328 RMAP_NOMATCH : RMAP_MATCH);
329 }
330 return RMAP_NOMATCH;
331}
332
333/* Route map `ip route-source' match statement. `arg' is
334 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000335static void *
hassoc1643bb2005-02-02 16:43:17 +0000336route_match_ip_route_source_compile (const char *arg)
337{
338 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
339}
340
341/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000342static void
hassoc1643bb2005-02-02 16:43:17 +0000343route_match_ip_route_source_free (void *rule)
344{
345 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
346}
347
348/* Route map commands for ip route-source matching. */
349struct route_map_rule_cmd route_match_ip_route_source_cmd =
350{
351 "ip route-source",
352 route_match_ip_route_source,
353 route_match_ip_route_source_compile,
354 route_match_ip_route_source_free
355};
356
paul718e3742002-12-13 20:15:29 +0000357/* `match ip address prefix-list PREFIX_LIST' */
358
paul94f2b392005-06-28 12:44:16 +0000359static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000360route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
361 route_map_object_t type, void *object)
362{
363 struct prefix_list *plist;
364
365 if (type == RMAP_BGP)
366 {
367 plist = prefix_list_lookup (AFI_IP, (char *) rule);
368 if (plist == NULL)
369 return RMAP_NOMATCH;
370
371 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
372 RMAP_NOMATCH : RMAP_MATCH);
373 }
374 return RMAP_NOMATCH;
375}
376
paul94f2b392005-06-28 12:44:16 +0000377static void *
paulfd79ac92004-10-13 05:06:08 +0000378route_match_ip_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000379{
380 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
381}
382
paul94f2b392005-06-28 12:44:16 +0000383static void
paul718e3742002-12-13 20:15:29 +0000384route_match_ip_address_prefix_list_free (void *rule)
385{
386 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
387}
388
389struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
390{
391 "ip address prefix-list",
392 route_match_ip_address_prefix_list,
393 route_match_ip_address_prefix_list_compile,
394 route_match_ip_address_prefix_list_free
395};
396
397/* `match ip next-hop prefix-list PREFIX_LIST' */
398
paul94f2b392005-06-28 12:44:16 +0000399static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000400route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
401 route_map_object_t type, void *object)
402{
403 struct prefix_list *plist;
404 struct bgp_info *bgp_info;
405 struct prefix_ipv4 p;
406
407 if (type == RMAP_BGP)
408 {
409 bgp_info = object;
410 p.family = AF_INET;
411 p.prefix = bgp_info->attr->nexthop;
412 p.prefixlen = IPV4_MAX_BITLEN;
413
414 plist = prefix_list_lookup (AFI_IP, (char *) rule);
415 if (plist == NULL)
416 return RMAP_NOMATCH;
417
418 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
419 RMAP_NOMATCH : RMAP_MATCH);
420 }
421 return RMAP_NOMATCH;
422}
423
paul94f2b392005-06-28 12:44:16 +0000424static void *
paulfd79ac92004-10-13 05:06:08 +0000425route_match_ip_next_hop_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000426{
427 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
428}
429
paul94f2b392005-06-28 12:44:16 +0000430static void
paul718e3742002-12-13 20:15:29 +0000431route_match_ip_next_hop_prefix_list_free (void *rule)
432{
433 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
434}
435
436struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
437{
438 "ip next-hop prefix-list",
439 route_match_ip_next_hop_prefix_list,
440 route_match_ip_next_hop_prefix_list_compile,
441 route_match_ip_next_hop_prefix_list_free
442};
443
hassoc1643bb2005-02-02 16:43:17 +0000444/* `match ip route-source prefix-list PREFIX_LIST' */
445
paul94f2b392005-06-28 12:44:16 +0000446static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000447route_match_ip_route_source_prefix_list (void *rule, struct prefix *prefix,
448 route_map_object_t type, void *object)
449{
450 struct prefix_list *plist;
451 struct bgp_info *bgp_info;
452 struct peer *peer;
453 struct prefix_ipv4 p;
454
455 if (type == RMAP_BGP)
456 {
457 bgp_info = object;
458 peer = bgp_info->peer;
459
460 if (! peer || sockunion_family (&peer->su) != AF_INET)
461 return RMAP_NOMATCH;
462
463 p.family = AF_INET;
464 p.prefix = peer->su.sin.sin_addr;
465 p.prefixlen = IPV4_MAX_BITLEN;
466
467 plist = prefix_list_lookup (AFI_IP, (char *) rule);
468 if (plist == NULL)
469 return RMAP_NOMATCH;
470
471 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
472 RMAP_NOMATCH : RMAP_MATCH);
473 }
474 return RMAP_NOMATCH;
475}
476
paul94f2b392005-06-28 12:44:16 +0000477static void *
hassoc1643bb2005-02-02 16:43:17 +0000478route_match_ip_route_source_prefix_list_compile (const char *arg)
479{
480 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
481}
482
paul94f2b392005-06-28 12:44:16 +0000483static void
hassoc1643bb2005-02-02 16:43:17 +0000484route_match_ip_route_source_prefix_list_free (void *rule)
485{
486 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
487}
488
489struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd =
490{
491 "ip route-source prefix-list",
492 route_match_ip_route_source_prefix_list,
493 route_match_ip_route_source_prefix_list_compile,
494 route_match_ip_route_source_prefix_list_free
495};
496
paul718e3742002-12-13 20:15:29 +0000497/* `match metric METRIC' */
498
499/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000500static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000501route_match_metric (void *rule, struct prefix *prefix,
502 route_map_object_t type, void *object)
503{
504 u_int32_t *med;
505 struct bgp_info *bgp_info;
506
507 if (type == RMAP_BGP)
508 {
509 med = rule;
510 bgp_info = object;
511
512 if (bgp_info->attr->med == *med)
513 return RMAP_MATCH;
514 else
515 return RMAP_NOMATCH;
516 }
517 return RMAP_NOMATCH;
518}
519
520/* Route map `match metric' match statement. `arg' is MED value */
paul94f2b392005-06-28 12:44:16 +0000521static void *
paulfd79ac92004-10-13 05:06:08 +0000522route_match_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000523{
524 u_int32_t *med;
525 char *endptr = NULL;
paul3b424972003-10-13 09:47:32 +0000526 unsigned long tmpval;
paul718e3742002-12-13 20:15:29 +0000527
Ulrich Weber664711c2011-12-21 02:24:11 +0400528 /* Metric value shoud be integer. */
529 if (! all_digit (arg))
530 return NULL;
531
532 errno = 0;
paul3b424972003-10-13 09:47:32 +0000533 tmpval = strtoul (arg, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +0400534 if (*endptr != '\0' || errno || tmpval > UINT32_MAX)
paul3b424972003-10-13 09:47:32 +0000535 return NULL;
paulfd79ac92004-10-13 05:06:08 +0000536
paul718e3742002-12-13 20:15:29 +0000537 med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +0000538
539 if (!med)
540 return med;
541
paul3b424972003-10-13 09:47:32 +0000542 *med = tmpval;
paul718e3742002-12-13 20:15:29 +0000543 return med;
544}
545
546/* Free route map's compiled `match metric' value. */
paul94f2b392005-06-28 12:44:16 +0000547static void
paul718e3742002-12-13 20:15:29 +0000548route_match_metric_free (void *rule)
549{
550 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
551}
552
553/* Route map commands for metric matching. */
554struct route_map_rule_cmd route_match_metric_cmd =
555{
556 "metric",
557 route_match_metric,
558 route_match_metric_compile,
559 route_match_metric_free
560};
561
562/* `match as-path ASPATH' */
563
564/* Match function for as-path match. I assume given object is */
paul94f2b392005-06-28 12:44:16 +0000565static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000566route_match_aspath (void *rule, struct prefix *prefix,
567 route_map_object_t type, void *object)
568{
569
570 struct as_list *as_list;
571 struct bgp_info *bgp_info;
572
573 if (type == RMAP_BGP)
574 {
575 as_list = as_list_lookup ((char *) rule);
576 if (as_list == NULL)
577 return RMAP_NOMATCH;
578
579 bgp_info = object;
580
581 /* Perform match. */
582 return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
583 }
584 return RMAP_NOMATCH;
585}
586
587/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000588static void *
paulfd79ac92004-10-13 05:06:08 +0000589route_match_aspath_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000590{
591 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
592}
593
594/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000595static void
paul718e3742002-12-13 20:15:29 +0000596route_match_aspath_free (void *rule)
597{
598 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
599}
600
601/* Route map commands for aspath matching. */
602struct route_map_rule_cmd route_match_aspath_cmd =
603{
604 "as-path",
605 route_match_aspath,
606 route_match_aspath_compile,
607 route_match_aspath_free
608};
paul718e3742002-12-13 20:15:29 +0000609
610/* `match community COMMUNIY' */
611struct rmap_community
612{
613 char *name;
614 int exact;
615};
616
617/* Match function for community match. */
paul94f2b392005-06-28 12:44:16 +0000618static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000619route_match_community (void *rule, struct prefix *prefix,
620 route_map_object_t type, void *object)
621{
622 struct community_list *list;
623 struct bgp_info *bgp_info;
624 struct rmap_community *rcom;
625
626 if (type == RMAP_BGP)
627 {
628 bgp_info = object;
629 rcom = rule;
630
hassofee6e4e2005-02-02 16:29:31 +0000631 list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +0000632 if (! list)
633 return RMAP_NOMATCH;
634
635 if (rcom->exact)
636 {
637 if (community_list_exact_match (bgp_info->attr->community, list))
638 return RMAP_MATCH;
639 }
640 else
641 {
642 if (community_list_match (bgp_info->attr->community, list))
643 return RMAP_MATCH;
644 }
645 }
646 return RMAP_NOMATCH;
647}
648
649/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000650static void *
paulfd79ac92004-10-13 05:06:08 +0000651route_match_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000652{
653 struct rmap_community *rcom;
654 int len;
655 char *p;
656
657 rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
658
659 p = strchr (arg, ' ');
660 if (p)
661 {
662 len = p - arg;
663 rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
664 memcpy (rcom->name, arg, len);
665 rcom->exact = 1;
666 }
667 else
668 {
669 rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
670 rcom->exact = 0;
671 }
672 return rcom;
673}
674
675/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000676static void
paul718e3742002-12-13 20:15:29 +0000677route_match_community_free (void *rule)
678{
679 struct rmap_community *rcom = rule;
680
681 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
682 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
683}
684
685/* Route map commands for community matching. */
686struct route_map_rule_cmd route_match_community_cmd =
687{
688 "community",
689 route_match_community,
690 route_match_community_compile,
691 route_match_community_free
692};
693
paul73ffb252003-04-19 15:49:49 +0000694/* Match function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000695static route_map_result_t
paul73ffb252003-04-19 15:49:49 +0000696route_match_ecommunity (void *rule, struct prefix *prefix,
697 route_map_object_t type, void *object)
698{
699 struct community_list *list;
700 struct bgp_info *bgp_info;
701
702 if (type == RMAP_BGP)
703 {
704 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +0000705
706 if (!bgp_info->attr->extra)
707 return RMAP_NOMATCH;
708
paul73ffb252003-04-19 15:49:49 +0000709 list = community_list_lookup (bgp_clist, (char *) rule,
hassofee6e4e2005-02-02 16:29:31 +0000710 EXTCOMMUNITY_LIST_MASTER);
paul73ffb252003-04-19 15:49:49 +0000711 if (! list)
712 return RMAP_NOMATCH;
713
Paul Jakmafb982c22007-05-04 20:15:47 +0000714 if (ecommunity_list_match (bgp_info->attr->extra->ecommunity, list))
paul73ffb252003-04-19 15:49:49 +0000715 return RMAP_MATCH;
716 }
717 return RMAP_NOMATCH;
718}
719
720/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000721static void *
paulfd79ac92004-10-13 05:06:08 +0000722route_match_ecommunity_compile (const char *arg)
paul73ffb252003-04-19 15:49:49 +0000723{
724 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
725}
726
727/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000728static void
paul73ffb252003-04-19 15:49:49 +0000729route_match_ecommunity_free (void *rule)
730{
731 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
732}
733
734/* Route map commands for community matching. */
735struct route_map_rule_cmd route_match_ecommunity_cmd =
736{
737 "extcommunity",
738 route_match_ecommunity,
739 route_match_ecommunity_compile,
740 route_match_ecommunity_free
741};
742
paul718e3742002-12-13 20:15:29 +0000743/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
744 and `address-family vpnv4'. */
745
746/* `match origin' */
paul94f2b392005-06-28 12:44:16 +0000747static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000748route_match_origin (void *rule, struct prefix *prefix,
749 route_map_object_t type, void *object)
750{
751 u_char *origin;
752 struct bgp_info *bgp_info;
753
754 if (type == RMAP_BGP)
755 {
756 origin = rule;
757 bgp_info = object;
758
759 if (bgp_info->attr->origin == *origin)
760 return RMAP_MATCH;
761 }
762
763 return RMAP_NOMATCH;
764}
765
paul94f2b392005-06-28 12:44:16 +0000766static void *
paulfd79ac92004-10-13 05:06:08 +0000767route_match_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000768{
769 u_char *origin;
770
771 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
772
773 if (strcmp (arg, "igp") == 0)
774 *origin = 0;
775 else if (strcmp (arg, "egp") == 0)
776 *origin = 1;
777 else
778 *origin = 2;
779
780 return origin;
781}
782
783/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000784static void
paul718e3742002-12-13 20:15:29 +0000785route_match_origin_free (void *rule)
786{
787 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
788}
789
790/* Route map commands for origin matching. */
791struct route_map_rule_cmd route_match_origin_cmd =
792{
793 "origin",
794 route_match_origin,
795 route_match_origin_compile,
796 route_match_origin_free
797};
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400798
799/* match probability { */
800
801static route_map_result_t
802route_match_probability (void *rule, struct prefix *prefix,
803 route_map_object_t type, void *object)
804{
805 long r;
806#if _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500
807 r = random();
808#else
809 r = (long) rand();
810#endif
811
812 switch (*(unsigned *) rule)
813 {
814 case 0: break;
815 case RAND_MAX: return RMAP_MATCH;
816 default:
817 if (r < *(unsigned *) rule)
818 {
819 return RMAP_MATCH;
820 }
821 }
822
823 return RMAP_NOMATCH;
824}
825
826static void *
827route_match_probability_compile (const char *arg)
828{
829 unsigned *lobule;
830 unsigned perc;
831
832#if _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500
833 srandom (time (NULL));
834#else
835 srand (time (NULL));
836#endif
837
838 perc = atoi (arg);
839 lobule = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (unsigned));
840
841 switch (perc)
842 {
843 case 0: *lobule = 0; break;
844 case 100: *lobule = RAND_MAX; break;
845 default: *lobule = RAND_MAX / 100 * perc;
846 }
847
848 return lobule;
849}
850
851static void
852route_match_probability_free (void *rule)
853{
854 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
855}
856
857struct route_map_rule_cmd route_match_probability_cmd =
858{
859 "probability",
860 route_match_probability,
861 route_match_probability_compile,
862 route_match_probability_free
863};
864
865/* } */
866
paul718e3742002-12-13 20:15:29 +0000867/* `set ip next-hop IP_ADDRESS' */
868
869/* Set nexthop to object. ojbect must be pointer to struct attr. */
paulac41b2a2003-08-12 05:32:27 +0000870struct rmap_ip_nexthop_set
871{
872 struct in_addr *address;
873 int peer_address;
874};
875
paul94f2b392005-06-28 12:44:16 +0000876static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000877route_set_ip_nexthop (void *rule, struct prefix *prefix,
878 route_map_object_t type, void *object)
879{
paulac41b2a2003-08-12 05:32:27 +0000880 struct rmap_ip_nexthop_set *rins = rule;
paul718e3742002-12-13 20:15:29 +0000881 struct bgp_info *bgp_info;
paulac41b2a2003-08-12 05:32:27 +0000882 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000883
884 if (type == RMAP_BGP)
885 {
paul718e3742002-12-13 20:15:29 +0000886 bgp_info = object;
paulac41b2a2003-08-12 05:32:27 +0000887 peer = bgp_info->peer;
888
889 if (rins->peer_address)
890 {
paulfee0f4c2004-09-13 05:12:46 +0000891 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
892 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
paulac41b2a2003-08-12 05:32:27 +0000893 && peer->su_remote
894 && sockunion_family (peer->su_remote) == AF_INET)
895 {
Jorge Boncompte [DTI2]0c5ed3e2012-04-10 16:57:22 +0200896 bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote);
paulac41b2a2003-08-12 05:32:27 +0000897 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
898 }
899 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
900 && peer->su_local
901 && sockunion_family (peer->su_local) == AF_INET)
902 {
Jorge Boncompte [DTI2]0c5ed3e2012-04-10 16:57:22 +0200903 bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_local);
paulac41b2a2003-08-12 05:32:27 +0000904 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
905 }
906 }
907 else
908 {
909 /* Set next hop value. */
910 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
911 bgp_info->attr->nexthop = *rins->address;
912 }
paul718e3742002-12-13 20:15:29 +0000913 }
914
915 return RMAP_OKAY;
916}
917
918/* Route map `ip nexthop' compile function. Given string is converted
919 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +0000920static void *
paulfd79ac92004-10-13 05:06:08 +0000921route_set_ip_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000922{
paulac41b2a2003-08-12 05:32:27 +0000923 struct rmap_ip_nexthop_set *rins;
924 struct in_addr *address = NULL;
925 int peer_address = 0;
paul718e3742002-12-13 20:15:29 +0000926 int ret;
paul718e3742002-12-13 20:15:29 +0000927
paulac41b2a2003-08-12 05:32:27 +0000928 if (strcmp (arg, "peer-address") == 0)
929 peer_address = 1;
930 else
paul718e3742002-12-13 20:15:29 +0000931 {
paulac41b2a2003-08-12 05:32:27 +0000932 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
933 ret = inet_aton (arg, address);
934
935 if (ret == 0)
936 {
937 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
938 return NULL;
939 }
paul718e3742002-12-13 20:15:29 +0000940 }
941
Stephen Hemminger393deb92008-08-18 14:13:29 -0700942 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
paulac41b2a2003-08-12 05:32:27 +0000943
944 rins->address = address;
945 rins->peer_address = peer_address;
946
947 return rins;
paul718e3742002-12-13 20:15:29 +0000948}
949
950/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +0000951static void
paul718e3742002-12-13 20:15:29 +0000952route_set_ip_nexthop_free (void *rule)
953{
paulac41b2a2003-08-12 05:32:27 +0000954 struct rmap_ip_nexthop_set *rins = rule;
955
956 if (rins->address)
957 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
958
959 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +0000960}
961
962/* Route map commands for ip nexthop set. */
963struct route_map_rule_cmd route_set_ip_nexthop_cmd =
964{
965 "ip next-hop",
966 route_set_ip_nexthop,
967 route_set_ip_nexthop_compile,
968 route_set_ip_nexthop_free
969};
970
971/* `set local-preference LOCAL_PREF' */
972
973/* Set local preference. */
paul94f2b392005-06-28 12:44:16 +0000974static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000975route_set_local_pref (void *rule, struct prefix *prefix,
976 route_map_object_t type, void *object)
977{
978 u_int32_t *local_pref;
979 struct bgp_info *bgp_info;
980
981 if (type == RMAP_BGP)
982 {
983 /* Fetch routemap's rule information. */
984 local_pref = rule;
985 bgp_info = object;
986
987 /* Set local preference value. */
988 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
989 bgp_info->attr->local_pref = *local_pref;
990 }
991
992 return RMAP_OKAY;
993}
994
995/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +0000996static void *
paulfd79ac92004-10-13 05:06:08 +0000997route_set_local_pref_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000998{
paulfd79ac92004-10-13 05:06:08 +0000999 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +00001000 u_int32_t *local_pref;
1001 char *endptr = NULL;
1002
1003 /* Local preference value shoud be integer. */
1004 if (! all_digit (arg))
1005 return NULL;
paulfd79ac92004-10-13 05:06:08 +00001006
Ulrich Weber664711c2011-12-21 02:24:11 +04001007 errno = 0;
paulfd79ac92004-10-13 05:06:08 +00001008 tmp = strtoul (arg, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +04001009 if (*endptr != '\0' || errno || tmp > UINT32_MAX)
paulfd79ac92004-10-13 05:06:08 +00001010 return NULL;
1011
1012 local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
1013
1014 if (!local_pref)
1015 return local_pref;
1016
1017 *local_pref = tmp;
1018
paul718e3742002-12-13 20:15:29 +00001019 return local_pref;
1020}
1021
1022/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +00001023static void
paul718e3742002-12-13 20:15:29 +00001024route_set_local_pref_free (void *rule)
1025{
1026 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1027}
1028
1029/* Set local preference rule structure. */
1030struct route_map_rule_cmd route_set_local_pref_cmd =
1031{
1032 "local-preference",
1033 route_set_local_pref,
1034 route_set_local_pref_compile,
1035 route_set_local_pref_free,
1036};
1037
1038/* `set weight WEIGHT' */
1039
1040/* Set weight. */
paul94f2b392005-06-28 12:44:16 +00001041static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001042route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
1043 void *object)
1044{
1045 u_int32_t *weight;
1046 struct bgp_info *bgp_info;
1047
1048 if (type == RMAP_BGP)
1049 {
1050 /* Fetch routemap's rule information. */
1051 weight = rule;
1052 bgp_info = object;
1053
1054 /* Set weight value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001055 if (*weight)
1056 (bgp_attr_extra_get (bgp_info->attr))->weight = *weight;
1057 else if (bgp_info->attr->extra)
1058 bgp_info->attr->extra->weight = 0;
paul718e3742002-12-13 20:15:29 +00001059 }
1060
1061 return RMAP_OKAY;
1062}
1063
1064/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +00001065static void *
paulfd79ac92004-10-13 05:06:08 +00001066route_set_weight_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001067{
paulfd79ac92004-10-13 05:06:08 +00001068 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +00001069 u_int32_t *weight;
1070 char *endptr = NULL;
1071
1072 /* Local preference value shoud be integer. */
1073 if (! all_digit (arg))
1074 return NULL;
1075
Ulrich Weber664711c2011-12-21 02:24:11 +04001076 errno = 0;
paulfd79ac92004-10-13 05:06:08 +00001077 tmp = strtoul (arg, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +04001078 if (*endptr != '\0' || errno || tmp > UINT32_MAX)
paulfd79ac92004-10-13 05:06:08 +00001079 return NULL;
1080
paul718e3742002-12-13 20:15:29 +00001081 weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +00001082
1083 if (weight == NULL)
1084 return weight;
1085
1086 *weight = tmp;
1087
paul718e3742002-12-13 20:15:29 +00001088 return weight;
1089}
1090
1091/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +00001092static void
paul718e3742002-12-13 20:15:29 +00001093route_set_weight_free (void *rule)
1094{
1095 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1096}
1097
1098/* Set local preference rule structure. */
1099struct route_map_rule_cmd route_set_weight_cmd =
1100{
1101 "weight",
1102 route_set_weight,
1103 route_set_weight_compile,
1104 route_set_weight_free,
1105};
1106
1107/* `set metric METRIC' */
1108
1109/* Set metric to attribute. */
paul94f2b392005-06-28 12:44:16 +00001110static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001111route_set_metric (void *rule, struct prefix *prefix,
1112 route_map_object_t type, void *object)
1113{
1114 char *metric;
1115 u_int32_t metric_val;
1116 struct bgp_info *bgp_info;
1117
1118 if (type == RMAP_BGP)
1119 {
1120 /* Fetch routemap's rule information. */
1121 metric = rule;
1122 bgp_info = object;
1123
1124 if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
1125 bgp_info->attr->med = 0;
1126 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
1127
1128 if (all_digit (metric))
1129 {
1130 metric_val = strtoul (metric, (char **)NULL, 10);
1131 bgp_info->attr->med = metric_val;
1132 }
1133 else
1134 {
1135 metric_val = strtoul (metric+1, (char **)NULL, 10);
1136
1137 if (strncmp (metric, "+", 1) == 0)
1138 {
paul3b424972003-10-13 09:47:32 +00001139 if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2)
1140 bgp_info->attr->med = BGP_MED_MAX - 1;
paul718e3742002-12-13 20:15:29 +00001141 else
paul537d8ea2003-08-27 06:45:32 +00001142 bgp_info->attr->med += metric_val;
paul718e3742002-12-13 20:15:29 +00001143 }
1144 else if (strncmp (metric, "-", 1) == 0)
1145 {
paul537d8ea2003-08-27 06:45:32 +00001146 if (bgp_info->attr->med <= metric_val)
1147 bgp_info->attr->med = 0;
paul718e3742002-12-13 20:15:29 +00001148 else
paul537d8ea2003-08-27 06:45:32 +00001149 bgp_info->attr->med -= metric_val;
paul718e3742002-12-13 20:15:29 +00001150 }
1151 }
1152 }
1153 return RMAP_OKAY;
1154}
1155
1156/* set metric compilation. */
paul94f2b392005-06-28 12:44:16 +00001157static void *
paulfd79ac92004-10-13 05:06:08 +00001158route_set_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001159{
1160 u_int32_t metric;
paul94f2b392005-06-28 12:44:16 +00001161 unsigned long larg;
paul718e3742002-12-13 20:15:29 +00001162 char *endptr = NULL;
1163
1164 if (all_digit (arg))
1165 {
1166 /* set metric value check*/
Ulrich Weber664711c2011-12-21 02:24:11 +04001167 errno = 0;
paul94f2b392005-06-28 12:44:16 +00001168 larg = strtoul (arg, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +04001169 if (*endptr != '\0' || errno || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001170 return NULL;
paul94f2b392005-06-28 12:44:16 +00001171 metric = larg;
paul718e3742002-12-13 20:15:29 +00001172 }
1173 else
1174 {
1175 /* set metric +/-value check */
1176 if ((strncmp (arg, "+", 1) != 0
1177 && strncmp (arg, "-", 1) != 0)
1178 || (! all_digit (arg+1)))
1179 return NULL;
1180
Ulrich Weber664711c2011-12-21 02:24:11 +04001181 errno = 0;
paul94f2b392005-06-28 12:44:16 +00001182 larg = strtoul (arg+1, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +04001183 if (*endptr != '\0' || errno || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001184 return NULL;
paul94f2b392005-06-28 12:44:16 +00001185 metric = larg;
paul718e3742002-12-13 20:15:29 +00001186 }
1187
1188 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1189}
1190
1191/* Free route map's compiled `set metric' value. */
paul94f2b392005-06-28 12:44:16 +00001192static void
paul718e3742002-12-13 20:15:29 +00001193route_set_metric_free (void *rule)
1194{
1195 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1196}
1197
1198/* Set metric rule structure. */
1199struct route_map_rule_cmd route_set_metric_cmd =
1200{
1201 "metric",
1202 route_set_metric,
1203 route_set_metric_compile,
1204 route_set_metric_free,
1205};
1206
1207/* `set as-path prepend ASPATH' */
1208
1209/* For AS path prepend mechanism. */
paul94f2b392005-06-28 12:44:16 +00001210static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001211route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1212{
1213 struct aspath *aspath;
1214 struct aspath *new;
1215 struct bgp_info *binfo;
1216
1217 if (type == RMAP_BGP)
1218 {
1219 aspath = rule;
1220 binfo = object;
1221
1222 if (binfo->attr->aspath->refcnt)
1223 new = aspath_dup (binfo->attr->aspath);
1224 else
1225 new = binfo->attr->aspath;
1226
1227 aspath_prepend (aspath, new);
1228 binfo->attr->aspath = new;
1229 }
1230
1231 return RMAP_OKAY;
1232}
1233
1234/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001235static void *
paulfd79ac92004-10-13 05:06:08 +00001236route_set_aspath_prepend_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001237{
1238 struct aspath *aspath;
1239
1240 aspath = aspath_str2aspath (arg);
1241 if (! aspath)
1242 return NULL;
1243 return aspath;
1244}
1245
1246/* Compile function for as-path prepend. */
paul94f2b392005-06-28 12:44:16 +00001247static void
paul718e3742002-12-13 20:15:29 +00001248route_set_aspath_prepend_free (void *rule)
1249{
1250 struct aspath *aspath = rule;
1251 aspath_free (aspath);
1252}
1253
1254/* Set metric rule structure. */
1255struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1256{
1257 "as-path prepend",
1258 route_set_aspath_prepend,
1259 route_set_aspath_prepend_compile,
1260 route_set_aspath_prepend_free,
1261};
1262
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001263/* `set as-path exclude ASn' */
1264
1265/* For ASN exclude mechanism.
1266 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1267 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1268 */
1269static route_map_result_t
1270route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
1271{
1272 struct aspath * new_path, * exclude_path;
1273 struct bgp_info *binfo;
1274
1275 if (type == RMAP_BGP)
1276 {
1277 exclude_path = rule;
1278 binfo = object;
1279 if (binfo->attr->aspath->refcnt)
1280 new_path = aspath_dup (binfo->attr->aspath);
1281 else
1282 new_path = binfo->attr->aspath;
1283 binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
1284 }
1285 return RMAP_OKAY;
1286}
1287
1288/* FIXME: consider using route_set_aspath_prepend_compile() and
1289 * route_set_aspath_prepend_free(), which two below function are
1290 * exact clones of.
1291 */
1292
1293/* Compile function for as-path exclude. */
1294static void *
1295route_set_aspath_exclude_compile (const char *arg)
1296{
1297 struct aspath *aspath;
1298
1299 aspath = aspath_str2aspath (arg);
1300 if (! aspath)
1301 return NULL;
1302 return aspath;
1303}
1304
1305static void
1306route_set_aspath_exclude_free (void *rule)
1307{
1308 struct aspath *aspath = rule;
1309 aspath_free (aspath);
1310}
1311
1312/* Set ASn exlude rule structure. */
1313struct route_map_rule_cmd route_set_aspath_exclude_cmd =
1314{
1315 "as-path exclude",
1316 route_set_aspath_exclude,
1317 route_set_aspath_exclude_compile,
1318 route_set_aspath_exclude_free,
1319};
1320
paul718e3742002-12-13 20:15:29 +00001321/* `set community COMMUNITY' */
1322struct rmap_com_set
1323{
1324 struct community *com;
1325 int additive;
1326 int none;
1327};
1328
1329/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001330static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001331route_set_community (void *rule, struct prefix *prefix,
1332 route_map_object_t type, void *object)
1333{
1334 struct rmap_com_set *rcs;
1335 struct bgp_info *binfo;
1336 struct attr *attr;
1337 struct community *new = NULL;
1338 struct community *old;
1339 struct community *merge;
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001340
paul718e3742002-12-13 20:15:29 +00001341 if (type == RMAP_BGP)
1342 {
1343 rcs = rule;
1344 binfo = object;
1345 attr = binfo->attr;
1346 old = attr->community;
1347
1348 /* "none" case. */
1349 if (rcs->none)
1350 {
1351 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1352 attr->community = NULL;
1353 return RMAP_OKAY;
1354 }
1355
1356 /* "additive" case. */
1357 if (rcs->additive && old)
1358 {
1359 merge = community_merge (community_dup (old), rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001360
1361 /* HACK: if the old community is not intern'd,
1362 * we should free it here, or all reference to it may be lost.
1363 * Really need to cleanup attribute caching sometime.
1364 */
1365 if (old->refcnt == 0)
1366 community_free (old);
paul718e3742002-12-13 20:15:29 +00001367 new = community_uniq_sort (merge);
1368 community_free (merge);
1369 }
1370 else
1371 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001372
1373 /* will be interned by caller if required */
Paul Jakma4a2035f2011-04-01 15:58:27 +01001374 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001375
paul718e3742002-12-13 20:15:29 +00001376 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1377 }
1378
1379 return RMAP_OKAY;
1380}
1381
1382/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001383static void *
paulfd79ac92004-10-13 05:06:08 +00001384route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001385{
1386 struct rmap_com_set *rcs;
1387 struct community *com = NULL;
1388 char *sp;
1389 int additive = 0;
1390 int none = 0;
1391
1392 if (strcmp (arg, "none") == 0)
1393 none = 1;
1394 else
1395 {
1396 sp = strstr (arg, "additive");
1397
1398 if (sp && sp > arg)
1399 {
1400 /* "additive" keyworkd is included. */
1401 additive = 1;
1402 *(sp - 1) = '\0';
1403 }
1404
1405 com = community_str2com (arg);
1406
1407 if (additive)
1408 *(sp - 1) = ' ';
1409
1410 if (! com)
1411 return NULL;
1412 }
1413
Stephen Hemminger393deb92008-08-18 14:13:29 -07001414 rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
Paul Jakma4a2035f2011-04-01 15:58:27 +01001415 rcs->com = com;
paul718e3742002-12-13 20:15:29 +00001416 rcs->additive = additive;
1417 rcs->none = none;
1418
1419 return rcs;
1420}
1421
1422/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001423static void
paul718e3742002-12-13 20:15:29 +00001424route_set_community_free (void *rule)
1425{
1426 struct rmap_com_set *rcs = rule;
1427
1428 if (rcs->com)
1429 community_free (rcs->com);
1430 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1431}
1432
1433/* Set community rule structure. */
1434struct route_map_rule_cmd route_set_community_cmd =
1435{
1436 "community",
1437 route_set_community,
1438 route_set_community_compile,
1439 route_set_community_free,
1440};
1441
hassofee6e4e2005-02-02 16:29:31 +00001442/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001443
1444/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001445static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001446route_set_community_delete (void *rule, struct prefix *prefix,
1447 route_map_object_t type, void *object)
1448{
1449 struct community_list *list;
1450 struct community *merge;
1451 struct community *new;
1452 struct community *old;
1453 struct bgp_info *binfo;
1454
1455 if (type == RMAP_BGP)
1456 {
1457 if (! rule)
1458 return RMAP_OKAY;
1459
1460 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001461 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001462 old = binfo->attr->community;
1463
1464 if (list && old)
1465 {
1466 merge = community_list_match_delete (community_dup (old), list);
1467 new = community_uniq_sort (merge);
1468 community_free (merge);
1469
Michael Lambert604a9b42010-09-13 11:48:11 -04001470 /* HACK: if the old community is not intern'd,
1471 * we should free it here, or all reference to it may be lost.
1472 * Really need to cleanup attribute caching sometime.
1473 */
1474 if (old->refcnt == 0)
1475 community_free (old);
1476
paul718e3742002-12-13 20:15:29 +00001477 if (new->size == 0)
1478 {
1479 binfo->attr->community = NULL;
1480 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1481 community_free (new);
1482 }
1483 else
1484 {
Paul Jakma4a2035f2011-04-01 15:58:27 +01001485 binfo->attr->community = new;
paul718e3742002-12-13 20:15:29 +00001486 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1487 }
1488 }
1489 }
1490
1491 return RMAP_OKAY;
1492}
1493
1494/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001495static void *
paulfd79ac92004-10-13 05:06:08 +00001496route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001497{
1498 char *p;
1499 char *str;
1500 int len;
1501
1502 p = strchr (arg, ' ');
1503 if (p)
1504 {
1505 len = p - arg;
1506 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1507 memcpy (str, arg, len);
1508 }
1509 else
1510 str = NULL;
1511
1512 return str;
1513}
1514
1515/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001516static void
paul718e3742002-12-13 20:15:29 +00001517route_set_community_delete_free (void *rule)
1518{
1519 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1520}
1521
1522/* Set community rule structure. */
1523struct route_map_rule_cmd route_set_community_delete_cmd =
1524{
1525 "comm-list",
1526 route_set_community_delete,
1527 route_set_community_delete_compile,
1528 route_set_community_delete_free,
1529};
1530
1531/* `set extcommunity rt COMMUNITY' */
1532
1533/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001534static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001535route_set_ecommunity_rt (void *rule, struct prefix *prefix,
1536 route_map_object_t type, void *object)
1537{
1538 struct ecommunity *ecom;
1539 struct ecommunity *new_ecom;
1540 struct ecommunity *old_ecom;
1541 struct bgp_info *bgp_info;
1542
1543 if (type == RMAP_BGP)
1544 {
1545 ecom = rule;
1546 bgp_info = object;
1547
1548 if (! ecom)
1549 return RMAP_OKAY;
1550
1551 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001552 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001553
1554 if (old_ecom)
1555 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1556 else
1557 new_ecom = ecommunity_dup (ecom);
1558
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001559 bgp_info->attr->extra->ecommunity = ecommunity_intern (new_ecom);
paul718e3742002-12-13 20:15:29 +00001560
hasso70601e02005-05-27 03:26:57 +00001561 if (old_ecom)
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001562 ecommunity_unintern (&old_ecom);
hasso70601e02005-05-27 03:26:57 +00001563
paul718e3742002-12-13 20:15:29 +00001564 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1565 }
1566 return RMAP_OKAY;
1567}
1568
1569/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001570static void *
paulfd79ac92004-10-13 05:06:08 +00001571route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001572{
1573 struct ecommunity *ecom;
1574
1575 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1576 if (! ecom)
1577 return NULL;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001578 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001579}
1580
1581/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001582static void
paul718e3742002-12-13 20:15:29 +00001583route_set_ecommunity_rt_free (void *rule)
1584{
1585 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001586 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001587}
1588
1589/* Set community rule structure. */
1590struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1591{
1592 "extcommunity rt",
1593 route_set_ecommunity_rt,
1594 route_set_ecommunity_rt_compile,
1595 route_set_ecommunity_rt_free,
1596};
1597
1598/* `set extcommunity soo COMMUNITY' */
1599
1600/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001601static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001602route_set_ecommunity_soo (void *rule, struct prefix *prefix,
1603 route_map_object_t type, void *object)
1604{
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001605 struct ecommunity *ecom, *old_ecom, *new_ecom;
paul718e3742002-12-13 20:15:29 +00001606 struct bgp_info *bgp_info;
1607
1608 if (type == RMAP_BGP)
1609 {
1610 ecom = rule;
1611 bgp_info = object;
1612
1613 if (! ecom)
1614 return RMAP_OKAY;
1615
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001616 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
1617
1618 if (old_ecom)
1619 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1620 else
1621 new_ecom = ecommunity_dup (ecom);
1622
1623 bgp_info->attr->extra->ecommunity = ecommunity_intern (new_ecom);
1624
1625 if (old_ecom)
1626 ecommunity_unintern (&old_ecom);
1627
paul718e3742002-12-13 20:15:29 +00001628 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
paul718e3742002-12-13 20:15:29 +00001629 }
1630 return RMAP_OKAY;
1631}
1632
1633/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001634static void *
paulfd79ac92004-10-13 05:06:08 +00001635route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001636{
1637 struct ecommunity *ecom;
1638
1639 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1640 if (! ecom)
1641 return NULL;
1642
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001643 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001644}
1645
1646/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001647static void
paul718e3742002-12-13 20:15:29 +00001648route_set_ecommunity_soo_free (void *rule)
1649{
1650 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001651 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001652}
1653
1654/* Set community rule structure. */
1655struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1656{
1657 "extcommunity soo",
1658 route_set_ecommunity_soo,
1659 route_set_ecommunity_soo_compile,
1660 route_set_ecommunity_soo_free,
1661};
1662
1663/* `set origin ORIGIN' */
1664
1665/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001666static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001667route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1668{
1669 u_char *origin;
1670 struct bgp_info *bgp_info;
1671
1672 if (type == RMAP_BGP)
1673 {
1674 origin = rule;
1675 bgp_info = object;
1676
1677 bgp_info->attr->origin = *origin;
1678 }
1679
1680 return RMAP_OKAY;
1681}
1682
1683/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001684static void *
paulfd79ac92004-10-13 05:06:08 +00001685route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001686{
1687 u_char *origin;
1688
1689 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1690
1691 if (strcmp (arg, "igp") == 0)
1692 *origin = 0;
1693 else if (strcmp (arg, "egp") == 0)
1694 *origin = 1;
1695 else
1696 *origin = 2;
1697
1698 return origin;
1699}
1700
1701/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001702static void
paul718e3742002-12-13 20:15:29 +00001703route_set_origin_free (void *rule)
1704{
1705 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1706}
1707
1708/* Set metric rule structure. */
1709struct route_map_rule_cmd route_set_origin_cmd =
1710{
1711 "origin",
1712 route_set_origin,
1713 route_set_origin_compile,
1714 route_set_origin_free,
1715};
1716
1717/* `set atomic-aggregate' */
1718
1719/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001720static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001721route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1722 route_map_object_t type, void *object)
1723{
1724 struct bgp_info *bgp_info;
1725
1726 if (type == RMAP_BGP)
1727 {
1728 bgp_info = object;
1729 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1730 }
1731
1732 return RMAP_OKAY;
1733}
1734
1735/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001736static void *
paulfd79ac92004-10-13 05:06:08 +00001737route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001738{
1739 return (void *)1;
1740}
1741
1742/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001743static void
paul718e3742002-12-13 20:15:29 +00001744route_set_atomic_aggregate_free (void *rule)
1745{
1746 return;
1747}
1748
1749/* Set atomic aggregate rule structure. */
1750struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1751{
1752 "atomic-aggregate",
1753 route_set_atomic_aggregate,
1754 route_set_atomic_aggregate_compile,
1755 route_set_atomic_aggregate_free,
1756};
1757
1758/* `set aggregator as AS A.B.C.D' */
1759struct aggregator
1760{
1761 as_t as;
1762 struct in_addr address;
1763};
1764
paul94f2b392005-06-28 12:44:16 +00001765static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001766route_set_aggregator_as (void *rule, struct prefix *prefix,
1767 route_map_object_t type, void *object)
1768{
1769 struct bgp_info *bgp_info;
1770 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001771 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001772
1773 if (type == RMAP_BGP)
1774 {
1775 bgp_info = object;
1776 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001777 ae = bgp_attr_extra_get (bgp_info->attr);
1778
1779 ae->aggregator_as = aggregator->as;
1780 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001781 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1782 }
1783
1784 return RMAP_OKAY;
1785}
1786
paul94f2b392005-06-28 12:44:16 +00001787static void *
paulfd79ac92004-10-13 05:06:08 +00001788route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001789{
1790 struct aggregator *aggregator;
1791 char as[10];
1792 char address[20];
1793
Stephen Hemminger393deb92008-08-18 14:13:29 -07001794 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
paul718e3742002-12-13 20:15:29 +00001795 sscanf (arg, "%s %s", as, address);
1796
1797 aggregator->as = strtoul (as, NULL, 10);
1798 inet_aton (address, &aggregator->address);
1799
1800 return aggregator;
1801}
1802
paul94f2b392005-06-28 12:44:16 +00001803static void
paul718e3742002-12-13 20:15:29 +00001804route_set_aggregator_as_free (void *rule)
1805{
1806 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1807}
1808
1809struct route_map_rule_cmd route_set_aggregator_as_cmd =
1810{
1811 "aggregator as",
1812 route_set_aggregator_as,
1813 route_set_aggregator_as_compile,
1814 route_set_aggregator_as_free,
1815};
1816
1817#ifdef HAVE_IPV6
1818/* `match ipv6 address IP_ACCESS_LIST' */
1819
paul94f2b392005-06-28 12:44:16 +00001820static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001821route_match_ipv6_address (void *rule, struct prefix *prefix,
1822 route_map_object_t type, void *object)
1823{
1824 struct access_list *alist;
1825
1826 if (type == RMAP_BGP)
1827 {
1828 alist = access_list_lookup (AFI_IP6, (char *) rule);
1829 if (alist == NULL)
1830 return RMAP_NOMATCH;
1831
1832 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1833 RMAP_NOMATCH : RMAP_MATCH);
1834 }
1835 return RMAP_NOMATCH;
1836}
1837
paul94f2b392005-06-28 12:44:16 +00001838static void *
paulfd79ac92004-10-13 05:06:08 +00001839route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001840{
1841 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1842}
1843
paul94f2b392005-06-28 12:44:16 +00001844static void
paul718e3742002-12-13 20:15:29 +00001845route_match_ipv6_address_free (void *rule)
1846{
1847 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1848}
1849
1850/* Route map commands for ip address matching. */
1851struct route_map_rule_cmd route_match_ipv6_address_cmd =
1852{
1853 "ipv6 address",
1854 route_match_ipv6_address,
1855 route_match_ipv6_address_compile,
1856 route_match_ipv6_address_free
1857};
1858
1859/* `match ipv6 next-hop IP_ADDRESS' */
1860
paul94f2b392005-06-28 12:44:16 +00001861static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001862route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1863 route_map_object_t type, void *object)
1864{
1865 struct in6_addr *addr;
1866 struct bgp_info *bgp_info;
1867
1868 if (type == RMAP_BGP)
1869 {
1870 addr = rule;
1871 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001872
1873 if (!bgp_info->attr->extra)
1874 return RMAP_NOMATCH;
1875
1876 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, rule))
paul718e3742002-12-13 20:15:29 +00001877 return RMAP_MATCH;
1878
Paul Jakmafb982c22007-05-04 20:15:47 +00001879 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
1880 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, rule))
paul718e3742002-12-13 20:15:29 +00001881 return RMAP_MATCH;
1882
1883 return RMAP_NOMATCH;
1884 }
1885
1886 return RMAP_NOMATCH;
1887}
1888
paul94f2b392005-06-28 12:44:16 +00001889static void *
paulfd79ac92004-10-13 05:06:08 +00001890route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001891{
1892 struct in6_addr *address;
1893 int ret;
1894
1895 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1896
1897 ret = inet_pton (AF_INET6, arg, address);
1898 if (!ret)
1899 {
1900 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1901 return NULL;
1902 }
1903
1904 return address;
1905}
1906
paul94f2b392005-06-28 12:44:16 +00001907static void
paul718e3742002-12-13 20:15:29 +00001908route_match_ipv6_next_hop_free (void *rule)
1909{
1910 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1911}
1912
1913struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1914{
1915 "ipv6 next-hop",
1916 route_match_ipv6_next_hop,
1917 route_match_ipv6_next_hop_compile,
1918 route_match_ipv6_next_hop_free
1919};
1920
1921/* `match ipv6 address prefix-list PREFIX_LIST' */
1922
paul94f2b392005-06-28 12:44:16 +00001923static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001924route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1925 route_map_object_t type, void *object)
1926{
1927 struct prefix_list *plist;
1928
1929 if (type == RMAP_BGP)
1930 {
1931 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1932 if (plist == NULL)
1933 return RMAP_NOMATCH;
1934
1935 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1936 RMAP_NOMATCH : RMAP_MATCH);
1937 }
1938 return RMAP_NOMATCH;
1939}
1940
paul94f2b392005-06-28 12:44:16 +00001941static void *
paulfd79ac92004-10-13 05:06:08 +00001942route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001943{
1944 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1945}
1946
paul94f2b392005-06-28 12:44:16 +00001947static void
paul718e3742002-12-13 20:15:29 +00001948route_match_ipv6_address_prefix_list_free (void *rule)
1949{
1950 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1951}
1952
1953struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1954{
1955 "ipv6 address prefix-list",
1956 route_match_ipv6_address_prefix_list,
1957 route_match_ipv6_address_prefix_list_compile,
1958 route_match_ipv6_address_prefix_list_free
1959};
1960
1961/* `set ipv6 nexthop global IP_ADDRESS' */
1962
1963/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001964static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001965route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1966 route_map_object_t type, void *object)
1967{
1968 struct in6_addr *address;
1969 struct bgp_info *bgp_info;
1970
1971 if (type == RMAP_BGP)
1972 {
1973 /* Fetch routemap's rule information. */
1974 address = rule;
1975 bgp_info = object;
1976
1977 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001978 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00001979
1980 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001981 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1982 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00001983 }
1984
1985 return RMAP_OKAY;
1986}
1987
1988/* Route map `ip next-hop' compile function. Given string is converted
1989 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001990static void *
paulfd79ac92004-10-13 05:06:08 +00001991route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001992{
1993 int ret;
1994 struct in6_addr *address;
1995
1996 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1997
1998 ret = inet_pton (AF_INET6, arg, address);
1999
2000 if (ret == 0)
2001 {
2002 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2003 return NULL;
2004 }
2005
2006 return address;
2007}
2008
2009/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00002010static void
paul718e3742002-12-13 20:15:29 +00002011route_set_ipv6_nexthop_global_free (void *rule)
2012{
2013 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2014}
2015
2016/* Route map commands for ip nexthop set. */
2017struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
2018{
2019 "ipv6 next-hop global",
2020 route_set_ipv6_nexthop_global,
2021 route_set_ipv6_nexthop_global_compile,
2022 route_set_ipv6_nexthop_global_free
2023};
2024
2025/* `set ipv6 nexthop local IP_ADDRESS' */
2026
2027/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00002028static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002029route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
2030 route_map_object_t type, void *object)
2031{
2032 struct in6_addr *address;
2033 struct bgp_info *bgp_info;
2034
2035 if (type == RMAP_BGP)
2036 {
2037 /* Fetch routemap's rule information. */
2038 address = rule;
2039 bgp_info = object;
2040
2041 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002042 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00002043
2044 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002045 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2046 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00002047 }
2048
2049 return RMAP_OKAY;
2050}
2051
2052/* Route map `ip nexthop' compile function. Given string is converted
2053 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00002054static void *
paulfd79ac92004-10-13 05:06:08 +00002055route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002056{
2057 int ret;
2058 struct in6_addr *address;
2059
2060 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2061
2062 ret = inet_pton (AF_INET6, arg, address);
2063
2064 if (ret == 0)
2065 {
2066 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2067 return NULL;
2068 }
2069
2070 return address;
2071}
2072
2073/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00002074static void
paul718e3742002-12-13 20:15:29 +00002075route_set_ipv6_nexthop_local_free (void *rule)
2076{
2077 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2078}
2079
2080/* Route map commands for ip nexthop set. */
2081struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
2082{
2083 "ipv6 next-hop local",
2084 route_set_ipv6_nexthop_local,
2085 route_set_ipv6_nexthop_local_compile,
2086 route_set_ipv6_nexthop_local_free
2087};
2088#endif /* HAVE_IPV6 */
2089
2090/* `set vpnv4 nexthop A.B.C.D' */
2091
paul94f2b392005-06-28 12:44:16 +00002092static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002093route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2094 route_map_object_t type, void *object)
2095{
2096 struct in_addr *address;
2097 struct bgp_info *bgp_info;
2098
2099 if (type == RMAP_BGP)
2100 {
2101 /* Fetch routemap's rule information. */
2102 address = rule;
2103 bgp_info = object;
2104
2105 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002106 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
paul718e3742002-12-13 20:15:29 +00002107 }
2108
2109 return RMAP_OKAY;
2110}
2111
paul94f2b392005-06-28 12:44:16 +00002112static void *
paulfd79ac92004-10-13 05:06:08 +00002113route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002114{
2115 int ret;
2116 struct in_addr *address;
2117
2118 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2119
2120 ret = inet_aton (arg, address);
2121
2122 if (ret == 0)
2123 {
2124 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2125 return NULL;
2126 }
2127
2128 return address;
2129}
2130
paul94f2b392005-06-28 12:44:16 +00002131static void
paul718e3742002-12-13 20:15:29 +00002132route_set_vpnv4_nexthop_free (void *rule)
2133{
2134 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2135}
2136
2137/* Route map commands for ip nexthop set. */
2138struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2139{
2140 "vpnv4 next-hop",
2141 route_set_vpnv4_nexthop,
2142 route_set_vpnv4_nexthop_compile,
2143 route_set_vpnv4_nexthop_free
2144};
2145
2146/* `set originator-id' */
2147
2148/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002149static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002150route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2151{
2152 struct in_addr *address;
2153 struct bgp_info *bgp_info;
2154
2155 if (type == RMAP_BGP)
2156 {
2157 address = rule;
2158 bgp_info = object;
2159
2160 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002161 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002162 }
2163
2164 return RMAP_OKAY;
2165}
2166
2167/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002168static void *
paulfd79ac92004-10-13 05:06:08 +00002169route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002170{
2171 int ret;
2172 struct in_addr *address;
2173
2174 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2175
2176 ret = inet_aton (arg, address);
2177
2178 if (ret == 0)
2179 {
2180 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2181 return NULL;
2182 }
2183
2184 return address;
2185}
2186
2187/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002188static void
paul718e3742002-12-13 20:15:29 +00002189route_set_originator_id_free (void *rule)
2190{
2191 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2192}
2193
2194/* Set metric rule structure. */
2195struct route_map_rule_cmd route_set_originator_id_cmd =
2196{
2197 "originator-id",
2198 route_set_originator_id,
2199 route_set_originator_id_compile,
2200 route_set_originator_id_free,
2201};
2202
2203/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002204static int
paul718e3742002-12-13 20:15:29 +00002205bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002206 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002207{
2208 int ret;
2209
2210 ret = route_map_add_match (index, command, arg);
2211 if (ret)
2212 {
2213 switch (ret)
2214 {
2215 case RMAP_RULE_MISSING:
2216 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2217 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002218 case RMAP_COMPILE_ERROR:
2219 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2220 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002221 }
2222 }
2223 return CMD_SUCCESS;
2224}
2225
2226/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002227static int
paul718e3742002-12-13 20:15:29 +00002228bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002229 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002230{
2231 int ret;
2232
2233 ret = route_map_delete_match (index, command, arg);
2234 if (ret)
2235 {
2236 switch (ret)
2237 {
2238 case RMAP_RULE_MISSING:
2239 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2240 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002241 case RMAP_COMPILE_ERROR:
2242 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2243 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002244 }
2245 }
2246 return CMD_SUCCESS;
2247}
2248
2249/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002250static int
paul718e3742002-12-13 20:15:29 +00002251bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002252 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002253{
2254 int ret;
2255
2256 ret = route_map_add_set (index, command, arg);
2257 if (ret)
2258 {
2259 switch (ret)
2260 {
2261 case RMAP_RULE_MISSING:
2262 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2263 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002264 case RMAP_COMPILE_ERROR:
2265 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2266 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002267 }
2268 }
2269 return CMD_SUCCESS;
2270}
2271
2272/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002273static int
paul718e3742002-12-13 20:15:29 +00002274bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002275 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002276{
2277 int ret;
2278
2279 ret = route_map_delete_set (index, command, arg);
2280 if (ret)
2281 {
2282 switch (ret)
2283 {
2284 case RMAP_RULE_MISSING:
2285 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2286 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002287 case RMAP_COMPILE_ERROR:
2288 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2289 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002290 }
2291 }
2292 return CMD_SUCCESS;
2293}
2294
2295/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002296static void
paulfd79ac92004-10-13 05:06:08 +00002297bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002298{
2299 int i;
2300 afi_t afi;
2301 safi_t safi;
2302 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002303 struct listnode *node, *nnode;
2304 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002305 struct bgp *bgp;
2306 struct peer *peer;
2307 struct peer_group *group;
2308 struct bgp_filter *filter;
2309 struct bgp_node *bn;
2310 struct bgp_static *bgp_static;
2311
2312 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002313 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002314 {
paul1eb8ef22005-04-07 07:30:20 +00002315 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002316 {
2317 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2318 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2319 {
2320 filter = &peer->filter[afi][safi];
2321
paulfee0f4c2004-09-13 05:12:46 +00002322 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002323 {
2324 if (filter->map[direct].name)
2325 filter->map[direct].map =
2326 route_map_lookup_by_name (filter->map[direct].name);
2327 else
2328 filter->map[direct].map = NULL;
2329 }
2330
2331 if (filter->usmap.name)
2332 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2333 else
2334 filter->usmap.map = NULL;
2335 }
2336 }
paul1eb8ef22005-04-07 07:30:20 +00002337 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002338 {
2339 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2340 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2341 {
2342 filter = &group->conf->filter[afi][safi];
2343
paulfee0f4c2004-09-13 05:12:46 +00002344 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002345 {
2346 if (filter->map[direct].name)
2347 filter->map[direct].map =
2348 route_map_lookup_by_name (filter->map[direct].name);
2349 else
2350 filter->map[direct].map = NULL;
2351 }
2352
2353 if (filter->usmap.name)
2354 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2355 else
2356 filter->usmap.map = NULL;
2357 }
2358 }
2359 }
2360
2361 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002362 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002363 {
paul1eb8ef22005-04-07 07:30:20 +00002364 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002365 {
2366 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2367 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2368 {
2369 if (peer->default_rmap[afi][safi].name)
2370 peer->default_rmap[afi][safi].map =
2371 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2372 else
2373 peer->default_rmap[afi][safi].map = NULL;
2374 }
2375 }
2376 }
2377
2378 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002379 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002380 {
2381 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2382 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2383 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2384 bn = bgp_route_next (bn))
2385 if ((bgp_static = bn->info) != NULL)
2386 {
2387 if (bgp_static->rmap.name)
2388 bgp_static->rmap.map =
2389 route_map_lookup_by_name (bgp_static->rmap.name);
2390 else
2391 bgp_static->rmap.map = NULL;
2392 }
2393 }
2394
2395 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002396 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002397 {
2398 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2399 {
2400 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2401 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2402 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2403#ifdef HAVE_IPV6
2404 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2405 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2406 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2407#endif /* HAVE_IPV6 */
2408 }
2409 }
2410}
2411
paulfee0f4c2004-09-13 05:12:46 +00002412DEFUN (match_peer,
2413 match_peer_cmd,
2414 "match peer (A.B.C.D|X:X::X:X)",
2415 MATCH_STR
2416 "Match peer address\n"
2417 "IPv6 address of peer\n"
2418 "IP address of peer\n")
2419{
2420 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2421}
2422
2423DEFUN (match_peer_local,
2424 match_peer_local_cmd,
2425 "match peer local",
2426 MATCH_STR
2427 "Match peer address\n"
2428 "Static or Redistributed routes\n")
2429{
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +02002430 return bgp_route_match_add (vty, vty->index, "peer", "local");
paulfee0f4c2004-09-13 05:12:46 +00002431}
2432
2433DEFUN (no_match_peer,
2434 no_match_peer_cmd,
2435 "no match peer",
2436 NO_STR
2437 MATCH_STR
2438 "Match peer address\n")
2439{
2440 if (argc == 0)
2441 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2442
2443 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2444}
2445
2446ALIAS (no_match_peer,
2447 no_match_peer_val_cmd,
2448 "no match peer (A.B.C.D|X:X::X:X)",
2449 NO_STR
2450 MATCH_STR
2451 "Match peer address\n"
2452 "IPv6 address of peer\n"
2453 "IP address of peer\n")
2454
2455ALIAS (no_match_peer,
2456 no_match_peer_local_cmd,
2457 "no match peer local",
2458 NO_STR
2459 MATCH_STR
2460 "Match peer address\n"
2461 "Static or Redistributed routes\n")
2462
paul718e3742002-12-13 20:15:29 +00002463DEFUN (match_ip_address,
2464 match_ip_address_cmd,
2465 "match ip address (<1-199>|<1300-2699>|WORD)",
2466 MATCH_STR
2467 IP_STR
2468 "Match address of route\n"
2469 "IP access-list number\n"
2470 "IP access-list number (expanded range)\n"
2471 "IP Access-list name\n")
2472{
2473 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2474}
2475
2476DEFUN (no_match_ip_address,
2477 no_match_ip_address_cmd,
2478 "no match ip address",
2479 NO_STR
2480 MATCH_STR
2481 IP_STR
2482 "Match address of route\n")
2483{
2484 if (argc == 0)
2485 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2486
2487 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2488}
2489
2490ALIAS (no_match_ip_address,
2491 no_match_ip_address_val_cmd,
2492 "no match ip address (<1-199>|<1300-2699>|WORD)",
2493 NO_STR
2494 MATCH_STR
2495 IP_STR
2496 "Match address of route\n"
2497 "IP access-list number\n"
2498 "IP access-list number (expanded range)\n"
2499 "IP Access-list name\n")
2500
2501DEFUN (match_ip_next_hop,
2502 match_ip_next_hop_cmd,
2503 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2504 MATCH_STR
2505 IP_STR
2506 "Match next-hop address of route\n"
2507 "IP access-list number\n"
2508 "IP access-list number (expanded range)\n"
2509 "IP Access-list name\n")
2510{
2511 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2512}
2513
2514DEFUN (no_match_ip_next_hop,
2515 no_match_ip_next_hop_cmd,
2516 "no match ip next-hop",
2517 NO_STR
2518 MATCH_STR
2519 IP_STR
2520 "Match next-hop address of route\n")
2521{
2522 if (argc == 0)
2523 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2524
2525 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2526}
2527
2528ALIAS (no_match_ip_next_hop,
2529 no_match_ip_next_hop_val_cmd,
2530 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2531 NO_STR
2532 MATCH_STR
2533 IP_STR
2534 "Match next-hop address of route\n"
2535 "IP access-list number\n"
2536 "IP access-list number (expanded range)\n"
2537 "IP Access-list name\n")
2538
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04002539/* match probability { */
2540
2541DEFUN (match_probability,
2542 match_probability_cmd,
2543 "match probability <0-100>",
2544 MATCH_STR
2545 "Match portion of routes defined by percentage value\n"
2546 "Percentage of routes\n")
2547{
2548 return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
2549}
2550
2551DEFUN (no_match_probability,
2552 no_match_probability_cmd,
2553 "no match probability",
2554 NO_STR
2555 MATCH_STR
2556 "Match portion of routes defined by percentage value\n")
2557{
2558 return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL);
2559}
2560
2561ALIAS (no_match_probability,
2562 no_match_probability_val_cmd,
2563 "no match probability <1-99>",
2564 NO_STR
2565 MATCH_STR
2566 "Match portion of routes defined by percentage value\n"
2567 "Percentage of routes\n")
2568
2569/* } */
2570
hassoc1643bb2005-02-02 16:43:17 +00002571DEFUN (match_ip_route_source,
2572 match_ip_route_source_cmd,
2573 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2574 MATCH_STR
2575 IP_STR
2576 "Match advertising source address of route\n"
2577 "IP access-list number\n"
2578 "IP access-list number (expanded range)\n"
2579 "IP standard access-list name\n")
2580{
2581 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2582}
2583
2584DEFUN (no_match_ip_route_source,
2585 no_match_ip_route_source_cmd,
2586 "no match ip route-source",
2587 NO_STR
2588 MATCH_STR
2589 IP_STR
2590 "Match advertising source address of route\n")
2591{
2592 if (argc == 0)
2593 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2594
2595 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2596}
2597
2598ALIAS (no_match_ip_route_source,
2599 no_match_ip_route_source_val_cmd,
2600 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2601 NO_STR
2602 MATCH_STR
2603 IP_STR
2604 "Match advertising source address of route\n"
2605 "IP access-list number\n"
2606 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002607 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002608
paul718e3742002-12-13 20:15:29 +00002609DEFUN (match_ip_address_prefix_list,
2610 match_ip_address_prefix_list_cmd,
2611 "match ip address prefix-list WORD",
2612 MATCH_STR
2613 IP_STR
2614 "Match address of route\n"
2615 "Match entries of prefix-lists\n"
2616 "IP prefix-list name\n")
2617{
2618 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2619}
2620
2621DEFUN (no_match_ip_address_prefix_list,
2622 no_match_ip_address_prefix_list_cmd,
2623 "no match ip address prefix-list",
2624 NO_STR
2625 MATCH_STR
2626 IP_STR
2627 "Match address of route\n"
2628 "Match entries of prefix-lists\n")
2629{
2630 if (argc == 0)
2631 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2632
2633 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2634}
2635
2636ALIAS (no_match_ip_address_prefix_list,
2637 no_match_ip_address_prefix_list_val_cmd,
2638 "no match ip address prefix-list WORD",
2639 NO_STR
2640 MATCH_STR
2641 IP_STR
2642 "Match address of route\n"
2643 "Match entries of prefix-lists\n"
2644 "IP prefix-list name\n")
2645
2646DEFUN (match_ip_next_hop_prefix_list,
2647 match_ip_next_hop_prefix_list_cmd,
2648 "match ip next-hop prefix-list WORD",
2649 MATCH_STR
2650 IP_STR
2651 "Match next-hop address of route\n"
2652 "Match entries of prefix-lists\n"
2653 "IP prefix-list name\n")
2654{
2655 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2656}
2657
2658DEFUN (no_match_ip_next_hop_prefix_list,
2659 no_match_ip_next_hop_prefix_list_cmd,
2660 "no match ip next-hop prefix-list",
2661 NO_STR
2662 MATCH_STR
2663 IP_STR
2664 "Match next-hop address of route\n"
2665 "Match entries of prefix-lists\n")
2666{
2667 if (argc == 0)
2668 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2669
2670 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2671}
2672
2673ALIAS (no_match_ip_next_hop_prefix_list,
2674 no_match_ip_next_hop_prefix_list_val_cmd,
2675 "no match ip next-hop prefix-list WORD",
2676 NO_STR
2677 MATCH_STR
2678 IP_STR
2679 "Match next-hop address of route\n"
2680 "Match entries of prefix-lists\n"
2681 "IP prefix-list name\n")
2682
hassoc1643bb2005-02-02 16:43:17 +00002683DEFUN (match_ip_route_source_prefix_list,
2684 match_ip_route_source_prefix_list_cmd,
2685 "match ip route-source prefix-list WORD",
2686 MATCH_STR
2687 IP_STR
2688 "Match advertising source address of route\n"
2689 "Match entries of prefix-lists\n"
2690 "IP prefix-list name\n")
2691{
2692 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2693}
2694
2695DEFUN (no_match_ip_route_source_prefix_list,
2696 no_match_ip_route_source_prefix_list_cmd,
2697 "no match ip route-source prefix-list",
2698 NO_STR
2699 MATCH_STR
2700 IP_STR
2701 "Match advertising source address of route\n"
2702 "Match entries of prefix-lists\n")
2703{
2704 if (argc == 0)
2705 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2706
2707 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2708}
2709
2710ALIAS (no_match_ip_route_source_prefix_list,
2711 no_match_ip_route_source_prefix_list_val_cmd,
2712 "no match ip route-source prefix-list WORD",
2713 NO_STR
2714 MATCH_STR
2715 IP_STR
2716 "Match advertising source address of route\n"
2717 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002718 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002719
paul718e3742002-12-13 20:15:29 +00002720DEFUN (match_metric,
2721 match_metric_cmd,
2722 "match metric <0-4294967295>",
2723 MATCH_STR
2724 "Match metric of route\n"
2725 "Metric value\n")
2726{
2727 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2728}
2729
2730DEFUN (no_match_metric,
2731 no_match_metric_cmd,
2732 "no match metric",
2733 NO_STR
2734 MATCH_STR
2735 "Match metric of route\n")
2736{
2737 if (argc == 0)
2738 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2739
2740 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2741}
2742
2743ALIAS (no_match_metric,
2744 no_match_metric_val_cmd,
2745 "no match metric <0-4294967295>",
2746 NO_STR
2747 MATCH_STR
2748 "Match metric of route\n"
2749 "Metric value\n")
2750
2751DEFUN (match_community,
2752 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002753 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002754 MATCH_STR
2755 "Match BGP community list\n"
2756 "Community-list number (standard)\n"
2757 "Community-list number (expanded)\n"
2758 "Community-list name\n")
2759{
2760 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2761}
2762
2763DEFUN (match_community_exact,
2764 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002765 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002766 MATCH_STR
2767 "Match BGP community list\n"
2768 "Community-list number (standard)\n"
2769 "Community-list number (expanded)\n"
2770 "Community-list name\n"
2771 "Do exact matching of communities\n")
2772{
2773 int ret;
2774 char *argstr;
2775
2776 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2777 strlen (argv[0]) + strlen ("exact-match") + 2);
2778
2779 sprintf (argstr, "%s exact-match", argv[0]);
2780
2781 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2782
2783 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2784
2785 return ret;
2786}
2787
2788DEFUN (no_match_community,
2789 no_match_community_cmd,
2790 "no match community",
2791 NO_STR
2792 MATCH_STR
2793 "Match BGP community list\n")
2794{
2795 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2796}
2797
2798ALIAS (no_match_community,
2799 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002800 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002801 NO_STR
2802 MATCH_STR
2803 "Match BGP community list\n"
2804 "Community-list number (standard)\n"
2805 "Community-list number (expanded)\n"
2806 "Community-list name\n")
2807
2808ALIAS (no_match_community,
2809 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002810 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002811 NO_STR
2812 MATCH_STR
2813 "Match BGP community list\n"
2814 "Community-list number (standard)\n"
2815 "Community-list number (expanded)\n"
2816 "Community-list name\n"
2817 "Do exact matching of communities\n")
2818
paul73ffb252003-04-19 15:49:49 +00002819DEFUN (match_ecommunity,
2820 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002821 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002822 MATCH_STR
2823 "Match BGP/VPN extended community list\n"
2824 "Extended community-list number (standard)\n"
2825 "Extended community-list number (expanded)\n"
2826 "Extended community-list name\n")
2827{
2828 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2829}
2830
2831DEFUN (no_match_ecommunity,
2832 no_match_ecommunity_cmd,
2833 "no match extcommunity",
2834 NO_STR
2835 MATCH_STR
2836 "Match BGP/VPN extended community list\n")
2837{
2838 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2839}
2840
2841ALIAS (no_match_ecommunity,
2842 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002843 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002844 NO_STR
2845 MATCH_STR
2846 "Match BGP/VPN extended community list\n"
2847 "Extended community-list number (standard)\n"
2848 "Extended community-list number (expanded)\n"
2849 "Extended community-list name\n")
2850
paul718e3742002-12-13 20:15:29 +00002851DEFUN (match_aspath,
2852 match_aspath_cmd,
2853 "match as-path WORD",
2854 MATCH_STR
2855 "Match BGP AS path list\n"
2856 "AS path access-list name\n")
2857{
2858 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2859}
2860
2861DEFUN (no_match_aspath,
2862 no_match_aspath_cmd,
2863 "no match as-path",
2864 NO_STR
2865 MATCH_STR
2866 "Match BGP AS path list\n")
2867{
2868 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2869}
2870
2871ALIAS (no_match_aspath,
2872 no_match_aspath_val_cmd,
2873 "no match as-path WORD",
2874 NO_STR
2875 MATCH_STR
2876 "Match BGP AS path list\n"
2877 "AS path access-list name\n")
2878
2879DEFUN (match_origin,
2880 match_origin_cmd,
2881 "match origin (egp|igp|incomplete)",
2882 MATCH_STR
2883 "BGP origin code\n"
2884 "remote EGP\n"
2885 "local IGP\n"
2886 "unknown heritage\n")
2887{
2888 if (strncmp (argv[0], "igp", 2) == 0)
2889 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2890 if (strncmp (argv[0], "egp", 1) == 0)
2891 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2892 if (strncmp (argv[0], "incomplete", 2) == 0)
2893 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2894
2895 return CMD_WARNING;
2896}
2897
2898DEFUN (no_match_origin,
2899 no_match_origin_cmd,
2900 "no match origin",
2901 NO_STR
2902 MATCH_STR
2903 "BGP origin code\n")
2904{
2905 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2906}
2907
2908ALIAS (no_match_origin,
2909 no_match_origin_val_cmd,
2910 "no match origin (egp|igp|incomplete)",
2911 NO_STR
2912 MATCH_STR
2913 "BGP origin code\n"
2914 "remote EGP\n"
2915 "local IGP\n"
2916 "unknown heritage\n")
2917
2918DEFUN (set_ip_nexthop,
2919 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002920 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002921 SET_STR
2922 IP_STR
2923 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002924 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002925{
2926 union sockunion su;
2927 int ret;
2928
2929 ret = str2sockunion (argv[0], &su);
2930 if (ret < 0)
2931 {
2932 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2933 return CMD_WARNING;
2934 }
2935
2936 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2937}
2938
paulaf5cd0a2003-11-02 07:24:40 +00002939DEFUN (set_ip_nexthop_peer,
2940 set_ip_nexthop_peer_cmd,
2941 "set ip next-hop peer-address",
2942 SET_STR
2943 IP_STR
2944 "Next hop address\n"
2945 "Use peer address (for BGP only)\n")
2946{
2947 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2948}
2949
paul94f2b392005-06-28 12:44:16 +00002950DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00002951 no_set_ip_nexthop_peer_cmd,
2952 "no set ip next-hop peer-address",
2953 NO_STR
2954 SET_STR
2955 IP_STR
2956 "Next hop address\n"
2957 "Use peer address (for BGP only)\n")
2958{
2959 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2960}
2961
2962
paul718e3742002-12-13 20:15:29 +00002963DEFUN (no_set_ip_nexthop,
2964 no_set_ip_nexthop_cmd,
2965 "no set ip next-hop",
2966 NO_STR
2967 SET_STR
paul718e3742002-12-13 20:15:29 +00002968 "Next hop address\n")
2969{
paulaf5cd0a2003-11-02 07:24:40 +00002970 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002971 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2972
2973 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2974}
2975
2976ALIAS (no_set_ip_nexthop,
2977 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002978 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002979 NO_STR
2980 SET_STR
2981 IP_STR
2982 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002983 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002984
2985DEFUN (set_metric,
2986 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002987 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002988 SET_STR
2989 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002990 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002991{
2992 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2993}
2994
paul73ffb252003-04-19 15:49:49 +00002995ALIAS (set_metric,
2996 set_metric_addsub_cmd,
2997 "set metric <+/-metric>",
2998 SET_STR
2999 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00003000 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00003001
paul718e3742002-12-13 20:15:29 +00003002DEFUN (no_set_metric,
3003 no_set_metric_cmd,
3004 "no set metric",
3005 NO_STR
3006 SET_STR
3007 "Metric value for destination routing protocol\n")
3008{
3009 if (argc == 0)
3010 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
3011
3012 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
3013}
3014
3015ALIAS (no_set_metric,
3016 no_set_metric_val_cmd,
3017 "no set metric <0-4294967295>",
3018 NO_STR
3019 SET_STR
3020 "Metric value for destination routing protocol\n"
3021 "Metric value\n")
3022
3023DEFUN (set_local_pref,
3024 set_local_pref_cmd,
3025 "set local-preference <0-4294967295>",
3026 SET_STR
3027 "BGP local preference path attribute\n"
3028 "Preference value\n")
3029{
3030 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
3031}
3032
3033DEFUN (no_set_local_pref,
3034 no_set_local_pref_cmd,
3035 "no set local-preference",
3036 NO_STR
3037 SET_STR
3038 "BGP local preference path attribute\n")
3039{
3040 if (argc == 0)
3041 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3042
3043 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
3044}
3045
3046ALIAS (no_set_local_pref,
3047 no_set_local_pref_val_cmd,
3048 "no set local-preference <0-4294967295>",
3049 NO_STR
3050 SET_STR
3051 "BGP local preference path attribute\n"
3052 "Preference value\n")
3053
3054DEFUN (set_weight,
3055 set_weight_cmd,
3056 "set weight <0-4294967295>",
3057 SET_STR
3058 "BGP weight for routing table\n"
3059 "Weight value\n")
3060{
3061 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3062}
3063
3064DEFUN (no_set_weight,
3065 no_set_weight_cmd,
3066 "no set weight",
3067 NO_STR
3068 SET_STR
3069 "BGP weight for routing table\n")
3070{
3071 if (argc == 0)
3072 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3073
3074 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3075}
3076
3077ALIAS (no_set_weight,
3078 no_set_weight_val_cmd,
3079 "no set weight <0-4294967295>",
3080 NO_STR
3081 SET_STR
3082 "BGP weight for routing table\n"
3083 "Weight value\n")
3084
3085DEFUN (set_aspath_prepend,
3086 set_aspath_prepend_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003087 "set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003088 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003089 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003090 "Prepend to the as-path\n"
3091 "AS number\n")
3092{
3093 int ret;
3094 char *str;
3095
3096 str = argv_concat (argv, argc, 0);
3097 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3098 XFREE (MTYPE_TMP, str);
3099
3100 return ret;
3101}
3102
3103DEFUN (no_set_aspath_prepend,
3104 no_set_aspath_prepend_cmd,
3105 "no set as-path prepend",
3106 NO_STR
3107 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003108 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003109 "Prepend to the as-path\n")
3110{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00003111 int ret;
3112 char *str;
3113
3114 if (argc == 0)
3115 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3116
3117 str = argv_concat (argv, argc, 0);
3118 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3119 XFREE (MTYPE_TMP, str);
3120 return ret;
paul718e3742002-12-13 20:15:29 +00003121}
3122
3123ALIAS (no_set_aspath_prepend,
3124 no_set_aspath_prepend_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003125 "no set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003126 NO_STR
3127 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003128 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003129 "Prepend to the as-path\n"
3130 "AS number\n")
3131
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003132DEFUN (set_aspath_exclude,
3133 set_aspath_exclude_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003134 "set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003135 SET_STR
3136 "Transform BGP AS-path attribute\n"
3137 "Exclude from the as-path\n"
3138 "AS number\n")
3139{
3140 int ret;
3141 char *str;
3142
3143 str = argv_concat (argv, argc, 0);
3144 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3145 XFREE (MTYPE_TMP, str);
3146 return ret;
3147}
3148
3149DEFUN (no_set_aspath_exclude,
3150 no_set_aspath_exclude_cmd,
3151 "no set as-path exclude",
3152 NO_STR
3153 SET_STR
3154 "Transform BGP AS_PATH attribute\n"
3155 "Exclude from the as-path\n")
3156{
3157 int ret;
3158 char *str;
3159
3160 if (argc == 0)
3161 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3162
3163 str = argv_concat (argv, argc, 0);
3164 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3165 XFREE (MTYPE_TMP, str);
3166 return ret;
3167}
3168
3169ALIAS (no_set_aspath_exclude,
3170 no_set_aspath_exclude_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003171 "no set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003172 NO_STR
3173 SET_STR
3174 "Transform BGP AS_PATH attribute\n"
3175 "Exclude from the as-path\n"
3176 "AS number\n")
3177
paul718e3742002-12-13 20:15:29 +00003178DEFUN (set_community,
3179 set_community_cmd,
3180 "set community .AA:NN",
3181 SET_STR
3182 "BGP community attribute\n"
3183 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3184{
3185 int i;
3186 int first = 0;
3187 int additive = 0;
3188 struct buffer *b;
3189 struct community *com = NULL;
3190 char *str;
3191 char *argstr;
3192 int ret;
3193
3194 b = buffer_new (1024);
3195
3196 for (i = 0; i < argc; i++)
3197 {
3198 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3199 {
3200 additive = 1;
3201 continue;
3202 }
3203
3204 if (first)
3205 buffer_putc (b, ' ');
3206 else
3207 first = 1;
3208
3209 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3210 {
3211 buffer_putstr (b, "internet");
3212 continue;
3213 }
3214 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3215 {
3216 buffer_putstr (b, "local-AS");
3217 continue;
3218 }
3219 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3220 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3221 {
3222 buffer_putstr (b, "no-advertise");
3223 continue;
3224 }
3225 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3226 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3227 {
3228 buffer_putstr (b, "no-export");
3229 continue;
3230 }
3231 buffer_putstr (b, argv[i]);
3232 }
3233 buffer_putc (b, '\0');
3234
3235 /* Fetch result string then compile it to communities attribute. */
3236 str = buffer_getstr (b);
3237 buffer_free (b);
3238
3239 if (str)
3240 {
3241 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003242 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003243 }
3244
3245 /* Can't compile user input into communities attribute. */
3246 if (! com)
3247 {
3248 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3249 return CMD_WARNING;
3250 }
3251
3252 /* Set communites attribute string. */
3253 str = community_str (com);
3254
3255 if (additive)
3256 {
3257 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3258 strcpy (argstr, str);
3259 strcpy (argstr + strlen (str), " additive");
3260 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3261 XFREE (MTYPE_TMP, argstr);
3262 }
3263 else
3264 ret = bgp_route_set_add (vty, vty->index, "community", str);
3265
3266 community_free (com);
3267
3268 return ret;
3269}
3270
3271DEFUN (set_community_none,
3272 set_community_none_cmd,
3273 "set community none",
3274 SET_STR
3275 "BGP community attribute\n"
3276 "No community attribute\n")
3277{
3278 return bgp_route_set_add (vty, vty->index, "community", "none");
3279}
3280
3281DEFUN (no_set_community,
3282 no_set_community_cmd,
3283 "no set community",
3284 NO_STR
3285 SET_STR
3286 "BGP community attribute\n")
3287{
3288 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3289}
3290
3291ALIAS (no_set_community,
3292 no_set_community_val_cmd,
3293 "no set community .AA:NN",
3294 NO_STR
3295 SET_STR
3296 "BGP community attribute\n"
3297 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3298
3299ALIAS (no_set_community,
3300 no_set_community_none_cmd,
3301 "no set community none",
3302 NO_STR
3303 SET_STR
3304 "BGP community attribute\n"
3305 "No community attribute\n")
3306
3307DEFUN (set_community_delete,
3308 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003309 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003310 SET_STR
3311 "set BGP community list (for deletion)\n"
3312 "Community-list number (standard)\n"
3313 "Communitly-list number (expanded)\n"
3314 "Community-list name\n"
3315 "Delete matching communities\n")
3316{
3317 char *str;
3318
3319 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3320 strcpy (str, argv[0]);
3321 strcpy (str + strlen (argv[0]), " delete");
3322
3323 bgp_route_set_add (vty, vty->index, "comm-list", str);
3324
3325 XFREE (MTYPE_TMP, str);
3326 return CMD_SUCCESS;
3327}
3328
3329DEFUN (no_set_community_delete,
3330 no_set_community_delete_cmd,
3331 "no set comm-list",
3332 NO_STR
3333 SET_STR
3334 "set BGP community list (for deletion)\n")
3335{
3336 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3337}
3338
3339ALIAS (no_set_community_delete,
3340 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003341 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003342 NO_STR
3343 SET_STR
3344 "set BGP community list (for deletion)\n"
3345 "Community-list number (standard)\n"
3346 "Communitly-list number (expanded)\n"
3347 "Community-list name\n"
3348 "Delete matching communities\n")
3349
3350DEFUN (set_ecommunity_rt,
3351 set_ecommunity_rt_cmd,
3352 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3353 SET_STR
3354 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003355 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003356 "VPN extended community\n")
3357{
3358 int ret;
3359 char *str;
3360
3361 str = argv_concat (argv, argc, 0);
3362 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3363 XFREE (MTYPE_TMP, str);
3364
3365 return ret;
3366}
3367
3368DEFUN (no_set_ecommunity_rt,
3369 no_set_ecommunity_rt_cmd,
3370 "no set extcommunity rt",
3371 NO_STR
3372 SET_STR
3373 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003374 "Route Target extended community\n")
paul718e3742002-12-13 20:15:29 +00003375{
3376 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3377}
3378
3379ALIAS (no_set_ecommunity_rt,
3380 no_set_ecommunity_rt_val_cmd,
3381 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3382 NO_STR
3383 SET_STR
3384 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003385 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003386 "VPN extended community\n")
3387
3388DEFUN (set_ecommunity_soo,
3389 set_ecommunity_soo_cmd,
3390 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3391 SET_STR
3392 "BGP extended community attribute\n"
3393 "Site-of-Origin extended community\n"
3394 "VPN extended community\n")
3395{
3396 int ret;
3397 char *str;
3398
3399 str = argv_concat (argv, argc, 0);
3400 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3401 XFREE (MTYPE_TMP, str);
3402 return ret;
3403}
3404
3405DEFUN (no_set_ecommunity_soo,
3406 no_set_ecommunity_soo_cmd,
3407 "no set extcommunity soo",
3408 NO_STR
3409 SET_STR
3410 "BGP extended community attribute\n"
3411 "Site-of-Origin extended community\n")
3412{
3413 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3414}
3415
3416ALIAS (no_set_ecommunity_soo,
3417 no_set_ecommunity_soo_val_cmd,
3418 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3419 NO_STR
3420 SET_STR
3421 "BGP extended community attribute\n"
3422 "Site-of-Origin extended community\n"
3423 "VPN extended community\n")
3424
3425DEFUN (set_origin,
3426 set_origin_cmd,
3427 "set origin (egp|igp|incomplete)",
3428 SET_STR
3429 "BGP origin code\n"
3430 "remote EGP\n"
3431 "local IGP\n"
3432 "unknown heritage\n")
3433{
3434 if (strncmp (argv[0], "igp", 2) == 0)
3435 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3436 if (strncmp (argv[0], "egp", 1) == 0)
3437 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3438 if (strncmp (argv[0], "incomplete", 2) == 0)
3439 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3440
3441 return CMD_WARNING;
3442}
3443
3444DEFUN (no_set_origin,
3445 no_set_origin_cmd,
3446 "no set origin",
3447 NO_STR
3448 SET_STR
3449 "BGP origin code\n")
3450{
3451 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3452}
3453
3454ALIAS (no_set_origin,
3455 no_set_origin_val_cmd,
3456 "no set origin (egp|igp|incomplete)",
3457 NO_STR
3458 SET_STR
3459 "BGP origin code\n"
3460 "remote EGP\n"
3461 "local IGP\n"
3462 "unknown heritage\n")
3463
3464DEFUN (set_atomic_aggregate,
3465 set_atomic_aggregate_cmd,
3466 "set atomic-aggregate",
3467 SET_STR
3468 "BGP atomic aggregate attribute\n" )
3469{
3470 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3471}
3472
3473DEFUN (no_set_atomic_aggregate,
3474 no_set_atomic_aggregate_cmd,
3475 "no set atomic-aggregate",
3476 NO_STR
3477 SET_STR
3478 "BGP atomic aggregate attribute\n" )
3479{
3480 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3481}
3482
3483DEFUN (set_aggregator_as,
3484 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003485 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003486 SET_STR
3487 "BGP aggregator attribute\n"
3488 "AS number of aggregator\n"
3489 "AS number\n"
3490 "IP address of aggregator\n")
3491{
3492 int ret;
3493 as_t as;
3494 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003495 char *argstr;
3496
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003497 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003498
paul718e3742002-12-13 20:15:29 +00003499 ret = inet_aton (argv[1], &address);
3500 if (ret == 0)
3501 {
3502 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3503 return CMD_WARNING;
3504 }
3505
3506 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3507 strlen (argv[0]) + strlen (argv[1]) + 2);
3508
3509 sprintf (argstr, "%s %s", argv[0], argv[1]);
3510
3511 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3512
3513 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3514
3515 return ret;
3516}
3517
3518DEFUN (no_set_aggregator_as,
3519 no_set_aggregator_as_cmd,
3520 "no set aggregator as",
3521 NO_STR
3522 SET_STR
3523 "BGP aggregator attribute\n"
3524 "AS number of aggregator\n")
3525{
3526 int ret;
3527 as_t as;
3528 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003529 char *argstr;
3530
3531 if (argv == 0)
3532 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3533
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003534 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003535
3536 ret = inet_aton (argv[1], &address);
3537 if (ret == 0)
3538 {
3539 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3540 return CMD_WARNING;
3541 }
3542
3543 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3544 strlen (argv[0]) + strlen (argv[1]) + 2);
3545
3546 sprintf (argstr, "%s %s", argv[0], argv[1]);
3547
3548 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3549
3550 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3551
3552 return ret;
3553}
3554
3555ALIAS (no_set_aggregator_as,
3556 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003557 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003558 NO_STR
3559 SET_STR
3560 "BGP aggregator attribute\n"
3561 "AS number of aggregator\n"
3562 "AS number\n"
3563 "IP address of aggregator\n")
3564
3565
3566#ifdef HAVE_IPV6
3567DEFUN (match_ipv6_address,
3568 match_ipv6_address_cmd,
3569 "match ipv6 address WORD",
3570 MATCH_STR
3571 IPV6_STR
3572 "Match IPv6 address of route\n"
3573 "IPv6 access-list name\n")
3574{
3575 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3576}
3577
3578DEFUN (no_match_ipv6_address,
3579 no_match_ipv6_address_cmd,
3580 "no match ipv6 address WORD",
3581 NO_STR
3582 MATCH_STR
3583 IPV6_STR
3584 "Match IPv6 address of route\n"
3585 "IPv6 access-list name\n")
3586{
3587 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3588}
3589
3590DEFUN (match_ipv6_next_hop,
3591 match_ipv6_next_hop_cmd,
3592 "match ipv6 next-hop X:X::X:X",
3593 MATCH_STR
3594 IPV6_STR
3595 "Match IPv6 next-hop address of route\n"
3596 "IPv6 address of next hop\n")
3597{
3598 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3599}
3600
3601DEFUN (no_match_ipv6_next_hop,
3602 no_match_ipv6_next_hop_cmd,
3603 "no match ipv6 next-hop X:X::X:X",
3604 NO_STR
3605 MATCH_STR
3606 IPV6_STR
3607 "Match IPv6 next-hop address of route\n"
3608 "IPv6 address of next hop\n")
3609{
3610 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3611}
3612
3613DEFUN (match_ipv6_address_prefix_list,
3614 match_ipv6_address_prefix_list_cmd,
3615 "match ipv6 address prefix-list WORD",
3616 MATCH_STR
3617 IPV6_STR
3618 "Match address of route\n"
3619 "Match entries of prefix-lists\n"
3620 "IP prefix-list name\n")
3621{
3622 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3623}
3624
3625DEFUN (no_match_ipv6_address_prefix_list,
3626 no_match_ipv6_address_prefix_list_cmd,
3627 "no match ipv6 address prefix-list WORD",
3628 NO_STR
3629 MATCH_STR
3630 IPV6_STR
3631 "Match address of route\n"
3632 "Match entries of prefix-lists\n"
3633 "IP prefix-list name\n")
3634{
3635 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3636}
3637
3638DEFUN (set_ipv6_nexthop_global,
3639 set_ipv6_nexthop_global_cmd,
3640 "set ipv6 next-hop global X:X::X:X",
3641 SET_STR
3642 IPV6_STR
3643 "IPv6 next-hop address\n"
3644 "IPv6 global address\n"
3645 "IPv6 address of next hop\n")
3646{
3647 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3648}
3649
3650DEFUN (no_set_ipv6_nexthop_global,
3651 no_set_ipv6_nexthop_global_cmd,
3652 "no set ipv6 next-hop global",
3653 NO_STR
3654 SET_STR
3655 IPV6_STR
3656 "IPv6 next-hop address\n"
3657 "IPv6 global address\n")
3658{
3659 if (argc == 0)
3660 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3661
3662 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3663}
3664
3665ALIAS (no_set_ipv6_nexthop_global,
3666 no_set_ipv6_nexthop_global_val_cmd,
3667 "no set ipv6 next-hop global X:X::X:X",
3668 NO_STR
3669 SET_STR
3670 IPV6_STR
3671 "IPv6 next-hop address\n"
3672 "IPv6 global address\n"
3673 "IPv6 address of next hop\n")
3674
3675DEFUN (set_ipv6_nexthop_local,
3676 set_ipv6_nexthop_local_cmd,
3677 "set ipv6 next-hop local X:X::X:X",
3678 SET_STR
3679 IPV6_STR
3680 "IPv6 next-hop address\n"
3681 "IPv6 local address\n"
3682 "IPv6 address of next hop\n")
3683{
3684 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3685}
3686
3687DEFUN (no_set_ipv6_nexthop_local,
3688 no_set_ipv6_nexthop_local_cmd,
3689 "no set ipv6 next-hop local",
3690 NO_STR
3691 SET_STR
3692 IPV6_STR
3693 "IPv6 next-hop address\n"
3694 "IPv6 local address\n")
3695{
3696 if (argc == 0)
3697 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3698
3699 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3700}
3701
3702ALIAS (no_set_ipv6_nexthop_local,
3703 no_set_ipv6_nexthop_local_val_cmd,
3704 "no set ipv6 next-hop local X:X::X:X",
3705 NO_STR
3706 SET_STR
3707 IPV6_STR
3708 "IPv6 next-hop address\n"
3709 "IPv6 local address\n"
3710 "IPv6 address of next hop\n")
3711#endif /* HAVE_IPV6 */
3712
3713DEFUN (set_vpnv4_nexthop,
3714 set_vpnv4_nexthop_cmd,
3715 "set vpnv4 next-hop A.B.C.D",
3716 SET_STR
3717 "VPNv4 information\n"
3718 "VPNv4 next-hop address\n"
3719 "IP address of next hop\n")
3720{
3721 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3722}
3723
3724DEFUN (no_set_vpnv4_nexthop,
3725 no_set_vpnv4_nexthop_cmd,
3726 "no set vpnv4 next-hop",
3727 NO_STR
3728 SET_STR
3729 "VPNv4 information\n"
3730 "VPNv4 next-hop address\n")
3731{
3732 if (argc == 0)
3733 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3734
3735 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3736}
3737
3738ALIAS (no_set_vpnv4_nexthop,
3739 no_set_vpnv4_nexthop_val_cmd,
3740 "no set vpnv4 next-hop A.B.C.D",
3741 NO_STR
3742 SET_STR
3743 "VPNv4 information\n"
3744 "VPNv4 next-hop address\n"
3745 "IP address of next hop\n")
3746
3747DEFUN (set_originator_id,
3748 set_originator_id_cmd,
3749 "set originator-id A.B.C.D",
3750 SET_STR
3751 "BGP originator ID attribute\n"
3752 "IP address of originator\n")
3753{
3754 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3755}
3756
3757DEFUN (no_set_originator_id,
3758 no_set_originator_id_cmd,
3759 "no set originator-id",
3760 NO_STR
3761 SET_STR
3762 "BGP originator ID attribute\n")
3763{
3764 if (argc == 0)
3765 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3766
3767 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3768}
3769
3770ALIAS (no_set_originator_id,
3771 no_set_originator_id_val_cmd,
3772 "no set originator-id A.B.C.D",
3773 NO_STR
3774 SET_STR
3775 "BGP originator ID attribute\n"
3776 "IP address of originator\n")
3777
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003778DEFUN_DEPRECATED (set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003779 set_pathlimit_ttl_cmd,
3780 "set pathlimit ttl <1-255>",
3781 SET_STR
3782 "BGP AS-Pathlimit attribute\n"
3783 "Set AS-Path Hop-count TTL\n")
3784{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003785 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003786}
3787
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003788DEFUN_DEPRECATED (no_set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003789 no_set_pathlimit_ttl_cmd,
3790 "no set pathlimit ttl",
3791 NO_STR
3792 SET_STR
3793 "BGP AS-Pathlimit attribute\n"
3794 "Set AS-Path Hop-count TTL\n")
3795{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003796 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003797}
3798
3799ALIAS (no_set_pathlimit_ttl,
3800 no_set_pathlimit_ttl_val_cmd,
3801 "no set pathlimit ttl <1-255>",
3802 NO_STR
3803 MATCH_STR
3804 "BGP AS-Pathlimit attribute\n"
3805 "Set AS-Path Hop-count TTL\n")
3806
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003807DEFUN_DEPRECATED (match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003808 match_pathlimit_as_cmd,
3809 "match pathlimit as <1-65535>",
3810 MATCH_STR
3811 "BGP AS-Pathlimit attribute\n"
3812 "Match Pathlimit AS number\n")
3813{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003814 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003815}
3816
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003817DEFUN_DEPRECATED (no_match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003818 no_match_pathlimit_as_cmd,
3819 "no match pathlimit as",
3820 NO_STR
3821 MATCH_STR
3822 "BGP AS-Pathlimit attribute\n"
3823 "Match Pathlimit AS number\n")
3824{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003825 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003826}
3827
3828ALIAS (no_match_pathlimit_as,
3829 no_match_pathlimit_as_val_cmd,
3830 "no match pathlimit as <1-65535>",
3831 NO_STR
3832 MATCH_STR
3833 "BGP AS-Pathlimit attribute\n"
3834 "Match Pathlimit ASN\n")
3835
paul718e3742002-12-13 20:15:29 +00003836
3837/* Initialization of route map. */
3838void
paul94f2b392005-06-28 12:44:16 +00003839bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003840{
3841 route_map_init ();
3842 route_map_init_vty ();
3843 route_map_add_hook (bgp_route_map_update);
3844 route_map_delete_hook (bgp_route_map_update);
3845
paulfee0f4c2004-09-13 05:12:46 +00003846 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003847 route_map_install_match (&route_match_ip_address_cmd);
3848 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003849 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003850 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3851 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003852 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003853 route_map_install_match (&route_match_aspath_cmd);
3854 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003855 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003856 route_map_install_match (&route_match_metric_cmd);
3857 route_map_install_match (&route_match_origin_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003858 route_map_install_match (&route_match_probability_cmd);
paul718e3742002-12-13 20:15:29 +00003859
3860 route_map_install_set (&route_set_ip_nexthop_cmd);
3861 route_map_install_set (&route_set_local_pref_cmd);
3862 route_map_install_set (&route_set_weight_cmd);
3863 route_map_install_set (&route_set_metric_cmd);
3864 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003865 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003866 route_map_install_set (&route_set_origin_cmd);
3867 route_map_install_set (&route_set_atomic_aggregate_cmd);
3868 route_map_install_set (&route_set_aggregator_as_cmd);
3869 route_map_install_set (&route_set_community_cmd);
3870 route_map_install_set (&route_set_community_delete_cmd);
3871 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3872 route_map_install_set (&route_set_originator_id_cmd);
3873 route_map_install_set (&route_set_ecommunity_rt_cmd);
3874 route_map_install_set (&route_set_ecommunity_soo_cmd);
3875
paulfee0f4c2004-09-13 05:12:46 +00003876 install_element (RMAP_NODE, &match_peer_cmd);
3877 install_element (RMAP_NODE, &match_peer_local_cmd);
3878 install_element (RMAP_NODE, &no_match_peer_cmd);
3879 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3880 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003881 install_element (RMAP_NODE, &match_ip_address_cmd);
3882 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3883 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3884 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3885 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3886 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003887 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3888 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3889 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003890 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3891 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3892 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3893 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3894 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3895 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003896 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3897 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3898 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003899
3900 install_element (RMAP_NODE, &match_aspath_cmd);
3901 install_element (RMAP_NODE, &no_match_aspath_cmd);
3902 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3903 install_element (RMAP_NODE, &match_metric_cmd);
3904 install_element (RMAP_NODE, &no_match_metric_cmd);
3905 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3906 install_element (RMAP_NODE, &match_community_cmd);
3907 install_element (RMAP_NODE, &match_community_exact_cmd);
3908 install_element (RMAP_NODE, &no_match_community_cmd);
3909 install_element (RMAP_NODE, &no_match_community_val_cmd);
3910 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003911 install_element (RMAP_NODE, &match_ecommunity_cmd);
3912 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3913 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003914 install_element (RMAP_NODE, &match_origin_cmd);
3915 install_element (RMAP_NODE, &no_match_origin_cmd);
3916 install_element (RMAP_NODE, &no_match_origin_val_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003917 install_element (RMAP_NODE, &match_probability_cmd);
3918 install_element (RMAP_NODE, &no_match_probability_cmd);
3919 install_element (RMAP_NODE, &no_match_probability_val_cmd);
paul718e3742002-12-13 20:15:29 +00003920
3921 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003922 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003923 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3924 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3925 install_element (RMAP_NODE, &set_local_pref_cmd);
3926 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3927 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3928 install_element (RMAP_NODE, &set_weight_cmd);
3929 install_element (RMAP_NODE, &no_set_weight_cmd);
3930 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3931 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003932 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00003933 install_element (RMAP_NODE, &no_set_metric_cmd);
3934 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3935 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003936 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003937 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3938 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003939 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
3940 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00003941 install_element (RMAP_NODE, &set_origin_cmd);
3942 install_element (RMAP_NODE, &no_set_origin_cmd);
3943 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3944 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3945 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3946 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3947 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3948 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3949 install_element (RMAP_NODE, &set_community_cmd);
3950 install_element (RMAP_NODE, &set_community_none_cmd);
3951 install_element (RMAP_NODE, &no_set_community_cmd);
3952 install_element (RMAP_NODE, &no_set_community_val_cmd);
3953 install_element (RMAP_NODE, &no_set_community_none_cmd);
3954 install_element (RMAP_NODE, &set_community_delete_cmd);
3955 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3956 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3957 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3958 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3959 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3960 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3961 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3962 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3963 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3964 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3965 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3966 install_element (RMAP_NODE, &set_originator_id_cmd);
3967 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3968 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3969
3970#ifdef HAVE_IPV6
3971 route_map_install_match (&route_match_ipv6_address_cmd);
3972 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3973 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3974 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3975 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Paul Jakma41367172007-08-06 15:24:51 +00003976
paul718e3742002-12-13 20:15:29 +00003977 install_element (RMAP_NODE, &match_ipv6_address_cmd);
3978 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
3979 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
3980 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
3981 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
3982 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
3983 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
3984 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
3985 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
3986 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
3987 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
3988 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
3989#endif /* HAVE_IPV6 */
Paul Jakma41367172007-08-06 15:24:51 +00003990
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003991 /* AS-Pathlimit: functionality removed, commands kept for
3992 * compatibility.
3993 */
Paul Jakma41367172007-08-06 15:24:51 +00003994 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
3995 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
3996 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
3997 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
3998 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
3999 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00004000}