blob: 857781fea99b5a8a5b8ec3a10107762d9c2e1116 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* Route map function of bgpd.
2 Copyright (C) 1998, 1999 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "prefix.h"
24#include "filter.h"
25#include "routemap.h"
26#include "command.h"
27#include "linklist.h"
28#include "plist.h"
29#include "memory.h"
30#include "log.h"
Jeremy Jackson25f45882009-01-12 16:06:12 -050031#ifdef HAVE_LIBPCREPOSIX
32# include <pcreposix.h>
paul718e3742002-12-13 20:15:29 +000033#else
Jeremy Jackson25f45882009-01-12 16:06:12 -050034# ifdef HAVE_GNU_REGEX
35# include <regex.h>
36# else
37# include "regex-gnu.h"
38# endif /* HAVE_GNU_REGEX */
39#endif /* HAVE_LIBPCREPOSIX */
paul718e3742002-12-13 20:15:29 +000040#include "buffer.h"
41#include "sockunion.h"
42
43#include "bgpd/bgpd.h"
44#include "bgpd/bgp_table.h"
45#include "bgpd/bgp_attr.h"
46#include "bgpd/bgp_aspath.h"
47#include "bgpd/bgp_route.h"
48#include "bgpd/bgp_regex.h"
49#include "bgpd/bgp_community.h"
50#include "bgpd/bgp_clist.h"
51#include "bgpd/bgp_filter.h"
52#include "bgpd/bgp_mplsvpn.h"
53#include "bgpd/bgp_ecommunity.h"
Paul Jakma320da872008-07-02 13:40:33 +000054#include "bgpd/bgp_vty.h"
paul718e3742002-12-13 20:15:29 +000055
56/* Memo of route-map commands.
57
58o Cisco route-map
59
60 match as-path : Done
61 community : Done
62 interface : Not yet
63 ip address : Done
64 ip next-hop : Done
hassoc1643bb2005-02-02 16:43:17 +000065 ip route-source : Done
paul718e3742002-12-13 20:15:29 +000066 ip prefix-list : Done
67 ipv6 address : Done
68 ipv6 next-hop : Done
69 ipv6 route-source: (This will not be implemented by bgpd)
70 ipv6 prefix-list : Done
71 length : (This will not be implemented by bgpd)
72 metric : Done
73 route-type : (This will not be implemented by bgpd)
74 tag : (This will not be implemented by bgpd)
75
76 set as-path prepend : Done
77 as-path tag : Not yet
78 automatic-tag : (This will not be implemented by bgpd)
79 community : Done
80 comm-list : Not yet
81 dampning : Not yet
82 default : (This will not be implemented by bgpd)
83 interface : (This will not be implemented by bgpd)
84 ip default : (This will not be implemented by bgpd)
85 ip next-hop : Done
86 ip precedence : (This will not be implemented by bgpd)
87 ip tos : (This will not be implemented by bgpd)
88 level : (This will not be implemented by bgpd)
89 local-preference : Done
90 metric : Done
91 metric-type : Not yet
92 origin : Done
93 tag : (This will not be implemented by bgpd)
94 weight : Done
95
Timo Teräs2aa640b2014-05-20 08:57:26 +030096o Local extensions
paul718e3742002-12-13 20:15:29 +000097
98 set ipv6 next-hop global: Done
99 set ipv6 next-hop local : Done
Denis Ovsienko841f7a52008-04-10 11:47:45 +0000100 set as-path exclude : Done
paul718e3742002-12-13 20:15:29 +0000101
102*/
David Lamparter6b0655a2014-06-04 06:53:35 +0200103
Timo Teräsb304dcb2014-05-20 09:04:49 +0300104 /* generic as path object to be shared in multiple rules */
105
106static void *
107route_aspath_compile (const char *arg)
108{
109 struct aspath *aspath;
110
111 aspath = aspath_str2aspath (arg);
112 if (! aspath)
113 return NULL;
114 return aspath;
115}
116
117static void
118route_aspath_free (void *rule)
119{
120 struct aspath *aspath = rule;
121 aspath_free (aspath);
122}
123
paulfee0f4c2004-09-13 05:12:46 +0000124 /* 'match peer (A.B.C.D|X:X::X:X)' */
125
126/* Compares the peer specified in the 'match peer' clause with the peer
127 received in bgp_info->peer. If it is the same, or if the peer structure
128 received is a peer_group containing it, returns RMAP_MATCH. */
paul94f2b392005-06-28 12:44:16 +0000129static route_map_result_t
paulfee0f4c2004-09-13 05:12:46 +0000130route_match_peer (void *rule, struct prefix *prefix, route_map_object_t type,
131 void *object)
132{
133 union sockunion *su;
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200134 union sockunion su_def = { .sa.sa_family = AF_INET,
135 .sin.sin_addr.s_addr = INADDR_ANY };
paulfee0f4c2004-09-13 05:12:46 +0000136 struct peer_group *group;
137 struct peer *peer;
paul1eb8ef22005-04-07 07:30:20 +0000138 struct listnode *node, *nnode;
paulfee0f4c2004-09-13 05:12:46 +0000139
140 if (type == RMAP_BGP)
141 {
142 su = rule;
143 peer = ((struct bgp_info *) object)->peer;
144
145 if ( ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT) &&
146 ! CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_EXPORT) )
147 return RMAP_NOMATCH;
148
149 /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK,
150 REDISTRIBUTE or DEFAULT_GENERATED route => return RMAP_MATCH */
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200151 if (sockunion_same (su, &su_def))
paulfee0f4c2004-09-13 05:12:46 +0000152 {
paul22db9de2005-05-19 01:50:11 +0000153 int ret;
paulfee0f4c2004-09-13 05:12:46 +0000154 if ( CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_NETWORK) ||
155 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE) ||
156 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_DEFAULT))
paul22db9de2005-05-19 01:50:11 +0000157 ret = RMAP_MATCH;
paulfee0f4c2004-09-13 05:12:46 +0000158 else
paul22db9de2005-05-19 01:50:11 +0000159 ret = RMAP_NOMATCH;
paul22db9de2005-05-19 01:50:11 +0000160 return ret;
paulfee0f4c2004-09-13 05:12:46 +0000161 }
Jorge Boncompte [DTI2]c63b83f2012-04-10 16:57:24 +0200162
paulfee0f4c2004-09-13 05:12:46 +0000163 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
164 {
165 if (sockunion_same (su, &peer->su))
166 return RMAP_MATCH;
167
168 return RMAP_NOMATCH;
169 }
170 else
171 {
172 group = peer->group;
paul1eb8ef22005-04-07 07:30:20 +0000173 for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
paulfee0f4c2004-09-13 05:12:46 +0000174 {
175 if (sockunion_same (su, &peer->su))
176 return RMAP_MATCH;
paulfee0f4c2004-09-13 05:12:46 +0000177 }
Paul Jakma30a22312008-08-15 14:05:22 +0100178 return RMAP_NOMATCH;
paulfee0f4c2004-09-13 05:12:46 +0000179 }
180 }
181 return RMAP_NOMATCH;
182}
183
paul94f2b392005-06-28 12:44:16 +0000184static void *
paulfd79ac92004-10-13 05:06:08 +0000185route_match_peer_compile (const char *arg)
paulfee0f4c2004-09-13 05:12:46 +0000186{
187 union sockunion *su;
188 int ret;
189
190 su = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union sockunion));
191
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +0200192 ret = str2sockunion (strcmp(arg, "local") ? arg : "0.0.0.0", su);
paulfee0f4c2004-09-13 05:12:46 +0000193 if (ret < 0) {
194 XFREE (MTYPE_ROUTE_MAP_COMPILED, su);
195 return NULL;
196 }
197
198 return su;
199}
200
201/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000202static void
paulfee0f4c2004-09-13 05:12:46 +0000203route_match_peer_free (void *rule)
204{
205 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
206}
207
208/* Route map commands for ip address matching. */
209struct route_map_rule_cmd route_match_peer_cmd =
210{
211 "peer",
212 route_match_peer,
213 route_match_peer_compile,
214 route_match_peer_free
215};
216
paul718e3742002-12-13 20:15:29 +0000217/* `match ip address IP_ACCESS_LIST' */
218
219/* Match function should return 1 if match is success else return
220 zero. */
paul94f2b392005-06-28 12:44:16 +0000221static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000222route_match_ip_address (void *rule, struct prefix *prefix,
223 route_map_object_t type, void *object)
224{
225 struct access_list *alist;
226 /* struct prefix_ipv4 match; */
227
228 if (type == RMAP_BGP)
229 {
230 alist = access_list_lookup (AFI_IP, (char *) rule);
231 if (alist == NULL)
232 return RMAP_NOMATCH;
233
234 return (access_list_apply (alist, prefix) == FILTER_DENY ?
235 RMAP_NOMATCH : RMAP_MATCH);
236 }
237 return RMAP_NOMATCH;
238}
239
240/* Route map `ip address' match statement. `arg' should be
241 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000242static void *
paulfd79ac92004-10-13 05:06:08 +0000243route_match_ip_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000244{
245 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
246}
247
248/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000249static void
paul718e3742002-12-13 20:15:29 +0000250route_match_ip_address_free (void *rule)
251{
252 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
253}
254
255/* Route map commands for ip address matching. */
256struct route_map_rule_cmd route_match_ip_address_cmd =
257{
258 "ip address",
259 route_match_ip_address,
260 route_match_ip_address_compile,
261 route_match_ip_address_free
262};
David Lamparter6b0655a2014-06-04 06:53:35 +0200263
paul718e3742002-12-13 20:15:29 +0000264/* `match ip next-hop IP_ADDRESS' */
265
266/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000267static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000268route_match_ip_next_hop (void *rule, struct prefix *prefix,
269 route_map_object_t type, void *object)
270{
271 struct access_list *alist;
272 struct bgp_info *bgp_info;
273 struct prefix_ipv4 p;
274
275 if (type == RMAP_BGP)
276 {
277 bgp_info = object;
278 p.family = AF_INET;
279 p.prefix = bgp_info->attr->nexthop;
280 p.prefixlen = IPV4_MAX_BITLEN;
281
282 alist = access_list_lookup (AFI_IP, (char *) rule);
283 if (alist == NULL)
284 return RMAP_NOMATCH;
285
286 return (access_list_apply (alist, &p) == FILTER_DENY ?
287 RMAP_NOMATCH : RMAP_MATCH);
288 }
289 return RMAP_NOMATCH;
290}
291
292/* Route map `ip next-hop' match statement. `arg' is
293 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000294static void *
paulfd79ac92004-10-13 05:06:08 +0000295route_match_ip_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000296{
297 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
298}
299
300/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000301static void
paul718e3742002-12-13 20:15:29 +0000302route_match_ip_next_hop_free (void *rule)
303{
304 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
305}
306
307/* Route map commands for ip next-hop matching. */
308struct route_map_rule_cmd route_match_ip_next_hop_cmd =
309{
310 "ip next-hop",
311 route_match_ip_next_hop,
312 route_match_ip_next_hop_compile,
313 route_match_ip_next_hop_free
314};
David Lamparter6b0655a2014-06-04 06:53:35 +0200315
hassoc1643bb2005-02-02 16:43:17 +0000316/* `match ip route-source ACCESS-LIST' */
317
318/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000319static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000320route_match_ip_route_source (void *rule, struct prefix *prefix,
321 route_map_object_t type, void *object)
322{
323 struct access_list *alist;
324 struct bgp_info *bgp_info;
325 struct peer *peer;
326 struct prefix_ipv4 p;
327
328 if (type == RMAP_BGP)
329 {
330 bgp_info = object;
331 peer = bgp_info->peer;
332
333 if (! peer || sockunion_family (&peer->su) != AF_INET)
334 return RMAP_NOMATCH;
335
336 p.family = AF_INET;
337 p.prefix = peer->su.sin.sin_addr;
338 p.prefixlen = IPV4_MAX_BITLEN;
339
340 alist = access_list_lookup (AFI_IP, (char *) rule);
341 if (alist == NULL)
342 return RMAP_NOMATCH;
343
344 return (access_list_apply (alist, &p) == FILTER_DENY ?
345 RMAP_NOMATCH : RMAP_MATCH);
346 }
347 return RMAP_NOMATCH;
348}
349
350/* Route map `ip route-source' match statement. `arg' is
351 access-list name. */
paul94f2b392005-06-28 12:44:16 +0000352static void *
hassoc1643bb2005-02-02 16:43:17 +0000353route_match_ip_route_source_compile (const char *arg)
354{
355 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
356}
357
358/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000359static void
hassoc1643bb2005-02-02 16:43:17 +0000360route_match_ip_route_source_free (void *rule)
361{
362 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
363}
364
365/* Route map commands for ip route-source matching. */
366struct route_map_rule_cmd route_match_ip_route_source_cmd =
367{
368 "ip route-source",
369 route_match_ip_route_source,
370 route_match_ip_route_source_compile,
371 route_match_ip_route_source_free
372};
David Lamparter6b0655a2014-06-04 06:53:35 +0200373
paul718e3742002-12-13 20:15:29 +0000374/* `match ip address prefix-list PREFIX_LIST' */
375
paul94f2b392005-06-28 12:44:16 +0000376static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000377route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
378 route_map_object_t type, void *object)
379{
380 struct prefix_list *plist;
381
382 if (type == RMAP_BGP)
383 {
384 plist = prefix_list_lookup (AFI_IP, (char *) rule);
385 if (plist == NULL)
386 return RMAP_NOMATCH;
387
388 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
389 RMAP_NOMATCH : RMAP_MATCH);
390 }
391 return RMAP_NOMATCH;
392}
393
paul94f2b392005-06-28 12:44:16 +0000394static void *
paulfd79ac92004-10-13 05:06:08 +0000395route_match_ip_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000396{
397 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
398}
399
paul94f2b392005-06-28 12:44:16 +0000400static void
paul718e3742002-12-13 20:15:29 +0000401route_match_ip_address_prefix_list_free (void *rule)
402{
403 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
404}
405
406struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
407{
408 "ip address prefix-list",
409 route_match_ip_address_prefix_list,
410 route_match_ip_address_prefix_list_compile,
411 route_match_ip_address_prefix_list_free
412};
David Lamparter6b0655a2014-06-04 06:53:35 +0200413
paul718e3742002-12-13 20:15:29 +0000414/* `match ip next-hop prefix-list PREFIX_LIST' */
415
paul94f2b392005-06-28 12:44:16 +0000416static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000417route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
418 route_map_object_t type, void *object)
419{
420 struct prefix_list *plist;
421 struct bgp_info *bgp_info;
422 struct prefix_ipv4 p;
423
424 if (type == RMAP_BGP)
425 {
426 bgp_info = object;
427 p.family = AF_INET;
428 p.prefix = bgp_info->attr->nexthop;
429 p.prefixlen = IPV4_MAX_BITLEN;
430
431 plist = prefix_list_lookup (AFI_IP, (char *) rule);
432 if (plist == NULL)
433 return RMAP_NOMATCH;
434
435 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
436 RMAP_NOMATCH : RMAP_MATCH);
437 }
438 return RMAP_NOMATCH;
439}
440
paul94f2b392005-06-28 12:44:16 +0000441static void *
paulfd79ac92004-10-13 05:06:08 +0000442route_match_ip_next_hop_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000443{
444 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
445}
446
paul94f2b392005-06-28 12:44:16 +0000447static void
paul718e3742002-12-13 20:15:29 +0000448route_match_ip_next_hop_prefix_list_free (void *rule)
449{
450 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
451}
452
453struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
454{
455 "ip next-hop prefix-list",
456 route_match_ip_next_hop_prefix_list,
457 route_match_ip_next_hop_prefix_list_compile,
458 route_match_ip_next_hop_prefix_list_free
459};
David Lamparter6b0655a2014-06-04 06:53:35 +0200460
hassoc1643bb2005-02-02 16:43:17 +0000461/* `match ip route-source prefix-list PREFIX_LIST' */
462
paul94f2b392005-06-28 12:44:16 +0000463static route_map_result_t
hassoc1643bb2005-02-02 16:43:17 +0000464route_match_ip_route_source_prefix_list (void *rule, struct prefix *prefix,
465 route_map_object_t type, void *object)
466{
467 struct prefix_list *plist;
468 struct bgp_info *bgp_info;
469 struct peer *peer;
470 struct prefix_ipv4 p;
471
472 if (type == RMAP_BGP)
473 {
474 bgp_info = object;
475 peer = bgp_info->peer;
476
477 if (! peer || sockunion_family (&peer->su) != AF_INET)
478 return RMAP_NOMATCH;
479
480 p.family = AF_INET;
481 p.prefix = peer->su.sin.sin_addr;
482 p.prefixlen = IPV4_MAX_BITLEN;
483
484 plist = prefix_list_lookup (AFI_IP, (char *) rule);
485 if (plist == NULL)
486 return RMAP_NOMATCH;
487
488 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
489 RMAP_NOMATCH : RMAP_MATCH);
490 }
491 return RMAP_NOMATCH;
492}
493
paul94f2b392005-06-28 12:44:16 +0000494static void *
hassoc1643bb2005-02-02 16:43:17 +0000495route_match_ip_route_source_prefix_list_compile (const char *arg)
496{
497 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
498}
499
paul94f2b392005-06-28 12:44:16 +0000500static void
hassoc1643bb2005-02-02 16:43:17 +0000501route_match_ip_route_source_prefix_list_free (void *rule)
502{
503 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
504}
505
506struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd =
507{
508 "ip route-source prefix-list",
509 route_match_ip_route_source_prefix_list,
510 route_match_ip_route_source_prefix_list_compile,
511 route_match_ip_route_source_prefix_list_free
512};
David Lamparter6b0655a2014-06-04 06:53:35 +0200513
paul718e3742002-12-13 20:15:29 +0000514/* `match metric METRIC' */
515
516/* Match function return 1 if match is success else return zero. */
paul94f2b392005-06-28 12:44:16 +0000517static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000518route_match_metric (void *rule, struct prefix *prefix,
519 route_map_object_t type, void *object)
520{
521 u_int32_t *med;
522 struct bgp_info *bgp_info;
523
524 if (type == RMAP_BGP)
525 {
526 med = rule;
527 bgp_info = object;
528
529 if (bgp_info->attr->med == *med)
530 return RMAP_MATCH;
531 else
532 return RMAP_NOMATCH;
533 }
534 return RMAP_NOMATCH;
535}
536
537/* Route map `match metric' match statement. `arg' is MED value */
paul94f2b392005-06-28 12:44:16 +0000538static void *
paulfd79ac92004-10-13 05:06:08 +0000539route_match_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000540{
541 u_int32_t *med;
542 char *endptr = NULL;
paul3b424972003-10-13 09:47:32 +0000543 unsigned long tmpval;
paul718e3742002-12-13 20:15:29 +0000544
Ulrich Weber664711c2011-12-21 02:24:11 +0400545 /* Metric value shoud be integer. */
546 if (! all_digit (arg))
547 return NULL;
548
549 errno = 0;
paul3b424972003-10-13 09:47:32 +0000550 tmpval = strtoul (arg, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +0400551 if (*endptr != '\0' || errno || tmpval > UINT32_MAX)
paul3b424972003-10-13 09:47:32 +0000552 return NULL;
paulfd79ac92004-10-13 05:06:08 +0000553
paul718e3742002-12-13 20:15:29 +0000554 med = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +0000555
556 if (!med)
557 return med;
558
paul3b424972003-10-13 09:47:32 +0000559 *med = tmpval;
paul718e3742002-12-13 20:15:29 +0000560 return med;
561}
562
563/* Free route map's compiled `match metric' value. */
paul94f2b392005-06-28 12:44:16 +0000564static void
paul718e3742002-12-13 20:15:29 +0000565route_match_metric_free (void *rule)
566{
567 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
568}
569
570/* Route map commands for metric matching. */
571struct route_map_rule_cmd route_match_metric_cmd =
572{
573 "metric",
574 route_match_metric,
575 route_match_metric_compile,
576 route_match_metric_free
577};
David Lamparter6b0655a2014-06-04 06:53:35 +0200578
paul718e3742002-12-13 20:15:29 +0000579/* `match as-path ASPATH' */
580
581/* Match function for as-path match. I assume given object is */
paul94f2b392005-06-28 12:44:16 +0000582static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000583route_match_aspath (void *rule, struct prefix *prefix,
584 route_map_object_t type, void *object)
585{
586
587 struct as_list *as_list;
588 struct bgp_info *bgp_info;
589
590 if (type == RMAP_BGP)
591 {
592 as_list = as_list_lookup ((char *) rule);
593 if (as_list == NULL)
594 return RMAP_NOMATCH;
595
596 bgp_info = object;
597
598 /* Perform match. */
599 return ((as_list_apply (as_list, bgp_info->attr->aspath) == AS_FILTER_DENY) ? RMAP_NOMATCH : RMAP_MATCH);
600 }
601 return RMAP_NOMATCH;
602}
603
604/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000605static void *
paulfd79ac92004-10-13 05:06:08 +0000606route_match_aspath_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000607{
608 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
609}
610
611/* Compile function for as-path match. */
paul94f2b392005-06-28 12:44:16 +0000612static void
paul718e3742002-12-13 20:15:29 +0000613route_match_aspath_free (void *rule)
614{
615 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
616}
617
618/* Route map commands for aspath matching. */
619struct route_map_rule_cmd route_match_aspath_cmd =
620{
621 "as-path",
622 route_match_aspath,
623 route_match_aspath_compile,
624 route_match_aspath_free
625};
David Lamparter6b0655a2014-06-04 06:53:35 +0200626
paul718e3742002-12-13 20:15:29 +0000627/* `match community COMMUNIY' */
628struct rmap_community
629{
630 char *name;
631 int exact;
632};
633
634/* Match function for community match. */
paul94f2b392005-06-28 12:44:16 +0000635static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000636route_match_community (void *rule, struct prefix *prefix,
637 route_map_object_t type, void *object)
638{
639 struct community_list *list;
640 struct bgp_info *bgp_info;
641 struct rmap_community *rcom;
642
643 if (type == RMAP_BGP)
644 {
645 bgp_info = object;
646 rcom = rule;
647
hassofee6e4e2005-02-02 16:29:31 +0000648 list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +0000649 if (! list)
650 return RMAP_NOMATCH;
651
652 if (rcom->exact)
653 {
654 if (community_list_exact_match (bgp_info->attr->community, list))
655 return RMAP_MATCH;
656 }
657 else
658 {
659 if (community_list_match (bgp_info->attr->community, list))
660 return RMAP_MATCH;
661 }
662 }
663 return RMAP_NOMATCH;
664}
665
666/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000667static void *
paulfd79ac92004-10-13 05:06:08 +0000668route_match_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000669{
670 struct rmap_community *rcom;
671 int len;
672 char *p;
673
674 rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community));
675
676 p = strchr (arg, ' ');
677 if (p)
678 {
679 len = p - arg;
680 rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
681 memcpy (rcom->name, arg, len);
682 rcom->exact = 1;
683 }
684 else
685 {
686 rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
687 rcom->exact = 0;
688 }
689 return rcom;
690}
691
692/* Compile function for community match. */
paul94f2b392005-06-28 12:44:16 +0000693static void
paul718e3742002-12-13 20:15:29 +0000694route_match_community_free (void *rule)
695{
696 struct rmap_community *rcom = rule;
697
698 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name);
699 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);
700}
701
702/* Route map commands for community matching. */
703struct route_map_rule_cmd route_match_community_cmd =
704{
705 "community",
706 route_match_community,
707 route_match_community_compile,
708 route_match_community_free
709};
David Lamparter6b0655a2014-06-04 06:53:35 +0200710
paul73ffb252003-04-19 15:49:49 +0000711/* Match function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000712static route_map_result_t
paul73ffb252003-04-19 15:49:49 +0000713route_match_ecommunity (void *rule, struct prefix *prefix,
714 route_map_object_t type, void *object)
715{
716 struct community_list *list;
717 struct bgp_info *bgp_info;
718
719 if (type == RMAP_BGP)
720 {
721 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +0000722
723 if (!bgp_info->attr->extra)
724 return RMAP_NOMATCH;
725
paul73ffb252003-04-19 15:49:49 +0000726 list = community_list_lookup (bgp_clist, (char *) rule,
hassofee6e4e2005-02-02 16:29:31 +0000727 EXTCOMMUNITY_LIST_MASTER);
paul73ffb252003-04-19 15:49:49 +0000728 if (! list)
729 return RMAP_NOMATCH;
730
Paul Jakmafb982c22007-05-04 20:15:47 +0000731 if (ecommunity_list_match (bgp_info->attr->extra->ecommunity, list))
paul73ffb252003-04-19 15:49:49 +0000732 return RMAP_MATCH;
733 }
734 return RMAP_NOMATCH;
735}
736
737/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000738static void *
paulfd79ac92004-10-13 05:06:08 +0000739route_match_ecommunity_compile (const char *arg)
paul73ffb252003-04-19 15:49:49 +0000740{
741 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
742}
743
744/* Compile function for extcommunity match. */
paul94f2b392005-06-28 12:44:16 +0000745static void
paul73ffb252003-04-19 15:49:49 +0000746route_match_ecommunity_free (void *rule)
747{
748 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
749}
750
751/* Route map commands for community matching. */
752struct route_map_rule_cmd route_match_ecommunity_cmd =
753{
754 "extcommunity",
755 route_match_ecommunity,
756 route_match_ecommunity_compile,
757 route_match_ecommunity_free
758};
David Lamparter6b0655a2014-06-04 06:53:35 +0200759
paul718e3742002-12-13 20:15:29 +0000760/* `match nlri` and `set nlri` are replaced by `address-family ipv4`
761 and `address-family vpnv4'. */
David Lamparter6b0655a2014-06-04 06:53:35 +0200762
paul718e3742002-12-13 20:15:29 +0000763/* `match origin' */
paul94f2b392005-06-28 12:44:16 +0000764static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000765route_match_origin (void *rule, struct prefix *prefix,
766 route_map_object_t type, void *object)
767{
768 u_char *origin;
769 struct bgp_info *bgp_info;
770
771 if (type == RMAP_BGP)
772 {
773 origin = rule;
774 bgp_info = object;
775
776 if (bgp_info->attr->origin == *origin)
777 return RMAP_MATCH;
778 }
779
780 return RMAP_NOMATCH;
781}
782
paul94f2b392005-06-28 12:44:16 +0000783static void *
paulfd79ac92004-10-13 05:06:08 +0000784route_match_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000785{
786 u_char *origin;
787
788 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
789
790 if (strcmp (arg, "igp") == 0)
791 *origin = 0;
792 else if (strcmp (arg, "egp") == 0)
793 *origin = 1;
794 else
795 *origin = 2;
796
797 return origin;
798}
799
800/* Free route map's compiled `ip address' value. */
paul94f2b392005-06-28 12:44:16 +0000801static void
paul718e3742002-12-13 20:15:29 +0000802route_match_origin_free (void *rule)
803{
804 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
805}
806
807/* Route map commands for origin matching. */
808struct route_map_rule_cmd route_match_origin_cmd =
809{
810 "origin",
811 route_match_origin,
812 route_match_origin_compile,
813 route_match_origin_free
814};
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +0400815
816/* match probability { */
817
818static route_map_result_t
819route_match_probability (void *rule, struct prefix *prefix,
820 route_map_object_t type, void *object)
821{
822 long r;
823#if _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500
824 r = random();
825#else
826 r = (long) rand();
827#endif
828
829 switch (*(unsigned *) rule)
830 {
831 case 0: break;
832 case RAND_MAX: return RMAP_MATCH;
833 default:
834 if (r < *(unsigned *) rule)
835 {
836 return RMAP_MATCH;
837 }
838 }
839
840 return RMAP_NOMATCH;
841}
842
843static void *
844route_match_probability_compile (const char *arg)
845{
846 unsigned *lobule;
847 unsigned perc;
848
849#if _SVID_SOURCE || _BSD_SOURCE || _XOPEN_SOURCE >= 500
850 srandom (time (NULL));
851#else
852 srand (time (NULL));
853#endif
854
855 perc = atoi (arg);
856 lobule = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (unsigned));
857
858 switch (perc)
859 {
860 case 0: *lobule = 0; break;
861 case 100: *lobule = RAND_MAX; break;
862 default: *lobule = RAND_MAX / 100 * perc;
863 }
864
865 return lobule;
866}
867
868static void
869route_match_probability_free (void *rule)
870{
871 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
872}
873
874struct route_map_rule_cmd route_match_probability_cmd =
875{
876 "probability",
877 route_match_probability,
878 route_match_probability_compile,
879 route_match_probability_free
880};
881
882/* } */
883
paul718e3742002-12-13 20:15:29 +0000884/* `set ip next-hop IP_ADDRESS' */
885
886/* Set nexthop to object. ojbect must be pointer to struct attr. */
paulac41b2a2003-08-12 05:32:27 +0000887struct rmap_ip_nexthop_set
888{
889 struct in_addr *address;
890 int peer_address;
891};
892
paul94f2b392005-06-28 12:44:16 +0000893static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000894route_set_ip_nexthop (void *rule, struct prefix *prefix,
895 route_map_object_t type, void *object)
896{
paulac41b2a2003-08-12 05:32:27 +0000897 struct rmap_ip_nexthop_set *rins = rule;
paul718e3742002-12-13 20:15:29 +0000898 struct bgp_info *bgp_info;
paulac41b2a2003-08-12 05:32:27 +0000899 struct peer *peer;
paul718e3742002-12-13 20:15:29 +0000900
901 if (type == RMAP_BGP)
902 {
paul718e3742002-12-13 20:15:29 +0000903 bgp_info = object;
paulac41b2a2003-08-12 05:32:27 +0000904 peer = bgp_info->peer;
905
906 if (rins->peer_address)
907 {
paulfee0f4c2004-09-13 05:12:46 +0000908 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
909 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
paulac41b2a2003-08-12 05:32:27 +0000910 && peer->su_remote
911 && sockunion_family (peer->su_remote) == AF_INET)
912 {
Jorge Boncompte [DTI2]0c5ed3e2012-04-10 16:57:22 +0200913 bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_remote);
paulac41b2a2003-08-12 05:32:27 +0000914 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
915 }
916 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
917 && peer->su_local
918 && sockunion_family (peer->su_local) == AF_INET)
919 {
Jorge Boncompte [DTI2]0c5ed3e2012-04-10 16:57:22 +0200920 bgp_info->attr->nexthop.s_addr = sockunion2ip (peer->su_local);
paulac41b2a2003-08-12 05:32:27 +0000921 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
922 }
923 }
924 else
925 {
926 /* Set next hop value. */
927 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);
928 bgp_info->attr->nexthop = *rins->address;
929 }
paul718e3742002-12-13 20:15:29 +0000930 }
931
932 return RMAP_OKAY;
933}
934
935/* Route map `ip nexthop' compile function. Given string is converted
936 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +0000937static void *
paulfd79ac92004-10-13 05:06:08 +0000938route_set_ip_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +0000939{
paulac41b2a2003-08-12 05:32:27 +0000940 struct rmap_ip_nexthop_set *rins;
941 struct in_addr *address = NULL;
942 int peer_address = 0;
paul718e3742002-12-13 20:15:29 +0000943 int ret;
paul718e3742002-12-13 20:15:29 +0000944
paulac41b2a2003-08-12 05:32:27 +0000945 if (strcmp (arg, "peer-address") == 0)
946 peer_address = 1;
947 else
paul718e3742002-12-13 20:15:29 +0000948 {
paulac41b2a2003-08-12 05:32:27 +0000949 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
950 ret = inet_aton (arg, address);
951
952 if (ret == 0)
953 {
954 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
955 return NULL;
956 }
paul718e3742002-12-13 20:15:29 +0000957 }
958
Stephen Hemminger393deb92008-08-18 14:13:29 -0700959 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set));
paulac41b2a2003-08-12 05:32:27 +0000960
961 rins->address = address;
962 rins->peer_address = peer_address;
963
964 return rins;
paul718e3742002-12-13 20:15:29 +0000965}
966
967/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +0000968static void
paul718e3742002-12-13 20:15:29 +0000969route_set_ip_nexthop_free (void *rule)
970{
paulac41b2a2003-08-12 05:32:27 +0000971 struct rmap_ip_nexthop_set *rins = rule;
972
973 if (rins->address)
974 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address);
975
976 XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);
paul718e3742002-12-13 20:15:29 +0000977}
978
979/* Route map commands for ip nexthop set. */
980struct route_map_rule_cmd route_set_ip_nexthop_cmd =
981{
982 "ip next-hop",
983 route_set_ip_nexthop,
984 route_set_ip_nexthop_compile,
985 route_set_ip_nexthop_free
986};
David Lamparter6b0655a2014-06-04 06:53:35 +0200987
paul718e3742002-12-13 20:15:29 +0000988/* `set local-preference LOCAL_PREF' */
989
990/* Set local preference. */
paul94f2b392005-06-28 12:44:16 +0000991static route_map_result_t
paul718e3742002-12-13 20:15:29 +0000992route_set_local_pref (void *rule, struct prefix *prefix,
993 route_map_object_t type, void *object)
994{
995 u_int32_t *local_pref;
996 struct bgp_info *bgp_info;
997
998 if (type == RMAP_BGP)
999 {
1000 /* Fetch routemap's rule information. */
1001 local_pref = rule;
1002 bgp_info = object;
1003
1004 /* Set local preference value. */
1005 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
1006 bgp_info->attr->local_pref = *local_pref;
1007 }
1008
1009 return RMAP_OKAY;
1010}
1011
1012/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +00001013static void *
paulfd79ac92004-10-13 05:06:08 +00001014route_set_local_pref_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001015{
paulfd79ac92004-10-13 05:06:08 +00001016 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +00001017 u_int32_t *local_pref;
1018 char *endptr = NULL;
1019
1020 /* Local preference value shoud be integer. */
1021 if (! all_digit (arg))
1022 return NULL;
paulfd79ac92004-10-13 05:06:08 +00001023
Ulrich Weber664711c2011-12-21 02:24:11 +04001024 errno = 0;
paulfd79ac92004-10-13 05:06:08 +00001025 tmp = strtoul (arg, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +04001026 if (*endptr != '\0' || errno || tmp > UINT32_MAX)
paulfd79ac92004-10-13 05:06:08 +00001027 return NULL;
1028
1029 local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
1030
1031 if (!local_pref)
1032 return local_pref;
1033
1034 *local_pref = tmp;
1035
paul718e3742002-12-13 20:15:29 +00001036 return local_pref;
1037}
1038
1039/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +00001040static void
paul718e3742002-12-13 20:15:29 +00001041route_set_local_pref_free (void *rule)
1042{
1043 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1044}
1045
1046/* Set local preference rule structure. */
1047struct route_map_rule_cmd route_set_local_pref_cmd =
1048{
1049 "local-preference",
1050 route_set_local_pref,
1051 route_set_local_pref_compile,
1052 route_set_local_pref_free,
1053};
David Lamparter6b0655a2014-06-04 06:53:35 +02001054
paul718e3742002-12-13 20:15:29 +00001055/* `set weight WEIGHT' */
1056
1057/* Set weight. */
paul94f2b392005-06-28 12:44:16 +00001058static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001059route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
1060 void *object)
1061{
1062 u_int32_t *weight;
1063 struct bgp_info *bgp_info;
1064
1065 if (type == RMAP_BGP)
1066 {
1067 /* Fetch routemap's rule information. */
1068 weight = rule;
1069 bgp_info = object;
1070
1071 /* Set weight value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001072 if (*weight)
1073 (bgp_attr_extra_get (bgp_info->attr))->weight = *weight;
1074 else if (bgp_info->attr->extra)
1075 bgp_info->attr->extra->weight = 0;
paul718e3742002-12-13 20:15:29 +00001076 }
1077
1078 return RMAP_OKAY;
1079}
1080
1081/* set local preference compilation. */
paul94f2b392005-06-28 12:44:16 +00001082static void *
paulfd79ac92004-10-13 05:06:08 +00001083route_set_weight_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001084{
paulfd79ac92004-10-13 05:06:08 +00001085 unsigned long tmp;
paul718e3742002-12-13 20:15:29 +00001086 u_int32_t *weight;
1087 char *endptr = NULL;
1088
1089 /* Local preference value shoud be integer. */
1090 if (! all_digit (arg))
1091 return NULL;
1092
Ulrich Weber664711c2011-12-21 02:24:11 +04001093 errno = 0;
paulfd79ac92004-10-13 05:06:08 +00001094 tmp = strtoul (arg, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +04001095 if (*endptr != '\0' || errno || tmp > UINT32_MAX)
paulfd79ac92004-10-13 05:06:08 +00001096 return NULL;
1097
paul718e3742002-12-13 20:15:29 +00001098 weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
paulfd79ac92004-10-13 05:06:08 +00001099
1100 if (weight == NULL)
1101 return weight;
1102
1103 *weight = tmp;
1104
paul718e3742002-12-13 20:15:29 +00001105 return weight;
1106}
1107
1108/* Free route map's local preference value. */
paul94f2b392005-06-28 12:44:16 +00001109static void
paul718e3742002-12-13 20:15:29 +00001110route_set_weight_free (void *rule)
1111{
1112 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1113}
1114
1115/* Set local preference rule structure. */
1116struct route_map_rule_cmd route_set_weight_cmd =
1117{
1118 "weight",
1119 route_set_weight,
1120 route_set_weight_compile,
1121 route_set_weight_free,
1122};
David Lamparter6b0655a2014-06-04 06:53:35 +02001123
paul718e3742002-12-13 20:15:29 +00001124/* `set metric METRIC' */
1125
1126/* Set metric to attribute. */
paul94f2b392005-06-28 12:44:16 +00001127static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001128route_set_metric (void *rule, struct prefix *prefix,
1129 route_map_object_t type, void *object)
1130{
1131 char *metric;
1132 u_int32_t metric_val;
1133 struct bgp_info *bgp_info;
1134
1135 if (type == RMAP_BGP)
1136 {
1137 /* Fetch routemap's rule information. */
1138 metric = rule;
1139 bgp_info = object;
1140
1141 if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)))
1142 bgp_info->attr->med = 0;
1143 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
1144
1145 if (all_digit (metric))
1146 {
1147 metric_val = strtoul (metric, (char **)NULL, 10);
1148 bgp_info->attr->med = metric_val;
1149 }
1150 else
1151 {
1152 metric_val = strtoul (metric+1, (char **)NULL, 10);
1153
1154 if (strncmp (metric, "+", 1) == 0)
1155 {
paul3b424972003-10-13 09:47:32 +00001156 if (bgp_info->attr->med/2 + metric_val/2 > BGP_MED_MAX/2)
1157 bgp_info->attr->med = BGP_MED_MAX - 1;
paul718e3742002-12-13 20:15:29 +00001158 else
paul537d8ea2003-08-27 06:45:32 +00001159 bgp_info->attr->med += metric_val;
paul718e3742002-12-13 20:15:29 +00001160 }
1161 else if (strncmp (metric, "-", 1) == 0)
1162 {
paul537d8ea2003-08-27 06:45:32 +00001163 if (bgp_info->attr->med <= metric_val)
1164 bgp_info->attr->med = 0;
paul718e3742002-12-13 20:15:29 +00001165 else
paul537d8ea2003-08-27 06:45:32 +00001166 bgp_info->attr->med -= metric_val;
paul718e3742002-12-13 20:15:29 +00001167 }
1168 }
1169 }
1170 return RMAP_OKAY;
1171}
1172
1173/* set metric compilation. */
paul94f2b392005-06-28 12:44:16 +00001174static void *
paulfd79ac92004-10-13 05:06:08 +00001175route_set_metric_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001176{
paul94f2b392005-06-28 12:44:16 +00001177 unsigned long larg;
paul718e3742002-12-13 20:15:29 +00001178 char *endptr = NULL;
1179
1180 if (all_digit (arg))
1181 {
1182 /* set metric value check*/
Ulrich Weber664711c2011-12-21 02:24:11 +04001183 errno = 0;
paul94f2b392005-06-28 12:44:16 +00001184 larg = strtoul (arg, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +04001185 if (*endptr != '\0' || errno || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001186 return NULL;
1187 }
1188 else
1189 {
1190 /* set metric +/-value check */
1191 if ((strncmp (arg, "+", 1) != 0
1192 && strncmp (arg, "-", 1) != 0)
1193 || (! all_digit (arg+1)))
1194 return NULL;
1195
Ulrich Weber664711c2011-12-21 02:24:11 +04001196 errno = 0;
paul94f2b392005-06-28 12:44:16 +00001197 larg = strtoul (arg+1, &endptr, 10);
Ulrich Weber664711c2011-12-21 02:24:11 +04001198 if (*endptr != '\0' || errno || larg > UINT32_MAX)
paul718e3742002-12-13 20:15:29 +00001199 return NULL;
1200 }
1201
1202 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1203}
1204
1205/* Free route map's compiled `set metric' value. */
paul94f2b392005-06-28 12:44:16 +00001206static void
paul718e3742002-12-13 20:15:29 +00001207route_set_metric_free (void *rule)
1208{
1209 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1210}
1211
1212/* Set metric rule structure. */
1213struct route_map_rule_cmd route_set_metric_cmd =
1214{
1215 "metric",
1216 route_set_metric,
1217 route_set_metric_compile,
1218 route_set_metric_free,
1219};
David Lamparter6b0655a2014-06-04 06:53:35 +02001220
paul718e3742002-12-13 20:15:29 +00001221/* `set as-path prepend ASPATH' */
1222
1223/* For AS path prepend mechanism. */
paul94f2b392005-06-28 12:44:16 +00001224static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001225route_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1226{
1227 struct aspath *aspath;
1228 struct aspath *new;
1229 struct bgp_info *binfo;
1230
1231 if (type == RMAP_BGP)
1232 {
paul718e3742002-12-13 20:15:29 +00001233 binfo = object;
1234
1235 if (binfo->attr->aspath->refcnt)
1236 new = aspath_dup (binfo->attr->aspath);
1237 else
1238 new = binfo->attr->aspath;
1239
Timo Teräs85c854a2014-09-30 11:31:53 +03001240 if ((uintptr_t)rule > 10)
1241 {
1242 aspath = rule;
1243 aspath_prepend (aspath, new);
1244 }
1245 else
1246 {
1247 as_t as = aspath_leftmost(new);
1248 if (!as) as = binfo->peer->as;
1249 new = aspath_add_seq_n (new, as, (uintptr_t) rule);
1250 }
1251
paul718e3742002-12-13 20:15:29 +00001252 binfo->attr->aspath = new;
1253 }
1254
1255 return RMAP_OKAY;
1256}
1257
Timo Teräs85c854a2014-09-30 11:31:53 +03001258static void *
1259route_set_aspath_prepend_compile (const char *arg)
1260{
1261 unsigned int num;
1262
1263 if (sscanf(arg, "last-as %u", &num) == 1 && num > 0 && num < 10)
1264 return (void*)(uintptr_t)num;
1265
1266 return route_aspath_compile(arg);
1267}
1268
1269static void
1270route_set_aspath_prepend_free (void *rule)
1271{
1272 if ((uintptr_t)rule > 10)
1273 route_aspath_free(rule);
1274}
1275
1276
Timo Teräs2aa640b2014-05-20 08:57:26 +03001277/* Set as-path prepend rule structure. */
paul718e3742002-12-13 20:15:29 +00001278struct route_map_rule_cmd route_set_aspath_prepend_cmd =
1279{
1280 "as-path prepend",
1281 route_set_aspath_prepend,
Timo Teräs85c854a2014-09-30 11:31:53 +03001282 route_set_aspath_prepend_compile,
1283 route_set_aspath_prepend_free,
paul718e3742002-12-13 20:15:29 +00001284};
David Lamparter6b0655a2014-06-04 06:53:35 +02001285
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001286/* `set as-path exclude ASn' */
1287
1288/* For ASN exclude mechanism.
1289 * Iterate over ASns requested and filter them from the given AS_PATH one by one.
1290 * Make a deep copy of existing AS_PATH, but for the first ASn only.
1291 */
1292static route_map_result_t
1293route_set_aspath_exclude (void *rule, struct prefix *dummy, route_map_object_t type, void *object)
1294{
1295 struct aspath * new_path, * exclude_path;
1296 struct bgp_info *binfo;
1297
1298 if (type == RMAP_BGP)
1299 {
1300 exclude_path = rule;
1301 binfo = object;
1302 if (binfo->attr->aspath->refcnt)
1303 new_path = aspath_dup (binfo->attr->aspath);
1304 else
1305 new_path = binfo->attr->aspath;
1306 binfo->attr->aspath = aspath_filter_exclude (new_path, exclude_path);
1307 }
1308 return RMAP_OKAY;
1309}
1310
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001311/* Set ASn exlude rule structure. */
1312struct route_map_rule_cmd route_set_aspath_exclude_cmd =
1313{
1314 "as-path exclude",
1315 route_set_aspath_exclude,
Timo Teräsb304dcb2014-05-20 09:04:49 +03001316 route_aspath_compile,
1317 route_aspath_free,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00001318};
David Lamparter6b0655a2014-06-04 06:53:35 +02001319
paul718e3742002-12-13 20:15:29 +00001320/* `set community COMMUNITY' */
1321struct rmap_com_set
1322{
1323 struct community *com;
1324 int additive;
1325 int none;
1326};
1327
1328/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001329static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001330route_set_community (void *rule, struct prefix *prefix,
1331 route_map_object_t type, void *object)
1332{
1333 struct rmap_com_set *rcs;
1334 struct bgp_info *binfo;
1335 struct attr *attr;
1336 struct community *new = NULL;
1337 struct community *old;
1338 struct community *merge;
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001339
paul718e3742002-12-13 20:15:29 +00001340 if (type == RMAP_BGP)
1341 {
1342 rcs = rule;
1343 binfo = object;
1344 attr = binfo->attr;
1345 old = attr->community;
1346
1347 /* "none" case. */
1348 if (rcs->none)
1349 {
1350 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES));
1351 attr->community = NULL;
Christian Frankeb06b35f2012-12-07 14:26:09 +00001352 /* See the longer comment down below. */
1353 if (old && old->refcnt == 0)
1354 community_free(old);
paul718e3742002-12-13 20:15:29 +00001355 return RMAP_OKAY;
1356 }
1357
1358 /* "additive" case. */
1359 if (rcs->additive && old)
1360 {
1361 merge = community_merge (community_dup (old), rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001362
1363 /* HACK: if the old community is not intern'd,
1364 * we should free it here, or all reference to it may be lost.
1365 * Really need to cleanup attribute caching sometime.
1366 */
1367 if (old->refcnt == 0)
1368 community_free (old);
paul718e3742002-12-13 20:15:29 +00001369 new = community_uniq_sort (merge);
1370 community_free (merge);
1371 }
1372 else
1373 new = community_dup (rcs->com);
Paul Jakmaaa94ca82006-02-18 10:49:04 +00001374
1375 /* will be interned by caller if required */
Paul Jakma4a2035f2011-04-01 15:58:27 +01001376 attr->community = new;
hasso70601e02005-05-27 03:26:57 +00001377
paul718e3742002-12-13 20:15:29 +00001378 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1379 }
1380
1381 return RMAP_OKAY;
1382}
1383
1384/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001385static void *
paulfd79ac92004-10-13 05:06:08 +00001386route_set_community_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001387{
1388 struct rmap_com_set *rcs;
1389 struct community *com = NULL;
1390 char *sp;
1391 int additive = 0;
1392 int none = 0;
1393
1394 if (strcmp (arg, "none") == 0)
1395 none = 1;
1396 else
1397 {
1398 sp = strstr (arg, "additive");
1399
1400 if (sp && sp > arg)
1401 {
1402 /* "additive" keyworkd is included. */
1403 additive = 1;
1404 *(sp - 1) = '\0';
1405 }
1406
1407 com = community_str2com (arg);
1408
1409 if (additive)
1410 *(sp - 1) = ' ';
1411
1412 if (! com)
1413 return NULL;
1414 }
1415
Stephen Hemminger393deb92008-08-18 14:13:29 -07001416 rcs = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set));
Paul Jakma4a2035f2011-04-01 15:58:27 +01001417 rcs->com = com;
paul718e3742002-12-13 20:15:29 +00001418 rcs->additive = additive;
1419 rcs->none = none;
1420
1421 return rcs;
1422}
1423
1424/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001425static void
paul718e3742002-12-13 20:15:29 +00001426route_set_community_free (void *rule)
1427{
1428 struct rmap_com_set *rcs = rule;
1429
1430 if (rcs->com)
1431 community_free (rcs->com);
1432 XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);
1433}
1434
1435/* Set community rule structure. */
1436struct route_map_rule_cmd route_set_community_cmd =
1437{
1438 "community",
1439 route_set_community,
1440 route_set_community_compile,
1441 route_set_community_free,
1442};
David Lamparter6b0655a2014-06-04 06:53:35 +02001443
hassofee6e4e2005-02-02 16:29:31 +00001444/* `set comm-list (<1-99>|<100-500>|WORD) delete' */
paul718e3742002-12-13 20:15:29 +00001445
1446/* For community set mechanism. */
paul94f2b392005-06-28 12:44:16 +00001447static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001448route_set_community_delete (void *rule, struct prefix *prefix,
1449 route_map_object_t type, void *object)
1450{
1451 struct community_list *list;
1452 struct community *merge;
1453 struct community *new;
1454 struct community *old;
1455 struct bgp_info *binfo;
1456
1457 if (type == RMAP_BGP)
1458 {
1459 if (! rule)
1460 return RMAP_OKAY;
1461
1462 binfo = object;
hassofee6e4e2005-02-02 16:29:31 +00001463 list = community_list_lookup (bgp_clist, rule, COMMUNITY_LIST_MASTER);
paul718e3742002-12-13 20:15:29 +00001464 old = binfo->attr->community;
1465
1466 if (list && old)
1467 {
1468 merge = community_list_match_delete (community_dup (old), list);
1469 new = community_uniq_sort (merge);
1470 community_free (merge);
1471
Michael Lambert604a9b42010-09-13 11:48:11 -04001472 /* HACK: if the old community is not intern'd,
1473 * we should free it here, or all reference to it may be lost.
1474 * Really need to cleanup attribute caching sometime.
1475 */
1476 if (old->refcnt == 0)
1477 community_free (old);
1478
paul718e3742002-12-13 20:15:29 +00001479 if (new->size == 0)
1480 {
1481 binfo->attr->community = NULL;
1482 binfo->attr->flag &= ~ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1483 community_free (new);
1484 }
1485 else
1486 {
Paul Jakma4a2035f2011-04-01 15:58:27 +01001487 binfo->attr->community = new;
paul718e3742002-12-13 20:15:29 +00001488 binfo->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
1489 }
1490 }
1491 }
1492
1493 return RMAP_OKAY;
1494}
1495
1496/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001497static void *
paulfd79ac92004-10-13 05:06:08 +00001498route_set_community_delete_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001499{
1500 char *p;
1501 char *str;
1502 int len;
1503
1504 p = strchr (arg, ' ');
1505 if (p)
1506 {
1507 len = p - arg;
1508 str = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1);
1509 memcpy (str, arg, len);
1510 }
1511 else
1512 str = NULL;
1513
1514 return str;
1515}
1516
1517/* Free function for set community. */
paul94f2b392005-06-28 12:44:16 +00001518static void
paul718e3742002-12-13 20:15:29 +00001519route_set_community_delete_free (void *rule)
1520{
1521 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1522}
1523
1524/* Set community rule structure. */
1525struct route_map_rule_cmd route_set_community_delete_cmd =
1526{
1527 "comm-list",
1528 route_set_community_delete,
1529 route_set_community_delete_compile,
1530 route_set_community_delete_free,
1531};
David Lamparter6b0655a2014-06-04 06:53:35 +02001532
paul718e3742002-12-13 20:15:29 +00001533/* `set extcommunity rt COMMUNITY' */
1534
David Lamparter73d78ea2014-06-04 00:58:47 +02001535/* For community set mechanism. Used by _rt and _soo. */
paul94f2b392005-06-28 12:44:16 +00001536static route_map_result_t
David Lamparter73d78ea2014-06-04 00:58:47 +02001537route_set_ecommunity (void *rule, struct prefix *prefix,
1538 route_map_object_t type, void *object)
paul718e3742002-12-13 20:15:29 +00001539{
1540 struct ecommunity *ecom;
1541 struct ecommunity *new_ecom;
1542 struct ecommunity *old_ecom;
1543 struct bgp_info *bgp_info;
1544
1545 if (type == RMAP_BGP)
1546 {
1547 ecom = rule;
1548 bgp_info = object;
1549
1550 if (! ecom)
1551 return RMAP_OKAY;
1552
1553 /* We assume additive for Extended Community. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001554 old_ecom = (bgp_attr_extra_get (bgp_info->attr))->ecommunity;
paul718e3742002-12-13 20:15:29 +00001555
1556 if (old_ecom)
David Lamparter27bf90a2014-06-04 00:59:01 +02001557 {
1558 new_ecom = ecommunity_merge (ecommunity_dup (old_ecom), ecom);
1559
1560 /* old_ecom->refcnt = 1 => owned elsewhere, e.g. bgp_update_receive()
1561 * ->refcnt = 0 => set by a previous route-map statement */
1562 if (!old_ecom->refcnt)
1563 ecommunity_free (&old_ecom);
1564 }
paul718e3742002-12-13 20:15:29 +00001565 else
1566 new_ecom = ecommunity_dup (ecom);
1567
David Lamparter27bf90a2014-06-04 00:59:01 +02001568 /* will be intern()'d or attr_flush()'d by bgp_update_main() */
1569 bgp_info->attr->extra->ecommunity = new_ecom;
hasso70601e02005-05-27 03:26:57 +00001570
paul718e3742002-12-13 20:15:29 +00001571 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
1572 }
1573 return RMAP_OKAY;
1574}
1575
1576/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001577static void *
paulfd79ac92004-10-13 05:06:08 +00001578route_set_ecommunity_rt_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001579{
1580 struct ecommunity *ecom;
1581
1582 ecom = ecommunity_str2com (arg, ECOMMUNITY_ROUTE_TARGET, 0);
1583 if (! ecom)
1584 return NULL;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001585 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001586}
1587
David Lamparter73d78ea2014-06-04 00:58:47 +02001588/* Free function for set community. Used by _rt and _soo */
paul94f2b392005-06-28 12:44:16 +00001589static void
David Lamparter73d78ea2014-06-04 00:58:47 +02001590route_set_ecommunity_free (void *rule)
paul718e3742002-12-13 20:15:29 +00001591{
1592 struct ecommunity *ecom = rule;
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001593 ecommunity_unintern (&ecom);
paul718e3742002-12-13 20:15:29 +00001594}
1595
1596/* Set community rule structure. */
1597struct route_map_rule_cmd route_set_ecommunity_rt_cmd =
1598{
1599 "extcommunity rt",
David Lamparter73d78ea2014-06-04 00:58:47 +02001600 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001601 route_set_ecommunity_rt_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001602 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001603};
1604
1605/* `set extcommunity soo COMMUNITY' */
1606
paul718e3742002-12-13 20:15:29 +00001607/* Compile function for set community. */
paul94f2b392005-06-28 12:44:16 +00001608static void *
paulfd79ac92004-10-13 05:06:08 +00001609route_set_ecommunity_soo_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001610{
1611 struct ecommunity *ecom;
1612
1613 ecom = ecommunity_str2com (arg, ECOMMUNITY_SITE_ORIGIN, 0);
1614 if (! ecom)
1615 return NULL;
1616
Paul Jakmaf6f434b2010-11-23 21:28:03 +00001617 return ecommunity_intern (ecom);
paul718e3742002-12-13 20:15:29 +00001618}
1619
paul718e3742002-12-13 20:15:29 +00001620/* Set community rule structure. */
1621struct route_map_rule_cmd route_set_ecommunity_soo_cmd =
1622{
1623 "extcommunity soo",
David Lamparter73d78ea2014-06-04 00:58:47 +02001624 route_set_ecommunity,
paul718e3742002-12-13 20:15:29 +00001625 route_set_ecommunity_soo_compile,
David Lamparter73d78ea2014-06-04 00:58:47 +02001626 route_set_ecommunity_free,
paul718e3742002-12-13 20:15:29 +00001627};
David Lamparter6b0655a2014-06-04 06:53:35 +02001628
paul718e3742002-12-13 20:15:29 +00001629/* `set origin ORIGIN' */
1630
1631/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00001632static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001633route_set_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
1634{
1635 u_char *origin;
1636 struct bgp_info *bgp_info;
1637
1638 if (type == RMAP_BGP)
1639 {
1640 origin = rule;
1641 bgp_info = object;
1642
1643 bgp_info->attr->origin = *origin;
1644 }
1645
1646 return RMAP_OKAY;
1647}
1648
1649/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001650static void *
paulfd79ac92004-10-13 05:06:08 +00001651route_set_origin_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001652{
1653 u_char *origin;
1654
1655 origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char));
1656
1657 if (strcmp (arg, "igp") == 0)
1658 *origin = 0;
1659 else if (strcmp (arg, "egp") == 0)
1660 *origin = 1;
1661 else
1662 *origin = 2;
1663
1664 return origin;
1665}
1666
1667/* Compile function for origin set. */
paul94f2b392005-06-28 12:44:16 +00001668static void
paul718e3742002-12-13 20:15:29 +00001669route_set_origin_free (void *rule)
1670{
1671 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1672}
1673
Timo Teräs2aa640b2014-05-20 08:57:26 +03001674/* Set origin rule structure. */
paul718e3742002-12-13 20:15:29 +00001675struct route_map_rule_cmd route_set_origin_cmd =
1676{
1677 "origin",
1678 route_set_origin,
1679 route_set_origin_compile,
1680 route_set_origin_free,
1681};
David Lamparter6b0655a2014-06-04 06:53:35 +02001682
paul718e3742002-12-13 20:15:29 +00001683/* `set atomic-aggregate' */
1684
1685/* For atomic aggregate set. */
paul94f2b392005-06-28 12:44:16 +00001686static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001687route_set_atomic_aggregate (void *rule, struct prefix *prefix,
1688 route_map_object_t type, void *object)
1689{
1690 struct bgp_info *bgp_info;
1691
1692 if (type == RMAP_BGP)
1693 {
1694 bgp_info = object;
1695 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
1696 }
1697
1698 return RMAP_OKAY;
1699}
1700
1701/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001702static void *
paulfd79ac92004-10-13 05:06:08 +00001703route_set_atomic_aggregate_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001704{
1705 return (void *)1;
1706}
1707
1708/* Compile function for atomic aggregate. */
paul94f2b392005-06-28 12:44:16 +00001709static void
paul718e3742002-12-13 20:15:29 +00001710route_set_atomic_aggregate_free (void *rule)
1711{
1712 return;
1713}
1714
1715/* Set atomic aggregate rule structure. */
1716struct route_map_rule_cmd route_set_atomic_aggregate_cmd =
1717{
1718 "atomic-aggregate",
1719 route_set_atomic_aggregate,
1720 route_set_atomic_aggregate_compile,
1721 route_set_atomic_aggregate_free,
1722};
David Lamparter6b0655a2014-06-04 06:53:35 +02001723
paul718e3742002-12-13 20:15:29 +00001724/* `set aggregator as AS A.B.C.D' */
1725struct aggregator
1726{
1727 as_t as;
1728 struct in_addr address;
1729};
1730
paul94f2b392005-06-28 12:44:16 +00001731static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001732route_set_aggregator_as (void *rule, struct prefix *prefix,
1733 route_map_object_t type, void *object)
1734{
1735 struct bgp_info *bgp_info;
1736 struct aggregator *aggregator;
Paul Jakmafb982c22007-05-04 20:15:47 +00001737 struct attr_extra *ae;
paul718e3742002-12-13 20:15:29 +00001738
1739 if (type == RMAP_BGP)
1740 {
1741 bgp_info = object;
1742 aggregator = rule;
Paul Jakmafb982c22007-05-04 20:15:47 +00001743 ae = bgp_attr_extra_get (bgp_info->attr);
1744
1745 ae->aggregator_as = aggregator->as;
1746 ae->aggregator_addr = aggregator->address;
paul718e3742002-12-13 20:15:29 +00001747 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR);
1748 }
1749
1750 return RMAP_OKAY;
1751}
1752
paul94f2b392005-06-28 12:44:16 +00001753static void *
paulfd79ac92004-10-13 05:06:08 +00001754route_set_aggregator_as_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001755{
1756 struct aggregator *aggregator;
1757 char as[10];
1758 char address[20];
1759
Stephen Hemminger393deb92008-08-18 14:13:29 -07001760 aggregator = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct aggregator));
paul718e3742002-12-13 20:15:29 +00001761 sscanf (arg, "%s %s", as, address);
1762
1763 aggregator->as = strtoul (as, NULL, 10);
1764 inet_aton (address, &aggregator->address);
1765
1766 return aggregator;
1767}
1768
paul94f2b392005-06-28 12:44:16 +00001769static void
paul718e3742002-12-13 20:15:29 +00001770route_set_aggregator_as_free (void *rule)
1771{
1772 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1773}
1774
1775struct route_map_rule_cmd route_set_aggregator_as_cmd =
1776{
1777 "aggregator as",
1778 route_set_aggregator_as,
1779 route_set_aggregator_as_compile,
1780 route_set_aggregator_as_free,
1781};
David Lamparter6b0655a2014-06-04 06:53:35 +02001782
paul718e3742002-12-13 20:15:29 +00001783#ifdef HAVE_IPV6
1784/* `match ipv6 address IP_ACCESS_LIST' */
1785
paul94f2b392005-06-28 12:44:16 +00001786static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001787route_match_ipv6_address (void *rule, struct prefix *prefix,
1788 route_map_object_t type, void *object)
1789{
1790 struct access_list *alist;
1791
1792 if (type == RMAP_BGP)
1793 {
1794 alist = access_list_lookup (AFI_IP6, (char *) rule);
1795 if (alist == NULL)
1796 return RMAP_NOMATCH;
1797
1798 return (access_list_apply (alist, prefix) == FILTER_DENY ?
1799 RMAP_NOMATCH : RMAP_MATCH);
1800 }
1801 return RMAP_NOMATCH;
1802}
1803
paul94f2b392005-06-28 12:44:16 +00001804static void *
paulfd79ac92004-10-13 05:06:08 +00001805route_match_ipv6_address_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001806{
1807 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1808}
1809
paul94f2b392005-06-28 12:44:16 +00001810static void
paul718e3742002-12-13 20:15:29 +00001811route_match_ipv6_address_free (void *rule)
1812{
1813 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1814}
1815
1816/* Route map commands for ip address matching. */
1817struct route_map_rule_cmd route_match_ipv6_address_cmd =
1818{
1819 "ipv6 address",
1820 route_match_ipv6_address,
1821 route_match_ipv6_address_compile,
1822 route_match_ipv6_address_free
1823};
David Lamparter6b0655a2014-06-04 06:53:35 +02001824
paul718e3742002-12-13 20:15:29 +00001825/* `match ipv6 next-hop IP_ADDRESS' */
1826
paul94f2b392005-06-28 12:44:16 +00001827static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001828route_match_ipv6_next_hop (void *rule, struct prefix *prefix,
1829 route_map_object_t type, void *object)
1830{
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001831 struct in6_addr *addr = rule;
paul718e3742002-12-13 20:15:29 +00001832 struct bgp_info *bgp_info;
1833
1834 if (type == RMAP_BGP)
1835 {
paul718e3742002-12-13 20:15:29 +00001836 bgp_info = object;
Paul Jakmafb982c22007-05-04 20:15:47 +00001837
1838 if (!bgp_info->attr->extra)
1839 return RMAP_NOMATCH;
1840
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001841 if (IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_global, addr))
paul718e3742002-12-13 20:15:29 +00001842 return RMAP_MATCH;
1843
Paul Jakmafb982c22007-05-04 20:15:47 +00001844 if (bgp_info->attr->extra->mp_nexthop_len == 32 &&
Paul Jakma7aa9dce2014-09-19 14:42:23 +01001845 IPV6_ADDR_SAME (&bgp_info->attr->extra->mp_nexthop_local, addr))
paul718e3742002-12-13 20:15:29 +00001846 return RMAP_MATCH;
1847
1848 return RMAP_NOMATCH;
1849 }
1850
1851 return RMAP_NOMATCH;
1852}
1853
paul94f2b392005-06-28 12:44:16 +00001854static void *
paulfd79ac92004-10-13 05:06:08 +00001855route_match_ipv6_next_hop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001856{
1857 struct in6_addr *address;
1858 int ret;
1859
1860 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1861
1862 ret = inet_pton (AF_INET6, arg, address);
1863 if (!ret)
1864 {
1865 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1866 return NULL;
1867 }
1868
1869 return address;
1870}
1871
paul94f2b392005-06-28 12:44:16 +00001872static void
paul718e3742002-12-13 20:15:29 +00001873route_match_ipv6_next_hop_free (void *rule)
1874{
1875 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1876}
1877
1878struct route_map_rule_cmd route_match_ipv6_next_hop_cmd =
1879{
1880 "ipv6 next-hop",
1881 route_match_ipv6_next_hop,
1882 route_match_ipv6_next_hop_compile,
1883 route_match_ipv6_next_hop_free
1884};
David Lamparter6b0655a2014-06-04 06:53:35 +02001885
paul718e3742002-12-13 20:15:29 +00001886/* `match ipv6 address prefix-list PREFIX_LIST' */
1887
paul94f2b392005-06-28 12:44:16 +00001888static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001889route_match_ipv6_address_prefix_list (void *rule, struct prefix *prefix,
1890 route_map_object_t type, void *object)
1891{
1892 struct prefix_list *plist;
1893
1894 if (type == RMAP_BGP)
1895 {
1896 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
1897 if (plist == NULL)
1898 return RMAP_NOMATCH;
1899
1900 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
1901 RMAP_NOMATCH : RMAP_MATCH);
1902 }
1903 return RMAP_NOMATCH;
1904}
1905
paul94f2b392005-06-28 12:44:16 +00001906static void *
paulfd79ac92004-10-13 05:06:08 +00001907route_match_ipv6_address_prefix_list_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001908{
1909 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
1910}
1911
paul94f2b392005-06-28 12:44:16 +00001912static void
paul718e3742002-12-13 20:15:29 +00001913route_match_ipv6_address_prefix_list_free (void *rule)
1914{
1915 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1916}
1917
1918struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd =
1919{
1920 "ipv6 address prefix-list",
1921 route_match_ipv6_address_prefix_list,
1922 route_match_ipv6_address_prefix_list_compile,
1923 route_match_ipv6_address_prefix_list_free
1924};
David Lamparter6b0655a2014-06-04 06:53:35 +02001925
paul718e3742002-12-13 20:15:29 +00001926/* `set ipv6 nexthop global IP_ADDRESS' */
1927
1928/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001929static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001930route_set_ipv6_nexthop_global (void *rule, struct prefix *prefix,
1931 route_map_object_t type, void *object)
1932{
1933 struct in6_addr *address;
1934 struct bgp_info *bgp_info;
1935
1936 if (type == RMAP_BGP)
1937 {
1938 /* Fetch routemap's rule information. */
1939 address = rule;
1940 bgp_info = object;
1941
1942 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001943 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = *address;
paul718e3742002-12-13 20:15:29 +00001944
1945 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00001946 if (bgp_info->attr->extra->mp_nexthop_len == 0)
1947 bgp_info->attr->extra->mp_nexthop_len = 16;
paul718e3742002-12-13 20:15:29 +00001948 }
1949
1950 return RMAP_OKAY;
1951}
1952
1953/* Route map `ip next-hop' compile function. Given string is converted
1954 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00001955static void *
paulfd79ac92004-10-13 05:06:08 +00001956route_set_ipv6_nexthop_global_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00001957{
1958 int ret;
1959 struct in6_addr *address;
1960
1961 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
1962
1963 ret = inet_pton (AF_INET6, arg, address);
1964
1965 if (ret == 0)
1966 {
1967 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
1968 return NULL;
1969 }
1970
1971 return address;
1972}
1973
1974/* Free route map's compiled `ip next-hop' value. */
paul94f2b392005-06-28 12:44:16 +00001975static void
paul718e3742002-12-13 20:15:29 +00001976route_set_ipv6_nexthop_global_free (void *rule)
1977{
1978 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
1979}
1980
1981/* Route map commands for ip nexthop set. */
1982struct route_map_rule_cmd route_set_ipv6_nexthop_global_cmd =
1983{
1984 "ipv6 next-hop global",
1985 route_set_ipv6_nexthop_global,
1986 route_set_ipv6_nexthop_global_compile,
1987 route_set_ipv6_nexthop_global_free
1988};
David Lamparter6b0655a2014-06-04 06:53:35 +02001989
paul718e3742002-12-13 20:15:29 +00001990/* `set ipv6 nexthop local IP_ADDRESS' */
1991
1992/* Set nexthop to object. ojbect must be pointer to struct attr. */
paul94f2b392005-06-28 12:44:16 +00001993static route_map_result_t
paul718e3742002-12-13 20:15:29 +00001994route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
1995 route_map_object_t type, void *object)
1996{
1997 struct in6_addr *address;
1998 struct bgp_info *bgp_info;
1999
2000 if (type == RMAP_BGP)
2001 {
2002 /* Fetch routemap's rule information. */
2003 address = rule;
2004 bgp_info = object;
2005
2006 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002007 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = *address;
paul718e3742002-12-13 20:15:29 +00002008
2009 /* Set nexthop length. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002010 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2011 bgp_info->attr->extra->mp_nexthop_len = 32;
paul718e3742002-12-13 20:15:29 +00002012 }
2013
2014 return RMAP_OKAY;
2015}
2016
2017/* Route map `ip nexthop' compile function. Given string is converted
2018 to struct in_addr structure. */
paul94f2b392005-06-28 12:44:16 +00002019static void *
paulfd79ac92004-10-13 05:06:08 +00002020route_set_ipv6_nexthop_local_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002021{
2022 int ret;
2023 struct in6_addr *address;
2024
2025 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
2026
2027 ret = inet_pton (AF_INET6, arg, address);
2028
2029 if (ret == 0)
2030 {
2031 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2032 return NULL;
2033 }
2034
2035 return address;
2036}
2037
2038/* Free route map's compiled `ip nexthop' value. */
paul94f2b392005-06-28 12:44:16 +00002039static void
paul718e3742002-12-13 20:15:29 +00002040route_set_ipv6_nexthop_local_free (void *rule)
2041{
2042 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2043}
2044
2045/* Route map commands for ip nexthop set. */
2046struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
2047{
2048 "ipv6 next-hop local",
2049 route_set_ipv6_nexthop_local,
2050 route_set_ipv6_nexthop_local_compile,
2051 route_set_ipv6_nexthop_local_free
2052};
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002053
2054/* `set ipv6 nexthop peer-address' */
2055
2056/* Set nexthop to object. ojbect must be pointer to struct attr. */
2057static route_map_result_t
2058route_set_ipv6_nexthop_peer (void *rule, struct prefix *prefix,
2059 route_map_object_t type, void *object)
2060{
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002061 struct in6_addr peer_address;
2062 struct bgp_info *bgp_info;
2063 struct peer *peer;
2064 char peer_addr_buf[INET6_ADDRSTRLEN];
2065
2066 if (type == RMAP_BGP)
2067 {
2068 /* Fetch routemap's rule information. */
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002069 bgp_info = object;
2070 peer = bgp_info->peer;
2071
2072 if ((CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) ||
2073 CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT))
2074 && peer->su_remote
2075 && sockunion_family (peer->su_remote) == AF_INET6)
2076 {
2077 inet_pton (AF_INET6, sockunion2str (peer->su_remote,
2078 peer_addr_buf,
2079 INET6_ADDRSTRLEN),
2080 &peer_address);
2081 }
2082 else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT)
2083 && peer->su_local
2084 && sockunion_family (peer->su_local) == AF_INET6)
2085 {
2086 inet_pton (AF_INET, sockunion2str (peer->su_local,
2087 peer_addr_buf,
2088 INET6_ADDRSTRLEN),
2089 &peer_address);
2090 }
2091
2092 if (IN6_IS_ADDR_LINKLOCAL(&peer_address))
2093 {
2094 /* Set next hop value. */
2095 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_local = peer_address;
2096
2097 /* Set nexthop length. */
2098 if (bgp_info->attr->extra->mp_nexthop_len != 32)
2099 bgp_info->attr->extra->mp_nexthop_len = 32;
2100 }
2101 else
2102 {
2103 /* Set next hop value. */
2104 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global = peer_address;
2105
2106 /* Set nexthop length. */
2107 if (bgp_info->attr->extra->mp_nexthop_len == 0)
2108 bgp_info->attr->extra->mp_nexthop_len = 16;
2109 }
2110 }
2111
2112 return RMAP_OKAY;
2113}
2114
2115/* Route map `ip next-hop' compile function. Given string is converted
2116 to struct in_addr structure. */
2117static void *
2118route_set_ipv6_nexthop_peer_compile (const char *arg)
2119{
Dinesh G Duttad5233a2014-09-30 14:19:57 -07002120 int *rins = NULL;
2121
2122 rins = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (int));
2123 *rins = 1;
2124
2125 return rins;
2126}
2127
2128/* Free route map's compiled `ip next-hop' value. */
2129static void
2130route_set_ipv6_nexthop_peer_free (void *rule)
2131{
2132 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2133}
2134
2135/* Route map commands for ip nexthop set. */
2136struct route_map_rule_cmd route_set_ipv6_nexthop_peer_cmd =
2137{
2138 "ipv6 next-hop peer-address",
2139 route_set_ipv6_nexthop_peer,
2140 route_set_ipv6_nexthop_peer_compile,
2141 route_set_ipv6_nexthop_peer_free
2142};
2143
paul718e3742002-12-13 20:15:29 +00002144#endif /* HAVE_IPV6 */
David Lamparter6b0655a2014-06-04 06:53:35 +02002145
paul718e3742002-12-13 20:15:29 +00002146/* `set vpnv4 nexthop A.B.C.D' */
2147
paul94f2b392005-06-28 12:44:16 +00002148static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002149route_set_vpnv4_nexthop (void *rule, struct prefix *prefix,
2150 route_map_object_t type, void *object)
2151{
2152 struct in_addr *address;
2153 struct bgp_info *bgp_info;
2154
2155 if (type == RMAP_BGP)
2156 {
2157 /* Fetch routemap's rule information. */
2158 address = rule;
2159 bgp_info = object;
2160
2161 /* Set next hop value. */
Paul Jakmafb982c22007-05-04 20:15:47 +00002162 (bgp_attr_extra_get (bgp_info->attr))->mp_nexthop_global_in = *address;
paul718e3742002-12-13 20:15:29 +00002163 }
2164
2165 return RMAP_OKAY;
2166}
2167
paul94f2b392005-06-28 12:44:16 +00002168static void *
paulfd79ac92004-10-13 05:06:08 +00002169route_set_vpnv4_nexthop_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002170{
2171 int ret;
2172 struct in_addr *address;
2173
2174 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2175
2176 ret = inet_aton (arg, address);
2177
2178 if (ret == 0)
2179 {
2180 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2181 return NULL;
2182 }
2183
2184 return address;
2185}
2186
paul94f2b392005-06-28 12:44:16 +00002187static void
paul718e3742002-12-13 20:15:29 +00002188route_set_vpnv4_nexthop_free (void *rule)
2189{
2190 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2191}
2192
2193/* Route map commands for ip nexthop set. */
2194struct route_map_rule_cmd route_set_vpnv4_nexthop_cmd =
2195{
2196 "vpnv4 next-hop",
2197 route_set_vpnv4_nexthop,
2198 route_set_vpnv4_nexthop_compile,
2199 route_set_vpnv4_nexthop_free
2200};
David Lamparter6b0655a2014-06-04 06:53:35 +02002201
paul718e3742002-12-13 20:15:29 +00002202/* `set originator-id' */
2203
2204/* For origin set. */
paul94f2b392005-06-28 12:44:16 +00002205static route_map_result_t
paul718e3742002-12-13 20:15:29 +00002206route_set_originator_id (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
2207{
2208 struct in_addr *address;
2209 struct bgp_info *bgp_info;
2210
2211 if (type == RMAP_BGP)
2212 {
2213 address = rule;
2214 bgp_info = object;
2215
2216 bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
Paul Jakmafb982c22007-05-04 20:15:47 +00002217 (bgp_attr_extra_get (bgp_info->attr))->originator_id = *address;
paul718e3742002-12-13 20:15:29 +00002218 }
2219
2220 return RMAP_OKAY;
2221}
2222
2223/* Compile function for originator-id set. */
paul94f2b392005-06-28 12:44:16 +00002224static void *
paulfd79ac92004-10-13 05:06:08 +00002225route_set_originator_id_compile (const char *arg)
paul718e3742002-12-13 20:15:29 +00002226{
2227 int ret;
2228 struct in_addr *address;
2229
2230 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
2231
2232 ret = inet_aton (arg, address);
2233
2234 if (ret == 0)
2235 {
2236 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
2237 return NULL;
2238 }
2239
2240 return address;
2241}
2242
2243/* Compile function for originator_id set. */
paul94f2b392005-06-28 12:44:16 +00002244static void
paul718e3742002-12-13 20:15:29 +00002245route_set_originator_id_free (void *rule)
2246{
2247 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
2248}
2249
Timo Teräs2aa640b2014-05-20 08:57:26 +03002250/* Set originator-id rule structure. */
paul718e3742002-12-13 20:15:29 +00002251struct route_map_rule_cmd route_set_originator_id_cmd =
2252{
2253 "originator-id",
2254 route_set_originator_id,
2255 route_set_originator_id_compile,
2256 route_set_originator_id_free,
2257};
David Lamparter6b0655a2014-06-04 06:53:35 +02002258
paul718e3742002-12-13 20:15:29 +00002259/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002260static int
paul718e3742002-12-13 20:15:29 +00002261bgp_route_match_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002262 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002263{
2264 int ret;
2265
2266 ret = route_map_add_match (index, command, arg);
2267 if (ret)
2268 {
2269 switch (ret)
2270 {
2271 case RMAP_RULE_MISSING:
2272 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2273 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002274 case RMAP_COMPILE_ERROR:
2275 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2276 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002277 }
2278 }
2279 return CMD_SUCCESS;
2280}
2281
2282/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002283static int
paul718e3742002-12-13 20:15:29 +00002284bgp_route_match_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002285 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002286{
2287 int ret;
2288
2289 ret = route_map_delete_match (index, command, arg);
2290 if (ret)
2291 {
2292 switch (ret)
2293 {
2294 case RMAP_RULE_MISSING:
2295 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2296 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002297 case RMAP_COMPILE_ERROR:
2298 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2299 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002300 }
2301 }
2302 return CMD_SUCCESS;
2303}
2304
2305/* Add bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002306static int
paul718e3742002-12-13 20:15:29 +00002307bgp_route_set_add (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002308 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002309{
2310 int ret;
2311
2312 ret = route_map_add_set (index, command, arg);
2313 if (ret)
2314 {
2315 switch (ret)
2316 {
2317 case RMAP_RULE_MISSING:
2318 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2319 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002320 case RMAP_COMPILE_ERROR:
2321 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2322 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002323 }
2324 }
2325 return CMD_SUCCESS;
2326}
2327
2328/* Delete bgp route map rule. */
paul94f2b392005-06-28 12:44:16 +00002329static int
paul718e3742002-12-13 20:15:29 +00002330bgp_route_set_delete (struct vty *vty, struct route_map_index *index,
paulfd79ac92004-10-13 05:06:08 +00002331 const char *command, const char *arg)
paul718e3742002-12-13 20:15:29 +00002332{
2333 int ret;
2334
2335 ret = route_map_delete_set (index, command, arg);
2336 if (ret)
2337 {
2338 switch (ret)
2339 {
2340 case RMAP_RULE_MISSING:
2341 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
2342 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002343 case RMAP_COMPILE_ERROR:
2344 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
2345 return CMD_WARNING;
paul718e3742002-12-13 20:15:29 +00002346 }
2347 }
2348 return CMD_SUCCESS;
2349}
2350
2351/* Hook function for updating route_map assignment. */
paul94f2b392005-06-28 12:44:16 +00002352static void
paulfd79ac92004-10-13 05:06:08 +00002353bgp_route_map_update (const char *unused)
paul718e3742002-12-13 20:15:29 +00002354{
2355 int i;
2356 afi_t afi;
2357 safi_t safi;
2358 int direct;
paul1eb8ef22005-04-07 07:30:20 +00002359 struct listnode *node, *nnode;
2360 struct listnode *mnode, *mnnode;
paul718e3742002-12-13 20:15:29 +00002361 struct bgp *bgp;
2362 struct peer *peer;
2363 struct peer_group *group;
2364 struct bgp_filter *filter;
2365 struct bgp_node *bn;
2366 struct bgp_static *bgp_static;
2367
2368 /* For neighbor route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002369 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002370 {
paul1eb8ef22005-04-07 07:30:20 +00002371 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002372 {
2373 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2374 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2375 {
2376 filter = &peer->filter[afi][safi];
2377
paulfee0f4c2004-09-13 05:12:46 +00002378 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002379 {
2380 if (filter->map[direct].name)
2381 filter->map[direct].map =
2382 route_map_lookup_by_name (filter->map[direct].name);
2383 else
2384 filter->map[direct].map = NULL;
2385 }
2386
2387 if (filter->usmap.name)
2388 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2389 else
2390 filter->usmap.map = NULL;
2391 }
2392 }
paul1eb8ef22005-04-07 07:30:20 +00002393 for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
paul718e3742002-12-13 20:15:29 +00002394 {
2395 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2396 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2397 {
2398 filter = &group->conf->filter[afi][safi];
2399
paulfee0f4c2004-09-13 05:12:46 +00002400 for (direct = RMAP_IN; direct < RMAP_MAX; direct++)
paul718e3742002-12-13 20:15:29 +00002401 {
2402 if (filter->map[direct].name)
2403 filter->map[direct].map =
2404 route_map_lookup_by_name (filter->map[direct].name);
2405 else
2406 filter->map[direct].map = NULL;
2407 }
2408
2409 if (filter->usmap.name)
2410 filter->usmap.map = route_map_lookup_by_name (filter->usmap.name);
2411 else
2412 filter->usmap.map = NULL;
2413 }
2414 }
2415 }
2416
2417 /* For default-originate route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002418 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002419 {
paul1eb8ef22005-04-07 07:30:20 +00002420 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
paul718e3742002-12-13 20:15:29 +00002421 {
2422 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2423 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2424 {
2425 if (peer->default_rmap[afi][safi].name)
2426 peer->default_rmap[afi][safi].map =
2427 route_map_lookup_by_name (peer->default_rmap[afi][safi].name);
2428 else
2429 peer->default_rmap[afi][safi].map = NULL;
2430 }
2431 }
2432 }
2433
2434 /* For network route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002435 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002436 {
2437 for (afi = AFI_IP; afi < AFI_MAX; afi++)
2438 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
2439 for (bn = bgp_table_top (bgp->route[afi][safi]); bn;
2440 bn = bgp_route_next (bn))
2441 if ((bgp_static = bn->info) != NULL)
2442 {
2443 if (bgp_static->rmap.name)
2444 bgp_static->rmap.map =
2445 route_map_lookup_by_name (bgp_static->rmap.name);
2446 else
2447 bgp_static->rmap.map = NULL;
2448 }
2449 }
2450
2451 /* For redistribute route-map updates. */
paul1eb8ef22005-04-07 07:30:20 +00002452 for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
paul718e3742002-12-13 20:15:29 +00002453 {
2454 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
2455 {
2456 if (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name)
2457 bgp->rmap[ZEBRA_FAMILY_IPV4][i].map =
2458 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV4][i].name);
2459#ifdef HAVE_IPV6
2460 if (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name)
2461 bgp->rmap[ZEBRA_FAMILY_IPV6][i].map =
2462 route_map_lookup_by_name (bgp->rmap[ZEBRA_FAMILY_IPV6][i].name);
2463#endif /* HAVE_IPV6 */
2464 }
2465 }
2466}
David Lamparter6b0655a2014-06-04 06:53:35 +02002467
paulfee0f4c2004-09-13 05:12:46 +00002468DEFUN (match_peer,
2469 match_peer_cmd,
2470 "match peer (A.B.C.D|X:X::X:X)",
2471 MATCH_STR
2472 "Match peer address\n"
2473 "IPv6 address of peer\n"
2474 "IP address of peer\n")
2475{
2476 return bgp_route_match_add (vty, vty->index, "peer", argv[0]);
2477}
2478
2479DEFUN (match_peer_local,
2480 match_peer_local_cmd,
2481 "match peer local",
2482 MATCH_STR
2483 "Match peer address\n"
2484 "Static or Redistributed routes\n")
2485{
Jorge Boncompte [DTI2]4fe080d2012-04-13 13:46:08 +02002486 return bgp_route_match_add (vty, vty->index, "peer", "local");
paulfee0f4c2004-09-13 05:12:46 +00002487}
2488
2489DEFUN (no_match_peer,
2490 no_match_peer_cmd,
2491 "no match peer",
2492 NO_STR
2493 MATCH_STR
2494 "Match peer address\n")
2495{
2496 if (argc == 0)
2497 return bgp_route_match_delete (vty, vty->index, "peer", NULL);
2498
2499 return bgp_route_match_delete (vty, vty->index, "peer", argv[0]);
2500}
2501
2502ALIAS (no_match_peer,
2503 no_match_peer_val_cmd,
2504 "no match peer (A.B.C.D|X:X::X:X)",
2505 NO_STR
2506 MATCH_STR
2507 "Match peer address\n"
2508 "IPv6 address of peer\n"
2509 "IP address of peer\n")
2510
2511ALIAS (no_match_peer,
2512 no_match_peer_local_cmd,
2513 "no match peer local",
2514 NO_STR
2515 MATCH_STR
2516 "Match peer address\n"
2517 "Static or Redistributed routes\n")
2518
paul718e3742002-12-13 20:15:29 +00002519DEFUN (match_ip_address,
2520 match_ip_address_cmd,
2521 "match ip address (<1-199>|<1300-2699>|WORD)",
2522 MATCH_STR
2523 IP_STR
2524 "Match address of route\n"
2525 "IP access-list number\n"
2526 "IP access-list number (expanded range)\n"
2527 "IP Access-list name\n")
2528{
2529 return bgp_route_match_add (vty, vty->index, "ip address", argv[0]);
2530}
2531
2532DEFUN (no_match_ip_address,
2533 no_match_ip_address_cmd,
2534 "no match ip address",
2535 NO_STR
2536 MATCH_STR
2537 IP_STR
2538 "Match address of route\n")
2539{
2540 if (argc == 0)
2541 return bgp_route_match_delete (vty, vty->index, "ip address", NULL);
2542
2543 return bgp_route_match_delete (vty, vty->index, "ip address", argv[0]);
2544}
2545
2546ALIAS (no_match_ip_address,
2547 no_match_ip_address_val_cmd,
2548 "no match ip address (<1-199>|<1300-2699>|WORD)",
2549 NO_STR
2550 MATCH_STR
2551 IP_STR
2552 "Match address of route\n"
2553 "IP access-list number\n"
2554 "IP access-list number (expanded range)\n"
2555 "IP Access-list name\n")
2556
2557DEFUN (match_ip_next_hop,
2558 match_ip_next_hop_cmd,
2559 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
2560 MATCH_STR
2561 IP_STR
2562 "Match next-hop address of route\n"
2563 "IP access-list number\n"
2564 "IP access-list number (expanded range)\n"
2565 "IP Access-list name\n")
2566{
2567 return bgp_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
2568}
2569
2570DEFUN (no_match_ip_next_hop,
2571 no_match_ip_next_hop_cmd,
2572 "no match ip next-hop",
2573 NO_STR
2574 MATCH_STR
2575 IP_STR
2576 "Match next-hop address of route\n")
2577{
2578 if (argc == 0)
2579 return bgp_route_match_delete (vty, vty->index, "ip next-hop", NULL);
2580
2581 return bgp_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
2582}
2583
2584ALIAS (no_match_ip_next_hop,
2585 no_match_ip_next_hop_val_cmd,
2586 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
2587 NO_STR
2588 MATCH_STR
2589 IP_STR
2590 "Match next-hop address of route\n"
2591 "IP access-list number\n"
2592 "IP access-list number (expanded range)\n"
2593 "IP Access-list name\n")
2594
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04002595/* match probability { */
2596
2597DEFUN (match_probability,
2598 match_probability_cmd,
2599 "match probability <0-100>",
2600 MATCH_STR
2601 "Match portion of routes defined by percentage value\n"
2602 "Percentage of routes\n")
2603{
2604 return bgp_route_match_add (vty, vty->index, "probability", argv[0]);
2605}
2606
2607DEFUN (no_match_probability,
2608 no_match_probability_cmd,
2609 "no match probability",
2610 NO_STR
2611 MATCH_STR
2612 "Match portion of routes defined by percentage value\n")
2613{
2614 return bgp_route_match_delete (vty, vty->index, "probability", argc ? argv[0] : NULL);
2615}
2616
2617ALIAS (no_match_probability,
2618 no_match_probability_val_cmd,
2619 "no match probability <1-99>",
2620 NO_STR
2621 MATCH_STR
2622 "Match portion of routes defined by percentage value\n"
2623 "Percentage of routes\n")
2624
2625/* } */
2626
hassoc1643bb2005-02-02 16:43:17 +00002627DEFUN (match_ip_route_source,
2628 match_ip_route_source_cmd,
2629 "match ip route-source (<1-199>|<1300-2699>|WORD)",
2630 MATCH_STR
2631 IP_STR
2632 "Match advertising source address of route\n"
2633 "IP access-list number\n"
2634 "IP access-list number (expanded range)\n"
2635 "IP standard access-list name\n")
2636{
2637 return bgp_route_match_add (vty, vty->index, "ip route-source", argv[0]);
2638}
2639
2640DEFUN (no_match_ip_route_source,
2641 no_match_ip_route_source_cmd,
2642 "no match ip route-source",
2643 NO_STR
2644 MATCH_STR
2645 IP_STR
2646 "Match advertising source address of route\n")
2647{
2648 if (argc == 0)
2649 return bgp_route_match_delete (vty, vty->index, "ip route-source", NULL);
2650
2651 return bgp_route_match_delete (vty, vty->index, "ip route-source", argv[0]);
2652}
2653
2654ALIAS (no_match_ip_route_source,
2655 no_match_ip_route_source_val_cmd,
2656 "no match ip route-source (<1-199>|<1300-2699>|WORD)",
2657 NO_STR
2658 MATCH_STR
2659 IP_STR
2660 "Match advertising source address of route\n"
2661 "IP access-list number\n"
2662 "IP access-list number (expanded range)\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002663 "IP standard access-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002664
paul718e3742002-12-13 20:15:29 +00002665DEFUN (match_ip_address_prefix_list,
2666 match_ip_address_prefix_list_cmd,
2667 "match ip address prefix-list WORD",
2668 MATCH_STR
2669 IP_STR
2670 "Match address of route\n"
2671 "Match entries of prefix-lists\n"
2672 "IP prefix-list name\n")
2673{
2674 return bgp_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
2675}
2676
2677DEFUN (no_match_ip_address_prefix_list,
2678 no_match_ip_address_prefix_list_cmd,
2679 "no match ip address prefix-list",
2680 NO_STR
2681 MATCH_STR
2682 IP_STR
2683 "Match address of route\n"
2684 "Match entries of prefix-lists\n")
2685{
2686 if (argc == 0)
2687 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
2688
2689 return bgp_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
2690}
2691
2692ALIAS (no_match_ip_address_prefix_list,
2693 no_match_ip_address_prefix_list_val_cmd,
2694 "no match ip address prefix-list WORD",
2695 NO_STR
2696 MATCH_STR
2697 IP_STR
2698 "Match address of route\n"
2699 "Match entries of prefix-lists\n"
2700 "IP prefix-list name\n")
2701
2702DEFUN (match_ip_next_hop_prefix_list,
2703 match_ip_next_hop_prefix_list_cmd,
2704 "match ip next-hop prefix-list WORD",
2705 MATCH_STR
2706 IP_STR
2707 "Match next-hop address of route\n"
2708 "Match entries of prefix-lists\n"
2709 "IP prefix-list name\n")
2710{
2711 return bgp_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2712}
2713
2714DEFUN (no_match_ip_next_hop_prefix_list,
2715 no_match_ip_next_hop_prefix_list_cmd,
2716 "no match ip next-hop prefix-list",
2717 NO_STR
2718 MATCH_STR
2719 IP_STR
2720 "Match next-hop address of route\n"
2721 "Match entries of prefix-lists\n")
2722{
2723 if (argc == 0)
2724 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
2725
2726 return bgp_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
2727}
2728
2729ALIAS (no_match_ip_next_hop_prefix_list,
2730 no_match_ip_next_hop_prefix_list_val_cmd,
2731 "no match ip next-hop prefix-list WORD",
2732 NO_STR
2733 MATCH_STR
2734 IP_STR
2735 "Match next-hop address of route\n"
2736 "Match entries of prefix-lists\n"
2737 "IP prefix-list name\n")
2738
hassoc1643bb2005-02-02 16:43:17 +00002739DEFUN (match_ip_route_source_prefix_list,
2740 match_ip_route_source_prefix_list_cmd,
2741 "match ip route-source prefix-list WORD",
2742 MATCH_STR
2743 IP_STR
2744 "Match advertising source address of route\n"
2745 "Match entries of prefix-lists\n"
2746 "IP prefix-list name\n")
2747{
2748 return bgp_route_match_add (vty, vty->index, "ip route-source prefix-list", argv[0]);
2749}
2750
2751DEFUN (no_match_ip_route_source_prefix_list,
2752 no_match_ip_route_source_prefix_list_cmd,
2753 "no match ip route-source prefix-list",
2754 NO_STR
2755 MATCH_STR
2756 IP_STR
2757 "Match advertising source address of route\n"
2758 "Match entries of prefix-lists\n")
2759{
2760 if (argc == 0)
2761 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", NULL);
2762
2763 return bgp_route_match_delete (vty, vty->index, "ip route-source prefix-list", argv[0]);
2764}
2765
2766ALIAS (no_match_ip_route_source_prefix_list,
2767 no_match_ip_route_source_prefix_list_val_cmd,
2768 "no match ip route-source prefix-list WORD",
2769 NO_STR
2770 MATCH_STR
2771 IP_STR
2772 "Match advertising source address of route\n"
2773 "Match entries of prefix-lists\n"
Paul Jakma30a22312008-08-15 14:05:22 +01002774 "IP prefix-list name\n")
hassoc1643bb2005-02-02 16:43:17 +00002775
paul718e3742002-12-13 20:15:29 +00002776DEFUN (match_metric,
2777 match_metric_cmd,
2778 "match metric <0-4294967295>",
2779 MATCH_STR
2780 "Match metric of route\n"
2781 "Metric value\n")
2782{
2783 return bgp_route_match_add (vty, vty->index, "metric", argv[0]);
2784}
2785
2786DEFUN (no_match_metric,
2787 no_match_metric_cmd,
2788 "no match metric",
2789 NO_STR
2790 MATCH_STR
2791 "Match metric of route\n")
2792{
2793 if (argc == 0)
2794 return bgp_route_match_delete (vty, vty->index, "metric", NULL);
2795
2796 return bgp_route_match_delete (vty, vty->index, "metric", argv[0]);
2797}
2798
2799ALIAS (no_match_metric,
2800 no_match_metric_val_cmd,
2801 "no match metric <0-4294967295>",
2802 NO_STR
2803 MATCH_STR
2804 "Match metric of route\n"
2805 "Metric value\n")
2806
2807DEFUN (match_community,
2808 match_community_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002809 "match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002810 MATCH_STR
2811 "Match BGP community list\n"
2812 "Community-list number (standard)\n"
2813 "Community-list number (expanded)\n"
2814 "Community-list name\n")
2815{
2816 return bgp_route_match_add (vty, vty->index, "community", argv[0]);
2817}
2818
2819DEFUN (match_community_exact,
2820 match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002821 "match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002822 MATCH_STR
2823 "Match BGP community list\n"
2824 "Community-list number (standard)\n"
2825 "Community-list number (expanded)\n"
2826 "Community-list name\n"
2827 "Do exact matching of communities\n")
2828{
2829 int ret;
2830 char *argstr;
2831
2832 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
2833 strlen (argv[0]) + strlen ("exact-match") + 2);
2834
2835 sprintf (argstr, "%s exact-match", argv[0]);
2836
2837 ret = bgp_route_match_add (vty, vty->index, "community", argstr);
2838
2839 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
2840
2841 return ret;
2842}
2843
2844DEFUN (no_match_community,
2845 no_match_community_cmd,
2846 "no match community",
2847 NO_STR
2848 MATCH_STR
2849 "Match BGP community list\n")
2850{
2851 return bgp_route_match_delete (vty, vty->index, "community", NULL);
2852}
2853
2854ALIAS (no_match_community,
2855 no_match_community_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002856 "no match community (<1-99>|<100-500>|WORD)",
paul718e3742002-12-13 20:15:29 +00002857 NO_STR
2858 MATCH_STR
2859 "Match BGP community list\n"
2860 "Community-list number (standard)\n"
2861 "Community-list number (expanded)\n"
2862 "Community-list name\n")
2863
2864ALIAS (no_match_community,
2865 no_match_community_exact_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002866 "no match community (<1-99>|<100-500>|WORD) exact-match",
paul718e3742002-12-13 20:15:29 +00002867 NO_STR
2868 MATCH_STR
2869 "Match BGP community list\n"
2870 "Community-list number (standard)\n"
2871 "Community-list number (expanded)\n"
2872 "Community-list name\n"
2873 "Do exact matching of communities\n")
2874
paul73ffb252003-04-19 15:49:49 +00002875DEFUN (match_ecommunity,
2876 match_ecommunity_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002877 "match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002878 MATCH_STR
2879 "Match BGP/VPN extended community list\n"
2880 "Extended community-list number (standard)\n"
2881 "Extended community-list number (expanded)\n"
2882 "Extended community-list name\n")
2883{
2884 return bgp_route_match_add (vty, vty->index, "extcommunity", argv[0]);
2885}
2886
2887DEFUN (no_match_ecommunity,
2888 no_match_ecommunity_cmd,
2889 "no match extcommunity",
2890 NO_STR
2891 MATCH_STR
2892 "Match BGP/VPN extended community list\n")
2893{
2894 return bgp_route_match_delete (vty, vty->index, "extcommunity", NULL);
2895}
2896
2897ALIAS (no_match_ecommunity,
2898 no_match_ecommunity_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00002899 "no match extcommunity (<1-99>|<100-500>|WORD)",
paul73ffb252003-04-19 15:49:49 +00002900 NO_STR
2901 MATCH_STR
2902 "Match BGP/VPN extended community list\n"
2903 "Extended community-list number (standard)\n"
2904 "Extended community-list number (expanded)\n"
2905 "Extended community-list name\n")
2906
paul718e3742002-12-13 20:15:29 +00002907DEFUN (match_aspath,
2908 match_aspath_cmd,
2909 "match as-path WORD",
2910 MATCH_STR
2911 "Match BGP AS path list\n"
2912 "AS path access-list name\n")
2913{
2914 return bgp_route_match_add (vty, vty->index, "as-path", argv[0]);
2915}
2916
2917DEFUN (no_match_aspath,
2918 no_match_aspath_cmd,
2919 "no match as-path",
2920 NO_STR
2921 MATCH_STR
2922 "Match BGP AS path list\n")
2923{
2924 return bgp_route_match_delete (vty, vty->index, "as-path", NULL);
2925}
2926
2927ALIAS (no_match_aspath,
2928 no_match_aspath_val_cmd,
2929 "no match as-path WORD",
2930 NO_STR
2931 MATCH_STR
2932 "Match BGP AS path list\n"
2933 "AS path access-list name\n")
2934
2935DEFUN (match_origin,
2936 match_origin_cmd,
2937 "match origin (egp|igp|incomplete)",
2938 MATCH_STR
2939 "BGP origin code\n"
2940 "remote EGP\n"
2941 "local IGP\n"
2942 "unknown heritage\n")
2943{
2944 if (strncmp (argv[0], "igp", 2) == 0)
2945 return bgp_route_match_add (vty, vty->index, "origin", "igp");
2946 if (strncmp (argv[0], "egp", 1) == 0)
2947 return bgp_route_match_add (vty, vty->index, "origin", "egp");
2948 if (strncmp (argv[0], "incomplete", 2) == 0)
2949 return bgp_route_match_add (vty, vty->index, "origin", "incomplete");
2950
2951 return CMD_WARNING;
2952}
2953
2954DEFUN (no_match_origin,
2955 no_match_origin_cmd,
2956 "no match origin",
2957 NO_STR
2958 MATCH_STR
2959 "BGP origin code\n")
2960{
2961 return bgp_route_match_delete (vty, vty->index, "origin", NULL);
2962}
2963
2964ALIAS (no_match_origin,
2965 no_match_origin_val_cmd,
2966 "no match origin (egp|igp|incomplete)",
2967 NO_STR
2968 MATCH_STR
2969 "BGP origin code\n"
2970 "remote EGP\n"
2971 "local IGP\n"
2972 "unknown heritage\n")
2973
2974DEFUN (set_ip_nexthop,
2975 set_ip_nexthop_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00002976 "set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00002977 SET_STR
2978 IP_STR
2979 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00002980 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00002981{
2982 union sockunion su;
2983 int ret;
2984
2985 ret = str2sockunion (argv[0], &su);
2986 if (ret < 0)
2987 {
2988 vty_out (vty, "%% Malformed Next-hop address%s", VTY_NEWLINE);
2989 return CMD_WARNING;
2990 }
2991
2992 return bgp_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
2993}
2994
paulaf5cd0a2003-11-02 07:24:40 +00002995DEFUN (set_ip_nexthop_peer,
2996 set_ip_nexthop_peer_cmd,
2997 "set ip next-hop peer-address",
2998 SET_STR
2999 IP_STR
3000 "Next hop address\n"
3001 "Use peer address (for BGP only)\n")
3002{
3003 return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address");
3004}
3005
paul94f2b392005-06-28 12:44:16 +00003006DEFUN_DEPRECATED (no_set_ip_nexthop_peer,
paulaf5cd0a2003-11-02 07:24:40 +00003007 no_set_ip_nexthop_peer_cmd,
3008 "no set ip next-hop peer-address",
3009 NO_STR
3010 SET_STR
3011 IP_STR
3012 "Next hop address\n"
3013 "Use peer address (for BGP only)\n")
3014{
3015 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
3016}
3017
3018
paul718e3742002-12-13 20:15:29 +00003019DEFUN (no_set_ip_nexthop,
3020 no_set_ip_nexthop_cmd,
3021 "no set ip next-hop",
3022 NO_STR
3023 SET_STR
paul718e3742002-12-13 20:15:29 +00003024 "Next hop address\n")
3025{
paulaf5cd0a2003-11-02 07:24:40 +00003026 if (argc == 0)
paul718e3742002-12-13 20:15:29 +00003027 return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL);
3028
3029 return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
3030}
3031
3032ALIAS (no_set_ip_nexthop,
3033 no_set_ip_nexthop_val_cmd,
paulaf5cd0a2003-11-02 07:24:40 +00003034 "no set ip next-hop A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003035 NO_STR
3036 SET_STR
3037 IP_STR
3038 "Next hop address\n"
paulaf5cd0a2003-11-02 07:24:40 +00003039 "IP address of next hop\n")
paul718e3742002-12-13 20:15:29 +00003040
3041DEFUN (set_metric,
3042 set_metric_cmd,
paul73ffb252003-04-19 15:49:49 +00003043 "set metric <0-4294967295>",
paul718e3742002-12-13 20:15:29 +00003044 SET_STR
3045 "Metric value for destination routing protocol\n"
paul73ffb252003-04-19 15:49:49 +00003046 "Metric value\n")
paul718e3742002-12-13 20:15:29 +00003047{
3048 return bgp_route_set_add (vty, vty->index, "metric", argv[0]);
3049}
3050
paul73ffb252003-04-19 15:49:49 +00003051ALIAS (set_metric,
3052 set_metric_addsub_cmd,
3053 "set metric <+/-metric>",
3054 SET_STR
3055 "Metric value for destination routing protocol\n"
hasso033e8612005-05-28 04:50:54 +00003056 "Add or subtract metric\n")
paul73ffb252003-04-19 15:49:49 +00003057
paul718e3742002-12-13 20:15:29 +00003058DEFUN (no_set_metric,
3059 no_set_metric_cmd,
3060 "no set metric",
3061 NO_STR
3062 SET_STR
3063 "Metric value for destination routing protocol\n")
3064{
3065 if (argc == 0)
3066 return bgp_route_set_delete (vty, vty->index, "metric", NULL);
3067
3068 return bgp_route_set_delete (vty, vty->index, "metric", argv[0]);
3069}
3070
3071ALIAS (no_set_metric,
3072 no_set_metric_val_cmd,
3073 "no set metric <0-4294967295>",
3074 NO_STR
3075 SET_STR
3076 "Metric value for destination routing protocol\n"
3077 "Metric value\n")
3078
3079DEFUN (set_local_pref,
3080 set_local_pref_cmd,
3081 "set local-preference <0-4294967295>",
3082 SET_STR
3083 "BGP local preference path attribute\n"
3084 "Preference value\n")
3085{
3086 return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
3087}
3088
3089DEFUN (no_set_local_pref,
3090 no_set_local_pref_cmd,
3091 "no set local-preference",
3092 NO_STR
3093 SET_STR
3094 "BGP local preference path attribute\n")
3095{
3096 if (argc == 0)
3097 return bgp_route_set_delete (vty, vty->index, "local-preference", NULL);
3098
3099 return bgp_route_set_delete (vty, vty->index, "local-preference", argv[0]);
3100}
3101
3102ALIAS (no_set_local_pref,
3103 no_set_local_pref_val_cmd,
3104 "no set local-preference <0-4294967295>",
3105 NO_STR
3106 SET_STR
3107 "BGP local preference path attribute\n"
3108 "Preference value\n")
3109
3110DEFUN (set_weight,
3111 set_weight_cmd,
3112 "set weight <0-4294967295>",
3113 SET_STR
3114 "BGP weight for routing table\n"
3115 "Weight value\n")
3116{
3117 return bgp_route_set_add (vty, vty->index, "weight", argv[0]);
3118}
3119
3120DEFUN (no_set_weight,
3121 no_set_weight_cmd,
3122 "no set weight",
3123 NO_STR
3124 SET_STR
3125 "BGP weight for routing table\n")
3126{
3127 if (argc == 0)
3128 return bgp_route_set_delete (vty, vty->index, "weight", NULL);
3129
3130 return bgp_route_set_delete (vty, vty->index, "weight", argv[0]);
3131}
3132
3133ALIAS (no_set_weight,
3134 no_set_weight_val_cmd,
3135 "no set weight <0-4294967295>",
3136 NO_STR
3137 SET_STR
3138 "BGP weight for routing table\n"
3139 "Weight value\n")
3140
3141DEFUN (set_aspath_prepend,
3142 set_aspath_prepend_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003143 "set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003144 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003145 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003146 "Prepend to the as-path\n"
3147 "AS number\n")
3148{
3149 int ret;
3150 char *str;
3151
3152 str = argv_concat (argv, argc, 0);
3153 ret = bgp_route_set_add (vty, vty->index, "as-path prepend", str);
3154 XFREE (MTYPE_TMP, str);
3155
3156 return ret;
3157}
3158
Timo Teräs85c854a2014-09-30 11:31:53 +03003159ALIAS (set_aspath_prepend,
3160 set_aspath_prepend_lastas_cmd,
3161 "set as-path prepend (last-as) <1-10>",
3162 SET_STR
3163 "Transform BGP AS_PATH attribute\n"
3164 "Prepend to the as-path\n"
3165 "Use the peer's AS-number\n"
3166 "Number of times to insert");
3167
paul718e3742002-12-13 20:15:29 +00003168DEFUN (no_set_aspath_prepend,
3169 no_set_aspath_prepend_cmd,
3170 "no set as-path prepend",
3171 NO_STR
3172 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003173 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003174 "Prepend to the as-path\n")
3175{
Denis Ovsienkoa7f93f32007-12-18 15:13:06 +00003176 int ret;
3177 char *str;
3178
3179 if (argc == 0)
3180 return bgp_route_set_delete (vty, vty->index, "as-path prepend", NULL);
3181
3182 str = argv_concat (argv, argc, 0);
3183 ret = bgp_route_set_delete (vty, vty->index, "as-path prepend", str);
3184 XFREE (MTYPE_TMP, str);
3185 return ret;
paul718e3742002-12-13 20:15:29 +00003186}
3187
3188ALIAS (no_set_aspath_prepend,
3189 no_set_aspath_prepend_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003190 "no set as-path prepend ." CMD_AS_RANGE,
paul718e3742002-12-13 20:15:29 +00003191 NO_STR
3192 SET_STR
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003193 "Transform BGP AS_PATH attribute\n"
paul718e3742002-12-13 20:15:29 +00003194 "Prepend to the as-path\n"
3195 "AS number\n")
3196
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003197DEFUN (set_aspath_exclude,
3198 set_aspath_exclude_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003199 "set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003200 SET_STR
3201 "Transform BGP AS-path attribute\n"
3202 "Exclude from the as-path\n"
3203 "AS number\n")
3204{
3205 int ret;
3206 char *str;
3207
3208 str = argv_concat (argv, argc, 0);
3209 ret = bgp_route_set_add (vty, vty->index, "as-path exclude", str);
3210 XFREE (MTYPE_TMP, str);
3211 return ret;
3212}
3213
3214DEFUN (no_set_aspath_exclude,
3215 no_set_aspath_exclude_cmd,
3216 "no set as-path exclude",
3217 NO_STR
3218 SET_STR
3219 "Transform BGP AS_PATH attribute\n"
3220 "Exclude from the as-path\n")
3221{
3222 int ret;
3223 char *str;
3224
3225 if (argc == 0)
3226 return bgp_route_set_delete (vty, vty->index, "as-path exclude", NULL);
3227
3228 str = argv_concat (argv, argc, 0);
3229 ret = bgp_route_set_delete (vty, vty->index, "as-path exclude", str);
3230 XFREE (MTYPE_TMP, str);
3231 return ret;
3232}
3233
3234ALIAS (no_set_aspath_exclude,
3235 no_set_aspath_exclude_val_cmd,
Denis Ovsienko10819ec2009-06-09 15:15:33 +04003236 "no set as-path exclude ." CMD_AS_RANGE,
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003237 NO_STR
3238 SET_STR
3239 "Transform BGP AS_PATH attribute\n"
3240 "Exclude from the as-path\n"
3241 "AS number\n")
3242
paul718e3742002-12-13 20:15:29 +00003243DEFUN (set_community,
3244 set_community_cmd,
3245 "set community .AA:NN",
3246 SET_STR
3247 "BGP community attribute\n"
3248 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3249{
3250 int i;
3251 int first = 0;
3252 int additive = 0;
3253 struct buffer *b;
3254 struct community *com = NULL;
3255 char *str;
3256 char *argstr;
3257 int ret;
3258
3259 b = buffer_new (1024);
3260
3261 for (i = 0; i < argc; i++)
3262 {
3263 if (strncmp (argv[i], "additive", strlen (argv[i])) == 0)
3264 {
3265 additive = 1;
3266 continue;
3267 }
3268
3269 if (first)
3270 buffer_putc (b, ' ');
3271 else
3272 first = 1;
3273
3274 if (strncmp (argv[i], "internet", strlen (argv[i])) == 0)
3275 {
3276 buffer_putstr (b, "internet");
3277 continue;
3278 }
3279 if (strncmp (argv[i], "local-AS", strlen (argv[i])) == 0)
3280 {
3281 buffer_putstr (b, "local-AS");
3282 continue;
3283 }
3284 if (strncmp (argv[i], "no-a", strlen ("no-a")) == 0
3285 && strncmp (argv[i], "no-advertise", strlen (argv[i])) == 0)
3286 {
3287 buffer_putstr (b, "no-advertise");
3288 continue;
3289 }
3290 if (strncmp (argv[i], "no-e", strlen ("no-e"))== 0
3291 && strncmp (argv[i], "no-export", strlen (argv[i])) == 0)
3292 {
3293 buffer_putstr (b, "no-export");
3294 continue;
3295 }
3296 buffer_putstr (b, argv[i]);
3297 }
3298 buffer_putc (b, '\0');
3299
3300 /* Fetch result string then compile it to communities attribute. */
3301 str = buffer_getstr (b);
3302 buffer_free (b);
3303
3304 if (str)
3305 {
3306 com = community_str2com (str);
ajs3b8b1852005-01-29 18:19:13 +00003307 XFREE (MTYPE_TMP, str);
paul718e3742002-12-13 20:15:29 +00003308 }
3309
3310 /* Can't compile user input into communities attribute. */
3311 if (! com)
3312 {
3313 vty_out (vty, "%% Malformed communities attribute%s", VTY_NEWLINE);
3314 return CMD_WARNING;
3315 }
3316
3317 /* Set communites attribute string. */
3318 str = community_str (com);
3319
3320 if (additive)
3321 {
3322 argstr = XCALLOC (MTYPE_TMP, strlen (str) + strlen (" additive") + 1);
3323 strcpy (argstr, str);
3324 strcpy (argstr + strlen (str), " additive");
3325 ret = bgp_route_set_add (vty, vty->index, "community", argstr);
3326 XFREE (MTYPE_TMP, argstr);
3327 }
3328 else
3329 ret = bgp_route_set_add (vty, vty->index, "community", str);
3330
3331 community_free (com);
3332
3333 return ret;
3334}
3335
3336DEFUN (set_community_none,
3337 set_community_none_cmd,
3338 "set community none",
3339 SET_STR
3340 "BGP community attribute\n"
3341 "No community attribute\n")
3342{
3343 return bgp_route_set_add (vty, vty->index, "community", "none");
3344}
3345
3346DEFUN (no_set_community,
3347 no_set_community_cmd,
3348 "no set community",
3349 NO_STR
3350 SET_STR
3351 "BGP community attribute\n")
3352{
3353 return bgp_route_set_delete (vty, vty->index, "community", NULL);
3354}
3355
3356ALIAS (no_set_community,
3357 no_set_community_val_cmd,
3358 "no set community .AA:NN",
3359 NO_STR
3360 SET_STR
3361 "BGP community attribute\n"
3362 "Community number in aa:nn format or local-AS|no-advertise|no-export|internet or additive\n")
3363
3364ALIAS (no_set_community,
3365 no_set_community_none_cmd,
3366 "no set community none",
3367 NO_STR
3368 SET_STR
3369 "BGP community attribute\n"
3370 "No community attribute\n")
3371
3372DEFUN (set_community_delete,
3373 set_community_delete_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003374 "set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003375 SET_STR
3376 "set BGP community list (for deletion)\n"
3377 "Community-list number (standard)\n"
3378 "Communitly-list number (expanded)\n"
3379 "Community-list name\n"
3380 "Delete matching communities\n")
3381{
3382 char *str;
3383
3384 str = XCALLOC (MTYPE_TMP, strlen (argv[0]) + strlen (" delete") + 1);
3385 strcpy (str, argv[0]);
3386 strcpy (str + strlen (argv[0]), " delete");
3387
3388 bgp_route_set_add (vty, vty->index, "comm-list", str);
3389
3390 XFREE (MTYPE_TMP, str);
3391 return CMD_SUCCESS;
3392}
3393
3394DEFUN (no_set_community_delete,
3395 no_set_community_delete_cmd,
3396 "no set comm-list",
3397 NO_STR
3398 SET_STR
3399 "set BGP community list (for deletion)\n")
3400{
3401 return bgp_route_set_delete (vty, vty->index, "comm-list", NULL);
3402}
3403
3404ALIAS (no_set_community_delete,
3405 no_set_community_delete_val_cmd,
hassofee6e4e2005-02-02 16:29:31 +00003406 "no set comm-list (<1-99>|<100-500>|WORD) delete",
paul718e3742002-12-13 20:15:29 +00003407 NO_STR
3408 SET_STR
3409 "set BGP community list (for deletion)\n"
3410 "Community-list number (standard)\n"
3411 "Communitly-list number (expanded)\n"
3412 "Community-list name\n"
3413 "Delete matching communities\n")
3414
3415DEFUN (set_ecommunity_rt,
3416 set_ecommunity_rt_cmd,
3417 "set extcommunity rt .ASN:nn_or_IP-address:nn",
3418 SET_STR
3419 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003420 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003421 "VPN extended community\n")
3422{
3423 int ret;
3424 char *str;
3425
3426 str = argv_concat (argv, argc, 0);
3427 ret = bgp_route_set_add (vty, vty->index, "extcommunity rt", str);
3428 XFREE (MTYPE_TMP, str);
3429
3430 return ret;
3431}
3432
3433DEFUN (no_set_ecommunity_rt,
3434 no_set_ecommunity_rt_cmd,
3435 "no set extcommunity rt",
3436 NO_STR
3437 SET_STR
3438 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003439 "Route Target extended community\n")
paul718e3742002-12-13 20:15:29 +00003440{
3441 return bgp_route_set_delete (vty, vty->index, "extcommunity rt", NULL);
3442}
3443
3444ALIAS (no_set_ecommunity_rt,
3445 no_set_ecommunity_rt_val_cmd,
3446 "no set extcommunity rt .ASN:nn_or_IP-address:nn",
3447 NO_STR
3448 SET_STR
3449 "BGP extended community attribute\n"
Denis Ovsienkoe6b6a562009-06-01 20:20:36 +04003450 "Route Target extended community\n"
paul718e3742002-12-13 20:15:29 +00003451 "VPN extended community\n")
3452
3453DEFUN (set_ecommunity_soo,
3454 set_ecommunity_soo_cmd,
3455 "set extcommunity soo .ASN:nn_or_IP-address:nn",
3456 SET_STR
3457 "BGP extended community attribute\n"
3458 "Site-of-Origin extended community\n"
3459 "VPN extended community\n")
3460{
3461 int ret;
3462 char *str;
3463
3464 str = argv_concat (argv, argc, 0);
3465 ret = bgp_route_set_add (vty, vty->index, "extcommunity soo", str);
3466 XFREE (MTYPE_TMP, str);
3467 return ret;
3468}
3469
3470DEFUN (no_set_ecommunity_soo,
3471 no_set_ecommunity_soo_cmd,
3472 "no set extcommunity soo",
3473 NO_STR
3474 SET_STR
3475 "BGP extended community attribute\n"
3476 "Site-of-Origin extended community\n")
3477{
3478 return bgp_route_set_delete (vty, vty->index, "extcommunity soo", NULL);
3479}
3480
3481ALIAS (no_set_ecommunity_soo,
3482 no_set_ecommunity_soo_val_cmd,
3483 "no set extcommunity soo .ASN:nn_or_IP-address:nn",
3484 NO_STR
3485 SET_STR
3486 "BGP extended community attribute\n"
3487 "Site-of-Origin extended community\n"
3488 "VPN extended community\n")
3489
3490DEFUN (set_origin,
3491 set_origin_cmd,
3492 "set origin (egp|igp|incomplete)",
3493 SET_STR
3494 "BGP origin code\n"
3495 "remote EGP\n"
3496 "local IGP\n"
3497 "unknown heritage\n")
3498{
3499 if (strncmp (argv[0], "igp", 2) == 0)
3500 return bgp_route_set_add (vty, vty->index, "origin", "igp");
3501 if (strncmp (argv[0], "egp", 1) == 0)
3502 return bgp_route_set_add (vty, vty->index, "origin", "egp");
3503 if (strncmp (argv[0], "incomplete", 2) == 0)
3504 return bgp_route_set_add (vty, vty->index, "origin", "incomplete");
3505
3506 return CMD_WARNING;
3507}
3508
3509DEFUN (no_set_origin,
3510 no_set_origin_cmd,
3511 "no set origin",
3512 NO_STR
3513 SET_STR
3514 "BGP origin code\n")
3515{
3516 return bgp_route_set_delete (vty, vty->index, "origin", NULL);
3517}
3518
3519ALIAS (no_set_origin,
3520 no_set_origin_val_cmd,
3521 "no set origin (egp|igp|incomplete)",
3522 NO_STR
3523 SET_STR
3524 "BGP origin code\n"
3525 "remote EGP\n"
3526 "local IGP\n"
3527 "unknown heritage\n")
3528
3529DEFUN (set_atomic_aggregate,
3530 set_atomic_aggregate_cmd,
3531 "set atomic-aggregate",
3532 SET_STR
3533 "BGP atomic aggregate attribute\n" )
3534{
3535 return bgp_route_set_add (vty, vty->index, "atomic-aggregate", NULL);
3536}
3537
3538DEFUN (no_set_atomic_aggregate,
3539 no_set_atomic_aggregate_cmd,
3540 "no set atomic-aggregate",
3541 NO_STR
3542 SET_STR
3543 "BGP atomic aggregate attribute\n" )
3544{
3545 return bgp_route_set_delete (vty, vty->index, "atomic-aggregate", NULL);
3546}
3547
3548DEFUN (set_aggregator_as,
3549 set_aggregator_as_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003550 "set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003551 SET_STR
3552 "BGP aggregator attribute\n"
3553 "AS number of aggregator\n"
3554 "AS number\n"
3555 "IP address of aggregator\n")
3556{
3557 int ret;
Paul Jakma7aa9dce2014-09-19 14:42:23 +01003558 as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
paul718e3742002-12-13 20:15:29 +00003559 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003560 char *argstr;
3561
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003562 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paulfd79ac92004-10-13 05:06:08 +00003563
paul718e3742002-12-13 20:15:29 +00003564 ret = inet_aton (argv[1], &address);
3565 if (ret == 0)
3566 {
3567 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3568 return CMD_WARNING;
3569 }
3570
3571 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3572 strlen (argv[0]) + strlen (argv[1]) + 2);
3573
3574 sprintf (argstr, "%s %s", argv[0], argv[1]);
3575
3576 ret = bgp_route_set_add (vty, vty->index, "aggregator as", argstr);
3577
3578 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3579
3580 return ret;
3581}
3582
3583DEFUN (no_set_aggregator_as,
3584 no_set_aggregator_as_cmd,
3585 "no set aggregator as",
3586 NO_STR
3587 SET_STR
3588 "BGP aggregator attribute\n"
3589 "AS number of aggregator\n")
3590{
3591 int ret;
Paul Jakma7aa9dce2014-09-19 14:42:23 +01003592 as_t as __attribute__((unused)); /* dummy for VTY_GET_INTEGER_RANGE */
paul718e3742002-12-13 20:15:29 +00003593 struct in_addr address;
paul718e3742002-12-13 20:15:29 +00003594 char *argstr;
3595
3596 if (argv == 0)
3597 return bgp_route_set_delete (vty, vty->index, "aggregator as", NULL);
3598
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00003599 VTY_GET_INTEGER_RANGE ("AS", as, argv[0], 1, BGP_AS4_MAX);
paul718e3742002-12-13 20:15:29 +00003600
3601 ret = inet_aton (argv[1], &address);
3602 if (ret == 0)
3603 {
3604 vty_out (vty, "Aggregator IP address is invalid%s", VTY_NEWLINE);
3605 return CMD_WARNING;
3606 }
3607
3608 argstr = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
3609 strlen (argv[0]) + strlen (argv[1]) + 2);
3610
3611 sprintf (argstr, "%s %s", argv[0], argv[1]);
3612
3613 ret = bgp_route_set_delete (vty, vty->index, "aggregator as", argstr);
3614
3615 XFREE (MTYPE_ROUTE_MAP_COMPILED, argstr);
3616
3617 return ret;
3618}
3619
3620ALIAS (no_set_aggregator_as,
3621 no_set_aggregator_as_val_cmd,
Paul Jakma320da872008-07-02 13:40:33 +00003622 "no set aggregator as " CMD_AS_RANGE " A.B.C.D",
paul718e3742002-12-13 20:15:29 +00003623 NO_STR
3624 SET_STR
3625 "BGP aggregator attribute\n"
3626 "AS number of aggregator\n"
3627 "AS number\n"
3628 "IP address of aggregator\n")
3629
David Lamparter6b0655a2014-06-04 06:53:35 +02003630
paul718e3742002-12-13 20:15:29 +00003631#ifdef HAVE_IPV6
3632DEFUN (match_ipv6_address,
3633 match_ipv6_address_cmd,
3634 "match ipv6 address WORD",
3635 MATCH_STR
3636 IPV6_STR
3637 "Match IPv6 address of route\n"
3638 "IPv6 access-list name\n")
3639{
3640 return bgp_route_match_add (vty, vty->index, "ipv6 address", argv[0]);
3641}
3642
3643DEFUN (no_match_ipv6_address,
3644 no_match_ipv6_address_cmd,
3645 "no match ipv6 address WORD",
3646 NO_STR
3647 MATCH_STR
3648 IPV6_STR
3649 "Match IPv6 address of route\n"
3650 "IPv6 access-list name\n")
3651{
3652 return bgp_route_match_delete (vty, vty->index, "ipv6 address", argv[0]);
3653}
3654
3655DEFUN (match_ipv6_next_hop,
3656 match_ipv6_next_hop_cmd,
3657 "match ipv6 next-hop X:X::X:X",
3658 MATCH_STR
3659 IPV6_STR
3660 "Match IPv6 next-hop address of route\n"
3661 "IPv6 address of next hop\n")
3662{
3663 return bgp_route_match_add (vty, vty->index, "ipv6 next-hop", argv[0]);
3664}
3665
3666DEFUN (no_match_ipv6_next_hop,
3667 no_match_ipv6_next_hop_cmd,
3668 "no match ipv6 next-hop X:X::X:X",
3669 NO_STR
3670 MATCH_STR
3671 IPV6_STR
3672 "Match IPv6 next-hop address of route\n"
3673 "IPv6 address of next hop\n")
3674{
3675 return bgp_route_match_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3676}
3677
3678DEFUN (match_ipv6_address_prefix_list,
3679 match_ipv6_address_prefix_list_cmd,
3680 "match ipv6 address prefix-list WORD",
3681 MATCH_STR
3682 IPV6_STR
3683 "Match address of route\n"
3684 "Match entries of prefix-lists\n"
3685 "IP prefix-list name\n")
3686{
3687 return bgp_route_match_add (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3688}
3689
3690DEFUN (no_match_ipv6_address_prefix_list,
3691 no_match_ipv6_address_prefix_list_cmd,
3692 "no match ipv6 address prefix-list WORD",
3693 NO_STR
3694 MATCH_STR
3695 IPV6_STR
3696 "Match address of route\n"
3697 "Match entries of prefix-lists\n"
3698 "IP prefix-list name\n")
3699{
3700 return bgp_route_match_delete (vty, vty->index, "ipv6 address prefix-list", argv[0]);
3701}
3702
Dinesh G Duttad5233a2014-09-30 14:19:57 -07003703DEFUN (set_ipv6_nexthop_peer,
3704 set_ipv6_nexthop_peer_cmd,
3705 "set ipv6 next-hop peer-address",
3706 SET_STR
3707 IPV6_STR
3708 "Next hop address\n"
3709 "Use peer address (for BGP only)\n")
3710{
3711 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop peer-address", NULL);
3712}
3713
3714DEFUN (no_set_ipv6_nexthop_peer,
3715 no_set_ipv6_nexthop_peer_cmd,
3716 "no set ipv6 next-hop peer-address",
3717 NO_STR
3718 SET_STR
3719 IPV6_STR
3720 "IPv6 next-hop address\n"
3721 )
3722{
3723 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop", argv[0]);
3724}
3725
paul718e3742002-12-13 20:15:29 +00003726DEFUN (set_ipv6_nexthop_global,
3727 set_ipv6_nexthop_global_cmd,
3728 "set ipv6 next-hop global X:X::X:X",
3729 SET_STR
3730 IPV6_STR
3731 "IPv6 next-hop address\n"
3732 "IPv6 global address\n"
3733 "IPv6 address of next hop\n")
3734{
3735 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop global", argv[0]);
3736}
3737
3738DEFUN (no_set_ipv6_nexthop_global,
3739 no_set_ipv6_nexthop_global_cmd,
3740 "no set ipv6 next-hop global",
3741 NO_STR
3742 SET_STR
3743 IPV6_STR
3744 "IPv6 next-hop address\n"
3745 "IPv6 global address\n")
3746{
3747 if (argc == 0)
3748 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", NULL);
3749
3750 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop global", argv[0]);
3751}
3752
3753ALIAS (no_set_ipv6_nexthop_global,
3754 no_set_ipv6_nexthop_global_val_cmd,
3755 "no set ipv6 next-hop global X:X::X:X",
3756 NO_STR
3757 SET_STR
3758 IPV6_STR
3759 "IPv6 next-hop address\n"
3760 "IPv6 global address\n"
3761 "IPv6 address of next hop\n")
3762
3763DEFUN (set_ipv6_nexthop_local,
3764 set_ipv6_nexthop_local_cmd,
3765 "set ipv6 next-hop local X:X::X:X",
3766 SET_STR
3767 IPV6_STR
3768 "IPv6 next-hop address\n"
3769 "IPv6 local address\n"
3770 "IPv6 address of next hop\n")
3771{
3772 return bgp_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
3773}
3774
3775DEFUN (no_set_ipv6_nexthop_local,
3776 no_set_ipv6_nexthop_local_cmd,
3777 "no set ipv6 next-hop local",
3778 NO_STR
3779 SET_STR
3780 IPV6_STR
3781 "IPv6 next-hop address\n"
3782 "IPv6 local address\n")
3783{
3784 if (argc == 0)
3785 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
3786
3787 return bgp_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
3788}
3789
3790ALIAS (no_set_ipv6_nexthop_local,
3791 no_set_ipv6_nexthop_local_val_cmd,
3792 "no set ipv6 next-hop local X:X::X:X",
3793 NO_STR
3794 SET_STR
3795 IPV6_STR
3796 "IPv6 next-hop address\n"
3797 "IPv6 local address\n"
3798 "IPv6 address of next hop\n")
3799#endif /* HAVE_IPV6 */
3800
3801DEFUN (set_vpnv4_nexthop,
3802 set_vpnv4_nexthop_cmd,
3803 "set vpnv4 next-hop A.B.C.D",
3804 SET_STR
3805 "VPNv4 information\n"
3806 "VPNv4 next-hop address\n"
3807 "IP address of next hop\n")
3808{
3809 return bgp_route_set_add (vty, vty->index, "vpnv4 next-hop", argv[0]);
3810}
3811
3812DEFUN (no_set_vpnv4_nexthop,
3813 no_set_vpnv4_nexthop_cmd,
3814 "no set vpnv4 next-hop",
3815 NO_STR
3816 SET_STR
3817 "VPNv4 information\n"
3818 "VPNv4 next-hop address\n")
3819{
3820 if (argc == 0)
3821 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", NULL);
3822
3823 return bgp_route_set_delete (vty, vty->index, "vpnv4 next-hop", argv[0]);
3824}
3825
3826ALIAS (no_set_vpnv4_nexthop,
3827 no_set_vpnv4_nexthop_val_cmd,
3828 "no set vpnv4 next-hop A.B.C.D",
3829 NO_STR
3830 SET_STR
3831 "VPNv4 information\n"
3832 "VPNv4 next-hop address\n"
3833 "IP address of next hop\n")
3834
3835DEFUN (set_originator_id,
3836 set_originator_id_cmd,
3837 "set originator-id A.B.C.D",
3838 SET_STR
3839 "BGP originator ID attribute\n"
3840 "IP address of originator\n")
3841{
3842 return bgp_route_set_add (vty, vty->index, "originator-id", argv[0]);
3843}
3844
3845DEFUN (no_set_originator_id,
3846 no_set_originator_id_cmd,
3847 "no set originator-id",
3848 NO_STR
3849 SET_STR
3850 "BGP originator ID attribute\n")
3851{
3852 if (argc == 0)
3853 return bgp_route_set_delete (vty, vty->index, "originator-id", NULL);
3854
3855 return bgp_route_set_delete (vty, vty->index, "originator-id", argv[0]);
3856}
3857
3858ALIAS (no_set_originator_id,
3859 no_set_originator_id_val_cmd,
3860 "no set originator-id A.B.C.D",
3861 NO_STR
3862 SET_STR
3863 "BGP originator ID attribute\n"
3864 "IP address of originator\n")
3865
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003866DEFUN_DEPRECATED (set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003867 set_pathlimit_ttl_cmd,
3868 "set pathlimit ttl <1-255>",
3869 SET_STR
3870 "BGP AS-Pathlimit attribute\n"
3871 "Set AS-Path Hop-count TTL\n")
3872{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003873 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003874}
3875
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003876DEFUN_DEPRECATED (no_set_pathlimit_ttl,
Paul Jakma41367172007-08-06 15:24:51 +00003877 no_set_pathlimit_ttl_cmd,
3878 "no set pathlimit ttl",
3879 NO_STR
3880 SET_STR
3881 "BGP AS-Pathlimit attribute\n"
3882 "Set AS-Path Hop-count TTL\n")
3883{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003884 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003885}
3886
3887ALIAS (no_set_pathlimit_ttl,
3888 no_set_pathlimit_ttl_val_cmd,
3889 "no set pathlimit ttl <1-255>",
3890 NO_STR
3891 MATCH_STR
3892 "BGP AS-Pathlimit attribute\n"
3893 "Set AS-Path Hop-count TTL\n")
3894
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003895DEFUN_DEPRECATED (match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003896 match_pathlimit_as_cmd,
3897 "match pathlimit as <1-65535>",
3898 MATCH_STR
3899 "BGP AS-Pathlimit attribute\n"
3900 "Match Pathlimit AS number\n")
3901{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003902 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003903}
3904
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003905DEFUN_DEPRECATED (no_match_pathlimit_as,
Paul Jakma41367172007-08-06 15:24:51 +00003906 no_match_pathlimit_as_cmd,
3907 "no match pathlimit as",
3908 NO_STR
3909 MATCH_STR
3910 "BGP AS-Pathlimit attribute\n"
3911 "Match Pathlimit AS number\n")
3912{
Paul Jakmac8f3fe32010-12-05 20:28:02 +00003913 return CMD_SUCCESS;
Paul Jakma41367172007-08-06 15:24:51 +00003914}
3915
3916ALIAS (no_match_pathlimit_as,
3917 no_match_pathlimit_as_val_cmd,
3918 "no match pathlimit as <1-65535>",
3919 NO_STR
3920 MATCH_STR
3921 "BGP AS-Pathlimit attribute\n"
3922 "Match Pathlimit ASN\n")
3923
David Lamparter6b0655a2014-06-04 06:53:35 +02003924
paul718e3742002-12-13 20:15:29 +00003925/* Initialization of route map. */
3926void
paul94f2b392005-06-28 12:44:16 +00003927bgp_route_map_init (void)
paul718e3742002-12-13 20:15:29 +00003928{
3929 route_map_init ();
3930 route_map_init_vty ();
3931 route_map_add_hook (bgp_route_map_update);
3932 route_map_delete_hook (bgp_route_map_update);
3933
paulfee0f4c2004-09-13 05:12:46 +00003934 route_map_install_match (&route_match_peer_cmd);
paul718e3742002-12-13 20:15:29 +00003935 route_map_install_match (&route_match_ip_address_cmd);
3936 route_map_install_match (&route_match_ip_next_hop_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003937 route_map_install_match (&route_match_ip_route_source_cmd);
paul718e3742002-12-13 20:15:29 +00003938 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
3939 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003940 route_map_install_match (&route_match_ip_route_source_prefix_list_cmd);
paul718e3742002-12-13 20:15:29 +00003941 route_map_install_match (&route_match_aspath_cmd);
3942 route_map_install_match (&route_match_community_cmd);
paul73ffb252003-04-19 15:49:49 +00003943 route_map_install_match (&route_match_ecommunity_cmd);
paul718e3742002-12-13 20:15:29 +00003944 route_map_install_match (&route_match_metric_cmd);
3945 route_map_install_match (&route_match_origin_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04003946 route_map_install_match (&route_match_probability_cmd);
paul718e3742002-12-13 20:15:29 +00003947
3948 route_map_install_set (&route_set_ip_nexthop_cmd);
3949 route_map_install_set (&route_set_local_pref_cmd);
3950 route_map_install_set (&route_set_weight_cmd);
3951 route_map_install_set (&route_set_metric_cmd);
3952 route_map_install_set (&route_set_aspath_prepend_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00003953 route_map_install_set (&route_set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00003954 route_map_install_set (&route_set_origin_cmd);
3955 route_map_install_set (&route_set_atomic_aggregate_cmd);
3956 route_map_install_set (&route_set_aggregator_as_cmd);
3957 route_map_install_set (&route_set_community_cmd);
3958 route_map_install_set (&route_set_community_delete_cmd);
3959 route_map_install_set (&route_set_vpnv4_nexthop_cmd);
3960 route_map_install_set (&route_set_originator_id_cmd);
3961 route_map_install_set (&route_set_ecommunity_rt_cmd);
3962 route_map_install_set (&route_set_ecommunity_soo_cmd);
3963
paulfee0f4c2004-09-13 05:12:46 +00003964 install_element (RMAP_NODE, &match_peer_cmd);
3965 install_element (RMAP_NODE, &match_peer_local_cmd);
3966 install_element (RMAP_NODE, &no_match_peer_cmd);
3967 install_element (RMAP_NODE, &no_match_peer_val_cmd);
3968 install_element (RMAP_NODE, &no_match_peer_local_cmd);
paul718e3742002-12-13 20:15:29 +00003969 install_element (RMAP_NODE, &match_ip_address_cmd);
3970 install_element (RMAP_NODE, &no_match_ip_address_cmd);
3971 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
3972 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
3973 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
3974 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003975 install_element (RMAP_NODE, &match_ip_route_source_cmd);
3976 install_element (RMAP_NODE, &no_match_ip_route_source_cmd);
3977 install_element (RMAP_NODE, &no_match_ip_route_source_val_cmd);
paul718e3742002-12-13 20:15:29 +00003978 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
3979 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
3980 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
3981 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
3982 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
3983 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
hassoc1643bb2005-02-02 16:43:17 +00003984 install_element (RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
3985 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
3986 install_element (RMAP_NODE, &no_match_ip_route_source_prefix_list_val_cmd);
paul718e3742002-12-13 20:15:29 +00003987
3988 install_element (RMAP_NODE, &match_aspath_cmd);
3989 install_element (RMAP_NODE, &no_match_aspath_cmd);
3990 install_element (RMAP_NODE, &no_match_aspath_val_cmd);
3991 install_element (RMAP_NODE, &match_metric_cmd);
3992 install_element (RMAP_NODE, &no_match_metric_cmd);
3993 install_element (RMAP_NODE, &no_match_metric_val_cmd);
3994 install_element (RMAP_NODE, &match_community_cmd);
3995 install_element (RMAP_NODE, &match_community_exact_cmd);
3996 install_element (RMAP_NODE, &no_match_community_cmd);
3997 install_element (RMAP_NODE, &no_match_community_val_cmd);
3998 install_element (RMAP_NODE, &no_match_community_exact_cmd);
paul73ffb252003-04-19 15:49:49 +00003999 install_element (RMAP_NODE, &match_ecommunity_cmd);
4000 install_element (RMAP_NODE, &no_match_ecommunity_cmd);
4001 install_element (RMAP_NODE, &no_match_ecommunity_val_cmd);
paul718e3742002-12-13 20:15:29 +00004002 install_element (RMAP_NODE, &match_origin_cmd);
4003 install_element (RMAP_NODE, &no_match_origin_cmd);
4004 install_element (RMAP_NODE, &no_match_origin_val_cmd);
Vyacheslav Trushkin1add1152011-11-22 20:15:10 +04004005 install_element (RMAP_NODE, &match_probability_cmd);
4006 install_element (RMAP_NODE, &no_match_probability_cmd);
4007 install_element (RMAP_NODE, &no_match_probability_val_cmd);
paul718e3742002-12-13 20:15:29 +00004008
4009 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
paulaf5cd0a2003-11-02 07:24:40 +00004010 install_element (RMAP_NODE, &set_ip_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00004011 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
4012 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
4013 install_element (RMAP_NODE, &set_local_pref_cmd);
4014 install_element (RMAP_NODE, &no_set_local_pref_cmd);
4015 install_element (RMAP_NODE, &no_set_local_pref_val_cmd);
4016 install_element (RMAP_NODE, &set_weight_cmd);
4017 install_element (RMAP_NODE, &no_set_weight_cmd);
4018 install_element (RMAP_NODE, &no_set_weight_val_cmd);
4019 install_element (RMAP_NODE, &set_metric_cmd);
paul73ffb252003-04-19 15:49:49 +00004020 install_element (RMAP_NODE, &set_metric_addsub_cmd);
paul718e3742002-12-13 20:15:29 +00004021 install_element (RMAP_NODE, &no_set_metric_cmd);
4022 install_element (RMAP_NODE, &no_set_metric_val_cmd);
4023 install_element (RMAP_NODE, &set_aspath_prepend_cmd);
Timo Teräs85c854a2014-09-30 11:31:53 +03004024 install_element (RMAP_NODE, &set_aspath_prepend_lastas_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00004025 install_element (RMAP_NODE, &set_aspath_exclude_cmd);
paul718e3742002-12-13 20:15:29 +00004026 install_element (RMAP_NODE, &no_set_aspath_prepend_cmd);
4027 install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd);
Denis Ovsienko841f7a52008-04-10 11:47:45 +00004028 install_element (RMAP_NODE, &no_set_aspath_exclude_cmd);
4029 install_element (RMAP_NODE, &no_set_aspath_exclude_val_cmd);
paul718e3742002-12-13 20:15:29 +00004030 install_element (RMAP_NODE, &set_origin_cmd);
4031 install_element (RMAP_NODE, &no_set_origin_cmd);
4032 install_element (RMAP_NODE, &no_set_origin_val_cmd);
4033 install_element (RMAP_NODE, &set_atomic_aggregate_cmd);
4034 install_element (RMAP_NODE, &no_set_atomic_aggregate_cmd);
4035 install_element (RMAP_NODE, &set_aggregator_as_cmd);
4036 install_element (RMAP_NODE, &no_set_aggregator_as_cmd);
4037 install_element (RMAP_NODE, &no_set_aggregator_as_val_cmd);
4038 install_element (RMAP_NODE, &set_community_cmd);
4039 install_element (RMAP_NODE, &set_community_none_cmd);
4040 install_element (RMAP_NODE, &no_set_community_cmd);
4041 install_element (RMAP_NODE, &no_set_community_val_cmd);
4042 install_element (RMAP_NODE, &no_set_community_none_cmd);
4043 install_element (RMAP_NODE, &set_community_delete_cmd);
4044 install_element (RMAP_NODE, &no_set_community_delete_cmd);
4045 install_element (RMAP_NODE, &no_set_community_delete_val_cmd);
4046 install_element (RMAP_NODE, &set_ecommunity_rt_cmd);
4047 install_element (RMAP_NODE, &no_set_ecommunity_rt_cmd);
4048 install_element (RMAP_NODE, &no_set_ecommunity_rt_val_cmd);
4049 install_element (RMAP_NODE, &set_ecommunity_soo_cmd);
4050 install_element (RMAP_NODE, &no_set_ecommunity_soo_cmd);
4051 install_element (RMAP_NODE, &no_set_ecommunity_soo_val_cmd);
4052 install_element (RMAP_NODE, &set_vpnv4_nexthop_cmd);
4053 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_cmd);
4054 install_element (RMAP_NODE, &no_set_vpnv4_nexthop_val_cmd);
4055 install_element (RMAP_NODE, &set_originator_id_cmd);
4056 install_element (RMAP_NODE, &no_set_originator_id_cmd);
4057 install_element (RMAP_NODE, &no_set_originator_id_val_cmd);
4058
4059#ifdef HAVE_IPV6
4060 route_map_install_match (&route_match_ipv6_address_cmd);
4061 route_map_install_match (&route_match_ipv6_next_hop_cmd);
4062 route_map_install_match (&route_match_ipv6_address_prefix_list_cmd);
4063 route_map_install_set (&route_set_ipv6_nexthop_global_cmd);
4064 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
Dinesh G Duttad5233a2014-09-30 14:19:57 -07004065 route_map_install_set (&route_set_ipv6_nexthop_peer_cmd);
4066
paul718e3742002-12-13 20:15:29 +00004067 install_element (RMAP_NODE, &match_ipv6_address_cmd);
4068 install_element (RMAP_NODE, &no_match_ipv6_address_cmd);
4069 install_element (RMAP_NODE, &match_ipv6_next_hop_cmd);
4070 install_element (RMAP_NODE, &no_match_ipv6_next_hop_cmd);
4071 install_element (RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
4072 install_element (RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
4073 install_element (RMAP_NODE, &set_ipv6_nexthop_global_cmd);
4074 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_cmd);
4075 install_element (RMAP_NODE, &no_set_ipv6_nexthop_global_val_cmd);
4076 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
4077 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
4078 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
Dinesh G Duttad5233a2014-09-30 14:19:57 -07004079 install_element (RMAP_NODE, &set_ipv6_nexthop_peer_cmd);
4080 install_element (RMAP_NODE, &no_set_ipv6_nexthop_peer_cmd);
paul718e3742002-12-13 20:15:29 +00004081#endif /* HAVE_IPV6 */
Paul Jakma41367172007-08-06 15:24:51 +00004082
Paul Jakmac8f3fe32010-12-05 20:28:02 +00004083 /* AS-Pathlimit: functionality removed, commands kept for
4084 * compatibility.
4085 */
Paul Jakma41367172007-08-06 15:24:51 +00004086 install_element (RMAP_NODE, &set_pathlimit_ttl_cmd);
4087 install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd);
4088 install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd);
4089 install_element (RMAP_NODE, &match_pathlimit_as_cmd);
4090 install_element (RMAP_NODE, &no_match_pathlimit_as_cmd);
4091 install_element (RMAP_NODE, &no_match_pathlimit_as_val_cmd);
paul718e3742002-12-13 20:15:29 +00004092}