blob: 5467cfdc4358a534dbd1f960120c62d36013bd8d [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
Timo Teräs2aa640b2014-05-20 08:57:26 +030096o Local extensions
paul718e3742002-12-13 20:15:29 +000097
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*/
David Lamparter6b0655a2014-06-04 06:53:35 +0200103
Timo Teräs38f22ab2015-04-29 09:43:02 +0300104 /* generic value manipulation to be shared in multiple rules */
105
106#define RMAP_VALUE_SET 0
107#define RMAP_VALUE_ADD 1
108#define RMAP_VALUE_SUB 2
109
110struct rmap_value
111{
112 u_int8_t action;
Timo Teräsef757702015-04-29 09:43:04 +0300113 u_int8_t variable;
Timo Teräs38f22ab2015-04-29 09:43:02 +0300114 u_int32_t value;
115};
116
117static int
118route_value_match (struct rmap_value *rv, u_int32_t value)
119{
Timo Teräsef757702015-04-29 09:43:04 +0300120 if (rv->variable == 0 && value == rv->value)
Timo Teräs38f22ab2015-04-29 09:43:02 +0300121 return RMAP_MATCH;
122
123 return RMAP_NOMATCH;
124}
125
126static u_int32_t
Timo Teräsef757702015-04-29 09:43:04 +0300127route_value_adjust (struct rmap_value *rv, u_int32_t current, struct peer *peer)
Timo Teräs38f22ab2015-04-29 09:43:02 +0300128{
Timo Teräsef757702015-04-29 09:43:04 +0300129 u_int32_t value;
130
131 switch (rv->variable)
132 {
133 case 1:
134 value = peer->rtt;
135 break;
136 default:
137 value = rv->value;
138 break;
139 }
Timo Teräs38f22ab2015-04-29 09:43:02 +0300140
141 switch (rv->action)
142 {
143 case RMAP_VALUE_ADD:
144 if (current > UINT32_MAX-value)
145 return UINT32_MAX;
146 return current + value;
147 case RMAP_VALUE_SUB:
148 if (current <= value)
149 return 0;
150 return current - value;
151 default:
152 return value;
153 }
154}
155
156static void *
157route_value_compile (const char *arg)
158{
Timo Teräsef757702015-04-29 09:43:04 +0300159 u_int8_t action = RMAP_VALUE_SET, var = 0;
160 unsigned long larg = 0;
Timo Teräs38f22ab2015-04-29 09:43:02 +0300161 char *endptr = NULL;
162 struct rmap_value *rv;
163
164 if (arg[0] == '+')
165 {
166 action = RMAP_VALUE_ADD;
167 arg++;
168 }
169 else if (arg[0] == '-')
170 {
171 action = RMAP_VALUE_SUB;
172 arg++;
173 }
174
Timo Teräsef757702015-04-29 09:43:04 +0300175 if (all_digit(arg))
176 {
177 errno = 0;
178 larg = strtoul (arg, &endptr, 10);
179 if (*arg == 0 || *endptr != 0 || errno || larg > UINT32_MAX)
180 return NULL;
181 }
182 else
183 {
184 if (strcmp(arg, "rtt") == 0)
185 var = 1;
186 else
187 return NULL;
188 }
Timo Teräs38f22ab2015-04-29 09:43:02 +0300189
190 rv = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_value));
191 if (!rv)
192 return NULL;
193
194 rv->action = action;
Timo Teräsef757702015-04-29 09:43:04 +0300195 rv->variable = var;
Timo Teräs38f22ab2015-04-29 09:43:02 +0300196 rv->value = larg;
197 return rv;
198}
199
200static void
201route_value_free (void *rule)
202{
203 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
204}
205
Timo Teräsb304dcb2014-05-20 09:04:49 +0300206 /* generic as path object to be shared in multiple rules */
207
208static void *
209route_aspath_compile (const char *arg)
210{
211 struct aspath *aspath;
212
213 aspath = aspath_str2aspath (arg);
214 if (! aspath)
215 return NULL;
216 return aspath;
217}
218
219static void
220route_aspath_free (void *rule)
221{
222 struct aspath *aspath = rule;
223 aspath_free (aspath);
224}
225
paulfee0f4c2004-09-13 05:12:46 +0000226 /* 'match peer (A.B.C.D|X:X::X:X)' */
227
228/* Compares the peer specified in the 'match peer' clause with the peer
229 received in bgp_info->peer. If it is the same, or if the peer structure
230 received is a peer_group containing it, returns RMAP_MATCH. */
paul94f2b392005-06-28 12:44:16 +0000231static route_map_result_t
paulfee0f4c2004-09-13 05:12:46 +0000232route_match_peer (void *rule, struct prefix *prefix, route_map_object_t type,
233 void *object)
234{
235 union sockunion *su;
David Lamparter6ed810d2015-04-21 10:13:07 +0200236 union sockunion su_def = { .sin = { .sin_family = AF_INET,
237 .sin_addr.s_addr = INADDR_ANY } };
paulfee0f4c2004-09-13 05:12:46 +0000238 struct peer_group *group;
239 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +0000240 struct listnode *node, *nnode;
paulfee0f4c2004-09-13 05:12:46 +0000241
242 if (type == RMAP_BGP)
243 {
244 su = rule;
245 peer = ((struct bgp_info *) object)->peer;
246
247 if ( ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT) &&
248 ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_EXPORT) )
249 return RMAP_NOMATCH;
250
251 /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
252 REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200253 if (sockunion_same (su, &su_def))
paulfee0f4c2004-09-13 05:12:46 +0000254 {
paul22db9de2005-05-19 01:50:11 +0000255 int ret;
paulfee0f4c2004-09-13 05:12:46 +0000256 if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
257 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE) ||
258 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
paul22db9de2005-05-19 01:50:11 +0000259 ret = RMAP_MATCH;
paulfee0f4c2004-09-13 05:12:46 +0000260 else
paul22db9de2005-05-19 01:50:11 +0000261 ret = RMAP_NOMATCH;
paul22db9de2005-05-19 01:50:11 +0000262 return ret;
paulfee0f4c2004-09-13 05:12:46 +0000263 }
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200264
paulfee0f4c2004-09-13 05:12:46 +0000265 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
266 {
267 if (sockunion_same (su, &peer->su))
268 return RMAP_MATCH;
269
270 return RMAP_NOMATCH;
271 }
272 else
273 {
274 group = peer->group;
paul1eb8ef22005-04-07 07:30:20 +0000275 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
paulfee0f4c2004-09-13 05:12:46 +0000276 {
277 if (sockunion_same (su, &peer->su))
278 return RMAP_MATCH;
paulfee0f4c2004-09-13 05:12:46 +0000279 }
Paul Jakma30a22312008-08-15 14:05:22 +0100280 return RMAP_NOMATCH;
paulfee0f4c2004-09-13 05:12:46 +0000281 }
282 }
283 return RMAP_NOMATCH;
284}
285
paul94f2b392005-06-28 12:44:16 +0000286static void *
paulfd79ac92004-10-13 05:06:08 +0000287route_match_peer_compile (const char *arg)
paulfee0f4c2004-09-13 05:12:46 +0000288{
289 union sockunion *su;
290 int ret;
291
292 su = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union sockunion));
293
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +0200294 ret = str2sockunion (strcmp(arg, "local") ? arg : "0.0.0.0", su);
paulfee0f4c2004-09-13 05:12:46 +0000295 if (ret < 0) {
296 XFREE (MTYPE_ROUTE_MAP_COMPILED, su);
297 return NULL;
298 }
299
300 return su;
301}
302
303/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000304static void
paulfee0f4c2004-09-13 05:12:46 +0000305route_match_peer_free (void *rule)
306{
307 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
308}
309
310/* Route map commands for ip address matching. */
311struct route_map_rule_cmd route_match_peer_cmd =
312{
313 "peer",
314 route_match_peer,
315 route_match_peer_compile,
316 route_match_peer_free
317};
318
paul718e3742002-12-13 20:15:29 +0000319/* `match ip address IP_ACCESS_LIST' */
320
321/* Match function should return 1 if match is success else return
322 zero. */
paul94f2b392005-06-28 12:44:16 +0000323static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000324route_match_ip_address (void *rule, struct prefix *prefix,
325 route_map_object_t type, void *object)
326{
327 struct access_list *alist;
328 /* struct prefix_ipv4 match; */
329
330 if (type == RMAP_BGP)
331 {
332 alist = access_list_lookup (AFI_IP, (char *) rule);
333 if (alist == NULL)
334 return RMAP_NOMATCH;
335
336 return (access_list_apply (alist, prefix) == FILTER_DENY ?
337 RMAP_NOMATCH : RMAP_MATCH);
338 }
339 return RMAP_NOMATCH;
340}
341
342/* Route map `ip address' match statement. `arg' should be
343 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000344static void *
paulfd79ac92004-10-13 05:06:08 +0000345route_match_ip_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000346{
347 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
348}
349
350/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000351static void
paul718e3742002-12-13 20:15:29 +0000352route_match_ip_address_free (void *rule)
353{
354 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
355}
356
357/* Route map commands for ip address matching. */
358struct route_map_rule_cmd route_match_ip_address_cmd =
359{
360 "ip address",
361 route_match_ip_address,
362 route_match_ip_address_compile,
363 route_match_ip_address_free
364};
David Lamparter6b0655a2014-06-04 06:53:35 +0200365
paul718e3742002-12-13 20:15:29 +0000366/* `match ip next-hop IP_ADDRESS' */
367
368/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000369static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000370route_match_ip_next_hop (void *rule, struct prefix *prefix,
371 route_map_object_t type, void *object)
372{
373 struct access_list *alist;
374 struct bgp_info *bgp_info;
375 struct prefix_ipv4 p;
376
377 if (type == RMAP_BGP)
378 {
379 bgp_info = object;
380 p.family = AF_INET;
381 p.prefix = bgp_info->attr->nexthop;
382 p.prefixlen = IPV4_MAX_BITLEN;
383
384 alist = access_list_lookup (AFI_IP, (char *) rule);
385 if (alist == NULL)
386 return RMAP_NOMATCH;
387
388 return (access_list_apply (alist, &p) == FILTER_DENY ?
389 RMAP_NOMATCH : RMAP_MATCH);
390 }
391 return RMAP_NOMATCH;
392}
393
394/* Route map `ip next-hop' match statement. `arg' is
395 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000396static void *
paulfd79ac92004-10-13 05:06:08 +0000397route_match_ip_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000398{
399 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
400}
401
402/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000403static void
paul718e3742002-12-13 20:15:29 +0000404route_match_ip_next_hop_free (void *rule)
405{
406 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
407}
408
409/* Route map commands for ip next-hop matching. */
410struct route_map_rule_cmd route_match_ip_next_hop_cmd =
411{
412 "ip next-hop",
413 route_match_ip_next_hop,
414 route_match_ip_next_hop_compile,
415 route_match_ip_next_hop_free
416};
David Lamparter6b0655a2014-06-04 06:53:35 +0200417
hassoc1643bb2005-02-02 16:43:17 +0000418/* `match ip route-source ACCESS-LIST' */
419
420/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000421static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000422route_match_ip_route_source (void *rule, struct prefix *prefix,
423 route_map_object_t type, void *object)
424{
425 struct access_list *alist;
426 struct bgp_info *bgp_info;
427 struct peer *peer;
428 struct prefix_ipv4 p;
429
430 if (type == RMAP_BGP)
431 {
432 bgp_info = object;
433 peer = bgp_info->peer;
434
435 if (! peer || sockunion_family (&peer->su) != AF_INET)
436 return RMAP_NOMATCH;
437
438 p.family = AF_INET;
439 p.prefix = peer->su.sin.sin_addr;
440 p.prefixlen = IPV4_MAX_BITLEN;
441
442 alist = access_list_lookup (AFI_IP, (char *) rule);
443 if (alist == NULL)
444 return RMAP_NOMATCH;
445
446 return (access_list_apply (alist, &p) == FILTER_DENY ?
447 RMAP_NOMATCH : RMAP_MATCH);
448 }
449 return RMAP_NOMATCH;
450}
451
452/* Route map `ip route-source' match statement. `arg' is
453 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000454static void *
hassoc1643bb2005-02-02 16:43:17 +0000455route_match_ip_route_source_compile (const char *arg)
456{
457 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
458}
459
460/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000461static void
hassoc1643bb2005-02-02 16:43:17 +0000462route_match_ip_route_source_free (void *rule)
463{
464 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
465}
466
467/* Route map commands for ip route-source matching. */
468struct route_map_rule_cmd route_match_ip_route_source_cmd =
469{
470 "ip route-source",
471 route_match_ip_route_source,
472 route_match_ip_route_source_compile,
473 route_match_ip_route_source_free
474};
David Lamparter6b0655a2014-06-04 06:53:35 +0200475
paul718e3742002-12-13 20:15:29 +0000476/* `match ip address prefix-list PREFIX_LIST' */
477
paul94f2b392005-06-28 12:44:16 +0000478static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000479route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
480 route_map_object_t type, void *object)
481{
482 struct prefix_list *plist;
483
484 if (type == RMAP_BGP)
485 {
486 plist = prefix_list_lookup (AFI_IP, (char *) rule);
487 if (plist == NULL)
488 return RMAP_NOMATCH;
489
490 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
491 RMAP_NOMATCH : RMAP_MATCH);
492 }
493 return RMAP_NOMATCH;
494}
495
paul94f2b392005-06-28 12:44:16 +0000496static void *
paulfd79ac92004-10-13 05:06:08 +0000497route_match_ip_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000498{
499 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
500}
501
paul94f2b392005-06-28 12:44:16 +0000502static void
paul718e3742002-12-13 20:15:29 +0000503route_match_ip_address_prefix_list_free (void *rule)
504{
505 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
506}
507
508struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
509{
510 "ip address prefix-list",
511 route_match_ip_address_prefix_list,
512 route_match_ip_address_prefix_list_compile,
513 route_match_ip_address_prefix_list_free
514};
David Lamparter6b0655a2014-06-04 06:53:35 +0200515
paul718e3742002-12-13 20:15:29 +0000516/* `match ip next-hop prefix-list PREFIX_LIST' */
517
paul94f2b392005-06-28 12:44:16 +0000518static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000519route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
520 route_map_object_t type, void *object)
521{
522 struct prefix_list *plist;
523 struct bgp_info *bgp_info;
524 struct prefix_ipv4 p;
525
526 if (type == RMAP_BGP)
527 {
528 bgp_info = object;
529 p.family = AF_INET;
530 p.prefix = bgp_info->attr->nexthop;
531 p.prefixlen = IPV4_MAX_BITLEN;
532
533 plist = prefix_list_lookup (AFI_IP, (char *) rule);
534 if (plist == NULL)
535 return RMAP_NOMATCH;
536
537 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
538 RMAP_NOMATCH : RMAP_MATCH);
539 }
540 return RMAP_NOMATCH;
541}
542
paul94f2b392005-06-28 12:44:16 +0000543static void *
paulfd79ac92004-10-13 05:06:08 +0000544route_match_ip_next_hop_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000545{
546 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
547}
548
paul94f2b392005-06-28 12:44:16 +0000549static void
paul718e3742002-12-13 20:15:29 +0000550route_match_ip_next_hop_prefix_list_free (void *rule)
551{
552 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
553}
554
555struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
556{
557 "ip next-hop prefix-list",
558 route_match_ip_next_hop_prefix_list,
559 route_match_ip_next_hop_prefix_list_compile,
560 route_match_ip_next_hop_prefix_list_free
561};
David Lamparter6b0655a2014-06-04 06:53:35 +0200562
hassoc1643bb2005-02-02 16:43:17 +0000563/* `match ip route-source prefix-list PREFIX_LIST' */
564
paul94f2b392005-06-28 12:44:16 +0000565static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000566route_match_ip_route_source_prefix_list (void *rule, struct prefix *prefix,
567 route_map_object_t type, void *object)
568{
569 struct prefix_list *plist;
570 struct bgp_info *bgp_info;
571 struct peer *peer;
572 struct prefix_ipv4 p;
573
574 if (type == RMAP_BGP)
575 {
576 bgp_info = object;
577 peer = bgp_info->peer;
578
579 if (! peer || sockunion_family (&peer->su) != AF_INET)
580 return RMAP_NOMATCH;
581
582 p.family = AF_INET;
583 p.prefix = peer->su.sin.sin_addr;
584 p.prefixlen = IPV4_MAX_BITLEN;
585
586 plist = prefix_list_lookup (AFI_IP, (char *) rule);
587 if (plist == NULL)
588 return RMAP_NOMATCH;
589
590 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
591 RMAP_NOMATCH : RMAP_MATCH);
592 }
593 return RMAP_NOMATCH;
594}
595
paul94f2b392005-06-28 12:44:16 +0000596static void *
hassoc1643bb2005-02-02 16:43:17 +0000597route_match_ip_route_source_prefix_list_compile (const char *arg)
598{
599 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
600}
601
paul94f2b392005-06-28 12:44:16 +0000602static void
hassoc1643bb2005-02-02 16:43:17 +0000603route_match_ip_route_source_prefix_list_free (void *rule)
604{
605 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
606}
607
608struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd =
609{
610 "ip route-source prefix-list",
611 route_match_ip_route_source_prefix_list,
612 route_match_ip_route_source_prefix_list_compile,
613 route_match_ip_route_source_prefix_list_free
614};
David Lamparter6b0655a2014-06-04 06:53:35 +0200615
paul718e3742002-12-13 20:15:29 +0000616/* `match metric METRIC' */
617
618/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000619static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000620route_match_metric (void *rule, struct prefix *prefix,
621 route_map_object_t type, void *object)
622{
Timo Teräs38f22ab2015-04-29 09:43:02 +0300623 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +0000624 struct bgp_info *bgp_info;
625
626 if (type == RMAP_BGP)
627 {
Timo Teräs38f22ab2015-04-29 09:43:02 +0300628 rv = rule;
paul718e3742002-12-13 20:15:29 +0000629 bgp_info = object;
Timo Teräs38f22ab2015-04-29 09:43:02 +0300630 return route_value_match(rv, bgp_info->attr->med);
paul718e3742002-12-13 20:15:29 +0000631 }
632 return RMAP_NOMATCH;
633}
634
paul718e3742002-12-13 20:15:29 +0000635/* Route map commands for metric matching. */
636struct route_map_rule_cmd route_match_metric_cmd =
637{
638 "metric",
639 route_match_metric,
Timo Teräs38f22ab2015-04-29 09:43:02 +0300640 route_value_compile,
641 route_value_free,
paul718e3742002-12-13 20:15:29 +0000642};
David Lamparter6b0655a2014-06-04 06:53:35 +0200643
paul718e3742002-12-13 20:15:29 +0000644/* `match as-path ASPATH' */
645
646/* Match function for as-path match. I assume given object is */
paul94f2b392005-06-28 12:44:16 +0000647static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000648route_match_aspath (void *rule, struct prefix *prefix,
649 route_map_object_t type, void *object)
650{
651
652 struct as_list *as_list;
653 struct bgp_info *bgp_info;
654
655 if (type == RMAP_BGP)
656 {
657 as_list = as_list_lookup ((char *) rule);
658 if (as_list == NULL)
659 return RMAP_NOMATCH;
660
661 bgp_info = object;
662
663 /* Perform match. */
664 return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
665 }
666 return RMAP_NOMATCH;
667}
668
669/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000670static void *
paulfd79ac92004-10-13 05:06:08 +0000671route_match_aspath_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000672{
673 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
674}
675
676/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000677static void
paul718e3742002-12-13 20:15:29 +0000678route_match_aspath_free (void *rule)
679{
680 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
681}
682
683/* Route map commands for aspath matching. */
684struct route_map_rule_cmd route_match_aspath_cmd =
685{
686 "as-path",
687 route_match_aspath,
688 route_match_aspath_compile,
689 route_match_aspath_free
690};
David Lamparter6b0655a2014-06-04 06:53:35 +0200691
paul718e3742002-12-13 20:15:29 +0000692/* `match community COMMUNIY' */
693struct rmap_community
694{
695 char *name;
696 int exact;
697};
698
699/* Match function for community match. */
paul94f2b392005-06-28 12:44:16 +0000700static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000701route_match_community (void *rule, struct prefix *prefix,
702 route_map_object_t type, void *object)
703{
704 struct community_list *list;
705 struct bgp_info *bgp_info;
706 struct rmap_community *rcom;
707
708 if (type == RMAP_BGP)
709 {
710 bgp_info = object;
711 rcom = rule;
712
hassofee6e4e2005-02-02 16:29:31 +0000713 list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +0000714 if (! list)
715 return RMAP_NOMATCH;
716
717 if (rcom->exact)
718 {
719 if (community_list_exact_match (bgp_info->attr->community, list))
720 return RMAP_MATCH;
721 }
722 else
723 {
724 if (community_list_match (bgp_info->attr->community, list))
725 return RMAP_MATCH;
726 }
727 }
728 return RMAP_NOMATCH;
729}
730
731/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000732static void *
paulfd79ac92004-10-13 05:06:08 +0000733route_match_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000734{
735 struct rmap_community *rcom;
736 int len;
737 char *p;
738
739 rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
740
741 p = strchr (arg, ' ');
742 if (p)
743 {
744 len = p - arg;
745 rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
746 memcpy (rcom->name, arg, len);
747 rcom->exact = 1;
748 }
749 else
750 {
751 rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
752 rcom->exact = 0;
753 }
754 return rcom;
755}
756
757/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000758static void
paul718e3742002-12-13 20:15:29 +0000759route_match_community_free (void *rule)
760{
761 struct rmap_community *rcom = rule;
762
763 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
764 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
765}
766
767/* Route map commands for community matching. */
768struct route_map_rule_cmd route_match_community_cmd =
769{
770 "community",
771 route_match_community,
772 route_match_community_compile,
773 route_match_community_free
774};
David Lamparter6b0655a2014-06-04 06:53:35 +0200775
paul73ffb252003-04-19 15:49:49 +0000776/* Match function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000777static route_map_result_t
paul73ffb252003-04-19 15:49:49 +0000778route_match_ecommunity (void *rule, struct prefix *prefix,
779 route_map_object_t type, void *object)
780{
781 struct community_list *list;
782 struct bgp_info *bgp_info;
783
784 if (type == RMAP_BGP)
785 {
786 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +0000787
788 if (!bgp_info->attr->extra)
789 return RMAP_NOMATCH;
790
paul73ffb252003-04-19 15:49:49 +0000791 list = community_list_lookup (bgp_clist, (char *) rule,
hassofee6e4e2005-02-02 16:29:31 +0000792 EXTCOMMUNITY_LIST_MASTER);
paul73ffb252003-04-19 15:49:49 +0000793 if (! list)
794 return RMAP_NOMATCH;
795
Paul Jakmafb982c22007-05-04 20:15:47 +0000796 if (ecommunity_list_match (bgp_info->attr->extra->ecommunity, list))
paul73ffb252003-04-19 15:49:49 +0000797 return RMAP_MATCH;
798 }
799 return RMAP_NOMATCH;
800}
801
802/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000803static void *
paulfd79ac92004-10-13 05:06:08 +0000804route_match_ecommunity_compile (const char *arg)
paul73ffb252003-04-19 15:49:49 +0000805{
806 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
807}
808
809/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000810static void
paul73ffb252003-04-19 15:49:49 +0000811route_match_ecommunity_free (void *rule)
812{
813 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
814}
815
816/* Route map commands for community matching. */
817struct route_map_rule_cmd route_match_ecommunity_cmd =
818{
819 "extcommunity",
820 route_match_ecommunity,
821 route_match_ecommunity_compile,
822 route_match_ecommunity_free
823};
David Lamparter6b0655a2014-06-04 06:53:35 +0200824
paul718e3742002-12-13 20:15:29 +0000825/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
826 and `address-family vpnv4'. */
David Lamparter6b0655a2014-06-04 06:53:35 +0200827
paul718e3742002-12-13 20:15:29 +0000828/* `match origin' */
paul94f2b392005-06-28 12:44:16 +0000829static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000830route_match_origin (void *rule, struct prefix *prefix,
831 route_map_object_t type, void *object)
832{
833 u_char *origin;
834 struct bgp_info *bgp_info;
835
836 if (type == RMAP_BGP)
837 {
838 origin = rule;
839 bgp_info = object;
840
841 if (bgp_info->attr->origin == *origin)
842 return RMAP_MATCH;
843 }
844
845 return RMAP_NOMATCH;
846}
847
paul94f2b392005-06-28 12:44:16 +0000848static void *
paulfd79ac92004-10-13 05:06:08 +0000849route_match_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000850{
851 u_char *origin;
852
853 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
854
855 if (strcmp (arg, "igp") == 0)
856 *origin = 0;
857 else if (strcmp (arg, "egp") == 0)
858 *origin = 1;
859 else
860 *origin = 2;
861
862 return origin;
863}
864
865/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000866static void
paul718e3742002-12-13 20:15:29 +0000867route_match_origin_free (void *rule)
868{
869 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
870}
871
872/* Route map commands for origin matching. */
873struct route_map_rule_cmd route_match_origin_cmd =
874{
875 "origin",
876 route_match_origin,
877 route_match_origin_compile,
878 route_match_origin_free
879};
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400880
881/* match probability { */
882
883static route_map_result_t
884route_match_probability (void *rule, struct prefix *prefix,
885 route_map_object_t type, void *object)
886{
887 long r;
888#if _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500
889 r = random();
890#else
891 r = (long) rand();
892#endif
893
David Lamparter8c9cd852015-04-19 14:40:02 +0200894 switch (*(long *) rule)
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400895 {
896 case 0: break;
897 case RAND_MAX: return RMAP_MATCH;
898 default:
David Lamparter8c9cd852015-04-19 14:40:02 +0200899 if (r < *(long *) rule)
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400900 {
901 return RMAP_MATCH;
902 }
903 }
904
905 return RMAP_NOMATCH;
906}
907
908static void *
909route_match_probability_compile (const char *arg)
910{
David Lamparter8c9cd852015-04-19 14:40:02 +0200911 long *lobule;
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400912 unsigned perc;
913
914#if _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500
915 srandom (time (NULL));
916#else
917 srand (time (NULL));
918#endif
919
920 perc = atoi (arg);
David Lamparter8c9cd852015-04-19 14:40:02 +0200921 lobule = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (long));
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400922
923 switch (perc)
924 {
925 case 0: *lobule = 0; break;
926 case 100: *lobule = RAND_MAX; break;
927 default: *lobule = RAND_MAX / 100 * perc;
928 }
929
930 return lobule;
931}
932
933static void
934route_match_probability_free (void *rule)
935{
936 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
937}
938
939struct route_map_rule_cmd route_match_probability_cmd =
940{
941 "probability",
942 route_match_probability,
943 route_match_probability_compile,
944 route_match_probability_free
945};
946
947/* } */
948
paul718e3742002-12-13 20:15:29 +0000949/* `set ip next-hop IP_ADDRESS' */
950
951/* Set nexthop to object. ojbect must be pointer to struct attr. */
paulac41b2a2003-08-12 05:32:27 +0000952struct rmap_ip_nexthop_set
953{
954 struct in_addr *address;
955 int peer_address;
956};
957
paul94f2b392005-06-28 12:44:16 +0000958static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000959route_set_ip_nexthop (void *rule, struct prefix *prefix,
960 route_map_object_t type, void *object)
961{
paulac41b2a2003-08-12 05:32:27 +0000962 struct rmap_ip_nexthop_set *rins = rule;
paul718e3742002-12-13 20:15:29 +0000963 struct bgp_info *bgp_info;
paulac41b2a2003-08-12 05:32:27 +0000964 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000965
966 if (type == RMAP_BGP)
967 {
paul718e3742002-12-13 20:15:29 +0000968 bgp_info = object;
paulac41b2a2003-08-12 05:32:27 +0000969 peer = bgp_info->peer;
970
971 if (rins->peer_address)
972 {
paulfee0f4c2004-09-13 05:12:46 +0000973 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
974 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
paulac41b2a2003-08-12 05:32:27 +0000975 && peer->su_remote
976 && sockunion_family (peer->su_remote) == AF_INET)
977 {
Jorge Boncompte [DTI2]0c5ed3e2012-04-10 16:57:22 +0200978 bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote);
paulac41b2a2003-08-12 05:32:27 +0000979 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
980 }
981 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
982 && peer->su_local
983 && sockunion_family (peer->su_local) == AF_INET)
984 {
Jorge Boncompte [DTI2]0c5ed3e2012-04-10 16:57:22 +0200985 bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_local);
paulac41b2a2003-08-12 05:32:27 +0000986 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
987 }
988 }
989 else
990 {
991 /* Set next hop value. */
992 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
993 bgp_info->attr->nexthop = *rins->address;
994 }
paul718e3742002-12-13 20:15:29 +0000995 }
996
997 return RMAP_OKAY;
998}
999
1000/* Route map `ip nexthop' compile function. Given string is converted
1001 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001002static void *
paulfd79ac92004-10-13 05:06:08 +00001003route_set_ip_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001004{
paulac41b2a2003-08-12 05:32:27 +00001005 struct rmap_ip_nexthop_set *rins;
1006 struct in_addr *address = NULL;
1007 int peer_address = 0;
paul718e3742002-12-13 20:15:29 +00001008 int ret;
paul718e3742002-12-13 20:15:29 +00001009
paulac41b2a2003-08-12 05:32:27 +00001010 if (strcmp (arg, "peer-address") == 0)
1011 peer_address = 1;
1012 else
paul718e3742002-12-13 20:15:29 +00001013 {
paulac41b2a2003-08-12 05:32:27 +00001014 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
1015 ret = inet_aton (arg, address);
1016
1017 if (ret == 0)
1018 {
1019 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1020 return NULL;
1021 }
paul718e3742002-12-13 20:15:29 +00001022 }
1023
Stephen Hemminger393deb92008-08-18 14:13:29 -07001024 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
paulac41b2a2003-08-12 05:32:27 +00001025
1026 rins->address = address;
1027 rins->peer_address = peer_address;
1028
1029 return rins;
paul718e3742002-12-13 20:15:29 +00001030}
1031
1032/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00001033static void
paul718e3742002-12-13 20:15:29 +00001034route_set_ip_nexthop_free (void *rule)
1035{
paulac41b2a2003-08-12 05:32:27 +00001036 struct rmap_ip_nexthop_set *rins = rule;
1037
1038 if (rins->address)
1039 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
1040
1041 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +00001042}
1043
1044/* Route map commands for ip nexthop set. */
1045struct route_map_rule_cmd route_set_ip_nexthop_cmd =
1046{
1047 "ip next-hop",
1048 route_set_ip_nexthop,
1049 route_set_ip_nexthop_compile,
1050 route_set_ip_nexthop_free
1051};
David Lamparter6b0655a2014-06-04 06:53:35 +02001052
paul718e3742002-12-13 20:15:29 +00001053/* `set local-preference LOCAL_PREF' */
1054
1055/* Set local preference. */
paul94f2b392005-06-28 12:44:16 +00001056static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001057route_set_local_pref (void *rule, struct prefix *prefix,
1058 route_map_object_t type, void *object)
1059{
Timo Teräs38f22ab2015-04-29 09:43:02 +03001060 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +00001061 struct bgp_info *bgp_info;
Timo Teräs38f22ab2015-04-29 09:43:02 +03001062 u_int32_t locpref = 0;
paul718e3742002-12-13 20:15:29 +00001063
1064 if (type == RMAP_BGP)
1065 {
1066 /* Fetch routemap's rule information. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001067 rv = rule;
paul718e3742002-12-13 20:15:29 +00001068 bgp_info = object;
1069
1070 /* Set local preference value. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001071 if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
1072 locpref = bgp_info->attr->local_pref;
1073
paul718e3742002-12-13 20:15:29 +00001074 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
Timo Teräsef757702015-04-29 09:43:04 +03001075 bgp_info->attr->local_pref = route_value_adjust(rv, locpref, bgp_info->peer);
paul718e3742002-12-13 20:15:29 +00001076 }
1077
1078 return RMAP_OKAY;
1079}
1080
paul718e3742002-12-13 20:15:29 +00001081/* Set local preference rule structure. */
1082struct route_map_rule_cmd route_set_local_pref_cmd =
1083{
1084 "local-preference",
1085 route_set_local_pref,
Timo Teräs38f22ab2015-04-29 09:43:02 +03001086 route_value_compile,
1087 route_value_free,
paul718e3742002-12-13 20:15:29 +00001088};
David Lamparter6b0655a2014-06-04 06:53:35 +02001089
paul718e3742002-12-13 20:15:29 +00001090/* `set weight WEIGHT' */
1091
1092/* Set weight. */
paul94f2b392005-06-28 12:44:16 +00001093static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001094route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
1095 void *object)
1096{
Timo Teräs38f22ab2015-04-29 09:43:02 +03001097 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +00001098 struct bgp_info *bgp_info;
Timo Teräs38f22ab2015-04-29 09:43:02 +03001099 u_int32_t weight;
paul718e3742002-12-13 20:15:29 +00001100
1101 if (type == RMAP_BGP)
1102 {
1103 /* Fetch routemap's rule information. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001104 rv = rule;
paul718e3742002-12-13 20:15:29 +00001105 bgp_info = object;
1106
1107 /* Set weight value. */
Timo Teräsef757702015-04-29 09:43:04 +03001108 weight = route_value_adjust(rv, 0, bgp_info->peer);
Timo Teräs38f22ab2015-04-29 09:43:02 +03001109 if (weight)
1110 (bgp_attr_extra_get (bgp_info->attr))->weight = weight;
Paul Jakmafb982c22007-05-04 20:15:47 +00001111 else if (bgp_info->attr->extra)
1112 bgp_info->attr->extra->weight = 0;
paul718e3742002-12-13 20:15:29 +00001113 }
1114
1115 return RMAP_OKAY;
1116}
1117
paul718e3742002-12-13 20:15:29 +00001118/* Set local preference rule structure. */
1119struct route_map_rule_cmd route_set_weight_cmd =
1120{
1121 "weight",
1122 route_set_weight,
Timo Teräs38f22ab2015-04-29 09:43:02 +03001123 route_value_compile,
1124 route_value_free,
paul718e3742002-12-13 20:15:29 +00001125};
David Lamparter6b0655a2014-06-04 06:53:35 +02001126
paul718e3742002-12-13 20:15:29 +00001127/* `set metric METRIC' */
1128
1129/* Set metric to attribute. */
paul94f2b392005-06-28 12:44:16 +00001130static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001131route_set_metric (void *rule, struct prefix *prefix,
1132 route_map_object_t type, void *object)
1133{
Timo Teräs38f22ab2015-04-29 09:43:02 +03001134 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +00001135 struct bgp_info *bgp_info;
Timo Teräs38f22ab2015-04-29 09:43:02 +03001136 u_int32_t med = 0;
paul718e3742002-12-13 20:15:29 +00001137
1138 if (type == RMAP_BGP)
1139 {
1140 /* Fetch routemap's rule information. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001141 rv = rule;
paul718e3742002-12-13 20:15:29 +00001142 bgp_info = object;
1143
Timo Teräs38f22ab2015-04-29 09:43:02 +03001144 if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
1145 med = bgp_info->attr->med;
1146
Timo Teräsef757702015-04-29 09:43:04 +03001147 bgp_info->attr->med = route_value_adjust(rv, med, bgp_info->peer);
paul718e3742002-12-13 20:15:29 +00001148 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
paul718e3742002-12-13 20:15:29 +00001149 }
1150 return RMAP_OKAY;
1151}
1152
paul718e3742002-12-13 20:15:29 +00001153/* Set metric rule structure. */
1154struct route_map_rule_cmd route_set_metric_cmd =
1155{
1156 "metric",
1157 route_set_metric,
Timo Teräs38f22ab2015-04-29 09:43:02 +03001158 route_value_compile,
1159 route_value_free,
paul718e3742002-12-13 20:15:29 +00001160};
David Lamparter6b0655a2014-06-04 06:53:35 +02001161
paul718e3742002-12-13 20:15:29 +00001162/* `set as-path prepend ASPATH' */
1163
1164/* For AS path prepend mechanism. */
paul94f2b392005-06-28 12:44:16 +00001165static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001166route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1167{
1168 struct aspath *aspath;
1169 struct aspath *new;
1170 struct bgp_info *binfo;
1171
1172 if (type == RMAP_BGP)
1173 {
paul718e3742002-12-13 20:15:29 +00001174 binfo = object;
1175
1176 if (binfo->attr->aspath->refcnt)
1177 new = aspath_dup (binfo->attr->aspath);
1178 else
1179 new = binfo->attr->aspath;
1180
Timo Teräs85c854a2014-09-30 11:31:53 +03001181 if ((uintptr_t)rule > 10)
1182 {
1183 aspath = rule;
1184 aspath_prepend (aspath, new);
1185 }
1186 else
1187 {
1188 as_t as = aspath_leftmost(new);
1189 if (!as) as = binfo->peer->as;
1190 new = aspath_add_seq_n (new, as, (uintptr_t) rule);
1191 }
1192
paul718e3742002-12-13 20:15:29 +00001193 binfo->attr->aspath = new;
1194 }
1195
1196 return RMAP_OKAY;
1197}
1198
Timo Teräs85c854a2014-09-30 11:31:53 +03001199static void *
1200route_set_aspath_prepend_compile (const char *arg)
1201{
1202 unsigned int num;
1203
1204 if (sscanf(arg, "last-as %u", &num) == 1 && num > 0 && num < 10)
1205 return (void*)(uintptr_t)num;
1206
1207 return route_aspath_compile(arg);
1208}
1209
1210static void
1211route_set_aspath_prepend_free (void *rule)
1212{
1213 if ((uintptr_t)rule > 10)
1214 route_aspath_free(rule);
1215}
1216
1217
Timo Teräs2aa640b2014-05-20 08:57:26 +03001218/* Set as-path prepend rule structure. */
paul718e3742002-12-13 20:15:29 +00001219struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1220{
1221 "as-path prepend",
1222 route_set_aspath_prepend,
Timo Teräs85c854a2014-09-30 11:31:53 +03001223 route_set_aspath_prepend_compile,
1224 route_set_aspath_prepend_free,
paul718e3742002-12-13 20:15:29 +00001225};
David Lamparter6b0655a2014-06-04 06:53:35 +02001226
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001227/* `set as-path exclude ASn' */
1228
1229/* For ASN exclude mechanism.
1230 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1231 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1232 */
1233static route_map_result_t
1234route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
1235{
1236 struct aspath * new_path, * exclude_path;
1237 struct bgp_info *binfo;
1238
1239 if (type == RMAP_BGP)
1240 {
1241 exclude_path = rule;
1242 binfo = object;
1243 if (binfo->attr->aspath->refcnt)
1244 new_path = aspath_dup (binfo->attr->aspath);
1245 else
1246 new_path = binfo->attr->aspath;
1247 binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
1248 }
1249 return RMAP_OKAY;
1250}
1251
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001252/* Set ASn exlude rule structure. */
1253struct route_map_rule_cmd route_set_aspath_exclude_cmd =
1254{
1255 "as-path exclude",
1256 route_set_aspath_exclude,
Timo Teräsb304dcb2014-05-20 09:04:49 +03001257 route_aspath_compile,
1258 route_aspath_free,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001259};
David Lamparter6b0655a2014-06-04 06:53:35 +02001260
paul718e3742002-12-13 20:15:29 +00001261/* `set community COMMUNITY' */
1262struct rmap_com_set
1263{
1264 struct community *com;
1265 int additive;
1266 int none;
1267};
1268
1269/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001270static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001271route_set_community (void *rule, struct prefix *prefix,
1272 route_map_object_t type, void *object)
1273{
1274 struct rmap_com_set *rcs;
1275 struct bgp_info *binfo;
1276 struct attr *attr;
1277 struct community *new = NULL;
1278 struct community *old;
1279 struct community *merge;
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001280
paul718e3742002-12-13 20:15:29 +00001281 if (type == RMAP_BGP)
1282 {
1283 rcs = rule;
1284 binfo = object;
1285 attr = binfo->attr;
1286 old = attr->community;
1287
1288 /* "none" case. */
1289 if (rcs->none)
1290 {
1291 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1292 attr->community = NULL;
Christian Frankeb06b35f2012-12-07 14:26:09 +00001293 /* See the longer comment down below. */
1294 if (old && old->refcnt == 0)
1295 community_free(old);
paul718e3742002-12-13 20:15:29 +00001296 return RMAP_OKAY;
1297 }
1298
1299 /* "additive" case. */
1300 if (rcs->additive && old)
1301 {
1302 merge = community_merge (community_dup (old), rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001303
1304 /* HACK: if the old community is not intern'd,
1305 * we should free it here, or all reference to it may be lost.
1306 * Really need to cleanup attribute caching sometime.
1307 */
1308 if (old->refcnt == 0)
1309 community_free (old);
paul718e3742002-12-13 20:15:29 +00001310 new = community_uniq_sort (merge);
1311 community_free (merge);
1312 }
1313 else
1314 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001315
1316 /* will be interned by caller if required */
Paul Jakma4a2035f2011-04-01 15:58:27 +01001317 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001318
paul718e3742002-12-13 20:15:29 +00001319 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1320 }
1321
1322 return RMAP_OKAY;
1323}
1324
1325/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001326static void *
paulfd79ac92004-10-13 05:06:08 +00001327route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001328{
1329 struct rmap_com_set *rcs;
1330 struct community *com = NULL;
1331 char *sp;
1332 int additive = 0;
1333 int none = 0;
1334
1335 if (strcmp (arg, "none") == 0)
1336 none = 1;
1337 else
1338 {
1339 sp = strstr (arg, "additive");
1340
1341 if (sp && sp > arg)
1342 {
1343 /* "additive" keyworkd is included. */
1344 additive = 1;
1345 *(sp - 1) = '\0';
1346 }
1347
1348 com = community_str2com (arg);
1349
1350 if (additive)
1351 *(sp - 1) = ' ';
1352
1353 if (! com)
1354 return NULL;
1355 }
1356
Stephen Hemminger393deb92008-08-18 14:13:29 -07001357 rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
Paul Jakma4a2035f2011-04-01 15:58:27 +01001358 rcs->com = com;
paul718e3742002-12-13 20:15:29 +00001359 rcs->additive = additive;
1360 rcs->none = none;
1361
1362 return rcs;
1363}
1364
1365/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001366static void
paul718e3742002-12-13 20:15:29 +00001367route_set_community_free (void *rule)
1368{
1369 struct rmap_com_set *rcs = rule;
1370
1371 if (rcs->com)
1372 community_free (rcs->com);
1373 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1374}
1375
1376/* Set community rule structure. */
1377struct route_map_rule_cmd route_set_community_cmd =
1378{
1379 "community",
1380 route_set_community,
1381 route_set_community_compile,
1382 route_set_community_free,
1383};
David Lamparter6b0655a2014-06-04 06:53:35 +02001384
hassofee6e4e2005-02-02 16:29:31 +00001385/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001386
1387/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001388static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001389route_set_community_delete (void *rule, struct prefix *prefix,
1390 route_map_object_t type, void *object)
1391{
1392 struct community_list *list;
1393 struct community *merge;
1394 struct community *new;
1395 struct community *old;
1396 struct bgp_info *binfo;
1397
1398 if (type == RMAP_BGP)
1399 {
1400 if (! rule)
1401 return RMAP_OKAY;
1402
1403 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001404 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001405 old = binfo->attr->community;
1406
1407 if (list && old)
1408 {
1409 merge = community_list_match_delete (community_dup (old), list);
1410 new = community_uniq_sort (merge);
1411 community_free (merge);
1412
Michael Lambert604a9b42010-09-13 11:48:11 -04001413 /* HACK: if the old community is not intern'd,
1414 * we should free it here, or all reference to it may be lost.
1415 * Really need to cleanup attribute caching sometime.
1416 */
1417 if (old->refcnt == 0)
1418 community_free (old);
1419
paul718e3742002-12-13 20:15:29 +00001420 if (new->size == 0)
1421 {
1422 binfo->attr->community = NULL;
1423 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1424 community_free (new);
1425 }
1426 else
1427 {
Paul Jakma4a2035f2011-04-01 15:58:27 +01001428 binfo->attr->community = new;
paul718e3742002-12-13 20:15:29 +00001429 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1430 }
1431 }
1432 }
1433
1434 return RMAP_OKAY;
1435}
1436
1437/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001438static void *
paulfd79ac92004-10-13 05:06:08 +00001439route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001440{
1441 char *p;
1442 char *str;
1443 int len;
1444
1445 p = strchr (arg, ' ');
1446 if (p)
1447 {
1448 len = p - arg;
1449 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1450 memcpy (str, arg, len);
1451 }
1452 else
1453 str = NULL;
1454
1455 return str;
1456}
1457
1458/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001459static void
paul718e3742002-12-13 20:15:29 +00001460route_set_community_delete_free (void *rule)
1461{
1462 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1463}
1464
1465/* Set community rule structure. */
1466struct route_map_rule_cmd route_set_community_delete_cmd =
1467{
1468 "comm-list",
1469 route_set_community_delete,
1470 route_set_community_delete_compile,
1471 route_set_community_delete_free,
1472};
David Lamparter6b0655a2014-06-04 06:53:35 +02001473
paul718e3742002-12-13 20:15:29 +00001474/* `set extcommunity rt COMMUNITY' */
1475
David Lamparter73d78ea2014-06-04 00:58:47 +02001476/* For community set mechanism. Used by _rt and _soo. */
paul94f2b392005-06-28 12:44:16 +00001477static route_map_result_t
David Lamparter73d78ea2014-06-04 00:58:47 +02001478route_set_ecommunity (void *rule, struct prefix *prefix,
1479 route_map_object_t type, void *object)
paul718e3742002-12-13 20:15:29 +00001480{
1481 struct ecommunity *ecom;
1482 struct ecommunity *new_ecom;
1483 struct ecommunity *old_ecom;
1484 struct bgp_info *bgp_info;
1485
1486 if (type == RMAP_BGP)
1487 {
1488 ecom = rule;
1489 bgp_info = object;
1490
1491 if (! ecom)
1492 return RMAP_OKAY;
1493
1494 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001495 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001496
1497 if (old_ecom)
David Lamparter27bf90a2014-06-04 00:59:01 +02001498 {
1499 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1500
1501 /* old_ecom->refcnt = 1 => owned elsewhere, e.g. bgp_update_receive()
1502 * ->refcnt = 0 => set by a previous route-map statement */
1503 if (!old_ecom->refcnt)
1504 ecommunity_free (&old_ecom);
1505 }
paul718e3742002-12-13 20:15:29 +00001506 else
1507 new_ecom = ecommunity_dup (ecom);
1508
David Lamparter27bf90a2014-06-04 00:59:01 +02001509 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
1510 bgp_info->attr->extra->ecommunity = new_ecom;
hasso70601e02005-05-27 03:26:57 +00001511
paul718e3742002-12-13 20:15:29 +00001512 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1513 }
1514 return RMAP_OKAY;
1515}
1516
1517/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001518static void *
paulfd79ac92004-10-13 05:06:08 +00001519route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001520{
1521 struct ecommunity *ecom;
1522
1523 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1524 if (! ecom)
1525 return NULL;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001526 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001527}
1528
David Lamparter73d78ea2014-06-04 00:58:47 +02001529/* Free function for set community. Used by _rt and _soo */
paul94f2b392005-06-28 12:44:16 +00001530static void
David Lamparter73d78ea2014-06-04 00:58:47 +02001531route_set_ecommunity_free (void *rule)
paul718e3742002-12-13 20:15:29 +00001532{
1533 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001534 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001535}
1536
1537/* Set community rule structure. */
1538struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1539{
1540 "extcommunity rt",
David Lamparter73d78ea2014-06-04 00:58:47 +02001541 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001542 route_set_ecommunity_rt_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001543 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001544};
1545
1546/* `set extcommunity soo COMMUNITY' */
1547
paul718e3742002-12-13 20:15:29 +00001548/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001549static void *
paulfd79ac92004-10-13 05:06:08 +00001550route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001551{
1552 struct ecommunity *ecom;
1553
1554 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1555 if (! ecom)
1556 return NULL;
1557
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001558 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001559}
1560
paul718e3742002-12-13 20:15:29 +00001561/* Set community rule structure. */
1562struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1563{
1564 "extcommunity soo",
David Lamparter73d78ea2014-06-04 00:58:47 +02001565 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001566 route_set_ecommunity_soo_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001567 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001568};
David Lamparter6b0655a2014-06-04 06:53:35 +02001569
paul718e3742002-12-13 20:15:29 +00001570/* `set origin ORIGIN' */
1571
1572/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001573static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001574route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1575{
1576 u_char *origin;
1577 struct bgp_info *bgp_info;
1578
1579 if (type == RMAP_BGP)
1580 {
1581 origin = rule;
1582 bgp_info = object;
1583
1584 bgp_info->attr->origin = *origin;
1585 }
1586
1587 return RMAP_OKAY;
1588}
1589
1590/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001591static void *
paulfd79ac92004-10-13 05:06:08 +00001592route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001593{
1594 u_char *origin;
1595
1596 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1597
1598 if (strcmp (arg, "igp") == 0)
1599 *origin = 0;
1600 else if (strcmp (arg, "egp") == 0)
1601 *origin = 1;
1602 else
1603 *origin = 2;
1604
1605 return origin;
1606}
1607
1608/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001609static void
paul718e3742002-12-13 20:15:29 +00001610route_set_origin_free (void *rule)
1611{
1612 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1613}
1614
Timo Teräs2aa640b2014-05-20 08:57:26 +03001615/* Set origin rule structure. */
paul718e3742002-12-13 20:15:29 +00001616struct route_map_rule_cmd route_set_origin_cmd =
1617{
1618 "origin",
1619 route_set_origin,
1620 route_set_origin_compile,
1621 route_set_origin_free,
1622};
David Lamparter6b0655a2014-06-04 06:53:35 +02001623
paul718e3742002-12-13 20:15:29 +00001624/* `set atomic-aggregate' */
1625
1626/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001627static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001628route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1629 route_map_object_t type, void *object)
1630{
1631 struct bgp_info *bgp_info;
1632
1633 if (type == RMAP_BGP)
1634 {
1635 bgp_info = object;
1636 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1637 }
1638
1639 return RMAP_OKAY;
1640}
1641
1642/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001643static void *
paulfd79ac92004-10-13 05:06:08 +00001644route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001645{
1646 return (void *)1;
1647}
1648
1649/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001650static void
paul718e3742002-12-13 20:15:29 +00001651route_set_atomic_aggregate_free (void *rule)
1652{
1653 return;
1654}
1655
1656/* Set atomic aggregate rule structure. */
1657struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1658{
1659 "atomic-aggregate",
1660 route_set_atomic_aggregate,
1661 route_set_atomic_aggregate_compile,
1662 route_set_atomic_aggregate_free,
1663};
David Lamparter6b0655a2014-06-04 06:53:35 +02001664
paul718e3742002-12-13 20:15:29 +00001665/* `set aggregator as AS A.B.C.D' */
1666struct aggregator
1667{
1668 as_t as;
1669 struct in_addr address;
1670};
1671
paul94f2b392005-06-28 12:44:16 +00001672static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001673route_set_aggregator_as (void *rule, struct prefix *prefix,
1674 route_map_object_t type, void *object)
1675{
1676 struct bgp_info *bgp_info;
1677 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001678 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001679
1680 if (type == RMAP_BGP)
1681 {
1682 bgp_info = object;
1683 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001684 ae = bgp_attr_extra_get (bgp_info->attr);
1685
1686 ae->aggregator_as = aggregator->as;
1687 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001688 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1689 }
1690
1691 return RMAP_OKAY;
1692}
1693
paul94f2b392005-06-28 12:44:16 +00001694static void *
paulfd79ac92004-10-13 05:06:08 +00001695route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001696{
1697 struct aggregator *aggregator;
1698 char as[10];
1699 char address[20];
1700
Stephen Hemminger393deb92008-08-18 14:13:29 -07001701 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
paul718e3742002-12-13 20:15:29 +00001702 sscanf (arg, "%s %s", as, address);
1703
1704 aggregator->as = strtoul (as, NULL, 10);
1705 inet_aton (address, &aggregator->address);
1706
1707 return aggregator;
1708}
1709
paul94f2b392005-06-28 12:44:16 +00001710static void
paul718e3742002-12-13 20:15:29 +00001711route_set_aggregator_as_free (void *rule)
1712{
1713 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1714}
1715
1716struct route_map_rule_cmd route_set_aggregator_as_cmd =
1717{
1718 "aggregator as",
1719 route_set_aggregator_as,
1720 route_set_aggregator_as_compile,
1721 route_set_aggregator_as_free,
1722};
David Lamparter6b0655a2014-06-04 06:53:35 +02001723
paul718e3742002-12-13 20:15:29 +00001724#ifdef HAVE_IPV6
1725/* `match ipv6 address IP_ACCESS_LIST' */
1726
paul94f2b392005-06-28 12:44:16 +00001727static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001728route_match_ipv6_address (void *rule, struct prefix *prefix,
1729 route_map_object_t type, void *object)
1730{
1731 struct access_list *alist;
1732
1733 if (type == RMAP_BGP)
1734 {
1735 alist = access_list_lookup (AFI_IP6, (char *) rule);
1736 if (alist == NULL)
1737 return RMAP_NOMATCH;
1738
1739 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1740 RMAP_NOMATCH : RMAP_MATCH);
1741 }
1742 return RMAP_NOMATCH;
1743}
1744
paul94f2b392005-06-28 12:44:16 +00001745static void *
paulfd79ac92004-10-13 05:06:08 +00001746route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001747{
1748 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1749}
1750
paul94f2b392005-06-28 12:44:16 +00001751static void
paul718e3742002-12-13 20:15:29 +00001752route_match_ipv6_address_free (void *rule)
1753{
1754 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1755}
1756
1757/* Route map commands for ip address matching. */
1758struct route_map_rule_cmd route_match_ipv6_address_cmd =
1759{
1760 "ipv6 address",
1761 route_match_ipv6_address,
1762 route_match_ipv6_address_compile,
1763 route_match_ipv6_address_free
1764};
David Lamparter6b0655a2014-06-04 06:53:35 +02001765
paul718e3742002-12-13 20:15:29 +00001766/* `match ipv6 next-hop IP_ADDRESS' */
1767
paul94f2b392005-06-28 12:44:16 +00001768static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001769route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1770 route_map_object_t type, void *object)
1771{
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001772 struct in6_addr *addr = rule;
paul718e3742002-12-13 20:15:29 +00001773 struct bgp_info *bgp_info;
1774
1775 if (type == RMAP_BGP)
1776 {
paul718e3742002-12-13 20:15:29 +00001777 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001778
1779 if (!bgp_info->attr->extra)
1780 return RMAP_NOMATCH;
1781
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001782 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, addr))
paul718e3742002-12-13 20:15:29 +00001783 return RMAP_MATCH;
1784
Paul Jakmafb982c22007-05-04 20:15:47 +00001785 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001786 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, addr))
paul718e3742002-12-13 20:15:29 +00001787 return RMAP_MATCH;
1788
1789 return RMAP_NOMATCH;
1790 }
1791
1792 return RMAP_NOMATCH;
1793}
1794
paul94f2b392005-06-28 12:44:16 +00001795static void *
paulfd79ac92004-10-13 05:06:08 +00001796route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001797{
1798 struct in6_addr *address;
1799 int ret;
1800
1801 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1802
1803 ret = inet_pton (AF_INET6, arg, address);
1804 if (!ret)
1805 {
1806 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1807 return NULL;
1808 }
1809
1810 return address;
1811}
1812
paul94f2b392005-06-28 12:44:16 +00001813static void
paul718e3742002-12-13 20:15:29 +00001814route_match_ipv6_next_hop_free (void *rule)
1815{
1816 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1817}
1818
1819struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1820{
1821 "ipv6 next-hop",
1822 route_match_ipv6_next_hop,
1823 route_match_ipv6_next_hop_compile,
1824 route_match_ipv6_next_hop_free
1825};
David Lamparter6b0655a2014-06-04 06:53:35 +02001826
paul718e3742002-12-13 20:15:29 +00001827/* `match ipv6 address prefix-list PREFIX_LIST' */
1828
paul94f2b392005-06-28 12:44:16 +00001829static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001830route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1831 route_map_object_t type, void *object)
1832{
1833 struct prefix_list *plist;
1834
1835 if (type == RMAP_BGP)
1836 {
1837 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1838 if (plist == NULL)
1839 return RMAP_NOMATCH;
1840
1841 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1842 RMAP_NOMATCH : RMAP_MATCH);
1843 }
1844 return RMAP_NOMATCH;
1845}
1846
paul94f2b392005-06-28 12:44:16 +00001847static void *
paulfd79ac92004-10-13 05:06:08 +00001848route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001849{
1850 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1851}
1852
paul94f2b392005-06-28 12:44:16 +00001853static void
paul718e3742002-12-13 20:15:29 +00001854route_match_ipv6_address_prefix_list_free (void *rule)
1855{
1856 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1857}
1858
1859struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1860{
1861 "ipv6 address prefix-list",
1862 route_match_ipv6_address_prefix_list,
1863 route_match_ipv6_address_prefix_list_compile,
1864 route_match_ipv6_address_prefix_list_free
1865};
David Lamparter6b0655a2014-06-04 06:53:35 +02001866
paul718e3742002-12-13 20:15:29 +00001867/* `set ipv6 nexthop global IP_ADDRESS' */
1868
1869/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001870static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001871route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1872 route_map_object_t type, void *object)
1873{
1874 struct in6_addr *address;
1875 struct bgp_info *bgp_info;
1876
1877 if (type == RMAP_BGP)
1878 {
1879 /* Fetch routemap's rule information. */
1880 address = rule;
1881 bgp_info = object;
1882
1883 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001884 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00001885
1886 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001887 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1888 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00001889 }
1890
1891 return RMAP_OKAY;
1892}
1893
1894/* Route map `ip next-hop' compile function. Given string is converted
1895 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001896static void *
paulfd79ac92004-10-13 05:06:08 +00001897route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001898{
1899 int ret;
1900 struct in6_addr *address;
1901
1902 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1903
1904 ret = inet_pton (AF_INET6, arg, address);
1905
1906 if (ret == 0)
1907 {
1908 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1909 return NULL;
1910 }
1911
1912 return address;
1913}
1914
1915/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00001916static void
paul718e3742002-12-13 20:15:29 +00001917route_set_ipv6_nexthop_global_free (void *rule)
1918{
1919 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1920}
1921
1922/* Route map commands for ip nexthop set. */
1923struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
1924{
1925 "ipv6 next-hop global",
1926 route_set_ipv6_nexthop_global,
1927 route_set_ipv6_nexthop_global_compile,
1928 route_set_ipv6_nexthop_global_free
1929};
David Lamparter6b0655a2014-06-04 06:53:35 +02001930
paul718e3742002-12-13 20:15:29 +00001931/* `set ipv6 nexthop local IP_ADDRESS' */
1932
1933/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001934static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001935route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
1936 route_map_object_t type, void *object)
1937{
1938 struct in6_addr *address;
1939 struct bgp_info *bgp_info;
1940
1941 if (type == RMAP_BGP)
1942 {
1943 /* Fetch routemap's rule information. */
1944 address = rule;
1945 bgp_info = object;
1946
1947 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001948 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00001949
1950 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001951 if (bgp_info->attr->extra->mp_nexthop_len != 32)
1952 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00001953 }
1954
1955 return RMAP_OKAY;
1956}
1957
1958/* Route map `ip nexthop' compile function. Given string is converted
1959 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001960static void *
paulfd79ac92004-10-13 05:06:08 +00001961route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001962{
1963 int ret;
1964 struct in6_addr *address;
1965
1966 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1967
1968 ret = inet_pton (AF_INET6, arg, address);
1969
1970 if (ret == 0)
1971 {
1972 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1973 return NULL;
1974 }
1975
1976 return address;
1977}
1978
1979/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00001980static void
paul718e3742002-12-13 20:15:29 +00001981route_set_ipv6_nexthop_local_free (void *rule)
1982{
1983 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1984}
1985
1986/* Route map commands for ip nexthop set. */
1987struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
1988{
1989 "ipv6 next-hop local",
1990 route_set_ipv6_nexthop_local,
1991 route_set_ipv6_nexthop_local_compile,
1992 route_set_ipv6_nexthop_local_free
1993};
Dinesh G Duttad5233a2014-09-30 14:19:57 -07001994
1995/* `set ipv6 nexthop peer-address' */
1996
1997/* Set nexthop to object. ojbect must be pointer to struct attr. */
1998static route_map_result_t
1999route_set_ipv6_nexthop_peer (void *rule, struct prefix *prefix,
2000 route_map_object_t type, void *object)
2001{
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002002 struct in6_addr peer_address;
2003 struct bgp_info *bgp_info;
2004 struct peer *peer;
2005 char peer_addr_buf[INET6_ADDRSTRLEN];
2006
2007 if (type == RMAP_BGP)
2008 {
2009 /* Fetch routemap's rule information. */
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002010 bgp_info = object;
2011 peer = bgp_info->peer;
2012
2013 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
2014 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
2015 && peer->su_remote
2016 && sockunion_family (peer->su_remote) == AF_INET6)
2017 {
2018 inet_pton (AF_INET6, sockunion2str (peer->su_remote,
2019 peer_addr_buf,
2020 INET6_ADDRSTRLEN),
2021 &peer_address);
2022 }
2023 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
2024 && peer->su_local
2025 && sockunion_family (peer->su_local) == AF_INET6)
2026 {
2027 inet_pton (AF_INET, sockunion2str (peer->su_local,
2028 peer_addr_buf,
2029 INET6_ADDRSTRLEN),
2030 &peer_address);
2031 }
2032
2033 if (IN6_IS_ADDR_LINKLOCAL(&peer_address))
2034 {
2035 /* Set next hop value. */
2036 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = peer_address;
2037
2038 /* Set nexthop length. */
2039 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2040 bgp_info->attr->extra->mp_nexthop_len = 32;
2041 }
2042 else
2043 {
2044 /* Set next hop value. */
2045 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = peer_address;
2046
2047 /* Set nexthop length. */
2048 if (bgp_info->attr->extra->mp_nexthop_len == 0)
2049 bgp_info->attr->extra->mp_nexthop_len = 16;
2050 }
2051 }
2052
2053 return RMAP_OKAY;
2054}
2055
2056/* Route map `ip next-hop' compile function. Given string is converted
2057 to struct in_addr structure. */
2058static void *
2059route_set_ipv6_nexthop_peer_compile (const char *arg)
2060{
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002061 int *rins = NULL;
2062
2063 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (int));
2064 *rins = 1;
2065
2066 return rins;
2067}
2068
2069/* Free route map's compiled `ip next-hop' value. */
2070static void
2071route_set_ipv6_nexthop_peer_free (void *rule)
2072{
2073 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2074}
2075
2076/* Route map commands for ip nexthop set. */
2077struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd =
2078{
2079 "ipv6 next-hop peer-address",
2080 route_set_ipv6_nexthop_peer,
2081 route_set_ipv6_nexthop_peer_compile,
2082 route_set_ipv6_nexthop_peer_free
2083};
2084
paul718e3742002-12-13 20:15:29 +00002085#endif /* HAVE_IPV6 */
David Lamparter6b0655a2014-06-04 06:53:35 +02002086
paul718e3742002-12-13 20:15:29 +00002087/* `set vpnv4 nexthop A.B.C.D' */
2088
paul94f2b392005-06-28 12:44:16 +00002089static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002090route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2091 route_map_object_t type, void *object)
2092{
2093 struct in_addr *address;
2094 struct bgp_info *bgp_info;
2095
2096 if (type == RMAP_BGP)
2097 {
2098 /* Fetch routemap's rule information. */
2099 address = rule;
2100 bgp_info = object;
2101
2102 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002103 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
paul718e3742002-12-13 20:15:29 +00002104 }
2105
2106 return RMAP_OKAY;
2107}
2108
paul94f2b392005-06-28 12:44:16 +00002109static void *
paulfd79ac92004-10-13 05:06:08 +00002110route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002111{
2112 int ret;
2113 struct in_addr *address;
2114
2115 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2116
2117 ret = inet_aton (arg, address);
2118
2119 if (ret == 0)
2120 {
2121 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2122 return NULL;
2123 }
2124
2125 return address;
2126}
2127
paul94f2b392005-06-28 12:44:16 +00002128static void
paul718e3742002-12-13 20:15:29 +00002129route_set_vpnv4_nexthop_free (void *rule)
2130{
2131 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2132}
2133
2134/* Route map commands for ip nexthop set. */
2135struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2136{
2137 "vpnv4 next-hop",
2138 route_set_vpnv4_nexthop,
2139 route_set_vpnv4_nexthop_compile,
2140 route_set_vpnv4_nexthop_free
2141};
David Lamparter6b0655a2014-06-04 06:53:35 +02002142
paul718e3742002-12-13 20:15:29 +00002143/* `set originator-id' */
2144
2145/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002146static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002147route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2148{
2149 struct in_addr *address;
2150 struct bgp_info *bgp_info;
2151
2152 if (type == RMAP_BGP)
2153 {
2154 address = rule;
2155 bgp_info = object;
2156
2157 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002158 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002159 }
2160
2161 return RMAP_OKAY;
2162}
2163
2164/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002165static void *
paulfd79ac92004-10-13 05:06:08 +00002166route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002167{
2168 int ret;
2169 struct in_addr *address;
2170
2171 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2172
2173 ret = inet_aton (arg, address);
2174
2175 if (ret == 0)
2176 {
2177 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2178 return NULL;
2179 }
2180
2181 return address;
2182}
2183
2184/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002185static void
paul718e3742002-12-13 20:15:29 +00002186route_set_originator_id_free (void *rule)
2187{
2188 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2189}
2190
Timo Teräs2aa640b2014-05-20 08:57:26 +03002191/* Set originator-id rule structure. */
paul718e3742002-12-13 20:15:29 +00002192struct route_map_rule_cmd route_set_originator_id_cmd =
2193{
2194 "originator-id",
2195 route_set_originator_id,
2196 route_set_originator_id_compile,
2197 route_set_originator_id_free,
2198};
David Lamparter6b0655a2014-06-04 06:53:35 +02002199
paul718e3742002-12-13 20:15:29 +00002200/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002201static int
paul718e3742002-12-13 20:15:29 +00002202bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002203 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002204{
2205 int ret;
2206
2207 ret = route_map_add_match (index, command, arg);
2208 if (ret)
2209 {
2210 switch (ret)
2211 {
2212 case RMAP_RULE_MISSING:
2213 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2214 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002215 case RMAP_COMPILE_ERROR:
2216 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2217 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002218 }
2219 }
2220 return CMD_SUCCESS;
2221}
2222
2223/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002224static int
paul718e3742002-12-13 20:15:29 +00002225bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002226 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002227{
2228 int ret;
2229
2230 ret = route_map_delete_match (index, command, arg);
2231 if (ret)
2232 {
2233 switch (ret)
2234 {
2235 case RMAP_RULE_MISSING:
2236 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2237 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002238 case RMAP_COMPILE_ERROR:
2239 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2240 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002241 }
2242 }
2243 return CMD_SUCCESS;
2244}
2245
2246/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002247static int
paul718e3742002-12-13 20:15:29 +00002248bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002249 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002250{
2251 int ret;
2252
2253 ret = route_map_add_set (index, command, arg);
2254 if (ret)
2255 {
2256 switch (ret)
2257 {
2258 case RMAP_RULE_MISSING:
2259 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2260 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002261 case RMAP_COMPILE_ERROR:
2262 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2263 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002264 }
2265 }
2266 return CMD_SUCCESS;
2267}
2268
2269/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002270static int
paul718e3742002-12-13 20:15:29 +00002271bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002272 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002273{
2274 int ret;
2275
2276 ret = route_map_delete_set (index, command, arg);
2277 if (ret)
2278 {
2279 switch (ret)
2280 {
2281 case RMAP_RULE_MISSING:
2282 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2283 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002284 case RMAP_COMPILE_ERROR:
2285 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2286 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002287 }
2288 }
2289 return CMD_SUCCESS;
2290}
2291
2292/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002293static void
paulfd79ac92004-10-13 05:06:08 +00002294bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002295{
2296 int i;
2297 afi_t afi;
2298 safi_t safi;
2299 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002300 struct listnode *node, *nnode;
2301 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002302 struct bgp *bgp;
2303 struct peer *peer;
2304 struct peer_group *group;
2305 struct bgp_filter *filter;
2306 struct bgp_node *bn;
2307 struct bgp_static *bgp_static;
2308
2309 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002310 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002311 {
paul1eb8ef22005-04-07 07:30:20 +00002312 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002313 {
2314 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2315 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2316 {
2317 filter = &peer->filter[afi][safi];
2318
paulfee0f4c2004-09-13 05:12:46 +00002319 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002320 {
2321 if (filter->map[direct].name)
2322 filter->map[direct].map =
2323 route_map_lookup_by_name (filter->map[direct].name);
2324 else
2325 filter->map[direct].map = NULL;
2326 }
2327
2328 if (filter->usmap.name)
2329 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2330 else
2331 filter->usmap.map = NULL;
2332 }
2333 }
paul1eb8ef22005-04-07 07:30:20 +00002334 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002335 {
2336 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2337 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2338 {
2339 filter = &group->conf->filter[afi][safi];
2340
paulfee0f4c2004-09-13 05:12:46 +00002341 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002342 {
2343 if (filter->map[direct].name)
2344 filter->map[direct].map =
2345 route_map_lookup_by_name (filter->map[direct].name);
2346 else
2347 filter->map[direct].map = NULL;
2348 }
2349
2350 if (filter->usmap.name)
2351 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2352 else
2353 filter->usmap.map = NULL;
2354 }
2355 }
2356 }
2357
2358 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002359 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002360 {
paul1eb8ef22005-04-07 07:30:20 +00002361 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002362 {
2363 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2364 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2365 {
2366 if (peer->default_rmap[afi][safi].name)
2367 peer->default_rmap[afi][safi].map =
2368 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2369 else
2370 peer->default_rmap[afi][safi].map = NULL;
2371 }
2372 }
2373 }
2374
2375 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002376 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002377 {
2378 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2379 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2380 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2381 bn = bgp_route_next (bn))
2382 if ((bgp_static = bn->info) != NULL)
2383 {
2384 if (bgp_static->rmap.name)
2385 bgp_static->rmap.map =
2386 route_map_lookup_by_name (bgp_static->rmap.name);
2387 else
2388 bgp_static->rmap.map = NULL;
2389 }
2390 }
2391
2392 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002393 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002394 {
2395 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2396 {
2397 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2398 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2399 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2400#ifdef HAVE_IPV6
2401 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2402 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2403 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2404#endif /* HAVE_IPV6 */
2405 }
2406 }
2407}
David Lamparter6b0655a2014-06-04 06:53:35 +02002408
paulfee0f4c2004-09-13 05:12:46 +00002409DEFUN (match_peer,
2410 match_peer_cmd,
2411 "match peer (A.B.C.D|X:X::X:X)",
2412 MATCH_STR
2413 "Match peer address\n"
2414 "IPv6 address of peer\n"
2415 "IP address of peer\n")
2416{
2417 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2418}
2419
2420DEFUN (match_peer_local,
2421 match_peer_local_cmd,
2422 "match peer local",
2423 MATCH_STR
2424 "Match peer address\n"
2425 "Static or Redistributed routes\n")
2426{
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +02002427 return bgp_route_match_add (vty, vty->index, "peer", "local");
paulfee0f4c2004-09-13 05:12:46 +00002428}
2429
2430DEFUN (no_match_peer,
2431 no_match_peer_cmd,
2432 "no match peer",
2433 NO_STR
2434 MATCH_STR
2435 "Match peer address\n")
2436{
2437 if (argc == 0)
2438 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2439
2440 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2441}
2442
2443ALIAS (no_match_peer,
2444 no_match_peer_val_cmd,
2445 "no match peer (A.B.C.D|X:X::X:X)",
2446 NO_STR
2447 MATCH_STR
2448 "Match peer address\n"
2449 "IPv6 address of peer\n"
2450 "IP address of peer\n")
2451
2452ALIAS (no_match_peer,
2453 no_match_peer_local_cmd,
2454 "no match peer local",
2455 NO_STR
2456 MATCH_STR
2457 "Match peer address\n"
2458 "Static or Redistributed routes\n")
2459
paul718e3742002-12-13 20:15:29 +00002460DEFUN (match_ip_address,
2461 match_ip_address_cmd,
2462 "match ip address (<1-199>|<1300-2699>|WORD)",
2463 MATCH_STR
2464 IP_STR
2465 "Match address of route\n"
2466 "IP access-list number\n"
2467 "IP access-list number (expanded range)\n"
2468 "IP Access-list name\n")
2469{
2470 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2471}
2472
2473DEFUN (no_match_ip_address,
2474 no_match_ip_address_cmd,
2475 "no match ip address",
2476 NO_STR
2477 MATCH_STR
2478 IP_STR
2479 "Match address of route\n")
2480{
2481 if (argc == 0)
2482 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2483
2484 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2485}
2486
2487ALIAS (no_match_ip_address,
2488 no_match_ip_address_val_cmd,
2489 "no match ip address (<1-199>|<1300-2699>|WORD)",
2490 NO_STR
2491 MATCH_STR
2492 IP_STR
2493 "Match address of route\n"
2494 "IP access-list number\n"
2495 "IP access-list number (expanded range)\n"
2496 "IP Access-list name\n")
2497
2498DEFUN (match_ip_next_hop,
2499 match_ip_next_hop_cmd,
2500 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2501 MATCH_STR
2502 IP_STR
2503 "Match next-hop address of route\n"
2504 "IP access-list number\n"
2505 "IP access-list number (expanded range)\n"
2506 "IP Access-list name\n")
2507{
2508 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2509}
2510
2511DEFUN (no_match_ip_next_hop,
2512 no_match_ip_next_hop_cmd,
2513 "no match ip next-hop",
2514 NO_STR
2515 MATCH_STR
2516 IP_STR
2517 "Match next-hop address of route\n")
2518{
2519 if (argc == 0)
2520 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2521
2522 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2523}
2524
2525ALIAS (no_match_ip_next_hop,
2526 no_match_ip_next_hop_val_cmd,
2527 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2528 NO_STR
2529 MATCH_STR
2530 IP_STR
2531 "Match next-hop address of route\n"
2532 "IP access-list number\n"
2533 "IP access-list number (expanded range)\n"
2534 "IP Access-list name\n")
2535
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04002536/* match probability { */
2537
2538DEFUN (match_probability,
2539 match_probability_cmd,
2540 "match probability <0-100>",
2541 MATCH_STR
2542 "Match portion of routes defined by percentage value\n"
2543 "Percentage of routes\n")
2544{
2545 return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
2546}
2547
2548DEFUN (no_match_probability,
2549 no_match_probability_cmd,
2550 "no match probability",
2551 NO_STR
2552 MATCH_STR
2553 "Match portion of routes defined by percentage value\n")
2554{
2555 return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL);
2556}
2557
2558ALIAS (no_match_probability,
2559 no_match_probability_val_cmd,
2560 "no match probability <1-99>",
2561 NO_STR
2562 MATCH_STR
2563 "Match portion of routes defined by percentage value\n"
2564 "Percentage of routes\n")
2565
2566/* } */
2567
hassoc1643bb2005-02-02 16:43:17 +00002568DEFUN (match_ip_route_source,
2569 match_ip_route_source_cmd,
2570 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2571 MATCH_STR
2572 IP_STR
2573 "Match advertising source address of route\n"
2574 "IP access-list number\n"
2575 "IP access-list number (expanded range)\n"
2576 "IP standard access-list name\n")
2577{
2578 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2579}
2580
2581DEFUN (no_match_ip_route_source,
2582 no_match_ip_route_source_cmd,
2583 "no match ip route-source",
2584 NO_STR
2585 MATCH_STR
2586 IP_STR
2587 "Match advertising source address of route\n")
2588{
2589 if (argc == 0)
2590 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2591
2592 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2593}
2594
2595ALIAS (no_match_ip_route_source,
2596 no_match_ip_route_source_val_cmd,
2597 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2598 NO_STR
2599 MATCH_STR
2600 IP_STR
2601 "Match advertising source address of route\n"
2602 "IP access-list number\n"
2603 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002604 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002605
paul718e3742002-12-13 20:15:29 +00002606DEFUN (match_ip_address_prefix_list,
2607 match_ip_address_prefix_list_cmd,
2608 "match ip address prefix-list WORD",
2609 MATCH_STR
2610 IP_STR
2611 "Match address of route\n"
2612 "Match entries of prefix-lists\n"
2613 "IP prefix-list name\n")
2614{
2615 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2616}
2617
2618DEFUN (no_match_ip_address_prefix_list,
2619 no_match_ip_address_prefix_list_cmd,
2620 "no match ip address prefix-list",
2621 NO_STR
2622 MATCH_STR
2623 IP_STR
2624 "Match address of route\n"
2625 "Match entries of prefix-lists\n")
2626{
2627 if (argc == 0)
2628 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2629
2630 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2631}
2632
2633ALIAS (no_match_ip_address_prefix_list,
2634 no_match_ip_address_prefix_list_val_cmd,
2635 "no match ip address prefix-list WORD",
2636 NO_STR
2637 MATCH_STR
2638 IP_STR
2639 "Match address of route\n"
2640 "Match entries of prefix-lists\n"
2641 "IP prefix-list name\n")
2642
2643DEFUN (match_ip_next_hop_prefix_list,
2644 match_ip_next_hop_prefix_list_cmd,
2645 "match ip next-hop prefix-list WORD",
2646 MATCH_STR
2647 IP_STR
2648 "Match next-hop address of route\n"
2649 "Match entries of prefix-lists\n"
2650 "IP prefix-list name\n")
2651{
2652 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2653}
2654
2655DEFUN (no_match_ip_next_hop_prefix_list,
2656 no_match_ip_next_hop_prefix_list_cmd,
2657 "no match ip next-hop prefix-list",
2658 NO_STR
2659 MATCH_STR
2660 IP_STR
2661 "Match next-hop address of route\n"
2662 "Match entries of prefix-lists\n")
2663{
2664 if (argc == 0)
2665 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2666
2667 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2668}
2669
2670ALIAS (no_match_ip_next_hop_prefix_list,
2671 no_match_ip_next_hop_prefix_list_val_cmd,
2672 "no match ip next-hop prefix-list WORD",
2673 NO_STR
2674 MATCH_STR
2675 IP_STR
2676 "Match next-hop address of route\n"
2677 "Match entries of prefix-lists\n"
2678 "IP prefix-list name\n")
2679
hassoc1643bb2005-02-02 16:43:17 +00002680DEFUN (match_ip_route_source_prefix_list,
2681 match_ip_route_source_prefix_list_cmd,
2682 "match ip route-source prefix-list WORD",
2683 MATCH_STR
2684 IP_STR
2685 "Match advertising source address of route\n"
2686 "Match entries of prefix-lists\n"
2687 "IP prefix-list name\n")
2688{
2689 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2690}
2691
2692DEFUN (no_match_ip_route_source_prefix_list,
2693 no_match_ip_route_source_prefix_list_cmd,
2694 "no match ip route-source prefix-list",
2695 NO_STR
2696 MATCH_STR
2697 IP_STR
2698 "Match advertising source address of route\n"
2699 "Match entries of prefix-lists\n")
2700{
2701 if (argc == 0)
2702 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2703
2704 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2705}
2706
2707ALIAS (no_match_ip_route_source_prefix_list,
2708 no_match_ip_route_source_prefix_list_val_cmd,
2709 "no match ip route-source prefix-list WORD",
2710 NO_STR
2711 MATCH_STR
2712 IP_STR
2713 "Match advertising source address of route\n"
2714 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002715 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002716
paul718e3742002-12-13 20:15:29 +00002717DEFUN (match_metric,
2718 match_metric_cmd,
2719 "match metric <0-4294967295>",
2720 MATCH_STR
2721 "Match metric of route\n"
2722 "Metric value\n")
2723{
2724 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2725}
2726
2727DEFUN (no_match_metric,
2728 no_match_metric_cmd,
2729 "no match metric",
2730 NO_STR
2731 MATCH_STR
2732 "Match metric of route\n")
2733{
2734 if (argc == 0)
2735 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2736
2737 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2738}
2739
2740ALIAS (no_match_metric,
2741 no_match_metric_val_cmd,
2742 "no match metric <0-4294967295>",
2743 NO_STR
2744 MATCH_STR
2745 "Match metric of route\n"
2746 "Metric value\n")
2747
2748DEFUN (match_community,
2749 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002750 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002751 MATCH_STR
2752 "Match BGP community list\n"
2753 "Community-list number (standard)\n"
2754 "Community-list number (expanded)\n"
2755 "Community-list name\n")
2756{
2757 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2758}
2759
2760DEFUN (match_community_exact,
2761 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002762 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002763 MATCH_STR
2764 "Match BGP community list\n"
2765 "Community-list number (standard)\n"
2766 "Community-list number (expanded)\n"
2767 "Community-list name\n"
2768 "Do exact matching of communities\n")
2769{
2770 int ret;
2771 char *argstr;
2772
2773 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2774 strlen (argv[0]) + strlen ("exact-match") + 2);
2775
2776 sprintf (argstr, "%s exact-match", argv[0]);
2777
2778 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2779
2780 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2781
2782 return ret;
2783}
2784
2785DEFUN (no_match_community,
2786 no_match_community_cmd,
2787 "no match community",
2788 NO_STR
2789 MATCH_STR
2790 "Match BGP community list\n")
2791{
2792 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2793}
2794
2795ALIAS (no_match_community,
2796 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002797 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002798 NO_STR
2799 MATCH_STR
2800 "Match BGP community list\n"
2801 "Community-list number (standard)\n"
2802 "Community-list number (expanded)\n"
2803 "Community-list name\n")
2804
2805ALIAS (no_match_community,
2806 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002807 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002808 NO_STR
2809 MATCH_STR
2810 "Match BGP community list\n"
2811 "Community-list number (standard)\n"
2812 "Community-list number (expanded)\n"
2813 "Community-list name\n"
2814 "Do exact matching of communities\n")
2815
paul73ffb252003-04-19 15:49:49 +00002816DEFUN (match_ecommunity,
2817 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002818 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002819 MATCH_STR
2820 "Match BGP/VPN extended community list\n"
2821 "Extended community-list number (standard)\n"
2822 "Extended community-list number (expanded)\n"
2823 "Extended community-list name\n")
2824{
2825 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2826}
2827
2828DEFUN (no_match_ecommunity,
2829 no_match_ecommunity_cmd,
2830 "no match extcommunity",
2831 NO_STR
2832 MATCH_STR
2833 "Match BGP/VPN extended community list\n")
2834{
2835 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2836}
2837
2838ALIAS (no_match_ecommunity,
2839 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002840 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002841 NO_STR
2842 MATCH_STR
2843 "Match BGP/VPN extended community list\n"
2844 "Extended community-list number (standard)\n"
2845 "Extended community-list number (expanded)\n"
2846 "Extended community-list name\n")
2847
paul718e3742002-12-13 20:15:29 +00002848DEFUN (match_aspath,
2849 match_aspath_cmd,
2850 "match as-path WORD",
2851 MATCH_STR
2852 "Match BGP AS path list\n"
2853 "AS path access-list name\n")
2854{
2855 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2856}
2857
2858DEFUN (no_match_aspath,
2859 no_match_aspath_cmd,
2860 "no match as-path",
2861 NO_STR
2862 MATCH_STR
2863 "Match BGP AS path list\n")
2864{
2865 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2866}
2867
2868ALIAS (no_match_aspath,
2869 no_match_aspath_val_cmd,
2870 "no match as-path WORD",
2871 NO_STR
2872 MATCH_STR
2873 "Match BGP AS path list\n"
2874 "AS path access-list name\n")
2875
2876DEFUN (match_origin,
2877 match_origin_cmd,
2878 "match origin (egp|igp|incomplete)",
2879 MATCH_STR
2880 "BGP origin code\n"
2881 "remote EGP\n"
2882 "local IGP\n"
2883 "unknown heritage\n")
2884{
2885 if (strncmp (argv[0], "igp", 2) == 0)
2886 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2887 if (strncmp (argv[0], "egp", 1) == 0)
2888 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2889 if (strncmp (argv[0], "incomplete", 2) == 0)
2890 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2891
2892 return CMD_WARNING;
2893}
2894
2895DEFUN (no_match_origin,
2896 no_match_origin_cmd,
2897 "no match origin",
2898 NO_STR
2899 MATCH_STR
2900 "BGP origin code\n")
2901{
2902 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2903}
2904
2905ALIAS (no_match_origin,
2906 no_match_origin_val_cmd,
2907 "no match origin (egp|igp|incomplete)",
2908 NO_STR
2909 MATCH_STR
2910 "BGP origin code\n"
2911 "remote EGP\n"
2912 "local IGP\n"
2913 "unknown heritage\n")
2914
2915DEFUN (set_ip_nexthop,
2916 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002917 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002918 SET_STR
2919 IP_STR
2920 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002921 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002922{
2923 union sockunion su;
2924 int ret;
2925
2926 ret = str2sockunion (argv[0], &su);
2927 if (ret < 0)
2928 {
2929 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2930 return CMD_WARNING;
2931 }
2932
2933 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2934}
2935
paulaf5cd0a2003-11-02 07:24:40 +00002936DEFUN (set_ip_nexthop_peer,
2937 set_ip_nexthop_peer_cmd,
2938 "set ip next-hop peer-address",
2939 SET_STR
2940 IP_STR
2941 "Next hop address\n"
2942 "Use peer address (for BGP only)\n")
2943{
2944 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2945}
2946
paul94f2b392005-06-28 12:44:16 +00002947DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00002948 no_set_ip_nexthop_peer_cmd,
2949 "no set ip next-hop peer-address",
2950 NO_STR
2951 SET_STR
2952 IP_STR
2953 "Next hop address\n"
2954 "Use peer address (for BGP only)\n")
2955{
2956 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2957}
2958
2959
paul718e3742002-12-13 20:15:29 +00002960DEFUN (no_set_ip_nexthop,
2961 no_set_ip_nexthop_cmd,
2962 "no set ip next-hop",
2963 NO_STR
2964 SET_STR
paul718e3742002-12-13 20:15:29 +00002965 "Next hop address\n")
2966{
paulaf5cd0a2003-11-02 07:24:40 +00002967 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002968 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2969
2970 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2971}
2972
2973ALIAS (no_set_ip_nexthop,
2974 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002975 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002976 NO_STR
2977 SET_STR
2978 IP_STR
2979 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002980 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002981
2982DEFUN (set_metric,
2983 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002984 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002985 SET_STR
2986 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002987 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002988{
2989 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2990}
2991
paul73ffb252003-04-19 15:49:49 +00002992ALIAS (set_metric,
2993 set_metric_addsub_cmd,
2994 "set metric <+/-metric>",
2995 SET_STR
2996 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00002997 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00002998
Timo Teräsef757702015-04-29 09:43:04 +03002999ALIAS (set_metric,
3000 set_metric_rtt_cmd,
3001 "set metric (rtt|+rtt|-rtt)",
3002 SET_STR
3003 "Metric value for destination routing protocol\n"
3004 "Assign round trip time\n"
3005 "Add round trip time\n"
3006 "Subtract round trip time\n")
3007
paul718e3742002-12-13 20:15:29 +00003008DEFUN (no_set_metric,
3009 no_set_metric_cmd,
3010 "no set metric",
3011 NO_STR
3012 SET_STR
3013 "Metric value for destination routing protocol\n")
3014{
3015 if (argc == 0)
3016 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
3017
3018 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
3019}
3020
3021ALIAS (no_set_metric,
3022 no_set_metric_val_cmd,
3023 "no set metric <0-4294967295>",
3024 NO_STR
3025 SET_STR
3026 "Metric value for destination routing protocol\n"
3027 "Metric value\n")
3028
3029DEFUN (set_local_pref,
3030 set_local_pref_cmd,
3031 "set local-preference <0-4294967295>",
3032 SET_STR
3033 "BGP local preference path attribute\n"
3034 "Preference value\n")
3035{
3036 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
3037}
3038
3039DEFUN (no_set_local_pref,
3040 no_set_local_pref_cmd,
3041 "no set local-preference",
3042 NO_STR
3043 SET_STR
3044 "BGP local preference path attribute\n")
3045{
3046 if (argc == 0)
3047 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3048
3049 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
3050}
3051
3052ALIAS (no_set_local_pref,
3053 no_set_local_pref_val_cmd,
3054 "no set local-preference <0-4294967295>",
3055 NO_STR
3056 SET_STR
3057 "BGP local preference path attribute\n"
3058 "Preference value\n")
3059
3060DEFUN (set_weight,
3061 set_weight_cmd,
3062 "set weight <0-4294967295>",
3063 SET_STR
3064 "BGP weight for routing table\n"
3065 "Weight value\n")
3066{
3067 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3068}
3069
3070DEFUN (no_set_weight,
3071 no_set_weight_cmd,
3072 "no set weight",
3073 NO_STR
3074 SET_STR
3075 "BGP weight for routing table\n")
3076{
3077 if (argc == 0)
3078 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3079
3080 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3081}
3082
3083ALIAS (no_set_weight,
3084 no_set_weight_val_cmd,
3085 "no set weight <0-4294967295>",
3086 NO_STR
3087 SET_STR
3088 "BGP weight for routing table\n"
3089 "Weight value\n")
3090
3091DEFUN (set_aspath_prepend,
3092 set_aspath_prepend_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003093 "set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003094 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003095 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003096 "Prepend to the as-path\n"
3097 "AS number\n")
3098{
3099 int ret;
3100 char *str;
3101
3102 str = argv_concat (argv, argc, 0);
3103 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3104 XFREE (MTYPE_TMP, str);
3105
3106 return ret;
3107}
3108
Timo Teräs85c854a2014-09-30 11:31:53 +03003109ALIAS (set_aspath_prepend,
3110 set_aspath_prepend_lastas_cmd,
3111 "set as-path prepend (last-as) <1-10>",
3112 SET_STR
3113 "Transform BGP AS_PATH attribute\n"
3114 "Prepend to the as-path\n"
3115 "Use the peer's AS-number\n"
David Lamparterb7d50212015-03-03 08:53:18 +01003116 "Number of times to insert")
Timo Teräs85c854a2014-09-30 11:31:53 +03003117
paul718e3742002-12-13 20:15:29 +00003118DEFUN (no_set_aspath_prepend,
3119 no_set_aspath_prepend_cmd,
3120 "no set as-path prepend",
3121 NO_STR
3122 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003123 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003124 "Prepend to the as-path\n")
3125{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00003126 int ret;
3127 char *str;
3128
3129 if (argc == 0)
3130 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3131
3132 str = argv_concat (argv, argc, 0);
3133 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3134 XFREE (MTYPE_TMP, str);
3135 return ret;
paul718e3742002-12-13 20:15:29 +00003136}
3137
3138ALIAS (no_set_aspath_prepend,
3139 no_set_aspath_prepend_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003140 "no set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003141 NO_STR
3142 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003143 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003144 "Prepend to the as-path\n"
3145 "AS number\n")
3146
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003147DEFUN (set_aspath_exclude,
3148 set_aspath_exclude_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003149 "set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003150 SET_STR
3151 "Transform BGP AS-path attribute\n"
3152 "Exclude from the as-path\n"
3153 "AS number\n")
3154{
3155 int ret;
3156 char *str;
3157
3158 str = argv_concat (argv, argc, 0);
3159 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3160 XFREE (MTYPE_TMP, str);
3161 return ret;
3162}
3163
3164DEFUN (no_set_aspath_exclude,
3165 no_set_aspath_exclude_cmd,
3166 "no set as-path exclude",
3167 NO_STR
3168 SET_STR
3169 "Transform BGP AS_PATH attribute\n"
3170 "Exclude from the as-path\n")
3171{
3172 int ret;
3173 char *str;
3174
3175 if (argc == 0)
3176 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3177
3178 str = argv_concat (argv, argc, 0);
3179 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3180 XFREE (MTYPE_TMP, str);
3181 return ret;
3182}
3183
3184ALIAS (no_set_aspath_exclude,
3185 no_set_aspath_exclude_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003186 "no set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003187 NO_STR
3188 SET_STR
3189 "Transform BGP AS_PATH attribute\n"
3190 "Exclude from the as-path\n"
3191 "AS number\n")
3192
paul718e3742002-12-13 20:15:29 +00003193DEFUN (set_community,
3194 set_community_cmd,
3195 "set community .AA:NN",
3196 SET_STR
3197 "BGP community attribute\n"
3198 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3199{
3200 int i;
3201 int first = 0;
3202 int additive = 0;
3203 struct buffer *b;
3204 struct community *com = NULL;
3205 char *str;
3206 char *argstr;
3207 int ret;
3208
3209 b = buffer_new (1024);
3210
3211 for (i = 0; i < argc; i++)
3212 {
3213 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3214 {
3215 additive = 1;
3216 continue;
3217 }
3218
3219 if (first)
3220 buffer_putc (b, ' ');
3221 else
3222 first = 1;
3223
3224 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3225 {
3226 buffer_putstr (b, "internet");
3227 continue;
3228 }
3229 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3230 {
3231 buffer_putstr (b, "local-AS");
3232 continue;
3233 }
3234 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3235 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3236 {
3237 buffer_putstr (b, "no-advertise");
3238 continue;
3239 }
3240 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3241 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3242 {
3243 buffer_putstr (b, "no-export");
3244 continue;
3245 }
3246 buffer_putstr (b, argv[i]);
3247 }
3248 buffer_putc (b, '\0');
3249
3250 /* Fetch result string then compile it to communities attribute. */
3251 str = buffer_getstr (b);
3252 buffer_free (b);
3253
3254 if (str)
3255 {
3256 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003257 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003258 }
3259
3260 /* Can't compile user input into communities attribute. */
3261 if (! com)
3262 {
3263 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3264 return CMD_WARNING;
3265 }
3266
3267 /* Set communites attribute string. */
3268 str = community_str (com);
3269
3270 if (additive)
3271 {
3272 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3273 strcpy (argstr, str);
3274 strcpy (argstr + strlen (str), " additive");
3275 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3276 XFREE (MTYPE_TMP, argstr);
3277 }
3278 else
3279 ret = bgp_route_set_add (vty, vty->index, "community", str);
3280
3281 community_free (com);
3282
3283 return ret;
3284}
3285
3286DEFUN (set_community_none,
3287 set_community_none_cmd,
3288 "set community none",
3289 SET_STR
3290 "BGP community attribute\n"
3291 "No community attribute\n")
3292{
3293 return bgp_route_set_add (vty, vty->index, "community", "none");
3294}
3295
3296DEFUN (no_set_community,
3297 no_set_community_cmd,
3298 "no set community",
3299 NO_STR
3300 SET_STR
3301 "BGP community attribute\n")
3302{
3303 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3304}
3305
3306ALIAS (no_set_community,
3307 no_set_community_val_cmd,
3308 "no set community .AA:NN",
3309 NO_STR
3310 SET_STR
3311 "BGP community attribute\n"
3312 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3313
3314ALIAS (no_set_community,
3315 no_set_community_none_cmd,
3316 "no set community none",
3317 NO_STR
3318 SET_STR
3319 "BGP community attribute\n"
3320 "No community attribute\n")
3321
3322DEFUN (set_community_delete,
3323 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003324 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003325 SET_STR
3326 "set BGP community list (for deletion)\n"
3327 "Community-list number (standard)\n"
3328 "Communitly-list number (expanded)\n"
3329 "Community-list name\n"
3330 "Delete matching communities\n")
3331{
3332 char *str;
3333
3334 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3335 strcpy (str, argv[0]);
3336 strcpy (str + strlen (argv[0]), " delete");
3337
3338 bgp_route_set_add (vty, vty->index, "comm-list", str);
3339
3340 XFREE (MTYPE_TMP, str);
3341 return CMD_SUCCESS;
3342}
3343
3344DEFUN (no_set_community_delete,
3345 no_set_community_delete_cmd,
3346 "no set comm-list",
3347 NO_STR
3348 SET_STR
3349 "set BGP community list (for deletion)\n")
3350{
3351 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3352}
3353
3354ALIAS (no_set_community_delete,
3355 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003356 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003357 NO_STR
3358 SET_STR
3359 "set BGP community list (for deletion)\n"
3360 "Community-list number (standard)\n"
3361 "Communitly-list number (expanded)\n"
3362 "Community-list name\n"
3363 "Delete matching communities\n")
3364
3365DEFUN (set_ecommunity_rt,
3366 set_ecommunity_rt_cmd,
3367 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3368 SET_STR
3369 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003370 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003371 "VPN extended community\n")
3372{
3373 int ret;
3374 char *str;
3375
3376 str = argv_concat (argv, argc, 0);
3377 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3378 XFREE (MTYPE_TMP, str);
3379
3380 return ret;
3381}
3382
3383DEFUN (no_set_ecommunity_rt,
3384 no_set_ecommunity_rt_cmd,
3385 "no set extcommunity rt",
3386 NO_STR
3387 SET_STR
3388 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003389 "Route Target extended community\n")
paul718e3742002-12-13 20:15:29 +00003390{
3391 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3392}
3393
3394ALIAS (no_set_ecommunity_rt,
3395 no_set_ecommunity_rt_val_cmd,
3396 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3397 NO_STR
3398 SET_STR
3399 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003400 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003401 "VPN extended community\n")
3402
3403DEFUN (set_ecommunity_soo,
3404 set_ecommunity_soo_cmd,
3405 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3406 SET_STR
3407 "BGP extended community attribute\n"
3408 "Site-of-Origin extended community\n"
3409 "VPN extended community\n")
3410{
3411 int ret;
3412 char *str;
3413
3414 str = argv_concat (argv, argc, 0);
3415 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3416 XFREE (MTYPE_TMP, str);
3417 return ret;
3418}
3419
3420DEFUN (no_set_ecommunity_soo,
3421 no_set_ecommunity_soo_cmd,
3422 "no set extcommunity soo",
3423 NO_STR
3424 SET_STR
3425 "BGP extended community attribute\n"
3426 "Site-of-Origin extended community\n")
3427{
3428 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3429}
3430
3431ALIAS (no_set_ecommunity_soo,
3432 no_set_ecommunity_soo_val_cmd,
3433 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3434 NO_STR
3435 SET_STR
3436 "BGP extended community attribute\n"
3437 "Site-of-Origin extended community\n"
3438 "VPN extended community\n")
3439
3440DEFUN (set_origin,
3441 set_origin_cmd,
3442 "set origin (egp|igp|incomplete)",
3443 SET_STR
3444 "BGP origin code\n"
3445 "remote EGP\n"
3446 "local IGP\n"
3447 "unknown heritage\n")
3448{
3449 if (strncmp (argv[0], "igp", 2) == 0)
3450 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3451 if (strncmp (argv[0], "egp", 1) == 0)
3452 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3453 if (strncmp (argv[0], "incomplete", 2) == 0)
3454 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3455
3456 return CMD_WARNING;
3457}
3458
3459DEFUN (no_set_origin,
3460 no_set_origin_cmd,
3461 "no set origin",
3462 NO_STR
3463 SET_STR
3464 "BGP origin code\n")
3465{
3466 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3467}
3468
3469ALIAS (no_set_origin,
3470 no_set_origin_val_cmd,
3471 "no set origin (egp|igp|incomplete)",
3472 NO_STR
3473 SET_STR
3474 "BGP origin code\n"
3475 "remote EGP\n"
3476 "local IGP\n"
3477 "unknown heritage\n")
3478
3479DEFUN (set_atomic_aggregate,
3480 set_atomic_aggregate_cmd,
3481 "set atomic-aggregate",
3482 SET_STR
3483 "BGP atomic aggregate attribute\n" )
3484{
3485 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3486}
3487
3488DEFUN (no_set_atomic_aggregate,
3489 no_set_atomic_aggregate_cmd,
3490 "no set atomic-aggregate",
3491 NO_STR
3492 SET_STR
3493 "BGP atomic aggregate attribute\n" )
3494{
3495 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3496}
3497
3498DEFUN (set_aggregator_as,
3499 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003500 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003501 SET_STR
3502 "BGP aggregator attribute\n"
3503 "AS number of aggregator\n"
3504 "AS number\n"
3505 "IP address of aggregator\n")
3506{
3507 int ret;
Paul Jakma7aa9dce2014-09-19 14:42:23 +01003508 as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
paul718e3742002-12-13 20:15:29 +00003509 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003510 char *argstr;
3511
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003512 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003513
paul718e3742002-12-13 20:15:29 +00003514 ret = inet_aton (argv[1], &address);
3515 if (ret == 0)
3516 {
3517 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3518 return CMD_WARNING;
3519 }
3520
3521 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3522 strlen (argv[0]) + strlen (argv[1]) + 2);
3523
3524 sprintf (argstr, "%s %s", argv[0], argv[1]);
3525
3526 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3527
3528 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3529
3530 return ret;
3531}
3532
3533DEFUN (no_set_aggregator_as,
3534 no_set_aggregator_as_cmd,
3535 "no set aggregator as",
3536 NO_STR
3537 SET_STR
3538 "BGP aggregator attribute\n"
3539 "AS number of aggregator\n")
3540{
3541 int ret;
Paul Jakma7aa9dce2014-09-19 14:42:23 +01003542 as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
paul718e3742002-12-13 20:15:29 +00003543 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003544 char *argstr;
3545
3546 if (argv == 0)
3547 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3548
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003549 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003550
3551 ret = inet_aton (argv[1], &address);
3552 if (ret == 0)
3553 {
3554 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3555 return CMD_WARNING;
3556 }
3557
3558 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3559 strlen (argv[0]) + strlen (argv[1]) + 2);
3560
3561 sprintf (argstr, "%s %s", argv[0], argv[1]);
3562
3563 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3564
3565 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3566
3567 return ret;
3568}
3569
3570ALIAS (no_set_aggregator_as,
3571 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003572 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003573 NO_STR
3574 SET_STR
3575 "BGP aggregator attribute\n"
3576 "AS number of aggregator\n"
3577 "AS number\n"
3578 "IP address of aggregator\n")
3579
David Lamparter6b0655a2014-06-04 06:53:35 +02003580
paul718e3742002-12-13 20:15:29 +00003581#ifdef HAVE_IPV6
3582DEFUN (match_ipv6_address,
3583 match_ipv6_address_cmd,
3584 "match ipv6 address WORD",
3585 MATCH_STR
3586 IPV6_STR
3587 "Match IPv6 address of route\n"
3588 "IPv6 access-list name\n")
3589{
3590 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3591}
3592
3593DEFUN (no_match_ipv6_address,
3594 no_match_ipv6_address_cmd,
3595 "no match ipv6 address WORD",
3596 NO_STR
3597 MATCH_STR
3598 IPV6_STR
3599 "Match IPv6 address of route\n"
3600 "IPv6 access-list name\n")
3601{
3602 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3603}
3604
3605DEFUN (match_ipv6_next_hop,
3606 match_ipv6_next_hop_cmd,
3607 "match ipv6 next-hop X:X::X:X",
3608 MATCH_STR
3609 IPV6_STR
3610 "Match IPv6 next-hop address of route\n"
3611 "IPv6 address of next hop\n")
3612{
3613 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3614}
3615
3616DEFUN (no_match_ipv6_next_hop,
3617 no_match_ipv6_next_hop_cmd,
3618 "no match ipv6 next-hop X:X::X:X",
3619 NO_STR
3620 MATCH_STR
3621 IPV6_STR
3622 "Match IPv6 next-hop address of route\n"
3623 "IPv6 address of next hop\n")
3624{
3625 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3626}
3627
3628DEFUN (match_ipv6_address_prefix_list,
3629 match_ipv6_address_prefix_list_cmd,
3630 "match ipv6 address prefix-list WORD",
3631 MATCH_STR
3632 IPV6_STR
3633 "Match address of route\n"
3634 "Match entries of prefix-lists\n"
3635 "IP prefix-list name\n")
3636{
3637 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3638}
3639
3640DEFUN (no_match_ipv6_address_prefix_list,
3641 no_match_ipv6_address_prefix_list_cmd,
3642 "no match ipv6 address prefix-list WORD",
3643 NO_STR
3644 MATCH_STR
3645 IPV6_STR
3646 "Match address of route\n"
3647 "Match entries of prefix-lists\n"
3648 "IP prefix-list name\n")
3649{
3650 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3651}
3652
Dinesh G Duttad5233a2014-09-30 14:19:57 -07003653DEFUN (set_ipv6_nexthop_peer,
3654 set_ipv6_nexthop_peer_cmd,
3655 "set ipv6 next-hop peer-address",
3656 SET_STR
3657 IPV6_STR
3658 "Next hop address\n"
3659 "Use peer address (for BGP only)\n")
3660{
3661 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop peer-address", NULL);
3662}
3663
3664DEFUN (no_set_ipv6_nexthop_peer,
3665 no_set_ipv6_nexthop_peer_cmd,
3666 "no set ipv6 next-hop peer-address",
3667 NO_STR
3668 SET_STR
3669 IPV6_STR
3670 "IPv6 next-hop address\n"
3671 )
3672{
3673 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3674}
3675
paul718e3742002-12-13 20:15:29 +00003676DEFUN (set_ipv6_nexthop_global,
3677 set_ipv6_nexthop_global_cmd,
3678 "set ipv6 next-hop global X:X::X:X",
3679 SET_STR
3680 IPV6_STR
3681 "IPv6 next-hop address\n"
3682 "IPv6 global address\n"
3683 "IPv6 address of next hop\n")
3684{
3685 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3686}
3687
3688DEFUN (no_set_ipv6_nexthop_global,
3689 no_set_ipv6_nexthop_global_cmd,
3690 "no set ipv6 next-hop global",
3691 NO_STR
3692 SET_STR
3693 IPV6_STR
3694 "IPv6 next-hop address\n"
3695 "IPv6 global address\n")
3696{
3697 if (argc == 0)
3698 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3699
3700 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3701}
3702
3703ALIAS (no_set_ipv6_nexthop_global,
3704 no_set_ipv6_nexthop_global_val_cmd,
3705 "no set ipv6 next-hop global X:X::X:X",
3706 NO_STR
3707 SET_STR
3708 IPV6_STR
3709 "IPv6 next-hop address\n"
3710 "IPv6 global address\n"
3711 "IPv6 address of next hop\n")
3712
3713DEFUN (set_ipv6_nexthop_local,
3714 set_ipv6_nexthop_local_cmd,
3715 "set ipv6 next-hop local X:X::X:X",
3716 SET_STR
3717 IPV6_STR
3718 "IPv6 next-hop address\n"
3719 "IPv6 local address\n"
3720 "IPv6 address of next hop\n")
3721{
3722 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3723}
3724
3725DEFUN (no_set_ipv6_nexthop_local,
3726 no_set_ipv6_nexthop_local_cmd,
3727 "no set ipv6 next-hop local",
3728 NO_STR
3729 SET_STR
3730 IPV6_STR
3731 "IPv6 next-hop address\n"
3732 "IPv6 local address\n")
3733{
3734 if (argc == 0)
3735 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3736
3737 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3738}
3739
3740ALIAS (no_set_ipv6_nexthop_local,
3741 no_set_ipv6_nexthop_local_val_cmd,
3742 "no set ipv6 next-hop local X:X::X:X",
3743 NO_STR
3744 SET_STR
3745 IPV6_STR
3746 "IPv6 next-hop address\n"
3747 "IPv6 local address\n"
3748 "IPv6 address of next hop\n")
3749#endif /* HAVE_IPV6 */
3750
3751DEFUN (set_vpnv4_nexthop,
3752 set_vpnv4_nexthop_cmd,
3753 "set vpnv4 next-hop A.B.C.D",
3754 SET_STR
3755 "VPNv4 information\n"
3756 "VPNv4 next-hop address\n"
3757 "IP address of next hop\n")
3758{
3759 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3760}
3761
3762DEFUN (no_set_vpnv4_nexthop,
3763 no_set_vpnv4_nexthop_cmd,
3764 "no set vpnv4 next-hop",
3765 NO_STR
3766 SET_STR
3767 "VPNv4 information\n"
3768 "VPNv4 next-hop address\n")
3769{
3770 if (argc == 0)
3771 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3772
3773 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3774}
3775
3776ALIAS (no_set_vpnv4_nexthop,
3777 no_set_vpnv4_nexthop_val_cmd,
3778 "no set vpnv4 next-hop A.B.C.D",
3779 NO_STR
3780 SET_STR
3781 "VPNv4 information\n"
3782 "VPNv4 next-hop address\n"
3783 "IP address of next hop\n")
3784
3785DEFUN (set_originator_id,
3786 set_originator_id_cmd,
3787 "set originator-id A.B.C.D",
3788 SET_STR
3789 "BGP originator ID attribute\n"
3790 "IP address of originator\n")
3791{
3792 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3793}
3794
3795DEFUN (no_set_originator_id,
3796 no_set_originator_id_cmd,
3797 "no set originator-id",
3798 NO_STR
3799 SET_STR
3800 "BGP originator ID attribute\n")
3801{
3802 if (argc == 0)
3803 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3804
3805 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3806}
3807
3808ALIAS (no_set_originator_id,
3809 no_set_originator_id_val_cmd,
3810 "no set originator-id A.B.C.D",
3811 NO_STR
3812 SET_STR
3813 "BGP originator ID attribute\n"
3814 "IP address of originator\n")
3815
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003816DEFUN_DEPRECATED (set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003817 set_pathlimit_ttl_cmd,
3818 "set pathlimit ttl <1-255>",
3819 SET_STR
3820 "BGP AS-Pathlimit attribute\n"
3821 "Set AS-Path Hop-count TTL\n")
3822{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003823 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003824}
3825
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003826DEFUN_DEPRECATED (no_set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003827 no_set_pathlimit_ttl_cmd,
3828 "no set pathlimit ttl",
3829 NO_STR
3830 SET_STR
3831 "BGP AS-Pathlimit attribute\n"
3832 "Set AS-Path Hop-count TTL\n")
3833{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003834 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003835}
3836
3837ALIAS (no_set_pathlimit_ttl,
3838 no_set_pathlimit_ttl_val_cmd,
3839 "no set pathlimit ttl <1-255>",
3840 NO_STR
3841 MATCH_STR
3842 "BGP AS-Pathlimit attribute\n"
3843 "Set AS-Path Hop-count TTL\n")
3844
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003845DEFUN_DEPRECATED (match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003846 match_pathlimit_as_cmd,
3847 "match pathlimit as <1-65535>",
3848 MATCH_STR
3849 "BGP AS-Pathlimit attribute\n"
3850 "Match Pathlimit AS number\n")
3851{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003852 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003853}
3854
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003855DEFUN_DEPRECATED (no_match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003856 no_match_pathlimit_as_cmd,
3857 "no match pathlimit as",
3858 NO_STR
3859 MATCH_STR
3860 "BGP AS-Pathlimit attribute\n"
3861 "Match Pathlimit AS number\n")
3862{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003863 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003864}
3865
3866ALIAS (no_match_pathlimit_as,
3867 no_match_pathlimit_as_val_cmd,
3868 "no match pathlimit as <1-65535>",
3869 NO_STR
3870 MATCH_STR
3871 "BGP AS-Pathlimit attribute\n"
3872 "Match Pathlimit ASN\n")
3873
David Lamparter6b0655a2014-06-04 06:53:35 +02003874
paul718e3742002-12-13 20:15:29 +00003875/* Initialization of route map. */
3876void
paul94f2b392005-06-28 12:44:16 +00003877bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003878{
3879 route_map_init ();
3880 route_map_init_vty ();
3881 route_map_add_hook (bgp_route_map_update);
3882 route_map_delete_hook (bgp_route_map_update);
3883
paulfee0f4c2004-09-13 05:12:46 +00003884 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003885 route_map_install_match (&route_match_ip_address_cmd);
3886 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003887 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003888 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3889 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003890 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003891 route_map_install_match (&route_match_aspath_cmd);
3892 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003893 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003894 route_map_install_match (&route_match_metric_cmd);
3895 route_map_install_match (&route_match_origin_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003896 route_map_install_match (&route_match_probability_cmd);
paul718e3742002-12-13 20:15:29 +00003897
3898 route_map_install_set (&route_set_ip_nexthop_cmd);
3899 route_map_install_set (&route_set_local_pref_cmd);
3900 route_map_install_set (&route_set_weight_cmd);
3901 route_map_install_set (&route_set_metric_cmd);
3902 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003903 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003904 route_map_install_set (&route_set_origin_cmd);
3905 route_map_install_set (&route_set_atomic_aggregate_cmd);
3906 route_map_install_set (&route_set_aggregator_as_cmd);
3907 route_map_install_set (&route_set_community_cmd);
3908 route_map_install_set (&route_set_community_delete_cmd);
3909 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3910 route_map_install_set (&route_set_originator_id_cmd);
3911 route_map_install_set (&route_set_ecommunity_rt_cmd);
3912 route_map_install_set (&route_set_ecommunity_soo_cmd);
3913
paulfee0f4c2004-09-13 05:12:46 +00003914 install_element (RMAP_NODE, &match_peer_cmd);
3915 install_element (RMAP_NODE, &match_peer_local_cmd);
3916 install_element (RMAP_NODE, &no_match_peer_cmd);
3917 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3918 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003919 install_element (RMAP_NODE, &match_ip_address_cmd);
3920 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3921 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3922 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3923 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3924 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003925 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3926 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3927 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003928 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3929 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3930 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3931 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3932 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3933 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003934 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3935 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3936 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003937
3938 install_element (RMAP_NODE, &match_aspath_cmd);
3939 install_element (RMAP_NODE, &no_match_aspath_cmd);
3940 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3941 install_element (RMAP_NODE, &match_metric_cmd);
3942 install_element (RMAP_NODE, &no_match_metric_cmd);
3943 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3944 install_element (RMAP_NODE, &match_community_cmd);
3945 install_element (RMAP_NODE, &match_community_exact_cmd);
3946 install_element (RMAP_NODE, &no_match_community_cmd);
3947 install_element (RMAP_NODE, &no_match_community_val_cmd);
3948 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003949 install_element (RMAP_NODE, &match_ecommunity_cmd);
3950 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3951 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003952 install_element (RMAP_NODE, &match_origin_cmd);
3953 install_element (RMAP_NODE, &no_match_origin_cmd);
3954 install_element (RMAP_NODE, &no_match_origin_val_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003955 install_element (RMAP_NODE, &match_probability_cmd);
3956 install_element (RMAP_NODE, &no_match_probability_cmd);
3957 install_element (RMAP_NODE, &no_match_probability_val_cmd);
paul718e3742002-12-13 20:15:29 +00003958
3959 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003960 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003961 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3962 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3963 install_element (RMAP_NODE, &set_local_pref_cmd);
3964 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3965 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3966 install_element (RMAP_NODE, &set_weight_cmd);
3967 install_element (RMAP_NODE, &no_set_weight_cmd);
3968 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3969 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003970 install_element (RMAP_NODE, &set_metric_addsub_cmd);
Timo Teräsef757702015-04-29 09:43:04 +03003971 install_element (RMAP_NODE, &set_metric_rtt_cmd);
paul718e3742002-12-13 20:15:29 +00003972 install_element (RMAP_NODE, &no_set_metric_cmd);
3973 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3974 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Timo Teräs85c854a2014-09-30 11:31:53 +03003975 install_element (RMAP_NODE, &set_aspath_prepend_lastas_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003976 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003977 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3978 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003979 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
3980 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00003981 install_element (RMAP_NODE, &set_origin_cmd);
3982 install_element (RMAP_NODE, &no_set_origin_cmd);
3983 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3984 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3985 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3986 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3987 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3988 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3989 install_element (RMAP_NODE, &set_community_cmd);
3990 install_element (RMAP_NODE, &set_community_none_cmd);
3991 install_element (RMAP_NODE, &no_set_community_cmd);
3992 install_element (RMAP_NODE, &no_set_community_val_cmd);
3993 install_element (RMAP_NODE, &no_set_community_none_cmd);
3994 install_element (RMAP_NODE, &set_community_delete_cmd);
3995 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3996 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3997 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3998 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3999 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
4000 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
4001 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
4002 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
4003 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
4004 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
4005 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
4006 install_element (RMAP_NODE, &set_originator_id_cmd);
4007 install_element (RMAP_NODE, &no_set_originator_id_cmd);
4008 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
4009
4010#ifdef HAVE_IPV6
4011 route_map_install_match (&route_match_ipv6_address_cmd);
4012 route_map_install_match (&route_match_ipv6_next_hop_cmd);
4013 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
4014 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
4015 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Dinesh G Duttad5233a2014-09-30 14:19:57 -07004016 route_map_install_set (&route_set_ipv6_nexthop_peer_cmd);
4017
paul718e3742002-12-13 20:15:29 +00004018 install_element (RMAP_NODE, &match_ipv6_address_cmd);
4019 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
4020 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
4021 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
4022 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
4023 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
4024 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
4025 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
4026 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
4027 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
4028 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
4029 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
Dinesh G Duttad5233a2014-09-30 14:19:57 -07004030 install_element (RMAP_NODE, &set_ipv6_nexthop_peer_cmd);
4031 install_element (RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00004032#endif /* HAVE_IPV6 */
Paul Jakma41367172007-08-06 15:24:51 +00004033
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004034 /* AS-Pathlimit: functionality removed, commands kept for
4035 * compatibility.
4036 */
Paul Jakma41367172007-08-06 15:24:51 +00004037 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
4038 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
4039 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
4040 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
4041 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
4042 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00004043}