blob: 921687a7f4c6b0ba831b2ce7933c5df294fbcf92 [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
1029
1030/* Route map `match tag' match statement. `arg' is TAG value */
1031static void *
1032route_match_tag_compile (const char *arg)
1033{
Paul Jakma96d10602016-07-01 14:23:45 +01001034 route_tag_t *tag;
1035 route_tag_t tmp;
Piotr Chytła605aa332015-12-01 10:03:54 -05001036
1037 /* tag value shoud be integer. */
1038 if (! all_digit (arg))
1039 return NULL;
1040
1041 tmp = atoi(arg);
1042 if (tmp < 1)
1043 return NULL;
1044
1045 tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
1046
1047 if (!tag)
1048 return tag;
1049
1050 *tag = tmp;
1051
1052 return tag;
1053}
1054
1055
1056/* Free route map's compiled 'match tag' value. */
1057static void
1058route_match_tag_free (void *rule)
1059{
1060 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1061}
1062
1063/* Route map commands for tag matching. */
1064struct route_map_rule_cmd route_match_tag_cmd =
1065{
1066 "tag",
1067 route_match_tag,
1068 route_match_tag_compile,
1069 route_match_tag_free,
1070};
1071
1072
paul718e3742002-12-13 20:15:29 +00001073/* Set nexthop to object. ojbect must be pointer to struct attr. */
paulac41b2a2003-08-12 05:32:27 +00001074struct rmap_ip_nexthop_set
1075{
1076 struct in_addr *address;
1077 int peer_address;
1078};
1079
paul94f2b392005-06-28 12:44:16 +00001080static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001081route_set_ip_nexthop (void *rule, struct prefix *prefix,
1082 route_map_object_t type, void *object)
1083{
paulac41b2a2003-08-12 05:32:27 +00001084 struct rmap_ip_nexthop_set *rins = rule;
paul718e3742002-12-13 20:15:29 +00001085 struct bgp_info *bgp_info;
paulac41b2a2003-08-12 05:32:27 +00001086 struct peer *peer;
paul718e3742002-12-13 20:15:29 +00001087
1088 if (type == RMAP_BGP)
1089 {
paul718e3742002-12-13 20:15:29 +00001090 bgp_info = object;
paulac41b2a2003-08-12 05:32:27 +00001091 peer = bgp_info->peer;
1092
1093 if (rins->peer_address)
1094 {
paulfee0f4c2004-09-13 05:12:46 +00001095 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
1096 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
paulac41b2a2003-08-12 05:32:27 +00001097 && peer->su_remote
1098 && sockunion_family (peer->su_remote) == AF_INET)
1099 {
Jorge Boncompte [DTI2]0c5ed3e2012-04-10 16:57:22 +02001100 bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote);
paulac41b2a2003-08-12 05:32:27 +00001101 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
1102 }
1103 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
1104 && peer->su_local
1105 && sockunion_family (peer->su_local) == AF_INET)
1106 {
Jorge Boncompte [DTI2]0c5ed3e2012-04-10 16:57:22 +02001107 bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_local);
paulac41b2a2003-08-12 05:32:27 +00001108 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
1109 }
1110 }
1111 else
1112 {
1113 /* Set next hop value. */
1114 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
1115 bgp_info->attr->nexthop = *rins->address;
1116 }
paul718e3742002-12-13 20:15:29 +00001117 }
1118
1119 return RMAP_OKAY;
1120}
1121
1122/* Route map `ip nexthop' compile function. Given string is converted
1123 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001124static void *
paulfd79ac92004-10-13 05:06:08 +00001125route_set_ip_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001126{
paulac41b2a2003-08-12 05:32:27 +00001127 struct rmap_ip_nexthop_set *rins;
1128 struct in_addr *address = NULL;
1129 int peer_address = 0;
paul718e3742002-12-13 20:15:29 +00001130 int ret;
paul718e3742002-12-13 20:15:29 +00001131
paulac41b2a2003-08-12 05:32:27 +00001132 if (strcmp (arg, "peer-address") == 0)
1133 peer_address = 1;
1134 else
paul718e3742002-12-13 20:15:29 +00001135 {
paulac41b2a2003-08-12 05:32:27 +00001136 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
1137 ret = inet_aton (arg, address);
1138
1139 if (ret == 0)
1140 {
1141 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1142 return NULL;
1143 }
paul718e3742002-12-13 20:15:29 +00001144 }
1145
Stephen Hemminger393deb92008-08-18 14:13:29 -07001146 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
paulac41b2a2003-08-12 05:32:27 +00001147
1148 rins->address = address;
1149 rins->peer_address = peer_address;
1150
1151 return rins;
paul718e3742002-12-13 20:15:29 +00001152}
1153
1154/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00001155static void
paul718e3742002-12-13 20:15:29 +00001156route_set_ip_nexthop_free (void *rule)
1157{
paulac41b2a2003-08-12 05:32:27 +00001158 struct rmap_ip_nexthop_set *rins = rule;
1159
1160 if (rins->address)
1161 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
1162
1163 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +00001164}
1165
1166/* Route map commands for ip nexthop set. */
1167struct route_map_rule_cmd route_set_ip_nexthop_cmd =
1168{
1169 "ip next-hop",
1170 route_set_ip_nexthop,
1171 route_set_ip_nexthop_compile,
1172 route_set_ip_nexthop_free
1173};
David Lamparter6b0655a2014-06-04 06:53:35 +02001174
paul718e3742002-12-13 20:15:29 +00001175/* `set local-preference LOCAL_PREF' */
1176
1177/* Set local preference. */
paul94f2b392005-06-28 12:44:16 +00001178static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001179route_set_local_pref (void *rule, struct prefix *prefix,
1180 route_map_object_t type, void *object)
1181{
Timo Teräs38f22ab2015-04-29 09:43:02 +03001182 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +00001183 struct bgp_info *bgp_info;
Timo Teräs38f22ab2015-04-29 09:43:02 +03001184 u_int32_t locpref = 0;
paul718e3742002-12-13 20:15:29 +00001185
1186 if (type == RMAP_BGP)
1187 {
1188 /* Fetch routemap's rule information. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001189 rv = rule;
paul718e3742002-12-13 20:15:29 +00001190 bgp_info = object;
1191
1192 /* Set local preference value. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001193 if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
1194 locpref = bgp_info->attr->local_pref;
1195
paul718e3742002-12-13 20:15:29 +00001196 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
Timo Teräsef757702015-04-29 09:43:04 +03001197 bgp_info->attr->local_pref = route_value_adjust(rv, locpref, bgp_info->peer);
paul718e3742002-12-13 20:15:29 +00001198 }
1199
1200 return RMAP_OKAY;
1201}
1202
paul718e3742002-12-13 20:15:29 +00001203/* Set local preference rule structure. */
1204struct route_map_rule_cmd route_set_local_pref_cmd =
1205{
1206 "local-preference",
1207 route_set_local_pref,
Timo Teräs38f22ab2015-04-29 09:43:02 +03001208 route_value_compile,
1209 route_value_free,
paul718e3742002-12-13 20:15:29 +00001210};
David Lamparter6b0655a2014-06-04 06:53:35 +02001211
paul718e3742002-12-13 20:15:29 +00001212/* `set weight WEIGHT' */
1213
1214/* Set weight. */
paul94f2b392005-06-28 12:44:16 +00001215static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001216route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
1217 void *object)
1218{
Timo Teräs38f22ab2015-04-29 09:43:02 +03001219 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +00001220 struct bgp_info *bgp_info;
Timo Teräs38f22ab2015-04-29 09:43:02 +03001221 u_int32_t weight;
paul718e3742002-12-13 20:15:29 +00001222
1223 if (type == RMAP_BGP)
1224 {
1225 /* Fetch routemap's rule information. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001226 rv = rule;
paul718e3742002-12-13 20:15:29 +00001227 bgp_info = object;
1228
1229 /* Set weight value. */
Timo Teräsef757702015-04-29 09:43:04 +03001230 weight = route_value_adjust(rv, 0, bgp_info->peer);
Timo Teräs38f22ab2015-04-29 09:43:02 +03001231 if (weight)
1232 (bgp_attr_extra_get (bgp_info->attr))->weight = weight;
Paul Jakmafb982c22007-05-04 20:15:47 +00001233 else if (bgp_info->attr->extra)
1234 bgp_info->attr->extra->weight = 0;
paul718e3742002-12-13 20:15:29 +00001235 }
1236
1237 return RMAP_OKAY;
1238}
1239
paul718e3742002-12-13 20:15:29 +00001240/* Set local preference rule structure. */
1241struct route_map_rule_cmd route_set_weight_cmd =
1242{
1243 "weight",
1244 route_set_weight,
Timo Teräs38f22ab2015-04-29 09:43:02 +03001245 route_value_compile,
1246 route_value_free,
paul718e3742002-12-13 20:15:29 +00001247};
David Lamparter6b0655a2014-06-04 06:53:35 +02001248
paul718e3742002-12-13 20:15:29 +00001249/* `set metric METRIC' */
1250
1251/* Set metric to attribute. */
paul94f2b392005-06-28 12:44:16 +00001252static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001253route_set_metric (void *rule, struct prefix *prefix,
1254 route_map_object_t type, void *object)
1255{
Timo Teräs38f22ab2015-04-29 09:43:02 +03001256 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +00001257 struct bgp_info *bgp_info;
Timo Teräs38f22ab2015-04-29 09:43:02 +03001258 u_int32_t med = 0;
paul718e3742002-12-13 20:15:29 +00001259
1260 if (type == RMAP_BGP)
1261 {
1262 /* Fetch routemap's rule information. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001263 rv = rule;
paul718e3742002-12-13 20:15:29 +00001264 bgp_info = object;
1265
Timo Teräs38f22ab2015-04-29 09:43:02 +03001266 if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
1267 med = bgp_info->attr->med;
1268
Timo Teräsef757702015-04-29 09:43:04 +03001269 bgp_info->attr->med = route_value_adjust(rv, med, bgp_info->peer);
paul718e3742002-12-13 20:15:29 +00001270 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
paul718e3742002-12-13 20:15:29 +00001271 }
1272 return RMAP_OKAY;
1273}
1274
paul718e3742002-12-13 20:15:29 +00001275/* Set metric rule structure. */
1276struct route_map_rule_cmd route_set_metric_cmd =
1277{
1278 "metric",
1279 route_set_metric,
Timo Teräs38f22ab2015-04-29 09:43:02 +03001280 route_value_compile,
1281 route_value_free,
paul718e3742002-12-13 20:15:29 +00001282};
David Lamparter6b0655a2014-06-04 06:53:35 +02001283
paul718e3742002-12-13 20:15:29 +00001284/* `set as-path prepend ASPATH' */
1285
1286/* For AS path prepend mechanism. */
paul94f2b392005-06-28 12:44:16 +00001287static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001288route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1289{
1290 struct aspath *aspath;
1291 struct aspath *new;
1292 struct bgp_info *binfo;
1293
1294 if (type == RMAP_BGP)
1295 {
paul718e3742002-12-13 20:15:29 +00001296 binfo = object;
1297
1298 if (binfo->attr->aspath->refcnt)
1299 new = aspath_dup (binfo->attr->aspath);
1300 else
1301 new = binfo->attr->aspath;
1302
Timo Teräs85c854a2014-09-30 11:31:53 +03001303 if ((uintptr_t)rule > 10)
1304 {
1305 aspath = rule;
1306 aspath_prepend (aspath, new);
1307 }
1308 else
1309 {
1310 as_t as = aspath_leftmost(new);
1311 if (!as) as = binfo->peer->as;
1312 new = aspath_add_seq_n (new, as, (uintptr_t) rule);
1313 }
1314
paul718e3742002-12-13 20:15:29 +00001315 binfo->attr->aspath = new;
1316 }
1317
1318 return RMAP_OKAY;
1319}
1320
Timo Teräs85c854a2014-09-30 11:31:53 +03001321static void *
1322route_set_aspath_prepend_compile (const char *arg)
1323{
1324 unsigned int num;
1325
1326 if (sscanf(arg, "last-as %u", &num) == 1 && num > 0 && num < 10)
1327 return (void*)(uintptr_t)num;
1328
1329 return route_aspath_compile(arg);
1330}
1331
1332static void
1333route_set_aspath_prepend_free (void *rule)
1334{
1335 if ((uintptr_t)rule > 10)
1336 route_aspath_free(rule);
1337}
1338
1339
Timo Teräs2aa640b2014-05-20 08:57:26 +03001340/* Set as-path prepend rule structure. */
paul718e3742002-12-13 20:15:29 +00001341struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1342{
1343 "as-path prepend",
1344 route_set_aspath_prepend,
Timo Teräs85c854a2014-09-30 11:31:53 +03001345 route_set_aspath_prepend_compile,
1346 route_set_aspath_prepend_free,
paul718e3742002-12-13 20:15:29 +00001347};
David Lamparter6b0655a2014-06-04 06:53:35 +02001348
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001349/* `set as-path exclude ASn' */
1350
1351/* For ASN exclude mechanism.
1352 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1353 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1354 */
1355static route_map_result_t
1356route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
1357{
1358 struct aspath * new_path, * exclude_path;
1359 struct bgp_info *binfo;
1360
1361 if (type == RMAP_BGP)
1362 {
1363 exclude_path = rule;
1364 binfo = object;
1365 if (binfo->attr->aspath->refcnt)
1366 new_path = aspath_dup (binfo->attr->aspath);
1367 else
1368 new_path = binfo->attr->aspath;
1369 binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
1370 }
1371 return RMAP_OKAY;
1372}
1373
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001374/* Set ASn exlude rule structure. */
1375struct route_map_rule_cmd route_set_aspath_exclude_cmd =
1376{
1377 "as-path exclude",
1378 route_set_aspath_exclude,
Timo Teräsb304dcb2014-05-20 09:04:49 +03001379 route_aspath_compile,
1380 route_aspath_free,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001381};
David Lamparter6b0655a2014-06-04 06:53:35 +02001382
paul718e3742002-12-13 20:15:29 +00001383/* `set community COMMUNITY' */
1384struct rmap_com_set
1385{
1386 struct community *com;
1387 int additive;
1388 int none;
1389};
1390
1391/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001392static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001393route_set_community (void *rule, struct prefix *prefix,
1394 route_map_object_t type, void *object)
1395{
1396 struct rmap_com_set *rcs;
1397 struct bgp_info *binfo;
1398 struct attr *attr;
1399 struct community *new = NULL;
1400 struct community *old;
1401 struct community *merge;
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001402
paul718e3742002-12-13 20:15:29 +00001403 if (type == RMAP_BGP)
1404 {
1405 rcs = rule;
1406 binfo = object;
1407 attr = binfo->attr;
1408 old = attr->community;
1409
1410 /* "none" case. */
1411 if (rcs->none)
1412 {
1413 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1414 attr->community = NULL;
Christian Frankeb06b35f2012-12-07 14:26:09 +00001415 /* See the longer comment down below. */
1416 if (old && old->refcnt == 0)
1417 community_free(old);
paul718e3742002-12-13 20:15:29 +00001418 return RMAP_OKAY;
1419 }
1420
1421 /* "additive" case. */
1422 if (rcs->additive && old)
1423 {
1424 merge = community_merge (community_dup (old), rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001425
1426 /* HACK: if the old community is not intern'd,
1427 * we should free it here, or all reference to it may be lost.
1428 * Really need to cleanup attribute caching sometime.
1429 */
1430 if (old->refcnt == 0)
1431 community_free (old);
paul718e3742002-12-13 20:15:29 +00001432 new = community_uniq_sort (merge);
1433 community_free (merge);
1434 }
1435 else
1436 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001437
1438 /* will be interned by caller if required */
Paul Jakma4a2035f2011-04-01 15:58:27 +01001439 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001440
paul718e3742002-12-13 20:15:29 +00001441 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1442 }
1443
1444 return RMAP_OKAY;
1445}
1446
1447/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001448static void *
paulfd79ac92004-10-13 05:06:08 +00001449route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001450{
1451 struct rmap_com_set *rcs;
1452 struct community *com = NULL;
1453 char *sp;
1454 int additive = 0;
1455 int none = 0;
1456
1457 if (strcmp (arg, "none") == 0)
1458 none = 1;
1459 else
1460 {
1461 sp = strstr (arg, "additive");
1462
1463 if (sp && sp > arg)
1464 {
1465 /* "additive" keyworkd is included. */
1466 additive = 1;
1467 *(sp - 1) = '\0';
1468 }
1469
1470 com = community_str2com (arg);
1471
1472 if (additive)
1473 *(sp - 1) = ' ';
1474
1475 if (! com)
1476 return NULL;
1477 }
1478
Stephen Hemminger393deb92008-08-18 14:13:29 -07001479 rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
Paul Jakma4a2035f2011-04-01 15:58:27 +01001480 rcs->com = com;
paul718e3742002-12-13 20:15:29 +00001481 rcs->additive = additive;
1482 rcs->none = none;
1483
1484 return rcs;
1485}
1486
1487/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001488static void
paul718e3742002-12-13 20:15:29 +00001489route_set_community_free (void *rule)
1490{
1491 struct rmap_com_set *rcs = rule;
1492
1493 if (rcs->com)
1494 community_free (rcs->com);
1495 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1496}
1497
1498/* Set community rule structure. */
1499struct route_map_rule_cmd route_set_community_cmd =
1500{
1501 "community",
1502 route_set_community,
1503 route_set_community_compile,
1504 route_set_community_free,
1505};
David Lamparter6b0655a2014-06-04 06:53:35 +02001506
hassofee6e4e2005-02-02 16:29:31 +00001507/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001508
1509/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001510static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001511route_set_community_delete (void *rule, struct prefix *prefix,
1512 route_map_object_t type, void *object)
1513{
1514 struct community_list *list;
1515 struct community *merge;
1516 struct community *new;
1517 struct community *old;
1518 struct bgp_info *binfo;
1519
1520 if (type == RMAP_BGP)
1521 {
1522 if (! rule)
1523 return RMAP_OKAY;
1524
1525 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001526 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001527 old = binfo->attr->community;
1528
1529 if (list && old)
1530 {
1531 merge = community_list_match_delete (community_dup (old), list);
1532 new = community_uniq_sort (merge);
1533 community_free (merge);
1534
Michael Lambert604a9b42010-09-13 11:48:11 -04001535 /* HACK: if the old community is not intern'd,
1536 * we should free it here, or all reference to it may be lost.
1537 * Really need to cleanup attribute caching sometime.
1538 */
1539 if (old->refcnt == 0)
1540 community_free (old);
1541
paul718e3742002-12-13 20:15:29 +00001542 if (new->size == 0)
1543 {
1544 binfo->attr->community = NULL;
1545 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1546 community_free (new);
1547 }
1548 else
1549 {
Paul Jakma4a2035f2011-04-01 15:58:27 +01001550 binfo->attr->community = new;
paul718e3742002-12-13 20:15:29 +00001551 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1552 }
1553 }
1554 }
1555
1556 return RMAP_OKAY;
1557}
1558
1559/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001560static void *
paulfd79ac92004-10-13 05:06:08 +00001561route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001562{
1563 char *p;
1564 char *str;
1565 int len;
1566
1567 p = strchr (arg, ' ');
1568 if (p)
1569 {
1570 len = p - arg;
1571 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1572 memcpy (str, arg, len);
1573 }
1574 else
1575 str = NULL;
1576
1577 return str;
1578}
1579
1580/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001581static void
paul718e3742002-12-13 20:15:29 +00001582route_set_community_delete_free (void *rule)
1583{
1584 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1585}
1586
1587/* Set community rule structure. */
1588struct route_map_rule_cmd route_set_community_delete_cmd =
1589{
1590 "comm-list",
1591 route_set_community_delete,
1592 route_set_community_delete_compile,
1593 route_set_community_delete_free,
1594};
David Lamparter6b0655a2014-06-04 06:53:35 +02001595
paul718e3742002-12-13 20:15:29 +00001596/* `set extcommunity rt COMMUNITY' */
1597
David Lamparter73d78ea2014-06-04 00:58:47 +02001598/* For community set mechanism. Used by _rt and _soo. */
paul94f2b392005-06-28 12:44:16 +00001599static route_map_result_t
David Lamparter73d78ea2014-06-04 00:58:47 +02001600route_set_ecommunity (void *rule, struct prefix *prefix,
1601 route_map_object_t type, void *object)
paul718e3742002-12-13 20:15:29 +00001602{
1603 struct ecommunity *ecom;
1604 struct ecommunity *new_ecom;
1605 struct ecommunity *old_ecom;
1606 struct bgp_info *bgp_info;
1607
1608 if (type == RMAP_BGP)
1609 {
1610 ecom = rule;
1611 bgp_info = object;
1612
1613 if (! ecom)
1614 return RMAP_OKAY;
1615
1616 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001617 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001618
1619 if (old_ecom)
David Lamparter27bf90a2014-06-04 00:59:01 +02001620 {
1621 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1622
1623 /* old_ecom->refcnt = 1 => owned elsewhere, e.g. bgp_update_receive()
1624 * ->refcnt = 0 => set by a previous route-map statement */
1625 if (!old_ecom->refcnt)
1626 ecommunity_free (&old_ecom);
1627 }
paul718e3742002-12-13 20:15:29 +00001628 else
1629 new_ecom = ecommunity_dup (ecom);
1630
David Lamparter27bf90a2014-06-04 00:59:01 +02001631 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
1632 bgp_info->attr->extra->ecommunity = new_ecom;
hasso70601e02005-05-27 03:26:57 +00001633
paul718e3742002-12-13 20:15:29 +00001634 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1635 }
1636 return RMAP_OKAY;
1637}
1638
1639/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001640static void *
paulfd79ac92004-10-13 05:06:08 +00001641route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001642{
1643 struct ecommunity *ecom;
1644
1645 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1646 if (! ecom)
1647 return NULL;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001648 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001649}
1650
David Lamparter73d78ea2014-06-04 00:58:47 +02001651/* Free function for set community. Used by _rt and _soo */
paul94f2b392005-06-28 12:44:16 +00001652static void
David Lamparter73d78ea2014-06-04 00:58:47 +02001653route_set_ecommunity_free (void *rule)
paul718e3742002-12-13 20:15:29 +00001654{
1655 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001656 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001657}
1658
1659/* Set community rule structure. */
1660struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1661{
1662 "extcommunity rt",
David Lamparter73d78ea2014-06-04 00:58:47 +02001663 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001664 route_set_ecommunity_rt_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001665 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001666};
1667
1668/* `set extcommunity soo COMMUNITY' */
1669
paul718e3742002-12-13 20:15:29 +00001670/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001671static void *
paulfd79ac92004-10-13 05:06:08 +00001672route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001673{
1674 struct ecommunity *ecom;
1675
1676 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1677 if (! ecom)
1678 return NULL;
1679
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001680 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001681}
1682
paul718e3742002-12-13 20:15:29 +00001683/* Set community rule structure. */
1684struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1685{
1686 "extcommunity soo",
David Lamparter73d78ea2014-06-04 00:58:47 +02001687 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001688 route_set_ecommunity_soo_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001689 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001690};
David Lamparter6b0655a2014-06-04 06:53:35 +02001691
paul718e3742002-12-13 20:15:29 +00001692/* `set origin ORIGIN' */
1693
1694/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001695static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001696route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1697{
1698 u_char *origin;
1699 struct bgp_info *bgp_info;
1700
1701 if (type == RMAP_BGP)
1702 {
1703 origin = rule;
1704 bgp_info = object;
1705
1706 bgp_info->attr->origin = *origin;
1707 }
1708
1709 return RMAP_OKAY;
1710}
1711
1712/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001713static void *
paulfd79ac92004-10-13 05:06:08 +00001714route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001715{
1716 u_char *origin;
1717
1718 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1719
1720 if (strcmp (arg, "igp") == 0)
1721 *origin = 0;
1722 else if (strcmp (arg, "egp") == 0)
1723 *origin = 1;
1724 else
1725 *origin = 2;
1726
1727 return origin;
1728}
1729
1730/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001731static void
paul718e3742002-12-13 20:15:29 +00001732route_set_origin_free (void *rule)
1733{
1734 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1735}
1736
Timo Teräs2aa640b2014-05-20 08:57:26 +03001737/* Set origin rule structure. */
paul718e3742002-12-13 20:15:29 +00001738struct route_map_rule_cmd route_set_origin_cmd =
1739{
1740 "origin",
1741 route_set_origin,
1742 route_set_origin_compile,
1743 route_set_origin_free,
1744};
David Lamparter6b0655a2014-06-04 06:53:35 +02001745
paul718e3742002-12-13 20:15:29 +00001746/* `set atomic-aggregate' */
1747
1748/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001749static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001750route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1751 route_map_object_t type, void *object)
1752{
1753 struct bgp_info *bgp_info;
1754
1755 if (type == RMAP_BGP)
1756 {
1757 bgp_info = object;
1758 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1759 }
1760
1761 return RMAP_OKAY;
1762}
1763
1764/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001765static void *
paulfd79ac92004-10-13 05:06:08 +00001766route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001767{
1768 return (void *)1;
1769}
1770
1771/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001772static void
paul718e3742002-12-13 20:15:29 +00001773route_set_atomic_aggregate_free (void *rule)
1774{
1775 return;
1776}
1777
1778/* Set atomic aggregate rule structure. */
1779struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1780{
1781 "atomic-aggregate",
1782 route_set_atomic_aggregate,
1783 route_set_atomic_aggregate_compile,
1784 route_set_atomic_aggregate_free,
1785};
David Lamparter6b0655a2014-06-04 06:53:35 +02001786
paul718e3742002-12-13 20:15:29 +00001787/* `set aggregator as AS A.B.C.D' */
1788struct aggregator
1789{
1790 as_t as;
1791 struct in_addr address;
1792};
1793
paul94f2b392005-06-28 12:44:16 +00001794static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001795route_set_aggregator_as (void *rule, struct prefix *prefix,
1796 route_map_object_t type, void *object)
1797{
1798 struct bgp_info *bgp_info;
1799 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001800 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001801
1802 if (type == RMAP_BGP)
1803 {
1804 bgp_info = object;
1805 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001806 ae = bgp_attr_extra_get (bgp_info->attr);
1807
1808 ae->aggregator_as = aggregator->as;
1809 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001810 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1811 }
1812
1813 return RMAP_OKAY;
1814}
1815
paul94f2b392005-06-28 12:44:16 +00001816static void *
paulfd79ac92004-10-13 05:06:08 +00001817route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001818{
1819 struct aggregator *aggregator;
1820 char as[10];
1821 char address[20];
1822
Stephen Hemminger393deb92008-08-18 14:13:29 -07001823 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
paul718e3742002-12-13 20:15:29 +00001824 sscanf (arg, "%s %s", as, address);
1825
1826 aggregator->as = strtoul (as, NULL, 10);
1827 inet_aton (address, &aggregator->address);
1828
1829 return aggregator;
1830}
1831
paul94f2b392005-06-28 12:44:16 +00001832static void
paul718e3742002-12-13 20:15:29 +00001833route_set_aggregator_as_free (void *rule)
1834{
1835 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1836}
1837
1838struct route_map_rule_cmd route_set_aggregator_as_cmd =
1839{
1840 "aggregator as",
1841 route_set_aggregator_as,
1842 route_set_aggregator_as_compile,
1843 route_set_aggregator_as_free,
1844};
David Lamparter6b0655a2014-06-04 06:53:35 +02001845
Piotr Chytła605aa332015-12-01 10:03:54 -05001846/* Set tag to object. object must be pointer to struct bgp_info */
1847static route_map_result_t
1848route_set_tag (void *rule, struct prefix *prefix,
1849 route_map_object_t type, void *object)
1850{
Paul Jakma96d10602016-07-01 14:23:45 +01001851 route_tag_t *tag;
Piotr Chytła605aa332015-12-01 10:03:54 -05001852 struct bgp_info *bgp_info;
1853 struct attr_extra *ae;
1854
1855 if (type == RMAP_BGP)
1856 {
1857 tag = rule;
1858 bgp_info = object;
1859 ae = bgp_attr_extra_get (bgp_info->attr);
1860
1861 /* Set tag value */
1862 ae->tag=*tag;
1863
1864 }
1865
1866 return RMAP_OKAY;
1867}
1868
1869/* Route map `tag' compile function. Given string is converted to u_short. */
1870static void *
1871route_set_tag_compile (const char *arg)
1872{
Paul Jakma96d10602016-07-01 14:23:45 +01001873 route_tag_t *tag;
1874 route_tag_t tmp;
Piotr Chytła605aa332015-12-01 10:03:54 -05001875
1876 /* tag value shoud be integer. */
1877 if (! all_digit (arg))
1878 return NULL;
1879
1880 tmp = atoi(arg);
1881
1882 if (tmp < 1)
1883 return NULL;
1884
1885 tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
1886
1887 if (!tag)
1888 return tag;
1889
1890 *tag = tmp;
1891
1892 return tag;
1893}
1894
1895/* Free route map's tag value. */
1896static void
1897route_set_tag_free (void *rule)
1898{
1899 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1900}
1901
1902
1903/* Route map commands for tag set. */
1904struct route_map_rule_cmd route_set_tag_cmd =
1905{
1906 "tag",
1907 route_set_tag,
1908 route_set_tag_compile,
1909 route_set_tag_free,
1910};
1911
1912
paul718e3742002-12-13 20:15:29 +00001913/* `match ipv6 address IP_ACCESS_LIST' */
1914
paul94f2b392005-06-28 12:44:16 +00001915static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001916route_match_ipv6_address (void *rule, struct prefix *prefix,
1917 route_map_object_t type, void *object)
1918{
1919 struct access_list *alist;
1920
1921 if (type == RMAP_BGP)
1922 {
1923 alist = access_list_lookup (AFI_IP6, (char *) rule);
1924 if (alist == NULL)
1925 return RMAP_NOMATCH;
1926
1927 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1928 RMAP_NOMATCH : RMAP_MATCH);
1929 }
1930 return RMAP_NOMATCH;
1931}
1932
paul94f2b392005-06-28 12:44:16 +00001933static void *
paulfd79ac92004-10-13 05:06:08 +00001934route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001935{
1936 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1937}
1938
paul94f2b392005-06-28 12:44:16 +00001939static void
paul718e3742002-12-13 20:15:29 +00001940route_match_ipv6_address_free (void *rule)
1941{
1942 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1943}
1944
1945/* Route map commands for ip address matching. */
1946struct route_map_rule_cmd route_match_ipv6_address_cmd =
1947{
1948 "ipv6 address",
1949 route_match_ipv6_address,
1950 route_match_ipv6_address_compile,
1951 route_match_ipv6_address_free
1952};
David Lamparter6b0655a2014-06-04 06:53:35 +02001953
paul718e3742002-12-13 20:15:29 +00001954/* `match ipv6 next-hop IP_ADDRESS' */
1955
paul94f2b392005-06-28 12:44:16 +00001956static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001957route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1958 route_map_object_t type, void *object)
1959{
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001960 struct in6_addr *addr = rule;
paul718e3742002-12-13 20:15:29 +00001961 struct bgp_info *bgp_info;
1962
1963 if (type == RMAP_BGP)
1964 {
paul718e3742002-12-13 20:15:29 +00001965 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001966
1967 if (!bgp_info->attr->extra)
1968 return RMAP_NOMATCH;
1969
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001970 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, addr))
paul718e3742002-12-13 20:15:29 +00001971 return RMAP_MATCH;
1972
Paul Jakmafb982c22007-05-04 20:15:47 +00001973 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001974 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, addr))
paul718e3742002-12-13 20:15:29 +00001975 return RMAP_MATCH;
1976
1977 return RMAP_NOMATCH;
1978 }
1979
1980 return RMAP_NOMATCH;
1981}
1982
paul94f2b392005-06-28 12:44:16 +00001983static void *
paulfd79ac92004-10-13 05:06:08 +00001984route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001985{
1986 struct in6_addr *address;
1987 int ret;
1988
1989 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1990
1991 ret = inet_pton (AF_INET6, arg, address);
1992 if (!ret)
1993 {
1994 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1995 return NULL;
1996 }
1997
1998 return address;
1999}
2000
paul94f2b392005-06-28 12:44:16 +00002001static void
paul718e3742002-12-13 20:15:29 +00002002route_match_ipv6_next_hop_free (void *rule)
2003{
2004 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2005}
2006
2007struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
2008{
2009 "ipv6 next-hop",
2010 route_match_ipv6_next_hop,
2011 route_match_ipv6_next_hop_compile,
2012 route_match_ipv6_next_hop_free
2013};
David Lamparter6b0655a2014-06-04 06:53:35 +02002014
paul718e3742002-12-13 20:15:29 +00002015/* `match ipv6 address prefix-list PREFIX_LIST' */
2016
paul94f2b392005-06-28 12:44:16 +00002017static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002018route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
2019 route_map_object_t type, void *object)
2020{
2021 struct prefix_list *plist;
2022
2023 if (type == RMAP_BGP)
2024 {
2025 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
2026 if (plist == NULL)
2027 return RMAP_NOMATCH;
2028
2029 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
2030 RMAP_NOMATCH : RMAP_MATCH);
2031 }
2032 return RMAP_NOMATCH;
2033}
2034
paul94f2b392005-06-28 12:44:16 +00002035static void *
paulfd79ac92004-10-13 05:06:08 +00002036route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002037{
2038 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
2039}
2040
paul94f2b392005-06-28 12:44:16 +00002041static void
paul718e3742002-12-13 20:15:29 +00002042route_match_ipv6_address_prefix_list_free (void *rule)
2043{
2044 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2045}
2046
2047struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
2048{
2049 "ipv6 address prefix-list",
2050 route_match_ipv6_address_prefix_list,
2051 route_match_ipv6_address_prefix_list_compile,
2052 route_match_ipv6_address_prefix_list_free
2053};
David Lamparter6b0655a2014-06-04 06:53:35 +02002054
paul718e3742002-12-13 20:15:29 +00002055/* `set ipv6 nexthop global IP_ADDRESS' */
2056
2057/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00002058static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002059route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
2060 route_map_object_t type, void *object)
2061{
2062 struct in6_addr *address;
2063 struct bgp_info *bgp_info;
2064
2065 if (type == RMAP_BGP)
2066 {
2067 /* Fetch routemap's rule information. */
2068 address = rule;
2069 bgp_info = object;
2070
2071 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002072 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00002073
2074 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002075 if (bgp_info->attr->extra->mp_nexthop_len == 0)
2076 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00002077 }
2078
2079 return RMAP_OKAY;
2080}
2081
2082/* Route map `ip next-hop' compile function. Given string is converted
2083 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00002084static void *
paulfd79ac92004-10-13 05:06:08 +00002085route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002086{
2087 int ret;
2088 struct in6_addr *address;
2089
2090 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2091
2092 ret = inet_pton (AF_INET6, arg, address);
2093
2094 if (ret == 0)
2095 {
2096 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2097 return NULL;
2098 }
2099
2100 return address;
2101}
2102
2103/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00002104static void
paul718e3742002-12-13 20:15:29 +00002105route_set_ipv6_nexthop_global_free (void *rule)
2106{
2107 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2108}
2109
2110/* Route map commands for ip nexthop set. */
2111struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
2112{
2113 "ipv6 next-hop global",
2114 route_set_ipv6_nexthop_global,
2115 route_set_ipv6_nexthop_global_compile,
2116 route_set_ipv6_nexthop_global_free
2117};
David Lamparter6b0655a2014-06-04 06:53:35 +02002118
paul718e3742002-12-13 20:15:29 +00002119/* `set ipv6 nexthop local IP_ADDRESS' */
2120
2121/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00002122static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002123route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
2124 route_map_object_t type, void *object)
2125{
2126 struct in6_addr *address;
2127 struct bgp_info *bgp_info;
2128
2129 if (type == RMAP_BGP)
2130 {
2131 /* Fetch routemap's rule information. */
2132 address = rule;
2133 bgp_info = object;
2134
2135 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002136 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00002137
2138 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002139 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2140 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00002141 }
2142
2143 return RMAP_OKAY;
2144}
2145
2146/* Route map `ip nexthop' compile function. Given string is converted
2147 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00002148static void *
paulfd79ac92004-10-13 05:06:08 +00002149route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002150{
2151 int ret;
2152 struct in6_addr *address;
2153
2154 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2155
2156 ret = inet_pton (AF_INET6, arg, address);
2157
2158 if (ret == 0)
2159 {
2160 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2161 return NULL;
2162 }
2163
2164 return address;
2165}
2166
2167/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00002168static void
paul718e3742002-12-13 20:15:29 +00002169route_set_ipv6_nexthop_local_free (void *rule)
2170{
2171 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2172}
2173
2174/* Route map commands for ip nexthop set. */
2175struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
2176{
2177 "ipv6 next-hop local",
2178 route_set_ipv6_nexthop_local,
2179 route_set_ipv6_nexthop_local_compile,
2180 route_set_ipv6_nexthop_local_free
2181};
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002182
2183/* `set ipv6 nexthop peer-address' */
2184
2185/* Set nexthop to object. ojbect must be pointer to struct attr. */
2186static route_map_result_t
2187route_set_ipv6_nexthop_peer (void *rule, struct prefix *prefix,
2188 route_map_object_t type, void *object)
2189{
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002190 struct in6_addr peer_address;
2191 struct bgp_info *bgp_info;
2192 struct peer *peer;
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002193
2194 if (type == RMAP_BGP)
2195 {
2196 /* Fetch routemap's rule information. */
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002197 bgp_info = object;
2198 peer = bgp_info->peer;
2199
2200 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
2201 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
2202 && peer->su_remote
2203 && sockunion_family (peer->su_remote) == AF_INET6)
2204 {
Christian Franke5cb81ce2016-06-14 20:06:56 +02002205 peer_address = peer->su_remote->sin6.sin6_addr;
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002206 }
2207 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
2208 && peer->su_local
2209 && sockunion_family (peer->su_local) == AF_INET6)
2210 {
Christian Franke5cb81ce2016-06-14 20:06:56 +02002211 peer_address = peer->su_local->sin6.sin6_addr;
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002212 }
2213
2214 if (IN6_IS_ADDR_LINKLOCAL(&peer_address))
2215 {
2216 /* Set next hop value. */
2217 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = peer_address;
2218
2219 /* Set nexthop length. */
2220 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2221 bgp_info->attr->extra->mp_nexthop_len = 32;
2222 }
2223 else
2224 {
2225 /* Set next hop value. */
2226 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = peer_address;
2227
2228 /* Set nexthop length. */
2229 if (bgp_info->attr->extra->mp_nexthop_len == 0)
2230 bgp_info->attr->extra->mp_nexthop_len = 16;
2231 }
2232 }
2233
2234 return RMAP_OKAY;
2235}
2236
2237/* Route map `ip next-hop' compile function. Given string is converted
2238 to struct in_addr structure. */
2239static void *
2240route_set_ipv6_nexthop_peer_compile (const char *arg)
2241{
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002242 int *rins = NULL;
2243
2244 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (int));
2245 *rins = 1;
2246
2247 return rins;
2248}
2249
2250/* Free route map's compiled `ip next-hop' value. */
2251static void
2252route_set_ipv6_nexthop_peer_free (void *rule)
2253{
2254 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2255}
2256
2257/* Route map commands for ip nexthop set. */
2258struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd =
2259{
2260 "ipv6 next-hop peer-address",
2261 route_set_ipv6_nexthop_peer,
2262 route_set_ipv6_nexthop_peer_compile,
2263 route_set_ipv6_nexthop_peer_free
2264};
2265
paul718e3742002-12-13 20:15:29 +00002266/* `set vpnv4 nexthop A.B.C.D' */
2267
paul94f2b392005-06-28 12:44:16 +00002268static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002269route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2270 route_map_object_t type, void *object)
2271{
2272 struct in_addr *address;
2273 struct bgp_info *bgp_info;
2274
2275 if (type == RMAP_BGP)
2276 {
2277 /* Fetch routemap's rule information. */
2278 address = rule;
2279 bgp_info = object;
2280
2281 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002282 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
Lou Berger050defe2016-01-12 13:41:59 -05002283 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_len = 4;
paul718e3742002-12-13 20:15:29 +00002284 }
2285
2286 return RMAP_OKAY;
2287}
2288
paul94f2b392005-06-28 12:44:16 +00002289static void *
paulfd79ac92004-10-13 05:06:08 +00002290route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002291{
2292 int ret;
2293 struct in_addr *address;
2294
2295 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2296
2297 ret = inet_aton (arg, address);
2298
2299 if (ret == 0)
2300 {
2301 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2302 return NULL;
2303 }
2304
2305 return address;
2306}
2307
paul94f2b392005-06-28 12:44:16 +00002308static void
paul718e3742002-12-13 20:15:29 +00002309route_set_vpnv4_nexthop_free (void *rule)
2310{
2311 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2312}
2313
2314/* Route map commands for ip nexthop set. */
2315struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2316{
2317 "vpnv4 next-hop",
2318 route_set_vpnv4_nexthop,
2319 route_set_vpnv4_nexthop_compile,
2320 route_set_vpnv4_nexthop_free
2321};
David Lamparter6b0655a2014-06-04 06:53:35 +02002322
paul718e3742002-12-13 20:15:29 +00002323/* `set originator-id' */
2324
2325/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002326static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002327route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2328{
2329 struct in_addr *address;
2330 struct bgp_info *bgp_info;
2331
2332 if (type == RMAP_BGP)
2333 {
2334 address = rule;
2335 bgp_info = object;
2336
2337 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002338 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002339 }
2340
2341 return RMAP_OKAY;
2342}
2343
2344/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002345static void *
paulfd79ac92004-10-13 05:06:08 +00002346route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002347{
2348 int ret;
2349 struct in_addr *address;
2350
2351 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2352
2353 ret = inet_aton (arg, address);
2354
2355 if (ret == 0)
2356 {
2357 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2358 return NULL;
2359 }
2360
2361 return address;
2362}
2363
2364/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002365static void
paul718e3742002-12-13 20:15:29 +00002366route_set_originator_id_free (void *rule)
2367{
2368 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2369}
2370
Timo Teräs2aa640b2014-05-20 08:57:26 +03002371/* Set originator-id rule structure. */
paul718e3742002-12-13 20:15:29 +00002372struct route_map_rule_cmd route_set_originator_id_cmd =
2373{
2374 "originator-id",
2375 route_set_originator_id,
2376 route_set_originator_id_compile,
2377 route_set_originator_id_free,
2378};
David Lamparter6b0655a2014-06-04 06:53:35 +02002379
paul718e3742002-12-13 20:15:29 +00002380/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002381static int
paul718e3742002-12-13 20:15:29 +00002382bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002383 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002384{
2385 int ret;
2386
2387 ret = route_map_add_match (index, command, arg);
2388 if (ret)
2389 {
2390 switch (ret)
2391 {
2392 case RMAP_RULE_MISSING:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002393 vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002394 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002395 case RMAP_COMPILE_ERROR:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002396 vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002397 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002398 }
2399 }
2400 return CMD_SUCCESS;
2401}
2402
2403/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002404static int
paul718e3742002-12-13 20:15:29 +00002405bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002406 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002407{
2408 int ret;
2409
2410 ret = route_map_delete_match (index, command, arg);
2411 if (ret)
2412 {
2413 switch (ret)
2414 {
2415 case RMAP_RULE_MISSING:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002416 vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002417 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002418 case RMAP_COMPILE_ERROR:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002419 vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002420 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002421 }
2422 }
2423 return CMD_SUCCESS;
2424}
2425
2426/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002427static int
paul718e3742002-12-13 20:15:29 +00002428bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002429 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002430{
2431 int ret;
2432
2433 ret = route_map_add_set (index, command, arg);
2434 if (ret)
2435 {
2436 switch (ret)
2437 {
2438 case RMAP_RULE_MISSING:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002439 vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002440 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002441 case RMAP_COMPILE_ERROR:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002442 vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002443 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002444 }
2445 }
2446 return CMD_SUCCESS;
2447}
2448
2449/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002450static int
paul718e3742002-12-13 20:15:29 +00002451bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002452 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002453{
2454 int ret;
2455
2456 ret = route_map_delete_set (index, command, arg);
2457 if (ret)
2458 {
2459 switch (ret)
2460 {
2461 case RMAP_RULE_MISSING:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002462 vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002463 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002464 case RMAP_COMPILE_ERROR:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002465 vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002466 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002467 }
2468 }
2469 return CMD_SUCCESS;
2470}
2471
2472/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002473static void
paulfd79ac92004-10-13 05:06:08 +00002474bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002475{
2476 int i;
2477 afi_t afi;
2478 safi_t safi;
2479 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002480 struct listnode *node, *nnode;
2481 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002482 struct bgp *bgp;
2483 struct peer *peer;
2484 struct peer_group *group;
2485 struct bgp_filter *filter;
2486 struct bgp_node *bn;
2487 struct bgp_static *bgp_static;
2488
Lou Berger82dd7072016-01-12 13:41:57 -05002489 if (bm->bgp == NULL) /* may be called during cleanup */
2490 return;
2491
paul718e3742002-12-13 20:15:29 +00002492 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002493 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002494 {
paul1eb8ef22005-04-07 07:30:20 +00002495 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002496 {
2497 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2498 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2499 {
2500 filter = &peer->filter[afi][safi];
2501
paulfee0f4c2004-09-13 05:12:46 +00002502 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002503 {
2504 if (filter->map[direct].name)
2505 filter->map[direct].map =
2506 route_map_lookup_by_name (filter->map[direct].name);
2507 else
2508 filter->map[direct].map = NULL;
2509 }
2510
2511 if (filter->usmap.name)
2512 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2513 else
2514 filter->usmap.map = NULL;
2515 }
2516 }
paul1eb8ef22005-04-07 07:30:20 +00002517 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002518 {
2519 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2520 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2521 {
2522 filter = &group->conf->filter[afi][safi];
2523
paulfee0f4c2004-09-13 05:12:46 +00002524 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002525 {
2526 if (filter->map[direct].name)
2527 filter->map[direct].map =
2528 route_map_lookup_by_name (filter->map[direct].name);
2529 else
2530 filter->map[direct].map = NULL;
2531 }
2532
2533 if (filter->usmap.name)
2534 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2535 else
2536 filter->usmap.map = NULL;
2537 }
2538 }
2539 }
2540
2541 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002542 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002543 {
paul1eb8ef22005-04-07 07:30:20 +00002544 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002545 {
2546 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2547 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2548 {
2549 if (peer->default_rmap[afi][safi].name)
2550 peer->default_rmap[afi][safi].map =
2551 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2552 else
2553 peer->default_rmap[afi][safi].map = NULL;
2554 }
2555 }
2556 }
2557
2558 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002559 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002560 {
2561 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2562 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2563 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2564 bn = bgp_route_next (bn))
2565 if ((bgp_static = bn->info) != NULL)
2566 {
2567 if (bgp_static->rmap.name)
2568 bgp_static->rmap.map =
2569 route_map_lookup_by_name (bgp_static->rmap.name);
2570 else
2571 bgp_static->rmap.map = NULL;
2572 }
2573 }
2574
2575 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002576 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002577 {
2578 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2579 {
Donald Sharpf3cfc462016-01-07 09:33:28 -05002580 if (bgp->rmap[AFI_IP][i].name)
2581 bgp->rmap[AFI_IP][i].map =
2582 route_map_lookup_by_name (bgp->rmap[AFI_IP][i].name);
2583 if (bgp->rmap[AFI_IP6][i].name)
2584 bgp->rmap[AFI_IP6][i].map =
Andrej Ota220355d2016-05-09 20:49:01 +02002585 route_map_lookup_by_name (bgp->rmap[AFI_IP6][i].name);
paul718e3742002-12-13 20:15:29 +00002586 }
2587 }
2588}
David Lamparter6b0655a2014-06-04 06:53:35 +02002589
paulfee0f4c2004-09-13 05:12:46 +00002590DEFUN (match_peer,
2591 match_peer_cmd,
2592 "match peer (A.B.C.D|X:X::X:X)",
2593 MATCH_STR
2594 "Match peer address\n"
Igor Ryzhov93b493a2016-05-11 15:26:39 +03002595 "IP address of peer\n"
2596 "IPv6 address of peer\n")
paulfee0f4c2004-09-13 05:12:46 +00002597{
2598 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2599}
2600
2601DEFUN (match_peer_local,
2602 match_peer_local_cmd,
2603 "match peer local",
2604 MATCH_STR
2605 "Match peer address\n"
2606 "Static or Redistributed routes\n")
2607{
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +02002608 return bgp_route_match_add (vty, vty->index, "peer", "local");
paulfee0f4c2004-09-13 05:12:46 +00002609}
2610
2611DEFUN (no_match_peer,
2612 no_match_peer_cmd,
2613 "no match peer",
2614 NO_STR
2615 MATCH_STR
2616 "Match peer address\n")
2617{
2618 if (argc == 0)
2619 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2620
2621 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2622}
2623
2624ALIAS (no_match_peer,
2625 no_match_peer_val_cmd,
2626 "no match peer (A.B.C.D|X:X::X:X)",
2627 NO_STR
2628 MATCH_STR
2629 "Match peer address\n"
Igor Ryzhov93b493a2016-05-11 15:26:39 +03002630 "IP address of peer\n"
2631 "IPv6 address of peer\n")
paulfee0f4c2004-09-13 05:12:46 +00002632
2633ALIAS (no_match_peer,
2634 no_match_peer_local_cmd,
2635 "no match peer local",
2636 NO_STR
2637 MATCH_STR
2638 "Match peer address\n"
2639 "Static or Redistributed routes\n")
2640
paul718e3742002-12-13 20:15:29 +00002641DEFUN (match_ip_address,
2642 match_ip_address_cmd,
2643 "match ip address (<1-199>|<1300-2699>|WORD)",
2644 MATCH_STR
2645 IP_STR
2646 "Match address of route\n"
2647 "IP access-list number\n"
2648 "IP access-list number (expanded range)\n"
2649 "IP Access-list name\n")
2650{
2651 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2652}
2653
2654DEFUN (no_match_ip_address,
2655 no_match_ip_address_cmd,
2656 "no match ip address",
2657 NO_STR
2658 MATCH_STR
2659 IP_STR
2660 "Match address of route\n")
2661{
2662 if (argc == 0)
2663 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2664
2665 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2666}
2667
2668ALIAS (no_match_ip_address,
2669 no_match_ip_address_val_cmd,
2670 "no match ip address (<1-199>|<1300-2699>|WORD)",
2671 NO_STR
2672 MATCH_STR
2673 IP_STR
2674 "Match address of route\n"
2675 "IP access-list number\n"
2676 "IP access-list number (expanded range)\n"
2677 "IP Access-list name\n")
2678
2679DEFUN (match_ip_next_hop,
2680 match_ip_next_hop_cmd,
2681 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2682 MATCH_STR
2683 IP_STR
2684 "Match next-hop address of route\n"
2685 "IP access-list number\n"
2686 "IP access-list number (expanded range)\n"
2687 "IP Access-list name\n")
2688{
2689 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2690}
2691
2692DEFUN (no_match_ip_next_hop,
2693 no_match_ip_next_hop_cmd,
2694 "no match ip next-hop",
2695 NO_STR
2696 MATCH_STR
2697 IP_STR
2698 "Match next-hop address of route\n")
2699{
2700 if (argc == 0)
2701 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2702
2703 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2704}
2705
2706ALIAS (no_match_ip_next_hop,
2707 no_match_ip_next_hop_val_cmd,
2708 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2709 NO_STR
2710 MATCH_STR
2711 IP_STR
2712 "Match next-hop address of route\n"
2713 "IP access-list number\n"
2714 "IP access-list number (expanded range)\n"
2715 "IP Access-list name\n")
2716
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04002717/* match probability { */
2718
2719DEFUN (match_probability,
2720 match_probability_cmd,
2721 "match probability <0-100>",
2722 MATCH_STR
2723 "Match portion of routes defined by percentage value\n"
2724 "Percentage of routes\n")
2725{
2726 return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
2727}
2728
2729DEFUN (no_match_probability,
2730 no_match_probability_cmd,
2731 "no match probability",
2732 NO_STR
2733 MATCH_STR
2734 "Match portion of routes defined by percentage value\n")
2735{
2736 return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL);
2737}
2738
2739ALIAS (no_match_probability,
2740 no_match_probability_val_cmd,
2741 "no match probability <1-99>",
2742 NO_STR
2743 MATCH_STR
2744 "Match portion of routes defined by percentage value\n"
2745 "Percentage of routes\n")
2746
2747/* } */
2748
hassoc1643bb2005-02-02 16:43:17 +00002749DEFUN (match_ip_route_source,
2750 match_ip_route_source_cmd,
2751 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2752 MATCH_STR
2753 IP_STR
2754 "Match advertising source address of route\n"
2755 "IP access-list number\n"
2756 "IP access-list number (expanded range)\n"
2757 "IP standard access-list name\n")
2758{
2759 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2760}
2761
2762DEFUN (no_match_ip_route_source,
2763 no_match_ip_route_source_cmd,
2764 "no match ip route-source",
2765 NO_STR
2766 MATCH_STR
2767 IP_STR
2768 "Match advertising source address of route\n")
2769{
2770 if (argc == 0)
2771 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2772
2773 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2774}
2775
2776ALIAS (no_match_ip_route_source,
2777 no_match_ip_route_source_val_cmd,
2778 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2779 NO_STR
2780 MATCH_STR
2781 IP_STR
2782 "Match advertising source address of route\n"
2783 "IP access-list number\n"
2784 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002785 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002786
paul718e3742002-12-13 20:15:29 +00002787DEFUN (match_ip_address_prefix_list,
2788 match_ip_address_prefix_list_cmd,
2789 "match ip address prefix-list WORD",
2790 MATCH_STR
2791 IP_STR
2792 "Match address of route\n"
2793 "Match entries of prefix-lists\n"
2794 "IP prefix-list name\n")
2795{
2796 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2797}
2798
2799DEFUN (no_match_ip_address_prefix_list,
2800 no_match_ip_address_prefix_list_cmd,
2801 "no match ip address prefix-list",
2802 NO_STR
2803 MATCH_STR
2804 IP_STR
2805 "Match address of route\n"
2806 "Match entries of prefix-lists\n")
2807{
2808 if (argc == 0)
2809 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2810
2811 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2812}
2813
2814ALIAS (no_match_ip_address_prefix_list,
2815 no_match_ip_address_prefix_list_val_cmd,
2816 "no match ip address prefix-list WORD",
2817 NO_STR
2818 MATCH_STR
2819 IP_STR
2820 "Match address of route\n"
2821 "Match entries of prefix-lists\n"
2822 "IP prefix-list name\n")
2823
2824DEFUN (match_ip_next_hop_prefix_list,
2825 match_ip_next_hop_prefix_list_cmd,
2826 "match ip next-hop prefix-list WORD",
2827 MATCH_STR
2828 IP_STR
2829 "Match next-hop address of route\n"
2830 "Match entries of prefix-lists\n"
2831 "IP prefix-list name\n")
2832{
2833 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2834}
2835
2836DEFUN (no_match_ip_next_hop_prefix_list,
2837 no_match_ip_next_hop_prefix_list_cmd,
2838 "no match ip next-hop prefix-list",
2839 NO_STR
2840 MATCH_STR
2841 IP_STR
2842 "Match next-hop address of route\n"
2843 "Match entries of prefix-lists\n")
2844{
2845 if (argc == 0)
2846 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2847
2848 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2849}
2850
2851ALIAS (no_match_ip_next_hop_prefix_list,
2852 no_match_ip_next_hop_prefix_list_val_cmd,
2853 "no match ip next-hop prefix-list WORD",
2854 NO_STR
2855 MATCH_STR
2856 IP_STR
2857 "Match next-hop address of route\n"
2858 "Match entries of prefix-lists\n"
2859 "IP prefix-list name\n")
2860
hassoc1643bb2005-02-02 16:43:17 +00002861DEFUN (match_ip_route_source_prefix_list,
2862 match_ip_route_source_prefix_list_cmd,
2863 "match ip route-source prefix-list WORD",
2864 MATCH_STR
2865 IP_STR
2866 "Match advertising source address of route\n"
2867 "Match entries of prefix-lists\n"
2868 "IP prefix-list name\n")
2869{
2870 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2871}
2872
2873DEFUN (no_match_ip_route_source_prefix_list,
2874 no_match_ip_route_source_prefix_list_cmd,
2875 "no match ip route-source prefix-list",
2876 NO_STR
2877 MATCH_STR
2878 IP_STR
2879 "Match advertising source address of route\n"
2880 "Match entries of prefix-lists\n")
2881{
2882 if (argc == 0)
2883 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2884
2885 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2886}
2887
2888ALIAS (no_match_ip_route_source_prefix_list,
2889 no_match_ip_route_source_prefix_list_val_cmd,
2890 "no match ip route-source prefix-list WORD",
2891 NO_STR
2892 MATCH_STR
2893 IP_STR
2894 "Match advertising source address of route\n"
2895 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002896 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002897
paul718e3742002-12-13 20:15:29 +00002898DEFUN (match_metric,
2899 match_metric_cmd,
2900 "match metric <0-4294967295>",
2901 MATCH_STR
2902 "Match metric of route\n"
2903 "Metric value\n")
2904{
2905 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2906}
2907
2908DEFUN (no_match_metric,
2909 no_match_metric_cmd,
2910 "no match metric",
2911 NO_STR
2912 MATCH_STR
2913 "Match metric of route\n")
2914{
2915 if (argc == 0)
2916 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2917
2918 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2919}
2920
2921ALIAS (no_match_metric,
2922 no_match_metric_val_cmd,
2923 "no match metric <0-4294967295>",
2924 NO_STR
2925 MATCH_STR
2926 "Match metric of route\n"
2927 "Metric value\n")
2928
Dinesh Dutt5cf768a2015-11-09 20:21:53 -05002929DEFUN (match_local_pref,
2930 match_local_pref_cmd,
2931 "match local-preference <0-4294967295>",
2932 MATCH_STR
2933 "Match local-preference of route\n"
2934 "Metric value\n")
2935{
2936 return bgp_route_match_add (vty, vty->index, "local-preference", argv[0]);
2937}
2938
2939DEFUN (no_match_local_pref,
2940 no_match_local_pref_cmd,
2941 "no match local-preference",
2942 NO_STR
2943 MATCH_STR
2944 "Match local preference of route\n")
2945{
2946 if (argc == 0)
2947 return bgp_route_match_delete (vty, vty->index, "local-preference", NULL);
2948
2949 return bgp_route_match_delete (vty, vty->index, "local-preference", argv[0]);
2950}
2951
2952ALIAS (no_match_local_pref,
2953 no_match_local_pref_val_cmd,
2954 "no match local-preference <0-4294967295>",
2955 NO_STR
2956 MATCH_STR
2957 "Match local preference of route\n"
2958 "Local preference value\n")
2959
paul718e3742002-12-13 20:15:29 +00002960DEFUN (match_community,
2961 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002962 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002963 MATCH_STR
2964 "Match BGP community list\n"
2965 "Community-list number (standard)\n"
2966 "Community-list number (expanded)\n"
2967 "Community-list name\n")
2968{
2969 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2970}
2971
2972DEFUN (match_community_exact,
2973 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002974 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002975 MATCH_STR
2976 "Match BGP community list\n"
2977 "Community-list number (standard)\n"
2978 "Community-list number (expanded)\n"
2979 "Community-list name\n"
2980 "Do exact matching of communities\n")
2981{
2982 int ret;
2983 char *argstr;
2984
2985 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2986 strlen (argv[0]) + strlen ("exact-match") + 2);
2987
2988 sprintf (argstr, "%s exact-match", argv[0]);
2989
2990 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2991
2992 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2993
2994 return ret;
2995}
2996
2997DEFUN (no_match_community,
2998 no_match_community_cmd,
2999 "no match community",
3000 NO_STR
3001 MATCH_STR
3002 "Match BGP community list\n")
3003{
3004 return bgp_route_match_delete (vty, vty->index, "community", NULL);
3005}
3006
3007ALIAS (no_match_community,
3008 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003009 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00003010 NO_STR
3011 MATCH_STR
3012 "Match BGP community list\n"
3013 "Community-list number (standard)\n"
3014 "Community-list number (expanded)\n"
3015 "Community-list name\n")
3016
3017ALIAS (no_match_community,
3018 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003019 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00003020 NO_STR
3021 MATCH_STR
3022 "Match BGP community list\n"
3023 "Community-list number (standard)\n"
3024 "Community-list number (expanded)\n"
3025 "Community-list name\n"
3026 "Do exact matching of communities\n")
3027
paul73ffb252003-04-19 15:49:49 +00003028DEFUN (match_ecommunity,
3029 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003030 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00003031 MATCH_STR
3032 "Match BGP/VPN extended community list\n"
3033 "Extended community-list number (standard)\n"
3034 "Extended community-list number (expanded)\n"
3035 "Extended community-list name\n")
3036{
3037 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
3038}
3039
3040DEFUN (no_match_ecommunity,
3041 no_match_ecommunity_cmd,
3042 "no match extcommunity",
3043 NO_STR
3044 MATCH_STR
3045 "Match BGP/VPN extended community list\n")
3046{
3047 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
3048}
3049
3050ALIAS (no_match_ecommunity,
3051 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003052 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00003053 NO_STR
3054 MATCH_STR
3055 "Match BGP/VPN extended community list\n"
3056 "Extended community-list number (standard)\n"
3057 "Extended community-list number (expanded)\n"
3058 "Extended community-list name\n")
3059
paul718e3742002-12-13 20:15:29 +00003060DEFUN (match_aspath,
3061 match_aspath_cmd,
3062 "match as-path WORD",
3063 MATCH_STR
3064 "Match BGP AS path list\n"
3065 "AS path access-list name\n")
3066{
3067 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
3068}
3069
3070DEFUN (no_match_aspath,
3071 no_match_aspath_cmd,
3072 "no match as-path",
3073 NO_STR
3074 MATCH_STR
3075 "Match BGP AS path list\n")
3076{
3077 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
3078}
3079
3080ALIAS (no_match_aspath,
3081 no_match_aspath_val_cmd,
3082 "no match as-path WORD",
3083 NO_STR
3084 MATCH_STR
3085 "Match BGP AS path list\n"
3086 "AS path access-list name\n")
3087
3088DEFUN (match_origin,
3089 match_origin_cmd,
3090 "match origin (egp|igp|incomplete)",
3091 MATCH_STR
3092 "BGP origin code\n"
3093 "remote EGP\n"
3094 "local IGP\n"
3095 "unknown heritage\n")
3096{
3097 if (strncmp (argv[0], "igp", 2) == 0)
3098 return bgp_route_match_add (vty, vty->index, "origin", "igp");
3099 if (strncmp (argv[0], "egp", 1) == 0)
3100 return bgp_route_match_add (vty, vty->index, "origin", "egp");
3101 if (strncmp (argv[0], "incomplete", 2) == 0)
3102 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
3103
3104 return CMD_WARNING;
3105}
3106
3107DEFUN (no_match_origin,
3108 no_match_origin_cmd,
3109 "no match origin",
3110 NO_STR
3111 MATCH_STR
3112 "BGP origin code\n")
3113{
3114 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
3115}
3116
3117ALIAS (no_match_origin,
3118 no_match_origin_val_cmd,
3119 "no match origin (egp|igp|incomplete)",
3120 NO_STR
3121 MATCH_STR
3122 "BGP origin code\n"
3123 "remote EGP\n"
3124 "local IGP\n"
3125 "unknown heritage\n")
3126
Piotr Chytła605aa332015-12-01 10:03:54 -05003127DEFUN (match_tag,
3128 match_tag_cmd,
3129 "match tag <1-65535>",
3130 MATCH_STR
3131 "Match tag of route\n"
3132 "Tag value\n")
3133{
3134 return bgp_route_match_add (vty, vty->index, "tag", argv[0]);
3135}
3136
3137DEFUN (no_match_tag,
3138 no_match_tag_cmd,
3139 "no match tag",
3140 NO_STR
3141 MATCH_STR
3142 "Match tag of route\n")
3143{
3144 if (argc == 0)
3145 return bgp_route_match_delete (vty, vty->index, "tag", NULL);
3146
3147 return bgp_route_match_delete (vty, vty->index, "tag", argv[0]);
3148}
3149
3150ALIAS (no_match_tag,
3151 no_match_tag_val_cmd,
3152 "no match tag <1-65535>",
3153 NO_STR
3154 MATCH_STR
3155 "Match tag of route\n"
3156 "Tag value\n")
3157
paul718e3742002-12-13 20:15:29 +00003158DEFUN (set_ip_nexthop,
3159 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00003160 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003161 SET_STR
3162 IP_STR
3163 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00003164 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00003165{
3166 union sockunion su;
3167 int ret;
3168
3169 ret = str2sockunion (argv[0], &su);
3170 if (ret < 0)
3171 {
3172 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
3173 return CMD_WARNING;
3174 }
3175
3176 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
3177}
3178
paulaf5cd0a2003-11-02 07:24:40 +00003179DEFUN (set_ip_nexthop_peer,
3180 set_ip_nexthop_peer_cmd,
3181 "set ip next-hop peer-address",
3182 SET_STR
3183 IP_STR
3184 "Next hop address\n"
3185 "Use peer address (for BGP only)\n")
3186{
3187 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
3188}
3189
paul94f2b392005-06-28 12:44:16 +00003190DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00003191 no_set_ip_nexthop_peer_cmd,
3192 "no set ip next-hop peer-address",
3193 NO_STR
3194 SET_STR
3195 IP_STR
3196 "Next hop address\n"
3197 "Use peer address (for BGP only)\n")
3198{
3199 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
3200}
3201
3202
paul718e3742002-12-13 20:15:29 +00003203DEFUN (no_set_ip_nexthop,
3204 no_set_ip_nexthop_cmd,
3205 "no set ip next-hop",
3206 NO_STR
3207 SET_STR
paul718e3742002-12-13 20:15:29 +00003208 "Next hop address\n")
3209{
paulaf5cd0a2003-11-02 07:24:40 +00003210 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00003211 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
3212
3213 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
3214}
3215
3216ALIAS (no_set_ip_nexthop,
3217 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00003218 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003219 NO_STR
3220 SET_STR
3221 IP_STR
3222 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00003223 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00003224
3225DEFUN (set_metric,
3226 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00003227 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00003228 SET_STR
3229 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00003230 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00003231{
3232 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
3233}
3234
paul73ffb252003-04-19 15:49:49 +00003235ALIAS (set_metric,
3236 set_metric_addsub_cmd,
3237 "set metric <+/-metric>",
3238 SET_STR
3239 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00003240 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00003241
Timo Teräsef757702015-04-29 09:43:04 +03003242ALIAS (set_metric,
3243 set_metric_rtt_cmd,
3244 "set metric (rtt|+rtt|-rtt)",
3245 SET_STR
3246 "Metric value for destination routing protocol\n"
3247 "Assign round trip time\n"
3248 "Add round trip time\n"
3249 "Subtract round trip time\n")
3250
paul718e3742002-12-13 20:15:29 +00003251DEFUN (no_set_metric,
3252 no_set_metric_cmd,
3253 "no set metric",
3254 NO_STR
3255 SET_STR
3256 "Metric value for destination routing protocol\n")
3257{
3258 if (argc == 0)
3259 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
3260
3261 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
3262}
3263
3264ALIAS (no_set_metric,
3265 no_set_metric_val_cmd,
3266 "no set metric <0-4294967295>",
3267 NO_STR
3268 SET_STR
3269 "Metric value for destination routing protocol\n"
3270 "Metric value\n")
3271
3272DEFUN (set_local_pref,
3273 set_local_pref_cmd,
3274 "set local-preference <0-4294967295>",
3275 SET_STR
3276 "BGP local preference path attribute\n"
3277 "Preference value\n")
3278{
3279 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
3280}
3281
3282DEFUN (no_set_local_pref,
3283 no_set_local_pref_cmd,
3284 "no set local-preference",
3285 NO_STR
3286 SET_STR
3287 "BGP local preference path attribute\n")
3288{
3289 if (argc == 0)
3290 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3291
3292 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
3293}
3294
3295ALIAS (no_set_local_pref,
3296 no_set_local_pref_val_cmd,
3297 "no set local-preference <0-4294967295>",
3298 NO_STR
3299 SET_STR
3300 "BGP local preference path attribute\n"
3301 "Preference value\n")
3302
3303DEFUN (set_weight,
3304 set_weight_cmd,
3305 "set weight <0-4294967295>",
3306 SET_STR
3307 "BGP weight for routing table\n"
3308 "Weight value\n")
3309{
3310 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3311}
3312
3313DEFUN (no_set_weight,
3314 no_set_weight_cmd,
3315 "no set weight",
3316 NO_STR
3317 SET_STR
3318 "BGP weight for routing table\n")
3319{
3320 if (argc == 0)
3321 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3322
3323 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3324}
3325
3326ALIAS (no_set_weight,
3327 no_set_weight_val_cmd,
3328 "no set weight <0-4294967295>",
3329 NO_STR
3330 SET_STR
3331 "BGP weight for routing table\n"
3332 "Weight value\n")
3333
3334DEFUN (set_aspath_prepend,
3335 set_aspath_prepend_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003336 "set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003337 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003338 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003339 "Prepend to the as-path\n"
3340 "AS number\n")
3341{
3342 int ret;
3343 char *str;
3344
3345 str = argv_concat (argv, argc, 0);
3346 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3347 XFREE (MTYPE_TMP, str);
3348
3349 return ret;
3350}
3351
Timo Teräs85c854a2014-09-30 11:31:53 +03003352ALIAS (set_aspath_prepend,
3353 set_aspath_prepend_lastas_cmd,
3354 "set as-path prepend (last-as) <1-10>",
3355 SET_STR
3356 "Transform BGP AS_PATH attribute\n"
3357 "Prepend to the as-path\n"
3358 "Use the peer's AS-number\n"
David Lamparterb7d50212015-03-03 08:53:18 +01003359 "Number of times to insert")
Timo Teräs85c854a2014-09-30 11:31:53 +03003360
paul718e3742002-12-13 20:15:29 +00003361DEFUN (no_set_aspath_prepend,
3362 no_set_aspath_prepend_cmd,
3363 "no set as-path prepend",
3364 NO_STR
3365 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003366 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003367 "Prepend to the as-path\n")
3368{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00003369 int ret;
3370 char *str;
3371
3372 if (argc == 0)
3373 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3374
3375 str = argv_concat (argv, argc, 0);
3376 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3377 XFREE (MTYPE_TMP, str);
3378 return ret;
paul718e3742002-12-13 20:15:29 +00003379}
3380
3381ALIAS (no_set_aspath_prepend,
3382 no_set_aspath_prepend_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003383 "no set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003384 NO_STR
3385 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003386 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003387 "Prepend to the as-path\n"
3388 "AS number\n")
3389
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003390DEFUN (set_aspath_exclude,
3391 set_aspath_exclude_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003392 "set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003393 SET_STR
3394 "Transform BGP AS-path attribute\n"
3395 "Exclude from the as-path\n"
3396 "AS number\n")
3397{
3398 int ret;
3399 char *str;
3400
3401 str = argv_concat (argv, argc, 0);
3402 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3403 XFREE (MTYPE_TMP, str);
3404 return ret;
3405}
3406
3407DEFUN (no_set_aspath_exclude,
3408 no_set_aspath_exclude_cmd,
3409 "no set as-path exclude",
3410 NO_STR
3411 SET_STR
3412 "Transform BGP AS_PATH attribute\n"
3413 "Exclude from the as-path\n")
3414{
3415 int ret;
3416 char *str;
3417
3418 if (argc == 0)
3419 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3420
3421 str = argv_concat (argv, argc, 0);
3422 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3423 XFREE (MTYPE_TMP, str);
3424 return ret;
3425}
3426
3427ALIAS (no_set_aspath_exclude,
3428 no_set_aspath_exclude_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003429 "no set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003430 NO_STR
3431 SET_STR
3432 "Transform BGP AS_PATH attribute\n"
3433 "Exclude from the as-path\n"
3434 "AS number\n")
3435
paul718e3742002-12-13 20:15:29 +00003436DEFUN (set_community,
3437 set_community_cmd,
3438 "set community .AA:NN",
3439 SET_STR
3440 "BGP community attribute\n"
3441 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3442{
3443 int i;
3444 int first = 0;
3445 int additive = 0;
3446 struct buffer *b;
3447 struct community *com = NULL;
3448 char *str;
3449 char *argstr;
3450 int ret;
3451
3452 b = buffer_new (1024);
3453
3454 for (i = 0; i < argc; i++)
3455 {
3456 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3457 {
3458 additive = 1;
3459 continue;
3460 }
3461
3462 if (first)
3463 buffer_putc (b, ' ');
3464 else
3465 first = 1;
3466
3467 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3468 {
3469 buffer_putstr (b, "internet");
3470 continue;
3471 }
3472 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3473 {
3474 buffer_putstr (b, "local-AS");
3475 continue;
3476 }
3477 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3478 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3479 {
3480 buffer_putstr (b, "no-advertise");
3481 continue;
3482 }
3483 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3484 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3485 {
3486 buffer_putstr (b, "no-export");
3487 continue;
3488 }
3489 buffer_putstr (b, argv[i]);
3490 }
3491 buffer_putc (b, '\0');
3492
3493 /* Fetch result string then compile it to communities attribute. */
3494 str = buffer_getstr (b);
3495 buffer_free (b);
3496
3497 if (str)
3498 {
3499 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003500 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003501 }
3502
3503 /* Can't compile user input into communities attribute. */
3504 if (! com)
3505 {
3506 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3507 return CMD_WARNING;
3508 }
3509
3510 /* Set communites attribute string. */
3511 str = community_str (com);
3512
3513 if (additive)
3514 {
3515 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3516 strcpy (argstr, str);
3517 strcpy (argstr + strlen (str), " additive");
3518 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3519 XFREE (MTYPE_TMP, argstr);
3520 }
3521 else
3522 ret = bgp_route_set_add (vty, vty->index, "community", str);
3523
3524 community_free (com);
3525
3526 return ret;
3527}
3528
3529DEFUN (set_community_none,
3530 set_community_none_cmd,
3531 "set community none",
3532 SET_STR
3533 "BGP community attribute\n"
3534 "No community attribute\n")
3535{
3536 return bgp_route_set_add (vty, vty->index, "community", "none");
3537}
3538
3539DEFUN (no_set_community,
3540 no_set_community_cmd,
3541 "no set community",
3542 NO_STR
3543 SET_STR
3544 "BGP community attribute\n")
3545{
3546 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3547}
3548
3549ALIAS (no_set_community,
3550 no_set_community_val_cmd,
3551 "no set community .AA:NN",
3552 NO_STR
3553 SET_STR
3554 "BGP community attribute\n"
3555 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3556
3557ALIAS (no_set_community,
3558 no_set_community_none_cmd,
3559 "no set community none",
3560 NO_STR
3561 SET_STR
3562 "BGP community attribute\n"
3563 "No community attribute\n")
3564
3565DEFUN (set_community_delete,
3566 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003567 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003568 SET_STR
3569 "set BGP community list (for deletion)\n"
3570 "Community-list number (standard)\n"
Daniel Waltonc7f25b92015-05-19 17:47:22 -07003571 "Community-list number (expanded)\n"
paul718e3742002-12-13 20:15:29 +00003572 "Community-list name\n"
3573 "Delete matching communities\n")
3574{
3575 char *str;
3576
3577 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3578 strcpy (str, argv[0]);
3579 strcpy (str + strlen (argv[0]), " delete");
3580
3581 bgp_route_set_add (vty, vty->index, "comm-list", str);
3582
3583 XFREE (MTYPE_TMP, str);
3584 return CMD_SUCCESS;
3585}
3586
3587DEFUN (no_set_community_delete,
3588 no_set_community_delete_cmd,
3589 "no set comm-list",
3590 NO_STR
3591 SET_STR
3592 "set BGP community list (for deletion)\n")
3593{
3594 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3595}
3596
3597ALIAS (no_set_community_delete,
3598 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003599 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003600 NO_STR
3601 SET_STR
3602 "set BGP community list (for deletion)\n"
3603 "Community-list number (standard)\n"
Daniel Waltonc7f25b92015-05-19 17:47:22 -07003604 "Community-list number (expanded)\n"
paul718e3742002-12-13 20:15:29 +00003605 "Community-list name\n"
3606 "Delete matching communities\n")
3607
3608DEFUN (set_ecommunity_rt,
3609 set_ecommunity_rt_cmd,
3610 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3611 SET_STR
3612 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003613 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003614 "VPN extended community\n")
3615{
3616 int ret;
3617 char *str;
3618
3619 str = argv_concat (argv, argc, 0);
3620 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3621 XFREE (MTYPE_TMP, str);
3622
3623 return ret;
3624}
3625
3626DEFUN (no_set_ecommunity_rt,
3627 no_set_ecommunity_rt_cmd,
3628 "no set extcommunity rt",
3629 NO_STR
3630 SET_STR
3631 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003632 "Route Target extended community\n")
paul718e3742002-12-13 20:15:29 +00003633{
3634 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3635}
3636
3637ALIAS (no_set_ecommunity_rt,
3638 no_set_ecommunity_rt_val_cmd,
3639 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3640 NO_STR
3641 SET_STR
3642 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003643 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003644 "VPN extended community\n")
3645
3646DEFUN (set_ecommunity_soo,
3647 set_ecommunity_soo_cmd,
3648 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3649 SET_STR
3650 "BGP extended community attribute\n"
3651 "Site-of-Origin extended community\n"
3652 "VPN extended community\n")
3653{
3654 int ret;
3655 char *str;
3656
3657 str = argv_concat (argv, argc, 0);
3658 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3659 XFREE (MTYPE_TMP, str);
3660 return ret;
3661}
3662
3663DEFUN (no_set_ecommunity_soo,
3664 no_set_ecommunity_soo_cmd,
3665 "no set extcommunity soo",
3666 NO_STR
3667 SET_STR
3668 "BGP extended community attribute\n"
3669 "Site-of-Origin extended community\n")
3670{
3671 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3672}
3673
3674ALIAS (no_set_ecommunity_soo,
3675 no_set_ecommunity_soo_val_cmd,
3676 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3677 NO_STR
3678 SET_STR
3679 "BGP extended community attribute\n"
3680 "Site-of-Origin extended community\n"
3681 "VPN extended community\n")
3682
3683DEFUN (set_origin,
3684 set_origin_cmd,
3685 "set origin (egp|igp|incomplete)",
3686 SET_STR
3687 "BGP origin code\n"
3688 "remote EGP\n"
3689 "local IGP\n"
3690 "unknown heritage\n")
3691{
3692 if (strncmp (argv[0], "igp", 2) == 0)
3693 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3694 if (strncmp (argv[0], "egp", 1) == 0)
3695 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3696 if (strncmp (argv[0], "incomplete", 2) == 0)
3697 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3698
3699 return CMD_WARNING;
3700}
3701
3702DEFUN (no_set_origin,
3703 no_set_origin_cmd,
3704 "no set origin",
3705 NO_STR
3706 SET_STR
3707 "BGP origin code\n")
3708{
3709 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3710}
3711
3712ALIAS (no_set_origin,
3713 no_set_origin_val_cmd,
3714 "no set origin (egp|igp|incomplete)",
3715 NO_STR
3716 SET_STR
3717 "BGP origin code\n"
3718 "remote EGP\n"
3719 "local IGP\n"
3720 "unknown heritage\n")
3721
3722DEFUN (set_atomic_aggregate,
3723 set_atomic_aggregate_cmd,
3724 "set atomic-aggregate",
3725 SET_STR
3726 "BGP atomic aggregate attribute\n" )
3727{
3728 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3729}
3730
3731DEFUN (no_set_atomic_aggregate,
3732 no_set_atomic_aggregate_cmd,
3733 "no set atomic-aggregate",
3734 NO_STR
3735 SET_STR
3736 "BGP atomic aggregate attribute\n" )
3737{
3738 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3739}
3740
3741DEFUN (set_aggregator_as,
3742 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003743 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003744 SET_STR
3745 "BGP aggregator attribute\n"
3746 "AS number of aggregator\n"
3747 "AS number\n"
3748 "IP address of aggregator\n")
3749{
3750 int ret;
Paul Jakma7aa9dce2014-09-19 14:42:23 +01003751 as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
paul718e3742002-12-13 20:15:29 +00003752 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003753 char *argstr;
3754
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003755 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003756
paul718e3742002-12-13 20:15:29 +00003757 ret = inet_aton (argv[1], &address);
3758 if (ret == 0)
3759 {
3760 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3761 return CMD_WARNING;
3762 }
3763
3764 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3765 strlen (argv[0]) + strlen (argv[1]) + 2);
3766
3767 sprintf (argstr, "%s %s", argv[0], argv[1]);
3768
3769 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3770
3771 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3772
3773 return ret;
3774}
3775
3776DEFUN (no_set_aggregator_as,
3777 no_set_aggregator_as_cmd,
3778 "no set aggregator as",
3779 NO_STR
3780 SET_STR
3781 "BGP aggregator attribute\n"
3782 "AS number of aggregator\n")
3783{
3784 int ret;
Paul Jakma7aa9dce2014-09-19 14:42:23 +01003785 as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
paul718e3742002-12-13 20:15:29 +00003786 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003787 char *argstr;
3788
3789 if (argv == 0)
3790 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3791
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003792 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003793
3794 ret = inet_aton (argv[1], &address);
3795 if (ret == 0)
3796 {
3797 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3798 return CMD_WARNING;
3799 }
3800
3801 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3802 strlen (argv[0]) + strlen (argv[1]) + 2);
3803
3804 sprintf (argstr, "%s %s", argv[0], argv[1]);
3805
3806 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3807
3808 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3809
3810 return ret;
3811}
3812
3813ALIAS (no_set_aggregator_as,
3814 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003815 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003816 NO_STR
3817 SET_STR
3818 "BGP aggregator attribute\n"
3819 "AS number of aggregator\n"
3820 "AS number\n"
3821 "IP address of aggregator\n")
3822
Piotr Chytła605aa332015-12-01 10:03:54 -05003823DEFUN (set_tag,
3824 set_tag_cmd,
3825 "set tag <1-65535>",
3826 SET_STR
3827 "Tag value for routing protocol\n"
3828 "Tag value\n")
3829{
3830 return bgp_route_set_add (vty, vty->index, "tag", argv[0]);
3831}
3832
3833DEFUN (no_set_tag,
3834 no_set_tag_cmd,
3835 "no set tag",
3836 NO_STR
3837 SET_STR
3838 "Tag value for routing protocol\n")
3839{
3840 if (argc == 0)
3841 bgp_route_set_delete(vty, vty->index, "tag", NULL);
3842
3843 return bgp_route_set_delete (vty, vty->index, "tag", argv[0]);
3844}
3845
3846ALIAS (no_set_tag,
3847 no_set_tag_val_cmd,
3848 "no set tag <1-65535>",
3849 NO_STR
3850 SET_STR
3851 "Tag value for routing protocol\n"
3852 "Tag value\n")
3853
3854
paul718e3742002-12-13 20:15:29 +00003855DEFUN (match_ipv6_address,
3856 match_ipv6_address_cmd,
3857 "match ipv6 address WORD",
3858 MATCH_STR
3859 IPV6_STR
3860 "Match IPv6 address of route\n"
3861 "IPv6 access-list name\n")
3862{
3863 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3864}
3865
3866DEFUN (no_match_ipv6_address,
3867 no_match_ipv6_address_cmd,
3868 "no match ipv6 address WORD",
3869 NO_STR
3870 MATCH_STR
3871 IPV6_STR
3872 "Match IPv6 address of route\n"
3873 "IPv6 access-list name\n")
3874{
3875 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3876}
3877
3878DEFUN (match_ipv6_next_hop,
3879 match_ipv6_next_hop_cmd,
3880 "match ipv6 next-hop X:X::X:X",
3881 MATCH_STR
3882 IPV6_STR
3883 "Match IPv6 next-hop address of route\n"
3884 "IPv6 address of next hop\n")
3885{
3886 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3887}
3888
3889DEFUN (no_match_ipv6_next_hop,
3890 no_match_ipv6_next_hop_cmd,
3891 "no match ipv6 next-hop X:X::X:X",
3892 NO_STR
3893 MATCH_STR
3894 IPV6_STR
3895 "Match IPv6 next-hop address of route\n"
3896 "IPv6 address of next hop\n")
3897{
3898 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3899}
3900
3901DEFUN (match_ipv6_address_prefix_list,
3902 match_ipv6_address_prefix_list_cmd,
3903 "match ipv6 address prefix-list WORD",
3904 MATCH_STR
3905 IPV6_STR
3906 "Match address of route\n"
3907 "Match entries of prefix-lists\n"
3908 "IP prefix-list name\n")
3909{
3910 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3911}
3912
3913DEFUN (no_match_ipv6_address_prefix_list,
3914 no_match_ipv6_address_prefix_list_cmd,
3915 "no match ipv6 address prefix-list WORD",
3916 NO_STR
3917 MATCH_STR
3918 IPV6_STR
3919 "Match address of route\n"
3920 "Match entries of prefix-lists\n"
3921 "IP prefix-list name\n")
3922{
3923 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3924}
3925
Dinesh G Duttad5233a2014-09-30 14:19:57 -07003926DEFUN (set_ipv6_nexthop_peer,
3927 set_ipv6_nexthop_peer_cmd,
3928 "set ipv6 next-hop peer-address",
3929 SET_STR
3930 IPV6_STR
3931 "Next hop address\n"
3932 "Use peer address (for BGP only)\n")
3933{
3934 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop peer-address", NULL);
3935}
3936
3937DEFUN (no_set_ipv6_nexthop_peer,
3938 no_set_ipv6_nexthop_peer_cmd,
3939 "no set ipv6 next-hop peer-address",
3940 NO_STR
3941 SET_STR
3942 IPV6_STR
3943 "IPv6 next-hop address\n"
3944 )
3945{
3946 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3947}
3948
paul718e3742002-12-13 20:15:29 +00003949DEFUN (set_ipv6_nexthop_global,
3950 set_ipv6_nexthop_global_cmd,
3951 "set ipv6 next-hop global X:X::X:X",
3952 SET_STR
3953 IPV6_STR
3954 "IPv6 next-hop address\n"
3955 "IPv6 global address\n"
3956 "IPv6 address of next hop\n")
3957{
3958 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3959}
3960
3961DEFUN (no_set_ipv6_nexthop_global,
3962 no_set_ipv6_nexthop_global_cmd,
3963 "no set ipv6 next-hop global",
3964 NO_STR
3965 SET_STR
3966 IPV6_STR
3967 "IPv6 next-hop address\n"
3968 "IPv6 global address\n")
3969{
3970 if (argc == 0)
3971 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3972
3973 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3974}
3975
3976ALIAS (no_set_ipv6_nexthop_global,
3977 no_set_ipv6_nexthop_global_val_cmd,
3978 "no set ipv6 next-hop global X:X::X:X",
3979 NO_STR
3980 SET_STR
3981 IPV6_STR
3982 "IPv6 next-hop address\n"
3983 "IPv6 global address\n"
3984 "IPv6 address of next hop\n")
3985
3986DEFUN (set_ipv6_nexthop_local,
3987 set_ipv6_nexthop_local_cmd,
3988 "set ipv6 next-hop local X:X::X:X",
3989 SET_STR
3990 IPV6_STR
3991 "IPv6 next-hop address\n"
3992 "IPv6 local address\n"
3993 "IPv6 address of next hop\n")
3994{
3995 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3996}
3997
3998DEFUN (no_set_ipv6_nexthop_local,
3999 no_set_ipv6_nexthop_local_cmd,
4000 "no set ipv6 next-hop local",
4001 NO_STR
4002 SET_STR
4003 IPV6_STR
4004 "IPv6 next-hop address\n"
4005 "IPv6 local address\n")
4006{
4007 if (argc == 0)
4008 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
4009
4010 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
4011}
4012
4013ALIAS (no_set_ipv6_nexthop_local,
4014 no_set_ipv6_nexthop_local_val_cmd,
4015 "no set ipv6 next-hop local X:X::X:X",
4016 NO_STR
4017 SET_STR
4018 IPV6_STR
4019 "IPv6 next-hop address\n"
4020 "IPv6 local address\n"
4021 "IPv6 address of next hop\n")
paul718e3742002-12-13 20:15:29 +00004022
4023DEFUN (set_vpnv4_nexthop,
4024 set_vpnv4_nexthop_cmd,
4025 "set vpnv4 next-hop A.B.C.D",
4026 SET_STR
4027 "VPNv4 information\n"
4028 "VPNv4 next-hop address\n"
4029 "IP address of next hop\n")
4030{
4031 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
4032}
4033
4034DEFUN (no_set_vpnv4_nexthop,
4035 no_set_vpnv4_nexthop_cmd,
4036 "no set vpnv4 next-hop",
4037 NO_STR
4038 SET_STR
4039 "VPNv4 information\n"
4040 "VPNv4 next-hop address\n")
4041{
4042 if (argc == 0)
4043 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
4044
4045 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
4046}
4047
4048ALIAS (no_set_vpnv4_nexthop,
4049 no_set_vpnv4_nexthop_val_cmd,
4050 "no set vpnv4 next-hop A.B.C.D",
4051 NO_STR
4052 SET_STR
4053 "VPNv4 information\n"
4054 "VPNv4 next-hop address\n"
4055 "IP address of next hop\n")
4056
4057DEFUN (set_originator_id,
4058 set_originator_id_cmd,
4059 "set originator-id A.B.C.D",
4060 SET_STR
4061 "BGP originator ID attribute\n"
4062 "IP address of originator\n")
4063{
4064 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
4065}
4066
4067DEFUN (no_set_originator_id,
4068 no_set_originator_id_cmd,
4069 "no set originator-id",
4070 NO_STR
4071 SET_STR
4072 "BGP originator ID attribute\n")
4073{
4074 if (argc == 0)
4075 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
4076
4077 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
4078}
4079
4080ALIAS (no_set_originator_id,
4081 no_set_originator_id_val_cmd,
4082 "no set originator-id A.B.C.D",
4083 NO_STR
4084 SET_STR
4085 "BGP originator ID attribute\n"
4086 "IP address of originator\n")
4087
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004088DEFUN_DEPRECATED (set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00004089 set_pathlimit_ttl_cmd,
4090 "set pathlimit ttl <1-255>",
4091 SET_STR
4092 "BGP AS-Pathlimit attribute\n"
4093 "Set AS-Path Hop-count TTL\n")
4094{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004095 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00004096}
4097
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004098DEFUN_DEPRECATED (no_set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00004099 no_set_pathlimit_ttl_cmd,
4100 "no set pathlimit ttl",
4101 NO_STR
4102 SET_STR
4103 "BGP AS-Pathlimit attribute\n"
4104 "Set AS-Path Hop-count TTL\n")
4105{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004106 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00004107}
4108
4109ALIAS (no_set_pathlimit_ttl,
4110 no_set_pathlimit_ttl_val_cmd,
4111 "no set pathlimit ttl <1-255>",
4112 NO_STR
4113 MATCH_STR
4114 "BGP AS-Pathlimit attribute\n"
4115 "Set AS-Path Hop-count TTL\n")
4116
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004117DEFUN_DEPRECATED (match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00004118 match_pathlimit_as_cmd,
4119 "match pathlimit as <1-65535>",
4120 MATCH_STR
4121 "BGP AS-Pathlimit attribute\n"
4122 "Match Pathlimit AS number\n")
4123{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004124 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00004125}
4126
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004127DEFUN_DEPRECATED (no_match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00004128 no_match_pathlimit_as_cmd,
4129 "no match pathlimit as",
4130 NO_STR
4131 MATCH_STR
4132 "BGP AS-Pathlimit attribute\n"
4133 "Match Pathlimit AS number\n")
4134{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004135 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00004136}
4137
4138ALIAS (no_match_pathlimit_as,
4139 no_match_pathlimit_as_val_cmd,
4140 "no match pathlimit as <1-65535>",
4141 NO_STR
4142 MATCH_STR
4143 "BGP AS-Pathlimit attribute\n"
4144 "Match Pathlimit ASN\n")
4145
David Lamparter6b0655a2014-06-04 06:53:35 +02004146
paul718e3742002-12-13 20:15:29 +00004147/* Initialization of route map. */
4148void
paul94f2b392005-06-28 12:44:16 +00004149bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00004150{
4151 route_map_init ();
4152 route_map_init_vty ();
4153 route_map_add_hook (bgp_route_map_update);
4154 route_map_delete_hook (bgp_route_map_update);
4155
paulfee0f4c2004-09-13 05:12:46 +00004156 route_map_install_match (&route_match_peer_cmd);
Dinesh Dutt5cf768a2015-11-09 20:21:53 -05004157 route_map_install_match (&route_match_local_pref_cmd);
paul718e3742002-12-13 20:15:29 +00004158 route_map_install_match (&route_match_ip_address_cmd);
4159 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00004160 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00004161 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
4162 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00004163 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00004164 route_map_install_match (&route_match_aspath_cmd);
4165 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00004166 route_map_install_match (&route_match_ecommunity_cmd);
Dinesh Dutt5cf768a2015-11-09 20:21:53 -05004167 route_map_install_match (&route_match_local_pref_cmd);
paul718e3742002-12-13 20:15:29 +00004168 route_map_install_match (&route_match_metric_cmd);
4169 route_map_install_match (&route_match_origin_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04004170 route_map_install_match (&route_match_probability_cmd);
Piotr Chytła605aa332015-12-01 10:03:54 -05004171 route_map_install_match (&route_match_tag_cmd);
paul718e3742002-12-13 20:15:29 +00004172
4173 route_map_install_set (&route_set_ip_nexthop_cmd);
4174 route_map_install_set (&route_set_local_pref_cmd);
4175 route_map_install_set (&route_set_weight_cmd);
4176 route_map_install_set (&route_set_metric_cmd);
4177 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00004178 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00004179 route_map_install_set (&route_set_origin_cmd);
4180 route_map_install_set (&route_set_atomic_aggregate_cmd);
4181 route_map_install_set (&route_set_aggregator_as_cmd);
4182 route_map_install_set (&route_set_community_cmd);
4183 route_map_install_set (&route_set_community_delete_cmd);
4184 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
4185 route_map_install_set (&route_set_originator_id_cmd);
4186 route_map_install_set (&route_set_ecommunity_rt_cmd);
4187 route_map_install_set (&route_set_ecommunity_soo_cmd);
Piotr Chytła605aa332015-12-01 10:03:54 -05004188 route_map_install_set (&route_set_tag_cmd);
paul718e3742002-12-13 20:15:29 +00004189
paulfee0f4c2004-09-13 05:12:46 +00004190 install_element (RMAP_NODE, &match_peer_cmd);
4191 install_element (RMAP_NODE, &match_peer_local_cmd);
4192 install_element (RMAP_NODE, &no_match_peer_cmd);
4193 install_element (RMAP_NODE, &no_match_peer_val_cmd);
4194 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00004195 install_element (RMAP_NODE, &match_ip_address_cmd);
4196 install_element (RMAP_NODE, &no_match_ip_address_cmd);
4197 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
4198 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
4199 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
4200 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00004201 install_element (RMAP_NODE, &match_ip_route_source_cmd);
4202 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
4203 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00004204 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
4205 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
4206 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
4207 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
4208 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
4209 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00004210 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
4211 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
4212 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00004213
4214 install_element (RMAP_NODE, &match_aspath_cmd);
4215 install_element (RMAP_NODE, &no_match_aspath_cmd);
4216 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
4217 install_element (RMAP_NODE, &match_metric_cmd);
4218 install_element (RMAP_NODE, &no_match_metric_cmd);
4219 install_element (RMAP_NODE, &no_match_metric_val_cmd);
Dinesh Dutt5cf768a2015-11-09 20:21:53 -05004220 install_element (RMAP_NODE, &match_local_pref_cmd);
4221 install_element (RMAP_NODE, &no_match_local_pref_cmd);
4222 install_element (RMAP_NODE, &no_match_local_pref_val_cmd);
paul718e3742002-12-13 20:15:29 +00004223 install_element (RMAP_NODE, &match_community_cmd);
4224 install_element (RMAP_NODE, &match_community_exact_cmd);
4225 install_element (RMAP_NODE, &no_match_community_cmd);
4226 install_element (RMAP_NODE, &no_match_community_val_cmd);
4227 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00004228 install_element (RMAP_NODE, &match_ecommunity_cmd);
4229 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
4230 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00004231 install_element (RMAP_NODE, &match_origin_cmd);
4232 install_element (RMAP_NODE, &no_match_origin_cmd);
4233 install_element (RMAP_NODE, &no_match_origin_val_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04004234 install_element (RMAP_NODE, &match_probability_cmd);
4235 install_element (RMAP_NODE, &no_match_probability_cmd);
4236 install_element (RMAP_NODE, &no_match_probability_val_cmd);
Piotr Chytła605aa332015-12-01 10:03:54 -05004237 install_element (RMAP_NODE, &match_tag_cmd);
4238 install_element (RMAP_NODE, &no_match_tag_cmd);
4239 install_element (RMAP_NODE, &no_match_tag_val_cmd);
paul718e3742002-12-13 20:15:29 +00004240
4241 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00004242 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00004243 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
4244 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
4245 install_element (RMAP_NODE, &set_local_pref_cmd);
4246 install_element (RMAP_NODE, &no_set_local_pref_cmd);
4247 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
4248 install_element (RMAP_NODE, &set_weight_cmd);
4249 install_element (RMAP_NODE, &no_set_weight_cmd);
4250 install_element (RMAP_NODE, &no_set_weight_val_cmd);
4251 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00004252 install_element (RMAP_NODE, &set_metric_addsub_cmd);
Timo Teräsef757702015-04-29 09:43:04 +03004253 install_element (RMAP_NODE, &set_metric_rtt_cmd);
paul718e3742002-12-13 20:15:29 +00004254 install_element (RMAP_NODE, &no_set_metric_cmd);
4255 install_element (RMAP_NODE, &no_set_metric_val_cmd);
4256 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Timo Teräs85c854a2014-09-30 11:31:53 +03004257 install_element (RMAP_NODE, &set_aspath_prepend_lastas_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00004258 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00004259 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
4260 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00004261 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
4262 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00004263 install_element (RMAP_NODE, &set_origin_cmd);
4264 install_element (RMAP_NODE, &no_set_origin_cmd);
4265 install_element (RMAP_NODE, &no_set_origin_val_cmd);
4266 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
4267 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
4268 install_element (RMAP_NODE, &set_aggregator_as_cmd);
4269 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
4270 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
4271 install_element (RMAP_NODE, &set_community_cmd);
4272 install_element (RMAP_NODE, &set_community_none_cmd);
4273 install_element (RMAP_NODE, &no_set_community_cmd);
4274 install_element (RMAP_NODE, &no_set_community_val_cmd);
4275 install_element (RMAP_NODE, &no_set_community_none_cmd);
4276 install_element (RMAP_NODE, &set_community_delete_cmd);
4277 install_element (RMAP_NODE, &no_set_community_delete_cmd);
4278 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
4279 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
4280 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
4281 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
4282 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
4283 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
4284 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
4285 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
4286 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
4287 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
4288 install_element (RMAP_NODE, &set_originator_id_cmd);
4289 install_element (RMAP_NODE, &no_set_originator_id_cmd);
4290 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
Piotr Chytła605aa332015-12-01 10:03:54 -05004291 install_element (RMAP_NODE, &set_tag_cmd);
4292 install_element (RMAP_NODE, &no_set_tag_cmd);
4293 install_element (RMAP_NODE, &no_set_tag_val_cmd);
paul718e3742002-12-13 20:15:29 +00004294
paul718e3742002-12-13 20:15:29 +00004295 route_map_install_match (&route_match_ipv6_address_cmd);
4296 route_map_install_match (&route_match_ipv6_next_hop_cmd);
4297 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
4298 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
4299 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Dinesh G Duttad5233a2014-09-30 14:19:57 -07004300 route_map_install_set (&route_set_ipv6_nexthop_peer_cmd);
4301
paul718e3742002-12-13 20:15:29 +00004302 install_element (RMAP_NODE, &match_ipv6_address_cmd);
4303 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
4304 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
4305 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
4306 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
4307 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
4308 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
4309 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
4310 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
4311 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
4312 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
4313 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
Dinesh G Duttad5233a2014-09-30 14:19:57 -07004314 install_element (RMAP_NODE, &set_ipv6_nexthop_peer_cmd);
4315 install_element (RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd);
Paul Jakma41367172007-08-06 15:24:51 +00004316
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004317 /* AS-Pathlimit: functionality removed, commands kept for
4318 * compatibility.
4319 */
Paul Jakma41367172007-08-06 15:24:51 +00004320 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
4321 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
4322 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
4323 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
4324 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
4325 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00004326}