blob: 8d3a8f5608ead7216a04e5893dfd26cb6efb2c49 [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{
Donald Sharpf31bab42015-06-19 19:26:19 -0400887 long r = random();
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400888
David Lamparter8c9cd852015-04-19 14:40:02 +0200889 switch (*(long *) rule)
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400890 {
891 case 0: break;
892 case RAND_MAX: return RMAP_MATCH;
893 default:
David Lamparter8c9cd852015-04-19 14:40:02 +0200894 if (r < *(long *) rule)
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400895 {
896 return RMAP_MATCH;
897 }
898 }
899
900 return RMAP_NOMATCH;
901}
902
903static void *
904route_match_probability_compile (const char *arg)
905{
David Lamparter8c9cd852015-04-19 14:40:02 +0200906 long *lobule;
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400907 unsigned perc;
908
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400909 perc = atoi (arg);
David Lamparter8c9cd852015-04-19 14:40:02 +0200910 lobule = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (long));
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400911
912 switch (perc)
913 {
914 case 0: *lobule = 0; break;
915 case 100: *lobule = RAND_MAX; break;
916 default: *lobule = RAND_MAX / 100 * perc;
917 }
918
919 return lobule;
920}
921
922static void
923route_match_probability_free (void *rule)
924{
925 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
926}
927
928struct route_map_rule_cmd route_match_probability_cmd =
929{
930 "probability",
931 route_match_probability,
932 route_match_probability_compile,
933 route_match_probability_free
934};
935
936/* } */
937
paul718e3742002-12-13 20:15:29 +0000938/* `set ip next-hop IP_ADDRESS' */
939
940/* Set nexthop to object. ojbect must be pointer to struct attr. */
paulac41b2a2003-08-12 05:32:27 +0000941struct rmap_ip_nexthop_set
942{
943 struct in_addr *address;
944 int peer_address;
945};
946
paul94f2b392005-06-28 12:44:16 +0000947static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000948route_set_ip_nexthop (void *rule, struct prefix *prefix,
949 route_map_object_t type, void *object)
950{
paulac41b2a2003-08-12 05:32:27 +0000951 struct rmap_ip_nexthop_set *rins = rule;
paul718e3742002-12-13 20:15:29 +0000952 struct bgp_info *bgp_info;
paulac41b2a2003-08-12 05:32:27 +0000953 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000954
955 if (type == RMAP_BGP)
956 {
paul718e3742002-12-13 20:15:29 +0000957 bgp_info = object;
paulac41b2a2003-08-12 05:32:27 +0000958 peer = bgp_info->peer;
959
960 if (rins->peer_address)
961 {
paulfee0f4c2004-09-13 05:12:46 +0000962 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
963 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
paulac41b2a2003-08-12 05:32:27 +0000964 && peer->su_remote
965 && sockunion_family (peer->su_remote) == AF_INET)
966 {
Jorge Boncompte [DTI2]0c5ed3e2012-04-10 16:57:22 +0200967 bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote);
paulac41b2a2003-08-12 05:32:27 +0000968 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
969 }
970 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
971 && peer->su_local
972 && sockunion_family (peer->su_local) == AF_INET)
973 {
Jorge Boncompte [DTI2]0c5ed3e2012-04-10 16:57:22 +0200974 bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_local);
paulac41b2a2003-08-12 05:32:27 +0000975 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
976 }
977 }
978 else
979 {
980 /* Set next hop value. */
981 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
982 bgp_info->attr->nexthop = *rins->address;
983 }
paul718e3742002-12-13 20:15:29 +0000984 }
985
986 return RMAP_OKAY;
987}
988
989/* Route map `ip nexthop' compile function. Given string is converted
990 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +0000991static void *
paulfd79ac92004-10-13 05:06:08 +0000992route_set_ip_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000993{
paulac41b2a2003-08-12 05:32:27 +0000994 struct rmap_ip_nexthop_set *rins;
995 struct in_addr *address = NULL;
996 int peer_address = 0;
paul718e3742002-12-13 20:15:29 +0000997 int ret;
paul718e3742002-12-13 20:15:29 +0000998
paulac41b2a2003-08-12 05:32:27 +0000999 if (strcmp (arg, "peer-address") == 0)
1000 peer_address = 1;
1001 else
paul718e3742002-12-13 20:15:29 +00001002 {
paulac41b2a2003-08-12 05:32:27 +00001003 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
1004 ret = inet_aton (arg, address);
1005
1006 if (ret == 0)
1007 {
1008 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1009 return NULL;
1010 }
paul718e3742002-12-13 20:15:29 +00001011 }
1012
Stephen Hemminger393deb92008-08-18 14:13:29 -07001013 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
paulac41b2a2003-08-12 05:32:27 +00001014
1015 rins->address = address;
1016 rins->peer_address = peer_address;
1017
1018 return rins;
paul718e3742002-12-13 20:15:29 +00001019}
1020
1021/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00001022static void
paul718e3742002-12-13 20:15:29 +00001023route_set_ip_nexthop_free (void *rule)
1024{
paulac41b2a2003-08-12 05:32:27 +00001025 struct rmap_ip_nexthop_set *rins = rule;
1026
1027 if (rins->address)
1028 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
1029
1030 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +00001031}
1032
1033/* Route map commands for ip nexthop set. */
1034struct route_map_rule_cmd route_set_ip_nexthop_cmd =
1035{
1036 "ip next-hop",
1037 route_set_ip_nexthop,
1038 route_set_ip_nexthop_compile,
1039 route_set_ip_nexthop_free
1040};
David Lamparter6b0655a2014-06-04 06:53:35 +02001041
paul718e3742002-12-13 20:15:29 +00001042/* `set local-preference LOCAL_PREF' */
1043
1044/* Set local preference. */
paul94f2b392005-06-28 12:44:16 +00001045static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001046route_set_local_pref (void *rule, struct prefix *prefix,
1047 route_map_object_t type, void *object)
1048{
Timo Teräs38f22ab2015-04-29 09:43:02 +03001049 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +00001050 struct bgp_info *bgp_info;
Timo Teräs38f22ab2015-04-29 09:43:02 +03001051 u_int32_t locpref = 0;
paul718e3742002-12-13 20:15:29 +00001052
1053 if (type == RMAP_BGP)
1054 {
1055 /* Fetch routemap's rule information. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001056 rv = rule;
paul718e3742002-12-13 20:15:29 +00001057 bgp_info = object;
1058
1059 /* Set local preference value. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001060 if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
1061 locpref = bgp_info->attr->local_pref;
1062
paul718e3742002-12-13 20:15:29 +00001063 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
Timo Teräsef757702015-04-29 09:43:04 +03001064 bgp_info->attr->local_pref = route_value_adjust(rv, locpref, bgp_info->peer);
paul718e3742002-12-13 20:15:29 +00001065 }
1066
1067 return RMAP_OKAY;
1068}
1069
paul718e3742002-12-13 20:15:29 +00001070/* Set local preference rule structure. */
1071struct route_map_rule_cmd route_set_local_pref_cmd =
1072{
1073 "local-preference",
1074 route_set_local_pref,
Timo Teräs38f22ab2015-04-29 09:43:02 +03001075 route_value_compile,
1076 route_value_free,
paul718e3742002-12-13 20:15:29 +00001077};
David Lamparter6b0655a2014-06-04 06:53:35 +02001078
paul718e3742002-12-13 20:15:29 +00001079/* `set weight WEIGHT' */
1080
1081/* Set weight. */
paul94f2b392005-06-28 12:44:16 +00001082static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001083route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
1084 void *object)
1085{
Timo Teräs38f22ab2015-04-29 09:43:02 +03001086 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +00001087 struct bgp_info *bgp_info;
Timo Teräs38f22ab2015-04-29 09:43:02 +03001088 u_int32_t weight;
paul718e3742002-12-13 20:15:29 +00001089
1090 if (type == RMAP_BGP)
1091 {
1092 /* Fetch routemap's rule information. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001093 rv = rule;
paul718e3742002-12-13 20:15:29 +00001094 bgp_info = object;
1095
1096 /* Set weight value. */
Timo Teräsef757702015-04-29 09:43:04 +03001097 weight = route_value_adjust(rv, 0, bgp_info->peer);
Timo Teräs38f22ab2015-04-29 09:43:02 +03001098 if (weight)
1099 (bgp_attr_extra_get (bgp_info->attr))->weight = weight;
Paul Jakmafb982c22007-05-04 20:15:47 +00001100 else if (bgp_info->attr->extra)
1101 bgp_info->attr->extra->weight = 0;
paul718e3742002-12-13 20:15:29 +00001102 }
1103
1104 return RMAP_OKAY;
1105}
1106
paul718e3742002-12-13 20:15:29 +00001107/* Set local preference rule structure. */
1108struct route_map_rule_cmd route_set_weight_cmd =
1109{
1110 "weight",
1111 route_set_weight,
Timo Teräs38f22ab2015-04-29 09:43:02 +03001112 route_value_compile,
1113 route_value_free,
paul718e3742002-12-13 20:15:29 +00001114};
David Lamparter6b0655a2014-06-04 06:53:35 +02001115
paul718e3742002-12-13 20:15:29 +00001116/* `set metric METRIC' */
1117
1118/* Set metric to attribute. */
paul94f2b392005-06-28 12:44:16 +00001119static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001120route_set_metric (void *rule, struct prefix *prefix,
1121 route_map_object_t type, void *object)
1122{
Timo Teräs38f22ab2015-04-29 09:43:02 +03001123 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +00001124 struct bgp_info *bgp_info;
Timo Teräs38f22ab2015-04-29 09:43:02 +03001125 u_int32_t med = 0;
paul718e3742002-12-13 20:15:29 +00001126
1127 if (type == RMAP_BGP)
1128 {
1129 /* Fetch routemap's rule information. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001130 rv = rule;
paul718e3742002-12-13 20:15:29 +00001131 bgp_info = object;
1132
Timo Teräs38f22ab2015-04-29 09:43:02 +03001133 if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
1134 med = bgp_info->attr->med;
1135
Timo Teräsef757702015-04-29 09:43:04 +03001136 bgp_info->attr->med = route_value_adjust(rv, med, bgp_info->peer);
paul718e3742002-12-13 20:15:29 +00001137 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
paul718e3742002-12-13 20:15:29 +00001138 }
1139 return RMAP_OKAY;
1140}
1141
paul718e3742002-12-13 20:15:29 +00001142/* Set metric rule structure. */
1143struct route_map_rule_cmd route_set_metric_cmd =
1144{
1145 "metric",
1146 route_set_metric,
Timo Teräs38f22ab2015-04-29 09:43:02 +03001147 route_value_compile,
1148 route_value_free,
paul718e3742002-12-13 20:15:29 +00001149};
David Lamparter6b0655a2014-06-04 06:53:35 +02001150
paul718e3742002-12-13 20:15:29 +00001151/* `set as-path prepend ASPATH' */
1152
1153/* For AS path prepend mechanism. */
paul94f2b392005-06-28 12:44:16 +00001154static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001155route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1156{
1157 struct aspath *aspath;
1158 struct aspath *new;
1159 struct bgp_info *binfo;
1160
1161 if (type == RMAP_BGP)
1162 {
paul718e3742002-12-13 20:15:29 +00001163 binfo = object;
1164
1165 if (binfo->attr->aspath->refcnt)
1166 new = aspath_dup (binfo->attr->aspath);
1167 else
1168 new = binfo->attr->aspath;
1169
Timo Teräs85c854a2014-09-30 11:31:53 +03001170 if ((uintptr_t)rule > 10)
1171 {
1172 aspath = rule;
1173 aspath_prepend (aspath, new);
1174 }
1175 else
1176 {
1177 as_t as = aspath_leftmost(new);
1178 if (!as) as = binfo->peer->as;
1179 new = aspath_add_seq_n (new, as, (uintptr_t) rule);
1180 }
1181
paul718e3742002-12-13 20:15:29 +00001182 binfo->attr->aspath = new;
1183 }
1184
1185 return RMAP_OKAY;
1186}
1187
Timo Teräs85c854a2014-09-30 11:31:53 +03001188static void *
1189route_set_aspath_prepend_compile (const char *arg)
1190{
1191 unsigned int num;
1192
1193 if (sscanf(arg, "last-as %u", &num) == 1 && num > 0 && num < 10)
1194 return (void*)(uintptr_t)num;
1195
1196 return route_aspath_compile(arg);
1197}
1198
1199static void
1200route_set_aspath_prepend_free (void *rule)
1201{
1202 if ((uintptr_t)rule > 10)
1203 route_aspath_free(rule);
1204}
1205
1206
Timo Teräs2aa640b2014-05-20 08:57:26 +03001207/* Set as-path prepend rule structure. */
paul718e3742002-12-13 20:15:29 +00001208struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1209{
1210 "as-path prepend",
1211 route_set_aspath_prepend,
Timo Teräs85c854a2014-09-30 11:31:53 +03001212 route_set_aspath_prepend_compile,
1213 route_set_aspath_prepend_free,
paul718e3742002-12-13 20:15:29 +00001214};
David Lamparter6b0655a2014-06-04 06:53:35 +02001215
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001216/* `set as-path exclude ASn' */
1217
1218/* For ASN exclude mechanism.
1219 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1220 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1221 */
1222static route_map_result_t
1223route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
1224{
1225 struct aspath * new_path, * exclude_path;
1226 struct bgp_info *binfo;
1227
1228 if (type == RMAP_BGP)
1229 {
1230 exclude_path = rule;
1231 binfo = object;
1232 if (binfo->attr->aspath->refcnt)
1233 new_path = aspath_dup (binfo->attr->aspath);
1234 else
1235 new_path = binfo->attr->aspath;
1236 binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
1237 }
1238 return RMAP_OKAY;
1239}
1240
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001241/* Set ASn exlude rule structure. */
1242struct route_map_rule_cmd route_set_aspath_exclude_cmd =
1243{
1244 "as-path exclude",
1245 route_set_aspath_exclude,
Timo Teräsb304dcb2014-05-20 09:04:49 +03001246 route_aspath_compile,
1247 route_aspath_free,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001248};
David Lamparter6b0655a2014-06-04 06:53:35 +02001249
paul718e3742002-12-13 20:15:29 +00001250/* `set community COMMUNITY' */
1251struct rmap_com_set
1252{
1253 struct community *com;
1254 int additive;
1255 int none;
1256};
1257
1258/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001259static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001260route_set_community (void *rule, struct prefix *prefix,
1261 route_map_object_t type, void *object)
1262{
1263 struct rmap_com_set *rcs;
1264 struct bgp_info *binfo;
1265 struct attr *attr;
1266 struct community *new = NULL;
1267 struct community *old;
1268 struct community *merge;
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001269
paul718e3742002-12-13 20:15:29 +00001270 if (type == RMAP_BGP)
1271 {
1272 rcs = rule;
1273 binfo = object;
1274 attr = binfo->attr;
1275 old = attr->community;
1276
1277 /* "none" case. */
1278 if (rcs->none)
1279 {
1280 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1281 attr->community = NULL;
Christian Frankeb06b35f2012-12-07 14:26:09 +00001282 /* See the longer comment down below. */
1283 if (old && old->refcnt == 0)
1284 community_free(old);
paul718e3742002-12-13 20:15:29 +00001285 return RMAP_OKAY;
1286 }
1287
1288 /* "additive" case. */
1289 if (rcs->additive && old)
1290 {
1291 merge = community_merge (community_dup (old), rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001292
1293 /* HACK: if the old community is not intern'd,
1294 * we should free it here, or all reference to it may be lost.
1295 * Really need to cleanup attribute caching sometime.
1296 */
1297 if (old->refcnt == 0)
1298 community_free (old);
paul718e3742002-12-13 20:15:29 +00001299 new = community_uniq_sort (merge);
1300 community_free (merge);
1301 }
1302 else
1303 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001304
1305 /* will be interned by caller if required */
Paul Jakma4a2035f2011-04-01 15:58:27 +01001306 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001307
paul718e3742002-12-13 20:15:29 +00001308 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1309 }
1310
1311 return RMAP_OKAY;
1312}
1313
1314/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001315static void *
paulfd79ac92004-10-13 05:06:08 +00001316route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001317{
1318 struct rmap_com_set *rcs;
1319 struct community *com = NULL;
1320 char *sp;
1321 int additive = 0;
1322 int none = 0;
1323
1324 if (strcmp (arg, "none") == 0)
1325 none = 1;
1326 else
1327 {
1328 sp = strstr (arg, "additive");
1329
1330 if (sp && sp > arg)
1331 {
1332 /* "additive" keyworkd is included. */
1333 additive = 1;
1334 *(sp - 1) = '\0';
1335 }
1336
1337 com = community_str2com (arg);
1338
1339 if (additive)
1340 *(sp - 1) = ' ';
1341
1342 if (! com)
1343 return NULL;
1344 }
1345
Stephen Hemminger393deb92008-08-18 14:13:29 -07001346 rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
Paul Jakma4a2035f2011-04-01 15:58:27 +01001347 rcs->com = com;
paul718e3742002-12-13 20:15:29 +00001348 rcs->additive = additive;
1349 rcs->none = none;
1350
1351 return rcs;
1352}
1353
1354/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001355static void
paul718e3742002-12-13 20:15:29 +00001356route_set_community_free (void *rule)
1357{
1358 struct rmap_com_set *rcs = rule;
1359
1360 if (rcs->com)
1361 community_free (rcs->com);
1362 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1363}
1364
1365/* Set community rule structure. */
1366struct route_map_rule_cmd route_set_community_cmd =
1367{
1368 "community",
1369 route_set_community,
1370 route_set_community_compile,
1371 route_set_community_free,
1372};
David Lamparter6b0655a2014-06-04 06:53:35 +02001373
hassofee6e4e2005-02-02 16:29:31 +00001374/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001375
1376/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001377static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001378route_set_community_delete (void *rule, struct prefix *prefix,
1379 route_map_object_t type, void *object)
1380{
1381 struct community_list *list;
1382 struct community *merge;
1383 struct community *new;
1384 struct community *old;
1385 struct bgp_info *binfo;
1386
1387 if (type == RMAP_BGP)
1388 {
1389 if (! rule)
1390 return RMAP_OKAY;
1391
1392 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001393 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001394 old = binfo->attr->community;
1395
1396 if (list && old)
1397 {
1398 merge = community_list_match_delete (community_dup (old), list);
1399 new = community_uniq_sort (merge);
1400 community_free (merge);
1401
Michael Lambert604a9b42010-09-13 11:48:11 -04001402 /* HACK: if the old community is not intern'd,
1403 * we should free it here, or all reference to it may be lost.
1404 * Really need to cleanup attribute caching sometime.
1405 */
1406 if (old->refcnt == 0)
1407 community_free (old);
1408
paul718e3742002-12-13 20:15:29 +00001409 if (new->size == 0)
1410 {
1411 binfo->attr->community = NULL;
1412 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1413 community_free (new);
1414 }
1415 else
1416 {
Paul Jakma4a2035f2011-04-01 15:58:27 +01001417 binfo->attr->community = new;
paul718e3742002-12-13 20:15:29 +00001418 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1419 }
1420 }
1421 }
1422
1423 return RMAP_OKAY;
1424}
1425
1426/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001427static void *
paulfd79ac92004-10-13 05:06:08 +00001428route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001429{
1430 char *p;
1431 char *str;
1432 int len;
1433
1434 p = strchr (arg, ' ');
1435 if (p)
1436 {
1437 len = p - arg;
1438 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1439 memcpy (str, arg, len);
1440 }
1441 else
1442 str = NULL;
1443
1444 return str;
1445}
1446
1447/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001448static void
paul718e3742002-12-13 20:15:29 +00001449route_set_community_delete_free (void *rule)
1450{
1451 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1452}
1453
1454/* Set community rule structure. */
1455struct route_map_rule_cmd route_set_community_delete_cmd =
1456{
1457 "comm-list",
1458 route_set_community_delete,
1459 route_set_community_delete_compile,
1460 route_set_community_delete_free,
1461};
David Lamparter6b0655a2014-06-04 06:53:35 +02001462
paul718e3742002-12-13 20:15:29 +00001463/* `set extcommunity rt COMMUNITY' */
1464
David Lamparter73d78ea2014-06-04 00:58:47 +02001465/* For community set mechanism. Used by _rt and _soo. */
paul94f2b392005-06-28 12:44:16 +00001466static route_map_result_t
David Lamparter73d78ea2014-06-04 00:58:47 +02001467route_set_ecommunity (void *rule, struct prefix *prefix,
1468 route_map_object_t type, void *object)
paul718e3742002-12-13 20:15:29 +00001469{
1470 struct ecommunity *ecom;
1471 struct ecommunity *new_ecom;
1472 struct ecommunity *old_ecom;
1473 struct bgp_info *bgp_info;
1474
1475 if (type == RMAP_BGP)
1476 {
1477 ecom = rule;
1478 bgp_info = object;
1479
1480 if (! ecom)
1481 return RMAP_OKAY;
1482
1483 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001484 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001485
1486 if (old_ecom)
David Lamparter27bf90a2014-06-04 00:59:01 +02001487 {
1488 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1489
1490 /* old_ecom->refcnt = 1 => owned elsewhere, e.g. bgp_update_receive()
1491 * ->refcnt = 0 => set by a previous route-map statement */
1492 if (!old_ecom->refcnt)
1493 ecommunity_free (&old_ecom);
1494 }
paul718e3742002-12-13 20:15:29 +00001495 else
1496 new_ecom = ecommunity_dup (ecom);
1497
David Lamparter27bf90a2014-06-04 00:59:01 +02001498 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
1499 bgp_info->attr->extra->ecommunity = new_ecom;
hasso70601e02005-05-27 03:26:57 +00001500
paul718e3742002-12-13 20:15:29 +00001501 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1502 }
1503 return RMAP_OKAY;
1504}
1505
1506/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001507static void *
paulfd79ac92004-10-13 05:06:08 +00001508route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001509{
1510 struct ecommunity *ecom;
1511
1512 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1513 if (! ecom)
1514 return NULL;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001515 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001516}
1517
David Lamparter73d78ea2014-06-04 00:58:47 +02001518/* Free function for set community. Used by _rt and _soo */
paul94f2b392005-06-28 12:44:16 +00001519static void
David Lamparter73d78ea2014-06-04 00:58:47 +02001520route_set_ecommunity_free (void *rule)
paul718e3742002-12-13 20:15:29 +00001521{
1522 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001523 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001524}
1525
1526/* Set community rule structure. */
1527struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1528{
1529 "extcommunity rt",
David Lamparter73d78ea2014-06-04 00:58:47 +02001530 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001531 route_set_ecommunity_rt_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001532 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001533};
1534
1535/* `set extcommunity soo COMMUNITY' */
1536
paul718e3742002-12-13 20:15:29 +00001537/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001538static void *
paulfd79ac92004-10-13 05:06:08 +00001539route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001540{
1541 struct ecommunity *ecom;
1542
1543 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1544 if (! ecom)
1545 return NULL;
1546
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001547 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001548}
1549
paul718e3742002-12-13 20:15:29 +00001550/* Set community rule structure. */
1551struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1552{
1553 "extcommunity soo",
David Lamparter73d78ea2014-06-04 00:58:47 +02001554 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001555 route_set_ecommunity_soo_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001556 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001557};
David Lamparter6b0655a2014-06-04 06:53:35 +02001558
paul718e3742002-12-13 20:15:29 +00001559/* `set origin ORIGIN' */
1560
1561/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001562static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001563route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1564{
1565 u_char *origin;
1566 struct bgp_info *bgp_info;
1567
1568 if (type == RMAP_BGP)
1569 {
1570 origin = rule;
1571 bgp_info = object;
1572
1573 bgp_info->attr->origin = *origin;
1574 }
1575
1576 return RMAP_OKAY;
1577}
1578
1579/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001580static void *
paulfd79ac92004-10-13 05:06:08 +00001581route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001582{
1583 u_char *origin;
1584
1585 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1586
1587 if (strcmp (arg, "igp") == 0)
1588 *origin = 0;
1589 else if (strcmp (arg, "egp") == 0)
1590 *origin = 1;
1591 else
1592 *origin = 2;
1593
1594 return origin;
1595}
1596
1597/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001598static void
paul718e3742002-12-13 20:15:29 +00001599route_set_origin_free (void *rule)
1600{
1601 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1602}
1603
Timo Teräs2aa640b2014-05-20 08:57:26 +03001604/* Set origin rule structure. */
paul718e3742002-12-13 20:15:29 +00001605struct route_map_rule_cmd route_set_origin_cmd =
1606{
1607 "origin",
1608 route_set_origin,
1609 route_set_origin_compile,
1610 route_set_origin_free,
1611};
David Lamparter6b0655a2014-06-04 06:53:35 +02001612
paul718e3742002-12-13 20:15:29 +00001613/* `set atomic-aggregate' */
1614
1615/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001616static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001617route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1618 route_map_object_t type, void *object)
1619{
1620 struct bgp_info *bgp_info;
1621
1622 if (type == RMAP_BGP)
1623 {
1624 bgp_info = object;
1625 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1626 }
1627
1628 return RMAP_OKAY;
1629}
1630
1631/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001632static void *
paulfd79ac92004-10-13 05:06:08 +00001633route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001634{
1635 return (void *)1;
1636}
1637
1638/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001639static void
paul718e3742002-12-13 20:15:29 +00001640route_set_atomic_aggregate_free (void *rule)
1641{
1642 return;
1643}
1644
1645/* Set atomic aggregate rule structure. */
1646struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1647{
1648 "atomic-aggregate",
1649 route_set_atomic_aggregate,
1650 route_set_atomic_aggregate_compile,
1651 route_set_atomic_aggregate_free,
1652};
David Lamparter6b0655a2014-06-04 06:53:35 +02001653
paul718e3742002-12-13 20:15:29 +00001654/* `set aggregator as AS A.B.C.D' */
1655struct aggregator
1656{
1657 as_t as;
1658 struct in_addr address;
1659};
1660
paul94f2b392005-06-28 12:44:16 +00001661static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001662route_set_aggregator_as (void *rule, struct prefix *prefix,
1663 route_map_object_t type, void *object)
1664{
1665 struct bgp_info *bgp_info;
1666 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001667 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001668
1669 if (type == RMAP_BGP)
1670 {
1671 bgp_info = object;
1672 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001673 ae = bgp_attr_extra_get (bgp_info->attr);
1674
1675 ae->aggregator_as = aggregator->as;
1676 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001677 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1678 }
1679
1680 return RMAP_OKAY;
1681}
1682
paul94f2b392005-06-28 12:44:16 +00001683static void *
paulfd79ac92004-10-13 05:06:08 +00001684route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001685{
1686 struct aggregator *aggregator;
1687 char as[10];
1688 char address[20];
1689
Stephen Hemminger393deb92008-08-18 14:13:29 -07001690 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
paul718e3742002-12-13 20:15:29 +00001691 sscanf (arg, "%s %s", as, address);
1692
1693 aggregator->as = strtoul (as, NULL, 10);
1694 inet_aton (address, &aggregator->address);
1695
1696 return aggregator;
1697}
1698
paul94f2b392005-06-28 12:44:16 +00001699static void
paul718e3742002-12-13 20:15:29 +00001700route_set_aggregator_as_free (void *rule)
1701{
1702 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1703}
1704
1705struct route_map_rule_cmd route_set_aggregator_as_cmd =
1706{
1707 "aggregator as",
1708 route_set_aggregator_as,
1709 route_set_aggregator_as_compile,
1710 route_set_aggregator_as_free,
1711};
David Lamparter6b0655a2014-06-04 06:53:35 +02001712
paul718e3742002-12-13 20:15:29 +00001713/* `match ipv6 address IP_ACCESS_LIST' */
1714
paul94f2b392005-06-28 12:44:16 +00001715static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001716route_match_ipv6_address (void *rule, struct prefix *prefix,
1717 route_map_object_t type, void *object)
1718{
1719 struct access_list *alist;
1720
1721 if (type == RMAP_BGP)
1722 {
1723 alist = access_list_lookup (AFI_IP6, (char *) rule);
1724 if (alist == NULL)
1725 return RMAP_NOMATCH;
1726
1727 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1728 RMAP_NOMATCH : RMAP_MATCH);
1729 }
1730 return RMAP_NOMATCH;
1731}
1732
paul94f2b392005-06-28 12:44:16 +00001733static void *
paulfd79ac92004-10-13 05:06:08 +00001734route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001735{
1736 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1737}
1738
paul94f2b392005-06-28 12:44:16 +00001739static void
paul718e3742002-12-13 20:15:29 +00001740route_match_ipv6_address_free (void *rule)
1741{
1742 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1743}
1744
1745/* Route map commands for ip address matching. */
1746struct route_map_rule_cmd route_match_ipv6_address_cmd =
1747{
1748 "ipv6 address",
1749 route_match_ipv6_address,
1750 route_match_ipv6_address_compile,
1751 route_match_ipv6_address_free
1752};
David Lamparter6b0655a2014-06-04 06:53:35 +02001753
paul718e3742002-12-13 20:15:29 +00001754/* `match ipv6 next-hop IP_ADDRESS' */
1755
paul94f2b392005-06-28 12:44:16 +00001756static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001757route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1758 route_map_object_t type, void *object)
1759{
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001760 struct in6_addr *addr = rule;
paul718e3742002-12-13 20:15:29 +00001761 struct bgp_info *bgp_info;
1762
1763 if (type == RMAP_BGP)
1764 {
paul718e3742002-12-13 20:15:29 +00001765 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001766
1767 if (!bgp_info->attr->extra)
1768 return RMAP_NOMATCH;
1769
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001770 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, addr))
paul718e3742002-12-13 20:15:29 +00001771 return RMAP_MATCH;
1772
Paul Jakmafb982c22007-05-04 20:15:47 +00001773 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001774 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, addr))
paul718e3742002-12-13 20:15:29 +00001775 return RMAP_MATCH;
1776
1777 return RMAP_NOMATCH;
1778 }
1779
1780 return RMAP_NOMATCH;
1781}
1782
paul94f2b392005-06-28 12:44:16 +00001783static void *
paulfd79ac92004-10-13 05:06:08 +00001784route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001785{
1786 struct in6_addr *address;
1787 int ret;
1788
1789 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1790
1791 ret = inet_pton (AF_INET6, arg, address);
1792 if (!ret)
1793 {
1794 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1795 return NULL;
1796 }
1797
1798 return address;
1799}
1800
paul94f2b392005-06-28 12:44:16 +00001801static void
paul718e3742002-12-13 20:15:29 +00001802route_match_ipv6_next_hop_free (void *rule)
1803{
1804 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1805}
1806
1807struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1808{
1809 "ipv6 next-hop",
1810 route_match_ipv6_next_hop,
1811 route_match_ipv6_next_hop_compile,
1812 route_match_ipv6_next_hop_free
1813};
David Lamparter6b0655a2014-06-04 06:53:35 +02001814
paul718e3742002-12-13 20:15:29 +00001815/* `match ipv6 address prefix-list PREFIX_LIST' */
1816
paul94f2b392005-06-28 12:44:16 +00001817static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001818route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1819 route_map_object_t type, void *object)
1820{
1821 struct prefix_list *plist;
1822
1823 if (type == RMAP_BGP)
1824 {
1825 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1826 if (plist == NULL)
1827 return RMAP_NOMATCH;
1828
1829 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1830 RMAP_NOMATCH : RMAP_MATCH);
1831 }
1832 return RMAP_NOMATCH;
1833}
1834
paul94f2b392005-06-28 12:44:16 +00001835static void *
paulfd79ac92004-10-13 05:06:08 +00001836route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001837{
1838 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1839}
1840
paul94f2b392005-06-28 12:44:16 +00001841static void
paul718e3742002-12-13 20:15:29 +00001842route_match_ipv6_address_prefix_list_free (void *rule)
1843{
1844 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1845}
1846
1847struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1848{
1849 "ipv6 address prefix-list",
1850 route_match_ipv6_address_prefix_list,
1851 route_match_ipv6_address_prefix_list_compile,
1852 route_match_ipv6_address_prefix_list_free
1853};
David Lamparter6b0655a2014-06-04 06:53:35 +02001854
paul718e3742002-12-13 20:15:29 +00001855/* `set ipv6 nexthop global IP_ADDRESS' */
1856
1857/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001858static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001859route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1860 route_map_object_t type, void *object)
1861{
1862 struct in6_addr *address;
1863 struct bgp_info *bgp_info;
1864
1865 if (type == RMAP_BGP)
1866 {
1867 /* Fetch routemap's rule information. */
1868 address = rule;
1869 bgp_info = object;
1870
1871 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001872 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00001873
1874 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001875 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1876 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00001877 }
1878
1879 return RMAP_OKAY;
1880}
1881
1882/* Route map `ip next-hop' compile function. Given string is converted
1883 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001884static void *
paulfd79ac92004-10-13 05:06:08 +00001885route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001886{
1887 int ret;
1888 struct in6_addr *address;
1889
1890 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1891
1892 ret = inet_pton (AF_INET6, arg, address);
1893
1894 if (ret == 0)
1895 {
1896 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1897 return NULL;
1898 }
1899
1900 return address;
1901}
1902
1903/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00001904static void
paul718e3742002-12-13 20:15:29 +00001905route_set_ipv6_nexthop_global_free (void *rule)
1906{
1907 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1908}
1909
1910/* Route map commands for ip nexthop set. */
1911struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
1912{
1913 "ipv6 next-hop global",
1914 route_set_ipv6_nexthop_global,
1915 route_set_ipv6_nexthop_global_compile,
1916 route_set_ipv6_nexthop_global_free
1917};
David Lamparter6b0655a2014-06-04 06:53:35 +02001918
paul718e3742002-12-13 20:15:29 +00001919/* `set ipv6 nexthop local IP_ADDRESS' */
1920
1921/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001922static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001923route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
1924 route_map_object_t type, void *object)
1925{
1926 struct in6_addr *address;
1927 struct bgp_info *bgp_info;
1928
1929 if (type == RMAP_BGP)
1930 {
1931 /* Fetch routemap's rule information. */
1932 address = rule;
1933 bgp_info = object;
1934
1935 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001936 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00001937
1938 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001939 if (bgp_info->attr->extra->mp_nexthop_len != 32)
1940 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00001941 }
1942
1943 return RMAP_OKAY;
1944}
1945
1946/* Route map `ip nexthop' compile function. Given string is converted
1947 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001948static void *
paulfd79ac92004-10-13 05:06:08 +00001949route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001950{
1951 int ret;
1952 struct in6_addr *address;
1953
1954 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1955
1956 ret = inet_pton (AF_INET6, arg, address);
1957
1958 if (ret == 0)
1959 {
1960 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1961 return NULL;
1962 }
1963
1964 return address;
1965}
1966
1967/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00001968static void
paul718e3742002-12-13 20:15:29 +00001969route_set_ipv6_nexthop_local_free (void *rule)
1970{
1971 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1972}
1973
1974/* Route map commands for ip nexthop set. */
1975struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
1976{
1977 "ipv6 next-hop local",
1978 route_set_ipv6_nexthop_local,
1979 route_set_ipv6_nexthop_local_compile,
1980 route_set_ipv6_nexthop_local_free
1981};
Dinesh G Duttad5233a2014-09-30 14:19:57 -07001982
1983/* `set ipv6 nexthop peer-address' */
1984
1985/* Set nexthop to object. ojbect must be pointer to struct attr. */
1986static route_map_result_t
1987route_set_ipv6_nexthop_peer (void *rule, struct prefix *prefix,
1988 route_map_object_t type, void *object)
1989{
Dinesh G Duttad5233a2014-09-30 14:19:57 -07001990 struct in6_addr peer_address;
1991 struct bgp_info *bgp_info;
1992 struct peer *peer;
1993 char peer_addr_buf[INET6_ADDRSTRLEN];
1994
1995 if (type == RMAP_BGP)
1996 {
1997 /* Fetch routemap's rule information. */
Dinesh G Duttad5233a2014-09-30 14:19:57 -07001998 bgp_info = object;
1999 peer = bgp_info->peer;
2000
2001 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
2002 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
2003 && peer->su_remote
2004 && sockunion_family (peer->su_remote) == AF_INET6)
2005 {
2006 inet_pton (AF_INET6, sockunion2str (peer->su_remote,
2007 peer_addr_buf,
2008 INET6_ADDRSTRLEN),
2009 &peer_address);
2010 }
2011 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
2012 && peer->su_local
2013 && sockunion_family (peer->su_local) == AF_INET6)
2014 {
2015 inet_pton (AF_INET, sockunion2str (peer->su_local,
2016 peer_addr_buf,
2017 INET6_ADDRSTRLEN),
2018 &peer_address);
2019 }
2020
2021 if (IN6_IS_ADDR_LINKLOCAL(&peer_address))
2022 {
2023 /* Set next hop value. */
2024 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = peer_address;
2025
2026 /* Set nexthop length. */
2027 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2028 bgp_info->attr->extra->mp_nexthop_len = 32;
2029 }
2030 else
2031 {
2032 /* Set next hop value. */
2033 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = peer_address;
2034
2035 /* Set nexthop length. */
2036 if (bgp_info->attr->extra->mp_nexthop_len == 0)
2037 bgp_info->attr->extra->mp_nexthop_len = 16;
2038 }
2039 }
2040
2041 return RMAP_OKAY;
2042}
2043
2044/* Route map `ip next-hop' compile function. Given string is converted
2045 to struct in_addr structure. */
2046static void *
2047route_set_ipv6_nexthop_peer_compile (const char *arg)
2048{
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002049 int *rins = NULL;
2050
2051 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (int));
2052 *rins = 1;
2053
2054 return rins;
2055}
2056
2057/* Free route map's compiled `ip next-hop' value. */
2058static void
2059route_set_ipv6_nexthop_peer_free (void *rule)
2060{
2061 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2062}
2063
2064/* Route map commands for ip nexthop set. */
2065struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd =
2066{
2067 "ipv6 next-hop peer-address",
2068 route_set_ipv6_nexthop_peer,
2069 route_set_ipv6_nexthop_peer_compile,
2070 route_set_ipv6_nexthop_peer_free
2071};
2072
paul718e3742002-12-13 20:15:29 +00002073/* `set vpnv4 nexthop A.B.C.D' */
2074
paul94f2b392005-06-28 12:44:16 +00002075static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002076route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2077 route_map_object_t type, void *object)
2078{
2079 struct in_addr *address;
2080 struct bgp_info *bgp_info;
2081
2082 if (type == RMAP_BGP)
2083 {
2084 /* Fetch routemap's rule information. */
2085 address = rule;
2086 bgp_info = object;
2087
2088 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002089 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
Lou Berger050defe2016-01-12 13:41:59 -05002090 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_len = 4;
paul718e3742002-12-13 20:15:29 +00002091 }
2092
2093 return RMAP_OKAY;
2094}
2095
paul94f2b392005-06-28 12:44:16 +00002096static void *
paulfd79ac92004-10-13 05:06:08 +00002097route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002098{
2099 int ret;
2100 struct in_addr *address;
2101
2102 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2103
2104 ret = inet_aton (arg, address);
2105
2106 if (ret == 0)
2107 {
2108 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2109 return NULL;
2110 }
2111
2112 return address;
2113}
2114
paul94f2b392005-06-28 12:44:16 +00002115static void
paul718e3742002-12-13 20:15:29 +00002116route_set_vpnv4_nexthop_free (void *rule)
2117{
2118 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2119}
2120
2121/* Route map commands for ip nexthop set. */
2122struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2123{
2124 "vpnv4 next-hop",
2125 route_set_vpnv4_nexthop,
2126 route_set_vpnv4_nexthop_compile,
2127 route_set_vpnv4_nexthop_free
2128};
David Lamparter6b0655a2014-06-04 06:53:35 +02002129
paul718e3742002-12-13 20:15:29 +00002130/* `set originator-id' */
2131
2132/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002133static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002134route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2135{
2136 struct in_addr *address;
2137 struct bgp_info *bgp_info;
2138
2139 if (type == RMAP_BGP)
2140 {
2141 address = rule;
2142 bgp_info = object;
2143
2144 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002145 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002146 }
2147
2148 return RMAP_OKAY;
2149}
2150
2151/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002152static void *
paulfd79ac92004-10-13 05:06:08 +00002153route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002154{
2155 int ret;
2156 struct in_addr *address;
2157
2158 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2159
2160 ret = inet_aton (arg, address);
2161
2162 if (ret == 0)
2163 {
2164 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2165 return NULL;
2166 }
2167
2168 return address;
2169}
2170
2171/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002172static void
paul718e3742002-12-13 20:15:29 +00002173route_set_originator_id_free (void *rule)
2174{
2175 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2176}
2177
Timo Teräs2aa640b2014-05-20 08:57:26 +03002178/* Set originator-id rule structure. */
paul718e3742002-12-13 20:15:29 +00002179struct route_map_rule_cmd route_set_originator_id_cmd =
2180{
2181 "originator-id",
2182 route_set_originator_id,
2183 route_set_originator_id_compile,
2184 route_set_originator_id_free,
2185};
David Lamparter6b0655a2014-06-04 06:53:35 +02002186
paul718e3742002-12-13 20:15:29 +00002187/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002188static int
paul718e3742002-12-13 20:15:29 +00002189bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002190 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002191{
2192 int ret;
2193
2194 ret = route_map_add_match (index, command, arg);
2195 if (ret)
2196 {
2197 switch (ret)
2198 {
2199 case RMAP_RULE_MISSING:
2200 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2201 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002202 case RMAP_COMPILE_ERROR:
2203 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2204 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002205 }
2206 }
2207 return CMD_SUCCESS;
2208}
2209
2210/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002211static int
paul718e3742002-12-13 20:15:29 +00002212bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002213 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002214{
2215 int ret;
2216
2217 ret = route_map_delete_match (index, command, arg);
2218 if (ret)
2219 {
2220 switch (ret)
2221 {
2222 case RMAP_RULE_MISSING:
2223 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2224 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002225 case RMAP_COMPILE_ERROR:
2226 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2227 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002228 }
2229 }
2230 return CMD_SUCCESS;
2231}
2232
2233/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002234static int
paul718e3742002-12-13 20:15:29 +00002235bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002236 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002237{
2238 int ret;
2239
2240 ret = route_map_add_set (index, command, arg);
2241 if (ret)
2242 {
2243 switch (ret)
2244 {
2245 case RMAP_RULE_MISSING:
2246 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2247 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002248 case RMAP_COMPILE_ERROR:
2249 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2250 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002251 }
2252 }
2253 return CMD_SUCCESS;
2254}
2255
2256/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002257static int
paul718e3742002-12-13 20:15:29 +00002258bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002259 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002260{
2261 int ret;
2262
2263 ret = route_map_delete_set (index, command, arg);
2264 if (ret)
2265 {
2266 switch (ret)
2267 {
2268 case RMAP_RULE_MISSING:
2269 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2270 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002271 case RMAP_COMPILE_ERROR:
2272 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2273 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002274 }
2275 }
2276 return CMD_SUCCESS;
2277}
2278
2279/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002280static void
paulfd79ac92004-10-13 05:06:08 +00002281bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002282{
2283 int i;
2284 afi_t afi;
2285 safi_t safi;
2286 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002287 struct listnode *node, *nnode;
2288 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002289 struct bgp *bgp;
2290 struct peer *peer;
2291 struct peer_group *group;
2292 struct bgp_filter *filter;
2293 struct bgp_node *bn;
2294 struct bgp_static *bgp_static;
2295
Lou Berger82dd7072016-01-12 13:41:57 -05002296 if (bm->bgp == NULL) /* may be called during cleanup */
2297 return;
2298
paul718e3742002-12-13 20:15:29 +00002299 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002300 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002301 {
paul1eb8ef22005-04-07 07:30:20 +00002302 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002303 {
2304 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2305 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2306 {
2307 filter = &peer->filter[afi][safi];
2308
paulfee0f4c2004-09-13 05:12:46 +00002309 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002310 {
2311 if (filter->map[direct].name)
2312 filter->map[direct].map =
2313 route_map_lookup_by_name (filter->map[direct].name);
2314 else
2315 filter->map[direct].map = NULL;
2316 }
2317
2318 if (filter->usmap.name)
2319 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2320 else
2321 filter->usmap.map = NULL;
2322 }
2323 }
paul1eb8ef22005-04-07 07:30:20 +00002324 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002325 {
2326 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2327 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2328 {
2329 filter = &group->conf->filter[afi][safi];
2330
paulfee0f4c2004-09-13 05:12:46 +00002331 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002332 {
2333 if (filter->map[direct].name)
2334 filter->map[direct].map =
2335 route_map_lookup_by_name (filter->map[direct].name);
2336 else
2337 filter->map[direct].map = NULL;
2338 }
2339
2340 if (filter->usmap.name)
2341 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2342 else
2343 filter->usmap.map = NULL;
2344 }
2345 }
2346 }
2347
2348 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002349 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002350 {
paul1eb8ef22005-04-07 07:30:20 +00002351 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002352 {
2353 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2354 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2355 {
2356 if (peer->default_rmap[afi][safi].name)
2357 peer->default_rmap[afi][safi].map =
2358 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2359 else
2360 peer->default_rmap[afi][safi].map = NULL;
2361 }
2362 }
2363 }
2364
2365 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002366 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002367 {
2368 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2369 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2370 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2371 bn = bgp_route_next (bn))
2372 if ((bgp_static = bn->info) != NULL)
2373 {
2374 if (bgp_static->rmap.name)
2375 bgp_static->rmap.map =
2376 route_map_lookup_by_name (bgp_static->rmap.name);
2377 else
2378 bgp_static->rmap.map = NULL;
2379 }
2380 }
2381
2382 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002383 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002384 {
2385 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2386 {
Donald Sharpf3cfc462016-01-07 09:33:28 -05002387 if (bgp->rmap[AFI_IP][i].name)
2388 bgp->rmap[AFI_IP][i].map =
2389 route_map_lookup_by_name (bgp->rmap[AFI_IP][i].name);
2390 if (bgp->rmap[AFI_IP6][i].name)
2391 bgp->rmap[AFI_IP6][i].map =
Andrej Ota220355d2016-05-09 20:49:01 +02002392 route_map_lookup_by_name (bgp->rmap[AFI_IP6][i].name);
paul718e3742002-12-13 20:15:29 +00002393 }
2394 }
2395}
David Lamparter6b0655a2014-06-04 06:53:35 +02002396
paulfee0f4c2004-09-13 05:12:46 +00002397DEFUN (match_peer,
2398 match_peer_cmd,
2399 "match peer (A.B.C.D|X:X::X:X)",
2400 MATCH_STR
2401 "Match peer address\n"
Igor Ryzhov93b493a2016-05-11 15:26:39 +03002402 "IP address of peer\n"
2403 "IPv6 address of peer\n")
paulfee0f4c2004-09-13 05:12:46 +00002404{
2405 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2406}
2407
2408DEFUN (match_peer_local,
2409 match_peer_local_cmd,
2410 "match peer local",
2411 MATCH_STR
2412 "Match peer address\n"
2413 "Static or Redistributed routes\n")
2414{
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +02002415 return bgp_route_match_add (vty, vty->index, "peer", "local");
paulfee0f4c2004-09-13 05:12:46 +00002416}
2417
2418DEFUN (no_match_peer,
2419 no_match_peer_cmd,
2420 "no match peer",
2421 NO_STR
2422 MATCH_STR
2423 "Match peer address\n")
2424{
2425 if (argc == 0)
2426 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2427
2428 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2429}
2430
2431ALIAS (no_match_peer,
2432 no_match_peer_val_cmd,
2433 "no match peer (A.B.C.D|X:X::X:X)",
2434 NO_STR
2435 MATCH_STR
2436 "Match peer address\n"
Igor Ryzhov93b493a2016-05-11 15:26:39 +03002437 "IP address of peer\n"
2438 "IPv6 address of peer\n")
paulfee0f4c2004-09-13 05:12:46 +00002439
2440ALIAS (no_match_peer,
2441 no_match_peer_local_cmd,
2442 "no match peer local",
2443 NO_STR
2444 MATCH_STR
2445 "Match peer address\n"
2446 "Static or Redistributed routes\n")
2447
paul718e3742002-12-13 20:15:29 +00002448DEFUN (match_ip_address,
2449 match_ip_address_cmd,
2450 "match ip address (<1-199>|<1300-2699>|WORD)",
2451 MATCH_STR
2452 IP_STR
2453 "Match address of route\n"
2454 "IP access-list number\n"
2455 "IP access-list number (expanded range)\n"
2456 "IP Access-list name\n")
2457{
2458 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2459}
2460
2461DEFUN (no_match_ip_address,
2462 no_match_ip_address_cmd,
2463 "no match ip address",
2464 NO_STR
2465 MATCH_STR
2466 IP_STR
2467 "Match address of route\n")
2468{
2469 if (argc == 0)
2470 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2471
2472 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2473}
2474
2475ALIAS (no_match_ip_address,
2476 no_match_ip_address_val_cmd,
2477 "no match ip address (<1-199>|<1300-2699>|WORD)",
2478 NO_STR
2479 MATCH_STR
2480 IP_STR
2481 "Match address of route\n"
2482 "IP access-list number\n"
2483 "IP access-list number (expanded range)\n"
2484 "IP Access-list name\n")
2485
2486DEFUN (match_ip_next_hop,
2487 match_ip_next_hop_cmd,
2488 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2489 MATCH_STR
2490 IP_STR
2491 "Match next-hop address of route\n"
2492 "IP access-list number\n"
2493 "IP access-list number (expanded range)\n"
2494 "IP Access-list name\n")
2495{
2496 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2497}
2498
2499DEFUN (no_match_ip_next_hop,
2500 no_match_ip_next_hop_cmd,
2501 "no match ip next-hop",
2502 NO_STR
2503 MATCH_STR
2504 IP_STR
2505 "Match next-hop address of route\n")
2506{
2507 if (argc == 0)
2508 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2509
2510 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2511}
2512
2513ALIAS (no_match_ip_next_hop,
2514 no_match_ip_next_hop_val_cmd,
2515 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2516 NO_STR
2517 MATCH_STR
2518 IP_STR
2519 "Match next-hop address of route\n"
2520 "IP access-list number\n"
2521 "IP access-list number (expanded range)\n"
2522 "IP Access-list name\n")
2523
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04002524/* match probability { */
2525
2526DEFUN (match_probability,
2527 match_probability_cmd,
2528 "match probability <0-100>",
2529 MATCH_STR
2530 "Match portion of routes defined by percentage value\n"
2531 "Percentage of routes\n")
2532{
2533 return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
2534}
2535
2536DEFUN (no_match_probability,
2537 no_match_probability_cmd,
2538 "no match probability",
2539 NO_STR
2540 MATCH_STR
2541 "Match portion of routes defined by percentage value\n")
2542{
2543 return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL);
2544}
2545
2546ALIAS (no_match_probability,
2547 no_match_probability_val_cmd,
2548 "no match probability <1-99>",
2549 NO_STR
2550 MATCH_STR
2551 "Match portion of routes defined by percentage value\n"
2552 "Percentage of routes\n")
2553
2554/* } */
2555
hassoc1643bb2005-02-02 16:43:17 +00002556DEFUN (match_ip_route_source,
2557 match_ip_route_source_cmd,
2558 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2559 MATCH_STR
2560 IP_STR
2561 "Match advertising source address of route\n"
2562 "IP access-list number\n"
2563 "IP access-list number (expanded range)\n"
2564 "IP standard access-list name\n")
2565{
2566 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2567}
2568
2569DEFUN (no_match_ip_route_source,
2570 no_match_ip_route_source_cmd,
2571 "no match ip route-source",
2572 NO_STR
2573 MATCH_STR
2574 IP_STR
2575 "Match advertising source address of route\n")
2576{
2577 if (argc == 0)
2578 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2579
2580 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2581}
2582
2583ALIAS (no_match_ip_route_source,
2584 no_match_ip_route_source_val_cmd,
2585 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2586 NO_STR
2587 MATCH_STR
2588 IP_STR
2589 "Match advertising source address of route\n"
2590 "IP access-list number\n"
2591 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002592 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002593
paul718e3742002-12-13 20:15:29 +00002594DEFUN (match_ip_address_prefix_list,
2595 match_ip_address_prefix_list_cmd,
2596 "match ip address prefix-list WORD",
2597 MATCH_STR
2598 IP_STR
2599 "Match address of route\n"
2600 "Match entries of prefix-lists\n"
2601 "IP prefix-list name\n")
2602{
2603 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2604}
2605
2606DEFUN (no_match_ip_address_prefix_list,
2607 no_match_ip_address_prefix_list_cmd,
2608 "no match ip address prefix-list",
2609 NO_STR
2610 MATCH_STR
2611 IP_STR
2612 "Match address of route\n"
2613 "Match entries of prefix-lists\n")
2614{
2615 if (argc == 0)
2616 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2617
2618 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2619}
2620
2621ALIAS (no_match_ip_address_prefix_list,
2622 no_match_ip_address_prefix_list_val_cmd,
2623 "no match ip address prefix-list WORD",
2624 NO_STR
2625 MATCH_STR
2626 IP_STR
2627 "Match address of route\n"
2628 "Match entries of prefix-lists\n"
2629 "IP prefix-list name\n")
2630
2631DEFUN (match_ip_next_hop_prefix_list,
2632 match_ip_next_hop_prefix_list_cmd,
2633 "match ip next-hop prefix-list WORD",
2634 MATCH_STR
2635 IP_STR
2636 "Match next-hop address of route\n"
2637 "Match entries of prefix-lists\n"
2638 "IP prefix-list name\n")
2639{
2640 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2641}
2642
2643DEFUN (no_match_ip_next_hop_prefix_list,
2644 no_match_ip_next_hop_prefix_list_cmd,
2645 "no match ip next-hop prefix-list",
2646 NO_STR
2647 MATCH_STR
2648 IP_STR
2649 "Match next-hop address of route\n"
2650 "Match entries of prefix-lists\n")
2651{
2652 if (argc == 0)
2653 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2654
2655 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2656}
2657
2658ALIAS (no_match_ip_next_hop_prefix_list,
2659 no_match_ip_next_hop_prefix_list_val_cmd,
2660 "no match ip next-hop prefix-list WORD",
2661 NO_STR
2662 MATCH_STR
2663 IP_STR
2664 "Match next-hop address of route\n"
2665 "Match entries of prefix-lists\n"
2666 "IP prefix-list name\n")
2667
hassoc1643bb2005-02-02 16:43:17 +00002668DEFUN (match_ip_route_source_prefix_list,
2669 match_ip_route_source_prefix_list_cmd,
2670 "match ip route-source prefix-list WORD",
2671 MATCH_STR
2672 IP_STR
2673 "Match advertising source address of route\n"
2674 "Match entries of prefix-lists\n"
2675 "IP prefix-list name\n")
2676{
2677 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2678}
2679
2680DEFUN (no_match_ip_route_source_prefix_list,
2681 no_match_ip_route_source_prefix_list_cmd,
2682 "no match ip route-source prefix-list",
2683 NO_STR
2684 MATCH_STR
2685 IP_STR
2686 "Match advertising source address of route\n"
2687 "Match entries of prefix-lists\n")
2688{
2689 if (argc == 0)
2690 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2691
2692 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2693}
2694
2695ALIAS (no_match_ip_route_source_prefix_list,
2696 no_match_ip_route_source_prefix_list_val_cmd,
2697 "no match ip route-source prefix-list WORD",
2698 NO_STR
2699 MATCH_STR
2700 IP_STR
2701 "Match advertising source address of route\n"
2702 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002703 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002704
paul718e3742002-12-13 20:15:29 +00002705DEFUN (match_metric,
2706 match_metric_cmd,
2707 "match metric <0-4294967295>",
2708 MATCH_STR
2709 "Match metric of route\n"
2710 "Metric value\n")
2711{
2712 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2713}
2714
2715DEFUN (no_match_metric,
2716 no_match_metric_cmd,
2717 "no match metric",
2718 NO_STR
2719 MATCH_STR
2720 "Match metric of route\n")
2721{
2722 if (argc == 0)
2723 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2724
2725 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2726}
2727
2728ALIAS (no_match_metric,
2729 no_match_metric_val_cmd,
2730 "no match metric <0-4294967295>",
2731 NO_STR
2732 MATCH_STR
2733 "Match metric of route\n"
2734 "Metric value\n")
2735
2736DEFUN (match_community,
2737 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002738 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002739 MATCH_STR
2740 "Match BGP community list\n"
2741 "Community-list number (standard)\n"
2742 "Community-list number (expanded)\n"
2743 "Community-list name\n")
2744{
2745 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2746}
2747
2748DEFUN (match_community_exact,
2749 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002750 "match community (<1-99>|<100-500>|WORD) exact-match",
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 "Do exact matching of communities\n")
2757{
2758 int ret;
2759 char *argstr;
2760
2761 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2762 strlen (argv[0]) + strlen ("exact-match") + 2);
2763
2764 sprintf (argstr, "%s exact-match", argv[0]);
2765
2766 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2767
2768 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2769
2770 return ret;
2771}
2772
2773DEFUN (no_match_community,
2774 no_match_community_cmd,
2775 "no match community",
2776 NO_STR
2777 MATCH_STR
2778 "Match BGP community list\n")
2779{
2780 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2781}
2782
2783ALIAS (no_match_community,
2784 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002785 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002786 NO_STR
2787 MATCH_STR
2788 "Match BGP community list\n"
2789 "Community-list number (standard)\n"
2790 "Community-list number (expanded)\n"
2791 "Community-list name\n")
2792
2793ALIAS (no_match_community,
2794 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002795 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002796 NO_STR
2797 MATCH_STR
2798 "Match BGP community list\n"
2799 "Community-list number (standard)\n"
2800 "Community-list number (expanded)\n"
2801 "Community-list name\n"
2802 "Do exact matching of communities\n")
2803
paul73ffb252003-04-19 15:49:49 +00002804DEFUN (match_ecommunity,
2805 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002806 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002807 MATCH_STR
2808 "Match BGP/VPN extended community list\n"
2809 "Extended community-list number (standard)\n"
2810 "Extended community-list number (expanded)\n"
2811 "Extended community-list name\n")
2812{
2813 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2814}
2815
2816DEFUN (no_match_ecommunity,
2817 no_match_ecommunity_cmd,
2818 "no match extcommunity",
2819 NO_STR
2820 MATCH_STR
2821 "Match BGP/VPN extended community list\n")
2822{
2823 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2824}
2825
2826ALIAS (no_match_ecommunity,
2827 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002828 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002829 NO_STR
2830 MATCH_STR
2831 "Match BGP/VPN extended community list\n"
2832 "Extended community-list number (standard)\n"
2833 "Extended community-list number (expanded)\n"
2834 "Extended community-list name\n")
2835
paul718e3742002-12-13 20:15:29 +00002836DEFUN (match_aspath,
2837 match_aspath_cmd,
2838 "match as-path WORD",
2839 MATCH_STR
2840 "Match BGP AS path list\n"
2841 "AS path access-list name\n")
2842{
2843 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2844}
2845
2846DEFUN (no_match_aspath,
2847 no_match_aspath_cmd,
2848 "no match as-path",
2849 NO_STR
2850 MATCH_STR
2851 "Match BGP AS path list\n")
2852{
2853 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2854}
2855
2856ALIAS (no_match_aspath,
2857 no_match_aspath_val_cmd,
2858 "no match as-path WORD",
2859 NO_STR
2860 MATCH_STR
2861 "Match BGP AS path list\n"
2862 "AS path access-list name\n")
2863
2864DEFUN (match_origin,
2865 match_origin_cmd,
2866 "match origin (egp|igp|incomplete)",
2867 MATCH_STR
2868 "BGP origin code\n"
2869 "remote EGP\n"
2870 "local IGP\n"
2871 "unknown heritage\n")
2872{
2873 if (strncmp (argv[0], "igp", 2) == 0)
2874 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2875 if (strncmp (argv[0], "egp", 1) == 0)
2876 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2877 if (strncmp (argv[0], "incomplete", 2) == 0)
2878 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2879
2880 return CMD_WARNING;
2881}
2882
2883DEFUN (no_match_origin,
2884 no_match_origin_cmd,
2885 "no match origin",
2886 NO_STR
2887 MATCH_STR
2888 "BGP origin code\n")
2889{
2890 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2891}
2892
2893ALIAS (no_match_origin,
2894 no_match_origin_val_cmd,
2895 "no match origin (egp|igp|incomplete)",
2896 NO_STR
2897 MATCH_STR
2898 "BGP origin code\n"
2899 "remote EGP\n"
2900 "local IGP\n"
2901 "unknown heritage\n")
2902
2903DEFUN (set_ip_nexthop,
2904 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002905 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002906 SET_STR
2907 IP_STR
2908 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002909 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002910{
2911 union sockunion su;
2912 int ret;
2913
2914 ret = str2sockunion (argv[0], &su);
2915 if (ret < 0)
2916 {
2917 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2918 return CMD_WARNING;
2919 }
2920
2921 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2922}
2923
paulaf5cd0a2003-11-02 07:24:40 +00002924DEFUN (set_ip_nexthop_peer,
2925 set_ip_nexthop_peer_cmd,
2926 "set ip next-hop peer-address",
2927 SET_STR
2928 IP_STR
2929 "Next hop address\n"
2930 "Use peer address (for BGP only)\n")
2931{
2932 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
2933}
2934
paul94f2b392005-06-28 12:44:16 +00002935DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00002936 no_set_ip_nexthop_peer_cmd,
2937 "no set ip next-hop peer-address",
2938 NO_STR
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_delete (vty, vty->index, "ip next-hop", NULL);
2945}
2946
2947
paul718e3742002-12-13 20:15:29 +00002948DEFUN (no_set_ip_nexthop,
2949 no_set_ip_nexthop_cmd,
2950 "no set ip next-hop",
2951 NO_STR
2952 SET_STR
paul718e3742002-12-13 20:15:29 +00002953 "Next hop address\n")
2954{
paulaf5cd0a2003-11-02 07:24:40 +00002955 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00002956 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
2957
2958 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
2959}
2960
2961ALIAS (no_set_ip_nexthop,
2962 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002963 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002964 NO_STR
2965 SET_STR
2966 IP_STR
2967 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002968 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002969
2970DEFUN (set_metric,
2971 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00002972 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00002973 SET_STR
2974 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00002975 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00002976{
2977 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
2978}
2979
paul73ffb252003-04-19 15:49:49 +00002980ALIAS (set_metric,
2981 set_metric_addsub_cmd,
2982 "set metric <+/-metric>",
2983 SET_STR
2984 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00002985 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00002986
Timo Teräsef757702015-04-29 09:43:04 +03002987ALIAS (set_metric,
2988 set_metric_rtt_cmd,
2989 "set metric (rtt|+rtt|-rtt)",
2990 SET_STR
2991 "Metric value for destination routing protocol\n"
2992 "Assign round trip time\n"
2993 "Add round trip time\n"
2994 "Subtract round trip time\n")
2995
paul718e3742002-12-13 20:15:29 +00002996DEFUN (no_set_metric,
2997 no_set_metric_cmd,
2998 "no set metric",
2999 NO_STR
3000 SET_STR
3001 "Metric value for destination routing protocol\n")
3002{
3003 if (argc == 0)
3004 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
3005
3006 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
3007}
3008
3009ALIAS (no_set_metric,
3010 no_set_metric_val_cmd,
3011 "no set metric <0-4294967295>",
3012 NO_STR
3013 SET_STR
3014 "Metric value for destination routing protocol\n"
3015 "Metric value\n")
3016
3017DEFUN (set_local_pref,
3018 set_local_pref_cmd,
3019 "set local-preference <0-4294967295>",
3020 SET_STR
3021 "BGP local preference path attribute\n"
3022 "Preference value\n")
3023{
3024 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
3025}
3026
3027DEFUN (no_set_local_pref,
3028 no_set_local_pref_cmd,
3029 "no set local-preference",
3030 NO_STR
3031 SET_STR
3032 "BGP local preference path attribute\n")
3033{
3034 if (argc == 0)
3035 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3036
3037 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
3038}
3039
3040ALIAS (no_set_local_pref,
3041 no_set_local_pref_val_cmd,
3042 "no set local-preference <0-4294967295>",
3043 NO_STR
3044 SET_STR
3045 "BGP local preference path attribute\n"
3046 "Preference value\n")
3047
3048DEFUN (set_weight,
3049 set_weight_cmd,
3050 "set weight <0-4294967295>",
3051 SET_STR
3052 "BGP weight for routing table\n"
3053 "Weight value\n")
3054{
3055 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3056}
3057
3058DEFUN (no_set_weight,
3059 no_set_weight_cmd,
3060 "no set weight",
3061 NO_STR
3062 SET_STR
3063 "BGP weight for routing table\n")
3064{
3065 if (argc == 0)
3066 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3067
3068 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3069}
3070
3071ALIAS (no_set_weight,
3072 no_set_weight_val_cmd,
3073 "no set weight <0-4294967295>",
3074 NO_STR
3075 SET_STR
3076 "BGP weight for routing table\n"
3077 "Weight value\n")
3078
3079DEFUN (set_aspath_prepend,
3080 set_aspath_prepend_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003081 "set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003082 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003083 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003084 "Prepend to the as-path\n"
3085 "AS number\n")
3086{
3087 int ret;
3088 char *str;
3089
3090 str = argv_concat (argv, argc, 0);
3091 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3092 XFREE (MTYPE_TMP, str);
3093
3094 return ret;
3095}
3096
Timo Teräs85c854a2014-09-30 11:31:53 +03003097ALIAS (set_aspath_prepend,
3098 set_aspath_prepend_lastas_cmd,
3099 "set as-path prepend (last-as) <1-10>",
3100 SET_STR
3101 "Transform BGP AS_PATH attribute\n"
3102 "Prepend to the as-path\n"
3103 "Use the peer's AS-number\n"
David Lamparterb7d50212015-03-03 08:53:18 +01003104 "Number of times to insert")
Timo Teräs85c854a2014-09-30 11:31:53 +03003105
paul718e3742002-12-13 20:15:29 +00003106DEFUN (no_set_aspath_prepend,
3107 no_set_aspath_prepend_cmd,
3108 "no set as-path prepend",
3109 NO_STR
3110 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003111 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003112 "Prepend to the as-path\n")
3113{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00003114 int ret;
3115 char *str;
3116
3117 if (argc == 0)
3118 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3119
3120 str = argv_concat (argv, argc, 0);
3121 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3122 XFREE (MTYPE_TMP, str);
3123 return ret;
paul718e3742002-12-13 20:15:29 +00003124}
3125
3126ALIAS (no_set_aspath_prepend,
3127 no_set_aspath_prepend_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003128 "no set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003129 NO_STR
3130 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003131 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003132 "Prepend to the as-path\n"
3133 "AS number\n")
3134
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003135DEFUN (set_aspath_exclude,
3136 set_aspath_exclude_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003137 "set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003138 SET_STR
3139 "Transform BGP AS-path attribute\n"
3140 "Exclude from the as-path\n"
3141 "AS number\n")
3142{
3143 int ret;
3144 char *str;
3145
3146 str = argv_concat (argv, argc, 0);
3147 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3148 XFREE (MTYPE_TMP, str);
3149 return ret;
3150}
3151
3152DEFUN (no_set_aspath_exclude,
3153 no_set_aspath_exclude_cmd,
3154 "no set as-path exclude",
3155 NO_STR
3156 SET_STR
3157 "Transform BGP AS_PATH attribute\n"
3158 "Exclude from the as-path\n")
3159{
3160 int ret;
3161 char *str;
3162
3163 if (argc == 0)
3164 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3165
3166 str = argv_concat (argv, argc, 0);
3167 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3168 XFREE (MTYPE_TMP, str);
3169 return ret;
3170}
3171
3172ALIAS (no_set_aspath_exclude,
3173 no_set_aspath_exclude_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003174 "no set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003175 NO_STR
3176 SET_STR
3177 "Transform BGP AS_PATH attribute\n"
3178 "Exclude from the as-path\n"
3179 "AS number\n")
3180
paul718e3742002-12-13 20:15:29 +00003181DEFUN (set_community,
3182 set_community_cmd,
3183 "set community .AA:NN",
3184 SET_STR
3185 "BGP community attribute\n"
3186 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3187{
3188 int i;
3189 int first = 0;
3190 int additive = 0;
3191 struct buffer *b;
3192 struct community *com = NULL;
3193 char *str;
3194 char *argstr;
3195 int ret;
3196
3197 b = buffer_new (1024);
3198
3199 for (i = 0; i < argc; i++)
3200 {
3201 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3202 {
3203 additive = 1;
3204 continue;
3205 }
3206
3207 if (first)
3208 buffer_putc (b, ' ');
3209 else
3210 first = 1;
3211
3212 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3213 {
3214 buffer_putstr (b, "internet");
3215 continue;
3216 }
3217 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3218 {
3219 buffer_putstr (b, "local-AS");
3220 continue;
3221 }
3222 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3223 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3224 {
3225 buffer_putstr (b, "no-advertise");
3226 continue;
3227 }
3228 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3229 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3230 {
3231 buffer_putstr (b, "no-export");
3232 continue;
3233 }
3234 buffer_putstr (b, argv[i]);
3235 }
3236 buffer_putc (b, '\0');
3237
3238 /* Fetch result string then compile it to communities attribute. */
3239 str = buffer_getstr (b);
3240 buffer_free (b);
3241
3242 if (str)
3243 {
3244 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003245 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003246 }
3247
3248 /* Can't compile user input into communities attribute. */
3249 if (! com)
3250 {
3251 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3252 return CMD_WARNING;
3253 }
3254
3255 /* Set communites attribute string. */
3256 str = community_str (com);
3257
3258 if (additive)
3259 {
3260 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3261 strcpy (argstr, str);
3262 strcpy (argstr + strlen (str), " additive");
3263 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3264 XFREE (MTYPE_TMP, argstr);
3265 }
3266 else
3267 ret = bgp_route_set_add (vty, vty->index, "community", str);
3268
3269 community_free (com);
3270
3271 return ret;
3272}
3273
3274DEFUN (set_community_none,
3275 set_community_none_cmd,
3276 "set community none",
3277 SET_STR
3278 "BGP community attribute\n"
3279 "No community attribute\n")
3280{
3281 return bgp_route_set_add (vty, vty->index, "community", "none");
3282}
3283
3284DEFUN (no_set_community,
3285 no_set_community_cmd,
3286 "no set community",
3287 NO_STR
3288 SET_STR
3289 "BGP community attribute\n")
3290{
3291 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3292}
3293
3294ALIAS (no_set_community,
3295 no_set_community_val_cmd,
3296 "no set community .AA:NN",
3297 NO_STR
3298 SET_STR
3299 "BGP community attribute\n"
3300 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3301
3302ALIAS (no_set_community,
3303 no_set_community_none_cmd,
3304 "no set community none",
3305 NO_STR
3306 SET_STR
3307 "BGP community attribute\n"
3308 "No community attribute\n")
3309
3310DEFUN (set_community_delete,
3311 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003312 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003313 SET_STR
3314 "set BGP community list (for deletion)\n"
3315 "Community-list number (standard)\n"
3316 "Communitly-list number (expanded)\n"
3317 "Community-list name\n"
3318 "Delete matching communities\n")
3319{
3320 char *str;
3321
3322 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3323 strcpy (str, argv[0]);
3324 strcpy (str + strlen (argv[0]), " delete");
3325
3326 bgp_route_set_add (vty, vty->index, "comm-list", str);
3327
3328 XFREE (MTYPE_TMP, str);
3329 return CMD_SUCCESS;
3330}
3331
3332DEFUN (no_set_community_delete,
3333 no_set_community_delete_cmd,
3334 "no set comm-list",
3335 NO_STR
3336 SET_STR
3337 "set BGP community list (for deletion)\n")
3338{
3339 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3340}
3341
3342ALIAS (no_set_community_delete,
3343 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003344 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003345 NO_STR
3346 SET_STR
3347 "set BGP community list (for deletion)\n"
3348 "Community-list number (standard)\n"
3349 "Communitly-list number (expanded)\n"
3350 "Community-list name\n"
3351 "Delete matching communities\n")
3352
3353DEFUN (set_ecommunity_rt,
3354 set_ecommunity_rt_cmd,
3355 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3356 SET_STR
3357 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003358 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003359 "VPN extended community\n")
3360{
3361 int ret;
3362 char *str;
3363
3364 str = argv_concat (argv, argc, 0);
3365 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3366 XFREE (MTYPE_TMP, str);
3367
3368 return ret;
3369}
3370
3371DEFUN (no_set_ecommunity_rt,
3372 no_set_ecommunity_rt_cmd,
3373 "no set extcommunity rt",
3374 NO_STR
3375 SET_STR
3376 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003377 "Route Target extended community\n")
paul718e3742002-12-13 20:15:29 +00003378{
3379 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3380}
3381
3382ALIAS (no_set_ecommunity_rt,
3383 no_set_ecommunity_rt_val_cmd,
3384 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3385 NO_STR
3386 SET_STR
3387 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003388 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003389 "VPN extended community\n")
3390
3391DEFUN (set_ecommunity_soo,
3392 set_ecommunity_soo_cmd,
3393 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3394 SET_STR
3395 "BGP extended community attribute\n"
3396 "Site-of-Origin extended community\n"
3397 "VPN extended community\n")
3398{
3399 int ret;
3400 char *str;
3401
3402 str = argv_concat (argv, argc, 0);
3403 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3404 XFREE (MTYPE_TMP, str);
3405 return ret;
3406}
3407
3408DEFUN (no_set_ecommunity_soo,
3409 no_set_ecommunity_soo_cmd,
3410 "no set extcommunity soo",
3411 NO_STR
3412 SET_STR
3413 "BGP extended community attribute\n"
3414 "Site-of-Origin extended community\n")
3415{
3416 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3417}
3418
3419ALIAS (no_set_ecommunity_soo,
3420 no_set_ecommunity_soo_val_cmd,
3421 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3422 NO_STR
3423 SET_STR
3424 "BGP extended community attribute\n"
3425 "Site-of-Origin extended community\n"
3426 "VPN extended community\n")
3427
3428DEFUN (set_origin,
3429 set_origin_cmd,
3430 "set origin (egp|igp|incomplete)",
3431 SET_STR
3432 "BGP origin code\n"
3433 "remote EGP\n"
3434 "local IGP\n"
3435 "unknown heritage\n")
3436{
3437 if (strncmp (argv[0], "igp", 2) == 0)
3438 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3439 if (strncmp (argv[0], "egp", 1) == 0)
3440 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3441 if (strncmp (argv[0], "incomplete", 2) == 0)
3442 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3443
3444 return CMD_WARNING;
3445}
3446
3447DEFUN (no_set_origin,
3448 no_set_origin_cmd,
3449 "no set origin",
3450 NO_STR
3451 SET_STR
3452 "BGP origin code\n")
3453{
3454 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3455}
3456
3457ALIAS (no_set_origin,
3458 no_set_origin_val_cmd,
3459 "no set origin (egp|igp|incomplete)",
3460 NO_STR
3461 SET_STR
3462 "BGP origin code\n"
3463 "remote EGP\n"
3464 "local IGP\n"
3465 "unknown heritage\n")
3466
3467DEFUN (set_atomic_aggregate,
3468 set_atomic_aggregate_cmd,
3469 "set atomic-aggregate",
3470 SET_STR
3471 "BGP atomic aggregate attribute\n" )
3472{
3473 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3474}
3475
3476DEFUN (no_set_atomic_aggregate,
3477 no_set_atomic_aggregate_cmd,
3478 "no set atomic-aggregate",
3479 NO_STR
3480 SET_STR
3481 "BGP atomic aggregate attribute\n" )
3482{
3483 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3484}
3485
3486DEFUN (set_aggregator_as,
3487 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003488 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003489 SET_STR
3490 "BGP aggregator attribute\n"
3491 "AS number of aggregator\n"
3492 "AS number\n"
3493 "IP address of aggregator\n")
3494{
3495 int ret;
Paul Jakma7aa9dce2014-09-19 14:42:23 +01003496 as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
paul718e3742002-12-13 20:15:29 +00003497 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003498 char *argstr;
3499
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003500 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003501
paul718e3742002-12-13 20:15:29 +00003502 ret = inet_aton (argv[1], &address);
3503 if (ret == 0)
3504 {
3505 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3506 return CMD_WARNING;
3507 }
3508
3509 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3510 strlen (argv[0]) + strlen (argv[1]) + 2);
3511
3512 sprintf (argstr, "%s %s", argv[0], argv[1]);
3513
3514 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3515
3516 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3517
3518 return ret;
3519}
3520
3521DEFUN (no_set_aggregator_as,
3522 no_set_aggregator_as_cmd,
3523 "no set aggregator as",
3524 NO_STR
3525 SET_STR
3526 "BGP aggregator attribute\n"
3527 "AS number of aggregator\n")
3528{
3529 int ret;
Paul Jakma7aa9dce2014-09-19 14:42:23 +01003530 as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
paul718e3742002-12-13 20:15:29 +00003531 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003532 char *argstr;
3533
3534 if (argv == 0)
3535 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3536
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003537 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003538
3539 ret = inet_aton (argv[1], &address);
3540 if (ret == 0)
3541 {
3542 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3543 return CMD_WARNING;
3544 }
3545
3546 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3547 strlen (argv[0]) + strlen (argv[1]) + 2);
3548
3549 sprintf (argstr, "%s %s", argv[0], argv[1]);
3550
3551 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3552
3553 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3554
3555 return ret;
3556}
3557
3558ALIAS (no_set_aggregator_as,
3559 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003560 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003561 NO_STR
3562 SET_STR
3563 "BGP aggregator attribute\n"
3564 "AS number of aggregator\n"
3565 "AS number\n"
3566 "IP address of aggregator\n")
3567
paul718e3742002-12-13 20:15:29 +00003568DEFUN (match_ipv6_address,
3569 match_ipv6_address_cmd,
3570 "match ipv6 address WORD",
3571 MATCH_STR
3572 IPV6_STR
3573 "Match IPv6 address of route\n"
3574 "IPv6 access-list name\n")
3575{
3576 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3577}
3578
3579DEFUN (no_match_ipv6_address,
3580 no_match_ipv6_address_cmd,
3581 "no match ipv6 address WORD",
3582 NO_STR
3583 MATCH_STR
3584 IPV6_STR
3585 "Match IPv6 address of route\n"
3586 "IPv6 access-list name\n")
3587{
3588 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3589}
3590
3591DEFUN (match_ipv6_next_hop,
3592 match_ipv6_next_hop_cmd,
3593 "match ipv6 next-hop X:X::X:X",
3594 MATCH_STR
3595 IPV6_STR
3596 "Match IPv6 next-hop address of route\n"
3597 "IPv6 address of next hop\n")
3598{
3599 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3600}
3601
3602DEFUN (no_match_ipv6_next_hop,
3603 no_match_ipv6_next_hop_cmd,
3604 "no match ipv6 next-hop X:X::X:X",
3605 NO_STR
3606 MATCH_STR
3607 IPV6_STR
3608 "Match IPv6 next-hop address of route\n"
3609 "IPv6 address of next hop\n")
3610{
3611 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3612}
3613
3614DEFUN (match_ipv6_address_prefix_list,
3615 match_ipv6_address_prefix_list_cmd,
3616 "match ipv6 address prefix-list WORD",
3617 MATCH_STR
3618 IPV6_STR
3619 "Match address of route\n"
3620 "Match entries of prefix-lists\n"
3621 "IP prefix-list name\n")
3622{
3623 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3624}
3625
3626DEFUN (no_match_ipv6_address_prefix_list,
3627 no_match_ipv6_address_prefix_list_cmd,
3628 "no match ipv6 address prefix-list WORD",
3629 NO_STR
3630 MATCH_STR
3631 IPV6_STR
3632 "Match address of route\n"
3633 "Match entries of prefix-lists\n"
3634 "IP prefix-list name\n")
3635{
3636 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3637}
3638
Dinesh G Duttad5233a2014-09-30 14:19:57 -07003639DEFUN (set_ipv6_nexthop_peer,
3640 set_ipv6_nexthop_peer_cmd,
3641 "set ipv6 next-hop peer-address",
3642 SET_STR
3643 IPV6_STR
3644 "Next hop address\n"
3645 "Use peer address (for BGP only)\n")
3646{
3647 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop peer-address", NULL);
3648}
3649
3650DEFUN (no_set_ipv6_nexthop_peer,
3651 no_set_ipv6_nexthop_peer_cmd,
3652 "no set ipv6 next-hop peer-address",
3653 NO_STR
3654 SET_STR
3655 IPV6_STR
3656 "IPv6 next-hop address\n"
3657 )
3658{
3659 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3660}
3661
paul718e3742002-12-13 20:15:29 +00003662DEFUN (set_ipv6_nexthop_global,
3663 set_ipv6_nexthop_global_cmd,
3664 "set ipv6 next-hop global X:X::X:X",
3665 SET_STR
3666 IPV6_STR
3667 "IPv6 next-hop address\n"
3668 "IPv6 global address\n"
3669 "IPv6 address of next hop\n")
3670{
3671 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3672}
3673
3674DEFUN (no_set_ipv6_nexthop_global,
3675 no_set_ipv6_nexthop_global_cmd,
3676 "no set ipv6 next-hop global",
3677 NO_STR
3678 SET_STR
3679 IPV6_STR
3680 "IPv6 next-hop address\n"
3681 "IPv6 global address\n")
3682{
3683 if (argc == 0)
3684 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3685
3686 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3687}
3688
3689ALIAS (no_set_ipv6_nexthop_global,
3690 no_set_ipv6_nexthop_global_val_cmd,
3691 "no set ipv6 next-hop global X:X::X:X",
3692 NO_STR
3693 SET_STR
3694 IPV6_STR
3695 "IPv6 next-hop address\n"
3696 "IPv6 global address\n"
3697 "IPv6 address of next hop\n")
3698
3699DEFUN (set_ipv6_nexthop_local,
3700 set_ipv6_nexthop_local_cmd,
3701 "set ipv6 next-hop local X:X::X:X",
3702 SET_STR
3703 IPV6_STR
3704 "IPv6 next-hop address\n"
3705 "IPv6 local address\n"
3706 "IPv6 address of next hop\n")
3707{
3708 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3709}
3710
3711DEFUN (no_set_ipv6_nexthop_local,
3712 no_set_ipv6_nexthop_local_cmd,
3713 "no set ipv6 next-hop local",
3714 NO_STR
3715 SET_STR
3716 IPV6_STR
3717 "IPv6 next-hop address\n"
3718 "IPv6 local address\n")
3719{
3720 if (argc == 0)
3721 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3722
3723 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3724}
3725
3726ALIAS (no_set_ipv6_nexthop_local,
3727 no_set_ipv6_nexthop_local_val_cmd,
3728 "no set ipv6 next-hop local X:X::X:X",
3729 NO_STR
3730 SET_STR
3731 IPV6_STR
3732 "IPv6 next-hop address\n"
3733 "IPv6 local address\n"
3734 "IPv6 address of next hop\n")
paul718e3742002-12-13 20:15:29 +00003735
3736DEFUN (set_vpnv4_nexthop,
3737 set_vpnv4_nexthop_cmd,
3738 "set vpnv4 next-hop A.B.C.D",
3739 SET_STR
3740 "VPNv4 information\n"
3741 "VPNv4 next-hop address\n"
3742 "IP address of next hop\n")
3743{
3744 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3745}
3746
3747DEFUN (no_set_vpnv4_nexthop,
3748 no_set_vpnv4_nexthop_cmd,
3749 "no set vpnv4 next-hop",
3750 NO_STR
3751 SET_STR
3752 "VPNv4 information\n"
3753 "VPNv4 next-hop address\n")
3754{
3755 if (argc == 0)
3756 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3757
3758 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3759}
3760
3761ALIAS (no_set_vpnv4_nexthop,
3762 no_set_vpnv4_nexthop_val_cmd,
3763 "no set vpnv4 next-hop A.B.C.D",
3764 NO_STR
3765 SET_STR
3766 "VPNv4 information\n"
3767 "VPNv4 next-hop address\n"
3768 "IP address of next hop\n")
3769
3770DEFUN (set_originator_id,
3771 set_originator_id_cmd,
3772 "set originator-id A.B.C.D",
3773 SET_STR
3774 "BGP originator ID attribute\n"
3775 "IP address of originator\n")
3776{
3777 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3778}
3779
3780DEFUN (no_set_originator_id,
3781 no_set_originator_id_cmd,
3782 "no set originator-id",
3783 NO_STR
3784 SET_STR
3785 "BGP originator ID attribute\n")
3786{
3787 if (argc == 0)
3788 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3789
3790 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3791}
3792
3793ALIAS (no_set_originator_id,
3794 no_set_originator_id_val_cmd,
3795 "no set originator-id A.B.C.D",
3796 NO_STR
3797 SET_STR
3798 "BGP originator ID attribute\n"
3799 "IP address of originator\n")
3800
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003801DEFUN_DEPRECATED (set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003802 set_pathlimit_ttl_cmd,
3803 "set pathlimit ttl <1-255>",
3804 SET_STR
3805 "BGP AS-Pathlimit attribute\n"
3806 "Set AS-Path Hop-count TTL\n")
3807{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003808 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003809}
3810
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003811DEFUN_DEPRECATED (no_set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003812 no_set_pathlimit_ttl_cmd,
3813 "no set pathlimit ttl",
3814 NO_STR
3815 SET_STR
3816 "BGP AS-Pathlimit attribute\n"
3817 "Set AS-Path Hop-count TTL\n")
3818{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003819 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003820}
3821
3822ALIAS (no_set_pathlimit_ttl,
3823 no_set_pathlimit_ttl_val_cmd,
3824 "no set pathlimit ttl <1-255>",
3825 NO_STR
3826 MATCH_STR
3827 "BGP AS-Pathlimit attribute\n"
3828 "Set AS-Path Hop-count TTL\n")
3829
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003830DEFUN_DEPRECATED (match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003831 match_pathlimit_as_cmd,
3832 "match pathlimit as <1-65535>",
3833 MATCH_STR
3834 "BGP AS-Pathlimit attribute\n"
3835 "Match Pathlimit AS number\n")
3836{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003837 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003838}
3839
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003840DEFUN_DEPRECATED (no_match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003841 no_match_pathlimit_as_cmd,
3842 "no match pathlimit as",
3843 NO_STR
3844 MATCH_STR
3845 "BGP AS-Pathlimit attribute\n"
3846 "Match Pathlimit AS number\n")
3847{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003848 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003849}
3850
3851ALIAS (no_match_pathlimit_as,
3852 no_match_pathlimit_as_val_cmd,
3853 "no match pathlimit as <1-65535>",
3854 NO_STR
3855 MATCH_STR
3856 "BGP AS-Pathlimit attribute\n"
3857 "Match Pathlimit ASN\n")
3858
David Lamparter6b0655a2014-06-04 06:53:35 +02003859
paul718e3742002-12-13 20:15:29 +00003860/* Initialization of route map. */
3861void
paul94f2b392005-06-28 12:44:16 +00003862bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003863{
3864 route_map_init ();
3865 route_map_init_vty ();
3866 route_map_add_hook (bgp_route_map_update);
3867 route_map_delete_hook (bgp_route_map_update);
3868
paulfee0f4c2004-09-13 05:12:46 +00003869 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003870 route_map_install_match (&route_match_ip_address_cmd);
3871 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003872 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003873 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3874 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003875 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003876 route_map_install_match (&route_match_aspath_cmd);
3877 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003878 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003879 route_map_install_match (&route_match_metric_cmd);
3880 route_map_install_match (&route_match_origin_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003881 route_map_install_match (&route_match_probability_cmd);
paul718e3742002-12-13 20:15:29 +00003882
3883 route_map_install_set (&route_set_ip_nexthop_cmd);
3884 route_map_install_set (&route_set_local_pref_cmd);
3885 route_map_install_set (&route_set_weight_cmd);
3886 route_map_install_set (&route_set_metric_cmd);
3887 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003888 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003889 route_map_install_set (&route_set_origin_cmd);
3890 route_map_install_set (&route_set_atomic_aggregate_cmd);
3891 route_map_install_set (&route_set_aggregator_as_cmd);
3892 route_map_install_set (&route_set_community_cmd);
3893 route_map_install_set (&route_set_community_delete_cmd);
3894 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3895 route_map_install_set (&route_set_originator_id_cmd);
3896 route_map_install_set (&route_set_ecommunity_rt_cmd);
3897 route_map_install_set (&route_set_ecommunity_soo_cmd);
3898
paulfee0f4c2004-09-13 05:12:46 +00003899 install_element (RMAP_NODE, &match_peer_cmd);
3900 install_element (RMAP_NODE, &match_peer_local_cmd);
3901 install_element (RMAP_NODE, &no_match_peer_cmd);
3902 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3903 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003904 install_element (RMAP_NODE, &match_ip_address_cmd);
3905 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3906 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3907 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3908 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3909 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003910 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3911 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3912 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003913 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3914 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3915 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3916 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3917 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3918 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003919 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3920 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3921 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003922
3923 install_element (RMAP_NODE, &match_aspath_cmd);
3924 install_element (RMAP_NODE, &no_match_aspath_cmd);
3925 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3926 install_element (RMAP_NODE, &match_metric_cmd);
3927 install_element (RMAP_NODE, &no_match_metric_cmd);
3928 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3929 install_element (RMAP_NODE, &match_community_cmd);
3930 install_element (RMAP_NODE, &match_community_exact_cmd);
3931 install_element (RMAP_NODE, &no_match_community_cmd);
3932 install_element (RMAP_NODE, &no_match_community_val_cmd);
3933 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003934 install_element (RMAP_NODE, &match_ecommunity_cmd);
3935 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
3936 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00003937 install_element (RMAP_NODE, &match_origin_cmd);
3938 install_element (RMAP_NODE, &no_match_origin_cmd);
3939 install_element (RMAP_NODE, &no_match_origin_val_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003940 install_element (RMAP_NODE, &match_probability_cmd);
3941 install_element (RMAP_NODE, &no_match_probability_cmd);
3942 install_element (RMAP_NODE, &no_match_probability_val_cmd);
paul718e3742002-12-13 20:15:29 +00003943
3944 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00003945 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003946 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
3947 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
3948 install_element (RMAP_NODE, &set_local_pref_cmd);
3949 install_element (RMAP_NODE, &no_set_local_pref_cmd);
3950 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
3951 install_element (RMAP_NODE, &set_weight_cmd);
3952 install_element (RMAP_NODE, &no_set_weight_cmd);
3953 install_element (RMAP_NODE, &no_set_weight_val_cmd);
3954 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00003955 install_element (RMAP_NODE, &set_metric_addsub_cmd);
Timo Teräsef757702015-04-29 09:43:04 +03003956 install_element (RMAP_NODE, &set_metric_rtt_cmd);
paul718e3742002-12-13 20:15:29 +00003957 install_element (RMAP_NODE, &no_set_metric_cmd);
3958 install_element (RMAP_NODE, &no_set_metric_val_cmd);
3959 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Timo Teräs85c854a2014-09-30 11:31:53 +03003960 install_element (RMAP_NODE, &set_aspath_prepend_lastas_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003961 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003962 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
3963 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003964 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
3965 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00003966 install_element (RMAP_NODE, &set_origin_cmd);
3967 install_element (RMAP_NODE, &no_set_origin_cmd);
3968 install_element (RMAP_NODE, &no_set_origin_val_cmd);
3969 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
3970 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
3971 install_element (RMAP_NODE, &set_aggregator_as_cmd);
3972 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
3973 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
3974 install_element (RMAP_NODE, &set_community_cmd);
3975 install_element (RMAP_NODE, &set_community_none_cmd);
3976 install_element (RMAP_NODE, &no_set_community_cmd);
3977 install_element (RMAP_NODE, &no_set_community_val_cmd);
3978 install_element (RMAP_NODE, &no_set_community_none_cmd);
3979 install_element (RMAP_NODE, &set_community_delete_cmd);
3980 install_element (RMAP_NODE, &no_set_community_delete_cmd);
3981 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
3982 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
3983 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
3984 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
3985 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
3986 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
3987 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
3988 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
3989 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
3990 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
3991 install_element (RMAP_NODE, &set_originator_id_cmd);
3992 install_element (RMAP_NODE, &no_set_originator_id_cmd);
3993 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
3994
paul718e3742002-12-13 20:15:29 +00003995 route_map_install_match (&route_match_ipv6_address_cmd);
3996 route_map_install_match (&route_match_ipv6_next_hop_cmd);
3997 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
3998 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
3999 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Dinesh G Duttad5233a2014-09-30 14:19:57 -07004000 route_map_install_set (&route_set_ipv6_nexthop_peer_cmd);
4001
paul718e3742002-12-13 20:15:29 +00004002 install_element (RMAP_NODE, &match_ipv6_address_cmd);
4003 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
4004 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
4005 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
4006 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
4007 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
4008 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
4009 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
4010 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
4011 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
4012 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
4013 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
Dinesh G Duttad5233a2014-09-30 14:19:57 -07004014 install_element (RMAP_NODE, &set_ipv6_nexthop_peer_cmd);
4015 install_element (RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd);
Paul Jakma41367172007-08-06 15:24:51 +00004016
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004017 /* AS-Pathlimit: functionality removed, commands kept for
4018 * compatibility.
4019 */
Paul Jakma41367172007-08-06 15:24:51 +00004020 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
4021 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
4022 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
4023 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
4024 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
4025 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00004026}