blob: c66f260e8480be7cb273fe70ce9cc619d611e85c [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;
2193 char peer_addr_buf[INET6_ADDRSTRLEN];
2194
2195 if (type == RMAP_BGP)
2196 {
2197 /* Fetch routemap's rule information. */
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002198 bgp_info = object;
2199 peer = bgp_info->peer;
2200
2201 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
2202 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
2203 && peer->su_remote
2204 && sockunion_family (peer->su_remote) == AF_INET6)
2205 {
2206 inet_pton (AF_INET6, sockunion2str (peer->su_remote,
2207 peer_addr_buf,
2208 INET6_ADDRSTRLEN),
2209 &peer_address);
2210 }
2211 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
2212 && peer->su_local
2213 && sockunion_family (peer->su_local) == AF_INET6)
2214 {
2215 inet_pton (AF_INET, sockunion2str (peer->su_local,
2216 peer_addr_buf,
2217 INET6_ADDRSTRLEN),
2218 &peer_address);
2219 }
2220
2221 if (IN6_IS_ADDR_LINKLOCAL(&peer_address))
2222 {
2223 /* Set next hop value. */
2224 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = peer_address;
2225
2226 /* Set nexthop length. */
2227 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2228 bgp_info->attr->extra->mp_nexthop_len = 32;
2229 }
2230 else
2231 {
2232 /* Set next hop value. */
2233 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = peer_address;
2234
2235 /* Set nexthop length. */
2236 if (bgp_info->attr->extra->mp_nexthop_len == 0)
2237 bgp_info->attr->extra->mp_nexthop_len = 16;
2238 }
2239 }
2240
2241 return RMAP_OKAY;
2242}
2243
2244/* Route map `ip next-hop' compile function. Given string is converted
2245 to struct in_addr structure. */
2246static void *
2247route_set_ipv6_nexthop_peer_compile (const char *arg)
2248{
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002249 int *rins = NULL;
2250
2251 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (int));
2252 *rins = 1;
2253
2254 return rins;
2255}
2256
2257/* Free route map's compiled `ip next-hop' value. */
2258static void
2259route_set_ipv6_nexthop_peer_free (void *rule)
2260{
2261 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2262}
2263
2264/* Route map commands for ip nexthop set. */
2265struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd =
2266{
2267 "ipv6 next-hop peer-address",
2268 route_set_ipv6_nexthop_peer,
2269 route_set_ipv6_nexthop_peer_compile,
2270 route_set_ipv6_nexthop_peer_free
2271};
2272
paul718e3742002-12-13 20:15:29 +00002273/* `set vpnv4 nexthop A.B.C.D' */
2274
paul94f2b392005-06-28 12:44:16 +00002275static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002276route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2277 route_map_object_t type, void *object)
2278{
2279 struct in_addr *address;
2280 struct bgp_info *bgp_info;
2281
2282 if (type == RMAP_BGP)
2283 {
2284 /* Fetch routemap's rule information. */
2285 address = rule;
2286 bgp_info = object;
2287
2288 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002289 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
Lou Berger050defe2016-01-12 13:41:59 -05002290 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_len = 4;
paul718e3742002-12-13 20:15:29 +00002291 }
2292
2293 return RMAP_OKAY;
2294}
2295
paul94f2b392005-06-28 12:44:16 +00002296static void *
paulfd79ac92004-10-13 05:06:08 +00002297route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002298{
2299 int ret;
2300 struct in_addr *address;
2301
2302 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2303
2304 ret = inet_aton (arg, address);
2305
2306 if (ret == 0)
2307 {
2308 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2309 return NULL;
2310 }
2311
2312 return address;
2313}
2314
paul94f2b392005-06-28 12:44:16 +00002315static void
paul718e3742002-12-13 20:15:29 +00002316route_set_vpnv4_nexthop_free (void *rule)
2317{
2318 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2319}
2320
2321/* Route map commands for ip nexthop set. */
2322struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2323{
2324 "vpnv4 next-hop",
2325 route_set_vpnv4_nexthop,
2326 route_set_vpnv4_nexthop_compile,
2327 route_set_vpnv4_nexthop_free
2328};
David Lamparter6b0655a2014-06-04 06:53:35 +02002329
paul718e3742002-12-13 20:15:29 +00002330/* `set originator-id' */
2331
2332/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002333static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002334route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2335{
2336 struct in_addr *address;
2337 struct bgp_info *bgp_info;
2338
2339 if (type == RMAP_BGP)
2340 {
2341 address = rule;
2342 bgp_info = object;
2343
2344 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002345 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002346 }
2347
2348 return RMAP_OKAY;
2349}
2350
2351/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002352static void *
paulfd79ac92004-10-13 05:06:08 +00002353route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002354{
2355 int ret;
2356 struct in_addr *address;
2357
2358 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2359
2360 ret = inet_aton (arg, address);
2361
2362 if (ret == 0)
2363 {
2364 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2365 return NULL;
2366 }
2367
2368 return address;
2369}
2370
2371/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002372static void
paul718e3742002-12-13 20:15:29 +00002373route_set_originator_id_free (void *rule)
2374{
2375 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2376}
2377
Timo Teräs2aa640b2014-05-20 08:57:26 +03002378/* Set originator-id rule structure. */
paul718e3742002-12-13 20:15:29 +00002379struct route_map_rule_cmd route_set_originator_id_cmd =
2380{
2381 "originator-id",
2382 route_set_originator_id,
2383 route_set_originator_id_compile,
2384 route_set_originator_id_free,
2385};
David Lamparter6b0655a2014-06-04 06:53:35 +02002386
paul718e3742002-12-13 20:15:29 +00002387/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002388static int
paul718e3742002-12-13 20:15:29 +00002389bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002390 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002391{
2392 int ret;
2393
2394 ret = route_map_add_match (index, command, arg);
2395 if (ret)
2396 {
2397 switch (ret)
2398 {
2399 case RMAP_RULE_MISSING:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002400 vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002401 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002402 case RMAP_COMPILE_ERROR:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002403 vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002404 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002405 }
2406 }
2407 return CMD_SUCCESS;
2408}
2409
2410/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002411static int
paul718e3742002-12-13 20:15:29 +00002412bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002413 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002414{
2415 int ret;
2416
2417 ret = route_map_delete_match (index, command, arg);
2418 if (ret)
2419 {
2420 switch (ret)
2421 {
2422 case RMAP_RULE_MISSING:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002423 vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002424 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002425 case RMAP_COMPILE_ERROR:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002426 vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002427 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002428 }
2429 }
2430 return CMD_SUCCESS;
2431}
2432
2433/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002434static int
paul718e3742002-12-13 20:15:29 +00002435bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002436 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002437{
2438 int ret;
2439
2440 ret = route_map_add_set (index, command, arg);
2441 if (ret)
2442 {
2443 switch (ret)
2444 {
2445 case RMAP_RULE_MISSING:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002446 vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002447 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002448 case RMAP_COMPILE_ERROR:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002449 vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002450 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002451 }
2452 }
2453 return CMD_SUCCESS;
2454}
2455
2456/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002457static int
paul718e3742002-12-13 20:15:29 +00002458bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002459 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002460{
2461 int ret;
2462
2463 ret = route_map_delete_set (index, command, arg);
2464 if (ret)
2465 {
2466 switch (ret)
2467 {
2468 case RMAP_RULE_MISSING:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002469 vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002470 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002471 case RMAP_COMPILE_ERROR:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002472 vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002473 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002474 }
2475 }
2476 return CMD_SUCCESS;
2477}
2478
2479/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002480static void
paulfd79ac92004-10-13 05:06:08 +00002481bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002482{
2483 int i;
2484 afi_t afi;
2485 safi_t safi;
2486 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002487 struct listnode *node, *nnode;
2488 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002489 struct bgp *bgp;
2490 struct peer *peer;
2491 struct peer_group *group;
2492 struct bgp_filter *filter;
2493 struct bgp_node *bn;
2494 struct bgp_static *bgp_static;
2495
Lou Berger82dd7072016-01-12 13:41:57 -05002496 if (bm->bgp == NULL) /* may be called during cleanup */
2497 return;
2498
paul718e3742002-12-13 20:15:29 +00002499 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002500 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002501 {
paul1eb8ef22005-04-07 07:30:20 +00002502 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002503 {
2504 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2505 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2506 {
2507 filter = &peer->filter[afi][safi];
2508
paulfee0f4c2004-09-13 05:12:46 +00002509 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002510 {
2511 if (filter->map[direct].name)
2512 filter->map[direct].map =
2513 route_map_lookup_by_name (filter->map[direct].name);
2514 else
2515 filter->map[direct].map = NULL;
2516 }
2517
2518 if (filter->usmap.name)
2519 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2520 else
2521 filter->usmap.map = NULL;
2522 }
2523 }
paul1eb8ef22005-04-07 07:30:20 +00002524 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002525 {
2526 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2527 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2528 {
2529 filter = &group->conf->filter[afi][safi];
2530
paulfee0f4c2004-09-13 05:12:46 +00002531 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002532 {
2533 if (filter->map[direct].name)
2534 filter->map[direct].map =
2535 route_map_lookup_by_name (filter->map[direct].name);
2536 else
2537 filter->map[direct].map = NULL;
2538 }
2539
2540 if (filter->usmap.name)
2541 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2542 else
2543 filter->usmap.map = NULL;
2544 }
2545 }
2546 }
2547
2548 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002549 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002550 {
paul1eb8ef22005-04-07 07:30:20 +00002551 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002552 {
2553 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2554 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2555 {
2556 if (peer->default_rmap[afi][safi].name)
2557 peer->default_rmap[afi][safi].map =
2558 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2559 else
2560 peer->default_rmap[afi][safi].map = NULL;
2561 }
2562 }
2563 }
2564
2565 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002566 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002567 {
2568 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2569 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2570 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2571 bn = bgp_route_next (bn))
2572 if ((bgp_static = bn->info) != NULL)
2573 {
2574 if (bgp_static->rmap.name)
2575 bgp_static->rmap.map =
2576 route_map_lookup_by_name (bgp_static->rmap.name);
2577 else
2578 bgp_static->rmap.map = NULL;
2579 }
2580 }
2581
2582 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002583 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002584 {
2585 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2586 {
Donald Sharpf3cfc462016-01-07 09:33:28 -05002587 if (bgp->rmap[AFI_IP][i].name)
2588 bgp->rmap[AFI_IP][i].map =
2589 route_map_lookup_by_name (bgp->rmap[AFI_IP][i].name);
2590 if (bgp->rmap[AFI_IP6][i].name)
2591 bgp->rmap[AFI_IP6][i].map =
Andrej Ota220355d2016-05-09 20:49:01 +02002592 route_map_lookup_by_name (bgp->rmap[AFI_IP6][i].name);
paul718e3742002-12-13 20:15:29 +00002593 }
2594 }
2595}
David Lamparter6b0655a2014-06-04 06:53:35 +02002596
paulfee0f4c2004-09-13 05:12:46 +00002597DEFUN (match_peer,
2598 match_peer_cmd,
2599 "match peer (A.B.C.D|X:X::X:X)",
2600 MATCH_STR
2601 "Match peer address\n"
Igor Ryzhov93b493a2016-05-11 15:26:39 +03002602 "IP address of peer\n"
2603 "IPv6 address of peer\n")
paulfee0f4c2004-09-13 05:12:46 +00002604{
2605 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2606}
2607
2608DEFUN (match_peer_local,
2609 match_peer_local_cmd,
2610 "match peer local",
2611 MATCH_STR
2612 "Match peer address\n"
2613 "Static or Redistributed routes\n")
2614{
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +02002615 return bgp_route_match_add (vty, vty->index, "peer", "local");
paulfee0f4c2004-09-13 05:12:46 +00002616}
2617
2618DEFUN (no_match_peer,
2619 no_match_peer_cmd,
2620 "no match peer",
2621 NO_STR
2622 MATCH_STR
2623 "Match peer address\n")
2624{
2625 if (argc == 0)
2626 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2627
2628 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2629}
2630
2631ALIAS (no_match_peer,
2632 no_match_peer_val_cmd,
2633 "no match peer (A.B.C.D|X:X::X:X)",
2634 NO_STR
2635 MATCH_STR
2636 "Match peer address\n"
Igor Ryzhov93b493a2016-05-11 15:26:39 +03002637 "IP address of peer\n"
2638 "IPv6 address of peer\n")
paulfee0f4c2004-09-13 05:12:46 +00002639
2640ALIAS (no_match_peer,
2641 no_match_peer_local_cmd,
2642 "no match peer local",
2643 NO_STR
2644 MATCH_STR
2645 "Match peer address\n"
2646 "Static or Redistributed routes\n")
2647
paul718e3742002-12-13 20:15:29 +00002648DEFUN (match_ip_address,
2649 match_ip_address_cmd,
2650 "match ip address (<1-199>|<1300-2699>|WORD)",
2651 MATCH_STR
2652 IP_STR
2653 "Match address of route\n"
2654 "IP access-list number\n"
2655 "IP access-list number (expanded range)\n"
2656 "IP Access-list name\n")
2657{
2658 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2659}
2660
2661DEFUN (no_match_ip_address,
2662 no_match_ip_address_cmd,
2663 "no match ip address",
2664 NO_STR
2665 MATCH_STR
2666 IP_STR
2667 "Match address of route\n")
2668{
2669 if (argc == 0)
2670 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2671
2672 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2673}
2674
2675ALIAS (no_match_ip_address,
2676 no_match_ip_address_val_cmd,
2677 "no match ip address (<1-199>|<1300-2699>|WORD)",
2678 NO_STR
2679 MATCH_STR
2680 IP_STR
2681 "Match address of route\n"
2682 "IP access-list number\n"
2683 "IP access-list number (expanded range)\n"
2684 "IP Access-list name\n")
2685
2686DEFUN (match_ip_next_hop,
2687 match_ip_next_hop_cmd,
2688 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2689 MATCH_STR
2690 IP_STR
2691 "Match next-hop address of route\n"
2692 "IP access-list number\n"
2693 "IP access-list number (expanded range)\n"
2694 "IP Access-list name\n")
2695{
2696 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2697}
2698
2699DEFUN (no_match_ip_next_hop,
2700 no_match_ip_next_hop_cmd,
2701 "no match ip next-hop",
2702 NO_STR
2703 MATCH_STR
2704 IP_STR
2705 "Match next-hop address of route\n")
2706{
2707 if (argc == 0)
2708 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2709
2710 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2711}
2712
2713ALIAS (no_match_ip_next_hop,
2714 no_match_ip_next_hop_val_cmd,
2715 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2716 NO_STR
2717 MATCH_STR
2718 IP_STR
2719 "Match next-hop address of route\n"
2720 "IP access-list number\n"
2721 "IP access-list number (expanded range)\n"
2722 "IP Access-list name\n")
2723
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04002724/* match probability { */
2725
2726DEFUN (match_probability,
2727 match_probability_cmd,
2728 "match probability <0-100>",
2729 MATCH_STR
2730 "Match portion of routes defined by percentage value\n"
2731 "Percentage of routes\n")
2732{
2733 return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
2734}
2735
2736DEFUN (no_match_probability,
2737 no_match_probability_cmd,
2738 "no match probability",
2739 NO_STR
2740 MATCH_STR
2741 "Match portion of routes defined by percentage value\n")
2742{
2743 return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL);
2744}
2745
2746ALIAS (no_match_probability,
2747 no_match_probability_val_cmd,
2748 "no match probability <1-99>",
2749 NO_STR
2750 MATCH_STR
2751 "Match portion of routes defined by percentage value\n"
2752 "Percentage of routes\n")
2753
2754/* } */
2755
hassoc1643bb2005-02-02 16:43:17 +00002756DEFUN (match_ip_route_source,
2757 match_ip_route_source_cmd,
2758 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2759 MATCH_STR
2760 IP_STR
2761 "Match advertising source address of route\n"
2762 "IP access-list number\n"
2763 "IP access-list number (expanded range)\n"
2764 "IP standard access-list name\n")
2765{
2766 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2767}
2768
2769DEFUN (no_match_ip_route_source,
2770 no_match_ip_route_source_cmd,
2771 "no match ip route-source",
2772 NO_STR
2773 MATCH_STR
2774 IP_STR
2775 "Match advertising source address of route\n")
2776{
2777 if (argc == 0)
2778 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2779
2780 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2781}
2782
2783ALIAS (no_match_ip_route_source,
2784 no_match_ip_route_source_val_cmd,
2785 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2786 NO_STR
2787 MATCH_STR
2788 IP_STR
2789 "Match advertising source address of route\n"
2790 "IP access-list number\n"
2791 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002792 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002793
paul718e3742002-12-13 20:15:29 +00002794DEFUN (match_ip_address_prefix_list,
2795 match_ip_address_prefix_list_cmd,
2796 "match ip address prefix-list WORD",
2797 MATCH_STR
2798 IP_STR
2799 "Match address of route\n"
2800 "Match entries of prefix-lists\n"
2801 "IP prefix-list name\n")
2802{
2803 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2804}
2805
2806DEFUN (no_match_ip_address_prefix_list,
2807 no_match_ip_address_prefix_list_cmd,
2808 "no match ip address prefix-list",
2809 NO_STR
2810 MATCH_STR
2811 IP_STR
2812 "Match address of route\n"
2813 "Match entries of prefix-lists\n")
2814{
2815 if (argc == 0)
2816 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2817
2818 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2819}
2820
2821ALIAS (no_match_ip_address_prefix_list,
2822 no_match_ip_address_prefix_list_val_cmd,
2823 "no match ip address prefix-list WORD",
2824 NO_STR
2825 MATCH_STR
2826 IP_STR
2827 "Match address of route\n"
2828 "Match entries of prefix-lists\n"
2829 "IP prefix-list name\n")
2830
2831DEFUN (match_ip_next_hop_prefix_list,
2832 match_ip_next_hop_prefix_list_cmd,
2833 "match ip next-hop prefix-list WORD",
2834 MATCH_STR
2835 IP_STR
2836 "Match next-hop address of route\n"
2837 "Match entries of prefix-lists\n"
2838 "IP prefix-list name\n")
2839{
2840 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2841}
2842
2843DEFUN (no_match_ip_next_hop_prefix_list,
2844 no_match_ip_next_hop_prefix_list_cmd,
2845 "no match ip next-hop prefix-list",
2846 NO_STR
2847 MATCH_STR
2848 IP_STR
2849 "Match next-hop address of route\n"
2850 "Match entries of prefix-lists\n")
2851{
2852 if (argc == 0)
2853 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2854
2855 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2856}
2857
2858ALIAS (no_match_ip_next_hop_prefix_list,
2859 no_match_ip_next_hop_prefix_list_val_cmd,
2860 "no match ip next-hop prefix-list WORD",
2861 NO_STR
2862 MATCH_STR
2863 IP_STR
2864 "Match next-hop address of route\n"
2865 "Match entries of prefix-lists\n"
2866 "IP prefix-list name\n")
2867
hassoc1643bb2005-02-02 16:43:17 +00002868DEFUN (match_ip_route_source_prefix_list,
2869 match_ip_route_source_prefix_list_cmd,
2870 "match ip route-source prefix-list WORD",
2871 MATCH_STR
2872 IP_STR
2873 "Match advertising source address of route\n"
2874 "Match entries of prefix-lists\n"
2875 "IP prefix-list name\n")
2876{
2877 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2878}
2879
2880DEFUN (no_match_ip_route_source_prefix_list,
2881 no_match_ip_route_source_prefix_list_cmd,
2882 "no match ip route-source prefix-list",
2883 NO_STR
2884 MATCH_STR
2885 IP_STR
2886 "Match advertising source address of route\n"
2887 "Match entries of prefix-lists\n")
2888{
2889 if (argc == 0)
2890 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2891
2892 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2893}
2894
2895ALIAS (no_match_ip_route_source_prefix_list,
2896 no_match_ip_route_source_prefix_list_val_cmd,
2897 "no match ip route-source prefix-list WORD",
2898 NO_STR
2899 MATCH_STR
2900 IP_STR
2901 "Match advertising source address of route\n"
2902 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002903 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002904
paul718e3742002-12-13 20:15:29 +00002905DEFUN (match_metric,
2906 match_metric_cmd,
2907 "match metric <0-4294967295>",
2908 MATCH_STR
2909 "Match metric of route\n"
2910 "Metric value\n")
2911{
2912 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2913}
2914
2915DEFUN (no_match_metric,
2916 no_match_metric_cmd,
2917 "no match metric",
2918 NO_STR
2919 MATCH_STR
2920 "Match metric of route\n")
2921{
2922 if (argc == 0)
2923 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2924
2925 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2926}
2927
2928ALIAS (no_match_metric,
2929 no_match_metric_val_cmd,
2930 "no match metric <0-4294967295>",
2931 NO_STR
2932 MATCH_STR
2933 "Match metric of route\n"
2934 "Metric value\n")
2935
Dinesh Dutt5cf768a2015-11-09 20:21:53 -05002936DEFUN (match_local_pref,
2937 match_local_pref_cmd,
2938 "match local-preference <0-4294967295>",
2939 MATCH_STR
2940 "Match local-preference of route\n"
2941 "Metric value\n")
2942{
2943 return bgp_route_match_add (vty, vty->index, "local-preference", argv[0]);
2944}
2945
2946DEFUN (no_match_local_pref,
2947 no_match_local_pref_cmd,
2948 "no match local-preference",
2949 NO_STR
2950 MATCH_STR
2951 "Match local preference of route\n")
2952{
2953 if (argc == 0)
2954 return bgp_route_match_delete (vty, vty->index, "local-preference", NULL);
2955
2956 return bgp_route_match_delete (vty, vty->index, "local-preference", argv[0]);
2957}
2958
2959ALIAS (no_match_local_pref,
2960 no_match_local_pref_val_cmd,
2961 "no match local-preference <0-4294967295>",
2962 NO_STR
2963 MATCH_STR
2964 "Match local preference of route\n"
2965 "Local preference value\n")
2966
paul718e3742002-12-13 20:15:29 +00002967DEFUN (match_community,
2968 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002969 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002970 MATCH_STR
2971 "Match BGP community list\n"
2972 "Community-list number (standard)\n"
2973 "Community-list number (expanded)\n"
2974 "Community-list name\n")
2975{
2976 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2977}
2978
2979DEFUN (match_community_exact,
2980 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002981 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002982 MATCH_STR
2983 "Match BGP community list\n"
2984 "Community-list number (standard)\n"
2985 "Community-list number (expanded)\n"
2986 "Community-list name\n"
2987 "Do exact matching of communities\n")
2988{
2989 int ret;
2990 char *argstr;
2991
2992 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2993 strlen (argv[0]) + strlen ("exact-match") + 2);
2994
2995 sprintf (argstr, "%s exact-match", argv[0]);
2996
2997 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2998
2999 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3000
3001 return ret;
3002}
3003
3004DEFUN (no_match_community,
3005 no_match_community_cmd,
3006 "no match community",
3007 NO_STR
3008 MATCH_STR
3009 "Match BGP community list\n")
3010{
3011 return bgp_route_match_delete (vty, vty->index, "community", NULL);
3012}
3013
3014ALIAS (no_match_community,
3015 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003016 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00003017 NO_STR
3018 MATCH_STR
3019 "Match BGP community list\n"
3020 "Community-list number (standard)\n"
3021 "Community-list number (expanded)\n"
3022 "Community-list name\n")
3023
3024ALIAS (no_match_community,
3025 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003026 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00003027 NO_STR
3028 MATCH_STR
3029 "Match BGP community list\n"
3030 "Community-list number (standard)\n"
3031 "Community-list number (expanded)\n"
3032 "Community-list name\n"
3033 "Do exact matching of communities\n")
3034
paul73ffb252003-04-19 15:49:49 +00003035DEFUN (match_ecommunity,
3036 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003037 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00003038 MATCH_STR
3039 "Match BGP/VPN extended community list\n"
3040 "Extended community-list number (standard)\n"
3041 "Extended community-list number (expanded)\n"
3042 "Extended community-list name\n")
3043{
3044 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
3045}
3046
3047DEFUN (no_match_ecommunity,
3048 no_match_ecommunity_cmd,
3049 "no match extcommunity",
3050 NO_STR
3051 MATCH_STR
3052 "Match BGP/VPN extended community list\n")
3053{
3054 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
3055}
3056
3057ALIAS (no_match_ecommunity,
3058 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003059 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00003060 NO_STR
3061 MATCH_STR
3062 "Match BGP/VPN extended community list\n"
3063 "Extended community-list number (standard)\n"
3064 "Extended community-list number (expanded)\n"
3065 "Extended community-list name\n")
3066
paul718e3742002-12-13 20:15:29 +00003067DEFUN (match_aspath,
3068 match_aspath_cmd,
3069 "match as-path WORD",
3070 MATCH_STR
3071 "Match BGP AS path list\n"
3072 "AS path access-list name\n")
3073{
3074 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
3075}
3076
3077DEFUN (no_match_aspath,
3078 no_match_aspath_cmd,
3079 "no match as-path",
3080 NO_STR
3081 MATCH_STR
3082 "Match BGP AS path list\n")
3083{
3084 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
3085}
3086
3087ALIAS (no_match_aspath,
3088 no_match_aspath_val_cmd,
3089 "no match as-path WORD",
3090 NO_STR
3091 MATCH_STR
3092 "Match BGP AS path list\n"
3093 "AS path access-list name\n")
3094
3095DEFUN (match_origin,
3096 match_origin_cmd,
3097 "match origin (egp|igp|incomplete)",
3098 MATCH_STR
3099 "BGP origin code\n"
3100 "remote EGP\n"
3101 "local IGP\n"
3102 "unknown heritage\n")
3103{
3104 if (strncmp (argv[0], "igp", 2) == 0)
3105 return bgp_route_match_add (vty, vty->index, "origin", "igp");
3106 if (strncmp (argv[0], "egp", 1) == 0)
3107 return bgp_route_match_add (vty, vty->index, "origin", "egp");
3108 if (strncmp (argv[0], "incomplete", 2) == 0)
3109 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
3110
3111 return CMD_WARNING;
3112}
3113
3114DEFUN (no_match_origin,
3115 no_match_origin_cmd,
3116 "no match origin",
3117 NO_STR
3118 MATCH_STR
3119 "BGP origin code\n")
3120{
3121 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
3122}
3123
3124ALIAS (no_match_origin,
3125 no_match_origin_val_cmd,
3126 "no match origin (egp|igp|incomplete)",
3127 NO_STR
3128 MATCH_STR
3129 "BGP origin code\n"
3130 "remote EGP\n"
3131 "local IGP\n"
3132 "unknown heritage\n")
3133
Piotr Chytła605aa332015-12-01 10:03:54 -05003134DEFUN (match_tag,
3135 match_tag_cmd,
3136 "match tag <1-65535>",
3137 MATCH_STR
3138 "Match tag of route\n"
3139 "Tag value\n")
3140{
3141 return bgp_route_match_add (vty, vty->index, "tag", argv[0]);
3142}
3143
3144DEFUN (no_match_tag,
3145 no_match_tag_cmd,
3146 "no match tag",
3147 NO_STR
3148 MATCH_STR
3149 "Match tag of route\n")
3150{
3151 if (argc == 0)
3152 return bgp_route_match_delete (vty, vty->index, "tag", NULL);
3153
3154 return bgp_route_match_delete (vty, vty->index, "tag", argv[0]);
3155}
3156
3157ALIAS (no_match_tag,
3158 no_match_tag_val_cmd,
3159 "no match tag <1-65535>",
3160 NO_STR
3161 MATCH_STR
3162 "Match tag of route\n"
3163 "Tag value\n")
3164
paul718e3742002-12-13 20:15:29 +00003165DEFUN (set_ip_nexthop,
3166 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00003167 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003168 SET_STR
3169 IP_STR
3170 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00003171 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00003172{
3173 union sockunion su;
3174 int ret;
3175
3176 ret = str2sockunion (argv[0], &su);
3177 if (ret < 0)
3178 {
3179 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
3180 return CMD_WARNING;
3181 }
3182
3183 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
3184}
3185
paulaf5cd0a2003-11-02 07:24:40 +00003186DEFUN (set_ip_nexthop_peer,
3187 set_ip_nexthop_peer_cmd,
3188 "set ip next-hop peer-address",
3189 SET_STR
3190 IP_STR
3191 "Next hop address\n"
3192 "Use peer address (for BGP only)\n")
3193{
3194 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
3195}
3196
paul94f2b392005-06-28 12:44:16 +00003197DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00003198 no_set_ip_nexthop_peer_cmd,
3199 "no set ip next-hop peer-address",
3200 NO_STR
3201 SET_STR
3202 IP_STR
3203 "Next hop address\n"
3204 "Use peer address (for BGP only)\n")
3205{
3206 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
3207}
3208
3209
paul718e3742002-12-13 20:15:29 +00003210DEFUN (no_set_ip_nexthop,
3211 no_set_ip_nexthop_cmd,
3212 "no set ip next-hop",
3213 NO_STR
3214 SET_STR
paul718e3742002-12-13 20:15:29 +00003215 "Next hop address\n")
3216{
paulaf5cd0a2003-11-02 07:24:40 +00003217 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00003218 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
3219
3220 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
3221}
3222
3223ALIAS (no_set_ip_nexthop,
3224 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00003225 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003226 NO_STR
3227 SET_STR
3228 IP_STR
3229 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00003230 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00003231
3232DEFUN (set_metric,
3233 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00003234 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00003235 SET_STR
3236 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00003237 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00003238{
3239 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
3240}
3241
paul73ffb252003-04-19 15:49:49 +00003242ALIAS (set_metric,
3243 set_metric_addsub_cmd,
3244 "set metric <+/-metric>",
3245 SET_STR
3246 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00003247 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00003248
Timo Teräsef757702015-04-29 09:43:04 +03003249ALIAS (set_metric,
3250 set_metric_rtt_cmd,
3251 "set metric (rtt|+rtt|-rtt)",
3252 SET_STR
3253 "Metric value for destination routing protocol\n"
3254 "Assign round trip time\n"
3255 "Add round trip time\n"
3256 "Subtract round trip time\n")
3257
paul718e3742002-12-13 20:15:29 +00003258DEFUN (no_set_metric,
3259 no_set_metric_cmd,
3260 "no set metric",
3261 NO_STR
3262 SET_STR
3263 "Metric value for destination routing protocol\n")
3264{
3265 if (argc == 0)
3266 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
3267
3268 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
3269}
3270
3271ALIAS (no_set_metric,
3272 no_set_metric_val_cmd,
3273 "no set metric <0-4294967295>",
3274 NO_STR
3275 SET_STR
3276 "Metric value for destination routing protocol\n"
3277 "Metric value\n")
3278
3279DEFUN (set_local_pref,
3280 set_local_pref_cmd,
3281 "set local-preference <0-4294967295>",
3282 SET_STR
3283 "BGP local preference path attribute\n"
3284 "Preference value\n")
3285{
3286 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
3287}
3288
3289DEFUN (no_set_local_pref,
3290 no_set_local_pref_cmd,
3291 "no set local-preference",
3292 NO_STR
3293 SET_STR
3294 "BGP local preference path attribute\n")
3295{
3296 if (argc == 0)
3297 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3298
3299 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
3300}
3301
3302ALIAS (no_set_local_pref,
3303 no_set_local_pref_val_cmd,
3304 "no set local-preference <0-4294967295>",
3305 NO_STR
3306 SET_STR
3307 "BGP local preference path attribute\n"
3308 "Preference value\n")
3309
3310DEFUN (set_weight,
3311 set_weight_cmd,
3312 "set weight <0-4294967295>",
3313 SET_STR
3314 "BGP weight for routing table\n"
3315 "Weight value\n")
3316{
3317 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3318}
3319
3320DEFUN (no_set_weight,
3321 no_set_weight_cmd,
3322 "no set weight",
3323 NO_STR
3324 SET_STR
3325 "BGP weight for routing table\n")
3326{
3327 if (argc == 0)
3328 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3329
3330 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3331}
3332
3333ALIAS (no_set_weight,
3334 no_set_weight_val_cmd,
3335 "no set weight <0-4294967295>",
3336 NO_STR
3337 SET_STR
3338 "BGP weight for routing table\n"
3339 "Weight value\n")
3340
3341DEFUN (set_aspath_prepend,
3342 set_aspath_prepend_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003343 "set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003344 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003345 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003346 "Prepend to the as-path\n"
3347 "AS number\n")
3348{
3349 int ret;
3350 char *str;
3351
3352 str = argv_concat (argv, argc, 0);
3353 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3354 XFREE (MTYPE_TMP, str);
3355
3356 return ret;
3357}
3358
Timo Teräs85c854a2014-09-30 11:31:53 +03003359ALIAS (set_aspath_prepend,
3360 set_aspath_prepend_lastas_cmd,
3361 "set as-path prepend (last-as) <1-10>",
3362 SET_STR
3363 "Transform BGP AS_PATH attribute\n"
3364 "Prepend to the as-path\n"
3365 "Use the peer's AS-number\n"
David Lamparterb7d50212015-03-03 08:53:18 +01003366 "Number of times to insert")
Timo Teräs85c854a2014-09-30 11:31:53 +03003367
paul718e3742002-12-13 20:15:29 +00003368DEFUN (no_set_aspath_prepend,
3369 no_set_aspath_prepend_cmd,
3370 "no set as-path prepend",
3371 NO_STR
3372 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003373 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003374 "Prepend to the as-path\n")
3375{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00003376 int ret;
3377 char *str;
3378
3379 if (argc == 0)
3380 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3381
3382 str = argv_concat (argv, argc, 0);
3383 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3384 XFREE (MTYPE_TMP, str);
3385 return ret;
paul718e3742002-12-13 20:15:29 +00003386}
3387
3388ALIAS (no_set_aspath_prepend,
3389 no_set_aspath_prepend_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003390 "no set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003391 NO_STR
3392 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003393 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003394 "Prepend to the as-path\n"
3395 "AS number\n")
3396
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003397DEFUN (set_aspath_exclude,
3398 set_aspath_exclude_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003399 "set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003400 SET_STR
3401 "Transform BGP AS-path attribute\n"
3402 "Exclude from the as-path\n"
3403 "AS number\n")
3404{
3405 int ret;
3406 char *str;
3407
3408 str = argv_concat (argv, argc, 0);
3409 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3410 XFREE (MTYPE_TMP, str);
3411 return ret;
3412}
3413
3414DEFUN (no_set_aspath_exclude,
3415 no_set_aspath_exclude_cmd,
3416 "no set as-path exclude",
3417 NO_STR
3418 SET_STR
3419 "Transform BGP AS_PATH attribute\n"
3420 "Exclude from the as-path\n")
3421{
3422 int ret;
3423 char *str;
3424
3425 if (argc == 0)
3426 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3427
3428 str = argv_concat (argv, argc, 0);
3429 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3430 XFREE (MTYPE_TMP, str);
3431 return ret;
3432}
3433
3434ALIAS (no_set_aspath_exclude,
3435 no_set_aspath_exclude_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003436 "no set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003437 NO_STR
3438 SET_STR
3439 "Transform BGP AS_PATH attribute\n"
3440 "Exclude from the as-path\n"
3441 "AS number\n")
3442
paul718e3742002-12-13 20:15:29 +00003443DEFUN (set_community,
3444 set_community_cmd,
3445 "set community .AA:NN",
3446 SET_STR
3447 "BGP community attribute\n"
3448 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3449{
3450 int i;
3451 int first = 0;
3452 int additive = 0;
3453 struct buffer *b;
3454 struct community *com = NULL;
3455 char *str;
3456 char *argstr;
3457 int ret;
3458
3459 b = buffer_new (1024);
3460
3461 for (i = 0; i < argc; i++)
3462 {
3463 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3464 {
3465 additive = 1;
3466 continue;
3467 }
3468
3469 if (first)
3470 buffer_putc (b, ' ');
3471 else
3472 first = 1;
3473
3474 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3475 {
3476 buffer_putstr (b, "internet");
3477 continue;
3478 }
3479 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3480 {
3481 buffer_putstr (b, "local-AS");
3482 continue;
3483 }
3484 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3485 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3486 {
3487 buffer_putstr (b, "no-advertise");
3488 continue;
3489 }
3490 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3491 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3492 {
3493 buffer_putstr (b, "no-export");
3494 continue;
3495 }
3496 buffer_putstr (b, argv[i]);
3497 }
3498 buffer_putc (b, '\0');
3499
3500 /* Fetch result string then compile it to communities attribute. */
3501 str = buffer_getstr (b);
3502 buffer_free (b);
3503
3504 if (str)
3505 {
3506 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003507 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003508 }
3509
3510 /* Can't compile user input into communities attribute. */
3511 if (! com)
3512 {
3513 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3514 return CMD_WARNING;
3515 }
3516
3517 /* Set communites attribute string. */
3518 str = community_str (com);
3519
3520 if (additive)
3521 {
3522 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3523 strcpy (argstr, str);
3524 strcpy (argstr + strlen (str), " additive");
3525 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3526 XFREE (MTYPE_TMP, argstr);
3527 }
3528 else
3529 ret = bgp_route_set_add (vty, vty->index, "community", str);
3530
3531 community_free (com);
3532
3533 return ret;
3534}
3535
3536DEFUN (set_community_none,
3537 set_community_none_cmd,
3538 "set community none",
3539 SET_STR
3540 "BGP community attribute\n"
3541 "No community attribute\n")
3542{
3543 return bgp_route_set_add (vty, vty->index, "community", "none");
3544}
3545
3546DEFUN (no_set_community,
3547 no_set_community_cmd,
3548 "no set community",
3549 NO_STR
3550 SET_STR
3551 "BGP community attribute\n")
3552{
3553 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3554}
3555
3556ALIAS (no_set_community,
3557 no_set_community_val_cmd,
3558 "no set community .AA:NN",
3559 NO_STR
3560 SET_STR
3561 "BGP community attribute\n"
3562 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3563
3564ALIAS (no_set_community,
3565 no_set_community_none_cmd,
3566 "no set community none",
3567 NO_STR
3568 SET_STR
3569 "BGP community attribute\n"
3570 "No community attribute\n")
3571
3572DEFUN (set_community_delete,
3573 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003574 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003575 SET_STR
3576 "set BGP community list (for deletion)\n"
3577 "Community-list number (standard)\n"
Daniel Waltonc7f25b92015-05-19 17:47:22 -07003578 "Community-list number (expanded)\n"
paul718e3742002-12-13 20:15:29 +00003579 "Community-list name\n"
3580 "Delete matching communities\n")
3581{
3582 char *str;
3583
3584 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3585 strcpy (str, argv[0]);
3586 strcpy (str + strlen (argv[0]), " delete");
3587
3588 bgp_route_set_add (vty, vty->index, "comm-list", str);
3589
3590 XFREE (MTYPE_TMP, str);
3591 return CMD_SUCCESS;
3592}
3593
3594DEFUN (no_set_community_delete,
3595 no_set_community_delete_cmd,
3596 "no set comm-list",
3597 NO_STR
3598 SET_STR
3599 "set BGP community list (for deletion)\n")
3600{
3601 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3602}
3603
3604ALIAS (no_set_community_delete,
3605 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003606 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003607 NO_STR
3608 SET_STR
3609 "set BGP community list (for deletion)\n"
3610 "Community-list number (standard)\n"
Daniel Waltonc7f25b92015-05-19 17:47:22 -07003611 "Community-list number (expanded)\n"
paul718e3742002-12-13 20:15:29 +00003612 "Community-list name\n"
3613 "Delete matching communities\n")
3614
3615DEFUN (set_ecommunity_rt,
3616 set_ecommunity_rt_cmd,
3617 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3618 SET_STR
3619 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003620 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003621 "VPN extended community\n")
3622{
3623 int ret;
3624 char *str;
3625
3626 str = argv_concat (argv, argc, 0);
3627 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3628 XFREE (MTYPE_TMP, str);
3629
3630 return ret;
3631}
3632
3633DEFUN (no_set_ecommunity_rt,
3634 no_set_ecommunity_rt_cmd,
3635 "no set extcommunity rt",
3636 NO_STR
3637 SET_STR
3638 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003639 "Route Target extended community\n")
paul718e3742002-12-13 20:15:29 +00003640{
3641 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3642}
3643
3644ALIAS (no_set_ecommunity_rt,
3645 no_set_ecommunity_rt_val_cmd,
3646 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3647 NO_STR
3648 SET_STR
3649 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003650 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003651 "VPN extended community\n")
3652
3653DEFUN (set_ecommunity_soo,
3654 set_ecommunity_soo_cmd,
3655 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3656 SET_STR
3657 "BGP extended community attribute\n"
3658 "Site-of-Origin extended community\n"
3659 "VPN extended community\n")
3660{
3661 int ret;
3662 char *str;
3663
3664 str = argv_concat (argv, argc, 0);
3665 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3666 XFREE (MTYPE_TMP, str);
3667 return ret;
3668}
3669
3670DEFUN (no_set_ecommunity_soo,
3671 no_set_ecommunity_soo_cmd,
3672 "no set extcommunity soo",
3673 NO_STR
3674 SET_STR
3675 "BGP extended community attribute\n"
3676 "Site-of-Origin extended community\n")
3677{
3678 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3679}
3680
3681ALIAS (no_set_ecommunity_soo,
3682 no_set_ecommunity_soo_val_cmd,
3683 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3684 NO_STR
3685 SET_STR
3686 "BGP extended community attribute\n"
3687 "Site-of-Origin extended community\n"
3688 "VPN extended community\n")
3689
3690DEFUN (set_origin,
3691 set_origin_cmd,
3692 "set origin (egp|igp|incomplete)",
3693 SET_STR
3694 "BGP origin code\n"
3695 "remote EGP\n"
3696 "local IGP\n"
3697 "unknown heritage\n")
3698{
3699 if (strncmp (argv[0], "igp", 2) == 0)
3700 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3701 if (strncmp (argv[0], "egp", 1) == 0)
3702 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3703 if (strncmp (argv[0], "incomplete", 2) == 0)
3704 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3705
3706 return CMD_WARNING;
3707}
3708
3709DEFUN (no_set_origin,
3710 no_set_origin_cmd,
3711 "no set origin",
3712 NO_STR
3713 SET_STR
3714 "BGP origin code\n")
3715{
3716 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3717}
3718
3719ALIAS (no_set_origin,
3720 no_set_origin_val_cmd,
3721 "no set origin (egp|igp|incomplete)",
3722 NO_STR
3723 SET_STR
3724 "BGP origin code\n"
3725 "remote EGP\n"
3726 "local IGP\n"
3727 "unknown heritage\n")
3728
3729DEFUN (set_atomic_aggregate,
3730 set_atomic_aggregate_cmd,
3731 "set atomic-aggregate",
3732 SET_STR
3733 "BGP atomic aggregate attribute\n" )
3734{
3735 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3736}
3737
3738DEFUN (no_set_atomic_aggregate,
3739 no_set_atomic_aggregate_cmd,
3740 "no set atomic-aggregate",
3741 NO_STR
3742 SET_STR
3743 "BGP atomic aggregate attribute\n" )
3744{
3745 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3746}
3747
3748DEFUN (set_aggregator_as,
3749 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003750 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003751 SET_STR
3752 "BGP aggregator attribute\n"
3753 "AS number of aggregator\n"
3754 "AS number\n"
3755 "IP address of aggregator\n")
3756{
3757 int ret;
Paul Jakma7aa9dce2014-09-19 14:42:23 +01003758 as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
paul718e3742002-12-13 20:15:29 +00003759 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003760 char *argstr;
3761
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003762 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003763
paul718e3742002-12-13 20:15:29 +00003764 ret = inet_aton (argv[1], &address);
3765 if (ret == 0)
3766 {
3767 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3768 return CMD_WARNING;
3769 }
3770
3771 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3772 strlen (argv[0]) + strlen (argv[1]) + 2);
3773
3774 sprintf (argstr, "%s %s", argv[0], argv[1]);
3775
3776 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3777
3778 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3779
3780 return ret;
3781}
3782
3783DEFUN (no_set_aggregator_as,
3784 no_set_aggregator_as_cmd,
3785 "no set aggregator as",
3786 NO_STR
3787 SET_STR
3788 "BGP aggregator attribute\n"
3789 "AS number of aggregator\n")
3790{
3791 int ret;
Paul Jakma7aa9dce2014-09-19 14:42:23 +01003792 as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
paul718e3742002-12-13 20:15:29 +00003793 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003794 char *argstr;
3795
3796 if (argv == 0)
3797 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3798
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003799 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003800
3801 ret = inet_aton (argv[1], &address);
3802 if (ret == 0)
3803 {
3804 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3805 return CMD_WARNING;
3806 }
3807
3808 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3809 strlen (argv[0]) + strlen (argv[1]) + 2);
3810
3811 sprintf (argstr, "%s %s", argv[0], argv[1]);
3812
3813 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3814
3815 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3816
3817 return ret;
3818}
3819
3820ALIAS (no_set_aggregator_as,
3821 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003822 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003823 NO_STR
3824 SET_STR
3825 "BGP aggregator attribute\n"
3826 "AS number of aggregator\n"
3827 "AS number\n"
3828 "IP address of aggregator\n")
3829
Piotr Chytła605aa332015-12-01 10:03:54 -05003830DEFUN (set_tag,
3831 set_tag_cmd,
3832 "set tag <1-65535>",
3833 SET_STR
3834 "Tag value for routing protocol\n"
3835 "Tag value\n")
3836{
3837 return bgp_route_set_add (vty, vty->index, "tag", argv[0]);
3838}
3839
3840DEFUN (no_set_tag,
3841 no_set_tag_cmd,
3842 "no set tag",
3843 NO_STR
3844 SET_STR
3845 "Tag value for routing protocol\n")
3846{
3847 if (argc == 0)
3848 bgp_route_set_delete(vty, vty->index, "tag", NULL);
3849
3850 return bgp_route_set_delete (vty, vty->index, "tag", argv[0]);
3851}
3852
3853ALIAS (no_set_tag,
3854 no_set_tag_val_cmd,
3855 "no set tag <1-65535>",
3856 NO_STR
3857 SET_STR
3858 "Tag value for routing protocol\n"
3859 "Tag value\n")
3860
3861
paul718e3742002-12-13 20:15:29 +00003862DEFUN (match_ipv6_address,
3863 match_ipv6_address_cmd,
3864 "match ipv6 address WORD",
3865 MATCH_STR
3866 IPV6_STR
3867 "Match IPv6 address of route\n"
3868 "IPv6 access-list name\n")
3869{
3870 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3871}
3872
3873DEFUN (no_match_ipv6_address,
3874 no_match_ipv6_address_cmd,
3875 "no match ipv6 address WORD",
3876 NO_STR
3877 MATCH_STR
3878 IPV6_STR
3879 "Match IPv6 address of route\n"
3880 "IPv6 access-list name\n")
3881{
3882 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3883}
3884
3885DEFUN (match_ipv6_next_hop,
3886 match_ipv6_next_hop_cmd,
3887 "match ipv6 next-hop X:X::X:X",
3888 MATCH_STR
3889 IPV6_STR
3890 "Match IPv6 next-hop address of route\n"
3891 "IPv6 address of next hop\n")
3892{
3893 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3894}
3895
3896DEFUN (no_match_ipv6_next_hop,
3897 no_match_ipv6_next_hop_cmd,
3898 "no match ipv6 next-hop X:X::X:X",
3899 NO_STR
3900 MATCH_STR
3901 IPV6_STR
3902 "Match IPv6 next-hop address of route\n"
3903 "IPv6 address of next hop\n")
3904{
3905 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3906}
3907
3908DEFUN (match_ipv6_address_prefix_list,
3909 match_ipv6_address_prefix_list_cmd,
3910 "match ipv6 address prefix-list WORD",
3911 MATCH_STR
3912 IPV6_STR
3913 "Match address of route\n"
3914 "Match entries of prefix-lists\n"
3915 "IP prefix-list name\n")
3916{
3917 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3918}
3919
3920DEFUN (no_match_ipv6_address_prefix_list,
3921 no_match_ipv6_address_prefix_list_cmd,
3922 "no match ipv6 address prefix-list WORD",
3923 NO_STR
3924 MATCH_STR
3925 IPV6_STR
3926 "Match address of route\n"
3927 "Match entries of prefix-lists\n"
3928 "IP prefix-list name\n")
3929{
3930 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3931}
3932
Dinesh G Duttad5233a2014-09-30 14:19:57 -07003933DEFUN (set_ipv6_nexthop_peer,
3934 set_ipv6_nexthop_peer_cmd,
3935 "set ipv6 next-hop peer-address",
3936 SET_STR
3937 IPV6_STR
3938 "Next hop address\n"
3939 "Use peer address (for BGP only)\n")
3940{
3941 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop peer-address", NULL);
3942}
3943
3944DEFUN (no_set_ipv6_nexthop_peer,
3945 no_set_ipv6_nexthop_peer_cmd,
3946 "no set ipv6 next-hop peer-address",
3947 NO_STR
3948 SET_STR
3949 IPV6_STR
3950 "IPv6 next-hop address\n"
3951 )
3952{
3953 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3954}
3955
paul718e3742002-12-13 20:15:29 +00003956DEFUN (set_ipv6_nexthop_global,
3957 set_ipv6_nexthop_global_cmd,
3958 "set ipv6 next-hop global X:X::X:X",
3959 SET_STR
3960 IPV6_STR
3961 "IPv6 next-hop address\n"
3962 "IPv6 global address\n"
3963 "IPv6 address of next hop\n")
3964{
3965 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3966}
3967
3968DEFUN (no_set_ipv6_nexthop_global,
3969 no_set_ipv6_nexthop_global_cmd,
3970 "no set ipv6 next-hop global",
3971 NO_STR
3972 SET_STR
3973 IPV6_STR
3974 "IPv6 next-hop address\n"
3975 "IPv6 global address\n")
3976{
3977 if (argc == 0)
3978 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3979
3980 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3981}
3982
3983ALIAS (no_set_ipv6_nexthop_global,
3984 no_set_ipv6_nexthop_global_val_cmd,
3985 "no set ipv6 next-hop global X:X::X:X",
3986 NO_STR
3987 SET_STR
3988 IPV6_STR
3989 "IPv6 next-hop address\n"
3990 "IPv6 global address\n"
3991 "IPv6 address of next hop\n")
3992
3993DEFUN (set_ipv6_nexthop_local,
3994 set_ipv6_nexthop_local_cmd,
3995 "set ipv6 next-hop local X:X::X:X",
3996 SET_STR
3997 IPV6_STR
3998 "IPv6 next-hop address\n"
3999 "IPv6 local address\n"
4000 "IPv6 address of next hop\n")
4001{
4002 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
4003}
4004
4005DEFUN (no_set_ipv6_nexthop_local,
4006 no_set_ipv6_nexthop_local_cmd,
4007 "no set ipv6 next-hop local",
4008 NO_STR
4009 SET_STR
4010 IPV6_STR
4011 "IPv6 next-hop address\n"
4012 "IPv6 local address\n")
4013{
4014 if (argc == 0)
4015 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
4016
4017 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
4018}
4019
4020ALIAS (no_set_ipv6_nexthop_local,
4021 no_set_ipv6_nexthop_local_val_cmd,
4022 "no set ipv6 next-hop local X:X::X:X",
4023 NO_STR
4024 SET_STR
4025 IPV6_STR
4026 "IPv6 next-hop address\n"
4027 "IPv6 local address\n"
4028 "IPv6 address of next hop\n")
paul718e3742002-12-13 20:15:29 +00004029
4030DEFUN (set_vpnv4_nexthop,
4031 set_vpnv4_nexthop_cmd,
4032 "set vpnv4 next-hop A.B.C.D",
4033 SET_STR
4034 "VPNv4 information\n"
4035 "VPNv4 next-hop address\n"
4036 "IP address of next hop\n")
4037{
4038 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
4039}
4040
4041DEFUN (no_set_vpnv4_nexthop,
4042 no_set_vpnv4_nexthop_cmd,
4043 "no set vpnv4 next-hop",
4044 NO_STR
4045 SET_STR
4046 "VPNv4 information\n"
4047 "VPNv4 next-hop address\n")
4048{
4049 if (argc == 0)
4050 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
4051
4052 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
4053}
4054
4055ALIAS (no_set_vpnv4_nexthop,
4056 no_set_vpnv4_nexthop_val_cmd,
4057 "no set vpnv4 next-hop A.B.C.D",
4058 NO_STR
4059 SET_STR
4060 "VPNv4 information\n"
4061 "VPNv4 next-hop address\n"
4062 "IP address of next hop\n")
4063
4064DEFUN (set_originator_id,
4065 set_originator_id_cmd,
4066 "set originator-id A.B.C.D",
4067 SET_STR
4068 "BGP originator ID attribute\n"
4069 "IP address of originator\n")
4070{
4071 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
4072}
4073
4074DEFUN (no_set_originator_id,
4075 no_set_originator_id_cmd,
4076 "no set originator-id",
4077 NO_STR
4078 SET_STR
4079 "BGP originator ID attribute\n")
4080{
4081 if (argc == 0)
4082 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
4083
4084 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
4085}
4086
4087ALIAS (no_set_originator_id,
4088 no_set_originator_id_val_cmd,
4089 "no set originator-id A.B.C.D",
4090 NO_STR
4091 SET_STR
4092 "BGP originator ID attribute\n"
4093 "IP address of originator\n")
4094
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004095DEFUN_DEPRECATED (set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00004096 set_pathlimit_ttl_cmd,
4097 "set pathlimit ttl <1-255>",
4098 SET_STR
4099 "BGP AS-Pathlimit attribute\n"
4100 "Set AS-Path Hop-count TTL\n")
4101{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004102 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00004103}
4104
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004105DEFUN_DEPRECATED (no_set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00004106 no_set_pathlimit_ttl_cmd,
4107 "no set pathlimit ttl",
4108 NO_STR
4109 SET_STR
4110 "BGP AS-Pathlimit attribute\n"
4111 "Set AS-Path Hop-count TTL\n")
4112{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004113 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00004114}
4115
4116ALIAS (no_set_pathlimit_ttl,
4117 no_set_pathlimit_ttl_val_cmd,
4118 "no set pathlimit ttl <1-255>",
4119 NO_STR
4120 MATCH_STR
4121 "BGP AS-Pathlimit attribute\n"
4122 "Set AS-Path Hop-count TTL\n")
4123
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004124DEFUN_DEPRECATED (match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00004125 match_pathlimit_as_cmd,
4126 "match pathlimit as <1-65535>",
4127 MATCH_STR
4128 "BGP AS-Pathlimit attribute\n"
4129 "Match Pathlimit AS number\n")
4130{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004131 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00004132}
4133
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004134DEFUN_DEPRECATED (no_match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00004135 no_match_pathlimit_as_cmd,
4136 "no match pathlimit as",
4137 NO_STR
4138 MATCH_STR
4139 "BGP AS-Pathlimit attribute\n"
4140 "Match Pathlimit AS number\n")
4141{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004142 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00004143}
4144
4145ALIAS (no_match_pathlimit_as,
4146 no_match_pathlimit_as_val_cmd,
4147 "no match pathlimit as <1-65535>",
4148 NO_STR
4149 MATCH_STR
4150 "BGP AS-Pathlimit attribute\n"
4151 "Match Pathlimit ASN\n")
4152
David Lamparter6b0655a2014-06-04 06:53:35 +02004153
paul718e3742002-12-13 20:15:29 +00004154/* Initialization of route map. */
4155void
paul94f2b392005-06-28 12:44:16 +00004156bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00004157{
4158 route_map_init ();
4159 route_map_init_vty ();
4160 route_map_add_hook (bgp_route_map_update);
4161 route_map_delete_hook (bgp_route_map_update);
4162
paulfee0f4c2004-09-13 05:12:46 +00004163 route_map_install_match (&route_match_peer_cmd);
Dinesh Dutt5cf768a2015-11-09 20:21:53 -05004164 route_map_install_match (&route_match_local_pref_cmd);
paul718e3742002-12-13 20:15:29 +00004165 route_map_install_match (&route_match_ip_address_cmd);
4166 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00004167 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00004168 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
4169 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00004170 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00004171 route_map_install_match (&route_match_aspath_cmd);
4172 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00004173 route_map_install_match (&route_match_ecommunity_cmd);
Dinesh Dutt5cf768a2015-11-09 20:21:53 -05004174 route_map_install_match (&route_match_local_pref_cmd);
paul718e3742002-12-13 20:15:29 +00004175 route_map_install_match (&route_match_metric_cmd);
4176 route_map_install_match (&route_match_origin_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04004177 route_map_install_match (&route_match_probability_cmd);
Piotr Chytła605aa332015-12-01 10:03:54 -05004178 route_map_install_match (&route_match_tag_cmd);
paul718e3742002-12-13 20:15:29 +00004179
4180 route_map_install_set (&route_set_ip_nexthop_cmd);
4181 route_map_install_set (&route_set_local_pref_cmd);
4182 route_map_install_set (&route_set_weight_cmd);
4183 route_map_install_set (&route_set_metric_cmd);
4184 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00004185 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00004186 route_map_install_set (&route_set_origin_cmd);
4187 route_map_install_set (&route_set_atomic_aggregate_cmd);
4188 route_map_install_set (&route_set_aggregator_as_cmd);
4189 route_map_install_set (&route_set_community_cmd);
4190 route_map_install_set (&route_set_community_delete_cmd);
4191 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
4192 route_map_install_set (&route_set_originator_id_cmd);
4193 route_map_install_set (&route_set_ecommunity_rt_cmd);
4194 route_map_install_set (&route_set_ecommunity_soo_cmd);
Piotr Chytła605aa332015-12-01 10:03:54 -05004195 route_map_install_set (&route_set_tag_cmd);
paul718e3742002-12-13 20:15:29 +00004196
paulfee0f4c2004-09-13 05:12:46 +00004197 install_element (RMAP_NODE, &match_peer_cmd);
4198 install_element (RMAP_NODE, &match_peer_local_cmd);
4199 install_element (RMAP_NODE, &no_match_peer_cmd);
4200 install_element (RMAP_NODE, &no_match_peer_val_cmd);
4201 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00004202 install_element (RMAP_NODE, &match_ip_address_cmd);
4203 install_element (RMAP_NODE, &no_match_ip_address_cmd);
4204 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
4205 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
4206 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
4207 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00004208 install_element (RMAP_NODE, &match_ip_route_source_cmd);
4209 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
4210 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00004211 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
4212 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
4213 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
4214 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
4215 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
4216 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00004217 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
4218 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
4219 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00004220
4221 install_element (RMAP_NODE, &match_aspath_cmd);
4222 install_element (RMAP_NODE, &no_match_aspath_cmd);
4223 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
4224 install_element (RMAP_NODE, &match_metric_cmd);
4225 install_element (RMAP_NODE, &no_match_metric_cmd);
4226 install_element (RMAP_NODE, &no_match_metric_val_cmd);
Dinesh Dutt5cf768a2015-11-09 20:21:53 -05004227 install_element (RMAP_NODE, &match_local_pref_cmd);
4228 install_element (RMAP_NODE, &no_match_local_pref_cmd);
4229 install_element (RMAP_NODE, &no_match_local_pref_val_cmd);
paul718e3742002-12-13 20:15:29 +00004230 install_element (RMAP_NODE, &match_community_cmd);
4231 install_element (RMAP_NODE, &match_community_exact_cmd);
4232 install_element (RMAP_NODE, &no_match_community_cmd);
4233 install_element (RMAP_NODE, &no_match_community_val_cmd);
4234 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00004235 install_element (RMAP_NODE, &match_ecommunity_cmd);
4236 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
4237 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00004238 install_element (RMAP_NODE, &match_origin_cmd);
4239 install_element (RMAP_NODE, &no_match_origin_cmd);
4240 install_element (RMAP_NODE, &no_match_origin_val_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04004241 install_element (RMAP_NODE, &match_probability_cmd);
4242 install_element (RMAP_NODE, &no_match_probability_cmd);
4243 install_element (RMAP_NODE, &no_match_probability_val_cmd);
Piotr Chytła605aa332015-12-01 10:03:54 -05004244 install_element (RMAP_NODE, &match_tag_cmd);
4245 install_element (RMAP_NODE, &no_match_tag_cmd);
4246 install_element (RMAP_NODE, &no_match_tag_val_cmd);
paul718e3742002-12-13 20:15:29 +00004247
4248 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00004249 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00004250 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
4251 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
4252 install_element (RMAP_NODE, &set_local_pref_cmd);
4253 install_element (RMAP_NODE, &no_set_local_pref_cmd);
4254 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
4255 install_element (RMAP_NODE, &set_weight_cmd);
4256 install_element (RMAP_NODE, &no_set_weight_cmd);
4257 install_element (RMAP_NODE, &no_set_weight_val_cmd);
4258 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00004259 install_element (RMAP_NODE, &set_metric_addsub_cmd);
Timo Teräsef757702015-04-29 09:43:04 +03004260 install_element (RMAP_NODE, &set_metric_rtt_cmd);
paul718e3742002-12-13 20:15:29 +00004261 install_element (RMAP_NODE, &no_set_metric_cmd);
4262 install_element (RMAP_NODE, &no_set_metric_val_cmd);
4263 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Timo Teräs85c854a2014-09-30 11:31:53 +03004264 install_element (RMAP_NODE, &set_aspath_prepend_lastas_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00004265 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00004266 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
4267 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00004268 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
4269 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00004270 install_element (RMAP_NODE, &set_origin_cmd);
4271 install_element (RMAP_NODE, &no_set_origin_cmd);
4272 install_element (RMAP_NODE, &no_set_origin_val_cmd);
4273 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
4274 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
4275 install_element (RMAP_NODE, &set_aggregator_as_cmd);
4276 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
4277 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
4278 install_element (RMAP_NODE, &set_community_cmd);
4279 install_element (RMAP_NODE, &set_community_none_cmd);
4280 install_element (RMAP_NODE, &no_set_community_cmd);
4281 install_element (RMAP_NODE, &no_set_community_val_cmd);
4282 install_element (RMAP_NODE, &no_set_community_none_cmd);
4283 install_element (RMAP_NODE, &set_community_delete_cmd);
4284 install_element (RMAP_NODE, &no_set_community_delete_cmd);
4285 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
4286 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
4287 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
4288 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
4289 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
4290 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
4291 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
4292 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
4293 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
4294 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
4295 install_element (RMAP_NODE, &set_originator_id_cmd);
4296 install_element (RMAP_NODE, &no_set_originator_id_cmd);
4297 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
Piotr Chytła605aa332015-12-01 10:03:54 -05004298 install_element (RMAP_NODE, &set_tag_cmd);
4299 install_element (RMAP_NODE, &no_set_tag_cmd);
4300 install_element (RMAP_NODE, &no_set_tag_val_cmd);
paul718e3742002-12-13 20:15:29 +00004301
paul718e3742002-12-13 20:15:29 +00004302 route_map_install_match (&route_match_ipv6_address_cmd);
4303 route_map_install_match (&route_match_ipv6_next_hop_cmd);
4304 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
4305 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
4306 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Dinesh G Duttad5233a2014-09-30 14:19:57 -07004307 route_map_install_set (&route_set_ipv6_nexthop_peer_cmd);
4308
paul718e3742002-12-13 20:15:29 +00004309 install_element (RMAP_NODE, &match_ipv6_address_cmd);
4310 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
4311 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
4312 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
4313 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
4314 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
4315 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
4316 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
4317 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
4318 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
4319 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
4320 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
Dinesh G Duttad5233a2014-09-30 14:19:57 -07004321 install_element (RMAP_NODE, &set_ipv6_nexthop_peer_cmd);
4322 install_element (RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd);
Paul Jakma41367172007-08-06 15:24:51 +00004323
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004324 /* AS-Pathlimit: functionality removed, commands kept for
4325 * compatibility.
4326 */
Paul Jakma41367172007-08-06 15:24:51 +00004327 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
4328 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
4329 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
4330 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
4331 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
4332 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00004333}