blob: 68c78458ece653fcb50d97d189a4cccaa16e7c23 [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)
Piotr Chytła605aa332015-12-01 10:03:54 -050074 tag : Done
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
Piotr Chytła605aa332015-12-01 10:03:54 -050094 tag : Done
paul718e3742002-12-13 20:15:29 +000095 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
Piotr Chytła605aa332015-12-01 10:03:54 -05001007/* Match function return 1 if match is success else return zero. */
1008static route_map_result_t
1009route_match_tag (void *rule, struct prefix *prefix,
1010 route_map_object_t type, void *object)
1011{
Paul Jakma96d10602016-07-01 14:23:45 +01001012 route_tag_t *tag;
Piotr Chytła605aa332015-12-01 10:03:54 -05001013 struct bgp_info *bgp_info;
1014
1015 if (type == RMAP_BGP)
1016 {
1017 tag = rule;
1018 bgp_info = object;
1019
1020 if (!bgp_info->attr->extra)
1021 return RMAP_NOMATCH;
1022
1023 return ((bgp_info->attr->extra->tag == *tag)? RMAP_MATCH : RMAP_NOMATCH);
1024 }
1025
1026 return RMAP_NOMATCH;
1027}
1028
Piotr Chytła605aa332015-12-01 10:03:54 -05001029/* Route map commands for tag matching. */
Christian Frankeddc160c2016-10-01 20:42:34 +02001030static struct route_map_rule_cmd route_match_tag_cmd =
Piotr Chytła605aa332015-12-01 10:03:54 -05001031{
1032 "tag",
1033 route_match_tag,
Christian Frankeddc160c2016-10-01 20:42:34 +02001034 route_map_rule_tag_compile,
1035 route_map_rule_tag_free,
Piotr Chytła605aa332015-12-01 10:03:54 -05001036};
1037
1038
paul718e3742002-12-13 20:15:29 +00001039/* Set nexthop to object. ojbect must be pointer to struct attr. */
paulac41b2a2003-08-12 05:32:27 +00001040struct rmap_ip_nexthop_set
1041{
1042 struct in_addr *address;
1043 int peer_address;
1044};
1045
paul94f2b392005-06-28 12:44:16 +00001046static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001047route_set_ip_nexthop (void *rule, struct prefix *prefix,
1048 route_map_object_t type, void *object)
1049{
paulac41b2a2003-08-12 05:32:27 +00001050 struct rmap_ip_nexthop_set *rins = rule;
paul718e3742002-12-13 20:15:29 +00001051 struct bgp_info *bgp_info;
paulac41b2a2003-08-12 05:32:27 +00001052 struct peer *peer;
paul718e3742002-12-13 20:15:29 +00001053
1054 if (type == RMAP_BGP)
1055 {
paul718e3742002-12-13 20:15:29 +00001056 bgp_info = object;
paulac41b2a2003-08-12 05:32:27 +00001057 peer = bgp_info->peer;
1058
1059 if (rins->peer_address)
1060 {
paulfee0f4c2004-09-13 05:12:46 +00001061 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
1062 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
paulac41b2a2003-08-12 05:32:27 +00001063 && peer->su_remote
1064 && sockunion_family (peer->su_remote) == AF_INET)
1065 {
Jorge Boncompte [DTI2]0c5ed3e2012-04-10 16:57:22 +02001066 bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote);
paulac41b2a2003-08-12 05:32:27 +00001067 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
1068 }
1069 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
1070 && peer->su_local
1071 && sockunion_family (peer->su_local) == AF_INET)
1072 {
Jorge Boncompte [DTI2]0c5ed3e2012-04-10 16:57:22 +02001073 bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_local);
paulac41b2a2003-08-12 05:32:27 +00001074 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
1075 }
1076 }
1077 else
1078 {
1079 /* Set next hop value. */
1080 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
1081 bgp_info->attr->nexthop = *rins->address;
1082 }
paul718e3742002-12-13 20:15:29 +00001083 }
1084
1085 return RMAP_OKAY;
1086}
1087
1088/* Route map `ip nexthop' compile function. Given string is converted
1089 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001090static void *
paulfd79ac92004-10-13 05:06:08 +00001091route_set_ip_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001092{
paulac41b2a2003-08-12 05:32:27 +00001093 struct rmap_ip_nexthop_set *rins;
1094 struct in_addr *address = NULL;
1095 int peer_address = 0;
paul718e3742002-12-13 20:15:29 +00001096 int ret;
paul718e3742002-12-13 20:15:29 +00001097
paulac41b2a2003-08-12 05:32:27 +00001098 if (strcmp (arg, "peer-address") == 0)
1099 peer_address = 1;
1100 else
paul718e3742002-12-13 20:15:29 +00001101 {
paulac41b2a2003-08-12 05:32:27 +00001102 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
1103 ret = inet_aton (arg, address);
1104
1105 if (ret == 0)
1106 {
1107 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1108 return NULL;
1109 }
paul718e3742002-12-13 20:15:29 +00001110 }
1111
Stephen Hemminger393deb92008-08-18 14:13:29 -07001112 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
paulac41b2a2003-08-12 05:32:27 +00001113
1114 rins->address = address;
1115 rins->peer_address = peer_address;
1116
1117 return rins;
paul718e3742002-12-13 20:15:29 +00001118}
1119
1120/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00001121static void
paul718e3742002-12-13 20:15:29 +00001122route_set_ip_nexthop_free (void *rule)
1123{
paulac41b2a2003-08-12 05:32:27 +00001124 struct rmap_ip_nexthop_set *rins = rule;
1125
1126 if (rins->address)
1127 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
1128
1129 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +00001130}
1131
1132/* Route map commands for ip nexthop set. */
1133struct route_map_rule_cmd route_set_ip_nexthop_cmd =
1134{
1135 "ip next-hop",
1136 route_set_ip_nexthop,
1137 route_set_ip_nexthop_compile,
1138 route_set_ip_nexthop_free
1139};
David Lamparter6b0655a2014-06-04 06:53:35 +02001140
paul718e3742002-12-13 20:15:29 +00001141/* `set local-preference LOCAL_PREF' */
1142
1143/* Set local preference. */
paul94f2b392005-06-28 12:44:16 +00001144static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001145route_set_local_pref (void *rule, struct prefix *prefix,
1146 route_map_object_t type, void *object)
1147{
Timo Teräs38f22ab2015-04-29 09:43:02 +03001148 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +00001149 struct bgp_info *bgp_info;
Timo Teräs38f22ab2015-04-29 09:43:02 +03001150 u_int32_t locpref = 0;
paul718e3742002-12-13 20:15:29 +00001151
1152 if (type == RMAP_BGP)
1153 {
1154 /* Fetch routemap's rule information. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001155 rv = rule;
paul718e3742002-12-13 20:15:29 +00001156 bgp_info = object;
1157
1158 /* Set local preference value. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001159 if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
1160 locpref = bgp_info->attr->local_pref;
1161
paul718e3742002-12-13 20:15:29 +00001162 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
Timo Teräsef757702015-04-29 09:43:04 +03001163 bgp_info->attr->local_pref = route_value_adjust(rv, locpref, bgp_info->peer);
paul718e3742002-12-13 20:15:29 +00001164 }
1165
1166 return RMAP_OKAY;
1167}
1168
paul718e3742002-12-13 20:15:29 +00001169/* Set local preference rule structure. */
1170struct route_map_rule_cmd route_set_local_pref_cmd =
1171{
1172 "local-preference",
1173 route_set_local_pref,
Timo Teräs38f22ab2015-04-29 09:43:02 +03001174 route_value_compile,
1175 route_value_free,
paul718e3742002-12-13 20:15:29 +00001176};
David Lamparter6b0655a2014-06-04 06:53:35 +02001177
paul718e3742002-12-13 20:15:29 +00001178/* `set weight WEIGHT' */
1179
1180/* Set weight. */
paul94f2b392005-06-28 12:44:16 +00001181static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001182route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
1183 void *object)
1184{
Timo Teräs38f22ab2015-04-29 09:43:02 +03001185 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +00001186 struct bgp_info *bgp_info;
Timo Teräs38f22ab2015-04-29 09:43:02 +03001187 u_int32_t weight;
paul718e3742002-12-13 20:15:29 +00001188
1189 if (type == RMAP_BGP)
1190 {
1191 /* Fetch routemap's rule information. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001192 rv = rule;
paul718e3742002-12-13 20:15:29 +00001193 bgp_info = object;
1194
1195 /* Set weight value. */
Timo Teräsef757702015-04-29 09:43:04 +03001196 weight = route_value_adjust(rv, 0, bgp_info->peer);
Timo Teräs38f22ab2015-04-29 09:43:02 +03001197 if (weight)
1198 (bgp_attr_extra_get (bgp_info->attr))->weight = weight;
Paul Jakmafb982c22007-05-04 20:15:47 +00001199 else if (bgp_info->attr->extra)
1200 bgp_info->attr->extra->weight = 0;
paul718e3742002-12-13 20:15:29 +00001201 }
1202
1203 return RMAP_OKAY;
1204}
1205
paul718e3742002-12-13 20:15:29 +00001206/* Set local preference rule structure. */
1207struct route_map_rule_cmd route_set_weight_cmd =
1208{
1209 "weight",
1210 route_set_weight,
Timo Teräs38f22ab2015-04-29 09:43:02 +03001211 route_value_compile,
1212 route_value_free,
paul718e3742002-12-13 20:15:29 +00001213};
David Lamparter6b0655a2014-06-04 06:53:35 +02001214
paul718e3742002-12-13 20:15:29 +00001215/* `set metric METRIC' */
1216
1217/* Set metric to attribute. */
paul94f2b392005-06-28 12:44:16 +00001218static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001219route_set_metric (void *rule, struct prefix *prefix,
1220 route_map_object_t type, void *object)
1221{
Timo Teräs38f22ab2015-04-29 09:43:02 +03001222 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +00001223 struct bgp_info *bgp_info;
Timo Teräs38f22ab2015-04-29 09:43:02 +03001224 u_int32_t med = 0;
paul718e3742002-12-13 20:15:29 +00001225
1226 if (type == RMAP_BGP)
1227 {
1228 /* Fetch routemap's rule information. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001229 rv = rule;
paul718e3742002-12-13 20:15:29 +00001230 bgp_info = object;
1231
Timo Teräs38f22ab2015-04-29 09:43:02 +03001232 if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
1233 med = bgp_info->attr->med;
1234
Timo Teräsef757702015-04-29 09:43:04 +03001235 bgp_info->attr->med = route_value_adjust(rv, med, bgp_info->peer);
paul718e3742002-12-13 20:15:29 +00001236 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
paul718e3742002-12-13 20:15:29 +00001237 }
1238 return RMAP_OKAY;
1239}
1240
paul718e3742002-12-13 20:15:29 +00001241/* Set metric rule structure. */
1242struct route_map_rule_cmd route_set_metric_cmd =
1243{
1244 "metric",
1245 route_set_metric,
Timo Teräs38f22ab2015-04-29 09:43:02 +03001246 route_value_compile,
1247 route_value_free,
paul718e3742002-12-13 20:15:29 +00001248};
David Lamparter6b0655a2014-06-04 06:53:35 +02001249
paul718e3742002-12-13 20:15:29 +00001250/* `set as-path prepend ASPATH' */
1251
1252/* For AS path prepend mechanism. */
paul94f2b392005-06-28 12:44:16 +00001253static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001254route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1255{
1256 struct aspath *aspath;
1257 struct aspath *new;
1258 struct bgp_info *binfo;
1259
1260 if (type == RMAP_BGP)
1261 {
paul718e3742002-12-13 20:15:29 +00001262 binfo = object;
1263
1264 if (binfo->attr->aspath->refcnt)
1265 new = aspath_dup (binfo->attr->aspath);
1266 else
1267 new = binfo->attr->aspath;
1268
Timo Teräs85c854a2014-09-30 11:31:53 +03001269 if ((uintptr_t)rule > 10)
1270 {
1271 aspath = rule;
1272 aspath_prepend (aspath, new);
1273 }
1274 else
1275 {
1276 as_t as = aspath_leftmost(new);
1277 if (!as) as = binfo->peer->as;
1278 new = aspath_add_seq_n (new, as, (uintptr_t) rule);
1279 }
1280
paul718e3742002-12-13 20:15:29 +00001281 binfo->attr->aspath = new;
1282 }
1283
1284 return RMAP_OKAY;
1285}
1286
Timo Teräs85c854a2014-09-30 11:31:53 +03001287static void *
1288route_set_aspath_prepend_compile (const char *arg)
1289{
1290 unsigned int num;
1291
1292 if (sscanf(arg, "last-as %u", &num) == 1 && num > 0 && num < 10)
1293 return (void*)(uintptr_t)num;
1294
1295 return route_aspath_compile(arg);
1296}
1297
1298static void
1299route_set_aspath_prepend_free (void *rule)
1300{
1301 if ((uintptr_t)rule > 10)
1302 route_aspath_free(rule);
1303}
1304
1305
Timo Teräs2aa640b2014-05-20 08:57:26 +03001306/* Set as-path prepend rule structure. */
paul718e3742002-12-13 20:15:29 +00001307struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1308{
1309 "as-path prepend",
1310 route_set_aspath_prepend,
Timo Teräs85c854a2014-09-30 11:31:53 +03001311 route_set_aspath_prepend_compile,
1312 route_set_aspath_prepend_free,
paul718e3742002-12-13 20:15:29 +00001313};
David Lamparter6b0655a2014-06-04 06:53:35 +02001314
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001315/* `set as-path exclude ASn' */
1316
1317/* For ASN exclude mechanism.
1318 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1319 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1320 */
1321static route_map_result_t
1322route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
1323{
1324 struct aspath * new_path, * exclude_path;
1325 struct bgp_info *binfo;
1326
1327 if (type == RMAP_BGP)
1328 {
1329 exclude_path = rule;
1330 binfo = object;
1331 if (binfo->attr->aspath->refcnt)
1332 new_path = aspath_dup (binfo->attr->aspath);
1333 else
1334 new_path = binfo->attr->aspath;
1335 binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
1336 }
1337 return RMAP_OKAY;
1338}
1339
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001340/* Set ASn exlude rule structure. */
1341struct route_map_rule_cmd route_set_aspath_exclude_cmd =
1342{
1343 "as-path exclude",
1344 route_set_aspath_exclude,
Timo Teräsb304dcb2014-05-20 09:04:49 +03001345 route_aspath_compile,
1346 route_aspath_free,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001347};
David Lamparter6b0655a2014-06-04 06:53:35 +02001348
paul718e3742002-12-13 20:15:29 +00001349/* `set community COMMUNITY' */
1350struct rmap_com_set
1351{
1352 struct community *com;
1353 int additive;
1354 int none;
1355};
1356
1357/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001358static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001359route_set_community (void *rule, struct prefix *prefix,
1360 route_map_object_t type, void *object)
1361{
1362 struct rmap_com_set *rcs;
1363 struct bgp_info *binfo;
1364 struct attr *attr;
1365 struct community *new = NULL;
1366 struct community *old;
1367 struct community *merge;
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001368
paul718e3742002-12-13 20:15:29 +00001369 if (type == RMAP_BGP)
1370 {
1371 rcs = rule;
1372 binfo = object;
1373 attr = binfo->attr;
1374 old = attr->community;
1375
1376 /* "none" case. */
1377 if (rcs->none)
1378 {
1379 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1380 attr->community = NULL;
Christian Frankeb06b35f2012-12-07 14:26:09 +00001381 /* See the longer comment down below. */
1382 if (old && old->refcnt == 0)
1383 community_free(old);
paul718e3742002-12-13 20:15:29 +00001384 return RMAP_OKAY;
1385 }
1386
1387 /* "additive" case. */
1388 if (rcs->additive && old)
1389 {
1390 merge = community_merge (community_dup (old), rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001391
1392 /* HACK: if the old community is not intern'd,
1393 * we should free it here, or all reference to it may be lost.
1394 * Really need to cleanup attribute caching sometime.
1395 */
1396 if (old->refcnt == 0)
1397 community_free (old);
paul718e3742002-12-13 20:15:29 +00001398 new = community_uniq_sort (merge);
1399 community_free (merge);
1400 }
1401 else
1402 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001403
1404 /* will be interned by caller if required */
Paul Jakma4a2035f2011-04-01 15:58:27 +01001405 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001406
paul718e3742002-12-13 20:15:29 +00001407 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1408 }
1409
1410 return RMAP_OKAY;
1411}
1412
1413/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001414static void *
paulfd79ac92004-10-13 05:06:08 +00001415route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001416{
1417 struct rmap_com_set *rcs;
1418 struct community *com = NULL;
1419 char *sp;
1420 int additive = 0;
1421 int none = 0;
1422
1423 if (strcmp (arg, "none") == 0)
1424 none = 1;
1425 else
1426 {
1427 sp = strstr (arg, "additive");
1428
1429 if (sp && sp > arg)
1430 {
1431 /* "additive" keyworkd is included. */
1432 additive = 1;
1433 *(sp - 1) = '\0';
1434 }
1435
1436 com = community_str2com (arg);
1437
1438 if (additive)
1439 *(sp - 1) = ' ';
1440
1441 if (! com)
1442 return NULL;
1443 }
1444
Stephen Hemminger393deb92008-08-18 14:13:29 -07001445 rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
Paul Jakma4a2035f2011-04-01 15:58:27 +01001446 rcs->com = com;
paul718e3742002-12-13 20:15:29 +00001447 rcs->additive = additive;
1448 rcs->none = none;
1449
1450 return rcs;
1451}
1452
1453/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001454static void
paul718e3742002-12-13 20:15:29 +00001455route_set_community_free (void *rule)
1456{
1457 struct rmap_com_set *rcs = rule;
1458
1459 if (rcs->com)
1460 community_free (rcs->com);
1461 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1462}
1463
1464/* Set community rule structure. */
1465struct route_map_rule_cmd route_set_community_cmd =
1466{
1467 "community",
1468 route_set_community,
1469 route_set_community_compile,
1470 route_set_community_free,
1471};
David Lamparter6b0655a2014-06-04 06:53:35 +02001472
hassofee6e4e2005-02-02 16:29:31 +00001473/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001474
1475/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001476static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001477route_set_community_delete (void *rule, struct prefix *prefix,
1478 route_map_object_t type, void *object)
1479{
1480 struct community_list *list;
1481 struct community *merge;
1482 struct community *new;
1483 struct community *old;
1484 struct bgp_info *binfo;
1485
1486 if (type == RMAP_BGP)
1487 {
1488 if (! rule)
1489 return RMAP_OKAY;
1490
1491 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001492 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001493 old = binfo->attr->community;
1494
1495 if (list && old)
1496 {
1497 merge = community_list_match_delete (community_dup (old), list);
1498 new = community_uniq_sort (merge);
1499 community_free (merge);
1500
Michael Lambert604a9b42010-09-13 11:48:11 -04001501 /* HACK: if the old community is not intern'd,
1502 * we should free it here, or all reference to it may be lost.
1503 * Really need to cleanup attribute caching sometime.
1504 */
1505 if (old->refcnt == 0)
1506 community_free (old);
1507
paul718e3742002-12-13 20:15:29 +00001508 if (new->size == 0)
1509 {
1510 binfo->attr->community = NULL;
1511 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1512 community_free (new);
1513 }
1514 else
1515 {
Paul Jakma4a2035f2011-04-01 15:58:27 +01001516 binfo->attr->community = new;
paul718e3742002-12-13 20:15:29 +00001517 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1518 }
1519 }
1520 }
1521
1522 return RMAP_OKAY;
1523}
1524
1525/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001526static void *
paulfd79ac92004-10-13 05:06:08 +00001527route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001528{
1529 char *p;
1530 char *str;
1531 int len;
1532
1533 p = strchr (arg, ' ');
1534 if (p)
1535 {
1536 len = p - arg;
1537 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1538 memcpy (str, arg, len);
1539 }
1540 else
1541 str = NULL;
1542
1543 return str;
1544}
1545
1546/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001547static void
paul718e3742002-12-13 20:15:29 +00001548route_set_community_delete_free (void *rule)
1549{
1550 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1551}
1552
1553/* Set community rule structure. */
1554struct route_map_rule_cmd route_set_community_delete_cmd =
1555{
1556 "comm-list",
1557 route_set_community_delete,
1558 route_set_community_delete_compile,
1559 route_set_community_delete_free,
1560};
David Lamparter6b0655a2014-06-04 06:53:35 +02001561
paul718e3742002-12-13 20:15:29 +00001562/* `set extcommunity rt COMMUNITY' */
1563
David Lamparter73d78ea2014-06-04 00:58:47 +02001564/* For community set mechanism. Used by _rt and _soo. */
paul94f2b392005-06-28 12:44:16 +00001565static route_map_result_t
David Lamparter73d78ea2014-06-04 00:58:47 +02001566route_set_ecommunity (void *rule, struct prefix *prefix,
1567 route_map_object_t type, void *object)
paul718e3742002-12-13 20:15:29 +00001568{
1569 struct ecommunity *ecom;
1570 struct ecommunity *new_ecom;
1571 struct ecommunity *old_ecom;
1572 struct bgp_info *bgp_info;
1573
1574 if (type == RMAP_BGP)
1575 {
1576 ecom = rule;
1577 bgp_info = object;
1578
1579 if (! ecom)
1580 return RMAP_OKAY;
1581
1582 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001583 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001584
1585 if (old_ecom)
David Lamparter27bf90a2014-06-04 00:59:01 +02001586 {
1587 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1588
1589 /* old_ecom->refcnt = 1 => owned elsewhere, e.g. bgp_update_receive()
1590 * ->refcnt = 0 => set by a previous route-map statement */
1591 if (!old_ecom->refcnt)
1592 ecommunity_free (&old_ecom);
1593 }
paul718e3742002-12-13 20:15:29 +00001594 else
1595 new_ecom = ecommunity_dup (ecom);
1596
David Lamparter27bf90a2014-06-04 00:59:01 +02001597 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
1598 bgp_info->attr->extra->ecommunity = new_ecom;
hasso70601e02005-05-27 03:26:57 +00001599
paul718e3742002-12-13 20:15:29 +00001600 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1601 }
1602 return RMAP_OKAY;
1603}
1604
1605/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001606static void *
paulfd79ac92004-10-13 05:06:08 +00001607route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001608{
1609 struct ecommunity *ecom;
1610
1611 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1612 if (! ecom)
1613 return NULL;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001614 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001615}
1616
David Lamparter73d78ea2014-06-04 00:58:47 +02001617/* Free function for set community. Used by _rt and _soo */
paul94f2b392005-06-28 12:44:16 +00001618static void
David Lamparter73d78ea2014-06-04 00:58:47 +02001619route_set_ecommunity_free (void *rule)
paul718e3742002-12-13 20:15:29 +00001620{
1621 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001622 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001623}
1624
1625/* Set community rule structure. */
1626struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1627{
1628 "extcommunity rt",
David Lamparter73d78ea2014-06-04 00:58:47 +02001629 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001630 route_set_ecommunity_rt_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001631 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001632};
1633
1634/* `set extcommunity soo COMMUNITY' */
1635
paul718e3742002-12-13 20:15:29 +00001636/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001637static void *
paulfd79ac92004-10-13 05:06:08 +00001638route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001639{
1640 struct ecommunity *ecom;
1641
1642 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1643 if (! ecom)
1644 return NULL;
1645
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001646 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001647}
1648
paul718e3742002-12-13 20:15:29 +00001649/* Set community rule structure. */
1650struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1651{
1652 "extcommunity soo",
David Lamparter73d78ea2014-06-04 00:58:47 +02001653 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001654 route_set_ecommunity_soo_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001655 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001656};
David Lamparter6b0655a2014-06-04 06:53:35 +02001657
paul718e3742002-12-13 20:15:29 +00001658/* `set origin ORIGIN' */
1659
1660/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001661static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001662route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1663{
1664 u_char *origin;
1665 struct bgp_info *bgp_info;
1666
1667 if (type == RMAP_BGP)
1668 {
1669 origin = rule;
1670 bgp_info = object;
1671
1672 bgp_info->attr->origin = *origin;
1673 }
1674
1675 return RMAP_OKAY;
1676}
1677
1678/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001679static void *
paulfd79ac92004-10-13 05:06:08 +00001680route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001681{
1682 u_char *origin;
1683
1684 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1685
1686 if (strcmp (arg, "igp") == 0)
1687 *origin = 0;
1688 else if (strcmp (arg, "egp") == 0)
1689 *origin = 1;
1690 else
1691 *origin = 2;
1692
1693 return origin;
1694}
1695
1696/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001697static void
paul718e3742002-12-13 20:15:29 +00001698route_set_origin_free (void *rule)
1699{
1700 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1701}
1702
Timo Teräs2aa640b2014-05-20 08:57:26 +03001703/* Set origin rule structure. */
paul718e3742002-12-13 20:15:29 +00001704struct route_map_rule_cmd route_set_origin_cmd =
1705{
1706 "origin",
1707 route_set_origin,
1708 route_set_origin_compile,
1709 route_set_origin_free,
1710};
David Lamparter6b0655a2014-06-04 06:53:35 +02001711
paul718e3742002-12-13 20:15:29 +00001712/* `set atomic-aggregate' */
1713
1714/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001715static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001716route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1717 route_map_object_t type, void *object)
1718{
1719 struct bgp_info *bgp_info;
1720
1721 if (type == RMAP_BGP)
1722 {
1723 bgp_info = object;
1724 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1725 }
1726
1727 return RMAP_OKAY;
1728}
1729
1730/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001731static void *
paulfd79ac92004-10-13 05:06:08 +00001732route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001733{
1734 return (void *)1;
1735}
1736
1737/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001738static void
paul718e3742002-12-13 20:15:29 +00001739route_set_atomic_aggregate_free (void *rule)
1740{
1741 return;
1742}
1743
1744/* Set atomic aggregate rule structure. */
1745struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1746{
1747 "atomic-aggregate",
1748 route_set_atomic_aggregate,
1749 route_set_atomic_aggregate_compile,
1750 route_set_atomic_aggregate_free,
1751};
David Lamparter6b0655a2014-06-04 06:53:35 +02001752
paul718e3742002-12-13 20:15:29 +00001753/* `set aggregator as AS A.B.C.D' */
1754struct aggregator
1755{
1756 as_t as;
1757 struct in_addr address;
1758};
1759
paul94f2b392005-06-28 12:44:16 +00001760static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001761route_set_aggregator_as (void *rule, struct prefix *prefix,
1762 route_map_object_t type, void *object)
1763{
1764 struct bgp_info *bgp_info;
1765 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001766 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001767
1768 if (type == RMAP_BGP)
1769 {
1770 bgp_info = object;
1771 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001772 ae = bgp_attr_extra_get (bgp_info->attr);
1773
1774 ae->aggregator_as = aggregator->as;
1775 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001776 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1777 }
1778
1779 return RMAP_OKAY;
1780}
1781
paul94f2b392005-06-28 12:44:16 +00001782static void *
paulfd79ac92004-10-13 05:06:08 +00001783route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001784{
1785 struct aggregator *aggregator;
1786 char as[10];
1787 char address[20];
1788
Stephen Hemminger393deb92008-08-18 14:13:29 -07001789 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
paul718e3742002-12-13 20:15:29 +00001790 sscanf (arg, "%s %s", as, address);
1791
1792 aggregator->as = strtoul (as, NULL, 10);
1793 inet_aton (address, &aggregator->address);
1794
1795 return aggregator;
1796}
1797
paul94f2b392005-06-28 12:44:16 +00001798static void
paul718e3742002-12-13 20:15:29 +00001799route_set_aggregator_as_free (void *rule)
1800{
1801 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1802}
1803
1804struct route_map_rule_cmd route_set_aggregator_as_cmd =
1805{
1806 "aggregator as",
1807 route_set_aggregator_as,
1808 route_set_aggregator_as_compile,
1809 route_set_aggregator_as_free,
1810};
David Lamparter6b0655a2014-06-04 06:53:35 +02001811
Piotr Chytła605aa332015-12-01 10:03:54 -05001812/* Set tag to object. object must be pointer to struct bgp_info */
1813static route_map_result_t
1814route_set_tag (void *rule, struct prefix *prefix,
1815 route_map_object_t type, void *object)
1816{
Paul Jakma96d10602016-07-01 14:23:45 +01001817 route_tag_t *tag;
Piotr Chytła605aa332015-12-01 10:03:54 -05001818 struct bgp_info *bgp_info;
1819 struct attr_extra *ae;
1820
1821 if (type == RMAP_BGP)
1822 {
1823 tag = rule;
1824 bgp_info = object;
1825 ae = bgp_attr_extra_get (bgp_info->attr);
1826
1827 /* Set tag value */
1828 ae->tag=*tag;
1829
1830 }
1831
1832 return RMAP_OKAY;
1833}
1834
Piotr Chytła605aa332015-12-01 10:03:54 -05001835/* Route map commands for tag set. */
Christian Frankeddc160c2016-10-01 20:42:34 +02001836static struct route_map_rule_cmd route_set_tag_cmd =
Piotr Chytła605aa332015-12-01 10:03:54 -05001837{
1838 "tag",
1839 route_set_tag,
Christian Frankeddc160c2016-10-01 20:42:34 +02001840 route_map_rule_tag_compile,
1841 route_map_rule_tag_free,
Piotr Chytła605aa332015-12-01 10:03:54 -05001842};
1843
1844
paul718e3742002-12-13 20:15:29 +00001845/* `match ipv6 address IP_ACCESS_LIST' */
1846
paul94f2b392005-06-28 12:44:16 +00001847static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001848route_match_ipv6_address (void *rule, struct prefix *prefix,
1849 route_map_object_t type, void *object)
1850{
1851 struct access_list *alist;
1852
1853 if (type == RMAP_BGP)
1854 {
1855 alist = access_list_lookup (AFI_IP6, (char *) rule);
1856 if (alist == NULL)
1857 return RMAP_NOMATCH;
1858
1859 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1860 RMAP_NOMATCH : RMAP_MATCH);
1861 }
1862 return RMAP_NOMATCH;
1863}
1864
paul94f2b392005-06-28 12:44:16 +00001865static void *
paulfd79ac92004-10-13 05:06:08 +00001866route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001867{
1868 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1869}
1870
paul94f2b392005-06-28 12:44:16 +00001871static void
paul718e3742002-12-13 20:15:29 +00001872route_match_ipv6_address_free (void *rule)
1873{
1874 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1875}
1876
1877/* Route map commands for ip address matching. */
1878struct route_map_rule_cmd route_match_ipv6_address_cmd =
1879{
1880 "ipv6 address",
1881 route_match_ipv6_address,
1882 route_match_ipv6_address_compile,
1883 route_match_ipv6_address_free
1884};
David Lamparter6b0655a2014-06-04 06:53:35 +02001885
paul718e3742002-12-13 20:15:29 +00001886/* `match ipv6 next-hop IP_ADDRESS' */
1887
paul94f2b392005-06-28 12:44:16 +00001888static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001889route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1890 route_map_object_t type, void *object)
1891{
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001892 struct in6_addr *addr = rule;
paul718e3742002-12-13 20:15:29 +00001893 struct bgp_info *bgp_info;
1894
1895 if (type == RMAP_BGP)
1896 {
paul718e3742002-12-13 20:15:29 +00001897 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001898
1899 if (!bgp_info->attr->extra)
1900 return RMAP_NOMATCH;
1901
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001902 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, addr))
paul718e3742002-12-13 20:15:29 +00001903 return RMAP_MATCH;
1904
Paul Jakmafb982c22007-05-04 20:15:47 +00001905 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001906 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, addr))
paul718e3742002-12-13 20:15:29 +00001907 return RMAP_MATCH;
1908
1909 return RMAP_NOMATCH;
1910 }
1911
1912 return RMAP_NOMATCH;
1913}
1914
paul94f2b392005-06-28 12:44:16 +00001915static void *
paulfd79ac92004-10-13 05:06:08 +00001916route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001917{
1918 struct in6_addr *address;
1919 int ret;
1920
1921 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1922
1923 ret = inet_pton (AF_INET6, arg, address);
1924 if (!ret)
1925 {
1926 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1927 return NULL;
1928 }
1929
1930 return address;
1931}
1932
paul94f2b392005-06-28 12:44:16 +00001933static void
paul718e3742002-12-13 20:15:29 +00001934route_match_ipv6_next_hop_free (void *rule)
1935{
1936 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1937}
1938
1939struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1940{
1941 "ipv6 next-hop",
1942 route_match_ipv6_next_hop,
1943 route_match_ipv6_next_hop_compile,
1944 route_match_ipv6_next_hop_free
1945};
David Lamparter6b0655a2014-06-04 06:53:35 +02001946
paul718e3742002-12-13 20:15:29 +00001947/* `match ipv6 address prefix-list PREFIX_LIST' */
1948
paul94f2b392005-06-28 12:44:16 +00001949static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001950route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1951 route_map_object_t type, void *object)
1952{
1953 struct prefix_list *plist;
1954
1955 if (type == RMAP_BGP)
1956 {
1957 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1958 if (plist == NULL)
1959 return RMAP_NOMATCH;
1960
1961 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1962 RMAP_NOMATCH : RMAP_MATCH);
1963 }
1964 return RMAP_NOMATCH;
1965}
1966
paul94f2b392005-06-28 12:44:16 +00001967static void *
paulfd79ac92004-10-13 05:06:08 +00001968route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001969{
1970 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1971}
1972
paul94f2b392005-06-28 12:44:16 +00001973static void
paul718e3742002-12-13 20:15:29 +00001974route_match_ipv6_address_prefix_list_free (void *rule)
1975{
1976 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1977}
1978
1979struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1980{
1981 "ipv6 address prefix-list",
1982 route_match_ipv6_address_prefix_list,
1983 route_match_ipv6_address_prefix_list_compile,
1984 route_match_ipv6_address_prefix_list_free
1985};
David Lamparter6b0655a2014-06-04 06:53:35 +02001986
paul718e3742002-12-13 20:15:29 +00001987/* `set ipv6 nexthop global IP_ADDRESS' */
1988
1989/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001990static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001991route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1992 route_map_object_t type, void *object)
1993{
1994 struct in6_addr *address;
1995 struct bgp_info *bgp_info;
1996
1997 if (type == RMAP_BGP)
1998 {
1999 /* Fetch routemap's rule information. */
2000 address = rule;
2001 bgp_info = object;
2002
2003 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002004 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00002005
2006 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002007 if (bgp_info->attr->extra->mp_nexthop_len == 0)
2008 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00002009 }
2010
2011 return RMAP_OKAY;
2012}
2013
2014/* Route map `ip next-hop' compile function. Given string is converted
2015 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00002016static void *
paulfd79ac92004-10-13 05:06:08 +00002017route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002018{
2019 int ret;
2020 struct in6_addr *address;
2021
2022 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2023
2024 ret = inet_pton (AF_INET6, arg, address);
2025
2026 if (ret == 0)
2027 {
2028 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2029 return NULL;
2030 }
2031
2032 return address;
2033}
2034
2035/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00002036static void
paul718e3742002-12-13 20:15:29 +00002037route_set_ipv6_nexthop_global_free (void *rule)
2038{
2039 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2040}
2041
2042/* Route map commands for ip nexthop set. */
2043struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
2044{
2045 "ipv6 next-hop global",
2046 route_set_ipv6_nexthop_global,
2047 route_set_ipv6_nexthop_global_compile,
2048 route_set_ipv6_nexthop_global_free
2049};
David Lamparter6b0655a2014-06-04 06:53:35 +02002050
paul718e3742002-12-13 20:15:29 +00002051/* `set ipv6 nexthop local IP_ADDRESS' */
2052
2053/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00002054static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002055route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
2056 route_map_object_t type, void *object)
2057{
2058 struct in6_addr *address;
2059 struct bgp_info *bgp_info;
2060
2061 if (type == RMAP_BGP)
2062 {
2063 /* Fetch routemap's rule information. */
2064 address = rule;
2065 bgp_info = object;
2066
2067 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002068 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00002069
2070 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002071 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2072 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00002073 }
2074
2075 return RMAP_OKAY;
2076}
2077
2078/* Route map `ip nexthop' compile function. Given string is converted
2079 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00002080static void *
paulfd79ac92004-10-13 05:06:08 +00002081route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002082{
2083 int ret;
2084 struct in6_addr *address;
2085
2086 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2087
2088 ret = inet_pton (AF_INET6, arg, address);
2089
2090 if (ret == 0)
2091 {
2092 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2093 return NULL;
2094 }
2095
2096 return address;
2097}
2098
2099/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00002100static void
paul718e3742002-12-13 20:15:29 +00002101route_set_ipv6_nexthop_local_free (void *rule)
2102{
2103 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2104}
2105
2106/* Route map commands for ip nexthop set. */
2107struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
2108{
2109 "ipv6 next-hop local",
2110 route_set_ipv6_nexthop_local,
2111 route_set_ipv6_nexthop_local_compile,
2112 route_set_ipv6_nexthop_local_free
2113};
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002114
2115/* `set ipv6 nexthop peer-address' */
2116
2117/* Set nexthop to object. ojbect must be pointer to struct attr. */
2118static route_map_result_t
2119route_set_ipv6_nexthop_peer (void *rule, struct prefix *prefix,
2120 route_map_object_t type, void *object)
2121{
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002122 struct in6_addr peer_address;
2123 struct bgp_info *bgp_info;
2124 struct peer *peer;
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002125
2126 if (type == RMAP_BGP)
2127 {
2128 /* Fetch routemap's rule information. */
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002129 bgp_info = object;
2130 peer = bgp_info->peer;
2131
2132 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
2133 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
2134 && peer->su_remote
2135 && sockunion_family (peer->su_remote) == AF_INET6)
2136 {
Christian Franke5cb81ce2016-06-14 20:06:56 +02002137 peer_address = peer->su_remote->sin6.sin6_addr;
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002138 }
2139 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
2140 && peer->su_local
2141 && sockunion_family (peer->su_local) == AF_INET6)
2142 {
Christian Franke5cb81ce2016-06-14 20:06:56 +02002143 peer_address = peer->su_local->sin6.sin6_addr;
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002144 }
2145
2146 if (IN6_IS_ADDR_LINKLOCAL(&peer_address))
2147 {
2148 /* Set next hop value. */
2149 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = peer_address;
2150
2151 /* Set nexthop length. */
2152 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2153 bgp_info->attr->extra->mp_nexthop_len = 32;
2154 }
2155 else
2156 {
2157 /* Set next hop value. */
2158 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = peer_address;
2159
2160 /* Set nexthop length. */
2161 if (bgp_info->attr->extra->mp_nexthop_len == 0)
2162 bgp_info->attr->extra->mp_nexthop_len = 16;
2163 }
2164 }
2165
2166 return RMAP_OKAY;
2167}
2168
2169/* Route map `ip next-hop' compile function. Given string is converted
2170 to struct in_addr structure. */
2171static void *
2172route_set_ipv6_nexthop_peer_compile (const char *arg)
2173{
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002174 int *rins = NULL;
2175
2176 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (int));
2177 *rins = 1;
2178
2179 return rins;
2180}
2181
2182/* Free route map's compiled `ip next-hop' value. */
2183static void
2184route_set_ipv6_nexthop_peer_free (void *rule)
2185{
2186 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2187}
2188
2189/* Route map commands for ip nexthop set. */
2190struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd =
2191{
2192 "ipv6 next-hop peer-address",
2193 route_set_ipv6_nexthop_peer,
2194 route_set_ipv6_nexthop_peer_compile,
2195 route_set_ipv6_nexthop_peer_free
2196};
2197
paul718e3742002-12-13 20:15:29 +00002198/* `set vpnv4 nexthop A.B.C.D' */
2199
paul94f2b392005-06-28 12:44:16 +00002200static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002201route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2202 route_map_object_t type, void *object)
2203{
2204 struct in_addr *address;
2205 struct bgp_info *bgp_info;
2206
2207 if (type == RMAP_BGP)
2208 {
2209 /* Fetch routemap's rule information. */
2210 address = rule;
2211 bgp_info = object;
2212
2213 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002214 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
Lou Berger050defe2016-01-12 13:41:59 -05002215 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_len = 4;
paul718e3742002-12-13 20:15:29 +00002216 }
2217
2218 return RMAP_OKAY;
2219}
2220
paul94f2b392005-06-28 12:44:16 +00002221static void *
paulfd79ac92004-10-13 05:06:08 +00002222route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002223{
2224 int ret;
2225 struct in_addr *address;
2226
2227 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2228
2229 ret = inet_aton (arg, address);
2230
2231 if (ret == 0)
2232 {
2233 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2234 return NULL;
2235 }
2236
2237 return address;
2238}
2239
paul94f2b392005-06-28 12:44:16 +00002240static void
paul718e3742002-12-13 20:15:29 +00002241route_set_vpnv4_nexthop_free (void *rule)
2242{
2243 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2244}
2245
2246/* Route map commands for ip nexthop set. */
2247struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2248{
2249 "vpnv4 next-hop",
2250 route_set_vpnv4_nexthop,
2251 route_set_vpnv4_nexthop_compile,
2252 route_set_vpnv4_nexthop_free
2253};
David Lamparter6b0655a2014-06-04 06:53:35 +02002254
paul718e3742002-12-13 20:15:29 +00002255/* `set originator-id' */
2256
2257/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002258static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002259route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2260{
2261 struct in_addr *address;
2262 struct bgp_info *bgp_info;
2263
2264 if (type == RMAP_BGP)
2265 {
2266 address = rule;
2267 bgp_info = object;
2268
2269 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002270 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002271 }
2272
2273 return RMAP_OKAY;
2274}
2275
2276/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002277static void *
paulfd79ac92004-10-13 05:06:08 +00002278route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002279{
2280 int ret;
2281 struct in_addr *address;
2282
2283 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2284
2285 ret = inet_aton (arg, address);
2286
2287 if (ret == 0)
2288 {
2289 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2290 return NULL;
2291 }
2292
2293 return address;
2294}
2295
2296/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002297static void
paul718e3742002-12-13 20:15:29 +00002298route_set_originator_id_free (void *rule)
2299{
2300 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2301}
2302
Timo Teräs2aa640b2014-05-20 08:57:26 +03002303/* Set originator-id rule structure. */
paul718e3742002-12-13 20:15:29 +00002304struct route_map_rule_cmd route_set_originator_id_cmd =
2305{
2306 "originator-id",
2307 route_set_originator_id,
2308 route_set_originator_id_compile,
2309 route_set_originator_id_free,
2310};
David Lamparter6b0655a2014-06-04 06:53:35 +02002311
paul718e3742002-12-13 20:15:29 +00002312/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002313static int
paul718e3742002-12-13 20:15:29 +00002314bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002315 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002316{
2317 int ret;
2318
2319 ret = route_map_add_match (index, command, arg);
2320 if (ret)
2321 {
2322 switch (ret)
2323 {
2324 case RMAP_RULE_MISSING:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002325 vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002326 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002327 case RMAP_COMPILE_ERROR:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002328 vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002329 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002330 }
2331 }
2332 return CMD_SUCCESS;
2333}
2334
2335/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002336static int
paul718e3742002-12-13 20:15:29 +00002337bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002338 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002339{
2340 int ret;
2341
2342 ret = route_map_delete_match (index, command, arg);
2343 if (ret)
2344 {
2345 switch (ret)
2346 {
2347 case RMAP_RULE_MISSING:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002348 vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002349 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002350 case RMAP_COMPILE_ERROR:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002351 vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002352 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002353 }
2354 }
2355 return CMD_SUCCESS;
2356}
2357
2358/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002359static int
paul718e3742002-12-13 20:15:29 +00002360bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002361 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002362{
2363 int ret;
2364
2365 ret = route_map_add_set (index, command, arg);
2366 if (ret)
2367 {
2368 switch (ret)
2369 {
2370 case RMAP_RULE_MISSING:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002371 vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002372 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002373 case RMAP_COMPILE_ERROR:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002374 vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002375 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002376 }
2377 }
2378 return CMD_SUCCESS;
2379}
2380
2381/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002382static int
paul718e3742002-12-13 20:15:29 +00002383bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002384 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002385{
2386 int ret;
2387
2388 ret = route_map_delete_set (index, command, arg);
2389 if (ret)
2390 {
2391 switch (ret)
2392 {
2393 case RMAP_RULE_MISSING:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002394 vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002395 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002396 case RMAP_COMPILE_ERROR:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002397 vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002398 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002399 }
2400 }
2401 return CMD_SUCCESS;
2402}
2403
2404/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002405static void
paulfd79ac92004-10-13 05:06:08 +00002406bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002407{
2408 int i;
2409 afi_t afi;
2410 safi_t safi;
2411 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002412 struct listnode *node, *nnode;
2413 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002414 struct bgp *bgp;
2415 struct peer *peer;
2416 struct peer_group *group;
2417 struct bgp_filter *filter;
2418 struct bgp_node *bn;
2419 struct bgp_static *bgp_static;
2420
Lou Berger82dd7072016-01-12 13:41:57 -05002421 if (bm->bgp == NULL) /* may be called during cleanup */
2422 return;
2423
paul718e3742002-12-13 20:15:29 +00002424 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002425 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002426 {
paul1eb8ef22005-04-07 07:30:20 +00002427 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002428 {
2429 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2430 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2431 {
2432 filter = &peer->filter[afi][safi];
2433
paulfee0f4c2004-09-13 05:12:46 +00002434 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002435 {
2436 if (filter->map[direct].name)
2437 filter->map[direct].map =
2438 route_map_lookup_by_name (filter->map[direct].name);
2439 else
2440 filter->map[direct].map = NULL;
2441 }
2442
2443 if (filter->usmap.name)
2444 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2445 else
2446 filter->usmap.map = NULL;
2447 }
2448 }
paul1eb8ef22005-04-07 07:30:20 +00002449 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002450 {
2451 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2452 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2453 {
2454 filter = &group->conf->filter[afi][safi];
2455
paulfee0f4c2004-09-13 05:12:46 +00002456 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002457 {
2458 if (filter->map[direct].name)
2459 filter->map[direct].map =
2460 route_map_lookup_by_name (filter->map[direct].name);
2461 else
2462 filter->map[direct].map = NULL;
2463 }
2464
2465 if (filter->usmap.name)
2466 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2467 else
2468 filter->usmap.map = NULL;
2469 }
2470 }
2471 }
2472
2473 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002474 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002475 {
paul1eb8ef22005-04-07 07:30:20 +00002476 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002477 {
2478 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2479 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2480 {
2481 if (peer->default_rmap[afi][safi].name)
2482 peer->default_rmap[afi][safi].map =
2483 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2484 else
2485 peer->default_rmap[afi][safi].map = NULL;
2486 }
2487 }
2488 }
2489
2490 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002491 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002492 {
2493 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2494 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2495 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2496 bn = bgp_route_next (bn))
2497 if ((bgp_static = bn->info) != NULL)
2498 {
2499 if (bgp_static->rmap.name)
2500 bgp_static->rmap.map =
2501 route_map_lookup_by_name (bgp_static->rmap.name);
2502 else
2503 bgp_static->rmap.map = NULL;
2504 }
2505 }
2506
2507 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002508 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002509 {
2510 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2511 {
Donald Sharpf3cfc462016-01-07 09:33:28 -05002512 if (bgp->rmap[AFI_IP][i].name)
2513 bgp->rmap[AFI_IP][i].map =
2514 route_map_lookup_by_name (bgp->rmap[AFI_IP][i].name);
2515 if (bgp->rmap[AFI_IP6][i].name)
2516 bgp->rmap[AFI_IP6][i].map =
Andrej Ota220355d2016-05-09 20:49:01 +02002517 route_map_lookup_by_name (bgp->rmap[AFI_IP6][i].name);
paul718e3742002-12-13 20:15:29 +00002518 }
2519 }
2520}
David Lamparter6b0655a2014-06-04 06:53:35 +02002521
paulfee0f4c2004-09-13 05:12:46 +00002522DEFUN (match_peer,
2523 match_peer_cmd,
2524 "match peer (A.B.C.D|X:X::X:X)",
2525 MATCH_STR
2526 "Match peer address\n"
Igor Ryzhov93b493a2016-05-11 15:26:39 +03002527 "IP address of peer\n"
2528 "IPv6 address of peer\n")
paulfee0f4c2004-09-13 05:12:46 +00002529{
2530 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2531}
2532
2533DEFUN (match_peer_local,
2534 match_peer_local_cmd,
2535 "match peer local",
2536 MATCH_STR
2537 "Match peer address\n"
2538 "Static or Redistributed routes\n")
2539{
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +02002540 return bgp_route_match_add (vty, vty->index, "peer", "local");
paulfee0f4c2004-09-13 05:12:46 +00002541}
2542
2543DEFUN (no_match_peer,
2544 no_match_peer_cmd,
2545 "no match peer",
2546 NO_STR
2547 MATCH_STR
2548 "Match peer address\n")
2549{
2550 if (argc == 0)
2551 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2552
2553 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2554}
2555
2556ALIAS (no_match_peer,
2557 no_match_peer_val_cmd,
2558 "no match peer (A.B.C.D|X:X::X:X)",
2559 NO_STR
2560 MATCH_STR
2561 "Match peer address\n"
Igor Ryzhov93b493a2016-05-11 15:26:39 +03002562 "IP address of peer\n"
2563 "IPv6 address of peer\n")
paulfee0f4c2004-09-13 05:12:46 +00002564
2565ALIAS (no_match_peer,
2566 no_match_peer_local_cmd,
2567 "no match peer local",
2568 NO_STR
2569 MATCH_STR
2570 "Match peer address\n"
2571 "Static or Redistributed routes\n")
2572
paul718e3742002-12-13 20:15:29 +00002573DEFUN (match_ip_address,
2574 match_ip_address_cmd,
2575 "match ip address (<1-199>|<1300-2699>|WORD)",
2576 MATCH_STR
2577 IP_STR
2578 "Match address of route\n"
2579 "IP access-list number\n"
2580 "IP access-list number (expanded range)\n"
2581 "IP Access-list name\n")
2582{
2583 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2584}
2585
2586DEFUN (no_match_ip_address,
2587 no_match_ip_address_cmd,
2588 "no match ip address",
2589 NO_STR
2590 MATCH_STR
2591 IP_STR
2592 "Match address of route\n")
2593{
2594 if (argc == 0)
2595 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2596
2597 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2598}
2599
2600ALIAS (no_match_ip_address,
2601 no_match_ip_address_val_cmd,
2602 "no match ip address (<1-199>|<1300-2699>|WORD)",
2603 NO_STR
2604 MATCH_STR
2605 IP_STR
2606 "Match address of route\n"
2607 "IP access-list number\n"
2608 "IP access-list number (expanded range)\n"
2609 "IP Access-list name\n")
2610
2611DEFUN (match_ip_next_hop,
2612 match_ip_next_hop_cmd,
2613 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2614 MATCH_STR
2615 IP_STR
2616 "Match next-hop address of route\n"
2617 "IP access-list number\n"
2618 "IP access-list number (expanded range)\n"
2619 "IP Access-list name\n")
2620{
2621 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2622}
2623
2624DEFUN (no_match_ip_next_hop,
2625 no_match_ip_next_hop_cmd,
2626 "no match ip next-hop",
2627 NO_STR
2628 MATCH_STR
2629 IP_STR
2630 "Match next-hop address of route\n")
2631{
2632 if (argc == 0)
2633 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2634
2635 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2636}
2637
2638ALIAS (no_match_ip_next_hop,
2639 no_match_ip_next_hop_val_cmd,
2640 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2641 NO_STR
2642 MATCH_STR
2643 IP_STR
2644 "Match next-hop address of route\n"
2645 "IP access-list number\n"
2646 "IP access-list number (expanded range)\n"
2647 "IP Access-list name\n")
2648
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04002649/* match probability { */
2650
2651DEFUN (match_probability,
2652 match_probability_cmd,
2653 "match probability <0-100>",
2654 MATCH_STR
2655 "Match portion of routes defined by percentage value\n"
2656 "Percentage of routes\n")
2657{
2658 return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
2659}
2660
2661DEFUN (no_match_probability,
2662 no_match_probability_cmd,
2663 "no match probability",
2664 NO_STR
2665 MATCH_STR
2666 "Match portion of routes defined by percentage value\n")
2667{
2668 return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL);
2669}
2670
2671ALIAS (no_match_probability,
2672 no_match_probability_val_cmd,
2673 "no match probability <1-99>",
2674 NO_STR
2675 MATCH_STR
2676 "Match portion of routes defined by percentage value\n"
2677 "Percentage of routes\n")
2678
2679/* } */
2680
hassoc1643bb2005-02-02 16:43:17 +00002681DEFUN (match_ip_route_source,
2682 match_ip_route_source_cmd,
2683 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2684 MATCH_STR
2685 IP_STR
2686 "Match advertising source address of route\n"
2687 "IP access-list number\n"
2688 "IP access-list number (expanded range)\n"
2689 "IP standard access-list name\n")
2690{
2691 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2692}
2693
2694DEFUN (no_match_ip_route_source,
2695 no_match_ip_route_source_cmd,
2696 "no match ip route-source",
2697 NO_STR
2698 MATCH_STR
2699 IP_STR
2700 "Match advertising source address of route\n")
2701{
2702 if (argc == 0)
2703 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2704
2705 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2706}
2707
2708ALIAS (no_match_ip_route_source,
2709 no_match_ip_route_source_val_cmd,
2710 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2711 NO_STR
2712 MATCH_STR
2713 IP_STR
2714 "Match advertising source address of route\n"
2715 "IP access-list number\n"
2716 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002717 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002718
paul718e3742002-12-13 20:15:29 +00002719DEFUN (match_ip_address_prefix_list,
2720 match_ip_address_prefix_list_cmd,
2721 "match ip address prefix-list WORD",
2722 MATCH_STR
2723 IP_STR
2724 "Match address of route\n"
2725 "Match entries of prefix-lists\n"
2726 "IP prefix-list name\n")
2727{
2728 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2729}
2730
2731DEFUN (no_match_ip_address_prefix_list,
2732 no_match_ip_address_prefix_list_cmd,
2733 "no match ip address prefix-list",
2734 NO_STR
2735 MATCH_STR
2736 IP_STR
2737 "Match address of route\n"
2738 "Match entries of prefix-lists\n")
2739{
2740 if (argc == 0)
2741 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2742
2743 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2744}
2745
2746ALIAS (no_match_ip_address_prefix_list,
2747 no_match_ip_address_prefix_list_val_cmd,
2748 "no match ip address prefix-list WORD",
2749 NO_STR
2750 MATCH_STR
2751 IP_STR
2752 "Match address of route\n"
2753 "Match entries of prefix-lists\n"
2754 "IP prefix-list name\n")
2755
2756DEFUN (match_ip_next_hop_prefix_list,
2757 match_ip_next_hop_prefix_list_cmd,
2758 "match ip next-hop prefix-list WORD",
2759 MATCH_STR
2760 IP_STR
2761 "Match next-hop address of route\n"
2762 "Match entries of prefix-lists\n"
2763 "IP prefix-list name\n")
2764{
2765 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2766}
2767
2768DEFUN (no_match_ip_next_hop_prefix_list,
2769 no_match_ip_next_hop_prefix_list_cmd,
2770 "no match ip next-hop prefix-list",
2771 NO_STR
2772 MATCH_STR
2773 IP_STR
2774 "Match next-hop address of route\n"
2775 "Match entries of prefix-lists\n")
2776{
2777 if (argc == 0)
2778 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2779
2780 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2781}
2782
2783ALIAS (no_match_ip_next_hop_prefix_list,
2784 no_match_ip_next_hop_prefix_list_val_cmd,
2785 "no match ip next-hop prefix-list WORD",
2786 NO_STR
2787 MATCH_STR
2788 IP_STR
2789 "Match next-hop address of route\n"
2790 "Match entries of prefix-lists\n"
2791 "IP prefix-list name\n")
2792
hassoc1643bb2005-02-02 16:43:17 +00002793DEFUN (match_ip_route_source_prefix_list,
2794 match_ip_route_source_prefix_list_cmd,
2795 "match ip route-source prefix-list WORD",
2796 MATCH_STR
2797 IP_STR
2798 "Match advertising source address of route\n"
2799 "Match entries of prefix-lists\n"
2800 "IP prefix-list name\n")
2801{
2802 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2803}
2804
2805DEFUN (no_match_ip_route_source_prefix_list,
2806 no_match_ip_route_source_prefix_list_cmd,
2807 "no match ip route-source prefix-list",
2808 NO_STR
2809 MATCH_STR
2810 IP_STR
2811 "Match advertising source address of route\n"
2812 "Match entries of prefix-lists\n")
2813{
2814 if (argc == 0)
2815 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2816
2817 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2818}
2819
2820ALIAS (no_match_ip_route_source_prefix_list,
2821 no_match_ip_route_source_prefix_list_val_cmd,
2822 "no match ip route-source prefix-list WORD",
2823 NO_STR
2824 MATCH_STR
2825 IP_STR
2826 "Match advertising source address of route\n"
2827 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002828 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002829
paul718e3742002-12-13 20:15:29 +00002830DEFUN (match_metric,
2831 match_metric_cmd,
2832 "match metric <0-4294967295>",
2833 MATCH_STR
2834 "Match metric of route\n"
2835 "Metric value\n")
2836{
2837 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2838}
2839
2840DEFUN (no_match_metric,
2841 no_match_metric_cmd,
2842 "no match metric",
2843 NO_STR
2844 MATCH_STR
2845 "Match metric of route\n")
2846{
2847 if (argc == 0)
2848 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2849
2850 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2851}
2852
2853ALIAS (no_match_metric,
2854 no_match_metric_val_cmd,
2855 "no match metric <0-4294967295>",
2856 NO_STR
2857 MATCH_STR
2858 "Match metric of route\n"
2859 "Metric value\n")
2860
Dinesh Dutt5cf768a2015-11-09 20:21:53 -05002861DEFUN (match_local_pref,
2862 match_local_pref_cmd,
2863 "match local-preference <0-4294967295>",
2864 MATCH_STR
2865 "Match local-preference of route\n"
2866 "Metric value\n")
2867{
2868 return bgp_route_match_add (vty, vty->index, "local-preference", argv[0]);
2869}
2870
2871DEFUN (no_match_local_pref,
2872 no_match_local_pref_cmd,
2873 "no match local-preference",
2874 NO_STR
2875 MATCH_STR
2876 "Match local preference of route\n")
2877{
2878 if (argc == 0)
2879 return bgp_route_match_delete (vty, vty->index, "local-preference", NULL);
2880
2881 return bgp_route_match_delete (vty, vty->index, "local-preference", argv[0]);
2882}
2883
2884ALIAS (no_match_local_pref,
2885 no_match_local_pref_val_cmd,
2886 "no match local-preference <0-4294967295>",
2887 NO_STR
2888 MATCH_STR
2889 "Match local preference of route\n"
2890 "Local preference value\n")
2891
paul718e3742002-12-13 20:15:29 +00002892DEFUN (match_community,
2893 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002894 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002895 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{
2901 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2902}
2903
2904DEFUN (match_community_exact,
2905 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002906 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002907 MATCH_STR
2908 "Match BGP community list\n"
2909 "Community-list number (standard)\n"
2910 "Community-list number (expanded)\n"
2911 "Community-list name\n"
2912 "Do exact matching of communities\n")
2913{
2914 int ret;
2915 char *argstr;
2916
2917 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2918 strlen (argv[0]) + strlen ("exact-match") + 2);
2919
2920 sprintf (argstr, "%s exact-match", argv[0]);
2921
2922 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2923
2924 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2925
2926 return ret;
2927}
2928
2929DEFUN (no_match_community,
2930 no_match_community_cmd,
2931 "no match community",
2932 NO_STR
2933 MATCH_STR
2934 "Match BGP community list\n")
2935{
2936 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2937}
2938
2939ALIAS (no_match_community,
2940 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002941 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002942 NO_STR
2943 MATCH_STR
2944 "Match BGP community list\n"
2945 "Community-list number (standard)\n"
2946 "Community-list number (expanded)\n"
2947 "Community-list name\n")
2948
2949ALIAS (no_match_community,
2950 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002951 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002952 NO_STR
2953 MATCH_STR
2954 "Match BGP community list\n"
2955 "Community-list number (standard)\n"
2956 "Community-list number (expanded)\n"
2957 "Community-list name\n"
2958 "Do exact matching of communities\n")
2959
paul73ffb252003-04-19 15:49:49 +00002960DEFUN (match_ecommunity,
2961 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002962 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002963 MATCH_STR
2964 "Match BGP/VPN extended community list\n"
2965 "Extended community-list number (standard)\n"
2966 "Extended community-list number (expanded)\n"
2967 "Extended community-list name\n")
2968{
2969 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2970}
2971
2972DEFUN (no_match_ecommunity,
2973 no_match_ecommunity_cmd,
2974 "no match extcommunity",
2975 NO_STR
2976 MATCH_STR
2977 "Match BGP/VPN extended community list\n")
2978{
2979 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2980}
2981
2982ALIAS (no_match_ecommunity,
2983 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002984 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002985 NO_STR
2986 MATCH_STR
2987 "Match BGP/VPN extended community list\n"
2988 "Extended community-list number (standard)\n"
2989 "Extended community-list number (expanded)\n"
2990 "Extended community-list name\n")
2991
paul718e3742002-12-13 20:15:29 +00002992DEFUN (match_aspath,
2993 match_aspath_cmd,
2994 "match as-path WORD",
2995 MATCH_STR
2996 "Match BGP AS path list\n"
2997 "AS path access-list name\n")
2998{
2999 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
3000}
3001
3002DEFUN (no_match_aspath,
3003 no_match_aspath_cmd,
3004 "no match as-path",
3005 NO_STR
3006 MATCH_STR
3007 "Match BGP AS path list\n")
3008{
3009 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
3010}
3011
3012ALIAS (no_match_aspath,
3013 no_match_aspath_val_cmd,
3014 "no match as-path WORD",
3015 NO_STR
3016 MATCH_STR
3017 "Match BGP AS path list\n"
3018 "AS path access-list name\n")
3019
3020DEFUN (match_origin,
3021 match_origin_cmd,
3022 "match origin (egp|igp|incomplete)",
3023 MATCH_STR
3024 "BGP origin code\n"
3025 "remote EGP\n"
3026 "local IGP\n"
3027 "unknown heritage\n")
3028{
3029 if (strncmp (argv[0], "igp", 2) == 0)
3030 return bgp_route_match_add (vty, vty->index, "origin", "igp");
3031 if (strncmp (argv[0], "egp", 1) == 0)
3032 return bgp_route_match_add (vty, vty->index, "origin", "egp");
3033 if (strncmp (argv[0], "incomplete", 2) == 0)
3034 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
3035
3036 return CMD_WARNING;
3037}
3038
3039DEFUN (no_match_origin,
3040 no_match_origin_cmd,
3041 "no match origin",
3042 NO_STR
3043 MATCH_STR
3044 "BGP origin code\n")
3045{
3046 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
3047}
3048
3049ALIAS (no_match_origin,
3050 no_match_origin_val_cmd,
3051 "no match origin (egp|igp|incomplete)",
3052 NO_STR
3053 MATCH_STR
3054 "BGP origin code\n"
3055 "remote EGP\n"
3056 "local IGP\n"
3057 "unknown heritage\n")
3058
Piotr Chytła605aa332015-12-01 10:03:54 -05003059DEFUN (match_tag,
3060 match_tag_cmd,
Christian Frankeddc160c2016-10-01 20:42:34 +02003061 "match tag <1-4294967295>",
Piotr Chytła605aa332015-12-01 10:03:54 -05003062 MATCH_STR
3063 "Match tag of route\n"
3064 "Tag value\n")
3065{
3066 return bgp_route_match_add (vty, vty->index, "tag", argv[0]);
3067}
3068
3069DEFUN (no_match_tag,
3070 no_match_tag_cmd,
3071 "no match tag",
3072 NO_STR
3073 MATCH_STR
3074 "Match tag of route\n")
3075{
3076 if (argc == 0)
3077 return bgp_route_match_delete (vty, vty->index, "tag", NULL);
3078
3079 return bgp_route_match_delete (vty, vty->index, "tag", argv[0]);
3080}
3081
3082ALIAS (no_match_tag,
3083 no_match_tag_val_cmd,
Christian Frankeddc160c2016-10-01 20:42:34 +02003084 "no match tag <1-4294967295>",
Piotr Chytła605aa332015-12-01 10:03:54 -05003085 NO_STR
3086 MATCH_STR
3087 "Match tag of route\n"
3088 "Tag value\n")
3089
paul718e3742002-12-13 20:15:29 +00003090DEFUN (set_ip_nexthop,
3091 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00003092 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003093 SET_STR
3094 IP_STR
3095 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00003096 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00003097{
3098 union sockunion su;
3099 int ret;
3100
3101 ret = str2sockunion (argv[0], &su);
3102 if (ret < 0)
3103 {
3104 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
3105 return CMD_WARNING;
3106 }
3107
3108 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
3109}
3110
paulaf5cd0a2003-11-02 07:24:40 +00003111DEFUN (set_ip_nexthop_peer,
3112 set_ip_nexthop_peer_cmd,
3113 "set ip next-hop peer-address",
3114 SET_STR
3115 IP_STR
3116 "Next hop address\n"
3117 "Use peer address (for BGP only)\n")
3118{
3119 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
3120}
3121
paul94f2b392005-06-28 12:44:16 +00003122DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00003123 no_set_ip_nexthop_peer_cmd,
3124 "no set ip next-hop peer-address",
3125 NO_STR
3126 SET_STR
3127 IP_STR
3128 "Next hop address\n"
3129 "Use peer address (for BGP only)\n")
3130{
3131 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
3132}
3133
3134
paul718e3742002-12-13 20:15:29 +00003135DEFUN (no_set_ip_nexthop,
3136 no_set_ip_nexthop_cmd,
3137 "no set ip next-hop",
3138 NO_STR
3139 SET_STR
paul718e3742002-12-13 20:15:29 +00003140 "Next hop address\n")
3141{
paulaf5cd0a2003-11-02 07:24:40 +00003142 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00003143 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
3144
3145 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
3146}
3147
3148ALIAS (no_set_ip_nexthop,
3149 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00003150 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003151 NO_STR
3152 SET_STR
3153 IP_STR
3154 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00003155 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00003156
3157DEFUN (set_metric,
3158 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00003159 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00003160 SET_STR
3161 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00003162 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00003163{
3164 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
3165}
3166
paul73ffb252003-04-19 15:49:49 +00003167ALIAS (set_metric,
3168 set_metric_addsub_cmd,
3169 "set metric <+/-metric>",
3170 SET_STR
3171 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00003172 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00003173
Timo Teräsef757702015-04-29 09:43:04 +03003174ALIAS (set_metric,
3175 set_metric_rtt_cmd,
3176 "set metric (rtt|+rtt|-rtt)",
3177 SET_STR
3178 "Metric value for destination routing protocol\n"
3179 "Assign round trip time\n"
3180 "Add round trip time\n"
3181 "Subtract round trip time\n")
3182
paul718e3742002-12-13 20:15:29 +00003183DEFUN (no_set_metric,
3184 no_set_metric_cmd,
3185 "no set metric",
3186 NO_STR
3187 SET_STR
3188 "Metric value for destination routing protocol\n")
3189{
3190 if (argc == 0)
3191 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
3192
3193 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
3194}
3195
3196ALIAS (no_set_metric,
3197 no_set_metric_val_cmd,
3198 "no set metric <0-4294967295>",
3199 NO_STR
3200 SET_STR
3201 "Metric value for destination routing protocol\n"
3202 "Metric value\n")
3203
3204DEFUN (set_local_pref,
3205 set_local_pref_cmd,
3206 "set local-preference <0-4294967295>",
3207 SET_STR
3208 "BGP local preference path attribute\n"
3209 "Preference value\n")
3210{
3211 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
3212}
3213
3214DEFUN (no_set_local_pref,
3215 no_set_local_pref_cmd,
3216 "no set local-preference",
3217 NO_STR
3218 SET_STR
3219 "BGP local preference path attribute\n")
3220{
3221 if (argc == 0)
3222 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3223
3224 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
3225}
3226
3227ALIAS (no_set_local_pref,
3228 no_set_local_pref_val_cmd,
3229 "no set local-preference <0-4294967295>",
3230 NO_STR
3231 SET_STR
3232 "BGP local preference path attribute\n"
3233 "Preference value\n")
3234
3235DEFUN (set_weight,
3236 set_weight_cmd,
3237 "set weight <0-4294967295>",
3238 SET_STR
3239 "BGP weight for routing table\n"
3240 "Weight value\n")
3241{
3242 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3243}
3244
3245DEFUN (no_set_weight,
3246 no_set_weight_cmd,
3247 "no set weight",
3248 NO_STR
3249 SET_STR
3250 "BGP weight for routing table\n")
3251{
3252 if (argc == 0)
3253 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3254
3255 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3256}
3257
3258ALIAS (no_set_weight,
3259 no_set_weight_val_cmd,
3260 "no set weight <0-4294967295>",
3261 NO_STR
3262 SET_STR
3263 "BGP weight for routing table\n"
3264 "Weight value\n")
3265
3266DEFUN (set_aspath_prepend,
3267 set_aspath_prepend_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003268 "set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003269 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003270 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003271 "Prepend to the as-path\n"
3272 "AS number\n")
3273{
3274 int ret;
3275 char *str;
3276
3277 str = argv_concat (argv, argc, 0);
3278 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3279 XFREE (MTYPE_TMP, str);
3280
3281 return ret;
3282}
3283
Timo Teräs85c854a2014-09-30 11:31:53 +03003284ALIAS (set_aspath_prepend,
3285 set_aspath_prepend_lastas_cmd,
3286 "set as-path prepend (last-as) <1-10>",
3287 SET_STR
3288 "Transform BGP AS_PATH attribute\n"
3289 "Prepend to the as-path\n"
3290 "Use the peer's AS-number\n"
David Lamparterb7d50212015-03-03 08:53:18 +01003291 "Number of times to insert")
Timo Teräs85c854a2014-09-30 11:31:53 +03003292
paul718e3742002-12-13 20:15:29 +00003293DEFUN (no_set_aspath_prepend,
3294 no_set_aspath_prepend_cmd,
3295 "no set as-path prepend",
3296 NO_STR
3297 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003298 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003299 "Prepend to the as-path\n")
3300{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00003301 int ret;
3302 char *str;
3303
3304 if (argc == 0)
3305 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3306
3307 str = argv_concat (argv, argc, 0);
3308 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3309 XFREE (MTYPE_TMP, str);
3310 return ret;
paul718e3742002-12-13 20:15:29 +00003311}
3312
3313ALIAS (no_set_aspath_prepend,
3314 no_set_aspath_prepend_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003315 "no set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003316 NO_STR
3317 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003318 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003319 "Prepend to the as-path\n"
3320 "AS number\n")
3321
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003322DEFUN (set_aspath_exclude,
3323 set_aspath_exclude_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003324 "set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003325 SET_STR
3326 "Transform BGP AS-path attribute\n"
3327 "Exclude from the as-path\n"
3328 "AS number\n")
3329{
3330 int ret;
3331 char *str;
3332
3333 str = argv_concat (argv, argc, 0);
3334 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3335 XFREE (MTYPE_TMP, str);
3336 return ret;
3337}
3338
3339DEFUN (no_set_aspath_exclude,
3340 no_set_aspath_exclude_cmd,
3341 "no set as-path exclude",
3342 NO_STR
3343 SET_STR
3344 "Transform BGP AS_PATH attribute\n"
3345 "Exclude from the as-path\n")
3346{
3347 int ret;
3348 char *str;
3349
3350 if (argc == 0)
3351 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3352
3353 str = argv_concat (argv, argc, 0);
3354 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3355 XFREE (MTYPE_TMP, str);
3356 return ret;
3357}
3358
3359ALIAS (no_set_aspath_exclude,
3360 no_set_aspath_exclude_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003361 "no set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003362 NO_STR
3363 SET_STR
3364 "Transform BGP AS_PATH attribute\n"
3365 "Exclude from the as-path\n"
3366 "AS number\n")
3367
paul718e3742002-12-13 20:15:29 +00003368DEFUN (set_community,
3369 set_community_cmd,
3370 "set community .AA:NN",
3371 SET_STR
3372 "BGP community attribute\n"
3373 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3374{
3375 int i;
3376 int first = 0;
3377 int additive = 0;
3378 struct buffer *b;
3379 struct community *com = NULL;
3380 char *str;
3381 char *argstr;
3382 int ret;
3383
3384 b = buffer_new (1024);
3385
3386 for (i = 0; i < argc; i++)
3387 {
3388 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3389 {
3390 additive = 1;
3391 continue;
3392 }
3393
3394 if (first)
3395 buffer_putc (b, ' ');
3396 else
3397 first = 1;
3398
3399 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3400 {
3401 buffer_putstr (b, "internet");
3402 continue;
3403 }
3404 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3405 {
3406 buffer_putstr (b, "local-AS");
3407 continue;
3408 }
3409 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3410 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3411 {
3412 buffer_putstr (b, "no-advertise");
3413 continue;
3414 }
3415 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3416 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3417 {
3418 buffer_putstr (b, "no-export");
3419 continue;
3420 }
3421 buffer_putstr (b, argv[i]);
3422 }
3423 buffer_putc (b, '\0');
3424
3425 /* Fetch result string then compile it to communities attribute. */
3426 str = buffer_getstr (b);
3427 buffer_free (b);
3428
3429 if (str)
3430 {
3431 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003432 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003433 }
3434
3435 /* Can't compile user input into communities attribute. */
3436 if (! com)
3437 {
3438 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3439 return CMD_WARNING;
3440 }
3441
3442 /* Set communites attribute string. */
3443 str = community_str (com);
3444
3445 if (additive)
3446 {
3447 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3448 strcpy (argstr, str);
3449 strcpy (argstr + strlen (str), " additive");
3450 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3451 XFREE (MTYPE_TMP, argstr);
3452 }
3453 else
3454 ret = bgp_route_set_add (vty, vty->index, "community", str);
3455
3456 community_free (com);
3457
3458 return ret;
3459}
3460
3461DEFUN (set_community_none,
3462 set_community_none_cmd,
3463 "set community none",
3464 SET_STR
3465 "BGP community attribute\n"
3466 "No community attribute\n")
3467{
3468 return bgp_route_set_add (vty, vty->index, "community", "none");
3469}
3470
3471DEFUN (no_set_community,
3472 no_set_community_cmd,
3473 "no set community",
3474 NO_STR
3475 SET_STR
3476 "BGP community attribute\n")
3477{
3478 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3479}
3480
3481ALIAS (no_set_community,
3482 no_set_community_val_cmd,
3483 "no set community .AA:NN",
3484 NO_STR
3485 SET_STR
3486 "BGP community attribute\n"
3487 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3488
3489ALIAS (no_set_community,
3490 no_set_community_none_cmd,
3491 "no set community none",
3492 NO_STR
3493 SET_STR
3494 "BGP community attribute\n"
3495 "No community attribute\n")
3496
3497DEFUN (set_community_delete,
3498 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003499 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003500 SET_STR
3501 "set BGP community list (for deletion)\n"
3502 "Community-list number (standard)\n"
Daniel Waltonc7f25b92015-05-19 17:47:22 -07003503 "Community-list number (expanded)\n"
paul718e3742002-12-13 20:15:29 +00003504 "Community-list name\n"
3505 "Delete matching communities\n")
3506{
3507 char *str;
3508
3509 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3510 strcpy (str, argv[0]);
3511 strcpy (str + strlen (argv[0]), " delete");
3512
3513 bgp_route_set_add (vty, vty->index, "comm-list", str);
3514
3515 XFREE (MTYPE_TMP, str);
3516 return CMD_SUCCESS;
3517}
3518
3519DEFUN (no_set_community_delete,
3520 no_set_community_delete_cmd,
3521 "no set comm-list",
3522 NO_STR
3523 SET_STR
3524 "set BGP community list (for deletion)\n")
3525{
3526 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3527}
3528
3529ALIAS (no_set_community_delete,
3530 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003531 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003532 NO_STR
3533 SET_STR
3534 "set BGP community list (for deletion)\n"
3535 "Community-list number (standard)\n"
Daniel Waltonc7f25b92015-05-19 17:47:22 -07003536 "Community-list number (expanded)\n"
paul718e3742002-12-13 20:15:29 +00003537 "Community-list name\n"
3538 "Delete matching communities\n")
3539
3540DEFUN (set_ecommunity_rt,
3541 set_ecommunity_rt_cmd,
3542 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3543 SET_STR
3544 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003545 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003546 "VPN extended community\n")
3547{
3548 int ret;
3549 char *str;
3550
3551 str = argv_concat (argv, argc, 0);
3552 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3553 XFREE (MTYPE_TMP, str);
3554
3555 return ret;
3556}
3557
3558DEFUN (no_set_ecommunity_rt,
3559 no_set_ecommunity_rt_cmd,
3560 "no set extcommunity rt",
3561 NO_STR
3562 SET_STR
3563 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003564 "Route Target extended community\n")
paul718e3742002-12-13 20:15:29 +00003565{
3566 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3567}
3568
3569ALIAS (no_set_ecommunity_rt,
3570 no_set_ecommunity_rt_val_cmd,
3571 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3572 NO_STR
3573 SET_STR
3574 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003575 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003576 "VPN extended community\n")
3577
3578DEFUN (set_ecommunity_soo,
3579 set_ecommunity_soo_cmd,
3580 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3581 SET_STR
3582 "BGP extended community attribute\n"
3583 "Site-of-Origin extended community\n"
3584 "VPN extended community\n")
3585{
3586 int ret;
3587 char *str;
3588
3589 str = argv_concat (argv, argc, 0);
3590 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3591 XFREE (MTYPE_TMP, str);
3592 return ret;
3593}
3594
3595DEFUN (no_set_ecommunity_soo,
3596 no_set_ecommunity_soo_cmd,
3597 "no set extcommunity soo",
3598 NO_STR
3599 SET_STR
3600 "BGP extended community attribute\n"
3601 "Site-of-Origin extended community\n")
3602{
3603 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3604}
3605
3606ALIAS (no_set_ecommunity_soo,
3607 no_set_ecommunity_soo_val_cmd,
3608 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3609 NO_STR
3610 SET_STR
3611 "BGP extended community attribute\n"
3612 "Site-of-Origin extended community\n"
3613 "VPN extended community\n")
3614
3615DEFUN (set_origin,
3616 set_origin_cmd,
3617 "set origin (egp|igp|incomplete)",
3618 SET_STR
3619 "BGP origin code\n"
3620 "remote EGP\n"
3621 "local IGP\n"
3622 "unknown heritage\n")
3623{
3624 if (strncmp (argv[0], "igp", 2) == 0)
3625 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3626 if (strncmp (argv[0], "egp", 1) == 0)
3627 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3628 if (strncmp (argv[0], "incomplete", 2) == 0)
3629 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3630
3631 return CMD_WARNING;
3632}
3633
3634DEFUN (no_set_origin,
3635 no_set_origin_cmd,
3636 "no set origin",
3637 NO_STR
3638 SET_STR
3639 "BGP origin code\n")
3640{
3641 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3642}
3643
3644ALIAS (no_set_origin,
3645 no_set_origin_val_cmd,
3646 "no set origin (egp|igp|incomplete)",
3647 NO_STR
3648 SET_STR
3649 "BGP origin code\n"
3650 "remote EGP\n"
3651 "local IGP\n"
3652 "unknown heritage\n")
3653
3654DEFUN (set_atomic_aggregate,
3655 set_atomic_aggregate_cmd,
3656 "set atomic-aggregate",
3657 SET_STR
3658 "BGP atomic aggregate attribute\n" )
3659{
3660 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3661}
3662
3663DEFUN (no_set_atomic_aggregate,
3664 no_set_atomic_aggregate_cmd,
3665 "no set atomic-aggregate",
3666 NO_STR
3667 SET_STR
3668 "BGP atomic aggregate attribute\n" )
3669{
3670 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3671}
3672
3673DEFUN (set_aggregator_as,
3674 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003675 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003676 SET_STR
3677 "BGP aggregator attribute\n"
3678 "AS number of aggregator\n"
3679 "AS number\n"
3680 "IP address of aggregator\n")
3681{
3682 int ret;
Paul Jakma7aa9dce2014-09-19 14:42:23 +01003683 as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
paul718e3742002-12-13 20:15:29 +00003684 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003685 char *argstr;
3686
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003687 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003688
paul718e3742002-12-13 20:15:29 +00003689 ret = inet_aton (argv[1], &address);
3690 if (ret == 0)
3691 {
3692 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3693 return CMD_WARNING;
3694 }
3695
3696 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3697 strlen (argv[0]) + strlen (argv[1]) + 2);
3698
3699 sprintf (argstr, "%s %s", argv[0], argv[1]);
3700
3701 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3702
3703 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3704
3705 return ret;
3706}
3707
3708DEFUN (no_set_aggregator_as,
3709 no_set_aggregator_as_cmd,
3710 "no set aggregator as",
3711 NO_STR
3712 SET_STR
3713 "BGP aggregator attribute\n"
3714 "AS number of aggregator\n")
3715{
3716 int ret;
Paul Jakma7aa9dce2014-09-19 14:42:23 +01003717 as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
paul718e3742002-12-13 20:15:29 +00003718 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003719 char *argstr;
3720
3721 if (argv == 0)
3722 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3723
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003724 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003725
3726 ret = inet_aton (argv[1], &address);
3727 if (ret == 0)
3728 {
3729 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3730 return CMD_WARNING;
3731 }
3732
3733 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3734 strlen (argv[0]) + strlen (argv[1]) + 2);
3735
3736 sprintf (argstr, "%s %s", argv[0], argv[1]);
3737
3738 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3739
3740 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3741
3742 return ret;
3743}
3744
3745ALIAS (no_set_aggregator_as,
3746 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003747 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003748 NO_STR
3749 SET_STR
3750 "BGP aggregator attribute\n"
3751 "AS number of aggregator\n"
3752 "AS number\n"
3753 "IP address of aggregator\n")
3754
Piotr Chytła605aa332015-12-01 10:03:54 -05003755DEFUN (set_tag,
3756 set_tag_cmd,
Christian Frankeddc160c2016-10-01 20:42:34 +02003757 "set tag <1-4294967295>",
Piotr Chytła605aa332015-12-01 10:03:54 -05003758 SET_STR
3759 "Tag value for routing protocol\n"
3760 "Tag value\n")
3761{
3762 return bgp_route_set_add (vty, vty->index, "tag", argv[0]);
3763}
3764
3765DEFUN (no_set_tag,
3766 no_set_tag_cmd,
3767 "no set tag",
3768 NO_STR
3769 SET_STR
3770 "Tag value for routing protocol\n")
3771{
3772 if (argc == 0)
3773 bgp_route_set_delete(vty, vty->index, "tag", NULL);
3774
3775 return bgp_route_set_delete (vty, vty->index, "tag", argv[0]);
3776}
3777
3778ALIAS (no_set_tag,
3779 no_set_tag_val_cmd,
Christian Frankeddc160c2016-10-01 20:42:34 +02003780 "no set tag <1-4294967295>",
Piotr Chytła605aa332015-12-01 10:03:54 -05003781 NO_STR
3782 SET_STR
3783 "Tag value for routing protocol\n"
3784 "Tag value\n")
3785
3786
paul718e3742002-12-13 20:15:29 +00003787DEFUN (match_ipv6_address,
3788 match_ipv6_address_cmd,
3789 "match ipv6 address WORD",
3790 MATCH_STR
3791 IPV6_STR
3792 "Match IPv6 address of route\n"
3793 "IPv6 access-list name\n")
3794{
3795 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3796}
3797
3798DEFUN (no_match_ipv6_address,
3799 no_match_ipv6_address_cmd,
3800 "no match ipv6 address WORD",
3801 NO_STR
3802 MATCH_STR
3803 IPV6_STR
3804 "Match IPv6 address of route\n"
3805 "IPv6 access-list name\n")
3806{
3807 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3808}
3809
3810DEFUN (match_ipv6_next_hop,
3811 match_ipv6_next_hop_cmd,
3812 "match ipv6 next-hop X:X::X:X",
3813 MATCH_STR
3814 IPV6_STR
3815 "Match IPv6 next-hop address of route\n"
3816 "IPv6 address of next hop\n")
3817{
3818 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3819}
3820
3821DEFUN (no_match_ipv6_next_hop,
3822 no_match_ipv6_next_hop_cmd,
3823 "no match ipv6 next-hop X:X::X:X",
3824 NO_STR
3825 MATCH_STR
3826 IPV6_STR
3827 "Match IPv6 next-hop address of route\n"
3828 "IPv6 address of next hop\n")
3829{
3830 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3831}
3832
3833DEFUN (match_ipv6_address_prefix_list,
3834 match_ipv6_address_prefix_list_cmd,
3835 "match ipv6 address prefix-list WORD",
3836 MATCH_STR
3837 IPV6_STR
3838 "Match address of route\n"
3839 "Match entries of prefix-lists\n"
3840 "IP prefix-list name\n")
3841{
3842 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3843}
3844
3845DEFUN (no_match_ipv6_address_prefix_list,
3846 no_match_ipv6_address_prefix_list_cmd,
3847 "no match ipv6 address prefix-list WORD",
3848 NO_STR
3849 MATCH_STR
3850 IPV6_STR
3851 "Match address of route\n"
3852 "Match entries of prefix-lists\n"
3853 "IP prefix-list name\n")
3854{
3855 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3856}
3857
Dinesh G Duttad5233a2014-09-30 14:19:57 -07003858DEFUN (set_ipv6_nexthop_peer,
3859 set_ipv6_nexthop_peer_cmd,
3860 "set ipv6 next-hop peer-address",
3861 SET_STR
3862 IPV6_STR
3863 "Next hop address\n"
3864 "Use peer address (for BGP only)\n")
3865{
3866 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop peer-address", NULL);
3867}
3868
3869DEFUN (no_set_ipv6_nexthop_peer,
3870 no_set_ipv6_nexthop_peer_cmd,
3871 "no set ipv6 next-hop peer-address",
3872 NO_STR
3873 SET_STR
3874 IPV6_STR
3875 "IPv6 next-hop address\n"
3876 )
3877{
3878 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3879}
3880
paul718e3742002-12-13 20:15:29 +00003881DEFUN (set_ipv6_nexthop_global,
3882 set_ipv6_nexthop_global_cmd,
3883 "set ipv6 next-hop global X:X::X:X",
3884 SET_STR
3885 IPV6_STR
3886 "IPv6 next-hop address\n"
3887 "IPv6 global address\n"
3888 "IPv6 address of next hop\n")
3889{
3890 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3891}
3892
3893DEFUN (no_set_ipv6_nexthop_global,
3894 no_set_ipv6_nexthop_global_cmd,
3895 "no set ipv6 next-hop global",
3896 NO_STR
3897 SET_STR
3898 IPV6_STR
3899 "IPv6 next-hop address\n"
3900 "IPv6 global address\n")
3901{
3902 if (argc == 0)
3903 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3904
3905 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3906}
3907
3908ALIAS (no_set_ipv6_nexthop_global,
3909 no_set_ipv6_nexthop_global_val_cmd,
3910 "no set ipv6 next-hop global X:X::X:X",
3911 NO_STR
3912 SET_STR
3913 IPV6_STR
3914 "IPv6 next-hop address\n"
3915 "IPv6 global address\n"
3916 "IPv6 address of next hop\n")
3917
3918DEFUN (set_ipv6_nexthop_local,
3919 set_ipv6_nexthop_local_cmd,
3920 "set ipv6 next-hop local X:X::X:X",
3921 SET_STR
3922 IPV6_STR
3923 "IPv6 next-hop address\n"
3924 "IPv6 local address\n"
3925 "IPv6 address of next hop\n")
3926{
3927 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3928}
3929
3930DEFUN (no_set_ipv6_nexthop_local,
3931 no_set_ipv6_nexthop_local_cmd,
3932 "no set ipv6 next-hop local",
3933 NO_STR
3934 SET_STR
3935 IPV6_STR
3936 "IPv6 next-hop address\n"
3937 "IPv6 local address\n")
3938{
3939 if (argc == 0)
3940 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3941
3942 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3943}
3944
3945ALIAS (no_set_ipv6_nexthop_local,
3946 no_set_ipv6_nexthop_local_val_cmd,
3947 "no set ipv6 next-hop local X:X::X:X",
3948 NO_STR
3949 SET_STR
3950 IPV6_STR
3951 "IPv6 next-hop address\n"
3952 "IPv6 local address\n"
3953 "IPv6 address of next hop\n")
paul718e3742002-12-13 20:15:29 +00003954
3955DEFUN (set_vpnv4_nexthop,
3956 set_vpnv4_nexthop_cmd,
3957 "set vpnv4 next-hop A.B.C.D",
3958 SET_STR
3959 "VPNv4 information\n"
3960 "VPNv4 next-hop address\n"
3961 "IP address of next hop\n")
3962{
3963 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3964}
3965
3966DEFUN (no_set_vpnv4_nexthop,
3967 no_set_vpnv4_nexthop_cmd,
3968 "no set vpnv4 next-hop",
3969 NO_STR
3970 SET_STR
3971 "VPNv4 information\n"
3972 "VPNv4 next-hop address\n")
3973{
3974 if (argc == 0)
3975 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3976
3977 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3978}
3979
3980ALIAS (no_set_vpnv4_nexthop,
3981 no_set_vpnv4_nexthop_val_cmd,
3982 "no set vpnv4 next-hop A.B.C.D",
3983 NO_STR
3984 SET_STR
3985 "VPNv4 information\n"
3986 "VPNv4 next-hop address\n"
3987 "IP address of next hop\n")
3988
3989DEFUN (set_originator_id,
3990 set_originator_id_cmd,
3991 "set originator-id A.B.C.D",
3992 SET_STR
3993 "BGP originator ID attribute\n"
3994 "IP address of originator\n")
3995{
3996 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3997}
3998
3999DEFUN (no_set_originator_id,
4000 no_set_originator_id_cmd,
4001 "no set originator-id",
4002 NO_STR
4003 SET_STR
4004 "BGP originator ID attribute\n")
4005{
4006 if (argc == 0)
4007 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
4008
4009 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
4010}
4011
4012ALIAS (no_set_originator_id,
4013 no_set_originator_id_val_cmd,
4014 "no set originator-id A.B.C.D",
4015 NO_STR
4016 SET_STR
4017 "BGP originator ID attribute\n"
4018 "IP address of originator\n")
4019
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004020DEFUN_DEPRECATED (set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00004021 set_pathlimit_ttl_cmd,
4022 "set pathlimit ttl <1-255>",
4023 SET_STR
4024 "BGP AS-Pathlimit attribute\n"
4025 "Set AS-Path Hop-count TTL\n")
4026{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004027 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00004028}
4029
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004030DEFUN_DEPRECATED (no_set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00004031 no_set_pathlimit_ttl_cmd,
4032 "no set pathlimit ttl",
4033 NO_STR
4034 SET_STR
4035 "BGP AS-Pathlimit attribute\n"
4036 "Set AS-Path Hop-count TTL\n")
4037{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004038 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00004039}
4040
4041ALIAS (no_set_pathlimit_ttl,
4042 no_set_pathlimit_ttl_val_cmd,
4043 "no set pathlimit ttl <1-255>",
4044 NO_STR
4045 MATCH_STR
4046 "BGP AS-Pathlimit attribute\n"
4047 "Set AS-Path Hop-count TTL\n")
4048
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004049DEFUN_DEPRECATED (match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00004050 match_pathlimit_as_cmd,
4051 "match pathlimit as <1-65535>",
4052 MATCH_STR
4053 "BGP AS-Pathlimit attribute\n"
4054 "Match Pathlimit AS number\n")
4055{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004056 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00004057}
4058
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004059DEFUN_DEPRECATED (no_match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00004060 no_match_pathlimit_as_cmd,
4061 "no match pathlimit as",
4062 NO_STR
4063 MATCH_STR
4064 "BGP AS-Pathlimit attribute\n"
4065 "Match Pathlimit AS number\n")
4066{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004067 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00004068}
4069
4070ALIAS (no_match_pathlimit_as,
4071 no_match_pathlimit_as_val_cmd,
4072 "no match pathlimit as <1-65535>",
4073 NO_STR
4074 MATCH_STR
4075 "BGP AS-Pathlimit attribute\n"
4076 "Match Pathlimit ASN\n")
4077
David Lamparter6b0655a2014-06-04 06:53:35 +02004078
paul718e3742002-12-13 20:15:29 +00004079/* Initialization of route map. */
4080void
paul94f2b392005-06-28 12:44:16 +00004081bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00004082{
4083 route_map_init ();
4084 route_map_init_vty ();
4085 route_map_add_hook (bgp_route_map_update);
4086 route_map_delete_hook (bgp_route_map_update);
4087
paulfee0f4c2004-09-13 05:12:46 +00004088 route_map_install_match (&route_match_peer_cmd);
Dinesh Dutt5cf768a2015-11-09 20:21:53 -05004089 route_map_install_match (&route_match_local_pref_cmd);
paul718e3742002-12-13 20:15:29 +00004090 route_map_install_match (&route_match_ip_address_cmd);
4091 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00004092 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00004093 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
4094 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00004095 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00004096 route_map_install_match (&route_match_aspath_cmd);
4097 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00004098 route_map_install_match (&route_match_ecommunity_cmd);
Dinesh Dutt5cf768a2015-11-09 20:21:53 -05004099 route_map_install_match (&route_match_local_pref_cmd);
paul718e3742002-12-13 20:15:29 +00004100 route_map_install_match (&route_match_metric_cmd);
4101 route_map_install_match (&route_match_origin_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04004102 route_map_install_match (&route_match_probability_cmd);
Piotr Chytła605aa332015-12-01 10:03:54 -05004103 route_map_install_match (&route_match_tag_cmd);
paul718e3742002-12-13 20:15:29 +00004104
4105 route_map_install_set (&route_set_ip_nexthop_cmd);
4106 route_map_install_set (&route_set_local_pref_cmd);
4107 route_map_install_set (&route_set_weight_cmd);
4108 route_map_install_set (&route_set_metric_cmd);
4109 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00004110 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00004111 route_map_install_set (&route_set_origin_cmd);
4112 route_map_install_set (&route_set_atomic_aggregate_cmd);
4113 route_map_install_set (&route_set_aggregator_as_cmd);
4114 route_map_install_set (&route_set_community_cmd);
4115 route_map_install_set (&route_set_community_delete_cmd);
4116 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
4117 route_map_install_set (&route_set_originator_id_cmd);
4118 route_map_install_set (&route_set_ecommunity_rt_cmd);
4119 route_map_install_set (&route_set_ecommunity_soo_cmd);
Piotr Chytła605aa332015-12-01 10:03:54 -05004120 route_map_install_set (&route_set_tag_cmd);
paul718e3742002-12-13 20:15:29 +00004121
paulfee0f4c2004-09-13 05:12:46 +00004122 install_element (RMAP_NODE, &match_peer_cmd);
4123 install_element (RMAP_NODE, &match_peer_local_cmd);
4124 install_element (RMAP_NODE, &no_match_peer_cmd);
4125 install_element (RMAP_NODE, &no_match_peer_val_cmd);
4126 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00004127 install_element (RMAP_NODE, &match_ip_address_cmd);
4128 install_element (RMAP_NODE, &no_match_ip_address_cmd);
4129 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
4130 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
4131 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
4132 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00004133 install_element (RMAP_NODE, &match_ip_route_source_cmd);
4134 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
4135 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00004136 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
4137 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
4138 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
4139 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
4140 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
4141 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00004142 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
4143 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
4144 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00004145
4146 install_element (RMAP_NODE, &match_aspath_cmd);
4147 install_element (RMAP_NODE, &no_match_aspath_cmd);
4148 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
4149 install_element (RMAP_NODE, &match_metric_cmd);
4150 install_element (RMAP_NODE, &no_match_metric_cmd);
4151 install_element (RMAP_NODE, &no_match_metric_val_cmd);
Dinesh Dutt5cf768a2015-11-09 20:21:53 -05004152 install_element (RMAP_NODE, &match_local_pref_cmd);
4153 install_element (RMAP_NODE, &no_match_local_pref_cmd);
4154 install_element (RMAP_NODE, &no_match_local_pref_val_cmd);
paul718e3742002-12-13 20:15:29 +00004155 install_element (RMAP_NODE, &match_community_cmd);
4156 install_element (RMAP_NODE, &match_community_exact_cmd);
4157 install_element (RMAP_NODE, &no_match_community_cmd);
4158 install_element (RMAP_NODE, &no_match_community_val_cmd);
4159 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00004160 install_element (RMAP_NODE, &match_ecommunity_cmd);
4161 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
4162 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00004163 install_element (RMAP_NODE, &match_origin_cmd);
4164 install_element (RMAP_NODE, &no_match_origin_cmd);
4165 install_element (RMAP_NODE, &no_match_origin_val_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04004166 install_element (RMAP_NODE, &match_probability_cmd);
4167 install_element (RMAP_NODE, &no_match_probability_cmd);
4168 install_element (RMAP_NODE, &no_match_probability_val_cmd);
Piotr Chytła605aa332015-12-01 10:03:54 -05004169 install_element (RMAP_NODE, &match_tag_cmd);
4170 install_element (RMAP_NODE, &no_match_tag_cmd);
4171 install_element (RMAP_NODE, &no_match_tag_val_cmd);
paul718e3742002-12-13 20:15:29 +00004172
4173 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00004174 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00004175 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
4176 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
4177 install_element (RMAP_NODE, &set_local_pref_cmd);
4178 install_element (RMAP_NODE, &no_set_local_pref_cmd);
4179 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
4180 install_element (RMAP_NODE, &set_weight_cmd);
4181 install_element (RMAP_NODE, &no_set_weight_cmd);
4182 install_element (RMAP_NODE, &no_set_weight_val_cmd);
4183 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00004184 install_element (RMAP_NODE, &set_metric_addsub_cmd);
Timo Teräsef757702015-04-29 09:43:04 +03004185 install_element (RMAP_NODE, &set_metric_rtt_cmd);
paul718e3742002-12-13 20:15:29 +00004186 install_element (RMAP_NODE, &no_set_metric_cmd);
4187 install_element (RMAP_NODE, &no_set_metric_val_cmd);
4188 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Timo Teräs85c854a2014-09-30 11:31:53 +03004189 install_element (RMAP_NODE, &set_aspath_prepend_lastas_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00004190 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00004191 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
4192 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00004193 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
4194 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00004195 install_element (RMAP_NODE, &set_origin_cmd);
4196 install_element (RMAP_NODE, &no_set_origin_cmd);
4197 install_element (RMAP_NODE, &no_set_origin_val_cmd);
4198 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
4199 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
4200 install_element (RMAP_NODE, &set_aggregator_as_cmd);
4201 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
4202 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
4203 install_element (RMAP_NODE, &set_community_cmd);
4204 install_element (RMAP_NODE, &set_community_none_cmd);
4205 install_element (RMAP_NODE, &no_set_community_cmd);
4206 install_element (RMAP_NODE, &no_set_community_val_cmd);
4207 install_element (RMAP_NODE, &no_set_community_none_cmd);
4208 install_element (RMAP_NODE, &set_community_delete_cmd);
4209 install_element (RMAP_NODE, &no_set_community_delete_cmd);
4210 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
4211 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
4212 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
4213 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
4214 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
4215 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
4216 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
4217 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
4218 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
4219 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
4220 install_element (RMAP_NODE, &set_originator_id_cmd);
4221 install_element (RMAP_NODE, &no_set_originator_id_cmd);
4222 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
Piotr Chytła605aa332015-12-01 10:03:54 -05004223 install_element (RMAP_NODE, &set_tag_cmd);
4224 install_element (RMAP_NODE, &no_set_tag_cmd);
4225 install_element (RMAP_NODE, &no_set_tag_val_cmd);
paul718e3742002-12-13 20:15:29 +00004226
paul718e3742002-12-13 20:15:29 +00004227 route_map_install_match (&route_match_ipv6_address_cmd);
4228 route_map_install_match (&route_match_ipv6_next_hop_cmd);
4229 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
4230 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
4231 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Dinesh G Duttad5233a2014-09-30 14:19:57 -07004232 route_map_install_set (&route_set_ipv6_nexthop_peer_cmd);
4233
paul718e3742002-12-13 20:15:29 +00004234 install_element (RMAP_NODE, &match_ipv6_address_cmd);
4235 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
4236 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
4237 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
4238 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
4239 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
4240 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
4241 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
4242 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
4243 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
4244 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
4245 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
Dinesh G Duttad5233a2014-09-30 14:19:57 -07004246 install_element (RMAP_NODE, &set_ipv6_nexthop_peer_cmd);
4247 install_element (RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd);
Paul Jakma41367172007-08-06 15:24:51 +00004248
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004249 /* AS-Pathlimit: functionality removed, commands kept for
4250 * compatibility.
4251 */
Paul Jakma41367172007-08-06 15:24:51 +00004252 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
4253 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
4254 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
4255 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
4256 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
4257 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00004258}