blob: a9b6b50255ee9556a81c41058e531fc12565a383 [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)
Dinesh Dutt5cf768a2015-11-09 20:21:53 -050075 local-preference : Done
paul718e3742002-12-13 20:15:29 +000076
77 set as-path prepend : Done
78 as-path tag : Not yet
79 automatic-tag : (This will not be implemented by bgpd)
80 community : Done
81 comm-list : Not yet
82 dampning : Not yet
83 default : (This will not be implemented by bgpd)
84 interface : (This will not be implemented by bgpd)
85 ip default : (This will not be implemented by bgpd)
86 ip next-hop : Done
87 ip precedence : (This will not be implemented by bgpd)
88 ip tos : (This will not be implemented by bgpd)
89 level : (This will not be implemented by bgpd)
90 local-preference : Done
91 metric : Done
92 metric-type : Not yet
93 origin : Done
94 tag : (This will not be implemented by bgpd)
95 weight : Done
96
Timo Teräs2aa640b2014-05-20 08:57:26 +030097o Local extensions
paul718e3742002-12-13 20:15:29 +000098
99 set ipv6 next-hop global: Done
100 set ipv6 next-hop local : Done
Denis Ovsienko841f7a52008-04-10 11:47:45 +0000101 set as-path exclude : Done
paul718e3742002-12-13 20:15:29 +0000102
103*/
David Lamparter6b0655a2014-06-04 06:53:35 +0200104
Timo Teräs38f22ab2015-04-29 09:43:02 +0300105 /* generic value manipulation to be shared in multiple rules */
106
107#define RMAP_VALUE_SET 0
108#define RMAP_VALUE_ADD 1
109#define RMAP_VALUE_SUB 2
110
111struct rmap_value
112{
113 u_int8_t action;
Timo Teräsef757702015-04-29 09:43:04 +0300114 u_int8_t variable;
Timo Teräs38f22ab2015-04-29 09:43:02 +0300115 u_int32_t value;
116};
117
118static int
119route_value_match (struct rmap_value *rv, u_int32_t value)
120{
Timo Teräsef757702015-04-29 09:43:04 +0300121 if (rv->variable == 0 && value == rv->value)
Timo Teräs38f22ab2015-04-29 09:43:02 +0300122 return RMAP_MATCH;
123
124 return RMAP_NOMATCH;
125}
126
127static u_int32_t
Timo Teräsef757702015-04-29 09:43:04 +0300128route_value_adjust (struct rmap_value *rv, u_int32_t current, struct peer *peer)
Timo Teräs38f22ab2015-04-29 09:43:02 +0300129{
Timo Teräsef757702015-04-29 09:43:04 +0300130 u_int32_t value;
131
132 switch (rv->variable)
133 {
134 case 1:
135 value = peer->rtt;
136 break;
137 default:
138 value = rv->value;
139 break;
140 }
Timo Teräs38f22ab2015-04-29 09:43:02 +0300141
142 switch (rv->action)
143 {
144 case RMAP_VALUE_ADD:
145 if (current > UINT32_MAX-value)
146 return UINT32_MAX;
147 return current + value;
148 case RMAP_VALUE_SUB:
149 if (current <= value)
150 return 0;
151 return current - value;
152 default:
153 return value;
154 }
155}
156
157static void *
158route_value_compile (const char *arg)
159{
Timo Teräsef757702015-04-29 09:43:04 +0300160 u_int8_t action = RMAP_VALUE_SET, var = 0;
161 unsigned long larg = 0;
Timo Teräs38f22ab2015-04-29 09:43:02 +0300162 char *endptr = NULL;
163 struct rmap_value *rv;
164
165 if (arg[0] == '+')
166 {
167 action = RMAP_VALUE_ADD;
168 arg++;
169 }
170 else if (arg[0] == '-')
171 {
172 action = RMAP_VALUE_SUB;
173 arg++;
174 }
175
Timo Teräsef757702015-04-29 09:43:04 +0300176 if (all_digit(arg))
177 {
178 errno = 0;
179 larg = strtoul (arg, &endptr, 10);
180 if (*arg == 0 || *endptr != 0 || errno || larg > UINT32_MAX)
181 return NULL;
182 }
183 else
184 {
185 if (strcmp(arg, "rtt") == 0)
186 var = 1;
187 else
188 return NULL;
189 }
Timo Teräs38f22ab2015-04-29 09:43:02 +0300190
191 rv = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_value));
192 if (!rv)
193 return NULL;
194
195 rv->action = action;
Timo Teräsef757702015-04-29 09:43:04 +0300196 rv->variable = var;
Timo Teräs38f22ab2015-04-29 09:43:02 +0300197 rv->value = larg;
198 return rv;
199}
200
201static void
202route_value_free (void *rule)
203{
204 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
205}
206
Timo Teräsb304dcb2014-05-20 09:04:49 +0300207 /* generic as path object to be shared in multiple rules */
208
209static void *
210route_aspath_compile (const char *arg)
211{
212 struct aspath *aspath;
213
214 aspath = aspath_str2aspath (arg);
215 if (! aspath)
216 return NULL;
217 return aspath;
218}
219
220static void
221route_aspath_free (void *rule)
222{
223 struct aspath *aspath = rule;
224 aspath_free (aspath);
225}
226
paulfee0f4c2004-09-13 05:12:46 +0000227 /* 'match peer (A.B.C.D|X:X::X:X)' */
228
229/* Compares the peer specified in the 'match peer' clause with the peer
230 received in bgp_info->peer. If it is the same, or if the peer structure
231 received is a peer_group containing it, returns RMAP_MATCH. */
paul94f2b392005-06-28 12:44:16 +0000232static route_map_result_t
paulfee0f4c2004-09-13 05:12:46 +0000233route_match_peer (void *rule, struct prefix *prefix, route_map_object_t type,
234 void *object)
235{
236 union sockunion *su;
David Lamparter6ed810d2015-04-21 10:13:07 +0200237 union sockunion su_def = { .sin = { .sin_family = AF_INET,
238 .sin_addr.s_addr = INADDR_ANY } };
paulfee0f4c2004-09-13 05:12:46 +0000239 struct peer_group *group;
240 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +0000241 struct listnode *node, *nnode;
paulfee0f4c2004-09-13 05:12:46 +0000242
243 if (type == RMAP_BGP)
244 {
245 su = rule;
246 peer = ((struct bgp_info *) object)->peer;
247
248 if ( ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT) &&
249 ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_EXPORT) )
250 return RMAP_NOMATCH;
251
252 /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
253 REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200254 if (sockunion_same (su, &su_def))
paulfee0f4c2004-09-13 05:12:46 +0000255 {
paul22db9de2005-05-19 01:50:11 +0000256 int ret;
paulfee0f4c2004-09-13 05:12:46 +0000257 if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
258 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE) ||
259 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
paul22db9de2005-05-19 01:50:11 +0000260 ret = RMAP_MATCH;
paulfee0f4c2004-09-13 05:12:46 +0000261 else
paul22db9de2005-05-19 01:50:11 +0000262 ret = RMAP_NOMATCH;
paul22db9de2005-05-19 01:50:11 +0000263 return ret;
paulfee0f4c2004-09-13 05:12:46 +0000264 }
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200265
paulfee0f4c2004-09-13 05:12:46 +0000266 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
267 {
268 if (sockunion_same (su, &peer->su))
269 return RMAP_MATCH;
270
271 return RMAP_NOMATCH;
272 }
273 else
274 {
275 group = peer->group;
paul1eb8ef22005-04-07 07:30:20 +0000276 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
paulfee0f4c2004-09-13 05:12:46 +0000277 {
278 if (sockunion_same (su, &peer->su))
279 return RMAP_MATCH;
paulfee0f4c2004-09-13 05:12:46 +0000280 }
Paul Jakma30a22312008-08-15 14:05:22 +0100281 return RMAP_NOMATCH;
paulfee0f4c2004-09-13 05:12:46 +0000282 }
283 }
284 return RMAP_NOMATCH;
285}
286
paul94f2b392005-06-28 12:44:16 +0000287static void *
paulfd79ac92004-10-13 05:06:08 +0000288route_match_peer_compile (const char *arg)
paulfee0f4c2004-09-13 05:12:46 +0000289{
290 union sockunion *su;
291 int ret;
292
293 su = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union sockunion));
294
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +0200295 ret = str2sockunion (strcmp(arg, "local") ? arg : "0.0.0.0", su);
paulfee0f4c2004-09-13 05:12:46 +0000296 if (ret < 0) {
297 XFREE (MTYPE_ROUTE_MAP_COMPILED, su);
298 return NULL;
299 }
300
301 return su;
302}
303
304/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000305static void
paulfee0f4c2004-09-13 05:12:46 +0000306route_match_peer_free (void *rule)
307{
308 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
309}
310
311/* Route map commands for ip address matching. */
312struct route_map_rule_cmd route_match_peer_cmd =
313{
314 "peer",
315 route_match_peer,
316 route_match_peer_compile,
317 route_match_peer_free
318};
319
paul718e3742002-12-13 20:15:29 +0000320/* `match ip address IP_ACCESS_LIST' */
321
322/* Match function should return 1 if match is success else return
323 zero. */
paul94f2b392005-06-28 12:44:16 +0000324static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000325route_match_ip_address (void *rule, struct prefix *prefix,
326 route_map_object_t type, void *object)
327{
328 struct access_list *alist;
329 /* struct prefix_ipv4 match; */
330
331 if (type == RMAP_BGP)
332 {
333 alist = access_list_lookup (AFI_IP, (char *) rule);
334 if (alist == NULL)
335 return RMAP_NOMATCH;
336
337 return (access_list_apply (alist, prefix) == FILTER_DENY ?
338 RMAP_NOMATCH : RMAP_MATCH);
339 }
340 return RMAP_NOMATCH;
341}
342
343/* Route map `ip address' match statement. `arg' should be
344 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000345static void *
paulfd79ac92004-10-13 05:06:08 +0000346route_match_ip_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000347{
348 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
349}
350
351/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000352static void
paul718e3742002-12-13 20:15:29 +0000353route_match_ip_address_free (void *rule)
354{
355 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
356}
357
358/* Route map commands for ip address matching. */
359struct route_map_rule_cmd route_match_ip_address_cmd =
360{
361 "ip address",
362 route_match_ip_address,
363 route_match_ip_address_compile,
364 route_match_ip_address_free
365};
David Lamparter6b0655a2014-06-04 06:53:35 +0200366
paul718e3742002-12-13 20:15:29 +0000367/* `match ip next-hop IP_ADDRESS' */
368
369/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000370static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000371route_match_ip_next_hop (void *rule, struct prefix *prefix,
372 route_map_object_t type, void *object)
373{
374 struct access_list *alist;
375 struct bgp_info *bgp_info;
376 struct prefix_ipv4 p;
377
378 if (type == RMAP_BGP)
379 {
380 bgp_info = object;
381 p.family = AF_INET;
382 p.prefix = bgp_info->attr->nexthop;
383 p.prefixlen = IPV4_MAX_BITLEN;
384
385 alist = access_list_lookup (AFI_IP, (char *) rule);
386 if (alist == NULL)
387 return RMAP_NOMATCH;
388
389 return (access_list_apply (alist, &p) == FILTER_DENY ?
390 RMAP_NOMATCH : RMAP_MATCH);
391 }
392 return RMAP_NOMATCH;
393}
394
395/* Route map `ip next-hop' match statement. `arg' is
396 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000397static void *
paulfd79ac92004-10-13 05:06:08 +0000398route_match_ip_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000399{
400 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
401}
402
403/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000404static void
paul718e3742002-12-13 20:15:29 +0000405route_match_ip_next_hop_free (void *rule)
406{
407 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
408}
409
410/* Route map commands for ip next-hop matching. */
411struct route_map_rule_cmd route_match_ip_next_hop_cmd =
412{
413 "ip next-hop",
414 route_match_ip_next_hop,
415 route_match_ip_next_hop_compile,
416 route_match_ip_next_hop_free
417};
David Lamparter6b0655a2014-06-04 06:53:35 +0200418
hassoc1643bb2005-02-02 16:43:17 +0000419/* `match ip route-source ACCESS-LIST' */
420
421/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000422static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000423route_match_ip_route_source (void *rule, struct prefix *prefix,
424 route_map_object_t type, void *object)
425{
426 struct access_list *alist;
427 struct bgp_info *bgp_info;
428 struct peer *peer;
429 struct prefix_ipv4 p;
430
431 if (type == RMAP_BGP)
432 {
433 bgp_info = object;
434 peer = bgp_info->peer;
435
436 if (! peer || sockunion_family (&peer->su) != AF_INET)
437 return RMAP_NOMATCH;
438
439 p.family = AF_INET;
440 p.prefix = peer->su.sin.sin_addr;
441 p.prefixlen = IPV4_MAX_BITLEN;
442
443 alist = access_list_lookup (AFI_IP, (char *) rule);
444 if (alist == NULL)
445 return RMAP_NOMATCH;
446
447 return (access_list_apply (alist, &p) == FILTER_DENY ?
448 RMAP_NOMATCH : RMAP_MATCH);
449 }
450 return RMAP_NOMATCH;
451}
452
453/* Route map `ip route-source' match statement. `arg' is
454 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000455static void *
hassoc1643bb2005-02-02 16:43:17 +0000456route_match_ip_route_source_compile (const char *arg)
457{
458 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
459}
460
461/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000462static void
hassoc1643bb2005-02-02 16:43:17 +0000463route_match_ip_route_source_free (void *rule)
464{
465 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
466}
467
468/* Route map commands for ip route-source matching. */
469struct route_map_rule_cmd route_match_ip_route_source_cmd =
470{
471 "ip route-source",
472 route_match_ip_route_source,
473 route_match_ip_route_source_compile,
474 route_match_ip_route_source_free
475};
David Lamparter6b0655a2014-06-04 06:53:35 +0200476
paul718e3742002-12-13 20:15:29 +0000477/* `match ip address prefix-list PREFIX_LIST' */
478
paul94f2b392005-06-28 12:44:16 +0000479static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000480route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
481 route_map_object_t type, void *object)
482{
483 struct prefix_list *plist;
484
485 if (type == RMAP_BGP)
486 {
487 plist = prefix_list_lookup (AFI_IP, (char *) rule);
488 if (plist == NULL)
489 return RMAP_NOMATCH;
490
491 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
492 RMAP_NOMATCH : RMAP_MATCH);
493 }
494 return RMAP_NOMATCH;
495}
496
paul94f2b392005-06-28 12:44:16 +0000497static void *
paulfd79ac92004-10-13 05:06:08 +0000498route_match_ip_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000499{
500 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
501}
502
paul94f2b392005-06-28 12:44:16 +0000503static void
paul718e3742002-12-13 20:15:29 +0000504route_match_ip_address_prefix_list_free (void *rule)
505{
506 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
507}
508
509struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
510{
511 "ip address prefix-list",
512 route_match_ip_address_prefix_list,
513 route_match_ip_address_prefix_list_compile,
514 route_match_ip_address_prefix_list_free
515};
David Lamparter6b0655a2014-06-04 06:53:35 +0200516
paul718e3742002-12-13 20:15:29 +0000517/* `match ip next-hop prefix-list PREFIX_LIST' */
518
paul94f2b392005-06-28 12:44:16 +0000519static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000520route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
521 route_map_object_t type, void *object)
522{
523 struct prefix_list *plist;
524 struct bgp_info *bgp_info;
525 struct prefix_ipv4 p;
526
527 if (type == RMAP_BGP)
528 {
529 bgp_info = object;
530 p.family = AF_INET;
531 p.prefix = bgp_info->attr->nexthop;
532 p.prefixlen = IPV4_MAX_BITLEN;
533
534 plist = prefix_list_lookup (AFI_IP, (char *) rule);
535 if (plist == NULL)
536 return RMAP_NOMATCH;
537
538 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
539 RMAP_NOMATCH : RMAP_MATCH);
540 }
541 return RMAP_NOMATCH;
542}
543
paul94f2b392005-06-28 12:44:16 +0000544static void *
paulfd79ac92004-10-13 05:06:08 +0000545route_match_ip_next_hop_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000546{
547 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
548}
549
paul94f2b392005-06-28 12:44:16 +0000550static void
paul718e3742002-12-13 20:15:29 +0000551route_match_ip_next_hop_prefix_list_free (void *rule)
552{
553 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
554}
555
556struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
557{
558 "ip next-hop prefix-list",
559 route_match_ip_next_hop_prefix_list,
560 route_match_ip_next_hop_prefix_list_compile,
561 route_match_ip_next_hop_prefix_list_free
562};
David Lamparter6b0655a2014-06-04 06:53:35 +0200563
hassoc1643bb2005-02-02 16:43:17 +0000564/* `match ip route-source prefix-list PREFIX_LIST' */
565
paul94f2b392005-06-28 12:44:16 +0000566static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000567route_match_ip_route_source_prefix_list (void *rule, struct prefix *prefix,
568 route_map_object_t type, void *object)
569{
570 struct prefix_list *plist;
571 struct bgp_info *bgp_info;
572 struct peer *peer;
573 struct prefix_ipv4 p;
574
575 if (type == RMAP_BGP)
576 {
577 bgp_info = object;
578 peer = bgp_info->peer;
579
580 if (! peer || sockunion_family (&peer->su) != AF_INET)
581 return RMAP_NOMATCH;
582
583 p.family = AF_INET;
584 p.prefix = peer->su.sin.sin_addr;
585 p.prefixlen = IPV4_MAX_BITLEN;
586
587 plist = prefix_list_lookup (AFI_IP, (char *) rule);
588 if (plist == NULL)
589 return RMAP_NOMATCH;
590
591 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
592 RMAP_NOMATCH : RMAP_MATCH);
593 }
594 return RMAP_NOMATCH;
595}
596
paul94f2b392005-06-28 12:44:16 +0000597static void *
hassoc1643bb2005-02-02 16:43:17 +0000598route_match_ip_route_source_prefix_list_compile (const char *arg)
599{
600 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
601}
602
paul94f2b392005-06-28 12:44:16 +0000603static void
hassoc1643bb2005-02-02 16:43:17 +0000604route_match_ip_route_source_prefix_list_free (void *rule)
605{
606 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
607}
608
609struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd =
610{
611 "ip route-source prefix-list",
612 route_match_ip_route_source_prefix_list,
613 route_match_ip_route_source_prefix_list_compile,
614 route_match_ip_route_source_prefix_list_free
615};
David Lamparter6b0655a2014-06-04 06:53:35 +0200616
Dinesh Dutt5cf768a2015-11-09 20:21:53 -0500617/* `match local-preference LOCAL-PREF' */
618
619/* Match function return 1 if match is success else return zero. */
620static route_map_result_t
621route_match_local_pref (void *rule, struct prefix *prefix,
622 route_map_object_t type, void *object)
623{
624 u_int32_t *local_pref;
625 struct bgp_info *bgp_info;
626
627 if (type == RMAP_BGP)
628 {
629 local_pref = rule;
630 bgp_info = object;
631
632 if (bgp_info->attr->local_pref == *local_pref)
633 return RMAP_MATCH;
634 else
635 return RMAP_NOMATCH;
636 }
637 return RMAP_NOMATCH;
638}
639
640/* Route map `match local-preference' match statement.
641 `arg' is local-pref value */
642static void *
643route_match_local_pref_compile (const char *arg)
644{
645 u_int32_t *local_pref;
646 char *endptr = NULL;
647 unsigned long tmpval;
648
649 /* Locpref value shoud be integer. */
650 if (! all_digit (arg))
651 return NULL;
652
653 errno = 0;
654 tmpval = strtoul (arg, &endptr, 10);
655 if (*endptr != '\0' || errno || tmpval > UINT32_MAX)
656 return NULL;
657
658 local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
659
660 if (!local_pref)
661 return local_pref;
662
663 *local_pref = tmpval;
664 return local_pref;
665}
666
667/* Free route map's compiled `match local-preference' value. */
668static void
669route_match_local_pref_free (void *rule)
670{
671 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
672}
673
674/* Route map commands for metric matching. */
675struct route_map_rule_cmd route_match_local_pref_cmd =
676{
677 "local-preference",
678 route_match_local_pref,
679 route_match_local_pref_compile,
680 route_match_local_pref_free
681};
682
paul718e3742002-12-13 20:15:29 +0000683/* `match metric METRIC' */
684
685/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000686static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000687route_match_metric (void *rule, struct prefix *prefix,
688 route_map_object_t type, void *object)
689{
Timo Teräs38f22ab2015-04-29 09:43:02 +0300690 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +0000691 struct bgp_info *bgp_info;
692
693 if (type == RMAP_BGP)
694 {
Timo Teräs38f22ab2015-04-29 09:43:02 +0300695 rv = rule;
paul718e3742002-12-13 20:15:29 +0000696 bgp_info = object;
Timo Teräs38f22ab2015-04-29 09:43:02 +0300697 return route_value_match(rv, bgp_info->attr->med);
paul718e3742002-12-13 20:15:29 +0000698 }
699 return RMAP_NOMATCH;
700}
701
paul718e3742002-12-13 20:15:29 +0000702/* Route map commands for metric matching. */
703struct route_map_rule_cmd route_match_metric_cmd =
704{
705 "metric",
706 route_match_metric,
Timo Teräs38f22ab2015-04-29 09:43:02 +0300707 route_value_compile,
708 route_value_free,
paul718e3742002-12-13 20:15:29 +0000709};
David Lamparter6b0655a2014-06-04 06:53:35 +0200710
paul718e3742002-12-13 20:15:29 +0000711/* `match as-path ASPATH' */
712
713/* Match function for as-path match. I assume given object is */
paul94f2b392005-06-28 12:44:16 +0000714static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000715route_match_aspath (void *rule, struct prefix *prefix,
716 route_map_object_t type, void *object)
717{
718
719 struct as_list *as_list;
720 struct bgp_info *bgp_info;
721
722 if (type == RMAP_BGP)
723 {
724 as_list = as_list_lookup ((char *) rule);
725 if (as_list == NULL)
726 return RMAP_NOMATCH;
727
728 bgp_info = object;
729
730 /* Perform match. */
731 return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
732 }
733 return RMAP_NOMATCH;
734}
735
736/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000737static void *
paulfd79ac92004-10-13 05:06:08 +0000738route_match_aspath_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000739{
740 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
741}
742
743/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000744static void
paul718e3742002-12-13 20:15:29 +0000745route_match_aspath_free (void *rule)
746{
747 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
748}
749
750/* Route map commands for aspath matching. */
751struct route_map_rule_cmd route_match_aspath_cmd =
752{
753 "as-path",
754 route_match_aspath,
755 route_match_aspath_compile,
756 route_match_aspath_free
757};
David Lamparter6b0655a2014-06-04 06:53:35 +0200758
paul718e3742002-12-13 20:15:29 +0000759/* `match community COMMUNIY' */
760struct rmap_community
761{
762 char *name;
763 int exact;
764};
765
766/* Match function for community match. */
paul94f2b392005-06-28 12:44:16 +0000767static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000768route_match_community (void *rule, struct prefix *prefix,
769 route_map_object_t type, void *object)
770{
771 struct community_list *list;
772 struct bgp_info *bgp_info;
773 struct rmap_community *rcom;
774
775 if (type == RMAP_BGP)
776 {
777 bgp_info = object;
778 rcom = rule;
779
hassofee6e4e2005-02-02 16:29:31 +0000780 list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +0000781 if (! list)
782 return RMAP_NOMATCH;
783
784 if (rcom->exact)
785 {
786 if (community_list_exact_match (bgp_info->attr->community, list))
787 return RMAP_MATCH;
788 }
789 else
790 {
791 if (community_list_match (bgp_info->attr->community, list))
792 return RMAP_MATCH;
793 }
794 }
795 return RMAP_NOMATCH;
796}
797
798/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000799static void *
paulfd79ac92004-10-13 05:06:08 +0000800route_match_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000801{
802 struct rmap_community *rcom;
803 int len;
804 char *p;
805
806 rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
807
808 p = strchr (arg, ' ');
809 if (p)
810 {
811 len = p - arg;
812 rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
813 memcpy (rcom->name, arg, len);
814 rcom->exact = 1;
815 }
816 else
817 {
818 rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
819 rcom->exact = 0;
820 }
821 return rcom;
822}
823
824/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000825static void
paul718e3742002-12-13 20:15:29 +0000826route_match_community_free (void *rule)
827{
828 struct rmap_community *rcom = rule;
829
830 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
831 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
832}
833
834/* Route map commands for community matching. */
835struct route_map_rule_cmd route_match_community_cmd =
836{
837 "community",
838 route_match_community,
839 route_match_community_compile,
840 route_match_community_free
841};
David Lamparter6b0655a2014-06-04 06:53:35 +0200842
paul73ffb252003-04-19 15:49:49 +0000843/* Match function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000844static route_map_result_t
paul73ffb252003-04-19 15:49:49 +0000845route_match_ecommunity (void *rule, struct prefix *prefix,
846 route_map_object_t type, void *object)
847{
848 struct community_list *list;
849 struct bgp_info *bgp_info;
850
851 if (type == RMAP_BGP)
852 {
853 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +0000854
855 if (!bgp_info->attr->extra)
856 return RMAP_NOMATCH;
857
paul73ffb252003-04-19 15:49:49 +0000858 list = community_list_lookup (bgp_clist, (char *) rule,
hassofee6e4e2005-02-02 16:29:31 +0000859 EXTCOMMUNITY_LIST_MASTER);
paul73ffb252003-04-19 15:49:49 +0000860 if (! list)
861 return RMAP_NOMATCH;
862
Paul Jakmafb982c22007-05-04 20:15:47 +0000863 if (ecommunity_list_match (bgp_info->attr->extra->ecommunity, list))
paul73ffb252003-04-19 15:49:49 +0000864 return RMAP_MATCH;
865 }
866 return RMAP_NOMATCH;
867}
868
869/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000870static void *
paulfd79ac92004-10-13 05:06:08 +0000871route_match_ecommunity_compile (const char *arg)
paul73ffb252003-04-19 15:49:49 +0000872{
873 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
874}
875
876/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000877static void
paul73ffb252003-04-19 15:49:49 +0000878route_match_ecommunity_free (void *rule)
879{
880 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
881}
882
883/* Route map commands for community matching. */
884struct route_map_rule_cmd route_match_ecommunity_cmd =
885{
886 "extcommunity",
887 route_match_ecommunity,
888 route_match_ecommunity_compile,
889 route_match_ecommunity_free
890};
David Lamparter6b0655a2014-06-04 06:53:35 +0200891
paul718e3742002-12-13 20:15:29 +0000892/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
893 and `address-family vpnv4'. */
David Lamparter6b0655a2014-06-04 06:53:35 +0200894
paul718e3742002-12-13 20:15:29 +0000895/* `match origin' */
paul94f2b392005-06-28 12:44:16 +0000896static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000897route_match_origin (void *rule, struct prefix *prefix,
898 route_map_object_t type, void *object)
899{
900 u_char *origin;
901 struct bgp_info *bgp_info;
902
903 if (type == RMAP_BGP)
904 {
905 origin = rule;
906 bgp_info = object;
907
908 if (bgp_info->attr->origin == *origin)
909 return RMAP_MATCH;
910 }
911
912 return RMAP_NOMATCH;
913}
914
paul94f2b392005-06-28 12:44:16 +0000915static void *
paulfd79ac92004-10-13 05:06:08 +0000916route_match_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000917{
918 u_char *origin;
919
920 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
921
922 if (strcmp (arg, "igp") == 0)
923 *origin = 0;
924 else if (strcmp (arg, "egp") == 0)
925 *origin = 1;
926 else
927 *origin = 2;
928
929 return origin;
930}
931
932/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000933static void
paul718e3742002-12-13 20:15:29 +0000934route_match_origin_free (void *rule)
935{
936 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
937}
938
939/* Route map commands for origin matching. */
940struct route_map_rule_cmd route_match_origin_cmd =
941{
942 "origin",
943 route_match_origin,
944 route_match_origin_compile,
945 route_match_origin_free
946};
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400947
948/* match probability { */
949
950static route_map_result_t
951route_match_probability (void *rule, struct prefix *prefix,
952 route_map_object_t type, void *object)
953{
Donald Sharpf31bab42015-06-19 19:26:19 -0400954 long r = random();
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400955
David Lamparter8c9cd852015-04-19 14:40:02 +0200956 switch (*(long *) rule)
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400957 {
958 case 0: break;
959 case RAND_MAX: return RMAP_MATCH;
960 default:
David Lamparter8c9cd852015-04-19 14:40:02 +0200961 if (r < *(long *) rule)
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400962 {
963 return RMAP_MATCH;
964 }
965 }
966
967 return RMAP_NOMATCH;
968}
969
970static void *
971route_match_probability_compile (const char *arg)
972{
David Lamparter8c9cd852015-04-19 14:40:02 +0200973 long *lobule;
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400974 unsigned perc;
975
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400976 perc = atoi (arg);
David Lamparter8c9cd852015-04-19 14:40:02 +0200977 lobule = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (long));
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400978
979 switch (perc)
980 {
981 case 0: *lobule = 0; break;
982 case 100: *lobule = RAND_MAX; break;
983 default: *lobule = RAND_MAX / 100 * perc;
984 }
985
986 return lobule;
987}
988
989static void
990route_match_probability_free (void *rule)
991{
992 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
993}
994
995struct route_map_rule_cmd route_match_probability_cmd =
996{
997 "probability",
998 route_match_probability,
999 route_match_probability_compile,
1000 route_match_probability_free
1001};
1002
1003/* } */
1004
paul718e3742002-12-13 20:15:29 +00001005/* `set ip next-hop IP_ADDRESS' */
1006
1007/* Set nexthop to object. ojbect must be pointer to struct attr. */
paulac41b2a2003-08-12 05:32:27 +00001008struct rmap_ip_nexthop_set
1009{
1010 struct in_addr *address;
1011 int peer_address;
1012};
1013
paul94f2b392005-06-28 12:44:16 +00001014static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001015route_set_ip_nexthop (void *rule, struct prefix *prefix,
1016 route_map_object_t type, void *object)
1017{
paulac41b2a2003-08-12 05:32:27 +00001018 struct rmap_ip_nexthop_set *rins = rule;
paul718e3742002-12-13 20:15:29 +00001019 struct bgp_info *bgp_info;
paulac41b2a2003-08-12 05:32:27 +00001020 struct peer *peer;
paul718e3742002-12-13 20:15:29 +00001021
1022 if (type == RMAP_BGP)
1023 {
paul718e3742002-12-13 20:15:29 +00001024 bgp_info = object;
paulac41b2a2003-08-12 05:32:27 +00001025 peer = bgp_info->peer;
1026
1027 if (rins->peer_address)
1028 {
paulfee0f4c2004-09-13 05:12:46 +00001029 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
1030 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
paulac41b2a2003-08-12 05:32:27 +00001031 && peer->su_remote
1032 && sockunion_family (peer->su_remote) == AF_INET)
1033 {
Jorge Boncompte [DTI2]0c5ed3e2012-04-10 16:57:22 +02001034 bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote);
paulac41b2a2003-08-12 05:32:27 +00001035 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
1036 }
1037 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
1038 && peer->su_local
1039 && sockunion_family (peer->su_local) == AF_INET)
1040 {
Jorge Boncompte [DTI2]0c5ed3e2012-04-10 16:57:22 +02001041 bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_local);
paulac41b2a2003-08-12 05:32:27 +00001042 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
1043 }
1044 }
1045 else
1046 {
1047 /* Set next hop value. */
1048 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
1049 bgp_info->attr->nexthop = *rins->address;
1050 }
paul718e3742002-12-13 20:15:29 +00001051 }
1052
1053 return RMAP_OKAY;
1054}
1055
1056/* Route map `ip nexthop' compile function. Given string is converted
1057 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001058static void *
paulfd79ac92004-10-13 05:06:08 +00001059route_set_ip_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001060{
paulac41b2a2003-08-12 05:32:27 +00001061 struct rmap_ip_nexthop_set *rins;
1062 struct in_addr *address = NULL;
1063 int peer_address = 0;
paul718e3742002-12-13 20:15:29 +00001064 int ret;
paul718e3742002-12-13 20:15:29 +00001065
paulac41b2a2003-08-12 05:32:27 +00001066 if (strcmp (arg, "peer-address") == 0)
1067 peer_address = 1;
1068 else
paul718e3742002-12-13 20:15:29 +00001069 {
paulac41b2a2003-08-12 05:32:27 +00001070 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
1071 ret = inet_aton (arg, address);
1072
1073 if (ret == 0)
1074 {
1075 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1076 return NULL;
1077 }
paul718e3742002-12-13 20:15:29 +00001078 }
1079
Stephen Hemminger393deb92008-08-18 14:13:29 -07001080 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
paulac41b2a2003-08-12 05:32:27 +00001081
1082 rins->address = address;
1083 rins->peer_address = peer_address;
1084
1085 return rins;
paul718e3742002-12-13 20:15:29 +00001086}
1087
1088/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00001089static void
paul718e3742002-12-13 20:15:29 +00001090route_set_ip_nexthop_free (void *rule)
1091{
paulac41b2a2003-08-12 05:32:27 +00001092 struct rmap_ip_nexthop_set *rins = rule;
1093
1094 if (rins->address)
1095 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
1096
1097 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +00001098}
1099
1100/* Route map commands for ip nexthop set. */
1101struct route_map_rule_cmd route_set_ip_nexthop_cmd =
1102{
1103 "ip next-hop",
1104 route_set_ip_nexthop,
1105 route_set_ip_nexthop_compile,
1106 route_set_ip_nexthop_free
1107};
David Lamparter6b0655a2014-06-04 06:53:35 +02001108
paul718e3742002-12-13 20:15:29 +00001109/* `set local-preference LOCAL_PREF' */
1110
1111/* Set local preference. */
paul94f2b392005-06-28 12:44:16 +00001112static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001113route_set_local_pref (void *rule, struct prefix *prefix,
1114 route_map_object_t type, void *object)
1115{
Timo Teräs38f22ab2015-04-29 09:43:02 +03001116 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +00001117 struct bgp_info *bgp_info;
Timo Teräs38f22ab2015-04-29 09:43:02 +03001118 u_int32_t locpref = 0;
paul718e3742002-12-13 20:15:29 +00001119
1120 if (type == RMAP_BGP)
1121 {
1122 /* Fetch routemap's rule information. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001123 rv = rule;
paul718e3742002-12-13 20:15:29 +00001124 bgp_info = object;
1125
1126 /* Set local preference value. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001127 if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
1128 locpref = bgp_info->attr->local_pref;
1129
paul718e3742002-12-13 20:15:29 +00001130 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
Timo Teräsef757702015-04-29 09:43:04 +03001131 bgp_info->attr->local_pref = route_value_adjust(rv, locpref, bgp_info->peer);
paul718e3742002-12-13 20:15:29 +00001132 }
1133
1134 return RMAP_OKAY;
1135}
1136
paul718e3742002-12-13 20:15:29 +00001137/* Set local preference rule structure. */
1138struct route_map_rule_cmd route_set_local_pref_cmd =
1139{
1140 "local-preference",
1141 route_set_local_pref,
Timo Teräs38f22ab2015-04-29 09:43:02 +03001142 route_value_compile,
1143 route_value_free,
paul718e3742002-12-13 20:15:29 +00001144};
David Lamparter6b0655a2014-06-04 06:53:35 +02001145
paul718e3742002-12-13 20:15:29 +00001146/* `set weight WEIGHT' */
1147
1148/* Set weight. */
paul94f2b392005-06-28 12:44:16 +00001149static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001150route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
1151 void *object)
1152{
Timo Teräs38f22ab2015-04-29 09:43:02 +03001153 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +00001154 struct bgp_info *bgp_info;
Timo Teräs38f22ab2015-04-29 09:43:02 +03001155 u_int32_t weight;
paul718e3742002-12-13 20:15:29 +00001156
1157 if (type == RMAP_BGP)
1158 {
1159 /* Fetch routemap's rule information. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001160 rv = rule;
paul718e3742002-12-13 20:15:29 +00001161 bgp_info = object;
1162
1163 /* Set weight value. */
Timo Teräsef757702015-04-29 09:43:04 +03001164 weight = route_value_adjust(rv, 0, bgp_info->peer);
Timo Teräs38f22ab2015-04-29 09:43:02 +03001165 if (weight)
1166 (bgp_attr_extra_get (bgp_info->attr))->weight = weight;
Paul Jakmafb982c22007-05-04 20:15:47 +00001167 else if (bgp_info->attr->extra)
1168 bgp_info->attr->extra->weight = 0;
paul718e3742002-12-13 20:15:29 +00001169 }
1170
1171 return RMAP_OKAY;
1172}
1173
paul718e3742002-12-13 20:15:29 +00001174/* Set local preference rule structure. */
1175struct route_map_rule_cmd route_set_weight_cmd =
1176{
1177 "weight",
1178 route_set_weight,
Timo Teräs38f22ab2015-04-29 09:43:02 +03001179 route_value_compile,
1180 route_value_free,
paul718e3742002-12-13 20:15:29 +00001181};
David Lamparter6b0655a2014-06-04 06:53:35 +02001182
paul718e3742002-12-13 20:15:29 +00001183/* `set metric METRIC' */
1184
1185/* Set metric to attribute. */
paul94f2b392005-06-28 12:44:16 +00001186static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001187route_set_metric (void *rule, struct prefix *prefix,
1188 route_map_object_t type, void *object)
1189{
Timo Teräs38f22ab2015-04-29 09:43:02 +03001190 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +00001191 struct bgp_info *bgp_info;
Timo Teräs38f22ab2015-04-29 09:43:02 +03001192 u_int32_t med = 0;
paul718e3742002-12-13 20:15:29 +00001193
1194 if (type == RMAP_BGP)
1195 {
1196 /* Fetch routemap's rule information. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001197 rv = rule;
paul718e3742002-12-13 20:15:29 +00001198 bgp_info = object;
1199
Timo Teräs38f22ab2015-04-29 09:43:02 +03001200 if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
1201 med = bgp_info->attr->med;
1202
Timo Teräsef757702015-04-29 09:43:04 +03001203 bgp_info->attr->med = route_value_adjust(rv, med, bgp_info->peer);
paul718e3742002-12-13 20:15:29 +00001204 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
paul718e3742002-12-13 20:15:29 +00001205 }
1206 return RMAP_OKAY;
1207}
1208
paul718e3742002-12-13 20:15:29 +00001209/* Set metric rule structure. */
1210struct route_map_rule_cmd route_set_metric_cmd =
1211{
1212 "metric",
1213 route_set_metric,
Timo Teräs38f22ab2015-04-29 09:43:02 +03001214 route_value_compile,
1215 route_value_free,
paul718e3742002-12-13 20:15:29 +00001216};
David Lamparter6b0655a2014-06-04 06:53:35 +02001217
paul718e3742002-12-13 20:15:29 +00001218/* `set as-path prepend ASPATH' */
1219
1220/* For AS path prepend mechanism. */
paul94f2b392005-06-28 12:44:16 +00001221static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001222route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1223{
1224 struct aspath *aspath;
1225 struct aspath *new;
1226 struct bgp_info *binfo;
1227
1228 if (type == RMAP_BGP)
1229 {
paul718e3742002-12-13 20:15:29 +00001230 binfo = object;
1231
1232 if (binfo->attr->aspath->refcnt)
1233 new = aspath_dup (binfo->attr->aspath);
1234 else
1235 new = binfo->attr->aspath;
1236
Timo Teräs85c854a2014-09-30 11:31:53 +03001237 if ((uintptr_t)rule > 10)
1238 {
1239 aspath = rule;
1240 aspath_prepend (aspath, new);
1241 }
1242 else
1243 {
1244 as_t as = aspath_leftmost(new);
1245 if (!as) as = binfo->peer->as;
1246 new = aspath_add_seq_n (new, as, (uintptr_t) rule);
1247 }
1248
paul718e3742002-12-13 20:15:29 +00001249 binfo->attr->aspath = new;
1250 }
1251
1252 return RMAP_OKAY;
1253}
1254
Timo Teräs85c854a2014-09-30 11:31:53 +03001255static void *
1256route_set_aspath_prepend_compile (const char *arg)
1257{
1258 unsigned int num;
1259
1260 if (sscanf(arg, "last-as %u", &num) == 1 && num > 0 && num < 10)
1261 return (void*)(uintptr_t)num;
1262
1263 return route_aspath_compile(arg);
1264}
1265
1266static void
1267route_set_aspath_prepend_free (void *rule)
1268{
1269 if ((uintptr_t)rule > 10)
1270 route_aspath_free(rule);
1271}
1272
1273
Timo Teräs2aa640b2014-05-20 08:57:26 +03001274/* Set as-path prepend rule structure. */
paul718e3742002-12-13 20:15:29 +00001275struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1276{
1277 "as-path prepend",
1278 route_set_aspath_prepend,
Timo Teräs85c854a2014-09-30 11:31:53 +03001279 route_set_aspath_prepend_compile,
1280 route_set_aspath_prepend_free,
paul718e3742002-12-13 20:15:29 +00001281};
David Lamparter6b0655a2014-06-04 06:53:35 +02001282
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001283/* `set as-path exclude ASn' */
1284
1285/* For ASN exclude mechanism.
1286 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1287 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1288 */
1289static route_map_result_t
1290route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
1291{
1292 struct aspath * new_path, * exclude_path;
1293 struct bgp_info *binfo;
1294
1295 if (type == RMAP_BGP)
1296 {
1297 exclude_path = rule;
1298 binfo = object;
1299 if (binfo->attr->aspath->refcnt)
1300 new_path = aspath_dup (binfo->attr->aspath);
1301 else
1302 new_path = binfo->attr->aspath;
1303 binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
1304 }
1305 return RMAP_OKAY;
1306}
1307
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001308/* Set ASn exlude rule structure. */
1309struct route_map_rule_cmd route_set_aspath_exclude_cmd =
1310{
1311 "as-path exclude",
1312 route_set_aspath_exclude,
Timo Teräsb304dcb2014-05-20 09:04:49 +03001313 route_aspath_compile,
1314 route_aspath_free,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001315};
David Lamparter6b0655a2014-06-04 06:53:35 +02001316
paul718e3742002-12-13 20:15:29 +00001317/* `set community COMMUNITY' */
1318struct rmap_com_set
1319{
1320 struct community *com;
1321 int additive;
1322 int none;
1323};
1324
1325/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001326static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001327route_set_community (void *rule, struct prefix *prefix,
1328 route_map_object_t type, void *object)
1329{
1330 struct rmap_com_set *rcs;
1331 struct bgp_info *binfo;
1332 struct attr *attr;
1333 struct community *new = NULL;
1334 struct community *old;
1335 struct community *merge;
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001336
paul718e3742002-12-13 20:15:29 +00001337 if (type == RMAP_BGP)
1338 {
1339 rcs = rule;
1340 binfo = object;
1341 attr = binfo->attr;
1342 old = attr->community;
1343
1344 /* "none" case. */
1345 if (rcs->none)
1346 {
1347 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1348 attr->community = NULL;
Christian Frankeb06b35f2012-12-07 14:26:09 +00001349 /* See the longer comment down below. */
1350 if (old && old->refcnt == 0)
1351 community_free(old);
paul718e3742002-12-13 20:15:29 +00001352 return RMAP_OKAY;
1353 }
1354
1355 /* "additive" case. */
1356 if (rcs->additive && old)
1357 {
1358 merge = community_merge (community_dup (old), rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001359
1360 /* HACK: if the old community is not intern'd,
1361 * we should free it here, or all reference to it may be lost.
1362 * Really need to cleanup attribute caching sometime.
1363 */
1364 if (old->refcnt == 0)
1365 community_free (old);
paul718e3742002-12-13 20:15:29 +00001366 new = community_uniq_sort (merge);
1367 community_free (merge);
1368 }
1369 else
1370 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001371
1372 /* will be interned by caller if required */
Paul Jakma4a2035f2011-04-01 15:58:27 +01001373 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001374
paul718e3742002-12-13 20:15:29 +00001375 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1376 }
1377
1378 return RMAP_OKAY;
1379}
1380
1381/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001382static void *
paulfd79ac92004-10-13 05:06:08 +00001383route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001384{
1385 struct rmap_com_set *rcs;
1386 struct community *com = NULL;
1387 char *sp;
1388 int additive = 0;
1389 int none = 0;
1390
1391 if (strcmp (arg, "none") == 0)
1392 none = 1;
1393 else
1394 {
1395 sp = strstr (arg, "additive");
1396
1397 if (sp && sp > arg)
1398 {
1399 /* "additive" keyworkd is included. */
1400 additive = 1;
1401 *(sp - 1) = '\0';
1402 }
1403
1404 com = community_str2com (arg);
1405
1406 if (additive)
1407 *(sp - 1) = ' ';
1408
1409 if (! com)
1410 return NULL;
1411 }
1412
Stephen Hemminger393deb92008-08-18 14:13:29 -07001413 rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
Paul Jakma4a2035f2011-04-01 15:58:27 +01001414 rcs->com = com;
paul718e3742002-12-13 20:15:29 +00001415 rcs->additive = additive;
1416 rcs->none = none;
1417
1418 return rcs;
1419}
1420
1421/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001422static void
paul718e3742002-12-13 20:15:29 +00001423route_set_community_free (void *rule)
1424{
1425 struct rmap_com_set *rcs = rule;
1426
1427 if (rcs->com)
1428 community_free (rcs->com);
1429 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1430}
1431
1432/* Set community rule structure. */
1433struct route_map_rule_cmd route_set_community_cmd =
1434{
1435 "community",
1436 route_set_community,
1437 route_set_community_compile,
1438 route_set_community_free,
1439};
David Lamparter6b0655a2014-06-04 06:53:35 +02001440
hassofee6e4e2005-02-02 16:29:31 +00001441/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001442
1443/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001444static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001445route_set_community_delete (void *rule, struct prefix *prefix,
1446 route_map_object_t type, void *object)
1447{
1448 struct community_list *list;
1449 struct community *merge;
1450 struct community *new;
1451 struct community *old;
1452 struct bgp_info *binfo;
1453
1454 if (type == RMAP_BGP)
1455 {
1456 if (! rule)
1457 return RMAP_OKAY;
1458
1459 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001460 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001461 old = binfo->attr->community;
1462
1463 if (list && old)
1464 {
1465 merge = community_list_match_delete (community_dup (old), list);
1466 new = community_uniq_sort (merge);
1467 community_free (merge);
1468
Michael Lambert604a9b42010-09-13 11:48:11 -04001469 /* HACK: if the old community is not intern'd,
1470 * we should free it here, or all reference to it may be lost.
1471 * Really need to cleanup attribute caching sometime.
1472 */
1473 if (old->refcnt == 0)
1474 community_free (old);
1475
paul718e3742002-12-13 20:15:29 +00001476 if (new->size == 0)
1477 {
1478 binfo->attr->community = NULL;
1479 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1480 community_free (new);
1481 }
1482 else
1483 {
Paul Jakma4a2035f2011-04-01 15:58:27 +01001484 binfo->attr->community = new;
paul718e3742002-12-13 20:15:29 +00001485 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1486 }
1487 }
1488 }
1489
1490 return RMAP_OKAY;
1491}
1492
1493/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001494static void *
paulfd79ac92004-10-13 05:06:08 +00001495route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001496{
1497 char *p;
1498 char *str;
1499 int len;
1500
1501 p = strchr (arg, ' ');
1502 if (p)
1503 {
1504 len = p - arg;
1505 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1506 memcpy (str, arg, len);
1507 }
1508 else
1509 str = NULL;
1510
1511 return str;
1512}
1513
1514/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001515static void
paul718e3742002-12-13 20:15:29 +00001516route_set_community_delete_free (void *rule)
1517{
1518 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1519}
1520
1521/* Set community rule structure. */
1522struct route_map_rule_cmd route_set_community_delete_cmd =
1523{
1524 "comm-list",
1525 route_set_community_delete,
1526 route_set_community_delete_compile,
1527 route_set_community_delete_free,
1528};
David Lamparter6b0655a2014-06-04 06:53:35 +02001529
paul718e3742002-12-13 20:15:29 +00001530/* `set extcommunity rt COMMUNITY' */
1531
David Lamparter73d78ea2014-06-04 00:58:47 +02001532/* For community set mechanism. Used by _rt and _soo. */
paul94f2b392005-06-28 12:44:16 +00001533static route_map_result_t
David Lamparter73d78ea2014-06-04 00:58:47 +02001534route_set_ecommunity (void *rule, struct prefix *prefix,
1535 route_map_object_t type, void *object)
paul718e3742002-12-13 20:15:29 +00001536{
1537 struct ecommunity *ecom;
1538 struct ecommunity *new_ecom;
1539 struct ecommunity *old_ecom;
1540 struct bgp_info *bgp_info;
1541
1542 if (type == RMAP_BGP)
1543 {
1544 ecom = rule;
1545 bgp_info = object;
1546
1547 if (! ecom)
1548 return RMAP_OKAY;
1549
1550 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001551 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001552
1553 if (old_ecom)
David Lamparter27bf90a2014-06-04 00:59:01 +02001554 {
1555 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1556
1557 /* old_ecom->refcnt = 1 => owned elsewhere, e.g. bgp_update_receive()
1558 * ->refcnt = 0 => set by a previous route-map statement */
1559 if (!old_ecom->refcnt)
1560 ecommunity_free (&old_ecom);
1561 }
paul718e3742002-12-13 20:15:29 +00001562 else
1563 new_ecom = ecommunity_dup (ecom);
1564
David Lamparter27bf90a2014-06-04 00:59:01 +02001565 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
1566 bgp_info->attr->extra->ecommunity = new_ecom;
hasso70601e02005-05-27 03:26:57 +00001567
paul718e3742002-12-13 20:15:29 +00001568 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1569 }
1570 return RMAP_OKAY;
1571}
1572
1573/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001574static void *
paulfd79ac92004-10-13 05:06:08 +00001575route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001576{
1577 struct ecommunity *ecom;
1578
1579 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1580 if (! ecom)
1581 return NULL;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001582 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001583}
1584
David Lamparter73d78ea2014-06-04 00:58:47 +02001585/* Free function for set community. Used by _rt and _soo */
paul94f2b392005-06-28 12:44:16 +00001586static void
David Lamparter73d78ea2014-06-04 00:58:47 +02001587route_set_ecommunity_free (void *rule)
paul718e3742002-12-13 20:15:29 +00001588{
1589 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001590 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001591}
1592
1593/* Set community rule structure. */
1594struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1595{
1596 "extcommunity rt",
David Lamparter73d78ea2014-06-04 00:58:47 +02001597 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001598 route_set_ecommunity_rt_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001599 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001600};
1601
1602/* `set extcommunity soo COMMUNITY' */
1603
paul718e3742002-12-13 20:15:29 +00001604/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001605static void *
paulfd79ac92004-10-13 05:06:08 +00001606route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001607{
1608 struct ecommunity *ecom;
1609
1610 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1611 if (! ecom)
1612 return NULL;
1613
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001614 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001615}
1616
paul718e3742002-12-13 20:15:29 +00001617/* Set community rule structure. */
1618struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1619{
1620 "extcommunity soo",
David Lamparter73d78ea2014-06-04 00:58:47 +02001621 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001622 route_set_ecommunity_soo_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001623 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001624};
David Lamparter6b0655a2014-06-04 06:53:35 +02001625
paul718e3742002-12-13 20:15:29 +00001626/* `set origin ORIGIN' */
1627
1628/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001629static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001630route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1631{
1632 u_char *origin;
1633 struct bgp_info *bgp_info;
1634
1635 if (type == RMAP_BGP)
1636 {
1637 origin = rule;
1638 bgp_info = object;
1639
1640 bgp_info->attr->origin = *origin;
1641 }
1642
1643 return RMAP_OKAY;
1644}
1645
1646/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001647static void *
paulfd79ac92004-10-13 05:06:08 +00001648route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001649{
1650 u_char *origin;
1651
1652 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1653
1654 if (strcmp (arg, "igp") == 0)
1655 *origin = 0;
1656 else if (strcmp (arg, "egp") == 0)
1657 *origin = 1;
1658 else
1659 *origin = 2;
1660
1661 return origin;
1662}
1663
1664/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001665static void
paul718e3742002-12-13 20:15:29 +00001666route_set_origin_free (void *rule)
1667{
1668 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1669}
1670
Timo Teräs2aa640b2014-05-20 08:57:26 +03001671/* Set origin rule structure. */
paul718e3742002-12-13 20:15:29 +00001672struct route_map_rule_cmd route_set_origin_cmd =
1673{
1674 "origin",
1675 route_set_origin,
1676 route_set_origin_compile,
1677 route_set_origin_free,
1678};
David Lamparter6b0655a2014-06-04 06:53:35 +02001679
paul718e3742002-12-13 20:15:29 +00001680/* `set atomic-aggregate' */
1681
1682/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001683static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001684route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1685 route_map_object_t type, void *object)
1686{
1687 struct bgp_info *bgp_info;
1688
1689 if (type == RMAP_BGP)
1690 {
1691 bgp_info = object;
1692 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1693 }
1694
1695 return RMAP_OKAY;
1696}
1697
1698/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001699static void *
paulfd79ac92004-10-13 05:06:08 +00001700route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001701{
1702 return (void *)1;
1703}
1704
1705/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001706static void
paul718e3742002-12-13 20:15:29 +00001707route_set_atomic_aggregate_free (void *rule)
1708{
1709 return;
1710}
1711
1712/* Set atomic aggregate rule structure. */
1713struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1714{
1715 "atomic-aggregate",
1716 route_set_atomic_aggregate,
1717 route_set_atomic_aggregate_compile,
1718 route_set_atomic_aggregate_free,
1719};
David Lamparter6b0655a2014-06-04 06:53:35 +02001720
paul718e3742002-12-13 20:15:29 +00001721/* `set aggregator as AS A.B.C.D' */
1722struct aggregator
1723{
1724 as_t as;
1725 struct in_addr address;
1726};
1727
paul94f2b392005-06-28 12:44:16 +00001728static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001729route_set_aggregator_as (void *rule, struct prefix *prefix,
1730 route_map_object_t type, void *object)
1731{
1732 struct bgp_info *bgp_info;
1733 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001734 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001735
1736 if (type == RMAP_BGP)
1737 {
1738 bgp_info = object;
1739 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001740 ae = bgp_attr_extra_get (bgp_info->attr);
1741
1742 ae->aggregator_as = aggregator->as;
1743 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001744 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1745 }
1746
1747 return RMAP_OKAY;
1748}
1749
paul94f2b392005-06-28 12:44:16 +00001750static void *
paulfd79ac92004-10-13 05:06:08 +00001751route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001752{
1753 struct aggregator *aggregator;
1754 char as[10];
1755 char address[20];
1756
Stephen Hemminger393deb92008-08-18 14:13:29 -07001757 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
paul718e3742002-12-13 20:15:29 +00001758 sscanf (arg, "%s %s", as, address);
1759
1760 aggregator->as = strtoul (as, NULL, 10);
1761 inet_aton (address, &aggregator->address);
1762
1763 return aggregator;
1764}
1765
paul94f2b392005-06-28 12:44:16 +00001766static void
paul718e3742002-12-13 20:15:29 +00001767route_set_aggregator_as_free (void *rule)
1768{
1769 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1770}
1771
1772struct route_map_rule_cmd route_set_aggregator_as_cmd =
1773{
1774 "aggregator as",
1775 route_set_aggregator_as,
1776 route_set_aggregator_as_compile,
1777 route_set_aggregator_as_free,
1778};
David Lamparter6b0655a2014-06-04 06:53:35 +02001779
paul718e3742002-12-13 20:15:29 +00001780/* `match ipv6 address IP_ACCESS_LIST' */
1781
paul94f2b392005-06-28 12:44:16 +00001782static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001783route_match_ipv6_address (void *rule, struct prefix *prefix,
1784 route_map_object_t type, void *object)
1785{
1786 struct access_list *alist;
1787
1788 if (type == RMAP_BGP)
1789 {
1790 alist = access_list_lookup (AFI_IP6, (char *) rule);
1791 if (alist == NULL)
1792 return RMAP_NOMATCH;
1793
1794 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1795 RMAP_NOMATCH : RMAP_MATCH);
1796 }
1797 return RMAP_NOMATCH;
1798}
1799
paul94f2b392005-06-28 12:44:16 +00001800static void *
paulfd79ac92004-10-13 05:06:08 +00001801route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001802{
1803 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1804}
1805
paul94f2b392005-06-28 12:44:16 +00001806static void
paul718e3742002-12-13 20:15:29 +00001807route_match_ipv6_address_free (void *rule)
1808{
1809 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1810}
1811
1812/* Route map commands for ip address matching. */
1813struct route_map_rule_cmd route_match_ipv6_address_cmd =
1814{
1815 "ipv6 address",
1816 route_match_ipv6_address,
1817 route_match_ipv6_address_compile,
1818 route_match_ipv6_address_free
1819};
David Lamparter6b0655a2014-06-04 06:53:35 +02001820
paul718e3742002-12-13 20:15:29 +00001821/* `match ipv6 next-hop IP_ADDRESS' */
1822
paul94f2b392005-06-28 12:44:16 +00001823static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001824route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1825 route_map_object_t type, void *object)
1826{
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001827 struct in6_addr *addr = rule;
paul718e3742002-12-13 20:15:29 +00001828 struct bgp_info *bgp_info;
1829
1830 if (type == RMAP_BGP)
1831 {
paul718e3742002-12-13 20:15:29 +00001832 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001833
1834 if (!bgp_info->attr->extra)
1835 return RMAP_NOMATCH;
1836
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001837 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, addr))
paul718e3742002-12-13 20:15:29 +00001838 return RMAP_MATCH;
1839
Paul Jakmafb982c22007-05-04 20:15:47 +00001840 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001841 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, addr))
paul718e3742002-12-13 20:15:29 +00001842 return RMAP_MATCH;
1843
1844 return RMAP_NOMATCH;
1845 }
1846
1847 return RMAP_NOMATCH;
1848}
1849
paul94f2b392005-06-28 12:44:16 +00001850static void *
paulfd79ac92004-10-13 05:06:08 +00001851route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001852{
1853 struct in6_addr *address;
1854 int ret;
1855
1856 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1857
1858 ret = inet_pton (AF_INET6, arg, address);
1859 if (!ret)
1860 {
1861 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1862 return NULL;
1863 }
1864
1865 return address;
1866}
1867
paul94f2b392005-06-28 12:44:16 +00001868static void
paul718e3742002-12-13 20:15:29 +00001869route_match_ipv6_next_hop_free (void *rule)
1870{
1871 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1872}
1873
1874struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1875{
1876 "ipv6 next-hop",
1877 route_match_ipv6_next_hop,
1878 route_match_ipv6_next_hop_compile,
1879 route_match_ipv6_next_hop_free
1880};
David Lamparter6b0655a2014-06-04 06:53:35 +02001881
paul718e3742002-12-13 20:15:29 +00001882/* `match ipv6 address prefix-list PREFIX_LIST' */
1883
paul94f2b392005-06-28 12:44:16 +00001884static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001885route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1886 route_map_object_t type, void *object)
1887{
1888 struct prefix_list *plist;
1889
1890 if (type == RMAP_BGP)
1891 {
1892 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1893 if (plist == NULL)
1894 return RMAP_NOMATCH;
1895
1896 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1897 RMAP_NOMATCH : RMAP_MATCH);
1898 }
1899 return RMAP_NOMATCH;
1900}
1901
paul94f2b392005-06-28 12:44:16 +00001902static void *
paulfd79ac92004-10-13 05:06:08 +00001903route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001904{
1905 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1906}
1907
paul94f2b392005-06-28 12:44:16 +00001908static void
paul718e3742002-12-13 20:15:29 +00001909route_match_ipv6_address_prefix_list_free (void *rule)
1910{
1911 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1912}
1913
1914struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1915{
1916 "ipv6 address prefix-list",
1917 route_match_ipv6_address_prefix_list,
1918 route_match_ipv6_address_prefix_list_compile,
1919 route_match_ipv6_address_prefix_list_free
1920};
David Lamparter6b0655a2014-06-04 06:53:35 +02001921
paul718e3742002-12-13 20:15:29 +00001922/* `set ipv6 nexthop global IP_ADDRESS' */
1923
1924/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001925static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001926route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1927 route_map_object_t type, void *object)
1928{
1929 struct in6_addr *address;
1930 struct bgp_info *bgp_info;
1931
1932 if (type == RMAP_BGP)
1933 {
1934 /* Fetch routemap's rule information. */
1935 address = rule;
1936 bgp_info = object;
1937
1938 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001939 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00001940
1941 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001942 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1943 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00001944 }
1945
1946 return RMAP_OKAY;
1947}
1948
1949/* Route map `ip next-hop' compile function. Given string is converted
1950 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001951static void *
paulfd79ac92004-10-13 05:06:08 +00001952route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001953{
1954 int ret;
1955 struct in6_addr *address;
1956
1957 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1958
1959 ret = inet_pton (AF_INET6, arg, address);
1960
1961 if (ret == 0)
1962 {
1963 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1964 return NULL;
1965 }
1966
1967 return address;
1968}
1969
1970/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00001971static void
paul718e3742002-12-13 20:15:29 +00001972route_set_ipv6_nexthop_global_free (void *rule)
1973{
1974 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1975}
1976
1977/* Route map commands for ip nexthop set. */
1978struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
1979{
1980 "ipv6 next-hop global",
1981 route_set_ipv6_nexthop_global,
1982 route_set_ipv6_nexthop_global_compile,
1983 route_set_ipv6_nexthop_global_free
1984};
David Lamparter6b0655a2014-06-04 06:53:35 +02001985
paul718e3742002-12-13 20:15:29 +00001986/* `set ipv6 nexthop local IP_ADDRESS' */
1987
1988/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001989static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001990route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
1991 route_map_object_t type, void *object)
1992{
1993 struct in6_addr *address;
1994 struct bgp_info *bgp_info;
1995
1996 if (type == RMAP_BGP)
1997 {
1998 /* Fetch routemap's rule information. */
1999 address = rule;
2000 bgp_info = object;
2001
2002 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002003 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00002004
2005 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002006 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2007 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00002008 }
2009
2010 return RMAP_OKAY;
2011}
2012
2013/* Route map `ip nexthop' compile function. Given string is converted
2014 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00002015static void *
paulfd79ac92004-10-13 05:06:08 +00002016route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002017{
2018 int ret;
2019 struct in6_addr *address;
2020
2021 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2022
2023 ret = inet_pton (AF_INET6, arg, address);
2024
2025 if (ret == 0)
2026 {
2027 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2028 return NULL;
2029 }
2030
2031 return address;
2032}
2033
2034/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00002035static void
paul718e3742002-12-13 20:15:29 +00002036route_set_ipv6_nexthop_local_free (void *rule)
2037{
2038 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2039}
2040
2041/* Route map commands for ip nexthop set. */
2042struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
2043{
2044 "ipv6 next-hop local",
2045 route_set_ipv6_nexthop_local,
2046 route_set_ipv6_nexthop_local_compile,
2047 route_set_ipv6_nexthop_local_free
2048};
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002049
2050/* `set ipv6 nexthop peer-address' */
2051
2052/* Set nexthop to object. ojbect must be pointer to struct attr. */
2053static route_map_result_t
2054route_set_ipv6_nexthop_peer (void *rule, struct prefix *prefix,
2055 route_map_object_t type, void *object)
2056{
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002057 struct in6_addr peer_address;
2058 struct bgp_info *bgp_info;
2059 struct peer *peer;
2060 char peer_addr_buf[INET6_ADDRSTRLEN];
2061
2062 if (type == RMAP_BGP)
2063 {
2064 /* Fetch routemap's rule information. */
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002065 bgp_info = object;
2066 peer = bgp_info->peer;
2067
2068 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
2069 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
2070 && peer->su_remote
2071 && sockunion_family (peer->su_remote) == AF_INET6)
2072 {
2073 inet_pton (AF_INET6, sockunion2str (peer->su_remote,
2074 peer_addr_buf,
2075 INET6_ADDRSTRLEN),
2076 &peer_address);
2077 }
2078 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
2079 && peer->su_local
2080 && sockunion_family (peer->su_local) == AF_INET6)
2081 {
2082 inet_pton (AF_INET, sockunion2str (peer->su_local,
2083 peer_addr_buf,
2084 INET6_ADDRSTRLEN),
2085 &peer_address);
2086 }
2087
2088 if (IN6_IS_ADDR_LINKLOCAL(&peer_address))
2089 {
2090 /* Set next hop value. */
2091 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = peer_address;
2092
2093 /* Set nexthop length. */
2094 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2095 bgp_info->attr->extra->mp_nexthop_len = 32;
2096 }
2097 else
2098 {
2099 /* Set next hop value. */
2100 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = peer_address;
2101
2102 /* Set nexthop length. */
2103 if (bgp_info->attr->extra->mp_nexthop_len == 0)
2104 bgp_info->attr->extra->mp_nexthop_len = 16;
2105 }
2106 }
2107
2108 return RMAP_OKAY;
2109}
2110
2111/* Route map `ip next-hop' compile function. Given string is converted
2112 to struct in_addr structure. */
2113static void *
2114route_set_ipv6_nexthop_peer_compile (const char *arg)
2115{
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002116 int *rins = NULL;
2117
2118 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (int));
2119 *rins = 1;
2120
2121 return rins;
2122}
2123
2124/* Free route map's compiled `ip next-hop' value. */
2125static void
2126route_set_ipv6_nexthop_peer_free (void *rule)
2127{
2128 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2129}
2130
2131/* Route map commands for ip nexthop set. */
2132struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd =
2133{
2134 "ipv6 next-hop peer-address",
2135 route_set_ipv6_nexthop_peer,
2136 route_set_ipv6_nexthop_peer_compile,
2137 route_set_ipv6_nexthop_peer_free
2138};
2139
paul718e3742002-12-13 20:15:29 +00002140/* `set vpnv4 nexthop A.B.C.D' */
2141
paul94f2b392005-06-28 12:44:16 +00002142static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002143route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2144 route_map_object_t type, void *object)
2145{
2146 struct in_addr *address;
2147 struct bgp_info *bgp_info;
2148
2149 if (type == RMAP_BGP)
2150 {
2151 /* Fetch routemap's rule information. */
2152 address = rule;
2153 bgp_info = object;
2154
2155 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002156 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
Lou Berger050defe2016-01-12 13:41:59 -05002157 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_len = 4;
paul718e3742002-12-13 20:15:29 +00002158 }
2159
2160 return RMAP_OKAY;
2161}
2162
paul94f2b392005-06-28 12:44:16 +00002163static void *
paulfd79ac92004-10-13 05:06:08 +00002164route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002165{
2166 int ret;
2167 struct in_addr *address;
2168
2169 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2170
2171 ret = inet_aton (arg, address);
2172
2173 if (ret == 0)
2174 {
2175 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2176 return NULL;
2177 }
2178
2179 return address;
2180}
2181
paul94f2b392005-06-28 12:44:16 +00002182static void
paul718e3742002-12-13 20:15:29 +00002183route_set_vpnv4_nexthop_free (void *rule)
2184{
2185 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2186}
2187
2188/* Route map commands for ip nexthop set. */
2189struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2190{
2191 "vpnv4 next-hop",
2192 route_set_vpnv4_nexthop,
2193 route_set_vpnv4_nexthop_compile,
2194 route_set_vpnv4_nexthop_free
2195};
David Lamparter6b0655a2014-06-04 06:53:35 +02002196
paul718e3742002-12-13 20:15:29 +00002197/* `set originator-id' */
2198
2199/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002200static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002201route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2202{
2203 struct in_addr *address;
2204 struct bgp_info *bgp_info;
2205
2206 if (type == RMAP_BGP)
2207 {
2208 address = rule;
2209 bgp_info = object;
2210
2211 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002212 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002213 }
2214
2215 return RMAP_OKAY;
2216}
2217
2218/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002219static void *
paulfd79ac92004-10-13 05:06:08 +00002220route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002221{
2222 int ret;
2223 struct in_addr *address;
2224
2225 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2226
2227 ret = inet_aton (arg, address);
2228
2229 if (ret == 0)
2230 {
2231 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2232 return NULL;
2233 }
2234
2235 return address;
2236}
2237
2238/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002239static void
paul718e3742002-12-13 20:15:29 +00002240route_set_originator_id_free (void *rule)
2241{
2242 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2243}
2244
Timo Teräs2aa640b2014-05-20 08:57:26 +03002245/* Set originator-id rule structure. */
paul718e3742002-12-13 20:15:29 +00002246struct route_map_rule_cmd route_set_originator_id_cmd =
2247{
2248 "originator-id",
2249 route_set_originator_id,
2250 route_set_originator_id_compile,
2251 route_set_originator_id_free,
2252};
David Lamparter6b0655a2014-06-04 06:53:35 +02002253
paul718e3742002-12-13 20:15:29 +00002254/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002255static int
paul718e3742002-12-13 20:15:29 +00002256bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002257 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002258{
2259 int ret;
2260
2261 ret = route_map_add_match (index, command, arg);
2262 if (ret)
2263 {
2264 switch (ret)
2265 {
2266 case RMAP_RULE_MISSING:
2267 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2268 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002269 case RMAP_COMPILE_ERROR:
2270 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2271 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002272 }
2273 }
2274 return CMD_SUCCESS;
2275}
2276
2277/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002278static int
paul718e3742002-12-13 20:15:29 +00002279bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002280 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002281{
2282 int ret;
2283
2284 ret = route_map_delete_match (index, command, arg);
2285 if (ret)
2286 {
2287 switch (ret)
2288 {
2289 case RMAP_RULE_MISSING:
2290 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2291 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002292 case RMAP_COMPILE_ERROR:
2293 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2294 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002295 }
2296 }
2297 return CMD_SUCCESS;
2298}
2299
2300/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002301static int
paul718e3742002-12-13 20:15:29 +00002302bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002303 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002304{
2305 int ret;
2306
2307 ret = route_map_add_set (index, command, arg);
2308 if (ret)
2309 {
2310 switch (ret)
2311 {
2312 case RMAP_RULE_MISSING:
2313 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2314 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002315 case RMAP_COMPILE_ERROR:
2316 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2317 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002318 }
2319 }
2320 return CMD_SUCCESS;
2321}
2322
2323/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002324static int
paul718e3742002-12-13 20:15:29 +00002325bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002326 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002327{
2328 int ret;
2329
2330 ret = route_map_delete_set (index, command, arg);
2331 if (ret)
2332 {
2333 switch (ret)
2334 {
2335 case RMAP_RULE_MISSING:
2336 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2337 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002338 case RMAP_COMPILE_ERROR:
2339 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2340 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002341 }
2342 }
2343 return CMD_SUCCESS;
2344}
2345
2346/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002347static void
paulfd79ac92004-10-13 05:06:08 +00002348bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002349{
2350 int i;
2351 afi_t afi;
2352 safi_t safi;
2353 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002354 struct listnode *node, *nnode;
2355 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002356 struct bgp *bgp;
2357 struct peer *peer;
2358 struct peer_group *group;
2359 struct bgp_filter *filter;
2360 struct bgp_node *bn;
2361 struct bgp_static *bgp_static;
2362
Lou Berger82dd7072016-01-12 13:41:57 -05002363 if (bm->bgp == NULL) /* may be called during cleanup */
2364 return;
2365
paul718e3742002-12-13 20:15:29 +00002366 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002367 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002368 {
paul1eb8ef22005-04-07 07:30:20 +00002369 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002370 {
2371 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2372 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2373 {
2374 filter = &peer->filter[afi][safi];
2375
paulfee0f4c2004-09-13 05:12:46 +00002376 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002377 {
2378 if (filter->map[direct].name)
2379 filter->map[direct].map =
2380 route_map_lookup_by_name (filter->map[direct].name);
2381 else
2382 filter->map[direct].map = NULL;
2383 }
2384
2385 if (filter->usmap.name)
2386 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2387 else
2388 filter->usmap.map = NULL;
2389 }
2390 }
paul1eb8ef22005-04-07 07:30:20 +00002391 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002392 {
2393 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2394 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2395 {
2396 filter = &group->conf->filter[afi][safi];
2397
paulfee0f4c2004-09-13 05:12:46 +00002398 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002399 {
2400 if (filter->map[direct].name)
2401 filter->map[direct].map =
2402 route_map_lookup_by_name (filter->map[direct].name);
2403 else
2404 filter->map[direct].map = NULL;
2405 }
2406
2407 if (filter->usmap.name)
2408 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2409 else
2410 filter->usmap.map = NULL;
2411 }
2412 }
2413 }
2414
2415 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002416 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002417 {
paul1eb8ef22005-04-07 07:30:20 +00002418 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002419 {
2420 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2421 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2422 {
2423 if (peer->default_rmap[afi][safi].name)
2424 peer->default_rmap[afi][safi].map =
2425 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2426 else
2427 peer->default_rmap[afi][safi].map = NULL;
2428 }
2429 }
2430 }
2431
2432 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002433 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002434 {
2435 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2436 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2437 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2438 bn = bgp_route_next (bn))
2439 if ((bgp_static = bn->info) != NULL)
2440 {
2441 if (bgp_static->rmap.name)
2442 bgp_static->rmap.map =
2443 route_map_lookup_by_name (bgp_static->rmap.name);
2444 else
2445 bgp_static->rmap.map = NULL;
2446 }
2447 }
2448
2449 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002450 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002451 {
2452 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2453 {
Donald Sharpf3cfc462016-01-07 09:33:28 -05002454 if (bgp->rmap[AFI_IP][i].name)
2455 bgp->rmap[AFI_IP][i].map =
2456 route_map_lookup_by_name (bgp->rmap[AFI_IP][i].name);
2457 if (bgp->rmap[AFI_IP6][i].name)
2458 bgp->rmap[AFI_IP6][i].map =
Andrej Ota220355d2016-05-09 20:49:01 +02002459 route_map_lookup_by_name (bgp->rmap[AFI_IP6][i].name);
paul718e3742002-12-13 20:15:29 +00002460 }
2461 }
2462}
David Lamparter6b0655a2014-06-04 06:53:35 +02002463
paulfee0f4c2004-09-13 05:12:46 +00002464DEFUN (match_peer,
2465 match_peer_cmd,
2466 "match peer (A.B.C.D|X:X::X:X)",
2467 MATCH_STR
2468 "Match peer address\n"
Igor Ryzhov93b493a2016-05-11 15:26:39 +03002469 "IP address of peer\n"
2470 "IPv6 address of peer\n")
paulfee0f4c2004-09-13 05:12:46 +00002471{
2472 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2473}
2474
2475DEFUN (match_peer_local,
2476 match_peer_local_cmd,
2477 "match peer local",
2478 MATCH_STR
2479 "Match peer address\n"
2480 "Static or Redistributed routes\n")
2481{
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +02002482 return bgp_route_match_add (vty, vty->index, "peer", "local");
paulfee0f4c2004-09-13 05:12:46 +00002483}
2484
2485DEFUN (no_match_peer,
2486 no_match_peer_cmd,
2487 "no match peer",
2488 NO_STR
2489 MATCH_STR
2490 "Match peer address\n")
2491{
2492 if (argc == 0)
2493 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2494
2495 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2496}
2497
2498ALIAS (no_match_peer,
2499 no_match_peer_val_cmd,
2500 "no match peer (A.B.C.D|X:X::X:X)",
2501 NO_STR
2502 MATCH_STR
2503 "Match peer address\n"
Igor Ryzhov93b493a2016-05-11 15:26:39 +03002504 "IP address of peer\n"
2505 "IPv6 address of peer\n")
paulfee0f4c2004-09-13 05:12:46 +00002506
2507ALIAS (no_match_peer,
2508 no_match_peer_local_cmd,
2509 "no match peer local",
2510 NO_STR
2511 MATCH_STR
2512 "Match peer address\n"
2513 "Static or Redistributed routes\n")
2514
paul718e3742002-12-13 20:15:29 +00002515DEFUN (match_ip_address,
2516 match_ip_address_cmd,
2517 "match ip address (<1-199>|<1300-2699>|WORD)",
2518 MATCH_STR
2519 IP_STR
2520 "Match address of route\n"
2521 "IP access-list number\n"
2522 "IP access-list number (expanded range)\n"
2523 "IP Access-list name\n")
2524{
2525 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2526}
2527
2528DEFUN (no_match_ip_address,
2529 no_match_ip_address_cmd,
2530 "no match ip address",
2531 NO_STR
2532 MATCH_STR
2533 IP_STR
2534 "Match address of route\n")
2535{
2536 if (argc == 0)
2537 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2538
2539 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2540}
2541
2542ALIAS (no_match_ip_address,
2543 no_match_ip_address_val_cmd,
2544 "no match ip address (<1-199>|<1300-2699>|WORD)",
2545 NO_STR
2546 MATCH_STR
2547 IP_STR
2548 "Match address of route\n"
2549 "IP access-list number\n"
2550 "IP access-list number (expanded range)\n"
2551 "IP Access-list name\n")
2552
2553DEFUN (match_ip_next_hop,
2554 match_ip_next_hop_cmd,
2555 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2556 MATCH_STR
2557 IP_STR
2558 "Match next-hop address of route\n"
2559 "IP access-list number\n"
2560 "IP access-list number (expanded range)\n"
2561 "IP Access-list name\n")
2562{
2563 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2564}
2565
2566DEFUN (no_match_ip_next_hop,
2567 no_match_ip_next_hop_cmd,
2568 "no match ip next-hop",
2569 NO_STR
2570 MATCH_STR
2571 IP_STR
2572 "Match next-hop address of route\n")
2573{
2574 if (argc == 0)
2575 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2576
2577 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2578}
2579
2580ALIAS (no_match_ip_next_hop,
2581 no_match_ip_next_hop_val_cmd,
2582 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2583 NO_STR
2584 MATCH_STR
2585 IP_STR
2586 "Match next-hop address of route\n"
2587 "IP access-list number\n"
2588 "IP access-list number (expanded range)\n"
2589 "IP Access-list name\n")
2590
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04002591/* match probability { */
2592
2593DEFUN (match_probability,
2594 match_probability_cmd,
2595 "match probability <0-100>",
2596 MATCH_STR
2597 "Match portion of routes defined by percentage value\n"
2598 "Percentage of routes\n")
2599{
2600 return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
2601}
2602
2603DEFUN (no_match_probability,
2604 no_match_probability_cmd,
2605 "no match probability",
2606 NO_STR
2607 MATCH_STR
2608 "Match portion of routes defined by percentage value\n")
2609{
2610 return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL);
2611}
2612
2613ALIAS (no_match_probability,
2614 no_match_probability_val_cmd,
2615 "no match probability <1-99>",
2616 NO_STR
2617 MATCH_STR
2618 "Match portion of routes defined by percentage value\n"
2619 "Percentage of routes\n")
2620
2621/* } */
2622
hassoc1643bb2005-02-02 16:43:17 +00002623DEFUN (match_ip_route_source,
2624 match_ip_route_source_cmd,
2625 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2626 MATCH_STR
2627 IP_STR
2628 "Match advertising source address of route\n"
2629 "IP access-list number\n"
2630 "IP access-list number (expanded range)\n"
2631 "IP standard access-list name\n")
2632{
2633 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2634}
2635
2636DEFUN (no_match_ip_route_source,
2637 no_match_ip_route_source_cmd,
2638 "no match ip route-source",
2639 NO_STR
2640 MATCH_STR
2641 IP_STR
2642 "Match advertising source address of route\n")
2643{
2644 if (argc == 0)
2645 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2646
2647 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2648}
2649
2650ALIAS (no_match_ip_route_source,
2651 no_match_ip_route_source_val_cmd,
2652 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2653 NO_STR
2654 MATCH_STR
2655 IP_STR
2656 "Match advertising source address of route\n"
2657 "IP access-list number\n"
2658 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002659 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002660
paul718e3742002-12-13 20:15:29 +00002661DEFUN (match_ip_address_prefix_list,
2662 match_ip_address_prefix_list_cmd,
2663 "match ip address prefix-list WORD",
2664 MATCH_STR
2665 IP_STR
2666 "Match address of route\n"
2667 "Match entries of prefix-lists\n"
2668 "IP prefix-list name\n")
2669{
2670 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2671}
2672
2673DEFUN (no_match_ip_address_prefix_list,
2674 no_match_ip_address_prefix_list_cmd,
2675 "no match ip address prefix-list",
2676 NO_STR
2677 MATCH_STR
2678 IP_STR
2679 "Match address of route\n"
2680 "Match entries of prefix-lists\n")
2681{
2682 if (argc == 0)
2683 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2684
2685 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2686}
2687
2688ALIAS (no_match_ip_address_prefix_list,
2689 no_match_ip_address_prefix_list_val_cmd,
2690 "no match ip address prefix-list WORD",
2691 NO_STR
2692 MATCH_STR
2693 IP_STR
2694 "Match address of route\n"
2695 "Match entries of prefix-lists\n"
2696 "IP prefix-list name\n")
2697
2698DEFUN (match_ip_next_hop_prefix_list,
2699 match_ip_next_hop_prefix_list_cmd,
2700 "match ip next-hop prefix-list WORD",
2701 MATCH_STR
2702 IP_STR
2703 "Match next-hop address of route\n"
2704 "Match entries of prefix-lists\n"
2705 "IP prefix-list name\n")
2706{
2707 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2708}
2709
2710DEFUN (no_match_ip_next_hop_prefix_list,
2711 no_match_ip_next_hop_prefix_list_cmd,
2712 "no match ip next-hop prefix-list",
2713 NO_STR
2714 MATCH_STR
2715 IP_STR
2716 "Match next-hop address of route\n"
2717 "Match entries of prefix-lists\n")
2718{
2719 if (argc == 0)
2720 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2721
2722 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2723}
2724
2725ALIAS (no_match_ip_next_hop_prefix_list,
2726 no_match_ip_next_hop_prefix_list_val_cmd,
2727 "no match ip next-hop prefix-list WORD",
2728 NO_STR
2729 MATCH_STR
2730 IP_STR
2731 "Match next-hop address of route\n"
2732 "Match entries of prefix-lists\n"
2733 "IP prefix-list name\n")
2734
hassoc1643bb2005-02-02 16:43:17 +00002735DEFUN (match_ip_route_source_prefix_list,
2736 match_ip_route_source_prefix_list_cmd,
2737 "match ip route-source prefix-list WORD",
2738 MATCH_STR
2739 IP_STR
2740 "Match advertising source address of route\n"
2741 "Match entries of prefix-lists\n"
2742 "IP prefix-list name\n")
2743{
2744 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2745}
2746
2747DEFUN (no_match_ip_route_source_prefix_list,
2748 no_match_ip_route_source_prefix_list_cmd,
2749 "no match ip route-source prefix-list",
2750 NO_STR
2751 MATCH_STR
2752 IP_STR
2753 "Match advertising source address of route\n"
2754 "Match entries of prefix-lists\n")
2755{
2756 if (argc == 0)
2757 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2758
2759 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2760}
2761
2762ALIAS (no_match_ip_route_source_prefix_list,
2763 no_match_ip_route_source_prefix_list_val_cmd,
2764 "no match ip route-source prefix-list WORD",
2765 NO_STR
2766 MATCH_STR
2767 IP_STR
2768 "Match advertising source address of route\n"
2769 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002770 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002771
paul718e3742002-12-13 20:15:29 +00002772DEFUN (match_metric,
2773 match_metric_cmd,
2774 "match metric <0-4294967295>",
2775 MATCH_STR
2776 "Match metric of route\n"
2777 "Metric value\n")
2778{
2779 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2780}
2781
2782DEFUN (no_match_metric,
2783 no_match_metric_cmd,
2784 "no match metric",
2785 NO_STR
2786 MATCH_STR
2787 "Match metric of route\n")
2788{
2789 if (argc == 0)
2790 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2791
2792 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2793}
2794
2795ALIAS (no_match_metric,
2796 no_match_metric_val_cmd,
2797 "no match metric <0-4294967295>",
2798 NO_STR
2799 MATCH_STR
2800 "Match metric of route\n"
2801 "Metric value\n")
2802
Dinesh Dutt5cf768a2015-11-09 20:21:53 -05002803DEFUN (match_local_pref,
2804 match_local_pref_cmd,
2805 "match local-preference <0-4294967295>",
2806 MATCH_STR
2807 "Match local-preference of route\n"
2808 "Metric value\n")
2809{
2810 return bgp_route_match_add (vty, vty->index, "local-preference", argv[0]);
2811}
2812
2813DEFUN (no_match_local_pref,
2814 no_match_local_pref_cmd,
2815 "no match local-preference",
2816 NO_STR
2817 MATCH_STR
2818 "Match local preference of route\n")
2819{
2820 if (argc == 0)
2821 return bgp_route_match_delete (vty, vty->index, "local-preference", NULL);
2822
2823 return bgp_route_match_delete (vty, vty->index, "local-preference", argv[0]);
2824}
2825
2826ALIAS (no_match_local_pref,
2827 no_match_local_pref_val_cmd,
2828 "no match local-preference <0-4294967295>",
2829 NO_STR
2830 MATCH_STR
2831 "Match local preference of route\n"
2832 "Local preference value\n")
2833
paul718e3742002-12-13 20:15:29 +00002834DEFUN (match_community,
2835 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002836 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002837 MATCH_STR
2838 "Match BGP community list\n"
2839 "Community-list number (standard)\n"
2840 "Community-list number (expanded)\n"
2841 "Community-list name\n")
2842{
2843 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2844}
2845
2846DEFUN (match_community_exact,
2847 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002848 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002849 MATCH_STR
2850 "Match BGP community list\n"
2851 "Community-list number (standard)\n"
2852 "Community-list number (expanded)\n"
2853 "Community-list name\n"
2854 "Do exact matching of communities\n")
2855{
2856 int ret;
2857 char *argstr;
2858
2859 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2860 strlen (argv[0]) + strlen ("exact-match") + 2);
2861
2862 sprintf (argstr, "%s exact-match", argv[0]);
2863
2864 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2865
2866 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2867
2868 return ret;
2869}
2870
2871DEFUN (no_match_community,
2872 no_match_community_cmd,
2873 "no match community",
2874 NO_STR
2875 MATCH_STR
2876 "Match BGP community list\n")
2877{
2878 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2879}
2880
2881ALIAS (no_match_community,
2882 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002883 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002884 NO_STR
2885 MATCH_STR
2886 "Match BGP community list\n"
2887 "Community-list number (standard)\n"
2888 "Community-list number (expanded)\n"
2889 "Community-list name\n")
2890
2891ALIAS (no_match_community,
2892 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002893 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002894 NO_STR
2895 MATCH_STR
2896 "Match BGP community list\n"
2897 "Community-list number (standard)\n"
2898 "Community-list number (expanded)\n"
2899 "Community-list name\n"
2900 "Do exact matching of communities\n")
2901
paul73ffb252003-04-19 15:49:49 +00002902DEFUN (match_ecommunity,
2903 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002904 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002905 MATCH_STR
2906 "Match BGP/VPN extended community list\n"
2907 "Extended community-list number (standard)\n"
2908 "Extended community-list number (expanded)\n"
2909 "Extended community-list name\n")
2910{
2911 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2912}
2913
2914DEFUN (no_match_ecommunity,
2915 no_match_ecommunity_cmd,
2916 "no match extcommunity",
2917 NO_STR
2918 MATCH_STR
2919 "Match BGP/VPN extended community list\n")
2920{
2921 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2922}
2923
2924ALIAS (no_match_ecommunity,
2925 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002926 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002927 NO_STR
2928 MATCH_STR
2929 "Match BGP/VPN extended community list\n"
2930 "Extended community-list number (standard)\n"
2931 "Extended community-list number (expanded)\n"
2932 "Extended community-list name\n")
2933
paul718e3742002-12-13 20:15:29 +00002934DEFUN (match_aspath,
2935 match_aspath_cmd,
2936 "match as-path WORD",
2937 MATCH_STR
2938 "Match BGP AS path list\n"
2939 "AS path access-list name\n")
2940{
2941 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2942}
2943
2944DEFUN (no_match_aspath,
2945 no_match_aspath_cmd,
2946 "no match as-path",
2947 NO_STR
2948 MATCH_STR
2949 "Match BGP AS path list\n")
2950{
2951 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2952}
2953
2954ALIAS (no_match_aspath,
2955 no_match_aspath_val_cmd,
2956 "no match as-path WORD",
2957 NO_STR
2958 MATCH_STR
2959 "Match BGP AS path list\n"
2960 "AS path access-list name\n")
2961
2962DEFUN (match_origin,
2963 match_origin_cmd,
2964 "match origin (egp|igp|incomplete)",
2965 MATCH_STR
2966 "BGP origin code\n"
2967 "remote EGP\n"
2968 "local IGP\n"
2969 "unknown heritage\n")
2970{
2971 if (strncmp (argv[0], "igp", 2) == 0)
2972 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2973 if (strncmp (argv[0], "egp", 1) == 0)
2974 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2975 if (strncmp (argv[0], "incomplete", 2) == 0)
2976 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2977
2978 return CMD_WARNING;
2979}
2980
2981DEFUN (no_match_origin,
2982 no_match_origin_cmd,
2983 "no match origin",
2984 NO_STR
2985 MATCH_STR
2986 "BGP origin code\n")
2987{
2988 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2989}
2990
2991ALIAS (no_match_origin,
2992 no_match_origin_val_cmd,
2993 "no match origin (egp|igp|incomplete)",
2994 NO_STR
2995 MATCH_STR
2996 "BGP origin code\n"
2997 "remote EGP\n"
2998 "local IGP\n"
2999 "unknown heritage\n")
3000
3001DEFUN (set_ip_nexthop,
3002 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00003003 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003004 SET_STR
3005 IP_STR
3006 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00003007 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00003008{
3009 union sockunion su;
3010 int ret;
3011
3012 ret = str2sockunion (argv[0], &su);
3013 if (ret < 0)
3014 {
3015 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
3016 return CMD_WARNING;
3017 }
3018
3019 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
3020}
3021
paulaf5cd0a2003-11-02 07:24:40 +00003022DEFUN (set_ip_nexthop_peer,
3023 set_ip_nexthop_peer_cmd,
3024 "set ip next-hop peer-address",
3025 SET_STR
3026 IP_STR
3027 "Next hop address\n"
3028 "Use peer address (for BGP only)\n")
3029{
3030 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
3031}
3032
paul94f2b392005-06-28 12:44:16 +00003033DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00003034 no_set_ip_nexthop_peer_cmd,
3035 "no set ip next-hop peer-address",
3036 NO_STR
3037 SET_STR
3038 IP_STR
3039 "Next hop address\n"
3040 "Use peer address (for BGP only)\n")
3041{
3042 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
3043}
3044
3045
paul718e3742002-12-13 20:15:29 +00003046DEFUN (no_set_ip_nexthop,
3047 no_set_ip_nexthop_cmd,
3048 "no set ip next-hop",
3049 NO_STR
3050 SET_STR
paul718e3742002-12-13 20:15:29 +00003051 "Next hop address\n")
3052{
paulaf5cd0a2003-11-02 07:24:40 +00003053 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00003054 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
3055
3056 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
3057}
3058
3059ALIAS (no_set_ip_nexthop,
3060 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00003061 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003062 NO_STR
3063 SET_STR
3064 IP_STR
3065 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00003066 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00003067
3068DEFUN (set_metric,
3069 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00003070 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00003071 SET_STR
3072 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00003073 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00003074{
3075 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
3076}
3077
paul73ffb252003-04-19 15:49:49 +00003078ALIAS (set_metric,
3079 set_metric_addsub_cmd,
3080 "set metric <+/-metric>",
3081 SET_STR
3082 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00003083 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00003084
Timo Teräsef757702015-04-29 09:43:04 +03003085ALIAS (set_metric,
3086 set_metric_rtt_cmd,
3087 "set metric (rtt|+rtt|-rtt)",
3088 SET_STR
3089 "Metric value for destination routing protocol\n"
3090 "Assign round trip time\n"
3091 "Add round trip time\n"
3092 "Subtract round trip time\n")
3093
paul718e3742002-12-13 20:15:29 +00003094DEFUN (no_set_metric,
3095 no_set_metric_cmd,
3096 "no set metric",
3097 NO_STR
3098 SET_STR
3099 "Metric value for destination routing protocol\n")
3100{
3101 if (argc == 0)
3102 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
3103
3104 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
3105}
3106
3107ALIAS (no_set_metric,
3108 no_set_metric_val_cmd,
3109 "no set metric <0-4294967295>",
3110 NO_STR
3111 SET_STR
3112 "Metric value for destination routing protocol\n"
3113 "Metric value\n")
3114
3115DEFUN (set_local_pref,
3116 set_local_pref_cmd,
3117 "set local-preference <0-4294967295>",
3118 SET_STR
3119 "BGP local preference path attribute\n"
3120 "Preference value\n")
3121{
3122 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
3123}
3124
3125DEFUN (no_set_local_pref,
3126 no_set_local_pref_cmd,
3127 "no set local-preference",
3128 NO_STR
3129 SET_STR
3130 "BGP local preference path attribute\n")
3131{
3132 if (argc == 0)
3133 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3134
3135 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
3136}
3137
3138ALIAS (no_set_local_pref,
3139 no_set_local_pref_val_cmd,
3140 "no set local-preference <0-4294967295>",
3141 NO_STR
3142 SET_STR
3143 "BGP local preference path attribute\n"
3144 "Preference value\n")
3145
3146DEFUN (set_weight,
3147 set_weight_cmd,
3148 "set weight <0-4294967295>",
3149 SET_STR
3150 "BGP weight for routing table\n"
3151 "Weight value\n")
3152{
3153 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3154}
3155
3156DEFUN (no_set_weight,
3157 no_set_weight_cmd,
3158 "no set weight",
3159 NO_STR
3160 SET_STR
3161 "BGP weight for routing table\n")
3162{
3163 if (argc == 0)
3164 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3165
3166 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3167}
3168
3169ALIAS (no_set_weight,
3170 no_set_weight_val_cmd,
3171 "no set weight <0-4294967295>",
3172 NO_STR
3173 SET_STR
3174 "BGP weight for routing table\n"
3175 "Weight value\n")
3176
3177DEFUN (set_aspath_prepend,
3178 set_aspath_prepend_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003179 "set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003180 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003181 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003182 "Prepend to the as-path\n"
3183 "AS number\n")
3184{
3185 int ret;
3186 char *str;
3187
3188 str = argv_concat (argv, argc, 0);
3189 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3190 XFREE (MTYPE_TMP, str);
3191
3192 return ret;
3193}
3194
Timo Teräs85c854a2014-09-30 11:31:53 +03003195ALIAS (set_aspath_prepend,
3196 set_aspath_prepend_lastas_cmd,
3197 "set as-path prepend (last-as) <1-10>",
3198 SET_STR
3199 "Transform BGP AS_PATH attribute\n"
3200 "Prepend to the as-path\n"
3201 "Use the peer's AS-number\n"
David Lamparterb7d50212015-03-03 08:53:18 +01003202 "Number of times to insert")
Timo Teräs85c854a2014-09-30 11:31:53 +03003203
paul718e3742002-12-13 20:15:29 +00003204DEFUN (no_set_aspath_prepend,
3205 no_set_aspath_prepend_cmd,
3206 "no set as-path prepend",
3207 NO_STR
3208 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003209 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003210 "Prepend to the as-path\n")
3211{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00003212 int ret;
3213 char *str;
3214
3215 if (argc == 0)
3216 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3217
3218 str = argv_concat (argv, argc, 0);
3219 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3220 XFREE (MTYPE_TMP, str);
3221 return ret;
paul718e3742002-12-13 20:15:29 +00003222}
3223
3224ALIAS (no_set_aspath_prepend,
3225 no_set_aspath_prepend_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003226 "no set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003227 NO_STR
3228 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003229 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003230 "Prepend to the as-path\n"
3231 "AS number\n")
3232
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003233DEFUN (set_aspath_exclude,
3234 set_aspath_exclude_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003235 "set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003236 SET_STR
3237 "Transform BGP AS-path attribute\n"
3238 "Exclude from the as-path\n"
3239 "AS number\n")
3240{
3241 int ret;
3242 char *str;
3243
3244 str = argv_concat (argv, argc, 0);
3245 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3246 XFREE (MTYPE_TMP, str);
3247 return ret;
3248}
3249
3250DEFUN (no_set_aspath_exclude,
3251 no_set_aspath_exclude_cmd,
3252 "no set as-path exclude",
3253 NO_STR
3254 SET_STR
3255 "Transform BGP AS_PATH attribute\n"
3256 "Exclude from the as-path\n")
3257{
3258 int ret;
3259 char *str;
3260
3261 if (argc == 0)
3262 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3263
3264 str = argv_concat (argv, argc, 0);
3265 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3266 XFREE (MTYPE_TMP, str);
3267 return ret;
3268}
3269
3270ALIAS (no_set_aspath_exclude,
3271 no_set_aspath_exclude_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003272 "no set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003273 NO_STR
3274 SET_STR
3275 "Transform BGP AS_PATH attribute\n"
3276 "Exclude from the as-path\n"
3277 "AS number\n")
3278
paul718e3742002-12-13 20:15:29 +00003279DEFUN (set_community,
3280 set_community_cmd,
3281 "set community .AA:NN",
3282 SET_STR
3283 "BGP community attribute\n"
3284 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3285{
3286 int i;
3287 int first = 0;
3288 int additive = 0;
3289 struct buffer *b;
3290 struct community *com = NULL;
3291 char *str;
3292 char *argstr;
3293 int ret;
3294
3295 b = buffer_new (1024);
3296
3297 for (i = 0; i < argc; i++)
3298 {
3299 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3300 {
3301 additive = 1;
3302 continue;
3303 }
3304
3305 if (first)
3306 buffer_putc (b, ' ');
3307 else
3308 first = 1;
3309
3310 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3311 {
3312 buffer_putstr (b, "internet");
3313 continue;
3314 }
3315 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3316 {
3317 buffer_putstr (b, "local-AS");
3318 continue;
3319 }
3320 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3321 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3322 {
3323 buffer_putstr (b, "no-advertise");
3324 continue;
3325 }
3326 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3327 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3328 {
3329 buffer_putstr (b, "no-export");
3330 continue;
3331 }
3332 buffer_putstr (b, argv[i]);
3333 }
3334 buffer_putc (b, '\0');
3335
3336 /* Fetch result string then compile it to communities attribute. */
3337 str = buffer_getstr (b);
3338 buffer_free (b);
3339
3340 if (str)
3341 {
3342 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003343 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003344 }
3345
3346 /* Can't compile user input into communities attribute. */
3347 if (! com)
3348 {
3349 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3350 return CMD_WARNING;
3351 }
3352
3353 /* Set communites attribute string. */
3354 str = community_str (com);
3355
3356 if (additive)
3357 {
3358 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3359 strcpy (argstr, str);
3360 strcpy (argstr + strlen (str), " additive");
3361 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3362 XFREE (MTYPE_TMP, argstr);
3363 }
3364 else
3365 ret = bgp_route_set_add (vty, vty->index, "community", str);
3366
3367 community_free (com);
3368
3369 return ret;
3370}
3371
3372DEFUN (set_community_none,
3373 set_community_none_cmd,
3374 "set community none",
3375 SET_STR
3376 "BGP community attribute\n"
3377 "No community attribute\n")
3378{
3379 return bgp_route_set_add (vty, vty->index, "community", "none");
3380}
3381
3382DEFUN (no_set_community,
3383 no_set_community_cmd,
3384 "no set community",
3385 NO_STR
3386 SET_STR
3387 "BGP community attribute\n")
3388{
3389 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3390}
3391
3392ALIAS (no_set_community,
3393 no_set_community_val_cmd,
3394 "no set community .AA:NN",
3395 NO_STR
3396 SET_STR
3397 "BGP community attribute\n"
3398 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3399
3400ALIAS (no_set_community,
3401 no_set_community_none_cmd,
3402 "no set community none",
3403 NO_STR
3404 SET_STR
3405 "BGP community attribute\n"
3406 "No community attribute\n")
3407
3408DEFUN (set_community_delete,
3409 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003410 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003411 SET_STR
3412 "set BGP community list (for deletion)\n"
3413 "Community-list number (standard)\n"
3414 "Communitly-list number (expanded)\n"
3415 "Community-list name\n"
3416 "Delete matching communities\n")
3417{
3418 char *str;
3419
3420 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3421 strcpy (str, argv[0]);
3422 strcpy (str + strlen (argv[0]), " delete");
3423
3424 bgp_route_set_add (vty, vty->index, "comm-list", str);
3425
3426 XFREE (MTYPE_TMP, str);
3427 return CMD_SUCCESS;
3428}
3429
3430DEFUN (no_set_community_delete,
3431 no_set_community_delete_cmd,
3432 "no set comm-list",
3433 NO_STR
3434 SET_STR
3435 "set BGP community list (for deletion)\n")
3436{
3437 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3438}
3439
3440ALIAS (no_set_community_delete,
3441 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003442 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003443 NO_STR
3444 SET_STR
3445 "set BGP community list (for deletion)\n"
3446 "Community-list number (standard)\n"
3447 "Communitly-list number (expanded)\n"
3448 "Community-list name\n"
3449 "Delete matching communities\n")
3450
3451DEFUN (set_ecommunity_rt,
3452 set_ecommunity_rt_cmd,
3453 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3454 SET_STR
3455 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003456 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003457 "VPN extended community\n")
3458{
3459 int ret;
3460 char *str;
3461
3462 str = argv_concat (argv, argc, 0);
3463 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3464 XFREE (MTYPE_TMP, str);
3465
3466 return ret;
3467}
3468
3469DEFUN (no_set_ecommunity_rt,
3470 no_set_ecommunity_rt_cmd,
3471 "no set extcommunity rt",
3472 NO_STR
3473 SET_STR
3474 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003475 "Route Target extended community\n")
paul718e3742002-12-13 20:15:29 +00003476{
3477 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3478}
3479
3480ALIAS (no_set_ecommunity_rt,
3481 no_set_ecommunity_rt_val_cmd,
3482 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3483 NO_STR
3484 SET_STR
3485 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003486 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003487 "VPN extended community\n")
3488
3489DEFUN (set_ecommunity_soo,
3490 set_ecommunity_soo_cmd,
3491 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3492 SET_STR
3493 "BGP extended community attribute\n"
3494 "Site-of-Origin extended community\n"
3495 "VPN extended community\n")
3496{
3497 int ret;
3498 char *str;
3499
3500 str = argv_concat (argv, argc, 0);
3501 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3502 XFREE (MTYPE_TMP, str);
3503 return ret;
3504}
3505
3506DEFUN (no_set_ecommunity_soo,
3507 no_set_ecommunity_soo_cmd,
3508 "no set extcommunity soo",
3509 NO_STR
3510 SET_STR
3511 "BGP extended community attribute\n"
3512 "Site-of-Origin extended community\n")
3513{
3514 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3515}
3516
3517ALIAS (no_set_ecommunity_soo,
3518 no_set_ecommunity_soo_val_cmd,
3519 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3520 NO_STR
3521 SET_STR
3522 "BGP extended community attribute\n"
3523 "Site-of-Origin extended community\n"
3524 "VPN extended community\n")
3525
3526DEFUN (set_origin,
3527 set_origin_cmd,
3528 "set origin (egp|igp|incomplete)",
3529 SET_STR
3530 "BGP origin code\n"
3531 "remote EGP\n"
3532 "local IGP\n"
3533 "unknown heritage\n")
3534{
3535 if (strncmp (argv[0], "igp", 2) == 0)
3536 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3537 if (strncmp (argv[0], "egp", 1) == 0)
3538 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3539 if (strncmp (argv[0], "incomplete", 2) == 0)
3540 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3541
3542 return CMD_WARNING;
3543}
3544
3545DEFUN (no_set_origin,
3546 no_set_origin_cmd,
3547 "no set origin",
3548 NO_STR
3549 SET_STR
3550 "BGP origin code\n")
3551{
3552 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3553}
3554
3555ALIAS (no_set_origin,
3556 no_set_origin_val_cmd,
3557 "no set origin (egp|igp|incomplete)",
3558 NO_STR
3559 SET_STR
3560 "BGP origin code\n"
3561 "remote EGP\n"
3562 "local IGP\n"
3563 "unknown heritage\n")
3564
3565DEFUN (set_atomic_aggregate,
3566 set_atomic_aggregate_cmd,
3567 "set atomic-aggregate",
3568 SET_STR
3569 "BGP atomic aggregate attribute\n" )
3570{
3571 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3572}
3573
3574DEFUN (no_set_atomic_aggregate,
3575 no_set_atomic_aggregate_cmd,
3576 "no set atomic-aggregate",
3577 NO_STR
3578 SET_STR
3579 "BGP atomic aggregate attribute\n" )
3580{
3581 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3582}
3583
3584DEFUN (set_aggregator_as,
3585 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003586 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003587 SET_STR
3588 "BGP aggregator attribute\n"
3589 "AS number of aggregator\n"
3590 "AS number\n"
3591 "IP address of aggregator\n")
3592{
3593 int ret;
Paul Jakma7aa9dce2014-09-19 14:42:23 +01003594 as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
paul718e3742002-12-13 20:15:29 +00003595 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003596 char *argstr;
3597
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003598 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003599
paul718e3742002-12-13 20:15:29 +00003600 ret = inet_aton (argv[1], &address);
3601 if (ret == 0)
3602 {
3603 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3604 return CMD_WARNING;
3605 }
3606
3607 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3608 strlen (argv[0]) + strlen (argv[1]) + 2);
3609
3610 sprintf (argstr, "%s %s", argv[0], argv[1]);
3611
3612 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3613
3614 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3615
3616 return ret;
3617}
3618
3619DEFUN (no_set_aggregator_as,
3620 no_set_aggregator_as_cmd,
3621 "no set aggregator as",
3622 NO_STR
3623 SET_STR
3624 "BGP aggregator attribute\n"
3625 "AS number of aggregator\n")
3626{
3627 int ret;
Paul Jakma7aa9dce2014-09-19 14:42:23 +01003628 as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
paul718e3742002-12-13 20:15:29 +00003629 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003630 char *argstr;
3631
3632 if (argv == 0)
3633 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3634
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003635 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003636
3637 ret = inet_aton (argv[1], &address);
3638 if (ret == 0)
3639 {
3640 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3641 return CMD_WARNING;
3642 }
3643
3644 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3645 strlen (argv[0]) + strlen (argv[1]) + 2);
3646
3647 sprintf (argstr, "%s %s", argv[0], argv[1]);
3648
3649 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3650
3651 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3652
3653 return ret;
3654}
3655
3656ALIAS (no_set_aggregator_as,
3657 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003658 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003659 NO_STR
3660 SET_STR
3661 "BGP aggregator attribute\n"
3662 "AS number of aggregator\n"
3663 "AS number\n"
3664 "IP address of aggregator\n")
3665
paul718e3742002-12-13 20:15:29 +00003666DEFUN (match_ipv6_address,
3667 match_ipv6_address_cmd,
3668 "match ipv6 address WORD",
3669 MATCH_STR
3670 IPV6_STR
3671 "Match IPv6 address of route\n"
3672 "IPv6 access-list name\n")
3673{
3674 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3675}
3676
3677DEFUN (no_match_ipv6_address,
3678 no_match_ipv6_address_cmd,
3679 "no match ipv6 address WORD",
3680 NO_STR
3681 MATCH_STR
3682 IPV6_STR
3683 "Match IPv6 address of route\n"
3684 "IPv6 access-list name\n")
3685{
3686 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3687}
3688
3689DEFUN (match_ipv6_next_hop,
3690 match_ipv6_next_hop_cmd,
3691 "match ipv6 next-hop X:X::X:X",
3692 MATCH_STR
3693 IPV6_STR
3694 "Match IPv6 next-hop address of route\n"
3695 "IPv6 address of next hop\n")
3696{
3697 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3698}
3699
3700DEFUN (no_match_ipv6_next_hop,
3701 no_match_ipv6_next_hop_cmd,
3702 "no match ipv6 next-hop X:X::X:X",
3703 NO_STR
3704 MATCH_STR
3705 IPV6_STR
3706 "Match IPv6 next-hop address of route\n"
3707 "IPv6 address of next hop\n")
3708{
3709 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3710}
3711
3712DEFUN (match_ipv6_address_prefix_list,
3713 match_ipv6_address_prefix_list_cmd,
3714 "match ipv6 address prefix-list WORD",
3715 MATCH_STR
3716 IPV6_STR
3717 "Match address of route\n"
3718 "Match entries of prefix-lists\n"
3719 "IP prefix-list name\n")
3720{
3721 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3722}
3723
3724DEFUN (no_match_ipv6_address_prefix_list,
3725 no_match_ipv6_address_prefix_list_cmd,
3726 "no match ipv6 address prefix-list WORD",
3727 NO_STR
3728 MATCH_STR
3729 IPV6_STR
3730 "Match address of route\n"
3731 "Match entries of prefix-lists\n"
3732 "IP prefix-list name\n")
3733{
3734 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3735}
3736
Dinesh G Duttad5233a2014-09-30 14:19:57 -07003737DEFUN (set_ipv6_nexthop_peer,
3738 set_ipv6_nexthop_peer_cmd,
3739 "set ipv6 next-hop peer-address",
3740 SET_STR
3741 IPV6_STR
3742 "Next hop address\n"
3743 "Use peer address (for BGP only)\n")
3744{
3745 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop peer-address", NULL);
3746}
3747
3748DEFUN (no_set_ipv6_nexthop_peer,
3749 no_set_ipv6_nexthop_peer_cmd,
3750 "no set ipv6 next-hop peer-address",
3751 NO_STR
3752 SET_STR
3753 IPV6_STR
3754 "IPv6 next-hop address\n"
3755 )
3756{
3757 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3758}
3759
paul718e3742002-12-13 20:15:29 +00003760DEFUN (set_ipv6_nexthop_global,
3761 set_ipv6_nexthop_global_cmd,
3762 "set ipv6 next-hop global X:X::X:X",
3763 SET_STR
3764 IPV6_STR
3765 "IPv6 next-hop address\n"
3766 "IPv6 global address\n"
3767 "IPv6 address of next hop\n")
3768{
3769 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3770}
3771
3772DEFUN (no_set_ipv6_nexthop_global,
3773 no_set_ipv6_nexthop_global_cmd,
3774 "no set ipv6 next-hop global",
3775 NO_STR
3776 SET_STR
3777 IPV6_STR
3778 "IPv6 next-hop address\n"
3779 "IPv6 global address\n")
3780{
3781 if (argc == 0)
3782 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3783
3784 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3785}
3786
3787ALIAS (no_set_ipv6_nexthop_global,
3788 no_set_ipv6_nexthop_global_val_cmd,
3789 "no set ipv6 next-hop global X:X::X:X",
3790 NO_STR
3791 SET_STR
3792 IPV6_STR
3793 "IPv6 next-hop address\n"
3794 "IPv6 global address\n"
3795 "IPv6 address of next hop\n")
3796
3797DEFUN (set_ipv6_nexthop_local,
3798 set_ipv6_nexthop_local_cmd,
3799 "set ipv6 next-hop local X:X::X:X",
3800 SET_STR
3801 IPV6_STR
3802 "IPv6 next-hop address\n"
3803 "IPv6 local address\n"
3804 "IPv6 address of next hop\n")
3805{
3806 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3807}
3808
3809DEFUN (no_set_ipv6_nexthop_local,
3810 no_set_ipv6_nexthop_local_cmd,
3811 "no set ipv6 next-hop local",
3812 NO_STR
3813 SET_STR
3814 IPV6_STR
3815 "IPv6 next-hop address\n"
3816 "IPv6 local address\n")
3817{
3818 if (argc == 0)
3819 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3820
3821 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3822}
3823
3824ALIAS (no_set_ipv6_nexthop_local,
3825 no_set_ipv6_nexthop_local_val_cmd,
3826 "no set ipv6 next-hop local X:X::X:X",
3827 NO_STR
3828 SET_STR
3829 IPV6_STR
3830 "IPv6 next-hop address\n"
3831 "IPv6 local address\n"
3832 "IPv6 address of next hop\n")
paul718e3742002-12-13 20:15:29 +00003833
3834DEFUN (set_vpnv4_nexthop,
3835 set_vpnv4_nexthop_cmd,
3836 "set vpnv4 next-hop A.B.C.D",
3837 SET_STR
3838 "VPNv4 information\n"
3839 "VPNv4 next-hop address\n"
3840 "IP address of next hop\n")
3841{
3842 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3843}
3844
3845DEFUN (no_set_vpnv4_nexthop,
3846 no_set_vpnv4_nexthop_cmd,
3847 "no set vpnv4 next-hop",
3848 NO_STR
3849 SET_STR
3850 "VPNv4 information\n"
3851 "VPNv4 next-hop address\n")
3852{
3853 if (argc == 0)
3854 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3855
3856 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3857}
3858
3859ALIAS (no_set_vpnv4_nexthop,
3860 no_set_vpnv4_nexthop_val_cmd,
3861 "no set vpnv4 next-hop A.B.C.D",
3862 NO_STR
3863 SET_STR
3864 "VPNv4 information\n"
3865 "VPNv4 next-hop address\n"
3866 "IP address of next hop\n")
3867
3868DEFUN (set_originator_id,
3869 set_originator_id_cmd,
3870 "set originator-id A.B.C.D",
3871 SET_STR
3872 "BGP originator ID attribute\n"
3873 "IP address of originator\n")
3874{
3875 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3876}
3877
3878DEFUN (no_set_originator_id,
3879 no_set_originator_id_cmd,
3880 "no set originator-id",
3881 NO_STR
3882 SET_STR
3883 "BGP originator ID attribute\n")
3884{
3885 if (argc == 0)
3886 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3887
3888 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3889}
3890
3891ALIAS (no_set_originator_id,
3892 no_set_originator_id_val_cmd,
3893 "no set originator-id A.B.C.D",
3894 NO_STR
3895 SET_STR
3896 "BGP originator ID attribute\n"
3897 "IP address of originator\n")
3898
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003899DEFUN_DEPRECATED (set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003900 set_pathlimit_ttl_cmd,
3901 "set pathlimit ttl <1-255>",
3902 SET_STR
3903 "BGP AS-Pathlimit attribute\n"
3904 "Set AS-Path Hop-count TTL\n")
3905{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003906 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003907}
3908
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003909DEFUN_DEPRECATED (no_set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003910 no_set_pathlimit_ttl_cmd,
3911 "no set pathlimit ttl",
3912 NO_STR
3913 SET_STR
3914 "BGP AS-Pathlimit attribute\n"
3915 "Set AS-Path Hop-count TTL\n")
3916{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003917 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003918}
3919
3920ALIAS (no_set_pathlimit_ttl,
3921 no_set_pathlimit_ttl_val_cmd,
3922 "no set pathlimit ttl <1-255>",
3923 NO_STR
3924 MATCH_STR
3925 "BGP AS-Pathlimit attribute\n"
3926 "Set AS-Path Hop-count TTL\n")
3927
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003928DEFUN_DEPRECATED (match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003929 match_pathlimit_as_cmd,
3930 "match pathlimit as <1-65535>",
3931 MATCH_STR
3932 "BGP AS-Pathlimit attribute\n"
3933 "Match Pathlimit AS number\n")
3934{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003935 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003936}
3937
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003938DEFUN_DEPRECATED (no_match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003939 no_match_pathlimit_as_cmd,
3940 "no match pathlimit as",
3941 NO_STR
3942 MATCH_STR
3943 "BGP AS-Pathlimit attribute\n"
3944 "Match Pathlimit AS number\n")
3945{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003946 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003947}
3948
3949ALIAS (no_match_pathlimit_as,
3950 no_match_pathlimit_as_val_cmd,
3951 "no match pathlimit as <1-65535>",
3952 NO_STR
3953 MATCH_STR
3954 "BGP AS-Pathlimit attribute\n"
3955 "Match Pathlimit ASN\n")
3956
David Lamparter6b0655a2014-06-04 06:53:35 +02003957
paul718e3742002-12-13 20:15:29 +00003958/* Initialization of route map. */
3959void
paul94f2b392005-06-28 12:44:16 +00003960bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003961{
3962 route_map_init ();
3963 route_map_init_vty ();
3964 route_map_add_hook (bgp_route_map_update);
3965 route_map_delete_hook (bgp_route_map_update);
3966
paulfee0f4c2004-09-13 05:12:46 +00003967 route_map_install_match (&route_match_peer_cmd);
Dinesh Dutt5cf768a2015-11-09 20:21:53 -05003968 route_map_install_match (&route_match_local_pref_cmd);
paul718e3742002-12-13 20:15:29 +00003969 route_map_install_match (&route_match_ip_address_cmd);
3970 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003971 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003972 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3973 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003974 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003975 route_map_install_match (&route_match_aspath_cmd);
3976 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003977 route_map_install_match (&route_match_ecommunity_cmd);
Dinesh Dutt5cf768a2015-11-09 20:21:53 -05003978 route_map_install_match (&route_match_local_pref_cmd);
paul718e3742002-12-13 20:15:29 +00003979 route_map_install_match (&route_match_metric_cmd);
3980 route_map_install_match (&route_match_origin_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003981 route_map_install_match (&route_match_probability_cmd);
paul718e3742002-12-13 20:15:29 +00003982
3983 route_map_install_set (&route_set_ip_nexthop_cmd);
3984 route_map_install_set (&route_set_local_pref_cmd);
3985 route_map_install_set (&route_set_weight_cmd);
3986 route_map_install_set (&route_set_metric_cmd);
3987 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003988 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003989 route_map_install_set (&route_set_origin_cmd);
3990 route_map_install_set (&route_set_atomic_aggregate_cmd);
3991 route_map_install_set (&route_set_aggregator_as_cmd);
3992 route_map_install_set (&route_set_community_cmd);
3993 route_map_install_set (&route_set_community_delete_cmd);
3994 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3995 route_map_install_set (&route_set_originator_id_cmd);
3996 route_map_install_set (&route_set_ecommunity_rt_cmd);
3997 route_map_install_set (&route_set_ecommunity_soo_cmd);
3998
paulfee0f4c2004-09-13 05:12:46 +00003999 install_element (RMAP_NODE, &match_peer_cmd);
4000 install_element (RMAP_NODE, &match_peer_local_cmd);
4001 install_element (RMAP_NODE, &no_match_peer_cmd);
4002 install_element (RMAP_NODE, &no_match_peer_val_cmd);
4003 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00004004 install_element (RMAP_NODE, &match_ip_address_cmd);
4005 install_element (RMAP_NODE, &no_match_ip_address_cmd);
4006 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
4007 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
4008 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
4009 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00004010 install_element (RMAP_NODE, &match_ip_route_source_cmd);
4011 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
4012 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00004013 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
4014 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
4015 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
4016 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
4017 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
4018 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00004019 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
4020 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
4021 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00004022
4023 install_element (RMAP_NODE, &match_aspath_cmd);
4024 install_element (RMAP_NODE, &no_match_aspath_cmd);
4025 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
4026 install_element (RMAP_NODE, &match_metric_cmd);
4027 install_element (RMAP_NODE, &no_match_metric_cmd);
4028 install_element (RMAP_NODE, &no_match_metric_val_cmd);
Dinesh Dutt5cf768a2015-11-09 20:21:53 -05004029 install_element (RMAP_NODE, &match_local_pref_cmd);
4030 install_element (RMAP_NODE, &no_match_local_pref_cmd);
4031 install_element (RMAP_NODE, &no_match_local_pref_val_cmd);
paul718e3742002-12-13 20:15:29 +00004032 install_element (RMAP_NODE, &match_community_cmd);
4033 install_element (RMAP_NODE, &match_community_exact_cmd);
4034 install_element (RMAP_NODE, &no_match_community_cmd);
4035 install_element (RMAP_NODE, &no_match_community_val_cmd);
4036 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00004037 install_element (RMAP_NODE, &match_ecommunity_cmd);
4038 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
4039 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00004040 install_element (RMAP_NODE, &match_origin_cmd);
4041 install_element (RMAP_NODE, &no_match_origin_cmd);
4042 install_element (RMAP_NODE, &no_match_origin_val_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04004043 install_element (RMAP_NODE, &match_probability_cmd);
4044 install_element (RMAP_NODE, &no_match_probability_cmd);
4045 install_element (RMAP_NODE, &no_match_probability_val_cmd);
paul718e3742002-12-13 20:15:29 +00004046
4047 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00004048 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00004049 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
4050 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
4051 install_element (RMAP_NODE, &set_local_pref_cmd);
4052 install_element (RMAP_NODE, &no_set_local_pref_cmd);
4053 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
4054 install_element (RMAP_NODE, &set_weight_cmd);
4055 install_element (RMAP_NODE, &no_set_weight_cmd);
4056 install_element (RMAP_NODE, &no_set_weight_val_cmd);
4057 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00004058 install_element (RMAP_NODE, &set_metric_addsub_cmd);
Timo Teräsef757702015-04-29 09:43:04 +03004059 install_element (RMAP_NODE, &set_metric_rtt_cmd);
paul718e3742002-12-13 20:15:29 +00004060 install_element (RMAP_NODE, &no_set_metric_cmd);
4061 install_element (RMAP_NODE, &no_set_metric_val_cmd);
4062 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Timo Teräs85c854a2014-09-30 11:31:53 +03004063 install_element (RMAP_NODE, &set_aspath_prepend_lastas_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00004064 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00004065 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
4066 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00004067 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
4068 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00004069 install_element (RMAP_NODE, &set_origin_cmd);
4070 install_element (RMAP_NODE, &no_set_origin_cmd);
4071 install_element (RMAP_NODE, &no_set_origin_val_cmd);
4072 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
4073 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
4074 install_element (RMAP_NODE, &set_aggregator_as_cmd);
4075 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
4076 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
4077 install_element (RMAP_NODE, &set_community_cmd);
4078 install_element (RMAP_NODE, &set_community_none_cmd);
4079 install_element (RMAP_NODE, &no_set_community_cmd);
4080 install_element (RMAP_NODE, &no_set_community_val_cmd);
4081 install_element (RMAP_NODE, &no_set_community_none_cmd);
4082 install_element (RMAP_NODE, &set_community_delete_cmd);
4083 install_element (RMAP_NODE, &no_set_community_delete_cmd);
4084 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
4085 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
4086 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
4087 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
4088 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
4089 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
4090 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
4091 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
4092 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
4093 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
4094 install_element (RMAP_NODE, &set_originator_id_cmd);
4095 install_element (RMAP_NODE, &no_set_originator_id_cmd);
4096 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
4097
paul718e3742002-12-13 20:15:29 +00004098 route_map_install_match (&route_match_ipv6_address_cmd);
4099 route_map_install_match (&route_match_ipv6_next_hop_cmd);
4100 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
4101 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
4102 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Dinesh G Duttad5233a2014-09-30 14:19:57 -07004103 route_map_install_set (&route_set_ipv6_nexthop_peer_cmd);
4104
paul718e3742002-12-13 20:15:29 +00004105 install_element (RMAP_NODE, &match_ipv6_address_cmd);
4106 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
4107 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
4108 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
4109 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
4110 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
4111 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
4112 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
4113 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
4114 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
4115 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
4116 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
Dinesh G Duttad5233a2014-09-30 14:19:57 -07004117 install_element (RMAP_NODE, &set_ipv6_nexthop_peer_cmd);
4118 install_element (RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd);
Paul Jakma41367172007-08-06 15:24:51 +00004119
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004120 /* AS-Pathlimit: functionality removed, commands kept for
4121 * compatibility.
4122 */
Paul Jakma41367172007-08-06 15:24:51 +00004123 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
4124 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
4125 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
4126 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
4127 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
4128 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00004129}