blob: ccd73b6c5c38a7452737ee32aa00747c476b4fe5 [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"
Job Snijders3334bab2017-01-20 14:47:12 +000054#include "bgpd/bgp_lcommunity.h"
Paul Jakma320da872008-07-02 13:40:33 +000055#include "bgpd/bgp_vty.h"
paul718e3742002-12-13 20:15:29 +000056
57/* Memo of route-map commands.
58
59o Cisco route-map
60
61 match as-path : Done
62 community : Done
Job Snijders3334bab2017-01-20 14:47:12 +000063 lcommunity : Done
paul718e3742002-12-13 20:15:29 +000064 interface : Not yet
65 ip address : Done
66 ip next-hop : Done
hassoc1643bb2005-02-02 16:43:17 +000067 ip route-source : Done
paul718e3742002-12-13 20:15:29 +000068 ip prefix-list : Done
69 ipv6 address : Done
70 ipv6 next-hop : Done
71 ipv6 route-source: (This will not be implemented by bgpd)
72 ipv6 prefix-list : Done
73 length : (This will not be implemented by bgpd)
74 metric : Done
75 route-type : (This will not be implemented by bgpd)
Piotr Chytła605aa332015-12-01 10:03:54 -050076 tag : Done
Dinesh Dutt5cf768a2015-11-09 20:21:53 -050077 local-preference : Done
paul718e3742002-12-13 20:15:29 +000078
79 set as-path prepend : Done
80 as-path tag : Not yet
81 automatic-tag : (This will not be implemented by bgpd)
82 community : Done
Job Snijders3334bab2017-01-20 14:47:12 +000083 large-community : Done
84 large-comm-list : Done
paul718e3742002-12-13 20:15:29 +000085 comm-list : Not yet
86 dampning : Not yet
87 default : (This will not be implemented by bgpd)
88 interface : (This will not be implemented by bgpd)
89 ip default : (This will not be implemented by bgpd)
90 ip next-hop : Done
91 ip precedence : (This will not be implemented by bgpd)
92 ip tos : (This will not be implemented by bgpd)
93 level : (This will not be implemented by bgpd)
94 local-preference : Done
95 metric : Done
96 metric-type : Not yet
97 origin : Done
Piotr Chytła605aa332015-12-01 10:03:54 -050098 tag : Done
paul718e3742002-12-13 20:15:29 +000099 weight : Done
100
Timo Teräs2aa640b2014-05-20 08:57:26 +0300101o Local extensions
paul718e3742002-12-13 20:15:29 +0000102
103 set ipv6 next-hop global: Done
104 set ipv6 next-hop local : Done
Denis Ovsienko841f7a52008-04-10 11:47:45 +0000105 set as-path exclude : Done
paul718e3742002-12-13 20:15:29 +0000106
107*/
David Lamparter6b0655a2014-06-04 06:53:35 +0200108
Timo Teräs38f22ab2015-04-29 09:43:02 +0300109 /* generic value manipulation to be shared in multiple rules */
110
111#define RMAP_VALUE_SET 0
112#define RMAP_VALUE_ADD 1
113#define RMAP_VALUE_SUB 2
114
115struct rmap_value
116{
117 u_int8_t action;
Timo Teräsef757702015-04-29 09:43:04 +0300118 u_int8_t variable;
Timo Teräs38f22ab2015-04-29 09:43:02 +0300119 u_int32_t value;
120};
121
122static int
123route_value_match (struct rmap_value *rv, u_int32_t value)
124{
Timo Teräsef757702015-04-29 09:43:04 +0300125 if (rv->variable == 0 && value == rv->value)
Timo Teräs38f22ab2015-04-29 09:43:02 +0300126 return RMAP_MATCH;
127
128 return RMAP_NOMATCH;
129}
130
131static u_int32_t
Timo Teräsef757702015-04-29 09:43:04 +0300132route_value_adjust (struct rmap_value *rv, u_int32_t current, struct peer *peer)
Timo Teräs38f22ab2015-04-29 09:43:02 +0300133{
Timo Teräsef757702015-04-29 09:43:04 +0300134 u_int32_t value;
135
136 switch (rv->variable)
137 {
138 case 1:
139 value = peer->rtt;
140 break;
141 default:
142 value = rv->value;
143 break;
144 }
Timo Teräs38f22ab2015-04-29 09:43:02 +0300145
146 switch (rv->action)
147 {
148 case RMAP_VALUE_ADD:
149 if (current > UINT32_MAX-value)
150 return UINT32_MAX;
151 return current + value;
152 case RMAP_VALUE_SUB:
153 if (current <= value)
154 return 0;
155 return current - value;
156 default:
157 return value;
158 }
159}
160
161static void *
162route_value_compile (const char *arg)
163{
Timo Teräsef757702015-04-29 09:43:04 +0300164 u_int8_t action = RMAP_VALUE_SET, var = 0;
165 unsigned long larg = 0;
Timo Teräs38f22ab2015-04-29 09:43:02 +0300166 char *endptr = NULL;
167 struct rmap_value *rv;
168
169 if (arg[0] == '+')
170 {
171 action = RMAP_VALUE_ADD;
172 arg++;
173 }
174 else if (arg[0] == '-')
175 {
176 action = RMAP_VALUE_SUB;
177 arg++;
178 }
179
Timo Teräsef757702015-04-29 09:43:04 +0300180 if (all_digit(arg))
181 {
182 errno = 0;
183 larg = strtoul (arg, &endptr, 10);
184 if (*arg == 0 || *endptr != 0 || errno || larg > UINT32_MAX)
185 return NULL;
186 }
187 else
188 {
189 if (strcmp(arg, "rtt") == 0)
190 var = 1;
191 else
192 return NULL;
193 }
Timo Teräs38f22ab2015-04-29 09:43:02 +0300194
195 rv = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_value));
196 if (!rv)
197 return NULL;
198
199 rv->action = action;
Timo Teräsef757702015-04-29 09:43:04 +0300200 rv->variable = var;
Timo Teräs38f22ab2015-04-29 09:43:02 +0300201 rv->value = larg;
202 return rv;
203}
204
205static void
206route_value_free (void *rule)
207{
208 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
209}
210
Timo Teräsb304dcb2014-05-20 09:04:49 +0300211 /* generic as path object to be shared in multiple rules */
212
213static void *
214route_aspath_compile (const char *arg)
215{
216 struct aspath *aspath;
217
218 aspath = aspath_str2aspath (arg);
219 if (! aspath)
220 return NULL;
221 return aspath;
222}
223
224static void
225route_aspath_free (void *rule)
226{
227 struct aspath *aspath = rule;
228 aspath_free (aspath);
229}
230
paulfee0f4c2004-09-13 05:12:46 +0000231 /* 'match peer (A.B.C.D|X:X::X:X)' */
232
233/* Compares the peer specified in the 'match peer' clause with the peer
234 received in bgp_info->peer. If it is the same, or if the peer structure
235 received is a peer_group containing it, returns RMAP_MATCH. */
paul94f2b392005-06-28 12:44:16 +0000236static route_map_result_t
paulfee0f4c2004-09-13 05:12:46 +0000237route_match_peer (void *rule, struct prefix *prefix, route_map_object_t type,
238 void *object)
239{
240 union sockunion *su;
David Lamparter6ed810d2015-04-21 10:13:07 +0200241 union sockunion su_def = { .sin = { .sin_family = AF_INET,
242 .sin_addr.s_addr = INADDR_ANY } };
paulfee0f4c2004-09-13 05:12:46 +0000243 struct peer_group *group;
244 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +0000245 struct listnode *node, *nnode;
paulfee0f4c2004-09-13 05:12:46 +0000246
247 if (type == RMAP_BGP)
248 {
249 su = rule;
250 peer = ((struct bgp_info *) object)->peer;
251
252 if ( ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT) &&
253 ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_EXPORT) )
254 return RMAP_NOMATCH;
255
256 /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
257 REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200258 if (sockunion_same (su, &su_def))
paulfee0f4c2004-09-13 05:12:46 +0000259 {
paul22db9de2005-05-19 01:50:11 +0000260 int ret;
paulfee0f4c2004-09-13 05:12:46 +0000261 if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
262 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE) ||
263 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
paul22db9de2005-05-19 01:50:11 +0000264 ret = RMAP_MATCH;
paulfee0f4c2004-09-13 05:12:46 +0000265 else
paul22db9de2005-05-19 01:50:11 +0000266 ret = RMAP_NOMATCH;
paul22db9de2005-05-19 01:50:11 +0000267 return ret;
paulfee0f4c2004-09-13 05:12:46 +0000268 }
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200269
paulfee0f4c2004-09-13 05:12:46 +0000270 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
271 {
272 if (sockunion_same (su, &peer->su))
273 return RMAP_MATCH;
274
275 return RMAP_NOMATCH;
276 }
277 else
278 {
279 group = peer->group;
paul1eb8ef22005-04-07 07:30:20 +0000280 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
paulfee0f4c2004-09-13 05:12:46 +0000281 {
282 if (sockunion_same (su, &peer->su))
283 return RMAP_MATCH;
paulfee0f4c2004-09-13 05:12:46 +0000284 }
Paul Jakma30a22312008-08-15 14:05:22 +0100285 return RMAP_NOMATCH;
paulfee0f4c2004-09-13 05:12:46 +0000286 }
287 }
288 return RMAP_NOMATCH;
289}
290
paul94f2b392005-06-28 12:44:16 +0000291static void *
paulfd79ac92004-10-13 05:06:08 +0000292route_match_peer_compile (const char *arg)
paulfee0f4c2004-09-13 05:12:46 +0000293{
294 union sockunion *su;
295 int ret;
296
297 su = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union sockunion));
298
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +0200299 ret = str2sockunion (strcmp(arg, "local") ? arg : "0.0.0.0", su);
paulfee0f4c2004-09-13 05:12:46 +0000300 if (ret < 0) {
301 XFREE (MTYPE_ROUTE_MAP_COMPILED, su);
302 return NULL;
303 }
304
305 return su;
306}
307
308/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000309static void
paulfee0f4c2004-09-13 05:12:46 +0000310route_match_peer_free (void *rule)
311{
312 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
313}
314
315/* Route map commands for ip address matching. */
316struct route_map_rule_cmd route_match_peer_cmd =
317{
318 "peer",
319 route_match_peer,
320 route_match_peer_compile,
321 route_match_peer_free
322};
323
paul718e3742002-12-13 20:15:29 +0000324/* `match ip address IP_ACCESS_LIST' */
325
326/* Match function should return 1 if match is success else return
327 zero. */
paul94f2b392005-06-28 12:44:16 +0000328static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000329route_match_ip_address (void *rule, struct prefix *prefix,
330 route_map_object_t type, void *object)
331{
332 struct access_list *alist;
333 /* struct prefix_ipv4 match; */
334
335 if (type == RMAP_BGP)
336 {
337 alist = access_list_lookup (AFI_IP, (char *) rule);
338 if (alist == NULL)
339 return RMAP_NOMATCH;
340
341 return (access_list_apply (alist, prefix) == FILTER_DENY ?
342 RMAP_NOMATCH : RMAP_MATCH);
343 }
344 return RMAP_NOMATCH;
345}
346
347/* Route map `ip address' match statement. `arg' should be
348 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000349static void *
paulfd79ac92004-10-13 05:06:08 +0000350route_match_ip_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000351{
352 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
353}
354
355/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000356static void
paul718e3742002-12-13 20:15:29 +0000357route_match_ip_address_free (void *rule)
358{
359 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
360}
361
362/* Route map commands for ip address matching. */
363struct route_map_rule_cmd route_match_ip_address_cmd =
364{
365 "ip address",
366 route_match_ip_address,
367 route_match_ip_address_compile,
368 route_match_ip_address_free
369};
David Lamparter6b0655a2014-06-04 06:53:35 +0200370
paul718e3742002-12-13 20:15:29 +0000371/* `match ip next-hop IP_ADDRESS' */
372
373/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000374static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000375route_match_ip_next_hop (void *rule, struct prefix *prefix,
376 route_map_object_t type, void *object)
377{
378 struct access_list *alist;
379 struct bgp_info *bgp_info;
380 struct prefix_ipv4 p;
381
382 if (type == RMAP_BGP)
383 {
384 bgp_info = object;
385 p.family = AF_INET;
386 p.prefix = bgp_info->attr->nexthop;
387 p.prefixlen = IPV4_MAX_BITLEN;
388
389 alist = access_list_lookup (AFI_IP, (char *) rule);
390 if (alist == NULL)
391 return RMAP_NOMATCH;
392
393 return (access_list_apply (alist, &p) == FILTER_DENY ?
394 RMAP_NOMATCH : RMAP_MATCH);
395 }
396 return RMAP_NOMATCH;
397}
398
399/* Route map `ip next-hop' match statement. `arg' is
400 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000401static void *
paulfd79ac92004-10-13 05:06:08 +0000402route_match_ip_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000403{
404 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
405}
406
407/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000408static void
paul718e3742002-12-13 20:15:29 +0000409route_match_ip_next_hop_free (void *rule)
410{
411 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
412}
413
414/* Route map commands for ip next-hop matching. */
415struct route_map_rule_cmd route_match_ip_next_hop_cmd =
416{
417 "ip next-hop",
418 route_match_ip_next_hop,
419 route_match_ip_next_hop_compile,
420 route_match_ip_next_hop_free
421};
David Lamparter6b0655a2014-06-04 06:53:35 +0200422
hassoc1643bb2005-02-02 16:43:17 +0000423/* `match ip route-source ACCESS-LIST' */
424
425/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000426static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000427route_match_ip_route_source (void *rule, struct prefix *prefix,
428 route_map_object_t type, void *object)
429{
430 struct access_list *alist;
431 struct bgp_info *bgp_info;
432 struct peer *peer;
433 struct prefix_ipv4 p;
434
435 if (type == RMAP_BGP)
436 {
437 bgp_info = object;
438 peer = bgp_info->peer;
439
440 if (! peer || sockunion_family (&peer->su) != AF_INET)
441 return RMAP_NOMATCH;
442
443 p.family = AF_INET;
444 p.prefix = peer->su.sin.sin_addr;
445 p.prefixlen = IPV4_MAX_BITLEN;
446
447 alist = access_list_lookup (AFI_IP, (char *) rule);
448 if (alist == NULL)
449 return RMAP_NOMATCH;
450
451 return (access_list_apply (alist, &p) == FILTER_DENY ?
452 RMAP_NOMATCH : RMAP_MATCH);
453 }
454 return RMAP_NOMATCH;
455}
456
457/* Route map `ip route-source' match statement. `arg' is
458 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000459static void *
hassoc1643bb2005-02-02 16:43:17 +0000460route_match_ip_route_source_compile (const char *arg)
461{
462 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
463}
464
465/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000466static void
hassoc1643bb2005-02-02 16:43:17 +0000467route_match_ip_route_source_free (void *rule)
468{
469 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
470}
471
472/* Route map commands for ip route-source matching. */
473struct route_map_rule_cmd route_match_ip_route_source_cmd =
474{
475 "ip route-source",
476 route_match_ip_route_source,
477 route_match_ip_route_source_compile,
478 route_match_ip_route_source_free
479};
David Lamparter6b0655a2014-06-04 06:53:35 +0200480
paul718e3742002-12-13 20:15:29 +0000481/* `match ip address prefix-list PREFIX_LIST' */
482
paul94f2b392005-06-28 12:44:16 +0000483static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000484route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
485 route_map_object_t type, void *object)
486{
487 struct prefix_list *plist;
488
489 if (type == RMAP_BGP)
490 {
491 plist = prefix_list_lookup (AFI_IP, (char *) rule);
492 if (plist == NULL)
493 return RMAP_NOMATCH;
494
495 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
496 RMAP_NOMATCH : RMAP_MATCH);
497 }
498 return RMAP_NOMATCH;
499}
500
paul94f2b392005-06-28 12:44:16 +0000501static void *
paulfd79ac92004-10-13 05:06:08 +0000502route_match_ip_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000503{
504 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
505}
506
paul94f2b392005-06-28 12:44:16 +0000507static void
paul718e3742002-12-13 20:15:29 +0000508route_match_ip_address_prefix_list_free (void *rule)
509{
510 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
511}
512
513struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
514{
515 "ip address prefix-list",
516 route_match_ip_address_prefix_list,
517 route_match_ip_address_prefix_list_compile,
518 route_match_ip_address_prefix_list_free
519};
David Lamparter6b0655a2014-06-04 06:53:35 +0200520
paul718e3742002-12-13 20:15:29 +0000521/* `match ip next-hop prefix-list PREFIX_LIST' */
522
paul94f2b392005-06-28 12:44:16 +0000523static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000524route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
525 route_map_object_t type, void *object)
526{
527 struct prefix_list *plist;
528 struct bgp_info *bgp_info;
529 struct prefix_ipv4 p;
530
531 if (type == RMAP_BGP)
532 {
533 bgp_info = object;
534 p.family = AF_INET;
535 p.prefix = bgp_info->attr->nexthop;
536 p.prefixlen = IPV4_MAX_BITLEN;
537
538 plist = prefix_list_lookup (AFI_IP, (char *) rule);
539 if (plist == NULL)
540 return RMAP_NOMATCH;
541
542 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
543 RMAP_NOMATCH : RMAP_MATCH);
544 }
545 return RMAP_NOMATCH;
546}
547
paul94f2b392005-06-28 12:44:16 +0000548static void *
paulfd79ac92004-10-13 05:06:08 +0000549route_match_ip_next_hop_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000550{
551 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
552}
553
paul94f2b392005-06-28 12:44:16 +0000554static void
paul718e3742002-12-13 20:15:29 +0000555route_match_ip_next_hop_prefix_list_free (void *rule)
556{
557 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
558}
559
560struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
561{
562 "ip next-hop prefix-list",
563 route_match_ip_next_hop_prefix_list,
564 route_match_ip_next_hop_prefix_list_compile,
565 route_match_ip_next_hop_prefix_list_free
566};
David Lamparter6b0655a2014-06-04 06:53:35 +0200567
hassoc1643bb2005-02-02 16:43:17 +0000568/* `match ip route-source prefix-list PREFIX_LIST' */
569
paul94f2b392005-06-28 12:44:16 +0000570static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000571route_match_ip_route_source_prefix_list (void *rule, struct prefix *prefix,
572 route_map_object_t type, void *object)
573{
574 struct prefix_list *plist;
575 struct bgp_info *bgp_info;
576 struct peer *peer;
577 struct prefix_ipv4 p;
578
579 if (type == RMAP_BGP)
580 {
581 bgp_info = object;
582 peer = bgp_info->peer;
583
584 if (! peer || sockunion_family (&peer->su) != AF_INET)
585 return RMAP_NOMATCH;
586
587 p.family = AF_INET;
588 p.prefix = peer->su.sin.sin_addr;
589 p.prefixlen = IPV4_MAX_BITLEN;
590
591 plist = prefix_list_lookup (AFI_IP, (char *) rule);
592 if (plist == NULL)
593 return RMAP_NOMATCH;
594
595 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
596 RMAP_NOMATCH : RMAP_MATCH);
597 }
598 return RMAP_NOMATCH;
599}
600
paul94f2b392005-06-28 12:44:16 +0000601static void *
hassoc1643bb2005-02-02 16:43:17 +0000602route_match_ip_route_source_prefix_list_compile (const char *arg)
603{
604 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
605}
606
paul94f2b392005-06-28 12:44:16 +0000607static void
hassoc1643bb2005-02-02 16:43:17 +0000608route_match_ip_route_source_prefix_list_free (void *rule)
609{
610 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
611}
612
613struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd =
614{
615 "ip route-source prefix-list",
616 route_match_ip_route_source_prefix_list,
617 route_match_ip_route_source_prefix_list_compile,
618 route_match_ip_route_source_prefix_list_free
619};
David Lamparter6b0655a2014-06-04 06:53:35 +0200620
Dinesh Dutt5cf768a2015-11-09 20:21:53 -0500621/* `match local-preference LOCAL-PREF' */
622
623/* Match function return 1 if match is success else return zero. */
624static route_map_result_t
625route_match_local_pref (void *rule, struct prefix *prefix,
626 route_map_object_t type, void *object)
627{
628 u_int32_t *local_pref;
629 struct bgp_info *bgp_info;
630
631 if (type == RMAP_BGP)
632 {
633 local_pref = rule;
634 bgp_info = object;
635
636 if (bgp_info->attr->local_pref == *local_pref)
637 return RMAP_MATCH;
638 else
639 return RMAP_NOMATCH;
640 }
641 return RMAP_NOMATCH;
642}
643
644/* Route map `match local-preference' match statement.
645 `arg' is local-pref value */
646static void *
647route_match_local_pref_compile (const char *arg)
648{
649 u_int32_t *local_pref;
650 char *endptr = NULL;
651 unsigned long tmpval;
652
653 /* Locpref value shoud be integer. */
654 if (! all_digit (arg))
655 return NULL;
656
657 errno = 0;
658 tmpval = strtoul (arg, &endptr, 10);
659 if (*endptr != '\0' || errno || tmpval > UINT32_MAX)
660 return NULL;
661
662 local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
663
664 if (!local_pref)
665 return local_pref;
666
667 *local_pref = tmpval;
668 return local_pref;
669}
670
671/* Free route map's compiled `match local-preference' value. */
672static void
673route_match_local_pref_free (void *rule)
674{
675 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
676}
677
678/* Route map commands for metric matching. */
679struct route_map_rule_cmd route_match_local_pref_cmd =
680{
681 "local-preference",
682 route_match_local_pref,
683 route_match_local_pref_compile,
684 route_match_local_pref_free
685};
686
paul718e3742002-12-13 20:15:29 +0000687/* `match metric METRIC' */
688
689/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000690static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000691route_match_metric (void *rule, struct prefix *prefix,
692 route_map_object_t type, void *object)
693{
Timo Teräs38f22ab2015-04-29 09:43:02 +0300694 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +0000695 struct bgp_info *bgp_info;
696
697 if (type == RMAP_BGP)
698 {
Timo Teräs38f22ab2015-04-29 09:43:02 +0300699 rv = rule;
paul718e3742002-12-13 20:15:29 +0000700 bgp_info = object;
Timo Teräs38f22ab2015-04-29 09:43:02 +0300701 return route_value_match(rv, bgp_info->attr->med);
paul718e3742002-12-13 20:15:29 +0000702 }
703 return RMAP_NOMATCH;
704}
705
paul718e3742002-12-13 20:15:29 +0000706/* Route map commands for metric matching. */
707struct route_map_rule_cmd route_match_metric_cmd =
708{
709 "metric",
710 route_match_metric,
Timo Teräs38f22ab2015-04-29 09:43:02 +0300711 route_value_compile,
712 route_value_free,
paul718e3742002-12-13 20:15:29 +0000713};
David Lamparter6b0655a2014-06-04 06:53:35 +0200714
paul718e3742002-12-13 20:15:29 +0000715/* `match as-path ASPATH' */
716
717/* Match function for as-path match. I assume given object is */
paul94f2b392005-06-28 12:44:16 +0000718static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000719route_match_aspath (void *rule, struct prefix *prefix,
720 route_map_object_t type, void *object)
721{
722
723 struct as_list *as_list;
724 struct bgp_info *bgp_info;
725
726 if (type == RMAP_BGP)
727 {
728 as_list = as_list_lookup ((char *) rule);
729 if (as_list == NULL)
730 return RMAP_NOMATCH;
731
732 bgp_info = object;
733
734 /* Perform match. */
735 return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
736 }
737 return RMAP_NOMATCH;
738}
739
740/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000741static void *
paulfd79ac92004-10-13 05:06:08 +0000742route_match_aspath_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000743{
744 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
745}
746
747/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000748static void
paul718e3742002-12-13 20:15:29 +0000749route_match_aspath_free (void *rule)
750{
751 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
752}
753
754/* Route map commands for aspath matching. */
755struct route_map_rule_cmd route_match_aspath_cmd =
756{
757 "as-path",
758 route_match_aspath,
759 route_match_aspath_compile,
760 route_match_aspath_free
761};
David Lamparter6b0655a2014-06-04 06:53:35 +0200762
paul718e3742002-12-13 20:15:29 +0000763/* `match community COMMUNIY' */
764struct rmap_community
765{
766 char *name;
767 int exact;
768};
769
770/* Match function for community match. */
paul94f2b392005-06-28 12:44:16 +0000771static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000772route_match_community (void *rule, struct prefix *prefix,
773 route_map_object_t type, void *object)
774{
775 struct community_list *list;
776 struct bgp_info *bgp_info;
777 struct rmap_community *rcom;
778
779 if (type == RMAP_BGP)
780 {
781 bgp_info = object;
782 rcom = rule;
783
hassofee6e4e2005-02-02 16:29:31 +0000784 list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +0000785 if (! list)
786 return RMAP_NOMATCH;
787
788 if (rcom->exact)
789 {
790 if (community_list_exact_match (bgp_info->attr->community, list))
791 return RMAP_MATCH;
792 }
793 else
794 {
795 if (community_list_match (bgp_info->attr->community, list))
796 return RMAP_MATCH;
797 }
798 }
799 return RMAP_NOMATCH;
800}
801
802/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000803static void *
paulfd79ac92004-10-13 05:06:08 +0000804route_match_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000805{
806 struct rmap_community *rcom;
807 int len;
808 char *p;
809
810 rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
811
812 p = strchr (arg, ' ');
813 if (p)
814 {
815 len = p - arg;
816 rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
817 memcpy (rcom->name, arg, len);
818 rcom->exact = 1;
819 }
820 else
821 {
822 rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
823 rcom->exact = 0;
824 }
825 return rcom;
826}
827
828/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000829static void
paul718e3742002-12-13 20:15:29 +0000830route_match_community_free (void *rule)
831{
832 struct rmap_community *rcom = rule;
833
834 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
835 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
836}
837
838/* Route map commands for community matching. */
839struct route_map_rule_cmd route_match_community_cmd =
840{
841 "community",
842 route_match_community,
843 route_match_community_compile,
844 route_match_community_free
845};
David Lamparter6b0655a2014-06-04 06:53:35 +0200846
Job Snijders3334bab2017-01-20 14:47:12 +0000847/* Match function for lcommunity match. */
848static route_map_result_t
849route_match_lcommunity (void *rule, struct prefix *prefix,
850 route_map_object_t type, void *object)
851{
852 struct community_list *list;
853 struct bgp_info *bgp_info;
854 struct rmap_community *rcom;
855
856 if (type == RMAP_BGP)
857 {
858 bgp_info = object;
859 rcom = rule;
860
861 list = community_list_lookup (bgp_clist, rcom->name,
862 LARGE_COMMUNITY_LIST_MASTER);
863 if (! list)
864 return RMAP_NOMATCH;
865
866 if (bgp_info->attr->extra &&
867 lcommunity_list_match (bgp_info->attr->extra->lcommunity, list))
868 return RMAP_MATCH;
869
870 }
871 return RMAP_NOMATCH;
872}
873
874/* Compile function for community match. */
875static void *
876route_match_lcommunity_compile (const char *arg)
877{
878 struct rmap_community *rcom;
879 int len;
880 char *p;
881
882 rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
883
884 p = strchr (arg, ' ');
885 if (p)
886 {
887 len = p - arg;
888 rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
889 memcpy (rcom->name, arg, len);
890 }
891 else
892 {
893 rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
894 rcom->exact = 0;
895 }
896 return rcom;
897}
898
899/* Compile function for community match. */
900static void
901route_match_lcommunity_free (void *rule)
902{
903 struct rmap_community *rcom = rule;
904
905 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
906 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
907}
908
909/* Route map commands for community matching. */
910struct route_map_rule_cmd route_match_lcommunity_cmd =
911{
912 "large-community",
913 route_match_lcommunity,
914 route_match_lcommunity_compile,
915 route_match_lcommunity_free
916};
917
918
paul73ffb252003-04-19 15:49:49 +0000919/* Match function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000920static route_map_result_t
Job Snijders3334bab2017-01-20 14:47:12 +0000921route_match_ecommunity (void *rule, struct prefix *prefix,
paul73ffb252003-04-19 15:49:49 +0000922 route_map_object_t type, void *object)
923{
924 struct community_list *list;
925 struct bgp_info *bgp_info;
926
Job Snijders3334bab2017-01-20 14:47:12 +0000927 if (type == RMAP_BGP)
paul73ffb252003-04-19 15:49:49 +0000928 {
929 bgp_info = object;
Job Snijders3334bab2017-01-20 14:47:12 +0000930
Paul Jakmafb982c22007-05-04 20:15:47 +0000931 if (!bgp_info->attr->extra)
932 return RMAP_NOMATCH;
Job Snijders3334bab2017-01-20 14:47:12 +0000933
paul73ffb252003-04-19 15:49:49 +0000934 list = community_list_lookup (bgp_clist, (char *) rule,
hassofee6e4e2005-02-02 16:29:31 +0000935 EXTCOMMUNITY_LIST_MASTER);
paul73ffb252003-04-19 15:49:49 +0000936 if (! list)
937 return RMAP_NOMATCH;
938
Paul Jakmafb982c22007-05-04 20:15:47 +0000939 if (ecommunity_list_match (bgp_info->attr->extra->ecommunity, list))
paul73ffb252003-04-19 15:49:49 +0000940 return RMAP_MATCH;
941 }
942 return RMAP_NOMATCH;
943}
944
945/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000946static void *
paulfd79ac92004-10-13 05:06:08 +0000947route_match_ecommunity_compile (const char *arg)
paul73ffb252003-04-19 15:49:49 +0000948{
949 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
950}
951
952/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000953static void
paul73ffb252003-04-19 15:49:49 +0000954route_match_ecommunity_free (void *rule)
955{
956 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
957}
958
959/* Route map commands for community matching. */
960struct route_map_rule_cmd route_match_ecommunity_cmd =
961{
962 "extcommunity",
963 route_match_ecommunity,
964 route_match_ecommunity_compile,
965 route_match_ecommunity_free
966};
David Lamparter6b0655a2014-06-04 06:53:35 +0200967
paul718e3742002-12-13 20:15:29 +0000968/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
969 and `address-family vpnv4'. */
David Lamparter6b0655a2014-06-04 06:53:35 +0200970
paul718e3742002-12-13 20:15:29 +0000971/* `match origin' */
paul94f2b392005-06-28 12:44:16 +0000972static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000973route_match_origin (void *rule, struct prefix *prefix,
974 route_map_object_t type, void *object)
975{
976 u_char *origin;
977 struct bgp_info *bgp_info;
978
979 if (type == RMAP_BGP)
980 {
981 origin = rule;
982 bgp_info = object;
983
984 if (bgp_info->attr->origin == *origin)
985 return RMAP_MATCH;
986 }
987
988 return RMAP_NOMATCH;
989}
990
paul94f2b392005-06-28 12:44:16 +0000991static void *
paulfd79ac92004-10-13 05:06:08 +0000992route_match_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000993{
994 u_char *origin;
995
996 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
997
998 if (strcmp (arg, "igp") == 0)
999 *origin = 0;
1000 else if (strcmp (arg, "egp") == 0)
1001 *origin = 1;
1002 else
1003 *origin = 2;
1004
1005 return origin;
1006}
1007
1008/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +00001009static void
paul718e3742002-12-13 20:15:29 +00001010route_match_origin_free (void *rule)
1011{
1012 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1013}
1014
1015/* Route map commands for origin matching. */
1016struct route_map_rule_cmd route_match_origin_cmd =
1017{
1018 "origin",
1019 route_match_origin,
1020 route_match_origin_compile,
1021 route_match_origin_free
1022};
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04001023
1024/* match probability { */
1025
1026static route_map_result_t
1027route_match_probability (void *rule, struct prefix *prefix,
1028 route_map_object_t type, void *object)
1029{
Donald Sharpf31bab42015-06-19 19:26:19 -04001030 long r = random();
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04001031
David Lamparter8c9cd852015-04-19 14:40:02 +02001032 switch (*(long *) rule)
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04001033 {
1034 case 0: break;
1035 case RAND_MAX: return RMAP_MATCH;
1036 default:
David Lamparter8c9cd852015-04-19 14:40:02 +02001037 if (r < *(long *) rule)
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04001038 {
1039 return RMAP_MATCH;
1040 }
1041 }
1042
1043 return RMAP_NOMATCH;
1044}
1045
1046static void *
1047route_match_probability_compile (const char *arg)
1048{
David Lamparter8c9cd852015-04-19 14:40:02 +02001049 long *lobule;
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04001050 unsigned perc;
1051
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04001052 perc = atoi (arg);
David Lamparter8c9cd852015-04-19 14:40:02 +02001053 lobule = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (long));
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04001054
1055 switch (perc)
1056 {
1057 case 0: *lobule = 0; break;
1058 case 100: *lobule = RAND_MAX; break;
1059 default: *lobule = RAND_MAX / 100 * perc;
1060 }
1061
1062 return lobule;
1063}
1064
1065static void
1066route_match_probability_free (void *rule)
1067{
1068 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1069}
1070
1071struct route_map_rule_cmd route_match_probability_cmd =
1072{
1073 "probability",
1074 route_match_probability,
1075 route_match_probability_compile,
1076 route_match_probability_free
1077};
1078
1079/* } */
1080
paul718e3742002-12-13 20:15:29 +00001081/* `set ip next-hop IP_ADDRESS' */
1082
Piotr Chytła605aa332015-12-01 10:03:54 -05001083/* Match function return 1 if match is success else return zero. */
1084static route_map_result_t
1085route_match_tag (void *rule, struct prefix *prefix,
1086 route_map_object_t type, void *object)
1087{
Paul Jakma96d10602016-07-01 14:23:45 +01001088 route_tag_t *tag;
Piotr Chytła605aa332015-12-01 10:03:54 -05001089 struct bgp_info *bgp_info;
1090
1091 if (type == RMAP_BGP)
1092 {
1093 tag = rule;
1094 bgp_info = object;
1095
1096 if (!bgp_info->attr->extra)
1097 return RMAP_NOMATCH;
1098
1099 return ((bgp_info->attr->extra->tag == *tag)? RMAP_MATCH : RMAP_NOMATCH);
1100 }
1101
1102 return RMAP_NOMATCH;
1103}
1104
Piotr Chytła605aa332015-12-01 10:03:54 -05001105/* Route map commands for tag matching. */
Christian Frankeddc160c2016-10-01 20:42:34 +02001106static struct route_map_rule_cmd route_match_tag_cmd =
Piotr Chytła605aa332015-12-01 10:03:54 -05001107{
1108 "tag",
1109 route_match_tag,
Christian Frankeddc160c2016-10-01 20:42:34 +02001110 route_map_rule_tag_compile,
1111 route_map_rule_tag_free,
Piotr Chytła605aa332015-12-01 10:03:54 -05001112};
1113
1114
paul718e3742002-12-13 20:15:29 +00001115/* Set nexthop to object. ojbect must be pointer to struct attr. */
paulac41b2a2003-08-12 05:32:27 +00001116struct rmap_ip_nexthop_set
1117{
1118 struct in_addr *address;
1119 int peer_address;
1120};
1121
paul94f2b392005-06-28 12:44:16 +00001122static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001123route_set_ip_nexthop (void *rule, struct prefix *prefix,
1124 route_map_object_t type, void *object)
1125{
paulac41b2a2003-08-12 05:32:27 +00001126 struct rmap_ip_nexthop_set *rins = rule;
paul718e3742002-12-13 20:15:29 +00001127 struct bgp_info *bgp_info;
paulac41b2a2003-08-12 05:32:27 +00001128 struct peer *peer;
paul718e3742002-12-13 20:15:29 +00001129
1130 if (type == RMAP_BGP)
1131 {
paul718e3742002-12-13 20:15:29 +00001132 bgp_info = object;
paulac41b2a2003-08-12 05:32:27 +00001133 peer = bgp_info->peer;
1134
1135 if (rins->peer_address)
1136 {
paulfee0f4c2004-09-13 05:12:46 +00001137 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
1138 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
paulac41b2a2003-08-12 05:32:27 +00001139 && peer->su_remote
1140 && sockunion_family (peer->su_remote) == AF_INET)
1141 {
Jorge Boncompte [DTI2]0c5ed3e2012-04-10 16:57:22 +02001142 bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote);
paulac41b2a2003-08-12 05:32:27 +00001143 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
1144 }
1145 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
1146 && peer->su_local
1147 && sockunion_family (peer->su_local) == AF_INET)
1148 {
Jorge Boncompte [DTI2]0c5ed3e2012-04-10 16:57:22 +02001149 bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_local);
paulac41b2a2003-08-12 05:32:27 +00001150 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
1151 }
1152 }
1153 else
1154 {
1155 /* Set next hop value. */
1156 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
1157 bgp_info->attr->nexthop = *rins->address;
1158 }
paul718e3742002-12-13 20:15:29 +00001159 }
1160
1161 return RMAP_OKAY;
1162}
1163
1164/* Route map `ip nexthop' compile function. Given string is converted
1165 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001166static void *
paulfd79ac92004-10-13 05:06:08 +00001167route_set_ip_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001168{
paulac41b2a2003-08-12 05:32:27 +00001169 struct rmap_ip_nexthop_set *rins;
1170 struct in_addr *address = NULL;
1171 int peer_address = 0;
paul718e3742002-12-13 20:15:29 +00001172 int ret;
paul718e3742002-12-13 20:15:29 +00001173
paulac41b2a2003-08-12 05:32:27 +00001174 if (strcmp (arg, "peer-address") == 0)
1175 peer_address = 1;
1176 else
paul718e3742002-12-13 20:15:29 +00001177 {
paulac41b2a2003-08-12 05:32:27 +00001178 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
1179 ret = inet_aton (arg, address);
1180
1181 if (ret == 0)
1182 {
1183 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1184 return NULL;
1185 }
paul718e3742002-12-13 20:15:29 +00001186 }
1187
Stephen Hemminger393deb92008-08-18 14:13:29 -07001188 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
paulac41b2a2003-08-12 05:32:27 +00001189
1190 rins->address = address;
1191 rins->peer_address = peer_address;
1192
1193 return rins;
paul718e3742002-12-13 20:15:29 +00001194}
1195
1196/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00001197static void
paul718e3742002-12-13 20:15:29 +00001198route_set_ip_nexthop_free (void *rule)
1199{
paulac41b2a2003-08-12 05:32:27 +00001200 struct rmap_ip_nexthop_set *rins = rule;
1201
1202 if (rins->address)
1203 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
1204
1205 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +00001206}
1207
1208/* Route map commands for ip nexthop set. */
1209struct route_map_rule_cmd route_set_ip_nexthop_cmd =
1210{
1211 "ip next-hop",
1212 route_set_ip_nexthop,
1213 route_set_ip_nexthop_compile,
1214 route_set_ip_nexthop_free
1215};
David Lamparter6b0655a2014-06-04 06:53:35 +02001216
paul718e3742002-12-13 20:15:29 +00001217/* `set local-preference LOCAL_PREF' */
1218
1219/* Set local preference. */
paul94f2b392005-06-28 12:44:16 +00001220static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001221route_set_local_pref (void *rule, struct prefix *prefix,
1222 route_map_object_t type, void *object)
1223{
Timo Teräs38f22ab2015-04-29 09:43:02 +03001224 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +00001225 struct bgp_info *bgp_info;
Timo Teräs38f22ab2015-04-29 09:43:02 +03001226 u_int32_t locpref = 0;
paul718e3742002-12-13 20:15:29 +00001227
1228 if (type == RMAP_BGP)
1229 {
1230 /* Fetch routemap's rule information. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001231 rv = rule;
paul718e3742002-12-13 20:15:29 +00001232 bgp_info = object;
1233
1234 /* Set local preference value. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001235 if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
1236 locpref = bgp_info->attr->local_pref;
1237
paul718e3742002-12-13 20:15:29 +00001238 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
Timo Teräsef757702015-04-29 09:43:04 +03001239 bgp_info->attr->local_pref = route_value_adjust(rv, locpref, bgp_info->peer);
paul718e3742002-12-13 20:15:29 +00001240 }
1241
1242 return RMAP_OKAY;
1243}
1244
paul718e3742002-12-13 20:15:29 +00001245/* Set local preference rule structure. */
1246struct route_map_rule_cmd route_set_local_pref_cmd =
1247{
1248 "local-preference",
1249 route_set_local_pref,
Timo Teräs38f22ab2015-04-29 09:43:02 +03001250 route_value_compile,
1251 route_value_free,
paul718e3742002-12-13 20:15:29 +00001252};
David Lamparter6b0655a2014-06-04 06:53:35 +02001253
paul718e3742002-12-13 20:15:29 +00001254/* `set weight WEIGHT' */
1255
1256/* Set weight. */
paul94f2b392005-06-28 12:44:16 +00001257static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001258route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
1259 void *object)
1260{
Timo Teräs38f22ab2015-04-29 09:43:02 +03001261 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +00001262 struct bgp_info *bgp_info;
Timo Teräs38f22ab2015-04-29 09:43:02 +03001263 u_int32_t weight;
paul718e3742002-12-13 20:15:29 +00001264
1265 if (type == RMAP_BGP)
1266 {
1267 /* Fetch routemap's rule information. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001268 rv = rule;
paul718e3742002-12-13 20:15:29 +00001269 bgp_info = object;
1270
1271 /* Set weight value. */
Timo Teräsef757702015-04-29 09:43:04 +03001272 weight = route_value_adjust(rv, 0, bgp_info->peer);
Timo Teräs38f22ab2015-04-29 09:43:02 +03001273 if (weight)
1274 (bgp_attr_extra_get (bgp_info->attr))->weight = weight;
Paul Jakmafb982c22007-05-04 20:15:47 +00001275 else if (bgp_info->attr->extra)
1276 bgp_info->attr->extra->weight = 0;
paul718e3742002-12-13 20:15:29 +00001277 }
1278
1279 return RMAP_OKAY;
1280}
1281
paul718e3742002-12-13 20:15:29 +00001282/* Set local preference rule structure. */
1283struct route_map_rule_cmd route_set_weight_cmd =
1284{
1285 "weight",
1286 route_set_weight,
Timo Teräs38f22ab2015-04-29 09:43:02 +03001287 route_value_compile,
1288 route_value_free,
paul718e3742002-12-13 20:15:29 +00001289};
David Lamparter6b0655a2014-06-04 06:53:35 +02001290
paul718e3742002-12-13 20:15:29 +00001291/* `set metric METRIC' */
1292
1293/* Set metric to attribute. */
paul94f2b392005-06-28 12:44:16 +00001294static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001295route_set_metric (void *rule, struct prefix *prefix,
1296 route_map_object_t type, void *object)
1297{
Timo Teräs38f22ab2015-04-29 09:43:02 +03001298 struct rmap_value *rv;
paul718e3742002-12-13 20:15:29 +00001299 struct bgp_info *bgp_info;
Timo Teräs38f22ab2015-04-29 09:43:02 +03001300 u_int32_t med = 0;
paul718e3742002-12-13 20:15:29 +00001301
1302 if (type == RMAP_BGP)
1303 {
1304 /* Fetch routemap's rule information. */
Timo Teräs38f22ab2015-04-29 09:43:02 +03001305 rv = rule;
paul718e3742002-12-13 20:15:29 +00001306 bgp_info = object;
1307
Timo Teräs38f22ab2015-04-29 09:43:02 +03001308 if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
1309 med = bgp_info->attr->med;
1310
Timo Teräsef757702015-04-29 09:43:04 +03001311 bgp_info->attr->med = route_value_adjust(rv, med, bgp_info->peer);
paul718e3742002-12-13 20:15:29 +00001312 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
paul718e3742002-12-13 20:15:29 +00001313 }
1314 return RMAP_OKAY;
1315}
1316
paul718e3742002-12-13 20:15:29 +00001317/* Set metric rule structure. */
1318struct route_map_rule_cmd route_set_metric_cmd =
1319{
1320 "metric",
1321 route_set_metric,
Timo Teräs38f22ab2015-04-29 09:43:02 +03001322 route_value_compile,
1323 route_value_free,
paul718e3742002-12-13 20:15:29 +00001324};
David Lamparter6b0655a2014-06-04 06:53:35 +02001325
paul718e3742002-12-13 20:15:29 +00001326/* `set as-path prepend ASPATH' */
1327
1328/* For AS path prepend mechanism. */
paul94f2b392005-06-28 12:44:16 +00001329static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001330route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1331{
1332 struct aspath *aspath;
1333 struct aspath *new;
1334 struct bgp_info *binfo;
1335
1336 if (type == RMAP_BGP)
1337 {
paul718e3742002-12-13 20:15:29 +00001338 binfo = object;
1339
1340 if (binfo->attr->aspath->refcnt)
1341 new = aspath_dup (binfo->attr->aspath);
1342 else
1343 new = binfo->attr->aspath;
1344
Timo Teräs85c854a2014-09-30 11:31:53 +03001345 if ((uintptr_t)rule > 10)
1346 {
1347 aspath = rule;
1348 aspath_prepend (aspath, new);
1349 }
1350 else
1351 {
1352 as_t as = aspath_leftmost(new);
1353 if (!as) as = binfo->peer->as;
1354 new = aspath_add_seq_n (new, as, (uintptr_t) rule);
1355 }
1356
paul718e3742002-12-13 20:15:29 +00001357 binfo->attr->aspath = new;
1358 }
1359
1360 return RMAP_OKAY;
1361}
1362
Timo Teräs85c854a2014-09-30 11:31:53 +03001363static void *
1364route_set_aspath_prepend_compile (const char *arg)
1365{
1366 unsigned int num;
1367
1368 if (sscanf(arg, "last-as %u", &num) == 1 && num > 0 && num < 10)
1369 return (void*)(uintptr_t)num;
1370
1371 return route_aspath_compile(arg);
1372}
1373
1374static void
1375route_set_aspath_prepend_free (void *rule)
1376{
1377 if ((uintptr_t)rule > 10)
1378 route_aspath_free(rule);
1379}
1380
1381
Timo Teräs2aa640b2014-05-20 08:57:26 +03001382/* Set as-path prepend rule structure. */
paul718e3742002-12-13 20:15:29 +00001383struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1384{
1385 "as-path prepend",
1386 route_set_aspath_prepend,
Timo Teräs85c854a2014-09-30 11:31:53 +03001387 route_set_aspath_prepend_compile,
1388 route_set_aspath_prepend_free,
paul718e3742002-12-13 20:15:29 +00001389};
David Lamparter6b0655a2014-06-04 06:53:35 +02001390
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001391/* `set as-path exclude ASn' */
1392
1393/* For ASN exclude mechanism.
1394 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1395 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1396 */
1397static route_map_result_t
1398route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
1399{
1400 struct aspath * new_path, * exclude_path;
1401 struct bgp_info *binfo;
1402
1403 if (type == RMAP_BGP)
1404 {
1405 exclude_path = rule;
1406 binfo = object;
1407 if (binfo->attr->aspath->refcnt)
1408 new_path = aspath_dup (binfo->attr->aspath);
1409 else
1410 new_path = binfo->attr->aspath;
1411 binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
1412 }
1413 return RMAP_OKAY;
1414}
1415
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001416/* Set ASn exlude rule structure. */
1417struct route_map_rule_cmd route_set_aspath_exclude_cmd =
1418{
1419 "as-path exclude",
1420 route_set_aspath_exclude,
Timo Teräsb304dcb2014-05-20 09:04:49 +03001421 route_aspath_compile,
1422 route_aspath_free,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001423};
David Lamparter6b0655a2014-06-04 06:53:35 +02001424
paul718e3742002-12-13 20:15:29 +00001425/* `set community COMMUNITY' */
1426struct rmap_com_set
1427{
1428 struct community *com;
1429 int additive;
1430 int none;
1431};
1432
1433/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001434static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001435route_set_community (void *rule, struct prefix *prefix,
1436 route_map_object_t type, void *object)
1437{
1438 struct rmap_com_set *rcs;
1439 struct bgp_info *binfo;
1440 struct attr *attr;
1441 struct community *new = NULL;
1442 struct community *old;
1443 struct community *merge;
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001444
paul718e3742002-12-13 20:15:29 +00001445 if (type == RMAP_BGP)
1446 {
1447 rcs = rule;
1448 binfo = object;
1449 attr = binfo->attr;
1450 old = attr->community;
1451
1452 /* "none" case. */
1453 if (rcs->none)
1454 {
1455 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1456 attr->community = NULL;
Christian Frankeb06b35f2012-12-07 14:26:09 +00001457 /* See the longer comment down below. */
1458 if (old && old->refcnt == 0)
1459 community_free(old);
paul718e3742002-12-13 20:15:29 +00001460 return RMAP_OKAY;
1461 }
1462
1463 /* "additive" case. */
1464 if (rcs->additive && old)
1465 {
1466 merge = community_merge (community_dup (old), rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001467
1468 /* HACK: if the old community is not intern'd,
1469 * we should free it here, or all reference to it may be lost.
1470 * Really need to cleanup attribute caching sometime.
1471 */
1472 if (old->refcnt == 0)
1473 community_free (old);
paul718e3742002-12-13 20:15:29 +00001474 new = community_uniq_sort (merge);
1475 community_free (merge);
1476 }
1477 else
1478 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001479
1480 /* will be interned by caller if required */
Paul Jakma4a2035f2011-04-01 15:58:27 +01001481 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001482
paul718e3742002-12-13 20:15:29 +00001483 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1484 }
1485
1486 return RMAP_OKAY;
1487}
1488
1489/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001490static void *
paulfd79ac92004-10-13 05:06:08 +00001491route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001492{
1493 struct rmap_com_set *rcs;
1494 struct community *com = NULL;
1495 char *sp;
1496 int additive = 0;
1497 int none = 0;
1498
1499 if (strcmp (arg, "none") == 0)
1500 none = 1;
1501 else
1502 {
1503 sp = strstr (arg, "additive");
1504
1505 if (sp && sp > arg)
1506 {
1507 /* "additive" keyworkd is included. */
1508 additive = 1;
1509 *(sp - 1) = '\0';
1510 }
1511
1512 com = community_str2com (arg);
1513
1514 if (additive)
1515 *(sp - 1) = ' ';
1516
1517 if (! com)
1518 return NULL;
1519 }
1520
Stephen Hemminger393deb92008-08-18 14:13:29 -07001521 rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
Paul Jakma4a2035f2011-04-01 15:58:27 +01001522 rcs->com = com;
paul718e3742002-12-13 20:15:29 +00001523 rcs->additive = additive;
1524 rcs->none = none;
1525
1526 return rcs;
1527}
1528
1529/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001530static void
paul718e3742002-12-13 20:15:29 +00001531route_set_community_free (void *rule)
1532{
1533 struct rmap_com_set *rcs = rule;
1534
1535 if (rcs->com)
1536 community_free (rcs->com);
1537 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1538}
1539
1540/* Set community rule structure. */
1541struct route_map_rule_cmd route_set_community_cmd =
1542{
1543 "community",
1544 route_set_community,
1545 route_set_community_compile,
1546 route_set_community_free,
1547};
David Lamparter6b0655a2014-06-04 06:53:35 +02001548
Job Snijders3334bab2017-01-20 14:47:12 +00001549/* `set community COMMUNITY' */
1550struct rmap_lcom_set
1551{
1552 struct lcommunity *lcom;
1553 int additive;
1554 int none;
1555};
1556
1557
1558/* For lcommunity set mechanism. */
1559static route_map_result_t
1560route_set_lcommunity (void *rule, struct prefix *prefix,
1561 route_map_object_t type, void *object)
1562{
1563 struct rmap_lcom_set *rcs;
1564 struct bgp_info *binfo;
1565 struct attr *attr;
1566 struct lcommunity *new = NULL;
1567 struct lcommunity *old;
1568 struct lcommunity *merge;
1569
1570 if (type == RMAP_BGP)
1571 {
1572 rcs = rule;
1573 binfo = object;
1574 attr = binfo->attr;
1575 old = (attr->extra) ? attr->extra->lcommunity : NULL;
1576
1577 /* "none" case. */
1578 if (rcs->none)
1579 {
1580 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES));
1581 if (attr->extra) {
1582 attr->extra->lcommunity = NULL;
1583 }
1584 /* See the longer comment down below. */
1585 if (old && old->refcnt == 0)
1586 lcommunity_free(&old);
1587 return RMAP_OKAY;
1588 }
1589
1590 if (rcs->additive && old)
1591 {
1592 merge = lcommunity_merge (lcommunity_dup (old), rcs->lcom);
1593
1594 /* HACK: if the old large-community is not intern'd,
1595 * we should free it here, or all reference to it may be lost.
1596 * Really need to cleanup attribute caching sometime.
1597 */
1598 if (old->refcnt == 0)
1599 lcommunity_free (&old);
1600 new = lcommunity_uniq_sort (merge);
1601 lcommunity_free (&merge);
1602 }
1603 else
1604 {
1605 new = lcommunity_dup (rcs->lcom);
1606 }
1607
1608 /* will be interned by caller if required */
1609 bgp_attr_extra_get (attr)->lcommunity = new;
1610 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES);
1611 }
1612
1613 return RMAP_OKAY;
1614}
1615
1616/* Compile function for set community. */
1617static void *
1618route_set_lcommunity_compile (const char *arg)
1619{
1620 struct rmap_lcom_set *rcs;
1621 struct lcommunity *lcom = NULL;
1622 char *sp;
1623 int additive = 0;
1624 int none = 0;
1625
1626 if (strcmp (arg, "none") == 0)
1627 none = 1;
1628 else
1629 {
1630 sp = strstr (arg, "additive");
1631
1632 if (sp && sp > arg)
1633 {
1634 /* "additive" keyworkd is included. */
1635 additive = 1;
1636 *(sp - 1) = '\0';
1637 }
1638
1639 lcom = lcommunity_str2com (arg);
1640
1641 if (additive)
1642 *(sp - 1) = ' ';
1643
1644 if (! lcom)
1645 return NULL;
1646 }
1647
1648 rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
1649 rcs->lcom = lcom;
1650 rcs->additive = additive;
1651 rcs->none = none;
1652
1653 return rcs;
1654}
1655
1656/* Free function for set lcommunity. */
1657static void
1658route_set_lcommunity_free (void *rule)
1659{
1660 struct rmap_lcom_set *rcs = rule;
1661
1662 if (rcs->lcom) {
1663 lcommunity_free (&rcs->lcom);
1664 }
1665 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1666}
1667
1668/* Set community rule structure. */
1669struct route_map_rule_cmd route_set_lcommunity_cmd =
1670{
1671 "large-community",
1672 route_set_lcommunity,
1673 route_set_lcommunity_compile,
1674 route_set_lcommunity_free,
1675};
1676
1677/* `set large-comm-list (<1-99>|<100-500>|WORD) delete' */
1678
1679/* For large community set mechanism. */
1680static route_map_result_t
1681route_set_lcommunity_delete (void *rule, struct prefix *prefix,
1682 route_map_object_t type, void *object)
1683{
1684 struct community_list *list;
1685 struct lcommunity *merge;
1686 struct lcommunity *new;
1687 struct lcommunity *old;
1688 struct bgp_info *binfo;
1689
1690 if (type == RMAP_BGP)
1691 {
1692 if (! rule)
1693 return RMAP_OKAY;
1694
1695 binfo = object;
1696 list = community_list_lookup (bgp_clist, rule,
1697 LARGE_COMMUNITY_LIST_MASTER);
1698 old = ((binfo->attr->extra) ? binfo->attr->extra->lcommunity : NULL);
1699
1700 if (list && old)
1701 {
1702 merge = lcommunity_list_match_delete (lcommunity_dup (old), list);
1703 new = lcommunity_uniq_sort (merge);
1704 lcommunity_free (&merge);
1705
1706 /* HACK: if the old community is not intern'd,
1707 * we should free it here, or all reference to it may be lost.
1708 * Really need to cleanup attribute caching sometime.
1709 */
1710 if (old->refcnt == 0)
1711 lcommunity_free (&old);
1712
1713 if (new->size == 0)
1714 {
1715 binfo->attr->extra->lcommunity = NULL;
1716 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES);
1717 lcommunity_free (&new);
1718 }
1719 else
1720 {
1721 binfo->attr->extra->lcommunity = new;
1722 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LARGE_COMMUNITIES);
1723 }
1724 }
1725 }
1726
1727 return RMAP_OKAY;
1728}
1729
1730/* Compile function for set lcommunity. */
1731static void *
1732route_set_lcommunity_delete_compile (const char *arg)
1733{
1734 char *p;
1735 char *str;
1736 int len;
1737
1738 p = strchr (arg, ' ');
1739 if (p)
1740 {
1741 len = p - arg;
1742 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1743 memcpy (str, arg, len);
1744 }
1745 else
1746 str = NULL;
1747
1748 return str;
1749}
1750
1751/* Free function for set lcommunity. */
1752static void
1753route_set_lcommunity_delete_free (void *rule)
1754{
1755 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1756}
1757
1758/* Set lcommunity rule structure. */
1759struct route_map_rule_cmd route_set_lcommunity_delete_cmd =
1760{
1761 "large-comm-list",
1762 route_set_lcommunity_delete,
1763 route_set_lcommunity_delete_compile,
1764 route_set_lcommunity_delete_free,
1765};
1766
1767
hassofee6e4e2005-02-02 16:29:31 +00001768/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001769
1770/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001771static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001772route_set_community_delete (void *rule, struct prefix *prefix,
1773 route_map_object_t type, void *object)
1774{
1775 struct community_list *list;
1776 struct community *merge;
1777 struct community *new;
1778 struct community *old;
1779 struct bgp_info *binfo;
1780
1781 if (type == RMAP_BGP)
1782 {
1783 if (! rule)
1784 return RMAP_OKAY;
1785
1786 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001787 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001788 old = binfo->attr->community;
1789
1790 if (list && old)
1791 {
1792 merge = community_list_match_delete (community_dup (old), list);
1793 new = community_uniq_sort (merge);
1794 community_free (merge);
1795
Michael Lambert604a9b42010-09-13 11:48:11 -04001796 /* HACK: if the old community is not intern'd,
1797 * we should free it here, or all reference to it may be lost.
1798 * Really need to cleanup attribute caching sometime.
1799 */
1800 if (old->refcnt == 0)
1801 community_free (old);
1802
paul718e3742002-12-13 20:15:29 +00001803 if (new->size == 0)
1804 {
1805 binfo->attr->community = NULL;
1806 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1807 community_free (new);
1808 }
1809 else
1810 {
Paul Jakma4a2035f2011-04-01 15:58:27 +01001811 binfo->attr->community = new;
paul718e3742002-12-13 20:15:29 +00001812 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1813 }
1814 }
1815 }
1816
1817 return RMAP_OKAY;
1818}
1819
1820/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001821static void *
paulfd79ac92004-10-13 05:06:08 +00001822route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001823{
1824 char *p;
1825 char *str;
1826 int len;
1827
1828 p = strchr (arg, ' ');
1829 if (p)
1830 {
1831 len = p - arg;
1832 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1833 memcpy (str, arg, len);
1834 }
1835 else
1836 str = NULL;
1837
1838 return str;
1839}
1840
1841/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001842static void
paul718e3742002-12-13 20:15:29 +00001843route_set_community_delete_free (void *rule)
1844{
1845 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1846}
1847
1848/* Set community rule structure. */
1849struct route_map_rule_cmd route_set_community_delete_cmd =
1850{
1851 "comm-list",
1852 route_set_community_delete,
1853 route_set_community_delete_compile,
1854 route_set_community_delete_free,
1855};
David Lamparter6b0655a2014-06-04 06:53:35 +02001856
paul718e3742002-12-13 20:15:29 +00001857/* `set extcommunity rt COMMUNITY' */
1858
David Lamparter73d78ea2014-06-04 00:58:47 +02001859/* For community set mechanism. Used by _rt and _soo. */
paul94f2b392005-06-28 12:44:16 +00001860static route_map_result_t
David Lamparter73d78ea2014-06-04 00:58:47 +02001861route_set_ecommunity (void *rule, struct prefix *prefix,
1862 route_map_object_t type, void *object)
paul718e3742002-12-13 20:15:29 +00001863{
1864 struct ecommunity *ecom;
1865 struct ecommunity *new_ecom;
1866 struct ecommunity *old_ecom;
1867 struct bgp_info *bgp_info;
1868
1869 if (type == RMAP_BGP)
1870 {
1871 ecom = rule;
1872 bgp_info = object;
1873
1874 if (! ecom)
1875 return RMAP_OKAY;
1876
1877 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001878 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001879
1880 if (old_ecom)
David Lamparter27bf90a2014-06-04 00:59:01 +02001881 {
1882 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1883
1884 /* old_ecom->refcnt = 1 => owned elsewhere, e.g. bgp_update_receive()
1885 * ->refcnt = 0 => set by a previous route-map statement */
1886 if (!old_ecom->refcnt)
1887 ecommunity_free (&old_ecom);
1888 }
paul718e3742002-12-13 20:15:29 +00001889 else
1890 new_ecom = ecommunity_dup (ecom);
1891
David Lamparter27bf90a2014-06-04 00:59:01 +02001892 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
1893 bgp_info->attr->extra->ecommunity = new_ecom;
hasso70601e02005-05-27 03:26:57 +00001894
paul718e3742002-12-13 20:15:29 +00001895 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1896 }
1897 return RMAP_OKAY;
1898}
1899
1900/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001901static void *
paulfd79ac92004-10-13 05:06:08 +00001902route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001903{
1904 struct ecommunity *ecom;
1905
1906 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1907 if (! ecom)
1908 return NULL;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001909 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001910}
1911
David Lamparter73d78ea2014-06-04 00:58:47 +02001912/* Free function for set community. Used by _rt and _soo */
paul94f2b392005-06-28 12:44:16 +00001913static void
David Lamparter73d78ea2014-06-04 00:58:47 +02001914route_set_ecommunity_free (void *rule)
paul718e3742002-12-13 20:15:29 +00001915{
1916 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001917 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001918}
1919
1920/* Set community rule structure. */
1921struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1922{
1923 "extcommunity rt",
David Lamparter73d78ea2014-06-04 00:58:47 +02001924 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001925 route_set_ecommunity_rt_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001926 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001927};
1928
1929/* `set extcommunity soo COMMUNITY' */
1930
paul718e3742002-12-13 20:15:29 +00001931/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001932static void *
paulfd79ac92004-10-13 05:06:08 +00001933route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001934{
1935 struct ecommunity *ecom;
1936
1937 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1938 if (! ecom)
1939 return NULL;
1940
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001941 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001942}
1943
paul718e3742002-12-13 20:15:29 +00001944/* Set community rule structure. */
1945struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1946{
1947 "extcommunity soo",
David Lamparter73d78ea2014-06-04 00:58:47 +02001948 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001949 route_set_ecommunity_soo_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001950 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001951};
David Lamparter6b0655a2014-06-04 06:53:35 +02001952
paul718e3742002-12-13 20:15:29 +00001953/* `set origin ORIGIN' */
1954
1955/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001956static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001957route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1958{
1959 u_char *origin;
1960 struct bgp_info *bgp_info;
1961
1962 if (type == RMAP_BGP)
1963 {
1964 origin = rule;
1965 bgp_info = object;
1966
1967 bgp_info->attr->origin = *origin;
1968 }
1969
1970 return RMAP_OKAY;
1971}
1972
1973/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001974static void *
paulfd79ac92004-10-13 05:06:08 +00001975route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001976{
1977 u_char *origin;
1978
1979 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1980
1981 if (strcmp (arg, "igp") == 0)
1982 *origin = 0;
1983 else if (strcmp (arg, "egp") == 0)
1984 *origin = 1;
1985 else
1986 *origin = 2;
1987
1988 return origin;
1989}
1990
1991/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001992static void
paul718e3742002-12-13 20:15:29 +00001993route_set_origin_free (void *rule)
1994{
1995 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1996}
1997
Timo Teräs2aa640b2014-05-20 08:57:26 +03001998/* Set origin rule structure. */
paul718e3742002-12-13 20:15:29 +00001999struct route_map_rule_cmd route_set_origin_cmd =
2000{
2001 "origin",
2002 route_set_origin,
2003 route_set_origin_compile,
2004 route_set_origin_free,
2005};
David Lamparter6b0655a2014-06-04 06:53:35 +02002006
paul718e3742002-12-13 20:15:29 +00002007/* `set atomic-aggregate' */
2008
2009/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00002010static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002011route_set_atomic_aggregate (void *rule, struct prefix *prefix,
2012 route_map_object_t type, void *object)
2013{
2014 struct bgp_info *bgp_info;
2015
2016 if (type == RMAP_BGP)
2017 {
2018 bgp_info = object;
2019 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
2020 }
2021
2022 return RMAP_OKAY;
2023}
2024
2025/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00002026static void *
paulfd79ac92004-10-13 05:06:08 +00002027route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002028{
2029 return (void *)1;
2030}
2031
2032/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00002033static void
paul718e3742002-12-13 20:15:29 +00002034route_set_atomic_aggregate_free (void *rule)
2035{
2036 return;
2037}
2038
2039/* Set atomic aggregate rule structure. */
2040struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
2041{
2042 "atomic-aggregate",
2043 route_set_atomic_aggregate,
2044 route_set_atomic_aggregate_compile,
2045 route_set_atomic_aggregate_free,
2046};
David Lamparter6b0655a2014-06-04 06:53:35 +02002047
paul718e3742002-12-13 20:15:29 +00002048/* `set aggregator as AS A.B.C.D' */
2049struct aggregator
2050{
2051 as_t as;
2052 struct in_addr address;
2053};
2054
paul94f2b392005-06-28 12:44:16 +00002055static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002056route_set_aggregator_as (void *rule, struct prefix *prefix,
2057 route_map_object_t type, void *object)
2058{
2059 struct bgp_info *bgp_info;
2060 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00002061 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00002062
2063 if (type == RMAP_BGP)
2064 {
2065 bgp_info = object;
2066 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00002067 ae = bgp_attr_extra_get (bgp_info->attr);
2068
2069 ae->aggregator_as = aggregator->as;
2070 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00002071 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
2072 }
2073
2074 return RMAP_OKAY;
2075}
2076
paul94f2b392005-06-28 12:44:16 +00002077static void *
paulfd79ac92004-10-13 05:06:08 +00002078route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002079{
2080 struct aggregator *aggregator;
2081 char as[10];
2082 char address[20];
2083
Stephen Hemminger393deb92008-08-18 14:13:29 -07002084 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
paul718e3742002-12-13 20:15:29 +00002085 sscanf (arg, "%s %s", as, address);
2086
2087 aggregator->as = strtoul (as, NULL, 10);
2088 inet_aton (address, &aggregator->address);
2089
2090 return aggregator;
2091}
2092
paul94f2b392005-06-28 12:44:16 +00002093static void
paul718e3742002-12-13 20:15:29 +00002094route_set_aggregator_as_free (void *rule)
2095{
2096 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2097}
2098
2099struct route_map_rule_cmd route_set_aggregator_as_cmd =
2100{
2101 "aggregator as",
2102 route_set_aggregator_as,
2103 route_set_aggregator_as_compile,
2104 route_set_aggregator_as_free,
2105};
David Lamparter6b0655a2014-06-04 06:53:35 +02002106
Piotr Chytła605aa332015-12-01 10:03:54 -05002107/* Set tag to object. object must be pointer to struct bgp_info */
2108static route_map_result_t
2109route_set_tag (void *rule, struct prefix *prefix,
2110 route_map_object_t type, void *object)
2111{
Paul Jakma96d10602016-07-01 14:23:45 +01002112 route_tag_t *tag;
Piotr Chytła605aa332015-12-01 10:03:54 -05002113 struct bgp_info *bgp_info;
2114 struct attr_extra *ae;
2115
2116 if (type == RMAP_BGP)
2117 {
2118 tag = rule;
2119 bgp_info = object;
2120 ae = bgp_attr_extra_get (bgp_info->attr);
2121
2122 /* Set tag value */
2123 ae->tag=*tag;
2124
2125 }
2126
2127 return RMAP_OKAY;
2128}
2129
Piotr Chytła605aa332015-12-01 10:03:54 -05002130/* Route map commands for tag set. */
Christian Frankeddc160c2016-10-01 20:42:34 +02002131static struct route_map_rule_cmd route_set_tag_cmd =
Piotr Chytła605aa332015-12-01 10:03:54 -05002132{
2133 "tag",
2134 route_set_tag,
Christian Frankeddc160c2016-10-01 20:42:34 +02002135 route_map_rule_tag_compile,
2136 route_map_rule_tag_free,
Piotr Chytła605aa332015-12-01 10:03:54 -05002137};
2138
2139
paul718e3742002-12-13 20:15:29 +00002140/* `match ipv6 address IP_ACCESS_LIST' */
2141
paul94f2b392005-06-28 12:44:16 +00002142static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002143route_match_ipv6_address (void *rule, struct prefix *prefix,
2144 route_map_object_t type, void *object)
2145{
2146 struct access_list *alist;
2147
2148 if (type == RMAP_BGP)
2149 {
2150 alist = access_list_lookup (AFI_IP6, (char *) rule);
2151 if (alist == NULL)
2152 return RMAP_NOMATCH;
2153
2154 return (access_list_apply (alist, prefix) == FILTER_DENY ?
2155 RMAP_NOMATCH : RMAP_MATCH);
2156 }
2157 return RMAP_NOMATCH;
2158}
2159
paul94f2b392005-06-28 12:44:16 +00002160static void *
paulfd79ac92004-10-13 05:06:08 +00002161route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002162{
2163 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
2164}
2165
paul94f2b392005-06-28 12:44:16 +00002166static void
paul718e3742002-12-13 20:15:29 +00002167route_match_ipv6_address_free (void *rule)
2168{
2169 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2170}
2171
2172/* Route map commands for ip address matching. */
2173struct route_map_rule_cmd route_match_ipv6_address_cmd =
2174{
2175 "ipv6 address",
2176 route_match_ipv6_address,
2177 route_match_ipv6_address_compile,
2178 route_match_ipv6_address_free
2179};
David Lamparter6b0655a2014-06-04 06:53:35 +02002180
paul718e3742002-12-13 20:15:29 +00002181/* `match ipv6 next-hop IP_ADDRESS' */
2182
paul94f2b392005-06-28 12:44:16 +00002183static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002184route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
2185 route_map_object_t type, void *object)
2186{
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002187 struct in6_addr *addr = rule;
paul718e3742002-12-13 20:15:29 +00002188 struct bgp_info *bgp_info;
2189
2190 if (type == RMAP_BGP)
2191 {
paul718e3742002-12-13 20:15:29 +00002192 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00002193
2194 if (!bgp_info->attr->extra)
2195 return RMAP_NOMATCH;
2196
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002197 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, addr))
paul718e3742002-12-13 20:15:29 +00002198 return RMAP_MATCH;
2199
Paul Jakmafb982c22007-05-04 20:15:47 +00002200 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
Paul Jakma7aa9dce2014-09-19 14:42:23 +01002201 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, addr))
paul718e3742002-12-13 20:15:29 +00002202 return RMAP_MATCH;
2203
2204 return RMAP_NOMATCH;
2205 }
2206
2207 return RMAP_NOMATCH;
2208}
2209
paul94f2b392005-06-28 12:44:16 +00002210static void *
paulfd79ac92004-10-13 05:06:08 +00002211route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002212{
2213 struct in6_addr *address;
2214 int ret;
2215
2216 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2217
2218 ret = inet_pton (AF_INET6, arg, address);
2219 if (!ret)
2220 {
2221 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2222 return NULL;
2223 }
2224
2225 return address;
2226}
2227
paul94f2b392005-06-28 12:44:16 +00002228static void
paul718e3742002-12-13 20:15:29 +00002229route_match_ipv6_next_hop_free (void *rule)
2230{
2231 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2232}
2233
2234struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
2235{
2236 "ipv6 next-hop",
2237 route_match_ipv6_next_hop,
2238 route_match_ipv6_next_hop_compile,
2239 route_match_ipv6_next_hop_free
2240};
David Lamparter6b0655a2014-06-04 06:53:35 +02002241
paul718e3742002-12-13 20:15:29 +00002242/* `match ipv6 address prefix-list PREFIX_LIST' */
2243
paul94f2b392005-06-28 12:44:16 +00002244static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002245route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
2246 route_map_object_t type, void *object)
2247{
2248 struct prefix_list *plist;
2249
2250 if (type == RMAP_BGP)
2251 {
2252 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
2253 if (plist == NULL)
2254 return RMAP_NOMATCH;
2255
2256 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
2257 RMAP_NOMATCH : RMAP_MATCH);
2258 }
2259 return RMAP_NOMATCH;
2260}
2261
paul94f2b392005-06-28 12:44:16 +00002262static void *
paulfd79ac92004-10-13 05:06:08 +00002263route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002264{
2265 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
2266}
2267
paul94f2b392005-06-28 12:44:16 +00002268static void
paul718e3742002-12-13 20:15:29 +00002269route_match_ipv6_address_prefix_list_free (void *rule)
2270{
2271 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2272}
2273
2274struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
2275{
2276 "ipv6 address prefix-list",
2277 route_match_ipv6_address_prefix_list,
2278 route_match_ipv6_address_prefix_list_compile,
2279 route_match_ipv6_address_prefix_list_free
2280};
David Lamparter6b0655a2014-06-04 06:53:35 +02002281
paul718e3742002-12-13 20:15:29 +00002282/* `set ipv6 nexthop global IP_ADDRESS' */
2283
2284/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00002285static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002286route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
2287 route_map_object_t type, void *object)
2288{
2289 struct in6_addr *address;
2290 struct bgp_info *bgp_info;
2291
2292 if (type == RMAP_BGP)
2293 {
2294 /* Fetch routemap's rule information. */
2295 address = rule;
2296 bgp_info = object;
2297
2298 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002299 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00002300
2301 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002302 if (bgp_info->attr->extra->mp_nexthop_len == 0)
2303 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00002304 }
2305
2306 return RMAP_OKAY;
2307}
2308
2309/* Route map `ip next-hop' compile function. Given string is converted
2310 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00002311static void *
paulfd79ac92004-10-13 05:06:08 +00002312route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002313{
2314 int ret;
2315 struct in6_addr *address;
2316
2317 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2318
2319 ret = inet_pton (AF_INET6, arg, address);
2320
2321 if (ret == 0)
2322 {
2323 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2324 return NULL;
2325 }
2326
2327 return address;
2328}
2329
2330/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00002331static void
paul718e3742002-12-13 20:15:29 +00002332route_set_ipv6_nexthop_global_free (void *rule)
2333{
2334 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2335}
2336
2337/* Route map commands for ip nexthop set. */
2338struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
2339{
2340 "ipv6 next-hop global",
2341 route_set_ipv6_nexthop_global,
2342 route_set_ipv6_nexthop_global_compile,
2343 route_set_ipv6_nexthop_global_free
2344};
David Lamparter6b0655a2014-06-04 06:53:35 +02002345
paul718e3742002-12-13 20:15:29 +00002346/* `set ipv6 nexthop local IP_ADDRESS' */
2347
2348/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00002349static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002350route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
2351 route_map_object_t type, void *object)
2352{
2353 struct in6_addr *address;
2354 struct bgp_info *bgp_info;
2355
2356 if (type == RMAP_BGP)
2357 {
2358 /* Fetch routemap's rule information. */
2359 address = rule;
2360 bgp_info = object;
2361
2362 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002363 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00002364
2365 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002366 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2367 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00002368 }
2369
2370 return RMAP_OKAY;
2371}
2372
2373/* Route map `ip nexthop' compile function. Given string is converted
2374 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00002375static void *
paulfd79ac92004-10-13 05:06:08 +00002376route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002377{
2378 int ret;
2379 struct in6_addr *address;
2380
2381 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2382
2383 ret = inet_pton (AF_INET6, arg, address);
2384
2385 if (ret == 0)
2386 {
2387 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2388 return NULL;
2389 }
2390
2391 return address;
2392}
2393
2394/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00002395static void
paul718e3742002-12-13 20:15:29 +00002396route_set_ipv6_nexthop_local_free (void *rule)
2397{
2398 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2399}
2400
2401/* Route map commands for ip nexthop set. */
2402struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
2403{
2404 "ipv6 next-hop local",
2405 route_set_ipv6_nexthop_local,
2406 route_set_ipv6_nexthop_local_compile,
2407 route_set_ipv6_nexthop_local_free
2408};
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002409
2410/* `set ipv6 nexthop peer-address' */
2411
2412/* Set nexthop to object. ojbect must be pointer to struct attr. */
2413static route_map_result_t
2414route_set_ipv6_nexthop_peer (void *rule, struct prefix *prefix,
2415 route_map_object_t type, void *object)
2416{
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002417 struct in6_addr peer_address;
2418 struct bgp_info *bgp_info;
2419 struct peer *peer;
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002420
2421 if (type == RMAP_BGP)
2422 {
2423 /* Fetch routemap's rule information. */
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002424 bgp_info = object;
2425 peer = bgp_info->peer;
2426
2427 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
2428 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
2429 && peer->su_remote
2430 && sockunion_family (peer->su_remote) == AF_INET6)
2431 {
Christian Franke5cb81ce2016-06-14 20:06:56 +02002432 peer_address = peer->su_remote->sin6.sin6_addr;
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002433 }
2434 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
2435 && peer->su_local
2436 && sockunion_family (peer->su_local) == AF_INET6)
2437 {
Christian Franke5cb81ce2016-06-14 20:06:56 +02002438 peer_address = peer->su_local->sin6.sin6_addr;
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002439 }
2440
2441 if (IN6_IS_ADDR_LINKLOCAL(&peer_address))
2442 {
2443 /* Set next hop value. */
2444 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = peer_address;
2445
2446 /* Set nexthop length. */
2447 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2448 bgp_info->attr->extra->mp_nexthop_len = 32;
2449 }
2450 else
2451 {
2452 /* Set next hop value. */
2453 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = peer_address;
2454
2455 /* Set nexthop length. */
2456 if (bgp_info->attr->extra->mp_nexthop_len == 0)
2457 bgp_info->attr->extra->mp_nexthop_len = 16;
2458 }
2459 }
2460
2461 return RMAP_OKAY;
2462}
2463
2464/* Route map `ip next-hop' compile function. Given string is converted
2465 to struct in_addr structure. */
2466static void *
2467route_set_ipv6_nexthop_peer_compile (const char *arg)
2468{
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002469 int *rins = NULL;
2470
2471 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (int));
2472 *rins = 1;
2473
2474 return rins;
2475}
2476
2477/* Free route map's compiled `ip next-hop' value. */
2478static void
2479route_set_ipv6_nexthop_peer_free (void *rule)
2480{
2481 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2482}
2483
2484/* Route map commands for ip nexthop set. */
2485struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd =
2486{
2487 "ipv6 next-hop peer-address",
2488 route_set_ipv6_nexthop_peer,
2489 route_set_ipv6_nexthop_peer_compile,
2490 route_set_ipv6_nexthop_peer_free
2491};
2492
paul718e3742002-12-13 20:15:29 +00002493/* `set vpnv4 nexthop A.B.C.D' */
2494
paul94f2b392005-06-28 12:44:16 +00002495static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002496route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2497 route_map_object_t type, void *object)
2498{
2499 struct in_addr *address;
2500 struct bgp_info *bgp_info;
2501
2502 if (type == RMAP_BGP)
2503 {
2504 /* Fetch routemap's rule information. */
2505 address = rule;
2506 bgp_info = object;
2507
2508 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002509 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
Lou Berger050defe2016-01-12 13:41:59 -05002510 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_len = 4;
paul718e3742002-12-13 20:15:29 +00002511 }
2512
2513 return RMAP_OKAY;
2514}
2515
paul94f2b392005-06-28 12:44:16 +00002516static void *
paulfd79ac92004-10-13 05:06:08 +00002517route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002518{
2519 int ret;
2520 struct in_addr *address;
2521
2522 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2523
2524 ret = inet_aton (arg, address);
2525
2526 if (ret == 0)
2527 {
2528 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2529 return NULL;
2530 }
2531
2532 return address;
2533}
2534
paul94f2b392005-06-28 12:44:16 +00002535static void
paul718e3742002-12-13 20:15:29 +00002536route_set_vpnv4_nexthop_free (void *rule)
2537{
2538 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2539}
2540
2541/* Route map commands for ip nexthop set. */
2542struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2543{
2544 "vpnv4 next-hop",
2545 route_set_vpnv4_nexthop,
2546 route_set_vpnv4_nexthop_compile,
2547 route_set_vpnv4_nexthop_free
2548};
David Lamparter6b0655a2014-06-04 06:53:35 +02002549
paul718e3742002-12-13 20:15:29 +00002550/* `set originator-id' */
2551
2552/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002553static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002554route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2555{
2556 struct in_addr *address;
2557 struct bgp_info *bgp_info;
2558
2559 if (type == RMAP_BGP)
2560 {
2561 address = rule;
2562 bgp_info = object;
2563
2564 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002565 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002566 }
2567
2568 return RMAP_OKAY;
2569}
2570
2571/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002572static void *
paulfd79ac92004-10-13 05:06:08 +00002573route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002574{
2575 int ret;
2576 struct in_addr *address;
2577
2578 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2579
2580 ret = inet_aton (arg, address);
2581
2582 if (ret == 0)
2583 {
2584 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2585 return NULL;
2586 }
2587
2588 return address;
2589}
2590
2591/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002592static void
paul718e3742002-12-13 20:15:29 +00002593route_set_originator_id_free (void *rule)
2594{
2595 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2596}
2597
Timo Teräs2aa640b2014-05-20 08:57:26 +03002598/* Set originator-id rule structure. */
paul718e3742002-12-13 20:15:29 +00002599struct route_map_rule_cmd route_set_originator_id_cmd =
2600{
2601 "originator-id",
2602 route_set_originator_id,
2603 route_set_originator_id_compile,
2604 route_set_originator_id_free,
2605};
David Lamparter6b0655a2014-06-04 06:53:35 +02002606
paul718e3742002-12-13 20:15:29 +00002607/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002608static int
paul718e3742002-12-13 20:15:29 +00002609bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002610 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002611{
2612 int ret;
2613
2614 ret = route_map_add_match (index, command, arg);
2615 if (ret)
2616 {
2617 switch (ret)
2618 {
2619 case RMAP_RULE_MISSING:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002620 vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002621 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002622 case RMAP_COMPILE_ERROR:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002623 vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002624 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002625 }
2626 }
2627 return CMD_SUCCESS;
2628}
2629
2630/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002631static int
paul718e3742002-12-13 20:15:29 +00002632bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002633 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002634{
2635 int ret;
2636
2637 ret = route_map_delete_match (index, command, arg);
2638 if (ret)
2639 {
2640 switch (ret)
2641 {
2642 case RMAP_RULE_MISSING:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002643 vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002644 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002645 case RMAP_COMPILE_ERROR:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002646 vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002647 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002648 }
2649 }
2650 return CMD_SUCCESS;
2651}
2652
2653/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002654static int
paul718e3742002-12-13 20:15:29 +00002655bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002656 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002657{
2658 int ret;
2659
2660 ret = route_map_add_set (index, command, arg);
2661 if (ret)
2662 {
2663 switch (ret)
2664 {
2665 case RMAP_RULE_MISSING:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002666 vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002667 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002668 case RMAP_COMPILE_ERROR:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002669 vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002670 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002671 }
2672 }
2673 return CMD_SUCCESS;
2674}
2675
2676/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002677static int
paul718e3742002-12-13 20:15:29 +00002678bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002679 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002680{
2681 int ret;
2682
2683 ret = route_map_delete_set (index, command, arg);
2684 if (ret)
2685 {
2686 switch (ret)
2687 {
2688 case RMAP_RULE_MISSING:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002689 vty_out (vty, "%% BGP Can't find rule.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002690 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002691 case RMAP_COMPILE_ERROR:
Daniel Waltonc7f25b92015-05-19 17:47:22 -07002692 vty_out (vty, "%% BGP Argument is malformed.%s", VTY_NEWLINE);
paul718e3742002-12-13 20:15:29 +00002693 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002694 }
2695 }
2696 return CMD_SUCCESS;
2697}
2698
2699/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002700static void
paulfd79ac92004-10-13 05:06:08 +00002701bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002702{
2703 int i;
2704 afi_t afi;
2705 safi_t safi;
2706 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002707 struct listnode *node, *nnode;
2708 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002709 struct bgp *bgp;
2710 struct peer *peer;
2711 struct peer_group *group;
2712 struct bgp_filter *filter;
2713 struct bgp_node *bn;
2714 struct bgp_static *bgp_static;
2715
Lou Berger82dd7072016-01-12 13:41:57 -05002716 if (bm->bgp == NULL) /* may be called during cleanup */
2717 return;
2718
paul718e3742002-12-13 20:15:29 +00002719 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002720 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002721 {
paul1eb8ef22005-04-07 07:30:20 +00002722 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002723 {
2724 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2725 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2726 {
2727 filter = &peer->filter[afi][safi];
2728
paulfee0f4c2004-09-13 05:12:46 +00002729 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002730 {
2731 if (filter->map[direct].name)
2732 filter->map[direct].map =
2733 route_map_lookup_by_name (filter->map[direct].name);
2734 else
2735 filter->map[direct].map = NULL;
2736 }
2737
2738 if (filter->usmap.name)
2739 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2740 else
2741 filter->usmap.map = NULL;
2742 }
2743 }
paul1eb8ef22005-04-07 07:30:20 +00002744 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002745 {
2746 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2747 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2748 {
2749 filter = &group->conf->filter[afi][safi];
2750
paulfee0f4c2004-09-13 05:12:46 +00002751 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002752 {
2753 if (filter->map[direct].name)
2754 filter->map[direct].map =
2755 route_map_lookup_by_name (filter->map[direct].name);
2756 else
2757 filter->map[direct].map = NULL;
2758 }
2759
2760 if (filter->usmap.name)
2761 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2762 else
2763 filter->usmap.map = NULL;
2764 }
2765 }
2766 }
2767
2768 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002769 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002770 {
paul1eb8ef22005-04-07 07:30:20 +00002771 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002772 {
2773 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2774 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2775 {
2776 if (peer->default_rmap[afi][safi].name)
2777 peer->default_rmap[afi][safi].map =
2778 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2779 else
2780 peer->default_rmap[afi][safi].map = NULL;
2781 }
2782 }
2783 }
2784
2785 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002786 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002787 {
2788 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2789 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2790 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2791 bn = bgp_route_next (bn))
2792 if ((bgp_static = bn->info) != NULL)
2793 {
2794 if (bgp_static->rmap.name)
2795 bgp_static->rmap.map =
2796 route_map_lookup_by_name (bgp_static->rmap.name);
2797 else
2798 bgp_static->rmap.map = NULL;
2799 }
2800 }
2801
2802 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002803 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002804 {
2805 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2806 {
Donald Sharpf3cfc462016-01-07 09:33:28 -05002807 if (bgp->rmap[AFI_IP][i].name)
2808 bgp->rmap[AFI_IP][i].map =
2809 route_map_lookup_by_name (bgp->rmap[AFI_IP][i].name);
2810 if (bgp->rmap[AFI_IP6][i].name)
2811 bgp->rmap[AFI_IP6][i].map =
Andrej Ota220355d2016-05-09 20:49:01 +02002812 route_map_lookup_by_name (bgp->rmap[AFI_IP6][i].name);
paul718e3742002-12-13 20:15:29 +00002813 }
2814 }
2815}
David Lamparter6b0655a2014-06-04 06:53:35 +02002816
paulfee0f4c2004-09-13 05:12:46 +00002817DEFUN (match_peer,
2818 match_peer_cmd,
2819 "match peer (A.B.C.D|X:X::X:X)",
2820 MATCH_STR
2821 "Match peer address\n"
Igor Ryzhov93b493a2016-05-11 15:26:39 +03002822 "IP address of peer\n"
2823 "IPv6 address of peer\n")
paulfee0f4c2004-09-13 05:12:46 +00002824{
2825 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2826}
2827
2828DEFUN (match_peer_local,
2829 match_peer_local_cmd,
2830 "match peer local",
2831 MATCH_STR
2832 "Match peer address\n"
2833 "Static or Redistributed routes\n")
2834{
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +02002835 return bgp_route_match_add (vty, vty->index, "peer", "local");
paulfee0f4c2004-09-13 05:12:46 +00002836}
2837
2838DEFUN (no_match_peer,
2839 no_match_peer_cmd,
2840 "no match peer",
2841 NO_STR
2842 MATCH_STR
2843 "Match peer address\n")
2844{
2845 if (argc == 0)
2846 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2847
2848 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2849}
2850
2851ALIAS (no_match_peer,
2852 no_match_peer_val_cmd,
2853 "no match peer (A.B.C.D|X:X::X:X)",
2854 NO_STR
2855 MATCH_STR
2856 "Match peer address\n"
Igor Ryzhov93b493a2016-05-11 15:26:39 +03002857 "IP address of peer\n"
2858 "IPv6 address of peer\n")
paulfee0f4c2004-09-13 05:12:46 +00002859
2860ALIAS (no_match_peer,
2861 no_match_peer_local_cmd,
2862 "no match peer local",
2863 NO_STR
2864 MATCH_STR
2865 "Match peer address\n"
2866 "Static or Redistributed routes\n")
2867
paul718e3742002-12-13 20:15:29 +00002868DEFUN (match_ip_address,
2869 match_ip_address_cmd,
2870 "match ip address (<1-199>|<1300-2699>|WORD)",
2871 MATCH_STR
2872 IP_STR
2873 "Match address of route\n"
2874 "IP access-list number\n"
2875 "IP access-list number (expanded range)\n"
2876 "IP Access-list name\n")
2877{
2878 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2879}
2880
2881DEFUN (no_match_ip_address,
2882 no_match_ip_address_cmd,
2883 "no match ip address",
2884 NO_STR
2885 MATCH_STR
2886 IP_STR
2887 "Match address of route\n")
2888{
2889 if (argc == 0)
2890 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2891
2892 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2893}
2894
2895ALIAS (no_match_ip_address,
2896 no_match_ip_address_val_cmd,
2897 "no match ip address (<1-199>|<1300-2699>|WORD)",
2898 NO_STR
2899 MATCH_STR
2900 IP_STR
2901 "Match address of route\n"
2902 "IP access-list number\n"
2903 "IP access-list number (expanded range)\n"
2904 "IP Access-list name\n")
2905
2906DEFUN (match_ip_next_hop,
2907 match_ip_next_hop_cmd,
2908 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2909 MATCH_STR
2910 IP_STR
2911 "Match next-hop address of route\n"
2912 "IP access-list number\n"
2913 "IP access-list number (expanded range)\n"
2914 "IP Access-list name\n")
2915{
2916 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2917}
2918
2919DEFUN (no_match_ip_next_hop,
2920 no_match_ip_next_hop_cmd,
2921 "no match ip next-hop",
2922 NO_STR
2923 MATCH_STR
2924 IP_STR
2925 "Match next-hop address of route\n")
2926{
2927 if (argc == 0)
2928 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2929
2930 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2931}
2932
2933ALIAS (no_match_ip_next_hop,
2934 no_match_ip_next_hop_val_cmd,
2935 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2936 NO_STR
2937 MATCH_STR
2938 IP_STR
2939 "Match next-hop address of route\n"
2940 "IP access-list number\n"
2941 "IP access-list number (expanded range)\n"
2942 "IP Access-list name\n")
2943
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04002944/* match probability { */
2945
2946DEFUN (match_probability,
2947 match_probability_cmd,
2948 "match probability <0-100>",
2949 MATCH_STR
2950 "Match portion of routes defined by percentage value\n"
2951 "Percentage of routes\n")
2952{
2953 return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
2954}
2955
2956DEFUN (no_match_probability,
2957 no_match_probability_cmd,
2958 "no match probability",
2959 NO_STR
2960 MATCH_STR
2961 "Match portion of routes defined by percentage value\n")
2962{
2963 return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL);
2964}
2965
2966ALIAS (no_match_probability,
2967 no_match_probability_val_cmd,
2968 "no match probability <1-99>",
2969 NO_STR
2970 MATCH_STR
2971 "Match portion of routes defined by percentage value\n"
2972 "Percentage of routes\n")
2973
2974/* } */
2975
hassoc1643bb2005-02-02 16:43:17 +00002976DEFUN (match_ip_route_source,
2977 match_ip_route_source_cmd,
2978 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2979 MATCH_STR
2980 IP_STR
2981 "Match advertising source address of route\n"
2982 "IP access-list number\n"
2983 "IP access-list number (expanded range)\n"
2984 "IP standard access-list name\n")
2985{
2986 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2987}
2988
2989DEFUN (no_match_ip_route_source,
2990 no_match_ip_route_source_cmd,
2991 "no match ip route-source",
2992 NO_STR
2993 MATCH_STR
2994 IP_STR
2995 "Match advertising source address of route\n")
2996{
2997 if (argc == 0)
2998 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2999
3000 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
3001}
3002
3003ALIAS (no_match_ip_route_source,
3004 no_match_ip_route_source_val_cmd,
3005 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
3006 NO_STR
3007 MATCH_STR
3008 IP_STR
3009 "Match advertising source address of route\n"
3010 "IP access-list number\n"
3011 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01003012 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00003013
paul718e3742002-12-13 20:15:29 +00003014DEFUN (match_ip_address_prefix_list,
3015 match_ip_address_prefix_list_cmd,
3016 "match ip address prefix-list WORD",
3017 MATCH_STR
3018 IP_STR
3019 "Match address of route\n"
3020 "Match entries of prefix-lists\n"
3021 "IP prefix-list name\n")
3022{
3023 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
3024}
3025
3026DEFUN (no_match_ip_address_prefix_list,
3027 no_match_ip_address_prefix_list_cmd,
3028 "no match ip address prefix-list",
3029 NO_STR
3030 MATCH_STR
3031 IP_STR
3032 "Match address of route\n"
3033 "Match entries of prefix-lists\n")
3034{
3035 if (argc == 0)
3036 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
3037
3038 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
3039}
3040
3041ALIAS (no_match_ip_address_prefix_list,
3042 no_match_ip_address_prefix_list_val_cmd,
3043 "no match ip address prefix-list WORD",
3044 NO_STR
3045 MATCH_STR
3046 IP_STR
3047 "Match address of route\n"
3048 "Match entries of prefix-lists\n"
3049 "IP prefix-list name\n")
3050
3051DEFUN (match_ip_next_hop_prefix_list,
3052 match_ip_next_hop_prefix_list_cmd,
3053 "match ip next-hop prefix-list WORD",
3054 MATCH_STR
3055 IP_STR
3056 "Match next-hop address of route\n"
3057 "Match entries of prefix-lists\n"
3058 "IP prefix-list name\n")
3059{
3060 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
3061}
3062
3063DEFUN (no_match_ip_next_hop_prefix_list,
3064 no_match_ip_next_hop_prefix_list_cmd,
3065 "no match ip next-hop prefix-list",
3066 NO_STR
3067 MATCH_STR
3068 IP_STR
3069 "Match next-hop address of route\n"
3070 "Match entries of prefix-lists\n")
3071{
3072 if (argc == 0)
3073 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
3074
3075 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
3076}
3077
3078ALIAS (no_match_ip_next_hop_prefix_list,
3079 no_match_ip_next_hop_prefix_list_val_cmd,
3080 "no match ip next-hop prefix-list WORD",
3081 NO_STR
3082 MATCH_STR
3083 IP_STR
3084 "Match next-hop address of route\n"
3085 "Match entries of prefix-lists\n"
3086 "IP prefix-list name\n")
3087
hassoc1643bb2005-02-02 16:43:17 +00003088DEFUN (match_ip_route_source_prefix_list,
3089 match_ip_route_source_prefix_list_cmd,
3090 "match ip route-source prefix-list WORD",
3091 MATCH_STR
3092 IP_STR
3093 "Match advertising source address of route\n"
3094 "Match entries of prefix-lists\n"
3095 "IP prefix-list name\n")
3096{
3097 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
3098}
3099
3100DEFUN (no_match_ip_route_source_prefix_list,
3101 no_match_ip_route_source_prefix_list_cmd,
3102 "no match ip route-source prefix-list",
3103 NO_STR
3104 MATCH_STR
3105 IP_STR
3106 "Match advertising source address of route\n"
3107 "Match entries of prefix-lists\n")
3108{
3109 if (argc == 0)
3110 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
3111
3112 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
3113}
3114
3115ALIAS (no_match_ip_route_source_prefix_list,
3116 no_match_ip_route_source_prefix_list_val_cmd,
3117 "no match ip route-source prefix-list WORD",
3118 NO_STR
3119 MATCH_STR
3120 IP_STR
3121 "Match advertising source address of route\n"
3122 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01003123 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00003124
paul718e3742002-12-13 20:15:29 +00003125DEFUN (match_metric,
3126 match_metric_cmd,
3127 "match metric <0-4294967295>",
3128 MATCH_STR
3129 "Match metric of route\n"
3130 "Metric value\n")
3131{
3132 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
3133}
3134
3135DEFUN (no_match_metric,
3136 no_match_metric_cmd,
3137 "no match metric",
3138 NO_STR
3139 MATCH_STR
3140 "Match metric of route\n")
3141{
3142 if (argc == 0)
3143 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
3144
3145 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
3146}
3147
3148ALIAS (no_match_metric,
3149 no_match_metric_val_cmd,
3150 "no match metric <0-4294967295>",
3151 NO_STR
3152 MATCH_STR
3153 "Match metric of route\n"
3154 "Metric value\n")
3155
Dinesh Dutt5cf768a2015-11-09 20:21:53 -05003156DEFUN (match_local_pref,
3157 match_local_pref_cmd,
3158 "match local-preference <0-4294967295>",
3159 MATCH_STR
3160 "Match local-preference of route\n"
3161 "Metric value\n")
3162{
3163 return bgp_route_match_add (vty, vty->index, "local-preference", argv[0]);
3164}
3165
3166DEFUN (no_match_local_pref,
3167 no_match_local_pref_cmd,
3168 "no match local-preference",
3169 NO_STR
3170 MATCH_STR
3171 "Match local preference of route\n")
3172{
3173 if (argc == 0)
3174 return bgp_route_match_delete (vty, vty->index, "local-preference", NULL);
3175
3176 return bgp_route_match_delete (vty, vty->index, "local-preference", argv[0]);
3177}
3178
3179ALIAS (no_match_local_pref,
3180 no_match_local_pref_val_cmd,
3181 "no match local-preference <0-4294967295>",
3182 NO_STR
3183 MATCH_STR
3184 "Match local preference of route\n"
3185 "Local preference value\n")
3186
paul718e3742002-12-13 20:15:29 +00003187DEFUN (match_community,
3188 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003189 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00003190 MATCH_STR
3191 "Match BGP community list\n"
3192 "Community-list number (standard)\n"
3193 "Community-list number (expanded)\n"
3194 "Community-list name\n")
3195{
3196 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
3197}
3198
3199DEFUN (match_community_exact,
3200 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003201 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00003202 MATCH_STR
3203 "Match BGP community list\n"
3204 "Community-list number (standard)\n"
3205 "Community-list number (expanded)\n"
3206 "Community-list name\n"
3207 "Do exact matching of communities\n")
3208{
3209 int ret;
3210 char *argstr;
3211
3212 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3213 strlen (argv[0]) + strlen ("exact-match") + 2);
3214
3215 sprintf (argstr, "%s exact-match", argv[0]);
3216
3217 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
3218
3219 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3220
3221 return ret;
3222}
3223
3224DEFUN (no_match_community,
3225 no_match_community_cmd,
3226 "no match community",
3227 NO_STR
3228 MATCH_STR
3229 "Match BGP community list\n")
3230{
3231 return bgp_route_match_delete (vty, vty->index, "community", NULL);
3232}
3233
3234ALIAS (no_match_community,
3235 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003236 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00003237 NO_STR
3238 MATCH_STR
3239 "Match BGP community list\n"
3240 "Community-list number (standard)\n"
3241 "Community-list number (expanded)\n"
3242 "Community-list name\n")
3243
3244ALIAS (no_match_community,
3245 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003246 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00003247 NO_STR
3248 MATCH_STR
3249 "Match BGP community list\n"
3250 "Community-list number (standard)\n"
3251 "Community-list number (expanded)\n"
3252 "Community-list name\n"
3253 "Do exact matching of communities\n")
3254
Job Snijders3334bab2017-01-20 14:47:12 +00003255DEFUN (match_lcommunity,
3256 match_lcommunity_cmd,
3257 "match large-community (<1-99>|<100-500>|WORD)",
3258 MATCH_STR
3259 "Match BGP large community list\n"
3260 "Large Community-list number (standard)\n"
3261 "Large Community-list number (expanded)\n"
3262 "Large Community-list name\n")
3263{
3264 return bgp_route_match_add (vty, vty->index, "large-community", argv[0]);
3265}
3266
3267DEFUN (no_match_lcommunity,
3268 no_match_lcommunity_cmd,
3269 "no match large-community (<1-99>|<100-500>|WORD)",
3270 NO_STR
3271 MATCH_STR
3272 "Match BGP large community list\n"
3273 "Large Community-list number (standard)\n"
3274 "Large Community-list number (expanded)\n"
3275 "Large Community-list name\n")
3276{
3277 return bgp_route_match_delete (vty, vty->index, "large-community", NULL);
3278}
3279
3280
paul73ffb252003-04-19 15:49:49 +00003281DEFUN (match_ecommunity,
3282 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003283 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00003284 MATCH_STR
3285 "Match BGP/VPN extended community list\n"
3286 "Extended community-list number (standard)\n"
3287 "Extended community-list number (expanded)\n"
3288 "Extended community-list name\n")
3289{
3290 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
3291}
3292
3293DEFUN (no_match_ecommunity,
3294 no_match_ecommunity_cmd,
3295 "no match extcommunity",
3296 NO_STR
3297 MATCH_STR
3298 "Match BGP/VPN extended community list\n")
3299{
3300 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
3301}
3302
3303ALIAS (no_match_ecommunity,
3304 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003305 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00003306 NO_STR
3307 MATCH_STR
3308 "Match BGP/VPN extended community list\n"
3309 "Extended community-list number (standard)\n"
3310 "Extended community-list number (expanded)\n"
3311 "Extended community-list name\n")
3312
paul718e3742002-12-13 20:15:29 +00003313DEFUN (match_aspath,
3314 match_aspath_cmd,
3315 "match as-path WORD",
3316 MATCH_STR
3317 "Match BGP AS path list\n"
3318 "AS path access-list name\n")
3319{
3320 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
3321}
3322
3323DEFUN (no_match_aspath,
3324 no_match_aspath_cmd,
3325 "no match as-path",
3326 NO_STR
3327 MATCH_STR
3328 "Match BGP AS path list\n")
3329{
3330 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
3331}
3332
3333ALIAS (no_match_aspath,
3334 no_match_aspath_val_cmd,
3335 "no match as-path WORD",
3336 NO_STR
3337 MATCH_STR
3338 "Match BGP AS path list\n"
3339 "AS path access-list name\n")
3340
3341DEFUN (match_origin,
3342 match_origin_cmd,
3343 "match origin (egp|igp|incomplete)",
3344 MATCH_STR
3345 "BGP origin code\n"
3346 "remote EGP\n"
3347 "local IGP\n"
3348 "unknown heritage\n")
3349{
3350 if (strncmp (argv[0], "igp", 2) == 0)
3351 return bgp_route_match_add (vty, vty->index, "origin", "igp");
3352 if (strncmp (argv[0], "egp", 1) == 0)
3353 return bgp_route_match_add (vty, vty->index, "origin", "egp");
3354 if (strncmp (argv[0], "incomplete", 2) == 0)
3355 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
3356
3357 return CMD_WARNING;
3358}
3359
3360DEFUN (no_match_origin,
3361 no_match_origin_cmd,
3362 "no match origin",
3363 NO_STR
3364 MATCH_STR
3365 "BGP origin code\n")
3366{
3367 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
3368}
3369
3370ALIAS (no_match_origin,
3371 no_match_origin_val_cmd,
3372 "no match origin (egp|igp|incomplete)",
3373 NO_STR
3374 MATCH_STR
3375 "BGP origin code\n"
3376 "remote EGP\n"
3377 "local IGP\n"
3378 "unknown heritage\n")
3379
Piotr Chytła605aa332015-12-01 10:03:54 -05003380DEFUN (match_tag,
3381 match_tag_cmd,
Christian Frankeddc160c2016-10-01 20:42:34 +02003382 "match tag <1-4294967295>",
Piotr Chytła605aa332015-12-01 10:03:54 -05003383 MATCH_STR
3384 "Match tag of route\n"
3385 "Tag value\n")
3386{
3387 return bgp_route_match_add (vty, vty->index, "tag", argv[0]);
3388}
3389
3390DEFUN (no_match_tag,
3391 no_match_tag_cmd,
3392 "no match tag",
3393 NO_STR
3394 MATCH_STR
3395 "Match tag of route\n")
3396{
3397 if (argc == 0)
3398 return bgp_route_match_delete (vty, vty->index, "tag", NULL);
3399
3400 return bgp_route_match_delete (vty, vty->index, "tag", argv[0]);
3401}
3402
3403ALIAS (no_match_tag,
3404 no_match_tag_val_cmd,
Christian Frankeddc160c2016-10-01 20:42:34 +02003405 "no match tag <1-4294967295>",
Piotr Chytła605aa332015-12-01 10:03:54 -05003406 NO_STR
3407 MATCH_STR
3408 "Match tag of route\n"
3409 "Tag value\n")
3410
paul718e3742002-12-13 20:15:29 +00003411DEFUN (set_ip_nexthop,
3412 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00003413 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003414 SET_STR
3415 IP_STR
3416 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00003417 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00003418{
3419 union sockunion su;
3420 int ret;
3421
3422 ret = str2sockunion (argv[0], &su);
3423 if (ret < 0)
3424 {
3425 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
3426 return CMD_WARNING;
3427 }
3428
3429 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
3430}
3431
paulaf5cd0a2003-11-02 07:24:40 +00003432DEFUN (set_ip_nexthop_peer,
3433 set_ip_nexthop_peer_cmd,
3434 "set ip next-hop peer-address",
3435 SET_STR
3436 IP_STR
3437 "Next hop address\n"
3438 "Use peer address (for BGP only)\n")
3439{
3440 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
3441}
3442
paul94f2b392005-06-28 12:44:16 +00003443DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00003444 no_set_ip_nexthop_peer_cmd,
3445 "no set ip next-hop peer-address",
3446 NO_STR
3447 SET_STR
3448 IP_STR
3449 "Next hop address\n"
3450 "Use peer address (for BGP only)\n")
3451{
3452 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
3453}
3454
3455
paul718e3742002-12-13 20:15:29 +00003456DEFUN (no_set_ip_nexthop,
3457 no_set_ip_nexthop_cmd,
3458 "no set ip next-hop",
3459 NO_STR
3460 SET_STR
paul718e3742002-12-13 20:15:29 +00003461 "Next hop address\n")
3462{
paulaf5cd0a2003-11-02 07:24:40 +00003463 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00003464 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
3465
3466 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
3467}
3468
3469ALIAS (no_set_ip_nexthop,
3470 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00003471 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003472 NO_STR
3473 SET_STR
3474 IP_STR
3475 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00003476 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00003477
3478DEFUN (set_metric,
3479 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00003480 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00003481 SET_STR
3482 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00003483 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00003484{
3485 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
3486}
3487
paul73ffb252003-04-19 15:49:49 +00003488ALIAS (set_metric,
3489 set_metric_addsub_cmd,
3490 "set metric <+/-metric>",
3491 SET_STR
3492 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00003493 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00003494
Timo Teräsef757702015-04-29 09:43:04 +03003495ALIAS (set_metric,
3496 set_metric_rtt_cmd,
3497 "set metric (rtt|+rtt|-rtt)",
3498 SET_STR
3499 "Metric value for destination routing protocol\n"
3500 "Assign round trip time\n"
3501 "Add round trip time\n"
3502 "Subtract round trip time\n")
3503
paul718e3742002-12-13 20:15:29 +00003504DEFUN (no_set_metric,
3505 no_set_metric_cmd,
3506 "no set metric",
3507 NO_STR
3508 SET_STR
3509 "Metric value for destination routing protocol\n")
3510{
3511 if (argc == 0)
3512 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
3513
3514 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
3515}
3516
3517ALIAS (no_set_metric,
3518 no_set_metric_val_cmd,
3519 "no set metric <0-4294967295>",
3520 NO_STR
3521 SET_STR
3522 "Metric value for destination routing protocol\n"
3523 "Metric value\n")
3524
3525DEFUN (set_local_pref,
3526 set_local_pref_cmd,
3527 "set local-preference <0-4294967295>",
3528 SET_STR
3529 "BGP local preference path attribute\n"
3530 "Preference value\n")
3531{
3532 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
3533}
3534
3535DEFUN (no_set_local_pref,
3536 no_set_local_pref_cmd,
3537 "no set local-preference",
3538 NO_STR
3539 SET_STR
3540 "BGP local preference path attribute\n")
3541{
3542 if (argc == 0)
3543 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3544
3545 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
3546}
3547
3548ALIAS (no_set_local_pref,
3549 no_set_local_pref_val_cmd,
3550 "no set local-preference <0-4294967295>",
3551 NO_STR
3552 SET_STR
3553 "BGP local preference path attribute\n"
3554 "Preference value\n")
3555
3556DEFUN (set_weight,
3557 set_weight_cmd,
3558 "set weight <0-4294967295>",
3559 SET_STR
3560 "BGP weight for routing table\n"
3561 "Weight value\n")
3562{
3563 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3564}
3565
3566DEFUN (no_set_weight,
3567 no_set_weight_cmd,
3568 "no set weight",
3569 NO_STR
3570 SET_STR
3571 "BGP weight for routing table\n")
3572{
3573 if (argc == 0)
3574 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3575
3576 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3577}
3578
3579ALIAS (no_set_weight,
3580 no_set_weight_val_cmd,
3581 "no set weight <0-4294967295>",
3582 NO_STR
3583 SET_STR
3584 "BGP weight for routing table\n"
3585 "Weight value\n")
3586
3587DEFUN (set_aspath_prepend,
3588 set_aspath_prepend_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003589 "set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003590 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003591 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003592 "Prepend to the as-path\n"
3593 "AS number\n")
3594{
3595 int ret;
3596 char *str;
3597
3598 str = argv_concat (argv, argc, 0);
3599 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3600 XFREE (MTYPE_TMP, str);
3601
3602 return ret;
3603}
3604
Timo Teräs85c854a2014-09-30 11:31:53 +03003605ALIAS (set_aspath_prepend,
3606 set_aspath_prepend_lastas_cmd,
3607 "set as-path prepend (last-as) <1-10>",
3608 SET_STR
3609 "Transform BGP AS_PATH attribute\n"
3610 "Prepend to the as-path\n"
3611 "Use the peer's AS-number\n"
David Lamparterb7d50212015-03-03 08:53:18 +01003612 "Number of times to insert")
Timo Teräs85c854a2014-09-30 11:31:53 +03003613
paul718e3742002-12-13 20:15:29 +00003614DEFUN (no_set_aspath_prepend,
3615 no_set_aspath_prepend_cmd,
3616 "no set as-path prepend",
3617 NO_STR
3618 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003619 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003620 "Prepend to the as-path\n")
3621{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00003622 int ret;
3623 char *str;
3624
3625 if (argc == 0)
3626 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3627
3628 str = argv_concat (argv, argc, 0);
3629 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3630 XFREE (MTYPE_TMP, str);
3631 return ret;
paul718e3742002-12-13 20:15:29 +00003632}
3633
3634ALIAS (no_set_aspath_prepend,
3635 no_set_aspath_prepend_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003636 "no set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003637 NO_STR
3638 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003639 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003640 "Prepend to the as-path\n"
3641 "AS number\n")
3642
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003643DEFUN (set_aspath_exclude,
3644 set_aspath_exclude_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003645 "set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003646 SET_STR
3647 "Transform BGP AS-path attribute\n"
3648 "Exclude from the as-path\n"
3649 "AS number\n")
3650{
3651 int ret;
3652 char *str;
3653
3654 str = argv_concat (argv, argc, 0);
3655 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3656 XFREE (MTYPE_TMP, str);
3657 return ret;
3658}
3659
3660DEFUN (no_set_aspath_exclude,
3661 no_set_aspath_exclude_cmd,
3662 "no set as-path exclude",
3663 NO_STR
3664 SET_STR
3665 "Transform BGP AS_PATH attribute\n"
3666 "Exclude from the as-path\n")
3667{
3668 int ret;
3669 char *str;
3670
3671 if (argc == 0)
3672 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3673
3674 str = argv_concat (argv, argc, 0);
3675 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3676 XFREE (MTYPE_TMP, str);
3677 return ret;
3678}
3679
3680ALIAS (no_set_aspath_exclude,
3681 no_set_aspath_exclude_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003682 "no set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003683 NO_STR
3684 SET_STR
3685 "Transform BGP AS_PATH attribute\n"
3686 "Exclude from the as-path\n"
3687 "AS number\n")
3688
paul718e3742002-12-13 20:15:29 +00003689DEFUN (set_community,
3690 set_community_cmd,
3691 "set community .AA:NN",
3692 SET_STR
3693 "BGP community attribute\n"
3694 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3695{
3696 int i;
3697 int first = 0;
3698 int additive = 0;
3699 struct buffer *b;
3700 struct community *com = NULL;
3701 char *str;
3702 char *argstr;
3703 int ret;
3704
3705 b = buffer_new (1024);
3706
3707 for (i = 0; i < argc; i++)
3708 {
3709 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3710 {
3711 additive = 1;
3712 continue;
3713 }
3714
3715 if (first)
3716 buffer_putc (b, ' ');
3717 else
3718 first = 1;
3719
3720 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3721 {
3722 buffer_putstr (b, "internet");
3723 continue;
3724 }
3725 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3726 {
3727 buffer_putstr (b, "local-AS");
3728 continue;
3729 }
3730 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3731 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3732 {
3733 buffer_putstr (b, "no-advertise");
3734 continue;
3735 }
3736 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3737 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3738 {
3739 buffer_putstr (b, "no-export");
3740 continue;
3741 }
3742 buffer_putstr (b, argv[i]);
3743 }
3744 buffer_putc (b, '\0');
3745
3746 /* Fetch result string then compile it to communities attribute. */
3747 str = buffer_getstr (b);
3748 buffer_free (b);
3749
3750 if (str)
3751 {
3752 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003753 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003754 }
3755
3756 /* Can't compile user input into communities attribute. */
3757 if (! com)
3758 {
3759 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3760 return CMD_WARNING;
3761 }
3762
3763 /* Set communites attribute string. */
3764 str = community_str (com);
3765
3766 if (additive)
3767 {
3768 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3769 strcpy (argstr, str);
3770 strcpy (argstr + strlen (str), " additive");
3771 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3772 XFREE (MTYPE_TMP, argstr);
3773 }
3774 else
3775 ret = bgp_route_set_add (vty, vty->index, "community", str);
3776
3777 community_free (com);
3778
3779 return ret;
3780}
3781
3782DEFUN (set_community_none,
3783 set_community_none_cmd,
3784 "set community none",
3785 SET_STR
3786 "BGP community attribute\n"
3787 "No community attribute\n")
3788{
3789 return bgp_route_set_add (vty, vty->index, "community", "none");
3790}
3791
3792DEFUN (no_set_community,
3793 no_set_community_cmd,
3794 "no set community",
3795 NO_STR
3796 SET_STR
3797 "BGP community attribute\n")
3798{
3799 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3800}
3801
3802ALIAS (no_set_community,
3803 no_set_community_val_cmd,
3804 "no set community .AA:NN",
3805 NO_STR
3806 SET_STR
3807 "BGP community attribute\n"
3808 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3809
3810ALIAS (no_set_community,
3811 no_set_community_none_cmd,
3812 "no set community none",
3813 NO_STR
3814 SET_STR
3815 "BGP community attribute\n"
3816 "No community attribute\n")
3817
3818DEFUN (set_community_delete,
3819 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003820 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003821 SET_STR
3822 "set BGP community list (for deletion)\n"
3823 "Community-list number (standard)\n"
Daniel Waltonc7f25b92015-05-19 17:47:22 -07003824 "Community-list number (expanded)\n"
paul718e3742002-12-13 20:15:29 +00003825 "Community-list name\n"
3826 "Delete matching communities\n")
3827{
3828 char *str;
3829
3830 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3831 strcpy (str, argv[0]);
3832 strcpy (str + strlen (argv[0]), " delete");
3833
3834 bgp_route_set_add (vty, vty->index, "comm-list", str);
3835
3836 XFREE (MTYPE_TMP, str);
3837 return CMD_SUCCESS;
3838}
3839
3840DEFUN (no_set_community_delete,
3841 no_set_community_delete_cmd,
3842 "no set comm-list",
3843 NO_STR
3844 SET_STR
3845 "set BGP community list (for deletion)\n")
3846{
3847 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3848}
3849
3850ALIAS (no_set_community_delete,
3851 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003852 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003853 NO_STR
3854 SET_STR
3855 "set BGP community list (for deletion)\n"
3856 "Community-list number (standard)\n"
Daniel Waltonc7f25b92015-05-19 17:47:22 -07003857 "Community-list number (expanded)\n"
paul718e3742002-12-13 20:15:29 +00003858 "Community-list name\n"
3859 "Delete matching communities\n")
3860
Job Snijders3334bab2017-01-20 14:47:12 +00003861
3862DEFUN (set_lcommunity,
3863 set_lcommunity_cmd,
3864 "set large-community .AA:BB:CC",
3865 SET_STR
3866 "BGP large community attribute\n"
3867 "Large Community number in aa:bb:cc format or additive\n")
3868{
3869 int ret;
3870 char *str;
3871
3872 str = argv_concat (argv, argc, 0);
3873 ret = bgp_route_set_add (vty, vty->index, "large-community", str);
3874 XFREE (MTYPE_TMP, str);
3875
3876 return ret;
3877}
3878
3879DEFUN (set_lcommunity_none,
3880 set_lcommunity_none_cmd,
3881 "set large-community none",
3882 SET_STR
3883 "BGP large community attribute\n"
3884 "No large community attribute\n")
3885{
3886 return bgp_route_set_add (vty, vty->index, "large-community", "none");
3887}
3888
3889DEFUN (no_set_lcommunity,
3890 no_set_lcommunity_cmd,
3891 "no set large-community",
3892 NO_STR
3893 SET_STR
3894 "BGP large community attribute\n"
3895 "Large community\n")
3896{
3897 return bgp_route_set_delete (vty, vty->index, "large-community", NULL);
3898}
3899
3900ALIAS (no_set_lcommunity,
3901 no_set_lcommunity_val_cmd,
3902 "no set large-community .AA:BB:CC",
3903 NO_STR
3904 SET_STR
3905 "BGP large community attribute\n"
3906 "Large community in .AA:BB:CC format or additive\n")
3907
3908ALIAS (no_set_lcommunity,
3909 no_set_lcommunity_none_cmd,
3910 "no set large-community none",
3911 NO_STR
3912 SET_STR
3913 "BGP community attribute\n"
3914 "No community attribute\n")
3915
3916DEFUN (set_lcommunity_delete,
3917 set_lcommunity_delete_cmd,
3918 "set large-comm-list (<1-99>|<100-500>|WORD) delete",
3919 SET_STR
3920 "set BGP large community list (for deletion)\n"
3921 "Large Community-list number (standard)\n"
3922 "Large Communitly-list number (expanded)\n"
3923 "Large Community-list name\n"
3924 "Delete matching large communities\n")
3925{
3926 char *str;
3927
3928 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3929 strcpy (str, argv[0]);
3930 strcpy (str + strlen (argv[0]), " delete");
3931
3932 bgp_route_set_add (vty, vty->index, "large-comm-list", str);
3933
3934 XFREE (MTYPE_TMP, str);
3935 return CMD_SUCCESS;
3936}
3937
3938DEFUN (no_set_lcommunity_delete,
3939 no_set_lcommunity_delete_cmd,
3940 "no set large-comm-list",
3941 NO_STR
3942 SET_STR
3943 "set BGP large community list (for deletion)\n")
3944{
3945 return bgp_route_set_delete (vty, vty->index, "large-comm-list", NULL);
3946}
3947
3948ALIAS (no_set_lcommunity_delete,
3949 no_set_lcommunity_delete_val_cmd,
3950 "no set large-comm-list (<1-99>|<100-500>|WORD) delete",
3951 NO_STR
3952 SET_STR
3953 "set BGP large community list (for deletion)\n"
3954 "Large Community-list number (standard)\n"
3955 "Large Communitly-list number (expanded)\n"
3956 "Large Community-list name\n"
3957 "Delete matching large communities\n")
3958
paul718e3742002-12-13 20:15:29 +00003959DEFUN (set_ecommunity_rt,
3960 set_ecommunity_rt_cmd,
3961 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3962 SET_STR
3963 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003964 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003965 "VPN extended community\n")
3966{
3967 int ret;
3968 char *str;
3969
3970 str = argv_concat (argv, argc, 0);
3971 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3972 XFREE (MTYPE_TMP, str);
3973
3974 return ret;
3975}
3976
3977DEFUN (no_set_ecommunity_rt,
3978 no_set_ecommunity_rt_cmd,
3979 "no set extcommunity rt",
3980 NO_STR
3981 SET_STR
3982 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003983 "Route Target extended community\n")
paul718e3742002-12-13 20:15:29 +00003984{
3985 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3986}
3987
3988ALIAS (no_set_ecommunity_rt,
3989 no_set_ecommunity_rt_val_cmd,
3990 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3991 NO_STR
3992 SET_STR
3993 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003994 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003995 "VPN extended community\n")
3996
3997DEFUN (set_ecommunity_soo,
3998 set_ecommunity_soo_cmd,
3999 "set extcommunity soo .ASN:nn_or_IP-address:nn",
4000 SET_STR
4001 "BGP extended community attribute\n"
4002 "Site-of-Origin extended community\n"
4003 "VPN extended community\n")
4004{
4005 int ret;
4006 char *str;
4007
4008 str = argv_concat (argv, argc, 0);
4009 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
4010 XFREE (MTYPE_TMP, str);
4011 return ret;
4012}
4013
4014DEFUN (no_set_ecommunity_soo,
4015 no_set_ecommunity_soo_cmd,
4016 "no set extcommunity soo",
4017 NO_STR
4018 SET_STR
4019 "BGP extended community attribute\n"
4020 "Site-of-Origin extended community\n")
4021{
4022 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
4023}
4024
4025ALIAS (no_set_ecommunity_soo,
4026 no_set_ecommunity_soo_val_cmd,
4027 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
4028 NO_STR
4029 SET_STR
4030 "BGP extended community attribute\n"
4031 "Site-of-Origin extended community\n"
4032 "VPN extended community\n")
4033
4034DEFUN (set_origin,
4035 set_origin_cmd,
4036 "set origin (egp|igp|incomplete)",
4037 SET_STR
4038 "BGP origin code\n"
4039 "remote EGP\n"
4040 "local IGP\n"
4041 "unknown heritage\n")
4042{
4043 if (strncmp (argv[0], "igp", 2) == 0)
4044 return bgp_route_set_add (vty, vty->index, "origin", "igp");
4045 if (strncmp (argv[0], "egp", 1) == 0)
4046 return bgp_route_set_add (vty, vty->index, "origin", "egp");
4047 if (strncmp (argv[0], "incomplete", 2) == 0)
4048 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
4049
4050 return CMD_WARNING;
4051}
4052
4053DEFUN (no_set_origin,
4054 no_set_origin_cmd,
4055 "no set origin",
4056 NO_STR
4057 SET_STR
4058 "BGP origin code\n")
4059{
4060 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
4061}
4062
4063ALIAS (no_set_origin,
4064 no_set_origin_val_cmd,
4065 "no set origin (egp|igp|incomplete)",
4066 NO_STR
4067 SET_STR
4068 "BGP origin code\n"
4069 "remote EGP\n"
4070 "local IGP\n"
4071 "unknown heritage\n")
4072
4073DEFUN (set_atomic_aggregate,
4074 set_atomic_aggregate_cmd,
4075 "set atomic-aggregate",
4076 SET_STR
4077 "BGP atomic aggregate attribute\n" )
4078{
4079 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
4080}
4081
4082DEFUN (no_set_atomic_aggregate,
4083 no_set_atomic_aggregate_cmd,
4084 "no set atomic-aggregate",
4085 NO_STR
4086 SET_STR
4087 "BGP atomic aggregate attribute\n" )
4088{
4089 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
4090}
4091
4092DEFUN (set_aggregator_as,
4093 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00004094 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00004095 SET_STR
4096 "BGP aggregator attribute\n"
4097 "AS number of aggregator\n"
4098 "AS number\n"
4099 "IP address of aggregator\n")
4100{
4101 int ret;
Paul Jakma7aa9dce2014-09-19 14:42:23 +01004102 as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
paul718e3742002-12-13 20:15:29 +00004103 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00004104 char *argstr;
4105
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00004106 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00004107
paul718e3742002-12-13 20:15:29 +00004108 ret = inet_aton (argv[1], &address);
4109 if (ret == 0)
4110 {
4111 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
4112 return CMD_WARNING;
4113 }
4114
4115 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
4116 strlen (argv[0]) + strlen (argv[1]) + 2);
4117
4118 sprintf (argstr, "%s %s", argv[0], argv[1]);
4119
4120 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
4121
4122 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
4123
4124 return ret;
4125}
4126
4127DEFUN (no_set_aggregator_as,
4128 no_set_aggregator_as_cmd,
4129 "no set aggregator as",
4130 NO_STR
4131 SET_STR
4132 "BGP aggregator attribute\n"
4133 "AS number of aggregator\n")
4134{
4135 int ret;
Paul Jakma7aa9dce2014-09-19 14:42:23 +01004136 as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
paul718e3742002-12-13 20:15:29 +00004137 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00004138 char *argstr;
4139
4140 if (argv == 0)
4141 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
4142
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00004143 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00004144
4145 ret = inet_aton (argv[1], &address);
4146 if (ret == 0)
4147 {
4148 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
4149 return CMD_WARNING;
4150 }
4151
4152 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
4153 strlen (argv[0]) + strlen (argv[1]) + 2);
4154
4155 sprintf (argstr, "%s %s", argv[0], argv[1]);
4156
4157 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
4158
4159 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
4160
4161 return ret;
4162}
4163
4164ALIAS (no_set_aggregator_as,
4165 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00004166 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00004167 NO_STR
4168 SET_STR
4169 "BGP aggregator attribute\n"
4170 "AS number of aggregator\n"
4171 "AS number\n"
4172 "IP address of aggregator\n")
4173
Piotr Chytła605aa332015-12-01 10:03:54 -05004174DEFUN (set_tag,
4175 set_tag_cmd,
Christian Frankeddc160c2016-10-01 20:42:34 +02004176 "set tag <1-4294967295>",
Piotr Chytła605aa332015-12-01 10:03:54 -05004177 SET_STR
4178 "Tag value for routing protocol\n"
4179 "Tag value\n")
4180{
4181 return bgp_route_set_add (vty, vty->index, "tag", argv[0]);
4182}
4183
4184DEFUN (no_set_tag,
4185 no_set_tag_cmd,
4186 "no set tag",
4187 NO_STR
4188 SET_STR
4189 "Tag value for routing protocol\n")
4190{
4191 if (argc == 0)
4192 bgp_route_set_delete(vty, vty->index, "tag", NULL);
4193
4194 return bgp_route_set_delete (vty, vty->index, "tag", argv[0]);
4195}
4196
4197ALIAS (no_set_tag,
4198 no_set_tag_val_cmd,
Christian Frankeddc160c2016-10-01 20:42:34 +02004199 "no set tag <1-4294967295>",
Piotr Chytła605aa332015-12-01 10:03:54 -05004200 NO_STR
4201 SET_STR
4202 "Tag value for routing protocol\n"
4203 "Tag value\n")
4204
4205
paul718e3742002-12-13 20:15:29 +00004206DEFUN (match_ipv6_address,
4207 match_ipv6_address_cmd,
4208 "match ipv6 address WORD",
4209 MATCH_STR
4210 IPV6_STR
4211 "Match IPv6 address of route\n"
4212 "IPv6 access-list name\n")
4213{
4214 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
4215}
4216
4217DEFUN (no_match_ipv6_address,
4218 no_match_ipv6_address_cmd,
4219 "no match ipv6 address WORD",
4220 NO_STR
4221 MATCH_STR
4222 IPV6_STR
4223 "Match IPv6 address of route\n"
4224 "IPv6 access-list name\n")
4225{
4226 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
4227}
4228
4229DEFUN (match_ipv6_next_hop,
4230 match_ipv6_next_hop_cmd,
4231 "match ipv6 next-hop X:X::X:X",
4232 MATCH_STR
4233 IPV6_STR
4234 "Match IPv6 next-hop address of route\n"
4235 "IPv6 address of next hop\n")
4236{
4237 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
4238}
4239
4240DEFUN (no_match_ipv6_next_hop,
4241 no_match_ipv6_next_hop_cmd,
4242 "no match ipv6 next-hop X:X::X:X",
4243 NO_STR
4244 MATCH_STR
4245 IPV6_STR
4246 "Match IPv6 next-hop address of route\n"
4247 "IPv6 address of next hop\n")
4248{
4249 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
4250}
4251
4252DEFUN (match_ipv6_address_prefix_list,
4253 match_ipv6_address_prefix_list_cmd,
4254 "match ipv6 address prefix-list WORD",
4255 MATCH_STR
4256 IPV6_STR
4257 "Match address of route\n"
4258 "Match entries of prefix-lists\n"
4259 "IP prefix-list name\n")
4260{
4261 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
4262}
4263
4264DEFUN (no_match_ipv6_address_prefix_list,
4265 no_match_ipv6_address_prefix_list_cmd,
4266 "no match ipv6 address prefix-list WORD",
4267 NO_STR
4268 MATCH_STR
4269 IPV6_STR
4270 "Match address of route\n"
4271 "Match entries of prefix-lists\n"
4272 "IP prefix-list name\n")
4273{
4274 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
4275}
4276
Dinesh G Duttad5233a2014-09-30 14:19:57 -07004277DEFUN (set_ipv6_nexthop_peer,
4278 set_ipv6_nexthop_peer_cmd,
4279 "set ipv6 next-hop peer-address",
4280 SET_STR
4281 IPV6_STR
4282 "Next hop address\n"
4283 "Use peer address (for BGP only)\n")
4284{
4285 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop peer-address", NULL);
4286}
4287
4288DEFUN (no_set_ipv6_nexthop_peer,
4289 no_set_ipv6_nexthop_peer_cmd,
4290 "no set ipv6 next-hop peer-address",
4291 NO_STR
4292 SET_STR
4293 IPV6_STR
4294 "IPv6 next-hop address\n"
4295 )
4296{
4297 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
4298}
4299
paul718e3742002-12-13 20:15:29 +00004300DEFUN (set_ipv6_nexthop_global,
4301 set_ipv6_nexthop_global_cmd,
4302 "set ipv6 next-hop global X:X::X:X",
4303 SET_STR
4304 IPV6_STR
4305 "IPv6 next-hop address\n"
4306 "IPv6 global address\n"
4307 "IPv6 address of next hop\n")
4308{
4309 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
4310}
4311
4312DEFUN (no_set_ipv6_nexthop_global,
4313 no_set_ipv6_nexthop_global_cmd,
4314 "no set ipv6 next-hop global",
4315 NO_STR
4316 SET_STR
4317 IPV6_STR
4318 "IPv6 next-hop address\n"
4319 "IPv6 global address\n")
4320{
4321 if (argc == 0)
4322 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
4323
4324 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
4325}
4326
4327ALIAS (no_set_ipv6_nexthop_global,
4328 no_set_ipv6_nexthop_global_val_cmd,
4329 "no set ipv6 next-hop global X:X::X:X",
4330 NO_STR
4331 SET_STR
4332 IPV6_STR
4333 "IPv6 next-hop address\n"
4334 "IPv6 global address\n"
4335 "IPv6 address of next hop\n")
4336
4337DEFUN (set_ipv6_nexthop_local,
4338 set_ipv6_nexthop_local_cmd,
4339 "set ipv6 next-hop local X:X::X:X",
4340 SET_STR
4341 IPV6_STR
4342 "IPv6 next-hop address\n"
4343 "IPv6 local address\n"
4344 "IPv6 address of next hop\n")
4345{
4346 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
4347}
4348
4349DEFUN (no_set_ipv6_nexthop_local,
4350 no_set_ipv6_nexthop_local_cmd,
4351 "no set ipv6 next-hop local",
4352 NO_STR
4353 SET_STR
4354 IPV6_STR
4355 "IPv6 next-hop address\n"
4356 "IPv6 local address\n")
4357{
4358 if (argc == 0)
4359 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
4360
4361 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
4362}
4363
4364ALIAS (no_set_ipv6_nexthop_local,
4365 no_set_ipv6_nexthop_local_val_cmd,
4366 "no set ipv6 next-hop local X:X::X:X",
4367 NO_STR
4368 SET_STR
4369 IPV6_STR
4370 "IPv6 next-hop address\n"
4371 "IPv6 local address\n"
4372 "IPv6 address of next hop\n")
paul718e3742002-12-13 20:15:29 +00004373
4374DEFUN (set_vpnv4_nexthop,
4375 set_vpnv4_nexthop_cmd,
4376 "set vpnv4 next-hop A.B.C.D",
4377 SET_STR
4378 "VPNv4 information\n"
4379 "VPNv4 next-hop address\n"
4380 "IP address of next hop\n")
4381{
4382 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
4383}
4384
4385DEFUN (no_set_vpnv4_nexthop,
4386 no_set_vpnv4_nexthop_cmd,
4387 "no set vpnv4 next-hop",
4388 NO_STR
4389 SET_STR
4390 "VPNv4 information\n"
4391 "VPNv4 next-hop address\n")
4392{
4393 if (argc == 0)
4394 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
4395
4396 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
4397}
4398
4399ALIAS (no_set_vpnv4_nexthop,
4400 no_set_vpnv4_nexthop_val_cmd,
4401 "no set vpnv4 next-hop A.B.C.D",
4402 NO_STR
4403 SET_STR
4404 "VPNv4 information\n"
4405 "VPNv4 next-hop address\n"
4406 "IP address of next hop\n")
4407
4408DEFUN (set_originator_id,
4409 set_originator_id_cmd,
4410 "set originator-id A.B.C.D",
4411 SET_STR
4412 "BGP originator ID attribute\n"
4413 "IP address of originator\n")
4414{
4415 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
4416}
4417
4418DEFUN (no_set_originator_id,
4419 no_set_originator_id_cmd,
4420 "no set originator-id",
4421 NO_STR
4422 SET_STR
4423 "BGP originator ID attribute\n")
4424{
4425 if (argc == 0)
4426 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
4427
4428 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
4429}
4430
4431ALIAS (no_set_originator_id,
4432 no_set_originator_id_val_cmd,
4433 "no set originator-id A.B.C.D",
4434 NO_STR
4435 SET_STR
4436 "BGP originator ID attribute\n"
4437 "IP address of originator\n")
4438
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004439DEFUN_DEPRECATED (set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00004440 set_pathlimit_ttl_cmd,
4441 "set pathlimit ttl <1-255>",
4442 SET_STR
4443 "BGP AS-Pathlimit attribute\n"
4444 "Set AS-Path Hop-count TTL\n")
4445{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004446 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00004447}
4448
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004449DEFUN_DEPRECATED (no_set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00004450 no_set_pathlimit_ttl_cmd,
4451 "no set pathlimit ttl",
4452 NO_STR
4453 SET_STR
4454 "BGP AS-Pathlimit attribute\n"
4455 "Set AS-Path Hop-count TTL\n")
4456{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004457 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00004458}
4459
4460ALIAS (no_set_pathlimit_ttl,
4461 no_set_pathlimit_ttl_val_cmd,
4462 "no set pathlimit ttl <1-255>",
4463 NO_STR
4464 MATCH_STR
4465 "BGP AS-Pathlimit attribute\n"
4466 "Set AS-Path Hop-count TTL\n")
4467
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004468DEFUN_DEPRECATED (match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00004469 match_pathlimit_as_cmd,
4470 "match pathlimit as <1-65535>",
4471 MATCH_STR
4472 "BGP AS-Pathlimit attribute\n"
4473 "Match Pathlimit AS number\n")
4474{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004475 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00004476}
4477
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004478DEFUN_DEPRECATED (no_match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00004479 no_match_pathlimit_as_cmd,
4480 "no match pathlimit as",
4481 NO_STR
4482 MATCH_STR
4483 "BGP AS-Pathlimit attribute\n"
4484 "Match Pathlimit AS number\n")
4485{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004486 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00004487}
4488
4489ALIAS (no_match_pathlimit_as,
4490 no_match_pathlimit_as_val_cmd,
4491 "no match pathlimit as <1-65535>",
4492 NO_STR
4493 MATCH_STR
4494 "BGP AS-Pathlimit attribute\n"
4495 "Match Pathlimit ASN\n")
4496
David Lamparter6b0655a2014-06-04 06:53:35 +02004497
paul718e3742002-12-13 20:15:29 +00004498/* Initialization of route map. */
4499void
paul94f2b392005-06-28 12:44:16 +00004500bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00004501{
4502 route_map_init ();
4503 route_map_init_vty ();
4504 route_map_add_hook (bgp_route_map_update);
4505 route_map_delete_hook (bgp_route_map_update);
4506
paulfee0f4c2004-09-13 05:12:46 +00004507 route_map_install_match (&route_match_peer_cmd);
Dinesh Dutt5cf768a2015-11-09 20:21:53 -05004508 route_map_install_match (&route_match_local_pref_cmd);
paul718e3742002-12-13 20:15:29 +00004509 route_map_install_match (&route_match_ip_address_cmd);
4510 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00004511 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00004512 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
4513 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00004514 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00004515 route_map_install_match (&route_match_aspath_cmd);
4516 route_map_install_match (&route_match_community_cmd);
Job Snijders3334bab2017-01-20 14:47:12 +00004517 route_map_install_match (&route_match_lcommunity_cmd);
paul73ffb252003-04-19 15:49:49 +00004518 route_map_install_match (&route_match_ecommunity_cmd);
Dinesh Dutt5cf768a2015-11-09 20:21:53 -05004519 route_map_install_match (&route_match_local_pref_cmd);
paul718e3742002-12-13 20:15:29 +00004520 route_map_install_match (&route_match_metric_cmd);
4521 route_map_install_match (&route_match_origin_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04004522 route_map_install_match (&route_match_probability_cmd);
Piotr Chytła605aa332015-12-01 10:03:54 -05004523 route_map_install_match (&route_match_tag_cmd);
paul718e3742002-12-13 20:15:29 +00004524
4525 route_map_install_set (&route_set_ip_nexthop_cmd);
4526 route_map_install_set (&route_set_local_pref_cmd);
4527 route_map_install_set (&route_set_weight_cmd);
4528 route_map_install_set (&route_set_metric_cmd);
4529 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00004530 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00004531 route_map_install_set (&route_set_origin_cmd);
4532 route_map_install_set (&route_set_atomic_aggregate_cmd);
4533 route_map_install_set (&route_set_aggregator_as_cmd);
4534 route_map_install_set (&route_set_community_cmd);
4535 route_map_install_set (&route_set_community_delete_cmd);
Job Snijders3334bab2017-01-20 14:47:12 +00004536 route_map_install_set (&route_set_lcommunity_cmd);
4537 route_map_install_set (&route_set_lcommunity_delete_cmd);
paul718e3742002-12-13 20:15:29 +00004538 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
4539 route_map_install_set (&route_set_originator_id_cmd);
4540 route_map_install_set (&route_set_ecommunity_rt_cmd);
4541 route_map_install_set (&route_set_ecommunity_soo_cmd);
Piotr Chytła605aa332015-12-01 10:03:54 -05004542 route_map_install_set (&route_set_tag_cmd);
paul718e3742002-12-13 20:15:29 +00004543
paulfee0f4c2004-09-13 05:12:46 +00004544 install_element (RMAP_NODE, &match_peer_cmd);
4545 install_element (RMAP_NODE, &match_peer_local_cmd);
4546 install_element (RMAP_NODE, &no_match_peer_cmd);
4547 install_element (RMAP_NODE, &no_match_peer_val_cmd);
4548 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00004549 install_element (RMAP_NODE, &match_ip_address_cmd);
4550 install_element (RMAP_NODE, &no_match_ip_address_cmd);
4551 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
4552 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
4553 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
4554 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00004555 install_element (RMAP_NODE, &match_ip_route_source_cmd);
4556 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
4557 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00004558 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
4559 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
4560 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
4561 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
4562 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
4563 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00004564 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
4565 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
4566 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00004567
4568 install_element (RMAP_NODE, &match_aspath_cmd);
4569 install_element (RMAP_NODE, &no_match_aspath_cmd);
4570 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
4571 install_element (RMAP_NODE, &match_metric_cmd);
4572 install_element (RMAP_NODE, &no_match_metric_cmd);
4573 install_element (RMAP_NODE, &no_match_metric_val_cmd);
Dinesh Dutt5cf768a2015-11-09 20:21:53 -05004574 install_element (RMAP_NODE, &match_local_pref_cmd);
4575 install_element (RMAP_NODE, &no_match_local_pref_cmd);
4576 install_element (RMAP_NODE, &no_match_local_pref_val_cmd);
paul718e3742002-12-13 20:15:29 +00004577 install_element (RMAP_NODE, &match_community_cmd);
4578 install_element (RMAP_NODE, &match_community_exact_cmd);
4579 install_element (RMAP_NODE, &no_match_community_cmd);
4580 install_element (RMAP_NODE, &no_match_community_val_cmd);
4581 install_element (RMAP_NODE, &no_match_community_exact_cmd);
Job Snijders3334bab2017-01-20 14:47:12 +00004582 install_element (RMAP_NODE, &match_lcommunity_cmd);
4583 install_element (RMAP_NODE, &no_match_lcommunity_cmd);
paul73ffb252003-04-19 15:49:49 +00004584 install_element (RMAP_NODE, &match_ecommunity_cmd);
4585 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
4586 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00004587 install_element (RMAP_NODE, &match_origin_cmd);
4588 install_element (RMAP_NODE, &no_match_origin_cmd);
4589 install_element (RMAP_NODE, &no_match_origin_val_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04004590 install_element (RMAP_NODE, &match_probability_cmd);
4591 install_element (RMAP_NODE, &no_match_probability_cmd);
4592 install_element (RMAP_NODE, &no_match_probability_val_cmd);
Piotr Chytła605aa332015-12-01 10:03:54 -05004593 install_element (RMAP_NODE, &match_tag_cmd);
4594 install_element (RMAP_NODE, &no_match_tag_cmd);
4595 install_element (RMAP_NODE, &no_match_tag_val_cmd);
paul718e3742002-12-13 20:15:29 +00004596
4597 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00004598 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00004599 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
4600 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
4601 install_element (RMAP_NODE, &set_local_pref_cmd);
4602 install_element (RMAP_NODE, &no_set_local_pref_cmd);
4603 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
4604 install_element (RMAP_NODE, &set_weight_cmd);
4605 install_element (RMAP_NODE, &no_set_weight_cmd);
4606 install_element (RMAP_NODE, &no_set_weight_val_cmd);
4607 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00004608 install_element (RMAP_NODE, &set_metric_addsub_cmd);
Timo Teräsef757702015-04-29 09:43:04 +03004609 install_element (RMAP_NODE, &set_metric_rtt_cmd);
paul718e3742002-12-13 20:15:29 +00004610 install_element (RMAP_NODE, &no_set_metric_cmd);
4611 install_element (RMAP_NODE, &no_set_metric_val_cmd);
4612 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Timo Teräs85c854a2014-09-30 11:31:53 +03004613 install_element (RMAP_NODE, &set_aspath_prepend_lastas_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00004614 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00004615 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
4616 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00004617 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
4618 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00004619 install_element (RMAP_NODE, &set_origin_cmd);
4620 install_element (RMAP_NODE, &no_set_origin_cmd);
4621 install_element (RMAP_NODE, &no_set_origin_val_cmd);
4622 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
4623 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
4624 install_element (RMAP_NODE, &set_aggregator_as_cmd);
4625 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
4626 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
4627 install_element (RMAP_NODE, &set_community_cmd);
4628 install_element (RMAP_NODE, &set_community_none_cmd);
4629 install_element (RMAP_NODE, &no_set_community_cmd);
4630 install_element (RMAP_NODE, &no_set_community_val_cmd);
4631 install_element (RMAP_NODE, &no_set_community_none_cmd);
4632 install_element (RMAP_NODE, &set_community_delete_cmd);
4633 install_element (RMAP_NODE, &no_set_community_delete_cmd);
4634 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
Job Snijders3334bab2017-01-20 14:47:12 +00004635 install_element (RMAP_NODE, &set_lcommunity_cmd);
4636 install_element (RMAP_NODE, &set_lcommunity_none_cmd);
4637 install_element (RMAP_NODE, &no_set_lcommunity_cmd);
4638 install_element (RMAP_NODE, &no_set_lcommunity_val_cmd);
4639 install_element (RMAP_NODE, &no_set_lcommunity_none_cmd);
4640 install_element (RMAP_NODE, &set_lcommunity_delete_cmd);
4641 install_element (RMAP_NODE, &no_set_lcommunity_delete_cmd);
4642 install_element (RMAP_NODE, &no_set_lcommunity_delete_val_cmd);
paul718e3742002-12-13 20:15:29 +00004643 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
4644 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
4645 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
4646 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
4647 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
4648 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
4649 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
4650 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
4651 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
4652 install_element (RMAP_NODE, &set_originator_id_cmd);
4653 install_element (RMAP_NODE, &no_set_originator_id_cmd);
4654 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
Piotr Chytła605aa332015-12-01 10:03:54 -05004655 install_element (RMAP_NODE, &set_tag_cmd);
4656 install_element (RMAP_NODE, &no_set_tag_cmd);
4657 install_element (RMAP_NODE, &no_set_tag_val_cmd);
paul718e3742002-12-13 20:15:29 +00004658
paul718e3742002-12-13 20:15:29 +00004659 route_map_install_match (&route_match_ipv6_address_cmd);
4660 route_map_install_match (&route_match_ipv6_next_hop_cmd);
4661 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
4662 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
4663 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Dinesh G Duttad5233a2014-09-30 14:19:57 -07004664 route_map_install_set (&route_set_ipv6_nexthop_peer_cmd);
4665
paul718e3742002-12-13 20:15:29 +00004666 install_element (RMAP_NODE, &match_ipv6_address_cmd);
4667 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
4668 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
4669 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
4670 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
4671 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
4672 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
4673 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
4674 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
4675 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
4676 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
4677 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
Dinesh G Duttad5233a2014-09-30 14:19:57 -07004678 install_element (RMAP_NODE, &set_ipv6_nexthop_peer_cmd);
4679 install_element (RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd);
Paul Jakma41367172007-08-06 15:24:51 +00004680
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004681 /* AS-Pathlimit: functionality removed, commands kept for
4682 * compatibility.
4683 */
Paul Jakma41367172007-08-06 15:24:51 +00004684 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
4685 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
4686 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
4687 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
4688 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
4689 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00004690}